diff --git a/src/game/phase/phase_demo.c b/src/game/phase/phase_demo.c index 9d7b2d353e..7b9731114b 100644 --- a/src/game/phase/phase_demo.c +++ b/src/game/phase/phase_demo.c @@ -249,7 +249,6 @@ static GAMEFLOW_COMMAND Phase_Demo_Run(int32_t nframes) Sound_ResetAmbient(); Effect_RunActiveFlipEffect(); Sound_UpdateEffects(); - g_GameInfo.current[g_CurrentLevel].stats.timer++; Overlay_BarHealthTimerTick(); // Discard demo input; check for debounced real keypresses diff --git a/src/game/phase/phase_game.c b/src/game/phase/phase_game.c index 942475c6c4..e7be45ece3 100644 --- a/src/game/phase/phase_game.c +++ b/src/game/phase/phase_game.c @@ -1,5 +1,6 @@ #include "game/phase/phase_game.h" +#include "game/stats.h" #include "game/camera.h" #include "game/effects.h" #include "game/game.h" @@ -33,6 +34,7 @@ static void Phase_Game_Draw(void); static void Phase_Game_Start(void *arg) { Interpolation_Remember(); + Stats_StartTimer(); if (Phase_Get() != PHASE_PAUSE) { Output_FadeReset(); } @@ -45,6 +47,7 @@ static void Phase_Game_End(void) static GAMEFLOW_COMMAND Phase_Game_Control(int32_t nframes) { Interpolation_Remember(); + Stats_UpdateTimer(); CLAMPG(nframes, MAX_FRAMES); for (int32_t i = 0; i < nframes; i++) { @@ -123,7 +126,6 @@ static GAMEFLOW_COMMAND Phase_Game_Control(int32_t nframes) Sound_ResetAmbient(); Effect_RunActiveFlipEffect(); Sound_UpdateEffects(); - g_GameInfo.current[g_CurrentLevel].stats.timer++; Overlay_BarHealthTimerTick(); } } diff --git a/src/game/phase/phase_inventory.c b/src/game/phase/phase_inventory.c index c1b4570bbb..7a5849f4d1 100644 --- a/src/game/phase/phase_inventory.c +++ b/src/game/phase/phase_inventory.c @@ -5,6 +5,7 @@ #include "game/console.h" #include "game/game.h" #include "game/gameflow.h" +#include "game/stats.h" #include "game/input.h" #include "game/interpolation.h" #include "game/inventory.h" @@ -571,6 +572,9 @@ static bool Inv_CheckDemoTimer(const IMOTION_INFO *const motion) static void Phase_Inventory_Start(void *arg) { Interpolation_Remember(); + if (g_Config.enable_timer_in_inventory) { + Stats_StartTimer(); + } INV_MODE inv_mode = (INV_MODE)arg; @@ -696,11 +700,6 @@ static GAMEFLOW_COMMAND Phase_Inventory_ControlFrame(void) && ((ring->type == RT_MAIN && g_InvKeysObjects) || (ring->type == RT_OPTION && g_InvMainObjects)); - if (g_Config.enable_timer_in_inventory) { - const double ticks = Clock_GetElapsedLogicalFrames(&m_StatsTimer); - g_GameInfo.current[g_CurrentLevel].stats.timer += round(ticks); - } - if (ring->rotating) { return (GAMEFLOW_COMMAND) { .command = GF_PHASE_CONTINUE, @@ -1091,12 +1090,17 @@ static GAMEFLOW_COMMAND Phase_Inventory_ControlFrame(void) static GAMEFLOW_COMMAND Phase_Inventory_Control(int32_t nframes) { Interpolation_Remember(); + if (g_Config.enable_timer_in_inventory) { + Stats_UpdateTimer(); + } + for (int32_t i = 0; i < nframes; i++) { GAMEFLOW_COMMAND result = Phase_Inventory_ControlFrame(); if (result.command != GF_PHASE_CONTINUE) { return result; } } + return (GAMEFLOW_COMMAND) { .command = GF_PHASE_CONTINUE, .param = 0, diff --git a/src/game/stats.c b/src/game/stats.c index bb8ba41f62..11b5c33ffa 100644 --- a/src/game/stats.c +++ b/src/game/stats.c @@ -1,6 +1,7 @@ #include "game/stats.h" #include "game/carrier.h" +#include "game/clock.h" #include "game/gamebuf.h" #include "game/gameflow.h" #include "game/items.h" @@ -25,6 +26,11 @@ static uint32_t m_SecretRoom = 0; static bool m_KillableItems[MAX_ITEMS] = { 0 }; static bool m_IfKillable[O_NUMBER_OF] = { 0 }; +static struct { + double start_counter; + int32_t start_timer; +} m_StatsTimer = { 0 }; + int16_t m_PickupObjs[] = { O_PICKUP_ITEM1, O_PICKUP_ITEM2, O_KEY_ITEM1, O_KEY_ITEM2, O_KEY_ITEM3, O_KEY_ITEM4, O_PUZZLE_ITEM1, O_PUZZLE_ITEM2, O_PUZZLE_ITEM3, @@ -282,3 +288,20 @@ bool Stats_CheckAllSecretsCollected(GAMEFLOW_LEVEL_TYPE level_type) Stats_ComputeTotal(level_type, &total_stats); return total_stats.player_secret_count >= total_stats.total_secret_count; } + +void Stats_StartTimer(void) +{ + m_StatsTimer.start_counter = Clock_GetHighPrecisionCounter(); + m_StatsTimer.start_timer = g_GameInfo.current[g_CurrentLevel].stats.timer; +} + +void Stats_UpdateTimer(void) +{ + const double elapsed = + (Clock_GetHighPrecisionCounter() - m_StatsTimer.start_counter) + * LOGIC_FPS / 1000.0; + g_GameInfo.current[g_CurrentLevel].stats.timer = + m_StatsTimer.start_timer + elapsed; +} + +void Stats_StopTimer(void); diff --git a/src/game/stats.h b/src/game/stats.h index e9b2821b52..2ef2189696 100644 --- a/src/game/stats.h +++ b/src/game/stats.h @@ -24,3 +24,7 @@ int32_t Stats_GetKillables(void); int32_t Stats_GetSecrets(void); void Stats_ComputeTotal(GAMEFLOW_LEVEL_TYPE level_type, TOTAL_STATS *stats); bool Stats_CheckAllSecretsCollected(GAMEFLOW_LEVEL_TYPE level_type); + +void Stats_StartTimer(void); +void Stats_UpdateTimer(void); +void Stats_StopTimer(void);