use crate::{
input::ButtonState,
lifecycle::Event,
};
use std::ops::Index;
#[derive(Copy, Clone, Debug)]
pub struct Gamepad {
pub(crate) id: i32,
pub(crate) buttons: [ButtonState; 17],
pub(crate) axes: [f32; 4],
}
impl Gamepad {
pub(crate) fn clear_temporary_states(&mut self) {
for button in self.buttons.iter_mut() {
*button = button.clear_temporary();
}
}
pub(crate) fn set_previous(&mut self, previous: &Gamepad, events: &mut Vec<Event>) {
for button in GAMEPAD_BUTTON_LIST.iter() {
if self[*button].is_down() != previous[*button].is_down() {
self.buttons[*button as usize] = if self[*button].is_down() {
ButtonState::Pressed
} else {
ButtonState::Released
};
events.push(Event::GamepadButton(self.id(), *button, self[*button]));
}
}
for axis in GAMEPAD_AXIS_LIST.iter() {
if self[*axis] != previous[*axis] {
events.push(Event::GamepadAxis(self.id(), *axis, self[*axis]));
}
}
}
pub fn id(&self) -> i32 {
self.id
}
}
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
pub enum GamepadAxis {
LeftStickX = 0,
LeftStickY = 1,
RightStickX = 2,
RightStickY = 3
}
#[repr(u32)]
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
pub enum GamepadButton {
FaceDown,
FaceRight,
FaceLeft,
FaceUp,
ShoulderLeft,
ShoulderRight,
TriggerLeft,
TriggerRight,
Select,
Start,
StickButtonLeft,
StickButtonRight,
DpadUp,
DpadDown,
DpadLeft,
DpadRight,
Home
}
impl Index<GamepadAxis> for Gamepad {
type Output = f32;
fn index(&self, index: GamepadAxis) -> &f32 {
&self.axes[index as usize]
}
}
impl Index<GamepadButton> for Gamepad {
type Output = ButtonState;
fn index(&self, index: GamepadButton) -> &ButtonState {
&self.buttons[index as usize]
}
}
pub(crate) const GAMEPAD_BUTTON_LIST: &[GamepadButton] = &[
GamepadButton::FaceDown,
GamepadButton::FaceRight,
GamepadButton::FaceUp,
GamepadButton::FaceLeft,
GamepadButton::ShoulderLeft,
GamepadButton::TriggerLeft,
GamepadButton::ShoulderRight,
GamepadButton::TriggerRight,
GamepadButton::Select,
GamepadButton::Start,
GamepadButton::Home,
GamepadButton::StickButtonLeft,
GamepadButton::StickButtonRight,
GamepadButton::DpadUp,
GamepadButton::DpadDown,
GamepadButton::DpadLeft,
GamepadButton::DpadRight,
];
const GAMEPAD_AXIS_LIST: &[GamepadAxis] = &[
GamepadAxis::LeftStickX,
GamepadAxis::LeftStickY,
GamepadAxis::RightStickX,
GamepadAxis::RightStickY,
];