FileSystem: Make path caching optional via config

Because Windows has case insensitive paths, this should
be turned on (which it is by default) for maximum
compatibility. Can be turned off as an optimization
(this will speed up startup a little depending on the
number of game assets).
This commit is contained in:
Jonas Kulla 2014-01-01 07:07:18 +01:00
parent f163c51eed
commit ce7bf97dd4
5 changed files with 66 additions and 16 deletions

View File

@ -80,6 +80,7 @@ mkxp reads configuration data from the file "mkxp.conf" contained in the current
| solidFonts | bool | false | Don't use alpha blending for fonts | | solidFonts | bool | false | Don't use alpha blending for fonts |
| gameFolder | string | "." | mkxp will look for all game related files here | | gameFolder | string | "." | mkxp will look for all game related files here |
| allowSymlinks | bool | false | Allow symlinks to be followed in the game folder. | | allowSymlinks | bool | false | Allow symlinks to be followed in the game folder. |
| pathCache | bool | true | Scan and cache asset paths at startup. Allows for case insensitive paths. |
| customScript | string | "" | Execute a raw ruby script file instead of an RPG Maker game. | | customScript | string | "" | Execute a raw ruby script file instead of an RPG Maker game. |
| RTP | string | "" | Path to a Run Time Package to be used. Can be specified multiple times. | | RTP | string | "" | Path to a Run Time Package to be used. Can be specified multiple times. |

View File

@ -45,26 +45,28 @@ Config::Config()
frameSkip(true), frameSkip(true),
solidFonts(false), solidFonts(false),
gameFolder("."), gameFolder("."),
allowSymlinks(false) allowSymlinks(false),
pathCache(true)
{} {}
void Config::read() void Config::read()
{ {
#define PO_DESC_ALL \ #define PO_DESC_ALL \
PO_DESC(debugMode, bool) \ PO_DESC(debugMode, bool) \
PO_DESC(winResizable, bool) \ PO_DESC(winResizable, bool) \
PO_DESC(fullscreen, bool) \ PO_DESC(fullscreen, bool) \
PO_DESC(fixedAspectRatio, bool) \ PO_DESC(fixedAspectRatio, bool) \
PO_DESC(smoothScaling, bool) \ PO_DESC(smoothScaling, bool) \
PO_DESC(vsync, bool) \ PO_DESC(vsync, bool) \
PO_DESC(defScreenW, int) \ PO_DESC(defScreenW, int) \
PO_DESC(defScreenH, int) \ PO_DESC(defScreenH, int) \
PO_DESC(fixedFramerate, int) \ PO_DESC(fixedFramerate, int) \
PO_DESC(frameSkip, bool) \ PO_DESC(frameSkip, bool) \
PO_DESC(solidFonts, bool) \ PO_DESC(solidFonts, bool) \
PO_DESC(gameFolder, std::string) \ PO_DESC(gameFolder, std::string) \
PO_DESC(allowSymlinks, bool) \ PO_DESC(allowSymlinks, bool) \
PO_DESC(customScript, std::string) PO_DESC(customScript, std::string) \
PO_DESC(pathCache, bool)
#define PO_DESC(key, type) (#key, po::value< type >()->default_value(key)) #define PO_DESC(key, type) (#key, po::value< type >()->default_value(key))

View File

@ -45,6 +45,7 @@ struct Config
std::string gameFolder; std::string gameFolder;
bool allowSymlinks; bool allowSymlinks;
bool pathCache;
std::string customScript; std::string customScript;
std::vector<std::string> rtps; std::vector<std::string> rtps;

View File

@ -498,7 +498,11 @@ struct FileSystemPrivate
/* All keys are lower case */ /* All keys are lower case */
BoostHash<std::string, std::string> pathCache; BoostHash<std::string, std::string> pathCache;
std::vector<std::string> extensions[FileSystem::Undefined]; std::vector<std::string> extensions[FileSystem::Undefined+1];
// FIXME Need to find a better way to do this..
char pathBuffer[512];
bool havePathCache;
/* Attempt to locate an extension string in a filename. /* Attempt to locate an extension string in a filename.
* Either a pointer into the input string pointing at the * Either a pointer into the input string pointing at the
@ -523,6 +527,39 @@ struct FileSystemPrivate
FileSystem::FileType type, FileSystem::FileType type,
const char **foundExt) const char **foundExt)
{ {
if (!havePathCache)
{
if (PHYSFS_exists(filename))
{
if (foundExt)
*foundExt = findExt(filename);
return filename;
}
const std::vector<std::string> &extList = extensions[type];
for (size_t i = 0; i < extList.size(); ++i)
{
const char *ext = extList[i].c_str();
snprintf(pathBuffer, sizeof(pathBuffer), "%s.%s", filename, ext);
if (PHYSFS_exists(pathBuffer))
{
if (foundExt)
*foundExt = ext;
return pathBuffer;
}
}
// Is this even necessary?
if (foundExt)
*foundExt = 0;
return 0;
}
char buff[512]; char buff[512];
size_t i; size_t i;
@ -533,6 +570,8 @@ struct FileSystemPrivate
std::string key(buff); std::string key(buff);
/* If the path was already complete,
* we are done at this point */
if (pathCache.contains(key)) if (pathCache.contains(key))
{ {
/* The extension might already be included here, /* The extension might already be included here,
@ -545,6 +584,8 @@ struct FileSystemPrivate
char buff2[512]; char buff2[512];
/* Try supplementing extensions
* to find an existing path */
if (type != FileSystem::Undefined) if (type != FileSystem::Undefined)
{ {
std::vector<std::string> &extList = extensions[type]; std::vector<std::string> &extList = extensions[type];
@ -594,6 +635,8 @@ FileSystem::FileSystem(const char *argv0,
{ {
p = new FileSystemPrivate; p = new FileSystemPrivate;
p->havePathCache = false;
/* Image extensions */ /* Image extensions */
p->extensions[Image].push_back("jpg"); p->extensions[Image].push_back("jpg");
p->extensions[Image].push_back("png"); p->extensions[Image].push_back("png");
@ -671,6 +714,8 @@ static void cacheEnumCB(void *d, const char *origdir,
void FileSystem::createPathCache() void FileSystem::createPathCache()
{ {
PHYSFS_enumerateFilesCallback(".", cacheEnumCB, p); PHYSFS_enumerateFilesCallback(".", cacheEnumCB, p);
p->havePathCache = true;
} }
static inline PHYSFS_File *sdlPHYS(SDL_RWops *ops) static inline PHYSFS_File *sdlPHYS(SDL_RWops *ops)

View File

@ -118,7 +118,8 @@ struct SharedStatePrivate
for (size_t i = 0; i < config.rtps.size(); ++i) for (size_t i = 0; i < config.rtps.size(); ++i)
fileSystem.addPath(config.rtps[i].c_str()); fileSystem.addPath(config.rtps[i].c_str());
fileSystem.createPathCache(); if (config.pathCache)
fileSystem.createPathCache();
globalTexW = 128; globalTexW = 128;
globalTexH = 64; globalTexH = 64;