Added keyrepeat support to keyboard

This commit is contained in:
rxi
2016-09-25 21:00:43 +01:00
parent d9ddfea4df
commit 06cb68125a
2 changed files with 27 additions and 17 deletions

View File

@@ -14,10 +14,14 @@
#include "keyboard.h" #include "keyboard.h"
#define KEYBOARD_KEY_MAX 256 #define KEYBOARD_KEY_MAX 256
#define BUFFER_SIZE 32
#define BUFFER_MASK (BUFFER_SIZE - 1)
typedef struct { unsigned char type, code, isrepeat; } KeyEvent;
volatile char keyboard_keyStates[KEYBOARD_KEY_MAX]; volatile char keyboard_keyStates[KEYBOARD_KEY_MAX];
volatile struct { volatile struct {
struct { unsigned char type; unsigned char code; } data[32]; KeyEvent data[32];
int readi, writei; int readi, writei;
} keyboard_events; } keyboard_events;
@@ -33,25 +37,28 @@ void keyboard_handler() {
extended = 1 << 7; extended = 1 << 7;
} else { } else {
volatile KeyEvent *e;
/* Handle key up / down */ /* Handle key up / down */
if (code & (1 << 7)) { if (code & (1 << 7)) {
/* Key up */ /* Key up */
code &= ~(1 << 7); code &= ~(1 << 7);
code |= extended; code |= extended;
keyboard_keyStates[code] = 0; e = &keyboard_events.data[keyboard_events.writei & BUFFER_MASK];
keyboard_events.data[keyboard_events.writei & 31].code = code; e->code = code;
keyboard_events.data[keyboard_events.writei & 31].type = 0; e->type = 0;
e->isrepeat = 0;
keyboard_events.writei++; keyboard_events.writei++;
keyboard_keyStates[code] = 0;
} else { } else {
/* Key down */ /* Key down */
code |= extended; code |= extended;
if (!keyboard_keyStates[code]) { /* Ignore key repeat */ e = &keyboard_events.data[keyboard_events.writei & BUFFER_MASK];
keyboard_keyStates[code] = 1; e->code = code;
keyboard_events.data[keyboard_events.writei & 31].code = code; e->type = 1;
keyboard_events.data[keyboard_events.writei & 31].type = 1; e->isrepeat = keyboard_keyStates[code];
keyboard_events.writei++; keyboard_events.writei++;
} keyboard_keyStates[code] = 1;
} }
extended = 0x0; extended = 0x0;
} }
@@ -238,16 +245,19 @@ int l_keyboard_poll(lua_State *L) {
while (keyboard_events.readi != keyboard_events.writei) { while (keyboard_events.readi != keyboard_events.writei) {
lua_newtable(L); lua_newtable(L);
int type = keyboard_events.data[keyboard_events.readi & 31].type; KeyEvent e = keyboard_events.data[keyboard_events.readi & BUFFER_MASK];
int code = keyboard_events.data[keyboard_events.readi & 31].code; e.code &= 127;
code &= 127;
lua_pushstring(L, type ? "down" : "up"); lua_pushstring(L, e.type ? "down" : "up");
lua_setfield(L, -2, "type"); lua_setfield(L, -2, "type");
lua_pushnumber(L, code); lua_pushnumber(L, e.code);
lua_setfield(L, -2, "code"); lua_setfield(L, -2, "code");
lua_pushstring(L, scancodeMap[code]); lua_pushstring(L, scancodeMap[e.code]);
lua_setfield(L, -2, "key"); lua_setfield(L, -2, "key");
if (e.type) { /* Only set `isrepeat` field for keydown event */
lua_pushboolean(L, e.isrepeat);
lua_setfield(L, -2, "isrepeat");
}
lua_rawseti(L, -2, idx++); lua_rawseti(L, -2, idx++);
keyboard_events.readi++; keyboard_events.readi++;

View File

@@ -77,7 +77,7 @@ int main(void) {
/* Keyboard events */ /* Keyboard events */
"for _, e in ipairs(love.keyboard.poll()) do\n" "for _, e in ipairs(love.keyboard.poll()) do\n"
"if e.type == 'down' then\n" "if e.type == 'down' then\n"
"if love.keypressed then love.keypressed(e.key, e.code) end\n" "if love.keypressed then love.keypressed(e.key, e.code, e.isrepeat) end\n"
"elseif e.type == 'up' then\n" "elseif e.type == 'up' then\n"
"if love.keyreleased then love.keyreleased(e.key, e.code) end\n" "if love.keyreleased then love.keyreleased(e.key, e.code) end\n"
"elseif e.type == 'text' then\n" "elseif e.type == 'text' then\n"