[Scummvm-git-logs] scummvm master -> 91386e917060da3059e46a5c93317a50fc1e7b13

bluegr noreply at scummvm.org
Fri Jun 5 22:08:23 UTC 2026


This automated email contains information about 3 new commits which have been
pushed to the 'scummvm' repo located at https://api.github.com/repos/scummvm/scummvm .

Summary:
a70c81f574 NANCY: Better search for case-insensitive convo texts in Nancy10+
3e03d26189 NANCY: Fix restoring the textbox after loading a saved game in Nancy10
91386e9170 NANCY: Add changes to onebuildpuzzle for Nancy10


Commit: a70c81f5745545d00e452c946869e7160fee6517
    https://github.com/scummvm/scummvm/commit/a70c81f5745545d00e452c946869e7160fee6517
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2026-06-06T01:08:08+03:00

Commit Message:
NANCY: Better search for case-insensitive convo texts in Nancy10+

Changed paths:
    engines/nancy/action/conversation.cpp


diff --git a/engines/nancy/action/conversation.cpp b/engines/nancy/action/conversation.cpp
index 64ad001d71e..5989b549e1f 100644
--- a/engines/nancy/action/conversation.cpp
+++ b/engines/nancy/action/conversation.cpp
@@ -185,13 +185,23 @@ void ConversationSound::readTerseCaptionText(Common::SeekableReadStream &stream)
 	const CVTX *convo = (const CVTX *)g_nancy->getEngineData("CONVO");
 	assert(convo);
 
-	// WORKAROUND: Return an empty string for captions that aren't found.
-	// Happens with some conversations in Nancy10 (e.g. when calling the Rawleys).
 	if (convo->texts.contains(key)) {
 		_text = convo->texts[key];
 	} else {
-		warning("Convo key not found: %s", key.c_str());
-		_text = "";
+		// Nancy10+ searched convo texts in a key insensitive way, but
+		// the possible permutations involve mainly the last character
+		// being upper or lower case, so just try that before giving up.
+		if (key[key.size() - 1] == toupper(key[key.size() - 1]))
+			key[key.size() - 1] = tolower(key[key.size() - 1]);
+		else
+			key[key.size() - 1] = toupper(key[key.size() - 1]);
+
+		if (convo->texts.contains(key)) {
+			_text = convo->texts[key];
+		} else {
+			warning("Convo key not found: %s", key.c_str());
+			_text = "";
+		}
 	}
 }
 


Commit: 3e03d2618964798f96c77bfbd48bd670559d6b7e
    https://github.com/scummvm/scummvm/commit/3e03d2618964798f96c77bfbd48bd670559d6b7e
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2026-06-06T01:08:09+03:00

Commit Message:
NANCY: Fix restoring the textbox after loading a saved game in Nancy10

Changed paths:
    engines/nancy/state/scene.cpp
    engines/nancy/ui/textbox.cpp


diff --git a/engines/nancy/state/scene.cpp b/engines/nancy/state/scene.cpp
index cb27b1b43cf..975ed3f5f37 100644
--- a/engines/nancy/state/scene.cpp
+++ b/engines/nancy/state/scene.cpp
@@ -1378,7 +1378,7 @@ void Scene::clearSceneData() {
 		_lightning->endLightning();
 	}
 
-	if (_textbox.hasBeenDrawn()) {
+	if (_textbox.hasBeenDrawn() || g_nancy->getGameType() >= kGameTypeNancy10) {
 		// Improvement: the dog portrait scenes in nancy7 queue a piece of text,
 		// then immediately change the scene. This makes the text disappear instantly;
 		// instead, we check if the textbox has been drawn, and don't clear it if it hasn't.
diff --git a/engines/nancy/ui/textbox.cpp b/engines/nancy/ui/textbox.cpp
index 9126feb4f38..a8248564fe3 100644
--- a/engines/nancy/ui/textbox.cpp
+++ b/engines/nancy/ui/textbox.cpp
@@ -258,11 +258,11 @@ void Textbox::drawTextbox() {
 
 	HypertextParser::drawAllText(textBounds, 0, baseFontID, highlightFontID);
 
-	setVisible(true);
+	setVisible(g_nancy->getGameType() <= kGameTypeNancy9 || _isFullMode);
 }
 
 void Textbox::clear() {
-	if (_textLines.size()) {
+	if (!_textLines.empty() || g_nancy->getGameType() >= kGameTypeNancy10) {
 		HypertextParser::clear();
 		if (_scrollbar) {
 			_scrollbar->resetPosition();


Commit: 91386e917060da3059e46a5c93317a50fc1e7b13
    https://github.com/scummvm/scummvm/commit/91386e917060da3059e46a5c93317a50fc1e7b13
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2026-06-06T01:08:13+03:00

Commit Message:
NANCY: Add changes to onebuildpuzzle for Nancy10

Fixes the egg basket jigsaw puzzle in Nancy10

Changed paths:
    engines/nancy/action/puzzle/onebuildpuzzle.cpp
    engines/nancy/action/puzzle/onebuildpuzzle.h


diff --git a/engines/nancy/action/puzzle/onebuildpuzzle.cpp b/engines/nancy/action/puzzle/onebuildpuzzle.cpp
index a49b1adfb4d..c8313c81e5b 100644
--- a/engines/nancy/action/puzzle/onebuildpuzzle.cpp
+++ b/engines/nancy/action/puzzle/onebuildpuzzle.cpp
@@ -91,6 +91,8 @@ void OneBuildPuzzle::registerGraphics() {
 }
 
 void OneBuildPuzzle::readData(Common::SeekableReadStream &stream) {
+	const bool isNancy10 = g_nancy->getGameType() >= kGameTypeNancy10;
+
 	readFilename(stream, _imageName);
 
 	_numPieces = stream.readUint16LE();
@@ -98,33 +100,66 @@ void OneBuildPuzzle::readData(Common::SeekableReadStream &stream) {
 	_canRotateAll = stream.readByte();
 	stream.skip(6); // rotationMode, zoneHeight, zoneWidth, mouse-clamping flag
 	_slotTolerance = stream.readSint16LE();
+
+	if (isNancy10) {
+		// TODO: purpose of this duplicate placement-order block is unknown.
+		_legacyOrderedFlag = stream.readByte() != 0;
+		_legacyPlacementOrder.resize(20);
+		for (uint i = 0; i < 20; ++i)
+			_legacyPlacementOrder[i] = stream.readSint16LE();
+	}
+
 	_orderedPlacement = stream.readByte();
 
 	_placementOrder.resize(20);
 	for (uint i = 0; i < 20; ++i)
 		_placementOrder[i] = stream.readSint16LE();
 
+	// Nancy 10 piece records add an alternative source rect at the front.
+	const uint pieceSize = isNancy10 ? 66 : 50;
+
 	_pieces.resize(_numPieces);
 	for (uint i = 0; i < 20; ++i) {
-		if (i < _numPieces) {
-			Piece &p = _pieces[i];
+		if (i >= _numPieces) {
+			stream.skip(pieceSize);
+			continue;
+		}
+
+		Piece &p = _pieces[i];
+		if (isNancy10) {
+			// Fall back to the alt rect when the primary one is empty.
+			Common::Rect altSrc;
+			readRect(stream, altSrc);
 			readRect(stream, p.srcRect);
-			readRect(stream, p.slotRect);
-			readRect(stream, p.homeRect);
-			p.defaultRotation = stream.readByte();
-			p.isPreRotated = stream.readByte();
+			if (p.srcRect.isEmpty())
+				p.srcRect = altSrc;
 		} else {
-			stream.skip(50);
+			readRect(stream, p.srcRect);
 		}
+		readRect(stream, p.slotRect);
+		readRect(stream, p.homeRect);
+		p.defaultRotation = stream.readByte();
+		p.isPreRotated = stream.readByte();
+	}
+
+	if (isNancy10) {
+		stream.skip(32); // TODO: 32 post-piece bytes, layout undecoded.
+		readFilename(stream, _extraSoundName);
+		readRect(stream, _animRectA);
+		readRect(stream, _animRectB);
+		for (uint i = 0; i < 6; ++i)
+			_animLayout[i] = stream.readSint16LE();
+		_animSound1.readNormal(stream);
+		_animSound2.readNormal(stream);
 	}
 
-	_pickupSound.readNormal(stream);  // +0x43e: played when rotating a placed piece
-	_rotateSound.readNormal(stream);  // +0x46f: played when picking up an unplaced piece
-	_dropSound.readNormal(stream);    // +0x4a0: played when dropping a piece
+	_pickupSound.readNormal(stream);
+	_rotateSound.readNormal(stream);
+	_dropSound.readNormal(stream);
 	readFilename(stream, _dropAlt1Filename);
 	readFilename(stream, _dropAlt2Filename);
 
-	_goodPlacementSound.readNormal(stream); // +0x513
+	_goodPlacementSound.readNormal(stream);
 	readFilename(stream, _goodAlt1Filename);
 	readFilename(stream, _goodAlt2Filename);
 
@@ -145,7 +180,7 @@ void OneBuildPuzzle::readData(Common::SeekableReadStream &stream) {
 	for (uint i = 0; i < 3; ++i)
 		readFilename(stream, unusedKey);
 
-	_badPlacementSound.readNormal(stream);  // +0x841
+	_badPlacementSound.readNormal(stream);
 	readFilename(stream, _badAlt1Filename);
 	readFilename(stream, _badAlt2Filename);
 
@@ -159,7 +194,7 @@ void OneBuildPuzzle::readData(Common::SeekableReadStream &stream) {
 	for (uint i = 0; i < 3; ++i)
 		readFilename(stream, unusedKey);
 
-	stream.skip(4); // unknown bytes at +0xb6f
+	stream.skip(4); // TODO: 4 bytes before solveScene, unknown.
 	_solveScene.readData(stream);
 	_completionSound.readNormal(stream);
 	readFilename(stream, unusedKey);
diff --git a/engines/nancy/action/puzzle/onebuildpuzzle.h b/engines/nancy/action/puzzle/onebuildpuzzle.h
index 5e7db6f8c0b..81f2d6f7c49 100644
--- a/engines/nancy/action/puzzle/onebuildpuzzle.h
+++ b/engines/nancy/action/puzzle/onebuildpuzzle.h
@@ -84,6 +84,22 @@ protected:
 	bool _orderedPlacement = false; // Pieces must be placed in a specific order
 	Common::Array<int16> _placementOrder; // 1-indexed piece IDs in required placement order
 
+	// --- Nancy 10 additions ---
+
+	// TODO: runtime role unknown; parsed for round-trip but not consumed.
+	bool _legacyOrderedFlag = false;
+	Common::Array<int16> _legacyPlacementOrder;
+
+	// Filename only (no SoundDescription metadata).
+	Common::String _extraSoundName;
+
+	// Completion sprite-sheet animation; TODO: not wired up.
+	Common::Rect _animRectA;
+	Common::Rect _animRectB;
+	int16 _animLayout[6] = {}; // cols, framesPerStep, baseX, baseY, spacing, totalRows
+	SoundDescription _animSound1;
+	SoundDescription _animSound2;
+
 	Common::Array<Piece> _pieces;
 
 	SoundDescription _pickupSound;




More information about the Scummvm-git-logs mailing list