use server_framework::{Decode, Encode}; pub use port_input_device::{Key, GamepadButton, Axis, InputEvent}; #[derive(Debug, PartialEq)] pub enum InputRequest { PollEvent, WaitEvent, } #[derive(Debug, PartialEq)] pub enum InputResponse { Event(InputEvent), NoEvent, } impl Encode for InputRequest { fn encode(&self) -> [usize; 4] { match self { InputRequest::PollEvent => [0, 0, 0, 0], InputRequest::WaitEvent => [1, 0, 0, 0], } } } impl Decode for InputRequest { fn decode(words: [usize; 4]) -> Option { match words[0] { 0 => Some(InputRequest::PollEvent), 1 => Some(InputRequest::WaitEvent), _ => None, } } } const EV_KEY_DOWN: usize = 1; const EV_KEY_UP: usize = 2; const EV_PTR_DOWN: usize = types::input::event::POINTER_DOWN; const EV_PTR_MOVE: usize = types::input::event::POINTER_MOVE; const EV_PTR_UP: usize = types::input::event::POINTER_UP; const EV_SCROLL: usize = 6; const EV_GAMEPAD_BTN: usize = 7; const EV_GAMEPAD_AXIS: usize = 8; fn encode_key(key: Key) -> (usize, usize) { match key { Key::Up => (0, 0), Key::Down => (1, 0), Key::Left => (2, 0), Key::Right => (3, 0), Key::Enter => (4, 0), Key::Escape => (5, 0), Key::Space => (6, 0), Key::Backspace => (7, 0), Key::Tab => (8, 0), Key::Char(c) => (9, c as usize), Key::Function(n) => (types::input::event::FUNCTION_KEY, n as usize), } } fn decode_key(kind: usize, data: usize) -> Option { match kind { 0 => Some(Key::Up), 1 => Some(Key::Down), 2 => Some(Key::Left), 3 => Some(Key::Right), 4 => Some(Key::Enter), 5 => Some(Key::Escape), 6 => Some(Key::Space), 7 => Some(Key::Backspace), 8 => Some(Key::Tab), 9 => Some(Key::Char(data as u8)), types::input::event::FUNCTION_KEY => Some(Key::Function(data as u8)), _ => None, } } fn encode_pointer(id: u8, x: u16, y: u16) -> (usize, usize) { (id as usize, (x as usize) | ((y as usize) << 16)) } fn decode_pointer(w1: usize, w2: usize) -> (u8, u16, u16) { (w1 as u8, (w2 & 0xFFFF) as u16, ((w2 >> 16) & 0xFFFF) as u16) } fn encode_gamepad_button(button: GamepadButton) -> usize { match button { GamepadButton::South => 0, GamepadButton::East => 1, GamepadButton::North => 2, GamepadButton::West => 3, GamepadButton::DpadUp => 4, GamepadButton::DpadDown => 5, GamepadButton::DpadLeft => 6, GamepadButton::DpadRight => 7, GamepadButton::Start => 8, GamepadButton::Select => 9, } } fn decode_gamepad_button(v: usize) -> Option { match v { 0 => Some(GamepadButton::South), 1 => Some(GamepadButton::East), 2 => Some(GamepadButton::North), 3 => Some(GamepadButton::West), 4 => Some(GamepadButton::DpadUp), 5 => Some(GamepadButton::DpadDown), 6 => Some(GamepadButton::DpadLeft), 7 => Some(GamepadButton::DpadRight), 8 => Some(GamepadButton::Start), 9 => Some(GamepadButton::Select), _ => None, } } fn encode_axis(axis: Axis) -> usize { match axis { Axis::LeftX => 0, Axis::LeftY => 1, Axis::RightX => 2, Axis::RightY => 3, } } fn decode_axis(v: usize) -> Option { match v { 0 => Some(Axis::LeftX), 1 => Some(Axis::LeftY), 2 => Some(Axis::RightX), 3 => Some(Axis::RightY), _ => None, } } impl Encode for InputResponse { fn encode(&self) -> [usize; 4] { match self { InputResponse::NoEvent => [0, 0, 0, 0], InputResponse::Event(event) => match event { InputEvent::KeyDown(key) => { let (k, d) = encode_key(*key); [EV_KEY_DOWN, k, d, 0] } InputEvent::KeyUp(key) => { let (k, d) = encode_key(*key); [EV_KEY_UP, k, d, 0] } InputEvent::PointerDown { id, x, y } => { let (w1, w2) = encode_pointer(*id, *x, *y); [EV_PTR_DOWN, w1, w2, 0] } InputEvent::PointerMove { id, x, y } => { let (w1, w2) = encode_pointer(*id, *x, *y); [EV_PTR_MOVE, w1, w2, 0] } InputEvent::PointerUp { id, x, y } => { let (w1, w2) = encode_pointer(*id, *x, *y); [EV_PTR_UP, w1, w2, 0] } InputEvent::Scroll { dx, dy } => { [EV_SCROLL, *dx as usize, *dy as usize, 0] } InputEvent::GamepadButton { button, pressed } => { [EV_GAMEPAD_BTN, encode_gamepad_button(*button), *pressed as usize, 0] } InputEvent::GamepadAxis { axis, value } => { [EV_GAMEPAD_AXIS, encode_axis(*axis), *value as usize, 0] } }, } } } impl Decode for InputResponse { fn decode(words: [usize; 4]) -> Option { match words[0] { 0 => Some(InputResponse::NoEvent), EV_KEY_DOWN => { let key = decode_key(words[1], words[2])?; Some(InputResponse::Event(InputEvent::KeyDown(key))) } EV_KEY_UP => { let key = decode_key(words[1], words[2])?; Some(InputResponse::Event(InputEvent::KeyUp(key))) } EV_PTR_DOWN => { let (id, x, y) = decode_pointer(words[1], words[2]); Some(InputResponse::Event(InputEvent::PointerDown { id, x, y })) } EV_PTR_MOVE => { let (id, x, y) = decode_pointer(words[1], words[2]); Some(InputResponse::Event(InputEvent::PointerMove { id, x, y })) } EV_PTR_UP => { let (id, x, y) = decode_pointer(words[1], words[2]); Some(InputResponse::Event(InputEvent::PointerUp { id, x, y })) } EV_SCROLL => { Some(InputResponse::Event(InputEvent::Scroll { dx: words[1] as i16, dy: words[2] as i16, })) } EV_GAMEPAD_BTN => { let button = decode_gamepad_button(words[1])?; Some(InputResponse::Event(InputEvent::GamepadButton { button, pressed: words[2] != 0, })) } EV_GAMEPAD_AXIS => { let axis = decode_axis(words[1])?; Some(InputResponse::Event(InputEvent::GamepadAxis { axis, value: words[2] as i16, })) } _ => None, } } }