Expose inputs to Lua

This commit is contained in:
SwitchKaze 2021-03-24 03:54:11 -05:00
parent 6bf76602ed
commit 3faa98cf4a
18 changed files with 471 additions and 61 deletions

View file

@ -281,6 +281,7 @@ set(SRB2_LUA_SOURCES
lua_mobjlib.c
lua_playerlib.c
lua_polyobjlib.c
lua_inputlib.c
lua_script.c
lua_skinlib.c
lua_thinkerlib.c

View file

@ -50,4 +50,5 @@ OBJS:=$(OBJS) \
$(OBJDIR)/lua_taglib.o \
$(OBJDIR)/lua_polyobjlib.o \
$(OBJDIR)/lua_blockmaplib.o \
$(OBJDIR)/lua_hudlib.o
$(OBJDIR)/lua_hudlib.o \
$(OBJDIR)/lua_inputlib.o

View file

@ -221,7 +221,7 @@ static void CONS_Bind_f(void)
for (key = 0; key < NUMINPUTS; key++)
if (bindtable[key])
{
CONS_Printf("%s : \"%s\"\n", G_KeynumToString(key), bindtable[key]);
CONS_Printf("%s : \"%s\"\n", G_KeyNumToString(key), bindtable[key]);
na = 1;
}
if (!na)
@ -229,7 +229,7 @@ static void CONS_Bind_f(void)
return;
}
key = G_KeyStringtoNum(COM_Argv(1));
key = G_KeyStringToNum(COM_Argv(1));
if (key <= 0 || key >= NUMINPUTS)
{
CONS_Alert(CONS_NOTICE, M_GetText("Invalid key name\n"));

View file

@ -181,6 +181,8 @@ void D_ProcessEvents(void)
for (; eventtail != eventhead; eventtail = (eventtail+1) & (MAXEVENTS-1))
{
boolean hooked = false;
ev = &events[eventtail];
// Screenshots over everything so that they can be taken anywhere.
@ -193,6 +195,12 @@ void D_ProcessEvents(void)
continue;
}
if (!CON_Ready() && !menuactive) {
if (G_LuaResponder(ev))
continue;
hooked = true;
}
// Menu input
#ifdef HAVE_THREADS
I_lock_mutex(&m_menu_mutex);
@ -207,6 +215,12 @@ void D_ProcessEvents(void)
if (eaten)
continue; // menu ate the event
if (!hooked && !CON_Ready()) {
if (G_LuaResponder(ev))
continue;
hooked = true;
}
// console input
#ifdef HAVE_THREADS
I_lock_mutex(&con_mutex);
@ -221,6 +235,9 @@ void D_ProcessEvents(void)
if (eaten)
continue; // ate the event
if (!hooked && G_LuaResponder(ev))
continue;
G_Responder(ev);
}

View file

@ -22,6 +22,8 @@
#include "v_video.h" // video flags (for lua)
#include "i_sound.h" // musictype_t (for lua)
#include "g_state.h" // gamestate_t (for lua)
#include "g_game.h" // Joystick axes (for lua)
#include "g_input.h" // Game controls (for lua)
#include "deh_tables.h"
@ -5455,6 +5457,63 @@ struct int_const_s const INT_CONST[] = {
{"GS_DEDICATEDSERVER",GS_DEDICATEDSERVER},
{"GS_WAITINGPLAYERS",GS_WAITINGPLAYERS},
// Joystick axes
{"JA_NONE",JA_NONE},
{"JA_TURN",JA_TURN},
{"JA_MOVE",JA_MOVE},
{"JA_LOOK",JA_LOOK},
{"JA_STRAFE",JA_STRAFE},
{"JA_DIGITAL",JA_DIGITAL},
{"JA_JUMP",JA_JUMP},
{"JA_SPIN",JA_SPIN},
{"JA_FIRE",JA_FIRE},
{"JA_FIRENORMAL",JA_FIRENORMAL},
// Game controls
{"gc_null",gc_null},
{"gc_forward",gc_forward},
{"gc_backward",gc_backward},
{"gc_strafeleft",gc_strafeleft},
{"gc_straferight",gc_straferight},
{"gc_turnleft",gc_turnleft},
{"gc_turnright",gc_turnright},
{"gc_weaponnext",gc_weaponnext},
{"gc_weaponprev",gc_weaponprev},
{"gc_wepslot1",gc_wepslot1},
{"gc_wepslot2",gc_wepslot2},
{"gc_wepslot3",gc_wepslot3},
{"gc_wepslot4",gc_wepslot4},
{"gc_wepslot5",gc_wepslot5},
{"gc_wepslot6",gc_wepslot6},
{"gc_wepslot7",gc_wepslot7},
{"gc_wepslot8",gc_wepslot8},
{"gc_wepslot9",gc_wepslot9},
{"gc_wepslot10",gc_wepslot10},
{"gc_fire",gc_fire},
{"gc_firenormal",gc_firenormal},
{"gc_tossflag",gc_tossflag},
{"gc_spin",gc_spin},
{"gc_camtoggle",gc_camtoggle},
{"gc_camreset",gc_camreset},
{"gc_lookup",gc_lookup},
{"gc_lookdown",gc_lookdown},
{"gc_centerview",gc_centerview},
{"gc_mouseaiming",gc_mouseaiming},
{"gc_talkkey",gc_talkkey},
{"gc_teamkey",gc_teamkey},
{"gc_scores",gc_scores},
{"gc_jump",gc_jump},
{"gc_console",gc_console},
{"gc_pause",gc_pause},
{"gc_systemmenu",gc_systemmenu},
{"gc_screenshot",gc_screenshot},
{"gc_recordgif",gc_recordgif},
{"gc_viewpoint",gc_viewpoint},
{"gc_custom1",gc_custom1},
{"gc_custom2",gc_custom2},
{"gc_custom3",gc_custom3},
{"num_gamecontrols",num_gamecontrols},
{NULL,0}
};

View file

@ -406,22 +406,6 @@ consvar_t cv_cam_lockonboss[2] = {
CVAR_INIT ("cam2_lockaimassist", "Bosses", CV_SAVE, lockedassist_cons_t, NULL),
};
typedef enum
{
AXISNONE = 0,
AXISTURN,
AXISMOVE,
AXISLOOK,
AXISSTRAFE,
AXISDIGITAL, // axes below this use digital deadzone
AXISJUMP,
AXISSPIN,
AXISFIRE,
AXISFIRENORMAL,
} axis_input_e;
consvar_t cv_turnaxis = CVAR_INIT ("joyaxis_turn", "X-Rudder", CV_SAVE, joyaxis_cons_t, NULL);
consvar_t cv_moveaxis = CVAR_INIT ("joyaxis_move", "Y-Axis", CV_SAVE, joyaxis_cons_t, NULL);
consvar_t cv_sideaxis = CVAR_INIT ("joyaxis_side", "X-Axis", CV_SAVE, joyaxis_cons_t, NULL);
@ -841,7 +825,7 @@ INT16 G_SoftwareClipAimingPitch(INT32 *aiming)
return (INT16)((*aiming)>>16);
}
static INT32 JoyAxis(axis_input_e axissel)
INT32 JoyAxis(joyaxis_e axissel)
{
INT32 retaxis;
INT32 axisval;
@ -850,28 +834,28 @@ static INT32 JoyAxis(axis_input_e axissel)
//find what axis to get
switch (axissel)
{
case AXISTURN:
case JA_TURN:
axisval = cv_turnaxis.value;
break;
case AXISMOVE:
case JA_MOVE:
axisval = cv_moveaxis.value;
break;
case AXISLOOK:
case JA_LOOK:
axisval = cv_lookaxis.value;
break;
case AXISSTRAFE:
case JA_STRAFE:
axisval = cv_sideaxis.value;
break;
case AXISJUMP:
case JA_JUMP:
axisval = cv_jumpaxis.value;
break;
case AXISSPIN:
case JA_SPIN:
axisval = cv_spinaxis.value;
break;
case AXISFIRE:
case JA_FIRE:
axisval = cv_fireaxis.value;
break;
case AXISFIRENORMAL:
case JA_FIRENORMAL:
axisval = cv_firenaxis.value;
break;
default:
@ -903,7 +887,7 @@ static INT32 JoyAxis(axis_input_e axissel)
if (retaxis > (+JOYAXISRANGE))
retaxis = +JOYAXISRANGE;
if (!Joystick.bGamepadStyle && axissel > AXISDIGITAL)
if (!Joystick.bGamepadStyle && axissel > JA_DIGITAL)
{
const INT32 jdeadzone = ((JOYAXISRANGE-1) * cv_digitaldeadzone.value) >> FRACBITS;
if (-jdeadzone < retaxis && retaxis < jdeadzone)
@ -914,7 +898,7 @@ static INT32 JoyAxis(axis_input_e axissel)
return retaxis;
}
static INT32 Joy2Axis(axis_input_e axissel)
INT32 Joy2Axis(joyaxis_e axissel)
{
INT32 retaxis;
INT32 axisval;
@ -923,28 +907,28 @@ static INT32 Joy2Axis(axis_input_e axissel)
//find what axis to get
switch (axissel)
{
case AXISTURN:
case JA_TURN:
axisval = cv_turnaxis2.value;
break;
case AXISMOVE:
case JA_MOVE:
axisval = cv_moveaxis2.value;
break;
case AXISLOOK:
case JA_LOOK:
axisval = cv_lookaxis2.value;
break;
case AXISSTRAFE:
case JA_STRAFE:
axisval = cv_sideaxis2.value;
break;
case AXISJUMP:
case JA_JUMP:
axisval = cv_jumpaxis2.value;
break;
case AXISSPIN:
case JA_SPIN:
axisval = cv_spinaxis2.value;
break;
case AXISFIRE:
case JA_FIRE:
axisval = cv_fireaxis2.value;
break;
case AXISFIRENORMAL:
case JA_FIRENORMAL:
axisval = cv_firenaxis2.value;
break;
default:
@ -978,7 +962,7 @@ static INT32 Joy2Axis(axis_input_e axissel)
if (retaxis > (+JOYAXISRANGE))
retaxis = +JOYAXISRANGE;
if (!Joystick2.bGamepadStyle && axissel > AXISDIGITAL)
if (!Joystick2.bGamepadStyle && axissel > JA_DIGITAL)
{
const INT32 jdeadzone = ((JOYAXISRANGE-1) * cv_digitaldeadzone2.value) >> FRACBITS;
if (-jdeadzone < retaxis && retaxis < jdeadzone)
@ -1174,10 +1158,10 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
*myaiming = 0;
joyaiming[forplayer] = thisjoyaiming;
turnaxis = PlayerJoyAxis(ssplayer, AXISTURN);
turnaxis = PlayerJoyAxis(ssplayer, JA_TURN);
if (strafeisturn)
turnaxis += PlayerJoyAxis(ssplayer, AXISSTRAFE);
lookaxis = PlayerJoyAxis(ssplayer, AXISLOOK);
turnaxis += PlayerJoyAxis(ssplayer, JA_STRAFE);
lookaxis = PlayerJoyAxis(ssplayer, JA_LOOK);
lookjoystickvector.xaxis = turnaxis;
lookjoystickvector.yaxis = lookaxis;
G_HandleAxisDeadZone(forplayer, &lookjoystickvector);
@ -1256,8 +1240,8 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
tta_factor[forplayer] = 0; // suspend turn to angle
}
strafeaxis = strafeisturn ? 0 : PlayerJoyAxis(ssplayer, AXISSTRAFE);
moveaxis = PlayerJoyAxis(ssplayer, AXISMOVE);
strafeaxis = strafeisturn ? 0 : PlayerJoyAxis(ssplayer, JA_STRAFE);
moveaxis = PlayerJoyAxis(ssplayer, JA_MOVE);
movejoystickvector.xaxis = strafeaxis;
movejoystickvector.yaxis = moveaxis;
G_HandleAxisDeadZone(forplayer, &movejoystickvector);
@ -1313,12 +1297,12 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
}
// fire with any button/key
axis = PlayerJoyAxis(ssplayer, AXISFIRE);
axis = PlayerJoyAxis(ssplayer, JA_FIRE);
if (PLAYERINPUTDOWN(ssplayer, gc_fire) || (usejoystick && axis > 0))
cmd->buttons |= BT_ATTACK;
// fire normal with any button/key
axis = PlayerJoyAxis(ssplayer, AXISFIRENORMAL);
axis = PlayerJoyAxis(ssplayer, JA_FIRENORMAL);
if (PLAYERINPUTDOWN(ssplayer, gc_firenormal) || (usejoystick && axis > 0))
cmd->buttons |= BT_FIRENORMAL;
@ -1334,7 +1318,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
cmd->buttons |= BT_CUSTOM3;
// use with any button/key
axis = PlayerJoyAxis(ssplayer, AXISSPIN);
axis = PlayerJoyAxis(ssplayer, JA_SPIN);
if (PLAYERINPUTDOWN(ssplayer, gc_spin) || (usejoystick && axis > 0))
cmd->buttons |= BT_SPIN;
@ -1452,7 +1436,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
// jump button
axis = PlayerJoyAxis(ssplayer, AXISJUMP);
axis = PlayerJoyAxis(ssplayer, JA_JUMP);
if (PLAYERINPUTDOWN(ssplayer, gc_jump) || (usejoystick && axis > 0))
cmd->buttons |= BT_JUMP;
@ -2191,6 +2175,16 @@ boolean G_Responder(event_t *ev)
return false;
}
//
// G_LuaResponder
// Let Lua handle key events.
//
boolean G_LuaResponder(event_t *ev)
{
return (ev->type == ev_keydown && LUAh_KeyDown(ev->data1)) ||
(ev->type == ev_keyup && LUAh_KeyUp(ev->data1));
}
//
// G_Ticker
// Make ticcmd_ts for the players.

View file

@ -85,6 +85,25 @@ typedef enum
} lockassist_e;
typedef enum
{
JA_NONE = 0,
JA_TURN,
JA_MOVE,
JA_LOOK,
JA_STRAFE,
JA_DIGITAL, // axes below this use digital deadzone
JA_JUMP,
JA_SPIN,
JA_FIRE,
JA_FIRENORMAL,
} joyaxis_e;
INT32 JoyAxis(joyaxis_e axissel);
INT32 Joy2Axis(joyaxis_e axissel);
// mouseaiming (looking up/down with the mouse or keyboard)
#define KB_LOOKSPEED (1<<25)
#define MAXPLMOVE (50)
@ -204,6 +223,7 @@ void G_EndGame(void); // moved from y_inter.c/h and renamed
void G_Ticker(boolean run);
boolean G_Responder(event_t *ev);
boolean G_LuaResponder(event_t *ev);
void G_AddPlayer(INT32 playernum);

View file

@ -626,7 +626,7 @@ void G_ClearAllControlKeys(void)
// Returns the name of a key (or virtual key for mouse and joy)
// the input value being an keynum
//
const char *G_KeynumToString(INT32 keynum)
const char *G_KeyNumToString(INT32 keynum)
{
static char keynamestr[8];
@ -650,7 +650,7 @@ const char *G_KeynumToString(INT32 keynum)
return keynamestr;
}
INT32 G_KeyStringtoNum(const char *keystr)
INT32 G_KeyStringToNum(const char *keystr)
{
UINT32 j;
@ -813,10 +813,10 @@ void G_SaveKeySetting(FILE *f, INT32 (*fromcontrols)[2], INT32 (*fromcontrolsbis
for (i = 1; i < num_gamecontrols; i++)
{
fprintf(f, "setcontrol \"%s\" \"%s\"", gamecontrolname[i],
G_KeynumToString(fromcontrols[i][0]));
G_KeyNumToString(fromcontrols[i][0]));
if (fromcontrols[i][1])
fprintf(f, " \"%s\"\n", G_KeynumToString(fromcontrols[i][1]));
fprintf(f, " \"%s\"\n", G_KeyNumToString(fromcontrols[i][1]));
else
fprintf(f, "\n");
}
@ -824,10 +824,10 @@ void G_SaveKeySetting(FILE *f, INT32 (*fromcontrols)[2], INT32 (*fromcontrolsbis
for (i = 1; i < num_gamecontrols; i++)
{
fprintf(f, "setcontrol2 \"%s\" \"%s\"", gamecontrolname[i],
G_KeynumToString(fromcontrolsbis[i][0]));
G_KeyNumToString(fromcontrolsbis[i][0]));
if (fromcontrolsbis[i][1])
fprintf(f, " \"%s\"\n", G_KeynumToString(fromcontrolsbis[i][1]));
fprintf(f, " \"%s\"\n", G_KeyNumToString(fromcontrolsbis[i][1]));
else
fprintf(f, "\n");
}
@ -1003,8 +1003,8 @@ static void setcontrol(INT32 (*gc)[2])
CONS_Printf(M_GetText("Control '%s' unknown\n"), namectrl);
return;
}
keynum1 = G_KeyStringtoNum(COM_Argv(2));
keynum2 = G_KeyStringtoNum(COM_Argv(3));
keynum1 = G_KeyStringToNum(COM_Argv(2));
keynum2 = G_KeyStringToNum(COM_Argv(3));
keynum = G_FilterKeyByVersion(numctrl, 0, player, &keynum1, &keynum2, &nestedoverride);
if (keynum >= 0)

View file

@ -169,8 +169,8 @@ extern const INT32 gcl_jump_spin[num_gcl_jump_spin];
void G_MapEventsToControls(event_t *ev);
// returns the name of a key
const char *G_KeynumToString(INT32 keynum);
INT32 G_KeyStringtoNum(const char *keystr);
const char *G_KeyNumToString(INT32 keynum);
INT32 G_KeyStringToNum(const char *keystr);
// detach any keys associated to the given game control
void G_ClearControlKeys(INT32 (*setupcontrols)[2], INT32 control);

View file

@ -212,6 +212,8 @@ static const struct {
{META_ACTION, "action"},
{META_LUABANKS, "luabanks[]"},
{META_MOUSE, "mouse_t"},
{NULL, NULL}
};

View file

@ -63,6 +63,8 @@ enum hook {
hook_MusicChange,
hook_PlayerHeight,
hook_PlayerCanEnterSpinGaps,
hook_KeyDown,
hook_KeyUp,
hook_MAX // last hook
};
@ -122,3 +124,5 @@ boolean LUAh_PlayerCmd(player_t *player, ticcmd_t *cmd); // Hook for building pl
boolean LUAh_MusicChange(const char *oldname, char *newname, UINT16 *mflags, boolean *looping, UINT32 *position, UINT32 *prefadems, UINT32 *fadeinms); // Hook for music changes
fixed_t LUAh_PlayerHeight(player_t *player);
UINT8 LUAh_PlayerCanEnterSpinGaps(player_t *player);
boolean LUAh_KeyDown(INT32 keycode); // Hooks for key events
boolean LUAh_KeyUp(INT32 keycode);

View file

@ -79,6 +79,8 @@ const char *const hookNames[hook_MAX+1] = {
"MusicChange",
"PlayerHeight",
"PlayerCanEnterSpinGaps",
"KeyDown",
"KeyUp",
NULL
};
@ -2061,3 +2063,73 @@ UINT8 LUAh_PlayerCanEnterSpinGaps(player_t *player)
lua_settop(gL, 0);
return canEnter;
}
// Hook for key press
boolean LUAh_KeyDown(INT32 keycode)
{
hook_p hookp;
boolean override = false;
if (!gL || !(hooksAvailable[hook_KeyDown/8] & (1<<(hook_KeyDown%8))))
return false;
lua_settop(gL, 0);
lua_pushcfunction(gL, LUA_GetErrorMessage);
for (hookp = roothook; hookp; hookp = hookp->next)
{
if (hookp->type != hook_KeyDown)
continue;
PushHook(gL, hookp);
lua_pushinteger(gL, keycode);
if (lua_pcall(gL, 1, 1, 1)) {
if (!hookp->error || cv_debug & DBG_LUA)
CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1));
lua_pop(gL, 1);
hookp->error = true;
continue;
}
if (lua_toboolean(gL, -1))
override = true;
lua_pop(gL, 1);
}
lua_settop(gL, 0);
return override;
}
// Hook for key release
boolean LUAh_KeyUp(INT32 keycode)
{
hook_p hookp;
boolean override = false;
if (!gL || !(hooksAvailable[hook_KeyUp/8] & (1<<(hook_KeyUp%8))))
return false;
lua_settop(gL, 0);
lua_pushcfunction(gL, LUA_GetErrorMessage);
for (hookp = roothook; hookp; hookp = hookp->next)
{
if (hookp->type != hook_KeyUp)
continue;
PushHook(gL, hookp);
lua_pushinteger(gL, keycode);
if (lua_pcall(gL, 1, 1, 1)) {
if (!hookp->error || cv_debug & DBG_LUA)
CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1));
lua_pop(gL, 1);
hookp->error = true;
continue;
}
if (lua_toboolean(gL, -1))
override = true;
lua_pop(gL, 1);
}
lua_settop(gL, 0);
return override;
}

214
src/lua_inputlib.c Normal file
View file

@ -0,0 +1,214 @@
// SONIC ROBO BLAST 2
//-----------------------------------------------------------------------------
// Copyright (C) 2021 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 "lua_script.h"
#include "lua_libs.h"
///////////////
// 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_keyNumToString(lua_State *L)
{
int i = luaL_checkinteger(L, 1);
lua_pushstring(L, G_KeyNumToString(i));
return 1;
}
static int lib_keyStringToNum(lua_State *L)
{
const char *str = luaL_checkstring(L, 1);
lua_pushinteger(L, G_KeyStringToNum(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 luaL_Reg lib[] = {
{"G_GameControlDown", lib_gameControlDown},
{"G_GameControl2Down", lib_gameControl2Down},
{"G_GameControlToKeyNum", lib_gameControlToKeyNum},
{"G_GameControl2ToKeyNum", lib_gameControl2ToKeyNum},
{"G_JoyAxis", lib_joyAxis},
{"G_Joy2Axis", lib_joy2Axis},
{"G_KeyNumToString", lib_keyNumToString},
{"G_KeyStringToNum", lib_keyStringToNum},
{"HU_KeyNumPrintable", lib_keyNumPrintable},
{"HU_ShiftKeyNum", lib_shiftKeyNum},
{NULL, NULL}
};
///////////////////
// 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;
}
///////////
// 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
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_newuserdata(L, 0);
lua_createtable(L, 0, 2);
lua_pushcfunction(L, lib_getGameKeyDown);
lua_setfield(L, -2, "__index");
lua_pushcfunction(L, lib_setGameKeyDown);
lua_setfield(L, -2, "__newindex");
lua_pushcfunction(L, lib_lenGameKeyDown);
lua_setfield(L, -2, "__len");
lua_setmetatable(L, -2);
lua_setglobal(L, "gamekeydown");
luaL_newmetatable(L, META_MOUSE);
lua_pushcfunction(L, mouse_get);
lua_setfield(L, -2, "__index");
lua_pushcfunction(L, mouse_num);
lua_setfield(L, -2, "__len");
lua_pop(L, 1);
// Set global functions
lua_pushvalue(L, LUA_GLOBALSINDEX);
luaL_register(L, NULL, lib);
return 0;
}

View file

@ -88,6 +88,8 @@ extern lua_State *gL;
#define META_LUABANKS "LUABANKS[]*"
#define META_MOUSE "MOUSE_T*"
boolean luaL_checkboolean(lua_State *L, int narg);
int LUA_EnumLib(lua_State *L);
@ -106,3 +108,4 @@ int LUA_TagLib(lua_State *L);
int LUA_PolyObjLib(lua_State *L);
int LUA_BlockmapLib(lua_State *L);
int LUA_HudLib(lua_State *L);
int LUA_InputLib(lua_State *L);

View file

@ -20,6 +20,7 @@
#include "r_state.h"
#include "r_sky.h"
#include "g_game.h"
#include "g_input.h"
#include "f_finale.h"
#include "byteptr.h"
#include "p_saveg.h"
@ -57,6 +58,7 @@ static lua_CFunction liblist[] = {
LUA_PolyObjLib, // polyobj_t
LUA_BlockmapLib, // blockmap stuff
LUA_HudLib, // HUD stuff
LUA_InputLib, // inputs
NULL
};
@ -380,6 +382,12 @@ int LUA_PushGlobals(lua_State *L, const char *word)
} else if (fastcmp(word, "gamestate")) {
lua_pushinteger(L, gamestate);
return 1;
} else if (fastcmp(word, "mouse")) {
LUA_PushUserdata(L, &mouse, META_MOUSE);
return 1;
} else if (fastcmp(word, "mouse2")) {
LUA_PushUserdata(L, &mouse2, META_MOUSE);
return 1;
}
return 0;
}
@ -934,6 +942,7 @@ enum
ARCH_SLOPE,
ARCH_MAPHEADER,
ARCH_SKINCOLOR,
ARCH_MOUSE,
ARCH_TEND=0xFF,
};
@ -961,6 +970,7 @@ static const struct {
{META_SLOPE, ARCH_SLOPE},
{META_MAPHEADER, ARCH_MAPHEADER},
{META_SKINCOLOR, ARCH_SKINCOLOR},
{META_MOUSE, ARCH_MOUSE},
{NULL, ARCH_NULL}
};
@ -1268,7 +1278,6 @@ static UINT8 ArchiveValue(int TABLESINDEX, int myindex)
}
break;
}
case ARCH_SKINCOLOR:
{
skincolor_t *info = *((skincolor_t **)lua_touserdata(gL, myindex));
@ -1276,6 +1285,13 @@ static UINT8 ArchiveValue(int TABLESINDEX, int myindex)
WRITEUINT16(save_p, info - skincolors);
break;
}
case ARCH_MOUSE:
{
mouse_t *m = *((mouse_t **)lua_touserdata(gL, myindex));
WRITEUINT8(save_p, ARCH_MOUSE);
WRITEUINT8(save_p, m == &mouse ? 1 : 2);
break;
}
default:
WRITEUINT8(save_p, ARCH_NULL);
return 2;
@ -1527,6 +1543,9 @@ static UINT8 UnArchiveValue(int TABLESINDEX)
case ARCH_SKINCOLOR:
LUA_PushUserdata(gL, &skincolors[READUINT16(save_p)], META_SKINCOLOR);
break;
case ARCH_MOUSE:
LUA_PushUserdata(gL, READUINT16(save_p) == 1 ? &mouse : &mouse2, META_MOUSE);
break;
case ARCH_TEND:
return 1;
}

View file

@ -12683,13 +12683,13 @@ static void M_DrawControl(void)
else
{
if (keys[0] != KEY_NULL)
strcat (tmp, G_KeynumToString (keys[0]));
strcat (tmp, G_KeyNumToString (keys[0]));
if (keys[0] != KEY_NULL && keys[1] != KEY_NULL)
strcat(tmp," or ");
if (keys[1] != KEY_NULL)
strcat (tmp, G_KeynumToString (keys[1]));
strcat (tmp, G_KeyNumToString (keys[1]));
}

View file

@ -406,6 +406,7 @@
<ClCompile Include="..\lua_hooklib.c" />
<ClCompile Include="..\lua_hudlib.c" />
<ClCompile Include="..\lua_infolib.c" />
<ClCompile Include="..\lua_inputlib.c" />
<ClCompile Include="..\lua_maplib.c" />
<ClCompile Include="..\lua_mathlib.c" />
<ClCompile Include="..\lua_mobjlib.c" />

View file

@ -720,6 +720,9 @@
<ClCompile Include="..\lua_infolib.c">
<Filter>LUA</Filter>
</ClCompile>
<ClCompile Include="..\lua_inputlib.c">
<Filter>LUA</Filter>
</ClCompile>
<ClCompile Include="..\lua_maplib.c">
<Filter>LUA</Filter>
</ClCompile>