[Scummvm-git-logs] scummvm master -> bcd1006a9f9b6c2b40a83fd6388696e26b89bd5c
bluegr
noreply at scummvm.org
Mon Jun 29 21:11:50 UTC 2026
This automated email contains information about 7 new commits which have been
pushed to the 'scummvm' repo located at https://api.github.com/repos/scummvm/scummvm .
Summary:
99ac983ee7 NANCY: NANCY12: Implement differences in RippedLetterPuzzle
56ef8f3aad NANCY: NANCY10: Use the correct white font for the text box
fe8bd554f5 NANCY: NANCY10: Fix cursors set from some ARs
2cee36c78c NANCY: NANCY12: Implement differences in MemoryPuzzle
3bff2e67b3 NANCY: NANCY12: Implement differences for SafeDialPuzzle
fdae801637 NANCY: NANCY12: Implement differences for TurningPuzzle
bcd1006a9f NANCY: NANCY12: Implement differences for TwoDialPuzzle
Commit: 99ac983ee71a3e0224605662bce086d4a172e232
https://github.com/scummvm/scummvm/commit/99ac983ee71a3e0224605662bce086d4a172e232
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2026-06-30T00:11:32+03:00
Commit Message:
NANCY: NANCY12: Implement differences in RippedLetterPuzzle
Changed paths:
engines/nancy/action/puzzle/rippedletterpuzzle.cpp
diff --git a/engines/nancy/action/puzzle/rippedletterpuzzle.cpp b/engines/nancy/action/puzzle/rippedletterpuzzle.cpp
index da4957803ed..74990ba1e82 100644
--- a/engines/nancy/action/puzzle/rippedletterpuzzle.cpp
+++ b/engines/nancy/action/puzzle/rippedletterpuzzle.cpp
@@ -120,8 +120,8 @@ void RippedLetterPuzzle::readData(Common::SeekableReadStream &stream) {
stream.skip((maxWidth > width ? (maxHeight - height) * maxWidth : maxWidth * maxHeight - width * height) * elemSize);
if (g_nancy->getGameType() >= kGameTypeNancy9) {
- uint16 numDoubledElements = stream.readUint16LE();
- _doubles.resize(numDoubledElements);
+ uint16 numDoubledElements = stream.readUint16LE(); // 0 in Nancy 12
+ _doubles.resize(numDoubledElements > 0 ? numDoubledElements : 20);
uint i = 0;
for (uint j = 0; j < 20; ++j) {
int16 id = stream.readSint16LE();
Commit: 56ef8f3aadb6a41393dcd2c20c0e7fc1c793ddee
https://github.com/scummvm/scummvm/commit/56ef8f3aadb6a41393dcd2c20c0e7fc1c793ddee
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2026-06-30T00:11:34+03:00
Commit Message:
NANCY: NANCY10: Use the correct white font for the text box
Partial fix for #16888
Changed paths:
engines/nancy/ui/scrolltextbox.cpp
diff --git a/engines/nancy/ui/scrolltextbox.cpp b/engines/nancy/ui/scrolltextbox.cpp
index 0c74fd0db84..6d1e7e5373d 100644
--- a/engines/nancy/ui/scrolltextbox.cpp
+++ b/engines/nancy/ui/scrolltextbox.cpp
@@ -131,7 +131,9 @@ void ScrollTextBox::drawContent() {
textBounds.top += _tboxData->scrollbarDefaultPos.y;
textBounds.left += _tboxData->scrollbarDefaultPos.x;
- const uint16 fontID = _fontIDOverride != -1 ? (uint16)_fontIDOverride : _tboxData->conversationFontID;
+ // Narration/caption text uses the (white) highlight font, not the (cyan)
+ // conversation body font that the ConversationPopup uses.
+ const uint16 fontID = _fontIDOverride != -1 ? (uint16)_fontIDOverride : _tboxData->highlightConversationFontID;
drawAllText(textBounds, 0, fontID, _tboxData->highlightConversationFontID);
// Two discrete states: "mini" (<= 2 lines) is a short strip above the
Commit: fe8bd554f5056cf652ef0bdb974dee3517f714aa
https://github.com/scummvm/scummvm/commit/fe8bd554f5056cf652ef0bdb974dee3517f714aa
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2026-06-30T00:11:34+03:00
Commit Message:
NANCY: NANCY10: Fix cursors set from some ARs
- Correctly flag cursors set from the EventFlagsMultiHS AR as
script-based
- Add another mapping table for the cursors set from the
HotSingleFrameSceneChange AR
Fix #16889
Changed paths:
engines/nancy/action/datarecords.cpp
engines/nancy/action/datarecords.h
engines/nancy/action/navigationrecords.cpp
engines/nancy/action/navigationrecords.h
diff --git a/engines/nancy/action/datarecords.cpp b/engines/nancy/action/datarecords.cpp
index 46bf2f41328..852248d260b 100644
--- a/engines/nancy/action/datarecords.cpp
+++ b/engines/nancy/action/datarecords.cpp
@@ -359,6 +359,12 @@ void EventFlagsMultiHS::readData(Common::SeekableReadStream &stream) {
}
}
+bool EventFlagsMultiHS::cursorSetFromScript() const {
+ if (g_nancy->getGameType() >= kGameTypeNancy10 && NancySceneState.getHeldItem() >= 0)
+ return false;
+ return _isCursor;
+}
+
CursorManager::CursorType EventFlagsMultiHS::getHoverCursor() const {
if (g_nancy->getGameType() >= kGameTypeNancy10 && NancySceneState.getHeldItem() >= 0)
return CursorManager::kHotspot;
diff --git a/engines/nancy/action/datarecords.h b/engines/nancy/action/datarecords.h
index 9dba69646af..cf4cecacb34 100644
--- a/engines/nancy/action/datarecords.h
+++ b/engines/nancy/action/datarecords.h
@@ -122,7 +122,7 @@ public:
void execute() override;
CursorManager::CursorType getHoverCursor() const override;
- bool cursorSetFromScript() const override { return true; }
+ bool cursorSetFromScript() const override;
CursorManager::CursorType _hoverCursor = CursorManager::kHotspot;
Common::Array<HotspotDescription> _hotspots;
diff --git a/engines/nancy/action/navigationrecords.cpp b/engines/nancy/action/navigationrecords.cpp
index cb37292cd28..6761c82da4e 100644
--- a/engines/nancy/action/navigationrecords.cpp
+++ b/engines/nancy/action/navigationrecords.cpp
@@ -82,8 +82,34 @@ void HotMultiframeSceneChange::execute() {
}
}
+// The hover cursor is stored as the id of the matching directional scene-change
+// action record type, which gets translated into the actual cursor to display.
+static CursorManager::CursorType getNavigationCursor(uint16 id) {
+ switch (id) {
+ case 14:
+ return CursorManager::kExit;
+ case 15:
+ case 23:
+ return CursorManager::kMoveForward;
+ case 16:
+ return CursorManager::kMoveBackward;
+ case 17:
+ case 24:
+ return CursorManager::kMoveUp;
+ case 18:
+ case 25:
+ return CursorManager::kMoveDown;
+ case 19:
+ return CursorManager::kMoveLeft;
+ case 20:
+ return CursorManager::kMoveRight;
+ default:
+ return CursorManager::kHotspot;
+ }
+}
+
void HotSingleFrameSceneChange::readData(Common::SeekableReadStream &stream) {
- _hoverCursor = (CursorManager::CursorType)stream.readUint16LE();
+ _hoverCursor = getNavigationCursor(stream.readUint16LE());
_sceneChange.sceneID = stream.readUint16LE();
_sceneChange.continueSceneSound = kContinueSceneSound;
_sceneChange.listenerFrontVector.set(0, 0, 1);
diff --git a/engines/nancy/action/navigationrecords.h b/engines/nancy/action/navigationrecords.h
index 45647d57f88..4d224fe2a55 100644
--- a/engines/nancy/action/navigationrecords.h
+++ b/engines/nancy/action/navigationrecords.h
@@ -52,7 +52,7 @@ public:
void execute() override;
CursorManager::CursorType getHoverCursor() const override { return _hoverCursor; }
- bool cursorSetFromScript() const override { return true; }
+ bool cursorSetFromScript() const override { return false; }
HotspotDescription _sceneHotspot;
Commit: 2cee36c78cdd8905e914cbc54adcbfb32edfa8ff
https://github.com/scummvm/scummvm/commit/2cee36c78cdd8905e914cbc54adcbfb32edfa8ff
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2026-06-30T00:11:35+03:00
Commit Message:
NANCY: NANCY12: Implement differences in MemoryPuzzle
Changed paths:
engines/nancy/action/puzzle/memorypuzzle.cpp
diff --git a/engines/nancy/action/puzzle/memorypuzzle.cpp b/engines/nancy/action/puzzle/memorypuzzle.cpp
index d70e39ac382..c67a21973d7 100644
--- a/engines/nancy/action/puzzle/memorypuzzle.cpp
+++ b/engines/nancy/action/puzzle/memorypuzzle.cpp
@@ -145,7 +145,7 @@ void MemoryPuzzle::readDataNancy11(Common::SeekableReadStream &stream) {
_winScene._sceneChange.continueSceneSound = stream.readUint16LE();
_winScene._flag.label = stream.readSint16LE();
_winScene._flag.flag = stream.readSint16LE() ? g_nancy->_true : g_nancy->_false;
- stream.skip(26); // alternate scene
+ stream.skip(g_nancy->getGameType() >= kGameTypeNancy12 ? 24 : 26); // alternate scene
}
// Shuffles type IDs (0..numPairs-1) into the 72-card array so that every type
Commit: 3bff2e67b38d0ddf1d80416b566dd672a9f743cc
https://github.com/scummvm/scummvm/commit/3bff2e67b38d0ddf1d80416b566dd672a9f743cc
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2026-06-30T00:11:36+03:00
Commit Message:
NANCY: NANCY12: Implement differences for SafeDialPuzzle
Changed paths:
engines/nancy/action/puzzle/safedialpuzzle.cpp
diff --git a/engines/nancy/action/puzzle/safedialpuzzle.cpp b/engines/nancy/action/puzzle/safedialpuzzle.cpp
index 3c6e6bdbc70..20de6afa520 100644
--- a/engines/nancy/action/puzzle/safedialpuzzle.cpp
+++ b/engines/nancy/action/puzzle/safedialpuzzle.cpp
@@ -90,7 +90,10 @@ void SafeDialPuzzle::updateGraphics() {
void SafeDialPuzzle::readData(Common::SeekableReadStream &stream) {
readFilename(stream, _imageName1);
readFilename(stream, _imageName2);
- readFilename(stream, _resetImageName);
+ if (g_nancy->getGameType() < kGameTypeNancy12) {
+ // Nancy 12 dropped the separate reset image from the header
+ readFilename(stream, _resetImageName);
+ }
_numInbetweens = (!_imageName2.empty() ? 1 : 0);
@@ -108,7 +111,7 @@ void SafeDialPuzzle::readData(Common::SeekableReadStream &stream) {
readRect(stream, _arrowDest);
readRect(stream, _arrowSrc);
- readRectArray(stream, _resetDialSrcs, 10);
+ readRectArray(stream, _resetDialSrcs, g_nancy->getGameType() >= kGameTypeNancy12 ? 12 : 10);
_resetTurns = stream.readUint16LE();
Commit: fdae801637d7c5187d670b7e0481f635e7238a2e
https://github.com/scummvm/scummvm/commit/fdae801637d7c5187d670b7e0481f635e7238a2e
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2026-06-30T00:11:37+03:00
Commit Message:
NANCY: NANCY12: Implement differences for TurningPuzzle
Changed paths:
engines/nancy/action/puzzle/turningpuzzle.cpp
diff --git a/engines/nancy/action/puzzle/turningpuzzle.cpp b/engines/nancy/action/puzzle/turningpuzzle.cpp
index 3c6476337b7..878e8fe1636 100644
--- a/engines/nancy/action/puzzle/turningpuzzle.cpp
+++ b/engines/nancy/action/puzzle/turningpuzzle.cpp
@@ -182,12 +182,22 @@ void TurningPuzzle::readData(Common::SeekableReadStream &stream) {
}
stream.skip((16 - numSpindles) * 2);
+ if (g_nancy->getGameType() >= kGameTypeNancy12) {
+ // Nancy 12 inserts 3 bytes here (zero in the samples seen); purpose unknown.
+ stream.skip(3);
+ }
+
_solveScene.readData(stream);
_solveSoundDelay = stream.readUint16LE();
_solveSound.readNormal(stream);
_exitScene.readData(stream);
readRect(stream, _exitHotspot);
+
+ if (g_nancy->getGameType() >= kGameTypeNancy12) {
+ // Nancy 12 appends a uint16 here (5 in the sample seen); purpose unknown.
+ stream.skip(2);
+ }
}
void TurningPuzzle::execute() {
Commit: bcd1006a9f9b6c2b40a83fd6388696e26b89bd5c
https://github.com/scummvm/scummvm/commit/bcd1006a9f9b6c2b40a83fd6388696e26b89bd5c
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2026-06-30T00:11:38+03:00
Commit Message:
NANCY: NANCY12: Implement differences for TwoDialPuzzle
Changed paths:
engines/nancy/action/puzzle/twodialpuzzle.cpp
engines/nancy/action/puzzle/twodialpuzzle.h
diff --git a/engines/nancy/action/puzzle/twodialpuzzle.cpp b/engines/nancy/action/puzzle/twodialpuzzle.cpp
index 8b74dbbf96e..e1021b188f2 100644
--- a/engines/nancy/action/puzzle/twodialpuzzle.cpp
+++ b/engines/nancy/action/puzzle/twodialpuzzle.cpp
@@ -64,18 +64,55 @@ void TwoDialPuzzle::readData(Common::SeekableReadStream &stream) {
readRectArray(stream, _srcs[0], num1, 20);
readRectArray(stream, _srcs[1], num2, 20);
- _correctPositions[0] = stream.readUint16LE();
- _correctPositions[1] = stream.readUint16LE();
+ if (g_nancy->getGameType() < kGameTypeNancy12) {
+ _correctPositions[0] = stream.readUint16LE();
+ _correctPositions[1] = stream.readUint16LE();
+ }
_rotateSounds[0].readNormal(stream);
_rotateSounds[1].readNormal(stream);
- _solveScene.readData(stream);
- _solveSoundDelay = stream.readUint16LE();
- _solveSound.readNormal(stream);
+ if (g_nancy->getGameType() >= kGameTypeNancy12) {
+ // Nancy 12 reworked this puzzle (see execute()): the single correctPositions
+ // pair was replaced by an event-flag-gated solution list at the end. The
+ // solve scene here carries NO sceneID of its own (it is taken from the matched
+ // solution), so it is read manually starting from the frameID.
+ _solveScene._sceneChange.frameID = stream.readUint16LE();
+ _solveScene._sceneChange.verticalOffset = stream.readUint16LE();
+ _solveScene._sceneChange.continueSceneSound = stream.readUint16LE();
+ int32 x = stream.readSint32LE();
+ int32 y = stream.readSint32LE();
+ int32 z = stream.readSint32LE();
+ _solveScene._sceneChange.listenerFrontVector.set(x, y, z);
+ _solveScene._sceneChange.frontVectorFrameID = _solveScene._sceneChange.frameID;
+ stream.skip(2); // shouldStopRendering
+ _solveScene._flag.label = stream.readSint16LE();
+ _solveScene._flag.flag = stream.readByte();
+
+ _solveSoundDelay = stream.readUint16LE();
+ _solveSound.readNormal(stream);
+
+ _exitScene.readData(stream);
+ stream.skip(2); // unknown
+ readRect(stream, _exitHotspot);
+
+ uint16 numSolutions = stream.readUint16LE();
+ _solutions.resize(numSolutions);
+ for (uint i = 0; i < numSolutions; ++i) {
+ _solutions[i].positions[0] = stream.readUint16LE();
+ _solutions[i].positions[1] = stream.readUint16LE();
+ _solutions[i].sceneID = stream.readUint16LE();
+ _solutions[i].condition.label = stream.readSint16LE();
+ _solutions[i].condition.flag = stream.readByte();
+ }
+ } else {
+ _solveScene.readData(stream);
+ _solveSoundDelay = stream.readUint16LE();
+ _solveSound.readNormal(stream);
- _exitScene.readData(stream);
- readRect(stream, _exitHotspot);
+ _exitScene.readData(stream);
+ readRect(stream, _exitHotspot);
+ }
}
void TwoDialPuzzle::execute() {
@@ -100,7 +137,24 @@ void TwoDialPuzzle::execute() {
return;
}
- if ((uint)_currentPositions[0] == _correctPositions[0] && (uint)_currentPositions[1] == _correctPositions[1]) {
+ if (g_nancy->getGameType() >= kGameTypeNancy12) {
+ // A combo solves only while one of its solutions is active: the dial
+ // positions match and that solution's condition flag is currently set.
+ // The matched solution supplies the scene to change to.
+ for (uint i = 0; i < _solutions.size(); ++i) {
+ const DialSolution &sol = _solutions[i];
+ if (sol.sceneID != 9999 &&
+ _currentPositions[0] == sol.positions[0] &&
+ _currentPositions[1] == sol.positions[1] &&
+ NancySceneState.getEventFlag(sol.condition.label, sol.condition.flag)) {
+ _solveScene._sceneChange.sceneID = sol.sceneID;
+ _state = kActionTrigger;
+ _isSolved = true;
+ _solveSoundDelayTime = g_nancy->getTotalPlayTime() + (_solveSoundDelay * 1000);
+ break;
+ }
+ }
+ } else if ((uint)_currentPositions[0] == _correctPositions[0] && (uint)_currentPositions[1] == _correctPositions[1]) {
_state = kActionTrigger;
_isSolved = true;
_solveSoundDelayTime = g_nancy->getTotalPlayTime() + (_solveSoundDelay * 1000);
diff --git a/engines/nancy/action/puzzle/twodialpuzzle.h b/engines/nancy/action/puzzle/twodialpuzzle.h
index b4ae24c33d2..ce2948812df 100644
--- a/engines/nancy/action/puzzle/twodialpuzzle.h
+++ b/engines/nancy/action/puzzle/twodialpuzzle.h
@@ -56,6 +56,16 @@ protected:
uint16 _correctPositions[2] = { 0, 0 };
+ // Nancy 12+ replaced the single correctPositions pair with a list of
+ // event-flag-gated solutions: a combo only solves while its condition flag
+ // matches, and it changes to its own target scene.
+ struct DialSolution {
+ uint16 positions[2] = { 0, 0 };
+ uint16 sceneID = 0;
+ FlagDescription condition;
+ };
+ Common::Array<DialSolution> _solutions;
+
SoundDescription _rotateSounds[2];
SceneChangeWithFlag _solveScene;
More information about the Scummvm-git-logs
mailing list