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

This commit is contained in:
Sam Lantinga 2022-09-05 10:01:28 -07:00
parent fd93f817ba
commit b00e1b1b62
2 changed files with 88 additions and 3 deletions

View file

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

View file

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