diff --git a/Engine/source/core/util/zip/zipVolume.cpp b/Engine/source/core/util/zip/zipVolume.cpp index 5dcb8dee8..d56c9471e 100644 --- a/Engine/source/core/util/zip/zipVolume.cpp +++ b/Engine/source/core/util/zip/zipVolume.cpp @@ -407,8 +407,15 @@ FileNodeRef ZipFileSystem::resolve(const Path& path) if(mZipNameIsDir) { // Remove the fake root from the name so things can be found +#ifdef TORQUE_ZIP_PATH_CASE_INSENSITIVE + String lowerFakeRoot = String::ToLower(mFakeRoot); + String lowerName = String::ToLower(name); + if(lowerName.find(lowerFakeRoot) == 0) + name = name.substr(mFakeRoot.length()); +#else if(name.find(mFakeRoot) == 0) - name = name.substr(mFakeRoot.length()); + name = name.substr(mFakeRoot.length()); +#endif #ifdef TORQUE_DISABLE_FIND_ROOT_WITHIN_ZIP else @@ -480,8 +487,15 @@ FileNodeRef ZipFileSystem::resolveLoose(const Path& path) if(mZipNameIsDir) { // Remove the fake root from the name so things can be found +#ifdef TORQUE_ZIP_PATH_CASE_INSENSITIVE + String lowerFakeRoot = String::ToLower(mFakeRoot); + String lowerName = String::ToLower(name); + if(lowerName.find(lowerFakeRoot) == 0) + name = name.substr(mFakeRoot.length()); +#else if(name.find(mFakeRoot) == 0) - name = name.substr(mFakeRoot.length()); + name = name.substr(mFakeRoot.length()); +#endif #ifdef TORQUE_DISABLE_FIND_ROOT_WITHIN_ZIP else diff --git a/Engine/source/platformPOSIX/posixVolume.cpp b/Engine/source/platformPOSIX/posixVolume.cpp index 271df1e18..b8b070217 100644 --- a/Engine/source/platformPOSIX/posixVolume.cpp +++ b/Engine/source/platformPOSIX/posixVolume.cpp @@ -42,7 +42,7 @@ //#define DEBUG_SPEW - +extern void ResolvePathCaseInsensitive(char* pathName, S32 pathNameSize); namespace Torque { @@ -153,17 +153,35 @@ FileNodeRef PosixFileSystem::resolve(const Path& path) { String file = buildFileName(_volume,path); struct stat info; - if (stat(file.c_str(),&info) == 0) + +#ifdef TORQUE_POSIX_PATH_CASE_INSENSITIVE + // Resolve the case sensitive filepath + String::SizeType fileLength = file.length(); + UTF8* caseSensitivePath = new UTF8[fileLength + 1]; + dMemcpy(caseSensitivePath, file.c_str(), fileLength); + caseSensitivePath[fileLength] = 0x00; + ResolvePathCaseInsensitive(caseSensitivePath, fileLength); + + String caseSensitiveFile(caseSensitivePath); +#else + String caseSensitiveFile = file; +#endif + + FileNodeRef result = 0; + if (stat(caseSensitiveFile.c_str(),&info) == 0) { // Construct the appropriate object if (S_ISREG(info.st_mode)) - return new PosixFile(path,file); + result = new PosixFile(path,caseSensitiveFile); if (S_ISDIR(info.st_mode)) - return new PosixDirectory(path,file); + result = new PosixDirectory(path,caseSensitiveFile); } - - return 0; + +#ifdef TORQUE_POSIX_PATH_CASE_INSENSITIVE + delete[] caseSensitivePath; +#endif + return result; } FileNodeRef PosixFileSystem::create(const Path& path, FileNode::Mode mode) diff --git a/Engine/source/platformWin32/winVolume.cpp b/Engine/source/platformWin32/winVolume.cpp index af0bf96bc..5d168ac95 100644 --- a/Engine/source/platformWin32/winVolume.cpp +++ b/Engine/source/platformWin32/winVolume.cpp @@ -238,10 +238,12 @@ Win32FileSystem::~Win32FileSystem() void Win32FileSystem::verifyCompatibility(const Path& _path, WIN32_FIND_DATAW _info) { +#ifndef TORQUE_POSIX_PATH_CASE_INSENSITIVE if (_path.getFullFileName().isNotEmpty() && _path.getFullFileName().compare(String(_info.cFileName)) != 0) { Con::warnf("Linux Compatibility Warning: %s != %s", String(_info.cFileName).c_str(), _path.getFullFileName().c_str()); } +#endif } FileNodeRef Win32FileSystem::resolve(const Path& path) diff --git a/Engine/source/platformX86UNIX/x86UNIXFileio.cpp b/Engine/source/platformX86UNIX/x86UNIXFileio.cpp index eee06a84e..9669638ae 100644 --- a/Engine/source/platformX86UNIX/x86UNIXFileio.cpp +++ b/Engine/source/platformX86UNIX/x86UNIXFileio.cpp @@ -33,7 +33,7 @@ directory. Files are never created or modified in the game directory. For case-sensitivity, the MungePath code will test whether a given path - specified by the engine exists. If not, it will use the MungeCase function + specified by the engine exists. If not, it will use the ResolvePathCaseInsensitive function which will try to determine if an actual filesystem path matches the specified path case insensitive. If one is found, the actual path transparently (we hope) replaces the one requested by the engine. @@ -183,7 +183,7 @@ bool dPathCopy(const char *fromName, const char *toName, bool nooverwrite) // munge the case of the specified pathName. This means try to find the actual // filename in with case-insensitive matching on the specified pathName, and // store the actual found name. - static void MungeCase(char* pathName, S32 pathNameSize) + void ResolvePathCaseInsensitive(char* pathName, S32 pathNameSize) { char tempBuf[MaxPath]; dStrncpy(tempBuf, pathName, pathNameSize); @@ -296,7 +296,7 @@ bool dPathCopy(const char *fromName, const char *toName, bool nooverwrite) return; // otherwise munge the case of the path - MungeCase(dest, destSize); + ResolvePathCaseInsensitive(dest, destSize); } //----------------------------------------------------------------------------- @@ -1284,8 +1284,24 @@ bool dPathCopy(const char *fromName, const char *toName, bool nooverwrite) bool Platform::dumpDirectories(const char *path, Vector &directoryVector, S32 depth, bool noBasePath) { - bool retVal = recurseDumpDirectories(path, "", directoryVector, -1, depth, noBasePath); +#ifdef TORQUE_POSIX_PATH_CASE_INSENSITIVE + dsize_t pathLength = dStrlen(path); + char* caseSensitivePath = new char[pathLength + 1]; + + // Load path into temporary buffer + dMemcpy(caseSensitivePath, path, pathLength); + caseSensitivePath[pathLength] = 0x00; + ResolvePathCaseInsensitive(caseSensitivePath, pathLength); +#else + const char* caseSensitivePath = path; +#endif + + bool retVal = recurseDumpDirectories(caseSensitivePath, "", directoryVector, -1, depth, noBasePath); clearExcludedDirectories(); + +#ifdef TORQUE_POSIX_PATH_CASE_INSENSITIVE + delete[] caseSensitivePath; +#endif return retVal; } diff --git a/Tools/CMake/torque3d.cmake b/Tools/CMake/torque3d.cmake index 987a094b8..97b57260e 100644 --- a/Tools/CMake/torque3d.cmake +++ b/Tools/CMake/torque3d.cmake @@ -163,6 +163,12 @@ endif() option(TORQUE_MULTITHREAD "Multi Threading" ON) mark_as_advanced(TORQUE_MULTITHREAD) +option(TORQUE_POSIX_PATH_CASE_INSENSITIVE "POSIX Pathing Case Insensitivity" ON) +mark_as_advanced(TORQUE_POSIX_PATH_CASE_INSENSITIVE) + +option(TORQUE_ZIP_PATH_CASE_INSENSITIVE "ZIP Pathing Case Insensitivity" ON) +mark_as_advanced(TORQUE_ZIP_PATH_CASE_INSENSITIVE) + option(TORQUE_DISABLE_MEMORY_MANAGER "Disable memory manager" ON) mark_as_advanced(TORQUE_DISABLE_MEMORY_MANAGER) diff --git a/Tools/CMake/torqueConfig.h.in b/Tools/CMake/torqueConfig.h.in index 13ce58b6c..9e045b1d5 100644 --- a/Tools/CMake/torqueConfig.h.in +++ b/Tools/CMake/torqueConfig.h.in @@ -44,6 +44,12 @@ /// Define me if you want to enable Arcane FX support. #cmakedefine TORQUE_AFX_ENABLED +/// Define me if you want path case insensitivity support on POSIX systems. Does nothing on Windows. +#cmakedefine TORQUE_POSIX_PATH_CASE_INSENSITIVE + +/// Define me if you want path case insensitivity support in ZIP files. +#cmakedefine TORQUE_ZIP_PATH_CASE_INSENSITIVE + /// Define me if you want to enable multithreading support. #cmakedefine TORQUE_MULTITHREAD