summaryrefslogtreecommitdiff
path: root/Source/Core/DiscIO/DirectoryBlob.cpp
diff options
context:
space:
mode:
authorJMC47 <JMC4789@gmail.com>2022-07-28 20:29:31 -0400
committerGitHub <noreply@github.com>2022-07-28 20:29:31 -0400
commit3bf1ddc54957d597f9e0d6e8a0f5cafa3c65f82f (patch)
treebd3b2f3760af3386b404b6fcd28eb2675208cd82 /Source/Core/DiscIO/DirectoryBlob.cpp
parent000c9c7545dca99f2947d77549a7090d3929f9f2 (diff)
parentec3cfc01c1d87b038c72f162cefaa631cb788981 (diff)
Merge pull request #10730 from AdmiralCurtiss/riivolution-sysfile-patches
Riivolution: Add custom extension to patch boot.bin, bi2.bin, and apploader.img.
Diffstat (limited to 'Source/Core/DiscIO/DirectoryBlob.cpp')
-rw-r--r--Source/Core/DiscIO/DirectoryBlob.cpp73
1 files changed, 65 insertions, 8 deletions
diff --git a/Source/Core/DiscIO/DirectoryBlob.cpp b/Source/Core/DiscIO/DirectoryBlob.cpp
index 86de55595a..7decaac2e3 100644
--- a/Source/Core/DiscIO/DirectoryBlob.cpp
+++ b/Source/Core/DiscIO/DirectoryBlob.cpp
@@ -134,6 +134,12 @@ bool DiscContent::Read(u64* offset, u64* length, u8** buffer) const
const ContentFixedByte& source = std::get<ContentFixedByte>(m_content_source);
std::fill_n(*buffer, bytes_to_read, source.m_byte);
}
+ else if (std::holds_alternative<ContentByteVector>(m_content_source))
+ {
+ const ContentByteVector& source = std::get<ContentByteVector>(m_content_source);
+ std::copy(source.m_bytes.begin() + offset_in_content,
+ source.m_bytes.begin() + offset_in_content + bytes_to_read, *buffer);
+ }
else
{
PanicAlertFmt("DirectoryBlob: Invalid content source in DiscContent.");
@@ -356,6 +362,7 @@ std::unique_ptr<DirectoryBlobReader> DirectoryBlobReader::Create(const std::stri
std::unique_ptr<DirectoryBlobReader> DirectoryBlobReader::Create(
std::unique_ptr<DiscIO::VolumeDisc> volume,
+ const std::function<void(std::vector<FSTBuilderNode>* fst_nodes)>& sys_callback,
const std::function<void(std::vector<FSTBuilderNode>* fst_nodes, FSTBuilderNode* dol_node)>&
fst_callback)
{
@@ -363,7 +370,7 @@ std::unique_ptr<DirectoryBlobReader> DirectoryBlobReader::Create(
return nullptr;
return std::unique_ptr<DirectoryBlobReader>(
- new DirectoryBlobReader(std::move(volume), fst_callback));
+ new DirectoryBlobReader(std::move(volume), sys_callback, fst_callback));
}
DirectoryBlobReader::DirectoryBlobReader(const std::string& game_partition_root,
@@ -412,12 +419,14 @@ DirectoryBlobReader::DirectoryBlobReader(const std::string& game_partition_root,
DirectoryBlobReader::DirectoryBlobReader(
std::unique_ptr<DiscIO::VolumeDisc> volume,
+ const std::function<void(std::vector<FSTBuilderNode>* fst_nodes)>& sys_callback,
const std::function<void(std::vector<FSTBuilderNode>* fst_nodes, FSTBuilderNode* dol_node)>&
fst_callback)
: m_encryption_cache(this), m_wrapped_volume(std::move(volume))
{
- DirectoryBlobPartition game_partition(
- m_wrapped_volume.get(), m_wrapped_volume->GetGamePartition(), std::nullopt, fst_callback);
+ DirectoryBlobPartition game_partition(m_wrapped_volume.get(),
+ m_wrapped_volume->GetGamePartition(), std::nullopt,
+ sys_callback, fst_callback);
m_is_wii = game_partition.IsWii();
if (!m_is_wii)
@@ -457,7 +466,7 @@ DirectoryBlobReader::DirectoryBlobReader(
if (type)
{
partitions.emplace_back(
- DirectoryBlobPartition(m_wrapped_volume.get(), partition, m_is_wii, nullptr),
+ DirectoryBlobPartition(m_wrapped_volume.get(), partition, m_is_wii, nullptr, nullptr),
static_cast<PartitionType>(*type));
}
}
@@ -814,32 +823,80 @@ DirectoryBlobPartition::DirectoryBlobPartition(const std::string& root_directory
BuildFSTFromFolder(m_root_directory + "files/", fst_address);
}
+static void FillSingleFileNode(FSTBuilderNode* node, std::vector<u8> data)
+{
+ std::vector<BuilderContentSource> contents;
+ const size_t size = data.size();
+ contents.emplace_back(BuilderContentSource{0, size, ContentByteVector{std::move(data)}});
+ node->m_size = size;
+ node->m_content = std::move(contents);
+}
+
+static FSTBuilderNode BuildSingleFileNode(std::string filename, std::vector<u8> data,
+ void* userdata)
+{
+ FSTBuilderNode node{std::move(filename), 0, {}, userdata};
+ FillSingleFileNode(&node, std::move(data));
+ return node;
+}
+
+static std::vector<u8> ExtractNodeToVector(std::vector<FSTBuilderNode>* nodes, void* userdata)
+{
+ std::vector<u8> data;
+ const auto it =
+ std::find_if(nodes->begin(), nodes->end(), [&userdata](const FSTBuilderNode& node) {
+ return node.m_user_data == userdata;
+ });
+ if (it == nodes->end() || !it->IsFile())
+ return data;
+
+ DiscContentContainer tmp;
+ for (auto& content : it->GetFileContent())
+ tmp.Add(content.m_offset, content.m_size, std::move(content.m_source));
+ data.resize(it->m_size);
+ tmp.Read(0, it->m_size, data.data());
+ return data;
+}
+
DirectoryBlobPartition::DirectoryBlobPartition(
DiscIO::VolumeDisc* volume, const DiscIO::Partition& partition, std::optional<bool> is_wii,
+ const std::function<void(std::vector<FSTBuilderNode>* fst_nodes)>& sys_callback,
const std::function<void(std::vector<FSTBuilderNode>* fst_nodes, FSTBuilderNode* dol_node)>&
fst_callback)
: m_wrapped_partition(partition)
{
+ std::vector<FSTBuilderNode> sys_nodes;
+
std::vector<u8> disc_header(DISCHEADER_SIZE);
if (!volume->Read(DISCHEADER_ADDRESS, DISCHEADER_SIZE, disc_header.data(), partition))
disc_header.clear();
- SetDiscHeader(std::move(disc_header));
- SetDiscType(is_wii);
+ sys_nodes.emplace_back(BuildSingleFileNode("boot.bin", std::move(disc_header), &m_disc_header));
std::vector<u8> bi2(BI2_SIZE);
if (!volume->Read(BI2_ADDRESS, BI2_SIZE, bi2.data(), partition))
bi2.clear();
- SetBI2(std::move(bi2));
+ sys_nodes.emplace_back(BuildSingleFileNode("bi2.bin", std::move(bi2), &m_bi2));
std::vector<u8> apploader;
const auto apploader_size = GetApploaderSize(*volume, partition);
+ auto& apploader_node =
+ sys_nodes.emplace_back(FSTBuilderNode{"apploader.img", 0, {}, &m_apploader});
if (apploader_size)
{
apploader.resize(*apploader_size);
if (!volume->Read(APPLOADER_ADDRESS, *apploader_size, apploader.data(), partition))
apploader.clear();
+ FillSingleFileNode(&apploader_node, std::move(apploader));
}
- const u64 new_dol_address = SetApploader(apploader, "apploader");
+
+ if (sys_callback)
+ sys_callback(&sys_nodes);
+
+ SetDiscHeader(ExtractNodeToVector(&sys_nodes, &m_disc_header));
+ SetDiscType(is_wii);
+ SetBI2(ExtractNodeToVector(&sys_nodes, &m_bi2));
+ const u64 new_dol_address =
+ SetApploader(ExtractNodeToVector(&sys_nodes, &m_apploader), "apploader");
FSTBuilderNode dol_node{"main.dol", 0, {}};
const auto dol_offset = GetBootDOLOffset(*volume, partition);