mirror of
https://github.com/moonlight-stream/moonlight-qt.git
synced 2025-06-30 23:06:35 +00:00
DualSense adaptive trigger support (#1561)
This commit is contained in:
parent
fabb4fdadc
commit
d9c7a245ef
@ -900,6 +900,22 @@ void SdlInputHandler::setControllerLED(uint16_t controllerNumber, uint8_t r, uin
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SdlInputHandler::setAdaptiveTriggers(uint16_t controllerNumber, DualSenseOutputReport *report){
|
||||||
|
|
||||||
|
#if SDL_VERSION_ATLEAST(2, 0, 16)
|
||||||
|
// Make sure the controller number is within our supported count
|
||||||
|
if (controllerNumber <= MAX_GAMEPADS &&
|
||||||
|
// and we have a valid controller
|
||||||
|
m_GamepadState[controllerNumber].controller != nullptr &&
|
||||||
|
// and it's a PS5 controller
|
||||||
|
SDL_GameControllerGetType(m_GamepadState[controllerNumber].controller) == SDL_CONTROLLER_TYPE_PS5) {
|
||||||
|
SDL_GameControllerSendEffect(m_GamepadState[controllerNumber].controller, report, sizeof(*report));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
SDL_free(report);
|
||||||
|
}
|
||||||
|
|
||||||
QString SdlInputHandler::getUnmappedGamepads()
|
QString SdlInputHandler::getUnmappedGamepads()
|
||||||
{
|
{
|
||||||
QString ret;
|
QString ret;
|
||||||
|
@ -38,6 +38,37 @@ struct GamepadState {
|
|||||||
unsigned char lt, rt;
|
unsigned char lt, rt;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct DualSenseOutputReport{
|
||||||
|
uint8_t validFlag0;
|
||||||
|
uint8_t validFlag1;
|
||||||
|
|
||||||
|
/* For DualShock 4 compatibility mode. */
|
||||||
|
uint8_t motorRight;
|
||||||
|
uint8_t motorLeft;
|
||||||
|
|
||||||
|
/* Audio controls */
|
||||||
|
uint8_t reserved[4];
|
||||||
|
uint8_t muteButtonLed;
|
||||||
|
|
||||||
|
uint8_t powerSaveControl;
|
||||||
|
uint8_t rightTriggerEffectType;
|
||||||
|
uint8_t rightTriggerEffect[DS_EFFECT_PAYLOAD_SIZE];
|
||||||
|
uint8_t leftTriggerEffectType;
|
||||||
|
uint8_t leftTriggerEffect[DS_EFFECT_PAYLOAD_SIZE];
|
||||||
|
uint8_t reserved2[6];
|
||||||
|
|
||||||
|
/* LEDs and lightbar */
|
||||||
|
uint8_t validFlag2;
|
||||||
|
uint8_t reserved3[2];
|
||||||
|
uint8_t lightbarSetup;
|
||||||
|
uint8_t ledBrightness;
|
||||||
|
uint8_t playerLeds;
|
||||||
|
uint8_t lightbarRed;
|
||||||
|
uint8_t lightbarGreen;
|
||||||
|
uint8_t lightbarBlue;
|
||||||
|
};
|
||||||
|
|
||||||
// activeGamepadMask is a short, so we're bounded by the number of mask bits
|
// activeGamepadMask is a short, so we're bounded by the number of mask bits
|
||||||
#define MAX_GAMEPADS 16
|
#define MAX_GAMEPADS 16
|
||||||
|
|
||||||
@ -95,6 +126,8 @@ public:
|
|||||||
|
|
||||||
void setControllerLED(uint16_t controllerNumber, uint8_t r, uint8_t g, uint8_t b);
|
void setControllerLED(uint16_t controllerNumber, uint8_t r, uint8_t g, uint8_t b);
|
||||||
|
|
||||||
|
void setAdaptiveTriggers(uint16_t controllerNumber, DualSenseOutputReport *report);
|
||||||
|
|
||||||
void handleTouchFingerEvent(SDL_TouchFingerEvent* event);
|
void handleTouchFingerEvent(SDL_TouchFingerEvent* event);
|
||||||
|
|
||||||
int getAttachedGamepadMask();
|
int getAttachedGamepadMask();
|
||||||
|
@ -40,6 +40,7 @@
|
|||||||
#define SDL_CODE_GAMECONTROLLER_RUMBLE_TRIGGERS 102
|
#define SDL_CODE_GAMECONTROLLER_RUMBLE_TRIGGERS 102
|
||||||
#define SDL_CODE_GAMECONTROLLER_SET_MOTION_EVENT_STATE 103
|
#define SDL_CODE_GAMECONTROLLER_SET_MOTION_EVENT_STATE 103
|
||||||
#define SDL_CODE_GAMECONTROLLER_SET_CONTROLLER_LED 104
|
#define SDL_CODE_GAMECONTROLLER_SET_CONTROLLER_LED 104
|
||||||
|
#define SDL_CODE_GAMECONTROLLER_SET_ADAPTIVE_TRIGGERS 105
|
||||||
|
|
||||||
#include <openssl/rand.h>
|
#include <openssl/rand.h>
|
||||||
|
|
||||||
@ -69,6 +70,7 @@ CONNECTION_LISTENER_CALLBACKS Session::k_ConnCallbacks = {
|
|||||||
Session::clRumbleTriggers,
|
Session::clRumbleTriggers,
|
||||||
Session::clSetMotionEventState,
|
Session::clSetMotionEventState,
|
||||||
Session::clSetControllerLED,
|
Session::clSetControllerLED,
|
||||||
|
Session::clSetAdaptiveTriggers
|
||||||
};
|
};
|
||||||
|
|
||||||
Session* Session::s_ActiveSession;
|
Session* Session::s_ActiveSession;
|
||||||
@ -259,6 +261,30 @@ void Session::clSetControllerLED(uint16_t controllerNumber, uint8_t r, uint8_t g
|
|||||||
SDL_PushEvent(&setControllerLEDEvent);
|
SDL_PushEvent(&setControllerLEDEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Session::clSetAdaptiveTriggers(uint16_t controllerNumber, uint8_t eventFlags, uint8_t typeLeft, uint8_t typeRight, uint8_t *left, uint8_t *right){
|
||||||
|
// 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 setControllerLEDEvent = {};
|
||||||
|
setControllerLEDEvent.type = SDL_USEREVENT;
|
||||||
|
setControllerLEDEvent.user.code = SDL_CODE_GAMECONTROLLER_SET_ADAPTIVE_TRIGGERS;
|
||||||
|
setControllerLEDEvent.user.data1 = (void*)(uintptr_t)controllerNumber;
|
||||||
|
|
||||||
|
// Based on the following SDL code:
|
||||||
|
// https://github.com/libsdl-org/SDL/blob/120c76c84bbce4c1bfed4e9eb74e10678bd83120/test/testgamecontroller.c#L286-L307
|
||||||
|
DualSenseOutputReport *state = (DualSenseOutputReport *) SDL_malloc(sizeof(DualSenseOutputReport));
|
||||||
|
SDL_zero(*state);
|
||||||
|
state->validFlag0 = (eventFlags & DS_EFFECT_RIGHT_TRIGGER) | (eventFlags & DS_EFFECT_LEFT_TRIGGER);
|
||||||
|
state->rightTriggerEffectType = typeRight;
|
||||||
|
SDL_memcpy(state->rightTriggerEffect, right, sizeof(state->rightTriggerEffect));
|
||||||
|
state->leftTriggerEffectType = typeLeft;
|
||||||
|
SDL_memcpy(state->leftTriggerEffect, left, sizeof(state->leftTriggerEffect));
|
||||||
|
|
||||||
|
setControllerLEDEvent.user.data2 = (void *) state;
|
||||||
|
SDL_PushEvent(&setControllerLEDEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Session::chooseDecoder(StreamingPreferences::VideoDecoderSelection vds,
|
bool Session::chooseDecoder(StreamingPreferences::VideoDecoderSelection vds,
|
||||||
SDL_Window* window, int videoFormat, int width, int height,
|
SDL_Window* window, int videoFormat, int width, int height,
|
||||||
int frameRate, bool enableVsync, bool enableFramePacing, bool testOnly, IVideoDecoder*& chosenDecoder)
|
int frameRate, bool enableVsync, bool enableFramePacing, bool testOnly, IVideoDecoder*& chosenDecoder)
|
||||||
@ -2041,6 +2067,10 @@ void Session::execInternal()
|
|||||||
(uint8_t)((uintptr_t)event.user.data2 >> 8),
|
(uint8_t)((uintptr_t)event.user.data2 >> 8),
|
||||||
(uint8_t)((uintptr_t)event.user.data2));
|
(uint8_t)((uintptr_t)event.user.data2));
|
||||||
break;
|
break;
|
||||||
|
case SDL_CODE_GAMECONTROLLER_SET_ADAPTIVE_TRIGGERS:
|
||||||
|
m_InputHandler->setAdaptiveTriggers((uint16_t)(uintptr_t)event.user.data1,
|
||||||
|
(DualSenseOutputReport *)event.user.data2);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
SDL_assert(false);
|
SDL_assert(false);
|
||||||
}
|
}
|
||||||
|
@ -220,6 +220,9 @@ private:
|
|||||||
static
|
static
|
||||||
void clSetControllerLED(uint16_t controllerNumber, uint8_t r, uint8_t g, uint8_t b);
|
void clSetControllerLED(uint16_t controllerNumber, uint8_t r, uint8_t g, uint8_t b);
|
||||||
|
|
||||||
|
static
|
||||||
|
void clSetAdaptiveTriggers(uint16_t controllerNumber, uint8_t eventFlags, uint8_t typeLeft, uint8_t typeRight, uint8_t *left, uint8_t *right);
|
||||||
|
|
||||||
static
|
static
|
||||||
int arInit(int audioConfiguration,
|
int arInit(int audioConfiguration,
|
||||||
const POPUS_MULTISTREAM_CONFIGURATION opusConfig,
|
const POPUS_MULTISTREAM_CONFIGURATION opusConfig,
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit 8599b6042a4ba27749b0f94134dd614b4328a9bc
|
Subproject commit e95feaf4951b8dc774671a5d6a1c31d76d78e3ac
|
Loading…
x
Reference in New Issue
Block a user