Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions src/input.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -961,8 +961,12 @@ namespace input {
}

if (input->gamepads[packet->controllerNumber].id >= 0) {
BOOST_LOG(warning) << "ControllerNumber already allocated ["sv << packet->controllerNumber << ']';
return;
// A client may intentionally re-declare a controller to change its emulated type or
// capabilities at runtime. Recreate it so the new arrival metadata takes effect.
BOOST_LOG(info) << "Reallocating ControllerNumber with updated metadata ["sv
<< packet->controllerNumber << ']';
free_gamepad(platf_input, input->gamepads[packet->controllerNumber].id);
input->gamepads[packet->controllerNumber].id = -1;
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated
}

platf::gamepad_arrival_t arrival {
Expand Down
4 changes: 4 additions & 0 deletions src/platform/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,10 @@ namespace platf {
constexpr std::uint32_t TOUCHPAD_BUTTON = 0x100000;
constexpr std::uint32_t MISC_BUTTON = 0x200000;

// Foundation client extension carried in SS_CONTROLLER_ARRIVAL_PACKET::capabilities.
// Requests a native DualSense device rather than the generic PS/DS4 fallback.
constexpr std::uint16_t GAMEPAD_CAP_PREFER_DS5 = 0x0100;

struct supported_gamepad_t {
std::string name;
bool is_enabled;
Expand Down
26 changes: 17 additions & 9 deletions src/platform/windows/input.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1912,19 +1912,27 @@ namespace platf {
const auto gamepad_mode = effective_gamepad_mode();
const auto per_app_override = current_gamepad_mode.load(std::memory_order_relaxed) != 0;

if (gamepad_mode == 4) {
const auto client_prefers_ds5 = gamepad_mode == 1 &&
(metadata.capabilities & GAMEPAD_CAP_PREFER_DS5);
if (gamepad_mode == 4 || client_prefers_ds5) {
BOOST_LOG(info) << "Gamepad " << id.globalIndex << " will be DualSense controller ("
<< (per_app_override ? "per-app selection" : "global selection") << ')';
<< (client_prefers_ds5 ? "requested by client" :
per_app_override ? "per-app selection" : "global selection") << ')';
if (!raw->ds5_sidecar || !raw->ds5_sidecar->configured()) {
BOOST_LOG(error) << "DualSense emulation is selected but its optional sidecar component is unavailable"sv;
return -1;
if (!client_prefers_ds5) {
BOOST_LOG(error) << "DualSense emulation is selected but its optional sidecar component is unavailable"sv;
return -1;
}
BOOST_LOG(warning) << "Client requested DualSense emulation, but its optional sidecar component is unavailable; falling back to DualShock 4"sv;
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.
const auto result = raw->ds5_sidecar->alloc(id, feedback_queue, config::input.ds5_audio_haptics);
if (result == 0) {
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));
else {
const auto result = raw->ds5_sidecar->alloc(id, feedback_queue, config::input.ds5_audio_haptics);
if (result == 0) {
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));
}
return result;
}
Comment on lines +1937 to 1948
return result;
}

if (!raw->vigem) {
Expand Down
Loading