veloren_voxygen/
controller.rs

1//! Module containing controller-specific abstractions allowing complex
2//! keybindings
3
4use 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;
9use serde::{Deserialize, Serialize};
10
11/// Contains all controller related settings and keymaps
12#[derive(Clone, Debug, Serialize, Deserialize, Default)]
13#[serde(default)]
14pub struct ControllerSettings {
15    pub game_button_map: HashMap<Button, Vec<GameInput>>,
16    pub menu_button_map: HashMap<Button, Vec<MenuInput>>,
17    pub game_analog_button_map: HashMap<AnalogButton, Vec<AnalogButtonGameAction>>,
18    pub menu_analog_button_map: HashMap<AnalogButton, Vec<AnalogButtonMenuAction>>,
19    pub game_axis_map: HashMap<Axis, Vec<AxisGameAction>>,
20    pub menu_axis_map: HashMap<Axis, Vec<AxisMenuAction>>,
21    pub layer_button_map: HashMap<LayerEntry, Vec<GameInput>>,
22    pub modifier_buttons: Vec<Button>,
23    pub pan_sensitivity: u32,
24    pub pan_invert_y: bool,
25    pub axis_deadzones: HashMap<Axis, f32>,
26    pub button_deadzones: HashMap<AnalogButton, f32>,
27    pub mouse_emulation_sensitivity: u32,
28    pub inverted_axes: Vec<Axis>,
29}
30
31impl ControllerSettings {
32    pub fn apply_axis_deadzone(&self, k: &Axis, input: f32) -> f32 {
33        let threshold = *self.axis_deadzones.get(k).unwrap_or(&0.2);
34
35        // This could be one comparison per handled event faster if threshold was
36        // guaranteed to fall into <0, 1) range
37        let input_abs = input.abs();
38        if input_abs <= threshold || threshold >= 1.0 {
39            0.0
40        } else if threshold <= 0.0 {
41            input
42        } else {
43            (input_abs - threshold) / (1.0 - threshold) * input.signum()
44        }
45    }
46
47    pub fn apply_button_deadzone(&self, k: &AnalogButton, input: f32) -> f32 {
48        let threshold = *self.button_deadzones.get(k).unwrap_or(&0.2);
49
50        // This could be one comparison per handled event faster if threshold was
51        // guaranteed to fall into <0, 1) range
52        if input <= threshold || threshold >= 1.0 {
53            0.0
54        } else if threshold <= 0.0 {
55            input
56        } else {
57            (input - threshold) / (1.0 - threshold)
58        }
59    }
60}
61
62impl From<&crate::settings::GamepadSettings> for ControllerSettings {
63    fn from(settings: &crate::settings::GamepadSettings) -> Self {
64        Self {
65            game_button_map: {
66                let mut map: HashMap<_, Vec<_>> = HashMap::new();
67                map.entry(settings.game_buttons.primary)
68                    .or_default()
69                    .push(GameInput::Primary);
70                map.entry(settings.game_buttons.secondary)
71                    .or_default()
72                    .push(GameInput::Secondary);
73                map.entry(settings.game_buttons.block)
74                    .or_default()
75                    .push(GameInput::Block);
76                map.entry(settings.game_buttons.slot1)
77                    .or_default()
78                    .push(GameInput::Slot1);
79                map.entry(settings.game_buttons.slot2)
80                    .or_default()
81                    .push(GameInput::Slot2);
82                map.entry(settings.game_buttons.slot3)
83                    .or_default()
84                    .push(GameInput::Slot3);
85                map.entry(settings.game_buttons.slot4)
86                    .or_default()
87                    .push(GameInput::Slot4);
88                map.entry(settings.game_buttons.slot5)
89                    .or_default()
90                    .push(GameInput::Slot5);
91                map.entry(settings.game_buttons.slot6)
92                    .or_default()
93                    .push(GameInput::Slot6);
94                map.entry(settings.game_buttons.slot7)
95                    .or_default()
96                    .push(GameInput::Slot7);
97                map.entry(settings.game_buttons.slot8)
98                    .or_default()
99                    .push(GameInput::Slot8);
100                map.entry(settings.game_buttons.slot9)
101                    .or_default()
102                    .push(GameInput::Slot9);
103                map.entry(settings.game_buttons.slot10)
104                    .or_default()
105                    .push(GameInput::Slot10);
106                map.entry(settings.game_buttons.toggle_cursor)
107                    .or_default()
108                    .push(GameInput::ToggleCursor);
109                map.entry(settings.game_buttons.escape)
110                    .or_default()
111                    .push(GameInput::Escape);
112                map.entry(settings.game_buttons.enter)
113                    .or_default()
114                    .push(GameInput::Chat);
115                map.entry(settings.game_buttons.command)
116                    .or_default()
117                    .push(GameInput::Command);
118                map.entry(settings.game_buttons.move_forward)
119                    .or_default()
120                    .push(GameInput::MoveForward);
121                map.entry(settings.game_buttons.move_left)
122                    .or_default()
123                    .push(GameInput::MoveLeft);
124                map.entry(settings.game_buttons.move_back)
125                    .or_default()
126                    .push(GameInput::MoveBack);
127                map.entry(settings.game_buttons.move_right)
128                    .or_default()
129                    .push(GameInput::MoveRight);
130                map.entry(settings.game_buttons.jump)
131                    .or_default()
132                    .push(GameInput::Jump);
133                map.entry(settings.game_buttons.sit)
134                    .or_default()
135                    .push(GameInput::Sit);
136                map.entry(settings.game_buttons.dance)
137                    .or_default()
138                    .push(GameInput::Dance);
139                map.entry(settings.game_buttons.glide)
140                    .or_default()
141                    .push(GameInput::Glide);
142                map.entry(settings.game_buttons.swimup)
143                    .or_default()
144                    .push(GameInput::SwimUp);
145                map.entry(settings.game_buttons.swimdown)
146                    .or_default()
147                    .push(GameInput::SwimDown);
148                map.entry(settings.game_buttons.sneak)
149                    .or_default()
150                    .push(GameInput::Sneak);
151                map.entry(settings.game_buttons.toggle_lantern)
152                    .or_default()
153                    .push(GameInput::ToggleLantern);
154                map.entry(settings.game_buttons.mount)
155                    .or_default()
156                    .push(GameInput::Mount);
157                map.entry(settings.game_buttons.map)
158                    .or_default()
159                    .push(GameInput::Map);
160                map.entry(settings.game_buttons.bag)
161                    .or_default()
162                    .push(GameInput::Inventory);
163                map.entry(settings.game_buttons.social)
164                    .or_default()
165                    .push(GameInput::Social);
166                map.entry(settings.game_buttons.crafting)
167                    .or_default()
168                    .push(GameInput::Crafting);
169                map.entry(settings.game_buttons.diary)
170                    .or_default()
171                    .push(GameInput::Diary);
172                map.entry(settings.game_buttons.settings)
173                    .or_default()
174                    .push(GameInput::Settings);
175                map.entry(settings.game_buttons.controls)
176                    .or_default()
177                    .push(GameInput::Controls);
178                map.entry(settings.game_buttons.toggle_interface)
179                    .or_default()
180                    .push(GameInput::ToggleInterface);
181                map.entry(settings.game_buttons.toggle_debug)
182                    .or_default()
183                    .push(GameInput::ToggleDebug);
184                #[cfg(feature = "egui-ui")]
185                map.entry(settings.game_buttons.toggle_debug)
186                    .or_default()
187                    .push(GameInput::ToggleEguiDebug);
188                map.entry(settings.game_buttons.toggle_chat)
189                    .or_default()
190                    .push(GameInput::ToggleChat);
191                map.entry(settings.game_buttons.fullscreen)
192                    .or_default()
193                    .push(GameInput::Fullscreen);
194                map.entry(settings.game_buttons.screenshot)
195                    .or_default()
196                    .push(GameInput::Screenshot);
197                map.entry(settings.game_buttons.toggle_ingame_ui)
198                    .or_default()
199                    .push(GameInput::ToggleIngameUi);
200                map.entry(settings.game_buttons.roll)
201                    .or_default()
202                    .push(GameInput::Roll);
203                map.entry(settings.game_buttons.respawn)
204                    .or_default()
205                    .push(GameInput::Respawn);
206                map.entry(settings.game_buttons.interact)
207                    .or_default()
208                    .push(GameInput::Interact);
209                map.entry(settings.game_buttons.toggle_wield)
210                    .or_default()
211                    .push(GameInput::ToggleWield);
212                map.entry(settings.game_buttons.swap_loadout)
213                    .or_default()
214                    .push(GameInput::SwapLoadout);
215                map
216            },
217            menu_button_map: {
218                let mut map: HashMap<_, Vec<_>> = HashMap::new();
219                map.entry(settings.menu_buttons.up)
220                    .or_default()
221                    .push(MenuInput::Up);
222                map.entry(settings.menu_buttons.down)
223                    .or_default()
224                    .push(MenuInput::Down);
225                map.entry(settings.menu_buttons.left)
226                    .or_default()
227                    .push(MenuInput::Left);
228                map.entry(settings.menu_buttons.right)
229                    .or_default()
230                    .push(MenuInput::Right);
231                map.entry(settings.menu_buttons.scroll_up)
232                    .or_default()
233                    .push(MenuInput::ScrollUp);
234                map.entry(settings.menu_buttons.scroll_down)
235                    .or_default()
236                    .push(MenuInput::ScrollDown);
237                map.entry(settings.menu_buttons.scroll_left)
238                    .or_default()
239                    .push(MenuInput::ScrollLeft);
240                map.entry(settings.menu_buttons.scroll_right)
241                    .or_default()
242                    .push(MenuInput::ScrollRight);
243                map.entry(settings.menu_buttons.home)
244                    .or_default()
245                    .push(MenuInput::Home);
246                map.entry(settings.menu_buttons.end)
247                    .or_default()
248                    .push(MenuInput::End);
249                map.entry(settings.menu_buttons.apply)
250                    .or_default()
251                    .push(MenuInput::Apply);
252                map.entry(settings.menu_buttons.back)
253                    .or_default()
254                    .push(MenuInput::Back);
255                map.entry(settings.menu_buttons.exit)
256                    .or_default()
257                    .push(MenuInput::Exit);
258                map
259            },
260            game_analog_button_map: HashMap::new(),
261            menu_analog_button_map: HashMap::new(),
262            game_axis_map: {
263                let mut map: HashMap<_, Vec<_>> = HashMap::new();
264                map.entry(settings.game_axis.movement_x)
265                    .or_default()
266                    .push(AxisGameAction::MovementX);
267                map.entry(settings.game_axis.movement_y)
268                    .or_default()
269                    .push(AxisGameAction::MovementY);
270                map.entry(settings.game_axis.camera_x)
271                    .or_default()
272                    .push(AxisGameAction::CameraX);
273                map.entry(settings.game_axis.camera_y)
274                    .or_default()
275                    .push(AxisGameAction::CameraY);
276                map
277            },
278            menu_axis_map: {
279                let mut map: HashMap<_, Vec<_>> = HashMap::new();
280                map.entry(settings.menu_axis.move_x)
281                    .or_default()
282                    .push(AxisMenuAction::MoveX);
283                map.entry(settings.menu_axis.move_y)
284                    .or_default()
285                    .push(AxisMenuAction::MoveY);
286                map.entry(settings.menu_axis.scroll_x)
287                    .or_default()
288                    .push(AxisMenuAction::ScrollX);
289                map.entry(settings.menu_axis.scroll_y)
290                    .or_default()
291                    .push(AxisMenuAction::ScrollY);
292                map
293            },
294            layer_button_map: {
295                let mut map: HashMap<_, Vec<_>> = HashMap::new();
296                map.entry(settings.game_layer_buttons.primary)
297                    .or_default()
298                    .push(GameInput::Primary);
299                map.entry(settings.game_layer_buttons.secondary)
300                    .or_default()
301                    .push(GameInput::Secondary);
302                map.entry(settings.game_layer_buttons.block)
303                    .or_default()
304                    .push(GameInput::Block);
305                map.entry(settings.game_layer_buttons.slot1)
306                    .or_default()
307                    .push(GameInput::Slot1);
308                map.entry(settings.game_layer_buttons.slot2)
309                    .or_default()
310                    .push(GameInput::Slot2);
311                map.entry(settings.game_layer_buttons.slot3)
312                    .or_default()
313                    .push(GameInput::Slot3);
314                map.entry(settings.game_layer_buttons.slot4)
315                    .or_default()
316                    .push(GameInput::Slot4);
317                map.entry(settings.game_layer_buttons.slot5)
318                    .or_default()
319                    .push(GameInput::Slot5);
320                map.entry(settings.game_layer_buttons.slot6)
321                    .or_default()
322                    .push(GameInput::Slot6);
323                map.entry(settings.game_layer_buttons.slot7)
324                    .or_default()
325                    .push(GameInput::Slot7);
326                map.entry(settings.game_layer_buttons.slot8)
327                    .or_default()
328                    .push(GameInput::Slot8);
329                map.entry(settings.game_layer_buttons.slot9)
330                    .or_default()
331                    .push(GameInput::Slot9);
332                map.entry(settings.game_layer_buttons.slot10)
333                    .or_default()
334                    .push(GameInput::Slot10);
335                map.entry(settings.game_layer_buttons.toggle_cursor)
336                    .or_default()
337                    .push(GameInput::ToggleCursor);
338                map.entry(settings.game_layer_buttons.escape)
339                    .or_default()
340                    .push(GameInput::Escape);
341                map.entry(settings.game_layer_buttons.enter)
342                    .or_default()
343                    .push(GameInput::Chat);
344                map.entry(settings.game_layer_buttons.command)
345                    .or_default()
346                    .push(GameInput::Command);
347                map.entry(settings.game_layer_buttons.move_forward)
348                    .or_default()
349                    .push(GameInput::MoveForward);
350                map.entry(settings.game_layer_buttons.move_left)
351                    .or_default()
352                    .push(GameInput::MoveLeft);
353                map.entry(settings.game_layer_buttons.move_back)
354                    .or_default()
355                    .push(GameInput::MoveBack);
356                map.entry(settings.game_layer_buttons.move_right)
357                    .or_default()
358                    .push(GameInput::MoveRight);
359                map.entry(settings.game_layer_buttons.jump)
360                    .or_default()
361                    .push(GameInput::Jump);
362                map.entry(settings.game_layer_buttons.sit)
363                    .or_default()
364                    .push(GameInput::Sit);
365                map.entry(settings.game_layer_buttons.dance)
366                    .or_default()
367                    .push(GameInput::Dance);
368                map.entry(settings.game_layer_buttons.glide)
369                    .or_default()
370                    .push(GameInput::Glide);
371                map.entry(settings.game_layer_buttons.swimup)
372                    .or_default()
373                    .push(GameInput::SwimUp);
374                map.entry(settings.game_layer_buttons.swimdown)
375                    .or_default()
376                    .push(GameInput::SwimDown);
377                map.entry(settings.game_layer_buttons.sneak)
378                    .or_default()
379                    .push(GameInput::Sneak);
380                map.entry(settings.game_layer_buttons.toggle_lantern)
381                    .or_default()
382                    .push(GameInput::ToggleLantern);
383                map.entry(settings.game_layer_buttons.mount)
384                    .or_default()
385                    .push(GameInput::Mount);
386                map.entry(settings.game_layer_buttons.map)
387                    .or_default()
388                    .push(GameInput::Map);
389                map.entry(settings.game_layer_buttons.bag)
390                    .or_default()
391                    .push(GameInput::Inventory);
392                map.entry(settings.game_layer_buttons.social)
393                    .or_default()
394                    .push(GameInput::Social);
395                map.entry(settings.game_layer_buttons.crafting)
396                    .or_default()
397                    .push(GameInput::Crafting);
398                map.entry(settings.game_layer_buttons.diary)
399                    .or_default()
400                    .push(GameInput::Diary);
401                map.entry(settings.game_layer_buttons.settings)
402                    .or_default()
403                    .push(GameInput::Settings);
404                map.entry(settings.game_layer_buttons.controls)
405                    .or_default()
406                    .push(GameInput::Controls);
407                map.entry(settings.game_layer_buttons.toggle_interface)
408                    .or_default()
409                    .push(GameInput::ToggleInterface);
410                map.entry(settings.game_layer_buttons.toggle_debug)
411                    .or_default()
412                    .push(GameInput::ToggleDebug);
413                #[cfg(feature = "egui-ui")]
414                map.entry(settings.game_layer_buttons.toggle_debug)
415                    .or_default()
416                    .push(GameInput::ToggleEguiDebug);
417                map.entry(settings.game_layer_buttons.toggle_chat)
418                    .or_default()
419                    .push(GameInput::ToggleChat);
420                map.entry(settings.game_layer_buttons.fullscreen)
421                    .or_default()
422                    .push(GameInput::Fullscreen);
423                map.entry(settings.game_layer_buttons.screenshot)
424                    .or_default()
425                    .push(GameInput::Screenshot);
426                map.entry(settings.game_layer_buttons.toggle_ingame_ui)
427                    .or_default()
428                    .push(GameInput::ToggleIngameUi);
429                map.entry(settings.game_layer_buttons.roll)
430                    .or_default()
431                    .push(GameInput::Roll);
432                map.entry(settings.game_layer_buttons.respawn)
433                    .or_default()
434                    .push(GameInput::Respawn);
435                map.entry(settings.game_layer_buttons.interact)
436                    .or_default()
437                    .push(GameInput::Interact);
438                map.entry(settings.game_layer_buttons.toggle_wield)
439                    .or_default()
440                    .push(GameInput::ToggleWield);
441                map.entry(settings.game_layer_buttons.swap_loadout)
442                    .or_default()
443                    .push(GameInput::SwapLoadout);
444                map
445            },
446            modifier_buttons: {
447                let vec: Vec<Button> = vec![
448                    Button::Simple(GilButton::RightTrigger),
449                    Button::Simple(GilButton::LeftTrigger),
450                ];
451                vec
452            },
453            pan_sensitivity: settings.pan_sensitivity,
454            pan_invert_y: settings.pan_invert_y,
455            axis_deadzones: settings.axis_deadzones.clone(),
456            button_deadzones: settings.button_deadzones.clone(),
457            mouse_emulation_sensitivity: settings.mouse_emulation_sensitivity,
458            inverted_axes: settings.inverted_axes.clone(),
459        }
460    }
461}
462
463/// All the menu actions you can bind to an Axis
464#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Deserialize, Serialize)]
465pub enum AxisMenuAction {
466    MoveX,
467    MoveY,
468    ScrollX,
469    ScrollY,
470}
471
472/// All the game actions you can bind to an Axis
473#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Deserialize, Serialize)]
474pub enum AxisGameAction {
475    MovementX,
476    MovementY,
477    CameraX,
478    CameraY,
479}
480
481/// All the menu actions you can bind to an analog button
482#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Deserialize, Serialize)]
483pub enum AnalogButtonMenuAction {}
484
485/// All the game actions you can bind to an analog button
486#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Deserialize, Serialize)]
487pub enum AnalogButtonGameAction {}
488
489/// Button::Simple(GilButton::Unknown) is invalid and equal to mapping an action
490/// to nothing
491#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Deserialize, Serialize)]
492pub enum Button {
493    Simple(GilButton),
494    EventCode(u32),
495}
496
497impl Default for Button {
498    fn default() -> Self { Button::Simple(GilButton::Unknown) }
499}
500
501/// AnalogButton::Simple(GilButton::Unknown) is invalid and equal to mapping an
502/// action to nothing
503#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Deserialize, Serialize)]
504pub enum AnalogButton {
505    Simple(GilButton),
506    EventCode(u32),
507}
508
509impl Default for AnalogButton {
510    fn default() -> Self { AnalogButton::Simple(GilButton::Unknown) }
511}
512
513/// Axis::Simple(GilAxis::Unknown) is invalid and equal to mapping an action to
514/// nothing
515#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Deserialize, Serialize)]
516pub enum Axis {
517    Simple(GilAxis),
518    EventCode(u32),
519}
520
521impl Default for Axis {
522    fn default() -> Self { Axis::Simple(GilAxis::Unknown) }
523}
524
525impl From<(GilAxis, GilCode)> for Axis {
526    fn from((axis, code): (GilAxis, GilCode)) -> Self {
527        match axis {
528            GilAxis::Unknown => Self::EventCode(code.into_u32()),
529            _ => Self::Simple(axis),
530        }
531    }
532}
533
534impl From<(GilButton, GilCode)> for Button {
535    fn from((button, code): (GilButton, GilCode)) -> Self {
536        match button {
537            GilButton::Unknown => Self::EventCode(code.into_u32()),
538            _ => Self::Simple(button),
539        }
540    }
541}
542
543impl From<(GilButton, GilCode)> for AnalogButton {
544    fn from((button, code): (GilButton, GilCode)) -> Self {
545        match button {
546            GilButton::Unknown => Self::EventCode(code.into_u32()),
547            _ => Self::Simple(button),
548        }
549    }
550}