diff options
Diffstat (limited to 'src')
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 | ||
| 45 | create_target_directory_groups(audio_core) | 45 | create_target_directory_groups(audio_core) |
| 46 | 46 | ||
| 47 | if (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 | ) | ||
| 55 | endif() | ||
| 56 | |||
| 47 | target_link_libraries(audio_core PUBLIC common core) | 57 | target_link_libraries(audio_core PUBLIC common core) |
| 48 | target_link_libraries(audio_core PRIVATE SoundTouch) | 58 | target_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 | ||
| 27 | namespace Core::Timing { | 26 | namespace 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 | ||
| 60 | bool BehaviorInfo::IsAudioRenererProcessingTimeLimit80PercentSupported() const { | 60 | bool BehaviorInfo::IsAudioRendererProcessingTimeLimit80PercentSupported() const { |
| 61 | return AudioCommon::IsRevisionSupported(5, user_revision); | 61 | return AudioCommon::IsRevisionSupported(5, user_revision); |
| 62 | } | 62 | } |
| 63 | 63 | ||
| 64 | bool BehaviorInfo::IsAudioRenererProcessingTimeLimit75PercentSupported() const { | 64 | bool BehaviorInfo::IsAudioRendererProcessingTimeLimit75PercentSupported() const { |
| 65 | return AudioCommon::IsRevisionSupported(4, user_revision); | 65 | return AudioCommon::IsRevisionSupported(4, user_revision); |
| 66 | } | 66 | } |
| 67 | 67 | ||
| 68 | bool BehaviorInfo::IsAudioRenererProcessingTimeLimit70PercentSupported() const { | 68 | bool 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 | */ |
| 41 | std::vector<s16> DecodeADPCM(const u8* const data, std::size_t size, const ADPCM_Coeff& coeff, | 41 | std::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 | ||
| 13 | namespace Core::Memory { | 12 | namespace 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 | ||
| 193 | long CubebSinkStream::DataCallback(cubeb_stream* stream, void* user_data, const void* input_buffer, | 193 | long 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 | ||
| 187 | const VAddr EffectAuxInfo::GetSendInfo() const { | 187 | VAddr EffectAuxInfo::GetSendInfo() const { |
| 188 | return send_info; | 188 | return send_info; |
| 189 | } | 189 | } |
| 190 | 190 | ||
| 191 | const VAddr EffectAuxInfo::GetSendBuffer() const { | 191 | VAddr EffectAuxInfo::GetSendBuffer() const { |
| 192 | return send_buffer; | 192 | return send_buffer; |
| 193 | } | 193 | } |
| 194 | 194 | ||
| 195 | const VAddr EffectAuxInfo::GetRecvInfo() const { | 195 | VAddr EffectAuxInfo::GetRecvInfo() const { |
| 196 | return recv_info; | 196 | return recv_info; |
| 197 | } | 197 | } |
| 198 | 198 | ||
| 199 | const VAddr EffectAuxInfo::GetRecvBuffer() const { | 199 | VAddr 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 | ||
| 178 | struct AuxAddress { | 178 | struct AuxAddress { |
| @@ -184,8 +184,8 @@ struct AuxAddress { | |||
| 184 | 184 | ||
| 185 | class EffectBase { | 185 | class EffectBase { |
| 186 | public: | 186 | public: |
| 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: | |||
| 206 | template <typename T> | 206 | template <typename T> |
| 207 | class EffectGeneric : public EffectBase { | 207 | class EffectGeneric : public EffectBase { |
| 208 | public: | 208 | public: |
| 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: | |||
| 224 | class EffectStubbed : public EffectBase { | 223 | class EffectStubbed : public EffectBase { |
| 225 | public: | 224 | public: |
| 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: | |||
| 233 | class EffectI3dl2Reverb : public EffectGeneric<I3dl2ReverbParams> { | 232 | class EffectI3dl2Reverb : public EffectGeneric<I3dl2ReverbParams> { |
| 234 | public: | 233 | public: |
| 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: | |||
| 245 | class EffectBiquadFilter : public EffectGeneric<BiquadFilterParams> { | 244 | class EffectBiquadFilter : public EffectGeneric<BiquadFilterParams> { |
| 246 | public: | 245 | public: |
| 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: | |||
| 254 | class EffectAuxInfo : public EffectGeneric<AuxInfo> { | 253 | class EffectAuxInfo : public EffectGeneric<AuxInfo> { |
| 255 | public: | 254 | public: |
| 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 | ||
| 266 | private: | 265 | private: |
| 267 | VAddr send_info{}; | 266 | VAddr send_info{}; |
| @@ -275,7 +274,7 @@ private: | |||
| 275 | class EffectDelay : public EffectGeneric<DelayParams> { | 274 | class EffectDelay : public EffectGeneric<DelayParams> { |
| 276 | public: | 275 | public: |
| 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: | |||
| 287 | class EffectBufferMixer : public EffectGeneric<BufferMixerParams> { | 286 | class EffectBufferMixer : public EffectGeneric<BufferMixerParams> { |
| 288 | public: | 287 | public: |
| 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: | |||
| 296 | class EffectReverb : public EffectGeneric<ReverbParams> { | 295 | class EffectReverb : public EffectGeneric<ReverbParams> { |
| 297 | public: | 296 | public: |
| 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 | ||
| 66 | bool InfoUpdater::UpdateMemoryPools(std::vector<ServerMemoryPoolInfo>& memory_pool_info) { | 66 | bool 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 | ||
| 436 | void NodeStates::PushTsortResult(s32 index) { | 436 | void 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 | ||
| 18 | namespace AudioCore { | 17 | namespace 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) | |||
| 192 | find_package(Boost 1.71 COMPONENTS context headers REQUIRED) | 192 | find_package(Boost 1.71 COMPONENTS context headers REQUIRED) |
| 193 | 193 | ||
| 194 | target_link_libraries(common PUBLIC ${Boost_LIBRARIES} fmt::fmt microprofile) | 194 | target_link_libraries(common PUBLIC ${Boost_LIBRARIES} fmt::fmt microprofile) |
| 195 | target_link_libraries(common PRIVATE lz4::lz4 zstd::zstd xbyak) | 195 | target_link_libraries(common PRIVATE lz4::lz4 xbyak) |
| 196 | if (MSVC) | ||
| 197 | target_link_libraries(common PRIVATE zstd::zstd) | ||
| 198 | else() | ||
| 199 | target_link_libraries(common PRIVATE zstd) | ||
| 200 | endif() | ||
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 { | |||
| 15 | using base_timer = std::chrono::steady_clock; | 15 | using base_timer = std::chrono::steady_clock; |
| 16 | using base_time_point = std::chrono::time_point<base_timer>; | 16 | using base_time_point = std::chrono::time_point<base_timer>; |
| 17 | 17 | ||
| 18 | class StandardWallClock : public WallClock { | 18 | class StandardWallClock final : public WallClock { |
| 19 | public: | 19 | public: |
| 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 | ||
| 14 | class WallClock { | 14 | class WallClock { |
| 15 | public: | 15 | public: |
| 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 @@ | |||
| 12 | namespace Common { | 12 | namespace Common { |
| 13 | 13 | ||
| 14 | namespace X64 { | 14 | namespace X64 { |
| 15 | class NativeClock : public WallClock { | 15 | class NativeClock final : public WallClock { |
| 16 | public: | 16 | public: |
| 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 | ||
| 15 | ControllerApplet::~ControllerApplet() = default; | 14 | ControllerApplet::~ControllerApplet() = default; |
| 16 | 15 | ||
| 16 | DefaultControllerApplet::DefaultControllerApplet(Service::SM::ServiceManager& service_manager_) | ||
| 17 | : service_manager{service_manager_} {} | ||
| 18 | |||
| 17 | DefaultControllerApplet::~DefaultControllerApplet() = default; | 19 | DefaultControllerApplet::~DefaultControllerApplet() = default; |
| 18 | 20 | ||
| 19 | void DefaultControllerApplet::ReconfigureControllers(std::function<void()> callback, | 21 | void 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 | ||
| 11 | namespace Service::SM { | ||
| 12 | class ServiceManager; | ||
| 13 | } | ||
| 14 | |||
| 11 | namespace Core::Frontend { | 15 | namespace Core::Frontend { |
| 12 | 16 | ||
| 13 | using BorderColor = std::array<u8, 4>; | 17 | using BorderColor = std::array<u8, 4>; |
| @@ -39,10 +43,14 @@ public: | |||
| 39 | 43 | ||
| 40 | class DefaultControllerApplet final : public ControllerApplet { | 44 | class DefaultControllerApplet final : public ControllerApplet { |
| 41 | public: | 45 | public: |
| 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 | |||
| 52 | private: | ||
| 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 | ||
| 207 | void AppletManager::SetDefaultAppletsIfMissing() { | 207 | void 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 | ||
| 7 | namespace Service::Capture { | 9 | namespace 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 | ||
| 73 | CAPS_C::~CAPS_C() = default; | 75 | CAPS_C::~CAPS_C() = default; |
| 74 | 76 | ||
| 77 | void 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> { | |||
| 16 | public: | 16 | public: |
| 17 | explicit CAPS_C(); | 17 | explicit CAPS_C(); |
| 18 | ~CAPS_C() override; | 18 | ~CAPS_C() override; |
| 19 | |||
| 20 | private: | ||
| 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") { | |||
| 25 | CAPS_SU::~CAPS_SU() = default; | 25 | CAPS_SU::~CAPS_SU() = default; |
| 26 | 26 | ||
| 27 | void CAPS_SU::SetShimLibraryVersion(Kernel::HLERequestContext& ctx) { | 27 | void 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: | |||
| 31 | CAPS_U::CAPS_U() : ServiceFramework("caps:u") { | 31 | CAPS_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 | ||
| 54 | CAPS_U::~CAPS_U() = default; | 53 | CAPS_U::~CAPS_U() = default; |
| 55 | 54 | ||
| 55 | void 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 | |||
| 56 | void CAPS_U::GetAlbumContentsFileListForApplication(Kernel::HLERequestContext& ctx) { | 67 | void 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 | ||
| 20 | private: | 20 | private: |
| 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 | ||
| 261 | void Controller_NPad::RequestPadStateUpdate(u32 npad_id) { | 261 | void 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 | ||
| 329 | void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data, | 338 | void 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 | |||
| 492 | void 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 | ||
| 612 | void Controller_NPad::VibrateController(const std::vector<u32>& controller_ids, | 677 | void 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 | ||
| 628 | Controller_NPad::Vibration Controller_NPad::GetLastVibration() const { | 704 | Controller_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 | ||
| 849 | bool Controller_NPad::IsUnintendedHomeButtonInputProtectionEnabled(u32 npad_id) const { | ||
| 850 | return unintended_home_button_input_protection[NPadIdToIndex(npad_id)]; | ||
| 851 | } | ||
| 852 | |||
| 853 | void 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 | |||
| 773 | void Controller_NPad::SetVibrationEnabled(bool can_vibrate) { | 858 | void 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 |
| 43 | constexpr auto pad_update_ns = std::chrono::nanoseconds{1000 * 1000}; // (1ms, 1000Hz) | 43 | constexpr auto pad_update_ns = std::chrono::nanoseconds{1000 * 1000}; // (1ms, 1000Hz) |
| 44 | constexpr auto motion_update_ns = std::chrono::nanoseconds{15 * 1000 * 1000}; // (15ms, 66.666Hz) | ||
| 44 | constexpr std::size_t SHARED_MEMORY_SIZE = 0x40000; | 45 | constexpr std::size_t SHARED_MEMORY_SIZE = 0x40000; |
| 45 | 46 | ||
| 46 | IAppletResource::IAppletResource(Core::System& system) | 47 | IAppletResource::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 | ||
| 130 | void 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 | |||
| 125 | class IActiveVibrationDeviceList final : public ServiceFramework<IActiveVibrationDeviceList> { | 140 | class IActiveVibrationDeviceList final : public ServiceFramework<IActiveVibrationDeviceList> { |
| 126 | public: | 141 | public: |
| 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 | ||
| 476 | void 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 | |||
| 461 | void Hid::SetGyroscopeZeroDriftMode(Kernel::HLERequestContext& ctx) { | 489 | void 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 | ||
| 812 | void 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 | |||
| 827 | void 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 | |||
| 784 | void Hid::BeginPermitVibrationSession(Kernel::HLERequestContext& ctx) { | 846 | void 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 | ||
| 803 | void Hid::SendVibrationValue(Kernel::HLERequestContext& ctx) { | 865 | void 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 | ||
| 819 | void Hid::SendVibrationValues(Kernel::HLERequestContext& ctx) { | 881 | void 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 | ||
| 31 | u32 nvhost_nvdec::SetNVMAPfd(const std::vector<u8>& input, std::vector<u8>& output) { | 43 | u32 nvhost_nvdec::SetNVMAPfd(const std::vector<u8>& input, std::vector<u8>& output) { |
| 32 | IoctlSetNvmapFD params{}; | 44 | IoctlSetNvmapFD params{}; |
| 33 | std::memcpy(¶ms, input.data(), input.size()); | 45 | std::memcpy(¶ms, 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 | ||
| 52 | u32 nvhost_nvdec::Submit(const std::vector<u8>& input, std::vector<u8>& output) { | ||
| 53 | IoctlSubmit params{}; | ||
| 54 | std::memcpy(¶ms, input.data(), sizeof(IoctlSubmit)); | ||
| 55 | LOG_WARNING(Service_NVDRV, "(STUBBED) called"); | ||
| 56 | std::memcpy(output.data(), ¶ms, sizeof(IoctlSubmit)); | ||
| 57 | return 0; | ||
| 58 | } | ||
| 59 | |||
| 60 | u32 nvhost_nvdec::GetSyncpoint(const std::vector<u8>& input, std::vector<u8>& output) { | ||
| 61 | IoctlGetSyncpoint params{}; | ||
| 62 | std::memcpy(¶ms, 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(), ¶ms, sizeof(IoctlGetSyncpoint)); | ||
| 66 | return 0; | ||
| 67 | } | ||
| 68 | |||
| 69 | u32 nvhost_nvdec::GetWaitbase(const std::vector<u8>& input, std::vector<u8>& output) { | ||
| 70 | IoctlGetWaitbase params{}; | ||
| 71 | std::memcpy(¶ms, 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(), ¶ms, sizeof(IoctlGetWaitbase)); | ||
| 75 | return 0; | ||
| 76 | } | ||
| 77 | |||
| 78 | u32 nvhost_nvdec::MapBuffer(const std::vector<u8>& input, std::vector<u8>& output) { | ||
| 79 | IoctlMapBuffer params{}; | ||
| 80 | std::memcpy(¶ms, 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(), ¶ms, sizeof(IoctlMapBuffer)); | ||
| 86 | return 0; | ||
| 87 | } | ||
| 88 | |||
| 89 | u32 nvhost_nvdec::MapBufferEx(const std::vector<u8>& input, std::vector<u8>& output) { | ||
| 90 | IoctlMapBufferEx params{}; | ||
| 91 | std::memcpy(¶ms, 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(), ¶ms, sizeof(IoctlMapBufferEx)); | ||
| 97 | return 0; | ||
| 98 | } | ||
| 99 | |||
| 100 | u32 nvhost_nvdec::UnmapBufferEx(const std::vector<u8>& input, std::vector<u8>& output) { | ||
| 101 | IoctlUnmapBufferEx params{}; | ||
| 102 | std::memcpy(¶ms, input.data(), sizeof(IoctlUnmapBufferEx)); | ||
| 103 | LOG_WARNING(Service_NVDRV, "(STUBBED) called"); | ||
| 104 | std::memcpy(output.data(), ¶ms, 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: | |||
| 23 | private: | 23 | private: |
| 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 | ||
| 31 | u32 nvhost_vic::SetNVMAPfd(const std::vector<u8>& input, std::vector<u8>& output) { | 43 | u32 nvhost_vic::SetNVMAPfd(const std::vector<u8>& input, std::vector<u8>& output) { |
| 32 | IoctlSetNvmapFD params{}; | 44 | IoctlSetNvmapFD params{}; |
| 33 | std::memcpy(¶ms, input.data(), input.size()); | 45 | std::memcpy(¶ms, 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 | ||
| 52 | u32 nvhost_vic::Submit(const std::vector<u8>& input, std::vector<u8>& output) { | ||
| 53 | IoctlSubmit params{}; | ||
| 54 | std::memcpy(¶ms, 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(), ¶ms, sizeof(IoctlSubmit)); | ||
| 61 | return 0; | ||
| 62 | } | ||
| 63 | |||
| 64 | u32 nvhost_vic::GetSyncpoint(const std::vector<u8>& input, std::vector<u8>& output) { | ||
| 65 | IoctlGetSyncpoint params{}; | ||
| 66 | std::memcpy(¶ms, 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(), ¶ms, sizeof(IoctlGetSyncpoint)); | ||
| 70 | return 0; | ||
| 71 | } | ||
| 72 | |||
| 73 | u32 nvhost_vic::GetWaitbase(const std::vector<u8>& input, std::vector<u8>& output) { | ||
| 74 | IoctlGetWaitbase params{}; | ||
| 75 | std::memcpy(¶ms, 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(), ¶ms, sizeof(IoctlGetWaitbase)); | ||
| 79 | return 0; | ||
| 80 | } | ||
| 81 | |||
| 82 | u32 nvhost_vic::MapBuffer(const std::vector<u8>& input, std::vector<u8>& output) { | ||
| 83 | IoctlMapBuffer params{}; | ||
| 84 | std::memcpy(¶ms, 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(), ¶ms, sizeof(IoctlMapBuffer)); | ||
| 90 | return 0; | ||
| 91 | } | ||
| 92 | |||
| 93 | u32 nvhost_vic::MapBufferEx(const std::vector<u8>& input, std::vector<u8>& output) { | ||
| 94 | IoctlMapBufferEx params{}; | ||
| 95 | std::memcpy(¶ms, 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(), ¶ms, sizeof(IoctlMapBufferEx)); | ||
| 101 | return 0; | ||
| 102 | } | ||
| 103 | |||
| 104 | u32 nvhost_vic::UnmapBufferEx(const std::vector<u8>& input, std::vector<u8>& output) { | ||
| 105 | IoctlUnmapBufferEx params{}; | ||
| 106 | std::memcpy(¶ms, input.data(), sizeof(IoctlUnmapBufferEx)); | ||
| 107 | LOG_WARNING(Service_NVDRV, "(STUBBED) called"); | ||
| 108 | std::memcpy(output.data(), ¶ms, 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: | |||
| 23 | private: | 24 | private: |
| 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 | |||
| 314 | private: | 351 | private: |
| 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 | ||
| 273 | void Client::UpdateYuzuSettings(std::size_t client, const Common::Vec3<float>& acc, | 273 | void 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 | ||
| 13 | constexpr size_t COMMAND_BUFFER_POOL_SIZE = 0x1000; | 13 | constexpr size_t COMMAND_BUFFER_POOL_SIZE = 0x1000; |
| 14 | 14 | ||
| 15 | struct CommandPool::Pool { | ||
| 16 | vk::CommandPool handle; | ||
| 17 | vk::CommandBuffers cmdbufs; | ||
| 18 | }; | ||
| 19 | |||
| 15 | CommandPool::CommandPool(MasterSemaphore& master_semaphore, const VKDevice& device) | 20 | CommandPool::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; | |||
| 16 | class CommandPool final : public ResourcePool { | 18 | class CommandPool final : public ResourcePool { |
| 17 | public: | 19 | public: |
| 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 | ||
| 25 | private: | 27 | private: |
| 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 | ||
| 18 | namespace { | 19 | namespace { |
| 19 | 20 | ||
| 21 | template <typename Func> | ||
| 22 | void 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 | |||
| 33 | void 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 | |||
| 20 | void SortPhysicalDevices(std::vector<VkPhysicalDevice>& devices, const InstanceDispatch& dld) { | 44 | void 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 | ||
| 37 | template <typename T> | 59 | template <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 | ||
| 40 | ComputeInfo MakeComputeInfo(ShaderType shader_stage, ConstBufferEngineInterface& engine) { | 41 | ComputeInfo 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 | ||
| 56 | Registry::Registry(Tegra::Engines::ShaderType shader_stage, const SerializedRegistryInfo& info) | 58 | Registry::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 | ||
| 60 | Registry::Registry(Tegra::Engines::ShaderType shader_stage, | 62 | Registry::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 | ||
| 66 | Registry::~Registry() = default; | 67 | Registry::~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 | ||
| 116 | std::optional<Tegra::Engines::SamplerDescriptor> Registry::ObtainBindlessSampler(u32 buffer, | 117 | std::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 | ||
| 28 | GameListSearchField::KeyReleaseEater::KeyReleaseEater(GameList* gamelist) : gamelist{gamelist} {} | 28 | GameListSearchField::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 |
| 31 | bool GameListSearchField::KeyReleaseEater::eventFilter(QObject* obj, QEvent* event) { | 32 | bool GameListSearchField::KeyReleaseEater::eventFilter(QObject* obj, QEvent* event) { |
| @@ -116,7 +117,7 @@ void GameListSearchField::setFocus() { | |||
| 116 | } | 117 | } |
| 117 | 118 | ||
| 118 | GameListSearchField::GameListSearchField(GameList* parent) : QWidget{parent} { | 119 | GameListSearchField::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: | |||
| 330 | private: | 330 | private: |
| 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() { | |||
| 288 | void GMainWindow::ControllerSelectorReconfigureControllers( | 288 | void 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() { | |||
| 331 | void GMainWindow::SoftwareKeyboardGetText( | 332 | void 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) { |