[Scummvm-git-logs] scummvm master -> 20d77710c98ace3a018244586c08ab82bb9b5c41

antoniou79 antoniou at cti.gr
Sun Mar 31 11:26:12 CEST 2019


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

Summary:
20d77710c9 BLADERUNNER: Release non-repeated and support queued overlays


Commit: 20d77710c98ace3a018244586c08ab82bb9b5c41
    https://github.com/scummvm/scummvm/commit/20d77710c98ace3a018244586c08ab82bb9b5c41
Author: Thanasis Antoniou (a.antoniou79 at gmail.com)
Date: 2019-03-31T12:24:23+03:00

Commit Message:
BLADERUNNER: Release non-repeated and support queued overlays

Changed paths:
    engines/bladerunner/overlays.cpp
    engines/bladerunner/overlays.h
    engines/bladerunner/script/scene/bb06.cpp
    engines/bladerunner/script/scene/bb51.cpp
    engines/bladerunner/vqa_player.cpp


diff --git a/engines/bladerunner/overlays.cpp b/engines/bladerunner/overlays.cpp
index 5bbac87..20e93b2 100644
--- a/engines/bladerunner/overlays.cpp
+++ b/engines/bladerunner/overlays.cpp
@@ -23,6 +23,7 @@
 #include "bladerunner/overlays.h"
 
 #include "bladerunner/bladerunner.h"
+#include "bladerunner/game_constants.h"
 
 #include "bladerunner/archive.h"
 #include "bladerunner/savefile.h"
@@ -58,6 +59,10 @@ Overlays::~Overlays() {
 
 int Overlays::play(const Common::String &name, int loopId, bool loopForever, bool startNow, int a6) {
 	assert(name.size() <= 12);
+	if (loopId < 0) {
+		warning("Overlays::play - loop id can't be a negative number!");
+		return -1;
+	}
 
 	int32 hash = MIXArchive::getHash(name);
 	int index = findByHash(hash);
@@ -70,20 +75,38 @@ int Overlays::play(const Common::String &name, int loopId, bool loopForever, boo
 		_videos[index].name = name;
 		_videos[index].hash = hash;
 		_videos[index].loopId = loopId;
+		_videos[index].enqueuedLoopId = -1;
 		_videos[index].loopForever = loopForever;
 		_videos[index].vqaPlayer = new VQAPlayer(_vm, &_vm->_surfaceFront, Common::String::format("%s.VQA", name.c_str()));
 
+		if (!_videos[index].vqaPlayer) {
+			resetSingle(index);
+			return -1;
+		}
+		// TODO? Removed as redundant
 		// repeat forever
-		_videos[index].vqaPlayer->setBeginAndEndFrame(0, 0, -1, kLoopSetModeJustStart, nullptr, nullptr);
+		//_videos[index].vqaPlayer->setBeginAndEndFrame(0, 0, -1, kLoopSetModeJustStart, nullptr, nullptr);
 	}
 
-	_videos[index].vqaPlayer->open();
-	_videos[index].vqaPlayer->setLoop(
-		loopId,
-		loopForever ? -1 : 0,
-		startNow ? kLoopSetModeImmediate : kLoopSetModeEnqueue,
-		nullptr, nullptr);
+	bool skipNewVQAPlayerOpen = false;
+	if (_videos[index].vqaPlayer
+	    && !startNow
+	    && _videos[index].vqaPlayer->getFrameCount() > 0
+	) {
+		skipNewVQAPlayerOpen = true;
+		_videos[index].enqueuedLoopId = loopId;
+	}
 
+	if (skipNewVQAPlayerOpen || _videos[index].vqaPlayer->open()) {
+		_videos[index].vqaPlayer->setLoop(
+			loopId,
+			loopForever ? -1 : 0,
+			startNow ? kLoopSetModeImmediate : kLoopSetModeEnqueue,
+			nullptr, nullptr);
+	} else {
+		resetSingle(index);
+		return -1;
+	}
 	return index;
 }
 
@@ -179,7 +202,12 @@ void Overlays::save(SaveFileWriteStream &f) {
 		f.writeInt(0); // vqaPlayer pointer
 		f.writeStringSz(ov.name, 13);
 		f.writeSint32LE(ov.hash);
-		f.writeInt(ov.loopId);
+		if (ov.enqueuedLoopId != -1) {
+		// When there is an enqueued video, save that loop Id instead
+			f.writeInt(ov.enqueuedLoopId);
+		} else {
+			f.writeInt(ov.loopId);
+		}
 		f.writeBool(ov.loopForever);
 		f.writeInt(ov.frame);
 	}
diff --git a/engines/bladerunner/overlays.h b/engines/bladerunner/overlays.h
index cbb01fa..3ba3a65 100644
--- a/engines/bladerunner/overlays.h
+++ b/engines/bladerunner/overlays.h
@@ -48,6 +48,7 @@ class Overlays {
 		Common::String  name;
 		int32           hash;
 		int             loopId;
+		int             enqueuedLoopId;
 		bool            loopForever;
 		int             frame;
 	};
diff --git a/engines/bladerunner/script/scene/bb06.cpp b/engines/bladerunner/script/scene/bb06.cpp
index 92fdefe..b2b185d 100644
--- a/engines/bladerunner/script/scene/bb06.cpp
+++ b/engines/bladerunner/script/scene/bb06.cpp
@@ -67,7 +67,7 @@ void SceneScriptBB06::InitializeScene() {
 #else
 		// bugfix: case of not transitioning from BB51: chess/ egg boiler sub-space
 		if (Game_Flag_Query(kFlagBB06AndroidDestroyed)) {
-			Overlay_Play("BB06OVER", 1, false, false, 0);
+			Overlay_Play("BB06OVER", 1, true, true, 0);
 		}
 #endif // BLADERUNNER_ORIGINAL_BUGS
 	}
@@ -111,8 +111,17 @@ bool SceneScriptBB06::ClickedOn3DObject(const char *objectName, bool a2) {
 		}
 #else
 		if (Player_Query_Combat_Mode()) {
-			Overlay_Play("BB06OVER", 0, false, true, 0); // explosion - don't loop
+			// Doll Explosion case:
+			// We need to use enqueued overlays for this.
+			// Note: Queuing only works on top of a video that is repeating itself.
+			// First we load the "exploding animation state" as a forever loop (even though it will only play once)
+			// Then we enqueue the final exploded state loop, also as a forever loop.
+			// This (along with some fixes in the Overlays class will ensure
+			// that the second overlay will play after the first has completed one loop
+			// and it will persist (across save games too).
 			Game_Flag_Set(kFlagBB06AndroidDestroyed);
+			Overlay_Play("BB06OVER", 0, true, true,  0);
+			Overlay_Play("BB06OVER", 1, true, false, 0);
 			Un_Combat_Target_Object("BOX31");
 			return true;
 		} else {
@@ -195,7 +204,7 @@ void SceneScriptBB06::SceneFrameAdvanced(int frame) {
 	// last frame of transition is 15, try 13 for better transition - minimize weird effect
 	if (frame == 13) { // executed once during transition FROM bb51 (chess sub space)
 		if (Game_Flag_Query(kFlagBB06AndroidDestroyed)) {
-			Overlay_Play("BB06OVER", 1, false, false, 0);
+			Overlay_Play("BB06OVER", 1, true, true, 0);
 		}
 	}
 #endif // BLADERUNNER_ORIGINAL_BUGS
diff --git a/engines/bladerunner/script/scene/bb51.cpp b/engines/bladerunner/script/scene/bb51.cpp
index fd706c2..d5d5630 100644
--- a/engines/bladerunner/script/scene/bb51.cpp
+++ b/engines/bladerunner/script/scene/bb51.cpp
@@ -51,7 +51,7 @@ void SceneScriptBB51::InitializeScene() {
 #if BLADERUNNER_ORIGINAL_BUGS // Sebastian's Doll Fix
 #else
 	if (Game_Flag_Query(kFlagBB06AndroidDestroyed)) {
-		Overlay_Play("BB06OVER", 1, false, false, 0);
+		Overlay_Play("BB06OVER", 1, true, true, 0);
 	}
 #endif // BLADERUNNER_ORIGINAL_BUGS
 
diff --git a/engines/bladerunner/vqa_player.cpp b/engines/bladerunner/vqa_player.cpp
index 300740e..65fab5f 100644
--- a/engines/bladerunner/vqa_player.cpp
+++ b/engines/bladerunner/vqa_player.cpp
@@ -57,10 +57,12 @@ bool VQAPlayer::open() {
 	_repeatsCountQueued = -1;
 
 	if (_loopInitial >= 0) {
+		// TODO? When does this happen? _loopInitial seems to be unused
 		setLoop(_loopInitial, _repeatsCountInitial, kLoopSetModeImmediate, nullptr, nullptr);
 	} else {
 		_frameNext = 0;
-		setBeginAndEndFrame(0, _frameEnd, 0, kLoopSetModeJustStart, nullptr, nullptr);
+		// TODO? Removed as redundant
+//		setBeginAndEndFrame(0, _frameEnd, 0, kLoopSetModeJustStart, nullptr, nullptr);
 	}
 
 	return true;
@@ -107,6 +109,8 @@ int VQAPlayer::update(bool forceDraw, bool advanceFrame, bool useTime, Graphics:
 		result = -1;
 	} else if (_frameNext > _frameEnd) {
 		result = -3;
+		// _repeatsCount == 0, so return here at the end of the video, to release the resource
+		return result;
 	} else if (useTime && (now < _frameNextTime)) {
 		result = -1;
 	} else if (advanceFrame) {
@@ -149,7 +153,9 @@ int VQAPlayer::update(bool forceDraw, bool advanceFrame, bool useTime, Graphics:
 		_decoder.decodeVideoFrame(customSurface != nullptr ? customSurface : _surface, _frame, true);
 		result = _frame;
 	}
-	return result;
+	return result; // Note: result here could be negative.
+	               // Negative valid value should only be -1, since there are various assertions
+	               // assert(frame >= -1) in overlay modes (elevator, scores, spinner)
 }
 
 void VQAPlayer::updateZBuffer(ZBuffer *zbuffer) {
@@ -187,11 +193,23 @@ bool VQAPlayer::setLoop(int loop, int repeatsCount, int loopSetMode, void (*call
 }
 
 bool VQAPlayer::setBeginAndEndFrame(int begin, int end, int repeatsCount, int loopSetMode, void (*callback)(void *, int, int), void *callbackData) {
+	if ( begin >= getFrameCount()
+	    || end >= getFrameCount()
+	    || begin >= end
+	    || loopSetMode < 0
+	    || loopSetMode >= 3
+	) {
+		warning("VQAPlayer::setBeginAndEndFrame - Invalid arguments for video");
+		return false; // VQA_DECODER_ERROR_BAD_INPUT case
+	}
+
 	if (repeatsCount < 0) {
 		repeatsCount = -1;
 	}
 
 	if (_repeatsCount == 0 && loopSetMode == kLoopSetModeEnqueue) {
+		// if the member var _repeatsCount is 0 (which means "don't repeat existing loop")
+		// then execute set the enqueued loop for immediate execution
 		loopSetMode = kLoopSetModeImmediate;
 	}
 
@@ -199,6 +217,7 @@ bool VQAPlayer::setBeginAndEndFrame(int begin, int end, int repeatsCount, int lo
 
 	if (loopSetMode == kLoopSetModeJustStart) {
 		_repeatsCount = repeatsCount;
+		_frameEnd = end;
 	} else if (loopSetMode == kLoopSetModeEnqueue) {
 		_repeatsCountQueued = repeatsCount;
 		_frameEndQueued = end;





More information about the Scummvm-git-logs mailing list