1use crate::{game_input::GameInput, window::MenuInput};
2use gilrs::{Axis as GilAxis, Button as GilButton, ev::Code as GilCode};
3use hashbrown::{HashMap, HashSet};
4use i18n::Localization;
5use serde::{Deserialize, Serialize};
6use strum::{EnumIter, IntoEnumIterator};
7
8#[derive(Serialize, Deserialize)]
9#[serde(default)]
10struct ControllerSettingsSerde {
11 game_button_map: HashMap<GameInput, Option<Button>>,
13 menu_button_map: HashMap<MenuInput, Option<Button>>,
14 game_analog_button_map: HashMap<AnalogButtonGameAction, AnalogButton>,
15 menu_analog_button_map: HashMap<AnalogButtonMenuAction, AnalogButton>,
16 game_axis_map: HashMap<AxisGameAction, Axis>,
17 menu_axis_map: HashMap<AxisMenuAction, Axis>,
18 layer_button_map: HashMap<GameInput, Option<LayerEntry>>,
19 modifier_buttons: Vec<Button>,
20
21 pan_sensitivity: u32,
22 pan_invert_y: bool,
23 axis_deadzones: HashMap<Axis, f32>,
24 button_deadzones: HashMap<AnalogButton, f32>,
25 mouse_emulation_sensitivity: u32,
26 inverted_axes: Vec<Axis>,
27}
28
29impl From<ControllerSettings> for ControllerSettingsSerde {
30 fn from(controller_settings: ControllerSettings) -> Self {
31 let mut button_bindings: HashMap<GameInput, Option<Button>> = HashMap::new();
36 for (k, v) in controller_settings.game_button_map {
37 if ControllerSettings::default_button_binding(k) != v {
38 button_bindings.insert(k, v);
39 }
40 }
41
42 let mut layer_bindings: HashMap<GameInput, Option<LayerEntry>> = HashMap::new();
44 for (k, v) in controller_settings.layer_button_map {
45 if ControllerSettings::default_layer_binding(k) != v {
46 layer_bindings.insert(k, v);
47 }
48 }
49
50 let mut menu_bindings: HashMap<MenuInput, Option<Button>> = HashMap::new();
52 for (k, v) in controller_settings.menu_button_map {
53 if ControllerSettings::default_menu_button_binding(k) != v {
54 menu_bindings.insert(k, v);
55 }
56 }
57
58 let modifier_buttons = controller_settings.modifier_buttons;
60 let pan_sensitivity = controller_settings.pan_sensitivity;
61 let pan_invert_y = controller_settings.pan_invert_y;
62 let axis_deadzones = controller_settings.axis_deadzones;
63
64 let mouse_emulation_sensitivity = controller_settings.mouse_emulation_sensitivity;
65 let inverted_axes = controller_settings.inverted_axes;
66
67 ControllerSettingsSerde {
68 game_button_map: button_bindings,
69 menu_button_map: menu_bindings,
70 game_analog_button_map: HashMap::new(),
71 menu_analog_button_map: HashMap::new(),
72 game_axis_map: HashMap::new(),
73 menu_axis_map: HashMap::new(),
74 layer_button_map: layer_bindings,
75
76 modifier_buttons,
77 pan_sensitivity,
78 pan_invert_y,
79 axis_deadzones,
80
81 button_deadzones: HashMap::new(),
82 mouse_emulation_sensitivity,
83 inverted_axes,
84 }
85 }
86}
87
88impl Default for ControllerSettingsSerde {
89 fn default() -> Self { ControllerSettings::default().into() }
90}
91
92#[derive(Clone, Debug, Serialize, Deserialize)]
94#[serde(from = "ControllerSettingsSerde", into = "ControllerSettingsSerde")]
95pub struct ControllerSettings {
96 pub game_button_map: HashMap<GameInput, Option<Button>>,
97 pub inverse_game_button_map: HashMap<Button, HashSet<GameInput>>,
98 pub menu_button_map: HashMap<MenuInput, Option<Button>>,
99 pub inverse_menu_button_map: HashMap<Button, HashSet<MenuInput>>,
100 pub game_analog_button_map: HashMap<AnalogButtonGameAction, AnalogButton>,
101 pub inverse_game_analog_button_map: HashMap<AnalogButton, HashSet<AnalogButtonGameAction>>,
102 pub menu_analog_button_map: HashMap<AnalogButtonMenuAction, AnalogButton>,
103 pub inverse_menu_analog_button_map: HashMap<AnalogButton, HashSet<AnalogButtonMenuAction>>,
104 pub game_axis_map: HashMap<AxisGameAction, Axis>,
105 pub inverse_game_axis_map: HashMap<Axis, HashSet<AxisGameAction>>,
106 pub menu_axis_map: HashMap<AxisMenuAction, Axis>,
107 pub inverse_menu_axis_map: HashMap<Axis, HashSet<AxisMenuAction>>,
108 pub layer_button_map: HashMap<GameInput, Option<LayerEntry>>,
109 pub inverse_layer_button_map: HashMap<LayerEntry, HashSet<GameInput>>,
110
111 pub modifier_buttons: Vec<Button>,
112 pub pan_sensitivity: u32,
113 pub pan_invert_y: bool,
114 pub axis_deadzones: HashMap<Axis, f32>,
115 pub button_deadzones: HashMap<AnalogButton, f32>,
116 pub mouse_emulation_sensitivity: u32,
117 pub inverted_axes: Vec<Axis>,
118}
119
120impl From<ControllerSettingsSerde> for ControllerSettings {
121 fn from(controller_serde: ControllerSettingsSerde) -> Self {
122 let button_bindings = controller_serde.game_button_map;
123 let layer_bindings = controller_serde.layer_button_map;
124 let menu_bindings = controller_serde.menu_button_map;
125 let mut controller_settings = ControllerSettings::default();
126 for (k, maybe_v) in button_bindings {
128 match maybe_v {
129 Some(v) => controller_settings.modify_button_binding(k, v),
130 None => controller_settings.remove_button_binding(k),
131 }
132 }
133 for (k, maybe_v) in layer_bindings {
135 match maybe_v {
136 Some(v) => controller_settings.modify_layer_binding(k, v),
137 None => controller_settings.remove_layer_binding(k),
138 }
139 }
140 for (k, maybe_v) in menu_bindings {
142 match maybe_v {
143 Some(v) => controller_settings.modify_menu_binding(k, v),
144 None => controller_settings.remove_menu_binding(k),
145 }
146 }
147 controller_settings
148 }
149}
150
151impl ControllerSettings {
152 pub fn apply_axis_deadzone(&self, k: &Axis, input: f32) -> f32 {
153 let threshold = *self.axis_deadzones.get(k).unwrap_or(&0.2);
154
155 let input_abs = input.abs();
158 if input_abs <= threshold || threshold >= 1.0 {
159 0.0
160 } else if threshold <= 0.0 {
161 input
162 } else {
163 (input_abs - threshold) / (1.0 - threshold) * input.signum()
164 }
165 }
166
167 pub fn apply_button_deadzone(&self, k: &AnalogButton, input: f32) -> f32 {
168 let threshold = *self.button_deadzones.get(k).unwrap_or(&0.2);
169
170 if input <= threshold || threshold >= 1.0 {
173 0.0
174 } else if threshold <= 0.0 {
175 input
176 } else {
177 (input - threshold) / (1.0 - threshold)
178 }
179 }
180
181 pub fn remove_button_binding(&mut self, game_input: GameInput) {
182 if let Some(inverse) = self
183 .game_button_map
184 .insert(game_input, None)
185 .flatten()
186 .and_then(|button| self.inverse_game_button_map.get_mut(&button))
187 {
188 inverse.remove(&game_input);
189 }
190 }
191
192 pub fn remove_layer_binding(&mut self, layer_input: GameInput) {
193 if let Some(inverse) = self
194 .layer_button_map
195 .insert(layer_input, None)
196 .flatten()
197 .and_then(|button| self.inverse_layer_button_map.get_mut(&button))
198 {
199 inverse.remove(&layer_input);
200 }
201 }
202
203 pub fn remove_menu_binding(&mut self, menu_input: MenuInput) {
204 if let Some(inverse) = self
205 .menu_button_map
206 .insert(menu_input, None)
207 .flatten()
208 .and_then(|button| self.inverse_menu_button_map.get_mut(&button))
209 {
210 inverse.remove(&menu_input);
211 }
212 }
213
214 pub fn get_associated_game_button_inputs(
215 &self,
216 button: &Button,
217 ) -> Option<&HashSet<GameInput>> {
218 self.inverse_game_button_map.get(button)
219 }
220
221 pub fn get_associated_game_layer_inputs(
222 &self,
223 layers: &LayerEntry,
224 ) -> Option<&HashSet<GameInput>> {
225 self.inverse_layer_button_map.get(layers)
226 }
227
228 pub fn get_associated_game_menu_inputs(&self, button: &Button) -> Option<&HashSet<MenuInput>> {
229 self.inverse_menu_button_map.get(button)
230 }
231
232 pub fn get_game_button_binding(&self, input: GameInput) -> Option<Button> {
233 self.game_button_map.get(&input).cloned().flatten()
234 }
235
236 pub fn get_menu_button_binding(&self, input: MenuInput) -> Option<Button> {
237 self.menu_button_map.get(&input).cloned().flatten()
238 }
239
240 pub fn get_layer_button_binding(&self, input: GameInput) -> Option<LayerEntry> {
241 self.layer_button_map.get(&input).cloned().flatten()
242 }
243
244 pub fn insert_game_button_binding(&mut self, game_input: GameInput, game_button: Button) {
245 if game_button != Button::default() {
246 self.game_button_map.insert(game_input, Some(game_button));
247 self.inverse_game_button_map
248 .entry(game_button)
249 .or_default()
250 .insert(game_input);
251 }
252 }
253
254 pub fn insert_menu_button_binding(&mut self, menu_input: MenuInput, button: Button) {
255 if button != Button::default() {
256 self.menu_button_map.insert(menu_input, Some(button));
257 self.inverse_menu_button_map
258 .entry(button)
259 .or_default()
260 .insert(menu_input);
261 }
262 }
263
264 pub fn insert_game_axis_binding(&mut self, input: AxisGameAction, axis: Axis) {
265 if axis != Axis::default() {
266 self.game_axis_map.insert(input, axis);
267 self.inverse_game_axis_map
268 .entry(axis)
269 .or_default()
270 .insert(input);
271 }
272 }
273
274 pub fn insert_menu_axis_binding(&mut self, input: AxisMenuAction, axis: Axis) {
275 if axis != Axis::default() {
276 self.menu_axis_map.insert(input, axis);
277 self.inverse_menu_axis_map
278 .entry(axis)
279 .or_default()
280 .insert(input);
281 }
282 }
283
284 pub fn insert_layer_button_binding(&mut self, input: GameInput, layer_entry: LayerEntry) {
285 if layer_entry != LayerEntry::default() {
286 self.layer_button_map.insert(input, Some(layer_entry));
287 self.inverse_layer_button_map
288 .entry(layer_entry)
289 .or_default()
290 .insert(input);
291 }
292 }
293
294 pub fn modify_button_binding(&mut self, game_input: GameInput, button: Button) {
295 if let Some(old_binding) = self.get_game_button_binding(game_input) {
298 self.inverse_game_button_map
299 .entry(old_binding)
300 .or_default()
301 .remove(&game_input);
302 }
303 self.inverse_game_button_map
305 .entry(button)
306 .or_default()
307 .insert(game_input);
308 self.game_button_map.insert(game_input, Some(button));
310 }
311
312 pub fn modify_layer_binding(&mut self, game_input: GameInput, layers: LayerEntry) {
313 if let Some(old_binding) = self.get_layer_button_binding(game_input) {
316 self.inverse_layer_button_map
317 .entry(old_binding)
318 .or_default()
319 .remove(&game_input);
320 }
321 self.inverse_layer_button_map
323 .entry(layers)
324 .or_default()
325 .insert(game_input);
326 self.layer_button_map.insert(game_input, Some(layers));
328 }
329
330 pub fn modify_menu_binding(&mut self, menu_input: MenuInput, button: Button) {
331 if let Some(old_binding) = self.get_menu_button_binding(menu_input) {
334 self.inverse_menu_button_map
335 .entry(old_binding)
336 .or_default()
337 .remove(&menu_input);
338 }
339 self.inverse_menu_button_map
341 .entry(button)
342 .or_default()
343 .insert(menu_input);
344 self.menu_button_map.insert(menu_input, Some(button));
346 }
347
348 pub fn game_button_has_conflicting_bindings(&self, game_button: Button) -> bool {
351 if let Some(game_inputs) = self.inverse_game_button_map.get(&game_button) {
352 for a in game_inputs.iter() {
353 for b in game_inputs.iter() {
354 if !GameInput::can_share_bindings(*a, *b) {
355 return true;
356 }
357 }
358 }
359
360 let layer_entry = LayerEntry {
361 button: game_button,
362 mod1: Button::Simple(GilButton::Unknown),
363 mod2: Button::Simple(GilButton::Unknown),
364 };
365 if let Some(layer_inputs) = self.inverse_layer_button_map.get(&layer_entry) {
366 for a in game_inputs.iter() {
367 for b in layer_inputs.iter() {
368 if !GameInput::can_share_bindings(*a, *b) {
369 return true;
370 }
371 }
372 }
373 }
374 }
375 false
376 }
377
378 pub fn menu_button_has_conflicting_bindings(&self, menu_button: Button) -> bool {
379 self.inverse_menu_button_map
380 .get(&menu_button)
381 .is_some_and(|menu_inputs| menu_inputs.len() > 1)
382 }
383
384 pub fn layer_entry_has_conflicting_bindings(&self, layer_entry: LayerEntry) -> bool {
387 if let Some(layer_inputs) = self.inverse_layer_button_map.get(&layer_entry) {
388 for a in layer_inputs.iter() {
389 for b in layer_inputs.iter() {
390 if !GameInput::can_share_bindings(*a, *b) {
391 return true;
392 }
393 }
394 }
395
396 if layer_entry.mod1 == Button::Simple(GilButton::Unknown)
397 && layer_entry.mod2 == Button::Simple(GilButton::Unknown)
398 && let Some(game_inputs) = self.inverse_game_button_map.get(&layer_entry.button)
399 {
400 for a in layer_inputs.iter() {
401 for b in game_inputs.iter() {
402 if !GameInput::can_share_bindings(*a, *b) {
403 return true;
404 }
405 }
406 }
407 }
408 }
409 false
410 }
411
412 pub fn default_game_axis(game_axis: AxisGameAction) -> Option<Axis> {
413 match game_axis {
414 AxisGameAction::MovementX => Some(Axis::Simple(GilAxis::LeftStickX)),
415 AxisGameAction::MovementY => Some(Axis::Simple(GilAxis::LeftStickY)),
416 AxisGameAction::CameraX => Some(Axis::Simple(GilAxis::RightStickX)),
417 AxisGameAction::CameraY => Some(Axis::Simple(GilAxis::RightStickY)),
418 }
419 }
420
421 pub fn default_menu_axis(menu_axis: AxisMenuAction) -> Option<Axis> {
422 match menu_axis {
423 AxisMenuAction::MoveX => Some(Axis::Simple(GilAxis::LeftStickX)),
424 AxisMenuAction::MoveY => Some(Axis::Simple(GilAxis::LeftStickY)),
425 AxisMenuAction::ScrollX => Some(Axis::Simple(GilAxis::RightStickX)),
426 AxisMenuAction::ScrollY => Some(Axis::Simple(GilAxis::RightStickY)),
427 }
428 }
429
430 pub fn default_button_binding(game_input: GameInput) -> Option<Button> {
431 match game_input {
432 GameInput::Primary => Some(Button::Simple(GilButton::RightTrigger2)),
433 GameInput::Secondary => Some(Button::Simple(GilButton::LeftTrigger2)),
434 GameInput::Block => Some(Button::Simple(GilButton::LeftTrigger)),
435 GameInput::Slot1 => Some(Button::Simple(GilButton::Unknown)),
436 GameInput::Slot2 => Some(Button::Simple(GilButton::Unknown)),
437 GameInput::Slot3 => Some(Button::Simple(GilButton::Unknown)),
438 GameInput::Slot4 => Some(Button::Simple(GilButton::Unknown)),
439 GameInput::Slot5 => Some(Button::Simple(GilButton::Unknown)),
440 GameInput::Slot6 => Some(Button::Simple(GilButton::Unknown)),
441 GameInput::Slot7 => Some(Button::Simple(GilButton::Unknown)),
442 GameInput::Slot8 => Some(Button::Simple(GilButton::Unknown)),
443 GameInput::Slot9 => Some(Button::Simple(GilButton::Unknown)),
444 GameInput::Slot10 => Some(Button::Simple(GilButton::Unknown)),
445 GameInput::PreviousSlot => Some(Button::Simple(GilButton::Unknown)),
446 GameInput::NextSlot => Some(Button::Simple(GilButton::Unknown)),
447 GameInput::CurrentSlot => Some(Button::Simple(GilButton::North)),
448 GameInput::ToggleCursor => Some(Button::Simple(GilButton::Unknown)),
449 GameInput::MoveForward => Some(Button::Simple(GilButton::Unknown)),
450 GameInput::MoveBack => Some(Button::Simple(GilButton::Unknown)),
451 GameInput::MoveLeft => Some(Button::Simple(GilButton::Unknown)),
452 GameInput::MoveRight => Some(Button::Simple(GilButton::Unknown)),
453 GameInput::Jump => Some(Button::Simple(GilButton::South)),
454 GameInput::WallJump => Some(Button::Simple(GilButton::South)),
455 GameInput::Sit => Some(Button::Simple(GilButton::Unknown)),
456 GameInput::Crawl => Some(Button::Simple(GilButton::Unknown)),
457 GameInput::Dance => Some(Button::Simple(GilButton::Unknown)),
458 GameInput::Greet => Some(Button::Simple(GilButton::Unknown)),
459 GameInput::Glide => Some(Button::Simple(GilButton::DPadUp)),
460 GameInput::SwimUp => Some(Button::Simple(GilButton::South)),
461 GameInput::SwimDown => Some(Button::Simple(GilButton::West)),
462 GameInput::Fly => Some(Button::Simple(GilButton::Unknown)),
463 GameInput::Sneak => Some(Button::Simple(GilButton::LeftThumb)),
464 GameInput::CancelClimb => Some(Button::Simple(GilButton::East)),
465 GameInput::ToggleLantern => Some(Button::Simple(GilButton::Unknown)),
466 GameInput::Mount => Some(Button::Simple(GilButton::South)),
467 GameInput::StayFollow => Some(Button::Simple(GilButton::Unknown)),
468 GameInput::Chat => Some(Button::Simple(GilButton::Unknown)),
469 GameInput::Command => Some(Button::Simple(GilButton::Unknown)),
470 GameInput::Escape => Some(Button::Simple(GilButton::Start)),
471 GameInput::Map => Some(Button::Simple(GilButton::Select)),
472 GameInput::Inventory => Some(Button::Simple(GilButton::DPadRight)),
473 GameInput::Trade => Some(Button::Simple(GilButton::Unknown)),
474 GameInput::Social => Some(Button::Simple(GilButton::DPadLeft)),
475 GameInput::Crafting => Some(Button::Simple(GilButton::Unknown)),
476 GameInput::Diary => Some(Button::Simple(GilButton::Unknown)),
477 GameInput::Settings => Some(Button::Simple(GilButton::Unknown)),
478 GameInput::Controls => Some(Button::Simple(GilButton::Unknown)),
479 GameInput::ToggleInterface => Some(Button::Simple(GilButton::Unknown)),
480 GameInput::ToggleDebug => Some(Button::Simple(GilButton::Unknown)),
481 #[cfg(feature = "egui-ui")]
482 GameInput::ToggleEguiDebug => Some(Button::Simple(GilButton::Unknown)),
483 GameInput::ToggleChat => Some(Button::Simple(GilButton::Unknown)),
484 GameInput::Fullscreen => Some(Button::Simple(GilButton::Unknown)),
485 GameInput::Screenshot => Some(Button::Simple(GilButton::Unknown)),
486 GameInput::ToggleIngameUi => Some(Button::Simple(GilButton::Unknown)),
487 GameInput::Roll => Some(Button::Simple(GilButton::RightThumb)),
488 GameInput::GiveUp => Some(Button::Simple(GilButton::South)),
489 GameInput::Respawn => Some(Button::Simple(GilButton::South)),
490 GameInput::Interact => Some(Button::Simple(GilButton::West)),
491 GameInput::ToggleWield => Some(Button::Simple(GilButton::East)),
492 GameInput::SwapLoadout => Some(Button::Simple(GilButton::DPadDown)),
493 GameInput::FreeLook => Some(Button::Simple(GilButton::Unknown)),
494 GameInput::AutoWalk => Some(Button::Simple(GilButton::Unknown)),
495 GameInput::ZoomIn => Some(Button::Simple(GilButton::Unknown)),
496 GameInput::ZoomOut => Some(Button::Simple(GilButton::Unknown)),
497 GameInput::ZoomLock => Some(Button::Simple(GilButton::Unknown)),
498 GameInput::CameraClamp => Some(Button::Simple(GilButton::Unknown)),
499 GameInput::CycleCamera => Some(Button::Simple(GilButton::Unknown)),
500 GameInput::Select => Some(Button::Simple(GilButton::Unknown)),
501 GameInput::AcceptGroupInvite => Some(Button::Simple(GilButton::Unknown)),
502 GameInput::DeclineGroupInvite => Some(Button::Simple(GilButton::Unknown)),
503 GameInput::MapZoomIn => Some(Button::Simple(GilButton::Unknown)),
504 GameInput::MapZoomOut => Some(Button::Simple(GilButton::Unknown)),
505 GameInput::MapSetMarker => Some(Button::Simple(GilButton::Unknown)),
506 GameInput::SpectateSpeedBoost => Some(Button::Simple(GilButton::Unknown)),
507 GameInput::SpectateViewpoint => Some(Button::Simple(GilButton::Unknown)),
508 GameInput::MuteMaster => Some(Button::Simple(GilButton::Unknown)),
509 GameInput::MuteInactiveMaster => Some(Button::Simple(GilButton::Unknown)),
510 GameInput::MuteMusic => Some(Button::Simple(GilButton::Unknown)),
511 GameInput::MuteSfx => Some(Button::Simple(GilButton::Unknown)),
512 GameInput::MuteAmbience => Some(Button::Simple(GilButton::Unknown)),
513 GameInput::ToggleWalk => Some(Button::Simple(GilButton::Unknown)),
514 }
515 }
516
517 pub fn default_layer_binding(layer_input: GameInput) -> Option<LayerEntry> {
518 match layer_input {
519 GameInput::Primary => Some(LayerEntry {
520 button: Button::Simple(GilButton::Unknown),
521 mod1: Button::Simple(GilButton::Unknown),
522 mod2: Button::Simple(GilButton::Unknown),
523 }),
524 GameInput::Secondary => Some(LayerEntry {
525 button: Button::Simple(GilButton::Unknown),
526 mod1: Button::Simple(GilButton::Unknown),
527 mod2: Button::Simple(GilButton::Unknown),
528 }),
529 GameInput::Block => Some(LayerEntry {
530 button: Button::Simple(GilButton::Unknown),
531 mod1: Button::Simple(GilButton::Unknown),
532 mod2: Button::Simple(GilButton::Unknown),
533 }),
534 GameInput::Slot1 => Some(LayerEntry {
535 button: Button::Simple(GilButton::Unknown),
536 mod1: Button::Simple(GilButton::Unknown),
537 mod2: Button::Simple(GilButton::Unknown),
538 }),
539 GameInput::Slot2 => Some(LayerEntry {
540 button: Button::Simple(GilButton::Unknown),
541 mod1: Button::Simple(GilButton::Unknown),
542 mod2: Button::Simple(GilButton::Unknown),
543 }),
544 GameInput::Slot3 => Some(LayerEntry {
545 button: Button::Simple(GilButton::Unknown),
546 mod1: Button::Simple(GilButton::Unknown),
547 mod2: Button::Simple(GilButton::Unknown),
548 }),
549 GameInput::Slot4 => Some(LayerEntry {
550 button: Button::Simple(GilButton::Unknown),
551 mod1: Button::Simple(GilButton::Unknown),
552 mod2: Button::Simple(GilButton::Unknown),
553 }),
554 GameInput::Slot5 => Some(LayerEntry {
555 button: Button::Simple(GilButton::Unknown),
556 mod1: Button::Simple(GilButton::Unknown),
557 mod2: Button::Simple(GilButton::Unknown),
558 }),
559 GameInput::Slot6 => Some(LayerEntry {
560 button: Button::Simple(GilButton::Unknown),
561 mod1: Button::Simple(GilButton::Unknown),
562 mod2: Button::Simple(GilButton::Unknown),
563 }),
564 GameInput::Slot7 => Some(LayerEntry {
565 button: Button::Simple(GilButton::Unknown),
566 mod1: Button::Simple(GilButton::Unknown),
567 mod2: Button::Simple(GilButton::Unknown),
568 }),
569 GameInput::Slot8 => Some(LayerEntry {
570 button: Button::Simple(GilButton::Unknown),
571 mod1: Button::Simple(GilButton::Unknown),
572 mod2: Button::Simple(GilButton::Unknown),
573 }),
574 GameInput::Slot9 => Some(LayerEntry {
575 button: Button::Simple(GilButton::Unknown),
576 mod1: Button::Simple(GilButton::Unknown),
577 mod2: Button::Simple(GilButton::Unknown),
578 }),
579 GameInput::Slot10 => Some(LayerEntry {
580 button: Button::Simple(GilButton::Unknown),
581 mod1: Button::Simple(GilButton::Unknown),
582 mod2: Button::Simple(GilButton::Unknown),
583 }),
584 GameInput::PreviousSlot => Some(LayerEntry {
585 button: Button::Simple(GilButton::West),
586 mod1: Button::Simple(GilButton::RightTrigger),
587 mod2: Button::Simple(GilButton::Unknown),
588 }),
589 GameInput::NextSlot => Some(LayerEntry {
590 button: Button::Simple(GilButton::East),
591 mod1: Button::Simple(GilButton::RightTrigger),
592 mod2: Button::Simple(GilButton::Unknown),
593 }),
594 GameInput::CurrentSlot => Some(LayerEntry {
595 button: Button::Simple(GilButton::Unknown),
596 mod1: Button::Simple(GilButton::Unknown),
597 mod2: Button::Simple(GilButton::Unknown),
598 }),
599 GameInput::ToggleCursor => Some(LayerEntry {
600 button: Button::Simple(GilButton::Unknown),
601 mod1: Button::Simple(GilButton::Unknown),
602 mod2: Button::Simple(GilButton::Unknown),
603 }),
604 GameInput::MoveForward => Some(LayerEntry {
605 button: Button::Simple(GilButton::Unknown),
606 mod1: Button::Simple(GilButton::Unknown),
607 mod2: Button::Simple(GilButton::Unknown),
608 }),
609 GameInput::MoveBack => Some(LayerEntry {
610 button: Button::Simple(GilButton::Unknown),
611 mod1: Button::Simple(GilButton::Unknown),
612 mod2: Button::Simple(GilButton::Unknown),
613 }),
614 GameInput::MoveLeft => Some(LayerEntry {
615 button: Button::Simple(GilButton::Unknown),
616 mod1: Button::Simple(GilButton::Unknown),
617 mod2: Button::Simple(GilButton::Unknown),
618 }),
619 GameInput::MoveRight => Some(LayerEntry {
620 button: Button::Simple(GilButton::Unknown),
621 mod1: Button::Simple(GilButton::Unknown),
622 mod2: Button::Simple(GilButton::Unknown),
623 }),
624 GameInput::Jump => Some(LayerEntry {
625 button: Button::Simple(GilButton::Unknown),
626 mod1: Button::Simple(GilButton::Unknown),
627 mod2: Button::Simple(GilButton::Unknown),
628 }),
629 GameInput::WallJump => Some(LayerEntry {
630 button: Button::Simple(GilButton::Unknown),
631 mod1: Button::Simple(GilButton::Unknown),
632 mod2: Button::Simple(GilButton::Unknown),
633 }),
634 GameInput::Sit => Some(LayerEntry {
635 button: Button::Simple(GilButton::DPadDown),
636 mod1: Button::Simple(GilButton::RightTrigger),
637 mod2: Button::Simple(GilButton::Unknown),
638 }),
639 GameInput::Crawl => Some(LayerEntry {
640 button: Button::Simple(GilButton::Unknown),
641 mod1: Button::Simple(GilButton::Unknown),
642 mod2: Button::Simple(GilButton::Unknown),
643 }),
644 GameInput::Dance => Some(LayerEntry {
645 button: Button::Simple(GilButton::Unknown),
646 mod1: Button::Simple(GilButton::Unknown),
647 mod2: Button::Simple(GilButton::Unknown),
648 }),
649 GameInput::Greet => Some(LayerEntry {
650 button: Button::Simple(GilButton::Unknown),
651 mod1: Button::Simple(GilButton::Unknown),
652 mod2: Button::Simple(GilButton::Unknown),
653 }),
654 GameInput::Glide => Some(LayerEntry {
655 button: Button::Simple(GilButton::Unknown),
656 mod1: Button::Simple(GilButton::Unknown),
657 mod2: Button::Simple(GilButton::Unknown),
658 }),
659 GameInput::SwimUp => Some(LayerEntry {
660 button: Button::Simple(GilButton::Unknown),
661 mod1: Button::Simple(GilButton::Unknown),
662 mod2: Button::Simple(GilButton::Unknown),
663 }),
664 GameInput::SwimDown => Some(LayerEntry {
665 button: Button::Simple(GilButton::Unknown),
666 mod1: Button::Simple(GilButton::Unknown),
667 mod2: Button::Simple(GilButton::Unknown),
668 }),
669 GameInput::Fly => Some(LayerEntry {
670 button: Button::Simple(GilButton::Unknown),
671 mod1: Button::Simple(GilButton::Unknown),
672 mod2: Button::Simple(GilButton::Unknown),
673 }),
674 GameInput::Sneak => Some(LayerEntry {
675 button: Button::Simple(GilButton::Unknown),
676 mod1: Button::Simple(GilButton::Unknown),
677 mod2: Button::Simple(GilButton::Unknown),
678 }),
679 GameInput::CancelClimb => Some(LayerEntry {
680 button: Button::Simple(GilButton::Unknown),
681 mod1: Button::Simple(GilButton::Unknown),
682 mod2: Button::Simple(GilButton::Unknown),
683 }),
684 GameInput::ToggleLantern => Some(LayerEntry {
685 button: Button::Simple(GilButton::DPadUp),
686 mod1: Button::Simple(GilButton::RightTrigger),
687 mod2: Button::Simple(GilButton::Unknown),
688 }),
689 GameInput::Mount => Some(LayerEntry {
690 button: Button::Simple(GilButton::Unknown),
691 mod1: Button::Simple(GilButton::Unknown),
692 mod2: Button::Simple(GilButton::Unknown),
693 }),
694 GameInput::StayFollow => Some(LayerEntry {
695 button: Button::Simple(GilButton::Unknown),
696 mod1: Button::Simple(GilButton::Unknown),
697 mod2: Button::Simple(GilButton::Unknown),
698 }),
699 GameInput::Chat => Some(LayerEntry {
700 button: Button::Simple(GilButton::Unknown),
701 mod1: Button::Simple(GilButton::Unknown),
702 mod2: Button::Simple(GilButton::Unknown),
703 }),
704 GameInput::Command => Some(LayerEntry {
705 button: Button::Simple(GilButton::Unknown),
706 mod1: Button::Simple(GilButton::Unknown),
707 mod2: Button::Simple(GilButton::Unknown),
708 }),
709 GameInput::Escape => Some(LayerEntry {
710 button: Button::Simple(GilButton::Unknown),
711 mod1: Button::Simple(GilButton::Unknown),
712 mod2: Button::Simple(GilButton::Unknown),
713 }),
714 GameInput::Map => Some(LayerEntry {
715 button: Button::Simple(GilButton::Unknown),
716 mod1: Button::Simple(GilButton::Unknown),
717 mod2: Button::Simple(GilButton::Unknown),
718 }),
719 GameInput::Inventory => Some(LayerEntry {
720 button: Button::Simple(GilButton::Unknown),
721 mod1: Button::Simple(GilButton::Unknown),
722 mod2: Button::Simple(GilButton::Unknown),
723 }),
724 GameInput::Trade => Some(LayerEntry {
725 button: Button::Simple(GilButton::North),
726 mod1: Button::Simple(GilButton::RightTrigger),
727 mod2: Button::Simple(GilButton::Unknown),
728 }),
729 GameInput::Social => Some(LayerEntry {
730 button: Button::Simple(GilButton::Unknown),
731 mod1: Button::Simple(GilButton::Unknown),
732 mod2: Button::Simple(GilButton::Unknown),
733 }),
734 GameInput::Crafting => Some(LayerEntry {
735 button: Button::Simple(GilButton::Unknown),
736 mod1: Button::Simple(GilButton::Unknown),
737 mod2: Button::Simple(GilButton::Unknown),
738 }),
739 GameInput::Diary => Some(LayerEntry {
740 button: Button::Simple(GilButton::Unknown),
741 mod1: Button::Simple(GilButton::Unknown),
742 mod2: Button::Simple(GilButton::Unknown),
743 }),
744 GameInput::Settings => Some(LayerEntry {
745 button: Button::Simple(GilButton::Unknown),
746 mod1: Button::Simple(GilButton::Unknown),
747 mod2: Button::Simple(GilButton::Unknown),
748 }),
749 GameInput::Controls => Some(LayerEntry {
750 button: Button::Simple(GilButton::Unknown),
751 mod1: Button::Simple(GilButton::Unknown),
752 mod2: Button::Simple(GilButton::Unknown),
753 }),
754 GameInput::ToggleInterface => Some(LayerEntry {
755 button: Button::Simple(GilButton::Unknown),
756 mod1: Button::Simple(GilButton::Unknown),
757 mod2: Button::Simple(GilButton::Unknown),
758 }),
759 GameInput::ToggleDebug => Some(LayerEntry {
760 button: Button::Simple(GilButton::Unknown),
761 mod1: Button::Simple(GilButton::Unknown),
762 mod2: Button::Simple(GilButton::Unknown),
763 }),
764 #[cfg(feature = "egui-ui")]
765 GameInput::ToggleEguiDebug => Some(LayerEntry {
766 button: Button::Simple(GilButton::Unknown),
767 mod1: Button::Simple(GilButton::Unknown),
768 mod2: Button::Simple(GilButton::Unknown),
769 }),
770 GameInput::ToggleChat => Some(LayerEntry {
771 button: Button::Simple(GilButton::Unknown),
772 mod1: Button::Simple(GilButton::Unknown),
773 mod2: Button::Simple(GilButton::Unknown),
774 }),
775 GameInput::Fullscreen => Some(LayerEntry {
776 button: Button::Simple(GilButton::Unknown),
777 mod1: Button::Simple(GilButton::Unknown),
778 mod2: Button::Simple(GilButton::Unknown),
779 }),
780 GameInput::Screenshot => Some(LayerEntry {
781 button: Button::Simple(GilButton::Unknown),
782 mod1: Button::Simple(GilButton::Unknown),
783 mod2: Button::Simple(GilButton::Unknown),
784 }),
785 GameInput::ToggleIngameUi => Some(LayerEntry {
786 button: Button::Simple(GilButton::Unknown),
787 mod1: Button::Simple(GilButton::Unknown),
788 mod2: Button::Simple(GilButton::Unknown),
789 }),
790 GameInput::Roll => Some(LayerEntry {
791 button: Button::Simple(GilButton::Unknown),
792 mod1: Button::Simple(GilButton::Unknown),
793 mod2: Button::Simple(GilButton::Unknown),
794 }),
795 GameInput::GiveUp => Some(LayerEntry {
796 button: Button::Simple(GilButton::Unknown),
797 mod1: Button::Simple(GilButton::Unknown),
798 mod2: Button::Simple(GilButton::Unknown),
799 }),
800 GameInput::Respawn => Some(LayerEntry {
801 button: Button::Simple(GilButton::Unknown),
802 mod1: Button::Simple(GilButton::Unknown),
803 mod2: Button::Simple(GilButton::Unknown),
804 }),
805 GameInput::Interact => Some(LayerEntry {
806 button: Button::Simple(GilButton::Unknown),
807 mod1: Button::Simple(GilButton::Unknown),
808 mod2: Button::Simple(GilButton::Unknown),
809 }),
810 GameInput::ToggleWield => Some(LayerEntry {
811 button: Button::Simple(GilButton::Unknown),
812 mod1: Button::Simple(GilButton::Unknown),
813 mod2: Button::Simple(GilButton::Unknown),
814 }),
815 GameInput::SwapLoadout => Some(LayerEntry {
816 button: Button::Simple(GilButton::Unknown),
817 mod1: Button::Simple(GilButton::Unknown),
818 mod2: Button::Simple(GilButton::Unknown),
819 }),
820 GameInput::FreeLook => Some(LayerEntry {
821 button: Button::Simple(GilButton::South),
822 mod1: Button::Simple(GilButton::RightTrigger),
823 mod2: Button::Simple(GilButton::Unknown),
824 }),
825 GameInput::AutoWalk => Some(LayerEntry {
826 button: Button::Simple(GilButton::Unknown),
827 mod1: Button::Simple(GilButton::Unknown),
828 mod2: Button::Simple(GilButton::Unknown),
829 }),
830 GameInput::ZoomIn => Some(LayerEntry {
831 button: Button::Simple(GilButton::Unknown),
832 mod1: Button::Simple(GilButton::Unknown),
833 mod2: Button::Simple(GilButton::Unknown),
834 }),
835 GameInput::ZoomOut => Some(LayerEntry {
836 button: Button::Simple(GilButton::Unknown),
837 mod1: Button::Simple(GilButton::Unknown),
838 mod2: Button::Simple(GilButton::Unknown),
839 }),
840 GameInput::ZoomLock => Some(LayerEntry {
841 button: Button::Simple(GilButton::Unknown),
842 mod1: Button::Simple(GilButton::Unknown),
843 mod2: Button::Simple(GilButton::Unknown),
844 }),
845 GameInput::CameraClamp => Some(LayerEntry {
846 button: Button::Simple(GilButton::Unknown),
847 mod1: Button::Simple(GilButton::Unknown),
848 mod2: Button::Simple(GilButton::Unknown),
849 }),
850 GameInput::CycleCamera => Some(LayerEntry {
851 button: Button::Simple(GilButton::Unknown),
852 mod1: Button::Simple(GilButton::Unknown),
853 mod2: Button::Simple(GilButton::Unknown),
854 }),
855 GameInput::Select => Some(LayerEntry {
856 button: Button::Simple(GilButton::Unknown),
857 mod1: Button::Simple(GilButton::Unknown),
858 mod2: Button::Simple(GilButton::Unknown),
859 }),
860 GameInput::AcceptGroupInvite => Some(LayerEntry {
861 button: Button::Simple(GilButton::DPadRight),
862 mod1: Button::Simple(GilButton::RightTrigger),
863 mod2: Button::Simple(GilButton::Unknown),
864 }),
865 GameInput::DeclineGroupInvite => Some(LayerEntry {
866 button: Button::Simple(GilButton::DPadLeft),
867 mod1: Button::Simple(GilButton::RightTrigger),
868 mod2: Button::Simple(GilButton::Unknown),
869 }),
870 GameInput::MapZoomIn => Some(LayerEntry {
871 button: Button::Simple(GilButton::Unknown),
872 mod1: Button::Simple(GilButton::Unknown),
873 mod2: Button::Simple(GilButton::Unknown),
874 }),
875 GameInput::MapZoomOut => Some(LayerEntry {
876 button: Button::Simple(GilButton::Unknown),
877 mod1: Button::Simple(GilButton::Unknown),
878 mod2: Button::Simple(GilButton::Unknown),
879 }),
880 GameInput::MapSetMarker => Some(LayerEntry {
881 button: Button::Simple(GilButton::Unknown),
882 mod1: Button::Simple(GilButton::Unknown),
883 mod2: Button::Simple(GilButton::Unknown),
884 }),
885 GameInput::SpectateSpeedBoost => Some(LayerEntry {
886 button: Button::Simple(GilButton::Unknown),
887 mod1: Button::Simple(GilButton::Unknown),
888 mod2: Button::Simple(GilButton::Unknown),
889 }),
890 GameInput::SpectateViewpoint => Some(LayerEntry {
891 button: Button::Simple(GilButton::Unknown),
892 mod1: Button::Simple(GilButton::Unknown),
893 mod2: Button::Simple(GilButton::Unknown),
894 }),
895 GameInput::MuteMaster => Some(LayerEntry {
896 button: Button::Simple(GilButton::Unknown),
897 mod1: Button::Simple(GilButton::Unknown),
898 mod2: Button::Simple(GilButton::Unknown),
899 }),
900 GameInput::MuteInactiveMaster => Some(LayerEntry {
901 button: Button::Simple(GilButton::Unknown),
902 mod1: Button::Simple(GilButton::Unknown),
903 mod2: Button::Simple(GilButton::Unknown),
904 }),
905 GameInput::MuteMusic => Some(LayerEntry {
906 button: Button::Simple(GilButton::Unknown),
907 mod1: Button::Simple(GilButton::Unknown),
908 mod2: Button::Simple(GilButton::Unknown),
909 }),
910 GameInput::MuteSfx => Some(LayerEntry {
911 button: Button::Simple(GilButton::Unknown),
912 mod1: Button::Simple(GilButton::Unknown),
913 mod2: Button::Simple(GilButton::Unknown),
914 }),
915 GameInput::MuteAmbience => Some(LayerEntry {
916 button: Button::Simple(GilButton::Unknown),
917 mod1: Button::Simple(GilButton::Unknown),
918 mod2: Button::Simple(GilButton::Unknown),
919 }),
920 GameInput::ToggleWalk => Some(LayerEntry {
921 button: Button::Simple(GilButton::Unknown),
922 mod1: Button::Simple(GilButton::Unknown),
923 mod2: Button::Simple(GilButton::Unknown),
924 }),
925 }
926 }
927
928 pub fn default_menu_button_binding(menu_input: MenuInput) -> Option<Button> {
929 match menu_input {
930 MenuInput::Up => Some(Button::Simple(GilButton::DPadUp)),
931 MenuInput::Down => Some(Button::Simple(GilButton::DPadDown)),
932 MenuInput::Left => Some(Button::Simple(GilButton::DPadLeft)),
933 MenuInput::Right => Some(Button::Simple(GilButton::DPadRight)),
934 MenuInput::ScrollUp => Some(Button::Simple(GilButton::Unknown)),
935 MenuInput::ScrollDown => Some(Button::Simple(GilButton::Unknown)),
936 MenuInput::ScrollLeft => Some(Button::Simple(GilButton::Unknown)),
937 MenuInput::ScrollRight => Some(Button::Simple(GilButton::Unknown)),
938 MenuInput::PageUp => Some(Button::Simple(GilButton::RightTrigger)),
939 MenuInput::PageDown => Some(Button::Simple(GilButton::LeftTrigger)),
940 MenuInput::Apply => Some(Button::Simple(GilButton::South)),
941 MenuInput::Back => Some(Button::Simple(GilButton::East)),
942 MenuInput::Exit => Some(Button::Simple(GilButton::Mode)),
943 MenuInput::LocalFocus => Some(Button::Simple(GilButton::North)),
944 MenuInput::GlobalFocus => Some(Button::Simple(GilButton::Select)),
945 MenuInput::EmulateLeftClick => Some(Button::Simple(GilButton::RightTrigger2)),
946 MenuInput::EmulateRightClick => Some(Button::Simple(GilButton::LeftTrigger2)),
947 }
948 }
949}
950
951impl Default for ControllerSettings {
952 fn default() -> Self {
953 let mut controller_settings = Self {
954 game_button_map: HashMap::new(),
955 inverse_game_button_map: HashMap::new(),
956 menu_button_map: HashMap::new(),
957 inverse_menu_button_map: HashMap::new(),
958 game_analog_button_map: HashMap::new(),
959 inverse_game_analog_button_map: HashMap::new(),
960 menu_analog_button_map: HashMap::new(),
961 inverse_menu_analog_button_map: HashMap::new(),
962 game_axis_map: HashMap::new(),
963 inverse_game_axis_map: HashMap::new(),
964 menu_axis_map: HashMap::new(),
965 inverse_menu_axis_map: HashMap::new(),
966 layer_button_map: HashMap::new(),
967 inverse_layer_button_map: HashMap::new(),
968
969 modifier_buttons: vec![
970 Button::Simple(GilButton::RightTrigger),
971 Button::Simple(GilButton::LeftTrigger),
972 ],
973 pan_sensitivity: 10,
974 pan_invert_y: false,
975 axis_deadzones: HashMap::new(),
976 button_deadzones: HashMap::new(),
977 mouse_emulation_sensitivity: 12,
978 inverted_axes: Vec::new(),
979 };
980 for button_input in GameInput::iter() {
982 if let Some(default) = ControllerSettings::default_button_binding(button_input) {
983 controller_settings.insert_game_button_binding(button_input, default)
984 };
985 }
986 for layer_input in GameInput::iter() {
988 if let Some(default) = ControllerSettings::default_layer_binding(layer_input) {
989 controller_settings.insert_layer_button_binding(layer_input, default);
990 };
991 }
992 for button_input in MenuInput::iter() {
994 if let Some(default) = ControllerSettings::default_menu_button_binding(button_input) {
995 controller_settings.insert_menu_button_binding(button_input, default)
996 };
997 }
998 for axis_input in AxisGameAction::iter() {
1000 if let Some(default) = ControllerSettings::default_game_axis(axis_input) {
1001 controller_settings.insert_game_axis_binding(axis_input, default)
1002 };
1003 }
1004 for axis_input in AxisMenuAction::iter() {
1006 if let Some(default) = ControllerSettings::default_menu_axis(axis_input) {
1007 controller_settings.insert_menu_axis_binding(axis_input, default)
1008 };
1009 }
1010 controller_settings
1011 }
1012}
1013
1014#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Deserialize, Serialize, EnumIter)]
1016pub enum AxisMenuAction {
1017 MoveX,
1018 MoveY,
1019 ScrollX,
1020 ScrollY,
1021}
1022
1023#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Deserialize, Serialize, EnumIter)]
1025pub enum AxisGameAction {
1026 MovementX,
1027 MovementY,
1028 CameraX,
1029 CameraY,
1030}
1031
1032#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Deserialize, Serialize)]
1034pub enum AnalogButtonMenuAction {}
1035
1036#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Deserialize, Serialize)]
1038pub enum AnalogButtonGameAction {}
1039
1040#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Deserialize, Serialize)]
1043pub enum Button {
1044 Simple(GilButton),
1045 EventCode(u32),
1046}
1047
1048impl Default for Button {
1049 fn default() -> Self { Button::Simple(GilButton::Unknown) }
1050}
1051
1052impl Button {
1053 pub fn display_string(&self, localized_strings: &Localization) -> String {
1055 use self::Button::*;
1056 let button_string = match self {
1058 Simple(GilButton::South) => localized_strings.get_msg("gamepad-south").to_string(),
1059 Simple(GilButton::East) => localized_strings.get_msg("gamepad-east").to_string(),
1060 Simple(GilButton::North) => localized_strings.get_msg("gamepad-north").to_string(),
1061 Simple(GilButton::West) => localized_strings.get_msg("gamepad-west").to_string(),
1062 Simple(GilButton::C) => localized_strings.get_msg("gamepad-c").to_string(),
1063 Simple(GilButton::Z) => localized_strings.get_msg("gamepad-z").to_string(),
1064 Simple(GilButton::LeftTrigger) => localized_strings
1065 .get_msg("gamepad-left_trigger")
1066 .to_string(),
1067 Simple(GilButton::LeftTrigger2) => localized_strings
1068 .get_msg("gamepad-left_trigger_2")
1069 .to_string(),
1070 Simple(GilButton::RightTrigger) => localized_strings
1071 .get_msg("gamepad-right_trigger")
1072 .to_string(),
1073 Simple(GilButton::RightTrigger2) => localized_strings
1074 .get_msg("gamepad-right_trigger_2")
1075 .to_string(),
1076 Simple(GilButton::Select) => localized_strings.get_msg("gamepad-select").to_string(),
1077 Simple(GilButton::Start) => localized_strings.get_msg("gamepad-start").to_string(),
1078 Simple(GilButton::Mode) => localized_strings.get_msg("gamepad-mode").to_string(),
1079 Simple(GilButton::LeftThumb) => {
1080 localized_strings.get_msg("gamepad-left_thumb").to_string()
1081 },
1082 Simple(GilButton::RightThumb) => {
1083 localized_strings.get_msg("gamepad-right_thumb").to_string()
1084 },
1085 Simple(GilButton::DPadUp) => localized_strings.get_msg("gamepad-dpad_up").to_string(),
1086 Simple(GilButton::DPadDown) => {
1087 localized_strings.get_msg("gamepad-dpad_down").to_string()
1088 },
1089 Simple(GilButton::DPadLeft) => {
1090 localized_strings.get_msg("gamepad-dpad_left").to_string()
1091 },
1092 Simple(GilButton::DPadRight) => {
1093 localized_strings.get_msg("gamepad-dpad_right").to_string()
1094 },
1095 Simple(GilButton::Unknown) => localized_strings.get_msg("gamepad-unknown").to_string(),
1096 EventCode(code) => code.to_string(),
1097 };
1098
1099 button_string.to_owned()
1100 }
1101
1102 pub fn try_shortened(&self) -> Option<String> {
1105 use self::Button::*;
1106 let button_string = match self {
1107 Simple(GilButton::South) => "A",
1108 Simple(GilButton::East) => "B",
1109 Simple(GilButton::North) => "Y",
1110 Simple(GilButton::West) => "X",
1111 Simple(GilButton::LeftTrigger) => "LB",
1112 Simple(GilButton::LeftTrigger2) => "LT",
1113 Simple(GilButton::RightTrigger) => "RB",
1114 Simple(GilButton::RightTrigger2) => "RT",
1115 Simple(GilButton::LeftThumb) => "L3",
1116 Simple(GilButton::RightThumb) => "R3",
1117 _ => return None,
1118 };
1119
1120 Some(button_string.to_owned())
1121 }
1122}
1123
1124#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
1127#[serde(default)]
1128pub struct LayerEntry {
1129 pub button: Button,
1130 pub mod1: Button,
1131 pub mod2: Button,
1132}
1133
1134impl Default for LayerEntry {
1135 fn default() -> Self {
1136 Self {
1138 button: Button::Simple(GilButton::Unknown),
1139 mod1: Button::Simple(GilButton::Unknown),
1140 mod2: Button::Simple(GilButton::Unknown),
1141 }
1142 }
1143}
1144
1145impl LayerEntry {
1146 pub fn display_string(&self, localized_strings: &Localization) -> String {
1147 use self::Button::*;
1148
1149 let mod1: Option<String> = match self.mod1 {
1150 Simple(GilButton::Unknown) => None,
1151 _ => self
1152 .mod1
1153 .try_shortened()
1154 .map_or(Some(self.mod1.display_string(localized_strings)), Some),
1155 };
1156 let mod2: Option<String> = match self.mod2 {
1157 Simple(GilButton::Unknown) => None,
1158 _ => self
1159 .mod2
1160 .try_shortened()
1161 .map_or(Some(self.mod2.display_string(localized_strings)), Some),
1162 };
1163
1164 format!(
1165 "{}{}{} {}",
1166 mod1.map_or("".to_owned(), |m1| format!("{} + ", m1)),
1167 mod2.map_or("".to_owned(), |m2| format!("{} + ", m2)),
1168 self.button.display_string(localized_strings),
1169 self.button
1170 .try_shortened()
1171 .map_or("".to_owned(), |short| format!("({})", short))
1172 )
1173 }
1174}
1175
1176#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Deserialize, Serialize)]
1179pub enum AnalogButton {
1180 Simple(GilButton),
1181 EventCode(u32),
1182}
1183
1184impl Default for AnalogButton {
1185 fn default() -> Self { AnalogButton::Simple(GilButton::Unknown) }
1186}
1187
1188#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Deserialize, Serialize)]
1191pub enum Axis {
1192 Simple(GilAxis),
1193 EventCode(u32),
1194}
1195
1196impl Default for Axis {
1197 fn default() -> Self { Axis::Simple(GilAxis::Unknown) }
1198}
1199
1200impl From<(GilAxis, GilCode)> for Axis {
1201 fn from((axis, code): (GilAxis, GilCode)) -> Self {
1202 match axis {
1203 GilAxis::Unknown => Self::EventCode(code.into_u32()),
1204 _ => Self::Simple(axis),
1205 }
1206 }
1207}
1208
1209impl From<(GilButton, GilCode)> for Button {
1210 fn from((button, code): (GilButton, GilCode)) -> Self {
1211 match button {
1212 GilButton::Unknown => Self::EventCode(code.into_u32()),
1213 _ => Self::Simple(button),
1214 }
1215 }
1216}
1217
1218impl From<(GilButton, GilCode)> for AnalogButton {
1219 fn from((button, code): (GilButton, GilCode)) -> Self {
1220 match button {
1221 GilButton::Unknown => Self::EventCode(code.into_u32()),
1222 _ => Self::Simple(button),
1223 }
1224 }
1225}