1use glam::Vec2;
2
3#[derive(Clone, Copy, Debug, Default)]
4pub struct MouseState {
5 pub left_held: bool,
6 pub left_pressed: bool,
7 pub right_held: bool,
8 pub right_pressed: bool,
9}
10
11#[derive(Clone, Copy, Debug, Default)]
12pub struct GamepadState {
13 pub left_stick: Vec2,
14 pub right_stick: Vec2,
15 pub right_trigger_held: bool,
16 pub right_trigger_pressed: bool,
17 pub left_trigger_held: bool,
18 pub left_trigger_pressed: bool,
19 pub south_pressed: bool,
20 pub east_pressed: bool,
21 pub dpad_left_pressed: bool,
22 pub dpad_up_pressed: bool,
23 pub dpad_right_pressed: bool,
24 pub north_pressed: bool,
25}
26
27#[derive(Clone, Copy, Debug, Default)]
28pub struct TouchContact {
29 pub start: Vec2,
30 pub pos: Vec2,
31 pub just_pressed: bool,
32}
33
34pub fn dead_zone(value: Vec2) -> Vec2 {
35 const DEAD_ZONE: f32 = 0.22;
36
37 let length = value.length();
38 if length <= DEAD_ZONE {
39 return Vec2::ZERO;
40 }
41
42 let scaled = ((length - DEAD_ZONE) / (1.0 - DEAD_ZONE)).clamp(0.0, 1.0);
43 value.normalize_or_zero() * scaled
44}
45
46pub fn apply_stick(raw: Vec2) -> Vec2 {
47 dead_zone(raw).clamp_length_max(1.0)
48}
49
50#[cfg(test)]
51mod tests {
52 use super::*;
53
54 #[test]
55 fn dead_zone_kills_rest() {
56 assert_eq!(dead_zone(Vec2::new(0.1, 0.0)), Vec2::ZERO);
57 }
58
59 #[test]
60 fn full_deflection_survives() {
61 let out = apply_stick(Vec2::new(1.0, 0.0));
62 assert!((out.length() - 1.0).abs() < 1e-6);
63 }
64}