sn30pro/
raw.rs

1//possible values of event
2pub const JS_EVENT_BUTTON: u8 = 0x01; /* button pressed/released */
3pub const JS_EVENT_AXIS: u8 = 0x02; /* joystick moved */
4pub const JS_EVENT_INIT: u8 = 0x80; /* initial state of device */
5
6#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq)]
7pub enum ButtonEvent {
8    Pressed,
9    Released,
10}
11
12impl ButtonEvent {
13    pub(crate) fn from_1or0(v: i16) -> ButtonEvent {
14        match v {
15            1 => ButtonEvent::Pressed,
16            0 => ButtonEvent::Released,
17            _ => panic!("you did a nono")
18        }
19    }
20
21    pub(crate) fn from_i16max(v: i16) -> ButtonEvent {
22        match v {
23            32767 => ButtonEvent::Pressed,
24            -32767 => ButtonEvent::Released,
25            _ => panic!("you did a nono")
26        }
27    }
28}
29
30#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq)]
31pub enum DirectionX {
32    Up,
33    Center,
34    Down,
35}
36
37impl DirectionX {
38    pub(crate) fn from_i16max(v: i16) -> DirectionX {
39        match v {
40            32767 => DirectionX::Down,
41            0 => DirectionX::Center,
42            -32767 => DirectionX::Up,
43            _ => panic!("you did a nono")
44        }
45    }
46}
47
48impl Default for DirectionX {
49    fn default() -> Self {
50        Self::Center
51    }
52}
53
54// 8 => InputUpdate::HeartButton(ButtonEvent::from_1or0(raw_event.value)),
55#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq)]
56pub enum DirectionY {
57    Left,
58    Center,
59    Right,
60}
61
62impl DirectionY {
63    pub(crate) fn from_i16max(v: i16) -> DirectionY {
64        match v {
65            32767 => DirectionY::Right,
66            0 => DirectionY::Center,
67            -32767 => DirectionY::Left,
68            _ => panic!("you did a nono")
69        }
70    }
71}
72
73impl Default for DirectionY {
74    fn default() -> Self {
75        Self::Center
76    }
77}
78
79#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq)]
80pub enum InputUpdate {
81    R1(ButtonEvent),
82    R2(ButtonEvent),
83    L1(ButtonEvent),
84    L2(ButtonEvent),
85    BtnY(ButtonEvent),
86    BtnX(ButtonEvent),
87    BtnA(ButtonEvent),
88    BtnB(ButtonEvent),
89    BtnSelect(ButtonEvent),
90    BtnStart(ButtonEvent),
91    HeartButton(ButtonEvent),
92    ButtonPadX(DirectionX),
93    ButtonPadY(DirectionY),
94    LJoystickX(i16),
95    LJoystickY(i16),
96    LJoystickButton(ButtonEvent),
97    RJoystickX(i16),
98    RJoystickY(i16),
99    RJoystickButton(ButtonEvent),
100}
101
102#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq)]
103#[repr(C)]
104pub struct RawEvent {
105    pub time: u32, // event timestamp in ms (unknown base time)
106    pub value: i16, //value of the event, for axis changes it is -32767 to 32767, for buttons it is 0 or 1
107    pub event: u8,
108    pub number: u8,
109}
110
111pub const EVENT_SIZE: usize = std::mem::size_of::<RawEvent>();
112
113pub fn parse_event(raw_event: RawEvent) -> InputUpdate {
114    match raw_event.event {
115        JS_EVENT_BUTTON => {
116            match raw_event.number {
117                0 => InputUpdate::BtnB(ButtonEvent::from_1or0(raw_event.value)),
118                1 => InputUpdate::BtnA(ButtonEvent::from_1or0(raw_event.value)),
119                2 => InputUpdate::BtnY(ButtonEvent::from_1or0(raw_event.value)),
120                3 => InputUpdate::BtnX(ButtonEvent::from_1or0(raw_event.value)),
121                4 => InputUpdate::L1(ButtonEvent::from_1or0(raw_event.value)),
122                5 => InputUpdate::R1(ButtonEvent::from_1or0(raw_event.value)),
123                6 => InputUpdate::BtnSelect(ButtonEvent::from_1or0(raw_event.value)),
124                7 => InputUpdate::BtnStart(ButtonEvent::from_1or0(raw_event.value)),
125                8 => InputUpdate::HeartButton(ButtonEvent::from_1or0(raw_event.value)),
126                9 => InputUpdate::LJoystickButton(ButtonEvent::from_1or0(raw_event.value)),
127                10 => InputUpdate::RJoystickButton(ButtonEvent::from_1or0(raw_event.value)),
128                b => panic!("Invalid button {}", b),
129            }
130        }
131        JS_EVENT_AXIS => {
132            match raw_event.number {
133                0 => InputUpdate::LJoystickY(raw_event.value),
134                1 => InputUpdate::LJoystickX(-raw_event.value),
135                2 => InputUpdate::RJoystickY(raw_event.value),
136                3 => InputUpdate::RJoystickX(-raw_event.value),
137                4 => InputUpdate::R2(ButtonEvent::from_i16max(raw_event.value)),
138                5 => InputUpdate::L2(ButtonEvent::from_i16max(raw_event.value)),
139                6 => InputUpdate::ButtonPadY(DirectionY::from_i16max(raw_event.value)),
140                7 => InputUpdate::ButtonPadX(DirectionX::from_i16max(raw_event.value)),
141                _ => unreachable!(),
142            }
143        }
144        _ => unreachable!()
145    }
146}
147
148pub fn is_init_event(event: &RawEvent) -> bool {
149    event.event & JS_EVENT_INIT == JS_EVENT_INIT
150}