Skip to content

Commit

Permalink
stats: fix ingame timer not working correctly
Browse files Browse the repository at this point in the history
Fixes #1420.

Also, refactors the stat calculation for simpler usage.

The timer would become inaccurate when opening the inventory due to the
internal stats timer not being reset on launch. As a result, the
previous value was meaningless, leading to incorrect elapsed time
calculations on the opening frame.
  • Loading branch information
rr- committed Jul 24, 2024
1 parent 54598df commit f644bec
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 7 deletions.
1 change: 0 additions & 1 deletion src/game/phase/phase_demo.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 3 additions & 1 deletion src/game/phase/phase_game.c
Original file line number Diff line number Diff line change
@@ -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"
Expand Down Expand Up @@ -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();
}
Expand All @@ -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++) {
Expand Down Expand Up @@ -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();
}
}
Expand Down
14 changes: 9 additions & 5 deletions src/game/phase/phase_inventory.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down
23 changes: 23 additions & 0 deletions src/game/stats.c
Original file line number Diff line number Diff line change
@@ -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"
Expand All @@ -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,
Expand Down Expand Up @@ -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);
4 changes: 4 additions & 0 deletions src/game/stats.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);

0 comments on commit f644bec

Please sign in to comment.