From 06c1d1c42eeba1c418f3d2789f26d68cf09cdd5a Mon Sep 17 00:00:00 2001 From: Miloslav Ciz Date: Sun, 20 Apr 2025 14:18:57 +0200 Subject: [PATCH] Add FPS measure --- TODO.txt | 2 +- frontend_sdl.c | 3 +++ game.h | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 62 insertions(+), 1 deletion(-) diff --git a/TODO.txt b/TODO.txt index be0ba06..e413072 100644 --- a/TODO.txt +++ b/TODO.txt @@ -14,7 +14,6 @@ inbetween world space and model space. - Consider better input handling in SDL? Currently it just detects presses on the exact frame, so a press can be missed. But how tho? -- FPS logging for optim - try to add distance fog? - use 332 in SDL with potato? - option to turn on simple 332 colors? @@ -79,6 +78,7 @@ =========== HANDLED ============== - MAP4: one triangle in top section is missing! +- FPS logging for optim - the pinch collision test seems to sometimes stop the car e.g. after falling from bigger height or when running into ramp at high speed (or not?) - FIX - sometimes during long loading the screen goes black, seems to have appeared diff --git a/frontend_sdl.c b/frontend_sdl.c index e6abfeb..2b91c7c 100644 --- a/frontend_sdl.c +++ b/frontend_sdl.c @@ -8,6 +8,9 @@ #define LCR_SETTING_LOG_LEVEL 2 #define DATA_FILE_NAME "data" #define LCR_LOADING_COMMAND SDL_PumpEvents(); + +// #define LCR_FPS_GET_MS SDL_GetTicks() // uncomment for FPS measuring + #include "game.h" SDL_Window *window; diff --git a/game.h b/game.h index e91cdea..b875875 100644 --- a/game.h +++ b/game.h @@ -176,6 +176,12 @@ uint8_t LCR_gameGetNextAudioSample(void); #define LCR_LOADING_COMMAND ; #endif +/* + To make the game log FPS define a macro named LCR_FPS_GET_MS to a command that + evaluates to the current number of milliseconds since some given time. It + will be used to measure frame duration and average values will be logged. +*/ + //------------------------------------------------------------------------------ #define LCR_LOG0(s) ; @@ -357,6 +363,13 @@ struct is to allow ghosts for even long replays. */ } ghost; #endif + +#ifdef LCR_FPS_GET_MS + uint16_t renderFrameMS; + uint16_t physicsFrameMS; + uint8_t renderFramesMeasured; + uint8_t physicsFramesMeasured; +#endif } LCR_game; uint8_t LCR_gameMusicOn(void) @@ -1039,6 +1052,11 @@ void LCR_gameInit(int argc, const char **argv) LCR_game.cameraMode = LCR_CAMERA_MODE_DRIVE; LCR_currentMap.blockCount = 0; // means no map loaded +#ifdef LCR_FPS_GET_MS + LCR_game.renderFrameMS = 0; + LCR_game.physicsFrameMS = 0; +#endif + LCR_LOG2("parsing arguments"); uint8_t quickLoad = 0; @@ -1550,6 +1568,10 @@ uint8_t LCR_gameStep(uint32_t time) { LCR_LOG2("game step (start)"); +#ifdef LCR_FPS_GET_MS + uint32_t frameTime; +#endif + uint32_t sleep = 0; int paused = LCR_game.state == LCR_GAME_STATE_MENU || LCR_game.state == LCR_GAME_STATE_RUN_STARTING; @@ -1593,8 +1615,17 @@ uint8_t LCR_gameStep(uint32_t time) (LCR_game.keyStates[LCR_KEY_DOWN] ? LCR_RACING_INPUT_BACK : 0) | (LCR_game.keyStates[LCR_KEY_LEFT] ? LCR_RACING_INPUT_LEFT : 0)); +#ifdef LCR_FPS_GET_MS + frameTime = LCR_FPS_GET_MS; +#endif + uint32_t events = paused ? 0 : LCR_racingStep(input); +#ifdef LCR_FPS_GET_MS + LCR_game.physicsFrameMS += LCR_FPS_GET_MS - frameTime; + LCR_game.physicsFramesMeasured++; +#endif + if (events & LCR_RACING_EVENT_CP_TAKEN) { int carBlock[3]; @@ -1680,6 +1711,10 @@ uint8_t LCR_gameStep(uint32_t time) while (time >= LCR_game.nextRenderFrameTime) LCR_game.nextRenderFrameTime += 1000 / LCR_SETTING_FPS; +#ifdef LCR_FPS_GET_MS + frameTime = LCR_FPS_GET_MS; +#endif + if ((LCR_game.state == LCR_GAME_STATE_MENU) || LCR_game.state == LCR_GAME_STATE_LOADING) LCR_rendererDrawMenu(LCR_texts[LCR_TEXTS_TABS @@ -1696,6 +1731,11 @@ uint8_t LCR_gameStep(uint32_t time) LCR_gameDrawPopupMessage(); LCR_game.popupCountdown--; } + +#ifdef LCR_FPS_GET_MS + LCR_game.renderFrameMS += LCR_FPS_GET_MS - frameTime; + LCR_game.renderFramesMeasured++; +#endif } else { @@ -1722,6 +1762,24 @@ uint8_t LCR_gameStep(uint32_t time) LCR_game.frame++; LCR_LOG2("game step (end)"); +#ifdef LCR_FPS_GET_MS + if (LCR_game.renderFramesMeasured >= 64) + { + LCR_LOG0("us/frame (render):"); + LCR_LOG0_NUM((LCR_game.renderFrameMS * 1000) / 64); + LCR_game.renderFramesMeasured = 0; + LCR_game.renderFrameMS = 0; + } + + if (LCR_game.physicsFramesMeasured >= 64) + { + LCR_LOG0("us/frame (physics):"); + LCR_LOG0_NUM((LCR_game.physicsFrameMS * 1000) / 64); + LCR_game.physicsFramesMeasured = 0; + LCR_game.physicsFrameMS = 0; + } +#endif + return 1; }