Clear out state before deserialization - fixes many crashes.
This commit is contained in:
parent
f156fdd332
commit
5b6ee9a6ab
|
@ -132,7 +132,9 @@ void OpenGLWindow::Present() {
|
||||||
return;
|
return;
|
||||||
|
|
||||||
context->makeCurrent(this);
|
context->makeCurrent(this);
|
||||||
VideoCore::g_renderer->TryPresent(100);
|
if (VideoCore::g_renderer) {
|
||||||
|
VideoCore::g_renderer->TryPresent(100);
|
||||||
|
}
|
||||||
context->swapBuffers(this);
|
context->swapBuffers(this);
|
||||||
auto f = context->versionFunctions<QOpenGLFunctions_3_3_Core>();
|
auto f = context->versionFunctions<QOpenGLFunctions_3_3_Core>();
|
||||||
f->glFinish();
|
f->glFinish();
|
||||||
|
|
|
@ -12,7 +12,7 @@ namespace boost::serialization {
|
||||||
|
|
||||||
template <class Archive, class T>
|
template <class Archive, class T>
|
||||||
void save(Archive& ar, const boost::icl::interval_set<T>& set, const unsigned int file_version) {
|
void save(Archive& ar, const boost::icl::interval_set<T>& set, const unsigned int file_version) {
|
||||||
ar << static_cast<u64>(set.size());
|
ar << static_cast<u64>(set.iterative_size());
|
||||||
for (auto& v : set) {
|
for (auto& v : set) {
|
||||||
ar << v;
|
ar << v;
|
||||||
}
|
}
|
||||||
|
@ -24,9 +24,9 @@ void load(Archive& ar, boost::icl::interval_set<T>& set, const unsigned int file
|
||||||
ar >> count;
|
ar >> count;
|
||||||
set.clear();
|
set.clear();
|
||||||
for (u64 i = 0; i < count; i++) {
|
for (u64 i = 0; i < count; i++) {
|
||||||
T value{};
|
typename boost::icl::interval_set<T>::interval_type value{};
|
||||||
ar >> value;
|
ar >> value;
|
||||||
set.insert(value);
|
set.add(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -478,7 +478,7 @@ void System::RegisterImageInterface(std::shared_ptr<Frontend::ImageInterface> im
|
||||||
registered_image_interface = std::move(image_interface);
|
registered_image_interface = std::move(image_interface);
|
||||||
}
|
}
|
||||||
|
|
||||||
void System::Shutdown() {
|
void System::Shutdown(bool is_deserializing) {
|
||||||
// Log last frame performance stats
|
// Log last frame performance stats
|
||||||
const auto perf_results = GetAndResetPerfStats();
|
const auto perf_results = GetAndResetPerfStats();
|
||||||
telemetry_session->AddField(Telemetry::FieldType::Performance, "Shutdown_EmulationSpeed",
|
telemetry_session->AddField(Telemetry::FieldType::Performance, "Shutdown_EmulationSpeed",
|
||||||
|
@ -494,17 +494,19 @@ void System::Shutdown() {
|
||||||
GDBStub::Shutdown();
|
GDBStub::Shutdown();
|
||||||
VideoCore::Shutdown();
|
VideoCore::Shutdown();
|
||||||
HW::Shutdown();
|
HW::Shutdown();
|
||||||
|
if (!is_deserializing) {
|
||||||
|
perf_stats.reset();
|
||||||
|
cheat_engine.reset();
|
||||||
|
app_loader.reset();
|
||||||
|
}
|
||||||
telemetry_session.reset();
|
telemetry_session.reset();
|
||||||
perf_stats.reset();
|
|
||||||
rpc_server.reset();
|
rpc_server.reset();
|
||||||
cheat_engine.reset();
|
|
||||||
archive_manager.reset();
|
archive_manager.reset();
|
||||||
service_manager.reset();
|
service_manager.reset();
|
||||||
dsp_core.reset();
|
dsp_core.reset();
|
||||||
cpu_cores.clear();
|
cpu_cores.clear();
|
||||||
kernel.reset();
|
kernel.reset();
|
||||||
timing.reset();
|
timing.reset();
|
||||||
app_loader.reset();
|
|
||||||
|
|
||||||
if (video_dumper->IsDumping()) {
|
if (video_dumper->IsDumping()) {
|
||||||
video_dumper->StopDumping();
|
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!
|
// This needs to be set from somewhere - might as well be here!
|
||||||
if (Archive::is_loading::value) {
|
if (Archive::is_loading::value) {
|
||||||
Service::GSP::SetGlobalModule(*this);
|
Service::GSP::SetGlobalModule(*this);
|
||||||
|
memory->SetDSP(*dsp_core);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -113,7 +113,7 @@ public:
|
||||||
ResultStatus SingleStep();
|
ResultStatus SingleStep();
|
||||||
|
|
||||||
/// Shutdown the emulated system.
|
/// Shutdown the emulated system.
|
||||||
void Shutdown();
|
void Shutdown(bool is_deserializing = false);
|
||||||
|
|
||||||
/// Shutdown and then load again
|
/// Shutdown and then load again
|
||||||
void Reset();
|
void Reset();
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "common/scm_rev.h"
|
#include "common/scm_rev.h"
|
||||||
#include "common/zstd_compression.h"
|
#include "common/zstd_compression.h"
|
||||||
|
#include "core/cheats/cheats.h"
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
#include "core/savestate.h"
|
#include "core/savestate.h"
|
||||||
#include "video_core/video_core.h"
|
#include "video_core/video_core.h"
|
||||||
|
@ -158,6 +159,15 @@ void System::LoadState(u32 slot) {
|
||||||
std::ios_base::binary};
|
std::ios_base::binary};
|
||||||
decompressed.clear();
|
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 {
|
try {
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
Reference in New Issue