From 032956d3436fd3f32d9c82516e165ba9526de1e2 Mon Sep 17 00:00:00 2001 From: Vivian Lim Date: Mon, 23 Dec 2019 00:22:35 -0800 Subject: [PATCH 1/5] Add keyboard input bindings --- examples/sdl2_emulator.rs | 95 +++++++++++++++++++++++++++++++-------- 1 file changed, 76 insertions(+), 19 deletions(-) diff --git a/examples/sdl2_emulator.rs b/examples/sdl2_emulator.rs index 8ca7db2..4dd24f4 100644 --- a/examples/sdl2_emulator.rs +++ b/examples/sdl2_emulator.rs @@ -48,6 +48,7 @@ struct MyEmulator { // input bits gamepad_subsys: sdl2::GameControllerSubsystem, gamepads: Vec, + pressed_keys: Vec, } impl MyEmulator { @@ -112,6 +113,8 @@ impl MyEmulator { gamepads.extend(gamepad_subsys.open(i).into_iter()); } + let pressed_keys = Vec::new(); + let emu = MyEmulator { retro, core_path, @@ -128,6 +131,7 @@ impl MyEmulator { audio_sender, gamepad_subsys, gamepads, + pressed_keys, }; let mut pin_emu = Box::pin(emu); retro::wrapper::set_handler(pin_emu.as_mut()); @@ -152,6 +156,8 @@ impl MyEmulator { } } + self.update_key_state(&event_pump.keyboard_state()); + // The rest of the game loop goes here... self.retro.run(); self.canvas.present(); @@ -188,6 +194,11 @@ impl MyEmulator { } } + pub fn update_key_state<'a>(&mut self, keyboard_state: &sdl2::keyboard::KeyboardState<'a>){ + let keys: Vec = keyboard_state.pressed_scancodes().filter_map(Keycode::from_scancode).collect(); + self.pressed_keys = keys; + } + fn send_audio_samples(&mut self) { let stereo_samples = self.audio_spec.samples as usize * 2; while self.audio_buffer.len() >= stereo_samples { @@ -196,6 +207,44 @@ impl MyEmulator { let _ = self.audio_sender.try_send(msg); } } + + fn input_state_gamepad(&mut self, port: u32, device: &InputDeviceId, index: &InputIndex) -> i16 { + match self.gamepads.get(port as usize) { + Some(gamepad) => { + match device { + InputDeviceId::Joypad(button) => { + match button_map(&button) { + Some(x) => gamepad.button(x) as i16, + None => match button { + JoypadButton::L2 => gamepad.axis(Axis::TriggerLeft), + JoypadButton::R2 => gamepad.axis(Axis::TriggerRight), + _ => 0, + } + } + } + InputDeviceId::Analog(axis) => gamepad.axis(axis_map(index, axis)), + _ => 0, + } + } + None => 0, + } + } + + fn input_state_keyboard(&mut self, port: u32, device: &InputDeviceId, index: &InputIndex) -> i16 { + if port != 0 { // Keyboard only controls the first port. + return 0; + } + + match device { + InputDeviceId::Joypad(button) => { + match keyboard_map(&button) { + Some(x) => return if self.pressed_keys.contains(&x) {1} else {0}, + None => 0 + } + }, + _ => 0 + } + } } impl Drop for MyEmulator { @@ -241,25 +290,12 @@ impl retro::wrapper::Handler for MyEmulator { } fn input_state(&mut self, port: u32, device: InputDeviceId, index: InputIndex) -> i16 { - match self.gamepads.get(port as usize) { - Some(gamepad) => { - match device { - InputDeviceId::Joypad(button) => { - match button_map(&button) { - Some(x) => gamepad.button(x) as i16, - None => match button { - JoypadButton::L2 => gamepad.axis(Axis::TriggerLeft), - JoypadButton::R2 => gamepad.axis(Axis::TriggerRight), - _ => 0, - } - } - } - InputDeviceId::Analog(axis) => gamepad.axis(axis_map(index, axis)), - _ => 0, - } - } - None => 0, + let gamepad_state = self.input_state_gamepad(port, &device, &index); + if gamepad_state > 0 { + return gamepad_state; } + + return self.input_state_keyboard(port, &device, &index); } fn get_can_dupe(&mut self) -> Option { Some(true) } @@ -407,7 +443,28 @@ fn button_map(retro_button: &JoypadButton) -> Option