@@ -350,6 +350,32 @@ void GSTextureReplacements::GameChanged()
350350 ClearDumpedTextureList ();
351351}
352352
353+ // / If the given file exists in the given directory, but with a different case than the original file, return its on-disk path.
354+ static bool GetWrongCasePath (std::string* output, const char * dir, std::string_view file, FileSystem::FindResultsArray* reuseme)
355+ {
356+ if (FileSystem::FindFiles (dir, " *" , FILESYSTEM_FIND_FOLDERS | FILESYSTEM_FIND_HIDDEN_FILES, reuseme))
357+ {
358+ bool case_matches = false ;
359+ const FILESYSTEM_FIND_DATA* found = nullptr ;
360+ for (const FILESYSTEM_FIND_DATA& fd : *reuseme)
361+ {
362+ std::string_view name = Path::GetFileName (fd.FileName );
363+ if (name.size () != file.size ())
364+ continue ;
365+ if (0 == strncmp (name.data (), file.data (), name.size ()))
366+ case_matches = true ;
367+ else if (0 == StringUtil::Strncasecmp (name.data (), file.data (), name.size ()))
368+ found = &fd;
369+ }
370+ if (!case_matches && found)
371+ {
372+ *output = found->FileName ;
373+ return true ;
374+ }
375+ }
376+ return false ;
377+ }
378+
353379void GSTextureReplacements::ReloadReplacementMap ()
354380{
355381 SyncWorkerThread ();
@@ -369,9 +395,27 @@ void GSTextureReplacements::ReloadReplacementMap()
369395 if (s_current_serial.empty () || !GSConfig.LoadTextureReplacements )
370396 return ;
371397
372- const std::string replacement_dir (Path::Combine (GetGameTextureDirectory (), TEXTURE_REPLACEMENT_SUBDIRECTORY_NAME));
398+ const std::string texture_dir = GetGameTextureDirectory ();
399+ const std::string replacement_dir (Path::Combine (texture_dir, TEXTURE_REPLACEMENT_SUBDIRECTORY_NAME));
373400
374401 FileSystem::FindResultsArray files;
402+
403+ // For some reason texture pack authors think it's a good idea to rename the replacements directory to something with the wrong case...
404+ std::string wrong_case_path;
405+ const std::string* right_case_path = nullptr ;
406+ if (GetWrongCasePath (&wrong_case_path, EmuFolders::Textures.c_str (), s_current_serial, &files))
407+ right_case_path = &texture_dir;
408+ else if (GetWrongCasePath (&wrong_case_path, texture_dir.c_str (), TEXTURE_REPLACEMENT_SUBDIRECTORY_NAME, &files))
409+ right_case_path = &replacement_dir;
410+ if (right_case_path)
411+ {
412+ Host::AddKeyedOSDMessage (" TextureReplacementDirCaseMismatch" ,
413+ fmt::format (TRANSLATE_FS (" TextureReplacement" , " Texture replacement directory {} will not work on case sensitive filesystems.\n "
414+ " Rename it to {} to remove this warning." ),
415+ wrong_case_path, *right_case_path),
416+ Host::OSD_WARNING_DURATION);
417+ }
418+
375419 if (!FileSystem::FindFiles (replacement_dir.c_str (), " *" , FILESYSTEM_FIND_FILES | FILESYSTEM_FIND_HIDDEN_FILES | FILESYSTEM_FIND_RECURSIVE, &files))
376420 return ;
377421
0 commit comments