From 1892fb9f189de95b26492d71822da9bafe621b16 Mon Sep 17 00:00:00 2001 From: Alan Jian Date: Thu, 4 Aug 2022 14:52:03 +0800 Subject: [PATCH] Add the suppport for input event specific system calls This commit adds the support for the new event system in rv32emu, by invoking system call poll_event to accept input specific events, we can now move the character and control the menu with the keyboard, adjust the view angle with the mouse in relative mode and use the mouse to control weapon. --- include/quakembd.h | 17 ++-- port/boards/rv32emu/display.c | 4 +- port/boards/rv32emu/main.c | 158 ++++++++++++++++++++++++++++++++-- port/in_port.c | 39 +++------ port/sys_port.c | 2 +- 5 files changed, 178 insertions(+), 42 deletions(-) diff --git a/include/quakembd.h b/include/quakembd.h index 7b6dd97..f7c93e6 100644 --- a/include/quakembd.h +++ b/include/quakembd.h @@ -53,14 +53,19 @@ #define bail(msg) { qembd_error(msg); goto bail; } typedef struct { - uint8_t code; - uint8_t down; + uint32_t keycode; + uint8_t state; } key_event_t; typedef struct { - int x; - int y; -} mouse_position_t; + int32_t xrel; + int32_t yrel; +} mouse_motion_t; + +typedef struct { + int32_t x; + int32_t y; +} mouse_movement_t; int qembd_get_width(); int qembd_get_height(); @@ -72,6 +77,6 @@ void qembd_udelay(uint32_t us); void *qembd_allocmain(size_t size); int qembd_main(int c, char **v); int qembd_dequeue_key_event(key_event_t *e); -int qembd_get_current_position(mouse_position_t *position); +int qembd_get_mouse_movement(mouse_movement_t *movement); #endif /* __QUAKEMBD_H */ \ No newline at end of file diff --git a/port/boards/rv32emu/display.c b/port/boards/rv32emu/display.c index 4b9edb6..d95f149 100644 --- a/port/boards/rv32emu/display.c +++ b/port/boards/rv32emu/display.c @@ -46,7 +46,7 @@ void qembd_vidinit() register int a7 asm("a7") = syscall_draw_frame; asm volatile("scall" - : "r+"(a0) : "r"(a1), "r"(a2), "r"(a7)); + : "+r"(a0) : "r"(a1), "r"(a2), "r"(a7)); } void qembd_fillrect(uint8_t *src, uint32_t *clut, @@ -67,5 +67,5 @@ void qembd_refresh() register int a7 asm("a7") = syscall_draw_frame; asm volatile("scall" - : "r+"(a0) : "r"(a1), "r"(a2), "r"(a7)); + : "+r"(a0) : "r"(a1), "r"(a2), "r"(a7)); } diff --git a/port/boards/rv32emu/main.c b/port/boards/rv32emu/main.c index 7d8b79a..6a77f17 100644 --- a/port/boards/rv32emu/main.c +++ b/port/boards/rv32emu/main.c @@ -16,10 +16,40 @@ */ #include +#include +#include #include #include #include -#include + +#define MOUSE_BUTTON_LEFT 1 +#define MOUSE_BUTTON_MIDDLE 2 +#define MOUSE_BUTTON_RIGHT 3 + +enum { + KEY_EVENT = 0, + MOUSE_MOTION_EVENT = 1, + MOUSE_BUTTON_EVENT = 2, +}; + +typedef struct { + uint8_t button; + uint8_t state; +} mouse_button_t; + +typedef struct { + uint32_t type; + union { + key_event_t key_event; + union { + mouse_motion_t motion; + mouse_button_t button; + } mouse; + }; +} event_t; + +static event_t event; +static mouse_movement_t mouse_movement; uint64_t qembd_get_us_time() { @@ -52,14 +82,132 @@ void *qembd_allocmain(size_t size) return malloc(size); } +static int poll_event() +{ + register int a0 asm("a0") = (uintptr_t) &event; + register int a7 asm("a7") = 0xc0de; + asm volatile("scall" : "+r"(a0) : "r"(a7)); + if (event.type == MOUSE_MOTION_EVENT) { + mouse_movement.x += event.mouse.motion.xrel; + mouse_movement.y += event.mouse.motion.yrel; + } + return a0; +} + int qembd_dequeue_key_event(key_event_t *e) { - /* Not Implemented */ + while (poll_event()) { + if (event.type == KEY_EVENT) { + *e = event.key_event; + /* remap keyode */ + switch (e->keycode) { + case 0x08: + e->keycode = K_BACKSPACE; + break; + case 0x40000052: + e->keycode = K_UPARROW; + break; + case 0x40000051: + e->keycode = K_DOWNARROW; + break; + case 0x40000050: + e->keycode = K_LEFTARROW; + break; + case 0x4000004F: + e->keycode = K_RIGHTARROW; + break; + case 0x400000E2: + e->keycode = K_ALT; + break; + case 0x400000E0: + e->keycode = K_CTRL; + break; + case 0x400000E1: + e->keycode = K_SHIFT; + break; + case 0x4000003A: + e->keycode = K_F1; + break; + case 0x4000003B: + e->keycode = K_F2; + break; + case 0x4000003C: + e->keycode = K_F3; + break; + case 0x4000003D: + e->keycode = K_F4; + break; + case 0x4000003E: + e->keycode = K_F5; + break; + case 0x4000003F: + e->keycode = K_F6; + break; + case 0x40000040: + e->keycode = K_F7; + break; + case 0x40000041: + e->keycode = K_F8; + break; + case 0x40000042: + e->keycode = K_F9; + break; + case 0x40000043: + e->keycode = K_F10; + break; + case 0x40000044: + e->keycode = K_F11; + break; + case 0x40000045: + e->keycode = K_F12; + break; + case 0x40000049: + e->keycode = K_INS; + break; + case 0x7f: + e->keycode = K_DEL; + break; + case 0x4000004E: + e->keycode = K_PGDN; + break; + case 0x4000004B: + e->keycode = K_PGUP; + break; + case 0x4000004A: + e->keycode = K_HOME; + break; + case 0x4000004D: + e->keycode = K_END; + break; + case 0x40000048: + e->keycode = K_PAUSE; + break; + } + return 0; + } + if (event.type == MOUSE_BUTTON_EVENT) { + e->state = event.mouse.button.state; + switch (event.mouse.button.button) { + case MOUSE_BUTTON_LEFT: + e->keycode = K_MOUSE1; + break; + case MOUSE_BUTTON_RIGHT: + e->keycode = K_MOUSE2; + break; + case MOUSE_BUTTON_MIDDLE: + e->keycode = K_MOUSE3; + break; + } + return 0; + } + } return -1; } -int qembd_get_current_position(mouse_position_t *position) +int qembd_get_mouse_movement(mouse_movement_t *movement) { - /* Not Implemented */ - return -1; + *movement = mouse_movement; + mouse_movement.x = 0; + mouse_movement.y = 0; + return 0; } diff --git a/port/in_port.c b/port/in_port.c index 77d3f54..6ab7f48 100644 --- a/port/in_port.c +++ b/port/in_port.c @@ -32,39 +32,22 @@ void IN_Commands(void) void IN_Move(usercmd_t *cmd) { - int mouse_x, mouse_y; - mouse_position_t position; + mouse_movement_t movement; int r; - r = qembd_get_current_position(&position); + r = qembd_get_mouse_movement(&movement); if (r != 0) return; - mouse_x = position.x - (qembd_get_width() / 2); - mouse_y = position.y - (qembd_get_height() / 2); + movement.x *= sensitivity.value; + movement.y *= sensitivity.value; - mouse_x *= sensitivity.value; - mouse_y *= sensitivity.value; - - if ((in_strafe.state & 1) || (lookstrafe.value && (in_mlook.state & 1))) - cmd->sidemove += m_side.value * mouse_x; - else - cl.viewangles[YAW] -= m_yaw.value * mouse_x; - - if (in_mlook.state & 1) - V_StopPitchDrift(); - - if ((in_mlook.state & 1) && !(in_strafe.state & 1)) { - cl.viewangles[PITCH] += m_pitch.value * mouse_y; - if (cl.viewangles[PITCH] > 80) - cl.viewangles[PITCH] = 80; - if (cl.viewangles[PITCH] < -70) - cl.viewangles[PITCH] = -70; - } else { - if ((in_strafe.state & 1) && noclip_anglehack) - cmd->upmove -= m_forward.value * mouse_y; - else - cmd->forwardmove -= m_forward.value * mouse_y; - } + V_StopPitchDrift(); + cl.viewangles[YAW] -= m_yaw.value * movement.x; + cl.viewangles[PITCH] += m_pitch.value * movement.y; + if (cl.viewangles[PITCH] > 80) + cl.viewangles[PITCH] = 80; + if (cl.viewangles[PITCH] < -70) + cl.viewangles[PITCH] = -70; } diff --git a/port/sys_port.c b/port/sys_port.c index 492b45f..bba8587 100644 --- a/port/sys_port.c +++ b/port/sys_port.c @@ -102,7 +102,7 @@ void Sys_SendKeyEvents(void) { key_event_t e; while (qembd_dequeue_key_event(&e) == 0) - Key_Event(e.code, e.down == 1); + Key_Event(e.keycode, e.state == 1); } void Sys_HighFPPrecision(void)