summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/common/alignment.h7
-rw-r--r--src/common/settings.h5
-rw-r--r--src/common/string_util.cpp12
-rw-r--r--src/common/string_util.h2
-rw-r--r--src/core/arm/dynarmic/arm_dynarmic_64.cpp2
-rw-r--r--src/core/core.cpp100
-rw-r--r--src/core/core.h61
-rw-r--r--src/core/hle/kernel/k_page_table.cpp2
-rw-r--r--src/core/hle/kernel/k_scheduler.h5
-rw-r--r--src/core/hle/kernel/svc.cpp17
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp14
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp17
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.h13
-rw-r--r--src/core/hle/service/nvdrv/nvdrv.h2
-rw-r--r--src/core/hle/service/time/time_manager.cpp13
-rw-r--r--src/core/hle/service/vi/vi.cpp12
-rw-r--r--src/input_common/udp/client.cpp74
-rw-r--r--src/shader_recompiler/ir_opt/texture_pass.cpp3
-rw-r--r--src/video_core/dirty_flags.h3
-rw-r--r--src/video_core/query_cache.h8
-rw-r--r--src/video_core/rasterizer_accelerated.h2
-rw-r--r--src/video_core/renderer_opengl/gl_device.cpp1
-rw-r--r--src/video_core/renderer_vulkan/vk_master_semaphore.h17
-rw-r--r--src/video_core/renderer_vulkan/vk_query_cache.cpp3
-rw-r--r--src/video_core/renderer_vulkan/vk_rasterizer.cpp16
-rw-r--r--src/video_core/renderer_vulkan/vk_state_tracker.cpp1
-rw-r--r--src/video_core/renderer_vulkan/vk_state_tracker.h3
-rw-r--r--src/video_core/texture_cache/texture_cache.h3
-rw-r--r--src/video_core/vulkan_common/vulkan_device.cpp4
-rw-r--r--src/video_core/vulkan_common/vulkan_device.h5
-rw-r--r--src/yuzu/about_dialog.cpp3
-rw-r--r--src/yuzu/applets/qt_web_browser.cpp1
-rw-r--r--src/yuzu/bootmanager.cpp6
-rw-r--r--src/yuzu/bootmanager.h8
-rw-r--r--src/yuzu/configuration/config.cpp7
-rw-r--r--src/yuzu/configuration/configure_cpu.cpp2
-rw-r--r--src/yuzu/configuration/configure_cpu_debug.cpp2
-rw-r--r--src/yuzu/configuration/configure_debug.cpp2
-rw-r--r--src/yuzu/configuration/configure_debug_tab.cpp4
-rw-r--r--src/yuzu/configuration/configure_dialog.cpp2
-rw-r--r--src/yuzu/configuration/configure_general.cpp2
-rw-r--r--src/yuzu/configuration/configure_graphics.cpp2
-rw-r--r--src/yuzu/configuration/configure_graphics_advanced.cpp2
-rw-r--r--src/yuzu/configuration/configure_per_game_addons.cpp2
-rw-r--r--src/yuzu/configuration/configure_profile_manager.cpp2
-rw-r--r--src/yuzu/configuration/configure_system.cpp12
-rw-r--r--src/yuzu/configuration/configure_tas.ui4
-rw-r--r--src/yuzu/configuration/configure_ui.cpp2
-rw-r--r--src/yuzu/main.cpp461
-rw-r--r--src/yuzu/main.h20
-rw-r--r--src/yuzu/uisettings.h2
-rw-r--r--src/yuzu_cmd/config.cpp3
-rw-r--r--src/yuzu_cmd/yuzu.cpp21
53 files changed, 549 insertions, 450 deletions
diff --git a/src/common/alignment.h b/src/common/alignment.h
index 1b56569d1..8570c7d3c 100644
--- a/src/common/alignment.h
+++ b/src/common/alignment.h
@@ -64,7 +64,7 @@ public:
64 using propagate_on_container_copy_assignment = std::true_type; 64 using propagate_on_container_copy_assignment = std::true_type;
65 using propagate_on_container_move_assignment = std::true_type; 65 using propagate_on_container_move_assignment = std::true_type;
66 using propagate_on_container_swap = std::true_type; 66 using propagate_on_container_swap = std::true_type;
67 using is_always_equal = std::true_type; 67 using is_always_equal = std::false_type;
68 68
69 constexpr AlignmentAllocator() noexcept = default; 69 constexpr AlignmentAllocator() noexcept = default;
70 70
@@ -83,6 +83,11 @@ public:
83 struct rebind { 83 struct rebind {
84 using other = AlignmentAllocator<T2, Align>; 84 using other = AlignmentAllocator<T2, Align>;
85 }; 85 };
86
87 template <typename T2, size_t Align2>
88 constexpr bool operator==(const AlignmentAllocator<T2, Align2>&) const noexcept {
89 return std::is_same_v<T, T2> && Align == Align2;
90 }
86}; 91};
87 92
88} // namespace Common 93} // namespace Common
diff --git a/src/common/settings.h b/src/common/settings.h
index 402339443..9ff4cf85d 100644
--- a/src/common/settings.h
+++ b/src/common/settings.h
@@ -7,7 +7,6 @@
7#include <algorithm> 7#include <algorithm>
8#include <array> 8#include <array>
9#include <atomic> 9#include <atomic>
10#include <chrono>
11#include <map> 10#include <map>
12#include <optional> 11#include <optional>
13#include <string> 12#include <string>
@@ -487,9 +486,9 @@ struct Values {
487 // System 486 // System
488 Setting<std::optional<u32>> rng_seed{std::optional<u32>(), "rng_seed"}; 487 Setting<std::optional<u32>> rng_seed{std::optional<u32>(), "rng_seed"};
489 // Measured in seconds since epoch 488 // Measured in seconds since epoch
490 std::optional<std::chrono::seconds> custom_rtc; 489 std::optional<s64> custom_rtc;
491 // Set on game boot, reset on stop. Seconds difference between current time and `custom_rtc` 490 // Set on game boot, reset on stop. Seconds difference between current time and `custom_rtc`
492 std::chrono::seconds custom_rtc_differential; 491 s64 custom_rtc_differential;
493 492
494 BasicSetting<s32> current_user{0, "current_user"}; 493 BasicSetting<s32> current_user{0, "current_user"};
495 RangedSetting<s32> language_index{1, 0, 17, "language_index"}; 494 RangedSetting<s32> language_index{1, 0, 17, "language_index"};
diff --git a/src/common/string_util.cpp b/src/common/string_util.cpp
index e6344fd41..662171138 100644
--- a/src/common/string_util.cpp
+++ b/src/common/string_util.cpp
@@ -180,20 +180,20 @@ std::wstring UTF8ToUTF16W(const std::string& input) {
180 180
181#endif 181#endif
182 182
183std::string StringFromFixedZeroTerminatedBuffer(const char* buffer, std::size_t max_len) { 183std::string StringFromFixedZeroTerminatedBuffer(std::string_view buffer, std::size_t max_len) {
184 std::size_t len = 0; 184 std::size_t len = 0;
185 while (len < max_len && buffer[len] != '\0') 185 while (len < buffer.length() && len < max_len && buffer[len] != '\0') {
186 ++len; 186 ++len;
187 187 }
188 return std::string(buffer, len); 188 return std::string(buffer.begin(), buffer.begin() + len);
189} 189}
190 190
191std::u16string UTF16StringFromFixedZeroTerminatedBuffer(std::u16string_view buffer, 191std::u16string UTF16StringFromFixedZeroTerminatedBuffer(std::u16string_view buffer,
192 std::size_t max_len) { 192 std::size_t max_len) {
193 std::size_t len = 0; 193 std::size_t len = 0;
194 while (len < max_len && buffer[len] != '\0') 194 while (len < buffer.length() && len < max_len && buffer[len] != '\0') {
195 ++len; 195 ++len;
196 196 }
197 return std::u16string(buffer.begin(), buffer.begin() + len); 197 return std::u16string(buffer.begin(), buffer.begin() + len);
198} 198}
199 199
diff --git a/src/common/string_util.h b/src/common/string_util.h
index 7e90a9ca5..f0dd632ee 100644
--- a/src/common/string_util.h
+++ b/src/common/string_util.h
@@ -63,7 +63,7 @@ template <typename InIt>
63 * Creates a std::string from a fixed-size NUL-terminated char buffer. If the buffer isn't 63 * Creates a std::string from a fixed-size NUL-terminated char buffer. If the buffer isn't
64 * NUL-terminated then the string ends at max_len characters. 64 * NUL-terminated then the string ends at max_len characters.
65 */ 65 */
66[[nodiscard]] std::string StringFromFixedZeroTerminatedBuffer(const char* buffer, 66[[nodiscard]] std::string StringFromFixedZeroTerminatedBuffer(std::string_view buffer,
67 std::size_t max_len); 67 std::size_t max_len);
68 68
69/** 69/**
diff --git a/src/core/arm/dynarmic/arm_dynarmic_64.cpp b/src/core/arm/dynarmic/arm_dynarmic_64.cpp
index bf27ffe71..4fd15f111 100644
--- a/src/core/arm/dynarmic/arm_dynarmic_64.cpp
+++ b/src/core/arm/dynarmic/arm_dynarmic_64.cpp
@@ -263,7 +263,7 @@ void ARM_Dynarmic_64::Run() {
263} 263}
264 264
265void ARM_Dynarmic_64::Step() { 265void ARM_Dynarmic_64::Step() {
266 cb->InterpreterFallback(jit->GetPC(), 1); 266 jit->Step();
267} 267}
268 268
269ARM_Dynarmic_64::ARM_Dynarmic_64(System& system_, CPUInterrupts& interrupt_handlers_, 269ARM_Dynarmic_64::ARM_Dynarmic_64(System& system_, CPUInterrupts& interrupt_handlers_,
diff --git a/src/core/core.cpp b/src/core/core.cpp
index bb268a319..3c75f42ae 100644
--- a/src/core/core.cpp
+++ b/src/core/core.cpp
@@ -139,27 +139,47 @@ struct System::Impl {
139 : kernel{system}, fs_controller{system}, memory{system}, 139 : kernel{system}, fs_controller{system}, memory{system},
140 cpu_manager{system}, reporter{system}, applet_manager{system}, time_manager{system} {} 140 cpu_manager{system}, reporter{system}, applet_manager{system}, time_manager{system} {}
141 141
142 ResultStatus Run() { 142 SystemResultStatus Run() {
143 status = ResultStatus::Success; 143 std::unique_lock<std::mutex> lk(suspend_guard);
144 status = SystemResultStatus::Success;
144 145
145 kernel.Suspend(false); 146 kernel.Suspend(false);
146 core_timing.SyncPause(false); 147 core_timing.SyncPause(false);
147 cpu_manager.Pause(false); 148 cpu_manager.Pause(false);
149 is_paused = false;
148 150
149 return status; 151 return status;
150 } 152 }
151 153
152 ResultStatus Pause() { 154 SystemResultStatus Pause() {
153 status = ResultStatus::Success; 155 std::unique_lock<std::mutex> lk(suspend_guard);
156 status = SystemResultStatus::Success;
154 157
155 core_timing.SyncPause(true); 158 core_timing.SyncPause(true);
156 kernel.Suspend(true); 159 kernel.Suspend(true);
157 cpu_manager.Pause(true); 160 cpu_manager.Pause(true);
161 is_paused = true;
158 162
159 return status; 163 return status;
160 } 164 }
161 165
162 ResultStatus Init(System& system, Frontend::EmuWindow& emu_window) { 166 std::unique_lock<std::mutex> StallCPU() {
167 std::unique_lock<std::mutex> lk(suspend_guard);
168 kernel.Suspend(true);
169 core_timing.SyncPause(true);
170 cpu_manager.Pause(true);
171 return lk;
172 }
173
174 void UnstallCPU() {
175 if (!is_paused) {
176 core_timing.SyncPause(false);
177 kernel.Suspend(false);
178 cpu_manager.Pause(false);
179 }
180 }
181
182 SystemResultStatus Init(System& system, Frontend::EmuWindow& emu_window) {
163 LOG_DEBUG(Core, "initialized OK"); 183 LOG_DEBUG(Core, "initialized OK");
164 184
165 device_memory = std::make_unique<Core::DeviceMemory>(); 185 device_memory = std::make_unique<Core::DeviceMemory>();
@@ -176,8 +196,9 @@ struct System::Impl {
176 cpu_manager.Initialize(); 196 cpu_manager.Initialize();
177 core_timing.Initialize([&system]() { system.RegisterHostThread(); }); 197 core_timing.Initialize([&system]() { system.RegisterHostThread(); });
178 198
179 const auto current_time = std::chrono::duration_cast<std::chrono::seconds>( 199 const auto posix_time = std::chrono::system_clock::now().time_since_epoch();
180 std::chrono::system_clock::now().time_since_epoch()); 200 const auto current_time =
201 std::chrono::duration_cast<std::chrono::seconds>(posix_time).count();
181 Settings::values.custom_rtc_differential = 202 Settings::values.custom_rtc_differential =
182 Settings::values.custom_rtc.value_or(current_time) - current_time; 203 Settings::values.custom_rtc.value_or(current_time) - current_time;
183 204
@@ -197,7 +218,7 @@ struct System::Impl {
197 218
198 gpu_core = VideoCore::CreateGPU(emu_window, system); 219 gpu_core = VideoCore::CreateGPU(emu_window, system);
199 if (!gpu_core) { 220 if (!gpu_core) {
200 return ResultStatus::ErrorVideoCore; 221 return SystemResultStatus::ErrorVideoCore;
201 } 222 }
202 223
203 service_manager = std::make_shared<Service::SM::ServiceManager>(kernel); 224 service_manager = std::make_shared<Service::SM::ServiceManager>(kernel);
@@ -217,21 +238,22 @@ struct System::Impl {
217 238
218 LOG_DEBUG(Core, "Initialized OK"); 239 LOG_DEBUG(Core, "Initialized OK");
219 240
220 return ResultStatus::Success; 241 return SystemResultStatus::Success;
221 } 242 }
222 243
223 ResultStatus Load(System& system, Frontend::EmuWindow& emu_window, const std::string& filepath, 244 SystemResultStatus Load(System& system, Frontend::EmuWindow& emu_window,
224 u64 program_id, std::size_t program_index) { 245 const std::string& filepath, u64 program_id,
246 std::size_t program_index) {
225 app_loader = Loader::GetLoader(system, GetGameFileFromPath(virtual_filesystem, filepath), 247 app_loader = Loader::GetLoader(system, GetGameFileFromPath(virtual_filesystem, filepath),
226 program_id, program_index); 248 program_id, program_index);
227 249
228 if (!app_loader) { 250 if (!app_loader) {
229 LOG_CRITICAL(Core, "Failed to obtain loader for {}!", filepath); 251 LOG_CRITICAL(Core, "Failed to obtain loader for {}!", filepath);
230 return ResultStatus::ErrorGetLoader; 252 return SystemResultStatus::ErrorGetLoader;
231 } 253 }
232 254
233 ResultStatus init_result{Init(system, emu_window)}; 255 SystemResultStatus init_result{Init(system, emu_window)};
234 if (init_result != ResultStatus::Success) { 256 if (init_result != SystemResultStatus::Success) {
235 LOG_CRITICAL(Core, "Failed to initialize system (Error {})!", 257 LOG_CRITICAL(Core, "Failed to initialize system (Error {})!",
236 static_cast<int>(init_result)); 258 static_cast<int>(init_result));
237 Shutdown(); 259 Shutdown();
@@ -249,8 +271,8 @@ struct System::Impl {
249 LOG_CRITICAL(Core, "Failed to load ROM (Error {})!", load_result); 271 LOG_CRITICAL(Core, "Failed to load ROM (Error {})!", load_result);
250 Shutdown(); 272 Shutdown();
251 273
252 return static_cast<ResultStatus>(static_cast<u32>(ResultStatus::ErrorLoader) + 274 return static_cast<SystemResultStatus>(
253 static_cast<u32>(load_result)); 275 static_cast<u32>(SystemResultStatus::ErrorLoader) + static_cast<u32>(load_result));
254 } 276 }
255 AddGlueRegistrationForProcess(*app_loader, *main_process); 277 AddGlueRegistrationForProcess(*app_loader, *main_process);
256 kernel.MakeCurrentProcess(main_process.get()); 278 kernel.MakeCurrentProcess(main_process.get());
@@ -282,7 +304,7 @@ struct System::Impl {
282 GetAndResetPerfStats(); 304 GetAndResetPerfStats();
283 perf_stats->BeginSystemFrame(); 305 perf_stats->BeginSystemFrame();
284 306
285 status = ResultStatus::Success; 307 status = SystemResultStatus::Success;
286 return status; 308 return status;
287 } 309 }
288 310
@@ -355,7 +377,7 @@ struct System::Impl {
355 arp_manager.Register(launch.title_id, launch, std::move(nacp_data)); 377 arp_manager.Register(launch.title_id, launch, std::move(nacp_data));
356 } 378 }
357 379
358 void SetStatus(ResultStatus new_status, const char* details = nullptr) { 380 void SetStatus(SystemResultStatus new_status, const char* details = nullptr) {
359 status = new_status; 381 status = new_status;
360 if (details) { 382 if (details) {
361 status_details = details; 383 status_details = details;
@@ -366,6 +388,9 @@ struct System::Impl {
366 return perf_stats->GetAndResetStats(core_timing.GetGlobalTimeUs()); 388 return perf_stats->GetAndResetStats(core_timing.GetGlobalTimeUs());
367 } 389 }
368 390
391 std::mutex suspend_guard;
392 bool is_paused{};
393
369 Timing::CoreTiming core_timing; 394 Timing::CoreTiming core_timing;
370 Kernel::KernelCore kernel; 395 Kernel::KernelCore kernel;
371 /// RealVfsFilesystem instance 396 /// RealVfsFilesystem instance
@@ -411,7 +436,7 @@ struct System::Impl {
411 /// Network instance 436 /// Network instance
412 Network::NetworkInstance network_instance; 437 Network::NetworkInstance network_instance;
413 438
414 ResultStatus status = ResultStatus::Success; 439 SystemResultStatus status = SystemResultStatus::Success;
415 std::string status_details = ""; 440 std::string status_details = "";
416 441
417 std::unique_ptr<Core::PerfStats> perf_stats; 442 std::unique_ptr<Core::PerfStats> perf_stats;
@@ -428,21 +453,8 @@ struct System::Impl {
428}; 453};
429 454
430System::System() : impl{std::make_unique<Impl>(*this)} {} 455System::System() : impl{std::make_unique<Impl>(*this)} {}
431System::~System() = default;
432 456
433System& System::GetInstance() { 457System::~System() = default;
434 if (!s_instance) {
435 throw std::runtime_error("Using System instance before its initialization");
436 }
437 return *s_instance;
438}
439
440void System::InitializeGlobalInstance() {
441 if (s_instance) {
442 throw std::runtime_error("Reinitializing Global System instance.");
443 }
444 s_instance = std::unique_ptr<System>(new System);
445}
446 458
447CpuManager& System::GetCpuManager() { 459CpuManager& System::GetCpuManager() {
448 return impl->cpu_manager; 460 return impl->cpu_manager;
@@ -452,16 +464,16 @@ const CpuManager& System::GetCpuManager() const {
452 return impl->cpu_manager; 464 return impl->cpu_manager;
453} 465}
454 466
455System::ResultStatus System::Run() { 467SystemResultStatus System::Run() {
456 return impl->Run(); 468 return impl->Run();
457} 469}
458 470
459System::ResultStatus System::Pause() { 471SystemResultStatus System::Pause() {
460 return impl->Pause(); 472 return impl->Pause();
461} 473}
462 474
463System::ResultStatus System::SingleStep() { 475SystemResultStatus System::SingleStep() {
464 return ResultStatus::Success; 476 return SystemResultStatus::Success;
465} 477}
466 478
467void System::InvalidateCpuInstructionCaches() { 479void System::InvalidateCpuInstructionCaches() {
@@ -476,8 +488,16 @@ void System::Shutdown() {
476 impl->Shutdown(); 488 impl->Shutdown();
477} 489}
478 490
479System::ResultStatus System::Load(Frontend::EmuWindow& emu_window, const std::string& filepath, 491std::unique_lock<std::mutex> System::StallCPU() {
480 u64 program_id, std::size_t program_index) { 492 return impl->StallCPU();
493}
494
495void System::UnstallCPU() {
496 impl->UnstallCPU();
497}
498
499SystemResultStatus System::Load(Frontend::EmuWindow& emu_window, const std::string& filepath,
500 u64 program_id, std::size_t program_index) {
481 return impl->Load(*this, emu_window, filepath, program_id, program_index); 501 return impl->Load(*this, emu_window, filepath, program_id, program_index);
482} 502}
483 503
@@ -637,7 +657,7 @@ Loader::ResultStatus System::GetGameName(std::string& out) const {
637 return impl->GetGameName(out); 657 return impl->GetGameName(out);
638} 658}
639 659
640void System::SetStatus(ResultStatus new_status, const char* details) { 660void System::SetStatus(SystemResultStatus new_status, const char* details) {
641 impl->SetStatus(new_status, details); 661 impl->SetStatus(new_status, details);
642} 662}
643 663
diff --git a/src/core/core.h b/src/core/core.h
index a796472b2..1cfe1bba6 100644
--- a/src/core/core.h
+++ b/src/core/core.h
@@ -7,6 +7,7 @@
7#include <cstddef> 7#include <cstddef>
8#include <functional> 8#include <functional>
9#include <memory> 9#include <memory>
10#include <mutex>
10#include <string> 11#include <string>
11#include <vector> 12#include <vector>
12 13
@@ -104,55 +105,49 @@ struct PerfStatsResults;
104FileSys::VirtualFile GetGameFileFromPath(const FileSys::VirtualFilesystem& vfs, 105FileSys::VirtualFile GetGameFileFromPath(const FileSys::VirtualFilesystem& vfs,
105 const std::string& path); 106 const std::string& path);
106 107
108/// Enumeration representing the return values of the System Initialize and Load process.
109enum class SystemResultStatus : u32 {
110 Success, ///< Succeeded
111 ErrorNotInitialized, ///< Error trying to use core prior to initialization
112 ErrorGetLoader, ///< Error finding the correct application loader
113 ErrorSystemFiles, ///< Error in finding system files
114 ErrorSharedFont, ///< Error in finding shared font
115 ErrorVideoCore, ///< Error in the video core
116 ErrorUnknown, ///< Any other error
117 ErrorLoader, ///< The base for loader errors (too many to repeat)
118};
119
107class System { 120class System {
108public: 121public:
109 using CurrentBuildProcessID = std::array<u8, 0x20>; 122 using CurrentBuildProcessID = std::array<u8, 0x20>;
110 123
124 explicit System();
125
126 ~System();
127
111 System(const System&) = delete; 128 System(const System&) = delete;
112 System& operator=(const System&) = delete; 129 System& operator=(const System&) = delete;
113 130
114 System(System&&) = delete; 131 System(System&&) = delete;
115 System& operator=(System&&) = delete; 132 System& operator=(System&&) = delete;
116 133
117 ~System();
118
119 /**
120 * Gets the instance of the System singleton class.
121 * @returns Reference to the instance of the System singleton class.
122 */
123 [[deprecated("Use of the global system instance is deprecated")]] static System& GetInstance();
124
125 static void InitializeGlobalInstance();
126
127 /// Enumeration representing the return values of the System Initialize and Load process.
128 enum class ResultStatus : u32 {
129 Success, ///< Succeeded
130 ErrorNotInitialized, ///< Error trying to use core prior to initialization
131 ErrorGetLoader, ///< Error finding the correct application loader
132 ErrorSystemFiles, ///< Error in finding system files
133 ErrorSharedFont, ///< Error in finding shared font
134 ErrorVideoCore, ///< Error in the video core
135 ErrorUnknown, ///< Any other error
136 ErrorLoader, ///< The base for loader errors (too many to repeat)
137 };
138
139 /** 134 /**
140 * Run the OS and Application 135 * Run the OS and Application
141 * This function will start emulation and run the relevant devices 136 * This function will start emulation and run the relevant devices
142 */ 137 */
143 [[nodiscard]] ResultStatus Run(); 138 [[nodiscard]] SystemResultStatus Run();
144 139
145 /** 140 /**
146 * Pause the OS and Application 141 * Pause the OS and Application
147 * This function will pause emulation and stop the relevant devices 142 * This function will pause emulation and stop the relevant devices
148 */ 143 */
149 [[nodiscard]] ResultStatus Pause(); 144 [[nodiscard]] SystemResultStatus Pause();
150 145
151 /** 146 /**
152 * Step the CPU one instruction 147 * Step the CPU one instruction
153 * @return Result status, indicating whether or not the operation succeeded. 148 * @return Result status, indicating whether or not the operation succeeded.
154 */ 149 */
155 [[nodiscard]] ResultStatus SingleStep(); 150 [[nodiscard]] SystemResultStatus SingleStep();
156 151
157 /** 152 /**
158 * Invalidate the CPU instruction caches 153 * Invalidate the CPU instruction caches
@@ -166,16 +161,20 @@ public:
166 /// Shutdown the emulated system. 161 /// Shutdown the emulated system.
167 void Shutdown(); 162 void Shutdown();
168 163
164 std::unique_lock<std::mutex> StallCPU();
165 void UnstallCPU();
166
169 /** 167 /**
170 * Load an executable application. 168 * Load an executable application.
171 * @param emu_window Reference to the host-system window used for video output and keyboard 169 * @param emu_window Reference to the host-system window used for video output and keyboard
172 * input. 170 * input.
173 * @param filepath String path to the executable application to load on the host file system. 171 * @param filepath String path to the executable application to load on the host file system.
174 * @param program_index Specifies the index within the container of the program to launch. 172 * @param program_index Specifies the index within the container of the program to launch.
175 * @returns ResultStatus code, indicating if the operation succeeded. 173 * @returns SystemResultStatus code, indicating if the operation succeeded.
176 */ 174 */
177 [[nodiscard]] ResultStatus Load(Frontend::EmuWindow& emu_window, const std::string& filepath, 175 [[nodiscard]] SystemResultStatus Load(Frontend::EmuWindow& emu_window,
178 u64 program_id = 0, std::size_t program_index = 0); 176 const std::string& filepath, u64 program_id = 0,
177 std::size_t program_index = 0);
179 178
180 /** 179 /**
181 * Indicates if the emulated system is powered on (all subsystems initialized and able to run an 180 * Indicates if the emulated system is powered on (all subsystems initialized and able to run an
@@ -301,7 +300,7 @@ public:
301 /// Gets the name of the current game 300 /// Gets the name of the current game
302 [[nodiscard]] Loader::ResultStatus GetGameName(std::string& out) const; 301 [[nodiscard]] Loader::ResultStatus GetGameName(std::string& out) const;
303 302
304 void SetStatus(ResultStatus new_status, const char* details); 303 void SetStatus(SystemResultStatus new_status, const char* details);
305 304
306 [[nodiscard]] const std::string& GetStatusDetails() const; 305 [[nodiscard]] const std::string& GetStatusDetails() const;
307 306
@@ -403,12 +402,8 @@ public:
403 void ApplySettings(); 402 void ApplySettings();
404 403
405private: 404private:
406 System();
407
408 struct Impl; 405 struct Impl;
409 std::unique_ptr<Impl> impl; 406 std::unique_ptr<Impl> impl;
410
411 inline static std::unique_ptr<System> s_instance{};
412}; 407};
413 408
414} // namespace Core 409} // namespace Core
diff --git a/src/core/hle/kernel/k_page_table.cpp b/src/core/hle/kernel/k_page_table.cpp
index 701268545..5e0b620c2 100644
--- a/src/core/hle/kernel/k_page_table.cpp
+++ b/src/core/hle/kernel/k_page_table.cpp
@@ -363,6 +363,8 @@ ResultCode KPageTable::UnmapProcessCodeMemory(VAddr dst_addr, VAddr src_addr, st
363 block_manager->Update(src_addr, num_pages, KMemoryState::Normal, 363 block_manager->Update(src_addr, num_pages, KMemoryState::Normal,
364 KMemoryPermission::ReadAndWrite); 364 KMemoryPermission::ReadAndWrite);
365 365
366 system.InvalidateCpuInstructionCacheRange(dst_addr, size);
367
366 return ResultSuccess; 368 return ResultSuccess;
367} 369}
368 370
diff --git a/src/core/hle/kernel/k_scheduler.h b/src/core/hle/kernel/k_scheduler.h
index c8ccc1ae4..7df288438 100644
--- a/src/core/hle/kernel/k_scheduler.h
+++ b/src/core/hle/kernel/k_scheduler.h
@@ -49,6 +49,11 @@ public:
49 /// Gets the current running thread 49 /// Gets the current running thread
50 [[nodiscard]] KThread* GetCurrentThread() const; 50 [[nodiscard]] KThread* GetCurrentThread() const;
51 51
52 /// Gets the idle thread
53 [[nodiscard]] KThread* GetIdleThread() const {
54 return idle_thread;
55 }
56
52 /// Returns true if the scheduler is idle 57 /// Returns true if the scheduler is idle
53 [[nodiscard]] bool IsIdle() const { 58 [[nodiscard]] bool IsIdle() const {
54 return GetCurrentThread() == idle_thread; 59 return GetCurrentThread() == idle_thread;
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp
index f98f24a60..7f38ade1c 100644
--- a/src/core/hle/kernel/svc.cpp
+++ b/src/core/hle/kernel/svc.cpp
@@ -886,7 +886,24 @@ static ResultCode GetInfo(Core::System& system, u64* result, u64 info_id, Handle
886 *result = out_ticks; 886 *result = out_ticks;
887 return ResultSuccess; 887 return ResultSuccess;
888 } 888 }
889 case GetInfoType::IdleTickCount: {
890 if (handle == 0) {
891 LOG_ERROR(Kernel_SVC, "Thread handle does not exist, handle=0x{:08X}",
892 static_cast<Handle>(handle));
893 return ResultInvalidHandle;
894 }
889 895
896 if (info_sub_id != 0xFFFFFFFFFFFFFFFF && info_sub_id != system.CurrentCoreIndex()) {
897 LOG_ERROR(Kernel_SVC, "Core is not the current core, got {}", info_sub_id);
898 return ResultInvalidCombination;
899 }
900
901 const auto& scheduler = *system.Kernel().CurrentScheduler();
902 const auto* const idle_thread = scheduler.GetIdleThread();
903
904 *result = idle_thread->GetCpuTime();
905 return ResultSuccess;
906 }
890 default: 907 default:
891 LOG_ERROR(Kernel_SVC, "Unimplemented svcGetInfo id=0x{:016X}", info_id); 908 LOG_ERROR(Kernel_SVC, "Unimplemented svcGetInfo id=0x{:016X}", info_id);
892 return ResultInvalidEnumValue; 909 return ResultInvalidEnumValue;
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp
index 8b4867ca7..f9b82b504 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp
@@ -92,6 +92,7 @@ NvResult nvhost_ctrl::IocCtrlEventWait(const std::vector<u8>& input, std::vector
92 if (syncpoint_manager.IsSyncpointExpired(params.syncpt_id, params.threshold)) { 92 if (syncpoint_manager.IsSyncpointExpired(params.syncpt_id, params.threshold)) {
93 params.value = syncpoint_manager.GetSyncpointMin(params.syncpt_id); 93 params.value = syncpoint_manager.GetSyncpointMin(params.syncpt_id);
94 std::memcpy(output.data(), &params, sizeof(params)); 94 std::memcpy(output.data(), &params, sizeof(params));
95 events_interface.failed[event_id] = false;
95 return NvResult::Success; 96 return NvResult::Success;
96 } 97 }
97 98
@@ -99,6 +100,7 @@ NvResult nvhost_ctrl::IocCtrlEventWait(const std::vector<u8>& input, std::vector
99 syncpoint_manager.IsSyncpointExpired(params.syncpt_id, params.threshold)) { 100 syncpoint_manager.IsSyncpointExpired(params.syncpt_id, params.threshold)) {
100 params.value = new_value; 101 params.value = new_value;
101 std::memcpy(output.data(), &params, sizeof(params)); 102 std::memcpy(output.data(), &params, sizeof(params));
103 events_interface.failed[event_id] = false;
102 return NvResult::Success; 104 return NvResult::Success;
103 } 105 }
104 106
@@ -117,6 +119,7 @@ NvResult nvhost_ctrl::IocCtrlEventWait(const std::vector<u8>& input, std::vector
117 event.event->GetWritableEvent().Signal(); 119 event.event->GetWritableEvent().Signal();
118 params.value = current_syncpoint_value; 120 params.value = current_syncpoint_value;
119 std::memcpy(output.data(), &params, sizeof(params)); 121 std::memcpy(output.data(), &params, sizeof(params));
122 events_interface.failed[event_id] = false;
120 return NvResult::Success; 123 return NvResult::Success;
121 } 124 }
122 const u32 target_value = current_syncpoint_value - diff; 125 const u32 target_value = current_syncpoint_value - diff;
@@ -146,6 +149,16 @@ NvResult nvhost_ctrl::IocCtrlEventWait(const std::vector<u8>& input, std::vector
146 } 149 }
147 params.value |= event_id; 150 params.value |= event_id;
148 event.event->GetWritableEvent().Clear(); 151 event.event->GetWritableEvent().Clear();
152 if (events_interface.failed[event_id]) {
153 {
154 auto lk = system.StallCPU();
155 gpu.WaitFence(params.syncpt_id, target_value);
156 system.UnstallCPU();
157 }
158 std::memcpy(output.data(), &params, sizeof(params));
159 events_interface.failed[event_id] = false;
160 return NvResult::Success;
161 }
149 gpu.RegisterSyncptInterrupt(params.syncpt_id, target_value); 162 gpu.RegisterSyncptInterrupt(params.syncpt_id, target_value);
150 std::memcpy(output.data(), &params, sizeof(params)); 163 std::memcpy(output.data(), &params, sizeof(params));
151 return NvResult::Timeout; 164 return NvResult::Timeout;
@@ -201,6 +214,7 @@ NvResult nvhost_ctrl::IocCtrlClearEventWait(const std::vector<u8>& input, std::v
201 if (events_interface.status[event_id] == EventState::Waiting) { 214 if (events_interface.status[event_id] == EventState::Waiting) {
202 events_interface.LiberateEvent(event_id); 215 events_interface.LiberateEvent(event_id);
203 } 216 }
217 events_interface.failed[event_id] = true;
204 218
205 syncpoint_manager.RefreshSyncpoint(events_interface.events[event_id].fence.id); 219 syncpoint_manager.RefreshSyncpoint(events_interface.events[event_id].fence.id);
206 220
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 845de724d..e61261f98 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp
@@ -69,8 +69,7 @@ NvResult nvhost_nvdec_common::Submit(const std::vector<u8>& input, std::vector<u
69 std::vector<Reloc> relocs(params.relocation_count); 69 std::vector<Reloc> relocs(params.relocation_count);
70 std::vector<u32> reloc_shifts(params.relocation_count); 70 std::vector<u32> reloc_shifts(params.relocation_count);
71 std::vector<SyncptIncr> syncpt_increments(params.syncpoint_count); 71 std::vector<SyncptIncr> syncpt_increments(params.syncpoint_count);
72 std::vector<SyncptIncr> wait_checks(params.syncpoint_count); 72 std::vector<u32> fence_thresholds(params.fence_count);
73 std::vector<Fence> fences(params.fence_count);
74 73
75 // Slice input into their respective buffers 74 // Slice input into their respective buffers
76 std::size_t offset = sizeof(IoctlSubmit); 75 std::size_t offset = sizeof(IoctlSubmit);
@@ -78,15 +77,13 @@ NvResult nvhost_nvdec_common::Submit(const std::vector<u8>& input, std::vector<u
78 offset += SliceVectors(input, relocs, params.relocation_count, offset); 77 offset += SliceVectors(input, relocs, params.relocation_count, offset);
79 offset += SliceVectors(input, reloc_shifts, params.relocation_count, offset); 78 offset += SliceVectors(input, reloc_shifts, params.relocation_count, offset);
80 offset += SliceVectors(input, syncpt_increments, params.syncpoint_count, offset); 79 offset += SliceVectors(input, syncpt_increments, params.syncpoint_count, offset);
81 offset += SliceVectors(input, wait_checks, params.syncpoint_count, offset); 80 offset += SliceVectors(input, fence_thresholds, params.fence_count, offset);
82 offset += SliceVectors(input, fences, params.fence_count, offset);
83 81
84 auto& gpu = system.GPU(); 82 auto& gpu = system.GPU();
85 if (gpu.UseNvdec()) { 83 if (gpu.UseNvdec()) {
86 for (std::size_t i = 0; i < syncpt_increments.size(); i++) { 84 for (std::size_t i = 0; i < syncpt_increments.size(); i++) {
87 const SyncptIncr& syncpt_incr = syncpt_increments[i]; 85 const SyncptIncr& syncpt_incr = syncpt_increments[i];
88 fences[i].id = syncpt_incr.id; 86 fence_thresholds[i] =
89 fences[i].value =
90 syncpoint_manager.IncreaseSyncpoint(syncpt_incr.id, syncpt_incr.increments); 87 syncpoint_manager.IncreaseSyncpoint(syncpt_incr.id, syncpt_incr.increments);
91 } 88 }
92 } 89 }
@@ -98,11 +95,6 @@ NvResult nvhost_nvdec_common::Submit(const std::vector<u8>& input, std::vector<u
98 cmdlist.size() * sizeof(u32)); 95 cmdlist.size() * sizeof(u32));
99 gpu.PushCommandBuffer(cmdlist); 96 gpu.PushCommandBuffer(cmdlist);
100 } 97 }
101 if (gpu.UseNvdec()) {
102 fences[0].value = syncpoint_manager.IncreaseSyncpoint(fences[0].id, 1);
103 Tegra::ChCommandHeaderList cmdlist{{(4 << 28) | fences[0].id}};
104 gpu.PushCommandBuffer(cmdlist);
105 }
106 std::memcpy(output.data(), &params, sizeof(IoctlSubmit)); 98 std::memcpy(output.data(), &params, sizeof(IoctlSubmit));
107 // Some games expect command_buffers to be written back 99 // Some games expect command_buffers to be written back
108 offset = sizeof(IoctlSubmit); 100 offset = sizeof(IoctlSubmit);
@@ -110,8 +102,7 @@ NvResult nvhost_nvdec_common::Submit(const std::vector<u8>& input, std::vector<u
110 offset += WriteVectors(output, relocs, offset); 102 offset += WriteVectors(output, relocs, offset);
111 offset += WriteVectors(output, reloc_shifts, offset); 103 offset += WriteVectors(output, reloc_shifts, offset);
112 offset += WriteVectors(output, syncpt_increments, offset); 104 offset += WriteVectors(output, syncpt_increments, offset);
113 offset += WriteVectors(output, wait_checks, offset); 105 offset += WriteVectors(output, fence_thresholds, offset);
114 offset += WriteVectors(output, fences, offset);
115 106
116 return NvResult::Success; 107 return NvResult::Success;
117} 108}
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.h b/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.h
index af59f00d2..ae4199b79 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.h
+++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.h
@@ -56,19 +56,16 @@ protected:
56 s32 target{}; 56 s32 target{};
57 s32 target_offset{}; 57 s32 target_offset{};
58 }; 58 };
59 static_assert(sizeof(Reloc) == 0x10, "CommandBuffer has incorrect size"); 59 static_assert(sizeof(Reloc) == 0x10, "Reloc has incorrect size");
60 60
61 struct SyncptIncr { 61 struct SyncptIncr {
62 u32 id{}; 62 u32 id{};
63 u32 increments{}; 63 u32 increments{};
64 u32 unk0{};
65 u32 unk1{};
66 u32 unk2{};
64 }; 67 };
65 static_assert(sizeof(SyncptIncr) == 0x8, "CommandBuffer has incorrect size"); 68 static_assert(sizeof(SyncptIncr) == 0x14, "SyncptIncr has incorrect size");
66
67 struct Fence {
68 u32 id{};
69 u32 value{};
70 };
71 static_assert(sizeof(Fence) == 0x8, "CommandBuffer has incorrect size");
72 69
73 struct IoctlGetSyncpoint { 70 struct IoctlGetSyncpoint {
74 // Input 71 // Input
diff --git a/src/core/hle/service/nvdrv/nvdrv.h b/src/core/hle/service/nvdrv/nvdrv.h
index e2a1dde5b..a5af5b785 100644
--- a/src/core/hle/service/nvdrv/nvdrv.h
+++ b/src/core/hle/service/nvdrv/nvdrv.h
@@ -49,6 +49,8 @@ struct EventInterface {
49 std::array<EventState, MaxNvEvents> status{}; 49 std::array<EventState, MaxNvEvents> status{};
50 // Tells if an NVEvent is registered or not 50 // Tells if an NVEvent is registered or not
51 std::array<bool, MaxNvEvents> registered{}; 51 std::array<bool, MaxNvEvents> registered{};
52 // Tells the NVEvent that it has failed.
53 std::array<bool, MaxNvEvents> failed{};
52 // When an NVEvent is waiting on GPU interrupt, this is the sync_point 54 // When an NVEvent is waiting on GPU interrupt, this is the sync_point
53 // associated with it. 55 // associated with it.
54 std::array<u32, MaxNvEvents> assigned_syncpt{}; 56 std::array<u32, MaxNvEvents> assigned_syncpt{};
diff --git a/src/core/hle/service/time/time_manager.cpp b/src/core/hle/service/time/time_manager.cpp
index 4bbc606a1..9c4c960ef 100644
--- a/src/core/hle/service/time/time_manager.cpp
+++ b/src/core/hle/service/time/time_manager.cpp
@@ -13,18 +13,19 @@
13#include "core/hle/service/time/time_manager.h" 13#include "core/hle/service/time/time_manager.h"
14 14
15namespace Service::Time { 15namespace Service::Time {
16 16namespace {
17constexpr Clock::TimeSpanType standard_network_clock_accuracy{0x0009356907420000ULL}; 17constexpr Clock::TimeSpanType standard_network_clock_accuracy{0x0009356907420000ULL};
18 18
19static std::chrono::seconds GetSecondsSinceEpoch() { 19s64 GetSecondsSinceEpoch() {
20 return std::chrono::duration_cast<std::chrono::seconds>( 20 const auto time_since_epoch = std::chrono::system_clock::now().time_since_epoch();
21 std::chrono::system_clock::now().time_since_epoch()) + 21 return std::chrono::duration_cast<std::chrono::seconds>(time_since_epoch).count() +
22 Settings::values.custom_rtc_differential; 22 Settings::values.custom_rtc_differential;
23} 23}
24 24
25static s64 GetExternalRtcValue() { 25s64 GetExternalRtcValue() {
26 return GetSecondsSinceEpoch().count() + TimeManager::GetExternalTimeZoneOffset(); 26 return GetSecondsSinceEpoch() + TimeManager::GetExternalTimeZoneOffset();
27} 27}
28} // Anonymous namespace
28 29
29struct TimeManager::Impl final { 30struct TimeManager::Impl final {
30 explicit Impl(Core::System& system) 31 explicit Impl(Core::System& system)
diff --git a/src/core/hle/service/vi/vi.cpp b/src/core/hle/service/vi/vi.cpp
index be3d52d54..439e7e472 100644
--- a/src/core/hle/service/vi/vi.cpp
+++ b/src/core/hle/service/vi/vi.cpp
@@ -524,7 +524,9 @@ private:
524 Disconnect = 11, 524 Disconnect = 11,
525 525
526 AllocateBuffers = 13, 526 AllocateBuffers = 13,
527 SetPreallocatedBuffer = 14 527 SetPreallocatedBuffer = 14,
528
529 GetBufferHistory = 17
528 }; 530 };
529 531
530 void TransactParcel(Kernel::HLERequestContext& ctx) { 532 void TransactParcel(Kernel::HLERequestContext& ctx) {
@@ -641,6 +643,14 @@ private:
641 ctx.WriteBuffer(response.Serialize()); 643 ctx.WriteBuffer(response.Serialize());
642 break; 644 break;
643 } 645 }
646 case TransactionId::GetBufferHistory: {
647 LOG_WARNING(Service_VI, "(STUBBED) called, transaction=GetBufferHistory");
648 [[maybe_unused]] const auto buffer = ctx.ReadBuffer();
649
650 IGBPEmptyResponseParcel response{};
651 ctx.WriteBuffer(response.Serialize());
652 break;
653 }
644 default: 654 default:
645 ASSERT_MSG(false, "Unimplemented"); 655 ASSERT_MSG(false, "Unimplemented");
646 } 656 }
diff --git a/src/input_common/udp/client.cpp b/src/input_common/udp/client.cpp
index 9b0aec797..b9512aa2e 100644
--- a/src/input_common/udp/client.cpp
+++ b/src/input_common/udp/client.cpp
@@ -471,46 +471,42 @@ CalibrationConfigurationJob::CalibrationConfigurationJob(
471 std::function<void(u16, u16, u16, u16)> data_callback) { 471 std::function<void(u16, u16, u16, u16)> data_callback) {
472 472
473 std::thread([=, this] { 473 std::thread([=, this] {
474 constexpr u16 CALIBRATION_THRESHOLD = 100;
475
476 u16 min_x{UINT16_MAX};
477 u16 min_y{UINT16_MAX};
478 u16 max_x{};
479 u16 max_y{};
480
481 Status current_status{Status::Initialized}; 474 Status current_status{Status::Initialized};
482 SocketCallback callback{[](Response::Version) {}, [](Response::PortInfo) {}, 475 SocketCallback callback{
483 [&](Response::PadData data) { 476 [](Response::Version) {}, [](Response::PortInfo) {},
484 if (current_status == Status::Initialized) { 477 [&](Response::PadData data) {
485 // Receiving data means the communication is ready now 478 static constexpr u16 CALIBRATION_THRESHOLD = 100;
486 current_status = Status::Ready; 479 static constexpr u16 MAX_VALUE = UINT16_MAX;
487 status_callback(current_status); 480
488 } 481 if (current_status == Status::Initialized) {
489 if (data.touch[0].is_active == 0) { 482 // Receiving data means the communication is ready now
490 return; 483 current_status = Status::Ready;
491 } 484 status_callback(current_status);
492 LOG_DEBUG(Input, "Current touch: {} {}", data.touch[0].x, 485 }
493 data.touch[0].y); 486 const auto& touchpad_0 = data.touch[0];
494 min_x = std::min(min_x, static_cast<u16>(data.touch[0].x)); 487 if (touchpad_0.is_active == 0) {
495 min_y = std::min(min_y, static_cast<u16>(data.touch[0].y)); 488 return;
496 if (current_status == Status::Ready) { 489 }
497 // First touch - min data (min_x/min_y) 490 LOG_DEBUG(Input, "Current touch: {} {}", touchpad_0.x, touchpad_0.y);
498 current_status = Status::Stage1Completed; 491 const u16 min_x = std::min(MAX_VALUE, static_cast<u16>(touchpad_0.x));
499 status_callback(current_status); 492 const u16 min_y = std::min(MAX_VALUE, static_cast<u16>(touchpad_0.y));
500 } 493 if (current_status == Status::Ready) {
501 if (data.touch[0].x - min_x > CALIBRATION_THRESHOLD && 494 // First touch - min data (min_x/min_y)
502 data.touch[0].y - min_y > CALIBRATION_THRESHOLD) { 495 current_status = Status::Stage1Completed;
503 // Set the current position as max value and finishes 496 status_callback(current_status);
504 // configuration 497 }
505 max_x = data.touch[0].x; 498 if (touchpad_0.x - min_x > CALIBRATION_THRESHOLD &&
506 max_y = data.touch[0].y; 499 touchpad_0.y - min_y > CALIBRATION_THRESHOLD) {
507 current_status = Status::Completed; 500 // Set the current position as max value and finishes configuration
508 data_callback(min_x, min_y, max_x, max_y); 501 const u16 max_x = touchpad_0.x;
509 status_callback(current_status); 502 const u16 max_y = touchpad_0.y;
510 503 current_status = Status::Completed;
511 complete_event.Set(); 504 data_callback(min_x, min_y, max_x, max_y);
512 } 505 status_callback(current_status);
513 }}; 506
507 complete_event.Set();
508 }
509 }};
514 Socket socket{host, port, std::move(callback)}; 510 Socket socket{host, port, std::move(callback)};
515 std::thread worker_thread{SocketLoop, &socket}; 511 std::thread worker_thread{SocketLoop, &socket};
516 complete_event.Wait(); 512 complete_event.Wait();
diff --git a/src/shader_recompiler/ir_opt/texture_pass.cpp b/src/shader_recompiler/ir_opt/texture_pass.cpp
index 44ad10d43..96c997a58 100644
--- a/src/shader_recompiler/ir_opt/texture_pass.cpp
+++ b/src/shader_recompiler/ir_opt/texture_pass.cpp
@@ -492,7 +492,8 @@ void TexturePass(Environment& env, IR::Program& program) {
492 const auto insert_point{IR::Block::InstructionList::s_iterator_to(*inst)}; 492 const auto insert_point{IR::Block::InstructionList::s_iterator_to(*inst)};
493 IR::IREmitter ir{*texture_inst.block, insert_point}; 493 IR::IREmitter ir{*texture_inst.block, insert_point};
494 const IR::U32 shift{ir.Imm32(std::countr_zero(DESCRIPTOR_SIZE))}; 494 const IR::U32 shift{ir.Imm32(std::countr_zero(DESCRIPTOR_SIZE))};
495 inst->SetArg(0, ir.ShiftRightArithmetic(cbuf.dynamic_offset, shift)); 495 inst->SetArg(0, ir.UMin(ir.ShiftRightArithmetic(cbuf.dynamic_offset, shift),
496 ir.Imm32(DESCRIPTOR_SIZE - 1)));
496 } else { 497 } else {
497 inst->SetArg(0, IR::Value{}); 498 inst->SetArg(0, IR::Value{});
498 } 499 }
diff --git a/src/video_core/dirty_flags.h b/src/video_core/dirty_flags.h
index 504465d3f..f0d545f90 100644
--- a/src/video_core/dirty_flags.h
+++ b/src/video_core/dirty_flags.h
@@ -38,6 +38,9 @@ enum : u8 {
38 38
39 Shaders, 39 Shaders,
40 40
41 // Special entries
42 DepthBiasGlobal,
43
41 LastCommonEntry, 44 LastCommonEntry,
42}; 45};
43 46
diff --git a/src/video_core/query_cache.h b/src/video_core/query_cache.h
index 73231061a..392f82eb7 100644
--- a/src/video_core/query_cache.h
+++ b/src/video_core/query_cache.h
@@ -258,9 +258,9 @@ private:
258 258
259 void AsyncFlushQuery(VAddr addr) { 259 void AsyncFlushQuery(VAddr addr) {
260 if (!uncommitted_flushes) { 260 if (!uncommitted_flushes) {
261 uncommitted_flushes = std::make_shared<std::unordered_set<VAddr>>(); 261 uncommitted_flushes = std::make_shared<std::vector<VAddr>>();
262 } 262 }
263 uncommitted_flushes->insert(addr); 263 uncommitted_flushes->push_back(addr);
264 } 264 }
265 265
266 static constexpr std::uintptr_t PAGE_SIZE = 4096; 266 static constexpr std::uintptr_t PAGE_SIZE = 4096;
@@ -276,8 +276,8 @@ private:
276 276
277 std::array<CounterStream, VideoCore::NumQueryTypes> streams; 277 std::array<CounterStream, VideoCore::NumQueryTypes> streams;
278 278
279 std::shared_ptr<std::unordered_set<VAddr>> uncommitted_flushes{}; 279 std::shared_ptr<std::vector<VAddr>> uncommitted_flushes{};
280 std::list<std::shared_ptr<std::unordered_set<VAddr>>> committed_flushes; 280 std::list<std::shared_ptr<std::vector<VAddr>>> committed_flushes;
281}; 281};
282 282
283template <class QueryCache, class HostCounter> 283template <class QueryCache, class HostCounter>
diff --git a/src/video_core/rasterizer_accelerated.h b/src/video_core/rasterizer_accelerated.h
index ea879bfdd..249644e50 100644
--- a/src/video_core/rasterizer_accelerated.h
+++ b/src/video_core/rasterizer_accelerated.h
@@ -42,7 +42,7 @@ private:
42 }; 42 };
43 static_assert(sizeof(CacheEntry) == 8, "CacheEntry should be 8 bytes!"); 43 static_assert(sizeof(CacheEntry) == 8, "CacheEntry should be 8 bytes!");
44 44
45 std::array<CacheEntry, 0x1000000> cached_pages; 45 std::array<CacheEntry, 0x2000000> cached_pages;
46 Core::Memory::Memory& cpu_memory; 46 Core::Memory::Memory& cpu_memory;
47}; 47};
48 48
diff --git a/src/video_core/renderer_opengl/gl_device.cpp b/src/video_core/renderer_opengl/gl_device.cpp
index 9692b8e94..1e1d1d020 100644
--- a/src/video_core/renderer_opengl/gl_device.cpp
+++ b/src/video_core/renderer_opengl/gl_device.cpp
@@ -10,6 +10,7 @@
10#include <limits> 10#include <limits>
11#include <optional> 11#include <optional>
12#include <span> 12#include <span>
13#include <stdexcept>
13#include <vector> 14#include <vector>
14 15
15#include <glad/glad.h> 16#include <glad/glad.h>
diff --git a/src/video_core/renderer_vulkan/vk_master_semaphore.h b/src/video_core/renderer_vulkan/vk_master_semaphore.h
index 4f8688118..0886b7da8 100644
--- a/src/video_core/renderer_vulkan/vk_master_semaphore.h
+++ b/src/video_core/renderer_vulkan/vk_master_semaphore.h
@@ -21,12 +21,12 @@ public:
21 21
22 /// Returns the current logical tick. 22 /// Returns the current logical tick.
23 [[nodiscard]] u64 CurrentTick() const noexcept { 23 [[nodiscard]] u64 CurrentTick() const noexcept {
24 return current_tick.load(std::memory_order_relaxed); 24 return current_tick.load(std::memory_order_acquire);
25 } 25 }
26 26
27 /// Returns the last known GPU tick. 27 /// Returns the last known GPU tick.
28 [[nodiscard]] u64 KnownGpuTick() const noexcept { 28 [[nodiscard]] u64 KnownGpuTick() const noexcept {
29 return gpu_tick.load(std::memory_order_relaxed); 29 return gpu_tick.load(std::memory_order_acquire);
30 } 30 }
31 31
32 /// Returns the timeline semaphore handle. 32 /// Returns the timeline semaphore handle.
@@ -41,12 +41,21 @@ public:
41 41
42 /// Advance to the logical tick and return the old one 42 /// Advance to the logical tick and return the old one
43 [[nodiscard]] u64 NextTick() noexcept { 43 [[nodiscard]] u64 NextTick() noexcept {
44 return current_tick.fetch_add(1, std::memory_order::relaxed); 44 return current_tick.fetch_add(1, std::memory_order_release);
45 } 45 }
46 46
47 /// Refresh the known GPU tick 47 /// Refresh the known GPU tick
48 void Refresh() { 48 void Refresh() {
49 gpu_tick.store(semaphore.GetCounter(), std::memory_order_relaxed); 49 u64 this_tick{};
50 u64 counter{};
51 do {
52 this_tick = gpu_tick.load(std::memory_order_acquire);
53 counter = semaphore.GetCounter();
54 if (counter < this_tick) {
55 return;
56 }
57 } while (!gpu_tick.compare_exchange_weak(this_tick, counter, std::memory_order_release,
58 std::memory_order_relaxed));
50 } 59 }
51 60
52 /// Waits for a tick to be hit on the GPU 61 /// Waits for a tick to be hit on the GPU
diff --git a/src/video_core/renderer_vulkan/vk_query_cache.cpp b/src/video_core/renderer_vulkan/vk_query_cache.cpp
index c9cb32d71..259cba156 100644
--- a/src/video_core/renderer_vulkan/vk_query_cache.cpp
+++ b/src/video_core/renderer_vulkan/vk_query_cache.cpp
@@ -117,7 +117,8 @@ u64 HostCounter::BlockingQuery() const {
117 cache.GetScheduler().Wait(tick); 117 cache.GetScheduler().Wait(tick);
118 u64 data; 118 u64 data;
119 const VkResult query_result = cache.GetDevice().GetLogical().GetQueryResults( 119 const VkResult query_result = cache.GetDevice().GetLogical().GetQueryResults(
120 query.first, query.second, 1, sizeof(data), &data, sizeof(data), VK_QUERY_RESULT_64_BIT); 120 query.first, query.second, 1, sizeof(data), &data, sizeof(data),
121 VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WAIT_BIT);
121 122
122 switch (query_result) { 123 switch (query_result) {
123 case VK_SUCCESS: 124 case VK_SUCCESS:
diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp
index 3bcd6d6cc..30b47a7a0 100644
--- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp
+++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp
@@ -627,9 +627,21 @@ void RasterizerVulkan::UpdateDepthBias(Tegra::Engines::Maxwell3D::Regs& regs) {
627 if (!state_tracker.TouchDepthBias()) { 627 if (!state_tracker.TouchDepthBias()) {
628 return; 628 return;
629 } 629 }
630 scheduler.Record([constant = regs.polygon_offset_units, clamp = regs.polygon_offset_clamp, 630 float units = regs.polygon_offset_units / 2.0f;
631 const bool is_d24 = regs.zeta.format == Tegra::DepthFormat::S8_UINT_Z24_UNORM ||
632 regs.zeta.format == Tegra::DepthFormat::D24X8_UNORM ||
633 regs.zeta.format == Tegra::DepthFormat::D24S8_UNORM ||
634 regs.zeta.format == Tegra::DepthFormat::D24C8_UNORM;
635 if (is_d24 && !device.SupportsD24DepthBuffer()) {
636 // the base formulas can be obtained from here:
637 // https://docs.microsoft.com/en-us/windows/win32/direct3d11/d3d10-graphics-programming-guide-output-merger-stage-depth-bias
638 const double rescale_factor =
639 static_cast<double>(1ULL << (32 - 24)) / (static_cast<double>(0x1.ep+127));
640 units = static_cast<float>(static_cast<double>(units) * rescale_factor);
641 }
642 scheduler.Record([constant = units, clamp = regs.polygon_offset_clamp,
631 factor = regs.polygon_offset_factor](vk::CommandBuffer cmdbuf) { 643 factor = regs.polygon_offset_factor](vk::CommandBuffer cmdbuf) {
632 cmdbuf.SetDepthBias(constant, clamp, factor / 2.0f); 644 cmdbuf.SetDepthBias(constant, clamp, factor);
633 }); 645 });
634} 646}
635 647
diff --git a/src/video_core/renderer_vulkan/vk_state_tracker.cpp b/src/video_core/renderer_vulkan/vk_state_tracker.cpp
index e3b7dd61c..c00913f55 100644
--- a/src/video_core/renderer_vulkan/vk_state_tracker.cpp
+++ b/src/video_core/renderer_vulkan/vk_state_tracker.cpp
@@ -54,6 +54,7 @@ void SetupDirtyViewports(Tables& tables) {
54 FillBlock(tables[0], OFF(viewport_transform), NUM(viewport_transform), Viewports); 54 FillBlock(tables[0], OFF(viewport_transform), NUM(viewport_transform), Viewports);
55 FillBlock(tables[0], OFF(viewports), NUM(viewports), Viewports); 55 FillBlock(tables[0], OFF(viewports), NUM(viewports), Viewports);
56 tables[0][OFF(viewport_transform_enabled)] = Viewports; 56 tables[0][OFF(viewport_transform_enabled)] = Viewports;
57 tables[1][OFF(screen_y_control)] = Viewports;
57} 58}
58 59
59void SetupDirtyScissors(Tables& tables) { 60void SetupDirtyScissors(Tables& tables) {
diff --git a/src/video_core/renderer_vulkan/vk_state_tracker.h b/src/video_core/renderer_vulkan/vk_state_tracker.h
index d90935f52..2f2d6b31f 100644
--- a/src/video_core/renderer_vulkan/vk_state_tracker.h
+++ b/src/video_core/renderer_vulkan/vk_state_tracker.h
@@ -79,7 +79,8 @@ public:
79 } 79 }
80 80
81 bool TouchDepthBias() { 81 bool TouchDepthBias() {
82 return Exchange(Dirty::DepthBias, false); 82 return Exchange(Dirty::DepthBias, false) ||
83 Exchange(VideoCommon::Dirty::DepthBiasGlobal, false);
83 } 84 }
84 85
85 bool TouchBlendConstants() { 86 bool TouchBlendConstants() {
diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h
index 329df2e49..f70c1f764 100644
--- a/src/video_core/texture_cache/texture_cache.h
+++ b/src/video_core/texture_cache/texture_cache.h
@@ -221,6 +221,7 @@ void TextureCache<P>::UpdateRenderTargets(bool is_clear) {
221 BindRenderTarget(&render_targets.depth_buffer_id, FindDepthBuffer(is_clear)); 221 BindRenderTarget(&render_targets.depth_buffer_id, FindDepthBuffer(is_clear));
222 } 222 }
223 const ImageViewId depth_buffer_id = render_targets.depth_buffer_id; 223 const ImageViewId depth_buffer_id = render_targets.depth_buffer_id;
224
224 PrepareImageView(depth_buffer_id, true, is_clear && IsFullClear(depth_buffer_id)); 225 PrepareImageView(depth_buffer_id, true, is_clear && IsFullClear(depth_buffer_id));
225 226
226 for (size_t index = 0; index < NUM_RT; ++index) { 227 for (size_t index = 0; index < NUM_RT; ++index) {
@@ -230,6 +231,8 @@ void TextureCache<P>::UpdateRenderTargets(bool is_clear) {
230 maxwell3d.regs.render_area.width, 231 maxwell3d.regs.render_area.width,
231 maxwell3d.regs.render_area.height, 232 maxwell3d.regs.render_area.height,
232 }; 233 };
234
235 flags[Dirty::DepthBiasGlobal] = true;
233} 236}
234 237
235template <class P> 238template <class P>
diff --git a/src/video_core/vulkan_common/vulkan_device.cpp b/src/video_core/vulkan_common/vulkan_device.cpp
index 6388ed2eb..0f807990c 100644
--- a/src/video_core/vulkan_common/vulkan_device.cpp
+++ b/src/video_core/vulkan_common/vulkan_device.cpp
@@ -623,6 +623,10 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR
623 is_float16_supported = false; 623 is_float16_supported = false;
624 } 624 }
625 625
626 supports_d24_depth =
627 IsFormatSupported(VK_FORMAT_D24_UNORM_S8_UINT,
628 VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT, FormatType::Optimal);
629
626 graphics_queue = logical.GetQueue(graphics_family); 630 graphics_queue = logical.GetQueue(graphics_family);
627 present_queue = logical.GetQueue(present_family); 631 present_queue = logical.GetQueue(present_family);
628} 632}
diff --git a/src/video_core/vulkan_common/vulkan_device.h b/src/video_core/vulkan_common/vulkan_device.h
index d9e74f1aa..2d5daf6cd 100644
--- a/src/video_core/vulkan_common/vulkan_device.h
+++ b/src/video_core/vulkan_common/vulkan_device.h
@@ -332,6 +332,10 @@ public:
332 return sets_per_pool; 332 return sets_per_pool;
333 } 333 }
334 334
335 bool SupportsD24DepthBuffer() const {
336 return supports_d24_depth;
337 }
338
335private: 339private:
336 /// Checks if the physical device is suitable. 340 /// Checks if the physical device is suitable.
337 void CheckSuitability(bool requires_swapchain) const; 341 void CheckSuitability(bool requires_swapchain) const;
@@ -425,6 +429,7 @@ private:
425 bool has_broken_cube_compatibility{}; ///< Has broken cube compatiblity bit 429 bool has_broken_cube_compatibility{}; ///< Has broken cube compatiblity bit
426 bool has_renderdoc{}; ///< Has RenderDoc attached 430 bool has_renderdoc{}; ///< Has RenderDoc attached
427 bool has_nsight_graphics{}; ///< Has Nsight Graphics attached 431 bool has_nsight_graphics{}; ///< Has Nsight Graphics attached
432 bool supports_d24_depth{}; ///< Supports D24 depth buffers.
428 433
429 // Telemetry parameters 434 // Telemetry parameters
430 std::string vendor_name; ///< Device's driver name. 435 std::string vendor_name; ///< Device's driver name.
diff --git a/src/yuzu/about_dialog.cpp b/src/yuzu/about_dialog.cpp
index 6b0155a78..04ab4ae21 100644
--- a/src/yuzu/about_dialog.cpp
+++ b/src/yuzu/about_dialog.cpp
@@ -8,7 +8,8 @@
8#include "ui_aboutdialog.h" 8#include "ui_aboutdialog.h"
9#include "yuzu/about_dialog.h" 9#include "yuzu/about_dialog.h"
10 10
11AboutDialog::AboutDialog(QWidget* parent) : QDialog(parent), ui(new Ui::AboutDialog) { 11AboutDialog::AboutDialog(QWidget* parent)
12 : QDialog(parent), ui{std::make_unique<Ui::AboutDialog>()} {
12 const auto branch_name = std::string(Common::g_scm_branch); 13 const auto branch_name = std::string(Common::g_scm_branch);
13 const auto description = std::string(Common::g_scm_desc); 14 const auto description = std::string(Common::g_scm_desc);
14 const auto build_id = std::string(Common::g_build_id); 15 const auto build_id = std::string(Common::g_build_id);
diff --git a/src/yuzu/applets/qt_web_browser.cpp b/src/yuzu/applets/qt_web_browser.cpp
index 7d433ca50..da8c6882a 100644
--- a/src/yuzu/applets/qt_web_browser.cpp
+++ b/src/yuzu/applets/qt_web_browser.cpp
@@ -3,6 +3,7 @@
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#ifdef YUZU_USE_QT_WEB_ENGINE 5#ifdef YUZU_USE_QT_WEB_ENGINE
6#include <QApplication>
6#include <QKeyEvent> 7#include <QKeyEvent>
7 8
8#include <QWebEngineProfile> 9#include <QWebEngineProfile>
diff --git a/src/yuzu/bootmanager.cpp b/src/yuzu/bootmanager.cpp
index c75f5e1ee..40fd47406 100644
--- a/src/yuzu/bootmanager.cpp
+++ b/src/yuzu/bootmanager.cpp
@@ -86,15 +86,15 @@ void EmuThread::run() {
86 } 86 }
87 87
88 running_guard = true; 88 running_guard = true;
89 Core::System::ResultStatus result = system.Run(); 89 Core::SystemResultStatus result = system.Run();
90 if (result != Core::System::ResultStatus::Success) { 90 if (result != Core::SystemResultStatus::Success) {
91 running_guard = false; 91 running_guard = false;
92 this->SetRunning(false); 92 this->SetRunning(false);
93 emit ErrorThrown(result, system.GetStatusDetails()); 93 emit ErrorThrown(result, system.GetStatusDetails());
94 } 94 }
95 running_wait.Wait(); 95 running_wait.Wait();
96 result = system.Pause(); 96 result = system.Pause();
97 if (result != Core::System::ResultStatus::Success) { 97 if (result != Core::SystemResultStatus::Success) {
98 running_guard = false; 98 running_guard = false;
99 this->SetRunning(false); 99 this->SetRunning(false);
100 emit ErrorThrown(result, system.GetStatusDetails()); 100 emit ErrorThrown(result, system.GetStatusDetails());
diff --git a/src/yuzu/bootmanager.h b/src/yuzu/bootmanager.h
index 8d7ab8c2e..e6a0666e9 100644
--- a/src/yuzu/bootmanager.h
+++ b/src/yuzu/bootmanager.h
@@ -16,7 +16,6 @@
16#include <QWindow> 16#include <QWindow>
17 17
18#include "common/thread.h" 18#include "common/thread.h"
19#include "core/core.h"
20#include "core/frontend/emu_window.h" 19#include "core/frontend/emu_window.h"
21 20
22class GRenderWindow; 21class GRenderWindow;
@@ -24,6 +23,11 @@ class GMainWindow;
24class QKeyEvent; 23class QKeyEvent;
25class QStringList; 24class QStringList;
26 25
26namespace Core {
27enum class SystemResultStatus : u32;
28class System;
29} // namespace Core
30
27namespace InputCommon { 31namespace InputCommon {
28class InputSubsystem; 32class InputSubsystem;
29} 33}
@@ -123,7 +127,7 @@ signals:
123 */ 127 */
124 void DebugModeLeft(); 128 void DebugModeLeft();
125 129
126 void ErrorThrown(Core::System::ResultStatus, std::string); 130 void ErrorThrown(Core::SystemResultStatus, std::string);
127 131
128 void LoadProgress(VideoCore::LoadCallbackStage stage, std::size_t value, std::size_t total); 132 void LoadProgress(VideoCore::LoadCallbackStage stage, std::size_t value, std::size_t total);
129}; 133};
diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp
index 30a864135..faea5dda1 100644
--- a/src/yuzu/configuration/config.cpp
+++ b/src/yuzu/configuration/config.cpp
@@ -918,8 +918,7 @@ void Config::ReadSystemValues() {
918 const auto custom_rtc_enabled = 918 const auto custom_rtc_enabled =
919 ReadSetting(QStringLiteral("custom_rtc_enabled"), false).toBool(); 919 ReadSetting(QStringLiteral("custom_rtc_enabled"), false).toBool();
920 if (custom_rtc_enabled) { 920 if (custom_rtc_enabled) {
921 Settings::values.custom_rtc = 921 Settings::values.custom_rtc = ReadSetting(QStringLiteral("custom_rtc"), 0).toLongLong();
922 std::chrono::seconds(ReadSetting(QStringLiteral("custom_rtc"), 0).toULongLong());
923 } else { 922 } else {
924 Settings::values.custom_rtc = std::nullopt; 923 Settings::values.custom_rtc = std::nullopt;
925 } 924 }
@@ -1450,9 +1449,7 @@ void Config::SaveSystemValues() {
1450 WriteSetting(QStringLiteral("custom_rtc_enabled"), Settings::values.custom_rtc.has_value(), 1449 WriteSetting(QStringLiteral("custom_rtc_enabled"), Settings::values.custom_rtc.has_value(),
1451 false); 1450 false);
1452 WriteSetting(QStringLiteral("custom_rtc"), 1451 WriteSetting(QStringLiteral("custom_rtc"),
1453 QVariant::fromValue<long long>( 1452 QVariant::fromValue<long long>(Settings::values.custom_rtc.value_or(0)), 0);
1454 Settings::values.custom_rtc.value_or(std::chrono::seconds{}).count()),
1455 0);
1456 } 1453 }
1457 1454
1458 WriteGlobalSetting(Settings::values.sound_index); 1455 WriteGlobalSetting(Settings::values.sound_index);
diff --git a/src/yuzu/configuration/configure_cpu.cpp b/src/yuzu/configuration/configure_cpu.cpp
index 27fabef38..f66cab5d4 100644
--- a/src/yuzu/configuration/configure_cpu.cpp
+++ b/src/yuzu/configuration/configure_cpu.cpp
@@ -14,7 +14,7 @@
14#include "yuzu/configuration/configure_cpu.h" 14#include "yuzu/configuration/configure_cpu.h"
15 15
16ConfigureCpu::ConfigureCpu(const Core::System& system_, QWidget* parent) 16ConfigureCpu::ConfigureCpu(const Core::System& system_, QWidget* parent)
17 : QWidget(parent), ui(new Ui::ConfigureCpu), system{system_} { 17 : QWidget(parent), ui{std::make_unique<Ui::ConfigureCpu>()}, system{system_} {
18 ui->setupUi(this); 18 ui->setupUi(this);
19 19
20 SetupPerGameUI(); 20 SetupPerGameUI();
diff --git a/src/yuzu/configuration/configure_cpu_debug.cpp b/src/yuzu/configuration/configure_cpu_debug.cpp
index 6e910e33e..05a90963d 100644
--- a/src/yuzu/configuration/configure_cpu_debug.cpp
+++ b/src/yuzu/configuration/configure_cpu_debug.cpp
@@ -12,7 +12,7 @@
12#include "yuzu/configuration/configure_cpu_debug.h" 12#include "yuzu/configuration/configure_cpu_debug.h"
13 13
14ConfigureCpuDebug::ConfigureCpuDebug(const Core::System& system_, QWidget* parent) 14ConfigureCpuDebug::ConfigureCpuDebug(const Core::System& system_, QWidget* parent)
15 : QWidget(parent), ui(new Ui::ConfigureCpuDebug), system{system_} { 15 : QWidget(parent), ui{std::make_unique<Ui::ConfigureCpuDebug>()}, system{system_} {
16 ui->setupUi(this); 16 ui->setupUi(this);
17 17
18 SetConfiguration(); 18 SetConfiguration();
diff --git a/src/yuzu/configuration/configure_debug.cpp b/src/yuzu/configuration/configure_debug.cpp
index 40447093e..07bfa0360 100644
--- a/src/yuzu/configuration/configure_debug.cpp
+++ b/src/yuzu/configuration/configure_debug.cpp
@@ -15,7 +15,7 @@
15#include "yuzu/uisettings.h" 15#include "yuzu/uisettings.h"
16 16
17ConfigureDebug::ConfigureDebug(const Core::System& system_, QWidget* parent) 17ConfigureDebug::ConfigureDebug(const Core::System& system_, QWidget* parent)
18 : QWidget(parent), ui(new Ui::ConfigureDebug), system{system_} { 18 : QWidget(parent), ui{std::make_unique<Ui::ConfigureDebug>()}, system{system_} {
19 ui->setupUi(this); 19 ui->setupUi(this);
20 SetConfiguration(); 20 SetConfiguration();
21 21
diff --git a/src/yuzu/configuration/configure_debug_tab.cpp b/src/yuzu/configuration/configure_debug_tab.cpp
index e126eeea9..e69cca1ef 100644
--- a/src/yuzu/configuration/configure_debug_tab.cpp
+++ b/src/yuzu/configuration/configure_debug_tab.cpp
@@ -9,8 +9,8 @@
9#include "yuzu/configuration/configure_debug_tab.h" 9#include "yuzu/configuration/configure_debug_tab.h"
10 10
11ConfigureDebugTab::ConfigureDebugTab(const Core::System& system_, QWidget* parent) 11ConfigureDebugTab::ConfigureDebugTab(const Core::System& system_, QWidget* parent)
12 : QWidget(parent), 12 : QWidget(parent), ui{std::make_unique<Ui::ConfigureDebugTab>()},
13 ui(new Ui::ConfigureDebugTab), debug_tab{std::make_unique<ConfigureDebug>(system_, this)}, 13 debug_tab{std::make_unique<ConfigureDebug>(system_, this)},
14 cpu_debug_tab{std::make_unique<ConfigureCpuDebug>(system_, this)} { 14 cpu_debug_tab{std::make_unique<ConfigureCpuDebug>(system_, this)} {
15 ui->setupUi(this); 15 ui->setupUi(this);
16 16
diff --git a/src/yuzu/configuration/configure_dialog.cpp b/src/yuzu/configuration/configure_dialog.cpp
index cf269f5d1..642a5f966 100644
--- a/src/yuzu/configuration/configure_dialog.cpp
+++ b/src/yuzu/configuration/configure_dialog.cpp
@@ -36,7 +36,7 @@
36ConfigureDialog::ConfigureDialog(QWidget* parent, HotkeyRegistry& registry, 36ConfigureDialog::ConfigureDialog(QWidget* parent, HotkeyRegistry& registry,
37 InputCommon::InputSubsystem* input_subsystem, 37 InputCommon::InputSubsystem* input_subsystem,
38 Core::System& system_) 38 Core::System& system_)
39 : QDialog(parent), ui(new Ui::ConfigureDialog), 39 : QDialog(parent), ui{std::make_unique<Ui::ConfigureDialog>()},
40 registry(registry), system{system_}, audio_tab{std::make_unique<ConfigureAudio>(system_, 40 registry(registry), system{system_}, audio_tab{std::make_unique<ConfigureAudio>(system_,
41 this)}, 41 this)},
42 cpu_tab{std::make_unique<ConfigureCpu>(system_, this)}, 42 cpu_tab{std::make_unique<ConfigureCpu>(system_, this)},
diff --git a/src/yuzu/configuration/configure_general.cpp b/src/yuzu/configuration/configure_general.cpp
index e562e89e5..7af3ea97e 100644
--- a/src/yuzu/configuration/configure_general.cpp
+++ b/src/yuzu/configuration/configure_general.cpp
@@ -16,7 +16,7 @@
16#include "yuzu/uisettings.h" 16#include "yuzu/uisettings.h"
17 17
18ConfigureGeneral::ConfigureGeneral(const Core::System& system_, QWidget* parent) 18ConfigureGeneral::ConfigureGeneral(const Core::System& system_, QWidget* parent)
19 : QWidget(parent), ui(new Ui::ConfigureGeneral), system{system_} { 19 : QWidget(parent), ui{std::make_unique<Ui::ConfigureGeneral>()}, system{system_} {
20 ui->setupUi(this); 20 ui->setupUi(this);
21 21
22 SetupPerGameUI(); 22 SetupPerGameUI();
diff --git a/src/yuzu/configuration/configure_graphics.cpp b/src/yuzu/configuration/configure_graphics.cpp
index be4e7997b..8e20cc6f3 100644
--- a/src/yuzu/configuration/configure_graphics.cpp
+++ b/src/yuzu/configuration/configure_graphics.cpp
@@ -20,7 +20,7 @@
20#include "yuzu/configuration/configure_graphics.h" 20#include "yuzu/configuration/configure_graphics.h"
21 21
22ConfigureGraphics::ConfigureGraphics(const Core::System& system_, QWidget* parent) 22ConfigureGraphics::ConfigureGraphics(const Core::System& system_, QWidget* parent)
23 : QWidget(parent), ui(new Ui::ConfigureGraphics), system{system_} { 23 : QWidget(parent), ui{std::make_unique<Ui::ConfigureGraphics>()}, system{system_} {
24 vulkan_device = Settings::values.vulkan_device.GetValue(); 24 vulkan_device = Settings::values.vulkan_device.GetValue();
25 RetrieveVulkanDevices(); 25 RetrieveVulkanDevices();
26 26
diff --git a/src/yuzu/configuration/configure_graphics_advanced.cpp b/src/yuzu/configuration/configure_graphics_advanced.cpp
index 4407e65d3..30c5a3595 100644
--- a/src/yuzu/configuration/configure_graphics_advanced.cpp
+++ b/src/yuzu/configuration/configure_graphics_advanced.cpp
@@ -9,7 +9,7 @@
9#include "yuzu/configuration/configure_graphics_advanced.h" 9#include "yuzu/configuration/configure_graphics_advanced.h"
10 10
11ConfigureGraphicsAdvanced::ConfigureGraphicsAdvanced(const Core::System& system_, QWidget* parent) 11ConfigureGraphicsAdvanced::ConfigureGraphicsAdvanced(const Core::System& system_, QWidget* parent)
12 : QWidget(parent), ui(new Ui::ConfigureGraphicsAdvanced), system{system_} { 12 : QWidget(parent), ui{std::make_unique<Ui::ConfigureGraphicsAdvanced>()}, system{system_} {
13 13
14 ui->setupUi(this); 14 ui->setupUi(this);
15 15
diff --git a/src/yuzu/configuration/configure_per_game_addons.cpp b/src/yuzu/configuration/configure_per_game_addons.cpp
index c8de8e2ff..65e615963 100644
--- a/src/yuzu/configuration/configure_per_game_addons.cpp
+++ b/src/yuzu/configuration/configure_per_game_addons.cpp
@@ -27,7 +27,7 @@
27#include "yuzu/util/util.h" 27#include "yuzu/util/util.h"
28 28
29ConfigurePerGameAddons::ConfigurePerGameAddons(Core::System& system_, QWidget* parent) 29ConfigurePerGameAddons::ConfigurePerGameAddons(Core::System& system_, QWidget* parent)
30 : QWidget(parent), ui(new Ui::ConfigurePerGameAddons), system{system_} { 30 : QWidget(parent), ui{std::make_unique<Ui::ConfigurePerGameAddons>()}, system{system_} {
31 ui->setupUi(this); 31 ui->setupUi(this);
32 32
33 layout = new QVBoxLayout; 33 layout = new QVBoxLayout;
diff --git a/src/yuzu/configuration/configure_profile_manager.cpp b/src/yuzu/configuration/configure_profile_manager.cpp
index 9feec37ff..99d5f4686 100644
--- a/src/yuzu/configuration/configure_profile_manager.cpp
+++ b/src/yuzu/configuration/configure_profile_manager.cpp
@@ -77,7 +77,7 @@ QString GetProfileUsernameFromUser(QWidget* parent, const QString& description_t
77} // Anonymous namespace 77} // Anonymous namespace
78 78
79ConfigureProfileManager::ConfigureProfileManager(const Core::System& system_, QWidget* parent) 79ConfigureProfileManager::ConfigureProfileManager(const Core::System& system_, QWidget* parent)
80 : QWidget(parent), ui(new Ui::ConfigureProfileManager), 80 : QWidget(parent), ui{std::make_unique<Ui::ConfigureProfileManager>()},
81 profile_manager(std::make_unique<Service::Account::ProfileManager>()), system{system_} { 81 profile_manager(std::make_unique<Service::Account::ProfileManager>()), system{system_} {
82 ui->setupUi(this); 82 ui->setupUi(this);
83 83
diff --git a/src/yuzu/configuration/configure_system.cpp b/src/yuzu/configuration/configure_system.cpp
index 33eb059a3..56c762d64 100644
--- a/src/yuzu/configuration/configure_system.cpp
+++ b/src/yuzu/configuration/configure_system.cpp
@@ -18,7 +18,7 @@
18#include "yuzu/configuration/configure_system.h" 18#include "yuzu/configuration/configure_system.h"
19 19
20ConfigureSystem::ConfigureSystem(Core::System& system_, QWidget* parent) 20ConfigureSystem::ConfigureSystem(Core::System& system_, QWidget* parent)
21 : QWidget(parent), ui(new Ui::ConfigureSystem), system{system_} { 21 : QWidget(parent), ui{std::make_unique<Ui::ConfigureSystem>()}, system{system_} {
22 ui->setupUi(this); 22 ui->setupUi(this);
23 connect(ui->button_regenerate_console_id, &QPushButton::clicked, this, 23 connect(ui->button_regenerate_console_id, &QPushButton::clicked, this,
24 &ConfigureSystem::RefreshConsoleID); 24 &ConfigureSystem::RefreshConsoleID);
@@ -65,8 +65,7 @@ void ConfigureSystem::SetConfiguration() {
65 QStringLiteral("%1") 65 QStringLiteral("%1")
66 .arg(Settings::values.rng_seed.GetValue().value_or(0), 8, 16, QLatin1Char{'0'}) 66 .arg(Settings::values.rng_seed.GetValue().value_or(0), 8, 16, QLatin1Char{'0'})
67 .toUpper(); 67 .toUpper();
68 const auto rtc_time = Settings::values.custom_rtc.value_or( 68 const auto rtc_time = Settings::values.custom_rtc.value_or(QDateTime::currentSecsSinceEpoch());
69 std::chrono::seconds(QDateTime::currentSecsSinceEpoch()));
70 69
71 ui->rng_seed_checkbox->setChecked(Settings::values.rng_seed.GetValue().has_value()); 70 ui->rng_seed_checkbox->setChecked(Settings::values.rng_seed.GetValue().has_value());
72 ui->rng_seed_edit->setEnabled(Settings::values.rng_seed.GetValue().has_value() && 71 ui->rng_seed_edit->setEnabled(Settings::values.rng_seed.GetValue().has_value() &&
@@ -75,7 +74,7 @@ void ConfigureSystem::SetConfiguration() {
75 74
76 ui->custom_rtc_checkbox->setChecked(Settings::values.custom_rtc.has_value()); 75 ui->custom_rtc_checkbox->setChecked(Settings::values.custom_rtc.has_value());
77 ui->custom_rtc_edit->setEnabled(Settings::values.custom_rtc.has_value()); 76 ui->custom_rtc_edit->setEnabled(Settings::values.custom_rtc.has_value());
78 ui->custom_rtc_edit->setDateTime(QDateTime::fromSecsSinceEpoch(rtc_time.count())); 77 ui->custom_rtc_edit->setDateTime(QDateTime::fromSecsSinceEpoch(rtc_time));
79 78
80 if (Settings::IsConfiguringGlobal()) { 79 if (Settings::IsConfiguringGlobal()) {
81 ui->combo_language->setCurrentIndex(Settings::values.language_index.GetValue()); 80 ui->combo_language->setCurrentIndex(Settings::values.language_index.GetValue());
@@ -108,10 +107,9 @@ void ConfigureSystem::ApplyConfiguration() {
108 // to allow in-game time to be fast forwarded 107 // to allow in-game time to be fast forwarded
109 if (Settings::IsConfiguringGlobal()) { 108 if (Settings::IsConfiguringGlobal()) {
110 if (ui->custom_rtc_checkbox->isChecked()) { 109 if (ui->custom_rtc_checkbox->isChecked()) {
111 Settings::values.custom_rtc = 110 Settings::values.custom_rtc = ui->custom_rtc_edit->dateTime().toSecsSinceEpoch();
112 std::chrono::seconds(ui->custom_rtc_edit->dateTime().toSecsSinceEpoch());
113 if (system.IsPoweredOn()) { 111 if (system.IsPoweredOn()) {
114 const s64 posix_time{Settings::values.custom_rtc->count() + 112 const s64 posix_time{*Settings::values.custom_rtc +
115 Service::Time::TimeManager::GetExternalTimeZoneOffset()}; 113 Service::Time::TimeManager::GetExternalTimeZoneOffset()};
116 system.GetTimeManager().UpdateLocalSystemClockTime(posix_time); 114 system.GetTimeManager().UpdateLocalSystemClockTime(posix_time);
117 } 115 }
diff --git a/src/yuzu/configuration/configure_tas.ui b/src/yuzu/configuration/configure_tas.ui
index 6caa19031..7d44895c4 100644
--- a/src/yuzu/configuration/configure_tas.ui
+++ b/src/yuzu/configuration/configure_tas.ui
@@ -14,14 +14,14 @@
14 <item row="0" column="0" colspan="4"> 14 <item row="0" column="0" colspan="4">
15 <widget class="QLabel" name="label_1"> 15 <widget class="QLabel" name="label_1">
16 <property name="text"> 16 <property name="text">
17 <string>Reads controller input from scripts in the same format as TAS-nx scripts.&lt;br/&gt;For a more detailed explanation please consult the FAQ on the yuzu website.</string> 17 <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Reads controller input from scripts in the same format as TAS-nx scripts.&lt;br/&gt;For a more detailed explanation, please consult the &lt;a href=&quot;https://yuzu-emu.org/help/feature/tas/&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;help page&lt;/span&gt;&lt;/a&gt; on the yuzu website.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
18 </property> 18 </property>
19 </widget> 19 </widget>
20 </item> 20 </item>
21 <item row="1" column="0" colspan="4"> 21 <item row="1" column="0" colspan="4">
22 <widget class="QLabel" name="label_2"> 22 <widget class="QLabel" name="label_2">
23 <property name="text"> 23 <property name="text">
24 <string>To check which hotkeys control the playback/recording, please refer to the Hotkey settings (General -&gt; Hotkeys).</string> 24 <string>To check which hotkeys control the playback/recording, please refer to the Hotkey settings (Configure -&gt; General -&gt; Hotkeys).</string>
25 </property> 25 </property>
26 <property name="wordWrap"> 26 <property name="wordWrap">
27 <bool>true</bool> 27 <bool>true</bool>
diff --git a/src/yuzu/configuration/configure_ui.cpp b/src/yuzu/configuration/configure_ui.cpp
index d01895bf2..46e5409db 100644
--- a/src/yuzu/configuration/configure_ui.cpp
+++ b/src/yuzu/configuration/configure_ui.cpp
@@ -55,7 +55,7 @@ QString GetTranslatedRowTextName(size_t index) {
55} // Anonymous namespace 55} // Anonymous namespace
56 56
57ConfigureUi::ConfigureUi(Core::System& system_, QWidget* parent) 57ConfigureUi::ConfigureUi(Core::System& system_, QWidget* parent)
58 : QWidget(parent), ui(new Ui::ConfigureUi), system{system_} { 58 : QWidget(parent), ui{std::make_unique<Ui::ConfigureUi>()}, system{system_} {
59 ui->setupUi(this); 59 ui->setupUi(this);
60 60
61 InitializeLanguageComboBox(); 61 InitializeLanguageComboBox();
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp
index 9f80a245c..2af582fe5 100644
--- a/src/yuzu/main.cpp
+++ b/src/yuzu/main.cpp
@@ -104,6 +104,7 @@ static FileSys::VirtualFile VfsDirectoryCreateFileWrapper(const FileSys::Virtual
104#include "core/telemetry_session.h" 104#include "core/telemetry_session.h"
105#include "input_common/main.h" 105#include "input_common/main.h"
106#include "input_common/tas/tas_input.h" 106#include "input_common/tas/tas_input.h"
107#include "ui_main.h"
107#include "util/overlay_dialog.h" 108#include "util/overlay_dialog.h"
108#include "video_core/gpu.h" 109#include "video_core/gpu.h"
109#include "video_core/renderer_base.h" 110#include "video_core/renderer_base.h"
@@ -171,7 +172,7 @@ void GMainWindow::ShowTelemetryCallout() {
171 "<br/><br/>Would you like to share your usage data with us?"); 172 "<br/><br/>Would you like to share your usage data with us?");
172 if (QMessageBox::question(this, tr("Telemetry"), telemetry_message) != QMessageBox::Yes) { 173 if (QMessageBox::question(this, tr("Telemetry"), telemetry_message) != QMessageBox::Yes) {
173 Settings::values.enable_telemetry = false; 174 Settings::values.enable_telemetry = false;
174 system.ApplySettings(); 175 system->ApplySettings();
175 } 176 }
176} 177}
177 178
@@ -190,16 +191,17 @@ static void RemoveCachedContents() {
190 Common::FS::RemoveDirRecursively(offline_system_data); 191 Common::FS::RemoveDirRecursively(offline_system_data);
191} 192}
192 193
193GMainWindow::GMainWindow(Core::System& system_) 194GMainWindow::GMainWindow()
194 : input_subsystem{std::make_shared<InputCommon::InputSubsystem>()}, system{system_}, 195 : ui{std::make_unique<Ui::MainWindow>()}, system{std::make_unique<Core::System>()},
195 config{std::make_unique<Config>(system_)}, 196 input_subsystem{std::make_shared<InputCommon::InputSubsystem>()},
197 config{std::make_unique<Config>(*system)},
196 vfs{std::make_shared<FileSys::RealVfsFilesystem>()}, 198 vfs{std::make_shared<FileSys::RealVfsFilesystem>()},
197 provider{std::make_unique<FileSys::ManualContentProvider>()} { 199 provider{std::make_unique<FileSys::ManualContentProvider>()} {
198 Common::Log::Initialize(); 200 Common::Log::Initialize();
199 LoadTranslation(); 201 LoadTranslation();
200 202
201 setAcceptDrops(true); 203 setAcceptDrops(true);
202 ui.setupUi(this); 204 ui->setupUi(this);
203 statusBar()->hide(); 205 statusBar()->hide();
204 206
205 default_theme_paths = QIcon::themeSearchPaths(); 207 default_theme_paths = QIcon::themeSearchPaths();
@@ -256,10 +258,10 @@ GMainWindow::GMainWindow(Core::System& system_)
256 258
257 show(); 259 show();
258 260
259 system.SetContentProvider(std::make_unique<FileSys::ContentProviderUnion>()); 261 system->SetContentProvider(std::make_unique<FileSys::ContentProviderUnion>());
260 system.RegisterContentProvider(FileSys::ContentProviderUnionSlot::FrontendManual, 262 system->RegisterContentProvider(FileSys::ContentProviderUnionSlot::FrontendManual,
261 provider.get()); 263 provider.get());
262 system.GetFileSystemController().CreateFactories(*vfs); 264 system->GetFileSystemController().CreateFactories(*vfs);
263 265
264 // Remove cached contents generated during the previous session 266 // Remove cached contents generated during the previous session
265 RemoveCachedContents(); 267 RemoveCachedContents();
@@ -274,16 +276,16 @@ GMainWindow::GMainWindow(Core::System& system_)
274 ShowTelemetryCallout(); 276 ShowTelemetryCallout();
275 277
276 // make sure menubar has the arrow cursor instead of inheriting from this 278 // make sure menubar has the arrow cursor instead of inheriting from this
277 ui.menubar->setCursor(QCursor()); 279 ui->menubar->setCursor(QCursor());
278 statusBar()->setCursor(QCursor()); 280 statusBar()->setCursor(QCursor());
279 281
280 mouse_hide_timer.setInterval(default_mouse_timeout); 282 mouse_hide_timer.setInterval(default_mouse_timeout);
281 connect(&mouse_hide_timer, &QTimer::timeout, this, &GMainWindow::HideMouseCursor); 283 connect(&mouse_hide_timer, &QTimer::timeout, this, &GMainWindow::HideMouseCursor);
282 connect(ui.menubar, &QMenuBar::hovered, this, &GMainWindow::ShowMouseCursor); 284 connect(ui->menubar, &QMenuBar::hovered, this, &GMainWindow::ShowMouseCursor);
283 285
284 MigrateConfigFiles(); 286 MigrateConfigFiles();
285 287
286 ui.action_Fullscreen->setChecked(false); 288 ui->action_Fullscreen->setChecked(false);
287 289
288 QStringList args = QApplication::arguments(); 290 QStringList args = QApplication::arguments();
289 291
@@ -302,7 +304,7 @@ GMainWindow::GMainWindow(Core::System& system_)
302 304
303 // Launch game in fullscreen mode 305 // Launch game in fullscreen mode
304 if (args[i] == QStringLiteral("-f")) { 306 if (args[i] == QStringLiteral("-f")) {
305 ui.action_Fullscreen->setChecked(true); 307 ui->action_Fullscreen->setChecked(true);
306 continue; 308 continue;
307 } 309 }
308 310
@@ -405,12 +407,12 @@ void GMainWindow::RegisterMetaTypes() {
405 qRegisterMetaType<Service::AM::Applets::WebExitReason>("Service::AM::Applets::WebExitReason"); 407 qRegisterMetaType<Service::AM::Applets::WebExitReason>("Service::AM::Applets::WebExitReason");
406 408
407 // Register loader types 409 // Register loader types
408 qRegisterMetaType<Core::System::ResultStatus>("Core::System::ResultStatus"); 410 qRegisterMetaType<Core::SystemResultStatus>("Core::SystemResultStatus");
409} 411}
410 412
411void GMainWindow::ControllerSelectorReconfigureControllers( 413void GMainWindow::ControllerSelectorReconfigureControllers(
412 const Core::Frontend::ControllerParameters& parameters) { 414 const Core::Frontend::ControllerParameters& parameters) {
413 QtControllerSelectorDialog dialog(this, parameters, input_subsystem.get(), system); 415 QtControllerSelectorDialog dialog(this, parameters, input_subsystem.get(), *system);
414 416
415 dialog.setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowStaysOnTopHint | 417 dialog.setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowStaysOnTopHint |
416 Qt::WindowTitleHint | Qt::WindowSystemMenuHint); 418 Qt::WindowTitleHint | Qt::WindowSystemMenuHint);
@@ -420,7 +422,7 @@ void GMainWindow::ControllerSelectorReconfigureControllers(
420 emit ControllerSelectorReconfigureFinished(); 422 emit ControllerSelectorReconfigureFinished();
421 423
422 // Don't forget to apply settings. 424 // Don't forget to apply settings.
423 system.ApplySettings(); 425 system->ApplySettings();
424 config->Save(); 426 config->Save();
425 427
426 UpdateStatusButtons(); 428 UpdateStatusButtons();
@@ -454,7 +456,7 @@ void GMainWindow::SoftwareKeyboardInitialize(
454 return; 456 return;
455 } 457 }
456 458
457 software_keyboard = new QtSoftwareKeyboardDialog(render_window, system, is_inline, 459 software_keyboard = new QtSoftwareKeyboardDialog(render_window, *system, is_inline,
458 std::move(initialize_parameters)); 460 std::move(initialize_parameters));
459 461
460 if (is_inline) { 462 if (is_inline) {
@@ -566,11 +568,11 @@ void GMainWindow::WebBrowserOpenWebPage(const std::string& main_url,
566 return; 568 return;
567 } 569 }
568 570
569 QtNXWebEngineView web_browser_view(this, system, input_subsystem.get()); 571 QtNXWebEngineView web_browser_view(this, *system, input_subsystem.get());
570 572
571 ui.action_Pause->setEnabled(false); 573 ui->action_Pause->setEnabled(false);
572 ui.action_Restart->setEnabled(false); 574 ui->action_Restart->setEnabled(false);
573 ui.action_Stop->setEnabled(false); 575 ui->action_Stop->setEnabled(false);
574 576
575 { 577 {
576 QProgressDialog loading_progress(this); 578 QProgressDialog loading_progress(this);
@@ -634,7 +636,7 @@ void GMainWindow::WebBrowserOpenWebPage(const std::string& main_url,
634 web_browser_view.SetFinished(true); 636 web_browser_view.SetFinished(true);
635 } 637 }
636 }); 638 });
637 ui.menubar->addAction(exit_action); 639 ui->menubar->addAction(exit_action);
638 640
639 while (!web_browser_view.IsFinished()) { 641 while (!web_browser_view.IsFinished()) {
640 QCoreApplication::processEvents(); 642 QCoreApplication::processEvents();
@@ -676,11 +678,11 @@ void GMainWindow::WebBrowserOpenWebPage(const std::string& main_url,
676 render_window->show(); 678 render_window->show();
677 } 679 }
678 680
679 ui.action_Pause->setEnabled(true); 681 ui->action_Pause->setEnabled(true);
680 ui.action_Restart->setEnabled(true); 682 ui->action_Restart->setEnabled(true);
681 ui.action_Stop->setEnabled(true); 683 ui->action_Stop->setEnabled(true);
682 684
683 ui.menubar->removeAction(exit_action); 685 ui->menubar->removeAction(exit_action);
684 686
685 QCoreApplication::processEvents(); 687 QCoreApplication::processEvents();
686 688
@@ -696,21 +698,21 @@ void GMainWindow::WebBrowserOpenWebPage(const std::string& main_url,
696 698
697void GMainWindow::InitializeWidgets() { 699void GMainWindow::InitializeWidgets() {
698#ifdef YUZU_ENABLE_COMPATIBILITY_REPORTING 700#ifdef YUZU_ENABLE_COMPATIBILITY_REPORTING
699 ui.action_Report_Compatibility->setVisible(true); 701 ui->action_Report_Compatibility->setVisible(true);
700#endif 702#endif
701 render_window = new GRenderWindow(this, emu_thread.get(), input_subsystem, system); 703 render_window = new GRenderWindow(this, emu_thread.get(), input_subsystem, *system);
702 render_window->hide(); 704 render_window->hide();
703 705
704 game_list = new GameList(vfs, provider.get(), system, this); 706 game_list = new GameList(vfs, provider.get(), *system, this);
705 ui.horizontalLayout->addWidget(game_list); 707 ui->horizontalLayout->addWidget(game_list);
706 708
707 game_list_placeholder = new GameListPlaceholder(this); 709 game_list_placeholder = new GameListPlaceholder(this);
708 ui.horizontalLayout->addWidget(game_list_placeholder); 710 ui->horizontalLayout->addWidget(game_list_placeholder);
709 game_list_placeholder->setVisible(false); 711 game_list_placeholder->setVisible(false);
710 712
711 loading_screen = new LoadingScreen(this); 713 loading_screen = new LoadingScreen(this);
712 loading_screen->hide(); 714 loading_screen->hide();
713 ui.horizontalLayout->addWidget(loading_screen); 715 ui->horizontalLayout->addWidget(loading_screen);
714 connect(loading_screen, &LoadingScreen::Hidden, [&] { 716 connect(loading_screen, &LoadingScreen::Hidden, [&] {
715 loading_screen->Clear(); 717 loading_screen->Clear();
716 if (emulation_running) { 718 if (emulation_running) {
@@ -767,14 +769,14 @@ void GMainWindow::InitializeWidgets() {
767 tr("Handheld controller can't be used on docked mode. Pro " 769 tr("Handheld controller can't be used on docked mode. Pro "
768 "controller will be selected.")); 770 "controller will be selected."));
769 controller_type = Settings::ControllerType::ProController; 771 controller_type = Settings::ControllerType::ProController;
770 ConfigureDialog configure_dialog(this, hotkey_registry, input_subsystem.get(), system); 772 ConfigureDialog configure_dialog(this, hotkey_registry, input_subsystem.get(), *system);
771 configure_dialog.ApplyConfiguration(); 773 configure_dialog.ApplyConfiguration();
772 controller_dialog->refreshConfiguration(); 774 controller_dialog->refreshConfiguration();
773 } 775 }
774 776
775 Settings::values.use_docked_mode.SetValue(!is_docked); 777 Settings::values.use_docked_mode.SetValue(!is_docked);
776 dock_status_button->setChecked(!is_docked); 778 dock_status_button->setChecked(!is_docked);
777 OnDockedModeChanged(is_docked, !is_docked, system); 779 OnDockedModeChanged(is_docked, !is_docked, *system);
778 }); 780 });
779 dock_status_button->setText(tr("DOCK")); 781 dock_status_button->setText(tr("DOCK"));
780 dock_status_button->setCheckable(true); 782 dock_status_button->setCheckable(true);
@@ -798,7 +800,7 @@ void GMainWindow::InitializeWidgets() {
798 } 800 }
799 } 801 }
800 802
801 system.ApplySettings(); 803 system->ApplySettings();
802 UpdateGPUAccuracyButton(); 804 UpdateGPUAccuracyButton();
803 }); 805 });
804 UpdateGPUAccuracyButton(); 806 UpdateGPUAccuracyButton();
@@ -826,7 +828,7 @@ void GMainWindow::InitializeWidgets() {
826 Settings::values.renderer_backend.SetValue(Settings::RendererBackend::OpenGL); 828 Settings::values.renderer_backend.SetValue(Settings::RendererBackend::OpenGL);
827 } 829 }
828 830
829 system.ApplySettings(); 831 system->ApplySettings();
830 }); 832 });
831 statusBar()->insertPermanentWidget(0, renderer_status_button); 833 statusBar()->insertPermanentWidget(0, renderer_status_button);
832 834
@@ -835,7 +837,7 @@ void GMainWindow::InitializeWidgets() {
835} 837}
836 838
837void GMainWindow::InitializeDebugWidgets() { 839void GMainWindow::InitializeDebugWidgets() {
838 QMenu* debug_menu = ui.menu_View_Debugging; 840 QMenu* debug_menu = ui->menu_View_Debugging;
839 841
840#if MICROPROFILE_ENABLED 842#if MICROPROFILE_ENABLED
841 microProfileDialog = new MicroProfileDialog(this); 843 microProfileDialog = new MicroProfileDialog(this);
@@ -843,7 +845,7 @@ void GMainWindow::InitializeDebugWidgets() {
843 debug_menu->addAction(microProfileDialog->toggleViewAction()); 845 debug_menu->addAction(microProfileDialog->toggleViewAction());
844#endif 846#endif
845 847
846 waitTreeWidget = new WaitTreeWidget(system, this); 848 waitTreeWidget = new WaitTreeWidget(*system, this);
847 addDockWidget(Qt::LeftDockWidgetArea, waitTreeWidget); 849 addDockWidget(Qt::LeftDockWidgetArea, waitTreeWidget);
848 waitTreeWidget->hide(); 850 waitTreeWidget->hide();
849 debug_menu->addAction(waitTreeWidget->toggleViewAction()); 851 debug_menu->addAction(waitTreeWidget->toggleViewAction());
@@ -864,16 +866,16 @@ void GMainWindow::InitializeRecentFileMenuActions() {
864 actions_recent_files[i]->setVisible(false); 866 actions_recent_files[i]->setVisible(false);
865 connect(actions_recent_files[i], &QAction::triggered, this, &GMainWindow::OnMenuRecentFile); 867 connect(actions_recent_files[i], &QAction::triggered, this, &GMainWindow::OnMenuRecentFile);
866 868
867 ui.menu_recent_files->addAction(actions_recent_files[i]); 869 ui->menu_recent_files->addAction(actions_recent_files[i]);
868 } 870 }
869 ui.menu_recent_files->addSeparator(); 871 ui->menu_recent_files->addSeparator();
870 QAction* action_clear_recent_files = new QAction(this); 872 QAction* action_clear_recent_files = new QAction(this);
871 action_clear_recent_files->setText(tr("&Clear Recent Files")); 873 action_clear_recent_files->setText(tr("&Clear Recent Files"));
872 connect(action_clear_recent_files, &QAction::triggered, this, [this] { 874 connect(action_clear_recent_files, &QAction::triggered, this, [this] {
873 UISettings::values.recent_files.clear(); 875 UISettings::values.recent_files.clear();
874 UpdateRecentFiles(); 876 UpdateRecentFiles();
875 }); 877 });
876 ui.menu_recent_files->addAction(action_clear_recent_files); 878 ui->menu_recent_files->addAction(action_clear_recent_files);
877 879
878 UpdateRecentFiles(); 880 UpdateRecentFiles();
879} 881}
@@ -892,43 +894,43 @@ void GMainWindow::InitializeHotkeys() {
892 const QString fullscreen = QStringLiteral("Fullscreen"); 894 const QString fullscreen = QStringLiteral("Fullscreen");
893 const QString capture_screenshot = QStringLiteral("Capture Screenshot"); 895 const QString capture_screenshot = QStringLiteral("Capture Screenshot");
894 896
895 ui.action_Load_File->setShortcut(hotkey_registry.GetKeySequence(main_window, load_file)); 897 ui->action_Load_File->setShortcut(hotkey_registry.GetKeySequence(main_window, load_file));
896 ui.action_Load_File->setShortcutContext( 898 ui->action_Load_File->setShortcutContext(
897 hotkey_registry.GetShortcutContext(main_window, load_file)); 899 hotkey_registry.GetShortcutContext(main_window, load_file));
898 900
899 ui.action_Load_Amiibo->setShortcut(hotkey_registry.GetKeySequence(main_window, load_amiibo)); 901 ui->action_Load_Amiibo->setShortcut(hotkey_registry.GetKeySequence(main_window, load_amiibo));
900 ui.action_Load_Amiibo->setShortcutContext( 902 ui->action_Load_Amiibo->setShortcutContext(
901 hotkey_registry.GetShortcutContext(main_window, load_amiibo)); 903 hotkey_registry.GetShortcutContext(main_window, load_amiibo));
902 904
903 ui.action_Exit->setShortcut(hotkey_registry.GetKeySequence(main_window, exit_yuzu)); 905 ui->action_Exit->setShortcut(hotkey_registry.GetKeySequence(main_window, exit_yuzu));
904 ui.action_Exit->setShortcutContext(hotkey_registry.GetShortcutContext(main_window, exit_yuzu)); 906 ui->action_Exit->setShortcutContext(hotkey_registry.GetShortcutContext(main_window, exit_yuzu));
905 907
906 ui.action_Restart->setShortcut(hotkey_registry.GetKeySequence(main_window, restart_emulation)); 908 ui->action_Restart->setShortcut(hotkey_registry.GetKeySequence(main_window, restart_emulation));
907 ui.action_Restart->setShortcutContext( 909 ui->action_Restart->setShortcutContext(
908 hotkey_registry.GetShortcutContext(main_window, restart_emulation)); 910 hotkey_registry.GetShortcutContext(main_window, restart_emulation));
909 911
910 ui.action_Stop->setShortcut(hotkey_registry.GetKeySequence(main_window, stop_emulation)); 912 ui->action_Stop->setShortcut(hotkey_registry.GetKeySequence(main_window, stop_emulation));
911 ui.action_Stop->setShortcutContext( 913 ui->action_Stop->setShortcutContext(
912 hotkey_registry.GetShortcutContext(main_window, stop_emulation)); 914 hotkey_registry.GetShortcutContext(main_window, stop_emulation));
913 915
914 ui.action_Show_Filter_Bar->setShortcut( 916 ui->action_Show_Filter_Bar->setShortcut(
915 hotkey_registry.GetKeySequence(main_window, toggle_filter_bar)); 917 hotkey_registry.GetKeySequence(main_window, toggle_filter_bar));
916 ui.action_Show_Filter_Bar->setShortcutContext( 918 ui->action_Show_Filter_Bar->setShortcutContext(
917 hotkey_registry.GetShortcutContext(main_window, toggle_filter_bar)); 919 hotkey_registry.GetShortcutContext(main_window, toggle_filter_bar));
918 920
919 ui.action_Show_Status_Bar->setShortcut( 921 ui->action_Show_Status_Bar->setShortcut(
920 hotkey_registry.GetKeySequence(main_window, toggle_status_bar)); 922 hotkey_registry.GetKeySequence(main_window, toggle_status_bar));
921 ui.action_Show_Status_Bar->setShortcutContext( 923 ui->action_Show_Status_Bar->setShortcutContext(
922 hotkey_registry.GetShortcutContext(main_window, toggle_status_bar)); 924 hotkey_registry.GetShortcutContext(main_window, toggle_status_bar));
923 925
924 ui.action_Capture_Screenshot->setShortcut( 926 ui->action_Capture_Screenshot->setShortcut(
925 hotkey_registry.GetKeySequence(main_window, capture_screenshot)); 927 hotkey_registry.GetKeySequence(main_window, capture_screenshot));
926 ui.action_Capture_Screenshot->setShortcutContext( 928 ui->action_Capture_Screenshot->setShortcutContext(
927 hotkey_registry.GetShortcutContext(main_window, capture_screenshot)); 929 hotkey_registry.GetShortcutContext(main_window, capture_screenshot));
928 930
929 ui.action_Fullscreen->setShortcut( 931 ui->action_Fullscreen->setShortcut(
930 hotkey_registry.GetHotkey(main_window, fullscreen, this)->key()); 932 hotkey_registry.GetHotkey(main_window, fullscreen, this)->key());
931 ui.action_Fullscreen->setShortcutContext( 933 ui->action_Fullscreen->setShortcutContext(
932 hotkey_registry.GetShortcutContext(main_window, fullscreen)); 934 hotkey_registry.GetShortcutContext(main_window, fullscreen));
933 935
934 connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Load File"), this), 936 connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Load File"), this),
@@ -946,19 +948,19 @@ void GMainWindow::InitializeHotkeys() {
946 }); 948 });
947 connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Restart Emulation"), this), 949 connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Restart Emulation"), this),
948 &QShortcut::activated, this, [this] { 950 &QShortcut::activated, this, [this] {
949 if (!system.IsPoweredOn()) { 951 if (!system->IsPoweredOn()) {
950 return; 952 return;
951 } 953 }
952 BootGame(game_path); 954 BootGame(game_path);
953 }); 955 });
954 connect(hotkey_registry.GetHotkey(main_window, fullscreen, render_window), 956 connect(hotkey_registry.GetHotkey(main_window, fullscreen, render_window),
955 &QShortcut::activated, ui.action_Fullscreen, &QAction::trigger); 957 &QShortcut::activated, ui->action_Fullscreen, &QAction::trigger);
956 connect(hotkey_registry.GetHotkey(main_window, fullscreen, render_window), 958 connect(hotkey_registry.GetHotkey(main_window, fullscreen, render_window),
957 &QShortcut::activatedAmbiguously, ui.action_Fullscreen, &QAction::trigger); 959 &QShortcut::activatedAmbiguously, ui->action_Fullscreen, &QAction::trigger);
958 connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Exit Fullscreen"), this), 960 connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Exit Fullscreen"), this),
959 &QShortcut::activated, this, [&] { 961 &QShortcut::activated, this, [&] {
960 if (emulation_running) { 962 if (emulation_running) {
961 ui.action_Fullscreen->setChecked(false); 963 ui->action_Fullscreen->setChecked(false);
962 ToggleFullscreen(); 964 ToggleFullscreen();
963 } 965 }
964 }); 966 });
@@ -987,7 +989,7 @@ void GMainWindow::InitializeHotkeys() {
987 }); 989 });
988 connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Load Amiibo"), this), 990 connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Load Amiibo"), this),
989 &QShortcut::activated, this, [&] { 991 &QShortcut::activated, this, [&] {
990 if (ui.action_Load_Amiibo->isEnabled()) { 992 if (ui->action_Load_Amiibo->isEnabled()) {
991 OnLoadAmiibo(); 993 OnLoadAmiibo();
992 } 994 }
993 }); 995 });
@@ -1002,7 +1004,7 @@ void GMainWindow::InitializeHotkeys() {
1002 Settings::values.use_docked_mode.SetValue( 1004 Settings::values.use_docked_mode.SetValue(
1003 !Settings::values.use_docked_mode.GetValue()); 1005 !Settings::values.use_docked_mode.GetValue());
1004 OnDockedModeChanged(!Settings::values.use_docked_mode.GetValue(), 1006 OnDockedModeChanged(!Settings::values.use_docked_mode.GetValue(),
1005 Settings::values.use_docked_mode.GetValue(), system); 1007 Settings::values.use_docked_mode.GetValue(), *system);
1006 dock_status_button->setChecked(Settings::values.use_docked_mode.GetValue()); 1008 dock_status_button->setChecked(Settings::values.use_docked_mode.GetValue());
1007 }); 1009 });
1008 connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Mute Audio"), this), 1010 connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Mute Audio"), this),
@@ -1068,20 +1070,20 @@ void GMainWindow::RestoreUIState() {
1068 1070
1069 game_list->LoadInterfaceLayout(); 1071 game_list->LoadInterfaceLayout();
1070 1072
1071 ui.action_Single_Window_Mode->setChecked(UISettings::values.single_window_mode.GetValue()); 1073 ui->action_Single_Window_Mode->setChecked(UISettings::values.single_window_mode.GetValue());
1072 ToggleWindowMode(); 1074 ToggleWindowMode();
1073 1075
1074 ui.action_Fullscreen->setChecked(UISettings::values.fullscreen.GetValue()); 1076 ui->action_Fullscreen->setChecked(UISettings::values.fullscreen.GetValue());
1075 1077
1076 ui.action_Display_Dock_Widget_Headers->setChecked( 1078 ui->action_Display_Dock_Widget_Headers->setChecked(
1077 UISettings::values.display_titlebar.GetValue()); 1079 UISettings::values.display_titlebar.GetValue());
1078 OnDisplayTitleBars(ui.action_Display_Dock_Widget_Headers->isChecked()); 1080 OnDisplayTitleBars(ui->action_Display_Dock_Widget_Headers->isChecked());
1079 1081
1080 ui.action_Show_Filter_Bar->setChecked(UISettings::values.show_filter_bar.GetValue()); 1082 ui->action_Show_Filter_Bar->setChecked(UISettings::values.show_filter_bar.GetValue());
1081 game_list->SetFilterVisible(ui.action_Show_Filter_Bar->isChecked()); 1083 game_list->SetFilterVisible(ui->action_Show_Filter_Bar->isChecked());
1082 1084
1083 ui.action_Show_Status_Bar->setChecked(UISettings::values.show_status_bar.GetValue()); 1085 ui->action_Show_Status_Bar->setChecked(UISettings::values.show_status_bar.GetValue());
1084 statusBar()->setVisible(ui.action_Show_Status_Bar->isChecked()); 1086 statusBar()->setVisible(ui->action_Show_Status_Bar->isChecked());
1085 Debugger::ToggleConsole(); 1087 Debugger::ToggleConsole();
1086} 1088}
1087 1089
@@ -1093,11 +1095,11 @@ void GMainWindow::OnAppFocusStateChanged(Qt::ApplicationState state) {
1093 state != Qt::ApplicationActive) { 1095 state != Qt::ApplicationActive) {
1094 LOG_DEBUG(Frontend, "ApplicationState unusual flag: {} ", state); 1096 LOG_DEBUG(Frontend, "ApplicationState unusual flag: {} ", state);
1095 } 1097 }
1096 if (ui.action_Pause->isEnabled() && 1098 if (ui->action_Pause->isEnabled() &&
1097 (state & (Qt::ApplicationHidden | Qt::ApplicationInactive))) { 1099 (state & (Qt::ApplicationHidden | Qt::ApplicationInactive))) {
1098 auto_paused = true; 1100 auto_paused = true;
1099 OnPauseGame(); 1101 OnPauseGame();
1100 } else if (ui.action_Start->isEnabled() && auto_paused && state == Qt::ApplicationActive) { 1102 } else if (ui->action_Start->isEnabled() && auto_paused && state == Qt::ApplicationActive) {
1101 auto_paused = false; 1103 auto_paused = false;
1102 OnStartGame(); 1104 OnStartGame();
1103 } 1105 }
@@ -1142,59 +1144,60 @@ void GMainWindow::ConnectWidgetEvents() {
1142 1144
1143void GMainWindow::ConnectMenuEvents() { 1145void GMainWindow::ConnectMenuEvents() {
1144 // File 1146 // File
1145 connect(ui.action_Load_File, &QAction::triggered, this, &GMainWindow::OnMenuLoadFile); 1147 connect(ui->action_Load_File, &QAction::triggered, this, &GMainWindow::OnMenuLoadFile);
1146 connect(ui.action_Load_Folder, &QAction::triggered, this, &GMainWindow::OnMenuLoadFolder); 1148 connect(ui->action_Load_Folder, &QAction::triggered, this, &GMainWindow::OnMenuLoadFolder);
1147 connect(ui.action_Install_File_NAND, &QAction::triggered, this, 1149 connect(ui->action_Install_File_NAND, &QAction::triggered, this,
1148 &GMainWindow::OnMenuInstallToNAND); 1150 &GMainWindow::OnMenuInstallToNAND);
1149 connect(ui.action_Exit, &QAction::triggered, this, &QMainWindow::close); 1151 connect(ui->action_Exit, &QAction::triggered, this, &QMainWindow::close);
1150 connect(ui.action_Load_Amiibo, &QAction::triggered, this, &GMainWindow::OnLoadAmiibo); 1152 connect(ui->action_Load_Amiibo, &QAction::triggered, this, &GMainWindow::OnLoadAmiibo);
1151 1153
1152 // Emulation 1154 // Emulation
1153 connect(ui.action_Start, &QAction::triggered, this, &GMainWindow::OnStartGame); 1155 connect(ui->action_Start, &QAction::triggered, this, &GMainWindow::OnStartGame);
1154 connect(ui.action_Pause, &QAction::triggered, this, &GMainWindow::OnPauseGame); 1156 connect(ui->action_Pause, &QAction::triggered, this, &GMainWindow::OnPauseGame);
1155 connect(ui.action_Stop, &QAction::triggered, this, &GMainWindow::OnStopGame); 1157 connect(ui->action_Stop, &QAction::triggered, this, &GMainWindow::OnStopGame);
1156 connect(ui.action_Report_Compatibility, &QAction::triggered, this, 1158 connect(ui->action_Report_Compatibility, &QAction::triggered, this,
1157 &GMainWindow::OnMenuReportCompatibility); 1159 &GMainWindow::OnMenuReportCompatibility);
1158 connect(ui.action_Open_Mods_Page, &QAction::triggered, this, &GMainWindow::OnOpenModsPage); 1160 connect(ui->action_Open_Mods_Page, &QAction::triggered, this, &GMainWindow::OnOpenModsPage);
1159 connect(ui.action_Open_Quickstart_Guide, &QAction::triggered, this, 1161 connect(ui->action_Open_Quickstart_Guide, &QAction::triggered, this,
1160 &GMainWindow::OnOpenQuickstartGuide); 1162 &GMainWindow::OnOpenQuickstartGuide);
1161 connect(ui.action_Open_FAQ, &QAction::triggered, this, &GMainWindow::OnOpenFAQ); 1163 connect(ui->action_Open_FAQ, &QAction::triggered, this, &GMainWindow::OnOpenFAQ);
1162 connect(ui.action_Restart, &QAction::triggered, this, [this] { BootGame(QString(game_path)); }); 1164 connect(ui->action_Restart, &QAction::triggered, this,
1163 connect(ui.action_Configure, &QAction::triggered, this, &GMainWindow::OnConfigure); 1165 [this] { BootGame(QString(game_path)); });
1164 connect(ui.action_Configure_Tas, &QAction::triggered, this, &GMainWindow::OnConfigureTas); 1166 connect(ui->action_Configure, &QAction::triggered, this, &GMainWindow::OnConfigure);
1165 connect(ui.action_Configure_Current_Game, &QAction::triggered, this, 1167 connect(ui->action_Configure_Tas, &QAction::triggered, this, &GMainWindow::OnConfigureTas);
1168 connect(ui->action_Configure_Current_Game, &QAction::triggered, this,
1166 &GMainWindow::OnConfigurePerGame); 1169 &GMainWindow::OnConfigurePerGame);
1167 1170
1168 // View 1171 // View
1169 connect(ui.action_Single_Window_Mode, &QAction::triggered, this, 1172 connect(ui->action_Single_Window_Mode, &QAction::triggered, this,
1170 &GMainWindow::ToggleWindowMode); 1173 &GMainWindow::ToggleWindowMode);
1171 connect(ui.action_Display_Dock_Widget_Headers, &QAction::triggered, this, 1174 connect(ui->action_Display_Dock_Widget_Headers, &QAction::triggered, this,
1172 &GMainWindow::OnDisplayTitleBars); 1175 &GMainWindow::OnDisplayTitleBars);
1173 connect(ui.action_Show_Filter_Bar, &QAction::triggered, this, &GMainWindow::OnToggleFilterBar); 1176 connect(ui->action_Show_Filter_Bar, &QAction::triggered, this, &GMainWindow::OnToggleFilterBar);
1174 connect(ui.action_Show_Status_Bar, &QAction::triggered, statusBar(), &QStatusBar::setVisible); 1177 connect(ui->action_Show_Status_Bar, &QAction::triggered, statusBar(), &QStatusBar::setVisible);
1175 1178
1176 connect(ui.action_Reset_Window_Size_720, &QAction::triggered, this, 1179 connect(ui->action_Reset_Window_Size_720, &QAction::triggered, this,
1177 &GMainWindow::ResetWindowSize720); 1180 &GMainWindow::ResetWindowSize720);
1178 connect(ui.action_Reset_Window_Size_900, &QAction::triggered, this, 1181 connect(ui->action_Reset_Window_Size_900, &QAction::triggered, this,
1179 &GMainWindow::ResetWindowSize900); 1182 &GMainWindow::ResetWindowSize900);
1180 connect(ui.action_Reset_Window_Size_1080, &QAction::triggered, this, 1183 connect(ui->action_Reset_Window_Size_1080, &QAction::triggered, this,
1181 &GMainWindow::ResetWindowSize1080); 1184 &GMainWindow::ResetWindowSize1080);
1182 ui.menu_Reset_Window_Size->addAction(ui.action_Reset_Window_Size_720); 1185 ui->menu_Reset_Window_Size->addAction(ui->action_Reset_Window_Size_720);
1183 ui.menu_Reset_Window_Size->addAction(ui.action_Reset_Window_Size_900); 1186 ui->menu_Reset_Window_Size->addAction(ui->action_Reset_Window_Size_900);
1184 ui.menu_Reset_Window_Size->addAction(ui.action_Reset_Window_Size_1080); 1187 ui->menu_Reset_Window_Size->addAction(ui->action_Reset_Window_Size_1080);
1185 1188
1186 // Fullscreen 1189 // Fullscreen
1187 connect(ui.action_Fullscreen, &QAction::triggered, this, &GMainWindow::ToggleFullscreen); 1190 connect(ui->action_Fullscreen, &QAction::triggered, this, &GMainWindow::ToggleFullscreen);
1188 1191
1189 // Movie 1192 // Movie
1190 connect(ui.action_Capture_Screenshot, &QAction::triggered, this, 1193 connect(ui->action_Capture_Screenshot, &QAction::triggered, this,
1191 &GMainWindow::OnCaptureScreenshot); 1194 &GMainWindow::OnCaptureScreenshot);
1192 1195
1193 // Help 1196 // Help
1194 connect(ui.action_Open_yuzu_Folder, &QAction::triggered, this, &GMainWindow::OnOpenYuzuFolder); 1197 connect(ui->action_Open_yuzu_Folder, &QAction::triggered, this, &GMainWindow::OnOpenYuzuFolder);
1195 connect(ui.action_Rederive, &QAction::triggered, this, 1198 connect(ui->action_Rederive, &QAction::triggered, this,
1196 std::bind(&GMainWindow::OnReinitializeKeys, this, ReinitializeKeyBehavior::Warning)); 1199 std::bind(&GMainWindow::OnReinitializeKeys, this, ReinitializeKeyBehavior::Warning));
1197 connect(ui.action_About, &QAction::triggered, this, &GMainWindow::OnAbout); 1200 connect(ui->action_About, &QAction::triggered, this, &GMainWindow::OnAbout);
1198} 1201}
1199 1202
1200void GMainWindow::OnDisplayTitleBars(bool show) { 1203void GMainWindow::OnDisplayTitleBars(bool show) {
@@ -1238,9 +1241,9 @@ bool GMainWindow::LoadROM(const QString& filename, u64 program_id, std::size_t p
1238 return false; 1241 return false;
1239 } 1242 }
1240 1243
1241 system.SetFilesystem(vfs); 1244 system->SetFilesystem(vfs);
1242 1245
1243 system.SetAppletFrontendSet({ 1246 system->SetAppletFrontendSet({
1244 std::make_unique<QtControllerSelector>(*this), // Controller Selector 1247 std::make_unique<QtControllerSelector>(*this), // Controller Selector
1245 std::make_unique<QtErrorDisplay>(*this), // Error Display 1248 std::make_unique<QtErrorDisplay>(*this), // Error Display
1246 nullptr, // Parental Controls 1249 nullptr, // Parental Controls
@@ -1250,14 +1253,14 @@ bool GMainWindow::LoadROM(const QString& filename, u64 program_id, std::size_t p
1250 std::make_unique<QtWebBrowser>(*this), // Web Browser 1253 std::make_unique<QtWebBrowser>(*this), // Web Browser
1251 }); 1254 });
1252 1255
1253 const Core::System::ResultStatus result{ 1256 const Core::SystemResultStatus result{
1254 system.Load(*render_window, filename.toStdString(), program_id, program_index)}; 1257 system->Load(*render_window, filename.toStdString(), program_id, program_index)};
1255 1258
1256 const auto drd_callout = (UISettings::values.callout_flags.GetValue() & 1259 const auto drd_callout = (UISettings::values.callout_flags.GetValue() &
1257 static_cast<u32>(CalloutFlag::DRDDeprecation)) == 0; 1260 static_cast<u32>(CalloutFlag::DRDDeprecation)) == 0;
1258 1261
1259 if (result == Core::System::ResultStatus::Success && 1262 if (result == Core::SystemResultStatus::Success &&
1260 system.GetAppLoader().GetFileType() == Loader::FileType::DeconstructedRomDirectory && 1263 system->GetAppLoader().GetFileType() == Loader::FileType::DeconstructedRomDirectory &&
1261 drd_callout) { 1264 drd_callout) {
1262 UISettings::values.callout_flags = UISettings::values.callout_flags.GetValue() | 1265 UISettings::values.callout_flags = UISettings::values.callout_flags.GetValue() |
1263 static_cast<u32>(CalloutFlag::DRDDeprecation); 1266 static_cast<u32>(CalloutFlag::DRDDeprecation);
@@ -1271,14 +1274,14 @@ bool GMainWindow::LoadROM(const QString& filename, u64 program_id, std::size_t p
1271 "wiki</a>. This message will not be shown again.")); 1274 "wiki</a>. This message will not be shown again."));
1272 } 1275 }
1273 1276
1274 if (result != Core::System::ResultStatus::Success) { 1277 if (result != Core::SystemResultStatus::Success) {
1275 switch (result) { 1278 switch (result) {
1276 case Core::System::ResultStatus::ErrorGetLoader: 1279 case Core::SystemResultStatus::ErrorGetLoader:
1277 LOG_CRITICAL(Frontend, "Failed to obtain loader for {}!", filename.toStdString()); 1280 LOG_CRITICAL(Frontend, "Failed to obtain loader for {}!", filename.toStdString());
1278 QMessageBox::critical(this, tr("Error while loading ROM!"), 1281 QMessageBox::critical(this, tr("Error while loading ROM!"),
1279 tr("The ROM format is not supported.")); 1282 tr("The ROM format is not supported."));
1280 break; 1283 break;
1281 case Core::System::ResultStatus::ErrorVideoCore: 1284 case Core::SystemResultStatus::ErrorVideoCore:
1282 QMessageBox::critical( 1285 QMessageBox::critical(
1283 this, tr("An error occurred initializing the video core."), 1286 this, tr("An error occurred initializing the video core."),
1284 tr("yuzu has encountered an error while running the video core, please see the " 1287 tr("yuzu has encountered an error while running the video core, please see the "
@@ -1292,8 +1295,8 @@ bool GMainWindow::LoadROM(const QString& filename, u64 program_id, std::size_t p
1292 break; 1295 break;
1293 1296
1294 default: 1297 default:
1295 if (result > Core::System::ResultStatus::ErrorLoader) { 1298 if (result > Core::SystemResultStatus::ErrorLoader) {
1296 const u16 loader_id = static_cast<u16>(Core::System::ResultStatus::ErrorLoader); 1299 const u16 loader_id = static_cast<u16>(Core::SystemResultStatus::ErrorLoader);
1297 const u16 error_id = static_cast<u16>(result) - loader_id; 1300 const u16 error_id = static_cast<u16>(result) - loader_id;
1298 const std::string error_code = fmt::format("({:04X}-{:04X})", loader_id, error_id); 1301 const std::string error_code = fmt::format("({:04X}-{:04X})", loader_id, error_id);
1299 LOG_CRITICAL(Frontend, "Failed to load ROM! {}", error_code); 1302 LOG_CRITICAL(Frontend, "Failed to load ROM! {}", error_code);
@@ -1321,7 +1324,7 @@ bool GMainWindow::LoadROM(const QString& filename, u64 program_id, std::size_t p
1321 } 1324 }
1322 game_path = filename; 1325 game_path = filename;
1323 1326
1324 system.TelemetrySession().AddField(Common::Telemetry::FieldType::App, "Frontend", "Qt"); 1327 system->TelemetrySession().AddField(Common::Telemetry::FieldType::App, "Frontend", "Qt");
1325 return true; 1328 return true;
1326} 1329}
1327 1330
@@ -1348,7 +1351,7 @@ void GMainWindow::BootGame(const QString& filename, u64 program_id, std::size_t
1348 last_filename_booted = filename; 1351 last_filename_booted = filename;
1349 1352
1350 const auto v_file = Core::GetGameFileFromPath(vfs, filename.toUtf8().constData()); 1353 const auto v_file = Core::GetGameFileFromPath(vfs, filename.toUtf8().constData());
1351 const auto loader = Loader::GetLoader(system, v_file, program_id, program_index); 1354 const auto loader = Loader::GetLoader(*system, v_file, program_id, program_index);
1352 1355
1353 if (loader != nullptr && loader->ReadProgramId(title_id) == Loader::ResultStatus::Success && 1356 if (loader != nullptr && loader->ReadProgramId(title_id) == Loader::ResultStatus::Success &&
1354 type == StartGameType::Normal) { 1357 type == StartGameType::Normal) {
@@ -1357,7 +1360,7 @@ void GMainWindow::BootGame(const QString& filename, u64 program_id, std::size_t
1357 const auto config_file_name = title_id == 0 1360 const auto config_file_name = title_id == 0
1358 ? Common::FS::PathToUTF8String(file_path.filename()) 1361 ? Common::FS::PathToUTF8String(file_path.filename())
1359 : fmt::format("{:016X}", title_id); 1362 : fmt::format("{:016X}", title_id);
1360 Config per_game_config(system, config_file_name, Config::ConfigType::PerGameConfig); 1363 Config per_game_config(*system, config_file_name, Config::ConfigType::PerGameConfig);
1361 } 1364 }
1362 1365
1363 ConfigureVibration::SetAllVibrationDevices(); 1366 ConfigureVibration::SetAllVibrationDevices();
@@ -1380,16 +1383,16 @@ void GMainWindow::BootGame(const QString& filename, u64 program_id, std::size_t
1380 return; 1383 return;
1381 1384
1382 // Create and start the emulation thread 1385 // Create and start the emulation thread
1383 emu_thread = std::make_unique<EmuThread>(system); 1386 emu_thread = std::make_unique<EmuThread>(*system);
1384 emit EmulationStarting(emu_thread.get()); 1387 emit EmulationStarting(emu_thread.get());
1385 emu_thread->start(); 1388 emu_thread->start();
1386 1389
1387 // Register an ExecuteProgram callback such that Core can execute a sub-program 1390 // Register an ExecuteProgram callback such that Core can execute a sub-program
1388 system.RegisterExecuteProgramCallback( 1391 system->RegisterExecuteProgramCallback(
1389 [this](std::size_t program_index) { render_window->ExecuteProgram(program_index); }); 1392 [this](std::size_t program_index) { render_window->ExecuteProgram(program_index); });
1390 1393
1391 // Register an Exit callback such that Core can exit the currently running application. 1394 // Register an Exit callback such that Core can exit the currently running application.
1392 system.RegisterExitCallback([this]() { render_window->Exit(); }); 1395 system->RegisterExitCallback([this]() { render_window->Exit(); });
1393 1396
1394 connect(render_window, &GRenderWindow::Closed, this, &GMainWindow::OnStopGame); 1397 connect(render_window, &GRenderWindow::Closed, this, &GMainWindow::OnStopGame);
1395 connect(render_window, &GRenderWindow::MouseActivity, this, &GMainWindow::OnMouseActivity); 1398 connect(render_window, &GRenderWindow::MouseActivity, this, &GMainWindow::OnMouseActivity);
@@ -1405,7 +1408,7 @@ void GMainWindow::BootGame(const QString& filename, u64 program_id, std::size_t
1405 1408
1406 // Update the GUI 1409 // Update the GUI
1407 UpdateStatusButtons(); 1410 UpdateStatusButtons();
1408 if (ui.action_Single_Window_Mode->isChecked()) { 1411 if (ui->action_Single_Window_Mode->isChecked()) {
1409 game_list->hide(); 1412 game_list->hide();
1410 game_list_placeholder->hide(); 1413 game_list_placeholder->hide();
1411 } 1414 }
@@ -1423,11 +1426,11 @@ void GMainWindow::BootGame(const QString& filename, u64 program_id, std::size_t
1423 1426
1424 std::string title_name; 1427 std::string title_name;
1425 std::string title_version; 1428 std::string title_version;
1426 const auto res = system.GetGameName(title_name); 1429 const auto res = system->GetGameName(title_name);
1427 1430
1428 const auto metadata = [this, title_id] { 1431 const auto metadata = [this, title_id] {
1429 const FileSys::PatchManager pm(title_id, system.GetFileSystemController(), 1432 const FileSys::PatchManager pm(title_id, system->GetFileSystemController(),
1430 system.GetContentProvider()); 1433 system->GetContentProvider());
1431 return pm.GetControlMetadata(); 1434 return pm.GetControlMetadata();
1432 }(); 1435 }();
1433 if (metadata.first != nullptr) { 1436 if (metadata.first != nullptr) {
@@ -1438,20 +1441,20 @@ void GMainWindow::BootGame(const QString& filename, u64 program_id, std::size_t
1438 title_name = Common::FS::PathToUTF8String( 1441 title_name = Common::FS::PathToUTF8String(
1439 std::filesystem::path{filename.toStdU16String()}.filename()); 1442 std::filesystem::path{filename.toStdU16String()}.filename());
1440 } 1443 }
1441 const bool is_64bit = system.Kernel().CurrentProcess()->Is64BitProcess(); 1444 const bool is_64bit = system->Kernel().CurrentProcess()->Is64BitProcess();
1442 const auto instruction_set_suffix = is_64bit ? tr("(64-bit)") : tr("(32-bit)"); 1445 const auto instruction_set_suffix = is_64bit ? tr("(64-bit)") : tr("(32-bit)");
1443 title_name = tr("%1 %2", "%1 is the title name. %2 indicates if the title is 64-bit or 32-bit") 1446 title_name = tr("%1 %2", "%1 is the title name. %2 indicates if the title is 64-bit or 32-bit")
1444 .arg(QString::fromStdString(title_name), instruction_set_suffix) 1447 .arg(QString::fromStdString(title_name), instruction_set_suffix)
1445 .toStdString(); 1448 .toStdString();
1446 LOG_INFO(Frontend, "Booting game: {:016X} | {} | {}", title_id, title_name, title_version); 1449 LOG_INFO(Frontend, "Booting game: {:016X} | {} | {}", title_id, title_name, title_version);
1447 const auto gpu_vendor = system.GPU().Renderer().GetDeviceVendor(); 1450 const auto gpu_vendor = system->GPU().Renderer().GetDeviceVendor();
1448 UpdateWindowTitle(title_name, title_version, gpu_vendor); 1451 UpdateWindowTitle(title_name, title_version, gpu_vendor);
1449 1452
1450 loading_screen->Prepare(system.GetAppLoader()); 1453 loading_screen->Prepare(system->GetAppLoader());
1451 loading_screen->show(); 1454 loading_screen->show();
1452 1455
1453 emulation_running = true; 1456 emulation_running = true;
1454 if (ui.action_Fullscreen->isChecked()) { 1457 if (ui->action_Fullscreen->isChecked()) {
1455 ShowFullscreen(); 1458 ShowFullscreen();
1456 } 1459 }
1457 OnStartGame(); 1460 OnStartGame();
@@ -1462,7 +1465,7 @@ void GMainWindow::ShutdownGame() {
1462 return; 1465 return;
1463 } 1466 }
1464 1467
1465 if (ui.action_Fullscreen->isChecked()) { 1468 if (ui->action_Fullscreen->isChecked()) {
1466 HideFullscreen(); 1469 HideFullscreen();
1467 } 1470 }
1468 1471
@@ -1483,15 +1486,15 @@ void GMainWindow::ShutdownGame() {
1483 disconnect(render_window, &GRenderWindow::Closed, this, &GMainWindow::OnStopGame); 1486 disconnect(render_window, &GRenderWindow::Closed, this, &GMainWindow::OnStopGame);
1484 1487
1485 // Update the GUI 1488 // Update the GUI
1486 ui.action_Start->setEnabled(false); 1489 ui->action_Start->setEnabled(false);
1487 ui.action_Start->setText(tr("Start")); 1490 ui->action_Start->setText(tr("Start"));
1488 ui.action_Pause->setEnabled(false); 1491 ui->action_Pause->setEnabled(false);
1489 ui.action_Stop->setEnabled(false); 1492 ui->action_Stop->setEnabled(false);
1490 ui.action_Restart->setEnabled(false); 1493 ui->action_Restart->setEnabled(false);
1491 ui.action_Configure_Current_Game->setEnabled(false); 1494 ui->action_Configure_Current_Game->setEnabled(false);
1492 ui.action_Report_Compatibility->setEnabled(false); 1495 ui->action_Report_Compatibility->setEnabled(false);
1493 ui.action_Load_Amiibo->setEnabled(false); 1496 ui->action_Load_Amiibo->setEnabled(false);
1494 ui.action_Capture_Screenshot->setEnabled(false); 1497 ui->action_Capture_Screenshot->setEnabled(false);
1495 render_window->hide(); 1498 render_window->hide();
1496 loading_screen->hide(); 1499 loading_screen->hide();
1497 loading_screen->Clear(); 1500 loading_screen->Clear();
@@ -1553,7 +1556,7 @@ void GMainWindow::UpdateRecentFiles() {
1553 } 1556 }
1554 1557
1555 // Enable the recent files menu if the list isn't empty 1558 // Enable the recent files menu if the list isn't empty
1556 ui.menu_recent_files->setEnabled(num_recent_files != 0); 1559 ui->menu_recent_files->setEnabled(num_recent_files != 0);
1557} 1560}
1558 1561
1559void GMainWindow::OnGameListLoadFile(QString game_path, u64 program_id) { 1562void GMainWindow::OnGameListLoadFile(QString game_path, u64 program_id) {
@@ -1566,15 +1569,15 @@ void GMainWindow::OnGameListOpenFolder(u64 program_id, GameListOpenTarget target
1566 QString open_target; 1569 QString open_target;
1567 1570
1568 const auto [user_save_size, device_save_size] = [this, &game_path, &program_id] { 1571 const auto [user_save_size, device_save_size] = [this, &game_path, &program_id] {
1569 const FileSys::PatchManager pm{program_id, system.GetFileSystemController(), 1572 const FileSys::PatchManager pm{program_id, system->GetFileSystemController(),
1570 system.GetContentProvider()}; 1573 system->GetContentProvider()};
1571 const auto control = pm.GetControlMetadata().first; 1574 const auto control = pm.GetControlMetadata().first;
1572 if (control != nullptr) { 1575 if (control != nullptr) {
1573 return std::make_pair(control->GetDefaultNormalSaveSize(), 1576 return std::make_pair(control->GetDefaultNormalSaveSize(),
1574 control->GetDeviceSaveDataSize()); 1577 control->GetDeviceSaveDataSize());
1575 } else { 1578 } else {
1576 const auto file = Core::GetGameFileFromPath(vfs, game_path); 1579 const auto file = Core::GetGameFileFromPath(vfs, game_path);
1577 const auto loader = Loader::GetLoader(system, file); 1580 const auto loader = Loader::GetLoader(*system, file);
1578 1581
1579 FileSys::NACP nacp{}; 1582 FileSys::NACP nacp{};
1580 loader->ReadControlData(nacp); 1583 loader->ReadControlData(nacp);
@@ -1617,14 +1620,14 @@ void GMainWindow::OnGameListOpenFolder(u64 program_id, GameListOpenTarget target
1617 ASSERT(user_id); 1620 ASSERT(user_id);
1618 1621
1619 const auto user_save_data_path = FileSys::SaveDataFactory::GetFullPath( 1622 const auto user_save_data_path = FileSys::SaveDataFactory::GetFullPath(
1620 system, FileSys::SaveDataSpaceId::NandUser, FileSys::SaveDataType::SaveData, 1623 *system, FileSys::SaveDataSpaceId::NandUser, FileSys::SaveDataType::SaveData,
1621 program_id, user_id->uuid, 0); 1624 program_id, user_id->uuid, 0);
1622 1625
1623 path = Common::FS::ConcatPathSafe(nand_dir, user_save_data_path); 1626 path = Common::FS::ConcatPathSafe(nand_dir, user_save_data_path);
1624 } else { 1627 } else {
1625 // Device save data 1628 // Device save data
1626 const auto device_save_data_path = FileSys::SaveDataFactory::GetFullPath( 1629 const auto device_save_data_path = FileSys::SaveDataFactory::GetFullPath(
1627 system, FileSys::SaveDataSpaceId::NandUser, FileSys::SaveDataType::SaveData, 1630 *system, FileSys::SaveDataSpaceId::NandUser, FileSys::SaveDataType::SaveData,
1628 program_id, {}, 0); 1631 program_id, {}, 0);
1629 1632
1630 path = Common::FS::ConcatPathSafe(nand_dir, device_save_data_path); 1633 path = Common::FS::ConcatPathSafe(nand_dir, device_save_data_path);
@@ -1663,7 +1666,7 @@ void GMainWindow::OnTransferableShaderCacheOpenFile(u64 program_id) {
1663 const auto shader_cache_folder_path{shader_cache_dir / fmt::format("{:016x}", program_id)}; 1666 const auto shader_cache_folder_path{shader_cache_dir / fmt::format("{:016x}", program_id)};
1664 if (!Common::FS::CreateDirs(shader_cache_folder_path)) { 1667 if (!Common::FS::CreateDirs(shader_cache_folder_path)) {
1665 QMessageBox::warning(this, tr("Error Opening Transferable Shader Cache"), 1668 QMessageBox::warning(this, tr("Error Opening Transferable Shader Cache"),
1666 tr("Filed to create the shader cache directory for this title.")); 1669 tr("Failed to create the shader cache directory for this title."));
1667 return; 1670 return;
1668 } 1671 }
1669 const auto shader_path_string{Common::FS::PathToUTF8String(shader_cache_folder_path)}; 1672 const auto shader_path_string{Common::FS::PathToUTF8String(shader_cache_folder_path)};
@@ -1751,7 +1754,7 @@ void GMainWindow::OnGameListRemoveInstalledEntry(u64 program_id, InstalledEntryT
1751} 1754}
1752 1755
1753void GMainWindow::RemoveBaseContent(u64 program_id, const QString& entry_type) { 1756void GMainWindow::RemoveBaseContent(u64 program_id, const QString& entry_type) {
1754 const auto& fs_controller = system.GetFileSystemController(); 1757 const auto& fs_controller = system->GetFileSystemController();
1755 const auto res = fs_controller.GetUserNANDContents()->RemoveExistingEntry(program_id) || 1758 const auto res = fs_controller.GetUserNANDContents()->RemoveExistingEntry(program_id) ||
1756 fs_controller.GetSDMCContents()->RemoveExistingEntry(program_id); 1759 fs_controller.GetSDMCContents()->RemoveExistingEntry(program_id);
1757 1760
@@ -1767,7 +1770,7 @@ void GMainWindow::RemoveBaseContent(u64 program_id, const QString& entry_type) {
1767 1770
1768void GMainWindow::RemoveUpdateContent(u64 program_id, const QString& entry_type) { 1771void GMainWindow::RemoveUpdateContent(u64 program_id, const QString& entry_type) {
1769 const auto update_id = program_id | 0x800; 1772 const auto update_id = program_id | 0x800;
1770 const auto& fs_controller = system.GetFileSystemController(); 1773 const auto& fs_controller = system->GetFileSystemController();
1771 const auto res = fs_controller.GetUserNANDContents()->RemoveExistingEntry(update_id) || 1774 const auto res = fs_controller.GetUserNANDContents()->RemoveExistingEntry(update_id) ||
1772 fs_controller.GetSDMCContents()->RemoveExistingEntry(update_id); 1775 fs_controller.GetSDMCContents()->RemoveExistingEntry(update_id);
1773 1776
@@ -1782,8 +1785,8 @@ void GMainWindow::RemoveUpdateContent(u64 program_id, const QString& entry_type)
1782 1785
1783void GMainWindow::RemoveAddOnContent(u64 program_id, const QString& entry_type) { 1786void GMainWindow::RemoveAddOnContent(u64 program_id, const QString& entry_type) {
1784 u32 count{}; 1787 u32 count{};
1785 const auto& fs_controller = system.GetFileSystemController(); 1788 const auto& fs_controller = system->GetFileSystemController();
1786 const auto dlc_entries = system.GetContentProvider().ListEntriesFilter( 1789 const auto dlc_entries = system->GetContentProvider().ListEntriesFilter(
1787 FileSys::TitleType::AOC, FileSys::ContentRecordType::Data); 1790 FileSys::TitleType::AOC, FileSys::ContentRecordType::Data);
1788 1791
1789 for (const auto& entry : dlc_entries) { 1792 for (const auto& entry : dlc_entries) {
@@ -1921,7 +1924,7 @@ void GMainWindow::OnGameListDumpRomFS(u64 program_id, const std::string& game_pa
1921 "cancelled the operation.")); 1924 "cancelled the operation."));
1922 }; 1925 };
1923 1926
1924 const auto loader = Loader::GetLoader(system, vfs->OpenFile(game_path, FileSys::Mode::Read)); 1927 const auto loader = Loader::GetLoader(*system, vfs->OpenFile(game_path, FileSys::Mode::Read));
1925 if (loader == nullptr) { 1928 if (loader == nullptr) {
1926 failed(); 1929 failed();
1927 return; 1930 return;
@@ -1933,7 +1936,7 @@ void GMainWindow::OnGameListDumpRomFS(u64 program_id, const std::string& game_pa
1933 return; 1936 return;
1934 } 1937 }
1935 1938
1936 const auto& installed = system.GetContentProvider(); 1939 const auto& installed = system->GetContentProvider();
1937 const auto romfs_title_id = SelectRomFSDumpTarget(installed, program_id); 1940 const auto romfs_title_id = SelectRomFSDumpTarget(installed, program_id);
1938 1941
1939 if (!romfs_title_id) { 1942 if (!romfs_title_id) {
@@ -1953,7 +1956,7 @@ void GMainWindow::OnGameListDumpRomFS(u64 program_id, const std::string& game_pa
1953 1956
1954 if (*romfs_title_id == program_id) { 1957 if (*romfs_title_id == program_id) {
1955 const u64 ivfc_offset = loader->ReadRomFSIVFCOffset(); 1958 const u64 ivfc_offset = loader->ReadRomFSIVFCOffset();
1956 const FileSys::PatchManager pm{program_id, system.GetFileSystemController(), installed}; 1959 const FileSys::PatchManager pm{program_id, system->GetFileSystemController(), installed};
1957 romfs = 1960 romfs =
1958 pm.PatchRomFS(file, ivfc_offset, FileSys::ContentRecordType::Program, nullptr, false); 1961 pm.PatchRomFS(file, ivfc_offset, FileSys::ContentRecordType::Program, nullptr, false);
1959 } else { 1962 } else {
@@ -2079,7 +2082,7 @@ void GMainWindow::OnGameListAddDirectory() {
2079} 2082}
2080 2083
2081void GMainWindow::OnGameListShowList(bool show) { 2084void GMainWindow::OnGameListShowList(bool show) {
2082 if (emulation_running && ui.action_Single_Window_Mode->isChecked()) 2085 if (emulation_running && ui->action_Single_Window_Mode->isChecked())
2083 return; 2086 return;
2084 game_list->setVisible(show); 2087 game_list->setVisible(show);
2085 game_list_placeholder->setVisible(!show); 2088 game_list_placeholder->setVisible(!show);
@@ -2088,7 +2091,7 @@ void GMainWindow::OnGameListShowList(bool show) {
2088void GMainWindow::OnGameListOpenPerGameProperties(const std::string& file) { 2091void GMainWindow::OnGameListOpenPerGameProperties(const std::string& file) {
2089 u64 title_id{}; 2092 u64 title_id{};
2090 const auto v_file = Core::GetGameFileFromPath(vfs, file); 2093 const auto v_file = Core::GetGameFileFromPath(vfs, file);
2091 const auto loader = Loader::GetLoader(system, v_file); 2094 const auto loader = Loader::GetLoader(*system, v_file);
2092 2095
2093 if (loader == nullptr || loader->ReadProgramId(title_id) != Loader::ResultStatus::Success) { 2096 if (loader == nullptr || loader->ReadProgramId(title_id) != Loader::ResultStatus::Success) {
2094 QMessageBox::information(this, tr("Properties"), 2097 QMessageBox::information(this, tr("Properties"),
@@ -2181,7 +2184,7 @@ void GMainWindow::OnMenuInstallToNAND() {
2181 QStringList failed_files{}; // Files that failed to install due to errors 2184 QStringList failed_files{}; // Files that failed to install due to errors
2182 bool detected_base_install{}; // Whether a base game was attempted to be installed 2185 bool detected_base_install{}; // Whether a base game was attempted to be installed
2183 2186
2184 ui.action_Install_File_NAND->setEnabled(false); 2187 ui->action_Install_File_NAND->setEnabled(false);
2185 2188
2186 install_progress = new QProgressDialog(QString{}, tr("Cancel"), 0, total_size, this); 2189 install_progress = new QProgressDialog(QString{}, tr("Cancel"), 0, total_size, this);
2187 install_progress->setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint & 2190 install_progress->setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint &
@@ -2257,7 +2260,7 @@ void GMainWindow::OnMenuInstallToNAND() {
2257 Common::FS::RemoveDirRecursively(Common::FS::GetYuzuPath(Common::FS::YuzuPath::CacheDir) / 2260 Common::FS::RemoveDirRecursively(Common::FS::GetYuzuPath(Common::FS::YuzuPath::CacheDir) /
2258 "game_list"); 2261 "game_list");
2259 game_list->PopulateAsync(UISettings::values.game_dirs); 2262 game_list->PopulateAsync(UISettings::values.game_dirs);
2260 ui.action_Install_File_NAND->setEnabled(true); 2263 ui->action_Install_File_NAND->setEnabled(true);
2261} 2264}
2262 2265
2263InstallResult GMainWindow::InstallNSPXCI(const QString& filename) { 2266InstallResult GMainWindow::InstallNSPXCI(const QString& filename) {
@@ -2302,7 +2305,7 @@ InstallResult GMainWindow::InstallNSPXCI(const QString& filename) {
2302 if (nsp->GetStatus() != Loader::ResultStatus::Success) { 2305 if (nsp->GetStatus() != Loader::ResultStatus::Success) {
2303 return InstallResult::Failure; 2306 return InstallResult::Failure;
2304 } 2307 }
2305 const auto res = system.GetFileSystemController().GetUserNANDContents()->InstallEntry( 2308 const auto res = system->GetFileSystemController().GetUserNANDContents()->InstallEntry(
2306 *nsp, true, qt_raw_copy); 2309 *nsp, true, qt_raw_copy);
2307 switch (res) { 2310 switch (res) {
2308 case FileSys::InstallResult::Success: 2311 case FileSys::InstallResult::Success:
@@ -2381,15 +2384,13 @@ InstallResult GMainWindow::InstallNCA(const QString& filename) {
2381 static_cast<size_t>(FileSys::TitleType::FirmwarePackageB); 2384 static_cast<size_t>(FileSys::TitleType::FirmwarePackageB);
2382 } 2385 }
2383 2386
2384 FileSys::InstallResult res; 2387 const bool is_application = index >= static_cast<s32>(FileSys::TitleType::Application);
2385 if (index >= static_cast<s32>(FileSys::TitleType::Application)) { 2388 const auto& fs_controller = system->GetFileSystemController();
2386 res = system.GetFileSystemController().GetUserNANDContents()->InstallEntry( 2389 auto* registered_cache = is_application ? fs_controller.GetUserNANDContents()
2387 *nca, static_cast<FileSys::TitleType>(index), true, qt_raw_copy); 2390 : fs_controller.GetSystemNANDContents();
2388 } else {
2389 res = system.GetFileSystemController().GetSystemNANDContents()->InstallEntry(
2390 *nca, static_cast<FileSys::TitleType>(index), true, qt_raw_copy);
2391 }
2392 2391
2392 const auto res = registered_cache->InstallEntry(*nca, static_cast<FileSys::TitleType>(index),
2393 true, qt_raw_copy);
2393 if (res == FileSys::InstallResult::Success) { 2394 if (res == FileSys::InstallResult::Success) {
2394 return InstallResult::Success; 2395 return InstallResult::Success;
2395 } else if (res == FileSys::InstallResult::OverwriteExisting) { 2396 } else if (res == FileSys::InstallResult::OverwriteExisting) {
@@ -2423,39 +2424,39 @@ void GMainWindow::OnStartGame() {
2423 2424
2424 connect(emu_thread.get(), &EmuThread::ErrorThrown, this, &GMainWindow::OnCoreError); 2425 connect(emu_thread.get(), &EmuThread::ErrorThrown, this, &GMainWindow::OnCoreError);
2425 2426
2426 ui.action_Start->setEnabled(false); 2427 ui->action_Start->setEnabled(false);
2427 ui.action_Start->setText(tr("&Continue")); 2428 ui->action_Start->setText(tr("&Continue"));
2428 2429
2429 ui.action_Pause->setEnabled(true); 2430 ui->action_Pause->setEnabled(true);
2430 ui.action_Stop->setEnabled(true); 2431 ui->action_Stop->setEnabled(true);
2431 ui.action_Restart->setEnabled(true); 2432 ui->action_Restart->setEnabled(true);
2432 ui.action_Configure_Current_Game->setEnabled(true); 2433 ui->action_Configure_Current_Game->setEnabled(true);
2433 ui.action_Report_Compatibility->setEnabled(true); 2434 ui->action_Report_Compatibility->setEnabled(true);
2434 2435
2435 discord_rpc->Update(); 2436 discord_rpc->Update();
2436 ui.action_Load_Amiibo->setEnabled(true); 2437 ui->action_Load_Amiibo->setEnabled(true);
2437 ui.action_Capture_Screenshot->setEnabled(true); 2438 ui->action_Capture_Screenshot->setEnabled(true);
2438} 2439}
2439 2440
2440void GMainWindow::OnPauseGame() { 2441void GMainWindow::OnPauseGame() {
2441 emu_thread->SetRunning(false); 2442 emu_thread->SetRunning(false);
2442 2443
2443 ui.action_Start->setEnabled(true); 2444 ui->action_Start->setEnabled(true);
2444 ui.action_Pause->setEnabled(false); 2445 ui->action_Pause->setEnabled(false);
2445 ui.action_Stop->setEnabled(true); 2446 ui->action_Stop->setEnabled(true);
2446 ui.action_Capture_Screenshot->setEnabled(false); 2447 ui->action_Capture_Screenshot->setEnabled(false);
2447 2448
2448 AllowOSSleep(); 2449 AllowOSSleep();
2449} 2450}
2450 2451
2451void GMainWindow::OnStopGame() { 2452void GMainWindow::OnStopGame() {
2452 if (system.GetExitLock() && !ConfirmForceLockedExit()) { 2453 if (system->GetExitLock() && !ConfirmForceLockedExit()) {
2453 return; 2454 return;
2454 } 2455 }
2455 2456
2456 ShutdownGame(); 2457 ShutdownGame();
2457 2458
2458 Settings::RestoreGlobalState(system.IsPoweredOn()); 2459 Settings::RestoreGlobalState(system->IsPoweredOn());
2459 UpdateStatusButtons(); 2460 UpdateStatusButtons();
2460} 2461}
2461 2462
@@ -2473,7 +2474,7 @@ void GMainWindow::OnExit() {
2473} 2474}
2474 2475
2475void GMainWindow::ErrorDisplayDisplayError(QString error_code, QString error_text) { 2476void GMainWindow::ErrorDisplayDisplayError(QString error_code, QString error_text) {
2476 OverlayDialog dialog(render_window, system, error_code, error_text, QString{}, tr("OK"), 2477 OverlayDialog dialog(render_window, *system, error_code, error_text, QString{}, tr("OK"),
2477 Qt::AlignLeft | Qt::AlignVCenter); 2478 Qt::AlignLeft | Qt::AlignVCenter);
2478 dialog.exec(); 2479 dialog.exec();
2479 2480
@@ -2483,7 +2484,7 @@ void GMainWindow::ErrorDisplayDisplayError(QString error_code, QString error_tex
2483void GMainWindow::OnMenuReportCompatibility() { 2484void GMainWindow::OnMenuReportCompatibility() {
2484 if (!Settings::values.yuzu_token.GetValue().empty() && 2485 if (!Settings::values.yuzu_token.GetValue().empty() &&
2485 !Settings::values.yuzu_username.GetValue().empty()) { 2486 !Settings::values.yuzu_username.GetValue().empty()) {
2486 CompatDB compatdb{system.TelemetrySession(), this}; 2487 CompatDB compatdb{system->TelemetrySession(), this};
2487 compatdb.exec(); 2488 compatdb.exec();
2488 } else { 2489 } else {
2489 QMessageBox::critical( 2490 QMessageBox::critical(
@@ -2519,7 +2520,7 @@ void GMainWindow::ToggleFullscreen() {
2519 if (!emulation_running) { 2520 if (!emulation_running) {
2520 return; 2521 return;
2521 } 2522 }
2522 if (ui.action_Fullscreen->isChecked()) { 2523 if (ui->action_Fullscreen->isChecked()) {
2523 ShowFullscreen(); 2524 ShowFullscreen();
2524 } else { 2525 } else {
2525 HideFullscreen(); 2526 HideFullscreen();
@@ -2527,10 +2528,10 @@ void GMainWindow::ToggleFullscreen() {
2527} 2528}
2528 2529
2529void GMainWindow::ShowFullscreen() { 2530void GMainWindow::ShowFullscreen() {
2530 if (ui.action_Single_Window_Mode->isChecked()) { 2531 if (ui->action_Single_Window_Mode->isChecked()) {
2531 UISettings::values.geometry = saveGeometry(); 2532 UISettings::values.geometry = saveGeometry();
2532 2533
2533 ui.menubar->hide(); 2534 ui->menubar->hide();
2534 statusBar()->hide(); 2535 statusBar()->hide();
2535 2536
2536 if (Settings::values.fullscreen_mode.GetValue() == Settings::FullscreenMode::Exclusive) { 2537 if (Settings::values.fullscreen_mode.GetValue() == Settings::FullscreenMode::Exclusive) {
@@ -2564,7 +2565,7 @@ void GMainWindow::ShowFullscreen() {
2564} 2565}
2565 2566
2566void GMainWindow::HideFullscreen() { 2567void GMainWindow::HideFullscreen() {
2567 if (ui.action_Single_Window_Mode->isChecked()) { 2568 if (ui->action_Single_Window_Mode->isChecked()) {
2568 if (Settings::values.fullscreen_mode.GetValue() == Settings::FullscreenMode::Exclusive) { 2569 if (Settings::values.fullscreen_mode.GetValue() == Settings::FullscreenMode::Exclusive) {
2569 showNormal(); 2570 showNormal();
2570 restoreGeometry(UISettings::values.geometry); 2571 restoreGeometry(UISettings::values.geometry);
@@ -2576,8 +2577,8 @@ void GMainWindow::HideFullscreen() {
2576 show(); 2577 show();
2577 } 2578 }
2578 2579
2579 statusBar()->setVisible(ui.action_Show_Status_Bar->isChecked()); 2580 statusBar()->setVisible(ui->action_Show_Status_Bar->isChecked());
2580 ui.menubar->show(); 2581 ui->menubar->show();
2581 } else { 2582 } else {
2582 if (Settings::values.fullscreen_mode.GetValue() == Settings::FullscreenMode::Exclusive) { 2583 if (Settings::values.fullscreen_mode.GetValue() == Settings::FullscreenMode::Exclusive) {
2583 render_window->showNormal(); 2584 render_window->showNormal();
@@ -2593,10 +2594,10 @@ void GMainWindow::HideFullscreen() {
2593} 2594}
2594 2595
2595void GMainWindow::ToggleWindowMode() { 2596void GMainWindow::ToggleWindowMode() {
2596 if (ui.action_Single_Window_Mode->isChecked()) { 2597 if (ui->action_Single_Window_Mode->isChecked()) {
2597 // Render in the main window... 2598 // Render in the main window...
2598 render_window->BackupGeometry(); 2599 render_window->BackupGeometry();
2599 ui.horizontalLayout->addWidget(render_window); 2600 ui->horizontalLayout->addWidget(render_window);
2600 render_window->setFocusPolicy(Qt::StrongFocus); 2601 render_window->setFocusPolicy(Qt::StrongFocus);
2601 if (emulation_running) { 2602 if (emulation_running) {
2602 render_window->setVisible(true); 2603 render_window->setVisible(true);
@@ -2606,7 +2607,7 @@ void GMainWindow::ToggleWindowMode() {
2606 2607
2607 } else { 2608 } else {
2608 // Render in a separate window... 2609 // Render in a separate window...
2609 ui.horizontalLayout->removeWidget(render_window); 2610 ui->horizontalLayout->removeWidget(render_window);
2610 render_window->setParent(nullptr); 2611 render_window->setParent(nullptr);
2611 render_window->setFocusPolicy(Qt::NoFocus); 2612 render_window->setFocusPolicy(Qt::NoFocus);
2612 if (emulation_running) { 2613 if (emulation_running) {
@@ -2621,10 +2622,10 @@ void GMainWindow::ResetWindowSize(u32 width, u32 height) {
2621 const auto aspect_ratio = Layout::EmulationAspectRatio( 2622 const auto aspect_ratio = Layout::EmulationAspectRatio(
2622 static_cast<Layout::AspectRatio>(Settings::values.aspect_ratio.GetValue()), 2623 static_cast<Layout::AspectRatio>(Settings::values.aspect_ratio.GetValue()),
2623 static_cast<float>(height) / width); 2624 static_cast<float>(height) / width);
2624 if (!ui.action_Single_Window_Mode->isChecked()) { 2625 if (!ui->action_Single_Window_Mode->isChecked()) {
2625 render_window->resize(height / aspect_ratio, height); 2626 render_window->resize(height / aspect_ratio, height);
2626 } else { 2627 } else {
2627 const bool show_status_bar = ui.action_Show_Status_Bar->isChecked(); 2628 const bool show_status_bar = ui->action_Show_Status_Bar->isChecked();
2628 const auto status_bar_height = show_status_bar ? statusBar()->height() : 0; 2629 const auto status_bar_height = show_status_bar ? statusBar()->height() : 0;
2629 resize(height / aspect_ratio, height + menuBar()->height() + status_bar_height); 2630 resize(height / aspect_ratio, height + menuBar()->height() + status_bar_height);
2630 } 2631 }
@@ -2647,7 +2648,7 @@ void GMainWindow::OnConfigure() {
2647 const bool old_discord_presence = UISettings::values.enable_discord_presence.GetValue(); 2648 const bool old_discord_presence = UISettings::values.enable_discord_presence.GetValue();
2648 2649
2649 Settings::SetConfiguringGlobal(true); 2650 Settings::SetConfiguringGlobal(true);
2650 ConfigureDialog configure_dialog(this, hotkey_registry, input_subsystem.get(), system); 2651 ConfigureDialog configure_dialog(this, hotkey_registry, input_subsystem.get(), *system);
2651 connect(&configure_dialog, &ConfigureDialog::LanguageChanged, this, 2652 connect(&configure_dialog, &ConfigureDialog::LanguageChanged, this,
2652 &GMainWindow::OnLanguageChanged); 2653 &GMainWindow::OnLanguageChanged);
2653 2654
@@ -2683,7 +2684,7 @@ void GMainWindow::OnConfigure() {
2683 2684
2684 Settings::values.disabled_addons.clear(); 2685 Settings::values.disabled_addons.clear();
2685 2686
2686 config = std::make_unique<Config>(system); 2687 config = std::make_unique<Config>(*system);
2687 UISettings::values.reset_to_defaults = false; 2688 UISettings::values.reset_to_defaults = false;
2688 2689
2689 UISettings::values.game_dirs = std::move(old_game_dirs); 2690 UISettings::values.game_dirs = std::move(old_game_dirs);
@@ -2732,12 +2733,11 @@ void GMainWindow::OnConfigure() {
2732} 2733}
2733 2734
2734void GMainWindow::OnConfigureTas() { 2735void GMainWindow::OnConfigureTas() {
2735 const auto& system = Core::System::GetInstance();
2736 ConfigureTasDialog dialog(this); 2736 ConfigureTasDialog dialog(this);
2737 const auto result = dialog.exec(); 2737 const auto result = dialog.exec();
2738 2738
2739 if (result != QDialog::Accepted && !UISettings::values.configuration_applied) { 2739 if (result != QDialog::Accepted && !UISettings::values.configuration_applied) {
2740 Settings::RestoreGlobalState(system.IsPoweredOn()); 2740 Settings::RestoreGlobalState(system->IsPoweredOn());
2741 return; 2741 return;
2742 } else if (result == QDialog::Accepted) { 2742 } else if (result == QDialog::Accepted) {
2743 dialog.ApplyConfiguration(); 2743 dialog.ApplyConfiguration();
@@ -2745,7 +2745,7 @@ void GMainWindow::OnConfigureTas() {
2745} 2745}
2746 2746
2747void GMainWindow::OnConfigurePerGame() { 2747void GMainWindow::OnConfigurePerGame() {
2748 const u64 title_id = system.CurrentProcess()->GetTitleID(); 2748 const u64 title_id = system->CurrentProcess()->GetTitleID();
2749 OpenPerGameConfiguration(title_id, game_path.toStdString()); 2749 OpenPerGameConfiguration(title_id, game_path.toStdString());
2750} 2750}
2751 2751
@@ -2753,12 +2753,12 @@ void GMainWindow::OpenPerGameConfiguration(u64 title_id, const std::string& file
2753 const auto v_file = Core::GetGameFileFromPath(vfs, file_name); 2753 const auto v_file = Core::GetGameFileFromPath(vfs, file_name);
2754 2754
2755 Settings::SetConfiguringGlobal(false); 2755 Settings::SetConfiguringGlobal(false);
2756 ConfigurePerGame dialog(this, title_id, file_name, system); 2756 ConfigurePerGame dialog(this, title_id, file_name, *system);
2757 dialog.LoadFromFile(v_file); 2757 dialog.LoadFromFile(v_file);
2758 const auto result = dialog.exec(); 2758 const auto result = dialog.exec();
2759 2759
2760 if (result != QDialog::Accepted && !UISettings::values.configuration_applied) { 2760 if (result != QDialog::Accepted && !UISettings::values.configuration_applied) {
2761 Settings::RestoreGlobalState(system.IsPoweredOn()); 2761 Settings::RestoreGlobalState(system->IsPoweredOn());
2762 return; 2762 return;
2763 } else if (result == QDialog::Accepted) { 2763 } else if (result == QDialog::Accepted) {
2764 dialog.ApplyConfiguration(); 2764 dialog.ApplyConfiguration();
@@ -2770,7 +2770,7 @@ void GMainWindow::OpenPerGameConfiguration(u64 title_id, const std::string& file
2770 } 2770 }
2771 2771
2772 // Do not cause the global config to write local settings into the config file 2772 // Do not cause the global config to write local settings into the config file
2773 const bool is_powered_on = system.IsPoweredOn(); 2773 const bool is_powered_on = system->IsPoweredOn();
2774 Settings::RestoreGlobalState(is_powered_on); 2774 Settings::RestoreGlobalState(is_powered_on);
2775 2775
2776 UISettings::values.configuration_applied = false; 2776 UISettings::values.configuration_applied = false;
@@ -2793,7 +2793,7 @@ void GMainWindow::OnLoadAmiibo() {
2793} 2793}
2794 2794
2795void GMainWindow::LoadAmiibo(const QString& filename) { 2795void GMainWindow::LoadAmiibo(const QString& filename) {
2796 Service::SM::ServiceManager& sm = system.ServiceManager(); 2796 Service::SM::ServiceManager& sm = system->ServiceManager();
2797 auto nfc = sm.GetService<Service::NFP::Module::Interface>("nfp:user"); 2797 auto nfc = sm.GetService<Service::NFP::Module::Interface>("nfp:user");
2798 if (nfc == nullptr) { 2798 if (nfc == nullptr) {
2799 return; 2799 return;
@@ -2835,8 +2835,8 @@ void GMainWindow::OnAbout() {
2835} 2835}
2836 2836
2837void GMainWindow::OnToggleFilterBar() { 2837void GMainWindow::OnToggleFilterBar() {
2838 game_list->SetFilterVisible(ui.action_Show_Filter_Bar->isChecked()); 2838 game_list->SetFilterVisible(ui->action_Show_Filter_Bar->isChecked());
2839 if (ui.action_Show_Filter_Bar->isChecked()) { 2839 if (ui->action_Show_Filter_Bar->isChecked()) {
2840 game_list->SetFilterFocus(); 2840 game_list->SetFilterFocus();
2841 } else { 2841 } else {
2842 game_list->ClearFilter(); 2842 game_list->ClearFilter();
@@ -2844,7 +2844,7 @@ void GMainWindow::OnToggleFilterBar() {
2844} 2844}
2845 2845
2846void GMainWindow::OnCaptureScreenshot() { 2846void GMainWindow::OnCaptureScreenshot() {
2847 const u64 title_id = system.CurrentProcess()->GetTitleID(); 2847 const u64 title_id = system->CurrentProcess()->GetTitleID();
2848 const auto screenshot_path = 2848 const auto screenshot_path =
2849 QString::fromStdString(Common::FS::GetYuzuPathString(Common::FS::YuzuPath::ScreenshotsDir)); 2849 QString::fromStdString(Common::FS::GetYuzuPathString(Common::FS::YuzuPath::ScreenshotsDir));
2850 const auto date = 2850 const auto date =
@@ -2950,8 +2950,8 @@ void GMainWindow::UpdateStatusBar() {
2950 tas_label->clear(); 2950 tas_label->clear();
2951 } 2951 }
2952 2952
2953 auto results = system.GetAndResetPerfStats(); 2953 auto results = system->GetAndResetPerfStats();
2954 auto& shader_notify = system.GPU().ShaderNotify(); 2954 auto& shader_notify = system->GPU().ShaderNotify();
2955 const int shaders_building = shader_notify.ShadersBuilding(); 2955 const int shaders_building = shader_notify.ShadersBuilding();
2956 2956
2957 if (shaders_building > 0) { 2957 if (shaders_building > 0) {
@@ -3013,7 +3013,7 @@ void GMainWindow::UpdateStatusButtons() {
3013} 3013}
3014 3014
3015void GMainWindow::UpdateUISettings() { 3015void GMainWindow::UpdateUISettings() {
3016 if (!ui.action_Fullscreen->isChecked()) { 3016 if (!ui->action_Fullscreen->isChecked()) {
3017 UISettings::values.geometry = saveGeometry(); 3017 UISettings::values.geometry = saveGeometry();
3018 UISettings::values.renderwindow_geometry = render_window->saveGeometry(); 3018 UISettings::values.renderwindow_geometry = render_window->saveGeometry();
3019 } 3019 }
@@ -3022,11 +3022,11 @@ void GMainWindow::UpdateUISettings() {
3022 UISettings::values.microprofile_geometry = microProfileDialog->saveGeometry(); 3022 UISettings::values.microprofile_geometry = microProfileDialog->saveGeometry();
3023 UISettings::values.microprofile_visible = microProfileDialog->isVisible(); 3023 UISettings::values.microprofile_visible = microProfileDialog->isVisible();
3024#endif 3024#endif
3025 UISettings::values.single_window_mode = ui.action_Single_Window_Mode->isChecked(); 3025 UISettings::values.single_window_mode = ui->action_Single_Window_Mode->isChecked();
3026 UISettings::values.fullscreen = ui.action_Fullscreen->isChecked(); 3026 UISettings::values.fullscreen = ui->action_Fullscreen->isChecked();
3027 UISettings::values.display_titlebar = ui.action_Display_Dock_Widget_Headers->isChecked(); 3027 UISettings::values.display_titlebar = ui->action_Display_Dock_Widget_Headers->isChecked();
3028 UISettings::values.show_filter_bar = ui.action_Show_Filter_Bar->isChecked(); 3028 UISettings::values.show_filter_bar = ui->action_Show_Filter_Bar->isChecked();
3029 UISettings::values.show_status_bar = ui.action_Show_Status_Bar->isChecked(); 3029 UISettings::values.show_status_bar = ui->action_Show_Status_Bar->isChecked();
3030 UISettings::values.first_start = false; 3030 UISettings::values.first_start = false;
3031} 3031}
3032 3032
@@ -3052,7 +3052,7 @@ void GMainWindow::OnMouseActivity() {
3052 } 3052 }
3053} 3053}
3054 3054
3055void GMainWindow::OnCoreError(Core::System::ResultStatus result, std::string details) { 3055void GMainWindow::OnCoreError(Core::SystemResultStatus result, std::string details) {
3056 QMessageBox::StandardButton answer; 3056 QMessageBox::StandardButton answer;
3057 QString status_message; 3057 QString status_message;
3058 const QString common_message = 3058 const QString common_message =
@@ -3067,7 +3067,7 @@ void GMainWindow::OnCoreError(Core::System::ResultStatus result, std::string det
3067 "back to the game list? Continuing emulation may result in crashes, corrupted save " 3067 "back to the game list? Continuing emulation may result in crashes, corrupted save "
3068 "data, or other bugs."); 3068 "data, or other bugs.");
3069 switch (result) { 3069 switch (result) {
3070 case Core::System::ResultStatus::ErrorSystemFiles: { 3070 case Core::SystemResultStatus::ErrorSystemFiles: {
3071 QString message; 3071 QString message;
3072 if (details.empty()) { 3072 if (details.empty()) {
3073 message = 3073 message =
@@ -3083,7 +3083,7 @@ void GMainWindow::OnCoreError(Core::System::ResultStatus result, std::string det
3083 break; 3083 break;
3084 } 3084 }
3085 3085
3086 case Core::System::ResultStatus::ErrorSharedFont: { 3086 case Core::SystemResultStatus::ErrorSharedFont: {
3087 const QString message = 3087 const QString message =
3088 tr("yuzu was unable to locate the Switch shared fonts. %1").arg(common_message); 3088 tr("yuzu was unable to locate the Switch shared fonts. %1").arg(common_message);
3089 answer = QMessageBox::question(this, tr("Shared Fonts Not Found"), message, 3089 answer = QMessageBox::question(this, tr("Shared Fonts Not Found"), message,
@@ -3112,7 +3112,7 @@ void GMainWindow::OnCoreError(Core::System::ResultStatus result, std::string det
3112 if (emu_thread) { 3112 if (emu_thread) {
3113 ShutdownGame(); 3113 ShutdownGame();
3114 3114
3115 Settings::RestoreGlobalState(system.IsPoweredOn()); 3115 Settings::RestoreGlobalState(system->IsPoweredOn());
3116 UpdateStatusButtons(); 3116 UpdateStatusButtons();
3117 } 3117 }
3118 } else { 3118 } else {
@@ -3154,8 +3154,8 @@ void GMainWindow::OnReinitializeKeys(ReinitializeKeyBehavior behavior) {
3154 const auto function = [this, &keys, &pdm] { 3154 const auto function = [this, &keys, &pdm] {
3155 keys.PopulateFromPartitionData(pdm); 3155 keys.PopulateFromPartitionData(pdm);
3156 3156
3157 system.GetFileSystemController().CreateFactories(*vfs); 3157 system->GetFileSystemController().CreateFactories(*vfs);
3158 keys.DeriveETicket(pdm, system.GetContentProvider()); 3158 keys.DeriveETicket(pdm, system->GetContentProvider());
3159 }; 3159 };
3160 3160
3161 QString errors; 3161 QString errors;
@@ -3197,7 +3197,7 @@ void GMainWindow::OnReinitializeKeys(ReinitializeKeyBehavior behavior) {
3197 prog.close(); 3197 prog.close();
3198 } 3198 }
3199 3199
3200 system.GetFileSystemController().CreateFactories(*vfs); 3200 system->GetFileSystemController().CreateFactories(*vfs);
3201 3201
3202 if (behavior == ReinitializeKeyBehavior::Warning) { 3202 if (behavior == ReinitializeKeyBehavior::Warning) {
3203 game_list->PopulateAsync(UISettings::values.game_dirs); 3203 game_list->PopulateAsync(UISettings::values.game_dirs);
@@ -3265,7 +3265,7 @@ void GMainWindow::closeEvent(QCloseEvent* event) {
3265 if (emu_thread != nullptr) { 3265 if (emu_thread != nullptr) {
3266 ShutdownGame(); 3266 ShutdownGame();
3267 3267
3268 Settings::RestoreGlobalState(system.IsPoweredOn()); 3268 Settings::RestoreGlobalState(system->IsPoweredOn());
3269 UpdateStatusButtons(); 3269 UpdateStatusButtons();
3270 } 3270 }
3271 3271
@@ -3340,7 +3340,7 @@ bool GMainWindow::ConfirmForceLockedExit() {
3340} 3340}
3341 3341
3342void GMainWindow::RequestGameExit() { 3342void GMainWindow::RequestGameExit() {
3343 auto& sm{system.ServiceManager()}; 3343 auto& sm{system->ServiceManager()};
3344 auto applet_oe = sm.GetService<Service::AM::AppletOE>("appletOE"); 3344 auto applet_oe = sm.GetService<Service::AM::AppletOE>("appletOE");
3345 auto applet_ae = sm.GetService<Service::AM::AppletAE>("appletAE"); 3345 auto applet_ae = sm.GetService<Service::AM::AppletAE>("appletAE");
3346 bool has_signalled = false; 3346 bool has_signalled = false;
@@ -3356,7 +3356,7 @@ void GMainWindow::RequestGameExit() {
3356} 3356}
3357 3357
3358void GMainWindow::filterBarSetChecked(bool state) { 3358void GMainWindow::filterBarSetChecked(bool state) {
3359 ui.action_Show_Filter_Bar->setChecked(state); 3359 ui->action_Show_Filter_Bar->setChecked(state);
3360 emit(OnToggleFilterBar()); 3360 emit(OnToggleFilterBar());
3361} 3361}
3362 3362
@@ -3424,17 +3424,17 @@ void GMainWindow::OnLanguageChanged(const QString& locale) {
3424 3424
3425 UISettings::values.language = locale; 3425 UISettings::values.language = locale;
3426 LoadTranslation(); 3426 LoadTranslation();
3427 ui.retranslateUi(this); 3427 ui->retranslateUi(this);
3428 UpdateWindowTitle(); 3428 UpdateWindowTitle();
3429 3429
3430 if (emulation_running) 3430 if (emulation_running)
3431 ui.action_Start->setText(tr("&Continue")); 3431 ui->action_Start->setText(tr("&Continue"));
3432} 3432}
3433 3433
3434void GMainWindow::SetDiscordEnabled([[maybe_unused]] bool state) { 3434void GMainWindow::SetDiscordEnabled([[maybe_unused]] bool state) {
3435#ifdef USE_DISCORD_PRESENCE 3435#ifdef USE_DISCORD_PRESENCE
3436 if (state) { 3436 if (state) {
3437 discord_rpc = std::make_unique<DiscordRPC::DiscordImpl>(system); 3437 discord_rpc = std::make_unique<DiscordRPC::DiscordImpl>(*system);
3438 } else { 3438 } else {
3439 discord_rpc = std::make_unique<DiscordRPC::NullImpl>(); 3439 discord_rpc = std::make_unique<DiscordRPC::NullImpl>();
3440 } 3440 }
@@ -3488,8 +3488,7 @@ int main(int argc, char* argv[]) {
3488 // generating shaders 3488 // generating shaders
3489 setlocale(LC_ALL, "C"); 3489 setlocale(LC_ALL, "C");
3490 3490
3491 Core::System::InitializeGlobalInstance(); 3491 GMainWindow main_window{};
3492 GMainWindow main_window{Core::System::GetInstance()};
3493 // After settings have been loaded by GMainWindow, apply the filter 3492 // After settings have been loaded by GMainWindow, apply the filter
3494 main_window.show(); 3493 main_window.show();
3495 3494
diff --git a/src/yuzu/main.h b/src/yuzu/main.h
index e31b3d06b..aed15a0a0 100644
--- a/src/yuzu/main.h
+++ b/src/yuzu/main.h
@@ -13,9 +13,7 @@
13#include <QTranslator> 13#include <QTranslator>
14 14
15#include "common/common_types.h" 15#include "common/common_types.h"
16#include "core/core.h"
17#include "core/hle/service/acc/profile_manager.h" 16#include "core/hle/service/acc/profile_manager.h"
18#include "ui_main.h"
19#include "yuzu/compatibility_list.h" 17#include "yuzu/compatibility_list.h"
20#include "yuzu/hotkeys.h" 18#include "yuzu/hotkeys.h"
21 19
@@ -45,6 +43,11 @@ enum class StartGameType {
45 Global, // Only uses global configuration 43 Global, // Only uses global configuration
46}; 44};
47 45
46namespace Core {
47enum class SystemResultStatus : u32;
48class System;
49} // namespace Core
50
48namespace Core::Frontend { 51namespace Core::Frontend {
49struct ControllerParameters; 52struct ControllerParameters;
50struct InlineAppearParameters; 53struct InlineAppearParameters;
@@ -73,6 +76,10 @@ enum class SwkbdReplyType : u32;
73enum class WebExitReason : u32; 76enum class WebExitReason : u32;
74} // namespace Service::AM::Applets 77} // namespace Service::AM::Applets
75 78
79namespace Ui {
80class MainWindow;
81}
82
76enum class EmulatedDirectoryTarget { 83enum class EmulatedDirectoryTarget {
77 NAND, 84 NAND,
78 SDMC, 85 SDMC,
@@ -107,7 +114,7 @@ class GMainWindow : public QMainWindow {
107public: 114public:
108 void filterBarSetChecked(bool state); 115 void filterBarSetChecked(bool state);
109 void UpdateUITheme(); 116 void UpdateUITheme();
110 GMainWindow(Core::System& system_); 117 explicit GMainWindow();
111 ~GMainWindow() override; 118 ~GMainWindow() override;
112 119
113 bool DropAction(QDropEvent* event); 120 bool DropAction(QDropEvent* event);
@@ -277,7 +284,7 @@ private slots:
277 void ResetWindowSize900(); 284 void ResetWindowSize900();
278 void ResetWindowSize1080(); 285 void ResetWindowSize1080();
279 void OnCaptureScreenshot(); 286 void OnCaptureScreenshot();
280 void OnCoreError(Core::System::ResultStatus, std::string); 287 void OnCoreError(Core::SystemResultStatus, std::string);
281 void OnReinitializeKeys(ReinitializeKeyBehavior behavior); 288 void OnReinitializeKeys(ReinitializeKeyBehavior behavior);
282 void OnLanguageChanged(const QString& locale); 289 void OnLanguageChanged(const QString& locale);
283 void OnMouseActivity(); 290 void OnMouseActivity();
@@ -306,13 +313,12 @@ private:
306 void OpenPerGameConfiguration(u64 title_id, const std::string& file_name); 313 void OpenPerGameConfiguration(u64 title_id, const std::string& file_name);
307 QString GetTasStateDescription() const; 314 QString GetTasStateDescription() const;
308 315
309 Ui::MainWindow ui; 316 std::unique_ptr<Ui::MainWindow> ui;
310 317
318 std::unique_ptr<Core::System> system;
311 std::unique_ptr<DiscordRPC::DiscordInterface> discord_rpc; 319 std::unique_ptr<DiscordRPC::DiscordInterface> discord_rpc;
312 std::shared_ptr<InputCommon::InputSubsystem> input_subsystem; 320 std::shared_ptr<InputCommon::InputSubsystem> input_subsystem;
313 321
314 Core::System& system;
315
316 GRenderWindow* render_window; 322 GRenderWindow* render_window;
317 GameList* game_list; 323 GameList* game_list;
318 LoadingScreen* loading_screen; 324 LoadingScreen* loading_screen;
diff --git a/src/yuzu/uisettings.h b/src/yuzu/uisettings.h
index 81f741f20..cac19452f 100644
--- a/src/yuzu/uisettings.h
+++ b/src/yuzu/uisettings.h
@@ -60,7 +60,7 @@ struct Values {
60 Settings::BasicSetting<bool> confirm_before_closing{true, "confirmClose"}; 60 Settings::BasicSetting<bool> confirm_before_closing{true, "confirmClose"};
61 Settings::BasicSetting<bool> first_start{true, "firstStart"}; 61 Settings::BasicSetting<bool> first_start{true, "firstStart"};
62 Settings::BasicSetting<bool> pause_when_in_background{false, "pauseWhenInBackground"}; 62 Settings::BasicSetting<bool> pause_when_in_background{false, "pauseWhenInBackground"};
63 Settings::BasicSetting<bool> hide_mouse{false, "hideInactiveMouse"}; 63 Settings::BasicSetting<bool> hide_mouse{true, "hideInactiveMouse"};
64 64
65 Settings::BasicSetting<bool> select_user_on_boot{false, "select_user_on_boot"}; 65 Settings::BasicSetting<bool> select_user_on_boot{false, "select_user_on_boot"};
66 66
diff --git a/src/yuzu_cmd/config.cpp b/src/yuzu_cmd/config.cpp
index 8ca20679a..0b8fde691 100644
--- a/src/yuzu_cmd/config.cpp
+++ b/src/yuzu_cmd/config.cpp
@@ -412,8 +412,7 @@ void Config::ReadValues() {
412 412
413 const auto custom_rtc_enabled = sdl2_config->GetBoolean("System", "custom_rtc_enabled", false); 413 const auto custom_rtc_enabled = sdl2_config->GetBoolean("System", "custom_rtc_enabled", false);
414 if (custom_rtc_enabled) { 414 if (custom_rtc_enabled) {
415 Settings::values.custom_rtc = 415 Settings::values.custom_rtc = sdl2_config->GetInteger("System", "custom_rtc", 0);
416 std::chrono::seconds(sdl2_config->GetInteger("System", "custom_rtc", 0));
417 } else { 416 } else {
418 Settings::values.custom_rtc = std::nullopt; 417 Settings::values.custom_rtc = std::nullopt;
419 } 418 }
diff --git a/src/yuzu_cmd/yuzu.cpp b/src/yuzu_cmd/yuzu.cpp
index ba2c993ba..67587cc54 100644
--- a/src/yuzu_cmd/yuzu.cpp
+++ b/src/yuzu_cmd/yuzu.cpp
@@ -146,9 +146,8 @@ int main(int argc, char** argv) {
146 return -1; 146 return -1;
147 } 147 }
148 148
149 Core::System::InitializeGlobalInstance(); 149 Core::System system{};
150 auto& system{Core::System::GetInstance()}; 150 InputCommon::InputSubsystem input_subsystem{};
151 InputCommon::InputSubsystem input_subsystem;
152 151
153 // Apply the command line arguments 152 // Apply the command line arguments
154 system.ApplySettings(); 153 system.ApplySettings();
@@ -167,27 +166,27 @@ int main(int argc, char** argv) {
167 system.SetFilesystem(std::make_shared<FileSys::RealVfsFilesystem>()); 166 system.SetFilesystem(std::make_shared<FileSys::RealVfsFilesystem>());
168 system.GetFileSystemController().CreateFactories(*system.GetFilesystem()); 167 system.GetFileSystemController().CreateFactories(*system.GetFilesystem());
169 168
170 const Core::System::ResultStatus load_result{system.Load(*emu_window, filepath)}; 169 const Core::SystemResultStatus load_result{system.Load(*emu_window, filepath)};
171 170
172 switch (load_result) { 171 switch (load_result) {
173 case Core::System::ResultStatus::ErrorGetLoader: 172 case Core::SystemResultStatus::ErrorGetLoader:
174 LOG_CRITICAL(Frontend, "Failed to obtain loader for {}!", filepath); 173 LOG_CRITICAL(Frontend, "Failed to obtain loader for {}!", filepath);
175 return -1; 174 return -1;
176 case Core::System::ResultStatus::ErrorLoader: 175 case Core::SystemResultStatus::ErrorLoader:
177 LOG_CRITICAL(Frontend, "Failed to load ROM!"); 176 LOG_CRITICAL(Frontend, "Failed to load ROM!");
178 return -1; 177 return -1;
179 case Core::System::ResultStatus::ErrorNotInitialized: 178 case Core::SystemResultStatus::ErrorNotInitialized:
180 LOG_CRITICAL(Frontend, "CPUCore not initialized"); 179 LOG_CRITICAL(Frontend, "CPUCore not initialized");
181 return -1; 180 return -1;
182 case Core::System::ResultStatus::ErrorVideoCore: 181 case Core::SystemResultStatus::ErrorVideoCore:
183 LOG_CRITICAL(Frontend, "Failed to initialize VideoCore!"); 182 LOG_CRITICAL(Frontend, "Failed to initialize VideoCore!");
184 return -1; 183 return -1;
185 case Core::System::ResultStatus::Success: 184 case Core::SystemResultStatus::Success:
186 break; // Expected case 185 break; // Expected case
187 default: 186 default:
188 if (static_cast<u32>(load_result) > 187 if (static_cast<u32>(load_result) >
189 static_cast<u32>(Core::System::ResultStatus::ErrorLoader)) { 188 static_cast<u32>(Core::SystemResultStatus::ErrorLoader)) {
190 const u16 loader_id = static_cast<u16>(Core::System::ResultStatus::ErrorLoader); 189 const u16 loader_id = static_cast<u16>(Core::SystemResultStatus::ErrorLoader);
191 const u16 error_id = static_cast<u16>(load_result) - loader_id; 190 const u16 error_id = static_cast<u16>(load_result) - loader_id;
192 LOG_CRITICAL(Frontend, 191 LOG_CRITICAL(Frontend,
193 "While attempting to load the ROM requested, an error occurred. Please " 192 "While attempting to load the ROM requested, an error occurred. Please "