[Scummvm-git-logs] scummvm master -> e2cdf0b484dd70020157798059d24ed2748c2879
bluegr
noreply at scummvm.org
Thu Jul 16 17:26:34 UTC 2026
This automated email contains information about 2 new commits which have been
pushed to the 'scummvm' repo located at https://api.github.com/repos/scummvm/scummvm .
Summary:
affd2c50ca NANCY: NANCY14: Map new/changed Action Records
e2cdf0b484 NANCY: NANCY14: Implement differences in SecondaryMovie
Commit: affd2c50ca982658411e3e9869fa949aa0d2c229
https://github.com/scummvm/scummvm/commit/affd2c50ca982658411e3e9869fa949aa0d2c229
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2026-07-16T20:26:26+03:00
Commit Message:
NANCY: NANCY14: Map new/changed Action Records
Changed paths:
engines/nancy/action/arfactory.cpp
diff --git a/engines/nancy/action/arfactory.cpp b/engines/nancy/action/arfactory.cpp
index 9034a9cf00e..a289a62a75f 100644
--- a/engines/nancy/action/arfactory.cpp
+++ b/engines/nancy/action/arfactory.cpp
@@ -195,6 +195,22 @@ ActionRecord *ActionManager::createActionRecord(uint16 type, Common::SeekableRea
return new PlaySecondaryMovie(true);
case 46: // Nancy11
return new PlayRandomMovieControl();
+ // Nancy14 dispatches the secondary-movie family from 41-47 instead of the
+ // legacy 50-53 slots. Only the Nancy14 layout is verified; earlier games
+ // stay unmapped here.
+ case 41: // PlaySecondaryMovie
+ case 44: // PlaySecondaryMovie (adds a trailing volume byte)
+ if (g_nancy->getGameType() >= kGameTypeNancy14)
+ return new PlaySecondaryMovie();
+ return nullptr;
+ case 42: // PlaySecondaryMovie, random-sequence variant
+ case 43:
+ if (g_nancy->getGameType() >= kGameTypeNancy14)
+ return new PlaySecondaryMovie(true);
+ return nullptr;
+ case 47: // PlaySecondaryMovie subclass with a per-frame flag list
+ // TODO: not yet implemented
+ return nullptr;
case 40:
if (g_nancy->getGameType() <= kGameTypeNancy1)
return new LightningOn(); // Only used in TVD
@@ -377,6 +393,13 @@ ActionRecord *ActionManager::createActionRecord(uint16 type, Common::SeekableRea
return new AddSearchLink();
case 132: // Nancy12
return new ResourceUse();
+ case 133: // Nancy14: new AR, unidentified
+ // TODO: not yet implemented
+ return nullptr;
+ case 143: // Nancy14: new paired AR, unidentified
+ case 144:
+ // TODO: not yet implemented
+ return nullptr;
case 140:
if (g_nancy->getGameType() >= kGameTypeNancy12)
return new SetPlayerClock(); // Moved from 170 in Nancy12
@@ -387,19 +410,17 @@ ActionRecord *ActionManager::createActionRecord(uint16 type, Common::SeekableRea
// Saves a cropped image of the screen to a bitmap/TGA file.
// TODO: debug-only feature, not implemented
return nullptr;
- case 145:
- // Nancy13 moved PlaySound here (was 150).
+ case 145: // Nancy13
if (g_nancy->getGameType() >= kGameTypeNancy13)
- return new PlaySound();
+ return new PlaySound(); // Moved from 150 in Nancy13
return nullptr;
- case 146:
- // Nancy13: FadeSoundToSilence moved here (was 147).
+ case 146: // Nancy13
if (g_nancy->getGameType() >= kGameTypeNancy13)
- return new FadeSoundToSilence();
+ return new FadeSoundToSilence(); // Moved from 147 in Nancy13
return nullptr;
- case 147:
+ case 147: // Nancy11
if (g_nancy->getGameType() >= kGameTypeNancy13)
- return new SetVolume(); // Nancy13: SetVolume moved here (was 148)
+ return new SetVolume(); // Moved from 148 in Nancy13
return new FadeSoundToSilence(); // Nancy11
case 148:
if (g_nancy->getGameType() >= kGameTypeNancy13)
@@ -419,6 +440,8 @@ ActionRecord *ActionManager::createActionRecord(uint16 type, Common::SeekableRea
else
return nullptr;
case 150:
+ if (g_nancy->getGameType() >= kGameTypeNancy14)
+ return nullptr; // Nancy14: SetMovieVolume, TODO. PlaySound moved to 145 in Nancy13.
return new PlaySound();
case 151:
if (g_nancy->getGameType() <= kGameTypeNancy6) {
@@ -441,6 +464,8 @@ ActionRecord *ActionManager::createActionRecord(uint16 type, Common::SeekableRea
case 158:
return new PlayRandomSound();
case 159:
+ if (g_nancy->getGameType() >= kGameTypeNancy14)
+ return nullptr; // Nancy14: new AR here, not PlaySoundTerse. TODO.
return new PlaySoundTerse();
case 160:
// In Nancy12 the hint system was removed (the HINT boot chunk is gone) and this
@@ -508,6 +533,25 @@ ActionRecord *ActionManager::createActionRecord(uint16 type, Common::SeekableRea
// Unknown Puzzle, new in Nancy13
// TODO: not yet implemented
return nullptr;
+ // -- Nancy14 new puzzles (types 177-182) --
+ case 177: // HangmanPuzzle
+ // TODO: not yet implemented
+ return nullptr;
+ case 178: // logic-grid / crossword-like puzzle, unconfirmed
+ // TODO: not yet implemented
+ return nullptr;
+ case 179: // small utility AR, unconfirmed
+ // TODO: not yet implemented
+ return nullptr;
+ case 180: // movie-driven puzzle, unconfirmed
+ // TODO: not yet implemented
+ return nullptr;
+ case 181: // image/hotspot puzzle, unconfirmed
+ // TODO: not yet implemented
+ return nullptr;
+ case 182: // word puzzle, unconfirmed
+ // TODO: not yet implemented
+ return nullptr;
case 200:
return new SoundEqualizerPuzzle();
case 201:
Commit: e2cdf0b484dd70020157798059d24ed2748c2879
https://github.com/scummvm/scummvm/commit/e2cdf0b484dd70020157798059d24ed2748c2879
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2026-07-16T20:26:27+03:00
Commit Message:
NANCY: NANCY14: Implement differences in SecondaryMovie
The game (including the new menu system) now starts
Changed paths:
engines/nancy/action/secondarymovie.cpp
engines/nancy/action/secondarymovie.h
diff --git a/engines/nancy/action/secondarymovie.cpp b/engines/nancy/action/secondarymovie.cpp
index e8656d340ef..70854e4e200 100644
--- a/engines/nancy/action/secondarymovie.cpp
+++ b/engines/nancy/action/secondarymovie.cpp
@@ -209,6 +209,52 @@ int PlaySecondaryMovie::rollNextSequence() {
return -1;
}
+// Nancy14 compacted the non-random layout: the videoSceneChange 5/6 flag is
+// gone (a scene change is now requested via the sceneID sentinel), playDirection
+// moved after lastFrame, and a "hide on finish" flag was added. AR 44 matches
+// AR 41 plus a trailing movie-volume byte.
+void PlaySecondaryMovie::readDataNancy14(Common::Serializer &ser, Common::SeekableReadStream &stream) {
+ readFilename(ser, _videoName);
+
+ ser.syncAsUint16LE(_videoFormat);
+ _videoFormat = kLargeVideoFormat;
+
+ ser.skip(2); // Visibility frame ID; ScummVM drives visibility from the videoDescs instead
+ ser.syncAsUint16LE(_playerCursorAllowed);
+ ser.syncAsUint16LE(_hideOnFinish);
+ ser.syncAsUint16LE(_firstFrame);
+ ser.syncAsUint16LE(_lastFrame);
+ ser.syncAsUint16LE(_playDirection);
+ ser.syncAsSint16LE(_sceneChange.sceneID);
+ ser.syncAsUint16LE(_sceneChange.frameID);
+
+ _videoSceneChange = _sceneChange.sceneID != kNoScene ? kMovieSceneChange : kMovieNoSceneChange;
+
+ if (_type == 44) {
+ // Per-movie volume; consumed but unused (movie sound is off since Nancy6).
+ byte movieVolume = 0;
+ ser.syncAsByte(movieVolume);
+ }
+
+ uint16 numFrameFlags = 0;
+ ser.syncAsUint16LE(numFrameFlags);
+ _frameFlags.resize(numFrameFlags);
+ for (uint i = 0; i < numFrameFlags; ++i) {
+ ser.syncAsSint16LE(_frameFlags[i].frameID);
+ ser.syncAsSint16LE(_frameFlags[i].flagDesc.label);
+ ser.syncAsUint16LE(_frameFlags[i].flagDesc.flag);
+ }
+
+ uint16 numVideoDescs = 0;
+ ser.syncAsUint16LE(numVideoDescs);
+ _videoDescs.resize(numVideoDescs);
+ for (uint i = 0; i < numVideoDescs; ++i) {
+ _videoDescs[i].readData(stream);
+ }
+
+ _sound.name = "NO SOUND";
+}
+
void PlaySecondaryMovie::readData(Common::SeekableReadStream &stream) {
Common::Serializer ser(&stream, nullptr);
ser.setVersion(g_nancy->getGameType());
@@ -218,6 +264,11 @@ void PlaySecondaryMovie::readData(Common::SeekableReadStream &stream) {
return;
}
+ if (g_nancy->getGameType() >= kGameTypeNancy14) {
+ readDataNancy14(ser, stream);
+ return;
+ }
+
readFilename(ser, _videoName);
readFilename(ser, _paletteName, kGameTypeVampire, kGameTypeVampire);
readFilename(ser, _bitmapOverlayName, kGameTypeVampire, kGameTypeNancy9);
@@ -417,7 +468,14 @@ void PlaySecondaryMovie::execute() {
}
GraphicsManager::copyToManaged(*_decoder.decodeNextFrame(), _fullFrame, g_nancy->getGameType() == kGameTypeVampire, _videoFormat == kSmallVideoFormat);
- _drawSurface.create(_fullFrame, _videoDescs[descID].srcRect);
+
+ // Nancy14 stores an all -1 srcRect to mean "use the whole frame".
+ Common::Rect srcRect = _videoDescs[descID].srcRect;
+ if (srcRect.isEmpty()) {
+ srcRect = Common::Rect(_fullFrame.w, _fullFrame.h);
+ }
+
+ _drawSurface.create(_fullFrame, srcRect);
moveTo(_videoDescs[descID].destRect);
_needsRedraw = true;
diff --git a/engines/nancy/action/secondarymovie.h b/engines/nancy/action/secondarymovie.h
index f70dfcb1a88..7d754ebc69e 100644
--- a/engines/nancy/action/secondarymovie.h
+++ b/engines/nancy/action/secondarymovie.h
@@ -101,6 +101,8 @@ public:
byte _playDirection = kPlayMovieForward;
uint16 _firstFrame = 0;
uint16 _lastFrame = 0;
+ // Nancy14-only: when non-zero, hide the movie once it reaches its last frame.
+ uint16 _hideOnFinish = 0;
Common::Array<FlagAtFrame> _frameFlags;
MultiEventFlagDescription _triggerFlags;
FlagDescription _videoStartFlag;
@@ -152,6 +154,8 @@ protected:
void readRandomMovieData(Common::Serializer &ser, Common::SeekableReadStream &stream);
void readRandomSequence(Common::Serializer &ser, RandomSequence &seq);
+ void readDataNancy14(Common::Serializer &ser, Common::SeekableReadStream &stream);
+
// Apply a RandomSequence's playback config to the PSM flat fields
// and reload the decoder. Returns true on success.
bool activateRandomSequence(int index);
More information about the Scummvm-git-logs
mailing list