diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 33898c9a1..e639ae14d 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -284,6 +284,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
diff --git a/src/blua/Makefile.cfg b/src/blua/Makefile.cfg
index 3a2962e65..4536628ba 100644
--- a/src/blua/Makefile.cfg
+++ b/src/blua/Makefile.cfg
@@ -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
diff --git a/src/console.c b/src/console.c
index 9e65a97b1..b3c413840 100644
--- a/src/console.c
+++ b/src/console.c
@@ -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"));
diff --git a/src/d_main.c b/src/d_main.c
index 900390864..1b3449ec1 100644
--- a/src/d_main.c
+++ b/src/d_main.c
@@ -175,10 +175,53 @@ void D_ProcessEvents(void)
boolean eaten;
+ // Reset possibly stale mouse info
+ G_SetMouseDeltas(0, 0, 1);
+ G_SetMouseDeltas(0, 0, 2);
+ mouse.buttons &= ~(MB_SCROLLUP|MB_SCROLLDOWN);
+ mouse2.buttons &= ~(MB_SCROLLUP|MB_SCROLLDOWN);
+
for (; eventtail != eventhead; eventtail = (eventtail+1) & (MAXEVENTS-1))
{
+ boolean hooked = false;
+
ev = &events[eventtail];
+ // Set mouse buttons early in case event is eaten later
+ if (ev->type == ev_keydown || ev->type == ev_keyup)
+ {
+ // Mouse buttons
+ if ((UINT32)(ev->data1 - KEY_MOUSE1) < MOUSEBUTTONS)
+ {
+ if (ev->type == ev_keydown)
+ mouse.buttons |= 1 << (ev->data1 - KEY_MOUSE1);
+ else
+ mouse.buttons &= ~(1 << (ev->data1 - KEY_MOUSE1));
+ }
+ else if ((UINT32)(ev->data1 - KEY_2MOUSE1) < MOUSEBUTTONS)
+ {
+ if (ev->type == ev_keydown)
+ mouse2.buttons |= 1 << (ev->data1 - KEY_2MOUSE1);
+ else
+ mouse2.buttons &= ~(1 << (ev->data1 - KEY_2MOUSE1));
+ }
+ // Scroll (has no keyup event)
+ else switch (ev->data1) {
+ case KEY_MOUSEWHEELUP:
+ mouse.buttons |= MB_SCROLLUP;
+ break;
+ case KEY_MOUSEWHEELDOWN:
+ mouse.buttons |= MB_SCROLLDOWN;
+ break;
+ case KEY_2MOUSEWHEELUP:
+ mouse2.buttons |= MB_SCROLLUP;
+ break;
+ case KEY_2MOUSEWHEELDOWN:
+ mouse2.buttons |= MB_SCROLLDOWN;
+ break;
+ }
+ }
+
// Screenshots over everything so that they can be taken anywhere.
if (M_ScreenshotResponder(ev))
continue; // ate the event
@@ -189,6 +232,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);
@@ -203,6 +252,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);
@@ -217,8 +272,16 @@ void D_ProcessEvents(void)
if (eaten)
continue; // ate the event
+ if (!hooked && G_LuaResponder(ev))
+ continue;
+
G_Responder(ev);
}
+
+ if (mouse.rdx || mouse.rdy)
+ G_SetMouseDeltas(mouse.rdx, mouse.rdy, 1);
+ if (mouse2.rdx || mouse2.rdy)
+ G_SetMouseDeltas(mouse2.rdx, mouse2.rdy, 2);
}
//
diff --git a/src/deh_tables.c b/src/deh_tables.c
index 23faf0092..677b23214 100644
--- a/src/deh_tables.c
+++ b/src/deh_tables.c
@@ -22,6 +22,9 @@
#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 "i_joy.h"
+#include "g_input.h" // Game controls (for lua)
#include "deh_tables.h"
@@ -5455,6 +5458,76 @@ 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},
+ {"JOYAXISRANGE",JOYAXISRANGE},
+
+ // 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},
+
+ // Mouse buttons
+ {"MB_BUTTON1",MB_BUTTON1},
+ {"MB_BUTTON2",MB_BUTTON2},
+ {"MB_BUTTON3",MB_BUTTON3},
+ {"MB_BUTTON4",MB_BUTTON4},
+ {"MB_BUTTON5",MB_BUTTON5},
+ {"MB_BUTTON6",MB_BUTTON6},
+ {"MB_BUTTON7",MB_BUTTON7},
+ {"MB_BUTTON8",MB_BUTTON8},
+ {"MB_SCROLLUP",MB_SCROLLUP},
+ {"MB_SCROLLDOWN",MB_SCROLLDOWN},
+
{NULL,0}
};
diff --git a/src/g_game.c b/src/g_game.c
index debc27096..acd43f3c6 100644
--- a/src/g_game.c
+++ b/src/g_game.c
@@ -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)
@@ -1094,7 +1078,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
angle_t drawangleoffset = (player->powers[pw_carry] == CR_ROLLOUT) ? ANGLE_180 : 0;
INT32 chasecam, chasefreelook, alwaysfreelook, usejoystick, invertmouse, turnmultiplier, mousemove;
controlstyle_e controlstyle = G_ControlStyle(ssplayer);
- INT32 *mx; INT32 *my; INT32 *mly;
+ INT32 mdx, mdy, mldy;
static INT32 turnheld[2]; // for accelerative turning
static boolean keyboard_look[2]; // true if lookup/down using keyboard
@@ -1117,9 +1101,9 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
invertmouse = cv_invertmouse.value;
turnmultiplier = cv_cam_turnmultiplier.value;
mousemove = cv_mousemove.value;
- mx = &mousex;
- my = &mousey;
- mly = &mlooky;
+ mdx = mouse.dx;
+ mdy = -mouse.dy;
+ mldy = -mouse.mlookdy;
G_CopyTiccmd(cmd, I_BaseTiccmd(), 1); // empty, or external driver
}
else
@@ -1131,12 +1115,15 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
invertmouse = cv_invertmouse2.value;
turnmultiplier = cv_cam2_turnmultiplier.value;
mousemove = cv_mousemove2.value;
- mx = &mouse2x;
- my = &mouse2y;
- mly = &mlook2y;
+ mdx = mouse2.dx;
+ mdy = -mouse2.dy;
+ mldy = -mouse2.mlookdy;
G_CopyTiccmd(cmd, I_BaseTiccmd2(), 1); // empty, or external driver
}
+ if (menuactive || CON_Ready() || chat_on)
+ mdx = mdy = mldy = 0;
+
strafeisturn = controlstyle == CS_SIMPLE && ticcmd_centerviewdown[forplayer] &&
((cv_cam_lockedinput[forplayer].value && !ticcmd_ztargetfocus[forplayer]) || (player->pflags & PF_STARTDASH)) &&
!player->climbing && player->powers[pw_carry] != CR_MINECART;
@@ -1179,10 +1166,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);
@@ -1261,8 +1248,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);
@@ -1318,12 +1305,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;
@@ -1339,7 +1326,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;
@@ -1457,7 +1444,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;
@@ -1476,7 +1463,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
keyboard_look[forplayer] = false;
// looking up/down
- *myaiming += (*mly<<19)*player_invert*screen_invert;
+ *myaiming += (mldy<<19)*player_invert*screen_invert;
}
if (analogjoystickmove && joyaiming[forplayer] && lookjoystickvector.yaxis != 0 && configlookaxis != 0)
@@ -1510,24 +1497,22 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
}
if (!mouseaiming && mousemove)
- forward += *my;
+ forward += mdy;
if ((!demoplayback && (player->pflags & PF_SLIDING))) // Analog for mouse
- side += *mx*2;
+ side += mdx*2;
else if (controlstyle == CS_LMAOGALOG)
{
- if (*mx)
+ if (mdx)
{
- if (*mx > 0)
+ if (mdx > 0)
cmd->buttons |= BT_CAMRIGHT;
else
cmd->buttons |= BT_CAMLEFT;
}
}
else
- cmd->angleturn = (INT16)(cmd->angleturn - (*mx*8));
-
- *mx = *my = *mly = 0;
+ cmd->angleturn = (INT16)(cmd->angleturn - (mdx*8));
if (forward > MAXPLMOVE)
forward = MAXPLMOVE;
@@ -1878,8 +1863,8 @@ void G_DoLoadLevel(boolean resetplayer)
joyxmove[i] = joyymove[i] = 0;
joy2xmove[i] = joy2ymove[i] = 0;
}
- mousex = mousey = 0;
- mouse2x = mouse2y = 0;
+ G_SetMouseDeltas(0, 0, 1);
+ G_SetMouseDeltas(0, 0, 2);
// clear hud messages remains (usually from game startup)
CON_ClearHUD();
@@ -2203,6 +2188,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.
@@ -3103,8 +3098,8 @@ void G_DoReborn(INT32 playernum)
joyxmove[i] = joyymove[i] = 0;
joy2xmove[i] = joy2ymove[i] = 0;
}
- mousex = mousey = 0;
- mouse2x = mouse2y = 0;
+ G_SetMouseDeltas(0, 0, 1);
+ G_SetMouseDeltas(0, 0, 2);
// clear hud messages remains (usually from game startup)
CON_ClearHUD();
diff --git a/src/g_game.h b/src/g_game.h
index 98336ad44..f98269fce 100644
--- a/src/g_game.h
+++ b/src/g_game.h
@@ -85,6 +85,25 @@ typedef enum
} lockassist_e;
+typedef enum
+{
+ JA_NONE = 0,
+ JA_TURN,
+ JA_MOVE,
+ JA_LOOK,
+ JA_STRAFE,
+
+ JA_DIGITAL, // axes henceforth use digital deadzone
+
+ JA_JUMP = JA_DIGITAL,
+ 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);
diff --git a/src/g_input.c b/src/g_input.c
index 357081e1d..2f7980c64 100644
--- a/src/g_input.c
+++ b/src/g_input.c
@@ -31,10 +31,8 @@ consvar_t cv_mouseysens = CVAR_INIT ("mouseysens", "20", CV_SAVE, mousesens_cons
consvar_t cv_mouseysens2 = CVAR_INIT ("mouseysens2", "20", CV_SAVE, mousesens_cons_t, NULL);
consvar_t cv_controlperkey = CVAR_INIT ("controlperkey", "One", CV_SAVE, onecontrolperkey_cons_t, NULL);
-INT32 mousex, mousey;
-INT32 mlooky; // like mousey but with a custom sensitivity for mlook
-
-INT32 mouse2x, mouse2y, mlook2y;
+mouse_t mouse;
+mouse_t mouse2;
// joystick values are repeated
INT32 joyxmove[JOYAXISSET], joyymove[JOYAXISSET], joy2xmove[JOYAXISSET], joy2ymove[JOYAXISSET];
@@ -140,11 +138,8 @@ void G_MapEventsToControls(event_t *ev)
break;
case ev_mouse: // buttons are virtual keys
- if (menuactive || CON_Ready() || chat_on)
- break;
- mousex = (INT32)(ev->data2*((cv_mousesens.value*cv_mousesens.value)/110.0f + 0.1f));
- mousey = (INT32)(ev->data3*((cv_mousesens.value*cv_mousesens.value)/110.0f + 0.1f));
- mlooky = (INT32)(ev->data3*((cv_mouseysens.value*cv_mousesens.value)/110.0f + 0.1f));
+ mouse.rdx = ev->data2;
+ mouse.rdy = ev->data3;
break;
case ev_joystick: // buttons are virtual keys
@@ -166,9 +161,8 @@ void G_MapEventsToControls(event_t *ev)
case ev_mouse2: // buttons are virtual keys
if (menuactive || CON_Ready() || chat_on)
break;
- mouse2x = (INT32)(ev->data2*((cv_mousesens2.value*cv_mousesens2.value)/110.0f + 0.1f));
- mouse2y = (INT32)(ev->data3*((cv_mousesens2.value*cv_mousesens2.value)/110.0f + 0.1f));
- mlook2y = (INT32)(ev->data3*((cv_mouseysens2.value*cv_mousesens2.value)/110.0f + 0.1f));
+ mouse2.rdx = ev->data2;
+ mouse2.rdy = ev->data3;
break;
default:
@@ -630,7 +624,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];
@@ -654,7 +648,7 @@ const char *G_KeynumToString(INT32 keynum)
return keynamestr;
}
-INT32 G_KeyStringtoNum(const char *keystr)
+INT32 G_KeyStringToNum(const char *keystr)
{
UINT32 j;
@@ -817,10 +811,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");
}
@@ -828,10 +822,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");
}
@@ -1007,8 +1001,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)
@@ -1073,3 +1067,17 @@ void Command_Setcontrol2_f(void)
setcontrol(gamecontrolbis);
}
+
+void G_SetMouseDeltas(INT32 dx, INT32 dy, UINT8 ssplayer)
+{
+ mouse_t *m = ssplayer == 1 ? &mouse : &mouse2;
+ consvar_t *cvsens, *cvysens;
+
+ cvsens = ssplayer == 1 ? &cv_mousesens : &cv_mousesens2;
+ cvysens = ssplayer == 1 ? &cv_mouseysens : &cv_mouseysens2;
+ m->rdx = dx;
+ m->rdy = dy;
+ m->dx = (INT32)(m->rdx*((cvsens->value*cvsens->value)/110.0f + 0.1f));
+ m->dy = (INT32)(m->rdy*((cvsens->value*cvsens->value)/110.0f + 0.1f));
+ m->mlookdy = (INT32)(m->rdy*((cvysens->value*cvsens->value)/110.0f + 0.1f));
+}
diff --git a/src/g_input.h b/src/g_input.h
index 609141825..ffd0cb560 100644
--- a/src/g_input.h
+++ b/src/g_input.h
@@ -116,9 +116,29 @@ extern consvar_t cv_mousesens, cv_mouseysens;
extern consvar_t cv_mousesens2, cv_mouseysens2;
extern consvar_t cv_controlperkey;
-extern INT32 mousex, mousey;
-extern INT32 mlooky; //mousey with mlookSensitivity
-extern INT32 mouse2x, mouse2y, mlook2y;
+typedef struct
+{
+ INT32 dx; // deltas with mousemove sensitivity
+ INT32 dy;
+ INT32 mlookdy; // dy with mouselook sensitivity
+ INT32 rdx; // deltas without sensitivity
+ INT32 rdy;
+ UINT16 buttons;
+} mouse_t;
+
+#define MB_BUTTON1 0x0001
+#define MB_BUTTON2 0x0002
+#define MB_BUTTON3 0x0004
+#define MB_BUTTON4 0x0008
+#define MB_BUTTON5 0x0010
+#define MB_BUTTON6 0x0020
+#define MB_BUTTON7 0x0040
+#define MB_BUTTON8 0x0080
+#define MB_SCROLLUP 0x0100
+#define MB_SCROLLDOWN 0x0200
+
+extern mouse_t mouse;
+extern mouse_t mouse2;
extern INT32 joyxmove[JOYAXISSET], joyymove[JOYAXISSET], joy2xmove[JOYAXISSET], joy2ymove[JOYAXISSET];
@@ -161,8 +181,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);
@@ -175,4 +195,7 @@ void G_CopyControls(INT32 (*setupcontrols)[2], INT32 (*fromcontrols)[2], const I
void G_SaveKeySetting(FILE *f, INT32 (*fromcontrols)[2], INT32 (*fromcontrolsbis)[2]);
INT32 G_CheckDoubleUsage(INT32 keynum, boolean modify);
+// sets the members of a mouse_t given position deltas
+void G_SetMouseDeltas(INT32 dx, INT32 dy, UINT8 ssplayer);
+
#endif
diff --git a/src/i_system.h b/src/i_system.h
index b88ea3177..e046fd620 100644
--- a/src/i_system.h
+++ b/src/i_system.h
@@ -314,4 +314,16 @@ const char *I_ClipboardPaste(void);
void I_RegisterSysCommands(void);
+/** \brief Return the position of the cursor relative to the top-left window corner.
+*/
+void I_GetCursorPosition(INT32 *x, INT32 *y);
+
+/** \brief Returns whether the mouse is grabbed
+*/
+boolean I_GetMouseGrab(void);
+
+/** \brief Sets whether the mouse is grabbed
+*/
+void I_SetMouseGrab(boolean grab);
+
#endif
diff --git a/src/lua_baselib.c b/src/lua_baselib.c
index 594ac6af2..d6f40846c 100644
--- a/src/lua_baselib.c
+++ b/src/lua_baselib.c
@@ -213,6 +213,8 @@ static const struct {
{META_ACTION, "action"},
{META_LUABANKS, "luabanks[]"},
+
+ {META_MOUSE, "mouse_t"},
{NULL, NULL}
};
diff --git a/src/lua_hook.h b/src/lua_hook.h
index 3a5ba3afd..22f81074d 100644
--- a/src/lua_hook.h
+++ b/src/lua_hook.h
@@ -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);
diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c
index 5dca0d7a0..08226311e 100644
--- a/src/lua_hooklib.c
+++ b/src/lua_hooklib.c
@@ -79,6 +79,8 @@ const char *const hookNames[hook_MAX+1] = {
"MusicChange",
"PlayerHeight",
"PlayerCanEnterSpinGaps",
+ "KeyDown",
+ "KeyUp",
NULL
};
@@ -1945,7 +1947,7 @@ boolean LUAh_MusicChange(const char *oldname, char *newname, UINT16 *mflags, boo
lua_pushinteger(gL, *prefadems);
lua_pushinteger(gL, *fadeinms);
if (lua_pcall(gL, 7, 6, 1)) {
- CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL,-1));
+ CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1));
lua_pop(gL, 1);
continue;
}
@@ -2064,3 +2066,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;
+}
diff --git a/src/lua_inputlib.c b/src/lua_inputlib.c
new file mode 100644
index 000000000..217202222
--- /dev/null
+++ b/src/lua_inputlib.c
@@ -0,0 +1,242 @@
+// 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 "i_system.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 int lib_getMouseGrab(lua_State *L)
+{
+ lua_pushboolean(L, I_GetMouseGrab());
+ return 1;
+}
+
+static int lib_setMouseGrab(lua_State *L)
+{
+ boolean grab = luaL_checkboolean(L, 1);
+ I_SetMouseGrab(grab);
+ return 0;
+}
+
+static boolean 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[] = {
+ {"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},
+ {"I_GetMouseGrab", lib_getMouseGrab},
+ {"I_SetMouseGrab", lib_setMouseGrab},
+ {"I_GetCursorPosition", lib_getCursorPosition},
+ {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 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_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;
+}
diff --git a/src/lua_libs.h b/src/lua_libs.h
index 05061f118..668eb99b0 100644
--- a/src/lua_libs.h
+++ b/src/lua_libs.h
@@ -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);
diff --git a/src/lua_script.c b/src/lua_script.c
index 4e04c2ee0..3074b159b 100644
--- a/src/lua_script.c
+++ b/src/lua_script.c
@@ -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
};
@@ -385,6 +387,11 @@ int LUA_PushGlobals(lua_State *L, const char *word)
return 1;
} else if (fastcmp(word, "stagefailed")) {
lua_pushboolean(L, stagefailed);
+ } 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;
@@ -921,6 +928,7 @@ enum
ARCH_SLOPE,
ARCH_MAPHEADER,
ARCH_SKINCOLOR,
+ ARCH_MOUSE,
ARCH_TEND=0xFF,
};
@@ -948,6 +956,7 @@ static const struct {
{META_SLOPE, ARCH_SLOPE},
{META_MAPHEADER, ARCH_MAPHEADER},
{META_SKINCOLOR, ARCH_SKINCOLOR},
+ {META_MOUSE, ARCH_MOUSE},
{NULL, ARCH_NULL}
};
@@ -1255,7 +1264,6 @@ static UINT8 ArchiveValue(int TABLESINDEX, int myindex)
}
break;
}
-
case ARCH_SKINCOLOR:
{
skincolor_t *info = *((skincolor_t **)lua_touserdata(gL, myindex));
@@ -1263,6 +1271,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;
@@ -1514,6 +1529,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;
}
diff --git a/src/m_menu.c b/src/m_menu.c
index b19479797..525e9cbdd 100644
--- a/src/m_menu.c
+++ b/src/m_menu.c
@@ -3307,7 +3307,7 @@ boolean M_Responder(event_t *ev)
}
else if (ev->type == ev_mouse && mousewait < I_GetTime())
{
- pmousey += ev->data3;
+ pmousey -= ev->data3;
if (pmousey < lasty-30)
{
ch = KEY_DOWNARROW;
@@ -12826,13 +12826,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]));
}
diff --git a/src/sdl/Srb2SDL-vc10.vcxproj b/src/sdl/Srb2SDL-vc10.vcxproj
index de9c4f32f..105e1def8 100644
--- a/src/sdl/Srb2SDL-vc10.vcxproj
+++ b/src/sdl/Srb2SDL-vc10.vcxproj
@@ -407,6 +407,7 @@
+
diff --git a/src/sdl/Srb2SDL-vc10.vcxproj.filters b/src/sdl/Srb2SDL-vc10.vcxproj.filters
index b59d9864d..404890397 100644
--- a/src/sdl/Srb2SDL-vc10.vcxproj.filters
+++ b/src/sdl/Srb2SDL-vc10.vcxproj.filters
@@ -723,6 +723,9 @@
LUA
+
+ LUA
+
LUA
diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c
index 4ad3769ab..d68e3e435 100644
--- a/src/sdl/i_system.c
+++ b/src/sdl/i_system.c
@@ -1969,7 +1969,7 @@ void I_GetMouseEvents(void)
event.data1 = 0;
// event.data1 = buttons; // not needed
event.data2 = handlermouse2x << 1;
- event.data3 = -handlermouse2y << 1;
+ event.data3 = handlermouse2y << 1;
handlermouse2x = 0;
handlermouse2y = 0;
diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c
index 5f18720f8..c387e5a18 100644
--- a/src/sdl/i_video.c
+++ b/src/sdl/i_video.c
@@ -405,6 +405,19 @@ void I_UpdateMouseGrab(void)
SDLdoGrabMouse();
}
+boolean I_GetMouseGrab(void)
+{
+ return SDL_GetWindowGrab(window);
+}
+
+void I_SetMouseGrab(boolean grab)
+{
+ if (grab)
+ SDLdoGrabMouse();
+ else
+ SDLdoUngrabMouse();
+}
+
static void VID_Command_NumModes_f (void)
{
CONS_Printf(M_GetText("%d video mode(s) available(s)\n"), VID_NumModes());
@@ -673,8 +686,8 @@ static void Impl_HandleMouseMotionEvent(SDL_MouseMotionEvent evt)
{
if (SDL_GetMouseFocus() == window && SDL_GetKeyboardFocus() == window)
{
- mousemovex += evt.xrel;
- mousemovey += -evt.yrel;
+ mousemovex += evt.xrel;
+ mousemovey += evt.yrel;
SDL_SetWindowGrab(window, SDL_TRUE);
}
firstmove = false;
@@ -1938,3 +1951,8 @@ void I_ShutdownGraphics(void)
framebuffer = SDL_FALSE;
}
#endif
+
+void I_GetCursorPosition(INT32 *x, INT32 *y)
+{
+ SDL_GetMouseState(x, y);
+}