diff options
-rw-r--r-- | engines/bladerunner/bladerunner.cpp | 10 | ||||
-rw-r--r-- | engines/bladerunner/bladerunner.h | 4 | ||||
-rw-r--r-- | engines/bladerunner/outtake.cpp | 17 | ||||
-rw-r--r-- | engines/bladerunner/outtake.h | 1 | ||||
-rw-r--r-- | engines/bladerunner/ui/elevator.cpp | 13 | ||||
-rw-r--r-- | engines/bladerunner/ui/elevator.h | 3 | ||||
-rw-r--r-- | engines/bladerunner/ui/end_credits.cpp | 9 | ||||
-rw-r--r-- | engines/bladerunner/ui/esper.cpp | 49 | ||||
-rw-r--r-- | engines/bladerunner/ui/esper.h | 3 | ||||
-rw-r--r-- | engines/bladerunner/ui/kia.cpp | 6 | ||||
-rw-r--r-- | engines/bladerunner/ui/spinner.cpp | 16 | ||||
-rw-r--r-- | engines/bladerunner/ui/spinner.h | 3 | ||||
-rw-r--r-- | engines/bladerunner/ui/vk.cpp | 48 | ||||
-rw-r--r-- | engines/bladerunner/ui/vk.h | 3 |
14 files changed, 141 insertions, 44 deletions
diff --git a/engines/bladerunner/bladerunner.cpp b/engines/bladerunner/bladerunner.cpp index f451db1642..2da701f5d3 100644 --- a/engines/bladerunner/bladerunner.cpp +++ b/engines/bladerunner/bladerunner.cpp @@ -954,6 +954,7 @@ bool BladeRunnerEngine::isMouseButtonDown() const { void BladeRunnerEngine::gameLoop() { _gameIsRunning = true; + _timeOfMainGameLoopTickPrevious = _time->currentSystem(); do { if (_playerDead) { playerDied(); @@ -964,9 +965,11 @@ void BladeRunnerEngine::gameLoop() { } void BladeRunnerEngine::gameTick() { + handleEvents(); if (!_gameIsRunning || !_windowIsActive) { + _timeOfMainGameLoopTickPrevious = _time->currentSystem(); return; } @@ -975,6 +978,7 @@ void BladeRunnerEngine::gameTick() { Common::Error runtimeError = Common::Error(Common::kUnknownError, _("A required game resource was not found")); GUI::MessageDialog dialog(runtimeError.getDesc()); dialog.runModal(); + _timeOfMainGameLoopTickPrevious = _time->currentSystem(); return; } } @@ -1106,13 +1110,17 @@ void BladeRunnerEngine::gameTick() { _subtitles->tick(_surfaceFront); + uint32 mainGameLoopTickNow = _time->currentSystem(); + if (mainGameLoopTickNow - _timeOfMainGameLoopTickPrevious < kUpdateFrameTimeInMs) { + return; + } + _timeOfMainGameLoopTickPrevious = mainGameLoopTickNow; // Without this condition the game may flash back to the game screen // between and ending outtake and the end credits. if (!_gameOver) { blitToScreen(_surfaceFront); } - _system->delayMillis(10); } void BladeRunnerEngine::actorsUpdate() { diff --git a/engines/bladerunner/bladerunner.h b/engines/bladerunner/bladerunner.h index 3293741915..68c8c9b448 100644 --- a/engines/bladerunner/bladerunner.h +++ b/engines/bladerunner/bladerunner.h @@ -119,6 +119,8 @@ public: // 2: all time code uses uint32 (since July 17 2019), static const int kBladeRunnerScummVMVersion = 2; + static const uint32 kUpdateFrameTimeInMs = 16u; + bool _gameIsRunning; bool _windowIsActive; int _playerLosesControlCounter; @@ -238,6 +240,8 @@ public: int _actorUpdateCounter; uint32 _actorUpdateTimeLast; + uint32 _timeOfMainGameLoopTickPrevious; + private: MIXArchive _archives[kArchiveCount]; diff --git a/engines/bladerunner/outtake.cpp b/engines/bladerunner/outtake.cpp index 112a12085d..0c995ff614 100644 --- a/engines/bladerunner/outtake.cpp +++ b/engines/bladerunner/outtake.cpp @@ -26,6 +26,7 @@ #include "bladerunner/chapters.h" #include "bladerunner/subtitles.h" #include "bladerunner/vqa_player.h" +#include "bladerunner/time.h" #include "common/debug.h" #include "common/events.h" @@ -69,13 +70,26 @@ void OuttakePlayer::play(const Common::String &name, bool noLocalization, int co _vm->_vqaIsPlaying = true; _vm->_vqaStopIsRequested = false; + uint32 timeNow = 0; + bool firstFrame = true; + _timeLast = _vm->_time->currentSystem(); + while (!_vm->_vqaStopIsRequested && !_vm->shouldQuit()) { _vm->handleEvents(); if (!_vm->_windowIsActive) { + _timeLast = _vm->_time->currentSystem(); continue; } + timeNow = _vm->_time->currentSystem(); + // unsigned difference is intentional + if (timeNow - _timeLast < _vm->kUpdateFrameTimeInMs && !firstFrame) { + continue; + } else if (firstFrame) { + firstFrame = false; + } + int frame = vqaPlayer.update(); blit(_surfaceVideo, _vm->_surfaceFront); // This helps to make subtitles disappear properly, if the video is rendered in separate surface and then pushed to the front surface if (frame == -3) { // end of video @@ -87,8 +101,7 @@ void OuttakePlayer::play(const Common::String &name, bool noLocalization, int co _vm->_subtitles->tickOuttakes(_vm->_surfaceFront); _vm->blitToScreen(_vm->_surfaceFront); } - - _vm->_system->delayMillis(10); + _timeLast = timeNow; } _vm->_vqaIsPlaying = false; diff --git a/engines/bladerunner/outtake.h b/engines/bladerunner/outtake.h index 32b6690ba8..fc202736fa 100644 --- a/engines/bladerunner/outtake.h +++ b/engines/bladerunner/outtake.h @@ -34,6 +34,7 @@ class BladeRunnerEngine; class OuttakePlayer { BladeRunnerEngine *_vm; Graphics::Surface _surfaceVideo; + uint32 _timeLast; public: OuttakePlayer(BladeRunnerEngine *vm); diff --git a/engines/bladerunner/ui/elevator.cpp b/engines/bladerunner/ui/elevator.cpp index a3f795263a..15354c739c 100644 --- a/engines/bladerunner/ui/elevator.cpp +++ b/engines/bladerunner/ui/elevator.cpp @@ -187,6 +187,8 @@ int Elevator::activate(int elevatorId) { void Elevator::open() { resetDescription(); _isOpen = true; + _timeLast = _vm->_time->currentSystem(); + _firstTickCall = true; } bool Elevator::isOpen() const { @@ -205,9 +207,18 @@ int Elevator::handleMouseDown(int x, int y) { void Elevator::tick() { if (!_vm->_windowIsActive) { + _timeLast = _vm->_time->currentSystem(); return; } + uint32 timeNow = _vm->_time->currentSystem(); + // unsigned difference is intentional + if (timeNow - _timeLast < _vm->kUpdateFrameTimeInMs && !_firstTickCall) { + return; + } else if (_firstTickCall) { + _firstTickCall = false; + } + int frame = _vqaPlayer->update(); assert(frame >= -1); @@ -231,7 +242,7 @@ void Elevator::tick() { _vm->blitToScreen(_vm->_surfaceFront); tickDescription(); - _vm->_system->delayMillis(10); + _timeLast = timeNow; } void Elevator::buttonClick(int buttonId) { diff --git a/engines/bladerunner/ui/elevator.h b/engines/bladerunner/ui/elevator.h index 6ed91ce799..92afb6e2b7 100644 --- a/engines/bladerunner/ui/elevator.h +++ b/engines/bladerunner/ui/elevator.h @@ -43,6 +43,9 @@ class Elevator { int _sentenceId; uint32 _timeSpeakDescriptionStart; + uint32 _timeLast; + bool _firstTickCall; + public: Elevator(BladeRunnerEngine *vm); ~Elevator(); diff --git a/engines/bladerunner/ui/end_credits.cpp b/engines/bladerunner/ui/end_credits.cpp index 57ea6b3e7c..91e8501794 100644 --- a/engines/bladerunner/ui/end_credits.cpp +++ b/engines/bladerunner/ui/end_credits.cpp @@ -93,6 +93,7 @@ void EndCredits::show() { double position = 0.0; uint32 timeLast = _vm->_time->currentSystem(); + bool firstPass = true; while (!_vm->_vqaStopIsRequested && !_vm->shouldQuit()) { if (position >= textPositions[textCount - 1]) { @@ -109,6 +110,12 @@ void EndCredits::show() { } uint32 timeNow = _vm->_time->currentSystem(); + if (timeNow - timeLast < _vm->kUpdateFrameTimeInMs && !firstPass) { + continue; + } else if (firstPass) { + firstPass = false; + } + position += (double)(timeNow - timeLast) * 0.05f; // unsigned difference is intentional timeLast = timeNow; @@ -147,8 +154,6 @@ void EndCredits::show() { _vm->_surfaceFront.fillRect(Common::Rect(0, 452, 640, 480), 0); _vm->blitToScreen(_vm->_surfaceFront); - - _vm->_system->delayMillis(10); } _vm->_vqaIsPlaying = false; diff --git a/engines/bladerunner/ui/esper.cpp b/engines/bladerunner/ui/esper.cpp index 753b2f9532..a8877e9e1d 100644 --- a/engines/bladerunner/ui/esper.cpp +++ b/engines/bladerunner/ui/esper.cpp @@ -57,6 +57,7 @@ ESPER::ESPER(BladeRunnerEngine *vm) { _isDrawingSelection = false; _isOpen = false; + _firstTickCall = false; _shapeButton = nullptr; _shapeThumbnail = nullptr; _vqaPlayerMain = nullptr; @@ -115,6 +116,8 @@ void ESPER::open(Graphics::Surface *surface) { _vqaPlayerMain->setLoop(2, -1, kLoopSetModeJustStart, nullptr, nullptr); _isOpen = true; + _timeLast = _vm->_time->currentSystem(); + _firstTickCall = true; _flash = false; _script = new ESPERScript(_vm); @@ -207,33 +210,43 @@ void ESPER::handleMouseDown(int x, int y, bool mainButton) { void ESPER::tick() { if (!_vm->_windowIsActive) { + _timeLast = _vm->_time->currentSystem(); return; } - tickSound(); + uint32 timeNow = _vm->_time->currentSystem(); + // unsigned difference is intentional + if (timeNow - _timeLast < _vm->kUpdateFrameTimeInMs && !_firstTickCall) { + return; + } else { + if (_firstTickCall) { + _firstTickCall = false; + } + tickSound(); - blit(_vm->_surfaceBack, _vm->_surfaceFront); + blit(_vm->_surfaceBack, _vm->_surfaceFront); - int mouseX, mouseY; - _vm->_mouse->getXY(&mouseX, &mouseY); - if (!_vm->_mouse->isDisabled()) { - _buttons->handleMouseAction(mouseX, mouseY, false, false, false); - } + int mouseX, mouseY; + _vm->_mouse->getXY(&mouseX, &mouseY); + if (!_vm->_mouse->isDisabled()) { + _buttons->handleMouseAction(mouseX, mouseY, false, false, false); + } - if (!_isOpen) { - return; - } + if (!_isOpen) { + return; + } - draw(_vm->_surfaceFront); - _buttons->draw(_vm->_surfaceFront); - drawMouse(_vm->_surfaceFront); + draw(_vm->_surfaceFront); + _buttons->draw(_vm->_surfaceFront); + drawMouse(_vm->_surfaceFront); - tickSound(); - _vm->_subtitles->tick(_vm->_surfaceFront); - _vm->blitToScreen(_vm->_surfaceFront); + tickSound(); + _vm->_subtitles->tick(_vm->_surfaceFront); + _vm->blitToScreen(_vm->_surfaceFront); - // TODO: implement 60hz lock for smoother experience - _vm->_system->delayMillis(10); + // TODO: implement 60hz lock for smoother experience + _timeLast = timeNow; + } if (_statePhoto == kEsperPhotoStateVideoShow) { if (_regionSelectedAck) { diff --git a/engines/bladerunner/ui/esper.h b/engines/bladerunner/ui/esper.h index 33954cb34e..8360864963 100644 --- a/engines/bladerunner/ui/esper.h +++ b/engines/bladerunner/ui/esper.h @@ -184,6 +184,9 @@ class ESPER { int _volume3; int _ambientVolume; + uint32 _timeLast; + bool _firstTickCall; + public: ESPER(BladeRunnerEngine *vm); ~ESPER(); diff --git a/engines/bladerunner/ui/kia.cpp b/engines/bladerunner/ui/kia.cpp index 6980544fa8..ed5dabcb54 100644 --- a/engines/bladerunner/ui/kia.cpp +++ b/engines/bladerunner/ui/kia.cpp @@ -227,6 +227,7 @@ bool KIA::isOpen() const { void KIA::tick() { if (!isOpen()) { + _timeLast = _vm->_time->currentSystem(); return; } @@ -234,6 +235,10 @@ void KIA::tick() { // unsigned difference is intentional uint32 timeDiff = timeNow - _timeLast; + if (timeDiff < _vm->kUpdateFrameTimeInMs) { + return; + } + if (_playerActorDialogueQueueSize == _playerActorDialogueQueuePosition) { _playerActorDialogueState = 0; } else if (_playerActorDialogueState == 0) { @@ -383,7 +388,6 @@ void KIA::tick() { _vm->_subtitles->tick(_vm->_surfaceFront); _vm->blitToScreen(_vm->_surfaceFront); - _vm->_system->delayMillis(10); _timeLast = timeNow; } diff --git a/engines/bladerunner/ui/spinner.cpp b/engines/bladerunner/ui/spinner.cpp index cab2d67dee..1f3439ee9a 100644 --- a/engines/bladerunner/ui/spinner.cpp +++ b/engines/bladerunner/ui/spinner.cpp @@ -80,6 +80,8 @@ int Spinner::chooseDestination(int loopId, bool immediately) { if (loopId < 0) { _isOpen = true; + _timeLast = _vm->_time->currentSystem(); + _firstTickCall = true; } else { _vm->playerLosesControl(); _vm->_scene->loopStartSpecial(kSceneLoopModeSpinner, loopId, immediately); @@ -229,6 +231,8 @@ void Spinner::mouseUpCallback(int destinationImage, void *self) { void Spinner::open() { _isOpen = true; + _timeLast = _vm->_time->currentSystem(); + _firstTickCall = true; } bool Spinner::isOpen() const { @@ -247,9 +251,18 @@ int Spinner::handleMouseDown(int x, int y) { void Spinner::tick() { if (!_vm->_windowIsActive) { + _timeLast = _vm->_time->currentSystem(); return; } + uint32 timeNow = _vm->_time->currentSystem(); + // unsigned difference is intentional + if (timeNow - _timeLast < _vm->kUpdateFrameTimeInMs && !_firstTickCall) { + return; + } else if (_firstTickCall) { + _firstTickCall = false; + } + int frame = _vqaPlayer->update(); assert(frame >= -1); @@ -274,7 +287,7 @@ void Spinner::tick() { if (_vm->_cutContent) { tickDescription(); } - _vm->_system->delayMillis(10); + _timeLast = timeNow; } void Spinner::setSelectedDestination(int destination) { @@ -287,6 +300,7 @@ void Spinner::reset() { } _isOpen = false; + _firstTickCall = false; _destinations = nullptr; _selectedDestination = -1; _imagePicker = nullptr; diff --git a/engines/bladerunner/ui/spinner.h b/engines/bladerunner/ui/spinner.h index 2fa0dc659c..0477595ef4 100644 --- a/engines/bladerunner/ui/spinner.h +++ b/engines/bladerunner/ui/spinner.h @@ -56,6 +56,9 @@ class Spinner { int _sentenceId; uint32 _timeSpeakDescriptionStart; + uint32 _timeLast; + bool _firstTickCall; + public: Spinner(BladeRunnerEngine *vm); ~Spinner(); diff --git a/engines/bladerunner/ui/vk.cpp b/engines/bladerunner/ui/vk.cpp index 1cacf31584..e9064ab409 100644 --- a/engines/bladerunner/ui/vk.cpp +++ b/engines/bladerunner/ui/vk.cpp @@ -126,6 +126,8 @@ void VK::open(int actorId, int calibrationRatio) { } _isOpen = true; + _timeLast = _vm->_time->currentSystem(); + _firstTickCall = true; _script = new VKScript(_vm); @@ -190,28 +192,38 @@ void VK::close() { } void VK::tick() { - int mouseX, mouseY; - _vm->_mouse->getXY(&mouseX, &mouseY); - if (!_vm->_mouse->isDisabled()) { - _buttons->handleMouseAction(mouseX, mouseY, false, false, false); - } - draw(); + uint32 timeNow = _vm->_time->currentSystem(); + // unsigned difference is intentional + if (timeNow - _timeLast < _vm->kUpdateFrameTimeInMs && !_firstTickCall) { + return; + } else { + if (_firstTickCall) { + _firstTickCall = false; + } + int mouseX, mouseY; + _vm->_mouse->getXY(&mouseX, &mouseY); + if (!_vm->_mouse->isDisabled()) { + _buttons->handleMouseAction(mouseX, mouseY, false, false, false); + } + + draw(); - if ( _vm->_debugger->_showStatsVk - && !_vm->_actors[_actorId]->isSpeeching() - && !_vm->_actors[kActorMcCoy]->isSpeeching() - && !_vm->_actors[kActorAnsweringMachine]->isSpeeching() - && !_isClosing - ) { - _vm->_subtitles->setGameSubsText(Common::String::format("Calibration: %02d Ratio: %02d Anxiety: %02d%%\nReplicant: %02d%% Human: %02d%%", _calibration, _calibrationRatio, _anxiety, _replicantProbability, _humanProbability), true); - _vm->_subtitles->show(); - } + if ( _vm->_debugger->_showStatsVk + && !_vm->_actors[_actorId]->isSpeeching() + && !_vm->_actors[kActorMcCoy]->isSpeeching() + && !_vm->_actors[kActorAnsweringMachine]->isSpeeching() + && !_isClosing + ) { + _vm->_subtitles->setGameSubsText(Common::String::format("Calibration: %02d Ratio: %02d Anxiety: %02d%%\nReplicant: %02d%% Human: %02d%%", _calibration, _calibrationRatio, _anxiety, _replicantProbability, _humanProbability), true); + _vm->_subtitles->show(); + } - _vm->_subtitles->tick(_vm->_surfaceFront); + _vm->_subtitles->tick(_vm->_surfaceFront); - _vm->blitToScreen(_vm->_surfaceFront); - _vm->_system->delayMillis(10); + _vm->blitToScreen(_vm->_surfaceFront); + _timeLast = timeNow; + } // unsigned difference is intentional if (_isClosing && (_vm->_time->current() - _timeCloseStart >= 3000u) && !_script->isInsideScript()) { diff --git a/engines/bladerunner/ui/vk.h b/engines/bladerunner/ui/vk.h index eeaee1b54d..8593e6b1b3 100644 --- a/engines/bladerunner/ui/vk.h +++ b/engines/bladerunner/ui/vk.h @@ -124,6 +124,9 @@ class VK { uint32 _timeNextEyeLineStepStart; uint32 _timeNextEyeLineStart; + uint32 _timeLast; + bool _firstTickCall; + public: VK(BladeRunnerEngine *vm); ~VK(); |