[Scummvm-git-logs] scummvm master -> e697caa6c80011ed0b22d5051b893b7cddb2a6c9
bluegr
noreply at scummvm.org
Fri Jul 3 06:32:18 UTC 2026
This automated email contains information about 6 new commits which have been
pushed to the 'scummvm' repo located at https://api.github.com/repos/scummvm/scummvm .
Summary:
ca8ec48109 NANCY: NANCY10: Fix reading data for SecondaryVideo ARs
59a2d1830c NANCY: NANCY11: Implement changes to OrderingPuzzle
dcecf3935c NANCY: NANCY11: Further work on CardGamePuzzle
86d338dab0 NANCY: NANCY12: More work on the ActionZone fields
5052525d1a NANCY: NANCY10: Use the correct screen rect in the cellphone browser
e697caa6c8 NANCY: NANCY12: Fix light beam drawing in MirrorLightPuzzle
Commit: ca8ec48109e9cf4e553f9a030371f449cd534f4b
https://github.com/scummvm/scummvm/commit/ca8ec48109e9cf4e553f9a030371f449cd534f4b
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2026-07-03T09:32:04+03:00
Commit Message:
NANCY: NANCY10: Fix reading data for SecondaryVideo ARs
This fixes SecondaryVideo ARs going out of sync in Nancy11+ and reading
junk data. This allows us to remove a relevant hack for Nancy10
Changed paths:
engines/nancy/action/secondarymovie.cpp
engines/nancy/action/secondaryvideo.cpp
engines/nancy/commontypes.cpp
engines/nancy/commontypes.h
diff --git a/engines/nancy/action/secondarymovie.cpp b/engines/nancy/action/secondarymovie.cpp
index c504e75271e..2e4701d9952 100644
--- a/engines/nancy/action/secondarymovie.cpp
+++ b/engines/nancy/action/secondarymovie.cpp
@@ -312,17 +312,6 @@ void PlaySecondaryMovie::onPause(bool pause) {
void PlaySecondaryMovie::execute() {
switch (_state) {
case kBegin:
- // HACK: In Nancy 10, scene 2987, there are two PlaySecondaryMovie records that play
- // the same video, but have no dependencies. The first video leads to the losing scene,
- // while the second one leads to the winning scene. Since none of the two records has a
- // dependency, the first one will always be executed. It seems like there should be
- // a check to prevent the first record from being executed, but it wasn't possible to
- // find it. Don't start the first record for now, so that the second one can be
- // executed and the player can proceed.
- // TODO: Find out what the original engine does in this case, and implement it properly.
- if (g_nancy->getGameType() == kGameTypeNancy10 && _videoSceneChange == kMovieSceneChange && _sceneChange.sceneID == 2989)
- return;
-
init();
registerGraphics();
g_nancy->_sound->loadSound(_sound);
diff --git a/engines/nancy/action/secondaryvideo.cpp b/engines/nancy/action/secondaryvideo.cpp
index 25ad754dfd2..1c4491cad30 100644
--- a/engines/nancy/action/secondaryvideo.cpp
+++ b/engines/nancy/action/secondaryvideo.cpp
@@ -207,7 +207,7 @@ void PlaySecondaryVideo::readData(Common::SeekableReadStream &stream) {
_videoDescs.resize(numVideoDescs);
for (uint i = 0; i < numVideoDescs; ++i) {
- _videoDescs[i].readData(stream);
+ _videoDescs[i].readData(stream, true);
}
// Nancy 10+ stores the record's dependency block right after the video
diff --git a/engines/nancy/commontypes.cpp b/engines/nancy/commontypes.cpp
index 219a1c0b1da..703daebc2e0 100644
--- a/engines/nancy/commontypes.cpp
+++ b/engines/nancy/commontypes.cpp
@@ -128,12 +128,16 @@ void MultiEventFlagDescription::execute() {
}
}
-void SecondaryVideoDescription::readData(Common::SeekableReadStream &stream) {
+void SecondaryVideoDescription::readData(Common::SeekableReadStream &stream, bool hasTrailingRects) {
frameID = stream.readUint16LE();
readRect(stream, srcRect);
readRect(stream, destRect);
- if (g_nancy->getGameType() <= kGameTypeNancy10)
- stream.skip(0x20);
+ // PlaySecondaryVideo keeps the two trailing rects in every game, while
+ // PlaySecondaryMovie only has them up to Nancy 9 and dropped them afterwards.
+ if (hasTrailingRects || g_nancy->getGameType() <= kGameTypeNancy9) {
+ stream.skip(16);
+ stream.skip(16);
+ }
}
void SoundEffectDescription::readData(Common::SeekableReadStream &stream) {
diff --git a/engines/nancy/commontypes.h b/engines/nancy/commontypes.h
index 004c3b43387..65833886434 100644
--- a/engines/nancy/commontypes.h
+++ b/engines/nancy/commontypes.h
@@ -210,7 +210,7 @@ struct SecondaryVideoDescription {
Common::Rect destRect;
// 2 unknown/empty rects
- void readData(Common::SeekableReadStream &stream);
+ void readData(Common::SeekableReadStream &stream, bool hasTrailingRects = false);
};
// Describes set of effects that can be applied to sounds.
Commit: 59a2d1830c01da04508de12a75882a09c58b036b
https://github.com/scummvm/scummvm/commit/59a2d1830c01da04508de12a75882a09c58b036b
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2026-07-03T09:32:05+03:00
Commit Message:
NANCY: NANCY11: Implement changes to OrderingPuzzle
Fixes the Zodiac symbols puzzle
Changed paths:
engines/nancy/action/puzzle/orderingpuzzle.cpp
diff --git a/engines/nancy/action/puzzle/orderingpuzzle.cpp b/engines/nancy/action/puzzle/orderingpuzzle.cpp
index 766530b558e..d09fecf70b3 100644
--- a/engines/nancy/action/puzzle/orderingpuzzle.cpp
+++ b/engines/nancy/action/puzzle/orderingpuzzle.cpp
@@ -85,6 +85,11 @@ void OrderingPuzzle::readData(Common::SeekableReadStream &stream) {
ser.syncAsUint16LE(numElements);
}
+ // Nancy 11 bumped the base ordering puzzle's element cap from 15 to 16
+ if (_puzzleType == kOrdering && g_nancy->getGameType() >= kGameTypeNancy11) {
+ maxNumElements = 16;
+ }
+
switch (_puzzleType) {
case kOrderItems :
ser.syncAsByte(_hasSecondState);
Commit: dcecf3935c84f18f58bb1737c834b8c6bd92b509
https://github.com/scummvm/scummvm/commit/dcecf3935c84f18f58bb1737c834b8c6bd92b509
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2026-07-03T09:32:06+03:00
Commit Message:
NANCY: NANCY11: Further work on CardGamePuzzle
Makes the "Go fish" card game puzzle with Jane playable
Changed paths:
engines/nancy/action/puzzle/cardgamepuzzle.cpp
engines/nancy/action/puzzle/cardgamepuzzle.h
diff --git a/engines/nancy/action/puzzle/cardgamepuzzle.cpp b/engines/nancy/action/puzzle/cardgamepuzzle.cpp
index d1c3ab927fb..c536ae4e185 100644
--- a/engines/nancy/action/puzzle/cardgamepuzzle.cpp
+++ b/engines/nancy/action/puzzle/cardgamepuzzle.cpp
@@ -456,6 +456,39 @@ void CardGamePuzzle::execute() {
// The deal/match slide animations and the voiced lines come in a later stage.
}
+// A column is playable while the player (side 1) owns one or two cards in it - a column they are
+// building but have not yet completed. Depending on the scene the click target is either the bottom
+// button row or the player's own cards in the tableau.
+int CardGamePuzzle::columnUnderMouse(const Common::Point &mousePos) const {
+ if (usesColumnButtons()) {
+ for (int col = 0; col < (int)_numCols; ++col) {
+ if (_board[1].colCount[col] <= 0 || _board[1].colCount[col] >= 3) {
+ continue;
+ }
+
+ Common::Rect button = NancySceneState.getViewport().convertViewportToScreen(_columnButtons[col]);
+ if (button.contains(mousePos)) {
+ return col;
+ }
+ }
+ } else {
+ for (int row = 0; row < _numRows; ++row) {
+ for (int col = 0; col < (int)_numCols; ++col) {
+ if (_board[1].grid[row][col] != 1 || _board[1].colCount[col] >= 3) {
+ continue;
+ }
+
+ Common::Rect card = NancySceneState.getViewport().convertViewportToScreen(_faceDownSrc[row * kMaxCols + col]);
+ if (card.contains(mousePos)) {
+ return col;
+ }
+ }
+ }
+ }
+
+ return -1;
+}
+
void CardGamePuzzle::handleInput(NancyInput &input) {
if (_state != kRun || _awaitingEnd) {
return;
@@ -475,46 +508,27 @@ void CardGamePuzzle::handleInput(NancyInput &input) {
return;
}
- int opponent = _currentTurn ^ 1;
-
- for (int col = 0; col < (int)_numCols; ++col) {
- Common::Rect button = NancySceneState.getViewport().convertViewportToScreen(_columnButtons[col]);
- if (!button.contains(input.mousePos)) {
- continue;
- }
-
- // A column is playable only while the opponent still holds a card in it
- bool hasTarget = false;
- for (int row = 0; row < _numRows; ++row) {
- if (_board[opponent].grid[row][col] == 1) {
- hasTarget = true;
- break;
- }
- }
-
- if (!hasTarget) {
- return;
- }
+ int col = columnUnderMouse(input.mousePos);
+ if (col == -1) {
+ return;
+ }
- g_nancy->_cursor->setCursorType(CursorManager::kHotspot);
+ g_nancy->_cursor->setCursorType(CursorManager::kHotspot);
- if (input.input & NancyInput::kLeftMouseButtonUp) {
- bool before[kMaxRows][kMaxCols];
- for (int r = 0; r < kMaxRows; ++r)
- for (int c = 0; c < kMaxCols; ++c)
- before[r][c] = (_board[1].grid[r][c] == 1);
+ if (input.input & NancyInput::kLeftMouseButtonUp) {
+ bool before[kMaxRows][kMaxCols];
+ for (int r = 0; r < kMaxRows; ++r)
+ for (int c = 0; c < kMaxCols; ++c)
+ before[r][c] = (_board[1].grid[r][c] == 1);
- playVoice(_moveVoiceName);
- playColumn(col);
- finishMove();
+ playVoice(_moveVoiceName);
+ playColumn(col);
+ finishMove();
- // finishMove may have ended the game (kActionTrigger); only animate if still playing
- if (_state == kRun) {
- startMoveAnimation(before);
- }
+ // finishMove may have ended the game (kActionTrigger); only animate if still playing
+ if (_state == kRun) {
+ startMoveAnimation(before);
}
-
- return;
}
}
diff --git a/engines/nancy/action/puzzle/cardgamepuzzle.h b/engines/nancy/action/puzzle/cardgamepuzzle.h
index a251884481c..98f758d1ece 100644
--- a/engines/nancy/action/puzzle/cardgamepuzzle.h
+++ b/engines/nancy/action/puzzle/cardgamepuzzle.h
@@ -63,6 +63,11 @@ protected:
bool dealOne(int player); // draw a card from the deck to a side; false if the deck is empty
void drawBoard();
+ // True when the scene has a bottom button row (the player clicks those); false when it doesn't,
+ // in which case the player clicks their own cards in the tableau directly.
+ bool usesColumnButtons() const { return _columnButtons[0].top != _columnButtons[0].bottom; }
+ // The column the player is pointing at (owning 1-2 cards in it), or -1 if none is under the mouse.
+ int columnUnderMouse(const Common::Point &mousePos) const;
// Current side takes every opponent card in the given column; returns true if a card moved.
bool playColumn(int col);
int aiPickColumn(); // the AI's column choice, or -1 if it has no productive move
Commit: 86d338dab0548f3d5b3cb3f16ef5eb5ce9893c3c
https://github.com/scummvm/scummvm/commit/86d338dab0548f3d5b3cb3f16ef5eb5ce9893c3c
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2026-07-03T09:32:07+03:00
Commit Message:
NANCY: NANCY12: More work on the ActionZone fields
Changed paths:
engines/nancy/action/actionzone.cpp
engines/nancy/action/actionzone.h
diff --git a/engines/nancy/action/actionzone.cpp b/engines/nancy/action/actionzone.cpp
index dc8f730137e..aecb02f585f 100644
--- a/engines/nancy/action/actionzone.cpp
+++ b/engines/nancy/action/actionzone.cpp
@@ -59,8 +59,9 @@ void ActionZone::readData(Common::SeekableReadStream &stream) {
case 0x13:
readSpecialEffect(stream);
break;
- case 0x0b:
- stream.skip(3); // int16 + byte (plain, no peek)
+ case 0x0b: // collision zone: event-flag id + on/off
+ tailId = stream.readSint16LE();
+ tailFlag = stream.readByte();
break;
case 0x0e:
stream.skip(2); // int16
@@ -80,9 +81,10 @@ void ActionZone::readData(Common::SeekableReadStream &stream) {
case 2:
stream.skip(24); // Rect + int32 + int16 + int16
break;
- case 0x0c:
+ case 0x0c: // trigger zone: special effect + target scene id + flag
readSpecialEffect(stream);
- stream.skip(3); // int16 + byte
+ tailId = stream.readSint16LE();
+ tailFlag = stream.readByte();
break;
case 0x15:
readSpecialEffect(stream);
diff --git a/engines/nancy/action/actionzone.h b/engines/nancy/action/actionzone.h
index 9d359e15647..f2711a5644a 100644
--- a/engines/nancy/action/actionzone.h
+++ b/engines/nancy/action/actionzone.h
@@ -63,6 +63,12 @@ struct ActionZone {
int32 specialEffect[5] = {};
byte specialEffectFlag = 0;
+ // int16 + byte trailer carried by the collision (0x0b) and trigger (0x0c)
+ // subtypes. For 0x0b it is an event-flag id + on/off; for 0x0c it is a target
+ // scene id + a flag. Left at their defaults for the other subtypes.
+ int16 tailId = 0;
+ byte tailFlag = 0;
+
// OverlayZone subtypes (0x0d / 0x16)
Common::String overlayName;
Common::Array<Common::Rect> overlaySrcRects;
Commit: 5052525d1a9b727a113f3bbcd367e87bbb28ddd4
https://github.com/scummvm/scummvm/commit/5052525d1a9b727a113f3bbcd367e87bbb28ddd4
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2026-07-03T09:32:07+03:00
Commit Message:
NANCY: NANCY10: Use the correct screen rect in the cellphone browser
Fixes text being cut off in long search subjects
Changed paths:
engines/nancy/ui/cellphonepopup.cpp
diff --git a/engines/nancy/ui/cellphonepopup.cpp b/engines/nancy/ui/cellphonepopup.cpp
index 2fbfda3301b..bc55160ffbc 100644
--- a/engines/nancy/ui/cellphonepopup.cpp
+++ b/engines/nancy/ui/cellphonepopup.cpp
@@ -1251,16 +1251,25 @@ Common::Rect CellPhonePopup::directoryRowRect(uint visibleIndex) const {
const Common::Rect &ws = _uiclData->welcomeScreen.destRect;
const int pitch = rowPitch();
+ // The web / email lists render under the zoomed (keypad-hidden) chrome,
+ // where the LCD extends into the wider emailListContainer. Use that as
+ // the right bound so long entries aren't clipped to the narrow
+ // keypad-mode screen; the directory list keeps the small LCD.
+ const Common::Rect &lcd =
+ (isZoomedChromeState() && !_uiclData->emailListContainer.isEmpty())
+ ? _uiclData->emailListContainer
+ : ws;
+
// Row text spans from just right of the arrow cursor to a margin
- // inside the LCD's right edge (the -30 the original applies).
+ // inside the LCD's right edge.
int xLeftScreen, xRightScreen;
if (!cursor.isEmpty()) {
xLeftScreen = cursor.right + 5;
- xRightScreen = ws.right - 30;
+ xRightScreen = lcd.right - 30;
} else {
const Common::Rect &arrow = _uiclData->dirArrowSrc;
xLeftScreen = ws.left + arrow.width() + 4;
- xRightScreen = ws.right - 2;
+ xRightScreen = lcd.right - 2;
}
const int yTopScreen = rowTopScreen() + (int)visibleIndex * pitch;
Commit: e697caa6c80011ed0b22d5051b893b7cddb2a6c9
https://github.com/scummvm/scummvm/commit/e697caa6c80011ed0b22d5051b893b7cddb2a6c9
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2026-07-03T09:32:08+03:00
Commit Message:
NANCY: NANCY12: Fix light beam drawing in MirrorLightPuzzle
Changed paths:
engines/nancy/action/puzzle/mirrorlightpuzzle.cpp
engines/nancy/action/puzzle/mirrorlightpuzzle.h
engines/nancy/ui/viewport.h
diff --git a/engines/nancy/action/puzzle/mirrorlightpuzzle.cpp b/engines/nancy/action/puzzle/mirrorlightpuzzle.cpp
index 25b563b095b..7e0f6fa0699 100644
--- a/engines/nancy/action/puzzle/mirrorlightpuzzle.cpp
+++ b/engines/nancy/action/puzzle/mirrorlightpuzzle.cpp
@@ -34,16 +34,18 @@ namespace Nancy {
namespace Action {
// TODO - open items for this puzzle:
-// - Win/exit scene progression: the "solved" event flag is set outside the
-// puzzle data (not embedded here) and is still unidentified, so the scene
-// may not advance after a win.
-// - No exit/cancel path: how the player quits an unsolved puzzle is unknown.
-// - Win presentation: only a static lit-bulb overlay is drawn; the original
-// plays a bulb-lights-up animation with a sound cue - neither is wired up.
+// - Win/exit is fully EXTERNAL: the record has no scene-change of its own (its
+// scene-change vtable slot is null) and writes no scene state, so the scene
+// itself watches for the solved state and transitions. The exact signal (an
+// event flag?) is still unidentified, so on solve we just finishExecution and
+// the scene may not advance. The player's quit/cancel path is likewise unknown.
+// - Win presentation: the original lights the bulb via a per-zone movie
+// animation (loaded by the movie loader at init); we draw a single static
+// overlay frame with no sound instead.
// - Detector zone is chosen heuristically (any non-boundary zone away from the
-// source); the true detector zone is unconfirmed.
-// - Mirror rotation step (2 deg/click) and the glowing light-ray rendering are
-// approximations, not the original's exact behaviour.
+// source); the precise detector is the tiny boundary zone inside the bulb.
+// - Mirror rotation step (2 deg/click) approximates the original's exact
+// per-click amount.
void MirrorLightPuzzle::readData(Common::SeekableReadStream &stream) {
// 65-byte base header.
@@ -157,7 +159,13 @@ void MirrorLightPuzzle::traceBeam() {
}
if (hit != -1) {
- _beamPath.push_back(p);
+ // Bounce at the mirror's centre (not the edge where the beam entered),
+ // so the beam visually meets each mirror at its middle.
+ const Common::Rect &mr = _mirrors[hit].destRect;
+ px = (mr.left + mr.right) / 2.0;
+ py = (mr.top + mr.bottom) / 2.0;
+ _beamPath.push_back(Common::Point((int16)px, (int16)py));
+
// Reflect about the mirror's surface normal (its stored angle).
double nx = cos(_mirrors[hit].angle);
double ny = -sin(_mirrors[hit].angle);
@@ -187,6 +195,94 @@ void MirrorLightPuzzle::traceBeam() {
_beamPath.push_back(Common::Point((int16)(px + 0.5), (int16)(py + 0.5)));
}
+void MirrorLightPuzzle::drawBeamGlow() {
+ if (_beamPath.size() < 2) {
+ return;
+ }
+
+ const int w = _drawSurface.w;
+ const int h = _drawSurface.h;
+ // A soft Gaussian profile reads as a fuzzy, translucent light ray. peak is the
+ // additive intensity at the beam centre (well under 255 so the room shows
+ // through); sigma controls how quickly it fades; R clips the faint tail.
+ const int R = MAX<int>(4, _glowRadius + _glowRadius / 2);
+ const int R2 = R * R;
+ const double sigma = MAX<double>(1.5, _glowRadius / 2.0);
+ const double twoSigma2 = 2.0 * sigma * sigma;
+ const int peak = 110;
+
+ // Accumulate the max glow intensity per pixel (so overlapping stamps don't
+ // over-brighten), then composite once.
+ Common::Array<byte> intensity(w * h, 0);
+ for (uint s = 1; s < _beamPath.size(); ++s) {
+ const Common::Point &p0 = _beamPath[s - 1];
+ const Common::Point &p1 = _beamPath[s];
+ int dx = p1.x - p0.x;
+ int dy = p1.y - p0.y;
+ int len = MAX<int>(1, (int)sqrt((double)(dx * dx + dy * dy)));
+ for (int i = 0; i <= len; ++i) {
+ int cx = p0.x + dx * i / len;
+ int cy = p0.y + dy * i / len;
+ for (int oy = -R; oy <= R; ++oy) {
+ for (int ox = -R; ox <= R; ++ox) {
+ int px = cx + ox;
+ int py = cy + oy;
+ if (px < 0 || py < 0 || px >= w || py >= h) {
+ continue;
+ }
+ int d2 = ox * ox + oy * oy;
+ if (d2 > R2) {
+ continue;
+ }
+ int val = (int)(peak * exp(-(double)d2 / twoSigma2));
+ if (val <= 0) {
+ continue;
+ }
+ byte &acc = intensity[py * w + px];
+ if (val > acc) {
+ acc = (byte)val;
+ }
+ }
+ }
+ }
+ }
+
+ const Graphics::ManagedSurface &bg = NancySceneState.getViewport().getBackground();
+ const Graphics::PixelFormat &fmt = _drawSurface.format;
+ uint32 transColor = _drawSurface.getTransparentColor();
+
+ for (int y = 0; y < h; ++y) {
+ for (int x = 0; x < w; ++x) {
+ int inten = intensity[y * w + x];
+ if (inten == 0) {
+ continue;
+ }
+
+ // Skip actual mirror-sprite pixels (the mirror faces stay clean), but
+ // still glow over the transparent parts of a mirror's bounding box.
+ // Mirrors are the only thing drawn before the glow, so any opaque
+ // pixel here is a mirror pixel.
+ uint32 under = _drawSurface.getPixel(x, y);
+ if (under != transColor) {
+ continue;
+ }
+
+ // Glow over the scene background behind the beam.
+ byte r, g, b;
+ if (x < bg.w && y < bg.h) {
+ bg.format.colorToRGB(bg.getPixel(x, y), r, g, b);
+ } else {
+ r = g = b = 0;
+ }
+
+ r = (byte)MIN<int>(255, r + inten);
+ g = (byte)MIN<int>(255, g + inten);
+ b = (byte)MIN<int>(255, b + inten);
+ _drawSurface.setPixel(x, y, fmt.RGBToColor(r, g, b));
+ }
+ }
+}
+
void MirrorLightPuzzle::redraw() {
_drawSurface.clear(g_nancy->_graphics->getTransColor());
@@ -195,34 +291,9 @@ void MirrorLightPuzzle::redraw() {
drawMirror(i);
}
- // The beam as a round radial falloff (dim green-white outer -> bright white
- // core) to read as glowing light. TODO: the original composites actual
- // glowing light-ray sprites; a soft/additive glow is a follow-up.
- if (_beamPath.size() >= 2) {
- int t = MAX<int>(2, _glowRadius);
- uint32 colors[3] = {
- _drawSurface.format.RGBToColor(90, 120, 90), // outer haze
- _drawSurface.format.RGBToColor(180, 210, 180), // mid glow
- _drawSurface.format.RGBToColor(255, 255, 255) // core
- };
- int bands[3] = { t, t / 2, MAX<int>(1, t / 4) };
- // Outer band first so brighter bands land on top.
- for (int band = 0; band < 3; ++band) {
- int r = bands[band];
- for (uint i = 1; i < _beamPath.size(); ++i) {
- const Common::Point &p0 = _beamPath[i - 1];
- const Common::Point &p1 = _beamPath[i];
- for (int oy = -r; oy <= r; ++oy) {
- for (int ox = -r; ox <= r; ++ox) {
- if (ox * ox + oy * oy > r * r) {
- continue;
- }
- _drawSurface.drawLine(p0.x + ox, p0.y + oy, p1.x + ox, p1.y + oy, colors[band]);
- }
- }
- }
- }
- }
+ // The beam, composited additively over the mirrors and scene background so it
+ // reads as glowing light rather than flat lines.
+ drawBeamGlow();
// Once solved, light up the detector overlay (the bulb graphic).
if (_solved) {
diff --git a/engines/nancy/action/puzzle/mirrorlightpuzzle.h b/engines/nancy/action/puzzle/mirrorlightpuzzle.h
index 9c935e09dbe..9f8fe0ce728 100644
--- a/engines/nancy/action/puzzle/mirrorlightpuzzle.h
+++ b/engines/nancy/action/puzzle/mirrorlightpuzzle.h
@@ -85,6 +85,7 @@ protected:
void drawMirror(uint index);
void rotateMirror(uint index, bool clockwise);
void traceBeam();
+ void drawBeamGlow();
void redraw();
};
diff --git a/engines/nancy/ui/viewport.h b/engines/nancy/ui/viewport.h
index 7d3a8adb0e8..729c3b527fe 100644
--- a/engines/nancy/ui/viewport.h
+++ b/engines/nancy/ui/viewport.h
@@ -71,6 +71,10 @@ public:
uint16 getCurVerticalScroll() const { return _drawSurface.getOffsetFromOwner().y; }
uint16 getMaxScroll() const;
+ // The currently-visible scene background, in viewport-local coords. Used by
+ // puzzles that composite additively over the background (e.g. MirrorLight).
+ const Graphics::ManagedSurface &getBackground() const { return _drawSurface; }
+
Common::Rect convertViewportToScreen(const Common::Rect &viewportRect) const;
Common::Rect convertScreenToViewport(const Common::Rect &viewportRect) const;
More information about the Scummvm-git-logs
mailing list