VolumeDirectory: Use case-insensitive comparison when sorting

This fixes a regression from 5.0-1556, but I don't know why
the regression occurred or why this fixes it. (Many games
failed to fully boot - I tried Metroid Prime and Twilight
Princess (both GC), and they never got to the title screen.)
This commit is contained in:
JosJuice 2017-01-24 18:18:26 +01:00
parent 90ee85f4e8
commit 104faa9fb3
1 changed files with 19 additions and 4 deletions

View File

@ -5,6 +5,7 @@
#include <algorithm> #include <algorithm>
#include <cstddef> #include <cstddef>
#include <cstring> #include <cstring>
#include <locale>
#include <map> #include <map>
#include <memory> #include <memory>
#include <string> #include <string>
@ -25,6 +26,7 @@
namespace DiscIO namespace DiscIO
{ {
static u32 ComputeNameSize(const File::FSTEntry& parent_entry); static u32 ComputeNameSize(const File::FSTEntry& parent_entry);
static std::string ASCIIToLowercase(std::string str);
const size_t CVolumeDirectory::MAX_NAME_LENGTH; const size_t CVolumeDirectory::MAX_NAME_LENGTH;
const size_t CVolumeDirectory::MAX_ID_LENGTH; const size_t CVolumeDirectory::MAX_ID_LENGTH;
@ -452,9 +454,15 @@ void CVolumeDirectory::WriteDirectory(const File::FSTEntry& parent_entry, u32* f
{ {
std::vector<File::FSTEntry> sorted_entries = parent_entry.children; std::vector<File::FSTEntry> sorted_entries = parent_entry.children;
std::sort(sorted_entries.begin(), sorted_entries.end(), // Sort for determinism
[](const File::FSTEntry& one, const File::FSTEntry& two) { std::sort(sorted_entries.begin(), sorted_entries.end(), [](const File::FSTEntry& one,
return one.virtualName < two.virtualName; const File::FSTEntry& two) {
// For some reason, sorting by lowest ASCII value first prevents many games from
// fully booting. We make the comparison case insensitive to solve the problem.
// (Highest ASCII value first seems to work regardless of case sensitivity.)
const std::string one_lower = ASCIIToLowercase(one.virtualName);
const std::string two_lower = ASCIIToLowercase(two.virtualName);
return one_lower == two_lower ? one.virtualName < two.virtualName : one_lower < two_lower;
}); });
for (const File::FSTEntry& entry : sorted_entries) for (const File::FSTEntry& entry : sorted_entries)
@ -497,4 +505,11 @@ static u32 ComputeNameSize(const File::FSTEntry& parent_entry)
return name_size; return name_size;
} }
static std::string ASCIIToLowercase(std::string str)
{
std::transform(str.begin(), str.end(), str.begin(),
[](char c) { return std::tolower(c, std::locale::classic()); });
return str;
}
} // namespace } // namespace