diff options
author | Peter Kohaut | 2017-03-26 22:09:29 +0200 |
---|---|---|
committer | Peter Kohaut | 2017-03-26 22:09:29 +0200 |
commit | f5ebf4d6803feaf1e1ae914db1dad8ff4e39b445 (patch) | |
tree | d58ad62698a023100df42777aecc551eb4a5670b /engines | |
parent | 96b31ca5eb82af59f0032ecae7277fa36fb8eedf (diff) | |
download | scummvm-rg350-f5ebf4d6803feaf1e1ae914db1dad8ff4e39b445.tar.gz scummvm-rg350-f5ebf4d6803feaf1e1ae914db1dad8ff4e39b445.tar.bz2 scummvm-rg350-f5ebf4d6803feaf1e1ae914db1dad8ff4e39b445.zip |
BLADERUNNER: Added correct video looping and loop switching
Diffstat (limited to 'engines')
-rw-r--r-- | engines/bladerunner/script/scene/rc01.cpp | 5 | ||||
-rw-r--r-- | engines/bladerunner/vqa_player.cpp | 135 | ||||
-rw-r--r-- | engines/bladerunner/vqa_player.h | 39 |
3 files changed, 129 insertions, 50 deletions
diff --git a/engines/bladerunner/script/scene/rc01.cpp b/engines/bladerunner/script/scene/rc01.cpp index 8d8b604a89..1a5367b0fc 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 4fb19cf561..e2b3833390 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 3a821a8323..941b3638ed 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); }; |