summaryrefslogtreecommitdiff
path: root/Source/Core/DiscIO/DirectoryBlob.cpp
diff options
context:
space:
mode:
authornaari3 <naari.named@gmail.com>2026-04-25 19:48:00 +0900
committernaari3 <naari.named@gmail.com>2026-04-25 19:48:00 +0900
commite013d950533a5b6e6e411347f2997d4dff5f4951 (patch)
tree5635c19c2320b5af4130de03f46faba2700c9818 /Source/Core/DiscIO/DirectoryBlob.cpp
parent6871428a8146bf4513123bbe9d8b39948d290a4b (diff)
DirectoryBlob: fix data alignment for GC/Triforce and skip Triforce DIMM memory range
The 0x8000 alignment in DirectoryBlob is needed for Wii disc group encryption, but for GC/Triforce it inflates file offsets unnecessarily. Use 0x20 alignment for Triforce (matching original disc layout) while keeping 0x8000 for GC due to DTK audio streaming requirements. On Triforce games with many files, the inflated offsets can land in the AMMediaboard DIMM memory range (0x1F000000-0x1F800000). Reads from that region return SRAM data instead of disc data, causing the game to hang. Skip the DIMM range when assigning per-file data offsets if any portion of the file would overlap [0x1F000000, 0x1F800000).
Diffstat (limited to 'Source/Core/DiscIO/DirectoryBlob.cpp')
-rw-r--r--Source/Core/DiscIO/DirectoryBlob.cpp15
1 files changed, 12 insertions, 3 deletions
diff --git a/Source/Core/DiscIO/DirectoryBlob.cpp b/Source/Core/DiscIO/DirectoryBlob.cpp
index fe6c3880df..63ff5a6eb6 100644
--- a/Source/Core/DiscIO/DirectoryBlob.cpp
+++ b/Source/Core/DiscIO/DirectoryBlob.cpp
@@ -895,7 +895,8 @@ DirectoryBlobPartition::DirectoryBlobPartition(
const std::function<void(std::vector<FSTBuilderNode>* fst_nodes, FSTBuilderNode* dol_node)>&
fst_callback,
DirectoryBlobReader* blob)
- : m_wrapped_partition(partition)
+ : m_wrapped_partition(partition),
+ m_is_triforce(volume && volume->GetVolumeType() == Platform::Triforce)
{
std::vector<FSTBuilderNode> sys_nodes;
@@ -1230,6 +1231,14 @@ void DirectoryBlobPartition::WriteDirectory(std::vector<u8>* fst_data,
}
else
{
+ // Skip Triforce DIMM so the file doesn't overlap with it. Any portion of
+ // a file placed in 0x1F000000-0x1F800000 would be shadowed by SRAM on the
+ // AMMediaboard and read back as DIMM contents instead of disc data.
+ if (m_is_triforce && *data_offset < 0x1F800000 && *data_offset + entry.m_size > 0x1F000000)
+ {
+ *data_offset = 0x1F800000ull;
+ }
+
// put entry in FST
WriteEntryData(fst_data, fst_offset, FILE_ENTRY, *name_offset, *data_offset, entry.m_size,
m_address_shift);
@@ -1243,8 +1252,8 @@ void DirectoryBlobPartition::WriteDirectory(std::vector<u8>* fst_data,
std::move(content.m_source));
}
- // 32 KiB aligned - many games are fine with less alignment, but not all
- *data_offset = Common::AlignUp(*data_offset + entry.m_size, 0x8000ull);
+ const u64 data_alignment = m_is_triforce ? 0x20ull : 0x8000ull;
+ *data_offset = Common::AlignUp(*data_offset + entry.m_size, data_alignment);
}
}
}