diff --git a/src/main.rs b/src/main.rs index 5b7690c..6c18d3f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -525,6 +525,77 @@ unsafe fn point_to_model ( vertex_attrib_pointer (attrs ["normal"], 3, model.get_vertex_slice (2)); } +const KEY_LEFT: usize = 0; +const KEY_RIGHT: usize = KEY_LEFT + 1; +const KEY_UP: usize = KEY_RIGHT + 1; +const KEY_DOWN: usize = KEY_UP + 1; +const KEY_COUNT: usize = KEY_DOWN + 1; + +struct ControllerState { + keys: Vec , +} + +impl ControllerState { + pub fn from_sdl_keyboard (k: &sdl2::keyboard::KeyboardState) -> Self { + let f = |c| k.is_scancode_pressed (c); + + Self { + keys: vec! [ + f (Scancode::Left), + f (Scancode::Right), + f (Scancode::Up), + f (Scancode::Down), + ], + } + } + + pub fn is_pressed (&self, code: usize) -> bool { + self.keys [code] + } +} + +struct WorldState { + azimuth: f32, + altitude: f32, + spin_speed: i32, +} + +impl WorldState { + pub fn new () -> Self { + Self { + azimuth: 0.0, + altitude: 0.0, + spin_speed: 0, + } + } + + pub fn step (&mut self, controller: &ControllerState) { + const SPIN_RAMP_TIME: i32 = 30; + + let spin_f = 4.0 * self.spin_speed as f32 / SPIN_RAMP_TIME as f32; + + if controller.is_pressed (KEY_LEFT) { + self.spin_speed = std::cmp::min (self.spin_speed + 1, SPIN_RAMP_TIME); + self.azimuth += spin_f; + } + else if controller.is_pressed (KEY_RIGHT) { + self.spin_speed = std::cmp::min (self.spin_speed + 1, SPIN_RAMP_TIME); + self.azimuth -= spin_f; + } + else if controller.is_pressed (KEY_UP) { + self.spin_speed = std::cmp::min (self.spin_speed + 1, SPIN_RAMP_TIME); + self.altitude = f32::min (90.0, self.altitude + spin_f); + } + else if controller.is_pressed (KEY_DOWN) { + self.spin_speed = std::cmp::min (self.spin_speed + 1, SPIN_RAMP_TIME); + self.altitude = f32::max (-90.0, self.altitude - spin_f); + } + else { + self.spin_speed = 0; + } + } +} + fn main () { let sdl_context = sdl2::init ().unwrap (); let video_subsystem = sdl_context.video ().unwrap (); @@ -630,10 +701,8 @@ fn main () { let mut last_frame_time = Instant::now (); let mut frame = 0; let mut timestep_accum = Duration::from_millis (0); - let mut azimuth: f32 = 0.0; - let mut altitude: f32 = 0.0; - let mut spin_speed: i32 = 0; - const SPIN_RAMP_TIME: i32 = 30; + + let mut state = WorldState::new (); let mut event_pump = sdl_context.event_pump ().unwrap (); 'running: loop { @@ -647,34 +716,14 @@ fn main () { timestep_accum += (frame_time - last_frame_time).mul_f32 (fps_num); - let keyboard_state = event_pump.keyboard_state (); + 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); - let spin_f = 4.0 * spin_speed as f32 / SPIN_RAMP_TIME as f32; - - if keyboard_state.is_scancode_pressed (Scancode::Left) { - spin_speed = std::cmp::min (spin_speed + 1, SPIN_RAMP_TIME); - azimuth += spin_f; - } - else if keyboard_state.is_scancode_pressed (Scancode::Right) { - spin_speed = std::cmp::min (spin_speed + 1, SPIN_RAMP_TIME); - azimuth -= spin_f; - } - else if keyboard_state.is_scancode_pressed (Scancode::Up) { - spin_speed = std::cmp::min (spin_speed + 1, SPIN_RAMP_TIME); - altitude = f32::min (90.0, altitude + spin_f); - } - else if keyboard_state.is_scancode_pressed (Scancode::Down) { - spin_speed = std::cmp::min (spin_speed + 1, SPIN_RAMP_TIME); - altitude = f32::max (-90.0, altitude - spin_f); - } - else { - spin_speed = 0; - } + state.step (&controller); } else { break; @@ -698,8 +747,8 @@ fn main () { window.gl_make_current (&gl_ctx).unwrap (); //let longitude = (frame as f32).to_radians (); - let longitude = azimuth.to_radians (); - let latitude = (altitude - 90.0).to_radians (); + let longitude = state.azimuth.to_radians (); + let latitude = (state.altitude - 90.0).to_radians (); //let latitude = (frame as f32 / 5.0).to_radians ().sin () * -40.0f32.to_radians () - 75.0f32.to_radians (); let proj_mat = Mat4::perspective_rh_gl (30.0f32.to_radians (), 1280.0 / 720.0, 0.5, 500.0);