[Scummvm-git-logs] scummvm master -> f5ebf4d6803feaf1e1ae914db1dad8ff4e39b445

peterkohaut peterkohaut at users.noreply.github.com
Sun Mar 26 22:13:45 CEST 2017


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:
f5ebf4d680 BLADERUNNER: Added correct video looping and loop switching


Commit: f5ebf4d6803feaf1e1ae914db1dad8ff4e39b445
    https://github.com/scummvm/scummvm/commit/f5ebf4d6803feaf1e1ae914db1dad8ff4e39b445
Author: Peter Kohaut (peter.kohaut at gmail.com)
Date: 2017-03-26T22:09:29+02:00

Commit Message:
BLADERUNNER: Added correct video looping and loop switching

Changed paths:
    engines/bladerunner/script/scene/rc01.cpp
    engines/bladerunner/vqa_player.cpp
    engines/bladerunner/vqa_player.h


diff --git a/engines/bladerunner/script/scene/rc01.cpp b/engines/bladerunner/script/scene/rc01.cpp
index 8d8b604..1a5367b 100644
--- a/engines/bladerunner/script/scene/rc01.cpp
+++ b/engines/bladerunner/script/scene/rc01.cpp
@@ -27,10 +27,7 @@ namespace BladeRunner {
 void SceneScriptRC01::InitializeScene() {
 #if _DEBUG
 	//TODO: not part of game, remove
-	Game_Flag_Set(24); // force skip intro
-	// Game_Flag_Set(9); // Force flag 9 so McCoy will be in view
-
-	Footstep_Sound_Override_On(0);
+//	Game_Flag_Set(24); // force skip intro
 #endif
 
 	if (!Game_Flag_Query(24)) {
diff --git a/engines/bladerunner/vqa_player.cpp b/engines/bladerunner/vqa_player.cpp
index 4fb19cf..e2b3833 100644
--- a/engines/bladerunner/vqa_player.cpp
+++ b/engines/bladerunner/vqa_player.cpp
@@ -32,18 +32,26 @@ namespace BladeRunner {
 
 bool VQAPlayer::open(const Common::String &name) {
 	_s = _vm->getResourceStream(name);
-	if (!_s)
+	if (!_s) {
 		return false;
+	}
 
-	if(!_decoder.loadStream(_s)) {
+	if (!_decoder.loadStream(_s)) {
 		delete _s;
 		_s = nullptr;
 		return false;
 	}
 
 	_hasAudio = _decoder.hasAudio();
-	if (_hasAudio)
+	if (_hasAudio) {
 		_audioStream = Audio::makeQueuingAudioStream(_decoder.frequency(), false);
+	}
+
+	if (_loopInitial >= 0) {
+		setLoop(_loopInitial, _repeatsCountInitial, 2, nullptr, nullptr);
+	} else {
+		setBeginAndEndFrame(0, _decoder.numFrames() - 1, 0, 0, nullptr, nullptr);
+	}
 
 	return true;
 }
@@ -57,19 +65,19 @@ void VQAPlayer::close() {
 int VQAPlayer::update() {
 	uint32 now = 60 * _vm->_system->getMillis();
 
-	if (_curFrame == -1) {
-		_curFrame = 0;
-		if (_curFrame >= 0) {
-			_decoder.readPacket(_curFrame);
+	if (_frameCurrent == -1) {
+		_frameCurrent = 0;
+		if (_frameCurrent >= 0) {
+			_decoder.readPacket(_frameCurrent);
 			if (_hasAudio)
 				queueAudioFrame(_decoder.decodeAudioFrame());
 			_surface = _decoder.decodeVideoFrame();
 			_zBuffer = _decoder.decodeZBuffer();
 		}
 
-		_decodedFrame = calcNextFrame(_curFrame);
-		if (_decodedFrame >= 0) {
-			_decoder.readPacket(_decodedFrame);
+		_frameDecoded = calcNextFrame(_frameCurrent);
+		if (_frameDecoded >= 0) {
+			_decoder.readPacket(_frameDecoded);
 			if (_hasAudio)
 				queueAudioFrame(_decoder.decodeAudioFrame());
 		}
@@ -80,25 +88,25 @@ int VQAPlayer::update() {
 		}
 
 		_nextFrameTime = now + 60000 / 15;
-		return _curFrame;
+		return _frameCurrent;
 	}
 
 	if (now >= _nextFrameTime) {
-		_curFrame = _decodedFrame;
-		if (_curFrame >= 0) {
+		_frameCurrent = _frameDecoded;
+		if (_frameCurrent >= 0) {
 			_surface = _decoder.decodeVideoFrame();
 			_zBuffer = _decoder.decodeZBuffer();
 		}
 
-		_decodedFrame = calcNextFrame(_curFrame);
-		if (_decodedFrame >= 0) {
-			_decoder.readPacket(_decodedFrame);
+		_frameDecoded = calcNextFrame(_frameCurrent);
+		if (_frameDecoded >= 0) {
+			_decoder.readPacket(_frameDecoded);
 			if (_hasAudio)
 				queueAudioFrame(_decoder.decodeAudioFrame());
 		}
 
 		_nextFrameTime += 60000 / 15;
-		return _curFrame;
+		return _frameCurrent;
 	}
 
 	_surface = nullptr;
@@ -121,21 +129,58 @@ void VQAPlayer::updateLights(Lights *lights) {
 	_decoder.decodeLights(lights);
 }
 
-bool VQAPlayer::setLoop(int loop, int unknown, int loopMode, void(*callback)(void*, int, int), void *callbackData) {
+bool VQAPlayer::setLoop(int loop, int repeatsCount, int loopMode, void (*callback)(void *, int, int), void *callbackData) {
+	debug("VQAPlayer::setBeginAndEndFrameFromLoop(%i, %i, %i, %p, %p), streamLoaded = %i", loop, repeatsCount, loopMode, (void*)callback, callbackData, _s != nullptr);
+	if (_s == nullptr) {
+		_loopInitial = loop;
+		_repeatsCountInitial = repeatsCount;
+		return true;
+	}
+
 	int begin, end;
 	if (!_decoder.getLoopBeginAndEndFrame(loop, &begin, &end)) {
 		return false;
 	}
+	if (setBeginAndEndFrame(begin, end, repeatsCount, loopMode, callback, callbackData)) {
+		_loop = loop;
+		return true;
+	}
+	return false;
+}
+
+bool VQAPlayer::setBeginAndEndFrame(int begin, int end, int repeatsCount, int loopMode, void (*callback)(void *, int, int), void *callbackData) {
+	debug("VQAPlayer::setBeginAndEndFrame(%i, %i, %i, %i, %p, %p), streamLoaded = %i", begin, end, repeatsCount, loopMode, (void*)callback, callbackData, _s != nullptr);
+
+	if (repeatsCount < 0) {
+		repeatsCount = -1;
+	}
 
-	_curLoop   = loop;
-	_loopBegin = begin;
-	_loopEnd   = end;
+	if (_repeatsCount == 0 && loopMode == 1) {
+		loopMode = 2;
+	}
+
+	//TODO: there is code in original game which deals with changing loop at start of loop, is it nescesarry? loc_46EA04
+
+	_frameBegin = begin;
+
+	if (loopMode == 1) {
+		_repeatsCountQueued = repeatsCount;
+		_frameEndQueued = end;
+	} else if (loopMode == 2) {
+		_repeatsCount = repeatsCount;
+		_frameEnd = end;
+		_frameCurrent = begin;
+		//TODO: extract this to seek function
+		_decoder.readPacket(_frameCurrent);
+		_frameDecoded = _frameCurrent;
+		_nextFrameTime = 60 * _vm->_system->getMillis();
+	} else if (loopMode == 0) {
+		_repeatsCount = repeatsCount;
+	}
 
 	_callbackLoopEnded = callback;
 	_callbackData = callbackData;
 
-	// warning("\t\t\tActive Loop: %d - %d\n", begin, end);
-
 	return true;
 }
 
@@ -155,23 +200,45 @@ int VQAPlayer::getLoopEndFrame(int loop) {
 	return end;
 }
 
-int VQAPlayer::calcNextFrame(int frame) const {
-	if (frame < 0)
+int VQAPlayer::calcNextFrame(int frame) {
+	//TODO: needs a slight refactoring, because it is not only calculating the next frame
+	if (frame < 0) {
 		return -3;
+	}
+
+	int frameNext = frame + 1;
 
-	if (_curLoop != -1 && frame >= _loopEnd) {
-		frame = _loopBegin;
-		if (_callbackLoopEnded != nullptr) {
-			_callbackLoopEnded(_callbackData, 0, _curLoop);
+	if ((_repeatsCount > 0 || _repeatsCount == -1) && (frameNext > _frameEnd)) {
+		int loopEndQueued = _frameEndQueued;
+		if (_frameEndQueued != -1) {
+			_frameEnd = _frameEndQueued;
+			_frameEndQueued = -1;
+		}
+		if (frameNext != _frameBegin) {
+			frameNext = _frameBegin;
+		}
+
+		if (loopEndQueued == -1) {
+			if (_repeatsCount != -1) {
+				_repeatsCount--;
+			}
+			//callback for repeat, it is not used in the blade runner
+		} else {
+			_repeatsCount = _repeatsCountQueued;
+			_repeatsCountQueued = -1;
+
+			if (_callbackLoopEnded != nullptr) {
+				_callbackLoopEnded(_callbackData, 0, _loop);
+			}
 		}
-	} else {
-		frame++;
 	}
 
-	if (frame == _decoder.numFrames())
-		frame = -3;
+	//TODO: original game is using end of loop instead of count of frames
+	if (frameNext == _decoder.numFrames()) {
+		return -3;
+	}
 
-	return frame;
+	return frameNext;
 }
 
 void VQAPlayer::queueAudioFrame(Audio::AudioStream *audioStream) {
diff --git a/engines/bladerunner/vqa_player.h b/engines/bladerunner/vqa_player.h
index 3a821a8..941b363 100644
--- a/engines/bladerunner/vqa_player.h
+++ b/engines/bladerunner/vqa_player.h
@@ -36,6 +36,8 @@ class BladeRunnerEngine;
 class View;
 class Lights;
 
+//TODO: split this into two components as it is in original game: universal vqa player, blade runner player functionality
+
 class VQAPlayer {
 	BladeRunnerEngine           *_vm;
 	Common::SeekableReadStream  *_s;
@@ -44,11 +46,18 @@ class VQAPlayer {
 	const uint16                *_zBuffer;
 	Audio::QueuingAudioStream   *_audioStream;
 
-	int _curFrame;
-	int _decodedFrame;
-	int _curLoop;
-	int _loopBegin;
-	int _loopEnd;
+	int _frameCurrent;
+	int _frameDecoded;
+	int _frameBegin;
+	int _frameEnd;
+	int _loop;
+	int _repeatsCount;
+
+	int _repeatsCountQueued;
+	int _frameEndQueued;
+
+	int _loopInitial;
+	int _repeatsCountInitial;
 
 	uint32 _nextFrameTime;
 	bool   _hasAudio;
@@ -65,11 +74,16 @@ public:
 		  _s(nullptr),
 		  _surface(nullptr),
 		  _audioStream(nullptr),
-		  _curFrame(-1),
-		  _decodedFrame(-1),
-		  _curLoop(-1),
-		  _loopBegin(-1),
-		  _loopEnd(-1),
+		  _frameCurrent(-1),
+		  _frameDecoded(-1),
+		  _frameBegin(-1),
+		  _frameEnd(-1),
+		  _loop(-1),
+		  _repeatsCount(-1),
+		  _repeatsCountQueued(-1),
+		  _frameEndQueued(-1),
+		  _loopInitial(-1),
+		  _repeatsCountInitial(-1),
 		  _nextFrameTime(0),
 		  _hasAudio(false),
 		  _audioStarted(false),
@@ -89,13 +103,14 @@ public:
 	void updateView(View *view);
 	void updateLights(Lights *lights);
 
-	bool setLoop(int loop, int unknown, int loopMode, void(*callback)(void*, int, int), void* callbackData);
+	bool setBeginAndEndFrame(int begin, int end, int repeatsCount, int loopMode, void(*callback)(void *, int, int), void *callbackData);
+	bool setLoop(int loop, int repeatsCount, int loopMode, void(*callback)(void*, int, int), void* callbackData);
 
 	int getLoopBeginFrame(int loop);
 	int getLoopEndFrame(int loop);
 
 private:
-	int calcNextFrame(int frame) const;
+	int calcNextFrame(int frame);
 	void queueAudioFrame(Audio::AudioStream *audioStream);
 };
 





More information about the Scummvm-git-logs mailing list