From ca0a7c716777dc8b9ddd22245692ea5add9cf881 Mon Sep 17 00:00:00 2001 From: "BADIM-PC\\Vadim" Date: Fri, 29 Dec 2017 17:59:07 +0300 Subject: [PATCH] added key() / keyp() LUA api --- include/tic80/tic80.h | 5 +- src/luaapi.c | 201 +++++++++++++++++------------------------- src/machine.h | 2 + src/tic.c | 77 ++++++++++++++++ src/tic.h | 9 +- src/ticapi.h | 2 + 6 files changed, 172 insertions(+), 124 deletions(-) diff --git a/include/tic80/tic80.h b/include/tic80/tic80.h index 430e979..5054869 100644 --- a/include/tic80/tic80.h +++ b/include/tic80/tic80.h @@ -34,6 +34,7 @@ extern "C" { #define TIC80_FULLWIDTH_BITS 8 #define TIC80_FULLWIDTH (1 << TIC80_FULLWIDTH_BITS) #define TIC80_FULLHEIGHT (TIC80_FULLWIDTH*9/16) +#define TIC_KEY_BUFFER 4 typedef struct { @@ -104,9 +105,11 @@ typedef struct }; } tic80_mouse; +typedef u8 tic_key; + typedef union { - u8 keys[4]; + tic_key keys[TIC_KEY_BUFFER]; u32 data; } tic80_keyboard; diff --git a/src/luaapi.c b/src/luaapi.c index c3b60d2..dc5256e 100644 --- a/src/luaapi.c +++ b/src/luaapi.c @@ -360,61 +360,57 @@ static s32 lua_btnp(lua_State* lua) tic_machine* machine = getLuaMachine(lua); tic_mem* memory = (tic_mem*)machine; - if(machine->memory.input.gamepad) + s32 top = lua_gettop(lua); + + if (top == 0) { - s32 top = lua_gettop(lua); - - if (top == 0) - { - lua_pushinteger(lua, memory->api.btnp(memory, -1, -1, -1)); - } - else if(top == 1) - { - s32 index = getLuaNumber(lua, 1) & 0xf; - - lua_pushboolean(lua, memory->api.btnp(memory, index, -1, -1)); - } - else if (top == 3) - { - s32 index = getLuaNumber(lua, 1) & 0xf; - u32 hold = getLuaNumber(lua, 2); - u32 period = getLuaNumber(lua, 3); - - lua_pushboolean(lua, memory->api.btnp(memory, index, hold, period)); - } - else luaL_error(lua, "invalid params, btnp [ id [ hold period ] ]\n"); - - return 1; + lua_pushinteger(lua, memory->api.btnp(memory, -1, -1, -1)); } - else luaL_error(lua, "gamepad input not declared in metadata\n"); + else if(top == 1) + { + s32 index = getLuaNumber(lua, 1) & 0x1f; - return 0; + lua_pushboolean(lua, memory->api.btnp(memory, index, -1, -1)); + } + else if (top == 3) + { + s32 index = getLuaNumber(lua, 1) & 0x1f; + u32 hold = getLuaNumber(lua, 2); + u32 period = getLuaNumber(lua, 3); + + lua_pushboolean(lua, memory->api.btnp(memory, index, hold, period)); + } + else + { + luaL_error(lua, "invalid params, btnp [ id [ hold period ] ]\n"); + return 0; + } + + return 1; } static s32 lua_btn(lua_State* lua) { tic_machine* machine = getLuaMachine(lua); - if(machine->memory.input.gamepad) + s32 top = lua_gettop(lua); + + if (top == 0) { - s32 top = lua_gettop(lua); - - if (top == 0) - { - lua_pushinteger(lua, machine->memory.ram.input.gamepads.data); - } - else if (top == 1) - { - s32 index = getLuaNumber(lua, 1) & 0xf; - lua_pushboolean(lua, machine->memory.ram.input.gamepads.data & (1 << index)); - } - else luaL_error(lua, "invalid params, btn [ id ]\n"); - - return 1; + lua_pushinteger(lua, machine->memory.ram.input.gamepads.data); } - else luaL_error(lua, "gamepad input not declared in metadata\n"); + else if (top == 1) + { + u32 index = getLuaNumber(lua, 1) & 0x1f; + lua_pushboolean(lua, machine->memory.ram.input.gamepads.data & (1 << index)); + } + else + { + luaL_error(lua, "invalid params, btn [ id ]\n"); + return 0; + } - return 0; + return 1; } static s32 lua_spr(lua_State* lua) @@ -787,31 +783,28 @@ static s32 lua_reset(lua_State* lua) static s32 lua_key(lua_State* lua) { tic_machine* machine = getLuaMachine(lua); + tic_mem* tic = &machine->memory; s32 top = lua_gettop(lua); - tic80_input* input = &machine->memory.ram.input; + tic80_input* input = &tic->ram.input; - if (top == 1) + enum{Count = COUNT_OF(input->keyboard.keys)}; + + if (top == 0) { - u8 index = getLuaNumber(lua, 1)+1; - - if(index > tic_key_unknown) - { - for(s32 i = 0; i < COUNT_OF(input->keyboard.keys); i++) - { - if(input->keyboard.keys[i] == index) - { - lua_pushboolean(lua, true); - return 1; - } - } - } - - lua_pushboolean(lua, false); + lua_pushboolean(lua, tic->api.key(tic, tic_key_unknown)); return 1; } - else luaL_error(lua, "invalid params, key ( code )\n"); + else if (top == 1) + { + tic_key key = getLuaNumber(lua, 1) + TIC_KEY_START_INDEX; + + lua_pushboolean(lua, tic->api.key(tic, key)); + + return 1; + } + else luaL_error(lua, "invalid params, key [code]\n"); return 0; } @@ -819,65 +812,35 @@ static s32 lua_key(lua_State* lua) static s32 lua_keyp(lua_State* lua) { tic_machine* machine = getLuaMachine(lua); + tic_mem* tic = &machine->memory; s32 top = lua_gettop(lua); - tic80_input* input = &machine->memory.ram.input; if (top == 0) { - for(s32 i = 0; i < COUNT_OF(input->keyboard.keys); i++) - { - s32 code = input->keyboard.keys[i]; - - bool found = false; - - for(s32 p = 0; p < COUNT_OF(machine->state.keyboard.previous.keys); p++) - { - if(machine->state.keyboard.previous.keys[p] == code) - { - found = true; - break; - } - } - - if(!found) - { - lua_pushinteger(lua, code); - return 1; - } - } + lua_pushboolean(lua, tic->api.keyp(tic, tic_key_unknown, -1, -1)); } else if(top == 1) { - { - s32 code = getLuaNumber(lua, 1); + tic_key key = getLuaNumber(lua, 1) + TIC_KEY_START_INDEX;; - if(code > 0) - { - for(s32 i = 0; i < COUNT_OF(input->keyboard.keys); i++) - { - if(input->keyboard.keys[i] == code) - { - for(s32 p = 0; p < COUNT_OF(machine->state.keyboard.previous.keys); p++) - { - if(machine->state.keyboard.previous.keys[p] == code) - { - lua_pushboolean(lua, true); - return 1; - } - } - } - } - - } - - lua_pushboolean(lua, false); - return 1; - } + lua_pushboolean(lua, tic->api.keyp(tic, key, -1, -1)); } - else luaL_error(lua, "invalid params, keyp [ code ]\n"); + else if(top == 3) + { + tic_key key = getLuaNumber(lua, 1) + TIC_KEY_START_INDEX; + u32 hold = getLuaNumber(lua, 2); + u32 period = getLuaNumber(lua, 3); - return 0; + lua_pushboolean(lua, tic->api.keyp(tic, key, hold, period)); + } + else + { + luaL_error(lua, "invalid params, keyp [ code [ hold period ] ]\n"); + return 0; + } + + return 1; } static s32 lua_memcpy(lua_State* lua) @@ -1129,21 +1092,15 @@ static s32 lua_mouse(lua_State *lua) { tic_machine* machine = getLuaMachine(lua); - if(machine->memory.input.mouse) - { - const tic80_mouse* mouse = &machine->memory.ram.input.mouse; + const tic80_mouse* mouse = &machine->memory.ram.input.mouse; - lua_pushinteger(lua, mouse->x); - lua_pushinteger(lua, mouse->y); - lua_pushboolean(lua, mouse->left); - lua_pushboolean(lua, mouse->middle); - lua_pushboolean(lua, mouse->right); + lua_pushinteger(lua, mouse->x); + lua_pushinteger(lua, mouse->y); + lua_pushboolean(lua, mouse->left); + lua_pushboolean(lua, mouse->middle); + lua_pushboolean(lua, mouse->right); - return 5; - } - else luaL_error(lua, "mouse input not declared in metadata\n"); - - return 0; + return 5; } static s32 lua_dofile(lua_State *lua) diff --git a/src/machine.h b/src/machine.h index 22a1112..bdb8dca 100644 --- a/src/machine.h +++ b/src/machine.h @@ -72,6 +72,8 @@ typedef struct struct { tic80_keyboard previous; + + u32 holds[TIC_KEYS_COUNT]; } keyboard; Clip clip; diff --git a/src/tic.c b/src/tic.c index 500888e..a120517 100644 --- a/src/tic.c +++ b/src/tic.c @@ -1244,6 +1244,15 @@ static bool isNoiseWaveform(const tic_waveform* wave) return memcmp(&NoiseWave.data, &wave->data, sizeof(tic_waveform)) == 0; } +static bool isKeyPressed(const tic80_keyboard* input, tic_key key) +{ + for(s32 i = 0; i < TIC_KEY_BUFFER; i++) + if(input->keys[i] == key) + return true; + + return false; +} + static void api_tick_start(tic_mem* memory, const tic_sfx* sfxsrc, const tic_music* music) { tic_machine* machine = (tic_machine*)memory; @@ -1276,6 +1285,18 @@ static void api_tick_start(tic_mem* memory, const tic_sfx* sfxsrc, const tic_mus else *hold = 0; } + // process keyboard + for(s32 i = TIC_KEY_START_INDEX; i < TIC_KEYS_COUNT; i++) + { + bool prevDown = isKeyPressed(&machine->state.keyboard.previous, i); + bool down = isKeyPressed(&memory->ram.input.keyboard, i); + + u32* hold = &machine->state.keyboard.holds[i]; + + if(prevDown && down) (*hold)++; + else *hold = 0; + } + machine->state.setpix = setPixelDma; machine->state.getpix = getPixelDma; machine->state.synced = 0; @@ -1627,6 +1648,60 @@ static u32 api_btnp(tic_mem* tic, s32 index, s32 hold, s32 period) return ((~previous.data) & machine->memory.ram.input.gamepads.data) & (1 << index); } +static bool api_key(tic_mem* tic, tic_key key) +{ + if(key >= TIC_KEY_START_INDEX) + return isKeyPressed(&tic->ram.input.keyboard, key); + + for(s32 i = 0; i < TIC_KEY_BUFFER; i++) + if(isKeyPressed(&tic->ram.input.keyboard, i)) + return true; + + return false; +} + +static bool api_keyp(tic_mem* tic, tic_key key, s32 hold, s32 period) +{ + tic_machine* machine = (tic_machine*)tic; + + if(key >= TIC_KEY_START_INDEX) + { + bool prevDown = hold >= 0 && period >= 0 && machine->state.keyboard.holds[key] >= hold + ? period && machine->state.keyboard.holds[key] % period + ? isKeyPressed(&machine->state.keyboard.previous, key) + : false + : isKeyPressed(&machine->state.keyboard.previous, key); + + bool down = isKeyPressed(&tic->ram.input.keyboard, key); + + return !prevDown && down; + } + + for(s32 i = 0; i < TIC_KEY_BUFFER; i++) + { + tic_key key = tic->ram.input.keyboard.keys[i]; + + if(key) + { + bool wasPressed = false; + for(s32 p = 0; p < TIC_KEY_BUFFER; p++) + { + if(machine->state.keyboard.previous.keys[p] == key) + { + wasPressed = true; + break; + } + } + + if(!wasPressed) + return true; + } + } + + return false; +} + + static void api_load(tic_cartridge* cart, const u8* buffer, s32 size, bool palette) { const u8* end = buffer + size; @@ -1854,6 +1929,8 @@ static void initApi(tic_api* api) INIT_API(resume); INIT_API(sync); INIT_API(btnp); + INIT_API(key); + INIT_API(keyp); INIT_API(load); INIT_API(save); INIT_API(tick_start); diff --git a/src/tic.h b/src/tic.h index 9ad5e94..fcded04 100644 --- a/src/tic.h +++ b/src/tic.h @@ -497,5 +497,12 @@ enum tic_key_pagedown, tic_key_ctrl, tic_key_shift, - tic_key_alt + tic_key_alt, + + //////////////// + + tic_last_key }; + +#define TIC_KEY_START_INDEX (tic_key_up) +#define TIC_KEYS_COUNT (tic_last_key) diff --git a/src/ticapi.h b/src/ticapi.h index 1766441..4fc66f4 100644 --- a/src/ticapi.h +++ b/src/ticapi.h @@ -154,6 +154,8 @@ typedef struct void (*resume) (tic_mem* memory); void (*sync) (tic_mem* memory, u32 mask, s32 bank, bool toCart); u32 (*btnp) (tic_mem* memory, s32 id, s32 hold, s32 period); + bool (*key) (tic_mem* memory, tic_key key); + bool (*keyp) (tic_mem* memory, tic_key key, s32 hold, s32 period); void (*load) (tic_cartridge* rom, const u8* buffer, s32 size, bool palette); s32 (*save) (const tic_cartridge* rom, u8* buffer);