SDL: Allow floating point values for SDL_HINT_JOYSTICK_HIDAPI_SWITCH_HOME_LED

From a423848ea05b40bac1054f076f6c1577d13723aa Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Mon, 25 Jul 2022 11:26:18 -0700
Subject: [PATCH] Allow floating point values for
 SDL_HINT_JOYSTICK_HIDAPI_SWITCH_HOME_LED

This allows setting the brightness of the home LED on Nintendo Switch Pro controllers, in the range 0.0 - 1.0.

This can be updated at runtime by setting the hint dynamically.

Fixes https://github.com/libsdl-org/SDL/issues/3787
---
 src/joystick/hidapi/SDL_hidapi_switch.c | 31 ++++++++++++++++++-------
 1 file changed, 23 insertions(+), 8 deletions(-)

diff --git a/src/joystick/hidapi/SDL_hidapi_switch.c b/src/joystick/hidapi/SDL_hidapi_switch.c
index 3fbd91e0266..061f3b3c9a4 100644
--- a/src/joystick/hidapi/SDL_hidapi_switch.c
+++ b/src/joystick/hidapi/SDL_hidapi_switch.c
@@ -745,6 +745,24 @@ static SDL_bool SetHomeLED(SDL_DriverSwitch_Context *ctx, Uint8 brightness)
     return WriteSubcommand(ctx, k_eSwitchSubcommandIDs_SetHomeLight, rgucBuffer, sizeof(rgucBuffer), NULL);
 }
 
+static void SDLCALL SDL_HomeLEDHintChanged(void *userdata, const char *name, const char *oldValue, const char *hint)
+{
+    SDL_DriverSwitch_Context *ctx = (SDL_DriverSwitch_Context *)userdata;
+
+    if (hint && *hint) {
+        int value;
+
+        if (SDL_strchr(hint, '.') != NULL) {
+            value = (int)(100.0f * SDL_atof(hint));
+        } else if (SDL_GetStringBoolean(hint, SDL_TRUE)) {
+            value = 100;
+        } else {
+            value = 0;
+        }
+        SetHomeLED(ctx, value);
+    }
+}
+
 static SDL_bool SetSlotLED(SDL_DriverSwitch_Context *ctx, Uint8 slot)
 {
     Uint8 led_data = (1 << slot);
@@ -1066,14 +1084,8 @@ HIDAPI_DriverSwitch_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joysti
 
         /* Set the LED state */
         if (ctx->m_bHasHomeLED) {
-            const char *hint = SDL_GetHint(SDL_HINT_JOYSTICK_HIDAPI_SWITCH_HOME_LED);
-            if (hint && *hint) {
-                if (SDL_GetStringBoolean(hint, SDL_TRUE)) {
-                    SetHomeLED(ctx, 100);
-                } else {
-                    SetHomeLED(ctx, 0);
-                }
-            }
+            SDL_AddHintCallback(SDL_HINT_JOYSTICK_HIDAPI_SWITCH_HOME_LED,
+                                SDL_HomeLEDHintChanged, ctx);
         }
         SetSlotLED(ctx, (joystick->instance_id % 4));
 
@@ -1654,6 +1666,9 @@ HIDAPI_DriverSwitch_CloseJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joyst
     SDL_DelHintCallback(SDL_HINT_GAMECONTROLLER_USE_BUTTON_LABELS,
                         SDL_GameControllerButtonReportingHintChanged, ctx);
 
+    SDL_DelHintCallback(SDL_HINT_JOYSTICK_HIDAPI_SWITCH_HOME_LED,
+                        SDL_HomeLEDHintChanged, ctx);
+
     SDL_LockMutex(device->dev_lock);
     {
         SDL_hid_close(device->dev);