diff --git a/src/main.rs b/src/main.rs index 6c18d3f..63ca855 100644 --- a/src/main.rs +++ b/src/main.rs @@ -596,6 +596,54 @@ impl WorldState { } } +struct TimeStep { + last_frame_time: Instant, + // Milliseconds + accum: u128, + fps_num: u16, + fps_den: u16, +} + +impl TimeStep { + pub fn new (fps_num: u16, fps_den: u16) -> Self { + Self { + last_frame_time: Instant::now (), + accum: 0, + fps_num, + fps_den, + } + } + + // Automatically gets monotonic system time from Instant + // If you need something fancy just rewrite this. + // Returns: How many logics steps to run. Typically 0 or 1. + + pub fn step (&mut self) -> u16 { + let frame_time = Instant::now (); + + let fps_num_128: u128 = self.fps_num.into (); + let fps_den_128: u128 = self.fps_den.into (); + + self.accum += (frame_time - self.last_frame_time).as_millis () * fps_num_128; + + let mut result = 0; + const MAX_FRAMES: u16 = 4; + + for _ in 0..MAX_FRAMES { + if self.accum > fps_den_128 { + result += 1; + self.accum -= fps_den_128; + } + else { + break; + } + } + + self.last_frame_time = frame_time; + result + } +} + fn main () { let sdl_context = sdl2::init ().unwrap (); let video_subsystem = sdl_context.video ().unwrap (); @@ -698,40 +746,19 @@ fn main () { let stride = 4 * num_coords; } - let mut last_frame_time = Instant::now (); - let mut frame = 0; - let mut timestep_accum = Duration::from_millis (0); - + let mut time_step = TimeStep::new (60, 1000); let mut state = WorldState::new (); let mut event_pump = sdl_context.event_pump ().unwrap (); 'running: loop { - let frame_time = Instant::now (); - - // Take 60 steps every 1,000 milliseconds. - // I know this is a float, but since we're multiplying it will - // be deterministic, since it's a whole number. - let fps_num = 60.0; - let fps_den = 1000; - - timestep_accum += (frame_time - last_frame_time).mul_f32 (fps_num); + let frames_to_do = time_step.step (); let controller = ControllerState::from_sdl_keyboard (&event_pump.keyboard_state ()); - for _ in 0..4 { - if timestep_accum > Duration::from_millis (fps_den) { - frame += 1; - timestep_accum -= Duration::from_millis (fps_den); - - state.step (&controller); - } - else { - break; - } + for _ in 0..frames_to_do { + state.step (&controller); } - last_frame_time = frame_time; - let _mouse = event_pump.mouse_state (); for event in event_pump.poll_iter() {