From a34422dc2605165a1cdbd7063daa8f11772dd844 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=CE=B6eh=20Matt?= Date: Thu, 17 Jan 2019 23:22:27 +0100 Subject: [PATCH] Fix #8591: Game loop does not run at a consistent tick rate of 40 Hz (#8594) * Fix #8591: Run game loop at consistent tick rate of 40hz. * Update distribution/changelog.txt Co-Authored-By: ZehMatt --- distribution/changelog.txt | 1 + src/openrct2/Context.cpp | 14 ++++++++------ src/openrct2/GameState.cpp | 14 +++++++++----- src/openrct2/network/Network.cpp | 2 +- 4 files changed, 19 insertions(+), 12 deletions(-) diff --git a/distribution/changelog.txt b/distribution/changelog.txt index df2b294615..1ffb085974 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -53,6 +53,7 @@ - Fix: [#8469] Crash modifying colour on hacked rides. - Fix: [#8508] Underground roto-drop is not going up. - Fix: [#8555] Multiplayer window text limits are not computed properly. +- Fix: [#8591] Game loop does not run at a consistent tick rate of 40 Hz. - Improved: [#2940] Allow mouse-dragging to set patrol area (Singleplayer only). - Improved: [#7730] Draw extreme vertical and lateral Gs red in the ride window's graph tab. - Improved: [#7930] Automatically create folders for custom content. diff --git a/src/openrct2/Context.cpp b/src/openrct2/Context.cpp index 2bd2ea66a9..aa4c63d3c2 100644 --- a/src/openrct2/Context.cpp +++ b/src/openrct2/Context.cpp @@ -857,7 +857,7 @@ namespace OpenRCT2 uint32_t elapsed = currentTick - _lastTick; _lastTick = currentTick; - _accumulator = std::min(_accumulator + elapsed, (uint32_t)GAME_UPDATE_MAX_THRESHOLD); + _accumulator = std::min(_accumulator + elapsed, static_cast(GAME_UPDATE_MAX_THRESHOLD)); _uiContext->ProcessMessages(); @@ -867,9 +867,12 @@ namespace OpenRCT2 return; } - _accumulator -= GAME_UPDATE_TIME_MS; + while (_accumulator >= GAME_UPDATE_TIME_MS) + { + Update(); + _accumulator -= GAME_UPDATE_TIME_MS; + } - Update(); if (!_isWindowMinimised && !gOpenRCT2Headless) { _drawingEngine->BeginDraw(); @@ -884,7 +887,6 @@ namespace OpenRCT2 uint32_t currentTick = platform_get_ticks(); bool draw = !_isWindowMinimised && !gOpenRCT2Headless; - if (_lastTick == 0) { sprite_position_tween_reset(); @@ -894,7 +896,7 @@ namespace OpenRCT2 uint32_t elapsed = currentTick - _lastTick; _lastTick = currentTick; - _accumulator = std::min(_accumulator + elapsed, (uint32_t)GAME_UPDATE_MAX_THRESHOLD); + _accumulator = std::min(_accumulator + elapsed, static_cast(GAME_UPDATE_MAX_THRESHOLD)); _uiContext->ProcessMessages(); @@ -915,7 +917,7 @@ namespace OpenRCT2 if (draw) { - const float alpha = (float)_accumulator / GAME_UPDATE_TIME_MS; + const float alpha = std::min((float)_accumulator / GAME_UPDATE_TIME_MS, 1.0f); sprite_position_tween_all(alpha); _drawingEngine->BeginDraw(); diff --git a/src/openrct2/GameState.cpp b/src/openrct2/GameState.cpp index b9be0b3eec..cb6de02a1e 100644 --- a/src/openrct2/GameState.cpp +++ b/src/openrct2/GameState.cpp @@ -73,11 +73,18 @@ void GameState::InitAll(int32_t mapSize) load_palette(); } +/** + * Function will be called every GAME_UPDATE_TIME_MS. + * It has its own loop which might run multiple updates per call such as + * when operating as a client it may run multiple updates to catch up with the server tick, + * another influence can be the game speed setting. + */ void GameState::Update() { gInUpdateCode = true; - uint32_t numUpdates; + // Normal game play will update only once every GAME_UPDATE_TIME_MS + uint32_t numUpdates = 1; // 0x006E3AEC // screen_game_process_mouse_input(); screenshot_check(); @@ -101,12 +108,9 @@ void GameState::Update() // Determine how many times we need to update the game if (gGameSpeed > 1) { + // Update more often if game speed is above normal. numUpdates = 1 << (gGameSpeed - 1); } - else - { - numUpdates = realtimeTicksElapsed; - } if (network_get_mode() == NETWORK_MODE_CLIENT && network_get_status() == NETWORK_STATUS_CONNECTED && network_get_authstatus() == NETWORK_AUTH_OK) diff --git a/src/openrct2/network/Network.cpp b/src/openrct2/network/Network.cpp index fc0d7ec66e..1d99495b65 100644 --- a/src/openrct2/network/Network.cpp +++ b/src/openrct2/network/Network.cpp @@ -30,7 +30,7 @@ // This string specifies which version of network stream current build uses. // It is used for making sure only compatible builds get connected, even within // single OpenRCT2 version. -#define NETWORK_STREAM_VERSION "21" +#define NETWORK_STREAM_VERSION "22" #define NETWORK_STREAM_ID OPENRCT2_VERSION "-" NETWORK_STREAM_VERSION static rct_peep* _pickup_peep = nullptr;