Skip to content

Commit

Permalink
BLADERUNNER: Fix bad timer initialization for actors after LOAD
Browse files Browse the repository at this point in the history
  • Loading branch information
antoniou79 committed May 31, 2019
1 parent 2b2c8d6 commit 35daa69
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 1 deletion.
3 changes: 3 additions & 0 deletions engines/bladerunner/actor.cpp
Expand Up @@ -255,7 +255,9 @@ void Actor::timerUpdate(int timerId) {
if (_timersLeft[timerId] <= 0) {
switch (timerId) {
case kActorTimerAIScriptCustomTask0:
// fall through
case kActorTimerAIScriptCustomTask1:
// fall through
case kActorTimerAIScriptCustomTask2:
if (!_vm->_aiScripts->isInsideScript() && !_vm->_sceneScript->isInsideScript()) {
_vm->_aiScripts->timerExpired(_id, timerId);
Expand Down Expand Up @@ -1397,6 +1399,7 @@ void Actor::save(SaveFileWriteStream &f) {

uint32 now = _vm->_time->getPauseStart();
for (int i = 0; i < kActorTimers; ++i) {
// this effectively stores the next timeDiff to be applied to timer i (in timerUpdate)
f.writeInt(now - _timersLast[i]);
}

Expand Down
17 changes: 16 additions & 1 deletion engines/bladerunner/bladerunner.cpp
Expand Up @@ -254,7 +254,12 @@ Common::Error BladeRunnerEngine::loadGameState(int slot) {
if (!BladeRunner::SaveFileManager::readHeader(*saveFile, header)) {
error("Invalid savegame");
}

setTotalPlayTime(header._playTime);
// this essentially does something similar with setTotalPlayTime
// reseting and updating Blade Runner's _pauseStart and offset before starting a loaded game
_time->resetPauseStart();

loadGame(*saveFile);

delete saveFile;
Expand Down Expand Up @@ -336,8 +341,17 @@ Common::Error BladeRunnerEngine::run() {
// end of additional code for gracefully handling end-game

if (ConfMan.hasKey("save_slot") && ConfMan.getInt("save_slot") != -1) {
// when loading from ScummVM main menu, we should emulate
// the Kia pause/resume in order to get a valid "current" time when the game
// is actually loaded (assuming delays can be introduced by a popup warning dialogue)
if(!_time->isLocked()) {
_time->pause();
}
loadGameState(ConfMan.getInt("save_slot"));
ConfMan.set("save_slot", "-1");
if(_time->isLocked()) {
_time->resume();
}
} else if (hasSavegames) {
_kia->_forceOpen = true;
_kia->open(kKIASectionLoad);
Expand Down Expand Up @@ -402,7 +416,6 @@ bool BladeRunnerEngine::startup(bool hasSavegames) {
_surfaceBack.create(640, 480, screenPixelFormat());

_time = new Time(this);

// Try to load the SUBTITLES.MIX first, before Startup.MIX
// allows overriding any identically named resources (such as the original font files and as a bonus also the TRE files for the UI and dialogue menu)
_subtitles = new Subtitles(this);
Expand Down Expand Up @@ -972,6 +985,8 @@ void BladeRunnerEngine::gameTick() {
_overlays->tick();

if (!inDialogueMenu) {
// TODO This is probably responsible for actors getting stuck in place
// after reaching a waypoint when dialoge menu is open
actorsUpdate();
}

Expand Down
9 changes: 9 additions & 0 deletions engines/bladerunner/time.cpp
Expand Up @@ -70,4 +70,13 @@ bool Time::isLocked() {
return _pauseCount > 0;
}

// To be called before loading a new game, since
// the offset should be reset to zero and _pauseStart should be current() (ie currentSystem() - _start)
// TODO Explore if it would make sense to only use the Engine methods for time accounting (pauseEngine, get/setTotalPlatTime)
// or do we need separated/independent time accounting and pausing?
void Time::resetPauseStart() {
_offset = 0;
_pauseStart = current();
}

} // End of namespace BladeRunner
1 change: 1 addition & 0 deletions engines/bladerunner/time.h
Expand Up @@ -44,6 +44,7 @@ class Time {
int getPauseStart();
int resume();
bool isLocked();
void resetPauseStart();
};

} // End of namespace BladeRunner
Expand Down

0 comments on commit 35daa69

Please sign in to comment.