From 8a9683542bbdc8d3fcb40b320bccae7196be176e Mon Sep 17 00:00:00 2001 From: NepDisk Date: Sat, 14 Feb 2026 16:27:53 -0500 Subject: [PATCH] Fix Gamepads Thanks thanks thanks thanks so much Alug for the time working on this!!!!! --- src/d_clisrv.c | 4 +- src/d_main.cpp | 8 +- src/d_netcmd.c | 45 +- src/d_netcmd.h | 7 +- src/dummy/i_system.c | 12 +- src/g_demo.c | 2 +- src/g_game.c | 18 +- src/g_input.c | 169 +++--- src/g_input.h | 33 +- src/{i_joy.h => i_gamepad.h} | 69 ++- src/i_system.h | 128 +---- src/locale/en.po | 4 +- src/locale/srb2.pot | 4 +- src/lua_baselib.c | 15 +- src/m_menu.c | 72 +-- src/p_inter.c | 56 -- src/p_local.h | 14 - src/p_setup.c | 2 +- src/p_tick.c | 2 +- src/p_user.c | 2 +- src/sdl/CMakeLists.txt | 1 + src/sdl/i_gamepad.c | 406 +++++++++++++ src/sdl/i_system.cpp | 543 +----------------- src/sdl/i_video.cpp | 189 +++--- src/sdl/macosx/Srb2mac.pbproj/project.pbxproj | 4 +- .../macosx/Srb2mac.xcodeproj/project.pbxproj | 4 +- src/sdl/sdlmain.h | 49 +- src/typedef.h | 2 +- 28 files changed, 778 insertions(+), 1086 deletions(-) rename src/{i_joy.h => i_gamepad.h} (51%) create mode 100644 src/sdl/i_gamepad.c diff --git a/src/d_clisrv.c b/src/d_clisrv.c index eda765bfe..868967d82 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -2106,8 +2106,6 @@ static boolean CL_ServerConnectionTicker(const char *tmpsave, tic_t *oldtic, tic renderdeltatics = FRACUNIT; R_SetTimeFrac(FRACUNIT); - memset(deviceResponding, false, sizeof (deviceResponding)); - if (cl_mode == CL_CONFIRMCONNECT) { D_ProcessEvents(); //needed for menu system to receive inputs @@ -2837,7 +2835,7 @@ void CL_Reset(void) http_source[0] = '\0'; #endif - G_ResetAllDeviceRumbles(); + G_ResetAllControllerRumbles(); // D_StartTitle should get done now, but the calling function will handle it } diff --git a/src/d_main.cpp b/src/d_main.cpp index f37657523..456fc24d3 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -221,7 +221,6 @@ void D_ProcessEvents(void) for (size_t i = 0; i < 4; i++) gamekeydown[0][KEY_MOUSEMOVE + i] = 0; - memset(deviceResponding, false, sizeof (deviceResponding)); for (; eventtail != eventhead; eventtail = (eventtail+1) & (MAXEVENTS-1)) { ev = &events[eventtail]; @@ -1105,7 +1104,7 @@ void D_SRB2Loop(void) if (!dedicated) { - G_DeviceLEDTick(); + G_ControllerLEDTick(); } // consoleplayer -> displayplayers (hear sounds from viewpoint) @@ -1222,7 +1221,6 @@ void D_StartTitle(void) // clear cmd building stuff memset(gamekeydown, 0, sizeof(gamekeydown)); - memset(deviceResponding, false, sizeof (deviceResponding)); F_StartTitleScreen(); @@ -1230,13 +1228,13 @@ void D_StartTitle(void) if (rendermode != render_none) V_SetPaletteLump("PLAYPAL"); - G_ResetAllDeviceRumbles(); + G_ResetAllControllerRumbles(); // The title screen is obviously not a tutorial! (Unless I'm mistaken) tutorialmode = false; // map palettes affect this - G_ResetDeviceLED(); + G_ResetControllerLED(); } // diff --git a/src/d_netcmd.c b/src/d_netcmd.c index fcd86e778..19836fb5f 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -18,6 +18,7 @@ #include "console.h" #include "command.h" #include "i_time.h" +#include "i_gamepad.h" #include "i_system.h" #include "g_game.h" #include "hu_stuff.h" @@ -382,31 +383,22 @@ consvar_t cv_usemouse = CVAR_INIT ("use_mouse", "Off", CV_SAVE|CV_CALL,usemouse_ consvar_t cv_laglesscam = CVAR_INIT ("laglesscamera", "Off", CV_SAVE,CV_OnOff, NULL); -consvar_t cv_usejoystick[MAXSPLITSCREENPLAYERS] = { - CVAR_INIT ("use_joystick", "1", CV_SAVE|CV_CALL, usejoystick_cons_t, I_InitJoystick1), - CVAR_INIT ("use_joystick2", "2", CV_SAVE|CV_CALL, usejoystick_cons_t, I_InitJoystick2), - CVAR_INIT ("use_joystick3", "3", CV_SAVE|CV_CALL, usejoystick_cons_t, I_InitJoystick3), - CVAR_INIT ("use_joystick4", "4", CV_SAVE|CV_CALL, usejoystick_cons_t, I_InitJoystick4) +consvar_t cv_usecontroller[MAXSPLITSCREENPLAYERS] = { + CVAR_INIT ("use_joystick", "1", CV_SAVE|CV_CALL, usejoystick_cons_t, I_InitController1), + CVAR_INIT ("use_joystick2", "2", CV_SAVE|CV_CALL, usejoystick_cons_t, I_InitController2), + CVAR_INIT ("use_joystick3", "3", CV_SAVE|CV_CALL, usejoystick_cons_t, I_InitController3), + CVAR_INIT ("use_joystick4", "4", CV_SAVE|CV_CALL, usejoystick_cons_t, I_InitController4) }; #if (defined (LJOYSTICK) || defined (HAVE_SDL)) -consvar_t cv_joyscale[MAXSPLITSCREENPLAYERS] = { - CVAR_INIT ("padscale", "1", CV_SAVE|CV_CALL, NULL, I_JoyScale), - CVAR_INIT ("padscale2", "1", CV_SAVE|CV_CALL, NULL, I_JoyScale2), - CVAR_INIT ("padscale3", "1", CV_SAVE|CV_CALL, NULL, I_JoyScale3), - CVAR_INIT ("padscale4", "1", CV_SAVE|CV_CALL, NULL, I_JoyScale4) +consvar_t cv_controllerscale[MAXSPLITSCREENPLAYERS] = { + CVAR_INIT ("padscale", "1", CV_SAVE|CV_CALL, NULL, I_ControllerScale), + CVAR_INIT ("padscale2", "1", CV_SAVE|CV_CALL, NULL, I_ControllerScale2), + CVAR_INIT ("padscale3", "1", CV_SAVE|CV_CALL, NULL, I_ControllerScale3), + CVAR_INIT ("padscale4", "1", CV_SAVE|CV_CALL, NULL, I_ControllerScale4) }; - -#ifdef LJOYSTICK -consvar_t cv_joyport[MAXSPLITSCREENPLAYERS] = { //Alam: for later - CVAR_INIT ("padport", "/dev/js0", CV_SAVE, joyport_cons_t, NULL), - CVAR_INIT ("padport2", "/dev/js0", CV_SAVE, joyport_cons_t, NULL), - CVAR_INIT ("padport3", "/dev/js0", CV_SAVE, joyport_cons_t, NULL), - CVAR_INIT ("padport4", "/dev/js0", CV_SAVE, joyport_cons_t, NULL) -}; -#endif #else -consvar_t cv_joyscale[MAXSPLITSCREENPLAYERS] = { //Alam: Dummy for save +consvar_t cv_controllerscale[MAXSPLITSCREENPLAYERS] = { //Alam: Dummy for save CVAR_INIT ("padscale", "1", CV_SAVE|CV_HIDEN, NULL, NULL), CVAR_INIT ("padscale2", "1", CV_SAVE|CV_HIDEN, NULL, NULL), CVAR_INIT ("padscale3", "1", CV_SAVE|CV_HIDEN, NULL, NULL), @@ -1385,9 +1377,9 @@ void D_RegisterClientCommands(void) CV_RegisterVar(&cv_deadzonestyle[i]); CV_RegisterVar(&cv_litesteer[i]); CV_RegisterVar(&cv_turnsmooth[i]); - CV_RegisterVar(&cv_rumble[i]); + CV_RegisterVar(&cv_controllerrumble[i]); CV_RegisterVar(&cv_rumblestrength[i]); - CV_RegisterVar(&cv_gamepadled[i]); + CV_RegisterVar(&cv_controllerled[i]); } // filesrch.c @@ -1408,11 +1400,8 @@ void D_RegisterClientCommands(void) for (i = 0; i < MAXSPLITSCREENPLAYERS; i++) { - CV_RegisterVar(&cv_usejoystick[i]); - CV_RegisterVar(&cv_joyscale[i]); -#ifdef LJOYSTICK - CV_RegisterVar(&cv_joyport[i]); -#endif + CV_RegisterVar(&cv_usecontroller[i]); + CV_RegisterVar(&cv_controllerscale[i]); } // s_sound.c @@ -4080,7 +4069,7 @@ static void Got_Pause(UINT8 **cp, INT32 playernum) } I_UpdateMouseGrab(); - G_ResetAllDeviceRumbles(); + G_ResetAllControllerRumbles(); } static void Command_ReplayMarker(void) diff --git a/src/d_netcmd.h b/src/d_netcmd.h index 90aec9a0a..7cca831ac 100644 --- a/src/d_netcmd.h +++ b/src/d_netcmd.h @@ -37,11 +37,8 @@ extern consvar_t cv_splitplayers; extern consvar_t cv_seenames; extern consvar_t cv_usemouse; extern consvar_t cv_laglesscam; -extern consvar_t cv_usejoystick[MAXSPLITSCREENPLAYERS]; -extern consvar_t cv_joyscale[MAXSPLITSCREENPLAYERS]; -#ifdef LJOYSTICK -extern consvar_t cv_joyport[MAXSPLITSCREENPLAYERS]; -#endif +extern consvar_t cv_usecontroller[MAXSPLITSCREENPLAYERS]; +extern consvar_t cv_controllerscale[MAXSPLITSCREENPLAYERS]; // normally in p_mobj but the .h is not read extern consvar_t cv_itemrespawntime; diff --git a/src/dummy/i_system.c b/src/dummy/i_system.c index 4f04769bf..c70dfb855 100644 --- a/src/dummy/i_system.c +++ b/src/dummy/i_system.c @@ -58,20 +58,20 @@ void I_Tactile2(FFType Type, const JoyFF_t *Effect) (void)Effect; } -void I_JoyScale(void){} +void I_ControllerScale(void){} -void I_JoyScale2(void){} +void I_ControllerScale2(void){} -void I_InitJoystick(void){} +void I_InitController(void){} -void I_InitJoystick2(void){} +void I_InitController2(void){} -INT32 I_NumJoys(void) +INT32 I_NumControllers(void) { return 0; } -const char *I_GetJoyName(INT32 joyid) +const char *I_GetControllerName(INT32 joyid) { (void)joyid; return NULL; diff --git a/src/g_demo.c b/src/g_demo.c index c1e254791..2bda27327 100644 --- a/src/g_demo.c +++ b/src/g_demo.c @@ -33,7 +33,7 @@ #include "z_zone.h" #include "i_video.h" #include "byteptr.h" -#include "i_joy.h" +#include "i_gamepad.h" #include "r_local.h" #include "r_skins.h" #include "y_inter.h" diff --git a/src/g_game.c b/src/g_game.c index 6d9a4fe9a..1add0e7f0 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -41,7 +41,7 @@ #include "z_zone.h" #include "i_video.h" #include "byteptr.h" -#include "i_joy.h" +#include "i_gamepad.h" #include "r_local.h" #include "r_skins.h" #include "y_inter.h" @@ -1186,6 +1186,7 @@ boolean G_AxisInDeadzone(UINT8 p, event_t *ev) // if defaults is true, also check default controls if the gamecontrol has no binds boolean G_ControlBoundToKey(UINT8 p, INT32 gc, INT32 key, boolean defaults) { + INT32 deviceID; INT32 i; INT32 (*map)[MAXINPUTMAPPING] = &gamecontrol[p][gc]; @@ -1194,9 +1195,11 @@ boolean G_ControlBoundToKey(UINT8 p, INT32 gc, INT32 key, boolean defaults) if (defaults) { + deviceID = I_GetControllerSlotfromID(I_GetControllerIDForPlayer(p)); for (i = 0; i < MAXINPUTMAPPING; i++) - if (G_KeyIsAvailable((*map)[i], cv_usejoystick[p].value, false)) + if (G_KeyIsAvailable((*map)[i], deviceID, false)) goto bound; + map = &gamecontroldefault[gc]; } bound: @@ -1259,11 +1262,13 @@ INT32 G_PlayerInputAnalog(UINT8 p, INT32 gc, boolean digital, SINT8 type) return 0; } - fixed_t deadzonetype = G_GetDeadZoneType(p,type); + fixed_t deadzonetype = G_GetDeadZoneType(p, type); deadzone = (JOYAXISRANGE * deadzonetype) / FRACUNIT; - deviceID = I_GetJoystickIDForPlayer(p) + 1; + deviceID = I_GetControllerSlotfromID(I_GetControllerIDForPlayer(p)); + if (deviceID == INVALID_DEVICE) + return 0; retrygetcontrol: for (i = 0; i < MAXINPUTMAPPING; i++) @@ -1812,14 +1817,13 @@ void G_DoLoadLevel(boolean resetplayer) // clear cmd building stuff memset(gamekeydown, 0, sizeof (gamekeydown)); - memset(deviceResponding, false, sizeof (deviceResponding)); // clear hud messages remains (usually from game startup) CON_ClearHUD(); server_lagless = cv_lagless.value; - G_ResetAllDeviceRumbles(); + G_ResetAllControllerRumbles(); if (doAutomate == true) { @@ -3783,7 +3787,7 @@ void G_FinishExitLevel(void) { if (gamestate == GS_LEVEL) { - G_ResetAllDeviceRumbles(); + G_ResetAllControllerRumbles(); if (g_exit.retry) { diff --git a/src/g_input.c b/src/g_input.c index d6d62818e..d9eceaca3 100644 --- a/src/g_input.c +++ b/src/g_input.c @@ -14,13 +14,12 @@ #include "doomdef.h" #include "doomstat.h" #include "g_input.h" -#include "i_system.h" #include "k_items.h" #include "keys.h" #include "hu_stuff.h" // need HUFONT start & end #include "d_net.h" #include "console.h" -#include "i_joy.h" // JOYAXISRANGE +#include "i_gamepad.h" // JOYAXISRANGE #include "m_menu.h" // menustack #include "i_system.h" #include "g_game.h" @@ -55,19 +54,19 @@ consvar_t cv_turnsmooth[MAXSPLITSCREENPLAYERS] = { CVAR_INIT ("turnsmoothing4", "Off", CV_SAVE, turnsmooth_cons_t, NULL) }; -static void G_ResetPlayerDeviceRumble(INT32 player); +static void G_ResetPlayerControllerRumble(INT32 player); static void rumble_off_handle(void); static void rumble_off_handle2(void); static void rumble_off_handle3(void); static void rumble_off_handle4(void); -static void G_ResetPlayerGamepadIndicatorColor(INT32 player); +static void G_ResetPlayerControllerIndicatorColor(INT32 player); static void led_off_handle(void); static void led_off_handle2(void); static void led_off_handle3(void); static void led_off_handle4(void); -consvar_t cv_rumble[MAXSPLITSCREENPLAYERS] = { +consvar_t cv_controllerrumble[MAXSPLITSCREENPLAYERS] = { CVAR_INIT ("rumble", "On", CV_SAVE, CV_OnOff, rumble_off_handle), CVAR_INIT ("rumble2", "On", CV_SAVE, CV_OnOff, rumble_off_handle2), CVAR_INIT ("rumble3", "On", CV_SAVE, CV_OnOff, rumble_off_handle3), @@ -83,63 +82,62 @@ consvar_t cv_rumblestrength[MAXSPLITSCREENPLAYERS] = { CVAR_INIT ("rumblestrength4", "1.0", CV_SAVE|CV_FLOAT, rumblestrength_cons_t, NULL) }; -static CV_PossibleValue_t gamepadled_cons_t[] = {{0, "Off"}, {1, "Skincolor"}, {2, "Mobjcolor"}, {0, NULL}}; -consvar_t cv_gamepadled[MAXSPLITSCREENPLAYERS] = { - CVAR_INIT ("gamepadled", "Skincolor", CV_SAVE|CV_CALL|CV_NOINIT, gamepadled_cons_t, led_off_handle), - CVAR_INIT ("gamepadled2", "Skincolor", CV_SAVE|CV_CALL|CV_NOINIT, gamepadled_cons_t, led_off_handle2), - CVAR_INIT ("gamepadled3", "Skincolor", CV_SAVE|CV_CALL|CV_NOINIT, gamepadled_cons_t, led_off_handle3), - CVAR_INIT ("gamepadled4", "Skincolor", CV_SAVE|CV_CALL|CV_NOINIT, gamepadled_cons_t, led_off_handle4) +static CV_PossibleValue_t controllerled_cons_t[] = {{0, "Off"}, {1, "Skincolor"}, {2, "Mobjcolor"}, {0, NULL}}; +consvar_t cv_controllerled[MAXSPLITSCREENPLAYERS] = { + CVAR_INIT ("gamepadled", "Skincolor", CV_SAVE|CV_CALL|CV_NOINIT, controllerled_cons_t, led_off_handle), + CVAR_INIT ("gamepadled2", "Skincolor", CV_SAVE|CV_CALL|CV_NOINIT, controllerled_cons_t, led_off_handle2), + CVAR_INIT ("gamepadled3", "Skincolor", CV_SAVE|CV_CALL|CV_NOINIT, controllerled_cons_t, led_off_handle3), + CVAR_INIT ("gamepadled4", "Skincolor", CV_SAVE|CV_CALL|CV_NOINIT, controllerled_cons_t, led_off_handle4) }; static void rumble_off_handle(void) { - if (cv_rumble[0].value == 0) - G_ResetPlayerDeviceRumble(0); + if (cv_controllerrumble[0].value == 0) + G_ResetPlayerControllerRumble(0); } static void rumble_off_handle2(void) { - if (cv_rumble[1].value == 0) - G_ResetPlayerDeviceRumble(1); + if (cv_controllerrumble[1].value == 0) + G_ResetPlayerControllerRumble(1); } static void rumble_off_handle3(void) { - if (cv_rumble[2].value == 0) - G_ResetPlayerDeviceRumble(2); + if (cv_controllerrumble[2].value == 0) + G_ResetPlayerControllerRumble(2); } static void rumble_off_handle4(void) { - if (cv_rumble[3].value == 0) - G_ResetPlayerDeviceRumble(3); + if (cv_controllerrumble[3].value == 0) + G_ResetPlayerControllerRumble(3); } static void led_off_handle(void) { - G_ResetPlayerGamepadIndicatorColor(0); + G_ResetPlayerControllerIndicatorColor(0); } static void led_off_handle2(void) { - G_ResetPlayerGamepadIndicatorColor(1); + G_ResetPlayerControllerIndicatorColor(1); } static void led_off_handle3(void) { - G_ResetPlayerGamepadIndicatorColor(2); + G_ResetPlayerControllerIndicatorColor(2); } static void led_off_handle4(void) { - G_ResetPlayerGamepadIndicatorColor(3); + G_ResetPlayerControllerIndicatorColor(3); } // current state of the keys // JOYAXISRANGE for fully pressed, 0 for not pressed inputpoll_t gamekeydown = {}; inputpoll_t gamekeydown_msec = {}; -boolean deviceResponding[MAXDEVICES] = {false}; // several key codes (or virtual key) per game control INT32 gamecontrol[MAXSPLITSCREENPLAYERS][num_gamecontrols][MAXINPUTMAPPING] = {}; @@ -202,7 +200,7 @@ INT32 G_GetDevicePlayer(INT32 deviceID) for (i = 0; i < MAXSPLITSCREENPLAYERS; i++) { - if (deviceID == I_GetJoystickIDForPlayer(i) + 1) + if (deviceID == I_GetControllerIDForPlayer(i) + 1) { return i; } @@ -215,8 +213,8 @@ INT32 G_GetDevicePlayer(INT32 deviceID) INT32 G_AxisToKey(event_t *ev) { return KEY_AXIS1 + (ev->data1 >= JOYANALOGS - ? ev->data1 + JOYANALOGS // triggers - : ev->data1*2 + (ev->data2 >= 0)); // analog sticks + ? ev->data1 + JOYANALOGS // triggers + : ev->data1*2 + (ev->data2 >= 0)); // analog sticks } // @@ -230,32 +228,28 @@ void G_MapEventsToControls(event_t *ev) { INT32 i; - if (ev->device >= 0 && ev->device < MAXDEVICES) - { - switch (ev->type) - { - case ev_keydown: - //case ev_keyup: - //case ev_mouse: - //case ev_joystick: - deviceResponding[ev->device] = true; - break; + INT32 device = ev->device; - default: - break; - } - } - else - { + // invalid + if (device < KEYBOARD_MOUSE_DEVICE || device >= UINT32_MAX) + return; + + // not a keyboard? + // try to see if its a controller in use + if (device > KEYBOARD_MOUSE_DEVICE) + device = I_GetControllerSlotfromID(device-1); + + // nope no controller thats used + // so ignore it + if (device == INVALID_DEVICE) return; - } switch (ev->type) { case ev_keydown: if (ev->data1 < NUMINPUTS) { - gamekeydown[ev->device][ev->data1] = JOYAXISRANGE; + gamekeydown[device][ev->data1] = JOYAXISRANGE; } #ifdef PARANOIA else @@ -268,7 +262,7 @@ void G_MapEventsToControls(event_t *ev) case ev_keyup: if (ev->data1 < NUMINPUTS) { - gamekeydown[ev->device][ev->data1] = 0; + gamekeydown[device][ev->data1] = 0; } #ifdef PARANOIA else @@ -288,28 +282,28 @@ void G_MapEventsToControls(event_t *ev) if (ev->data2 < 0) { // Left - gamekeydown[ev->device][KEY_MOUSEMOVE + 2] = abs(ev->data2); - gamekeydown[ev->device][KEY_MOUSEMOVE + 3] = 0; + gamekeydown[device][KEY_MOUSEMOVE + 2] = abs(ev->data2); + gamekeydown[device][KEY_MOUSEMOVE + 3] = 0; } else { // Right - gamekeydown[ev->device][KEY_MOUSEMOVE + 2] = 0; - gamekeydown[ev->device][KEY_MOUSEMOVE + 3] = abs(ev->data2); + gamekeydown[device][KEY_MOUSEMOVE + 2] = 0; + gamekeydown[device][KEY_MOUSEMOVE + 3] = abs(ev->data2); } // Y axis if (ev->data3 < 0) { // Up - gamekeydown[ev->device][KEY_MOUSEMOVE] = abs(ev->data3); - gamekeydown[ev->device][KEY_MOUSEMOVE + 1] = 0; + gamekeydown[device][KEY_MOUSEMOVE] = abs(ev->data3); + gamekeydown[device][KEY_MOUSEMOVE + 1] = 0; } else { // Down - gamekeydown[ev->device][KEY_MOUSEMOVE] = 0; - gamekeydown[ev->device][KEY_MOUSEMOVE + 1] = abs(ev->data3); + gamekeydown[device][KEY_MOUSEMOVE] = 0; + gamekeydown[device][KEY_MOUSEMOVE + 1] = abs(ev->data3); } break; @@ -327,6 +321,7 @@ void G_MapEventsToControls(event_t *ev) break; } + // tf is this for? if (G_GetDevicePlayer(ev->device) == 0) { if (CON_Ready() || chat_on) @@ -338,9 +333,9 @@ void G_MapEventsToControls(event_t *ev) { // analog stick axes have a negative and positive keydown i -= ev->data2 >= 0; - gamekeydown[ev->device][i++] = max(0, -ev->data2); + gamekeydown[device][i++] = max(0, -ev->data2); } - gamekeydown[ev->device][i] = max(0, ev->data2); + gamekeydown[device][i] = max(0, ev->data2); break; @@ -520,7 +515,7 @@ static const char *gamecontrolname[num_gamecontrols] = #define NUMKEYNAMES (sizeof (keynames)/sizeof (keyname_t)) -skincolornum_t G_GetSkinColorForGamepad(INT32 playernum) +skincolornum_t G_GetSkinColorForController(INT32 playernum) { I_Assert(playernum >= 0 && playernum < MAXSPLITSCREENPLAYERS); @@ -531,7 +526,7 @@ skincolornum_t G_GetSkinColorForGamepad(INT32 playernum) if (player) { // make rgb rainbow vomit when invul or flash blue when grow - if ((cv_gamepadled[playernum].value == 2) && player->mo && player->mo->color) + if ((cv_controllerled[playernum].value == 2) && player->mo && player->mo->color) return (skincolornum_t)player->mo->color; // take actual player skincolour when ingame @@ -546,45 +541,46 @@ skincolornum_t G_GetSkinColorForGamepad(INT32 playernum) // Sets the Indicator LED on supported gamepads to a desired skincolor // pass SKINCOLOR_NONE/0 to set the players skin color -void G_SetPlayerGamepadIndicatorColor(INT32 playernum, UINT16 color) +void G_SetPlayerControllerIndicatorColor(INT32 playernum, UINT16 color) { skincolornum_t skincolor; byteColor_t byte_color; I_Assert(playernum >= 0 && playernum < MAXSPLITSCREENPLAYERS); - if (cv_gamepadled[playernum].value == 0) + if (cv_controllerled[playernum].value == 0) { return; } // so we can override this - skincolor = color ? color : G_GetSkinColorForGamepad(playernum); + skincolor = color ? color : G_GetSkinColorForController(playernum); byte_color = V_GetColor(skincolors[skincolor].ramp[8]).s; - I_SetGamepadIndicatorColor(playernum, byte_color.red, byte_color.green, byte_color.blue); + I_SetControllerIndicatorColor(playernum, byte_color.red, byte_color.green, byte_color.blue); } -static void G_ResetPlayerGamepadIndicatorColor(INT32 playernum) +static void G_ResetPlayerControllerIndicatorColor(INT32 playernum) { I_Assert(playernum >= 0 && playernum < MAXSPLITSCREENPLAYERS); - if (cv_gamepadled[playernum].value == 0) + if (cv_controllerled[playernum].value == 0) { - I_SetGamepadIndicatorColor(playernum, 0, 0, 255); + I_SetControllerIndicatorColor(playernum, 0, 0, 255); } else { - G_SetPlayerGamepadIndicatorColor(playernum, 0); + G_SetPlayerControllerIndicatorColor(playernum, 0); } } static skincolornum_t curcolor[MAXSPLITSCREENPLAYERS] = {}; -void G_DeviceLEDTick(void) +void G_ControllerLEDTick(void) { UINT8 i; static skincolornum_t newcolor = SKINCOLOR_NONE; + const INT32 numcontrollers = I_NumControllers(); if (numcontrollers == 0) { @@ -593,44 +589,48 @@ void G_DeviceLEDTick(void) for (i = 0; i <= splitscreen; i++) { - if (!cv_usejoystick[i].value || !cv_gamepadled[i].value) + if (!cv_usecontroller[i].value || !cv_controllerled[i].value) continue; - newcolor = G_GetSkinColorForGamepad(i); + // Players controller does not have an addressable rbg light, bummer! + if (!I_ControllerSupportsIndicatorColor(i)) + continue; + + newcolor = G_GetSkinColorForController(i); if (curcolor[i] == newcolor) // dont update if same colour continue; - G_SetPlayerGamepadIndicatorColor(i, newcolor); + G_SetPlayerControllerIndicatorColor(i, newcolor); curcolor[i] = newcolor; } } -void G_ResetDeviceLED(void) +void G_ResetControllerLED(void) { memset(curcolor, 0, sizeof(curcolor)); } -static void G_ResetPlayerDeviceRumble(INT32 playernum) +static void G_ResetPlayerControllerRumble(INT32 playernum) { I_Assert(playernum >= 0 && playernum < MAXSPLITSCREENPLAYERS); - I_GamepadRumble(playernum, 0, 0, 0); + I_ControllerRumble(playernum, 0, 0, 0); } -void G_ResetAllDeviceRumbles(void) +void G_ResetAllControllerRumbles(void) { for (int i = 0; i < MAXSPLITSCREENPLAYERS; i++) { - I_GamepadRumble(i, 0, 0, 0); + I_ControllerRumble(i, 0, 0, 0); } } -void G_PlayerDeviceRumble(INT32 playernum, UINT16 low_strength, UINT16 high_strength, UINT32 duration) +void G_PlayerControllerRumble(INT32 playernum, UINT16 low_strength, UINT16 high_strength, UINT32 duration) { I_Assert(playernum >= 0 && playernum < MAXSPLITSCREENPLAYERS); - if (cv_rumble[playernum].value == 0) + if (cv_controllerrumble[playernum].value == 0) { return; } @@ -641,7 +641,7 @@ void G_PlayerDeviceRumble(INT32 playernum, UINT16 low_strength, UINT16 high_stre low_strength = (UINT16)min(FixedMul(low_strength, cv_rumblestrength[playernum].value), UINT16_MAX); high_strength = (UINT16)min(FixedMul(high_strength, cv_rumblestrength[playernum].value), UINT16_MAX); - I_GamepadRumble(playernum, low_strength, high_strength, duration); + I_ControllerRumble(playernum, low_strength, high_strength, duration); } // rumble strengths @@ -657,9 +657,10 @@ enum // Controller rumble! // this keeps track of a bunch of things // and makes your controller rumble accordingly -void G_DeviceRumbleTick(void) +void G_ControllerRumbleTick(void) { UINT8 i; + const INT32 numcontrollers = I_NumControllers(); if (dedicated || numcontrollers == 0 || gamestate != GS_LEVEL) { @@ -668,11 +669,15 @@ void G_DeviceRumbleTick(void) for (i = 0; i <= splitscreen; i++) { - if (!cv_usejoystick[i].value || !cv_rumble[i].value) + if (!cv_usecontroller[i].value || !cv_controllerrumble[i].value) { continue; } + // Players controller does not support rumble, bummer! + if (!I_ControllerSupportsRumble(i)) + continue; + if (camera[i].freecam) { continue; @@ -694,7 +699,7 @@ void G_DeviceRumbleTick(void) player->playerstate == PST_DEAD || player->respawn > 1) { - G_PlayerDeviceRumble(i, low, high, 0); + G_PlayerControllerRumble(i, low, high, 0); continue; } @@ -799,7 +804,7 @@ void G_DeviceRumbleTick(void) continue; } - G_PlayerDeviceRumble(i, low, high, lenght); + G_PlayerControllerRumble(i, low, high, lenght); } } diff --git a/src/g_input.h b/src/g_input.h index 8bd3561c7..fd0a0839f 100644 --- a/src/g_input.h +++ b/src/g_input.h @@ -29,7 +29,9 @@ extern "C" { #define MOUSEBUTTONS 8 -#define JOYBUTTONS SDL_GAMEPAD_BUTTON_COUNT // 26 buttons, to match SDL_GameControllerButton +#define JOYBUTTONS 26 // 26 buttons, to match SDL_GameControllerButton +#define JOY_DPAD_UP 11 + #define JOYANALOGS 4 // 4 analog stick axes (2 sticks * 2 axes) #define JOYTRIGGERS 2 // 2 trigger axes, positive only #define JOYAXISES (JOYANALOGS + JOYTRIGGERS) @@ -43,7 +45,7 @@ extern "C" { typedef enum { KEY_JOY1 = NUMKEYS, - KEY_HAT1 = KEY_JOY1 + SDL_GAMEPAD_BUTTON_DPAD_UP, // macro for SDL_CONTROLLER_BUTTON_DPAD_UP + KEY_HAT1 = KEY_JOY1 + JOY_DPAD_UP, KEY_AXIS1 = KEY_JOY1 + JOYBUTTONS, JOYINPUTEND = KEY_AXIS1 + JOYAXISKEYS, @@ -98,19 +100,19 @@ extern consvar_t cv_mousesens2, cv_mouseysens2; extern consvar_t cv_controlperkey; extern consvar_t cv_litesteer[MAXSPLITSCREENPLAYERS]; extern consvar_t cv_turnsmooth[MAXSPLITSCREENPLAYERS]; -extern consvar_t cv_rumble[MAXSPLITSCREENPLAYERS]; +extern consvar_t cv_controllerrumble[MAXSPLITSCREENPLAYERS]; extern consvar_t cv_rumblestrength[MAXSPLITSCREENPLAYERS]; -extern consvar_t cv_gamepadled[MAXSPLITSCREENPLAYERS]; +extern consvar_t cv_controllerled[MAXSPLITSCREENPLAYERS]; // current state of the keys: JOYAXISRANGE or 0 when boolean. // Or anything inbetween for analog values -#define MAXDEVICES (MAXGAMEPADS + 1) // Gamepads + keyboard & mouse +#define MAXDEVICES (MAXGAMEPADS + 10) // Gamepads + keyboard & mouse +// the above is horrid since device tracks the gamepad id for whatever godawful reason +// the gamepad instance id may be alot larger than (MAXGAMEPADS + 1)/"9" typedef INT32 inputpoll_t[MAXDEVICES][NUMINPUTS]; extern inputpoll_t gamekeydown, gamekeydown_msec; -extern boolean deviceResponding[MAXDEVICES]; - // several key codes (or virtual key) per game control extern INT32 gamecontrol[MAXSPLITSCREENPLAYERS][num_gamecontrols][MAXINPUTMAPPING]; extern INT32 gamecontroldefault[num_gamecontrols][MAXINPUTMAPPING]; // default control storage @@ -134,13 +136,16 @@ extern const INT32 gcl_full[num_gcl_full]; // peace to my little coder fingers! // check a gamecontrol being active or not -skincolornum_t G_GetSkinColorForGamepad(INT32 playernum); -void G_SetPlayerGamepadIndicatorColor(INT32 playernum, UINT16 color); -void G_DeviceLEDTick(void); -void G_ResetDeviceLED(void); -void G_ResetAllDeviceRumbles(void); -void G_PlayerDeviceRumble(INT32 playernum, UINT16 low_strength, UINT16 high_strength, UINT32 duration); -void G_DeviceRumbleTick(void); +#define INVALID_DEVICE -1 +#define KEYBOARD_MOUSE_DEVICE 0 + +skincolornum_t G_GetSkinColorForController(INT32 playernum); +void G_SetPlayerControllerIndicatorColor(INT32 playernum, UINT16 color); +void G_ControllerLEDTick(void); +void G_ResetControllerLED(void); +void G_ResetAllControllerRumbles(void); +void G_PlayerControllerRumble(INT32 playernum, UINT16 low_strength, UINT16 high_strength, UINT32 duration); +void G_ControllerRumbleTick(void); INT32 G_GetDevicePlayer(INT32 deviceID); diff --git a/src/i_joy.h b/src/i_gamepad.h similarity index 51% rename from src/i_joy.h rename to src/i_gamepad.h index b3fe1c39a..08656051d 100644 --- a/src/i_joy.h +++ b/src/i_gamepad.h @@ -7,11 +7,11 @@ // terms of the GNU General Public License, version 2. // See the 'LICENSE' file for more details. //----------------------------------------------------------------------------- -/// \file i_joy.h -/// \brief share joystick information with game control code +/// \file i_gamepad.h +/// \brief share gamepad information with game control code -#ifndef __I_JOY_H__ -#define __I_JOY_H__ +#ifndef __I_GAMEPAD_H__ +#define __I_GAMEPAD_H__ #include "g_input.h" @@ -44,9 +44,6 @@ extern "C" { struct JoyType_t { - /*! if true, we MUST Poll() to get new joystick data, - that is: we NEED the DIRECTINPUTDEVICE2 ! (watchout NT compatibility) */ - INT32 bJoyNeedPoll; /*! this joystick is a gamepad, read: digital axes if FALSE, interpret the joystick event data as JOYAXISRANGE (see above) */ INT32 bGamepadStyle; @@ -58,6 +55,64 @@ struct JoyType_t extern JoyType_t Joystick[MAXSPLITSCREENPLAYERS]; +/** \brief to set up the first joystick scale +*/ +void I_ControllerScale(void); + +/** \brief to set up the second joystick scale +*/ +void I_ControllerScale2(void); + +/** \brief to set up the third joystick scale +*/ +void I_ControllerScale3(void); + +/** \brief to set up the fourth joystick scale +*/ +void I_ControllerScale4(void); + +// Called by D_SRB2Main. + +/** \brief to startup a joystick +*/ +void I_InitController(UINT8 index); + +/** \brief to startup the first joystick +*/ +void I_InitController1(void); + +/** \brief to startup the second joystick +*/ +void I_InitController2(void); + +/** \brief to startup the third joystick +*/ +void I_InitController3(void); + +/** \brief to startup the fourth joystick +*/ +void I_InitController4(void); + +/** \brief return the number of joystick on the system +*/ +INT32 I_NumControllers(void); + +/** \brief The *I_GetControllerName function + + \param joyid which joystick + + \return joystick name +*/ +const char *I_GetControllerName(INT32 joyid); + +INT32 I_GetControllerSlotfromID(INT32 id); + +boolean I_ControllerSupportsRumble(INT32 playernum); +boolean I_ControllerSupportsIndicatorColor(INT32 playernum); + +void I_ControllerRumble(INT32 playernum, UINT16 low_strength, UINT16 high_strength, UINT32 duration); +void I_SetControllerIndicatorColor(INT32 playernum, UINT8 red, UINT8 green, UINT8 blue); + #ifdef __cplusplus } // extern "C" #endif diff --git a/src/i_system.h b/src/i_system.h index 2bd528f7b..076a62101 100644 --- a/src/i_system.h +++ b/src/i_system.h @@ -118,132 +118,6 @@ ticcmd_t *I_BaseTiccmd4(void); */ void I_Quit(void) FUNCNORETURN; -typedef enum -{ - EvilForce = -1, - //Constant - ConstantForce = 0, - //Ramp - RampForce, - //Periodics - SquareForce, - SineForce, - TriangleForce, - SawtoothUpForce, - SawtoothDownForce, - //MAX - NumberofForces, -} FFType; - -struct JoyFF_t -{ - INT32 ForceX; ///< The X of the Force's Vel - INT32 ForceY; ///< The Y of the Force's Vel - //All - UINT32 Duration; ///< The total duration of the effect, in microseconds - INT32 Gain; //< /The gain to be applied to the effect, in the range from 0 through 10,000. - //All, CONSTANTFORCE -10,000 to 10,000 - INT32 Magnitude; ///< Magnitude of the effect, in the range from 0 through 10,000. - //RAMPFORCE - INT32 Start; ///< Magnitude at the start of the effect, in the range from -10,000 through 10,000. - INT32 End; ///< Magnitude at the end of the effect, in the range from -10,000 through 10,000. - //PERIODIC - INT32 Offset; ///< Offset of the effect. - UINT32 Phase; ///< Position in the cycle of the periodic effect at which playback begins, in the range from 0 through 35,999 - UINT32 Period; ///< Period of the effect, in microseconds. -}; - -/** \brief Forcefeedback for the first joystick - - \param Type what kind of Effect - \param Effect Effect Info - - \return void -*/ - -void I_Tactile(FFType Type, const JoyFF_t *Effect); - -/** \brief Forcefeedback for the second joystick - - \param Type what kind of Effect - \param Effect Effect Info - - \return void -*/ -void I_Tactile2(FFType Type, const JoyFF_t *Effect); - -/** \brief Forcefeedback for the third joystick - -\param Type what kind of Effect -\param Effect Effect Info - -\return void -*/ -void I_Tactile3(FFType Type, const JoyFF_t *Effect); - -/** \brief Forcefeedback for the fourth joystick - -\param Type what kind of Effect -\param Effect Effect Info - -\return void -*/ -void I_Tactile4(FFType Type, const JoyFF_t *Effect); - -/** \brief to set up the first joystick scale -*/ -void I_JoyScale(void); - -/** \brief to set up the second joystick scale -*/ -void I_JoyScale2(void); - -/** \brief to set up the third joystick scale -*/ -void I_JoyScale3(void); - -/** \brief to set up the fourth joystick scale -*/ -void I_JoyScale4(void); - -// Called by D_SRB2Main. - -/** \brief to startup a joystick -*/ -void I_InitJoystick(UINT8 index); - -/** \brief to startup the first joystick -*/ -void I_InitJoystick1(void); - -/** \brief to startup the second joystick -*/ -void I_InitJoystick2(void); - -/** \brief to startup the third joystick -*/ -void I_InitJoystick3(void); - -/** \brief to startup the fourth joystick -*/ -void I_InitJoystick4(void); - -/** \brief return the number of joystick on the system -*/ -INT32 I_NumJoys(void); -extern INT32 numcontrollers; - -/** \brief The *I_GetJoyName function - - \param joyid which joystick - - \return joystick name -*/ -const char *I_GetJoyName(INT32 joyid); - -void I_GamepadRumble(INT32 playernum, UINT16 low_strength, UINT16 high_strength, UINT32 duration); -void I_SetGamepadIndicatorColor(INT32 playernum, UINT8 red, UINT8 green, UINT8 blue); - #ifndef NOMUMBLE #include "p_mobj.h" // mobj_t #include "s_sound.h" // listener_t @@ -320,7 +194,7 @@ const char *I_LocateWad(void); */ void I_GetJoystickEvents(UINT8 index); -INT32 I_GetJoystickIDForPlayer(UINT8 pnum); +INT32 I_GetControllerIDForPlayer(UINT8 pnum); /** \brief Checks if the mouse needs to be grabbed */ diff --git a/src/locale/en.po b/src/locale/en.po index 8dd08173d..9a8f39acf 100644 --- a/src/locale/en.po +++ b/src/locale/en.po @@ -3866,7 +3866,7 @@ msgid "Set the use_joystick variable to one of the enumerated joystick numbers\n msgstr "" #: win32/win_sys.c:2002 -msgid "I_InitJoystick: SetCooperativeLevel FAILED" +msgid "I_InitController: SetCooperativeLevel FAILED" msgstr "" #: win32/win_sys.c:2006 win32/win_sys.c:2373 @@ -3882,7 +3882,7 @@ msgid "Set the use_joystick2 variable to one of the enumerated joysticks number\ msgstr "" #: win32/win_sys.c:2364 -msgid "I_InitJoystick2: SetCooperativeLevel FAILED" +msgid "I_InitController2: SetCooperativeLevel FAILED" msgstr "" #: win32/win_sys.c:3466 diff --git a/src/locale/srb2.pot b/src/locale/srb2.pot index cd2db750d..5cbf8b165 100644 --- a/src/locale/srb2.pot +++ b/src/locale/srb2.pot @@ -4062,7 +4062,7 @@ msgid "Set the use_joystick variable to one of the enumerated joystick numbers\n msgstr "" #: win32/win_sys.c:2004 -msgid "I_InitJoystick: SetCooperativeLevel FAILED" +msgid "I_InitController: SetCooperativeLevel FAILED" msgstr "" #: win32/win_sys.c:2008 win32/win_sys.c:2375 @@ -4078,7 +4078,7 @@ msgid "Set the use_joystick2 variable to one of the enumerated joysticks number\ msgstr "" #: win32/win_sys.c:2366 -msgid "I_InitJoystick2: SetCooperativeLevel FAILED" +msgid "I_InitController2: SetCooperativeLevel FAILED" msgstr "" #: win32/win_sys.c:3468 diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 875cb9675..007c26d4e 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -5392,7 +5392,7 @@ static int lib_kGetItemListEntry(lua_State *L) // G_INPUT //////////// -static int lib_gSetPlayerGamepadIndicatorColor(lua_State *L) +static int lib_gSetPlayerControllerIndicatorColor(lua_State *L) { INT32 player = -1; player_t *plr = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); // retrieve player @@ -5417,12 +5417,12 @@ static int lib_gSetPlayerGamepadIndicatorColor(lua_State *L) if (player == -1) return 0; // pls update with color 0 when youre done with changing led stuff so it can get player color again - G_SetPlayerGamepadIndicatorColor(player, color); + G_SetPlayerControllerIndicatorColor(player, color); return 0; } -static int lib_gPlayerDeviceRumble(lua_State *L) +static int lib_gPlayerControllerRumble(lua_State *L) { INT32 player = -1; player_t *plr = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); // retrieve player @@ -5445,7 +5445,7 @@ static int lib_gPlayerDeviceRumble(lua_State *L) // Not a local player if (player == -1) return 0; - G_PlayerDeviceRumble(player, low_strength, high_strength, duration); + G_PlayerControllerRumble(player, low_strength, high_strength, duration); return 0; } @@ -5862,8 +5862,11 @@ static luaL_Reg lib[] = { {"K_GetItemListEntry", lib_kGetItemListEntry}, //g_input - {"G_SetPlayerGamepadIndicatorColor",lib_gSetPlayerGamepadIndicatorColor}, - {"G_PlayerDeviceRumble",lib_gPlayerDeviceRumble}, + //{"G_SetPlayerControllerIndicatorColor", lib_gSetPlayerControllerIndicatorColor}, + //{"G_PlayerControllerRumble", lib_gPlayerControllerRumble}, + // gotta keep backwards compat :chaosleep: + {"G_SetPlayerGamepadIndicatorColor", lib_gSetPlayerControllerIndicatorColor}, + {"G_PlayerDeviceRumble", lib_gPlayerControllerRumble}, {NULL, NULL} }; diff --git a/src/m_menu.c b/src/m_menu.c index ab3cef159..3451cdc55 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -78,7 +78,7 @@ #include "r_fps.h" #include "m_easing.h" -#include "i_joy.h" // for joystick menu controls +#include "i_gamepad.h" // for joystick menu controls // Condition Sets #include "m_cond.h" @@ -531,7 +531,7 @@ consvar_t cv_dummyfollower = CVAR_INIT ("dummyfollower", "-1", CV_HIDEN, dummyfo SINT8 dummycolorplayer = 0; static void SetDummyColorPlayer(void) { - G_SetPlayerGamepadIndicatorColor(dummycolorplayer, (UINT16)cv_dummycolor.value); + G_SetPlayerControllerIndicatorColor(dummycolorplayer, (UINT16)cv_dummycolor.value); } consvar_t cv_dummycolor = CVAR_INIT ("dummycolor", "0", CV_HIDEN|CV_CALL|CV_NOINIT, dummycolor_cons_t, SetDummyColorPlayer); @@ -2617,8 +2617,8 @@ static void M_DrawRightString(menuitem_t *item, INT16 x, INT16 y, INT32 vflags, } else if (item->submenu == MN_OP_JOYSTICKSET) // gamepad select { - INT32 stick = cv_usejoystick[setupcontrolplayer-1].value; - const char *name = stick == 0 ? "None" : I_GetJoyName(stick); + INT32 stick = cv_usecontroller[setupcontrolplayer-1].value; + const char *name = stick == 0 ? "None" : I_GetControllerName(stick); if (!name) name = "?"; w = V_StringWidth(name, vflags); (w > BASEVIDWIDTH/2 - 4 ? V_DrawRightAlignedThinString : V_DrawRightAlignedString) @@ -8148,7 +8148,7 @@ INT32 MR_SetupMultiPlayer(INT32 arg) gridcss_skinmemory = cv_chooseskin.value; CV_SetValue(&cv_dummyfollower, cv_follower[arg].value); CV_SetValue(&cv_dummycolor, cv_playercolor[arg].value); - G_SetPlayerGamepadIndicatorColor(arg, cv_playercolor[arg].value); + G_SetPlayerControllerIndicatorColor(arg, cv_playercolor[arg].value); dummycolorplayer = arg; Skinsort_option_Onchange(); @@ -8419,17 +8419,19 @@ void MD_DrawJoystick(void) { INT32 i; INT32 compareval; - +#ifdef JOYSTICK_HOTPLUG + const INT32 numcontrollers = I_NumControllers(); +#endif MD_DrawGenericMenu(); for (i = 0; i <= MAXGAMEPADS; i++) { #ifdef JOYSTICK_HOTPLUG - if (atoi(cv_usejoystick[setupcontrolplayer-1].string) > numcontrollers) - compareval = atoi(cv_usejoystick[setupcontrolplayer-1].string); + if (atoi(cv_usecontroller[setupcontrolplayer-1].string) > numcontrollers) + compareval = atoi(cv_usecontroller[setupcontrolplayer-1].string); else #endif - compareval = cv_usejoystick[setupcontrolplayer-1].value; + compareval = cv_usecontroller[setupcontrolplayer-1].value; V_DrawString(menudefs[MN_OP_JOYSTICKSET].x, menudefs[MN_OP_JOYSTICKSET].y + 16*i, ((i == compareval) ? V_GREENMAP : 0)|MENUCAPS, joystickInfo[i]); } @@ -8438,7 +8440,7 @@ void MD_DrawJoystick(void) INT32 MR_SetupJoystickMenu(INT32 arg) { const char *joyNA = "Unavailable"; - const INT32 n = numcontrollers; + const INT32 numcontrollers = I_NumControllers(); INT32 i = 0; INT32 j; @@ -8452,24 +8454,24 @@ INT32 MR_SetupJoystickMenu(INT32 arg) for (i = 1; i <= MAXGAMEPADS; i++) { - if (i <= n && (I_GetJoyName(i)) != NULL) - strncpy(joystickInfo[i], I_GetJoyName(i), 28); + if (i <= numcontrollers && (I_GetControllerName(i)) != NULL) + strncpy(joystickInfo[i], I_GetControllerName(i), 28); else strcpy(joystickInfo[i], joyNA); #ifdef JOYSTICK_HOTPLUG - // We use cv_usejoystick.string as the USER-SET var - // and cv_usejoystick.value as the INTERNAL var + // We use cv_usecontroller.string as the USER-SET var + // and cv_usecontroller.value as the INTERNAL var // - // In practice, if cv_usejoystick.string == 0, this overrides - // cv_usejoystick.value and always disables + // In practice, if cv_usecontroller.string == 0, this overrides + // cv_usecontroller.value and always disables // - // Update cv_usejoystick.string here so that the user can + // Update cv_usecontroller.string here so that the user can // properly change this value. for (j = 0; j < MAXSPLITSCREENPLAYERS; j++) { - if (i == cv_usejoystick[j].value) - CV_SetValue(&cv_usejoystick[j], i); + if (i == cv_usecontroller[j].value) + CV_SetValue(&cv_usecontroller[j], i); } #endif } @@ -8483,29 +8485,29 @@ INT32 MR_AssignJoystick(INT32 arg) #ifdef JOYSTICK_HOTPLUG INT32 oldchoice, oldstringchoice; - INT32 numjoys = numcontrollers; + const INT32 numcontrollers = I_NumControllers(); - oldchoice = oldstringchoice = atoi(cv_usejoystick[p].string) > numjoys ? atoi(cv_usejoystick[p].string) : cv_usejoystick[p].value; - CV_SetValue(&cv_usejoystick[p], arg); + oldchoice = oldstringchoice = atoi(cv_usecontroller[p].string) > numcontrollers ? atoi(cv_usecontroller[p].string) : cv_usecontroller[p].value; + CV_SetValue(&cv_usecontroller[p], arg); - // Just in case last-minute changes were made to cv_usejoystick.value, + // Just in case last-minute changes were made to cv_usecontroller.value, // update the string too - // But don't do this if we're intentionally setting higher than numjoys - if (arg <= numjoys) + // But don't do this if we're intentionally setting higher than numcontrollers + if (arg <= numcontrollers) { - CV_SetValue(&cv_usejoystick[p], cv_usejoystick[p].value); + CV_SetValue(&cv_usecontroller[p], cv_usecontroller[p].value); // reset this so the comparison is valid - if (oldchoice > numjoys) - oldchoice = cv_usejoystick[p].value; + if (oldchoice > numcontrollers) + oldchoice = cv_usecontroller[p].value; if (oldchoice != arg) { - if (arg && oldstringchoice > numjoys) // if we did not select "None", we likely selected a used device - CV_SetValue(&cv_usejoystick[p], (oldstringchoice > numjoys ? oldstringchoice : oldchoice)); + if (arg && oldstringchoice > numcontrollers) // if we did not select "None", we likely selected a used device + CV_SetValue(&cv_usecontroller[p], (oldstringchoice > numcontrollers ? oldstringchoice : oldchoice)); if (oldstringchoice == - (atoi(cv_usejoystick[p].string) > numjoys ? atoi(cv_usejoystick[p].string) : cv_usejoystick[p].value)) + (atoi(cv_usecontroller[p].string) > numcontrollers ? atoi(cv_usecontroller[p].string) : cv_usecontroller[p].value)) M_StartMessage("This joystick is used by another\n" "player. Reset the joystick\n" "for that player first.\n\n" @@ -8513,7 +8515,7 @@ INT32 MR_AssignJoystick(INT32 arg) } } #else - CV_SetValue(&cv_usejoystick[p], arg); + CV_SetValue(&cv_usecontroller[p], arg); #endif return true; } @@ -8540,8 +8542,8 @@ INT32 MR_SetupControlsMenu(INT32 arg) M_SetItemCvar(MN_OP_CHANGECONTROLS, "DEAZS", &cv_deadzonestyle[arg]); M_SetItemCvar(MN_OP_CHANGECONTROLS, "TURNSMOOTHING", &cv_turnsmooth[arg]); M_SetItemCvar(MN_OP_CHANGECONTROLS, "LITESTEER", &cv_litesteer[arg]); - M_SetItemCvar(MN_OP_CHANGECONTROLS, "LEDCOLOR", &cv_gamepadled[arg]); - M_SetItemCvar(MN_OP_CHANGECONTROLS, "RUMBLE", &cv_rumble[arg]); + M_SetItemCvar(MN_OP_CHANGECONTROLS, "LEDCOLOR", &cv_controllerled[arg]); + M_SetItemCvar(MN_OP_CHANGECONTROLS, "RUMBLE", &cv_controllerrumble[arg]); M_SetItemCvar(MN_OP_CHANGECONTROLS, "RUMBLESTR", &cv_rumblestrength[arg]); M_SetItemVisible(MN_OP_CHANGECONTROLS, "TALK", player1); // Chat @@ -8683,7 +8685,7 @@ static void M_ResetControlsResponse(INT32 ch) G_ResetControls(p); // Setup gamepad option defaults (yucky) - CV_StealthSet(&cv_usejoystick[p], cv_usejoystick[p].defaultvalue); + CV_StealthSet(&cv_usecontroller[p], cv_usecontroller[p].defaultvalue); S_StartSound(NULL, sfx_s224); } diff --git a/src/p_inter.c b/src/p_inter.c index 97b0add7a..7844122f6 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -47,62 +47,6 @@ #define CTFTEAMCODE(pl) pl->ctfteam ? (pl->ctfteam == 1 ? "\x85" : "\x84") : "" #define CTFTEAMENDCODE(pl) pl->ctfteam ? "\x80" : "" -void P_ForceFeed(const player_t *player, INT32 attack, INT32 fade, tic_t duration, INT32 period) -{ - BasicFF_t Basicfeed; - if (!player) - return; - Basicfeed.Duration = (UINT32)(duration * (100L/TICRATE)); - Basicfeed.ForceX = Basicfeed.ForceY = 1; - Basicfeed.Gain = 25000; - Basicfeed.Magnitude = period*10; - Basicfeed.player = player; - /// \todo test FFB - P_RampConstant(&Basicfeed, attack, fade); -} - -void P_ForceConstant(const BasicFF_t *FFInfo) -{ - JoyFF_t ConstantQuake; - if (!FFInfo || !FFInfo->player) - return; - ConstantQuake.ForceX = FFInfo->ForceX; - ConstantQuake.ForceY = FFInfo->ForceY; - ConstantQuake.Duration = FFInfo->Duration; - ConstantQuake.Gain = FFInfo->Gain; - ConstantQuake.Magnitude = FFInfo->Magnitude; - if (FFInfo->player == &players[consoleplayer]) - I_Tactile(ConstantForce, &ConstantQuake); - else if (splitscreen && FFInfo->player == &players[g_localplayers[1]]) - I_Tactile2(ConstantForce, &ConstantQuake); - else if (splitscreen > 1 && FFInfo->player == &players[g_localplayers[2]]) - I_Tactile3(ConstantForce, &ConstantQuake); - else if (splitscreen > 2 && FFInfo->player == &players[g_localplayers[3]]) - I_Tactile4(ConstantForce, &ConstantQuake); -} -void P_RampConstant(const BasicFF_t *FFInfo, INT32 Start, INT32 End) -{ - JoyFF_t RampQuake; - if (!FFInfo || !FFInfo->player) - return; - RampQuake.ForceX = FFInfo->ForceX; - RampQuake.ForceY = FFInfo->ForceY; - RampQuake.Duration = FFInfo->Duration; - RampQuake.Gain = FFInfo->Gain; - RampQuake.Magnitude = FFInfo->Magnitude; - RampQuake.Start = Start; - RampQuake.End = End; - if (FFInfo->player == &players[consoleplayer]) - I_Tactile(ConstantForce, &RampQuake); - else if (splitscreen && FFInfo->player == &players[g_localplayers[1]]) - I_Tactile2(ConstantForce, &RampQuake); - else if (splitscreen > 1 && FFInfo->player == &players[g_localplayers[2]]) - I_Tactile3(ConstantForce, &RampQuake); - else if (splitscreen > 2 && FFInfo->player == &players[g_localplayers[3]]) - I_Tactile4(ConstantForce, &RampQuake); -} - - // // GET STUFF // diff --git a/src/p_local.h b/src/p_local.h index 6db4dfb3d..063be6a9c 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -570,17 +570,6 @@ extern struct minimapinfo // // P_INTER // -struct BasicFF_t -{ - INT32 ForceX; ///< The X of the Force's Vel - INT32 ForceY; ///< The Y of the Force's Vel - const player_t *player; ///< Player of Rumble - //All - UINT32 Duration; ///< The total duration of the effect, in microseconds - INT32 Gain; ///< /The gain to be applied to the effect, in the range from 0 through 10,000. - //All, CONSTANTFORCE �10,000 to 10,000 - INT32 Magnitude; ///< Magnitude of the effect, in the range from 0 through 10,000. -}; /* Damage/death types, for P_DamageMobj and related */ //// Damage types @@ -604,9 +593,6 @@ struct BasicFF_t #define DMG_DEATHMASK DMG_INSTAKILL // if bit 7 is set, this is a death type instead of a damage type #define DMG_TYPEMASK 0x0F // Get type without any flags -void P_ForceFeed(const player_t *player, INT32 attack, INT32 fade, tic_t duration, INT32 period); -void P_ForceConstant(const BasicFF_t *FFInfo); -void P_RampConstant(const BasicFF_t *FFInfo, INT32 Start, INT32 End); void P_SpecialStageDamage(player_t *player, mobj_t *inflictor, mobj_t *source); boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage, UINT8 damagetype); void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damagetype); diff --git a/src/p_setup.c b/src/p_setup.c index 5fa9a1978..991ddb65c 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -9118,7 +9118,7 @@ boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate) G_AddMapToBuffer(gamemap-1); - G_ResetDeviceLED(); + G_ResetControllerLED(); P_MapEnd(); // g_tm.thing is no longer needed from this point onwards diff --git a/src/p_tick.c b/src/p_tick.c index f35600ca8..929615fa2 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -796,7 +796,7 @@ void P_Ticker(boolean run) // Apply rumble to local players if (!demo.playback) { - G_DeviceRumbleTick(); + G_ControllerRumbleTick(); } // run all the bot tickers diff --git a/src/p_user.c b/src/p_user.c index 6e39016f3..63d88d6e6 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -34,7 +34,7 @@ #include "m_random.h" #include "m_misc.h" #include "i_video.h" -#include "i_joy.h" +#include "i_gamepad.h" #include "p_slopes.h" #include "p_spec.h" #include "r_splats.h" diff --git a/src/sdl/CMakeLists.txt b/src/sdl/CMakeLists.txt index 5f1c2f1b4..a5d9ea7b4 100644 --- a/src/sdl/CMakeLists.txt +++ b/src/sdl/CMakeLists.txt @@ -4,6 +4,7 @@ target_sources(BLANKART PRIVATE ogl_sdl.c i_threads.c i_net.c + i_gamepad.c i_system.cpp i_main.c i_video.cpp diff --git a/src/sdl/i_gamepad.c b/src/sdl/i_gamepad.c new file mode 100644 index 000000000..1ba66224a --- /dev/null +++ b/src/sdl/i_gamepad.c @@ -0,0 +1,406 @@ +// Emacs style mode select -*- C++ -*- +// BLANKART +//----------------------------------------------------------------------------- +// +// Copyright (C) 1993-1996 by id Software, Inc. +// Portions Copyright (C) 1998-2000 by DooM Legacy Team. +// Copyright (C) 2014-2020 by Sonic Team Junior. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +//----------------------------------------------------------------------------- +/// \file i_gamepad.c +/// \brief Blankart Gamepad Handling + +#ifdef HAVE_SDL + +#include +#include +#include +#include + +#include "../doomdef.h" +#include "../d_main.h" +#include "../d_netcmd.h" +#include "../m_argv.h" +#include "../i_gamepad.h" +#include "../i_system.h" + +#include "sdlmain.h" + +// information on the Controller a player uses +controllerinfo_t controllerInfo[MAXSPLITSCREENPLAYERS] = {}; +static INT32 numcontrollers = 0; + +// +// I_ControllerReset +// +static void I_ControllerReset(controllerinfo_t *controller) +{ + if (controller->dev) + { + SDL_CloseGamepad(controller->dev); + } + + controller->dev = NULL; + //controller->joydev = NULL; + controller->id = -1; + //controller->name = NULL; + controller->hasrumble = false; + controller->hasrgbled = false; +} + +// +// I_ShutdownController +// +void I_ShutdownController(UINT8 index) +{ + INT32 i; + event_t event; + + event.device = index+1; + 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 < JOYAXISES; i++) + { + event.data1 = i; + D_PostEvent(&event); + } + + I_ControllerReset(&controllerInfo[index]); +} + +void I_ShutdownControllerSystem(void) +{ + UINT8 i; + + // 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_ShutdownController(i); + + // reset this just in case + numcontrollers = 0; + + if (SDL_WasInit(SDL_INIT_GAMEPAD) == SDL_INIT_GAMEPAD) + { + CONS_Printf("Shutting down gamecontroller system\n"); + SDL_QuitSubSystem(SDL_INIT_GAMEPAD); + I_OutputMsg("I_Joystick: SDL's Game Controller system has been shutdown\n"); + } + + if (SDL_WasInit(SDL_INIT_JOYSTICK) == SDL_INIT_JOYSTICK) + { + CONS_Printf("Shutting down joy system\n"); + SDL_QuitSubSystem(SDL_INIT_JOYSTICK); + I_OutputMsg("I_Joystick: SDL's Joystick system has been shutdown\n"); + } +} + +// +// I_InitController +// +void I_InitController(UINT8 playernum) +{ + SDL_Gamepad *newcontroller = NULL; + SDL_JoystickID *controller_list = NULL; + int num_joy = 0; + + if (M_CheckParm("-nojoy")) + return; + + { + char dbpath[1024]; + sprintf(dbpath, "%s" PATHSEP "gamecontrollerdb.txt", srb2path); + SDL_AddGamepadMappingsFromFile(dbpath); + } + + { + char dbpath[1024]; + sprintf(dbpath, "%s" PATHSEP "gamecontrollerdb_user.txt", srb2home); + SDL_AddGamepadMappingsFromFile(dbpath); + } + + if (M_CheckParm("-noxinput")) + SDL_SetHintWithPriority("SDL_XINPUT_ENABLED", "0", SDL_HINT_OVERRIDE); + + if (M_CheckParm("-nohidapi")) + SDL_SetHintWithPriority("SDL_JOYSTICK_HIDAPI", "0", SDL_HINT_OVERRIDE); + + if (M_CheckParm("-nolibusb")) + SDL_SetHintWithPriority("SDL_HIDAPI_LIBUSB", "0", SDL_HINT_OVERRIDE); + + if (SDL_WasInit(SDL_INIT_JOYSTICK) == 0) + { + CONS_Printf("I_InitController()...\n"); + + if (!SDL_InitSubSystem(SDL_INIT_JOYSTICK)) + { + CONS_Printf(M_GetText("Couldn't initialize joystick: %s\n"), SDL_GetError()); + return; + } + } + + if (SDL_WasInit(SDL_INIT_GAMEPAD) == 0) + { + if (!SDL_InitSubSystem(SDL_INIT_GAMEPAD)) + { + CONS_Printf(M_GetText("Couldn't initialize gamepads: %s\n"), SDL_GetError()); + return; + } + } + + I_ControllerReset(&controllerInfo[playernum]); + + // dont need to do any of this if we dont want to use a controller + if (cv_usecontroller[playernum].value <= 0) + return; + + controller_list = SDL_GetGamepads(&num_joy); + + if (!controller_list) + { + CONS_Debug(DBG_GAMELOGIC, "Failed to fetch Controller list: %s\n", SDL_GetError()); + return; + } + + if (cv_usecontroller[playernum].value > num_joy) + { + SDL_free(controller_list); + return; + } + + SDL_JoystickID joystick_id = controller_list[cv_usecontroller[playernum].value - 1]; + if (joystick_id == 0) + { + CONS_Debug(DBG_GAMELOGIC, "Failed to get Controller instance id for Player %d: %s\n", playernum+1, SDL_GetError()); + SDL_free(controller_list); + return; + } + + // dont need this anymore + SDL_free(controller_list); + + newcontroller = SDL_OpenGamepad(joystick_id); + + if (!newcontroller) + { + CONS_Debug(DBG_GAMELOGIC, "Failed to open Controller with id %d for Player %d: %s\n", joystick_id, playernum+1, SDL_GetError()); + return; + } + + // fill in our controller info + controllerinfo_t *controller = &controllerInfo[playernum]; + controller->dev = newcontroller; + //controller->joydev = SDL_GetGamepadJoystick(newcontroller); + controller->id = joystick_id; + //controller->name = SDL_GetGamepadNameForID(joystick_id); + SDL_PropertiesID controllerproperties = SDL_GetGamepadProperties(newcontroller); + controller->hasrumble = SDL_GetBooleanProperty(controllerproperties, SDL_PROP_GAMEPAD_CAP_RUMBLE_BOOLEAN, false); + controller->hasrgbled = SDL_GetBooleanProperty(controllerproperties, SDL_PROP_GAMEPAD_CAP_RGB_LED_BOOLEAN, false); +} + +void I_InitController1(void) +{ + I_InitController(0); +} + +void I_InitController2(void) +{ + I_InitController(1); +} + +void I_InitController3(void) +{ + I_InitController(2); +} + +void I_InitController4(void) +{ + I_InitController(3); +} + + +// +// I_ControllerScale +// +void I_ControllerScale(void) +{ + Joystick[0].bGamepadStyle = cv_controllerscale[0].value == 0; + controllerInfo[0].scale = Joystick[0].bGamepadStyle ? 1 : cv_controllerscale[0].value; +} + +void I_ControllerScale2(void) +{ + Joystick[1].bGamepadStyle = cv_controllerscale[1].value == 0; + controllerInfo[1].scale = Joystick[1].bGamepadStyle ? 1 : cv_controllerscale[1].value; +} + +void I_ControllerScale3(void) +{ + Joystick[2].bGamepadStyle = cv_controllerscale[2].value == 0; + controllerInfo[2].scale = Joystick[2].bGamepadStyle ? 1 : cv_controllerscale[2].value; +} + +void I_ControllerScale4(void) +{ + Joystick[3].bGamepadStyle = cv_controllerscale[3].value == 0; + controllerInfo[3].scale = Joystick[3].bGamepadStyle ? 1 : cv_controllerscale[3].value; +} + +static SDL_JoystickID *controllerlist = NULL; +void I_UpdateControllerList(void) +{ + int num_joy = 0; + + if (controllerlist) + SDL_free(controllerlist); + controllerlist = SDL_GetGamepads(&num_joy); + + if (!controllerlist) + { + CONS_Debug(DBG_GAMELOGIC, "Failed to fetch Controller list: %s\n", SDL_GetError()); + numcontrollers = 0; + return; + } + + numcontrollers = num_joy; +} + +// +// I_GetControllerID +// Cheat to get the device index for a game controller handle +// +INT32 I_GetControllerID(SDL_Gamepad *dev) +{ + if (dev) + { + return (INT32)SDL_GetGamepadID(dev); + } + + return -1; +} + +INT32 I_GetControllerSlotfromID(INT32 id) +{ + if (!controllerlist) + { + CONS_Debug(DBG_GAMELOGIC, "Failed to fetch Controller list: %s\n", SDL_GetError()); + return -1; + } + + for (int i = 0; i < numcontrollers; i++) + { + if (controllerlist[i] == (SDL_JoystickID)id) + { + return i+1; + } + } + + return -1; +} + +// +// I_GetControllerIDForPlayer +// Cheat to get the device index for a specified player +// +INT32 I_GetControllerIDForPlayer(UINT8 pnum) +{ + if (controllerInfo[pnum].dev) + { + return (INT32)controllerInfo[pnum].id; + } + + return -1; +} + +// +// I_NumControllers +// Updates the number of connected controllers +// +INT32 I_NumControllers(void) +{ + return numcontrollers; +} + +// +// I_GetControllerName +// joystick name is straight from the driver +// +const char *I_GetControllerName(INT32 joyid) +{ + if (SDL_WasInit(SDL_INIT_GAMEPAD) == SDL_INIT_GAMEPAD) + { + if (joyid <= 0) + return NULL; + + if (!controllerlist) + return NULL; + + SDL_JoystickID joystick_id = controllerlist[joyid - 1]; + + return SDL_GetGamepadNameForID(joystick_id); + } + + return NULL; +} + +// +// Controller Rumble and RGB LED stuff +// + +boolean I_ControllerSupportsRumble(INT32 playernum) +{ + return (controllerInfo[playernum].dev && controllerInfo[playernum].hasrumble); +} + +boolean I_ControllerSupportsIndicatorColor(INT32 playernum) +{ + return (controllerInfo[playernum].dev && controllerInfo[playernum].hasrgbled); +} + +void I_ControllerRumble(INT32 playernum, UINT16 low_strength, UINT16 high_strength, UINT32 duration) +{ + SDL_Gamepad *controller = controllerInfo[playernum].dev; + + if (controller == NULL || !I_ControllerSupportsRumble(playernum)) + { + return; + } + + SDL_RumbleGamepad(controller, low_strength, high_strength, duration); +} + +void I_SetControllerIndicatorColor(INT32 playernum, UINT8 red, UINT8 green, UINT8 blue) +{ + SDL_Gamepad *controller = controllerInfo[playernum].dev; + + if (controller == NULL || !I_ControllerSupportsIndicatorColor(playernum)) + { + return; + } + + SDL_SetGamepadLED(controller, red, green, blue); +} + +#endif diff --git a/src/sdl/i_system.cpp b/src/sdl/i_system.cpp index 72e9da333..ad18d841f 100644 --- a/src/sdl/i_system.cpp +++ b/src/sdl/i_system.cpp @@ -23,8 +23,6 @@ /// \file /// \brief SRB2 system stuff for SDL -#include -#include #include #ifdef CMAKECONFIG @@ -195,7 +193,7 @@ static char returnWadPath[256]; #include "endtxt.h" #include "sdlmain.h" -#include "../i_joy.h" +#include "../i_gamepad.h" #include "../m_argv.h" @@ -218,34 +216,6 @@ static char returnWadPath[256]; static std::thread::id g_main_thread_id; -/** \brief The JoyReset function - - \param JoySet Joystick info to reset - - \return void -*/ -static void JoyReset(SDLJoyInfo_t *JoySet) -{ - if (JoySet->dev) - { - SDL_CloseGamepad(JoySet->dev); - } - JoySet->dev = NULL; - JoySet->id = -1; - JoySet->oldjoy = -1; - //JoySet->scale -} - -/** \brief First joystick up and running -*/ -static INT32 joystick_started[MAXSPLITSCREENPLAYERS] = {0,0,0,0}; - -/** \brief SDL info about joystick 1 -*/ -SDLJoyInfo_t JoyInfo[MAXSPLITSCREENPLAYERS]; -INT32 numcontrollers = 0; -SDL_Gamepad *ExJoystick[MAXGAMEPADS]; - bool consolevent = false; bool framebuffer = false; @@ -1037,480 +1007,6 @@ INT32 I_GetKey (void) return rc; } -// -// I_JoyScale -// -void I_JoyScale(void) -{ - Joystick[0].bGamepadStyle = cv_joyscale[0].value==0; - JoyInfo[0].scale = Joystick[0].bGamepadStyle?1:cv_joyscale[0].value; -} - -void I_JoyScale2(void) -{ - Joystick[1].bGamepadStyle = cv_joyscale[1].value==0; - JoyInfo[1].scale = Joystick[1].bGamepadStyle?1:cv_joyscale[1].value; -} - -void I_JoyScale3(void) -{ - Joystick[2].bGamepadStyle = cv_joyscale[2].value==0; - JoyInfo[2].scale = Joystick[2].bGamepadStyle?1:cv_joyscale[2].value; -} - -void I_JoyScale4(void) -{ - Joystick[3].bGamepadStyle = cv_joyscale[3].value==0; - JoyInfo[3].scale = Joystick[3].bGamepadStyle?1:cv_joyscale[1].value; -} - -// Cheat to get the device index for a game controller handle -INT32 I_GetJoystickID(SDL_Gamepad *dev) -{ - if (dev) - { - return SDL_GetGamepadID(dev); - } - - return -1; -} - -INT32 I_GetJoystickIDForPlayer(UINT8 pnum) -{ - if (JoyInfo[pnum].dev) - { - return SDL_GetGamepadID(JoyInfo[pnum].dev); - } - - return -1; -} - -void I_UpdateJoystickDeviceIndex(UINT8 player) -{ - /////////////////////////////////////////////// - // update this joystick's device index (wow) // - /////////////////////////////////////////////// - - if (JoyInfo[player].dev) - { - cv_usejoystick[player].value = JoyInfo[player].id + 1; - } - 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) - { - // We DID make it through the whole loop, so we can use this one! - cv_usejoystick[player].value = 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; - } - } -} - -// 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_GetJoystickID(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 < JOYAXISES; 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 joyID) -{ - SDL_Gamepad *newdev = NULL; - SDL_JoystickID *joystick_list = 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_GAMEPAD) == 0) - { - CONS_Printf(M_GetText("Game Controller subsystem not started\n")); - return -1; - } - - if (joyID <= 0) - return -1; - - joystick_list = SDL_GetGamepads(&num_joy); - - if (!joystick_list || num_joy == 0) - { - CONS_Printf("%s", M_GetText("Found no joysticks on this system\n")); - return -1; - } - - if (joyID > num_joy) - { - SDL_free(joystick_list); - return -1; - } - - SDL_JoystickID joystick_id = joystick_list[joyID - 1]; - SDL_free(joystick_list); - - newdev = SDL_OpenGamepad(joystick_id); - - // 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_GamepadConnected(JoyInfo[playerIndex].dev))) // we failed, but already have a working device - { - return SDL_GAMEPAD_AXIS_COUNT; - } - - // 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; - JoyInfo[playerIndex].id = joystick_id;; - - 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_GetGamepadName(JoyInfo[playerIndex].dev)); - - JoyInfo[playerIndex].axises = SDL_GAMEPAD_AXIS_COUNT; - JoyInfo[playerIndex].buttons = SDL_GAMEPAD_BUTTON_COUNT; - JoyInfo[playerIndex].hats = 1; - JoyInfo[playerIndex].balls = 0; - - //JoyInfo[playerIndex].bGamepadStyle = fasticmp(SDL_JoystickName(JoyInfo[playerIndex].dev), "pad"); - - return JoyInfo[playerIndex].axises; - } -} - -// -// I_InitJoystick -// -void I_InitJoystick(UINT8 index) -{ - SDL_Gamepad *newcontroller = NULL; - SDL_JoystickID *joystick_list = NULL; - int num_joy = 0; - UINT8 i; - - //I_ShutdownJoystick(); - //SDL_SetHintWithPriority("SDL_XINPUT_ENABLED", "0", SDL_HINT_OVERRIDE); - if (M_CheckParm("-nojoy")) - return; - - { - char dbpath[1024]; - sprintf(dbpath, "%s" PATHSEP "gamecontrollerdb.txt", srb2path); - SDL_AddGamepadMappingsFromFile(dbpath); - } - - { - char dbpath[1024]; - sprintf(dbpath, "%s" PATHSEP "gamecontrollerdb_user.txt", srb2home); - SDL_AddGamepadMappingsFromFile(dbpath); - } - - if (M_CheckParm("-noxinput")) - SDL_SetHintWithPriority("SDL_XINPUT_ENABLED", "0", SDL_HINT_OVERRIDE); - - if (M_CheckParm("-nohidapi")) - SDL_SetHintWithPriority("SDL_JOYSTICK_HIDAPI", "0", SDL_HINT_OVERRIDE); - - if (M_CheckParm("-nolibusb")) - SDL_SetHintWithPriority("SDL_HIDAPI_LIBUSB", "0", SDL_HINT_OVERRIDE); - - if (SDL_WasInit(SDL_INIT_JOYSTICK) == 0) - { - CONS_Printf("I_InitJoystick()...\n"); - - if (!SDL_InitSubSystem(SDL_INIT_JOYSTICK)) - { - CONS_Printf(M_GetText("Couldn't initialize joystick: %s\n"), SDL_GetError()); - return; - } - } - - if (SDL_WasInit(SDL_INIT_GAMEPAD) == 0) - { - if (!SDL_InitSubSystem(SDL_INIT_GAMEPAD)) - { - CONS_Printf(M_GetText("Couldn't initialize gamepads: %s\n"), SDL_GetError()); - return; - } - } - - joystick_list = SDL_GetGamepads(&num_joy); - - if (joystick_list && cv_usejoystick[index].value > 0 && cv_usejoystick[index].value <= num_joy) - { - SDL_JoystickID joystick_id = joystick_list[cv_usejoystick[index].value - 1]; - newcontroller = SDL_OpenGamepad(joystick_id); - } - - if (joystick_list) - SDL_free(joystick_list); - - for (i = 0; i < MAXSPLITSCREENPLAYERS; i++) - { - if (i == index) - continue; - - if (JoyInfo[i].dev == newcontroller) - break; - } - - JoyInfo[index].id = I_GetJoystickID(JoyInfo[index].dev); - - if (newcontroller && i < MAXSPLITSCREENPLAYERS) // don't override an active device - { - cv_usejoystick[index].value = JoyInfo[index].id + 1; - } - 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 = JoyInfo[index].id + 1; - joystick_started[index] = 1; - } - else - { - if (JoyInfo[index].oldjoy) - I_ShutdownJoystick(index); - cv_usejoystick[index].value = 0; - 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 - SDL_CloseGamepad(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) -{ - UINT8 i; - - // 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_GAMEPAD) == SDL_INIT_GAMEPAD) - { - CONS_Printf("Shutting down gamecontroller system\n"); - SDL_QuitSubSystem(SDL_INIT_GAMEPAD); - I_OutputMsg("I_Joystick: SDL's Game Controller system has been shutdown\n"); - } - - if (SDL_WasInit(SDL_INIT_JOYSTICK) == SDL_INIT_JOYSTICK) - { - CONS_Printf("Shutting down joy system\n"); - SDL_QuitSubSystem(SDL_INIT_JOYSTICK); - I_OutputMsg("I_Joystick: SDL's Joystick system has been shutdown\n"); - } -} - -INT32 I_NumJoys(void) -{ - INT32 num_joy = 0; - if (SDL_WasInit(SDL_INIT_GAMEPAD) == SDL_INIT_GAMEPAD) - SDL_GetGamepads(&num_joy); - return num_joy; -} - -static char joyname[255]; // joystick name is straight from the driver - -const char *I_GetJoyName(INT32 joyid) -{ - const char *tempname = NULL; - SDL_JoystickID *joystick_list = NULL; - int num_joy = 0; - - joyname[0] = 0; - - if (SDL_WasInit(SDL_INIT_GAMEPAD) == SDL_INIT_GAMEPAD) - { - if (joyid <= 0) - return joyname; - - joystick_list = SDL_GetGamepads(&num_joy); - - if (!joystick_list || joyid > num_joy) - { - if (joystick_list) - SDL_free(joystick_list); - return joyname; - } - - SDL_JoystickID joystick_id = joystick_list[joyid - 1]; - SDL_free(joystick_list); - - tempname = SDL_GetGamepadNameForID(joystick_id); - if (tempname) - { - strncpy(joyname, tempname, 254); - joyname[254] = 0; - } - } - return joyname; -} - -void I_GamepadRumble(INT32 playernum, UINT16 low_strength, UINT16 high_strength, UINT32 duration) -{ -#if !(SDL_VERSION_ATLEAST(2,0,14)) - (void)playernum; - (void)low_strength; - (void)high_strength; - (void)duration; -#else - SDL_Gamepad *controller = JoyInfo[playernum].dev; - - if (controller == NULL) - { - return; - } - - SDL_RumbleGamepad(controller, low_strength, high_strength, duration); -#endif -} - -void I_SetGamepadIndicatorColor(INT32 playernum, UINT8 red, UINT8 green, UINT8 blue) -{ -#if !(SDL_VERSION_ATLEAST(2,0,14)) - (void)playernum; - (void)red; - (void)green; - (void)blue; -#else - SDL_Gamepad *controller = JoyInfo[playernum].dev; - - if (controller == NULL) - { - return; - } - - SDL_SetGamepadLED(controller, red, green, blue); -#endif -} - #ifndef NOMUMBLE #ifdef HAVE_MUMBLE // Best Mumble positional audio settings: @@ -1639,37 +1135,6 @@ void I_UpdateMumble(const mobj_t *mobj, const listener_t listener) #undef WINMUMBLE #endif // NOMUMBLE -// -// I_Tactile -// -void I_Tactile(FFType pFFType, const JoyFF_t *FFEffect) -{ - // UNUSED. - (void)pFFType; - (void)FFEffect; -} - -void I_Tactile2(FFType pFFType, const JoyFF_t *FFEffect) -{ - // UNUSED. - (void)pFFType; - (void)FFEffect; -} - -void I_Tactile3(FFType pFFType, const JoyFF_t *FFEffect) -{ - // UNUSED. - (void)pFFType; - (void)FFEffect; -} - -void I_Tactile4(FFType pFFType, const JoyFF_t *FFEffect) -{ - // UNUSED. - (void)pFFType; - (void)FFEffect; -} - static ticcmd_t emptycmd[MAXSPLITSCREENPLAYERS]; /** \brief empty ticcmd for player 1 @@ -1970,7 +1435,7 @@ void I_Quit(void) I_ShutdownSound(); // use this for 1.28 19990220 by Kin I_ShutdownGraphics(); - I_ShutdownInput(); + I_ShutdownControllerSystem(); I_ShutdownSystem(); SDL_Quit(); /* if option -noendtxt is set, don't print the text */ @@ -2036,7 +1501,7 @@ FUNCIERROR void ATTRNORETURN I_Error(const char *error, ...) if (errorcount == 4) I_ShutdownGraphics(); if (errorcount == 5) - I_ShutdownInput(); + I_ShutdownControllerSystem(); if (errorcount == 6) I_ShutdownSystem(); if (errorcount == 7) @@ -2096,7 +1561,7 @@ FUNCIERROR void ATTRNORETURN I_Error(const char *error, ...) I_ShutdownMusic(); I_ShutdownGraphics(); - I_ShutdownInput(); + I_ShutdownControllerSystem(); I_ShowErrorMessageBox(buffer, false); diff --git a/src/sdl/i_video.cpp b/src/sdl/i_video.cpp index 8608f5ed7..62046a7fa 100644 --- a/src/sdl/i_video.cpp +++ b/src/sdl/i_video.cpp @@ -58,7 +58,7 @@ #include "../d_main.h" #include "../s_sound.h" #include "../i_sound.h" // midi pause/unpause -#include "../i_joy.h" +#include "../i_gamepad.h" #include "../st_stuff.h" #include "../hu_stuff.h" #include "../g_game.h" @@ -601,11 +601,6 @@ static void Impl_SetFocused(boolean focused) } } -static inline void SDLJoyRemap(event_t *event) -{ - (void)event; -} - static INT32 SDLJoyAxis(const Sint16 axis, UINT8 pid) { // -32768 to 32767 @@ -623,12 +618,7 @@ static INT32 SDLJoyAxis(const Sint16 axis, UINT8 pid) } else { - raxis = (abs(JoyInfo[pid].scale) > 1) ? ((raxis / JoyInfo[pid].scale) * JoyInfo[pid].scale) : raxis; - -#ifdef SDL_JDEADZONE - if (-SDL_JDEADZONE <= raxis && raxis <= SDL_JDEADZONE) - raxis = 0; -#endif + raxis = (abs(controllerInfo[pid].scale) > 1) ? ((raxis / controllerInfo[pid].scale) * controllerInfo[pid].scale) : raxis; } return raxis; @@ -844,6 +834,61 @@ static void Impl_HandleMouseWheelEvent(SDL_MouseWheelEvent evt) } } +// ill put this here if blan wants this +// allows controller dpads to scroll through menus +/* +static UINT8 hatrepeattimer[MAXSPLITSCREENPLAYERS]; +#define HATREPEATDELAY 19 + +void I_HandleControllerHatRepeat(void) +{ + // why bother if theres no controllers? + if (numcontrollers == 0) + return; + + event_t event = {ev_keydown, 0, 0, 0}; + + static const SDL_GameControllerButton hatbutt[4] = + { + SDL_CONTROLLER_BUTTON_DPAD_UP, + SDL_CONTROLLER_BUTTON_DPAD_DOWN, + SDL_CONTROLLER_BUTTON_DPAD_LEFT, + SDL_CONTROLLER_BUTTON_DPAD_RIGHT + }; + + for (int i = 0; i < MAXSPLITSCREENPLAYERS; i++) + { + if (!cv_usejoystick[i].value) + continue; + + SDL_GameController *controller = JoyInfo[i].dev; + + if (!controller) + continue; + + for (UINT8 h = 0; h < JOYHATS; h++) + { + if (SDL_GameControllerGetButton(controller, hatbutt[h])) + { + if (hatrepeattimer[i] < HATREPEATDELAY) + { + hatrepeattimer[i]++; + } + else if (hatrepeattimer[i] == HATREPEATDELAY) + { + event.data1 = KEY_HAT1 + (i * JOYHATS) + h; + D_PostEvent(&event); + } + + return; + } + } + + hatrepeattimer[i] = 0; + } +} +*/ + static void Impl_HandleControllerAxisEvent(SDL_GamepadAxisEvent evt) { event_t event; @@ -884,7 +929,7 @@ static void Impl_HandleControllerAxisEvent(SDL_GamepadAxisEvent evt) } //value - event.data2 = SDLJoyAxis(evt.value, evt.which); + event.data2 = SDLJoyAxis(evt.value, G_GetDevicePlayer(event.device)); D_PostEvent(&event); } @@ -924,8 +969,6 @@ static void Impl_HandleControllerButtonEvent(SDL_GamepadButtonEvent evt, Uint32 return; } - SDLJoyRemap(&event); - if (event.type != ev_console) { D_PostEvent(&event); @@ -937,79 +980,25 @@ static void Impl_HandleControllerAddEvent(SDL_Event evt) UINT8 i; SDL_JoystickID joystick_id = evt.gdevice.which; - SDL_Gamepad *newcontroller = SDL_OpenGamepad(joystick_id); - - CONS_Debug(DBG_GAMELOGIC, "Controller device index %d added\n", joystick_id + 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 (joystick_id == 0) { - if (newcontroller && (!JoyInfo[i].dev || !SDL_GamepadConnected(JoyInfo[i].dev))) - { - UINT8 j; - - for (j = 0; j < MAXSPLITSCREENPLAYERS; j++) - { - if (i == j) - continue; - - if (JoyInfo[j].dev == newcontroller) - break; - } - - if (j == MAXSPLITSCREENPLAYERS) - { - // ensures we aren't overriding a currently active device - cv_usejoystick[i].value = joystick_id + 1; - I_UpdateJoystickDeviceIndices(0); - } - } - } - - // Was cv_usejoystick disabled in settings? - for (i = 0; i < MAXSPLITSCREENPLAYERS; i++) - { - if (fastcmp(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); - G_SetPlayerGamepadIndicatorColor(i, SKINCOLOR_NONE); // gotta update the controller led again on reconnect + CONS_Debug(DBG_GAMELOGIC, "Invalid Controller: %s\n", SDL_GetError()); + return; } for (i = 0; i < MAXSPLITSCREENPLAYERS; i++) - CONS_Debug(DBG_GAMELOGIC, "Joystick%d device index: %d\n", i+1, JoyInfo[i].oldjoy); + { + I_InitController(i); + G_SetPlayerControllerIndicatorColor(i, SKINCOLOR_NONE); // gotta update the controller led again on reconnect + } + + I_UpdateControllerList(); // update the menu if (menustack[0] == MN_OP_JOYSTICKSET) MR_SetupJoystickMenu(0); - numcontrollers = I_NumJoys(); - - for (i = 0; i < MAXSPLITSCREENPLAYERS; i++) - { - if (JoyInfo[i].dev == newcontroller) - break; - } - - if (i == MAXSPLITSCREENPLAYERS) - SDL_CloseGamepad(newcontroller); + CONS_Debug(DBG_GAMELOGIC, "Controller device index %d added\n", joystick_id); } static void Impl_HandleControllerRemoveEvent(SDL_Event evt) @@ -1017,44 +1006,26 @@ static void Impl_HandleControllerRemoveEvent(SDL_Event evt) UINT8 i; SDL_JoystickID joystick_id = evt.gdevice.which; - for (i = 0; i < MAXSPLITSCREENPLAYERS; i++) + if (joystick_id == 0) { - if (JoyInfo[i].dev && JoyInfo[i].id == joystick_id && !SDL_GamepadConnected(JoyInfo[i].dev)) - { - CONS_Debug(DBG_GAMELOGIC, "Joystick%d removed, device index: %d\n", i+1, joystick_id); - 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 (fastcmp(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); - } + CONS_Debug(DBG_GAMELOGIC, "Invalid Controller: %s\n", SDL_GetError()); + return; } for (i = 0; i < MAXSPLITSCREENPLAYERS; i++) - CONS_Debug(DBG_GAMELOGIC, "Joystick%d device index: %d\n", i+1, JoyInfo[i].oldjoy); + { + if (controllerInfo[i].dev && (controllerInfo[i].id == (INT32)joystick_id) && !SDL_GamepadConnected(controllerInfo[i].dev)) + { + CONS_Debug(DBG_GAMELOGIC, "Controller for Player %d removed, device index: %d\n", i+1, joystick_id); + I_ShutdownController(i); + } + } + + I_UpdateControllerList(); // update the menu if (menustack[0] == MN_OP_JOYSTICKSET) MR_SetupJoystickMenu(0); - numcontrollers = I_NumJoys(); } void I_GetEvent(void) diff --git a/src/sdl/macosx/Srb2mac.pbproj/project.pbxproj b/src/sdl/macosx/Srb2mac.pbproj/project.pbxproj index 746093127..bb556508f 100644 --- a/src/sdl/macosx/Srb2mac.pbproj/project.pbxproj +++ b/src/sdl/macosx/Srb2mac.pbproj/project.pbxproj @@ -1793,8 +1793,8 @@ 841777A5085A1200000C01D8 = { fileEncoding = 30; isa = PBXFileReference; - name = i_joy.h; - path = ../../i_joy.h; + name = i_gamepad.h; + path = ../../i_gamepad.h; refType = 2; }; 841777A6085A1200000C01D8 = { diff --git a/src/sdl/macosx/Srb2mac.xcodeproj/project.pbxproj b/src/sdl/macosx/Srb2mac.xcodeproj/project.pbxproj index 7403b53bf..498661fd6 100644 --- a/src/sdl/macosx/Srb2mac.xcodeproj/project.pbxproj +++ b/src/sdl/macosx/Srb2mac.xcodeproj/project.pbxproj @@ -228,7 +228,7 @@ 1E44AED60B67CD1200BAD059 /* i_tcp.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = i_tcp.h; path = ../../i_tcp.h; sourceTree = SOURCE_ROOT; }; 1E44AED70B67CD1200BAD059 /* i_system.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = i_system.h; path = ../../i_system.h; sourceTree = SOURCE_ROOT; }; 1E44AED80B67CD1200BAD059 /* i_video.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = i_video.h; path = ../../i_video.h; sourceTree = SOURCE_ROOT; }; - 1E44AED90B67CD1300BAD059 /* i_joy.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = i_joy.h; path = ../../i_joy.h; sourceTree = SOURCE_ROOT; }; + 1E44AED90B67CD1300BAD059 /* i_gamepad.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = i_gamepad.h; path = ../../i_gamepad.h; sourceTree = SOURCE_ROOT; }; 1E44AEE10B67CD2B00BAD059 /* am_map.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = am_map.c; path = ../../am_map.c; sourceTree = SOURCE_ROOT; }; 1E44AEE20B67CD2B00BAD059 /* am_map.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = am_map.h; path = ../../am_map.h; sourceTree = SOURCE_ROOT; }; 1E44AEE50B67CD3200BAD059 /* byteptr.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = byteptr.h; path = ../../byteptr.h; sourceTree = SOURCE_ROOT; }; @@ -651,7 +651,7 @@ 1E44AED60B67CD1200BAD059 /* i_tcp.h */, 1E44AED70B67CD1200BAD059 /* i_system.h */, 1E44AED80B67CD1200BAD059 /* i_video.h */, - 1E44AED90B67CD1300BAD059 /* i_joy.h */, + 1E44AED90B67CD1300BAD059 /* i_gamepad.h */, 1E44AEF50B67CD9F00BAD059 /* keys.h */, 1E44AF200B67CE4100BAD059 /* mserv.c */, 1E44AF210B67CE4100BAD059 /* mserv.h */, diff --git a/src/sdl/sdlmain.h b/src/sdl/sdlmain.h index 9bb223e6b..f5df5e63a 100644 --- a/src/sdl/sdlmain.h +++ b/src/sdl/sdlmain.h @@ -32,7 +32,8 @@ extern "C" { // SDL3 stub macro #define SDL3STUB() CONS_Printf("SDL3: stubbed: %s:%d\n", __func__, __LINE__) -// So m_menu knows whether to store cv_usejoystick value or string + +// So m_menu knows whether to store cv_usecontroller value or string #define JOYSTICK_HOTPLUG /** \brief The JoyInfo_s struct @@ -41,48 +42,36 @@ extern "C" { */ typedef struct SDLJoyInfo_s { - /// Controller handle + /// Gamepad handle SDL_Gamepad *dev; + /// Joystick handle + //SDL_Joystick *joydev; /// Controller index - INT32 id; - /// number of old joystick - int oldjoy; - /// number of axies - int axises; + INT32 id; // SDL_JoystickID + /// name of controller + //const char *name; /// scale of axises INT32 scale; - /// number of buttons - int buttons; - /// number of hats - int hats; - /// number of balls - int balls; - -} SDLJoyInfo_t; + // Rumble Support + boolean hasrumble; + // RGB LED Support + boolean hasrgbled; +} controllerinfo_t; /** \brief SDL info about controllers */ -extern SDLJoyInfo_t JoyInfo[MAXSPLITSCREENPLAYERS]; -extern SDL_Gamepad *ExJoystick[MAXGAMEPADS]; +extern controllerinfo_t controllerInfo[MAXSPLITSCREENPLAYERS]; -void I_StoreExJoystick(SDL_Gamepad *dev); - -/** \brief joystick axis deadzone -*/ -#define SDL_JDEADZONE 153 -#undef SDL_JDEADZONE - -void I_GetConsoleEvents(void); +void I_ShutdownControllerSystem(void); // So we can call this from i_video event loop -void I_ShutdownJoystick(UINT8 index); +void I_ShutdownController(UINT8 index); // Cheat to get the device index for a game controller handle -INT32 I_GetJoystickID(SDL_Gamepad *dev); +INT32 I_GetControllerID(SDL_Gamepad *dev); + +void I_UpdateControllerList(void); -// 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); diff --git a/src/typedef.h b/src/typedef.h index 1d8d326bc..af50e9342 100644 --- a/src/typedef.h +++ b/src/typedef.h @@ -138,7 +138,7 @@ TYPEDEF (mapsearchfreq_t); // hu_stuff.h TYPEDEF (playersort_t); -// i_joy.h +// i_gamepad.h TYPEDEF (JoyType_t); // i_net.h