浏览代码

Worked around bug with Sony PS Now PS3 controller where DirectInput polling 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

Sam Lantinga 7 年之前
父节点
当前提交
888bf1af69

+ 18 - 4
src/joystick/SDL_joystick.c

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

+ 1 - 5
src/joystick/SDL_sysjoystick.h

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

+ 0 - 7
src/joystick/android/SDL_sysjoystick.c

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

+ 0 - 6
src/joystick/bsd/SDL_sysjoystick.c

@@ -467,12 +467,6 @@ desc_failed:
     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)
 {

+ 0 - 7
src/joystick/darwin/SDL_sysjoystick.c

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

+ 0 - 7
src/joystick/dummy/SDL_sysjoystick.c

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

+ 0 - 6
src/joystick/emscripten/SDL_sysjoystick.c

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

+ 0 - 6
src/joystick/haiku/SDL_haikujoystick.cc

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

+ 0 - 16
src/joystick/hidapi/SDL_hidapijoystick.c

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

+ 0 - 7
src/joystick/iphoneos/SDL_sysjoystick.m

@@ -425,12 +425,6 @@ IOS_JoystickOpen(SDL_Joystick * joystick, int device_index)
     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 @@ SDL_JoystickDriver SDL_IOS_JoystickDriver =
     IOS_JoystickGetDeviceGUID,
     IOS_JoystickGetDeviceInstanceID,
     IOS_JoystickOpen,
-    IOS_JoystickIsAttached,
     IOS_JoystickRumble,
     IOS_JoystickUpdate,
     IOS_JoystickClose,

+ 0 - 8
src/joystick/linux/SDL_sysjoystick.c

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

+ 0 - 6
src/joystick/psp/SDL_sysjoystick.c

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

+ 0 - 4
src/joystick/windows/SDL_dinputjoystick.c

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

+ 0 - 6
src/joystick/windows/SDL_mmjoystick.c

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

+ 1 - 13
src/joystick/windows/SDL_windowsjoystick.c

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

+ 0 - 2
src/joystick/windows/SDL_windowsjoystick_c.h

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

+ 11 - 8
src/joystick/windows/SDL_xinputjoystick.c

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