use std::collections::HashMap; use std::cell::RefCell; use sdl2::haptic::Haptic; use sdl2::HapticSubsystem; pub use sdl2::GameControllerSubsystem; use sdl2::event::Event; use sdl2::controller::GameController; use std::rc::Rc; //#[derive(Debug)] pub struct ControllerManager { pub ctrl: GameControllerSubsystem, haptic: Rc, pub controllers: HashMap>>, } //#[derive(Debug)] pub struct Controller { pub ctrl: GameController, haptic: Option>>, } impl ControllerManager { pub fn new(ctrl: GameControllerSubsystem, haptic: HapticSubsystem) -> Self { let mut c = ControllerManager { ctrl, haptic: Rc::new(haptic), controllers: HashMap::new(), }; c.init(); c } fn init(&mut self) { for i in 0..self.ctrl.num_joysticks().unwrap() { self.add_device(i); } } pub fn handle_event(&mut self, event: &Event) { match event { Event::ControllerDeviceAdded { which, .. } => { self.add_device(*which) } Event::ControllerDeviceRemoved { which, .. } => { self.remove_device(*which) } Event::ControllerDeviceRemapped { which, .. } => { println!("device remapped ({})!", *which) } Event::ControllerButtonDown { button, .. } => { println!("button {} down!", button.string()) } Event::ControllerButtonUp { button, .. } => { println!("button {} up!", button.string()) } Event::ControllerAxisMotion { axis, .. } => { println!("axis motion {}!", axis.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()); /* 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 }; 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 } } 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); } } }