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