mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-30 21:30:04 +00:00 
			
		
		
		
	Clear out state before deserialization - fixes many crashes.
This commit is contained in:
		
							parent
							
								
									f156fdd332
								
							
						
					
					
						commit
						5b6ee9a6ab
					
				
					 5 changed files with 24 additions and 9 deletions
				
			
		|  | @ -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 { | ||||||
| 
 | 
 | ||||||
|         { |         { | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue