Implement case insensitive path resolution
This commit is contained in:
		
							parent
							
								
									f49b03ba23
								
							
						
					
					
						commit
						408864339f
					
				
					 3 changed files with 104 additions and 53 deletions
				
			
		| 
						 | 
					@ -525,32 +525,6 @@ void FileStream::close()
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void enumCB(void *, const char *origdir,
 | 
					 | 
				
			||||||
                   const char *fname)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	qDebug() << origdir << fname;
 | 
					 | 
				
			||||||
	char buf[128];
 | 
					 | 
				
			||||||
	sprintf(buf, "%s/%s", origdir, fname);
 | 
					 | 
				
			||||||
	PHYSFS_enumerateFilesCallback(buf, enumCB, 0);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
FileSystem::FileSystem(const char *argv0)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	PHYSFS_init(argv0);
 | 
					 | 
				
			||||||
	PHYSFS_registerArchiver(&RGSS_Archiver);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
FileSystem::~FileSystem()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	if (PHYSFS_deinit() == 0)
 | 
					 | 
				
			||||||
		qDebug() << "PhyFS failed to deinit.";
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void FileSystem::addPath(const char *path)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	PHYSFS_mount(path, 0, 1);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static const char *imgExt[] =
 | 
					static const char *imgExt[] =
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	"jpg",
 | 
						"jpg",
 | 
				
			||||||
| 
						 | 
					@ -583,31 +557,48 @@ struct FileExtensions
 | 
				
			||||||
	{ fonExt, ARRAY_SIZE(fonExt) }
 | 
						{ fonExt, ARRAY_SIZE(fonExt) }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const char *completeFileName(const char *filename,
 | 
					struct FileSystemPrivate
 | 
				
			||||||
                                    FileSystem::FileType type)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	static char buff[1024];
 | 
						/* All keys are lower case */
 | 
				
			||||||
 | 
						QHash<QByteArray, QByteArray> pathCache;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (PHYSFS_exists(filename))
 | 
						const char *completeFileName(const char *filename,
 | 
				
			||||||
		return filename;
 | 
						                             FileSystem::FileType type)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							char buff[512];
 | 
				
			||||||
 | 
							size_t i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							for (i = 0; i < sizeof(buff) && filename[i]; ++i)
 | 
				
			||||||
 | 
								buff[i] = tolower(filename[i]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							buff[i] = '\0';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							QByteArray key(buff);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (pathCache.contains(key))
 | 
				
			||||||
 | 
								return pathCache[key].constData();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							char buff2[512];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (type != FileSystem::Undefined)
 | 
							if (type != FileSystem::Undefined)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			FileExtensions *extTest = &fileExtensions[type];
 | 
								FileExtensions *extTest = &fileExtensions[type];
 | 
				
			||||||
			for (int i = 0; i < extTest->count; ++i)
 | 
								for (int i = 0; i < extTest->count; ++i)
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
			snprintf(buff, sizeof(buff), "%s.%s", filename, extTest->ext[i]);
 | 
									snprintf(buff2, sizeof(buff2), "%s.%s", buff, extTest->ext[i]);
 | 
				
			||||||
			if (PHYSFS_exists(buff))
 | 
					
 | 
				
			||||||
				return buff;
 | 
									key = buff2;
 | 
				
			||||||
 | 
									if (pathCache.contains(key))
 | 
				
			||||||
 | 
										return pathCache[key].constData();
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		return 0;
 | 
							return 0;
 | 
				
			||||||
}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static PHYSFS_File *openReadInt(const char *filename,
 | 
						PHYSFS_File *openReadInt(const char *filename,
 | 
				
			||||||
	                         FileSystem::FileType type)
 | 
						                         FileSystem::FileType type)
 | 
				
			||||||
{
 | 
						{
 | 
				
			||||||
		const char *foundName = completeFileName(filename, type);
 | 
							const char *foundName = completeFileName(filename, type);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (!foundName)
 | 
							if (!foundName)
 | 
				
			||||||
| 
						 | 
					@ -621,12 +612,62 @@ static PHYSFS_File *openReadInt(const char *filename,
 | 
				
			||||||
		PHYSFS_fileLength(handle);
 | 
							PHYSFS_fileLength(handle);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		return handle;
 | 
							return handle;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					FileSystem::FileSystem(const char *argv0)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						p = new FileSystemPrivate;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						PHYSFS_init(argv0);
 | 
				
			||||||
 | 
						PHYSFS_registerArchiver(&RGSS_Archiver);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					FileSystem::~FileSystem()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						delete p;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (PHYSFS_deinit() == 0)
 | 
				
			||||||
 | 
							qDebug() << "PhyFS failed to deinit.";
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void FileSystem::addPath(const char *path)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						PHYSFS_mount(path, 0, 1);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void cacheEnumCB(void *d, const char *origdir,
 | 
				
			||||||
 | 
					                        const char *fname)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						FileSystemPrivate *p = static_cast<FileSystemPrivate*>(d);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						char buf[512];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (*origdir != '.')
 | 
				
			||||||
 | 
							snprintf(buf, sizeof(buf), "%s/%s", origdir, fname);
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							strncpy(buf, fname, sizeof(buf));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						QByteArray mixedCase = buf;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						QByteArray lowerCase = mixedCase;
 | 
				
			||||||
 | 
						for (char *p = lowerCase.data(); *p; ++p)
 | 
				
			||||||
 | 
							*p = tolower(*p);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						p->pathCache.insert(lowerCase, mixedCase);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						PHYSFS_enumerateFilesCallback(mixedCase.constData(), cacheEnumCB, p);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void FileSystem::createPathCache()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						PHYSFS_enumerateFilesCallback(".", cacheEnumCB, p);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
FileStream FileSystem::openRead(const char *filename,
 | 
					FileStream FileSystem::openRead(const char *filename,
 | 
				
			||||||
                                FileType type)
 | 
					                                FileType type)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	PHYSFS_File *handle = openReadInt(filename, type);
 | 
						PHYSFS_File *handle = p->openReadInt(filename, type);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return FileStream(handle);
 | 
						return FileStream(handle);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -727,7 +768,7 @@ void FileSystem::openRead(SDL_RWops &ops,
 | 
				
			||||||
                          FileType type,
 | 
					                          FileType type,
 | 
				
			||||||
                          bool freeOnClose)
 | 
					                          bool freeOnClose)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	PHYSFS_File *handle = openReadInt(filename, type);
 | 
						PHYSFS_File *handle = p->openReadInt(filename, type);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ops.size  = SDL_RWopsSize;
 | 
						ops.size  = SDL_RWopsSize;
 | 
				
			||||||
	ops.seek  = SDL_RWopsSeek;
 | 
						ops.seek  = SDL_RWopsSeek;
 | 
				
			||||||
| 
						 | 
					@ -745,7 +786,7 @@ void FileSystem::openRead(SDL_RWops &ops,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool FileSystem::exists(const char *filename, FileType type)
 | 
					bool FileSystem::exists(const char *filename, FileType type)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	const char *foundName = completeFileName(filename, type);
 | 
						const char *foundName = p->completeFileName(filename, type);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return (foundName != 0);
 | 
						return (foundName != 0);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -49,6 +49,8 @@ private:
 | 
				
			||||||
	PHYSFS_File *p; /* NULL denotes invalid stream */
 | 
						PHYSFS_File *p; /* NULL denotes invalid stream */
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct FileSystemPrivate;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class FileSystem
 | 
					class FileSystem
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
| 
						 | 
					@ -57,6 +59,9 @@ public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void addPath(const char *path);
 | 
						void addPath(const char *path);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Call this after the last 'addPath()' */
 | 
				
			||||||
 | 
						void createPathCache();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* For extension supplementing */
 | 
						/* For extension supplementing */
 | 
				
			||||||
	enum FileType
 | 
						enum FileType
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
| 
						 | 
					@ -76,6 +81,9 @@ public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bool exists(const char *filename,
 | 
						bool exists(const char *filename,
 | 
				
			||||||
	            FileType type = Undefined);
 | 
						            FileType type = Undefined);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
						FileSystemPrivate *p;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern const Uint32 SDL_RWOPS_PHYSFS;
 | 
					extern const Uint32 SDL_RWOPS_PHYSFS;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -117,6 +117,8 @@ struct GlobalStatePrivate
 | 
				
			||||||
		for (int i = 0; i < config.rtps.count(); ++i)
 | 
							for (int i = 0; i < config.rtps.count(); ++i)
 | 
				
			||||||
			fileSystem.addPath(config.rtps[i].constData());
 | 
								fileSystem.addPath(config.rtps[i].constData());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							fileSystem.createPathCache();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		globalTexW = 128;
 | 
							globalTexW = 128;
 | 
				
			||||||
		globalTexH = 64;
 | 
							globalTexH = 64;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue