From b945c8c2dcc070f968fa011a2547fe3fa3b8d858 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Sun, 18 Jun 2023 16:04:49 -0500 Subject: [PATCH] Implement trigger rumble using Sunshine protocol extension --- app/streaming/input/gamepad.cpp | 14 ++++++++++++++ app/streaming/input/input.h | 4 +++- app/streaming/session.cpp | 26 +++++++++++++++++++++++--- app/streaming/session.h | 3 +++ 4 files changed, 43 insertions(+), 4 deletions(-) diff --git a/app/streaming/input/gamepad.cpp b/app/streaming/input/gamepad.cpp index 728d0f0e..79b4954a 100644 --- a/app/streaming/input/gamepad.cpp +++ b/app/streaming/input/gamepad.cpp @@ -566,6 +566,20 @@ void SdlInputHandler::rumble(unsigned short controllerNumber, unsigned short low #endif } +void SdlInputHandler::rumbleTriggers(uint16_t controllerNumber, uint16_t leftTrigger, uint16_t rightTrigger) +{ + // Make sure the controller number is within our supported count + if (controllerNumber >= MAX_GAMEPADS) { + return; + } + +#if SDL_VERSION_ATLEAST(2, 0, 14) + if (m_GamepadState[controllerNumber].controller != nullptr) { + SDL_GameControllerRumbleTriggers(m_GamepadState[controllerNumber].controller, leftTrigger, rightTrigger, 30000); + } +#endif +} + QString SdlInputHandler::getUnmappedGamepads() { QString ret; diff --git a/app/streaming/input/input.h b/app/streaming/input/input.h index ab93a4a4..050ca438 100644 --- a/app/streaming/input/input.h +++ b/app/streaming/input/input.h @@ -62,7 +62,9 @@ public: void sendText(QString& string); - void rumble(unsigned short controllerNumber, unsigned short lowFreqMotor, unsigned short highFreqMotor); + void rumble(uint16_t controllerNumber, uint16_t lowFreqMotor, uint16_t highFreqMotor); + + void rumbleTriggers(uint16_t controllerNumber, uint16_t leftTrigger, uint16_t rightTrigger); void handleTouchFingerEvent(SDL_TouchFingerEvent* event); diff --git a/app/streaming/session.cpp b/app/streaming/session.cpp index 35e0b7c1..c448f189 100644 --- a/app/streaming/session.cpp +++ b/app/streaming/session.cpp @@ -37,6 +37,7 @@ #define SDL_CODE_FLUSH_WINDOW_EVENT_BARRIER 100 #define SDL_CODE_GAMECONTROLLER_RUMBLE 101 +#define SDL_CODE_GAMECONTROLLER_RUMBLE_TRIGGERS 102 #include @@ -62,6 +63,7 @@ CONNECTION_LISTENER_CALLBACKS Session::k_ConnCallbacks = { Session::clRumble, Session::clConnectionStatusUpdate, Session::clSetHdrMode, + Session::clRumbleTriggers, }; Session* Session::s_ActiveSession; @@ -213,6 +215,19 @@ void Session::clSetHdrMode(bool enabled) } } +void Session::clRumbleTriggers(uint16_t controllerNumber, uint16_t leftTrigger, uint16_t rightTrigger) +{ + // We push an event for the main thread to handle in order to properly synchronize + // with the removal of game controllers that could result in our game controller + // going away during this callback. + SDL_Event rumbleEvent = {}; + rumbleEvent.type = SDL_USEREVENT; + rumbleEvent.user.code = SDL_CODE_GAMECONTROLLER_RUMBLE_TRIGGERS; + rumbleEvent.user.data1 = (void*)(uintptr_t)controllerNumber; + rumbleEvent.user.data2 = (void*)(uintptr_t)((leftTrigger << 16) | rightTrigger); + SDL_PushEvent(&rumbleEvent); +} + bool Session::chooseDecoder(StreamingPreferences::VideoDecoderSelection vds, SDL_Window* window, int videoFormat, int width, int height, int frameRate, bool enableVsync, bool enableFramePacing, bool testOnly, IVideoDecoder*& chosenDecoder) @@ -1635,9 +1650,14 @@ void Session::execInternal() m_FlushingWindowEventsRef--; break; case SDL_CODE_GAMECONTROLLER_RUMBLE: - m_InputHandler->rumble((unsigned short)(uintptr_t)event.user.data1, - (unsigned short)((uintptr_t)event.user.data2 >> 16), - (unsigned short)((uintptr_t)event.user.data2 & 0xFFFF)); + m_InputHandler->rumble((uint16_t)(uintptr_t)event.user.data1, + (uint16_t)((uintptr_t)event.user.data2 >> 16), + (uint16_t)((uintptr_t)event.user.data2 & 0xFFFF)); + break; + case SDL_CODE_GAMECONTROLLER_RUMBLE_TRIGGERS: + m_InputHandler->rumbleTriggers((uint16_t)(uintptr_t)event.user.data1, + (uint16_t)((uintptr_t)event.user.data2 >> 16), + (uint16_t)((uintptr_t)event.user.data2 & 0xFFFF)); break; default: SDL_assert(false); diff --git a/app/streaming/session.h b/app/streaming/session.h index a23abb90..83776f7a 100644 --- a/app/streaming/session.h +++ b/app/streaming/session.h @@ -124,6 +124,9 @@ private: static void clSetHdrMode(bool enabled); + static + void clRumbleTriggers(uint16_t controllerNumber, uint16_t leftTrigger, uint16_t rightTrigger); + static int arInit(int audioConfiguration, const POPUS_MULTISTREAM_CONFIGURATION opusConfig,