From a19dad718a768ad289b5d23ceeb9ee5728ce7703 Mon Sep 17 00:00:00 2001 From: rxi Date: Sat, 15 Oct 2016 15:35:08 +0100 Subject: [PATCH] Separated lua bindings from keyboard.c --- src/keyboard.c | 213 ++++++++++++++++----------------------- src/keyboard.h | 19 +++- src/modules/l_keyboard.c | 76 ++++++++++++++ 3 files changed, 183 insertions(+), 125 deletions(-) create mode 100644 src/modules/l_keyboard.c diff --git a/src/keyboard.c b/src/keyboard.c index 7aef929..533dba5 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -17,81 +17,7 @@ #define BUFFER_SIZE 32 #define BUFFER_MASK (BUFFER_SIZE - 1) -enum { KEY_UP, KEY_DOWN }; - -typedef struct { unsigned char type, code, isrepeat; } KeyEvent; - -volatile int keyboard_allowKeyRepeat = 0; -volatile char keyboard_keyStates[KEY_MAX]; - -volatile struct { - KeyEvent data[32]; - int readi, writei; -} keyboard_events; - -_go32_dpmi_seginfo old_keyb_handler_seginfo, new_keyb_handler_seginfo; - - -void keyboard_handler() { - static unsigned char code; - code = inportb(0x60); - - if (code != 224) { - volatile KeyEvent *e; - /* Handle key up / down */ - if (code & (1 << 7)) { - /* Key up */ - code &= ~(1 << 7); - keyboard_keyStates[code] = 0; - e = &keyboard_events.data[keyboard_events.writei & BUFFER_MASK]; - e->code = code; - e->type = KEY_UP; - e->isrepeat = 0; - keyboard_events.writei++; - - } else { - /* Key down */ - int isrepeat = keyboard_keyStates[code]; - if (!isrepeat || keyboard_allowKeyRepeat) { - keyboard_keyStates[code] = 1; - e = &keyboard_events.data[keyboard_events.writei & BUFFER_MASK]; - e->code = code; - e->type = KEY_DOWN; - e->isrepeat = isrepeat; - keyboard_events.writei++; - } - } - } - - outportb(0x20, 0x20); -} - - -void keyboard_handler_end() {} - - -int keyboard_init(void) { - _go32_dpmi_lock_data((char*)&keyboard_keyStates, KEY_MAX); - _go32_dpmi_lock_data((char*)&keyboard_events, sizeof(keyboard_events)); - _go32_dpmi_lock_code(keyboard_handler,(unsigned long)keyboard_handler_end - - (unsigned long)keyboard_handler); - _go32_dpmi_get_protected_mode_interrupt_vector(9, &old_keyb_handler_seginfo); - new_keyb_handler_seginfo.pm_offset = (int)keyboard_handler; - _go32_dpmi_chain_protected_mode_interrupt_vector(9, &new_keyb_handler_seginfo); - return 0; -} - - -void keyboard_deinit(void) { - _go32_dpmi_set_protected_mode_interrupt_vector(9, &old_keyb_handler_seginfo); -} - - -/** - * Lua binds - */ - -const char *scancodeMap[] = { +static const char *scancodeMap[] = { [ 0] = "?", [ 1] = "escape", [ 2] = "1", @@ -224,48 +150,101 @@ const char *scancodeMap[] = { }; -int l_keyboard_setKeyRepeat(lua_State *L) { - keyboard_allowKeyRepeat = lua_toboolean(L, 1); +volatile int keyboard_allowKeyRepeat = 0; +volatile char keyboard_keyStates[KEY_MAX]; + +typedef struct { unsigned char type, code, isrepeat; } KeyEvent; + +volatile struct { + KeyEvent data[32]; + int readi, writei; +} keyboard_events; + +_go32_dpmi_seginfo old_keyb_handler_seginfo, new_keyb_handler_seginfo; + + +void keyboard_handler() { + static unsigned char code; + code = inportb(0x60); + + if (code != 224) { + volatile KeyEvent *e; + /* Handle key up / down */ + if (code & (1 << 7)) { + /* Key up */ + code &= ~(1 << 7); + keyboard_keyStates[code] = 0; + e = &keyboard_events.data[keyboard_events.writei & BUFFER_MASK]; + e->type = KEYBOARD_KEYRELEASE; + e->code = code; + e->isrepeat = 0; + keyboard_events.writei++; + + } else { + /* Key down */ + int isrepeat = keyboard_keyStates[code]; + if (!isrepeat || keyboard_allowKeyRepeat) { + keyboard_keyStates[code] = 1; + e = &keyboard_events.data[keyboard_events.writei & BUFFER_MASK]; + e->type = KEYBOARD_KEYPRESS; + e->code = code; + e->isrepeat = isrepeat; + keyboard_events.writei++; + } + } + } + + outportb(0x20, 0x20); +} + + +void keyboard_handler_end() {} + + +int keyboard_init(void) { + _go32_dpmi_lock_data((char*)&keyboard_keyStates, KEY_MAX); + _go32_dpmi_lock_data((char*)&keyboard_events, sizeof(keyboard_events)); + _go32_dpmi_lock_code(keyboard_handler,(unsigned long)keyboard_handler_end - + (unsigned long)keyboard_handler); + _go32_dpmi_get_protected_mode_interrupt_vector(9, &old_keyb_handler_seginfo); + new_keyb_handler_seginfo.pm_offset = (int)keyboard_handler; + _go32_dpmi_chain_protected_mode_interrupt_vector(9, &new_keyb_handler_seginfo); return 0; } -int l_keyboard_isDown(lua_State *L) { - int n = lua_gettop(L); - int res = 0; - int i; - for (i = 1; i <= n; i++) { - int code = luaL_checkoption(L, 1, NULL, scancodeMap); - res |= keyboard_keyStates[code]; - } - lua_pushboolean(L, res); - return 1; +void keyboard_deinit(void) { + _go32_dpmi_set_protected_mode_interrupt_vector(9, &old_keyb_handler_seginfo); } -int l_keyboard_poll(lua_State *L) { - lua_newtable(L); - int idx = 1; +void keyboard_setKeyRepeat(int allow) { + keyboard_allowKeyRepeat = allow; +} - /* Handle key presses / releases */ - while (keyboard_events.readi != keyboard_events.writei) { - lua_newtable(L); - KeyEvent e = keyboard_events.data[keyboard_events.readi & BUFFER_MASK]; - - lua_pushstring(L, e.type == KEY_DOWN ? "down" : "up"); - lua_setfield(L, -2, "type"); - lua_pushnumber(L, e.code); - lua_setfield(L, -2, "code"); - lua_pushstring(L, scancodeMap[e.code]); - lua_setfield(L, -2, "key"); - if (e.type == KEY_DOWN) { - lua_pushboolean(L, e.isrepeat); - lua_setfield(L, -2, "isrepeat"); +int keyboard_isDown(const char *key) { + int i; + for (i = 0; scancodeMap[i]; i++) { + if (!strcmp(scancodeMap[i], key)) { + return keyboard_keyStates[i]; } + } + return 0; +} - lua_rawseti(L, -2, idx++); + +int keyboard_poll(keyboard_Event *e) { + + /* Handle key press / release */ + if (keyboard_events.readi != keyboard_events.writei) { + KeyEvent ke = keyboard_events.data[keyboard_events.readi & BUFFER_MASK]; + e->type = ke.type; + e->code = ke.code; + e->key = scancodeMap[ke.code]; + e->isrepeat = ke.isrepeat; keyboard_events.readi++; + return 1; } /* Handle text input */ @@ -280,25 +259,11 @@ int l_keyboard_poll(lua_State *L) { } } if (i > 0) { - lua_newtable(L); - lua_pushstring(L, "text"); - lua_setfield(L, -2, "type"); - lua_pushlstring(L, buf, i); - lua_setfield(L, -2, "text"); - lua_rawseti(L, -2, idx++); + e->type = KEYBOARD_TEXTINPUT; + memcpy(e->text, buf, i); + e->text[i] = '\0'; + return 1; } - return 1; -} - - -int luaopen_keyboard(lua_State *L) { - luaL_Reg reg[] = { - { "poll", l_keyboard_poll }, - { "setKeyRepeat", l_keyboard_setKeyRepeat }, - { "isDown", l_keyboard_isDown }, - { 0, 0 }, - }; - luaL_newlib(L, reg); - return 1; + return 0; } diff --git a/src/keyboard.h b/src/keyboard.h index 8c42e92..5d6f795 100644 --- a/src/keyboard.h +++ b/src/keyboard.h @@ -1,4 +1,4 @@ -/** +/** * Copyright (c) 2016 rxi * * This library is free software; you can redistribute it and/or modify it @@ -8,7 +8,24 @@ #ifndef KEYBOARD_H #define KEYBOARD_H +typedef struct { + int type; + unsigned code; + const char *key; + char text[64]; + int isrepeat; +} keyboard_Event; + +enum { + KEYBOARD_KEYPRESS, + KEYBOARD_KEYRELEASE, + KEYBOARD_TEXTINPUT +}; + int keyboard_init(void); void keyboard_deinit(void); +void keyboard_setKeyRepeat(int allow); +int keyboard_isDown(const char *key); +int keyboard_poll(keyboard_Event *e); #endif diff --git a/src/modules/l_keyboard.c b/src/modules/l_keyboard.c new file mode 100644 index 0000000..192c846 --- /dev/null +++ b/src/modules/l_keyboard.c @@ -0,0 +1,76 @@ +/** + * Copyright (c) 2016 rxi + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the MIT license. See LICENSE for details. + */ + + +#include "keyboard.h" +#include "luaobj.h" + + +int l_keyboard_setKeyRepeat(lua_State *L) { + keyboard_setKeyRepeat( lua_toboolean(L, 1) ); + return 0; +} + + +int l_keyboard_isDown(lua_State *L) { + int n = lua_gettop(L); + int res = 0; + int i; + for (i = 1; i <= n; i++) { + const char *key = luaL_checkstring(L, 1); + res |= keyboard_isDown(key); + } + lua_pushboolean(L, res); + return 1; +} + + +int l_keyboard_poll(lua_State *L) { + lua_newtable(L); + keyboard_Event e; + int idx = 1; + + while (keyboard_poll(&e)) { + + if (e.type == KEYBOARD_KEYPRESS || e.type == KEYBOARD_KEYRELEASE) { + lua_newtable(L); + lua_pushstring(L, e.type == KEYBOARD_KEYPRESS ? "down" : "up"); + lua_setfield(L, -2, "type"); + lua_pushnumber(L, e.code); + lua_setfield(L, -2, "code"); + lua_pushstring(L, e.key); + lua_setfield(L, -2, "key"); + if (e.type == KEYBOARD_KEYPRESS) { + lua_pushboolean(L, e.isrepeat); + lua_setfield(L, -2, "isrepeat"); + } + lua_rawseti(L, -2, idx++); + + } else if (e.type == KEYBOARD_TEXTINPUT) { + lua_newtable(L); + lua_pushstring(L, "text"); + lua_setfield(L, -2, "type"); + lua_pushstring(L, e.text); + lua_setfield(L, -2, "text"); + lua_rawseti(L, -2, idx++); + } + } + + return 1; +} + + +int luaopen_keyboard(lua_State *L) { + luaL_Reg reg[] = { + { "poll", l_keyboard_poll }, + { "setKeyRepeat", l_keyboard_setKeyRepeat }, + { "isDown", l_keyboard_isDown }, + { 0, 0 }, + }; + luaL_newlib(L, reg); + return 1; +}