mirror of
https://github.com/ringtailsoftware/uvm32.git
synced 2026-06-05 22:43:39 +00:00
Fix sticky keys in doom. host-sdl only reported the last key pressed, now uses a circular buffer.
This commit is contained in:
parent
49a94ca174
commit
e524ea4815
1 changed files with 36 additions and 17 deletions
|
|
@ -19,13 +19,36 @@
|
||||||
#define WIDTH 320
|
#define WIDTH 320
|
||||||
#define HEIGHT 200
|
#define HEIGHT 200
|
||||||
|
|
||||||
#define WINDOW_WIDTH WIDTH*2
|
#define WINDOW_WIDTH WIDTH*3
|
||||||
#define WINDOW_HEIGHT HEIGHT*2
|
#define WINDOW_HEIGHT HEIGHT*3
|
||||||
|
|
||||||
// TBD replace with queue of keypresses
|
// circular buffer of keypresses, so vm code can read them as it's ready
|
||||||
uint16_t last_keyscancode;
|
typedef struct {
|
||||||
bool last_keyvalid = false;
|
bool down;
|
||||||
bool last_keypressed = false;
|
uint16_t scancode;
|
||||||
|
} keyevent_t;
|
||||||
|
|
||||||
|
#define KEYBUFFER_LEN 8
|
||||||
|
static keyevent_t keyBuffer[KEYBUFFER_LEN];
|
||||||
|
static int keyBufferWr = 0;
|
||||||
|
static int keyBufferRd = 0;
|
||||||
|
|
||||||
|
void key_enq(uint16_t scancode, bool down) {
|
||||||
|
keyBuffer[keyBufferWr].scancode = scancode;
|
||||||
|
keyBuffer[keyBufferWr].down = down;
|
||||||
|
|
||||||
|
keyBufferWr = (keyBufferWr + 1) % KEYBUFFER_LEN;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool key_deq(keyevent_t *ke) {
|
||||||
|
if (keyBufferWr != keyBufferRd) {
|
||||||
|
*ke = keyBuffer[keyBufferRd];
|
||||||
|
keyBufferRd = (keyBufferRd + 1) % KEYBUFFER_LEN;
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static uint8_t *read_file(const char* filename, int *len) {
|
static uint8_t *read_file(const char* filename, int *len) {
|
||||||
FILE* f = fopen(filename, "rb");
|
FILE* f = fopen(filename, "rb");
|
||||||
|
|
@ -185,16 +208,12 @@ int main(int argc, char *argv[]) {
|
||||||
break;
|
break;
|
||||||
case SDL_EVENT_KEY_DOWN:
|
case SDL_EVENT_KEY_DOWN:
|
||||||
if (!event.key.repeat) {
|
if (!event.key.repeat) {
|
||||||
last_keyscancode = event.key.scancode;
|
key_enq(event.key.scancode, true);
|
||||||
last_keypressed = true;
|
|
||||||
last_keyvalid = true;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SDL_EVENT_KEY_UP:
|
case SDL_EVENT_KEY_UP:
|
||||||
if (!event.key.repeat) {
|
if (!event.key.repeat) {
|
||||||
last_keyscancode = event.key.scancode;
|
key_enq(event.key.scancode, false);
|
||||||
last_keypressed = false;
|
|
||||||
last_keyvalid = true;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -281,15 +300,15 @@ int main(int argc, char *argv[]) {
|
||||||
SDL_RenderTexture(renderer, render_target, &src_rect, &dst_rect);
|
SDL_RenderTexture(renderer, render_target, &src_rect, &dst_rect);
|
||||||
SDL_RenderPresent(renderer);
|
SDL_RenderPresent(renderer);
|
||||||
} break;
|
} break;
|
||||||
case UVM32_SYSCALL_GETKEY:
|
case UVM32_SYSCALL_GETKEY: {
|
||||||
if (last_keyvalid) {
|
keyevent_t ke;
|
||||||
uint32_t code = (last_keypressed ? 0x80000000 : 0) | last_keyscancode;
|
if (key_deq(&ke)) {
|
||||||
|
uint32_t code = (ke.down ? 0x80000000 : 0) | ke.scancode;
|
||||||
uvm32_arg_setval(vmst, &evt, RET, code);
|
uvm32_arg_setval(vmst, &evt, RET, code);
|
||||||
} else {
|
} else {
|
||||||
uvm32_arg_setval(vmst, &evt, RET, 0xFFFFFFFF);
|
uvm32_arg_setval(vmst, &evt, RET, 0xFFFFFFFF);
|
||||||
}
|
}
|
||||||
last_keyvalid = false;
|
} break;
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
printf("Unhandled syscall 0x%08x\n", evt.data.syscall.code);
|
printf("Unhandled syscall 0x%08x\n", evt.data.syscall.code);
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue