mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2026-01-04 22:16:35 +00:00
Port Ediolon's SDL GameController work
Basically instantly solved all of the issues that made this branch completely unusable
This commit is contained in:
parent
a8d847227d
commit
85a132c149
6 changed files with 220 additions and 301 deletions
161
src/g_input.c
161
src/g_input.c
|
|
@ -173,7 +173,7 @@ void G_MapEventsToControls(event_t *ev)
|
|||
break;
|
||||
|
||||
case ev_joystick: // buttons are virtual keys
|
||||
if (ev->data1 >= JOYAXISSET)
|
||||
if (ev->data1 >= JOYAXISSETS)
|
||||
{
|
||||
#ifdef PARANOIA
|
||||
CONS_Debug(DBG_GAMELOGIC, "Bad joystick axis event %d\n", ev->data1);
|
||||
|
|
@ -181,37 +181,56 @@ void G_MapEventsToControls(event_t *ev)
|
|||
break;
|
||||
}
|
||||
|
||||
i = ev->data1 * 4;
|
||||
i = ev->data1;
|
||||
|
||||
if (ev->data2 != INT32_MAX)
|
||||
if (i >= JOYANALOGS)
|
||||
{
|
||||
if (ev->data2 < 0)
|
||||
// The trigger axes are handled specially.
|
||||
i -= JOYANALOGS;
|
||||
|
||||
if (ev->data2 != INT32_MAX)
|
||||
{
|
||||
// Left
|
||||
gamekeydown[ev->device][KEY_AXIS1 + i] = abs(ev->data2);
|
||||
gamekeydown[ev->device][KEY_AXIS1 + i + 1] = 0;
|
||||
gamekeydown[ev->device][KEY_AXIS1 + (JOYANALOGS * 4) + (i * 2)] = max(0, ev->data2);
|
||||
}
|
||||
else
|
||||
|
||||
if (ev->data3 != INT32_MAX)
|
||||
{
|
||||
// Right
|
||||
gamekeydown[ev->device][KEY_AXIS1 + i] = 0;
|
||||
gamekeydown[ev->device][KEY_AXIS1 + i + 1] = abs(ev->data2);
|
||||
gamekeydown[ev->device][KEY_AXIS1 + (JOYANALOGS * 4) + (i * 2) + 1] = max(0, ev->data3);
|
||||
}
|
||||
}
|
||||
|
||||
if (ev->data3 != INT32_MAX)
|
||||
else
|
||||
{
|
||||
if (ev->data3 < 0)
|
||||
// Actual analog sticks
|
||||
if (ev->data2 != INT32_MAX)
|
||||
{
|
||||
// Up
|
||||
gamekeydown[ev->device][KEY_AXIS1 + i + 2] = abs(ev->data3);
|
||||
gamekeydown[ev->device][KEY_AXIS1 + i + 3] = 0;
|
||||
if (ev->data2 < 0)
|
||||
{
|
||||
// Left
|
||||
gamekeydown[ev->device][KEY_AXIS1 + (i * 4)] = abs(ev->data2);
|
||||
gamekeydown[ev->device][KEY_AXIS1 + (i * 4) + 1] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Right
|
||||
gamekeydown[ev->device][KEY_AXIS1 + (i * 4)] = 0;
|
||||
gamekeydown[ev->device][KEY_AXIS1 + (i * 4) + 1] = abs(ev->data2);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
if (ev->data3 != INT32_MAX)
|
||||
{
|
||||
// Down
|
||||
gamekeydown[ev->device][KEY_AXIS1 + i + 2] = 0;
|
||||
gamekeydown[ev->device][KEY_AXIS1 + i + 3] = abs(ev->data3);
|
||||
if (ev->data3 < 0)
|
||||
{
|
||||
// Up
|
||||
gamekeydown[ev->device][KEY_AXIS1 + (i * 4) + 2] = abs(ev->data3);
|
||||
gamekeydown[ev->device][KEY_AXIS1 + (i * 4) + 3] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Down
|
||||
gamekeydown[ev->device][KEY_AXIS1 + (i * 4) + 2] = 0;
|
||||
gamekeydown[ev->device][KEY_AXIS1 + (i * 4) + 3] = abs(ev->data3);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
@ -316,76 +335,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] =
|
||||
|
|
|
|||
|
|
@ -23,9 +23,12 @@
|
|||
#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
|
||||
|
||||
|
|
@ -35,9 +38,9 @@
|
|||
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,
|
||||
|
|
|
|||
|
|
@ -2418,10 +2418,14 @@ static boolean M_HandlePressStart(setup_player_t *p, UINT8 num)
|
|||
// this is to allow them to retain controller usage when they play alone.
|
||||
// Because let's face it, when you test mods, you're often lazy to grab your controller for menuing :)
|
||||
if (!i && !num)
|
||||
{
|
||||
setup_player[num].ponedevice = cv_usejoystick[num].value;
|
||||
}
|
||||
else if (num)
|
||||
{
|
||||
// For any player past player 1, set controls to default profile controls, otherwise it's generally awful to do any menuing...
|
||||
memcpy(&gamecontrol[num], gamecontroldefault, sizeof(gamecontroldefault));
|
||||
}
|
||||
|
||||
|
||||
CV_SetValue(&cv_usejoystick[num], i);
|
||||
|
|
@ -3132,7 +3136,9 @@ void M_CharacterSelectTick(void)
|
|||
|
||||
// P1 is alone, set their old device just in case.
|
||||
if (setup_numplayers < 2 && setup_player[0].ponedevice)
|
||||
{
|
||||
CV_StealthSetValue(&cv_usejoystick[0], setup_player[0].ponedevice);
|
||||
}
|
||||
|
||||
M_SetupNextMenu(&PLAY_MainDef, false);
|
||||
}
|
||||
|
|
@ -5307,7 +5313,7 @@ void M_MapProfileControl(event_t *ev)
|
|||
#endif
|
||||
break;
|
||||
case ev_joystick:
|
||||
if (ev->data1 >= JOYAXISSET)
|
||||
if (ev->data1 >= JOYAXES)
|
||||
{
|
||||
#ifdef PARANOIA
|
||||
CONS_Debug(DBG_GAMELOGIC, "Bad joystick axis event %d\n", ev->data1);
|
||||
|
|
@ -5320,65 +5326,58 @@ void M_MapProfileControl(event_t *ev)
|
|||
boolean responsivelr = ((ev->data2 != INT32_MAX) && (abs(ev->data2) >= deadzone));
|
||||
boolean responsiveud = ((ev->data3 != INT32_MAX) && (abs(ev->data3) >= deadzone));
|
||||
|
||||
// Only consider unambiguous assignment.
|
||||
if (responsivelr == responsiveud)
|
||||
return;
|
||||
i = ev->data1;
|
||||
|
||||
i = (ev->data1 * 4);
|
||||
|
||||
if (responsivelr)
|
||||
if (i >= JOYANALOGS)
|
||||
{
|
||||
if (ev->data2 < 0)
|
||||
// The trigger axes are handled specially.
|
||||
i -= JOYANALOGS;
|
||||
|
||||
if (responsivelr)
|
||||
{
|
||||
// Left
|
||||
c = KEY_AXIS1 + i;
|
||||
c = KEY_AXIS1 + (JOYANALOGS * 4) + (i * 2);
|
||||
}
|
||||
else
|
||||
else if (responsiveud)
|
||||
{
|
||||
// Right
|
||||
c = KEY_AXIS1 + i + 1;
|
||||
c = KEY_AXIS1 + (JOYANALOGS * 4) + (i * 2) + 1;
|
||||
}
|
||||
}
|
||||
else //if (responsiveud)
|
||||
else
|
||||
{
|
||||
if (ev->data3 < 0)
|
||||
// Actual analog sticks
|
||||
|
||||
// Only consider unambiguous assignment.
|
||||
if (responsivelr == responsiveud)
|
||||
return;
|
||||
|
||||
if (responsivelr)
|
||||
{
|
||||
// Up
|
||||
c = KEY_AXIS1 + i + 2;
|
||||
if (ev->data2 < 0)
|
||||
{
|
||||
// Left
|
||||
c = KEY_AXIS1 + (i * 4);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Right
|
||||
c = KEY_AXIS1 + (i * 4) + 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
else //if (responsiveud)
|
||||
{
|
||||
// Down
|
||||
c = KEY_AXIS1 + i + 3;
|
||||
if (ev->data3 < 0)
|
||||
{
|
||||
// Up
|
||||
c = KEY_AXIS1 + (i * 4) + 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Down
|
||||
c = KEY_AXIS1 + (i * 4) + 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* I hate this.
|
||||
I shouldn't have to do this.
|
||||
But we HAVE to because of some controllers, INCLUDING MINE.
|
||||
|
||||
Triggers on X360 controllers go from -1024 when not held
|
||||
To 1023 when pressed.
|
||||
The result is that pressing the trigger makes the game THINK the input is for a negative value.
|
||||
Which then means that the input is considered pressed when the trigger is released.
|
||||
|
||||
So what we're going to do is make sure that the detected 'c' key is the same for multiple rolls of ev_joystick.
|
||||
NOTE: We need the player to press the key all the way down otherwise this might just not work...
|
||||
|
||||
@TODO: This isn't entirely consistent because we only check for events..... maybe check continuously for gamekeydown[]?
|
||||
but this seems messy...
|
||||
*/
|
||||
|
||||
//CONS_Printf("mapping joystick ... attempt (%d)\n", optionsmenu.keyheldfor);
|
||||
|
||||
if (c != optionsmenu.lastkey)
|
||||
{
|
||||
optionsmenu.lastkey = c;
|
||||
optionsmenu.keyheldfor = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
|
|
@ -5411,7 +5410,8 @@ void M_MapProfileControl(event_t *ev)
|
|||
// If possible, reapply the profile...
|
||||
// 19/05/22: Actually, no, don't do that, it just fucks everything up in too many cases.
|
||||
|
||||
/*if (gamestate == GS_MENU) // In menu? Apply this to P1, no questions asked.
|
||||
/*
|
||||
if (gamestate == GS_MENU) // In menu? Apply this to P1, no questions asked.
|
||||
{
|
||||
// Apply the profile's properties to player 1 but keep the last profile cv to p1's ACTUAL profile to revert once we exit.
|
||||
UINT8 lastp = cv_lastprofile[0].value;
|
||||
|
|
@ -5430,7 +5430,8 @@ void M_MapProfileControl(event_t *ev)
|
|||
break;
|
||||
}
|
||||
}
|
||||
}*/
|
||||
}
|
||||
*/
|
||||
}
|
||||
#undef KEYHOLDFOR
|
||||
|
||||
|
|
|
|||
|
|
@ -200,12 +200,12 @@ static char returnWadPath[256];
|
|||
#include "../byteptr.h"
|
||||
#endif
|
||||
|
||||
void I_StoreExJoystick(SDL_Joystick *dev)
|
||||
void I_StoreExJoystick(SDL_GameController *dev)
|
||||
{
|
||||
// ExJoystick is a massive hack to avoid needing to completely
|
||||
// rewrite pretty much all of the controller support from scratch...
|
||||
|
||||
// Used in favor of most instances of SDL_JoystickClose.
|
||||
// Used in favor of most instances of SDL_GameControllerClose.
|
||||
// If a joystick would've been discarded, then save it in an array,
|
||||
// because we want it have it for the joystick input screen.
|
||||
|
||||
|
|
@ -217,12 +217,12 @@ void I_StoreExJoystick(SDL_Joystick *dev)
|
|||
return;
|
||||
}
|
||||
|
||||
index = SDL_JoystickInstanceID(dev);
|
||||
index = SDL_JoystickInstanceID(SDL_GameControllerGetJoystick(dev));
|
||||
|
||||
if (index >= MAXGAMEPADS || index < 0)
|
||||
{
|
||||
// Not enough space to save this joystick, completely discard.
|
||||
SDL_JoystickClose(dev);
|
||||
SDL_GameControllerClose(dev);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -235,7 +235,7 @@ void I_StoreExJoystick(SDL_Joystick *dev)
|
|||
if (ExJoystick[index] != NULL)
|
||||
{
|
||||
// Discard joystick in the old slot.
|
||||
SDL_JoystickClose(ExJoystick[index]);
|
||||
SDL_GameControllerClose(ExJoystick[index]);
|
||||
}
|
||||
|
||||
// Keep for safe-keeping.
|
||||
|
|
@ -267,7 +267,7 @@ static INT32 joystick_started[MAXSPLITSCREENPLAYERS] = {0,0,0,0};
|
|||
/** \brief SDL info about joystick 1
|
||||
*/
|
||||
SDLJoyInfo_t JoyInfo[MAXSPLITSCREENPLAYERS];
|
||||
SDL_Joystick *ExJoystick[MAXGAMEPADS];
|
||||
SDL_GameController *ExJoystick[MAXGAMEPADS];
|
||||
|
||||
SDL_bool consolevent = SDL_FALSE;
|
||||
SDL_bool framebuffer = SDL_FALSE;
|
||||
|
|
@ -989,29 +989,16 @@ 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
|
||||
INT32 I_GetJoystickDeviceIndex(SDL_Joystick *dev)
|
||||
// Cheat to get the device index for a game controller handle
|
||||
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
|
||||
{
|
||||
UINT8 j;
|
||||
|
||||
for (j = 0; j < MAXSPLITSCREENPLAYERS; j++)
|
||||
{
|
||||
if (JoyInfo[j].dev == test)
|
||||
break;
|
||||
}
|
||||
|
||||
if (j == MAXSPLITSCREENPLAYERS)
|
||||
I_StoreExJoystick(test);
|
||||
}
|
||||
return SDL_JoystickInstanceID(joystick);
|
||||
}
|
||||
|
||||
return -1;
|
||||
|
|
@ -1082,7 +1069,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);
|
||||
|
|
@ -1093,23 +1080,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 < JOYAXES; i++)
|
||||
{
|
||||
event.data1 = i;
|
||||
D_PostEvent(&event);
|
||||
|
|
@ -1131,7 +1108,7 @@ void I_ShutdownJoystick(UINT8 index)
|
|||
*/
|
||||
static int joy_open(int playerIndex, int joyIndex)
|
||||
{
|
||||
SDL_Joystick *newdev = NULL;
|
||||
SDL_GameController *newdev = NULL;
|
||||
int num_joy = 0;
|
||||
|
||||
if (SDL_WasInit(SDL_INIT_JOYSTICK) == 0)
|
||||
|
|
@ -1140,6 +1117,12 @@ static int joy_open(int playerIndex, int joyIndex)
|
|||
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;
|
||||
|
||||
|
|
@ -1151,7 +1134,7 @@ static int joy_open(int playerIndex, 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.
|
||||
|
|
@ -1166,9 +1149,9 @@ static int joy_open(int playerIndex, int joyIndex)
|
|||
if (JoyInfo[playerIndex].dev)
|
||||
{
|
||||
if (JoyInfo[playerIndex].dev == newdev // same device, nothing to do
|
||||
|| (newdev == NULL && SDL_JoystickGetAttached(JoyInfo[playerIndex].dev))) // we failed, but already have a working device
|
||||
|| (newdev == NULL && SDL_GameControllerGetAttached(JoyInfo[playerIndex].dev))) // we failed, but already have a working device
|
||||
{
|
||||
return JoyInfo[playerIndex].axises;
|
||||
return SDL_CONTROLLER_AXIS_MAX;
|
||||
}
|
||||
|
||||
// Else, we're changing devices, so send neutral joy events
|
||||
|
|
@ -1185,29 +1168,12 @@ static int joy_open(int playerIndex, int joyIndex)
|
|||
}
|
||||
else
|
||||
{
|
||||
CONS_Debug(DBG_GAMELOGIC, M_GetText("Joystick%d: %s\n"), playerIndex+1, SDL_JoystickName(JoyInfo[playerIndex].dev));
|
||||
CONS_Debug(DBG_GAMELOGIC, M_GetText("Joystick%d: %s\n"), playerIndex+1, SDL_GameControllerName(JoyInfo[playerIndex].dev));
|
||||
|
||||
JoyInfo[playerIndex].axises = SDL_JoystickNumAxes(JoyInfo[playerIndex].dev);
|
||||
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_JoystickNumButtons(JoyInfo[playerIndex].dev);
|
||||
if (JoyInfo[playerIndex].buttons > JOYBUTTONS)
|
||||
JoyInfo[playerIndex].buttons = JOYBUTTONS;
|
||||
|
||||
JoyInfo[playerIndex].hats = SDL_JoystickNumHats(JoyInfo[playerIndex].dev);
|
||||
if (JoyInfo[playerIndex].hats > JOYHATS)
|
||||
JoyInfo[playerIndex].hats = JOYHATS;
|
||||
|
||||
JoyInfo[playerIndex].balls = SDL_JoystickNumBalls(JoyInfo[playerIndex].dev);
|
||||
JoyInfo[playerIndex].axises = SDL_CONTROLLER_AXIS_MAX;
|
||||
JoyInfo[playerIndex].buttons = SDL_CONTROLLER_BUTTON_MAX;
|
||||
JoyInfo[playerIndex].hats = 1;
|
||||
JoyInfo[playerIndex].balls = 0;
|
||||
|
||||
//JoyInfo[playerIndex].bGamepadStyle = !stricmp(SDL_JoystickName(JoyInfo[playerIndex].dev), "pad");
|
||||
|
||||
|
|
@ -1220,7 +1186,7 @@ static int joy_open(int playerIndex, int joyIndex)
|
|||
//
|
||||
void I_InitJoystick(UINT8 index)
|
||||
{
|
||||
SDL_Joystick *newjoy = NULL;
|
||||
SDL_GameController *newcontroller = NULL;
|
||||
UINT8 i;
|
||||
|
||||
//I_ShutdownJoystick();
|
||||
|
|
@ -1245,23 +1211,32 @@ 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)
|
||||
newjoy = SDL_JoystickOpen(cv_usejoystick[index].value-1);
|
||||
newcontroller = SDL_GameControllerOpen(cv_usejoystick[index].value-1);
|
||||
|
||||
for (i = 0; i < MAXSPLITSCREENPLAYERS; i++)
|
||||
{
|
||||
if (i == index)
|
||||
continue;
|
||||
|
||||
if (JoyInfo[i].dev == newjoy)
|
||||
if (JoyInfo[i].dev == newcontroller)
|
||||
break;
|
||||
}
|
||||
|
||||
if (newjoy && i < MAXSPLITSCREENPLAYERS) // don't override an active device
|
||||
if (newcontroller && i < MAXSPLITSCREENPLAYERS) // don't override an active device
|
||||
{
|
||||
cv_usejoystick[index].value = I_GetJoystickDeviceIndex(JoyInfo[index].dev) + 1;
|
||||
}
|
||||
else if (newjoy && joy_open(index, cv_usejoystick[index].value) != -1)
|
||||
else if (newcontroller && joy_open(index, cv_usejoystick[index].value) != -1)
|
||||
{
|
||||
// SDL's device indexes are unstable, so cv_usejoystick may not match
|
||||
// the actual device index. So let's cheat a bit and find the device's current index.
|
||||
|
|
@ -1278,14 +1253,14 @@ void I_InitJoystick(UINT8 index)
|
|||
|
||||
for (i = 0; i < MAXSPLITSCREENPLAYERS; i++)
|
||||
{
|
||||
if (JoyInfo[i].dev == newjoy)
|
||||
if (JoyInfo[i].dev == newcontroller)
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == MAXSPLITSCREENPLAYERS)
|
||||
{
|
||||
// Joystick didn't end up being used
|
||||
I_StoreExJoystick(newjoy);
|
||||
I_StoreExJoystick(newcontroller);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1320,6 +1295,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");
|
||||
|
|
|
|||
|
|
@ -770,9 +770,10 @@ static void Impl_HandleMouseWheelEvent(SDL_MouseWheelEvent evt)
|
|||
}
|
||||
}
|
||||
|
||||
static void Impl_HandleJoystickAxisEvent(SDL_JoyAxisEvent evt)
|
||||
static void Impl_HandleControllerAxisEvent(SDL_ControllerAxisEvent evt)
|
||||
{
|
||||
event_t event;
|
||||
INT32 value;
|
||||
|
||||
event.type = ev_joystick;
|
||||
|
||||
|
|
@ -782,78 +783,32 @@ static void Impl_HandleJoystickAxisEvent(SDL_JoyAxisEvent evt)
|
|||
return;
|
||||
}
|
||||
|
||||
evt.axis++;
|
||||
event.data1 = event.data2 = event.data3 = INT32_MAX;
|
||||
|
||||
//axis
|
||||
if (evt.axis > JOYAXISSET*2)
|
||||
if (evt.axis > 2 * JOYAXISSETS)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//vaule[sic]
|
||||
if (evt.axis % 2)
|
||||
value = SDLJoyAxis(evt.value, evt.which);
|
||||
|
||||
if (evt.axis & 1)
|
||||
{
|
||||
event.data1 = evt.axis / 2;
|
||||
event.data2 = SDLJoyAxis(evt.value, 0); // TODO: replace 0 with pid
|
||||
event.data3 = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
evt.axis--;
|
||||
event.data1 = evt.axis / 2;
|
||||
event.data3 = SDLJoyAxis(evt.value, 0); // TODO: replace 0 with pid
|
||||
event.data2 = value;
|
||||
}
|
||||
|
||||
event.data1 = evt.axis / 2;
|
||||
|
||||
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_HandleJoystickButtonEvent(SDL_JoyButtonEvent evt, Uint32 type)
|
||||
static void Impl_HandleControllerButtonEvent(SDL_ControllerButtonEvent evt, Uint32 type)
|
||||
{
|
||||
event_t event;
|
||||
|
||||
|
|
@ -866,11 +821,11 @@ static void Impl_HandleJoystickButtonEvent(SDL_JoyButtonEvent evt, Uint32 type)
|
|||
|
||||
event.data1 = KEY_JOY1;
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
@ -936,26 +891,23 @@ 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;
|
||||
case SDL_JOYHATMOTION:
|
||||
Impl_HandleJoystickHatEvent(evt.jhat);
|
||||
break;
|
||||
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);
|
||||
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:
|
||||
|
|
@ -970,7 +922,7 @@ void I_GetEvent(void)
|
|||
|
||||
for (i = 0; i < MAXSPLITSCREENPLAYERS; i++)
|
||||
{
|
||||
if (newjoy && (!JoyInfo[i].dev || !SDL_JoystickGetAttached(JoyInfo[i].dev)))
|
||||
if (newcontroller && (!JoyInfo[i].dev || !SDL_GameControllerGetAttached(JoyInfo[i].dev)))
|
||||
{
|
||||
UINT8 j;
|
||||
|
||||
|
|
@ -979,14 +931,14 @@ void I_GetEvent(void)
|
|||
if (i == j)
|
||||
continue;
|
||||
|
||||
if (JoyInfo[j].dev == newjoy)
|
||||
if (JoyInfo[j].dev == newcontroller)
|
||||
break;
|
||||
}
|
||||
|
||||
if (j == MAXSPLITSCREENPLAYERS)
|
||||
{
|
||||
// ensures we aren't overriding a currently active device
|
||||
cv_usejoystick[i].value = evt.jdevice.which + 1;
|
||||
cv_usejoystick[i].value = evt.cdevice.which + 1;
|
||||
I_UpdateJoystickDeviceIndices(0);
|
||||
}
|
||||
}
|
||||
|
|
@ -1028,21 +980,21 @@ void I_GetEvent(void)
|
|||
|
||||
for (i = 0; i < MAXSPLITSCREENPLAYERS; i++)
|
||||
{
|
||||
if (JoyInfo[i].dev == newjoy)
|
||||
if (JoyInfo[i].dev == newcontroller)
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == MAXSPLITSCREENPLAYERS)
|
||||
I_StoreExJoystick(newjoy);
|
||||
I_StoreExJoystick(newcontroller);
|
||||
}
|
||||
break;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
case SDL_JOYDEVICEREMOVED:
|
||||
case SDL_CONTROLLERDEVICEREMOVED:
|
||||
for (i = 0; i < MAXSPLITSCREENPLAYERS; i++)
|
||||
{
|
||||
if (JoyInfo[i].dev && !SDL_JoystickGetAttached(JoyInfo[i].dev))
|
||||
if (JoyInfo[i].dev && !SDL_GameControllerGetAttached(JoyInfo[i].dev))
|
||||
{
|
||||
CONS_Debug(DBG_GAMELOGIC, "Joystick%d removed, device index: %d\n", i+1, JoyInfo[i].oldjoy);
|
||||
I_ShutdownJoystick(i);
|
||||
|
|
@ -1146,8 +1098,8 @@ void I_OsPolling(void)
|
|||
if (consolevent)
|
||||
I_GetConsoleEvents();
|
||||
|
||||
if (SDL_WasInit(SDL_INIT_JOYSTICK) == SDL_INIT_JOYSTICK)
|
||||
SDL_JoystickUpdate();
|
||||
if (SDL_WasInit(SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER) == (SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER))
|
||||
SDL_GameControllerUpdate();
|
||||
|
||||
I_GetEvent();
|
||||
|
||||
|
|
|
|||
|
|
@ -41,8 +41,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
|
||||
|
|
@ -58,12 +58,12 @@ typedef struct SDLJoyInfo_s
|
|||
|
||||
} SDLJoyInfo_t;
|
||||
|
||||
/** \brief SDL info about joysticks
|
||||
/** \brief SDL info about controllers
|
||||
*/
|
||||
extern SDLJoyInfo_t JoyInfo[MAXSPLITSCREENPLAYERS];
|
||||
extern SDL_Joystick *ExJoystick[MAXGAMEPADS];
|
||||
extern SDL_GameController *ExJoystick[MAXGAMEPADS];
|
||||
|
||||
void I_StoreExJoystick(SDL_Joystick *dev);
|
||||
void I_StoreExJoystick(SDL_GameController *dev);
|
||||
|
||||
/** \brief joystick axis deadzone
|
||||
*/
|
||||
|
|
@ -75,8 +75,8 @@ void I_GetConsoleEvents(void);
|
|||
// So we can call this from i_video event loop
|
||||
void I_ShutdownJoystick(UINT8 index);
|
||||
|
||||
// Cheat to get the device index for a 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_UpdateJoystickDeviceIndex(UINT8 player);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue