SRB2/src/lua_inputlib.c
2023-10-28 00:24:04 +02:00

302 lines
6.9 KiB
C

// SONIC ROBO BLAST 2
//-----------------------------------------------------------------------------
// Copyright (C) 2021-2023 by Sonic Team Junior.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
// See the 'LICENSE' file for more details.
//-----------------------------------------------------------------------------
/// \file lua_inputlib.c
/// \brief input library for Lua scripting
#include "doomdef.h"
#include "fastcmp.h"
#include "g_input.h"
#include "g_game.h"
#include "hu_stuff.h"
#include "i_system.h"
#include "lua_script.h"
#include "lua_libs.h"
boolean mousegrabbedbylua = true;
boolean ignoregameinputs = false;
///////////////
// FUNCTIONS //
///////////////
static int lib_gameControlDown(lua_State *L)
{
int i = luaL_checkinteger(L, 1);
if (i < 0 || i >= NUM_GAMECONTROLS)
return luaL_error(L, "GC_* constant %d out of range (0 - %d)", i, NUM_GAMECONTROLS-1);
lua_pushinteger(L, PLAYER1INPUTDOWN(i));
return 1;
}
static int lib_gameControl2Down(lua_State *L)
{
int i = luaL_checkinteger(L, 1);
if (i < 0 || i >= NUM_GAMECONTROLS)
return luaL_error(L, "GC_* constant %d out of range (0 - %d)", i, NUM_GAMECONTROLS-1);
lua_pushinteger(L, PLAYER2INPUTDOWN(i));
return 1;
}
static int lib_gameControlToKeyNum(lua_State *L)
{
int i = luaL_checkinteger(L, 1);
if (i < 0 || i >= NUM_GAMECONTROLS)
return luaL_error(L, "GC_* constant %d out of range (0 - %d)", i, NUM_GAMECONTROLS-1);
lua_pushinteger(L, gamecontrol[i][0]);
lua_pushinteger(L, gamecontrol[i][1]);
return 2;
}
static int lib_gameControl2ToKeyNum(lua_State *L)
{
int i = luaL_checkinteger(L, 1);
if (i < 0 || i >= NUM_GAMECONTROLS)
return luaL_error(L, "GC_* constant %d out of range (0 - %d)", i, NUM_GAMECONTROLS-1);
lua_pushinteger(L, gamecontrolbis[i][0]);
lua_pushinteger(L, gamecontrolbis[i][1]);
return 2;
}
static int lib_joyAxis(lua_State *L)
{
int i = luaL_checkinteger(L, 1);
lua_pushinteger(L, JoyAxis(i));
return 1;
}
static int lib_joy2Axis(lua_State *L)
{
int i = luaL_checkinteger(L, 1);
lua_pushinteger(L, Joy2Axis(i));
return 1;
}
static int lib_keyNumToName(lua_State *L)
{
int i = luaL_checkinteger(L, 1);
lua_pushstring(L, G_KeyNumToName(i));
return 1;
}
static int lib_keyNameToNum(lua_State *L)
{
const char *str = luaL_checkstring(L, 1);
lua_pushinteger(L, G_KeyNameToNum(str));
return 1;
}
static int lib_keyNumPrintable(lua_State *L)
{
int i = luaL_checkinteger(L, 1);
lua_pushboolean(L, i >= 32 && i <= 127);
return 1;
}
static int lib_shiftKeyNum(lua_State *L)
{
int i = luaL_checkinteger(L, 1);
if (i >= 32 && i <= 127)
lua_pushinteger(L, shiftxform[i]);
return 1;
}
static int lib_getMouseGrab(lua_State *L)
{
lua_pushboolean(L, mousegrabbedbylua);
return 1;
}
static int lib_setMouseGrab(lua_State *L)
{
mousegrabbedbylua = luaL_checkboolean(L, 1);
I_UpdateMouseGrab();
return 0;
}
static int lib_getCursorPosition(lua_State *L)
{
int x, y;
I_GetCursorPosition(&x, &y);
lua_pushinteger(L, x);
lua_pushinteger(L, y);
return 2;
}
static luaL_Reg lib[] = {
{"gameControlDown", lib_gameControlDown},
{"gameControl2Down", lib_gameControl2Down},
{"gameControlToKeyNum", lib_gameControlToKeyNum},
{"gameControl2ToKeyNum", lib_gameControl2ToKeyNum},
{"joyAxis", lib_joyAxis},
{"joy2Axis", lib_joy2Axis},
{"keyNumToName", lib_keyNumToName},
{"keyNameToNum", lib_keyNameToNum},
{"keyNumPrintable", lib_keyNumPrintable},
{"shiftKeyNum", lib_shiftKeyNum},
{"getMouseGrab", lib_getMouseGrab},
{"setMouseGrab", lib_setMouseGrab},
{"getCursorPosition", lib_getCursorPosition},
{NULL, NULL}
};
///////////////
// VARIABLES //
///////////////
static int lib_get(lua_State *L)
{
const char *field = luaL_checkstring(L, 2);
if (fastcmp(field, "mouse"))
{
LUA_PushUserdata(L, &mouse, META_MOUSE);
return 1;
}
else if (fastcmp(field, "mouse2"))
{
LUA_PushUserdata(L, &mouse2, META_MOUSE);
return 1;
}
else if (fastcmp(field, "ignoregameinputs"))
{
lua_pushboolean(L, ignoregameinputs);
return 1;
}
else
{
return 0;
}
}
static int lib_set(lua_State *L)
{
const char *field = luaL_checkstring(L, 2);
if (fastcmp(field, "ignoregameinputs"))
{
ignoregameinputs = luaL_checkboolean(L, 3);
}
else
{
lua_rawset(L, 1);
}
return 0;
}
///////////////////
// gamekeydown[] //
///////////////////
static int lib_getGameKeyDown(lua_State *L)
{
int i = luaL_checkinteger(L, 2);
if (i < 0 || i >= NUMINPUTS)
return luaL_error(L, "gamekeydown[] index %d out of range (0 - %d)", i, NUMINPUTS-1);
lua_pushboolean(L, gamekeydown[i]);
return 1;
}
static int lib_setGameKeyDown(lua_State *L)
{
int i = luaL_checkinteger(L, 2);
boolean j = luaL_checkboolean(L, 3);
if (i < 0 || i >= NUMINPUTS)
return luaL_error(L, "gamekeydown[] index %d out of range (0 - %d)", i, NUMINPUTS-1);
gamekeydown[i] = j;
return 0;
}
static int lib_lenGameKeyDown(lua_State *L)
{
lua_pushinteger(L, NUMINPUTS);
return 1;
}
///////////////
// KEY EVENT //
///////////////
static int keyevent_get(lua_State *L)
{
event_t *event = *((event_t **)luaL_checkudata(L, 1, META_KEYEVENT));
const char *field = luaL_checkstring(L, 2);
I_Assert(event != NULL);
if (fastcmp(field,"name"))
lua_pushstring(L, G_KeyNumToName(event->key));
else if (fastcmp(field,"num"))
lua_pushinteger(L, event->key);
else if (fastcmp(field,"repeated"))
lua_pushboolean(L, event->repeated);
else
return luaL_error(L, "keyevent_t has no field named %s", field);
return 1;
}
///////////
// MOUSE //
///////////
static int mouse_get(lua_State *L)
{
mouse_t *m = *((mouse_t **)luaL_checkudata(L, 1, META_MOUSE));
const char *field = luaL_checkstring(L, 2);
I_Assert(m != NULL);
if (fastcmp(field,"dx"))
lua_pushinteger(L, m->dx);
else if (fastcmp(field,"dy"))
lua_pushinteger(L, m->dy);
else if (fastcmp(field,"mlookdy"))
lua_pushinteger(L, m->mlookdy);
else if (fastcmp(field,"rdx"))
lua_pushinteger(L, m->rdx);
else if (fastcmp(field,"rdy"))
lua_pushinteger(L, m->rdy);
else if (fastcmp(field,"buttons"))
lua_pushinteger(L, m->buttons);
else
return luaL_error(L, "mouse_t has no field named %s", field);
return 1;
}
// #mouse -> 1 or 2
static int mouse_num(lua_State *L)
{
mouse_t *m = *((mouse_t **)luaL_checkudata(L, 1, META_MOUSE));
I_Assert(m != NULL);
lua_pushinteger(L, m == &mouse ? 1 : 2);
return 1;
}
int LUA_InputLib(lua_State *L)
{
LUA_RegisterUserdataMetatable(L, META_KEYEVENT, keyevent_get, NULL, NULL);
LUA_RegisterUserdataMetatable(L, META_MOUSE, mouse_get, NULL, mouse_num);
// Register the library, then add __index and __newindex
// metamethods to it to allow global variables
luaL_register(L, "input", lib);
LUA_CreateAndSetMetatable(L, lib_get, lib_set, NULL, false);
LUA_CreateAndSetUserdataField(L, -1, "gamekeydown", lib_getGameKeyDown, lib_setGameKeyDown, lib_lenGameKeyDown, false);
// TODO: 2.3: Delete this alias (moved to input library)
LUA_RegisterGlobalUserdata(L, "gamekeydown", lib_getGameKeyDown, lib_setGameKeyDown, lib_lenGameKeyDown);
lua_pop(L, 1);
return 0;
}