|
|
|
@ -133,6 +133,30 @@ 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(); |
|
|
|
} |
|
|
|
|
|
|
|
SystemResultStatus Run() { |
|
|
|
std::unique_lock<std::mutex> lk(suspend_guard); |
|
|
|
status = SystemResultStatus::Success; |
|
|
|
@ -178,37 +202,17 @@ 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); |
|
|
|
|
|
|
|
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 +257,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 +280,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 +339,7 @@ struct System::Impl { |
|
|
|
return status; |
|
|
|
} |
|
|
|
|
|
|
|
void Shutdown() { |
|
|
|
void ShutdownMainProcess() { |
|
|
|
SetShuttingDown(true); |
|
|
|
|
|
|
|
// Log last frame performance stats if game was loded
|
|
|
|
@ -369,7 +373,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 +381,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 +523,10 @@ const CpuManager& System::GetCpuManager() const { |
|
|
|
return impl->cpu_manager; |
|
|
|
} |
|
|
|
|
|
|
|
void System::Initialize() { |
|
|
|
impl->Initialize(*this); |
|
|
|
} |
|
|
|
|
|
|
|
SystemResultStatus System::Run() { |
|
|
|
return impl->Run(); |
|
|
|
} |
|
|
|
@ -540,8 +547,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 { |
|
|
|
|