Skip to content

Commit 39f8c19

Browse files
committed
GS: Warn on texture replacement folder with wrong case
1 parent 1f3c8f7 commit 39f8c19

1 file changed

Lines changed: 45 additions & 1 deletion

File tree

pcsx2/GS/Renderers/HW/GSTextureReplacements.cpp

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -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+
353379
void 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

Comments
 (0)