summaryrefslogtreecommitdiff
path: root/Source/Core/DiscIO
diff options
context:
space:
mode:
authorAdmiral H. Curtiss <pikachu025@gmail.com>2021-10-03 06:23:33 +0200
committerAdmiral H. Curtiss <pikachu025@gmail.com>2021-10-24 00:09:07 +0200
commitfe242f79eeb5c92c39362203cdeb46e9b72707a7 (patch)
treebc13d49ba38846d325e60091250fa23edb2dc6c0 /Source/Core/DiscIO
parent588c31acb61d966dc05e0c1b346aad37deeb4905 (diff)
Core: Implement Wii NAND path redirects for Riivolution savegame patches.
Diffstat (limited to 'Source/Core/DiscIO')
-rw-r--r--Source/Core/DiscIO/RiivolutionPatcher.cpp24
-rw-r--r--Source/Core/DiscIO/RiivolutionPatcher.h13
2 files changed, 37 insertions, 0 deletions
diff --git a/Source/Core/DiscIO/RiivolutionPatcher.cpp b/Source/Core/DiscIO/RiivolutionPatcher.cpp
index af8be05944..3f3a1f876f 100644
--- a/Source/Core/DiscIO/RiivolutionPatcher.cpp
+++ b/Source/Core/DiscIO/RiivolutionPatcher.cpp
@@ -14,6 +14,7 @@
#include "Common/IOFile.h"
#include "Common/StringUtil.h"
#include "Core/HW/Memmap.h"
+#include "Core/IOS/FS/FileSystem.h"
#include "Core/PowerPC/MMU.h"
#include "DiscIO/DirectoryBlob.h"
#include "DiscIO/RiivolutionParser.h"
@@ -174,6 +175,12 @@ FileDataLoaderHostFS::MakeContentSource(std::string_view external_relative_path,
ContentFile{std::move(*path), external_offset}};
}
+std::optional<std::string>
+FileDataLoaderHostFS::ResolveSavegameRedirectPath(std::string_view external_relative_path)
+{
+ return MakeAbsoluteFromRelative(external_relative_path);
+}
+
// 'before' and 'after' should be two copies of the same source
// 'split_at' needs to be between the start and end of the source, may not match either boundary
static void SplitAt(BuilderContentSource* before, BuilderContentSource* after, u64 split_at)
@@ -588,4 +595,21 @@ void ApplyPatchesToMemory(const std::vector<Patch>& patches)
}
}
}
+
+std::optional<SavegameRedirect>
+ExtractSavegameRedirect(const std::vector<Patch>& riivolution_patches)
+{
+ for (const auto& patch : riivolution_patches)
+ {
+ if (!patch.m_savegame_patches.empty())
+ {
+ const auto& save_patch = patch.m_savegame_patches[0];
+ auto resolved = patch.m_file_data_loader->ResolveSavegameRedirectPath(save_patch.m_external);
+ if (resolved)
+ return SavegameRedirect{std::move(*resolved), save_patch.m_clone};
+ return std::nullopt;
+ }
+ }
+ return std::nullopt;
+}
} // namespace DiscIO::Riivolution
diff --git a/Source/Core/DiscIO/RiivolutionPatcher.h b/Source/Core/DiscIO/RiivolutionPatcher.h
index 8ddd887cb5..e93ae5c00e 100644
--- a/Source/Core/DiscIO/RiivolutionPatcher.h
+++ b/Source/Core/DiscIO/RiivolutionPatcher.h
@@ -3,6 +3,7 @@
#pragma once
+#include <optional>
#include <string>
#include <string_view>
#include <vector>
@@ -12,6 +13,12 @@
namespace DiscIO::Riivolution
{
+struct SavegameRedirect
+{
+ std::string m_target_path;
+ bool m_clone;
+};
+
class FileDataLoader
{
public:
@@ -28,6 +35,8 @@ public:
virtual BuilderContentSource MakeContentSource(std::string_view external_relative_path,
u64 external_offset, u64 external_size,
u64 disc_offset) = 0;
+ virtual std::optional<std::string>
+ ResolveSavegameRedirectPath(std::string_view external_relative_path) = 0;
};
class FileDataLoaderHostFS : public FileDataLoader
@@ -46,6 +55,8 @@ public:
BuilderContentSource MakeContentSource(std::string_view external_relative_path,
u64 external_offset, u64 external_size,
u64 disc_offset) override;
+ std::optional<std::string>
+ ResolveSavegameRedirectPath(std::string_view external_relative_path) override;
private:
std::optional<std::string> MakeAbsoluteFromRelative(std::string_view external_relative_path);
@@ -58,4 +69,6 @@ void ApplyPatchesToFiles(const std::vector<Patch>& patches,
std::vector<DiscIO::FSTBuilderNode>* fst,
DiscIO::FSTBuilderNode* dol_node);
void ApplyPatchesToMemory(const std::vector<Patch>& patches);
+std::optional<SavegameRedirect>
+ExtractSavegameRedirect(const std::vector<Patch>& riivolution_patches);
} // namespace DiscIO::Riivolution