diff options
Diffstat (limited to 'engines/bladerunner/vqa_player.cpp')
-rw-r--r-- | engines/bladerunner/vqa_player.cpp | 135 |
1 files changed, 101 insertions, 34 deletions
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) { |