SDL_hidapi_ps5.c 54 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464
  1. /*
  2. Simple DirectMedia Layer
  3. Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
  4. This software is provided 'as-is', without any express or implied
  5. warranty. In no event will the authors be held liable for any damages
  6. arising from the use of this software.
  7. Permission is granted to anyone to use this software for any purpose,
  8. including commercial applications, and to alter it and redistribute it
  9. freely, subject to the following restrictions:
  10. 1. The origin of this software must not be misrepresented; you must not
  11. claim that you wrote the original software. If you use this software
  12. in a product, an acknowledgment in the product documentation would be
  13. appreciated but is not required.
  14. 2. Altered source versions must be plainly marked as such, and must not be
  15. misrepresented as being the original software.
  16. 3. This notice may not be removed or altered from any source distribution.
  17. */
  18. #include "../../SDL_internal.h"
  19. #ifdef SDL_JOYSTICK_HIDAPI
  20. #include "SDL_events.h"
  21. #include "SDL_timer.h"
  22. #include "SDL_joystick.h"
  23. #include "SDL_gamecontroller.h"
  24. #include "../../SDL_hints_c.h"
  25. #include "../SDL_sysjoystick.h"
  26. #include "SDL_hidapijoystick_c.h"
  27. #include "SDL_hidapi_rumble.h"
  28. #ifdef SDL_JOYSTICK_HIDAPI_PS5
  29. /* Define this if you want to log all packets from the controller */
  30. /*#define DEBUG_PS5_PROTOCOL*/
  31. /* Define this if you want to log calibration data */
  32. /*#define DEBUG_PS5_CALIBRATION*/
  33. #define GYRO_RES_PER_DEGREE 1024.0f
  34. #define ACCEL_RES_PER_G 8192.0f
  35. #define BLUETOOTH_DISCONNECT_TIMEOUT_MS 500
  36. #define LOAD16(A, B) (Sint16)((Uint16)(A) | (((Uint16)(B)) << 8))
  37. #define LOAD32(A, B, C, D) ((((Uint32)(A)) << 0) | \
  38. (((Uint32)(B)) << 8) | \
  39. (((Uint32)(C)) << 16) | \
  40. (((Uint32)(D)) << 24))
  41. typedef enum
  42. {
  43. k_EPS5ReportIdState = 0x01,
  44. k_EPS5ReportIdUsbEffects = 0x02,
  45. k_EPS5ReportIdBluetoothEffects = 0x31,
  46. k_EPS5ReportIdBluetoothState = 0x31,
  47. } EPS5ReportId;
  48. typedef enum
  49. {
  50. k_EPS5FeatureReportIdCapabilities = 0x03,
  51. k_EPS5FeatureReportIdCalibration = 0x05,
  52. k_EPS5FeatureReportIdSerialNumber = 0x09,
  53. k_EPS5FeatureReportIdFirmwareInfo = 0x20,
  54. } EPS5FeatureReportId;
  55. typedef struct
  56. {
  57. Uint8 ucLeftJoystickX;
  58. Uint8 ucLeftJoystickY;
  59. Uint8 ucRightJoystickX;
  60. Uint8 ucRightJoystickY;
  61. Uint8 rgucButtonsHatAndCounter[3];
  62. Uint8 ucTriggerLeft;
  63. Uint8 ucTriggerRight;
  64. } PS5SimpleStatePacket_t;
  65. typedef struct
  66. {
  67. Uint8 ucLeftJoystickX; /* 0 */
  68. Uint8 ucLeftJoystickY; /* 1 */
  69. Uint8 ucRightJoystickX; /* 2 */
  70. Uint8 ucRightJoystickY; /* 3 */
  71. Uint8 ucTriggerLeft; /* 4 */
  72. Uint8 ucTriggerRight; /* 5 */
  73. Uint8 ucCounter; /* 6 */
  74. Uint8 rgucButtonsAndHat[4]; /* 7 */
  75. Uint8 rgucPacketSequence[4]; /* 11 - 32 bit little endian */
  76. Uint8 rgucGyroX[2]; /* 15 */
  77. Uint8 rgucGyroY[2]; /* 17 */
  78. Uint8 rgucGyroZ[2]; /* 19 */
  79. Uint8 rgucAccelX[2]; /* 21 */
  80. Uint8 rgucAccelY[2]; /* 23 */
  81. Uint8 rgucAccelZ[2]; /* 25 */
  82. Uint8 rgucSensorTimestamp[4]; /* 27 - 32 bit little endian */
  83. } PS5StatePacketCommon_t;
  84. typedef struct
  85. {
  86. Uint8 ucLeftJoystickX; /* 0 */
  87. Uint8 ucLeftJoystickY; /* 1 */
  88. Uint8 ucRightJoystickX; /* 2 */
  89. Uint8 ucRightJoystickY; /* 3 */
  90. Uint8 ucTriggerLeft; /* 4 */
  91. Uint8 ucTriggerRight; /* 5 */
  92. Uint8 ucCounter; /* 6 */
  93. Uint8 rgucButtonsAndHat[4]; /* 7 */
  94. Uint8 rgucPacketSequence[4]; /* 11 - 32 bit little endian */
  95. Uint8 rgucGyroX[2]; /* 15 */
  96. Uint8 rgucGyroY[2]; /* 17 */
  97. Uint8 rgucGyroZ[2]; /* 19 */
  98. Uint8 rgucAccelX[2]; /* 21 */
  99. Uint8 rgucAccelY[2]; /* 23 */
  100. Uint8 rgucAccelZ[2]; /* 25 */
  101. Uint8 rgucSensorTimestamp[4]; /* 27 - 32 bit little endian */
  102. Uint8 ucSensorTemp; /* 31 */
  103. Uint8 ucTouchpadCounter1; /* 32 - high bit clear + counter */
  104. Uint8 rgucTouchpadData1[3]; /* 33 - X/Y, 12 bits per axis */
  105. Uint8 ucTouchpadCounter2; /* 36 - high bit clear + counter */
  106. Uint8 rgucTouchpadData2[3]; /* 37 - X/Y, 12 bits per axis */
  107. Uint8 rgucUnknown1[8]; /* 40 */
  108. Uint8 rgucTimer2[4]; /* 48 - 32 bit little endian */
  109. Uint8 ucBatteryLevel; /* 52 */
  110. Uint8 ucConnectState; /* 53 - 0x08 = USB, 0x01 = headphone */
  111. /* There's more unknown data at the end, and a 32-bit CRC on Bluetooth */
  112. } PS5StatePacket_t;
  113. typedef struct
  114. {
  115. Uint8 ucLeftJoystickX; /* 0 */
  116. Uint8 ucLeftJoystickY; /* 1 */
  117. Uint8 ucRightJoystickX; /* 2 */
  118. Uint8 ucRightJoystickY; /* 3 */
  119. Uint8 ucTriggerLeft; /* 4 */
  120. Uint8 ucTriggerRight; /* 5 */
  121. Uint8 ucCounter; /* 6 */
  122. Uint8 rgucButtonsAndHat[4]; /* 7 */
  123. Uint8 rgucPacketSequence[4]; /* 11 - 32 bit little endian */
  124. Uint8 rgucGyroX[2]; /* 15 */
  125. Uint8 rgucGyroY[2]; /* 17 */
  126. Uint8 rgucGyroZ[2]; /* 19 */
  127. Uint8 rgucAccelX[2]; /* 21 */
  128. Uint8 rgucAccelY[2]; /* 23 */
  129. Uint8 rgucAccelZ[2]; /* 25 */
  130. Uint8 rgucSensorTimestamp[4]; /* 27 - 32 bit little endian */
  131. Uint8 ucTouchpadCounter1; /* 31 - high bit clear + counter */
  132. Uint8 rgucTouchpadData1[3]; /* 32 - X/Y, 12 bits per axis */
  133. Uint8 ucTouchpadCounter2; /* 35 - high bit clear + counter */
  134. Uint8 rgucTouchpadData2[3]; /* 36 - X/Y, 12 bits per axis */
  135. /* There's more unknown data at the end, and a 32-bit CRC on Bluetooth */
  136. } PS5StatePacketAlt_t;
  137. typedef struct
  138. {
  139. Uint8 ucEnableBits1; /* 0 */
  140. Uint8 ucEnableBits2; /* 1 */
  141. Uint8 ucRumbleRight; /* 2 */
  142. Uint8 ucRumbleLeft; /* 3 */
  143. Uint8 ucHeadphoneVolume; /* 4 */
  144. Uint8 ucSpeakerVolume; /* 5 */
  145. Uint8 ucMicrophoneVolume; /* 6 */
  146. Uint8 ucAudioEnableBits; /* 7 */
  147. Uint8 ucMicLightMode; /* 8 */
  148. Uint8 ucAudioMuteBits; /* 9 */
  149. Uint8 rgucRightTriggerEffect[11]; /* 10 */
  150. Uint8 rgucLeftTriggerEffect[11]; /* 21 */
  151. Uint8 rgucUnknown1[6]; /* 32 */
  152. Uint8 ucEnableBits3; /* 38 */
  153. Uint8 rgucUnknown2[2]; /* 39 */
  154. Uint8 ucLedAnim; /* 41 */
  155. Uint8 ucLedBrightness; /* 42 */
  156. Uint8 ucPadLights; /* 43 */
  157. Uint8 ucLedRed; /* 44 */
  158. Uint8 ucLedGreen; /* 45 */
  159. Uint8 ucLedBlue; /* 46 */
  160. } DS5EffectsState_t;
  161. typedef enum {
  162. k_EDS5EffectRumbleStart = (1 << 0),
  163. k_EDS5EffectRumble = (1 << 1),
  164. k_EDS5EffectLEDReset = (1 << 2),
  165. k_EDS5EffectLED = (1 << 3),
  166. k_EDS5EffectPadLights = (1 << 4),
  167. k_EDS5EffectMicLight = (1 << 5)
  168. } EDS5Effect;
  169. typedef enum {
  170. k_EDS5LEDResetStateNone,
  171. k_EDS5LEDResetStatePending,
  172. k_EDS5LEDResetStateComplete,
  173. } EDS5LEDResetState;
  174. typedef struct {
  175. Sint16 bias;
  176. float sensitivity;
  177. } IMUCalibrationData;
  178. typedef struct {
  179. SDL_HIDAPI_Device *device;
  180. SDL_Joystick *joystick;
  181. SDL_bool use_alternate_report;
  182. SDL_bool sensors_supported;
  183. SDL_bool lightbar_supported;
  184. SDL_bool vibration_supported;
  185. SDL_bool playerled_supported;
  186. SDL_bool touchpad_supported;
  187. SDL_bool effects_supported;
  188. SDL_bool enhanced_mode;
  189. SDL_bool report_sensors;
  190. SDL_bool report_touchpad;
  191. SDL_bool hardware_calibration;
  192. IMUCalibrationData calibration[6];
  193. Uint16 firmware_version;
  194. Uint32 last_packet;
  195. int player_index;
  196. SDL_bool player_lights;
  197. Uint8 rumble_left;
  198. Uint8 rumble_right;
  199. SDL_bool color_set;
  200. Uint8 led_red;
  201. Uint8 led_green;
  202. Uint8 led_blue;
  203. EDS5LEDResetState led_reset_state;
  204. Uint32 last_timestamp;
  205. Uint64 timestamp;
  206. union
  207. {
  208. PS5SimpleStatePacket_t simple;
  209. PS5StatePacketCommon_t state;
  210. PS5StatePacket_t full_state;
  211. Uint8 data[64];
  212. } last_state;
  213. } SDL_DriverPS5_Context;
  214. static int HIDAPI_DriverPS5_SendJoystickEffect(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, const void *effect, int size);
  215. static void
  216. HIDAPI_DriverPS5_RegisterHints(SDL_HintCallback callback, void *userdata)
  217. {
  218. SDL_AddHintCallback(SDL_HINT_JOYSTICK_HIDAPI_PS5, callback, userdata);
  219. }
  220. static void
  221. HIDAPI_DriverPS5_UnregisterHints(SDL_HintCallback callback, void *userdata)
  222. {
  223. SDL_DelHintCallback(SDL_HINT_JOYSTICK_HIDAPI_PS5, callback, userdata);
  224. }
  225. static SDL_bool
  226. HIDAPI_DriverPS5_IsEnabled(void)
  227. {
  228. return SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI_PS5,
  229. SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI,
  230. SDL_HIDAPI_DEFAULT));
  231. }
  232. static int ReadFeatureReport(SDL_hid_device *dev, Uint8 report_id, Uint8 *report, size_t length)
  233. {
  234. SDL_memset(report, 0, length);
  235. report[0] = report_id;
  236. return SDL_hid_get_feature_report(dev, report, length);
  237. }
  238. static SDL_bool
  239. HIDAPI_DriverPS5_IsSupportedDevice(SDL_HIDAPI_Device *device, const char *name, SDL_GameControllerType type, Uint16 vendor_id, Uint16 product_id, Uint16 version, int interface_number, int interface_class, int interface_subclass, int interface_protocol)
  240. {
  241. Uint8 data[USB_PACKET_LENGTH];
  242. int size;
  243. if (type == SDL_CONTROLLER_TYPE_PS5) {
  244. return SDL_TRUE;
  245. }
  246. if (SONY_THIRDPARTY_VENDOR(vendor_id)) {
  247. if (device) {
  248. if ((size = ReadFeatureReport(device->dev, k_EPS5FeatureReportIdCapabilities, data, sizeof(data))) == 48 &&
  249. data[2] == 0x28) {
  250. /* Supported third party controller */
  251. return SDL_TRUE;
  252. } else {
  253. return SDL_FALSE;
  254. }
  255. } else {
  256. /* Might be supported by this driver, enumerate and find out */
  257. return SDL_TRUE;
  258. }
  259. }
  260. return SDL_FALSE;
  261. }
  262. static void
  263. SetLedsForPlayerIndex(DS5EffectsState_t *effects, int player_index)
  264. {
  265. /* This list is the same as what hid-sony.c uses in the Linux kernel.
  266. The first 4 values correspond to what the PS4 assigns.
  267. */
  268. static const Uint8 colors[7][3] = {
  269. { 0x00, 0x00, 0x40 }, /* Blue */
  270. { 0x40, 0x00, 0x00 }, /* Red */
  271. { 0x00, 0x40, 0x00 }, /* Green */
  272. { 0x20, 0x00, 0x20 }, /* Pink */
  273. { 0x20, 0x10, 0x00 }, /* Orange */
  274. { 0x00, 0x10, 0x10 }, /* Teal */
  275. { 0x10, 0x10, 0x10 } /* White */
  276. };
  277. if (player_index >= 0) {
  278. player_index %= SDL_arraysize(colors);
  279. } else {
  280. player_index = 0;
  281. }
  282. effects->ucLedRed = colors[player_index][0];
  283. effects->ucLedGreen = colors[player_index][1];
  284. effects->ucLedBlue = colors[player_index][2];
  285. }
  286. static void
  287. SetLightsForPlayerIndex(DS5EffectsState_t *effects, int player_index)
  288. {
  289. static const Uint8 lights[] = {
  290. 0x04,
  291. 0x0A,
  292. 0x15,
  293. 0x1B
  294. };
  295. if (player_index >= 0) {
  296. /* Bitmask, 0x1F enables all lights, 0x20 changes instantly instead of fade */
  297. player_index %= SDL_arraysize(lights);
  298. effects->ucPadLights = lights[player_index] | 0x20;
  299. } else {
  300. effects->ucPadLights = 0x00;
  301. }
  302. }
  303. static SDL_bool
  304. HIDAPI_DriverPS5_InitDevice(SDL_HIDAPI_Device *device)
  305. {
  306. SDL_DriverPS5_Context *ctx;
  307. Uint8 data[USB_PACKET_LENGTH*2];
  308. int size;
  309. char serial[18];
  310. SDL_JoystickType joystick_type = SDL_JOYSTICK_TYPE_GAMECONTROLLER;
  311. ctx = (SDL_DriverPS5_Context *)SDL_calloc(1, sizeof(*ctx));
  312. if (!ctx) {
  313. SDL_OutOfMemory();
  314. return SDL_FALSE;
  315. }
  316. ctx->device = device;
  317. device->context = ctx;
  318. if (device->serial && SDL_strlen(device->serial) == 12) {
  319. int i, j;
  320. j = -1;
  321. for (i = 0; i < 12; i += 2) {
  322. j += 1;
  323. SDL_memcpy(&serial[j], &device->serial[i], 2);
  324. j += 2;
  325. serial[j] = '-';
  326. }
  327. serial[j] = '\0';
  328. } else {
  329. serial[0] = '\0';
  330. }
  331. /* Read a report to see what mode we're in */
  332. size = SDL_hid_read_timeout(device->dev, data, sizeof(data), 16);
  333. #ifdef DEBUG_PS5_PROTOCOL
  334. if (size > 0) {
  335. HIDAPI_DumpPacket("PS5 first packet: size = %d", data, size);
  336. } else {
  337. SDL_Log("PS5 first packet: size = %d\n", size);
  338. }
  339. #endif
  340. if (size == 64) {
  341. /* Connected over USB */
  342. device->is_bluetooth = SDL_FALSE;
  343. ctx->enhanced_mode = SDL_TRUE;
  344. } else if (size > 0 && data[0] == k_EPS5ReportIdBluetoothEffects) {
  345. /* Connected over Bluetooth, using enhanced reports */
  346. device->is_bluetooth = SDL_TRUE;
  347. ctx->enhanced_mode = SDL_TRUE;
  348. } else {
  349. /* Connected over Bluetooth, using simple reports (DirectInput enabled) */
  350. device->is_bluetooth = SDL_TRUE;
  351. /* Games written prior the introduction of PS5 controller support in SDL will not be aware of
  352. SDL_HINT_JOYSTICK_HIDAPI_PS5_RUMBLE, but they did know SDL_HINT_JOYSTICK_HIDAPI_PS4_RUMBLE.
  353. To support apps that only knew about the PS4 hint, we'll use the PS4 hint as the default.
  354. */
  355. ctx->enhanced_mode = SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI_PS5_RUMBLE,
  356. SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI_PS4_RUMBLE, SDL_FALSE));
  357. }
  358. if (ctx->enhanced_mode) {
  359. /* Read the serial number (Bluetooth address in reverse byte order)
  360. This will also enable enhanced reports over Bluetooth
  361. */
  362. if (ReadFeatureReport(device->dev, k_EPS5FeatureReportIdSerialNumber, data, sizeof(data)) >= 7) {
  363. SDL_snprintf(serial, sizeof(serial), "%.2x-%.2x-%.2x-%.2x-%.2x-%.2x",
  364. data[6], data[5], data[4], data[3], data[2], data[1]);
  365. }
  366. /* Read the firmware version
  367. This will also enable enhanced reports over Bluetooth
  368. */
  369. if (ReadFeatureReport(device->dev, k_EPS5FeatureReportIdFirmwareInfo, data, USB_PACKET_LENGTH) >= 46) {
  370. ctx->firmware_version = (Uint16)data[44] | ((Uint16)data[45] << 8);
  371. }
  372. }
  373. /* Get the device capabilities */
  374. if (device->vendor_id == USB_VENDOR_SONY) {
  375. ctx->sensors_supported = SDL_TRUE;
  376. ctx->lightbar_supported = SDL_TRUE;
  377. ctx->vibration_supported = SDL_TRUE;
  378. ctx->playerled_supported = SDL_TRUE;
  379. ctx->touchpad_supported = SDL_TRUE;
  380. } else if ((size = ReadFeatureReport(device->dev, k_EPS5FeatureReportIdCapabilities, data, sizeof(data))) == 48 &&
  381. data[2] == 0x28) {
  382. Uint8 capabilities = data[4];
  383. Uint8 capabilities2 = data[20];
  384. Uint8 device_type = data[5];
  385. #ifdef DEBUG_PS5_PROTOCOL
  386. HIDAPI_DumpPacket("PS5 capabilities: size = %d", data, size);
  387. #endif
  388. if ((capabilities & 0x02) != 0) {
  389. ctx->sensors_supported = SDL_TRUE;
  390. }
  391. if ((capabilities & 0x04) != 0) {
  392. ctx->lightbar_supported = SDL_TRUE;
  393. }
  394. if ((capabilities & 0x08) != 0) {
  395. ctx->vibration_supported = SDL_TRUE;
  396. }
  397. if ((capabilities & 0x40) != 0) {
  398. ctx->touchpad_supported = SDL_TRUE;
  399. }
  400. if ((capabilities2 & 0x80) != 0) {
  401. ctx->playerled_supported = SDL_TRUE;
  402. }
  403. switch (device_type) {
  404. case 0x00:
  405. joystick_type = SDL_JOYSTICK_TYPE_GAMECONTROLLER;
  406. break;
  407. case 0x01:
  408. joystick_type = SDL_JOYSTICK_TYPE_GUITAR;
  409. break;
  410. case 0x02:
  411. joystick_type = SDL_JOYSTICK_TYPE_DRUM_KIT;
  412. break;
  413. case 0x06:
  414. joystick_type = SDL_JOYSTICK_TYPE_WHEEL;
  415. break;
  416. case 0x07:
  417. joystick_type = SDL_JOYSTICK_TYPE_ARCADE_STICK;
  418. break;
  419. case 0x08:
  420. joystick_type = SDL_JOYSTICK_TYPE_FLIGHT_STICK;
  421. break;
  422. default:
  423. joystick_type = SDL_JOYSTICK_TYPE_UNKNOWN;
  424. break;
  425. }
  426. ctx->use_alternate_report = SDL_TRUE;
  427. }
  428. ctx->effects_supported = (ctx->lightbar_supported || ctx->vibration_supported || ctx->playerled_supported);
  429. device->joystick_type = joystick_type;
  430. device->type = SDL_CONTROLLER_TYPE_PS5;
  431. if (device->vendor_id == USB_VENDOR_SONY) {
  432. HIDAPI_SetDeviceName(device, "PS5 Controller");
  433. }
  434. HIDAPI_SetDeviceSerial(device, serial);
  435. /* Prefer the USB device over the Bluetooth device */
  436. if (device->is_bluetooth) {
  437. if (HIDAPI_HasConnectedUSBDevice(device->serial)) {
  438. return SDL_TRUE;
  439. }
  440. } else {
  441. HIDAPI_DisconnectBluetoothDevice(device->serial);
  442. }
  443. return HIDAPI_JoystickConnected(device, NULL);
  444. }
  445. static int
  446. HIDAPI_DriverPS5_GetDevicePlayerIndex(SDL_HIDAPI_Device *device, SDL_JoystickID instance_id)
  447. {
  448. return -1;
  449. }
  450. static void
  451. HIDAPI_DriverPS5_LoadCalibrationData(SDL_HIDAPI_Device *device)
  452. {
  453. SDL_DriverPS5_Context *ctx = (SDL_DriverPS5_Context *)device->context;
  454. int i, size;
  455. Uint8 data[USB_PACKET_LENGTH];
  456. size = ReadFeatureReport(device->dev, k_EPS5FeatureReportIdCalibration, data, sizeof(data));
  457. if (size < 35) {
  458. #ifdef DEBUG_PS5_CALIBRATION
  459. SDL_Log("Short read of calibration data: %d, ignoring calibration\n", size);
  460. #endif
  461. return;
  462. }
  463. {
  464. Sint16 sGyroPitchBias, sGyroYawBias, sGyroRollBias;
  465. Sint16 sGyroPitchPlus, sGyroPitchMinus;
  466. Sint16 sGyroYawPlus, sGyroYawMinus;
  467. Sint16 sGyroRollPlus, sGyroRollMinus;
  468. Sint16 sGyroSpeedPlus, sGyroSpeedMinus;
  469. Sint16 sAccXPlus, sAccXMinus;
  470. Sint16 sAccYPlus, sAccYMinus;
  471. Sint16 sAccZPlus, sAccZMinus;
  472. float flNumerator;
  473. Sint16 sRange2g;
  474. #ifdef DEBUG_PS5_CALIBRATION
  475. HIDAPI_DumpPacket("PS5 calibration packet: size = %d", data, size);
  476. #endif
  477. sGyroPitchBias = LOAD16(data[1], data[2]);
  478. sGyroYawBias = LOAD16(data[3], data[4]);
  479. sGyroRollBias = LOAD16(data[5], data[6]);
  480. sGyroPitchPlus = LOAD16(data[7], data[8]);
  481. sGyroPitchMinus = LOAD16(data[9], data[10]);
  482. sGyroYawPlus = LOAD16(data[11], data[12]);
  483. sGyroYawMinus = LOAD16(data[13], data[14]);
  484. sGyroRollPlus = LOAD16(data[15], data[16]);
  485. sGyroRollMinus = LOAD16(data[17], data[18]);
  486. sGyroSpeedPlus = LOAD16(data[19], data[20]);
  487. sGyroSpeedMinus = LOAD16(data[21], data[22]);
  488. sAccXPlus = LOAD16(data[23], data[24]);
  489. sAccXMinus = LOAD16(data[25], data[26]);
  490. sAccYPlus = LOAD16(data[27], data[28]);
  491. sAccYMinus = LOAD16(data[29], data[30]);
  492. sAccZPlus = LOAD16(data[31], data[32]);
  493. sAccZMinus = LOAD16(data[33], data[34]);
  494. flNumerator = (sGyroSpeedPlus + sGyroSpeedMinus) * GYRO_RES_PER_DEGREE;
  495. ctx->calibration[0].bias = sGyroPitchBias;
  496. ctx->calibration[0].sensitivity = flNumerator / (sGyroPitchPlus - sGyroPitchMinus);
  497. ctx->calibration[1].bias = sGyroYawBias;
  498. ctx->calibration[1].sensitivity = flNumerator / (sGyroYawPlus - sGyroYawMinus);
  499. ctx->calibration[2].bias = sGyroRollBias;
  500. ctx->calibration[2].sensitivity = flNumerator / (sGyroRollPlus - sGyroRollMinus);
  501. sRange2g = sAccXPlus - sAccXMinus;
  502. ctx->calibration[3].bias = sAccXPlus - sRange2g / 2;
  503. ctx->calibration[3].sensitivity = 2.0f * ACCEL_RES_PER_G / (float)sRange2g;
  504. sRange2g = sAccYPlus - sAccYMinus;
  505. ctx->calibration[4].bias = sAccYPlus - sRange2g / 2;
  506. ctx->calibration[4].sensitivity = 2.0f * ACCEL_RES_PER_G / (float)sRange2g;
  507. sRange2g = sAccZPlus - sAccZMinus;
  508. ctx->calibration[5].bias = sAccZPlus - sRange2g / 2;
  509. ctx->calibration[5].sensitivity = 2.0f * ACCEL_RES_PER_G / (float)sRange2g;
  510. ctx->hardware_calibration = SDL_TRUE;
  511. for (i = 0; i < 6; ++i) {
  512. float divisor = (i < 3 ? 64.0f : 1.0f);
  513. #ifdef DEBUG_PS5_CALIBRATION
  514. SDL_Log("calibration[%d] bias = %d, sensitivity = %f\n", i, ctx->calibration[i].bias, ctx->calibration[i].sensitivity);
  515. #endif
  516. /* Some controllers have a bad calibration */
  517. if ((SDL_abs(ctx->calibration[i].bias) > 1024) || (SDL_fabs(1.0f - ctx->calibration[i].sensitivity / divisor) > 0.5f)) {
  518. #ifdef DEBUG_PS5_CALIBRATION
  519. SDL_Log("invalid calibration, ignoring\n");
  520. #endif
  521. ctx->hardware_calibration = SDL_FALSE;
  522. }
  523. }
  524. }
  525. }
  526. static float
  527. HIDAPI_DriverPS5_ApplyCalibrationData(SDL_DriverPS5_Context *ctx, int index, Sint16 value)
  528. {
  529. float result;
  530. if (ctx->hardware_calibration) {
  531. IMUCalibrationData *calibration = &ctx->calibration[index];
  532. result = (value - calibration->bias) * calibration->sensitivity;
  533. } else if (index < 3) {
  534. result = value * 64.f;
  535. } else {
  536. result = value;
  537. }
  538. /* Convert the raw data to the units expected by SDL */
  539. if (index < 3) {
  540. result = (result / GYRO_RES_PER_DEGREE) * (float)M_PI / 180.0f;
  541. } else {
  542. result = (result / ACCEL_RES_PER_G) * SDL_STANDARD_GRAVITY;
  543. }
  544. return result;
  545. }
  546. static int
  547. HIDAPI_DriverPS5_UpdateEffects(SDL_HIDAPI_Device *device, int effect_mask)
  548. {
  549. SDL_DriverPS5_Context *ctx = (SDL_DriverPS5_Context *)device->context;
  550. DS5EffectsState_t effects;
  551. if (!ctx->enhanced_mode || !ctx->effects_supported) {
  552. return SDL_Unsupported();
  553. }
  554. SDL_zero(effects);
  555. /* Make sure the Bluetooth connection sequence has completed before sending LED color change */
  556. if (device->is_bluetooth &&
  557. (effect_mask & (k_EDS5EffectLED | k_EDS5EffectPadLights)) != 0) {
  558. if (ctx->led_reset_state != k_EDS5LEDResetStateComplete) {
  559. ctx->led_reset_state = k_EDS5LEDResetStatePending;
  560. return 0;
  561. }
  562. }
  563. if (ctx->vibration_supported) {
  564. if (ctx->rumble_left || ctx->rumble_right) {
  565. if (ctx->firmware_version < 0x0224) {
  566. effects.ucEnableBits1 |= 0x01; /* Enable rumble emulation */
  567. /* Shift to reduce effective rumble strength to match Xbox controllers */
  568. effects.ucRumbleLeft = ctx->rumble_left >> 1;
  569. effects.ucRumbleRight = ctx->rumble_right >> 1;
  570. } else {
  571. effects.ucEnableBits3 |= 0x04; /* Enable improved rumble emulation on 2.24 firmware and newer */
  572. effects.ucRumbleLeft = ctx->rumble_left;
  573. effects.ucRumbleRight = ctx->rumble_right;
  574. }
  575. effects.ucEnableBits1 |= 0x02; /* Disable audio haptics */
  576. } else {
  577. /* Leaving emulated rumble bits off will restore audio haptics */
  578. }
  579. if ((effect_mask & k_EDS5EffectRumbleStart) != 0) {
  580. effects.ucEnableBits1 |= 0x02; /* Disable audio haptics */
  581. }
  582. if ((effect_mask & k_EDS5EffectRumble) != 0) {
  583. /* Already handled above */
  584. }
  585. }
  586. if (ctx->lightbar_supported) {
  587. if ((effect_mask & k_EDS5EffectLEDReset) != 0) {
  588. effects.ucEnableBits2 |= 0x08; /* Reset LED state */
  589. }
  590. if ((effect_mask & k_EDS5EffectLED) != 0) {
  591. effects.ucEnableBits2 |= 0x04; /* Enable LED color */
  592. /* Populate the LED state with the appropriate color from our lookup table */
  593. if (ctx->color_set) {
  594. effects.ucLedRed = ctx->led_red;
  595. effects.ucLedGreen = ctx->led_green;
  596. effects.ucLedBlue = ctx->led_blue;
  597. } else {
  598. SetLedsForPlayerIndex(&effects, ctx->player_index);
  599. }
  600. }
  601. }
  602. if (ctx->playerled_supported) {
  603. if ((effect_mask & k_EDS5EffectPadLights) != 0) {
  604. effects.ucEnableBits2 |= 0x10; /* Enable touchpad lights */
  605. if (ctx->player_lights) {
  606. SetLightsForPlayerIndex(&effects, ctx->player_index);
  607. } else {
  608. effects.ucPadLights = 0x00;
  609. }
  610. }
  611. }
  612. if ((effect_mask & k_EDS5EffectMicLight) != 0) {
  613. effects.ucEnableBits2 |= 0x01; /* Enable microphone light */
  614. effects.ucMicLightMode = 0; /* Bitmask, 0x00 = off, 0x01 = solid, 0x02 = pulse */
  615. }
  616. return HIDAPI_DriverPS5_SendJoystickEffect(device, ctx->joystick, &effects, sizeof(effects));
  617. }
  618. static void
  619. HIDAPI_DriverPS5_CheckPendingLEDReset(SDL_HIDAPI_Device *device)
  620. {
  621. SDL_DriverPS5_Context *ctx = (SDL_DriverPS5_Context *)device->context;
  622. SDL_bool led_reset_complete = SDL_FALSE;
  623. if (ctx->sensors_supported) {
  624. const PS5StatePacketCommon_t *packet = &ctx->last_state.state;
  625. /* Check the timer to make sure the Bluetooth connection LED animation is complete */
  626. const Uint32 connection_complete = 10200000;
  627. Uint32 timestamp = LOAD32(packet->rgucSensorTimestamp[0],
  628. packet->rgucSensorTimestamp[1],
  629. packet->rgucSensorTimestamp[2],
  630. packet->rgucSensorTimestamp[3]);
  631. if (SDL_TICKS_PASSED(timestamp, connection_complete)) {
  632. led_reset_complete = SDL_TRUE;
  633. }
  634. } else {
  635. /* We don't know how to check the timer, just assume it's complete for now */
  636. led_reset_complete = SDL_TRUE;
  637. }
  638. if (led_reset_complete) {
  639. HIDAPI_DriverPS5_UpdateEffects(device, k_EDS5EffectLEDReset);
  640. ctx->led_reset_state = k_EDS5LEDResetStateComplete;
  641. HIDAPI_DriverPS5_UpdateEffects(device, (k_EDS5EffectLED | k_EDS5EffectPadLights));
  642. }
  643. }
  644. static void
  645. HIDAPI_DriverPS5_TickleBluetooth(SDL_HIDAPI_Device *device)
  646. {
  647. /* This is just a dummy packet that should have no effect, since we don't set the CRC */
  648. Uint8 data[78];
  649. SDL_zeroa(data);
  650. data[0] = k_EPS5ReportIdBluetoothEffects;
  651. data[1] = 0x02; /* Magic value */
  652. SDL_HIDAPI_SendRumble(device, data, sizeof(data));
  653. }
  654. static void
  655. HIDAPI_DriverPS5_SetEnhancedMode(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
  656. {
  657. SDL_DriverPS5_Context *ctx = (SDL_DriverPS5_Context *)device->context;
  658. if (!ctx->enhanced_mode) {
  659. ctx->enhanced_mode = SDL_TRUE;
  660. if (ctx->touchpad_supported) {
  661. SDL_PrivateJoystickAddTouchpad(joystick, 2);
  662. ctx->report_touchpad = SDL_TRUE;
  663. }
  664. if (ctx->sensors_supported) {
  665. if (device->is_bluetooth) {
  666. /* Bluetooth sensor update rate appears to be 1000 Hz */
  667. SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_GYRO, 1000.0f);
  668. SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_ACCEL, 1000.0f);
  669. } else {
  670. SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_GYRO, 250.0f);
  671. SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_ACCEL, 250.0f);
  672. }
  673. }
  674. /* Switch into enhanced report mode */
  675. HIDAPI_DriverPS5_UpdateEffects(device, 0);
  676. /* Update the light effects */
  677. HIDAPI_DriverPS5_UpdateEffects(device, (k_EDS5EffectLED | k_EDS5EffectPadLights));
  678. }
  679. }
  680. static void SDLCALL SDL_PS5RumbleHintChanged(void *userdata, const char *name, const char *oldValue, const char *hint)
  681. {
  682. SDL_DriverPS5_Context *ctx = (SDL_DriverPS5_Context *)userdata;
  683. /* This is a one-way trip, you can't switch the controller back to simple report mode */
  684. if (SDL_GetStringBoolean(hint, SDL_FALSE)) {
  685. HIDAPI_DriverPS5_SetEnhancedMode(ctx->device, ctx->joystick);
  686. }
  687. }
  688. static void SDLCALL SDL_PS5PlayerLEDHintChanged(void *userdata, const char *name, const char *oldValue, const char *hint)
  689. {
  690. SDL_DriverPS5_Context *ctx = (SDL_DriverPS5_Context *)userdata;
  691. SDL_bool player_lights = SDL_GetStringBoolean(hint, SDL_TRUE);
  692. if (player_lights != ctx->player_lights) {
  693. ctx->player_lights = player_lights;
  694. HIDAPI_DriverPS5_UpdateEffects(ctx->device, k_EDS5EffectPadLights);
  695. }
  696. }
  697. static void
  698. HIDAPI_DriverPS5_SetDevicePlayerIndex(SDL_HIDAPI_Device *device, SDL_JoystickID instance_id, int player_index)
  699. {
  700. SDL_DriverPS5_Context *ctx = (SDL_DriverPS5_Context *)device->context;
  701. if (!ctx->joystick) {
  702. return;
  703. }
  704. ctx->player_index = player_index;
  705. /* This will set the new LED state based on the new player index */
  706. HIDAPI_DriverPS5_UpdateEffects(device, (k_EDS5EffectLED | k_EDS5EffectPadLights));
  707. }
  708. static SDL_bool
  709. HIDAPI_DriverPS5_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
  710. {
  711. SDL_DriverPS5_Context *ctx = (SDL_DriverPS5_Context *)device->context;
  712. ctx->joystick = joystick;
  713. ctx->last_packet = SDL_GetTicks();
  714. ctx->report_sensors = SDL_FALSE;
  715. ctx->report_touchpad = SDL_FALSE;
  716. ctx->rumble_left = 0;
  717. ctx->rumble_right = 0;
  718. ctx->color_set = SDL_FALSE;
  719. ctx->led_reset_state = k_EDS5LEDResetStateNone;
  720. SDL_zero(ctx->last_state);
  721. /* Initialize player index (needed for setting LEDs) */
  722. ctx->player_index = SDL_JoystickGetPlayerIndex(joystick);
  723. ctx->player_lights = SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI_PS5_PLAYER_LED, SDL_TRUE);
  724. /* Initialize the joystick capabilities */
  725. joystick->nbuttons = ctx->touchpad_supported ? 17 : 15;
  726. joystick->naxes = SDL_CONTROLLER_AXIS_MAX;
  727. joystick->epowerlevel = device->is_bluetooth ? SDL_JOYSTICK_POWER_UNKNOWN : SDL_JOYSTICK_POWER_WIRED;
  728. joystick->firmware_version = ctx->firmware_version;
  729. if (ctx->enhanced_mode) {
  730. /* Force initialization when opening the joystick */
  731. ctx->enhanced_mode = SDL_FALSE;
  732. HIDAPI_DriverPS5_SetEnhancedMode(device, joystick);
  733. } else {
  734. SDL_AddHintCallback(SDL_HINT_JOYSTICK_HIDAPI_PS5_RUMBLE,
  735. SDL_PS5RumbleHintChanged, ctx);
  736. }
  737. SDL_AddHintCallback(SDL_HINT_JOYSTICK_HIDAPI_PS5_PLAYER_LED,
  738. SDL_PS5PlayerLEDHintChanged, ctx);
  739. return SDL_TRUE;
  740. }
  741. static int
  742. HIDAPI_DriverPS5_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble)
  743. {
  744. SDL_DriverPS5_Context *ctx = (SDL_DriverPS5_Context *)device->context;
  745. if (!ctx->vibration_supported) {
  746. return SDL_Unsupported();
  747. }
  748. if (!ctx->rumble_left && !ctx->rumble_right) {
  749. HIDAPI_DriverPS5_UpdateEffects(device, k_EDS5EffectRumbleStart);
  750. }
  751. ctx->rumble_left = (low_frequency_rumble >> 8);
  752. ctx->rumble_right = (high_frequency_rumble >> 8);
  753. return HIDAPI_DriverPS5_UpdateEffects(device, k_EDS5EffectRumble);
  754. }
  755. static int
  756. HIDAPI_DriverPS5_RumbleJoystickTriggers(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble)
  757. {
  758. return SDL_Unsupported();
  759. }
  760. static Uint32
  761. HIDAPI_DriverPS5_GetJoystickCapabilities(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
  762. {
  763. SDL_DriverPS5_Context *ctx = (SDL_DriverPS5_Context *)device->context;
  764. Uint32 result = 0;
  765. if (ctx->enhanced_mode) {
  766. if (ctx->lightbar_supported) {
  767. result |= SDL_JOYCAP_LED;
  768. }
  769. if (ctx->vibration_supported) {
  770. result |= SDL_JOYCAP_RUMBLE;
  771. }
  772. }
  773. return result;
  774. }
  775. static int
  776. HIDAPI_DriverPS5_SetJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue)
  777. {
  778. SDL_DriverPS5_Context *ctx = (SDL_DriverPS5_Context *)device->context;
  779. if (!ctx->lightbar_supported) {
  780. return SDL_Unsupported();
  781. }
  782. ctx->color_set = SDL_TRUE;
  783. ctx->led_red = red;
  784. ctx->led_green = green;
  785. ctx->led_blue = blue;
  786. return HIDAPI_DriverPS5_UpdateEffects(device, k_EDS5EffectLED);
  787. }
  788. static int
  789. HIDAPI_DriverPS5_SendJoystickEffect(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, const void *effect, int size)
  790. {
  791. SDL_DriverPS5_Context *ctx = (SDL_DriverPS5_Context *)device->context;
  792. Uint8 data[78];
  793. int report_size, offset;
  794. Uint8 *pending_data;
  795. int *pending_size;
  796. int maximum_size;
  797. if (!ctx->effects_supported) {
  798. return SDL_Unsupported();
  799. }
  800. if (!ctx->enhanced_mode) {
  801. HIDAPI_DriverPS5_SetEnhancedMode(device, joystick);
  802. }
  803. SDL_zeroa(data);
  804. if (device->is_bluetooth) {
  805. data[0] = k_EPS5ReportIdBluetoothEffects;
  806. data[1] = 0x02; /* Magic value */
  807. report_size = 78;
  808. offset = 2;
  809. } else {
  810. data[0] = k_EPS5ReportIdUsbEffects;
  811. report_size = 48;
  812. offset = 1;
  813. }
  814. SDL_memcpy(&data[offset], effect, SDL_min((sizeof(data) - offset), (size_t)size));
  815. if (device->is_bluetooth) {
  816. /* Bluetooth reports need a CRC at the end of the packet (at least on Linux) */
  817. Uint8 ubHdr = 0xA2; /* hidp header is part of the CRC calculation */
  818. Uint32 unCRC;
  819. unCRC = SDL_crc32(0, &ubHdr, 1);
  820. unCRC = SDL_crc32(unCRC, data, (size_t)(report_size - sizeof(unCRC)));
  821. SDL_memcpy(&data[report_size - sizeof(unCRC)], &unCRC, sizeof(unCRC));
  822. }
  823. if (SDL_HIDAPI_LockRumble() < 0) {
  824. return -1;
  825. }
  826. /* See if we can update an existing pending request */
  827. if (SDL_HIDAPI_GetPendingRumbleLocked(device, &pending_data, &pending_size, &maximum_size)) {
  828. DS5EffectsState_t *effects = (DS5EffectsState_t *)&data[offset];
  829. DS5EffectsState_t *pending_effects = (DS5EffectsState_t *)&pending_data[offset];
  830. if (report_size == *pending_size &&
  831. effects->ucEnableBits1 == pending_effects->ucEnableBits1 &&
  832. effects->ucEnableBits2 == pending_effects->ucEnableBits2) {
  833. /* We're simply updating the data for this request */
  834. SDL_memcpy(pending_data, data, report_size);
  835. SDL_HIDAPI_UnlockRumble();
  836. return 0;
  837. }
  838. }
  839. if (SDL_HIDAPI_SendRumbleAndUnlock(device, data, report_size) != report_size) {
  840. return -1;
  841. }
  842. return 0;
  843. }
  844. static int
  845. HIDAPI_DriverPS5_SetJoystickSensorsEnabled(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, SDL_bool enabled)
  846. {
  847. SDL_DriverPS5_Context *ctx = (SDL_DriverPS5_Context *)device->context;
  848. if (!ctx->enhanced_mode) {
  849. return SDL_Unsupported();
  850. }
  851. if (enabled) {
  852. HIDAPI_DriverPS5_LoadCalibrationData(device);
  853. }
  854. ctx->report_sensors = enabled;
  855. ctx->timestamp = 0;
  856. return 0;
  857. }
  858. static void
  859. HIDAPI_DriverPS5_HandleSimpleStatePacket(SDL_Joystick *joystick, SDL_hid_device *dev, SDL_DriverPS5_Context *ctx, PS5SimpleStatePacket_t *packet)
  860. {
  861. Sint16 axis;
  862. if (ctx->last_state.simple.rgucButtonsHatAndCounter[0] != packet->rgucButtonsHatAndCounter[0]) {
  863. {
  864. Uint8 data = (packet->rgucButtonsHatAndCounter[0] >> 4);
  865. SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_X, (data & 0x01) ? SDL_PRESSED : SDL_RELEASED);
  866. SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_A, (data & 0x02) ? SDL_PRESSED : SDL_RELEASED);
  867. SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_B, (data & 0x04) ? SDL_PRESSED : SDL_RELEASED);
  868. SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_Y, (data & 0x08) ? SDL_PRESSED : SDL_RELEASED);
  869. }
  870. {
  871. Uint8 data = (packet->rgucButtonsHatAndCounter[0] & 0x0F);
  872. SDL_bool dpad_up = SDL_FALSE;
  873. SDL_bool dpad_down = SDL_FALSE;
  874. SDL_bool dpad_left = SDL_FALSE;
  875. SDL_bool dpad_right = SDL_FALSE;
  876. switch (data) {
  877. case 0:
  878. dpad_up = SDL_TRUE;
  879. break;
  880. case 1:
  881. dpad_up = SDL_TRUE;
  882. dpad_right = SDL_TRUE;
  883. break;
  884. case 2:
  885. dpad_right = SDL_TRUE;
  886. break;
  887. case 3:
  888. dpad_right = SDL_TRUE;
  889. dpad_down = SDL_TRUE;
  890. break;
  891. case 4:
  892. dpad_down = SDL_TRUE;
  893. break;
  894. case 5:
  895. dpad_left = SDL_TRUE;
  896. dpad_down = SDL_TRUE;
  897. break;
  898. case 6:
  899. dpad_left = SDL_TRUE;
  900. break;
  901. case 7:
  902. dpad_up = SDL_TRUE;
  903. dpad_left = SDL_TRUE;
  904. break;
  905. default:
  906. break;
  907. }
  908. SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_DOWN, dpad_down);
  909. SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_UP, dpad_up);
  910. SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_RIGHT, dpad_right);
  911. SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_LEFT, dpad_left);
  912. }
  913. }
  914. if (ctx->last_state.simple.rgucButtonsHatAndCounter[1] != packet->rgucButtonsHatAndCounter[1]) {
  915. Uint8 data = packet->rgucButtonsHatAndCounter[1];
  916. SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_LEFTSHOULDER, (data & 0x01) ? SDL_PRESSED : SDL_RELEASED);
  917. SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER, (data & 0x02) ? SDL_PRESSED : SDL_RELEASED);
  918. SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_BACK, (data & 0x10) ? SDL_PRESSED : SDL_RELEASED);
  919. SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_START, (data & 0x20) ? SDL_PRESSED : SDL_RELEASED);
  920. SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_LEFTSTICK, (data & 0x40) ? SDL_PRESSED : SDL_RELEASED);
  921. SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_RIGHTSTICK, (data & 0x80) ? SDL_PRESSED : SDL_RELEASED);
  922. }
  923. if (ctx->last_state.simple.rgucButtonsHatAndCounter[2] != packet->rgucButtonsHatAndCounter[2]) {
  924. Uint8 data = (packet->rgucButtonsHatAndCounter[2] & 0x03);
  925. SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_GUIDE, (data & 0x01) ? SDL_PRESSED : SDL_RELEASED);
  926. SDL_PrivateJoystickButton(joystick, 15, (data & 0x02) ? SDL_PRESSED : SDL_RELEASED);
  927. }
  928. axis = ((int)packet->ucTriggerLeft * 257) - 32768;
  929. SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERLEFT, axis);
  930. axis = ((int)packet->ucTriggerRight * 257) - 32768;
  931. SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERRIGHT, axis);
  932. axis = ((int)packet->ucLeftJoystickX * 257) - 32768;
  933. SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_LEFTX, axis);
  934. axis = ((int)packet->ucLeftJoystickY * 257) - 32768;
  935. SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_LEFTY, axis);
  936. axis = ((int)packet->ucRightJoystickX * 257) - 32768;
  937. SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTX, axis);
  938. axis = ((int)packet->ucRightJoystickY * 257) - 32768;
  939. SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTY, axis);
  940. SDL_memcpy(&ctx->last_state.simple, packet, sizeof(ctx->last_state.simple));
  941. }
  942. static void
  943. HIDAPI_DriverPS5_HandleStatePacketCommon(SDL_Joystick *joystick, SDL_hid_device *dev, SDL_DriverPS5_Context *ctx, PS5StatePacketCommon_t *packet)
  944. {
  945. Sint16 axis;
  946. if (ctx->last_state.state.rgucButtonsAndHat[0] != packet->rgucButtonsAndHat[0]) {
  947. {
  948. Uint8 data = (packet->rgucButtonsAndHat[0] >> 4);
  949. SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_X, (data & 0x01) ? SDL_PRESSED : SDL_RELEASED);
  950. SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_A, (data & 0x02) ? SDL_PRESSED : SDL_RELEASED);
  951. SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_B, (data & 0x04) ? SDL_PRESSED : SDL_RELEASED);
  952. SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_Y, (data & 0x08) ? SDL_PRESSED : SDL_RELEASED);
  953. }
  954. {
  955. Uint8 data = (packet->rgucButtonsAndHat[0] & 0x0F);
  956. SDL_bool dpad_up = SDL_FALSE;
  957. SDL_bool dpad_down = SDL_FALSE;
  958. SDL_bool dpad_left = SDL_FALSE;
  959. SDL_bool dpad_right = SDL_FALSE;
  960. switch (data) {
  961. case 0:
  962. dpad_up = SDL_TRUE;
  963. break;
  964. case 1:
  965. dpad_up = SDL_TRUE;
  966. dpad_right = SDL_TRUE;
  967. break;
  968. case 2:
  969. dpad_right = SDL_TRUE;
  970. break;
  971. case 3:
  972. dpad_right = SDL_TRUE;
  973. dpad_down = SDL_TRUE;
  974. break;
  975. case 4:
  976. dpad_down = SDL_TRUE;
  977. break;
  978. case 5:
  979. dpad_left = SDL_TRUE;
  980. dpad_down = SDL_TRUE;
  981. break;
  982. case 6:
  983. dpad_left = SDL_TRUE;
  984. break;
  985. case 7:
  986. dpad_up = SDL_TRUE;
  987. dpad_left = SDL_TRUE;
  988. break;
  989. default:
  990. break;
  991. }
  992. SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_DOWN, dpad_down);
  993. SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_UP, dpad_up);
  994. SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_RIGHT, dpad_right);
  995. SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_LEFT, dpad_left);
  996. }
  997. }
  998. if (ctx->last_state.state.rgucButtonsAndHat[1] != packet->rgucButtonsAndHat[1]) {
  999. Uint8 data = packet->rgucButtonsAndHat[1];
  1000. SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_LEFTSHOULDER, (data & 0x01) ? SDL_PRESSED : SDL_RELEASED);
  1001. SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER, (data & 0x02) ? SDL_PRESSED : SDL_RELEASED);
  1002. SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_BACK, (data & 0x10) ? SDL_PRESSED : SDL_RELEASED);
  1003. SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_START, (data & 0x20) ? SDL_PRESSED : SDL_RELEASED);
  1004. SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_LEFTSTICK, (data & 0x40) ? SDL_PRESSED : SDL_RELEASED);
  1005. SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_RIGHTSTICK, (data & 0x80) ? SDL_PRESSED : SDL_RELEASED);
  1006. }
  1007. if (ctx->last_state.state.rgucButtonsAndHat[2] != packet->rgucButtonsAndHat[2]) {
  1008. Uint8 data = packet->rgucButtonsAndHat[2];
  1009. SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_GUIDE, (data & 0x01) ? SDL_PRESSED : SDL_RELEASED);
  1010. SDL_PrivateJoystickButton(joystick, 15, (data & 0x02) ? SDL_PRESSED : SDL_RELEASED);
  1011. SDL_PrivateJoystickButton(joystick, 16, (data & 0x04) ? SDL_PRESSED : SDL_RELEASED);
  1012. }
  1013. axis = ((int)packet->ucTriggerLeft * 257) - 32768;
  1014. SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERLEFT, axis);
  1015. axis = ((int)packet->ucTriggerRight * 257) - 32768;
  1016. SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERRIGHT, axis);
  1017. axis = ((int)packet->ucLeftJoystickX * 257) - 32768;
  1018. SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_LEFTX, axis);
  1019. axis = ((int)packet->ucLeftJoystickY * 257) - 32768;
  1020. SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_LEFTY, axis);
  1021. axis = ((int)packet->ucRightJoystickX * 257) - 32768;
  1022. SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTX, axis);
  1023. axis = ((int)packet->ucRightJoystickY * 257) - 32768;
  1024. SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTY, axis);
  1025. if (ctx->report_sensors) {
  1026. Uint32 timestamp;
  1027. Uint64 timestamp_us;
  1028. float data[3];
  1029. timestamp = LOAD32(packet->rgucSensorTimestamp[0],
  1030. packet->rgucSensorTimestamp[1],
  1031. packet->rgucSensorTimestamp[2],
  1032. packet->rgucSensorTimestamp[3]);
  1033. if (ctx->timestamp) {
  1034. Uint32 delta;
  1035. if (ctx->last_timestamp > timestamp) {
  1036. delta = (SDL_MAX_UINT32 - ctx->last_timestamp + timestamp + 1);
  1037. } else {
  1038. delta = (timestamp - ctx->last_timestamp);
  1039. }
  1040. ctx->timestamp += delta;
  1041. } else {
  1042. ctx->timestamp = timestamp;
  1043. }
  1044. ctx->last_timestamp = timestamp;
  1045. /* Sensor timestamp is in 0.33us units */
  1046. timestamp_us = ctx->timestamp / 3;
  1047. data[0] = HIDAPI_DriverPS5_ApplyCalibrationData(ctx, 0, LOAD16(packet->rgucGyroX[0], packet->rgucGyroX[1]));
  1048. data[1] = HIDAPI_DriverPS5_ApplyCalibrationData(ctx, 1, LOAD16(packet->rgucGyroY[0], packet->rgucGyroY[1]));
  1049. data[2] = HIDAPI_DriverPS5_ApplyCalibrationData(ctx, 2, LOAD16(packet->rgucGyroZ[0], packet->rgucGyroZ[1]));
  1050. SDL_PrivateJoystickSensor(joystick, SDL_SENSOR_GYRO, timestamp_us, data, 3);
  1051. data[0] = HIDAPI_DriverPS5_ApplyCalibrationData(ctx, 3, LOAD16(packet->rgucAccelX[0], packet->rgucAccelX[1]));
  1052. data[1] = HIDAPI_DriverPS5_ApplyCalibrationData(ctx, 4, LOAD16(packet->rgucAccelY[0], packet->rgucAccelY[1]));
  1053. data[2] = HIDAPI_DriverPS5_ApplyCalibrationData(ctx, 5, LOAD16(packet->rgucAccelZ[0], packet->rgucAccelZ[1]));
  1054. SDL_PrivateJoystickSensor(joystick, SDL_SENSOR_ACCEL, timestamp_us, data, 3);
  1055. }
  1056. }
  1057. static void
  1058. HIDAPI_DriverPS5_HandleStatePacket(SDL_Joystick *joystick, SDL_hid_device *dev, SDL_DriverPS5_Context *ctx, PS5StatePacket_t *packet)
  1059. {
  1060. static const float TOUCHPAD_SCALEX = 1.0f / 1920;
  1061. static const float TOUCHPAD_SCALEY = 1.0f / 1070;
  1062. Uint8 touchpad_state;
  1063. int touchpad_x, touchpad_y;
  1064. if (ctx->report_touchpad) {
  1065. touchpad_state = ((packet->ucTouchpadCounter1 & 0x80) == 0) ? SDL_PRESSED : SDL_RELEASED;
  1066. touchpad_x = packet->rgucTouchpadData1[0] | (((int)packet->rgucTouchpadData1[1] & 0x0F) << 8);
  1067. touchpad_y = (packet->rgucTouchpadData1[1] >> 4) | ((int)packet->rgucTouchpadData1[2] << 4);
  1068. SDL_PrivateJoystickTouchpad(joystick, 0, 0, touchpad_state, touchpad_x * TOUCHPAD_SCALEX, touchpad_y * TOUCHPAD_SCALEY, touchpad_state ? 1.0f : 0.0f);
  1069. touchpad_state = ((packet->ucTouchpadCounter2 & 0x80) == 0) ? SDL_PRESSED : SDL_RELEASED;
  1070. touchpad_x = packet->rgucTouchpadData2[0] | (((int)packet->rgucTouchpadData2[1] & 0x0F) << 8);
  1071. touchpad_y = (packet->rgucTouchpadData2[1] >> 4) | ((int)packet->rgucTouchpadData2[2] << 4);
  1072. SDL_PrivateJoystickTouchpad(joystick, 0, 1, touchpad_state, touchpad_x * TOUCHPAD_SCALEX, touchpad_y * TOUCHPAD_SCALEY, touchpad_state ? 1.0f : 0.0f);
  1073. }
  1074. /* A check of packet->ucBatteryLevel & 0x10 should work as a check for BT vs USB but doesn't
  1075. * seem to always work. Possibly related to being 100% charged?
  1076. */
  1077. if (!ctx->device->is_bluetooth) {
  1078. /* 0x20 set means fully charged */
  1079. SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_WIRED);
  1080. } else {
  1081. /* Battery level ranges from 0 to 10 */
  1082. int level = (packet->ucBatteryLevel & 0xF);
  1083. if (level == 0) {
  1084. SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_EMPTY);
  1085. } else if (level <= 2) {
  1086. SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_LOW);
  1087. } else if (level <= 7) {
  1088. SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_MEDIUM);
  1089. } else {
  1090. SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_FULL);
  1091. }
  1092. }
  1093. SDL_memcpy(&ctx->last_state, packet, sizeof(ctx->last_state));
  1094. }
  1095. static void
  1096. HIDAPI_DriverPS5_HandleStatePacketAlt(SDL_Joystick *joystick, SDL_hid_device *dev, SDL_DriverPS5_Context *ctx, PS5StatePacketAlt_t *packet)
  1097. {
  1098. static const float TOUCHPAD_SCALEX = 1.0f / 1920;
  1099. static const float TOUCHPAD_SCALEY = 1.0f / 1070;
  1100. Uint8 touchpad_state;
  1101. int touchpad_x, touchpad_y;
  1102. if (ctx->report_touchpad) {
  1103. touchpad_state = ((packet->ucTouchpadCounter1 & 0x80) == 0) ? SDL_PRESSED : SDL_RELEASED;
  1104. touchpad_x = packet->rgucTouchpadData1[0] | (((int) packet->rgucTouchpadData1[1] & 0x0F) << 8);
  1105. touchpad_y = (packet->rgucTouchpadData1[1] >> 4) | ((int) packet->rgucTouchpadData1[2] << 4);
  1106. SDL_PrivateJoystickTouchpad(joystick, 0, 0, touchpad_state, touchpad_x * TOUCHPAD_SCALEX, touchpad_y * TOUCHPAD_SCALEY, touchpad_state ? 1.0f : 0.0f);
  1107. touchpad_state = ((packet->ucTouchpadCounter2 & 0x80) == 0) ? SDL_PRESSED : SDL_RELEASED;
  1108. touchpad_x = packet->rgucTouchpadData2[0] | (((int) packet->rgucTouchpadData2[1] & 0x0F) << 8);
  1109. touchpad_y = (packet->rgucTouchpadData2[1] >> 4) | ((int) packet->rgucTouchpadData2[2] << 4);
  1110. SDL_PrivateJoystickTouchpad(joystick, 0, 1, touchpad_state, touchpad_x * TOUCHPAD_SCALEX, touchpad_y * TOUCHPAD_SCALEY, touchpad_state ? 1.0f : 0.0f);
  1111. }
  1112. SDL_memcpy(&ctx->last_state, packet, sizeof(ctx->last_state));
  1113. }
  1114. static SDL_bool
  1115. VerifyCRC(Uint8 *data, int size)
  1116. {
  1117. Uint8 ubHdr = 0xA1; /* hidp header is part of the CRC calculation */
  1118. Uint32 unCRC, unPacketCRC;
  1119. Uint8 *packetCRC = data + size - sizeof(unPacketCRC);
  1120. unCRC = SDL_crc32(0, &ubHdr, 1);
  1121. unCRC = SDL_crc32(unCRC, data, (size_t)(size - sizeof(unCRC)));
  1122. unPacketCRC = LOAD32(packetCRC[0],
  1123. packetCRC[1],
  1124. packetCRC[2],
  1125. packetCRC[3]);
  1126. return (unCRC == unPacketCRC) ? SDL_TRUE : SDL_FALSE;
  1127. }
  1128. static SDL_bool
  1129. HIDAPI_DriverPS5_IsPacketValid(SDL_DriverPS5_Context *ctx, Uint8 *data, int size)
  1130. {
  1131. switch (data[0]) {
  1132. case k_EPS5ReportIdState:
  1133. return SDL_TRUE;
  1134. case k_EPS5ReportIdBluetoothState:
  1135. if (VerifyCRC(data, size)) {
  1136. return SDL_TRUE;
  1137. }
  1138. break;
  1139. default:
  1140. break;
  1141. }
  1142. return SDL_FALSE;
  1143. }
  1144. static SDL_bool
  1145. HIDAPI_DriverPS5_UpdateDevice(SDL_HIDAPI_Device *device)
  1146. {
  1147. SDL_DriverPS5_Context *ctx = (SDL_DriverPS5_Context *)device->context;
  1148. SDL_Joystick *joystick = NULL;
  1149. Uint8 data[USB_PACKET_LENGTH*2];
  1150. int size;
  1151. int packet_count = 0;
  1152. Uint32 now = SDL_GetTicks();
  1153. if (device->num_joysticks > 0) {
  1154. joystick = SDL_JoystickFromInstanceID(device->joysticks[0]);
  1155. }
  1156. while ((size = SDL_hid_read_timeout(device->dev, data, sizeof(data), 0)) > 0) {
  1157. #ifdef DEBUG_PS5_PROTOCOL
  1158. HIDAPI_DumpPacket("PS5 packet: size = %d", data, size);
  1159. #endif
  1160. if (!HIDAPI_DriverPS5_IsPacketValid(ctx, data, size)) {
  1161. continue;
  1162. }
  1163. ++packet_count;
  1164. ctx->last_packet = now;
  1165. if (!joystick) {
  1166. continue;
  1167. }
  1168. switch (data[0]) {
  1169. case k_EPS5ReportIdState:
  1170. if (size == 10 || size == 78) {
  1171. HIDAPI_DriverPS5_HandleSimpleStatePacket(joystick, device->dev, ctx, (PS5SimpleStatePacket_t *)&data[1]);
  1172. } else {
  1173. HIDAPI_DriverPS5_HandleStatePacketCommon(joystick, device->dev, ctx, (PS5StatePacketCommon_t *)&data[1]);
  1174. if (ctx->use_alternate_report) {
  1175. HIDAPI_DriverPS5_HandleStatePacketAlt(joystick, device->dev, ctx, (PS5StatePacketAlt_t *)&data[1]);
  1176. } else {
  1177. HIDAPI_DriverPS5_HandleStatePacket(joystick, device->dev, ctx, (PS5StatePacket_t *)&data[1]);
  1178. }
  1179. }
  1180. break;
  1181. case k_EPS5ReportIdBluetoothState:
  1182. if (!ctx->enhanced_mode) {
  1183. /* This is the extended report, we can enable effects now */
  1184. HIDAPI_DriverPS5_SetEnhancedMode(device, joystick);
  1185. }
  1186. if (ctx->led_reset_state == k_EDS5LEDResetStatePending) {
  1187. HIDAPI_DriverPS5_CheckPendingLEDReset(device);
  1188. }
  1189. HIDAPI_DriverPS5_HandleStatePacketCommon(joystick, device->dev, ctx, (PS5StatePacketCommon_t *)&data[2]);
  1190. if (ctx->use_alternate_report) {
  1191. HIDAPI_DriverPS5_HandleStatePacketAlt(joystick, device->dev, ctx, (PS5StatePacketAlt_t *)&data[2]);
  1192. } else {
  1193. HIDAPI_DriverPS5_HandleStatePacket(joystick, device->dev, ctx, (PS5StatePacket_t *)&data[2]);
  1194. }
  1195. break;
  1196. default:
  1197. #ifdef DEBUG_JOYSTICK
  1198. SDL_Log("Unknown PS5 packet: 0x%.2x\n", data[0]);
  1199. #endif
  1200. break;
  1201. }
  1202. }
  1203. if (device->is_bluetooth) {
  1204. if (packet_count == 0) {
  1205. /* Check to see if it looks like the device disconnected */
  1206. if (SDL_TICKS_PASSED(now, ctx->last_packet + BLUETOOTH_DISCONNECT_TIMEOUT_MS)) {
  1207. /* Send an empty output report to tickle the Bluetooth stack */
  1208. HIDAPI_DriverPS5_TickleBluetooth(device);
  1209. }
  1210. } else {
  1211. /* Reconnect the Bluetooth device once the USB device is gone */
  1212. if (device->num_joysticks == 0 &&
  1213. !HIDAPI_HasConnectedUSBDevice(device->serial)) {
  1214. HIDAPI_JoystickConnected(device, NULL);
  1215. }
  1216. }
  1217. }
  1218. if (size < 0 && device->num_joysticks > 0) {
  1219. /* Read error, device is disconnected */
  1220. HIDAPI_JoystickDisconnected(device, device->joysticks[0]);
  1221. }
  1222. return (size >= 0);
  1223. }
  1224. static void
  1225. HIDAPI_DriverPS5_CloseJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
  1226. {
  1227. SDL_DriverPS5_Context *ctx = (SDL_DriverPS5_Context *)device->context;
  1228. SDL_DelHintCallback(SDL_HINT_JOYSTICK_HIDAPI_PS5_RUMBLE,
  1229. SDL_PS5RumbleHintChanged, ctx);
  1230. SDL_DelHintCallback(SDL_HINT_JOYSTICK_HIDAPI_PS5_PLAYER_LED,
  1231. SDL_PS5PlayerLEDHintChanged, ctx);
  1232. ctx->joystick = NULL;
  1233. }
  1234. static void
  1235. HIDAPI_DriverPS5_FreeDevice(SDL_HIDAPI_Device *device)
  1236. {
  1237. }
  1238. SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverPS5 =
  1239. {
  1240. SDL_HINT_JOYSTICK_HIDAPI_PS5,
  1241. SDL_TRUE,
  1242. HIDAPI_DriverPS5_RegisterHints,
  1243. HIDAPI_DriverPS5_UnregisterHints,
  1244. HIDAPI_DriverPS5_IsEnabled,
  1245. HIDAPI_DriverPS5_IsSupportedDevice,
  1246. HIDAPI_DriverPS5_InitDevice,
  1247. HIDAPI_DriverPS5_GetDevicePlayerIndex,
  1248. HIDAPI_DriverPS5_SetDevicePlayerIndex,
  1249. HIDAPI_DriverPS5_UpdateDevice,
  1250. HIDAPI_DriverPS5_OpenJoystick,
  1251. HIDAPI_DriverPS5_RumbleJoystick,
  1252. HIDAPI_DriverPS5_RumbleJoystickTriggers,
  1253. HIDAPI_DriverPS5_GetJoystickCapabilities,
  1254. HIDAPI_DriverPS5_SetJoystickLED,
  1255. HIDAPI_DriverPS5_SendJoystickEffect,
  1256. HIDAPI_DriverPS5_SetJoystickSensorsEnabled,
  1257. HIDAPI_DriverPS5_CloseJoystick,
  1258. HIDAPI_DriverPS5_FreeDevice,
  1259. };
  1260. #endif /* SDL_JOYSTICK_HIDAPI_PS5 */
  1261. #endif /* SDL_JOYSTICK_HIDAPI */
  1262. /* vi: set ts=4 sw=4 expandtab: */