summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/audio_core/CMakeLists.txt10
-rw-r--r--src/audio_core/audio_renderer.cpp5
-rw-r--r--src/audio_core/audio_renderer.h1
-rw-r--r--src/audio_core/behavior_info.cpp6
-rw-r--r--src/audio_core/behavior_info.h6
-rw-r--r--src/audio_core/codec.cpp5
-rw-r--r--src/audio_core/codec.h2
-rw-r--r--src/audio_core/command_generator.cpp17
-rw-r--r--src/audio_core/command_generator.h1
-rw-r--r--src/audio_core/common.h1
-rw-r--r--src/audio_core/cubeb_sink.cpp4
-rw-r--r--src/audio_core/effect_context.cpp8
-rw-r--r--src/audio_core/effect_context.h33
-rw-r--r--src/audio_core/info_updater.cpp7
-rw-r--r--src/audio_core/mix_context.cpp4
-rw-r--r--src/audio_core/splitter_context.cpp6
-rw-r--r--src/audio_core/stream.cpp1
-rw-r--r--src/audio_core/voice_context.cpp4
-rw-r--r--src/common/CMakeLists.txt7
-rw-r--r--src/common/wall_clock.cpp2
-rw-r--r--src/common/wall_clock.h2
-rw-r--r--src/common/x64/native_clock.h2
-rw-r--r--src/core/core.h2
-rw-r--r--src/core/file_sys/submission_package.cpp25
-rw-r--r--src/core/frontend/applets/controller.cpp8
-rw-r--r--src/core/frontend/applets/controller.h8
-rw-r--r--src/core/frontend/input.h3
-rw-r--r--src/core/hle/service/am/applets/applets.cpp3
-rw-r--r--src/core/hle/service/caps/caps_c.cpp16
-rw-r--r--src/core/hle/service/caps/caps_c.h3
-rw-r--r--src/core/hle/service/caps/caps_su.cpp7
-rw-r--r--src/core/hle/service/caps/caps_u.cpp15
-rw-r--r--src/core/hle/service/caps/caps_u.h1
-rw-r--r--src/core/hle/service/hid/controllers/controller_base.h4
-rw-r--r--src/core/hle/service/hid/controllers/npad.cpp343
-rw-r--r--src/core/hle/service/hid/controllers/npad.h9
-rw-r--r--src/core/hle/service/hid/hid.cpp82
-rw-r--r--src/core/hle/service/hid/hid.h5
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp70
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_nvdec.h52
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_vic.cpp74
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_vic.h63
-rw-r--r--src/input_common/sdl/sdl_impl.cpp39
-rw-r--r--src/input_common/udp/client.cpp8
-rw-r--r--src/video_core/renderer_vulkan/vk_command_pool.cpp5
-rw-r--r--src/video_core/renderer_vulkan/vk_command_pool.h9
-rw-r--r--src/video_core/renderer_vulkan/vk_device.cpp8
-rw-r--r--src/video_core/renderer_vulkan/vk_stream_buffer.cpp3
-rw-r--r--src/video_core/renderer_vulkan/wrapper.cpp48
-rw-r--r--src/video_core/shader/registry.cpp50
-rw-r--r--src/video_core/shader/registry.h2
-rw-r--r--src/yuzu/game_list.cpp5
-rw-r--r--src/yuzu/game_list_p.h2
-rw-r--r--src/yuzu/main.cpp14
54 files changed, 837 insertions, 283 deletions
diff --git a/src/audio_core/CMakeLists.txt b/src/audio_core/CMakeLists.txt
index cb00ef60e..6a7075f73 100644
--- a/src/audio_core/CMakeLists.txt
+++ b/src/audio_core/CMakeLists.txt
@@ -44,6 +44,16 @@ add_library(audio_core STATIC
44 44
45create_target_directory_groups(audio_core) 45create_target_directory_groups(audio_core)
46 46
47if (NOT MSVC)
48 target_compile_options(audio_core PRIVATE
49 -Werror=ignored-qualifiers
50 -Werror=implicit-fallthrough
51 -Werror=reorder
52 -Werror=sign-compare
53 -Werror=unused-variable
54 )
55endif()
56
47target_link_libraries(audio_core PUBLIC common core) 57target_link_libraries(audio_core PUBLIC common core)
48target_link_libraries(audio_core PRIVATE SoundTouch) 58target_link_libraries(audio_core PRIVATE SoundTouch)
49 59
diff --git a/src/audio_core/audio_renderer.cpp b/src/audio_core/audio_renderer.cpp
index 56dc892b1..a7e851bb8 100644
--- a/src/audio_core/audio_renderer.cpp
+++ b/src/audio_core/audio_renderer.cpp
@@ -3,16 +3,13 @@
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include <vector> 5#include <vector>
6#include "audio_core/algorithm/interpolate.h" 6
7#include "audio_core/audio_out.h" 7#include "audio_core/audio_out.h"
8#include "audio_core/audio_renderer.h" 8#include "audio_core/audio_renderer.h"
9#include "audio_core/codec.h"
10#include "audio_core/common.h" 9#include "audio_core/common.h"
11#include "audio_core/info_updater.h" 10#include "audio_core/info_updater.h"
12#include "audio_core/voice_context.h" 11#include "audio_core/voice_context.h"
13#include "common/assert.h"
14#include "common/logging/log.h" 12#include "common/logging/log.h"
15#include "core/core.h"
16#include "core/hle/kernel/writable_event.h" 13#include "core/hle/kernel/writable_event.h"
17#include "core/memory.h" 14#include "core/memory.h"
18#include "core/settings.h" 15#include "core/settings.h"
diff --git a/src/audio_core/audio_renderer.h b/src/audio_core/audio_renderer.h
index 2bca795ba..2fd93e058 100644
--- a/src/audio_core/audio_renderer.h
+++ b/src/audio_core/audio_renderer.h
@@ -21,7 +21,6 @@
21#include "common/common_funcs.h" 21#include "common/common_funcs.h"
22#include "common/common_types.h" 22#include "common/common_types.h"
23#include "common/swap.h" 23#include "common/swap.h"
24#include "core/hle/kernel/object.h"
25#include "core/hle/result.h" 24#include "core/hle/result.h"
26 25
27namespace Core::Timing { 26namespace Core::Timing {
diff --git a/src/audio_core/behavior_info.cpp b/src/audio_core/behavior_info.cpp
index 5d62adb0b..3c2e3e6f1 100644
--- a/src/audio_core/behavior_info.cpp
+++ b/src/audio_core/behavior_info.cpp
@@ -57,15 +57,15 @@ bool BehaviorInfo::IsLongSizePreDelaySupported() const {
57 return AudioCommon::IsRevisionSupported(3, user_revision); 57 return AudioCommon::IsRevisionSupported(3, user_revision);
58} 58}
59 59
60bool BehaviorInfo::IsAudioRenererProcessingTimeLimit80PercentSupported() const { 60bool BehaviorInfo::IsAudioRendererProcessingTimeLimit80PercentSupported() const {
61 return AudioCommon::IsRevisionSupported(5, user_revision); 61 return AudioCommon::IsRevisionSupported(5, user_revision);
62} 62}
63 63
64bool BehaviorInfo::IsAudioRenererProcessingTimeLimit75PercentSupported() const { 64bool BehaviorInfo::IsAudioRendererProcessingTimeLimit75PercentSupported() const {
65 return AudioCommon::IsRevisionSupported(4, user_revision); 65 return AudioCommon::IsRevisionSupported(4, user_revision);
66} 66}
67 67
68bool BehaviorInfo::IsAudioRenererProcessingTimeLimit70PercentSupported() const { 68bool BehaviorInfo::IsAudioRendererProcessingTimeLimit70PercentSupported() const {
69 return AudioCommon::IsRevisionSupported(1, user_revision); 69 return AudioCommon::IsRevisionSupported(1, user_revision);
70} 70}
71 71
diff --git a/src/audio_core/behavior_info.h b/src/audio_core/behavior_info.h
index 50948e8df..512a4ebe3 100644
--- a/src/audio_core/behavior_info.h
+++ b/src/audio_core/behavior_info.h
@@ -49,9 +49,9 @@ public:
49 bool IsAdpcmLoopContextBugFixed() const; 49 bool IsAdpcmLoopContextBugFixed() const;
50 bool IsSplitterSupported() const; 50 bool IsSplitterSupported() const;
51 bool IsLongSizePreDelaySupported() const; 51 bool IsLongSizePreDelaySupported() const;
52 bool IsAudioRenererProcessingTimeLimit80PercentSupported() const; 52 bool IsAudioRendererProcessingTimeLimit80PercentSupported() const;
53 bool IsAudioRenererProcessingTimeLimit75PercentSupported() const; 53 bool IsAudioRendererProcessingTimeLimit75PercentSupported() const;
54 bool IsAudioRenererProcessingTimeLimit70PercentSupported() const; 54 bool IsAudioRendererProcessingTimeLimit70PercentSupported() const;
55 bool IsElapsedFrameCountSupported() const; 55 bool IsElapsedFrameCountSupported() const;
56 bool IsMemoryPoolForceMappingEnabled() const; 56 bool IsMemoryPoolForceMappingEnabled() const;
57 bool IsFlushVoiceWaveBuffersSupported() const; 57 bool IsFlushVoiceWaveBuffersSupported() const;
diff --git a/src/audio_core/codec.cpp b/src/audio_core/codec.cpp
index c5a0d98ce..2fb91c13a 100644
--- a/src/audio_core/codec.cpp
+++ b/src/audio_core/codec.cpp
@@ -16,8 +16,9 @@ std::vector<s16> DecodeADPCM(const u8* const data, std::size_t size, const ADPCM
16 16
17 constexpr std::size_t FRAME_LEN = 8; 17 constexpr std::size_t FRAME_LEN = 8;
18 constexpr std::size_t SAMPLES_PER_FRAME = 14; 18 constexpr std::size_t SAMPLES_PER_FRAME = 14;
19 constexpr std::array<int, 16> SIGNED_NIBBLES = { 19 static constexpr std::array<int, 16> SIGNED_NIBBLES{
20 {0, 1, 2, 3, 4, 5, 6, 7, -8, -7, -6, -5, -4, -3, -2, -1}}; 20 0, 1, 2, 3, 4, 5, 6, 7, -8, -7, -6, -5, -4, -3, -2, -1,
21 };
21 22
22 const std::size_t sample_count = (size / FRAME_LEN) * SAMPLES_PER_FRAME; 23 const std::size_t sample_count = (size / FRAME_LEN) * SAMPLES_PER_FRAME;
23 const std::size_t ret_size = 24 const std::size_t ret_size =
diff --git a/src/audio_core/codec.h b/src/audio_core/codec.h
index ef2ce01a8..9507abb1b 100644
--- a/src/audio_core/codec.h
+++ b/src/audio_core/codec.h
@@ -38,7 +38,7 @@ using ADPCM_Coeff = std::array<s16, 16>;
38 * @param state ADPCM state, this is updated with new state 38 * @param state ADPCM state, this is updated with new state
39 * @return Decoded stereo signed PCM16 data, sample_count in length 39 * @return Decoded stereo signed PCM16 data, sample_count in length
40 */ 40 */
41std::vector<s16> DecodeADPCM(const u8* const data, std::size_t size, const ADPCM_Coeff& coeff, 41std::vector<s16> DecodeADPCM(const u8* data, std::size_t size, const ADPCM_Coeff& coeff,
42 ADPCMState& state); 42 ADPCMState& state);
43 43
44}; // namespace AudioCore::Codec 44}; // namespace AudioCore::Codec
diff --git a/src/audio_core/command_generator.cpp b/src/audio_core/command_generator.cpp
index 8f7da49e6..bba40d13d 100644
--- a/src/audio_core/command_generator.cpp
+++ b/src/audio_core/command_generator.cpp
@@ -152,7 +152,7 @@ void CommandGenerator::GenerateVoiceCommand(ServerVoiceInfo& voice_info) {
152 if (!destination_data->IsConfigured()) { 152 if (!destination_data->IsConfigured()) {
153 continue; 153 continue;
154 } 154 }
155 if (destination_data->GetMixId() >= mix_context.GetCount()) { 155 if (destination_data->GetMixId() >= static_cast<int>(mix_context.GetCount())) {
156 continue; 156 continue;
157 } 157 }
158 158
@@ -435,7 +435,7 @@ void CommandGenerator::GenerateAuxCommand(s32 mix_buffer_offset, EffectBase* inf
435 GetMixBuffer(output_index), worker_params.sample_count, offset, write_count); 435 GetMixBuffer(output_index), worker_params.sample_count, offset, write_count);
436 memory.WriteBlock(aux->GetRecvInfo(), &recv_info, sizeof(AuxInfoDSP)); 436 memory.WriteBlock(aux->GetRecvInfo(), &recv_info, sizeof(AuxInfoDSP));
437 437
438 if (samples_read != worker_params.sample_count && 438 if (samples_read != static_cast<int>(worker_params.sample_count) &&
439 samples_read <= params.sample_count) { 439 samples_read <= params.sample_count) {
440 std::memset(GetMixBuffer(output_index), 0, params.sample_count - samples_read); 440 std::memset(GetMixBuffer(output_index), 0, params.sample_count - samples_read);
441 } 441 }
@@ -611,7 +611,8 @@ void CommandGenerator::GenerateMixCommands(ServerMixInfo& mix_info) {
611 const auto& dest_mix = mix_context.GetInfo(destination_data->GetMixId()); 611 const auto& dest_mix = mix_context.GetInfo(destination_data->GetMixId());
612 const auto& dest_in_params = dest_mix.GetInParams(); 612 const auto& dest_in_params = dest_mix.GetInParams();
613 const auto mix_index = (base - 1) % in_params.buffer_count + in_params.buffer_offset; 613 const auto mix_index = (base - 1) % in_params.buffer_count + in_params.buffer_offset;
614 for (std::size_t i = 0; i < dest_in_params.buffer_count; i++) { 614 for (std::size_t i = 0; i < static_cast<std::size_t>(dest_in_params.buffer_count);
615 i++) {
615 const auto mixed_volume = in_params.volume * destination_data->GetMixVolume(i); 616 const auto mixed_volume = in_params.volume * destination_data->GetMixVolume(i);
616 if (mixed_volume != 0.0f) { 617 if (mixed_volume != 0.0f) {
617 GenerateMixCommand(dest_in_params.buffer_offset + i, mix_index, mixed_volume, 618 GenerateMixCommand(dest_in_params.buffer_offset + i, mix_index, mixed_volume,
@@ -704,7 +705,7 @@ s32 CommandGenerator::DecodePcm16(ServerVoiceInfo& voice_info, VoiceState& dsp_s
704 std::vector<s16> buffer(samples_processed * channel_count); 705 std::vector<s16> buffer(samples_processed * channel_count);
705 memory.ReadBlock(buffer_pos, buffer.data(), buffer.size() * sizeof(s16)); 706 memory.ReadBlock(buffer_pos, buffer.data(), buffer.size() * sizeof(s16));
706 707
707 for (std::size_t i = 0; i < samples_processed; i++) { 708 for (std::size_t i = 0; i < static_cast<std::size_t>(samples_processed); i++) {
708 sample_buffer[mix_offset + i] = buffer[i * channel_count + channel]; 709 sample_buffer[mix_offset + i] = buffer[i * channel_count + channel];
709 } 710 }
710 } 711 }
@@ -726,8 +727,9 @@ s32 CommandGenerator::DecodeAdpcm(ServerVoiceInfo& voice_info, VoiceState& dsp_s
726 return 0; 727 return 0;
727 } 728 }
728 729
729 constexpr std::array<int, 16> SIGNED_NIBBLES = { 730 static constexpr std::array<int, 16> SIGNED_NIBBLES{
730 {0, 1, 2, 3, 4, 5, 6, 7, -8, -7, -6, -5, -4, -3, -2, -1}}; 731 0, 1, 2, 3, 4, 5, 6, 7, -8, -7, -6, -5, -4, -3, -2, -1,
732 };
731 733
732 constexpr std::size_t FRAME_LEN = 8; 734 constexpr std::size_t FRAME_LEN = 8;
733 constexpr std::size_t NIBBLES_PER_SAMPLE = 16; 735 constexpr std::size_t NIBBLES_PER_SAMPLE = 16;
@@ -789,7 +791,7 @@ s32 CommandGenerator::DecodeAdpcm(ServerVoiceInfo& voice_info, VoiceState& dsp_s
789 position_in_frame += 2; 791 position_in_frame += 2;
790 792
791 // Decode entire frame 793 // Decode entire frame
792 if (remaining_samples >= SAMPLES_PER_FRAME) { 794 if (remaining_samples >= static_cast<int>(SAMPLES_PER_FRAME)) {
793 for (std::size_t i = 0; i < SAMPLES_PER_FRAME / 2; i++) { 795 for (std::size_t i = 0; i < SAMPLES_PER_FRAME / 2; i++) {
794 796
795 // Sample 1 797 // Sample 1
@@ -866,7 +868,6 @@ void CommandGenerator::DecodeFromWaveBuffers(ServerVoiceInfo& voice_info, s32* o
866 const auto resample_rate = static_cast<s32>( 868 const auto resample_rate = static_cast<s32>(
867 static_cast<float>(in_params.sample_rate) / static_cast<float>(target_sample_rate) * 869 static_cast<float>(in_params.sample_rate) / static_cast<float>(target_sample_rate) *
868 static_cast<float>(static_cast<s32>(in_params.pitch * 32768.0f))); 870 static_cast<float>(static_cast<s32>(in_params.pitch * 32768.0f)));
869 auto* output_base = output;
870 if (dsp_state.fraction + sample_count * resample_rate > 871 if (dsp_state.fraction + sample_count * resample_rate >
871 static_cast<s32>(SCALED_MIX_BUFFER_SIZE - 4ULL)) { 872 static_cast<s32>(SCALED_MIX_BUFFER_SIZE - 4ULL)) {
872 return; 873 return;
diff --git a/src/audio_core/command_generator.h b/src/audio_core/command_generator.h
index 967d24078..53e57748b 100644
--- a/src/audio_core/command_generator.h
+++ b/src/audio_core/command_generator.h
@@ -7,7 +7,6 @@
7#include <array> 7#include <array>
8#include "audio_core/common.h" 8#include "audio_core/common.h"
9#include "audio_core/voice_context.h" 9#include "audio_core/voice_context.h"
10#include "common/common_funcs.h"
11#include "common/common_types.h" 10#include "common/common_types.h"
12 11
13namespace Core::Memory { 12namespace Core::Memory {
diff --git a/src/audio_core/common.h b/src/audio_core/common.h
index 72ebce221..7b4a1e9e8 100644
--- a/src/audio_core/common.h
+++ b/src/audio_core/common.h
@@ -3,6 +3,7 @@
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#pragma once 5#pragma once
6
6#include "common/common_funcs.h" 7#include "common/common_funcs.h"
7#include "common/common_types.h" 8#include "common/common_types.h"
8#include "common/swap.h" 9#include "common/swap.h"
diff --git a/src/audio_core/cubeb_sink.cpp b/src/audio_core/cubeb_sink.cpp
index 83c06c0ed..eb82791f6 100644
--- a/src/audio_core/cubeb_sink.cpp
+++ b/src/audio_core/cubeb_sink.cpp
@@ -192,8 +192,8 @@ SinkStream& CubebSink::AcquireSinkStream(u32 sample_rate, u32 num_channels,
192 192
193long CubebSinkStream::DataCallback(cubeb_stream* stream, void* user_data, const void* input_buffer, 193long CubebSinkStream::DataCallback(cubeb_stream* stream, void* user_data, const void* input_buffer,
194 void* output_buffer, long num_frames) { 194 void* output_buffer, long num_frames) {
195 CubebSinkStream* impl = static_cast<CubebSinkStream*>(user_data); 195 auto* impl = static_cast<CubebSinkStream*>(user_data);
196 u8* buffer = reinterpret_cast<u8*>(output_buffer); 196 auto* buffer = static_cast<u8*>(output_buffer);
197 197
198 if (!impl) { 198 if (!impl) {
199 return {}; 199 return {};
diff --git a/src/audio_core/effect_context.cpp b/src/audio_core/effect_context.cpp
index adfec3df5..4d9cdf524 100644
--- a/src/audio_core/effect_context.cpp
+++ b/src/audio_core/effect_context.cpp
@@ -184,19 +184,19 @@ void EffectAuxInfo::UpdateForCommandGeneration() {
184 } 184 }
185} 185}
186 186
187const VAddr EffectAuxInfo::GetSendInfo() const { 187VAddr EffectAuxInfo::GetSendInfo() const {
188 return send_info; 188 return send_info;
189} 189}
190 190
191const VAddr EffectAuxInfo::GetSendBuffer() const { 191VAddr EffectAuxInfo::GetSendBuffer() const {
192 return send_buffer; 192 return send_buffer;
193} 193}
194 194
195const VAddr EffectAuxInfo::GetRecvInfo() const { 195VAddr EffectAuxInfo::GetRecvInfo() const {
196 return recv_info; 196 return recv_info;
197} 197}
198 198
199const VAddr EffectAuxInfo::GetRecvBuffer() const { 199VAddr EffectAuxInfo::GetRecvBuffer() const {
200 return recv_buffer; 200 return recv_buffer;
201} 201}
202 202
diff --git a/src/audio_core/effect_context.h b/src/audio_core/effect_context.h
index 2f2da72dd..2c4ce53ef 100644
--- a/src/audio_core/effect_context.h
+++ b/src/audio_core/effect_context.h
@@ -166,13 +166,13 @@ public:
166 std::array<u8, 0xa0> raw; 166 std::array<u8, 0xa0> raw;
167 }; 167 };
168 }; 168 };
169 static_assert(sizeof(EffectInfo::InParams) == 0xc0, "InParams is an invalid size"); 169 static_assert(sizeof(InParams) == 0xc0, "InParams is an invalid size");
170 170
171 struct OutParams { 171 struct OutParams {
172 UsageStatus status{}; 172 UsageStatus status{};
173 INSERT_PADDING_BYTES(15); 173 INSERT_PADDING_BYTES(15);
174 }; 174 };
175 static_assert(sizeof(EffectInfo::OutParams) == 0x10, "OutParams is an invalid size"); 175 static_assert(sizeof(OutParams) == 0x10, "OutParams is an invalid size");
176}; 176};
177 177
178struct AuxAddress { 178struct AuxAddress {
@@ -184,8 +184,8 @@ struct AuxAddress {
184 184
185class EffectBase { 185class EffectBase {
186public: 186public:
187 EffectBase(EffectType effect_type); 187 explicit EffectBase(EffectType effect_type);
188 ~EffectBase(); 188 virtual ~EffectBase();
189 189
190 virtual void Update(EffectInfo::InParams& in_params) = 0; 190 virtual void Update(EffectInfo::InParams& in_params) = 0;
191 virtual void UpdateForCommandGeneration() = 0; 191 virtual void UpdateForCommandGeneration() = 0;
@@ -206,8 +206,7 @@ protected:
206template <typename T> 206template <typename T>
207class EffectGeneric : public EffectBase { 207class EffectGeneric : public EffectBase {
208public: 208public:
209 EffectGeneric(EffectType effect_type) : EffectBase::EffectBase(effect_type) {} 209 explicit EffectGeneric(EffectType effect_type) : EffectBase(effect_type) {}
210 ~EffectGeneric() = default;
211 210
212 T& GetParams() { 211 T& GetParams() {
213 return internal_params; 212 return internal_params;
@@ -224,7 +223,7 @@ private:
224class EffectStubbed : public EffectBase { 223class EffectStubbed : public EffectBase {
225public: 224public:
226 explicit EffectStubbed(); 225 explicit EffectStubbed();
227 ~EffectStubbed(); 226 ~EffectStubbed() override;
228 227
229 void Update(EffectInfo::InParams& in_params) override; 228 void Update(EffectInfo::InParams& in_params) override;
230 void UpdateForCommandGeneration() override; 229 void UpdateForCommandGeneration() override;
@@ -233,7 +232,7 @@ public:
233class EffectI3dl2Reverb : public EffectGeneric<I3dl2ReverbParams> { 232class EffectI3dl2Reverb : public EffectGeneric<I3dl2ReverbParams> {
234public: 233public:
235 explicit EffectI3dl2Reverb(); 234 explicit EffectI3dl2Reverb();
236 ~EffectI3dl2Reverb(); 235 ~EffectI3dl2Reverb() override;
237 236
238 void Update(EffectInfo::InParams& in_params) override; 237 void Update(EffectInfo::InParams& in_params) override;
239 void UpdateForCommandGeneration() override; 238 void UpdateForCommandGeneration() override;
@@ -245,7 +244,7 @@ private:
245class EffectBiquadFilter : public EffectGeneric<BiquadFilterParams> { 244class EffectBiquadFilter : public EffectGeneric<BiquadFilterParams> {
246public: 245public:
247 explicit EffectBiquadFilter(); 246 explicit EffectBiquadFilter();
248 ~EffectBiquadFilter(); 247 ~EffectBiquadFilter() override;
249 248
250 void Update(EffectInfo::InParams& in_params) override; 249 void Update(EffectInfo::InParams& in_params) override;
251 void UpdateForCommandGeneration() override; 250 void UpdateForCommandGeneration() override;
@@ -254,14 +253,14 @@ public:
254class EffectAuxInfo : public EffectGeneric<AuxInfo> { 253class EffectAuxInfo : public EffectGeneric<AuxInfo> {
255public: 254public:
256 explicit EffectAuxInfo(); 255 explicit EffectAuxInfo();
257 ~EffectAuxInfo(); 256 ~EffectAuxInfo() override;
258 257
259 void Update(EffectInfo::InParams& in_params) override; 258 void Update(EffectInfo::InParams& in_params) override;
260 void UpdateForCommandGeneration() override; 259 void UpdateForCommandGeneration() override;
261 const VAddr GetSendInfo() const; 260 VAddr GetSendInfo() const;
262 const VAddr GetSendBuffer() const; 261 VAddr GetSendBuffer() const;
263 const VAddr GetRecvInfo() const; 262 VAddr GetRecvInfo() const;
264 const VAddr GetRecvBuffer() const; 263 VAddr GetRecvBuffer() const;
265 264
266private: 265private:
267 VAddr send_info{}; 266 VAddr send_info{};
@@ -275,7 +274,7 @@ private:
275class EffectDelay : public EffectGeneric<DelayParams> { 274class EffectDelay : public EffectGeneric<DelayParams> {
276public: 275public:
277 explicit EffectDelay(); 276 explicit EffectDelay();
278 ~EffectDelay(); 277 ~EffectDelay() override;
279 278
280 void Update(EffectInfo::InParams& in_params) override; 279 void Update(EffectInfo::InParams& in_params) override;
281 void UpdateForCommandGeneration() override; 280 void UpdateForCommandGeneration() override;
@@ -287,7 +286,7 @@ private:
287class EffectBufferMixer : public EffectGeneric<BufferMixerParams> { 286class EffectBufferMixer : public EffectGeneric<BufferMixerParams> {
288public: 287public:
289 explicit EffectBufferMixer(); 288 explicit EffectBufferMixer();
290 ~EffectBufferMixer(); 289 ~EffectBufferMixer() override;
291 290
292 void Update(EffectInfo::InParams& in_params) override; 291 void Update(EffectInfo::InParams& in_params) override;
293 void UpdateForCommandGeneration() override; 292 void UpdateForCommandGeneration() override;
@@ -296,7 +295,7 @@ public:
296class EffectReverb : public EffectGeneric<ReverbParams> { 295class EffectReverb : public EffectGeneric<ReverbParams> {
297public: 296public:
298 explicit EffectReverb(); 297 explicit EffectReverb();
299 ~EffectReverb(); 298 ~EffectReverb() override;
300 299
301 void Update(EffectInfo::InParams& in_params) override; 300 void Update(EffectInfo::InParams& in_params) override;
302 void UpdateForCommandGeneration() override; 301 void UpdateForCommandGeneration() override;
diff --git a/src/audio_core/info_updater.cpp b/src/audio_core/info_updater.cpp
index f53ce21a5..2940e53a9 100644
--- a/src/audio_core/info_updater.cpp
+++ b/src/audio_core/info_updater.cpp
@@ -64,7 +64,6 @@ bool InfoUpdater::UpdateBehaviorInfo(BehaviorInfo& in_behavior_info) {
64} 64}
65 65
66bool InfoUpdater::UpdateMemoryPools(std::vector<ServerMemoryPoolInfo>& memory_pool_info) { 66bool InfoUpdater::UpdateMemoryPools(std::vector<ServerMemoryPoolInfo>& memory_pool_info) {
67 const auto force_mapping = behavior_info.IsMemoryPoolForceMappingEnabled();
68 const auto memory_pool_count = memory_pool_info.size(); 67 const auto memory_pool_count = memory_pool_info.size();
69 const auto total_memory_pool_in = sizeof(ServerMemoryPoolInfo::InParams) * memory_pool_count; 68 const auto total_memory_pool_in = sizeof(ServerMemoryPoolInfo::InParams) * memory_pool_count;
70 const auto total_memory_pool_out = sizeof(ServerMemoryPoolInfo::OutParams) * memory_pool_count; 69 const auto total_memory_pool_out = sizeof(ServerMemoryPoolInfo::OutParams) * memory_pool_count;
@@ -174,7 +173,7 @@ bool InfoUpdater::UpdateVoices(VoiceContext& voice_context,
174 } 173 }
175 // Voice states for each channel 174 // Voice states for each channel
176 std::array<VoiceState*, AudioCommon::MAX_CHANNEL_COUNT> voice_states{}; 175 std::array<VoiceState*, AudioCommon::MAX_CHANNEL_COUNT> voice_states{};
177 ASSERT(in_params.id < voice_count); 176 ASSERT(static_cast<std::size_t>(in_params.id) < voice_count);
178 177
179 // Grab our current voice info 178 // Grab our current voice info
180 auto& voice_info = voice_context.GetInfo(static_cast<std::size_t>(in_params.id)); 179 auto& voice_info = voice_context.GetInfo(static_cast<std::size_t>(in_params.id));
@@ -352,8 +351,8 @@ ResultCode InfoUpdater::UpdateMixes(MixContext& mix_context, std::size_t mix_buf
352 for (std::size_t i = 0; i < mix_count; i++) { 351 for (std::size_t i = 0; i < mix_count; i++) {
353 const auto& in = mix_in_params[i]; 352 const auto& in = mix_in_params[i];
354 total_buffer_count += in.buffer_count; 353 total_buffer_count += in.buffer_count;
355 if (in.dest_mix_id > mix_count && in.dest_mix_id != AudioCommon::NO_MIX && 354 if (static_cast<std::size_t>(in.dest_mix_id) > mix_count &&
356 in.mix_id != AudioCommon::FINAL_MIX) { 355 in.dest_mix_id != AudioCommon::NO_MIX && in.mix_id != AudioCommon::FINAL_MIX) {
357 LOG_ERROR( 356 LOG_ERROR(
358 Audio, 357 Audio,
359 "Invalid mix destination, mix_id={:X}, dest_mix_id={:X}, mix_buffer_count={:X}", 358 "Invalid mix destination, mix_id={:X}, dest_mix_id={:X}, mix_buffer_count={:X}",
diff --git a/src/audio_core/mix_context.cpp b/src/audio_core/mix_context.cpp
index 042891490..4bca72eb0 100644
--- a/src/audio_core/mix_context.cpp
+++ b/src/audio_core/mix_context.cpp
@@ -53,7 +53,7 @@ void MixContext::UpdateDistancesFromFinalMix() {
53 auto mix_id = in_params.mix_id; 53 auto mix_id = in_params.mix_id;
54 // Needs to be referenced out of scope 54 // Needs to be referenced out of scope
55 s32 distance_to_final_mix{AudioCommon::FINAL_MIX}; 55 s32 distance_to_final_mix{AudioCommon::FINAL_MIX};
56 for (; distance_to_final_mix < info_count; distance_to_final_mix++) { 56 for (; distance_to_final_mix < static_cast<s32>(info_count); distance_to_final_mix++) {
57 if (mix_id == AudioCommon::FINAL_MIX) { 57 if (mix_id == AudioCommon::FINAL_MIX) {
58 // If we're at the final mix, we're done 58 // If we're at the final mix, we're done
59 break; 59 break;
@@ -77,7 +77,7 @@ void MixContext::UpdateDistancesFromFinalMix() {
77 } 77 }
78 78
79 // If we're out of range for our distance, mark it as no final mix 79 // If we're out of range for our distance, mark it as no final mix
80 if (distance_to_final_mix >= info_count) { 80 if (distance_to_final_mix >= static_cast<s32>(info_count)) {
81 distance_to_final_mix = AudioCommon::NO_FINAL_MIX; 81 distance_to_final_mix = AudioCommon::NO_FINAL_MIX;
82 } 82 }
83 83
diff --git a/src/audio_core/splitter_context.cpp b/src/audio_core/splitter_context.cpp
index 79bb2f516..f21b53147 100644
--- a/src/audio_core/splitter_context.cpp
+++ b/src/audio_core/splitter_context.cpp
@@ -306,7 +306,7 @@ bool SplitterContext::UpdateInfo(const std::vector<u8>& input, std::size_t& inpu
306 break; 306 break;
307 } 307 }
308 308
309 if (header.send_id < 0 || header.send_id > info_count) { 309 if (header.send_id < 0 || static_cast<std::size_t>(header.send_id) > info_count) {
310 LOG_ERROR(Audio, "Bad splitter data id"); 310 LOG_ERROR(Audio, "Bad splitter data id");
311 break; 311 break;
312 } 312 }
@@ -348,7 +348,7 @@ bool SplitterContext::UpdateData(const std::vector<u8>& input, std::size_t& inpu
348 break; 348 break;
349 } 349 }
350 350
351 if (header.splitter_id < 0 || header.splitter_id > data_count) { 351 if (header.splitter_id < 0 || static_cast<std::size_t>(header.splitter_id) > data_count) {
352 LOG_ERROR(Audio, "Bad splitter data id"); 352 LOG_ERROR(Audio, "Bad splitter data id");
353 break; 353 break;
354 } 354 }
@@ -434,7 +434,7 @@ const std::vector<s32>& NodeStates::GetIndexList() const {
434} 434}
435 435
436void NodeStates::PushTsortResult(s32 index) { 436void NodeStates::PushTsortResult(s32 index) {
437 ASSERT(index < node_count); 437 ASSERT(index < static_cast<s32>(node_count));
438 index_list[index_pos++] = index; 438 index_list[index_pos++] = index;
439} 439}
440 440
diff --git a/src/audio_core/stream.cpp b/src/audio_core/stream.cpp
index cb33926bc..4bbb1e0c4 100644
--- a/src/audio_core/stream.cpp
+++ b/src/audio_core/stream.cpp
@@ -12,7 +12,6 @@
12#include "common/assert.h" 12#include "common/assert.h"
13#include "common/logging/log.h" 13#include "common/logging/log.h"
14#include "core/core_timing.h" 14#include "core/core_timing.h"
15#include "core/core_timing_util.h"
16#include "core/settings.h" 15#include "core/settings.h"
17 16
18namespace AudioCore { 17namespace AudioCore {
diff --git a/src/audio_core/voice_context.cpp b/src/audio_core/voice_context.cpp
index 1d8f69844..863ac9267 100644
--- a/src/audio_core/voice_context.cpp
+++ b/src/audio_core/voice_context.cpp
@@ -488,11 +488,11 @@ s32 VoiceContext::DecodePcm16(s32* output_buffer, ServerWaveBuffer* wave_buffer,
488 488
489 // Fast path 489 // Fast path
490 if (channel_count == 1) { 490 if (channel_count == 1) {
491 for (std::size_t i = 0; i < samples_processed; i++) { 491 for (std::ptrdiff_t i = 0; i < samples_processed; i++) {
492 output_buffer[i] = buffer_data[i]; 492 output_buffer[i] = buffer_data[i];
493 } 493 }
494 } else { 494 } else {
495 for (std::size_t i = 0; i < samples_processed; i++) { 495 for (std::ptrdiff_t i = 0; i < samples_processed; i++) {
496 output_buffer[i] = buffer_data[i * channel_count + channel]; 496 output_buffer[i] = buffer_data[i * channel_count + channel];
497 } 497 }
498 } 498 }
diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt
index 5d54516eb..0fb5d9708 100644
--- a/src/common/CMakeLists.txt
+++ b/src/common/CMakeLists.txt
@@ -192,4 +192,9 @@ create_target_directory_groups(common)
192find_package(Boost 1.71 COMPONENTS context headers REQUIRED) 192find_package(Boost 1.71 COMPONENTS context headers REQUIRED)
193 193
194target_link_libraries(common PUBLIC ${Boost_LIBRARIES} fmt::fmt microprofile) 194target_link_libraries(common PUBLIC ${Boost_LIBRARIES} fmt::fmt microprofile)
195target_link_libraries(common PRIVATE lz4::lz4 zstd::zstd xbyak) 195target_link_libraries(common PRIVATE lz4::lz4 xbyak)
196if (MSVC)
197 target_link_libraries(common PRIVATE zstd::zstd)
198else()
199 target_link_libraries(common PRIVATE zstd)
200endif()
diff --git a/src/common/wall_clock.cpp b/src/common/wall_clock.cpp
index 3afbdb898..7a20e95b7 100644
--- a/src/common/wall_clock.cpp
+++ b/src/common/wall_clock.cpp
@@ -15,7 +15,7 @@ namespace Common {
15using base_timer = std::chrono::steady_clock; 15using base_timer = std::chrono::steady_clock;
16using base_time_point = std::chrono::time_point<base_timer>; 16using base_time_point = std::chrono::time_point<base_timer>;
17 17
18class StandardWallClock : public WallClock { 18class StandardWallClock final : public WallClock {
19public: 19public:
20 StandardWallClock(u64 emulated_cpu_frequency, u64 emulated_clock_frequency) 20 StandardWallClock(u64 emulated_cpu_frequency, u64 emulated_clock_frequency)
21 : WallClock(emulated_cpu_frequency, emulated_clock_frequency, false) { 21 : WallClock(emulated_cpu_frequency, emulated_clock_frequency, false) {
diff --git a/src/common/wall_clock.h b/src/common/wall_clock.h
index 5db30083d..bc7adfbf8 100644
--- a/src/common/wall_clock.h
+++ b/src/common/wall_clock.h
@@ -13,6 +13,8 @@ namespace Common {
13 13
14class WallClock { 14class WallClock {
15public: 15public:
16 virtual ~WallClock() = default;
17
16 /// Returns current wall time in nanoseconds 18 /// Returns current wall time in nanoseconds
17 [[nodiscard]] virtual std::chrono::nanoseconds GetTimeNS() = 0; 19 [[nodiscard]] virtual std::chrono::nanoseconds GetTimeNS() = 0;
18 20
diff --git a/src/common/x64/native_clock.h b/src/common/x64/native_clock.h
index 891a3bbfd..7c503df26 100644
--- a/src/common/x64/native_clock.h
+++ b/src/common/x64/native_clock.h
@@ -12,7 +12,7 @@
12namespace Common { 12namespace Common {
13 13
14namespace X64 { 14namespace X64 {
15class NativeClock : public WallClock { 15class NativeClock final : public WallClock {
16public: 16public:
17 NativeClock(u64 emulated_cpu_frequency, u64 emulated_clock_frequency, u64 rtsc_frequency); 17 NativeClock(u64 emulated_cpu_frequency, u64 emulated_clock_frequency, u64 rtsc_frequency);
18 18
diff --git a/src/core/core.h b/src/core/core.h
index 83ded63a5..27efe30bb 100644
--- a/src/core/core.h
+++ b/src/core/core.h
@@ -120,7 +120,7 @@ public:
120 * Gets the instance of the System singleton class. 120 * Gets the instance of the System singleton class.
121 * @returns Reference to the instance of the System singleton class. 121 * @returns Reference to the instance of the System singleton class.
122 */ 122 */
123 static System& GetInstance() { 123 [[deprecated("Use of the global system instance is deprecated")]] static System& GetInstance() {
124 return s_instance; 124 return s_instance;
125 } 125 }
126 126
diff --git a/src/core/file_sys/submission_package.cpp b/src/core/file_sys/submission_package.cpp
index aab957bf2..07ae90819 100644
--- a/src/core/file_sys/submission_package.cpp
+++ b/src/core/file_sys/submission_package.cpp
@@ -286,12 +286,31 @@ void NSP::ReadNCAs(const std::vector<VirtualFile>& files) {
286 } 286 }
287 287
288 auto next_nca = std::make_shared<NCA>(std::move(next_file), nullptr, 0); 288 auto next_nca = std::make_shared<NCA>(std::move(next_file), nullptr, 0);
289
289 if (next_nca->GetType() == NCAContentType::Program) { 290 if (next_nca->GetType() == NCAContentType::Program) {
290 program_status[next_nca->GetTitleId()] = next_nca->GetStatus(); 291 program_status[next_nca->GetTitleId()] = next_nca->GetStatus();
291 } 292 }
292 if (next_nca->GetStatus() == Loader::ResultStatus::Success || 293
293 (next_nca->GetStatus() == Loader::ResultStatus::ErrorMissingBKTRBaseRomFS && 294 if (next_nca->GetStatus() != Loader::ResultStatus::Success &&
294 (next_nca->GetTitleId() & 0x800) != 0)) { 295 next_nca->GetStatus() != Loader::ResultStatus::ErrorMissingBKTRBaseRomFS) {
296 continue;
297 }
298
299 // If the last 3 hexadecimal digits of the CNMT TitleID is 0x800 or is missing the
300 // BKTRBaseRomFS, this is an update NCA. Otherwise, this is a base NCA.
301 if ((cnmt.GetTitleID() & 0x800) != 0 ||
302 next_nca->GetStatus() == Loader::ResultStatus::ErrorMissingBKTRBaseRomFS) {
303 // If the last 3 hexadecimal digits of the NCA's TitleID is between 0x1 and
304 // 0x7FF, this is a multi-program update NCA. Otherwise, this is a regular
305 // update NCA.
306 if ((next_nca->GetTitleId() & 0x7FF) != 0 &&
307 (next_nca->GetTitleId() & 0x800) == 0) {
308 ncas[next_nca->GetTitleId()][{cnmt.GetType(), rec.type}] =
309 std::move(next_nca);
310 } else {
311 ncas[cnmt.GetTitleID()][{cnmt.GetType(), rec.type}] = std::move(next_nca);
312 }
313 } else {
295 ncas[next_nca->GetTitleId()][{cnmt.GetType(), rec.type}] = std::move(next_nca); 314 ncas[next_nca->GetTitleId()][{cnmt.GetType(), rec.type}] = std::move(next_nca);
296 } 315 }
297 } 316 }
diff --git a/src/core/frontend/applets/controller.cpp b/src/core/frontend/applets/controller.cpp
index 4505da758..c5d65f2d0 100644
--- a/src/core/frontend/applets/controller.cpp
+++ b/src/core/frontend/applets/controller.cpp
@@ -4,7 +4,6 @@
4 4
5#include "common/assert.h" 5#include "common/assert.h"
6#include "common/logging/log.h" 6#include "common/logging/log.h"
7#include "core/core.h"
8#include "core/frontend/applets/controller.h" 7#include "core/frontend/applets/controller.h"
9#include "core/hle/service/hid/controllers/npad.h" 8#include "core/hle/service/hid/controllers/npad.h"
10#include "core/hle/service/hid/hid.h" 9#include "core/hle/service/hid/hid.h"
@@ -14,6 +13,9 @@ namespace Core::Frontend {
14 13
15ControllerApplet::~ControllerApplet() = default; 14ControllerApplet::~ControllerApplet() = default;
16 15
16DefaultControllerApplet::DefaultControllerApplet(Service::SM::ServiceManager& service_manager_)
17 : service_manager{service_manager_} {}
18
17DefaultControllerApplet::~DefaultControllerApplet() = default; 19DefaultControllerApplet::~DefaultControllerApplet() = default;
18 20
19void DefaultControllerApplet::ReconfigureControllers(std::function<void()> callback, 21void DefaultControllerApplet::ReconfigureControllers(std::function<void()> callback,
@@ -21,9 +23,7 @@ void DefaultControllerApplet::ReconfigureControllers(std::function<void()> callb
21 LOG_INFO(Service_HID, "called, deducing the best configuration based on the given parameters!"); 23 LOG_INFO(Service_HID, "called, deducing the best configuration based on the given parameters!");
22 24
23 auto& npad = 25 auto& npad =
24 Core::System::GetInstance() 26 service_manager.GetService<Service::HID::Hid>("hid")
25 .ServiceManager()
26 .GetService<Service::HID::Hid>("hid")
27 ->GetAppletResource() 27 ->GetAppletResource()
28 ->GetController<Service::HID::Controller_NPad>(Service::HID::HidController::NPad); 28 ->GetController<Service::HID::Controller_NPad>(Service::HID::HidController::NPad);
29 29
diff --git a/src/core/frontend/applets/controller.h b/src/core/frontend/applets/controller.h
index a227f15cd..3e49cdbb9 100644
--- a/src/core/frontend/applets/controller.h
+++ b/src/core/frontend/applets/controller.h
@@ -8,6 +8,10 @@
8 8
9#include "common/common_types.h" 9#include "common/common_types.h"
10 10
11namespace Service::SM {
12class ServiceManager;
13}
14
11namespace Core::Frontend { 15namespace Core::Frontend {
12 16
13using BorderColor = std::array<u8, 4>; 17using BorderColor = std::array<u8, 4>;
@@ -39,10 +43,14 @@ public:
39 43
40class DefaultControllerApplet final : public ControllerApplet { 44class DefaultControllerApplet final : public ControllerApplet {
41public: 45public:
46 explicit DefaultControllerApplet(Service::SM::ServiceManager& service_manager_);
42 ~DefaultControllerApplet() override; 47 ~DefaultControllerApplet() override;
43 48
44 void ReconfigureControllers(std::function<void()> callback, 49 void ReconfigureControllers(std::function<void()> callback,
45 ControllerParameters parameters) const override; 50 ControllerParameters parameters) const override;
51
52private:
53 Service::SM::ServiceManager& service_manager;
46}; 54};
47 55
48} // namespace Core::Frontend 56} // namespace Core::Frontend
diff --git a/src/core/frontend/input.h b/src/core/frontend/input.h
index 9da0d2829..277b70e53 100644
--- a/src/core/frontend/input.h
+++ b/src/core/frontend/input.h
@@ -33,6 +33,9 @@ public:
33 virtual bool GetAnalogDirectionStatus(AnalogDirection direction) const { 33 virtual bool GetAnalogDirectionStatus(AnalogDirection direction) const {
34 return {}; 34 return {};
35 } 35 }
36 virtual bool SetRumblePlay(f32 amp_high, f32 amp_low, f32 freq_high, f32 freq_low) const {
37 return {};
38 }
36}; 39};
37 40
38/// An abstract class template for a factory that can create input devices. 41/// An abstract class template for a factory that can create input devices.
diff --git a/src/core/hle/service/am/applets/applets.cpp b/src/core/hle/service/am/applets/applets.cpp
index 4e0800f9a..2b626bb40 100644
--- a/src/core/hle/service/am/applets/applets.cpp
+++ b/src/core/hle/service/am/applets/applets.cpp
@@ -206,7 +206,8 @@ void AppletManager::SetDefaultAppletFrontendSet() {
206 206
207void AppletManager::SetDefaultAppletsIfMissing() { 207void AppletManager::SetDefaultAppletsIfMissing() {
208 if (frontend.controller == nullptr) { 208 if (frontend.controller == nullptr) {
209 frontend.controller = std::make_unique<Core::Frontend::DefaultControllerApplet>(); 209 frontend.controller =
210 std::make_unique<Core::Frontend::DefaultControllerApplet>(system.ServiceManager());
210 } 211 }
211 212
212 if (frontend.e_commerce == nullptr) { 213 if (frontend.e_commerce == nullptr) {
diff --git a/src/core/hle/service/caps/caps_c.cpp b/src/core/hle/service/caps/caps_c.cpp
index ab17a187e..a0ee116fa 100644
--- a/src/core/hle/service/caps/caps_c.cpp
+++ b/src/core/hle/service/caps/caps_c.cpp
@@ -2,6 +2,8 @@
2// Licensed under GPLv2 or any later version 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include "common/logging/log.h"
6#include "core/hle/ipc_helpers.h"
5#include "core/hle/service/caps/caps_c.h" 7#include "core/hle/service/caps/caps_c.h"
6 8
7namespace Service::Capture { 9namespace Service::Capture {
@@ -47,7 +49,7 @@ CAPS_C::CAPS_C() : ServiceFramework("caps:c") {
47 static const FunctionInfo functions[] = { 49 static const FunctionInfo functions[] = {
48 {1, nullptr, "CaptureRawImage"}, 50 {1, nullptr, "CaptureRawImage"},
49 {2, nullptr, "CaptureRawImageWithTimeout"}, 51 {2, nullptr, "CaptureRawImageWithTimeout"},
50 {33, nullptr, "Unknown33"}, 52 {33, &CAPS_C::SetShimLibraryVersion, "SetShimLibraryVersion"},
51 {1001, nullptr, "RequestTakingScreenShot"}, 53 {1001, nullptr, "RequestTakingScreenShot"},
52 {1002, nullptr, "RequestTakingScreenShotWithTimeout"}, 54 {1002, nullptr, "RequestTakingScreenShotWithTimeout"},
53 {1011, nullptr, "NotifyTakingScreenShotRefused"}, 55 {1011, nullptr, "NotifyTakingScreenShotRefused"},
@@ -72,4 +74,16 @@ CAPS_C::CAPS_C() : ServiceFramework("caps:c") {
72 74
73CAPS_C::~CAPS_C() = default; 75CAPS_C::~CAPS_C() = default;
74 76
77void CAPS_C::SetShimLibraryVersion(Kernel::HLERequestContext& ctx) {
78 IPC::RequestParser rp{ctx};
79 const auto library_version{rp.Pop<u64>()};
80 const auto applet_resource_user_id{rp.Pop<u64>()};
81
82 LOG_WARNING(Service_Capture, "(STUBBED) called. library_version={}, applet_resource_user_id={}",
83 library_version, applet_resource_user_id);
84
85 IPC::ResponseBuilder rb{ctx, 2};
86 rb.Push(RESULT_SUCCESS);
87}
88
75} // namespace Service::Capture 89} // namespace Service::Capture
diff --git a/src/core/hle/service/caps/caps_c.h b/src/core/hle/service/caps/caps_c.h
index a9d028689..b110301d4 100644
--- a/src/core/hle/service/caps/caps_c.h
+++ b/src/core/hle/service/caps/caps_c.h
@@ -16,6 +16,9 @@ class CAPS_C final : public ServiceFramework<CAPS_C> {
16public: 16public:
17 explicit CAPS_C(); 17 explicit CAPS_C();
18 ~CAPS_C() override; 18 ~CAPS_C() override;
19
20private:
21 void SetShimLibraryVersion(Kernel::HLERequestContext& ctx);
19}; 22};
20 23
21} // namespace Service::Capture 24} // namespace Service::Capture
diff --git a/src/core/hle/service/caps/caps_su.cpp b/src/core/hle/service/caps/caps_su.cpp
index fffb2ecf9..e386470f7 100644
--- a/src/core/hle/service/caps/caps_su.cpp
+++ b/src/core/hle/service/caps/caps_su.cpp
@@ -25,7 +25,12 @@ CAPS_SU::CAPS_SU() : ServiceFramework("caps:su") {
25CAPS_SU::~CAPS_SU() = default; 25CAPS_SU::~CAPS_SU() = default;
26 26
27void CAPS_SU::SetShimLibraryVersion(Kernel::HLERequestContext& ctx) { 27void CAPS_SU::SetShimLibraryVersion(Kernel::HLERequestContext& ctx) {
28 LOG_WARNING(Service_Capture, "(STUBBED) called"); 28 IPC::RequestParser rp{ctx};
29 const auto library_version{rp.Pop<u64>()};
30 const auto applet_resource_user_id{rp.Pop<u64>()};
31
32 LOG_WARNING(Service_Capture, "(STUBBED) called. library_version={}, applet_resource_user_id={}",
33 library_version, applet_resource_user_id);
29 34
30 IPC::ResponseBuilder rb{ctx, 2}; 35 IPC::ResponseBuilder rb{ctx, 2};
31 rb.Push(RESULT_SUCCESS); 36 rb.Push(RESULT_SUCCESS);
diff --git a/src/core/hle/service/caps/caps_u.cpp b/src/core/hle/service/caps/caps_u.cpp
index f36d8de2d..8e2b83629 100644
--- a/src/core/hle/service/caps/caps_u.cpp
+++ b/src/core/hle/service/caps/caps_u.cpp
@@ -31,8 +31,7 @@ public:
31CAPS_U::CAPS_U() : ServiceFramework("caps:u") { 31CAPS_U::CAPS_U() : ServiceFramework("caps:u") {
32 // clang-format off 32 // clang-format off
33 static const FunctionInfo functions[] = { 33 static const FunctionInfo functions[] = {
34 {31, nullptr, "GetShimLibraryVersion"}, 34 {32, &CAPS_U::SetShimLibraryVersion, "SetShimLibraryVersion"},
35 {32, nullptr, "SetShimLibraryVersion"},
36 {102, &CAPS_U::GetAlbumContentsFileListForApplication, "GetAlbumContentsFileListForApplication"}, 35 {102, &CAPS_U::GetAlbumContentsFileListForApplication, "GetAlbumContentsFileListForApplication"},
37 {103, nullptr, "DeleteAlbumContentsFileForApplication"}, 36 {103, nullptr, "DeleteAlbumContentsFileForApplication"},
38 {104, nullptr, "GetAlbumContentsFileSizeForApplication"}, 37 {104, nullptr, "GetAlbumContentsFileSizeForApplication"},
@@ -53,6 +52,18 @@ CAPS_U::CAPS_U() : ServiceFramework("caps:u") {
53 52
54CAPS_U::~CAPS_U() = default; 53CAPS_U::~CAPS_U() = default;
55 54
55void CAPS_U::SetShimLibraryVersion(Kernel::HLERequestContext& ctx) {
56 IPC::RequestParser rp{ctx};
57 const auto library_version{rp.Pop<u64>()};
58 const auto applet_resource_user_id{rp.Pop<u64>()};
59
60 LOG_WARNING(Service_Capture, "(STUBBED) called. library_version={}, applet_resource_user_id={}",
61 library_version, applet_resource_user_id);
62
63 IPC::ResponseBuilder rb{ctx, 2};
64 rb.Push(RESULT_SUCCESS);
65}
66
56void CAPS_U::GetAlbumContentsFileListForApplication(Kernel::HLERequestContext& ctx) { 67void CAPS_U::GetAlbumContentsFileListForApplication(Kernel::HLERequestContext& ctx) {
57 // Takes a type-0x6 output buffer containing an array of ApplicationAlbumFileEntry, a PID, an 68 // Takes a type-0x6 output buffer containing an array of ApplicationAlbumFileEntry, a PID, an
58 // u8 ContentType, two s64s, and an u64 AppletResourceUserId. Returns an output u64 for total 69 // u8 ContentType, two s64s, and an u64 AppletResourceUserId. Returns an output u64 for total
diff --git a/src/core/hle/service/caps/caps_u.h b/src/core/hle/service/caps/caps_u.h
index 689364de4..e04e56bbc 100644
--- a/src/core/hle/service/caps/caps_u.h
+++ b/src/core/hle/service/caps/caps_u.h
@@ -18,6 +18,7 @@ public:
18 ~CAPS_U() override; 18 ~CAPS_U() override;
19 19
20private: 20private:
21 void SetShimLibraryVersion(Kernel::HLERequestContext& ctx);
21 void GetAlbumContentsFileListForApplication(Kernel::HLERequestContext& ctx); 22 void GetAlbumContentsFileListForApplication(Kernel::HLERequestContext& ctx);
22}; 23};
23 24
diff --git a/src/core/hle/service/hid/controllers/controller_base.h b/src/core/hle/service/hid/controllers/controller_base.h
index 8bc69c372..f47a9e61c 100644
--- a/src/core/hle/service/hid/controllers/controller_base.h
+++ b/src/core/hle/service/hid/controllers/controller_base.h
@@ -31,6 +31,10 @@ public:
31 virtual void OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data, 31 virtual void OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data,
32 std::size_t size) = 0; 32 std::size_t size) = 0;
33 33
34 // When the controller is requesting a motion update for the shared memory
35 virtual void OnMotionUpdate(const Core::Timing::CoreTiming& core_timing, u8* data,
36 std::size_t size) {}
37
34 // Called when input devices should be loaded 38 // Called when input devices should be loaded
35 virtual void OnLoadInputDevices() = 0; 39 virtual void OnLoadInputDevices() = 0;
36 40
diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp
index 620386cd1..2de4ed348 100644
--- a/src/core/hle/service/hid/controllers/npad.cpp
+++ b/src/core/hle/service/hid/controllers/npad.cpp
@@ -260,7 +260,7 @@ void Controller_NPad::OnRelease() {}
260 260
261void Controller_NPad::RequestPadStateUpdate(u32 npad_id) { 261void Controller_NPad::RequestPadStateUpdate(u32 npad_id) {
262 const auto controller_idx = NPadIdToIndex(npad_id); 262 const auto controller_idx = NPadIdToIndex(npad_id);
263 [[maybe_unused]] const auto controller_type = connected_controllers[controller_idx].type; 263 const auto controller_type = connected_controllers[controller_idx].type;
264 if (!connected_controllers[controller_idx].is_connected) { 264 if (!connected_controllers[controller_idx].is_connected) {
265 return; 265 return;
266 } 266 }
@@ -276,54 +276,63 @@ void Controller_NPad::RequestPadStateUpdate(u32 npad_id) {
276 analog_state[static_cast<std::size_t>(JoystickId::Joystick_Right)]->GetStatus(); 276 analog_state[static_cast<std::size_t>(JoystickId::Joystick_Right)]->GetStatus();
277 277
278 using namespace Settings::NativeButton; 278 using namespace Settings::NativeButton;
279 pad_state.a.Assign(button_state[A - BUTTON_HID_BEGIN]->GetStatus()); 279 if (controller_type != NPadControllerType::JoyLeft) {
280 pad_state.b.Assign(button_state[B - BUTTON_HID_BEGIN]->GetStatus()); 280 pad_state.a.Assign(button_state[A - BUTTON_HID_BEGIN]->GetStatus());
281 pad_state.x.Assign(button_state[X - BUTTON_HID_BEGIN]->GetStatus()); 281 pad_state.b.Assign(button_state[B - BUTTON_HID_BEGIN]->GetStatus());
282 pad_state.y.Assign(button_state[Y - BUTTON_HID_BEGIN]->GetStatus()); 282 pad_state.x.Assign(button_state[X - BUTTON_HID_BEGIN]->GetStatus());
283 pad_state.l_stick.Assign(button_state[LStick - BUTTON_HID_BEGIN]->GetStatus()); 283 pad_state.y.Assign(button_state[Y - BUTTON_HID_BEGIN]->GetStatus());
284 pad_state.r_stick.Assign(button_state[RStick - BUTTON_HID_BEGIN]->GetStatus()); 284 pad_state.r_stick.Assign(button_state[RStick - BUTTON_HID_BEGIN]->GetStatus());
285 pad_state.l.Assign(button_state[L - BUTTON_HID_BEGIN]->GetStatus()); 285 pad_state.r.Assign(button_state[R - BUTTON_HID_BEGIN]->GetStatus());
286 pad_state.r.Assign(button_state[R - BUTTON_HID_BEGIN]->GetStatus()); 286 pad_state.zr.Assign(button_state[ZR - BUTTON_HID_BEGIN]->GetStatus());
287 pad_state.zl.Assign(button_state[ZL - BUTTON_HID_BEGIN]->GetStatus()); 287 pad_state.plus.Assign(button_state[Plus - BUTTON_HID_BEGIN]->GetStatus());
288 pad_state.zr.Assign(button_state[ZR - BUTTON_HID_BEGIN]->GetStatus()); 288
289 pad_state.plus.Assign(button_state[Plus - BUTTON_HID_BEGIN]->GetStatus()); 289 pad_state.r_stick_right.Assign(
290 pad_state.minus.Assign(button_state[Minus - BUTTON_HID_BEGIN]->GetStatus()); 290 analog_state[static_cast<std::size_t>(JoystickId::Joystick_Right)]
291 291 ->GetAnalogDirectionStatus(Input::AnalogDirection::RIGHT));
292 pad_state.d_left.Assign(button_state[DLeft - BUTTON_HID_BEGIN]->GetStatus()); 292 pad_state.r_stick_left.Assign(
293 pad_state.d_up.Assign(button_state[DUp - BUTTON_HID_BEGIN]->GetStatus()); 293 analog_state[static_cast<std::size_t>(JoystickId::Joystick_Right)]
294 pad_state.d_right.Assign(button_state[DRight - BUTTON_HID_BEGIN]->GetStatus()); 294 ->GetAnalogDirectionStatus(Input::AnalogDirection::LEFT));
295 pad_state.d_down.Assign(button_state[DDown - BUTTON_HID_BEGIN]->GetStatus()); 295 pad_state.r_stick_up.Assign(
296 296 analog_state[static_cast<std::size_t>(JoystickId::Joystick_Right)]
297 pad_state.l_stick_right.Assign( 297 ->GetAnalogDirectionStatus(Input::AnalogDirection::UP));
298 analog_state[static_cast<std::size_t>(JoystickId::Joystick_Left)]->GetAnalogDirectionStatus( 298 pad_state.r_stick_down.Assign(
299 Input::AnalogDirection::RIGHT)); 299 analog_state[static_cast<std::size_t>(JoystickId::Joystick_Right)]
300 pad_state.l_stick_left.Assign( 300 ->GetAnalogDirectionStatus(Input::AnalogDirection::DOWN));
301 analog_state[static_cast<std::size_t>(JoystickId::Joystick_Left)]->GetAnalogDirectionStatus( 301 rstick_entry.x = static_cast<s32>(stick_r_x_f * HID_JOYSTICK_MAX);
302 Input::AnalogDirection::LEFT)); 302 rstick_entry.y = static_cast<s32>(stick_r_y_f * HID_JOYSTICK_MAX);
303 pad_state.l_stick_up.Assign( 303 }
304 analog_state[static_cast<std::size_t>(JoystickId::Joystick_Left)]->GetAnalogDirectionStatus( 304
305 Input::AnalogDirection::UP)); 305 if (controller_type != NPadControllerType::JoyRight) {
306 pad_state.l_stick_down.Assign( 306 pad_state.d_left.Assign(button_state[DLeft - BUTTON_HID_BEGIN]->GetStatus());
307 analog_state[static_cast<std::size_t>(JoystickId::Joystick_Left)]->GetAnalogDirectionStatus( 307 pad_state.d_up.Assign(button_state[DUp - BUTTON_HID_BEGIN]->GetStatus());
308 Input::AnalogDirection::DOWN)); 308 pad_state.d_right.Assign(button_state[DRight - BUTTON_HID_BEGIN]->GetStatus());
309 309 pad_state.d_down.Assign(button_state[DDown - BUTTON_HID_BEGIN]->GetStatus());
310 pad_state.r_stick_right.Assign( 310 pad_state.l_stick.Assign(button_state[LStick - BUTTON_HID_BEGIN]->GetStatus());
311 analog_state[static_cast<std::size_t>(JoystickId::Joystick_Right)] 311 pad_state.l.Assign(button_state[L - BUTTON_HID_BEGIN]->GetStatus());
312 ->GetAnalogDirectionStatus(Input::AnalogDirection::RIGHT)); 312 pad_state.zl.Assign(button_state[ZL - BUTTON_HID_BEGIN]->GetStatus());
313 pad_state.r_stick_left.Assign(analog_state[static_cast<std::size_t>(JoystickId::Joystick_Right)] 313 pad_state.minus.Assign(button_state[Minus - BUTTON_HID_BEGIN]->GetStatus());
314 ->GetAnalogDirectionStatus(Input::AnalogDirection::LEFT)); 314
315 pad_state.r_stick_up.Assign(analog_state[static_cast<std::size_t>(JoystickId::Joystick_Right)] 315 pad_state.l_stick_right.Assign(
316 ->GetAnalogDirectionStatus(Input::AnalogDirection::UP)); 316 analog_state[static_cast<std::size_t>(JoystickId::Joystick_Left)]
317 pad_state.r_stick_down.Assign(analog_state[static_cast<std::size_t>(JoystickId::Joystick_Right)] 317 ->GetAnalogDirectionStatus(Input::AnalogDirection::RIGHT));
318 ->GetAnalogDirectionStatus(Input::AnalogDirection::DOWN)); 318 pad_state.l_stick_left.Assign(
319 319 analog_state[static_cast<std::size_t>(JoystickId::Joystick_Left)]
320 pad_state.left_sl.Assign(button_state[SL - BUTTON_HID_BEGIN]->GetStatus()); 320 ->GetAnalogDirectionStatus(Input::AnalogDirection::LEFT));
321 pad_state.left_sr.Assign(button_state[SR - BUTTON_HID_BEGIN]->GetStatus()); 321 pad_state.l_stick_up.Assign(
322 322 analog_state[static_cast<std::size_t>(JoystickId::Joystick_Left)]
323 lstick_entry.x = static_cast<s32>(stick_l_x_f * HID_JOYSTICK_MAX); 323 ->GetAnalogDirectionStatus(Input::AnalogDirection::UP));
324 lstick_entry.y = static_cast<s32>(stick_l_y_f * HID_JOYSTICK_MAX); 324 pad_state.l_stick_down.Assign(
325 rstick_entry.x = static_cast<s32>(stick_r_x_f * HID_JOYSTICK_MAX); 325 analog_state[static_cast<std::size_t>(JoystickId::Joystick_Left)]
326 rstick_entry.y = static_cast<s32>(stick_r_y_f * HID_JOYSTICK_MAX); 326 ->GetAnalogDirectionStatus(Input::AnalogDirection::DOWN));
327 lstick_entry.x = static_cast<s32>(stick_l_x_f * HID_JOYSTICK_MAX);
328 lstick_entry.y = static_cast<s32>(stick_l_y_f * HID_JOYSTICK_MAX);
329 }
330
331 if (controller_type == NPadControllerType::JoyLeft ||
332 controller_type == NPadControllerType::JoyRight) {
333 pad_state.left_sl.Assign(button_state[SL - BUTTON_HID_BEGIN]->GetStatus());
334 pad_state.left_sr.Assign(button_state[SR - BUTTON_HID_BEGIN]->GetStatus());
335 }
327} 336}
328 337
329void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data, 338void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data,
@@ -365,6 +374,135 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8*
365 } 374 }
366 const u32 npad_index = static_cast<u32>(i); 375 const u32 npad_index = static_cast<u32>(i);
367 376
377 RequestPadStateUpdate(npad_index);
378 auto& pad_state = npad_pad_states[npad_index];
379
380 auto& main_controller =
381 npad.main_controller_states.npad[npad.main_controller_states.common.last_entry_index];
382 auto& handheld_entry =
383 npad.handheld_states.npad[npad.handheld_states.common.last_entry_index];
384 auto& dual_entry = npad.dual_states.npad[npad.dual_states.common.last_entry_index];
385 auto& left_entry = npad.left_joy_states.npad[npad.left_joy_states.common.last_entry_index];
386 auto& right_entry =
387 npad.right_joy_states.npad[npad.right_joy_states.common.last_entry_index];
388 auto& pokeball_entry =
389 npad.pokeball_states.npad[npad.pokeball_states.common.last_entry_index];
390 auto& libnx_entry = npad.libnx.npad[npad.libnx.common.last_entry_index];
391
392 libnx_entry.connection_status.raw = 0;
393 libnx_entry.connection_status.IsConnected.Assign(1);
394 auto& full_sixaxis_entry =
395 npad.sixaxis_full.sixaxis[npad.sixaxis_full.common.last_entry_index];
396 auto& handheld_sixaxis_entry =
397 npad.sixaxis_handheld.sixaxis[npad.sixaxis_handheld.common.last_entry_index];
398 auto& dual_left_sixaxis_entry =
399 npad.sixaxis_dual_left.sixaxis[npad.sixaxis_dual_left.common.last_entry_index];
400 auto& dual_right_sixaxis_entry =
401 npad.sixaxis_dual_right.sixaxis[npad.sixaxis_dual_right.common.last_entry_index];
402 auto& left_sixaxis_entry =
403 npad.sixaxis_left.sixaxis[npad.sixaxis_left.common.last_entry_index];
404 auto& right_sixaxis_entry =
405 npad.sixaxis_right.sixaxis[npad.sixaxis_right.common.last_entry_index];
406
407 switch (controller_type) {
408 case NPadControllerType::None:
409 UNREACHABLE();
410 break;
411 case NPadControllerType::ProController:
412 main_controller.connection_status.raw = 0;
413 main_controller.connection_status.IsConnected.Assign(1);
414 main_controller.connection_status.IsWired.Assign(1);
415 main_controller.pad.pad_states.raw = pad_state.pad_states.raw;
416 main_controller.pad.l_stick = pad_state.l_stick;
417 main_controller.pad.r_stick = pad_state.r_stick;
418
419 libnx_entry.connection_status.IsWired.Assign(1);
420 break;
421 case NPadControllerType::Handheld:
422 handheld_entry.connection_status.raw = 0;
423 handheld_entry.connection_status.IsConnected.Assign(1);
424 handheld_entry.connection_status.IsWired.Assign(1);
425 handheld_entry.connection_status.IsLeftJoyConnected.Assign(1);
426 handheld_entry.connection_status.IsRightJoyConnected.Assign(1);
427 handheld_entry.connection_status.IsLeftJoyWired.Assign(1);
428 handheld_entry.connection_status.IsRightJoyWired.Assign(1);
429 handheld_entry.pad.pad_states.raw = pad_state.pad_states.raw;
430 handheld_entry.pad.l_stick = pad_state.l_stick;
431 handheld_entry.pad.r_stick = pad_state.r_stick;
432
433 libnx_entry.connection_status.IsWired.Assign(1);
434 libnx_entry.connection_status.IsLeftJoyConnected.Assign(1);
435 libnx_entry.connection_status.IsRightJoyConnected.Assign(1);
436 libnx_entry.connection_status.IsLeftJoyWired.Assign(1);
437 libnx_entry.connection_status.IsRightJoyWired.Assign(1);
438 break;
439 case NPadControllerType::JoyDual:
440 dual_entry.connection_status.raw = 0;
441 dual_entry.connection_status.IsConnected.Assign(1);
442 dual_entry.connection_status.IsLeftJoyConnected.Assign(1);
443 dual_entry.connection_status.IsRightJoyConnected.Assign(1);
444 dual_entry.pad.pad_states.raw = pad_state.pad_states.raw;
445 dual_entry.pad.l_stick = pad_state.l_stick;
446 dual_entry.pad.r_stick = pad_state.r_stick;
447
448 libnx_entry.connection_status.IsLeftJoyConnected.Assign(1);
449 libnx_entry.connection_status.IsRightJoyConnected.Assign(1);
450 break;
451 case NPadControllerType::JoyLeft:
452 left_entry.connection_status.raw = 0;
453 left_entry.connection_status.IsConnected.Assign(1);
454 left_entry.connection_status.IsLeftJoyConnected.Assign(1);
455 left_entry.pad.pad_states.raw = pad_state.pad_states.raw;
456 left_entry.pad.l_stick = pad_state.l_stick;
457 left_entry.pad.r_stick = pad_state.r_stick;
458
459 libnx_entry.connection_status.IsLeftJoyConnected.Assign(1);
460 break;
461 case NPadControllerType::JoyRight:
462 right_entry.connection_status.raw = 0;
463 right_entry.connection_status.IsConnected.Assign(1);
464 right_entry.connection_status.IsRightJoyConnected.Assign(1);
465 right_entry.pad.pad_states.raw = pad_state.pad_states.raw;
466 right_entry.pad.l_stick = pad_state.l_stick;
467 right_entry.pad.r_stick = pad_state.r_stick;
468
469 libnx_entry.connection_status.IsRightJoyConnected.Assign(1);
470 break;
471 case NPadControllerType::Pokeball:
472 pokeball_entry.connection_status.raw = 0;
473 pokeball_entry.connection_status.IsConnected.Assign(1);
474 pokeball_entry.pad.pad_states.raw = pad_state.pad_states.raw;
475 pokeball_entry.pad.l_stick = pad_state.l_stick;
476 pokeball_entry.pad.r_stick = pad_state.r_stick;
477 break;
478 }
479
480 // LibNX exclusively uses this section, so we always update it since LibNX doesn't activate
481 // any controllers.
482 libnx_entry.pad.pad_states.raw = pad_state.pad_states.raw;
483 libnx_entry.pad.l_stick = pad_state.l_stick;
484 libnx_entry.pad.r_stick = pad_state.r_stick;
485
486 press_state |= static_cast<u32>(pad_state.pad_states.raw);
487 }
488 std::memcpy(data + NPAD_OFFSET, shared_memory_entries.data(),
489 shared_memory_entries.size() * sizeof(NPadEntry));
490}
491
492void Controller_NPad::OnMotionUpdate(const Core::Timing::CoreTiming& core_timing, u8* data,
493 std::size_t data_len) {
494 if (!IsControllerActivated()) {
495 return;
496 }
497 for (std::size_t i = 0; i < shared_memory_entries.size(); i++) {
498 auto& npad = shared_memory_entries[i];
499
500 const auto& controller_type = connected_controllers[i].type;
501
502 if (controller_type == NPadControllerType::None || !connected_controllers[i].is_connected) {
503 continue;
504 }
505
368 const std::array<SixAxisGeneric*, 6> controller_sixaxes{ 506 const std::array<SixAxisGeneric*, 6> controller_sixaxes{
369 &npad.sixaxis_full, &npad.sixaxis_handheld, &npad.sixaxis_dual_left, 507 &npad.sixaxis_full, &npad.sixaxis_handheld, &npad.sixaxis_dual_left,
370 &npad.sixaxis_dual_right, &npad.sixaxis_left, &npad.sixaxis_right, 508 &npad.sixaxis_dual_right, &npad.sixaxis_left, &npad.sixaxis_right,
@@ -403,9 +541,6 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8*
403 } 541 }
404 } 542 }
405 543
406 RequestPadStateUpdate(npad_index);
407 auto& pad_state = npad_pad_states[npad_index];
408
409 auto& main_controller = 544 auto& main_controller =
410 npad.main_controller_states.npad[npad.main_controller_states.common.last_entry_index]; 545 npad.main_controller_states.npad[npad.main_controller_states.common.last_entry_index];
411 auto& handheld_entry = 546 auto& handheld_entry =
@@ -418,8 +553,6 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8*
418 npad.pokeball_states.npad[npad.pokeball_states.common.last_entry_index]; 553 npad.pokeball_states.npad[npad.pokeball_states.common.last_entry_index];
419 auto& libnx_entry = npad.libnx.npad[npad.libnx.common.last_entry_index]; 554 auto& libnx_entry = npad.libnx.npad[npad.libnx.common.last_entry_index];
420 555
421 libnx_entry.connection_status.raw = 0;
422 libnx_entry.connection_status.IsConnected.Assign(1);
423 auto& full_sixaxis_entry = 556 auto& full_sixaxis_entry =
424 npad.sixaxis_full.sixaxis[npad.sixaxis_full.common.last_entry_index]; 557 npad.sixaxis_full.sixaxis[npad.sixaxis_full.common.last_entry_index];
425 auto& handheld_sixaxis_entry = 558 auto& handheld_sixaxis_entry =
@@ -438,15 +571,6 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8*
438 UNREACHABLE(); 571 UNREACHABLE();
439 break; 572 break;
440 case NPadControllerType::ProController: 573 case NPadControllerType::ProController:
441 main_controller.connection_status.raw = 0;
442 main_controller.connection_status.IsConnected.Assign(1);
443 main_controller.connection_status.IsWired.Assign(1);
444 main_controller.pad.pad_states.raw = pad_state.pad_states.raw;
445 main_controller.pad.l_stick = pad_state.l_stick;
446 main_controller.pad.r_stick = pad_state.r_stick;
447
448 libnx_entry.connection_status.IsWired.Assign(1);
449
450 if (sixaxis_sensors_enabled && motions[i][0]) { 574 if (sixaxis_sensors_enabled && motions[i][0]) {
451 full_sixaxis_entry.accel = motion_devices[0].accel; 575 full_sixaxis_entry.accel = motion_devices[0].accel;
452 full_sixaxis_entry.gyro = motion_devices[0].gyro; 576 full_sixaxis_entry.gyro = motion_devices[0].gyro;
@@ -455,23 +579,6 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8*
455 } 579 }
456 break; 580 break;
457 case NPadControllerType::Handheld: 581 case NPadControllerType::Handheld:
458 handheld_entry.connection_status.raw = 0;
459 handheld_entry.connection_status.IsConnected.Assign(1);
460 handheld_entry.connection_status.IsWired.Assign(1);
461 handheld_entry.connection_status.IsLeftJoyConnected.Assign(1);
462 handheld_entry.connection_status.IsRightJoyConnected.Assign(1);
463 handheld_entry.connection_status.IsLeftJoyWired.Assign(1);
464 handheld_entry.connection_status.IsRightJoyWired.Assign(1);
465 handheld_entry.pad.pad_states.raw = pad_state.pad_states.raw;
466 handheld_entry.pad.l_stick = pad_state.l_stick;
467 handheld_entry.pad.r_stick = pad_state.r_stick;
468
469 libnx_entry.connection_status.IsWired.Assign(1);
470 libnx_entry.connection_status.IsLeftJoyConnected.Assign(1);
471 libnx_entry.connection_status.IsRightJoyConnected.Assign(1);
472 libnx_entry.connection_status.IsLeftJoyWired.Assign(1);
473 libnx_entry.connection_status.IsRightJoyWired.Assign(1);
474
475 if (sixaxis_sensors_enabled && motions[i][0]) { 582 if (sixaxis_sensors_enabled && motions[i][0]) {
476 handheld_sixaxis_entry.accel = motion_devices[0].accel; 583 handheld_sixaxis_entry.accel = motion_devices[0].accel;
477 handheld_sixaxis_entry.gyro = motion_devices[0].gyro; 584 handheld_sixaxis_entry.gyro = motion_devices[0].gyro;
@@ -480,17 +587,6 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8*
480 } 587 }
481 break; 588 break;
482 case NPadControllerType::JoyDual: 589 case NPadControllerType::JoyDual:
483 dual_entry.connection_status.raw = 0;
484 dual_entry.connection_status.IsConnected.Assign(1);
485 dual_entry.connection_status.IsLeftJoyConnected.Assign(1);
486 dual_entry.connection_status.IsRightJoyConnected.Assign(1);
487 dual_entry.pad.pad_states.raw = pad_state.pad_states.raw;
488 dual_entry.pad.l_stick = pad_state.l_stick;
489 dual_entry.pad.r_stick = pad_state.r_stick;
490
491 libnx_entry.connection_status.IsLeftJoyConnected.Assign(1);
492 libnx_entry.connection_status.IsRightJoyConnected.Assign(1);
493
494 if (sixaxis_sensors_enabled && motions[i][0]) { 590 if (sixaxis_sensors_enabled && motions[i][0]) {
495 // Set motion for the left joycon 591 // Set motion for the left joycon
496 dual_left_sixaxis_entry.accel = motion_devices[0].accel; 592 dual_left_sixaxis_entry.accel = motion_devices[0].accel;
@@ -507,15 +603,6 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8*
507 } 603 }
508 break; 604 break;
509 case NPadControllerType::JoyLeft: 605 case NPadControllerType::JoyLeft:
510 left_entry.connection_status.raw = 0;
511 left_entry.connection_status.IsConnected.Assign(1);
512 left_entry.connection_status.IsLeftJoyConnected.Assign(1);
513 left_entry.pad.pad_states.raw = pad_state.pad_states.raw;
514 left_entry.pad.l_stick = pad_state.l_stick;
515 left_entry.pad.r_stick = pad_state.r_stick;
516
517 libnx_entry.connection_status.IsLeftJoyConnected.Assign(1);
518
519 if (sixaxis_sensors_enabled && motions[i][0]) { 606 if (sixaxis_sensors_enabled && motions[i][0]) {
520 left_sixaxis_entry.accel = motion_devices[0].accel; 607 left_sixaxis_entry.accel = motion_devices[0].accel;
521 left_sixaxis_entry.gyro = motion_devices[0].gyro; 608 left_sixaxis_entry.gyro = motion_devices[0].gyro;
@@ -524,15 +611,6 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8*
524 } 611 }
525 break; 612 break;
526 case NPadControllerType::JoyRight: 613 case NPadControllerType::JoyRight:
527 right_entry.connection_status.raw = 0;
528 right_entry.connection_status.IsConnected.Assign(1);
529 right_entry.connection_status.IsRightJoyConnected.Assign(1);
530 right_entry.pad.pad_states.raw = pad_state.pad_states.raw;
531 right_entry.pad.l_stick = pad_state.l_stick;
532 right_entry.pad.r_stick = pad_state.r_stick;
533
534 libnx_entry.connection_status.IsRightJoyConnected.Assign(1);
535
536 if (sixaxis_sensors_enabled && motions[i][1]) { 614 if (sixaxis_sensors_enabled && motions[i][1]) {
537 right_sixaxis_entry.accel = motion_devices[1].accel; 615 right_sixaxis_entry.accel = motion_devices[1].accel;
538 right_sixaxis_entry.gyro = motion_devices[1].gyro; 616 right_sixaxis_entry.gyro = motion_devices[1].gyro;
@@ -541,21 +619,8 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8*
541 } 619 }
542 break; 620 break;
543 case NPadControllerType::Pokeball: 621 case NPadControllerType::Pokeball:
544 pokeball_entry.connection_status.raw = 0;
545 pokeball_entry.connection_status.IsConnected.Assign(1);
546 pokeball_entry.pad.pad_states.raw = pad_state.pad_states.raw;
547 pokeball_entry.pad.l_stick = pad_state.l_stick;
548 pokeball_entry.pad.r_stick = pad_state.r_stick;
549 break; 622 break;
550 } 623 }
551
552 // LibNX exclusively uses this section, so we always update it since LibNX doesn't activate
553 // any controllers.
554 libnx_entry.pad.pad_states.raw = pad_state.pad_states.raw;
555 libnx_entry.pad.l_stick = pad_state.l_stick;
556 libnx_entry.pad.r_stick = pad_state.r_stick;
557
558 press_state |= static_cast<u32>(pad_state.pad_states.raw);
559 } 624 }
560 std::memcpy(data + NPAD_OFFSET, shared_memory_entries.data(), 625 std::memcpy(data + NPAD_OFFSET, shared_memory_entries.data(),
561 shared_memory_entries.size() * sizeof(NPadEntry)); 626 shared_memory_entries.size() * sizeof(NPadEntry));
@@ -609,20 +674,31 @@ void Controller_NPad::SetNpadMode(u32 npad_id, NPadAssignments assignment_mode)
609 } 674 }
610} 675}
611 676
612void Controller_NPad::VibrateController(const std::vector<u32>& controller_ids, 677void Controller_NPad::VibrateController(const std::vector<u32>& controllers,
613 const std::vector<Vibration>& vibrations) { 678 const std::vector<Vibration>& vibrations) {
614 LOG_DEBUG(Service_HID, "(STUBBED) called"); 679 LOG_TRACE(Service_HID, "called");
615 680
616 if (!Settings::values.vibration_enabled || !can_controllers_vibrate) { 681 if (!Settings::values.vibration_enabled || !can_controllers_vibrate) {
617 return; 682 return;
618 } 683 }
619 for (std::size_t i = 0; i < controller_ids.size(); i++) { 684 bool success = true;
620 std::size_t controller_pos = NPadIdToIndex(static_cast<u32>(i)); 685 for (std::size_t i = 0; i < controllers.size(); ++i) {
621 if (connected_controllers[controller_pos].is_connected) { 686 if (!connected_controllers[i].is_connected) {
622 // TODO(ogniK): Vibrate the physical controller 687 continue;
623 } 688 }
689 using namespace Settings::NativeButton;
690 const auto& button_state = buttons[i];
691 if (button_state[A - BUTTON_HID_BEGIN]) {
692 if (button_state[A - BUTTON_HID_BEGIN]->SetRumblePlay(
693 vibrations[0].amp_high, vibrations[0].amp_low, vibrations[0].freq_high,
694 vibrations[0].freq_low)) {
695 success = false;
696 }
697 }
698 }
699 if (success) {
700 last_processed_vibration = vibrations.back();
624 } 701 }
625 last_processed_vibration = vibrations.back();
626} 702}
627 703
628Controller_NPad::Vibration Controller_NPad::GetLastVibration() const { 704Controller_NPad::Vibration Controller_NPad::GetLastVibration() const {
@@ -770,6 +846,15 @@ Controller_NPad::LedPattern Controller_NPad::GetLedPattern(u32 npad_id) {
770 } 846 }
771} 847}
772 848
849bool Controller_NPad::IsUnintendedHomeButtonInputProtectionEnabled(u32 npad_id) const {
850 return unintended_home_button_input_protection[NPadIdToIndex(npad_id)];
851}
852
853void Controller_NPad::SetUnintendedHomeButtonInputProtectionEnabled(bool is_protection_enabled,
854 u32 npad_id) {
855 unintended_home_button_input_protection[NPadIdToIndex(npad_id)] = is_protection_enabled;
856}
857
773void Controller_NPad::SetVibrationEnabled(bool can_vibrate) { 858void Controller_NPad::SetVibrationEnabled(bool can_vibrate) {
774 can_controllers_vibrate = can_vibrate; 859 can_controllers_vibrate = can_vibrate;
775} 860}
diff --git a/src/core/hle/service/hid/controllers/npad.h b/src/core/hle/service/hid/controllers/npad.h
index 654d97c3f..fd5c5a6eb 100644
--- a/src/core/hle/service/hid/controllers/npad.h
+++ b/src/core/hle/service/hid/controllers/npad.h
@@ -32,6 +32,10 @@ public:
32 // When the controller is requesting an update for the shared memory 32 // When the controller is requesting an update for the shared memory
33 void OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data, std::size_t size) override; 33 void OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data, std::size_t size) override;
34 34
35 // When the controller is requesting a motion update for the shared memory
36 void OnMotionUpdate(const Core::Timing::CoreTiming& core_timing, u8* data,
37 std::size_t size) override;
38
35 // Called when input devices should be loaded 39 // Called when input devices should be loaded
36 void OnLoadInputDevices() override; 40 void OnLoadInputDevices() override;
37 41
@@ -121,7 +125,7 @@ public:
121 125
122 void SetNpadMode(u32 npad_id, NPadAssignments assignment_mode); 126 void SetNpadMode(u32 npad_id, NPadAssignments assignment_mode);
123 127
124 void VibrateController(const std::vector<u32>& controller_ids, 128 void VibrateController(const std::vector<u32>& controllers,
125 const std::vector<Vibration>& vibrations); 129 const std::vector<Vibration>& vibrations);
126 130
127 Vibration GetLastVibration() const; 131 Vibration GetLastVibration() const;
@@ -142,6 +146,8 @@ public:
142 bool IsSixAxisSensorAtRest() const; 146 bool IsSixAxisSensorAtRest() const;
143 void SetSixAxisEnabled(bool six_axis_status); 147 void SetSixAxisEnabled(bool six_axis_status);
144 LedPattern GetLedPattern(u32 npad_id); 148 LedPattern GetLedPattern(u32 npad_id);
149 bool IsUnintendedHomeButtonInputProtectionEnabled(u32 npad_id) const;
150 void SetUnintendedHomeButtonInputProtectionEnabled(bool is_protection_enabled, u32 npad_id);
145 void SetVibrationEnabled(bool can_vibrate); 151 void SetVibrationEnabled(bool can_vibrate);
146 bool IsVibrationEnabled() const; 152 bool IsVibrationEnabled() const;
147 void ClearAllConnectedControllers(); 153 void ClearAllConnectedControllers();
@@ -383,6 +389,7 @@ private:
383 std::array<Kernel::EventPair, 10> styleset_changed_events; 389 std::array<Kernel::EventPair, 10> styleset_changed_events;
384 Vibration last_processed_vibration{}; 390 Vibration last_processed_vibration{};
385 std::array<ControllerHolder, 10> connected_controllers{}; 391 std::array<ControllerHolder, 10> connected_controllers{};
392 std::array<bool, 10> unintended_home_button_input_protection{};
386 GyroscopeZeroDriftMode gyroscope_zero_drift_mode{GyroscopeZeroDriftMode::Standard}; 393 GyroscopeZeroDriftMode gyroscope_zero_drift_mode{GyroscopeZeroDriftMode::Standard};
387 bool can_controllers_vibrate{true}; 394 bool can_controllers_vibrate{true};
388 bool sixaxis_sensors_enabled{true}; 395 bool sixaxis_sensors_enabled{true};
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp
index 395e83b3f..71dbaba7f 100644
--- a/src/core/hle/service/hid/hid.cpp
+++ b/src/core/hle/service/hid/hid.cpp
@@ -40,7 +40,8 @@ namespace Service::HID {
40// Updating period for each HID device. 40// Updating period for each HID device.
41// HID is polled every 15ms, this value was derived from 41// HID is polled every 15ms, this value was derived from
42// https://github.com/dekuNukem/Nintendo_Switch_Reverse_Engineering#joy-con-status-data-packet 42// https://github.com/dekuNukem/Nintendo_Switch_Reverse_Engineering#joy-con-status-data-packet
43constexpr auto pad_update_ns = std::chrono::nanoseconds{1000 * 1000}; // (1ms, 1000Hz) 43constexpr auto pad_update_ns = std::chrono::nanoseconds{1000 * 1000}; // (1ms, 1000Hz)
44constexpr auto motion_update_ns = std::chrono::nanoseconds{15 * 1000 * 1000}; // (15ms, 66.666Hz)
44constexpr std::size_t SHARED_MEMORY_SIZE = 0x40000; 45constexpr std::size_t SHARED_MEMORY_SIZE = 0x40000;
45 46
46IAppletResource::IAppletResource(Core::System& system) 47IAppletResource::IAppletResource(Core::System& system)
@@ -79,10 +80,14 @@ IAppletResource::IAppletResource(Core::System& system)
79 [this](std::uintptr_t user_data, std::chrono::nanoseconds ns_late) { 80 [this](std::uintptr_t user_data, std::chrono::nanoseconds ns_late) {
80 UpdateControllers(user_data, ns_late); 81 UpdateControllers(user_data, ns_late);
81 }); 82 });
82 83 motion_update_event = Core::Timing::CreateEvent(
83 // TODO(shinyquagsire23): Other update callbacks? (accel, gyro?) 84 "HID::MotionPadCallback",
85 [this](std::uintptr_t user_data, std::chrono::nanoseconds ns_late) {
86 UpdateMotion(user_data, ns_late);
87 });
84 88
85 system.CoreTiming().ScheduleEvent(pad_update_ns, pad_update_event); 89 system.CoreTiming().ScheduleEvent(pad_update_ns, pad_update_event);
90 system.CoreTiming().ScheduleEvent(motion_update_ns, motion_update_event);
86 91
87 ReloadInputDevices(); 92 ReloadInputDevices();
88} 93}
@@ -122,6 +127,16 @@ void IAppletResource::UpdateControllers(std::uintptr_t user_data,
122 core_timing.ScheduleEvent(pad_update_ns - ns_late, pad_update_event); 127 core_timing.ScheduleEvent(pad_update_ns - ns_late, pad_update_event);
123} 128}
124 129
130void IAppletResource::UpdateMotion(std::uintptr_t user_data, std::chrono::nanoseconds ns_late) {
131 auto& core_timing = system.CoreTiming();
132
133 for (const auto& controller : controllers) {
134 controller->OnMotionUpdate(core_timing, shared_mem->GetPointer(), SHARED_MEMORY_SIZE);
135 }
136
137 core_timing.ScheduleEvent(motion_update_ns - ns_late, motion_update_event);
138}
139
125class IActiveVibrationDeviceList final : public ServiceFramework<IActiveVibrationDeviceList> { 140class IActiveVibrationDeviceList final : public ServiceFramework<IActiveVibrationDeviceList> {
126public: 141public:
127 IActiveVibrationDeviceList() : ServiceFramework("IActiveVibrationDeviceList") { 142 IActiveVibrationDeviceList() : ServiceFramework("IActiveVibrationDeviceList") {
@@ -173,7 +188,7 @@ Hid::Hid(Core::System& system) : ServiceFramework("hid"), system(system) {
173 {66, &Hid::StartSixAxisSensor, "StartSixAxisSensor"}, 188 {66, &Hid::StartSixAxisSensor, "StartSixAxisSensor"},
174 {67, &Hid::StopSixAxisSensor, "StopSixAxisSensor"}, 189 {67, &Hid::StopSixAxisSensor, "StopSixAxisSensor"},
175 {68, nullptr, "IsSixAxisSensorFusionEnabled"}, 190 {68, nullptr, "IsSixAxisSensorFusionEnabled"},
176 {69, nullptr, "EnableSixAxisSensorFusion"}, 191 {69, &Hid::EnableSixAxisSensorFusion, "EnableSixAxisSensorFusion"},
177 {70, nullptr, "SetSixAxisSensorFusionParameters"}, 192 {70, nullptr, "SetSixAxisSensorFusionParameters"},
178 {71, nullptr, "GetSixAxisSensorFusionParameters"}, 193 {71, nullptr, "GetSixAxisSensorFusionParameters"},
179 {72, nullptr, "ResetSixAxisSensorFusionParameters"}, 194 {72, nullptr, "ResetSixAxisSensorFusionParameters"},
@@ -209,8 +224,8 @@ Hid::Hid(Core::System& system) : ServiceFramework("hid"), system(system) {
209 {128, &Hid::SetNpadHandheldActivationMode, "SetNpadHandheldActivationMode"}, 224 {128, &Hid::SetNpadHandheldActivationMode, "SetNpadHandheldActivationMode"},
210 {129, &Hid::GetNpadHandheldActivationMode, "GetNpadHandheldActivationMode"}, 225 {129, &Hid::GetNpadHandheldActivationMode, "GetNpadHandheldActivationMode"},
211 {130, &Hid::SwapNpadAssignment, "SwapNpadAssignment"}, 226 {130, &Hid::SwapNpadAssignment, "SwapNpadAssignment"},
212 {131, nullptr, "IsUnintendedHomeButtonInputProtectionEnabled"}, 227 {131, &Hid::IsUnintendedHomeButtonInputProtectionEnabled, "IsUnintendedHomeButtonInputProtectionEnabled"},
213 {132, nullptr, "EnableUnintendedHomeButtonInputProtection"}, 228 {132, &Hid::EnableUnintendedHomeButtonInputProtection, "EnableUnintendedHomeButtonInputProtection"},
214 {133, nullptr, "SetNpadJoyAssignmentModeSingleWithDestination"}, 229 {133, nullptr, "SetNpadJoyAssignmentModeSingleWithDestination"},
215 {134, nullptr, "SetNpadAnalogStickUseCenterClamp"}, 230 {134, nullptr, "SetNpadAnalogStickUseCenterClamp"},
216 {135, nullptr, "SetNpadCaptureButtonAssignment"}, 231 {135, nullptr, "SetNpadCaptureButtonAssignment"},
@@ -458,6 +473,19 @@ void Hid::StopSixAxisSensor(Kernel::HLERequestContext& ctx) {
458 rb.Push(RESULT_SUCCESS); 473 rb.Push(RESULT_SUCCESS);
459} 474}
460 475
476void Hid::EnableSixAxisSensorFusion(Kernel::HLERequestContext& ctx) {
477 IPC::RequestParser rp{ctx};
478 const auto enable{rp.Pop<bool>()};
479 const auto handle{rp.Pop<u32>()};
480 const auto applet_resource_user_id{rp.Pop<u64>()};
481
482 LOG_WARNING(Service_HID, "(STUBBED) called, handle={}, applet_resource_user_id={}", handle,
483 applet_resource_user_id);
484
485 IPC::ResponseBuilder rb{ctx, 2};
486 rb.Push(RESULT_SUCCESS);
487}
488
461void Hid::SetGyroscopeZeroDriftMode(Kernel::HLERequestContext& ctx) { 489void Hid::SetGyroscopeZeroDriftMode(Kernel::HLERequestContext& ctx) {
462 IPC::RequestParser rp{ctx}; 490 IPC::RequestParser rp{ctx};
463 const auto handle{rp.Pop<u32>()}; 491 const auto handle{rp.Pop<u32>()};
@@ -781,6 +809,40 @@ void Hid::SwapNpadAssignment(Kernel::HLERequestContext& ctx) {
781 } 809 }
782} 810}
783 811
812void Hid::IsUnintendedHomeButtonInputProtectionEnabled(Kernel::HLERequestContext& ctx) {
813 IPC::RequestParser rp{ctx};
814 const auto npad_id{rp.Pop<u32>()};
815 const auto applet_resource_user_id{rp.Pop<u64>()};
816
817 LOG_WARNING(Service_HID, "(STUBBED) called, npad_id={}, applet_resource_user_id={}", npad_id,
818 applet_resource_user_id);
819
820 auto& controller = applet_resource->GetController<Controller_NPad>(HidController::NPad);
821
822 IPC::ResponseBuilder rb{ctx, 3};
823 rb.Push(RESULT_SUCCESS);
824 rb.Push<bool>(controller.IsUnintendedHomeButtonInputProtectionEnabled(npad_id));
825}
826
827void Hid::EnableUnintendedHomeButtonInputProtection(Kernel::HLERequestContext& ctx) {
828 IPC::RequestParser rp{ctx};
829 const auto unintended_home_button_input_protection{rp.Pop<bool>()};
830 const auto npad_id{rp.Pop<u32>()};
831 const auto applet_resource_user_id{rp.Pop<u64>()};
832
833 LOG_WARNING(Service_HID,
834 "(STUBBED) called, unintended_home_button_input_protection={}, npad_id={},"
835 "applet_resource_user_id={}",
836 npad_id, unintended_home_button_input_protection, applet_resource_user_id);
837
838 auto& controller = applet_resource->GetController<Controller_NPad>(HidController::NPad);
839 controller.SetUnintendedHomeButtonInputProtectionEnabled(
840 unintended_home_button_input_protection, npad_id);
841
842 IPC::ResponseBuilder rb{ctx, 2};
843 rb.Push(RESULT_SUCCESS);
844}
845
784void Hid::BeginPermitVibrationSession(Kernel::HLERequestContext& ctx) { 846void Hid::BeginPermitVibrationSession(Kernel::HLERequestContext& ctx) {
785 IPC::RequestParser rp{ctx}; 847 IPC::RequestParser rp{ctx};
786 const auto applet_resource_user_id{rp.Pop<u64>()}; 848 const auto applet_resource_user_id{rp.Pop<u64>()};
@@ -802,18 +864,18 @@ void Hid::EndPermitVibrationSession(Kernel::HLERequestContext& ctx) {
802 864
803void Hid::SendVibrationValue(Kernel::HLERequestContext& ctx) { 865void Hid::SendVibrationValue(Kernel::HLERequestContext& ctx) {
804 IPC::RequestParser rp{ctx}; 866 IPC::RequestParser rp{ctx};
805 const auto controller_id{rp.Pop<u32>()}; 867 const auto controller{rp.Pop<u32>()};
806 const auto vibration_values{rp.PopRaw<Controller_NPad::Vibration>()}; 868 const auto vibration_values{rp.PopRaw<Controller_NPad::Vibration>()};
807 const auto applet_resource_user_id{rp.Pop<u64>()}; 869 const auto applet_resource_user_id{rp.Pop<u64>()};
808 870
809 LOG_DEBUG(Service_HID, "called, controller_id={}, applet_resource_user_id={}", controller_id, 871 LOG_DEBUG(Service_HID, "called, controller={}, applet_resource_user_id={}", controller,
810 applet_resource_user_id); 872 applet_resource_user_id);
811 873
812 IPC::ResponseBuilder rb{ctx, 2}; 874 IPC::ResponseBuilder rb{ctx, 2};
813 rb.Push(RESULT_SUCCESS); 875 rb.Push(RESULT_SUCCESS);
814 876
815 applet_resource->GetController<Controller_NPad>(HidController::NPad) 877 applet_resource->GetController<Controller_NPad>(HidController::NPad)
816 .VibrateController({controller_id}, {vibration_values}); 878 .VibrateController({controller}, {vibration_values});
817} 879}
818 880
819void Hid::SendVibrationValues(Kernel::HLERequestContext& ctx) { 881void Hid::SendVibrationValues(Kernel::HLERequestContext& ctx) {
@@ -831,8 +893,6 @@ void Hid::SendVibrationValues(Kernel::HLERequestContext& ctx) {
831 893
832 std::memcpy(controller_list.data(), controllers.data(), controllers.size()); 894 std::memcpy(controller_list.data(), controllers.data(), controllers.size());
833 std::memcpy(vibration_list.data(), vibrations.data(), vibrations.size()); 895 std::memcpy(vibration_list.data(), vibrations.data(), vibrations.size());
834 std::transform(controller_list.begin(), controller_list.end(), controller_list.begin(),
835 [](u32 controller_id) { return controller_id - 3; });
836 896
837 applet_resource->GetController<Controller_NPad>(HidController::NPad) 897 applet_resource->GetController<Controller_NPad>(HidController::NPad)
838 .VibrateController(controller_list, vibration_list); 898 .VibrateController(controller_list, vibration_list);
diff --git a/src/core/hle/service/hid/hid.h b/src/core/hle/service/hid/hid.h
index e04aaf1e9..fd0372b18 100644
--- a/src/core/hle/service/hid/hid.h
+++ b/src/core/hle/service/hid/hid.h
@@ -65,10 +65,12 @@ private:
65 65
66 void GetSharedMemoryHandle(Kernel::HLERequestContext& ctx); 66 void GetSharedMemoryHandle(Kernel::HLERequestContext& ctx);
67 void UpdateControllers(std::uintptr_t user_data, std::chrono::nanoseconds ns_late); 67 void UpdateControllers(std::uintptr_t user_data, std::chrono::nanoseconds ns_late);
68 void UpdateMotion(std::uintptr_t user_data, std::chrono::nanoseconds ns_late);
68 69
69 std::shared_ptr<Kernel::SharedMemory> shared_mem; 70 std::shared_ptr<Kernel::SharedMemory> shared_mem;
70 71
71 std::shared_ptr<Core::Timing::EventType> pad_update_event; 72 std::shared_ptr<Core::Timing::EventType> pad_update_event;
73 std::shared_ptr<Core::Timing::EventType> motion_update_event;
72 Core::System& system; 74 Core::System& system;
73 75
74 std::array<std::unique_ptr<ControllerBase>, static_cast<size_t>(HidController::MaxControllers)> 76 std::array<std::unique_ptr<ControllerBase>, static_cast<size_t>(HidController::MaxControllers)>
@@ -97,6 +99,7 @@ private:
97 void ActivateNpadWithRevision(Kernel::HLERequestContext& ctx); 99 void ActivateNpadWithRevision(Kernel::HLERequestContext& ctx);
98 void StartSixAxisSensor(Kernel::HLERequestContext& ctx); 100 void StartSixAxisSensor(Kernel::HLERequestContext& ctx);
99 void StopSixAxisSensor(Kernel::HLERequestContext& ctx); 101 void StopSixAxisSensor(Kernel::HLERequestContext& ctx);
102 void EnableSixAxisSensorFusion(Kernel::HLERequestContext& ctx);
100 void SetGyroscopeZeroDriftMode(Kernel::HLERequestContext& ctx); 103 void SetGyroscopeZeroDriftMode(Kernel::HLERequestContext& ctx);
101 void GetGyroscopeZeroDriftMode(Kernel::HLERequestContext& ctx); 104 void GetGyroscopeZeroDriftMode(Kernel::HLERequestContext& ctx);
102 void ResetGyroscopeZeroDriftMode(Kernel::HLERequestContext& ctx); 105 void ResetGyroscopeZeroDriftMode(Kernel::HLERequestContext& ctx);
@@ -120,6 +123,8 @@ private:
120 void SetNpadHandheldActivationMode(Kernel::HLERequestContext& ctx); 123 void SetNpadHandheldActivationMode(Kernel::HLERequestContext& ctx);
121 void GetNpadHandheldActivationMode(Kernel::HLERequestContext& ctx); 124 void GetNpadHandheldActivationMode(Kernel::HLERequestContext& ctx);
122 void SwapNpadAssignment(Kernel::HLERequestContext& ctx); 125 void SwapNpadAssignment(Kernel::HLERequestContext& ctx);
126 void IsUnintendedHomeButtonInputProtectionEnabled(Kernel::HLERequestContext& ctx);
127 void EnableUnintendedHomeButtonInputProtection(Kernel::HLERequestContext& ctx);
123 void BeginPermitVibrationSession(Kernel::HLERequestContext& ctx); 128 void BeginPermitVibrationSession(Kernel::HLERequestContext& ctx);
124 void EndPermitVibrationSession(Kernel::HLERequestContext& ctx); 129 void EndPermitVibrationSession(Kernel::HLERequestContext& ctx);
125 void SendVibrationValue(Kernel::HLERequestContext& ctx); 130 void SendVibrationValue(Kernel::HLERequestContext& ctx);
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp
index bdae8b887..fcb612864 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp
@@ -22,6 +22,18 @@ u32 nvhost_nvdec::ioctl(Ioctl command, const std::vector<u8>& input, const std::
22 switch (static_cast<IoctlCommand>(command.raw)) { 22 switch (static_cast<IoctlCommand>(command.raw)) {
23 case IoctlCommand::IocSetNVMAPfdCommand: 23 case IoctlCommand::IocSetNVMAPfdCommand:
24 return SetNVMAPfd(input, output); 24 return SetNVMAPfd(input, output);
25 case IoctlCommand::IocSubmit:
26 return Submit(input, output);
27 case IoctlCommand::IocGetSyncpoint:
28 return GetSyncpoint(input, output);
29 case IoctlCommand::IocGetWaitbase:
30 return GetWaitbase(input, output);
31 case IoctlCommand::IocMapBuffer:
32 return MapBuffer(input, output);
33 case IoctlCommand::IocMapBufferEx:
34 return MapBufferEx(input, output);
35 case IoctlCommand::IocUnmapBufferEx:
36 return UnmapBufferEx(input, output);
25 } 37 }
26 38
27 UNIMPLEMENTED_MSG("Unimplemented ioctl"); 39 UNIMPLEMENTED_MSG("Unimplemented ioctl");
@@ -30,11 +42,67 @@ u32 nvhost_nvdec::ioctl(Ioctl command, const std::vector<u8>& input, const std::
30 42
31u32 nvhost_nvdec::SetNVMAPfd(const std::vector<u8>& input, std::vector<u8>& output) { 43u32 nvhost_nvdec::SetNVMAPfd(const std::vector<u8>& input, std::vector<u8>& output) {
32 IoctlSetNvmapFD params{}; 44 IoctlSetNvmapFD params{};
33 std::memcpy(&params, input.data(), input.size()); 45 std::memcpy(&params, input.data(), sizeof(IoctlSetNvmapFD));
34 LOG_DEBUG(Service_NVDRV, "called, fd={}", params.nvmap_fd); 46 LOG_DEBUG(Service_NVDRV, "called, fd={}", params.nvmap_fd);
35 47
36 nvmap_fd = params.nvmap_fd; 48 nvmap_fd = params.nvmap_fd;
37 return 0; 49 return 0;
38} 50}
39 51
52u32 nvhost_nvdec::Submit(const std::vector<u8>& input, std::vector<u8>& output) {
53 IoctlSubmit params{};
54 std::memcpy(&params, input.data(), sizeof(IoctlSubmit));
55 LOG_WARNING(Service_NVDRV, "(STUBBED) called");
56 std::memcpy(output.data(), &params, sizeof(IoctlSubmit));
57 return 0;
58}
59
60u32 nvhost_nvdec::GetSyncpoint(const std::vector<u8>& input, std::vector<u8>& output) {
61 IoctlGetSyncpoint params{};
62 std::memcpy(&params, input.data(), sizeof(IoctlGetSyncpoint));
63 LOG_INFO(Service_NVDRV, "called, unknown=0x{:X}", params.unknown);
64 params.value = 0; // Seems to be hard coded at 0
65 std::memcpy(output.data(), &params, sizeof(IoctlGetSyncpoint));
66 return 0;
67}
68
69u32 nvhost_nvdec::GetWaitbase(const std::vector<u8>& input, std::vector<u8>& output) {
70 IoctlGetWaitbase params{};
71 std::memcpy(&params, input.data(), sizeof(IoctlGetWaitbase));
72 LOG_INFO(Service_NVDRV, "called, unknown=0x{:X}", params.unknown);
73 params.value = 0; // Seems to be hard coded at 0
74 std::memcpy(output.data(), &params, sizeof(IoctlGetWaitbase));
75 return 0;
76}
77
78u32 nvhost_nvdec::MapBuffer(const std::vector<u8>& input, std::vector<u8>& output) {
79 IoctlMapBuffer params{};
80 std::memcpy(&params, input.data(), sizeof(IoctlMapBuffer));
81 LOG_WARNING(Service_NVDRV, "(STUBBED) called with address={:08X}{:08X}", params.address_2,
82 params.address_1);
83 params.address_1 = 0;
84 params.address_2 = 0;
85 std::memcpy(output.data(), &params, sizeof(IoctlMapBuffer));
86 return 0;
87}
88
89u32 nvhost_nvdec::MapBufferEx(const std::vector<u8>& input, std::vector<u8>& output) {
90 IoctlMapBufferEx params{};
91 std::memcpy(&params, input.data(), sizeof(IoctlMapBufferEx));
92 LOG_WARNING(Service_NVDRV, "(STUBBED) called with address={:08X}{:08X}", params.address_2,
93 params.address_1);
94 params.address_1 = 0;
95 params.address_2 = 0;
96 std::memcpy(output.data(), &params, sizeof(IoctlMapBufferEx));
97 return 0;
98}
99
100u32 nvhost_nvdec::UnmapBufferEx(const std::vector<u8>& input, std::vector<u8>& output) {
101 IoctlUnmapBufferEx params{};
102 std::memcpy(&params, input.data(), sizeof(IoctlUnmapBufferEx));
103 LOG_WARNING(Service_NVDRV, "(STUBBED) called");
104 std::memcpy(output.data(), &params, sizeof(IoctlUnmapBufferEx));
105 return 0;
106}
107
40} // namespace Service::Nvidia::Devices 108} // namespace Service::Nvidia::Devices
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.h b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.h
index cbdac8069..4332db118 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.h
+++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.h
@@ -23,16 +23,66 @@ public:
23private: 23private:
24 enum class IoctlCommand : u32_le { 24 enum class IoctlCommand : u32_le {
25 IocSetNVMAPfdCommand = 0x40044801, 25 IocSetNVMAPfdCommand = 0x40044801,
26 IocSubmit = 0xC0400001,
27 IocGetSyncpoint = 0xC0080002,
28 IocGetWaitbase = 0xC0080003,
29 IocMapBuffer = 0xC01C0009,
30 IocMapBufferEx = 0xC0A40009,
31 IocUnmapBufferEx = 0xC0A4000A,
26 }; 32 };
27 33
28 struct IoctlSetNvmapFD { 34 struct IoctlSetNvmapFD {
29 u32_le nvmap_fd; 35 u32_le nvmap_fd;
30 }; 36 };
31 static_assert(sizeof(IoctlSetNvmapFD) == 4, "IoctlSetNvmapFD is incorrect size"); 37 static_assert(sizeof(IoctlSetNvmapFD) == 0x4, "IoctlSetNvmapFD is incorrect size");
38
39 struct IoctlSubmit {
40 INSERT_PADDING_BYTES(0x40); // TODO(DarkLordZach): RE this structure
41 };
42 static_assert(sizeof(IoctlSubmit) == 0x40, "IoctlSubmit has incorrect size");
43
44 struct IoctlGetSyncpoint {
45 u32 unknown; // seems to be ignored? Nintendo added this
46 u32 value;
47 };
48 static_assert(sizeof(IoctlGetSyncpoint) == 0x08, "IoctlGetSyncpoint has incorrect size");
49
50 struct IoctlGetWaitbase {
51 u32 unknown; // seems to be ignored? Nintendo added this
52 u32 value;
53 };
54 static_assert(sizeof(IoctlGetWaitbase) == 0x08, "IoctlGetWaitbase has incorrect size");
55
56 struct IoctlMapBuffer {
57 u32 unknown;
58 u32 address_1;
59 u32 address_2;
60 INSERT_PADDING_BYTES(0x10); // TODO(DarkLordZach): RE this structure
61 };
62 static_assert(sizeof(IoctlMapBuffer) == 0x1C, "IoctlMapBuffer is incorrect size");
63
64 struct IoctlMapBufferEx {
65 u32 unknown;
66 u32 address_1;
67 u32 address_2;
68 INSERT_PADDING_BYTES(0x98); // TODO(DarkLordZach): RE this structure
69 };
70 static_assert(sizeof(IoctlMapBufferEx) == 0xA4, "IoctlMapBufferEx has incorrect size");
71
72 struct IoctlUnmapBufferEx {
73 INSERT_PADDING_BYTES(0xA4); // TODO(DarkLordZach): RE this structure
74 };
75 static_assert(sizeof(IoctlUnmapBufferEx) == 0xA4, "IoctlUnmapBufferEx has incorrect size");
32 76
33 u32_le nvmap_fd{}; 77 u32_le nvmap_fd{};
34 78
35 u32 SetNVMAPfd(const std::vector<u8>& input, std::vector<u8>& output); 79 u32 SetNVMAPfd(const std::vector<u8>& input, std::vector<u8>& output);
80 u32 Submit(const std::vector<u8>& input, std::vector<u8>& output);
81 u32 GetSyncpoint(const std::vector<u8>& input, std::vector<u8>& output);
82 u32 GetWaitbase(const std::vector<u8>& input, std::vector<u8>& output);
83 u32 MapBuffer(const std::vector<u8>& input, std::vector<u8>& output);
84 u32 MapBufferEx(const std::vector<u8>& input, std::vector<u8>& output);
85 u32 UnmapBufferEx(const std::vector<u8>& input, std::vector<u8>& output);
36}; 86};
37 87
38} // namespace Service::Nvidia::Devices 88} // namespace Service::Nvidia::Devices
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp b/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp
index c695b8863..9da19ad56 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp
@@ -22,6 +22,18 @@ u32 nvhost_vic::ioctl(Ioctl command, const std::vector<u8>& input, const std::ve
22 switch (static_cast<IoctlCommand>(command.raw)) { 22 switch (static_cast<IoctlCommand>(command.raw)) {
23 case IoctlCommand::IocSetNVMAPfdCommand: 23 case IoctlCommand::IocSetNVMAPfdCommand:
24 return SetNVMAPfd(input, output); 24 return SetNVMAPfd(input, output);
25 case IoctlCommand::IocSubmit:
26 return Submit(input, output);
27 case IoctlCommand::IocGetSyncpoint:
28 return GetSyncpoint(input, output);
29 case IoctlCommand::IocGetWaitbase:
30 return GetWaitbase(input, output);
31 case IoctlCommand::IocMapBuffer:
32 return MapBuffer(input, output);
33 case IoctlCommand::IocMapBufferEx:
34 return MapBuffer(input, output);
35 case IoctlCommand::IocUnmapBufferEx:
36 return UnmapBufferEx(input, output);
25 } 37 }
26 38
27 UNIMPLEMENTED_MSG("Unimplemented ioctl"); 39 UNIMPLEMENTED_MSG("Unimplemented ioctl");
@@ -30,11 +42,71 @@ u32 nvhost_vic::ioctl(Ioctl command, const std::vector<u8>& input, const std::ve
30 42
31u32 nvhost_vic::SetNVMAPfd(const std::vector<u8>& input, std::vector<u8>& output) { 43u32 nvhost_vic::SetNVMAPfd(const std::vector<u8>& input, std::vector<u8>& output) {
32 IoctlSetNvmapFD params{}; 44 IoctlSetNvmapFD params{};
33 std::memcpy(&params, input.data(), input.size()); 45 std::memcpy(&params, input.data(), sizeof(IoctlSetNvmapFD));
34 LOG_DEBUG(Service_NVDRV, "called, fd={}", params.nvmap_fd); 46 LOG_DEBUG(Service_NVDRV, "called, fd={}", params.nvmap_fd);
35 47
36 nvmap_fd = params.nvmap_fd; 48 nvmap_fd = params.nvmap_fd;
37 return 0; 49 return 0;
38} 50}
39 51
52u32 nvhost_vic::Submit(const std::vector<u8>& input, std::vector<u8>& output) {
53 IoctlSubmit params{};
54 std::memcpy(&params, input.data(), sizeof(IoctlSubmit));
55 LOG_WARNING(Service_NVDRV, "(STUBBED) called");
56
57 // Workaround for Luigi's Mansion 3, as nvhost_vic is not implemented for asynch GPU
58 params.command_buffer = {};
59
60 std::memcpy(output.data(), &params, sizeof(IoctlSubmit));
61 return 0;
62}
63
64u32 nvhost_vic::GetSyncpoint(const std::vector<u8>& input, std::vector<u8>& output) {
65 IoctlGetSyncpoint params{};
66 std::memcpy(&params, input.data(), sizeof(IoctlGetSyncpoint));
67 LOG_INFO(Service_NVDRV, "called, unknown=0x{:X}", params.unknown);
68 params.value = 0; // Seems to be hard coded at 0
69 std::memcpy(output.data(), &params, sizeof(IoctlGetSyncpoint));
70 return 0;
71}
72
73u32 nvhost_vic::GetWaitbase(const std::vector<u8>& input, std::vector<u8>& output) {
74 IoctlGetWaitbase params{};
75 std::memcpy(&params, input.data(), sizeof(IoctlGetWaitbase));
76 LOG_INFO(Service_NVDRV, "called, unknown=0x{:X}", params.unknown);
77 params.value = 0; // Seems to be hard coded at 0
78 std::memcpy(output.data(), &params, sizeof(IoctlGetWaitbase));
79 return 0;
80}
81
82u32 nvhost_vic::MapBuffer(const std::vector<u8>& input, std::vector<u8>& output) {
83 IoctlMapBuffer params{};
84 std::memcpy(&params, input.data(), sizeof(IoctlMapBuffer));
85 LOG_WARNING(Service_NVDRV, "(STUBBED) called with address={:08X}{:08X}", params.address_2,
86 params.address_1);
87 params.address_1 = 0;
88 params.address_2 = 0;
89 std::memcpy(output.data(), &params, sizeof(IoctlMapBuffer));
90 return 0;
91}
92
93u32 nvhost_vic::MapBufferEx(const std::vector<u8>& input, std::vector<u8>& output) {
94 IoctlMapBufferEx params{};
95 std::memcpy(&params, input.data(), sizeof(IoctlMapBufferEx));
96 LOG_WARNING(Service_NVDRV, "(STUBBED) called with address={:08X}{:08X}", params.address_2,
97 params.address_1);
98 params.address_1 = 0;
99 params.address_2 = 0;
100 std::memcpy(output.data(), &params, sizeof(IoctlMapBufferEx));
101 return 0;
102}
103
104u32 nvhost_vic::UnmapBufferEx(const std::vector<u8>& input, std::vector<u8>& output) {
105 IoctlUnmapBufferEx params{};
106 std::memcpy(&params, input.data(), sizeof(IoctlUnmapBufferEx));
107 LOG_WARNING(Service_NVDRV, "(STUBBED) called");
108 std::memcpy(output.data(), &params, sizeof(IoctlUnmapBufferEx));
109 return 0;
110}
111
40} // namespace Service::Nvidia::Devices 112} // namespace Service::Nvidia::Devices
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_vic.h b/src/core/hle/service/nvdrv/devices/nvhost_vic.h
index bec32bea1..a7bb7bbd5 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_vic.h
+++ b/src/core/hle/service/nvdrv/devices/nvhost_vic.h
@@ -4,6 +4,7 @@
4 4
5#pragma once 5#pragma once
6 6
7#include <array>
7#include <vector> 8#include <vector>
8#include "common/common_types.h" 9#include "common/common_types.h"
9#include "common/swap.h" 10#include "common/swap.h"
@@ -23,6 +24,12 @@ public:
23private: 24private:
24 enum class IoctlCommand : u32_le { 25 enum class IoctlCommand : u32_le {
25 IocSetNVMAPfdCommand = 0x40044801, 26 IocSetNVMAPfdCommand = 0x40044801,
27 IocSubmit = 0xC0400001,
28 IocGetSyncpoint = 0xC0080002,
29 IocGetWaitbase = 0xC0080003,
30 IocMapBuffer = 0xC01C0009,
31 IocMapBufferEx = 0xC03C0009,
32 IocUnmapBufferEx = 0xC03C000A,
26 }; 33 };
27 34
28 struct IoctlSetNvmapFD { 35 struct IoctlSetNvmapFD {
@@ -30,9 +37,65 @@ private:
30 }; 37 };
31 static_assert(sizeof(IoctlSetNvmapFD) == 4, "IoctlSetNvmapFD is incorrect size"); 38 static_assert(sizeof(IoctlSetNvmapFD) == 4, "IoctlSetNvmapFD is incorrect size");
32 39
40 struct IoctlSubmitCommandBuffer {
41 u32 id;
42 u32 offset;
43 u32 count;
44 };
45 static_assert(sizeof(IoctlSubmitCommandBuffer) == 0xC,
46 "IoctlSubmitCommandBuffer is incorrect size");
47
48 struct IoctlSubmit {
49 u32 command_buffer_count;
50 u32 relocations_count;
51 u32 syncpt_count;
52 u32 wait_count;
53 std::array<IoctlSubmitCommandBuffer, 4> command_buffer;
54 };
55 static_assert(sizeof(IoctlSubmit) == 0x40, "IoctlSubmit is incorrect size");
56
57 struct IoctlGetSyncpoint {
58 u32 unknown; // seems to be ignored? Nintendo added this
59 u32 value;
60 };
61 static_assert(sizeof(IoctlGetSyncpoint) == 0x8, "IoctlGetSyncpoint is incorrect size");
62
63 struct IoctlGetWaitbase {
64 u32 unknown; // seems to be ignored? Nintendo added this
65 u32 value;
66 };
67 static_assert(sizeof(IoctlGetWaitbase) == 0x8, "IoctlGetWaitbase is incorrect size");
68
69 struct IoctlMapBuffer {
70 u32 unknown;
71 u32 address_1;
72 u32 address_2;
73 INSERT_PADDING_BYTES(0x10); // TODO(DarkLordZach): RE this structure
74 };
75 static_assert(sizeof(IoctlMapBuffer) == 0x1C, "IoctlMapBuffer is incorrect size");
76
77 struct IoctlMapBufferEx {
78 u32 unknown;
79 u32 address_1;
80 u32 address_2;
81 INSERT_PADDING_BYTES(0x30); // TODO(DarkLordZach): RE this structure
82 };
83 static_assert(sizeof(IoctlMapBufferEx) == 0x3C, "IoctlMapBufferEx is incorrect size");
84
85 struct IoctlUnmapBufferEx {
86 INSERT_PADDING_BYTES(0x3C); // TODO(DarkLordZach): RE this structure
87 };
88 static_assert(sizeof(IoctlUnmapBufferEx) == 0x3C, "IoctlUnmapBufferEx is incorrect size");
89
33 u32_le nvmap_fd{}; 90 u32_le nvmap_fd{};
34 91
35 u32 SetNVMAPfd(const std::vector<u8>& input, std::vector<u8>& output); 92 u32 SetNVMAPfd(const std::vector<u8>& input, std::vector<u8>& output);
93 u32 Submit(const std::vector<u8>& input, std::vector<u8>& output);
94 u32 GetSyncpoint(const std::vector<u8>& input, std::vector<u8>& output);
95 u32 GetWaitbase(const std::vector<u8>& input, std::vector<u8>& output);
96 u32 MapBuffer(const std::vector<u8>& input, std::vector<u8>& output);
97 u32 MapBufferEx(const std::vector<u8>& input, std::vector<u8>& output);
98 u32 UnmapBufferEx(const std::vector<u8>& input, std::vector<u8>& output);
36}; 99};
37 100
38} // namespace Service::Nvidia::Devices 101} // namespace Service::Nvidia::Devices
diff --git a/src/input_common/sdl/sdl_impl.cpp b/src/input_common/sdl/sdl_impl.cpp
index 0b0095978..bd480570a 100644
--- a/src/input_common/sdl/sdl_impl.cpp
+++ b/src/input_common/sdl/sdl_impl.cpp
@@ -5,6 +5,7 @@
5#include <algorithm> 5#include <algorithm>
6#include <array> 6#include <array>
7#include <atomic> 7#include <atomic>
8#include <chrono>
8#include <cmath> 9#include <cmath>
9#include <functional> 10#include <functional>
10#include <mutex> 11#include <mutex>
@@ -79,6 +80,33 @@ public:
79 return state.axes.at(axis) / (32767.0f * range); 80 return state.axes.at(axis) / (32767.0f * range);
80 } 81 }
81 82
83 bool RumblePlay(f32 amp_low, f32 amp_high, int time) {
84 const u16 raw_amp_low = static_cast<u16>(amp_low * 0xFFFF);
85 const u16 raw_amp_high = static_cast<u16>(amp_high * 0xFFFF);
86 // Lower drastically the number of state changes
87 if (raw_amp_low >> 11 == last_state_rumble_low >> 11 &&
88 raw_amp_high >> 11 == last_state_rumble_high >> 11) {
89 if (raw_amp_low + raw_amp_high != 0 ||
90 last_state_rumble_low + last_state_rumble_high == 0) {
91 return false;
92 }
93 }
94 // Don't change state if last vibration was < 20ms
95 const auto now = std::chrono::system_clock::now();
96 if (std::chrono::duration_cast<std::chrono::milliseconds>(now - last_vibration) <
97 std::chrono::milliseconds(20)) {
98 return raw_amp_low + raw_amp_high == 0;
99 }
100
101 last_vibration = now;
102 last_state_rumble_low = raw_amp_low;
103 last_state_rumble_high = raw_amp_high;
104 if (sdl_joystick) {
105 SDL_JoystickRumble(sdl_joystick.get(), raw_amp_low, raw_amp_high, time);
106 }
107 return false;
108 }
109
82 std::tuple<float, float> GetAnalog(int axis_x, int axis_y, float range) const { 110 std::tuple<float, float> GetAnalog(int axis_x, int axis_y, float range) const {
83 float x = GetAxis(axis_x, range); 111 float x = GetAxis(axis_x, range);
84 float y = GetAxis(axis_y, range); 112 float y = GetAxis(axis_y, range);
@@ -144,6 +172,9 @@ private:
144 } state; 172 } state;
145 std::string guid; 173 std::string guid;
146 int port; 174 int port;
175 u16 last_state_rumble_high;
176 u16 last_state_rumble_low;
177 std::chrono::time_point<std::chrono::system_clock> last_vibration;
147 std::unique_ptr<SDL_Joystick, decltype(&SDL_JoystickClose)> sdl_joystick; 178 std::unique_ptr<SDL_Joystick, decltype(&SDL_JoystickClose)> sdl_joystick;
148 std::unique_ptr<SDL_GameController, decltype(&SDL_GameControllerClose)> sdl_controller; 179 std::unique_ptr<SDL_GameController, decltype(&SDL_GameControllerClose)> sdl_controller;
149 mutable std::mutex mutex; 180 mutable std::mutex mutex;
@@ -215,7 +246,7 @@ void SDLState::InitJoystick(int joystick_index) {
215 sdl_gamecontroller = SDL_GameControllerOpen(joystick_index); 246 sdl_gamecontroller = SDL_GameControllerOpen(joystick_index);
216 } 247 }
217 if (!sdl_joystick) { 248 if (!sdl_joystick) {
218 LOG_ERROR(Input, "failed to open joystick {}", joystick_index); 249 LOG_ERROR(Input, "Failed to open joystick {}", joystick_index);
219 return; 250 return;
220 } 251 }
221 const std::string guid = GetGUID(sdl_joystick); 252 const std::string guid = GetGUID(sdl_joystick);
@@ -311,6 +342,12 @@ public:
311 return joystick->GetButton(button); 342 return joystick->GetButton(button);
312 } 343 }
313 344
345 bool SetRumblePlay(f32 amp_high, f32 amp_low, f32 freq_high, f32 freq_low) const override {
346 const f32 new_amp_low = pow(amp_low, 0.5f) * (3.0f - 2.0f * pow(amp_low, 0.15f));
347 const f32 new_amp_high = pow(amp_high, 0.5f) * (3.0f - 2.0f * pow(amp_high, 0.15f));
348 return joystick->RumblePlay(new_amp_low, new_amp_high, 250);
349 }
350
314private: 351private:
315 std::shared_ptr<SDLJoystick> joystick; 352 std::shared_ptr<SDLJoystick> joystick;
316 int button; 353 int button;
diff --git a/src/input_common/udp/client.cpp b/src/input_common/udp/client.cpp
index b6323d56f..9d0b9f31d 100644
--- a/src/input_common/udp/client.cpp
+++ b/src/input_common/udp/client.cpp
@@ -272,18 +272,22 @@ void Client::Reset() {
272 272
273void Client::UpdateYuzuSettings(std::size_t client, const Common::Vec3<float>& acc, 273void Client::UpdateYuzuSettings(std::size_t client, const Common::Vec3<float>& acc,
274 const Common::Vec3<float>& gyro, bool touch) { 274 const Common::Vec3<float>& gyro, bool touch) {
275 if (gyro.Length() > 0.2f) {
276 LOG_DEBUG(Input, "UDP Controller {}: gyro=({}, {}, {}), accel=({}, {}, {}), touch={}",
277 client, gyro[0], gyro[1], gyro[2], acc[0], acc[1], acc[2], touch);
278 }
275 UDPPadStatus pad; 279 UDPPadStatus pad;
276 if (touch) { 280 if (touch) {
277 pad.touch = PadTouch::Click; 281 pad.touch = PadTouch::Click;
278 pad_queue[client].Push(pad); 282 pad_queue[client].Push(pad);
279 } 283 }
280 for (size_t i = 0; i < 3; ++i) { 284 for (size_t i = 0; i < 3; ++i) {
281 if (gyro[i] > 6.0f || gyro[i] < -6.0f) { 285 if (gyro[i] > 5.0f || gyro[i] < -5.0f) {
282 pad.motion = static_cast<PadMotion>(i); 286 pad.motion = static_cast<PadMotion>(i);
283 pad.motion_value = gyro[i]; 287 pad.motion_value = gyro[i];
284 pad_queue[client].Push(pad); 288 pad_queue[client].Push(pad);
285 } 289 }
286 if (acc[i] > 2.0f || acc[i] < -2.0f) { 290 if (acc[i] > 1.75f || acc[i] < -1.75f) {
287 pad.motion = static_cast<PadMotion>(i + 3); 291 pad.motion = static_cast<PadMotion>(i + 3);
288 pad.motion_value = acc[i]; 292 pad.motion_value = acc[i];
289 pad_queue[client].Push(pad); 293 pad_queue[client].Push(pad);
diff --git a/src/video_core/renderer_vulkan/vk_command_pool.cpp b/src/video_core/renderer_vulkan/vk_command_pool.cpp
index f1abd4b1a..6339f4fe0 100644
--- a/src/video_core/renderer_vulkan/vk_command_pool.cpp
+++ b/src/video_core/renderer_vulkan/vk_command_pool.cpp
@@ -12,6 +12,11 @@ namespace Vulkan {
12 12
13constexpr size_t COMMAND_BUFFER_POOL_SIZE = 0x1000; 13constexpr size_t COMMAND_BUFFER_POOL_SIZE = 0x1000;
14 14
15struct CommandPool::Pool {
16 vk::CommandPool handle;
17 vk::CommandBuffers cmdbufs;
18};
19
15CommandPool::CommandPool(MasterSemaphore& master_semaphore, const VKDevice& device) 20CommandPool::CommandPool(MasterSemaphore& master_semaphore, const VKDevice& device)
16 : ResourcePool(master_semaphore, COMMAND_BUFFER_POOL_SIZE), device{device} {} 21 : ResourcePool(master_semaphore, COMMAND_BUFFER_POOL_SIZE), device{device} {}
17 22
diff --git a/src/video_core/renderer_vulkan/vk_command_pool.h b/src/video_core/renderer_vulkan/vk_command_pool.h
index 3aee239b9..b9cb3fb5d 100644
--- a/src/video_core/renderer_vulkan/vk_command_pool.h
+++ b/src/video_core/renderer_vulkan/vk_command_pool.h
@@ -2,6 +2,8 @@
2// Licensed under GPLv2 or any later version 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#pragma once
6
5#include <cstddef> 7#include <cstddef>
6#include <vector> 8#include <vector>
7 9
@@ -16,17 +18,14 @@ class VKDevice;
16class CommandPool final : public ResourcePool { 18class CommandPool final : public ResourcePool {
17public: 19public:
18 explicit CommandPool(MasterSemaphore& master_semaphore, const VKDevice& device); 20 explicit CommandPool(MasterSemaphore& master_semaphore, const VKDevice& device);
19 virtual ~CommandPool(); 21 ~CommandPool() override;
20 22
21 void Allocate(size_t begin, size_t end) override; 23 void Allocate(size_t begin, size_t end) override;
22 24
23 VkCommandBuffer Commit(); 25 VkCommandBuffer Commit();
24 26
25private: 27private:
26 struct Pool { 28 struct Pool;
27 vk::CommandPool handle;
28 vk::CommandBuffers cmdbufs;
29 };
30 29
31 const VKDevice& device; 30 const VKDevice& device;
32 std::vector<Pool> pools; 31 std::vector<Pool> pools;
diff --git a/src/video_core/renderer_vulkan/vk_device.cpp b/src/video_core/renderer_vulkan/vk_device.cpp
index 05e31f1de..3d8d3213d 100644
--- a/src/video_core/renderer_vulkan/vk_device.cpp
+++ b/src/video_core/renderer_vulkan/vk_device.cpp
@@ -388,14 +388,6 @@ bool VKDevice::Create() {
388 388
389 CollectTelemetryParameters(); 389 CollectTelemetryParameters();
390 390
391 if (ext_extended_dynamic_state && driver_id == VK_DRIVER_ID_AMD_PROPRIETARY_KHR) {
392 // AMD's proprietary driver supports VK_EXT_extended_dynamic_state but the <stride> field
393 // seems to be bugged. Blacklisting it for now.
394 LOG_WARNING(Render_Vulkan,
395 "Blacklisting AMD proprietary from VK_EXT_extended_dynamic_state");
396 ext_extended_dynamic_state = false;
397 }
398
399 graphics_queue = logical.GetQueue(graphics_family); 391 graphics_queue = logical.GetQueue(graphics_family);
400 present_queue = logical.GetQueue(present_family); 392 present_queue = logical.GetQueue(present_family);
401 393
diff --git a/src/video_core/renderer_vulkan/vk_stream_buffer.cpp b/src/video_core/renderer_vulkan/vk_stream_buffer.cpp
index 5218c875b..1b59612b9 100644
--- a/src/video_core/renderer_vulkan/vk_stream_buffer.cpp
+++ b/src/video_core/renderer_vulkan/vk_stream_buffer.cpp
@@ -120,7 +120,8 @@ void VKStreamBuffer::CreateBuffers(VkBufferUsageFlags usage) {
120 120
121 // Substract from the preferred heap size some bytes to avoid getting out of memory. 121 // Substract from the preferred heap size some bytes to avoid getting out of memory.
122 const VkDeviceSize heap_size = memory_properties.memoryHeaps[preferred_heap].size; 122 const VkDeviceSize heap_size = memory_properties.memoryHeaps[preferred_heap].size;
123 const VkDeviceSize allocable_size = heap_size - 9 * 1024 * 1024; 123 // As per DXVK's example, using `heap_size / 2`
124 const VkDeviceSize allocable_size = heap_size / 2;
124 buffer = device.GetLogical().CreateBuffer({ 125 buffer = device.GetLogical().CreateBuffer({
125 .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, 126 .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
126 .pNext = nullptr, 127 .pNext = nullptr,
diff --git a/src/video_core/renderer_vulkan/wrapper.cpp b/src/video_core/renderer_vulkan/wrapper.cpp
index 1fb14e190..2598440fb 100644
--- a/src/video_core/renderer_vulkan/wrapper.cpp
+++ b/src/video_core/renderer_vulkan/wrapper.cpp
@@ -6,6 +6,7 @@
6#include <exception> 6#include <exception>
7#include <memory> 7#include <memory>
8#include <optional> 8#include <optional>
9#include <string_view>
9#include <utility> 10#include <utility>
10#include <vector> 11#include <vector>
11 12
@@ -17,21 +18,42 @@ namespace Vulkan::vk {
17 18
18namespace { 19namespace {
19 20
21template <typename Func>
22void SortPhysicalDevices(std::vector<VkPhysicalDevice>& devices, const InstanceDispatch& dld,
23 Func&& func) {
24 // Calling GetProperties calls Vulkan more than needed. But they are supposed to be cheap
25 // functions.
26 std::stable_sort(devices.begin(), devices.end(),
27 [&dld, &func](VkPhysicalDevice lhs, VkPhysicalDevice rhs) {
28 return func(vk::PhysicalDevice(lhs, dld).GetProperties(),
29 vk::PhysicalDevice(rhs, dld).GetProperties());
30 });
31}
32
33void SortPhysicalDevicesPerVendor(std::vector<VkPhysicalDevice>& devices,
34 const InstanceDispatch& dld,
35 std::initializer_list<u32> vendor_ids) {
36 for (auto it = vendor_ids.end(); it != vendor_ids.begin();) {
37 --it;
38 SortPhysicalDevices(devices, dld, [id = *it](const auto& lhs, const auto& rhs) {
39 return lhs.vendorID == id && rhs.vendorID != id;
40 });
41 }
42}
43
20void SortPhysicalDevices(std::vector<VkPhysicalDevice>& devices, const InstanceDispatch& dld) { 44void SortPhysicalDevices(std::vector<VkPhysicalDevice>& devices, const InstanceDispatch& dld) {
21 std::stable_sort(devices.begin(), devices.end(), [&](auto lhs, auto rhs) { 45 // Sort by name, this will set a base and make GPUs with higher numbers appear first
22 // This will call Vulkan more than needed, but these calls are cheap. 46 // (e.g. GTX 1650 will intentionally be listed before a GTX 1080).
23 const auto lhs_properties = vk::PhysicalDevice(lhs, dld).GetProperties(); 47 SortPhysicalDevices(devices, dld, [](const auto& lhs, const auto& rhs) {
24 const auto rhs_properties = vk::PhysicalDevice(rhs, dld).GetProperties(); 48 return std::string_view{lhs.deviceName} > std::string_view{rhs.deviceName};
25 49 });
26 // Prefer discrete GPUs, Nvidia over AMD, AMD over Intel, Intel over the rest. 50 // Prefer discrete over non-discrete
27 const bool preferred = 51 SortPhysicalDevices(devices, dld, [](const auto& lhs, const auto& rhs) {
28 (lhs_properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU && 52 return lhs.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU &&
29 rhs_properties.deviceType != VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU) || 53 rhs.deviceType != VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU;
30 (lhs_properties.vendorID == 0x10DE && rhs_properties.vendorID != 0x10DE) ||
31 (lhs_properties.vendorID == 0x1002 && rhs_properties.vendorID != 0x1002) ||
32 (lhs_properties.vendorID == 0x8086 && rhs_properties.vendorID != 0x8086);
33 return !preferred;
34 }); 54 });
55 // Prefer Nvidia over AMD, AMD over Intel, Intel over the rest.
56 SortPhysicalDevicesPerVendor(devices, dld, {0x10DE, 0x1002, 0x8086});
35} 57}
36 58
37template <typename T> 59template <typename T>
diff --git a/src/video_core/shader/registry.cpp b/src/video_core/shader/registry.cpp
index cdf274e54..148d91fcb 100644
--- a/src/video_core/shader/registry.cpp
+++ b/src/video_core/shader/registry.cpp
@@ -24,44 +24,45 @@ GraphicsInfo MakeGraphicsInfo(ShaderType shader_stage, ConstBufferEngineInterfac
24 if (shader_stage == ShaderType::Compute) { 24 if (shader_stage == ShaderType::Compute) {
25 return {}; 25 return {};
26 } 26 }
27 auto& graphics = static_cast<Tegra::Engines::Maxwell3D&>(engine); 27
28 28 auto& graphics = dynamic_cast<Tegra::Engines::Maxwell3D&>(engine);
29 GraphicsInfo info; 29
30 info.tfb_layouts = graphics.regs.tfb_layouts; 30 return {
31 info.tfb_varying_locs = graphics.regs.tfb_varying_locs; 31 .tfb_layouts = graphics.regs.tfb_layouts,
32 info.primitive_topology = graphics.regs.draw.topology; 32 .tfb_varying_locs = graphics.regs.tfb_varying_locs,
33 info.tessellation_primitive = graphics.regs.tess_mode.prim; 33 .primitive_topology = graphics.regs.draw.topology,
34 info.tessellation_spacing = graphics.regs.tess_mode.spacing; 34 .tessellation_primitive = graphics.regs.tess_mode.prim,
35 info.tfb_enabled = graphics.regs.tfb_enabled; 35 .tessellation_spacing = graphics.regs.tess_mode.spacing,
36 info.tessellation_clockwise = graphics.regs.tess_mode.cw; 36 .tfb_enabled = graphics.regs.tfb_enabled != 0,
37 return info; 37 .tessellation_clockwise = graphics.regs.tess_mode.cw.Value() != 0,
38 };
38} 39}
39 40
40ComputeInfo MakeComputeInfo(ShaderType shader_stage, ConstBufferEngineInterface& engine) { 41ComputeInfo MakeComputeInfo(ShaderType shader_stage, ConstBufferEngineInterface& engine) {
41 if (shader_stage != ShaderType::Compute) { 42 if (shader_stage != ShaderType::Compute) {
42 return {}; 43 return {};
43 } 44 }
44 auto& compute = static_cast<Tegra::Engines::KeplerCompute&>(engine); 45
46 auto& compute = dynamic_cast<Tegra::Engines::KeplerCompute&>(engine);
45 const auto& launch = compute.launch_description; 47 const auto& launch = compute.launch_description;
46 48
47 ComputeInfo info; 49 return {
48 info.workgroup_size = {launch.block_dim_x, launch.block_dim_y, launch.block_dim_z}; 50 .workgroup_size = {launch.block_dim_x, launch.block_dim_y, launch.block_dim_z},
49 info.local_memory_size_in_words = launch.local_pos_alloc; 51 .shared_memory_size_in_words = launch.shared_alloc,
50 info.shared_memory_size_in_words = launch.shared_alloc; 52 .local_memory_size_in_words = launch.local_pos_alloc,
51 return info; 53 };
52} 54}
53 55
54} // Anonymous namespace 56} // Anonymous namespace
55 57
56Registry::Registry(Tegra::Engines::ShaderType shader_stage, const SerializedRegistryInfo& info) 58Registry::Registry(ShaderType shader_stage, const SerializedRegistryInfo& info)
57 : stage{shader_stage}, stored_guest_driver_profile{info.guest_driver_profile}, 59 : stage{shader_stage}, stored_guest_driver_profile{info.guest_driver_profile},
58 bound_buffer{info.bound_buffer}, graphics_info{info.graphics}, compute_info{info.compute} {} 60 bound_buffer{info.bound_buffer}, graphics_info{info.graphics}, compute_info{info.compute} {}
59 61
60Registry::Registry(Tegra::Engines::ShaderType shader_stage, 62Registry::Registry(ShaderType shader_stage, ConstBufferEngineInterface& engine_)
61 Tegra::Engines::ConstBufferEngineInterface& engine) 63 : stage{shader_stage}, engine{&engine_}, bound_buffer{engine_.GetBoundBuffer()},
62 : stage{shader_stage}, engine{&engine}, bound_buffer{engine.GetBoundBuffer()}, 64 graphics_info{MakeGraphicsInfo(shader_stage, engine_)}, compute_info{MakeComputeInfo(
63 graphics_info{MakeGraphicsInfo(shader_stage, engine)}, compute_info{MakeComputeInfo( 65 shader_stage, engine_)} {}
64 shader_stage, engine)} {}
65 66
66Registry::~Registry() = default; 67Registry::~Registry() = default;
67 68
@@ -113,8 +114,7 @@ std::optional<Tegra::Engines::SamplerDescriptor> Registry::ObtainSeparateSampler
113 return value; 114 return value;
114} 115}
115 116
116std::optional<Tegra::Engines::SamplerDescriptor> Registry::ObtainBindlessSampler(u32 buffer, 117std::optional<SamplerDescriptor> Registry::ObtainBindlessSampler(u32 buffer, u32 offset) {
117 u32 offset) {
118 const std::pair key = {buffer, offset}; 118 const std::pair key = {buffer, offset};
119 const auto iter = bindless_samplers.find(key); 119 const auto iter = bindless_samplers.find(key);
120 if (iter != bindless_samplers.end()) { 120 if (iter != bindless_samplers.end()) {
diff --git a/src/video_core/shader/registry.h b/src/video_core/shader/registry.h
index 231206765..4bebefdde 100644
--- a/src/video_core/shader/registry.h
+++ b/src/video_core/shader/registry.h
@@ -94,7 +94,7 @@ public:
94 explicit Registry(Tegra::Engines::ShaderType shader_stage, const SerializedRegistryInfo& info); 94 explicit Registry(Tegra::Engines::ShaderType shader_stage, const SerializedRegistryInfo& info);
95 95
96 explicit Registry(Tegra::Engines::ShaderType shader_stage, 96 explicit Registry(Tegra::Engines::ShaderType shader_stage,
97 Tegra::Engines::ConstBufferEngineInterface& engine); 97 Tegra::Engines::ConstBufferEngineInterface& engine_);
98 98
99 ~Registry(); 99 ~Registry();
100 100
diff --git a/src/yuzu/game_list.cpp b/src/yuzu/game_list.cpp
index a9738e298..70d865112 100644
--- a/src/yuzu/game_list.cpp
+++ b/src/yuzu/game_list.cpp
@@ -25,7 +25,8 @@
25#include "yuzu/main.h" 25#include "yuzu/main.h"
26#include "yuzu/uisettings.h" 26#include "yuzu/uisettings.h"
27 27
28GameListSearchField::KeyReleaseEater::KeyReleaseEater(GameList* gamelist) : gamelist{gamelist} {} 28GameListSearchField::KeyReleaseEater::KeyReleaseEater(GameList* gamelist, QObject* parent)
29 : QObject(parent), gamelist{gamelist} {}
29 30
30// EventFilter in order to process systemkeys while editing the searchfield 31// EventFilter in order to process systemkeys while editing the searchfield
31bool GameListSearchField::KeyReleaseEater::eventFilter(QObject* obj, QEvent* event) { 32bool GameListSearchField::KeyReleaseEater::eventFilter(QObject* obj, QEvent* event) {
@@ -116,7 +117,7 @@ void GameListSearchField::setFocus() {
116} 117}
117 118
118GameListSearchField::GameListSearchField(GameList* parent) : QWidget{parent} { 119GameListSearchField::GameListSearchField(GameList* parent) : QWidget{parent} {
119 auto* const key_release_eater = new KeyReleaseEater(parent); 120 auto* const key_release_eater = new KeyReleaseEater(parent, this);
120 layout_filter = new QHBoxLayout; 121 layout_filter = new QHBoxLayout;
121 layout_filter->setMargin(8); 122 layout_filter->setMargin(8);
122 label_filter = new QLabel; 123 label_filter = new QLabel;
diff --git a/src/yuzu/game_list_p.h b/src/yuzu/game_list_p.h
index 92779a9c7..248855aff 100644
--- a/src/yuzu/game_list_p.h
+++ b/src/yuzu/game_list_p.h
@@ -330,7 +330,7 @@ public:
330private: 330private:
331 class KeyReleaseEater : public QObject { 331 class KeyReleaseEater : public QObject {
332 public: 332 public:
333 explicit KeyReleaseEater(GameList* gamelist); 333 explicit KeyReleaseEater(GameList* gamelist, QObject* parent = nullptr);
334 334
335 private: 335 private:
336 GameList* gamelist = nullptr; 336 GameList* gamelist = nullptr;
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp
index 6a2a88dd8..e3de0f0e1 100644
--- a/src/yuzu/main.cpp
+++ b/src/yuzu/main.cpp
@@ -288,8 +288,8 @@ GMainWindow::~GMainWindow() {
288void GMainWindow::ControllerSelectorReconfigureControllers( 288void GMainWindow::ControllerSelectorReconfigureControllers(
289 const Core::Frontend::ControllerParameters& parameters) { 289 const Core::Frontend::ControllerParameters& parameters) {
290 QtControllerSelectorDialog dialog(this, parameters, input_subsystem.get()); 290 QtControllerSelectorDialog dialog(this, parameters, input_subsystem.get());
291 dialog.setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowTitleHint | 291 dialog.setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowStaysOnTopHint |
292 Qt::WindowSystemMenuHint); 292 Qt::WindowTitleHint | Qt::WindowSystemMenuHint);
293 dialog.setWindowModality(Qt::WindowModal); 293 dialog.setWindowModality(Qt::WindowModal);
294 dialog.exec(); 294 dialog.exec();
295 295
@@ -307,8 +307,9 @@ void GMainWindow::ProfileSelectorSelectProfile() {
307 int index = 0; 307 int index = 0;
308 if (manager.GetUserCount() != 1) { 308 if (manager.GetUserCount() != 1) {
309 QtProfileSelectionDialog dialog(this); 309 QtProfileSelectionDialog dialog(this);
310 dialog.setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowTitleHint | 310 dialog.setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowStaysOnTopHint |
311 Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint); 311 Qt::WindowTitleHint | Qt::WindowSystemMenuHint |
312 Qt::WindowCloseButtonHint);
312 dialog.setWindowModality(Qt::WindowModal); 313 dialog.setWindowModality(Qt::WindowModal);
313 314
314 if (dialog.exec() == QDialog::Rejected) { 315 if (dialog.exec() == QDialog::Rejected) {
@@ -331,8 +332,9 @@ void GMainWindow::ProfileSelectorSelectProfile() {
331void GMainWindow::SoftwareKeyboardGetText( 332void GMainWindow::SoftwareKeyboardGetText(
332 const Core::Frontend::SoftwareKeyboardParameters& parameters) { 333 const Core::Frontend::SoftwareKeyboardParameters& parameters) {
333 QtSoftwareKeyboardDialog dialog(this, parameters); 334 QtSoftwareKeyboardDialog dialog(this, parameters);
334 dialog.setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowTitleHint | 335 dialog.setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowStaysOnTopHint |
335 Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint); 336 Qt::WindowTitleHint | Qt::WindowSystemMenuHint |
337 Qt::WindowCloseButtonHint);
336 dialog.setWindowModality(Qt::WindowModal); 338 dialog.setWindowModality(Qt::WindowModal);
337 339
338 if (dialog.exec() == QDialog::Rejected) { 340 if (dialog.exec() == QDialog::Rejected) {