use std::collections::HashMap; use winit::{ event::KeyEvent, keyboard::{KeyCode, PhysicalKey}, }; use crate::emulator::{SimId, VBKey}; pub struct InputMapper { vb_bindings: HashMap>, key_bindings: HashMap, } impl InputMapper { pub fn new() -> Self { let mut mapper = Self { vb_bindings: HashMap::new(), key_bindings: HashMap::new(), }; mapper.bind_key(SimId::Player1, VBKey::SEL, PhysicalKey::Code(KeyCode::KeyA)); mapper.bind_key(SimId::Player1, VBKey::STA, PhysicalKey::Code(KeyCode::KeyS)); mapper.bind_key(SimId::Player1, VBKey::B, PhysicalKey::Code(KeyCode::KeyD)); mapper.bind_key(SimId::Player1, VBKey::A, PhysicalKey::Code(KeyCode::KeyF)); mapper.bind_key(SimId::Player1, VBKey::LT, PhysicalKey::Code(KeyCode::KeyE)); mapper.bind_key(SimId::Player1, VBKey::RT, PhysicalKey::Code(KeyCode::KeyR)); mapper.bind_key(SimId::Player1, VBKey::RU, PhysicalKey::Code(KeyCode::KeyI)); mapper.bind_key(SimId::Player1, VBKey::RL, PhysicalKey::Code(KeyCode::KeyJ)); mapper.bind_key(SimId::Player1, VBKey::RD, PhysicalKey::Code(KeyCode::KeyK)); mapper.bind_key(SimId::Player1, VBKey::RR, PhysicalKey::Code(KeyCode::KeyL)); mapper.bind_key( SimId::Player1, VBKey::LU, PhysicalKey::Code(KeyCode::ArrowUp), ); mapper.bind_key( SimId::Player1, VBKey::LL, PhysicalKey::Code(KeyCode::ArrowLeft), ); mapper.bind_key( SimId::Player1, VBKey::LD, PhysicalKey::Code(KeyCode::ArrowDown), ); mapper.bind_key( SimId::Player1, VBKey::LR, PhysicalKey::Code(KeyCode::ArrowRight), ); mapper } pub fn binding_names(&self, sim_id: &SimId) -> HashMap { let Some(bindings) = self.vb_bindings.get(sim_id) else { return HashMap::new(); }; bindings .iter() .map(|(k, v)| { let name = match v { PhysicalKey::Code(code) => format!("{code:?}"), k => format!("{:?}", k), }; (*k, name) }) .collect() } pub fn bind_key(&mut self, sim_id: SimId, vb: VBKey, key: PhysicalKey) { let vb_bindings = self.vb_bindings.entry(sim_id).or_default(); if let Some(old) = vb_bindings.insert(vb, key) { self.key_bindings.remove(&old); } self.key_bindings.insert(key, (sim_id, vb)); } pub fn clear_binding(&mut self, sim_id: SimId, vb: VBKey) { let vb_bindings = self.vb_bindings.entry(sim_id).or_default(); if let Some(old) = vb_bindings.remove(&vb) { self.key_bindings.remove(&old); } } pub fn key_event(&self, event: &KeyEvent) -> Option<(SimId, VBKey)> { self.key_bindings.get(&event.physical_key).copied() } }