Separated lua bindings from keyboard.c
This commit is contained in:
213
src/keyboard.c
213
src/keyboard.c
@@ -17,81 +17,7 @@
|
|||||||
#define BUFFER_SIZE 32
|
#define BUFFER_SIZE 32
|
||||||
#define BUFFER_MASK (BUFFER_SIZE - 1)
|
#define BUFFER_MASK (BUFFER_SIZE - 1)
|
||||||
|
|
||||||
enum { KEY_UP, KEY_DOWN };
|
static const char *scancodeMap[] = {
|
||||||
|
|
||||||
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[] = {
|
|
||||||
[ 0] = "?",
|
[ 0] = "?",
|
||||||
[ 1] = "escape",
|
[ 1] = "escape",
|
||||||
[ 2] = "1",
|
[ 2] = "1",
|
||||||
@@ -224,48 +150,101 @@ const char *scancodeMap[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
int l_keyboard_setKeyRepeat(lua_State *L) {
|
volatile int keyboard_allowKeyRepeat = 0;
|
||||||
keyboard_allowKeyRepeat = lua_toboolean(L, 1);
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int l_keyboard_isDown(lua_State *L) {
|
void keyboard_deinit(void) {
|
||||||
int n = lua_gettop(L);
|
_go32_dpmi_set_protected_mode_interrupt_vector(9, &old_keyb_handler_seginfo);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int l_keyboard_poll(lua_State *L) {
|
void keyboard_setKeyRepeat(int allow) {
|
||||||
lua_newtable(L);
|
keyboard_allowKeyRepeat = allow;
|
||||||
int idx = 1;
|
}
|
||||||
|
|
||||||
/* Handle key presses / releases */
|
|
||||||
while (keyboard_events.readi != keyboard_events.writei) {
|
|
||||||
lua_newtable(L);
|
|
||||||
|
|
||||||
KeyEvent e = keyboard_events.data[keyboard_events.readi & BUFFER_MASK];
|
int keyboard_isDown(const char *key) {
|
||||||
|
int i;
|
||||||
lua_pushstring(L, e.type == KEY_DOWN ? "down" : "up");
|
for (i = 0; scancodeMap[i]; i++) {
|
||||||
lua_setfield(L, -2, "type");
|
if (!strcmp(scancodeMap[i], key)) {
|
||||||
lua_pushnumber(L, e.code);
|
return keyboard_keyStates[i];
|
||||||
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");
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
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++;
|
keyboard_events.readi++;
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Handle text input */
|
/* Handle text input */
|
||||||
@@ -280,25 +259,11 @@ int l_keyboard_poll(lua_State *L) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (i > 0) {
|
if (i > 0) {
|
||||||
lua_newtable(L);
|
e->type = KEYBOARD_TEXTINPUT;
|
||||||
lua_pushstring(L, "text");
|
memcpy(e->text, buf, i);
|
||||||
lua_setfield(L, -2, "type");
|
e->text[i] = '\0';
|
||||||
lua_pushlstring(L, buf, i);
|
return 1;
|
||||||
lua_setfield(L, -2, "text");
|
|
||||||
lua_rawseti(L, -2, idx++);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 0;
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
/**
|
/**
|
||||||
* Copyright (c) 2016 rxi
|
* Copyright (c) 2016 rxi
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or modify it
|
* This library is free software; you can redistribute it and/or modify it
|
||||||
@@ -8,7 +8,24 @@
|
|||||||
#ifndef KEYBOARD_H
|
#ifndef KEYBOARD_H
|
||||||
#define 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);
|
int keyboard_init(void);
|
||||||
void keyboard_deinit(void);
|
void keyboard_deinit(void);
|
||||||
|
void keyboard_setKeyRepeat(int allow);
|
||||||
|
int keyboard_isDown(const char *key);
|
||||||
|
int keyboard_poll(keyboard_Event *e);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
76
src/modules/l_keyboard.c
Normal file
76
src/modules/l_keyboard.c
Normal file
@@ -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;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user