diff options
Diffstat (limited to 'src/core/core.cpp')
| -rw-r--r-- | src/core/core.cpp | 92 |
1 files changed, 58 insertions, 34 deletions
diff --git a/src/core/core.cpp b/src/core/core.cpp index 1deeee154..7fb8bc019 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp | |||
| @@ -133,6 +133,50 @@ struct System::Impl { | |||
| 133 | : kernel{system}, fs_controller{system}, memory{system}, hid_core{}, room_network{}, | 133 | : kernel{system}, fs_controller{system}, memory{system}, hid_core{}, room_network{}, |
| 134 | cpu_manager{system}, reporter{system}, applet_manager{system}, time_manager{system} {} | 134 | cpu_manager{system}, reporter{system}, applet_manager{system}, time_manager{system} {} |
| 135 | 135 | ||
| 136 | void Initialize(System& system) { | ||
| 137 | device_memory = std::make_unique<Core::DeviceMemory>(); | ||
| 138 | |||
| 139 | is_multicore = Settings::values.use_multi_core.GetValue(); | ||
| 140 | |||
| 141 | core_timing.SetMulticore(is_multicore); | ||
| 142 | core_timing.Initialize([&system]() { system.RegisterHostThread(); }); | ||
| 143 | |||
| 144 | const auto posix_time = std::chrono::system_clock::now().time_since_epoch(); | ||
| 145 | const auto current_time = | ||
| 146 | std::chrono::duration_cast<std::chrono::seconds>(posix_time).count(); | ||
| 147 | Settings::values.custom_rtc_differential = | ||
| 148 | Settings::values.custom_rtc.value_or(current_time) - current_time; | ||
| 149 | |||
| 150 | // Create a default fs if one doesn't already exist. | ||
| 151 | if (virtual_filesystem == nullptr) { | ||
| 152 | virtual_filesystem = std::make_shared<FileSys::RealVfsFilesystem>(); | ||
| 153 | } | ||
| 154 | if (content_provider == nullptr) { | ||
| 155 | content_provider = std::make_unique<FileSys::ContentProviderUnion>(); | ||
| 156 | } | ||
| 157 | |||
| 158 | // Create default implementations of applets if one is not provided. | ||
| 159 | applet_manager.SetDefaultAppletsIfMissing(); | ||
| 160 | |||
| 161 | is_async_gpu = Settings::values.use_asynchronous_gpu_emulation.GetValue(); | ||
| 162 | |||
| 163 | kernel.SetMulticore(is_multicore); | ||
| 164 | cpu_manager.SetMulticore(is_multicore); | ||
| 165 | cpu_manager.SetAsyncGpu(is_async_gpu); | ||
| 166 | } | ||
| 167 | |||
| 168 | void ReinitializeIfNecessary(System& system) { | ||
| 169 | if (is_multicore == Settings::values.use_multi_core.GetValue()) { | ||
| 170 | return; | ||
| 171 | } | ||
| 172 | |||
| 173 | LOG_DEBUG(Kernel, "Re-initializing"); | ||
| 174 | |||
| 175 | is_multicore = Settings::values.use_multi_core.GetValue(); | ||
| 176 | |||
| 177 | Initialize(system); | ||
| 178 | } | ||
| 179 | |||
| 136 | SystemResultStatus Run() { | 180 | SystemResultStatus Run() { |
| 137 | std::unique_lock<std::mutex> lk(suspend_guard); | 181 | std::unique_lock<std::mutex> lk(suspend_guard); |
| 138 | status = SystemResultStatus::Success; | 182 | status = SystemResultStatus::Success; |
| @@ -178,37 +222,14 @@ struct System::Impl { | |||
| 178 | debugger = std::make_unique<Debugger>(system, port); | 222 | debugger = std::make_unique<Debugger>(system, port); |
| 179 | } | 223 | } |
| 180 | 224 | ||
| 181 | SystemResultStatus Init(System& system, Frontend::EmuWindow& emu_window) { | 225 | SystemResultStatus SetupForMainProcess(System& system, Frontend::EmuWindow& emu_window) { |
| 182 | LOG_DEBUG(Core, "initialized OK"); | 226 | LOG_DEBUG(Core, "initialized OK"); |
| 183 | 227 | ||
| 184 | device_memory = std::make_unique<Core::DeviceMemory>(); | 228 | // Setting changes may require a full system reinitialization (e.g., disabling multicore). |
| 185 | 229 | ReinitializeIfNecessary(system); | |
| 186 | is_multicore = Settings::values.use_multi_core.GetValue(); | ||
| 187 | is_async_gpu = Settings::values.use_asynchronous_gpu_emulation.GetValue(); | ||
| 188 | |||
| 189 | kernel.SetMulticore(is_multicore); | ||
| 190 | cpu_manager.SetMulticore(is_multicore); | ||
| 191 | cpu_manager.SetAsyncGpu(is_async_gpu); | ||
| 192 | core_timing.SetMulticore(is_multicore); | ||
| 193 | 230 | ||
| 194 | kernel.Initialize(); | 231 | kernel.Initialize(); |
| 195 | cpu_manager.Initialize(); | 232 | cpu_manager.Initialize(); |
| 196 | core_timing.Initialize([&system]() { system.RegisterHostThread(); }); | ||
| 197 | |||
| 198 | const auto posix_time = std::chrono::system_clock::now().time_since_epoch(); | ||
| 199 | const auto current_time = | ||
| 200 | std::chrono::duration_cast<std::chrono::seconds>(posix_time).count(); | ||
| 201 | Settings::values.custom_rtc_differential = | ||
| 202 | Settings::values.custom_rtc.value_or(current_time) - current_time; | ||
| 203 | |||
| 204 | // Create a default fs if one doesn't already exist. | ||
| 205 | if (virtual_filesystem == nullptr) | ||
| 206 | virtual_filesystem = std::make_shared<FileSys::RealVfsFilesystem>(); | ||
| 207 | if (content_provider == nullptr) | ||
| 208 | content_provider = std::make_unique<FileSys::ContentProviderUnion>(); | ||
| 209 | |||
| 210 | /// Create default implementations of applets if one is not provided. | ||
| 211 | applet_manager.SetDefaultAppletsIfMissing(); | ||
| 212 | 233 | ||
| 213 | /// Reset all glue registrations | 234 | /// Reset all glue registrations |
| 214 | arp_manager.ResetAll(); | 235 | arp_manager.ResetAll(); |
| @@ -253,11 +274,11 @@ struct System::Impl { | |||
| 253 | return SystemResultStatus::ErrorGetLoader; | 274 | return SystemResultStatus::ErrorGetLoader; |
| 254 | } | 275 | } |
| 255 | 276 | ||
| 256 | SystemResultStatus init_result{Init(system, emu_window)}; | 277 | SystemResultStatus init_result{SetupForMainProcess(system, emu_window)}; |
| 257 | if (init_result != SystemResultStatus::Success) { | 278 | if (init_result != SystemResultStatus::Success) { |
| 258 | LOG_CRITICAL(Core, "Failed to initialize system (Error {})!", | 279 | LOG_CRITICAL(Core, "Failed to initialize system (Error {})!", |
| 259 | static_cast<int>(init_result)); | 280 | static_cast<int>(init_result)); |
| 260 | Shutdown(); | 281 | ShutdownMainProcess(); |
| 261 | return init_result; | 282 | return init_result; |
| 262 | } | 283 | } |
| 263 | 284 | ||
| @@ -276,7 +297,7 @@ struct System::Impl { | |||
| 276 | const auto [load_result, load_parameters] = app_loader->Load(*main_process, system); | 297 | const auto [load_result, load_parameters] = app_loader->Load(*main_process, system); |
| 277 | if (load_result != Loader::ResultStatus::Success) { | 298 | if (load_result != Loader::ResultStatus::Success) { |
| 278 | LOG_CRITICAL(Core, "Failed to load ROM (Error {})!", load_result); | 299 | LOG_CRITICAL(Core, "Failed to load ROM (Error {})!", load_result); |
| 279 | Shutdown(); | 300 | ShutdownMainProcess(); |
| 280 | 301 | ||
| 281 | return static_cast<SystemResultStatus>( | 302 | return static_cast<SystemResultStatus>( |
| 282 | static_cast<u32>(SystemResultStatus::ErrorLoader) + static_cast<u32>(load_result)); | 303 | static_cast<u32>(SystemResultStatus::ErrorLoader) + static_cast<u32>(load_result)); |
| @@ -335,7 +356,7 @@ struct System::Impl { | |||
| 335 | return status; | 356 | return status; |
| 336 | } | 357 | } |
| 337 | 358 | ||
| 338 | void Shutdown() { | 359 | void ShutdownMainProcess() { |
| 339 | SetShuttingDown(true); | 360 | SetShuttingDown(true); |
| 340 | 361 | ||
| 341 | // Log last frame performance stats if game was loded | 362 | // Log last frame performance stats if game was loded |
| @@ -369,7 +390,7 @@ struct System::Impl { | |||
| 369 | cheat_engine.reset(); | 390 | cheat_engine.reset(); |
| 370 | telemetry_session.reset(); | 391 | telemetry_session.reset(); |
| 371 | time_manager.Shutdown(); | 392 | time_manager.Shutdown(); |
| 372 | core_timing.Shutdown(); | 393 | core_timing.ClearPendingEvents(); |
| 373 | app_loader.reset(); | 394 | app_loader.reset(); |
| 374 | audio_core.reset(); | 395 | audio_core.reset(); |
| 375 | gpu_core.reset(); | 396 | gpu_core.reset(); |
| @@ -377,7 +398,6 @@ struct System::Impl { | |||
| 377 | perf_stats.reset(); | 398 | perf_stats.reset(); |
| 378 | kernel.Shutdown(); | 399 | kernel.Shutdown(); |
| 379 | memory.Reset(); | 400 | memory.Reset(); |
| 380 | applet_manager.ClearAll(); | ||
| 381 | 401 | ||
| 382 | if (auto room_member = room_network.GetRoomMember().lock()) { | 402 | if (auto room_member = room_network.GetRoomMember().lock()) { |
| 383 | Network::GameInfo game_info{}; | 403 | Network::GameInfo game_info{}; |
| @@ -520,6 +540,10 @@ const CpuManager& System::GetCpuManager() const { | |||
| 520 | return impl->cpu_manager; | 540 | return impl->cpu_manager; |
| 521 | } | 541 | } |
| 522 | 542 | ||
| 543 | void System::Initialize() { | ||
| 544 | impl->Initialize(*this); | ||
| 545 | } | ||
| 546 | |||
| 523 | SystemResultStatus System::Run() { | 547 | SystemResultStatus System::Run() { |
| 524 | return impl->Run(); | 548 | return impl->Run(); |
| 525 | } | 549 | } |
| @@ -540,8 +564,8 @@ void System::InvalidateCpuInstructionCacheRange(VAddr addr, std::size_t size) { | |||
| 540 | impl->kernel.InvalidateCpuInstructionCacheRange(addr, size); | 564 | impl->kernel.InvalidateCpuInstructionCacheRange(addr, size); |
| 541 | } | 565 | } |
| 542 | 566 | ||
| 543 | void System::Shutdown() { | 567 | void System::ShutdownMainProcess() { |
| 544 | impl->Shutdown(); | 568 | impl->ShutdownMainProcess(); |
| 545 | } | 569 | } |
| 546 | 570 | ||
| 547 | bool System::IsShuttingDown() const { | 571 | bool System::IsShuttingDown() const { |