fix: VirtIO keyboard input latency and direction accuracy
- Driver now drains SYN/repeat/unknown events in a loop instead of returning None on the first non-key event - Snake drains all pending input events per tick, applies only the latest direction change (prevents stale event accumulation)
This commit is contained in:
@@ -65,16 +65,19 @@ extern "C" fn main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn handle_input(snake: &mut Snake) {
|
fn handle_input(snake: &mut Snake) {
|
||||||
let _ = syscall::send(INPUT_EP, 0, 0, 0, 0);
|
// Drain all pending events, apply the latest direction
|
||||||
let (tag, kind, _, _) = syscall::receive(INPUT_EP);
|
loop {
|
||||||
|
let _ = syscall::send(INPUT_EP, 0, 0, 0, 0);
|
||||||
if tag == 1 {
|
let (tag, kind, _, _) = syscall::receive(INPUT_EP);
|
||||||
match kind {
|
if tag == 0 { break; } // NoEvent — queue drained
|
||||||
0 => snake.set_direction(Direction::Up),
|
if tag == 1 {
|
||||||
1 => snake.set_direction(Direction::Down),
|
match kind {
|
||||||
2 => snake.set_direction(Direction::Left),
|
0 => snake.set_direction(Direction::Up),
|
||||||
3 => snake.set_direction(Direction::Right),
|
1 => snake.set_direction(Direction::Down),
|
||||||
_ => {}
|
2 => snake.set_direction(Direction::Left),
|
||||||
|
3 => snake.set_direction(Direction::Right),
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -129,28 +129,29 @@ fn linux_keycode_to_key(code: u16) -> Option<Key> {
|
|||||||
|
|
||||||
impl InputDevice for VirtioInputDevice {
|
impl InputDevice for VirtioInputDevice {
|
||||||
fn poll(&mut self) -> Option<InputEvent> {
|
fn poll(&mut self) -> Option<InputEvent> {
|
||||||
let current_used = self.used_idx();
|
loop {
|
||||||
if current_used == self.last_used {
|
let current_used = self.used_idx();
|
||||||
return None;
|
if current_used == self.last_used {
|
||||||
}
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
let desc_idx = self.used_entry_id(self.last_used);
|
let desc_idx = self.used_entry_id(self.last_used);
|
||||||
self.last_used = self.last_used.wrapping_add(1);
|
self.last_used = self.last_used.wrapping_add(1);
|
||||||
|
|
||||||
let (ev_type, ev_code, ev_value) = self.read_event(desc_idx);
|
let (ev_type, ev_code, ev_value) = self.read_event(desc_idx);
|
||||||
self.resubmit(desc_idx);
|
self.resubmit(desc_idx);
|
||||||
|
|
||||||
if ev_type == EV_KEY {
|
if ev_type == EV_KEY {
|
||||||
if let Some(key) = linux_keycode_to_key(ev_code) {
|
if let Some(key) = linux_keycode_to_key(ev_code) {
|
||||||
if ev_value == KEY_PRESS {
|
if ev_value == KEY_PRESS {
|
||||||
return Some(InputEvent::KeyDown(key));
|
return Some(InputEvent::KeyDown(key));
|
||||||
} else if ev_value == 0 {
|
} else if ev_value == 0 {
|
||||||
return Some(InputEvent::KeyUp(key));
|
return Some(InputEvent::KeyUp(key));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Skip SYN events, repeats, and unknown keys — keep draining
|
||||||
}
|
}
|
||||||
|
|
||||||
None
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn has_event(&self) -> bool {
|
fn has_event(&self) -> bool {
|
||||||
|
|||||||
Reference in New Issue
Block a user