summaryrefslogtreecommitdiff
path: root/Source/Core/DiscIO/VolumeDirectory.cpp
diff options
context:
space:
mode:
authorJosJuice <josjuice@gmail.com>2016-12-25 22:35:38 +0100
committerJosJuice <josjuice@gmail.com>2016-12-25 22:35:38 +0100
commita502f069e8228fb0b63db44ffccc4b2e13201418 (patch)
treec6df49ead6942166ad5fabc7805da7498b8cb52b /Source/Core/DiscIO/VolumeDirectory.cpp
parent09c6148abaaad47bec90ffa8c43b9fff28db2bfd (diff)
VolumeDirectory: Sort the FST
We can't rely on the OS returning files and directories in a deterministic order, so we should sort them on our own if we want VolumeDirectory to work for movies and netplay.
Diffstat (limited to 'Source/Core/DiscIO/VolumeDirectory.cpp')
-rw-r--r--Source/Core/DiscIO/VolumeDirectory.cpp56
1 files changed, 30 insertions, 26 deletions
diff --git a/Source/Core/DiscIO/VolumeDirectory.cpp b/Source/Core/DiscIO/VolumeDirectory.cpp
index 1d58f76052..60bb9f40f0 100644
--- a/Source/Core/DiscIO/VolumeDirectory.cpp
+++ b/Source/Core/DiscIO/VolumeDirectory.cpp
@@ -363,10 +363,7 @@ void CVolumeDirectory::BuildFST()
// write root entry
WriteEntryData(fstOffset, DIRECTORY_ENTRY, 0, 0, totalEntries);
- for (auto& entry : rootEntry.children)
- {
- WriteEntry(entry, fstOffset, nameOffset, curDataAddress, rootOffset);
- }
+ WriteDirectory(rootEntry, fstOffset, nameOffset, curDataAddress, rootOffset);
// overflow check
_dbg_assert_(DVDINTERFACE, nameOffset == m_totalNameSize);
@@ -443,34 +440,41 @@ void CVolumeDirectory::WriteEntryName(u32& nameOffset, const std::string& name)
nameOffset += (u32)(name.length() + 1);
}
-void CVolumeDirectory::WriteEntry(const File::FSTEntry& entry, u32& fstOffset, u32& nameOffset,
- u64& dataOffset, u32 parentEntryNum)
+void CVolumeDirectory::WriteDirectory(const File::FSTEntry& parent_entry, u32& fstOffset,
+ u32& nameOffset, u64& dataOffset, u32 parentEntryNum)
{
- if (entry.isDirectory)
- {
- u32 myOffset = fstOffset;
- u32 myEntryNum = myOffset / ENTRY_SIZE;
- WriteEntryData(fstOffset, DIRECTORY_ENTRY, nameOffset, parentEntryNum,
- myEntryNum + entry.size + 1);
- WriteEntryName(nameOffset, entry.virtualName);
+ std::vector<File::FSTEntry> sorted_entries = parent_entry.children;
- for (const auto& child : entry.children)
+ std::sort(sorted_entries.begin(), sorted_entries.end(),
+ [](const File::FSTEntry& one, const File::FSTEntry& two) {
+ return one.virtualName < two.virtualName;
+ });
+
+ for (const File::FSTEntry& entry : sorted_entries)
+ {
+ if (entry.isDirectory)
{
- WriteEntry(child, fstOffset, nameOffset, dataOffset, myEntryNum);
+ u32 myOffset = fstOffset;
+ u32 myEntryNum = myOffset / ENTRY_SIZE;
+ WriteEntryData(fstOffset, DIRECTORY_ENTRY, nameOffset, parentEntryNum,
+ myEntryNum + entry.size + 1);
+ WriteEntryName(nameOffset, entry.virtualName);
+
+ WriteDirectory(entry, fstOffset, nameOffset, dataOffset, myEntryNum);
}
- }
- else
- {
- // put entry in FST
- WriteEntryData(fstOffset, FILE_ENTRY, nameOffset, dataOffset, entry.size);
- WriteEntryName(nameOffset, entry.virtualName);
+ else
+ {
+ // put entry in FST
+ WriteEntryData(fstOffset, FILE_ENTRY, nameOffset, dataOffset, entry.size);
+ WriteEntryName(nameOffset, entry.virtualName);
- // write entry to virtual disk
- _dbg_assert_(DVDINTERFACE, m_virtualDisk.find(dataOffset) == m_virtualDisk.end());
- m_virtualDisk.emplace(dataOffset, entry.physicalName);
+ // write entry to virtual disk
+ _dbg_assert_(DVDINTERFACE, m_virtualDisk.find(dataOffset) == m_virtualDisk.end());
+ m_virtualDisk.emplace(dataOffset, entry.physicalName);
- // 4 byte aligned
- dataOffset = Common::AlignUp(dataOffset + std::max<u64>(entry.size, 1ull), 0x8000ull);
+ // 4 byte aligned
+ dataOffset = Common::AlignUp(dataOffset + std::max<u64>(entry.size, 1ull), 0x8000ull);
+ }
}
}