From 5ad0ddfbc08aa1c0f9f8728a174aedb2f73d507f Mon Sep 17 00:00:00 2001 From: anth64 Date: Sun, 23 Aug 2026 17:43:51 +0200 Subject: [PATCH] feat: add fps module for rolling frame/fps diagnostics Real-time 1-second rolling window, independent of tick rate or display refresh. --- bmake.mk | 2 +- gmake.mk | 2 +- include/fps.h | 21 +++++++++++++++++++++ src/fps.c | 41 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 64 insertions(+), 2 deletions(-) create mode 100644 include/fps.h create mode 100644 src/fps.c diff --git a/bmake.mk b/bmake.mk index 21e697f..9ac23c4 100644 --- a/bmake.mk +++ b/bmake.mk @@ -3,7 +3,7 @@ INPUT_SRC = src/platform/client/input/sdl.c .include "config.mk" -ENGINE_SRCS = src/skele.c ${CLOCK_SRC} +ENGINE_SRCS = src/skele.c src/fps.c ${CLOCK_SRC} SOFT_PLAT_SRCS = src/platform/client/video/sdl.c ${INPUT_SRC} GL_PLAT_SRCS = src/platform/client/video/gl.c ${INPUT_SRC} SOFT_CLIENT_SRCS = example/client/main.c diff --git a/gmake.mk b/gmake.mk index db65f74..a041560 100644 --- a/gmake.mk +++ b/gmake.mk @@ -8,7 +8,7 @@ endif include config.mk -ENGINE_SRCS := src/skele.c $(CLOCK_SRC) +ENGINE_SRCS := src/skele.c src/fps.c $(CLOCK_SRC) SOFT_PLAT_SRCS := src/platform/client/video/sdl.c $(INPUT_SRC) GL_PLAT_SRCS := src/platform/client/video/gl.c $(INPUT_SRC) SOFT_CLIENT_SRCS := example/client/main.c diff --git a/include/fps.h b/include/fps.h new file mode 100644 index 0000000..b110b14 --- /dev/null +++ b/include/fps.h @@ -0,0 +1,21 @@ +#ifndef SKELE_FPS_H +#define SKELE_FPS_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +extern float skele_fps; +extern float skele_frame_time_ms; +extern float skele_frame_budget_ms; + +void skele_fps_init(void); +void skele_fps_frame_mark(void); + +#ifdef __cplusplus +} +#endif + +#endif /* SKELE_FPS_H */ diff --git a/src/fps.c b/src/fps.c new file mode 100644 index 0000000..5cdf39a --- /dev/null +++ b/src/fps.c @@ -0,0 +1,41 @@ +#include "fps.h" +#include "clock.h" + +float skele_fps = 0.0f; +float skele_frame_time_ms = 0.0f; +float skele_frame_budget_ms = 0.0f; + +static uint64_t win_start = 0; +static uint64_t last_frame_ns = 0; +static uint64_t frame_ns_accum = 0; +static uint32_t frame_count = 0; + +void skele_fps_init(void) +{ + win_start = skele_time_ns(); + last_frame_ns = win_start; + frame_ns_accum = 0; + frame_count = 0; + skele_fps = 0.0f; + skele_frame_time_ms = 0.0f; +} + +void skele_fps_frame_mark(void) +{ + uint64_t now = skele_time_ns(); + + frame_ns_accum += now - last_frame_ns; + last_frame_ns = now; + frame_count++; + + if (now - win_start >= 1000000000ULL) { + double elapsed_s = (double)(now - win_start) / 1e9; + skele_fps = (float)(frame_count / elapsed_s); + skele_frame_time_ms = + (float)((frame_ns_accum / (double)frame_count) / 1e6); + + win_start = now; + frame_ns_accum = 0; + frame_count = 0; + } +}