From 303b418dda38c4d4b88411c0a73ce387911b8ccb Mon Sep 17 00:00:00 2001 From: Eugene Sandulenko Date: Tue, 10 Dec 2019 00:32:35 +0100 Subject: DIRECTOR: Implement zoomBox rendering --- engines/director/frame.cpp | 4 ++ engines/director/lingo/lingo-builtins.cpp | 29 ++++++++----- engines/director/score.cpp | 70 ++++++++++++++++++++++++++++++- engines/director/score.h | 15 +++++++ 4 files changed, 106 insertions(+), 12 deletions(-) (limited to 'engines') diff --git a/engines/director/frame.cpp b/engines/director/frame.cpp index e3615d3cf7..06f074faa6 100644 --- a/engines/director/frame.cpp +++ b/engines/director/frame.cpp @@ -407,6 +407,8 @@ void Frame::prepareFrame(Score *score) { renderSprites(*score->_surface, false); renderSprites(*score->_trailSurface, true); + score->renderZoomBox(); + if (_transType != 0) // TODO Handle changing area case playTransition(score); @@ -415,6 +417,8 @@ void Frame::prepareFrame(Score *score) { playSoundChannel(); } + score->_backSurface->copyFrom(*score->_surface); + g_system->copyRectToScreen(score->_surface->getPixels(), score->_surface->pitch, 0, 0, score->_surface->getBounds().width(), score->_surface->getBounds().height()); } diff --git a/engines/director/lingo/lingo-builtins.cpp b/engines/director/lingo/lingo-builtins.cpp index 09b8c11ca3..a8e8c75e6a 100644 --- a/engines/director/lingo/lingo-builtins.cpp +++ b/engines/director/lingo/lingo-builtins.cpp @@ -1280,9 +1280,6 @@ void Lingo::b_unLoadCast(int nargs) { void Lingo::b_zoomBox(int nargs) { // zoomBox startSprite, endSprite [, delatTicks] // ticks are in 1/60th, default 1 - - g_lingo->printSTUBWithArglist("b_zoomBox", nargs); - if (nargs < 2 || nargs > 3) { warning("b_zoomBox: expected 2 or 3 arguments, got %d", nargs); @@ -1305,10 +1302,9 @@ void Lingo::b_zoomBox(int nargs) { startSprite.toInt(); endSprite.toInt(); - Frame *frame = g_director->getCurrentScore()->_frames[g_director->getCurrentScore()->getCurrentFrame()]; - Frame *frame2 = nullptr; - if (g_director->getCurrentScore()->_frames.size() > g_director->getCurrentScore()->getCurrentFrame()) - frame2 = g_director->getCurrentScore()->_frames[g_director->getCurrentScore()->getCurrentFrame() + 1]; + Score *score = g_director->getCurrentScore(); + uint16 curFrame = score->getCurrentFrame(); + Frame *frame = score->_frames[curFrame]; Common::Rect *startRect = frame->getSpriteRect(startSprite.u.i); if (!startRect) { @@ -1316,17 +1312,28 @@ void Lingo::b_zoomBox(int nargs) { return; } + // Looks for endSprite in the current frame, otherwise + // Looks for endSprite in the next frame Common::Rect *endRect = frame->getSpriteRect(endSprite.u.i); - if (!endRect && frame2) - endRect = frame2->getSpriteRect(endSprite.u.i); + if (!endRect) { + if (score->_frames.size() > curFrame) + score->_frames[curFrame + 1]->getSpriteRect(endSprite.u.i); + } if (!endRect) { warning("b_zoomBox: unknown end sprite #%d", endSprite.u.i); return; } - startRect->debugPrint(0, "b_zoomBox: start: "); - endRect->debugPrint(0, "b_zoomBox: end: "); + ZoomBox *box = new ZoomBox; + box->start = *startRect; + box->end = *endRect; + box->delay = delayTicks; + box->step = 0; + box->startTime = g_system->getMillis(); + box->nextTime = g_system->getMillis() + 1000 * box->step / 60; + + score->addZoomBox(box); } void Lingo::b_updateStage(int nargs) { diff --git a/engines/director/score.cpp b/engines/director/score.cpp index 0d11c7b54a..42937add74 100644 --- a/engines/director/score.cpp +++ b/engines/director/score.cpp @@ -28,6 +28,7 @@ #include "engines/util.h" #include "graphics/font.h" #include "graphics/palette.h" +#include "graphics/primitives.h" #include "graphics/macgui/macfontmanager.h" #include "graphics/macgui/macwindowmanager.h" #include "image/bmp.h" @@ -65,6 +66,7 @@ Score::Score(DirectorEngine *vm) { _vm = vm; _surface = new Graphics::ManagedSurface; _trailSurface = new Graphics::ManagedSurface; + _backSurface = new Graphics::ManagedSurface; _lingo = _vm->getLingo(); _soundManager = _vm->getSoundManager(); _currentMouseDownSpriteId = 0; @@ -324,6 +326,10 @@ Score::~Score() { if (_trailSurface) _trailSurface->free(); + if (_backSurface) + _backSurface->free(); + + delete _backSurface; delete _surface; delete _trailSurface; @@ -1261,6 +1267,7 @@ void Score::startLoop() { _surface->create(_movieRect.width(), _movieRect.height()); _trailSurface->create(_movieRect.width(), _movieRect.height()); + _backSurface->create(_movieRect.width(), _movieRect.height()); if (_stageColor == 0) _trailSurface->clear(_vm->getPaletteColorCount() - 1); @@ -1283,8 +1290,10 @@ void Score::startLoop() { } void Score::update() { - if (g_system->getMillis() < _nextFrameTime) + if (g_system->getMillis() < _nextFrameTime) { + renderZoomBox(true); return; + } _surface->clear(); _surface->copyFrom(*_trailSurface); @@ -1372,4 +1381,63 @@ Sprite *Score::getSpriteById(uint16 id) { } } +void Score::addZoomBox(ZoomBox *box) { + _zoomBoxes.push_back(box); +} + +void Score::renderZoomBox(bool redraw) { + if (!_zoomBoxes.size()) + return; + + ZoomBox *box = _zoomBoxes.front(); + uint32 t = g_system->getMillis(); + + if (box->nextTime > t) + return; + + if (redraw) { + _surface->copyFrom(*_backSurface); + } + + const int numSteps = 14; + // We have 15 steps in total, and we have flying rectange + // from switching 3/4 frames + + int start, end; + // Determine, how many rectangles and what are their numbers + if (box->step < 5) { + start = 1; + end = box->step; + } else { + start = box->step - 4; + end = MIN(start + 3 - box->step % 2, 8); + } + + Graphics::MacPlotData pd(_surface, &_vm->_wm->getPatterns(), Graphics::kPatternCheckers, 1, 0); + + for (int i = start; i <= end; i++) { + Common::Rect r(box->start.left + (box->end.left - box->start.left) * i / 8, + box->start.top + (box->end.top - box->start.top) * i / 8, + box->start.right + (box->end.right - box->start.right) * i / 8, + box->start.bottom + (box->end.bottom - box->start.bottom) * i / 8); + + Graphics::drawLine(r.left, r.top, r.right, r.top, 0xffff, Graphics::macDrawPixel, &pd); + Graphics::drawLine(r.right, r.top, r.right, r.bottom, 0xffff, Graphics::macDrawPixel, &pd); + Graphics::drawLine(r.left, r.bottom, r.right, r.bottom, 0xffff, Graphics::macDrawPixel, &pd); + Graphics::drawLine(r.left, r.top, r.left, r.bottom, 0xffff, Graphics::macDrawPixel, &pd); + } + + box->step++; + + if (box->step >= numSteps) { + _zoomBoxes.remove_at(0); + } + + box->nextTime = box->startTime + 1000 * box->step * box->delay / 60; + + if (redraw) { + g_system->copyRectToScreen(_surface->getPixels(), _surface->pitch, 0, 0, _surface->getBounds().width(), _surface->getBounds().height()); + } +} + } // End of namespace Director diff --git a/engines/director/score.h b/engines/director/score.h index 5f9b79cb31..388c14e73b 100644 --- a/engines/director/score.h +++ b/engines/director/score.h @@ -46,6 +46,15 @@ struct Label; class Lingo; class Sprite; +struct ZoomBox { + Common::Rect start; + Common::Rect end; + int delay; + int step; + uint32 startTime; + uint32 nextTime; +}; + enum ScriptType { kMovieScript = 0, kSpriteScript = 1, @@ -94,6 +103,9 @@ public: int getCurrentLabelNumber(); int getNextLabelNumber(int referenceFrame); + void addZoomBox(ZoomBox *box); + void renderZoomBox(bool redraw = false); + private: void update(); void readVersion(uint32 rid); @@ -123,6 +135,7 @@ public: Common::HashMap _fontMap; Graphics::ManagedSurface *_surface; Graphics::ManagedSurface *_trailSurface; + Graphics::ManagedSurface *_backSurface; Graphics::Font *_font; Archive *_movieArchive; Common::Rect _movieRect; @@ -158,6 +171,8 @@ private: Lingo *_lingo; DirectorSound *_soundManager; DirectorEngine *_vm; + + Common::Array _zoomBoxes; }; } // End of namespace Director -- cgit v1.2.3