aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEugene Sandulenko2019-12-10 00:32:35 +0100
committerEugene Sandulenko2019-12-10 00:32:54 +0100
commit303b418dda38c4d4b88411c0a73ce387911b8ccb (patch)
tree80a22de56ab99a618e0c94c77d876fab25000d2d
parent080c2b8410c6c2d48f72a156a43710776872b9c3 (diff)
downloadscummvm-rg350-303b418dda38c4d4b88411c0a73ce387911b8ccb.tar.gz
scummvm-rg350-303b418dda38c4d4b88411c0a73ce387911b8ccb.tar.bz2
scummvm-rg350-303b418dda38c4d4b88411c0a73ce387911b8ccb.zip
DIRECTOR: Implement zoomBox rendering
-rw-r--r--engines/director/frame.cpp4
-rw-r--r--engines/director/lingo/lingo-builtins.cpp29
-rw-r--r--engines/director/score.cpp70
-rw-r--r--engines/director/score.h15
4 files changed, 106 insertions, 12 deletions
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<uint16, Common::String> _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<ZoomBox *> _zoomBoxes;
};
} // End of namespace Director