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 && let Some(game_inputs) = self.inverse_game_button_map.get(&layer_entry.button)
181 {
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 false
192 }
193}
194
195impl From<&crate::settings::GamepadSettings> for ControllerSettings {
196 fn from(settings: &crate::settings::GamepadSettings) -> Self {
197 let mut controller_settings: ControllerSettings = ControllerSettings::default();
198
199 controller_settings
200 .insert_game_button_binding(GameInput::Primary, settings.game_buttons.primary);
201 controller_settings
202 .insert_game_button_binding(GameInput::Secondary, settings.game_buttons.secondary);
203 controller_settings
204 .insert_game_button_binding(GameInput::Block, settings.game_buttons.block);
205 controller_settings
206 .insert_game_button_binding(GameInput::Slot1, settings.game_buttons.slot1);
207 controller_settings
208 .insert_game_button_binding(GameInput::Slot2, settings.game_buttons.slot2);
209 controller_settings
210 .insert_game_button_binding(GameInput::Slot3, settings.game_buttons.slot3);
211 controller_settings
212 .insert_game_button_binding(GameInput::Slot4, settings.game_buttons.slot4);
213 controller_settings
214 .insert_game_button_binding(GameInput::Slot5, settings.game_buttons.slot5);
215 controller_settings
216 .insert_game_button_binding(GameInput::Slot6, settings.game_buttons.slot6);
217 controller_settings
218 .insert_game_button_binding(GameInput::Slot7, settings.game_buttons.slot7);
219 controller_settings
220 .insert_game_button_binding(GameInput::Slot8, settings.game_buttons.slot8);
221 controller_settings
222 .insert_game_button_binding(GameInput::Slot9, settings.game_buttons.slot9);
223 controller_settings
224 .insert_game_button_binding(GameInput::Slot10, settings.game_buttons.slot10);
225 controller_settings.insert_game_button_binding(
226 GameInput::ToggleCursor,
227 settings.game_buttons.toggle_cursor,
228 );
229 controller_settings
230 .insert_game_button_binding(GameInput::Escape, settings.game_buttons.escape);
231 controller_settings
232 .insert_game_button_binding(GameInput::Chat, settings.game_buttons.enter);
233 controller_settings
234 .insert_game_button_binding(GameInput::Command, settings.game_buttons.command);
235 controller_settings
236 .insert_game_button_binding(GameInput::MoveForward, settings.game_buttons.move_forward);
237 controller_settings
238 .insert_game_button_binding(GameInput::MoveLeft, settings.game_buttons.move_left);
239 controller_settings
240 .insert_game_button_binding(GameInput::MoveBack, settings.game_buttons.move_back);
241 controller_settings
242 .insert_game_button_binding(GameInput::MoveRight, settings.game_buttons.move_right);
243 controller_settings.insert_game_button_binding(GameInput::Jump, settings.game_buttons.jump);
244 controller_settings.insert_game_button_binding(GameInput::Sit, settings.game_buttons.sit);
245 controller_settings
246 .insert_game_button_binding(GameInput::Dance, settings.game_buttons.dance);
247 controller_settings
248 .insert_game_button_binding(GameInput::Glide, settings.game_buttons.glide);
249 controller_settings
250 .insert_game_button_binding(GameInput::SwimUp, settings.game_buttons.swimup);
251 controller_settings
252 .insert_game_button_binding(GameInput::SwimDown, settings.game_buttons.swimdown);
253 controller_settings
254 .insert_game_button_binding(GameInput::Sneak, settings.game_buttons.sneak);
255 controller_settings.insert_game_button_binding(
256 GameInput::ToggleLantern,
257 settings.game_buttons.toggle_lantern,
258 );
259 controller_settings
260 .insert_game_button_binding(GameInput::Mount, settings.game_buttons.mount);
261 controller_settings.insert_game_button_binding(GameInput::Map, settings.game_buttons.map);
262 controller_settings
263 .insert_game_button_binding(GameInput::Inventory, settings.game_buttons.bag);
264 controller_settings
265 .insert_game_button_binding(GameInput::Social, settings.game_buttons.social);
266 controller_settings
267 .insert_game_button_binding(GameInput::Crafting, settings.game_buttons.crafting);
268 controller_settings
269 .insert_game_button_binding(GameInput::Diary, settings.game_buttons.diary);
270 controller_settings
271 .insert_game_button_binding(GameInput::Settings, settings.game_buttons.settings);
272 controller_settings
273 .insert_game_button_binding(GameInput::Controls, settings.game_buttons.controls);
274 controller_settings.insert_game_button_binding(
275 GameInput::ToggleInterface,
276 settings.game_buttons.toggle_interface,
277 );
278 controller_settings
279 .insert_game_button_binding(GameInput::ToggleDebug, settings.game_buttons.toggle_debug);
280 #[cfg(feature = "egui-ui")]
281 controller_settings.insert_game_button_binding(
282 GameInput::ToggleEguiDebug,
283 settings.game_buttons.toggle_debug,
284 );
285 controller_settings
286 .insert_game_button_binding(GameInput::ToggleChat, settings.game_buttons.toggle_chat);
287 controller_settings
288 .insert_game_button_binding(GameInput::Fullscreen, settings.game_buttons.fullscreen);
289 controller_settings
290 .insert_game_button_binding(GameInput::Screenshot, settings.game_buttons.screenshot);
291 controller_settings.insert_game_button_binding(
292 GameInput::ToggleIngameUi,
293 settings.game_buttons.toggle_ingame_ui,
294 );
295 controller_settings.insert_game_button_binding(GameInput::Roll, settings.game_buttons.roll);
296 controller_settings
297 .insert_game_button_binding(GameInput::Respawn, settings.game_buttons.respawn);
298 controller_settings
299 .insert_game_button_binding(GameInput::Interact, settings.game_buttons.interact);
300 controller_settings
301 .insert_game_button_binding(GameInput::ToggleWield, settings.game_buttons.toggle_wield);
302 controller_settings
303 .insert_game_button_binding(GameInput::SwapLoadout, settings.game_buttons.swap_loadout);
304
305 controller_settings.insert_menu_button_binding(MenuInput::Up, settings.menu_buttons.up);
306 controller_settings.insert_menu_button_binding(MenuInput::Down, settings.menu_buttons.down);
307 controller_settings.insert_menu_button_binding(MenuInput::Left, settings.menu_buttons.left);
308 controller_settings
309 .insert_menu_button_binding(MenuInput::Right, settings.menu_buttons.right);
310 controller_settings
311 .insert_menu_button_binding(MenuInput::ScrollUp, settings.menu_buttons.scroll_up);
312 controller_settings
313 .insert_menu_button_binding(MenuInput::ScrollDown, settings.menu_buttons.scroll_down);
314 controller_settings
315 .insert_menu_button_binding(MenuInput::ScrollLeft, settings.menu_buttons.scroll_left);
316 controller_settings
317 .insert_menu_button_binding(MenuInput::ScrollRight, settings.menu_buttons.scroll_right);
318 controller_settings.insert_menu_button_binding(MenuInput::Home, settings.menu_buttons.home);
319 controller_settings.insert_menu_button_binding(MenuInput::End, settings.menu_buttons.end);
320 controller_settings
321 .insert_menu_button_binding(MenuInput::Apply, settings.menu_buttons.apply);
322 controller_settings.insert_menu_button_binding(MenuInput::Back, settings.menu_buttons.back);
323 controller_settings.insert_menu_button_binding(MenuInput::Exit, settings.menu_buttons.exit);
324
325 controller_settings
326 .insert_game_axis_binding(AxisGameAction::MovementX, settings.game_axis.movement_x);
327 controller_settings
328 .insert_game_axis_binding(AxisGameAction::MovementY, settings.game_axis.movement_y);
329 controller_settings
330 .insert_game_axis_binding(AxisGameAction::CameraX, settings.game_axis.camera_x);
331 controller_settings
332 .insert_game_axis_binding(AxisGameAction::CameraY, settings.game_axis.camera_y);
333
334 controller_settings
335 .insert_menu_axis_binding(AxisMenuAction::MoveX, settings.menu_axis.move_x);
336 controller_settings
337 .insert_menu_axis_binding(AxisMenuAction::MoveY, settings.menu_axis.move_y);
338 controller_settings
339 .insert_menu_axis_binding(AxisMenuAction::ScrollX, settings.menu_axis.scroll_x);
340 controller_settings
341 .insert_menu_axis_binding(AxisMenuAction::ScrollY, settings.menu_axis.scroll_y);
342
343 controller_settings.insert_layer_button_binding(
344 GameInput::Secondary,
345 settings.game_layer_buttons.secondary,
346 );
347 controller_settings
348 .insert_layer_button_binding(GameInput::Primary, settings.game_layer_buttons.primary);
349 controller_settings
350 .insert_layer_button_binding(GameInput::Block, settings.game_layer_buttons.block);
351 controller_settings
352 .insert_layer_button_binding(GameInput::Slot1, settings.game_layer_buttons.slot1);
353 controller_settings
354 .insert_layer_button_binding(GameInput::Slot2, settings.game_layer_buttons.slot2);
355 controller_settings
356 .insert_layer_button_binding(GameInput::Slot3, settings.game_layer_buttons.slot3);
357 controller_settings
358 .insert_layer_button_binding(GameInput::Slot4, settings.game_layer_buttons.slot4);
359 controller_settings
360 .insert_layer_button_binding(GameInput::Slot5, settings.game_layer_buttons.slot5);
361 controller_settings
362 .insert_layer_button_binding(GameInput::Slot6, settings.game_layer_buttons.slot6);
363 controller_settings
364 .insert_layer_button_binding(GameInput::Slot7, settings.game_layer_buttons.slot7);
365 controller_settings
366 .insert_layer_button_binding(GameInput::Slot8, settings.game_layer_buttons.slot8);
367 controller_settings
368 .insert_layer_button_binding(GameInput::Slot9, settings.game_layer_buttons.slot9);
369 controller_settings
370 .insert_layer_button_binding(GameInput::Slot10, settings.game_layer_buttons.slot10);
371 controller_settings.insert_layer_button_binding(
372 GameInput::ToggleCursor,
373 settings.game_layer_buttons.toggle_cursor,
374 );
375 controller_settings
376 .insert_layer_button_binding(GameInput::Escape, settings.game_layer_buttons.escape);
377 controller_settings
378 .insert_layer_button_binding(GameInput::Chat, settings.game_layer_buttons.enter);
379 controller_settings
380 .insert_layer_button_binding(GameInput::Command, settings.game_layer_buttons.command);
381 controller_settings.insert_layer_button_binding(
382 GameInput::MoveForward,
383 settings.game_layer_buttons.move_forward,
384 );
385 controller_settings.insert_layer_button_binding(
386 GameInput::MoveLeft,
387 settings.game_layer_buttons.move_left,
388 );
389 controller_settings.insert_layer_button_binding(
390 GameInput::MoveBack,
391 settings.game_layer_buttons.move_back,
392 );
393 controller_settings.insert_layer_button_binding(
394 GameInput::MoveRight,
395 settings.game_layer_buttons.move_right,
396 );
397 controller_settings
398 .insert_layer_button_binding(GameInput::Jump, settings.game_layer_buttons.jump);
399 controller_settings
400 .insert_layer_button_binding(GameInput::Sit, settings.game_layer_buttons.sit);
401 controller_settings
402 .insert_layer_button_binding(GameInput::Dance, settings.game_layer_buttons.dance);
403 controller_settings
404 .insert_layer_button_binding(GameInput::Glide, settings.game_layer_buttons.glide);
405 controller_settings
406 .insert_layer_button_binding(GameInput::SwimUp, settings.game_layer_buttons.swimup);
407 controller_settings
408 .insert_layer_button_binding(GameInput::SwimDown, settings.game_layer_buttons.swimdown);
409 controller_settings
410 .insert_layer_button_binding(GameInput::Sneak, settings.game_layer_buttons.sneak);
411 controller_settings.insert_layer_button_binding(
412 GameInput::ToggleLantern,
413 settings.game_layer_buttons.toggle_lantern,
414 );
415 controller_settings
416 .insert_layer_button_binding(GameInput::Mount, settings.game_layer_buttons.mount);
417 controller_settings
418 .insert_layer_button_binding(GameInput::Map, settings.game_layer_buttons.map);
419 controller_settings
420 .insert_layer_button_binding(GameInput::Inventory, settings.game_layer_buttons.bag);
421 controller_settings
422 .insert_layer_button_binding(GameInput::Social, settings.game_layer_buttons.social);
423 controller_settings
424 .insert_layer_button_binding(GameInput::Crafting, settings.game_layer_buttons.crafting);
425 controller_settings
426 .insert_layer_button_binding(GameInput::Diary, settings.game_layer_buttons.diary);
427 controller_settings
428 .insert_layer_button_binding(GameInput::Settings, settings.game_layer_buttons.settings);
429 controller_settings
430 .insert_layer_button_binding(GameInput::Controls, settings.game_layer_buttons.controls);
431 controller_settings.insert_layer_button_binding(
432 GameInput::ToggleInterface,
433 settings.game_layer_buttons.toggle_interface,
434 );
435 controller_settings.insert_layer_button_binding(
436 GameInput::ToggleDebug,
437 settings.game_layer_buttons.toggle_debug,
438 );
439 #[cfg(feature = "egui-ui")]
440 controller_settings.insert_layer_button_binding(
441 GameInput::ToggleEguiDebug,
442 settings.game_layer_buttons.toggle_debug,
443 );
444 controller_settings.insert_layer_button_binding(
445 GameInput::ToggleChat,
446 settings.game_layer_buttons.toggle_chat,
447 );
448 controller_settings.insert_layer_button_binding(
449 GameInput::Fullscreen,
450 settings.game_layer_buttons.fullscreen,
451 );
452 controller_settings.insert_layer_button_binding(
453 GameInput::Screenshot,
454 settings.game_layer_buttons.screenshot,
455 );
456 controller_settings.insert_layer_button_binding(
457 GameInput::ToggleIngameUi,
458 settings.game_layer_buttons.toggle_ingame_ui,
459 );
460 controller_settings
461 .insert_layer_button_binding(GameInput::Roll, settings.game_layer_buttons.roll);
462 controller_settings
463 .insert_layer_button_binding(GameInput::Respawn, settings.game_layer_buttons.respawn);
464 controller_settings
465 .insert_layer_button_binding(GameInput::Interact, settings.game_layer_buttons.interact);
466 controller_settings.insert_layer_button_binding(
467 GameInput::ToggleWield,
468 settings.game_layer_buttons.toggle_wield,
469 );
470 controller_settings.insert_layer_button_binding(
471 GameInput::SwapLoadout,
472 settings.game_layer_buttons.swap_loadout,
473 );
474
475 controller_settings.modifier_buttons = vec![
476 Button::Simple(GilButton::RightTrigger),
477 Button::Simple(GilButton::LeftTrigger),
478 ];
479 controller_settings.pan_sensitivity = settings.pan_sensitivity;
480 controller_settings.pan_invert_y = settings.pan_invert_y;
481 controller_settings
482 .axis_deadzones
483 .clone_from(&settings.axis_deadzones);
484 controller_settings
485 .button_deadzones
486 .clone_from(&settings.button_deadzones);
487 controller_settings.mouse_emulation_sensitivity = settings.mouse_emulation_sensitivity;
488 controller_settings
489 .inverted_axes
490 .clone_from(&settings.inverted_axes);
491
492 controller_settings
493 }
494}
495
496#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Deserialize, Serialize)]
498pub enum AxisMenuAction {
499 MoveX,
500 MoveY,
501 ScrollX,
502 ScrollY,
503}
504
505#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Deserialize, Serialize)]
507pub enum AxisGameAction {
508 MovementX,
509 MovementY,
510 CameraX,
511 CameraY,
512}
513
514#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Deserialize, Serialize)]
516pub enum AnalogButtonMenuAction {}
517
518#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Deserialize, Serialize)]
520pub enum AnalogButtonGameAction {}
521
522#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Deserialize, Serialize)]
525pub enum Button {
526 Simple(GilButton),
527 EventCode(u32),
528}
529
530impl Default for Button {
531 fn default() -> Self { Button::Simple(GilButton::Unknown) }
532}
533
534impl Button {
535 pub fn display_string(&self, localized_strings: &Localization) -> String {
537 use self::Button::*;
538 let button_string = match self {
540 Simple(GilButton::South) => localized_strings.get_msg("gamepad-south").to_string(),
541 Simple(GilButton::East) => localized_strings.get_msg("gamepad-east").to_string(),
542 Simple(GilButton::North) => localized_strings.get_msg("gamepad-north").to_string(),
543 Simple(GilButton::West) => localized_strings.get_msg("gamepad-west").to_string(),
544 Simple(GilButton::C) => localized_strings.get_msg("gamepad-c").to_string(),
545 Simple(GilButton::Z) => localized_strings.get_msg("gamepad-z").to_string(),
546 Simple(GilButton::LeftTrigger) => localized_strings
547 .get_msg("gamepad-left_trigger")
548 .to_string(),
549 Simple(GilButton::LeftTrigger2) => localized_strings
550 .get_msg("gamepad-left_trigger_2")
551 .to_string(),
552 Simple(GilButton::RightTrigger) => localized_strings
553 .get_msg("gamepad-right_trigger")
554 .to_string(),
555 Simple(GilButton::RightTrigger2) => localized_strings
556 .get_msg("gamepad-right_trigger_2")
557 .to_string(),
558 Simple(GilButton::Select) => localized_strings.get_msg("gamepad-select").to_string(),
559 Simple(GilButton::Start) => localized_strings.get_msg("gamepad-start").to_string(),
560 Simple(GilButton::Mode) => localized_strings.get_msg("gamepad-mode").to_string(),
561 Simple(GilButton::LeftThumb) => {
562 localized_strings.get_msg("gamepad-left_thumb").to_string()
563 },
564 Simple(GilButton::RightThumb) => {
565 localized_strings.get_msg("gamepad-right_thumb").to_string()
566 },
567 Simple(GilButton::DPadUp) => localized_strings.get_msg("gamepad-dpad_up").to_string(),
568 Simple(GilButton::DPadDown) => {
569 localized_strings.get_msg("gamepad-dpad_down").to_string()
570 },
571 Simple(GilButton::DPadLeft) => {
572 localized_strings.get_msg("gamepad-dpad_left").to_string()
573 },
574 Simple(GilButton::DPadRight) => {
575 localized_strings.get_msg("gamepad-dpad_right").to_string()
576 },
577 Simple(GilButton::Unknown) => localized_strings.get_msg("gamepad-unknown").to_string(),
578 EventCode(code) => code.to_string(),
579 };
580
581 button_string.to_owned()
582 }
583
584 pub fn try_shortened(&self) -> Option<String> {
587 use self::Button::*;
588 let button_string = match self {
589 Simple(GilButton::South) => "A",
590 Simple(GilButton::East) => "B",
591 Simple(GilButton::North) => "Y",
592 Simple(GilButton::West) => "X",
593 Simple(GilButton::LeftTrigger) => "LB",
594 Simple(GilButton::LeftTrigger2) => "LT",
595 Simple(GilButton::RightTrigger) => "RB",
596 Simple(GilButton::RightTrigger2) => "RT",
597 Simple(GilButton::LeftThumb) => "L3",
598 Simple(GilButton::RightThumb) => "R3",
599 _ => return None,
600 };
601
602 Some(button_string.to_owned())
603 }
604}
605
606#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Deserialize, Serialize)]
609pub enum AnalogButton {
610 Simple(GilButton),
611 EventCode(u32),
612}
613
614impl Default for AnalogButton {
615 fn default() -> Self { AnalogButton::Simple(GilButton::Unknown) }
616}
617
618#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Deserialize, Serialize)]
621pub enum Axis {
622 Simple(GilAxis),
623 EventCode(u32),
624}
625
626impl Default for Axis {
627 fn default() -> Self { Axis::Simple(GilAxis::Unknown) }
628}
629
630impl From<(GilAxis, GilCode)> for Axis {
631 fn from((axis, code): (GilAxis, GilCode)) -> Self {
632 match axis {
633 GilAxis::Unknown => Self::EventCode(code.into_u32()),
634 _ => Self::Simple(axis),
635 }
636 }
637}
638
639impl From<(GilButton, GilCode)> for Button {
640 fn from((button, code): (GilButton, GilCode)) -> Self {
641 match button {
642 GilButton::Unknown => Self::EventCode(code.into_u32()),
643 _ => Self::Simple(button),
644 }
645 }
646}
647
648impl From<(GilButton, GilCode)> for AnalogButton {
649 fn from((button, code): (GilButton, GilCode)) -> Self {
650 match button {
651 GilButton::Unknown => Self::EventCode(code.into_u32()),
652 _ => Self::Simple(button),
653 }
654 }
655}