diff options
| author | 3gg <3gg@shellblade.net> | 2026-04-12 10:48:04 -0700 |
|---|---|---|
| committer | 3gg <3gg@shellblade.net> | 2026-04-12 10:48:04 -0700 |
| commit | e5fe20ad83e01b3c8262ac90af984da47d8a16a1 (patch) | |
| tree | ffb55eabccc2018cb0359dc054fdadebfc815d65 /simloop/src/simloop.c | |
| parent | 9dceaee478545ed8df89722f5c90bb171de100e8 (diff) | |
Work in terms of time deltas; remove dependency on timer module
Diffstat (limited to 'simloop/src/simloop.c')
| -rw-r--r-- | simloop/src/simloop.c | 56 |
1 files changed, 30 insertions, 26 deletions
diff --git a/simloop/src/simloop.c b/simloop/src/simloop.c index 606f5ed..bd5a72d 100644 --- a/simloop/src/simloop.c +++ b/simloop/src/simloop.c | |||
| @@ -2,9 +2,9 @@ | |||
| 2 | 2 | ||
| 3 | #include <assert.h> | 3 | #include <assert.h> |
| 4 | 4 | ||
| 5 | static uint64_t ddt_from_fps(int fps) { | 5 | static simloop_time_t ddt_from_fps(int fps) { |
| 6 | static constexpr double NANOSECONDS = 1e9; | 6 | static constexpr double NANOSECONDS = 1e9; |
| 7 | return (fps == 0) ? 0 : (uint64_t)(NANOSECONDS / (double)fps); | 7 | return (fps == 0) ? 0 : (simloop_time_t)(NANOSECONDS / (double)fps); |
| 8 | } | 8 | } |
| 9 | 9 | ||
| 10 | Simloop simloop_make(const SimloopArgs* args) { | 10 | Simloop simloop_make(const SimloopArgs* args) { |
| @@ -12,31 +12,30 @@ Simloop simloop_make(const SimloopArgs* args) { | |||
| 12 | assert(args->update_fps > 0); | 12 | assert(args->update_fps > 0); |
| 13 | 13 | ||
| 14 | return (Simloop){ | 14 | return (Simloop){ |
| 15 | .frame = 0, | 15 | .frame = 0, |
| 16 | .update = (SimloopTimeline){.ddt = ddt_from_fps(args->update_fps), | 16 | .update = |
| 17 | .last_step = args->timer->start_time}, | 17 | (SimloopTimeline){ |
| 18 | .render = (SimloopTimeline){ .ddt = ddt_from_fps(args->max_render_fps), | 18 | .ddt = ddt_from_fps(args->update_fps), |
| 19 | .last_step = args->timer->start_time}, | 19 | .time = 0, |
| 20 | .timer = args->timer, | 20 | }, |
| 21 | .first_iter = true, | 21 | .render = |
| 22 | (SimloopTimeline){ | ||
| 23 | .ddt = ddt_from_fps(args->max_render_fps), | ||
| 24 | .time = 0, | ||
| 25 | }, | ||
| 26 | .first_iter = true, | ||
| 22 | .updates_since_last_render = false, | 27 | .updates_since_last_render = false, |
| 23 | }; | 28 | }; |
| 24 | } | 29 | } |
| 25 | 30 | ||
| 26 | static time_delta time_elapsed(const Simloop* sim, time_point t) { | ||
| 27 | assert(sim); | ||
| 28 | return time_diff(sim->timer->start_time, t); | ||
| 29 | } | ||
| 30 | |||
| 31 | static bool step_update(const Simloop* sim, SimloopTimeline* timeline) { | 31 | static bool step_update(const Simloop* sim, SimloopTimeline* timeline) { |
| 32 | assert(sim); | 32 | assert(sim); |
| 33 | assert(timeline); | 33 | assert(timeline); |
| 34 | assert(timeline->ddt > 0); | 34 | assert(timeline->ddt > 0); |
| 35 | 35 | ||
| 36 | const time_delta dt = time_diff(timeline->last_step, sim->timer->last_tick); | 36 | const simloop_time_t dt = sim->clock - timeline->time; |
| 37 | const bool should_step = dt >= timeline->ddt; | 37 | const bool should_step = dt >= timeline->ddt; |
| 38 | timeline->last_step = | 38 | timeline->time += should_step ? timeline->ddt : 0; |
| 39 | should_step ? time_add(timeline->last_step, dt) : timeline->last_step; | ||
| 40 | return should_step; | 39 | return should_step; |
| 41 | } | 40 | } |
| 42 | 41 | ||
| @@ -48,32 +47,37 @@ static bool step_render(const Simloop* sim, SimloopTimeline* timeline) { | |||
| 48 | if (timeline->ddt > 0) { | 47 | if (timeline->ddt > 0) { |
| 49 | render = step_update(sim, timeline); | 48 | render = step_update(sim, timeline); |
| 50 | } else { | 49 | } else { |
| 51 | timeline->last_step = sim->timer->last_tick; | 50 | timeline->time = sim->clock; |
| 52 | render = true; | 51 | render = true; |
| 53 | } | 52 | } |
| 54 | return render; | 53 | return render; |
| 55 | } | 54 | } |
| 56 | 55 | ||
| 57 | void simloop_update(Simloop* sim, SimloopOut* out) { | 56 | void simloop_update(Simloop* sim, simloop_time_t dt, SimloopOut* out) { |
| 58 | assert(sim); | 57 | assert(sim); |
| 59 | assert(out); | 58 | assert(out); |
| 60 | 59 | ||
| 60 | sim->clock += dt; | ||
| 61 | |||
| 61 | // Simulation update. | 62 | // Simulation update. |
| 62 | const bool updated = step_update(sim, &sim->update); | 63 | const bool updated = step_update(sim, &sim->update); |
| 63 | out->should_update = updated; | ||
| 64 | sim->updates_since_last_render = sim->updates_since_last_render || updated; | 64 | sim->updates_since_last_render = sim->updates_since_last_render || updated; |
| 65 | |||
| 65 | // Simulation render. | 66 | // Simulation render. |
| 66 | const bool rendered = | 67 | const bool rendered = |
| 67 | (sim->updates_since_last_render && step_render(sim, &sim->render)) || | 68 | (sim->updates_since_last_render && step_render(sim, &sim->render)) || |
| 68 | (sim->first_iter); // Trigger an initial render on the first frame. | 69 | (sim->first_iter); // Trigger an initial render on the first frame. |
| 69 | out->should_render = rendered; | ||
| 70 | sim->updates_since_last_render = | 70 | sim->updates_since_last_render = |
| 71 | sim->updates_since_last_render && !out->should_render; | 71 | sim->updates_since_last_render && !out->should_render; |
| 72 | |||
| 72 | // Loop state update. | 73 | // Loop state update. |
| 73 | sim->frame += (updated ? 1 : 0); | 74 | sim->frame += (updated ? 1 : 0); |
| 74 | sim->first_iter = false; | 75 | sim->first_iter = false; |
| 76 | |||
| 75 | out->frame = sim->frame; | 77 | out->frame = sim->frame; |
| 76 | out->render_elapsed = time_elapsed(sim, sim->render.last_step); | 78 | out->render_elapsed = sim->render.time; |
| 77 | out->update_elapsed = time_elapsed(sim, sim->update.last_step); | 79 | out->update_elapsed = sim->update.time; |
| 78 | out->update_dt = sim->update.ddt; | 80 | out->update_dt = sim->update.ddt; |
| 81 | out->should_update = updated; | ||
| 82 | out->should_render = rendered; | ||
| 79 | } | 83 | } |
