added key() / keyp() LUA api
This commit is contained in:
parent
c3a57954aa
commit
ca0a7c7167
|
@ -34,6 +34,7 @@ extern "C" {
|
||||||
#define TIC80_FULLWIDTH_BITS 8
|
#define TIC80_FULLWIDTH_BITS 8
|
||||||
#define TIC80_FULLWIDTH (1 << TIC80_FULLWIDTH_BITS)
|
#define TIC80_FULLWIDTH (1 << TIC80_FULLWIDTH_BITS)
|
||||||
#define TIC80_FULLHEIGHT (TIC80_FULLWIDTH*9/16)
|
#define TIC80_FULLHEIGHT (TIC80_FULLWIDTH*9/16)
|
||||||
|
#define TIC_KEY_BUFFER 4
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
|
@ -104,9 +105,11 @@ typedef struct
|
||||||
};
|
};
|
||||||
} tic80_mouse;
|
} tic80_mouse;
|
||||||
|
|
||||||
|
typedef u8 tic_key;
|
||||||
|
|
||||||
typedef union
|
typedef union
|
||||||
{
|
{
|
||||||
u8 keys[4];
|
tic_key keys[TIC_KEY_BUFFER];
|
||||||
u32 data;
|
u32 data;
|
||||||
} tic80_keyboard;
|
} tic80_keyboard;
|
||||||
|
|
||||||
|
|
201
src/luaapi.c
201
src/luaapi.c
|
@ -360,61 +360,57 @@ static s32 lua_btnp(lua_State* lua)
|
||||||
tic_machine* machine = getLuaMachine(lua);
|
tic_machine* machine = getLuaMachine(lua);
|
||||||
tic_mem* memory = (tic_mem*)machine;
|
tic_mem* memory = (tic_mem*)machine;
|
||||||
|
|
||||||
if(machine->memory.input.gamepad)
|
s32 top = lua_gettop(lua);
|
||||||
|
|
||||||
|
if (top == 0)
|
||||||
{
|
{
|
||||||
s32 top = lua_gettop(lua);
|
lua_pushinteger(lua, memory->api.btnp(memory, -1, -1, -1));
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
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)
|
static s32 lua_btn(lua_State* lua)
|
||||||
{
|
{
|
||||||
tic_machine* machine = getLuaMachine(lua);
|
tic_machine* machine = getLuaMachine(lua);
|
||||||
|
|
||||||
if(machine->memory.input.gamepad)
|
s32 top = lua_gettop(lua);
|
||||||
|
|
||||||
|
if (top == 0)
|
||||||
{
|
{
|
||||||
s32 top = lua_gettop(lua);
|
lua_pushinteger(lua, machine->memory.ram.input.gamepads.data);
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
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)
|
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)
|
static s32 lua_key(lua_State* lua)
|
||||||
{
|
{
|
||||||
tic_machine* machine = getLuaMachine(lua);
|
tic_machine* machine = getLuaMachine(lua);
|
||||||
|
tic_mem* tic = &machine->memory;
|
||||||
|
|
||||||
s32 top = lua_gettop(lua);
|
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;
|
lua_pushboolean(lua, tic->api.key(tic, tic_key_unknown));
|
||||||
|
|
||||||
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);
|
|
||||||
return 1;
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -819,65 +812,35 @@ static s32 lua_key(lua_State* lua)
|
||||||
static s32 lua_keyp(lua_State* lua)
|
static s32 lua_keyp(lua_State* lua)
|
||||||
{
|
{
|
||||||
tic_machine* machine = getLuaMachine(lua);
|
tic_machine* machine = getLuaMachine(lua);
|
||||||
|
tic_mem* tic = &machine->memory;
|
||||||
|
|
||||||
s32 top = lua_gettop(lua);
|
s32 top = lua_gettop(lua);
|
||||||
tic80_input* input = &machine->memory.ram.input;
|
|
||||||
|
|
||||||
if (top == 0)
|
if (top == 0)
|
||||||
{
|
{
|
||||||
for(s32 i = 0; i < COUNT_OF(input->keyboard.keys); i++)
|
lua_pushboolean(lua, tic->api.keyp(tic, tic_key_unknown, -1, -1));
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if(top == 1)
|
else if(top == 1)
|
||||||
{
|
{
|
||||||
{
|
tic_key key = getLuaNumber(lua, 1) + TIC_KEY_START_INDEX;;
|
||||||
s32 code = getLuaNumber(lua, 1);
|
|
||||||
|
|
||||||
if(code > 0)
|
lua_pushboolean(lua, tic->api.keyp(tic, key, -1, -1));
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
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)
|
static s32 lua_memcpy(lua_State* lua)
|
||||||
|
@ -1129,21 +1092,15 @@ static s32 lua_mouse(lua_State *lua)
|
||||||
{
|
{
|
||||||
tic_machine* machine = getLuaMachine(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->x);
|
||||||
lua_pushinteger(lua, mouse->y);
|
lua_pushinteger(lua, mouse->y);
|
||||||
lua_pushboolean(lua, mouse->left);
|
lua_pushboolean(lua, mouse->left);
|
||||||
lua_pushboolean(lua, mouse->middle);
|
lua_pushboolean(lua, mouse->middle);
|
||||||
lua_pushboolean(lua, mouse->right);
|
lua_pushboolean(lua, mouse->right);
|
||||||
|
|
||||||
return 5;
|
return 5;
|
||||||
}
|
|
||||||
else luaL_error(lua, "mouse input not declared in metadata\n");
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static s32 lua_dofile(lua_State *lua)
|
static s32 lua_dofile(lua_State *lua)
|
||||||
|
|
|
@ -72,6 +72,8 @@ typedef struct
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
tic80_keyboard previous;
|
tic80_keyboard previous;
|
||||||
|
|
||||||
|
u32 holds[TIC_KEYS_COUNT];
|
||||||
} keyboard;
|
} keyboard;
|
||||||
|
|
||||||
Clip clip;
|
Clip clip;
|
||||||
|
|
77
src/tic.c
77
src/tic.c
|
@ -1244,6 +1244,15 @@ static bool isNoiseWaveform(const tic_waveform* wave)
|
||||||
return memcmp(&NoiseWave.data, &wave->data, sizeof(tic_waveform)) == 0;
|
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)
|
static void api_tick_start(tic_mem* memory, const tic_sfx* sfxsrc, const tic_music* music)
|
||||||
{
|
{
|
||||||
tic_machine* machine = (tic_machine*)memory;
|
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;
|
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.setpix = setPixelDma;
|
||||||
machine->state.getpix = getPixelDma;
|
machine->state.getpix = getPixelDma;
|
||||||
machine->state.synced = 0;
|
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);
|
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)
|
static void api_load(tic_cartridge* cart, const u8* buffer, s32 size, bool palette)
|
||||||
{
|
{
|
||||||
const u8* end = buffer + size;
|
const u8* end = buffer + size;
|
||||||
|
@ -1854,6 +1929,8 @@ static void initApi(tic_api* api)
|
||||||
INIT_API(resume);
|
INIT_API(resume);
|
||||||
INIT_API(sync);
|
INIT_API(sync);
|
||||||
INIT_API(btnp);
|
INIT_API(btnp);
|
||||||
|
INIT_API(key);
|
||||||
|
INIT_API(keyp);
|
||||||
INIT_API(load);
|
INIT_API(load);
|
||||||
INIT_API(save);
|
INIT_API(save);
|
||||||
INIT_API(tick_start);
|
INIT_API(tick_start);
|
||||||
|
|
|
@ -497,5 +497,12 @@ enum
|
||||||
tic_key_pagedown,
|
tic_key_pagedown,
|
||||||
tic_key_ctrl,
|
tic_key_ctrl,
|
||||||
tic_key_shift,
|
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)
|
||||||
|
|
|
@ -154,6 +154,8 @@ typedef struct
|
||||||
void (*resume) (tic_mem* memory);
|
void (*resume) (tic_mem* memory);
|
||||||
void (*sync) (tic_mem* memory, u32 mask, s32 bank, bool toCart);
|
void (*sync) (tic_mem* memory, u32 mask, s32 bank, bool toCart);
|
||||||
u32 (*btnp) (tic_mem* memory, s32 id, s32 hold, s32 period);
|
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);
|
void (*load) (tic_cartridge* rom, const u8* buffer, s32 size, bool palette);
|
||||||
s32 (*save) (const tic_cartridge* rom, u8* buffer);
|
s32 (*save) (const tic_cartridge* rom, u8* buffer);
|
||||||
|
|
Loading…
Reference in New Issue