Skip to content
Permalink
Browse files

Worked around bug with Sony PS Now PS3 controller where DirectInput p…

…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 888bf1af69492fb5044a5a7082132e7e2ee0fdf3
@@ -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);
@@ -545,7 +546,7 @@ SDL_JoystickGetAttached(SDL_Joystick * joystick)
return SDL_FALSE;
}

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

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

void SDL_PrivateJoystickRemoved(SDL_JoystickID device_instance)
{
SDL_Joystick *joystick;

#if !SDL_EVENTS_DISABLED
SDL_Event event;

@@ -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
@@ -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) {
@@ -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 */
@@ -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);

@@ -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)
{
@@ -698,7 +692,6 @@ SDL_JoystickDriver SDL_ANDROID_JoystickDriver =
ANDROID_JoystickGetDeviceGUID,
ANDROID_JoystickGetDeviceInstanceID,
ANDROID_JoystickOpen,
ANDROID_JoystickIsAttached,
ANDROID_JoystickRumble,
ANDROID_JoystickUpdate,
ANDROID_JoystickClose,
@@ -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)
{
@@ -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.
*/
@@ -1007,7 +1001,6 @@ SDL_JoystickDriver SDL_DARWIN_JoystickDriver =
DARWIN_JoystickGetDeviceGUID,
DARWIN_JoystickGetDeviceInstanceID,
DARWIN_JoystickOpen,
DARWIN_JoystickIsAttached,
DARWIN_JoystickRumble,
DARWIN_JoystickUpdate,
DARWIN_JoystickClose,
@@ -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)
{
@@ -108,7 +102,6 @@ SDL_JoystickDriver SDL_DUMMY_JoystickDriver =
DUMMY_JoystickGetDeviceGUID,
DUMMY_JoystickGetDeviceInstanceID,
DUMMY_JoystickOpen,
DUMMY_JoystickIsAttached,
DUMMY_JoystickRumble,
DUMMY_JoystickUpdate,
DUMMY_JoystickClose,
@@ -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
@@ -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
@@ -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)
{
@@ -529,7 +514,6 @@ SDL_JoystickDriver SDL_HIDAPI_JoystickDriver =
HIDAPI_JoystickGetDeviceGUID,
HIDAPI_JoystickGetDeviceInstanceID,
HIDAPI_JoystickOpen,
HIDAPI_JoystickIsAttached,
HIDAPI_JoystickRumble,
HIDAPI_JoystickUpdate,
HIDAPI_JoystickClose,
@@ -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)
{
@@ -724,7 +718,6 @@
IOS_JoystickGetDeviceGUID,
IOS_JoystickGetDeviceInstanceID,
IOS_JoystickOpen,
IOS_JoystickIsAttached,
IOS_JoystickRumble,
IOS_JoystickUpdate,
IOS_JoystickClose,
@@ -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)
{
@@ -1112,7 +1105,6 @@ SDL_JoystickDriver SDL_LINUX_JoystickDriver =
LINUX_JoystickGetDeviceGUID,
LINUX_JoystickGetDeviceInstanceID,
LINUX_JoystickOpen,
LINUX_JoystickIsAttached,
LINUX_JoystickRumble,
LINUX_JoystickUpdate,
LINUX_JoystickClose,
@@ -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
@@ -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;
}

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

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

@@ -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 */
@@ -558,7 +547,6 @@ SDL_JoystickDriver SDL_WINDOWS_JoystickDriver =
WINDOWS_JoystickGetDeviceGUID,
WINDOWS_JoystickGetDeviceInstanceID,
WINDOWS_JoystickOpen,
WINDOWS_JoystickIsAttached,
WINDOWS_JoystickRumble,
WINDOWS_JoystickUpdate,
WINDOWS_JoystickClose,
@@ -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
@@ -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)
{
@@ -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);
}
}
}
@@ -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;
}

0 comments on commit 888bf1a

Please sign in to comment.