Browse Source

Added support for a ShanWan PS2 -> PS3 USB converter to the HIDAPI driver

Sam Lantinga 3 years ago
parent
commit
b00e1b1b62
2 changed files with 88 additions and 3 deletions
  1. 86 3
      src/joystick/hidapi/SDL_hidapi_ps3.c
  2. 2 0
      src/joystick/usb_ids.h

+ 86 - 3
src/joystick/hidapi/SDL_hidapi_ps3.c

@@ -18,9 +18,6 @@
      misrepresented as being the original software.
      misrepresented as being the original software.
   3. This notice may not be removed or altered from any source distribution.
   3. This notice may not be removed or altered from any source distribution.
 */
 */
-/* This driver supports both simplified reports and the extended input reports enabled by Steam.
-   Code and logic contributed by Valve Corporation under the SDL zlib license.
-*/
 #include "../../SDL_internal.h"
 #include "../../SDL_internal.h"
 
 
 #ifdef SDL_JOYSTICK_HIDAPI
 #ifdef SDL_JOYSTICK_HIDAPI
@@ -109,6 +106,9 @@ HIDAPI_DriverPS3_IsSupportedDevice(SDL_HIDAPI_Device *device, const char *name,
     if (vendor_id == USB_VENDOR_SONY && product_id == USB_PRODUCT_SONY_DS3) {
     if (vendor_id == USB_VENDOR_SONY && product_id == USB_PRODUCT_SONY_DS3) {
         return SDL_TRUE;
         return SDL_TRUE;
     }
     }
+    if (vendor_id == USB_VENDOR_SHANWAN && product_id == USB_PRODUCT_SHANWAN_DS3) {
+        return SDL_TRUE;
+    }
     return SDL_FALSE;
     return SDL_FALSE;
 }
 }
 
 
@@ -323,6 +323,83 @@ HIDAPI_DriverPS3_ScaleAccel(Sint16 value)
     return (float)(value - 511) / 113.0f;
     return (float)(value - 511) / 113.0f;
 }
 }
 
 
+static void
+HIDAPI_DriverPS3_HandleMiniStatePacket(SDL_Joystick *joystick, SDL_DriverPS3_Context *ctx, Uint8 *data, int size)
+{
+    Sint16 axis;
+
+    if (ctx->last_state[4] != data[4]) {
+        SDL_bool dpad_up = SDL_FALSE;
+        SDL_bool dpad_down = SDL_FALSE;
+        SDL_bool dpad_left = SDL_FALSE;
+        SDL_bool dpad_right = SDL_FALSE;
+
+        switch (data[4] & 0x0f) {
+        case 0:
+            dpad_up = SDL_TRUE;
+            break;
+        case 1:
+            dpad_up = SDL_TRUE;
+            dpad_right = SDL_TRUE;
+            break;
+        case 2:
+            dpad_right = SDL_TRUE;
+            break;
+        case 3:
+            dpad_right = SDL_TRUE;
+            dpad_down = SDL_TRUE;
+            break;
+        case 4:
+            dpad_down = SDL_TRUE;
+            break;
+        case 5:
+            dpad_left = SDL_TRUE;
+            dpad_down = SDL_TRUE;
+            break;
+        case 6:
+            dpad_left = SDL_TRUE;
+            break;
+        case 7:
+            dpad_up = SDL_TRUE;
+            dpad_left = SDL_TRUE;
+            break;
+        default:
+            break;
+        }
+        SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_DOWN, dpad_down);
+        SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_UP, dpad_up);
+        SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_RIGHT, dpad_right);
+        SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_LEFT, dpad_left);
+
+        SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_Y, (data[4] & 0x10) ? SDL_PRESSED : SDL_RELEASED);
+        SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_B, (data[4] & 0x20) ? SDL_PRESSED : SDL_RELEASED);
+        SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_A, (data[4] & 0x40) ? SDL_PRESSED : SDL_RELEASED);
+        SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_X, (data[4] & 0x80) ? SDL_PRESSED : SDL_RELEASED);
+    }
+
+    if (ctx->last_state[5] != data[5]) {
+        SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_LEFTSHOULDER, (data[5] & 0x01) ? SDL_PRESSED : SDL_RELEASED);
+        SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER, (data[5] & 0x02) ? SDL_PRESSED : SDL_RELEASED);
+        SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERLEFT, (data[5] & 0x04) ? SDL_JOYSTICK_AXIS_MAX : SDL_JOYSTICK_AXIS_MIN);
+        SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERRIGHT, (data[5] & 0x08) ? SDL_JOYSTICK_AXIS_MAX : SDL_JOYSTICK_AXIS_MIN);
+        SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_BACK, (data[5] & 0x10) ? SDL_PRESSED : SDL_RELEASED);
+        SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_START, (data[5] & 0x20) ? SDL_PRESSED : SDL_RELEASED);
+        SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_LEFTSTICK, (data[5] & 0x40) ? SDL_PRESSED : SDL_RELEASED);
+        SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_RIGHTSTICK, (data[5] & 0x80) ? SDL_PRESSED : SDL_RELEASED);
+    }
+
+    axis = ((int)data[2] * 257) - 32768;
+    SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_LEFTX, axis);
+    axis = ((int)data[3] * 257) - 32768;
+    SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_LEFTY, axis);
+    axis = ((int)data[0] * 257) - 32768;
+    SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTX, axis);
+    axis = ((int)data[1] * 257) - 32768;
+    SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTY, axis);
+
+    SDL_memcpy(ctx->last_state, data, SDL_min(size, sizeof(ctx->last_state)));
+}
+
 static void
 static void
 HIDAPI_DriverPS3_HandleStatePacket(SDL_Joystick *joystick, SDL_DriverPS3_Context *ctx, Uint8 *data, int size)
 HIDAPI_DriverPS3_HandleStatePacket(SDL_Joystick *joystick, SDL_DriverPS3_Context *ctx, Uint8 *data, int size)
 {
 {
@@ -431,6 +508,12 @@ HIDAPI_DriverPS3_UpdateDevice(SDL_HIDAPI_Device *device)
         HIDAPI_DumpPacket("PS3 packet: size = %d", data, size);
         HIDAPI_DumpPacket("PS3 packet: size = %d", data, size);
 #endif
 #endif
 
 
+        if (size == 7) {
+            /* Seen on a ShanWan PS2 -> PS3 USB converter */
+            HIDAPI_DriverPS3_HandleMiniStatePacket(joystick, ctx, data, size);
+            continue;
+        }
+
         switch (data[0]) {
         switch (data[0]) {
         case k_EPS3ReportIdState:
         case k_EPS3ReportIdState:
             if (data[1] == 0xFF) {
             if (data[1] == 0xFF) {

+ 2 - 0
src/joystick/usb_ids.h

@@ -37,6 +37,7 @@
 #define USB_VENDOR_POWERA       0x24c6
 #define USB_VENDOR_POWERA       0x24c6
 #define USB_VENDOR_POWERA_ALT   0x20d6
 #define USB_VENDOR_POWERA_ALT   0x20d6
 #define USB_VENDOR_RAZER        0x1532
 #define USB_VENDOR_RAZER        0x1532
+#define USB_VENDOR_SHANWAN      0x2563
 #define USB_VENDOR_SHENZHEN     0x0079
 #define USB_VENDOR_SHENZHEN     0x0079
 #define USB_VENDOR_SONY         0x054c
 #define USB_VENDOR_SONY         0x054c
 #define USB_VENDOR_VALVE        0x28de
 #define USB_VENDOR_VALVE        0x28de
@@ -62,6 +63,7 @@
 #define USB_PRODUCT_RAZER_PANTHERA                          0x0401
 #define USB_PRODUCT_RAZER_PANTHERA                          0x0401
 #define USB_PRODUCT_RAZER_PANTHERA_EVO                      0x1008
 #define USB_PRODUCT_RAZER_PANTHERA_EVO                      0x1008
 #define USB_PRODUCT_RAZER_ATROX                             0x0a00
 #define USB_PRODUCT_RAZER_ATROX                             0x0a00
+#define USB_PRODUCT_SHANWAN_DS3                             0x0523
 #define USB_PRODUCT_SONY_DS3                                0x0268
 #define USB_PRODUCT_SONY_DS3                                0x0268
 #define USB_PRODUCT_SONY_DS4                                0x05c4
 #define USB_PRODUCT_SONY_DS4                                0x05c4
 #define USB_PRODUCT_SONY_DS4_DONGLE                         0x0ba0
 #define USB_PRODUCT_SONY_DS4_DONGLE                         0x0ba0