summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
m---------externals/dynarmic0
-rw-r--r--src/audio_core/stream.cpp8
-rw-r--r--src/audio_core/stream.h3
-rw-r--r--src/core/hle/kernel/hle_ipc.cpp22
-rw-r--r--src/core/hle/kernel/hle_ipc.h6
-rw-r--r--src/core/hle/service/audio/audout_u.cpp10
-rw-r--r--src/core/hle/service/hid/controllers/npad.cpp7
-rw-r--r--src/core/hle/service/hid/controllers/npad.h6
-rw-r--r--src/core/hle/service/hid/hid.cpp41
-rw-r--r--src/core/hle/service/prepo/prepo.cpp66
-rw-r--r--src/core/hle/service/sockets/bsd.cpp17
-rw-r--r--src/core/hle/service/sockets/bsd.h1
-rw-r--r--src/video_core/renderer_vulkan/vk_scheduler.h12
-rw-r--r--src/yuzu/configuration/configure_input.cpp6
-rw-r--r--src/yuzu/configuration/configure_input_player.cpp46
15 files changed, 178 insertions, 73 deletions
diff --git a/externals/dynarmic b/externals/dynarmic
-Subproject 3806284cbefc4115436dcdc687776a45ec31309
+Subproject 8c09da666aa3f0bb1000b0b6c5d5b0a1876f306
diff --git a/src/audio_core/stream.cpp b/src/audio_core/stream.cpp
index afe68c9ed..5b0b285cd 100644
--- a/src/audio_core/stream.cpp
+++ b/src/audio_core/stream.cpp
@@ -51,6 +51,14 @@ void Stream::Stop() {
UNIMPLEMENTED();
}
+bool Stream::Flush() {
+ const bool had_buffers = !queued_buffers.empty();
+ while (!queued_buffers.empty()) {
+ queued_buffers.pop();
+ }
+ return had_buffers;
+}
+
void Stream::SetVolume(float volume) {
game_volume = volume;
}
diff --git a/src/audio_core/stream.h b/src/audio_core/stream.h
index 506ac536b..559844b9b 100644
--- a/src/audio_core/stream.h
+++ b/src/audio_core/stream.h
@@ -56,6 +56,9 @@ public:
/// Queues a buffer into the audio stream, returns true on success
bool QueueBuffer(BufferPtr&& buffer);
+ /// Flush audio buffers
+ bool Flush();
+
/// Returns true if the audio stream contains a buffer with the specified tag
[[nodiscard]] bool ContainsBuffer(Buffer::Tag tag) const;
diff --git a/src/core/hle/kernel/hle_ipc.cpp b/src/core/hle/kernel/hle_ipc.cpp
index 83decf6cf..a419f9602 100644
--- a/src/core/hle/kernel/hle_ipc.cpp
+++ b/src/core/hle/kernel/hle_ipc.cpp
@@ -338,6 +338,28 @@ std::size_t HLERequestContext::GetWriteBufferSize(std::size_t buffer_index) cons
return 0;
}
+bool HLERequestContext::CanReadBuffer(std::size_t buffer_index) const {
+ const bool is_buffer_a{BufferDescriptorA().size() > buffer_index &&
+ BufferDescriptorA()[buffer_index].Size()};
+
+ if (is_buffer_a) {
+ return BufferDescriptorA().size() > buffer_index;
+ } else {
+ return BufferDescriptorX().size() > buffer_index;
+ }
+}
+
+bool HLERequestContext::CanWriteBuffer(std::size_t buffer_index) const {
+ const bool is_buffer_b{BufferDescriptorB().size() > buffer_index &&
+ BufferDescriptorB()[buffer_index].Size()};
+
+ if (is_buffer_b) {
+ return BufferDescriptorB().size() > buffer_index;
+ } else {
+ return BufferDescriptorC().size() > buffer_index;
+ }
+}
+
std::string HLERequestContext::Description() const {
if (!command_header) {
return "No command header available";
diff --git a/src/core/hle/kernel/hle_ipc.h b/src/core/hle/kernel/hle_ipc.h
index b112e1ebd..698f607e6 100644
--- a/src/core/hle/kernel/hle_ipc.h
+++ b/src/core/hle/kernel/hle_ipc.h
@@ -207,6 +207,12 @@ public:
/// Helper function to get the size of the output buffer
std::size_t GetWriteBufferSize(std::size_t buffer_index = 0) const;
+ /// Helper function to test whether the input buffer at buffer_index can be read
+ bool CanReadBuffer(std::size_t buffer_index = 0) const;
+
+ /// Helper function to test whether the output buffer at buffer_index can be written
+ bool CanWriteBuffer(std::size_t buffer_index = 0) const;
+
template <typename T>
std::shared_ptr<T> GetCopyObject(std::size_t index) {
return DynamicObjectCast<T>(copy_objects.at(index));
diff --git a/src/core/hle/service/audio/audout_u.cpp b/src/core/hle/service/audio/audout_u.cpp
index 02ca711fb..273a46265 100644
--- a/src/core/hle/service/audio/audout_u.cpp
+++ b/src/core/hle/service/audio/audout_u.cpp
@@ -58,7 +58,7 @@ public:
{8, &IAudioOut::GetReleasedAudioOutBufferImpl, "GetReleasedAudioOutBufferAuto"},
{9, &IAudioOut::GetAudioOutBufferCount, "GetAudioOutBufferCount"},
{10, nullptr, "GetAudioOutPlayedSampleCount"},
- {11, nullptr, "FlushAudioOutBuffers"},
+ {11, &IAudioOut::FlushAudioOutBuffers, "FlushAudioOutBuffers"},
{12, &IAudioOut::SetAudioOutVolume, "SetAudioOutVolume"},
{13, &IAudioOut::GetAudioOutVolume, "GetAudioOutVolume"},
};
@@ -185,6 +185,14 @@ private:
rb.Push(static_cast<u32>(stream->GetQueueSize()));
}
+ void FlushAudioOutBuffers(Kernel::HLERequestContext& ctx) {
+ LOG_DEBUG(Service_Audio, "called");
+
+ IPC::ResponseBuilder rb{ctx, 3};
+ rb.Push(RESULT_SUCCESS);
+ rb.Push(stream->Flush());
+ }
+
void SetAudioOutVolume(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const float volume = rp.Pop<float>();
diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp
index 265c986e2..0c227b135 100644
--- a/src/core/hle/service/hid/controllers/npad.cpp
+++ b/src/core/hle/service/hid/controllers/npad.cpp
@@ -946,20 +946,19 @@ void Controller_NPad::SetSixAxisEnabled(bool six_axis_status) {
sixaxis_sensors_enabled = six_axis_status;
}
-void Controller_NPad::SetSixAxisFusionParameters(const DeviceHandle& handle, f32 parameter1,
- f32 parameter2) {
+void Controller_NPad::SetSixAxisFusionParameters(f32 parameter1, f32 parameter2) {
sixaxis_fusion_parameter1 = parameter1;
sixaxis_fusion_parameter2 = parameter2;
}
-std::pair<f32, f32> Controller_NPad::GetSixAxisFusionParameters(const DeviceHandle& handle) {
+std::pair<f32, f32> Controller_NPad::GetSixAxisFusionParameters() {
return {
sixaxis_fusion_parameter1,
sixaxis_fusion_parameter2,
};
}
-void Controller_NPad::ResetSixAxisFusionParameters(const DeviceHandle& handle) {
+void Controller_NPad::ResetSixAxisFusionParameters() {
sixaxis_fusion_parameter1 = 0.0f;
sixaxis_fusion_parameter2 = 0.0f;
}
diff --git a/src/core/hle/service/hid/controllers/npad.h b/src/core/hle/service/hid/controllers/npad.h
index bfd06372a..2e13922b9 100644
--- a/src/core/hle/service/hid/controllers/npad.h
+++ b/src/core/hle/service/hid/controllers/npad.h
@@ -202,9 +202,9 @@ public:
GyroscopeZeroDriftMode GetGyroscopeZeroDriftMode() const;
bool IsSixAxisSensorAtRest() const;
void SetSixAxisEnabled(bool six_axis_status);
- void SetSixAxisFusionParameters(const DeviceHandle& handle, f32 parameter1, f32 parameter2);
- std::pair<f32, f32> GetSixAxisFusionParameters(const DeviceHandle& handle);
- void ResetSixAxisFusionParameters(const DeviceHandle& handle);
+ void SetSixAxisFusionParameters(f32 parameter1, f32 parameter2);
+ std::pair<f32, f32> GetSixAxisFusionParameters();
+ void ResetSixAxisFusionParameters();
LedPattern GetLedPattern(u32 npad_id);
bool IsUnintendedHomeButtonInputProtectionEnabled(u32 npad_id) const;
void SetUnintendedHomeButtonInputProtectionEnabled(bool is_protection_enabled, u32 npad_id);
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp
index 7fd3161e8..5efc1237e 100644
--- a/src/core/hle/service/hid/hid.cpp
+++ b/src/core/hle/service/hid/hid.cpp
@@ -520,6 +520,7 @@ void Hid::EnableSixAxisSensorFusion(Kernel::HLERequestContext& ctx) {
Controller_NPad::DeviceHandle sixaxis_handle;
u64 applet_resource_user_id;
};
+ static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
const auto parameters{rp.PopRaw<Parameters>()};
@@ -542,19 +543,19 @@ void Hid::SetSixAxisSensorFusionParameters(Kernel::HLERequestContext& ctx) {
f32 parameter2;
u64 applet_resource_user_id;
};
+ static_assert(sizeof(Parameters) == 0x18, "Parameters has incorrect size.");
const auto parameters{rp.PopRaw<Parameters>()};
applet_resource->GetController<Controller_NPad>(HidController::NPad)
- .SetSixAxisFusionParameters(parameters.sixaxis_handle, parameters.parameter1,
- parameters.parameter2);
+ .SetSixAxisFusionParameters(parameters.parameter1, parameters.parameter2);
LOG_WARNING(Service_HID,
- "(STUBBED) called, float1={}, float2={}, npad_type={}, npad_id={}, "
- "device_index={}, applet_resource_user_id={}",
- parameters.parameter1, parameters.parameter2, parameters.sixaxis_handle.npad_type,
- parameters.sixaxis_handle.npad_id, parameters.sixaxis_handle.device_index,
- parameters.applet_resource_user_id);
+ "(STUBBED) called, npad_type={}, npad_id={}, device_index={}, parameter1={}, "
+ "parameter2={}, applet_resource_user_id={}",
+ parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id,
+ parameters.sixaxis_handle.device_index, parameters.parameter1,
+ parameters.parameter2, parameters.applet_resource_user_id);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
@@ -566,6 +567,7 @@ void Hid::GetSixAxisSensorFusionParameters(Kernel::HLERequestContext& ctx) {
Controller_NPad::DeviceHandle sixaxis_handle;
u64 applet_resource_user_id;
};
+ static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
f32 parameter1 = 0;
f32 parameter2 = 0;
@@ -573,13 +575,13 @@ void Hid::GetSixAxisSensorFusionParameters(Kernel::HLERequestContext& ctx) {
std::tie(parameter1, parameter2) =
applet_resource->GetController<Controller_NPad>(HidController::NPad)
- .GetSixAxisFusionParameters(parameters.sixaxis_handle);
+ .GetSixAxisFusionParameters();
- LOG_WARNING(Service_HID,
- "(STUBBED) called, npad_type={}, npad_id={}, "
- "device_index={}, applet_resource_user_id={}",
- parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id,
- parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id);
+ LOG_WARNING(
+ Service_HID,
+ "(STUBBED) called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
+ parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id,
+ parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id);
IPC::ResponseBuilder rb{ctx, 4};
rb.Push(RESULT_SUCCESS);
@@ -593,17 +595,18 @@ void Hid::ResetSixAxisSensorFusionParameters(Kernel::HLERequestContext& ctx) {
Controller_NPad::DeviceHandle sixaxis_handle;
u64 applet_resource_user_id;
};
+ static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
const auto parameters{rp.PopRaw<Parameters>()};
applet_resource->GetController<Controller_NPad>(HidController::NPad)
- .ResetSixAxisFusionParameters(parameters.sixaxis_handle);
+ .ResetSixAxisFusionParameters();
- LOG_WARNING(Service_HID,
- "(STUBBED) called, npad_type={}, npad_id={}, "
- "device_index={}, applet_resource_user_id={}",
- parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id,
- parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id);
+ LOG_WARNING(
+ Service_HID,
+ "(STUBBED) called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
+ parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id,
+ parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
diff --git a/src/core/hle/service/prepo/prepo.cpp b/src/core/hle/service/prepo/prepo.cpp
index c0b38bf0d..86ecc5b97 100644
--- a/src/core/hle/service/prepo/prepo.cpp
+++ b/src/core/hle/service/prepo/prepo.cpp
@@ -23,8 +23,8 @@ public:
{10101, &PlayReport::SaveReportWithUser<Core::Reporter::PlayReportType::Old>, "SaveReportWithUserOld"},
{10102, &PlayReport::SaveReport<Core::Reporter::PlayReportType::Old2>, "SaveReportOld2"},
{10103, &PlayReport::SaveReportWithUser<Core::Reporter::PlayReportType::Old2>, "SaveReportWithUserOld2"},
- {10104, nullptr, "SaveReport"},
- {10105, nullptr, "SaveReportWithUser"},
+ {10104, &PlayReport::SaveReport<Core::Reporter::PlayReportType::New>, "SaveReport"},
+ {10105, &PlayReport::SaveReportWithUser<Core::Reporter::PlayReportType::New>, "SaveReportWithUser"},
{10200, nullptr, "RequestImmediateTransmission"},
{10300, nullptr, "GetTransmissionStatus"},
{10400, &PlayReport::GetSystemSessionId, "GetSystemSessionId"},
@@ -59,16 +59,22 @@ private:
IPC::RequestParser rp{ctx};
const auto process_id = rp.PopRaw<u64>();
- std::vector<std::vector<u8>> data{ctx.ReadBuffer(0)};
- if constexpr (Type == Core::Reporter::PlayReportType::Old2) {
- data.emplace_back(ctx.ReadBuffer(1));
- }
+ const auto data1 = ctx.ReadBuffer(0);
+ const auto data2 = [ctx] {
+ if (ctx.CanReadBuffer(1)) {
+ return ctx.ReadBuffer(1);
+ }
+
+ return std::vector<u8>{};
+ }();
- LOG_DEBUG(Service_PREPO, "called, type={:02X}, process_id={:016X}, data1_size={:016X}",
- Type, process_id, data[0].size());
+ LOG_DEBUG(Service_PREPO,
+ "called, type={:02X}, process_id={:016X}, data1_size={:016X}, data2_size={:016X}",
+ Type, process_id, data1.size(), data2.size());
const auto& reporter{system.GetReporter()};
- reporter.SavePlayReport(Type, system.CurrentProcess()->GetTitleID(), data, process_id);
+ reporter.SavePlayReport(Type, system.CurrentProcess()->GetTitleID(), {data1, data2},
+ process_id);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
@@ -79,24 +85,24 @@ private:
IPC::RequestParser rp{ctx};
const auto user_id = rp.PopRaw<u128>();
const auto process_id = rp.PopRaw<u64>();
- std::vector<std::vector<u8>> data{ctx.ReadBuffer(0)};
- if constexpr (Type == Core::Reporter::PlayReportType::Old2) {
- const auto read_buffer_count =
- ctx.BufferDescriptorX().size() + ctx.BufferDescriptorA().size();
- if (read_buffer_count > 1) {
- data.emplace_back(ctx.ReadBuffer(1));
+ const auto data1 = ctx.ReadBuffer(0);
+ const auto data2 = [ctx] {
+ if (ctx.CanReadBuffer(1)) {
+ return ctx.ReadBuffer(1);
}
- }
- LOG_DEBUG(
- Service_PREPO,
- "called, type={:02X}, user_id={:016X}{:016X}, process_id={:016X}, data1_size={:016X}",
- Type, user_id[1], user_id[0], process_id, data[0].size());
+ return std::vector<u8>{};
+ }();
+
+ LOG_DEBUG(Service_PREPO,
+ "called, type={:02X}, user_id={:016X}{:016X}, process_id={:016X}, "
+ "data1_size={:016X}, data2_size={:016X}",
+ Type, user_id[1], user_id[0], process_id, data1.size(), data2.size());
const auto& reporter{system.GetReporter()};
- reporter.SavePlayReport(Type, system.CurrentProcess()->GetTitleID(), data, process_id,
- user_id);
+ reporter.SavePlayReport(Type, system.CurrentProcess()->GetTitleID(), {data1, data2},
+ process_id, user_id);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
@@ -116,7 +122,13 @@ private:
const auto title_id = rp.PopRaw<u64>();
const auto data1 = ctx.ReadBuffer(0);
- const auto data2 = ctx.ReadBuffer(1);
+ const auto data2 = [ctx] {
+ if (ctx.CanReadBuffer(1)) {
+ return ctx.ReadBuffer(1);
+ }
+
+ return std::vector<u8>{};
+ }();
LOG_DEBUG(Service_PREPO, "called, title_id={:016X}, data1_size={:016X}, data2_size={:016X}",
title_id, data1.size(), data2.size());
@@ -134,7 +146,13 @@ private:
const auto title_id = rp.PopRaw<u64>();
const auto data1 = ctx.ReadBuffer(0);
- const auto data2 = ctx.ReadBuffer(1);
+ const auto data2 = [ctx] {
+ if (ctx.CanReadBuffer(1)) {
+ return ctx.ReadBuffer(1);
+ }
+
+ return std::vector<u8>{};
+ }();
LOG_DEBUG(Service_PREPO,
"called, user_id={:016X}{:016X}, title_id={:016X}, data1_size={:016X}, "
diff --git a/src/core/hle/service/sockets/bsd.cpp b/src/core/hle/service/sockets/bsd.cpp
index 2b824059d..d85df6af1 100644
--- a/src/core/hle/service/sockets/bsd.cpp
+++ b/src/core/hle/service/sockets/bsd.cpp
@@ -255,6 +255,21 @@ void BSD::GetSockName(Kernel::HLERequestContext& ctx) {
rb.Push<u32>(static_cast<u32>(write_buffer.size()));
}
+void BSD::GetSockOpt(Kernel::HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const s32 fd = rp.Pop<s32>();
+ const u32 level = rp.Pop<u32>();
+ const auto optname = static_cast<OptName>(rp.Pop<u32>());
+
+ LOG_WARNING(Service, "(STUBBED) called. fd={} level={} optname=0x{:x}", fd, level, optname);
+
+ IPC::ResponseBuilder rb{ctx, 5};
+ rb.Push(RESULT_SUCCESS);
+ rb.Push<s32>(-1);
+ rb.PushEnum(Errno::NOTCONN);
+ rb.Push<u32>(0);
+}
+
void BSD::Listen(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const s32 fd = rp.Pop<s32>();
@@ -812,7 +827,7 @@ BSD::BSD(Core::System& system_, const char* name) : ServiceFramework{system_, na
{14, &BSD::Connect, "Connect"},
{15, &BSD::GetPeerName, "GetPeerName"},
{16, &BSD::GetSockName, "GetSockName"},
- {17, nullptr, "GetSockOpt"},
+ {17, &BSD::GetSockOpt, "GetSockOpt"},
{18, &BSD::Listen, "Listen"},
{19, nullptr, "Ioctl"},
{20, &BSD::Fcntl, "Fcntl"},
diff --git a/src/core/hle/service/sockets/bsd.h b/src/core/hle/service/sockets/bsd.h
index 6da0bfeb2..f5831dd48 100644
--- a/src/core/hle/service/sockets/bsd.h
+++ b/src/core/hle/service/sockets/bsd.h
@@ -125,6 +125,7 @@ private:
void Connect(Kernel::HLERequestContext& ctx);
void GetPeerName(Kernel::HLERequestContext& ctx);
void GetSockName(Kernel::HLERequestContext& ctx);
+ void GetSockOpt(Kernel::HLERequestContext& ctx);
void Listen(Kernel::HLERequestContext& ctx);
void Fcntl(Kernel::HLERequestContext& ctx);
void SetSockOpt(Kernel::HLERequestContext& ctx);
diff --git a/src/video_core/renderer_vulkan/vk_scheduler.h b/src/video_core/renderer_vulkan/vk_scheduler.h
index 4cd43e425..15f2987eb 100644
--- a/src/video_core/renderer_vulkan/vk_scheduler.h
+++ b/src/video_core/renderer_vulkan/vk_scheduler.h
@@ -6,10 +6,12 @@
#include <atomic>
#include <condition_variable>
+#include <cstddef>
#include <memory>
#include <stack>
#include <thread>
#include <utility>
+#include "common/alignment.h"
#include "common/common_types.h"
#include "common/threadsafe_queue.h"
#include "video_core/vulkan_common/vulkan_wrapper.h"
@@ -130,12 +132,11 @@ private:
using FuncType = TypedCommand<T>;
static_assert(sizeof(FuncType) < sizeof(data), "Lambda is too large");
+ command_offset = Common::AlignUp(command_offset, alignof(FuncType));
if (command_offset > sizeof(data) - sizeof(FuncType)) {
return false;
}
-
- Command* current_last = last;
-
+ Command* const current_last = last;
last = new (data.data() + command_offset) FuncType(std::move(command));
if (current_last) {
@@ -143,7 +144,6 @@ private:
} else {
first = last;
}
-
command_offset += sizeof(FuncType);
return true;
}
@@ -156,8 +156,8 @@ private:
Command* first = nullptr;
Command* last = nullptr;
- std::size_t command_offset = 0;
- std::array<u8, 0x8000> data{};
+ size_t command_offset = 0;
+ alignas(std::max_align_t) std::array<u8, 0x8000> data{};
};
struct State {
diff --git a/src/yuzu/configuration/configure_input.cpp b/src/yuzu/configuration/configure_input.cpp
index 567a36d9b..422022d02 100644
--- a/src/yuzu/configuration/configure_input.cpp
+++ b/src/yuzu/configuration/configure_input.cpp
@@ -190,12 +190,16 @@ void ConfigureInput::ApplyConfiguration() {
// This emulates a delay between disconnecting and reconnecting controllers as some games
// do not respond to a change in controller type if it was instantaneous.
using namespace std::chrono_literals;
- std::this_thread::sleep_for(60ms);
+ std::this_thread::sleep_for(150ms);
for (auto* controller : player_controllers) {
controller->TryConnectSelectedController();
}
+ // This emulates a delay between disconnecting and reconnecting controllers as some games
+ // do not respond to a change in controller type if it was instantaneous.
+ std::this_thread::sleep_for(150ms);
+
advanced->ApplyConfiguration();
const bool pre_docked_mode = Settings::values.use_docked_mode.GetValue();
diff --git a/src/yuzu/configuration/configure_input_player.cpp b/src/yuzu/configuration/configure_input_player.cpp
index 13f0351d4..fbe36046b 100644
--- a/src/yuzu/configuration/configure_input_player.cpp
+++ b/src/yuzu/configuration/configure_input_player.cpp
@@ -579,11 +579,11 @@ void ConfigureInputPlayer::ApplyConfiguration() {
// Apply configuration for handheld
if (player_index == 0) {
auto& handheld = Settings::values.players.GetValue()[HANDHELD_INDEX];
+ const auto handheld_connected = handheld.connected;
if (player.controller_type == Settings::ControllerType::Handheld) {
handheld = player;
}
- handheld.connected = ui->groupConnectedController->isChecked() &&
- player.controller_type == Settings::ControllerType::Handheld;
+ handheld.connected = handheld_connected;
}
}
@@ -595,6 +595,18 @@ void ConfigureInputPlayer::TryConnectSelectedController() {
const auto player_connected = ui->groupConnectedController->isChecked() &&
controller_type != Settings::ControllerType::Handheld;
+ // Connect Handheld depending on Player 1's controller configuration.
+ if (player_index == 0 && controller_type == Settings::ControllerType::Handheld) {
+ auto& handheld = Settings::values.players.GetValue()[HANDHELD_INDEX];
+ const auto handheld_connected = ui->groupConnectedController->isChecked() &&
+ controller_type == Settings::ControllerType::Handheld;
+ // Connect only if handheld is going from disconnected to connected
+ if (!handheld.connected && handheld_connected) {
+ UpdateController(controller_type, HANDHELD_INDEX, true);
+ }
+ handheld.connected = handheld_connected;
+ }
+
if (player.controller_type == controller_type && player.connected == player_connected) {
// Set vibration devices in the event that the input device has changed.
ConfigureVibration::SetVibrationDevices(player_index);
@@ -606,22 +618,11 @@ void ConfigureInputPlayer::TryConnectSelectedController() {
ConfigureVibration::SetVibrationDevices(player_index);
- // Connect/Disconnect Handheld depending on Player 1's controller configuration.
- if (player_index == 0) {
- auto& handheld = Settings::values.players.GetValue()[HANDHELD_INDEX];
- if (controller_type == Settings::ControllerType::Handheld) {
- handheld = player;
- }
- handheld.connected = ui->groupConnectedController->isChecked() &&
- controller_type == Settings::ControllerType::Handheld;
- UpdateController(Settings::ControllerType::Handheld, HANDHELD_INDEX, handheld.connected);
- }
-
if (!player.connected) {
return;
}
- UpdateController(controller_type, player_index, player_connected);
+ UpdateController(controller_type, player_index, true);
}
void ConfigureInputPlayer::TryDisconnectSelectedController() {
@@ -632,11 +633,28 @@ void ConfigureInputPlayer::TryDisconnectSelectedController() {
const auto player_connected = ui->groupConnectedController->isChecked() &&
controller_type != Settings::ControllerType::Handheld;
+ // Disconnect Handheld depending on Player 1's controller configuration.
+ if (player_index == 0 && player.controller_type == Settings::ControllerType::Handheld) {
+ const auto& handheld = Settings::values.players.GetValue()[HANDHELD_INDEX];
+ const auto handheld_connected = ui->groupConnectedController->isChecked() &&
+ controller_type == Settings::ControllerType::Handheld;
+ // Disconnect only if handheld is going from connected to disconnected
+ if (handheld.connected && !handheld_connected) {
+ UpdateController(controller_type, HANDHELD_INDEX, false);
+ }
+ return;
+ }
+
// Do not do anything if the controller configuration has not changed.
if (player.controller_type == controller_type && player.connected == player_connected) {
return;
}
+ // Do not disconnect if the controller is already disconnected
+ if (!player.connected) {
+ return;
+ }
+
// Disconnect the controller first.
UpdateController(controller_type, player_index, false);
}