From ce7bf97dd498d1b1fd6acc4d9e995c50170d9c4a Mon Sep 17 00:00:00 2001 From: Jonas Kulla Date: Wed, 1 Jan 2014 07:07:18 +0100 Subject: [PATCH] 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). --- README.md | 1 + src/config.cpp | 30 +++++++++++++++-------------- src/config.h | 1 + src/filesystem.cpp | 47 ++++++++++++++++++++++++++++++++++++++++++++- src/sharedstate.cpp | 3 ++- 5 files changed, 66 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index f82add6..c2cfa83 100644 --- a/README.md +++ b/README.md @@ -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 | | gameFolder | string | "." | mkxp will look for all game related files here | | 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. | | RTP | string | "" | Path to a Run Time Package to be used. Can be specified multiple times. | diff --git a/src/config.cpp b/src/config.cpp index 1775a55..e5c502d 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -45,26 +45,28 @@ Config::Config() frameSkip(true), solidFonts(false), gameFolder("."), - allowSymlinks(false) + allowSymlinks(false), + pathCache(true) {} void Config::read() { #define PO_DESC_ALL \ PO_DESC(debugMode, bool) \ - PO_DESC(winResizable, bool) \ - PO_DESC(fullscreen, bool) \ - PO_DESC(fixedAspectRatio, bool) \ - PO_DESC(smoothScaling, bool) \ - PO_DESC(vsync, bool) \ - PO_DESC(defScreenW, int) \ - PO_DESC(defScreenH, int) \ - PO_DESC(fixedFramerate, int) \ - PO_DESC(frameSkip, bool) \ - PO_DESC(solidFonts, bool) \ - PO_DESC(gameFolder, std::string) \ - PO_DESC(allowSymlinks, bool) \ - PO_DESC(customScript, std::string) + PO_DESC(winResizable, bool) \ + PO_DESC(fullscreen, bool) \ + PO_DESC(fixedAspectRatio, bool) \ + PO_DESC(smoothScaling, bool) \ + PO_DESC(vsync, bool) \ + PO_DESC(defScreenW, int) \ + PO_DESC(defScreenH, int) \ + PO_DESC(fixedFramerate, int) \ + PO_DESC(frameSkip, bool) \ + PO_DESC(solidFonts, bool) \ + PO_DESC(gameFolder, std::string) \ + PO_DESC(allowSymlinks, bool) \ + PO_DESC(customScript, std::string) \ + PO_DESC(pathCache, bool) #define PO_DESC(key, type) (#key, po::value< type >()->default_value(key)) diff --git a/src/config.h b/src/config.h index a01dac9..4192ef5 100644 --- a/src/config.h +++ b/src/config.h @@ -45,6 +45,7 @@ struct Config std::string gameFolder; bool allowSymlinks; + bool pathCache; std::string customScript; std::vector rtps; diff --git a/src/filesystem.cpp b/src/filesystem.cpp index dab78a3..cb59bcd 100644 --- a/src/filesystem.cpp +++ b/src/filesystem.cpp @@ -498,7 +498,11 @@ struct FileSystemPrivate /* All keys are lower case */ BoostHash pathCache; - std::vector extensions[FileSystem::Undefined]; + std::vector 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. * Either a pointer into the input string pointing at the @@ -523,6 +527,39 @@ struct FileSystemPrivate FileSystem::FileType type, const char **foundExt) { + if (!havePathCache) + { + if (PHYSFS_exists(filename)) + { + if (foundExt) + *foundExt = findExt(filename); + + return filename; + } + + const std::vector &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]; size_t i; @@ -533,6 +570,8 @@ struct FileSystemPrivate std::string key(buff); + /* If the path was already complete, + * we are done at this point */ if (pathCache.contains(key)) { /* The extension might already be included here, @@ -545,6 +584,8 @@ struct FileSystemPrivate char buff2[512]; + /* Try supplementing extensions + * to find an existing path */ if (type != FileSystem::Undefined) { std::vector &extList = extensions[type]; @@ -594,6 +635,8 @@ FileSystem::FileSystem(const char *argv0, { p = new FileSystemPrivate; + p->havePathCache = false; + /* Image extensions */ p->extensions[Image].push_back("jpg"); p->extensions[Image].push_back("png"); @@ -671,6 +714,8 @@ static void cacheEnumCB(void *d, const char *origdir, void FileSystem::createPathCache() { PHYSFS_enumerateFilesCallback(".", cacheEnumCB, p); + + p->havePathCache = true; } static inline PHYSFS_File *sdlPHYS(SDL_RWops *ops) diff --git a/src/sharedstate.cpp b/src/sharedstate.cpp index 84d0c24..7d0b587 100644 --- a/src/sharedstate.cpp +++ b/src/sharedstate.cpp @@ -118,7 +118,8 @@ struct SharedStatePrivate for (size_t i = 0; i < config.rtps.size(); ++i) fileSystem.addPath(config.rtps[i].c_str()); - fileSystem.createPathCache(); + if (config.pathCache) + fileSystem.createPathCache(); globalTexW = 128; globalTexH = 64;