SDL: Add basic rumble support to Steam Deck

From bec1b8f849b782ca7d815337380c5f2b42ed60ce Mon Sep 17 00:00:00 2001
From: Vicki Pfau <[EMAIL REDACTED]>
Date: Fri, 22 Dec 2023 19:48:41 -0800
Subject: [PATCH] Add basic rumble support to Steam Deck

---
 src/joystick/hidapi/SDL_hidapi_steamdeck.c | 20 +++++++++++++++++---
 1 file changed, 17 insertions(+), 3 deletions(-)

diff --git a/src/joystick/hidapi/SDL_hidapi_steamdeck.c b/src/joystick/hidapi/SDL_hidapi_steamdeck.c
index 7b606b8bf8bb..b387add9afad 100644
--- a/src/joystick/hidapi/SDL_hidapi_steamdeck.c
+++ b/src/joystick/hidapi/SDL_hidapi_steamdeck.c
@@ -363,8 +363,22 @@ static SDL_bool HIDAPI_DriverSteamDeck_OpenJoystick(SDL_HIDAPI_Device *device, S
 
 static int HIDAPI_DriverSteamDeck_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble)
 {
-    /* You should use the full Steam Input API for rumble support */
-    return SDL_Unsupported();
+    int rc;
+    Uint8 buffer[HID_FEATURE_REPORT_BYTES + 1] = { 0 };
+    FeatureReportMsg *msg = (FeatureReportMsg *)(buffer + 1);
+
+    msg->header.type = ID_TRIGGER_RUMBLE_CMD;
+    msg->payload.simpleRumble.unRumbleType = 0;
+    msg->payload.simpleRumble.unIntensity = HAPTIC_INTENSITY_SYSTEM;
+    msg->payload.simpleRumble.unLeftMotorSpeed = low_frequency_rumble;
+    msg->payload.simpleRumble.unRightMotorSpeed = high_frequency_rumble;
+    msg->payload.simpleRumble.nLeftGain = 2;
+    msg->payload.simpleRumble.nRightGain = 0;
+
+    rc = SDL_hid_send_feature_report(device->dev, buffer, sizeof(buffer));
+    if (rc != sizeof(buffer))
+        return -1;
+    return 0;
 }
 
 static int HIDAPI_DriverSteamDeck_RumbleJoystickTriggers(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble)
@@ -374,7 +388,7 @@ static int HIDAPI_DriverSteamDeck_RumbleJoystickTriggers(SDL_HIDAPI_Device *devi
 
 static Uint32 HIDAPI_DriverSteamDeck_GetJoystickCapabilities(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
 {
-    return 0;
+    return SDL_JOYCAP_RUMBLE;
 }
 
 static int HIDAPI_DriverSteamDeck_SetJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue)