summaryrefslogtreecommitdiff
path: root/Source/Core/DiscIO/RiivolutionPatcher.cpp
diff options
context:
space:
mode:
authorAdmiral H. Curtiss <pikachu025@gmail.com>2023-01-15 05:39:03 +0100
committerAdmiral H. Curtiss <pikachu025@gmail.com>2023-02-28 00:56:34 +0100
commita0974c18cd4a445940c737bf52904db3fc56c39e (patch)
tree1a5fd580e407584646c65e3ca577cc0f219342fc /Source/Core/DiscIO/RiivolutionPatcher.cpp
parentbdb19085c47cdfeb2051020cb5564c6ecd9605c5 (diff)
RiivolutionPatcher: Use capitalization of file that exists in the host file system if possible.
Fixes https://bugs.dolphin-emu.org/issues/13138
Diffstat (limited to 'Source/Core/DiscIO/RiivolutionPatcher.cpp')
-rw-r--r--Source/Core/DiscIO/RiivolutionPatcher.cpp30
1 files changed, 29 insertions, 1 deletions
diff --git a/Source/Core/DiscIO/RiivolutionPatcher.cpp b/Source/Core/DiscIO/RiivolutionPatcher.cpp
index f12664710d..0f9bbec3ca 100644
--- a/Source/Core/DiscIO/RiivolutionPatcher.cpp
+++ b/Source/Core/DiscIO/RiivolutionPatcher.cpp
@@ -64,7 +64,8 @@ FileDataLoaderHostFS::MakeAbsoluteFromRelative(std::string_view external_relativ
return std::nullopt;
#endif
- std::string result = external_relative_path.starts_with('/') ? m_sd_root : m_patch_root;
+ const std::string& root = external_relative_path.starts_with('/') ? m_sd_root : m_patch_root;
+ std::string result = root;
std::string_view work = external_relative_path;
// Strip away all leading and trailing path separators.
@@ -116,6 +117,33 @@ FileDataLoaderHostFS::MakeAbsoluteFromRelative(std::string_view external_relativ
// Append path element to result string.
result += '/';
result += element;
+
+ // Riivolution assumes a case-insensitive file system, which means it's possible that an XML
+ // file references a 'file.bin' but the actual file is named 'File.bin' or 'FILE.BIN'. To
+ // preserve this behavior, we modify the file path to match any existing file in the file
+ // system, if one exists.
+ if (!::File::Exists(result))
+ {
+ // Drop path element again so we can search in the directory.
+ result.erase(result.size() - element.size(), element.size());
+
+ // Re-attach an element that actually matches the capitalization in the host filesystem.
+ auto possible_files = ::File::ScanDirectoryTree(result, false);
+ bool found = false;
+ for (auto& f : possible_files.children)
+ {
+ if (Common::CaseInsensitiveEquals(element, f.virtualName))
+ {
+ result += f.virtualName;
+ found = true;
+ break;
+ }
+ }
+
+ // If there isn't any file that matches just use the given element.
+ if (!found)
+ result += element;
+ }
}
// If this was the last path element, we're done.