1pub const JS_EVENT_BUTTON: u8 = 0x01; pub const JS_EVENT_AXIS: u8 = 0x02; pub const JS_EVENT_INIT: u8 = 0x80; #[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#[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, pub value: i16, 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}