Port Ediolon's SDL GameController work

Basically instantly solved all of the issues that made this branch completely unusable
This commit is contained in:
Eidolon 2022-08-23 00:05:50 -05:00 committed by GenericHeroGuy
parent e1ffc206e7
commit 4d65f09eb7
5 changed files with 94 additions and 180 deletions

View file

@ -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

View file

@ -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,

View file

@ -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))
{

View file

@ -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");

View file

@ -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: