From 4d65f09eb797bb667be37e602a165f3d95872f20 Mon Sep 17 00:00:00 2001 From: Eidolon Date: Tue, 23 Aug 2022 00:05:50 -0500 Subject: [PATCH] Port Ediolon's SDL GameController work Basically instantly solved all of the issues that made this branch completely unusable --- src/g_input.c | 136 +++++++++++++++++-------------------------- src/g_input.h | 15 +++-- src/m_menu.c | 2 +- src/sdl/i_system.cpp | 59 +++++++++---------- src/sdl/i_video.cpp | 62 +------------------- 5 files changed, 94 insertions(+), 180 deletions(-) diff --git a/src/g_input.c b/src/g_input.c index 652ead489..af4b9cd34 100644 --- a/src/g_input.c +++ b/src/g_input.c @@ -84,7 +84,9 @@ INT32 G_GetDevicePlayer(INT32 deviceID) // converts ev_joystick axis to its corresponding key INT32 G_AxisToKey(event_t *ev) { - return KEY_AXIS1 + ev->data1*2 + (ev->data2 >= 0); + return KEY_AXIS1 + (ev->data1 >= JOYANALOGS*2 + ? ev->data1 + JOYANALOGS*2 + : ev->data1*2 + (ev->data2 >= 0)); } // @@ -187,7 +189,7 @@ void G_MapEventsToControls(event_t *ev) break; } - if (ev->data1 >= JOYAXISSET*2) + if (ev->data1 >= JOYAXISSETS*2) { #ifdef PARANOIA CONS_Debug(DBG_GAMELOGIC, "Bad joystick axis event %d\n", ev->data1); @@ -195,7 +197,7 @@ void G_MapEventsToControls(event_t *ev) break; } - i = ev->data1 * 2; + i = ev->data1; if (G_GetDevicePlayer(ev->device) == 0) { @@ -203,17 +205,27 @@ void G_MapEventsToControls(event_t *ev) break; } - if (ev->data2 < 0) + if (i >= 2 * JOYANALOGS) { - // Left - gamekeydown[ev->device][KEY_AXIS1 + i] = abs(ev->data2); - gamekeydown[ev->device][KEY_AXIS1 + i + 1] = 0; + // The trigger axes are handled specially. + i -= 2 * JOYANALOGS; + gamekeydown[ev->device][KEY_AXIS1 + (JOYANALOGS * 4) + i] = max(0, ev->data2); } else { - // Right - gamekeydown[ev->device][KEY_AXIS1 + i] = 0; - gamekeydown[ev->device][KEY_AXIS1 + i + 1] = abs(ev->data2); + i *= 2; + if (ev->data2 < 0) + { + // Left + gamekeydown[ev->device][KEY_AXIS1 + i] = abs(ev->data2); + gamekeydown[ev->device][KEY_AXIS1 + i + 1] = 0; + } + else + { + // Right + gamekeydown[ev->device][KEY_AXIS1 + i] = 0; + gamekeydown[ev->device][KEY_AXIS1 + i + 1] = abs(ev->data2); + } } break; @@ -318,76 +330,38 @@ static keyname_t keynames[] = {KEY_MOUSEWHEELUP, "Wheel Up"}, {KEY_MOUSEWHEELDOWN, "Wheel Down"}, - {KEY_JOY1+0, "JOY1"}, - {KEY_JOY1+1, "JOY2"}, - {KEY_JOY1+2, "JOY3"}, - {KEY_JOY1+3, "JOY4"}, - {KEY_JOY1+4, "JOY5"}, - {KEY_JOY1+5, "JOY6"}, - {KEY_JOY1+6, "JOY7"}, - {KEY_JOY1+7, "JOY8"}, - {KEY_JOY1+8, "JOY9"}, -#if !defined (NOMOREJOYBTN_1S) - // we use up to 32 buttons in DirectInput - {KEY_JOY1+9, "JOY10"}, - {KEY_JOY1+10, "JOY11"}, - {KEY_JOY1+11, "JOY12"}, - {KEY_JOY1+12, "JOY13"}, - {KEY_JOY1+13, "JOY14"}, - {KEY_JOY1+14, "JOY15"}, - {KEY_JOY1+15, "JOY16"}, - {KEY_JOY1+16, "JOY17"}, - {KEY_JOY1+17, "JOY18"}, - {KEY_JOY1+18, "JOY19"}, - {KEY_JOY1+19, "JOY20"}, - {KEY_JOY1+20, "JOY21"}, - {KEY_JOY1+21, "JOY22"}, - {KEY_JOY1+22, "JOY23"}, - {KEY_JOY1+23, "JOY24"}, - {KEY_JOY1+24, "JOY25"}, - {KEY_JOY1+25, "JOY26"}, - {KEY_JOY1+26, "JOY27"}, - {KEY_JOY1+27, "JOY28"}, - {KEY_JOY1+28, "JOY29"}, - {KEY_JOY1+29, "JOY30"}, - {KEY_JOY1+30, "JOY31"}, - {KEY_JOY1+31, "JOY32"}, -#endif + {KEY_JOY1+0, "A BUTTON"}, + {KEY_JOY1+1, "B BUTTON"}, + {KEY_JOY1+2, "X BUTTON"}, + {KEY_JOY1+3, "Y BUTTON"}, + {KEY_JOY1+4, "BACK BUTTON"}, + {KEY_JOY1+5, "GUIDE BUTTON"}, + {KEY_JOY1+6, "START BUTTON"}, + {KEY_JOY1+7, "L-STICK CLICK"}, + {KEY_JOY1+8, "R-STICK CLICK"}, + {KEY_JOY1+9, "L BUMPER"}, + {KEY_JOY1+10, "R BUMPER"}, + {KEY_JOY1+11, "D-PAD UP"}, + {KEY_JOY1+12, "D-PAD DOWN"}, + {KEY_JOY1+13, "D-PAD LEFT"}, + {KEY_JOY1+14, "D-PAD RIGHT"}, + {KEY_JOY1+15, "MISC. BUTTON"}, + {KEY_JOY1+16, "PADDLE1 BUTTON"}, + {KEY_JOY1+17, "PADDLE2 BUTTON"}, + {KEY_JOY1+18, "PADDLE3 BUTTON"}, + {KEY_JOY1+19, "PADDLE4 BUTTON"}, + {KEY_JOY1+20, "TOUCHPAD"}, - // the DOS version uses Allegro's joystick support - {KEY_HAT1+0, "HATUP"}, - {KEY_HAT1+1, "HATDOWN"}, - {KEY_HAT1+2, "HATLEFT"}, - {KEY_HAT1+3, "HATRIGHT"}, - {KEY_HAT1+4, "HATUP2"}, - {KEY_HAT1+5, "HATDOWN2"}, - {KEY_HAT1+6, "HATLEFT2"}, - {KEY_HAT1+7, "HATRIGHT2"}, - {KEY_HAT1+8, "HATUP3"}, - {KEY_HAT1+9, "HATDOWN3"}, - {KEY_HAT1+10, "HATLEFT3"}, - {KEY_HAT1+11, "HATRIGHT3"}, - {KEY_HAT1+12, "HATUP4"}, - {KEY_HAT1+13, "HATDOWN4"}, - {KEY_HAT1+14, "HATLEFT4"}, - {KEY_HAT1+15, "HATRIGHT4"}, - - {KEY_AXIS1+0, "AXISX-"}, - {KEY_AXIS1+1, "AXISX+"}, - {KEY_AXIS1+2, "AXISY-"}, - {KEY_AXIS1+3, "AXISY+"}, - {KEY_AXIS1+4, "AXISZ-"}, - {KEY_AXIS1+5, "AXISZ+"}, - {KEY_AXIS1+6, "AXISXRUDDER-"}, - {KEY_AXIS1+7, "AXISXRUDDER+"}, - {KEY_AXIS1+8, "AXISYRUDDER-"}, - {KEY_AXIS1+9, "AXISYRUDDER+"}, - {KEY_AXIS1+10, "AXISZRUDDER-"}, - {KEY_AXIS1+11, "AXISZRUDDER+"}, - {KEY_AXIS1+12, "AXISU-"}, - {KEY_AXIS1+13, "AXISU+"}, - {KEY_AXIS1+14, "AXISV-"}, - {KEY_AXIS1+15, "AXISV+"}, + {KEY_AXIS1+0, "L-STICK LEFT"}, + {KEY_AXIS1+1, "L-STICK RIGHT"}, + {KEY_AXIS1+2, "L-STICK UP"}, + {KEY_AXIS1+3, "L-STICK DOWN"}, + {KEY_AXIS1+4, "R-STICK LEFT"}, + {KEY_AXIS1+5, "R-STICK RIGHT"}, + {KEY_AXIS1+6, "R-STICK UP"}, + {KEY_AXIS1+7, "R-STICK DOWN"}, + {KEY_AXIS1+8, "L TRIGGER"}, + {KEY_AXIS1+9, "R TRIGGER"}, }; static const char *gamecontrolname[num_gamecontrols] = @@ -596,10 +570,10 @@ void G_DefineDefaultControls(void) gamecontroldefault[gc_turnright ][1] = KEY_AXIS1+1; // Left X+ gamecontroldefault[gc_accelerate ][1] = KEY_JOY1+0; // A gamecontroldefault[gc_drift ][1] = KEY_JOY1+10; // RB - gamecontroldefault[gc_drift ][2] = KEY_AXIS1+11;// RT + gamecontroldefault[gc_drift ][2] = KEY_AXIS1+9; // RT gamecontroldefault[gc_brake ][1] = KEY_JOY1+1; // B gamecontroldefault[gc_fire ][1] = KEY_JOY1+9; // LB - gamecontroldefault[gc_fire ][2] = KEY_AXIS1+9; // LT + gamecontroldefault[gc_fire ][2] = KEY_AXIS1+8; // LT gamecontroldefault[gc_lookback ][1] = KEY_JOY1+2; // X gamecontroldefault[gc_pause ][1] = KEY_JOY1+4; // Back diff --git a/src/g_input.h b/src/g_input.h index 03a48cd4d..b8c496047 100644 --- a/src/g_input.h +++ b/src/g_input.h @@ -27,9 +27,12 @@ extern "C" { #define NUMKEYS 256 #define MOUSEBUTTONS 8 -#define JOYBUTTONS 32 // 32 buttons -#define JOYHATS 4 // 4 hats -#define JOYAXISSET 4 // 4 Sets of 2 axises + +#define JOYBUTTONS 21 // 21 buttons, to match SDL_GameControllerButton +#define JOYANALOGS 2 // 2 sets of analog stick axes, with positive and negative each +#define JOYTRIGGERS 1 // 1 set of trigger axes, positive only +#define JOYAXISSETS (JOYANALOGS + JOYTRIGGERS) +#define JOYAXES ((4 * JOYANALOGS) + (2 * JOYTRIGGERS)) #define MAXINPUTMAPPING 4 @@ -39,9 +42,9 @@ extern "C" { typedef enum { KEY_JOY1 = NUMKEYS, - KEY_HAT1 = KEY_JOY1 + JOYBUTTONS, - KEY_AXIS1 = KEY_HAT1 + JOYHATS*4, - JOYINPUTEND = KEY_AXIS1 + JOYAXISSET*2*2, // 4 sets of 2 axes, each with positive & negative + KEY_HAT1 = KEY_JOY1 + 11, // macro for SDL_CONTROLLER_BUTTON_DPAD_UP + KEY_AXIS1 = KEY_JOY1 + JOYBUTTONS, + JOYINPUTEND = KEY_AXIS1 + JOYAXES, KEY_MOUSE1 = JOYINPUTEND, KEY_MOUSEMOVE = KEY_MOUSE1 + MOUSEBUTTONS, diff --git a/src/m_menu.c b/src/m_menu.c index a9a270c55..d477207db 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -2609,7 +2609,7 @@ boolean M_Responder(event_t *ev) { if (ev->type == ev_joystick && deviceplayer == 0) { - static INT32 lastjoy[JOYAXISSET*2] = {0}; + static INT32 lastjoy[JOYAXISSETS*2] = {0}; if (G_AxisInDeadzone(deviceplayer, ev)) { diff --git a/src/sdl/i_system.cpp b/src/sdl/i_system.cpp index e6cbff824..8b2297dd5 100644 --- a/src/sdl/i_system.cpp +++ b/src/sdl/i_system.cpp @@ -1089,7 +1089,7 @@ void I_JoyScale4(void) JoyInfo[3].scale = Joystick[3].bGamepadStyle?1:cv_joyscale[1].value; } -// Cheat to get the device index for a joystick handle +// Cheat to get the device index for a game controller handle INT32 I_GetJoystickDeviceIndex(SDL_GameController *dev) { SDL_Joystick *joystick = NULL; @@ -1169,7 +1169,7 @@ void I_UpdateJoystickDeviceIndices(UINT8 excludePlayer) */ void I_ShutdownJoystick(UINT8 index) { - INT32 i, j; + INT32 i; event_t event; event.device = I_GetJoystickDeviceIndex(JoyInfo[index].dev); @@ -1180,23 +1180,13 @@ void I_ShutdownJoystick(UINT8 index) // emulate the up of all joystick buttons for (i = 0; i < JOYBUTTONS; i++) { - event.data1=KEY_JOY1+i; + event.data1 = KEY_JOY1+i; D_PostEvent(&event); } - // emulate the up of all joystick hats - for (i = 0; i < JOYHATS*4; i++) - { - for (j = 0; j < 4; j++) - { - event.data1 = KEY_HAT1 + (i * 4) + j; - D_PostEvent(&event); - } - } - // reset joystick position event.type = ev_joystick; - for (i = 0; i < JOYAXISSET; i++) + for (i = 0; i < JOYAXISSETS*2; i++) { event.data1 = i; D_PostEvent(&event); @@ -1233,6 +1223,12 @@ static int joy_open(int playerIndex, int joyIndex) } + if (SDL_WasInit(SDL_INIT_GAMECONTROLLER) == 0) + { + CONS_Printf(M_GetText("Game Controller subsystem not started\n")); + return -1; + } + if (joyIndex <= 0) return -1; @@ -1281,25 +1277,8 @@ static int joy_open(int playerIndex, int joyIndex) CONS_Debug(DBG_GAMELOGIC, M_GetText("Joystick%d: %s\n"), playerIndex+1, SDL_GameControllerName(JoyInfo[playerIndex].dev)); JoyInfo[playerIndex].axises = SDL_CONTROLLER_AXIS_MAX; - if (JoyInfo[playerIndex].axises > JOYAXISSET*2) - JoyInfo[playerIndex].axises = JOYAXISSET*2; - - /* - if (joyaxes<2) - { - I_OutputMsg("Not enought axes?\n"); - return 0; - } - */ - JoyInfo[playerIndex].buttons = SDL_CONTROLLER_BUTTON_MAX; - if (JoyInfo[playerIndex].buttons > JOYBUTTONS) - JoyInfo[playerIndex].buttons = JOYBUTTONS; - - JoyInfo[playerIndex].hats = 4; - if (JoyInfo[playerIndex].hats > JOYHATS) - JoyInfo[playerIndex].hats = JOYHATS; - + JoyInfo[playerIndex].hats = 1; JoyInfo[playerIndex].balls = 0; //JoyInfo[playerIndex].bGamepadStyle = !stricmp(SDL_JoystickName(JoyInfo[playerIndex].dev), "pad"); @@ -1347,6 +1326,15 @@ void I_InitJoystick(UINT8 index) } + if (SDL_WasInit(SDL_INIT_GAMECONTROLLER) == 0) + { + if (SDL_InitSubSystem(SDL_INIT_GAMECONTROLLER) == -1) + { + CONS_Printf(M_GetText("Couldn't initialize gamepads: %s\n"), SDL_GetError()); + return; + } + } + if (cv_usejoystick[index].value) newcontroller = SDL_GameControllerOpen(cv_usejoystick[index].value-1); @@ -1422,6 +1410,13 @@ static void I_ShutdownInput(void) for (i = 0; i < MAXSPLITSCREENPLAYERS; i++) I_ShutdownJoystick(i); + if (SDL_WasInit(SDL_INIT_GAMECONTROLLER) == SDL_INIT_GAMECONTROLLER) + { + CONS_Printf("Shutting down gamecontroller system\n"); + SDL_QuitSubSystem(SDL_INIT_GAMECONTROLLER); + 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"); diff --git a/src/sdl/i_video.cpp b/src/sdl/i_video.cpp index 6fc556d71..12b858db9 100644 --- a/src/sdl/i_video.cpp +++ b/src/sdl/i_video.cpp @@ -833,57 +833,11 @@ static void Impl_HandleControllerAxisEvent(SDL_ControllerAxisEvent evt) } //value - event.data2 = SDLJoyAxis(evt.value, 0); // TODO: replace 0 with pid + event.data2 = SDLJoyAxis(evt.value, evt.which); D_PostEvent(&event); } -static void Impl_SendHatEvent(SDL_JoyHatEvent evt, UINT64 hatFlag, UINT8 keyOffset) -{ - event_t event; - - event.device = 1 + evt.which; - if (event.device == INT32_MAX) - { - return; - } - - event.data1 = KEY_HAT1 + keyOffset; - - if (evt.hat < JOYHATS) - { - event.data1 += (evt.hat * 4); - } - else - { - return; - } - - if (evt.value & hatFlag) - { - event.type = ev_keydown; - } - else - { - event.type = ev_keyup; - } - - SDLJoyRemap(&event); - - if (event.type != ev_console) - { - D_PostEvent(&event); - } -} - -static void Impl_HandleJoystickHatEvent(SDL_JoyHatEvent evt) -{ - Impl_SendHatEvent(evt, SDL_HAT_UP, 0); - Impl_SendHatEvent(evt, SDL_HAT_DOWN, 1); - Impl_SendHatEvent(evt, SDL_HAT_LEFT, 2); - Impl_SendHatEvent(evt, SDL_HAT_RIGHT, 3); -} - static void Impl_HandleControllerButtonEvent(SDL_ControllerButtonEvent evt, Uint32 type) { event_t event; @@ -892,15 +846,6 @@ static void Impl_HandleControllerButtonEvent(SDL_ControllerButtonEvent evt, Uint event.data1 = event.data2 = event.data3 = INT32_MAX; - if (evt.button == SDL_CONTROLLER_BUTTON_DPAD_UP - || evt.button == SDL_CONTROLLER_BUTTON_DPAD_DOWN - || evt.button == SDL_CONTROLLER_BUTTON_DPAD_LEFT - || evt.button == SDL_CONTROLLER_BUTTON_DPAD_RIGHT) - { - // dpad buttons are mapped as the hat instead - return; - } - if (event.device == INT32_MAX) { return; @@ -980,9 +925,6 @@ void I_GetEvent(void) case SDL_CONTROLLERAXISMOTION: Impl_HandleControllerAxisEvent(evt.caxis); break; - case SDL_JOYHATMOTION: - Impl_HandleJoystickHatEvent(evt.jhat); - break; case SDL_CONTROLLERBUTTONUP: case SDL_CONTROLLERBUTTONDOWN: Impl_HandleControllerButtonEvent(evt.cbutton, evt.type); @@ -997,7 +939,7 @@ void I_GetEvent(void) SDL_GameController *newcontroller = SDL_GameControllerOpen(evt.cdevice.which); - CONS_Debug(DBG_GAMELOGIC, "Joystick device index %d added\n", evt.jdevice.which + 1); + 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: