aboutsummaryrefslogtreecommitdiff
path: root/engines/bladerunner/vqa_player.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/bladerunner/vqa_player.cpp')
-rw-r--r--engines/bladerunner/vqa_player.cpp135
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) {