diff options
| author | Thanasis Antoniou | 2019-03-31 12:23:01 +0300 | 
|---|---|---|
| committer | Thanasis Antoniou | 2019-03-31 12:24:23 +0300 | 
| commit | 20d77710c98ace3a018244586c08ab82bb9b5c41 (patch) | |
| tree | 95fdbb9493a9be97376085ad01f7fc7b7e36cfeb | |
| parent | fa50678125ed51ccdbf9362762b520ecfa6be423 (diff) | |
| download | scummvm-rg350-20d77710c98ace3a018244586c08ab82bb9b5c41.tar.gz scummvm-rg350-20d77710c98ace3a018244586c08ab82bb9b5c41.tar.bz2 scummvm-rg350-20d77710c98ace3a018244586c08ab82bb9b5c41.zip | |
BLADERUNNER: Release non-repeated and support queued overlays
| -rw-r--r-- | engines/bladerunner/overlays.cpp | 44 | ||||
| -rw-r--r-- | engines/bladerunner/overlays.h | 1 | ||||
| -rw-r--r-- | engines/bladerunner/script/scene/bb06.cpp | 15 | ||||
| -rw-r--r-- | engines/bladerunner/script/scene/bb51.cpp | 2 | ||||
| -rw-r--r-- | engines/bladerunner/vqa_player.cpp | 23 | 
5 files changed, 71 insertions, 14 deletions
| diff --git a/engines/bladerunner/overlays.cpp b/engines/bladerunner/overlays.cpp index 5bbac87c36..20e93b22e3 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 cbb01fa04b..3ba3a654c1 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 92fdefefd8..b2b185d630 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 fd706c2bcf..d5d5630d36 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 300740e028..65fab5f1cd 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; | 
