SDL_hidapi_switch2.c 48 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335
  1. /*
  2. Simple DirectMedia Layer
  3. Copyright (C) 1997-2026 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. /* This driver supports the Nintendo Switch Pro controller.
  19. Code and logic contributed by Valve Corporation under the SDL zlib license.
  20. */
  21. #include "SDL_internal.h"
  22. #ifdef SDL_JOYSTICK_HIDAPI
  23. #include "../../SDL_hints_c.h"
  24. #include "../../misc/SDL_libusb.h"
  25. #include "../SDL_sysjoystick.h"
  26. #include "SDL_hidapijoystick_c.h"
  27. #include "SDL_hidapi_rumble.h"
  28. #ifdef SDL_JOYSTICK_HIDAPI_SWITCH2
  29. #define RUMBLE_INTERVAL 12
  30. #define RUMBLE_MAX 29000
  31. // Define this if you want to log all packets from the controller
  32. #if 0
  33. #define DEBUG_SWITCH2_PROTOCOL
  34. #endif
  35. enum
  36. {
  37. SDL_GAMEPAD_BUTTON_SWITCH2_PRO_SHARE = 11,
  38. SDL_GAMEPAD_BUTTON_SWITCH2_PRO_C,
  39. SDL_GAMEPAD_BUTTON_SWITCH2_PRO_RIGHT_PADDLE,
  40. SDL_GAMEPAD_BUTTON_SWITCH2_PRO_LEFT_PADDLE,
  41. SDL_GAMEPAD_NUM_SWITCH2_PRO_BUTTONS
  42. };
  43. enum
  44. {
  45. SDL_GAMEPAD_BUTTON_SWITCH2_JOYCON_SHARE = 11,
  46. SDL_GAMEPAD_BUTTON_SWITCH2_JOYCON_C,
  47. SDL_GAMEPAD_BUTTON_SWITCH2_JOYCON_RIGHT_PADDLE1,
  48. SDL_GAMEPAD_BUTTON_SWITCH2_JOYCON_LEFT_PADDLE1,
  49. SDL_GAMEPAD_BUTTON_SWITCH2_JOYCON_RIGHT_PADDLE2,
  50. SDL_GAMEPAD_BUTTON_SWITCH2_JOYCON_LEFT_PADDLE2,
  51. SDL_GAMEPAD_NUM_SWITCH2_JOYCON_BUTTONS
  52. };
  53. enum
  54. {
  55. SDL_GAMEPAD_BUTTON_SWITCH2_GAMECUBE_GUIDE = 4,
  56. SDL_GAMEPAD_BUTTON_SWITCH2_GAMECUBE_START,
  57. SDL_GAMEPAD_BUTTON_SWITCH2_GAMECUBE_LEFT_SHOULDER,
  58. SDL_GAMEPAD_BUTTON_SWITCH2_GAMECUBE_RIGHT_SHOULDER,
  59. SDL_GAMEPAD_BUTTON_SWITCH2_GAMECUBE_SHARE,
  60. SDL_GAMEPAD_BUTTON_SWITCH2_GAMECUBE_C,
  61. SDL_GAMEPAD_BUTTON_SWITCH2_GAMECUBE_LEFT_TRIGGER, // Full trigger pull click
  62. SDL_GAMEPAD_BUTTON_SWITCH2_GAMECUBE_RIGHT_TRIGGER, // Full trigger pull click
  63. SDL_GAMEPAD_NUM_SWITCH2_GAMECUBE_BUTTONS
  64. };
  65. typedef struct
  66. {
  67. Uint16 neutral;
  68. Uint16 max;
  69. Uint16 min;
  70. } Switch2_AxisCalibration;
  71. typedef struct
  72. {
  73. Switch2_AxisCalibration x;
  74. Switch2_AxisCalibration y;
  75. } Switch2_StickCalibration;
  76. typedef struct
  77. {
  78. SDL_HIDAPI_Device *device;
  79. SDL_Joystick *joystick;
  80. SDL_LibUSBContext *libusb;
  81. libusb_device_handle *device_handle;
  82. bool interface_claimed;
  83. Uint8 interface_number;
  84. Uint8 out_endpoint;
  85. Uint8 in_endpoint;
  86. Uint64 rumble_timestamp;
  87. Uint32 rumble_seq;
  88. Uint16 rumble_hi_amp;
  89. Uint16 rumble_hi_freq;
  90. Uint16 rumble_lo_amp;
  91. Uint16 rumble_lo_freq;
  92. Uint32 rumble_error;
  93. bool rumble_updated;
  94. Switch2_StickCalibration left_stick;
  95. Switch2_StickCalibration right_stick;
  96. Uint8 left_trigger_zero;
  97. Uint8 right_trigger_zero;
  98. float gyro_bias_x;
  99. float gyro_bias_y;
  100. float gyro_bias_z;
  101. float accel_bias_x;
  102. float accel_bias_y;
  103. float accel_bias_z;
  104. bool sensors_enabled;
  105. bool sensors_ready;
  106. int sample_count;
  107. Uint64 first_sensor_timestamp;
  108. Uint64 sensor_ts_coeff;
  109. float gyro_coeff;
  110. bool player_lights;
  111. int player_index;
  112. bool vertical_mode;
  113. Uint8 last_state[USB_PACKET_LENGTH];
  114. } SDL_DriverSwitch2_Context;
  115. static void ParseStickCalibration(Switch2_StickCalibration *stick_data, const Uint8 *data)
  116. {
  117. stick_data->x.neutral = data[0];
  118. stick_data->x.neutral |= (data[1] & 0x0F) << 8;
  119. stick_data->y.neutral = data[1] >> 4;
  120. stick_data->y.neutral |= data[2] << 4;
  121. stick_data->x.max = data[3];
  122. stick_data->x.max |= (data[4] & 0x0F) << 8;
  123. stick_data->y.max = data[4] >> 4;
  124. stick_data->y.max |= data[5] << 4;
  125. stick_data->x.min = data[6];
  126. stick_data->x.min |= (data[7] & 0x0F) << 8;
  127. stick_data->y.min = data[7] >> 4;
  128. stick_data->y.min |= data[8] << 4;
  129. }
  130. static int SendBulkData(SDL_DriverSwitch2_Context *ctx, const Uint8 *data, unsigned size)
  131. {
  132. int transferred;
  133. int res = ctx->libusb->bulk_transfer(ctx->device_handle,
  134. ctx->out_endpoint,
  135. (Uint8 *)data,
  136. size,
  137. &transferred,
  138. 1000);
  139. if (res < 0) {
  140. return res;
  141. }
  142. return transferred;
  143. }
  144. static int RecvBulkData(SDL_DriverSwitch2_Context *ctx, Uint8 *data, unsigned size)
  145. {
  146. int transferred;
  147. int total_transferred = 0;
  148. int res;
  149. while (size > 0) {
  150. unsigned current_read = size;
  151. if (current_read > 64) {
  152. current_read = 64;
  153. }
  154. res = ctx->libusb->bulk_transfer(ctx->device_handle,
  155. ctx->in_endpoint,
  156. data,
  157. current_read,
  158. &transferred,
  159. 100);
  160. if (res < 0) {
  161. return res;
  162. }
  163. total_transferred += transferred;
  164. size -= transferred;
  165. data += current_read;
  166. if ((unsigned) transferred < current_read) {
  167. break;
  168. }
  169. }
  170. return total_transferred;
  171. }
  172. static void MapJoystickAxis(Uint64 timestamp, SDL_Joystick *joystick, Uint8 axis, const Switch2_AxisCalibration *calib, float value, bool invert)
  173. {
  174. Sint16 mapped_value;
  175. if (calib && calib->neutral && calib->min && calib->max) {
  176. value -= calib->neutral;
  177. if (value < 0) {
  178. value /= calib->min;
  179. } else {
  180. value /= calib->max;
  181. }
  182. mapped_value = (Sint16) SDL_clamp(value * SDL_MAX_SINT16, SDL_MIN_SINT16, SDL_MAX_SINT16);
  183. } else {
  184. mapped_value = (Sint16) HIDAPI_RemapVal(value, 0, 4096, SDL_MIN_SINT16, SDL_MAX_SINT16);
  185. }
  186. if (invert) {
  187. mapped_value = ~mapped_value;
  188. }
  189. SDL_SendJoystickAxis(timestamp, joystick, axis, mapped_value);
  190. }
  191. static void MapTriggerAxis(Uint64 timestamp, SDL_Joystick *joystick, Uint8 axis, Uint8 max, float value)
  192. {
  193. Sint16 mapped_value = (Sint16) HIDAPI_RemapVal(
  194. SDL_clamp((value - max) / (232.f - max), 0, 1),
  195. 0, 1,
  196. SDL_MIN_SINT16, SDL_MAX_SINT16
  197. );
  198. SDL_SendJoystickAxis(timestamp, joystick, axis, mapped_value);
  199. }
  200. static bool UpdateSlotLED(SDL_DriverSwitch2_Context *ctx)
  201. {
  202. Uint8 set_led_data[] = {
  203. 0x09, 0x91, 0x00, 0x07, 0x00, 0x08, 0x00, 0x00,
  204. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
  205. };
  206. Uint8 reply[8] = {0};
  207. const Uint8 player_pattern[] = { 0x1, 0x3, 0x7, 0xf, 0x9, 0x5, 0xd, 0x6 };
  208. if (ctx->player_lights && ctx->player_index >= 0) {
  209. set_led_data[8] = player_pattern[ctx->player_index % 8];
  210. }
  211. int res = SendBulkData(ctx, set_led_data, sizeof(set_led_data));
  212. if (res < 0) {
  213. return SDL_SetError("Couldn't set LED data: %d\n", res);
  214. }
  215. return (RecvBulkData(ctx, reply, sizeof(reply)) > 0);
  216. }
  217. static int ReadFlashBlock(SDL_DriverSwitch2_Context *ctx, Uint32 address, Uint8 *out)
  218. {
  219. Uint8 flash_read_command[] = {
  220. 0x02, 0x91, 0x00, 0x01, 0x00, 0x08, 0x00, 0x00,
  221. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
  222. };
  223. Uint8 buffer[0x50] = {0};
  224. int res;
  225. flash_read_command[12] = (Uint8)address;
  226. flash_read_command[13] = (Uint8)(address >> 8);
  227. flash_read_command[14] = (Uint8)(address >> 16);
  228. flash_read_command[15] = (Uint8)(address >> 24);
  229. res = SendBulkData(ctx, flash_read_command, sizeof(flash_read_command));
  230. if (res < 0) {
  231. return res;
  232. }
  233. res = RecvBulkData(ctx, buffer, sizeof(buffer));
  234. if (res < 0) {
  235. return res;
  236. }
  237. SDL_memcpy(out, &buffer[0x10], 0x40);
  238. return 0;
  239. }
  240. static void SDLCALL SDL_PlayerLEDHintChanged(void *userdata, const char *name, const char *oldValue, const char *hint)
  241. {
  242. SDL_DriverSwitch2_Context *ctx = (SDL_DriverSwitch2_Context *)userdata;
  243. bool player_lights = SDL_GetStringBoolean(hint, true);
  244. if (player_lights != ctx->player_lights) {
  245. ctx->player_lights = player_lights;
  246. UpdateSlotLED(ctx);
  247. HIDAPI_UpdateDeviceProperties(ctx->device);
  248. }
  249. }
  250. static void HIDAPI_DriverSwitch2_RegisterHints(SDL_HintCallback callback, void *userdata)
  251. {
  252. SDL_AddHintCallback(SDL_HINT_JOYSTICK_HIDAPI_SWITCH2, callback, userdata);
  253. }
  254. static void HIDAPI_DriverSwitch2_UnregisterHints(SDL_HintCallback callback, void *userdata)
  255. {
  256. SDL_RemoveHintCallback(SDL_HINT_JOYSTICK_HIDAPI_SWITCH2, callback, userdata);
  257. }
  258. static bool HIDAPI_DriverSwitch2_IsEnabled(void)
  259. {
  260. return SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI_SWITCH2, SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI, SDL_HIDAPI_DEFAULT));
  261. }
  262. static bool HIDAPI_DriverSwitch2_IsSupportedDevice(SDL_HIDAPI_Device *device, const char *name, SDL_GamepadType type, Uint16 vendor_id, Uint16 product_id, Uint16 version, int interface_number, int interface_class, int interface_subclass, int interface_protocol)
  263. {
  264. if (vendor_id == USB_VENDOR_NINTENDO) {
  265. switch (product_id) {
  266. case USB_PRODUCT_NINTENDO_SWITCH2_GAMECUBE_CONTROLLER:
  267. case USB_PRODUCT_NINTENDO_SWITCH2_JOYCON_LEFT:
  268. case USB_PRODUCT_NINTENDO_SWITCH2_JOYCON_RIGHT:
  269. case USB_PRODUCT_NINTENDO_SWITCH2_PRO:
  270. return true;
  271. }
  272. }
  273. return false;
  274. }
  275. static bool HIDAPI_DriverSwitch2_InitBluetooth(SDL_HIDAPI_Device *device)
  276. {
  277. // FIXME: Need to add Bluetooth support
  278. return SDL_SetError("Nintendo Switch2 controllers not supported over Bluetooth");
  279. }
  280. static bool FindBulkEndpoints(SDL_LibUSBContext *libusb, libusb_device_handle *handle, Uint8 *bInterfaceNumber, Uint8 *out_endpoint, Uint8 *in_endpoint)
  281. {
  282. struct libusb_config_descriptor *config;
  283. int found = 0;
  284. if (libusb->get_config_descriptor(libusb->get_device(handle), 0, &config) != 0) {
  285. return false;
  286. }
  287. for (int i = 0; i < config->bNumInterfaces; i++) {
  288. const struct libusb_interface *iface = &config->interface[i];
  289. for (int j = 0; j < iface->num_altsetting; j++) {
  290. const struct libusb_interface_descriptor *altsetting = &iface->altsetting[j];
  291. if (altsetting->bInterfaceNumber == 1) {
  292. for (int k = 0; k < altsetting->bNumEndpoints; k++) {
  293. const struct libusb_endpoint_descriptor *ep = &altsetting->endpoint[k];
  294. if ((ep->bmAttributes & LIBUSB_TRANSFER_TYPE_MASK) == LIBUSB_TRANSFER_TYPE_BULK) {
  295. *bInterfaceNumber = altsetting->bInterfaceNumber;
  296. if ((ep->bEndpointAddress & LIBUSB_ENDPOINT_DIR_MASK) == LIBUSB_ENDPOINT_OUT) {
  297. *out_endpoint = ep->bEndpointAddress;
  298. found |= 1;
  299. }
  300. if ((ep->bEndpointAddress & LIBUSB_ENDPOINT_DIR_MASK) == LIBUSB_ENDPOINT_IN) {
  301. *in_endpoint = ep->bEndpointAddress;
  302. found |= 2;
  303. }
  304. if (found == 3) {
  305. libusb->free_config_descriptor(config);
  306. return true;
  307. }
  308. }
  309. }
  310. }
  311. }
  312. }
  313. libusb->free_config_descriptor(config);
  314. return false;
  315. }
  316. static bool HIDAPI_DriverSwitch2_InitUSB(SDL_HIDAPI_Device *device)
  317. {
  318. SDL_DriverSwitch2_Context *ctx = (SDL_DriverSwitch2_Context *)device->context;
  319. if (!SDL_InitLibUSB(&ctx->libusb)) {
  320. return false;
  321. }
  322. ctx->device_handle = (libusb_device_handle *)SDL_GetPointerProperty(SDL_hid_get_properties(device->dev), SDL_PROP_HIDAPI_LIBUSB_DEVICE_HANDLE_POINTER, NULL);
  323. if (!ctx->device_handle) {
  324. return SDL_SetError("Couldn't get libusb device handle");
  325. }
  326. if (!FindBulkEndpoints(ctx->libusb, ctx->device_handle, &ctx->interface_number, &ctx->out_endpoint, &ctx->in_endpoint)) {
  327. return SDL_SetError("Couldn't find bulk endpoints");
  328. }
  329. ctx->libusb->set_auto_detach_kernel_driver(ctx->device_handle, true);
  330. int res = ctx->libusb->claim_interface(ctx->device_handle, ctx->interface_number);
  331. if (res < 0) {
  332. return SDL_SetError("Couldn't claim interface %d: %d\n", ctx->interface_number, res);
  333. }
  334. ctx->interface_claimed = true;
  335. const Uint8 *init_sequence[] = {
  336. (Uint8[]) { // Unknown purpose
  337. 0x7, 0x91, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0,
  338. },
  339. (Uint8[]) { // Set feature output bit mask
  340. 0x0c, 0x91, 0x00, 0x02, 0x00, 0x04, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00
  341. },
  342. (Uint8[]) { // Unknown purpose
  343. 0x11, 0x91, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0,
  344. },
  345. (Uint8[]) { // Set rumble data?
  346. 0x0a, 0x91, 0x00, 0x08, 0x00, 0x14, 0x00, 0x00,
  347. 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  348. 0xff, 0x35, 0x00, 0x46, 0x00, 0x00, 0x00, 0x00,
  349. 0x00, 0x00, 0x00, 0x00
  350. },
  351. (Uint8[]) { // Enable feature output bits
  352. 0x0c, 0x91, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00
  353. },
  354. (Uint8[]) { // Unknown purpose
  355. 0x01, 0x91, 0x0, 0xc, 0x0, 0x0, 0x0, 0x0,
  356. },
  357. (Uint8[]) { // Enable rumble
  358. 0x01, 0x91, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0,
  359. },
  360. (Uint8[]) { // Enable grip buttons on charging grip
  361. 0x8, 0x91, 0x0, 0x2, 0x0, 0x4, 0x0, 0x0, 0x01, 0x0, 0x0, 0x0,
  362. },
  363. (Uint8[]) { // Set report format
  364. 0x03, 0x91, 0x00, 0x0a, 0x00, 0x04, 0x00, 0x00,
  365. 0x05, 0x00, 0x00, 0x00
  366. },
  367. (Uint8[]) { // Start output
  368. 0x03, 0x91, 0x00, 0x0d, 0x00, 0x08, 0x00, 0x00,
  369. 0x01, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  370. },
  371. NULL, // Sentinel
  372. };
  373. unsigned char calibration_data[0x40] = {0};
  374. res = ReadFlashBlock(ctx, 0x13000, calibration_data);
  375. if (res < 0) {
  376. SDL_LogWarn(SDL_LOG_CATEGORY_INPUT, "Couldn't read serial number: %d", res);
  377. } else {
  378. char serial[0x11] = {0};
  379. SDL_strlcpy(serial, (char*)&calibration_data[2], sizeof(serial));
  380. HIDAPI_SetDeviceSerial(device, serial);
  381. }
  382. res = ReadFlashBlock(ctx, 0x13040, calibration_data);
  383. if (res < 0) {
  384. SDL_LogWarn(SDL_LOG_CATEGORY_INPUT, "Couldn't read factory calibration data: %d", res);
  385. } else {
  386. ctx->gyro_bias_x = *(float*)&calibration_data[4];
  387. ctx->gyro_bias_y = *(float*)&calibration_data[8];
  388. ctx->gyro_bias_z = *(float*)&calibration_data[12];
  389. }
  390. res = ReadFlashBlock(ctx, 0x13080, calibration_data);
  391. if (res < 0) {
  392. SDL_LogWarn(SDL_LOG_CATEGORY_INPUT, "Couldn't read factory calibration data: %d", res);
  393. } else {
  394. ParseStickCalibration(&ctx->left_stick, &calibration_data[0x28]);
  395. }
  396. res = ReadFlashBlock(ctx, 0x130C0, calibration_data);
  397. if (res < 0) {
  398. SDL_LogWarn(SDL_LOG_CATEGORY_INPUT, "Couldn't read factory calibration data: %d", res);
  399. } else {
  400. ParseStickCalibration(&ctx->right_stick, &calibration_data[0x28]);
  401. }
  402. res = ReadFlashBlock(ctx, 0x13100, calibration_data);
  403. if (res < 0) {
  404. SDL_LogWarn(SDL_LOG_CATEGORY_INPUT, "Couldn't read factory calibration data: %d", res);
  405. } else {
  406. ctx->accel_bias_x = *(float*)&calibration_data[12];
  407. ctx->accel_bias_y = *(float*)&calibration_data[16];
  408. ctx->accel_bias_z = *(float*)&calibration_data[20];
  409. }
  410. if (device->product_id == USB_PRODUCT_NINTENDO_SWITCH2_GAMECUBE_CONTROLLER) {
  411. res = ReadFlashBlock(ctx, 0x13140, calibration_data);
  412. if (res < 0) {
  413. SDL_LogWarn(SDL_LOG_CATEGORY_INPUT, "Couldn't read factory calibration data: %d", res);
  414. } else {
  415. ctx->left_trigger_zero = calibration_data[0];
  416. ctx->right_trigger_zero = calibration_data[1];
  417. }
  418. }
  419. res = ReadFlashBlock(ctx, 0x1FC040, calibration_data);
  420. if (res < 0) {
  421. SDL_LogWarn(SDL_LOG_CATEGORY_INPUT, "Couldn't read user calibration data: %d", res);
  422. } else if (calibration_data[0] == 0xb2 && calibration_data[1] == 0xa1) {
  423. ParseStickCalibration(&ctx->left_stick, &calibration_data[2]);
  424. }
  425. res = ReadFlashBlock(ctx, 0x1FC080, calibration_data);
  426. if (res < 0) {
  427. SDL_LogWarn(SDL_LOG_CATEGORY_INPUT, "Couldn't read user calibration data: %d", res);
  428. } else if (calibration_data[0] == 0xb2 && calibration_data[1] == 0xa1) {
  429. ParseStickCalibration(&ctx->right_stick, &calibration_data[2]);
  430. }
  431. for (int i = 0; init_sequence[i]; i++) {
  432. res = SendBulkData(ctx, init_sequence[i], init_sequence[i][5] + 8);
  433. if (res < 0) {
  434. return SDL_SetError("Couldn't send initialization data: %d\n", res);
  435. }
  436. RecvBulkData(ctx, calibration_data, 0x40);
  437. }
  438. return true;
  439. }
  440. static bool HIDAPI_DriverSwitch2_InitDevice(SDL_HIDAPI_Device *device)
  441. {
  442. SDL_DriverSwitch2_Context *ctx;
  443. ctx = (SDL_DriverSwitch2_Context *)SDL_calloc(1, sizeof(*ctx));
  444. if (!ctx) {
  445. return false;
  446. }
  447. ctx->device = device;
  448. device->context = ctx;
  449. if (device->is_bluetooth) {
  450. if (!HIDAPI_DriverSwitch2_InitBluetooth(device)) {
  451. return false;
  452. }
  453. } else {
  454. if (!HIDAPI_DriverSwitch2_InitUSB(device)) {
  455. return false;
  456. }
  457. }
  458. ctx->sensor_ts_coeff = 10000;
  459. ctx->gyro_coeff = 34.8f;
  460. // Sometimes the device handle isn't available during enumeration so we don't get the device name, so set it explicitly
  461. switch (device->product_id) {
  462. case USB_PRODUCT_NINTENDO_SWITCH2_GAMECUBE_CONTROLLER:
  463. HIDAPI_SetDeviceName(device, "Nintendo GameCube Controller");
  464. break;
  465. case USB_PRODUCT_NINTENDO_SWITCH2_PRO:
  466. HIDAPI_SetDeviceName(device, "Nintendo Switch Pro Controller");
  467. break;
  468. default:
  469. break;
  470. }
  471. return HIDAPI_JoystickConnected(device, NULL);
  472. }
  473. static int HIDAPI_DriverSwitch2_GetDevicePlayerIndex(SDL_HIDAPI_Device *device, SDL_JoystickID instance_id)
  474. {
  475. return -1;
  476. }
  477. static void HIDAPI_DriverSwitch2_SetDevicePlayerIndex(SDL_HIDAPI_Device *device, SDL_JoystickID instance_id, int player_index)
  478. {
  479. SDL_DriverSwitch2_Context *ctx = (SDL_DriverSwitch2_Context *)device->context;
  480. if (!ctx->joystick) {
  481. return;
  482. }
  483. ctx->player_index = player_index;
  484. UpdateSlotLED(ctx);
  485. }
  486. static bool HIDAPI_DriverSwitch2_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
  487. {
  488. SDL_DriverSwitch2_Context *ctx = (SDL_DriverSwitch2_Context *)device->context;
  489. ctx->joystick = joystick;
  490. // Initialize player index (needed for setting LEDs)
  491. ctx->player_index = SDL_GetJoystickPlayerIndex(joystick);
  492. ctx->player_lights = SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI_SWITCH_PLAYER_LED, true);
  493. UpdateSlotLED(ctx);
  494. SDL_AddHintCallback(SDL_HINT_JOYSTICK_HIDAPI_SWITCH_PLAYER_LED,
  495. SDL_PlayerLEDHintChanged, ctx);
  496. // Initialize the joystick capabilities
  497. if (!ctx->device->parent) {
  498. SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_GYRO, 250.0f);
  499. SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_ACCEL, 250.0f);
  500. }
  501. switch (device->product_id) {
  502. case USB_PRODUCT_NINTENDO_SWITCH2_GAMECUBE_CONTROLLER:
  503. joystick->nbuttons = SDL_GAMEPAD_NUM_SWITCH2_GAMECUBE_BUTTONS;
  504. break;
  505. case USB_PRODUCT_NINTENDO_SWITCH2_JOYCON_LEFT:
  506. if (ctx->device->parent) {
  507. SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_GYRO_L, 250.0f);
  508. SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_ACCEL_L, 250.0f);
  509. }
  510. joystick->nbuttons = SDL_GAMEPAD_NUM_SWITCH2_JOYCON_BUTTONS;
  511. break;
  512. case USB_PRODUCT_NINTENDO_SWITCH2_JOYCON_RIGHT:
  513. if (ctx->device->parent) {
  514. SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_GYRO, 250.0f);
  515. SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_ACCEL, 250.0f);
  516. SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_GYRO_R, 250.0f);
  517. SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_ACCEL_R, 250.0f);
  518. }
  519. joystick->nbuttons = SDL_GAMEPAD_NUM_SWITCH2_JOYCON_BUTTONS;
  520. break;
  521. case USB_PRODUCT_NINTENDO_SWITCH2_PRO:
  522. joystick->nbuttons = SDL_GAMEPAD_NUM_SWITCH2_PRO_BUTTONS;
  523. break;
  524. default:
  525. // FIXME: How many buttons does this have?
  526. break;
  527. }
  528. joystick->naxes = SDL_GAMEPAD_AXIS_COUNT;
  529. joystick->nhats = 1;
  530. ctx->rumble_hi_freq = 0x187;
  531. ctx->rumble_lo_freq = 0x112;
  532. // Set up for vertical mode
  533. ctx->vertical_mode = SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI_VERTICAL_JOY_CONS, false);
  534. return true;
  535. }
  536. static bool HIDAPI_DriverSwitch2_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble)
  537. {
  538. SDL_DriverSwitch2_Context *ctx = (SDL_DriverSwitch2_Context *)device->context;
  539. if (low_frequency_rumble != ctx->rumble_lo_amp || high_frequency_rumble != ctx->rumble_hi_amp) {
  540. ctx->rumble_lo_amp = low_frequency_rumble;
  541. ctx->rumble_hi_amp = high_frequency_rumble;
  542. ctx->rumble_updated = true;
  543. }
  544. return true;
  545. }
  546. static bool HIDAPI_DriverSwitch2_RumbleJoystickTriggers(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble)
  547. {
  548. return SDL_Unsupported();
  549. }
  550. static Uint32 HIDAPI_DriverSwitch2_GetJoystickCapabilities(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
  551. {
  552. SDL_DriverSwitch2_Context *ctx = (SDL_DriverSwitch2_Context *)device->context;
  553. Uint32 result = SDL_JOYSTICK_CAP_RUMBLE;
  554. if (ctx->player_lights) {
  555. result |= SDL_JOYSTICK_CAP_PLAYER_LED;
  556. }
  557. return result;
  558. }
  559. static bool HIDAPI_DriverSwitch2_SetJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue)
  560. {
  561. return SDL_Unsupported();
  562. }
  563. static bool HIDAPI_DriverSwitch2_SendJoystickEffect(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, const void *data, int size)
  564. {
  565. return SDL_Unsupported();
  566. }
  567. static bool HIDAPI_DriverSwitch2_SetJoystickSensorsEnabled(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, bool enabled)
  568. {
  569. SDL_DriverSwitch2_Context *ctx = (SDL_DriverSwitch2_Context *)device->context;
  570. if (ctx->sensors_ready) {
  571. Uint8 data[] = {
  572. 0x0c, 0x91, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00
  573. };
  574. unsigned char reply[12] = {0};
  575. if (enabled) {
  576. data[8] |= 4;
  577. }
  578. int res = SendBulkData(ctx, data, sizeof(data));
  579. if (res < 0) {
  580. return SDL_SetError("Couldn't set sensors enabled: %d\n", res);
  581. }
  582. RecvBulkData(ctx, reply, sizeof(reply));
  583. }
  584. ctx->sensors_enabled = true;
  585. return true;
  586. }
  587. static void HandleGameCubeState(Uint64 timestamp, SDL_Joystick *joystick, SDL_DriverSwitch2_Context *ctx, Uint8 *data, int size)
  588. {
  589. if (data[5] != ctx->last_state[5]) {
  590. SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_WEST, ((data[5] & 0x01) != 0));
  591. SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_NORTH, ((data[5] & 0x02) != 0));
  592. SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_SOUTH, ((data[5] & 0x04) != 0));
  593. SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_EAST, ((data[5] & 0x08) != 0));
  594. SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_SWITCH2_GAMECUBE_RIGHT_TRIGGER, ((data[5] & 0x40) != 0));
  595. SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_SWITCH2_GAMECUBE_RIGHT_SHOULDER, ((data[5] & 0x80) != 0));
  596. }
  597. if (data[6] != ctx->last_state[6]) {
  598. SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_SWITCH2_GAMECUBE_START, ((data[6] & 0x02) != 0));
  599. SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_SWITCH2_GAMECUBE_GUIDE, ((data[6] & 0x10) != 0));
  600. SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_SWITCH2_GAMECUBE_SHARE, ((data[6] & 0x20) != 0));
  601. SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_SWITCH2_GAMECUBE_C, ((data[6] & 0x40) != 0));
  602. }
  603. if (data[7] != ctx->last_state[7]) {
  604. Uint8 hat = 0;
  605. if (data[7] & 0x01) {
  606. hat |= SDL_HAT_DOWN;
  607. }
  608. if (data[7] & 0x02) {
  609. hat |= SDL_HAT_UP;
  610. }
  611. if (data[7] & 0x04) {
  612. hat |= SDL_HAT_RIGHT;
  613. }
  614. if (data[7] & 0x08) {
  615. hat |= SDL_HAT_LEFT;
  616. }
  617. SDL_SendJoystickHat(timestamp, joystick, 0, hat);
  618. SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_SWITCH2_GAMECUBE_LEFT_TRIGGER, ((data[7] & 0x40) != 0));
  619. SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_SWITCH2_GAMECUBE_LEFT_SHOULDER, ((data[7] & 0x80) != 0));
  620. }
  621. MapTriggerAxis(
  622. timestamp,
  623. joystick,
  624. SDL_GAMEPAD_AXIS_LEFT_TRIGGER,
  625. ctx->left_trigger_zero,
  626. data[61]
  627. );
  628. MapTriggerAxis(
  629. timestamp,
  630. joystick,
  631. SDL_GAMEPAD_AXIS_RIGHT_TRIGGER,
  632. ctx->right_trigger_zero,
  633. data[62]
  634. );
  635. MapJoystickAxis(
  636. timestamp,
  637. joystick,
  638. SDL_GAMEPAD_AXIS_LEFTX,
  639. &ctx->left_stick.x,
  640. (float) (data[11] | ((data[12] & 0x0F) << 8)),
  641. false
  642. );
  643. MapJoystickAxis(
  644. timestamp,
  645. joystick,
  646. SDL_GAMEPAD_AXIS_LEFTY,
  647. &ctx->left_stick.y,
  648. (float) ((data[12] >> 4) | (data[13] << 4)),
  649. true
  650. );
  651. MapJoystickAxis(
  652. timestamp,
  653. joystick,
  654. SDL_GAMEPAD_AXIS_RIGHTX,
  655. &ctx->right_stick.x,
  656. (float) (data[14] | ((data[15] & 0x0F) << 8)),
  657. false
  658. );
  659. MapJoystickAxis(
  660. timestamp,
  661. joystick,
  662. SDL_GAMEPAD_AXIS_RIGHTY,
  663. &ctx->right_stick.y,
  664. (float)((data[15] >> 4) | (data[16] << 4)),
  665. true
  666. );
  667. }
  668. static void HandleCombinedControllerStateL(Uint64 timestamp, SDL_Joystick *joystick, SDL_DriverSwitch2_Context *ctx, Uint8 *data, int size)
  669. {
  670. if (data[6] != ctx->last_state[6]) {
  671. SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_BACK, ((data[6] & 0x01) != 0));
  672. SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_LEFT_STICK, ((data[6] & 0x08) != 0));
  673. SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_SWITCH2_JOYCON_SHARE, ((data[6] & 0x20) != 0));
  674. }
  675. if (data[7] != ctx->last_state[7]) {
  676. Uint8 hat = 0;
  677. if (data[7] & 0x01) {
  678. hat |= SDL_HAT_DOWN;
  679. }
  680. if (data[7] & 0x02) {
  681. hat |= SDL_HAT_UP;
  682. }
  683. if (data[7] & 0x04) {
  684. hat |= SDL_HAT_RIGHT;
  685. }
  686. if (data[7] & 0x08) {
  687. hat |= SDL_HAT_LEFT;
  688. }
  689. SDL_SendJoystickHat(timestamp, joystick, 0, hat);
  690. SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_LEFT_SHOULDER, ((data[7] & 0x40) != 0));
  691. }
  692. if (data[8] != ctx->last_state[8]) {
  693. SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_SWITCH2_JOYCON_LEFT_PADDLE1, ((data[8] & 0x02) != 0));
  694. }
  695. Sint16 axis = (data[7] & 0x80) ? 32767 : -32768;
  696. SDL_SendJoystickAxis(timestamp, joystick, SDL_GAMEPAD_AXIS_LEFT_TRIGGER, axis);
  697. MapJoystickAxis(
  698. timestamp,
  699. joystick,
  700. SDL_GAMEPAD_AXIS_LEFTX,
  701. &ctx->left_stick.x,
  702. (float) (data[11] | ((data[12] & 0x0F) << 8)),
  703. false
  704. );
  705. MapJoystickAxis(
  706. timestamp,
  707. joystick,
  708. SDL_GAMEPAD_AXIS_LEFTY,
  709. &ctx->left_stick.y,
  710. (float) ((data[12] >> 4) | (data[13] << 4)),
  711. true
  712. );
  713. }
  714. static void HandleMiniControllerStateL(Uint64 timestamp, SDL_Joystick *joystick, SDL_DriverSwitch2_Context *ctx, Uint8 *data, int size)
  715. {
  716. if (data[6] != ctx->last_state[6]) {
  717. SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_START, ((data[6] & 0x01) != 0));
  718. SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_LEFT_STICK, ((data[6] & 0x08) != 0));
  719. SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_GUIDE, ((data[6] & 0x20) != 0));
  720. SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_SWITCH2_JOYCON_SHARE, ((data[6] & 0x10) != 0));
  721. }
  722. if (data[7] != ctx->last_state[7]) {
  723. SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_WEST, ((data[7] & 0x01) != 0));
  724. SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_NORTH, ((data[7] & 0x02) != 0));
  725. SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_SOUTH, ((data[7] & 0x04) != 0));
  726. SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_EAST, ((data[7] & 0x08) != 0));
  727. SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER, ((data[7] & 0x10) != 0));
  728. SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_LEFT_SHOULDER, ((data[7] & 0x20) != 0));
  729. SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_SWITCH2_JOYCON_LEFT_PADDLE1, ((data[7] & 0x40) != 0));
  730. SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_SWITCH2_JOYCON_LEFT_PADDLE2, ((data[7] & 0x80) != 0));
  731. }
  732. MapJoystickAxis(
  733. timestamp,
  734. joystick,
  735. SDL_GAMEPAD_AXIS_LEFTX,
  736. &ctx->left_stick.y,
  737. (float) ((data[12] >> 4) | (data[13] << 4)),
  738. true
  739. );
  740. MapJoystickAxis(
  741. timestamp,
  742. joystick,
  743. SDL_GAMEPAD_AXIS_LEFTY,
  744. &ctx->left_stick.x,
  745. (float) (data[11] | ((data[12] & 0x0F) << 8)),
  746. true
  747. );
  748. }
  749. static void HandleCombinedControllerStateR(Uint64 timestamp, SDL_Joystick *joystick, SDL_DriverSwitch2_Context *ctx, Uint8 *data, int size)
  750. {
  751. if (data[5] != ctx->last_state[5]) {
  752. SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_WEST, ((data[5] & 0x01) != 0));
  753. SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_NORTH, ((data[5] & 0x02) != 0));
  754. SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_SOUTH, ((data[5] & 0x04) != 0));
  755. SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_EAST, ((data[5] & 0x08) != 0));
  756. SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER, ((data[5] & 0x40) != 0));
  757. }
  758. if (data[6] != ctx->last_state[6]) {
  759. SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_START, ((data[6] & 0x02) != 0));
  760. SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_RIGHT_STICK, ((data[6] & 0x04) != 0));
  761. SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_GUIDE, ((data[6] & 0x10) != 0));
  762. SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_SWITCH2_JOYCON_C, ((data[6] & 0x40) != 0));
  763. }
  764. if (data[8] != ctx->last_state[8]) {
  765. SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_SWITCH2_JOYCON_RIGHT_PADDLE1, ((data[8] & 0x01) != 0));
  766. }
  767. Sint16 axis = (data[5] & 0x80) ? 32767 : -32768;
  768. SDL_SendJoystickAxis(timestamp, joystick, SDL_GAMEPAD_AXIS_RIGHT_TRIGGER, axis);
  769. MapJoystickAxis(
  770. timestamp,
  771. joystick,
  772. SDL_GAMEPAD_AXIS_RIGHTX,
  773. &ctx->left_stick.x,
  774. (float) (data[14] | ((data[15] & 0x0F) << 8)),
  775. false
  776. );
  777. MapJoystickAxis(
  778. timestamp,
  779. joystick,
  780. SDL_GAMEPAD_AXIS_RIGHTY,
  781. &ctx->left_stick.y,
  782. (float)((data[15] >> 4) | (data[16] << 4)),
  783. true
  784. );
  785. }
  786. static void HandleMiniControllerStateR(Uint64 timestamp, SDL_Joystick *joystick, SDL_DriverSwitch2_Context *ctx, Uint8 *data, int size)
  787. {
  788. if (data[5] != ctx->last_state[5]) {
  789. SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_WEST, ((data[5] & 0x01) != 0));
  790. SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_NORTH, ((data[5] & 0x02) != 0));
  791. SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_SOUTH, ((data[5] & 0x04) != 0));
  792. SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_EAST, ((data[5] & 0x08) != 0));
  793. SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER, ((data[5] & 0x10) != 0));
  794. SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_LEFT_SHOULDER, ((data[5] & 0x20) != 0));
  795. SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_SWITCH2_JOYCON_RIGHT_PADDLE1, ((data[5] & 0x40) != 0));
  796. SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_SWITCH2_JOYCON_RIGHT_PADDLE2, ((data[5] & 0x80) != 0));
  797. }
  798. if (data[6] != ctx->last_state[6]) {
  799. SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_START, ((data[6] & 0x02) != 0));
  800. SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_LEFT_STICK, ((data[6] & 0x04) != 0));
  801. SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_GUIDE, ((data[6] & 0x10) != 0));
  802. SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_SWITCH2_JOYCON_C, ((data[6] & 0x40) != 0));
  803. }
  804. MapJoystickAxis(
  805. timestamp,
  806. joystick,
  807. SDL_GAMEPAD_AXIS_LEFTX,
  808. &ctx->left_stick.y,
  809. (float)((data[15] >> 4) | (data[16] << 4)),
  810. false
  811. );
  812. MapJoystickAxis(
  813. timestamp,
  814. joystick,
  815. SDL_GAMEPAD_AXIS_LEFTY,
  816. &ctx->left_stick.x,
  817. (float) (data[14] | ((data[15] & 0x0F) << 8)),
  818. false
  819. );
  820. }
  821. static void HandleSwitchProState(Uint64 timestamp, SDL_Joystick *joystick, SDL_DriverSwitch2_Context *ctx, Uint8 *data, int size)
  822. {
  823. Sint16 axis;
  824. if (data[5] != ctx->last_state[5]) {
  825. SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_WEST, ((data[5] & 0x01) != 0));
  826. SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_NORTH, ((data[5] & 0x02) != 0));
  827. SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_SOUTH, ((data[5] & 0x04) != 0));
  828. SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_EAST, ((data[5] & 0x08) != 0));
  829. SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER, ((data[5] & 0x40) != 0));
  830. }
  831. if (data[6] != ctx->last_state[6]) {
  832. SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_BACK, ((data[6] & 0x01) != 0));
  833. SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_START, ((data[6] & 0x02) != 0));
  834. SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_RIGHT_STICK, ((data[6] & 0x04) != 0));
  835. SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_LEFT_STICK, ((data[6] & 0x08) != 0));
  836. SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_GUIDE, ((data[6] & 0x10) != 0));
  837. SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_SWITCH2_PRO_SHARE, ((data[6] & 0x20) != 0));
  838. SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_SWITCH2_PRO_C, ((data[6] & 0x40) != 0));
  839. }
  840. if (data[7] != ctx->last_state[7]) {
  841. Uint8 hat = 0;
  842. if (data[7] & 0x01) {
  843. hat |= SDL_HAT_DOWN;
  844. }
  845. if (data[7] & 0x02) {
  846. hat |= SDL_HAT_UP;
  847. }
  848. if (data[7] & 0x04) {
  849. hat |= SDL_HAT_RIGHT;
  850. }
  851. if (data[7] & 0x08) {
  852. hat |= SDL_HAT_LEFT;
  853. }
  854. SDL_SendJoystickHat(timestamp, joystick, 0, hat);
  855. SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_LEFT_SHOULDER, ((data[7] & 0x40) != 0));
  856. }
  857. if (data[8] != ctx->last_state[8]) {
  858. SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_SWITCH2_PRO_RIGHT_PADDLE, ((data[8] & 0x01) != 0));
  859. SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_SWITCH2_PRO_LEFT_PADDLE, ((data[8] & 0x02) != 0));
  860. }
  861. axis = (data[5] & 0x80) ? 32767 : -32768;
  862. SDL_SendJoystickAxis(timestamp, joystick, SDL_GAMEPAD_AXIS_RIGHT_TRIGGER, axis);
  863. axis = (data[7] & 0x80) ? 32767 : -32768;
  864. SDL_SendJoystickAxis(timestamp, joystick, SDL_GAMEPAD_AXIS_LEFT_TRIGGER, axis);
  865. MapJoystickAxis(
  866. timestamp,
  867. joystick,
  868. SDL_GAMEPAD_AXIS_LEFTX,
  869. &ctx->left_stick.x,
  870. (float) (data[11] | ((data[12] & 0x0F) << 8)),
  871. false
  872. );
  873. MapJoystickAxis(
  874. timestamp,
  875. joystick,
  876. SDL_GAMEPAD_AXIS_LEFTY,
  877. &ctx->left_stick.y,
  878. (float) ((data[12] >> 4) | (data[13] << 4)),
  879. true
  880. );
  881. MapJoystickAxis(
  882. timestamp,
  883. joystick,
  884. SDL_GAMEPAD_AXIS_RIGHTX,
  885. &ctx->right_stick.x,
  886. (float) (data[14] | ((data[15] & 0x0F) << 8)),
  887. false
  888. );
  889. MapJoystickAxis(
  890. timestamp,
  891. joystick,
  892. SDL_GAMEPAD_AXIS_RIGHTY,
  893. &ctx->right_stick.y,
  894. (float)((data[15] >> 4) | (data[16] << 4)),
  895. true
  896. );
  897. }
  898. static void EncodeHDRumble(Uint16 high_freq, Uint16 high_amp, Uint16 low_freq, Uint16 low_amp, Uint8 rumble_data[5])
  899. {
  900. rumble_data[0] = (Uint8)(high_freq & 0xFF);
  901. rumble_data[1] = (Uint8)(((high_amp >> 4) & 0xfc) | ((high_freq >> 8) & 0x03));
  902. rumble_data[2] = (Uint8)((high_amp >> 12) | (low_freq << 4));
  903. rumble_data[3] = (Uint8)((low_amp & 0xc0) | ((low_freq >> 4) & 0x3f));
  904. rumble_data[4] = (Uint8)(low_amp >> 8);
  905. }
  906. static bool UpdateRumble(SDL_DriverSwitch2_Context *ctx)
  907. {
  908. if (!ctx->rumble_updated && !ctx->rumble_lo_amp && !ctx->rumble_hi_amp) {
  909. return true;
  910. }
  911. Uint64 timestamp = SDL_GetTicks();
  912. Uint64 interval = RUMBLE_INTERVAL;
  913. if (timestamp < ctx->rumble_timestamp) {
  914. return true;
  915. }
  916. if (!SDL_HIDAPI_LockRumble()) {
  917. return false;
  918. }
  919. unsigned char rumble_data[64] = {0};
  920. if (ctx->device->product_id == USB_PRODUCT_NINTENDO_SWITCH2_GAMECUBE_CONTROLLER) {
  921. Uint16 rumble_max = SDL_max(ctx->rumble_lo_amp, ctx->rumble_hi_amp);
  922. rumble_data[0x00] = 0x3;
  923. rumble_data[1] = 0x50 | (ctx->rumble_seq & 0xf);
  924. if (rumble_max == 0) {
  925. rumble_data[2] = 2;
  926. ctx->rumble_error = 0;
  927. } else {
  928. if (ctx->rumble_error < rumble_max) {
  929. rumble_data[2] = 1;
  930. ctx->rumble_error += UINT16_MAX - rumble_max;
  931. } else {
  932. rumble_data[2] = 0;
  933. ctx->rumble_error -= rumble_max;
  934. }
  935. }
  936. } else {
  937. // Rumble can get so strong that it might be dangerous to the controller...
  938. // This is a game controller, not a massage device, so let's clamp it somewhat
  939. Uint16 low_amp = (Uint16)((int)ctx->rumble_lo_amp * RUMBLE_MAX / UINT16_MAX);
  940. Uint16 high_amp = (Uint16)((int)ctx->rumble_hi_amp * RUMBLE_MAX / UINT16_MAX);
  941. rumble_data[0x01] = 0x50 | (ctx->rumble_seq & 0xf);
  942. EncodeHDRumble(ctx->rumble_hi_freq, high_amp, ctx->rumble_lo_freq, low_amp, &rumble_data[0x02]);
  943. switch (ctx->device->product_id) {
  944. case USB_PRODUCT_NINTENDO_SWITCH2_JOYCON_LEFT:
  945. case USB_PRODUCT_NINTENDO_SWITCH2_JOYCON_RIGHT:
  946. if (ctx->device->parent) {
  947. // FIXME: This shouldn't be necessary, but the rumble thread appears to back up if we don't do this
  948. interval *= 2;
  949. }
  950. rumble_data[0] = 0x1;
  951. break;
  952. case USB_PRODUCT_NINTENDO_SWITCH2_PRO:
  953. rumble_data[0] = 0x2;
  954. SDL_memcpy(&rumble_data[0x11], &rumble_data[0x01], 6);
  955. break;
  956. }
  957. }
  958. ctx->rumble_seq++;
  959. ctx->rumble_updated = false;
  960. if (!ctx->rumble_lo_amp && !ctx->rumble_hi_amp) {
  961. ctx->rumble_timestamp = 0;
  962. } else {
  963. if (!ctx->rumble_timestamp) {
  964. ctx->rumble_timestamp = timestamp;
  965. }
  966. ctx->rumble_timestamp += interval;
  967. }
  968. if (SDL_HIDAPI_SendRumbleAndUnlock(ctx->device, rumble_data, sizeof(rumble_data)) != sizeof(rumble_data)) {
  969. return SDL_SetError("Couldn't send rumble packet");
  970. }
  971. return true;
  972. }
  973. static void HIDAPI_DriverSwitch2_HandleStatePacket(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, SDL_DriverSwitch2_Context *ctx, Uint8 *data, int size)
  974. {
  975. Uint64 timestamp = SDL_GetTicksNS();
  976. if (size < 64) {
  977. // We don't know how to handle this report
  978. return;
  979. }
  980. switch (device->product_id) {
  981. case USB_PRODUCT_NINTENDO_SWITCH2_GAMECUBE_CONTROLLER:
  982. HandleGameCubeState(timestamp, joystick, ctx, data, size);
  983. break;
  984. case USB_PRODUCT_NINTENDO_SWITCH2_JOYCON_LEFT:
  985. if (device->parent || ctx->vertical_mode) {
  986. HandleCombinedControllerStateL(timestamp, joystick, ctx, data, size);
  987. } else {
  988. HandleMiniControllerStateL(timestamp, joystick, ctx, data, size);
  989. }
  990. break;
  991. case USB_PRODUCT_NINTENDO_SWITCH2_JOYCON_RIGHT:
  992. if (device->parent || ctx->vertical_mode) {
  993. HandleCombinedControllerStateR(timestamp, joystick, ctx, data, size);
  994. } else {
  995. HandleMiniControllerStateR(timestamp, joystick, ctx, data, size);
  996. }
  997. break;
  998. case USB_PRODUCT_NINTENDO_SWITCH2_PRO:
  999. HandleSwitchProState(timestamp, joystick, ctx, data, size);
  1000. break;
  1001. default:
  1002. // FIXME: Need state handling implementation
  1003. break;
  1004. }
  1005. Uint64 sensor_timestamp = (Uint32) (data[0x2b] | (data[0x2c] << 8U) | (data[0x2d] << 16U) | (data[0x2e] << 24U));
  1006. if (sensor_timestamp && !ctx->sensors_ready) {
  1007. ctx->sample_count++;
  1008. if (ctx->sample_count >= 5 && !ctx->first_sensor_timestamp) {
  1009. ctx->first_sensor_timestamp = sensor_timestamp;
  1010. ctx->sample_count = 0;
  1011. } else if (ctx->sample_count == 100) {
  1012. // Calculate timestamp coefficient
  1013. // Timestamp are normally microseconds but sometimes it's something else for no apparent reason
  1014. Uint64 coeff = 1000 * (sensor_timestamp - ctx->first_sensor_timestamp) / (ctx->sample_count * 4);
  1015. if ((coeff + 100000) / 200000 == 5) {
  1016. // Within 10% of 1000
  1017. ctx->sensor_ts_coeff = 10000;
  1018. ctx->gyro_coeff = 34.8f;
  1019. ctx->sensors_ready = true;
  1020. } else if (coeff != 0) {
  1021. ctx->sensor_ts_coeff = 10000000000 / coeff;
  1022. ctx->gyro_coeff = 40.0f;
  1023. ctx->sensors_ready = true;
  1024. } else {
  1025. // Didn't get a valid reading, try again
  1026. ctx->first_sensor_timestamp = 0;
  1027. ctx->sample_count = 0;
  1028. }
  1029. if (ctx->sensors_ready && !ctx->sensors_enabled) {
  1030. Uint8 set_features[] = {
  1031. 0x0c, 0x91, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00
  1032. };
  1033. unsigned char reply[12] = {0};
  1034. SendBulkData(ctx, set_features, sizeof(set_features));
  1035. RecvBulkData(ctx, reply, sizeof(reply));
  1036. }
  1037. }
  1038. }
  1039. if (ctx->sensors_enabled && sensor_timestamp && ctx->sensors_ready) {
  1040. sensor_timestamp = sensor_timestamp * ctx->sensor_ts_coeff / 10;
  1041. float accel_data[3];
  1042. float gyro_data[3];
  1043. const float g = 9.80665f;
  1044. const float accel_scale = g * 8.f / INT16_MAX;
  1045. accel_data[0] = (Sint16)(data[0x31] | (data[0x32] << 8)) * accel_scale;
  1046. accel_data[1] = (Sint16)(data[0x35] | (data[0x36] << 8)) * accel_scale;
  1047. accel_data[2] = (Sint16)(data[0x33] | (data[0x34] << 8)) * -accel_scale;
  1048. gyro_data[0] = (Sint16)(data[0x37] | (data[0x38] << 8)) * ctx->gyro_coeff / INT16_MAX - ctx->gyro_bias_x;
  1049. gyro_data[1] = (Sint16)(data[0x3b] | (data[0x3c] << 8)) * ctx->gyro_coeff / INT16_MAX - ctx->gyro_bias_z;
  1050. gyro_data[2] = (Sint16)(data[0x39] | (data[0x3a] << 8)) * -ctx->gyro_coeff / INT16_MAX + ctx->gyro_bias_y;
  1051. switch (ctx->device->product_id) {
  1052. case USB_PRODUCT_NINTENDO_SWITCH2_JOYCON_LEFT:
  1053. if (ctx->device->parent) {
  1054. SDL_SendJoystickSensor(timestamp, joystick, SDL_SENSOR_GYRO_L, sensor_timestamp, gyro_data, 3);
  1055. SDL_SendJoystickSensor(timestamp, joystick, SDL_SENSOR_ACCEL_L, sensor_timestamp, accel_data, 3);
  1056. } else {
  1057. float tmp = -accel_data[0];
  1058. accel_data[0] = accel_data[2];
  1059. accel_data[2] = tmp;
  1060. tmp = -gyro_data[0];
  1061. gyro_data[0] = gyro_data[2];
  1062. gyro_data[2] = tmp;
  1063. SDL_SendJoystickSensor(timestamp, joystick, SDL_SENSOR_GYRO, sensor_timestamp, gyro_data, 3);
  1064. SDL_SendJoystickSensor(timestamp, joystick, SDL_SENSOR_ACCEL, sensor_timestamp, accel_data, 3);
  1065. }
  1066. break;
  1067. case USB_PRODUCT_NINTENDO_SWITCH2_JOYCON_RIGHT:
  1068. if (ctx->device->parent) {
  1069. SDL_SendJoystickSensor(timestamp, joystick, SDL_SENSOR_GYRO, sensor_timestamp, gyro_data, 3);
  1070. SDL_SendJoystickSensor(timestamp, joystick, SDL_SENSOR_ACCEL, sensor_timestamp, accel_data, 3);
  1071. SDL_SendJoystickSensor(timestamp, joystick, SDL_SENSOR_GYRO_R, sensor_timestamp, gyro_data, 3);
  1072. SDL_SendJoystickSensor(timestamp, joystick, SDL_SENSOR_ACCEL_R, sensor_timestamp, accel_data, 3);
  1073. } else {
  1074. float tmp = accel_data[0];
  1075. accel_data[0] = -accel_data[2];
  1076. accel_data[2] = tmp;
  1077. tmp = gyro_data[0];
  1078. gyro_data[0] = -gyro_data[2];
  1079. gyro_data[2] = tmp;
  1080. SDL_SendJoystickSensor(timestamp, joystick, SDL_SENSOR_GYRO, sensor_timestamp, gyro_data, 3);
  1081. SDL_SendJoystickSensor(timestamp, joystick, SDL_SENSOR_ACCEL, sensor_timestamp, accel_data, 3);
  1082. }
  1083. break;
  1084. default:
  1085. SDL_SendJoystickSensor(timestamp, joystick, SDL_SENSOR_GYRO, sensor_timestamp, gyro_data, 3);
  1086. SDL_SendJoystickSensor(timestamp, joystick, SDL_SENSOR_ACCEL, sensor_timestamp, accel_data, 3);
  1087. break;
  1088. }
  1089. }
  1090. SDL_memcpy(ctx->last_state, data, SDL_min(size, sizeof(ctx->last_state)));
  1091. }
  1092. static bool HIDAPI_DriverSwitch2_UpdateDevice(SDL_HIDAPI_Device *device)
  1093. {
  1094. SDL_DriverSwitch2_Context *ctx = (SDL_DriverSwitch2_Context *)device->context;
  1095. SDL_Joystick *joystick = NULL;
  1096. Uint8 data[USB_PACKET_LENGTH];
  1097. int size = 0;
  1098. if (device->num_joysticks > 0) {
  1099. joystick = SDL_GetJoystickFromID(device->joysticks[0]);
  1100. } else {
  1101. return false;
  1102. }
  1103. while ((size = SDL_hid_read_timeout(device->dev, data, sizeof(data), 0)) > 0) {
  1104. #ifdef DEBUG_SWITCH2_PROTOCOL
  1105. if (device->product_id == USB_PRODUCT_NINTENDO_SWITCH2_JOYCON_LEFT) {
  1106. HIDAPI_DumpPacket("Nintendo Joy-Con(L) packet: size = %d", data, size);
  1107. } else if (device->product_id == USB_PRODUCT_NINTENDO_SWITCH2_JOYCON_RIGHT) {
  1108. HIDAPI_DumpPacket("Nintendo Joy-Con(R) packet: size = %d", data, size);
  1109. } else {
  1110. HIDAPI_DumpPacket("Nintendo Switch2 packet: size = %d", data, size);
  1111. }
  1112. #endif
  1113. if (!joystick) {
  1114. continue;
  1115. }
  1116. HIDAPI_DriverSwitch2_HandleStatePacket(device, joystick, ctx, data, size);
  1117. UpdateRumble(ctx);
  1118. }
  1119. if (size < 0) {
  1120. // Read error, device is disconnected
  1121. HIDAPI_JoystickDisconnected(device, device->joysticks[0]);
  1122. }
  1123. return (size >= 0);
  1124. }
  1125. static void HIDAPI_DriverSwitch2_CloseJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
  1126. {
  1127. SDL_DriverSwitch2_Context *ctx = (SDL_DriverSwitch2_Context *)device->context;
  1128. SDL_RemoveHintCallback(SDL_HINT_JOYSTICK_HIDAPI_SWITCH_PLAYER_LED,
  1129. SDL_PlayerLEDHintChanged, ctx);
  1130. ctx->joystick = NULL;
  1131. }
  1132. static void HIDAPI_DriverSwitch2_FreeDevice(SDL_HIDAPI_Device *device)
  1133. {
  1134. SDL_DriverSwitch2_Context *ctx = (SDL_DriverSwitch2_Context *)device->context;
  1135. if (ctx) {
  1136. if (ctx->interface_claimed) {
  1137. ctx->libusb->release_interface(ctx->device_handle, ctx->interface_number);
  1138. ctx->interface_claimed = false;
  1139. }
  1140. if (ctx->libusb) {
  1141. SDL_QuitLibUSB();
  1142. ctx->libusb = NULL;
  1143. }
  1144. }
  1145. }
  1146. SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverSwitch2 = {
  1147. SDL_HINT_JOYSTICK_HIDAPI_SWITCH2,
  1148. true,
  1149. HIDAPI_DriverSwitch2_RegisterHints,
  1150. HIDAPI_DriverSwitch2_UnregisterHints,
  1151. HIDAPI_DriverSwitch2_IsEnabled,
  1152. HIDAPI_DriverSwitch2_IsSupportedDevice,
  1153. HIDAPI_DriverSwitch2_InitDevice,
  1154. HIDAPI_DriverSwitch2_GetDevicePlayerIndex,
  1155. HIDAPI_DriverSwitch2_SetDevicePlayerIndex,
  1156. HIDAPI_DriverSwitch2_UpdateDevice,
  1157. HIDAPI_DriverSwitch2_OpenJoystick,
  1158. HIDAPI_DriverSwitch2_RumbleJoystick,
  1159. HIDAPI_DriverSwitch2_RumbleJoystickTriggers,
  1160. HIDAPI_DriverSwitch2_GetJoystickCapabilities,
  1161. HIDAPI_DriverSwitch2_SetJoystickLED,
  1162. HIDAPI_DriverSwitch2_SendJoystickEffect,
  1163. HIDAPI_DriverSwitch2_SetJoystickSensorsEnabled,
  1164. HIDAPI_DriverSwitch2_CloseJoystick,
  1165. HIDAPI_DriverSwitch2_FreeDevice,
  1166. };
  1167. #endif // SDL_JOYSTICK_HIDAPI_SWITCH2
  1168. #endif // SDL_JOYSTICK_HIDAPI