summaryrefslogtreecommitdiffstats
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 {
: kernel{system}, fs_controller{system}, memory{system}, hid_core{}, room_network{},
cpu_manager{system}, reporter{system}, applet_manager{system}, time_manager{system} {}
+ void Initialize(System& system) {
+ device_memory = std::make_unique<Core::DeviceMemory>();
+
+ is_multicore = Settings::values.use_multi_core.GetValue();
+
+ core_timing.SetMulticore(is_multicore);
+ core_timing.Initialize([&system]() { system.RegisterHostThread(); });
+
+ const auto posix_time = std::chrono::system_clock::now().time_since_epoch();
+ const auto current_time =
+ std::chrono::duration_cast<std::chrono::seconds>(posix_time).count();
+ Settings::values.custom_rtc_differential =
+ Settings::values.custom_rtc.value_or(current_time) - current_time;
+
+ // Create a default fs if one doesn't already exist.
+ if (virtual_filesystem == nullptr) {
+ virtual_filesystem = std::make_shared<FileSys::RealVfsFilesystem>();
+ }
+ if (content_provider == nullptr) {
+ content_provider = std::make_unique<FileSys::ContentProviderUnion>();
+ }
+
+ // Create default implementations of applets if one is not provided.
+ applet_manager.SetDefaultAppletsIfMissing();
+
+ is_async_gpu = Settings::values.use_asynchronous_gpu_emulation.GetValue();
+
+ kernel.SetMulticore(is_multicore);
+ cpu_manager.SetMulticore(is_multicore);
+ cpu_manager.SetAsyncGpu(is_async_gpu);
+ }
+
+ void ReinitializeIfNecessary(System& system) {
+ if (is_multicore == Settings::values.use_multi_core.GetValue()) {
+ return;
+ }
+
+ LOG_DEBUG(Kernel, "Re-initializing");
+
+ is_multicore = Settings::values.use_multi_core.GetValue();
+
+ Initialize(system);
+ }
+
SystemResultStatus Run() {
std::unique_lock<std::mutex> lk(suspend_guard);
status = SystemResultStatus::Success;
@@ -178,37 +222,14 @@ struct System::Impl {
debugger = std::make_unique<Debugger>(system, port);
}
- SystemResultStatus Init(System& system, Frontend::EmuWindow& emu_window) {
+ SystemResultStatus SetupForMainProcess(System& system, Frontend::EmuWindow& emu_window) {
LOG_DEBUG(Core, "initialized OK");
- device_memory = std::make_unique<Core::DeviceMemory>();
-
- is_multicore = Settings::values.use_multi_core.GetValue();
- is_async_gpu = Settings::values.use_asynchronous_gpu_emulation.GetValue();
-
- kernel.SetMulticore(is_multicore);
- cpu_manager.SetMulticore(is_multicore);
- cpu_manager.SetAsyncGpu(is_async_gpu);
- core_timing.SetMulticore(is_multicore);
+ // Setting changes may require a full system reinitialization (e.g., disabling multicore).
+ ReinitializeIfNecessary(system);
kernel.Initialize();
cpu_manager.Initialize();
- core_timing.Initialize([&system]() { system.RegisterHostThread(); });
-
- const auto posix_time = std::chrono::system_clock::now().time_since_epoch();
- const auto current_time =
- std::chrono::duration_cast<std::chrono::seconds>(posix_time).count();
- Settings::values.custom_rtc_differential =
- Settings::values.custom_rtc.value_or(current_time) - current_time;
-
- // Create a default fs if one doesn't already exist.
- if (virtual_filesystem == nullptr)
- virtual_filesystem = std::make_shared<FileSys::RealVfsFilesystem>();
- if (content_provider == nullptr)
- content_provider = std::make_unique<FileSys::ContentProviderUnion>();
-
- /// Create default implementations of applets if one is not provided.
- applet_manager.SetDefaultAppletsIfMissing();
/// Reset all glue registrations
arp_manager.ResetAll();
@@ -253,11 +274,11 @@ struct System::Impl {
return SystemResultStatus::ErrorGetLoader;
}
- SystemResultStatus init_result{Init(system, emu_window)};
+ SystemResultStatus init_result{SetupForMainProcess(system, emu_window)};
if (init_result != SystemResultStatus::Success) {
LOG_CRITICAL(Core, "Failed to initialize system (Error {})!",
static_cast<int>(init_result));
- Shutdown();
+ ShutdownMainProcess();
return init_result;
}
@@ -276,7 +297,7 @@ struct System::Impl {
const auto [load_result, load_parameters] = app_loader->Load(*main_process, system);
if (load_result != Loader::ResultStatus::Success) {
LOG_CRITICAL(Core, "Failed to load ROM (Error {})!", load_result);
- Shutdown();
+ ShutdownMainProcess();
return static_cast<SystemResultStatus>(
static_cast<u32>(SystemResultStatus::ErrorLoader) + static_cast<u32>(load_result));
@@ -335,7 +356,7 @@ struct System::Impl {
return status;
}
- void Shutdown() {
+ void ShutdownMainProcess() {
SetShuttingDown(true);
// Log last frame performance stats if game was loded
@@ -369,7 +390,7 @@ struct System::Impl {
cheat_engine.reset();
telemetry_session.reset();
time_manager.Shutdown();
- core_timing.Shutdown();
+ core_timing.ClearPendingEvents();
app_loader.reset();
audio_core.reset();
gpu_core.reset();
@@ -377,7 +398,6 @@ struct System::Impl {
perf_stats.reset();
kernel.Shutdown();
memory.Reset();
- applet_manager.ClearAll();
if (auto room_member = room_network.GetRoomMember().lock()) {
Network::GameInfo game_info{};
@@ -520,6 +540,10 @@ const CpuManager& System::GetCpuManager() const {
return impl->cpu_manager;
}
+void System::Initialize() {
+ impl->Initialize(*this);
+}
+
SystemResultStatus System::Run() {
return impl->Run();
}
@@ -540,8 +564,8 @@ void System::InvalidateCpuInstructionCacheRange(VAddr addr, std::size_t size) {
impl->kernel.InvalidateCpuInstructionCacheRange(addr, size);
}
-void System::Shutdown() {
- impl->Shutdown();
+void System::ShutdownMainProcess() {
+ impl->ShutdownMainProcess();
}
bool System::IsShuttingDown() const {