[Scummvm-git-logs] scummvm master -> 647e3e3b15baf8145eb4b0c3a68a8722a602525c
antoniou79
a.antoniou79 at gmail.com
Wed Jun 16 15:25:35 UTC 2021
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:
647e3e3b15 BLADERUNNER: Fix for resuming while a special loop plays
Commit: 647e3e3b15baf8145eb4b0c3a68a8722a602525c
https://github.com/scummvm/scummvm/commit/647e3e3b15baf8145eb4b0c3a68a8722a602525c
Author: antoniou79 (a.antoniou79 at gmail.com)
Date: 2021-06-16T18:25:25+03:00
Commit Message:
BLADERUNNER: Fix for resuming while a special loop plays
This is a better fix for the Zuben soup dump glitch (no exits) if user holds Esc down
Changed paths:
engines/bladerunner/bladerunner.cpp
engines/bladerunner/scene.cpp
engines/bladerunner/vqa_decoder.cpp
engines/bladerunner/vqa_decoder.h
engines/bladerunner/vqa_player.cpp
engines/bladerunner/vqa_player.h
diff --git a/engines/bladerunner/bladerunner.cpp b/engines/bladerunner/bladerunner.cpp
index 4434ec312a..c45f1b2c73 100644
--- a/engines/bladerunner/bladerunner.cpp
+++ b/engines/bladerunner/bladerunner.cpp
@@ -1126,6 +1126,7 @@ void BladeRunnerEngine::gameTick() {
bool backgroundChanged = false;
int frame = _scene->advanceFrame();
if (frame >= 0) {
+// debug("_sceneScript->sceneFrameAdvanced(%d)", frame);
_sceneScript->sceneFrameAdvanced(frame);
backgroundChanged = true;
}
diff --git a/engines/bladerunner/scene.cpp b/engines/bladerunner/scene.cpp
index 16dad7ef88..ace23893ba 100644
--- a/engines/bladerunner/scene.cpp
+++ b/engines/bladerunner/scene.cpp
@@ -299,7 +299,6 @@ void Scene::resume(bool isLoadingGame) {
loopStartSpecial(_specialLoopMode, _specialLoop, true);
if (_specialLoopMode == kSceneLoopModeLoseControl || _specialLoopMode == kSceneLoopModeChangeSet) {
_vm->playerGainsControl();
-
}
}
if (_specialLoopMode == kSceneLoopModeChangeSet) {
@@ -307,9 +306,19 @@ void Scene::resume(bool isLoadingGame) {
}
}
- int frame;
+ int frame, frameStart, frameEnd;
do {
+ // fast forward to targetFrame but do, at the very least, one advanceFrame() (with time=false)
frame = advanceFrame(false);
+ // check if active loop has changed, and we need to adjust targetFrame
+ if (_vqaPlayer->getCurrentBeginAndEndFrame(frame, &frameStart, &frameEnd)
+ && targetFrame >= 0
+ && (targetFrame < frameStart || targetFrame > frameEnd)
+ ) {
+ // active loop has changed, and targetFrame has a remnant frame value from the previous loop's frameset,
+ // so set it to the current loop's start
+ targetFrame = frameStart;
+ }
} while (frame >= 0 && frame != targetFrame);
if (!isLoadingGame) {
diff --git a/engines/bladerunner/vqa_decoder.cpp b/engines/bladerunner/vqa_decoder.cpp
index 6e8706c5b5..57760868c7 100644
--- a/engines/bladerunner/vqa_decoder.cpp
+++ b/engines/bladerunner/vqa_decoder.cpp
@@ -567,6 +567,17 @@ bool VQADecoder::getLoopBeginAndEndFrame(int loop, int *begin, int *end) {
return true;
}
+int VQADecoder::getLoopIdFromFrame(int frame) {
+ if (frame >= 0) {
+ for (int loopId = 0; loopId < _loopInfo.loopCount; ++loopId) {
+ if (frame >= _loopInfo.loops[loopId].begin && frame <= _loopInfo.loops[loopId].end) {
+ return loopId;
+ }
+ }
+ }
+ return -1;
+}
+
bool VQADecoder::readCLIP(Common::SeekableReadStream *s, uint32 size) {
s->skip(roundup(size));
return true;
diff --git a/engines/bladerunner/vqa_decoder.h b/engines/bladerunner/vqa_decoder.h
index 3690b73184..34110d7c0c 100644
--- a/engines/bladerunner/vqa_decoder.h
+++ b/engines/bladerunner/vqa_decoder.h
@@ -81,6 +81,7 @@ public:
uint16 frequency() const { return _header.freq; }
bool getLoopBeginAndEndFrame(int loop, int *begin, int *end);
+ int getLoopIdFromFrame(int frame);
struct Header {
uint16 version; // 0x00
diff --git a/engines/bladerunner/vqa_player.cpp b/engines/bladerunner/vqa_player.cpp
index fdf37e27b8..b29cfde1f8 100644
--- a/engines/bladerunner/vqa_player.cpp
+++ b/engines/bladerunner/vqa_player.cpp
@@ -62,9 +62,9 @@ bool VQAPlayer::open() {
}
_repeatsCount = 0;
- _loop = -1;
+ _loopNext = -1;
_frame = -1;
- _frameBegin = -1;
+ _frameBeginNext = -1;
_frameEnd = getFrameCount() - 1;
_frameEndQueued = -1;
_repeatsCountQueued = -1;
@@ -94,7 +94,7 @@ int VQAPlayer::update(bool forceDraw, bool advanceFrame, bool useTime, Graphics:
int result = -1;
if (_frameNext < 0) {
- _frameNext = _frameBegin;
+ _frameNext = _frameBeginNext;
}
if ((_repeatsCount > 0 || _repeatsCount == -1) && (_frameNext > _frameEnd)) {
@@ -111,16 +111,20 @@ int VQAPlayer::update(bool forceDraw, bool advanceFrame, bool useTime, Graphics:
// The code is similar to Scene::advanceFrame()
// This will be done once, since this first loop (loopId 1)
// is only executed once before moving on to loopId 2
- if (_name.equals("MA05_3.VQA") && _loop == 1) {
+ if (_name.equals("MA05_3.VQA") && _loopNext == 1) {
while (update(false, true, false) != 59) {
updateZBuffer(_vm->_zbuffer);
}
- _frameBegin = 60;
+ // This works because the loopId 1 executes once before moving to _loop 2
+ // See Scene::advanceFrame()
+ // Scene::loopEnded()
+ //
+ _frameBeginNext = 60;
}
#endif
}
- if (_frameNext != _frameBegin) {
- _frameNext = _frameBegin;
+ if (_frameNext != _frameBeginNext) {
+ _frameNext = _frameBeginNext;
}
if (loopEndQueued == -1) {
@@ -133,10 +137,9 @@ int VQAPlayer::update(bool forceDraw, bool advanceFrame, bool useTime, Graphics:
_repeatsCountQueued = -1;
if (_callbackLoopEnded != nullptr) {
- _callbackLoopEnded(_callbackData, 0, _loop);
+ _callbackLoopEnded(_callbackData, 0, _loopNext);
}
}
-
result = -1;
} else if (_frameNext > _frameEnd) {
result = -3;
@@ -254,7 +257,7 @@ bool VQAPlayer::setLoop(int loop, int repeatsCount, int loopSetMode, void (*call
return false;
}
if (setBeginAndEndFrame(begin, end, repeatsCount, loopSetMode, callback, callbackData)) {
- _loop = loop;
+ _loopNext = loop;
return true;
}
return false;
@@ -276,12 +279,12 @@ bool VQAPlayer::setBeginAndEndFrame(int begin, int end, int repeatsCount, int lo
}
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
+ // if the member var _repeatsCount is 0 (which means "current playing loop will not be repeated")
+ // then do not enqueue and, instead, treat the request as kLoopSetModeImmediate
loopSetMode = kLoopSetModeImmediate;
}
- _frameBegin = begin;
+ _frameBeginNext = begin;
if (loopSetMode == kLoopSetModeJustStart) {
_repeatsCount = repeatsCount;
@@ -307,6 +310,14 @@ bool VQAPlayer::seekToFrame(int frame) {
return true;
}
+bool VQAPlayer::getCurrentBeginAndEndFrame(int frame, int *begin, int *end) {
+ int playingLoop = _decoder.getLoopIdFromFrame(frame);
+ if (playingLoop != -1) {
+ return _decoder.getLoopBeginAndEndFrame(playingLoop, begin, end);
+ }
+ return false;
+}
+
int VQAPlayer::getLoopBeginFrame(int loop) {
int begin, end;
if (!_decoder.getLoopBeginAndEndFrame(loop, &begin, &end)) {
diff --git a/engines/bladerunner/vqa_player.h b/engines/bladerunner/vqa_player.h
index c3e1e99fd1..8b7efe6914 100644
--- a/engines/bladerunner/vqa_player.h
+++ b/engines/bladerunner/vqa_player.h
@@ -33,9 +33,9 @@
namespace BladeRunner {
enum LoopSetModes {
- kLoopSetModeJustStart = 0,
- kLoopSetModeEnqueue = 1,
- kLoopSetModeImmediate = 2
+ kLoopSetModeJustStart = 0, // sets _frameBeginNext, _repeatsCount, _frameEnd
+ kLoopSetModeEnqueue = 1, // sets _frameBeginNext, _repeatsCountQueued, _frameEndQueued
+ kLoopSetModeImmediate = 2 // like ModeJustStart, but also sets _frameNext to _frameBeginNext and updates _frameNextTime to current
};
class BladeRunnerEngine;
@@ -58,10 +58,18 @@ class VQAPlayer {
int _frame;
int _frameNext;
- int _frameBegin;
- int _frameEnd;
- int _loop;
- int _repeatsCount;
+ int _frameBeginNext; // The frame to begin from, after current playing loop ends.
+ // Does not necessarily reflect current playing loop's start frame
+ int _frameEnd; // The frame to end at for current playing loop
+ int _loopNext; // Does not necessarily reflect current playing loop's id
+ // Used: - as param for _callbackLoopEnded() (which typically is loopEnded()), but never actually used in there)
+ // - for the MA05 inshot glitch workaround
+ // It is set at every setLoop call except for the _loopInitial case (when no video stream is loaded)
+ int _repeatsCount; // -1 loop forever
+ // 0 final repetition (or don't repeat after playing)
+ // When that repetition is completeed VQAPlayer::update() returns -3 value
+ // See Scene::advanceFrame() and OuttakePlayer::play() for checks for -3 result
+ // Value is decreased per completed loop of current playing videoloop until it reaches 0
int _repeatsCountQueued;
int _frameEndQueued;
@@ -90,9 +98,9 @@ public:
_audioStream(nullptr),
_frame(-1),
_frameNext(-1),
- _frameBegin(-1),
+ _frameBeginNext(-1),
_frameEnd(-1),
- _loop(-1),
+ _loopNext(-1),
_repeatsCount(-1),
_repeatsCountQueued(-1),
_frameEndQueued(-1),
@@ -123,6 +131,7 @@ public:
bool seekToFrame(int frame);
+ bool getCurrentBeginAndEndFrame(int frame, int *begin, int *end);
int getLoopBeginFrame(int loop);
int getLoopEndFrame(int loop);
More information about the Scummvm-git-logs
mailing list