From 5af15399ec1e00feab1d80fcdb65bac2b66c5499 Mon Sep 17 00:00:00 2001 From: athrxx Date: Thu, 28 Feb 2019 16:53:59 +0100 Subject: KYRA: (EOB) - improve timer handling --- engines/kyra/engine/eobcommon.cpp | 2 +- engines/kyra/engine/eobcommon.h | 5 ++- engines/kyra/engine/kyra_rpg.h | 4 +-- engines/kyra/engine/scene_eob.cpp | 3 ++ engines/kyra/engine/timer_eob.cpp | 67 +++++++++++++++++++++++++++++++++++---- 5 files changed, 70 insertions(+), 11 deletions(-) diff --git a/engines/kyra/engine/eobcommon.cpp b/engines/kyra/engine/eobcommon.cpp index 96cc131767..0efaab838a 100644 --- a/engines/kyra/engine/eobcommon.cpp +++ b/engines/kyra/engine/eobcommon.cpp @@ -154,7 +154,7 @@ EoBCoreEngine::EoBCoreEngine(OSystem *system, const GameFlags &flags) : KyraRpgE _spells = 0; _spellAnimBuffer = 0; _clericSpellOffset = 0; - _restPartyElapsedTime = 0; + _restPartyElapsedTime = _disableElapsedTime = 0; _allowSkip = false; _allowImport = false; diff --git a/engines/kyra/engine/eobcommon.h b/engines/kyra/engine/eobcommon.h index 293878cd52..c7f3fbcb14 100644 --- a/engines/kyra/engine/eobcommon.h +++ b/engines/kyra/engine/eobcommon.h @@ -338,6 +338,8 @@ protected: // timers void setupTimers(); + virtual void enableSysTimer(int sysTimer); + virtual void disableSysTimer(int sysTimer); void setCharEventTimer(int charIndex, uint32 countdown, int evnt, int updateExistingTimer); void deleteCharEventTimer(int charIndex, int evnt); void setupCharacterTimers(); @@ -357,7 +359,8 @@ protected: static const uint8 _clock2Timers[]; static const uint8 _numClock2Timers; - int32 _restPartyElapsedTime; + uint32 _disableElapsedTime; + uint32 _restPartyElapsedTime; // Mouse void setHandItem(Item itemIndex); diff --git a/engines/kyra/engine/kyra_rpg.h b/engines/kyra/engine/kyra_rpg.h index a132ec7419..a6625e169e 100644 --- a/engines/kyra/engine/kyra_rpg.h +++ b/engines/kyra/engine/kyra_rpg.h @@ -150,8 +150,8 @@ protected: // timers virtual void setupTimers() = 0; - void enableSysTimer(int sysTimer); - void disableSysTimer(int sysTimer); + virtual void enableSysTimer(int sysTimer); + virtual void disableSysTimer(int sysTimer); void enableTimer(int id); virtual uint8 getClock2Timer(int index) = 0; virtual uint8 getNumClock2Timers() = 0; diff --git a/engines/kyra/engine/scene_eob.cpp b/engines/kyra/engine/scene_eob.cpp index 7eab7ce55f..80d3e7d99e 100644 --- a/engines/kyra/engine/scene_eob.cpp +++ b/engines/kyra/engine/scene_eob.cpp @@ -35,8 +35,11 @@ namespace Kyra { void EoBCoreEngine::loadLevel(int level, int sub) { _currentLevel = level; _currentSub = sub; + if (!_loading) setHandItem(-1); + + disableSysTimer(2); uint32 end = _system->getMillis() + 500; readLevelFileData(level); diff --git a/engines/kyra/engine/timer_eob.cpp b/engines/kyra/engine/timer_eob.cpp index 8cac8d8abc..ef50201bc8 100644 --- a/engines/kyra/engine/timer_eob.cpp +++ b/engines/kyra/engine/timer_eob.cpp @@ -55,6 +55,48 @@ void EoBCoreEngine::setupTimers() { _timer->resetNextRun(); } +void EoBCoreEngine::enableSysTimer(int sysTimer) { + if (sysTimer != 2) + return; + + KyraRpgEngine::enableSysTimer(sysTimer); + + _disableElapsedTime = _system->getMillis() - _disableElapsedTime; + + for (int i = 0; i < 6; i++) { + EoBCharacter *c = &_characters[i]; + for (int ii = 0; ii < 10; ii++) { + if (c->timers[ii]) + c->timers[ii] += _disableElapsedTime; + } + } + + setupCharacterTimers(); + + if (_scriptTimersMode & 1) { + for (int i = 0; i < _scriptTimersCount; i++) { + if (_scriptTimers[i].next) + _scriptTimers[i].next += _disableElapsedTime; + } + } + + for (int i = 0; i < 5; i++) { + if (_wallsOfForce[i].block) + _wallsOfForce[i].duration += _disableElapsedTime; + } + + _disableElapsedTime = 0; +} + +void EoBCoreEngine::disableSysTimer(int sysTimer) { + if (sysTimer != 2) + return; + + KyraRpgEngine::disableSysTimer(sysTimer); + + _disableElapsedTime = _system->getMillis(); +} + void EoBCoreEngine::setCharEventTimer(int charIndex, uint32 countdown, int evnt, int updateExistingTimer) { uint32 ntime = _system->getMillis() + countdown * _tickLength; uint8 timerId = 0x30 | (charIndex & 0x0F); @@ -130,7 +172,7 @@ void EoBCoreEngine::setupCharacterTimers() { _timer->disable(0x30 | i); else { enableTimer(0x30 | i); - _timer->setCountdown(0x30 | i, (nextTimer - ctime) / _tickLength); + _timer->setCountdown(0x30 | i, nextTimer >= ctime ? (nextTimer - ctime) / _tickLength : 1); } } _timer->resetNextRun(); @@ -143,27 +185,38 @@ void EoBCoreEngine::advanceTimers(uint32 millis) { for (int ii = 0; ii < 10; ii++) { if (c->timers[ii] > ct) { uint32 chrt = c->timers[ii] - ct; - c->timers[ii] = chrt > millis ? ct + chrt - millis : ct; - } + c->timers[ii] = chrt > millis ? ct + chrt - millis : 1; + } else if (c->timers[ii]) { + c->timers[ii] = 1; + } } } + if (_disableElapsedTime) + _disableElapsedTime += (ct - _disableElapsedTime); + setupCharacterTimers(); if (_scriptTimersMode & 1) { for (int i = 0; i < _scriptTimersCount; i++) { if (_scriptTimers[i].next > ct) { uint32 chrt = _scriptTimers[i].next - ct; - _scriptTimers[i].next = chrt > millis ? ct + chrt - millis : ct; - } + _scriptTimers[i].next = chrt > millis ? ct + chrt - millis : 1; + } else if (_scriptTimers[i].next) { + _scriptTimers[i].next = 1; + } } } for (int i = 0; i < 5; i++) { + if (!_wallsOfForce[i].block) + continue; if (_wallsOfForce[i].duration > ct) { uint32 chrt = _wallsOfForce[i].duration - ct; - _wallsOfForce[i].duration = chrt > millis ? ct + chrt - millis : ct; - } + _wallsOfForce[i].duration = chrt > millis ? ct + chrt - millis : 1; + } else { + _wallsOfForce[i].duration = 1; + } } } -- cgit v1.2.3