goud_engine/core/input_manager/
gamepad.rs1#[cfg(feature = "native")]
4use glfw::GamepadAxis;
5
6use crate::core::math::Vec2;
7
8use super::manager::InputManager;
9use super::types::{GamepadState, InputBinding};
10
11impl InputManager {
12 pub fn press_gamepad_button(&mut self, gamepad_id: usize, button: u32) {
19 self.ensure_gamepad_capacity(gamepad_id);
20
21 let is_new = !self.gamepad_buttons_current[gamepad_id].contains(&button);
23 if is_new {
24 self.buffer_input(InputBinding::GamepadButton { gamepad_id, button });
25 }
26
27 self.gamepad_buttons_current[gamepad_id].insert(button);
28 }
29
30 pub fn release_gamepad_button(&mut self, gamepad_id: usize, button: u32) {
35 self.ensure_gamepad_capacity(gamepad_id);
36 self.gamepad_buttons_current[gamepad_id].remove(&button);
37 }
38
39 pub fn gamepad_button_pressed(&self, gamepad_id: usize, button: u32) -> bool {
43 self.gamepad_buttons_current
44 .get(gamepad_id)
45 .is_some_and(|buttons| buttons.contains(&button))
46 }
47
48 pub fn gamepad_button_just_pressed(&self, gamepad_id: usize, button: u32) -> bool {
50 let current = self
51 .gamepad_buttons_current
52 .get(gamepad_id)
53 .is_some_and(|buttons| buttons.contains(&button));
54 let previous = self
55 .gamepad_buttons_previous
56 .get(gamepad_id)
57 .is_some_and(|buttons| buttons.contains(&button));
58 current && !previous
59 }
60
61 pub fn gamepad_button_just_released(&self, gamepad_id: usize, button: u32) -> bool {
63 let current = self
64 .gamepad_buttons_current
65 .get(gamepad_id)
66 .is_some_and(|buttons| buttons.contains(&button));
67 let previous = self
68 .gamepad_buttons_previous
69 .get(gamepad_id)
70 .is_some_and(|buttons| buttons.contains(&button));
71 !current && previous
72 }
73
74 pub(super) fn ensure_gamepad_capacity(&mut self, gamepad_id: usize) {
76 while self.gamepad_buttons_current.len() <= gamepad_id {
77 self.gamepad_buttons_current
78 .push(std::collections::HashSet::new());
79 }
80 while self.gamepad_buttons_previous.len() <= gamepad_id {
81 self.gamepad_buttons_previous
82 .push(std::collections::HashSet::new());
83 }
84 while self.gamepads.len() <= gamepad_id {
85 self.gamepads.push(GamepadState::new());
86 }
87 while self.gamepads_previous.len() <= gamepad_id {
88 self.gamepads_previous.push(GamepadState::new());
89 }
90 }
91
92 pub fn set_gamepad_axis(&mut self, gamepad_id: usize, axis: GamepadAxis, value: f32) {
98 self.ensure_gamepad_capacity(gamepad_id);
99
100 let deadzone_value = if value.abs() < self.analog_deadzone {
102 0.0
103 } else {
104 value
105 };
106
107 self.gamepads[gamepad_id].axes.insert(axis, deadzone_value);
108 }
109
110 pub fn gamepad_axis(&self, gamepad_id: usize, axis: GamepadAxis) -> f32 {
114 self.gamepads
115 .get(gamepad_id)
116 .and_then(|gamepad| gamepad.axes.get(&axis).copied())
117 .unwrap_or(0.0)
118 }
119
120 pub fn gamepad_left_stick(&self, gamepad_id: usize) -> Vec2 {
124 Vec2::new(
125 self.gamepad_axis(gamepad_id, GamepadAxis::AxisLeftX),
126 self.gamepad_axis(gamepad_id, GamepadAxis::AxisLeftY),
127 )
128 }
129
130 pub fn gamepad_right_stick(&self, gamepad_id: usize) -> Vec2 {
134 Vec2::new(
135 self.gamepad_axis(gamepad_id, GamepadAxis::AxisRightX),
136 self.gamepad_axis(gamepad_id, GamepadAxis::AxisRightY),
137 )
138 }
139
140 pub fn gamepad_left_trigger(&self, gamepad_id: usize) -> f32 {
144 (self.gamepad_axis(gamepad_id, GamepadAxis::AxisLeftTrigger) + 1.0) * 0.5
146 }
147
148 pub fn gamepad_right_trigger(&self, gamepad_id: usize) -> f32 {
152 (self.gamepad_axis(gamepad_id, GamepadAxis::AxisRightTrigger) + 1.0) * 0.5
154 }
155
156 pub fn set_gamepad_connected(&mut self, gamepad_id: usize, connected: bool) {
160 self.ensure_gamepad_capacity(gamepad_id);
161 self.gamepads[gamepad_id].connected = connected;
162 }
163
164 pub fn is_gamepad_connected(&self, gamepad_id: usize) -> bool {
166 self.gamepads
167 .get(gamepad_id)
168 .map(|gamepad| gamepad.connected)
169 .unwrap_or(false)
170 }
171
172 pub fn connected_gamepad_count(&self) -> usize {
174 self.gamepads
175 .iter()
176 .filter(|gamepad| gamepad.connected)
177 .count()
178 }
179
180 pub fn connected_gamepads(&self) -> impl Iterator<Item = usize> + '_ {
182 self.gamepads
183 .iter()
184 .enumerate()
185 .filter_map(|(id, gamepad)| if gamepad.connected { Some(id) } else { None })
186 }
187
188 pub fn set_gamepad_vibration(&mut self, gamepad_id: usize, intensity: f32) {
195 self.ensure_gamepad_capacity(gamepad_id);
196 self.gamepads[gamepad_id].vibration = intensity.clamp(0.0, 1.0);
197 }
198
199 pub fn gamepad_vibration(&self, gamepad_id: usize) -> f32 {
201 self.gamepads
202 .get(gamepad_id)
203 .map(|gamepad| gamepad.vibration)
204 .unwrap_or(0.0)
205 }
206
207 pub fn stop_gamepad_vibration(&mut self, gamepad_id: usize) {
209 self.set_gamepad_vibration(gamepad_id, 0.0);
210 }
211
212 pub fn stop_all_vibration(&mut self) {
214 for gamepad in &mut self.gamepads {
215 gamepad.vibration = 0.0;
216 }
217 }
218
219 pub fn analog_deadzone(&self) -> f32 {
225 self.analog_deadzone
226 }
227
228 pub fn set_analog_deadzone(&mut self, deadzone: f32) {
233 self.analog_deadzone = deadzone.clamp(0.0, 1.0);
234 }
235}