util.c: floating point timers for game loop

This commit is contained in:
veclav talica 2024-07-08 23:47:22 +03:00
parent 98467831d1
commit 194bf0e266
4 changed files with 27 additions and 1 deletions

View File

@ -39,6 +39,7 @@ typedef struct context {
int64_t frame_accumulator; int64_t frame_accumulator;
int64_t delta_averager_residual; int64_t delta_averager_residual;
int64_t time_averager[4]; int64_t time_averager[4];
int64_t delta_time; /* preserves real time frame delta with no manipilation */
uint64_t tick_count; uint64_t tick_count;
uint64_t step_count; uint64_t step_count;

View File

@ -56,6 +56,7 @@ void main_loop(void) {
int64_t current_frame_time = SDL_GetPerformanceCounter(); int64_t current_frame_time = SDL_GetPerformanceCounter();
int64_t delta_time = current_frame_time - ctx.prev_frame_time; int64_t delta_time = current_frame_time - ctx.prev_frame_time;
ctx.prev_frame_time = current_frame_time; ctx.prev_frame_time = current_frame_time;
ctx.delta_time = delta_time;
/* handle unexpected timer anomalies (overflow, extra slow frames, etc) */ /* handle unexpected timer anomalies (overflow, extra slow frames, etc) */
if (delta_time > ctx.desired_frametime * 8) { /* ignore extra-slow frames */ if (delta_time > ctx.desired_frametime * 8) { /* ignore extra-slow frames */

View File

@ -1,4 +1,5 @@
#include "util.h" #include "util.h"
#include "context.h"
#include <SDL2/SDL.h> #include <SDL2/SDL.h>
#include <physfsrwops.h> #include <physfsrwops.h>
@ -186,5 +187,18 @@ t_frect to_frect(t_rect rect) {
void tick_timer(int *value) { void tick_timer(int *value) {
*value = MAX(*value - 1, 0); *value = MAX(*value - 1, 0);
}
void tick_ftimer(float *value) {
*value = MAX(*value - ((float)ctx.delta_time / (float)ctx.clocks_per_second), 0.0f);
}
bool tick_ftimer_repeat(float *value, float at) {
*value -= (float)ctx.delta_time / (float)ctx.clocks_per_second;
if (*value < 0.0f) {
*value += at;
return true;
}
return false;
} }

View File

@ -118,4 +118,14 @@ typedef struct fvec2 {
void tick_timer(int *value); void tick_timer(int *value);
/* decrements a floating point second-based timer, stopping at 0.0 */
/* meant for poll based real time logic in game logic */
/* note that it should be decremented only on the next tick after its creation */
void tick_ftimer(float *value);
/* same as `tick_ftimer` but instaed of clamping it repeats */
/* returns true if value was cycled */
bool tick_ftimer_repeat(float *value, float at);
#endif #endif