mirror of
https://github.com/libretro/scummvm.git
synced 2025-02-04 09:56:30 +00:00
BLADERUNNER: Release non-repeated and support queued overlays
This commit is contained in:
parent
fa50678125
commit
20d77710c9
@ -23,6 +23,7 @@
|
||||
#include "bladerunner/overlays.h"
|
||||
|
||||
#include "bladerunner/bladerunner.h"
|
||||
#include "bladerunner/game_constants.h"
|
||||
|
||||
#include "bladerunner/archive.h"
|
||||
#include "bladerunner/savefile.h"
|
||||
@ -58,6 +59,10 @@ Overlays::~Overlays() {
|
||||
|
||||
int Overlays::play(const Common::String &name, int loopId, bool loopForever, bool startNow, int a6) {
|
||||
assert(name.size() <= 12);
|
||||
if (loopId < 0) {
|
||||
warning("Overlays::play - loop id can't be a negative number!");
|
||||
return -1;
|
||||
}
|
||||
|
||||
int32 hash = MIXArchive::getHash(name);
|
||||
int index = findByHash(hash);
|
||||
@ -70,20 +75,38 @@ int Overlays::play(const Common::String &name, int loopId, bool loopForever, boo
|
||||
_videos[index].name = name;
|
||||
_videos[index].hash = hash;
|
||||
_videos[index].loopId = loopId;
|
||||
_videos[index].enqueuedLoopId = -1;
|
||||
_videos[index].loopForever = loopForever;
|
||||
_videos[index].vqaPlayer = new VQAPlayer(_vm, &_vm->_surfaceFront, Common::String::format("%s.VQA", name.c_str()));
|
||||
|
||||
if (!_videos[index].vqaPlayer) {
|
||||
resetSingle(index);
|
||||
return -1;
|
||||
}
|
||||
// TODO? Removed as redundant
|
||||
// repeat forever
|
||||
_videos[index].vqaPlayer->setBeginAndEndFrame(0, 0, -1, kLoopSetModeJustStart, nullptr, nullptr);
|
||||
//_videos[index].vqaPlayer->setBeginAndEndFrame(0, 0, -1, kLoopSetModeJustStart, nullptr, nullptr);
|
||||
}
|
||||
|
||||
_videos[index].vqaPlayer->open();
|
||||
_videos[index].vqaPlayer->setLoop(
|
||||
loopId,
|
||||
loopForever ? -1 : 0,
|
||||
startNow ? kLoopSetModeImmediate : kLoopSetModeEnqueue,
|
||||
nullptr, nullptr);
|
||||
bool skipNewVQAPlayerOpen = false;
|
||||
if (_videos[index].vqaPlayer
|
||||
&& !startNow
|
||||
&& _videos[index].vqaPlayer->getFrameCount() > 0
|
||||
) {
|
||||
skipNewVQAPlayerOpen = true;
|
||||
_videos[index].enqueuedLoopId = loopId;
|
||||
}
|
||||
|
||||
if (skipNewVQAPlayerOpen || _videos[index].vqaPlayer->open()) {
|
||||
_videos[index].vqaPlayer->setLoop(
|
||||
loopId,
|
||||
loopForever ? -1 : 0,
|
||||
startNow ? kLoopSetModeImmediate : kLoopSetModeEnqueue,
|
||||
nullptr, nullptr);
|
||||
} else {
|
||||
resetSingle(index);
|
||||
return -1;
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
@ -179,7 +202,12 @@ void Overlays::save(SaveFileWriteStream &f) {
|
||||
f.writeInt(0); // vqaPlayer pointer
|
||||
f.writeStringSz(ov.name, 13);
|
||||
f.writeSint32LE(ov.hash);
|
||||
f.writeInt(ov.loopId);
|
||||
if (ov.enqueuedLoopId != -1) {
|
||||
// When there is an enqueued video, save that loop Id instead
|
||||
f.writeInt(ov.enqueuedLoopId);
|
||||
} else {
|
||||
f.writeInt(ov.loopId);
|
||||
}
|
||||
f.writeBool(ov.loopForever);
|
||||
f.writeInt(ov.frame);
|
||||
}
|
||||
|
@ -48,6 +48,7 @@ class Overlays {
|
||||
Common::String name;
|
||||
int32 hash;
|
||||
int loopId;
|
||||
int enqueuedLoopId;
|
||||
bool loopForever;
|
||||
int frame;
|
||||
};
|
||||
|
@ -67,7 +67,7 @@ void SceneScriptBB06::InitializeScene() {
|
||||
#else
|
||||
// bugfix: case of not transitioning from BB51: chess/ egg boiler sub-space
|
||||
if (Game_Flag_Query(kFlagBB06AndroidDestroyed)) {
|
||||
Overlay_Play("BB06OVER", 1, false, false, 0);
|
||||
Overlay_Play("BB06OVER", 1, true, true, 0);
|
||||
}
|
||||
#endif // BLADERUNNER_ORIGINAL_BUGS
|
||||
}
|
||||
@ -111,8 +111,17 @@ bool SceneScriptBB06::ClickedOn3DObject(const char *objectName, bool a2) {
|
||||
}
|
||||
#else
|
||||
if (Player_Query_Combat_Mode()) {
|
||||
Overlay_Play("BB06OVER", 0, false, true, 0); // explosion - don't loop
|
||||
// Doll Explosion case:
|
||||
// We need to use enqueued overlays for this.
|
||||
// Note: Queuing only works on top of a video that is repeating itself.
|
||||
// First we load the "exploding animation state" as a forever loop (even though it will only play once)
|
||||
// Then we enqueue the final exploded state loop, also as a forever loop.
|
||||
// This (along with some fixes in the Overlays class will ensure
|
||||
// that the second overlay will play after the first has completed one loop
|
||||
// and it will persist (across save games too).
|
||||
Game_Flag_Set(kFlagBB06AndroidDestroyed);
|
||||
Overlay_Play("BB06OVER", 0, true, true, 0);
|
||||
Overlay_Play("BB06OVER", 1, true, false, 0);
|
||||
Un_Combat_Target_Object("BOX31");
|
||||
return true;
|
||||
} else {
|
||||
@ -195,7 +204,7 @@ void SceneScriptBB06::SceneFrameAdvanced(int frame) {
|
||||
// last frame of transition is 15, try 13 for better transition - minimize weird effect
|
||||
if (frame == 13) { // executed once during transition FROM bb51 (chess sub space)
|
||||
if (Game_Flag_Query(kFlagBB06AndroidDestroyed)) {
|
||||
Overlay_Play("BB06OVER", 1, false, false, 0);
|
||||
Overlay_Play("BB06OVER", 1, true, true, 0);
|
||||
}
|
||||
}
|
||||
#endif // BLADERUNNER_ORIGINAL_BUGS
|
||||
|
@ -51,7 +51,7 @@ void SceneScriptBB51::InitializeScene() {
|
||||
#if BLADERUNNER_ORIGINAL_BUGS // Sebastian's Doll Fix
|
||||
#else
|
||||
if (Game_Flag_Query(kFlagBB06AndroidDestroyed)) {
|
||||
Overlay_Play("BB06OVER", 1, false, false, 0);
|
||||
Overlay_Play("BB06OVER", 1, true, true, 0);
|
||||
}
|
||||
#endif // BLADERUNNER_ORIGINAL_BUGS
|
||||
|
||||
|
@ -57,10 +57,12 @@ bool VQAPlayer::open() {
|
||||
_repeatsCountQueued = -1;
|
||||
|
||||
if (_loopInitial >= 0) {
|
||||
// TODO? When does this happen? _loopInitial seems to be unused
|
||||
setLoop(_loopInitial, _repeatsCountInitial, kLoopSetModeImmediate, nullptr, nullptr);
|
||||
} else {
|
||||
_frameNext = 0;
|
||||
setBeginAndEndFrame(0, _frameEnd, 0, kLoopSetModeJustStart, nullptr, nullptr);
|
||||
// TODO? Removed as redundant
|
||||
// setBeginAndEndFrame(0, _frameEnd, 0, kLoopSetModeJustStart, nullptr, nullptr);
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -107,6 +109,8 @@ int VQAPlayer::update(bool forceDraw, bool advanceFrame, bool useTime, Graphics:
|
||||
result = -1;
|
||||
} else if (_frameNext > _frameEnd) {
|
||||
result = -3;
|
||||
// _repeatsCount == 0, so return here at the end of the video, to release the resource
|
||||
return result;
|
||||
} else if (useTime && (now < _frameNextTime)) {
|
||||
result = -1;
|
||||
} else if (advanceFrame) {
|
||||
@ -149,7 +153,9 @@ int VQAPlayer::update(bool forceDraw, bool advanceFrame, bool useTime, Graphics:
|
||||
_decoder.decodeVideoFrame(customSurface != nullptr ? customSurface : _surface, _frame, true);
|
||||
result = _frame;
|
||||
}
|
||||
return result;
|
||||
return result; // Note: result here could be negative.
|
||||
// Negative valid value should only be -1, since there are various assertions
|
||||
// assert(frame >= -1) in overlay modes (elevator, scores, spinner)
|
||||
}
|
||||
|
||||
void VQAPlayer::updateZBuffer(ZBuffer *zbuffer) {
|
||||
@ -187,11 +193,23 @@ bool VQAPlayer::setLoop(int loop, int repeatsCount, int loopSetMode, void (*call
|
||||
}
|
||||
|
||||
bool VQAPlayer::setBeginAndEndFrame(int begin, int end, int repeatsCount, int loopSetMode, void (*callback)(void *, int, int), void *callbackData) {
|
||||
if ( begin >= getFrameCount()
|
||||
|| end >= getFrameCount()
|
||||
|| begin >= end
|
||||
|| loopSetMode < 0
|
||||
|| loopSetMode >= 3
|
||||
) {
|
||||
warning("VQAPlayer::setBeginAndEndFrame - Invalid arguments for video");
|
||||
return false; // VQA_DECODER_ERROR_BAD_INPUT case
|
||||
}
|
||||
|
||||
if (repeatsCount < 0) {
|
||||
repeatsCount = -1;
|
||||
}
|
||||
|
||||
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
|
||||
loopSetMode = kLoopSetModeImmediate;
|
||||
}
|
||||
|
||||
@ -199,6 +217,7 @@ bool VQAPlayer::setBeginAndEndFrame(int begin, int end, int repeatsCount, int lo
|
||||
|
||||
if (loopSetMode == kLoopSetModeJustStart) {
|
||||
_repeatsCount = repeatsCount;
|
||||
_frameEnd = end;
|
||||
} else if (loopSetMode == kLoopSetModeEnqueue) {
|
||||
_repeatsCountQueued = repeatsCount;
|
||||
_frameEndQueued = end;
|
||||
|
Loading…
x
Reference in New Issue
Block a user