Core: Implement Wii NAND path redirects for Riivolution savegame patches.

This commit is contained in:
Admiral H. Curtiss
2021-10-03 06:23:33 +02:00
parent 588c31acb6
commit fe242f79ee
11 changed files with 160 additions and 35 deletions

View File

@ -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

View File

@ -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