1use crate::{
5 game_input::GameInput, settings::gamepad::con_settings::LayerEntry, window::MenuInput,
6};
7use gilrs::{Axis as GilAxis, Button as GilButton, ev::Code as GilCode};
8use hashbrown::HashMap;
9use serde::{Deserialize, Serialize};
10
11#[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 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 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#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Deserialize, Serialize)]
465pub enum AxisMenuAction {
466 MoveX,
467 MoveY,
468 ScrollX,
469 ScrollY,
470}
471
472#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Deserialize, Serialize)]
474pub enum AxisGameAction {
475 MovementX,
476 MovementY,
477 CameraX,
478 CameraY,
479}
480
481#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Deserialize, Serialize)]
483pub enum AnalogButtonMenuAction {}
484
485#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Deserialize, Serialize)]
487pub enum AnalogButtonGameAction {}
488
489#[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#[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#[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}