diff --git a/src/main.rs b/src/main.rs index d062ce8..c687175 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,9 +1,14 @@ +#![feature(let_chains)] + use clap::{ArgGroup, Parser}; use gb_emu::{ connect::{JoypadState, Renderer}, util::scale_buffer, }; -use gilrs::{Button, Gilrs}; +use gilrs::{ + ff::{BaseEffect, BaseEffectType, EffectBuilder, Replay, Ticks}, + Button, Gilrs, +}; use minifb::{Key, Window, WindowOptions}; /// Gameboy (DMG-A/B/C) emulator @@ -83,6 +88,7 @@ struct WindowRenderer { factor: usize, gamepad_handler: Option, joypad_state: JoypadState, + current_rumble: bool, } impl WindowRenderer { @@ -95,6 +101,7 @@ impl WindowRenderer { factor, gamepad_handler, joypad_state: JoypadState::default(), + current_rumble: false, } } } @@ -180,4 +187,34 @@ impl Renderer for WindowRenderer { self.joypad_state } + + fn set_rumble(&mut self, rumbling: bool) { + if rumbling != self.current_rumble && let Some(ref mut gamepad_handler) = self.gamepad_handler { + self.current_rumble = rumbling; + + let ids = gamepad_handler + .gamepads() + .filter_map(|(id, gp)| if gp.is_ff_supported() { Some(id) } else { None }) + .collect::>(); + if ids.is_empty() { + return; + } + + let magnitude = if rumbling { 0xFF } else { 0x0 }; + + EffectBuilder::new() + .add_effect(BaseEffect { + kind: BaseEffectType::Strong { magnitude }, + scheduling: Replay { + after: Ticks::from_ms(0), + play_for: Ticks::from_ms(16), + with_delay: Ticks::from_ms(0), + }, + envelope: Default::default(), + }) + .gamepads(&ids) + .finish(gamepad_handler) + .unwrap(); + } + } }