use crate::*; pub use gilrs::{Gilrs, GamepadId}; pub struct OwnedGamepad { tag: usize, id: Option, gamepad: Gamepad, } impl OwnedGamepad { pub fn new(tag: usize) -> Self { Self { tag, id: None, gamepad: Gamepad::new() } } /// Returns Some if the ID owns this gamepad. pub fn register(&mut self, new_id: GamepadId) -> Option<&mut Gamepad> { if let Some(id) = self.id { match id == new_id { true => Some(&mut self.gamepad), false => None, } } else { self.id = Some(new_id); info!("Registered gamepad {}", self.tag); Some(&mut self.gamepad) } } pub fn state(&self) -> u8 { self.gamepad.state } pub fn reset(&mut self) { self.gamepad.reset(); } } pub struct Gamepad { pub state: u8, l_up: bool, l_down: bool, l_left: bool, l_right: bool, r_up: bool, r_down: bool, r_left: bool, r_right: bool, d_up: bool, d_down: bool, d_left: bool, d_right: bool, a: bool, b: bool, x: bool, y: bool, } impl Gamepad { pub fn new() -> Self { Self { state: 0, l_up: false, l_down: false, l_left: false, l_right: false, r_up: false, r_down: false, r_left: false, r_right: false, d_up: false, d_down: false, d_left: false, d_right: false, a: false, b: false, x: false, y: false, } } pub fn reset(&mut self) { self.state = 0; self.l_up = false; self.l_down = false; self.l_left = false; self.l_right = false; self.r_up = false; self.r_down = false; self.r_left = false; self.r_right = false; self.d_up = false; self.d_down = false; self.d_left = false; self.d_right = false; self.a = false; self.b = false; self.x = false; self.y = false; } // Returns true if the state changed. pub fn process_event(&mut self, event: &gilrs::Event) -> bool { macro_rules! schmitt { ($name_neg:ident, $name_pos:ident, $v:expr) => {{ if self.$name_neg { if $v > -0.40 { self.$name_neg = false; } } else { if $v < -0.50 { self.$name_neg = true; } } if self.$name_pos { if $v < 0.40 { self.$name_pos = false; } } else { if $v > 0.50 { self.$name_pos = true; } } }}; } match event.event { gilrs::EventType::ButtonPressed(button, _) => match button { gilrs::Button::South => self.a = true, gilrs::Button::East => self.b = true, gilrs::Button::West => self.x = true, gilrs::Button::North => self.y = true, gilrs::Button::DPadUp => self.d_up = true, gilrs::Button::DPadDown => self.d_down = true, gilrs::Button::DPadLeft => self.d_left = true, gilrs::Button::DPadRight => self.d_right = true, _ => (), } gilrs::EventType::ButtonReleased(button, _) => match button { gilrs::Button::South => self.a = false, gilrs::Button::East => self.b = false, gilrs::Button::West => self.x = false, gilrs::Button::North => self.y = false, gilrs::Button::DPadUp => self.d_up = false, gilrs::Button::DPadDown => self.d_down = false, gilrs::Button::DPadLeft => self.d_left = false, gilrs::Button::DPadRight => self.d_right = false, _ => (), } gilrs::EventType::AxisChanged(axis, v, _) => match axis { gilrs::Axis::LeftStickX => schmitt!(l_left, l_right, v), gilrs::Axis::LeftStickY => schmitt!(l_down, l_up, v), gilrs::Axis::RightStickX => schmitt!(r_left, r_right, v), gilrs::Axis::RightStickY => schmitt!(r_down, r_up, v), _ => (), } _ => (), } let old_state = self.state; self.state = 0; if self.l_up | self.r_up | self.d_up { self.state |= 0x80; } if self.l_down | self.r_down | self.d_down { self.state |= 0x40; } if self.l_left | self.r_left | self.d_left { self.state |= 0x20; } if self.l_right | self.r_right | self.d_right { self.state |= 0x10; } if self.a { self.state |= 0x08; } if self.b { self.state |= 0x04; } if self.x { self.state |= 0x02; } if self.y { self.state |= 0x01; } old_state != self.state } }