From 7b9d43a834d8cf6be6be9b4b0c582f9327d12184 Mon Sep 17 00:00:00 2001 From: "Admiral H. Curtiss" Date: Thu, 15 Aug 2019 04:08:20 +0200 Subject: [PATCH] Qt/GCMemcardManager and Qt/GameCubePane: Give detailed error messages for invalid memory cards. --- Source/Core/DolphinQt/GCMemcardManager.cpp | 54 ++++++++++++++++--- Source/Core/DolphinQt/GCMemcardManager.h | 4 ++ .../Core/DolphinQt/Settings/GameCubePane.cpp | 12 ++--- 3 files changed, 58 insertions(+), 12 deletions(-) diff --git a/Source/Core/DolphinQt/GCMemcardManager.cpp b/Source/Core/DolphinQt/GCMemcardManager.cpp index 7b60853f8d..12e9e5d48c 100644 --- a/Source/Core/DolphinQt/GCMemcardManager.cpp +++ b/Source/Core/DolphinQt/GCMemcardManager.cpp @@ -17,6 +17,8 @@ #include #include #include +#include +#include #include #include @@ -241,14 +243,20 @@ void GCMemcardManager::UpdateActions() void GCMemcardManager::SetSlotFile(int slot, QString path) { - // TODO: Check error codes and give reasonable error messages. auto [error_code, memcard] = GCMemcard::Open(path.toStdString()); - if (error_code.HasCriticalErrors() || !memcard || !memcard->IsValid()) - return; - - m_slot_file_edit[slot]->setText(path); - m_slot_memcard[slot] = std::make_unique(std::move(*memcard)); + if (!error_code.HasCriticalErrors() && memcard && memcard->IsValid()) + { + m_slot_file_edit[slot]->setText(path); + m_slot_memcard[slot] = std::make_unique(std::move(*memcard)); + } + else + { + m_slot_memcard[slot] = nullptr; + ModalMessageBox::critical( + this, tr("Error"), + tr("Failed opening memory card:\n%1").arg(GetErrorMessagesForErrorCode(error_code))); + } UpdateSlotTable(slot); UpdateActions(); @@ -524,3 +532,37 @@ std::vector GCMemcardManager::GetIconFromSaveFile(int file_index, int s return frame_pixmaps; } + +QString GCMemcardManager::GetErrorMessagesForErrorCode(const GCMemcardErrorCode& code) +{ + QStringList sl; + + if (code.Test(GCMemcardValidityIssues::FAILED_TO_OPEN)) + sl.push_back(tr("Couldn't open file.")); + + if (code.Test(GCMemcardValidityIssues::IO_ERROR)) + sl.push_back(tr("Couldn't read file.")); + + if (code.Test(GCMemcardValidityIssues::INVALID_CARD_SIZE)) + sl.push_back(tr("Filesize does not match any known GameCube Memory Card size.")); + + if (code.Test(GCMemcardValidityIssues::MISMATCHED_CARD_SIZE)) + sl.push_back(tr("Filesize in header mismatches actual card size.")); + + if (code.Test(GCMemcardValidityIssues::INVALID_CHECKSUM)) + sl.push_back(tr("Invalid checksums.")); + + if (code.Test(GCMemcardValidityIssues::FREE_BLOCK_MISMATCH)) + sl.push_back(tr("Mismatch between free block count in header and actually unused blocks.")); + + if (code.Test(GCMemcardValidityIssues::DIR_BAT_INCONSISTENT)) + sl.push_back(tr("Mismatch between internal data structures.")); + + if (code.Test(GCMemcardValidityIssues::DATA_IN_UNUSED_AREA)) + sl.push_back(tr("Data in area of file that should be unused.")); + + if (sl.empty()) + return QStringLiteral("No errors."); + + return sl.join(QStringLiteral("\n")); +} diff --git a/Source/Core/DolphinQt/GCMemcardManager.h b/Source/Core/DolphinQt/GCMemcardManager.h index e1579abe11..5e25989221 100644 --- a/Source/Core/DolphinQt/GCMemcardManager.h +++ b/Source/Core/DolphinQt/GCMemcardManager.h @@ -12,6 +12,7 @@ #include class GCMemcard; +class GCMemcardErrorCode; class QDialogButtonBox; class QGroupBox; @@ -19,6 +20,7 @@ class QLabel; class QLineEdit; class QPixmap; class QPushButton; +class QString; class QTableWidget; class QTimer; @@ -29,6 +31,8 @@ public: explicit GCMemcardManager(QWidget* parent = nullptr); ~GCMemcardManager(); + static QString GetErrorMessagesForErrorCode(const GCMemcardErrorCode& code); + private: void CreateWidgets(); void ConnectWidgets(); diff --git a/Source/Core/DolphinQt/Settings/GameCubePane.cpp b/Source/Core/DolphinQt/Settings/GameCubePane.cpp index 46595fc3c3..169d670a35 100644 --- a/Source/Core/DolphinQt/Settings/GameCubePane.cpp +++ b/Source/Core/DolphinQt/Settings/GameCubePane.cpp @@ -28,6 +28,7 @@ #include "Core/HW/GCMemcard/GCMemcard.h" #include "DolphinQt/Config/Mapping/MappingWindow.h" +#include "DolphinQt/GCMemcardManager.h" #include "DolphinQt/QtUtils/ModalMessageBox.h" enum @@ -212,16 +213,15 @@ void GameCubePane::OnConfigPressed(int slot) { if (File::Exists(filename.toStdString())) { - // TODO: check error codes and give reasonable error messages auto [error_code, mc] = GCMemcard::Open(filename.toStdString()); if (error_code.HasCriticalErrors() || !mc || !mc->IsValid()) { - ModalMessageBox::critical(this, tr("Error"), - tr("Cannot use that file as a memory card.\n%1\n" - "is not a valid GameCube memory card file") - .arg(filename)); - + ModalMessageBox::critical( + this, tr("Error"), + tr("The file\n%1\nis either corrupted or not a GameCube memory card file.\n%2") + .arg(filename) + .arg(GCMemcardManager::GetErrorMessagesForErrorCode(error_code))); return; } }