Implement case insensitive path resolution
This commit is contained in:
parent
f49b03ba23
commit
408864339f
|
@ -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,50 +557,117 @@ 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)
|
||||||
|
|
||||||
if (type != FileSystem::Undefined)
|
|
||||||
{
|
{
|
||||||
FileExtensions *extTest = &fileExtensions[type];
|
char buff[512];
|
||||||
for (int i = 0; i < extTest->count; ++i)
|
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)
|
||||||
{
|
{
|
||||||
snprintf(buff, sizeof(buff), "%s.%s", filename, extTest->ext[i]);
|
FileExtensions *extTest = &fileExtensions[type];
|
||||||
if (PHYSFS_exists(buff))
|
for (int i = 0; i < extTest->count; ++i)
|
||||||
return buff;
|
{
|
||||||
|
snprintf(buff2, sizeof(buff2), "%s.%s", buff, extTest->ext[i]);
|
||||||
|
|
||||||
|
key = buff2;
|
||||||
|
if (pathCache.contains(key))
|
||||||
|
return pathCache[key].constData();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
PHYSFS_File *openReadInt(const char *filename,
|
||||||
|
FileSystem::FileType type)
|
||||||
|
{
|
||||||
|
const char *foundName = completeFileName(filename, type);
|
||||||
|
|
||||||
|
if (!foundName)
|
||||||
|
throw Exception(Exception::NoFileError,
|
||||||
|
"No such file or directory - %s", filename);
|
||||||
|
|
||||||
|
PHYSFS_File *handle = PHYSFS_openRead(foundName);
|
||||||
|
if (!handle)
|
||||||
|
throw Exception(Exception::PHYSFSError, "PhysFS: %s", PHYSFS_getLastError());
|
||||||
|
|
||||||
|
PHYSFS_fileLength(handle);
|
||||||
|
|
||||||
|
return handle;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
FileSystem::FileSystem(const char *argv0)
|
||||||
|
{
|
||||||
|
p = new FileSystemPrivate;
|
||||||
|
|
||||||
|
PHYSFS_init(argv0);
|
||||||
|
PHYSFS_registerArchiver(&RGSS_Archiver);
|
||||||
}
|
}
|
||||||
|
|
||||||
static PHYSFS_File *openReadInt(const char *filename,
|
FileSystem::~FileSystem()
|
||||||
FileSystem::FileType type)
|
|
||||||
{
|
{
|
||||||
const char *foundName = completeFileName(filename, type);
|
delete p;
|
||||||
|
|
||||||
if (!foundName)
|
if (PHYSFS_deinit() == 0)
|
||||||
throw Exception(Exception::NoFileError,
|
qDebug() << "PhyFS failed to deinit.";
|
||||||
"No such file or directory - %s", filename);
|
}
|
||||||
|
|
||||||
PHYSFS_File *handle = PHYSFS_openRead(foundName);
|
void FileSystem::addPath(const char *path)
|
||||||
if (!handle)
|
{
|
||||||
throw Exception(Exception::PHYSFSError, "PhysFS: %s", PHYSFS_getLastError());
|
PHYSFS_mount(path, 0, 1);
|
||||||
|
}
|
||||||
|
|
||||||
PHYSFS_fileLength(handle);
|
static void cacheEnumCB(void *d, const char *origdir,
|
||||||
|
const char *fname)
|
||||||
|
{
|
||||||
|
FileSystemPrivate *p = static_cast<FileSystemPrivate*>(d);
|
||||||
|
|
||||||
return handle;
|
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…
Reference in New Issue