core: Partially persist emulation state across game boots.
This commit is contained in:
parent
3785e8d1c7
commit
a35c884097
8 changed files with 65 additions and 58 deletions
|
@ -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 {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue