Added a basic gamestate with a controlled mario
[kaka/rust-sdl-test.git] / src / core / controller.rs
index b3f6201..fb56465 100644 (file)
@@ -1,31 +1,39 @@
+use std::collections::HashMap;
 use std::cell::RefCell;
 use sdl2::haptic::Haptic;
 use sdl2::HapticSubsystem;
-use sdl2::GameControllerSubsystem;
+pub use sdl2::GameControllerSubsystem;
 use sdl2::event::Event;
 use sdl2::controller::GameController;
 use std::rc::Rc;
 
 //#[derive(Debug)]
 pub struct ControllerManager {
-    ctrl: GameControllerSubsystem,
+    pub ctrl: GameControllerSubsystem,
     haptic: Rc<HapticSubsystem>,
-    pub controllers: Vec<Rc<Controller>>,
+    pub controllers: HashMap<u32, Rc<RefCell<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 {
+       let mut c = ControllerManager {
            ctrl,
            haptic: Rc::new(haptic),
-           controllers: vec![],
+           controllers: HashMap::new(),
+       };
+       c.init();
+       c
+    }
+
+    fn init(&mut self) {
+       for i in 0..self.ctrl.num_joysticks().unwrap() {
+           self.add_device(i);
        }
     }
 
@@ -45,18 +53,38 @@ impl ControllerManager {
        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) {
+
+       /*
+       note about set_rumble (for dualshock 3 at least):
+       the active range for the low frequency is from 65536/4 to 65536 and escalates in large steps throughout the range
+       the active range for the high frequency is from 256 to 65536 and effect is the same throughout the whole range
+        */
+       let haptic = match ctrl.set_rumble(0, 256, 100) {
            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);
+       if self.controllers.contains_key(&id) {
+           return;
+       }
+
+       let detached = self.controllers.values().find(|c| !c.borrow().ctrl.attached());
+       match detached {
+           Some(c) => {
+               let mut c = c.borrow_mut();
+               c.ctrl = ctrl;
+               c.haptic = haptic.map(|h| Rc::new(RefCell::new(h)));
+           }
+           None => {
+               let c = Rc::new(RefCell::new(Controller {ctrl, haptic: haptic.map(|h| Rc::new(RefCell::new(h)))}));
+               self.controllers.insert(id, c);
+           }
+       };
     }
 
     pub fn remove_device(&mut self, id: i32) {
        println!("device removed ({})!", id);
+       // TODO
     }
 }