Commit | Line | Data |
---|---|---|
b0566120 | 1 | use std::collections::HashMap; |
3f344b63 TW |
2 | use std::cell::RefCell; |
3 | use sdl2::haptic::Haptic; | |
4 | use sdl2::HapticSubsystem; | |
b0566120 | 5 | pub use sdl2::GameControllerSubsystem; |
3f344b63 TW |
6 | use sdl2::event::Event; |
7 | use sdl2::controller::GameController; | |
8 | use std::rc::Rc; | |
9 | ||
10 | //#[derive(Debug)] | |
11 | pub struct ControllerManager { | |
b0566120 | 12 | pub ctrl: GameControllerSubsystem, |
3f344b63 | 13 | haptic: Rc<HapticSubsystem>, |
b0566120 | 14 | pub controllers: HashMap<u32, Rc<RefCell<Controller>>>, |
3f344b63 TW |
15 | } |
16 | ||
17 | //#[derive(Debug)] | |
18 | pub struct Controller { | |
3f344b63 TW |
19 | pub ctrl: GameController, |
20 | haptic: Option<Rc<RefCell<Haptic>>>, | |
21 | } | |
22 | ||
23 | impl ControllerManager { | |
24 | pub fn new(ctrl: GameControllerSubsystem, haptic: HapticSubsystem) -> Self { | |
b0566120 | 25 | let mut c = ControllerManager { |
3f344b63 TW |
26 | ctrl, |
27 | haptic: Rc::new(haptic), | |
b0566120 TW |
28 | controllers: HashMap::new(), |
29 | }; | |
30 | c.init(); | |
31 | c | |
32 | } | |
33 | ||
34 | fn init(&mut self) { | |
35 | for i in 0..self.ctrl.num_joysticks().unwrap() { | |
36 | self.add_device(i); | |
3f344b63 TW |
37 | } |
38 | } | |
39 | ||
40 | pub fn handle_event(&mut self, event: &Event) { | |
41 | match event { | |
fca4e4f0 TW |
42 | Event::ControllerDeviceAdded { which, .. } => { self.add_device(*which) } |
43 | Event::ControllerDeviceRemoved { which, .. } => { self.remove_device(*which) } | |
44 | Event::ControllerDeviceRemapped { which, .. } => { println!("device remapped ({})!", *which) } | |
45 | Event::ControllerButtonDown { button, .. } => { println!("button {} down!", button.string()) } | |
46 | Event::ControllerButtonUp { button, .. } => { println!("button {} up!", button.string()) } | |
47 | Event::ControllerAxisMotion { axis, .. } => { println!("axis motion {}!", axis.string()) } | |
3f344b63 TW |
48 | _ => {} |
49 | } | |
50 | } | |
51 | ||
52 | pub fn add_device(&mut self, id: u32) { | |
53 | println!("device added ({})!", id); | |
54 | let mut ctrl = self.ctrl.open(id).unwrap(); | |
55 | println!("opened {}", ctrl.name()); | |
ca99d4d7 TW |
56 | |
57 | /* | |
58 | note about set_rumble (for dualshock 3 at least): | |
59 | the active range for the low frequency is from 65536/4 to 65536 and escalates in large steps throughout the range | |
60 | the active range for the high frequency is from 256 to 65536 and effect is the same throughout the whole range | |
61 | */ | |
62 | let haptic = match ctrl.set_rumble(0, 256, 100) { | |
3f344b63 TW |
63 | Ok(_) => self.haptic.open_from_joystick_id(id).ok(), |
64 | Err(_) => None | |
65 | }; | |
66 | ||
b0566120 TW |
67 | if self.controllers.contains_key(&id) { |
68 | return; | |
69 | } | |
70 | ||
71 | let detached = self.controllers.values().find(|c| !c.borrow().ctrl.attached()); | |
ca99d4d7 TW |
72 | match detached { |
73 | Some(c) => { | |
74 | let mut c = c.borrow_mut(); | |
75 | c.ctrl = ctrl; | |
76 | c.haptic = haptic.map(|h| Rc::new(RefCell::new(h))); | |
77 | } | |
78 | None => { | |
b0566120 TW |
79 | let c = Rc::new(RefCell::new(Controller {ctrl, haptic: haptic.map(|h| Rc::new(RefCell::new(h)))})); |
80 | self.controllers.insert(id, c); | |
ca99d4d7 TW |
81 | } |
82 | }; | |
3f344b63 TW |
83 | } |
84 | ||
85 | pub fn remove_device(&mut self, id: i32) { | |
86 | println!("device removed ({})!", id); | |
ca99d4d7 | 87 | // TODO |
3f344b63 TW |
88 | } |
89 | } | |
90 | ||
91 | impl Controller { | |
92 | /// strength [0 - 1] | |
93 | pub fn rumble(&self, strength: f32, duration_ms: u32) { | |
94 | if let Some(h) = &self.haptic { | |
95 | h.borrow_mut().rumble_play(strength, duration_ms); | |
96 | } | |
97 | } | |
98 | } |