Skip to content

Commit

Permalink
Worked around bug with Sony PS Now PS3 controller where DirectInput p…
Browse files Browse the repository at this point in the history
…olling will continue to return success after the controller is unplugged.

The code is now reliant on SDL_PrivateJoystickAdded() and SDL_PrivateJoystickRemoved() being called correctly when devices are added or removed on Windows
  • Loading branch information
slouken committed Aug 9, 2018
1 parent f35e97b commit 888bf1a
Show file tree
Hide file tree
Showing 17 changed files with 31 additions and 118 deletions.
22 changes: 18 additions & 4 deletions src/joystick/SDL_joystick.c
Expand Up @@ -297,6 +297,7 @@ SDL_JoystickOpen(int device_index)
}
joystick->driver = driver;
joystick->instance_id = instance_id;
joystick->attached = SDL_TRUE;

if (driver->Open(joystick, device_index) < 0) {
SDL_free(joystick);
Expand Down Expand Up @@ -545,7 +546,7 @@ SDL_JoystickGetAttached(SDL_Joystick * joystick)
return SDL_FALSE;
}

return joystick->driver->IsAttached(joystick);
return joystick->attached;
}

/*
Expand Down Expand Up @@ -765,6 +766,8 @@ static void UpdateEventsForDeviceRemoval()

void SDL_PrivateJoystickRemoved(SDL_JoystickID device_instance)
{
SDL_Joystick *joystick;

#if !SDL_EVENTS_DISABLED
SDL_Event event;

Expand All @@ -777,6 +780,15 @@ void SDL_PrivateJoystickRemoved(SDL_JoystickID device_instance)

UpdateEventsForDeviceRemoval();
#endif /* !SDL_EVENTS_DISABLED */

/* Mark this joystick as no longer attached */
for (joystick = SDL_joysticks; joystick; joystick = joystick->next) {
if (joystick->instance_id == device_instance) {
joystick->attached = SDL_FALSE;
joystick->force_recentering = SDL_TRUE;
break;
}
}
}

int
Expand Down Expand Up @@ -984,10 +996,12 @@ SDL_JoystickUpdate(void)
SDL_UnlockJoysticks();

for (joystick = SDL_joysticks; joystick; joystick = joystick->next) {
joystick->driver->Update(joystick);
if (joystick->attached) {
joystick->driver->Update(joystick);

if (joystick->delayed_guide_button) {
SDL_GameControllerHandleDelayedGuideButton(joystick);
if (joystick->delayed_guide_button) {
SDL_GameControllerHandleDelayedGuideButton(joystick);
}
}

if (joystick->force_recentering) {
Expand Down
6 changes: 1 addition & 5 deletions src/joystick/SDL_sysjoystick.h
Expand Up @@ -59,6 +59,7 @@ struct _SDL_Joystick
int nbuttons; /* Number of buttons on the joystick */
Uint8 *buttons; /* Current button states */

SDL_bool attached;
SDL_bool is_game_controller;
SDL_bool delayed_guide_button; /* SDL_TRUE if this device has the guide button event delayed */
SDL_bool force_recentering; /* SDL_TRUE if this device needs to have its state reset to 0 */
Expand Down Expand Up @@ -117,11 +118,6 @@ typedef struct _SDL_JoystickDriver
*/
int (*Open)(SDL_Joystick * joystick, int device_index);

/* Function to query if the joystick is currently attached
* It returns SDL_TRUE if attached, SDL_FALSE otherwise.
*/
SDL_bool (*IsAttached)(SDL_Joystick * joystick);

/* Rumble functionality */
int (*Rumble)(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms);

Expand Down
7 changes: 0 additions & 7 deletions src/joystick/android/SDL_sysjoystick.c
Expand Up @@ -617,12 +617,6 @@ ANDROID_JoystickOpen(SDL_Joystick * joystick, int device_index)
return (0);
}

static SDL_bool
ANDROID_JoystickIsAttached(SDL_Joystick *joystick)
{
return joystick->hwdata != NULL;
}

static int
ANDROID_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms)
{
Expand Down Expand Up @@ -698,7 +692,6 @@ SDL_JoystickDriver SDL_ANDROID_JoystickDriver =
ANDROID_JoystickGetDeviceGUID,
ANDROID_JoystickGetDeviceInstanceID,
ANDROID_JoystickOpen,
ANDROID_JoystickIsAttached,
ANDROID_JoystickRumble,
ANDROID_JoystickUpdate,
ANDROID_JoystickClose,
Expand Down
6 changes: 0 additions & 6 deletions src/joystick/bsd/SDL_sysjoystick.c
Expand Up @@ -467,12 +467,6 @@ SDL_SYS_JoystickOpen(SDL_Joystick * joy, int device_index)
return (-1);
}

/* Function to determine if this joystick is attached to the system right now */
SDL_bool SDL_SYS_JoystickAttached(SDL_Joystick *joystick)
{
return SDL_TRUE;
}

void
SDL_SYS_JoystickUpdate(SDL_Joystick * joy)
{
Expand Down
7 changes: 0 additions & 7 deletions src/joystick/darwin/SDL_sysjoystick.c
Expand Up @@ -736,12 +736,6 @@ DARWIN_JoystickOpen(SDL_Joystick * joystick, int device_index)
return 0;
}

static SDL_bool
DARWIN_JoystickIsAttached(SDL_Joystick * joystick)
{
return joystick->hwdata != NULL;
}

/*
* Like strerror but for force feedback errors.
*/
Expand Down Expand Up @@ -1007,7 +1001,6 @@ SDL_JoystickDriver SDL_DARWIN_JoystickDriver =
DARWIN_JoystickGetDeviceGUID,
DARWIN_JoystickGetDeviceInstanceID,
DARWIN_JoystickOpen,
DARWIN_JoystickIsAttached,
DARWIN_JoystickRumble,
DARWIN_JoystickUpdate,
DARWIN_JoystickClose,
Expand Down
7 changes: 0 additions & 7 deletions src/joystick/dummy/SDL_sysjoystick.c
Expand Up @@ -72,12 +72,6 @@ DUMMY_JoystickOpen(SDL_Joystick * joystick, int device_index)
return SDL_SetError("Logic error: No joysticks available");
}

static SDL_bool
DUMMY_JoystickIsAttached(SDL_Joystick *joystick)
{
return SDL_FALSE;
}

static int
DUMMY_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms)
{
Expand Down Expand Up @@ -108,7 +102,6 @@ SDL_JoystickDriver SDL_DUMMY_JoystickDriver =
DUMMY_JoystickGetDeviceGUID,
DUMMY_JoystickGetDeviceInstanceID,
DUMMY_JoystickOpen,
DUMMY_JoystickIsAttached,
DUMMY_JoystickRumble,
DUMMY_JoystickUpdate,
DUMMY_JoystickClose,
Expand Down
6 changes: 0 additions & 6 deletions src/joystick/emscripten/SDL_sysjoystick.c
Expand Up @@ -295,12 +295,6 @@ SDL_SYS_JoystickOpen(SDL_Joystick * joystick, int device_index)
return (0);
}

/* Function to determine if this joystick is attached to the system right now */
SDL_bool SDL_SYS_JoystickAttached(SDL_Joystick *joystick)
{
return joystick->hwdata != NULL;
}

/* Function to update the state of a joystick - called as a device poll.
* This function shouldn't update the joystick structure directly,
* but instead should call SDL_PrivateJoystick*() to deliver events
Expand Down
6 changes: 0 additions & 6 deletions src/joystick/haiku/SDL_haikujoystick.cc
Expand Up @@ -152,12 +152,6 @@ extern "C"
return (0);
}

/* Function to determine if this joystick is attached to the system right now */
SDL_bool SDL_SYS_JoystickAttached(SDL_Joystick *joystick)
{
return SDL_TRUE;
}

/* Function to update the state of a joystick - called as a device poll.
* This function shouldn't update the joystick structure directly,
* but instead should call SDL_PrivateJoystick*() to deliver events
Expand Down
16 changes: 0 additions & 16 deletions src/joystick/hidapi/SDL_hidapijoystick.c
Expand Up @@ -458,21 +458,6 @@ HIDAPI_JoystickOpen(SDL_Joystick * joystick, int device_index)
return 0;
}

static SDL_bool
HIDAPI_JoystickIsAttached(SDL_Joystick *joystick)
{
SDL_HIDAPI_Device *device = SDL_HIDAPI_devices;
while (device) {
if (device->driver) {
if (joystick->instance_id == device->instance_id) {
return SDL_TRUE;
}
}
device = device->next;
}
return SDL_FALSE;
}

static int
HIDAPI_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms)
{
Expand Down Expand Up @@ -529,7 +514,6 @@ SDL_JoystickDriver SDL_HIDAPI_JoystickDriver =
HIDAPI_JoystickGetDeviceGUID,
HIDAPI_JoystickGetDeviceInstanceID,
HIDAPI_JoystickOpen,
HIDAPI_JoystickIsAttached,
HIDAPI_JoystickRumble,
HIDAPI_JoystickUpdate,
HIDAPI_JoystickClose,
Expand Down
7 changes: 0 additions & 7 deletions src/joystick/iphoneos/SDL_sysjoystick.m
Expand Up @@ -425,12 +425,6 @@
return 0;
}

static SDL_bool
IOS_JoystickIsAttached(SDL_Joystick *joystick)
{
return joystick->hwdata != NULL;
}

static void
IOS_AccelerometerUpdate(SDL_Joystick * joystick)
{
Expand Down Expand Up @@ -724,7 +718,6 @@
IOS_JoystickGetDeviceGUID,
IOS_JoystickGetDeviceInstanceID,
IOS_JoystickOpen,
IOS_JoystickIsAttached,
IOS_JoystickRumble,
IOS_JoystickUpdate,
IOS_JoystickClose,
Expand Down
8 changes: 0 additions & 8 deletions src/joystick/linux/SDL_sysjoystick.c
Expand Up @@ -809,13 +809,6 @@ LINUX_JoystickOpen(SDL_Joystick * joystick, int device_index)
return (0);
}

/* Function to determine if this joystick is attached to the system right now */
static SDL_bool
LINUX_JoystickIsAttached(SDL_Joystick *joystick)
{
return joystick->hwdata->item != NULL;
}

static int
LINUX_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms)
{
Expand Down Expand Up @@ -1112,7 +1105,6 @@ SDL_JoystickDriver SDL_LINUX_JoystickDriver =
LINUX_JoystickGetDeviceGUID,
LINUX_JoystickGetDeviceInstanceID,
LINUX_JoystickOpen,
LINUX_JoystickIsAttached,
LINUX_JoystickRumble,
LINUX_JoystickUpdate,
LINUX_JoystickClose,
Expand Down
6 changes: 0 additions & 6 deletions src/joystick/psp/SDL_sysjoystick.c
Expand Up @@ -177,12 +177,6 @@ int SDL_SYS_JoystickOpen(SDL_Joystick *joystick, int device_index)
return 0;
}

/* Function to determine if this joystick is attached to the system right now */
SDL_bool SDL_SYS_JoystickAttached(SDL_Joystick *joystick)
{
return SDL_TRUE;
}

/* Function to update the state of a joystick - called as a device poll.
* This function shouldn't update the joystick structure directly,
* but instead should call SDL_PrivateJoystick*() to deliver events
Expand Down
4 changes: 0 additions & 4 deletions src/joystick/windows/SDL_dinputjoystick.c
Expand Up @@ -955,8 +955,6 @@ UpdateDINPUTJoystickState_Buffered(SDL_Joystick * joystick)

/* Handle the events or punt */
if (FAILED(result)) {
joystick->hwdata->send_remove_event = SDL_TRUE;
joystick->hwdata->removed = SDL_TRUE;
return;
}

Expand Down Expand Up @@ -1011,8 +1009,6 @@ UpdateDINPUTJoystickState_Polled(SDL_Joystick * joystick)
}

if (result != DI_OK) {
joystick->hwdata->send_remove_event = SDL_TRUE;
joystick->hwdata->removed = SDL_TRUE;
return;
}

Expand Down
6 changes: 0 additions & 6 deletions src/joystick/windows/SDL_mmjoystick.c
Expand Up @@ -279,12 +279,6 @@ SDL_SYS_JoystickOpen(SDL_Joystick * joystick, int device_index)
return (0);
}

/* Function to determine if this joystick is attached to the system right now */
SDL_bool SDL_SYS_JoystickAttached(SDL_Joystick *joystick)
{
return SDL_TRUE;
}

static Uint8
TranslatePOV(DWORD value)
{
Expand Down
14 changes: 1 addition & 13 deletions src/joystick/windows/SDL_windowsjoystick.c
Expand Up @@ -463,13 +463,6 @@ WINDOWS_JoystickOpen(SDL_Joystick * joystick, int device_index)
}
}

/* return true if this joystick is plugged in right now */
static SDL_bool
WINDOWS_JoystickIsAttached(SDL_Joystick * joystick)
{
return joystick->hwdata && !joystick->hwdata->removed;
}

static int
WINDOWS_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms)
{
Expand All @@ -483,7 +476,7 @@ WINDOWS_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uin
static void
WINDOWS_JoystickUpdate(SDL_Joystick * joystick)
{
if (!joystick->hwdata || joystick->hwdata->removed) {
if (!joystick->hwdata) {
return;
}

Expand All @@ -492,10 +485,6 @@ WINDOWS_JoystickUpdate(SDL_Joystick * joystick)
} else {
SDL_DINPUT_JoystickUpdate(joystick);
}

if (joystick->hwdata->removed) {
joystick->force_recentering = SDL_TRUE;
}
}

/* Function to close a joystick after use */
Expand Down Expand Up @@ -558,7 +547,6 @@ SDL_JoystickDriver SDL_WINDOWS_JoystickDriver =
WINDOWS_JoystickGetDeviceGUID,
WINDOWS_JoystickGetDeviceInstanceID,
WINDOWS_JoystickOpen,
WINDOWS_JoystickIsAttached,
WINDOWS_JoystickRumble,
WINDOWS_JoystickUpdate,
WINDOWS_JoystickClose,
Expand Down
2 changes: 0 additions & 2 deletions src/joystick/windows/SDL_windowsjoystick_c.h
Expand Up @@ -66,8 +66,6 @@ typedef struct input_t
struct joystick_hwdata
{
SDL_JoystickGUID guid;
SDL_bool removed;
SDL_bool send_remove_event;
Uint32 rumble_expiration;

#if SDL_JOYSTICK_DINPUT
Expand Down
19 changes: 11 additions & 8 deletions src/joystick/windows/SDL_xinputjoystick.c
Expand Up @@ -270,6 +270,15 @@ AddXInputDevice(Uint8 userid, BYTE SubType, JoyStick_DeviceData **pContext)
WINDOWS_AddJoystickDevice(pNewJoystick);
}

static void
DelXInputDevice(Uint8 userid)
{
if (s_arrXInputDevicePath[userid]) {
SDL_free(s_arrXInputDevicePath[userid]);
s_arrXInputDevicePath[userid] = NULL;
}
}

void
SDL_XINPUT_JoystickDetect(JoyStick_DeviceData **pContext)
{
Expand All @@ -285,6 +294,8 @@ SDL_XINPUT_JoystickDetect(JoyStick_DeviceData **pContext)
XINPUT_CAPABILITIES capabilities;
if (XINPUTGETCAPABILITIES(userid, XINPUT_FLAG_GAMEPAD, &capabilities) == ERROR_SUCCESS) {
AddXInputDevice(userid, capabilities.SubType, pContext);
} else {
DelXInputDevice(userid);
}
}
}
Expand Down Expand Up @@ -456,14 +467,6 @@ SDL_XINPUT_JoystickUpdate(SDL_Joystick * joystick)

result = XINPUTGETSTATE(joystick->hwdata->userid, &XInputState);
if (result == ERROR_DEVICE_NOT_CONNECTED) {
Uint8 userid = joystick->hwdata->userid;

joystick->hwdata->send_remove_event = SDL_TRUE;
joystick->hwdata->removed = SDL_TRUE;
if (s_arrXInputDevicePath[userid]) {
SDL_free(s_arrXInputDevicePath[userid]);
s_arrXInputDevicePath[userid] = NULL;
}
return;
}

Expand Down

0 comments on commit 888bf1a

Please sign in to comment.