diff --git a/src/bin/pumpkin.rs b/src/bin/pumpkin.rs index 5c38613..e992af5 100644 --- a/src/bin/pumpkin.rs +++ b/src/bin/pumpkin.rs @@ -68,19 +68,41 @@ const KEY_DOWN: usize = KEY_UP + 1; struct ControllerState { keys: Vec , + + trigger_left: i16, + trigger_right: i16, } impl ControllerState { - pub fn from_sdl_keyboard (k: &sdl2::keyboard::KeyboardState) -> Self { - let f = |c| k.is_scancode_pressed (c); + pub fn new ( + k: &sdl2::keyboard::KeyboardState, + c: &Option + ) -> Self { + use sdl2::controller::*; + + let f = |code| k.is_scancode_pressed (code); + let b = |code| match c { + None => false, + Some (c) => c.button (code), + }; + + let key_or_gamepad = |key, button| f (key) || b (button); Self { keys: vec! [ - f (Scancode::Left), - f (Scancode::Right), - f (Scancode::Up), - f (Scancode::Down), + key_or_gamepad (Scancode::Left, Button::DPadLeft), + key_or_gamepad (Scancode::Right, Button::DPadRight), + key_or_gamepad (Scancode::Up, Button::DPadUp), + key_or_gamepad (Scancode::Down, Button::DPadDown), ], + trigger_left: match c { + None => 0, + Some (c) => c.axis (Axis::TriggerLeft), + }, + trigger_right: match c { + None => 0, + Some (c) => c.axis (Axis::TriggerRight), + }, } } @@ -187,6 +209,19 @@ struct FlightState { spin_speed: i32, } +impl Default for FlightState { + fn default () -> Self { + Self { + airplane: Airplane { + pos: (0.0, -10.0, 20.0).into (), + vel: (0.0, 0.0, 0.0).into (), + ori: Default::default (), + }, + spin_speed: 0, + } + } +} + impl FlightState { pub fn handle_event (&mut self, _event: &sdl2::event::Event) { @@ -209,10 +244,12 @@ impl FlightState { let object_space_dir = airplane.ori.conjugate ().mul_vec3 (direction); + let throttle = 1.0 + (controller.trigger_right as f32 - controller.trigger_left as f32) / 32767.0; + // Forces let gravity = Vec3::from ((0.0, 0.0, -0.25)); - let thrust = nose; - let laminar_drag = 0.5 * speed * -object_space_dir.y () * nose; + let thrust = nose * throttle; + let laminar_drag = 0.25 * speed * -object_space_dir.y () * nose; let turbulent_dir = Vec3::from ((0.5 * object_space_dir.x (), 0.0, object_space_dir.z ())); let turbulent_drag = -speed * speed * airplane.ori.mul_vec3 (turbulent_dir); @@ -231,11 +268,15 @@ impl FlightState { // Gauges let alti = airplane.pos.z () * 100.0; - let airspeed = speed * 100.0; + let air_speed = speed * 100.0; + let ground_vel = Vec3::from ((airplane.vel.x (), airplane.vel.y (), 0.0)); + let ground_speed = ground_vel.length () * 100.0; - println! ("Alti: {}, Airspeed: {}", + println! ("Alti: {}, Airspeed: {}, Groundspeed: {}, Throttle: {}", alti as i32, - airspeed as i32 + air_speed as i32, + ground_speed as i32, + (throttle * 100.0) as i32 ); } } @@ -295,14 +336,7 @@ impl WorldState { }, spin_speed: 0, }, - flight: FlightState { - airplane: Airplane { - pos: (0.0, -0.5, 0.125).into (), - vel: (0.0, 0.0, 0.0).into (), - ori: Default::default (), - }, - spin_speed: 0, - }, + flight: Default::default (), } } @@ -898,8 +932,8 @@ impl GameGraphics { fn main () { let sdl_context = sdl2::init ().unwrap (); - let video_subsystem = sdl_context.video ().unwrap (); + let video_subsystem = sdl_context.video ().unwrap (); let window = video_subsystem.window ("OpenGL? In my Rust?", 1280, 720) .position_centered () .opengl () @@ -924,6 +958,9 @@ fn main () { let mut graphics_frames = 0; + let controller_subsystem = sdl_context.game_controller ().unwrap (); + let controller = controller_subsystem.open (0).ok (); + let mut event_pump = sdl_context.event_pump ().unwrap (); 'running: loop { let frames_to_do = time_step.step (); @@ -940,7 +977,10 @@ fn main () { } } - let controller = ControllerState::from_sdl_keyboard (&event_pump.keyboard_state ()); + let controller = ControllerState::new ( + &event_pump.keyboard_state (), + &controller + ); for _ in 0..frames_to_do { state.step (&controller);