// 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; }