From d53e94db88d18178ed73a5bc48b8df8e2fa4c992 Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Sun, 12 Apr 2020 23:12:15 +0100 Subject: [PATCH] Show save/load errors to the user --- src/citra_qt/main.cpp | 3 +++ src/core/core.cpp | 20 +++++++++++++---- src/core/core.h | 1 + src/core/savestate.cpp | 49 ++++++++++++------------------------------ 4 files changed, 34 insertions(+), 39 deletions(-) diff --git a/src/citra_qt/main.cpp b/src/citra_qt/main.cpp index f6dc3f2ef..7389b8c23 100644 --- a/src/citra_qt/main.cpp +++ b/src/citra_qt/main.cpp @@ -2079,6 +2079,9 @@ void GMainWindow::OnCoreError(Core::System::ResultStatus result, std::string det title = tr("System Archive Not Found"); status_message = tr("System Archive Missing"); + } else if (result == Core::System::ResultStatus::ErrorSavestate) { + title = tr("Save/load Error"); + message = QString::fromStdString(details); } else { title = tr("Fatal Error"); message = diff --git a/src/core/core.cpp b/src/core/core.cpp index 1421d7f70..14b41207a 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -107,15 +107,27 @@ System::ResultStatus System::RunLoop(bool tight_loop) { return ResultStatus::ShutdownRequested; case Signal::Load: { LOG_INFO(Core, "Begin load"); - System::LoadState(param); - LOG_INFO(Core, "Load completed"); + try { + System::LoadState(param); + 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(); return ResultStatus::Success; } case Signal::Save: { LOG_INFO(Core, "Begin save"); - System::SaveState(param); - LOG_INFO(Core, "Save completed"); + try { + System::SaveState(param); + 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(); return ResultStatus::Success; } diff --git a/src/core/core.h b/src/core/core.h index eb3dc01b3..dca6a6888 100644 --- a/src/core/core.h +++ b/src/core/core.h @@ -89,6 +89,7 @@ public: /// generic drivers installed ErrorVideoCore_ErrorBelowGL33, ///< Error in the video core due to the user not having /// OpenGL 3.3 or higher + ErrorSavestate, ///< Error saving or loading ShutdownRequested, ///< Emulated program requested a system shutdown ErrorUnknown ///< Any other error }; diff --git a/src/core/savestate.cpp b/src/core/savestate.cpp index 2a6fb92cb..26fc0cbed 100644 --- a/src/core/savestate.cpp +++ b/src/core/savestate.cpp @@ -90,26 +90,22 @@ std::vector ListSaveStates(u64 program_id) { void System::SaveState(u32 slot) const { std::ostringstream sstream{std::ios_base::binary}; - try { - oarchive oa{sstream}; - oa&* this; - } catch (const std::exception& e) { - LOG_ERROR(Core, "Error saving: {}", e.what()); - } + // Serialize + oarchive oa{sstream}; + oa&* this; + const std::string& str{sstream.str()}; auto buffer = Common::Compression::CompressDataZSTDDefault( reinterpret_cast(str.data()), str.size()); const auto path = GetSaveStatePath(title_id, slot); if (!FileUtil::CreateFullPath(path)) { - LOG_ERROR(Core, "Could not create path {}", path); - return; + throw std::runtime_error("Could not create path " + path); } FileUtil::IOFile file(path, "wb"); if (!file) { - LOG_ERROR(Core, "Could not open file {}", path); - return; + throw std::runtime_error("Could not open file " + path); } CSTHeader header{}; @@ -123,41 +119,27 @@ void System::SaveState(u32 slot) const { std::chrono::system_clock::now().time_since_epoch()) .count(); - if (file.WriteBytes(&header, sizeof(header)) != sizeof(header)) { - LOG_ERROR(Core, "Could not write to file {}", path); - return; - } - if (file.WriteBytes(buffer.data(), buffer.size()) != buffer.size()) { - LOG_ERROR(Core, "Could not write to file {}", path); - return; + if (file.WriteBytes(&header, sizeof(header)) != sizeof(header) || + file.WriteBytes(buffer.data(), buffer.size()) != buffer.size()) { + throw std::runtime_error("Could not write to file " + path); } } void System::LoadState(u32 slot) { if (Network::GetRoomMember().lock()->IsConnected()) { - LOG_ERROR(Core, "Unable to load while connected to multiplayer"); - return; + throw std::runtime_error("Unable to load while connected to multiplayer"); } const auto path = GetSaveStatePath(title_id, slot); - if (!FileUtil::Exists(path)) { - LOG_ERROR(Core, "File not exist {}", path); - return; - } std::vector decompressed; { std::vector buffer(FileUtil::GetSize(path) - sizeof(CSTHeader)); FileUtil::IOFile file(path, "rb"); - if (!file) { - LOG_ERROR(Core, "Could not open file {}", path); - return; - } file.Seek(sizeof(CSTHeader), SEEK_SET); // Skip header if (file.ReadBytes(buffer.data(), buffer.size()) != buffer.size()) { - LOG_ERROR(Core, "Could not read from file {}", path); - return; + throw std::runtime_error("Could not read from file at " + path); } decompressed = Common::Compression::DecompressDataZSTD(buffer); } @@ -166,12 +148,9 @@ void System::LoadState(u32 slot) { std::ios_base::binary}; decompressed.clear(); - try { - iarchive ia{sstream}; - ia&* this; - } catch (const std::exception& e) { - LOG_ERROR(Core, "Error loading: {}", e.what()); - } + // Deserialize + iarchive ia{sstream}; + ia&* this; } } // namespace Core