24 #include "../../SDL_internal.h"
26 #ifdef SDL_JOYSTICK_HIDAPI
34 #include "../SDL_sysjoystick.h"
39 #ifdef SDL_JOYSTICK_HIDAPI_PS4
43 k_EPS4ReportIdUsbState = 1,
44 k_EPS4ReportIdUsbEffects = 5,
45 k_EPS4ReportIdBluetoothState = 17,
46 k_EPS4ReportIdBluetoothEffects = 17,
47 k_EPS4ReportIdDisconnectMessage = 226,
52 k_ePS4FeatureReportIdGyroCalibration_USB = 0x02,
53 k_ePS4FeatureReportIdGyroCalibration_BT = 0x05,
54 k_ePS4FeatureReportIdSerialNumber = 0x12,
55 } EPS4FeatureReportID;
59 Uint8 ucLeftJoystickX;
60 Uint8 ucLeftJoystickY;
61 Uint8 ucRightJoystickX;
62 Uint8 ucRightJoystickY;
63 Uint8 rgucButtonsHatAndCounter[ 3 ];
76 Uint8 ucTrackpadCounter1;
77 Uint8 rgucTrackpadData1[ 3 ];
78 Uint8 ucTrackpadCounter2;
79 Uint8 rgucTrackpadData2[ 3 ];
95 Uint8 ucVolumeSpeaker;
106 PS4StatePacket_t last_state;
107 } SDL_DriverPS4_Context;
116 for(
i = 0;
i < 8; ++
i) {
117 r = (
r & 1? 0: (
Uint32)0xEDB88320L) ^
r >> 1;
119 return r ^ (
Uint32)0xFF000000L;
138 HIDAPI_DriverPS4_GetDeviceName(
Uint16 vendor_id,
Uint16 product_id)
141 return "PS4 Controller";
151 report[0] = report_id;
165 if (ReadFeatureReport(dev, k_ePS4FeatureReportIdSerialNumber,
data,
sizeof(
data))) {
166 for (
i = 0;
i <
sizeof(
data); ++
i) {
167 if (
data[
i] != 0x00) {
187 SetLedsForPlayerIndex(DS4EffectsState_t *effects,
int player_index)
193 { 0x00, 0x00, 0x40 },
194 { 0x40, 0x00, 0x00 },
195 { 0x00, 0x40, 0x00 },
196 { 0x20, 0x00, 0x20 },
197 { 0x02, 0x01, 0x00 },
198 { 0x00, 0x01, 0x01 },
202 if (player_index >= 0) {
208 effects->ucLedRed =
colors[player_index][0];
209 effects->ucLedGreen =
colors[player_index][1];
210 effects->ucLedBlue =
colors[player_index][2];
214 HIDAPI_DriverPS4_InitDevice(SDL_HIDAPI_Device *
device)
225 static int HIDAPI_DriverPS4_RumbleJoystick(SDL_HIDAPI_Device *
device, SDL_Joystick *joystick,
Uint16 low_frequency_rumble,
Uint16 high_frequency_rumble);
228 HIDAPI_DriverPS4_SetDevicePlayerIndex(SDL_HIDAPI_Device *
device,
SDL_JoystickID instance_id,
int player_index)
230 SDL_DriverPS4_Context *
ctx = (SDL_DriverPS4_Context *)
device->context;
236 ctx->player_index = player_index;
243 HIDAPI_DriverPS4_OpenJoystick(SDL_HIDAPI_Device *
device, SDL_Joystick *joystick)
245 SDL_DriverPS4_Context *
ctx;
263 if (
ctx->is_dongle) {
266 ctx->is_bluetooth = !CheckUSBConnected(
device->dev);
272 SDL_Log(
"PS4 dongle = %s, bluetooth = %s\n",
ctx->is_dongle ?
"TRUE" :
"FALSE",
ctx->is_bluetooth ?
"TRUE" :
"FALSE");
281 if (HIDAPI_DriverPS4_CanRumble(
device->vendor_id,
device->product_id)) {
282 if (
ctx->is_bluetooth) {
293 HIDAPI_DriverPS4_RumbleJoystick(
device, joystick, 0, 0);
296 joystick->nbuttons = 16;
304 HIDAPI_DriverPS4_RumbleJoystick(SDL_HIDAPI_Device *
device, SDL_Joystick *joystick,
Uint16 low_frequency_rumble,
Uint16 high_frequency_rumble)
306 SDL_DriverPS4_Context *
ctx = (SDL_DriverPS4_Context *)
device->context;
307 DS4EffectsState_t *effects;
311 if (!
ctx->rumble_supported) {
318 if (
ctx->is_bluetooth) {
319 data[0] = k_EPS4ReportIdBluetoothEffects;
320 data[1] = 0xC0 | 0x04;
326 data[0] = k_EPS4ReportIdUsbEffects;
334 effects->ucRumbleLeft = (low_frequency_rumble >> 8);
335 effects->ucRumbleRight = (high_frequency_rumble >> 8);
338 SetLedsForPlayerIndex(effects,
ctx->player_index);
340 if (
ctx->is_bluetooth) {
344 unCRC = crc32(0, &ubHdr, 1);
345 unCRC = crc32(unCRC,
data, (
Uint32)(report_size -
sizeof(unCRC)));
346 SDL_memcpy(&
data[report_size -
sizeof(unCRC)], &unCRC,
sizeof(unCRC));
349 if (SDL_HIDAPI_SendRumble(
device,
data, report_size) != report_size) {
356 HIDAPI_DriverPS4_HandleStatePacket(SDL_Joystick *joystick,
hid_device *dev, SDL_DriverPS4_Context *
ctx, PS4StatePacket_t *packet)
360 if (
ctx->last_state.rgucButtonsHatAndCounter[0] != packet->rgucButtonsHatAndCounter[0]) {
362 Uint8 data = (packet->rgucButtonsHatAndCounter[0] >> 4);
370 Uint8 data = (packet->rgucButtonsHatAndCounter[0] & 0x0F);
415 if (
ctx->last_state.rgucButtonsHatAndCounter[1] != packet->rgucButtonsHatAndCounter[1]) {
416 Uint8 data = packet->rgucButtonsHatAndCounter[1];
426 if (
ctx->last_state.rgucButtonsHatAndCounter[2] != packet->rgucButtonsHatAndCounter[2]) {
427 Uint8 data = (packet->rgucButtonsHatAndCounter[2] & 0x03);
433 axis = ((int)packet->ucTriggerLeft * 257) - 32768;
435 axis = ((int)packet->ucTriggerRight * 257) - 32768;
437 axis = ((int)packet->ucLeftJoystickX * 257) - 32768;
439 axis = ((int)packet->ucLeftJoystickY * 257) - 32768;
441 axis = ((int)packet->ucRightJoystickX * 257) - 32768;
443 axis = ((int)packet->ucRightJoystickY * 257) - 32768;
446 if (packet->ucBatteryLevel & 0x10) {
450 int level = (packet->ucBatteryLevel & 0xF);
453 }
else if (
level <= 2) {
455 }
else if (
level <= 7) {
466 HIDAPI_DriverPS4_UpdateDevice(SDL_HIDAPI_Device *
device)
468 SDL_DriverPS4_Context *
ctx = (SDL_DriverPS4_Context *)
device->context;
469 SDL_Joystick *joystick =
NULL;
482 case k_EPS4ReportIdUsbState:
483 HIDAPI_DriverPS4_HandleStatePacket(joystick,
device->dev,
ctx, (PS4StatePacket_t *)&
data[1]);
485 case k_EPS4ReportIdBluetoothState:
487 HIDAPI_DriverPS4_HandleStatePacket(joystick,
device->dev,
ctx, (PS4StatePacket_t *)&
data[3]);
490 #ifdef DEBUG_JOYSTICK
505 HIDAPI_DriverPS4_CloseJoystick(SDL_HIDAPI_Device *
device, SDL_Joystick *joystick)
515 HIDAPI_DriverPS4_FreeDevice(SDL_HIDAPI_Device *
device)
523 HIDAPI_DriverPS4_IsSupportedDevice,
524 HIDAPI_DriverPS4_GetDeviceName,
525 HIDAPI_DriverPS4_InitDevice,
526 HIDAPI_DriverPS4_GetDevicePlayerIndex,
527 HIDAPI_DriverPS4_SetDevicePlayerIndex,
528 HIDAPI_DriverPS4_UpdateDevice,
529 HIDAPI_DriverPS4_OpenJoystick,
530 HIDAPI_DriverPS4_RumbleJoystick,
531 HIDAPI_DriverPS4_CloseJoystick,
532 HIDAPI_DriverPS4_FreeDevice