use std::{thread, time::Duration}; use color_eyre::{eyre::eyre, Result}; use gilrs::{ ff::{BaseEffect, BaseEffectType, EffectBuilder, Replay, Ticks}, Gamepad, GamepadId, Gilrs, }; pub struct GamepadManager { pub gilrs: Gilrs, gamepads: Vec, active_gamepad: Option, connected_gamepads: usize, } impl GamepadManager { pub fn new() -> Result { let gilrs = Gilrs::new().map_err(|e| eyre!("Failed to create Gilrs object:\n{:#?}", e))?; Ok(GamepadManager { gilrs, gamepads: vec![], active_gamepad: None, connected_gamepads: 0, }) } pub fn set_active_gamepad(&mut self, id: impl Into>) { self.active_gamepad = id.into(); // tracing::info!("Selected gamepad changed to: {:#?}", self.active_gamepad); } pub fn active_gamepad(&self) -> Result> { match self.active_gamepad { Some(id) => Ok(self.gilrs.gamepad(id)), None => Err(eyre!("No selected gamepad")), } } pub fn gamepads(&self) -> &Vec { &self.gamepads } pub fn connected_gamepads(&self) -> &usize { &self.connected_gamepads } pub fn scan_gamepads(&mut self) { let mut gamepads = vec![]; // Iterate over all connected gamepads for (id, _) in self.gilrs.gamepads() { // println!("{} is {:?}", gamepad.name(), gamepad.power_info()); // println!("Has Force Feedback Enabled ? {}", gamepad.is_ff_supported()); // if gamepad.is_ff_supported() { // test_ff(&mut gilrs, gamepad); // } gamepads.push(id); } self.connected_gamepads = gamepads.len(); self.gamepads = gamepads; } pub fn test_weak_ff(&mut self) { let Some(id) = self.active_gamepad else { tracing::warn!("No active gamepad found!"); return; }; thread::spawn(move || { let mut gilrs = Gilrs::new().unwrap(); let gamepad = gilrs.gamepad(id); let duration = Ticks::from_ms(1000); let delay = Ticks::from_ms(500); let effect = EffectBuilder::new() .add_effect(BaseEffect { kind: BaseEffectType::Weak { magnitude: 40_000 }, scheduling: Replay { play_for: duration, with_delay: delay, ..Default::default() }, envelope: Default::default(), }) .add_gamepad(&gamepad) .finish(&mut gilrs) .unwrap(); effect.play().unwrap(); thread::sleep(Duration::from_millis(4500)); }); } pub fn test_strong_ff(&mut self) { let Some(id) = self.active_gamepad else { tracing::warn!("No active gamepad found!"); return; }; thread::spawn(move || { let mut gilrs = Gilrs::new().unwrap(); let gamepad = gilrs.gamepad(id); let duration = Ticks::from_ms(1000); let delay = Ticks::from_ms(500); let effect = EffectBuilder::new() .add_effect(BaseEffect { kind: BaseEffectType::Strong { magnitude: 40_000 }, scheduling: Replay { play_for: duration, with_delay: delay, ..Default::default() }, envelope: Default::default(), }) .add_gamepad(&gamepad) .finish(&mut gilrs) .unwrap(); effect.play().unwrap(); thread::sleep(Duration::from_millis(4500)); }); } }