From 2e3331a0c080639bd03fb0b1a360307452e59680 Mon Sep 17 00:00:00 2001 From: "wagic.the.homebrew" Date: Tue, 13 Dec 2011 15:14:47 +0000 Subject: [PATCH] - Speed improvements to the filesystem (partial fix for issue 767) - minor speed improvement in the shop (removed a locked texture loading that wasn't necessary) --- JGE/include/JFileSystem.h | 5 +-- JGE/src/JFileSystem.cpp | 34 ++++++++++++-------- JGE/src/zipFS/zfsystem.cpp | 48 ++++++++++++++++++++-------- JGE/src/zipFS/zfsystem.h | 14 +++++++- projects/mtg/include/GameStateShop.h | 1 - projects/mtg/src/GameStateMenu.cpp | 1 - projects/mtg/src/GameStateShop.cpp | 19 ----------- 7 files changed, 70 insertions(+), 52 deletions(-) diff --git a/JGE/include/JFileSystem.h b/JGE/include/JFileSystem.h index 1b85889ab..9efa7cd39 100644 --- a/JGE/include/JFileSystem.h +++ b/JGE/include/JFileSystem.h @@ -23,7 +23,7 @@ class JZipCache { public: JZipCache(); ~JZipCache(); - map dir; + map dir; }; @@ -35,13 +35,14 @@ private: izfstream mFile; mapmZipCache; + unsigned int mZipCachedElementsCount; string mZipFileName; int mFileSize; char *mPassword; bool mZipAvailable; void preloadZip(const string& filename); izfstream mZipFile; - filesystem::file_info * mCurrentFileInZip; + filesystem::limited_file_info * mCurrentFileInZip; std::vector& scanRealFolder(const std::string& folderName, std::vector& results); diff --git a/JGE/src/JFileSystem.cpp b/JGE/src/JFileSystem.cpp index 117c0dc05..9e88baeda 100644 --- a/JGE/src/JFileSystem.cpp +++ b/JGE/src/JFileSystem.cpp @@ -46,6 +46,14 @@ void JFileSystem::preloadZip(const string& filename) map::iterator it = mZipCache.find(filename); if (it != mZipCache.end()) return; + //random number of files stored in the cache. + // This is based on the idea that an average filepath (in Wagic) for image is 37 characters (=bytes) + 8 bytes to store the fileinfo = 45 bytes, + //so 4500 files represent roughly 200kB, an "ok" size for the PSP + if (mZipCachedElementsCount > 4500) + { + clearZipCache(); + } + JZipCache * cache = new JZipCache(); mZipCache[filename] = cache; @@ -54,7 +62,11 @@ void JFileSystem::preloadZip(const string& filename) if (!mZipAvailable || !mZipFile) return; } - if (! (mUserFS->PreloadZip(filename.c_str(), cache->dir) || (mSystemFS && mSystemFS->PreloadZip(filename.c_str(), cache->dir)))) + if ((mUserFS->PreloadZip(filename.c_str(), cache->dir) || (mSystemFS && mSystemFS->PreloadZip(filename.c_str(), cache->dir)))) + { + mZipCachedElementsCount+= cache->dir.size(); + } + else { DetachZipFile(); } @@ -155,6 +167,7 @@ JFileSystem::JFileSystem(const string & _userPath, const string & _systemPath) mSystemFS = (mSystemFSPath.size() && (mSystemFSPath.compare(mUserFSPath) != 0)) ? new filesystem(systemPath.c_str()) : NULL; mZipAvailable = false; + mZipCachedElementsCount = 0; mPassword = NULL; mFileSize = 0; mCurrentFileInZip = NULL; @@ -171,20 +184,12 @@ void JFileSystem::Destroy() bool JFileSystem::DirExists(const string& strDirname) { - return mUserFS->DirExists(strDirname) || (mSystemFS && mSystemFS->DirExists(strDirname)); + return (mSystemFS && mSystemFS->DirExists(strDirname)) || mUserFS->DirExists(strDirname); } bool JFileSystem::FileExists(const string& strFilename) { - bool result = false; - if(strFilename != "") - { - izfstream temp; - result = openForRead(temp, strFilename); - if (temp) - temp.close(); - } - return result; + return (mSystemFS && mSystemFS->FileExists(strFilename)) || mUserFS->FileExists(strFilename); } bool JFileSystem::MakeDir(const string & dir) @@ -210,7 +215,8 @@ void JFileSystem::clearZipCache() for (it = mZipCache.begin(); it != mZipCache.end(); ++it){ delete(it->second); } - mZipCache.clear(); + mZipCache.clear(); + mZipCachedElementsCount = 0; } bool JFileSystem::AttachZipFile(const string &zipfile, char *password /* = NULL */) @@ -318,7 +324,7 @@ bool JFileSystem::OpenFile(const string &filename) return openForRead(mFile, filename); } JZipCache * zc = it->second; - map::iterator it2 = zc->dir.find(filename); + map::iterator it2 = zc->dir.find(filename); if (it2 == zc->dir.end()) { /*DetachZipFile(); @@ -350,7 +356,7 @@ int JFileSystem::ReadFile(void *buffer, int size) if (mCurrentFileInZip) { assert(mZipFile); - if((size_t)size > mCurrentFileInZip->m_CompSize) //only support "store" method for zip inside zips + if((size_t)size > mCurrentFileInZip->m_Size) //only support "store" method for zip inside zips return 0; std::streamoff offset = filesystem::SkipLFHdr(mZipFile, mCurrentFileInZip->m_Offset); if (!mZipFile.seekg(offset)) diff --git a/JGE/src/zipFS/zfsystem.cpp b/JGE/src/zipFS/zfsystem.cpp index 9610d564d..5367ae652 100644 --- a/JGE/src/zipFS/zfsystem.cpp +++ b/JGE/src/zipFS/zfsystem.cpp @@ -172,6 +172,13 @@ void filesystem::Open(izfstream & File, const char * Filename) bool filesystem::DirExists(const std::string & folderName) { + //Check in zip + file_info FileInfo; + + // Check whether the file is zipped, whether the file is a directory and try to open. + if (FindFile(folderName.c_str(), &FileInfo) && (FileInfo.m_Directory)) + return true; + //check real folder string FullPath = m_BasePath + folderName; @@ -186,17 +193,38 @@ bool filesystem::DirExists(const std::string & folderName) return true; #endif + //Neither in real folder nor in zip + return false; +} + +bool filesystem::FileExists(const std::string & fileName) +{ + //Check in zip file_info FileInfo; // Check whether the file is zipped, whether the file is a directory and try to open. - if (FindFile(folderName.c_str(), &FileInfo) && (FileInfo.m_Directory)) + if (FindFile(fileName.c_str(), &FileInfo) && (!FileInfo.m_Directory)) return true; + //check real folder + string FullPath = m_BasePath + fileName; + +#if defined (WIN32) + struct _stat statBuffer; + if (_stat(FullPath.c_str(), &statBuffer) >= 0) // make sure it exists + return true; +#else + struct stat st; + if (stat(FullPath.c_str(), &st) == 0) + return true; +#endif + //Neither in real folder nor in zip return false; } + // Note: this doesn't scan the folders outside of the zip...should we add that here ? std::vector& filesystem::scanfolder(const std::string& folderName, std::vector& results) { @@ -337,7 +365,7 @@ void filesystem::InsertZip(const char * Filename, const size_t PackID) } -bool filesystem::PreloadZip(const char * Filename, map& target) +bool filesystem::PreloadZip(const char * Filename, map& target) { zipfile_info ZipInfo; @@ -369,13 +397,9 @@ bool filesystem::PreloadZip(const char * Filename, map& targe if ((FileHdr.m_UncompSize != FileHdr.m_CompSize) || FileHdr.m_CompMethod != STORED) continue; - target[Name] = file_info( - 1, // Package ID + target[Name] = limited_file_info( realBeginOfFile + FileHdr.m_RelOffset, // "Local File" header offset position - FileHdr.m_UncompSize, // File Size - FileHdr.m_CompSize, // Compressed File Size - FileHdr.m_CompMethod, // Compression Method; - ((Name[i] == '/') || (Name[i] == '\\')) // Is a directory? + FileHdr.m_UncompSize // File Size ); } } @@ -402,13 +426,9 @@ bool filesystem::PreloadZip(const char * Filename, map& targe if ((FileHdr.m_UncompSize != FileHdr.m_CompSize) || FileHdr.m_CompMethod != STORED) continue; - target[Name] = file_info( - 1, // Package ID + target[Name] = limited_file_info( FileHdr.m_RelOffset, // "Local File" header offset position - FileHdr.m_UncompSize, // File Size - FileHdr.m_CompSize, // Compressed File Size - FileHdr.m_CompMethod, // Compression Method; - ((Name[i] == '/') || (Name[i] == '\\')) // Is a directory? + FileHdr.m_UncompSize // File Size ); } } diff --git a/JGE/src/zipFS/zfsystem.h b/JGE/src/zipFS/zfsystem.h index 2e1de3960..095fcb390 100644 --- a/JGE/src/zipFS/zfsystem.h +++ b/JGE/src/zipFS/zfsystem.h @@ -120,13 +120,25 @@ public: bool m_Directory; }; + class limited_file_info + { + public: + limited_file_info() : m_Offset(0), m_Size(0) { } + limited_file_info(size_t Offset, size_t Size) : + m_Offset(Offset), m_Size(Size) { } + + size_t m_Offset; + size_t m_Size; + }; + filesystem(const char * BasePath = "", const char * FileExt = "zip", bool DefaultFS = true); ~filesystem(); void MakeDefault(); void Open(izfstream & File, const char * Filename); bool DirExists(const std::string & folderName); - bool PreloadZip(const char * Filename, std::map& target); + bool FileExists(const std::string & fileName); + bool PreloadZip(const char * Filename, std::map& target); static std::string getCurrentZipName(); static filesystem * getCurrentFS(); static std::streamoff SkipLFHdr(std::istream & File, std::streamoff LFHdrPos); diff --git a/projects/mtg/include/GameStateShop.h b/projects/mtg/include/GameStateShop.h index aab2bee0c..e320ac388 100644 --- a/projects/mtg/include/GameStateShop.h +++ b/projects/mtg/include/GameStateShop.h @@ -63,7 +63,6 @@ class GameStateShop: public GameState, public JGuiListener private: JQuadPtr pspIcons[8]; WSrcCards * srcCards; - JTexture * altThumb[8]; TaskList * taskList; float mElapsed; WGuiMenu * shopMenu; diff --git a/projects/mtg/src/GameStateMenu.cpp b/projects/mtg/src/GameStateMenu.cpp index 0573e1515..017200447 100644 --- a/projects/mtg/src/GameStateMenu.cpp +++ b/projects/mtg/src/GameStateMenu.cpp @@ -137,7 +137,6 @@ void GameStateMenu::Start() mParent->gameType = GAME_TYPE_CLASSIC; //Manual clean up of some cache Data. Ideally those should clean themselves up, so this is kind of a hack for now - JFileSystem::GetInstance()->clearZipCache(); WResourceManager::Instance()->ClearUnlocked(); bgTexture = WResourceManager::Instance()->RetrieveTexture("menutitle.png", RETRIEVE_LOCK); diff --git a/projects/mtg/src/GameStateShop.cpp b/projects/mtg/src/GameStateShop.cpp index 0357a8105..c7f830071 100644 --- a/projects/mtg/src/GameStateShop.cpp +++ b/projects/mtg/src/GameStateShop.cpp @@ -52,8 +52,6 @@ GameStateShop::GameStateShop(GameApp* parent) : GameState(parent, "shop") { menu = NULL; - for (int i = 0; i < 8; i++) - altThumb[i] = NULL; boosterDisplay = NULL; taskList = NULL; srcCards = NULL; @@ -131,16 +129,6 @@ void GameStateShop::Start() bigDisplay->setY(135); } - //alternateRender doesn't lock, so lock our thumbnails for hgeDistort. - altThumb[0] = WResourceManager::Instance()->RetrieveTexture("artifact_thumb.jpg", RETRIEVE_LOCK); - altThumb[1] = WResourceManager::Instance()->RetrieveTexture("green_thumb.jpg", RETRIEVE_LOCK); - altThumb[2] = WResourceManager::Instance()->RetrieveTexture("blue_thumb.jpg", RETRIEVE_LOCK); - altThumb[3] = WResourceManager::Instance()->RetrieveTexture("red_thumb.jpg", RETRIEVE_LOCK); - altThumb[4] = WResourceManager::Instance()->RetrieveTexture("black_thumb.jpg", RETRIEVE_LOCK); - altThumb[5] = WResourceManager::Instance()->RetrieveTexture("white_thumb.jpg", RETRIEVE_LOCK); - altThumb[6] = WResourceManager::Instance()->RetrieveTexture("land_thumb.jpg", RETRIEVE_LOCK); - altThumb[7] = WResourceManager::Instance()->RetrieveTexture("gold_thumb.jpg", RETRIEVE_LOCK); - for (int i = 0; i < 8; ++i) { std::ostringstream stream; @@ -441,13 +429,6 @@ void GameStateShop::End() SAFE_DELETE(packlist); deleteDisplay(); - //Release alternate thumbnails. - for (int i = 0; i < 8; i++) - { - WResourceManager::Instance()->Release(altThumb[i]); - altThumb[i] = NULL; - } - SAFE_DELETE(menu); SAFE_DELETE(taskList); }