[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