Added support for the Logitech ChillStream (cherry picked from commit 6f7edaf8920c504ebd3e797bd04ec1d2e46c4aa9)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162
diff --git a/src/joystick/hidapi/SDL_hidapi_ps3.c b/src/joystick/hidapi/SDL_hidapi_ps3.c
index 6973b7b..157335c 100644
--- a/src/joystick/hidapi/SDL_hidapi_ps3.c
+++ b/src/joystick/hidapi/SDL_hidapi_ps3.c
@@ -616,6 +616,11 @@ static SDL_bool HIDAPI_DriverPS3ThirdParty_InitDevice(SDL_HIDAPI_Device *device)
device->type = SDL_CONTROLLER_TYPE_PS3;
+ if (device->vendor_id == USB_VENDOR_LOGITECH &&
+ device->product_id == USB_PRODUCT_LOGITECH_CHILLSTREAM) {
+ HIDAPI_SetDeviceName(device, "Logitech ChillStream");
+ }
+
return HIDAPI_JoystickConnected(device, NULL);
}
@@ -675,7 +680,120 @@ static int HIDAPI_DriverPS3ThirdParty_SetJoystickSensorsEnabled(SDL_HIDAPI_Devic
return SDL_Unsupported();
}
-static void HIDAPI_DriverPS3ThirdParty_HandleStatePacket(SDL_Joystick *joystick, SDL_DriverPS3_Context *ctx, Uint8 *data, int size)
+static void HIDAPI_DriverPS3ThirdParty_HandleStatePacket18(SDL_Joystick *joystick, SDL_DriverPS3_Context *ctx, Uint8 *data, int size)
+{
+ Sint16 axis;
+ Uint64 timestamp = SDL_GetTicksNS();
+
+ if (ctx->last_state[0] != data[0]) {
+ SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_X, (data[0] & 0x01) ? SDL_PRESSED : SDL_RELEASED);
+ SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_A, (data[0] & 0x02) ? SDL_PRESSED : SDL_RELEASED);
+ SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_B, (data[0] & 0x04) ? SDL_PRESSED : SDL_RELEASED);
+ SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_Y, (data[0] & 0x08) ? SDL_PRESSED : SDL_RELEASED);
+ SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_LEFT_SHOULDER, (data[0] & 0x10) ? SDL_PRESSED : SDL_RELEASED);
+ SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER, (data[0] & 0x20) ? SDL_PRESSED : SDL_RELEASED);
+ }
+
+ if (ctx->last_state[1] != data[1]) {
+ SDL_bool dpad_up = SDL_FALSE;
+ SDL_bool dpad_down = SDL_FALSE;
+ SDL_bool dpad_left = SDL_FALSE;
+ SDL_bool dpad_right = SDL_FALSE;
+
+ SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_BACK, (data[1] & 0x01) ? SDL_PRESSED : SDL_RELEASED);
+ SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_START, (data[1] & 0x02) ? SDL_PRESSED : SDL_RELEASED);
+ SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_LEFT_STICK, (data[1] & 0x04) ? SDL_PRESSED : SDL_RELEASED);
+ SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_RIGHT_STICK, (data[1] & 0x08) ? SDL_PRESSED : SDL_RELEASED);
+
+ switch (data[1] >> 4) {
+ 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_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_DPAD_DOWN, dpad_down);
+ SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_DPAD_UP, dpad_up);
+ SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_DPAD_RIGHT, dpad_right);
+ SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_DPAD_LEFT, dpad_left);
+ }
+
+ axis = ((int)data[16] * 257) - 32768;
+ SDL_SendJoystickAxis(timestamp, joystick, SDL_GAMEPAD_AXIS_LEFT_TRIGGER, axis);
+ axis = ((int)data[17] * 257) - 32768;
+ SDL_SendJoystickAxis(timestamp, joystick, SDL_GAMEPAD_AXIS_RIGHT_TRIGGER, axis);
+ axis = ((int)data[2] * 257) - 32768;
+ SDL_SendJoystickAxis(timestamp, joystick, SDL_GAMEPAD_AXIS_LEFTX, axis);
+ axis = ((int)data[3] * 257) - 32768;
+ SDL_SendJoystickAxis(timestamp, joystick, SDL_GAMEPAD_AXIS_LEFTY, axis);
+ axis = ((int)data[4] * 257) - 32768;
+ SDL_SendJoystickAxis(timestamp, joystick, SDL_GAMEPAD_AXIS_RIGHTX, axis);
+ axis = ((int)data[5] * 257) - 32768;
+ SDL_SendJoystickAxis(timestamp, joystick, SDL_GAMEPAD_AXIS_RIGHTY, axis);
+
+ /* Buttons are mapped as axes in the order they appear in the button enumeration */
+ {
+ static int button_axis_offsets[] = {
+ 12, /* SDL_GAMEPAD_BUTTON_A */
+ 11, /* SDL_GAMEPAD_BUTTON_B */
+ 13, /* SDL_GAMEPAD_BUTTON_X */
+ 10, /* SDL_GAMEPAD_BUTTON_Y */
+ 0, /* SDL_GAMEPAD_BUTTON_BACK */
+ 0, /* SDL_GAMEPAD_BUTTON_GUIDE */
+ 0, /* SDL_GAMEPAD_BUTTON_START */
+ 0, /* SDL_GAMEPAD_BUTTON_LEFT_STICK */
+ 0, /* SDL_GAMEPAD_BUTTON_RIGHT_STICK */
+ 14, /* SDL_GAMEPAD_BUTTON_LEFT_SHOULDER */
+ 16, /* SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER */
+ 8, /* SDL_GAMEPAD_BUTTON_DPAD_UP */
+ 9, /* SDL_GAMEPAD_BUTTON_DPAD_DOWN */
+ 7, /* SDL_GAMEPAD_BUTTON_DPAD_LEFT */
+ 6, /* SDL_GAMEPAD_BUTTON_DPAD_RIGHT */
+ };
+ int i, axis_index = 6;
+
+ for (i = 0; i < SDL_arraysize(button_axis_offsets); ++i) {
+ int offset = button_axis_offsets[i];
+ if (!offset) {
+ /* This button doesn't report as an axis */
+ continue;
+ }
+
+ axis = ((int)data[offset] * 257) - 32768;
+ SDL_SendJoystickAxis(timestamp, joystick, axis_index, axis);
+ ++axis_index;
+ }
+ }
+
+ SDL_memcpy(ctx->last_state, data, SDL_min(size, sizeof(ctx->last_state)));
+}
+
+static void HIDAPI_DriverPS3ThirdParty_HandleStatePacket19(SDL_Joystick *joystick, SDL_DriverPS3_Context *ctx, Uint8 *data, int size)
{
Sint16 axis;
@@ -812,7 +930,10 @@ static SDL_bool HIDAPI_DriverPS3ThirdParty_UpdateDevice(SDL_HIDAPI_Device *devic
}
if (size >= 19) {
- HIDAPI_DriverPS3ThirdParty_HandleStatePacket(joystick, ctx, data, size);
+ HIDAPI_DriverPS3ThirdParty_HandleStatePacket19(joystick, ctx, data, size);
+ } else if (size == 18) {
+ /* This packet format was seen with the Logitech ChillStream */
+ HIDAPI_DriverPS3ThirdParty_HandleStatePacket18(joystick, ctx, data, size);
} else {
#ifdef DEBUG_JOYSTICK
SDL_Log("Unknown PS3 packet, size %d\n", size);
diff --git a/src/joystick/usb_ids.h b/src/joystick/usb_ids.h
index 1d1041d..134364b 100644
--- a/src/joystick/usb_ids.h
+++ b/src/joystick/usb_ids.h
@@ -78,6 +78,7 @@
#define USB_PRODUCT_HORI_HORIPAD_PRO_SERIES_X 0x014f
#define USB_PRODUCT_HORI_FIGHTING_STICK_ALPHA_PS4 0x011c
#define USB_PRODUCT_HORI_FIGHTING_STICK_ALPHA_PS5 0x0184
+#define USB_PRODUCT_LOGITECH_CHILLSTREAM 0xcad1
#define USB_PRODUCT_NINTENDO_GAMECUBE_ADAPTER 0x0337
#define USB_PRODUCT_NINTENDO_N64_CONTROLLER 0x2019
#define USB_PRODUCT_NINTENDO_SEGA_GENESIS_CONTROLLER 0x201e