[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