DIRECTOR: Implement zoomBox rendering

This commit is contained in:
Eugene Sandulenko 2019-12-10 00:32:35 +01:00
parent 080c2b8410
commit 303b418dda
4 changed files with 106 additions and 12 deletions

View File

@ -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());
}

View File

@ -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) {

View File

@ -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

View File

@ -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