@@ -10,6 +10,7 @@ const AppBackend = sokol_app_backend.App;
1010
1111const NS_PER_SECOND : i64 = 1_000_000_000 ;
1212const NS_PER_SECOND_F : f32 = 1_000_000_000.0 ;
13+ const NS_FPS_LIMIT_OVERHEAD = 1_250_000 ; // tuned to ensure consistent frame pacing
1314
1415const state = struct {
1516 // FPS cap vars, if set
@@ -148,23 +149,44 @@ fn on_frame() void {
148149
149150 // tell modules this frame is done
150151 modules .postDrawModules ();
151- }
152152
153- /// Get time elapsed since last tick. Also calculate the FPS!
154- fn calcDeltaTime () f32 {
155- if (state .reset_delta ) {
156- state .reset_delta = false ;
157- state .game_loop_timer .reset ();
158- return 1.0 / 60.0 ;
159- }
153+ // keep under our FPS limit, if needed
154+ limitFps ();
155+ }
160156
157+ fn limitFps () void {
161158 if (state .target_fps != null ) {
162159 // Try to hit our target FPS!
163- const frame_len_ns = state .game_loop_timer .read ();
164160
161+ // Easy case, just stop here if we are under the target frame length
162+ const initial_frame_ns = state .game_loop_timer .read ();
163+ if (initial_frame_ns >= state .target_fps_ns )
164+ return ;
165+
166+ // Harder case, we are faster than the target frame length.
167+ // Note: time.sleep does not ensure consistent timing.
168+ // Due to this we need to sleep most of the time, but busy loop the rest.
169+
170+ const frame_len_ns = initial_frame_ns + NS_FPS_LIMIT_OVERHEAD ;
165171 if (frame_len_ns < state .target_fps_ns ) {
166172 time .sleep (state .target_fps_ns - frame_len_ns );
167173 }
174+
175+ // Eat up the rest of the time in a busy loop to ensure consistent frame pacing
176+ while (true ) {
177+ const cur_frame_len_ns = state .game_loop_timer .read ();
178+ if (cur_frame_len_ns >= state .target_fps_ns )
179+ break ;
180+ }
181+ }
182+ }
183+
184+ /// Get time elapsed since last tick. Also calculate the FPS!
185+ fn calcDeltaTime () f32 {
186+ if (state .reset_delta ) {
187+ state .reset_delta = false ;
188+ state .game_loop_timer .reset ();
189+ return 1.0 / 60.0 ;
168190 }
169191
170192 // calculate the fps by counting frames each second
0 commit comments