mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-30 13:20:03 +00:00 
			
		
		
		
	Show save/load errors to the user
This commit is contained in:
		
							parent
							
								
									915c426dc9
								
							
						
					
					
						commit
						d53e94db88
					
				
					 4 changed files with 34 additions and 39 deletions
				
			
		|  | @ -2079,6 +2079,9 @@ void GMainWindow::OnCoreError(Core::System::ResultStatus result, std::string det | ||||||
| 
 | 
 | ||||||
|         title = tr("System Archive Not Found"); |         title = tr("System Archive Not Found"); | ||||||
|         status_message = tr("System Archive Missing"); |         status_message = tr("System Archive Missing"); | ||||||
|  |     } else if (result == Core::System::ResultStatus::ErrorSavestate) { | ||||||
|  |         title = tr("Save/load Error"); | ||||||
|  |         message = QString::fromStdString(details); | ||||||
|     } else { |     } else { | ||||||
|         title = tr("Fatal Error"); |         title = tr("Fatal Error"); | ||||||
|         message = |         message = | ||||||
|  |  | ||||||
|  | @ -107,15 +107,27 @@ System::ResultStatus System::RunLoop(bool tight_loop) { | ||||||
|         return ResultStatus::ShutdownRequested; |         return ResultStatus::ShutdownRequested; | ||||||
|     case Signal::Load: { |     case Signal::Load: { | ||||||
|         LOG_INFO(Core, "Begin load"); |         LOG_INFO(Core, "Begin load"); | ||||||
|  |         try { | ||||||
|             System::LoadState(param); |             System::LoadState(param); | ||||||
|             LOG_INFO(Core, "Load completed"); |             LOG_INFO(Core, "Load completed"); | ||||||
|  |         } catch (const std::exception& e) { | ||||||
|  |             LOG_ERROR(Core, "Error loading: {}", e.what()); | ||||||
|  |             status_details = e.what(); | ||||||
|  |             return ResultStatus::ErrorSavestate; | ||||||
|  |         } | ||||||
|         frame_limiter.WaitOnce(); |         frame_limiter.WaitOnce(); | ||||||
|         return ResultStatus::Success; |         return ResultStatus::Success; | ||||||
|     } |     } | ||||||
|     case Signal::Save: { |     case Signal::Save: { | ||||||
|         LOG_INFO(Core, "Begin save"); |         LOG_INFO(Core, "Begin save"); | ||||||
|  |         try { | ||||||
|             System::SaveState(param); |             System::SaveState(param); | ||||||
|             LOG_INFO(Core, "Save completed"); |             LOG_INFO(Core, "Save completed"); | ||||||
|  |         } catch (const std::exception& e) { | ||||||
|  |             LOG_ERROR(Core, "Error saving: {}", e.what()); | ||||||
|  |             status_details = e.what(); | ||||||
|  |             return ResultStatus::ErrorSavestate; | ||||||
|  |         } | ||||||
|         frame_limiter.WaitOnce(); |         frame_limiter.WaitOnce(); | ||||||
|         return ResultStatus::Success; |         return ResultStatus::Success; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | @ -89,6 +89,7 @@ public: | ||||||
|                                             /// generic drivers installed
 |                                             /// generic drivers installed
 | ||||||
|         ErrorVideoCore_ErrorBelowGL33,      ///< Error in the video core due to the user not having
 |         ErrorVideoCore_ErrorBelowGL33,      ///< Error in the video core due to the user not having
 | ||||||
|                                             /// OpenGL 3.3 or higher
 |                                             /// OpenGL 3.3 or higher
 | ||||||
|  |         ErrorSavestate,                     ///< Error saving or loading
 | ||||||
|         ShutdownRequested,                  ///< Emulated program requested a system shutdown
 |         ShutdownRequested,                  ///< Emulated program requested a system shutdown
 | ||||||
|         ErrorUnknown                        ///< Any other error
 |         ErrorUnknown                        ///< Any other error
 | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|  | @ -90,26 +90,22 @@ std::vector<SaveStateInfo> ListSaveStates(u64 program_id) { | ||||||
| 
 | 
 | ||||||
| void System::SaveState(u32 slot) const { | void System::SaveState(u32 slot) const { | ||||||
|     std::ostringstream sstream{std::ios_base::binary}; |     std::ostringstream sstream{std::ios_base::binary}; | ||||||
|     try { |     // Serialize
 | ||||||
|     oarchive oa{sstream}; |     oarchive oa{sstream}; | ||||||
|     oa&* this; |     oa&* this; | ||||||
|     } catch (const std::exception& e) { | 
 | ||||||
|         LOG_ERROR(Core, "Error saving: {}", e.what()); |  | ||||||
|     } |  | ||||||
|     const std::string& str{sstream.str()}; |     const std::string& str{sstream.str()}; | ||||||
|     auto buffer = Common::Compression::CompressDataZSTDDefault( |     auto buffer = Common::Compression::CompressDataZSTDDefault( | ||||||
|         reinterpret_cast<const u8*>(str.data()), str.size()); |         reinterpret_cast<const u8*>(str.data()), str.size()); | ||||||
| 
 | 
 | ||||||
|     const auto path = GetSaveStatePath(title_id, slot); |     const auto path = GetSaveStatePath(title_id, slot); | ||||||
|     if (!FileUtil::CreateFullPath(path)) { |     if (!FileUtil::CreateFullPath(path)) { | ||||||
|         LOG_ERROR(Core, "Could not create path {}", path); |         throw std::runtime_error("Could not create path " + path); | ||||||
|         return; |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     FileUtil::IOFile file(path, "wb"); |     FileUtil::IOFile file(path, "wb"); | ||||||
|     if (!file) { |     if (!file) { | ||||||
|         LOG_ERROR(Core, "Could not open file {}", path); |         throw std::runtime_error("Could not open file " + path); | ||||||
|         return; |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     CSTHeader header{}; |     CSTHeader header{}; | ||||||
|  | @ -123,41 +119,27 @@ void System::SaveState(u32 slot) const { | ||||||
|                       std::chrono::system_clock::now().time_since_epoch()) |                       std::chrono::system_clock::now().time_since_epoch()) | ||||||
|                       .count(); |                       .count(); | ||||||
| 
 | 
 | ||||||
|     if (file.WriteBytes(&header, sizeof(header)) != sizeof(header)) { |     if (file.WriteBytes(&header, sizeof(header)) != sizeof(header) || | ||||||
|         LOG_ERROR(Core, "Could not write to file {}", path); |         file.WriteBytes(buffer.data(), buffer.size()) != buffer.size()) { | ||||||
|         return; |         throw std::runtime_error("Could not write to file " + path); | ||||||
|     } |  | ||||||
|     if (file.WriteBytes(buffer.data(), buffer.size()) != buffer.size()) { |  | ||||||
|         LOG_ERROR(Core, "Could not write to file {}", path); |  | ||||||
|         return; |  | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void System::LoadState(u32 slot) { | void System::LoadState(u32 slot) { | ||||||
|     if (Network::GetRoomMember().lock()->IsConnected()) { |     if (Network::GetRoomMember().lock()->IsConnected()) { | ||||||
|         LOG_ERROR(Core, "Unable to load while connected to multiplayer"); |         throw std::runtime_error("Unable to load while connected to multiplayer"); | ||||||
|         return; |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     const auto path = GetSaveStatePath(title_id, slot); |     const auto path = GetSaveStatePath(title_id, slot); | ||||||
|     if (!FileUtil::Exists(path)) { |  | ||||||
|         LOG_ERROR(Core, "File not exist {}", path); |  | ||||||
|         return; |  | ||||||
|     } |  | ||||||
| 
 | 
 | ||||||
|     std::vector<u8> decompressed; |     std::vector<u8> decompressed; | ||||||
|     { |     { | ||||||
|         std::vector<u8> buffer(FileUtil::GetSize(path) - sizeof(CSTHeader)); |         std::vector<u8> buffer(FileUtil::GetSize(path) - sizeof(CSTHeader)); | ||||||
| 
 | 
 | ||||||
|         FileUtil::IOFile file(path, "rb"); |         FileUtil::IOFile file(path, "rb"); | ||||||
|         if (!file) { |  | ||||||
|             LOG_ERROR(Core, "Could not open file {}", path); |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|         file.Seek(sizeof(CSTHeader), SEEK_SET); // Skip header
 |         file.Seek(sizeof(CSTHeader), SEEK_SET); // Skip header
 | ||||||
|         if (file.ReadBytes(buffer.data(), buffer.size()) != buffer.size()) { |         if (file.ReadBytes(buffer.data(), buffer.size()) != buffer.size()) { | ||||||
|             LOG_ERROR(Core, "Could not read from file {}", path); |             throw std::runtime_error("Could not read from file at " + path); | ||||||
|             return; |  | ||||||
|         } |         } | ||||||
|         decompressed = Common::Compression::DecompressDataZSTD(buffer); |         decompressed = Common::Compression::DecompressDataZSTD(buffer); | ||||||
|     } |     } | ||||||
|  | @ -166,12 +148,9 @@ void System::LoadState(u32 slot) { | ||||||
|         std::ios_base::binary}; |         std::ios_base::binary}; | ||||||
|     decompressed.clear(); |     decompressed.clear(); | ||||||
| 
 | 
 | ||||||
|     try { |     // Deserialize
 | ||||||
|     iarchive ia{sstream}; |     iarchive ia{sstream}; | ||||||
|     ia&* this; |     ia&* this; | ||||||
|     } catch (const std::exception& e) { |  | ||||||
|         LOG_ERROR(Core, "Error loading: {}", e.what()); |  | ||||||
|     } |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| } // namespace Core
 | } // namespace Core
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue