From 35daa692aff1cb2d6aa0cbca3480fa8c50be55c6 Mon Sep 17 00:00:00 2001 From: Thanasis Antoniou Date: Fri, 31 May 2019 16:42:31 +0300 Subject: [PATCH] BLADERUNNER: Fix bad timer initialization for actors after LOAD --- engines/bladerunner/actor.cpp | 3 +++ engines/bladerunner/bladerunner.cpp | 17 ++++++++++++++++- engines/bladerunner/time.cpp | 9 +++++++++ engines/bladerunner/time.h | 1 + 4 files changed, 29 insertions(+), 1 deletion(-) diff --git a/engines/bladerunner/actor.cpp b/engines/bladerunner/actor.cpp index 1c87d8e668e5..dd5650c32443 100644 --- a/engines/bladerunner/actor.cpp +++ b/engines/bladerunner/actor.cpp @@ -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); @@ -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]); } diff --git a/engines/bladerunner/bladerunner.cpp b/engines/bladerunner/bladerunner.cpp index 6fc8dda67c59..3d20423c39d0 100644 --- a/engines/bladerunner/bladerunner.cpp +++ b/engines/bladerunner/bladerunner.cpp @@ -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; @@ -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); @@ -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); @@ -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(); } diff --git a/engines/bladerunner/time.cpp b/engines/bladerunner/time.cpp index 5d82a0cd551f..ff7b6a78b552 100644 --- a/engines/bladerunner/time.cpp +++ b/engines/bladerunner/time.cpp @@ -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 diff --git a/engines/bladerunner/time.h b/engines/bladerunner/time.h index 4e372ea05fd7..48fa23a59420 100644 --- a/engines/bladerunner/time.h +++ b/engines/bladerunner/time.h @@ -44,6 +44,7 @@ class Time { int getPauseStart(); int resume(); bool isLocked(); + void resetPauseStart(); }; } // End of namespace BladeRunner