diff --git a/src/citra_qt/bootmanager.cpp b/src/citra_qt/bootmanager.cpp index 78541e880..feab64906 100644 --- a/src/citra_qt/bootmanager.cpp +++ b/src/citra_qt/bootmanager.cpp @@ -132,7 +132,9 @@ void OpenGLWindow::Present() { return; context->makeCurrent(this); - VideoCore::g_renderer->TryPresent(100); + if (VideoCore::g_renderer) { + VideoCore::g_renderer->TryPresent(100); + } context->swapBuffers(this); auto f = context->versionFunctions(); f->glFinish(); diff --git a/src/common/serialization/boost_interval_set.hpp b/src/common/serialization/boost_interval_set.hpp index 905e3f145..d4e48e62a 100644 --- a/src/common/serialization/boost_interval_set.hpp +++ b/src/common/serialization/boost_interval_set.hpp @@ -12,7 +12,7 @@ namespace boost::serialization { template void save(Archive& ar, const boost::icl::interval_set& set, const unsigned int file_version) { - ar << static_cast(set.size()); + ar << static_cast(set.iterative_size()); for (auto& v : set) { ar << v; } @@ -24,9 +24,9 @@ void load(Archive& ar, boost::icl::interval_set& set, const unsigned int file ar >> count; set.clear(); for (u64 i = 0; i < count; i++) { - T value{}; + typename boost::icl::interval_set::interval_type value{}; ar >> value; - set.insert(value); + set.add(value); } } diff --git a/src/core/core.cpp b/src/core/core.cpp index 69223a05e..1e48c0c62 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -478,7 +478,7 @@ void System::RegisterImageInterface(std::shared_ptr im registered_image_interface = std::move(image_interface); } -void System::Shutdown() { +void System::Shutdown(bool is_deserializing) { // Log last frame performance stats const auto perf_results = GetAndResetPerfStats(); telemetry_session->AddField(Telemetry::FieldType::Performance, "Shutdown_EmulationSpeed", @@ -494,17 +494,19 @@ void System::Shutdown() { GDBStub::Shutdown(); VideoCore::Shutdown(); HW::Shutdown(); + if (!is_deserializing) { + perf_stats.reset(); + cheat_engine.reset(); + app_loader.reset(); + } telemetry_session.reset(); - perf_stats.reset(); rpc_server.reset(); - cheat_engine.reset(); archive_manager.reset(); service_manager.reset(); dsp_core.reset(); cpu_cores.clear(); kernel.reset(); timing.reset(); - app_loader.reset(); if (video_dumper->IsDumping()) { video_dumper->StopDumping(); @@ -565,6 +567,7 @@ void System::serialize(Archive& ar, const unsigned int file_version) { // This needs to be set from somewhere - might as well be here! if (Archive::is_loading::value) { Service::GSP::SetGlobalModule(*this); + memory->SetDSP(*dsp_core); } } diff --git a/src/core/core.h b/src/core/core.h index dfb6aee3e..9fe98f723 100644 --- a/src/core/core.h +++ b/src/core/core.h @@ -113,7 +113,7 @@ public: ResultStatus SingleStep(); /// Shutdown the emulated system. - void Shutdown(); + void Shutdown(bool is_deserializing = false); /// Shutdown and then load again void Reset(); diff --git a/src/core/savestate.cpp b/src/core/savestate.cpp index d52789b2c..ae5ba11a8 100644 --- a/src/core/savestate.cpp +++ b/src/core/savestate.cpp @@ -8,6 +8,7 @@ #include "common/logging/log.h" #include "common/scm_rev.h" #include "common/zstd_compression.h" +#include "core/cheats/cheats.h" #include "core/core.h" #include "core/savestate.h" #include "video_core/video_core.h" @@ -158,6 +159,15 @@ void System::LoadState(u32 slot) { std::ios_base::binary}; decompressed.clear(); + // When loading, we want to make sure any lingering state gets cleared out before we begin. + // Shutdown, but persist a few things between loads... + Shutdown(true); + + // Re-initialize everything like it was before + auto system_mode = this->app_loader->LoadKernelSystemMode(); + auto n3ds_mode = this->app_loader->LoadKernelN3dsMode(); + Init(*m_emu_window, *system_mode.first, *n3ds_mode.first); + try { {