diff --git a/Source/Core/DiscIO/DirectoryBlob.cpp b/Source/Core/DiscIO/DirectoryBlob.cpp index b2fadeb814..332510efca 100644 --- a/Source/Core/DiscIO/DirectoryBlob.cpp +++ b/Source/Core/DiscIO/DirectoryBlob.cpp @@ -895,7 +895,8 @@ DirectoryBlobPartition::DirectoryBlobPartition( const std::function* 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 sys_nodes; @@ -1230,6 +1231,14 @@ void DirectoryBlobPartition::WriteDirectory(std::vector* 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* 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); } } } diff --git a/Source/Core/DiscIO/DirectoryBlob.h b/Source/Core/DiscIO/DirectoryBlob.h index a8add132d6..f0527cee9b 100644 --- a/Source/Core/DiscIO/DirectoryBlob.h +++ b/Source/Core/DiscIO/DirectoryBlob.h @@ -231,6 +231,7 @@ private: std::string m_root_directory; bool m_is_wii = false; + bool m_is_triforce = false; // GameCube has no shift, Wii has 2 bit shift u32 m_address_shift = 0;