Added a controller manager
authorTomas Wenström <tomas.wenstrom@gmail.com>
Sat, 9 Jan 2021 14:59:03 +0000 (15:59 +0100)
committerTomas Wenström <tomas.wenstrom@gmail.com>
Sat, 9 Jan 2021 14:59:03 +0000 (15:59 +0100)
src/core/app.rs
src/core/controller.rs [new file with mode: 0644]
src/core/mod.rs

index f6adba0..7e91c94 100644 (file)
@@ -1,5 +1,6 @@
 use boll::*;
 use common::{Point2D, Rect};
+use core::controller::ControllerManager;
 use point; // defined in common, but loaded from main...
 use rand::Rng;
 use sdl2::event::{Event, WindowEvent};
@@ -46,7 +47,6 @@ impl AppBuilder {
         let context = sdl2::init().unwrap();
         sdl2::image::init(sdl2::image::InitFlag::PNG)?;
         let video = context.video()?;
-
         self.print_video_display_modes(&video);
 
         let window = video
@@ -74,12 +74,15 @@ impl AppBuilder {
         let event_pump = context.event_pump()?;
         let sprites = SpriteManager::new(canvas.texture_creator());
        let screen = canvas.output_size().unwrap();
+       let ctrl = context.game_controller()?;
+       ctrl.set_event_state(true);
 
         Ok(App {
             canvas,
             event_pump,
             sprites,
             state: self.state.unwrap_or_else(|| Box::new(ActiveState::new(screen))),
+           ctrl_man: ControllerManager::new(ctrl, context.haptic()?),
         })
     }
 
@@ -128,6 +131,7 @@ pub struct App {
     pub event_pump: EventPump,
     pub sprites: SpriteManager,
     pub state: Box<dyn AppState>,
+    pub ctrl_man: ControllerManager,
 }
 
 impl App {
@@ -163,7 +167,7 @@ impl App {
             if frame_count == FPS as u64 {
                 let duration = fps_time.to(PreciseTime::now()).num_nanoseconds().unwrap() as f64
                     / 1_000_000_000.0;
-                println!("fps: {}", frame_count as f64 / duration);
+                // println!("fps: {}", frame_count as f64 / duration);
                 frame_count = 0;
                 fps_time = PreciseTime::now();
             }
@@ -174,7 +178,12 @@ impl App {
 
     fn handle_events(&mut self) -> Result<(), ()> {
         for event in self.event_pump.poll_iter() {
+           self.ctrl_man.handle_event(&event);
             match event {
+               Event::ControllerButtonDown { .. } => {
+                   let c = self.ctrl_man.controllers[0].clone();
+                   c.rumble(0.75, 100);
+               }
                 Event::Quit { .. }
                 | Event::KeyDown {
                     keycode: Some(Keycode::Escape),
diff --git a/src/core/controller.rs b/src/core/controller.rs
new file mode 100644 (file)
index 0000000..7037d81
--- /dev/null
@@ -0,0 +1,70 @@
+use std::cell::RefCell;
+use sdl2::haptic::Haptic;
+use sdl2::HapticSubsystem;
+use sdl2::GameControllerSubsystem;
+use sdl2::event::Event;
+use sdl2::controller::GameController;
+use std::rc::Rc;
+
+//#[derive(Debug)]
+pub struct ControllerManager {
+    ctrl: GameControllerSubsystem,
+    haptic: Rc<HapticSubsystem>,
+    pub controllers: Vec<Rc<Controller>>,
+}
+
+//#[derive(Debug)]
+pub struct Controller {
+    id: u32,
+    pub ctrl: GameController,
+    haptic: Option<Rc<RefCell<Haptic>>>,
+}
+
+impl ControllerManager {
+    pub fn new(ctrl: GameControllerSubsystem, haptic: HapticSubsystem) -> Self {
+       ControllerManager {
+           ctrl,
+           haptic: Rc::new(haptic),
+           controllers: vec![],
+       }
+    }
+
+    pub fn handle_event(&mut self, event: &Event) {
+       match event {
+           Event::ControllerDeviceAdded { which: id, .. } => { self.add_device(*id) }
+           Event::ControllerDeviceRemoved { which: id, .. } => { self.remove_device(*id) }
+           Event::ControllerDeviceRemapped { which: id, .. } => { println!("device remapped ({})!", *id) }
+           Event::ControllerButtonDown { button: btn, .. } => { println!("button {} down!", btn.string()) }
+           Event::ControllerButtonUp { button: btn, .. } => { println!("button {} up!", btn.string()) }
+           Event::ControllerAxisMotion { axis: ax, .. } => { println!("axis motion {}!", ax.string()) }
+           _ => {}
+       }
+    }
+
+    pub fn add_device(&mut self, id: u32) {
+       println!("device added ({})!", id);
+       let mut ctrl = self.ctrl.open(id).unwrap();
+       println!("opened {}", ctrl.name());
+       let haptic = match ctrl.set_rumble(500, 1000, 500) {
+           Ok(_) => self.haptic.open_from_joystick_id(id).ok(),
+           Err(_) => None
+       };
+
+       let c = Rc::new(Controller {id, ctrl, haptic: haptic.map(|h| Rc::new(RefCell::new(h)))});
+       c.rumble(0.5, 300);
+       self.controllers.push(c);
+    }
+
+    pub fn remove_device(&mut self, id: i32) {
+       println!("device removed ({})!", id);
+    }
+}
+
+impl Controller {
+    /// strength [0 - 1]
+    pub fn rumble(&self, strength: f32, duration_ms: u32) {
+       if let Some(h) = &self.haptic {
+           h.borrow_mut().rumble_play(strength, duration_ms);
+       }
+    }
+}
index 309be62..140bac4 100644 (file)
@@ -1 +1,2 @@
 pub mod app;
+pub mod controller;