1use crate::{
5 game_input::GameInput, settings::gamepad::con_settings::LayerEntry, window::MenuInput,
6};
7use gilrs::{Axis as GilAxis, Button as GilButton, ev::Code as GilCode};
8use hashbrown::{HashMap, HashSet};
9use i18n::Localization;
10use serde::{Deserialize, Serialize};
11
12#[derive(Clone, Debug, Default)]
14pub struct ControllerSettings {
15 pub game_button_map: HashMap<GameInput, Button>,
16 pub inverse_game_button_map: HashMap<Button, HashSet<GameInput>>,
17 pub menu_button_map: HashMap<MenuInput, Button>,
18 pub inverse_menu_button_map: HashMap<Button, HashSet<MenuInput>>,
19 pub game_analog_button_map: HashMap<AnalogButtonGameAction, AnalogButton>,
20 pub inverse_game_analog_button_map: HashMap<AnalogButton, HashSet<AnalogButtonGameAction>>,
21 pub menu_analog_button_map: HashMap<AnalogButtonMenuAction, AnalogButton>,
22 pub inverse_menu_analog_button_map: HashMap<AnalogButton, HashSet<AnalogButtonMenuAction>>,
23 pub game_axis_map: HashMap<AxisGameAction, Axis>,
24 pub inverse_game_axis_map: HashMap<Axis, HashSet<AxisGameAction>>,
25 pub menu_axis_map: HashMap<AxisMenuAction, Axis>,
26 pub inverse_menu_axis_map: HashMap<Axis, HashSet<AxisMenuAction>>,
27 pub layer_button_map: HashMap<GameInput, LayerEntry>,
28 pub inverse_layer_button_map: HashMap<LayerEntry, HashSet<GameInput>>,
29 pub modifier_buttons: Vec<Button>,
30 pub pan_sensitivity: u32,
31 pub pan_invert_y: bool,
32 pub axis_deadzones: HashMap<Axis, f32>,
33 pub button_deadzones: HashMap<AnalogButton, f32>,
34 pub mouse_emulation_sensitivity: u32,
35 pub inverted_axes: Vec<Axis>,
36}
37
38impl ControllerSettings {
39 pub fn apply_axis_deadzone(&self, k: &Axis, input: f32) -> f32 {
40 let threshold = *self.axis_deadzones.get(k).unwrap_or(&0.2);
41
42 let input_abs = input.abs();
45 if input_abs <= threshold || threshold >= 1.0 {
46 0.0
47 } else if threshold <= 0.0 {
48 input
49 } else {
50 (input_abs - threshold) / (1.0 - threshold) * input.signum()
51 }
52 }
53
54 pub fn apply_button_deadzone(&self, k: &AnalogButton, input: f32) -> f32 {
55 let threshold = *self.button_deadzones.get(k).unwrap_or(&0.2);
56
57 if input <= threshold || threshold >= 1.0 {
60 0.0
61 } else if threshold <= 0.0 {
62 input
63 } else {
64 (input - threshold) / (1.0 - threshold)
65 }
66 }
67
68 pub fn get_game_button_binding(&self, input: GameInput) -> Option<Button> {
69 self.game_button_map.get(&input).copied()
70 }
71
72 pub fn get_menu_button_binding(&self, input: MenuInput) -> Option<Button> {
73 self.menu_button_map.get(&input).copied()
74 }
75
76 pub fn get_layer_button_binding(&self, input: GameInput) -> Option<LayerEntry> {
77 self.layer_button_map.get(&input).copied()
78 }
79
80 pub fn insert_game_button_binding(&mut self, game_input: GameInput, game_button: Button) {
81 if game_button != Button::default() {
82 self.game_button_map.insert(game_input, game_button);
83 self.inverse_game_button_map
84 .entry(game_button)
85 .or_default()
86 .insert(game_input);
87 }
88 }
89
90 pub fn insert_menu_button_binding(&mut self, menu_input: MenuInput, button: Button) {
91 if button != Button::default() {
92 self.menu_button_map.insert(menu_input, button);
93 self.inverse_menu_button_map
94 .entry(button)
95 .or_default()
96 .insert(menu_input);
97 }
98 }
99
100 pub fn insert_game_axis_binding(&mut self, input: AxisGameAction, axis: Axis) {
101 if axis != Axis::default() {
102 self.game_axis_map.insert(input, axis);
103 self.inverse_game_axis_map
104 .entry(axis)
105 .or_default()
106 .insert(input);
107 }
108 }
109
110 pub fn insert_menu_axis_binding(&mut self, input: AxisMenuAction, axis: Axis) {
111 if axis != Axis::default() {
112 self.menu_axis_map.insert(input, axis);
113 self.inverse_menu_axis_map
114 .entry(axis)
115 .or_default()
116 .insert(input);
117 }
118 }
119
120 pub fn insert_layer_button_binding(&mut self, input: GameInput, layer_entry: LayerEntry) {
121 if layer_entry != LayerEntry::default() {
122 self.layer_button_map.insert(input, layer_entry);
123 self.inverse_layer_button_map
124 .entry(layer_entry)
125 .or_default()
126 .insert(input);
127 }
128 }
129
130 pub fn game_button_has_conflicting_bindings(&self, game_button: Button) -> bool {
133 if let Some(game_inputs) = self.inverse_game_button_map.get(&game_button) {
134 for a in game_inputs.iter() {
135 for b in game_inputs.iter() {
136 if !GameInput::can_share_bindings(*a, *b) {
137 return true;
138 }
139 }
140 }
141
142 let layer_entry = LayerEntry {
143 button: game_button,
144 mod1: Button::Simple(GilButton::Unknown),
145 mod2: Button::Simple(GilButton::Unknown),
146 };
147 if let Some(layer_inputs) = self.inverse_layer_button_map.get(&layer_entry) {
148 for a in game_inputs.iter() {
149 for b in layer_inputs.iter() {
150 if !GameInput::can_share_bindings(*a, *b) {
151 return true;
152 }
153 }
154 }
155 }
156 }
157 false
158 }
159
160 pub fn menu_button_has_conflicting_bindings(&self, menu_button: Button) -> bool {
161 self.inverse_menu_button_map
162 .get(&menu_button)
163 .is_some_and(|menu_inputs| menu_inputs.len() > 1)
164 }
165
166 pub fn layer_entry_has_conflicting_bindings(&self, layer_entry: LayerEntry) -> bool {
169 if let Some(layer_inputs) = self.inverse_layer_button_map.get(&layer_entry) {
170 for a in layer_inputs.iter() {
171 for b in layer_inputs.iter() {
172 if !GameInput::can_share_bindings(*a, *b) {
173 return true;
174 }
175 }
176 }
177
178 if layer_entry.mod1 == Button::Simple(GilButton::Unknown)
179 && layer_entry.mod2 == Button::Simple(GilButton::Unknown)
180 {
181 if let Some(game_inputs) = self.inverse_game_button_map.get(&layer_entry.button) {
182 for a in layer_inputs.iter() {
183 for b in game_inputs.iter() {
184 if !GameInput::can_share_bindings(*a, *b) {
185 return true;
186 }
187 }
188 }
189 }
190 }
191 }
192 false
193 }
194}
195
196impl From<&crate::settings::GamepadSettings> for ControllerSettings {
197 fn from(settings: &crate::settings::GamepadSettings) -> Self {
198 let mut controller_settings: ControllerSettings = ControllerSettings::default();
199
200 controller_settings
201 .insert_game_button_binding(GameInput::Primary, settings.game_buttons.primary);
202 controller_settings
203 .insert_game_button_binding(GameInput::Secondary, settings.game_buttons.secondary);
204 controller_settings
205 .insert_game_button_binding(GameInput::Block, settings.game_buttons.block);
206 controller_settings
207 .insert_game_button_binding(GameInput::Slot1, settings.game_buttons.slot1);
208 controller_settings
209 .insert_game_button_binding(GameInput::Slot2, settings.game_buttons.slot2);
210 controller_settings
211 .insert_game_button_binding(GameInput::Slot3, settings.game_buttons.slot3);
212 controller_settings
213 .insert_game_button_binding(GameInput::Slot4, settings.game_buttons.slot4);
214 controller_settings
215 .insert_game_button_binding(GameInput::Slot5, settings.game_buttons.slot5);
216 controller_settings
217 .insert_game_button_binding(GameInput::Slot6, settings.game_buttons.slot6);
218 controller_settings
219 .insert_game_button_binding(GameInput::Slot7, settings.game_buttons.slot7);
220 controller_settings
221 .insert_game_button_binding(GameInput::Slot8, settings.game_buttons.slot8);
222 controller_settings
223 .insert_game_button_binding(GameInput::Slot9, settings.game_buttons.slot9);
224 controller_settings
225 .insert_game_button_binding(GameInput::Slot10, settings.game_buttons.slot10);
226 controller_settings.insert_game_button_binding(
227 GameInput::ToggleCursor,
228 settings.game_buttons.toggle_cursor,
229 );
230 controller_settings
231 .insert_game_button_binding(GameInput::Escape, settings.game_buttons.escape);
232 controller_settings
233 .insert_game_button_binding(GameInput::Chat, settings.game_buttons.enter);
234 controller_settings
235 .insert_game_button_binding(GameInput::Command, settings.game_buttons.command);
236 controller_settings
237 .insert_game_button_binding(GameInput::MoveForward, settings.game_buttons.move_forward);
238 controller_settings
239 .insert_game_button_binding(GameInput::MoveLeft, settings.game_buttons.move_left);
240 controller_settings
241 .insert_game_button_binding(GameInput::MoveBack, settings.game_buttons.move_back);
242 controller_settings
243 .insert_game_button_binding(GameInput::MoveRight, settings.game_buttons.move_right);
244 controller_settings.insert_game_button_binding(GameInput::Jump, settings.game_buttons.jump);
245 controller_settings.insert_game_button_binding(GameInput::Sit, settings.game_buttons.sit);
246 controller_settings
247 .insert_game_button_binding(GameInput::Dance, settings.game_buttons.dance);
248 controller_settings
249 .insert_game_button_binding(GameInput::Glide, settings.game_buttons.glide);
250 controller_settings
251 .insert_game_button_binding(GameInput::SwimUp, settings.game_buttons.swimup);
252 controller_settings
253 .insert_game_button_binding(GameInput::SwimDown, settings.game_buttons.swimdown);
254 controller_settings
255 .insert_game_button_binding(GameInput::Sneak, settings.game_buttons.sneak);
256 controller_settings.insert_game_button_binding(
257 GameInput::ToggleLantern,
258 settings.game_buttons.toggle_lantern,
259 );
260 controller_settings
261 .insert_game_button_binding(GameInput::Mount, settings.game_buttons.mount);
262 controller_settings.insert_game_button_binding(GameInput::Map, settings.game_buttons.map);
263 controller_settings
264 .insert_game_button_binding(GameInput::Inventory, settings.game_buttons.bag);
265 controller_settings
266 .insert_game_button_binding(GameInput::Social, settings.game_buttons.social);
267 controller_settings
268 .insert_game_button_binding(GameInput::Crafting, settings.game_buttons.crafting);
269 controller_settings
270 .insert_game_button_binding(GameInput::Diary, settings.game_buttons.diary);
271 controller_settings
272 .insert_game_button_binding(GameInput::Settings, settings.game_buttons.settings);
273 controller_settings
274 .insert_game_button_binding(GameInput::Controls, settings.game_buttons.controls);
275 controller_settings.insert_game_button_binding(
276 GameInput::ToggleInterface,
277 settings.game_buttons.toggle_interface,
278 );
279 controller_settings
280 .insert_game_button_binding(GameInput::ToggleDebug, settings.game_buttons.toggle_debug);
281 #[cfg(feature = "egui-ui")]
282 controller_settings.insert_game_button_binding(
283 GameInput::ToggleEguiDebug,
284 settings.game_buttons.toggle_debug,
285 );
286 controller_settings
287 .insert_game_button_binding(GameInput::ToggleChat, settings.game_buttons.toggle_chat);
288 controller_settings
289 .insert_game_button_binding(GameInput::Fullscreen, settings.game_buttons.fullscreen);
290 controller_settings
291 .insert_game_button_binding(GameInput::Screenshot, settings.game_buttons.screenshot);
292 controller_settings.insert_game_button_binding(
293 GameInput::ToggleIngameUi,
294 settings.game_buttons.toggle_ingame_ui,
295 );
296 controller_settings.insert_game_button_binding(GameInput::Roll, settings.game_buttons.roll);
297 controller_settings
298 .insert_game_button_binding(GameInput::Respawn, settings.game_buttons.respawn);
299 controller_settings
300 .insert_game_button_binding(GameInput::Interact, settings.game_buttons.interact);
301 controller_settings
302 .insert_game_button_binding(GameInput::ToggleWield, settings.game_buttons.toggle_wield);
303 controller_settings
304 .insert_game_button_binding(GameInput::SwapLoadout, settings.game_buttons.swap_loadout);
305
306 controller_settings.insert_menu_button_binding(MenuInput::Up, settings.menu_buttons.up);
307 controller_settings.insert_menu_button_binding(MenuInput::Down, settings.menu_buttons.down);
308 controller_settings.insert_menu_button_binding(MenuInput::Left, settings.menu_buttons.left);
309 controller_settings
310 .insert_menu_button_binding(MenuInput::Right, settings.menu_buttons.right);
311 controller_settings
312 .insert_menu_button_binding(MenuInput::ScrollUp, settings.menu_buttons.scroll_up);
313 controller_settings
314 .insert_menu_button_binding(MenuInput::ScrollDown, settings.menu_buttons.scroll_down);
315 controller_settings
316 .insert_menu_button_binding(MenuInput::ScrollLeft, settings.menu_buttons.scroll_left);
317 controller_settings
318 .insert_menu_button_binding(MenuInput::ScrollRight, settings.menu_buttons.scroll_right);
319 controller_settings.insert_menu_button_binding(MenuInput::Home, settings.menu_buttons.home);
320 controller_settings.insert_menu_button_binding(MenuInput::End, settings.menu_buttons.end);
321 controller_settings
322 .insert_menu_button_binding(MenuInput::Apply, settings.menu_buttons.apply);
323 controller_settings.insert_menu_button_binding(MenuInput::Back, settings.menu_buttons.back);
324 controller_settings.insert_menu_button_binding(MenuInput::Exit, settings.menu_buttons.exit);
325
326 controller_settings
327 .insert_game_axis_binding(AxisGameAction::MovementX, settings.game_axis.movement_x);
328 controller_settings
329 .insert_game_axis_binding(AxisGameAction::MovementY, settings.game_axis.movement_y);
330 controller_settings
331 .insert_game_axis_binding(AxisGameAction::CameraX, settings.game_axis.camera_x);
332 controller_settings
333 .insert_game_axis_binding(AxisGameAction::CameraY, settings.game_axis.camera_y);
334
335 controller_settings
336 .insert_menu_axis_binding(AxisMenuAction::MoveX, settings.menu_axis.move_x);
337 controller_settings
338 .insert_menu_axis_binding(AxisMenuAction::MoveY, settings.menu_axis.move_y);
339 controller_settings
340 .insert_menu_axis_binding(AxisMenuAction::ScrollX, settings.menu_axis.scroll_x);
341 controller_settings
342 .insert_menu_axis_binding(AxisMenuAction::ScrollY, settings.menu_axis.scroll_y);
343
344 controller_settings.insert_layer_button_binding(
345 GameInput::Secondary,
346 settings.game_layer_buttons.secondary,
347 );
348 controller_settings
349 .insert_layer_button_binding(GameInput::Primary, settings.game_layer_buttons.primary);
350 controller_settings
351 .insert_layer_button_binding(GameInput::Block, settings.game_layer_buttons.block);
352 controller_settings
353 .insert_layer_button_binding(GameInput::Slot1, settings.game_layer_buttons.slot1);
354 controller_settings
355 .insert_layer_button_binding(GameInput::Slot2, settings.game_layer_buttons.slot2);
356 controller_settings
357 .insert_layer_button_binding(GameInput::Slot3, settings.game_layer_buttons.slot3);
358 controller_settings
359 .insert_layer_button_binding(GameInput::Slot4, settings.game_layer_buttons.slot4);
360 controller_settings
361 .insert_layer_button_binding(GameInput::Slot5, settings.game_layer_buttons.slot5);
362 controller_settings
363 .insert_layer_button_binding(GameInput::Slot6, settings.game_layer_buttons.slot6);
364 controller_settings
365 .insert_layer_button_binding(GameInput::Slot7, settings.game_layer_buttons.slot7);
366 controller_settings
367 .insert_layer_button_binding(GameInput::Slot8, settings.game_layer_buttons.slot8);
368 controller_settings
369 .insert_layer_button_binding(GameInput::Slot9, settings.game_layer_buttons.slot9);
370 controller_settings
371 .insert_layer_button_binding(GameInput::Slot10, settings.game_layer_buttons.slot10);
372 controller_settings.insert_layer_button_binding(
373 GameInput::ToggleCursor,
374 settings.game_layer_buttons.toggle_cursor,
375 );
376 controller_settings
377 .insert_layer_button_binding(GameInput::Escape, settings.game_layer_buttons.escape);
378 controller_settings
379 .insert_layer_button_binding(GameInput::Chat, settings.game_layer_buttons.enter);
380 controller_settings
381 .insert_layer_button_binding(GameInput::Command, settings.game_layer_buttons.command);
382 controller_settings.insert_layer_button_binding(
383 GameInput::MoveForward,
384 settings.game_layer_buttons.move_forward,
385 );
386 controller_settings.insert_layer_button_binding(
387 GameInput::MoveLeft,
388 settings.game_layer_buttons.move_left,
389 );
390 controller_settings.insert_layer_button_binding(
391 GameInput::MoveBack,
392 settings.game_layer_buttons.move_back,
393 );
394 controller_settings.insert_layer_button_binding(
395 GameInput::MoveRight,
396 settings.game_layer_buttons.move_right,
397 );
398 controller_settings
399 .insert_layer_button_binding(GameInput::Jump, settings.game_layer_buttons.jump);
400 controller_settings
401 .insert_layer_button_binding(GameInput::Sit, settings.game_layer_buttons.sit);
402 controller_settings
403 .insert_layer_button_binding(GameInput::Dance, settings.game_layer_buttons.dance);
404 controller_settings
405 .insert_layer_button_binding(GameInput::Glide, settings.game_layer_buttons.glide);
406 controller_settings
407 .insert_layer_button_binding(GameInput::SwimUp, settings.game_layer_buttons.swimup);
408 controller_settings
409 .insert_layer_button_binding(GameInput::SwimDown, settings.game_layer_buttons.swimdown);
410 controller_settings
411 .insert_layer_button_binding(GameInput::Sneak, settings.game_layer_buttons.sneak);
412 controller_settings.insert_layer_button_binding(
413 GameInput::ToggleLantern,
414 settings.game_layer_buttons.toggle_lantern,
415 );
416 controller_settings
417 .insert_layer_button_binding(GameInput::Mount, settings.game_layer_buttons.mount);
418 controller_settings
419 .insert_layer_button_binding(GameInput::Map, settings.game_layer_buttons.map);
420 controller_settings
421 .insert_layer_button_binding(GameInput::Inventory, settings.game_layer_buttons.bag);
422 controller_settings
423 .insert_layer_button_binding(GameInput::Social, settings.game_layer_buttons.social);
424 controller_settings
425 .insert_layer_button_binding(GameInput::Crafting, settings.game_layer_buttons.crafting);
426 controller_settings
427 .insert_layer_button_binding(GameInput::Diary, settings.game_layer_buttons.diary);
428 controller_settings
429 .insert_layer_button_binding(GameInput::Settings, settings.game_layer_buttons.settings);
430 controller_settings
431 .insert_layer_button_binding(GameInput::Controls, settings.game_layer_buttons.controls);
432 controller_settings.insert_layer_button_binding(
433 GameInput::ToggleInterface,
434 settings.game_layer_buttons.toggle_interface,
435 );
436 controller_settings.insert_layer_button_binding(
437 GameInput::ToggleDebug,
438 settings.game_layer_buttons.toggle_debug,
439 );
440 #[cfg(feature = "egui-ui")]
441 controller_settings.insert_layer_button_binding(
442 GameInput::ToggleEguiDebug,
443 settings.game_layer_buttons.toggle_debug,
444 );
445 controller_settings.insert_layer_button_binding(
446 GameInput::ToggleChat,
447 settings.game_layer_buttons.toggle_chat,
448 );
449 controller_settings.insert_layer_button_binding(
450 GameInput::Fullscreen,
451 settings.game_layer_buttons.fullscreen,
452 );
453 controller_settings.insert_layer_button_binding(
454 GameInput::Screenshot,
455 settings.game_layer_buttons.screenshot,
456 );
457 controller_settings.insert_layer_button_binding(
458 GameInput::ToggleIngameUi,
459 settings.game_layer_buttons.toggle_ingame_ui,
460 );
461 controller_settings
462 .insert_layer_button_binding(GameInput::Roll, settings.game_layer_buttons.roll);
463 controller_settings
464 .insert_layer_button_binding(GameInput::Respawn, settings.game_layer_buttons.respawn);
465 controller_settings
466 .insert_layer_button_binding(GameInput::Interact, settings.game_layer_buttons.interact);
467 controller_settings.insert_layer_button_binding(
468 GameInput::ToggleWield,
469 settings.game_layer_buttons.toggle_wield,
470 );
471 controller_settings.insert_layer_button_binding(
472 GameInput::SwapLoadout,
473 settings.game_layer_buttons.swap_loadout,
474 );
475
476 controller_settings.modifier_buttons = vec![
477 Button::Simple(GilButton::RightTrigger),
478 Button::Simple(GilButton::LeftTrigger),
479 ];
480 controller_settings.pan_sensitivity = settings.pan_sensitivity;
481 controller_settings.pan_invert_y = settings.pan_invert_y;
482 controller_settings
483 .axis_deadzones
484 .clone_from(&settings.axis_deadzones);
485 controller_settings
486 .button_deadzones
487 .clone_from(&settings.button_deadzones);
488 controller_settings.mouse_emulation_sensitivity = settings.mouse_emulation_sensitivity;
489 controller_settings
490 .inverted_axes
491 .clone_from(&settings.inverted_axes);
492
493 controller_settings
494 }
495}
496
497#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Deserialize, Serialize)]
499pub enum AxisMenuAction {
500 MoveX,
501 MoveY,
502 ScrollX,
503 ScrollY,
504}
505
506#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Deserialize, Serialize)]
508pub enum AxisGameAction {
509 MovementX,
510 MovementY,
511 CameraX,
512 CameraY,
513}
514
515#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Deserialize, Serialize)]
517pub enum AnalogButtonMenuAction {}
518
519#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Deserialize, Serialize)]
521pub enum AnalogButtonGameAction {}
522
523#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Deserialize, Serialize)]
526pub enum Button {
527 Simple(GilButton),
528 EventCode(u32),
529}
530
531impl Default for Button {
532 fn default() -> Self { Button::Simple(GilButton::Unknown) }
533}
534
535impl Button {
536 pub fn display_string(&self, localized_strings: &Localization) -> String {
538 use self::Button::*;
539 let button_string = match self {
541 Simple(GilButton::South) => localized_strings.get_msg("gamepad-south").to_string(),
542 Simple(GilButton::East) => localized_strings.get_msg("gamepad-east").to_string(),
543 Simple(GilButton::North) => localized_strings.get_msg("gamepad-north").to_string(),
544 Simple(GilButton::West) => localized_strings.get_msg("gamepad-west").to_string(),
545 Simple(GilButton::C) => localized_strings.get_msg("gamepad-c").to_string(),
546 Simple(GilButton::Z) => localized_strings.get_msg("gamepad-z").to_string(),
547 Simple(GilButton::LeftTrigger) => localized_strings
548 .get_msg("gamepad-left_trigger")
549 .to_string(),
550 Simple(GilButton::LeftTrigger2) => localized_strings
551 .get_msg("gamepad-left_trigger_2")
552 .to_string(),
553 Simple(GilButton::RightTrigger) => localized_strings
554 .get_msg("gamepad-right_trigger")
555 .to_string(),
556 Simple(GilButton::RightTrigger2) => localized_strings
557 .get_msg("gamepad-right_trigger_2")
558 .to_string(),
559 Simple(GilButton::Select) => localized_strings.get_msg("gamepad-select").to_string(),
560 Simple(GilButton::Start) => localized_strings.get_msg("gamepad-start").to_string(),
561 Simple(GilButton::Mode) => localized_strings.get_msg("gamepad-mode").to_string(),
562 Simple(GilButton::LeftThumb) => {
563 localized_strings.get_msg("gamepad-left_thumb").to_string()
564 },
565 Simple(GilButton::RightThumb) => {
566 localized_strings.get_msg("gamepad-right_thumb").to_string()
567 },
568 Simple(GilButton::DPadUp) => localized_strings.get_msg("gamepad-dpad_up").to_string(),
569 Simple(GilButton::DPadDown) => {
570 localized_strings.get_msg("gamepad-dpad_down").to_string()
571 },
572 Simple(GilButton::DPadLeft) => {
573 localized_strings.get_msg("gamepad-dpad_left").to_string()
574 },
575 Simple(GilButton::DPadRight) => {
576 localized_strings.get_msg("gamepad-dpad_right").to_string()
577 },
578 Simple(GilButton::Unknown) => localized_strings.get_msg("gamepad-unknown").to_string(),
579 EventCode(code) => code.to_string(),
580 };
581
582 button_string.to_owned()
583 }
584
585 pub fn try_shortened(&self) -> Option<String> {
588 use self::Button::*;
589 let button_string = match self {
590 Simple(GilButton::South) => "A",
591 Simple(GilButton::East) => "B",
592 Simple(GilButton::North) => "Y",
593 Simple(GilButton::West) => "X",
594 Simple(GilButton::LeftTrigger) => "LB",
595 Simple(GilButton::LeftTrigger2) => "LT",
596 Simple(GilButton::RightTrigger) => "RB",
597 Simple(GilButton::RightTrigger2) => "RT",
598 Simple(GilButton::LeftThumb) => "L3",
599 Simple(GilButton::RightThumb) => "R3",
600 _ => return None,
601 };
602
603 Some(button_string.to_owned())
604 }
605}
606
607#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Deserialize, Serialize)]
610pub enum AnalogButton {
611 Simple(GilButton),
612 EventCode(u32),
613}
614
615impl Default for AnalogButton {
616 fn default() -> Self { AnalogButton::Simple(GilButton::Unknown) }
617}
618
619#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Deserialize, Serialize)]
622pub enum Axis {
623 Simple(GilAxis),
624 EventCode(u32),
625}
626
627impl Default for Axis {
628 fn default() -> Self { Axis::Simple(GilAxis::Unknown) }
629}
630
631impl From<(GilAxis, GilCode)> for Axis {
632 fn from((axis, code): (GilAxis, GilCode)) -> Self {
633 match axis {
634 GilAxis::Unknown => Self::EventCode(code.into_u32()),
635 _ => Self::Simple(axis),
636 }
637 }
638}
639
640impl From<(GilButton, GilCode)> for Button {
641 fn from((button, code): (GilButton, GilCode)) -> Self {
642 match button {
643 GilButton::Unknown => Self::EventCode(code.into_u32()),
644 _ => Self::Simple(button),
645 }
646 }
647}
648
649impl From<(GilButton, GilCode)> for AnalogButton {
650 fn from((button, code): (GilButton, GilCode)) -> Self {
651 match button {
652 GilButton::Unknown => Self::EventCode(code.into_u32()),
653 _ => Self::Simple(button),
654 }
655 }
656}