From 1211d4fdcc0ac80f8ce2f3a3c941e106702f1368 Mon Sep 17 00:00:00 2001 From: Ry Date: Fri, 16 Sep 2022 18:34:16 -0700 Subject: [PATCH] Use a more reliable method for detecting key presses --- src/keyboard.rs | 98 ++++++++++++++++++++++++++++++++++++++++++++++--- src/main.rs | 10 ++--- 2 files changed, 96 insertions(+), 12 deletions(-) diff --git a/src/keyboard.rs b/src/keyboard.rs index f9ec083..57926ae 100644 --- a/src/keyboard.rs +++ b/src/keyboard.rs @@ -3,24 +3,112 @@ use crate::warn; use ringbuf::{Consumer, Producer, RingBuffer}; +use winit::event::{ElementState, VirtualKeyCode}; pub struct Keyboard { - consumer: Consumer, - producer: Producer, + consumer: Consumer, + producer: Producer, } impl Keyboard { pub fn new() -> Self { - let buffer = RingBuffer::::new(32); + let buffer = RingBuffer::::new(32); let (producer, consumer) = buffer.split(); Keyboard { consumer, producer } } - pub fn push(&mut self, scancode: u32) { + fn keycode_to_scancode(&self, keycode: VirtualKeyCode) -> u8 { + match keycode { + VirtualKeyCode::Escape => 0x01, + VirtualKeyCode::Key1 => 0x02, + VirtualKeyCode::Key2 => 0x03, + VirtualKeyCode::Key3 => 0x04, + VirtualKeyCode::Key4 => 0x05, + VirtualKeyCode::Key5 => 0x06, + VirtualKeyCode::Key6 => 0x07, + VirtualKeyCode::Key7 => 0x08, + VirtualKeyCode::Key8 => 0x09, + VirtualKeyCode::Key9 => 0x0A, + VirtualKeyCode::Key0 => 0x0B, + VirtualKeyCode::Minus => 0x0C, + VirtualKeyCode::Equals => 0x0D, + VirtualKeyCode::Back => 0x0E, + VirtualKeyCode::Tab => 0x0F, + VirtualKeyCode::Q => 0x10, + VirtualKeyCode::W => 0x11, + VirtualKeyCode::E => 0x12, + VirtualKeyCode::R => 0x13, + VirtualKeyCode::T => 0x14, + VirtualKeyCode::Y => 0x15, + VirtualKeyCode::U => 0x16, + VirtualKeyCode::I => 0x17, + VirtualKeyCode::O => 0x18, + VirtualKeyCode::P => 0x19, + VirtualKeyCode::LBracket => 0x1A, + VirtualKeyCode::RBracket => 0x1B, + VirtualKeyCode::Return => 0x1C, + VirtualKeyCode::LControl => 0x1D, + VirtualKeyCode::A => 0x1E, + VirtualKeyCode::S => 0x1F, + VirtualKeyCode::D => 0x20, + VirtualKeyCode::F => 0x21, + VirtualKeyCode::G => 0x22, + VirtualKeyCode::H => 0x23, + VirtualKeyCode::J => 0x24, + VirtualKeyCode::K => 0x25, + VirtualKeyCode::L => 0x26, + VirtualKeyCode::Semicolon => 0x27, + VirtualKeyCode::Apostrophe => 0x28, + VirtualKeyCode::Grave => 0x29, + VirtualKeyCode::LShift => 0x2A, + VirtualKeyCode::Backslash => 0x2B, + VirtualKeyCode::Z => 0x2C, + VirtualKeyCode::X => 0x2D, + VirtualKeyCode::C => 0x2E, + VirtualKeyCode::V => 0x2F, + VirtualKeyCode::B => 0x30, + VirtualKeyCode::N => 0x31, + VirtualKeyCode::M => 0x32, + VirtualKeyCode::Comma => 0x33, + VirtualKeyCode::Period => 0x34, + VirtualKeyCode::Slash => 0x35, + VirtualKeyCode::RShift => 0x36, + VirtualKeyCode::LAlt => 0x38, + VirtualKeyCode::Space => 0x39, + VirtualKeyCode::Capital => 0x3A, + VirtualKeyCode::F1 => 0x3B, + VirtualKeyCode::F2 => 0x3C, + VirtualKeyCode::F3 => 0x3D, + VirtualKeyCode::F4 => 0x3E, + VirtualKeyCode::F5 => 0x3F, + VirtualKeyCode::F6 => 0x40, + VirtualKeyCode::F7 => 0x41, + VirtualKeyCode::F8 => 0x42, + VirtualKeyCode::F9 => 0x43, + VirtualKeyCode::F10 => 0x44, + VirtualKeyCode::F11 => 0x57, + VirtualKeyCode::F12 => 0x58, + VirtualKeyCode::Up => 0x67, + VirtualKeyCode::Down => 0x6C, + VirtualKeyCode::Left => 0x69, + VirtualKeyCode::Right => 0x6A, + _ => 0x00, + } + } + + pub fn push(&mut self, keycode: Option, state: ElementState) { + let mut scancode = if let Some(keycode) = keycode { + self.keycode_to_scancode(keycode) + } else { + 0x00 + }; + if state == ElementState::Released && scancode != 0x00 { + scancode |= 0x80; // "break" scancode + } self.producer.push(scancode).unwrap_or_else(|_| warn("keyboard buffer full!")); } - pub fn pop(&mut self) -> u32 { + pub fn pop(&mut self) -> u8 { self.consumer.pop().unwrap_or_default() } } diff --git a/src/main.rs b/src/main.rs index 6e3918d..e2f00e6 100644 --- a/src/main.rs +++ b/src/main.rs @@ -28,7 +28,7 @@ use image; use log::error; use pixels::{Pixels, SurfaceTexture}; use winit::dpi::LogicalSize; -use winit::event::{ElementState, Event, WindowEvent}; +use winit::event::{Event, WindowEvent}; use winit::event_loop::{ControlFlow, EventLoop}; use winit::window::{WindowBuilder, Icon}; use winit_input_helper::WinitInputHelper; @@ -228,12 +228,8 @@ fn main() { if let Event::WindowEvent { ref event, .. } = event { if let WindowEvent::KeyboardInput { input, .. } = event { let mut keyboard_lock = keyboard.lock().unwrap(); - let mut scancode = input.scancode; - if input.state == ElementState::Released { - scancode |= 0x80; // "break" scancode - } - //println!("scancode: {:x}", scancode); - keyboard_lock.push(scancode); + let keycode = input.virtual_keycode; + keyboard_lock.push(keycode, input.state); } }