diff options
83 files changed, 713 insertions, 370 deletions
diff --git a/src/audio_core/audio_in_manager.cpp b/src/audio_core/audio_in_manager.cpp index f39fb4002..3dfb613cb 100644 --- a/src/audio_core/audio_in_manager.cpp +++ b/src/audio_core/audio_in_manager.cpp | |||
| @@ -20,7 +20,7 @@ Manager::Manager(Core::System& system_) : system{system_} { | |||
| 20 | Result Manager::AcquireSessionId(size_t& session_id) { | 20 | Result Manager::AcquireSessionId(size_t& session_id) { |
| 21 | if (num_free_sessions == 0) { | 21 | if (num_free_sessions == 0) { |
| 22 | LOG_ERROR(Service_Audio, "All 4 AudioIn sessions are in use, cannot create any more"); | 22 | LOG_ERROR(Service_Audio, "All 4 AudioIn sessions are in use, cannot create any more"); |
| 23 | return Service::Audio::ERR_MAXIMUM_SESSIONS_REACHED; | 23 | return Service::Audio::ResultOutOfSessions; |
| 24 | } | 24 | } |
| 25 | session_id = session_ids[next_session_id]; | 25 | session_id = session_ids[next_session_id]; |
| 26 | next_session_id = (next_session_id + 1) % MaxInSessions; | 26 | next_session_id = (next_session_id + 1) % MaxInSessions; |
diff --git a/src/audio_core/audio_manager.cpp b/src/audio_core/audio_manager.cpp index 2acde668e..10b56f214 100644 --- a/src/audio_core/audio_manager.cpp +++ b/src/audio_core/audio_manager.cpp | |||
| @@ -19,7 +19,7 @@ void AudioManager::Shutdown() { | |||
| 19 | 19 | ||
| 20 | Result AudioManager::SetOutManager(BufferEventFunc buffer_func) { | 20 | Result AudioManager::SetOutManager(BufferEventFunc buffer_func) { |
| 21 | if (!running) { | 21 | if (!running) { |
| 22 | return Service::Audio::ERR_OPERATION_FAILED; | 22 | return Service::Audio::ResultOperationFailed; |
| 23 | } | 23 | } |
| 24 | 24 | ||
| 25 | std::scoped_lock l{lock}; | 25 | std::scoped_lock l{lock}; |
| @@ -35,7 +35,7 @@ Result AudioManager::SetOutManager(BufferEventFunc buffer_func) { | |||
| 35 | 35 | ||
| 36 | Result AudioManager::SetInManager(BufferEventFunc buffer_func) { | 36 | Result AudioManager::SetInManager(BufferEventFunc buffer_func) { |
| 37 | if (!running) { | 37 | if (!running) { |
| 38 | return Service::Audio::ERR_OPERATION_FAILED; | 38 | return Service::Audio::ResultOperationFailed; |
| 39 | } | 39 | } |
| 40 | 40 | ||
| 41 | std::scoped_lock l{lock}; | 41 | std::scoped_lock l{lock}; |
diff --git a/src/audio_core/audio_out_manager.cpp b/src/audio_core/audio_out_manager.cpp index 1766efde1..f22821360 100644 --- a/src/audio_core/audio_out_manager.cpp +++ b/src/audio_core/audio_out_manager.cpp | |||
| @@ -19,7 +19,7 @@ Manager::Manager(Core::System& system_) : system{system_} { | |||
| 19 | Result Manager::AcquireSessionId(size_t& session_id) { | 19 | Result Manager::AcquireSessionId(size_t& session_id) { |
| 20 | if (num_free_sessions == 0) { | 20 | if (num_free_sessions == 0) { |
| 21 | LOG_ERROR(Service_Audio, "All 12 Audio Out sessions are in use, cannot create any more"); | 21 | LOG_ERROR(Service_Audio, "All 12 Audio Out sessions are in use, cannot create any more"); |
| 22 | return Service::Audio::ERR_MAXIMUM_SESSIONS_REACHED; | 22 | return Service::Audio::ResultOutOfSessions; |
| 23 | } | 23 | } |
| 24 | session_id = session_ids[next_session_id]; | 24 | session_id = session_ids[next_session_id]; |
| 25 | next_session_id = (next_session_id + 1) % MaxOutSessions; | 25 | next_session_id = (next_session_id + 1) % MaxOutSessions; |
diff --git a/src/audio_core/audio_render_manager.cpp b/src/audio_core/audio_render_manager.cpp index 7aba2b423..320715727 100644 --- a/src/audio_core/audio_render_manager.cpp +++ b/src/audio_core/audio_render_manager.cpp | |||
| @@ -28,7 +28,7 @@ SystemManager& Manager::GetSystemManager() { | |||
| 28 | Result Manager::GetWorkBufferSize(const AudioRendererParameterInternal& params, | 28 | Result Manager::GetWorkBufferSize(const AudioRendererParameterInternal& params, |
| 29 | u64& out_count) const { | 29 | u64& out_count) const { |
| 30 | if (!CheckValidRevision(params.revision)) { | 30 | if (!CheckValidRevision(params.revision)) { |
| 31 | return Service::Audio::ERR_INVALID_REVISION; | 31 | return Service::Audio::ResultInvalidRevision; |
| 32 | } | 32 | } |
| 33 | 33 | ||
| 34 | out_count = System::GetWorkBufferSize(params); | 34 | out_count = System::GetWorkBufferSize(params); |
diff --git a/src/audio_core/in/audio_in.cpp b/src/audio_core/in/audio_in.cpp index 91ccd5ad7..df8c44d1f 100644 --- a/src/audio_core/in/audio_in.cpp +++ b/src/audio_core/in/audio_in.cpp | |||
| @@ -46,7 +46,7 @@ Result In::AppendBuffer(const AudioInBuffer& buffer, u64 tag) { | |||
| 46 | if (system.AppendBuffer(buffer, tag)) { | 46 | if (system.AppendBuffer(buffer, tag)) { |
| 47 | return ResultSuccess; | 47 | return ResultSuccess; |
| 48 | } | 48 | } |
| 49 | return Service::Audio::ERR_BUFFER_COUNT_EXCEEDED; | 49 | return Service::Audio::ResultBufferCountReached; |
| 50 | } | 50 | } |
| 51 | 51 | ||
| 52 | void In::ReleaseAndRegisterBuffers() { | 52 | void In::ReleaseAndRegisterBuffers() { |
diff --git a/src/audio_core/in/audio_in_system.cpp b/src/audio_core/in/audio_in_system.cpp index 934ef8c1c..e23e51758 100644 --- a/src/audio_core/in/audio_in_system.cpp +++ b/src/audio_core/in/audio_in_system.cpp | |||
| @@ -45,11 +45,11 @@ Result System::IsConfigValid(const std::string_view device_name, | |||
| 45 | const AudioInParameter& in_params) const { | 45 | const AudioInParameter& in_params) const { |
| 46 | if ((device_name.size() > 0) && | 46 | if ((device_name.size() > 0) && |
| 47 | (device_name != GetDefaultDeviceName() && device_name != GetDefaultUacDeviceName())) { | 47 | (device_name != GetDefaultDeviceName() && device_name != GetDefaultUacDeviceName())) { |
| 48 | return Service::Audio::ERR_INVALID_DEVICE_NAME; | 48 | return Service::Audio::ResultNotFound; |
| 49 | } | 49 | } |
| 50 | 50 | ||
| 51 | if (in_params.sample_rate != TargetSampleRate && in_params.sample_rate > 0) { | 51 | if (in_params.sample_rate != TargetSampleRate && in_params.sample_rate > 0) { |
| 52 | return Service::Audio::ERR_INVALID_SAMPLE_RATE; | 52 | return Service::Audio::ResultInvalidSampleRate; |
| 53 | } | 53 | } |
| 54 | 54 | ||
| 55 | return ResultSuccess; | 55 | return ResultSuccess; |
| @@ -80,7 +80,7 @@ Result System::Initialize(std::string device_name, const AudioInParameter& in_pa | |||
| 80 | 80 | ||
| 81 | Result System::Start() { | 81 | Result System::Start() { |
| 82 | if (state != State::Stopped) { | 82 | if (state != State::Stopped) { |
| 83 | return Service::Audio::ERR_OPERATION_FAILED; | 83 | return Service::Audio::ResultOperationFailed; |
| 84 | } | 84 | } |
| 85 | 85 | ||
| 86 | session->Initialize(name, sample_format, channel_count, session_id, handle, | 86 | session->Initialize(name, sample_format, channel_count, session_id, handle, |
diff --git a/src/audio_core/out/audio_out.cpp b/src/audio_core/out/audio_out.cpp index d3ee4f0eb..b7ea13405 100644 --- a/src/audio_core/out/audio_out.cpp +++ b/src/audio_core/out/audio_out.cpp | |||
| @@ -46,7 +46,7 @@ Result Out::AppendBuffer(const AudioOutBuffer& buffer, const u64 tag) { | |||
| 46 | if (system.AppendBuffer(buffer, tag)) { | 46 | if (system.AppendBuffer(buffer, tag)) { |
| 47 | return ResultSuccess; | 47 | return ResultSuccess; |
| 48 | } | 48 | } |
| 49 | return Service::Audio::ERR_BUFFER_COUNT_EXCEEDED; | 49 | return Service::Audio::ResultBufferCountReached; |
| 50 | } | 50 | } |
| 51 | 51 | ||
| 52 | void Out::ReleaseAndRegisterBuffers() { | 52 | void Out::ReleaseAndRegisterBuffers() { |
diff --git a/src/audio_core/out/audio_out_system.cpp b/src/audio_core/out/audio_out_system.cpp index e096a1dac..bd13f7219 100644 --- a/src/audio_core/out/audio_out_system.cpp +++ b/src/audio_core/out/audio_out_system.cpp | |||
| @@ -33,11 +33,11 @@ std::string_view System::GetDefaultOutputDeviceName() const { | |||
| 33 | Result System::IsConfigValid(std::string_view device_name, | 33 | Result System::IsConfigValid(std::string_view device_name, |
| 34 | const AudioOutParameter& in_params) const { | 34 | const AudioOutParameter& in_params) const { |
| 35 | if ((device_name.size() > 0) && (device_name != GetDefaultOutputDeviceName())) { | 35 | if ((device_name.size() > 0) && (device_name != GetDefaultOutputDeviceName())) { |
| 36 | return Service::Audio::ERR_INVALID_DEVICE_NAME; | 36 | return Service::Audio::ResultNotFound; |
| 37 | } | 37 | } |
| 38 | 38 | ||
| 39 | if (in_params.sample_rate != TargetSampleRate && in_params.sample_rate > 0) { | 39 | if (in_params.sample_rate != TargetSampleRate && in_params.sample_rate > 0) { |
| 40 | return Service::Audio::ERR_INVALID_SAMPLE_RATE; | 40 | return Service::Audio::ResultInvalidSampleRate; |
| 41 | } | 41 | } |
| 42 | 42 | ||
| 43 | if (in_params.channel_count == 0 || in_params.channel_count == 2 || | 43 | if (in_params.channel_count == 0 || in_params.channel_count == 2 || |
| @@ -45,7 +45,7 @@ Result System::IsConfigValid(std::string_view device_name, | |||
| 45 | return ResultSuccess; | 45 | return ResultSuccess; |
| 46 | } | 46 | } |
| 47 | 47 | ||
| 48 | return Service::Audio::ERR_INVALID_CHANNEL_COUNT; | 48 | return Service::Audio::ResultInvalidChannelCount; |
| 49 | } | 49 | } |
| 50 | 50 | ||
| 51 | Result System::Initialize(std::string device_name, const AudioOutParameter& in_params, u32 handle_, | 51 | Result System::Initialize(std::string device_name, const AudioOutParameter& in_params, u32 handle_, |
| @@ -80,7 +80,7 @@ size_t System::GetSessionId() const { | |||
| 80 | 80 | ||
| 81 | Result System::Start() { | 81 | Result System::Start() { |
| 82 | if (state != State::Stopped) { | 82 | if (state != State::Stopped) { |
| 83 | return Service::Audio::ERR_OPERATION_FAILED; | 83 | return Service::Audio::ResultOperationFailed; |
| 84 | } | 84 | } |
| 85 | 85 | ||
| 86 | session->Initialize(name, sample_format, channel_count, session_id, handle, | 86 | session->Initialize(name, sample_format, channel_count, session_id, handle, |
diff --git a/src/audio_core/renderer/adsp/audio_renderer.cpp b/src/audio_core/renderer/adsp/audio_renderer.cpp index 78c15629b..0e437e779 100644 --- a/src/audio_core/renderer/adsp/audio_renderer.cpp +++ b/src/audio_core/renderer/adsp/audio_renderer.cpp | |||
| @@ -135,7 +135,7 @@ void AudioRenderer::ThreadFunc() { | |||
| 135 | static constexpr char name[]{"AudioRenderer"}; | 135 | static constexpr char name[]{"AudioRenderer"}; |
| 136 | MicroProfileOnThreadCreate(name); | 136 | MicroProfileOnThreadCreate(name); |
| 137 | Common::SetCurrentThreadName(name); | 137 | Common::SetCurrentThreadName(name); |
| 138 | Common::SetCurrentThreadPriority(Common::ThreadPriority::Critical); | 138 | Common::SetCurrentThreadPriority(Common::ThreadPriority::High); |
| 139 | if (mailbox->ADSPWaitMessage() != RenderMessage::AudioRenderer_InitializeOK) { | 139 | if (mailbox->ADSPWaitMessage() != RenderMessage::AudioRenderer_InitializeOK) { |
| 140 | LOG_ERROR(Service_Audio, | 140 | LOG_ERROR(Service_Audio, |
| 141 | "ADSP Audio Renderer -- Failed to receive initialize message from host!"); | 141 | "ADSP Audio Renderer -- Failed to receive initialize message from host!"); |
diff --git a/src/audio_core/renderer/audio_renderer.cpp b/src/audio_core/renderer/audio_renderer.cpp index 51aa17599..a8257eb2e 100644 --- a/src/audio_core/renderer/audio_renderer.cpp +++ b/src/audio_core/renderer/audio_renderer.cpp | |||
| @@ -22,7 +22,7 @@ Result Renderer::Initialize(const AudioRendererParameterInternal& params, | |||
| 22 | if (!manager.AddSystem(system)) { | 22 | if (!manager.AddSystem(system)) { |
| 23 | LOG_ERROR(Service_Audio, | 23 | LOG_ERROR(Service_Audio, |
| 24 | "Both Audio Render sessions are in use, cannot create any more"); | 24 | "Both Audio Render sessions are in use, cannot create any more"); |
| 25 | return Service::Audio::ERR_MAXIMUM_SESSIONS_REACHED; | 25 | return Service::Audio::ResultOutOfSessions; |
| 26 | } | 26 | } |
| 27 | system_registered = true; | 27 | system_registered = true; |
| 28 | } | 28 | } |
diff --git a/src/audio_core/renderer/behavior/info_updater.cpp b/src/audio_core/renderer/behavior/info_updater.cpp index 574cf0982..e312eb166 100644 --- a/src/audio_core/renderer/behavior/info_updater.cpp +++ b/src/audio_core/renderer/behavior/info_updater.cpp | |||
| @@ -48,7 +48,7 @@ Result InfoUpdater::UpdateVoiceChannelResources(VoiceContext& voice_context) { | |||
| 48 | LOG_ERROR(Service_Audio, | 48 | LOG_ERROR(Service_Audio, |
| 49 | "Consumed an incorrect voice resource size, header size={}, consumed={}", | 49 | "Consumed an incorrect voice resource size, header size={}, consumed={}", |
| 50 | in_header->voice_resources_size, consumed_input_size); | 50 | in_header->voice_resources_size, consumed_input_size); |
| 51 | return Service::Audio::ERR_INVALID_UPDATE_DATA; | 51 | return Service::Audio::ResultInvalidUpdateInfo; |
| 52 | } | 52 | } |
| 53 | 53 | ||
| 54 | input += consumed_input_size; | 54 | input += consumed_input_size; |
| @@ -123,7 +123,7 @@ Result InfoUpdater::UpdateVoices(VoiceContext& voice_context, | |||
| 123 | if (consumed_input_size != in_header->voices_size) { | 123 | if (consumed_input_size != in_header->voices_size) { |
| 124 | LOG_ERROR(Service_Audio, "Consumed an incorrect voices size, header size={}, consumed={}", | 124 | LOG_ERROR(Service_Audio, "Consumed an incorrect voices size, header size={}, consumed={}", |
| 125 | in_header->voices_size, consumed_input_size); | 125 | in_header->voices_size, consumed_input_size); |
| 126 | return Service::Audio::ERR_INVALID_UPDATE_DATA; | 126 | return Service::Audio::ResultInvalidUpdateInfo; |
| 127 | } | 127 | } |
| 128 | 128 | ||
| 129 | out_header->voices_size = consumed_output_size; | 129 | out_header->voices_size = consumed_output_size; |
| @@ -184,7 +184,7 @@ Result InfoUpdater::UpdateEffectsVersion1(EffectContext& effect_context, const b | |||
| 184 | if (consumed_input_size != in_header->effects_size) { | 184 | if (consumed_input_size != in_header->effects_size) { |
| 185 | LOG_ERROR(Service_Audio, "Consumed an incorrect effects size, header size={}, consumed={}", | 185 | LOG_ERROR(Service_Audio, "Consumed an incorrect effects size, header size={}, consumed={}", |
| 186 | in_header->effects_size, consumed_input_size); | 186 | in_header->effects_size, consumed_input_size); |
| 187 | return Service::Audio::ERR_INVALID_UPDATE_DATA; | 187 | return Service::Audio::ResultInvalidUpdateInfo; |
| 188 | } | 188 | } |
| 189 | 189 | ||
| 190 | out_header->effects_size = consumed_output_size; | 190 | out_header->effects_size = consumed_output_size; |
| @@ -239,7 +239,7 @@ Result InfoUpdater::UpdateEffectsVersion2(EffectContext& effect_context, const b | |||
| 239 | if (consumed_input_size != in_header->effects_size) { | 239 | if (consumed_input_size != in_header->effects_size) { |
| 240 | LOG_ERROR(Service_Audio, "Consumed an incorrect effects size, header size={}, consumed={}", | 240 | LOG_ERROR(Service_Audio, "Consumed an incorrect effects size, header size={}, consumed={}", |
| 241 | in_header->effects_size, consumed_input_size); | 241 | in_header->effects_size, consumed_input_size); |
| 242 | return Service::Audio::ERR_INVALID_UPDATE_DATA; | 242 | return Service::Audio::ResultInvalidUpdateInfo; |
| 243 | } | 243 | } |
| 244 | 244 | ||
| 245 | out_header->effects_size = consumed_output_size; | 245 | out_header->effects_size = consumed_output_size; |
| @@ -267,7 +267,7 @@ Result InfoUpdater::UpdateMixes(MixContext& mix_context, const u32 mix_buffer_co | |||
| 267 | } | 267 | } |
| 268 | 268 | ||
| 269 | if (mix_buffer_count == 0) { | 269 | if (mix_buffer_count == 0) { |
| 270 | return Service::Audio::ERR_INVALID_UPDATE_DATA; | 270 | return Service::Audio::ResultInvalidUpdateInfo; |
| 271 | } | 271 | } |
| 272 | 272 | ||
| 273 | std::span<const MixInfo::InParameter> in_params{ | 273 | std::span<const MixInfo::InParameter> in_params{ |
| @@ -281,13 +281,13 @@ Result InfoUpdater::UpdateMixes(MixContext& mix_context, const u32 mix_buffer_co | |||
| 281 | total_buffer_count += params.buffer_count; | 281 | total_buffer_count += params.buffer_count; |
| 282 | if (params.dest_mix_id > static_cast<s32>(mix_context.GetCount()) && | 282 | if (params.dest_mix_id > static_cast<s32>(mix_context.GetCount()) && |
| 283 | params.dest_mix_id != UnusedMixId && params.mix_id != FinalMixId) { | 283 | params.dest_mix_id != UnusedMixId && params.mix_id != FinalMixId) { |
| 284 | return Service::Audio::ERR_INVALID_UPDATE_DATA; | 284 | return Service::Audio::ResultInvalidUpdateInfo; |
| 285 | } | 285 | } |
| 286 | } | 286 | } |
| 287 | } | 287 | } |
| 288 | 288 | ||
| 289 | if (total_buffer_count > mix_buffer_count) { | 289 | if (total_buffer_count > mix_buffer_count) { |
| 290 | return Service::Audio::ERR_INVALID_UPDATE_DATA; | 290 | return Service::Audio::ResultInvalidUpdateInfo; |
| 291 | } | 291 | } |
| 292 | 292 | ||
| 293 | bool mix_dirty{false}; | 293 | bool mix_dirty{false}; |
| @@ -317,7 +317,7 @@ Result InfoUpdater::UpdateMixes(MixContext& mix_context, const u32 mix_buffer_co | |||
| 317 | if (mix_dirty) { | 317 | if (mix_dirty) { |
| 318 | if (behaviour.IsSplitterSupported() && splitter_context.UsingSplitter()) { | 318 | if (behaviour.IsSplitterSupported() && splitter_context.UsingSplitter()) { |
| 319 | if (!mix_context.TSortInfo(splitter_context)) { | 319 | if (!mix_context.TSortInfo(splitter_context)) { |
| 320 | return Service::Audio::ERR_INVALID_UPDATE_DATA; | 320 | return Service::Audio::ResultInvalidUpdateInfo; |
| 321 | } | 321 | } |
| 322 | } else { | 322 | } else { |
| 323 | mix_context.SortInfo(); | 323 | mix_context.SortInfo(); |
| @@ -327,7 +327,7 @@ Result InfoUpdater::UpdateMixes(MixContext& mix_context, const u32 mix_buffer_co | |||
| 327 | if (consumed_input_size != in_header->mix_size) { | 327 | if (consumed_input_size != in_header->mix_size) { |
| 328 | LOG_ERROR(Service_Audio, "Consumed an incorrect mixes size, header size={}, consumed={}", | 328 | LOG_ERROR(Service_Audio, "Consumed an incorrect mixes size, header size={}, consumed={}", |
| 329 | in_header->mix_size, consumed_input_size); | 329 | in_header->mix_size, consumed_input_size); |
| 330 | return Service::Audio::ERR_INVALID_UPDATE_DATA; | 330 | return Service::Audio::ResultInvalidUpdateInfo; |
| 331 | } | 331 | } |
| 332 | 332 | ||
| 333 | input += mix_count * sizeof(MixInfo::InParameter); | 333 | input += mix_count * sizeof(MixInfo::InParameter); |
| @@ -384,7 +384,7 @@ Result InfoUpdater::UpdateSinks(SinkContext& sink_context, std::span<MemoryPoolI | |||
| 384 | if (consumed_input_size != in_header->sinks_size) { | 384 | if (consumed_input_size != in_header->sinks_size) { |
| 385 | LOG_ERROR(Service_Audio, "Consumed an incorrect sinks size, header size={}, consumed={}", | 385 | LOG_ERROR(Service_Audio, "Consumed an incorrect sinks size, header size={}, consumed={}", |
| 386 | in_header->sinks_size, consumed_input_size); | 386 | in_header->sinks_size, consumed_input_size); |
| 387 | return Service::Audio::ERR_INVALID_UPDATE_DATA; | 387 | return Service::Audio::ResultInvalidUpdateInfo; |
| 388 | } | 388 | } |
| 389 | 389 | ||
| 390 | input += consumed_input_size; | 390 | input += consumed_input_size; |
| @@ -411,7 +411,7 @@ Result InfoUpdater::UpdateMemoryPools(std::span<MemoryPoolInfo> memory_pools, | |||
| 411 | state != MemoryPoolInfo::ResultState::MapFailed && | 411 | state != MemoryPoolInfo::ResultState::MapFailed && |
| 412 | state != MemoryPoolInfo::ResultState::InUse) { | 412 | state != MemoryPoolInfo::ResultState::InUse) { |
| 413 | LOG_WARNING(Service_Audio, "Invalid ResultState from updating memory pools"); | 413 | LOG_WARNING(Service_Audio, "Invalid ResultState from updating memory pools"); |
| 414 | return Service::Audio::ERR_INVALID_UPDATE_DATA; | 414 | return Service::Audio::ResultInvalidUpdateInfo; |
| 415 | } | 415 | } |
| 416 | } | 416 | } |
| 417 | 417 | ||
| @@ -423,7 +423,7 @@ Result InfoUpdater::UpdateMemoryPools(std::span<MemoryPoolInfo> memory_pools, | |||
| 423 | LOG_ERROR(Service_Audio, | 423 | LOG_ERROR(Service_Audio, |
| 424 | "Consumed an incorrect memory pool size, header size={}, consumed={}", | 424 | "Consumed an incorrect memory pool size, header size={}, consumed={}", |
| 425 | in_header->memory_pool_size, consumed_input_size); | 425 | in_header->memory_pool_size, consumed_input_size); |
| 426 | return Service::Audio::ERR_INVALID_UPDATE_DATA; | 426 | return Service::Audio::ResultInvalidUpdateInfo; |
| 427 | } | 427 | } |
| 428 | 428 | ||
| 429 | input += consumed_input_size; | 429 | input += consumed_input_size; |
| @@ -453,7 +453,7 @@ Result InfoUpdater::UpdatePerformanceBuffer(std::span<u8> performance_output, | |||
| 453 | LOG_ERROR(Service_Audio, | 453 | LOG_ERROR(Service_Audio, |
| 454 | "Consumed an incorrect performance size, header size={}, consumed={}", | 454 | "Consumed an incorrect performance size, header size={}, consumed={}", |
| 455 | in_header->performance_buffer_size, consumed_input_size); | 455 | in_header->performance_buffer_size, consumed_input_size); |
| 456 | return Service::Audio::ERR_INVALID_UPDATE_DATA; | 456 | return Service::Audio::ResultInvalidUpdateInfo; |
| 457 | } | 457 | } |
| 458 | 458 | ||
| 459 | input += consumed_input_size; | 459 | input += consumed_input_size; |
| @@ -467,18 +467,18 @@ Result InfoUpdater::UpdateBehaviorInfo(BehaviorInfo& behaviour_) { | |||
| 467 | const auto in_params{reinterpret_cast<const BehaviorInfo::InParameter*>(input)}; | 467 | const auto in_params{reinterpret_cast<const BehaviorInfo::InParameter*>(input)}; |
| 468 | 468 | ||
| 469 | if (!CheckValidRevision(in_params->revision)) { | 469 | if (!CheckValidRevision(in_params->revision)) { |
| 470 | return Service::Audio::ERR_INVALID_UPDATE_DATA; | 470 | return Service::Audio::ResultInvalidUpdateInfo; |
| 471 | } | 471 | } |
| 472 | 472 | ||
| 473 | if (in_params->revision != behaviour_.GetUserRevision()) { | 473 | if (in_params->revision != behaviour_.GetUserRevision()) { |
| 474 | return Service::Audio::ERR_INVALID_UPDATE_DATA; | 474 | return Service::Audio::ResultInvalidUpdateInfo; |
| 475 | } | 475 | } |
| 476 | 476 | ||
| 477 | behaviour_.ClearError(); | 477 | behaviour_.ClearError(); |
| 478 | behaviour_.UpdateFlags(in_params->flags); | 478 | behaviour_.UpdateFlags(in_params->flags); |
| 479 | 479 | ||
| 480 | if (in_header->behaviour_size != sizeof(BehaviorInfo::InParameter)) { | 480 | if (in_header->behaviour_size != sizeof(BehaviorInfo::InParameter)) { |
| 481 | return Service::Audio::ERR_INVALID_UPDATE_DATA; | 481 | return Service::Audio::ResultInvalidUpdateInfo; |
| 482 | } | 482 | } |
| 483 | 483 | ||
| 484 | input += sizeof(BehaviorInfo::InParameter); | 484 | input += sizeof(BehaviorInfo::InParameter); |
| @@ -500,7 +500,7 @@ Result InfoUpdater::UpdateErrorInfo(const BehaviorInfo& behaviour_) { | |||
| 500 | Result InfoUpdater::UpdateSplitterInfo(SplitterContext& splitter_context) { | 500 | Result InfoUpdater::UpdateSplitterInfo(SplitterContext& splitter_context) { |
| 501 | u32 consumed_size{0}; | 501 | u32 consumed_size{0}; |
| 502 | if (!splitter_context.Update(input, consumed_size)) { | 502 | if (!splitter_context.Update(input, consumed_size)) { |
| 503 | return Service::Audio::ERR_INVALID_UPDATE_DATA; | 503 | return Service::Audio::ResultInvalidUpdateInfo; |
| 504 | } | 504 | } |
| 505 | 505 | ||
| 506 | input += consumed_size; | 506 | input += consumed_size; |
| @@ -529,9 +529,9 @@ Result InfoUpdater::UpdateRendererInfo(const u64 elapsed_frames) { | |||
| 529 | 529 | ||
| 530 | Result InfoUpdater::CheckConsumedSize() { | 530 | Result InfoUpdater::CheckConsumedSize() { |
| 531 | if (CpuAddr(input) - CpuAddr(input_origin.data()) != expected_input_size) { | 531 | if (CpuAddr(input) - CpuAddr(input_origin.data()) != expected_input_size) { |
| 532 | return Service::Audio::ERR_INVALID_UPDATE_DATA; | 532 | return Service::Audio::ResultInvalidUpdateInfo; |
| 533 | } else if (CpuAddr(output) - CpuAddr(output_origin.data()) != expected_output_size) { | 533 | } else if (CpuAddr(output) - CpuAddr(output_origin.data()) != expected_output_size) { |
| 534 | return Service::Audio::ERR_INVALID_UPDATE_DATA; | 534 | return Service::Audio::ResultInvalidUpdateInfo; |
| 535 | } | 535 | } |
| 536 | return ResultSuccess; | 536 | return ResultSuccess; |
| 537 | } | 537 | } |
diff --git a/src/audio_core/renderer/memory/pool_mapper.cpp b/src/audio_core/renderer/memory/pool_mapper.cpp index 2baf2ce08..7fd2b5f47 100644 --- a/src/audio_core/renderer/memory/pool_mapper.cpp +++ b/src/audio_core/renderer/memory/pool_mapper.cpp | |||
| @@ -92,7 +92,7 @@ bool PoolMapper::TryAttachBuffer(BehaviorInfo::ErrorInfo& error_info, AddressInf | |||
| 92 | address_info.Setup(address, size); | 92 | address_info.Setup(address, size); |
| 93 | 93 | ||
| 94 | if (!FillDspAddr(address_info)) { | 94 | if (!FillDspAddr(address_info)) { |
| 95 | error_info.error_code = Service::Audio::ERR_POOL_MAPPING_FAILED; | 95 | error_info.error_code = Service::Audio::ResultInvalidAddressInfo; |
| 96 | error_info.address = address; | 96 | error_info.address = address; |
| 97 | return force_map; | 97 | return force_map; |
| 98 | } | 98 | } |
diff --git a/src/audio_core/renderer/system.cpp b/src/audio_core/renderer/system.cpp index 31cbee282..28f063641 100644 --- a/src/audio_core/renderer/system.cpp +++ b/src/audio_core/renderer/system.cpp | |||
| @@ -101,15 +101,15 @@ Result System::Initialize(const AudioRendererParameterInternal& params, | |||
| 101 | Kernel::KTransferMemory* transfer_memory, u64 transfer_memory_size, | 101 | Kernel::KTransferMemory* transfer_memory, u64 transfer_memory_size, |
| 102 | u32 process_handle_, u64 applet_resource_user_id_, s32 session_id_) { | 102 | u32 process_handle_, u64 applet_resource_user_id_, s32 session_id_) { |
| 103 | if (!CheckValidRevision(params.revision)) { | 103 | if (!CheckValidRevision(params.revision)) { |
| 104 | return Service::Audio::ERR_INVALID_REVISION; | 104 | return Service::Audio::ResultInvalidRevision; |
| 105 | } | 105 | } |
| 106 | 106 | ||
| 107 | if (GetWorkBufferSize(params) > transfer_memory_size) { | 107 | if (GetWorkBufferSize(params) > transfer_memory_size) { |
| 108 | return Service::Audio::ERR_INSUFFICIENT_BUFFER_SIZE; | 108 | return Service::Audio::ResultInsufficientBuffer; |
| 109 | } | 109 | } |
| 110 | 110 | ||
| 111 | if (process_handle_ == 0) { | 111 | if (process_handle_ == 0) { |
| 112 | return Service::Audio::ERR_INVALID_PROCESS_HANDLE; | 112 | return Service::Audio::ResultInvalidHandle; |
| 113 | } | 113 | } |
| 114 | 114 | ||
| 115 | behavior.SetUserLibRevision(params.revision); | 115 | behavior.SetUserLibRevision(params.revision); |
| @@ -143,19 +143,19 @@ Result System::Initialize(const AudioRendererParameterInternal& params, | |||
| 143 | samples_workbuffer = | 143 | samples_workbuffer = |
| 144 | allocator.Allocate<s32>((voice_channels + mix_buffer_count) * sample_count, 0x10); | 144 | allocator.Allocate<s32>((voice_channels + mix_buffer_count) * sample_count, 0x10); |
| 145 | if (samples_workbuffer.empty()) { | 145 | if (samples_workbuffer.empty()) { |
| 146 | return Service::Audio::ERR_INSUFFICIENT_BUFFER_SIZE; | 146 | return Service::Audio::ResultInsufficientBuffer; |
| 147 | } | 147 | } |
| 148 | 148 | ||
| 149 | auto upsampler_workbuffer{allocator.Allocate<s32>( | 149 | auto upsampler_workbuffer{allocator.Allocate<s32>( |
| 150 | (voice_channels + mix_buffer_count) * TargetSampleCount * upsampler_count, 0x10)}; | 150 | (voice_channels + mix_buffer_count) * TargetSampleCount * upsampler_count, 0x10)}; |
| 151 | if (upsampler_workbuffer.empty()) { | 151 | if (upsampler_workbuffer.empty()) { |
| 152 | return Service::Audio::ERR_INSUFFICIENT_BUFFER_SIZE; | 152 | return Service::Audio::ResultInsufficientBuffer; |
| 153 | } | 153 | } |
| 154 | 154 | ||
| 155 | depop_buffer = | 155 | depop_buffer = |
| 156 | allocator.Allocate<s32>(Common::AlignUp(static_cast<u32>(mix_buffer_count), 0x40), 0x40); | 156 | allocator.Allocate<s32>(Common::AlignUp(static_cast<u32>(mix_buffer_count), 0x40), 0x40); |
| 157 | if (depop_buffer.empty()) { | 157 | if (depop_buffer.empty()) { |
| 158 | return Service::Audio::ERR_INSUFFICIENT_BUFFER_SIZE; | 158 | return Service::Audio::ResultInsufficientBuffer; |
| 159 | } | 159 | } |
| 160 | 160 | ||
| 161 | // invalidate samples_workbuffer DSP cache | 161 | // invalidate samples_workbuffer DSP cache |
| @@ -166,12 +166,12 @@ Result System::Initialize(const AudioRendererParameterInternal& params, | |||
| 166 | } | 166 | } |
| 167 | 167 | ||
| 168 | if (voice_infos.empty()) { | 168 | if (voice_infos.empty()) { |
| 169 | return Service::Audio::ERR_INSUFFICIENT_BUFFER_SIZE; | 169 | return Service::Audio::ResultInsufficientBuffer; |
| 170 | } | 170 | } |
| 171 | 171 | ||
| 172 | auto sorted_voice_infos{allocator.Allocate<VoiceInfo*>(params.voices, 0x10)}; | 172 | auto sorted_voice_infos{allocator.Allocate<VoiceInfo*>(params.voices, 0x10)}; |
| 173 | if (sorted_voice_infos.empty()) { | 173 | if (sorted_voice_infos.empty()) { |
| 174 | return Service::Audio::ERR_INSUFFICIENT_BUFFER_SIZE; | 174 | return Service::Audio::ResultInsufficientBuffer; |
| 175 | } | 175 | } |
| 176 | 176 | ||
| 177 | std::memset(sorted_voice_infos.data(), 0, sorted_voice_infos.size_bytes()); | 177 | std::memset(sorted_voice_infos.data(), 0, sorted_voice_infos.size_bytes()); |
| @@ -183,12 +183,12 @@ Result System::Initialize(const AudioRendererParameterInternal& params, | |||
| 183 | } | 183 | } |
| 184 | 184 | ||
| 185 | if (voice_channel_resources.empty()) { | 185 | if (voice_channel_resources.empty()) { |
| 186 | return Service::Audio::ERR_INSUFFICIENT_BUFFER_SIZE; | 186 | return Service::Audio::ResultInsufficientBuffer; |
| 187 | } | 187 | } |
| 188 | 188 | ||
| 189 | auto voice_cpu_states{allocator.Allocate<VoiceState>(params.voices, 0x10)}; | 189 | auto voice_cpu_states{allocator.Allocate<VoiceState>(params.voices, 0x10)}; |
| 190 | if (voice_cpu_states.empty()) { | 190 | if (voice_cpu_states.empty()) { |
| 191 | return Service::Audio::ERR_INSUFFICIENT_BUFFER_SIZE; | 191 | return Service::Audio::ResultInsufficientBuffer; |
| 192 | } | 192 | } |
| 193 | 193 | ||
| 194 | for (auto& voice_state : voice_cpu_states) { | 194 | for (auto& voice_state : voice_cpu_states) { |
| @@ -198,7 +198,7 @@ Result System::Initialize(const AudioRendererParameterInternal& params, | |||
| 198 | auto mix_infos{allocator.Allocate<MixInfo>(params.sub_mixes + 1, 0x10)}; | 198 | auto mix_infos{allocator.Allocate<MixInfo>(params.sub_mixes + 1, 0x10)}; |
| 199 | 199 | ||
| 200 | if (mix_infos.empty()) { | 200 | if (mix_infos.empty()) { |
| 201 | return Service::Audio::ERR_INSUFFICIENT_BUFFER_SIZE; | 201 | return Service::Audio::ResultInsufficientBuffer; |
| 202 | } | 202 | } |
| 203 | 203 | ||
| 204 | u32 effect_process_order_count{0}; | 204 | u32 effect_process_order_count{0}; |
| @@ -208,7 +208,7 @@ Result System::Initialize(const AudioRendererParameterInternal& params, | |||
| 208 | effect_process_order_count = params.effects * (params.sub_mixes + 1); | 208 | effect_process_order_count = params.effects * (params.sub_mixes + 1); |
| 209 | effect_process_order_buffer = allocator.Allocate<s32>(effect_process_order_count, 0x10); | 209 | effect_process_order_buffer = allocator.Allocate<s32>(effect_process_order_count, 0x10); |
| 210 | if (effect_process_order_buffer.empty()) { | 210 | if (effect_process_order_buffer.empty()) { |
| 211 | return Service::Audio::ERR_INSUFFICIENT_BUFFER_SIZE; | 211 | return Service::Audio::ResultInsufficientBuffer; |
| 212 | } | 212 | } |
| 213 | } | 213 | } |
| 214 | 214 | ||
| @@ -222,7 +222,7 @@ Result System::Initialize(const AudioRendererParameterInternal& params, | |||
| 222 | 222 | ||
| 223 | auto sorted_mix_infos{allocator.Allocate<MixInfo*>(params.sub_mixes + 1, 0x10)}; | 223 | auto sorted_mix_infos{allocator.Allocate<MixInfo*>(params.sub_mixes + 1, 0x10)}; |
| 224 | if (sorted_mix_infos.empty()) { | 224 | if (sorted_mix_infos.empty()) { |
| 225 | return Service::Audio::ERR_INSUFFICIENT_BUFFER_SIZE; | 225 | return Service::Audio::ResultInsufficientBuffer; |
| 226 | } | 226 | } |
| 227 | 227 | ||
| 228 | std::memset(sorted_mix_infos.data(), 0, sorted_mix_infos.size_bytes()); | 228 | std::memset(sorted_mix_infos.data(), 0, sorted_mix_infos.size_bytes()); |
| @@ -235,7 +235,7 @@ Result System::Initialize(const AudioRendererParameterInternal& params, | |||
| 235 | auto edge_matrix_workbuffer{allocator.Allocate<u8>(edge_matrix_size, 1)}; | 235 | auto edge_matrix_workbuffer{allocator.Allocate<u8>(edge_matrix_size, 1)}; |
| 236 | 236 | ||
| 237 | if (node_states_workbuffer.empty() || edge_matrix_workbuffer.size() == 0) { | 237 | if (node_states_workbuffer.empty() || edge_matrix_workbuffer.size() == 0) { |
| 238 | return Service::Audio::ERR_INSUFFICIENT_BUFFER_SIZE; | 238 | return Service::Audio::ResultInsufficientBuffer; |
| 239 | } | 239 | } |
| 240 | 240 | ||
| 241 | mix_context.Initialize(sorted_mix_infos, mix_infos, params.sub_mixes + 1, | 241 | mix_context.Initialize(sorted_mix_infos, mix_infos, params.sub_mixes + 1, |
| @@ -250,7 +250,7 @@ Result System::Initialize(const AudioRendererParameterInternal& params, | |||
| 250 | 250 | ||
| 251 | upsampler_manager = allocator.Allocate<UpsamplerManager>(1, 0x10).data(); | 251 | upsampler_manager = allocator.Allocate<UpsamplerManager>(1, 0x10).data(); |
| 252 | if (upsampler_manager == nullptr) { | 252 | if (upsampler_manager == nullptr) { |
| 253 | return Service::Audio::ERR_INSUFFICIENT_BUFFER_SIZE; | 253 | return Service::Audio::ResultInsufficientBuffer; |
| 254 | } | 254 | } |
| 255 | 255 | ||
| 256 | memory_pool_workbuffer = allocator.Allocate<MemoryPoolInfo>(memory_pool_count, 0x10); | 256 | memory_pool_workbuffer = allocator.Allocate<MemoryPoolInfo>(memory_pool_count, 0x10); |
| @@ -259,18 +259,18 @@ Result System::Initialize(const AudioRendererParameterInternal& params, | |||
| 259 | } | 259 | } |
| 260 | 260 | ||
| 261 | if (memory_pool_workbuffer.empty() && memory_pool_count > 0) { | 261 | if (memory_pool_workbuffer.empty() && memory_pool_count > 0) { |
| 262 | return Service::Audio::ERR_INSUFFICIENT_BUFFER_SIZE; | 262 | return Service::Audio::ResultInsufficientBuffer; |
| 263 | } | 263 | } |
| 264 | 264 | ||
| 265 | if (!splitter_context.Initialize(behavior, params, allocator)) { | 265 | if (!splitter_context.Initialize(behavior, params, allocator)) { |
| 266 | return Service::Audio::ERR_INSUFFICIENT_BUFFER_SIZE; | 266 | return Service::Audio::ResultInsufficientBuffer; |
| 267 | } | 267 | } |
| 268 | 268 | ||
| 269 | std::span<EffectResultState> effect_result_states_cpu{}; | 269 | std::span<EffectResultState> effect_result_states_cpu{}; |
| 270 | if (behavior.IsEffectInfoVersion2Supported() && params.effects > 0) { | 270 | if (behavior.IsEffectInfoVersion2Supported() && params.effects > 0) { |
| 271 | effect_result_states_cpu = allocator.Allocate<EffectResultState>(params.effects, 0x10); | 271 | effect_result_states_cpu = allocator.Allocate<EffectResultState>(params.effects, 0x10); |
| 272 | if (effect_result_states_cpu.empty()) { | 272 | if (effect_result_states_cpu.empty()) { |
| 273 | return Service::Audio::ERR_INSUFFICIENT_BUFFER_SIZE; | 273 | return Service::Audio::ResultInsufficientBuffer; |
| 274 | } | 274 | } |
| 275 | std::memset(effect_result_states_cpu.data(), 0, effect_result_states_cpu.size_bytes()); | 275 | std::memset(effect_result_states_cpu.data(), 0, effect_result_states_cpu.size_bytes()); |
| 276 | } | 276 | } |
| @@ -289,7 +289,7 @@ Result System::Initialize(const AudioRendererParameterInternal& params, | |||
| 289 | upsampler_workbuffer); | 289 | upsampler_workbuffer); |
| 290 | 290 | ||
| 291 | if (upsampler_infos.empty()) { | 291 | if (upsampler_infos.empty()) { |
| 292 | return Service::Audio::ERR_INSUFFICIENT_BUFFER_SIZE; | 292 | return Service::Audio::ResultInsufficientBuffer; |
| 293 | } | 293 | } |
| 294 | 294 | ||
| 295 | auto effect_infos{allocator.Allocate<EffectInfoBase>(params.effects, 0x40)}; | 295 | auto effect_infos{allocator.Allocate<EffectInfoBase>(params.effects, 0x40)}; |
| @@ -298,14 +298,14 @@ Result System::Initialize(const AudioRendererParameterInternal& params, | |||
| 298 | } | 298 | } |
| 299 | 299 | ||
| 300 | if (effect_infos.empty() && params.effects > 0) { | 300 | if (effect_infos.empty() && params.effects > 0) { |
| 301 | return Service::Audio::ERR_INSUFFICIENT_BUFFER_SIZE; | 301 | return Service::Audio::ResultInsufficientBuffer; |
| 302 | } | 302 | } |
| 303 | 303 | ||
| 304 | std::span<EffectResultState> effect_result_states_dsp{}; | 304 | std::span<EffectResultState> effect_result_states_dsp{}; |
| 305 | if (behavior.IsEffectInfoVersion2Supported() && params.effects > 0) { | 305 | if (behavior.IsEffectInfoVersion2Supported() && params.effects > 0) { |
| 306 | effect_result_states_dsp = allocator.Allocate<EffectResultState>(params.effects, 0x40); | 306 | effect_result_states_dsp = allocator.Allocate<EffectResultState>(params.effects, 0x40); |
| 307 | if (effect_result_states_dsp.empty()) { | 307 | if (effect_result_states_dsp.empty()) { |
| 308 | return Service::Audio::ERR_INSUFFICIENT_BUFFER_SIZE; | 308 | return Service::Audio::ResultInsufficientBuffer; |
| 309 | } | 309 | } |
| 310 | std::memset(effect_result_states_dsp.data(), 0, effect_result_states_dsp.size_bytes()); | 310 | std::memset(effect_result_states_dsp.data(), 0, effect_result_states_dsp.size_bytes()); |
| 311 | } | 311 | } |
| @@ -319,14 +319,14 @@ Result System::Initialize(const AudioRendererParameterInternal& params, | |||
| 319 | } | 319 | } |
| 320 | 320 | ||
| 321 | if (sinks.empty()) { | 321 | if (sinks.empty()) { |
| 322 | return Service::Audio::ERR_INSUFFICIENT_BUFFER_SIZE; | 322 | return Service::Audio::ResultInsufficientBuffer; |
| 323 | } | 323 | } |
| 324 | 324 | ||
| 325 | sink_context.Initialize(sinks, params.sinks); | 325 | sink_context.Initialize(sinks, params.sinks); |
| 326 | 326 | ||
| 327 | auto voice_dsp_states{allocator.Allocate<VoiceState>(params.voices, 0x40)}; | 327 | auto voice_dsp_states{allocator.Allocate<VoiceState>(params.voices, 0x40)}; |
| 328 | if (voice_dsp_states.empty()) { | 328 | if (voice_dsp_states.empty()) { |
| 329 | return Service::Audio::ERR_INSUFFICIENT_BUFFER_SIZE; | 329 | return Service::Audio::ResultInsufficientBuffer; |
| 330 | } | 330 | } |
| 331 | 331 | ||
| 332 | for (auto& voice_state : voice_dsp_states) { | 332 | for (auto& voice_state : voice_dsp_states) { |
| @@ -344,7 +344,7 @@ Result System::Initialize(const AudioRendererParameterInternal& params, | |||
| 344 | 0xC}; | 344 | 0xC}; |
| 345 | performance_workbuffer = allocator.Allocate<u8>(perf_workbuffer_size, 0x40); | 345 | performance_workbuffer = allocator.Allocate<u8>(perf_workbuffer_size, 0x40); |
| 346 | if (performance_workbuffer.empty()) { | 346 | if (performance_workbuffer.empty()) { |
| 347 | return Service::Audio::ERR_INSUFFICIENT_BUFFER_SIZE; | 347 | return Service::Audio::ResultInsufficientBuffer; |
| 348 | } | 348 | } |
| 349 | std::memset(performance_workbuffer.data(), 0, performance_workbuffer.size_bytes()); | 349 | std::memset(performance_workbuffer.data(), 0, performance_workbuffer.size_bytes()); |
| 350 | performance_manager.Initialize(performance_workbuffer, performance_workbuffer.size_bytes(), | 350 | performance_manager.Initialize(performance_workbuffer, performance_workbuffer.size_bytes(), |
| @@ -360,7 +360,7 @@ Result System::Initialize(const AudioRendererParameterInternal& params, | |||
| 360 | command_workbuffer_size = allocator.GetRemainingSize(); | 360 | command_workbuffer_size = allocator.GetRemainingSize(); |
| 361 | command_workbuffer = allocator.Allocate<u8>(command_workbuffer_size, 0x40); | 361 | command_workbuffer = allocator.Allocate<u8>(command_workbuffer_size, 0x40); |
| 362 | if (command_workbuffer.empty()) { | 362 | if (command_workbuffer.empty()) { |
| 363 | return Service::Audio::ERR_INSUFFICIENT_BUFFER_SIZE; | 363 | return Service::Audio::ResultInsufficientBuffer; |
| 364 | } | 364 | } |
| 365 | 365 | ||
| 366 | command_buffer_size = 0; | 366 | command_buffer_size = 0; |
diff --git a/src/audio_core/renderer/voice/voice_info.cpp b/src/audio_core/renderer/voice/voice_info.cpp index 1849eeb57..c0bfb23fc 100644 --- a/src/audio_core/renderer/voice/voice_info.cpp +++ b/src/audio_core/renderer/voice/voice_info.cpp | |||
| @@ -181,7 +181,7 @@ void VoiceInfo::UpdateWaveBuffer(std::span<BehaviorInfo::ErrorInfo> error_info, | |||
| 181 | if (wave_buffer_internal.start_offset * byte_size > wave_buffer_internal.size || | 181 | if (wave_buffer_internal.start_offset * byte_size > wave_buffer_internal.size || |
| 182 | wave_buffer_internal.end_offset * byte_size > wave_buffer_internal.size) { | 182 | wave_buffer_internal.end_offset * byte_size > wave_buffer_internal.size) { |
| 183 | LOG_ERROR(Service_Audio, "Invalid PCM16 start/end wavebuffer sizes!"); | 183 | LOG_ERROR(Service_Audio, "Invalid PCM16 start/end wavebuffer sizes!"); |
| 184 | error_info[0].error_code = Service::Audio::ERR_INVALID_UPDATE_DATA; | 184 | error_info[0].error_code = Service::Audio::ResultInvalidUpdateInfo; |
| 185 | error_info[0].address = wave_buffer_internal.address; | 185 | error_info[0].address = wave_buffer_internal.address; |
| 186 | return; | 186 | return; |
| 187 | } | 187 | } |
| @@ -192,7 +192,7 @@ void VoiceInfo::UpdateWaveBuffer(std::span<BehaviorInfo::ErrorInfo> error_info, | |||
| 192 | if (wave_buffer_internal.start_offset * byte_size > wave_buffer_internal.size || | 192 | if (wave_buffer_internal.start_offset * byte_size > wave_buffer_internal.size || |
| 193 | wave_buffer_internal.end_offset * byte_size > wave_buffer_internal.size) { | 193 | wave_buffer_internal.end_offset * byte_size > wave_buffer_internal.size) { |
| 194 | LOG_ERROR(Service_Audio, "Invalid PCMFloat start/end wavebuffer sizes!"); | 194 | LOG_ERROR(Service_Audio, "Invalid PCMFloat start/end wavebuffer sizes!"); |
| 195 | error_info[0].error_code = Service::Audio::ERR_INVALID_UPDATE_DATA; | 195 | error_info[0].error_code = Service::Audio::ResultInvalidUpdateInfo; |
| 196 | error_info[0].address = wave_buffer_internal.address; | 196 | error_info[0].address = wave_buffer_internal.address; |
| 197 | return; | 197 | return; |
| 198 | } | 198 | } |
| @@ -216,7 +216,7 @@ void VoiceInfo::UpdateWaveBuffer(std::span<BehaviorInfo::ErrorInfo> error_info, | |||
| 216 | if (start > static_cast<s64>(wave_buffer_internal.size) || | 216 | if (start > static_cast<s64>(wave_buffer_internal.size) || |
| 217 | end > static_cast<s64>(wave_buffer_internal.size)) { | 217 | end > static_cast<s64>(wave_buffer_internal.size)) { |
| 218 | LOG_ERROR(Service_Audio, "Invalid ADPCM start/end wavebuffer sizes!"); | 218 | LOG_ERROR(Service_Audio, "Invalid ADPCM start/end wavebuffer sizes!"); |
| 219 | error_info[0].error_code = Service::Audio::ERR_INVALID_UPDATE_DATA; | 219 | error_info[0].error_code = Service::Audio::ResultInvalidUpdateInfo; |
| 220 | error_info[0].address = wave_buffer_internal.address; | 220 | error_info[0].address = wave_buffer_internal.address; |
| 221 | return; | 221 | return; |
| 222 | } | 222 | } |
| @@ -228,7 +228,7 @@ void VoiceInfo::UpdateWaveBuffer(std::span<BehaviorInfo::ErrorInfo> error_info, | |||
| 228 | 228 | ||
| 229 | if (wave_buffer_internal.start_offset < 0 || wave_buffer_internal.end_offset < 0) { | 229 | if (wave_buffer_internal.start_offset < 0 || wave_buffer_internal.end_offset < 0) { |
| 230 | LOG_ERROR(Service_Audio, "Invalid input start/end wavebuffer sizes!"); | 230 | LOG_ERROR(Service_Audio, "Invalid input start/end wavebuffer sizes!"); |
| 231 | error_info[0].error_code = Service::Audio::ERR_INVALID_UPDATE_DATA; | 231 | error_info[0].error_code = Service::Audio::ResultInvalidUpdateInfo; |
| 232 | error_info[0].address = wave_buffer_internal.address; | 232 | error_info[0].address = wave_buffer_internal.address; |
| 233 | return; | 233 | return; |
| 234 | } | 234 | } |
diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index 58ff5f2f3..61ab68864 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt | |||
| @@ -91,6 +91,7 @@ add_library(common STATIC | |||
| 91 | multi_level_page_table.h | 91 | multi_level_page_table.h |
| 92 | nvidia_flags.cpp | 92 | nvidia_flags.cpp |
| 93 | nvidia_flags.h | 93 | nvidia_flags.h |
| 94 | overflow.h | ||
| 94 | page_table.cpp | 95 | page_table.cpp |
| 95 | page_table.h | 96 | page_table.h |
| 96 | param_package.cpp | 97 | param_package.cpp |
diff --git a/src/common/bit_cast.h b/src/common/bit_cast.h index 535148b4d..c6110c542 100644 --- a/src/common/bit_cast.h +++ b/src/common/bit_cast.h | |||
| @@ -3,19 +3,21 @@ | |||
| 3 | 3 | ||
| 4 | #pragma once | 4 | #pragma once |
| 5 | 5 | ||
| 6 | #include <cstring> | 6 | #include <version> |
| 7 | #include <type_traits> | 7 | |
| 8 | #ifdef __cpp_lib_bit_cast | ||
| 9 | #include <bit> | ||
| 10 | #endif | ||
| 8 | 11 | ||
| 9 | namespace Common { | 12 | namespace Common { |
| 10 | 13 | ||
| 11 | template <typename To, typename From> | 14 | template <typename To, typename From> |
| 12 | [[nodiscard]] std::enable_if_t<sizeof(To) == sizeof(From) && std::is_trivially_copyable_v<From> && | 15 | constexpr inline To BitCast(const From& from) { |
| 13 | std::is_trivially_copyable_v<To>, | 16 | #ifdef __cpp_lib_bit_cast |
| 14 | To> | 17 | return std::bit_cast<To>(from); |
| 15 | BitCast(const From& src) noexcept { | 18 | #else |
| 16 | To dst; | 19 | return __builtin_bit_cast(To, from); |
| 17 | std::memcpy(&dst, &src, sizeof(To)); | 20 | #endif |
| 18 | return dst; | ||
| 19 | } | 21 | } |
| 20 | 22 | ||
| 21 | } // namespace Common | 23 | } // namespace Common |
diff --git a/src/common/input.h b/src/common/input.h index b5748a6c8..98e934685 100644 --- a/src/common/input.h +++ b/src/common/input.h | |||
| @@ -46,7 +46,7 @@ enum class PollingMode { | |||
| 46 | // Constant polling of buttons, analogs and motion data | 46 | // Constant polling of buttons, analogs and motion data |
| 47 | Active, | 47 | Active, |
| 48 | // Only update on button change, digital analogs | 48 | // Only update on button change, digital analogs |
| 49 | Pasive, | 49 | Passive, |
| 50 | // Enable near field communication polling | 50 | // Enable near field communication polling |
| 51 | NFC, | 51 | NFC, |
| 52 | // Enable infrared camera polling | 52 | // Enable infrared camera polling |
diff --git a/src/common/overflow.h b/src/common/overflow.h new file mode 100644 index 000000000..44d8e7e73 --- /dev/null +++ b/src/common/overflow.h | |||
| @@ -0,0 +1,22 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include <type_traits> | ||
| 7 | #include "bit_cast.h" | ||
| 8 | |||
| 9 | namespace Common { | ||
| 10 | |||
| 11 | template <typename T> | ||
| 12 | requires(std::is_integral_v<T> && std::is_signed_v<T>) | ||
| 13 | inline T WrappingAdd(T lhs, T rhs) { | ||
| 14 | using U = std::make_unsigned_t<T>; | ||
| 15 | |||
| 16 | U lhs_u = BitCast<U>(lhs); | ||
| 17 | U rhs_u = BitCast<U>(rhs); | ||
| 18 | |||
| 19 | return BitCast<T>(lhs_u + rhs_u); | ||
| 20 | } | ||
| 21 | |||
| 22 | } // namespace Common | ||
diff --git a/src/common/settings.h b/src/common/settings.h index 1ae28ce93..b77a1580a 100644 --- a/src/common/settings.h +++ b/src/common/settings.h | |||
| @@ -503,7 +503,7 @@ struct Values { | |||
| 503 | Setting<bool> tas_loop{false, "tas_loop"}; | 503 | Setting<bool> tas_loop{false, "tas_loop"}; |
| 504 | 504 | ||
| 505 | Setting<bool> mouse_panning{false, "mouse_panning"}; | 505 | Setting<bool> mouse_panning{false, "mouse_panning"}; |
| 506 | Setting<u8, true> mouse_panning_sensitivity{10, 1, 100, "mouse_panning_sensitivity"}; | 506 | Setting<u8, true> mouse_panning_sensitivity{50, 1, 100, "mouse_panning_sensitivity"}; |
| 507 | Setting<bool> mouse_enabled{false, "mouse_enabled"}; | 507 | Setting<bool> mouse_enabled{false, "mouse_enabled"}; |
| 508 | 508 | ||
| 509 | Setting<bool> emulate_analog_keyboard{false, "emulate_analog_keyboard"}; | 509 | Setting<bool> emulate_analog_keyboard{false, "emulate_analog_keyboard"}; |
diff --git a/src/common/steady_clock.cpp b/src/common/steady_clock.cpp index 0d5908aa7..782859196 100644 --- a/src/common/steady_clock.cpp +++ b/src/common/steady_clock.cpp | |||
| @@ -23,6 +23,19 @@ static s64 WindowsQueryPerformanceCounter() { | |||
| 23 | QueryPerformanceCounter(&counter); | 23 | QueryPerformanceCounter(&counter); |
| 24 | return counter.QuadPart; | 24 | return counter.QuadPart; |
| 25 | } | 25 | } |
| 26 | |||
| 27 | static s64 GetSystemTimeNS() { | ||
| 28 | // GetSystemTimePreciseAsFileTime returns the file time in 100ns units. | ||
| 29 | static constexpr s64 Multiplier = 100; | ||
| 30 | // Convert Windows epoch to Unix epoch. | ||
| 31 | static constexpr s64 WindowsEpochToUnixEpochNS = 0x19DB1DED53E8000LL; | ||
| 32 | |||
| 33 | FILETIME filetime; | ||
| 34 | GetSystemTimePreciseAsFileTime(&filetime); | ||
| 35 | return Multiplier * ((static_cast<s64>(filetime.dwHighDateTime) << 32) + | ||
| 36 | static_cast<s64>(filetime.dwLowDateTime)) - | ||
| 37 | WindowsEpochToUnixEpochNS; | ||
| 38 | } | ||
| 26 | #endif | 39 | #endif |
| 27 | 40 | ||
| 28 | SteadyClock::time_point SteadyClock::Now() noexcept { | 41 | SteadyClock::time_point SteadyClock::Now() noexcept { |
| @@ -53,4 +66,16 @@ SteadyClock::time_point SteadyClock::Now() noexcept { | |||
| 53 | #endif | 66 | #endif |
| 54 | } | 67 | } |
| 55 | 68 | ||
| 69 | RealTimeClock::time_point RealTimeClock::Now() noexcept { | ||
| 70 | #if defined(_WIN32) | ||
| 71 | return time_point{duration{GetSystemTimeNS()}}; | ||
| 72 | #elif defined(__APPLE__) | ||
| 73 | return time_point{duration{clock_gettime_nsec_np(CLOCK_REALTIME)}}; | ||
| 74 | #else | ||
| 75 | timespec ts; | ||
| 76 | clock_gettime(CLOCK_REALTIME, &ts); | ||
| 77 | return time_point{std::chrono::seconds{ts.tv_sec} + std::chrono::nanoseconds{ts.tv_nsec}}; | ||
| 78 | #endif | ||
| 79 | } | ||
| 80 | |||
| 56 | }; // namespace Common | 81 | }; // namespace Common |
diff --git a/src/common/steady_clock.h b/src/common/steady_clock.h index 9497cf865..dbd0e2513 100644 --- a/src/common/steady_clock.h +++ b/src/common/steady_clock.h | |||
| @@ -20,4 +20,15 @@ struct SteadyClock { | |||
| 20 | [[nodiscard]] static time_point Now() noexcept; | 20 | [[nodiscard]] static time_point Now() noexcept; |
| 21 | }; | 21 | }; |
| 22 | 22 | ||
| 23 | struct RealTimeClock { | ||
| 24 | using rep = s64; | ||
| 25 | using period = std::nano; | ||
| 26 | using duration = std::chrono::nanoseconds; | ||
| 27 | using time_point = std::chrono::time_point<RealTimeClock>; | ||
| 28 | |||
| 29 | static constexpr bool is_steady = false; | ||
| 30 | |||
| 31 | [[nodiscard]] static time_point Now() noexcept; | ||
| 32 | }; | ||
| 33 | |||
| 23 | } // namespace Common | 34 | } // namespace Common |
diff --git a/src/common/x64/native_clock.cpp b/src/common/x64/native_clock.cpp index bc1a973b0..76c66e7ee 100644 --- a/src/common/x64/native_clock.cpp +++ b/src/common/x64/native_clock.cpp | |||
| @@ -53,11 +53,11 @@ u64 EstimateRDTSCFrequency() { | |||
| 53 | FencedRDTSC(); | 53 | FencedRDTSC(); |
| 54 | 54 | ||
| 55 | // Get the current time. | 55 | // Get the current time. |
| 56 | const auto start_time = Common::SteadyClock::Now(); | 56 | const auto start_time = Common::RealTimeClock::Now(); |
| 57 | const u64 tsc_start = FencedRDTSC(); | 57 | const u64 tsc_start = FencedRDTSC(); |
| 58 | // Wait for 250 milliseconds. | 58 | // Wait for 250 milliseconds. |
| 59 | std::this_thread::sleep_for(std::chrono::milliseconds{250}); | 59 | std::this_thread::sleep_for(std::chrono::milliseconds{250}); |
| 60 | const auto end_time = Common::SteadyClock::Now(); | 60 | const auto end_time = Common::RealTimeClock::Now(); |
| 61 | const u64 tsc_end = FencedRDTSC(); | 61 | const u64 tsc_end = FencedRDTSC(); |
| 62 | // Calculate differences. | 62 | // Calculate differences. |
| 63 | const u64 timer_diff = static_cast<u64>( | 63 | const u64 timer_diff = static_cast<u64>( |
| @@ -72,13 +72,29 @@ NativeClock::NativeClock(u64 emulated_cpu_frequency_, u64 emulated_clock_frequen | |||
| 72 | u64 rtsc_frequency_) | 72 | u64 rtsc_frequency_) |
| 73 | : WallClock(emulated_cpu_frequency_, emulated_clock_frequency_, true), rtsc_frequency{ | 73 | : WallClock(emulated_cpu_frequency_, emulated_clock_frequency_, true), rtsc_frequency{ |
| 74 | rtsc_frequency_} { | 74 | rtsc_frequency_} { |
| 75 | // Thread to re-adjust the RDTSC frequency after 10 seconds has elapsed. | ||
| 76 | time_sync_thread = std::jthread{[this](std::stop_token token) { | ||
| 77 | // Get the current time. | ||
| 78 | const auto start_time = Common::RealTimeClock::Now(); | ||
| 79 | const u64 tsc_start = FencedRDTSC(); | ||
| 80 | // Wait for 10 seconds. | ||
| 81 | if (!Common::StoppableTimedWait(token, std::chrono::seconds{10})) { | ||
| 82 | return; | ||
| 83 | } | ||
| 84 | const auto end_time = Common::RealTimeClock::Now(); | ||
| 85 | const u64 tsc_end = FencedRDTSC(); | ||
| 86 | // Calculate differences. | ||
| 87 | const u64 timer_diff = static_cast<u64>( | ||
| 88 | std::chrono::duration_cast<std::chrono::nanoseconds>(end_time - start_time).count()); | ||
| 89 | const u64 tsc_diff = tsc_end - tsc_start; | ||
| 90 | const u64 tsc_freq = MultiplyAndDivide64(tsc_diff, 1000000000ULL, timer_diff); | ||
| 91 | rtsc_frequency = tsc_freq; | ||
| 92 | CalculateAndSetFactors(); | ||
| 93 | }}; | ||
| 94 | |||
| 75 | time_point.inner.last_measure = FencedRDTSC(); | 95 | time_point.inner.last_measure = FencedRDTSC(); |
| 76 | time_point.inner.accumulated_ticks = 0U; | 96 | time_point.inner.accumulated_ticks = 0U; |
| 77 | ns_rtsc_factor = GetFixedPoint64Factor(NS_RATIO, rtsc_frequency); | 97 | CalculateAndSetFactors(); |
| 78 | us_rtsc_factor = GetFixedPoint64Factor(US_RATIO, rtsc_frequency); | ||
| 79 | ms_rtsc_factor = GetFixedPoint64Factor(MS_RATIO, rtsc_frequency); | ||
| 80 | clock_rtsc_factor = GetFixedPoint64Factor(emulated_clock_frequency, rtsc_frequency); | ||
| 81 | cpu_rtsc_factor = GetFixedPoint64Factor(emulated_cpu_frequency, rtsc_frequency); | ||
| 82 | } | 98 | } |
| 83 | 99 | ||
| 84 | u64 NativeClock::GetRTSC() { | 100 | u64 NativeClock::GetRTSC() { |
| @@ -138,6 +154,14 @@ u64 NativeClock::GetCPUCycles() { | |||
| 138 | return MultiplyHigh(rtsc_value, cpu_rtsc_factor); | 154 | return MultiplyHigh(rtsc_value, cpu_rtsc_factor); |
| 139 | } | 155 | } |
| 140 | 156 | ||
| 157 | void NativeClock::CalculateAndSetFactors() { | ||
| 158 | ns_rtsc_factor = GetFixedPoint64Factor(NS_RATIO, rtsc_frequency); | ||
| 159 | us_rtsc_factor = GetFixedPoint64Factor(US_RATIO, rtsc_frequency); | ||
| 160 | ms_rtsc_factor = GetFixedPoint64Factor(MS_RATIO, rtsc_frequency); | ||
| 161 | clock_rtsc_factor = GetFixedPoint64Factor(emulated_clock_frequency, rtsc_frequency); | ||
| 162 | cpu_rtsc_factor = GetFixedPoint64Factor(emulated_cpu_frequency, rtsc_frequency); | ||
| 163 | } | ||
| 164 | |||
| 141 | } // namespace X64 | 165 | } // namespace X64 |
| 142 | 166 | ||
| 143 | } // namespace Common | 167 | } // namespace Common |
diff --git a/src/common/x64/native_clock.h b/src/common/x64/native_clock.h index 38ae7a462..03ca291d8 100644 --- a/src/common/x64/native_clock.h +++ b/src/common/x64/native_clock.h | |||
| @@ -3,6 +3,7 @@ | |||
| 3 | 3 | ||
| 4 | #pragma once | 4 | #pragma once |
| 5 | 5 | ||
| 6 | #include "common/polyfill_thread.h" | ||
| 6 | #include "common/wall_clock.h" | 7 | #include "common/wall_clock.h" |
| 7 | 8 | ||
| 8 | namespace Common { | 9 | namespace Common { |
| @@ -28,6 +29,8 @@ public: | |||
| 28 | private: | 29 | private: |
| 29 | u64 GetRTSC(); | 30 | u64 GetRTSC(); |
| 30 | 31 | ||
| 32 | void CalculateAndSetFactors(); | ||
| 33 | |||
| 31 | union alignas(16) TimePoint { | 34 | union alignas(16) TimePoint { |
| 32 | TimePoint() : pack{} {} | 35 | TimePoint() : pack{} {} |
| 33 | u128 pack{}; | 36 | u128 pack{}; |
| @@ -47,6 +50,8 @@ private: | |||
| 47 | u64 ms_rtsc_factor{}; | 50 | u64 ms_rtsc_factor{}; |
| 48 | 51 | ||
| 49 | u64 rtsc_frequency; | 52 | u64 rtsc_frequency; |
| 53 | |||
| 54 | std::jthread time_sync_thread; | ||
| 50 | }; | 55 | }; |
| 51 | } // namespace X64 | 56 | } // namespace X64 |
| 52 | 57 | ||
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 4a1a8bb43..75e0c4f38 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt | |||
| @@ -454,7 +454,6 @@ add_library(core STATIC | |||
| 454 | hle/service/filesystem/fsp_srv.h | 454 | hle/service/filesystem/fsp_srv.h |
| 455 | hle/service/fgm/fgm.cpp | 455 | hle/service/fgm/fgm.cpp |
| 456 | hle/service/fgm/fgm.h | 456 | hle/service/fgm/fgm.h |
| 457 | hle/service/friend/errors.h | ||
| 458 | hle/service/friend/friend.cpp | 457 | hle/service/friend/friend.cpp |
| 459 | hle/service/friend/friend.h | 458 | hle/service/friend/friend.h |
| 460 | hle/service/friend/friend_interface.cpp | 459 | hle/service/friend/friend_interface.cpp |
diff --git a/src/core/core_timing.cpp b/src/core/core_timing.cpp index 742cfb996..cd4df4522 100644 --- a/src/core/core_timing.cpp +++ b/src/core/core_timing.cpp | |||
| @@ -53,7 +53,7 @@ void CoreTiming::ThreadEntry(CoreTiming& instance) { | |||
| 53 | static constexpr char name[] = "HostTiming"; | 53 | static constexpr char name[] = "HostTiming"; |
| 54 | MicroProfileOnThreadCreate(name); | 54 | MicroProfileOnThreadCreate(name); |
| 55 | Common::SetCurrentThreadName(name); | 55 | Common::SetCurrentThreadName(name); |
| 56 | Common::SetCurrentThreadPriority(Common::ThreadPriority::Critical); | 56 | Common::SetCurrentThreadPriority(Common::ThreadPriority::High); |
| 57 | instance.on_thread_init(); | 57 | instance.on_thread_init(); |
| 58 | instance.ThreadLoop(); | 58 | instance.ThreadLoop(); |
| 59 | MicroProfileOnThreadExit(); | 59 | MicroProfileOnThreadExit(); |
diff --git a/src/core/cpu_manager.cpp b/src/core/cpu_manager.cpp index 04a11f444..980bb97f9 100644 --- a/src/core/cpu_manager.cpp +++ b/src/core/cpu_manager.cpp | |||
| @@ -192,7 +192,7 @@ void CpuManager::RunThread(std::stop_token token, std::size_t core) { | |||
| 192 | } | 192 | } |
| 193 | MicroProfileOnThreadCreate(name.c_str()); | 193 | MicroProfileOnThreadCreate(name.c_str()); |
| 194 | Common::SetCurrentThreadName(name.c_str()); | 194 | Common::SetCurrentThreadName(name.c_str()); |
| 195 | Common::SetCurrentThreadPriority(Common::ThreadPriority::High); | 195 | Common::SetCurrentThreadPriority(Common::ThreadPriority::Critical); |
| 196 | auto& data = core_data[core]; | 196 | auto& data = core_data[core]; |
| 197 | data.host_context = Common::Fiber::ThreadToFiber(); | 197 | data.host_context = Common::Fiber::ThreadToFiber(); |
| 198 | 198 | ||
diff --git a/src/core/hle/kernel/k_address_space_info.cpp b/src/core/hle/kernel/k_address_space_info.cpp index 97972ebae..c36eb5dc4 100644 --- a/src/core/hle/kernel/k_address_space_info.cpp +++ b/src/core/hle/kernel/k_address_space_info.cpp | |||
| @@ -44,11 +44,11 @@ const KAddressSpaceInfo& GetAddressSpaceInfo(size_t width, KAddressSpaceInfo::Ty | |||
| 44 | 44 | ||
| 45 | } // namespace | 45 | } // namespace |
| 46 | 46 | ||
| 47 | uintptr_t KAddressSpaceInfo::GetAddressSpaceStart(size_t width, KAddressSpaceInfo::Type type) { | 47 | std::size_t KAddressSpaceInfo::GetAddressSpaceStart(size_t width, KAddressSpaceInfo::Type type) { |
| 48 | return GetAddressSpaceInfo(width, type).address; | 48 | return GetAddressSpaceInfo(width, type).address; |
| 49 | } | 49 | } |
| 50 | 50 | ||
| 51 | size_t KAddressSpaceInfo::GetAddressSpaceSize(size_t width, KAddressSpaceInfo::Type type) { | 51 | std::size_t KAddressSpaceInfo::GetAddressSpaceSize(size_t width, KAddressSpaceInfo::Type type) { |
| 52 | return GetAddressSpaceInfo(width, type).size; | 52 | return GetAddressSpaceInfo(width, type).size; |
| 53 | } | 53 | } |
| 54 | 54 | ||
diff --git a/src/core/hle/kernel/k_address_space_info.h b/src/core/hle/kernel/k_address_space_info.h index 69e9d77f2..9a26f6b90 100644 --- a/src/core/hle/kernel/k_address_space_info.h +++ b/src/core/hle/kernel/k_address_space_info.h | |||
| @@ -18,7 +18,7 @@ struct KAddressSpaceInfo final { | |||
| 18 | Count, | 18 | Count, |
| 19 | }; | 19 | }; |
| 20 | 20 | ||
| 21 | static u64 GetAddressSpaceStart(std::size_t width, Type type); | 21 | static std::size_t GetAddressSpaceStart(std::size_t width, Type type); |
| 22 | static std::size_t GetAddressSpaceSize(std::size_t width, Type type); | 22 | static std::size_t GetAddressSpaceSize(std::size_t width, Type type); |
| 23 | 23 | ||
| 24 | const std::size_t bit_width{}; | 24 | const std::size_t bit_width{}; |
diff --git a/src/core/hle/kernel/k_device_address_space.h b/src/core/hle/kernel/k_device_address_space.h index 4709df995..b4a014c38 100644 --- a/src/core/hle/kernel/k_device_address_space.h +++ b/src/core/hle/kernel/k_device_address_space.h | |||
| @@ -21,9 +21,9 @@ public: | |||
| 21 | ~KDeviceAddressSpace(); | 21 | ~KDeviceAddressSpace(); |
| 22 | 22 | ||
| 23 | Result Initialize(u64 address, u64 size); | 23 | Result Initialize(u64 address, u64 size); |
| 24 | void Finalize(); | 24 | void Finalize() override; |
| 25 | 25 | ||
| 26 | bool IsInitialized() const { | 26 | bool IsInitialized() const override { |
| 27 | return m_is_initialized; | 27 | return m_is_initialized; |
| 28 | } | 28 | } |
| 29 | static void PostDestroy(uintptr_t arg) {} | 29 | static void PostDestroy(uintptr_t arg) {} |
diff --git a/src/core/hle/kernel/k_process.h b/src/core/hle/kernel/k_process.h index 09bf2f1d0..549809000 100644 --- a/src/core/hle/kernel/k_process.h +++ b/src/core/hle/kernel/k_process.h | |||
| @@ -310,10 +310,10 @@ public: | |||
| 310 | /// Clears the signaled state of the process if and only if it's signaled. | 310 | /// Clears the signaled state of the process if and only if it's signaled. |
| 311 | /// | 311 | /// |
| 312 | /// @pre The process must not be already terminated. If this is called on a | 312 | /// @pre The process must not be already terminated. If this is called on a |
| 313 | /// terminated process, then ERR_INVALID_STATE will be returned. | 313 | /// terminated process, then ResultInvalidState will be returned. |
| 314 | /// | 314 | /// |
| 315 | /// @pre The process must be in a signaled state. If this is called on a | 315 | /// @pre The process must be in a signaled state. If this is called on a |
| 316 | /// process instance that is not signaled, ERR_INVALID_STATE will be | 316 | /// process instance that is not signaled, ResultInvalidState will be |
| 317 | /// returned. | 317 | /// returned. |
| 318 | Result Reset(); | 318 | Result Reset(); |
| 319 | 319 | ||
diff --git a/src/core/hle/kernel/k_resource_limit.cpp b/src/core/hle/kernel/k_resource_limit.cpp index b9d22b414..626517619 100644 --- a/src/core/hle/kernel/k_resource_limit.cpp +++ b/src/core/hle/kernel/k_resource_limit.cpp | |||
| @@ -2,6 +2,7 @@ | |||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | 2 | // SPDX-License-Identifier: GPL-2.0-or-later |
| 3 | 3 | ||
| 4 | #include "common/assert.h" | 4 | #include "common/assert.h" |
| 5 | #include "common/overflow.h" | ||
| 5 | #include "core/core.h" | 6 | #include "core/core.h" |
| 6 | #include "core/core_timing.h" | 7 | #include "core/core_timing.h" |
| 7 | #include "core/hle/kernel/k_resource_limit.h" | 8 | #include "core/hle/kernel/k_resource_limit.h" |
| @@ -104,7 +105,7 @@ bool KResourceLimit::Reserve(LimitableResource which, s64 value, s64 timeout) { | |||
| 104 | ASSERT(current_hints[index] <= current_values[index]); | 105 | ASSERT(current_hints[index] <= current_values[index]); |
| 105 | 106 | ||
| 106 | // If we would overflow, don't allow to succeed. | 107 | // If we would overflow, don't allow to succeed. |
| 107 | if (current_values[index] + value <= current_values[index]) { | 108 | if (Common::WrappingAdd(current_values[index], value) <= current_values[index]) { |
| 108 | break; | 109 | break; |
| 109 | } | 110 | } |
| 110 | 111 | ||
diff --git a/src/core/hle/kernel/k_thread.cpp b/src/core/hle/kernel/k_thread.cpp index 96b90ffef..26e3700e4 100644 --- a/src/core/hle/kernel/k_thread.cpp +++ b/src/core/hle/kernel/k_thread.cpp | |||
| @@ -49,6 +49,7 @@ static void ResetThreadContext32(Core::ARM_Interface::ThreadContext32& context, | |||
| 49 | context.cpu_registers[0] = arg; | 49 | context.cpu_registers[0] = arg; |
| 50 | context.cpu_registers[15] = entry_point; | 50 | context.cpu_registers[15] = entry_point; |
| 51 | context.cpu_registers[13] = stack_top; | 51 | context.cpu_registers[13] = stack_top; |
| 52 | context.fpscr = 0; | ||
| 52 | } | 53 | } |
| 53 | 54 | ||
| 54 | static void ResetThreadContext64(Core::ARM_Interface::ThreadContext64& context, VAddr stack_top, | 55 | static void ResetThreadContext64(Core::ARM_Interface::ThreadContext64& context, VAddr stack_top, |
| @@ -58,8 +59,8 @@ static void ResetThreadContext64(Core::ARM_Interface::ThreadContext64& context, | |||
| 58 | context.cpu_registers[18] = Kernel::KSystemControl::GenerateRandomU64() | 1; | 59 | context.cpu_registers[18] = Kernel::KSystemControl::GenerateRandomU64() | 1; |
| 59 | context.pc = entry_point; | 60 | context.pc = entry_point; |
| 60 | context.sp = stack_top; | 61 | context.sp = stack_top; |
| 61 | // TODO(merry): Perform a hardware test to determine the below value. | ||
| 62 | context.fpcr = 0; | 62 | context.fpcr = 0; |
| 63 | context.fpsr = 0; | ||
| 63 | } | 64 | } |
| 64 | } // namespace | 65 | } // namespace |
| 65 | 66 | ||
| @@ -815,6 +816,27 @@ void KThread::Continue() { | |||
| 815 | KScheduler::OnThreadStateChanged(kernel, this, old_state); | 816 | KScheduler::OnThreadStateChanged(kernel, this, old_state); |
| 816 | } | 817 | } |
| 817 | 818 | ||
| 819 | void KThread::CloneFpuStatus() { | ||
| 820 | // We shouldn't reach here when starting kernel threads. | ||
| 821 | ASSERT(this->GetOwnerProcess() != nullptr); | ||
| 822 | ASSERT(this->GetOwnerProcess() == GetCurrentProcessPointer(kernel)); | ||
| 823 | |||
| 824 | if (this->GetOwnerProcess()->Is64BitProcess()) { | ||
| 825 | // Clone FPSR and FPCR. | ||
| 826 | ThreadContext64 cur_ctx{}; | ||
| 827 | kernel.System().CurrentArmInterface().SaveContext(cur_ctx); | ||
| 828 | |||
| 829 | this->GetContext64().fpcr = cur_ctx.fpcr; | ||
| 830 | this->GetContext64().fpsr = cur_ctx.fpsr; | ||
| 831 | } else { | ||
| 832 | // Clone FPSCR. | ||
| 833 | ThreadContext32 cur_ctx{}; | ||
| 834 | kernel.System().CurrentArmInterface().SaveContext(cur_ctx); | ||
| 835 | |||
| 836 | this->GetContext32().fpscr = cur_ctx.fpscr; | ||
| 837 | } | ||
| 838 | } | ||
| 839 | |||
| 818 | Result KThread::SetActivity(Svc::ThreadActivity activity) { | 840 | Result KThread::SetActivity(Svc::ThreadActivity activity) { |
| 819 | // Lock ourselves. | 841 | // Lock ourselves. |
| 820 | KScopedLightLock lk(activity_pause_lock); | 842 | KScopedLightLock lk(activity_pause_lock); |
diff --git a/src/core/hle/kernel/k_thread.h b/src/core/hle/kernel/k_thread.h index bd125f5f1..9423f08ca 100644 --- a/src/core/hle/kernel/k_thread.h +++ b/src/core/hle/kernel/k_thread.h | |||
| @@ -254,6 +254,8 @@ public: | |||
| 254 | thread_context_32.tpidr = static_cast<u32>(value); | 254 | thread_context_32.tpidr = static_cast<u32>(value); |
| 255 | } | 255 | } |
| 256 | 256 | ||
| 257 | void CloneFpuStatus(); | ||
| 258 | |||
| 257 | [[nodiscard]] ThreadContext32& GetContext32() { | 259 | [[nodiscard]] ThreadContext32& GetContext32() { |
| 258 | return thread_context_32; | 260 | return thread_context_32; |
| 259 | } | 261 | } |
diff --git a/src/core/hle/kernel/svc/svc_synchronization.cpp b/src/core/hle/kernel/svc/svc_synchronization.cpp index 1a8f7e191..9e7bf9530 100644 --- a/src/core/hle/kernel/svc/svc_synchronization.cpp +++ b/src/core/hle/kernel/svc/svc_synchronization.cpp | |||
| @@ -48,19 +48,15 @@ Result ResetSignal(Core::System& system, Handle handle) { | |||
| 48 | return ResultInvalidHandle; | 48 | return ResultInvalidHandle; |
| 49 | } | 49 | } |
| 50 | 50 | ||
| 51 | /// Wait for the given handles to synchronize, timeout after the specified nanoseconds | 51 | static Result WaitSynchronization(Core::System& system, int32_t* out_index, const Handle* handles, |
| 52 | Result WaitSynchronization(Core::System& system, s32* index, VAddr handles_address, s32 num_handles, | 52 | int32_t num_handles, int64_t timeout_ns) { |
| 53 | s64 nano_seconds) { | ||
| 54 | LOG_TRACE(Kernel_SVC, "called handles_address=0x{:X}, num_handles={}, nano_seconds={}", | ||
| 55 | handles_address, num_handles, nano_seconds); | ||
| 56 | |||
| 57 | // Ensure number of handles is valid. | 53 | // Ensure number of handles is valid. |
| 58 | R_UNLESS(0 <= num_handles && num_handles <= ArgumentHandleCountMax, ResultOutOfRange); | 54 | R_UNLESS(0 <= num_handles && num_handles <= Svc::ArgumentHandleCountMax, ResultOutOfRange); |
| 59 | 55 | ||
| 56 | // Get the synchronization context. | ||
| 60 | auto& kernel = system.Kernel(); | 57 | auto& kernel = system.Kernel(); |
| 58 | auto& handle_table = GetCurrentProcess(kernel).GetHandleTable(); | ||
| 61 | std::vector<KSynchronizationObject*> objs(num_handles); | 59 | std::vector<KSynchronizationObject*> objs(num_handles); |
| 62 | const auto& handle_table = GetCurrentProcess(kernel).GetHandleTable(); | ||
| 63 | Handle* handles = system.Memory().GetPointer<Handle>(handles_address); | ||
| 64 | 60 | ||
| 65 | // Copy user handles. | 61 | // Copy user handles. |
| 66 | if (num_handles > 0) { | 62 | if (num_handles > 0) { |
| @@ -68,21 +64,38 @@ Result WaitSynchronization(Core::System& system, s32* index, VAddr handles_addre | |||
| 68 | R_UNLESS(handle_table.GetMultipleObjects<KSynchronizationObject>(objs.data(), handles, | 64 | R_UNLESS(handle_table.GetMultipleObjects<KSynchronizationObject>(objs.data(), handles, |
| 69 | num_handles), | 65 | num_handles), |
| 70 | ResultInvalidHandle); | 66 | ResultInvalidHandle); |
| 71 | for (const auto& obj : objs) { | ||
| 72 | kernel.RegisterInUseObject(obj); | ||
| 73 | } | ||
| 74 | } | 67 | } |
| 75 | 68 | ||
| 76 | // Ensure handles are closed when we're done. | 69 | // Ensure handles are closed when we're done. |
| 77 | SCOPE_EXIT({ | 70 | SCOPE_EXIT({ |
| 78 | for (s32 i = 0; i < num_handles; ++i) { | 71 | for (auto i = 0; i < num_handles; ++i) { |
| 79 | kernel.UnregisterInUseObject(objs[i]); | ||
| 80 | objs[i]->Close(); | 72 | objs[i]->Close(); |
| 81 | } | 73 | } |
| 82 | }); | 74 | }); |
| 83 | 75 | ||
| 84 | return KSynchronizationObject::Wait(kernel, index, objs.data(), static_cast<s32>(objs.size()), | 76 | // Wait on the objects. |
| 85 | nano_seconds); | 77 | Result res = KSynchronizationObject::Wait(kernel, out_index, objs.data(), |
| 78 | static_cast<s32>(objs.size()), timeout_ns); | ||
| 79 | |||
| 80 | R_SUCCEED_IF(res == ResultSessionClosed); | ||
| 81 | R_RETURN(res); | ||
| 82 | } | ||
| 83 | |||
| 84 | /// Wait for the given handles to synchronize, timeout after the specified nanoseconds | ||
| 85 | Result WaitSynchronization(Core::System& system, int32_t* out_index, VAddr user_handles, | ||
| 86 | int32_t num_handles, int64_t timeout_ns) { | ||
| 87 | LOG_TRACE(Kernel_SVC, "called user_handles={:#x}, num_handles={}, timeout_ns={}", user_handles, | ||
| 88 | num_handles, timeout_ns); | ||
| 89 | |||
| 90 | // Ensure number of handles is valid. | ||
| 91 | R_UNLESS(0 <= num_handles && num_handles <= Svc::ArgumentHandleCountMax, ResultOutOfRange); | ||
| 92 | |||
| 93 | std::vector<Handle> handles(num_handles); | ||
| 94 | if (num_handles > 0) { | ||
| 95 | system.Memory().ReadBlock(user_handles, handles.data(), num_handles * sizeof(Handle)); | ||
| 96 | } | ||
| 97 | |||
| 98 | R_RETURN(WaitSynchronization(system, out_index, handles.data(), num_handles, timeout_ns)); | ||
| 86 | } | 99 | } |
| 87 | 100 | ||
| 88 | /// Resumes a thread waiting on WaitSynchronization | 101 | /// Resumes a thread waiting on WaitSynchronization |
diff --git a/src/core/hle/kernel/svc/svc_thread.cpp b/src/core/hle/kernel/svc/svc_thread.cpp index b39807841..9bc1ebe74 100644 --- a/src/core/hle/kernel/svc/svc_thread.cpp +++ b/src/core/hle/kernel/svc/svc_thread.cpp | |||
| @@ -82,6 +82,9 @@ Result CreateThread(Core::System& system, Handle* out_handle, VAddr entry_point, | |||
| 82 | // Commit the thread reservation. | 82 | // Commit the thread reservation. |
| 83 | thread_reservation.Commit(); | 83 | thread_reservation.Commit(); |
| 84 | 84 | ||
| 85 | // Clone the current fpu status to the new thread. | ||
| 86 | thread->CloneFpuStatus(); | ||
| 87 | |||
| 85 | // Register the new thread. | 88 | // Register the new thread. |
| 86 | KThread::Register(kernel, thread); | 89 | KThread::Register(kernel, thread); |
| 87 | 90 | ||
diff --git a/src/core/hle/service/acc/acc.cpp b/src/core/hle/service/acc/acc.cpp index ddc3a6dbe..120282aa4 100644 --- a/src/core/hle/service/acc/acc.cpp +++ b/src/core/hle/service/acc/acc.cpp | |||
| @@ -30,12 +30,6 @@ | |||
| 30 | 30 | ||
| 31 | namespace Service::Account { | 31 | namespace Service::Account { |
| 32 | 32 | ||
| 33 | constexpr Result ERR_INVALID_USER_ID{ErrorModule::Account, 20}; | ||
| 34 | constexpr Result ERR_INVALID_APPLICATION_ID{ErrorModule::Account, 22}; | ||
| 35 | constexpr Result ERR_INVALID_BUFFER{ErrorModule::Account, 30}; | ||
| 36 | constexpr Result ERR_INVALID_BUFFER_SIZE{ErrorModule::Account, 31}; | ||
| 37 | constexpr Result ERR_FAILED_SAVE_DATA{ErrorModule::Account, 100}; | ||
| 38 | |||
| 39 | // Thumbnails are hard coded to be at least this size | 33 | // Thumbnails are hard coded to be at least this size |
| 40 | constexpr std::size_t THUMBNAIL_SIZE = 0x24000; | 34 | constexpr std::size_t THUMBNAIL_SIZE = 0x24000; |
| 41 | 35 | ||
| @@ -384,7 +378,7 @@ protected: | |||
| 384 | if (user_data.size() < sizeof(UserData)) { | 378 | if (user_data.size() < sizeof(UserData)) { |
| 385 | LOG_ERROR(Service_ACC, "UserData buffer too small!"); | 379 | LOG_ERROR(Service_ACC, "UserData buffer too small!"); |
| 386 | IPC::ResponseBuilder rb{ctx, 2}; | 380 | IPC::ResponseBuilder rb{ctx, 2}; |
| 387 | rb.Push(ERR_INVALID_BUFFER); | 381 | rb.Push(Account::ResultInvalidArrayLength); |
| 388 | return; | 382 | return; |
| 389 | } | 383 | } |
| 390 | 384 | ||
| @@ -394,7 +388,7 @@ protected: | |||
| 394 | if (!profile_manager.SetProfileBaseAndData(user_id, base, data)) { | 388 | if (!profile_manager.SetProfileBaseAndData(user_id, base, data)) { |
| 395 | LOG_ERROR(Service_ACC, "Failed to update user data and base!"); | 389 | LOG_ERROR(Service_ACC, "Failed to update user data and base!"); |
| 396 | IPC::ResponseBuilder rb{ctx, 2}; | 390 | IPC::ResponseBuilder rb{ctx, 2}; |
| 397 | rb.Push(ERR_FAILED_SAVE_DATA); | 391 | rb.Push(Account::ResultAccountUpdateFailed); |
| 398 | return; | 392 | return; |
| 399 | } | 393 | } |
| 400 | 394 | ||
| @@ -417,7 +411,7 @@ protected: | |||
| 417 | if (user_data.size() < sizeof(UserData)) { | 411 | if (user_data.size() < sizeof(UserData)) { |
| 418 | LOG_ERROR(Service_ACC, "UserData buffer too small!"); | 412 | LOG_ERROR(Service_ACC, "UserData buffer too small!"); |
| 419 | IPC::ResponseBuilder rb{ctx, 2}; | 413 | IPC::ResponseBuilder rb{ctx, 2}; |
| 420 | rb.Push(ERR_INVALID_BUFFER); | 414 | rb.Push(Account::ResultInvalidArrayLength); |
| 421 | return; | 415 | return; |
| 422 | } | 416 | } |
| 423 | 417 | ||
| @@ -432,7 +426,7 @@ protected: | |||
| 432 | !profile_manager.SetProfileBaseAndData(user_id, base, data)) { | 426 | !profile_manager.SetProfileBaseAndData(user_id, base, data)) { |
| 433 | LOG_ERROR(Service_ACC, "Failed to update profile data, base, and image!"); | 427 | LOG_ERROR(Service_ACC, "Failed to update profile data, base, and image!"); |
| 434 | IPC::ResponseBuilder rb{ctx, 2}; | 428 | IPC::ResponseBuilder rb{ctx, 2}; |
| 435 | rb.Push(ERR_FAILED_SAVE_DATA); | 429 | rb.Push(Account::ResultAccountUpdateFailed); |
| 436 | return; | 430 | return; |
| 437 | } | 431 | } |
| 438 | 432 | ||
| @@ -764,7 +758,7 @@ void Module::Interface::InitializeApplicationInfoRestricted(HLERequestContext& c | |||
| 764 | Result Module::Interface::InitializeApplicationInfoBase() { | 758 | Result Module::Interface::InitializeApplicationInfoBase() { |
| 765 | if (application_info) { | 759 | if (application_info) { |
| 766 | LOG_ERROR(Service_ACC, "Application already initialized"); | 760 | LOG_ERROR(Service_ACC, "Application already initialized"); |
| 767 | return ERR_ACCOUNTINFO_ALREADY_INITIALIZED; | 761 | return Account::ResultApplicationInfoAlreadyInitialized; |
| 768 | } | 762 | } |
| 769 | 763 | ||
| 770 | // TODO(ogniK): This should be changed to reflect the target process for when we have multiple | 764 | // TODO(ogniK): This should be changed to reflect the target process for when we have multiple |
| @@ -775,7 +769,7 @@ Result Module::Interface::InitializeApplicationInfoBase() { | |||
| 775 | 769 | ||
| 776 | if (launch_property.Failed()) { | 770 | if (launch_property.Failed()) { |
| 777 | LOG_ERROR(Service_ACC, "Failed to get launch property"); | 771 | LOG_ERROR(Service_ACC, "Failed to get launch property"); |
| 778 | return ERR_ACCOUNTINFO_BAD_APPLICATION; | 772 | return Account::ResultInvalidApplication; |
| 779 | } | 773 | } |
| 780 | 774 | ||
| 781 | switch (launch_property->base_game_storage_id) { | 775 | switch (launch_property->base_game_storage_id) { |
| @@ -791,7 +785,7 @@ Result Module::Interface::InitializeApplicationInfoBase() { | |||
| 791 | default: | 785 | default: |
| 792 | LOG_ERROR(Service_ACC, "Invalid game storage ID! storage_id={}", | 786 | LOG_ERROR(Service_ACC, "Invalid game storage ID! storage_id={}", |
| 793 | launch_property->base_game_storage_id); | 787 | launch_property->base_game_storage_id); |
| 794 | return ERR_ACCOUNTINFO_BAD_APPLICATION; | 788 | return Account::ResultInvalidApplication; |
| 795 | } | 789 | } |
| 796 | 790 | ||
| 797 | LOG_WARNING(Service_ACC, "ApplicationInfo init required"); | 791 | LOG_WARNING(Service_ACC, "ApplicationInfo init required"); |
| @@ -899,20 +893,20 @@ void Module::Interface::StoreSaveDataThumbnail(HLERequestContext& ctx, const Com | |||
| 899 | 893 | ||
| 900 | if (tid == 0) { | 894 | if (tid == 0) { |
| 901 | LOG_ERROR(Service_ACC, "TitleID is not valid!"); | 895 | LOG_ERROR(Service_ACC, "TitleID is not valid!"); |
| 902 | rb.Push(ERR_INVALID_APPLICATION_ID); | 896 | rb.Push(Account::ResultInvalidApplication); |
| 903 | return; | 897 | return; |
| 904 | } | 898 | } |
| 905 | 899 | ||
| 906 | if (uuid.IsInvalid()) { | 900 | if (uuid.IsInvalid()) { |
| 907 | LOG_ERROR(Service_ACC, "User ID is not valid!"); | 901 | LOG_ERROR(Service_ACC, "User ID is not valid!"); |
| 908 | rb.Push(ERR_INVALID_USER_ID); | 902 | rb.Push(Account::ResultInvalidUserId); |
| 909 | return; | 903 | return; |
| 910 | } | 904 | } |
| 911 | const auto thumbnail_size = ctx.GetReadBufferSize(); | 905 | const auto thumbnail_size = ctx.GetReadBufferSize(); |
| 912 | if (thumbnail_size != THUMBNAIL_SIZE) { | 906 | if (thumbnail_size != THUMBNAIL_SIZE) { |
| 913 | LOG_ERROR(Service_ACC, "Buffer size is empty! size={:X} expecting {:X}", thumbnail_size, | 907 | LOG_ERROR(Service_ACC, "Buffer size is empty! size={:X} expecting {:X}", thumbnail_size, |
| 914 | THUMBNAIL_SIZE); | 908 | THUMBNAIL_SIZE); |
| 915 | rb.Push(ERR_INVALID_BUFFER_SIZE); | 909 | rb.Push(Account::ResultInvalidArrayLength); |
| 916 | return; | 910 | return; |
| 917 | } | 911 | } |
| 918 | 912 | ||
diff --git a/src/core/hle/service/acc/errors.h b/src/core/hle/service/acc/errors.h index e9c16b951..433ebfe9d 100644 --- a/src/core/hle/service/acc/errors.h +++ b/src/core/hle/service/acc/errors.h | |||
| @@ -7,7 +7,13 @@ | |||
| 7 | 7 | ||
| 8 | namespace Service::Account { | 8 | namespace Service::Account { |
| 9 | 9 | ||
| 10 | constexpr Result ERR_ACCOUNTINFO_BAD_APPLICATION{ErrorModule::Account, 22}; | 10 | constexpr Result ResultCancelledByUser{ErrorModule::Account, 1}; |
| 11 | constexpr Result ERR_ACCOUNTINFO_ALREADY_INITIALIZED{ErrorModule::Account, 41}; | 11 | constexpr Result ResultNoNotifications{ErrorModule::Account, 15}; |
| 12 | constexpr Result ResultInvalidUserId{ErrorModule::Account, 20}; | ||
| 13 | constexpr Result ResultInvalidApplication{ErrorModule::Account, 22}; | ||
| 14 | constexpr Result ResultNullptr{ErrorModule::Account, 30}; | ||
| 15 | constexpr Result ResultInvalidArrayLength{ErrorModule::Account, 32}; | ||
| 16 | constexpr Result ResultApplicationInfoAlreadyInitialized{ErrorModule::Account, 41}; | ||
| 17 | constexpr Result ResultAccountUpdateFailed{ErrorModule::Account, 100}; | ||
| 12 | 18 | ||
| 13 | } // namespace Service::Account | 19 | } // namespace Service::Account |
diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp index f74c7b550..f17df5124 100644 --- a/src/core/hle/service/am/am.cpp +++ b/src/core/hle/service/am/am.cpp | |||
| @@ -39,9 +39,9 @@ | |||
| 39 | 39 | ||
| 40 | namespace Service::AM { | 40 | namespace Service::AM { |
| 41 | 41 | ||
| 42 | constexpr Result ERR_NO_DATA_IN_CHANNEL{ErrorModule::AM, 2}; | 42 | constexpr Result ResultNoDataInChannel{ErrorModule::AM, 2}; |
| 43 | constexpr Result ERR_NO_MESSAGES{ErrorModule::AM, 3}; | 43 | constexpr Result ResultNoMessages{ErrorModule::AM, 3}; |
| 44 | constexpr Result ERR_SIZE_OUT_OF_BOUNDS{ErrorModule::AM, 503}; | 44 | constexpr Result ResultInvalidOffset{ErrorModule::AM, 503}; |
| 45 | 45 | ||
| 46 | enum class LaunchParameterKind : u32 { | 46 | enum class LaunchParameterKind : u32 { |
| 47 | ApplicationSpecific = 1, | 47 | ApplicationSpecific = 1, |
| @@ -758,7 +758,7 @@ void ICommonStateGetter::ReceiveMessage(HLERequestContext& ctx) { | |||
| 758 | 758 | ||
| 759 | if (message == AppletMessageQueue::AppletMessage::None) { | 759 | if (message == AppletMessageQueue::AppletMessage::None) { |
| 760 | LOG_ERROR(Service_AM, "Message queue is empty"); | 760 | LOG_ERROR(Service_AM, "Message queue is empty"); |
| 761 | rb.Push(ERR_NO_MESSAGES); | 761 | rb.Push(AM::ResultNoMessages); |
| 762 | rb.PushEnum<AppletMessageQueue::AppletMessage>(message); | 762 | rb.PushEnum<AppletMessageQueue::AppletMessage>(message); |
| 763 | return; | 763 | return; |
| 764 | } | 764 | } |
| @@ -1028,7 +1028,7 @@ private: | |||
| 1028 | LOG_DEBUG(Service_AM, | 1028 | LOG_DEBUG(Service_AM, |
| 1029 | "storage is a nullptr. There is no data in the current normal channel"); | 1029 | "storage is a nullptr. There is no data in the current normal channel"); |
| 1030 | IPC::ResponseBuilder rb{ctx, 2}; | 1030 | IPC::ResponseBuilder rb{ctx, 2}; |
| 1031 | rb.Push(ERR_NO_DATA_IN_CHANNEL); | 1031 | rb.Push(AM::ResultNoDataInChannel); |
| 1032 | return; | 1032 | return; |
| 1033 | } | 1033 | } |
| 1034 | 1034 | ||
| @@ -1059,7 +1059,7 @@ private: | |||
| 1059 | LOG_DEBUG(Service_AM, | 1059 | LOG_DEBUG(Service_AM, |
| 1060 | "storage is a nullptr. There is no data in the current interactive channel"); | 1060 | "storage is a nullptr. There is no data in the current interactive channel"); |
| 1061 | IPC::ResponseBuilder rb{ctx, 2}; | 1061 | IPC::ResponseBuilder rb{ctx, 2}; |
| 1062 | rb.Push(ERR_NO_DATA_IN_CHANNEL); | 1062 | rb.Push(AM::ResultNoDataInChannel); |
| 1063 | return; | 1063 | return; |
| 1064 | } | 1064 | } |
| 1065 | 1065 | ||
| @@ -1138,7 +1138,7 @@ void IStorageAccessor::Write(HLERequestContext& ctx) { | |||
| 1138 | backing.GetSize(), size, offset); | 1138 | backing.GetSize(), size, offset); |
| 1139 | 1139 | ||
| 1140 | IPC::ResponseBuilder rb{ctx, 2}; | 1140 | IPC::ResponseBuilder rb{ctx, 2}; |
| 1141 | rb.Push(ERR_SIZE_OUT_OF_BOUNDS); | 1141 | rb.Push(AM::ResultInvalidOffset); |
| 1142 | return; | 1142 | return; |
| 1143 | } | 1143 | } |
| 1144 | 1144 | ||
| @@ -1161,7 +1161,7 @@ void IStorageAccessor::Read(HLERequestContext& ctx) { | |||
| 1161 | backing.GetSize(), size, offset); | 1161 | backing.GetSize(), size, offset); |
| 1162 | 1162 | ||
| 1163 | IPC::ResponseBuilder rb{ctx, 2}; | 1163 | IPC::ResponseBuilder rb{ctx, 2}; |
| 1164 | rb.Push(ERR_SIZE_OUT_OF_BOUNDS); | 1164 | rb.Push(AM::ResultInvalidOffset); |
| 1165 | return; | 1165 | return; |
| 1166 | } | 1166 | } |
| 1167 | 1167 | ||
| @@ -1502,7 +1502,7 @@ void IApplicationFunctions::PopLaunchParameter(HLERequestContext& ctx) { | |||
| 1502 | 1502 | ||
| 1503 | LOG_ERROR(Service_AM, "Attempted to load launch parameter but none was found!"); | 1503 | LOG_ERROR(Service_AM, "Attempted to load launch parameter but none was found!"); |
| 1504 | IPC::ResponseBuilder rb{ctx, 2}; | 1504 | IPC::ResponseBuilder rb{ctx, 2}; |
| 1505 | rb.Push(ERR_NO_DATA_IN_CHANNEL); | 1505 | rb.Push(AM::ResultNoDataInChannel); |
| 1506 | } | 1506 | } |
| 1507 | 1507 | ||
| 1508 | void IApplicationFunctions::CreateApplicationAndRequestToStartForQuest(HLERequestContext& ctx) { | 1508 | void IApplicationFunctions::CreateApplicationAndRequestToStartForQuest(HLERequestContext& ctx) { |
| @@ -1799,7 +1799,7 @@ void IApplicationFunctions::TryPopFromFriendInvitationStorageChannel(HLERequestC | |||
| 1799 | LOG_WARNING(Service_AM, "(STUBBED) called"); | 1799 | LOG_WARNING(Service_AM, "(STUBBED) called"); |
| 1800 | 1800 | ||
| 1801 | IPC::ResponseBuilder rb{ctx, 2}; | 1801 | IPC::ResponseBuilder rb{ctx, 2}; |
| 1802 | rb.Push(ERR_NO_DATA_IN_CHANNEL); | 1802 | rb.Push(AM::ResultNoDataInChannel); |
| 1803 | } | 1803 | } |
| 1804 | 1804 | ||
| 1805 | void IApplicationFunctions::GetNotificationStorageChannelEvent(HLERequestContext& ctx) { | 1805 | void IApplicationFunctions::GetNotificationStorageChannelEvent(HLERequestContext& ctx) { |
diff --git a/src/core/hle/service/am/applets/applet_cabinet.cpp b/src/core/hle/service/am/applets/applet_cabinet.cpp index d0969b0f1..162687b29 100644 --- a/src/core/hle/service/am/applets/applet_cabinet.cpp +++ b/src/core/hle/service/am/applets/applet_cabinet.cpp | |||
| @@ -119,7 +119,7 @@ void Cabinet::DisplayCompleted(bool apply_changes, std::string_view amiibo_name) | |||
| 119 | case Service::NFP::CabinetMode::StartNicknameAndOwnerSettings: { | 119 | case Service::NFP::CabinetMode::StartNicknameAndOwnerSettings: { |
| 120 | Service::NFP::AmiiboName name{}; | 120 | Service::NFP::AmiiboName name{}; |
| 121 | std::memcpy(name.data(), amiibo_name.data(), std::min(amiibo_name.size(), name.size() - 1)); | 121 | std::memcpy(name.data(), amiibo_name.data(), std::min(amiibo_name.size(), name.size() - 1)); |
| 122 | nfp_device->SetNicknameAndOwner(name); | 122 | nfp_device->SetRegisterInfoPrivate(name); |
| 123 | break; | 123 | break; |
| 124 | } | 124 | } |
| 125 | case Service::NFP::CabinetMode::StartGameDataEraser: | 125 | case Service::NFP::CabinetMode::StartGameDataEraser: |
| @@ -129,7 +129,7 @@ void Cabinet::DisplayCompleted(bool apply_changes, std::string_view amiibo_name) | |||
| 129 | nfp_device->RestoreAmiibo(); | 129 | nfp_device->RestoreAmiibo(); |
| 130 | break; | 130 | break; |
| 131 | case Service::NFP::CabinetMode::StartFormatter: | 131 | case Service::NFP::CabinetMode::StartFormatter: |
| 132 | nfp_device->DeleteAllData(); | 132 | nfp_device->Format(); |
| 133 | break; | 133 | break; |
| 134 | default: | 134 | default: |
| 135 | UNIMPLEMENTED_MSG("Unknown CabinetMode={}", applet_input_common.applet_mode); | 135 | UNIMPLEMENTED_MSG("Unknown CabinetMode={}", applet_input_common.applet_mode); |
diff --git a/src/core/hle/service/am/applets/applet_controller.cpp b/src/core/hle/service/am/applets/applet_controller.cpp index b418031de..58484519b 100644 --- a/src/core/hle/service/am/applets/applet_controller.cpp +++ b/src/core/hle/service/am/applets/applet_controller.cpp | |||
| @@ -19,10 +19,9 @@ | |||
| 19 | 19 | ||
| 20 | namespace Service::AM::Applets { | 20 | namespace Service::AM::Applets { |
| 21 | 21 | ||
| 22 | // This error code (0x183ACA) is thrown when the applet fails to initialize. | 22 | [[maybe_unused]] constexpr Result ResultControllerSupportCanceled{ErrorModule::HID, 3101}; |
| 23 | [[maybe_unused]] constexpr Result ERR_CONTROLLER_APPLET_3101{ErrorModule::HID, 3101}; | 23 | [[maybe_unused]] constexpr Result ResultControllerSupportNotSupportedNpadStyle{ErrorModule::HID, |
| 24 | // This error code (0x183CCA) is thrown when the u32 result in ControllerSupportResultInfo is 2. | 24 | 3102}; |
| 25 | [[maybe_unused]] constexpr Result ERR_CONTROLLER_APPLET_3102{ErrorModule::HID, 3102}; | ||
| 26 | 25 | ||
| 27 | static Core::Frontend::ControllerParameters ConvertToFrontendParameters( | 26 | static Core::Frontend::ControllerParameters ConvertToFrontendParameters( |
| 28 | ControllerSupportArgPrivate private_arg, ControllerSupportArgHeader header, bool enable_text, | 27 | ControllerSupportArgPrivate private_arg, ControllerSupportArgHeader header, bool enable_text, |
diff --git a/src/core/hle/service/am/applets/applet_profile_select.cpp b/src/core/hle/service/am/applets/applet_profile_select.cpp index c738db028..1d69f5447 100644 --- a/src/core/hle/service/am/applets/applet_profile_select.cpp +++ b/src/core/hle/service/am/applets/applet_profile_select.cpp | |||
| @@ -7,13 +7,12 @@ | |||
| 7 | #include "common/string_util.h" | 7 | #include "common/string_util.h" |
| 8 | #include "core/core.h" | 8 | #include "core/core.h" |
| 9 | #include "core/frontend/applets/profile_select.h" | 9 | #include "core/frontend/applets/profile_select.h" |
| 10 | #include "core/hle/service/acc/errors.h" | ||
| 10 | #include "core/hle/service/am/am.h" | 11 | #include "core/hle/service/am/am.h" |
| 11 | #include "core/hle/service/am/applets/applet_profile_select.h" | 12 | #include "core/hle/service/am/applets/applet_profile_select.h" |
| 12 | 13 | ||
| 13 | namespace Service::AM::Applets { | 14 | namespace Service::AM::Applets { |
| 14 | 15 | ||
| 15 | constexpr Result ERR_USER_CANCELLED_SELECTION{ErrorModule::Account, 1}; | ||
| 16 | |||
| 17 | ProfileSelect::ProfileSelect(Core::System& system_, LibraryAppletMode applet_mode_, | 16 | ProfileSelect::ProfileSelect(Core::System& system_, LibraryAppletMode applet_mode_, |
| 18 | const Core::Frontend::ProfileSelectApplet& frontend_) | 17 | const Core::Frontend::ProfileSelectApplet& frontend_) |
| 19 | : Applet{system_, applet_mode_}, frontend{frontend_}, system{system_} {} | 18 | : Applet{system_, applet_mode_}, frontend{frontend_}, system{system_} {} |
| @@ -63,8 +62,8 @@ void ProfileSelect::SelectionComplete(std::optional<Common::UUID> uuid) { | |||
| 63 | output.result = 0; | 62 | output.result = 0; |
| 64 | output.uuid_selected = *uuid; | 63 | output.uuid_selected = *uuid; |
| 65 | } else { | 64 | } else { |
| 66 | status = ERR_USER_CANCELLED_SELECTION; | 65 | status = Account::ResultCancelledByUser; |
| 67 | output.result = ERR_USER_CANCELLED_SELECTION.raw; | 66 | output.result = Account::ResultCancelledByUser.raw; |
| 68 | output.uuid_selected = Common::InvalidUUID; | 67 | output.uuid_selected = Common::InvalidUUID; |
| 69 | } | 68 | } |
| 70 | 69 | ||
diff --git a/src/core/hle/service/audio/audren_u.cpp b/src/core/hle/service/audio/audren_u.cpp index 0a6830ffa..7086d4750 100644 --- a/src/core/hle/service/audio/audren_u.cpp +++ b/src/core/hle/service/audio/audren_u.cpp | |||
| @@ -170,7 +170,7 @@ private: | |||
| 170 | 170 | ||
| 171 | if (impl->GetSystem().GetExecutionMode() == AudioCore::ExecutionMode::Manual) { | 171 | if (impl->GetSystem().GetExecutionMode() == AudioCore::ExecutionMode::Manual) { |
| 172 | IPC::ResponseBuilder rb{ctx, 2}; | 172 | IPC::ResponseBuilder rb{ctx, 2}; |
| 173 | rb.Push(ERR_NOT_SUPPORTED); | 173 | rb.Push(Audio::ResultNotSupported); |
| 174 | return; | 174 | return; |
| 175 | } | 175 | } |
| 176 | 176 | ||
| @@ -448,7 +448,7 @@ void AudRenU::OpenAudioRenderer(HLERequestContext& ctx) { | |||
| 448 | if (impl->GetSessionCount() + 1 > AudioCore::MaxRendererSessions) { | 448 | if (impl->GetSessionCount() + 1 > AudioCore::MaxRendererSessions) { |
| 449 | LOG_ERROR(Service_Audio, "Too many AudioRenderer sessions open!"); | 449 | LOG_ERROR(Service_Audio, "Too many AudioRenderer sessions open!"); |
| 450 | IPC::ResponseBuilder rb{ctx, 2}; | 450 | IPC::ResponseBuilder rb{ctx, 2}; |
| 451 | rb.Push(ERR_MAXIMUM_SESSIONS_REACHED); | 451 | rb.Push(Audio::ResultOutOfSessions); |
| 452 | return; | 452 | return; |
| 453 | } | 453 | } |
| 454 | 454 | ||
| @@ -461,7 +461,7 @@ void AudRenU::OpenAudioRenderer(HLERequestContext& ctx) { | |||
| 461 | if (session_id == -1) { | 461 | if (session_id == -1) { |
| 462 | LOG_ERROR(Service_Audio, "Tried to open a session that's already in use!"); | 462 | LOG_ERROR(Service_Audio, "Tried to open a session that's already in use!"); |
| 463 | IPC::ResponseBuilder rb{ctx, 2}; | 463 | IPC::ResponseBuilder rb{ctx, 2}; |
| 464 | rb.Push(ERR_MAXIMUM_SESSIONS_REACHED); | 464 | rb.Push(Audio::ResultOutOfSessions); |
| 465 | return; | 465 | return; |
| 466 | } | 466 | } |
| 467 | 467 | ||
diff --git a/src/core/hle/service/audio/errors.h b/src/core/hle/service/audio/errors.h index d706978cb..3d3d3d97a 100644 --- a/src/core/hle/service/audio/errors.h +++ b/src/core/hle/service/audio/errors.h | |||
| @@ -7,17 +7,17 @@ | |||
| 7 | 7 | ||
| 8 | namespace Service::Audio { | 8 | namespace Service::Audio { |
| 9 | 9 | ||
| 10 | constexpr Result ERR_INVALID_DEVICE_NAME{ErrorModule::Audio, 1}; | 10 | constexpr Result ResultNotFound{ErrorModule::Audio, 1}; |
| 11 | constexpr Result ERR_OPERATION_FAILED{ErrorModule::Audio, 2}; | 11 | constexpr Result ResultOperationFailed{ErrorModule::Audio, 2}; |
| 12 | constexpr Result ERR_INVALID_SAMPLE_RATE{ErrorModule::Audio, 3}; | 12 | constexpr Result ResultInvalidSampleRate{ErrorModule::Audio, 3}; |
| 13 | constexpr Result ERR_INSUFFICIENT_BUFFER_SIZE{ErrorModule::Audio, 4}; | 13 | constexpr Result ResultInsufficientBuffer{ErrorModule::Audio, 4}; |
| 14 | constexpr Result ERR_MAXIMUM_SESSIONS_REACHED{ErrorModule::Audio, 5}; | 14 | constexpr Result ResultOutOfSessions{ErrorModule::Audio, 5}; |
| 15 | constexpr Result ERR_BUFFER_COUNT_EXCEEDED{ErrorModule::Audio, 8}; | 15 | constexpr Result ResultBufferCountReached{ErrorModule::Audio, 8}; |
| 16 | constexpr Result ERR_INVALID_CHANNEL_COUNT{ErrorModule::Audio, 10}; | 16 | constexpr Result ResultInvalidChannelCount{ErrorModule::Audio, 10}; |
| 17 | constexpr Result ERR_INVALID_UPDATE_DATA{ErrorModule::Audio, 41}; | 17 | constexpr Result ResultInvalidUpdateInfo{ErrorModule::Audio, 41}; |
| 18 | constexpr Result ERR_POOL_MAPPING_FAILED{ErrorModule::Audio, 42}; | 18 | constexpr Result ResultInvalidAddressInfo{ErrorModule::Audio, 42}; |
| 19 | constexpr Result ERR_NOT_SUPPORTED{ErrorModule::Audio, 513}; | 19 | constexpr Result ResultNotSupported{ErrorModule::Audio, 513}; |
| 20 | constexpr Result ERR_INVALID_PROCESS_HANDLE{ErrorModule::Audio, 1536}; | 20 | constexpr Result ResultInvalidHandle{ErrorModule::Audio, 1536}; |
| 21 | constexpr Result ERR_INVALID_REVISION{ErrorModule::Audio, 1537}; | 21 | constexpr Result ResultInvalidRevision{ErrorModule::Audio, 1537}; |
| 22 | 22 | ||
| 23 | } // namespace Service::Audio | 23 | } // namespace Service::Audio |
diff --git a/src/core/hle/service/friend/errors.h b/src/core/hle/service/friend/errors.h deleted file mode 100644 index ff525d865..000000000 --- a/src/core/hle/service/friend/errors.h +++ /dev/null | |||
| @@ -1,11 +0,0 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include "core/hle/result.h" | ||
| 7 | |||
| 8 | namespace Service::Friend { | ||
| 9 | |||
| 10 | constexpr Result ERR_NO_NOTIFICATIONS{ErrorModule::Account, 15}; | ||
| 11 | } | ||
diff --git a/src/core/hle/service/friend/friend.cpp b/src/core/hle/service/friend/friend.cpp index 447deab8b..9d05f9801 100644 --- a/src/core/hle/service/friend/friend.cpp +++ b/src/core/hle/service/friend/friend.cpp | |||
| @@ -6,7 +6,7 @@ | |||
| 6 | #include "common/uuid.h" | 6 | #include "common/uuid.h" |
| 7 | #include "core/core.h" | 7 | #include "core/core.h" |
| 8 | #include "core/hle/kernel/k_event.h" | 8 | #include "core/hle/kernel/k_event.h" |
| 9 | #include "core/hle/service/friend/errors.h" | 9 | #include "core/hle/service/acc/errors.h" |
| 10 | #include "core/hle/service/friend/friend.h" | 10 | #include "core/hle/service/friend/friend.h" |
| 11 | #include "core/hle/service/friend/friend_interface.h" | 11 | #include "core/hle/service/friend/friend_interface.h" |
| 12 | #include "core/hle/service/ipc_helpers.h" | 12 | #include "core/hle/service/ipc_helpers.h" |
| @@ -259,7 +259,7 @@ private: | |||
| 259 | if (notifications.empty()) { | 259 | if (notifications.empty()) { |
| 260 | LOG_ERROR(Service_Friend, "No notifications in queue!"); | 260 | LOG_ERROR(Service_Friend, "No notifications in queue!"); |
| 261 | IPC::ResponseBuilder rb{ctx, 2}; | 261 | IPC::ResponseBuilder rb{ctx, 2}; |
| 262 | rb.Push(ERR_NO_NOTIFICATIONS); | 262 | rb.Push(Account::ResultNoNotifications); |
| 263 | return; | 263 | return; |
| 264 | } | 264 | } |
| 265 | 265 | ||
diff --git a/src/core/hle/service/glue/arp.cpp b/src/core/hle/service/glue/arp.cpp index 9db136bac..929dcca0d 100644 --- a/src/core/hle/service/glue/arp.cpp +++ b/src/core/hle/service/glue/arp.cpp | |||
| @@ -61,7 +61,7 @@ void ARP_R::GetApplicationLaunchProperty(HLERequestContext& ctx) { | |||
| 61 | if (!title_id.has_value()) { | 61 | if (!title_id.has_value()) { |
| 62 | LOG_ERROR(Service_ARP, "Failed to get title ID for process ID!"); | 62 | LOG_ERROR(Service_ARP, "Failed to get title ID for process ID!"); |
| 63 | IPC::ResponseBuilder rb{ctx, 2}; | 63 | IPC::ResponseBuilder rb{ctx, 2}; |
| 64 | rb.Push(ERR_NOT_REGISTERED); | 64 | rb.Push(Glue::ResultProcessIdNotRegistered); |
| 65 | return; | 65 | return; |
| 66 | } | 66 | } |
| 67 | 67 | ||
| @@ -109,7 +109,7 @@ void ARP_R::GetApplicationControlProperty(HLERequestContext& ctx) { | |||
| 109 | if (!title_id.has_value()) { | 109 | if (!title_id.has_value()) { |
| 110 | LOG_ERROR(Service_ARP, "Failed to get title ID for process ID!"); | 110 | LOG_ERROR(Service_ARP, "Failed to get title ID for process ID!"); |
| 111 | IPC::ResponseBuilder rb{ctx, 2}; | 111 | IPC::ResponseBuilder rb{ctx, 2}; |
| 112 | rb.Push(ERR_NOT_REGISTERED); | 112 | rb.Push(Glue::ResultProcessIdNotRegistered); |
| 113 | return; | 113 | return; |
| 114 | } | 114 | } |
| 115 | 115 | ||
| @@ -178,7 +178,7 @@ private: | |||
| 178 | if (process_id == 0) { | 178 | if (process_id == 0) { |
| 179 | LOG_ERROR(Service_ARP, "Must have non-zero process ID!"); | 179 | LOG_ERROR(Service_ARP, "Must have non-zero process ID!"); |
| 180 | IPC::ResponseBuilder rb{ctx, 2}; | 180 | IPC::ResponseBuilder rb{ctx, 2}; |
| 181 | rb.Push(ERR_INVALID_PROCESS_ID); | 181 | rb.Push(Glue::ResultInvalidProcessId); |
| 182 | return; | 182 | return; |
| 183 | } | 183 | } |
| 184 | 184 | ||
| @@ -186,7 +186,7 @@ private: | |||
| 186 | LOG_ERROR(Service_ARP, | 186 | LOG_ERROR(Service_ARP, |
| 187 | "Attempted to issue registrar, but registrar is already issued!"); | 187 | "Attempted to issue registrar, but registrar is already issued!"); |
| 188 | IPC::ResponseBuilder rb{ctx, 2}; | 188 | IPC::ResponseBuilder rb{ctx, 2}; |
| 189 | rb.Push(ERR_INVALID_ACCESS); | 189 | rb.Push(Glue::ResultAlreadyBound); |
| 190 | return; | 190 | return; |
| 191 | } | 191 | } |
| 192 | 192 | ||
| @@ -205,7 +205,7 @@ private: | |||
| 205 | Service_ARP, | 205 | Service_ARP, |
| 206 | "Attempted to set application launch property, but registrar is already issued!"); | 206 | "Attempted to set application launch property, but registrar is already issued!"); |
| 207 | IPC::ResponseBuilder rb{ctx, 2}; | 207 | IPC::ResponseBuilder rb{ctx, 2}; |
| 208 | rb.Push(ERR_INVALID_ACCESS); | 208 | rb.Push(Glue::ResultAlreadyBound); |
| 209 | return; | 209 | return; |
| 210 | } | 210 | } |
| 211 | 211 | ||
| @@ -224,7 +224,7 @@ private: | |||
| 224 | Service_ARP, | 224 | Service_ARP, |
| 225 | "Attempted to set application control property, but registrar is already issued!"); | 225 | "Attempted to set application control property, but registrar is already issued!"); |
| 226 | IPC::ResponseBuilder rb{ctx, 2}; | 226 | IPC::ResponseBuilder rb{ctx, 2}; |
| 227 | rb.Push(ERR_INVALID_ACCESS); | 227 | rb.Push(Glue::ResultAlreadyBound); |
| 228 | return; | 228 | return; |
| 229 | } | 229 | } |
| 230 | 230 | ||
| @@ -263,7 +263,7 @@ void ARP_W::AcquireRegistrar(HLERequestContext& ctx) { | |||
| 263 | system, [this](u64 process_id, ApplicationLaunchProperty launch, std::vector<u8> control) { | 263 | system, [this](u64 process_id, ApplicationLaunchProperty launch, std::vector<u8> control) { |
| 264 | const auto res = GetTitleIDForProcessID(system, process_id); | 264 | const auto res = GetTitleIDForProcessID(system, process_id); |
| 265 | if (!res.has_value()) { | 265 | if (!res.has_value()) { |
| 266 | return ERR_NOT_REGISTERED; | 266 | return Glue::ResultProcessIdNotRegistered; |
| 267 | } | 267 | } |
| 268 | 268 | ||
| 269 | return manager.Register(*res, launch, std::move(control)); | 269 | return manager.Register(*res, launch, std::move(control)); |
| @@ -283,7 +283,7 @@ void ARP_W::UnregisterApplicationInstance(HLERequestContext& ctx) { | |||
| 283 | if (process_id == 0) { | 283 | if (process_id == 0) { |
| 284 | LOG_ERROR(Service_ARP, "Must have non-zero process ID!"); | 284 | LOG_ERROR(Service_ARP, "Must have non-zero process ID!"); |
| 285 | IPC::ResponseBuilder rb{ctx, 2}; | 285 | IPC::ResponseBuilder rb{ctx, 2}; |
| 286 | rb.Push(ERR_INVALID_PROCESS_ID); | 286 | rb.Push(Glue::ResultInvalidProcessId); |
| 287 | return; | 287 | return; |
| 288 | } | 288 | } |
| 289 | 289 | ||
| @@ -292,7 +292,7 @@ void ARP_W::UnregisterApplicationInstance(HLERequestContext& ctx) { | |||
| 292 | if (!title_id.has_value()) { | 292 | if (!title_id.has_value()) { |
| 293 | LOG_ERROR(Service_ARP, "No title ID for process ID!"); | 293 | LOG_ERROR(Service_ARP, "No title ID for process ID!"); |
| 294 | IPC::ResponseBuilder rb{ctx, 2}; | 294 | IPC::ResponseBuilder rb{ctx, 2}; |
| 295 | rb.Push(ERR_NOT_REGISTERED); | 295 | rb.Push(Glue::ResultProcessIdNotRegistered); |
| 296 | return; | 296 | return; |
| 297 | } | 297 | } |
| 298 | 298 | ||
diff --git a/src/core/hle/service/glue/errors.h b/src/core/hle/service/glue/errors.h index d4ce7f44e..30feaa5c0 100644 --- a/src/core/hle/service/glue/errors.h +++ b/src/core/hle/service/glue/errors.h | |||
| @@ -7,9 +7,8 @@ | |||
| 7 | 7 | ||
| 8 | namespace Service::Glue { | 8 | namespace Service::Glue { |
| 9 | 9 | ||
| 10 | constexpr Result ERR_INVALID_RESOURCE{ErrorModule::ARP, 30}; | 10 | constexpr Result ResultInvalidProcessId{ErrorModule::ARP, 31}; |
| 11 | constexpr Result ERR_INVALID_PROCESS_ID{ErrorModule::ARP, 31}; | 11 | constexpr Result ResultAlreadyBound{ErrorModule::ARP, 42}; |
| 12 | constexpr Result ERR_INVALID_ACCESS{ErrorModule::ARP, 42}; | 12 | constexpr Result ResultProcessIdNotRegistered{ErrorModule::ARP, 102}; |
| 13 | constexpr Result ERR_NOT_REGISTERED{ErrorModule::ARP, 102}; | ||
| 14 | 13 | ||
| 15 | } // namespace Service::Glue | 14 | } // namespace Service::Glue |
diff --git a/src/core/hle/service/glue/glue_manager.cpp b/src/core/hle/service/glue/glue_manager.cpp index 8a654cdca..4bf67921b 100644 --- a/src/core/hle/service/glue/glue_manager.cpp +++ b/src/core/hle/service/glue/glue_manager.cpp | |||
| @@ -17,12 +17,12 @@ ARPManager::~ARPManager() = default; | |||
| 17 | 17 | ||
| 18 | ResultVal<ApplicationLaunchProperty> ARPManager::GetLaunchProperty(u64 title_id) const { | 18 | ResultVal<ApplicationLaunchProperty> ARPManager::GetLaunchProperty(u64 title_id) const { |
| 19 | if (title_id == 0) { | 19 | if (title_id == 0) { |
| 20 | return ERR_INVALID_PROCESS_ID; | 20 | return Glue::ResultInvalidProcessId; |
| 21 | } | 21 | } |
| 22 | 22 | ||
| 23 | const auto iter = entries.find(title_id); | 23 | const auto iter = entries.find(title_id); |
| 24 | if (iter == entries.end()) { | 24 | if (iter == entries.end()) { |
| 25 | return ERR_NOT_REGISTERED; | 25 | return Glue::ResultProcessIdNotRegistered; |
| 26 | } | 26 | } |
| 27 | 27 | ||
| 28 | return iter->second.launch; | 28 | return iter->second.launch; |
| @@ -30,12 +30,12 @@ ResultVal<ApplicationLaunchProperty> ARPManager::GetLaunchProperty(u64 title_id) | |||
| 30 | 30 | ||
| 31 | ResultVal<std::vector<u8>> ARPManager::GetControlProperty(u64 title_id) const { | 31 | ResultVal<std::vector<u8>> ARPManager::GetControlProperty(u64 title_id) const { |
| 32 | if (title_id == 0) { | 32 | if (title_id == 0) { |
| 33 | return ERR_INVALID_PROCESS_ID; | 33 | return Glue::ResultInvalidProcessId; |
| 34 | } | 34 | } |
| 35 | 35 | ||
| 36 | const auto iter = entries.find(title_id); | 36 | const auto iter = entries.find(title_id); |
| 37 | if (iter == entries.end()) { | 37 | if (iter == entries.end()) { |
| 38 | return ERR_NOT_REGISTERED; | 38 | return Glue::ResultProcessIdNotRegistered; |
| 39 | } | 39 | } |
| 40 | 40 | ||
| 41 | return iter->second.control; | 41 | return iter->second.control; |
| @@ -44,12 +44,12 @@ ResultVal<std::vector<u8>> ARPManager::GetControlProperty(u64 title_id) const { | |||
| 44 | Result ARPManager::Register(u64 title_id, ApplicationLaunchProperty launch, | 44 | Result ARPManager::Register(u64 title_id, ApplicationLaunchProperty launch, |
| 45 | std::vector<u8> control) { | 45 | std::vector<u8> control) { |
| 46 | if (title_id == 0) { | 46 | if (title_id == 0) { |
| 47 | return ERR_INVALID_PROCESS_ID; | 47 | return Glue::ResultInvalidProcessId; |
| 48 | } | 48 | } |
| 49 | 49 | ||
| 50 | const auto iter = entries.find(title_id); | 50 | const auto iter = entries.find(title_id); |
| 51 | if (iter != entries.end()) { | 51 | if (iter != entries.end()) { |
| 52 | return ERR_INVALID_ACCESS; | 52 | return Glue::ResultAlreadyBound; |
| 53 | } | 53 | } |
| 54 | 54 | ||
| 55 | entries.insert_or_assign(title_id, MapEntry{launch, std::move(control)}); | 55 | entries.insert_or_assign(title_id, MapEntry{launch, std::move(control)}); |
| @@ -58,12 +58,12 @@ Result ARPManager::Register(u64 title_id, ApplicationLaunchProperty launch, | |||
| 58 | 58 | ||
| 59 | Result ARPManager::Unregister(u64 title_id) { | 59 | Result ARPManager::Unregister(u64 title_id) { |
| 60 | if (title_id == 0) { | 60 | if (title_id == 0) { |
| 61 | return ERR_INVALID_PROCESS_ID; | 61 | return Glue::ResultInvalidProcessId; |
| 62 | } | 62 | } |
| 63 | 63 | ||
| 64 | const auto iter = entries.find(title_id); | 64 | const auto iter = entries.find(title_id); |
| 65 | if (iter == entries.end()) { | 65 | if (iter == entries.end()) { |
| 66 | return ERR_NOT_REGISTERED; | 66 | return Glue::ResultProcessIdNotRegistered; |
| 67 | } | 67 | } |
| 68 | 68 | ||
| 69 | entries.erase(iter); | 69 | entries.erase(iter); |
diff --git a/src/core/hle/service/glue/glue_manager.h b/src/core/hle/service/glue/glue_manager.h index cd0b092ac..1cf53d9d9 100644 --- a/src/core/hle/service/glue/glue_manager.h +++ b/src/core/hle/service/glue/glue_manager.h | |||
| @@ -30,23 +30,23 @@ public: | |||
| 30 | ~ARPManager(); | 30 | ~ARPManager(); |
| 31 | 31 | ||
| 32 | // Returns the ApplicationLaunchProperty corresponding to the provided title ID if it was | 32 | // Returns the ApplicationLaunchProperty corresponding to the provided title ID if it was |
| 33 | // previously registered, otherwise ERR_NOT_REGISTERED if it was never registered or | 33 | // previously registered, otherwise ResultProcessIdNotRegistered if it was never registered or |
| 34 | // ERR_INVALID_PROCESS_ID if the title ID is 0. | 34 | // ResultInvalidProcessId if the title ID is 0. |
| 35 | ResultVal<ApplicationLaunchProperty> GetLaunchProperty(u64 title_id) const; | 35 | ResultVal<ApplicationLaunchProperty> GetLaunchProperty(u64 title_id) const; |
| 36 | 36 | ||
| 37 | // Returns a vector of the raw bytes of NACP data (necessarily 0x4000 in size) corresponding to | 37 | // Returns a vector of the raw bytes of NACP data (necessarily 0x4000 in size) corresponding to |
| 38 | // the provided title ID if it was previously registered, otherwise ERR_NOT_REGISTERED if it was | 38 | // the provided title ID if it was previously registered, otherwise ResultProcessIdNotRegistered |
| 39 | // never registered or ERR_INVALID_PROCESS_ID if the title ID is 0. | 39 | // if it was never registered or ResultInvalidProcessId if the title ID is 0. |
| 40 | ResultVal<std::vector<u8>> GetControlProperty(u64 title_id) const; | 40 | ResultVal<std::vector<u8>> GetControlProperty(u64 title_id) const; |
| 41 | 41 | ||
| 42 | // Adds a new entry to the internal database with the provided parameters, returning | 42 | // Adds a new entry to the internal database with the provided parameters, returning |
| 43 | // ERR_INVALID_ACCESS if attempting to re-register a title ID without an intermediate Unregister | 43 | // ResultProcessIdNotRegistered if attempting to re-register a title ID without an intermediate |
| 44 | // step, and ERR_INVALID_PROCESS_ID if the title ID is 0. | 44 | // Unregister step, and ResultInvalidProcessId if the title ID is 0. |
| 45 | Result Register(u64 title_id, ApplicationLaunchProperty launch, std::vector<u8> control); | 45 | Result Register(u64 title_id, ApplicationLaunchProperty launch, std::vector<u8> control); |
| 46 | 46 | ||
| 47 | // Removes the registration for the provided title ID from the database, returning | 47 | // Removes the registration for the provided title ID from the database, returning |
| 48 | // ERR_NOT_REGISTERED if it doesn't exist in the database and ERR_INVALID_PROCESS_ID if the | 48 | // ResultProcessIdNotRegistered if it doesn't exist in the database and ResultInvalidProcessId |
| 49 | // title ID is 0. | 49 | // if the title ID is 0. |
| 50 | Result Unregister(u64 title_id); | 50 | Result Unregister(u64 title_id); |
| 51 | 51 | ||
| 52 | // Removes all entries from the database, always succeeds. Should only be used when resetting | 52 | // Removes all entries from the database, always succeeds. Should only be used when resetting |
diff --git a/src/core/hle/service/hid/controllers/stubbed.cpp b/src/core/hle/service/hid/controllers/stubbed.cpp index df9ee0c3f..9e2f3ab21 100644 --- a/src/core/hle/service/hid/controllers/stubbed.cpp +++ b/src/core/hle/service/hid/controllers/stubbed.cpp | |||
| @@ -26,7 +26,7 @@ void Controller_Stubbed::OnUpdate(const Core::Timing::CoreTiming& core_timing) { | |||
| 26 | } | 26 | } |
| 27 | 27 | ||
| 28 | CommonHeader header{}; | 28 | CommonHeader header{}; |
| 29 | header.timestamp = core_timing.GetCPUTicks(); | 29 | header.timestamp = core_timing.GetGlobalTimeNs().count(); |
| 30 | header.total_entry_count = 17; | 30 | header.total_entry_count = 17; |
| 31 | header.entry_count = 0; | 31 | header.entry_count = 0; |
| 32 | header.last_entry_index = 0; | 32 | header.last_entry_index = 0; |
diff --git a/src/core/hle/service/hid/controllers/touchscreen.cpp b/src/core/hle/service/hid/controllers/touchscreen.cpp index d90a4e732..3ef91df4b 100644 --- a/src/core/hle/service/hid/controllers/touchscreen.cpp +++ b/src/core/hle/service/hid/controllers/touchscreen.cpp | |||
| @@ -32,7 +32,7 @@ void Controller_Touchscreen::OnInit() {} | |||
| 32 | void Controller_Touchscreen::OnRelease() {} | 32 | void Controller_Touchscreen::OnRelease() {} |
| 33 | 33 | ||
| 34 | void Controller_Touchscreen::OnUpdate(const Core::Timing::CoreTiming& core_timing) { | 34 | void Controller_Touchscreen::OnUpdate(const Core::Timing::CoreTiming& core_timing) { |
| 35 | shared_memory->touch_screen_lifo.timestamp = core_timing.GetCPUTicks(); | 35 | shared_memory->touch_screen_lifo.timestamp = core_timing.GetGlobalTimeNs().count(); |
| 36 | 36 | ||
| 37 | if (!IsControllerActivated()) { | 37 | if (!IsControllerActivated()) { |
| 38 | shared_memory->touch_screen_lifo.buffer_count = 0; | 38 | shared_memory->touch_screen_lifo.buffer_count = 0; |
| @@ -85,7 +85,7 @@ void Controller_Touchscreen::OnUpdate(const Core::Timing::CoreTiming& core_timin | |||
| 85 | const auto active_fingers_count = | 85 | const auto active_fingers_count = |
| 86 | static_cast<std::size_t>(std::distance(active_fingers.begin(), end_iter)); | 86 | static_cast<std::size_t>(std::distance(active_fingers.begin(), end_iter)); |
| 87 | 87 | ||
| 88 | const u64 tick = core_timing.GetCPUTicks(); | 88 | const u64 timestamp = static_cast<u64>(core_timing.GetGlobalTimeNs().count()); |
| 89 | const auto& last_entry = shared_memory->touch_screen_lifo.ReadCurrentEntry().state; | 89 | const auto& last_entry = shared_memory->touch_screen_lifo.ReadCurrentEntry().state; |
| 90 | 90 | ||
| 91 | next_state.sampling_number = last_entry.sampling_number + 1; | 91 | next_state.sampling_number = last_entry.sampling_number + 1; |
| @@ -102,8 +102,8 @@ void Controller_Touchscreen::OnUpdate(const Core::Timing::CoreTiming& core_timin | |||
| 102 | touch_entry.diameter_x = Settings::values.touchscreen.diameter_x; | 102 | touch_entry.diameter_x = Settings::values.touchscreen.diameter_x; |
| 103 | touch_entry.diameter_y = Settings::values.touchscreen.diameter_y; | 103 | touch_entry.diameter_y = Settings::values.touchscreen.diameter_y; |
| 104 | touch_entry.rotation_angle = Settings::values.touchscreen.rotation_angle; | 104 | touch_entry.rotation_angle = Settings::values.touchscreen.rotation_angle; |
| 105 | touch_entry.delta_time = tick - active_fingers[id].last_touch; | 105 | touch_entry.delta_time = timestamp - active_fingers[id].last_touch; |
| 106 | fingers[active_fingers[id].id].last_touch = tick; | 106 | fingers[active_fingers[id].id].last_touch = timestamp; |
| 107 | touch_entry.finger = active_fingers[id].id; | 107 | touch_entry.finger = active_fingers[id].id; |
| 108 | touch_entry.attribute.raw = active_fingers[id].attribute.raw; | 108 | touch_entry.attribute.raw = active_fingers[id].attribute.raw; |
| 109 | } else { | 109 | } else { |
diff --git a/src/core/hle/service/ipc_helpers.h b/src/core/hle/service/ipc_helpers.h index 3e67123c7..8703b57ca 100644 --- a/src/core/hle/service/ipc_helpers.h +++ b/src/core/hle/service/ipc_helpers.h | |||
| @@ -19,7 +19,7 @@ | |||
| 19 | 19 | ||
| 20 | namespace IPC { | 20 | namespace IPC { |
| 21 | 21 | ||
| 22 | constexpr Result ERR_REMOTE_PROCESS_DEAD{ErrorModule::HIPC, 301}; | 22 | constexpr Result ResultSessionClosed{ErrorModule::HIPC, 301}; |
| 23 | 23 | ||
| 24 | class RequestHelperBase { | 24 | class RequestHelperBase { |
| 25 | protected: | 25 | protected: |
diff --git a/src/core/hle/service/nfp/amiibo_crypto.cpp b/src/core/hle/service/nfp/amiibo_crypto.cpp index ffb2f959c..ddf04b1d7 100644 --- a/src/core/hle/service/nfp/amiibo_crypto.cpp +++ b/src/core/hle/service/nfp/amiibo_crypto.cpp | |||
| @@ -80,13 +80,16 @@ NTAG215File NfcDataToEncodedData(const EncryptedNTAG215File& nfc_data) { | |||
| 80 | encoded_data.hmac_data = nfc_data.user_memory.hmac_data; | 80 | encoded_data.hmac_data = nfc_data.user_memory.hmac_data; |
| 81 | encoded_data.constant_value = nfc_data.user_memory.constant_value; | 81 | encoded_data.constant_value = nfc_data.user_memory.constant_value; |
| 82 | encoded_data.write_counter = nfc_data.user_memory.write_counter; | 82 | encoded_data.write_counter = nfc_data.user_memory.write_counter; |
| 83 | encoded_data.amiibo_version = nfc_data.user_memory.amiibo_version; | ||
| 83 | encoded_data.settings = nfc_data.user_memory.settings; | 84 | encoded_data.settings = nfc_data.user_memory.settings; |
| 84 | encoded_data.owner_mii = nfc_data.user_memory.owner_mii; | 85 | encoded_data.owner_mii = nfc_data.user_memory.owner_mii; |
| 85 | encoded_data.title_id = nfc_data.user_memory.title_id; | 86 | encoded_data.application_id = nfc_data.user_memory.application_id; |
| 86 | encoded_data.applicaton_write_counter = nfc_data.user_memory.applicaton_write_counter; | 87 | encoded_data.application_write_counter = nfc_data.user_memory.application_write_counter; |
| 87 | encoded_data.application_area_id = nfc_data.user_memory.application_area_id; | 88 | encoded_data.application_area_id = nfc_data.user_memory.application_area_id; |
| 89 | encoded_data.application_id_byte = nfc_data.user_memory.application_id_byte; | ||
| 88 | encoded_data.unknown = nfc_data.user_memory.unknown; | 90 | encoded_data.unknown = nfc_data.user_memory.unknown; |
| 89 | encoded_data.unknown2 = nfc_data.user_memory.unknown2; | 91 | encoded_data.unknown2 = nfc_data.user_memory.unknown2; |
| 92 | encoded_data.application_area_crc = nfc_data.user_memory.application_area_crc; | ||
| 90 | encoded_data.application_area = nfc_data.user_memory.application_area; | 93 | encoded_data.application_area = nfc_data.user_memory.application_area; |
| 91 | encoded_data.hmac_tag = nfc_data.user_memory.hmac_tag; | 94 | encoded_data.hmac_tag = nfc_data.user_memory.hmac_tag; |
| 92 | encoded_data.lock_bytes = nfc_data.uuid.lock_bytes; | 95 | encoded_data.lock_bytes = nfc_data.uuid.lock_bytes; |
| @@ -111,13 +114,16 @@ EncryptedNTAG215File EncodedDataToNfcData(const NTAG215File& encoded_data) { | |||
| 111 | nfc_data.user_memory.hmac_data = encoded_data.hmac_data; | 114 | nfc_data.user_memory.hmac_data = encoded_data.hmac_data; |
| 112 | nfc_data.user_memory.constant_value = encoded_data.constant_value; | 115 | nfc_data.user_memory.constant_value = encoded_data.constant_value; |
| 113 | nfc_data.user_memory.write_counter = encoded_data.write_counter; | 116 | nfc_data.user_memory.write_counter = encoded_data.write_counter; |
| 117 | nfc_data.user_memory.amiibo_version = encoded_data.amiibo_version; | ||
| 114 | nfc_data.user_memory.settings = encoded_data.settings; | 118 | nfc_data.user_memory.settings = encoded_data.settings; |
| 115 | nfc_data.user_memory.owner_mii = encoded_data.owner_mii; | 119 | nfc_data.user_memory.owner_mii = encoded_data.owner_mii; |
| 116 | nfc_data.user_memory.title_id = encoded_data.title_id; | 120 | nfc_data.user_memory.application_id = encoded_data.application_id; |
| 117 | nfc_data.user_memory.applicaton_write_counter = encoded_data.applicaton_write_counter; | 121 | nfc_data.user_memory.application_write_counter = encoded_data.application_write_counter; |
| 118 | nfc_data.user_memory.application_area_id = encoded_data.application_area_id; | 122 | nfc_data.user_memory.application_area_id = encoded_data.application_area_id; |
| 123 | nfc_data.user_memory.application_id_byte = encoded_data.application_id_byte; | ||
| 119 | nfc_data.user_memory.unknown = encoded_data.unknown; | 124 | nfc_data.user_memory.unknown = encoded_data.unknown; |
| 120 | nfc_data.user_memory.unknown2 = encoded_data.unknown2; | 125 | nfc_data.user_memory.unknown2 = encoded_data.unknown2; |
| 126 | nfc_data.user_memory.application_area_crc = encoded_data.application_area_crc; | ||
| 121 | nfc_data.user_memory.application_area = encoded_data.application_area; | 127 | nfc_data.user_memory.application_area = encoded_data.application_area; |
| 122 | nfc_data.user_memory.hmac_tag = encoded_data.hmac_tag; | 128 | nfc_data.user_memory.hmac_tag = encoded_data.hmac_tag; |
| 123 | nfc_data.user_memory.model_info = encoded_data.model_info; | 129 | nfc_data.user_memory.model_info = encoded_data.model_info; |
diff --git a/src/core/hle/service/nfp/nfp_device.cpp b/src/core/hle/service/nfp/nfp_device.cpp index 1bdc42741..ddff90d6a 100644 --- a/src/core/hle/service/nfp/nfp_device.cpp +++ b/src/core/hle/service/nfp/nfp_device.cpp | |||
| @@ -174,8 +174,8 @@ Result NfpDevice::StopDetection() { | |||
| 174 | 174 | ||
| 175 | if (device_state == DeviceState::TagFound || device_state == DeviceState::TagMounted) { | 175 | if (device_state == DeviceState::TagFound || device_state == DeviceState::TagMounted) { |
| 176 | CloseAmiibo(); | 176 | CloseAmiibo(); |
| 177 | return ResultSuccess; | ||
| 178 | } | 177 | } |
| 178 | |||
| 179 | if (device_state == DeviceState::SearchingForTag || device_state == DeviceState::TagRemoved) { | 179 | if (device_state == DeviceState::SearchingForTag || device_state == DeviceState::TagRemoved) { |
| 180 | device_state = DeviceState::Initialized; | 180 | device_state = DeviceState::Initialized; |
| 181 | return ResultSuccess; | 181 | return ResultSuccess; |
| @@ -204,9 +204,7 @@ Result NfpDevice::Flush() { | |||
| 204 | const auto& current_date = GetAmiiboDate(current_posix_time); | 204 | const auto& current_date = GetAmiiboDate(current_posix_time); |
| 205 | if (settings.write_date.raw_date != current_date.raw_date) { | 205 | if (settings.write_date.raw_date != current_date.raw_date) { |
| 206 | settings.write_date = current_date; | 206 | settings.write_date = current_date; |
| 207 | settings.crc_counter++; | 207 | UpdateSettingsCrc(); |
| 208 | // TODO: Find how to calculate the crc check | ||
| 209 | // settings.crc = CalculateCRC(settings); | ||
| 210 | } | 208 | } |
| 211 | 209 | ||
| 212 | tag_data.write_counter++; | 210 | tag_data.write_counter++; |
| @@ -318,7 +316,7 @@ Result NfpDevice::GetCommonInfo(CommonInfo& common_info) const { | |||
| 318 | common_info = { | 316 | common_info = { |
| 319 | .last_write_date = settings.write_date.GetWriteDate(), | 317 | .last_write_date = settings.write_date.GetWriteDate(), |
| 320 | .write_counter = tag_data.write_counter, | 318 | .write_counter = tag_data.write_counter, |
| 321 | .version = 0, | 319 | .version = tag_data.amiibo_version, |
| 322 | .application_area_size = sizeof(ApplicationArea), | 320 | .application_area_size = sizeof(ApplicationArea), |
| 323 | }; | 321 | }; |
| 324 | return ResultSuccess; | 322 | return ResultSuccess; |
| @@ -370,13 +368,95 @@ Result NfpDevice::GetRegisterInfo(RegisterInfo& register_info) const { | |||
| 370 | .mii_char_info = manager.ConvertV3ToCharInfo(tag_data.owner_mii), | 368 | .mii_char_info = manager.ConvertV3ToCharInfo(tag_data.owner_mii), |
| 371 | .creation_date = settings.init_date.GetWriteDate(), | 369 | .creation_date = settings.init_date.GetWriteDate(), |
| 372 | .amiibo_name = GetAmiiboName(settings), | 370 | .amiibo_name = GetAmiiboName(settings), |
| 373 | .font_region = {}, | 371 | .font_region = settings.settings.font_region, |
| 372 | }; | ||
| 373 | |||
| 374 | return ResultSuccess; | ||
| 375 | } | ||
| 376 | |||
| 377 | Result NfpDevice::GetAdminInfo(AdminInfo& admin_info) const { | ||
| 378 | if (device_state != DeviceState::TagMounted) { | ||
| 379 | LOG_ERROR(Service_NFC, "Wrong device state {}", device_state); | ||
| 380 | if (device_state == DeviceState::TagRemoved) { | ||
| 381 | return TagRemoved; | ||
| 382 | } | ||
| 383 | return WrongDeviceState; | ||
| 384 | } | ||
| 385 | |||
| 386 | if (mount_target == MountTarget::None || mount_target == MountTarget::Rom) { | ||
| 387 | LOG_ERROR(Service_NFC, "Amiibo is read only", device_state); | ||
| 388 | return WrongDeviceState; | ||
| 389 | } | ||
| 390 | |||
| 391 | u8 flags = static_cast<u8>(tag_data.settings.settings.raw >> 0x4); | ||
| 392 | if (tag_data.settings.settings.amiibo_initialized == 0) { | ||
| 393 | flags = flags & 0xfe; | ||
| 394 | } | ||
| 395 | |||
| 396 | u64 application_id = 0; | ||
| 397 | u32 application_area_id = 0; | ||
| 398 | AppAreaVersion app_area_version = AppAreaVersion::NotSet; | ||
| 399 | if (tag_data.settings.settings.appdata_initialized != 0) { | ||
| 400 | application_id = tag_data.application_id; | ||
| 401 | app_area_version = | ||
| 402 | static_cast<AppAreaVersion>(application_id >> application_id_version_offset & 0xf); | ||
| 403 | |||
| 404 | // Restore application id to original value | ||
| 405 | if (application_id >> 0x38 != 0) { | ||
| 406 | const u8 application_byte = tag_data.application_id_byte & 0xf; | ||
| 407 | application_id = RemoveVersionByte(application_id) | | ||
| 408 | (static_cast<u64>(application_byte) << application_id_version_offset); | ||
| 409 | } | ||
| 410 | |||
| 411 | application_area_id = tag_data.application_area_id; | ||
| 412 | } | ||
| 413 | |||
| 414 | // TODO: Validate this data | ||
| 415 | admin_info = { | ||
| 416 | .application_id = application_id, | ||
| 417 | .application_area_id = application_area_id, | ||
| 418 | .crc_change_counter = tag_data.settings.crc_counter, | ||
| 419 | .flags = flags, | ||
| 420 | .tag_type = PackedTagType::Type2, | ||
| 421 | .app_area_version = app_area_version, | ||
| 374 | }; | 422 | }; |
| 375 | 423 | ||
| 376 | return ResultSuccess; | 424 | return ResultSuccess; |
| 377 | } | 425 | } |
| 378 | 426 | ||
| 379 | Result NfpDevice::SetNicknameAndOwner(const AmiiboName& amiibo_name) { | 427 | Result NfpDevice::DeleteRegisterInfo() { |
| 428 | if (device_state != DeviceState::TagMounted) { | ||
| 429 | LOG_ERROR(Service_NFC, "Wrong device state {}", device_state); | ||
| 430 | if (device_state == DeviceState::TagRemoved) { | ||
| 431 | return TagRemoved; | ||
| 432 | } | ||
| 433 | return WrongDeviceState; | ||
| 434 | } | ||
| 435 | |||
| 436 | if (mount_target == MountTarget::None || mount_target == MountTarget::Rom) { | ||
| 437 | LOG_ERROR(Service_NFC, "Amiibo is read only", device_state); | ||
| 438 | return WrongDeviceState; | ||
| 439 | } | ||
| 440 | |||
| 441 | if (tag_data.settings.settings.amiibo_initialized == 0) { | ||
| 442 | return RegistrationIsNotInitialized; | ||
| 443 | } | ||
| 444 | |||
| 445 | Common::TinyMT rng{}; | ||
| 446 | rng.GenerateRandomBytes(&tag_data.owner_mii, sizeof(tag_data.owner_mii)); | ||
| 447 | rng.GenerateRandomBytes(&tag_data.settings.amiibo_name, sizeof(tag_data.settings.amiibo_name)); | ||
| 448 | rng.GenerateRandomBytes(&tag_data.unknown, sizeof(u8)); | ||
| 449 | rng.GenerateRandomBytes(&tag_data.unknown2[0], sizeof(u32)); | ||
| 450 | rng.GenerateRandomBytes(&tag_data.unknown2[1], sizeof(u32)); | ||
| 451 | rng.GenerateRandomBytes(&tag_data.application_area_crc, sizeof(u32)); | ||
| 452 | rng.GenerateRandomBytes(&tag_data.settings.init_date, sizeof(u32)); | ||
| 453 | tag_data.settings.settings.font_region.Assign(0); | ||
| 454 | tag_data.settings.settings.amiibo_initialized.Assign(0); | ||
| 455 | |||
| 456 | return Flush(); | ||
| 457 | } | ||
| 458 | |||
| 459 | Result NfpDevice::SetRegisterInfoPrivate(const AmiiboName& amiibo_name) { | ||
| 380 | if (device_state != DeviceState::TagMounted) { | 460 | if (device_state != DeviceState::TagMounted) { |
| 381 | LOG_ERROR(Service_NFP, "Wrong device state {}", device_state); | 461 | LOG_ERROR(Service_NFP, "Wrong device state {}", device_state); |
| 382 | if (device_state == DeviceState::TagRemoved) { | 462 | if (device_state == DeviceState::TagRemoved) { |
| @@ -393,16 +473,23 @@ Result NfpDevice::SetNicknameAndOwner(const AmiiboName& amiibo_name) { | |||
| 393 | Service::Mii::MiiManager manager; | 473 | Service::Mii::MiiManager manager; |
| 394 | auto& settings = tag_data.settings; | 474 | auto& settings = tag_data.settings; |
| 395 | 475 | ||
| 396 | settings.init_date = GetAmiiboDate(current_posix_time); | 476 | if (tag_data.settings.settings.amiibo_initialized == 0) { |
| 397 | settings.write_date = GetAmiiboDate(current_posix_time); | 477 | settings.init_date = GetAmiiboDate(current_posix_time); |
| 398 | settings.crc_counter++; | 478 | settings.write_date.raw_date = 0; |
| 399 | // TODO: Find how to calculate the crc check | 479 | } |
| 400 | // settings.crc = CalculateCRC(settings); | ||
| 401 | 480 | ||
| 402 | SetAmiiboName(settings, amiibo_name); | 481 | SetAmiiboName(settings, amiibo_name); |
| 403 | tag_data.owner_mii = manager.ConvertCharInfoToV3(manager.BuildDefault(0)); | 482 | tag_data.owner_mii = manager.ConvertCharInfoToV3(manager.BuildDefault(0)); |
| 483 | tag_data.unknown = 0; | ||
| 484 | tag_data.unknown2[6] = 0; | ||
| 485 | settings.country_code_id = 0; | ||
| 486 | settings.settings.font_region.Assign(0); | ||
| 404 | settings.settings.amiibo_initialized.Assign(1); | 487 | settings.settings.amiibo_initialized.Assign(1); |
| 405 | 488 | ||
| 489 | // TODO: this is a mix of tag.file input | ||
| 490 | std::array<u8, 0x7e> unknown_input{}; | ||
| 491 | tag_data.application_area_crc = CalculateCrc(unknown_input); | ||
| 492 | |||
| 406 | return Flush(); | 493 | return Flush(); |
| 407 | } | 494 | } |
| 408 | 495 | ||
| @@ -425,23 +512,17 @@ Result NfpDevice::RestoreAmiibo() { | |||
| 425 | return ResultSuccess; | 512 | return ResultSuccess; |
| 426 | } | 513 | } |
| 427 | 514 | ||
| 428 | Result NfpDevice::DeleteAllData() { | 515 | Result NfpDevice::Format() { |
| 429 | const auto result = DeleteApplicationArea(); | 516 | auto result1 = DeleteApplicationArea(); |
| 430 | if (result.IsError()) { | 517 | auto result2 = DeleteRegisterInfo(); |
| 431 | return result; | ||
| 432 | } | ||
| 433 | 518 | ||
| 434 | if (device_state != DeviceState::TagMounted) { | 519 | if (result1.IsError()) { |
| 435 | LOG_ERROR(Service_NFP, "Wrong device state {}", device_state); | 520 | return result1; |
| 436 | if (device_state == DeviceState::TagRemoved) { | ||
| 437 | return TagRemoved; | ||
| 438 | } | ||
| 439 | return WrongDeviceState; | ||
| 440 | } | 521 | } |
| 441 | 522 | ||
| 442 | Common::TinyMT rng{}; | 523 | if (result2.IsError()) { |
| 443 | rng.GenerateRandomBytes(&tag_data.owner_mii, sizeof(tag_data.owner_mii)); | 524 | return result2; |
| 444 | tag_data.settings.settings.amiibo_initialized.Assign(0); | 525 | } |
| 445 | 526 | ||
| 446 | return Flush(); | 527 | return Flush(); |
| 447 | } | 528 | } |
| @@ -569,7 +650,10 @@ Result NfpDevice::SetApplicationArea(std::span<const u8> data) { | |||
| 569 | rng.GenerateRandomBytes(tag_data.application_area.data() + data.size(), | 650 | rng.GenerateRandomBytes(tag_data.application_area.data() + data.size(), |
| 570 | sizeof(ApplicationArea) - data.size()); | 651 | sizeof(ApplicationArea) - data.size()); |
| 571 | 652 | ||
| 572 | tag_data.applicaton_write_counter++; | 653 | if (tag_data.application_write_counter != counter_limit) { |
| 654 | tag_data.application_write_counter++; | ||
| 655 | } | ||
| 656 | |||
| 573 | is_data_moddified = true; | 657 | is_data_moddified = true; |
| 574 | 658 | ||
| 575 | return ResultSuccess; | 659 | return ResultSuccess; |
| @@ -617,14 +701,25 @@ Result NfpDevice::RecreateApplicationArea(u32 access_id, std::span<const u8> dat | |||
| 617 | rng.GenerateRandomBytes(tag_data.application_area.data() + data.size(), | 701 | rng.GenerateRandomBytes(tag_data.application_area.data() + data.size(), |
| 618 | sizeof(ApplicationArea) - data.size()); | 702 | sizeof(ApplicationArea) - data.size()); |
| 619 | 703 | ||
| 620 | // TODO: Investigate why the title id needs to be moddified | 704 | if (tag_data.application_write_counter != counter_limit) { |
| 621 | tag_data.title_id = system.GetApplicationProcessProgramID(); | 705 | tag_data.application_write_counter++; |
| 622 | tag_data.title_id = tag_data.title_id | 0x30000000ULL; | 706 | } |
| 707 | |||
| 708 | const u64 application_id = system.GetApplicationProcessProgramID(); | ||
| 709 | |||
| 710 | tag_data.application_id_byte = | ||
| 711 | static_cast<u8>(application_id >> application_id_version_offset & 0xf); | ||
| 712 | tag_data.application_id = | ||
| 713 | RemoveVersionByte(application_id) | | ||
| 714 | (static_cast<u64>(AppAreaVersion::NintendoSwitch) << application_id_version_offset); | ||
| 623 | tag_data.settings.settings.appdata_initialized.Assign(1); | 715 | tag_data.settings.settings.appdata_initialized.Assign(1); |
| 624 | tag_data.application_area_id = access_id; | 716 | tag_data.application_area_id = access_id; |
| 625 | tag_data.applicaton_write_counter++; | ||
| 626 | tag_data.unknown = {}; | 717 | tag_data.unknown = {}; |
| 627 | 718 | ||
| 719 | // TODO: this is a mix of tag_data input | ||
| 720 | std::array<u8, 0x7e> unknown_input{}; | ||
| 721 | tag_data.application_area_crc = CalculateCrc(unknown_input); | ||
| 722 | |||
| 628 | return Flush(); | 723 | return Flush(); |
| 629 | } | 724 | } |
| 630 | 725 | ||
| @@ -642,12 +737,20 @@ Result NfpDevice::DeleteApplicationArea() { | |||
| 642 | return WrongDeviceState; | 737 | return WrongDeviceState; |
| 643 | } | 738 | } |
| 644 | 739 | ||
| 740 | if (tag_data.settings.settings.appdata_initialized == 0) { | ||
| 741 | return ApplicationAreaIsNotInitialized; | ||
| 742 | } | ||
| 743 | |||
| 744 | if (tag_data.application_write_counter != counter_limit) { | ||
| 745 | tag_data.application_write_counter++; | ||
| 746 | } | ||
| 747 | |||
| 645 | Common::TinyMT rng{}; | 748 | Common::TinyMT rng{}; |
| 646 | rng.GenerateRandomBytes(tag_data.application_area.data(), sizeof(ApplicationArea)); | 749 | rng.GenerateRandomBytes(tag_data.application_area.data(), sizeof(ApplicationArea)); |
| 647 | rng.GenerateRandomBytes(&tag_data.title_id, sizeof(u64)); | 750 | rng.GenerateRandomBytes(&tag_data.application_id, sizeof(u64)); |
| 648 | rng.GenerateRandomBytes(&tag_data.application_area_id, sizeof(u32)); | 751 | rng.GenerateRandomBytes(&tag_data.application_area_id, sizeof(u32)); |
| 752 | rng.GenerateRandomBytes(&tag_data.application_id_byte, sizeof(u8)); | ||
| 649 | tag_data.settings.settings.appdata_initialized.Assign(0); | 753 | tag_data.settings.settings.appdata_initialized.Assign(0); |
| 650 | tag_data.applicaton_write_counter++; | ||
| 651 | tag_data.unknown = {}; | 754 | tag_data.unknown = {}; |
| 652 | 755 | ||
| 653 | return Flush(); | 756 | return Flush(); |
| @@ -719,4 +822,45 @@ AmiiboDate NfpDevice::GetAmiiboDate(s64 posix_time) const { | |||
| 719 | return amiibo_date; | 822 | return amiibo_date; |
| 720 | } | 823 | } |
| 721 | 824 | ||
| 825 | u64 NfpDevice::RemoveVersionByte(u64 application_id) const { | ||
| 826 | return application_id & ~(0xfULL << application_id_version_offset); | ||
| 827 | } | ||
| 828 | |||
| 829 | void NfpDevice::UpdateSettingsCrc() { | ||
| 830 | auto& settings = tag_data.settings; | ||
| 831 | |||
| 832 | if (settings.crc_counter != counter_limit) { | ||
| 833 | settings.crc_counter++; | ||
| 834 | } | ||
| 835 | |||
| 836 | // TODO: this reads data from a global, find what it is | ||
| 837 | std::array<u8, 8> unknown_input{}; | ||
| 838 | settings.crc = CalculateCrc(unknown_input); | ||
| 839 | } | ||
| 840 | |||
| 841 | u32 NfpDevice::CalculateCrc(std::span<const u8> data) { | ||
| 842 | constexpr u32 magic = 0xedb88320; | ||
| 843 | u32 crc = 0xffffffff; | ||
| 844 | |||
| 845 | if (data.size() == 0) { | ||
| 846 | return 0; | ||
| 847 | } | ||
| 848 | |||
| 849 | for (u8 input : data) { | ||
| 850 | u32 temp = (crc ^ input) >> 1; | ||
| 851 | if (((crc ^ input) & 1) != 0) { | ||
| 852 | temp = temp ^ magic; | ||
| 853 | } | ||
| 854 | |||
| 855 | for (std::size_t step = 0; step < 7; ++step) { | ||
| 856 | crc = temp >> 1; | ||
| 857 | if ((temp & 1) != 0) { | ||
| 858 | crc = temp >> 1 ^ magic; | ||
| 859 | } | ||
| 860 | } | ||
| 861 | } | ||
| 862 | |||
| 863 | return ~crc; | ||
| 864 | } | ||
| 865 | |||
| 722 | } // namespace Service::NFP | 866 | } // namespace Service::NFP |
diff --git a/src/core/hle/service/nfp/nfp_device.h b/src/core/hle/service/nfp/nfp_device.h index b6a46f2ac..06386401d 100644 --- a/src/core/hle/service/nfp/nfp_device.h +++ b/src/core/hle/service/nfp/nfp_device.h | |||
| @@ -47,10 +47,12 @@ public: | |||
| 47 | Result GetCommonInfo(CommonInfo& common_info) const; | 47 | Result GetCommonInfo(CommonInfo& common_info) const; |
| 48 | Result GetModelInfo(ModelInfo& model_info) const; | 48 | Result GetModelInfo(ModelInfo& model_info) const; |
| 49 | Result GetRegisterInfo(RegisterInfo& register_info) const; | 49 | Result GetRegisterInfo(RegisterInfo& register_info) const; |
| 50 | Result GetAdminInfo(AdminInfo& admin_info) const; | ||
| 50 | 51 | ||
| 51 | Result SetNicknameAndOwner(const AmiiboName& amiibo_name); | 52 | Result DeleteRegisterInfo(); |
| 53 | Result SetRegisterInfoPrivate(const AmiiboName& amiibo_name); | ||
| 52 | Result RestoreAmiibo(); | 54 | Result RestoreAmiibo(); |
| 53 | Result DeleteAllData(); | 55 | Result Format(); |
| 54 | 56 | ||
| 55 | Result OpenApplicationArea(u32 access_id); | 57 | Result OpenApplicationArea(u32 access_id); |
| 56 | Result GetApplicationAreaId(u32& application_area_id) const; | 58 | Result GetApplicationAreaId(u32& application_area_id) const; |
| @@ -76,6 +78,9 @@ private: | |||
| 76 | AmiiboName GetAmiiboName(const AmiiboSettings& settings) const; | 78 | AmiiboName GetAmiiboName(const AmiiboSettings& settings) const; |
| 77 | void SetAmiiboName(AmiiboSettings& settings, const AmiiboName& amiibo_name); | 79 | void SetAmiiboName(AmiiboSettings& settings, const AmiiboName& amiibo_name); |
| 78 | AmiiboDate GetAmiiboDate(s64 posix_time) const; | 80 | AmiiboDate GetAmiiboDate(s64 posix_time) const; |
| 81 | u64 RemoveVersionByte(u64 application_id) const; | ||
| 82 | void UpdateSettingsCrc(); | ||
| 83 | u32 CalculateCrc(std::span<const u8>); | ||
| 79 | 84 | ||
| 80 | bool is_controller_set{}; | 85 | bool is_controller_set{}; |
| 81 | int callback_key; | 86 | int callback_key; |
diff --git a/src/core/hle/service/nfp/nfp_types.h b/src/core/hle/service/nfp/nfp_types.h index fc228c2b2..142343d6e 100644 --- a/src/core/hle/service/nfp/nfp_types.h +++ b/src/core/hle/service/nfp/nfp_types.h | |||
| @@ -10,6 +10,8 @@ | |||
| 10 | 10 | ||
| 11 | namespace Service::NFP { | 11 | namespace Service::NFP { |
| 12 | static constexpr std::size_t amiibo_name_length = 0xA; | 12 | static constexpr std::size_t amiibo_name_length = 0xA; |
| 13 | static constexpr std::size_t application_id_version_offset = 0x1c; | ||
| 14 | static constexpr std::size_t counter_limit = 0xffff; | ||
| 13 | 15 | ||
| 14 | enum class ServiceType : u32 { | 16 | enum class ServiceType : u32 { |
| 15 | User, | 17 | User, |
| @@ -99,6 +101,14 @@ enum class TagProtocol : u32 { | |||
| 99 | All = 0xFFFFFFFFU, | 101 | All = 0xFFFFFFFFU, |
| 100 | }; | 102 | }; |
| 101 | 103 | ||
| 104 | enum class AppAreaVersion : u8 { | ||
| 105 | Nintendo3DS = 0, | ||
| 106 | NintendoWiiU = 1, | ||
| 107 | Nintendo3DSv2 = 2, | ||
| 108 | NintendoSwitch = 3, | ||
| 109 | NotSet = 0xFF, | ||
| 110 | }; | ||
| 111 | |||
| 102 | enum class CabinetMode : u8 { | 112 | enum class CabinetMode : u8 { |
| 103 | StartNicknameAndOwnerSettings, | 113 | StartNicknameAndOwnerSettings, |
| 104 | StartGameDataEraser, | 114 | StartGameDataEraser, |
| @@ -197,6 +207,7 @@ struct Settings { | |||
| 197 | union { | 207 | union { |
| 198 | u8 raw{}; | 208 | u8 raw{}; |
| 199 | 209 | ||
| 210 | BitField<0, 4, u8> font_region; | ||
| 200 | BitField<4, 1, u8> amiibo_initialized; | 211 | BitField<4, 1, u8> amiibo_initialized; |
| 201 | BitField<5, 1, u8> appdata_initialized; | 212 | BitField<5, 1, u8> appdata_initialized; |
| 202 | }; | 213 | }; |
| @@ -236,18 +247,20 @@ static_assert(sizeof(NTAG215Password) == 0x8, "NTAG215Password is an invalid siz | |||
| 236 | struct EncryptedAmiiboFile { | 247 | struct EncryptedAmiiboFile { |
| 237 | u8 constant_value; // Must be A5 | 248 | u8 constant_value; // Must be A5 |
| 238 | u16_be write_counter; // Number of times the amiibo has been written? | 249 | u16_be write_counter; // Number of times the amiibo has been written? |
| 239 | INSERT_PADDING_BYTES(0x1); // Unknown 1 | 250 | u8 amiibo_version; // Amiibo file version |
| 240 | AmiiboSettings settings; // Encrypted amiibo settings | 251 | AmiiboSettings settings; // Encrypted amiibo settings |
| 241 | HashData hmac_tag; // Hash | 252 | HashData hmac_tag; // Hash |
| 242 | AmiiboModelInfo model_info; // Encrypted amiibo model info | 253 | AmiiboModelInfo model_info; // Encrypted amiibo model info |
| 243 | HashData keygen_salt; // Salt | 254 | HashData keygen_salt; // Salt |
| 244 | HashData hmac_data; // Hash | 255 | HashData hmac_data; // Hash |
| 245 | Service::Mii::Ver3StoreData owner_mii; // Encrypted Mii data | 256 | Service::Mii::Ver3StoreData owner_mii; // Encrypted Mii data |
| 246 | u64_be title_id; // Encrypted Game id | 257 | u64_be application_id; // Encrypted Game id |
| 247 | u16_be applicaton_write_counter; // Encrypted Counter | 258 | u16_be application_write_counter; // Encrypted Counter |
| 248 | u32_be application_area_id; // Encrypted Game id | 259 | u32_be application_area_id; // Encrypted Game id |
| 249 | std::array<u8, 0x2> unknown; | 260 | u8 application_id_byte; |
| 250 | std::array<u32, 0x8> unknown2; | 261 | u8 unknown; |
| 262 | std::array<u32, 0x7> unknown2; | ||
| 263 | u32_be application_area_crc; | ||
| 251 | ApplicationArea application_area; // Encrypted Game data | 264 | ApplicationArea application_area; // Encrypted Game data |
| 252 | }; | 265 | }; |
| 253 | static_assert(sizeof(EncryptedAmiiboFile) == 0x1F8, "AmiiboFile is an invalid size"); | 266 | static_assert(sizeof(EncryptedAmiiboFile) == 0x1F8, "AmiiboFile is an invalid size"); |
| @@ -259,14 +272,16 @@ struct NTAG215File { | |||
| 259 | HashData hmac_data; // Hash | 272 | HashData hmac_data; // Hash |
| 260 | u8 constant_value; // Must be A5 | 273 | u8 constant_value; // Must be A5 |
| 261 | u16_be write_counter; // Number of times the amiibo has been written? | 274 | u16_be write_counter; // Number of times the amiibo has been written? |
| 262 | INSERT_PADDING_BYTES(0x1); // Unknown 1 | 275 | u8 amiibo_version; // Amiibo file version |
| 263 | AmiiboSettings settings; | 276 | AmiiboSettings settings; |
| 264 | Service::Mii::Ver3StoreData owner_mii; // Encrypted Mii data | 277 | Service::Mii::Ver3StoreData owner_mii; // Mii data |
| 265 | u64_be title_id; | 278 | u64_be application_id; // Game id |
| 266 | u16_be applicaton_write_counter; // Encrypted Counter | 279 | u16_be application_write_counter; // Counter |
| 267 | u32_be application_area_id; | 280 | u32_be application_area_id; |
| 268 | std::array<u8, 0x2> unknown; | 281 | u8 application_id_byte; |
| 269 | std::array<u32, 0x8> unknown2; | 282 | u8 unknown; |
| 283 | std::array<u32, 0x7> unknown2; | ||
| 284 | u32_be application_area_crc; | ||
| 270 | ApplicationArea application_area; // Encrypted Game data | 285 | ApplicationArea application_area; // Encrypted Game data |
| 271 | HashData hmac_tag; // Hash | 286 | HashData hmac_tag; // Hash |
| 272 | UniqueSerialNumber uid; // Unique serial number | 287 | UniqueSerialNumber uid; // Unique serial number |
| @@ -336,6 +351,18 @@ struct RegisterInfo { | |||
| 336 | }; | 351 | }; |
| 337 | static_assert(sizeof(RegisterInfo) == 0x100, "RegisterInfo is an invalid size"); | 352 | static_assert(sizeof(RegisterInfo) == 0x100, "RegisterInfo is an invalid size"); |
| 338 | 353 | ||
| 354 | struct AdminInfo { | ||
| 355 | u64 application_id; | ||
| 356 | u32 application_area_id; | ||
| 357 | u16 crc_change_counter; | ||
| 358 | u8 flags; | ||
| 359 | PackedTagType tag_type; | ||
| 360 | AppAreaVersion app_area_version; | ||
| 361 | INSERT_PADDING_BYTES(0x7); | ||
| 362 | INSERT_PADDING_BYTES(0x28); | ||
| 363 | }; | ||
| 364 | static_assert(sizeof(AdminInfo) == 0x40, "AdminInfo is an invalid size"); | ||
| 365 | |||
| 339 | struct SectorKey { | 366 | struct SectorKey { |
| 340 | MifareCmd command; | 367 | MifareCmd command; |
| 341 | u8 unknown; // Usually 1 | 368 | u8 unknown; // Usually 1 |
diff --git a/src/core/hle/service/ns/errors.h b/src/core/hle/service/ns/errors.h index 8a7621798..16d2ea6f7 100644 --- a/src/core/hle/service/ns/errors.h +++ b/src/core/hle/service/ns/errors.h | |||
| @@ -7,5 +7,6 @@ | |||
| 7 | 7 | ||
| 8 | namespace Service::NS { | 8 | namespace Service::NS { |
| 9 | 9 | ||
| 10 | constexpr Result ERR_APPLICATION_LANGUAGE_NOT_FOUND{ErrorModule::NS, 300}; | 10 | constexpr Result ResultApplicationLanguageNotFound{ErrorModule::NS, 300}; |
| 11 | } \ No newline at end of file | 11 | |
| 12 | } | ||
diff --git a/src/core/hle/service/ns/ns.cpp b/src/core/hle/service/ns/ns.cpp index d6f0faea2..376067a95 100644 --- a/src/core/hle/service/ns/ns.cpp +++ b/src/core/hle/service/ns/ns.cpp | |||
| @@ -416,14 +416,14 @@ ResultVal<u8> IApplicationManagerInterface::GetApplicationDesiredLanguage( | |||
| 416 | if (application_language == std::nullopt) { | 416 | if (application_language == std::nullopt) { |
| 417 | LOG_ERROR(Service_NS, "Could not convert application language! language_code={}", | 417 | LOG_ERROR(Service_NS, "Could not convert application language! language_code={}", |
| 418 | language_code); | 418 | language_code); |
| 419 | return ERR_APPLICATION_LANGUAGE_NOT_FOUND; | 419 | return Service::NS::ResultApplicationLanguageNotFound; |
| 420 | } | 420 | } |
| 421 | const auto priority_list = GetApplicationLanguagePriorityList(*application_language); | 421 | const auto priority_list = GetApplicationLanguagePriorityList(*application_language); |
| 422 | if (!priority_list) { | 422 | if (!priority_list) { |
| 423 | LOG_ERROR(Service_NS, | 423 | LOG_ERROR(Service_NS, |
| 424 | "Could not find application language priorities! application_language={}", | 424 | "Could not find application language priorities! application_language={}", |
| 425 | *application_language); | 425 | *application_language); |
| 426 | return ERR_APPLICATION_LANGUAGE_NOT_FOUND; | 426 | return Service::NS::ResultApplicationLanguageNotFound; |
| 427 | } | 427 | } |
| 428 | 428 | ||
| 429 | // Try to find a valid language. | 429 | // Try to find a valid language. |
| @@ -436,7 +436,7 @@ ResultVal<u8> IApplicationManagerInterface::GetApplicationDesiredLanguage( | |||
| 436 | 436 | ||
| 437 | LOG_ERROR(Service_NS, "Could not find a valid language! supported_languages={:08X}", | 437 | LOG_ERROR(Service_NS, "Could not find a valid language! supported_languages={:08X}", |
| 438 | supported_languages); | 438 | supported_languages); |
| 439 | return ERR_APPLICATION_LANGUAGE_NOT_FOUND; | 439 | return Service::NS::ResultApplicationLanguageNotFound; |
| 440 | } | 440 | } |
| 441 | 441 | ||
| 442 | void IApplicationManagerInterface::ConvertApplicationLanguageToLanguageCode( | 442 | void IApplicationManagerInterface::ConvertApplicationLanguageToLanguageCode( |
| @@ -461,7 +461,7 @@ ResultVal<u64> IApplicationManagerInterface::ConvertApplicationLanguageToLanguag | |||
| 461 | ConvertToLanguageCode(static_cast<ApplicationLanguage>(application_language)); | 461 | ConvertToLanguageCode(static_cast<ApplicationLanguage>(application_language)); |
| 462 | if (language_code == std::nullopt) { | 462 | if (language_code == std::nullopt) { |
| 463 | LOG_ERROR(Service_NS, "Language not found! application_language={}", application_language); | 463 | LOG_ERROR(Service_NS, "Language not found! application_language={}", application_language); |
| 464 | return ERR_APPLICATION_LANGUAGE_NOT_FOUND; | 464 | return Service::NS::ResultApplicationLanguageNotFound; |
| 465 | } | 465 | } |
| 466 | 466 | ||
| 467 | return static_cast<u64>(*language_code); | 467 | return static_cast<u64>(*language_code); |
diff --git a/src/core/hle/service/server_manager.cpp b/src/core/hle/service/server_manager.cpp index c91f6d880..bd04cd023 100644 --- a/src/core/hle/service/server_manager.cpp +++ b/src/core/hle/service/server_manager.cpp | |||
| @@ -404,7 +404,7 @@ Result ServerManager::CompleteSyncRequest(RequestState&& request) { | |||
| 404 | rc = request.session->SendReplyHLE(); | 404 | rc = request.session->SendReplyHLE(); |
| 405 | 405 | ||
| 406 | // If the session has been closed, we're done. | 406 | // If the session has been closed, we're done. |
| 407 | if (rc == Kernel::ResultSessionClosed || service_rc == IPC::ERR_REMOTE_PROCESS_DEAD) { | 407 | if (rc == Kernel::ResultSessionClosed || service_rc == IPC::ResultSessionClosed) { |
| 408 | // Close the session. | 408 | // Close the session. |
| 409 | request.session->Close(); | 409 | request.session->Close(); |
| 410 | 410 | ||
diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp index eed615377..69cdb5918 100644 --- a/src/core/hle/service/service.cpp +++ b/src/core/hle/service/service.cpp | |||
| @@ -176,7 +176,7 @@ Result ServiceFrameworkBase::HandleSyncRequest(Kernel::KServerSession& session, | |||
| 176 | case IPC::CommandType::TIPC_Close: { | 176 | case IPC::CommandType::TIPC_Close: { |
| 177 | IPC::ResponseBuilder rb{ctx, 2}; | 177 | IPC::ResponseBuilder rb{ctx, 2}; |
| 178 | rb.Push(ResultSuccess); | 178 | rb.Push(ResultSuccess); |
| 179 | result = IPC::ERR_REMOTE_PROCESS_DEAD; | 179 | result = IPC::ResultSessionClosed; |
| 180 | break; | 180 | break; |
| 181 | } | 181 | } |
| 182 | case IPC::CommandType::ControlWithContext: | 182 | case IPC::CommandType::ControlWithContext: |
diff --git a/src/core/hle/service/set/set.cpp b/src/core/hle/service/set/set.cpp index 88df52331..f5788b481 100644 --- a/src/core/hle/service/set/set.cpp +++ b/src/core/hle/service/set/set.cpp | |||
| @@ -74,7 +74,7 @@ constexpr std::array<std::pair<LanguageCode, KeyboardLayout>, 18> language_to_la | |||
| 74 | constexpr std::size_t PRE_4_0_0_MAX_ENTRIES = 0xF; | 74 | constexpr std::size_t PRE_4_0_0_MAX_ENTRIES = 0xF; |
| 75 | constexpr std::size_t POST_4_0_0_MAX_ENTRIES = 0x40; | 75 | constexpr std::size_t POST_4_0_0_MAX_ENTRIES = 0x40; |
| 76 | 76 | ||
| 77 | constexpr Result ERR_INVALID_LANGUAGE{ErrorModule::Settings, 625}; | 77 | constexpr Result ResultInvalidLanguage{ErrorModule::Settings, 625}; |
| 78 | 78 | ||
| 79 | void PushResponseLanguageCode(HLERequestContext& ctx, std::size_t num_language_codes) { | 79 | void PushResponseLanguageCode(HLERequestContext& ctx, std::size_t num_language_codes) { |
| 80 | IPC::ResponseBuilder rb{ctx, 3}; | 80 | IPC::ResponseBuilder rb{ctx, 3}; |
| @@ -130,7 +130,7 @@ void SET::MakeLanguageCode(HLERequestContext& ctx) { | |||
| 130 | if (index >= available_language_codes.size()) { | 130 | if (index >= available_language_codes.size()) { |
| 131 | LOG_ERROR(Service_SET, "Invalid language code index! index={}", index); | 131 | LOG_ERROR(Service_SET, "Invalid language code index! index={}", index); |
| 132 | IPC::ResponseBuilder rb{ctx, 2}; | 132 | IPC::ResponseBuilder rb{ctx, 2}; |
| 133 | rb.Push(ERR_INVALID_LANGUAGE); | 133 | rb.Push(Set::ResultInvalidLanguage); |
| 134 | return; | 134 | return; |
| 135 | } | 135 | } |
| 136 | 136 | ||
diff --git a/src/core/hle/service/sm/sm.cpp b/src/core/hle/service/sm/sm.cpp index a46f47d3e..b4046d3ce 100644 --- a/src/core/hle/service/sm/sm.cpp +++ b/src/core/hle/service/sm/sm.cpp | |||
| @@ -18,10 +18,10 @@ | |||
| 18 | 18 | ||
| 19 | namespace Service::SM { | 19 | namespace Service::SM { |
| 20 | 20 | ||
| 21 | constexpr Result ERR_NOT_INITIALIZED(ErrorModule::SM, 2); | 21 | constexpr Result ResultInvalidClient(ErrorModule::SM, 2); |
| 22 | constexpr Result ERR_ALREADY_REGISTERED(ErrorModule::SM, 4); | 22 | constexpr Result ResultAlreadyRegistered(ErrorModule::SM, 4); |
| 23 | constexpr Result ERR_INVALID_NAME(ErrorModule::SM, 6); | 23 | constexpr Result ResultInvalidServiceName(ErrorModule::SM, 6); |
| 24 | constexpr Result ERR_SERVICE_NOT_REGISTERED(ErrorModule::SM, 7); | 24 | constexpr Result ResultNotRegistered(ErrorModule::SM, 7); |
| 25 | 25 | ||
| 26 | ServiceManager::ServiceManager(Kernel::KernelCore& kernel_) : kernel{kernel_} { | 26 | ServiceManager::ServiceManager(Kernel::KernelCore& kernel_) : kernel{kernel_} { |
| 27 | controller_interface = std::make_unique<Controller>(kernel.System()); | 27 | controller_interface = std::make_unique<Controller>(kernel.System()); |
| @@ -45,7 +45,7 @@ void ServiceManager::InvokeControlRequest(HLERequestContext& context) { | |||
| 45 | static Result ValidateServiceName(const std::string& name) { | 45 | static Result ValidateServiceName(const std::string& name) { |
| 46 | if (name.empty() || name.size() > 8) { | 46 | if (name.empty() || name.size() > 8) { |
| 47 | LOG_ERROR(Service_SM, "Invalid service name! service={}", name); | 47 | LOG_ERROR(Service_SM, "Invalid service name! service={}", name); |
| 48 | return ERR_INVALID_NAME; | 48 | return Service::SM::ResultInvalidServiceName; |
| 49 | } | 49 | } |
| 50 | return ResultSuccess; | 50 | return ResultSuccess; |
| 51 | } | 51 | } |
| @@ -58,7 +58,7 @@ Result ServiceManager::RegisterService(std::string name, u32 max_sessions, | |||
| 58 | std::scoped_lock lk{lock}; | 58 | std::scoped_lock lk{lock}; |
| 59 | if (registered_services.find(name) != registered_services.end()) { | 59 | if (registered_services.find(name) != registered_services.end()) { |
| 60 | LOG_ERROR(Service_SM, "Service is already registered! service={}", name); | 60 | LOG_ERROR(Service_SM, "Service is already registered! service={}", name); |
| 61 | return ERR_ALREADY_REGISTERED; | 61 | return Service::SM::ResultAlreadyRegistered; |
| 62 | } | 62 | } |
| 63 | 63 | ||
| 64 | auto* port = Kernel::KPort::Create(kernel); | 64 | auto* port = Kernel::KPort::Create(kernel); |
| @@ -80,7 +80,7 @@ Result ServiceManager::UnregisterService(const std::string& name) { | |||
| 80 | const auto iter = registered_services.find(name); | 80 | const auto iter = registered_services.find(name); |
| 81 | if (iter == registered_services.end()) { | 81 | if (iter == registered_services.end()) { |
| 82 | LOG_ERROR(Service_SM, "Server is not registered! service={}", name); | 82 | LOG_ERROR(Service_SM, "Server is not registered! service={}", name); |
| 83 | return ERR_SERVICE_NOT_REGISTERED; | 83 | return Service::SM::ResultNotRegistered; |
| 84 | } | 84 | } |
| 85 | 85 | ||
| 86 | registered_services.erase(iter); | 86 | registered_services.erase(iter); |
| @@ -96,7 +96,7 @@ ResultVal<Kernel::KPort*> ServiceManager::GetServicePort(const std::string& name | |||
| 96 | auto it = service_ports.find(name); | 96 | auto it = service_ports.find(name); |
| 97 | if (it == service_ports.end()) { | 97 | if (it == service_ports.end()) { |
| 98 | LOG_WARNING(Service_SM, "Server is not registered! service={}", name); | 98 | LOG_WARNING(Service_SM, "Server is not registered! service={}", name); |
| 99 | return ERR_SERVICE_NOT_REGISTERED; | 99 | return Service::SM::ResultNotRegistered; |
| 100 | } | 100 | } |
| 101 | 101 | ||
| 102 | return it->second; | 102 | return it->second; |
| @@ -160,7 +160,7 @@ static std::string PopServiceName(IPC::RequestParser& rp) { | |||
| 160 | 160 | ||
| 161 | ResultVal<Kernel::KClientSession*> SM::GetServiceImpl(HLERequestContext& ctx) { | 161 | ResultVal<Kernel::KClientSession*> SM::GetServiceImpl(HLERequestContext& ctx) { |
| 162 | if (!ctx.GetManager()->GetIsInitializedForSm()) { | 162 | if (!ctx.GetManager()->GetIsInitializedForSm()) { |
| 163 | return ERR_NOT_INITIALIZED; | 163 | return Service::SM::ResultInvalidClient; |
| 164 | } | 164 | } |
| 165 | 165 | ||
| 166 | IPC::RequestParser rp{ctx}; | 166 | IPC::RequestParser rp{ctx}; |
| @@ -168,15 +168,15 @@ ResultVal<Kernel::KClientSession*> SM::GetServiceImpl(HLERequestContext& ctx) { | |||
| 168 | 168 | ||
| 169 | // Find the named port. | 169 | // Find the named port. |
| 170 | auto port_result = service_manager.GetServicePort(name); | 170 | auto port_result = service_manager.GetServicePort(name); |
| 171 | if (port_result.Code() == ERR_INVALID_NAME) { | 171 | if (port_result.Code() == Service::SM::ResultInvalidServiceName) { |
| 172 | LOG_ERROR(Service_SM, "Invalid service name '{}'", name); | 172 | LOG_ERROR(Service_SM, "Invalid service name '{}'", name); |
| 173 | return ERR_INVALID_NAME; | 173 | return Service::SM::ResultInvalidServiceName; |
| 174 | } | 174 | } |
| 175 | 175 | ||
| 176 | if (port_result.Failed()) { | 176 | if (port_result.Failed()) { |
| 177 | LOG_INFO(Service_SM, "Waiting for service {} to become available", name); | 177 | LOG_INFO(Service_SM, "Waiting for service {} to become available", name); |
| 178 | ctx.SetIsDeferred(); | 178 | ctx.SetIsDeferred(); |
| 179 | return ERR_SERVICE_NOT_REGISTERED; | 179 | return Service::SM::ResultNotRegistered; |
| 180 | } | 180 | } |
| 181 | auto& port = port_result.Unwrap(); | 181 | auto& port = port_result.Unwrap(); |
| 182 | 182 | ||
diff --git a/src/core/perf_stats.cpp b/src/core/perf_stats.cpp index f09c176f8..1231c0dc8 100644 --- a/src/core/perf_stats.cpp +++ b/src/core/perf_stats.cpp | |||
| @@ -126,8 +126,8 @@ double PerfStats::GetLastFrameTimeScale() const { | |||
| 126 | } | 126 | } |
| 127 | 127 | ||
| 128 | void SpeedLimiter::DoSpeedLimiting(microseconds current_system_time_us) { | 128 | void SpeedLimiter::DoSpeedLimiting(microseconds current_system_time_us) { |
| 129 | if (!Settings::values.use_speed_limit.GetValue() || | 129 | if (Settings::values.use_multi_core.GetValue() || |
| 130 | Settings::values.use_multi_core.GetValue()) { | 130 | !Settings::values.use_speed_limit.GetValue()) { |
| 131 | return; | 131 | return; |
| 132 | } | 132 | } |
| 133 | 133 | ||
diff --git a/src/input_common/drivers/joycon.cpp b/src/input_common/drivers/joycon.cpp index b4cd39a20..8b57ebe07 100644 --- a/src/input_common/drivers/joycon.cpp +++ b/src/input_common/drivers/joycon.cpp | |||
| @@ -307,8 +307,8 @@ Common::Input::DriverResult Joycons::SetPollingMode(const PadIdentifier& identif | |||
| 307 | switch (polling_mode) { | 307 | switch (polling_mode) { |
| 308 | case Common::Input::PollingMode::Active: | 308 | case Common::Input::PollingMode::Active: |
| 309 | return static_cast<Common::Input::DriverResult>(handle->SetActiveMode()); | 309 | return static_cast<Common::Input::DriverResult>(handle->SetActiveMode()); |
| 310 | case Common::Input::PollingMode::Pasive: | 310 | case Common::Input::PollingMode::Passive: |
| 311 | return static_cast<Common::Input::DriverResult>(handle->SetPasiveMode()); | 311 | return static_cast<Common::Input::DriverResult>(handle->SetPassiveMode()); |
| 312 | case Common::Input::PollingMode::IR: | 312 | case Common::Input::PollingMode::IR: |
| 313 | return static_cast<Common::Input::DriverResult>(handle->SetIrMode()); | 313 | return static_cast<Common::Input::DriverResult>(handle->SetIrMode()); |
| 314 | case Common::Input::PollingMode::NFC: | 314 | case Common::Input::PollingMode::NFC: |
diff --git a/src/input_common/drivers/mouse.cpp b/src/input_common/drivers/mouse.cpp index 8b7f9aee9..94e92c37d 100644 --- a/src/input_common/drivers/mouse.cpp +++ b/src/input_common/drivers/mouse.cpp | |||
| @@ -3,6 +3,7 @@ | |||
| 3 | 3 | ||
| 4 | #include <thread> | 4 | #include <thread> |
| 5 | #include <fmt/format.h> | 5 | #include <fmt/format.h> |
| 6 | #include <math.h> | ||
| 6 | 7 | ||
| 7 | #include "common/param_package.h" | 8 | #include "common/param_package.h" |
| 8 | #include "common/settings.h" | 9 | #include "common/settings.h" |
| @@ -11,8 +12,9 @@ | |||
| 11 | 12 | ||
| 12 | namespace InputCommon { | 13 | namespace InputCommon { |
| 13 | constexpr int update_time = 10; | 14 | constexpr int update_time = 10; |
| 14 | constexpr float default_stick_sensitivity = 0.022f; | 15 | constexpr float default_stick_sensitivity = 0.0044f; |
| 15 | constexpr float default_motion_sensitivity = 0.008f; | 16 | constexpr float default_motion_sensitivity = 0.0003f; |
| 17 | constexpr float maximum_rotation_speed = 2.0f; | ||
| 16 | constexpr int mouse_axis_x = 0; | 18 | constexpr int mouse_axis_x = 0; |
| 17 | constexpr int mouse_axis_y = 1; | 19 | constexpr int mouse_axis_y = 1; |
| 18 | constexpr int wheel_axis_x = 2; | 20 | constexpr int wheel_axis_x = 2; |
| @@ -99,11 +101,13 @@ void Mouse::UpdateMotionInput() { | |||
| 99 | const float sensitivity = | 101 | const float sensitivity = |
| 100 | Settings::values.mouse_panning_sensitivity.GetValue() * default_motion_sensitivity; | 102 | Settings::values.mouse_panning_sensitivity.GetValue() * default_motion_sensitivity; |
| 101 | 103 | ||
| 102 | // Slow movement by 7% | 104 | const float rotation_velocity = std::sqrt(last_motion_change.x * last_motion_change.x + |
| 103 | if (Settings::values.mouse_panning) { | 105 | last_motion_change.y * last_motion_change.y); |
| 104 | last_motion_change *= 0.93f; | 106 | |
| 105 | } else { | 107 | if (rotation_velocity > maximum_rotation_speed / sensitivity) { |
| 106 | last_motion_change.z *= 0.93f; | 108 | const float multiplier = maximum_rotation_speed / rotation_velocity / sensitivity; |
| 109 | last_motion_change.x = last_motion_change.x * multiplier; | ||
| 110 | last_motion_change.y = last_motion_change.y * multiplier; | ||
| 107 | } | 111 | } |
| 108 | 112 | ||
| 109 | const BasicMotion motion_data{ | 113 | const BasicMotion motion_data{ |
| @@ -116,6 +120,12 @@ void Mouse::UpdateMotionInput() { | |||
| 116 | .delta_timestamp = update_time * 1000, | 120 | .delta_timestamp = update_time * 1000, |
| 117 | }; | 121 | }; |
| 118 | 122 | ||
| 123 | if (Settings::values.mouse_panning) { | ||
| 124 | last_motion_change.x = 0; | ||
| 125 | last_motion_change.y = 0; | ||
| 126 | } | ||
| 127 | last_motion_change.z = 0; | ||
| 128 | |||
| 119 | SetMotion(motion_identifier, 0, motion_data); | 129 | SetMotion(motion_identifier, 0, motion_data); |
| 120 | } | 130 | } |
| 121 | 131 | ||
| @@ -125,7 +135,7 @@ void Mouse::Move(int x, int y, int center_x, int center_y) { | |||
| 125 | 135 | ||
| 126 | auto mouse_change = | 136 | auto mouse_change = |
| 127 | (Common::MakeVec(x, y) - Common::MakeVec(center_x, center_y)).Cast<float>(); | 137 | (Common::MakeVec(x, y) - Common::MakeVec(center_x, center_y)).Cast<float>(); |
| 128 | Common::Vec3<float> motion_change{-mouse_change.y, -mouse_change.x, last_motion_change.z}; | 138 | last_motion_change += {-mouse_change.y, -mouse_change.x, last_motion_change.z}; |
| 129 | 139 | ||
| 130 | const auto move_distance = mouse_change.Length(); | 140 | const auto move_distance = mouse_change.Length(); |
| 131 | if (move_distance == 0) { | 141 | if (move_distance == 0) { |
| @@ -141,7 +151,6 @@ void Mouse::Move(int x, int y, int center_x, int center_y) { | |||
| 141 | 151 | ||
| 142 | // Average mouse movements | 152 | // Average mouse movements |
| 143 | last_mouse_change = (last_mouse_change * 0.91f) + (mouse_change * 0.09f); | 153 | last_mouse_change = (last_mouse_change * 0.91f) + (mouse_change * 0.09f); |
| 144 | last_motion_change = (last_motion_change * 0.69f) + (motion_change * 0.31f); | ||
| 145 | 154 | ||
| 146 | const auto last_move_distance = last_mouse_change.Length(); | 155 | const auto last_move_distance = last_mouse_change.Length(); |
| 147 | 156 | ||
diff --git a/src/input_common/drivers/virtual_amiibo.h b/src/input_common/drivers/virtual_amiibo.h index 13cacfc0a..488d00b31 100644 --- a/src/input_common/drivers/virtual_amiibo.h +++ b/src/input_common/drivers/virtual_amiibo.h | |||
| @@ -60,6 +60,6 @@ private: | |||
| 60 | std::string file_path{}; | 60 | std::string file_path{}; |
| 61 | State state{State::Initialized}; | 61 | State state{State::Initialized}; |
| 62 | std::vector<u8> nfc_data; | 62 | std::vector<u8> nfc_data; |
| 63 | Common::Input::PollingMode polling_mode{Common::Input::PollingMode::Pasive}; | 63 | Common::Input::PollingMode polling_mode{Common::Input::PollingMode::Passive}; |
| 64 | }; | 64 | }; |
| 65 | } // namespace InputCommon | 65 | } // namespace InputCommon |
diff --git a/src/input_common/helpers/joycon_driver.cpp b/src/input_common/helpers/joycon_driver.cpp index e65b6b845..78cc5893c 100644 --- a/src/input_common/helpers/joycon_driver.cpp +++ b/src/input_common/helpers/joycon_driver.cpp | |||
| @@ -410,7 +410,7 @@ DriverResult JoyconDriver::SetIrsConfig(IrsMode mode_, IrsResolution format_) { | |||
| 410 | return result; | 410 | return result; |
| 411 | } | 411 | } |
| 412 | 412 | ||
| 413 | DriverResult JoyconDriver::SetPasiveMode() { | 413 | DriverResult JoyconDriver::SetPassiveMode() { |
| 414 | std::scoped_lock lock{mutex}; | 414 | std::scoped_lock lock{mutex}; |
| 415 | motion_enabled = false; | 415 | motion_enabled = false; |
| 416 | hidbus_enabled = false; | 416 | hidbus_enabled = false; |
diff --git a/src/input_common/helpers/joycon_driver.h b/src/input_common/helpers/joycon_driver.h index c1e189fa5..b52a13ecf 100644 --- a/src/input_common/helpers/joycon_driver.h +++ b/src/input_common/helpers/joycon_driver.h | |||
| @@ -44,7 +44,7 @@ public: | |||
| 44 | DriverResult SetVibration(const VibrationValue& vibration); | 44 | DriverResult SetVibration(const VibrationValue& vibration); |
| 45 | DriverResult SetLedConfig(u8 led_pattern); | 45 | DriverResult SetLedConfig(u8 led_pattern); |
| 46 | DriverResult SetIrsConfig(IrsMode mode_, IrsResolution format_); | 46 | DriverResult SetIrsConfig(IrsMode mode_, IrsResolution format_); |
| 47 | DriverResult SetPasiveMode(); | 47 | DriverResult SetPassiveMode(); |
| 48 | DriverResult SetActiveMode(); | 48 | DriverResult SetActiveMode(); |
| 49 | DriverResult SetIrMode(); | 49 | DriverResult SetIrMode(); |
| 50 | DriverResult SetNfcMode(); | 50 | DriverResult SetNfcMode(); |
diff --git a/src/input_common/helpers/joycon_protocol/joycon_types.h b/src/input_common/helpers/joycon_protocol/joycon_types.h index 2e50a99a8..dcac0e422 100644 --- a/src/input_common/helpers/joycon_protocol/joycon_types.h +++ b/src/input_common/helpers/joycon_protocol/joycon_types.h | |||
| @@ -78,7 +78,7 @@ enum class PadButton : u32 { | |||
| 78 | Capture = 0x200000, | 78 | Capture = 0x200000, |
| 79 | }; | 79 | }; |
| 80 | 80 | ||
| 81 | enum class PasivePadButton : u32 { | 81 | enum class PassivePadButton : u32 { |
| 82 | Down_A = 0x0001, | 82 | Down_A = 0x0001, |
| 83 | Right_X = 0x0002, | 83 | Right_X = 0x0002, |
| 84 | Left_B = 0x0004, | 84 | Left_B = 0x0004, |
| @@ -95,7 +95,7 @@ enum class PasivePadButton : u32 { | |||
| 95 | ZL_ZR = 0x8000, | 95 | ZL_ZR = 0x8000, |
| 96 | }; | 96 | }; |
| 97 | 97 | ||
| 98 | enum class PasivePadStick : u8 { | 98 | enum class PassivePadStick : u8 { |
| 99 | Right = 0x00, | 99 | Right = 0x00, |
| 100 | RightDown = 0x01, | 100 | RightDown = 0x01, |
| 101 | Down = 0x02, | 101 | Down = 0x02, |
diff --git a/src/input_common/helpers/joycon_protocol/poller.cpp b/src/input_common/helpers/joycon_protocol/poller.cpp index ab48352b8..dca797f7a 100644 --- a/src/input_common/helpers/joycon_protocol/poller.cpp +++ b/src/input_common/helpers/joycon_protocol/poller.cpp | |||
| @@ -48,13 +48,13 @@ void JoyconPoller::ReadPassiveMode(std::span<u8> buffer) { | |||
| 48 | 48 | ||
| 49 | switch (device_type) { | 49 | switch (device_type) { |
| 50 | case ControllerType::Left: | 50 | case ControllerType::Left: |
| 51 | UpdatePasiveLeftPadInput(data); | 51 | UpdatePassiveLeftPadInput(data); |
| 52 | break; | 52 | break; |
| 53 | case ControllerType::Right: | 53 | case ControllerType::Right: |
| 54 | UpdatePasiveRightPadInput(data); | 54 | UpdatePassiveRightPadInput(data); |
| 55 | break; | 55 | break; |
| 56 | case ControllerType::Pro: | 56 | case ControllerType::Pro: |
| 57 | UpdatePasiveProPadInput(data); | 57 | UpdatePassiveProPadInput(data); |
| 58 | break; | 58 | break; |
| 59 | default: | 59 | default: |
| 60 | break; | 60 | break; |
| @@ -210,12 +210,12 @@ void JoyconPoller::UpdateActiveProPadInput(const InputReportActive& input, | |||
| 210 | } | 210 | } |
| 211 | } | 211 | } |
| 212 | 212 | ||
| 213 | void JoyconPoller::UpdatePasiveLeftPadInput(const InputReportPassive& input) { | 213 | void JoyconPoller::UpdatePassiveLeftPadInput(const InputReportPassive& input) { |
| 214 | static constexpr std::array<PasivePadButton, 11> left_buttons{ | 214 | static constexpr std::array<PassivePadButton, 11> left_buttons{ |
| 215 | PasivePadButton::Down_A, PasivePadButton::Right_X, PasivePadButton::Left_B, | 215 | PassivePadButton::Down_A, PassivePadButton::Right_X, PassivePadButton::Left_B, |
| 216 | PasivePadButton::Up_Y, PasivePadButton::SL, PasivePadButton::SR, | 216 | PassivePadButton::Up_Y, PassivePadButton::SL, PassivePadButton::SR, |
| 217 | PasivePadButton::L_R, PasivePadButton::ZL_ZR, PasivePadButton::Minus, | 217 | PassivePadButton::L_R, PassivePadButton::ZL_ZR, PassivePadButton::Minus, |
| 218 | PasivePadButton::Capture, PasivePadButton::StickL, | 218 | PassivePadButton::Capture, PassivePadButton::StickL, |
| 219 | }; | 219 | }; |
| 220 | 220 | ||
| 221 | for (auto left_button : left_buttons) { | 221 | for (auto left_button : left_buttons) { |
| @@ -225,17 +225,17 @@ void JoyconPoller::UpdatePasiveLeftPadInput(const InputReportPassive& input) { | |||
| 225 | } | 225 | } |
| 226 | 226 | ||
| 227 | const auto [left_axis_x, left_axis_y] = | 227 | const auto [left_axis_x, left_axis_y] = |
| 228 | GetPassiveAxisValue(static_cast<PasivePadStick>(input.stick_state)); | 228 | GetPassiveAxisValue(static_cast<PassivePadStick>(input.stick_state)); |
| 229 | callbacks.on_stick_data(static_cast<int>(PadAxes::LeftStickX), left_axis_x); | 229 | callbacks.on_stick_data(static_cast<int>(PadAxes::LeftStickX), left_axis_x); |
| 230 | callbacks.on_stick_data(static_cast<int>(PadAxes::LeftStickY), left_axis_y); | 230 | callbacks.on_stick_data(static_cast<int>(PadAxes::LeftStickY), left_axis_y); |
| 231 | } | 231 | } |
| 232 | 232 | ||
| 233 | void JoyconPoller::UpdatePasiveRightPadInput(const InputReportPassive& input) { | 233 | void JoyconPoller::UpdatePassiveRightPadInput(const InputReportPassive& input) { |
| 234 | static constexpr std::array<PasivePadButton, 11> right_buttons{ | 234 | static constexpr std::array<PassivePadButton, 11> right_buttons{ |
| 235 | PasivePadButton::Down_A, PasivePadButton::Right_X, PasivePadButton::Left_B, | 235 | PassivePadButton::Down_A, PassivePadButton::Right_X, PassivePadButton::Left_B, |
| 236 | PasivePadButton::Up_Y, PasivePadButton::SL, PasivePadButton::SR, | 236 | PassivePadButton::Up_Y, PassivePadButton::SL, PassivePadButton::SR, |
| 237 | PasivePadButton::L_R, PasivePadButton::ZL_ZR, PasivePadButton::Plus, | 237 | PassivePadButton::L_R, PassivePadButton::ZL_ZR, PassivePadButton::Plus, |
| 238 | PasivePadButton::Home, PasivePadButton::StickR, | 238 | PassivePadButton::Home, PassivePadButton::StickR, |
| 239 | }; | 239 | }; |
| 240 | 240 | ||
| 241 | for (auto right_button : right_buttons) { | 241 | for (auto right_button : right_buttons) { |
| @@ -245,18 +245,18 @@ void JoyconPoller::UpdatePasiveRightPadInput(const InputReportPassive& input) { | |||
| 245 | } | 245 | } |
| 246 | 246 | ||
| 247 | const auto [right_axis_x, right_axis_y] = | 247 | const auto [right_axis_x, right_axis_y] = |
| 248 | GetPassiveAxisValue(static_cast<PasivePadStick>(input.stick_state)); | 248 | GetPassiveAxisValue(static_cast<PassivePadStick>(input.stick_state)); |
| 249 | callbacks.on_stick_data(static_cast<int>(PadAxes::RightStickX), right_axis_x); | 249 | callbacks.on_stick_data(static_cast<int>(PadAxes::RightStickX), right_axis_x); |
| 250 | callbacks.on_stick_data(static_cast<int>(PadAxes::RightStickY), right_axis_y); | 250 | callbacks.on_stick_data(static_cast<int>(PadAxes::RightStickY), right_axis_y); |
| 251 | } | 251 | } |
| 252 | 252 | ||
| 253 | void JoyconPoller::UpdatePasiveProPadInput(const InputReportPassive& input) { | 253 | void JoyconPoller::UpdatePassiveProPadInput(const InputReportPassive& input) { |
| 254 | static constexpr std::array<PasivePadButton, 14> pro_buttons{ | 254 | static constexpr std::array<PassivePadButton, 14> pro_buttons{ |
| 255 | PasivePadButton::Down_A, PasivePadButton::Right_X, PasivePadButton::Left_B, | 255 | PassivePadButton::Down_A, PassivePadButton::Right_X, PassivePadButton::Left_B, |
| 256 | PasivePadButton::Up_Y, PasivePadButton::SL, PasivePadButton::SR, | 256 | PassivePadButton::Up_Y, PassivePadButton::SL, PassivePadButton::SR, |
| 257 | PasivePadButton::L_R, PasivePadButton::ZL_ZR, PasivePadButton::Minus, | 257 | PassivePadButton::L_R, PassivePadButton::ZL_ZR, PassivePadButton::Minus, |
| 258 | PasivePadButton::Plus, PasivePadButton::Capture, PasivePadButton::Home, | 258 | PassivePadButton::Plus, PassivePadButton::Capture, PassivePadButton::Home, |
| 259 | PasivePadButton::StickL, PasivePadButton::StickR, | 259 | PassivePadButton::StickL, PassivePadButton::StickR, |
| 260 | }; | 260 | }; |
| 261 | 261 | ||
| 262 | for (auto pro_button : pro_buttons) { | 262 | for (auto pro_button : pro_buttons) { |
| @@ -266,9 +266,9 @@ void JoyconPoller::UpdatePasiveProPadInput(const InputReportPassive& input) { | |||
| 266 | } | 266 | } |
| 267 | 267 | ||
| 268 | const auto [left_axis_x, left_axis_y] = | 268 | const auto [left_axis_x, left_axis_y] = |
| 269 | GetPassiveAxisValue(static_cast<PasivePadStick>(input.stick_state && 0xf)); | 269 | GetPassiveAxisValue(static_cast<PassivePadStick>(input.stick_state & 0xf)); |
| 270 | const auto [right_axis_x, right_axis_y] = | 270 | const auto [right_axis_x, right_axis_y] = |
| 271 | GetPassiveAxisValue(static_cast<PasivePadStick>(input.stick_state >> 4)); | 271 | GetPassiveAxisValue(static_cast<PassivePadStick>(input.stick_state >> 4)); |
| 272 | callbacks.on_stick_data(static_cast<int>(PadAxes::LeftStickX), left_axis_x); | 272 | callbacks.on_stick_data(static_cast<int>(PadAxes::LeftStickX), left_axis_x); |
| 273 | callbacks.on_stick_data(static_cast<int>(PadAxes::LeftStickY), left_axis_y); | 273 | callbacks.on_stick_data(static_cast<int>(PadAxes::LeftStickY), left_axis_y); |
| 274 | callbacks.on_stick_data(static_cast<int>(PadAxes::RightStickX), right_axis_x); | 274 | callbacks.on_stick_data(static_cast<int>(PadAxes::RightStickX), right_axis_x); |
| @@ -283,25 +283,25 @@ f32 JoyconPoller::GetAxisValue(u16 raw_value, Joycon::JoyStickAxisCalibration ca | |||
| 283 | return value / calibration.min; | 283 | return value / calibration.min; |
| 284 | } | 284 | } |
| 285 | 285 | ||
| 286 | std::pair<f32, f32> JoyconPoller::GetPassiveAxisValue(PasivePadStick raw_value) const { | 286 | std::pair<f32, f32> JoyconPoller::GetPassiveAxisValue(PassivePadStick raw_value) const { |
| 287 | switch (raw_value) { | 287 | switch (raw_value) { |
| 288 | case PasivePadStick::Right: | 288 | case PassivePadStick::Right: |
| 289 | return {1.0f, 0.0f}; | 289 | return {1.0f, 0.0f}; |
| 290 | case PasivePadStick::RightDown: | 290 | case PassivePadStick::RightDown: |
| 291 | return {1.0f, -1.0f}; | 291 | return {1.0f, -1.0f}; |
| 292 | case PasivePadStick::Down: | 292 | case PassivePadStick::Down: |
| 293 | return {0.0f, -1.0f}; | 293 | return {0.0f, -1.0f}; |
| 294 | case PasivePadStick::DownLeft: | 294 | case PassivePadStick::DownLeft: |
| 295 | return {-1.0f, -1.0f}; | 295 | return {-1.0f, -1.0f}; |
| 296 | case PasivePadStick::Left: | 296 | case PassivePadStick::Left: |
| 297 | return {-1.0f, 0.0f}; | 297 | return {-1.0f, 0.0f}; |
| 298 | case PasivePadStick::LeftUp: | 298 | case PassivePadStick::LeftUp: |
| 299 | return {-1.0f, 1.0f}; | 299 | return {-1.0f, 1.0f}; |
| 300 | case PasivePadStick::Up: | 300 | case PassivePadStick::Up: |
| 301 | return {0.0f, 1.0f}; | 301 | return {0.0f, 1.0f}; |
| 302 | case PasivePadStick::UpRight: | 302 | case PassivePadStick::UpRight: |
| 303 | return {1.0f, 1.0f}; | 303 | return {1.0f, 1.0f}; |
| 304 | case PasivePadStick::Neutral: | 304 | case PassivePadStick::Neutral: |
| 305 | default: | 305 | default: |
| 306 | return {0.0f, 0.0f}; | 306 | return {0.0f, 0.0f}; |
| 307 | } | 307 | } |
diff --git a/src/input_common/helpers/joycon_protocol/poller.h b/src/input_common/helpers/joycon_protocol/poller.h index 5c897f070..0fa72c6db 100644 --- a/src/input_common/helpers/joycon_protocol/poller.h +++ b/src/input_common/helpers/joycon_protocol/poller.h | |||
| @@ -46,15 +46,15 @@ private: | |||
| 46 | const MotionStatus& motion_status); | 46 | const MotionStatus& motion_status); |
| 47 | void UpdateActiveProPadInput(const InputReportActive& input, const MotionStatus& motion_status); | 47 | void UpdateActiveProPadInput(const InputReportActive& input, const MotionStatus& motion_status); |
| 48 | 48 | ||
| 49 | void UpdatePasiveLeftPadInput(const InputReportPassive& buffer); | 49 | void UpdatePassiveLeftPadInput(const InputReportPassive& buffer); |
| 50 | void UpdatePasiveRightPadInput(const InputReportPassive& buffer); | 50 | void UpdatePassiveRightPadInput(const InputReportPassive& buffer); |
| 51 | void UpdatePasiveProPadInput(const InputReportPassive& buffer); | 51 | void UpdatePassiveProPadInput(const InputReportPassive& buffer); |
| 52 | 52 | ||
| 53 | /// Returns a calibrated joystick axis from raw axis data | 53 | /// Returns a calibrated joystick axis from raw axis data |
| 54 | f32 GetAxisValue(u16 raw_value, JoyStickAxisCalibration calibration) const; | 54 | f32 GetAxisValue(u16 raw_value, JoyStickAxisCalibration calibration) const; |
| 55 | 55 | ||
| 56 | /// Returns a digital joystick axis from passive axis data | 56 | /// Returns a digital joystick axis from passive axis data |
| 57 | std::pair<f32, f32> GetPassiveAxisValue(PasivePadStick raw_value) const; | 57 | std::pair<f32, f32> GetPassiveAxisValue(PassivePadStick raw_value) const; |
| 58 | 58 | ||
| 59 | /// Returns a calibrated accelerometer axis from raw motion data | 59 | /// Returns a calibrated accelerometer axis from raw motion data |
| 60 | f32 GetAccelerometerValue(s16 raw, const MotionSensorCalibration& cal, | 60 | f32 GetAccelerometerValue(s16 raw, const MotionSensorCalibration& cal, |
diff --git a/src/input_common/input_mapping.cpp b/src/input_common/input_mapping.cpp index 2ff480ff9..9361b00c5 100644 --- a/src/input_common/input_mapping.cpp +++ b/src/input_common/input_mapping.cpp | |||
| @@ -146,6 +146,7 @@ void MappingFactory::RegisterMotion(const MappingData& data) { | |||
| 146 | if (data.engine == "mouse") { | 146 | if (data.engine == "mouse") { |
| 147 | new_input.Set("motion", 0); | 147 | new_input.Set("motion", 0); |
| 148 | new_input.Set("pad", 1); | 148 | new_input.Set("pad", 1); |
| 149 | new_input.Set("threshold", 0.001f); | ||
| 149 | input_queue.Push(new_input); | 150 | input_queue.Push(new_input); |
| 150 | return; | 151 | return; |
| 151 | } | 152 | } |
diff --git a/src/shader_recompiler/ir_opt/global_memory_to_storage_buffer_pass.cpp b/src/shader_recompiler/ir_opt/global_memory_to_storage_buffer_pass.cpp index 336338e62..d1e59f22e 100644 --- a/src/shader_recompiler/ir_opt/global_memory_to_storage_buffer_pass.cpp +++ b/src/shader_recompiler/ir_opt/global_memory_to_storage_buffer_pass.cpp | |||
| @@ -35,6 +35,7 @@ struct Bias { | |||
| 35 | u32 index; | 35 | u32 index; |
| 36 | u32 offset_begin; | 36 | u32 offset_begin; |
| 37 | u32 offset_end; | 37 | u32 offset_end; |
| 38 | u32 alignment; | ||
| 38 | }; | 39 | }; |
| 39 | 40 | ||
| 40 | using boost::container::flat_set; | 41 | using boost::container::flat_set; |
| @@ -349,7 +350,8 @@ std::optional<StorageBufferAddr> Track(const IR::Value& value, const Bias* bias) | |||
| 349 | .index = index.U32(), | 350 | .index = index.U32(), |
| 350 | .offset = offset.U32(), | 351 | .offset = offset.U32(), |
| 351 | }; | 352 | }; |
| 352 | if (!Common::IsAligned(storage_buffer.offset, 16)) { | 353 | const u32 alignment{bias ? bias->alignment : 8U}; |
| 354 | if (!Common::IsAligned(storage_buffer.offset, alignment)) { | ||
| 353 | // The SSBO pointer has to be aligned | 355 | // The SSBO pointer has to be aligned |
| 354 | return std::nullopt; | 356 | return std::nullopt; |
| 355 | } | 357 | } |
| @@ -371,6 +373,7 @@ void CollectStorageBuffers(IR::Block& block, IR::Inst& inst, StorageInfo& info) | |||
| 371 | .index = 0, | 373 | .index = 0, |
| 372 | .offset_begin = 0x110, | 374 | .offset_begin = 0x110, |
| 373 | .offset_end = 0x610, | 375 | .offset_end = 0x610, |
| 376 | .alignment = 16, | ||
| 374 | }; | 377 | }; |
| 375 | // Track the low address of the instruction | 378 | // Track the low address of the instruction |
| 376 | const std::optional<LowAddrInfo> low_addr_info{TrackLowAddress(&inst)}; | 379 | const std::optional<LowAddrInfo> low_addr_info{TrackLowAddress(&inst)}; |
| @@ -386,8 +389,11 @@ void CollectStorageBuffers(IR::Block& block, IR::Inst& inst, StorageInfo& info) | |||
| 386 | storage_buffer = Track(low_addr, nullptr); | 389 | storage_buffer = Track(low_addr, nullptr); |
| 387 | if (!storage_buffer) { | 390 | if (!storage_buffer) { |
| 388 | // If that also fails, use NVN fallbacks | 391 | // If that also fails, use NVN fallbacks |
| 392 | LOG_WARNING(Shader, "Storage buffer failed to track, using global memory fallbacks"); | ||
| 389 | return; | 393 | return; |
| 390 | } | 394 | } |
| 395 | LOG_WARNING(Shader, "Storage buffer tracked without bias, index {} offset {}", | ||
| 396 | storage_buffer->index, storage_buffer->offset); | ||
| 391 | } | 397 | } |
| 392 | // Collect storage buffer and the instruction | 398 | // Collect storage buffer and the instruction |
| 393 | if (IsGlobalMemoryWrite(inst)) { | 399 | if (IsGlobalMemoryWrite(inst)) { |
diff --git a/src/video_core/buffer_cache/buffer_cache.h b/src/video_core/buffer_cache/buffer_cache.h index 2a150ccdc..1f656ffa8 100644 --- a/src/video_core/buffer_cache/buffer_cache.h +++ b/src/video_core/buffer_cache/buffer_cache.h | |||
| @@ -383,7 +383,8 @@ private: | |||
| 383 | 383 | ||
| 384 | void NotifyBufferDeletion(); | 384 | void NotifyBufferDeletion(); |
| 385 | 385 | ||
| 386 | [[nodiscard]] Binding StorageBufferBinding(GPUVAddr ssbo_addr, bool is_written = false) const; | 386 | [[nodiscard]] Binding StorageBufferBinding(GPUVAddr ssbo_addr, u32 cbuf_index, |
| 387 | bool is_written = false) const; | ||
| 387 | 388 | ||
| 388 | [[nodiscard]] TextureBufferBinding GetTextureBufferBinding(GPUVAddr gpu_addr, u32 size, | 389 | [[nodiscard]] TextureBufferBinding GetTextureBufferBinding(GPUVAddr gpu_addr, u32 size, |
| 389 | PixelFormat format); | 390 | PixelFormat format); |
| @@ -802,7 +803,7 @@ void BufferCache<P>::BindGraphicsStorageBuffer(size_t stage, size_t ssbo_index, | |||
| 802 | 803 | ||
| 803 | const auto& cbufs = maxwell3d->state.shader_stages[stage]; | 804 | const auto& cbufs = maxwell3d->state.shader_stages[stage]; |
| 804 | const GPUVAddr ssbo_addr = cbufs.const_buffers[cbuf_index].address + cbuf_offset; | 805 | const GPUVAddr ssbo_addr = cbufs.const_buffers[cbuf_index].address + cbuf_offset; |
| 805 | storage_buffers[stage][ssbo_index] = StorageBufferBinding(ssbo_addr, is_written); | 806 | storage_buffers[stage][ssbo_index] = StorageBufferBinding(ssbo_addr, cbuf_index, is_written); |
| 806 | } | 807 | } |
| 807 | 808 | ||
| 808 | template <class P> | 809 | template <class P> |
| @@ -842,7 +843,7 @@ void BufferCache<P>::BindComputeStorageBuffer(size_t ssbo_index, u32 cbuf_index, | |||
| 842 | 843 | ||
| 843 | const auto& cbufs = launch_desc.const_buffer_config; | 844 | const auto& cbufs = launch_desc.const_buffer_config; |
| 844 | const GPUVAddr ssbo_addr = cbufs[cbuf_index].Address() + cbuf_offset; | 845 | const GPUVAddr ssbo_addr = cbufs[cbuf_index].Address() + cbuf_offset; |
| 845 | compute_storage_buffers[ssbo_index] = StorageBufferBinding(ssbo_addr, is_written); | 846 | compute_storage_buffers[ssbo_index] = StorageBufferBinding(ssbo_addr, cbuf_index, is_written); |
| 846 | } | 847 | } |
| 847 | 848 | ||
| 848 | template <class P> | 849 | template <class P> |
| @@ -1988,11 +1989,26 @@ void BufferCache<P>::NotifyBufferDeletion() { | |||
| 1988 | 1989 | ||
| 1989 | template <class P> | 1990 | template <class P> |
| 1990 | typename BufferCache<P>::Binding BufferCache<P>::StorageBufferBinding(GPUVAddr ssbo_addr, | 1991 | typename BufferCache<P>::Binding BufferCache<P>::StorageBufferBinding(GPUVAddr ssbo_addr, |
| 1992 | u32 cbuf_index, | ||
| 1991 | bool is_written) const { | 1993 | bool is_written) const { |
| 1992 | const GPUVAddr gpu_addr = gpu_memory->Read<u64>(ssbo_addr); | 1994 | const GPUVAddr gpu_addr = gpu_memory->Read<u64>(ssbo_addr); |
| 1993 | const u32 size = gpu_memory->Read<u32>(ssbo_addr + 8); | 1995 | const auto size = [&]() { |
| 1996 | const bool is_nvn_cbuf = cbuf_index == 0; | ||
| 1997 | // The NVN driver buffer (index 0) is known to pack the SSBO address followed by its size. | ||
| 1998 | if (is_nvn_cbuf) { | ||
| 1999 | return gpu_memory->Read<u32>(ssbo_addr + 8); | ||
| 2000 | } | ||
| 2001 | // Other titles (notably Doom Eternal) may use STG/LDG on buffer addresses in custom defined | ||
| 2002 | // cbufs, which do not store the sizes adjacent to the addresses, so use the fully | ||
| 2003 | // mapped buffer size for now. | ||
| 2004 | const u32 memory_layout_size = static_cast<u32>(gpu_memory->GetMemoryLayoutSize(gpu_addr)); | ||
| 2005 | LOG_INFO(HW_GPU, "Binding storage buffer for cbuf index {}, MemoryLayoutSize 0x{:X}", | ||
| 2006 | cbuf_index, memory_layout_size); | ||
| 2007 | return memory_layout_size; | ||
| 2008 | }(); | ||
| 1994 | const std::optional<VAddr> cpu_addr = gpu_memory->GpuToCpuAddress(gpu_addr); | 2009 | const std::optional<VAddr> cpu_addr = gpu_memory->GpuToCpuAddress(gpu_addr); |
| 1995 | if (!cpu_addr || size == 0) { | 2010 | if (!cpu_addr || size == 0) { |
| 2011 | LOG_WARNING(HW_GPU, "Failed to find storage buffer for cbuf index {}", cbuf_index); | ||
| 1996 | return NULL_BINDING; | 2012 | return NULL_BINDING; |
| 1997 | } | 2013 | } |
| 1998 | const VAddr cpu_end = Common::AlignUp(*cpu_addr + size, Core::Memory::YUZU_PAGESIZE); | 2014 | const VAddr cpu_end = Common::AlignUp(*cpu_addr + size, Core::Memory::YUZU_PAGESIZE); |
diff --git a/src/video_core/gpu_thread.cpp b/src/video_core/gpu_thread.cpp index 9c103c0d4..050b11874 100644 --- a/src/video_core/gpu_thread.cpp +++ b/src/video_core/gpu_thread.cpp | |||
| @@ -25,7 +25,7 @@ static void RunThread(std::stop_token stop_token, Core::System& system, | |||
| 25 | SCOPE_EXIT({ MicroProfileOnThreadExit(); }); | 25 | SCOPE_EXIT({ MicroProfileOnThreadExit(); }); |
| 26 | 26 | ||
| 27 | Common::SetCurrentThreadName(name.c_str()); | 27 | Common::SetCurrentThreadName(name.c_str()); |
| 28 | Common::SetCurrentThreadPriority(Common::ThreadPriority::High); | 28 | Common::SetCurrentThreadPriority(Common::ThreadPriority::Critical); |
| 29 | system.RegisterHostThread(); | 29 | system.RegisterHostThread(); |
| 30 | 30 | ||
| 31 | auto current_context = context.Acquire(); | 31 | auto current_context = context.Acquire(); |
diff --git a/src/video_core/renderer_opengl/gl_fence_manager.cpp b/src/video_core/renderer_opengl/gl_fence_manager.cpp index 91463f854..5326172af 100644 --- a/src/video_core/renderer_opengl/gl_fence_manager.cpp +++ b/src/video_core/renderer_opengl/gl_fence_manager.cpp | |||
| @@ -27,9 +27,7 @@ bool GLInnerFence::IsSignaled() const { | |||
| 27 | return true; | 27 | return true; |
| 28 | } | 28 | } |
| 29 | ASSERT(sync_object.handle != 0); | 29 | ASSERT(sync_object.handle != 0); |
| 30 | GLint sync_status; | 30 | return sync_object.IsSignaled(); |
| 31 | glGetSynciv(sync_object.handle, GL_SYNC_STATUS, 1, nullptr, &sync_status); | ||
| 32 | return sync_status == GL_SIGNALED; | ||
| 33 | } | 31 | } |
| 34 | 32 | ||
| 35 | void GLInnerFence::Wait() { | 33 | void GLInnerFence::Wait() { |
diff --git a/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp b/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp index 29491e762..89000d6e0 100644 --- a/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp +++ b/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp | |||
| @@ -621,10 +621,7 @@ bool GraphicsPipeline::IsBuilt() noexcept { | |||
| 621 | if (built_fence.handle == 0) { | 621 | if (built_fence.handle == 0) { |
| 622 | return false; | 622 | return false; |
| 623 | } | 623 | } |
| 624 | // Timeout of zero means this is non-blocking | 624 | is_built = built_fence.IsSignaled(); |
| 625 | const auto sync_status = glClientWaitSync(built_fence.handle, 0, 0); | ||
| 626 | ASSERT(sync_status != GL_WAIT_FAILED); | ||
| 627 | is_built = sync_status != GL_TIMEOUT_EXPIRED; | ||
| 628 | return is_built; | 625 | return is_built; |
| 629 | } | 626 | } |
| 630 | 627 | ||
diff --git a/src/video_core/renderer_opengl/gl_resource_manager.cpp b/src/video_core/renderer_opengl/gl_resource_manager.cpp index 3a664fdec..eae8fd110 100644 --- a/src/video_core/renderer_opengl/gl_resource_manager.cpp +++ b/src/video_core/renderer_opengl/gl_resource_manager.cpp | |||
| @@ -3,6 +3,7 @@ | |||
| 3 | 3 | ||
| 4 | #include <string_view> | 4 | #include <string_view> |
| 5 | #include <glad/glad.h> | 5 | #include <glad/glad.h> |
| 6 | #include "common/assert.h" | ||
| 6 | #include "common/microprofile.h" | 7 | #include "common/microprofile.h" |
| 7 | #include "video_core/renderer_opengl/gl_resource_manager.h" | 8 | #include "video_core/renderer_opengl/gl_resource_manager.h" |
| 8 | #include "video_core/renderer_opengl/gl_shader_util.h" | 9 | #include "video_core/renderer_opengl/gl_shader_util.h" |
| @@ -158,6 +159,15 @@ void OGLSync::Release() { | |||
| 158 | handle = 0; | 159 | handle = 0; |
| 159 | } | 160 | } |
| 160 | 161 | ||
| 162 | bool OGLSync::IsSignaled() const noexcept { | ||
| 163 | // At least on Nvidia, glClientWaitSync with a timeout of 0 | ||
| 164 | // is faster than glGetSynciv of GL_SYNC_STATUS. | ||
| 165 | // Timeout of 0 means this check is non-blocking. | ||
| 166 | const auto sync_status = glClientWaitSync(handle, 0, 0); | ||
| 167 | ASSERT(sync_status != GL_WAIT_FAILED); | ||
| 168 | return sync_status != GL_TIMEOUT_EXPIRED; | ||
| 169 | } | ||
| 170 | |||
| 161 | void OGLFramebuffer::Create() { | 171 | void OGLFramebuffer::Create() { |
| 162 | if (handle != 0) | 172 | if (handle != 0) |
| 163 | return; | 173 | return; |
diff --git a/src/video_core/renderer_opengl/gl_resource_manager.h b/src/video_core/renderer_opengl/gl_resource_manager.h index bc05ba4bd..77362acd2 100644 --- a/src/video_core/renderer_opengl/gl_resource_manager.h +++ b/src/video_core/renderer_opengl/gl_resource_manager.h | |||
| @@ -263,6 +263,9 @@ public: | |||
| 263 | /// Deletes the internal OpenGL resource | 263 | /// Deletes the internal OpenGL resource |
| 264 | void Release(); | 264 | void Release(); |
| 265 | 265 | ||
| 266 | /// Checks if the sync has been signaled | ||
| 267 | bool IsSignaled() const noexcept; | ||
| 268 | |||
| 266 | GLsync handle = 0; | 269 | GLsync handle = 0; |
| 267 | }; | 270 | }; |
| 268 | 271 | ||
diff --git a/src/video_core/renderer_opengl/gl_texture_cache.cpp b/src/video_core/renderer_opengl/gl_texture_cache.cpp index b047e7b3d..9b99125e5 100644 --- a/src/video_core/renderer_opengl/gl_texture_cache.cpp +++ b/src/video_core/renderer_opengl/gl_texture_cache.cpp | |||
| @@ -112,13 +112,17 @@ GLenum ImageTarget(Shader::TextureType type, int num_samples = 1) { | |||
| 112 | return GL_NONE; | 112 | return GL_NONE; |
| 113 | } | 113 | } |
| 114 | 114 | ||
| 115 | GLenum TextureMode(PixelFormat format, bool is_first) { | 115 | GLenum TextureMode(PixelFormat format, std::array<SwizzleSource, 4> swizzle) { |
| 116 | bool any_r = | ||
| 117 | std::ranges::any_of(swizzle, [](SwizzleSource s) { return s == SwizzleSource::R; }); | ||
| 116 | switch (format) { | 118 | switch (format) { |
| 117 | case PixelFormat::D24_UNORM_S8_UINT: | 119 | case PixelFormat::D24_UNORM_S8_UINT: |
| 118 | case PixelFormat::D32_FLOAT_S8_UINT: | 120 | case PixelFormat::D32_FLOAT_S8_UINT: |
| 119 | return is_first ? GL_DEPTH_COMPONENT : GL_STENCIL_INDEX; | 121 | // R = depth, G = stencil |
| 122 | return any_r ? GL_DEPTH_COMPONENT : GL_STENCIL_INDEX; | ||
| 120 | case PixelFormat::S8_UINT_D24_UNORM: | 123 | case PixelFormat::S8_UINT_D24_UNORM: |
| 121 | return is_first ? GL_STENCIL_INDEX : GL_DEPTH_COMPONENT; | 124 | // R = stencil, G = depth |
| 125 | return any_r ? GL_STENCIL_INDEX : GL_DEPTH_COMPONENT; | ||
| 122 | default: | 126 | default: |
| 123 | ASSERT(false); | 127 | ASSERT(false); |
| 124 | return GL_DEPTH_COMPONENT; | 128 | return GL_DEPTH_COMPONENT; |
| @@ -208,8 +212,7 @@ void ApplySwizzle(GLuint handle, PixelFormat format, std::array<SwizzleSource, 4 | |||
| 208 | case PixelFormat::D32_FLOAT_S8_UINT: | 212 | case PixelFormat::D32_FLOAT_S8_UINT: |
| 209 | case PixelFormat::S8_UINT_D24_UNORM: | 213 | case PixelFormat::S8_UINT_D24_UNORM: |
| 210 | UNIMPLEMENTED_IF(swizzle[0] != SwizzleSource::R && swizzle[0] != SwizzleSource::G); | 214 | UNIMPLEMENTED_IF(swizzle[0] != SwizzleSource::R && swizzle[0] != SwizzleSource::G); |
| 211 | glTextureParameteri(handle, GL_DEPTH_STENCIL_TEXTURE_MODE, | 215 | glTextureParameteri(handle, GL_DEPTH_STENCIL_TEXTURE_MODE, TextureMode(format, swizzle)); |
| 212 | TextureMode(format, swizzle[0] == SwizzleSource::R)); | ||
| 213 | std::ranges::transform(swizzle, swizzle.begin(), ConvertGreenRed); | 216 | std::ranges::transform(swizzle, swizzle.begin(), ConvertGreenRed); |
| 214 | break; | 217 | break; |
| 215 | case PixelFormat::A5B5G5R1_UNORM: { | 218 | case PixelFormat::A5B5G5R1_UNORM: { |
| @@ -714,9 +717,7 @@ std::optional<size_t> TextureCacheRuntime::StagingBuffers::FindBuffer(size_t req | |||
| 714 | continue; | 717 | continue; |
| 715 | } | 718 | } |
| 716 | if (syncs[index].handle != 0) { | 719 | if (syncs[index].handle != 0) { |
| 717 | GLint status; | 720 | if (!syncs[index].IsSignaled()) { |
| 718 | glGetSynciv(syncs[index].handle, GL_SYNC_STATUS, 1, nullptr, &status); | ||
| 719 | if (status != GL_SIGNALED) { | ||
| 720 | continue; | 721 | continue; |
| 721 | } | 722 | } |
| 722 | syncs[index].Release(); | 723 | syncs[index].Release(); |
diff --git a/src/video_core/renderer_vulkan/vk_buffer_cache.cpp b/src/video_core/renderer_vulkan/vk_buffer_cache.cpp index b0153a502..9cbcb3c8f 100644 --- a/src/video_core/renderer_vulkan/vk_buffer_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_buffer_cache.cpp | |||
| @@ -238,7 +238,7 @@ private: | |||
| 238 | return indices; | 238 | return indices; |
| 239 | } | 239 | } |
| 240 | 240 | ||
| 241 | void MakeAndUpdateIndices(u8* staging_data, size_t quad_size, u32 quad, u32 first) { | 241 | void MakeAndUpdateIndices(u8* staging_data, size_t quad_size, u32 quad, u32 first) override { |
| 242 | switch (index_type) { | 242 | switch (index_type) { |
| 243 | case VK_INDEX_TYPE_UINT8_EXT: | 243 | case VK_INDEX_TYPE_UINT8_EXT: |
| 244 | std::memcpy(staging_data, MakeIndices<u8>(quad, first).data(), quad_size); | 244 | std::memcpy(staging_data, MakeIndices<u8>(quad, first).data(), quad_size); |
| @@ -278,7 +278,7 @@ private: | |||
| 278 | return indices; | 278 | return indices; |
| 279 | } | 279 | } |
| 280 | 280 | ||
| 281 | void MakeAndUpdateIndices(u8* staging_data, size_t quad_size, u32 quad, u32 first) { | 281 | void MakeAndUpdateIndices(u8* staging_data, size_t quad_size, u32 quad, u32 first) override { |
| 282 | switch (index_type) { | 282 | switch (index_type) { |
| 283 | case VK_INDEX_TYPE_UINT8_EXT: | 283 | case VK_INDEX_TYPE_UINT8_EXT: |
| 284 | std::memcpy(staging_data, MakeIndices<u8>(quad, first).data(), quad_size); | 284 | std::memcpy(staging_data, MakeIndices<u8>(quad, first).data(), quad_size); |
diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp index f085d53a1..25965b684 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp +++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp | |||
| @@ -1294,7 +1294,7 @@ void RasterizerVulkan::UpdateDepthBoundsTestEnable(Tegra::Engines::Maxwell3D::Re | |||
| 1294 | LOG_WARNING(Render_Vulkan, "Depth bounds is enabled but not supported"); | 1294 | LOG_WARNING(Render_Vulkan, "Depth bounds is enabled but not supported"); |
| 1295 | enabled = false; | 1295 | enabled = false; |
| 1296 | } | 1296 | } |
| 1297 | scheduler.Record([enable = regs.depth_bounds_enable](vk::CommandBuffer cmdbuf) { | 1297 | scheduler.Record([enable = enabled](vk::CommandBuffer cmdbuf) { |
| 1298 | cmdbuf.SetDepthBoundsTestEnableEXT(enable); | 1298 | cmdbuf.SetDepthBoundsTestEnableEXT(enable); |
| 1299 | }); | 1299 | }); |
| 1300 | } | 1300 | } |
diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.cpp b/src/video_core/renderer_vulkan/vk_texture_cache.cpp index 8a204f93f..e013d1c60 100644 --- a/src/video_core/renderer_vulkan/vk_texture_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_texture_cache.cpp | |||
| @@ -189,13 +189,16 @@ constexpr VkBorderColor ConvertBorderColor(const std::array<float, 4>& color) { | |||
| 189 | if (info.IsRenderTarget()) { | 189 | if (info.IsRenderTarget()) { |
| 190 | return ImageAspectMask(info.format); | 190 | return ImageAspectMask(info.format); |
| 191 | } | 191 | } |
| 192 | const bool is_first = info.Swizzle()[0] == SwizzleSource::R; | 192 | bool any_r = |
| 193 | std::ranges::any_of(info.Swizzle(), [](SwizzleSource s) { return s == SwizzleSource::R; }); | ||
| 193 | switch (info.format) { | 194 | switch (info.format) { |
| 194 | case PixelFormat::D24_UNORM_S8_UINT: | 195 | case PixelFormat::D24_UNORM_S8_UINT: |
| 195 | case PixelFormat::D32_FLOAT_S8_UINT: | 196 | case PixelFormat::D32_FLOAT_S8_UINT: |
| 196 | return is_first ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_STENCIL_BIT; | 197 | // R = depth, G = stencil |
| 198 | return any_r ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_STENCIL_BIT; | ||
| 197 | case PixelFormat::S8_UINT_D24_UNORM: | 199 | case PixelFormat::S8_UINT_D24_UNORM: |
| 198 | return is_first ? VK_IMAGE_ASPECT_STENCIL_BIT : VK_IMAGE_ASPECT_DEPTH_BIT; | 200 | // R = stencil, G = depth |
| 201 | return any_r ? VK_IMAGE_ASPECT_STENCIL_BIT : VK_IMAGE_ASPECT_DEPTH_BIT; | ||
| 199 | case PixelFormat::D16_UNORM: | 202 | case PixelFormat::D16_UNORM: |
| 200 | case PixelFormat::D32_FLOAT: | 203 | case PixelFormat::D32_FLOAT: |
| 201 | return VK_IMAGE_ASPECT_DEPTH_BIT; | 204 | return VK_IMAGE_ASPECT_DEPTH_BIT; |
| @@ -1769,7 +1772,7 @@ Sampler::Sampler(TextureCacheRuntime& runtime, const Tegra::Texture::TSCEntry& t | |||
| 1769 | .minLod = tsc.mipmap_filter == TextureMipmapFilter::None ? 0.0f : tsc.MinLod(), | 1772 | .minLod = tsc.mipmap_filter == TextureMipmapFilter::None ? 0.0f : tsc.MinLod(), |
| 1770 | .maxLod = tsc.mipmap_filter == TextureMipmapFilter::None ? 0.25f : tsc.MaxLod(), | 1773 | .maxLod = tsc.mipmap_filter == TextureMipmapFilter::None ? 0.25f : tsc.MaxLod(), |
| 1771 | .borderColor = | 1774 | .borderColor = |
| 1772 | arbitrary_borders ? VK_BORDER_COLOR_INT_CUSTOM_EXT : ConvertBorderColor(color), | 1775 | arbitrary_borders ? VK_BORDER_COLOR_FLOAT_CUSTOM_EXT : ConvertBorderColor(color), |
| 1773 | .unnormalizedCoordinates = VK_FALSE, | 1776 | .unnormalizedCoordinates = VK_FALSE, |
| 1774 | }); | 1777 | }); |
| 1775 | } | 1778 | } |