[Scummvm-git-logs] scummvm master -> 8c68e8c73a42def694d81eb3fede81a2b35cabb8
npjg
nathanael.gentrydb8 at gmail.com
Fri Jul 3 03:48:05 UTC 2020
This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
8c68e8c73a DIRECTOR: Implement changed area transitions
Commit: 8c68e8c73a42def694d81eb3fede81a2b35cabb8
https://github.com/scummvm/scummvm/commit/8c68e8c73a42def694d81eb3fede81a2b35cabb8
Author: Nathanael Gentry (nathanael.gentrydb8 at gmail.com)
Date: 2020-07-02T23:47:02-04:00
Commit Message:
DIRECTOR: Implement changed area transitions
No new transitions should be broken, but transitions that were broken
before (#9, 10, c. 30-36, 47-48) have not been fixed. All transitions (even
broken ones) should render only in the changed area, however.
Changed paths:
engines/director/transitions.cpp
diff --git a/engines/director/transitions.cpp b/engines/director/transitions.cpp
index 9b37f0880a..b9aa6e95a1 100644
--- a/engines/director/transitions.cpp
+++ b/engines/director/transitions.cpp
@@ -151,14 +151,41 @@ void Stage::playTransition(uint16 transDuration, uint8 transArea, uint8 transChu
// If a transition is being played, render the frame after the transition.
Graphics::ManagedSurface *nextFrame = new Graphics::ManagedSurface(_surface.w, _surface.h);
- g_director->getCurrentMovie()->getScore()->renderSprites(t.frame, kRenderForceUpdate);
- render(true, nextFrame);
- if (t.area)
- warning("STUB: Transition over changed area transition");
+ Common::Rect clipRect;
+ if (t.area) {
+ // Changed area transition
+ g_director->getCurrentMovie()->getScore()->renderSprites(t.frame);
- Common::Rect clipRect(_dims);
- clipRect.moveTo(0, 0);
+ 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;
+
+ _dirtyRects.push_back(clipRect);
+
+ render(false, nextFrame);
+ } else {
+ // Full stage transition
+ g_director->getCurrentMovie()->getScore()->renderSprites(t.frame, kRenderForceUpdate);
+ render(true, nextFrame);
+
+ clipRect = _dims;
+ clipRect.moveTo(0, 0);
+ }
Common::Rect rfrom, rto;
@@ -191,7 +218,7 @@ void Stage::playTransition(uint16 transDuration, uint8 transArea, uint8 transChu
blitFrom = nextFrame;
break;
- case kTransAlgoEdgesIn:
+ case kTransAlgoEdgesIn:
case kTransAlgoReveal:
case kTransAlgoPush:
blitFrom = currentFrame;
@@ -199,7 +226,7 @@ void Stage::playTransition(uint16 transDuration, uint8 transArea, uint8 transChu
break;
default:
- blitFrom = currentFrame;
+ blitFrom = nextFrame;
break;
}
@@ -212,8 +239,8 @@ void Stage::playTransition(uint16 transDuration, uint8 transArea, uint8 transChu
rfrom = clipRect;
if (transProps[t.type].algo == kTransAlgoReveal ||
- transProps[t.type].algo == kTransAlgoEdgesIn) {
- _surface.copyFrom(*nextFrame);
+ transProps[t.type].algo == kTransAlgoEdgesIn) {
+ _surface.copyRectToSurface(*nextFrame, clipRect.left, clipRect.top, clipRect);
}
switch (t.type) {
@@ -224,7 +251,7 @@ void Stage::playTransition(uint16 transDuration, uint8 transArea, uint8 transChu
case kTransWipeLeft: // 2
rto.setWidth(t.xStepSize * i);
- rto.moveTo(w - t.xStepSize * i, 0);
+ rto.translate(w - t.xStepSize * i, 0);
rfrom = rto;
break;
@@ -235,33 +262,33 @@ void Stage::playTransition(uint16 transDuration, uint8 transArea, uint8 transChu
case kTransWipeUp: // 4
rto.setHeight(t.yStepSize * i);
- rto.moveTo(0, h - 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.moveTo(w / 2 - t.xpos, 0);
+ rto.translate(w / 2 - t.xpos, 0);
rfrom = rto;
break;
case kTransEdgesInHorizontal: // 6
rto.setWidth(w - t.xStepSize * i * 2);
- rto.moveTo(t.xStepSize * i, 0);
+ rto.translate(t.xStepSize * i, 0);
rfrom = rto;
break;
case kTransCenterOutVertical: // 7
t.ypos += t.yStepSize;
rto.setHeight(t.ypos * 2);
- rto.moveTo(0, h / 2 - t.ypos);
+ rto.translate(0, h / 2 - t.ypos);
rfrom = rto;
break;
case kTransEdgesInVertical: // 8
rto.setHeight(h - t.yStepSize * i * 2);
- rto.moveTo(0, t.yStepSize * i);
+ rto.translate(0, t.yStepSize * i);
rfrom = rto;
break;
@@ -270,7 +297,7 @@ void Stage::playTransition(uint16 transDuration, uint8 transArea, uint8 transChu
rto.setHeight(t.ypos * 2);
t.xpos += t.xStepSize;
rto.setWidth(t.xpos * 2);
- rto.moveTo(w / 2 - t.xpos, h / 2 - t.ypos);
+ rto.translate(w / 2 - t.xpos, h / 2 - t.ypos);
rfrom = rto;
break;
@@ -282,75 +309,97 @@ void Stage::playTransition(uint16 transDuration, uint8 transArea, uint8 transChu
break;
case kTransPushLeft: // 11
- rto.moveTo(w - t.xStepSize * i, 0);
+ rto.translate(w - t.xStepSize * i, 0);
+ rfrom.right -= w - clipRect.findIntersectingRect(rto).width();
+ rto.clip(clipRect);
_surface.blitFrom(*nextFrame, rfrom, Common::Point(rto.left, rto.top));
- rfrom.moveTo(t.xStepSize * i, 0);
+ rfrom.translate(t.xStepSize * i, 0);
rfrom.setWidth(w - t.xStepSize * i);
- rto.moveTo(0, 0);
+ rto.moveTo(clipRect.left, clipRect.top);
break;
case kTransPushRight: // 12
- rfrom.moveTo(w - t.xStepSize * i, 0);
+ rfrom.translate(w - t.xStepSize * i, 0);
rfrom.setWidth(t.xStepSize * i);
_surface.blitFrom(*nextFrame, rfrom, Common::Point(rto.left, rto.top));
rto.setWidth(w - t.xStepSize * i);
- rto.moveTo(t.xStepSize * i, 0);
- rfrom.moveTo(0, 0);
+ rto.translate(t.xStepSize * i, 0);
+ rfrom.moveTo(clipRect.left, clipRect.top);
rfrom.setWidth(w - t.xStepSize * i);
break;
case kTransPushDown: // 13
- rfrom.moveTo(0, h - t.yStepSize * i);
+ rfrom.translate(0, h - t.yStepSize * i);
rfrom.setHeight(t.yStepSize * i);
_surface.blitFrom(*nextFrame, rfrom, Common::Point(rto.left, rto.top));
rto.setHeight(h - t.yStepSize * i);
- rto.moveTo(0, t.yStepSize * i);
- rfrom.moveTo(0, 0);
+ rto.translate(0, t.yStepSize * i);
+ rfrom.moveTo(clipRect.left, clipRect.top);
rfrom.setHeight(h - t.yStepSize * i);
break;
case kTransPushUp: // 14
- rto.moveTo(0, h - t.yStepSize * i);
+ rto.translate(0, h - t.yStepSize * i);
_surface.blitFrom(*nextFrame, rfrom, Common::Point(rto.left, rto.top));
- rfrom.moveTo(0, t.yStepSize * i);
+ rfrom.translate(0, t.yStepSize * i);
rfrom.setHeight(h - t.yStepSize * i);
- rto.moveTo(0, 0);
+ rto.moveTo(clipRect.left, clipRect.top);
break;
case kTransRevealUp: // 15
- rto.moveTo(0, -t.yStepSize * i);
+ rto.translate(0, -t.yStepSize * i);
+ rfrom.top += h - clipRect.findIntersectingRect(rto).height();
+ rto.clip(clipRect);
break;
case kTransRevealUpRight: // 16
- rto.moveTo(t.xStepSize * i, -t.yStepSize * i);
+ 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.moveTo(t.xStepSize * i, 0);
+ rto.translate(t.xStepSize * i, 0);
+ rfrom.right -= w - clipRect.findIntersectingRect(rto).width();
+ rto.clip(clipRect);
break;
case kTransRevealDownRight: // 18
- rto.moveTo(t.xStepSize * i, t.yStepSize * i);
+ 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.moveTo(0, t.yStepSize * i);
+ rto.translate(0, t.yStepSize * i);
+ rfrom.bottom -= h - clipRect.findIntersectingRect(rto).height();
+ rto.clip(clipRect);
break;
case kTransRevealDownLeft: // 20
- rto.moveTo(-t.xStepSize * i, t.yStepSize * i);
+ 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.moveTo(-t.xStepSize * i, 0);
+ 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
@@ -364,35 +413,55 @@ void Stage::playTransition(uint16 transDuration, uint8 transArea, uint8 transChu
case kTransCoverDown: // 29
rto.setHeight(h);
- rto.moveTo(0, t.yStepSize * i - h);
+ rto.translate(0, t.yStepSize * i - h);
+ rfrom.top += h - clipRect.findIntersectingRect(rto).height();
+ rto.clip(clipRect);
break;
case kTransCoverDownLeft: // 30
- rto.moveTo(w - t.xStepSize * i, t.yStepSize * i - h);
+ 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.moveTo(t.xStepSize * i - w, t.yStepSize * i - h);
+ 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.moveTo(w - t.xStepSize * i, 0);
+ rto.translate(w - t.xStepSize * i, 0);
+ rfrom.right -= w - clipRect.findIntersectingRect(rto).width();
+ rto.clip(clipRect);
break;
case kTransCoverRight: // 33
- rto.moveTo(t.xStepSize * i - w, 0);
+ rto.translate(t.xStepSize * i - w, 0);
+ rfrom.left += w - clipRect.findIntersectingRect(rto).width();
+ rto.clip(clipRect);
break;
case kTransCoverUp: // 34
- rto.moveTo(0, h - t.yStepSize * i);
+ rto.translate(0, h - t.yStepSize * i);
+ rfrom.bottom -= h - clipRect.findIntersectingRect(rto).height();
+ rto.clip(clipRect);
break;
case kTransCoverUpLeft: // 35
- rto.moveTo(w - t.xStepSize * i, h - t.yStepSize * i);
+ 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.moveTo(t.xStepSize * i - w, h - t.yStepSize * i);
+ 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
@@ -439,7 +508,7 @@ void Stage::playTransition(uint16 transDuration, uint8 transArea, uint8 transChu
break;
if (fullredraw) {
- g_system->copyRectToScreen(_surface.getPixels(), _surface.pitch, 0, 0, w, h);
+ g_system->copyRectToScreen(_surface.getBasePtr(clipRect.left, clipRect.top), _surface.pitch, clipRect.left, clipRect.top, w, h);
} else {
rto.clip(clipRect);
@@ -541,8 +610,8 @@ void Stage::dissolveTrans(TransParams &t, Common::Rect &clipRect, Graphics::Mana
break;
case kTransDissolveBoxySquares:
- t.xStepSize = w * t.chunkSize / h;
- t.yStepSize = h * t.chunkSize / w;
+ 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;
@@ -597,18 +666,25 @@ void Stage::dissolveTrans(TransParams &t, Common::Rect &clipRect, Graphics::Mana
y = y * t.yStepSize;
if (x < realw && y < realh) {
+ x += clipRect.left;
+ y += clipRect.top;
r.moveTo(x, y);
r.clip(clipRect);
- _surface.copyRectToSurface(*nextFrame, x, y, r);
+
+ if (!r.isEmpty())
+ _surface.copyRectToSurface(*nextFrame, x, y, r);
}
} else {
mask = pixmask[x % -t.xStepSize];
x = x / -t.xStepSize;
- byte *color1 = (byte *)_surface.getBasePtr(x, y);
- byte *color2 = (byte *)nextFrame->getBasePtr(x, y);
+ x += clipRect.left;
+ y += clipRect.top;
+
+ byte *dst = (byte *)_surface.getBasePtr(x, y);
+ byte *src = (byte *)nextFrame->getBasePtr(x, y);
- *color1 = ((*color1 & ~mask) | (*color2 & mask)) & 0xff;
+ *dst = ((*dst & ~mask) | (*src & mask)) & 0xff;
}
}
@@ -621,7 +697,7 @@ void Stage::dissolveTrans(TransParams &t, Common::Rect &clipRect, Graphics::Mana
}
} while (rnd != seed);
- g_system->copyRectToScreen(_surface.getPixels(), _surface.pitch, 0, 0, realw, realh);
+ g_system->copyRectToScreen(_surface.getBasePtr(clipRect.left, clipRect.top), _surface.pitch, clipRect.left, clipRect.top, clipRect.width(), clipRect.height());
g_system->updateScreen();
g_lingo->executePerFrameHook(t.frame, i + 1);
@@ -701,21 +777,18 @@ static byte dissolvePatterns[][8] = {
};
void Stage::dissolvePatternsTrans(TransParams &t, Common::Rect &clipRect, Graphics::ManagedSurface *nextFrame) {
- uint w = clipRect.width();
- uint h = clipRect.height();
-
t.steps = 64;
t.stepDuration = t.duration / t.steps;
for (int i = 0; i < t.steps; i++) {
- for (uint y = 0; y < h; y++) {
+ for (int y = clipRect.top; y < clipRect.bottom; y++) {
byte pat = dissolvePatterns[i][y % 8];
- byte *dst = (byte *)_surface.getBasePtr(0, y);
- byte *src = (byte *)nextFrame->getBasePtr(0, y);
+ byte *dst = (byte *)_surface.getBasePtr(clipRect.left, y);
+ byte *src = (byte *)nextFrame->getBasePtr(clipRect.left, y);
- for (uint x = 0; x < w;) {
+ for (int x = clipRect.left; x < clipRect.right;) {
byte mask = 0x80;
- for (int b = 0; b < 8 && x < w; b++, x++) {
+ for (int b = 0; b < 8 && x < clipRect.right; b++, x++) {
if (pat & mask)
*dst = *src;
@@ -726,7 +799,7 @@ void Stage::dissolvePatternsTrans(TransParams &t, Common::Rect &clipRect, Graphi
}
}
- g_system->copyRectToScreen(_surface.getPixels(), _surface.pitch, 0, 0, w, h);
+ g_system->copyRectToScreen(_surface.getBasePtr(clipRect.left, clipRect.top), _surface.pitch, clipRect.left, clipRect.top, clipRect.width(), clipRect.height());
g_system->updateScreen();
g_lingo->executePerFrameHook(t.frame, i + 1);
@@ -890,6 +963,7 @@ void Stage::transMultiPass(TransParams &t, Common::Rect &clipRect, Graphics::Man
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) {
More information about the Scummvm-git-logs
mailing list