diff --git a/src/framework/gamepad.rs b/src/framework/gamepad.rs index 93e59ee..f711fb7 100644 --- a/src/framework/gamepad.rs +++ b/src/framework/gamepad.rs @@ -3,8 +3,16 @@ use std::collections::{HashMap, HashSet}; use sdl2::controller::GameController; use serde::{Deserialize, Serialize}; +use crate::shared_game_state::SharedGameState; use crate::{common::Rect, engine_constants::EngineConstants, framework::context::Context}; +use crate::framework::error::GameResult; + +const QUAKE_RUMBLE_LOW_FREQ: u16 = 0x3000; +const QUAKE_RUMBLE_HI_FREQ: u16 = 0; +const SUPER_QUAKE_RUMBLE_LOW_FREQ: u16 = 0x5000; +const SUPER_QUAKE_RUMBLE_HI_FREQ: u16 = 0; + #[derive(Debug, Hash, Ord, PartialOrd, PartialEq, Eq, Clone, Copy, Serialize, Deserialize)] #[repr(u32)] pub enum Axis { @@ -186,6 +194,12 @@ impl GamepadData { name } + + pub fn set_rumble(&mut self, state: &SharedGameState, low_freq: u16, hi_freq: u16, ticks: u32) -> GameResult { + let duration_ms = (ticks as f32 / state.settings.timing_mode.get_tps() as f32 * 1000.0) as u32; + self.controller.set_rumble(low_freq, hi_freq, duration_ms); + Ok(()) + } } pub struct GamepadContext { @@ -209,6 +223,10 @@ impl GamepadContext { self.gamepads.iter_mut().find(|gamepad| gamepad.controller.instance_id() == gamepad_id) } + fn get_gamepad_by_index_mut(&mut self, gamepad_index: usize) -> Option<&mut GamepadData> { + self.gamepads.get_mut(gamepad_index) + } + pub(crate) fn add_gamepad(&mut self, game_controller: GameController, axis_sensitivity: f64) { self.gamepads.push(GamepadData::new(game_controller, axis_sensitivity)); } @@ -323,6 +341,35 @@ impl GamepadContext { HashMap::new() } + + pub(crate) fn set_rumble( + &mut self, + gamepad_index: u32, + state: &SharedGameState, + low_freq: u16, + hi_freq: u16, + ticks: u32, + ) -> GameResult { + if let Some(gamepad) = self.get_gamepad_by_index_mut(gamepad_index as usize) { + gamepad.set_rumble(state, low_freq, hi_freq, ticks)?; + } + + Ok(()) + } + + pub(crate) fn set_rumble_all( + &mut self, + state: &SharedGameState, + low_freq: u16, + hi_freq: u16, + ticks: u32, + ) -> GameResult { + for gamepad in self.gamepads.iter_mut() { + gamepad.set_rumble(state, low_freq, hi_freq, ticks)?; + } + + Ok(()) + } } impl Default for GamepadContext { @@ -370,3 +417,45 @@ pub fn pressed_buttons(ctx: &Context, gamepad_index: u32) -> HashSet