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.
This commit is contained in:
parent
09c6148aba
commit
a502f069e8
|
@ -363,10 +363,7 @@ void CVolumeDirectory::BuildFST()
|
||||||
// write root entry
|
// write root entry
|
||||||
WriteEntryData(fstOffset, DIRECTORY_ENTRY, 0, 0, totalEntries);
|
WriteEntryData(fstOffset, DIRECTORY_ENTRY, 0, 0, totalEntries);
|
||||||
|
|
||||||
for (auto& entry : rootEntry.children)
|
WriteDirectory(rootEntry, fstOffset, nameOffset, curDataAddress, rootOffset);
|
||||||
{
|
|
||||||
WriteEntry(entry, fstOffset, nameOffset, curDataAddress, rootOffset);
|
|
||||||
}
|
|
||||||
|
|
||||||
// overflow check
|
// overflow check
|
||||||
_dbg_assert_(DVDINTERFACE, nameOffset == m_totalNameSize);
|
_dbg_assert_(DVDINTERFACE, nameOffset == m_totalNameSize);
|
||||||
|
@ -443,34 +440,41 @@ void CVolumeDirectory::WriteEntryName(u32& nameOffset, const std::string& name)
|
||||||
nameOffset += (u32)(name.length() + 1);
|
nameOffset += (u32)(name.length() + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CVolumeDirectory::WriteEntry(const File::FSTEntry& entry, u32& fstOffset, u32& nameOffset,
|
void CVolumeDirectory::WriteDirectory(const File::FSTEntry& parent_entry, u32& fstOffset,
|
||||||
u64& dataOffset, u32 parentEntryNum)
|
u32& nameOffset, u64& dataOffset, u32 parentEntryNum)
|
||||||
{
|
{
|
||||||
if (entry.isDirectory)
|
std::vector<File::FSTEntry> sorted_entries = parent_entry.children;
|
||||||
{
|
|
||||||
u32 myOffset = fstOffset;
|
|
||||||
u32 myEntryNum = myOffset / ENTRY_SIZE;
|
|
||||||
WriteEntryData(fstOffset, DIRECTORY_ENTRY, nameOffset, parentEntryNum,
|
|
||||||
myEntryNum + entry.size + 1);
|
|
||||||
WriteEntryName(nameOffset, entry.virtualName);
|
|
||||||
|
|
||||||
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
|
||||||
else
|
{
|
||||||
{
|
// put entry in FST
|
||||||
// put entry in FST
|
WriteEntryData(fstOffset, FILE_ENTRY, nameOffset, dataOffset, entry.size);
|
||||||
WriteEntryData(fstOffset, FILE_ENTRY, nameOffset, dataOffset, entry.size);
|
WriteEntryName(nameOffset, entry.virtualName);
|
||||||
WriteEntryName(nameOffset, entry.virtualName);
|
|
||||||
|
|
||||||
// write entry to virtual disk
|
// write entry to virtual disk
|
||||||
_dbg_assert_(DVDINTERFACE, m_virtualDisk.find(dataOffset) == m_virtualDisk.end());
|
_dbg_assert_(DVDINTERFACE, m_virtualDisk.find(dataOffset) == m_virtualDisk.end());
|
||||||
m_virtualDisk.emplace(dataOffset, entry.physicalName);
|
m_virtualDisk.emplace(dataOffset, entry.physicalName);
|
||||||
|
|
||||||
// 4 byte aligned
|
// 4 byte aligned
|
||||||
dataOffset = Common::AlignUp(dataOffset + std::max<u64>(entry.size, 1ull), 0x8000ull);
|
dataOffset = Common::AlignUp(dataOffset + std::max<u64>(entry.size, 1ull), 0x8000ull);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -85,8 +85,8 @@ private:
|
||||||
// FST creation
|
// FST creation
|
||||||
void WriteEntryData(u32& entryOffset, u8 type, u32 nameOffset, u64 dataOffset, u64 length);
|
void WriteEntryData(u32& entryOffset, u8 type, u32 nameOffset, u64 dataOffset, u64 length);
|
||||||
void WriteEntryName(u32& nameOffset, const std::string& name);
|
void WriteEntryName(u32& nameOffset, const std::string& name);
|
||||||
void WriteEntry(const File::FSTEntry& entry, u32& fstOffset, u32& nameOffset, u64& dataOffset,
|
void WriteDirectory(const File::FSTEntry& parent_entry, u32& fstOffset, u32& nameOffset,
|
||||||
u32 parentEntryNum);
|
u64& dataOffset, u32 parentEntryNum);
|
||||||
|
|
||||||
// returns number of entries found in _Directory
|
// returns number of entries found in _Directory
|
||||||
u64 AddDirectoryEntries(const std::string& _Directory, File::FSTEntry& parentEntry);
|
u64 AddDirectoryEntries(const std::string& _Directory, File::FSTEntry& parentEntry);
|
||||||
|
|
Loading…
Reference in New Issue