summaryrefslogtreecommitdiff
path: root/Source
diff options
context:
space:
mode:
authorAdmiral H. Curtiss <pikachu025@gmail.com>2020-12-31 23:26:16 +0100
committerAdmiral H. Curtiss <pikachu025@gmail.com>2021-01-02 17:46:12 +0100
commit2932b5f8cdaad063ccc869dfd7ce58891471b3a2 (patch)
treee058864aa8d7037e069ca6b6792f763eac89588b /Source
parentd9c686db3074360698b12d9beaf425b95a4348fd (diff)
Qt: Give better error messages when Wii save importing fails.
Diffstat (limited to 'Source')
-rw-r--r--Source/Core/Core/HW/WiiSave.cpp32
-rw-r--r--Source/Core/Core/HW/WiiSave.h15
-rw-r--r--Source/Core/DolphinQt/GameList/GameList.cpp5
-rw-r--r--Source/Core/DolphinQt/MenuBar.cpp42
4 files changed, 63 insertions, 31 deletions
diff --git a/Source/Core/Core/HW/WiiSave.cpp b/Source/Core/Core/HW/WiiSave.cpp
index 98498a29cb..2bc87b8dad 100644
--- a/Source/Core/Core/HW/WiiSave.cpp
+++ b/Source/Core/Core/HW/WiiSave.cpp
@@ -477,28 +477,28 @@ StoragePointer MakeDataBinStorage(IOS::HLE::IOSC* iosc, const std::string& path,
return StoragePointer{new DataBinStorage{iosc, path, mode}};
}
-bool Copy(Storage* source, Storage* dest)
+CopyResult Copy(Storage* source, Storage* dest)
{
// first make sure we can read all the data from the source
const auto header = source->ReadHeader();
if (!header)
{
ERROR_LOG_FMT(CORE, "WiiSave::Copy: Failed to read header");
- return false;
+ return CopyResult::CorruptedSource;
}
const auto bk_header = source->ReadBkHeader();
if (!bk_header)
{
ERROR_LOG_FMT(CORE, "WiiSave::Copy: Failed to read bk header");
- return false;
+ return CopyResult::CorruptedSource;
}
const auto files = source->ReadFiles();
if (!files)
{
ERROR_LOG_FMT(CORE, "WiiSave::Copy: Failed to read files");
- return false;
+ return CopyResult::CorruptedSource;
}
// once we have confirmed we can read the source, erase corresponding save in the destination
@@ -507,7 +507,7 @@ bool Copy(Storage* source, Storage* dest)
if (!dest->EraseSave())
{
ERROR_LOG_FMT(CORE, "WiiSave::Copy: Failed to erase existing save");
- return false;
+ return CopyResult::Error;
}
}
@@ -515,25 +515,25 @@ bool Copy(Storage* source, Storage* dest)
if (!dest->WriteHeader(*header))
{
ERROR_LOG_FMT(CORE, "WiiSave::Copy: Failed to write header");
- return false;
+ return CopyResult::Error;
}
if (!dest->WriteBkHeader(*bk_header))
{
ERROR_LOG_FMT(CORE, "WiiSave::Copy: Failed to write bk header");
- return false;
+ return CopyResult::Error;
}
if (!dest->WriteFiles(*files))
{
ERROR_LOG_FMT(CORE, "WiiSave::Copy: Failed to write files");
- return false;
+ return CopyResult::Error;
}
- return true;
+ return CopyResult::Success;
}
-bool Import(const std::string& data_bin_path, std::function<bool()> can_overwrite)
+CopyResult Import(const std::string& data_bin_path, std::function<bool()> can_overwrite)
{
IOS::HLE::Kernel ios;
const auto data_bin = MakeDataBinStorage(&ios.GetIOSC(), data_bin_path, "rb");
@@ -541,23 +541,23 @@ bool Import(const std::string& data_bin_path, std::function<bool()> can_overwrit
if (!header)
{
ERROR_LOG_FMT(CORE, "WiiSave::Import: Failed to read header");
- return false;
+ return CopyResult::CorruptedSource;
}
if (!WiiUtils::EnsureTMDIsImported(*ios.GetFS(), *ios.GetES(), header->tid))
{
ERROR_LOG_FMT(CORE, "WiiSave::Import: Failed to find or import TMD for title {:16x}",
header->tid);
- return false;
+ return CopyResult::TitleMissing;
}
const auto nand = MakeNandStorage(ios.GetFS().get(), header->tid);
if (nand->SaveExists() && !can_overwrite())
- return false;
+ return CopyResult::Cancelled;
return Copy(data_bin.get(), nand.get());
}
-static bool Export(u64 tid, std::string_view export_path, IOS::HLE::Kernel* ios)
+static CopyResult Export(u64 tid, std::string_view export_path, IOS::HLE::Kernel* ios)
{
const std::string path = fmt::format("{}/private/wii/title/{}{}{}{}/data.bin", export_path,
static_cast<char>(tid >> 24), static_cast<char>(tid >> 16),
@@ -566,7 +566,7 @@ static bool Export(u64 tid, std::string_view export_path, IOS::HLE::Kernel* ios)
MakeDataBinStorage(&ios->GetIOSC(), path, "w+b").get());
}
-bool Export(u64 tid, std::string_view export_path)
+CopyResult Export(u64 tid, std::string_view export_path)
{
IOS::HLE::Kernel ios;
return Export(tid, export_path, &ios);
@@ -578,7 +578,7 @@ size_t ExportAll(std::string_view export_path)
size_t exported_save_count = 0;
for (const u64 title : ios.GetES()->GetInstalledTitles())
{
- if (Export(title, export_path, &ios))
+ if (Export(title, export_path, &ios) == CopyResult::Success)
++exported_save_count;
}
return exported_save_count;
diff --git a/Source/Core/Core/HW/WiiSave.h b/Source/Core/Core/HW/WiiSave.h
index d989498a94..f7d414586a 100644
--- a/Source/Core/Core/HW/WiiSave.h
+++ b/Source/Core/Core/HW/WiiSave.h
@@ -32,12 +32,21 @@ using StoragePointer = std::unique_ptr<Storage, StorageDeleter>;
StoragePointer MakeNandStorage(IOS::HLE::FS::FileSystem* fs, u64 tid);
StoragePointer MakeDataBinStorage(IOS::HLE::IOSC* iosc, const std::string& path, const char* mode);
-bool Copy(Storage* source, Storage* destination);
+enum class CopyResult
+{
+ Success,
+ Error,
+ Cancelled,
+ CorruptedSource,
+ TitleMissing,
+};
+
+CopyResult Copy(Storage* source, Storage* destination);
/// Import a save into the NAND from a .bin file.
-bool Import(const std::string& data_bin_path, std::function<bool()> can_overwrite);
+CopyResult Import(const std::string& data_bin_path, std::function<bool()> can_overwrite);
/// Export a save to a .bin file.
-bool Export(u64 tid, std::string_view export_path);
+CopyResult Export(u64 tid, std::string_view export_path);
/// Export all saves that are in the NAND. Returns the number of exported saves.
size_t ExportAll(std::string_view export_path);
} // namespace WiiSave
diff --git a/Source/Core/DolphinQt/GameList/GameList.cpp b/Source/Core/DolphinQt/GameList/GameList.cpp
index e3056b4ef4..1b458bdb35 100644
--- a/Source/Core/DolphinQt/GameList/GameList.cpp
+++ b/Source/Core/DolphinQt/GameList/GameList.cpp
@@ -452,8 +452,11 @@ void GameList::ExportWiiSave()
QList<std::string> failed;
for (const auto& game : GetSelectedGames())
{
- if (!WiiSave::Export(game->GetTitleID(), export_dir.toStdString()))
+ if (WiiSave::Export(game->GetTitleID(), export_dir.toStdString()) !=
+ WiiSave::CopyResult::Success)
+ {
failed.push_back(game->GetName(UICommon::GameFile::Variant::LongAndPossiblyCustom));
+ }
}
if (!failed.isEmpty())
diff --git a/Source/Core/DolphinQt/MenuBar.cpp b/Source/Core/DolphinQt/MenuBar.cpp
index 3869fcf8e5..b1f6d40169 100644
--- a/Source/Core/DolphinQt/MenuBar.cpp
+++ b/Source/Core/DolphinQt/MenuBar.cpp
@@ -1066,19 +1066,39 @@ void MenuBar::ImportWiiSave()
if (file.isEmpty())
return;
- bool cancelled = false;
auto can_overwrite = [&] {
- bool yes = ModalMessageBox::question(
- this, tr("Save Import"),
- tr("Save data for this title already exists in the NAND. Consider backing up "
- "the current data before overwriting.\nOverwrite now?")) == QMessageBox::Yes;
- cancelled = !yes;
- return yes;
+ return ModalMessageBox::question(
+ this, tr("Save Import"),
+ tr("Save data for this title already exists in the NAND. Consider backing up "
+ "the current data before overwriting.\nOverwrite now?")) == QMessageBox::Yes;
};
- if (WiiSave::Import(file.toStdString(), can_overwrite))
- ModalMessageBox::information(this, tr("Save Import"), tr("Successfully imported save files."));
- else if (!cancelled)
- ModalMessageBox::critical(this, tr("Save Import"), tr("Failed to import save files."));
+
+ const auto result = WiiSave::Import(file.toStdString(), can_overwrite);
+ switch (result)
+ {
+ case WiiSave::CopyResult::Success:
+ ModalMessageBox::information(this, tr("Save Import"), tr("Successfully imported save file."));
+ break;
+ case WiiSave::CopyResult::CorruptedSource:
+ ModalMessageBox::critical(this, tr("Save Import"),
+ tr("Failed to import save file. The given file appears to be "
+ "corrupted or is not a valid Wii save."));
+ break;
+ case WiiSave::CopyResult::TitleMissing:
+ ModalMessageBox::critical(
+ this, tr("Save Import"),
+ tr("Failed to import save file. Please launch the game once, then try again."));
+ break;
+ case WiiSave::CopyResult::Cancelled:
+ break;
+ default:
+ ModalMessageBox::critical(
+ this, tr("Save Import"),
+ tr("Failed to import save file. Your NAND may be corrupt, or something is preventing "
+ "access to files within it. Try repairing your NAND (Tools -> Manage NAND -> Check "
+ "NAND...), then import the save again."));
+ break;
+ }
}
void MenuBar::ExportWiiSaves()