mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-10-30 08:01:28 +00:00
Handle gamepads from interface dynamically
Fixes numerous issues with hotswapping, gamepad assignment, and menu responsiveness.
This commit is contained in:
parent
feb70916c1
commit
86a9579e16
18 changed files with 558 additions and 597 deletions
|
|
@ -449,7 +449,7 @@ boolean AM_Responder(event_t *ev)
|
||||||
{
|
{
|
||||||
//faB: prevent alt-tab in win32 version to activate automap just before
|
//faB: prevent alt-tab in win32 version to activate automap just before
|
||||||
// minimizing the app; doesn't do any harm to the DOS version
|
// minimizing the app; doesn't do any harm to the DOS version
|
||||||
if (!gamekeydown[0][KEY_LALT] && !gamekeydown[0][KEY_RALT])
|
if (!G_GetDeviceGameKeyDownArray(0)[KEY_LALT] && !G_GetDeviceGameKeyDownArray(0)[KEY_RALT])
|
||||||
{
|
{
|
||||||
bigstate = 0; //added : 24-01-98 : toggle off large view
|
bigstate = 0; //added : 24-01-98 : toggle off large view
|
||||||
AM_Start();
|
AM_Start();
|
||||||
|
|
|
||||||
|
|
@ -1485,7 +1485,7 @@ void CL_UpdateServerList (void)
|
||||||
|
|
||||||
static void M_ConfirmConnect(void)
|
static void M_ConfirmConnect(void)
|
||||||
{
|
{
|
||||||
if (G_PlayerInputDown(0, gc_a, 1) || gamekeydown[0][KEY_ENTER])
|
if (G_PlayerInputDown(0, gc_a, 1) || G_GetDeviceGameKeyDownArray(0)[KEY_ENTER])
|
||||||
{
|
{
|
||||||
if (totalfilesrequestednum > 0)
|
if (totalfilesrequestednum > 0)
|
||||||
{
|
{
|
||||||
|
|
@ -1512,7 +1512,7 @@ static void M_ConfirmConnect(void)
|
||||||
|
|
||||||
M_StopMessage(0);
|
M_StopMessage(0);
|
||||||
}
|
}
|
||||||
else if (G_PlayerInputDown(0, gc_b, 1) || G_PlayerInputDown(0, gc_x, 1) || gamekeydown[0][KEY_ESCAPE])
|
else if (G_PlayerInputDown(0, gc_b, 1) || G_PlayerInputDown(0, gc_x, 1) || G_GetDeviceGameKeyDownArray(0)[KEY_ESCAPE])
|
||||||
{
|
{
|
||||||
cl_mode = CL_ABORTED;
|
cl_mode = CL_ABORTED;
|
||||||
M_StopMessage(0);
|
M_StopMessage(0);
|
||||||
|
|
@ -1962,7 +1962,7 @@ static boolean CL_ServerConnectionTicker(const char *tmpsave, tic_t *oldtic, tic
|
||||||
renderdeltatics = FRACUNIT;
|
renderdeltatics = FRACUNIT;
|
||||||
rendertimefrac = FRACUNIT;
|
rendertimefrac = FRACUNIT;
|
||||||
|
|
||||||
memset(deviceResponding, false, sizeof (deviceResponding));
|
G_ResetAllDeviceResponding();
|
||||||
|
|
||||||
if (netgame)
|
if (netgame)
|
||||||
{
|
{
|
||||||
|
|
@ -1979,7 +1979,7 @@ static boolean CL_ServerConnectionTicker(const char *tmpsave, tic_t *oldtic, tic
|
||||||
{
|
{
|
||||||
if (G_PlayerInputDown(0, gc_b, 1)
|
if (G_PlayerInputDown(0, gc_b, 1)
|
||||||
|| G_PlayerInputDown(0, gc_x, 1)
|
|| G_PlayerInputDown(0, gc_x, 1)
|
||||||
|| gamekeydown[0][KEY_ESCAPE])
|
|| G_GetDeviceGameKeyDownArray(0)[KEY_ESCAPE])
|
||||||
cl_mode = CL_ABORTED;
|
cl_mode = CL_ABORTED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,9 @@ typedef enum
|
||||||
ev_keyup,
|
ev_keyup,
|
||||||
ev_console,
|
ev_console,
|
||||||
ev_mouse,
|
ev_mouse,
|
||||||
ev_joystick,
|
ev_gamepad_axis,
|
||||||
|
ev_gamepad_device_added,
|
||||||
|
ev_gamepad_device_removed,
|
||||||
} evtype_t;
|
} evtype_t;
|
||||||
|
|
||||||
// Event structure.
|
// Event structure.
|
||||||
|
|
@ -38,7 +40,7 @@ struct event_t
|
||||||
INT32 data1; // keys / mouse/joystick buttons
|
INT32 data1; // keys / mouse/joystick buttons
|
||||||
INT32 data2; // mouse/joystick x move
|
INT32 data2; // mouse/joystick x move
|
||||||
INT32 data3; // mouse/joystick y move
|
INT32 data3; // mouse/joystick y move
|
||||||
INT32 device; // which player's device it belongs to
|
INT32 device; // which device ID it belongs to (controller ID)
|
||||||
};
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
|
||||||
56
src/d_main.c
56
src/d_main.c
|
|
@ -171,6 +171,54 @@ UINT8 ctrldown = 0; // 0x1 left, 0x2 right
|
||||||
UINT8 altdown = 0; // 0x1 left, 0x2 right
|
UINT8 altdown = 0; // 0x1 left, 0x2 right
|
||||||
boolean capslock = 0; // gee i wonder what this does.
|
boolean capslock = 0; // gee i wonder what this does.
|
||||||
|
|
||||||
|
static void HandleGamepadDeviceAdded(event_t *ev)
|
||||||
|
{
|
||||||
|
I_Assert(ev != NULL);
|
||||||
|
I_Assert(ev->type == ev_gamepad_device_added);
|
||||||
|
|
||||||
|
G_RegisterAvailableGamepad(ev->device);
|
||||||
|
CONS_Debug(DBG_GAMELOGIC, "Registered available gamepad device %d\n", ev->device);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void HandleGamepadDeviceRemoved(event_t *ev)
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
I_Assert(ev != NULL);
|
||||||
|
I_Assert(ev->type == ev_gamepad_device_removed);
|
||||||
|
|
||||||
|
G_UnregisterAvailableGamepad(ev->device);
|
||||||
|
CONS_Debug(DBG_GAMELOGIC, "Unregistered available gamepad device %d\n", ev->device);
|
||||||
|
|
||||||
|
// Downstream responders need to update player gamepad assignments, pause, etc
|
||||||
|
|
||||||
|
for (i = 0; i < MAXSPLITSCREENPLAYERS; i++)
|
||||||
|
{
|
||||||
|
INT32 device = G_GetDeviceForPlayer(i);
|
||||||
|
if (device == ev->device)
|
||||||
|
{
|
||||||
|
G_SetDeviceForPlayer(i, -1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Respond to added/removed device events, for bookkeeping available gamepads.
|
||||||
|
static void HandleGamepadDeviceEvents(event_t *ev)
|
||||||
|
{
|
||||||
|
I_Assert(ev != NULL);
|
||||||
|
|
||||||
|
switch (ev->type)
|
||||||
|
{
|
||||||
|
case ev_gamepad_device_added:
|
||||||
|
HandleGamepadDeviceAdded(ev);
|
||||||
|
break;
|
||||||
|
case ev_gamepad_device_removed:
|
||||||
|
HandleGamepadDeviceRemoved(ev);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// D_ProcessEvents
|
// D_ProcessEvents
|
||||||
// Send all the events of the given timestamp down the responder chain
|
// Send all the events of the given timestamp down the responder chain
|
||||||
|
|
@ -183,11 +231,13 @@ void D_ProcessEvents(void)
|
||||||
boolean eaten;
|
boolean eaten;
|
||||||
boolean menuresponse = false;
|
boolean menuresponse = false;
|
||||||
|
|
||||||
memset(deviceResponding, false, sizeof (deviceResponding));
|
G_ResetAllDeviceResponding();
|
||||||
for (; eventtail != eventhead; eventtail = (eventtail+1) & (MAXEVENTS-1))
|
for (; eventtail != eventhead; eventtail = (eventtail+1) & (MAXEVENTS-1))
|
||||||
{
|
{
|
||||||
ev = &events[eventtail];
|
ev = &events[eventtail];
|
||||||
|
|
||||||
|
HandleGamepadDeviceEvents(ev);
|
||||||
|
|
||||||
// Screenshots over everything so that they can be taken anywhere.
|
// Screenshots over everything so that they can be taken anywhere.
|
||||||
if (M_ScreenshotResponder(ev))
|
if (M_ScreenshotResponder(ev))
|
||||||
continue; // ate the event
|
continue; // ate the event
|
||||||
|
|
@ -976,7 +1026,7 @@ void D_ClearState(void)
|
||||||
|
|
||||||
// clear cmd building stuff
|
// clear cmd building stuff
|
||||||
memset(gamekeydown, 0, sizeof (gamekeydown));
|
memset(gamekeydown, 0, sizeof (gamekeydown));
|
||||||
memset(deviceResponding, false, sizeof (deviceResponding));
|
G_ResetAllDeviceResponding();
|
||||||
|
|
||||||
// Reset the palette
|
// Reset the palette
|
||||||
if (rendermode != render_none)
|
if (rendermode != render_none)
|
||||||
|
|
@ -1507,6 +1557,8 @@ void D_SRB2Main(void)
|
||||||
CONS_Printf("I_StartupGraphics()...\n");
|
CONS_Printf("I_StartupGraphics()...\n");
|
||||||
I_StartupGraphics();
|
I_StartupGraphics();
|
||||||
|
|
||||||
|
I_StartupInput();
|
||||||
|
|
||||||
if (rendermode != render_none)
|
if (rendermode != render_none)
|
||||||
{
|
{
|
||||||
I_NewTwodeeFrame();
|
I_NewTwodeeFrame();
|
||||||
|
|
|
||||||
|
|
@ -237,9 +237,6 @@ static CV_PossibleValue_t usemouse_cons_t[] = {{0, "Off"}, {1, "On"}, {2, "Force
|
||||||
#ifdef LJOYSTICK
|
#ifdef LJOYSTICK
|
||||||
static CV_PossibleValue_t joyport_cons_t[] = {{1, "/dev/js0"}, {2, "/dev/js1"}, {3, "/dev/js2"},
|
static CV_PossibleValue_t joyport_cons_t[] = {{1, "/dev/js0"}, {2, "/dev/js1"}, {3, "/dev/js2"},
|
||||||
{4, "/dev/js3"}, {0, NULL}};
|
{4, "/dev/js3"}, {0, NULL}};
|
||||||
#else
|
|
||||||
// accept whatever value - it is in fact the joystick device number
|
|
||||||
static CV_PossibleValue_t usejoystick_cons_t[] = {{-1, "MIN"}, {MAXGAMEPADS, "MAX"}, {0, NULL}};
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static CV_PossibleValue_t teamscramble_cons_t[] = {{0, "Off"}, {1, "Random"}, {2, "Points"}, {0, NULL}};
|
static CV_PossibleValue_t teamscramble_cons_t[] = {{0, "Off"}, {1, "Random"}, {2, "Points"}, {0, NULL}};
|
||||||
|
|
@ -332,13 +329,6 @@ consvar_t cv_skipmapcheck = CVAR_INIT ("skipmapcheck", "Off", CV_SAVE, CV_OnOff,
|
||||||
|
|
||||||
consvar_t cv_usemouse = CVAR_INIT ("use_mouse", "Off", CV_SAVE|CV_CALL,usemouse_cons_t, I_StartupMouse);
|
consvar_t cv_usemouse = CVAR_INIT ("use_mouse", "Off", CV_SAVE|CV_CALL,usemouse_cons_t, I_StartupMouse);
|
||||||
|
|
||||||
consvar_t cv_usejoystick[MAXSPLITSCREENPLAYERS] = {
|
|
||||||
CVAR_INIT ("use_device", "1", CV_SAVE|CV_CALL, usejoystick_cons_t, I_InitJoystick1),
|
|
||||||
CVAR_INIT ("use_device2", "2", CV_SAVE|CV_CALL, usejoystick_cons_t, I_InitJoystick2),
|
|
||||||
CVAR_INIT ("use_device3", "3", CV_SAVE|CV_CALL, usejoystick_cons_t, I_InitJoystick3),
|
|
||||||
CVAR_INIT ("use_device4", "4", CV_SAVE|CV_CALL, usejoystick_cons_t, I_InitJoystick4)
|
|
||||||
};
|
|
||||||
|
|
||||||
#if (defined (LJOYSTICK) || defined (HAVE_SDL))
|
#if (defined (LJOYSTICK) || defined (HAVE_SDL))
|
||||||
consvar_t cv_joyscale[MAXSPLITSCREENPLAYERS] = {
|
consvar_t cv_joyscale[MAXSPLITSCREENPLAYERS] = {
|
||||||
CVAR_INIT ("padscale", "1", CV_SAVE|CV_CALL, NULL, I_JoyScale),
|
CVAR_INIT ("padscale", "1", CV_SAVE|CV_CALL, NULL, I_JoyScale),
|
||||||
|
|
@ -1039,7 +1029,6 @@ void D_RegisterClientCommands(void)
|
||||||
|
|
||||||
for (i = 0; i < MAXSPLITSCREENPLAYERS; i++)
|
for (i = 0; i < MAXSPLITSCREENPLAYERS; i++)
|
||||||
{
|
{
|
||||||
CV_RegisterVar(&cv_usejoystick[i]);
|
|
||||||
CV_RegisterVar(&cv_joyscale[i]);
|
CV_RegisterVar(&cv_joyscale[i]);
|
||||||
#ifdef LJOYSTICK
|
#ifdef LJOYSTICK
|
||||||
CV_RegisterVar(&cv_joyport[i]);
|
CV_RegisterVar(&cv_joyport[i]);
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,6 @@ extern consvar_t cv_splitplayers;
|
||||||
|
|
||||||
extern consvar_t cv_seenames;
|
extern consvar_t cv_seenames;
|
||||||
extern consvar_t cv_usemouse;
|
extern consvar_t cv_usemouse;
|
||||||
extern consvar_t cv_usejoystick[MAXSPLITSCREENPLAYERS];
|
|
||||||
extern consvar_t cv_joyscale[MAXSPLITSCREENPLAYERS];
|
extern consvar_t cv_joyscale[MAXSPLITSCREENPLAYERS];
|
||||||
#ifdef LJOYSTICK
|
#ifdef LJOYSTICK
|
||||||
extern consvar_t cv_joyport[MAXSPLITSCREENPLAYERS];
|
extern consvar_t cv_joyport[MAXSPLITSCREENPLAYERS];
|
||||||
|
|
|
||||||
46
src/g_game.c
46
src/g_game.c
|
|
@ -884,6 +884,7 @@ static INT32 keyboardMenuDefaults[][2] = {
|
||||||
INT32 G_PlayerInputAnalog(UINT8 p, INT32 gc, UINT8 menuPlayers)
|
INT32 G_PlayerInputAnalog(UINT8 p, INT32 gc, UINT8 menuPlayers)
|
||||||
{
|
{
|
||||||
INT32 deviceID;
|
INT32 deviceID;
|
||||||
|
INT32 avail_gamepad_id = 0;
|
||||||
INT32 i, j;
|
INT32 i, j;
|
||||||
INT32 deadzone = 0;
|
INT32 deadzone = 0;
|
||||||
boolean trydefaults = true;
|
boolean trydefaults = true;
|
||||||
|
|
@ -900,7 +901,22 @@ INT32 G_PlayerInputAnalog(UINT8 p, INT32 gc, UINT8 menuPlayers)
|
||||||
|
|
||||||
deadzone = (JOYAXISRANGE * cv_deadzone[p].value) / FRACUNIT;
|
deadzone = (JOYAXISRANGE * cv_deadzone[p].value) / FRACUNIT;
|
||||||
|
|
||||||
deviceID = cv_usejoystick[p].value;
|
deviceID = G_GetDeviceForPlayer(p);
|
||||||
|
|
||||||
|
if (deviceID == -1)
|
||||||
|
{
|
||||||
|
INT32 keyboard_player = G_GetPlayerForDevice(KEYBOARD_MOUSE_DEVICE);
|
||||||
|
|
||||||
|
// Player 1 is always allowed to use the keyboard in 1P (there is a check for splitscreen later in this func)
|
||||||
|
if (p == KEYBOARD_MOUSE_DEVICE && keyboard_player == -1)
|
||||||
|
{
|
||||||
|
deviceID = KEYBOARD_MOUSE_DEVICE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
goto deviceunassigned;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
retrygetcontrol:
|
retrygetcontrol:
|
||||||
for (i = 0; i < MAXINPUTMAPPING; i++)
|
for (i = 0; i < MAXINPUTMAPPING; i++)
|
||||||
|
|
@ -910,7 +926,6 @@ retrygetcontrol:
|
||||||
INT32 value = 0;
|
INT32 value = 0;
|
||||||
boolean processinput = true;
|
boolean processinput = true;
|
||||||
|
|
||||||
|
|
||||||
// for menus, keyboards have defaults!
|
// for menus, keyboards have defaults!
|
||||||
if (deviceID == 0)
|
if (deviceID == 0)
|
||||||
{
|
{
|
||||||
|
|
@ -951,9 +966,9 @@ retrygetcontrol:
|
||||||
// It's possible to access this control right now, so let's disable the default control backup for later.
|
// It's possible to access this control right now, so let's disable the default control backup for later.
|
||||||
trydefaults = false;
|
trydefaults = false;
|
||||||
|
|
||||||
value = gamekeydown[deviceID][key];
|
value = G_GetDeviceGameKeyDownArray(deviceID)[key];
|
||||||
if (menukey && gamekeydown[deviceID][menukey])
|
if (menukey && G_GetDeviceGameKeyDownArray(deviceID)[menukey])
|
||||||
value = gamekeydown[deviceID][menukey];
|
value = G_GetDeviceGameKeyDownArray(deviceID)[menukey];
|
||||||
|
|
||||||
if (value >= deadzone)
|
if (value >= deadzone)
|
||||||
{
|
{
|
||||||
|
|
@ -962,11 +977,13 @@ retrygetcontrol:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
deviceunassigned:
|
||||||
|
|
||||||
// If you're on controller, try your keyboard-based binds as an immediate backup.
|
// If you're on controller, try your keyboard-based binds as an immediate backup.
|
||||||
// Do not do this if there are more than 1 local player.
|
// Do not do this if there are more than 1 local player.
|
||||||
if (p == 0 && deviceID > 0 && !tryingotherID && menuPlayers < 2 && !splitscreen)
|
if (p == 0 && deviceID > 0 && !tryingotherID && menuPlayers < 2 && !splitscreen)
|
||||||
{
|
{
|
||||||
deviceID = 0;
|
deviceID = KEYBOARD_MOUSE_DEVICE;
|
||||||
goto retrygetcontrol;
|
goto retrygetcontrol;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -981,16 +998,21 @@ retrygetcontrol:
|
||||||
|
|
||||||
if (!tryingotherID)
|
if (!tryingotherID)
|
||||||
{
|
{
|
||||||
deviceID = MAXDEVICES;
|
avail_gamepad_id = 0;
|
||||||
tryingotherID = true;
|
tryingotherID = true;
|
||||||
}
|
}
|
||||||
loweringid:
|
loweringid:
|
||||||
deviceID--;
|
if (avail_gamepad_id >= G_GetNumAvailableGamepads())
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
deviceID = G_GetAvailableGamepadDevice(avail_gamepad_id);
|
||||||
|
avail_gamepad_id += 1;
|
||||||
if (deviceID > 0)
|
if (deviceID > 0)
|
||||||
{
|
{
|
||||||
for (i = 0; i < menuPlayers; i++)
|
for (i = 0; i < menuPlayers; i++)
|
||||||
{
|
{
|
||||||
if (deviceID != cv_usejoystick[i].value)
|
if (deviceID != G_GetDeviceForPlayer(i))
|
||||||
continue;
|
continue;
|
||||||
// Controller taken? Try again...
|
// Controller taken? Try again...
|
||||||
goto loweringid;
|
goto loweringid;
|
||||||
|
|
@ -1005,7 +1027,7 @@ loweringid:
|
||||||
trydefaults = false;
|
trydefaults = false;
|
||||||
controltable = &(gamecontroldefault[gc][0]);
|
controltable = &(gamecontroldefault[gc][0]);
|
||||||
tryingotherID = false;
|
tryingotherID = false;
|
||||||
deviceID = cv_usejoystick[p].value;
|
deviceID = G_GetDeviceForPlayer(p);
|
||||||
goto retrygetcontrol;
|
goto retrygetcontrol;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -1530,7 +1552,7 @@ void G_DoLoadLevel(boolean resetplayer)
|
||||||
|
|
||||||
// clear cmd building stuff
|
// clear cmd building stuff
|
||||||
memset(gamekeydown, 0, sizeof (gamekeydown));
|
memset(gamekeydown, 0, sizeof (gamekeydown));
|
||||||
memset(deviceResponding, false, sizeof (deviceResponding));
|
G_ResetAllDeviceResponding();
|
||||||
|
|
||||||
// clear hud messages remains (usually from game startup)
|
// clear hud messages remains (usually from game startup)
|
||||||
CON_ClearHUD();
|
CON_ClearHUD();
|
||||||
|
|
@ -1828,7 +1850,7 @@ boolean G_Responder(event_t *ev)
|
||||||
case ev_mouse:
|
case ev_mouse:
|
||||||
return true; // eat events
|
return true; // eat events
|
||||||
|
|
||||||
case ev_joystick:
|
case ev_gamepad_axis:
|
||||||
return true; // eat events
|
return true; // eat events
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
|
||||||
298
src/g_input.c
298
src/g_input.c
|
|
@ -19,6 +19,7 @@
|
||||||
#include "d_net.h"
|
#include "d_net.h"
|
||||||
#include "console.h"
|
#include "console.h"
|
||||||
#include "i_joy.h" // JOYAXISRANGE
|
#include "i_joy.h" // JOYAXISRANGE
|
||||||
|
#include "z_zone.h"
|
||||||
|
|
||||||
#define MAXMOUSESENSITIVITY 100 // sensitivity steps
|
#define MAXMOUSESENSITIVITY 100 // sensitivity steps
|
||||||
|
|
||||||
|
|
@ -35,7 +36,6 @@ consvar_t cv_controlperkey = CVAR_INIT ("controlperkey", "One", CV_SAVE, onecont
|
||||||
// current state of the keys
|
// current state of the keys
|
||||||
// FRACUNIT for fully pressed, 0 for not pressed
|
// FRACUNIT for fully pressed, 0 for not pressed
|
||||||
INT32 gamekeydown[MAXDEVICES][NUMINPUTS];
|
INT32 gamekeydown[MAXDEVICES][NUMINPUTS];
|
||||||
boolean deviceResponding[MAXDEVICES];
|
|
||||||
|
|
||||||
// two key codes (or virtual key) per game control
|
// two key codes (or virtual key) per game control
|
||||||
INT32 gamecontrol[MAXSPLITSCREENPLAYERS][num_gamecontrols][MAXINPUTMAPPING];
|
INT32 gamecontrol[MAXSPLITSCREENPLAYERS][num_gamecontrols][MAXINPUTMAPPING];
|
||||||
|
|
@ -68,13 +68,82 @@ const INT32 gcl_full[num_gcl_full] = {
|
||||||
};
|
};
|
||||||
*/
|
*/
|
||||||
|
|
||||||
INT32 G_GetDevicePlayer(INT32 deviceID)
|
static INT32 g_gamekeydown_device0[NUMINPUTS];
|
||||||
|
|
||||||
|
static INT32 g_available_gamepad_devices;
|
||||||
|
static INT32 g_gamepad_device_ids[MAXGAMEPADS];
|
||||||
|
static INT32* g_gamepad_gamekeydown[MAXGAMEPADS];
|
||||||
|
static boolean g_device0_responding;
|
||||||
|
static boolean g_gamepad_responding[MAXGAMEPADS];
|
||||||
|
static INT32 g_player_devices[MAXSPLITSCREENPLAYERS] = {-1, -1, -1, -1};
|
||||||
|
|
||||||
|
void G_RegisterAvailableGamepad(INT32 device_id)
|
||||||
|
{
|
||||||
|
I_Assert(device_id >= 1);
|
||||||
|
|
||||||
|
if (g_available_gamepad_devices == MAXGAMEPADS)
|
||||||
|
{
|
||||||
|
// too many!
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_gamepad_device_ids[g_available_gamepad_devices] = device_id;
|
||||||
|
|
||||||
|
g_gamepad_gamekeydown[g_available_gamepad_devices] = Z_CallocAlign(NUMINPUTS * sizeof(INT32), PU_STATIC, NULL, 4);
|
||||||
|
|
||||||
|
g_gamepad_responding[g_available_gamepad_devices] = false;
|
||||||
|
|
||||||
|
g_available_gamepad_devices += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void G_UnregisterAvailableGamepad(INT32 device_id)
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
I_Assert(device_id >= 1);
|
||||||
|
|
||||||
|
if (g_available_gamepad_devices <= 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < g_available_gamepad_devices; i++)
|
||||||
|
{
|
||||||
|
if (g_gamepad_device_ids[i] == device_id)
|
||||||
|
{
|
||||||
|
int32_t *old_gamekeydown = g_gamepad_gamekeydown[i];
|
||||||
|
g_gamepad_device_ids[i] = g_gamepad_device_ids[g_available_gamepad_devices - 1];
|
||||||
|
g_gamepad_gamekeydown[i] = g_gamepad_gamekeydown[g_available_gamepad_devices - 1];
|
||||||
|
g_gamepad_responding[i] = g_gamepad_responding[g_available_gamepad_devices - 1];
|
||||||
|
Z_Free(old_gamekeydown);
|
||||||
|
g_available_gamepad_devices -= 1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
INT32 G_GetNumAvailableGamepads(void)
|
||||||
|
{
|
||||||
|
return g_available_gamepad_devices;
|
||||||
|
}
|
||||||
|
|
||||||
|
INT32 G_GetAvailableGamepadDevice(INT32 available_index)
|
||||||
|
{
|
||||||
|
if (available_index < 0 || available_index >= G_GetNumAvailableGamepads())
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return g_gamepad_device_ids[available_index];
|
||||||
|
}
|
||||||
|
|
||||||
|
INT32 G_GetPlayerForDevice(INT32 device_id)
|
||||||
{
|
{
|
||||||
INT32 i;
|
INT32 i;
|
||||||
|
|
||||||
for (i = 0; i < MAXSPLITSCREENPLAYERS; i++)
|
for (i = 0; i < MAXSPLITSCREENPLAYERS; i++)
|
||||||
{
|
{
|
||||||
if (deviceID == cv_usejoystick[i].value)
|
if (device_id == g_player_devices[i])
|
||||||
{
|
{
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
@ -83,6 +152,172 @@ INT32 G_GetDevicePlayer(INT32 deviceID)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
INT32 G_GetDeviceForPlayer(INT32 player)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (G_GetPlayerForDevice(KEYBOARD_MOUSE_DEVICE) == player)
|
||||||
|
{
|
||||||
|
return KEYBOARD_MOUSE_DEVICE;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < G_GetNumAvailableGamepads() + 1; i++)
|
||||||
|
{
|
||||||
|
INT32 device = G_GetAvailableGamepadDevice(i);
|
||||||
|
if (G_GetPlayerForDevice(device) == player)
|
||||||
|
{
|
||||||
|
return device;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void G_SetDeviceForPlayer(INT32 player, INT32 device)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
I_Assert(player >= 0 && player < MAXSPLITSCREENPLAYERS);
|
||||||
|
I_Assert(device >= -1);
|
||||||
|
|
||||||
|
g_player_devices[player] = device;
|
||||||
|
|
||||||
|
if (device == -1)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (device != KEYBOARD_MOUSE_DEVICE)
|
||||||
|
{
|
||||||
|
I_SetGamepadPlayerIndex(device, player);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < MAXSPLITSCREENPLAYERS; i++)
|
||||||
|
{
|
||||||
|
if (i == player)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (g_player_devices[i] == device)
|
||||||
|
{
|
||||||
|
g_player_devices[i] = -1;
|
||||||
|
if (device > 0)
|
||||||
|
{
|
||||||
|
I_SetGamepadPlayerIndex(device, -1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
INT32* G_GetDeviceGameKeyDownArray(INT32 device)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
I_Assert(device >= 0);
|
||||||
|
|
||||||
|
if (device == KEYBOARD_MOUSE_DEVICE)
|
||||||
|
{
|
||||||
|
return g_gamekeydown_device0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < g_available_gamepad_devices; i++)
|
||||||
|
{
|
||||||
|
if (g_gamepad_device_ids[i] == device)
|
||||||
|
{
|
||||||
|
return g_gamepad_gamekeydown[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean G_IsDeviceResponding(INT32 device)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
I_Assert(device >= 0);
|
||||||
|
|
||||||
|
if (device == KEYBOARD_MOUSE_DEVICE)
|
||||||
|
{
|
||||||
|
return g_device0_responding;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < g_available_gamepad_devices; i++)
|
||||||
|
{
|
||||||
|
INT32 device_id = G_GetAvailableGamepadDevice(i);
|
||||||
|
if (device_id == device)
|
||||||
|
{
|
||||||
|
return g_gamepad_responding[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void G_SetDeviceResponding(INT32 device, boolean responding)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
I_Assert(device >= 0);
|
||||||
|
|
||||||
|
if (device == KEYBOARD_MOUSE_DEVICE)
|
||||||
|
{
|
||||||
|
g_device0_responding = responding;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < g_available_gamepad_devices; i++)
|
||||||
|
{
|
||||||
|
INT32 device_id = G_GetAvailableGamepadDevice(i);
|
||||||
|
if (device_id == device)
|
||||||
|
{
|
||||||
|
g_gamepad_responding[i] = responding;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void G_ResetAllDeviceResponding(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int num_gamepads;
|
||||||
|
|
||||||
|
g_device0_responding = false;
|
||||||
|
|
||||||
|
num_gamepads = G_GetNumAvailableGamepads();
|
||||||
|
|
||||||
|
for (i = 0; i < num_gamepads; i++)
|
||||||
|
{
|
||||||
|
g_gamepad_responding[i] = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static boolean AutomaticControllerReassignmentIsAllowed(INT32 device)
|
||||||
|
{
|
||||||
|
boolean device_is_gamepad = device > 0;
|
||||||
|
boolean device_is_unassigned = G_GetPlayerForDevice(device) == -1;
|
||||||
|
boolean gamestate_is_in_level = gamestate == GS_LEVEL;
|
||||||
|
|
||||||
|
return device_is_gamepad && device_is_unassigned && gamestate_is_in_level;
|
||||||
|
}
|
||||||
|
|
||||||
|
static INT32 AssignDeviceToFirstUnassignedPlayer(INT32 device)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < splitscreen + 1; i++)
|
||||||
|
{
|
||||||
|
if (G_GetDeviceForPlayer(i) == -1)
|
||||||
|
{
|
||||||
|
G_SetDeviceForPlayer(i, device);
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Remaps the inputs to game controls.
|
// Remaps the inputs to game controls.
|
||||||
//
|
//
|
||||||
|
|
@ -94,15 +329,15 @@ void G_MapEventsToControls(event_t *ev)
|
||||||
{
|
{
|
||||||
INT32 i;
|
INT32 i;
|
||||||
|
|
||||||
if (ev->device >= 0 && ev->device < MAXDEVICES)
|
if (ev->device >= 0)
|
||||||
{
|
{
|
||||||
switch (ev->type)
|
switch (ev->type)
|
||||||
{
|
{
|
||||||
case ev_keydown:
|
case ev_keydown:
|
||||||
//case ev_keyup:
|
//case ev_keyup:
|
||||||
//case ev_mouse:
|
//case ev_mouse:
|
||||||
//case ev_joystick:
|
//case ev_gamepad_axis:
|
||||||
deviceResponding[ev->device] = true;
|
G_SetDeviceResponding(ev->device, true);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
@ -119,7 +354,16 @@ void G_MapEventsToControls(event_t *ev)
|
||||||
case ev_keydown:
|
case ev_keydown:
|
||||||
if (ev->data1 < NUMINPUTS)
|
if (ev->data1 < NUMINPUTS)
|
||||||
{
|
{
|
||||||
gamekeydown[ev->device][ev->data1] = JOYAXISRANGE;
|
G_GetDeviceGameKeyDownArray(ev->device)[ev->data1] = JOYAXISRANGE;
|
||||||
|
|
||||||
|
if (AutomaticControllerReassignmentIsAllowed(ev->device))
|
||||||
|
{
|
||||||
|
INT32 assigned = AssignDeviceToFirstUnassignedPlayer(ev->device);
|
||||||
|
if (assigned >= 0)
|
||||||
|
{
|
||||||
|
CONS_Alert(CONS_NOTICE, "Player %d device was reassigned\n", assigned + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#ifdef PARANOIA
|
#ifdef PARANOIA
|
||||||
else
|
else
|
||||||
|
|
@ -132,7 +376,7 @@ void G_MapEventsToControls(event_t *ev)
|
||||||
case ev_keyup:
|
case ev_keyup:
|
||||||
if (ev->data1 < NUMINPUTS)
|
if (ev->data1 < NUMINPUTS)
|
||||||
{
|
{
|
||||||
gamekeydown[ev->device][ev->data1] = 0;
|
G_GetDeviceGameKeyDownArray(ev->device)[ev->data1] = 0;
|
||||||
}
|
}
|
||||||
#ifdef PARANOIA
|
#ifdef PARANOIA
|
||||||
else
|
else
|
||||||
|
|
@ -147,32 +391,32 @@ void G_MapEventsToControls(event_t *ev)
|
||||||
if (ev->data2 < 0)
|
if (ev->data2 < 0)
|
||||||
{
|
{
|
||||||
// Left
|
// Left
|
||||||
gamekeydown[ev->device][KEY_MOUSEMOVE + 2] = abs(ev->data2);
|
G_GetDeviceGameKeyDownArray(ev->device)[KEY_MOUSEMOVE + 2] = abs(ev->data2);
|
||||||
gamekeydown[ev->device][KEY_MOUSEMOVE + 3] = 0;
|
G_GetDeviceGameKeyDownArray(ev->device)[KEY_MOUSEMOVE + 3] = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Right
|
// Right
|
||||||
gamekeydown[ev->device][KEY_MOUSEMOVE + 2] = 0;
|
G_GetDeviceGameKeyDownArray(ev->device)[KEY_MOUSEMOVE + 2] = 0;
|
||||||
gamekeydown[ev->device][KEY_MOUSEMOVE + 3] = abs(ev->data2);
|
G_GetDeviceGameKeyDownArray(ev->device)[KEY_MOUSEMOVE + 3] = abs(ev->data2);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Y axis
|
// Y axis
|
||||||
if (ev->data3 < 0)
|
if (ev->data3 < 0)
|
||||||
{
|
{
|
||||||
// Up
|
// Up
|
||||||
gamekeydown[ev->device][KEY_MOUSEMOVE] = abs(ev->data3);
|
G_GetDeviceGameKeyDownArray(ev->device)[KEY_MOUSEMOVE] = abs(ev->data3);
|
||||||
gamekeydown[ev->device][KEY_MOUSEMOVE + 1] = 0;
|
G_GetDeviceGameKeyDownArray(ev->device)[KEY_MOUSEMOVE + 1] = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Down
|
// Down
|
||||||
gamekeydown[ev->device][KEY_MOUSEMOVE] = 0;
|
G_GetDeviceGameKeyDownArray(ev->device)[KEY_MOUSEMOVE] = 0;
|
||||||
gamekeydown[ev->device][KEY_MOUSEMOVE + 1] = abs(ev->data3);
|
G_GetDeviceGameKeyDownArray(ev->device)[KEY_MOUSEMOVE + 1] = abs(ev->data3);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ev_joystick: // buttons are virtual keys
|
case ev_gamepad_axis: // buttons are virtual keys
|
||||||
if (ev->data1 >= JOYAXISSETS)
|
if (ev->data1 >= JOYAXISSETS)
|
||||||
{
|
{
|
||||||
#ifdef PARANOIA
|
#ifdef PARANOIA
|
||||||
|
|
@ -190,12 +434,12 @@ void G_MapEventsToControls(event_t *ev)
|
||||||
|
|
||||||
if (ev->data2 != INT32_MAX)
|
if (ev->data2 != INT32_MAX)
|
||||||
{
|
{
|
||||||
gamekeydown[ev->device][KEY_AXIS1 + (JOYANALOGS * 4) + (i * 2)] = max(0, ev->data2);
|
G_GetDeviceGameKeyDownArray(ev->device)[KEY_AXIS1 + (JOYANALOGS * 4) + (i * 2)] = max(0, ev->data2);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ev->data3 != INT32_MAX)
|
if (ev->data3 != INT32_MAX)
|
||||||
{
|
{
|
||||||
gamekeydown[ev->device][KEY_AXIS1 + (JOYANALOGS * 4) + (i * 2) + 1] = max(0, ev->data3);
|
G_GetDeviceGameKeyDownArray(ev->device)[KEY_AXIS1 + (JOYANALOGS * 4) + (i * 2) + 1] = max(0, ev->data3);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
@ -206,14 +450,14 @@ void G_MapEventsToControls(event_t *ev)
|
||||||
if (ev->data2 < 0)
|
if (ev->data2 < 0)
|
||||||
{
|
{
|
||||||
// Left
|
// Left
|
||||||
gamekeydown[ev->device][KEY_AXIS1 + (i * 4)] = abs(ev->data2);
|
G_GetDeviceGameKeyDownArray(ev->device)[KEY_AXIS1 + (i * 4)] = abs(ev->data2);
|
||||||
gamekeydown[ev->device][KEY_AXIS1 + (i * 4) + 1] = 0;
|
G_GetDeviceGameKeyDownArray(ev->device)[KEY_AXIS1 + (i * 4) + 1] = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Right
|
// Right
|
||||||
gamekeydown[ev->device][KEY_AXIS1 + (i * 4)] = 0;
|
G_GetDeviceGameKeyDownArray(ev->device)[KEY_AXIS1 + (i * 4)] = 0;
|
||||||
gamekeydown[ev->device][KEY_AXIS1 + (i * 4) + 1] = abs(ev->data2);
|
G_GetDeviceGameKeyDownArray(ev->device)[KEY_AXIS1 + (i * 4) + 1] = abs(ev->data2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -222,14 +466,14 @@ void G_MapEventsToControls(event_t *ev)
|
||||||
if (ev->data3 < 0)
|
if (ev->data3 < 0)
|
||||||
{
|
{
|
||||||
// Up
|
// Up
|
||||||
gamekeydown[ev->device][KEY_AXIS1 + (i * 4) + 2] = abs(ev->data3);
|
G_GetDeviceGameKeyDownArray(ev->device)[KEY_AXIS1 + (i * 4) + 2] = abs(ev->data3);
|
||||||
gamekeydown[ev->device][KEY_AXIS1 + (i * 4) + 3] = 0;
|
G_GetDeviceGameKeyDownArray(ev->device)[KEY_AXIS1 + (i * 4) + 3] = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Down
|
// Down
|
||||||
gamekeydown[ev->device][KEY_AXIS1 + (i * 4) + 2] = 0;
|
G_GetDeviceGameKeyDownArray(ev->device)[KEY_AXIS1 + (i * 4) + 2] = 0;
|
||||||
gamekeydown[ev->device][KEY_AXIS1 + (i * 4) + 3] = abs(ev->data3);
|
G_GetDeviceGameKeyDownArray(ev->device)[KEY_AXIS1 + (i * 4) + 3] = abs(ev->data3);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -107,8 +107,8 @@ extern consvar_t cv_controlperkey;
|
||||||
// current state of the keys: JOYAXISRANGE or 0 when boolean.
|
// current state of the keys: JOYAXISRANGE or 0 when boolean.
|
||||||
// Or anything inbetween for analog values
|
// Or anything inbetween for analog values
|
||||||
#define MAXDEVICES (MAXGAMEPADS + 1) // Gamepads + keyboard & mouse
|
#define MAXDEVICES (MAXGAMEPADS + 1) // Gamepads + keyboard & mouse
|
||||||
|
#define KEYBOARD_MOUSE_DEVICE 0
|
||||||
extern INT32 gamekeydown[MAXDEVICES][NUMINPUTS];
|
extern INT32 gamekeydown[MAXDEVICES][NUMINPUTS];
|
||||||
extern boolean deviceResponding[MAXDEVICES];
|
|
||||||
|
|
||||||
// several key codes (or virtual key) per game control
|
// several key codes (or virtual key) per game control
|
||||||
extern INT32 gamecontrol[MAXSPLITSCREENPLAYERS][num_gamecontrols][MAXINPUTMAPPING];
|
extern INT32 gamecontrol[MAXSPLITSCREENPLAYERS][num_gamecontrols][MAXINPUTMAPPING];
|
||||||
|
|
@ -135,7 +135,31 @@ extern const INT32 gcl_full[num_gcl_full];
|
||||||
// peace to my little coder fingers!
|
// peace to my little coder fingers!
|
||||||
// check a gamecontrol being active or not
|
// check a gamecontrol being active or not
|
||||||
|
|
||||||
INT32 G_GetDevicePlayer(INT32 deviceID);
|
/*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/// Register a device index (from ev_gamepad_device_added) as an Available Gamepad
|
||||||
|
void G_RegisterAvailableGamepad(INT32 device_id);
|
||||||
|
/// Unregister a device index (from ev_gamepad_device_removed) as an Available Gamepad
|
||||||
|
void G_UnregisterAvailableGamepad(INT32 device_id);
|
||||||
|
/// Get the number of Available Gamepads registered.
|
||||||
|
INT32 G_GetNumAvailableGamepads(void);
|
||||||
|
/// Get the device ID for a given Available Gamepad Index, or -1. 0 <= available_index < G_GetNumAvailableGamepads()
|
||||||
|
INT32 G_GetAvailableGamepadDevice(INT32 available_index);
|
||||||
|
|
||||||
|
INT32 G_GetPlayerForDevice(INT32 deviceID);
|
||||||
|
/// Get gamepad device for given player, or -1.
|
||||||
|
INT32 G_GetDeviceForPlayer(INT32 player);
|
||||||
|
|
||||||
|
/// Set the given player index's assigned device. If the device is in use by another player, that player is unassigned.
|
||||||
|
void G_SetDeviceForPlayer(INT32 player, INT32 device);
|
||||||
|
|
||||||
|
/// Get the gamekeydown array (NUMINPUTS values) for the given device, or NULL if the device id is invalid.
|
||||||
|
INT32* G_GetDeviceGameKeyDownArray(INT32 device);
|
||||||
|
|
||||||
|
boolean G_IsDeviceResponding(INT32 device);
|
||||||
|
void G_SetDeviceResponding(INT32 device, boolean responding);
|
||||||
|
void G_ResetAllDeviceResponding(void);
|
||||||
|
|
||||||
// remaps the input event to a game control.
|
// remaps the input event to a game control.
|
||||||
void G_MapEventsToControls(event_t *ev);
|
void G_MapEventsToControls(event_t *ev);
|
||||||
|
|
|
||||||
|
|
@ -58,6 +58,9 @@ struct JoyType_t
|
||||||
|
|
||||||
extern JoyType_t Joystick[MAXSPLITSCREENPLAYERS];
|
extern JoyType_t Joystick[MAXSPLITSCREENPLAYERS];
|
||||||
|
|
||||||
|
void I_SetGamepadPlayerIndex(INT32 device_id, INT32 index);
|
||||||
|
void I_SetGamepadIndicatorColor(INT32 device_id, UINT8 red, UINT8 green, UINT8 blue);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} // extern "C"
|
} // extern "C"
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -205,9 +205,8 @@ void I_JoyScale4(void);
|
||||||
|
|
||||||
// Called by D_SRB2Main.
|
// Called by D_SRB2Main.
|
||||||
|
|
||||||
/** \brief to startup a joystick
|
/// Startup input subsystems.
|
||||||
*/
|
void I_StartupInput(void);
|
||||||
void I_InitJoystick(UINT8 index);
|
|
||||||
|
|
||||||
/** \brief to startup the first joystick
|
/** \brief to startup the first joystick
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -60,13 +60,6 @@
|
||||||
// And just some randomness for the exits.
|
// And just some randomness for the exits.
|
||||||
#include "m_random.h"
|
#include "m_random.h"
|
||||||
|
|
||||||
#if defined(HAVE_SDL)
|
|
||||||
#include "SDL.h"
|
|
||||||
#if SDL_VERSION_ATLEAST(2,0,0)
|
|
||||||
#include "sdl/sdlmain.h" // JOYSTICK_HOTPLUG
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef PC_DOS
|
#ifdef PC_DOS
|
||||||
#include <stdio.h> // for snprintf
|
#include <stdio.h> // for snprintf
|
||||||
int snprintf(char *str, size_t n, const char *fmt, ...);
|
int snprintf(char *str, size_t n, const char *fmt, ...);
|
||||||
|
|
@ -3385,11 +3378,18 @@ void M_DrawProfileControls(void)
|
||||||
// Get userbound controls...
|
// Get userbound controls...
|
||||||
for (k = 0; k < MAXINPUTMAPPING; k++)
|
for (k = 0; k < MAXINPUTMAPPING; k++)
|
||||||
{
|
{
|
||||||
|
int device;
|
||||||
keys[k] = optionsmenu.tempcontrols[gc][k];
|
keys[k] = optionsmenu.tempcontrols[gc][k];
|
||||||
if (keys[k] == KEY_NULL)
|
if (keys[k] == KEY_NULL)
|
||||||
continue;
|
continue;
|
||||||
set++;
|
set++;
|
||||||
if (!G_KeyIsAvailable(keys[k], cv_usejoystick[0].value))
|
|
||||||
|
device = G_GetDeviceForPlayer(0);
|
||||||
|
if (device == -1)
|
||||||
|
{
|
||||||
|
device = 0;
|
||||||
|
}
|
||||||
|
if (!G_KeyIsAvailable(keys[k], device))
|
||||||
continue;
|
continue;
|
||||||
available++;
|
available++;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -222,6 +222,22 @@ boolean M_Responder(event_t *ev)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (gamestate == GS_MENU && ev->type == ev_gamepad_device_removed && G_GetPlayerForDevice(ev->device) != -1)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
INT32 player = G_GetPlayerForDevice(ev->device);
|
||||||
|
|
||||||
|
// Unassign all controllers
|
||||||
|
for (i = 0; i < MAXSPLITSCREENPLAYERS; i++)
|
||||||
|
{
|
||||||
|
G_SetDeviceForPlayer(i, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return to the title because a controller was removed at the menu.
|
||||||
|
CONS_Alert(CONS_NOTICE, "Player %d's assigned gamepad was removed. Returning to the title screen.", player);
|
||||||
|
D_StartTitle();
|
||||||
|
}
|
||||||
|
|
||||||
if (ev->type == ev_keydown && ev->data1 < NUMKEYS)
|
if (ev->type == ev_keydown && ev->data1 < NUMKEYS)
|
||||||
{
|
{
|
||||||
// Record keyboard presses
|
// Record keyboard presses
|
||||||
|
|
|
||||||
|
|
@ -123,7 +123,7 @@ static void SetDeviceOnPress(void)
|
||||||
{
|
{
|
||||||
if (deviceResponding[i])
|
if (deviceResponding[i])
|
||||||
{
|
{
|
||||||
CV_SetValue(&cv_usejoystick[0], i); // Force-set this joystick as the current joystick we're using for P1 (which is the only one controlling menus)
|
G_SetDeviceForPlayer(0, i); // Force-set this joystick as the current joystick we're using for P1 (which is the only one controlling menus)
|
||||||
CONS_Printf("SetDeviceOnPress: Device for %d set to %d\n", 0, i);
|
CONS_Printf("SetDeviceOnPress: Device for %d set to %d\n", 0, i);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -307,7 +307,7 @@ void M_MapProfileControl(event_t *ev)
|
||||||
UINT8 where = n; // By default, we'll save the bind where we're supposed to map.
|
UINT8 where = n; // By default, we'll save the bind where we're supposed to map.
|
||||||
INT32 i;
|
INT32 i;
|
||||||
|
|
||||||
//SetDeviceOnPress(); // Update cv_usejoystick
|
//SetDeviceOnPress(); // Update player gamepad assignments
|
||||||
|
|
||||||
// Only consider keydown and joystick events to make sure we ignore ev_mouse and other events
|
// Only consider keydown and joystick events to make sure we ignore ev_mouse and other events
|
||||||
// See also G_MapEventsToControls
|
// See also G_MapEventsToControls
|
||||||
|
|
@ -325,11 +325,11 @@ void M_MapProfileControl(event_t *ev)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
case ev_joystick:
|
case ev_gamepad_axis:
|
||||||
if (ev->data1 >= JOYAXES)
|
if (ev->data1 >= JOYAXES)
|
||||||
{
|
{
|
||||||
#ifdef PARANOIA
|
#ifdef PARANOIA
|
||||||
CONS_Debug(DBG_GAMELOGIC, "Bad joystick axis event %d\n", ev->data1);
|
CONS_Debug(DBG_GAMELOGIC, "Bad gamepad axis event %d\n", ev->data1);
|
||||||
#endif
|
#endif
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -380,10 +380,10 @@ void M_CharacterSelectInit(void)
|
||||||
{
|
{
|
||||||
for (i = 0; i < MAXSPLITSCREENPLAYERS; i++)
|
for (i = 0; i < MAXSPLITSCREENPLAYERS; i++)
|
||||||
{
|
{
|
||||||
// Un-set devices for other players.
|
// Un-set devices for all players if not editing profile
|
||||||
if (i != 0 || optionsmenu.profile)
|
if (!optionsmenu.profile)
|
||||||
{
|
{
|
||||||
CV_SetValue(&cv_usejoystick[i], -1);
|
G_SetDeviceForPlayer(i, -1);
|
||||||
CONS_Printf("M_CharacterSelectInit: Device for %d set to %d\n", i, -1);
|
CONS_Printf("M_CharacterSelectInit: Device for %d set to %d\n", i, -1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -526,7 +526,12 @@ static boolean M_DeviceAvailable(INT32 deviceID, UINT8 numPlayers)
|
||||||
|
|
||||||
for (i = 0; i < numPlayers; i++)
|
for (i = 0; i < numPlayers; i++)
|
||||||
{
|
{
|
||||||
if (cv_usejoystick[i].value == deviceID)
|
int player_device = G_GetDeviceForPlayer(i);
|
||||||
|
if (player_device == -1)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (player_device == deviceID)
|
||||||
{
|
{
|
||||||
// This one's already being used.
|
// This one's already being used.
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -540,6 +545,7 @@ static boolean M_DeviceAvailable(INT32 deviceID, UINT8 numPlayers)
|
||||||
static boolean M_HandlePressStart(setup_player_t *p, UINT8 num)
|
static boolean M_HandlePressStart(setup_player_t *p, UINT8 num)
|
||||||
{
|
{
|
||||||
INT32 i, j;
|
INT32 i, j;
|
||||||
|
INT32 num_gamepads_available;
|
||||||
|
|
||||||
if (optionsmenu.profile)
|
if (optionsmenu.profile)
|
||||||
return false; // Don't allow for the possibility of SOMEHOW another player joining in.
|
return false; // Don't allow for the possibility of SOMEHOW another player joining in.
|
||||||
|
|
@ -568,24 +574,32 @@ static boolean M_HandlePressStart(setup_player_t *p, UINT8 num)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now detect new devices trying to join.
|
// Now detect new devices trying to join.
|
||||||
for (i = 0; i < MAXDEVICES; i++)
|
num_gamepads_available = G_GetNumAvailableGamepads();
|
||||||
|
for (i = 0; i < num_gamepads_available + 1; i++)
|
||||||
{
|
{
|
||||||
if (deviceResponding[i] != true)
|
INT32 device = 0;
|
||||||
|
|
||||||
|
if (i > 0)
|
||||||
|
{
|
||||||
|
device = G_GetAvailableGamepadDevice(i - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (G_IsDeviceResponding(device) != true)
|
||||||
{
|
{
|
||||||
// No buttons are being pushed.
|
// No buttons are being pushed.
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (M_DeviceAvailable(i, setup_numplayers) == true)
|
if (M_DeviceAvailable(device, setup_numplayers) == true)
|
||||||
{
|
{
|
||||||
// Available!! Let's use this one!!
|
// Available!! Let's use this one!!
|
||||||
|
|
||||||
// if P1 is setting up using keyboard (device 0), save their last used device.
|
// if P1 is setting up using keyboard (device 0), save their last used device.
|
||||||
// this is to allow them to retain controller usage when they play alone.
|
// this is to allow them to retain controller usage when they play alone.
|
||||||
// Because let's face it, when you test mods, you're often lazy to grab your controller for menuing :)
|
// Because let's face it, when you test mods, you're often lazy to grab your controller for menuing :)
|
||||||
if (!i && !num)
|
if (i == 0 && num == 0)
|
||||||
{
|
{
|
||||||
setup_player[num].ponedevice = cv_usejoystick[num].value;
|
setup_player[num].ponedevice = G_GetDeviceForPlayer(num);
|
||||||
}
|
}
|
||||||
else if (num)
|
else if (num)
|
||||||
{
|
{
|
||||||
|
|
@ -593,14 +607,13 @@ static boolean M_HandlePressStart(setup_player_t *p, UINT8 num)
|
||||||
memcpy(&gamecontrol[num], gamecontroldefault, sizeof(gamecontroldefault));
|
memcpy(&gamecontrol[num], gamecontroldefault, sizeof(gamecontroldefault));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
G_SetDeviceForPlayer(num, device);
|
||||||
|
CONS_Printf("M_HandlePressStart: Device for %d set to %d\n", num, device);
|
||||||
|
|
||||||
CV_SetValue(&cv_usejoystick[num], i);
|
for (j = num + 1; j < MAXSPLITSCREENPLAYERS; j++)
|
||||||
CONS_Printf("M_HandlePressStart: Device for %d set to %d\n", num, i);
|
|
||||||
|
|
||||||
for (j = num+1; j < MAXSPLITSCREENPLAYERS; j++)
|
|
||||||
{
|
{
|
||||||
// Un-set devices for other players.
|
// Un-set devices for other players.
|
||||||
CV_SetValue(&cv_usejoystick[j], -1);
|
G_SetDeviceForPlayer(j, -1);
|
||||||
CONS_Printf("M_HandlePressStart: Device for %d set to %d\n", j, -1);
|
CONS_Printf("M_HandlePressStart: Device for %d set to %d\n", j, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -616,7 +629,7 @@ static boolean M_HandlePressStart(setup_player_t *p, UINT8 num)
|
||||||
menucmd[j].buttonsHeld |= MBT_X;
|
menucmd[j].buttonsHeld |= MBT_X;
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(deviceResponding, false, sizeof(deviceResponding));
|
G_ResetAllDeviceResponding();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -668,11 +681,8 @@ static boolean M_HandleCSelectProfile(setup_player_t *p, UINT8 num)
|
||||||
menucmd[i].buttonsHeld |= MBT_X;
|
menucmd[i].buttonsHeld |= MBT_X;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (num > 0)
|
G_SetDeviceForPlayer(num, -1);
|
||||||
{
|
|
||||||
CV_StealthSetValue(&cv_usejoystick[num], -1);
|
|
||||||
CONS_Printf("M_HandleCSelectProfile: Device for %d set to %d\n", num, -1);
|
CONS_Printf("M_HandleCSelectProfile: Device for %d set to %d\n", num, -1);
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -1482,12 +1492,6 @@ void M_CharacterSelectTick(void)
|
||||||
|
|
||||||
CV_StealthSetValue(&cv_splitplayers, setup_numplayers);
|
CV_StealthSetValue(&cv_splitplayers, setup_numplayers);
|
||||||
|
|
||||||
// P1 is alone, set their old device just in case.
|
|
||||||
if (setup_numplayers < 2 && setup_player[0].ponedevice)
|
|
||||||
{
|
|
||||||
CV_StealthSetValue(&cv_usejoystick[0], setup_player[0].ponedevice);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined (TESTERS)
|
#if defined (TESTERS)
|
||||||
M_MPOptSelectInit(0);
|
M_MPOptSelectInit(0);
|
||||||
#else
|
#else
|
||||||
|
|
|
||||||
|
|
@ -194,48 +194,6 @@ static char returnWadPath[256];
|
||||||
#include "../byteptr.h"
|
#include "../byteptr.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void I_StoreExJoystick(SDL_GameController *dev)
|
|
||||||
{
|
|
||||||
// ExJoystick is a massive hack to avoid needing to completely
|
|
||||||
// rewrite pretty much all of the controller support from scratch...
|
|
||||||
|
|
||||||
// Used in favor of most instances of SDL_GameControllerClose.
|
|
||||||
// If a joystick would've been discarded, then save it in an array,
|
|
||||||
// because we want it have it for the joystick input screen.
|
|
||||||
|
|
||||||
int index = 0;
|
|
||||||
|
|
||||||
if (dev == NULL)
|
|
||||||
{
|
|
||||||
// No joystick?
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
index = SDL_JoystickInstanceID(SDL_GameControllerGetJoystick(dev));
|
|
||||||
|
|
||||||
if (index >= MAXGAMEPADS || index < 0)
|
|
||||||
{
|
|
||||||
// Not enough space to save this joystick, completely discard.
|
|
||||||
SDL_GameControllerClose(dev);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ExJoystick[index] == dev)
|
|
||||||
{
|
|
||||||
// No need to do anything else.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ExJoystick[index] != NULL)
|
|
||||||
{
|
|
||||||
// Discard joystick in the old slot.
|
|
||||||
SDL_GameControllerClose(ExJoystick[index]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Keep for safe-keeping.
|
|
||||||
ExJoystick[index] = dev;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** \brief The JoyReset function
|
/** \brief The JoyReset function
|
||||||
|
|
||||||
\param JoySet Joystick info to reset
|
\param JoySet Joystick info to reset
|
||||||
|
|
@ -244,10 +202,6 @@ void I_StoreExJoystick(SDL_GameController *dev)
|
||||||
*/
|
*/
|
||||||
static void JoyReset(SDLJoyInfo_t *JoySet)
|
static void JoyReset(SDLJoyInfo_t *JoySet)
|
||||||
{
|
{
|
||||||
if (JoySet->dev)
|
|
||||||
{
|
|
||||||
I_StoreExJoystick(JoySet->dev);
|
|
||||||
}
|
|
||||||
JoySet->dev = NULL;
|
JoySet->dev = NULL;
|
||||||
JoySet->oldjoy = -1;
|
JoySet->oldjoy = -1;
|
||||||
JoySet->axises = JoySet->buttons = JoySet->hats = JoySet->balls = 0;
|
JoySet->axises = JoySet->buttons = JoySet->hats = JoySet->balls = 0;
|
||||||
|
|
@ -261,7 +215,6 @@ static INT32 joystick_started[MAXSPLITSCREENPLAYERS] = {0,0,0,0};
|
||||||
/** \brief SDL info about joystick 1
|
/** \brief SDL info about joystick 1
|
||||||
*/
|
*/
|
||||||
SDLJoyInfo_t JoyInfo[MAXSPLITSCREENPLAYERS];
|
SDLJoyInfo_t JoyInfo[MAXSPLITSCREENPLAYERS];
|
||||||
SDL_GameController *ExJoystick[MAXGAMEPADS];
|
|
||||||
|
|
||||||
SDL_bool consolevent = SDL_FALSE;
|
SDL_bool consolevent = SDL_FALSE;
|
||||||
SDL_bool framebuffer = SDL_FALSE;
|
SDL_bool framebuffer = SDL_FALSE;
|
||||||
|
|
@ -983,316 +936,78 @@ void I_JoyScale4(void)
|
||||||
JoyInfo[3].scale = Joystick[3].bGamepadStyle?1:cv_joyscale[1].value;
|
JoyInfo[3].scale = Joystick[3].bGamepadStyle?1:cv_joyscale[1].value;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cheat to get the device index for a game controller handle
|
void I_SetGamepadPlayerIndex(INT32 device_id, INT32 player)
|
||||||
INT32 I_GetJoystickDeviceIndex(SDL_GameController *dev)
|
|
||||||
{
|
{
|
||||||
SDL_Joystick *joystick = NULL;
|
#if !(SDL_VERSION_ATLEAST(2,0,12))
|
||||||
|
(void)device_id;
|
||||||
|
(void)player;
|
||||||
|
#else
|
||||||
|
I_Assert(device_id > 0); // Gamepad devices are always ID 1 or higher
|
||||||
|
I_Assert(player >= 0 && player < MAXSPLITSCREENPLAYERS);
|
||||||
|
|
||||||
joystick = SDL_GameControllerGetJoystick(dev);
|
SDL_GameController *controller = SDL_GameControllerFromInstanceID(device_id - 1);
|
||||||
|
if (controller == NULL)
|
||||||
if (joystick)
|
|
||||||
{
|
{
|
||||||
return SDL_JoystickInstanceID(joystick);
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
SDL_GameControllerSetPlayerIndex(controller, player);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void I_UpdateJoystickDeviceIndex(UINT8 player)
|
void I_SetGamepadIndicatorColor(INT32 device_id, UINT8 red, UINT8 green, UINT8 blue)
|
||||||
{
|
{
|
||||||
///////////////////////////////////////////////
|
#if !(SDL_VERSION_ATLEAST(2,0,14))
|
||||||
// update this joystick's device index (wow) //
|
(void)device_id;
|
||||||
///////////////////////////////////////////////
|
(void)player;
|
||||||
|
#else
|
||||||
|
I_Assert(device_id > 0); // Gamepad devices are always ID 1 or higher
|
||||||
|
|
||||||
if (JoyInfo[player].dev)
|
SDL_GameController *controller = SDL_GameControllerFromInstanceID(device_id - 1);
|
||||||
|
if (controller == NULL)
|
||||||
{
|
{
|
||||||
cv_usejoystick[player].value = I_GetJoystickDeviceIndex(JoyInfo[player].dev) + 1;
|
return;
|
||||||
CONS_Printf("I_UpdateJoystickDeviceIndex: Device for %d set to %d\n", player, cv_usejoystick[player].value);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
UINT8 joystickID, compareJoystick;
|
|
||||||
|
|
||||||
for (joystickID = 0; joystickID < MAXSPLITSCREENPLAYERS; joystickID++)
|
|
||||||
{
|
|
||||||
// is this cv_usejoystick used?
|
|
||||||
const INT32 value = atoi(cv_usejoystick[joystickID].string);
|
|
||||||
|
|
||||||
for (compareJoystick = 0; compareJoystick < MAXSPLITSCREENPLAYERS; compareJoystick++)
|
|
||||||
{
|
|
||||||
if (compareJoystick == player)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (value == JoyInfo[compareJoystick].oldjoy || value == cv_usejoystick[compareJoystick].value)
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (compareJoystick == MAXSPLITSCREENPLAYERS)
|
SDL_GameControllerSetLED(controller, red, green, blue);
|
||||||
{
|
#endif
|
||||||
// We DID make it through the whole loop, so we can use this one!
|
|
||||||
cv_usejoystick[player].value = value;
|
|
||||||
CONS_Printf("I_UpdateJoystickDeviceIndex: Device for %d set to %d\n", player, cv_usejoystick[player].value);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (joystickID == MAXSPLITSCREENPLAYERS)
|
|
||||||
{
|
|
||||||
// We DID NOT make it through the whole loop, so we can't assign this joystick to anything.
|
|
||||||
// When you try your best, but you don't succeed...
|
|
||||||
cv_usejoystick[player].value = 0;
|
|
||||||
CONS_Printf("I_UpdateJoystickDeviceIndex: Device for %d set to %d\n", player, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Misleading function: updates device indices for all players BUT the one specified.
|
|
||||||
// Necessary for SDL_JOYDEVICEADDED events
|
|
||||||
void I_UpdateJoystickDeviceIndices(UINT8 excludePlayer)
|
|
||||||
{
|
|
||||||
UINT8 player;
|
|
||||||
|
|
||||||
for (player = 0; player < MAXSPLITSCREENPLAYERS; player++)
|
|
||||||
{
|
|
||||||
if (player == excludePlayer)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
I_UpdateJoystickDeviceIndex(player);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** \brief Shuts down joystick
|
|
||||||
\return void
|
|
||||||
*/
|
|
||||||
void I_ShutdownJoystick(UINT8 index)
|
|
||||||
{
|
|
||||||
INT32 i;
|
|
||||||
event_t event;
|
|
||||||
|
|
||||||
event.device = I_GetJoystickDeviceIndex(JoyInfo[index].dev);
|
|
||||||
event.type = ev_keyup;
|
|
||||||
event.data2 = 0;
|
|
||||||
event.data3 = 0;
|
|
||||||
|
|
||||||
// emulate the up of all joystick buttons
|
|
||||||
for (i = 0; i < JOYBUTTONS; i++)
|
|
||||||
{
|
|
||||||
event.data1 = KEY_JOY1+i;
|
|
||||||
D_PostEvent(&event);
|
|
||||||
}
|
|
||||||
|
|
||||||
// reset joystick position
|
|
||||||
event.type = ev_joystick;
|
|
||||||
for (i = 0; i < JOYAXES; i++)
|
|
||||||
{
|
|
||||||
event.data1 = i;
|
|
||||||
D_PostEvent(&event);
|
|
||||||
}
|
|
||||||
|
|
||||||
joystick_started[index] = 0;
|
|
||||||
JoyReset(&JoyInfo[index]);
|
|
||||||
|
|
||||||
// don't shut down the subsystem here, because hotplugging
|
|
||||||
}
|
|
||||||
|
|
||||||
/** \brief Open joystick handle
|
|
||||||
|
|
||||||
\param fname name of joystick
|
|
||||||
|
|
||||||
\return axises
|
|
||||||
|
|
||||||
|
|
||||||
*/
|
|
||||||
static int joy_open(int playerIndex, int joyIndex)
|
|
||||||
{
|
|
||||||
SDL_GameController *newdev = NULL;
|
|
||||||
int num_joy = 0;
|
|
||||||
|
|
||||||
if (SDL_WasInit(SDL_INIT_JOYSTICK) == 0)
|
|
||||||
{
|
|
||||||
CONS_Printf(M_GetText("Joystick subsystem not started\n"));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (SDL_WasInit(SDL_INIT_GAMECONTROLLER) == 0)
|
|
||||||
{
|
|
||||||
CONS_Printf(M_GetText("Game Controller subsystem not started\n"));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (joyIndex <= 0)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
num_joy = SDL_NumJoysticks();
|
|
||||||
|
|
||||||
if (num_joy == 0)
|
|
||||||
{
|
|
||||||
CONS_Printf("%s", M_GetText("Found no joysticks on this system\n"));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
newdev = SDL_GameControllerOpen(joyIndex-1);
|
|
||||||
|
|
||||||
// Handle the edge case where the device <-> joystick index assignment can change due to hotplugging
|
|
||||||
// This indexing is SDL's responsibility and there's not much we can do about it.
|
|
||||||
//
|
|
||||||
// Example:
|
|
||||||
// 1. Plug Controller A -> Index 0 opened
|
|
||||||
// 2. Plug Controller B -> Index 1 opened
|
|
||||||
// 3. Unplug Controller A -> Index 0 closed, Index 1 active
|
|
||||||
// 4. Unplug Controller B -> Index 0 inactive, Index 1 closed
|
|
||||||
// 5. Plug Controller B -> Index 0 opened
|
|
||||||
// 6. Plug Controller A -> Index 0 REPLACED, opened as Controller A; Index 1 is now Controller B
|
|
||||||
if (JoyInfo[playerIndex].dev)
|
|
||||||
{
|
|
||||||
if (JoyInfo[playerIndex].dev == newdev // same device, nothing to do
|
|
||||||
|| (newdev == NULL && SDL_GameControllerGetAttached(JoyInfo[playerIndex].dev))) // we failed, but already have a working device
|
|
||||||
{
|
|
||||||
return SDL_CONTROLLER_AXIS_MAX;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Else, we're changing devices, so send neutral joy events
|
|
||||||
CONS_Debug(DBG_GAMELOGIC, "Joystick%d device is changing; resetting events...\n", playerIndex+1);
|
|
||||||
I_ShutdownJoystick(playerIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
JoyInfo[playerIndex].dev = newdev;
|
|
||||||
|
|
||||||
if (JoyInfo[playerIndex].dev == NULL)
|
|
||||||
{
|
|
||||||
CONS_Debug(DBG_GAMELOGIC, M_GetText("Joystick%d: Couldn't open device - %s\n"), playerIndex+1, SDL_GetError());
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
CONS_Debug(DBG_GAMELOGIC, M_GetText("Joystick%d: %s\n"), playerIndex+1, SDL_GameControllerName(JoyInfo[playerIndex].dev));
|
|
||||||
|
|
||||||
JoyInfo[playerIndex].axises = SDL_CONTROLLER_AXIS_MAX;
|
|
||||||
JoyInfo[playerIndex].buttons = SDL_CONTROLLER_BUTTON_MAX;
|
|
||||||
JoyInfo[playerIndex].hats = 1;
|
|
||||||
JoyInfo[playerIndex].balls = 0;
|
|
||||||
|
|
||||||
//JoyInfo[playerIndex].bGamepadStyle = !stricmp(SDL_JoystickName(JoyInfo[playerIndex].dev), "pad");
|
|
||||||
|
|
||||||
return JoyInfo[playerIndex].axises;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// I_InitJoystick
|
// I_StartupInput
|
||||||
//
|
//
|
||||||
void I_InitJoystick(UINT8 index)
|
void I_StartupInput(void)
|
||||||
{
|
{
|
||||||
SDL_GameController *newcontroller = NULL;
|
|
||||||
UINT8 i;
|
|
||||||
|
|
||||||
//I_ShutdownJoystick();
|
|
||||||
//SDL_SetHintWithPriority("SDL_XINPUT_ENABLED", "0", SDL_HINT_OVERRIDE);
|
|
||||||
if (M_CheckParm("-nojoy"))
|
if (M_CheckParm("-nojoy"))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (SDL_WasInit(SDL_INIT_GAMECONTROLLER))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (M_CheckParm("-noxinput"))
|
if (M_CheckParm("-noxinput"))
|
||||||
SDL_SetHintWithPriority("SDL_XINPUT_ENABLED", "0", SDL_HINT_OVERRIDE);
|
SDL_SetHintWithPriority("SDL_XINPUT_ENABLED", "0", SDL_HINT_OVERRIDE);
|
||||||
|
|
||||||
if (M_CheckParm("-nohidapi"))
|
if (M_CheckParm("-nohidapi"))
|
||||||
SDL_SetHintWithPriority("SDL_JOYSTICK_HIDAPI", "0", SDL_HINT_OVERRIDE);
|
SDL_SetHintWithPriority("SDL_JOYSTICK_HIDAPI", "0", SDL_HINT_OVERRIDE);
|
||||||
|
|
||||||
if (SDL_WasInit(SDL_INIT_JOYSTICK) == 0)
|
CONS_Printf("I_StartupInput()...\n");
|
||||||
{
|
|
||||||
CONS_Printf("I_InitJoystick()...\n");
|
|
||||||
|
|
||||||
if (SDL_InitSubSystem(SDL_INIT_JOYSTICK) == -1)
|
|
||||||
{
|
|
||||||
CONS_Printf(M_GetText("Couldn't initialize joystick: %s\n"), SDL_GetError());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (SDL_WasInit(SDL_INIT_GAMECONTROLLER) == 0)
|
|
||||||
{
|
|
||||||
if (SDL_InitSubSystem(SDL_INIT_GAMECONTROLLER) == -1)
|
if (SDL_InitSubSystem(SDL_INIT_GAMECONTROLLER) == -1)
|
||||||
{
|
{
|
||||||
CONS_Printf(M_GetText("Couldn't initialize gamepads: %s\n"), SDL_GetError());
|
CONS_Printf(M_GetText("Couldn't initialize game controllers: %s\n"), SDL_GetError());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (cv_usejoystick[index].value)
|
// Upon initialization, the gamecontroller subsystem will automatically dispatch controller device added events
|
||||||
newcontroller = SDL_GameControllerOpen(cv_usejoystick[index].value-1);
|
// for controllers connected before initialization.
|
||||||
|
|
||||||
for (i = 0; i < MAXSPLITSCREENPLAYERS; i++)
|
|
||||||
{
|
|
||||||
if (i == index)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (JoyInfo[i].dev == newcontroller)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (newcontroller && i < MAXSPLITSCREENPLAYERS) // don't override an active device
|
|
||||||
{
|
|
||||||
cv_usejoystick[index].value = I_GetJoystickDeviceIndex(JoyInfo[index].dev) + 1;
|
|
||||||
CONS_Printf("I_InitJoystick: Device for %d set to %d\n", index, cv_usejoystick[index].value);
|
|
||||||
}
|
|
||||||
else if (newcontroller && joy_open(index, cv_usejoystick[index].value) != -1)
|
|
||||||
{
|
|
||||||
// SDL's device indexes are unstable, so cv_usejoystick may not match
|
|
||||||
// the actual device index. So let's cheat a bit and find the device's current index.
|
|
||||||
JoyInfo[index].oldjoy = I_GetJoystickDeviceIndex(JoyInfo[index].dev) + 1;
|
|
||||||
joystick_started[index] = 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (JoyInfo[index].oldjoy)
|
|
||||||
I_ShutdownJoystick(index);
|
|
||||||
cv_usejoystick[index].value = 0;
|
|
||||||
CONS_Printf("I_InitJoystick: Device for %d set to %d\n", index, cv_usejoystick[index].value);
|
|
||||||
joystick_started[index] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < MAXSPLITSCREENPLAYERS; i++)
|
|
||||||
{
|
|
||||||
if (JoyInfo[i].dev == newcontroller)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (i == MAXSPLITSCREENPLAYERS)
|
|
||||||
{
|
|
||||||
// Joystick didn't end up being used
|
|
||||||
I_StoreExJoystick(newcontroller);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void I_InitJoystick1(void)
|
|
||||||
{
|
|
||||||
I_InitJoystick(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void I_InitJoystick2(void)
|
|
||||||
{
|
|
||||||
I_InitJoystick(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void I_InitJoystick3(void)
|
|
||||||
{
|
|
||||||
I_InitJoystick(2);
|
|
||||||
}
|
|
||||||
|
|
||||||
void I_InitJoystick4(void)
|
|
||||||
{
|
|
||||||
I_InitJoystick(3);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void I_ShutdownInput(void)
|
static void I_ShutdownInput(void)
|
||||||
{
|
{
|
||||||
UINT8 i;
|
// The game code is now responsible for resetting its internal state based on ev_gamepad_device_removed events.
|
||||||
|
// In practice, Input should never be shutdown and restarted during runtime.
|
||||||
// Yes, the name is misleading: these send neutral events to
|
|
||||||
// clean up the unplugged joystick's input
|
|
||||||
// Note these methods are internal to this file, not called elsewhere.
|
|
||||||
|
|
||||||
for (i = 0; i < MAXSPLITSCREENPLAYERS; i++)
|
|
||||||
I_ShutdownJoystick(i);
|
|
||||||
|
|
||||||
if (SDL_WasInit(SDL_INIT_GAMECONTROLLER) == SDL_INIT_GAMECONTROLLER)
|
if (SDL_WasInit(SDL_INIT_GAMECONTROLLER) == SDL_INIT_GAMECONTROLLER)
|
||||||
{
|
{
|
||||||
|
|
@ -1322,14 +1037,28 @@ static char joyname[255]; // joystick name is straight from the driver
|
||||||
const char *I_GetJoyName(INT32 joyindex)
|
const char *I_GetJoyName(INT32 joyindex)
|
||||||
{
|
{
|
||||||
const char *tempname = NULL;
|
const char *tempname = NULL;
|
||||||
|
SDL_Joystick* joystick;
|
||||||
joyname[0] = 0;
|
joyname[0] = 0;
|
||||||
joyindex--; //SDL's Joystick System starts at 0, not 1
|
joyindex--; //SDL's Joystick System starts at 0, not 1
|
||||||
if (SDL_WasInit(SDL_INIT_JOYSTICK) == SDL_INIT_JOYSTICK)
|
|
||||||
|
if (!SDL_WasInit(SDL_INIT_JOYSTICK) == SDL_INIT_JOYSTICK)
|
||||||
{
|
{
|
||||||
|
return joyname;
|
||||||
|
}
|
||||||
|
|
||||||
|
// joyindex corresponds to the open joystick *instance* ID, not the joystick number
|
||||||
|
joystick = SDL_JoystickFromInstanceID(joyindex);
|
||||||
|
if (joystick == NULL)
|
||||||
|
{
|
||||||
|
return joyname;
|
||||||
|
}
|
||||||
|
|
||||||
tempname = SDL_JoystickNameForIndex(joyindex);
|
tempname = SDL_JoystickNameForIndex(joyindex);
|
||||||
if (tempname)
|
if (tempname)
|
||||||
|
{
|
||||||
strncpy(joyname, tempname, 255);
|
strncpy(joyname, tempname, 255);
|
||||||
}
|
}
|
||||||
|
|
||||||
return joyname;
|
return joyname;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -542,7 +542,7 @@ static void Impl_HandleWindowEvent(SDL_WindowEvent evt)
|
||||||
SDLforceUngrabMouse();
|
SDLforceUngrabMouse();
|
||||||
}
|
}
|
||||||
memset(gamekeydown, 0, sizeof(gamekeydown)); // TODO this is a scary memset
|
memset(gamekeydown, 0, sizeof(gamekeydown)); // TODO this is a scary memset
|
||||||
memset(deviceResponding, false, sizeof (deviceResponding));
|
G_ResetAllDeviceResponding();
|
||||||
|
|
||||||
if (MOUSE_MENU)
|
if (MOUSE_MENU)
|
||||||
{
|
{
|
||||||
|
|
@ -701,7 +701,7 @@ static void Impl_HandleControllerAxisEvent(SDL_ControllerAxisEvent evt)
|
||||||
event_t event;
|
event_t event;
|
||||||
INT32 value;
|
INT32 value;
|
||||||
|
|
||||||
event.type = ev_joystick;
|
event.type = ev_gamepad_axis;
|
||||||
|
|
||||||
event.device = 1 + evt.which;
|
event.device = 1 + evt.which;
|
||||||
if (event.device == INT32_MAX)
|
if (event.device == INT32_MAX)
|
||||||
|
|
@ -777,6 +777,40 @@ static void Impl_HandleControllerButtonEvent(SDL_ControllerButtonEvent evt, Uint
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void Impl_HandleControllerDeviceAddedEvent(SDL_ControllerDeviceEvent event)
|
||||||
|
{
|
||||||
|
// The game is always interested in controller events, even if they aren't internally assigned to a player.
|
||||||
|
// Thus, we *always* open SDL controllers as they become available, to begin receiving their events.
|
||||||
|
|
||||||
|
SDL_GameController* controller = SDL_GameControllerOpen(event.which);
|
||||||
|
if (controller == NULL)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_Joystick* joystick = SDL_GameControllerGetJoystick(controller);
|
||||||
|
SDL_JoystickID joystick_instance_id = SDL_JoystickInstanceID(joystick);
|
||||||
|
|
||||||
|
event_t engine_event {};
|
||||||
|
|
||||||
|
engine_event.type = ev_gamepad_device_added;
|
||||||
|
engine_event.device = 1 + joystick_instance_id;
|
||||||
|
|
||||||
|
D_PostEvent(&engine_event);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Impl_HandleControllerDeviceRemovedEvent(SDL_ControllerDeviceEvent event)
|
||||||
|
{
|
||||||
|
// SDL only posts Device Removed events for controllers that have actually been opened.
|
||||||
|
// Thus, we don't need to filter out controllers that may not have opened successfully prior to this event.
|
||||||
|
event_t engine_event {};
|
||||||
|
|
||||||
|
engine_event.type = ev_gamepad_device_removed;
|
||||||
|
engine_event.device = 1 + event.which;
|
||||||
|
|
||||||
|
D_PostEvent(&engine_event);
|
||||||
|
}
|
||||||
|
|
||||||
static ImGuiKey ImGui_ImplSDL2_KeycodeToImGuiKey(int keycode)
|
static ImGuiKey ImGui_ImplSDL2_KeycodeToImGuiKey(int keycode)
|
||||||
{
|
{
|
||||||
switch (keycode)
|
switch (keycode)
|
||||||
|
|
@ -983,8 +1017,6 @@ void I_GetEvent(void)
|
||||||
// otherwise we'll end up catching the warp back to center.
|
// otherwise we'll end up catching the warp back to center.
|
||||||
//int mouseMotionOnce = 0;
|
//int mouseMotionOnce = 0;
|
||||||
|
|
||||||
UINT8 i;
|
|
||||||
|
|
||||||
if (!graphics_started)
|
if (!graphics_started)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
|
|
@ -1031,147 +1063,14 @@ void I_GetEvent(void)
|
||||||
Impl_HandleControllerButtonEvent(evt.cbutton, evt.type);
|
Impl_HandleControllerButtonEvent(evt.cbutton, evt.type);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
case SDL_CONTROLLERDEVICEADDED:
|
case SDL_CONTROLLERDEVICEADDED:
|
||||||
{
|
Impl_HandleControllerDeviceAddedEvent(evt.cdevice);
|
||||||
// OH BOY are you in for a good time! #abominationstation
|
|
||||||
|
|
||||||
SDL_GameController *newcontroller = SDL_GameControllerOpen(evt.cdevice.which);
|
|
||||||
|
|
||||||
CONS_Debug(DBG_GAMELOGIC, "Controller device index %d added\n", evt.cdevice.which + 1);
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
// Because SDL's device index is unstable, we're going to cheat here a bit:
|
|
||||||
// For the first joystick setting that is NOT active:
|
|
||||||
//
|
|
||||||
// 1. Set cv_usejoystickX.value to the new device index (this does not change what is written to config.cfg)
|
|
||||||
//
|
|
||||||
// 2. Set OTHERS' cv_usejoystickX.value to THEIR new device index, because it likely changed
|
|
||||||
// * If device doesn't exist, switch cv_usejoystick back to default value (.string)
|
|
||||||
// * BUT: If that default index is being occupied, use ANOTHER cv_usejoystick's default value!
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
for (i = 0; i < MAXSPLITSCREENPLAYERS; i++)
|
|
||||||
{
|
|
||||||
if (newcontroller && (!JoyInfo[i].dev || !SDL_GameControllerGetAttached(JoyInfo[i].dev)))
|
|
||||||
{
|
|
||||||
UINT8 j;
|
|
||||||
|
|
||||||
for (j = 0; j < MAXSPLITSCREENPLAYERS; j++)
|
|
||||||
{
|
|
||||||
if (i == j)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (JoyInfo[j].dev == newcontroller)
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
if (j == MAXSPLITSCREENPLAYERS)
|
|
||||||
{
|
|
||||||
// ensures we aren't overriding a currently active device
|
|
||||||
cv_usejoystick[i].value = evt.cdevice.which + 1;
|
|
||||||
I_UpdateJoystickDeviceIndices(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
// Was cv_usejoystick disabled in settings?
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
for (i = 0; i < MAXSPLITSCREENPLAYERS; i++)
|
|
||||||
{
|
|
||||||
if (!strcmp(cv_usejoystick[i].string, "0") || !cv_usejoystick[i].value)
|
|
||||||
cv_usejoystick[i].value = 0;
|
|
||||||
else if (atoi(cv_usejoystick[i].string) <= I_NumJoys() // don't mess if we intentionally set higher than NumJoys
|
|
||||||
&& cv_usejoystick[i].value) // update the cvar ONLY if a device exists
|
|
||||||
CV_SetValue(&cv_usejoystick[i], cv_usejoystick[i].value);
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
// Update all joysticks' init states
|
|
||||||
// This is a little wasteful since cv_usejoystick already calls this, but
|
|
||||||
// we need to do this in case CV_SetValue did nothing because the string was already same.
|
|
||||||
// if the device is already active, this should do nothing, effectively.
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
for (i = 0; i < MAXSPLITSCREENPLAYERS; i++)
|
|
||||||
I_InitJoystick(i);
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
for (i = 0; i < MAXSPLITSCREENPLAYERS; i++)
|
|
||||||
CONS_Debug(DBG_GAMELOGIC, "Joystick%d device index: %d\n", i+1, JoyInfo[i].oldjoy);
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
// update the menu
|
|
||||||
if (currentMenu == &OP_JoystickSetDef)
|
|
||||||
M_SetupJoystickMenu(0);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
for (i = 0; i < MAXSPLITSCREENPLAYERS; i++)
|
|
||||||
{
|
|
||||||
if (JoyInfo[i].dev == newcontroller)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (i == MAXSPLITSCREENPLAYERS)
|
|
||||||
I_StoreExJoystick(newcontroller);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
case SDL_CONTROLLERDEVICEREMOVED:
|
case SDL_CONTROLLERDEVICEREMOVED:
|
||||||
for (i = 0; i < MAXSPLITSCREENPLAYERS; i++)
|
Impl_HandleControllerDeviceRemovedEvent(evt.cdevice);
|
||||||
{
|
|
||||||
if (JoyInfo[i].dev && !SDL_GameControllerGetAttached(JoyInfo[i].dev))
|
|
||||||
{
|
|
||||||
CONS_Debug(DBG_GAMELOGIC, "Joystick%d removed, device index: %d\n", i+1, JoyInfo[i].oldjoy);
|
|
||||||
I_ShutdownJoystick(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
// Update the device indexes, because they likely changed
|
|
||||||
// * If device doesn't exist, switch cv_usejoystick back to default value (.string)
|
|
||||||
// * BUT: If that default index is being occupied, use ANOTHER cv_usejoystick's default value!
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
for (i = 0; i < MAXSPLITSCREENPLAYERS; i++)
|
|
||||||
{
|
|
||||||
I_UpdateJoystickDeviceIndex(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
// Was cv_usejoystick disabled in settings?
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
for (i = 0; i < MAXSPLITSCREENPLAYERS; i++)
|
|
||||||
{
|
|
||||||
if (!strcmp(cv_usejoystick[i].string, "0"))
|
|
||||||
{
|
|
||||||
cv_usejoystick[i].value = 0;
|
|
||||||
}
|
|
||||||
else if (atoi(cv_usejoystick[i].string) <= I_NumJoys() // don't mess if we intentionally set higher than NumJoys
|
|
||||||
&& cv_usejoystick[i].value) // update the cvar ONLY if a device exists
|
|
||||||
{
|
|
||||||
CV_SetValue(&cv_usejoystick[i], cv_usejoystick[i].value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
for (i = 0; i < MAXSPLITSCREENPLAYERS; i++)
|
|
||||||
CONS_Debug(DBG_GAMELOGIC, "Joystick%d device index: %d\n", i+1, JoyInfo[i].oldjoy);
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
// update the menu
|
|
||||||
if (currentMenu == &OP_JoystickSetDef)
|
|
||||||
M_SetupJoystickMenu(0);
|
|
||||||
#endif
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SDL_QUIT:
|
case SDL_QUIT:
|
||||||
LUA_HookBool(true, HOOK(GameQuit));
|
LUA_HookBool(true, HOOK(GameQuit));
|
||||||
I_Quit();
|
I_Quit();
|
||||||
|
|
@ -1195,10 +1094,7 @@ void I_GetEvent(void)
|
||||||
|
|
||||||
// In order to make wheels act like buttons, we have to set their state to Up.
|
// In order to make wheels act like buttons, we have to set their state to Up.
|
||||||
// This is because wheel messages don't have an up/down state.
|
// This is because wheel messages don't have an up/down state.
|
||||||
for (i = 0; i < MAXSPLITSCREENPLAYERS; i++)
|
G_GetDeviceGameKeyDownArray(0)[KEY_MOUSEWHEELDOWN] = G_GetDeviceGameKeyDownArray(0)[KEY_MOUSEWHEELUP] = 0;
|
||||||
{
|
|
||||||
gamekeydown[i][KEY_MOUSEWHEELDOWN] = gamekeydown[i][KEY_MOUSEWHEELUP] = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void half_warp_mouse(uint16_t x, uint16_t y) {
|
static void half_warp_mouse(uint16_t x, uint16_t y) {
|
||||||
|
|
|
||||||
|
|
@ -36,9 +36,6 @@ extern "C" {
|
||||||
#define SDL2STUB() CONS_Printf("SDL2: stubbed: %s:%d\n", __func__, __LINE__)
|
#define SDL2STUB() CONS_Printf("SDL2: stubbed: %s:%d\n", __func__, __LINE__)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// So m_menu knows whether to store cv_usejoystick value or string
|
|
||||||
#define JOYSTICK_HOTPLUG
|
|
||||||
|
|
||||||
/** \brief The JoyInfo_s struct
|
/** \brief The JoyInfo_s struct
|
||||||
|
|
||||||
info about joystick
|
info about joystick
|
||||||
|
|
@ -65,9 +62,6 @@ typedef struct SDLJoyInfo_s
|
||||||
/** \brief SDL info about controllers
|
/** \brief SDL info about controllers
|
||||||
*/
|
*/
|
||||||
extern SDLJoyInfo_t JoyInfo[MAXSPLITSCREENPLAYERS];
|
extern SDLJoyInfo_t JoyInfo[MAXSPLITSCREENPLAYERS];
|
||||||
extern SDL_GameController *ExJoystick[MAXGAMEPADS];
|
|
||||||
|
|
||||||
void I_StoreExJoystick(SDL_GameController *dev);
|
|
||||||
|
|
||||||
/** \brief joystick axis deadzone
|
/** \brief joystick axis deadzone
|
||||||
*/
|
*/
|
||||||
|
|
@ -76,18 +70,6 @@ void I_StoreExJoystick(SDL_GameController *dev);
|
||||||
|
|
||||||
void I_GetConsoleEvents(void);
|
void I_GetConsoleEvents(void);
|
||||||
|
|
||||||
// So we can call this from i_video event loop
|
|
||||||
void I_ShutdownJoystick(UINT8 index);
|
|
||||||
|
|
||||||
// Cheat to get the device index for a game controller handle
|
|
||||||
INT32 I_GetJoystickDeviceIndex(SDL_GameController *dev);
|
|
||||||
|
|
||||||
// Quick thing to make SDL_JOYDEVICEADDED events less of an abomination
|
|
||||||
void I_UpdateJoystickDeviceIndex(UINT8 player);
|
|
||||||
void I_UpdateJoystickDeviceIndices(UINT8 excludePlayer);
|
|
||||||
|
|
||||||
void I_GetConsoleEvents(void);
|
|
||||||
|
|
||||||
void SDLforceUngrabMouse(void);
|
void SDLforceUngrabMouse(void);
|
||||||
|
|
||||||
// Needed for some WIN32 functions
|
// Needed for some WIN32 functions
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue