[Scummvm-git-logs] scummvm master -> 291c1f64221661e3594924ae0b700fa01888ac0c
bluegr
noreply at scummvm.org
Wed Jul 1 06:10:54 UTC 2026
This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://api.github.com/repos/scummvm/scummvm .
Summary:
291c1f6422 NANCY: NANCY12: Implement the new data layout in OneBuildPuzzle
Commit: 291c1f64221661e3594924ae0b700fa01888ac0c
https://github.com/scummvm/scummvm/commit/291c1f64221661e3594924ae0b700fa01888ac0c
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2026-07-01T09:10:47+03:00
Commit Message:
NANCY: NANCY12: Implement the new data layout in OneBuildPuzzle
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 70a641b3b81..17a795ab9f4 100644
--- a/engines/nancy/action/puzzle/onebuildpuzzle.cpp
+++ b/engines/nancy/action/puzzle/onebuildpuzzle.cpp
@@ -125,7 +125,112 @@ void OneBuildPuzzle::registerGraphics() {
_finalAnimOverlay.registerGraphics();
}
+// Nancy12 (AR 166) reworked OneBuildPuzzle onto the shared PuzzleBase loader:
+// a fixed 513-byte header blob, followed by six variable-length "random sound"
+// blocks, then a variable-count array of the same 66-byte piece records used by
+// the older games. The piece array is no longer a fixed 20-slot block.
+void OneBuildPuzzle::readDataNancy12(Common::SeekableReadStream &stream) {
+ // --- PuzzleBase header blob (513 bytes) ---
+ readFilename(stream, _imageName); // 0x00
+ _freePlacement = stream.readByte(); // 0x21
+ _canRotateAll = stream.readByte(); // 0x22
+ stream.skip(6); // 0x23: rotation/zone config + placement-mode byte
+ _slotTolerance = stream.readSint16LE(); // 0x29
+
+ // 0x2b..0x11f: placement-mode byte, final-animation centering rect, filler
+ // count and the home-scatter zone. None are needed by this port.
+ stream.skip(0x120 - 0x2b);
+
+ readFilename(stream, _extraSoundName); // 0x120: final-animation atlas image
+ readRect(stream, _animRectA); // 0x141
+ readRect(stream, _animRectB); // 0x151
+ for (uint i = 0; i < 6; ++i) // 0x161
+ _animLayout[i] = stream.readSint16LE();
+ _animSound1.readNormal(stream); // 0x16d
+ _animSound2.readNormal(stream); // 0x19e
+ _hasFinalAnim = !_animRectA.isEmpty();
+
+ _solveScene.readData(stream); // 0x1cf
+ _cancelScene.readData(stream); // 0x1e8 (ends the 513-byte blob)
+
+ // --- Six random-sound blocks: pickup, rotate, drop, good, bad, completion ---
+ RandomSoundBlock blocks[6];
+ for (uint i = 0; i < 6; ++i)
+ blocks[i].readData(stream);
+
+ SoundDescription *sounds[6] = { &_pickupSound, &_rotateSound, &_dropSound,
+ &_goodPlacementSound, &_badPlacementSound, &_completionSound };
+ for (uint i = 0; i < 6; ++i) {
+ SoundDescription &s = *sounds[i];
+ s.name = blocks[i].names.empty() ? "NO SOUND" : blocks[i].names[0];
+ s.channelID = blocks[i].channel;
+ s.numLoops = blocks[i].numLoops;
+ s.volume = blocks[i].volume;
+ }
+
+ // The drop/good/bad sounds pick randomly between their alternatives, which are
+ // now the extra entries of the corresponding block.
+ Common::String *dropAlts[2] = { &_dropAlt1Filename, &_dropAlt2Filename };
+ Common::String *goodAlts[2] = { &_goodAlt1Filename, &_goodAlt2Filename };
+ Common::String *badAlts[2] = { &_badAlt1Filename, &_badAlt2Filename };
+ Common::String **altSets[3] = { dropAlts, goodAlts, badAlts };
+ const uint altBlocks[3] = { 2, 3, 4 };
+ for (uint i = 0; i < 3; ++i) {
+ for (uint a = 0; a < 2; ++a) {
+ const RandomSoundBlock &b = blocks[altBlocks[i]];
+ *altSets[i][a] = (b.names.size() > a + 1) ? b.names[a + 1] : "NO SOUND";
+ }
+ }
+
+ // Nancy12 puzzles no longer carry inline good/bad/completion text.
+ _goodTexts.resize(3);
+ _badTexts.resize(3);
+
+ // --- Piece array (variable count) ---
+ stream.readSint16LE(); // Secondary piece count (matches numPieces in practice)
+ _numPieces = stream.readUint16LE();
+
+ _pieces.resize(_numPieces);
+ for (uint i = 0; i < _numPieces; ++i) {
+ Piece &p = _pieces[i];
+
+ // Two source rects: altSrc = at-home art, srcRect = active art.
+ Common::Rect altSrc;
+ readRect(stream, altSrc);
+ readRect(stream, p.srcRect);
+ if (p.srcRect.isEmpty())
+ p.srcRect = altSrc;
+ else if (!altSrc.isEmpty())
+ p.altSrcRect = altSrc;
+
+ readRect(stream, p.slotRect);
+ readRect(stream, p.homeRect);
+ p.defaultRotation = stream.readByte();
+ // A piece is pre-placed only when this marker is exactly 10.
+ p.isPreRotated = stream.readByte() == 10;
+ }
+
+ // Optional placement-order arrays, each present only when its flag is set.
+ _orderedPlacement = stream.readByte() != 0;
+ if (_orderedPlacement) {
+ _placementOrder.resize(_numPieces);
+ for (uint i = 0; i < _numPieces; ++i)
+ _placementOrder[i] = stream.readSint16LE();
+ }
+
+ if (stream.readByte() != 0) {
+ _legacyPlacementOrder.resize(_numPieces);
+ for (uint i = 0; i < _numPieces; ++i)
+ _legacyPlacementOrder[i] = stream.readSint16LE();
+ }
+}
+
void OneBuildPuzzle::readData(Common::SeekableReadStream &stream) {
+ if (g_nancy->getGameType() >= kGameTypeNancy12) {
+ readDataNancy12(stream);
+ return;
+ }
+
const bool isNancy10 = g_nancy->getGameType() >= kGameTypeNancy10;
readFilename(stream, _imageName);
diff --git a/engines/nancy/action/puzzle/onebuildpuzzle.h b/engines/nancy/action/puzzle/onebuildpuzzle.h
index 1339cf87c88..753299539ac 100644
--- a/engines/nancy/action/puzzle/onebuildpuzzle.h
+++ b/engines/nancy/action/puzzle/onebuildpuzzle.h
@@ -42,6 +42,7 @@ public:
void registerGraphics() override;
void readData(Common::SeekableReadStream &stream) override;
+ void readDataNancy12(Common::SeekableReadStream &stream);
void execute() override;
void handleInput(NancyInput &input) override;
More information about the Scummvm-git-logs
mailing list