summaryrefslogtreecommitdiff
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() {
51 UNIMPLEMENTED(); 51 UNIMPLEMENTED();
52} 52}
53 53
54bool Stream::Flush() {
55 const bool had_buffers = !queued_buffers.empty();
56 while (!queued_buffers.empty()) {
57 queued_buffers.pop();
58 }
59 return had_buffers;
60}
61
54void Stream::SetVolume(float volume) { 62void Stream::SetVolume(float volume) {
55 game_volume = volume; 63 game_volume = volume;
56} 64}
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:
56 /// Queues a buffer into the audio stream, returns true on success 56 /// Queues a buffer into the audio stream, returns true on success
57 bool QueueBuffer(BufferPtr&& buffer); 57 bool QueueBuffer(BufferPtr&& buffer);
58 58
59 /// Flush audio buffers
60 bool Flush();
61
59 /// Returns true if the audio stream contains a buffer with the specified tag 62 /// Returns true if the audio stream contains a buffer with the specified tag
60 [[nodiscard]] bool ContainsBuffer(Buffer::Tag tag) const; 63 [[nodiscard]] bool ContainsBuffer(Buffer::Tag tag) const;
61 64
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
338 return 0; 338 return 0;
339} 339}
340 340
341bool HLERequestContext::CanReadBuffer(std::size_t buffer_index) const {
342 const bool is_buffer_a{BufferDescriptorA().size() > buffer_index &&
343 BufferDescriptorA()[buffer_index].Size()};
344
345 if (is_buffer_a) {
346 return BufferDescriptorA().size() > buffer_index;
347 } else {
348 return BufferDescriptorX().size() > buffer_index;
349 }
350}
351
352bool HLERequestContext::CanWriteBuffer(std::size_t buffer_index) const {
353 const bool is_buffer_b{BufferDescriptorB().size() > buffer_index &&
354 BufferDescriptorB()[buffer_index].Size()};
355
356 if (is_buffer_b) {
357 return BufferDescriptorB().size() > buffer_index;
358 } else {
359 return BufferDescriptorC().size() > buffer_index;
360 }
361}
362
341std::string HLERequestContext::Description() const { 363std::string HLERequestContext::Description() const {
342 if (!command_header) { 364 if (!command_header) {
343 return "No command header available"; 365 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:
207 /// Helper function to get the size of the output buffer 207 /// Helper function to get the size of the output buffer
208 std::size_t GetWriteBufferSize(std::size_t buffer_index = 0) const; 208 std::size_t GetWriteBufferSize(std::size_t buffer_index = 0) const;
209 209
210 /// Helper function to test whether the input buffer at buffer_index can be read
211 bool CanReadBuffer(std::size_t buffer_index = 0) const;
212
213 /// Helper function to test whether the output buffer at buffer_index can be written
214 bool CanWriteBuffer(std::size_t buffer_index = 0) const;
215
210 template <typename T> 216 template <typename T>
211 std::shared_ptr<T> GetCopyObject(std::size_t index) { 217 std::shared_ptr<T> GetCopyObject(std::size_t index) {
212 return DynamicObjectCast<T>(copy_objects.at(index)); 218 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:
58 {8, &IAudioOut::GetReleasedAudioOutBufferImpl, "GetReleasedAudioOutBufferAuto"}, 58 {8, &IAudioOut::GetReleasedAudioOutBufferImpl, "GetReleasedAudioOutBufferAuto"},
59 {9, &IAudioOut::GetAudioOutBufferCount, "GetAudioOutBufferCount"}, 59 {9, &IAudioOut::GetAudioOutBufferCount, "GetAudioOutBufferCount"},
60 {10, nullptr, "GetAudioOutPlayedSampleCount"}, 60 {10, nullptr, "GetAudioOutPlayedSampleCount"},
61 {11, nullptr, "FlushAudioOutBuffers"}, 61 {11, &IAudioOut::FlushAudioOutBuffers, "FlushAudioOutBuffers"},
62 {12, &IAudioOut::SetAudioOutVolume, "SetAudioOutVolume"}, 62 {12, &IAudioOut::SetAudioOutVolume, "SetAudioOutVolume"},
63 {13, &IAudioOut::GetAudioOutVolume, "GetAudioOutVolume"}, 63 {13, &IAudioOut::GetAudioOutVolume, "GetAudioOutVolume"},
64 }; 64 };
@@ -185,6 +185,14 @@ private:
185 rb.Push(static_cast<u32>(stream->GetQueueSize())); 185 rb.Push(static_cast<u32>(stream->GetQueueSize()));
186 } 186 }
187 187
188 void FlushAudioOutBuffers(Kernel::HLERequestContext& ctx) {
189 LOG_DEBUG(Service_Audio, "called");
190
191 IPC::ResponseBuilder rb{ctx, 3};
192 rb.Push(RESULT_SUCCESS);
193 rb.Push(stream->Flush());
194 }
195
188 void SetAudioOutVolume(Kernel::HLERequestContext& ctx) { 196 void SetAudioOutVolume(Kernel::HLERequestContext& ctx) {
189 IPC::RequestParser rp{ctx}; 197 IPC::RequestParser rp{ctx};
190 const float volume = rp.Pop<float>(); 198 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) {
946 sixaxis_sensors_enabled = six_axis_status; 946 sixaxis_sensors_enabled = six_axis_status;
947} 947}
948 948
949void Controller_NPad::SetSixAxisFusionParameters(const DeviceHandle& handle, f32 parameter1, 949void Controller_NPad::SetSixAxisFusionParameters(f32 parameter1, f32 parameter2) {
950 f32 parameter2) {
951 sixaxis_fusion_parameter1 = parameter1; 950 sixaxis_fusion_parameter1 = parameter1;
952 sixaxis_fusion_parameter2 = parameter2; 951 sixaxis_fusion_parameter2 = parameter2;
953} 952}
954 953
955std::pair<f32, f32> Controller_NPad::GetSixAxisFusionParameters(const DeviceHandle& handle) { 954std::pair<f32, f32> Controller_NPad::GetSixAxisFusionParameters() {
956 return { 955 return {
957 sixaxis_fusion_parameter1, 956 sixaxis_fusion_parameter1,
958 sixaxis_fusion_parameter2, 957 sixaxis_fusion_parameter2,
959 }; 958 };
960} 959}
961 960
962void Controller_NPad::ResetSixAxisFusionParameters(const DeviceHandle& handle) { 961void Controller_NPad::ResetSixAxisFusionParameters() {
963 sixaxis_fusion_parameter1 = 0.0f; 962 sixaxis_fusion_parameter1 = 0.0f;
964 sixaxis_fusion_parameter2 = 0.0f; 963 sixaxis_fusion_parameter2 = 0.0f;
965} 964}
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:
202 GyroscopeZeroDriftMode GetGyroscopeZeroDriftMode() const; 202 GyroscopeZeroDriftMode GetGyroscopeZeroDriftMode() const;
203 bool IsSixAxisSensorAtRest() const; 203 bool IsSixAxisSensorAtRest() const;
204 void SetSixAxisEnabled(bool six_axis_status); 204 void SetSixAxisEnabled(bool six_axis_status);
205 void SetSixAxisFusionParameters(const DeviceHandle& handle, f32 parameter1, f32 parameter2); 205 void SetSixAxisFusionParameters(f32 parameter1, f32 parameter2);
206 std::pair<f32, f32> GetSixAxisFusionParameters(const DeviceHandle& handle); 206 std::pair<f32, f32> GetSixAxisFusionParameters();
207 void ResetSixAxisFusionParameters(const DeviceHandle& handle); 207 void ResetSixAxisFusionParameters();
208 LedPattern GetLedPattern(u32 npad_id); 208 LedPattern GetLedPattern(u32 npad_id);
209 bool IsUnintendedHomeButtonInputProtectionEnabled(u32 npad_id) const; 209 bool IsUnintendedHomeButtonInputProtectionEnabled(u32 npad_id) const;
210 void SetUnintendedHomeButtonInputProtectionEnabled(bool is_protection_enabled, u32 npad_id); 210 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) {
520 Controller_NPad::DeviceHandle sixaxis_handle; 520 Controller_NPad::DeviceHandle sixaxis_handle;
521 u64 applet_resource_user_id; 521 u64 applet_resource_user_id;
522 }; 522 };
523 static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
523 524
524 const auto parameters{rp.PopRaw<Parameters>()}; 525 const auto parameters{rp.PopRaw<Parameters>()};
525 526
@@ -542,19 +543,19 @@ void Hid::SetSixAxisSensorFusionParameters(Kernel::HLERequestContext& ctx) {
542 f32 parameter2; 543 f32 parameter2;
543 u64 applet_resource_user_id; 544 u64 applet_resource_user_id;
544 }; 545 };
546 static_assert(sizeof(Parameters) == 0x18, "Parameters has incorrect size.");
545 547
546 const auto parameters{rp.PopRaw<Parameters>()}; 548 const auto parameters{rp.PopRaw<Parameters>()};
547 549
548 applet_resource->GetController<Controller_NPad>(HidController::NPad) 550 applet_resource->GetController<Controller_NPad>(HidController::NPad)
549 .SetSixAxisFusionParameters(parameters.sixaxis_handle, parameters.parameter1, 551 .SetSixAxisFusionParameters(parameters.parameter1, parameters.parameter2);
550 parameters.parameter2);
551 552
552 LOG_WARNING(Service_HID, 553 LOG_WARNING(Service_HID,
553 "(STUBBED) called, float1={}, float2={}, npad_type={}, npad_id={}, " 554 "(STUBBED) called, npad_type={}, npad_id={}, device_index={}, parameter1={}, "
554 "device_index={}, applet_resource_user_id={}", 555 "parameter2={}, applet_resource_user_id={}",
555 parameters.parameter1, parameters.parameter2, parameters.sixaxis_handle.npad_type, 556 parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id,
556 parameters.sixaxis_handle.npad_id, parameters.sixaxis_handle.device_index, 557 parameters.sixaxis_handle.device_index, parameters.parameter1,
557 parameters.applet_resource_user_id); 558 parameters.parameter2, parameters.applet_resource_user_id);
558 559
559 IPC::ResponseBuilder rb{ctx, 2}; 560 IPC::ResponseBuilder rb{ctx, 2};
560 rb.Push(RESULT_SUCCESS); 561 rb.Push(RESULT_SUCCESS);
@@ -566,6 +567,7 @@ void Hid::GetSixAxisSensorFusionParameters(Kernel::HLERequestContext& ctx) {
566 Controller_NPad::DeviceHandle sixaxis_handle; 567 Controller_NPad::DeviceHandle sixaxis_handle;
567 u64 applet_resource_user_id; 568 u64 applet_resource_user_id;
568 }; 569 };
570 static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
569 571
570 f32 parameter1 = 0; 572 f32 parameter1 = 0;
571 f32 parameter2 = 0; 573 f32 parameter2 = 0;
@@ -573,13 +575,13 @@ void Hid::GetSixAxisSensorFusionParameters(Kernel::HLERequestContext& ctx) {
573 575
574 std::tie(parameter1, parameter2) = 576 std::tie(parameter1, parameter2) =
575 applet_resource->GetController<Controller_NPad>(HidController::NPad) 577 applet_resource->GetController<Controller_NPad>(HidController::NPad)
576 .GetSixAxisFusionParameters(parameters.sixaxis_handle); 578 .GetSixAxisFusionParameters();
577 579
578 LOG_WARNING(Service_HID, 580 LOG_WARNING(
579 "(STUBBED) called, npad_type={}, npad_id={}, " 581 Service_HID,
580 "device_index={}, applet_resource_user_id={}", 582 "(STUBBED) called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
581 parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id, 583 parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id,
582 parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id); 584 parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id);
583 585
584 IPC::ResponseBuilder rb{ctx, 4}; 586 IPC::ResponseBuilder rb{ctx, 4};
585 rb.Push(RESULT_SUCCESS); 587 rb.Push(RESULT_SUCCESS);
@@ -593,17 +595,18 @@ void Hid::ResetSixAxisSensorFusionParameters(Kernel::HLERequestContext& ctx) {
593 Controller_NPad::DeviceHandle sixaxis_handle; 595 Controller_NPad::DeviceHandle sixaxis_handle;
594 u64 applet_resource_user_id; 596 u64 applet_resource_user_id;
595 }; 597 };
598 static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
596 599
597 const auto parameters{rp.PopRaw<Parameters>()}; 600 const auto parameters{rp.PopRaw<Parameters>()};
598 601
599 applet_resource->GetController<Controller_NPad>(HidController::NPad) 602 applet_resource->GetController<Controller_NPad>(HidController::NPad)
600 .ResetSixAxisFusionParameters(parameters.sixaxis_handle); 603 .ResetSixAxisFusionParameters();
601 604
602 LOG_WARNING(Service_HID, 605 LOG_WARNING(
603 "(STUBBED) called, npad_type={}, npad_id={}, " 606 Service_HID,
604 "device_index={}, applet_resource_user_id={}", 607 "(STUBBED) called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
605 parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id, 608 parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id,
606 parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id); 609 parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id);
607 610
608 IPC::ResponseBuilder rb{ctx, 2}; 611 IPC::ResponseBuilder rb{ctx, 2};
609 rb.Push(RESULT_SUCCESS); 612 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:
23 {10101, &PlayReport::SaveReportWithUser<Core::Reporter::PlayReportType::Old>, "SaveReportWithUserOld"}, 23 {10101, &PlayReport::SaveReportWithUser<Core::Reporter::PlayReportType::Old>, "SaveReportWithUserOld"},
24 {10102, &PlayReport::SaveReport<Core::Reporter::PlayReportType::Old2>, "SaveReportOld2"}, 24 {10102, &PlayReport::SaveReport<Core::Reporter::PlayReportType::Old2>, "SaveReportOld2"},
25 {10103, &PlayReport::SaveReportWithUser<Core::Reporter::PlayReportType::Old2>, "SaveReportWithUserOld2"}, 25 {10103, &PlayReport::SaveReportWithUser<Core::Reporter::PlayReportType::Old2>, "SaveReportWithUserOld2"},
26 {10104, nullptr, "SaveReport"}, 26 {10104, &PlayReport::SaveReport<Core::Reporter::PlayReportType::New>, "SaveReport"},
27 {10105, nullptr, "SaveReportWithUser"}, 27 {10105, &PlayReport::SaveReportWithUser<Core::Reporter::PlayReportType::New>, "SaveReportWithUser"},
28 {10200, nullptr, "RequestImmediateTransmission"}, 28 {10200, nullptr, "RequestImmediateTransmission"},
29 {10300, nullptr, "GetTransmissionStatus"}, 29 {10300, nullptr, "GetTransmissionStatus"},
30 {10400, &PlayReport::GetSystemSessionId, "GetSystemSessionId"}, 30 {10400, &PlayReport::GetSystemSessionId, "GetSystemSessionId"},
@@ -59,16 +59,22 @@ private:
59 IPC::RequestParser rp{ctx}; 59 IPC::RequestParser rp{ctx};
60 const auto process_id = rp.PopRaw<u64>(); 60 const auto process_id = rp.PopRaw<u64>();
61 61
62 std::vector<std::vector<u8>> data{ctx.ReadBuffer(0)}; 62 const auto data1 = ctx.ReadBuffer(0);
63 if constexpr (Type == Core::Reporter::PlayReportType::Old2) { 63 const auto data2 = [ctx] {
64 data.emplace_back(ctx.ReadBuffer(1)); 64 if (ctx.CanReadBuffer(1)) {
65 } 65 return ctx.ReadBuffer(1);
66 }
67
68 return std::vector<u8>{};
69 }();
66 70
67 LOG_DEBUG(Service_PREPO, "called, type={:02X}, process_id={:016X}, data1_size={:016X}", 71 LOG_DEBUG(Service_PREPO,
68 Type, process_id, data[0].size()); 72 "called, type={:02X}, process_id={:016X}, data1_size={:016X}, data2_size={:016X}",
73 Type, process_id, data1.size(), data2.size());
69 74
70 const auto& reporter{system.GetReporter()}; 75 const auto& reporter{system.GetReporter()};
71 reporter.SavePlayReport(Type, system.CurrentProcess()->GetTitleID(), data, process_id); 76 reporter.SavePlayReport(Type, system.CurrentProcess()->GetTitleID(), {data1, data2},
77 process_id);
72 78
73 IPC::ResponseBuilder rb{ctx, 2}; 79 IPC::ResponseBuilder rb{ctx, 2};
74 rb.Push(RESULT_SUCCESS); 80 rb.Push(RESULT_SUCCESS);
@@ -79,24 +85,24 @@ private:
79 IPC::RequestParser rp{ctx}; 85 IPC::RequestParser rp{ctx};
80 const auto user_id = rp.PopRaw<u128>(); 86 const auto user_id = rp.PopRaw<u128>();
81 const auto process_id = rp.PopRaw<u64>(); 87 const auto process_id = rp.PopRaw<u64>();
82 std::vector<std::vector<u8>> data{ctx.ReadBuffer(0)};
83 88
84 if constexpr (Type == Core::Reporter::PlayReportType::Old2) { 89 const auto data1 = ctx.ReadBuffer(0);
85 const auto read_buffer_count = 90 const auto data2 = [ctx] {
86 ctx.BufferDescriptorX().size() + ctx.BufferDescriptorA().size(); 91 if (ctx.CanReadBuffer(1)) {
87 if (read_buffer_count > 1) { 92 return ctx.ReadBuffer(1);
88 data.emplace_back(ctx.ReadBuffer(1));
89 } 93 }
90 }
91 94
92 LOG_DEBUG( 95 return std::vector<u8>{};
93 Service_PREPO, 96 }();
94 "called, type={:02X}, user_id={:016X}{:016X}, process_id={:016X}, data1_size={:016X}", 97
95 Type, user_id[1], user_id[0], process_id, data[0].size()); 98 LOG_DEBUG(Service_PREPO,
99 "called, type={:02X}, user_id={:016X}{:016X}, process_id={:016X}, "
100 "data1_size={:016X}, data2_size={:016X}",
101 Type, user_id[1], user_id[0], process_id, data1.size(), data2.size());
96 102
97 const auto& reporter{system.GetReporter()}; 103 const auto& reporter{system.GetReporter()};
98 reporter.SavePlayReport(Type, system.CurrentProcess()->GetTitleID(), data, process_id, 104 reporter.SavePlayReport(Type, system.CurrentProcess()->GetTitleID(), {data1, data2},
99 user_id); 105 process_id, user_id);
100 106
101 IPC::ResponseBuilder rb{ctx, 2}; 107 IPC::ResponseBuilder rb{ctx, 2};
102 rb.Push(RESULT_SUCCESS); 108 rb.Push(RESULT_SUCCESS);
@@ -116,7 +122,13 @@ private:
116 const auto title_id = rp.PopRaw<u64>(); 122 const auto title_id = rp.PopRaw<u64>();
117 123
118 const auto data1 = ctx.ReadBuffer(0); 124 const auto data1 = ctx.ReadBuffer(0);
119 const auto data2 = ctx.ReadBuffer(1); 125 const auto data2 = [ctx] {
126 if (ctx.CanReadBuffer(1)) {
127 return ctx.ReadBuffer(1);
128 }
129
130 return std::vector<u8>{};
131 }();
120 132
121 LOG_DEBUG(Service_PREPO, "called, title_id={:016X}, data1_size={:016X}, data2_size={:016X}", 133 LOG_DEBUG(Service_PREPO, "called, title_id={:016X}, data1_size={:016X}, data2_size={:016X}",
122 title_id, data1.size(), data2.size()); 134 title_id, data1.size(), data2.size());
@@ -134,7 +146,13 @@ private:
134 const auto title_id = rp.PopRaw<u64>(); 146 const auto title_id = rp.PopRaw<u64>();
135 147
136 const auto data1 = ctx.ReadBuffer(0); 148 const auto data1 = ctx.ReadBuffer(0);
137 const auto data2 = ctx.ReadBuffer(1); 149 const auto data2 = [ctx] {
150 if (ctx.CanReadBuffer(1)) {
151 return ctx.ReadBuffer(1);
152 }
153
154 return std::vector<u8>{};
155 }();
138 156
139 LOG_DEBUG(Service_PREPO, 157 LOG_DEBUG(Service_PREPO,
140 "called, user_id={:016X}{:016X}, title_id={:016X}, data1_size={:016X}, " 158 "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) {
255 rb.Push<u32>(static_cast<u32>(write_buffer.size())); 255 rb.Push<u32>(static_cast<u32>(write_buffer.size()));
256} 256}
257 257
258void BSD::GetSockOpt(Kernel::HLERequestContext& ctx) {
259 IPC::RequestParser rp{ctx};
260 const s32 fd = rp.Pop<s32>();
261 const u32 level = rp.Pop<u32>();
262 const auto optname = static_cast<OptName>(rp.Pop<u32>());
263
264 LOG_WARNING(Service, "(STUBBED) called. fd={} level={} optname=0x{:x}", fd, level, optname);
265
266 IPC::ResponseBuilder rb{ctx, 5};
267 rb.Push(RESULT_SUCCESS);
268 rb.Push<s32>(-1);
269 rb.PushEnum(Errno::NOTCONN);
270 rb.Push<u32>(0);
271}
272
258void BSD::Listen(Kernel::HLERequestContext& ctx) { 273void BSD::Listen(Kernel::HLERequestContext& ctx) {
259 IPC::RequestParser rp{ctx}; 274 IPC::RequestParser rp{ctx};
260 const s32 fd = rp.Pop<s32>(); 275 const s32 fd = rp.Pop<s32>();
@@ -812,7 +827,7 @@ BSD::BSD(Core::System& system_, const char* name) : ServiceFramework{system_, na
812 {14, &BSD::Connect, "Connect"}, 827 {14, &BSD::Connect, "Connect"},
813 {15, &BSD::GetPeerName, "GetPeerName"}, 828 {15, &BSD::GetPeerName, "GetPeerName"},
814 {16, &BSD::GetSockName, "GetSockName"}, 829 {16, &BSD::GetSockName, "GetSockName"},
815 {17, nullptr, "GetSockOpt"}, 830 {17, &BSD::GetSockOpt, "GetSockOpt"},
816 {18, &BSD::Listen, "Listen"}, 831 {18, &BSD::Listen, "Listen"},
817 {19, nullptr, "Ioctl"}, 832 {19, nullptr, "Ioctl"},
818 {20, &BSD::Fcntl, "Fcntl"}, 833 {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:
125 void Connect(Kernel::HLERequestContext& ctx); 125 void Connect(Kernel::HLERequestContext& ctx);
126 void GetPeerName(Kernel::HLERequestContext& ctx); 126 void GetPeerName(Kernel::HLERequestContext& ctx);
127 void GetSockName(Kernel::HLERequestContext& ctx); 127 void GetSockName(Kernel::HLERequestContext& ctx);
128 void GetSockOpt(Kernel::HLERequestContext& ctx);
128 void Listen(Kernel::HLERequestContext& ctx); 129 void Listen(Kernel::HLERequestContext& ctx);
129 void Fcntl(Kernel::HLERequestContext& ctx); 130 void Fcntl(Kernel::HLERequestContext& ctx);
130 void SetSockOpt(Kernel::HLERequestContext& ctx); 131 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 @@
6 6
7#include <atomic> 7#include <atomic>
8#include <condition_variable> 8#include <condition_variable>
9#include <cstddef>
9#include <memory> 10#include <memory>
10#include <stack> 11#include <stack>
11#include <thread> 12#include <thread>
12#include <utility> 13#include <utility>
14#include "common/alignment.h"
13#include "common/common_types.h" 15#include "common/common_types.h"
14#include "common/threadsafe_queue.h" 16#include "common/threadsafe_queue.h"
15#include "video_core/vulkan_common/vulkan_wrapper.h" 17#include "video_core/vulkan_common/vulkan_wrapper.h"
@@ -130,12 +132,11 @@ private:
130 using FuncType = TypedCommand<T>; 132 using FuncType = TypedCommand<T>;
131 static_assert(sizeof(FuncType) < sizeof(data), "Lambda is too large"); 133 static_assert(sizeof(FuncType) < sizeof(data), "Lambda is too large");
132 134
135 command_offset = Common::AlignUp(command_offset, alignof(FuncType));
133 if (command_offset > sizeof(data) - sizeof(FuncType)) { 136 if (command_offset > sizeof(data) - sizeof(FuncType)) {
134 return false; 137 return false;
135 } 138 }
136 139 Command* const current_last = last;
137 Command* current_last = last;
138
139 last = new (data.data() + command_offset) FuncType(std::move(command)); 140 last = new (data.data() + command_offset) FuncType(std::move(command));
140 141
141 if (current_last) { 142 if (current_last) {
@@ -143,7 +144,6 @@ private:
143 } else { 144 } else {
144 first = last; 145 first = last;
145 } 146 }
146
147 command_offset += sizeof(FuncType); 147 command_offset += sizeof(FuncType);
148 return true; 148 return true;
149 } 149 }
@@ -156,8 +156,8 @@ private:
156 Command* first = nullptr; 156 Command* first = nullptr;
157 Command* last = nullptr; 157 Command* last = nullptr;
158 158
159 std::size_t command_offset = 0; 159 size_t command_offset = 0;
160 std::array<u8, 0x8000> data{}; 160 alignas(std::max_align_t) std::array<u8, 0x8000> data{};
161 }; 161 };
162 162
163 struct State { 163 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() {
190 // This emulates a delay between disconnecting and reconnecting controllers as some games 190 // This emulates a delay between disconnecting and reconnecting controllers as some games
191 // do not respond to a change in controller type if it was instantaneous. 191 // do not respond to a change in controller type if it was instantaneous.
192 using namespace std::chrono_literals; 192 using namespace std::chrono_literals;
193 std::this_thread::sleep_for(60ms); 193 std::this_thread::sleep_for(150ms);
194 194
195 for (auto* controller : player_controllers) { 195 for (auto* controller : player_controllers) {
196 controller->TryConnectSelectedController(); 196 controller->TryConnectSelectedController();
197 } 197 }
198 198
199 // This emulates a delay between disconnecting and reconnecting controllers as some games
200 // do not respond to a change in controller type if it was instantaneous.
201 std::this_thread::sleep_for(150ms);
202
199 advanced->ApplyConfiguration(); 203 advanced->ApplyConfiguration();
200 204
201 const bool pre_docked_mode = Settings::values.use_docked_mode.GetValue(); 205 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() {
579 // Apply configuration for handheld 579 // Apply configuration for handheld
580 if (player_index == 0) { 580 if (player_index == 0) {
581 auto& handheld = Settings::values.players.GetValue()[HANDHELD_INDEX]; 581 auto& handheld = Settings::values.players.GetValue()[HANDHELD_INDEX];
582 const auto handheld_connected = handheld.connected;
582 if (player.controller_type == Settings::ControllerType::Handheld) { 583 if (player.controller_type == Settings::ControllerType::Handheld) {
583 handheld = player; 584 handheld = player;
584 } 585 }
585 handheld.connected = ui->groupConnectedController->isChecked() && 586 handheld.connected = handheld_connected;
586 player.controller_type == Settings::ControllerType::Handheld;
587 } 587 }
588} 588}
589 589
@@ -595,6 +595,18 @@ void ConfigureInputPlayer::TryConnectSelectedController() {
595 const auto player_connected = ui->groupConnectedController->isChecked() && 595 const auto player_connected = ui->groupConnectedController->isChecked() &&
596 controller_type != Settings::ControllerType::Handheld; 596 controller_type != Settings::ControllerType::Handheld;
597 597
598 // Connect Handheld depending on Player 1's controller configuration.
599 if (player_index == 0 && controller_type == Settings::ControllerType::Handheld) {
600 auto& handheld = Settings::values.players.GetValue()[HANDHELD_INDEX];
601 const auto handheld_connected = ui->groupConnectedController->isChecked() &&
602 controller_type == Settings::ControllerType::Handheld;
603 // Connect only if handheld is going from disconnected to connected
604 if (!handheld.connected && handheld_connected) {
605 UpdateController(controller_type, HANDHELD_INDEX, true);
606 }
607 handheld.connected = handheld_connected;
608 }
609
598 if (player.controller_type == controller_type && player.connected == player_connected) { 610 if (player.controller_type == controller_type && player.connected == player_connected) {
599 // Set vibration devices in the event that the input device has changed. 611 // Set vibration devices in the event that the input device has changed.
600 ConfigureVibration::SetVibrationDevices(player_index); 612 ConfigureVibration::SetVibrationDevices(player_index);
@@ -606,22 +618,11 @@ void ConfigureInputPlayer::TryConnectSelectedController() {
606 618
607 ConfigureVibration::SetVibrationDevices(player_index); 619 ConfigureVibration::SetVibrationDevices(player_index);
608 620
609 // Connect/Disconnect Handheld depending on Player 1's controller configuration.
610 if (player_index == 0) {
611 auto& handheld = Settings::values.players.GetValue()[HANDHELD_INDEX];
612 if (controller_type == Settings::ControllerType::Handheld) {
613 handheld = player;
614 }
615 handheld.connected = ui->groupConnectedController->isChecked() &&
616 controller_type == Settings::ControllerType::Handheld;
617 UpdateController(Settings::ControllerType::Handheld, HANDHELD_INDEX, handheld.connected);
618 }
619
620 if (!player.connected) { 621 if (!player.connected) {
621 return; 622 return;
622 } 623 }
623 624
624 UpdateController(controller_type, player_index, player_connected); 625 UpdateController(controller_type, player_index, true);
625} 626}
626 627
627void ConfigureInputPlayer::TryDisconnectSelectedController() { 628void ConfigureInputPlayer::TryDisconnectSelectedController() {
@@ -632,11 +633,28 @@ void ConfigureInputPlayer::TryDisconnectSelectedController() {
632 const auto player_connected = ui->groupConnectedController->isChecked() && 633 const auto player_connected = ui->groupConnectedController->isChecked() &&
633 controller_type != Settings::ControllerType::Handheld; 634 controller_type != Settings::ControllerType::Handheld;
634 635
636 // Disconnect Handheld depending on Player 1's controller configuration.
637 if (player_index == 0 && player.controller_type == Settings::ControllerType::Handheld) {
638 const auto& handheld = Settings::values.players.GetValue()[HANDHELD_INDEX];
639 const auto handheld_connected = ui->groupConnectedController->isChecked() &&
640 controller_type == Settings::ControllerType::Handheld;
641 // Disconnect only if handheld is going from connected to disconnected
642 if (handheld.connected && !handheld_connected) {
643 UpdateController(controller_type, HANDHELD_INDEX, false);
644 }
645 return;
646 }
647
635 // Do not do anything if the controller configuration has not changed. 648 // Do not do anything if the controller configuration has not changed.
636 if (player.controller_type == controller_type && player.connected == player_connected) { 649 if (player.controller_type == controller_type && player.connected == player_connected) {
637 return; 650 return;
638 } 651 }
639 652
653 // Do not disconnect if the controller is already disconnected
654 if (!player.connected) {
655 return;
656 }
657
640 // Disconnect the controller first. 658 // Disconnect the controller first.
641 UpdateController(controller_type, player_index, false); 659 UpdateController(controller_type, player_index, false);
642} 660}