diff options
| author | JosJuice <josjuice@gmail.com> | 2017-01-24 18:18:26 +0100 |
|---|---|---|
| committer | JosJuice <josjuice@gmail.com> | 2017-01-25 15:07:07 +0100 |
| commit | 104faa9fb3f9416e7e18d66bab10122a1e0ad0ad (patch) | |
| tree | 688aa3efee014056bdb2cb5aa9b57d6be06ee28c /Source/Core/DiscIO/VolumeDirectory.cpp | |
| parent | 90ee85f4e83ba26ddb9dadd57f72f93405a56ca4 (diff) | |
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.)
Diffstat (limited to 'Source/Core/DiscIO/VolumeDirectory.cpp')
| -rw-r--r-- | Source/Core/DiscIO/VolumeDirectory.cpp | 23 |
1 files changed, 19 insertions, 4 deletions
diff --git a/Source/Core/DiscIO/VolumeDirectory.cpp b/Source/Core/DiscIO/VolumeDirectory.cpp index 40dda01d0d..9f93aa0331 100644 --- a/Source/Core/DiscIO/VolumeDirectory.cpp +++ b/Source/Core/DiscIO/VolumeDirectory.cpp @@ -5,6 +5,7 @@ #include <algorithm> #include <cstddef> #include <cstring> +#include <locale> #include <map> #include <memory> #include <string> @@ -25,6 +26,7 @@ namespace DiscIO { 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_ID_LENGTH; @@ -452,10 +454,16 @@ void CVolumeDirectory::WriteDirectory(const File::FSTEntry& parent_entry, u32* f { std::vector<File::FSTEntry> sorted_entries = parent_entry.children; - std::sort(sorted_entries.begin(), sorted_entries.end(), - [](const File::FSTEntry& one, const File::FSTEntry& two) { - return one.virtualName < two.virtualName; - }); + // Sort for determinism + std::sort(sorted_entries.begin(), sorted_entries.end(), [](const File::FSTEntry& one, + 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) { @@ -497,4 +505,11 @@ static u32 ComputeNameSize(const File::FSTEntry& parent_entry) 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 |
