From 467434b92d0ca8f5a691e36059eb1ac673dfd6b2 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Sat, 7 Mar 2020 13:17:28 -0800 Subject: [PATCH] Added support for indicating player index on DS4 controllers --- src/joystick/hidapi/SDL_hidapi_ps4.c | 50 +++++++++++++++++++++++++--- 1 file changed, 45 insertions(+), 5 deletions(-) diff --git a/src/joystick/hidapi/SDL_hidapi_ps4.c b/src/joystick/hidapi/SDL_hidapi_ps4.c index c2e590ad1988f..8288d1fb1ff7a 100644 --- a/src/joystick/hidapi/SDL_hidapi_ps4.c +++ b/src/joystick/hidapi/SDL_hidapi_ps4.c @@ -100,6 +100,7 @@ typedef struct { SDL_bool is_bluetooth; SDL_bool audio_supported; SDL_bool rumble_supported; + int player_index; Uint8 volume; Uint32 last_volume_check; PS4StatePacket_t last_state; @@ -182,6 +183,33 @@ static SDL_bool HIDAPI_DriverPS4_CanRumble(Uint16 vendor_id, Uint16 product_id) return SDL_TRUE; } +static void +SetLedsForPlayerIndex(DS4EffectsState_t *effects, int player_index) +{ + /* This list is the same as what hid-sony.c uses in the Linux kernel. + The first 4 values correspond to what the PS4 assigns. + */ + static const Uint8 colors[7][3] = { + { 0x00, 0x00, 0x40 }, /* Blue */ + { 0x40, 0x00, 0x00 }, /* Red */ + { 0x00, 0x40, 0x00 }, /* Green */ + { 0x20, 0x00, 0x20 }, /* Pink */ + { 0x02, 0x01, 0x00 }, /* Orange */ + { 0x00, 0x01, 0x01 }, /* Teal */ + { 0x01, 0x01, 0x01 } /* White */ + }; + + if (player_index >= 0) { + player_index %= SDL_arraysize(colors); + } else { + player_index = 0; + } + + effects->ucLedRed = colors[player_index][0]; + effects->ucLedGreen = colors[player_index][1]; + effects->ucLedBlue = colors[player_index][2]; +} + static SDL_bool HIDAPI_DriverPS4_InitDevice(SDL_HIDAPI_Device *device) { @@ -194,12 +222,22 @@ HIDAPI_DriverPS4_GetDevicePlayerIndex(SDL_HIDAPI_Device *device, SDL_JoystickID return -1; } +static int HIDAPI_DriverPS4_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble); + static void HIDAPI_DriverPS4_SetDevicePlayerIndex(SDL_HIDAPI_Device *device, SDL_JoystickID instance_id, int player_index) { -} + SDL_DriverPS4_Context *ctx = (SDL_DriverPS4_Context *)device->context; -static int HIDAPI_DriverPS4_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble); + if (!ctx) { + return; + } + + ctx->player_index = player_index; + + /* This will set the new LED state based on the new player index */ + HIDAPI_DriverPS4_RumbleJoystick(device, SDL_JoystickFromInstanceID(instance_id), 0, 0); +} static SDL_bool HIDAPI_DriverPS4_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) @@ -248,6 +286,9 @@ HIDAPI_DriverPS4_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) } } + /* Initialize player index (needed for setting LEDs) */ + ctx->player_index = SDL_JoystickGetPlayerIndex(joystick); + /* Initialize LED and effect state */ HIDAPI_DriverPS4_RumbleJoystick(device, joystick, 0, 0); @@ -293,9 +334,8 @@ HIDAPI_DriverPS4_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystic effects->ucRumbleLeft = (low_frequency_rumble >> 8); effects->ucRumbleRight = (high_frequency_rumble >> 8); - effects->ucLedRed = 0; - effects->ucLedGreen = 0; - effects->ucLedBlue = 80; + /* Populate the LED state with the appropriate color from our lookup table */ + SetLedsForPlayerIndex(effects, ctx->player_index); if (ctx->is_bluetooth) { /* Bluetooth reports need a CRC at the end of the packet (at least on Linux) */