Add keyboard input bindings

This commit is contained in:
Vivian Lim 2019-12-23 00:22:35 -08:00
parent 3a37efea02
commit 032956d343
1 changed files with 76 additions and 19 deletions

View File

@ -48,6 +48,7 @@ struct MyEmulator {
// input bits
gamepad_subsys: sdl2::GameControllerSubsystem,
gamepads: Vec<GameController>,
pressed_keys: Vec<Keycode>,
}
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<Keycode> = 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<bool> { Some(true) }
@ -407,7 +443,28 @@ fn button_map(retro_button: &JoypadButton) -> Option<Button> {
}
}
fn axis_map(index: InputIndex, axis: AnalogAxis) -> Axis {
fn keyboard_map(retro_button: &JoypadButton) -> Option<Keycode> {
match retro_button {
JoypadButton::B => Some(Keycode::K),
JoypadButton::Y => Some(Keycode::J),
JoypadButton::Select => Some(Keycode::Num5),
JoypadButton::Start => Some(Keycode::Num6),
JoypadButton::Up => Some(Keycode::W),
JoypadButton::Down => Some(Keycode::S),
JoypadButton::Left => Some(Keycode::A),
JoypadButton::Right => Some(Keycode::D),
JoypadButton::A => Some(Keycode::L),
JoypadButton::X => Some(Keycode::I),
JoypadButton::L => Some(Keycode::Num1),
JoypadButton::R => Some(Keycode::Num0),
JoypadButton::L2 => None,
JoypadButton::R2 => None,
JoypadButton::L3 => None,
JoypadButton::R3 => None,
}
}
fn axis_map(index: &InputIndex, axis: &AnalogAxis) -> Axis {
match (index, axis) {
(InputIndex::Left, AnalogAxis::X) => Axis::LeftX,
(InputIndex::Left, AnalogAxis::Y) => Axis::LeftY,