diff options
117 files changed, 1086 insertions, 454 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index a6c43f401..561eaafb2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt | |||
| @@ -222,7 +222,7 @@ find_package(ZLIB 1.2 REQUIRED) | |||
| 222 | find_package(zstd 1.5 REQUIRED) | 222 | find_package(zstd 1.5 REQUIRED) |
| 223 | 223 | ||
| 224 | if (NOT YUZU_USE_EXTERNAL_VULKAN_HEADERS) | 224 | if (NOT YUZU_USE_EXTERNAL_VULKAN_HEADERS) |
| 225 | find_package(Vulkan 1.3.238 REQUIRED) | 225 | find_package(Vulkan 1.3.246 REQUIRED) |
| 226 | endif() | 226 | endif() |
| 227 | 227 | ||
| 228 | if (ENABLE_LIBUSB) | 228 | if (ENABLE_LIBUSB) |
diff --git a/externals/Vulkan-Headers b/externals/Vulkan-Headers | |||
| Subproject 00671c64ba5c488ade22ad572a0ef81d5e64c80 | Subproject 63af1cf1ee906ba4dcd5a324bdd0201d4f4bfd1 | ||
diff --git a/src/audio_core/device/device_session.cpp b/src/audio_core/device/device_session.cpp index ad0f40e28..b5c0ef0e6 100644 --- a/src/audio_core/device/device_session.cpp +++ b/src/audio_core/device/device_session.cpp | |||
| @@ -93,7 +93,7 @@ void DeviceSession::AppendBuffers(std::span<const AudioBuffer> buffers) const { | |||
| 93 | stream->AppendBuffer(new_buffer, samples); | 93 | stream->AppendBuffer(new_buffer, samples); |
| 94 | } else { | 94 | } else { |
| 95 | std::vector<s16> samples(buffer.size / sizeof(s16)); | 95 | std::vector<s16> samples(buffer.size / sizeof(s16)); |
| 96 | system.Memory().ReadBlockUnsafe(buffer.samples, samples.data(), buffer.size); | 96 | system.ApplicationMemory().ReadBlockUnsafe(buffer.samples, samples.data(), buffer.size); |
| 97 | stream->AppendBuffer(new_buffer, samples); | 97 | stream->AppendBuffer(new_buffer, samples); |
| 98 | } | 98 | } |
| 99 | } | 99 | } |
| @@ -102,7 +102,7 @@ void DeviceSession::AppendBuffers(std::span<const AudioBuffer> buffers) const { | |||
| 102 | void DeviceSession::ReleaseBuffer(const AudioBuffer& buffer) const { | 102 | void DeviceSession::ReleaseBuffer(const AudioBuffer& buffer) const { |
| 103 | if (type == Sink::StreamType::In) { | 103 | if (type == Sink::StreamType::In) { |
| 104 | auto samples{stream->ReleaseBuffer(buffer.size / sizeof(s16))}; | 104 | auto samples{stream->ReleaseBuffer(buffer.size / sizeof(s16))}; |
| 105 | system.Memory().WriteBlockUnsafe(buffer.samples, samples.data(), buffer.size); | 105 | system.ApplicationMemory().WriteBlockUnsafe(buffer.samples, samples.data(), buffer.size); |
| 106 | } | 106 | } |
| 107 | } | 107 | } |
| 108 | 108 | ||
diff --git a/src/audio_core/renderer/adsp/adsp.cpp b/src/audio_core/renderer/adsp/adsp.cpp index a28395663..74772fc50 100644 --- a/src/audio_core/renderer/adsp/adsp.cpp +++ b/src/audio_core/renderer/adsp/adsp.cpp | |||
| @@ -13,7 +13,7 @@ | |||
| 13 | namespace AudioCore::AudioRenderer::ADSP { | 13 | namespace AudioCore::AudioRenderer::ADSP { |
| 14 | 14 | ||
| 15 | ADSP::ADSP(Core::System& system_, Sink::Sink& sink_) | 15 | ADSP::ADSP(Core::System& system_, Sink::Sink& sink_) |
| 16 | : system{system_}, memory{system.Memory()}, sink{sink_} {} | 16 | : system{system_}, memory{system.ApplicationMemory()}, sink{sink_} {} |
| 17 | 17 | ||
| 18 | ADSP::~ADSP() { | 18 | ADSP::~ADSP() { |
| 19 | ClearCommandBuffers(); | 19 | ClearCommandBuffers(); |
diff --git a/src/audio_core/renderer/adsp/command_list_processor.cpp b/src/audio_core/renderer/adsp/command_list_processor.cpp index e3bf2d7ec..7a300d216 100644 --- a/src/audio_core/renderer/adsp/command_list_processor.cpp +++ b/src/audio_core/renderer/adsp/command_list_processor.cpp | |||
| @@ -17,7 +17,7 @@ namespace AudioCore::AudioRenderer::ADSP { | |||
| 17 | void CommandListProcessor::Initialize(Core::System& system_, CpuAddr buffer, u64 size, | 17 | void CommandListProcessor::Initialize(Core::System& system_, CpuAddr buffer, u64 size, |
| 18 | Sink::SinkStream* stream_) { | 18 | Sink::SinkStream* stream_) { |
| 19 | system = &system_; | 19 | system = &system_; |
| 20 | memory = &system->Memory(); | 20 | memory = &system->ApplicationMemory(); |
| 21 | stream = stream_; | 21 | stream = stream_; |
| 22 | header = reinterpret_cast<CommandListHeader*>(buffer); | 22 | header = reinterpret_cast<CommandListHeader*>(buffer); |
| 23 | commands = reinterpret_cast<u8*>(buffer + sizeof(CommandListHeader)); | 23 | commands = reinterpret_cast<u8*>(buffer + sizeof(CommandListHeader)); |
diff --git a/src/audio_core/renderer/system.cpp b/src/audio_core/renderer/system.cpp index 28f063641..ad869facb 100644 --- a/src/audio_core/renderer/system.cpp +++ b/src/audio_core/renderer/system.cpp | |||
| @@ -127,8 +127,7 @@ Result System::Initialize(const AudioRendererParameterInternal& params, | |||
| 127 | render_device = params.rendering_device; | 127 | render_device = params.rendering_device; |
| 128 | execution_mode = params.execution_mode; | 128 | execution_mode = params.execution_mode; |
| 129 | 129 | ||
| 130 | core.Memory().ZeroBlock(*core.ApplicationProcess(), transfer_memory->GetSourceAddress(), | 130 | core.ApplicationMemory().ZeroBlock(transfer_memory->GetSourceAddress(), transfer_memory_size); |
| 131 | transfer_memory_size); | ||
| 132 | 131 | ||
| 133 | // Note: We're not actually using the transfer memory because it's a pain to code for. | 132 | // Note: We're not actually using the transfer memory because it's a pain to code for. |
| 134 | // Allocate the memory normally instead and hope the game doesn't try to read anything back | 133 | // Allocate the memory normally instead and hope the game doesn't try to read anything back |
diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index c1d2b24a1..13ed68b3f 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt | |||
| @@ -160,6 +160,8 @@ if(ARCHITECTURE_x86_64) | |||
| 160 | PRIVATE | 160 | PRIVATE |
| 161 | x64/cpu_detect.cpp | 161 | x64/cpu_detect.cpp |
| 162 | x64/cpu_detect.h | 162 | x64/cpu_detect.h |
| 163 | x64/cpu_wait.cpp | ||
| 164 | x64/cpu_wait.h | ||
| 163 | x64/native_clock.cpp | 165 | x64/native_clock.cpp |
| 164 | x64/native_clock.h | 166 | x64/native_clock.h |
| 165 | x64/xbyak_abi.h | 167 | x64/xbyak_abi.h |
diff --git a/src/common/range_map.h b/src/common/range_map.h index 79c7ef547..ab73993e3 100644 --- a/src/common/range_map.h +++ b/src/common/range_map.h | |||
| @@ -38,12 +38,12 @@ public: | |||
| 38 | Map(address, address_end, null_value); | 38 | Map(address, address_end, null_value); |
| 39 | } | 39 | } |
| 40 | 40 | ||
| 41 | [[nodiscard]] size_t GetContinousSizeFrom(KeyTBase address) const { | 41 | [[nodiscard]] size_t GetContinuousSizeFrom(KeyTBase address) const { |
| 42 | const KeyT new_address = static_cast<KeyT>(address); | 42 | const KeyT new_address = static_cast<KeyT>(address); |
| 43 | if (new_address < 0) { | 43 | if (new_address < 0) { |
| 44 | return 0; | 44 | return 0; |
| 45 | } | 45 | } |
| 46 | return ContinousSizeInternal(new_address); | 46 | return ContinuousSizeInternal(new_address); |
| 47 | } | 47 | } |
| 48 | 48 | ||
| 49 | [[nodiscard]] ValueT GetValueAt(KeyT address) const { | 49 | [[nodiscard]] ValueT GetValueAt(KeyT address) const { |
| @@ -59,7 +59,7 @@ private: | |||
| 59 | using IteratorType = typename MapType::iterator; | 59 | using IteratorType = typename MapType::iterator; |
| 60 | using ConstIteratorType = typename MapType::const_iterator; | 60 | using ConstIteratorType = typename MapType::const_iterator; |
| 61 | 61 | ||
| 62 | size_t ContinousSizeInternal(KeyT address) const { | 62 | size_t ContinuousSizeInternal(KeyT address) const { |
| 63 | const auto it = GetFirstElementBeforeOrOn(address); | 63 | const auto it = GetFirstElementBeforeOrOn(address); |
| 64 | if (it == container.end() || it->second == null_value) { | 64 | if (it == container.end() || it->second == null_value) { |
| 65 | return 0; | 65 | return 0; |
diff --git a/src/common/telemetry.cpp b/src/common/telemetry.cpp index d26394359..91352912d 100644 --- a/src/common/telemetry.cpp +++ b/src/common/telemetry.cpp | |||
| @@ -97,6 +97,7 @@ void AppendCPUInfo(FieldCollection& fc) { | |||
| 97 | add_field("CPU_Extension_x64_PCLMULQDQ", caps.pclmulqdq); | 97 | add_field("CPU_Extension_x64_PCLMULQDQ", caps.pclmulqdq); |
| 98 | add_field("CPU_Extension_x64_POPCNT", caps.popcnt); | 98 | add_field("CPU_Extension_x64_POPCNT", caps.popcnt); |
| 99 | add_field("CPU_Extension_x64_SHA", caps.sha); | 99 | add_field("CPU_Extension_x64_SHA", caps.sha); |
| 100 | add_field("CPU_Extension_x64_WAITPKG", caps.waitpkg); | ||
| 100 | #else | 101 | #else |
| 101 | fc.AddField(FieldType::UserSystem, "CPU_Model", "Other"); | 102 | fc.AddField(FieldType::UserSystem, "CPU_Model", "Other"); |
| 102 | #endif | 103 | #endif |
diff --git a/src/common/x64/cpu_detect.cpp b/src/common/x64/cpu_detect.cpp index e54383a4a..72ed6e96c 100644 --- a/src/common/x64/cpu_detect.cpp +++ b/src/common/x64/cpu_detect.cpp | |||
| @@ -144,6 +144,7 @@ static CPUCaps Detect() { | |||
| 144 | caps.bmi2 = Common::Bit<8>(cpu_id[1]); | 144 | caps.bmi2 = Common::Bit<8>(cpu_id[1]); |
| 145 | caps.sha = Common::Bit<29>(cpu_id[1]); | 145 | caps.sha = Common::Bit<29>(cpu_id[1]); |
| 146 | 146 | ||
| 147 | caps.waitpkg = Common::Bit<5>(cpu_id[2]); | ||
| 147 | caps.gfni = Common::Bit<8>(cpu_id[2]); | 148 | caps.gfni = Common::Bit<8>(cpu_id[2]); |
| 148 | 149 | ||
| 149 | __cpuidex(cpu_id, 0x00000007, 0x00000001); | 150 | __cpuidex(cpu_id, 0x00000007, 0x00000001); |
diff --git a/src/common/x64/cpu_detect.h b/src/common/x64/cpu_detect.h index ca8db19d6..8253944d6 100644 --- a/src/common/x64/cpu_detect.h +++ b/src/common/x64/cpu_detect.h | |||
| @@ -67,6 +67,7 @@ struct CPUCaps { | |||
| 67 | bool pclmulqdq : 1; | 67 | bool pclmulqdq : 1; |
| 68 | bool popcnt : 1; | 68 | bool popcnt : 1; |
| 69 | bool sha : 1; | 69 | bool sha : 1; |
| 70 | bool waitpkg : 1; | ||
| 70 | }; | 71 | }; |
| 71 | 72 | ||
| 72 | /** | 73 | /** |
diff --git a/src/common/x64/cpu_wait.cpp b/src/common/x64/cpu_wait.cpp new file mode 100644 index 000000000..cfeef6a3d --- /dev/null +++ b/src/common/x64/cpu_wait.cpp | |||
| @@ -0,0 +1,69 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #include <thread> | ||
| 5 | |||
| 6 | #ifdef _MSC_VER | ||
| 7 | #include <intrin.h> | ||
| 8 | #endif | ||
| 9 | |||
| 10 | #include "common/x64/cpu_detect.h" | ||
| 11 | #include "common/x64/cpu_wait.h" | ||
| 12 | |||
| 13 | namespace Common::X64 { | ||
| 14 | |||
| 15 | #ifdef _MSC_VER | ||
| 16 | __forceinline static u64 FencedRDTSC() { | ||
| 17 | _mm_lfence(); | ||
| 18 | _ReadWriteBarrier(); | ||
| 19 | const u64 result = __rdtsc(); | ||
| 20 | _mm_lfence(); | ||
| 21 | _ReadWriteBarrier(); | ||
| 22 | return result; | ||
| 23 | } | ||
| 24 | |||
| 25 | __forceinline static void TPAUSE() { | ||
| 26 | // 100,000 cycles is a reasonable amount of time to wait to save on CPU resources. | ||
| 27 | // For reference: | ||
| 28 | // At 1 GHz, 100K cycles is 100us | ||
| 29 | // At 2 GHz, 100K cycles is 50us | ||
| 30 | // At 4 GHz, 100K cycles is 25us | ||
| 31 | static constexpr auto PauseCycles = 100'000; | ||
| 32 | _tpause(0, FencedRDTSC() + PauseCycles); | ||
| 33 | } | ||
| 34 | #else | ||
| 35 | static u64 FencedRDTSC() { | ||
| 36 | u64 eax; | ||
| 37 | u64 edx; | ||
| 38 | asm volatile("lfence\n\t" | ||
| 39 | "rdtsc\n\t" | ||
| 40 | "lfence\n\t" | ||
| 41 | : "=a"(eax), "=d"(edx)); | ||
| 42 | return (edx << 32) | eax; | ||
| 43 | } | ||
| 44 | |||
| 45 | static void TPAUSE() { | ||
| 46 | // 100,000 cycles is a reasonable amount of time to wait to save on CPU resources. | ||
| 47 | // For reference: | ||
| 48 | // At 1 GHz, 100K cycles is 100us | ||
| 49 | // At 2 GHz, 100K cycles is 50us | ||
| 50 | // At 4 GHz, 100K cycles is 25us | ||
| 51 | static constexpr auto PauseCycles = 100'000; | ||
| 52 | const auto tsc = FencedRDTSC() + PauseCycles; | ||
| 53 | const auto eax = static_cast<u32>(tsc & 0xFFFFFFFF); | ||
| 54 | const auto edx = static_cast<u32>(tsc >> 32); | ||
| 55 | asm volatile("tpause %0" : : "r"(0), "d"(edx), "a"(eax)); | ||
| 56 | } | ||
| 57 | #endif | ||
| 58 | |||
| 59 | void MicroSleep() { | ||
| 60 | static const bool has_waitpkg = GetCPUCaps().waitpkg; | ||
| 61 | |||
| 62 | if (has_waitpkg) { | ||
| 63 | TPAUSE(); | ||
| 64 | } else { | ||
| 65 | std::this_thread::yield(); | ||
| 66 | } | ||
| 67 | } | ||
| 68 | |||
| 69 | } // namespace Common::X64 | ||
diff --git a/src/common/x64/cpu_wait.h b/src/common/x64/cpu_wait.h new file mode 100644 index 000000000..99d3757a7 --- /dev/null +++ b/src/common/x64/cpu_wait.h | |||
| @@ -0,0 +1,10 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | namespace Common::X64 { | ||
| 7 | |||
| 8 | void MicroSleep(); | ||
| 9 | |||
| 10 | } // namespace Common::X64 | ||
diff --git a/src/common/x64/native_clock.cpp b/src/common/x64/native_clock.cpp index 76c66e7ee..277b00662 100644 --- a/src/common/x64/native_clock.cpp +++ b/src/common/x64/native_clock.cpp | |||
| @@ -27,16 +27,13 @@ __forceinline static u64 FencedRDTSC() { | |||
| 27 | } | 27 | } |
| 28 | #else | 28 | #else |
| 29 | static u64 FencedRDTSC() { | 29 | static u64 FencedRDTSC() { |
| 30 | u64 result; | 30 | u64 eax; |
| 31 | u64 edx; | ||
| 31 | asm volatile("lfence\n\t" | 32 | asm volatile("lfence\n\t" |
| 32 | "rdtsc\n\t" | 33 | "rdtsc\n\t" |
| 33 | "shl $32, %%rdx\n\t" | 34 | "lfence\n\t" |
| 34 | "or %%rdx, %0\n\t" | 35 | : "=a"(eax), "=d"(edx)); |
| 35 | "lfence" | 36 | return (edx << 32) | eax; |
| 36 | : "=a"(result) | ||
| 37 | : | ||
| 38 | : "rdx", "memory", "cc"); | ||
| 39 | return result; | ||
| 40 | } | 37 | } |
| 41 | #endif | 38 | #endif |
| 42 | 39 | ||
diff --git a/src/core/arm/arm_interface.cpp b/src/core/arm/arm_interface.cpp index be3f55cd2..d30914b7a 100644 --- a/src/core/arm/arm_interface.cpp +++ b/src/core/arm/arm_interface.cpp | |||
| @@ -44,7 +44,7 @@ void ARM_Interface::SymbolicateBacktrace(Core::System& system, std::vector<Backt | |||
| 44 | std::map<std::string, Symbols::Symbols> symbols; | 44 | std::map<std::string, Symbols::Symbols> symbols; |
| 45 | for (const auto& module : modules) { | 45 | for (const auto& module : modules) { |
| 46 | symbols.insert_or_assign( | 46 | symbols.insert_or_assign( |
| 47 | module.second, Symbols::GetSymbols(module.first, system.Memory(), | 47 | module.second, Symbols::GetSymbols(module.first, system.ApplicationMemory(), |
| 48 | system.ApplicationProcess()->Is64BitProcess())); | 48 | system.ApplicationProcess()->Is64BitProcess())); |
| 49 | } | 49 | } |
| 50 | 50 | ||
diff --git a/src/core/arm/dynarmic/arm_dynarmic_32.cpp b/src/core/arm/dynarmic/arm_dynarmic_32.cpp index aa92d3fc3..cab21a88e 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_32.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic_32.cpp | |||
| @@ -28,8 +28,8 @@ using namespace Common::Literals; | |||
| 28 | class DynarmicCallbacks32 : public Dynarmic::A32::UserCallbacks { | 28 | class DynarmicCallbacks32 : public Dynarmic::A32::UserCallbacks { |
| 29 | public: | 29 | public: |
| 30 | explicit DynarmicCallbacks32(ARM_Dynarmic_32& parent_) | 30 | explicit DynarmicCallbacks32(ARM_Dynarmic_32& parent_) |
| 31 | : parent{parent_}, | 31 | : parent{parent_}, memory(parent.system.ApplicationMemory()), |
| 32 | memory(parent.system.Memory()), debugger_enabled{parent.system.DebuggerEnabled()}, | 32 | debugger_enabled{parent.system.DebuggerEnabled()}, |
| 33 | check_memory_access{debugger_enabled || | 33 | check_memory_access{debugger_enabled || |
| 34 | !Settings::values.cpuopt_ignore_memory_aborts.GetValue()} {} | 34 | !Settings::values.cpuopt_ignore_memory_aborts.GetValue()} {} |
| 35 | 35 | ||
| @@ -468,7 +468,7 @@ void ARM_Dynarmic_32::PageTableChanged(Common::PageTable& page_table, | |||
| 468 | std::vector<ARM_Interface::BacktraceEntry> ARM_Dynarmic_32::GetBacktrace(Core::System& system, | 468 | std::vector<ARM_Interface::BacktraceEntry> ARM_Dynarmic_32::GetBacktrace(Core::System& system, |
| 469 | u64 fp, u64 lr, u64 pc) { | 469 | u64 fp, u64 lr, u64 pc) { |
| 470 | std::vector<BacktraceEntry> out; | 470 | std::vector<BacktraceEntry> out; |
| 471 | auto& memory = system.Memory(); | 471 | auto& memory = system.ApplicationMemory(); |
| 472 | 472 | ||
| 473 | out.push_back({"", 0, pc, 0, ""}); | 473 | out.push_back({"", 0, pc, 0, ""}); |
| 474 | 474 | ||
diff --git a/src/core/arm/dynarmic/arm_dynarmic_64.cpp b/src/core/arm/dynarmic/arm_dynarmic_64.cpp index 67073c84d..bbbcb4f9d 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_64.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic_64.cpp | |||
| @@ -28,8 +28,8 @@ using namespace Common::Literals; | |||
| 28 | class DynarmicCallbacks64 : public Dynarmic::A64::UserCallbacks { | 28 | class DynarmicCallbacks64 : public Dynarmic::A64::UserCallbacks { |
| 29 | public: | 29 | public: |
| 30 | explicit DynarmicCallbacks64(ARM_Dynarmic_64& parent_) | 30 | explicit DynarmicCallbacks64(ARM_Dynarmic_64& parent_) |
| 31 | : parent{parent_}, | 31 | : parent{parent_}, memory(parent.system.ApplicationMemory()), |
| 32 | memory(parent.system.Memory()), debugger_enabled{parent.system.DebuggerEnabled()}, | 32 | debugger_enabled{parent.system.DebuggerEnabled()}, |
| 33 | check_memory_access{debugger_enabled || | 33 | check_memory_access{debugger_enabled || |
| 34 | !Settings::values.cpuopt_ignore_memory_aborts.GetValue()} {} | 34 | !Settings::values.cpuopt_ignore_memory_aborts.GetValue()} {} |
| 35 | 35 | ||
| @@ -529,7 +529,7 @@ void ARM_Dynarmic_64::PageTableChanged(Common::PageTable& page_table, | |||
| 529 | std::vector<ARM_Interface::BacktraceEntry> ARM_Dynarmic_64::GetBacktrace(Core::System& system, | 529 | std::vector<ARM_Interface::BacktraceEntry> ARM_Dynarmic_64::GetBacktrace(Core::System& system, |
| 530 | u64 fp, u64 lr, u64 pc) { | 530 | u64 fp, u64 lr, u64 pc) { |
| 531 | std::vector<BacktraceEntry> out; | 531 | std::vector<BacktraceEntry> out; |
| 532 | auto& memory = system.Memory(); | 532 | auto& memory = system.ApplicationMemory(); |
| 533 | 533 | ||
| 534 | out.push_back({"", 0, pc, 0, ""}); | 534 | out.push_back({"", 0, pc, 0, ""}); |
| 535 | 535 | ||
diff --git a/src/core/core.cpp b/src/core/core.cpp index f6273ac39..caa6a77be 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp | |||
| @@ -293,6 +293,7 @@ struct System::Impl { | |||
| 293 | ASSERT(Kernel::KProcess::Initialize(main_process, system, "main", | 293 | ASSERT(Kernel::KProcess::Initialize(main_process, system, "main", |
| 294 | Kernel::KProcess::ProcessType::Userland, resource_limit) | 294 | Kernel::KProcess::ProcessType::Userland, resource_limit) |
| 295 | .IsSuccess()); | 295 | .IsSuccess()); |
| 296 | kernel.MakeApplicationProcess(main_process); | ||
| 296 | const auto [load_result, load_parameters] = app_loader->Load(*main_process, system); | 297 | const auto [load_result, load_parameters] = app_loader->Load(*main_process, system); |
| 297 | if (load_result != Loader::ResultStatus::Success) { | 298 | if (load_result != Loader::ResultStatus::Success) { |
| 298 | LOG_CRITICAL(Core, "Failed to load ROM (Error {})!", load_result); | 299 | LOG_CRITICAL(Core, "Failed to load ROM (Error {})!", load_result); |
| @@ -302,7 +303,6 @@ struct System::Impl { | |||
| 302 | static_cast<u32>(SystemResultStatus::ErrorLoader) + static_cast<u32>(load_result)); | 303 | static_cast<u32>(SystemResultStatus::ErrorLoader) + static_cast<u32>(load_result)); |
| 303 | } | 304 | } |
| 304 | AddGlueRegistrationForProcess(*app_loader, *main_process); | 305 | AddGlueRegistrationForProcess(*app_loader, *main_process); |
| 305 | kernel.MakeApplicationProcess(main_process); | ||
| 306 | kernel.InitializeCores(); | 306 | kernel.InitializeCores(); |
| 307 | 307 | ||
| 308 | // Initialize cheat engine | 308 | // Initialize cheat engine |
| @@ -681,11 +681,11 @@ const ExclusiveMonitor& System::Monitor() const { | |||
| 681 | return impl->kernel.GetExclusiveMonitor(); | 681 | return impl->kernel.GetExclusiveMonitor(); |
| 682 | } | 682 | } |
| 683 | 683 | ||
| 684 | Memory::Memory& System::Memory() { | 684 | Memory::Memory& System::ApplicationMemory() { |
| 685 | return impl->memory; | 685 | return impl->memory; |
| 686 | } | 686 | } |
| 687 | 687 | ||
| 688 | const Core::Memory::Memory& System::Memory() const { | 688 | const Core::Memory::Memory& System::ApplicationMemory() const { |
| 689 | return impl->memory; | 689 | return impl->memory; |
| 690 | } | 690 | } |
| 691 | 691 | ||
diff --git a/src/core/core.h b/src/core/core.h index 7032240be..4a5aba032 100644 --- a/src/core/core.h +++ b/src/core/core.h | |||
| @@ -256,10 +256,10 @@ public: | |||
| 256 | [[nodiscard]] const ExclusiveMonitor& Monitor() const; | 256 | [[nodiscard]] const ExclusiveMonitor& Monitor() const; |
| 257 | 257 | ||
| 258 | /// Gets a mutable reference to the system memory instance. | 258 | /// Gets a mutable reference to the system memory instance. |
| 259 | [[nodiscard]] Core::Memory::Memory& Memory(); | 259 | [[nodiscard]] Core::Memory::Memory& ApplicationMemory(); |
| 260 | 260 | ||
| 261 | /// Gets a constant reference to the system memory instance. | 261 | /// Gets a constant reference to the system memory instance. |
| 262 | [[nodiscard]] const Core::Memory::Memory& Memory() const; | 262 | [[nodiscard]] const Core::Memory::Memory& ApplicationMemory() const; |
| 263 | 263 | ||
| 264 | /// Gets a mutable reference to the GPU interface | 264 | /// Gets a mutable reference to the GPU interface |
| 265 | [[nodiscard]] Tegra::GPU& GPU(); | 265 | [[nodiscard]] Tegra::GPU& GPU(); |
diff --git a/src/core/core_timing.cpp b/src/core/core_timing.cpp index cd4df4522..4f2692b05 100644 --- a/src/core/core_timing.cpp +++ b/src/core/core_timing.cpp | |||
| @@ -10,6 +10,10 @@ | |||
| 10 | #include "common/windows/timer_resolution.h" | 10 | #include "common/windows/timer_resolution.h" |
| 11 | #endif | 11 | #endif |
| 12 | 12 | ||
| 13 | #ifdef ARCHITECTURE_x86_64 | ||
| 14 | #include "common/x64/cpu_wait.h" | ||
| 15 | #endif | ||
| 16 | |||
| 13 | #include "common/microprofile.h" | 17 | #include "common/microprofile.h" |
| 14 | #include "core/core_timing.h" | 18 | #include "core/core_timing.h" |
| 15 | #include "core/core_timing_util.h" | 19 | #include "core/core_timing_util.h" |
| @@ -269,7 +273,11 @@ void CoreTiming::ThreadLoop() { | |||
| 269 | if (wait_time >= timer_resolution_ns) { | 273 | if (wait_time >= timer_resolution_ns) { |
| 270 | Common::Windows::SleepForOneTick(); | 274 | Common::Windows::SleepForOneTick(); |
| 271 | } else { | 275 | } else { |
| 276 | #ifdef ARCHITECTURE_x86_64 | ||
| 277 | Common::X64::MicroSleep(); | ||
| 278 | #else | ||
| 272 | std::this_thread::yield(); | 279 | std::this_thread::yield(); |
| 280 | #endif | ||
| 273 | } | 281 | } |
| 274 | } | 282 | } |
| 275 | 283 | ||
diff --git a/src/core/debugger/gdbstub.cpp b/src/core/debugger/gdbstub.cpp index 5cfb66b93..e2a13bbd2 100644 --- a/src/core/debugger/gdbstub.cpp +++ b/src/core/debugger/gdbstub.cpp | |||
| @@ -261,9 +261,9 @@ void GDBStub::ExecuteCommand(std::string_view packet, std::vector<DebuggerAction | |||
| 261 | const size_t addr{static_cast<size_t>(strtoll(command.data(), nullptr, 16))}; | 261 | const size_t addr{static_cast<size_t>(strtoll(command.data(), nullptr, 16))}; |
| 262 | const size_t size{static_cast<size_t>(strtoll(command.data() + sep, nullptr, 16))}; | 262 | const size_t size{static_cast<size_t>(strtoll(command.data() + sep, nullptr, 16))}; |
| 263 | 263 | ||
| 264 | if (system.Memory().IsValidVirtualAddressRange(addr, size)) { | 264 | if (system.ApplicationMemory().IsValidVirtualAddressRange(addr, size)) { |
| 265 | std::vector<u8> mem(size); | 265 | std::vector<u8> mem(size); |
| 266 | system.Memory().ReadBlock(addr, mem.data(), size); | 266 | system.ApplicationMemory().ReadBlock(addr, mem.data(), size); |
| 267 | 267 | ||
| 268 | SendReply(Common::HexToString(mem)); | 268 | SendReply(Common::HexToString(mem)); |
| 269 | } else { | 269 | } else { |
| @@ -281,8 +281,8 @@ void GDBStub::ExecuteCommand(std::string_view packet, std::vector<DebuggerAction | |||
| 281 | const auto mem_substr{std::string_view(command).substr(mem_sep)}; | 281 | const auto mem_substr{std::string_view(command).substr(mem_sep)}; |
| 282 | const auto mem{Common::HexStringToVector(mem_substr, false)}; | 282 | const auto mem{Common::HexStringToVector(mem_substr, false)}; |
| 283 | 283 | ||
| 284 | if (system.Memory().IsValidVirtualAddressRange(addr, size)) { | 284 | if (system.ApplicationMemory().IsValidVirtualAddressRange(addr, size)) { |
| 285 | system.Memory().WriteBlock(addr, mem.data(), size); | 285 | system.ApplicationMemory().WriteBlock(addr, mem.data(), size); |
| 286 | system.InvalidateCpuInstructionCacheRange(addr, size); | 286 | system.InvalidateCpuInstructionCacheRange(addr, size); |
| 287 | SendReply(GDB_STUB_REPLY_OK); | 287 | SendReply(GDB_STUB_REPLY_OK); |
| 288 | } else { | 288 | } else { |
| @@ -325,7 +325,7 @@ void GDBStub::HandleBreakpointInsert(std::string_view command) { | |||
| 325 | const size_t addr{static_cast<size_t>(strtoll(command.data() + addr_sep, nullptr, 16))}; | 325 | const size_t addr{static_cast<size_t>(strtoll(command.data() + addr_sep, nullptr, 16))}; |
| 326 | const size_t size{static_cast<size_t>(strtoll(command.data() + size_sep, nullptr, 16))}; | 326 | const size_t size{static_cast<size_t>(strtoll(command.data() + size_sep, nullptr, 16))}; |
| 327 | 327 | ||
| 328 | if (!system.Memory().IsValidVirtualAddressRange(addr, size)) { | 328 | if (!system.ApplicationMemory().IsValidVirtualAddressRange(addr, size)) { |
| 329 | SendReply(GDB_STUB_REPLY_ERR); | 329 | SendReply(GDB_STUB_REPLY_ERR); |
| 330 | return; | 330 | return; |
| 331 | } | 331 | } |
| @@ -334,22 +334,22 @@ void GDBStub::HandleBreakpointInsert(std::string_view command) { | |||
| 334 | 334 | ||
| 335 | switch (type) { | 335 | switch (type) { |
| 336 | case BreakpointType::Software: | 336 | case BreakpointType::Software: |
| 337 | replaced_instructions[addr] = system.Memory().Read32(addr); | 337 | replaced_instructions[addr] = system.ApplicationMemory().Read32(addr); |
| 338 | system.Memory().Write32(addr, arch->BreakpointInstruction()); | 338 | system.ApplicationMemory().Write32(addr, arch->BreakpointInstruction()); |
| 339 | system.InvalidateCpuInstructionCacheRange(addr, sizeof(u32)); | 339 | system.InvalidateCpuInstructionCacheRange(addr, sizeof(u32)); |
| 340 | success = true; | 340 | success = true; |
| 341 | break; | 341 | break; |
| 342 | case BreakpointType::WriteWatch: | 342 | case BreakpointType::WriteWatch: |
| 343 | success = system.ApplicationProcess()->InsertWatchpoint(system, addr, size, | 343 | success = system.ApplicationProcess()->InsertWatchpoint(addr, size, |
| 344 | Kernel::DebugWatchpointType::Write); | 344 | Kernel::DebugWatchpointType::Write); |
| 345 | break; | 345 | break; |
| 346 | case BreakpointType::ReadWatch: | 346 | case BreakpointType::ReadWatch: |
| 347 | success = system.ApplicationProcess()->InsertWatchpoint(system, addr, size, | 347 | success = system.ApplicationProcess()->InsertWatchpoint(addr, size, |
| 348 | Kernel::DebugWatchpointType::Read); | 348 | Kernel::DebugWatchpointType::Read); |
| 349 | break; | 349 | break; |
| 350 | case BreakpointType::AccessWatch: | 350 | case BreakpointType::AccessWatch: |
| 351 | success = system.ApplicationProcess()->InsertWatchpoint( | 351 | success = system.ApplicationProcess()->InsertWatchpoint( |
| 352 | system, addr, size, Kernel::DebugWatchpointType::ReadOrWrite); | 352 | addr, size, Kernel::DebugWatchpointType::ReadOrWrite); |
| 353 | break; | 353 | break; |
| 354 | case BreakpointType::Hardware: | 354 | case BreakpointType::Hardware: |
| 355 | default: | 355 | default: |
| @@ -372,7 +372,7 @@ void GDBStub::HandleBreakpointRemove(std::string_view command) { | |||
| 372 | const size_t addr{static_cast<size_t>(strtoll(command.data() + addr_sep, nullptr, 16))}; | 372 | const size_t addr{static_cast<size_t>(strtoll(command.data() + addr_sep, nullptr, 16))}; |
| 373 | const size_t size{static_cast<size_t>(strtoll(command.data() + size_sep, nullptr, 16))}; | 373 | const size_t size{static_cast<size_t>(strtoll(command.data() + size_sep, nullptr, 16))}; |
| 374 | 374 | ||
| 375 | if (!system.Memory().IsValidVirtualAddressRange(addr, size)) { | 375 | if (!system.ApplicationMemory().IsValidVirtualAddressRange(addr, size)) { |
| 376 | SendReply(GDB_STUB_REPLY_ERR); | 376 | SendReply(GDB_STUB_REPLY_ERR); |
| 377 | return; | 377 | return; |
| 378 | } | 378 | } |
| @@ -383,7 +383,7 @@ void GDBStub::HandleBreakpointRemove(std::string_view command) { | |||
| 383 | case BreakpointType::Software: { | 383 | case BreakpointType::Software: { |
| 384 | const auto orig_insn{replaced_instructions.find(addr)}; | 384 | const auto orig_insn{replaced_instructions.find(addr)}; |
| 385 | if (orig_insn != replaced_instructions.end()) { | 385 | if (orig_insn != replaced_instructions.end()) { |
| 386 | system.Memory().Write32(addr, orig_insn->second); | 386 | system.ApplicationMemory().Write32(addr, orig_insn->second); |
| 387 | system.InvalidateCpuInstructionCacheRange(addr, sizeof(u32)); | 387 | system.InvalidateCpuInstructionCacheRange(addr, sizeof(u32)); |
| 388 | replaced_instructions.erase(addr); | 388 | replaced_instructions.erase(addr); |
| 389 | success = true; | 389 | success = true; |
| @@ -391,16 +391,16 @@ void GDBStub::HandleBreakpointRemove(std::string_view command) { | |||
| 391 | break; | 391 | break; |
| 392 | } | 392 | } |
| 393 | case BreakpointType::WriteWatch: | 393 | case BreakpointType::WriteWatch: |
| 394 | success = system.ApplicationProcess()->RemoveWatchpoint(system, addr, size, | 394 | success = system.ApplicationProcess()->RemoveWatchpoint(addr, size, |
| 395 | Kernel::DebugWatchpointType::Write); | 395 | Kernel::DebugWatchpointType::Write); |
| 396 | break; | 396 | break; |
| 397 | case BreakpointType::ReadWatch: | 397 | case BreakpointType::ReadWatch: |
| 398 | success = system.ApplicationProcess()->RemoveWatchpoint(system, addr, size, | 398 | success = system.ApplicationProcess()->RemoveWatchpoint(addr, size, |
| 399 | Kernel::DebugWatchpointType::Read); | 399 | Kernel::DebugWatchpointType::Read); |
| 400 | break; | 400 | break; |
| 401 | case BreakpointType::AccessWatch: | 401 | case BreakpointType::AccessWatch: |
| 402 | success = system.ApplicationProcess()->RemoveWatchpoint( | 402 | success = system.ApplicationProcess()->RemoveWatchpoint( |
| 403 | system, addr, size, Kernel::DebugWatchpointType::ReadOrWrite); | 403 | addr, size, Kernel::DebugWatchpointType::ReadOrWrite); |
| 404 | break; | 404 | break; |
| 405 | case BreakpointType::Hardware: | 405 | case BreakpointType::Hardware: |
| 406 | default: | 406 | default: |
| @@ -483,9 +483,9 @@ static std::optional<std::string> GetNameFromThreadType64(Core::Memory::Memory& | |||
| 483 | static std::optional<std::string> GetThreadName(Core::System& system, | 483 | static std::optional<std::string> GetThreadName(Core::System& system, |
| 484 | const Kernel::KThread* thread) { | 484 | const Kernel::KThread* thread) { |
| 485 | if (system.ApplicationProcess()->Is64BitProcess()) { | 485 | if (system.ApplicationProcess()->Is64BitProcess()) { |
| 486 | return GetNameFromThreadType64(system.Memory(), thread); | 486 | return GetNameFromThreadType64(system.ApplicationMemory(), thread); |
| 487 | } else { | 487 | } else { |
| 488 | return GetNameFromThreadType32(system.Memory(), thread); | 488 | return GetNameFromThreadType32(system.ApplicationMemory(), thread); |
| 489 | } | 489 | } |
| 490 | } | 490 | } |
| 491 | 491 | ||
diff --git a/src/core/frontend/applets/applet.h b/src/core/frontend/applets/applet.h new file mode 100644 index 000000000..77fffe306 --- /dev/null +++ b/src/core/frontend/applets/applet.h | |||
| @@ -0,0 +1,14 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | namespace Core::Frontend { | ||
| 7 | |||
| 8 | class Applet { | ||
| 9 | public: | ||
| 10 | virtual ~Applet() = default; | ||
| 11 | virtual void Close() const = 0; | ||
| 12 | }; | ||
| 13 | |||
| 14 | } // namespace Core::Frontend | ||
diff --git a/src/core/frontend/applets/cabinet.cpp b/src/core/frontend/applets/cabinet.cpp index 26c7fefe3..2d501eeae 100644 --- a/src/core/frontend/applets/cabinet.cpp +++ b/src/core/frontend/applets/cabinet.cpp | |||
| @@ -10,6 +10,8 @@ namespace Core::Frontend { | |||
| 10 | 10 | ||
| 11 | CabinetApplet::~CabinetApplet() = default; | 11 | CabinetApplet::~CabinetApplet() = default; |
| 12 | 12 | ||
| 13 | void DefaultCabinetApplet::Close() const {} | ||
| 14 | |||
| 13 | void DefaultCabinetApplet::ShowCabinetApplet( | 15 | void DefaultCabinetApplet::ShowCabinetApplet( |
| 14 | const CabinetCallback& callback, const CabinetParameters& parameters, | 16 | const CabinetCallback& callback, const CabinetParameters& parameters, |
| 15 | std::shared_ptr<Service::NFP::NfpDevice> nfp_device) const { | 17 | std::shared_ptr<Service::NFP::NfpDevice> nfp_device) const { |
diff --git a/src/core/frontend/applets/cabinet.h b/src/core/frontend/applets/cabinet.h index c28a235c1..74dc5a4f6 100644 --- a/src/core/frontend/applets/cabinet.h +++ b/src/core/frontend/applets/cabinet.h | |||
| @@ -4,6 +4,7 @@ | |||
| 4 | #pragma once | 4 | #pragma once |
| 5 | 5 | ||
| 6 | #include <functional> | 6 | #include <functional> |
| 7 | #include "core/frontend/applets/applet.h" | ||
| 7 | #include "core/hle/service/nfp/nfp_types.h" | 8 | #include "core/hle/service/nfp/nfp_types.h" |
| 8 | 9 | ||
| 9 | namespace Service::NFP { | 10 | namespace Service::NFP { |
| @@ -20,7 +21,7 @@ struct CabinetParameters { | |||
| 20 | 21 | ||
| 21 | using CabinetCallback = std::function<void(bool, const std::string&)>; | 22 | using CabinetCallback = std::function<void(bool, const std::string&)>; |
| 22 | 23 | ||
| 23 | class CabinetApplet { | 24 | class CabinetApplet : public Applet { |
| 24 | public: | 25 | public: |
| 25 | virtual ~CabinetApplet(); | 26 | virtual ~CabinetApplet(); |
| 26 | virtual void ShowCabinetApplet(const CabinetCallback& callback, | 27 | virtual void ShowCabinetApplet(const CabinetCallback& callback, |
| @@ -30,6 +31,7 @@ public: | |||
| 30 | 31 | ||
| 31 | class DefaultCabinetApplet final : public CabinetApplet { | 32 | class DefaultCabinetApplet final : public CabinetApplet { |
| 32 | public: | 33 | public: |
| 34 | void Close() const override; | ||
| 33 | void ShowCabinetApplet(const CabinetCallback& callback, const CabinetParameters& parameters, | 35 | void ShowCabinetApplet(const CabinetCallback& callback, const CabinetParameters& parameters, |
| 34 | std::shared_ptr<Service::NFP::NfpDevice> nfp_device) const override; | 36 | std::shared_ptr<Service::NFP::NfpDevice> nfp_device) const override; |
| 35 | }; | 37 | }; |
diff --git a/src/core/frontend/applets/controller.cpp b/src/core/frontend/applets/controller.cpp index 52919484e..3300d4f79 100644 --- a/src/core/frontend/applets/controller.cpp +++ b/src/core/frontend/applets/controller.cpp | |||
| @@ -16,6 +16,8 @@ DefaultControllerApplet::DefaultControllerApplet(HID::HIDCore& hid_core_) : hid_ | |||
| 16 | 16 | ||
| 17 | DefaultControllerApplet::~DefaultControllerApplet() = default; | 17 | DefaultControllerApplet::~DefaultControllerApplet() = default; |
| 18 | 18 | ||
| 19 | void DefaultControllerApplet::Close() const {} | ||
| 20 | |||
| 19 | void DefaultControllerApplet::ReconfigureControllers(ReconfigureCallback callback, | 21 | void DefaultControllerApplet::ReconfigureControllers(ReconfigureCallback callback, |
| 20 | const ControllerParameters& parameters) const { | 22 | const ControllerParameters& parameters) const { |
| 21 | LOG_INFO(Service_HID, "called, deducing the best configuration based on the given parameters!"); | 23 | LOG_INFO(Service_HID, "called, deducing the best configuration based on the given parameters!"); |
| @@ -69,7 +71,7 @@ void DefaultControllerApplet::ReconfigureControllers(ReconfigureCallback callbac | |||
| 69 | } | 71 | } |
| 70 | } | 72 | } |
| 71 | 73 | ||
| 72 | callback(); | 74 | callback(true); |
| 73 | } | 75 | } |
| 74 | 76 | ||
| 75 | } // namespace Core::Frontend | 77 | } // namespace Core::Frontend |
diff --git a/src/core/frontend/applets/controller.h b/src/core/frontend/applets/controller.h index adb2feefd..19a2db6bf 100644 --- a/src/core/frontend/applets/controller.h +++ b/src/core/frontend/applets/controller.h | |||
| @@ -7,6 +7,7 @@ | |||
| 7 | #include <vector> | 7 | #include <vector> |
| 8 | 8 | ||
| 9 | #include "common/common_types.h" | 9 | #include "common/common_types.h" |
| 10 | #include "core/frontend/applets/applet.h" | ||
| 10 | 11 | ||
| 11 | namespace Core::HID { | 12 | namespace Core::HID { |
| 12 | class HIDCore; | 13 | class HIDCore; |
| @@ -34,9 +35,9 @@ struct ControllerParameters { | |||
| 34 | bool allow_gamecube_controller{}; | 35 | bool allow_gamecube_controller{}; |
| 35 | }; | 36 | }; |
| 36 | 37 | ||
| 37 | class ControllerApplet { | 38 | class ControllerApplet : public Applet { |
| 38 | public: | 39 | public: |
| 39 | using ReconfigureCallback = std::function<void()>; | 40 | using ReconfigureCallback = std::function<void(bool)>; |
| 40 | 41 | ||
| 41 | virtual ~ControllerApplet(); | 42 | virtual ~ControllerApplet(); |
| 42 | 43 | ||
| @@ -49,6 +50,7 @@ public: | |||
| 49 | explicit DefaultControllerApplet(HID::HIDCore& hid_core_); | 50 | explicit DefaultControllerApplet(HID::HIDCore& hid_core_); |
| 50 | ~DefaultControllerApplet() override; | 51 | ~DefaultControllerApplet() override; |
| 51 | 52 | ||
| 53 | void Close() const override; | ||
| 52 | void ReconfigureControllers(ReconfigureCallback callback, | 54 | void ReconfigureControllers(ReconfigureCallback callback, |
| 53 | const ControllerParameters& parameters) const override; | 55 | const ControllerParameters& parameters) const override; |
| 54 | 56 | ||
diff --git a/src/core/frontend/applets/error.cpp b/src/core/frontend/applets/error.cpp index 69c2b2b4d..2e6f7a3d9 100644 --- a/src/core/frontend/applets/error.cpp +++ b/src/core/frontend/applets/error.cpp | |||
| @@ -8,6 +8,8 @@ namespace Core::Frontend { | |||
| 8 | 8 | ||
| 9 | ErrorApplet::~ErrorApplet() = default; | 9 | ErrorApplet::~ErrorApplet() = default; |
| 10 | 10 | ||
| 11 | void DefaultErrorApplet::Close() const {} | ||
| 12 | |||
| 11 | void DefaultErrorApplet::ShowError(Result error, FinishedCallback finished) const { | 13 | void DefaultErrorApplet::ShowError(Result error, FinishedCallback finished) const { |
| 12 | LOG_CRITICAL(Service_Fatal, "Application requested error display: {:04}-{:04} (raw={:08X})", | 14 | LOG_CRITICAL(Service_Fatal, "Application requested error display: {:04}-{:04} (raw={:08X})", |
| 13 | error.module.Value(), error.description.Value(), error.raw); | 15 | error.module.Value(), error.description.Value(), error.raw); |
diff --git a/src/core/frontend/applets/error.h b/src/core/frontend/applets/error.h index 884f2f653..3a12196ce 100644 --- a/src/core/frontend/applets/error.h +++ b/src/core/frontend/applets/error.h | |||
| @@ -6,11 +6,12 @@ | |||
| 6 | #include <chrono> | 6 | #include <chrono> |
| 7 | #include <functional> | 7 | #include <functional> |
| 8 | 8 | ||
| 9 | #include "core/frontend/applets/applet.h" | ||
| 9 | #include "core/hle/result.h" | 10 | #include "core/hle/result.h" |
| 10 | 11 | ||
| 11 | namespace Core::Frontend { | 12 | namespace Core::Frontend { |
| 12 | 13 | ||
| 13 | class ErrorApplet { | 14 | class ErrorApplet : public Applet { |
| 14 | public: | 15 | public: |
| 15 | using FinishedCallback = std::function<void()>; | 16 | using FinishedCallback = std::function<void()>; |
| 16 | 17 | ||
| @@ -28,6 +29,7 @@ public: | |||
| 28 | 29 | ||
| 29 | class DefaultErrorApplet final : public ErrorApplet { | 30 | class DefaultErrorApplet final : public ErrorApplet { |
| 30 | public: | 31 | public: |
| 32 | void Close() const override; | ||
| 31 | void ShowError(Result error, FinishedCallback finished) const override; | 33 | void ShowError(Result error, FinishedCallback finished) const override; |
| 32 | void ShowErrorWithTimestamp(Result error, std::chrono::seconds time, | 34 | void ShowErrorWithTimestamp(Result error, std::chrono::seconds time, |
| 33 | FinishedCallback finished) const override; | 35 | FinishedCallback finished) const override; |
diff --git a/src/core/frontend/applets/general_frontend.cpp b/src/core/frontend/applets/general_frontend.cpp index 29a00fb6f..b4b213a31 100644 --- a/src/core/frontend/applets/general_frontend.cpp +++ b/src/core/frontend/applets/general_frontend.cpp | |||
| @@ -10,6 +10,8 @@ ParentalControlsApplet::~ParentalControlsApplet() = default; | |||
| 10 | 10 | ||
| 11 | DefaultParentalControlsApplet::~DefaultParentalControlsApplet() = default; | 11 | DefaultParentalControlsApplet::~DefaultParentalControlsApplet() = default; |
| 12 | 12 | ||
| 13 | void DefaultParentalControlsApplet::Close() const {} | ||
| 14 | |||
| 13 | void DefaultParentalControlsApplet::VerifyPIN(std::function<void(bool)> finished, | 15 | void DefaultParentalControlsApplet::VerifyPIN(std::function<void(bool)> finished, |
| 14 | bool suspend_future_verification_temporarily) { | 16 | bool suspend_future_verification_temporarily) { |
| 15 | LOG_INFO(Service_AM, | 17 | LOG_INFO(Service_AM, |
| @@ -39,6 +41,8 @@ PhotoViewerApplet::~PhotoViewerApplet() = default; | |||
| 39 | 41 | ||
| 40 | DefaultPhotoViewerApplet::~DefaultPhotoViewerApplet() = default; | 42 | DefaultPhotoViewerApplet::~DefaultPhotoViewerApplet() = default; |
| 41 | 43 | ||
| 44 | void DefaultPhotoViewerApplet::Close() const {} | ||
| 45 | |||
| 42 | void DefaultPhotoViewerApplet::ShowPhotosForApplication(u64 title_id, | 46 | void DefaultPhotoViewerApplet::ShowPhotosForApplication(u64 title_id, |
| 43 | std::function<void()> finished) const { | 47 | std::function<void()> finished) const { |
| 44 | LOG_INFO(Service_AM, | 48 | LOG_INFO(Service_AM, |
diff --git a/src/core/frontend/applets/general_frontend.h b/src/core/frontend/applets/general_frontend.h index cbec8b4ad..319838ac7 100644 --- a/src/core/frontend/applets/general_frontend.h +++ b/src/core/frontend/applets/general_frontend.h | |||
| @@ -6,9 +6,11 @@ | |||
| 6 | #include <functional> | 6 | #include <functional> |
| 7 | #include "common/common_types.h" | 7 | #include "common/common_types.h" |
| 8 | 8 | ||
| 9 | #include "core/frontend/applets/applet.h" | ||
| 10 | |||
| 9 | namespace Core::Frontend { | 11 | namespace Core::Frontend { |
| 10 | 12 | ||
| 11 | class ParentalControlsApplet { | 13 | class ParentalControlsApplet : public Applet { |
| 12 | public: | 14 | public: |
| 13 | virtual ~ParentalControlsApplet(); | 15 | virtual ~ParentalControlsApplet(); |
| 14 | 16 | ||
| @@ -33,6 +35,7 @@ class DefaultParentalControlsApplet final : public ParentalControlsApplet { | |||
| 33 | public: | 35 | public: |
| 34 | ~DefaultParentalControlsApplet() override; | 36 | ~DefaultParentalControlsApplet() override; |
| 35 | 37 | ||
| 38 | void Close() const override; | ||
| 36 | void VerifyPIN(std::function<void(bool)> finished, | 39 | void VerifyPIN(std::function<void(bool)> finished, |
| 37 | bool suspend_future_verification_temporarily) override; | 40 | bool suspend_future_verification_temporarily) override; |
| 38 | void VerifyPINForSettings(std::function<void(bool)> finished) override; | 41 | void VerifyPINForSettings(std::function<void(bool)> finished) override; |
| @@ -40,7 +43,7 @@ public: | |||
| 40 | void ChangePIN(std::function<void()> finished) override; | 43 | void ChangePIN(std::function<void()> finished) override; |
| 41 | }; | 44 | }; |
| 42 | 45 | ||
| 43 | class PhotoViewerApplet { | 46 | class PhotoViewerApplet : public Applet { |
| 44 | public: | 47 | public: |
| 45 | virtual ~PhotoViewerApplet(); | 48 | virtual ~PhotoViewerApplet(); |
| 46 | 49 | ||
| @@ -52,6 +55,7 @@ class DefaultPhotoViewerApplet final : public PhotoViewerApplet { | |||
| 52 | public: | 55 | public: |
| 53 | ~DefaultPhotoViewerApplet() override; | 56 | ~DefaultPhotoViewerApplet() override; |
| 54 | 57 | ||
| 58 | void Close() const override; | ||
| 55 | void ShowPhotosForApplication(u64 title_id, std::function<void()> finished) const override; | 59 | void ShowPhotosForApplication(u64 title_id, std::function<void()> finished) const override; |
| 56 | void ShowAllPhotos(std::function<void()> finished) const override; | 60 | void ShowAllPhotos(std::function<void()> finished) const override; |
| 57 | }; | 61 | }; |
diff --git a/src/core/frontend/applets/mii_edit.cpp b/src/core/frontend/applets/mii_edit.cpp index bc8c57067..2988c3e72 100644 --- a/src/core/frontend/applets/mii_edit.cpp +++ b/src/core/frontend/applets/mii_edit.cpp | |||
| @@ -8,6 +8,8 @@ namespace Core::Frontend { | |||
| 8 | 8 | ||
| 9 | MiiEditApplet::~MiiEditApplet() = default; | 9 | MiiEditApplet::~MiiEditApplet() = default; |
| 10 | 10 | ||
| 11 | void DefaultMiiEditApplet::Close() const {} | ||
| 12 | |||
| 11 | void DefaultMiiEditApplet::ShowMiiEdit(const MiiEditCallback& callback) const { | 13 | void DefaultMiiEditApplet::ShowMiiEdit(const MiiEditCallback& callback) const { |
| 12 | LOG_WARNING(Service_AM, "(STUBBED) called"); | 14 | LOG_WARNING(Service_AM, "(STUBBED) called"); |
| 13 | 15 | ||
diff --git a/src/core/frontend/applets/mii_edit.h b/src/core/frontend/applets/mii_edit.h index d828f06ec..9d86ee658 100644 --- a/src/core/frontend/applets/mii_edit.h +++ b/src/core/frontend/applets/mii_edit.h | |||
| @@ -5,9 +5,11 @@ | |||
| 5 | 5 | ||
| 6 | #include <functional> | 6 | #include <functional> |
| 7 | 7 | ||
| 8 | #include "core/frontend/applets/applet.h" | ||
| 9 | |||
| 8 | namespace Core::Frontend { | 10 | namespace Core::Frontend { |
| 9 | 11 | ||
| 10 | class MiiEditApplet { | 12 | class MiiEditApplet : public Applet { |
| 11 | public: | 13 | public: |
| 12 | using MiiEditCallback = std::function<void()>; | 14 | using MiiEditCallback = std::function<void()>; |
| 13 | 15 | ||
| @@ -18,6 +20,7 @@ public: | |||
| 18 | 20 | ||
| 19 | class DefaultMiiEditApplet final : public MiiEditApplet { | 21 | class DefaultMiiEditApplet final : public MiiEditApplet { |
| 20 | public: | 22 | public: |
| 23 | void Close() const override; | ||
| 21 | void ShowMiiEdit(const MiiEditCallback& callback) const override; | 24 | void ShowMiiEdit(const MiiEditCallback& callback) const override; |
| 22 | }; | 25 | }; |
| 23 | 26 | ||
diff --git a/src/core/frontend/applets/profile_select.cpp b/src/core/frontend/applets/profile_select.cpp index da4cfbf87..c18f17a36 100644 --- a/src/core/frontend/applets/profile_select.cpp +++ b/src/core/frontend/applets/profile_select.cpp | |||
| @@ -9,7 +9,10 @@ namespace Core::Frontend { | |||
| 9 | 9 | ||
| 10 | ProfileSelectApplet::~ProfileSelectApplet() = default; | 10 | ProfileSelectApplet::~ProfileSelectApplet() = default; |
| 11 | 11 | ||
| 12 | void DefaultProfileSelectApplet::SelectProfile(SelectProfileCallback callback) const { | 12 | void DefaultProfileSelectApplet::Close() const {} |
| 13 | |||
| 14 | void DefaultProfileSelectApplet::SelectProfile(SelectProfileCallback callback, | ||
| 15 | const ProfileSelectParameters& parameters) const { | ||
| 13 | Service::Account::ProfileManager manager; | 16 | Service::Account::ProfileManager manager; |
| 14 | callback(manager.GetUser(Settings::values.current_user.GetValue()).value_or(Common::UUID{})); | 17 | callback(manager.GetUser(Settings::values.current_user.GetValue()).value_or(Common::UUID{})); |
| 15 | LOG_INFO(Service_ACC, "called, selecting current user instead of prompting..."); | 18 | LOG_INFO(Service_ACC, "called, selecting current user instead of prompting..."); |
diff --git a/src/core/frontend/applets/profile_select.h b/src/core/frontend/applets/profile_select.h index 138429533..92e2737ea 100644 --- a/src/core/frontend/applets/profile_select.h +++ b/src/core/frontend/applets/profile_select.h | |||
| @@ -5,22 +5,35 @@ | |||
| 5 | 5 | ||
| 6 | #include <functional> | 6 | #include <functional> |
| 7 | #include <optional> | 7 | #include <optional> |
| 8 | |||
| 8 | #include "common/uuid.h" | 9 | #include "common/uuid.h" |
| 10 | #include "core/frontend/applets/applet.h" | ||
| 11 | #include "core/hle/service/am/applets/applet_profile_select.h" | ||
| 9 | 12 | ||
| 10 | namespace Core::Frontend { | 13 | namespace Core::Frontend { |
| 11 | 14 | ||
| 12 | class ProfileSelectApplet { | 15 | struct ProfileSelectParameters { |
| 16 | Service::AM::Applets::UiMode mode; | ||
| 17 | std::array<Common::UUID, 8> invalid_uid_list; | ||
| 18 | Service::AM::Applets::UiSettingsDisplayOptions display_options; | ||
| 19 | Service::AM::Applets::UserSelectionPurpose purpose; | ||
| 20 | }; | ||
| 21 | |||
| 22 | class ProfileSelectApplet : public Applet { | ||
| 13 | public: | 23 | public: |
| 14 | using SelectProfileCallback = std::function<void(std::optional<Common::UUID>)>; | 24 | using SelectProfileCallback = std::function<void(std::optional<Common::UUID>)>; |
| 15 | 25 | ||
| 16 | virtual ~ProfileSelectApplet(); | 26 | virtual ~ProfileSelectApplet(); |
| 17 | 27 | ||
| 18 | virtual void SelectProfile(SelectProfileCallback callback) const = 0; | 28 | virtual void SelectProfile(SelectProfileCallback callback, |
| 29 | const ProfileSelectParameters& parameters) const = 0; | ||
| 19 | }; | 30 | }; |
| 20 | 31 | ||
| 21 | class DefaultProfileSelectApplet final : public ProfileSelectApplet { | 32 | class DefaultProfileSelectApplet final : public ProfileSelectApplet { |
| 22 | public: | 33 | public: |
| 23 | void SelectProfile(SelectProfileCallback callback) const override; | 34 | void Close() const override; |
| 35 | void SelectProfile(SelectProfileCallback callback, | ||
| 36 | const ProfileSelectParameters& parameters) const override; | ||
| 24 | }; | 37 | }; |
| 25 | 38 | ||
| 26 | } // namespace Core::Frontend | 39 | } // namespace Core::Frontend |
diff --git a/src/core/frontend/applets/software_keyboard.cpp b/src/core/frontend/applets/software_keyboard.cpp index a3720f4d7..7655d215b 100644 --- a/src/core/frontend/applets/software_keyboard.cpp +++ b/src/core/frontend/applets/software_keyboard.cpp | |||
| @@ -13,6 +13,8 @@ SoftwareKeyboardApplet::~SoftwareKeyboardApplet() = default; | |||
| 13 | 13 | ||
| 14 | DefaultSoftwareKeyboardApplet::~DefaultSoftwareKeyboardApplet() = default; | 14 | DefaultSoftwareKeyboardApplet::~DefaultSoftwareKeyboardApplet() = default; |
| 15 | 15 | ||
| 16 | void DefaultSoftwareKeyboardApplet::Close() const {} | ||
| 17 | |||
| 16 | void DefaultSoftwareKeyboardApplet::InitializeKeyboard( | 18 | void DefaultSoftwareKeyboardApplet::InitializeKeyboard( |
| 17 | bool is_inline, KeyboardInitializeParameters initialize_parameters, | 19 | bool is_inline, KeyboardInitializeParameters initialize_parameters, |
| 18 | SubmitNormalCallback submit_normal_callback_, SubmitInlineCallback submit_inline_callback_) { | 20 | SubmitNormalCallback submit_normal_callback_, SubmitInlineCallback submit_inline_callback_) { |
diff --git a/src/core/frontend/applets/software_keyboard.h b/src/core/frontend/applets/software_keyboard.h index 8aef103d3..8ed96da24 100644 --- a/src/core/frontend/applets/software_keyboard.h +++ b/src/core/frontend/applets/software_keyboard.h | |||
| @@ -7,6 +7,7 @@ | |||
| 7 | 7 | ||
| 8 | #include "common/common_types.h" | 8 | #include "common/common_types.h" |
| 9 | 9 | ||
| 10 | #include "core/frontend/applets/applet.h" | ||
| 10 | #include "core/hle/service/am/applets/applet_software_keyboard_types.h" | 11 | #include "core/hle/service/am/applets/applet_software_keyboard_types.h" |
| 11 | 12 | ||
| 12 | namespace Core::Frontend { | 13 | namespace Core::Frontend { |
| @@ -52,7 +53,7 @@ struct InlineTextParameters { | |||
| 52 | s32 cursor_position; | 53 | s32 cursor_position; |
| 53 | }; | 54 | }; |
| 54 | 55 | ||
| 55 | class SoftwareKeyboardApplet { | 56 | class SoftwareKeyboardApplet : public Applet { |
| 56 | public: | 57 | public: |
| 57 | using SubmitInlineCallback = | 58 | using SubmitInlineCallback = |
| 58 | std::function<void(Service::AM::Applets::SwkbdReplyType, std::u16string, s32)>; | 59 | std::function<void(Service::AM::Applets::SwkbdReplyType, std::u16string, s32)>; |
| @@ -84,6 +85,8 @@ class DefaultSoftwareKeyboardApplet final : public SoftwareKeyboardApplet { | |||
| 84 | public: | 85 | public: |
| 85 | ~DefaultSoftwareKeyboardApplet() override; | 86 | ~DefaultSoftwareKeyboardApplet() override; |
| 86 | 87 | ||
| 88 | void Close() const override; | ||
| 89 | |||
| 87 | void InitializeKeyboard(bool is_inline, KeyboardInitializeParameters initialize_parameters, | 90 | void InitializeKeyboard(bool is_inline, KeyboardInitializeParameters initialize_parameters, |
| 88 | SubmitNormalCallback submit_normal_callback_, | 91 | SubmitNormalCallback submit_normal_callback_, |
| 89 | SubmitInlineCallback submit_inline_callback_) override; | 92 | SubmitInlineCallback submit_inline_callback_) override; |
diff --git a/src/core/frontend/applets/web_browser.cpp b/src/core/frontend/applets/web_browser.cpp index b09cb7102..6e703ef06 100644 --- a/src/core/frontend/applets/web_browser.cpp +++ b/src/core/frontend/applets/web_browser.cpp | |||
| @@ -10,6 +10,8 @@ WebBrowserApplet::~WebBrowserApplet() = default; | |||
| 10 | 10 | ||
| 11 | DefaultWebBrowserApplet::~DefaultWebBrowserApplet() = default; | 11 | DefaultWebBrowserApplet::~DefaultWebBrowserApplet() = default; |
| 12 | 12 | ||
| 13 | void DefaultWebBrowserApplet::Close() const {} | ||
| 14 | |||
| 13 | void DefaultWebBrowserApplet::OpenLocalWebPage(const std::string& local_url, | 15 | void DefaultWebBrowserApplet::OpenLocalWebPage(const std::string& local_url, |
| 14 | ExtractROMFSCallback extract_romfs_callback, | 16 | ExtractROMFSCallback extract_romfs_callback, |
| 15 | OpenWebPageCallback callback) const { | 17 | OpenWebPageCallback callback) const { |
diff --git a/src/core/frontend/applets/web_browser.h b/src/core/frontend/applets/web_browser.h index 4f72284ad..178bbdd3f 100644 --- a/src/core/frontend/applets/web_browser.h +++ b/src/core/frontend/applets/web_browser.h | |||
| @@ -5,11 +5,12 @@ | |||
| 5 | 5 | ||
| 6 | #include <functional> | 6 | #include <functional> |
| 7 | 7 | ||
| 8 | #include "core/frontend/applets/applet.h" | ||
| 8 | #include "core/hle/service/am/applets/applet_web_browser_types.h" | 9 | #include "core/hle/service/am/applets/applet_web_browser_types.h" |
| 9 | 10 | ||
| 10 | namespace Core::Frontend { | 11 | namespace Core::Frontend { |
| 11 | 12 | ||
| 12 | class WebBrowserApplet { | 13 | class WebBrowserApplet : public Applet { |
| 13 | public: | 14 | public: |
| 14 | using ExtractROMFSCallback = std::function<void()>; | 15 | using ExtractROMFSCallback = std::function<void()>; |
| 15 | using OpenWebPageCallback = | 16 | using OpenWebPageCallback = |
| @@ -29,6 +30,8 @@ class DefaultWebBrowserApplet final : public WebBrowserApplet { | |||
| 29 | public: | 30 | public: |
| 30 | ~DefaultWebBrowserApplet() override; | 31 | ~DefaultWebBrowserApplet() override; |
| 31 | 32 | ||
| 33 | void Close() const override; | ||
| 34 | |||
| 32 | void OpenLocalWebPage(const std::string& local_url, ExtractROMFSCallback extract_romfs_callback, | 35 | void OpenLocalWebPage(const std::string& local_url, ExtractROMFSCallback extract_romfs_callback, |
| 33 | OpenWebPageCallback callback) const override; | 36 | OpenWebPageCallback callback) const override; |
| 34 | 37 | ||
diff --git a/src/core/hle/kernel/k_address_arbiter.cpp b/src/core/hle/kernel/k_address_arbiter.cpp index 274928dcf..78d43d729 100644 --- a/src/core/hle/kernel/k_address_arbiter.cpp +++ b/src/core/hle/kernel/k_address_arbiter.cpp | |||
| @@ -21,8 +21,8 @@ KAddressArbiter::~KAddressArbiter() = default; | |||
| 21 | 21 | ||
| 22 | namespace { | 22 | namespace { |
| 23 | 23 | ||
| 24 | bool ReadFromUser(Core::System& system, s32* out, KProcessAddress address) { | 24 | bool ReadFromUser(KernelCore& kernel, s32* out, KProcessAddress address) { |
| 25 | *out = system.Memory().Read32(GetInteger(address)); | 25 | *out = GetCurrentMemory(kernel).Read32(GetInteger(address)); |
| 26 | return true; | 26 | return true; |
| 27 | } | 27 | } |
| 28 | 28 | ||
| @@ -35,24 +35,30 @@ bool DecrementIfLessThan(Core::System& system, s32* out, KProcessAddress address | |||
| 35 | 35 | ||
| 36 | // TODO(bunnei): We should call CanAccessAtomic(..) here. | 36 | // TODO(bunnei): We should call CanAccessAtomic(..) here. |
| 37 | 37 | ||
| 38 | // Load the value from the address. | 38 | s32 current_value{}; |
| 39 | const s32 current_value = | 39 | |
| 40 | static_cast<s32>(monitor.ExclusiveRead32(current_core, GetInteger(address))); | 40 | while (true) { |
| 41 | // Load the value from the address. | ||
| 42 | current_value = | ||
| 43 | static_cast<s32>(monitor.ExclusiveRead32(current_core, GetInteger(address))); | ||
| 41 | 44 | ||
| 42 | // Compare it to the desired one. | 45 | // Compare it to the desired one. |
| 43 | if (current_value < value) { | 46 | if (current_value < value) { |
| 44 | // If less than, we want to try to decrement. | 47 | // If less than, we want to try to decrement. |
| 45 | const s32 decrement_value = current_value - 1; | 48 | const s32 decrement_value = current_value - 1; |
| 49 | |||
| 50 | // Decrement and try to store. | ||
| 51 | if (monitor.ExclusiveWrite32(current_core, GetInteger(address), | ||
| 52 | static_cast<u32>(decrement_value))) { | ||
| 53 | break; | ||
| 54 | } | ||
| 46 | 55 | ||
| 47 | // Decrement and try to store. | ||
| 48 | if (!monitor.ExclusiveWrite32(current_core, GetInteger(address), | ||
| 49 | static_cast<u32>(decrement_value))) { | ||
| 50 | // If we failed to store, try again. | 56 | // If we failed to store, try again. |
| 51 | DecrementIfLessThan(system, out, address, value); | 57 | } else { |
| 58 | // Otherwise, clear our exclusive hold and finish | ||
| 59 | monitor.ClearExclusive(current_core); | ||
| 60 | break; | ||
| 52 | } | 61 | } |
| 53 | } else { | ||
| 54 | // Otherwise, clear our exclusive hold and finish | ||
| 55 | monitor.ClearExclusive(current_core); | ||
| 56 | } | 62 | } |
| 57 | 63 | ||
| 58 | // We're done. | 64 | // We're done. |
| @@ -70,23 +76,29 @@ bool UpdateIfEqual(Core::System& system, s32* out, KProcessAddress address, s32 | |||
| 70 | 76 | ||
| 71 | // TODO(bunnei): We should call CanAccessAtomic(..) here. | 77 | // TODO(bunnei): We should call CanAccessAtomic(..) here. |
| 72 | 78 | ||
| 73 | // Load the value from the address. | 79 | s32 current_value{}; |
| 74 | const s32 current_value = | ||
| 75 | static_cast<s32>(monitor.ExclusiveRead32(current_core, GetInteger(address))); | ||
| 76 | 80 | ||
| 77 | // Compare it to the desired one. | 81 | // Load the value from the address. |
| 78 | if (current_value == value) { | 82 | while (true) { |
| 79 | // If equal, we want to try to write the new value. | 83 | current_value = |
| 84 | static_cast<s32>(monitor.ExclusiveRead32(current_core, GetInteger(address))); | ||
| 85 | |||
| 86 | // Compare it to the desired one. | ||
| 87 | if (current_value == value) { | ||
| 88 | // If equal, we want to try to write the new value. | ||
| 89 | |||
| 90 | // Try to store. | ||
| 91 | if (monitor.ExclusiveWrite32(current_core, GetInteger(address), | ||
| 92 | static_cast<u32>(new_value))) { | ||
| 93 | break; | ||
| 94 | } | ||
| 80 | 95 | ||
| 81 | // Try to store. | ||
| 82 | if (!monitor.ExclusiveWrite32(current_core, GetInteger(address), | ||
| 83 | static_cast<u32>(new_value))) { | ||
| 84 | // If we failed to store, try again. | 96 | // If we failed to store, try again. |
| 85 | UpdateIfEqual(system, out, address, value, new_value); | 97 | } else { |
| 98 | // Otherwise, clear our exclusive hold and finish. | ||
| 99 | monitor.ClearExclusive(current_core); | ||
| 100 | break; | ||
| 86 | } | 101 | } |
| 87 | } else { | ||
| 88 | // Otherwise, clear our exclusive hold and finish. | ||
| 89 | monitor.ClearExclusive(current_core); | ||
| 90 | } | 102 | } |
| 91 | 103 | ||
| 92 | // We're done. | 104 | // We're done. |
| @@ -209,7 +221,7 @@ Result KAddressArbiter::SignalAndModifyByWaitingCountIfEqual(uint64_t addr, s32 | |||
| 209 | if (value != new_value) { | 221 | if (value != new_value) { |
| 210 | succeeded = UpdateIfEqual(m_system, std::addressof(user_value), addr, value, new_value); | 222 | succeeded = UpdateIfEqual(m_system, std::addressof(user_value), addr, value, new_value); |
| 211 | } else { | 223 | } else { |
| 212 | succeeded = ReadFromUser(m_system, std::addressof(user_value), addr); | 224 | succeeded = ReadFromUser(m_kernel, std::addressof(user_value), addr); |
| 213 | } | 225 | } |
| 214 | 226 | ||
| 215 | R_UNLESS(succeeded, ResultInvalidCurrentMemory); | 227 | R_UNLESS(succeeded, ResultInvalidCurrentMemory); |
| @@ -252,7 +264,7 @@ Result KAddressArbiter::WaitIfLessThan(uint64_t addr, s32 value, bool decrement, | |||
| 252 | if (decrement) { | 264 | if (decrement) { |
| 253 | succeeded = DecrementIfLessThan(m_system, std::addressof(user_value), addr, value); | 265 | succeeded = DecrementIfLessThan(m_system, std::addressof(user_value), addr, value); |
| 254 | } else { | 266 | } else { |
| 255 | succeeded = ReadFromUser(m_system, std::addressof(user_value), addr); | 267 | succeeded = ReadFromUser(m_kernel, std::addressof(user_value), addr); |
| 256 | } | 268 | } |
| 257 | 269 | ||
| 258 | if (!succeeded) { | 270 | if (!succeeded) { |
| @@ -303,7 +315,7 @@ Result KAddressArbiter::WaitIfEqual(uint64_t addr, s32 value, s64 timeout) { | |||
| 303 | 315 | ||
| 304 | // Read the value from userspace. | 316 | // Read the value from userspace. |
| 305 | s32 user_value{}; | 317 | s32 user_value{}; |
| 306 | if (!ReadFromUser(m_system, std::addressof(user_value), addr)) { | 318 | if (!ReadFromUser(m_kernel, std::addressof(user_value), addr)) { |
| 307 | slp.CancelSleep(); | 319 | slp.CancelSleep(); |
| 308 | R_THROW(ResultInvalidCurrentMemory); | 320 | R_THROW(ResultInvalidCurrentMemory); |
| 309 | } | 321 | } |
diff --git a/src/core/hle/kernel/k_condition_variable.cpp b/src/core/hle/kernel/k_condition_variable.cpp index c6634313f..efbac0e6a 100644 --- a/src/core/hle/kernel/k_condition_variable.cpp +++ b/src/core/hle/kernel/k_condition_variable.cpp | |||
| @@ -18,13 +18,13 @@ namespace Kernel { | |||
| 18 | 18 | ||
| 19 | namespace { | 19 | namespace { |
| 20 | 20 | ||
| 21 | bool ReadFromUser(Core::System& system, u32* out, KProcessAddress address) { | 21 | bool ReadFromUser(KernelCore& kernel, u32* out, KProcessAddress address) { |
| 22 | *out = system.Memory().Read32(GetInteger(address)); | 22 | *out = GetCurrentMemory(kernel).Read32(GetInteger(address)); |
| 23 | return true; | 23 | return true; |
| 24 | } | 24 | } |
| 25 | 25 | ||
| 26 | bool WriteToUser(Core::System& system, KProcessAddress address, const u32* p) { | 26 | bool WriteToUser(KernelCore& kernel, KProcessAddress address, const u32* p) { |
| 27 | system.Memory().Write32(GetInteger(address), *p); | 27 | GetCurrentMemory(kernel).Write32(GetInteger(address), *p); |
| 28 | return true; | 28 | return true; |
| 29 | } | 29 | } |
| 30 | 30 | ||
| @@ -33,21 +33,26 @@ bool UpdateLockAtomic(Core::System& system, u32* out, KProcessAddress address, u | |||
| 33 | auto& monitor = system.Monitor(); | 33 | auto& monitor = system.Monitor(); |
| 34 | const auto current_core = system.Kernel().CurrentPhysicalCoreIndex(); | 34 | const auto current_core = system.Kernel().CurrentPhysicalCoreIndex(); |
| 35 | 35 | ||
| 36 | // Load the value from the address. | 36 | u32 expected{}; |
| 37 | const auto expected = monitor.ExclusiveRead32(current_core, GetInteger(address)); | ||
| 38 | 37 | ||
| 39 | // Orr in the new mask. | 38 | while (true) { |
| 40 | u32 value = expected | new_orr_mask; | 39 | // Load the value from the address. |
| 40 | expected = monitor.ExclusiveRead32(current_core, GetInteger(address)); | ||
| 41 | 41 | ||
| 42 | // If the value is zero, use the if_zero value, otherwise use the newly orr'd value. | 42 | // Orr in the new mask. |
| 43 | if (!expected) { | 43 | u32 value = expected | new_orr_mask; |
| 44 | value = if_zero; | 44 | |
| 45 | } | 45 | // If the value is zero, use the if_zero value, otherwise use the newly orr'd value. |
| 46 | if (!expected) { | ||
| 47 | value = if_zero; | ||
| 48 | } | ||
| 49 | |||
| 50 | // Try to store. | ||
| 51 | if (monitor.ExclusiveWrite32(current_core, GetInteger(address), value)) { | ||
| 52 | break; | ||
| 53 | } | ||
| 46 | 54 | ||
| 47 | // Try to store. | ||
| 48 | if (!monitor.ExclusiveWrite32(current_core, GetInteger(address), value)) { | ||
| 49 | // If we failed to store, try again. | 55 | // If we failed to store, try again. |
| 50 | return UpdateLockAtomic(system, out, address, if_zero, new_orr_mask); | ||
| 51 | } | 56 | } |
| 52 | 57 | ||
| 53 | // We're done. | 58 | // We're done. |
| @@ -128,7 +133,7 @@ Result KConditionVariable::SignalToAddress(KProcessAddress addr) { | |||
| 128 | 133 | ||
| 129 | // Write the value to userspace. | 134 | // Write the value to userspace. |
| 130 | Result result{ResultSuccess}; | 135 | Result result{ResultSuccess}; |
| 131 | if (WriteToUser(m_system, addr, std::addressof(next_value))) [[likely]] { | 136 | if (WriteToUser(m_kernel, addr, std::addressof(next_value))) [[likely]] { |
| 132 | result = ResultSuccess; | 137 | result = ResultSuccess; |
| 133 | } else { | 138 | } else { |
| 134 | result = ResultInvalidCurrentMemory; | 139 | result = ResultInvalidCurrentMemory; |
| @@ -157,7 +162,7 @@ Result KConditionVariable::WaitForAddress(Handle handle, KProcessAddress addr, u | |||
| 157 | 162 | ||
| 158 | // Read the tag from userspace. | 163 | // Read the tag from userspace. |
| 159 | u32 test_tag{}; | 164 | u32 test_tag{}; |
| 160 | R_UNLESS(ReadFromUser(m_system, std::addressof(test_tag), addr), | 165 | R_UNLESS(ReadFromUser(m_kernel, std::addressof(test_tag), addr), |
| 161 | ResultInvalidCurrentMemory); | 166 | ResultInvalidCurrentMemory); |
| 162 | 167 | ||
| 163 | // If the tag isn't the handle (with wait mask), we're done. | 168 | // If the tag isn't the handle (with wait mask), we're done. |
| @@ -257,7 +262,7 @@ void KConditionVariable::Signal(u64 cv_key, s32 count) { | |||
| 257 | // If we have no waiters, clear the has waiter flag. | 262 | // If we have no waiters, clear the has waiter flag. |
| 258 | if (it == m_tree.end() || it->GetConditionVariableKey() != cv_key) { | 263 | if (it == m_tree.end() || it->GetConditionVariableKey() != cv_key) { |
| 259 | const u32 has_waiter_flag{}; | 264 | const u32 has_waiter_flag{}; |
| 260 | WriteToUser(m_system, cv_key, std::addressof(has_waiter_flag)); | 265 | WriteToUser(m_kernel, cv_key, std::addressof(has_waiter_flag)); |
| 261 | } | 266 | } |
| 262 | } | 267 | } |
| 263 | } | 268 | } |
| @@ -301,12 +306,12 @@ Result KConditionVariable::Wait(KProcessAddress addr, u64 key, u32 value, s64 ti | |||
| 301 | // Write to the cv key. | 306 | // Write to the cv key. |
| 302 | { | 307 | { |
| 303 | const u32 has_waiter_flag = 1; | 308 | const u32 has_waiter_flag = 1; |
| 304 | WriteToUser(m_system, key, std::addressof(has_waiter_flag)); | 309 | WriteToUser(m_kernel, key, std::addressof(has_waiter_flag)); |
| 305 | std::atomic_thread_fence(std::memory_order_seq_cst); | 310 | std::atomic_thread_fence(std::memory_order_seq_cst); |
| 306 | } | 311 | } |
| 307 | 312 | ||
| 308 | // Write the value to userspace. | 313 | // Write the value to userspace. |
| 309 | if (!WriteToUser(m_system, addr, std::addressof(next_value))) { | 314 | if (!WriteToUser(m_kernel, addr, std::addressof(next_value))) { |
| 310 | slp.CancelSleep(); | 315 | slp.CancelSleep(); |
| 311 | R_THROW(ResultInvalidCurrentMemory); | 316 | R_THROW(ResultInvalidCurrentMemory); |
| 312 | } | 317 | } |
diff --git a/src/core/hle/kernel/k_page_table.cpp b/src/core/hle/kernel/k_page_table.cpp index cb39387ea..02b5cada4 100644 --- a/src/core/hle/kernel/k_page_table.cpp +++ b/src/core/hle/kernel/k_page_table.cpp | |||
| @@ -108,7 +108,8 @@ Result KPageTable::InitializeForProcess(FileSys::ProgramAddressSpaceType as_type | |||
| 108 | bool enable_das_merge, bool from_back, | 108 | bool enable_das_merge, bool from_back, |
| 109 | KMemoryManager::Pool pool, KProcessAddress code_addr, | 109 | KMemoryManager::Pool pool, KProcessAddress code_addr, |
| 110 | size_t code_size, KSystemResource* system_resource, | 110 | size_t code_size, KSystemResource* system_resource, |
| 111 | KResourceLimit* resource_limit) { | 111 | KResourceLimit* resource_limit, |
| 112 | Core::Memory::Memory& memory) { | ||
| 112 | 113 | ||
| 113 | const auto GetSpaceStart = [this](KAddressSpaceInfo::Type type) { | 114 | const auto GetSpaceStart = [this](KAddressSpaceInfo::Type type) { |
| 114 | return KAddressSpaceInfo::GetAddressSpaceStart(m_address_space_width, type); | 115 | return KAddressSpaceInfo::GetAddressSpaceStart(m_address_space_width, type); |
| @@ -117,6 +118,9 @@ Result KPageTable::InitializeForProcess(FileSys::ProgramAddressSpaceType as_type | |||
| 117 | return KAddressSpaceInfo::GetAddressSpaceSize(m_address_space_width, type); | 118 | return KAddressSpaceInfo::GetAddressSpaceSize(m_address_space_width, type); |
| 118 | }; | 119 | }; |
| 119 | 120 | ||
| 121 | // Set the tracking memory | ||
| 122 | m_memory = std::addressof(memory); | ||
| 123 | |||
| 120 | // Set our width and heap/alias sizes | 124 | // Set our width and heap/alias sizes |
| 121 | m_address_space_width = GetAddressSpaceWidthFromType(as_type); | 125 | m_address_space_width = GetAddressSpaceWidthFromType(as_type); |
| 122 | const KProcessAddress start = 0; | 126 | const KProcessAddress start = 0; |
| @@ -334,10 +338,10 @@ Result KPageTable::InitializeForProcess(FileSys::ProgramAddressSpaceType as_type | |||
| 334 | 338 | ||
| 335 | void KPageTable::Finalize() { | 339 | void KPageTable::Finalize() { |
| 336 | // Finalize memory blocks. | 340 | // Finalize memory blocks. |
| 337 | m_memory_block_manager.Finalize( | 341 | m_memory_block_manager.Finalize(m_memory_block_slab_manager, |
| 338 | m_memory_block_slab_manager, [&](KProcessAddress addr, u64 size) { | 342 | [&](KProcessAddress addr, u64 size) { |
| 339 | m_system.Memory().UnmapRegion(*m_page_table_impl, addr, size); | 343 | m_memory->UnmapRegion(*m_page_table_impl, addr, size); |
| 340 | }); | 344 | }); |
| 341 | 345 | ||
| 342 | // Release any insecure mapped memory. | 346 | // Release any insecure mapped memory. |
| 343 | if (m_mapped_insecure_memory) { | 347 | if (m_mapped_insecure_memory) { |
| @@ -1010,23 +1014,22 @@ Result KPageTable::SetupForIpcServer(KProcessAddress* out_addr, size_t size, | |||
| 1010 | clear_size = 0; | 1014 | clear_size = 0; |
| 1011 | } | 1015 | } |
| 1012 | 1016 | ||
| 1013 | std::memset(m_system.Memory().GetPointer<void>(GetInteger(start_partial_virt)), | 1017 | std::memset(m_memory->GetPointer<void>(GetInteger(start_partial_virt)), fill_val, |
| 1014 | fill_val, partial_offset); | 1018 | partial_offset); |
| 1015 | std::memcpy( | 1019 | std::memcpy( |
| 1016 | m_system.Memory().GetPointer<void>(GetInteger(start_partial_virt) + partial_offset), | 1020 | m_memory->GetPointer<void>(GetInteger(start_partial_virt) + partial_offset), |
| 1017 | m_system.Memory().GetPointer<void>( | 1021 | m_memory->GetPointer<void>(GetInteger(GetHeapVirtualAddress( |
| 1018 | GetInteger( | 1022 | m_system.Kernel().MemoryLayout(), cur_block_addr)) + |
| 1019 | GetHeapVirtualAddress(m_system.Kernel().MemoryLayout(), cur_block_addr)) + | 1023 | partial_offset), |
| 1020 | partial_offset), | ||
| 1021 | copy_size); | 1024 | copy_size); |
| 1022 | if (clear_size > 0) { | 1025 | if (clear_size > 0) { |
| 1023 | std::memset(m_system.Memory().GetPointer<void>(GetInteger(start_partial_virt) + | 1026 | std::memset(m_memory->GetPointer<void>(GetInteger(start_partial_virt) + |
| 1024 | partial_offset + copy_size), | 1027 | partial_offset + copy_size), |
| 1025 | fill_val, clear_size); | 1028 | fill_val, clear_size); |
| 1026 | } | 1029 | } |
| 1027 | } else { | 1030 | } else { |
| 1028 | std::memset(m_system.Memory().GetPointer<void>(GetInteger(start_partial_virt)), | 1031 | std::memset(m_memory->GetPointer<void>(GetInteger(start_partial_virt)), fill_val, |
| 1029 | fill_val, PageSize); | 1032 | PageSize); |
| 1030 | } | 1033 | } |
| 1031 | 1034 | ||
| 1032 | // Map the page. | 1035 | // Map the page. |
| @@ -1099,15 +1102,14 @@ Result KPageTable::SetupForIpcServer(KProcessAddress* out_addr, size_t size, | |||
| 1099 | GetHeapVirtualAddress(m_system.Kernel().MemoryLayout(), end_partial_page); | 1102 | GetHeapVirtualAddress(m_system.Kernel().MemoryLayout(), end_partial_page); |
| 1100 | if (send) { | 1103 | if (send) { |
| 1101 | const size_t copy_size = src_end - mapping_src_end; | 1104 | const size_t copy_size = src_end - mapping_src_end; |
| 1102 | std::memcpy(m_system.Memory().GetPointer<void>(GetInteger(end_partial_virt)), | 1105 | std::memcpy(m_memory->GetPointer<void>(GetInteger(end_partial_virt)), |
| 1103 | m_system.Memory().GetPointer<void>(GetInteger(GetHeapVirtualAddress( | 1106 | m_memory->GetPointer<void>(GetInteger(GetHeapVirtualAddress( |
| 1104 | m_system.Kernel().MemoryLayout(), cur_block_addr))), | 1107 | m_system.Kernel().MemoryLayout(), cur_block_addr))), |
| 1105 | copy_size); | 1108 | copy_size); |
| 1106 | std::memset( | 1109 | std::memset(m_memory->GetPointer<void>(GetInteger(end_partial_virt) + copy_size), |
| 1107 | m_system.Memory().GetPointer<void>(GetInteger(end_partial_virt) + copy_size), | 1110 | fill_val, PageSize - copy_size); |
| 1108 | fill_val, PageSize - copy_size); | ||
| 1109 | } else { | 1111 | } else { |
| 1110 | std::memset(m_system.Memory().GetPointer<void>(GetInteger(end_partial_virt)), fill_val, | 1112 | std::memset(m_memory->GetPointer<void>(GetInteger(end_partial_virt)), fill_val, |
| 1111 | PageSize); | 1113 | PageSize); |
| 1112 | } | 1114 | } |
| 1113 | 1115 | ||
| @@ -2800,7 +2802,7 @@ Result KPageTable::SetHeapSize(u64* out, size_t size) { | |||
| 2800 | 2802 | ||
| 2801 | // Clear all the newly allocated pages. | 2803 | // Clear all the newly allocated pages. |
| 2802 | for (size_t cur_page = 0; cur_page < num_pages; ++cur_page) { | 2804 | for (size_t cur_page = 0; cur_page < num_pages; ++cur_page) { |
| 2803 | std::memset(m_system.Memory().GetPointer(m_current_heap_end + (cur_page * PageSize)), 0, | 2805 | std::memset(m_memory->GetPointer(m_current_heap_end + (cur_page * PageSize)), 0, |
| 2804 | PageSize); | 2806 | PageSize); |
| 2805 | } | 2807 | } |
| 2806 | 2808 | ||
| @@ -3006,7 +3008,7 @@ Result KPageTable::Operate(KProcessAddress addr, size_t num_pages, const KPageGr | |||
| 3006 | const size_t size{node.GetNumPages() * PageSize}; | 3008 | const size_t size{node.GetNumPages() * PageSize}; |
| 3007 | 3009 | ||
| 3008 | // Map the pages. | 3010 | // Map the pages. |
| 3009 | m_system.Memory().MapMemoryRegion(*m_page_table_impl, addr, size, node.GetAddress()); | 3011 | m_memory->MapMemoryRegion(*m_page_table_impl, addr, size, node.GetAddress()); |
| 3010 | 3012 | ||
| 3011 | addr += size; | 3013 | addr += size; |
| 3012 | } | 3014 | } |
| @@ -3039,14 +3041,14 @@ Result KPageTable::Operate(KProcessAddress addr, size_t num_pages, KMemoryPermis | |||
| 3039 | SCOPE_EXIT({ pages_to_close.CloseAndReset(); }); | 3041 | SCOPE_EXIT({ pages_to_close.CloseAndReset(); }); |
| 3040 | 3042 | ||
| 3041 | this->AddRegionToPages(addr, num_pages, pages_to_close); | 3043 | this->AddRegionToPages(addr, num_pages, pages_to_close); |
| 3042 | m_system.Memory().UnmapRegion(*m_page_table_impl, addr, num_pages * PageSize); | 3044 | m_memory->UnmapRegion(*m_page_table_impl, addr, num_pages * PageSize); |
| 3043 | break; | 3045 | break; |
| 3044 | } | 3046 | } |
| 3045 | case OperationType::MapFirst: | 3047 | case OperationType::MapFirst: |
| 3046 | case OperationType::Map: { | 3048 | case OperationType::Map: { |
| 3047 | ASSERT(map_addr); | 3049 | ASSERT(map_addr); |
| 3048 | ASSERT(Common::IsAligned(GetInteger(map_addr), PageSize)); | 3050 | ASSERT(Common::IsAligned(GetInteger(map_addr), PageSize)); |
| 3049 | m_system.Memory().MapMemoryRegion(*m_page_table_impl, addr, num_pages * PageSize, map_addr); | 3051 | m_memory->MapMemoryRegion(*m_page_table_impl, addr, num_pages * PageSize, map_addr); |
| 3050 | 3052 | ||
| 3051 | // Open references to pages, if we should. | 3053 | // Open references to pages, if we should. |
| 3052 | if (IsHeapPhysicalAddress(m_kernel.MemoryLayout(), map_addr)) { | 3054 | if (IsHeapPhysicalAddress(m_kernel.MemoryLayout(), map_addr)) { |
diff --git a/src/core/hle/kernel/k_page_table.h b/src/core/hle/kernel/k_page_table.h index 1917b2a98..022d15f35 100644 --- a/src/core/hle/kernel/k_page_table.h +++ b/src/core/hle/kernel/k_page_table.h | |||
| @@ -66,7 +66,8 @@ public: | |||
| 66 | Result InitializeForProcess(FileSys::ProgramAddressSpaceType as_type, bool enable_aslr, | 66 | Result InitializeForProcess(FileSys::ProgramAddressSpaceType as_type, bool enable_aslr, |
| 67 | bool enable_das_merge, bool from_back, KMemoryManager::Pool pool, | 67 | bool enable_das_merge, bool from_back, KMemoryManager::Pool pool, |
| 68 | KProcessAddress code_addr, size_t code_size, | 68 | KProcessAddress code_addr, size_t code_size, |
| 69 | KSystemResource* system_resource, KResourceLimit* resource_limit); | 69 | KSystemResource* system_resource, KResourceLimit* resource_limit, |
| 70 | Core::Memory::Memory& memory); | ||
| 70 | 71 | ||
| 71 | void Finalize(); | 72 | void Finalize(); |
| 72 | 73 | ||
| @@ -546,6 +547,7 @@ private: | |||
| 546 | 547 | ||
| 547 | Core::System& m_system; | 548 | Core::System& m_system; |
| 548 | KernelCore& m_kernel; | 549 | KernelCore& m_kernel; |
| 550 | Core::Memory::Memory* m_memory{}; | ||
| 549 | }; | 551 | }; |
| 550 | 552 | ||
| 551 | } // namespace Kernel | 553 | } // namespace Kernel |
diff --git a/src/core/hle/kernel/k_process.cpp b/src/core/hle/kernel/k_process.cpp index 53f8139f3..efe86ad27 100644 --- a/src/core/hle/kernel/k_process.cpp +++ b/src/core/hle/kernel/k_process.cpp | |||
| @@ -367,8 +367,8 @@ Result KProcess::LoadFromMetadata(const FileSys::ProgramMetadata& metadata, std: | |||
| 367 | // Initialize process address space | 367 | // Initialize process address space |
| 368 | if (const Result result{m_page_table.InitializeForProcess( | 368 | if (const Result result{m_page_table.InitializeForProcess( |
| 369 | metadata.GetAddressSpaceType(), false, false, false, KMemoryManager::Pool::Application, | 369 | metadata.GetAddressSpaceType(), false, false, false, KMemoryManager::Pool::Application, |
| 370 | 0x8000000, code_size, std::addressof(m_kernel.GetAppSystemResource()), | 370 | 0x8000000, code_size, std::addressof(m_kernel.GetAppSystemResource()), m_resource_limit, |
| 371 | m_resource_limit)}; | 371 | m_kernel.System().ApplicationMemory())}; |
| 372 | result.IsError()) { | 372 | result.IsError()) { |
| 373 | R_RETURN(result); | 373 | R_RETURN(result); |
| 374 | } | 374 | } |
| @@ -592,8 +592,7 @@ Result KProcess::DeleteThreadLocalRegion(KProcessAddress addr) { | |||
| 592 | R_SUCCEED(); | 592 | R_SUCCEED(); |
| 593 | } | 593 | } |
| 594 | 594 | ||
| 595 | bool KProcess::InsertWatchpoint(Core::System& system, KProcessAddress addr, u64 size, | 595 | bool KProcess::InsertWatchpoint(KProcessAddress addr, u64 size, DebugWatchpointType type) { |
| 596 | DebugWatchpointType type) { | ||
| 597 | const auto watch{std::find_if(m_watchpoints.begin(), m_watchpoints.end(), [&](const auto& wp) { | 596 | const auto watch{std::find_if(m_watchpoints.begin(), m_watchpoints.end(), [&](const auto& wp) { |
| 598 | return wp.type == DebugWatchpointType::None; | 597 | return wp.type == DebugWatchpointType::None; |
| 599 | })}; | 598 | })}; |
| @@ -609,14 +608,13 @@ bool KProcess::InsertWatchpoint(Core::System& system, KProcessAddress addr, u64 | |||
| 609 | for (KProcessAddress page = Common::AlignDown(GetInteger(addr), PageSize); page < addr + size; | 608 | for (KProcessAddress page = Common::AlignDown(GetInteger(addr), PageSize); page < addr + size; |
| 610 | page += PageSize) { | 609 | page += PageSize) { |
| 611 | m_debug_page_refcounts[page]++; | 610 | m_debug_page_refcounts[page]++; |
| 612 | system.Memory().MarkRegionDebug(page, PageSize, true); | 611 | this->GetMemory().MarkRegionDebug(page, PageSize, true); |
| 613 | } | 612 | } |
| 614 | 613 | ||
| 615 | return true; | 614 | return true; |
| 616 | } | 615 | } |
| 617 | 616 | ||
| 618 | bool KProcess::RemoveWatchpoint(Core::System& system, KProcessAddress addr, u64 size, | 617 | bool KProcess::RemoveWatchpoint(KProcessAddress addr, u64 size, DebugWatchpointType type) { |
| 619 | DebugWatchpointType type) { | ||
| 620 | const auto watch{std::find_if(m_watchpoints.begin(), m_watchpoints.end(), [&](const auto& wp) { | 618 | const auto watch{std::find_if(m_watchpoints.begin(), m_watchpoints.end(), [&](const auto& wp) { |
| 621 | return wp.start_address == addr && wp.end_address == addr + size && wp.type == type; | 619 | return wp.start_address == addr && wp.end_address == addr + size && wp.type == type; |
| 622 | })}; | 620 | })}; |
| @@ -633,7 +631,7 @@ bool KProcess::RemoveWatchpoint(Core::System& system, KProcessAddress addr, u64 | |||
| 633 | page += PageSize) { | 631 | page += PageSize) { |
| 634 | m_debug_page_refcounts[page]--; | 632 | m_debug_page_refcounts[page]--; |
| 635 | if (!m_debug_page_refcounts[page]) { | 633 | if (!m_debug_page_refcounts[page]) { |
| 636 | system.Memory().MarkRegionDebug(page, PageSize, false); | 634 | this->GetMemory().MarkRegionDebug(page, PageSize, false); |
| 637 | } | 635 | } |
| 638 | } | 636 | } |
| 639 | 637 | ||
| @@ -646,8 +644,7 @@ void KProcess::LoadModule(CodeSet code_set, KProcessAddress base_addr) { | |||
| 646 | m_page_table.SetProcessMemoryPermission(segment.addr + base_addr, segment.size, permission); | 644 | m_page_table.SetProcessMemoryPermission(segment.addr + base_addr, segment.size, permission); |
| 647 | }; | 645 | }; |
| 648 | 646 | ||
| 649 | m_kernel.System().Memory().WriteBlock(*this, base_addr, code_set.memory.data(), | 647 | this->GetMemory().WriteBlock(base_addr, code_set.memory.data(), code_set.memory.size()); |
| 650 | code_set.memory.size()); | ||
| 651 | 648 | ||
| 652 | ReprotectSegment(code_set.CodeSegment(), Svc::MemoryPermission::ReadExecute); | 649 | ReprotectSegment(code_set.CodeSegment(), Svc::MemoryPermission::ReadExecute); |
| 653 | ReprotectSegment(code_set.RODataSegment(), Svc::MemoryPermission::Read); | 650 | ReprotectSegment(code_set.RODataSegment(), Svc::MemoryPermission::Read); |
| @@ -706,4 +703,9 @@ Result KProcess::AllocateMainThreadStack(std::size_t stack_size) { | |||
| 706 | R_SUCCEED(); | 703 | R_SUCCEED(); |
| 707 | } | 704 | } |
| 708 | 705 | ||
| 706 | Core::Memory::Memory& KProcess::GetMemory() const { | ||
| 707 | // TODO: per-process memory | ||
| 708 | return m_kernel.System().ApplicationMemory(); | ||
| 709 | } | ||
| 710 | |||
| 709 | } // namespace Kernel | 711 | } // namespace Kernel |
diff --git a/src/core/hle/kernel/k_process.h b/src/core/hle/kernel/k_process.h index 04b6bbb86..925981d06 100644 --- a/src/core/hle/kernel/k_process.h +++ b/src/core/hle/kernel/k_process.h | |||
| @@ -22,8 +22,12 @@ | |||
| 22 | #include "core/hle/result.h" | 22 | #include "core/hle/result.h" |
| 23 | 23 | ||
| 24 | namespace Core { | 24 | namespace Core { |
| 25 | namespace Memory { | ||
| 26 | class Memory; | ||
| 27 | }; | ||
| 28 | |||
| 25 | class System; | 29 | class System; |
| 26 | } | 30 | } // namespace Core |
| 27 | 31 | ||
| 28 | namespace FileSys { | 32 | namespace FileSys { |
| 29 | class ProgramMetadata; | 33 | class ProgramMetadata; |
| @@ -135,6 +139,9 @@ public: | |||
| 135 | return m_handle_table; | 139 | return m_handle_table; |
| 136 | } | 140 | } |
| 137 | 141 | ||
| 142 | /// Gets a reference to process's memory. | ||
| 143 | Core::Memory::Memory& GetMemory() const; | ||
| 144 | |||
| 138 | Result SignalToAddress(KProcessAddress address) { | 145 | Result SignalToAddress(KProcessAddress address) { |
| 139 | return m_condition_var.SignalToAddress(address); | 146 | return m_condition_var.SignalToAddress(address); |
| 140 | } | 147 | } |
| @@ -397,12 +404,10 @@ public: | |||
| 397 | // Debug watchpoint management | 404 | // Debug watchpoint management |
| 398 | 405 | ||
| 399 | // Attempts to insert a watchpoint into a free slot. Returns false if none are available. | 406 | // Attempts to insert a watchpoint into a free slot. Returns false if none are available. |
| 400 | bool InsertWatchpoint(Core::System& system, KProcessAddress addr, u64 size, | 407 | bool InsertWatchpoint(KProcessAddress addr, u64 size, DebugWatchpointType type); |
| 401 | DebugWatchpointType type); | ||
| 402 | 408 | ||
| 403 | // Attempts to remove the watchpoint specified by the given parameters. | 409 | // Attempts to remove the watchpoint specified by the given parameters. |
| 404 | bool RemoveWatchpoint(Core::System& system, KProcessAddress addr, u64 size, | 410 | bool RemoveWatchpoint(KProcessAddress addr, u64 size, DebugWatchpointType type); |
| 405 | DebugWatchpointType type); | ||
| 406 | 411 | ||
| 407 | const std::array<DebugWatchpoint, Core::Hardware::NUM_WATCHPOINTS>& GetWatchpoints() const { | 412 | const std::array<DebugWatchpoint, Core::Hardware::NUM_WATCHPOINTS>& GetWatchpoints() const { |
| 408 | return m_watchpoints; | 413 | return m_watchpoints; |
diff --git a/src/core/hle/kernel/k_server_session.cpp b/src/core/hle/kernel/k_server_session.cpp index 2288ee435..c66aff501 100644 --- a/src/core/hle/kernel/k_server_session.cpp +++ b/src/core/hle/kernel/k_server_session.cpp | |||
| @@ -222,7 +222,7 @@ Result KServerSession::SendReply(bool is_hle) { | |||
| 222 | // HLE servers write directly to a pointer to the thread command buffer. Therefore | 222 | // HLE servers write directly to a pointer to the thread command buffer. Therefore |
| 223 | // the reply has already been written in this case. | 223 | // the reply has already been written in this case. |
| 224 | } else { | 224 | } else { |
| 225 | Core::Memory::Memory& memory{m_kernel.System().Memory()}; | 225 | Core::Memory::Memory& memory{client_thread->GetOwnerProcess()->GetMemory()}; |
| 226 | KThread* server_thread{GetCurrentThreadPointer(m_kernel)}; | 226 | KThread* server_thread{GetCurrentThreadPointer(m_kernel)}; |
| 227 | UNIMPLEMENTED_IF(server_thread->GetOwnerProcess() != client_thread->GetOwnerProcess()); | 227 | UNIMPLEMENTED_IF(server_thread->GetOwnerProcess() != client_thread->GetOwnerProcess()); |
| 228 | 228 | ||
| @@ -319,7 +319,7 @@ Result KServerSession::ReceiveRequest(std::shared_ptr<Service::HLERequestContext | |||
| 319 | // bool recv_list_broken = false; | 319 | // bool recv_list_broken = false; |
| 320 | 320 | ||
| 321 | // Receive the message. | 321 | // Receive the message. |
| 322 | Core::Memory::Memory& memory{m_kernel.System().Memory()}; | 322 | Core::Memory::Memory& memory{client_thread->GetOwnerProcess()->GetMemory()}; |
| 323 | if (out_context != nullptr) { | 323 | if (out_context != nullptr) { |
| 324 | // HLE request. | 324 | // HLE request. |
| 325 | u32* cmd_buf{reinterpret_cast<u32*>(memory.GetPointer(client_message))}; | 325 | u32* cmd_buf{reinterpret_cast<u32*>(memory.GetPointer(client_message))}; |
diff --git a/src/core/hle/kernel/k_thread.cpp b/src/core/hle/kernel/k_thread.cpp index 9d101c640..70480b725 100644 --- a/src/core/hle/kernel/k_thread.cpp +++ b/src/core/hle/kernel/k_thread.cpp | |||
| @@ -546,7 +546,7 @@ u16 KThread::GetUserDisableCount() const { | |||
| 546 | return {}; | 546 | return {}; |
| 547 | } | 547 | } |
| 548 | 548 | ||
| 549 | auto& memory = m_kernel.System().Memory(); | 549 | auto& memory = this->GetOwnerProcess()->GetMemory(); |
| 550 | return memory.Read16(m_tls_address + offsetof(ThreadLocalRegion, disable_count)); | 550 | return memory.Read16(m_tls_address + offsetof(ThreadLocalRegion, disable_count)); |
| 551 | } | 551 | } |
| 552 | 552 | ||
| @@ -556,7 +556,7 @@ void KThread::SetInterruptFlag() { | |||
| 556 | return; | 556 | return; |
| 557 | } | 557 | } |
| 558 | 558 | ||
| 559 | auto& memory = m_kernel.System().Memory(); | 559 | auto& memory = this->GetOwnerProcess()->GetMemory(); |
| 560 | memory.Write16(m_tls_address + offsetof(ThreadLocalRegion, interrupt_flag), 1); | 560 | memory.Write16(m_tls_address + offsetof(ThreadLocalRegion, interrupt_flag), 1); |
| 561 | } | 561 | } |
| 562 | 562 | ||
| @@ -566,7 +566,7 @@ void KThread::ClearInterruptFlag() { | |||
| 566 | return; | 566 | return; |
| 567 | } | 567 | } |
| 568 | 568 | ||
| 569 | auto& memory = m_kernel.System().Memory(); | 569 | auto& memory = this->GetOwnerProcess()->GetMemory(); |
| 570 | memory.Write16(m_tls_address + offsetof(ThreadLocalRegion, interrupt_flag), 0); | 570 | memory.Write16(m_tls_address + offsetof(ThreadLocalRegion, interrupt_flag), 0); |
| 571 | } | 571 | } |
| 572 | 572 | ||
| @@ -1422,6 +1422,11 @@ s32 GetCurrentCoreId(KernelCore& kernel) { | |||
| 1422 | return GetCurrentThread(kernel).GetCurrentCore(); | 1422 | return GetCurrentThread(kernel).GetCurrentCore(); |
| 1423 | } | 1423 | } |
| 1424 | 1424 | ||
| 1425 | Core::Memory::Memory& GetCurrentMemory(KernelCore& kernel) { | ||
| 1426 | // TODO: per-process memory | ||
| 1427 | return kernel.System().ApplicationMemory(); | ||
| 1428 | } | ||
| 1429 | |||
| 1425 | KScopedDisableDispatch::~KScopedDisableDispatch() { | 1430 | KScopedDisableDispatch::~KScopedDisableDispatch() { |
| 1426 | // If we are shutting down the kernel, none of this is relevant anymore. | 1431 | // If we are shutting down the kernel, none of this is relevant anymore. |
| 1427 | if (m_kernel.IsShuttingDown()) { | 1432 | if (m_kernel.IsShuttingDown()) { |
diff --git a/src/core/hle/kernel/k_thread.h b/src/core/hle/kernel/k_thread.h index 0fa9672bf..9c1a41128 100644 --- a/src/core/hle/kernel/k_thread.h +++ b/src/core/hle/kernel/k_thread.h | |||
| @@ -34,6 +34,9 @@ class Fiber; | |||
| 34 | } | 34 | } |
| 35 | 35 | ||
| 36 | namespace Core { | 36 | namespace Core { |
| 37 | namespace Memory { | ||
| 38 | class Memory; | ||
| 39 | } | ||
| 37 | class ARM_Interface; | 40 | class ARM_Interface; |
| 38 | class System; | 41 | class System; |
| 39 | } // namespace Core | 42 | } // namespace Core |
| @@ -113,6 +116,7 @@ KThread& GetCurrentThread(KernelCore& kernel); | |||
| 113 | KProcess* GetCurrentProcessPointer(KernelCore& kernel); | 116 | KProcess* GetCurrentProcessPointer(KernelCore& kernel); |
| 114 | KProcess& GetCurrentProcess(KernelCore& kernel); | 117 | KProcess& GetCurrentProcess(KernelCore& kernel); |
| 115 | s32 GetCurrentCoreId(KernelCore& kernel); | 118 | s32 GetCurrentCoreId(KernelCore& kernel); |
| 119 | Core::Memory::Memory& GetCurrentMemory(KernelCore& kernel); | ||
| 116 | 120 | ||
| 117 | class KThread final : public KAutoObjectWithSlabHeapAndContainer<KThread, KWorkerTask>, | 121 | class KThread final : public KAutoObjectWithSlabHeapAndContainer<KThread, KWorkerTask>, |
| 118 | public boost::intrusive::list_base_hook<>, | 122 | public boost::intrusive::list_base_hook<>, |
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 29809b2c5..4f3366c9d 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp | |||
| @@ -102,7 +102,7 @@ struct KernelCore::Impl { | |||
| 102 | void InitializeCores() { | 102 | void InitializeCores() { |
| 103 | for (u32 core_id = 0; core_id < Core::Hardware::NUM_CPU_CORES; core_id++) { | 103 | for (u32 core_id = 0; core_id < Core::Hardware::NUM_CPU_CORES; core_id++) { |
| 104 | cores[core_id]->Initialize((*application_process).Is64BitProcess()); | 104 | cores[core_id]->Initialize((*application_process).Is64BitProcess()); |
| 105 | system.Memory().SetCurrentPageTable(*application_process, core_id); | 105 | system.ApplicationMemory().SetCurrentPageTable(*application_process, core_id); |
| 106 | } | 106 | } |
| 107 | } | 107 | } |
| 108 | 108 | ||
| @@ -206,7 +206,7 @@ struct KernelCore::Impl { | |||
| 206 | 206 | ||
| 207 | void InitializePhysicalCores() { | 207 | void InitializePhysicalCores() { |
| 208 | exclusive_monitor = | 208 | exclusive_monitor = |
| 209 | Core::MakeExclusiveMonitor(system.Memory(), Core::Hardware::NUM_CPU_CORES); | 209 | Core::MakeExclusiveMonitor(system.ApplicationMemory(), Core::Hardware::NUM_CPU_CORES); |
| 210 | for (u32 i = 0; i < Core::Hardware::NUM_CPU_CORES; i++) { | 210 | for (u32 i = 0; i < Core::Hardware::NUM_CPU_CORES; i++) { |
| 211 | const s32 core{static_cast<s32>(i)}; | 211 | const s32 core{static_cast<s32>(i)}; |
| 212 | 212 | ||
diff --git a/src/core/hle/kernel/svc/svc_cache.cpp b/src/core/hle/kernel/svc/svc_cache.cpp index 1779832d3..082942dab 100644 --- a/src/core/hle/kernel/svc/svc_cache.cpp +++ b/src/core/hle/kernel/svc/svc_cache.cpp | |||
| @@ -46,7 +46,7 @@ Result FlushProcessDataCache(Core::System& system, Handle process_handle, u64 ad | |||
| 46 | R_UNLESS(page_table.Contains(address, size), ResultInvalidCurrentMemory); | 46 | R_UNLESS(page_table.Contains(address, size), ResultInvalidCurrentMemory); |
| 47 | 47 | ||
| 48 | // Perform the operation. | 48 | // Perform the operation. |
| 49 | R_RETURN(system.Memory().FlushDataCache(*process, address, size)); | 49 | R_RETURN(GetCurrentMemory(system.Kernel()).FlushDataCache(address, size)); |
| 50 | } | 50 | } |
| 51 | 51 | ||
| 52 | void FlushEntireDataCache64(Core::System& system) { | 52 | void FlushEntireDataCache64(Core::System& system) { |
diff --git a/src/core/hle/kernel/svc/svc_debug_string.cpp b/src/core/hle/kernel/svc/svc_debug_string.cpp index 8771d2b01..4c14ce668 100644 --- a/src/core/hle/kernel/svc/svc_debug_string.cpp +++ b/src/core/hle/kernel/svc/svc_debug_string.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 "core/core.h" | 4 | #include "core/core.h" |
| 5 | #include "core/hle/kernel/k_thread.h" | ||
| 5 | #include "core/hle/kernel/svc.h" | 6 | #include "core/hle/kernel/svc.h" |
| 6 | #include "core/memory.h" | 7 | #include "core/memory.h" |
| 7 | 8 | ||
| @@ -12,7 +13,7 @@ Result OutputDebugString(Core::System& system, u64 address, u64 len) { | |||
| 12 | R_SUCCEED_IF(len == 0); | 13 | R_SUCCEED_IF(len == 0); |
| 13 | 14 | ||
| 14 | std::string str(len, '\0'); | 15 | std::string str(len, '\0'); |
| 15 | system.Memory().ReadBlock(address, str.data(), str.size()); | 16 | GetCurrentMemory(system.Kernel()).ReadBlock(address, str.data(), str.size()); |
| 16 | LOG_DEBUG(Debug_Emulated, "{}", str); | 17 | LOG_DEBUG(Debug_Emulated, "{}", str); |
| 17 | 18 | ||
| 18 | R_SUCCEED(); | 19 | R_SUCCEED(); |
diff --git a/src/core/hle/kernel/svc/svc_exception.cpp b/src/core/hle/kernel/svc/svc_exception.cpp index 4ab5f471f..580cf2f75 100644 --- a/src/core/hle/kernel/svc/svc_exception.cpp +++ b/src/core/hle/kernel/svc/svc_exception.cpp | |||
| @@ -25,7 +25,7 @@ void Break(Core::System& system, BreakReason reason, u64 info1, u64 info2) { | |||
| 25 | return; | 25 | return; |
| 26 | } | 26 | } |
| 27 | 27 | ||
| 28 | auto& memory = system.Memory(); | 28 | auto& memory = GetCurrentMemory(system.Kernel()); |
| 29 | 29 | ||
| 30 | // This typically is an error code so we're going to assume this is the case | 30 | // This typically is an error code so we're going to assume this is the case |
| 31 | if (sz == sizeof(u32)) { | 31 | if (sz == sizeof(u32)) { |
diff --git a/src/core/hle/kernel/svc/svc_ipc.cpp b/src/core/hle/kernel/svc/svc_ipc.cpp index 2a8c09a79..ea03068aa 100644 --- a/src/core/hle/kernel/svc/svc_ipc.cpp +++ b/src/core/hle/kernel/svc/svc_ipc.cpp | |||
| @@ -41,12 +41,12 @@ Result ReplyAndReceive(Core::System& system, s32* out_index, uint64_t handles_ad | |||
| 41 | auto& handle_table = GetCurrentProcess(kernel).GetHandleTable(); | 41 | auto& handle_table = GetCurrentProcess(kernel).GetHandleTable(); |
| 42 | 42 | ||
| 43 | R_UNLESS(0 <= num_handles && num_handles <= ArgumentHandleCountMax, ResultOutOfRange); | 43 | R_UNLESS(0 <= num_handles && num_handles <= ArgumentHandleCountMax, ResultOutOfRange); |
| 44 | R_UNLESS(system.Memory().IsValidVirtualAddressRange( | 44 | R_UNLESS(GetCurrentMemory(kernel).IsValidVirtualAddressRange( |
| 45 | handles_addr, static_cast<u64>(sizeof(Handle) * num_handles)), | 45 | handles_addr, static_cast<u64>(sizeof(Handle) * num_handles)), |
| 46 | ResultInvalidPointer); | 46 | ResultInvalidPointer); |
| 47 | 47 | ||
| 48 | std::vector<Handle> handles(num_handles); | 48 | std::vector<Handle> handles(num_handles); |
| 49 | system.Memory().ReadBlock(handles_addr, handles.data(), sizeof(Handle) * num_handles); | 49 | GetCurrentMemory(kernel).ReadBlock(handles_addr, handles.data(), sizeof(Handle) * num_handles); |
| 50 | 50 | ||
| 51 | // Convert handle list to object table. | 51 | // Convert handle list to object table. |
| 52 | std::vector<KSynchronizationObject*> objs(num_handles); | 52 | std::vector<KSynchronizationObject*> objs(num_handles); |
diff --git a/src/core/hle/kernel/svc/svc_port.cpp b/src/core/hle/kernel/svc/svc_port.cpp index c6eb70422..abba757c7 100644 --- a/src/core/hle/kernel/svc/svc_port.cpp +++ b/src/core/hle/kernel/svc/svc_port.cpp | |||
| @@ -14,7 +14,8 @@ namespace Kernel::Svc { | |||
| 14 | 14 | ||
| 15 | Result ConnectToNamedPort(Core::System& system, Handle* out, u64 user_name) { | 15 | Result ConnectToNamedPort(Core::System& system, Handle* out, u64 user_name) { |
| 16 | // Copy the provided name from user memory to kernel memory. | 16 | // Copy the provided name from user memory to kernel memory. |
| 17 | auto string_name = system.Memory().ReadCString(user_name, KObjectName::NameLengthMax); | 17 | auto string_name = |
| 18 | GetCurrentMemory(system.Kernel()).ReadCString(user_name, KObjectName::NameLengthMax); | ||
| 18 | 19 | ||
| 19 | std::array<char, KObjectName::NameLengthMax> name{}; | 20 | std::array<char, KObjectName::NameLengthMax> name{}; |
| 20 | std::strncpy(name.data(), string_name.c_str(), KObjectName::NameLengthMax - 1); | 21 | std::strncpy(name.data(), string_name.c_str(), KObjectName::NameLengthMax - 1); |
| @@ -62,7 +63,8 @@ Result ConnectToPort(Core::System& system, Handle* out_handle, Handle port) { | |||
| 62 | Result ManageNamedPort(Core::System& system, Handle* out_server_handle, uint64_t user_name, | 63 | Result ManageNamedPort(Core::System& system, Handle* out_server_handle, uint64_t user_name, |
| 63 | int32_t max_sessions) { | 64 | int32_t max_sessions) { |
| 64 | // Copy the provided name from user memory to kernel memory. | 65 | // Copy the provided name from user memory to kernel memory. |
| 65 | auto string_name = system.Memory().ReadCString(user_name, KObjectName::NameLengthMax); | 66 | auto string_name = |
| 67 | GetCurrentMemory(system.Kernel()).ReadCString(user_name, KObjectName::NameLengthMax); | ||
| 66 | 68 | ||
| 67 | // Copy the provided name from user memory to kernel memory. | 69 | // Copy the provided name from user memory to kernel memory. |
| 68 | std::array<char, KObjectName::NameLengthMax> name{}; | 70 | std::array<char, KObjectName::NameLengthMax> name{}; |
diff --git a/src/core/hle/kernel/svc/svc_process.cpp b/src/core/hle/kernel/svc/svc_process.cpp index 3c3579947..619ed16a3 100644 --- a/src/core/hle/kernel/svc/svc_process.cpp +++ b/src/core/hle/kernel/svc/svc_process.cpp | |||
| @@ -73,7 +73,7 @@ Result GetProcessList(Core::System& system, s32* out_num_processes, u64 out_proc | |||
| 73 | R_THROW(ResultInvalidCurrentMemory); | 73 | R_THROW(ResultInvalidCurrentMemory); |
| 74 | } | 74 | } |
| 75 | 75 | ||
| 76 | auto& memory = system.Memory(); | 76 | auto& memory = GetCurrentMemory(kernel); |
| 77 | const auto& process_list = kernel.GetProcessList(); | 77 | const auto& process_list = kernel.GetProcessList(); |
| 78 | const auto num_processes = process_list.size(); | 78 | const auto num_processes = process_list.size(); |
| 79 | const auto copy_amount = | 79 | const auto copy_amount = |
diff --git a/src/core/hle/kernel/svc/svc_query_memory.cpp b/src/core/hle/kernel/svc/svc_query_memory.cpp index 5db5611f0..4d9fcd25f 100644 --- a/src/core/hle/kernel/svc/svc_query_memory.cpp +++ b/src/core/hle/kernel/svc/svc_query_memory.cpp | |||
| @@ -30,10 +30,10 @@ Result QueryProcessMemory(Core::System& system, uint64_t out_memory_info, PageIn | |||
| 30 | R_THROW(ResultInvalidHandle); | 30 | R_THROW(ResultInvalidHandle); |
| 31 | } | 31 | } |
| 32 | 32 | ||
| 33 | auto& memory{system.Memory()}; | 33 | auto& current_memory{GetCurrentMemory(system.Kernel())}; |
| 34 | const auto memory_info{process->PageTable().QueryInfo(address).GetSvcMemoryInfo()}; | 34 | const auto memory_info{process->PageTable().QueryInfo(address).GetSvcMemoryInfo()}; |
| 35 | 35 | ||
| 36 | memory.WriteBlock(out_memory_info, std::addressof(memory_info), sizeof(memory_info)); | 36 | current_memory.WriteBlock(out_memory_info, std::addressof(memory_info), sizeof(memory_info)); |
| 37 | 37 | ||
| 38 | //! This is supposed to be part of the QueryInfo call. | 38 | //! This is supposed to be part of the QueryInfo call. |
| 39 | *out_page_info = {}; | 39 | *out_page_info = {}; |
diff --git a/src/core/hle/kernel/svc/svc_synchronization.cpp b/src/core/hle/kernel/svc/svc_synchronization.cpp index e490a13ae..04d65f0bd 100644 --- a/src/core/hle/kernel/svc/svc_synchronization.cpp +++ b/src/core/hle/kernel/svc/svc_synchronization.cpp | |||
| @@ -90,7 +90,8 @@ Result WaitSynchronization(Core::System& system, int32_t* out_index, u64 user_ha | |||
| 90 | 90 | ||
| 91 | std::vector<Handle> handles(num_handles); | 91 | std::vector<Handle> handles(num_handles); |
| 92 | if (num_handles > 0) { | 92 | if (num_handles > 0) { |
| 93 | system.Memory().ReadBlock(user_handles, handles.data(), num_handles * sizeof(Handle)); | 93 | GetCurrentMemory(system.Kernel()) |
| 94 | .ReadBlock(user_handles, handles.data(), num_handles * sizeof(Handle)); | ||
| 94 | } | 95 | } |
| 95 | 96 | ||
| 96 | R_RETURN(WaitSynchronization(system, out_index, handles.data(), num_handles, timeout_ns)); | 97 | R_RETURN(WaitSynchronization(system, out_index, handles.data(), num_handles, timeout_ns)); |
diff --git a/src/core/hle/kernel/svc/svc_thread.cpp b/src/core/hle/kernel/svc/svc_thread.cpp index 0be4858a2..37b54079c 100644 --- a/src/core/hle/kernel/svc/svc_thread.cpp +++ b/src/core/hle/kernel/svc/svc_thread.cpp | |||
| @@ -178,7 +178,7 @@ Result GetThreadContext3(Core::System& system, u64 out_context, Handle thread_ha | |||
| 178 | R_TRY(thread->GetThreadContext3(context)); | 178 | R_TRY(thread->GetThreadContext3(context)); |
| 179 | 179 | ||
| 180 | // Copy the thread context to user space. | 180 | // Copy the thread context to user space. |
| 181 | system.Memory().WriteBlock(out_context, context.data(), context.size()); | 181 | GetCurrentMemory(kernel).WriteBlock(out_context, context.data(), context.size()); |
| 182 | 182 | ||
| 183 | R_SUCCEED(); | 183 | R_SUCCEED(); |
| 184 | } | 184 | } |
| @@ -242,7 +242,7 @@ Result GetThreadList(Core::System& system, s32* out_num_threads, u64 out_thread_ | |||
| 242 | R_THROW(ResultInvalidCurrentMemory); | 242 | R_THROW(ResultInvalidCurrentMemory); |
| 243 | } | 243 | } |
| 244 | 244 | ||
| 245 | auto& memory = system.Memory(); | 245 | auto& memory = GetCurrentMemory(system.Kernel()); |
| 246 | const auto& thread_list = current_process->GetThreadList(); | 246 | const auto& thread_list = current_process->GetThreadList(); |
| 247 | const auto num_threads = thread_list.size(); | 247 | const auto num_threads = thread_list.size(); |
| 248 | const auto copy_amount = std::min(static_cast<std::size_t>(out_thread_ids_size), num_threads); | 248 | const auto copy_amount = std::min(static_cast<std::size_t>(out_thread_ids_size), num_threads); |
diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp index deeca925d..a17c46121 100644 --- a/src/core/hle/service/am/am.cpp +++ b/src/core/hle/service/am/am.cpp | |||
| @@ -945,7 +945,7 @@ public: | |||
| 945 | {0, &ILibraryAppletAccessor::GetAppletStateChangedEvent, "GetAppletStateChangedEvent"}, | 945 | {0, &ILibraryAppletAccessor::GetAppletStateChangedEvent, "GetAppletStateChangedEvent"}, |
| 946 | {1, &ILibraryAppletAccessor::IsCompleted, "IsCompleted"}, | 946 | {1, &ILibraryAppletAccessor::IsCompleted, "IsCompleted"}, |
| 947 | {10, &ILibraryAppletAccessor::Start, "Start"}, | 947 | {10, &ILibraryAppletAccessor::Start, "Start"}, |
| 948 | {20, nullptr, "RequestExit"}, | 948 | {20, &ILibraryAppletAccessor::RequestExit, "RequestExit"}, |
| 949 | {25, nullptr, "Terminate"}, | 949 | {25, nullptr, "Terminate"}, |
| 950 | {30, &ILibraryAppletAccessor::GetResult, "GetResult"}, | 950 | {30, &ILibraryAppletAccessor::GetResult, "GetResult"}, |
| 951 | {50, nullptr, "SetOutOfFocusApplicationSuspendingEnabled"}, | 951 | {50, nullptr, "SetOutOfFocusApplicationSuspendingEnabled"}, |
| @@ -1010,6 +1010,15 @@ private: | |||
| 1010 | rb.Push(ResultSuccess); | 1010 | rb.Push(ResultSuccess); |
| 1011 | } | 1011 | } |
| 1012 | 1012 | ||
| 1013 | void RequestExit(HLERequestContext& ctx) { | ||
| 1014 | LOG_DEBUG(Service_AM, "called"); | ||
| 1015 | |||
| 1016 | ASSERT(applet != nullptr); | ||
| 1017 | |||
| 1018 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 1019 | rb.Push(applet->RequestExit()); | ||
| 1020 | } | ||
| 1021 | |||
| 1013 | void PushInData(HLERequestContext& ctx) { | 1022 | void PushInData(HLERequestContext& ctx) { |
| 1014 | LOG_DEBUG(Service_AM, "called"); | 1023 | LOG_DEBUG(Service_AM, "called"); |
| 1015 | 1024 | ||
| @@ -1265,7 +1274,8 @@ void ILibraryAppletCreator::CreateTransferMemoryStorage(HLERequestContext& ctx) | |||
| 1265 | } | 1274 | } |
| 1266 | 1275 | ||
| 1267 | std::vector<u8> memory(transfer_mem->GetSize()); | 1276 | std::vector<u8> memory(transfer_mem->GetSize()); |
| 1268 | system.Memory().ReadBlock(transfer_mem->GetSourceAddress(), memory.data(), memory.size()); | 1277 | system.ApplicationMemory().ReadBlock(transfer_mem->GetSourceAddress(), memory.data(), |
| 1278 | memory.size()); | ||
| 1269 | 1279 | ||
| 1270 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | 1280 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; |
| 1271 | rb.Push(ResultSuccess); | 1281 | rb.Push(ResultSuccess); |
| @@ -1298,7 +1308,8 @@ void ILibraryAppletCreator::CreateHandleStorage(HLERequestContext& ctx) { | |||
| 1298 | } | 1308 | } |
| 1299 | 1309 | ||
| 1300 | std::vector<u8> memory(transfer_mem->GetSize()); | 1310 | std::vector<u8> memory(transfer_mem->GetSize()); |
| 1301 | system.Memory().ReadBlock(transfer_mem->GetSourceAddress(), memory.data(), memory.size()); | 1311 | system.ApplicationMemory().ReadBlock(transfer_mem->GetSourceAddress(), memory.data(), |
| 1312 | memory.size()); | ||
| 1302 | 1313 | ||
| 1303 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | 1314 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; |
| 1304 | rb.Push(ResultSuccess); | 1315 | rb.Push(ResultSuccess); |
diff --git a/src/core/hle/service/am/applets/applet_cabinet.cpp b/src/core/hle/service/am/applets/applet_cabinet.cpp index 162687b29..93c9f2a55 100644 --- a/src/core/hle/service/am/applets/applet_cabinet.cpp +++ b/src/core/hle/service/am/applets/applet_cabinet.cpp | |||
| @@ -174,4 +174,9 @@ void Cabinet::Cancel() { | |||
| 174 | broker.SignalStateChanged(); | 174 | broker.SignalStateChanged(); |
| 175 | } | 175 | } |
| 176 | 176 | ||
| 177 | Result Cabinet::RequestExit() { | ||
| 178 | frontend.Close(); | ||
| 179 | R_SUCCEED(); | ||
| 180 | } | ||
| 181 | |||
| 177 | } // namespace Service::AM::Applets | 182 | } // namespace Service::AM::Applets |
diff --git a/src/core/hle/service/am/applets/applet_cabinet.h b/src/core/hle/service/am/applets/applet_cabinet.h index 84197a807..edd295a27 100644 --- a/src/core/hle/service/am/applets/applet_cabinet.h +++ b/src/core/hle/service/am/applets/applet_cabinet.h | |||
| @@ -89,6 +89,7 @@ public: | |||
| 89 | void Execute() override; | 89 | void Execute() override; |
| 90 | void DisplayCompleted(bool apply_changes, std::string_view amiibo_name); | 90 | void DisplayCompleted(bool apply_changes, std::string_view amiibo_name); |
| 91 | void Cancel(); | 91 | void Cancel(); |
| 92 | Result RequestExit() override; | ||
| 92 | 93 | ||
| 93 | private: | 94 | private: |
| 94 | const Core::Frontend::CabinetApplet& frontend; | 95 | const Core::Frontend::CabinetApplet& frontend; |
diff --git a/src/core/hle/service/am/applets/applet_controller.cpp b/src/core/hle/service/am/applets/applet_controller.cpp index 58484519b..9840d2547 100644 --- a/src/core/hle/service/am/applets/applet_controller.cpp +++ b/src/core/hle/service/am/applets/applet_controller.cpp | |||
| @@ -224,7 +224,8 @@ void Controller::Execute() { | |||
| 224 | parameters.allow_dual_joycons, parameters.allow_left_joycon, | 224 | parameters.allow_dual_joycons, parameters.allow_left_joycon, |
| 225 | parameters.allow_right_joycon); | 225 | parameters.allow_right_joycon); |
| 226 | 226 | ||
| 227 | frontend.ReconfigureControllers([this] { ConfigurationComplete(); }, parameters); | 227 | frontend.ReconfigureControllers( |
| 228 | [this](bool is_success) { ConfigurationComplete(is_success); }, parameters); | ||
| 228 | break; | 229 | break; |
| 229 | } | 230 | } |
| 230 | case ControllerSupportMode::ShowControllerStrapGuide: | 231 | case ControllerSupportMode::ShowControllerStrapGuide: |
| @@ -232,16 +233,16 @@ void Controller::Execute() { | |||
| 232 | case ControllerSupportMode::ShowControllerKeyRemappingForSystem: | 233 | case ControllerSupportMode::ShowControllerKeyRemappingForSystem: |
| 233 | UNIMPLEMENTED_MSG("ControllerSupportMode={} is not implemented", | 234 | UNIMPLEMENTED_MSG("ControllerSupportMode={} is not implemented", |
| 234 | controller_private_arg.mode); | 235 | controller_private_arg.mode); |
| 235 | ConfigurationComplete(); | 236 | ConfigurationComplete(true); |
| 236 | break; | 237 | break; |
| 237 | default: { | 238 | default: { |
| 238 | ConfigurationComplete(); | 239 | ConfigurationComplete(true); |
| 239 | break; | 240 | break; |
| 240 | } | 241 | } |
| 241 | } | 242 | } |
| 242 | } | 243 | } |
| 243 | 244 | ||
| 244 | void Controller::ConfigurationComplete() { | 245 | void Controller::ConfigurationComplete(bool is_success) { |
| 245 | ControllerSupportResultInfo result_info{}; | 246 | ControllerSupportResultInfo result_info{}; |
| 246 | 247 | ||
| 247 | // If enable_single_mode is enabled, player_count is 1 regardless of any other parameters. | 248 | // If enable_single_mode is enabled, player_count is 1 regardless of any other parameters. |
| @@ -250,7 +251,8 @@ void Controller::ConfigurationComplete() { | |||
| 250 | 251 | ||
| 251 | result_info.selected_id = static_cast<u32>(system.HIDCore().GetFirstNpadId()); | 252 | result_info.selected_id = static_cast<u32>(system.HIDCore().GetFirstNpadId()); |
| 252 | 253 | ||
| 253 | result_info.result = 0; | 254 | result_info.result = |
| 255 | is_success ? ControllerSupportResult::Success : ControllerSupportResult::Cancel; | ||
| 254 | 256 | ||
| 255 | LOG_DEBUG(Service_HID, "Result Info: player_count={}, selected_id={}, result={}", | 257 | LOG_DEBUG(Service_HID, "Result Info: player_count={}, selected_id={}, result={}", |
| 256 | result_info.player_count, result_info.selected_id, result_info.result); | 258 | result_info.player_count, result_info.selected_id, result_info.result); |
| @@ -262,4 +264,9 @@ void Controller::ConfigurationComplete() { | |||
| 262 | broker.SignalStateChanged(); | 264 | broker.SignalStateChanged(); |
| 263 | } | 265 | } |
| 264 | 266 | ||
| 267 | Result Controller::RequestExit() { | ||
| 268 | frontend.Close(); | ||
| 269 | R_SUCCEED(); | ||
| 270 | } | ||
| 271 | |||
| 265 | } // namespace Service::AM::Applets | 272 | } // namespace Service::AM::Applets |
diff --git a/src/core/hle/service/am/applets/applet_controller.h b/src/core/hle/service/am/applets/applet_controller.h index 1f9adec65..f6c64f633 100644 --- a/src/core/hle/service/am/applets/applet_controller.h +++ b/src/core/hle/service/am/applets/applet_controller.h | |||
| @@ -48,6 +48,11 @@ enum class ControllerSupportCaller : u8 { | |||
| 48 | MaxControllerSupportCaller, | 48 | MaxControllerSupportCaller, |
| 49 | }; | 49 | }; |
| 50 | 50 | ||
| 51 | enum class ControllerSupportResult : u32 { | ||
| 52 | Success = 0, | ||
| 53 | Cancel = 2, | ||
| 54 | }; | ||
| 55 | |||
| 51 | struct ControllerSupportArgPrivate { | 56 | struct ControllerSupportArgPrivate { |
| 52 | u32 arg_private_size{}; | 57 | u32 arg_private_size{}; |
| 53 | u32 arg_size{}; | 58 | u32 arg_size{}; |
| @@ -112,7 +117,7 @@ struct ControllerSupportResultInfo { | |||
| 112 | s8 player_count{}; | 117 | s8 player_count{}; |
| 113 | INSERT_PADDING_BYTES(3); | 118 | INSERT_PADDING_BYTES(3); |
| 114 | u32 selected_id{}; | 119 | u32 selected_id{}; |
| 115 | u32 result{}; | 120 | ControllerSupportResult result{}; |
| 116 | }; | 121 | }; |
| 117 | static_assert(sizeof(ControllerSupportResultInfo) == 0xC, | 122 | static_assert(sizeof(ControllerSupportResultInfo) == 0xC, |
| 118 | "ControllerSupportResultInfo has incorrect size."); | 123 | "ControllerSupportResultInfo has incorrect size."); |
| @@ -129,8 +134,9 @@ public: | |||
| 129 | Result GetStatus() const override; | 134 | Result GetStatus() const override; |
| 130 | void ExecuteInteractive() override; | 135 | void ExecuteInteractive() override; |
| 131 | void Execute() override; | 136 | void Execute() override; |
| 137 | Result RequestExit() override; | ||
| 132 | 138 | ||
| 133 | void ConfigurationComplete(); | 139 | void ConfigurationComplete(bool is_success); |
| 134 | 140 | ||
| 135 | private: | 141 | private: |
| 136 | const Core::Frontend::ControllerApplet& frontend; | 142 | const Core::Frontend::ControllerApplet& frontend; |
diff --git a/src/core/hle/service/am/applets/applet_error.cpp b/src/core/hle/service/am/applets/applet_error.cpp index b013896b4..b46ea840c 100644 --- a/src/core/hle/service/am/applets/applet_error.cpp +++ b/src/core/hle/service/am/applets/applet_error.cpp | |||
| @@ -209,4 +209,9 @@ void Error::DisplayCompleted() { | |||
| 209 | broker.SignalStateChanged(); | 209 | broker.SignalStateChanged(); |
| 210 | } | 210 | } |
| 211 | 211 | ||
| 212 | Result Error::RequestExit() { | ||
| 213 | frontend.Close(); | ||
| 214 | R_SUCCEED(); | ||
| 215 | } | ||
| 216 | |||
| 212 | } // namespace Service::AM::Applets | 217 | } // namespace Service::AM::Applets |
diff --git a/src/core/hle/service/am/applets/applet_error.h b/src/core/hle/service/am/applets/applet_error.h index d78d6f1d1..d822a32bb 100644 --- a/src/core/hle/service/am/applets/applet_error.h +++ b/src/core/hle/service/am/applets/applet_error.h | |||
| @@ -34,6 +34,7 @@ public: | |||
| 34 | Result GetStatus() const override; | 34 | Result GetStatus() const override; |
| 35 | void ExecuteInteractive() override; | 35 | void ExecuteInteractive() override; |
| 36 | void Execute() override; | 36 | void Execute() override; |
| 37 | Result RequestExit() override; | ||
| 37 | 38 | ||
| 38 | void DisplayCompleted(); | 39 | void DisplayCompleted(); |
| 39 | 40 | ||
diff --git a/src/core/hle/service/am/applets/applet_general_backend.cpp b/src/core/hle/service/am/applets/applet_general_backend.cpp index 1eefa85e3..8b352020e 100644 --- a/src/core/hle/service/am/applets/applet_general_backend.cpp +++ b/src/core/hle/service/am/applets/applet_general_backend.cpp | |||
| @@ -150,6 +150,11 @@ void Auth::AuthFinished(bool is_successful) { | |||
| 150 | broker.SignalStateChanged(); | 150 | broker.SignalStateChanged(); |
| 151 | } | 151 | } |
| 152 | 152 | ||
| 153 | Result Auth::RequestExit() { | ||
| 154 | frontend.Close(); | ||
| 155 | R_SUCCEED(); | ||
| 156 | } | ||
| 157 | |||
| 153 | PhotoViewer::PhotoViewer(Core::System& system_, LibraryAppletMode applet_mode_, | 158 | PhotoViewer::PhotoViewer(Core::System& system_, LibraryAppletMode applet_mode_, |
| 154 | const Core::Frontend::PhotoViewerApplet& frontend_) | 159 | const Core::Frontend::PhotoViewerApplet& frontend_) |
| 155 | : Applet{system_, applet_mode_}, frontend{frontend_}, system{system_} {} | 160 | : Applet{system_, applet_mode_}, frontend{frontend_}, system{system_} {} |
| @@ -202,6 +207,11 @@ void PhotoViewer::ViewFinished() { | |||
| 202 | broker.SignalStateChanged(); | 207 | broker.SignalStateChanged(); |
| 203 | } | 208 | } |
| 204 | 209 | ||
| 210 | Result PhotoViewer::RequestExit() { | ||
| 211 | frontend.Close(); | ||
| 212 | R_SUCCEED(); | ||
| 213 | } | ||
| 214 | |||
| 205 | StubApplet::StubApplet(Core::System& system_, AppletId id_, LibraryAppletMode applet_mode_) | 215 | StubApplet::StubApplet(Core::System& system_, AppletId id_, LibraryAppletMode applet_mode_) |
| 206 | : Applet{system_, applet_mode_}, id{id_}, system{system_} {} | 216 | : Applet{system_, applet_mode_}, id{id_}, system{system_} {} |
| 207 | 217 | ||
| @@ -250,4 +260,9 @@ void StubApplet::Execute() { | |||
| 250 | broker.SignalStateChanged(); | 260 | broker.SignalStateChanged(); |
| 251 | } | 261 | } |
| 252 | 262 | ||
| 263 | Result StubApplet::RequestExit() { | ||
| 264 | // Nothing to do. | ||
| 265 | R_SUCCEED(); | ||
| 266 | } | ||
| 267 | |||
| 253 | } // namespace Service::AM::Applets | 268 | } // namespace Service::AM::Applets |
diff --git a/src/core/hle/service/am/applets/applet_general_backend.h b/src/core/hle/service/am/applets/applet_general_backend.h index a9f2535a2..34ecaebb9 100644 --- a/src/core/hle/service/am/applets/applet_general_backend.h +++ b/src/core/hle/service/am/applets/applet_general_backend.h | |||
| @@ -28,6 +28,7 @@ public: | |||
| 28 | Result GetStatus() const override; | 28 | Result GetStatus() const override; |
| 29 | void ExecuteInteractive() override; | 29 | void ExecuteInteractive() override; |
| 30 | void Execute() override; | 30 | void Execute() override; |
| 31 | Result RequestExit() override; | ||
| 31 | 32 | ||
| 32 | void AuthFinished(bool is_successful = true); | 33 | void AuthFinished(bool is_successful = true); |
| 33 | 34 | ||
| @@ -59,6 +60,7 @@ public: | |||
| 59 | Result GetStatus() const override; | 60 | Result GetStatus() const override; |
| 60 | void ExecuteInteractive() override; | 61 | void ExecuteInteractive() override; |
| 61 | void Execute() override; | 62 | void Execute() override; |
| 63 | Result RequestExit() override; | ||
| 62 | 64 | ||
| 63 | void ViewFinished(); | 65 | void ViewFinished(); |
| 64 | 66 | ||
| @@ -80,6 +82,7 @@ public: | |||
| 80 | Result GetStatus() const override; | 82 | Result GetStatus() const override; |
| 81 | void ExecuteInteractive() override; | 83 | void ExecuteInteractive() override; |
| 82 | void Execute() override; | 84 | void Execute() override; |
| 85 | Result RequestExit() override; | ||
| 83 | 86 | ||
| 84 | private: | 87 | private: |
| 85 | AppletId id; | 88 | AppletId id; |
diff --git a/src/core/hle/service/am/applets/applet_mii_edit.cpp b/src/core/hle/service/am/applets/applet_mii_edit.cpp index ae80ef506..d1f652c09 100644 --- a/src/core/hle/service/am/applets/applet_mii_edit.cpp +++ b/src/core/hle/service/am/applets/applet_mii_edit.cpp | |||
| @@ -135,4 +135,9 @@ void MiiEdit::MiiEditOutputForCharInfoEditing(MiiEditResult result, | |||
| 135 | broker.SignalStateChanged(); | 135 | broker.SignalStateChanged(); |
| 136 | } | 136 | } |
| 137 | 137 | ||
| 138 | Result MiiEdit::RequestExit() { | ||
| 139 | frontend.Close(); | ||
| 140 | R_SUCCEED(); | ||
| 141 | } | ||
| 142 | |||
| 138 | } // namespace Service::AM::Applets | 143 | } // namespace Service::AM::Applets |
diff --git a/src/core/hle/service/am/applets/applet_mii_edit.h b/src/core/hle/service/am/applets/applet_mii_edit.h index d18dd3cf5..3f46fae1b 100644 --- a/src/core/hle/service/am/applets/applet_mii_edit.h +++ b/src/core/hle/service/am/applets/applet_mii_edit.h | |||
| @@ -25,6 +25,7 @@ public: | |||
| 25 | Result GetStatus() const override; | 25 | Result GetStatus() const override; |
| 26 | void ExecuteInteractive() override; | 26 | void ExecuteInteractive() override; |
| 27 | void Execute() override; | 27 | void Execute() override; |
| 28 | Result RequestExit() override; | ||
| 28 | 29 | ||
| 29 | void MiiEditOutput(MiiEditResult result, s32 index); | 30 | void MiiEditOutput(MiiEditResult result, s32 index); |
| 30 | 31 | ||
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 1d69f5447..89cb323e9 100644 --- a/src/core/hle/service/am/applets/applet_profile_select.cpp +++ b/src/core/hle/service/am/applets/applet_profile_select.cpp | |||
| @@ -25,13 +25,29 @@ void ProfileSelect::Initialize() { | |||
| 25 | final_data.clear(); | 25 | final_data.clear(); |
| 26 | 26 | ||
| 27 | Applet::Initialize(); | 27 | Applet::Initialize(); |
| 28 | profile_select_version = ProfileSelectAppletVersion{common_args.library_version}; | ||
| 28 | 29 | ||
| 29 | const auto user_config_storage = broker.PopNormalDataToApplet(); | 30 | const auto user_config_storage = broker.PopNormalDataToApplet(); |
| 30 | ASSERT(user_config_storage != nullptr); | 31 | ASSERT(user_config_storage != nullptr); |
| 31 | const auto& user_config = user_config_storage->GetData(); | 32 | const auto& user_config = user_config_storage->GetData(); |
| 32 | 33 | ||
| 33 | ASSERT(user_config.size() >= sizeof(UserSelectionConfig)); | 34 | LOG_INFO(Service_AM, "Initializing Profile Select Applet with version={}", |
| 34 | std::memcpy(&config, user_config.data(), sizeof(UserSelectionConfig)); | 35 | profile_select_version); |
| 36 | |||
| 37 | switch (profile_select_version) { | ||
| 38 | case ProfileSelectAppletVersion::Version1: | ||
| 39 | ASSERT(user_config.size() == sizeof(UiSettingsV1)); | ||
| 40 | std::memcpy(&config_old, user_config.data(), sizeof(UiSettingsV1)); | ||
| 41 | break; | ||
| 42 | case ProfileSelectAppletVersion::Version2: | ||
| 43 | case ProfileSelectAppletVersion::Version3: | ||
| 44 | ASSERT(user_config.size() == sizeof(UiSettings)); | ||
| 45 | std::memcpy(&config, user_config.data(), sizeof(UiSettings)); | ||
| 46 | break; | ||
| 47 | default: | ||
| 48 | UNIMPLEMENTED_MSG("Unknown profile_select_version = {}", profile_select_version); | ||
| 49 | break; | ||
| 50 | } | ||
| 35 | } | 51 | } |
| 36 | 52 | ||
| 37 | bool ProfileSelect::TransactionComplete() const { | 53 | bool ProfileSelect::TransactionComplete() const { |
| @@ -52,11 +68,37 @@ void ProfileSelect::Execute() { | |||
| 52 | return; | 68 | return; |
| 53 | } | 69 | } |
| 54 | 70 | ||
| 55 | frontend.SelectProfile([this](std::optional<Common::UUID> uuid) { SelectionComplete(uuid); }); | 71 | Core::Frontend::ProfileSelectParameters parameters{}; |
| 72 | |||
| 73 | switch (profile_select_version) { | ||
| 74 | case ProfileSelectAppletVersion::Version1: | ||
| 75 | parameters = { | ||
| 76 | .mode = config_old.mode, | ||
| 77 | .invalid_uid_list = config_old.invalid_uid_list, | ||
| 78 | .display_options = config_old.display_options, | ||
| 79 | .purpose = UserSelectionPurpose::General, | ||
| 80 | }; | ||
| 81 | break; | ||
| 82 | case ProfileSelectAppletVersion::Version2: | ||
| 83 | case ProfileSelectAppletVersion::Version3: | ||
| 84 | parameters = { | ||
| 85 | .mode = config.mode, | ||
| 86 | .invalid_uid_list = config.invalid_uid_list, | ||
| 87 | .display_options = config.display_options, | ||
| 88 | .purpose = config.purpose, | ||
| 89 | }; | ||
| 90 | break; | ||
| 91 | default: | ||
| 92 | UNIMPLEMENTED_MSG("Unknown profile_select_version = {}", profile_select_version); | ||
| 93 | break; | ||
| 94 | } | ||
| 95 | |||
| 96 | frontend.SelectProfile([this](std::optional<Common::UUID> uuid) { SelectionComplete(uuid); }, | ||
| 97 | parameters); | ||
| 56 | } | 98 | } |
| 57 | 99 | ||
| 58 | void ProfileSelect::SelectionComplete(std::optional<Common::UUID> uuid) { | 100 | void ProfileSelect::SelectionComplete(std::optional<Common::UUID> uuid) { |
| 59 | UserSelectionOutput output{}; | 101 | UiReturnArg output{}; |
| 60 | 102 | ||
| 61 | if (uuid.has_value() && uuid->IsValid()) { | 103 | if (uuid.has_value() && uuid->IsValid()) { |
| 62 | output.result = 0; | 104 | output.result = 0; |
| @@ -67,10 +109,15 @@ void ProfileSelect::SelectionComplete(std::optional<Common::UUID> uuid) { | |||
| 67 | output.uuid_selected = Common::InvalidUUID; | 109 | output.uuid_selected = Common::InvalidUUID; |
| 68 | } | 110 | } |
| 69 | 111 | ||
| 70 | final_data = std::vector<u8>(sizeof(UserSelectionOutput)); | 112 | final_data = std::vector<u8>(sizeof(UiReturnArg)); |
| 71 | std::memcpy(final_data.data(), &output, final_data.size()); | 113 | std::memcpy(final_data.data(), &output, final_data.size()); |
| 72 | broker.PushNormalDataFromApplet(std::make_shared<IStorage>(system, std::move(final_data))); | 114 | broker.PushNormalDataFromApplet(std::make_shared<IStorage>(system, std::move(final_data))); |
| 73 | broker.SignalStateChanged(); | 115 | broker.SignalStateChanged(); |
| 74 | } | 116 | } |
| 75 | 117 | ||
| 118 | Result ProfileSelect::RequestExit() { | ||
| 119 | frontend.Close(); | ||
| 120 | R_SUCCEED(); | ||
| 121 | } | ||
| 122 | |||
| 76 | } // namespace Service::AM::Applets | 123 | } // namespace Service::AM::Applets |
diff --git a/src/core/hle/service/am/applets/applet_profile_select.h b/src/core/hle/service/am/applets/applet_profile_select.h index b77f1d205..369f9250f 100644 --- a/src/core/hle/service/am/applets/applet_profile_select.h +++ b/src/core/hle/service/am/applets/applet_profile_select.h | |||
| @@ -16,19 +16,100 @@ class System; | |||
| 16 | 16 | ||
| 17 | namespace Service::AM::Applets { | 17 | namespace Service::AM::Applets { |
| 18 | 18 | ||
| 19 | struct UserSelectionConfig { | 19 | enum class ProfileSelectAppletVersion : u32 { |
| 20 | // TODO(DarkLordZach): RE this structure | 20 | Version1 = 0x1, // 1.0.0+ |
| 21 | // It seems to be flags and the like that determine the UI of the applet on the switch... from | 21 | Version2 = 0x10000, // 2.0.0+ |
| 22 | // my research this is safe to ignore for now. | 22 | Version3 = 0x20000, // 6.0.0+ |
| 23 | INSERT_PADDING_BYTES(0xA0); | ||
| 24 | }; | 23 | }; |
| 25 | static_assert(sizeof(UserSelectionConfig) == 0xA0, "UserSelectionConfig has incorrect size."); | ||
| 26 | 24 | ||
| 27 | struct UserSelectionOutput { | 25 | // This is nn::account::UiMode |
| 26 | enum class UiMode { | ||
| 27 | UserSelector, | ||
| 28 | UserCreator, | ||
| 29 | EnsureNetworkServiceAccountAvailable, | ||
| 30 | UserIconEditor, | ||
| 31 | UserNicknameEditor, | ||
| 32 | UserCreatorForStarter, | ||
| 33 | NintendoAccountAuthorizationRequestContext, | ||
| 34 | IntroduceExternalNetworkServiceAccount, | ||
| 35 | IntroduceExternalNetworkServiceAccountForRegistration, | ||
| 36 | NintendoAccountNnidLinker, | ||
| 37 | LicenseRequirementsForNetworkService, | ||
| 38 | LicenseRequirementsForNetworkServiceWithUserContextImpl, | ||
| 39 | UserCreatorForImmediateNaLoginTest, | ||
| 40 | UserQualificationPromoter, | ||
| 41 | }; | ||
| 42 | |||
| 43 | // This is nn::account::UserSelectionPurpose | ||
| 44 | enum class UserSelectionPurpose { | ||
| 45 | General, | ||
| 46 | GameCardRegistration, | ||
| 47 | EShopLaunch, | ||
| 48 | EShopItemShow, | ||
| 49 | PicturePost, | ||
| 50 | NintendoAccountLinkage, | ||
| 51 | SettingsUpdate, | ||
| 52 | SaveDataDeletion, | ||
| 53 | UserMigration, | ||
| 54 | SaveDataTransfer, | ||
| 55 | }; | ||
| 56 | |||
| 57 | // This is nn::account::NintendoAccountStartupDialogType | ||
| 58 | enum class NintendoAccountStartupDialogType { | ||
| 59 | LoginAndCreate, | ||
| 60 | Login, | ||
| 61 | Create, | ||
| 62 | }; | ||
| 63 | |||
| 64 | // This is nn::account::UserSelectionSettingsForSystemService | ||
| 65 | struct UserSelectionSettingsForSystemService { | ||
| 66 | UserSelectionPurpose purpose; | ||
| 67 | bool enable_user_creation; | ||
| 68 | INSERT_PADDING_BYTES(0x3); | ||
| 69 | }; | ||
| 70 | static_assert(sizeof(UserSelectionSettingsForSystemService) == 0x8, | ||
| 71 | "UserSelectionSettingsForSystemService has incorrect size."); | ||
| 72 | |||
| 73 | struct UiSettingsDisplayOptions { | ||
| 74 | bool is_network_service_account_required; | ||
| 75 | bool is_skip_enabled; | ||
| 76 | bool is_system_or_launcher; | ||
| 77 | bool is_registration_permitted; | ||
| 78 | bool show_skip_button; | ||
| 79 | bool aditional_select; | ||
| 80 | bool show_user_selector; | ||
| 81 | bool is_unqualified_user_selectable; | ||
| 82 | }; | ||
| 83 | static_assert(sizeof(UiSettingsDisplayOptions) == 0x8, | ||
| 84 | "UiSettingsDisplayOptions has incorrect size."); | ||
| 85 | |||
| 86 | struct UiSettingsV1 { | ||
| 87 | UiMode mode; | ||
| 88 | INSERT_PADDING_BYTES(0x4); | ||
| 89 | std::array<Common::UUID, 8> invalid_uid_list; | ||
| 90 | u64 application_id; | ||
| 91 | UiSettingsDisplayOptions display_options; | ||
| 92 | }; | ||
| 93 | static_assert(sizeof(UiSettingsV1) == 0x98, "UiSettings has incorrect size."); | ||
| 94 | |||
| 95 | // This is nn::account::UiSettings | ||
| 96 | struct UiSettings { | ||
| 97 | UiMode mode; | ||
| 98 | INSERT_PADDING_BYTES(0x4); | ||
| 99 | std::array<Common::UUID, 8> invalid_uid_list; | ||
| 100 | u64 application_id; | ||
| 101 | UiSettingsDisplayOptions display_options; | ||
| 102 | UserSelectionPurpose purpose; | ||
| 103 | INSERT_PADDING_BYTES(0x4); | ||
| 104 | }; | ||
| 105 | static_assert(sizeof(UiSettings) == 0xA0, "UiSettings has incorrect size."); | ||
| 106 | |||
| 107 | // This is nn::account::UiReturnArg | ||
| 108 | struct UiReturnArg { | ||
| 28 | u64 result; | 109 | u64 result; |
| 29 | Common::UUID uuid_selected; | 110 | Common::UUID uuid_selected; |
| 30 | }; | 111 | }; |
| 31 | static_assert(sizeof(UserSelectionOutput) == 0x18, "UserSelectionOutput has incorrect size."); | 112 | static_assert(sizeof(UiReturnArg) == 0x18, "UiReturnArg has incorrect size."); |
| 32 | 113 | ||
| 33 | class ProfileSelect final : public Applet { | 114 | class ProfileSelect final : public Applet { |
| 34 | public: | 115 | public: |
| @@ -42,13 +123,17 @@ public: | |||
| 42 | Result GetStatus() const override; | 123 | Result GetStatus() const override; |
| 43 | void ExecuteInteractive() override; | 124 | void ExecuteInteractive() override; |
| 44 | void Execute() override; | 125 | void Execute() override; |
| 126 | Result RequestExit() override; | ||
| 45 | 127 | ||
| 46 | void SelectionComplete(std::optional<Common::UUID> uuid); | 128 | void SelectionComplete(std::optional<Common::UUID> uuid); |
| 47 | 129 | ||
| 48 | private: | 130 | private: |
| 49 | const Core::Frontend::ProfileSelectApplet& frontend; | 131 | const Core::Frontend::ProfileSelectApplet& frontend; |
| 50 | 132 | ||
| 51 | UserSelectionConfig config; | 133 | UiSettings config; |
| 134 | UiSettingsV1 config_old; | ||
| 135 | ProfileSelectAppletVersion profile_select_version; | ||
| 136 | |||
| 52 | bool complete = false; | 137 | bool complete = false; |
| 53 | Result status = ResultSuccess; | 138 | Result status = ResultSuccess; |
| 54 | std::vector<u8> final_data; | 139 | std::vector<u8> final_data; |
diff --git a/src/core/hle/service/am/applets/applet_software_keyboard.cpp b/src/core/hle/service/am/applets/applet_software_keyboard.cpp index c18236045..4145bb84f 100644 --- a/src/core/hle/service/am/applets/applet_software_keyboard.cpp +++ b/src/core/hle/service/am/applets/applet_software_keyboard.cpp | |||
| @@ -770,6 +770,11 @@ void SoftwareKeyboard::ExitKeyboard() { | |||
| 770 | broker.SignalStateChanged(); | 770 | broker.SignalStateChanged(); |
| 771 | } | 771 | } |
| 772 | 772 | ||
| 773 | Result SoftwareKeyboard::RequestExit() { | ||
| 774 | frontend.Close(); | ||
| 775 | R_SUCCEED(); | ||
| 776 | } | ||
| 777 | |||
| 773 | // Inline Software Keyboard Requests | 778 | // Inline Software Keyboard Requests |
| 774 | 779 | ||
| 775 | void SoftwareKeyboard::RequestFinalize(const std::vector<u8>& request_data) { | 780 | void SoftwareKeyboard::RequestFinalize(const std::vector<u8>& request_data) { |
diff --git a/src/core/hle/service/am/applets/applet_software_keyboard.h b/src/core/hle/service/am/applets/applet_software_keyboard.h index b01b31c98..2e919811b 100644 --- a/src/core/hle/service/am/applets/applet_software_keyboard.h +++ b/src/core/hle/service/am/applets/applet_software_keyboard.h | |||
| @@ -31,6 +31,7 @@ public: | |||
| 31 | Result GetStatus() const override; | 31 | Result GetStatus() const override; |
| 32 | void ExecuteInteractive() override; | 32 | void ExecuteInteractive() override; |
| 33 | void Execute() override; | 33 | void Execute() override; |
| 34 | Result RequestExit() override; | ||
| 34 | 35 | ||
| 35 | /** | 36 | /** |
| 36 | * Submits the input text to the application. | 37 | * Submits the input text to the application. |
diff --git a/src/core/hle/service/am/applets/applet_web_browser.cpp b/src/core/hle/service/am/applets/applet_web_browser.cpp index f061bae80..2accf7898 100644 --- a/src/core/hle/service/am/applets/applet_web_browser.cpp +++ b/src/core/hle/service/am/applets/applet_web_browser.cpp | |||
| @@ -363,6 +363,11 @@ void WebBrowser::WebBrowserExit(WebExitReason exit_reason, std::string last_url) | |||
| 363 | broker.SignalStateChanged(); | 363 | broker.SignalStateChanged(); |
| 364 | } | 364 | } |
| 365 | 365 | ||
| 366 | Result WebBrowser::RequestExit() { | ||
| 367 | frontend.Close(); | ||
| 368 | R_SUCCEED(); | ||
| 369 | } | ||
| 370 | |||
| 366 | bool WebBrowser::InputTLVExistsInMap(WebArgInputTLVType input_tlv_type) const { | 371 | bool WebBrowser::InputTLVExistsInMap(WebArgInputTLVType input_tlv_type) const { |
| 367 | return web_arg_input_tlv_map.find(input_tlv_type) != web_arg_input_tlv_map.end(); | 372 | return web_arg_input_tlv_map.find(input_tlv_type) != web_arg_input_tlv_map.end(); |
| 368 | } | 373 | } |
diff --git a/src/core/hle/service/am/applets/applet_web_browser.h b/src/core/hle/service/am/applets/applet_web_browser.h index fd727fac8..99fe18659 100644 --- a/src/core/hle/service/am/applets/applet_web_browser.h +++ b/src/core/hle/service/am/applets/applet_web_browser.h | |||
| @@ -35,6 +35,7 @@ public: | |||
| 35 | Result GetStatus() const override; | 35 | Result GetStatus() const override; |
| 36 | void ExecuteInteractive() override; | 36 | void ExecuteInteractive() override; |
| 37 | void Execute() override; | 37 | void Execute() override; |
| 38 | Result RequestExit() override; | ||
| 38 | 39 | ||
| 39 | void ExtractOfflineRomFS(); | 40 | void ExtractOfflineRomFS(); |
| 40 | 41 | ||
diff --git a/src/core/hle/service/am/applets/applets.h b/src/core/hle/service/am/applets/applets.h index a22eb62a8..12f374199 100644 --- a/src/core/hle/service/am/applets/applets.h +++ b/src/core/hle/service/am/applets/applets.h | |||
| @@ -142,6 +142,7 @@ public: | |||
| 142 | virtual Result GetStatus() const = 0; | 142 | virtual Result GetStatus() const = 0; |
| 143 | virtual void ExecuteInteractive() = 0; | 143 | virtual void ExecuteInteractive() = 0; |
| 144 | virtual void Execute() = 0; | 144 | virtual void Execute() = 0; |
| 145 | virtual Result RequestExit() = 0; | ||
| 145 | 146 | ||
| 146 | AppletDataBroker& GetBroker() { | 147 | AppletDataBroker& GetBroker() { |
| 147 | return broker; | 148 | return broker; |
diff --git a/src/core/hle/service/hid/controllers/console_sixaxis.cpp b/src/core/hle/service/hid/controllers/console_sixaxis.cpp index 37f2e4405..bcb272eaf 100644 --- a/src/core/hle/service/hid/controllers/console_sixaxis.cpp +++ b/src/core/hle/service/hid/controllers/console_sixaxis.cpp | |||
| @@ -60,7 +60,8 @@ void Controller_ConsoleSixAxis::OnUpdate(const Core::Timing::CoreTiming& core_ti | |||
| 60 | 60 | ||
| 61 | // Update seven six axis transfer memory | 61 | // Update seven six axis transfer memory |
| 62 | seven_sixaxis_lifo.WriteNextEntry(next_seven_sixaxis_state); | 62 | seven_sixaxis_lifo.WriteNextEntry(next_seven_sixaxis_state); |
| 63 | system.Memory().WriteBlock(transfer_memory, &seven_sixaxis_lifo, sizeof(seven_sixaxis_lifo)); | 63 | system.ApplicationMemory().WriteBlock(transfer_memory, &seven_sixaxis_lifo, |
| 64 | sizeof(seven_sixaxis_lifo)); | ||
| 64 | } | 65 | } |
| 65 | 66 | ||
| 66 | void Controller_ConsoleSixAxis::SetTransferMemoryAddress(Common::ProcessAddress t_mem) { | 67 | void Controller_ConsoleSixAxis::SetTransferMemoryAddress(Common::ProcessAddress t_mem) { |
diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp index ba6f04d8d..b070327ec 100644 --- a/src/core/hle/service/hid/controllers/npad.cpp +++ b/src/core/hle/service/hid/controllers/npad.cpp | |||
| @@ -819,12 +819,12 @@ Controller_NPad::NpadCommunicationMode Controller_NPad::GetNpadCommunicationMode | |||
| 819 | return communication_mode; | 819 | return communication_mode; |
| 820 | } | 820 | } |
| 821 | 821 | ||
| 822 | Result Controller_NPad::SetNpadMode(Core::HID::NpadIdType npad_id, | 822 | bool Controller_NPad::SetNpadMode(Core::HID::NpadIdType& new_npad_id, Core::HID::NpadIdType npad_id, |
| 823 | NpadJoyDeviceType npad_device_type, | 823 | NpadJoyDeviceType npad_device_type, |
| 824 | NpadJoyAssignmentMode assignment_mode) { | 824 | NpadJoyAssignmentMode assignment_mode) { |
| 825 | if (!IsNpadIdValid(npad_id)) { | 825 | if (!IsNpadIdValid(npad_id)) { |
| 826 | LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id); | 826 | LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id); |
| 827 | return InvalidNpadId; | 827 | return false; |
| 828 | } | 828 | } |
| 829 | 829 | ||
| 830 | auto& controller = GetControllerFromNpadIdType(npad_id); | 830 | auto& controller = GetControllerFromNpadIdType(npad_id); |
| @@ -833,7 +833,7 @@ Result Controller_NPad::SetNpadMode(Core::HID::NpadIdType npad_id, | |||
| 833 | } | 833 | } |
| 834 | 834 | ||
| 835 | if (!controller.device->IsConnected()) { | 835 | if (!controller.device->IsConnected()) { |
| 836 | return ResultSuccess; | 836 | return false; |
| 837 | } | 837 | } |
| 838 | 838 | ||
| 839 | if (assignment_mode == NpadJoyAssignmentMode::Dual) { | 839 | if (assignment_mode == NpadJoyAssignmentMode::Dual) { |
| @@ -842,52 +842,52 @@ Result Controller_NPad::SetNpadMode(Core::HID::NpadIdType npad_id, | |||
| 842 | controller.is_dual_left_connected = true; | 842 | controller.is_dual_left_connected = true; |
| 843 | controller.is_dual_right_connected = false; | 843 | controller.is_dual_right_connected = false; |
| 844 | UpdateControllerAt(Core::HID::NpadStyleIndex::JoyconDual, npad_id, true); | 844 | UpdateControllerAt(Core::HID::NpadStyleIndex::JoyconDual, npad_id, true); |
| 845 | return ResultSuccess; | 845 | return false; |
| 846 | } | 846 | } |
| 847 | if (controller.device->GetNpadStyleIndex() == Core::HID::NpadStyleIndex::JoyconRight) { | 847 | if (controller.device->GetNpadStyleIndex() == Core::HID::NpadStyleIndex::JoyconRight) { |
| 848 | DisconnectNpad(npad_id); | 848 | DisconnectNpad(npad_id); |
| 849 | controller.is_dual_left_connected = false; | 849 | controller.is_dual_left_connected = false; |
| 850 | controller.is_dual_right_connected = true; | 850 | controller.is_dual_right_connected = true; |
| 851 | UpdateControllerAt(Core::HID::NpadStyleIndex::JoyconDual, npad_id, true); | 851 | UpdateControllerAt(Core::HID::NpadStyleIndex::JoyconDual, npad_id, true); |
| 852 | return ResultSuccess; | 852 | return false; |
| 853 | } | 853 | } |
| 854 | return ResultSuccess; | 854 | return false; |
| 855 | } | 855 | } |
| 856 | 856 | ||
| 857 | // This is for NpadJoyAssignmentMode::Single | 857 | // This is for NpadJoyAssignmentMode::Single |
| 858 | 858 | ||
| 859 | // Only JoyconDual get affected by this function | 859 | // Only JoyconDual get affected by this function |
| 860 | if (controller.device->GetNpadStyleIndex() != Core::HID::NpadStyleIndex::JoyconDual) { | 860 | if (controller.device->GetNpadStyleIndex() != Core::HID::NpadStyleIndex::JoyconDual) { |
| 861 | return ResultSuccess; | 861 | return false; |
| 862 | } | 862 | } |
| 863 | 863 | ||
| 864 | if (controller.is_dual_left_connected && !controller.is_dual_right_connected) { | 864 | if (controller.is_dual_left_connected && !controller.is_dual_right_connected) { |
| 865 | DisconnectNpad(npad_id); | 865 | DisconnectNpad(npad_id); |
| 866 | UpdateControllerAt(Core::HID::NpadStyleIndex::JoyconLeft, npad_id, true); | 866 | UpdateControllerAt(Core::HID::NpadStyleIndex::JoyconLeft, npad_id, true); |
| 867 | return ResultSuccess; | 867 | return false; |
| 868 | } | 868 | } |
| 869 | if (!controller.is_dual_left_connected && controller.is_dual_right_connected) { | 869 | if (!controller.is_dual_left_connected && controller.is_dual_right_connected) { |
| 870 | DisconnectNpad(npad_id); | 870 | DisconnectNpad(npad_id); |
| 871 | UpdateControllerAt(Core::HID::NpadStyleIndex::JoyconRight, npad_id, true); | 871 | UpdateControllerAt(Core::HID::NpadStyleIndex::JoyconRight, npad_id, true); |
| 872 | return ResultSuccess; | 872 | return false; |
| 873 | } | 873 | } |
| 874 | 874 | ||
| 875 | // We have two controllers connected to the same npad_id we need to split them | 875 | // We have two controllers connected to the same npad_id we need to split them |
| 876 | const auto npad_id_2 = hid_core.GetFirstDisconnectedNpadId(); | 876 | new_npad_id = hid_core.GetFirstDisconnectedNpadId(); |
| 877 | auto& controller_2 = GetControllerFromNpadIdType(npad_id_2); | 877 | auto& controller_2 = GetControllerFromNpadIdType(new_npad_id); |
| 878 | DisconnectNpad(npad_id); | 878 | DisconnectNpad(npad_id); |
| 879 | if (npad_device_type == NpadJoyDeviceType::Left) { | 879 | if (npad_device_type == NpadJoyDeviceType::Left) { |
| 880 | UpdateControllerAt(Core::HID::NpadStyleIndex::JoyconLeft, npad_id, true); | 880 | UpdateControllerAt(Core::HID::NpadStyleIndex::JoyconLeft, npad_id, true); |
| 881 | controller_2.is_dual_left_connected = false; | 881 | controller_2.is_dual_left_connected = false; |
| 882 | controller_2.is_dual_right_connected = true; | 882 | controller_2.is_dual_right_connected = true; |
| 883 | UpdateControllerAt(Core::HID::NpadStyleIndex::JoyconDual, npad_id_2, true); | 883 | UpdateControllerAt(Core::HID::NpadStyleIndex::JoyconDual, new_npad_id, true); |
| 884 | } else { | 884 | } else { |
| 885 | UpdateControllerAt(Core::HID::NpadStyleIndex::JoyconRight, npad_id, true); | 885 | UpdateControllerAt(Core::HID::NpadStyleIndex::JoyconRight, npad_id, true); |
| 886 | controller_2.is_dual_left_connected = true; | 886 | controller_2.is_dual_left_connected = true; |
| 887 | controller_2.is_dual_right_connected = false; | 887 | controller_2.is_dual_right_connected = false; |
| 888 | UpdateControllerAt(Core::HID::NpadStyleIndex::JoyconDual, npad_id_2, true); | 888 | UpdateControllerAt(Core::HID::NpadStyleIndex::JoyconDual, new_npad_id, true); |
| 889 | } | 889 | } |
| 890 | return ResultSuccess; | 890 | return true; |
| 891 | } | 891 | } |
| 892 | 892 | ||
| 893 | bool Controller_NPad::VibrateControllerAtIndex(Core::HID::NpadIdType npad_id, | 893 | bool Controller_NPad::VibrateControllerAtIndex(Core::HID::NpadIdType npad_id, |
| @@ -1388,7 +1388,8 @@ Result Controller_NPad::MergeSingleJoyAsDualJoy(Core::HID::NpadIdType npad_id_1, | |||
| 1388 | return NpadIsDualJoycon; | 1388 | return NpadIsDualJoycon; |
| 1389 | } | 1389 | } |
| 1390 | 1390 | ||
| 1391 | // Disconnect the joycon at the second id and connect the dual joycon at the first index. | 1391 | // Disconnect the joycons and connect them as dual joycon at the first index. |
| 1392 | DisconnectNpad(npad_id_1); | ||
| 1392 | DisconnectNpad(npad_id_2); | 1393 | DisconnectNpad(npad_id_2); |
| 1393 | controller_1.is_dual_left_connected = true; | 1394 | controller_1.is_dual_left_connected = true; |
| 1394 | controller_1.is_dual_right_connected = true; | 1395 | controller_1.is_dual_right_connected = true; |
diff --git a/src/core/hle/service/hid/controllers/npad.h b/src/core/hle/service/hid/controllers/npad.h index a5998c453..9cfe298f1 100644 --- a/src/core/hle/service/hid/controllers/npad.h +++ b/src/core/hle/service/hid/controllers/npad.h | |||
| @@ -102,8 +102,8 @@ public: | |||
| 102 | void SetNpadCommunicationMode(NpadCommunicationMode communication_mode_); | 102 | void SetNpadCommunicationMode(NpadCommunicationMode communication_mode_); |
| 103 | NpadCommunicationMode GetNpadCommunicationMode() const; | 103 | NpadCommunicationMode GetNpadCommunicationMode() const; |
| 104 | 104 | ||
| 105 | Result SetNpadMode(Core::HID::NpadIdType npad_id, NpadJoyDeviceType npad_device_type, | 105 | bool SetNpadMode(Core::HID::NpadIdType& new_npad_id, Core::HID::NpadIdType npad_id, |
| 106 | NpadJoyAssignmentMode assignment_mode); | 106 | NpadJoyDeviceType npad_device_type, NpadJoyAssignmentMode assignment_mode); |
| 107 | 107 | ||
| 108 | bool VibrateControllerAtIndex(Core::HID::NpadIdType npad_id, std::size_t device_index, | 108 | bool VibrateControllerAtIndex(Core::HID::NpadIdType npad_id, std::size_t device_index, |
| 109 | const Core::HID::VibrationValue& vibration_value); | 109 | const Core::HID::VibrationValue& vibration_value); |
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index 4529ad643..87e7b864a 100644 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp | |||
| @@ -302,7 +302,7 @@ Hid::Hid(Core::System& system_) | |||
| 302 | {130, &Hid::SwapNpadAssignment, "SwapNpadAssignment"}, | 302 | {130, &Hid::SwapNpadAssignment, "SwapNpadAssignment"}, |
| 303 | {131, &Hid::IsUnintendedHomeButtonInputProtectionEnabled, "IsUnintendedHomeButtonInputProtectionEnabled"}, | 303 | {131, &Hid::IsUnintendedHomeButtonInputProtectionEnabled, "IsUnintendedHomeButtonInputProtectionEnabled"}, |
| 304 | {132, &Hid::EnableUnintendedHomeButtonInputProtection, "EnableUnintendedHomeButtonInputProtection"}, | 304 | {132, &Hid::EnableUnintendedHomeButtonInputProtection, "EnableUnintendedHomeButtonInputProtection"}, |
| 305 | {133, nullptr, "SetNpadJoyAssignmentModeSingleWithDestination"}, | 305 | {133, &Hid::SetNpadJoyAssignmentModeSingleWithDestination, "SetNpadJoyAssignmentModeSingleWithDestination"}, |
| 306 | {134, &Hid::SetNpadAnalogStickUseCenterClamp, "SetNpadAnalogStickUseCenterClamp"}, | 306 | {134, &Hid::SetNpadAnalogStickUseCenterClamp, "SetNpadAnalogStickUseCenterClamp"}, |
| 307 | {135, &Hid::SetNpadCaptureButtonAssignment, "SetNpadCaptureButtonAssignment"}, | 307 | {135, &Hid::SetNpadCaptureButtonAssignment, "SetNpadCaptureButtonAssignment"}, |
| 308 | {136, &Hid::ClearNpadCaptureButtonAssignment, "ClearNpadCaptureButtonAssignment"}, | 308 | {136, &Hid::ClearNpadCaptureButtonAssignment, "ClearNpadCaptureButtonAssignment"}, |
| @@ -1180,8 +1180,10 @@ void Hid::SetNpadJoyAssignmentModeSingleByDefault(HLERequestContext& ctx) { | |||
| 1180 | 1180 | ||
| 1181 | const auto parameters{rp.PopRaw<Parameters>()}; | 1181 | const auto parameters{rp.PopRaw<Parameters>()}; |
| 1182 | 1182 | ||
| 1183 | Core::HID::NpadIdType new_npad_id{}; | ||
| 1183 | auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad); | 1184 | auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad); |
| 1184 | controller.SetNpadMode(parameters.npad_id, Controller_NPad::NpadJoyDeviceType::Left, | 1185 | controller.SetNpadMode(new_npad_id, parameters.npad_id, |
| 1186 | Controller_NPad::NpadJoyDeviceType::Left, | ||
| 1185 | Controller_NPad::NpadJoyAssignmentMode::Single); | 1187 | Controller_NPad::NpadJoyAssignmentMode::Single); |
| 1186 | 1188 | ||
| 1187 | LOG_INFO(Service_HID, "called, npad_id={}, applet_resource_user_id={}", parameters.npad_id, | 1189 | LOG_INFO(Service_HID, "called, npad_id={}, applet_resource_user_id={}", parameters.npad_id, |
| @@ -1203,8 +1205,9 @@ void Hid::SetNpadJoyAssignmentModeSingle(HLERequestContext& ctx) { | |||
| 1203 | 1205 | ||
| 1204 | const auto parameters{rp.PopRaw<Parameters>()}; | 1206 | const auto parameters{rp.PopRaw<Parameters>()}; |
| 1205 | 1207 | ||
| 1208 | Core::HID::NpadIdType new_npad_id{}; | ||
| 1206 | auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad); | 1209 | auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad); |
| 1207 | controller.SetNpadMode(parameters.npad_id, parameters.npad_joy_device_type, | 1210 | controller.SetNpadMode(new_npad_id, parameters.npad_id, parameters.npad_joy_device_type, |
| 1208 | Controller_NPad::NpadJoyAssignmentMode::Single); | 1211 | Controller_NPad::NpadJoyAssignmentMode::Single); |
| 1209 | 1212 | ||
| 1210 | LOG_INFO(Service_HID, "called, npad_id={}, applet_resource_user_id={}, npad_joy_device_type={}", | 1213 | LOG_INFO(Service_HID, "called, npad_id={}, applet_resource_user_id={}, npad_joy_device_type={}", |
| @@ -1226,8 +1229,10 @@ void Hid::SetNpadJoyAssignmentModeDual(HLERequestContext& ctx) { | |||
| 1226 | 1229 | ||
| 1227 | const auto parameters{rp.PopRaw<Parameters>()}; | 1230 | const auto parameters{rp.PopRaw<Parameters>()}; |
| 1228 | 1231 | ||
| 1232 | Core::HID::NpadIdType new_npad_id{}; | ||
| 1229 | auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad); | 1233 | auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad); |
| 1230 | controller.SetNpadMode(parameters.npad_id, {}, Controller_NPad::NpadJoyAssignmentMode::Dual); | 1234 | controller.SetNpadMode(new_npad_id, parameters.npad_id, {}, |
| 1235 | Controller_NPad::NpadJoyAssignmentMode::Dual); | ||
| 1231 | 1236 | ||
| 1232 | LOG_INFO(Service_HID, "called, npad_id={}, applet_resource_user_id={}", parameters.npad_id, | 1237 | LOG_INFO(Service_HID, "called, npad_id={}, applet_resource_user_id={}", parameters.npad_id, |
| 1233 | parameters.applet_resource_user_id); | 1238 | parameters.applet_resource_user_id); |
| @@ -1369,6 +1374,34 @@ void Hid::EnableUnintendedHomeButtonInputProtection(HLERequestContext& ctx) { | |||
| 1369 | rb.Push(result); | 1374 | rb.Push(result); |
| 1370 | } | 1375 | } |
| 1371 | 1376 | ||
| 1377 | void Hid::SetNpadJoyAssignmentModeSingleWithDestination(HLERequestContext& ctx) { | ||
| 1378 | IPC::RequestParser rp{ctx}; | ||
| 1379 | struct Parameters { | ||
| 1380 | Core::HID::NpadIdType npad_id; | ||
| 1381 | INSERT_PADDING_WORDS_NOINIT(1); | ||
| 1382 | u64 applet_resource_user_id; | ||
| 1383 | Controller_NPad::NpadJoyDeviceType npad_joy_device_type; | ||
| 1384 | }; | ||
| 1385 | static_assert(sizeof(Parameters) == 0x18, "Parameters has incorrect size."); | ||
| 1386 | |||
| 1387 | const auto parameters{rp.PopRaw<Parameters>()}; | ||
| 1388 | |||
| 1389 | Core::HID::NpadIdType new_npad_id{}; | ||
| 1390 | auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad); | ||
| 1391 | const auto is_reassigned = | ||
| 1392 | controller.SetNpadMode(new_npad_id, parameters.npad_id, parameters.npad_joy_device_type, | ||
| 1393 | Controller_NPad::NpadJoyAssignmentMode::Single); | ||
| 1394 | |||
| 1395 | LOG_INFO(Service_HID, "called, npad_id={}, applet_resource_user_id={}, npad_joy_device_type={}", | ||
| 1396 | parameters.npad_id, parameters.applet_resource_user_id, | ||
| 1397 | parameters.npad_joy_device_type); | ||
| 1398 | |||
| 1399 | IPC::ResponseBuilder rb{ctx, 4}; | ||
| 1400 | rb.Push(ResultSuccess); | ||
| 1401 | rb.Push(is_reassigned); | ||
| 1402 | rb.PushEnum(new_npad_id); | ||
| 1403 | } | ||
| 1404 | |||
| 1372 | void Hid::SetNpadAnalogStickUseCenterClamp(HLERequestContext& ctx) { | 1405 | void Hid::SetNpadAnalogStickUseCenterClamp(HLERequestContext& ctx) { |
| 1373 | IPC::RequestParser rp{ctx}; | 1406 | IPC::RequestParser rp{ctx}; |
| 1374 | struct Parameters { | 1407 | struct Parameters { |
diff --git a/src/core/hle/service/hid/hid.h b/src/core/hle/service/hid/hid.h index c69e5f3fb..f247b83c2 100644 --- a/src/core/hle/service/hid/hid.h +++ b/src/core/hle/service/hid/hid.h | |||
| @@ -151,6 +151,7 @@ private: | |||
| 151 | void SwapNpadAssignment(HLERequestContext& ctx); | 151 | void SwapNpadAssignment(HLERequestContext& ctx); |
| 152 | void IsUnintendedHomeButtonInputProtectionEnabled(HLERequestContext& ctx); | 152 | void IsUnintendedHomeButtonInputProtectionEnabled(HLERequestContext& ctx); |
| 153 | void EnableUnintendedHomeButtonInputProtection(HLERequestContext& ctx); | 153 | void EnableUnintendedHomeButtonInputProtection(HLERequestContext& ctx); |
| 154 | void SetNpadJoyAssignmentModeSingleWithDestination(HLERequestContext& ctx); | ||
| 154 | void SetNpadAnalogStickUseCenterClamp(HLERequestContext& ctx); | 155 | void SetNpadAnalogStickUseCenterClamp(HLERequestContext& ctx); |
| 155 | void SetNpadCaptureButtonAssignment(HLERequestContext& ctx); | 156 | void SetNpadCaptureButtonAssignment(HLERequestContext& ctx); |
| 156 | void ClearNpadCaptureButtonAssignment(HLERequestContext& ctx); | 157 | void ClearNpadCaptureButtonAssignment(HLERequestContext& ctx); |
diff --git a/src/core/hle/service/hid/hidbus/ringcon.cpp b/src/core/hle/service/hid/hidbus/ringcon.cpp index 65a2dd521..378108012 100644 --- a/src/core/hle/service/hid/hidbus/ringcon.cpp +++ b/src/core/hle/service/hid/hidbus/ringcon.cpp | |||
| @@ -64,8 +64,8 @@ void RingController::OnUpdate() { | |||
| 64 | curr_entry.polling_data.out_size = sizeof(ringcon_value); | 64 | curr_entry.polling_data.out_size = sizeof(ringcon_value); |
| 65 | std::memcpy(curr_entry.polling_data.data.data(), &ringcon_value, sizeof(ringcon_value)); | 65 | std::memcpy(curr_entry.polling_data.data.data(), &ringcon_value, sizeof(ringcon_value)); |
| 66 | 66 | ||
| 67 | system.Memory().WriteBlock(transfer_memory, &enable_sixaxis_data, | 67 | system.ApplicationMemory().WriteBlock(transfer_memory, &enable_sixaxis_data, |
| 68 | sizeof(enable_sixaxis_data)); | 68 | sizeof(enable_sixaxis_data)); |
| 69 | break; | 69 | break; |
| 70 | } | 70 | } |
| 71 | default: | 71 | default: |
diff --git a/src/core/hle/service/hid/irsensor/image_transfer_processor.cpp b/src/core/hle/service/hid/irsensor/image_transfer_processor.cpp index ca5d067e8..803a6277c 100644 --- a/src/core/hle/service/hid/irsensor/image_transfer_processor.cpp +++ b/src/core/hle/service/hid/irsensor/image_transfer_processor.cpp | |||
| @@ -58,16 +58,16 @@ void ImageTransferProcessor::OnControllerUpdate(Core::HID::ControllerTriggerType | |||
| 58 | if (camera_data.format != current_config.origin_format) { | 58 | if (camera_data.format != current_config.origin_format) { |
| 59 | LOG_WARNING(Service_IRS, "Wrong Input format {} expected {}", camera_data.format, | 59 | LOG_WARNING(Service_IRS, "Wrong Input format {} expected {}", camera_data.format, |
| 60 | current_config.origin_format); | 60 | current_config.origin_format); |
| 61 | system.Memory().ZeroBlock(*system.ApplicationProcess(), transfer_memory, | 61 | system.ApplicationMemory().ZeroBlock(transfer_memory, |
| 62 | GetDataSize(current_config.trimming_format)); | 62 | GetDataSize(current_config.trimming_format)); |
| 63 | return; | 63 | return; |
| 64 | } | 64 | } |
| 65 | 65 | ||
| 66 | if (current_config.origin_format > current_config.trimming_format) { | 66 | if (current_config.origin_format > current_config.trimming_format) { |
| 67 | LOG_WARNING(Service_IRS, "Origin format {} is smaller than trimming format {}", | 67 | LOG_WARNING(Service_IRS, "Origin format {} is smaller than trimming format {}", |
| 68 | current_config.origin_format, current_config.trimming_format); | 68 | current_config.origin_format, current_config.trimming_format); |
| 69 | system.Memory().ZeroBlock(*system.ApplicationProcess(), transfer_memory, | 69 | system.ApplicationMemory().ZeroBlock(transfer_memory, |
| 70 | GetDataSize(current_config.trimming_format)); | 70 | GetDataSize(current_config.trimming_format)); |
| 71 | return; | 71 | return; |
| 72 | } | 72 | } |
| 73 | 73 | ||
| @@ -84,8 +84,8 @@ void ImageTransferProcessor::OnControllerUpdate(Core::HID::ControllerTriggerType | |||
| 84 | "Trimming area ({}, {}, {}, {}) is outside of origin area ({}, {})", | 84 | "Trimming area ({}, {}, {}, {}) is outside of origin area ({}, {})", |
| 85 | current_config.trimming_start_x, current_config.trimming_start_y, | 85 | current_config.trimming_start_x, current_config.trimming_start_y, |
| 86 | trimming_width, trimming_height, origin_width, origin_height); | 86 | trimming_width, trimming_height, origin_width, origin_height); |
| 87 | system.Memory().ZeroBlock(*system.ApplicationProcess(), transfer_memory, | 87 | system.ApplicationMemory().ZeroBlock(transfer_memory, |
| 88 | GetDataSize(current_config.trimming_format)); | 88 | GetDataSize(current_config.trimming_format)); |
| 89 | return; | 89 | return; |
| 90 | } | 90 | } |
| 91 | 91 | ||
| @@ -99,8 +99,8 @@ void ImageTransferProcessor::OnControllerUpdate(Core::HID::ControllerTriggerType | |||
| 99 | } | 99 | } |
| 100 | } | 100 | } |
| 101 | 101 | ||
| 102 | system.Memory().WriteBlock(transfer_memory, window_data.data(), | 102 | system.ApplicationMemory().WriteBlock(transfer_memory, window_data.data(), |
| 103 | GetDataSize(current_config.trimming_format)); | 103 | GetDataSize(current_config.trimming_format)); |
| 104 | 104 | ||
| 105 | if (!IsProcessorActive()) { | 105 | if (!IsProcessorActive()) { |
| 106 | StartProcessor(); | 106 | StartProcessor(); |
| @@ -148,7 +148,7 @@ Core::IrSensor::ImageTransferProcessorState ImageTransferProcessor::GetState( | |||
| 148 | std::vector<u8>& data) const { | 148 | std::vector<u8>& data) const { |
| 149 | const auto size = GetDataSize(current_config.trimming_format); | 149 | const auto size = GetDataSize(current_config.trimming_format); |
| 150 | data.resize(size); | 150 | data.resize(size); |
| 151 | system.Memory().ReadBlock(transfer_memory, data.data(), size); | 151 | system.ApplicationMemory().ReadBlock(transfer_memory, data.data(), size); |
| 152 | return processor_state; | 152 | return processor_state; |
| 153 | } | 153 | } |
| 154 | 154 | ||
diff --git a/src/core/hle/service/hle_ipc.cpp b/src/core/hle/service/hle_ipc.cpp index cca697c64..2290df705 100644 --- a/src/core/hle/service/hle_ipc.cpp +++ b/src/core/hle/service/hle_ipc.cpp | |||
| @@ -303,8 +303,7 @@ Result HLERequestContext::WriteToOutgoingCommandBuffer(Kernel::KThread& requesti | |||
| 303 | } | 303 | } |
| 304 | 304 | ||
| 305 | // Copy the translated command buffer back into the thread's command buffer area. | 305 | // Copy the translated command buffer back into the thread's command buffer area. |
| 306 | memory.WriteBlock(owner_process, requesting_thread.GetTlsAddress(), cmd_buf.data(), | 306 | memory.WriteBlock(requesting_thread.GetTlsAddress(), cmd_buf.data(), write_size * sizeof(u32)); |
| 307 | write_size * sizeof(u32)); | ||
| 308 | 307 | ||
| 309 | return ResultSuccess; | 308 | return ResultSuccess; |
| 310 | } | 309 | } |
diff --git a/src/core/hle/service/jit/jit.cpp b/src/core/hle/service/jit/jit.cpp index 607f27b21..be996870f 100644 --- a/src/core/hle/service/jit/jit.cpp +++ b/src/core/hle/service/jit/jit.cpp | |||
| @@ -24,8 +24,8 @@ class IJitEnvironment final : public ServiceFramework<IJitEnvironment> { | |||
| 24 | public: | 24 | public: |
| 25 | explicit IJitEnvironment(Core::System& system_, Kernel::KProcess& process_, CodeRange user_rx, | 25 | explicit IJitEnvironment(Core::System& system_, Kernel::KProcess& process_, CodeRange user_rx, |
| 26 | CodeRange user_ro) | 26 | CodeRange user_ro) |
| 27 | : ServiceFramework{system_, "IJitEnvironment"}, process{&process_}, context{ | 27 | : ServiceFramework{system_, "IJitEnvironment"}, process{&process_}, |
| 28 | system_.Memory()} { | 28 | context{system_.ApplicationMemory()} { |
| 29 | // clang-format off | 29 | // clang-format off |
| 30 | static const FunctionInfo functions[] = { | 30 | static const FunctionInfo functions[] = { |
| 31 | {0, &IJitEnvironment::GenerateCode, "GenerateCode"}, | 31 | {0, &IJitEnvironment::GenerateCode, "GenerateCode"}, |
diff --git a/src/core/hle/service/ldr/ldr.cpp b/src/core/hle/service/ldr/ldr.cpp index 437dc2ea5..c42489ff9 100644 --- a/src/core/hle/service/ldr/ldr.cpp +++ b/src/core/hle/service/ldr/ldr.cpp | |||
| @@ -225,7 +225,7 @@ public: | |||
| 225 | 225 | ||
| 226 | // Read NRR data from memory | 226 | // Read NRR data from memory |
| 227 | std::vector<u8> nrr_data(nrr_size); | 227 | std::vector<u8> nrr_data(nrr_size); |
| 228 | system.Memory().ReadBlock(nrr_address, nrr_data.data(), nrr_size); | 228 | system.ApplicationMemory().ReadBlock(nrr_address, nrr_data.data(), nrr_size); |
| 229 | NRRHeader header; | 229 | NRRHeader header; |
| 230 | std::memcpy(&header, nrr_data.data(), sizeof(NRRHeader)); | 230 | std::memcpy(&header, nrr_data.data(), sizeof(NRRHeader)); |
| 231 | 231 | ||
| @@ -314,7 +314,7 @@ public: | |||
| 314 | const auto is_region_available = [&](VAddr addr) { | 314 | const auto is_region_available = [&](VAddr addr) { |
| 315 | const auto end_addr = addr + size; | 315 | const auto end_addr = addr + size; |
| 316 | while (addr < end_addr) { | 316 | while (addr < end_addr) { |
| 317 | if (system.Memory().IsValidVirtualAddress(addr)) { | 317 | if (system.ApplicationMemory().IsValidVirtualAddress(addr)) { |
| 318 | return false; | 318 | return false; |
| 319 | } | 319 | } |
| 320 | 320 | ||
| @@ -427,8 +427,8 @@ public: | |||
| 427 | const VAddr bss_end_addr{ | 427 | const VAddr bss_end_addr{ |
| 428 | Common::AlignUp(bss_start + nro_header.bss_size, Kernel::PageSize)}; | 428 | Common::AlignUp(bss_start + nro_header.bss_size, Kernel::PageSize)}; |
| 429 | 429 | ||
| 430 | const auto CopyCode = [this, process](VAddr src_addr, VAddr dst_addr, u64 size) { | 430 | const auto CopyCode = [this](VAddr src_addr, VAddr dst_addr, u64 size) { |
| 431 | system.Memory().CopyBlock(*process, dst_addr, src_addr, size); | 431 | system.ApplicationMemory().CopyBlock(dst_addr, src_addr, size); |
| 432 | }; | 432 | }; |
| 433 | CopyCode(nro_addr + nro_header.segment_headers[TEXT_INDEX].memory_offset, text_start, | 433 | CopyCode(nro_addr + nro_header.segment_headers[TEXT_INDEX].memory_offset, text_start, |
| 434 | nro_header.segment_headers[TEXT_INDEX].memory_size); | 434 | nro_header.segment_headers[TEXT_INDEX].memory_size); |
| @@ -506,7 +506,7 @@ public: | |||
| 506 | 506 | ||
| 507 | // Read NRO data from memory | 507 | // Read NRO data from memory |
| 508 | std::vector<u8> nro_data(nro_size); | 508 | std::vector<u8> nro_data(nro_size); |
| 509 | system.Memory().ReadBlock(nro_address, nro_data.data(), nro_size); | 509 | system.ApplicationMemory().ReadBlock(nro_address, nro_data.data(), nro_size); |
| 510 | 510 | ||
| 511 | SHA256Hash hash{}; | 511 | SHA256Hash hash{}; |
| 512 | mbedtls_sha256_ret(nro_data.data(), nro_data.size(), hash.data(), 0); | 512 | mbedtls_sha256_ret(nro_data.data(), nro_data.size(), hash.data(), 0); |
diff --git a/src/core/hle/service/nfp/amiibo_crypto.cpp b/src/core/hle/service/nfp/amiibo_crypto.cpp index bba862fb2..a3622e792 100644 --- a/src/core/hle/service/nfp/amiibo_crypto.cpp +++ b/src/core/hle/service/nfp/amiibo_crypto.cpp | |||
| @@ -70,6 +70,10 @@ bool IsAmiiboValid(const EncryptedNTAG215File& ntag_file) { | |||
| 70 | return true; | 70 | return true; |
| 71 | } | 71 | } |
| 72 | 72 | ||
| 73 | bool IsAmiiboValid(const NTAG215File& ntag_file) { | ||
| 74 | return IsAmiiboValid(EncodedDataToNfcData(ntag_file)); | ||
| 75 | } | ||
| 76 | |||
| 73 | NTAG215File NfcDataToEncodedData(const EncryptedNTAG215File& nfc_data) { | 77 | NTAG215File NfcDataToEncodedData(const EncryptedNTAG215File& nfc_data) { |
| 74 | NTAG215File encoded_data{}; | 78 | NTAG215File encoded_data{}; |
| 75 | 79 | ||
diff --git a/src/core/hle/service/nfp/amiibo_crypto.h b/src/core/hle/service/nfp/amiibo_crypto.h index c9fd67a39..f6208ee6b 100644 --- a/src/core/hle/service/nfp/amiibo_crypto.h +++ b/src/core/hle/service/nfp/amiibo_crypto.h | |||
| @@ -60,6 +60,9 @@ static_assert(sizeof(DerivedKeys) == 0x30, "DerivedKeys is an invalid size"); | |||
| 60 | /// Validates that the amiibo file is not corrupted | 60 | /// Validates that the amiibo file is not corrupted |
| 61 | bool IsAmiiboValid(const EncryptedNTAG215File& ntag_file); | 61 | bool IsAmiiboValid(const EncryptedNTAG215File& ntag_file); |
| 62 | 62 | ||
| 63 | /// Validates that the amiibo file is not corrupted | ||
| 64 | bool IsAmiiboValid(const NTAG215File& ntag_file); | ||
| 65 | |||
| 63 | /// Converts from encrypted file format to encoded file format | 66 | /// Converts from encrypted file format to encoded file format |
| 64 | NTAG215File NfcDataToEncodedData(const EncryptedNTAG215File& nfc_data); | 67 | NTAG215File NfcDataToEncodedData(const EncryptedNTAG215File& nfc_data); |
| 65 | 68 | ||
diff --git a/src/core/hle/service/nfp/nfp_device.cpp b/src/core/hle/service/nfp/nfp_device.cpp index 5990e1473..607e70968 100644 --- a/src/core/hle/service/nfp/nfp_device.cpp +++ b/src/core/hle/service/nfp/nfp_device.cpp | |||
| @@ -121,7 +121,16 @@ bool NfpDevice::LoadAmiibo(std::span<const u8> data) { | |||
| 121 | 121 | ||
| 122 | // TODO: Filter by allowed_protocols here | 122 | // TODO: Filter by allowed_protocols here |
| 123 | 123 | ||
| 124 | memcpy(&encrypted_tag_data, data.data(), sizeof(EncryptedNTAG215File)); | 124 | memcpy(&tag_data, data.data(), sizeof(EncryptedNTAG215File)); |
| 125 | is_plain_amiibo = AmiiboCrypto::IsAmiiboValid(tag_data); | ||
| 126 | |||
| 127 | if (is_plain_amiibo) { | ||
| 128 | encrypted_tag_data = AmiiboCrypto::EncodedDataToNfcData(tag_data); | ||
| 129 | LOG_INFO(Service_NFP, "Using plain amiibo"); | ||
| 130 | } else { | ||
| 131 | tag_data = {}; | ||
| 132 | memcpy(&encrypted_tag_data, data.data(), sizeof(EncryptedNTAG215File)); | ||
| 133 | } | ||
| 125 | 134 | ||
| 126 | device_state = DeviceState::TagFound; | 135 | device_state = DeviceState::TagFound; |
| 127 | deactivate_event->GetReadableEvent().Clear(); | 136 | deactivate_event->GetReadableEvent().Clear(); |
| @@ -232,13 +241,17 @@ Result NfpDevice::Flush() { | |||
| 232 | 241 | ||
| 233 | tag_data.write_counter++; | 242 | tag_data.write_counter++; |
| 234 | 243 | ||
| 235 | if (!AmiiboCrypto::EncodeAmiibo(tag_data, encrypted_tag_data)) { | 244 | std::vector<u8> data(sizeof(EncryptedNTAG215File)); |
| 236 | LOG_ERROR(Service_NFP, "Failed to encode data"); | 245 | if (is_plain_amiibo) { |
| 237 | return WriteAmiiboFailed; | 246 | memcpy(data.data(), &tag_data, sizeof(tag_data)); |
| 238 | } | 247 | } else { |
| 248 | if (!AmiiboCrypto::EncodeAmiibo(tag_data, encrypted_tag_data)) { | ||
| 249 | LOG_ERROR(Service_NFP, "Failed to encode data"); | ||
| 250 | return WriteAmiiboFailed; | ||
| 251 | } | ||
| 239 | 252 | ||
| 240 | std::vector<u8> data(sizeof(encrypted_tag_data)); | 253 | memcpy(data.data(), &encrypted_tag_data, sizeof(encrypted_tag_data)); |
| 241 | memcpy(data.data(), &encrypted_tag_data, sizeof(encrypted_tag_data)); | 254 | } |
| 242 | 255 | ||
| 243 | if (!npad_device->WriteNfc(data)) { | 256 | if (!npad_device->WriteNfc(data)) { |
| 244 | LOG_ERROR(Service_NFP, "Error writing to file"); | 257 | LOG_ERROR(Service_NFP, "Error writing to file"); |
| @@ -256,6 +269,13 @@ Result NfpDevice::Mount(MountTarget mount_target_) { | |||
| 256 | return WrongDeviceState; | 269 | return WrongDeviceState; |
| 257 | } | 270 | } |
| 258 | 271 | ||
| 272 | // The loaded amiibo is not encrypted | ||
| 273 | if (is_plain_amiibo) { | ||
| 274 | device_state = DeviceState::TagMounted; | ||
| 275 | mount_target = mount_target_; | ||
| 276 | return ResultSuccess; | ||
| 277 | } | ||
| 278 | |||
| 259 | if (!AmiiboCrypto::IsAmiiboValid(encrypted_tag_data)) { | 279 | if (!AmiiboCrypto::IsAmiiboValid(encrypted_tag_data)) { |
| 260 | LOG_ERROR(Service_NFP, "Not an amiibo"); | 280 | LOG_ERROR(Service_NFP, "Not an amiibo"); |
| 261 | return NotAnAmiibo; | 281 | return NotAnAmiibo; |
diff --git a/src/core/hle/service/nfp/nfp_device.h b/src/core/hle/service/nfp/nfp_device.h index 27122e86e..7f963730d 100644 --- a/src/core/hle/service/nfp/nfp_device.h +++ b/src/core/hle/service/nfp/nfp_device.h | |||
| @@ -95,6 +95,7 @@ private: | |||
| 95 | bool is_initalized{}; | 95 | bool is_initalized{}; |
| 96 | bool is_data_moddified{}; | 96 | bool is_data_moddified{}; |
| 97 | bool is_app_area_open{}; | 97 | bool is_app_area_open{}; |
| 98 | bool is_plain_amiibo{}; | ||
| 98 | TagProtocol allowed_protocols{}; | 99 | TagProtocol allowed_protocols{}; |
| 99 | s64 current_posix_time{}; | 100 | s64 current_posix_time{}; |
| 100 | MountTarget mount_target{MountTarget::None}; | 101 | MountTarget mount_target{MountTarget::None}; |
diff --git a/src/core/hle/service/nfp/nfp_types.h b/src/core/hle/service/nfp/nfp_types.h index b3599a513..70c878552 100644 --- a/src/core/hle/service/nfp/nfp_types.h +++ b/src/core/hle/service/nfp/nfp_types.h | |||
| @@ -309,7 +309,8 @@ struct EncryptedNTAG215File { | |||
| 309 | u32 CFG1; // Defines number of verification attempts | 309 | u32 CFG1; // Defines number of verification attempts |
| 310 | NTAG215Password password; // Password data | 310 | NTAG215Password password; // Password data |
| 311 | }; | 311 | }; |
| 312 | static_assert(sizeof(EncryptedNTAG215File) == 0x21C, "EncryptedNTAG215File is an invalid size"); | 312 | static_assert(sizeof(EncryptedNTAG215File) == sizeof(NTAG215File), |
| 313 | "EncryptedNTAG215File is an invalid size"); | ||
| 313 | static_assert(std::is_trivially_copyable_v<EncryptedNTAG215File>, | 314 | static_assert(std::is_trivially_copyable_v<EncryptedNTAG215File>, |
| 314 | "EncryptedNTAG215File must be trivially copyable."); | 315 | "EncryptedNTAG215File must be trivially copyable."); |
| 315 | 316 | ||
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp index d2308fffc..453a965dc 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp | |||
| @@ -304,8 +304,8 @@ NvResult nvhost_gpu::SubmitGPFIFOBase(std::span<const u8> input, std::vector<u8> | |||
| 304 | Tegra::CommandList entries(params.num_entries); | 304 | Tegra::CommandList entries(params.num_entries); |
| 305 | 305 | ||
| 306 | if (kickoff) { | 306 | if (kickoff) { |
| 307 | system.Memory().ReadBlock(params.address, entries.command_lists.data(), | 307 | system.ApplicationMemory().ReadBlock(params.address, entries.command_lists.data(), |
| 308 | params.num_entries * sizeof(Tegra::CommandListHeader)); | 308 | params.num_entries * sizeof(Tegra::CommandListHeader)); |
| 309 | } else { | 309 | } else { |
| 310 | std::memcpy(entries.command_lists.data(), &input[sizeof(IoctlSubmitGpfifo)], | 310 | std::memcpy(entries.command_lists.data(), &input[sizeof(IoctlSubmitGpfifo)], |
| 311 | params.num_entries * sizeof(Tegra::CommandListHeader)); | 311 | params.num_entries * sizeof(Tegra::CommandListHeader)); |
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp b/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp index 7bcef105b..1ab51f10b 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp | |||
| @@ -105,8 +105,8 @@ NvResult nvhost_nvdec_common::Submit(DeviceFD fd, std::span<const u8> input, | |||
| 105 | const auto object = nvmap.GetHandle(cmd_buffer.memory_id); | 105 | const auto object = nvmap.GetHandle(cmd_buffer.memory_id); |
| 106 | ASSERT_OR_EXECUTE(object, return NvResult::InvalidState;); | 106 | ASSERT_OR_EXECUTE(object, return NvResult::InvalidState;); |
| 107 | Tegra::ChCommandHeaderList cmdlist(cmd_buffer.word_count); | 107 | Tegra::ChCommandHeaderList cmdlist(cmd_buffer.word_count); |
| 108 | system.Memory().ReadBlock(object->address + cmd_buffer.offset, cmdlist.data(), | 108 | system.ApplicationMemory().ReadBlock(object->address + cmd_buffer.offset, cmdlist.data(), |
| 109 | cmdlist.size() * sizeof(u32)); | 109 | cmdlist.size() * sizeof(u32)); |
| 110 | gpu.PushCommandBuffer(core.Host1xDeviceFile().fd_to_id[fd], cmdlist); | 110 | gpu.PushCommandBuffer(core.Host1xDeviceFile().fd_to_id[fd], cmdlist); |
| 111 | } | 111 | } |
| 112 | std::memcpy(output.data(), ¶ms, sizeof(IoctlSubmit)); | 112 | std::memcpy(output.data(), ¶ms, sizeof(IoctlSubmit)); |
diff --git a/src/core/memory.cpp b/src/core/memory.cpp index 95e070825..432310632 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp | |||
| @@ -832,11 +832,6 @@ std::string Memory::ReadCString(Common::ProcessAddress vaddr, std::size_t max_le | |||
| 832 | return impl->ReadCString(vaddr, max_length); | 832 | return impl->ReadCString(vaddr, max_length); |
| 833 | } | 833 | } |
| 834 | 834 | ||
| 835 | void Memory::ReadBlock(const Kernel::KProcess& process, const Common::ProcessAddress src_addr, | ||
| 836 | void* dest_buffer, const std::size_t size) { | ||
| 837 | impl->ReadBlockImpl<false>(process, src_addr, dest_buffer, size); | ||
| 838 | } | ||
| 839 | |||
| 840 | void Memory::ReadBlock(const Common::ProcessAddress src_addr, void* dest_buffer, | 835 | void Memory::ReadBlock(const Common::ProcessAddress src_addr, void* dest_buffer, |
| 841 | const std::size_t size) { | 836 | const std::size_t size) { |
| 842 | impl->ReadBlock(src_addr, dest_buffer, size); | 837 | impl->ReadBlock(src_addr, dest_buffer, size); |
| @@ -847,11 +842,6 @@ void Memory::ReadBlockUnsafe(const Common::ProcessAddress src_addr, void* dest_b | |||
| 847 | impl->ReadBlockUnsafe(src_addr, dest_buffer, size); | 842 | impl->ReadBlockUnsafe(src_addr, dest_buffer, size); |
| 848 | } | 843 | } |
| 849 | 844 | ||
| 850 | void Memory::WriteBlock(const Kernel::KProcess& process, Common::ProcessAddress dest_addr, | ||
| 851 | const void* src_buffer, std::size_t size) { | ||
| 852 | impl->WriteBlockImpl<false>(process, dest_addr, src_buffer, size); | ||
| 853 | } | ||
| 854 | |||
| 855 | void Memory::WriteBlock(const Common::ProcessAddress dest_addr, const void* src_buffer, | 845 | void Memory::WriteBlock(const Common::ProcessAddress dest_addr, const void* src_buffer, |
| 856 | const std::size_t size) { | 846 | const std::size_t size) { |
| 857 | impl->WriteBlock(dest_addr, src_buffer, size); | 847 | impl->WriteBlock(dest_addr, src_buffer, size); |
| @@ -862,29 +852,25 @@ void Memory::WriteBlockUnsafe(const Common::ProcessAddress dest_addr, const void | |||
| 862 | impl->WriteBlockUnsafe(dest_addr, src_buffer, size); | 852 | impl->WriteBlockUnsafe(dest_addr, src_buffer, size); |
| 863 | } | 853 | } |
| 864 | 854 | ||
| 865 | void Memory::CopyBlock(const Kernel::KProcess& process, Common::ProcessAddress dest_addr, | 855 | void Memory::CopyBlock(Common::ProcessAddress dest_addr, Common::ProcessAddress src_addr, |
| 866 | Common::ProcessAddress src_addr, const std::size_t size) { | 856 | const std::size_t size) { |
| 867 | impl->CopyBlock(process, dest_addr, src_addr, size); | 857 | impl->CopyBlock(*system.ApplicationProcess(), dest_addr, src_addr, size); |
| 868 | } | 858 | } |
| 869 | 859 | ||
| 870 | void Memory::ZeroBlock(const Kernel::KProcess& process, Common::ProcessAddress dest_addr, | 860 | void Memory::ZeroBlock(Common::ProcessAddress dest_addr, const std::size_t size) { |
| 871 | const std::size_t size) { | 861 | impl->ZeroBlock(*system.ApplicationProcess(), dest_addr, size); |
| 872 | impl->ZeroBlock(process, dest_addr, size); | ||
| 873 | } | 862 | } |
| 874 | 863 | ||
| 875 | Result Memory::InvalidateDataCache(const Kernel::KProcess& process, | 864 | Result Memory::InvalidateDataCache(Common::ProcessAddress dest_addr, const std::size_t size) { |
| 876 | Common::ProcessAddress dest_addr, const std::size_t size) { | 865 | return impl->InvalidateDataCache(*system.ApplicationProcess(), dest_addr, size); |
| 877 | return impl->InvalidateDataCache(process, dest_addr, size); | ||
| 878 | } | 866 | } |
| 879 | 867 | ||
| 880 | Result Memory::StoreDataCache(const Kernel::KProcess& process, Common::ProcessAddress dest_addr, | 868 | Result Memory::StoreDataCache(Common::ProcessAddress dest_addr, const std::size_t size) { |
| 881 | const std::size_t size) { | 869 | return impl->StoreDataCache(*system.ApplicationProcess(), dest_addr, size); |
| 882 | return impl->StoreDataCache(process, dest_addr, size); | ||
| 883 | } | 870 | } |
| 884 | 871 | ||
| 885 | Result Memory::FlushDataCache(const Kernel::KProcess& process, Common::ProcessAddress dest_addr, | 872 | Result Memory::FlushDataCache(Common::ProcessAddress dest_addr, const std::size_t size) { |
| 886 | const std::size_t size) { | 873 | return impl->FlushDataCache(*system.ApplicationProcess(), dest_addr, size); |
| 887 | return impl->FlushDataCache(process, dest_addr, size); | ||
| 888 | } | 874 | } |
| 889 | 875 | ||
| 890 | void Memory::RasterizerMarkRegionCached(Common::ProcessAddress vaddr, u64 size, bool cached) { | 876 | void Memory::RasterizerMarkRegionCached(Common::ProcessAddress vaddr, u64 size, bool cached) { |
diff --git a/src/core/memory.h b/src/core/memory.h index ed4e87739..72a0be813 100644 --- a/src/core/memory.h +++ b/src/core/memory.h | |||
| @@ -305,26 +305,6 @@ public: | |||
| 305 | std::string ReadCString(Common::ProcessAddress vaddr, std::size_t max_length); | 305 | std::string ReadCString(Common::ProcessAddress vaddr, std::size_t max_length); |
| 306 | 306 | ||
| 307 | /** | 307 | /** |
| 308 | * Reads a contiguous block of bytes from a specified process' address space. | ||
| 309 | * | ||
| 310 | * @param process The process to read the data from. | ||
| 311 | * @param src_addr The virtual address to begin reading from. | ||
| 312 | * @param dest_buffer The buffer to place the read bytes into. | ||
| 313 | * @param size The amount of data to read, in bytes. | ||
| 314 | * | ||
| 315 | * @note If a size of 0 is specified, then this function reads nothing and | ||
| 316 | * no attempts to access memory are made at all. | ||
| 317 | * | ||
| 318 | * @pre dest_buffer must be at least size bytes in length, otherwise a | ||
| 319 | * buffer overrun will occur. | ||
| 320 | * | ||
| 321 | * @post The range [dest_buffer, size) contains the read bytes from the | ||
| 322 | * process' address space. | ||
| 323 | */ | ||
| 324 | void ReadBlock(const Kernel::KProcess& process, Common::ProcessAddress src_addr, | ||
| 325 | void* dest_buffer, std::size_t size); | ||
| 326 | |||
| 327 | /** | ||
| 328 | * Reads a contiguous block of bytes from the current process' address space. | 308 | * Reads a contiguous block of bytes from the current process' address space. |
| 329 | * | 309 | * |
| 330 | * @param src_addr The virtual address to begin reading from. | 310 | * @param src_addr The virtual address to begin reading from. |
| @@ -362,29 +342,6 @@ public: | |||
| 362 | void ReadBlockUnsafe(Common::ProcessAddress src_addr, void* dest_buffer, std::size_t size); | 342 | void ReadBlockUnsafe(Common::ProcessAddress src_addr, void* dest_buffer, std::size_t size); |
| 363 | 343 | ||
| 364 | /** | 344 | /** |
| 365 | * Writes a range of bytes into a given process' address space at the specified | ||
| 366 | * virtual address. | ||
| 367 | * | ||
| 368 | * @param process The process to write data into the address space of. | ||
| 369 | * @param dest_addr The destination virtual address to begin writing the data at. | ||
| 370 | * @param src_buffer The data to write into the process' address space. | ||
| 371 | * @param size The size of the data to write, in bytes. | ||
| 372 | * | ||
| 373 | * @post The address range [dest_addr, size) in the process' address space | ||
| 374 | * contains the data that was within src_buffer. | ||
| 375 | * | ||
| 376 | * @post If an attempt is made to write into an unmapped region of memory, the writes | ||
| 377 | * will be ignored and an error will be logged. | ||
| 378 | * | ||
| 379 | * @post If a write is performed into a region of memory that is considered cached | ||
| 380 | * rasterizer memory, will cause the currently active rasterizer to be notified | ||
| 381 | * and will mark that region as invalidated to caches that the active | ||
| 382 | * graphics backend may be maintaining over the course of execution. | ||
| 383 | */ | ||
| 384 | void WriteBlock(const Kernel::KProcess& process, Common::ProcessAddress dest_addr, | ||
| 385 | const void* src_buffer, std::size_t size); | ||
| 386 | |||
| 387 | /** | ||
| 388 | * Writes a range of bytes into the current process' address space at the specified | 345 | * Writes a range of bytes into the current process' address space at the specified |
| 389 | * virtual address. | 346 | * virtual address. |
| 390 | * | 347 | * |
| @@ -428,7 +385,6 @@ public: | |||
| 428 | * Copies data within a process' address space to another location within the | 385 | * Copies data within a process' address space to another location within the |
| 429 | * same address space. | 386 | * same address space. |
| 430 | * | 387 | * |
| 431 | * @param process The process that will have data copied within its address space. | ||
| 432 | * @param dest_addr The destination virtual address to begin copying the data into. | 388 | * @param dest_addr The destination virtual address to begin copying the data into. |
| 433 | * @param src_addr The source virtual address to begin copying the data from. | 389 | * @param src_addr The source virtual address to begin copying the data from. |
| 434 | * @param size The size of the data to copy, in bytes. | 390 | * @param size The size of the data to copy, in bytes. |
| @@ -436,58 +392,50 @@ public: | |||
| 436 | * @post The range [dest_addr, size) within the process' address space contains the | 392 | * @post The range [dest_addr, size) within the process' address space contains the |
| 437 | * same data within the range [src_addr, size). | 393 | * same data within the range [src_addr, size). |
| 438 | */ | 394 | */ |
| 439 | void CopyBlock(const Kernel::KProcess& process, Common::ProcessAddress dest_addr, | 395 | void CopyBlock(Common::ProcessAddress dest_addr, Common::ProcessAddress src_addr, |
| 440 | Common::ProcessAddress src_addr, std::size_t size); | 396 | std::size_t size); |
| 441 | 397 | ||
| 442 | /** | 398 | /** |
| 443 | * Zeros a range of bytes within the current process' address space at the specified | 399 | * Zeros a range of bytes within the current process' address space at the specified |
| 444 | * virtual address. | 400 | * virtual address. |
| 445 | * | 401 | * |
| 446 | * @param process The process that will have data zeroed within its address space. | ||
| 447 | * @param dest_addr The destination virtual address to zero the data from. | 402 | * @param dest_addr The destination virtual address to zero the data from. |
| 448 | * @param size The size of the range to zero out, in bytes. | 403 | * @param size The size of the range to zero out, in bytes. |
| 449 | * | 404 | * |
| 450 | * @post The range [dest_addr, size) within the process' address space contains the | 405 | * @post The range [dest_addr, size) within the process' address space contains the |
| 451 | * value 0. | 406 | * value 0. |
| 452 | */ | 407 | */ |
| 453 | void ZeroBlock(const Kernel::KProcess& process, Common::ProcessAddress dest_addr, | 408 | void ZeroBlock(Common::ProcessAddress dest_addr, std::size_t size); |
| 454 | std::size_t size); | ||
| 455 | 409 | ||
| 456 | /** | 410 | /** |
| 457 | * Invalidates a range of bytes within the current process' address space at the specified | 411 | * Invalidates a range of bytes within the current process' address space at the specified |
| 458 | * virtual address. | 412 | * virtual address. |
| 459 | * | 413 | * |
| 460 | * @param process The process that will have data invalidated within its address space. | ||
| 461 | * @param dest_addr The destination virtual address to invalidate the data from. | 414 | * @param dest_addr The destination virtual address to invalidate the data from. |
| 462 | * @param size The size of the range to invalidate, in bytes. | 415 | * @param size The size of the range to invalidate, in bytes. |
| 463 | * | 416 | * |
| 464 | */ | 417 | */ |
| 465 | Result InvalidateDataCache(const Kernel::KProcess& process, Common::ProcessAddress dest_addr, | 418 | Result InvalidateDataCache(Common::ProcessAddress dest_addr, std::size_t size); |
| 466 | std::size_t size); | ||
| 467 | 419 | ||
| 468 | /** | 420 | /** |
| 469 | * Stores a range of bytes within the current process' address space at the specified | 421 | * Stores a range of bytes within the current process' address space at the specified |
| 470 | * virtual address. | 422 | * virtual address. |
| 471 | * | 423 | * |
| 472 | * @param process The process that will have data stored within its address space. | ||
| 473 | * @param dest_addr The destination virtual address to store the data from. | 424 | * @param dest_addr The destination virtual address to store the data from. |
| 474 | * @param size The size of the range to store, in bytes. | 425 | * @param size The size of the range to store, in bytes. |
| 475 | * | 426 | * |
| 476 | */ | 427 | */ |
| 477 | Result StoreDataCache(const Kernel::KProcess& process, Common::ProcessAddress dest_addr, | 428 | Result StoreDataCache(Common::ProcessAddress dest_addr, std::size_t size); |
| 478 | std::size_t size); | ||
| 479 | 429 | ||
| 480 | /** | 430 | /** |
| 481 | * Flushes a range of bytes within the current process' address space at the specified | 431 | * Flushes a range of bytes within the current process' address space at the specified |
| 482 | * virtual address. | 432 | * virtual address. |
| 483 | * | 433 | * |
| 484 | * @param process The process that will have data flushed within its address space. | ||
| 485 | * @param dest_addr The destination virtual address to flush the data from. | 434 | * @param dest_addr The destination virtual address to flush the data from. |
| 486 | * @param size The size of the range to flush, in bytes. | 435 | * @param size The size of the range to flush, in bytes. |
| 487 | * | 436 | * |
| 488 | */ | 437 | */ |
| 489 | Result FlushDataCache(const Kernel::KProcess& process, Common::ProcessAddress dest_addr, | 438 | Result FlushDataCache(Common::ProcessAddress dest_addr, std::size_t size); |
| 490 | std::size_t size); | ||
| 491 | 439 | ||
| 492 | /** | 440 | /** |
| 493 | * Marks each page within the specified address range as cached or uncached. | 441 | * Marks each page within the specified address range as cached or uncached. |
diff --git a/src/core/memory/cheat_engine.cpp b/src/core/memory/cheat_engine.cpp index d1284a3a7..8742dd164 100644 --- a/src/core/memory/cheat_engine.cpp +++ b/src/core/memory/cheat_engine.cpp | |||
| @@ -39,11 +39,11 @@ StandardVmCallbacks::StandardVmCallbacks(System& system_, const CheatProcessMeta | |||
| 39 | StandardVmCallbacks::~StandardVmCallbacks() = default; | 39 | StandardVmCallbacks::~StandardVmCallbacks() = default; |
| 40 | 40 | ||
| 41 | void StandardVmCallbacks::MemoryRead(VAddr address, void* data, u64 size) { | 41 | void StandardVmCallbacks::MemoryRead(VAddr address, void* data, u64 size) { |
| 42 | system.Memory().ReadBlock(SanitizeAddress(address), data, size); | 42 | system.ApplicationMemory().ReadBlock(SanitizeAddress(address), data, size); |
| 43 | } | 43 | } |
| 44 | 44 | ||
| 45 | void StandardVmCallbacks::MemoryWrite(VAddr address, const void* data, u64 size) { | 45 | void StandardVmCallbacks::MemoryWrite(VAddr address, const void* data, u64 size) { |
| 46 | system.Memory().WriteBlock(SanitizeAddress(address), data, size); | 46 | system.ApplicationMemory().WriteBlock(SanitizeAddress(address), data, size); |
| 47 | } | 47 | } |
| 48 | 48 | ||
| 49 | u64 StandardVmCallbacks::HidKeysDown() { | 49 | u64 StandardVmCallbacks::HidKeysDown() { |
diff --git a/src/core/reporter.cpp b/src/core/reporter.cpp index 146c3f21e..6c3dc7369 100644 --- a/src/core/reporter.cpp +++ b/src/core/reporter.cpp | |||
| @@ -264,7 +264,7 @@ void Reporter::SaveUnimplementedFunctionReport(Service::HLERequestContext& ctx, | |||
| 264 | const auto title_id = system.GetApplicationProcessProgramID(); | 264 | const auto title_id = system.GetApplicationProcessProgramID(); |
| 265 | auto out = GetFullDataAuto(timestamp, title_id, system); | 265 | auto out = GetFullDataAuto(timestamp, title_id, system); |
| 266 | 266 | ||
| 267 | auto function_out = GetHLERequestContextData(ctx, system.Memory()); | 267 | auto function_out = GetHLERequestContextData(ctx, system.ApplicationMemory()); |
| 268 | function_out["command_id"] = command_id; | 268 | function_out["command_id"] = command_id; |
| 269 | function_out["function_name"] = name; | 269 | function_out["function_name"] = name; |
| 270 | function_out["service_name"] = service_name; | 270 | function_out["service_name"] = service_name; |
diff --git a/src/tests/common/range_map.cpp b/src/tests/common/range_map.cpp index d301ac5f6..faaefd49f 100644 --- a/src/tests/common/range_map.cpp +++ b/src/tests/common/range_map.cpp | |||
| @@ -21,9 +21,9 @@ TEST_CASE("Range Map: Setup", "[video_core]") { | |||
| 21 | my_map.Map(4000, 4500, MappedEnum::Valid_2); | 21 | my_map.Map(4000, 4500, MappedEnum::Valid_2); |
| 22 | my_map.Map(4200, 4400, MappedEnum::Valid_2); | 22 | my_map.Map(4200, 4400, MappedEnum::Valid_2); |
| 23 | my_map.Map(4200, 4400, MappedEnum::Valid_1); | 23 | my_map.Map(4200, 4400, MappedEnum::Valid_1); |
| 24 | REQUIRE(my_map.GetContinousSizeFrom(4200) == 200); | 24 | REQUIRE(my_map.GetContinuousSizeFrom(4200) == 200); |
| 25 | REQUIRE(my_map.GetContinousSizeFrom(3000) == 200); | 25 | REQUIRE(my_map.GetContinuousSizeFrom(3000) == 200); |
| 26 | REQUIRE(my_map.GetContinousSizeFrom(2900) == 0); | 26 | REQUIRE(my_map.GetContinuousSizeFrom(2900) == 0); |
| 27 | 27 | ||
| 28 | REQUIRE(my_map.GetValueAt(2900) == MappedEnum::Invalid); | 28 | REQUIRE(my_map.GetValueAt(2900) == MappedEnum::Invalid); |
| 29 | REQUIRE(my_map.GetValueAt(3100) == MappedEnum::Valid_1); | 29 | REQUIRE(my_map.GetValueAt(3100) == MappedEnum::Valid_1); |
| @@ -38,20 +38,20 @@ TEST_CASE("Range Map: Setup", "[video_core]") { | |||
| 38 | 38 | ||
| 39 | my_map.Unmap(0, 6000); | 39 | my_map.Unmap(0, 6000); |
| 40 | for (u64 address = 0; address < 10000; address += 1000) { | 40 | for (u64 address = 0; address < 10000; address += 1000) { |
| 41 | REQUIRE(my_map.GetContinousSizeFrom(address) == 0); | 41 | REQUIRE(my_map.GetContinuousSizeFrom(address) == 0); |
| 42 | } | 42 | } |
| 43 | 43 | ||
| 44 | my_map.Map(1000, 3000, MappedEnum::Valid_1); | 44 | my_map.Map(1000, 3000, MappedEnum::Valid_1); |
| 45 | my_map.Map(4000, 5000, MappedEnum::Valid_1); | 45 | my_map.Map(4000, 5000, MappedEnum::Valid_1); |
| 46 | my_map.Map(2500, 4100, MappedEnum::Valid_1); | 46 | my_map.Map(2500, 4100, MappedEnum::Valid_1); |
| 47 | REQUIRE(my_map.GetContinousSizeFrom(1000) == 4000); | 47 | REQUIRE(my_map.GetContinuousSizeFrom(1000) == 4000); |
| 48 | 48 | ||
| 49 | my_map.Map(1000, 3000, MappedEnum::Valid_1); | 49 | my_map.Map(1000, 3000, MappedEnum::Valid_1); |
| 50 | my_map.Map(4000, 5000, MappedEnum::Valid_2); | 50 | my_map.Map(4000, 5000, MappedEnum::Valid_2); |
| 51 | my_map.Map(2500, 4100, MappedEnum::Valid_3); | 51 | my_map.Map(2500, 4100, MappedEnum::Valid_3); |
| 52 | REQUIRE(my_map.GetContinousSizeFrom(1000) == 1500); | 52 | REQUIRE(my_map.GetContinuousSizeFrom(1000) == 1500); |
| 53 | REQUIRE(my_map.GetContinousSizeFrom(2500) == 1600); | 53 | REQUIRE(my_map.GetContinuousSizeFrom(2500) == 1600); |
| 54 | REQUIRE(my_map.GetContinousSizeFrom(4100) == 900); | 54 | REQUIRE(my_map.GetContinuousSizeFrom(4100) == 900); |
| 55 | REQUIRE(my_map.GetValueAt(900) == MappedEnum::Invalid); | 55 | REQUIRE(my_map.GetValueAt(900) == MappedEnum::Invalid); |
| 56 | REQUIRE(my_map.GetValueAt(1000) == MappedEnum::Valid_1); | 56 | REQUIRE(my_map.GetValueAt(1000) == MappedEnum::Valid_1); |
| 57 | REQUIRE(my_map.GetValueAt(2500) == MappedEnum::Valid_3); | 57 | REQUIRE(my_map.GetValueAt(2500) == MappedEnum::Valid_3); |
| @@ -59,8 +59,8 @@ TEST_CASE("Range Map: Setup", "[video_core]") { | |||
| 59 | REQUIRE(my_map.GetValueAt(5000) == MappedEnum::Invalid); | 59 | REQUIRE(my_map.GetValueAt(5000) == MappedEnum::Invalid); |
| 60 | 60 | ||
| 61 | my_map.Map(2000, 6000, MappedEnum::Valid_3); | 61 | my_map.Map(2000, 6000, MappedEnum::Valid_3); |
| 62 | REQUIRE(my_map.GetContinousSizeFrom(1000) == 1000); | 62 | REQUIRE(my_map.GetContinuousSizeFrom(1000) == 1000); |
| 63 | REQUIRE(my_map.GetContinousSizeFrom(3000) == 3000); | 63 | REQUIRE(my_map.GetContinuousSizeFrom(3000) == 3000); |
| 64 | REQUIRE(my_map.GetValueAt(1000) == MappedEnum::Valid_1); | 64 | REQUIRE(my_map.GetValueAt(1000) == MappedEnum::Valid_1); |
| 65 | REQUIRE(my_map.GetValueAt(1999) == MappedEnum::Valid_1); | 65 | REQUIRE(my_map.GetValueAt(1999) == MappedEnum::Valid_1); |
| 66 | REQUIRE(my_map.GetValueAt(1500) == MappedEnum::Valid_1); | 66 | REQUIRE(my_map.GetValueAt(1500) == MappedEnum::Valid_1); |
diff --git a/src/video_core/buffer_cache/buffer_cache.h b/src/video_core/buffer_cache/buffer_cache.h index 1f656ffa8..abdc593df 100644 --- a/src/video_core/buffer_cache/buffer_cache.h +++ b/src/video_core/buffer_cache/buffer_cache.h | |||
| @@ -1442,7 +1442,7 @@ void BufferCache<P>::UpdateVertexBuffer(u32 index) { | |||
| 1442 | } | 1442 | } |
| 1443 | if (!gpu_memory->IsWithinGPUAddressRange(gpu_addr_end)) { | 1443 | if (!gpu_memory->IsWithinGPUAddressRange(gpu_addr_end)) { |
| 1444 | address_size = | 1444 | address_size = |
| 1445 | static_cast<u32>(gpu_memory->MaxContinousRange(gpu_addr_begin, address_size)); | 1445 | static_cast<u32>(gpu_memory->MaxContinuousRange(gpu_addr_begin, address_size)); |
| 1446 | } | 1446 | } |
| 1447 | const u32 size = address_size; // TODO: Analyze stride and number of vertices | 1447 | const u32 size = address_size; // TODO: Analyze stride and number of vertices |
| 1448 | vertex_buffers[index] = Binding{ | 1448 | vertex_buffers[index] = Binding{ |
diff --git a/src/video_core/memory_manager.cpp b/src/video_core/memory_manager.cpp index 83924475b..01fb5b546 100644 --- a/src/video_core/memory_manager.cpp +++ b/src/video_core/memory_manager.cpp | |||
| @@ -22,7 +22,7 @@ std::atomic<size_t> MemoryManager::unique_identifier_generator{}; | |||
| 22 | 22 | ||
| 23 | MemoryManager::MemoryManager(Core::System& system_, u64 address_space_bits_, u64 big_page_bits_, | 23 | MemoryManager::MemoryManager(Core::System& system_, u64 address_space_bits_, u64 big_page_bits_, |
| 24 | u64 page_bits_) | 24 | u64 page_bits_) |
| 25 | : system{system_}, memory{system.Memory()}, device_memory{system.DeviceMemory()}, | 25 | : system{system_}, memory{system.ApplicationMemory()}, device_memory{system.DeviceMemory()}, |
| 26 | address_space_bits{address_space_bits_}, page_bits{page_bits_}, big_page_bits{big_page_bits_}, | 26 | address_space_bits{address_space_bits_}, page_bits{page_bits_}, big_page_bits{big_page_bits_}, |
| 27 | entries{}, big_entries{}, page_table{address_space_bits, address_space_bits + page_bits - 38, | 27 | entries{}, big_entries{}, page_table{address_space_bits, address_space_bits + page_bits - 38, |
| 28 | page_bits != big_page_bits ? page_bits : 0}, | 28 | page_bits != big_page_bits ? page_bits : 0}, |
| @@ -43,7 +43,7 @@ MemoryManager::MemoryManager(Core::System& system_, u64 address_space_bits_, u64 | |||
| 43 | 43 | ||
| 44 | big_entries.resize(big_page_table_size / 32, 0); | 44 | big_entries.resize(big_page_table_size / 32, 0); |
| 45 | big_page_table_cpu.resize(big_page_table_size); | 45 | big_page_table_cpu.resize(big_page_table_size); |
| 46 | big_page_continous.resize(big_page_table_size / continous_bits, 0); | 46 | big_page_continuous.resize(big_page_table_size / continuous_bits, 0); |
| 47 | entries.resize(page_table_size / 32, 0); | 47 | entries.resize(page_table_size / 32, 0); |
| 48 | } | 48 | } |
| 49 | 49 | ||
| @@ -85,17 +85,17 @@ PTEKind MemoryManager::GetPageKind(GPUVAddr gpu_addr) const { | |||
| 85 | return kind_map.GetValueAt(gpu_addr); | 85 | return kind_map.GetValueAt(gpu_addr); |
| 86 | } | 86 | } |
| 87 | 87 | ||
| 88 | inline bool MemoryManager::IsBigPageContinous(size_t big_page_index) const { | 88 | inline bool MemoryManager::IsBigPageContinuous(size_t big_page_index) const { |
| 89 | const u64 entry_mask = big_page_continous[big_page_index / continous_bits]; | 89 | const u64 entry_mask = big_page_continuous[big_page_index / continuous_bits]; |
| 90 | const size_t sub_index = big_page_index % continous_bits; | 90 | const size_t sub_index = big_page_index % continuous_bits; |
| 91 | return ((entry_mask >> sub_index) & 0x1ULL) != 0; | 91 | return ((entry_mask >> sub_index) & 0x1ULL) != 0; |
| 92 | } | 92 | } |
| 93 | 93 | ||
| 94 | inline void MemoryManager::SetBigPageContinous(size_t big_page_index, bool value) { | 94 | inline void MemoryManager::SetBigPageContinuous(size_t big_page_index, bool value) { |
| 95 | const u64 continous_mask = big_page_continous[big_page_index / continous_bits]; | 95 | const u64 continuous_mask = big_page_continuous[big_page_index / continuous_bits]; |
| 96 | const size_t sub_index = big_page_index % continous_bits; | 96 | const size_t sub_index = big_page_index % continuous_bits; |
| 97 | big_page_continous[big_page_index / continous_bits] = | 97 | big_page_continuous[big_page_index / continuous_bits] = |
| 98 | (~(1ULL << sub_index) & continous_mask) | (value ? 1ULL << sub_index : 0); | 98 | (~(1ULL << sub_index) & continuous_mask) | (value ? 1ULL << sub_index : 0); |
| 99 | } | 99 | } |
| 100 | 100 | ||
| 101 | template <MemoryManager::EntryType entry_type> | 101 | template <MemoryManager::EntryType entry_type> |
| @@ -140,7 +140,7 @@ GPUVAddr MemoryManager::BigPageTableOp(GPUVAddr gpu_addr, [[maybe_unused]] VAddr | |||
| 140 | const auto index = PageEntryIndex<true>(current_gpu_addr); | 140 | const auto index = PageEntryIndex<true>(current_gpu_addr); |
| 141 | const u32 sub_value = static_cast<u32>(current_cpu_addr >> cpu_page_bits); | 141 | const u32 sub_value = static_cast<u32>(current_cpu_addr >> cpu_page_bits); |
| 142 | big_page_table_cpu[index] = sub_value; | 142 | big_page_table_cpu[index] = sub_value; |
| 143 | const bool is_continous = ([&] { | 143 | const bool is_continuous = ([&] { |
| 144 | uintptr_t base_ptr{ | 144 | uintptr_t base_ptr{ |
| 145 | reinterpret_cast<uintptr_t>(memory.GetPointerSilent(current_cpu_addr))}; | 145 | reinterpret_cast<uintptr_t>(memory.GetPointerSilent(current_cpu_addr))}; |
| 146 | if (base_ptr == 0) { | 146 | if (base_ptr == 0) { |
| @@ -156,7 +156,7 @@ GPUVAddr MemoryManager::BigPageTableOp(GPUVAddr gpu_addr, [[maybe_unused]] VAddr | |||
| 156 | } | 156 | } |
| 157 | return true; | 157 | return true; |
| 158 | })(); | 158 | })(); |
| 159 | SetBigPageContinous(index, is_continous); | 159 | SetBigPageContinuous(index, is_continuous); |
| 160 | } | 160 | } |
| 161 | remaining_size -= big_page_size; | 161 | remaining_size -= big_page_size; |
| 162 | } | 162 | } |
| @@ -378,7 +378,7 @@ void MemoryManager::ReadBlockImpl(GPUVAddr gpu_src_addr, void* dest_buffer, std: | |||
| 378 | if constexpr (is_safe) { | 378 | if constexpr (is_safe) { |
| 379 | rasterizer->FlushRegion(cpu_addr_base, copy_amount, which); | 379 | rasterizer->FlushRegion(cpu_addr_base, copy_amount, which); |
| 380 | } | 380 | } |
| 381 | if (!IsBigPageContinous(page_index)) [[unlikely]] { | 381 | if (!IsBigPageContinuous(page_index)) [[unlikely]] { |
| 382 | memory.ReadBlockUnsafe(cpu_addr_base, dest_buffer, copy_amount); | 382 | memory.ReadBlockUnsafe(cpu_addr_base, dest_buffer, copy_amount); |
| 383 | } else { | 383 | } else { |
| 384 | u8* physical = memory.GetPointer(cpu_addr_base); | 384 | u8* physical = memory.GetPointer(cpu_addr_base); |
| @@ -427,7 +427,7 @@ void MemoryManager::WriteBlockImpl(GPUVAddr gpu_dest_addr, const void* src_buffe | |||
| 427 | if constexpr (is_safe) { | 427 | if constexpr (is_safe) { |
| 428 | rasterizer->InvalidateRegion(cpu_addr_base, copy_amount, which); | 428 | rasterizer->InvalidateRegion(cpu_addr_base, copy_amount, which); |
| 429 | } | 429 | } |
| 430 | if (!IsBigPageContinous(page_index)) [[unlikely]] { | 430 | if (!IsBigPageContinuous(page_index)) [[unlikely]] { |
| 431 | memory.WriteBlockUnsafe(cpu_addr_base, src_buffer, copy_amount); | 431 | memory.WriteBlockUnsafe(cpu_addr_base, src_buffer, copy_amount); |
| 432 | } else { | 432 | } else { |
| 433 | u8* physical = memory.GetPointer(cpu_addr_base); | 433 | u8* physical = memory.GetPointer(cpu_addr_base); |
| @@ -512,7 +512,7 @@ bool MemoryManager::IsMemoryDirty(GPUVAddr gpu_addr, size_t size, | |||
| 512 | return result; | 512 | return result; |
| 513 | } | 513 | } |
| 514 | 514 | ||
| 515 | size_t MemoryManager::MaxContinousRange(GPUVAddr gpu_addr, size_t size) const { | 515 | size_t MemoryManager::MaxContinuousRange(GPUVAddr gpu_addr, size_t size) const { |
| 516 | std::optional<VAddr> old_page_addr{}; | 516 | std::optional<VAddr> old_page_addr{}; |
| 517 | size_t range_so_far = 0; | 517 | size_t range_so_far = 0; |
| 518 | bool result{false}; | 518 | bool result{false}; |
| @@ -553,7 +553,7 @@ size_t MemoryManager::MaxContinousRange(GPUVAddr gpu_addr, size_t size) const { | |||
| 553 | } | 553 | } |
| 554 | 554 | ||
| 555 | size_t MemoryManager::GetMemoryLayoutSize(GPUVAddr gpu_addr, size_t max_size) const { | 555 | size_t MemoryManager::GetMemoryLayoutSize(GPUVAddr gpu_addr, size_t max_size) const { |
| 556 | return kind_map.GetContinousSizeFrom(gpu_addr); | 556 | return kind_map.GetContinuousSizeFrom(gpu_addr); |
| 557 | } | 557 | } |
| 558 | 558 | ||
| 559 | void MemoryManager::InvalidateRegion(GPUVAddr gpu_addr, size_t size, | 559 | void MemoryManager::InvalidateRegion(GPUVAddr gpu_addr, size_t size, |
| @@ -594,7 +594,7 @@ void MemoryManager::CopyBlock(GPUVAddr gpu_dest_addr, GPUVAddr gpu_src_addr, std | |||
| 594 | bool MemoryManager::IsGranularRange(GPUVAddr gpu_addr, std::size_t size) const { | 594 | bool MemoryManager::IsGranularRange(GPUVAddr gpu_addr, std::size_t size) const { |
| 595 | if (GetEntry<true>(gpu_addr) == EntryType::Mapped) [[likely]] { | 595 | if (GetEntry<true>(gpu_addr) == EntryType::Mapped) [[likely]] { |
| 596 | size_t page_index = gpu_addr >> big_page_bits; | 596 | size_t page_index = gpu_addr >> big_page_bits; |
| 597 | if (IsBigPageContinous(page_index)) [[likely]] { | 597 | if (IsBigPageContinuous(page_index)) [[likely]] { |
| 598 | const std::size_t page{(page_index & big_page_mask) + size}; | 598 | const std::size_t page{(page_index & big_page_mask) + size}; |
| 599 | return page <= big_page_size; | 599 | return page <= big_page_size; |
| 600 | } | 600 | } |
| @@ -608,7 +608,7 @@ bool MemoryManager::IsGranularRange(GPUVAddr gpu_addr, std::size_t size) const { | |||
| 608 | return page <= Core::Memory::YUZU_PAGESIZE; | 608 | return page <= Core::Memory::YUZU_PAGESIZE; |
| 609 | } | 609 | } |
| 610 | 610 | ||
| 611 | bool MemoryManager::IsContinousRange(GPUVAddr gpu_addr, std::size_t size) const { | 611 | bool MemoryManager::IsContinuousRange(GPUVAddr gpu_addr, std::size_t size) const { |
| 612 | std::optional<VAddr> old_page_addr{}; | 612 | std::optional<VAddr> old_page_addr{}; |
| 613 | bool result{true}; | 613 | bool result{true}; |
| 614 | auto fail = [&]([[maybe_unused]] std::size_t page_index, [[maybe_unused]] std::size_t offset, | 614 | auto fail = [&]([[maybe_unused]] std::size_t page_index, [[maybe_unused]] std::size_t offset, |
diff --git a/src/video_core/memory_manager.h b/src/video_core/memory_manager.h index 51ae2de68..fbbe856c4 100644 --- a/src/video_core/memory_manager.h +++ b/src/video_core/memory_manager.h | |||
| @@ -94,7 +94,7 @@ public: | |||
| 94 | /** | 94 | /** |
| 95 | * Checks if a gpu region is mapped by a single range of cpu addresses. | 95 | * Checks if a gpu region is mapped by a single range of cpu addresses. |
| 96 | */ | 96 | */ |
| 97 | [[nodiscard]] bool IsContinousRange(GPUVAddr gpu_addr, std::size_t size) const; | 97 | [[nodiscard]] bool IsContinuousRange(GPUVAddr gpu_addr, std::size_t size) const; |
| 98 | 98 | ||
| 99 | /** | 99 | /** |
| 100 | * Checks if a gpu region is mapped entirely. | 100 | * Checks if a gpu region is mapped entirely. |
| @@ -123,7 +123,7 @@ public: | |||
| 123 | bool IsMemoryDirty(GPUVAddr gpu_addr, size_t size, | 123 | bool IsMemoryDirty(GPUVAddr gpu_addr, size_t size, |
| 124 | VideoCommon::CacheType which = VideoCommon::CacheType::All) const; | 124 | VideoCommon::CacheType which = VideoCommon::CacheType::All) const; |
| 125 | 125 | ||
| 126 | size_t MaxContinousRange(GPUVAddr gpu_addr, size_t size) const; | 126 | size_t MaxContinuousRange(GPUVAddr gpu_addr, size_t size) const; |
| 127 | 127 | ||
| 128 | bool IsWithinGPUAddressRange(GPUVAddr gpu_addr) const { | 128 | bool IsWithinGPUAddressRange(GPUVAddr gpu_addr) const { |
| 129 | return gpu_addr < address_space_size; | 129 | return gpu_addr < address_space_size; |
| @@ -158,8 +158,8 @@ private: | |||
| 158 | } | 158 | } |
| 159 | } | 159 | } |
| 160 | 160 | ||
| 161 | inline bool IsBigPageContinous(size_t big_page_index) const; | 161 | inline bool IsBigPageContinuous(size_t big_page_index) const; |
| 162 | inline void SetBigPageContinous(size_t big_page_index, bool value); | 162 | inline void SetBigPageContinuous(size_t big_page_index, bool value); |
| 163 | 163 | ||
| 164 | template <bool is_gpu_address> | 164 | template <bool is_gpu_address> |
| 165 | void GetSubmappedRangeImpl( | 165 | void GetSubmappedRangeImpl( |
| @@ -213,10 +213,10 @@ private: | |||
| 213 | Common::RangeMap<GPUVAddr, PTEKind> kind_map; | 213 | Common::RangeMap<GPUVAddr, PTEKind> kind_map; |
| 214 | Common::VirtualBuffer<u32> big_page_table_cpu; | 214 | Common::VirtualBuffer<u32> big_page_table_cpu; |
| 215 | 215 | ||
| 216 | std::vector<u64> big_page_continous; | 216 | std::vector<u64> big_page_continuous; |
| 217 | std::vector<std::pair<VAddr, std::size_t>> page_stash{}; | 217 | std::vector<std::pair<VAddr, std::size_t>> page_stash{}; |
| 218 | 218 | ||
| 219 | static constexpr size_t continous_bits = 64; | 219 | static constexpr size_t continuous_bits = 64; |
| 220 | 220 | ||
| 221 | const size_t unique_identifier; | 221 | const size_t unique_identifier; |
| 222 | std::unique_ptr<VideoCommon::InvalidationAccumulator> accumulator; | 222 | std::unique_ptr<VideoCommon::InvalidationAccumulator> accumulator; |
diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h index 858449af8..63821d496 100644 --- a/src/video_core/texture_cache/texture_cache.h +++ b/src/video_core/texture_cache/texture_cache.h | |||
| @@ -1269,7 +1269,7 @@ ImageId TextureCache<P>::JoinImages(const ImageInfo& info, GPUVAddr gpu_addr, VA | |||
| 1269 | const ImageId new_image_id = slot_images.insert(runtime, new_info, gpu_addr, cpu_addr); | 1269 | const ImageId new_image_id = slot_images.insert(runtime, new_info, gpu_addr, cpu_addr); |
| 1270 | Image& new_image = slot_images[new_image_id]; | 1270 | Image& new_image = slot_images[new_image_id]; |
| 1271 | 1271 | ||
| 1272 | if (!gpu_memory->IsContinousRange(new_image.gpu_addr, new_image.guest_size_bytes)) { | 1272 | if (!gpu_memory->IsContinuousRange(new_image.gpu_addr, new_image.guest_size_bytes)) { |
| 1273 | new_image.flags |= ImageFlagBits::Sparse; | 1273 | new_image.flags |= ImageFlagBits::Sparse; |
| 1274 | } | 1274 | } |
| 1275 | 1275 | ||
diff --git a/src/video_core/video_core.cpp b/src/video_core/video_core.cpp index fedb4a7bb..b42d48416 100644 --- a/src/video_core/video_core.cpp +++ b/src/video_core/video_core.cpp | |||
| @@ -18,7 +18,7 @@ std::unique_ptr<VideoCore::RendererBase> CreateRenderer( | |||
| 18 | Core::System& system, Core::Frontend::EmuWindow& emu_window, Tegra::GPU& gpu, | 18 | Core::System& system, Core::Frontend::EmuWindow& emu_window, Tegra::GPU& gpu, |
| 19 | std::unique_ptr<Core::Frontend::GraphicsContext> context) { | 19 | std::unique_ptr<Core::Frontend::GraphicsContext> context) { |
| 20 | auto& telemetry_session = system.TelemetrySession(); | 20 | auto& telemetry_session = system.TelemetrySession(); |
| 21 | auto& cpu_memory = system.Memory(); | 21 | auto& cpu_memory = system.ApplicationMemory(); |
| 22 | 22 | ||
| 23 | switch (Settings::values.renderer_backend.GetValue()) { | 23 | switch (Settings::values.renderer_backend.GetValue()) { |
| 24 | case Settings::RendererBackend::OpenGL: | 24 | case Settings::RendererBackend::OpenGL: |
diff --git a/src/video_core/vulkan_common/vulkan_wrapper.cpp b/src/video_core/vulkan_common/vulkan_wrapper.cpp index 486d4dfaf..336f53700 100644 --- a/src/video_core/vulkan_common/vulkan_wrapper.cpp +++ b/src/video_core/vulkan_common/vulkan_wrapper.cpp | |||
| @@ -375,6 +375,8 @@ const char* ToString(VkResult result) noexcept { | |||
| 375 | return "VK_RESULT_MAX_ENUM"; | 375 | return "VK_RESULT_MAX_ENUM"; |
| 376 | case VkResult::VK_ERROR_COMPRESSION_EXHAUSTED_EXT: | 376 | case VkResult::VK_ERROR_COMPRESSION_EXHAUSTED_EXT: |
| 377 | return "VK_ERROR_COMPRESSION_EXHAUSTED_EXT"; | 377 | return "VK_ERROR_COMPRESSION_EXHAUSTED_EXT"; |
| 378 | case VkResult::VK_ERROR_INCOMPATIBLE_SHADER_BINARY_EXT: | ||
| 379 | return "VK_ERROR_INCOMPATIBLE_SHADER_BINARY_EXT"; | ||
| 378 | } | 380 | } |
| 379 | return "Unknown"; | 381 | return "Unknown"; |
| 380 | } | 382 | } |
diff --git a/src/yuzu/applets/qt_amiibo_settings.cpp b/src/yuzu/applets/qt_amiibo_settings.cpp index 93ad4b4f9..4559df5b1 100644 --- a/src/yuzu/applets/qt_amiibo_settings.cpp +++ b/src/yuzu/applets/qt_amiibo_settings.cpp | |||
| @@ -245,12 +245,19 @@ void QtAmiiboSettingsDialog::SetSettingsDescription() { | |||
| 245 | QtAmiiboSettings::QtAmiiboSettings(GMainWindow& parent) { | 245 | QtAmiiboSettings::QtAmiiboSettings(GMainWindow& parent) { |
| 246 | connect(this, &QtAmiiboSettings::MainWindowShowAmiiboSettings, &parent, | 246 | connect(this, &QtAmiiboSettings::MainWindowShowAmiiboSettings, &parent, |
| 247 | &GMainWindow::AmiiboSettingsShowDialog, Qt::QueuedConnection); | 247 | &GMainWindow::AmiiboSettingsShowDialog, Qt::QueuedConnection); |
| 248 | connect(this, &QtAmiiboSettings::MainWindowRequestExit, &parent, | ||
| 249 | &GMainWindow::AmiiboSettingsRequestExit, Qt::QueuedConnection); | ||
| 248 | connect(&parent, &GMainWindow::AmiiboSettingsFinished, this, | 250 | connect(&parent, &GMainWindow::AmiiboSettingsFinished, this, |
| 249 | &QtAmiiboSettings::MainWindowFinished, Qt::QueuedConnection); | 251 | &QtAmiiboSettings::MainWindowFinished, Qt::QueuedConnection); |
| 250 | } | 252 | } |
| 251 | 253 | ||
| 252 | QtAmiiboSettings::~QtAmiiboSettings() = default; | 254 | QtAmiiboSettings::~QtAmiiboSettings() = default; |
| 253 | 255 | ||
| 256 | void QtAmiiboSettings::Close() const { | ||
| 257 | callback = {}; | ||
| 258 | emit MainWindowRequestExit(); | ||
| 259 | } | ||
| 260 | |||
| 254 | void QtAmiiboSettings::ShowCabinetApplet( | 261 | void QtAmiiboSettings::ShowCabinetApplet( |
| 255 | const Core::Frontend::CabinetCallback& callback_, | 262 | const Core::Frontend::CabinetCallback& callback_, |
| 256 | const Core::Frontend::CabinetParameters& parameters, | 263 | const Core::Frontend::CabinetParameters& parameters, |
| @@ -260,5 +267,7 @@ void QtAmiiboSettings::ShowCabinetApplet( | |||
| 260 | } | 267 | } |
| 261 | 268 | ||
| 262 | void QtAmiiboSettings::MainWindowFinished(bool is_success, const std::string& name) { | 269 | void QtAmiiboSettings::MainWindowFinished(bool is_success, const std::string& name) { |
| 263 | callback(is_success, name); | 270 | if (callback) { |
| 271 | callback(is_success, name); | ||
| 272 | } | ||
| 264 | } | 273 | } |
diff --git a/src/yuzu/applets/qt_amiibo_settings.h b/src/yuzu/applets/qt_amiibo_settings.h index 930c96739..bc389a33f 100644 --- a/src/yuzu/applets/qt_amiibo_settings.h +++ b/src/yuzu/applets/qt_amiibo_settings.h | |||
| @@ -68,6 +68,7 @@ public: | |||
| 68 | explicit QtAmiiboSettings(GMainWindow& parent); | 68 | explicit QtAmiiboSettings(GMainWindow& parent); |
| 69 | ~QtAmiiboSettings() override; | 69 | ~QtAmiiboSettings() override; |
| 70 | 70 | ||
| 71 | void Close() const override; | ||
| 71 | void ShowCabinetApplet(const Core::Frontend::CabinetCallback& callback_, | 72 | void ShowCabinetApplet(const Core::Frontend::CabinetCallback& callback_, |
| 72 | const Core::Frontend::CabinetParameters& parameters, | 73 | const Core::Frontend::CabinetParameters& parameters, |
| 73 | std::shared_ptr<Service::NFP::NfpDevice> nfp_device) const override; | 74 | std::shared_ptr<Service::NFP::NfpDevice> nfp_device) const override; |
| @@ -75,6 +76,7 @@ public: | |||
| 75 | signals: | 76 | signals: |
| 76 | void MainWindowShowAmiiboSettings(const Core::Frontend::CabinetParameters& parameters, | 77 | void MainWindowShowAmiiboSettings(const Core::Frontend::CabinetParameters& parameters, |
| 77 | std::shared_ptr<Service::NFP::NfpDevice> nfp_device) const; | 78 | std::shared_ptr<Service::NFP::NfpDevice> nfp_device) const; |
| 79 | void MainWindowRequestExit() const; | ||
| 78 | 80 | ||
| 79 | private: | 81 | private: |
| 80 | void MainWindowFinished(bool is_success, const std::string& name); | 82 | void MainWindowFinished(bool is_success, const std::string& name); |
diff --git a/src/yuzu/applets/qt_controller.cpp b/src/yuzu/applets/qt_controller.cpp index c30b54499..00aafb8f8 100644 --- a/src/yuzu/applets/qt_controller.cpp +++ b/src/yuzu/applets/qt_controller.cpp | |||
| @@ -300,7 +300,7 @@ bool QtControllerSelectorDialog::CheckIfParametersMet() { | |||
| 300 | if (num_connected_players < min_supported_players || | 300 | if (num_connected_players < min_supported_players || |
| 301 | num_connected_players > max_supported_players) { | 301 | num_connected_players > max_supported_players) { |
| 302 | parameters_met = false; | 302 | parameters_met = false; |
| 303 | ui->buttonBox->setEnabled(parameters_met); | 303 | ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(parameters_met); |
| 304 | return parameters_met; | 304 | return parameters_met; |
| 305 | } | 305 | } |
| 306 | 306 | ||
| @@ -327,7 +327,7 @@ bool QtControllerSelectorDialog::CheckIfParametersMet() { | |||
| 327 | }(); | 327 | }(); |
| 328 | 328 | ||
| 329 | parameters_met = all_controllers_compatible; | 329 | parameters_met = all_controllers_compatible; |
| 330 | ui->buttonBox->setEnabled(parameters_met); | 330 | ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(parameters_met); |
| 331 | return parameters_met; | 331 | return parameters_met; |
| 332 | } | 332 | } |
| 333 | 333 | ||
| @@ -678,18 +678,27 @@ void QtControllerSelectorDialog::DisableUnsupportedPlayers() { | |||
| 678 | QtControllerSelector::QtControllerSelector(GMainWindow& parent) { | 678 | QtControllerSelector::QtControllerSelector(GMainWindow& parent) { |
| 679 | connect(this, &QtControllerSelector::MainWindowReconfigureControllers, &parent, | 679 | connect(this, &QtControllerSelector::MainWindowReconfigureControllers, &parent, |
| 680 | &GMainWindow::ControllerSelectorReconfigureControllers, Qt::QueuedConnection); | 680 | &GMainWindow::ControllerSelectorReconfigureControllers, Qt::QueuedConnection); |
| 681 | connect(this, &QtControllerSelector::MainWindowRequestExit, &parent, | ||
| 682 | &GMainWindow::ControllerSelectorRequestExit, Qt::QueuedConnection); | ||
| 681 | connect(&parent, &GMainWindow::ControllerSelectorReconfigureFinished, this, | 683 | connect(&parent, &GMainWindow::ControllerSelectorReconfigureFinished, this, |
| 682 | &QtControllerSelector::MainWindowReconfigureFinished, Qt::QueuedConnection); | 684 | &QtControllerSelector::MainWindowReconfigureFinished, Qt::QueuedConnection); |
| 683 | } | 685 | } |
| 684 | 686 | ||
| 685 | QtControllerSelector::~QtControllerSelector() = default; | 687 | QtControllerSelector::~QtControllerSelector() = default; |
| 686 | 688 | ||
| 689 | void QtControllerSelector::Close() const { | ||
| 690 | callback = {}; | ||
| 691 | emit MainWindowRequestExit(); | ||
| 692 | } | ||
| 693 | |||
| 687 | void QtControllerSelector::ReconfigureControllers( | 694 | void QtControllerSelector::ReconfigureControllers( |
| 688 | ReconfigureCallback callback_, const Core::Frontend::ControllerParameters& parameters) const { | 695 | ReconfigureCallback callback_, const Core::Frontend::ControllerParameters& parameters) const { |
| 689 | callback = std::move(callback_); | 696 | callback = std::move(callback_); |
| 690 | emit MainWindowReconfigureControllers(parameters); | 697 | emit MainWindowReconfigureControllers(parameters); |
| 691 | } | 698 | } |
| 692 | 699 | ||
| 693 | void QtControllerSelector::MainWindowReconfigureFinished() { | 700 | void QtControllerSelector::MainWindowReconfigureFinished(bool is_success) { |
| 694 | callback(); | 701 | if (callback) { |
| 702 | callback(is_success); | ||
| 703 | } | ||
| 695 | } | 704 | } |
diff --git a/src/yuzu/applets/qt_controller.h b/src/yuzu/applets/qt_controller.h index 16e99f507..2fdc35857 100644 --- a/src/yuzu/applets/qt_controller.h +++ b/src/yuzu/applets/qt_controller.h | |||
| @@ -156,6 +156,7 @@ public: | |||
| 156 | explicit QtControllerSelector(GMainWindow& parent); | 156 | explicit QtControllerSelector(GMainWindow& parent); |
| 157 | ~QtControllerSelector() override; | 157 | ~QtControllerSelector() override; |
| 158 | 158 | ||
| 159 | void Close() const override; | ||
| 159 | void ReconfigureControllers( | 160 | void ReconfigureControllers( |
| 160 | ReconfigureCallback callback_, | 161 | ReconfigureCallback callback_, |
| 161 | const Core::Frontend::ControllerParameters& parameters) const override; | 162 | const Core::Frontend::ControllerParameters& parameters) const override; |
| @@ -163,9 +164,10 @@ public: | |||
| 163 | signals: | 164 | signals: |
| 164 | void MainWindowReconfigureControllers( | 165 | void MainWindowReconfigureControllers( |
| 165 | const Core::Frontend::ControllerParameters& parameters) const; | 166 | const Core::Frontend::ControllerParameters& parameters) const; |
| 167 | void MainWindowRequestExit() const; | ||
| 166 | 168 | ||
| 167 | private: | 169 | private: |
| 168 | void MainWindowReconfigureFinished(); | 170 | void MainWindowReconfigureFinished(bool is_success); |
| 169 | 171 | ||
| 170 | mutable ReconfigureCallback callback; | 172 | mutable ReconfigureCallback callback; |
| 171 | }; | 173 | }; |
diff --git a/src/yuzu/applets/qt_controller.ui b/src/yuzu/applets/qt_controller.ui index f5eccba70..729e921ee 100644 --- a/src/yuzu/applets/qt_controller.ui +++ b/src/yuzu/applets/qt_controller.ui | |||
| @@ -2629,7 +2629,7 @@ | |||
| 2629 | <bool>true</bool> | 2629 | <bool>true</bool> |
| 2630 | </property> | 2630 | </property> |
| 2631 | <property name="standardButtons"> | 2631 | <property name="standardButtons"> |
| 2632 | <set>QDialogButtonBox::Ok</set> | 2632 | <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> |
| 2633 | </property> | 2633 | </property> |
| 2634 | </widget> | 2634 | </widget> |
| 2635 | </item> | 2635 | </item> |
| @@ -2649,5 +2649,11 @@ | |||
| 2649 | <receiver>QtControllerSelectorDialog</receiver> | 2649 | <receiver>QtControllerSelectorDialog</receiver> |
| 2650 | <slot>accept()</slot> | 2650 | <slot>accept()</slot> |
| 2651 | </connection> | 2651 | </connection> |
| 2652 | <connection> | ||
| 2653 | <sender>buttonBox</sender> | ||
| 2654 | <signal>rejected()</signal> | ||
| 2655 | <receiver>QtControllerSelectorDialog</receiver> | ||
| 2656 | <slot>reject()</slot> | ||
| 2657 | </connection> | ||
| 2652 | </connections> | 2658 | </connections> |
| 2653 | </ui> | 2659 | </ui> |
diff --git a/src/yuzu/applets/qt_error.cpp b/src/yuzu/applets/qt_error.cpp index e0190a979..1dc4f0383 100644 --- a/src/yuzu/applets/qt_error.cpp +++ b/src/yuzu/applets/qt_error.cpp | |||
| @@ -8,12 +8,19 @@ | |||
| 8 | QtErrorDisplay::QtErrorDisplay(GMainWindow& parent) { | 8 | QtErrorDisplay::QtErrorDisplay(GMainWindow& parent) { |
| 9 | connect(this, &QtErrorDisplay::MainWindowDisplayError, &parent, | 9 | connect(this, &QtErrorDisplay::MainWindowDisplayError, &parent, |
| 10 | &GMainWindow::ErrorDisplayDisplayError, Qt::QueuedConnection); | 10 | &GMainWindow::ErrorDisplayDisplayError, Qt::QueuedConnection); |
| 11 | connect(this, &QtErrorDisplay::MainWindowRequestExit, &parent, | ||
| 12 | &GMainWindow::ErrorDisplayRequestExit, Qt::QueuedConnection); | ||
| 11 | connect(&parent, &GMainWindow::ErrorDisplayFinished, this, | 13 | connect(&parent, &GMainWindow::ErrorDisplayFinished, this, |
| 12 | &QtErrorDisplay::MainWindowFinishedError, Qt::DirectConnection); | 14 | &QtErrorDisplay::MainWindowFinishedError, Qt::DirectConnection); |
| 13 | } | 15 | } |
| 14 | 16 | ||
| 15 | QtErrorDisplay::~QtErrorDisplay() = default; | 17 | QtErrorDisplay::~QtErrorDisplay() = default; |
| 16 | 18 | ||
| 19 | void QtErrorDisplay::Close() const { | ||
| 20 | callback = {}; | ||
| 21 | emit MainWindowRequestExit(); | ||
| 22 | } | ||
| 23 | |||
| 17 | void QtErrorDisplay::ShowError(Result error, FinishedCallback finished) const { | 24 | void QtErrorDisplay::ShowError(Result error, FinishedCallback finished) const { |
| 18 | callback = std::move(finished); | 25 | callback = std::move(finished); |
| 19 | emit MainWindowDisplayError( | 26 | emit MainWindowDisplayError( |
| @@ -55,5 +62,7 @@ void QtErrorDisplay::ShowCustomErrorText(Result error, std::string dialog_text, | |||
| 55 | } | 62 | } |
| 56 | 63 | ||
| 57 | void QtErrorDisplay::MainWindowFinishedError() { | 64 | void QtErrorDisplay::MainWindowFinishedError() { |
| 58 | callback(); | 65 | if (callback) { |
| 66 | callback(); | ||
| 67 | } | ||
| 59 | } | 68 | } |
diff --git a/src/yuzu/applets/qt_error.h b/src/yuzu/applets/qt_error.h index e4e174721..957f170ad 100644 --- a/src/yuzu/applets/qt_error.h +++ b/src/yuzu/applets/qt_error.h | |||
| @@ -16,6 +16,7 @@ public: | |||
| 16 | explicit QtErrorDisplay(GMainWindow& parent); | 16 | explicit QtErrorDisplay(GMainWindow& parent); |
| 17 | ~QtErrorDisplay() override; | 17 | ~QtErrorDisplay() override; |
| 18 | 18 | ||
| 19 | void Close() const override; | ||
| 19 | void ShowError(Result error, FinishedCallback finished) const override; | 20 | void ShowError(Result error, FinishedCallback finished) const override; |
| 20 | void ShowErrorWithTimestamp(Result error, std::chrono::seconds time, | 21 | void ShowErrorWithTimestamp(Result error, std::chrono::seconds time, |
| 21 | FinishedCallback finished) const override; | 22 | FinishedCallback finished) const override; |
| @@ -24,6 +25,7 @@ public: | |||
| 24 | 25 | ||
| 25 | signals: | 26 | signals: |
| 26 | void MainWindowDisplayError(QString error_code, QString error_text) const; | 27 | void MainWindowDisplayError(QString error_code, QString error_text) const; |
| 28 | void MainWindowRequestExit() const; | ||
| 27 | 29 | ||
| 28 | private: | 30 | private: |
| 29 | void MainWindowFinishedError(); | 31 | void MainWindowFinishedError(); |
diff --git a/src/yuzu/applets/qt_profile_select.cpp b/src/yuzu/applets/qt_profile_select.cpp index 4145c5299..2448e46b6 100644 --- a/src/yuzu/applets/qt_profile_select.cpp +++ b/src/yuzu/applets/qt_profile_select.cpp | |||
| @@ -46,11 +46,13 @@ QPixmap GetIcon(Common::UUID uuid) { | |||
| 46 | } | 46 | } |
| 47 | } // Anonymous namespace | 47 | } // Anonymous namespace |
| 48 | 48 | ||
| 49 | QtProfileSelectionDialog::QtProfileSelectionDialog(Core::HID::HIDCore& hid_core, QWidget* parent) | 49 | QtProfileSelectionDialog::QtProfileSelectionDialog( |
| 50 | Core::HID::HIDCore& hid_core, QWidget* parent, | ||
| 51 | const Core::Frontend::ProfileSelectParameters& parameters) | ||
| 50 | : QDialog(parent), profile_manager(std::make_unique<Service::Account::ProfileManager>()) { | 52 | : QDialog(parent), profile_manager(std::make_unique<Service::Account::ProfileManager>()) { |
| 51 | outer_layout = new QVBoxLayout; | 53 | outer_layout = new QVBoxLayout; |
| 52 | 54 | ||
| 53 | instruction_label = new QLabel(tr("Select a user:")); | 55 | instruction_label = new QLabel(); |
| 54 | 56 | ||
| 55 | scroll_area = new QScrollArea; | 57 | scroll_area = new QScrollArea; |
| 56 | 58 | ||
| @@ -120,7 +122,8 @@ QtProfileSelectionDialog::QtProfileSelectionDialog(Core::HID::HIDCore& hid_core, | |||
| 120 | item_model->appendRow(item); | 122 | item_model->appendRow(item); |
| 121 | 123 | ||
| 122 | setLayout(outer_layout); | 124 | setLayout(outer_layout); |
| 123 | setWindowTitle(tr("Profile Selector")); | 125 | SetWindowTitle(parameters); |
| 126 | SetDialogPurpose(parameters); | ||
| 124 | resize(550, 400); | 127 | resize(550, 400); |
| 125 | } | 128 | } |
| 126 | 129 | ||
| @@ -154,20 +157,101 @@ void QtProfileSelectionDialog::SelectUser(const QModelIndex& index) { | |||
| 154 | user_index = index.row(); | 157 | user_index = index.row(); |
| 155 | } | 158 | } |
| 156 | 159 | ||
| 160 | void QtProfileSelectionDialog::SetWindowTitle( | ||
| 161 | const Core::Frontend::ProfileSelectParameters& parameters) { | ||
| 162 | using Service::AM::Applets::UiMode; | ||
| 163 | switch (parameters.mode) { | ||
| 164 | case UiMode::UserCreator: | ||
| 165 | case UiMode::UserCreatorForStarter: | ||
| 166 | setWindowTitle(tr("Profile Creator")); | ||
| 167 | return; | ||
| 168 | case UiMode::EnsureNetworkServiceAccountAvailable: | ||
| 169 | setWindowTitle(tr("Profile Selector")); | ||
| 170 | return; | ||
| 171 | case UiMode::UserIconEditor: | ||
| 172 | setWindowTitle(tr("Profile Icon Editor")); | ||
| 173 | return; | ||
| 174 | case UiMode::UserNicknameEditor: | ||
| 175 | setWindowTitle(tr("Profile Nickname Editor")); | ||
| 176 | return; | ||
| 177 | case UiMode::NintendoAccountAuthorizationRequestContext: | ||
| 178 | case UiMode::IntroduceExternalNetworkServiceAccount: | ||
| 179 | case UiMode::IntroduceExternalNetworkServiceAccountForRegistration: | ||
| 180 | case UiMode::NintendoAccountNnidLinker: | ||
| 181 | case UiMode::LicenseRequirementsForNetworkService: | ||
| 182 | case UiMode::LicenseRequirementsForNetworkServiceWithUserContextImpl: | ||
| 183 | case UiMode::UserCreatorForImmediateNaLoginTest: | ||
| 184 | case UiMode::UserQualificationPromoter: | ||
| 185 | case UiMode::UserSelector: | ||
| 186 | default: | ||
| 187 | setWindowTitle(tr("Profile Selector")); | ||
| 188 | } | ||
| 189 | } | ||
| 190 | |||
| 191 | void QtProfileSelectionDialog::SetDialogPurpose( | ||
| 192 | const Core::Frontend::ProfileSelectParameters& parameters) { | ||
| 193 | using Service::AM::Applets::UserSelectionPurpose; | ||
| 194 | |||
| 195 | switch (parameters.purpose) { | ||
| 196 | case UserSelectionPurpose::GameCardRegistration: | ||
| 197 | instruction_label->setText(tr("Who will receive the points?")); | ||
| 198 | return; | ||
| 199 | case UserSelectionPurpose::EShopLaunch: | ||
| 200 | instruction_label->setText(tr("Who is using Nintendo eShop?")); | ||
| 201 | return; | ||
| 202 | case UserSelectionPurpose::EShopItemShow: | ||
| 203 | instruction_label->setText(tr("Who is making this purchase?")); | ||
| 204 | return; | ||
| 205 | case UserSelectionPurpose::PicturePost: | ||
| 206 | instruction_label->setText(tr("Who is posting?")); | ||
| 207 | return; | ||
| 208 | case UserSelectionPurpose::NintendoAccountLinkage: | ||
| 209 | instruction_label->setText(tr("Select a user to link to a Nintendo Account.")); | ||
| 210 | return; | ||
| 211 | case UserSelectionPurpose::SettingsUpdate: | ||
| 212 | instruction_label->setText(tr("Change settings for which user?")); | ||
| 213 | return; | ||
| 214 | case UserSelectionPurpose::SaveDataDeletion: | ||
| 215 | instruction_label->setText(tr("Format data for which user?")); | ||
| 216 | return; | ||
| 217 | case UserSelectionPurpose::UserMigration: | ||
| 218 | instruction_label->setText(tr("Which user will be transferred to another console?")); | ||
| 219 | return; | ||
| 220 | case UserSelectionPurpose::SaveDataTransfer: | ||
| 221 | instruction_label->setText(tr("Send save data for which user?")); | ||
| 222 | return; | ||
| 223 | case UserSelectionPurpose::General: | ||
| 224 | default: | ||
| 225 | instruction_label->setText(tr("Select a user:")); | ||
| 226 | return; | ||
| 227 | } | ||
| 228 | } | ||
| 229 | |||
| 157 | QtProfileSelector::QtProfileSelector(GMainWindow& parent) { | 230 | QtProfileSelector::QtProfileSelector(GMainWindow& parent) { |
| 158 | connect(this, &QtProfileSelector::MainWindowSelectProfile, &parent, | 231 | connect(this, &QtProfileSelector::MainWindowSelectProfile, &parent, |
| 159 | &GMainWindow::ProfileSelectorSelectProfile, Qt::QueuedConnection); | 232 | &GMainWindow::ProfileSelectorSelectProfile, Qt::QueuedConnection); |
| 233 | connect(this, &QtProfileSelector::MainWindowRequestExit, &parent, | ||
| 234 | &GMainWindow::ProfileSelectorRequestExit, Qt::QueuedConnection); | ||
| 160 | connect(&parent, &GMainWindow::ProfileSelectorFinishedSelection, this, | 235 | connect(&parent, &GMainWindow::ProfileSelectorFinishedSelection, this, |
| 161 | &QtProfileSelector::MainWindowFinishedSelection, Qt::DirectConnection); | 236 | &QtProfileSelector::MainWindowFinishedSelection, Qt::DirectConnection); |
| 162 | } | 237 | } |
| 163 | 238 | ||
| 164 | QtProfileSelector::~QtProfileSelector() = default; | 239 | QtProfileSelector::~QtProfileSelector() = default; |
| 165 | 240 | ||
| 166 | void QtProfileSelector::SelectProfile(SelectProfileCallback callback_) const { | 241 | void QtProfileSelector::Close() const { |
| 242 | callback = {}; | ||
| 243 | emit MainWindowRequestExit(); | ||
| 244 | } | ||
| 245 | |||
| 246 | void QtProfileSelector::SelectProfile( | ||
| 247 | SelectProfileCallback callback_, | ||
| 248 | const Core::Frontend::ProfileSelectParameters& parameters) const { | ||
| 167 | callback = std::move(callback_); | 249 | callback = std::move(callback_); |
| 168 | emit MainWindowSelectProfile(); | 250 | emit MainWindowSelectProfile(parameters); |
| 169 | } | 251 | } |
| 170 | 252 | ||
| 171 | void QtProfileSelector::MainWindowFinishedSelection(std::optional<Common::UUID> uuid) { | 253 | void QtProfileSelector::MainWindowFinishedSelection(std::optional<Common::UUID> uuid) { |
| 172 | callback(uuid); | 254 | if (callback) { |
| 255 | callback(uuid); | ||
| 256 | } | ||
| 173 | } | 257 | } |
diff --git a/src/yuzu/applets/qt_profile_select.h b/src/yuzu/applets/qt_profile_select.h index 637a3bda2..99056e274 100644 --- a/src/yuzu/applets/qt_profile_select.h +++ b/src/yuzu/applets/qt_profile_select.h | |||
| @@ -28,7 +28,8 @@ class QtProfileSelectionDialog final : public QDialog { | |||
| 28 | Q_OBJECT | 28 | Q_OBJECT |
| 29 | 29 | ||
| 30 | public: | 30 | public: |
| 31 | explicit QtProfileSelectionDialog(Core::HID::HIDCore& hid_core, QWidget* parent); | 31 | explicit QtProfileSelectionDialog(Core::HID::HIDCore& hid_core, QWidget* parent, |
| 32 | const Core::Frontend::ProfileSelectParameters& parameters); | ||
| 32 | ~QtProfileSelectionDialog() override; | 33 | ~QtProfileSelectionDialog() override; |
| 33 | 34 | ||
| 34 | int exec() override; | 35 | int exec() override; |
| @@ -40,6 +41,9 @@ public: | |||
| 40 | private: | 41 | private: |
| 41 | void SelectUser(const QModelIndex& index); | 42 | void SelectUser(const QModelIndex& index); |
| 42 | 43 | ||
| 44 | void SetWindowTitle(const Core::Frontend::ProfileSelectParameters& parameters); | ||
| 45 | void SetDialogPurpose(const Core::Frontend::ProfileSelectParameters& parameters); | ||
| 46 | |||
| 43 | int user_index = 0; | 47 | int user_index = 0; |
| 44 | 48 | ||
| 45 | QVBoxLayout* layout; | 49 | QVBoxLayout* layout; |
| @@ -65,10 +69,13 @@ public: | |||
| 65 | explicit QtProfileSelector(GMainWindow& parent); | 69 | explicit QtProfileSelector(GMainWindow& parent); |
| 66 | ~QtProfileSelector() override; | 70 | ~QtProfileSelector() override; |
| 67 | 71 | ||
| 68 | void SelectProfile(SelectProfileCallback callback_) const override; | 72 | void Close() const override; |
| 73 | void SelectProfile(SelectProfileCallback callback_, | ||
| 74 | const Core::Frontend::ProfileSelectParameters& parameters) const override; | ||
| 69 | 75 | ||
| 70 | signals: | 76 | signals: |
| 71 | void MainWindowSelectProfile() const; | 77 | void MainWindowSelectProfile(const Core::Frontend::ProfileSelectParameters& parameters) const; |
| 78 | void MainWindowRequestExit() const; | ||
| 72 | 79 | ||
| 73 | private: | 80 | private: |
| 74 | void MainWindowFinishedSelection(std::optional<Common::UUID> uuid); | 81 | void MainWindowFinishedSelection(std::optional<Common::UUID> uuid); |
diff --git a/src/yuzu/applets/qt_software_keyboard.h b/src/yuzu/applets/qt_software_keyboard.h index 30ac8ecf6..ac23ce047 100644 --- a/src/yuzu/applets/qt_software_keyboard.h +++ b/src/yuzu/applets/qt_software_keyboard.h | |||
| @@ -233,6 +233,10 @@ public: | |||
| 233 | explicit QtSoftwareKeyboard(GMainWindow& parent); | 233 | explicit QtSoftwareKeyboard(GMainWindow& parent); |
| 234 | ~QtSoftwareKeyboard() override; | 234 | ~QtSoftwareKeyboard() override; |
| 235 | 235 | ||
| 236 | void Close() const override { | ||
| 237 | ExitKeyboard(); | ||
| 238 | } | ||
| 239 | |||
| 236 | void InitializeKeyboard(bool is_inline, | 240 | void InitializeKeyboard(bool is_inline, |
| 237 | Core::Frontend::KeyboardInitializeParameters initialize_parameters, | 241 | Core::Frontend::KeyboardInitializeParameters initialize_parameters, |
| 238 | SubmitNormalCallback submit_normal_callback_, | 242 | SubmitNormalCallback submit_normal_callback_, |
diff --git a/src/yuzu/applets/qt_web_browser.cpp b/src/yuzu/applets/qt_web_browser.cpp index 0a5912326..28acc0ff8 100644 --- a/src/yuzu/applets/qt_web_browser.cpp +++ b/src/yuzu/applets/qt_web_browser.cpp | |||
| @@ -393,6 +393,8 @@ void QtNXWebEngineView::FocusFirstLinkElement() { | |||
| 393 | QtWebBrowser::QtWebBrowser(GMainWindow& main_window) { | 393 | QtWebBrowser::QtWebBrowser(GMainWindow& main_window) { |
| 394 | connect(this, &QtWebBrowser::MainWindowOpenWebPage, &main_window, | 394 | connect(this, &QtWebBrowser::MainWindowOpenWebPage, &main_window, |
| 395 | &GMainWindow::WebBrowserOpenWebPage, Qt::QueuedConnection); | 395 | &GMainWindow::WebBrowserOpenWebPage, Qt::QueuedConnection); |
| 396 | connect(this, &QtWebBrowser::MainWindowRequestExit, &main_window, | ||
| 397 | &GMainWindow::WebBrowserRequestExit, Qt::QueuedConnection); | ||
| 396 | connect(&main_window, &GMainWindow::WebBrowserExtractOfflineRomFS, this, | 398 | connect(&main_window, &GMainWindow::WebBrowserExtractOfflineRomFS, this, |
| 397 | &QtWebBrowser::MainWindowExtractOfflineRomFS, Qt::QueuedConnection); | 399 | &QtWebBrowser::MainWindowExtractOfflineRomFS, Qt::QueuedConnection); |
| 398 | connect(&main_window, &GMainWindow::WebBrowserClosed, this, | 400 | connect(&main_window, &GMainWindow::WebBrowserClosed, this, |
| @@ -401,6 +403,11 @@ QtWebBrowser::QtWebBrowser(GMainWindow& main_window) { | |||
| 401 | 403 | ||
| 402 | QtWebBrowser::~QtWebBrowser() = default; | 404 | QtWebBrowser::~QtWebBrowser() = default; |
| 403 | 405 | ||
| 406 | void QtWebBrowser::Close() const { | ||
| 407 | callback = {}; | ||
| 408 | emit MainWindowRequestExit(); | ||
| 409 | } | ||
| 410 | |||
| 404 | void QtWebBrowser::OpenLocalWebPage(const std::string& local_url, | 411 | void QtWebBrowser::OpenLocalWebPage(const std::string& local_url, |
| 405 | ExtractROMFSCallback extract_romfs_callback_, | 412 | ExtractROMFSCallback extract_romfs_callback_, |
| 406 | OpenWebPageCallback callback_) const { | 413 | OpenWebPageCallback callback_) const { |
| @@ -436,5 +443,7 @@ void QtWebBrowser::MainWindowExtractOfflineRomFS() { | |||
| 436 | 443 | ||
| 437 | void QtWebBrowser::MainWindowWebBrowserClosed(Service::AM::Applets::WebExitReason exit_reason, | 444 | void QtWebBrowser::MainWindowWebBrowserClosed(Service::AM::Applets::WebExitReason exit_reason, |
| 438 | std::string last_url) { | 445 | std::string last_url) { |
| 439 | callback(exit_reason, last_url); | 446 | if (callback) { |
| 447 | callback(exit_reason, last_url); | ||
| 448 | } | ||
| 440 | } | 449 | } |
diff --git a/src/yuzu/applets/qt_web_browser.h b/src/yuzu/applets/qt_web_browser.h index ceae7926e..1234108ae 100644 --- a/src/yuzu/applets/qt_web_browser.h +++ b/src/yuzu/applets/qt_web_browser.h | |||
| @@ -196,6 +196,7 @@ public: | |||
| 196 | explicit QtWebBrowser(GMainWindow& parent); | 196 | explicit QtWebBrowser(GMainWindow& parent); |
| 197 | ~QtWebBrowser() override; | 197 | ~QtWebBrowser() override; |
| 198 | 198 | ||
| 199 | void Close() const override; | ||
| 199 | void OpenLocalWebPage(const std::string& local_url, | 200 | void OpenLocalWebPage(const std::string& local_url, |
| 200 | ExtractROMFSCallback extract_romfs_callback_, | 201 | ExtractROMFSCallback extract_romfs_callback_, |
| 201 | OpenWebPageCallback callback_) const override; | 202 | OpenWebPageCallback callback_) const override; |
| @@ -206,6 +207,7 @@ public: | |||
| 206 | signals: | 207 | signals: |
| 207 | void MainWindowOpenWebPage(const std::string& main_url, const std::string& additional_args, | 208 | void MainWindowOpenWebPage(const std::string& main_url, const std::string& additional_args, |
| 208 | bool is_local) const; | 209 | bool is_local) const; |
| 210 | void MainWindowRequestExit() const; | ||
| 209 | 211 | ||
| 210 | private: | 212 | private: |
| 211 | void MainWindowExtractOfflineRomFS(); | 213 | void MainWindowExtractOfflineRomFS(); |
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index ae14884b5..b79409a68 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp | |||
| @@ -307,6 +307,8 @@ GMainWindow::GMainWindow(std::unique_ptr<Config> config_, bool has_broken_vulkan | |||
| 307 | system->Initialize(); | 307 | system->Initialize(); |
| 308 | 308 | ||
| 309 | Common::Log::Initialize(); | 309 | Common::Log::Initialize(); |
| 310 | Common::Log::Start(); | ||
| 311 | |||
| 310 | LoadTranslation(); | 312 | LoadTranslation(); |
| 311 | 313 | ||
| 312 | setAcceptDrops(true); | 314 | setAcceptDrops(true); |
| @@ -449,8 +451,6 @@ GMainWindow::GMainWindow(std::unique_ptr<Config> config_, bool has_broken_vulkan | |||
| 449 | 451 | ||
| 450 | SetupPrepareForSleep(); | 452 | SetupPrepareForSleep(); |
| 451 | 453 | ||
| 452 | Common::Log::Start(); | ||
| 453 | |||
| 454 | QStringList args = QApplication::arguments(); | 454 | QStringList args = QApplication::arguments(); |
| 455 | 455 | ||
| 456 | if (args.size() < 2) { | 456 | if (args.size() < 2) { |
| @@ -576,6 +576,10 @@ void GMainWindow::RegisterMetaTypes() { | |||
| 576 | // Controller Applet | 576 | // Controller Applet |
| 577 | qRegisterMetaType<Core::Frontend::ControllerParameters>("Core::Frontend::ControllerParameters"); | 577 | qRegisterMetaType<Core::Frontend::ControllerParameters>("Core::Frontend::ControllerParameters"); |
| 578 | 578 | ||
| 579 | // Profile Select Applet | ||
| 580 | qRegisterMetaType<Core::Frontend::ProfileSelectParameters>( | ||
| 581 | "Core::Frontend::ProfileSelectParameters"); | ||
| 582 | |||
| 579 | // Software Keyboard Applet | 583 | // Software Keyboard Applet |
| 580 | qRegisterMetaType<Core::Frontend::KeyboardInitializeParameters>( | 584 | qRegisterMetaType<Core::Frontend::KeyboardInitializeParameters>( |
| 581 | "Core::Frontend::KeyboardInitializeParameters"); | 585 | "Core::Frontend::KeyboardInitializeParameters"); |
| @@ -596,50 +600,81 @@ void GMainWindow::RegisterMetaTypes() { | |||
| 596 | 600 | ||
| 597 | void GMainWindow::AmiiboSettingsShowDialog(const Core::Frontend::CabinetParameters& parameters, | 601 | void GMainWindow::AmiiboSettingsShowDialog(const Core::Frontend::CabinetParameters& parameters, |
| 598 | std::shared_ptr<Service::NFP::NfpDevice> nfp_device) { | 602 | std::shared_ptr<Service::NFP::NfpDevice> nfp_device) { |
| 599 | QtAmiiboSettingsDialog dialog(this, parameters, input_subsystem.get(), nfp_device); | 603 | cabinet_applet = |
| 604 | new QtAmiiboSettingsDialog(this, parameters, input_subsystem.get(), nfp_device); | ||
| 605 | SCOPE_EXIT({ | ||
| 606 | cabinet_applet->deleteLater(); | ||
| 607 | cabinet_applet = nullptr; | ||
| 608 | }); | ||
| 600 | 609 | ||
| 601 | dialog.setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowStaysOnTopHint | | 610 | cabinet_applet->setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowStaysOnTopHint | |
| 602 | Qt::WindowTitleHint | Qt::WindowSystemMenuHint); | 611 | Qt::WindowTitleHint | Qt::WindowSystemMenuHint); |
| 603 | dialog.setWindowModality(Qt::WindowModal); | 612 | cabinet_applet->setWindowModality(Qt::WindowModal); |
| 604 | if (dialog.exec() == QDialog::Rejected) { | 613 | |
| 614 | if (cabinet_applet->exec() == QDialog::Rejected) { | ||
| 605 | emit AmiiboSettingsFinished(false, {}); | 615 | emit AmiiboSettingsFinished(false, {}); |
| 606 | return; | 616 | return; |
| 607 | } | 617 | } |
| 608 | 618 | ||
| 609 | emit AmiiboSettingsFinished(true, dialog.GetName()); | 619 | emit AmiiboSettingsFinished(true, cabinet_applet->GetName()); |
| 620 | } | ||
| 621 | |||
| 622 | void GMainWindow::AmiiboSettingsRequestExit() { | ||
| 623 | if (cabinet_applet) { | ||
| 624 | cabinet_applet->reject(); | ||
| 625 | } | ||
| 610 | } | 626 | } |
| 611 | 627 | ||
| 612 | void GMainWindow::ControllerSelectorReconfigureControllers( | 628 | void GMainWindow::ControllerSelectorReconfigureControllers( |
| 613 | const Core::Frontend::ControllerParameters& parameters) { | 629 | const Core::Frontend::ControllerParameters& parameters) { |
| 614 | QtControllerSelectorDialog dialog(this, parameters, input_subsystem.get(), *system); | 630 | controller_applet = |
| 615 | 631 | new QtControllerSelectorDialog(this, parameters, input_subsystem.get(), *system); | |
| 616 | dialog.setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowStaysOnTopHint | | 632 | SCOPE_EXIT({ |
| 617 | Qt::WindowTitleHint | Qt::WindowSystemMenuHint); | 633 | controller_applet->deleteLater(); |
| 618 | dialog.setWindowModality(Qt::WindowModal); | 634 | controller_applet = nullptr; |
| 619 | dialog.exec(); | 635 | }); |
| 620 | 636 | ||
| 621 | emit ControllerSelectorReconfigureFinished(); | 637 | controller_applet->setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | |
| 638 | Qt::WindowStaysOnTopHint | Qt::WindowTitleHint | | ||
| 639 | Qt::WindowSystemMenuHint); | ||
| 640 | controller_applet->setWindowModality(Qt::WindowModal); | ||
| 641 | bool is_success = controller_applet->exec() != QDialog::Rejected; | ||
| 622 | 642 | ||
| 623 | // Don't forget to apply settings. | 643 | // Don't forget to apply settings. |
| 644 | system->HIDCore().DisableAllControllerConfiguration(); | ||
| 624 | system->ApplySettings(); | 645 | system->ApplySettings(); |
| 625 | config->Save(); | 646 | config->Save(); |
| 626 | 647 | ||
| 627 | UpdateStatusButtons(); | 648 | UpdateStatusButtons(); |
| 649 | |||
| 650 | emit ControllerSelectorReconfigureFinished(is_success); | ||
| 628 | } | 651 | } |
| 629 | 652 | ||
| 630 | void GMainWindow::ProfileSelectorSelectProfile() { | 653 | void GMainWindow::ControllerSelectorRequestExit() { |
| 631 | QtProfileSelectionDialog dialog(system->HIDCore(), this); | 654 | if (controller_applet) { |
| 632 | dialog.setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowStaysOnTopHint | | 655 | controller_applet->reject(); |
| 633 | Qt::WindowTitleHint | Qt::WindowSystemMenuHint | | 656 | } |
| 634 | Qt::WindowCloseButtonHint); | 657 | } |
| 635 | dialog.setWindowModality(Qt::WindowModal); | 658 | |
| 636 | if (dialog.exec() == QDialog::Rejected) { | 659 | void GMainWindow::ProfileSelectorSelectProfile( |
| 660 | const Core::Frontend::ProfileSelectParameters& parameters) { | ||
| 661 | profile_select_applet = new QtProfileSelectionDialog(system->HIDCore(), this, parameters); | ||
| 662 | SCOPE_EXIT({ | ||
| 663 | profile_select_applet->deleteLater(); | ||
| 664 | profile_select_applet = nullptr; | ||
| 665 | }); | ||
| 666 | |||
| 667 | profile_select_applet->setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | | ||
| 668 | Qt::WindowStaysOnTopHint | Qt::WindowTitleHint | | ||
| 669 | Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint); | ||
| 670 | profile_select_applet->setWindowModality(Qt::WindowModal); | ||
| 671 | if (profile_select_applet->exec() == QDialog::Rejected) { | ||
| 637 | emit ProfileSelectorFinishedSelection(std::nullopt); | 672 | emit ProfileSelectorFinishedSelection(std::nullopt); |
| 638 | return; | 673 | return; |
| 639 | } | 674 | } |
| 640 | 675 | ||
| 641 | const Service::Account::ProfileManager manager; | 676 | const Service::Account::ProfileManager manager; |
| 642 | const auto uuid = manager.GetUser(static_cast<std::size_t>(dialog.GetIndex())); | 677 | const auto uuid = manager.GetUser(static_cast<std::size_t>(profile_select_applet->GetIndex())); |
| 643 | if (!uuid.has_value()) { | 678 | if (!uuid.has_value()) { |
| 644 | emit ProfileSelectorFinishedSelection(std::nullopt); | 679 | emit ProfileSelectorFinishedSelection(std::nullopt); |
| 645 | return; | 680 | return; |
| @@ -648,6 +683,12 @@ void GMainWindow::ProfileSelectorSelectProfile() { | |||
| 648 | emit ProfileSelectorFinishedSelection(uuid); | 683 | emit ProfileSelectorFinishedSelection(uuid); |
| 649 | } | 684 | } |
| 650 | 685 | ||
| 686 | void GMainWindow::ProfileSelectorRequestExit() { | ||
| 687 | if (profile_select_applet) { | ||
| 688 | profile_select_applet->reject(); | ||
| 689 | } | ||
| 690 | } | ||
| 691 | |||
| 651 | void GMainWindow::SoftwareKeyboardInitialize( | 692 | void GMainWindow::SoftwareKeyboardInitialize( |
| 652 | bool is_inline, Core::Frontend::KeyboardInitializeParameters initialize_parameters) { | 693 | bool is_inline, Core::Frontend::KeyboardInitializeParameters initialize_parameters) { |
| 653 | if (software_keyboard) { | 694 | if (software_keyboard) { |
| @@ -772,7 +813,7 @@ void GMainWindow::WebBrowserOpenWebPage(const std::string& main_url, | |||
| 772 | return; | 813 | return; |
| 773 | } | 814 | } |
| 774 | 815 | ||
| 775 | QtNXWebEngineView web_browser_view(this, *system, input_subsystem.get()); | 816 | web_applet = new QtNXWebEngineView(this, *system, input_subsystem.get()); |
| 776 | 817 | ||
| 777 | ui->action_Pause->setEnabled(false); | 818 | ui->action_Pause->setEnabled(false); |
| 778 | ui->action_Restart->setEnabled(false); | 819 | ui->action_Restart->setEnabled(false); |
| @@ -799,9 +840,9 @@ void GMainWindow::WebBrowserOpenWebPage(const std::string& main_url, | |||
| 799 | loading_progress.setValue(1); | 840 | loading_progress.setValue(1); |
| 800 | 841 | ||
| 801 | if (is_local) { | 842 | if (is_local) { |
| 802 | web_browser_view.LoadLocalWebPage(main_url, additional_args); | 843 | web_applet->LoadLocalWebPage(main_url, additional_args); |
| 803 | } else { | 844 | } else { |
| 804 | web_browser_view.LoadExternalWebPage(main_url, additional_args); | 845 | web_applet->LoadExternalWebPage(main_url, additional_args); |
| 805 | } | 846 | } |
| 806 | 847 | ||
| 807 | if (render_window->IsLoadingComplete()) { | 848 | if (render_window->IsLoadingComplete()) { |
| @@ -810,15 +851,15 @@ void GMainWindow::WebBrowserOpenWebPage(const std::string& main_url, | |||
| 810 | 851 | ||
| 811 | const auto& layout = render_window->GetFramebufferLayout(); | 852 | const auto& layout = render_window->GetFramebufferLayout(); |
| 812 | const auto scale_ratio = devicePixelRatioF(); | 853 | const auto scale_ratio = devicePixelRatioF(); |
| 813 | web_browser_view.resize(layout.screen.GetWidth() / scale_ratio, | 854 | web_applet->resize(layout.screen.GetWidth() / scale_ratio, |
| 814 | layout.screen.GetHeight() / scale_ratio); | 855 | layout.screen.GetHeight() / scale_ratio); |
| 815 | web_browser_view.move(layout.screen.left / scale_ratio, | 856 | web_applet->move(layout.screen.left / scale_ratio, |
| 816 | (layout.screen.top / scale_ratio) + menuBar()->height()); | 857 | (layout.screen.top / scale_ratio) + menuBar()->height()); |
| 817 | web_browser_view.setZoomFactor(static_cast<qreal>(layout.screen.GetWidth() / scale_ratio) / | 858 | web_applet->setZoomFactor(static_cast<qreal>(layout.screen.GetWidth() / scale_ratio) / |
| 818 | static_cast<qreal>(Layout::ScreenUndocked::Width)); | 859 | static_cast<qreal>(Layout::ScreenUndocked::Width)); |
| 819 | 860 | ||
| 820 | web_browser_view.setFocus(); | 861 | web_applet->setFocus(); |
| 821 | web_browser_view.show(); | 862 | web_applet->show(); |
| 822 | 863 | ||
| 823 | loading_progress.setValue(2); | 864 | loading_progress.setValue(2); |
| 824 | 865 | ||
| @@ -831,7 +872,7 @@ void GMainWindow::WebBrowserOpenWebPage(const std::string& main_url, | |||
| 831 | 872 | ||
| 832 | // TODO (Morph): Remove this | 873 | // TODO (Morph): Remove this |
| 833 | QAction* exit_action = new QAction(tr("Disable Web Applet"), this); | 874 | QAction* exit_action = new QAction(tr("Disable Web Applet"), this); |
| 834 | connect(exit_action, &QAction::triggered, this, [this, &web_browser_view] { | 875 | connect(exit_action, &QAction::triggered, this, [this] { |
| 835 | const auto result = QMessageBox::warning( | 876 | const auto result = QMessageBox::warning( |
| 836 | this, tr("Disable Web Applet"), | 877 | this, tr("Disable Web Applet"), |
| 837 | tr("Disabling the web applet can lead to undefined behavior and should only be used " | 878 | tr("Disabling the web applet can lead to undefined behavior and should only be used " |
| @@ -840,21 +881,21 @@ void GMainWindow::WebBrowserOpenWebPage(const std::string& main_url, | |||
| 840 | QMessageBox::Yes | QMessageBox::No); | 881 | QMessageBox::Yes | QMessageBox::No); |
| 841 | if (result == QMessageBox::Yes) { | 882 | if (result == QMessageBox::Yes) { |
| 842 | UISettings::values.disable_web_applet = true; | 883 | UISettings::values.disable_web_applet = true; |
| 843 | web_browser_view.SetFinished(true); | 884 | web_applet->SetFinished(true); |
| 844 | } | 885 | } |
| 845 | }); | 886 | }); |
| 846 | ui->menubar->addAction(exit_action); | 887 | ui->menubar->addAction(exit_action); |
| 847 | 888 | ||
| 848 | while (!web_browser_view.IsFinished()) { | 889 | while (!web_applet->IsFinished()) { |
| 849 | QCoreApplication::processEvents(); | 890 | QCoreApplication::processEvents(); |
| 850 | 891 | ||
| 851 | if (!exit_check) { | 892 | if (!exit_check) { |
| 852 | web_browser_view.page()->runJavaScript( | 893 | web_applet->page()->runJavaScript( |
| 853 | QStringLiteral("end_applet;"), [&](const QVariant& variant) { | 894 | QStringLiteral("end_applet;"), [&](const QVariant& variant) { |
| 854 | exit_check = false; | 895 | exit_check = false; |
| 855 | if (variant.toBool()) { | 896 | if (variant.toBool()) { |
| 856 | web_browser_view.SetFinished(true); | 897 | web_applet->SetFinished(true); |
| 857 | web_browser_view.SetExitReason( | 898 | web_applet->SetExitReason( |
| 858 | Service::AM::Applets::WebExitReason::EndButtonPressed); | 899 | Service::AM::Applets::WebExitReason::EndButtonPressed); |
| 859 | } | 900 | } |
| 860 | }); | 901 | }); |
| @@ -862,22 +903,22 @@ void GMainWindow::WebBrowserOpenWebPage(const std::string& main_url, | |||
| 862 | exit_check = true; | 903 | exit_check = true; |
| 863 | } | 904 | } |
| 864 | 905 | ||
| 865 | if (web_browser_view.GetCurrentURL().contains(QStringLiteral("localhost"))) { | 906 | if (web_applet->GetCurrentURL().contains(QStringLiteral("localhost"))) { |
| 866 | if (!web_browser_view.IsFinished()) { | 907 | if (!web_applet->IsFinished()) { |
| 867 | web_browser_view.SetFinished(true); | 908 | web_applet->SetFinished(true); |
| 868 | web_browser_view.SetExitReason(Service::AM::Applets::WebExitReason::CallbackURL); | 909 | web_applet->SetExitReason(Service::AM::Applets::WebExitReason::CallbackURL); |
| 869 | } | 910 | } |
| 870 | 911 | ||
| 871 | web_browser_view.SetLastURL(web_browser_view.GetCurrentURL().toStdString()); | 912 | web_applet->SetLastURL(web_applet->GetCurrentURL().toStdString()); |
| 872 | } | 913 | } |
| 873 | 914 | ||
| 874 | std::this_thread::sleep_for(std::chrono::milliseconds(1)); | 915 | std::this_thread::sleep_for(std::chrono::milliseconds(1)); |
| 875 | } | 916 | } |
| 876 | 917 | ||
| 877 | const auto exit_reason = web_browser_view.GetExitReason(); | 918 | const auto exit_reason = web_applet->GetExitReason(); |
| 878 | const auto last_url = web_browser_view.GetLastURL(); | 919 | const auto last_url = web_applet->GetLastURL(); |
| 879 | 920 | ||
| 880 | web_browser_view.hide(); | 921 | web_applet->hide(); |
| 881 | 922 | ||
| 882 | render_window->setFocus(); | 923 | render_window->setFocus(); |
| 883 | 924 | ||
| @@ -903,6 +944,15 @@ void GMainWindow::WebBrowserOpenWebPage(const std::string& main_url, | |||
| 903 | #endif | 944 | #endif |
| 904 | } | 945 | } |
| 905 | 946 | ||
| 947 | void GMainWindow::WebBrowserRequestExit() { | ||
| 948 | #ifdef YUZU_USE_QT_WEB_ENGINE | ||
| 949 | if (web_applet) { | ||
| 950 | web_applet->SetExitReason(Service::AM::Applets::WebExitReason::ExitRequested); | ||
| 951 | web_applet->SetFinished(true); | ||
| 952 | } | ||
| 953 | #endif | ||
| 954 | } | ||
| 955 | |||
| 906 | void GMainWindow::InitializeWidgets() { | 956 | void GMainWindow::InitializeWidgets() { |
| 907 | #ifdef YUZU_ENABLE_COMPATIBILITY_REPORTING | 957 | #ifdef YUZU_ENABLE_COMPATIBILITY_REPORTING |
| 908 | ui->action_Report_Compatibility->setVisible(true); | 958 | ui->action_Report_Compatibility->setVisible(true); |
| @@ -1675,8 +1725,9 @@ bool GMainWindow::LoadROM(const QString& filename, u64 program_id, std::size_t p | |||
| 1675 | return true; | 1725 | return true; |
| 1676 | } | 1726 | } |
| 1677 | 1727 | ||
| 1678 | bool GMainWindow::SelectAndSetCurrentUser() { | 1728 | bool GMainWindow::SelectAndSetCurrentUser( |
| 1679 | QtProfileSelectionDialog dialog(system->HIDCore(), this); | 1729 | const Core::Frontend::ProfileSelectParameters& parameters) { |
| 1730 | QtProfileSelectionDialog dialog(system->HIDCore(), this, parameters); | ||
| 1680 | dialog.setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowTitleHint | | 1731 | dialog.setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowTitleHint | |
| 1681 | Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint); | 1732 | Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint); |
| 1682 | dialog.setWindowModality(Qt::WindowModal); | 1733 | dialog.setWindowModality(Qt::WindowModal); |
| @@ -1722,7 +1773,13 @@ void GMainWindow::BootGame(const QString& filename, u64 program_id, std::size_t | |||
| 1722 | Settings::LogSettings(); | 1773 | Settings::LogSettings(); |
| 1723 | 1774 | ||
| 1724 | if (UISettings::values.select_user_on_boot) { | 1775 | if (UISettings::values.select_user_on_boot) { |
| 1725 | if (SelectAndSetCurrentUser() == false) { | 1776 | const Core::Frontend::ProfileSelectParameters parameters{ |
| 1777 | .mode = Service::AM::Applets::UiMode::UserSelector, | ||
| 1778 | .invalid_uid_list = {}, | ||
| 1779 | .display_options = {}, | ||
| 1780 | .purpose = Service::AM::Applets::UserSelectionPurpose::General, | ||
| 1781 | }; | ||
| 1782 | if (SelectAndSetCurrentUser(parameters) == false) { | ||
| 1726 | return; | 1783 | return; |
| 1727 | } | 1784 | } |
| 1728 | } | 1785 | } |
| @@ -2014,7 +2071,13 @@ void GMainWindow::OnGameListOpenFolder(u64 program_id, GameListOpenTarget target | |||
| 2014 | if (has_user_save) { | 2071 | if (has_user_save) { |
| 2015 | // User save data | 2072 | // User save data |
| 2016 | const auto select_profile = [this] { | 2073 | const auto select_profile = [this] { |
| 2017 | QtProfileSelectionDialog dialog(system->HIDCore(), this); | 2074 | const Core::Frontend::ProfileSelectParameters parameters{ |
| 2075 | .mode = Service::AM::Applets::UiMode::UserSelector, | ||
| 2076 | .invalid_uid_list = {}, | ||
| 2077 | .display_options = {}, | ||
| 2078 | .purpose = Service::AM::Applets::UserSelectionPurpose::General, | ||
| 2079 | }; | ||
| 2080 | QtProfileSelectionDialog dialog(system->HIDCore(), this, parameters); | ||
| 2018 | dialog.setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowTitleHint | | 2081 | dialog.setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowTitleHint | |
| 2019 | Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint); | 2082 | Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint); |
| 2020 | dialog.setWindowModality(Qt::WindowModal); | 2083 | dialog.setWindowModality(Qt::WindowModal); |
| @@ -3089,13 +3152,23 @@ void GMainWindow::OnSaveConfig() { | |||
| 3089 | } | 3152 | } |
| 3090 | 3153 | ||
| 3091 | void GMainWindow::ErrorDisplayDisplayError(QString error_code, QString error_text) { | 3154 | void GMainWindow::ErrorDisplayDisplayError(QString error_code, QString error_text) { |
| 3092 | OverlayDialog dialog(render_window, *system, error_code, error_text, QString{}, tr("OK"), | 3155 | error_applet = new OverlayDialog(render_window, *system, error_code, error_text, QString{}, |
| 3093 | Qt::AlignLeft | Qt::AlignVCenter); | 3156 | tr("OK"), Qt::AlignLeft | Qt::AlignVCenter); |
| 3094 | dialog.exec(); | 3157 | SCOPE_EXIT({ |
| 3158 | error_applet->deleteLater(); | ||
| 3159 | error_applet = nullptr; | ||
| 3160 | }); | ||
| 3161 | error_applet->exec(); | ||
| 3095 | 3162 | ||
| 3096 | emit ErrorDisplayFinished(); | 3163 | emit ErrorDisplayFinished(); |
| 3097 | } | 3164 | } |
| 3098 | 3165 | ||
| 3166 | void GMainWindow::ErrorDisplayRequestExit() { | ||
| 3167 | if (error_applet) { | ||
| 3168 | error_applet->reject(); | ||
| 3169 | } | ||
| 3170 | } | ||
| 3171 | |||
| 3099 | void GMainWindow::OnMenuReportCompatibility() { | 3172 | void GMainWindow::OnMenuReportCompatibility() { |
| 3100 | #if defined(ARCHITECTURE_x86_64) && !defined(__APPLE__) | 3173 | #if defined(ARCHITECTURE_x86_64) && !defined(__APPLE__) |
| 3101 | const auto& caps = Common::GetCPUCaps(); | 3174 | const auto& caps = Common::GetCPUCaps(); |
diff --git a/src/yuzu/main.h b/src/yuzu/main.h index a23b373a5..8b5c1d747 100644 --- a/src/yuzu/main.h +++ b/src/yuzu/main.h | |||
| @@ -47,7 +47,11 @@ enum class DumpRomFSTarget; | |||
| 47 | enum class InstalledEntryType; | 47 | enum class InstalledEntryType; |
| 48 | class GameListPlaceholder; | 48 | class GameListPlaceholder; |
| 49 | 49 | ||
| 50 | class QtAmiiboSettingsDialog; | ||
| 51 | class QtControllerSelectorDialog; | ||
| 52 | class QtProfileSelectionDialog; | ||
| 50 | class QtSoftwareKeyboardDialog; | 53 | class QtSoftwareKeyboardDialog; |
| 54 | class QtNXWebEngineView; | ||
| 51 | 55 | ||
| 52 | enum class StartGameType { | 56 | enum class StartGameType { |
| 53 | Normal, // Can use custom configuration | 57 | Normal, // Can use custom configuration |
| @@ -65,6 +69,7 @@ struct ControllerParameters; | |||
| 65 | struct InlineAppearParameters; | 69 | struct InlineAppearParameters; |
| 66 | struct InlineTextParameters; | 70 | struct InlineTextParameters; |
| 67 | struct KeyboardInitializeParameters; | 71 | struct KeyboardInitializeParameters; |
| 72 | struct ProfileSelectParameters; | ||
| 68 | } // namespace Core::Frontend | 73 | } // namespace Core::Frontend |
| 69 | 74 | ||
| 70 | namespace DiscordRPC { | 75 | namespace DiscordRPC { |
| @@ -161,7 +166,7 @@ signals: | |||
| 161 | 166 | ||
| 162 | void AmiiboSettingsFinished(bool is_success, const std::string& name); | 167 | void AmiiboSettingsFinished(bool is_success, const std::string& name); |
| 163 | 168 | ||
| 164 | void ControllerSelectorReconfigureFinished(); | 169 | void ControllerSelectorReconfigureFinished(bool is_success); |
| 165 | 170 | ||
| 166 | void ErrorDisplayFinished(); | 171 | void ErrorDisplayFinished(); |
| 167 | 172 | ||
| @@ -184,8 +189,10 @@ public slots: | |||
| 184 | void OnSaveConfig(); | 189 | void OnSaveConfig(); |
| 185 | void AmiiboSettingsShowDialog(const Core::Frontend::CabinetParameters& parameters, | 190 | void AmiiboSettingsShowDialog(const Core::Frontend::CabinetParameters& parameters, |
| 186 | std::shared_ptr<Service::NFP::NfpDevice> nfp_device); | 191 | std::shared_ptr<Service::NFP::NfpDevice> nfp_device); |
| 192 | void AmiiboSettingsRequestExit(); | ||
| 187 | void ControllerSelectorReconfigureControllers( | 193 | void ControllerSelectorReconfigureControllers( |
| 188 | const Core::Frontend::ControllerParameters& parameters); | 194 | const Core::Frontend::ControllerParameters& parameters); |
| 195 | void ControllerSelectorRequestExit(); | ||
| 189 | void SoftwareKeyboardInitialize( | 196 | void SoftwareKeyboardInitialize( |
| 190 | bool is_inline, Core::Frontend::KeyboardInitializeParameters initialize_parameters); | 197 | bool is_inline, Core::Frontend::KeyboardInitializeParameters initialize_parameters); |
| 191 | void SoftwareKeyboardShowNormal(); | 198 | void SoftwareKeyboardShowNormal(); |
| @@ -196,9 +203,12 @@ public slots: | |||
| 196 | void SoftwareKeyboardInlineTextChanged(Core::Frontend::InlineTextParameters text_parameters); | 203 | void SoftwareKeyboardInlineTextChanged(Core::Frontend::InlineTextParameters text_parameters); |
| 197 | void SoftwareKeyboardExit(); | 204 | void SoftwareKeyboardExit(); |
| 198 | void ErrorDisplayDisplayError(QString error_code, QString error_text); | 205 | void ErrorDisplayDisplayError(QString error_code, QString error_text); |
| 199 | void ProfileSelectorSelectProfile(); | 206 | void ErrorDisplayRequestExit(); |
| 207 | void ProfileSelectorSelectProfile(const Core::Frontend::ProfileSelectParameters& parameters); | ||
| 208 | void ProfileSelectorRequestExit(); | ||
| 200 | void WebBrowserOpenWebPage(const std::string& main_url, const std::string& additional_args, | 209 | void WebBrowserOpenWebPage(const std::string& main_url, const std::string& additional_args, |
| 201 | bool is_local); | 210 | bool is_local); |
| 211 | void WebBrowserRequestExit(); | ||
| 202 | void OnAppFocusStateChanged(Qt::ApplicationState state); | 212 | void OnAppFocusStateChanged(Qt::ApplicationState state); |
| 203 | void OnTasStateChanged(); | 213 | void OnTasStateChanged(); |
| 204 | 214 | ||
| @@ -233,7 +243,7 @@ private: | |||
| 233 | void SetDiscordEnabled(bool state); | 243 | void SetDiscordEnabled(bool state); |
| 234 | void LoadAmiibo(const QString& filename); | 244 | void LoadAmiibo(const QString& filename); |
| 235 | 245 | ||
| 236 | bool SelectAndSetCurrentUser(); | 246 | bool SelectAndSetCurrentUser(const Core::Frontend::ProfileSelectParameters& parameters); |
| 237 | 247 | ||
| 238 | /** | 248 | /** |
| 239 | * Stores the filename in the recently loaded files list. | 249 | * Stores the filename in the recently loaded files list. |
| @@ -466,7 +476,12 @@ private: | |||
| 466 | QString last_filename_booted; | 476 | QString last_filename_booted; |
| 467 | 477 | ||
| 468 | // Applets | 478 | // Applets |
| 479 | QtAmiiboSettingsDialog* cabinet_applet = nullptr; | ||
| 480 | QtControllerSelectorDialog* controller_applet = nullptr; | ||
| 481 | QtProfileSelectionDialog* profile_select_applet = nullptr; | ||
| 482 | QDialog* error_applet = nullptr; | ||
| 469 | QtSoftwareKeyboardDialog* software_keyboard = nullptr; | 483 | QtSoftwareKeyboardDialog* software_keyboard = nullptr; |
| 484 | QtNXWebEngineView* web_applet = nullptr; | ||
| 470 | 485 | ||
| 471 | // True if amiibo file select is visible | 486 | // True if amiibo file select is visible |
| 472 | bool is_amiibo_file_select_active{}; | 487 | bool is_amiibo_file_select_active{}; |