summaryrefslogtreecommitdiff
path: root/src/core/core.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/core.cpp')
-rw-r--r--src/core/core.cpp92
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
543void System::Initialize() {
544 impl->Initialize(*this);
545}
546
523SystemResultStatus System::Run() { 547SystemResultStatus 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
543void System::Shutdown() { 567void System::ShutdownMainProcess() {
544 impl->Shutdown(); 568 impl->ShutdownMainProcess();
545} 569}
546 570
547bool System::IsShuttingDown() const { 571bool System::IsShuttingDown() const {