From 5412be76e89d3119a74a942f47faa2f72acc9074 Mon Sep 17 00:00:00 2001 From: Eidolon Date: Tue, 23 Aug 2022 00:05:50 -0500 Subject: [PATCH 01/10] Use SDL Game Controllers API --- src/g_game.c | 22 ++-- src/sdl/i_system.c | 253 ++++++++++++++++++++++++++------------------- src/sdl/i_video.c | 128 ++++++++++++++--------- src/sdl/sdlmain.h | 16 +-- 4 files changed, 243 insertions(+), 176 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index a76d4770..1e97f08c 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -391,7 +391,7 @@ static CV_PossibleValue_t joyaxis_cons_t[] = {{0, "None"}, {7, "LAnalog"}, {8, "RAnalog"}, {-7, "LAnalog-"}, {-8, "RAnalog-"}, #endif #else -{1, "X-Axis"}, {2, "Y-Axis"}, {-1, "X-Axis-"}, {-2, "Y-Axis-"}, +{1, "Left X"}, {2, "Left Y"}, {-1, "Left X-"}, {-2, "Left Y-"}, #ifdef _arch_dreamcast {3, "R-Trig"}, {4, "L-Trig"}, {-3, "R-Trig-"}, {-4, "L-Trig-"}, {5, "Alt X-Axis"}, {6, "Alt Y-Axis"}, {-5, "Alt X-Axis-"}, {-6, "Alt Y-Axis-"}, @@ -400,10 +400,10 @@ static CV_PossibleValue_t joyaxis_cons_t[] = {{0, "None"}, {3, "Alt X-Axis"}, {4, "Alt Y-Axis"}, {-3, "Alt X-Axis-"}, {-4, "Alt Y-Axis-"}, #else #if JOYAXISSET > 1 -{3, "Z-Axis"}, {4, "X-Rudder"}, {-3, "Z-Axis-"}, {-4, "X-Rudder-"}, +{3, "Right X"}, {4, "Right Y"}, {-3, "Right X-"}, {-4, "Right Y-"}, #endif #if JOYAXISSET > 2 -{5, "Y-Rudder"}, {6, "Z-Rudder"}, {-5, "Y-Rudder-"}, {-6, "Z-Rudder-"}, +{5, "L Trigger"}, {6, "R Trigger"}, {-5, "L Trigger-"}, {-6, "R Trigger-"}, #endif #if JOYAXISSET > 3 {7, "U-Axis"}, {8, "V-Axis"}, {-7, "U-Axis-"}, {-8, "V-Axis-"}, @@ -486,40 +486,40 @@ consvar_t cv_useranalog3 = {"useranalog3", "Off", CV_SAVE|CV_CALL, CV_OnOff, Use consvar_t cv_useranalog4 = {"useranalog4", "Off", CV_SAVE|CV_CALL, CV_OnOff, UserAnalog4_OnChange, 0, NULL, NULL, 0, 0, NULL}; #endif -consvar_t cv_turnaxis = {"joyaxis_turn", "X-Axis", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_turnaxis = {"joyaxis_turn", "Left X", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_moveaxis = {"joyaxis_move", "None", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_brakeaxis = {"joyaxis_brake", "None", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_aimaxis = {"joyaxis_aim", "Y-Axis", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_aimaxis = {"joyaxis_aim", "Left Y", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_lookaxis = {"joyaxis_look", "None", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_fireaxis = {"joyaxis_fire", "None", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_driftaxis = {"joyaxis_drift", "None", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_xdeadzone = {"joy_xdeadzone", "0.3", CV_FLOAT|CV_SAVE, deadzone_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_ydeadzone = {"joy_ydeadzone", "0.5", CV_FLOAT|CV_SAVE, deadzone_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_turnaxis2 = {"joyaxis2_turn", "X-Axis", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_turnaxis2 = {"joyaxis2_turn", "Left X", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_moveaxis2 = {"joyaxis2_move", "None", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_brakeaxis2 = {"joyaxis2_brake", "None", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_aimaxis2 = {"joyaxis2_aim", "Y-Axis", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_aimaxis2 = {"joyaxis2_aim", "Left Y", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_lookaxis2 = {"joyaxis2_look", "None", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_fireaxis2 = {"joyaxis2_fire", "None", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_driftaxis2 = {"joyaxis2_drift", "None", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_xdeadzone2 = {"joy2_xdeadzone", "0.3", CV_FLOAT|CV_SAVE, deadzone_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_ydeadzone2 = {"joy2_ydeadzone", "0.5", CV_FLOAT|CV_SAVE, deadzone_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_turnaxis3 = {"joyaxis3_turn", "X-Axis", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_turnaxis3 = {"joyaxis3_turn", "Left X", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_moveaxis3 = {"joyaxis3_move", "None", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_brakeaxis3 = {"joyaxis3_brake", "None", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_aimaxis3 = {"joyaxis3_aim", "Y-Axis", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_aimaxis3 = {"joyaxis3_aim", "Left Y", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_lookaxis3 = {"joyaxis3_look", "None", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_fireaxis3 = {"joyaxis3_fire", "None", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_driftaxis3 = {"joyaxis3_drift", "None", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_xdeadzone3 = {"joy3_xdeadzone", "0.3", CV_FLOAT|CV_SAVE, deadzone_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_ydeadzone3 = {"joy3_ydeadzone", "0.5", CV_FLOAT|CV_SAVE, deadzone_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_turnaxis4 = {"joyaxis4_turn", "X-Axis", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_turnaxis4 = {"joyaxis4_turn", "Left X", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_moveaxis4 = {"joyaxis4_move", "None", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_brakeaxis4 = {"joyaxis4_brake", "None", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_aimaxis4 = {"joyaxis4_aim", "Y-Axis", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_aimaxis4 = {"joyaxis4_aim", "Left Y", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_lookaxis4 = {"joyaxis4_look", "None", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_fireaxis4 = {"joyaxis4_fire", "None", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_driftaxis4 = {"joyaxis4_drift", "None", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index 8cb479b8..23729503 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -201,7 +201,7 @@ static void JoyReset(SDLJoyInfo_t *JoySet) { if (JoySet->dev) { - SDL_JoystickClose(JoySet->dev); + SDL_GameControllerClose(JoySet->dev); } JoySet->dev = NULL; JoySet->oldjoy = -1; @@ -884,17 +884,15 @@ void I_JoyScale4(void) } // Cheat to get the device index for a joystick handle -INT32 I_GetJoystickDeviceIndex(SDL_Joystick *dev) +INT32 I_GetJoystickDeviceIndex(SDL_GameController *dev) { - INT32 i, count = SDL_NumJoysticks(); + SDL_Joystick *joystick = NULL; - for (i = 0; dev && i < count; i++) + joystick = SDL_GameControllerGetJoystick(dev); + + if (joystick) { - SDL_Joystick *test = SDL_JoystickOpen(i); - if (test && test == dev) - return i; - else if (JoyInfo.dev != test && JoyInfo2.dev != test && JoyInfo3.dev != test && JoyInfo4.dev != test) - SDL_JoystickClose(test); + return SDL_JoystickInstanceID(joystick); } return -1; @@ -1196,15 +1194,10 @@ void I_GetJoystickEvents(void) } #endif - for (i = JoyInfo.hats - 1; i >= 0; i--) - { - Uint8 hat = SDL_JoystickGetHat(JoyInfo.dev, i); - - if (hat & SDL_HAT_UP ) joyhats|=(UINT64)0x1<<(0 + 4*i); - if (hat & SDL_HAT_DOWN ) joyhats|=(UINT64)0x1<<(1 + 4*i); - if (hat & SDL_HAT_LEFT ) joyhats|=(UINT64)0x1<<(2 + 4*i); - if (hat & SDL_HAT_RIGHT) joyhats|=(UINT64)0x1<<(3 + 4*i); - } + joyhats |= SDL_GameControllerGetButton(JoyInfo.dev, SDL_CONTROLLER_BUTTON_DPAD_UP); + joyhats |= SDL_GameControllerGetButton(JoyInfo.dev, SDL_CONTROLLER_BUTTON_DPAD_DOWN) << 1; + joyhats |= SDL_GameControllerGetButton(JoyInfo.dev, SDL_CONTROLLER_BUTTON_DPAD_LEFT) << 2; + joyhats |= SDL_GameControllerGetButton(JoyInfo.dev, SDL_CONTROLLER_BUTTON_DPAD_RIGHT) << 3; if (joyhats != lastjoyhats) { @@ -1290,7 +1283,7 @@ void I_GetJoystickEvents(void) */ static int joy_open(int joyindex) { - SDL_Joystick *newdev = NULL; + SDL_GameController *newdev = NULL; int num_joy = 0; if (SDL_WasInit(SDL_INIT_JOYSTICK) == 0) @@ -1298,6 +1291,11 @@ static int joy_open(int joyindex) CONS_Printf(M_GetText("Joystick subsystem not started\n")); return -1; } + if (SDL_WasInit(SDL_INIT_GAMECONTROLLER) == 0) + { + CONS_Printf(M_GetText("Game Controller subsystem not started\n")); + return -1; + } if (joyindex <= 0) return -1; @@ -1310,7 +1308,7 @@ static int joy_open(int joyindex) return -1; } - newdev = SDL_JoystickOpen(joyindex-1); + newdev = SDL_GameControllerOpen(joyindex-1); // Handle the edge case where the device <-> joystick index assignment can change due to hotplugging // This indexing is SDL's responsibility and there's not much we can do about it. @@ -1325,8 +1323,8 @@ static int joy_open(int joyindex) if (JoyInfo.dev) { if (JoyInfo.dev == newdev // same device, nothing to do - || (newdev == NULL && SDL_JoystickGetAttached(JoyInfo.dev))) // we failed, but already have a working device - return JoyInfo.axises; + || (newdev == NULL && SDL_GameControllerGetAttached(JoyInfo.dev))) // we failed, but already have a working device + return SDL_CONTROLLER_AXIS_MAX; // Else, we're changing devices, so send neutral joy events CONS_Debug(DBG_GAMELOGIC, "Joystick1 device is changing; resetting events...\n"); I_ShutdownJoystick(); @@ -1341,8 +1339,8 @@ static int joy_open(int joyindex) } else { - CONS_Debug(DBG_GAMELOGIC, M_GetText("Joystick1: %s\n"), SDL_JoystickName(JoyInfo.dev)); - JoyInfo.axises = SDL_JoystickNumAxes(JoyInfo.dev); + CONS_Debug(DBG_GAMELOGIC, M_GetText("Joystick1: %s\n"), SDL_GameControllerName(JoyInfo.dev)); + JoyInfo.axises = SDL_CONTROLLER_AXIS_MAX; if (JoyInfo.axises > JOYAXISSET*2) JoyInfo.axises = JOYAXISSET*2; /* if (joyaxes<2) @@ -1351,15 +1349,15 @@ static int joy_open(int joyindex) return 0; }*/ - JoyInfo.buttons = SDL_JoystickNumButtons(JoyInfo.dev); + JoyInfo.buttons = SDL_CONTROLLER_BUTTON_MAX ; // dpad is 4 buttons if (JoyInfo.buttons > JOYBUTTONS) JoyInfo.buttons = JOYBUTTONS; - JoyInfo.hats = SDL_JoystickNumHats(JoyInfo.dev); + JoyInfo.hats = 4; if (JoyInfo.hats > JOYHATS) JoyInfo.hats = JOYHATS; - JoyInfo.balls = SDL_JoystickNumBalls(JoyInfo.dev); + JoyInfo.balls = 0; //Joystick.bGamepadStyle = !stricmp(SDL_JoystickName(JoyInfo.dev), "pad"); @@ -1468,15 +1466,10 @@ void I_GetJoystick2Events(void) } #endif - for (i = JoyInfo2.hats - 1; i >= 0; i--) - { - Uint8 hat = SDL_JoystickGetHat(JoyInfo2.dev, i); - - if (hat & SDL_HAT_UP ) joyhats|=(UINT64)0x1<<(0 + 4*i); - if (hat & SDL_HAT_DOWN ) joyhats|=(UINT64)0x1<<(1 + 4*i); - if (hat & SDL_HAT_LEFT ) joyhats|=(UINT64)0x1<<(2 + 4*i); - if (hat & SDL_HAT_RIGHT) joyhats|=(UINT64)0x1<<(3 + 4*i); - } + joyhats |= SDL_GameControllerGetButton(JoyInfo2.dev, SDL_CONTROLLER_BUTTON_DPAD_UP); + joyhats |= SDL_GameControllerGetButton(JoyInfo2.dev, SDL_CONTROLLER_BUTTON_DPAD_DOWN) << 1; + joyhats |= SDL_GameControllerGetButton(JoyInfo2.dev, SDL_CONTROLLER_BUTTON_DPAD_LEFT) << 2; + joyhats |= SDL_GameControllerGetButton(JoyInfo2.dev, SDL_CONTROLLER_BUTTON_DPAD_RIGHT) << 3; if (joyhats != lastjoy2hats) { @@ -1562,7 +1555,7 @@ void I_GetJoystick2Events(void) */ static int joy_open2(int joyindex) { - SDL_Joystick *newdev = NULL; + SDL_GameController *newdev = NULL; int num_joy = 0; if (SDL_WasInit(SDL_INIT_JOYSTICK) == 0) @@ -1570,6 +1563,11 @@ static int joy_open2(int joyindex) CONS_Printf(M_GetText("Joystick subsystem not started\n")); return -1; } + if (SDL_WasInit(SDL_INIT_GAMECONTROLLER) == 0) + { + CONS_Printf(M_GetText("Game Controller subsystem not started\n")); + return -1; + } if (joyindex <= 0) return -1; @@ -1582,7 +1580,7 @@ static int joy_open2(int joyindex) return -1; } - newdev = SDL_JoystickOpen(joyindex-1); + newdev = SDL_GameControllerOpen(joyindex-1); // Handle the edge case where the device <-> joystick index assignment can change due to hotplugging // This indexing is SDL's responsibility and there's not much we can do about it. @@ -1597,8 +1595,8 @@ static int joy_open2(int joyindex) if (JoyInfo2.dev) { if (JoyInfo2.dev == newdev // same device, nothing to do - || (newdev == NULL && SDL_JoystickGetAttached(JoyInfo2.dev))) // we failed, but already have a working device - return JoyInfo.axises; + || (newdev == NULL && SDL_GameControllerGetAttached(JoyInfo2.dev))) // we failed, but already have a working device + return SDL_CONTROLLER_AXIS_MAX; // Else, we're changing devices, so send neutral joy events CONS_Debug(DBG_GAMELOGIC, "Joystick2 device is changing; resetting events...\n"); I_ShutdownJoystick2(); @@ -1613,8 +1611,8 @@ static int joy_open2(int joyindex) } else { - CONS_Debug(DBG_GAMELOGIC, M_GetText("Joystick2: %s\n"), SDL_JoystickName(JoyInfo2.dev)); - JoyInfo2.axises = SDL_JoystickNumAxes(JoyInfo2.dev); + CONS_Debug(DBG_GAMELOGIC, M_GetText("Joystick2: %s\n"), SDL_GameControllerName(JoyInfo2.dev)); + JoyInfo2.axises = SDL_CONTROLLER_AXIS_MAX; if (JoyInfo2.axises > JOYAXISSET*2) JoyInfo2.axises = JOYAXISSET*2; /* if (joyaxes<2) @@ -1623,15 +1621,15 @@ static int joy_open2(int joyindex) return 0; }*/ - JoyInfo2.buttons = SDL_JoystickNumButtons(JoyInfo2.dev); + JoyInfo2.buttons = SDL_CONTROLLER_BUTTON_MAX ; // dpad is 4 buttons if (JoyInfo2.buttons > JOYBUTTONS) JoyInfo2.buttons = JOYBUTTONS; - JoyInfo2.hats = SDL_JoystickNumHats(JoyInfo2.dev); + JoyInfo2.hats = 4; if (JoyInfo2.hats > JOYHATS) JoyInfo2.hats = JOYHATS; - JoyInfo2.balls = SDL_JoystickNumBalls(JoyInfo2.dev); + JoyInfo2.balls = 0; //Joystick.bGamepadStyle = !stricmp(SDL_JoystickName(JoyInfo2.dev), "pad"); @@ -1740,15 +1738,10 @@ void I_GetJoystick3Events(void) } #endif - for (i = JoyInfo3.hats - 1; i >= 0; i--) - { - Uint8 hat = SDL_JoystickGetHat(JoyInfo3.dev, i); - - if (hat & SDL_HAT_UP ) joyhats|=(UINT64)0x1<<(0 + 4*i); - if (hat & SDL_HAT_DOWN ) joyhats|=(UINT64)0x1<<(1 + 4*i); - if (hat & SDL_HAT_LEFT ) joyhats|=(UINT64)0x1<<(2 + 4*i); - if (hat & SDL_HAT_RIGHT) joyhats|=(UINT64)0x1<<(3 + 4*i); - } + joyhats |= SDL_GameControllerGetButton(JoyInfo3.dev, SDL_CONTROLLER_BUTTON_DPAD_UP); + joyhats |= SDL_GameControllerGetButton(JoyInfo3.dev, SDL_CONTROLLER_BUTTON_DPAD_DOWN) << 1; + joyhats |= SDL_GameControllerGetButton(JoyInfo3.dev, SDL_CONTROLLER_BUTTON_DPAD_LEFT) << 2; + joyhats |= SDL_GameControllerGetButton(JoyInfo3.dev, SDL_CONTROLLER_BUTTON_DPAD_RIGHT) << 3; if (joyhats != lastjoy3hats) { @@ -1770,6 +1763,7 @@ void I_GetJoystick3Events(void) } } +#if 0 // send joystick axis positions event.type = ev_joystick3; @@ -1820,7 +1814,7 @@ void I_GetJoystick3Events(void) } D_PostEvent(&event); } - +#endif } /** \brief Open joystick handle @@ -1833,7 +1827,7 @@ void I_GetJoystick3Events(void) */ static int joy_open3(int joyindex) { - SDL_Joystick *newdev = NULL; + SDL_GameController *newdev = NULL; int num_joy = 0; if (SDL_WasInit(SDL_INIT_JOYSTICK) == 0) @@ -1841,6 +1835,11 @@ static int joy_open3(int joyindex) CONS_Printf(M_GetText("Joystick subsystem not started\n")); return -1; } + if (SDL_WasInit(SDL_INIT_GAMECONTROLLER) == 0) + { + CONS_Printf(M_GetText("Game Controller subsystem not started\n")); + return -1; + } if (joyindex <= 0) return -1; @@ -1853,7 +1852,7 @@ static int joy_open3(int joyindex) return -1; } - newdev = SDL_JoystickOpen(joyindex - 1); + newdev = SDL_GameControllerOpen(joyindex - 1); // Handle the edge case where the device <-> joystick index assignment can change due to hotplugging // This indexing is SDL's responsibility and there's not much we can do about it. @@ -1868,8 +1867,8 @@ static int joy_open3(int joyindex) if (JoyInfo3.dev) { if (JoyInfo3.dev == newdev // same device, nothing to do - || (newdev == NULL && SDL_JoystickGetAttached(JoyInfo3.dev))) // we failed, but already have a working device - return JoyInfo.axises; + || (newdev == NULL && SDL_GameControllerGetAttached(JoyInfo3.dev))) // we failed, but already have a working device + return SDL_CONTROLLER_AXIS_MAX; // Else, we're changing devices, so send neutral joy events CONS_Debug(DBG_GAMELOGIC, "Joystick3 device is changing; resetting events...\n"); I_ShutdownJoystick3(); @@ -1884,8 +1883,8 @@ static int joy_open3(int joyindex) } else { - CONS_Debug(DBG_GAMELOGIC, M_GetText("Joystick3: %s\n"), SDL_JoystickName(JoyInfo3.dev)); - JoyInfo3.axises = SDL_JoystickNumAxes(JoyInfo3.dev); + CONS_Debug(DBG_GAMELOGIC, M_GetText("Joystick3: %s\n"), SDL_GameControllerName(JoyInfo3.dev)); + JoyInfo3.axises = SDL_CONTROLLER_AXIS_MAX; if (JoyInfo3.axises > JOYAXISSET * 2) JoyInfo3.axises = JOYAXISSET * 2; /* if (joyaxes<2) @@ -1894,15 +1893,15 @@ static int joy_open3(int joyindex) return 0; }*/ - JoyInfo3.buttons = SDL_JoystickNumButtons(JoyInfo3.dev); + JoyInfo3.buttons = SDL_CONTROLLER_BUTTON_MAX ; // dpad is 4 buttons if (JoyInfo3.buttons > JOYBUTTONS) JoyInfo3.buttons = JOYBUTTONS; - JoyInfo3.hats = SDL_JoystickNumHats(JoyInfo3.dev); + JoyInfo3.hats = 4; if (JoyInfo3.hats > JOYHATS) JoyInfo3.hats = JOYHATS; - JoyInfo3.balls = SDL_JoystickNumBalls(JoyInfo3.dev); + JoyInfo3.balls = 0; //Joystick.bGamepadStyle = !stricmp(SDL_JoystickName(JoyInfo3.dev), "pad"); @@ -2011,15 +2010,10 @@ void I_GetJoystick4Events(void) } #endif - for (i = JoyInfo4.hats - 1; i >= 0; i--) - { - Uint8 hat = SDL_JoystickGetHat(JoyInfo4.dev, i); - - if (hat & SDL_HAT_UP ) joyhats|=(UINT64)0x1<<(0 + 4*i); - if (hat & SDL_HAT_DOWN ) joyhats|=(UINT64)0x1<<(1 + 4*i); - if (hat & SDL_HAT_LEFT ) joyhats|=(UINT64)0x1<<(2 + 4*i); - if (hat & SDL_HAT_RIGHT) joyhats|=(UINT64)0x1<<(3 + 4*i); - } + joyhats |= SDL_GameControllerGetButton(JoyInfo4.dev, SDL_CONTROLLER_BUTTON_DPAD_UP); + joyhats |= SDL_GameControllerGetButton(JoyInfo4.dev, SDL_CONTROLLER_BUTTON_DPAD_DOWN) << 1; + joyhats |= SDL_GameControllerGetButton(JoyInfo4.dev, SDL_CONTROLLER_BUTTON_DPAD_LEFT) << 2; + joyhats |= SDL_GameControllerGetButton(JoyInfo4.dev, SDL_CONTROLLER_BUTTON_DPAD_RIGHT) << 3; if (joyhats != lastjoy4hats) { @@ -2041,6 +2035,7 @@ void I_GetJoystick4Events(void) } } +#if 0 // send joystick axis positions event.type = ev_joystick4; @@ -2091,7 +2086,7 @@ void I_GetJoystick4Events(void) } D_PostEvent(&event); } - +#endif } /** \brief Open joystick handle @@ -2104,7 +2099,7 @@ void I_GetJoystick4Events(void) */ static int joy_open4(int joyindex) { - SDL_Joystick *newdev = NULL; + SDL_GameController *newdev = NULL; int num_joy = 0; if (SDL_WasInit(SDL_INIT_JOYSTICK) == 0) @@ -2112,6 +2107,11 @@ static int joy_open4(int joyindex) CONS_Printf(M_GetText("Joystick subsystem not started\n")); return -1; } + if (SDL_WasInit(SDL_INIT_GAMECONTROLLER) == 0) + { + CONS_Printf(M_GetText("Game Controller subsystem not started\n")); + return -1; + } if (joyindex <= 0) return -1; @@ -2124,7 +2124,7 @@ static int joy_open4(int joyindex) return -1; } - newdev = SDL_JoystickOpen(joyindex - 1); + newdev = SDL_GameControllerOpen(joyindex - 1); // Handle the edge case where the device <-> joystick index assignment can change due to hotplugging // This indexing is SDL's responsibility and there's not much we can do about it. @@ -2139,8 +2139,8 @@ static int joy_open4(int joyindex) if (JoyInfo4.dev) { if (JoyInfo4.dev == newdev // same device, nothing to do - || (newdev == NULL && SDL_JoystickGetAttached(JoyInfo4.dev))) // we failed, but already have a working device - return JoyInfo.axises; + || (newdev == NULL && SDL_GameControllerGetAttached(JoyInfo4.dev))) // we failed, but already have a working device + return SDL_CONTROLLER_AXIS_MAX; // Else, we're changing devices, so send neutral joy events CONS_Debug(DBG_GAMELOGIC, "Joystick4 device is changing; resetting events...\n"); I_ShutdownJoystick4(); @@ -2155,8 +2155,8 @@ static int joy_open4(int joyindex) } else { - CONS_Debug(DBG_GAMELOGIC, M_GetText("Joystick4: %s\n"), SDL_JoystickName(JoyInfo4.dev)); - JoyInfo4.axises = SDL_JoystickNumAxes(JoyInfo4.dev); + CONS_Debug(DBG_GAMELOGIC, M_GetText("Joystick4: %s\n"), SDL_GameControllerName(JoyInfo4.dev)); + JoyInfo4.axises = SDL_CONTROLLER_AXIS_MAX; if (JoyInfo4.axises > JOYAXISSET * 2) JoyInfo4.axises = JOYAXISSET * 2; /* if (joyaxes<2) @@ -2165,15 +2165,15 @@ static int joy_open4(int joyindex) return 0; }*/ - JoyInfo4.buttons = SDL_JoystickNumButtons(JoyInfo4.dev); + JoyInfo4.buttons = SDL_CONTROLLER_BUTTON_MAX ; // dpad is 4 buttons if (JoyInfo4.buttons > JOYBUTTONS) JoyInfo4.buttons = JOYBUTTONS; - JoyInfo4.hats = SDL_JoystickNumHats(JoyInfo4.dev); + JoyInfo4.hats = 4; if (JoyInfo4.hats > JOYHATS) JoyInfo4.hats = JOYHATS; - JoyInfo4.balls = SDL_JoystickNumBalls(JoyInfo4.dev); + JoyInfo4.balls = 0; //Joystick.bGamepadStyle = !stricmp(SDL_JoystickName(JoyInfo4.dev), "pad"); @@ -2186,7 +2186,7 @@ static int joy_open4(int joyindex) // void I_InitJoystick(void) { - SDL_Joystick *newjoy = NULL; + SDL_GameController *newcontroller = NULL; //I_ShutdownJoystick(); //SDL_SetHintWithPriority("SDL_XINPUT_ENABLED", "0", SDL_HINT_OVERRIDE); @@ -2209,13 +2209,21 @@ void I_InitJoystick(void) return; } } + 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.value) - newjoy = SDL_JoystickOpen(cv_usejoystick.value-1); + newcontroller = SDL_GameControllerOpen(cv_usejoystick.value-1); - if (newjoy && (JoyInfo2.dev == newjoy || JoyInfo3.dev == newjoy || JoyInfo4.dev == newjoy)) // don't override an active device + if (newcontroller && (JoyInfo2.dev == newcontroller || JoyInfo3.dev == newcontroller || JoyInfo4.dev == newcontroller)) // don't override an active device cv_usejoystick.value = I_GetJoystickDeviceIndex(JoyInfo.dev) + 1; - else if (newjoy && joy_open(cv_usejoystick.value) != -1) + else if (newcontroller && joy_open(cv_usejoystick.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. @@ -2230,13 +2238,13 @@ void I_InitJoystick(void) joystick_started = 0; } - if (JoyInfo.dev != newjoy && JoyInfo2.dev != newjoy && JoyInfo3.dev != newjoy && JoyInfo4.dev != newjoy) - SDL_JoystickClose(newjoy); + if (JoyInfo.dev != newcontroller && JoyInfo2.dev != newcontroller && JoyInfo3.dev != newcontroller && JoyInfo4.dev != newcontroller) + SDL_GameControllerClose(newcontroller); } void I_InitJoystick2(void) { - SDL_Joystick *newjoy = NULL; + SDL_GameController *newcontroller = NULL; //I_ShutdownJoystick2(); //SDL_SetHintWithPriority("SDL_XINPUT_ENABLED", "0", SDL_HINT_OVERRIDE); @@ -2252,13 +2260,21 @@ void I_InitJoystick2(void) return; } } + 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_usejoystick2.value) - newjoy = SDL_JoystickOpen(cv_usejoystick2.value-1); + newcontroller = SDL_GameControllerOpen(cv_usejoystick2.value-1); - if (newjoy && (JoyInfo.dev == newjoy || JoyInfo3.dev == newjoy || JoyInfo4.dev == newjoy)) // don't override an active device + if (newcontroller && (JoyInfo.dev == newcontroller || JoyInfo3.dev == newcontroller || JoyInfo4.dev == newcontroller)) // don't override an active device cv_usejoystick2.value = I_GetJoystickDeviceIndex(JoyInfo2.dev) + 1; - else if (newjoy && joy_open2(cv_usejoystick2.value) != -1) + else if (newcontroller && joy_open2(cv_usejoystick2.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. @@ -2273,13 +2289,13 @@ void I_InitJoystick2(void) joystick2_started = 0; } - if (JoyInfo.dev != newjoy && JoyInfo2.dev != newjoy && JoyInfo3.dev != newjoy && JoyInfo4.dev != newjoy) - SDL_JoystickClose(newjoy); + if (JoyInfo.dev != newcontroller && JoyInfo2.dev != newcontroller && JoyInfo3.dev != newcontroller && JoyInfo4.dev != newcontroller) + SDL_GameControllerClose(newcontroller); } void I_InitJoystick3(void) { - SDL_Joystick *newjoy = NULL; + SDL_GameController *newcontroller = NULL; //I_ShutdownJoystick3(); //SDL_SetHintWithPriority("SDL_XINPUT_ENABLED", "0", SDL_HINT_OVERRIDE); @@ -2295,13 +2311,21 @@ void I_InitJoystick3(void) return; } } + 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_usejoystick3.value) - newjoy = SDL_JoystickOpen(cv_usejoystick3.value - 1); + newcontroller = SDL_GameControllerOpen(cv_usejoystick3.value - 1); - if (newjoy && (JoyInfo.dev == newjoy || JoyInfo2.dev == newjoy || JoyInfo4.dev == newjoy)) // don't override an active device + if (newcontroller && (JoyInfo.dev == newcontroller || JoyInfo2.dev == newcontroller || JoyInfo4.dev == newcontroller)) // don't override an active device cv_usejoystick3.value = I_GetJoystickDeviceIndex(JoyInfo3.dev) + 1; - else if (newjoy && joy_open3(cv_usejoystick3.value) != -1) + else if (newcontroller && joy_open3(cv_usejoystick3.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. @@ -2316,13 +2340,13 @@ void I_InitJoystick3(void) joystick3_started = 0; } - if (JoyInfo.dev != newjoy && JoyInfo2.dev != newjoy && JoyInfo3.dev != newjoy && JoyInfo4.dev != newjoy) - SDL_JoystickClose(newjoy); + if (JoyInfo.dev != newcontroller && JoyInfo2.dev != newcontroller && JoyInfo3.dev != newcontroller && JoyInfo4.dev != newcontroller) + SDL_GameControllerClose(newcontroller); } void I_InitJoystick4(void) { - SDL_Joystick *newjoy = NULL; + SDL_GameController *newcontroller = NULL; //I_ShutdownJoystick4(); //SDL_SetHintWithPriority("SDL_XINPUT_ENABLED", "0", SDL_HINT_OVERRIDE); @@ -2338,13 +2362,21 @@ void I_InitJoystick4(void) return; } } + 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_usejoystick4.value) - newjoy = SDL_JoystickOpen(cv_usejoystick4.value - 1); + newcontroller = SDL_GameControllerOpen(cv_usejoystick4.value - 1); - if (newjoy && (JoyInfo.dev == newjoy || JoyInfo2.dev == newjoy || JoyInfo4.dev == newjoy)) // don't override an active device + if (newcontroller && (JoyInfo.dev == newcontroller || JoyInfo2.dev == newcontroller || JoyInfo4.dev == newcontroller)) // don't override an active device cv_usejoystick4.value = I_GetJoystickDeviceIndex(JoyInfo4.dev) + 1; - else if (newjoy && joy_open4(cv_usejoystick4.value) != -1) + else if (newcontroller && joy_open4(cv_usejoystick4.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. @@ -2359,8 +2391,8 @@ void I_InitJoystick4(void) joystick4_started = 0; } - if (JoyInfo.dev != newjoy && JoyInfo2.dev != newjoy && JoyInfo3.dev != newjoy && JoyInfo4.dev != newjoy) - SDL_JoystickClose(newjoy); + if (JoyInfo.dev != newcontroller && JoyInfo2.dev != newcontroller && JoyInfo3.dev != newcontroller && JoyInfo4.dev != newcontroller) + SDL_GameControllerClose(newcontroller); } static void I_ShutdownInput(void) @@ -2373,6 +2405,13 @@ static void I_ShutdownInput(void) I_ShutdownJoystick3(); I_ShutdownJoystick4(); + 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.c b/src/sdl/i_video.c index 02bea08d..b3771eba 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -788,18 +788,18 @@ static void Impl_HandleMouseWheelEvent(SDL_MouseWheelEvent evt) } } -static void Impl_HandleJoystickAxisEvent(SDL_JoyAxisEvent evt) +static void Impl_HandleControllerAxisEvent(SDL_ControllerAxisEvent evt) { event_t event; SDL_JoystickID joyid[4]; + int32_t value; // Determine the Joystick IDs for each current open joystick - joyid[0] = SDL_JoystickInstanceID(JoyInfo.dev); - joyid[1] = SDL_JoystickInstanceID(JoyInfo2.dev); - joyid[2] = SDL_JoystickInstanceID(JoyInfo3.dev); - joyid[3] = SDL_JoystickInstanceID(JoyInfo4.dev); + joyid[0] = SDL_JoystickInstanceID(SDL_GameControllerGetJoystick(JoyInfo.dev)); + joyid[1] = SDL_JoystickInstanceID(SDL_GameControllerGetJoystick(JoyInfo2.dev)); + joyid[2] = SDL_JoystickInstanceID(SDL_GameControllerGetJoystick(JoyInfo3.dev)); + joyid[3] = SDL_JoystickInstanceID(SDL_GameControllerGetJoystick(JoyInfo4.dev)); - evt.axis++; event.data1 = event.data2 = event.data3 = INT32_MAX; if (evt.which == joyid[0]) @@ -823,16 +823,35 @@ static void Impl_HandleJoystickAxisEvent(SDL_JoyAxisEvent evt) if (evt.axis > JOYAXISSET*2) return; //vaule - if (evt.axis%2) + value = SDLJoyAxis(evt.value, event.type); + switch (evt.axis) { - event.data1 = evt.axis / 2; - event.data2 = SDLJoyAxis(evt.value, event.type); - } - else - { - evt.axis--; - event.data1 = evt.axis / 2; - event.data3 = SDLJoyAxis(evt.value, event.type); + case SDL_CONTROLLER_AXIS_LEFTX: + event.data1 = 0; + event.data2 = SDLJoyAxis(evt.value, event.type); + break; + case SDL_CONTROLLER_AXIS_LEFTY: + event.data1 = 0; + event.data3 = SDLJoyAxis(evt.value, event.type); + break; + case SDL_CONTROLLER_AXIS_RIGHTX: + event.data1 = 1; + event.data2 = SDLJoyAxis(evt.value, event.type); + break; + case SDL_CONTROLLER_AXIS_RIGHTY: + event.data1 = 1; + event.data3 = SDLJoyAxis(evt.value, event.type); + break; + case SDL_CONTROLLER_AXIS_TRIGGERLEFT: + event.data1 = 2; + event.data2 = SDLJoyAxis(evt.value, event.type); + break; + case SDL_CONTROLLER_AXIS_TRIGGERRIGHT: + event.data1 = 2; + event.data3 = SDLJoyAxis(evt.value, event.type); + break; + default: + return; } D_PostEvent(&event); } @@ -864,16 +883,25 @@ static void Impl_HandleJoystickHatEvent(SDL_JoyHatEvent evt) } #endif -static void Impl_HandleJoystickButtonEvent(SDL_JoyButtonEvent evt, Uint32 type) +static void Impl_HandleControllerButtonEvent(SDL_ControllerButtonEvent evt, Uint32 type) { event_t event; SDL_JoystickID joyid[4]; // Determine the Joystick IDs for each current open joystick - joyid[0] = SDL_JoystickInstanceID(JoyInfo.dev); - joyid[1] = SDL_JoystickInstanceID(JoyInfo2.dev); - joyid[2] = SDL_JoystickInstanceID(JoyInfo3.dev); - joyid[3] = SDL_JoystickInstanceID(JoyInfo4.dev); + joyid[0] = SDL_JoystickInstanceID(SDL_GameControllerGetJoystick(JoyInfo.dev)); + joyid[1] = SDL_JoystickInstanceID(SDL_GameControllerGetJoystick(JoyInfo2.dev)); + joyid[2] = SDL_JoystickInstanceID(SDL_GameControllerGetJoystick(JoyInfo3.dev)); + joyid[3] = SDL_JoystickInstanceID(SDL_GameControllerGetJoystick(JoyInfo4.dev)); + + 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 (evt.which == joyid[0]) { @@ -892,11 +920,11 @@ static void Impl_HandleJoystickButtonEvent(SDL_JoyButtonEvent evt, Uint32 type) event.data1 = KEY_4JOY1; } else return; - if (type == SDL_JOYBUTTONUP) + if (type == SDL_CONTROLLERBUTTONUP) { event.type = ev_keyup; } - else if (type == SDL_JOYBUTTONDOWN) + else if (type == SDL_CONTROLLERBUTTONDOWN) { event.type = ev_keydown; } @@ -950,26 +978,26 @@ void I_GetEvent(void) case SDL_MOUSEWHEEL: Impl_HandleMouseWheelEvent(evt.wheel); break; - case SDL_JOYAXISMOTION: - Impl_HandleJoystickAxisEvent(evt.jaxis); + case SDL_CONTROLLERAXISMOTION: + Impl_HandleControllerAxisEvent(evt.caxis); break; #if 0 case SDL_JOYHATMOTION: Impl_HandleJoystickHatEvent(evt.jhat) break; #endif - case SDL_JOYBUTTONUP: - case SDL_JOYBUTTONDOWN: - Impl_HandleJoystickButtonEvent(evt.jbutton, evt.type); + case SDL_CONTROLLERBUTTONUP: + case SDL_CONTROLLERBUTTONDOWN: + Impl_HandleControllerButtonEvent(evt.cbutton, evt.type); break; //////////////////////////////////////////////////////////// - case SDL_JOYDEVICEADDED: + case SDL_CONTROLLERDEVICEADDED: { // OH BOY are you in for a good time! #abominationstation - SDL_Joystick *newjoy = SDL_JoystickOpen(evt.jdevice.which); + SDL_GameController *newcontroller = SDL_GameControllerOpen(evt.cdevice.which); CONS_Debug(DBG_GAMELOGIC, "Joystick device index %d added\n", evt.jdevice.which + 1); @@ -988,10 +1016,10 @@ void I_GetEvent(void) // PLAYER 1 ////////////////////////////// - if (newjoy && (!JoyInfo.dev || !SDL_JoystickGetAttached(JoyInfo.dev)) - && JoyInfo2.dev != newjoy && JoyInfo3.dev != newjoy && JoyInfo4.dev != newjoy) // don't override a currently active device + if (newcontroller && (!JoyInfo.dev || !SDL_GameControllerGetAttached(JoyInfo.dev)) + && JoyInfo2.dev != newcontroller && JoyInfo3.dev != newcontroller && JoyInfo4.dev != newcontroller) // don't override a currently active device { - cv_usejoystick.value = evt.jdevice.which + 1; + cv_usejoystick.value = evt.cdevice.which + 1; I_UpdateJoystickDeviceIndices(1); } @@ -999,10 +1027,10 @@ void I_GetEvent(void) // PLAYER 2 ////////////////////////////// - else if (newjoy && (!JoyInfo2.dev || !SDL_JoystickGetAttached(JoyInfo2.dev)) - && JoyInfo.dev != newjoy && JoyInfo3.dev != newjoy && JoyInfo4.dev != newjoy) // don't override a currently active device + else if (newcontroller && (!JoyInfo2.dev || !SDL_GameControllerGetAttached(JoyInfo2.dev)) + && JoyInfo.dev != newcontroller && JoyInfo3.dev != newcontroller && JoyInfo4.dev != newcontroller) // don't override a currently active device { - cv_usejoystick2.value = evt.jdevice.which + 1; + cv_usejoystick2.value = evt.cdevice.which + 1; I_UpdateJoystickDeviceIndices(2); } @@ -1010,10 +1038,10 @@ void I_GetEvent(void) // PLAYER 3 ////////////////////////////// - else if (newjoy && (!JoyInfo3.dev || !SDL_JoystickGetAttached(JoyInfo3.dev)) - && JoyInfo.dev != newjoy && JoyInfo2.dev != newjoy && JoyInfo4.dev != newjoy) // don't override a currently active device + else if (newcontroller && (!JoyInfo3.dev || !SDL_GameControllerGetAttached(JoyInfo3.dev)) + && JoyInfo.dev != newcontroller && JoyInfo2.dev != newcontroller && JoyInfo4.dev != newcontroller) // don't override a currently active device { - cv_usejoystick3.value = evt.jdevice.which + 1; + cv_usejoystick3.value = evt.cdevice.which + 1; I_UpdateJoystickDeviceIndices(3); } @@ -1021,10 +1049,10 @@ void I_GetEvent(void) // PLAYER 4 ////////////////////////////// - else if (newjoy && (!JoyInfo4.dev || !SDL_JoystickGetAttached(JoyInfo4.dev)) - && JoyInfo.dev != newjoy && JoyInfo2.dev != newjoy && JoyInfo3.dev != newjoy) // don't override a currently active device + else if (newcontroller && (!JoyInfo4.dev || !SDL_GameControllerGetAttached(JoyInfo4.dev)) + && JoyInfo.dev != newcontroller && JoyInfo2.dev != newcontroller && JoyInfo3.dev != newcontroller) // don't override a currently active device { - cv_usejoystick4.value = evt.jdevice.which + 1; + cv_usejoystick4.value = evt.cdevice.which + 1; I_UpdateJoystickDeviceIndices(4); } @@ -1079,33 +1107,33 @@ void I_GetEvent(void) if (currentMenu == &OP_JoystickSetDef) M_SetupJoystickMenu(0); - if (JoyInfo.dev != newjoy && JoyInfo2.dev != newjoy && JoyInfo3.dev != newjoy && JoyInfo4.dev != newjoy) - SDL_JoystickClose(newjoy); + if (JoyInfo.dev != newcontroller && JoyInfo2.dev != newcontroller && JoyInfo3.dev != newcontroller && JoyInfo4.dev != newcontroller) + SDL_GameControllerClose(newcontroller); } break; //////////////////////////////////////////////////////////// - case SDL_JOYDEVICEREMOVED: - if (JoyInfo.dev && !SDL_JoystickGetAttached(JoyInfo.dev)) + case SDL_CONTROLLERDEVICEREMOVED: + if (JoyInfo.dev && !SDL_GameControllerGetAttached(JoyInfo.dev)) { CONS_Debug(DBG_GAMELOGIC, "Joystick1 removed, device index: %d\n", JoyInfo.oldjoy); I_ShutdownJoystick(); } - if (JoyInfo2.dev && !SDL_JoystickGetAttached(JoyInfo2.dev)) + if (JoyInfo2.dev && !SDL_GameControllerGetAttached(JoyInfo2.dev)) { CONS_Debug(DBG_GAMELOGIC, "Joystick2 removed, device index: %d\n", JoyInfo2.oldjoy); I_ShutdownJoystick2(); } - if (JoyInfo3.dev && !SDL_JoystickGetAttached(JoyInfo3.dev)) + if (JoyInfo3.dev && !SDL_GameControllerGetAttached(JoyInfo3.dev)) { CONS_Debug(DBG_GAMELOGIC, "Joystick3 removed, device index: %d\n", JoyInfo3.oldjoy); I_ShutdownJoystick3(); } - if (JoyInfo4.dev && !SDL_JoystickGetAttached(JoyInfo4.dev)) + if (JoyInfo4.dev && !SDL_GameControllerGetAttached(JoyInfo4.dev)) { CONS_Debug(DBG_GAMELOGIC, "Joystick4 removed, device index: %d\n", JoyInfo4.oldjoy); I_ShutdownJoystick4(); @@ -1294,9 +1322,9 @@ void I_OsPolling(void) if (consolevent) I_GetConsoleEvents(); - if (SDL_WasInit(SDL_INIT_JOYSTICK) == SDL_INIT_JOYSTICK) + if (SDL_WasInit(SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER) == SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER) { - SDL_JoystickUpdate(); + SDL_GameControllerUpdate(); I_GetJoystickEvents(); I_GetJoystick2Events(); I_GetJoystick3Events(); diff --git a/src/sdl/sdlmain.h b/src/sdl/sdlmain.h index 0bc771a7..01edd866 100644 --- a/src/sdl/sdlmain.h +++ b/src/sdl/sdlmain.h @@ -40,8 +40,8 @@ extern SDL_bool framebuffer; */ typedef struct SDLJoyInfo_s { - /// Joystick handle - SDL_Joystick *dev; + /// Controller handle + SDL_GameController *dev; /// number of old joystick int oldjoy; /// number of axies @@ -57,7 +57,7 @@ typedef struct SDLJoyInfo_s } SDLJoyInfo_t; -/** \brief SDL info about joystick 1 +/** \brief SDL info about controller 1 */ extern SDLJoyInfo_t JoyInfo; @@ -66,15 +66,15 @@ extern SDLJoyInfo_t JoyInfo; #define SDL_JDEADZONE 153 #undef SDL_JDEADZONE -/** \brief SDL inof about joystick 2 +/** \brief SDL inof about controller 2 */ extern SDLJoyInfo_t JoyInfo2; -/** \brief SDL inof about joystick 3 +/** \brief SDL inof about controller 3 */ extern SDLJoyInfo_t JoyInfo3; -/** \brief SDL inof about joystick 4 +/** \brief SDL inof about controller 4 */ extern SDLJoyInfo_t JoyInfo4; @@ -86,8 +86,8 @@ void I_ShutdownJoystick2(void); void I_ShutdownJoystick3(void); void I_ShutdownJoystick4(void); -// Cheat to get the device index for a joystick handle -INT32 I_GetJoystickDeviceIndex(SDL_Joystick *dev); +// Cheat to get the device index for a game controller handle +INT32 I_GetJoystickDeviceIndex(SDL_GameController *dev); // Quick thing to make SDL_JOYDEVICEADDED events less of an abomination void I_UpdateJoystickDeviceIndices(INT32 player); From 08a218a3a144ced6bfaf71370c95b388efff8c03 Mon Sep 17 00:00:00 2001 From: Eidolon Date: Tue, 23 Aug 2022 19:48:42 -0500 Subject: [PATCH 02/10] Bump execversion to 10, remap xbox controls to SDL --- src/command.c | 46 +++++++++++++++++++++++++++++ src/doomdef.h | 2 +- src/g_game.c | 16 +++++----- src/g_input.c | 82 +++++++++++++++++++++++++++++++++------------------ 4 files changed, 109 insertions(+), 37 deletions(-) diff --git a/src/command.c b/src/command.c index 4e9d97aa..9804dbc0 100644 --- a/src/command.c +++ b/src/command.c @@ -1875,6 +1875,45 @@ static boolean CV_FilterJoyAxisVars(consvar_t *v, const char *valstr) return true; } +// Block the Xbox DInput default axes and reset to the current defaults +static boolean CV_FilterJoyAxisVars2(consvar_t *v, const char *valstr) +{ + if (!stricmp(v->name, "joyaxis_turn") && !stricmp(valstr, "X-Axis")) + return false; + if (!stricmp(v->name, "joyaxis2_turn") && !stricmp(valstr, "X-Axis")) + return false; + if (!stricmp(v->name, "joyaxis3_turn") && !stricmp(valstr, "X-Axis")) + return false; + if (!stricmp(v->name, "joyaxis4_turn") && !stricmp(valstr, "X-Axis")) + return false; + if (!stricmp(v->name, "joyaxis_aim") && !stricmp(valstr, "Y-Axis")) + return false; + if (!stricmp(v->name, "joyaxis2_aim") && !stricmp(valstr, "Y-Axis")) + return false; + if (!stricmp(v->name, "joyaxis3_aim") && !stricmp(valstr, "Y-Axis")) + return false; + if (!stricmp(v->name, "joyaxis4_aim") && !stricmp(valstr, "Y-Axis")) + return false; + if (!stricmp(v->name, "joyaxis_fire") && !stricmp(valstr, "None")) + return false; + if (!stricmp(v->name, "joyaxis2_fire") && !stricmp(valstr, "None")) + return false; + if (!stricmp(v->name, "joyaxis3_fire") && !stricmp(valstr, "None")) + return false; + if (!stricmp(v->name, "joyaxis4_fire") && !stricmp(valstr, "None")) + return false; + if (!stricmp(v->name, "joyaxis_drift") && !stricmp(valstr, "None")) + return false; + if (!stricmp(v->name, "joyaxis2_drift") && !stricmp(valstr, "None")) + return false; + if (!stricmp(v->name, "joyaxis3_drift") && !stricmp(valstr, "None")) + return false; + if (!stricmp(v->name, "joyaxis4_drift") && !stricmp(valstr, "None")) + return false; + + return true; +} + static boolean CV_FilterVarByVersion(consvar_t *v, const char *valstr) { // True means allow the CV change, False means block it @@ -1908,6 +1947,13 @@ static boolean CV_FilterVarByVersion(consvar_t *v, const char *valstr) return false; } + if (GETMAJOREXECVERSION(cv_execversion.value) < 10) // 10 = 1.6 + { + // axis defaults changed again to SDL game controllers + if (!CV_FilterJoyAxisVars2(v, valstr)) + return false; + } + return true; } diff --git a/src/doomdef.h b/src/doomdef.h index 070130cb..012b4926 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -204,7 +204,7 @@ extern char logfilename[1024]; // it's only for detection of the version the player is using so the MS can alert them of an update. // Only set it higher, not lower, obviously. // Note that we use this to help keep internal testing in check; this is why v2.1.0 is not version "1". -#define MODVERSION 9 +#define MODVERSION 10 // Filter consvars by version // To version config.cfg, MAJOREXECVERSION is set equal to MODVERSION automatically. diff --git a/src/g_game.c b/src/g_game.c index 1e97f08c..7d12bfb8 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -491,8 +491,8 @@ consvar_t cv_moveaxis = {"joyaxis_move", "None", CV_SAVE, joyaxis_cons_t, NULL, consvar_t cv_brakeaxis = {"joyaxis_brake", "None", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_aimaxis = {"joyaxis_aim", "Left Y", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_lookaxis = {"joyaxis_look", "None", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_fireaxis = {"joyaxis_fire", "None", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_driftaxis = {"joyaxis_drift", "None", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_fireaxis = {"joyaxis_fire", "L Trigger", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_driftaxis = {"joyaxis_drift", "R Trigger", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_xdeadzone = {"joy_xdeadzone", "0.3", CV_FLOAT|CV_SAVE, deadzone_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_ydeadzone = {"joy_ydeadzone", "0.5", CV_FLOAT|CV_SAVE, deadzone_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; @@ -501,8 +501,8 @@ consvar_t cv_moveaxis2 = {"joyaxis2_move", "None", CV_SAVE, joyaxis_cons_t, NULL consvar_t cv_brakeaxis2 = {"joyaxis2_brake", "None", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_aimaxis2 = {"joyaxis2_aim", "Left Y", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_lookaxis2 = {"joyaxis2_look", "None", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_fireaxis2 = {"joyaxis2_fire", "None", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_driftaxis2 = {"joyaxis2_drift", "None", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_fireaxis2 = {"joyaxis2_fire", "L Trigger", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_driftaxis2 = {"joyaxis2_drift", "R Trigger", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_xdeadzone2 = {"joy2_xdeadzone", "0.3", CV_FLOAT|CV_SAVE, deadzone_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_ydeadzone2 = {"joy2_ydeadzone", "0.5", CV_FLOAT|CV_SAVE, deadzone_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; @@ -511,8 +511,8 @@ consvar_t cv_moveaxis3 = {"joyaxis3_move", "None", CV_SAVE, joyaxis_cons_t, NULL consvar_t cv_brakeaxis3 = {"joyaxis3_brake", "None", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_aimaxis3 = {"joyaxis3_aim", "Left Y", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_lookaxis3 = {"joyaxis3_look", "None", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_fireaxis3 = {"joyaxis3_fire", "None", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_driftaxis3 = {"joyaxis3_drift", "None", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_fireaxis3 = {"joyaxis3_fire", "L Trigger", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_driftaxis3 = {"joyaxis3_drift", "R Trigger", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_xdeadzone3 = {"joy3_xdeadzone", "0.3", CV_FLOAT|CV_SAVE, deadzone_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_ydeadzone3 = {"joy3_ydeadzone", "0.5", CV_FLOAT|CV_SAVE, deadzone_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; @@ -521,8 +521,8 @@ consvar_t cv_moveaxis4 = {"joyaxis4_move", "None", CV_SAVE, joyaxis_cons_t, NULL consvar_t cv_brakeaxis4 = {"joyaxis4_brake", "None", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_aimaxis4 = {"joyaxis4_aim", "Left Y", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_lookaxis4 = {"joyaxis4_look", "None", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_fireaxis4 = {"joyaxis4_fire", "None", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_driftaxis4 = {"joyaxis4_drift", "None", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_fireaxis4 = {"joyaxis4_fire", "L Trigger", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_driftaxis4 = {"joyaxis4_drift", "R Trigger", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_xdeadzone4 = {"joy4_xdeadzone", "0.3", CV_FLOAT|CV_SAVE, deadzone_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_ydeadzone4 = {"joy4_ydeadzone", "0.5", CV_FLOAT|CV_SAVE, deadzone_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; diff --git a/src/g_input.c b/src/g_input.c index 08a323c7..dafbeca3 100644 --- a/src/g_input.c +++ b/src/g_input.c @@ -1308,8 +1308,8 @@ void G_Controldefault(UINT8 player) gamecontrol[gc_accelerate ][1] = KEY_JOY1+0; // A gamecontrol[gc_lookback ][1] = KEY_JOY1+2; // X gamecontrol[gc_brake ][1] = KEY_JOY1+1; // B - gamecontrol[gc_fire ][1] = KEY_JOY1+4; // LB - gamecontrol[gc_drift ][1] = KEY_JOY1+5; // RB + gamecontrol[gc_fire ][1] = KEY_JOY1+9; // LB + gamecontrol[gc_drift ][1] = KEY_JOY1+10; // RB // Extra controls gamecontrol[gc_pause ][0] = KEY_PAUSE; @@ -1328,8 +1328,8 @@ void G_Controldefault(UINT8 player) gamecontrol[gc_camtoggle ][0] = KEY_BACKSPACE; gamecontrol[gc_viewpoint ][1] = KEY_JOY1+3; // Y - gamecontrol[gc_pause ][1] = KEY_JOY1+6; // Back - gamecontrol[gc_systemmenu ][0] = KEY_JOY1+7; // Start + gamecontrol[gc_pause ][1] = KEY_JOY1+4; // Back + gamecontrol[gc_systemmenu ][0] = KEY_JOY1+6; // Start //gamecontrol[gc_camtoggle ][1] = KEY_HAT1+0; // D-Pad Up //gamecontrol[gc_screenshot ][1] = KEY_HAT1+1; // D-Pad Down // absolutely fucking NOT gamecontrol[gc_talkkey ][1] = KEY_HAT1+1; // D-Pad Down @@ -1342,8 +1342,8 @@ void G_Controldefault(UINT8 player) gamecontrolbis[gc_accelerate ][0] = KEY_2JOY1+0; // A gamecontrolbis[gc_lookback ][0] = KEY_2JOY1+2; // X gamecontrolbis[gc_brake ][0] = KEY_2JOY1+1; // B - gamecontrolbis[gc_fire ][0] = KEY_2JOY1+4; // LB - gamecontrolbis[gc_drift ][0] = KEY_2JOY1+5; // RB + gamecontrolbis[gc_fire ][0] = KEY_2JOY1+9; // LB + gamecontrolbis[gc_drift ][0] = KEY_2JOY1+10; // RB } if (player == 0 || player == 3) @@ -1352,8 +1352,8 @@ void G_Controldefault(UINT8 player) gamecontrol3[gc_accelerate ][0] = KEY_3JOY1+0; // A gamecontrol3[gc_lookback ][0] = KEY_3JOY1+2; // X gamecontrol3[gc_brake ][0] = KEY_3JOY1+1; // B - gamecontrol3[gc_fire ][0] = KEY_3JOY1+4; // LB - gamecontrol3[gc_drift ][0] = KEY_3JOY1+5; // RB + gamecontrol3[gc_fire ][0] = KEY_3JOY1+9; // LB + gamecontrol3[gc_drift ][0] = KEY_3JOY1+10; // RB } if (player == 0 || player == 4) @@ -1362,8 +1362,8 @@ void G_Controldefault(UINT8 player) gamecontrol4[gc_accelerate ][0] = KEY_4JOY1+0; // A gamecontrol4[gc_lookback ][0] = KEY_4JOY1+2; // X gamecontrol4[gc_brake ][0] = KEY_4JOY1+1; // B - gamecontrol4[gc_fire ][0] = KEY_4JOY1+4; // LB - gamecontrol4[gc_drift ][0] = KEY_4JOY1+5; // RB + gamecontrol4[gc_fire ][0] = KEY_4JOY1+9; // LB + gamecontrol4[gc_drift ][0] = KEY_4JOY1+10; // RB } } @@ -1452,25 +1452,51 @@ INT32 G_CheckDoubleUsage(INT32 keynum, boolean modify) static INT32 G_FilterKeyByVersion(INT32 numctrl, INT32 keyidx, INT32 player, INT32 *keynum1, INT32 *keynum2, boolean *nestedoverride) { - // Special case: ignore KEY_PAUSE because it's hardcoded - if (keyidx == 0 && *keynum1 == KEY_PAUSE) - { - if (*keynum2 != KEY_PAUSE) - { - *keynum1 = *keynum2; // shift down keynum2 and continue - *keynum2 = 0; - } - else - return -1; // skip setting control - } - else if (keyidx == 1 && *keynum2 == KEY_PAUSE) - return -1; // skip setting control - -#if 1 - // We don't have changed control defaults yet - (void)numctrl; - (void)player; +#if 1 // SRB2Kart filters/migrations (void)nestedoverride; + + // Migration: 1.6 (majorexec 10) Joystick Defaults changed to use SDL Game Controllers + if (GETMAJOREXECVERSION(cv_execversion.value) < 10) + { + INT32 joybuttonbase = KEY_JOY1; + + switch (player) + { + case 0: + joybuttonbase = KEY_JOY1; + break; + case 1: + joybuttonbase = KEY_2JOY1; + break; + case 2: + joybuttonbase = KEY_3JOY1; + break; + case 3: + joybuttonbase = KEY_4JOY1; + break; + } + + // The face buttons match, so we don't need to rebind those. + + if (keyidx == 1 && numctrl == gc_fire && *keynum2 == joybuttonbase + 4) // Xbox DInput LB + { + *keynum2 = joybuttonbase + 9; // SDL LEFTSHOULDER + } + if (keyidx == 1 && numctrl == gc_drift && *keynum2 == joybuttonbase + 5) // Xbox DInput RB + { + *keynum2 = joybuttonbase + 10; // SDL RIGHTSHOULDER + } + + // Pause and Systemmenu are only bound for P1 + if (keyidx == 1 && player == 0 && numctrl == gc_pause && *keynum2 == joybuttonbase + 6) // Xbox DInput Back + { + *keynum2 = joybuttonbase + 4; // SDL BACK + } + if (keyidx == 0 && player == 0 && numctrl == gc_systemmenu && *keynum1 == joybuttonbase + 7) // Xbox DInput Start + { + *keynum1 = joybuttonbase + 6; // SDL START + } + } #else #if !defined (DC) && !defined (_PSP) && !defined (GP2X) && !defined (_NDS) && !defined(WMINPUT) && !defined(_WII) if (GETMAJOREXECVERSION(cv_execversion.value) < 27 && ( // v2.1.22 From f167895865efd6463a7abdc719aef410bb67ed1d Mon Sep 17 00:00:00 2001 From: toaster Date: Thu, 25 Aug 2022 20:13:29 +0100 Subject: [PATCH 03/10] Fix compilation warnings and non-codebase-standard types Also, make the I_GetJoystickEvents functions match each other --- src/sdl/i_system.c | 28 +++++++++++++--------------- src/sdl/i_video.c | 16 ++++++++-------- 2 files changed, 21 insertions(+), 23 deletions(-) diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index 23729503..cc3a37e6 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -1155,10 +1155,11 @@ void I_GetJoystickEvents(void) UINT64 joyhats = 0; #if 0 UINT64 joybuttons = 0; - Sint16 axisx, axisy; + UINT32 axisx, axisy; #endif - if (!joystick_started) return; + if (!joystick_started) + return; if (!JoyInfo.dev) //I_ShutdownJoystick(); return; @@ -1233,12 +1234,10 @@ void I_GetJoystickEvents(void) axisy = SDL_JoystickGetAxis(JoyInfo.dev, i*2 + 1); else axisy = 0; - // -32768 to 32767 axisx = axisx/32; axisy = axisy/32; - if (Joystick.bGamepadStyle) { // gamepad control type, on or off, live or die @@ -1246,12 +1245,14 @@ void I_GetJoystickEvents(void) event.data2 = -1; else if (axisx > (JOYAXISRANGE/2)) event.data2 = 1; - else event.data2 = 0; + else + event.data2 = 0; if (axisy < -(JOYAXISRANGE/2)) event.data3 = -1; else if (axisy > (JOYAXISRANGE/2)) event.data3 = 1; - else event.data3 = 0; + else + event.data3 = 0; } else { @@ -1424,8 +1425,8 @@ void I_GetJoystick2Events(void) INT32 i = 0; UINT64 joyhats = 0; #if 0 - INT64 joybuttons = 0; - INT32 axisx, axisy; + UINT64 joybuttons = 0; + UINT32 axisx, axisy; #endif if (!joystick2_started) @@ -1434,7 +1435,6 @@ void I_GetJoystick2Events(void) if (!JoyInfo2.dev) //I_ShutdownJoystick2(); return; - #if 0 //faB: look for as much buttons as g_input code supports, // we don't use the others @@ -1696,9 +1696,9 @@ void I_GetJoystick3Events(void) INT32 i = 0; UINT64 joyhats = 0; #if 0 - INT64 joybuttons = 0; + UINT64 joybuttons = 0; + UINT32 axisx, axisy; #endif - INT32 axisx, axisy; if (!joystick3_started) return; @@ -1706,7 +1706,6 @@ void I_GetJoystick3Events(void) if (!JoyInfo3.dev) //I_ShutdownJoystick3(); return; - #if 0 //faB: look for as much buttons as g_input code supports, // we don't use the others @@ -1968,9 +1967,9 @@ void I_GetJoystick4Events(void) INT32 i = 0; UINT64 joyhats = 0; #if 0 - INT64 joybuttons = 0; + UINT64 joybuttons = 0; + UINT32 axisx, axisy; #endif - INT32 axisx, axisy; if (!joystick4_started) return; @@ -1978,7 +1977,6 @@ void I_GetJoystick4Events(void) if (!JoyInfo4.dev) //I_ShutdownJoystick4(); return; - #if 0 //faB: look for as much buttons as g_input code supports, // we don't use the others diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index b3771eba..05cb385e 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -792,7 +792,7 @@ static void Impl_HandleControllerAxisEvent(SDL_ControllerAxisEvent evt) { event_t event; SDL_JoystickID joyid[4]; - int32_t value; + INT32 value; // Determine the Joystick IDs for each current open joystick joyid[0] = SDL_JoystickInstanceID(SDL_GameControllerGetJoystick(JoyInfo.dev)); @@ -828,27 +828,27 @@ static void Impl_HandleControllerAxisEvent(SDL_ControllerAxisEvent evt) { case SDL_CONTROLLER_AXIS_LEFTX: event.data1 = 0; - event.data2 = SDLJoyAxis(evt.value, event.type); + event.data2 = value; break; case SDL_CONTROLLER_AXIS_LEFTY: event.data1 = 0; - event.data3 = SDLJoyAxis(evt.value, event.type); + event.data3 = value; break; case SDL_CONTROLLER_AXIS_RIGHTX: event.data1 = 1; - event.data2 = SDLJoyAxis(evt.value, event.type); + event.data2 = value; break; case SDL_CONTROLLER_AXIS_RIGHTY: event.data1 = 1; - event.data3 = SDLJoyAxis(evt.value, event.type); + event.data3 = value; break; case SDL_CONTROLLER_AXIS_TRIGGERLEFT: event.data1 = 2; - event.data2 = SDLJoyAxis(evt.value, event.type); + event.data2 = value; break; case SDL_CONTROLLER_AXIS_TRIGGERRIGHT: event.data1 = 2; - event.data3 = SDLJoyAxis(evt.value, event.type); + event.data3 = value; break; default: return; @@ -1322,7 +1322,7 @@ void I_OsPolling(void) if (consolevent) I_GetConsoleEvents(); - if (SDL_WasInit(SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER) == SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER) + if (SDL_WasInit(SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER) == (SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER)) { SDL_GameControllerUpdate(); I_GetJoystickEvents(); From 3ef3789f58270a89c7a046a17654a1b022d84c13 Mon Sep 17 00:00:00 2001 From: toaster Date: Fri, 26 Aug 2022 19:09:46 +0100 Subject: [PATCH 04/10] Gamepad improvements for menus * For left stick up/down/left/right input, allow holding a direction down to move continuously in a direction at a rate of 7 steps per second per axis * Now supports accel axis being used for the Enter key/"accept" in menus, to mirror how an accel BUTTON bind will be used as an Enter event. --- src/m_menu.c | 97 +++++++++++++++++++++++++++++++++++----------------- 1 file changed, 66 insertions(+), 31 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index 2fd5bc21..29585827 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -2517,8 +2517,8 @@ boolean M_Responder(event_t *ev) { INT32 ch = -1; // INT32 i; - static tic_t joywait = 0, mousewait = 0; - static INT32 pjoyx = 0, pjoyy = 0; + static tic_t joywaitx = 0, joywaity = 0, joywaitaccel = 0, mousewait = 0; + static INT32 pjoyx = 0, pjoyy = 0, pjoyaccel = 0; static INT32 pmousex = 0, pmousey = 0; static INT32 lastx = 0, lasty = 0; void (*routine)(INT32 choice); // for some casting problem @@ -2569,48 +2569,83 @@ boolean M_Responder(event_t *ev) } else if (menuactive) { - if (ev->type == ev_joystick && ev->data1 == 0 && joywait < I_GetTime()) + tic_t thistime = I_GetTime(); + if (ev->type == ev_joystick) { const INT32 jxdeadzone = ((JOYAXISRANGE-1) * max(cv_xdeadzone.value, FRACUNIT/2)) >> FRACBITS; const INT32 jydeadzone = ((JOYAXISRANGE-1) * max(cv_ydeadzone.value, FRACUNIT/2)) >> FRACBITS; - if (ev->data3 != INT32_MAX) + INT32 accelaxis = abs(cv_moveaxis.value); + if (ev->data1 == 0) { - if (Joystick.bGamepadStyle || abs(ev->data3) > jydeadzone) + if (ev->data3 != INT32_MAX) { - if (ev->data3 < 0 && pjoyy >= 0) + if (Joystick.bGamepadStyle || abs(ev->data3) > jydeadzone) { - ch = KEY_UPARROW; - joywait = I_GetTime() + NEWTICRATE/7; + if (joywaity < thistime) + { + ch = (ev->data3 < 0) ? KEY_UPARROW : KEY_DOWNARROW; + joywaity = thistime; + if (pjoyy == 0 // no previous input? + || ((ev->data3 < 0) == (pjoyy < 0))) // same direction as the current one? + joywaity += NEWTICRATE/7; + } + pjoyy = ev->data3; } - else if (ev->data3 > 0 && pjoyy <= 0) - { - ch = KEY_DOWNARROW; - joywait = I_GetTime() + NEWTICRATE/7; - } - pjoyy = ev->data3; + else + pjoyy = 0; } - else - pjoyy = 0; - } - if (ev->data2 != INT32_MAX) - { - if (Joystick.bGamepadStyle || abs(ev->data2) > jxdeadzone) + if (ev->data2 != INT32_MAX && joywaitx < thistime) { - if (ev->data2 < 0 && pjoyx >= 0) + if (Joystick.bGamepadStyle || abs(ev->data2) > jxdeadzone) { - ch = KEY_LEFTARROW; - joywait = I_GetTime() + NEWTICRATE/17; + if (joywaity < thistime) + { + ch = (ev->data2 < 0) ? KEY_LEFTARROW : KEY_RIGHTARROW; + joywaity = thistime; + if (pjoyx == 0 // no previous input? + || ((ev->data2 < 0) == (pjoyx < 0))) // same direction as the current one? + joywaity += NEWTICRATE/7; + } + pjoyx = ev->data2; + } + else + pjoyx = 0; + } + } + else if (!(accelaxis > JOYAXISSET*2 || accelaxis == 0)) + { + // The following borrows heavily from Joy1Axis. + const boolean xmode = (accelaxis%2); + INT32 retaxis = 0; + if (!xmode) + accelaxis--; + accelaxis /= 2; + if (ev->data1 == accelaxis) + { + const INT32 jacceldeadzone = xmode ? jxdeadzone : jydeadzone; + retaxis = xmode ? ev->data2 : ev->data3; + if (retaxis != INT32_MAX) + { + if (cv_moveaxis.value < 0) + retaxis = -retaxis; + + if (Joystick.bGamepadStyle || abs(retaxis) > jacceldeadzone) + { + if (joywaitaccel < thistime) + { + ch = KEY_ENTER; + joywaitaccel = thistime; + if (pjoyaccel == 0 // no previous input? + || ((retaxis < 0) == (pjoyaccel > 0))) // same direction as the current one? + joywaitaccel += NEWTICRATE/3; + } + pjoyaccel = retaxis; + } + else + pjoyaccel = 0; } - else if (ev->data2 > 0 && pjoyx <= 0) - { - ch = KEY_RIGHTARROW; - joywait = I_GetTime() + NEWTICRATE/17; - } - pjoyx = ev->data2; } - else - pjoyx = 0; } } else if (ev->type == ev_mouse && mousewait < I_GetTime()) From 44eeb3a0f380f81a6e61d01eda2762160ff1ec4d Mon Sep 17 00:00:00 2001 From: toaster Date: Fri, 26 Aug 2022 19:44:00 +0100 Subject: [PATCH 05/10] Remove game deadzone for Accel/Brake - They're binary inputs as processed by the game. - A mechanism for binary inputs with no deadzone is already used for item and drift. - Generally bound to triggers, not the stick. - SDL still has a minimum deadzone, so won't fire endlessly. --- src/g_game.h | 4 ++-- src/m_menu.c | 20 +++++++------------- 2 files changed, 9 insertions(+), 15 deletions(-) diff --git a/src/g_game.h b/src/g_game.h index 0dcc69c3..410577da 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -128,11 +128,11 @@ typedef enum { AXISNONE = 0, AXISTURN, - AXISMOVE, - AXISBRAKE, AXISAIM, AXISLOOK, AXISDEAD, //Axises that don't want deadzones + AXISMOVE, + AXISBRAKE, AXISFIRE, AXISDRIFT, } axis_input_e; diff --git a/src/m_menu.c b/src/m_menu.c index 29585827..4519a6a8 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -2623,27 +2623,21 @@ boolean M_Responder(event_t *ev) accelaxis /= 2; if (ev->data1 == accelaxis) { - const INT32 jacceldeadzone = xmode ? jxdeadzone : jydeadzone; retaxis = xmode ? ev->data2 : ev->data3; if (retaxis != INT32_MAX) { if (cv_moveaxis.value < 0) retaxis = -retaxis; - if (Joystick.bGamepadStyle || abs(retaxis) > jacceldeadzone) + if (joywaitaccel < thistime && (abs(retaxis) >= abs(pjoyaccel))) // only on upwards event { - if (joywaitaccel < thistime) - { - ch = KEY_ENTER; - joywaitaccel = thistime; - if (pjoyaccel == 0 // no previous input? - || ((retaxis < 0) == (pjoyaccel > 0))) // same direction as the current one? - joywaitaccel += NEWTICRATE/3; - } - pjoyaccel = retaxis; + ch = KEY_ENTER; + joywaitaccel = thistime; + if (pjoyaccel == 0 // no previous input? + || ((retaxis < 0) == (pjoyaccel < 0))) // same direction as the current one? + joywaitaccel += NEWTICRATE/3; } - else - pjoyaccel = 0; + pjoyaccel = retaxis; } } } From 9e194dab2d306f4879fa3bb2db0455d048f830b5 Mon Sep 17 00:00:00 2001 From: toaster Date: Fri, 26 Aug 2022 20:42:21 +0100 Subject: [PATCH 06/10] Add cv_lookbackaxis (and p2-4 equivalents) * Rename `Look Up/Down` to `Spec. Look Up/Down` to disambiguate from `Look Backward` * Make it support multiplayer replay recording save request too --- src/d_netcmd.c | 4 ++++ src/g_game.c | 21 ++++++++++++++++++--- src/g_game.h | 9 +++++---- src/m_menu.c | 28 ++++++++++++++++++---------- src/p_tick.c | 4 +++- src/y_inter.c | 4 +++- 6 files changed, 51 insertions(+), 19 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 057bdf2a..8404295e 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -912,6 +912,10 @@ void D_RegisterClientCommands(void) CV_RegisterVar(&cv_driftaxis2); CV_RegisterVar(&cv_driftaxis3); CV_RegisterVar(&cv_driftaxis4); + CV_RegisterVar(&cv_lookbackaxis); + CV_RegisterVar(&cv_lookbackaxis2); + CV_RegisterVar(&cv_lookbackaxis3); + CV_RegisterVar(&cv_lookbackaxis4); CV_RegisterVar(&cv_xdeadzone); CV_RegisterVar(&cv_ydeadzone); CV_RegisterVar(&cv_xdeadzone2); diff --git a/src/g_game.c b/src/g_game.c index 7d12bfb8..436ec14d 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -493,6 +493,7 @@ consvar_t cv_aimaxis = {"joyaxis_aim", "Left Y", CV_SAVE, joyaxis_cons_t, NULL, consvar_t cv_lookaxis = {"joyaxis_look", "None", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_fireaxis = {"joyaxis_fire", "L Trigger", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_driftaxis = {"joyaxis_drift", "R Trigger", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_lookbackaxis = {"joyaxis_lookback", "None", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_xdeadzone = {"joy_xdeadzone", "0.3", CV_FLOAT|CV_SAVE, deadzone_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_ydeadzone = {"joy_ydeadzone", "0.5", CV_FLOAT|CV_SAVE, deadzone_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; @@ -503,6 +504,7 @@ consvar_t cv_aimaxis2 = {"joyaxis2_aim", "Left Y", CV_SAVE, joyaxis_cons_t, NULL consvar_t cv_lookaxis2 = {"joyaxis2_look", "None", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_fireaxis2 = {"joyaxis2_fire", "L Trigger", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_driftaxis2 = {"joyaxis2_drift", "R Trigger", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_lookbackaxis2 = {"joyaxis2_lookback", "None", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_xdeadzone2 = {"joy2_xdeadzone", "0.3", CV_FLOAT|CV_SAVE, deadzone_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_ydeadzone2 = {"joy2_ydeadzone", "0.5", CV_FLOAT|CV_SAVE, deadzone_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; @@ -513,6 +515,7 @@ consvar_t cv_aimaxis3 = {"joyaxis3_aim", "Left Y", CV_SAVE, joyaxis_cons_t, NULL consvar_t cv_lookaxis3 = {"joyaxis3_look", "None", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_fireaxis3 = {"joyaxis3_fire", "L Trigger", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_driftaxis3 = {"joyaxis3_drift", "R Trigger", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_lookbackaxis3 = {"joyaxis3_lookback", "None", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_xdeadzone3 = {"joy3_xdeadzone", "0.3", CV_FLOAT|CV_SAVE, deadzone_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_ydeadzone3 = {"joy3_ydeadzone", "0.5", CV_FLOAT|CV_SAVE, deadzone_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; @@ -523,6 +526,7 @@ consvar_t cv_aimaxis4 = {"joyaxis4_aim", "Left Y", CV_SAVE, joyaxis_cons_t, NULL consvar_t cv_lookaxis4 = {"joyaxis4_look", "None", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_fireaxis4 = {"joyaxis4_fire", "L Trigger", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_driftaxis4 = {"joyaxis4_drift", "R Trigger", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_lookbackaxis4 = {"joyaxis4_lookback", "None", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_xdeadzone4 = {"joy4_xdeadzone", "0.3", CV_FLOAT|CV_SAVE, deadzone_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_ydeadzone4 = {"joy4_ydeadzone", "0.5", CV_FLOAT|CV_SAVE, deadzone_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; @@ -910,6 +914,9 @@ static INT32 Joy1Axis(axis_input_e axissel) case AXISDRIFT: axisval = cv_driftaxis.value; break; + case AXISLOOKBACK: + axisval = cv_lookbackaxis.value; + break; default: return 0; } @@ -1003,11 +1010,13 @@ static INT32 Joy2Axis(axis_input_e axissel) case AXISDRIFT: axisval = cv_driftaxis2.value; break; + case AXISLOOKBACK: + axisval = cv_lookbackaxis2.value; + break; default: return 0; } - if (axisval < 0) //odd -axises { axisval = -axisval; @@ -1099,11 +1108,13 @@ static INT32 Joy3Axis(axis_input_e axissel) case AXISDRIFT: axisval = cv_driftaxis3.value; break; + case AXISLOOKBACK: + axisval = cv_lookbackaxis3.value; + break; default: return 0; } - if (axisval < 0) //odd -axises { axisval = -axisval; @@ -1195,6 +1206,9 @@ static INT32 Joy4Axis(axis_input_e axissel) case AXISDRIFT: axisval = cv_driftaxis4.value; break; + case AXISLOOKBACK: + axisval = cv_lookbackaxis4.value; + break; default: return 0; } @@ -1645,7 +1659,8 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) keyboard_look[ssplayer-1] = kbl; turnheld[ssplayer-1] = th; resetdown[ssplayer-1] = rd; - camspin[ssplayer-1] = InputDown(gc_lookback, ssplayer); + axis = JoyAxis(AXISLOOKBACK, ssplayer); + camspin[ssplayer-1] = (InputDown(gc_lookback, ssplayer) || (usejoystick && axis > 0)); } /* Lua: Allow this hook to overwrite ticcmd. diff --git a/src/g_game.h b/src/g_game.h index 410577da..ead5b7ae 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -118,10 +118,10 @@ extern consvar_t cv_invertmouse/*, cv_alwaysfreelook, cv_chasefreelook, cv_mouse extern consvar_t cv_invertmouse2/*, cv_alwaysfreelook2, cv_chasefreelook2, cv_mousemove2*/; extern consvar_t cv_useranalog, cv_useranalog2, cv_useranalog3, cv_useranalog4; extern consvar_t cv_analog, cv_analog2, cv_analog3, cv_analog4; -extern consvar_t cv_turnaxis,cv_moveaxis,cv_brakeaxis,cv_aimaxis,cv_lookaxis,cv_fireaxis,cv_driftaxis,cv_xdeadzone,cv_ydeadzone; -extern consvar_t cv_turnaxis2,cv_moveaxis2,cv_brakeaxis2,cv_aimaxis2,cv_lookaxis2,cv_fireaxis2,cv_driftaxis2,cv_xdeadzone2,cv_ydeadzone2; -extern consvar_t cv_turnaxis3,cv_moveaxis3,cv_brakeaxis3,cv_aimaxis3,cv_lookaxis3,cv_fireaxis3,cv_driftaxis3,cv_xdeadzone3,cv_ydeadzone3; -extern consvar_t cv_turnaxis4,cv_moveaxis4,cv_brakeaxis4,cv_aimaxis4,cv_lookaxis4,cv_fireaxis4,cv_driftaxis4,cv_xdeadzone4,cv_ydeadzone4; +extern consvar_t cv_turnaxis,cv_moveaxis,cv_brakeaxis,cv_aimaxis,cv_lookaxis,cv_fireaxis,cv_driftaxis,cv_lookbackaxis,cv_xdeadzone,cv_ydeadzone; +extern consvar_t cv_turnaxis2,cv_moveaxis2,cv_brakeaxis2,cv_aimaxis2,cv_lookaxis2,cv_fireaxis2,cv_driftaxis2,cv_lookbackaxis2,cv_xdeadzone2,cv_ydeadzone2; +extern consvar_t cv_turnaxis3,cv_moveaxis3,cv_brakeaxis3,cv_aimaxis3,cv_lookaxis3,cv_fireaxis3,cv_driftaxis3,cv_lookbackaxis3,cv_xdeadzone3,cv_ydeadzone3; +extern consvar_t cv_turnaxis4,cv_moveaxis4,cv_brakeaxis4,cv_aimaxis4,cv_lookaxis4,cv_fireaxis4,cv_driftaxis4,cv_lookbackaxis4,cv_xdeadzone4,cv_ydeadzone4; extern consvar_t cv_ghost_besttime, cv_ghost_bestlap, cv_ghost_last, cv_ghost_guest, cv_ghost_staff; typedef enum @@ -135,6 +135,7 @@ typedef enum AXISBRAKE, AXISFIRE, AXISDRIFT, + AXISLOOKBACK, } axis_input_e; // mouseaiming (looking up/down with the mouse or keyboard) diff --git a/src/m_menu.c b/src/m_menu.c index 4519a6a8..3adbd172 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -1163,9 +1163,10 @@ static menuitem_t OP_Joystick1Menu[] = {IT_STRING | IT_CVAR, NULL, "Brake" , &cv_brakeaxis , 60}, {IT_STRING | IT_CVAR, NULL, "Drift" , &cv_driftaxis , 70}, {IT_STRING | IT_CVAR, NULL, "Use Item" , &cv_fireaxis , 80}, - {IT_STRING | IT_CVAR, NULL, "Look Up/Down" , &cv_lookaxis , 90}, - {IT_STRING | IT_CVAR, NULL, "X deadzone" , &cv_xdeadzone , 110}, - {IT_STRING | IT_CVAR, NULL, "Y deadzone" , &cv_ydeadzone , 120}, + {IT_STRING | IT_CVAR, NULL, "Look Backward" , &cv_lookbackaxis , 90}, + {IT_STRING | IT_CVAR, NULL, "Spec. Look Up/Down" , &cv_lookaxis , 100}, + {IT_STRING | IT_CVAR, NULL, "X deadzone" , &cv_xdeadzone , 120}, + {IT_STRING | IT_CVAR, NULL, "Y deadzone" , &cv_ydeadzone , 130}, }; static menuitem_t OP_Joystick2Menu[] = @@ -1177,9 +1178,10 @@ static menuitem_t OP_Joystick2Menu[] = {IT_STRING | IT_CVAR, NULL, "Brake" , &cv_brakeaxis2 , 60}, {IT_STRING | IT_CVAR, NULL, "Drift" , &cv_driftaxis2 , 70}, {IT_STRING | IT_CVAR, NULL, "Use Item" , &cv_fireaxis2 , 80}, - {IT_STRING | IT_CVAR, NULL, "Look Up/Down" , &cv_lookaxis2 , 90}, - {IT_STRING | IT_CVAR, NULL, "X deadzone" , &cv_xdeadzone2 , 110}, - {IT_STRING | IT_CVAR, NULL, "Y deadzone" , &cv_ydeadzone2 , 120}, + {IT_STRING | IT_CVAR, NULL, "Look Backward" , &cv_lookbackaxis2 , 90}, + {IT_STRING | IT_CVAR, NULL, "Spec. Look Up/Down" , &cv_lookaxis2 , 100}, + {IT_STRING | IT_CVAR, NULL, "X deadzone" , &cv_xdeadzone2 , 120}, + {IT_STRING | IT_CVAR, NULL, "Y deadzone" , &cv_ydeadzone2 , 130}, }; static menuitem_t OP_Joystick3Menu[] = @@ -1191,9 +1193,10 @@ static menuitem_t OP_Joystick3Menu[] = {IT_STRING | IT_CVAR, NULL, "Brake" , &cv_brakeaxis3 , 60}, {IT_STRING | IT_CVAR, NULL, "Drift" , &cv_driftaxis3 , 70}, {IT_STRING | IT_CVAR, NULL, "Use Item" , &cv_fireaxis3 , 80}, - {IT_STRING | IT_CVAR, NULL, "Look Up/Down" , &cv_lookaxis3 , 90}, - {IT_STRING | IT_CVAR, NULL, "X DeadZone" , &cv_xdeadzone3 , 110}, - {IT_STRING | IT_CVAR, NULL, "Y DeadZone" , &cv_ydeadzone3 , 120}, + {IT_STRING | IT_CVAR, NULL, "Look Backward" , &cv_lookbackaxis3 , 90}, + {IT_STRING | IT_CVAR, NULL, "Spec. Look Up/Down" , &cv_lookaxis3 , 100}, + {IT_STRING | IT_CVAR, NULL, "X deadzone" , &cv_xdeadzone3 , 120}, + {IT_STRING | IT_CVAR, NULL, "Y deadzone" , &cv_ydeadzone3 , 130}, }; static menuitem_t OP_Joystick4Menu[] = @@ -1205,7 +1208,8 @@ static menuitem_t OP_Joystick4Menu[] = {IT_STRING | IT_CVAR, NULL, "Brake" , &cv_brakeaxis4 , 60}, {IT_STRING | IT_CVAR, NULL, "Drift" , &cv_driftaxis4 , 70}, {IT_STRING | IT_CVAR, NULL, "Use Item" , &cv_fireaxis4 , 80}, - {IT_STRING | IT_CVAR, NULL, "Look Up/Down" , &cv_lookaxis4 , 90}, + {IT_STRING | IT_CVAR, NULL, "Look Backward" , &cv_lookbackaxis4 , 90}, + {IT_STRING | IT_CVAR, NULL, "Spec. Look Up/Down" , &cv_lookaxis4 , 100}, {IT_STRING | IT_CVAR, NULL, "X deadzone" , &cv_xdeadzone4 , 110}, {IT_STRING | IT_CVAR, NULL, "Y deadzone" , &cv_ydeadzone4 , 120}, }; @@ -10711,6 +10715,7 @@ static void M_ResetControlsResponse(INT32 ch) CV_StealthSet(&cv_lookaxis4, cv_lookaxis4.defaultvalue); CV_StealthSet(&cv_fireaxis4, cv_fireaxis4.defaultvalue); CV_StealthSet(&cv_driftaxis4, cv_driftaxis4.defaultvalue); + CV_StealthSet(&cv_lookbackaxis4, cv_lookbackaxis4.defaultvalue); break; case 3: CV_StealthSet(&cv_usejoystick3, cv_usejoystick3.defaultvalue); @@ -10721,6 +10726,7 @@ static void M_ResetControlsResponse(INT32 ch) CV_StealthSet(&cv_lookaxis3, cv_lookaxis3.defaultvalue); CV_StealthSet(&cv_fireaxis3, cv_fireaxis3.defaultvalue); CV_StealthSet(&cv_driftaxis3, cv_driftaxis3.defaultvalue); + CV_StealthSet(&cv_lookbackaxis3, cv_lookbackaxis3.defaultvalue); break; case 2: CV_StealthSet(&cv_usejoystick2, cv_usejoystick2.defaultvalue); @@ -10731,6 +10737,7 @@ static void M_ResetControlsResponse(INT32 ch) CV_StealthSet(&cv_lookaxis2, cv_lookaxis2.defaultvalue); CV_StealthSet(&cv_fireaxis2, cv_fireaxis2.defaultvalue); CV_StealthSet(&cv_driftaxis2, cv_driftaxis2.defaultvalue); + CV_StealthSet(&cv_lookbackaxis2, cv_lookbackaxis2.defaultvalue); break; case 1: default: @@ -10742,6 +10749,7 @@ static void M_ResetControlsResponse(INT32 ch) CV_StealthSet(&cv_lookaxis, cv_lookaxis.defaultvalue); CV_StealthSet(&cv_fireaxis, cv_fireaxis.defaultvalue); CV_StealthSet(&cv_driftaxis, cv_driftaxis.defaultvalue); + CV_StealthSet(&cv_lookbackaxis, cv_lookbackaxis.defaultvalue); break; } diff --git a/src/p_tick.c b/src/p_tick.c index e79bf1b5..0005aeb0 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -770,10 +770,12 @@ void P_Ticker(boolean run) if (demo.recording) { + INT32 axis = JoyAxis(AXISLOOKBACK, 1); + G_WriteAllGhostTics(); if (cv_recordmultiplayerdemos.value && (demo.savemode == DSM_NOTSAVING || demo.savemode == DSM_WILLAUTOSAVE)) - if (demo.savebutton && demo.savebutton + 3*TICRATE < leveltime && InputDown(gc_lookback, 1)) + if (demo.savebutton && demo.savebutton + 3*TICRATE < leveltime && (InputDown(gc_lookback, 1) || (cv_usejoystick.value && axis > 0))) demo.savemode = DSM_TITLEENTRY; } else if (demo.playback) // Use Ghost data for consistency checks. diff --git a/src/y_inter.c b/src/y_inter.c index 46dee64a..f14c26f1 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -608,7 +608,9 @@ void Y_Ticker(void) if (demo.recording) { - if (demo.savemode == DSM_NOTSAVING && InputDown(gc_lookback, 1)) + INT32 axis = JoyAxis(AXISLOOKBACK, 1); + + if (demo.savemode == DSM_NOTSAVING && (InputDown(gc_lookback, 1) || (cv_usejoystick.value && axis > 0))) demo.savemode = DSM_TITLEENTRY; if (demo.savemode == DSM_WILLSAVE || demo.savemode == DSM_WILLAUTOSAVE) From b10c21c504bcb3eacf2482785c72d383facfb35f Mon Sep 17 00:00:00 2001 From: toaster Date: Fri, 26 Aug 2022 21:00:39 +0100 Subject: [PATCH 07/10] Only use positive component of accel axis for menu KEY_ENTER behaviour --- src/m_menu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/m_menu.c b/src/m_menu.c index 3adbd172..1dbe458e 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -2633,7 +2633,7 @@ boolean M_Responder(event_t *ev) if (cv_moveaxis.value < 0) retaxis = -retaxis; - if (joywaitaccel < thistime && (abs(retaxis) >= abs(pjoyaccel))) // only on upwards event + if (joywaitaccel < thistime && retaxis >= pjoyaccel) // only on upwards event { ch = KEY_ENTER; joywaitaccel = thistime; From de97c41532becc25367f2c33130c0783fc42fca8 Mon Sep 17 00:00:00 2001 From: toaster Date: Fri, 26 Aug 2022 21:18:27 +0100 Subject: [PATCH 08/10] Revert "Remove game deadzone for Accel/Brake" This reverts commit 44eeb3a0f380f81a6e61d01eda2762160ff1ec4d. # Conflicts: # src/m_menu.c --- src/g_game.h | 4 ++-- src/m_menu.c | 20 +++++++++++++------- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/src/g_game.h b/src/g_game.h index ead5b7ae..9f1b8c5c 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -128,11 +128,11 @@ typedef enum { AXISNONE = 0, AXISTURN, + AXISMOVE, + AXISBRAKE, AXISAIM, AXISLOOK, AXISDEAD, //Axises that don't want deadzones - AXISMOVE, - AXISBRAKE, AXISFIRE, AXISDRIFT, AXISLOOKBACK, diff --git a/src/m_menu.c b/src/m_menu.c index 1dbe458e..ee854113 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -2627,21 +2627,27 @@ boolean M_Responder(event_t *ev) accelaxis /= 2; if (ev->data1 == accelaxis) { + const INT32 jacceldeadzone = xmode ? jxdeadzone : jydeadzone; retaxis = xmode ? ev->data2 : ev->data3; if (retaxis != INT32_MAX) { if (cv_moveaxis.value < 0) retaxis = -retaxis; - if (joywaitaccel < thistime && retaxis >= pjoyaccel) // only on upwards event + if (Joystick.bGamepadStyle || retaxis > jacceldeadzone) { - ch = KEY_ENTER; - joywaitaccel = thistime; - if (pjoyaccel == 0 // no previous input? - || ((retaxis < 0) == (pjoyaccel < 0))) // same direction as the current one? - joywaitaccel += NEWTICRATE/3; + if (joywaitaccel < thistime) + { + ch = KEY_ENTER; + joywaitaccel = thistime; + if (pjoyaccel == 0 // no previous input? + || ((retaxis < 0) == (pjoyaccel > 0))) // same direction as the current one? + joywaitaccel += NEWTICRATE/3; + } + pjoyaccel = retaxis; } - pjoyaccel = retaxis; + else + pjoyaccel = 0; } } } From f7fc5c684edb95e132974692ae23f71872aa18c4 Mon Sep 17 00:00:00 2001 From: toaster Date: Fri, 26 Aug 2022 21:26:03 +0100 Subject: [PATCH 09/10] Positive sign only --- src/m_menu.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index ee854113..5d1e35ee 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -2636,13 +2636,10 @@ boolean M_Responder(event_t *ev) if (Joystick.bGamepadStyle || retaxis > jacceldeadzone) { - if (joywaitaccel < thistime) + if (joywaitaccel < thistime && retaxis >= pjoyaccel) // only on upwards event { ch = KEY_ENTER; - joywaitaccel = thistime; - if (pjoyaccel == 0 // no previous input? - || ((retaxis < 0) == (pjoyaccel > 0))) // same direction as the current one? - joywaitaccel += NEWTICRATE/3; + joywaitaccel = thistime + NEWTICRATE/3; } pjoyaccel = retaxis; } From bbfaa0e99e3b0d63ac9047fc4c342729439283ef Mon Sep 17 00:00:00 2001 From: toaster Date: Sat, 27 Aug 2022 11:10:28 +0100 Subject: [PATCH 10/10] Revert continuous hold attempt - Does not function with controllers that don't produce continuous joystick events on hold, as testing unfortunately made clear. - The entire thing would need to be rewritten to make up for that, and I don't have the time to invest that kind of energy into version 1. - An unreliable feature is worse than no feature at all. --- src/m_menu.c | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index 5d1e35ee..de0e0f41 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -2585,13 +2585,11 @@ boolean M_Responder(event_t *ev) { if (Joystick.bGamepadStyle || abs(ev->data3) > jydeadzone) { - if (joywaity < thistime) + if (joywaity < thistime + && (pjoyy == 0 || (ev->data3 < 0) != (pjoyy < 0))) // no previous direction OR change direction { ch = (ev->data3 < 0) ? KEY_UPARROW : KEY_DOWNARROW; - joywaity = thistime; - if (pjoyy == 0 // no previous input? - || ((ev->data3 < 0) == (pjoyy < 0))) // same direction as the current one? - joywaity += NEWTICRATE/7; + joywaity = thistime + NEWTICRATE/7; } pjoyy = ev->data3; } @@ -2603,13 +2601,11 @@ boolean M_Responder(event_t *ev) { if (Joystick.bGamepadStyle || abs(ev->data2) > jxdeadzone) { - if (joywaity < thistime) + if (joywaitx < thistime + && (pjoyx == 0 || (ev->data2 < 0) != (pjoyx < 0))) // no previous direction OR change direction { ch = (ev->data2 < 0) ? KEY_LEFTARROW : KEY_RIGHTARROW; - joywaity = thistime; - if (pjoyx == 0 // no previous input? - || ((ev->data2 < 0) == (pjoyx < 0))) // same direction as the current one? - joywaity += NEWTICRATE/7; + joywaitx = thistime + NEWTICRATE/7; } pjoyx = ev->data2; } @@ -2636,7 +2632,7 @@ boolean M_Responder(event_t *ev) if (Joystick.bGamepadStyle || retaxis > jacceldeadzone) { - if (joywaitaccel < thistime && retaxis >= pjoyaccel) // only on upwards event + if (joywaitaccel < thistime && retaxis > pjoyaccel) // only on upwards event { ch = KEY_ENTER; joywaitaccel = thistime + NEWTICRATE/3;