use minifb::Key;
use spectrusty::peripherals::{ZXKeyboardMap,
joystick::{JoystickInterface, Directions},
serial::KeypadKeys
};
type ZXk = ZXKeyboardMap;
pub fn map_direct_key(key: Key) -> ZXKeyboardMap {
match key {
Key::Key1 => ZXk::N1,
Key::Key2 => ZXk::N2,
Key::Key3 => ZXk::N3,
Key::Key4 => ZXk::N4,
Key::Key5 => ZXk::N5,
Key::Key6 => ZXk::N6,
Key::Key7 => ZXk::N7,
Key::Key8 => ZXk::N8,
Key::Key9 => ZXk::N9,
Key::Key0 => ZXk::N0,
Key::A => ZXk::A,
Key::B => ZXk::B,
Key::C => ZXk::C,
Key::D => ZXk::D,
Key::E => ZXk::E,
Key::F => ZXk::F,
Key::G => ZXk::G,
Key::H => ZXk::H,
Key::I => ZXk::I,
Key::J => ZXk::J,
Key::K => ZXk::K,
Key::L => ZXk::L,
Key::M => ZXk::M,
Key::N => ZXk::N,
Key::O => ZXk::O,
Key::P => ZXk::P,
Key::Q => ZXk::Q,
Key::R => ZXk::R,
Key::S => ZXk::S,
Key::T => ZXk::T,
Key::U => ZXk::U,
Key::V => ZXk::V,
Key::W => ZXk::W,
Key::X => ZXk::X,
Key::Y => ZXk::Y,
Key::Z => ZXk::Z,
Key::LeftShift|Key::RightShift => ZXk::CS,
Key::LeftCtrl|Key::RightCtrl => ZXk::SS,
Key::Space => ZXk::BR,
Key::Enter => ZXk::EN,
_ => ZXk::empty()
}
}
pub fn map_combined_keys(key: Key, pressed: bool, shift_down: bool) -> (ZXKeyboardMap, bool) {
let mut removecs = false;
let zxk = match key {
Key::Left => ZXk::CS|ZXk::N5,
Key::Down => ZXk::CS|ZXk::N6,
Key::Up => ZXk::CS|ZXk::N7,
Key::Right => ZXk::CS|ZXk::N8,
Key::CapsLock => ZXk::CS|ZXk::N2,
Key::Backspace => ZXk::CS|ZXk::N0,
Key::LeftAlt|Key::RightAlt => ZXk::CS|ZXk::SS,
Key::LeftBracket => ZXk::SS|ZXk::N8,
Key::RightBracket => ZXk::SS|ZXk::N9,
Key::Backquote => ZXk::SS|ZXk::X,
Key::Minus if pressed => if shift_down {
removecs = true;
ZXk::SS|ZXk::N0
}
else {
ZXk::SS|ZXk::J
},
Key::Minus => ZXk::SS|ZXk::J|ZXk::N0,
Key::Equal if pressed => if shift_down {
removecs = true;
ZXk::SS|ZXk::K
}
else {
ZXk::SS|ZXk::L
},
Key::Equal => ZXk::SS|ZXk::K|ZXk::L,
Key::Comma if pressed => if shift_down {
removecs = true;
ZXk::SS|ZXk::R
}
else {
ZXk::SS|ZXk::N
},
Key::Comma => ZXk::SS|ZXk::R|ZXk::N,
Key::Period if pressed => if shift_down {
removecs = true;
ZXk::SS|ZXk::T
}
else {
ZXk::SS|ZXk::M
},
Key::Period => ZXk::SS|ZXk::T|ZXk::M,
Key::Apostrophe if pressed => if shift_down {
removecs = true;
ZXk::SS|ZXk::P
}
else {
ZXk::SS|ZXk::N7
},
Key::Apostrophe => ZXk::SS|ZXk::P|ZXk::N7,
Key::Slash if pressed => if shift_down {
removecs = true;
ZXk::SS|ZXk::C
}
else {
ZXk::SS|ZXk::V
},
Key::Slash => ZXk::SS|ZXk::C|ZXk::V,
Key::Semicolon if pressed => if shift_down {
removecs = true;
ZXk::SS|ZXk::Z
}
else {
ZXk::SS|ZXk::O
},
Key::Semicolon => ZXk::SS|ZXk::Z|ZXk::O,
k => map_direct_key(k)
};
(zxk, removecs)
}
pub fn update_keymap(
mut cur: ZXKeyboardMap,
key: Key,
pressed: bool,
shift_down: bool,
ctrl_down: bool
) -> ZXKeyboardMap
{
let (chg, removecs) = map_combined_keys(key, pressed, shift_down);
if pressed {
cur.insert(chg);
if removecs {
cur.remove(ZXk::CS);
}
}
else {
cur.remove(chg);
}
if cur.is_empty() {
if shift_down {
cur.insert(ZXk::CS);
}
if ctrl_down {
cur.insert(ZXk::SS);
}
}
cur
}
pub fn map_keypad_key(key: Key, parens: bool) -> KeypadKeys {
match key {
Key::NumPadSlash if parens => KeypadKeys::LPAREN,
Key::NumPadSlash => KeypadKeys::DIVIDE,
Key::NumPadAsterisk if parens => KeypadKeys::RPAREN,
Key::NumPadAsterisk => KeypadKeys::MULTIPLY,
Key::NumPadMinus => KeypadKeys::MINUS,
Key::NumPadPlus => KeypadKeys::PLUS,
Key::NumPadEnter => KeypadKeys::ENTER,
Key::NumPad1 => KeypadKeys::N1,
Key::NumPad2 => KeypadKeys::N2,
Key::NumPad3 => KeypadKeys::N3,
Key::NumPad4 => KeypadKeys::N4,
Key::NumPad5 => KeypadKeys::N5,
Key::NumPad6 => KeypadKeys::N6,
Key::NumPad7 => KeypadKeys::N7,
Key::NumPad8 => KeypadKeys::N8,
Key::NumPad9 => KeypadKeys::N9,
Key::NumPad0 => KeypadKeys::N0,
Key::NumPadDot => KeypadKeys::PERIOD,
_ => KeypadKeys::empty()
}
}
pub fn update_keypad_keys(mut cur: KeypadKeys, key: Key, pressed: bool, parens: bool) -> KeypadKeys {
let chg = map_keypad_key(key, parens);
if !chg.is_empty() {
cur.set(chg, pressed);
}
cur
}
pub fn map_key_to_direction(key: Key) -> Directions {
match key {
Key::Up => Directions::UP,
Key::Right => Directions::RIGHT,
Key::Down => Directions::DOWN,
Key::Left => Directions::LEFT,
_ => Directions::empty()
}
}
#[inline]
pub fn update_joystick_from_key_event<'a, J, F>(
key: Key,
pressed: bool,
fire_key: Key,
get_joy: F
) -> bool
where J: 'a + JoystickInterface + ?Sized,
F: FnOnce() -> Option<&'a mut J>
{
super::update_joystick_from_key_event(key, pressed, fire_key, map_key_to_direction, get_joy)
}