aboutsummaryrefslogtreecommitdiff
path: root/simloop/src
diff options
context:
space:
mode:
Diffstat (limited to 'simloop/src')
-rw-r--r--simloop/src/simloop.c56
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
5static uint64_t ddt_from_fps(int fps) { 5static 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
10Simloop simloop_make(const SimloopArgs* args) { 10Simloop 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
26static time_delta time_elapsed(const Simloop* sim, time_point t) {
27 assert(sim);
28 return time_diff(sim->timer->start_time, t);
29}
30
31static bool step_update(const Simloop* sim, SimloopTimeline* timeline) { 31static 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
57void simloop_update(Simloop* sim, SimloopOut* out) { 56void 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}