89 lines
3.5 KiB
Rust
89 lines
3.5 KiB
Rust
use std::collections::HashMap;
|
|
use crate::base::ControlFlow;
|
|
use crate::prelude::*;
|
|
|
|
use sdl2::Sdl;
|
|
use sdl2::event::Event;
|
|
use sdl2::keyboard::Keycode;
|
|
|
|
// FIXME: make it not hard require EventPump ownership, or allow user-provided function?
|
|
/// Maps the first "RetroPad" layout to the keyboard.
|
|
///
|
|
/// NOTE: This component is intended for exceedingly simple use-cases, and *must own* the
|
|
/// [sdl2::EventPump].
|
|
pub struct SimpleSdl2KeyboardComponent {
|
|
button_map: HashMap<Keycode, InputDeviceId>,
|
|
button_state: HashMap<InputDeviceId, i16>,
|
|
event_pump: sdl2::EventPump,
|
|
}
|
|
|
|
impl RetroCallbacks for SimpleSdl2KeyboardComponent {
|
|
fn input_state(&mut self, port: u32, device: InputDeviceId, _index: InputIndex) -> i16 {
|
|
if port != 0 {
|
|
return 0;
|
|
}
|
|
self.button_state.get(&device).cloned().unwrap_or_default()
|
|
}
|
|
|
|
fn get_input_device_capabilities(&mut self) -> Option<u64> {
|
|
let bits = 1 << (DeviceType::Joypad as u32);
|
|
Some(bits as u64)
|
|
}
|
|
}
|
|
|
|
impl RetroComponent for SimpleSdl2KeyboardComponent {
|
|
fn pre_run(&mut self, _retro: &mut LibretroWrapper) -> ControlFlow {
|
|
for event in self.event_pump.poll_iter() {
|
|
match event {
|
|
Event::Quit { .. }
|
|
| Event::KeyDown {
|
|
keycode: Some(Keycode::Escape),
|
|
..
|
|
} => return ControlFlow::Break,
|
|
Event::KeyDown { keycode: Some(k), .. } => {
|
|
if let Some(button) = self.button_map.get(&k) {
|
|
self.button_state.insert(button.to_owned(), 1);
|
|
}
|
|
}
|
|
Event::KeyUp { keycode: Some(k), .. } => {
|
|
if let Some(button) = self.button_map.get(&k) {
|
|
self.button_state.remove(button);
|
|
}
|
|
}
|
|
_ => {}
|
|
}
|
|
}
|
|
ControlFlow::Continue
|
|
}
|
|
}
|
|
|
|
impl SimpleSdl2KeyboardComponent {
|
|
pub fn new(sdl_context: &mut Sdl) -> crate::base::Result<Self> {
|
|
let event_pump = sdl_context.event_pump()?;
|
|
|
|
Ok(SimpleSdl2KeyboardComponent {
|
|
button_map: [
|
|
(Keycode::Up, InputDeviceId::Joypad(JoypadButton::Up)),
|
|
(Keycode::Down, InputDeviceId::Joypad(JoypadButton::Down)),
|
|
(Keycode::Left, InputDeviceId::Joypad(JoypadButton::Left)),
|
|
(Keycode::Right, InputDeviceId::Joypad(JoypadButton::Right)),
|
|
(Keycode::X, InputDeviceId::Joypad(JoypadButton::A)),
|
|
(Keycode::Z, InputDeviceId::Joypad(JoypadButton::B)),
|
|
(Keycode::S, InputDeviceId::Joypad(JoypadButton::X)),
|
|
(Keycode::A, InputDeviceId::Joypad(JoypadButton::Y)),
|
|
(Keycode::Q, InputDeviceId::Joypad(JoypadButton::L)),
|
|
(Keycode::W, InputDeviceId::Joypad(JoypadButton::R)),
|
|
(Keycode::E, InputDeviceId::Joypad(JoypadButton::L2)),
|
|
(Keycode::R, InputDeviceId::Joypad(JoypadButton::R2)),
|
|
(Keycode::T, InputDeviceId::Joypad(JoypadButton::L3)),
|
|
(Keycode::Y, InputDeviceId::Joypad(JoypadButton::R3)),
|
|
(Keycode::Return, InputDeviceId::Joypad(JoypadButton::Start)),
|
|
(Keycode::Backspace, InputDeviceId::Joypad(JoypadButton::Select)),
|
|
(Keycode::Tab, InputDeviceId::Joypad(JoypadButton::Select)),
|
|
].into_iter().collect(),
|
|
button_state: Default::default(),
|
|
event_pump,
|
|
})
|
|
}
|
|
}
|