Controller hotplugging by always keeping joy subsystem on (thanks WOLFS)

(with log messages)
This commit is contained in:
mazmazz 2018-12-06 10:54:58 -05:00
parent 88b2e5ce84
commit 6694b7d679
5 changed files with 148 additions and 111 deletions

View file

@ -6761,7 +6761,7 @@ static void M_DrawJoystick(void)
} }
} }
static void M_SetupJoystickMenu(INT32 choice) void M_SetupJoystickMenu(INT32 choice)
{ {
INT32 i = 0; INT32 i = 0;
const char *joyNA = "Unavailable"; const char *joyNA = "Unavailable";

View file

@ -69,7 +69,6 @@ void M_QuitResponse(INT32 ch);
// Determines whether to show a level in the list // Determines whether to show a level in the list
boolean M_CanShowLevelInList(INT32 mapnum, INT32 gt); boolean M_CanShowLevelInList(INT32 mapnum, INT32 gt);
// flags for items in the menu // flags for items in the menu
// menu handle (what we do when key is pressed // menu handle (what we do when key is pressed
#define IT_TYPE 14 // (2+4+8) #define IT_TYPE 14 // (2+4+8)
@ -171,6 +170,10 @@ extern menu_t *currentMenu;
extern menu_t MainDef; extern menu_t MainDef;
extern menu_t SP_LoadDef; extern menu_t SP_LoadDef;
// Call upon joystick hotplug
void M_SetupJoystickMenu(INT32 choice);
extern menu_t OP_JoystickSetDef;
// Stuff for customizing the player select screen // Stuff for customizing the player select screen
typedef struct typedef struct
{ {

View file

@ -843,7 +843,7 @@ static UINT64 lastjoyhats = 0;
*/ */
static void I_ShutdownJoystick(void) void I_ShutdownJoystick(void)
{ {
INT32 i; INT32 i;
event_t event; event_t event;
@ -877,14 +877,8 @@ static void I_ShutdownJoystick(void)
joystick_started = 0; joystick_started = 0;
JoyReset(&JoyInfo); JoyReset(&JoyInfo);
if (!joystick_started && !joystick2_started && SDL_WasInit(SDL_INIT_JOYSTICK) == SDL_INIT_JOYSTICK)
{ // don't shut down the subsystem here, because hotplugging
SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
if (cv_usejoystick.value == 0)
{
I_OutputMsg("I_Joystick: SDL's Joystick system has been shutdown\n");
}
}
} }
void I_GetJoystickEvents(void) void I_GetJoystickEvents(void)
@ -1031,37 +1025,20 @@ static int joy_open(const char *fname)
int num_joy = 0; int num_joy = 0;
int i; int i;
if (joystick_started == 0 && joystick2_started == 0) if (SDL_WasInit(SDL_INIT_JOYSTICK) == 0)
{ {
if (SDL_InitSubSystem(SDL_INIT_JOYSTICK) == -1) CONS_Printf(M_GetText("Joystick subsystem not started\n"));
{
CONS_Printf(M_GetText("Couldn't initialize joystick: %s\n"), SDL_GetError());
return -1; return -1;
} }
else
{
num_joy = SDL_NumJoysticks();
}
if (num_joy < joyindex)
{
CONS_Printf(M_GetText("Cannot use joystick #%d/(%s), it doesn't exist\n"),joyindex,fname);
for (i = 0; i < num_joy; i++)
CONS_Printf("#%d/(%s)\n", i+1, SDL_JoystickNameForIndex(i));
I_ShutdownJoystick();
return -1;
}
}
else
{
JoyReset(&JoyInfo); JoyReset(&JoyInfo);
//I_ShutdownJoystick();
//joy_open(fname); if (joyindex <= 0)
} return 0;
num_joy = SDL_NumJoysticks(); num_joy = SDL_NumJoysticks();
if (joyindex <= 0 || num_joy == 0 || JoyInfo.oldjoy == joyindex) if (num_joy == 0 || JoyInfo.oldjoy == joyindex)
{ {
// I_OutputMsg("Unable to use that joystick #(%s), non-number\n",fname); // I_OutputMsg("Unable to use that joystick #(%s), non-number\n",fname);
if (num_joy != 0) if (num_joy != 0)
@ -1069,10 +1046,20 @@ static int joy_open(const char *fname)
CONS_Printf(M_GetText("Found %d joysticks on this system\n"), num_joy); CONS_Printf(M_GetText("Found %d joysticks on this system\n"), num_joy);
for (i = 0; i < num_joy; i++) for (i = 0; i < num_joy; i++)
CONS_Printf("#%d/(%s)\n", i+1, SDL_JoystickNameForIndex(i)); CONS_Printf("#%d/(%s)\n", i+1, SDL_JoystickNameForIndex(i));
if (num_joy < joyindex)
{
CONS_Printf(M_GetText("Cannot use joystick #%d/(%s), it doesn't exist\n"),joyindex,fname);
for (i = 0; i < num_joy; i++)
CONS_Printf("#%d/(%s)\n", i+1, SDL_JoystickNameForIndex(i));
return 0;
}
} }
else else
{
CONS_Printf("%s", M_GetText("Found no joysticks on this system\n")); CONS_Printf("%s", M_GetText("Found no joysticks on this system\n"));
if (joyindex <= 0 || num_joy == 0) return 0; return 0;
}
} }
JoyInfo.dev = SDL_JoystickOpen(joyindex-1); JoyInfo.dev = SDL_JoystickOpen(joyindex-1);
@ -1080,7 +1067,6 @@ static int joy_open(const char *fname)
if (JoyInfo.dev == NULL) if (JoyInfo.dev == NULL)
{ {
CONS_Printf(M_GetText("Couldn't open joystick: %s\n"), SDL_GetError()); CONS_Printf(M_GetText("Couldn't open joystick: %s\n"), SDL_GetError());
I_ShutdownJoystick();
return -1; return -1;
} }
else else
@ -1092,7 +1078,6 @@ static int joy_open(const char *fname)
/* if (joyaxes<2) /* if (joyaxes<2)
{ {
I_OutputMsg("Not enought axes?\n"); I_OutputMsg("Not enought axes?\n");
I_ShutdownJoystick();
return 0; return 0;
}*/ }*/
@ -1127,7 +1112,7 @@ static UINT64 lastjoy2hats = 0;
\return void \return void
*/ */
static void I_ShutdownJoystick2(void) void I_ShutdownJoystick2(void)
{ {
INT32 i; INT32 i;
event_t event; event_t event;
@ -1161,14 +1146,8 @@ static void I_ShutdownJoystick2(void)
joystick2_started = 0; joystick2_started = 0;
JoyReset(&JoyInfo2); JoyReset(&JoyInfo2);
if (!joystick_started && !joystick2_started && SDL_WasInit(SDL_INIT_JOYSTICK) == SDL_INIT_JOYSTICK)
{ // don't shut down the subsystem here, because hotplugging
SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
if (cv_usejoystick2.value == 0)
{
DEBFILE("I_Joystick2: SDL's Joystick system has been shutdown\n");
}
}
} }
void I_GetJoystick2Events(void) void I_GetJoystick2Events(void)
@ -1317,35 +1296,20 @@ static int joy_open2(const char *fname)
int num_joy = 0; int num_joy = 0;
int i; int i;
if (joystick_started == 0 && joystick2_started == 0) if (SDL_WasInit(SDL_INIT_JOYSTICK) == 0)
{ {
if (SDL_InitSubSystem(SDL_INIT_JOYSTICK) == -1) CONS_Printf(M_GetText("Joystick subsystem not started\n"));
{
CONS_Printf(M_GetText("Couldn't initialize joystick: %s\n"), SDL_GetError());
return -1; return -1;
} }
else
num_joy = SDL_NumJoysticks();
if (num_joy < joyindex)
{
CONS_Printf(M_GetText("Cannot use joystick #%d/(%s), it doesn't exist\n"),joyindex,fname);
for (i = 0; i < num_joy; i++)
CONS_Printf("#%d/(%s)\n", i+1, SDL_JoystickNameForIndex(i));
I_ShutdownJoystick2();
return -1;
}
}
else
{
JoyReset(&JoyInfo2); JoyReset(&JoyInfo2);
//I_ShutdownJoystick();
//joy_open(fname); if (joyindex <= 0)
} return 0;
num_joy = SDL_NumJoysticks(); num_joy = SDL_NumJoysticks();
if (joyindex <= 0 || num_joy == 0 || JoyInfo2.oldjoy == joyindex) if (num_joy == 0 || JoyInfo2.oldjoy == joyindex)
{ {
// I_OutputMsg("Unable to use that joystick #(%s), non-number\n",fname); // I_OutputMsg("Unable to use that joystick #(%s), non-number\n",fname);
if (num_joy != 0) if (num_joy != 0)
@ -1353,18 +1317,27 @@ static int joy_open2(const char *fname)
CONS_Printf(M_GetText("Found %d joysticks on this system\n"), num_joy); CONS_Printf(M_GetText("Found %d joysticks on this system\n"), num_joy);
for (i = 0; i < num_joy; i++) for (i = 0; i < num_joy; i++)
CONS_Printf("#%d/(%s)\n", i+1, SDL_JoystickNameForIndex(i)); CONS_Printf("#%d/(%s)\n", i+1, SDL_JoystickNameForIndex(i));
if (num_joy < joyindex)
{
CONS_Printf(M_GetText("Cannot use joystick #%d/(%s), it doesn't exist\n"),joyindex,fname);
for (i = 0; i < num_joy; i++)
CONS_Printf("#%d/(%s)\n", i+1, SDL_JoystickNameForIndex(i));
return 0;
}
} }
else else
{
CONS_Printf("%s", M_GetText("Found no joysticks on this system\n")); CONS_Printf("%s", M_GetText("Found no joysticks on this system\n"));
if (joyindex <= 0 || num_joy == 0) return 0; return 0;
}
} }
JoyInfo2.dev = SDL_JoystickOpen(joyindex-1); JoyInfo2.dev = SDL_JoystickOpen(joyindex-1);
if (!JoyInfo2.dev) if (JoyInfo2.dev == NULL)
{ {
CONS_Printf(M_GetText("Couldn't open joystick2: %s\n"), SDL_GetError()); CONS_Printf(M_GetText("Couldn't open joystick2: %s\n"), SDL_GetError());
I_ShutdownJoystick2();
return -1; return -1;
} }
else else
@ -1376,7 +1349,6 @@ static int joy_open2(const char *fname)
/* if (joyaxes<2) /* if (joyaxes<2)
{ {
I_OutputMsg("Not enought axes?\n"); I_OutputMsg("Not enought axes?\n");
I_ShutdownJoystick2();
return 0; return 0;
}*/ }*/
@ -1401,57 +1373,89 @@ static int joy_open2(const char *fname)
// //
void I_InitJoystick(void) void I_InitJoystick(void)
{ {
I_ShutdownJoystick(); //I_ShutdownJoystick();
SDL_SetHintWithPriority("SDL_XINPUT_ENABLED", "0", SDL_HINT_OVERRIDE); if (M_CheckParm("-nojoy"))
if (!strcmp(cv_usejoystick.string, "0") || M_CheckParm("-nojoy"))
return; return;
if (joy_open(cv_usejoystick.string) != -1)
JoyInfo.oldjoy = atoi(cv_usejoystick.string); if (SDL_WasInit(SDL_INIT_JOYSTICK) == 0)
else
{ {
cv_usejoystick.value = 0; CONS_Printf("Initing joy system\n");
if (SDL_InitSubSystem(SDL_INIT_JOYSTICK) == -1)
{
CONS_Printf(M_GetText("Couldn't initialize joystick: %s\n"), SDL_GetError());
return; return;
} }
else
SDL_SetHintWithPriority("SDL_XINPUT_ENABLED", "0", SDL_HINT_OVERRIDE);
}
if (strcmp(cv_usejoystick.string, "0") && joy_open(cv_usejoystick.string) != -1)
{
JoyInfo.oldjoy = atoi(cv_usejoystick.string);
joystick_started = 1; joystick_started = 1;
} }
else
{
if (JoyInfo.oldjoy)
I_ShutdownJoystick();
cv_usejoystick.value = 0;
joystick_started = 0;
}
}
void I_InitJoystick2(void) void I_InitJoystick2(void)
{ {
I_ShutdownJoystick2(); //I_ShutdownJoystick2();
SDL_SetHintWithPriority("SDL_XINPUT_ENABLED", "0", SDL_HINT_OVERRIDE); if (M_CheckParm("-nojoy"))
if (!strcmp(cv_usejoystick2.string, "0") || M_CheckParm("-nojoy"))
return; return;
if (joy_open2(cv_usejoystick2.string) != -1)
JoyInfo2.oldjoy = atoi(cv_usejoystick2.string); if (SDL_WasInit(SDL_INIT_JOYSTICK) == 0)
else
{ {
cv_usejoystick2.value = 0; CONS_Printf("Initing joy system\n");
if (SDL_InitSubSystem(SDL_INIT_JOYSTICK) == -1)
{
CONS_Printf(M_GetText("Couldn't initialize joystick: %s\n"), SDL_GetError());
return; return;
} }
else
SDL_SetHintWithPriority("SDL_XINPUT_ENABLED", "0", SDL_HINT_OVERRIDE);
}
if (strcmp(cv_usejoystick2.string, "0") && joy_open2(cv_usejoystick2.string) != -1)
{
JoyInfo2.oldjoy = atoi(cv_usejoystick2.string);
joystick2_started = 1; joystick2_started = 1;
} }
else
{
if (JoyInfo2.oldjoy)
I_ShutdownJoystick2();
cv_usejoystick2.value = 0;
joystick2_started = 0;
}
}
static void I_ShutdownInput(void) static void I_ShutdownInput(void)
{ {
// Yes, the name is misleading: these send neutral events to
// clean up the unplugged joystick's input
// Note these methods are internal to this file, not called elsewhere.
I_ShutdownJoystick();
I_ShutdownJoystick2();
if (SDL_WasInit(SDL_INIT_JOYSTICK) == SDL_INIT_JOYSTICK) if (SDL_WasInit(SDL_INIT_JOYSTICK) == SDL_INIT_JOYSTICK)
{ {
JoyReset(&JoyInfo); CONS_Printf("Shutting down joy system\n");
JoyReset(&JoyInfo2);
SDL_QuitSubSystem(SDL_INIT_JOYSTICK); SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
I_OutputMsg("I_Joystick: SDL's Joystick system has been shutdown\n");
} }
} }
INT32 I_NumJoys(void) INT32 I_NumJoys(void)
{ {
INT32 numjoy = 0; INT32 numjoy = 0;
if (SDL_WasInit(SDL_INIT_JOYSTICK) == 0) if (SDL_WasInit(SDL_INIT_JOYSTICK) == SDL_INIT_JOYSTICK)
{
if (SDL_InitSubSystem(SDL_INIT_JOYSTICK) != -1)
numjoy = SDL_NumJoysticks();
SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
}
else
numjoy = SDL_NumJoysticks(); numjoy = SDL_NumJoysticks();
return numjoy; return numjoy;
} }
@ -1461,18 +1465,9 @@ static char joyname[255]; // MAX_PATH; joystick name is straight from the driver
const char *I_GetJoyName(INT32 joyindex) const char *I_GetJoyName(INT32 joyindex)
{ {
const char *tempname = NULL; const char *tempname = NULL;
joyname[0] = 0;
joyindex--; //SDL's Joystick System starts at 0, not 1 joyindex--; //SDL's Joystick System starts at 0, not 1
if (SDL_WasInit(SDL_INIT_JOYSTICK) == 0) if (SDL_WasInit(SDL_INIT_JOYSTICK) == SDL_INIT_JOYSTICK)
{
if (SDL_InitSubSystem(SDL_INIT_JOYSTICK) != -1)
{
tempname = SDL_JoystickNameForIndex(joyindex);
if (tempname)
strncpy(joyname, tempname, 255);
}
SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
}
else
{ {
tempname = SDL_JoystickNameForIndex(joyindex); tempname = SDL_JoystickNameForIndex(joyindex);
if (tempname) if (tempname)

View file

@ -116,6 +116,9 @@ static INT32 firstEntry = 0;
// Total mouse motion X/Y offsets // Total mouse motion X/Y offsets
static INT32 mousemovex = 0, mousemovey = 0; static INT32 mousemovex = 0, mousemovey = 0;
// Keep track of joy unplugged count
static INT32 joyunplugcount = 0;
// SDL vars // SDL vars
static SDL_Surface *vidSurface = NULL; static SDL_Surface *vidSurface = NULL;
static SDL_Surface *bufSurface = NULL; static SDL_Surface *bufSurface = NULL;
@ -882,6 +885,38 @@ void I_GetEvent(void)
case SDL_JOYBUTTONDOWN: case SDL_JOYBUTTONDOWN:
Impl_HandleJoystickButtonEvent(evt.jbutton, evt.type); Impl_HandleJoystickButtonEvent(evt.jbutton, evt.type);
break; break;
case SDL_JOYDEVICEADDED:
CONS_Printf("Joy device %d added\n", evt.jdevice.which);
// recounts hotplugged joysticks
I_InitJoystick();
I_InitJoystick2();
// update the menu
if (currentMenu == &OP_JoystickSetDef)
M_SetupJoystickMenu(0);
break;
case SDL_JOYDEVICEREMOVED:
{
// every time a device is unplugged, the "which" index increments by 1?
INT32 deviceIdx = evt.jdevice.which - joyunplugcount++;
CONS_Printf("Joy device %d removed%s\n", deviceIdx,
(JoyInfo.oldjoy-1 == deviceIdx) ? " was first joystick" :
(JoyInfo2.oldjoy-1 == deviceIdx) ? " was second joystick" : "");
// I_ShutdownJoystick doesn't shut down the subsystem
// It just fires neutral joy events to clean up the unplugged joy
if (JoyInfo.oldjoy-1 == deviceIdx)
I_ShutdownJoystick();
if (JoyInfo2.oldjoy-1 == deviceIdx)
I_ShutdownJoystick2();
// update the menu
if (currentMenu == &OP_JoystickSetDef)
M_SetupJoystickMenu(0);
}
break;
case SDL_QUIT: case SDL_QUIT:
I_Quit(); I_Quit();
M_QuitResponse('y'); M_QuitResponse('y');

View file

@ -67,6 +67,10 @@ extern SDLJoyInfo_t JoyInfo;
*/ */
extern SDLJoyInfo_t JoyInfo2; extern SDLJoyInfo_t JoyInfo2;
// So we can call this from i_video event loop
void I_ShutdownJoystick(void);
void I_ShutdownJoystick2(void);
void I_GetConsoleEvents(void); void I_GetConsoleEvents(void);
void SDLforceUngrabMouse(void); void SDLforceUngrabMouse(void);