[Scummvm-git-logs] scummvm master -> f7f856d40d821f9cf92102f8e9e656d778ada439

bluegr noreply at scummvm.org
Tue Jul 7 05:54:18 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:
1ba0d2ce40 NANCY: NANCY10: Remove non-existent variables from FrameTextBox
0ee6554c2b NANCY: NANCY11: Implement hand-delivery animation for CardGamePuzzle
f7f856d40d NANCY: Cleanup changing scene in OrderingPuzzle


Commit: 1ba0d2ce40009a5cb2a9e8a58f4bf2d0132d5997
    https://github.com/scummvm/scummvm/commit/1ba0d2ce40009a5cb2a9e8a58f4bf2d0132d5997
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2026-07-07T08:14:45+03:00

Commit Message:
NANCY: NANCY10: Remove non-existent variables from FrameTextBox

Changed paths:
    engines/nancy/action/miscrecords.cpp
    engines/nancy/action/miscrecords.h


diff --git a/engines/nancy/action/miscrecords.cpp b/engines/nancy/action/miscrecords.cpp
index 9cbd372b5a3..c0de26b1d90 100644
--- a/engines/nancy/action/miscrecords.cpp
+++ b/engines/nancy/action/miscrecords.cpp
@@ -211,11 +211,8 @@ void TextboxClear::execute() {
 void FrameTextBox::readData(Common::SeekableReadStream &stream) {
 	readTextboxText(stream, _text);
 
-	// Trailing two int16 fields: meaning differs slightly between the
-	// three opcodes that reuse this layout, but are safe to capture as a
-	// pair until UICO conversation rendering is wired up.
-	_flags = stream.readSint16LE();
-	_slot  = stream.readSint16LE();
+	// The original appends the "<e>" end-of-line hypertext tag to the caption
+	_text += "<e>";
 }
 
 void FrameTextBox::execute() {
diff --git a/engines/nancy/action/miscrecords.h b/engines/nancy/action/miscrecords.h
index c98b690bfd5..3ef861c8462 100644
--- a/engines/nancy/action/miscrecords.h
+++ b/engines/nancy/action/miscrecords.h
@@ -130,15 +130,13 @@ protected:
 // text into the new (UICO-driven) textbox
 class FrameTextBox : public ActionRecord {
 public:
-	FrameTextBox(bool fullMode) : _fullMode(fullMode), _flags(0), _slot(0) {}
+	FrameTextBox(bool fullMode) : _fullMode(fullMode) {}
 
 	void readData(Common::SeekableReadStream &stream) override;
 	void execute() override;
 
 	bool _fullMode;
 	Common::String _text;
-	int16 _flags;
-	int16 _slot;
 
 protected:
 	Common::String getRecordTypeName() const override { return "FrameTextBox"; }


Commit: 0ee6554c2bd9254db358b7f4d3e9f099349aaab7
    https://github.com/scummvm/scummvm/commit/0ee6554c2bd9254db358b7f4d3e9f099349aaab7
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2026-07-07T08:20:32+03:00

Commit Message:
NANCY: NANCY11: Implement hand-delivery animation for CardGamePuzzle

fixes showing the animation of Betty's hands dealing cards

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 6e8cc7a35d5..62d34aa2a91 100644
--- a/engines/nancy/action/puzzle/cardgamepuzzle.cpp
+++ b/engines/nancy/action/puzzle/cardgamepuzzle.cpp
@@ -79,9 +79,26 @@ void CardGamePuzzle::readData(Common::SeekableReadStream &stream) {
 	for (uint i = 0; i < _faceDownSrc.size(); ++i)
 		readRect(stream, _faceDownSrc[i]);
 
-	// 0x993: deal animation params + frames, then the voiced-line block (0xba3..0x1304, 33-byte
-	// name slots, per-side blocks 0x33d apart). Pull out the few lines we play; skip the rest.
-	stream.skip(0xbc4 - 0x993);                    // deal animation params + frames
+	// 0x993: per-turn hand-delivery animation (automaton variant), player (side 1) then Betty (side 0):
+	// {u16 frameCount, u16, u32 delay, 15 frame src rects, 1 delivery dest}. Empty in the grid variant.
+	_dealFrameCount[1] = stream.readUint16LE();    // 0x993
+	stream.skip(2);                                // 0x995
+	_dealFrameDelay[1] = stream.readUint32LE();    // 0x997
+	_dealFrames[1].resize(15);                     // 0x99b
+	for (uint i = 0; i < _dealFrames[1].size(); ++i)
+		readRect(stream, _dealFrames[1][i]);
+	readRect(stream, _deliverDest[1]);             // 0xa8b
+	_dealFrameCount[0] = stream.readUint16LE();    // 0xa9b
+	stream.skip(2);                                // 0xa9d
+	_dealFrameDelay[0] = stream.readUint32LE();    // 0xa9f
+	_dealFrames[0].resize(15);                     // 0xaa3
+	for (uint i = 0; i < _dealFrames[0].size(); ++i)
+		readRect(stream, _dealFrames[0][i]);
+	readRect(stream, _deliverDest[0]);             // 0xb93
+
+	// 0xba3: deal SFX name slot, then the voiced-line block (0xba3..0x1304, 33-byte name slots, per-
+	// side blocks 0x33d apart). Pull out the few lines we play; skip the rest.
+	stream.skip(0xbc4 - 0xba3);                    // deal SFX name
 	readFilename(stream, _moveVoiceName);          // 0xbc4
 	readFilename(stream, _dealVoiceName);          // 0xbe5
 	stream.skip(0xc2b - 0xc06);                    // 0xc06 deal SFX (alt)
@@ -200,6 +217,13 @@ void CardGamePuzzle::drawBoard() {
 			Common::Point(_turnHighlightDest[_currentTurn].left, _turnHighlightDest[_currentTurn].top));
 	}
 
+	// Automaton variant: the mover's hand-delivery sprite for the current frame.
+	if (_handAnimActive && _handFrame < _dealFrames[_handAnimSide].size()) {
+		const Common::Rect &src = _dealFrames[_handAnimSide][_handFrame];
+		const Common::Rect &dest = _deliverDest[_handAnimSide];
+		_drawSurface.blitFrom(_image, src, Common::Point(dest.left, dest.top));
+	}
+
 	_needsRedraw = true;
 }
 
@@ -269,6 +293,14 @@ void CardGamePuzzle::resolveAsk() {
 		}
 	}
 
+	// Automaton variant: the mover's hand delivers the card, cycling alongside the answer and slide.
+	if (_dealFrameCount[_mover] > 0) {
+		_handAnimActive = true;
+		_handAnimSide = _mover;
+		_handFrame = 0;
+		_handNextFrame = g_nancy->getTotalPlayTime() + _dealFrameDelay[_mover];
+	}
+
 	startMoveAnimation(before);
 	_phase = kAnswerSound;
 }
@@ -389,20 +421,34 @@ void CardGamePuzzle::startMoveAnimation(const bool beforeGrid[kMaxRows][kMaxCols
 }
 
 void CardGamePuzzle::updateGraphics() {
-	// Step any in-progress card slide first; the turn stays parked until it finishes.
-	if (_animating) {
-		if (g_nancy->getTotalPlayTime() < _animNextStep) {
-			return;
-		}
+	// Step any in-progress animations first; the turn stays parked until they finish. The card slide
+	// and the automaton hand-delivery sprite run on their own timers, concurrently.
+	uint32 now = g_nancy->getTotalPlayTime();
+	bool changed = false;
 
+	if (_animating && now >= _animNextStep) {
 		--_animStep;
-		_animNextStep = g_nancy->getTotalPlayTime() + _moveAnimDelay;
-
+		_animNextStep = now + _moveAnimDelay;
 		if (_animStep <= 0) {
 			_animating = false;
 		}
+		changed = true;
+	}
 
+	if (_handAnimActive && now >= _handNextFrame) {
+		++_handFrame;
+		_handNextFrame = now + _dealFrameDelay[_handAnimSide];
+		if (_handFrame >= _dealFrameCount[_handAnimSide]) {
+			_handAnimActive = false;
+		}
+		changed = true;
+	}
+
+	if (changed) {
 		drawBoard();
+	}
+
+	if (_animating || _handAnimActive) {
 		return;
 	}
 
@@ -500,6 +546,7 @@ void CardGamePuzzle::init() {
 	_gaveUp = false;
 	_animating = false;
 	_animStep = 0;
+	_handAnimActive = false;
 	_awaitingEnd = false;
 
 	// Opening deal: _dealRounds cards to each side, alternating
diff --git a/engines/nancy/action/puzzle/cardgamepuzzle.h b/engines/nancy/action/puzzle/cardgamepuzzle.h
index 352335a27ff..be2ce219dcb 100644
--- a/engines/nancy/action/puzzle/cardgamepuzzle.h
+++ b/engines/nancy/action/puzzle/cardgamepuzzle.h
@@ -110,6 +110,14 @@ protected:
 	uint16 _moveAnimDelta = 0;
 	uint32 _moveAnimDelay = 0;
 
+	// Automaton (Betty) variant: each turn a hand-delivery sprite is frame-cycled at a fixed slot,
+	// per side. Indexed by side (1 = player @0x993/0x99b/0xa8b, 0 = Betty @0xa9b/0xaa3/0xb93). The
+	// grid-vs-human variant leaves these empty (frame count 0), so the animation is simply skipped.
+	uint16 _dealFrameCount[2] = {};
+	uint32 _dealFrameDelay[2] = {};
+	Common::Array<Common::Rect> _dealFrames[2]; // hand-sprite frame src rects, by side
+	Common::Rect _deliverDest[2];               // where the hand sprite is drawn, by side
+
 	// Outcome scenes (data+0x1304 / 0x1320). The win block has two scene ids that share one set of
 	// transition params (frame/scroll/sound), held in _winScene; the id is chosen by the result.
 	uint16 _winSceneStartPlayer = 0; // data+0x1304
@@ -168,6 +176,12 @@ protected:
 	int _animStep = 0;
 	uint32 _animNextStep = 0;
 	bool _animating = false;
+
+	// The mover's hand-delivery sprite, cycled once per turn (automaton variant only).
+	bool _handAnimActive = false;
+	int _handAnimSide = 1;
+	uint16 _handFrame = 0;
+	uint32 _handNextFrame = 0;
 };
 
 } // End of namespace Action


Commit: f7f856d40d821f9cf92102f8e9e656d778ada439
    https://github.com/scummvm/scummvm/commit/f7f856d40d821f9cf92102f8e9e656d778ada439
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2026-07-07T08:30:55+03:00

Commit Message:
NANCY: Cleanup changing scene in OrderingPuzzle

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 532c14520ec..8e6fca0a82c 100644
--- a/engines/nancy/action/puzzle/orderingpuzzle.cpp
+++ b/engines/nancy/action/puzzle/orderingpuzzle.cpp
@@ -640,8 +640,7 @@ void OrderingPuzzle::execute() {
 		g_nancy->_sound->stopSound(_solveSound);
 
 		if (_stageDeath) {
-			NancySceneState.changeScene(_deathScene._sceneChange);
-			NancySceneState.setEventFlag(_deathScene._flag);
+			_deathScene.execute();
 		} else if (_solveState == kNotSolved) {
 			_exitScene.execute();
 		} else {




More information about the Scummvm-git-logs mailing list