[Scummvm-git-logs] scummvm master -> 6ef6950299fdd8f3882c9c9c4d12d5eb50b9acd4

fracturehill noreply at scummvm.org
Fri Mar 17 19:50:52 UTC 2023


This automated email contains information about 4 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
6b2780b464 NANCY: Fix secondary movie scene change trigger
62d7cd5792 NANCY: Complete reading of primary video data
ff642056b4 NANCY: Add support for uncompressed video
6ef6950299 NANCY: Fix PaletteNextScene


Commit: 6b2780b464ba0dbd79a831c1fd8ca593e1dd4b6c
    https://github.com/scummvm/scummvm/commit/6b2780b464ba0dbd79a831c1fd8ca593e1dd4b6c
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2023-03-17T21:32:22+02:00

Commit Message:
NANCY: Fix secondary movie scene change trigger

Fixed the way secondary movies trigger their scene changes to fix
issues that arise with reverse video playback.

Changed paths:
    engines/nancy/action/secondarymovie.cpp


diff --git a/engines/nancy/action/secondarymovie.cpp b/engines/nancy/action/secondarymovie.cpp
index 5e0d2d01c58..f75e93b14fa 100644
--- a/engines/nancy/action/secondarymovie.cpp
+++ b/engines/nancy/action/secondarymovie.cpp
@@ -149,10 +149,14 @@ void PlaySecondaryMovie::updateGraphics() {
 	if ((_decoder.getCurFrame() == _lastFrame && _playDirection == kPlayMovieForward) ||
 		(_decoder.getCurFrame() == _firstFrame && _playDirection == kPlayMovieReverse) ||
 		_decoder.atEnd()) {
+		
+		// Stop the video and block it from starting again, but also wait for
+		// sound to end before changing state
+		_decoder.stop();
+		_isFinished = true;
+
 		if (!g_nancy->_sound->isSoundPlaying(_sound)) {
 			g_nancy->_sound->stopSound(_sound);
-			_decoder.stop();
-			_isFinished = true;
 			_state = kActionTrigger;
 		}
 	}


Commit: 62d7cd57928fa5654440645260b5ac6db9883ced
    https://github.com/scummvm/scummvm/commit/62d7cd57928fa5654440645260b5ac6db9883ced
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2023-03-17T21:32:22+02:00

Commit Message:
NANCY: Complete reading of primary video data

Implemented the scene branch structs in primary video. Fixed the
evaluation of primary video flags so conditions with an orFlag
work correctly.

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


diff --git a/engines/nancy/action/primaryvideo.cpp b/engines/nancy/action/primaryvideo.cpp
index 660f0cad381..21954b95d20 100644
--- a/engines/nancy/action/primaryvideo.cpp
+++ b/engines/nancy/action/primaryvideo.cpp
@@ -37,14 +37,14 @@
 namespace Nancy {
 namespace Action {
 
-void PlayPrimaryVideoChan0::ConditionFlag::read(Common::SeekableReadStream &stream) {
+void PlayPrimaryVideoChan0::PrimaryVideoFlag::read(Common::SeekableReadStream &stream) {
 	type = stream.readByte();
 	flag.label = stream.readSint16LE();
 	flag.flag = stream.readByte();
 	orFlag = stream.readByte();
 }
 
-bool PlayPrimaryVideoChan0::ConditionFlag::isSatisfied() const {
+bool PlayPrimaryVideoChan0::PrimaryVideoFlag::isSatisfied() const {
 	switch (type) {
 	case kFlagEvent:
 		return NancySceneState.getEventFlag(flag);
@@ -55,7 +55,7 @@ bool PlayPrimaryVideoChan0::ConditionFlag::isSatisfied() const {
 	}
 }
 
-void PlayPrimaryVideoChan0::ConditionFlag::set() const {
+void PlayPrimaryVideoChan0::PrimaryVideoFlag::set() const {
 	switch (type) {
 	case kFlagEvent:
 		NancySceneState.setEventFlag(flag);
@@ -73,36 +73,42 @@ void PlayPrimaryVideoChan0::ConditionFlag::set() const {
 	}
 }
 
-void PlayPrimaryVideoChan0::ConditionFlags::read(Common::SeekableReadStream &stream) {
+void PlayPrimaryVideoChan0::PrimaryVideoFlags::read(Common::SeekableReadStream &stream) {
 	uint16 numFlags = stream.readUint16LE();
 
-	conditionFlags.reserve(numFlags);
+	conditionFlags.resize(numFlags);
 	for (uint i = 0; i < numFlags; ++i) {
-		conditionFlags.push_back(ConditionFlag());
-		conditionFlags.back().read(stream);
+		conditionFlags[i].read(stream);
 	}
 }
 
-bool PlayPrimaryVideoChan0::ConditionFlags::isSatisfied() const {
-	bool orFlag = false;
+bool PlayPrimaryVideoChan0::PrimaryVideoFlags::isSatisfied() const {
+	Common::Array<bool> conditionsMet(conditionFlags.size(), false);
 
 	for (uint i = 0; i < conditionFlags.size(); ++i) {
-		const ConditionFlag &cur = conditionFlags[i];
+		if (conditionFlags[i].isSatisfied()) {
+			conditionsMet[i] = true;
+		}
 
-		if (!cur.isSatisfied()) {
-			if (orFlag) {
-				return false;
-			} else {
-				orFlag = true;
+		if (conditionFlags[i].orFlag && i < conditionFlags.size() - 1) {
+			if (conditionsMet[i] == true) {
+				conditionsMet[i + 1] = true;
+				++i;
+			} else if (conditionFlags[i + 1].isSatisfied()) {
+				conditionsMet[i] = true;
+				conditionsMet[i + 1] = true;
+				++i;
 			}
 		}
 	}
 
-	if (orFlag) {
-		return false;
-	} else {
-		return true;
+	for (uint i = 0; i < conditionsMet.size(); ++i) {
+		if (conditionsMet[i] == false) {
+			return false;
+		}
 	}
+
+	return true;
 }
 
 PlayPrimaryVideoChan0::~PlayPrimaryVideoChan0() {
@@ -214,15 +220,17 @@ void PlayPrimaryVideoChan0::readData(Common::SeekableReadStream &stream) {
 	delete[] rawText;
 
 	uint16 numSceneBranchStructs = stream.readUint16LE();
-	if (numSceneBranchStructs > 0) {
-		// TODO
+	_sceneBranchStructs.resize(numSceneBranchStructs);
+	for (uint i = 0; i < numSceneBranchStructs; ++i) {
+		_sceneBranchStructs[i].conditions.read(stream);
+		_sceneBranchStructs[i].sceneChange.readData(stream, g_nancy->getGameType() == kGameTypeVampire);
+		stream.skip(0x32);
 	}
 
 	uint16 numFlagsStructs = stream.readUint16LE();
-	_flagsStructs.reserve(numFlagsStructs);
-	for (uint16 i = 0; i < numFlagsStructs; ++i) {
-		_flagsStructs.push_back(FlagsStruct());
-		FlagsStruct &flagsStruct = _flagsStructs.back();
+	_flagsStructs.resize(numFlagsStructs);
+	for (uint i = 0; i < numFlagsStructs; ++i) {
+		FlagsStruct &flagsStruct = _flagsStructs[i];
 		flagsStruct.conditions.read(stream);
 		flagsStruct.flagToSet.type = stream.readByte();
 		flagsStruct.flagToSet.flag.label = stream.readSint16LE();
@@ -365,7 +373,12 @@ void PlayPrimaryVideoChan0::execute() {
 			if (_pickedResponse != -1) {
 				NancySceneState.changeScene(_responses[_pickedResponse].sceneChange);
 			} else {
-				// Evaluate scene branch structs here
+				for (uint i = 0; i < _sceneBranchStructs.size(); ++i) {
+					if (_sceneBranchStructs[i].conditions.isSatisfied()) {
+						NancySceneState.changeScene(_sceneBranchStructs[i].sceneChange);
+						break;
+					}
+				}
 
 				if (_defaultNextScene == kDefaultNextSceneEnabled) {
 					NancySceneState.changeScene(_sceneChange);
diff --git a/engines/nancy/action/primaryvideo.h b/engines/nancy/action/primaryvideo.h
index 0ae0532f1fc..501556bd792 100644
--- a/engines/nancy/action/primaryvideo.h
+++ b/engines/nancy/action/primaryvideo.h
@@ -36,7 +36,7 @@ namespace Action {
 // ActionRecord subclass that handles all NPC dialog and nancy1's intro video
 class PlayPrimaryVideoChan0 : public ActionRecord, public RenderObject {
 
-struct ConditionFlag {
+struct PrimaryVideoFlag {
 	byte type;
 	FlagDescription flag;
 	byte orFlag;
@@ -46,15 +46,15 @@ struct ConditionFlag {
 	void set() const;
 };
 
-struct ConditionFlags {
-	Common::Array<ConditionFlag> conditionFlags;
+struct PrimaryVideoFlags {
+	Common::Array<PrimaryVideoFlag> conditionFlags;
 
 	void read(Common::SeekableReadStream &stream);
 	bool isSatisfied() const;
 };
 
 struct ResponseStruct {
-	ConditionFlags conditionFlags; // 0x01
+	PrimaryVideoFlags conditionFlags; // 0x01
 	Common::String text; // 0x06
 	Common::String soundName; // 0x196
 	SceneChangeDescription sceneChange; // 0x1A0
@@ -64,8 +64,13 @@ struct ResponseStruct {
 };
 
 struct FlagsStruct {
-	ConditionFlags conditions;
-	ConditionFlag flagToSet;
+	PrimaryVideoFlags conditions;
+	PrimaryVideoFlag flagToSet;
+};
+
+struct SceneBranchStruct {
+	PrimaryVideoFlags conditions;
+	SceneChangeDescription sceneChange;
 };
 
 public:
@@ -105,6 +110,7 @@ public:
 
 	Common::Array<ResponseStruct> _responses;
 	Common::Array<FlagsStruct> _flagsStructs;
+	Common::Array<SceneBranchStruct> _sceneBranchStructs;
 
 	AVFDecoder _decoder;
 


Commit: ff642056b432f45501b23bb76ff0f2db22d1edb2
    https://github.com/scummvm/scummvm/commit/ff642056b432f45501b23bb76ff0f2db22d1edb2
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2023-03-17T21:32:24+02:00

Commit Message:
NANCY: Add support for uncompressed video

Added support for the extremely rare case where an AVF video
would be uncompressed.

Changed paths:
    engines/nancy/video.cpp
    engines/nancy/video.h


diff --git a/engines/nancy/video.cpp b/engines/nancy/video.cpp
index b7b13095200..d03f685225b 100644
--- a/engines/nancy/video.cpp
+++ b/engines/nancy/video.cpp
@@ -100,6 +100,7 @@ AVFDecoder::AVFVideoTrack::AVFVideoTrack(Common::SeekableReadStream *stream, uin
 	_frameTime = stream->readUint32LE();
 
 	byte comp = stream->readByte();
+	_compressed = comp == 2;
 
 	uint formatHi = chunkFileFormat >> 16;
 
@@ -107,7 +108,7 @@ AVFDecoder::AVFVideoTrack::AVFVideoTrack(Common::SeekableReadStream *stream, uin
 		stream->skip(1);
 	}
 
-	if (comp != 2)
+	if (comp != 1 && comp != 2)
 		error("Unknown compression type %d found in AVF", comp);
 
 	_surface = new Graphics::Surface();
@@ -247,27 +248,38 @@ const Graphics::Surface *AVFDecoder::AVFVideoTrack::decodeFrame(uint frameNr) {
 			warning("Decompressed size %d exceeds frame size %d", info.size, _frameSize);
 			return nullptr;
 		}
+		
+		decompBuf = (byte *)_surface->getPixels();
 	} else {
 		// For types 1 and 2, we decompress to a temp buffer for decoding
 		decompBuf = new byte[info.size];
 	}
-
-	Common::MemoryWriteStream output((info.type == 0 ? (byte *)_surface->getPixels() : decompBuf), info.size);
+	
 	Common::SeekableSubReadStream input(_fileStream, info.offset, info.offset + info.compressedSize);
 
-	if (!_dec->decompress(input, output)) {
-		warning("Failed to decompress frame %d", frameNr);
-		delete[] decompBuf;
-		return nullptr;
-	}
+	if (_compressed) {
+		Common::MemoryWriteStream output(decompBuf, info.size);
+
+		if (!_dec->decompress(input, output)) {
+			warning("Failed to decompress frame %d", frameNr);
+			delete[] decompBuf;
+			return nullptr;
+		}
+	} else {
+		// No compression, just copy the data
+		input.read(decompBuf, info.size);
+	}	
 
 	if (info.type != 0) {
 		Common::MemoryReadStream decompStr(decompBuf, info.size);
 		decode((byte *)_surface->getPixels(), _frameSize, decompStr);
 	}
 
+	if (info.type != 0) {
+		delete[] decompBuf;
+	}
+	
 	_refFrame = frameNr;
-	delete[] decompBuf;
 	return _surface;
 }
 
diff --git a/engines/nancy/video.h b/engines/nancy/video.h
index ea93ffe62fb..9fa1f4e8047 100644
--- a/engines/nancy/video.h
+++ b/engines/nancy/video.h
@@ -92,6 +92,7 @@ private:
 		Common::Array<ChunkInfo> _chunkInfo;
 		Decompressor *_dec;
 		bool _reversed;
+		bool _compressed;
 	};
 };
 


Commit: 6ef6950299fdd8f3882c9c9c4d12d5eb50b9acd4
    https://github.com/scummvm/scummvm/commit/6ef6950299fdd8f3882c9c9c4d12d5eb50b9acd4
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2023-03-17T21:32:25+02:00

Commit Message:
NANCY: Fix PaletteNextScene

Fixed the handling of scene changes so the PaletteNextScene
action record does its job correctly.

Changed paths:
    engines/nancy/commontypes.h
    engines/nancy/state/scene.cpp
    engines/nancy/state/scene.h


diff --git a/engines/nancy/commontypes.h b/engines/nancy/commontypes.h
index 40d62138890..9c181137b26 100644
--- a/engines/nancy/commontypes.h
+++ b/engines/nancy/commontypes.h
@@ -113,7 +113,7 @@ struct SceneChangeDescription {
 	uint16 verticalOffset = 0;
 	uint16 continueSceneSound = kLoadSceneSound;
 
-	int8 paletteID = 0; // TVD only
+	int8 paletteID = -1; // TVD only
 
 	void readData(Common::SeekableReadStream &stream, bool longFormat = false);
 };
diff --git a/engines/nancy/state/scene.cpp b/engines/nancy/state/scene.cpp
index 60747578177..6b9de304881 100644
--- a/engines/nancy/state/scene.cpp
+++ b/engines/nancy/state/scene.cpp
@@ -174,7 +174,7 @@ void Scene::onStateExit() {
 	_gameStateRequested = NancyState::kNone;
 }
 
-void Scene::changeScene(uint16 id, uint16 frame, uint16 verticalOffset, byte continueSceneSound, byte paletteID) {
+void Scene::changeScene(uint16 id, uint16 frame, uint16 verticalOffset, byte continueSceneSound, int8 paletteID) {
 	if (id == 9999) {
 		return;
 	}
@@ -182,8 +182,12 @@ void Scene::changeScene(uint16 id, uint16 frame, uint16 verticalOffset, byte con
 	_sceneState.nextScene.sceneID = id;
 	_sceneState.nextScene.frameID = frame;
 	_sceneState.nextScene.verticalOffset = verticalOffset;
-	_sceneState.nextScene.paletteID = paletteID;
 	_sceneState.continueSceneSound = continueSceneSound;
+
+	if (paletteID != -1) {
+		_sceneState.nextScene.paletteID = paletteID;
+	}
+
 	_state = kLoad;
 }
 
@@ -561,7 +565,7 @@ void Scene::load() {
 						_sceneState.currentScene.verticalOffset,
 						_sceneState.summary.panningType,
 						_sceneState.summary.videoFormat,
-						_sceneState.summary.palettes.size() ? _sceneState.summary.palettes[_sceneState.currentScene.paletteID] : Common::String());
+						_sceneState.summary.palettes.size() ? _sceneState.summary.palettes[(byte)_sceneState.currentScene.paletteID] : Common::String());
 
 	if (_viewport.getFrameCount() <= 1) {
 		_viewport.disableEdges(kLeft | kRight);
diff --git a/engines/nancy/state/scene.h b/engines/nancy/state/scene.h
index 4a0c9692c9c..cbcce1951b2 100644
--- a/engines/nancy/state/scene.h
+++ b/engines/nancy/state/scene.h
@@ -118,7 +118,7 @@ public:
 	void onStateEnter() override;
 	void onStateExit() override;
 
-	void changeScene(uint16 id, uint16 frame, uint16 verticalOffset, byte continueSceneSound, byte paletteID = 0);
+	void changeScene(uint16 id, uint16 frame, uint16 verticalOffset, byte continueSceneSound, int8 paletteID = -1);
 	void changeScene(const SceneChangeDescription &sceneDescription);
 	void pushScene();
 	void popScene();




More information about the Scummvm-git-logs mailing list