1use serde::{Deserialize, Serialize};
2use std::fmt::Display;
3
4#[derive(PartialEq, Eq, Copy, Clone, Debug, Serialize, Deserialize)]
5pub enum KeyCode {
6 Key1,
7 Key2,
8 Key3,
9 Key4,
10 Key5,
11 Key6,
12 Key7,
13 Key8,
14 Key9,
15 Key0,
16 A,
17 B,
18 C,
19 D,
20 E,
21 F,
22 G,
23 H,
24 I,
25 J,
26 K,
27 L,
28 M,
29 N,
30 O,
31 P,
32 Q,
33 R,
34 S,
35 T,
36 U,
37 V,
38 W,
39 X,
40 Y,
41 Z,
42 Escape,
43 F1,
44 F2,
45 F3,
46 F4,
47 F5,
48 F6,
49 F7,
50 F8,
51 F9,
52 F10,
53 F11,
54 F12,
55 F13,
56 F14,
57 F15,
58 F16,
59 F17,
60 F18,
61 F19,
62 F20,
63 F21,
64 F22,
65 F23,
66 F24,
67 Snapshot,
68 Scroll,
69 Pause,
70 Insert,
71 Home,
72 Delete,
73 End,
74 PageDown,
75 PageUp,
76 Left,
77 Up,
78 Right,
79 Down,
80 Back,
81 Return,
82 Space,
83 Compose,
84 Caret,
85 Numlock,
86 Numpad0,
87 Numpad1,
88 Numpad2,
89 Numpad3,
90 Numpad4,
91 Numpad5,
92 Numpad6,
93 Numpad7,
94 Numpad8,
95 Numpad9,
96 AbntC1,
97 AbntC2,
98 NumpadAdd,
99 Apostrophe,
100 Apps,
101 Asterisk,
102 Plus,
103 At,
104 Ax,
105 Backslash,
106 Calculator,
107 Capital,
108 Colon,
109 Comma,
110 Convert,
111 NumpadDecimal,
112 NumpadDivide,
113 Equals,
114 Grave,
115 Kana,
116 Kanji,
117 LAlt,
118 LBracket,
119 LControl,
120 LShift,
121 LWin,
122 Mail,
123 MediaSelect,
124 MediaStop,
125 Minus,
126 NumpadMultiply,
127 Mute,
128 MyComputer,
129 NavigateForward,
130 NavigateBackward,
131 NextTrack,
132 NoConvert,
133 NumpadComma,
134 NumpadEnter,
135 NumpadEquals,
136 Oem102,
137 Period,
138 PlayPause,
139 Power,
140 PrevTrack,
141 RAlt,
142 RBracket,
143 RControl,
144 RShift,
145 RWin,
146 Semicolon,
147 Slash,
148 Sleep,
149 Stop,
150 NumpadSubtract,
151 Sysrq,
152 Tab,
153 Underline,
154 Unlabeled,
155 VolumeDown,
156 VolumeUp,
157 Wake,
158 WebBack,
159 WebFavorites,
160 WebForward,
161 WebHome,
162 WebRefresh,
163 WebSearch,
164 WebStop,
165 Yen,
166 Copy,
167 Paste,
168 Cut,
169}
170
171#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
172pub struct GamepadButton {
173 pub gamepad: Gamepad,
174 pub button_type: GamepadButtonType,
175}
176
177impl GamepadButton {
178 pub fn new(gamepad: Gamepad, button_type: GamepadButtonType) -> Self {
179 Self {
180 gamepad,
181 button_type,
182 }
183 }
184}
185
186#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
187pub struct Gamepad {
188 pub id: usize,
189}
190
191impl Gamepad {
192 pub fn new(id: usize) -> Self {
193 Self { id }
194 }
195}
196
197#[derive(PartialEq, Eq, Copy, Clone, Debug, Serialize, Deserialize)]
198pub enum GamepadButtonType {
199 South,
200 East,
201 North,
202 West,
203 C,
204 Z,
205 LeftTrigger,
206 LeftTrigger2,
207 RightTrigger,
208 RightTrigger2,
209 Select,
210 Start,
211 Mode,
212 LeftThumb,
213 RightThumb,
214 DPadUp,
215 DPadDown,
216 DPadLeft,
217 DPadRight,
218}
219
220#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
221pub struct GamepadAxis {
222 pub gamepad: Gamepad,
223 pub axis_type: GamepadAxisType,
224}
225
226impl GamepadAxis {
227 pub fn new(gamepad: Gamepad, axis_type: GamepadAxisType) -> Self {
228 Self { gamepad, axis_type }
229 }
230}
231
232#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
233pub enum GamepadAxisType {
234 LeftStickX,
235 LeftStickY,
236 LeftZ,
237 RightStickX,
238 RightStickY,
239 RightZ,
240}
241
242#[derive(PartialEq, Eq, Default, Clone, Debug, Serialize, Deserialize)]
243pub struct KeyAssign(pub Vec<MultiKey>);
244
245impl From<SingleKey> for KeyAssign {
246 fn from(key: SingleKey) -> Self {
247 KeyAssign(vec![MultiKey(vec![key])])
248 }
249}
250
251#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
252pub struct MultiKey(pub Vec<SingleKey>);
253
254#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
255pub enum SingleKey {
256 KeyCode(KeyCode),
257 GamepadButton(GamepadButton),
258 GamepadAxis(GamepadAxis, GamepadAxisDir),
259}
260
261#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
262pub enum GamepadAxisDir {
263 Pos,
264 Neg,
265}
266
267impl Display for KeyCode {
268 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
269 write!(f, "{:?}", self)
270 }
271}
272
273impl Display for GamepadButton {
274 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
275 write!(f, "Pad{}.{}", self.gamepad.id, self.button_type)
276 }
277}
278
279impl Display for GamepadButtonType {
280 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
281 use GamepadButtonType::*;
282 let s = match self {
283 South => "S",
284 East => "E",
285 North => "N",
286 West => "W",
287 C => "C",
288 Z => "Z",
289 LeftTrigger => "LB",
290 LeftTrigger2 => "LT",
291 RightTrigger => "RB",
292 RightTrigger2 => "RT",
293 Select => "Select",
294 Start => "Start",
295 Mode => "Mode",
296 LeftThumb => "LS",
297 RightThumb => "RS",
298 DPadUp => "DPadUp",
299 DPadDown => "DPadDown",
300 DPadLeft => "DPadLeft",
301 DPadRight => "DPadRight",
302 };
303 write!(f, "{s}")
304 }
305}
306
307impl Display for GamepadAxis {
308 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
309 write!(f, "Pad{}.{}", self.gamepad.id, self.axis_type)
310 }
311}
312
313impl Display for GamepadAxisDir {
314 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
315 let s = match self {
316 GamepadAxisDir::Pos => "+",
317 GamepadAxisDir::Neg => "-",
318 };
319 write!(f, "{s}")
320 }
321}
322
323impl Display for GamepadAxisType {
324 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
325 use GamepadAxisType::*;
326 let s = match self {
327 LeftStickX => "LX",
328 LeftStickY => "LY",
329 LeftZ => "LZ",
330 RightStickX => "RX",
331 RightStickY => "RY",
332 RightZ => "RZ",
333 };
334 write!(f, "{s}")
335 }
336}
337
338impl Display for MultiKey {
339 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
340 let mut first = true;
341 for single_key in &self.0 {
342 if !first {
343 write!(f, "+")?;
344 }
345 write!(f, "{}", single_key)?;
346 first = false;
347 }
348 Ok(())
349 }
350}
351
352impl Display for SingleKey {
353 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
354 match self {
355 SingleKey::KeyCode(kc) => write!(f, "{kc}"),
356 SingleKey::GamepadButton(button) => write!(f, "{button}"),
357 SingleKey::GamepadAxis(axis, dir) => write!(f, "{axis}{dir}"),
358 }
359 }
360}
361
362pub trait InputState {
363 fn pressed(&self, key: &SingleKey) -> bool;
364 fn just_pressed(&self, key: &SingleKey) -> bool;
365}
366
367impl KeyAssign {
368 pub fn and(self, rhs: Self) -> Self {
369 let mut ret = vec![];
370 for l in self.0.into_iter() {
371 for r in rhs.0.iter() {
372 let mut t = l.0.clone();
373 t.append(&mut r.0.clone());
374 ret.push(MultiKey(t));
375 }
376 }
377 Self(ret)
378 }
379
380 pub fn or(mut self, mut rhs: Self) -> Self {
381 self.0.append(&mut rhs.0);
382 self
383 }
384 pub fn pressed(&self, input_state: &impl InputState) -> bool {
385 self.0
386 .iter()
387 .any(|multi_key| multi_key.pressed(input_state))
388 }
389
390 pub fn just_pressed(&self, input_state: &impl InputState) -> bool {
391 self.0
392 .iter()
393 .any(|multi_key| multi_key.just_pressed(input_state))
394 }
395
396 pub fn extract_keycode(&self) -> Option<KeyCode> {
397 for MultiKey(mk) in &self.0 {
398 if let [SingleKey::KeyCode(r)] = &mk[..] {
399 return Some(*r);
400 }
401 }
402 None
403 }
404
405 pub fn insert_keycode(&mut self, kc: KeyCode) {
406 for MultiKey(mk) in self.0.iter_mut() {
407 if let [SingleKey::KeyCode(r)] = &mut mk[..] {
408 *r = kc;
409 return;
410 }
411 }
412 self.0.push(MultiKey(vec![SingleKey::KeyCode(kc)]));
413 }
414
415 pub fn extract_gamepad(&self) -> Option<GamepadButton> {
416 for MultiKey(mk) in &self.0 {
417 if let [SingleKey::GamepadButton(r)] = &mk[..] {
418 return Some(*r);
419 }
420 }
421 None
422 }
423
424 pub fn insert_gamepad(&mut self, button: GamepadButton) {
425 for MultiKey(mk) in self.0.iter_mut() {
426 if let [SingleKey::GamepadButton(r)] = &mut mk[..] {
427 *r = button;
428 return;
429 }
430 }
431 self.0
432 .push(MultiKey(vec![SingleKey::GamepadButton(button)]));
433 }
434}
435
436impl MultiKey {
437 fn pressed(&self, input_state: &impl InputState) -> bool {
438 self.0
439 .iter()
440 .all(|single_key| input_state.pressed(single_key))
441 }
442
443 fn just_pressed(&self, input_state: &impl InputState) -> bool {
444 self.pressed(input_state)
446 && self
447 .0
448 .iter()
449 .any(|single_key| input_state.just_pressed(single_key))
450 }
451}
452
453#[macro_export]
454macro_rules! any {
455 ($x:expr, $($xs:expr),* $(,)?) => {
456 [$($xs),*].into_iter().fold($x, |a, b| a.or(b))
457 };
458}
459pub use any;
460
461#[macro_export]
462macro_rules! all {
463 ($x:expr, $($xs:expr),* $(,)?) => {{
464 [$($xs),*].into_iter().fold($x, |a, b| a.and(b))
465 }};
466}
467pub use all;
468
469#[macro_export]
470macro_rules! keycode {
471 ($code:ident) => {
472 KeyAssign(vec![MultiKey(vec![
473 $crate::key_assign::SingleKey::KeyCode($crate::key_assign::KeyCode::$code),
474 ])])
475 };
476}
477pub use keycode;
478
479#[macro_export]
480macro_rules! pad_button {
481 ($id:literal, $button:ident) => {
482 $crate::key_assign::KeyAssign(vec![$crate::key_assign::MultiKey(vec![
483 $crate::key_assign::SingleKey::GamepadButton($crate::key_assign::GamepadButton::new(
484 $crate::key_assign::Gamepad::new($id),
485 $crate::key_assign::GamepadButtonType::$button,
486 )),
487 ])])
488 };
489}
490pub use pad_button;