@@ -85,6 +85,9 @@ typedef struct
85
85
86
86
typedef struct
87
87
{
88
+ SDL_HIDAPI_Device * device ;
89
+ SDL_Joystick * joystick ;
90
+
88
91
SDL_LibUSBContext * libusb ;
89
92
libusb_device_handle * device_handle ;
90
93
bool interface_claimed ;
@@ -97,6 +100,9 @@ typedef struct
97
100
Uint8 left_trigger_max ;
98
101
Uint8 right_trigger_max ;
99
102
103
+ bool player_lights ;
104
+ int player_index ;
105
+
100
106
bool vertical_mode ;
101
107
Uint8 last_state [USB_PACKET_LENGTH ];
102
108
} SDL_DriverSwitch2_Context ;
@@ -198,6 +204,37 @@ static void MapTriggerAxis(Uint64 timestamp, SDL_Joystick *joystick, Uint8 axis,
198
204
SDL_SendJoystickAxis (timestamp , joystick , axis , mapped_value );
199
205
}
200
206
207
+ static bool UpdateSlotLED (SDL_DriverSwitch2_Context * ctx )
208
+ {
209
+ unsigned char SET_LED_DATA [] = {
210
+ 0x09 , 0x91 , 0x00 , 0x07 , 0x00 , 0x08 , 0x00 , 0x00 ,
211
+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
212
+ };
213
+ unsigned char calibration_data [0x50 ] = {0 };
214
+
215
+ if (ctx -> player_lights && ctx -> player_index >= 0 ) {
216
+ SET_LED_DATA [8 ] = (1 << (ctx -> player_index % 4 ));
217
+ }
218
+ int res = SendBulkData (ctx , SET_LED_DATA , sizeof (SET_LED_DATA ));
219
+ if (res < 0 ) {
220
+ return SDL_SetError ("Couldn't set LED data: %d\n" , res );
221
+ }
222
+ return (RecvBulkData (ctx , calibration_data , 0x40 ) > 0 );
223
+ }
224
+
225
+ static void SDLCALL SDL_PlayerLEDHintChanged (void * userdata , const char * name , const char * oldValue , const char * hint )
226
+ {
227
+ SDL_DriverSwitch2_Context * ctx = (SDL_DriverSwitch2_Context * )userdata ;
228
+ bool player_lights = SDL_GetStringBoolean (hint , true);
229
+
230
+ if (player_lights != ctx -> player_lights ) {
231
+ ctx -> player_lights = player_lights ;
232
+
233
+ UpdateSlotLED (ctx );
234
+ HIDAPI_UpdateDeviceProperties (ctx -> device );
235
+ }
236
+ }
237
+
201
238
static void HIDAPI_DriverSwitch2_RegisterHints (SDL_HintCallback callback , void * userdata )
202
239
{
203
240
SDL_AddHintCallback (SDL_HINT_JOYSTICK_HIDAPI_SWITCH2 , callback , userdata );
@@ -300,10 +337,6 @@ static bool HIDAPI_DriverSwitch2_InitUSB(SDL_HIDAPI_Device *device)
300
337
0x03 , 0x91 , 0x00 , 0x0d , 0x00 , 0x08 , 0x00 , 0x00 ,
301
338
0x01 , 0x00 , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF
302
339
};
303
- const unsigned char SET_LED_DATA [] = {
304
- 0x09 , 0x91 , 0x00 , 0x07 , 0x00 , 0x08 , 0x00 , 0x00 ,
305
- 0x01 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
306
- };
307
340
unsigned char flash_read_command [] = {
308
341
0x02 , 0x91 , 0x00 , 0x01 , 0x00 , 0x08 , 0x00 , 0x00 ,
309
342
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x30 , 0x01 , 0x00
@@ -316,12 +349,6 @@ static bool HIDAPI_DriverSwitch2_InitUSB(SDL_HIDAPI_Device *device)
316
349
}
317
350
RecvBulkData (ctx , calibration_data , 0x40 );
318
351
319
- res = SendBulkData (ctx , SET_LED_DATA , sizeof (SET_LED_DATA ));
320
- if (res < 0 ) {
321
- return SDL_SetError ("Couldn't set LED data: %d\n" , res );
322
- }
323
- RecvBulkData (ctx , calibration_data , 0x40 );
324
-
325
352
flash_read_command [12 ] = 0x80 ;
326
353
res = SendBulkData (ctx , flash_read_command , sizeof (flash_read_command ));
327
354
if (res < 0 ) {
@@ -377,6 +404,7 @@ static bool HIDAPI_DriverSwitch2_InitDevice(SDL_HIDAPI_Device *device)
377
404
if (!ctx ) {
378
405
return false;
379
406
}
407
+ ctx -> device = device ;
380
408
device -> context = ctx ;
381
409
382
410
if (device -> is_bluetooth ) {
@@ -410,12 +438,31 @@ static int HIDAPI_DriverSwitch2_GetDevicePlayerIndex(SDL_HIDAPI_Device *device,
410
438
411
439
static void HIDAPI_DriverSwitch2_SetDevicePlayerIndex (SDL_HIDAPI_Device * device , SDL_JoystickID instance_id , int player_index )
412
440
{
441
+ SDL_DriverSwitch2_Context * ctx = (SDL_DriverSwitch2_Context * )device -> context ;
442
+
443
+ if (!ctx -> joystick ) {
444
+ return ;
445
+ }
446
+
447
+ ctx -> player_index = player_index ;
448
+
449
+ UpdateSlotLED (ctx );
413
450
}
414
451
415
452
static bool HIDAPI_DriverSwitch2_OpenJoystick (SDL_HIDAPI_Device * device , SDL_Joystick * joystick )
416
453
{
417
454
SDL_DriverSwitch2_Context * ctx = (SDL_DriverSwitch2_Context * )device -> context ;
418
455
456
+ ctx -> joystick = joystick ;
457
+
458
+ // Initialize player index (needed for setting LEDs)
459
+ ctx -> player_index = SDL_GetJoystickPlayerIndex (joystick );
460
+ ctx -> player_lights = SDL_GetHintBoolean (SDL_HINT_JOYSTICK_HIDAPI_SWITCH_PLAYER_LED , true);
461
+ UpdateSlotLED (ctx );
462
+
463
+ SDL_AddHintCallback (SDL_HINT_JOYSTICK_HIDAPI_SWITCH_PLAYER_LED ,
464
+ SDL_PlayerLEDHintChanged , ctx );
465
+
419
466
// Initialize the joystick capabilities
420
467
switch (device -> product_id ) {
421
468
case USB_PRODUCT_NINTENDO_SWITCH2_GAMECUBE_CONTROLLER :
@@ -453,7 +500,13 @@ static bool HIDAPI_DriverSwitch2_RumbleJoystickTriggers(SDL_HIDAPI_Device *devic
453
500
454
501
static Uint32 HIDAPI_DriverSwitch2_GetJoystickCapabilities (SDL_HIDAPI_Device * device , SDL_Joystick * joystick )
455
502
{
456
- return 0 ;
503
+ SDL_DriverSwitch2_Context * ctx = (SDL_DriverSwitch2_Context * )device -> context ;
504
+ Uint32 result = 0 ;
505
+
506
+ if (ctx -> player_lights ) {
507
+ result |= SDL_JOYSTICK_CAP_PLAYER_LED ;
508
+ }
509
+ return result ;
457
510
}
458
511
459
512
static bool HIDAPI_DriverSwitch2_SetJoystickLED (SDL_HIDAPI_Device * device , SDL_Joystick * joystick , Uint8 red , Uint8 green , Uint8 blue )
@@ -886,6 +939,12 @@ static bool HIDAPI_DriverSwitch2_UpdateDevice(SDL_HIDAPI_Device *device)
886
939
887
940
static void HIDAPI_DriverSwitch2_CloseJoystick (SDL_HIDAPI_Device * device , SDL_Joystick * joystick )
888
941
{
942
+ SDL_DriverSwitch2_Context * ctx = (SDL_DriverSwitch2_Context * )device -> context ;
943
+
944
+ SDL_RemoveHintCallback (SDL_HINT_JOYSTICK_HIDAPI_SWITCH_PLAYER_LED ,
945
+ SDL_PlayerLEDHintChanged , ctx );
946
+
947
+ ctx -> joystick = NULL ;
889
948
}
890
949
891
950
static void HIDAPI_DriverSwitch2_FreeDevice (SDL_HIDAPI_Device * device )
0 commit comments