From f65bb842fff26881bd5a1d69748ecb5babc847cd Mon Sep 17 00:00:00 2001 From: ABeltramo Date: Thu, 27 Mar 2025 00:16:20 +0100 Subject: [PATCH] feat(input/linux): DualSense adaptive trigger support (#3738) --- src/platform/common.h | 18 ++++++++++ .../linux/input/inputtino_gamepad.cpp | 4 +++ src/stream.cpp | 33 +++++++++++++++++++ third-party/inputtino | 2 +- 4 files changed, 56 insertions(+), 1 deletion(-) diff --git a/src/platform/common.h b/src/platform/common.h index 49d1fc7c..28704bb1 100644 --- a/src/platform/common.h +++ b/src/platform/common.h @@ -106,6 +106,7 @@ namespace platf { rumble_triggers, ///< Rumble triggers set_motion_event_state, ///< Set motion event state set_rgb_led, ///< Set RGB LED + set_adaptive_triggers, ///< Set adaptive triggers }; struct gamepad_feedback_msg_t { @@ -142,6 +143,14 @@ namespace platf { return msg; } + static gamepad_feedback_msg_t make_adaptive_triggers(std::uint16_t id, uint8_t event_flags, uint8_t type_left, uint8_t type_right, const std::array &left, const std::array &right) { + gamepad_feedback_msg_t msg; + msg.type = gamepad_feedback_e::set_adaptive_triggers; + msg.id = id; + msg.data.adaptive_triggers = {.event_flags = event_flags, .type_left = type_left, .type_right = type_right, .left = left, .right = right}; + return msg; + } + gamepad_feedback_e type; std::uint16_t id; @@ -166,6 +175,15 @@ namespace platf { std::uint8_t g; std::uint8_t b; } rgb_led; + + struct { + uint16_t controllerNumber; + uint8_t event_flags; + uint8_t type_left; + uint8_t type_right; + std::array left; + std::array right; + } adaptive_triggers; } data; }; diff --git a/src/platform/linux/input/inputtino_gamepad.cpp b/src/platform/linux/input/inputtino_gamepad.cpp index 16ecc56f..43814631 100644 --- a/src/platform/linux/input/inputtino_gamepad.cpp +++ b/src/platform/linux/input/inputtino_gamepad.cpp @@ -152,6 +152,10 @@ namespace platf::gamepad { gamepad->last_rgb_led = msg; }); + (*ds5).set_on_trigger_effect([feedback_queue, idx = id.clientRelativeIndex](const inputtino::PS5Joypad::TriggerEffect &trigger_effect) { + feedback_queue->raise(gamepad_feedback_msg_t::make_adaptive_triggers(idx, trigger_effect.event_flags, trigger_effect.type_left, trigger_effect.type_right, trigger_effect.left, trigger_effect.right)); + }); + // Activate the motion sensors feedback_queue->raise(gamepad_feedback_msg_t::make_motion_event_state(id.clientRelativeIndex, LI_MOTION_TYPE_ACCEL, 100)); feedback_queue->raise(gamepad_feedback_msg_t::make_motion_event_state(id.clientRelativeIndex, LI_MOTION_TYPE_GYRO, 100)); diff --git a/src/stream.cpp b/src/stream.cpp index b42bd304..2572d555 100644 --- a/src/stream.cpp +++ b/src/stream.cpp @@ -48,6 +48,7 @@ extern "C" { #define IDX_RUMBLE_TRIGGER_DATA 12 #define IDX_SET_MOTION_EVENT 13 #define IDX_SET_RGB_LED 14 +#define IDX_SET_ADAPTIVE_TRIGGERS 15 static const short packetTypes[] = { 0x0305, // Start A @@ -65,6 +66,7 @@ static const short packetTypes[] = { 0x5500, // Rumble triggers (Sunshine protocol extension) 0x5501, // Set motion event (Sunshine protocol extension) 0x5502, // Set RGB LED (Sunshine protocol extension) + 0x5503, // Set Adaptive triggers (Sunshine protocol extension) }; namespace asio = boost::asio; @@ -186,6 +188,21 @@ namespace stream { std::uint8_t b; }; + struct control_adaptive_triggers_t { + control_header_v2 header; + + std::uint16_t id; + /** + * 0x04 - Right trigger + * 0x08 - Left trigger + */ + std::uint8_t event_flags; + std::uint8_t type_left; + std::uint8_t type_right; + std::uint8_t left[DS_EFFECT_PAYLOAD_SIZE]; + std::uint8_t right[DS_EFFECT_PAYLOAD_SIZE]; + }; + struct control_hdr_mode_t { control_header_v2 header; @@ -833,6 +850,22 @@ namespace stream { plaintext.b = data.b; BOOST_LOG(verbose) << "RGB: "sv << msg.id << " :: "sv << util::hex(data.r).to_string_view() << util::hex(data.g).to_string_view() << util::hex(data.b).to_string_view(); + std::array + encrypted_payload; + + payload = encode_control(session, util::view(plaintext), encrypted_payload); + } else if (msg.type == platf::gamepad_feedback_e::set_adaptive_triggers) { + control_adaptive_triggers_t plaintext; + plaintext.header.type = packetTypes[IDX_SET_ADAPTIVE_TRIGGERS]; + plaintext.header.payloadLength = sizeof(plaintext) - sizeof(control_header_v2); + + plaintext.id = util::endian::little(msg.id); + plaintext.event_flags = msg.data.adaptive_triggers.event_flags; + plaintext.type_left = msg.data.adaptive_triggers.type_left; + std::ranges::copy(msg.data.adaptive_triggers.left, plaintext.left); + plaintext.type_right = msg.data.adaptive_triggers.type_right; + std::ranges::copy(msg.data.adaptive_triggers.right, plaintext.right); + std::array encrypted_payload; diff --git a/third-party/inputtino b/third-party/inputtino index 1170b1e4..fd136cfe 160000 --- a/third-party/inputtino +++ b/third-party/inputtino @@ -1 +1 @@ -Subproject commit 1170b1e4ad0f987b24dc94b20c0e866e8350b741 +Subproject commit fd136cfe492b4375b4507718bcca1f044588fc6f