mirror of
https://github.com/libretro/scummvm.git
synced 2025-02-04 01:46:42 +00:00
b7c903569c
The number of steps a transition has is calculated based on the chunksize. A larger chunksize means quicker execution with a downside of not having pixel perfect frames. Ensures that the chunksize is never more than sprite width and height to avoid floating point division errors. This is only enabled when the debugflag is used.
1129 lines
33 KiB
C++
1129 lines
33 KiB
C++
/* ScummVM - Graphic Adventure Engine
|
|
*
|
|
* ScummVM is the legal property of its developers, whose names
|
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
|
* file distributed with this source distribution.
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; either version 2
|
|
* of the License, or (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
*
|
|
*/
|
|
|
|
#include "common/system.h"
|
|
|
|
#include "graphics/primitives.h"
|
|
#include "graphics/macgui/macwindowmanager.h"
|
|
|
|
#include "director/director.h"
|
|
#include "director/movie.h"
|
|
#include "director/score.h"
|
|
#include "director/window.h"
|
|
#include "director/util.h"
|
|
#include "director/lingo/lingo.h"
|
|
|
|
namespace Director {
|
|
|
|
enum TransitionAlgo {
|
|
kTransAlgoBlinds,
|
|
kTransAlgoBoxy,
|
|
kTransAlgoStrips,
|
|
kTransAlgoCenterOut,
|
|
kTransAlgoChecker,
|
|
kTransAlgoCover,
|
|
kTransAlgoDissolve,
|
|
kTransAlgoEdgesIn,
|
|
kTransAlgoPush,
|
|
kTransAlgoRandomLines,
|
|
kTransAlgoReveal,
|
|
kTransAlgoWipe,
|
|
kTransAlgoZoom
|
|
};
|
|
|
|
enum TransitionDirection {
|
|
kTransDirNone,
|
|
kTransDirHorizontal,
|
|
kTransDirVertical,
|
|
kTransDirBoth,
|
|
kTransDirStepsH,
|
|
kTransDirStepsV,
|
|
kTransDirCheckers,
|
|
kTransDirBlindsV,
|
|
kTransDirBlindsH
|
|
};
|
|
|
|
enum {
|
|
kNumStrips = 16,
|
|
kNumChecks = 16,
|
|
kNumBlinds = 12
|
|
};
|
|
|
|
#define TRANS(t,a,d) {t,#t,a,d}
|
|
|
|
struct {
|
|
TransitionType type;
|
|
const char *name;
|
|
TransitionAlgo algo;
|
|
TransitionDirection dir;
|
|
} static const transProps[] = {
|
|
TRANS(kTransNone, kTransAlgoWipe, kTransDirNone),
|
|
TRANS(kTransWipeRight, kTransAlgoWipe, kTransDirHorizontal),
|
|
TRANS(kTransWipeLeft, kTransAlgoWipe, kTransDirHorizontal),
|
|
TRANS(kTransWipeDown, kTransAlgoWipe, kTransDirVertical),
|
|
TRANS(kTransWipeUp, kTransAlgoWipe, kTransDirVertical),
|
|
TRANS(kTransCenterOutHorizontal, kTransAlgoCenterOut,kTransDirHorizontal), // 5
|
|
TRANS(kTransEdgesInHorizontal, kTransAlgoEdgesIn, kTransDirHorizontal),
|
|
TRANS(kTransCenterOutVertical, kTransAlgoCenterOut,kTransDirVertical),
|
|
TRANS(kTransEdgesInVertical, kTransAlgoEdgesIn, kTransDirVertical),
|
|
TRANS(kTransCenterOutSquare, kTransAlgoCenterOut,kTransDirBoth),
|
|
TRANS(kTransEdgesInSquare, kTransAlgoEdgesIn, kTransDirBoth), // 10
|
|
TRANS(kTransPushLeft, kTransAlgoPush, kTransDirHorizontal),
|
|
TRANS(kTransPushRight, kTransAlgoPush, kTransDirHorizontal),
|
|
TRANS(kTransPushDown, kTransAlgoPush, kTransDirVertical),
|
|
TRANS(kTransPushUp, kTransAlgoPush, kTransDirVertical),
|
|
TRANS(kTransRevealUp, kTransAlgoReveal, kTransDirVertical), // 15
|
|
TRANS(kTransRevealUpRight, kTransAlgoReveal, kTransDirBoth),
|
|
TRANS(kTransRevealRight, kTransAlgoReveal, kTransDirHorizontal),
|
|
TRANS(kTransRevealDownRight, kTransAlgoReveal, kTransDirBoth),
|
|
TRANS(kTransRevealDown, kTransAlgoReveal, kTransDirVertical),
|
|
TRANS(kTransRevealDownLeft, kTransAlgoReveal, kTransDirBoth), // 20
|
|
TRANS(kTransRevealLeft, kTransAlgoReveal, kTransDirHorizontal),
|
|
TRANS(kTransRevealUpLeft, kTransAlgoReveal, kTransDirBoth),
|
|
TRANS(kTransDissolvePixelsFast, kTransAlgoDissolve, kTransDirNone),
|
|
TRANS(kTransDissolveBoxyRects, kTransAlgoDissolve, kTransDirNone),
|
|
TRANS(kTransDissolveBoxySquares, kTransAlgoDissolve, kTransDirNone), // 25
|
|
TRANS(kTransDissolvePatterns, kTransAlgoDissolve, kTransDirNone),
|
|
TRANS(kTransRandomRows, kTransAlgoDissolve, kTransDirNone),
|
|
TRANS(kTransRandomColumns, kTransAlgoDissolve, kTransDirNone),
|
|
TRANS(kTransCoverDown, kTransAlgoCover, kTransDirVertical),
|
|
TRANS(kTransCoverDownLeft, kTransAlgoCover, kTransDirBoth), // 30
|
|
TRANS(kTransCoverDownRight, kTransAlgoCover, kTransDirBoth),
|
|
TRANS(kTransCoverLeft, kTransAlgoCover, kTransDirHorizontal),
|
|
TRANS(kTransCoverRight, kTransAlgoCover, kTransDirHorizontal),
|
|
TRANS(kTransCoverUp, kTransAlgoCover, kTransDirVertical),
|
|
TRANS(kTransCoverUpLeft, kTransAlgoCover, kTransDirBoth), // 35
|
|
TRANS(kTransCoverUpRight, kTransAlgoCover, kTransDirBoth),
|
|
TRANS(kTransVenetianBlind, kTransAlgoBlinds, kTransDirBlindsH),
|
|
TRANS(kTransCheckerboard, kTransAlgoChecker, kTransDirCheckers),
|
|
TRANS(kTransStripsBottomBuildLeft, kTransAlgoStrips, kTransDirStepsV),
|
|
TRANS(kTransStripsBottomBuildRight, kTransAlgoStrips, kTransDirStepsV), // 40
|
|
TRANS(kTransStripsLeftBuildDown, kTransAlgoStrips, kTransDirStepsH),
|
|
TRANS(kTransStripsLeftBuildUp, kTransAlgoStrips, kTransDirStepsH),
|
|
TRANS(kTransStripsRightBuildDown, kTransAlgoStrips, kTransDirStepsH),
|
|
TRANS(kTransStripsRightBuildUp, kTransAlgoStrips, kTransDirStepsH),
|
|
TRANS(kTransStripsTopBuildLeft, kTransAlgoStrips, kTransDirStepsV), // 45
|
|
TRANS(kTransStripsTopBuildRight, kTransAlgoStrips, kTransDirStepsV),
|
|
TRANS(kTransZoomOpen, kTransAlgoZoom, kTransDirBoth),
|
|
TRANS(kTransZoomClose, kTransAlgoZoom, kTransDirBoth),
|
|
TRANS(kTransVerticalBinds, kTransAlgoBlinds, kTransDirBlindsV),
|
|
TRANS(kTransDissolveBitsFast, kTransAlgoDissolve, kTransDirNone), // 50
|
|
TRANS(kTransDissolvePixels, kTransAlgoDissolve, kTransDirNone),
|
|
TRANS(kTransDissolveBits, kTransAlgoDissolve, kTransDirNone)
|
|
};
|
|
|
|
void Window::exitTransition(Graphics::ManagedSurface *nextFrame, Common::Rect clipRect) {
|
|
_composeSurface->blitFrom(*nextFrame, clipRect, Common::Point(clipRect.left, clipRect.top));
|
|
stepTransition();
|
|
}
|
|
|
|
void Window::stepTransition() {
|
|
_contentIsDirty = true;
|
|
g_director->draw();
|
|
}
|
|
|
|
void Window::playTransition(uint16 transDuration, uint8 transArea, uint8 transChunkSize, TransitionType transType, uint frame) {
|
|
// Play a transition and return the number of subframes rendered
|
|
TransParams t;
|
|
|
|
t.type = transType;
|
|
t.duration = MAX<uint16>(250, transDuration); // When duration is < 1/4s, make it 1/4
|
|
t.frame = frame;
|
|
t.chunkSize = MAX<uint>(1, transChunkSize);
|
|
t.area = MAX<uint>(0, transArea);
|
|
|
|
// If we requested fast transitions, speed everything up
|
|
if (debugChannelSet(-1, kDebugFast))
|
|
t.duration = 250;
|
|
|
|
// Cache a copy of the frame before the transition.
|
|
Graphics::ManagedSurface currentFrame(Graphics::ManagedSurface(_composeSurface->w, _composeSurface->h, g_director->_pixelformat));
|
|
currentFrame.copyFrom(*_composeSurface);
|
|
|
|
// If a transition is being played, render the frame after the transition.
|
|
Graphics::ManagedSurface nextFrame(Graphics::ManagedSurface(_composeSurface->w, _composeSurface->h, g_director->_pixelformat));
|
|
|
|
Common::Rect clipRect;
|
|
if (t.area) {
|
|
// Changed area transition
|
|
g_director->getCurrentMovie()->getScore()->renderSprites(t.frame);
|
|
|
|
if (_dirtyRects.size() == 0)
|
|
return;
|
|
|
|
clipRect = *_dirtyRects.begin();
|
|
|
|
for (Common::List<Common::Rect>::iterator i = _dirtyRects.begin(); i != _dirtyRects.end(); ++i)
|
|
clipRect.extend(*i);
|
|
|
|
// Ensure we redraw any other sprites intersecting the non-clip area.
|
|
_dirtyRects.clear();
|
|
|
|
// Some transitions depend upon an even clipRect size
|
|
if (clipRect.width() % 2 == 1)
|
|
clipRect.right += 1;
|
|
|
|
if (clipRect.height() % 2 == 1)
|
|
clipRect.bottom += 1;
|
|
|
|
clipRect.clip(Common::Rect(_innerDims.width(), _innerDims.height()));
|
|
_dirtyRects.push_back(clipRect);
|
|
|
|
render(false, &nextFrame);
|
|
} else {
|
|
// Full stage transition
|
|
g_director->getCurrentMovie()->getScore()->renderSprites(t.frame, kRenderForceUpdate);
|
|
render(true, &nextFrame);
|
|
|
|
clipRect = _innerDims;
|
|
clipRect.moveTo(0, 0);
|
|
}
|
|
|
|
Common::Rect rfrom, rto;
|
|
|
|
initTransParams(t, clipRect);
|
|
|
|
Graphics::ManagedSurface *blitFrom;
|
|
bool fullredraw = false;
|
|
|
|
switch (transProps[t.type].algo) {
|
|
case kTransAlgoDissolve:
|
|
if (t.type == kTransDissolvePatterns)
|
|
dissolvePatternsTrans(t, clipRect, &nextFrame);
|
|
else
|
|
dissolveTrans(t, clipRect, &nextFrame);
|
|
return;
|
|
|
|
case kTransAlgoChecker:
|
|
case kTransAlgoStrips:
|
|
case kTransAlgoBlinds:
|
|
transMultiPass(t, clipRect, &nextFrame);
|
|
return;
|
|
|
|
case kTransAlgoZoom:
|
|
transZoom(t, clipRect, &nextFrame);
|
|
return;
|
|
|
|
case kTransAlgoCenterOut:
|
|
case kTransAlgoCover:
|
|
case kTransAlgoWipe:
|
|
blitFrom = &nextFrame;
|
|
break;
|
|
|
|
case kTransAlgoEdgesIn:
|
|
case kTransAlgoReveal:
|
|
case kTransAlgoPush:
|
|
blitFrom = ¤tFrame;
|
|
fullredraw = true;
|
|
break;
|
|
|
|
default:
|
|
blitFrom = &nextFrame;
|
|
break;
|
|
}
|
|
|
|
uint w = clipRect.width();
|
|
uint h = clipRect.height();
|
|
|
|
for (uint16 i = 1; i < t.steps + 1; i++) {
|
|
bool stop = false;
|
|
rto = clipRect;
|
|
rfrom = clipRect;
|
|
|
|
if (transProps[t.type].algo == kTransAlgoReveal ||
|
|
transProps[t.type].algo == kTransAlgoEdgesIn) {
|
|
_composeSurface->copyRectToSurface(nextFrame, clipRect.left, clipRect.top, clipRect);
|
|
}
|
|
|
|
switch (t.type) {
|
|
case kTransWipeRight: // 1
|
|
rto.setWidth(t.xStepSize * i);
|
|
rfrom = rto;
|
|
break;
|
|
|
|
case kTransWipeLeft: // 2
|
|
rto.setWidth(t.xStepSize * i);
|
|
rto.translate(w - t.xStepSize * i, 0);
|
|
rfrom = rto;
|
|
break;
|
|
|
|
case kTransWipeDown: // 3
|
|
rto.setHeight(t.yStepSize * i);
|
|
rfrom = rto;
|
|
break;
|
|
|
|
case kTransWipeUp: // 4
|
|
rto.setHeight(t.yStepSize * i);
|
|
rto.translate(0, h - t.yStepSize * i);
|
|
rfrom = rto;
|
|
break;
|
|
|
|
case kTransCenterOutHorizontal: // 5
|
|
t.xpos += t.xStepSize;
|
|
rto.setWidth(t.xpos * 2);
|
|
rto.translate(w / 2 - t.xpos, 0);
|
|
rfrom = rto;
|
|
break;
|
|
|
|
case kTransEdgesInHorizontal: // 6
|
|
rto.setWidth(w - t.xStepSize * i * 2);
|
|
rto.translate(t.xStepSize * i, 0);
|
|
rfrom = rto;
|
|
break;
|
|
|
|
case kTransCenterOutVertical: // 7
|
|
t.ypos += t.yStepSize;
|
|
rto.setHeight(t.ypos * 2);
|
|
rto.translate(0, h / 2 - t.ypos);
|
|
rfrom = rto;
|
|
break;
|
|
|
|
case kTransEdgesInVertical: // 8
|
|
rto.setHeight(h - t.yStepSize * i * 2);
|
|
rto.translate(0, t.yStepSize * i);
|
|
rfrom = rto;
|
|
break;
|
|
|
|
case kTransCenterOutSquare: // 9
|
|
t.ypos += t.yStepSize;
|
|
rto.setHeight(t.ypos * 2);
|
|
t.xpos += t.xStepSize;
|
|
rto.setWidth(t.xpos * 2);
|
|
rto.translate(w / 2 - t.xpos, h / 2 - t.ypos);
|
|
rfrom = rto;
|
|
break;
|
|
|
|
case kTransEdgesInSquare: // 10
|
|
rto.setHeight(h - t.yStepSize * i * 2);
|
|
rto.setWidth(w - t.xStepSize * i * 2);
|
|
rto.moveTo(t.xStepSize * i, t.yStepSize * i);
|
|
rfrom = rto;
|
|
break;
|
|
|
|
case kTransPushLeft: // 11
|
|
rto.translate(w - t.xStepSize * i, 0);
|
|
rfrom.right -= w - clipRect.findIntersectingRect(rto).width();
|
|
rto.clip(clipRect);
|
|
_composeSurface->blitFrom(nextFrame, rfrom, Common::Point(rto.left, rto.top));
|
|
|
|
rfrom.translate(t.xStepSize * i, 0);
|
|
rfrom.setWidth(w - t.xStepSize * i);
|
|
rto.moveTo(clipRect.left, clipRect.top);
|
|
break;
|
|
|
|
case kTransPushRight: // 12
|
|
rfrom.translate(w - t.xStepSize * i, 0);
|
|
rfrom.setWidth(t.xStepSize * i);
|
|
_composeSurface->blitFrom(nextFrame, rfrom, Common::Point(rto.left, rto.top));
|
|
|
|
rto.setWidth(w - t.xStepSize * i);
|
|
rto.translate(t.xStepSize * i, 0);
|
|
rfrom.moveTo(clipRect.left, clipRect.top);
|
|
rfrom.setWidth(w - t.xStepSize * i);
|
|
break;
|
|
|
|
case kTransPushDown: // 13
|
|
rfrom.translate(0, h - t.yStepSize * i);
|
|
rfrom.setHeight(t.yStepSize * i);
|
|
_composeSurface->blitFrom(nextFrame, rfrom, Common::Point(rto.left, rto.top));
|
|
|
|
rto.setHeight(h - t.yStepSize * i);
|
|
rto.translate(0, t.yStepSize * i);
|
|
rfrom.moveTo(clipRect.left, clipRect.top);
|
|
rfrom.setHeight(h - t.yStepSize * i);
|
|
break;
|
|
|
|
case kTransPushUp: // 14
|
|
rto.translate(0, h - t.yStepSize * i);
|
|
_composeSurface->blitFrom(nextFrame, rfrom, Common::Point(rto.left, rto.top));
|
|
|
|
rfrom.translate(0, t.yStepSize * i);
|
|
rfrom.setHeight(h - t.yStepSize * i);
|
|
rto.moveTo(clipRect.left, clipRect.top);
|
|
break;
|
|
|
|
case kTransRevealUp: // 15
|
|
rto.translate(0, -t.yStepSize * i);
|
|
rfrom.top += h - clipRect.findIntersectingRect(rto).height();
|
|
rto.clip(clipRect);
|
|
break;
|
|
|
|
case kTransRevealUpRight: // 16
|
|
rto.translate(t.xStepSize * i, -t.yStepSize * i);
|
|
rfrom.top += h - clipRect.findIntersectingRect(rto).height();
|
|
rfrom.right -= w - clipRect.findIntersectingRect(rto).width();
|
|
rto.clip(clipRect);
|
|
break;
|
|
|
|
case kTransRevealRight: // 17
|
|
rto.translate(t.xStepSize * i, 0);
|
|
rfrom.right -= w - clipRect.findIntersectingRect(rto).width();
|
|
rto.clip(clipRect);
|
|
break;
|
|
|
|
case kTransRevealDownRight: // 18
|
|
rto.translate(t.xStepSize * i, t.yStepSize * i);
|
|
rfrom.bottom -= h - clipRect.findIntersectingRect(rto).height();
|
|
rfrom.right -= w - clipRect.findIntersectingRect(rto).width();
|
|
rto.clip(clipRect);
|
|
break;
|
|
|
|
case kTransRevealDown: // 19
|
|
rto.translate(0, t.yStepSize * i);
|
|
rfrom.bottom -= h - clipRect.findIntersectingRect(rto).height();
|
|
rto.clip(clipRect);
|
|
break;
|
|
|
|
case kTransRevealDownLeft: // 20
|
|
rto.translate(-t.xStepSize * i, t.yStepSize * i);
|
|
rfrom.bottom -= h - clipRect.findIntersectingRect(rto).height();
|
|
rfrom.left += w - clipRect.findIntersectingRect(rto).width();
|
|
rto.clip(clipRect);
|
|
break;
|
|
|
|
case kTransRevealLeft: // 21
|
|
rto.translate(-t.xStepSize * i, 0);
|
|
rfrom.left += w - clipRect.findIntersectingRect(rto).width();
|
|
rto.clip(clipRect);
|
|
break;
|
|
|
|
case kTransRevealUpLeft: // 22
|
|
rto.moveTo(-t.xStepSize * i, -t.yStepSize * i);
|
|
rfrom.top += h - clipRect.findIntersectingRect(rto).height();
|
|
rfrom.left += w - clipRect.findIntersectingRect(rto).width();
|
|
rto.clip(clipRect);
|
|
break;
|
|
|
|
case kTransDissolvePixelsFast: // 23
|
|
case kTransDissolveBoxyRects: // 24
|
|
case kTransDissolveBoxySquares: // 25
|
|
case kTransDissolvePatterns: // 26
|
|
case kTransRandomRows: // 27
|
|
case kTransRandomColumns: // 28
|
|
// Dissolve
|
|
break;
|
|
|
|
case kTransCoverDown: // 29
|
|
rto.setHeight(h);
|
|
rto.translate(0, t.yStepSize * i - h);
|
|
rfrom.top += h - clipRect.findIntersectingRect(rto).height();
|
|
rto.clip(clipRect);
|
|
break;
|
|
|
|
case kTransCoverDownLeft: // 30
|
|
rto.translate(w - t.xStepSize * i, t.yStepSize * i - h);
|
|
rfrom.top += h - clipRect.findIntersectingRect(rto).height();
|
|
rfrom.right -= w - clipRect.findIntersectingRect(rto).width();
|
|
rto.clip(clipRect);
|
|
break;
|
|
|
|
case kTransCoverDownRight: // 31
|
|
rto.translate(t.xStepSize * i - w, t.yStepSize * i - h);
|
|
rfrom.top += h - clipRect.findIntersectingRect(rto).height();
|
|
rfrom.left += w - clipRect.findIntersectingRect(rto).width();
|
|
rto.clip(clipRect);
|
|
break;
|
|
|
|
case kTransCoverLeft: // 32
|
|
rto.translate(w - t.xStepSize * i, 0);
|
|
rfrom.right -= w - clipRect.findIntersectingRect(rto).width();
|
|
rto.clip(clipRect);
|
|
break;
|
|
|
|
case kTransCoverRight: // 33
|
|
rto.translate(t.xStepSize * i - w, 0);
|
|
rfrom.left += w - clipRect.findIntersectingRect(rto).width();
|
|
rto.clip(clipRect);
|
|
break;
|
|
|
|
case kTransCoverUp: // 34
|
|
rto.translate(0, h - t.yStepSize * i);
|
|
rfrom.bottom -= h - clipRect.findIntersectingRect(rto).height();
|
|
rto.clip(clipRect);
|
|
break;
|
|
|
|
case kTransCoverUpLeft: // 35
|
|
rto.translate(w - t.xStepSize * i, h - t.yStepSize * i);
|
|
rfrom.bottom -= h - clipRect.findIntersectingRect(rto).height();
|
|
rfrom.right -= w - clipRect.findIntersectingRect(rto).width();
|
|
rto.clip(clipRect);
|
|
break;
|
|
|
|
case kTransCoverUpRight: // 36
|
|
rto.translate(t.xStepSize * i - w, h - t.yStepSize * i);
|
|
rfrom.bottom -= h - clipRect.findIntersectingRect(rto).height();
|
|
rfrom.right -= w - clipRect.findIntersectingRect(rto).width();
|
|
rto.clip(clipRect);
|
|
break;
|
|
|
|
case kTransVenetianBlind: // 37
|
|
case kTransCheckerboard: // 38
|
|
case kTransStripsBottomBuildLeft: // 39
|
|
case kTransStripsBottomBuildRight: // 40
|
|
case kTransStripsLeftBuildDown: // 41
|
|
case kTransStripsLeftBuildUp: // 42
|
|
case kTransStripsRightBuildDown: // 43
|
|
case kTransStripsRightBuildUp: // 44
|
|
case kTransStripsTopBuildLeft: // 45
|
|
case kTransStripsTopBuildRight: // 46
|
|
// Multipass
|
|
break;
|
|
|
|
case kTransZoomOpen: // 47
|
|
case kTransZoomClose: // 48
|
|
// Zoom
|
|
break;
|
|
|
|
case kTransVerticalBinds: // 49
|
|
// Multipass
|
|
break;
|
|
|
|
case kTransDissolveBitsFast: // 50
|
|
case kTransDissolvePixels: // 51
|
|
case kTransDissolveBits: // 52
|
|
// Dissolve
|
|
break;
|
|
|
|
default:
|
|
warning("Score::playTransition(): Unhandled transition type %s %d %d", transProps[t.type].name, t.duration, t.chunkSize);
|
|
stop = true;
|
|
break;
|
|
}
|
|
|
|
if (stop)
|
|
break;
|
|
|
|
_composeSurface->blitFrom(*blitFrom, rfrom, Common::Point(rto.left, rto.top));
|
|
|
|
g_system->delayMillis(t.stepDuration);
|
|
if (processQuitEvent(true)) {
|
|
exitTransition(&nextFrame, clipRect);
|
|
break;
|
|
}
|
|
|
|
if (fullredraw) {
|
|
stepTransition();
|
|
} else {
|
|
rto.clip(clipRect);
|
|
|
|
if (rto.height() > 0 && rto.width() > 0)
|
|
stepTransition();
|
|
}
|
|
|
|
g_lingo->executePerFrameHook(t.frame, i);
|
|
}
|
|
}
|
|
|
|
static int getLog2(int n) {
|
|
int res;
|
|
|
|
for (res = 0; n != 0; res++)
|
|
n >>= 1;
|
|
|
|
return res;
|
|
}
|
|
|
|
static uint32 randomSeed[33] = {
|
|
0x00000000UL,
|
|
0x00000000UL, 0x00000003UL, 0x00000006UL, 0x0000000cUL,
|
|
0x00000014UL, 0x00000030UL, 0x00000060UL, 0x000000b8UL,
|
|
0x00000110UL, 0x00000240UL, 0x00000500UL, 0x00000ca0UL,
|
|
0x00001b00UL, 0x00003500UL, 0x00006000UL, 0x0000b400UL,
|
|
0x00012000UL, 0x00020400UL, 0x00072000UL, 0x00090000UL,
|
|
0x00140000UL, 0x00300000UL, 0x00420000UL, 0x00d80000UL,
|
|
0x01200000UL, 0x03880000UL, 0x07200000UL, 0x09000000UL,
|
|
0x14000000UL, 0x32800000UL, 0x48000000UL, 0xa3000000UL
|
|
};
|
|
|
|
void Window::dissolveTrans(TransParams &t, Common::Rect &clipRect, Graphics::ManagedSurface *nextFrame) {
|
|
uint w = clipRect.width();
|
|
uint h = clipRect.height();
|
|
uint realw = w, realh = h;
|
|
byte pixmask[8];
|
|
|
|
memset(pixmask, 0, 8);
|
|
|
|
t.xStepSize = 1;
|
|
t.yStepSize = 1;
|
|
|
|
switch (t.type) {
|
|
case kTransDissolveBitsFast:
|
|
case kTransDissolveBits:
|
|
if (t.chunkSize >= 32) {
|
|
w = (w + 3) >> 2;
|
|
t.xStepSize = 4;
|
|
} else if (t.chunkSize >= 16) {
|
|
w = (w + 1) >> 1;
|
|
t.xStepSize = 2;
|
|
} else if (t.chunkSize >= 8) {
|
|
t.xStepSize = 1;
|
|
} else if (t.chunkSize >= 4) {
|
|
w <<= 1;
|
|
t.xStepSize = -2;
|
|
pixmask[0] = 0x0f;
|
|
pixmask[1] = 0xf0;
|
|
} else if (t.chunkSize >= 2) {
|
|
w <<= 2;
|
|
t.xStepSize = -4;
|
|
|
|
for (int i = 0; i < 4; i++)
|
|
pixmask[i] = 0x3 << (i * 2);
|
|
} else {
|
|
w <<= 3;
|
|
t.xStepSize = -8;
|
|
|
|
for (int i = 0; i < 8; i++)
|
|
pixmask[i] = 1 << i;
|
|
}
|
|
break;
|
|
|
|
case kTransRandomRows:
|
|
t.xStepSize = realw;
|
|
t.yStepSize = t.chunkSize;
|
|
w = 1;
|
|
h = (h + t.chunkSize - 1) / t.chunkSize;
|
|
break;
|
|
|
|
case kTransRandomColumns:
|
|
t.xStepSize = t.chunkSize;
|
|
t.yStepSize = realh;
|
|
w = (w + t.chunkSize - 1) / t.chunkSize;
|
|
h = 1;
|
|
break;
|
|
|
|
case kTransDissolveBoxyRects:
|
|
t.xStepSize = t.chunkSize;
|
|
t.yStepSize = t.chunkSize;
|
|
w = (w + t.chunkSize - 1) / t.chunkSize;
|
|
h = (h + t.chunkSize - 1) / t.chunkSize;
|
|
break;
|
|
|
|
case kTransDissolveBoxySquares:
|
|
t.xStepSize = MAX(w * t.chunkSize / h, (uint)1);
|
|
t.yStepSize = MAX(h * t.chunkSize / w, (uint)1);
|
|
|
|
w = (w + t.xStepSize - 1) / t.xStepSize;
|
|
h = (h + t.yStepSize - 1) / t.yStepSize;
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
int vBits = getLog2(w);
|
|
int hBits = getLog2(h);
|
|
uint32 rnd, seed;
|
|
|
|
if (hBits <= 0 || vBits <= 0)
|
|
return;
|
|
|
|
rnd = seed = randomSeed[hBits + vBits];
|
|
int hMask = (1L << hBits) - 1;
|
|
int vShift = hBits;
|
|
|
|
// Calculate steps
|
|
uint32 pixPerStepInit = 1;
|
|
t.steps = (1 << (hBits + vBits)) - 1;
|
|
|
|
while (t.steps > 64) {
|
|
pixPerStepInit <<= 1;
|
|
t.steps >>= 1;
|
|
}
|
|
t.steps++;
|
|
|
|
t.stepDuration = t.duration / t.steps;
|
|
|
|
if (t.type == kTransDissolvePixelsFast ||
|
|
t.type == kTransDissolveBitsFast)
|
|
t.stepDuration = 0; // No delay
|
|
|
|
Common::Rect r(MAX(1, t.xStepSize), t.yStepSize);
|
|
|
|
for (int i = 0; i < t.steps; i++) {
|
|
uint32 pixPerStep = pixPerStepInit;
|
|
do {
|
|
uint32 x = (rnd - 1) >> vShift;
|
|
uint32 y = (rnd - 1) & hMask;
|
|
byte mask = 0;
|
|
|
|
r.setWidth(MAX(1, t.xStepSize));
|
|
r.setHeight(t.yStepSize);
|
|
|
|
if (x < w && y < h) {
|
|
if (t.xStepSize >= 1) {
|
|
x = x * t.xStepSize;
|
|
y = y * t.yStepSize;
|
|
|
|
if (x < realw && y < realh) {
|
|
x += clipRect.left;
|
|
y += clipRect.top;
|
|
r.moveTo(x, y);
|
|
r.clip(clipRect);
|
|
|
|
if (!r.isEmpty())
|
|
_composeSurface->copyRectToSurface(*nextFrame, x, y, r);
|
|
}
|
|
} else {
|
|
mask = pixmask[x % -t.xStepSize];
|
|
x = x / -t.xStepSize;
|
|
|
|
x += clipRect.left;
|
|
y += clipRect.top;
|
|
|
|
byte *dst = (byte *)_composeSurface->getBasePtr(x, y);
|
|
byte *src = (byte *)nextFrame->getBasePtr(x, y);
|
|
|
|
*dst = ((*dst & ~mask) | (*src & mask)) & 0xff;
|
|
}
|
|
}
|
|
|
|
rnd = (rnd & 1) ? (rnd >> 1) ^ seed : rnd >> 1;
|
|
|
|
if (pixPerStep > 0) {
|
|
if (--pixPerStep == 0) {
|
|
break;
|
|
}
|
|
}
|
|
} while (rnd != seed);
|
|
|
|
stepTransition();
|
|
|
|
g_lingo->executePerFrameHook(t.frame, i + 1);
|
|
|
|
if (processQuitEvent(true)) {
|
|
exitTransition(nextFrame, clipRect);
|
|
break;
|
|
}
|
|
|
|
g_system->delayMillis(t.stepDuration);
|
|
}
|
|
}
|
|
|
|
static byte dissolvePatterns[][8] = {
|
|
{ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x80, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00 },
|
|
{ 0x88, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00 },
|
|
{ 0x88, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00 },
|
|
{ 0x88, 0x00, 0x20, 0x00, 0x88, 0x00, 0x00, 0x00 },
|
|
{ 0x88, 0x00, 0x20, 0x00, 0x88, 0x00, 0x02, 0x00 },
|
|
{ 0x88, 0x00, 0x22, 0x00, 0x88, 0x00, 0x02, 0x00 },
|
|
{ 0x88, 0x00, 0x22, 0x00, 0x88, 0x00, 0x22, 0x00 },
|
|
{ 0xa8, 0x00, 0x22, 0x00, 0x88, 0x00, 0x22, 0x00 },
|
|
{ 0xa8, 0x00, 0x22, 0x00, 0x8a, 0x00, 0x22, 0x00 },
|
|
{ 0xaa, 0x00, 0x22, 0x00, 0x8a, 0x00, 0x22, 0x00 },
|
|
{ 0xaa, 0x00, 0x22, 0x00, 0xaa, 0x00, 0x22, 0x00 },
|
|
{ 0xaa, 0x00, 0xa2, 0x00, 0xaa, 0x00, 0x22, 0x00 },
|
|
{ 0xaa, 0x00, 0xa2, 0x00, 0xaa, 0x00, 0x2a, 0x00 },
|
|
{ 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0x2a, 0x00 },
|
|
{ 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00 },
|
|
{ 0xaa, 0x40, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00 },
|
|
{ 0xaa, 0x40, 0xaa, 0x00, 0xaa, 0x04, 0xaa, 0x00 },
|
|
{ 0xaa, 0x44, 0xaa, 0x00, 0xaa, 0x04, 0xaa, 0x00 },
|
|
{ 0xaa, 0x44, 0xaa, 0x00, 0xaa, 0x44, 0xaa, 0x00 },
|
|
{ 0xaa, 0x44, 0xaa, 0x10, 0xaa, 0x44, 0xaa, 0x00 },
|
|
{ 0xaa, 0x44, 0xaa, 0x10, 0xaa, 0x44, 0xaa, 0x01 },
|
|
{ 0xaa, 0x44, 0xaa, 0x11, 0xaa, 0x44, 0xaa, 0x01 },
|
|
{ 0xaa, 0x44, 0xaa, 0x11, 0xaa, 0x44, 0xaa, 0x11 },
|
|
{ 0xaa, 0x54, 0xaa, 0x11, 0xaa, 0x44, 0xaa, 0x11 },
|
|
{ 0xaa, 0x54, 0xaa, 0x11, 0xaa, 0x45, 0xaa, 0x11 },
|
|
{ 0xaa, 0x55, 0xaa, 0x11, 0xaa, 0x45, 0xaa, 0x11 },
|
|
{ 0xaa, 0x55, 0xaa, 0x11, 0xaa, 0x55, 0xaa, 0x11 },
|
|
{ 0xaa, 0x55, 0xaa, 0x51, 0xaa, 0x55, 0xaa, 0x11 },
|
|
{ 0xaa, 0x55, 0xaa, 0x51, 0xaa, 0x55, 0xaa, 0x15 },
|
|
{ 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x15 },
|
|
{ 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55 },
|
|
{ 0xea, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55 },
|
|
{ 0xea, 0x55, 0xaa, 0x55, 0xae, 0x55, 0xaa, 0x55 },
|
|
{ 0xee, 0x55, 0xaa, 0x55, 0xae, 0x55, 0xaa, 0x55 },
|
|
{ 0xee, 0x55, 0xaa, 0x55, 0xee, 0x55, 0xaa, 0x55 },
|
|
{ 0xee, 0x55, 0xba, 0x55, 0xee, 0x55, 0xaa, 0x55 },
|
|
{ 0xee, 0x55, 0xba, 0x55, 0xee, 0x55, 0xab, 0x55 },
|
|
{ 0xee, 0x55, 0xbb, 0x55, 0xee, 0x55, 0xab, 0x55 },
|
|
{ 0xee, 0x55, 0xbb, 0x55, 0xee, 0x55, 0xbb, 0x55 },
|
|
{ 0xfe, 0x55, 0xbb, 0x55, 0xee, 0x55, 0xbb, 0x55 },
|
|
{ 0xfe, 0x55, 0xbb, 0x55, 0xef, 0x55, 0xbb, 0x55 },
|
|
{ 0xff, 0x55, 0xbb, 0x55, 0xef, 0x55, 0xbb, 0x55 },
|
|
{ 0xff, 0x55, 0xbb, 0x55, 0xff, 0x55, 0xbb, 0x55 },
|
|
{ 0xff, 0x55, 0xfb, 0x55, 0xff, 0x55, 0xbb, 0x55 },
|
|
{ 0xff, 0x55, 0xfb, 0x55, 0xff, 0x55, 0xbf, 0x55 },
|
|
{ 0xff, 0x55, 0xff, 0x55, 0xff, 0x55, 0xbf, 0x55 },
|
|
{ 0xff, 0x55, 0xff, 0x55, 0xff, 0x55, 0xff, 0x55 },
|
|
{ 0xff, 0xd5, 0xff, 0x55, 0xff, 0x55, 0xff, 0x55 },
|
|
{ 0xff, 0xd5, 0xff, 0x55, 0xff, 0x5d, 0xff, 0x55 },
|
|
{ 0xff, 0xdd, 0xff, 0x55, 0xff, 0x5d, 0xff, 0x55 },
|
|
{ 0xff, 0xdd, 0xff, 0x55, 0xff, 0xdd, 0xff, 0x55 },
|
|
{ 0xff, 0xdd, 0xff, 0x75, 0xff, 0xdd, 0xff, 0x55 },
|
|
{ 0xff, 0xdd, 0xff, 0x75, 0xff, 0xdd, 0xff, 0x57 },
|
|
{ 0xff, 0xdd, 0xff, 0x77, 0xff, 0xdd, 0xff, 0x57 },
|
|
{ 0xff, 0xdd, 0xff, 0x77, 0xff, 0xdd, 0xff, 0x77 },
|
|
{ 0xff, 0xfd, 0xff, 0x77, 0xff, 0xdd, 0xff, 0x77 },
|
|
{ 0xff, 0xfd, 0xff, 0x77, 0xff, 0xdf, 0xff, 0x77 },
|
|
{ 0xff, 0xff, 0xff, 0x77, 0xff, 0xdf, 0xff, 0x77 },
|
|
{ 0xff, 0xff, 0xff, 0x77, 0xff, 0xff, 0xff, 0x77 },
|
|
{ 0xff, 0xff, 0xff, 0xf7, 0xff, 0xff, 0xff, 0x77 },
|
|
{ 0xff, 0xff, 0xff, 0xf7, 0xff, 0xff, 0xff, 0x7f },
|
|
{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f },
|
|
{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }
|
|
};
|
|
|
|
void Window::dissolvePatternsTrans(TransParams &t, Common::Rect &clipRect, Graphics::ManagedSurface *nextFrame) {
|
|
t.steps = 64;
|
|
t.stepDuration = t.duration / t.steps;
|
|
|
|
for (int i = 0; i < t.steps; i++) {
|
|
for (int y = clipRect.top; y < clipRect.bottom; y++) {
|
|
byte pat = dissolvePatterns[i][y % 8];
|
|
byte *dst = (byte *)_composeSurface->getBasePtr(clipRect.left, y);
|
|
byte *src = (byte *)nextFrame->getBasePtr(clipRect.left, y);
|
|
|
|
for (int x = clipRect.left; x < clipRect.right;) {
|
|
byte mask = 0x80;
|
|
for (int b = 0; b < 8 && x < clipRect.right; b++, x++) {
|
|
if (pat & mask)
|
|
*dst = *src;
|
|
|
|
dst++;
|
|
src++;
|
|
mask >>= 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
stepTransition();
|
|
|
|
g_lingo->executePerFrameHook(t.frame, i + 1);
|
|
|
|
if (processQuitEvent(true)) {
|
|
exitTransition(nextFrame, clipRect);
|
|
break;
|
|
}
|
|
|
|
g_system->delayMillis(t.stepDuration);
|
|
}
|
|
}
|
|
|
|
void Window::transMultiPass(TransParams &t, Common::Rect &clipRect, Graphics::ManagedSurface *nextFrame) {
|
|
Common::Rect rto;
|
|
uint w = clipRect.width();
|
|
uint h = clipRect.height();
|
|
bool flag = false;
|
|
|
|
Common::Array<Common::Rect> rects;
|
|
|
|
for (uint16 i = 1; i < t.steps; i++) {
|
|
bool stop = false;
|
|
rto = clipRect;
|
|
|
|
switch (t.type) {
|
|
case kTransVenetianBlind: // 37
|
|
rto.setHeight(t.yStepSize * i);
|
|
for (int r = 0; r < kNumBlinds; r++) {
|
|
rto.moveTo(0, r * t.stripSize);
|
|
rects.push_back(rto);
|
|
}
|
|
break;
|
|
|
|
case kTransCheckerboard: // 38
|
|
rto.setWidth(t.stripSize);
|
|
rto.setHeight((i % ((t.steps + 1) / 2)) * t.chunkSize);
|
|
|
|
flag = i + i > t.steps;
|
|
|
|
for (int y = 0; y < t.yStepSize; y++) {
|
|
for (int x = 0; x < t.xStepSize; x++) {
|
|
if ((x & 2) ^ (y & 2) ^ (int)flag) {
|
|
rto.moveTo(x * t.stripSize, y * t.stripSize);
|
|
rects.push_back(rto);
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case kTransStripsBottomBuildLeft: // 39
|
|
for (int r = 0; r < kNumStrips; r++) {
|
|
int len = t.yStepSize * i - (kNumStrips - r - 1) * t.stripSize;
|
|
if (len > 0) {
|
|
rto.setHeight(len);
|
|
rto.setWidth(t.xStepSize);
|
|
rto.moveTo(t.xStepSize * r, h - len);
|
|
rects.push_back(rto);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case kTransStripsBottomBuildRight: // 40
|
|
for (int r = 0; r < kNumStrips; r++) {
|
|
int len = t.yStepSize * i - r * t.stripSize;
|
|
if (len > 0) {
|
|
rto.setHeight(len);
|
|
rto.setWidth(t.xStepSize);
|
|
rto.moveTo(t.xStepSize * r, h - len);
|
|
rects.push_back(rto);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case kTransStripsLeftBuildDown: // 41
|
|
for (int r = 0; r < kNumStrips; r++) {
|
|
int len = t.xStepSize * i - r * t.stripSize;
|
|
if (len > 0) {
|
|
rto.setWidth(len);
|
|
rto.setHeight(t.yStepSize);
|
|
rto.moveTo(0, t.yStepSize * r);
|
|
rects.push_back(rto);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case kTransStripsLeftBuildUp: // 42
|
|
for (int r = 0; r < kNumStrips; r++) {
|
|
int len = t.xStepSize * i - (kNumStrips - r - 1) * t.stripSize;
|
|
if (len > 0) {
|
|
rto.setWidth(len);
|
|
rto.setHeight(t.yStepSize);
|
|
rto.moveTo(0, t.yStepSize * r);
|
|
rects.push_back(rto);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case kTransStripsRightBuildDown: // 43
|
|
for (int r = 0; r < kNumStrips; r++) {
|
|
int len = t.xStepSize * i - r * t.stripSize;
|
|
if (len > 0) {
|
|
rto.setWidth(len);
|
|
rto.setHeight(t.yStepSize);
|
|
rto.moveTo(w - len, t.yStepSize * r);
|
|
rects.push_back(rto);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case kTransStripsRightBuildUp: // 44
|
|
for (int r = 0; r < kNumStrips; r++) {
|
|
int len = t.xStepSize * i - (kNumStrips - r - 1) * t.stripSize;
|
|
if (len > 0) {
|
|
rto.setWidth(len);
|
|
rto.setHeight(t.yStepSize);
|
|
rto.moveTo(w - len, t.yStepSize * r);
|
|
rects.push_back(rto);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case kTransStripsTopBuildLeft: // 45
|
|
for (int r = 0; r < kNumStrips; r++) {
|
|
int len = t.yStepSize * i - (kNumStrips - r - 1) * t.stripSize;
|
|
if (len > 0) {
|
|
rto.setHeight(len);
|
|
rto.setWidth(t.xStepSize);
|
|
rto.moveTo(t.xStepSize * r, 0);
|
|
rects.push_back(rto);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case kTransStripsTopBuildRight: // 46
|
|
for (int r = 0; r < kNumStrips; r++) {
|
|
int len = t.yStepSize * i - r * t.stripSize;
|
|
if (len > 0) {
|
|
rto.setHeight(len);
|
|
rto.setWidth(t.xStepSize);
|
|
rto.moveTo(t.xStepSize * r, 0);
|
|
rects.push_back(rto);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case kTransVerticalBinds: // 49
|
|
rto.setWidth(t.xStepSize * i);
|
|
for (int r = 0; r < kNumBlinds; r++) {
|
|
rto.moveTo(r * t.stripSize, 0);
|
|
rects.push_back(rto);
|
|
}
|
|
break;
|
|
|
|
default:
|
|
warning("Score::transMultiPass(): Unhandled transition type %s %d %d", transProps[t.type].name, t.duration, t.chunkSize);
|
|
stop = true;
|
|
break;
|
|
}
|
|
|
|
if (stop)
|
|
break;
|
|
|
|
for (uint r = 0; r < rects.size(); r++) {
|
|
rto = rects[r];
|
|
rto.translate(clipRect.left, clipRect.top);
|
|
rto.clip(clipRect);
|
|
|
|
if (rto.height() > 0 && rto.width() > 0) {
|
|
_composeSurface->blitFrom(*nextFrame, rto, Common::Point(rto.left, rto.top));
|
|
stepTransition();
|
|
}
|
|
}
|
|
rects.clear();
|
|
|
|
g_lingo->executePerFrameHook(t.frame, i);
|
|
|
|
g_system->delayMillis(t.stepDuration);
|
|
|
|
if (processQuitEvent(true)) {
|
|
exitTransition(nextFrame, clipRect);
|
|
break;
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
void Window::transZoom(TransParams &t, Common::Rect &clipRect, Graphics::ManagedSurface *nextFrame) {
|
|
Common::Rect r = clipRect;
|
|
uint w = clipRect.width();
|
|
uint h = clipRect.height();
|
|
|
|
t.steps += 2;
|
|
|
|
Graphics::MacPlotData pd(_composeSurface, nullptr, &g_director->_wm->getPatterns(), Graphics::kPatternCheckers, 0, 0, 1, 0);
|
|
|
|
for (uint16 i = 1; i < t.steps; i++) {
|
|
|
|
for (int s = 2; s >= 0; s--) {
|
|
if (i - s < 0 || i - s > t.steps - 2)
|
|
continue;
|
|
|
|
if (t.type == kTransZoomOpen) {
|
|
r.setHeight(t.yStepSize * (i - s) * 2);
|
|
r.setWidth(t.xStepSize * (i - s) * 2);
|
|
r.moveTo(w / 2 - t.xStepSize * (i - s), h / 2 - t.yStepSize * (i - s));
|
|
} else {
|
|
r.setHeight(h - t.yStepSize * (i - s) * 2);
|
|
r.setWidth(w - t.xStepSize * (i - s) * 2);
|
|
r.moveTo(t.xStepSize * (i - s), t.yStepSize * (i - s));
|
|
}
|
|
|
|
Graphics::drawLine(r.left, r.top, r.right, r.top, 0xffff, _wm->getDrawPixel(), &pd);
|
|
Graphics::drawLine(r.right, r.top, r.right, r.bottom, 0xffff, _wm->getDrawPixel(), &pd);
|
|
Graphics::drawLine(r.left, r.bottom, r.right, r.bottom, 0xffff, _wm->getDrawPixel(), &pd);
|
|
Graphics::drawLine(r.left, r.top, r.left, r.bottom, 0xffff, _wm->getDrawPixel(), &pd);
|
|
}
|
|
|
|
r.setHeight(t.yStepSize * i * 2);
|
|
r.setWidth(t.xStepSize * i * 2);
|
|
r.moveTo(w / 2 - t.xStepSize * i, h / 2 - t.yStepSize * i);
|
|
|
|
g_lingo->executePerFrameHook(t.frame, i);
|
|
|
|
g_system->delayMillis(t.stepDuration);
|
|
|
|
if (processQuitEvent(true)) {
|
|
exitTransition(nextFrame, clipRect);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
void Window::initTransParams(TransParams &t, Common::Rect &clipRect) {
|
|
int w = clipRect.width();
|
|
int h = clipRect.height();
|
|
int m = MIN(w, h);
|
|
TransitionAlgo a = transProps[t.type].algo;
|
|
|
|
if (a == kTransAlgoCenterOut || a == kTransAlgoEdgesIn || a == kTransAlgoZoom) {
|
|
w = (w + 1) >> 1; // round up
|
|
h = (h + 1) >> 1;
|
|
}
|
|
|
|
// If we requested fast transitions, speed everything up
|
|
// Ensure the chunksize isn't larger than the amount of pixels.
|
|
if (debugChannelSet(-1, kDebugFast))
|
|
t.chunkSize = MIN((uint) m, t.chunkSize*16);
|
|
|
|
switch (transProps[t.type].dir) {
|
|
case kTransDirHorizontal:
|
|
t.steps = w / t.chunkSize;
|
|
t.xStepSize = w / t.steps;
|
|
t.xpos = w % t.steps;
|
|
break;
|
|
|
|
case kTransDirVertical:
|
|
t.steps = h / t.chunkSize;
|
|
t.yStepSize = h / t.steps;
|
|
t.ypos = h % t.steps;
|
|
break;
|
|
|
|
case kTransDirBoth:
|
|
t.steps = m / t.chunkSize;
|
|
|
|
t.xStepSize = w / t.steps;
|
|
t.xpos = w % t.steps;
|
|
t.yStepSize = h / t.steps;
|
|
t.ypos = h % t.steps;
|
|
break;
|
|
|
|
case kTransDirStepsH:
|
|
t.xStepSize = t.chunkSize;
|
|
t.yStepSize = (h + kNumStrips - 1) / kNumStrips;
|
|
t.stripSize = (w + kNumStrips - 1) / kNumStrips;
|
|
t.steps = ((w + t.xStepSize - 1) / t.xStepSize) * 2;
|
|
break;
|
|
|
|
case kTransDirStepsV:
|
|
t.xStepSize = (w + kNumStrips - 1) / kNumStrips;
|
|
t.yStepSize = t.chunkSize;
|
|
t.stripSize = (h + kNumStrips - 1) / kNumStrips;
|
|
t.steps = ((h + t.yStepSize - 1) / t.yStepSize) * 2;
|
|
break;
|
|
|
|
case kTransDirCheckers:
|
|
if (w > h)
|
|
t.stripSize = (w + kNumStrips - 1) / kNumStrips;
|
|
else
|
|
t.stripSize = (h + kNumStrips - 1) / kNumStrips;
|
|
|
|
t.steps = ((t.stripSize + t.chunkSize - 1) / t.chunkSize) * 2 + 2;
|
|
t.xStepSize = (w + t.stripSize - 1) / t.stripSize; // number of checkers
|
|
t.yStepSize = (h + t.stripSize - 1) / t.stripSize; // number of checkers
|
|
break;
|
|
|
|
case kTransDirBlindsV:
|
|
t.xStepSize = t.chunkSize;
|
|
t.yStepSize = t.chunkSize;
|
|
t.stripSize = (w + kNumBlinds - 1) / kNumBlinds;
|
|
t.steps = (w + t.stripSize - 1) / t.stripSize;
|
|
break;
|
|
|
|
case kTransDirBlindsH:
|
|
t.xStepSize = t.chunkSize;
|
|
t.yStepSize = t.chunkSize;
|
|
t.stripSize = (h + kNumBlinds - 1) / kNumBlinds;
|
|
t.steps = (h + t.stripSize - 1) / t.stripSize;
|
|
break;
|
|
|
|
default:
|
|
t.steps = 1;
|
|
}
|
|
|
|
t.stepDuration = t.duration / t.steps;
|
|
}
|
|
|
|
} // End of namespace Director
|