diff --git a/Source/Core/Common/Src/ChunkFile.h b/Source/Core/Common/Src/ChunkFile.h index 1e06234bd0..7d3aa35b93 100644 --- a/Source/Core/Common/Src/ChunkFile.h +++ b/Source/Core/Common/Src/ChunkFile.h @@ -31,6 +31,7 @@ #include #include +#include #include "Common.h" @@ -87,7 +88,42 @@ public: // TODO PanicAlert("Do(vector<>) does not yet work."); } + + // Store strings. + void Do(std::string &x) + { + int stringLen = x.length() + 1; + Do(stringLen); + + switch (mode) + { + case MODE_READ: x = (char*)*ptr; break; + case MODE_WRITE: memcpy(*ptr, x.c_str(), stringLen); break; + case MODE_MEASURE: break; + } + (*ptr) += stringLen; + } + void DoBuffer(u8** pBuffer, u32& _Size) + { + Do(_Size); + + if (_Size > 0) + { + switch (mode) + { + case MODE_READ: *pBuffer = new u8[_Size]; memcpy(*pBuffer, *ptr, _Size); break; + case MODE_WRITE: memcpy(*ptr, *pBuffer, _Size); break; + case MODE_MEASURE: break; + } + } + else + { + *pBuffer = NULL; + } + (*ptr) += _Size; + } + template void DoArray(T *x, int count) { DoVoid((void *)x, sizeof(T) * count); @@ -105,4 +141,96 @@ public: } }; + +class CChunkFileReader +{ +public: + template + static bool Load(const std::string& _rFilename, int _Revision, T& _class) + { + FILE* pFile = fopen(_rFilename.c_str(), "rb"); + if (pFile) + { + // get size + fseek(pFile, 0, SEEK_END); + size_t FileSize = ftell(pFile); + fseek(pFile, 0, SEEK_SET); + + if (FileSize < sizeof(SChunkHeader)) + { + fclose(pFile); + return false; + } + + // read the header + SChunkHeader Header; + fread(&Header, sizeof(SChunkHeader), 1, pFile); + if (Header.Revision != _Revision) + { + fclose(pFile); + return false; + } + + // get size + int sz = FileSize - sizeof(SChunkHeader); + if (Header.ExpectedSize != sz) + { + fclose(pFile); + return false; + } + + // read the state + u8* buffer = new u8[sz]; + fread(buffer, 1, sz, pFile); + fclose(pFile); + + u8 *ptr = buffer; + PointerWrap p(&ptr, PointerWrap::MODE_READ); + _class.DoState(p); + delete [] buffer; + + return true; + } + + return false; + } + + template + static bool Save(const std::string& _rFilename, int _Revision, T& _class) + { + FILE* pFile = fopen(_rFilename.c_str(), "wb"); + if (pFile) + { + u8 *ptr = 0; + PointerWrap p(&ptr, PointerWrap::MODE_MEASURE); + _class.DoState(p); + size_t sz = (size_t)ptr; + u8 *buffer = new u8[sz]; + ptr = buffer; + p.SetMode(PointerWrap::MODE_WRITE); + _class.DoState(p); + + SChunkHeader Header; + Header.Compress = 0; + Header.Revision = _Revision; + Header.ExpectedSize = sz; + + fwrite(&Header, sizeof(SChunkHeader), 1, pFile); + fwrite(buffer, sz, 1, pFile); + fclose(pFile); + + return true; + } + + return false; + } +private: + struct SChunkHeader + { + int Revision; + int Compress; + int ExpectedSize; + }; +}; + #endif // _POINTERWRAP_H diff --git a/Source/Core/Core/Core.vcproj b/Source/Core/Core/Core.vcproj index 13fd3691f9..bfa0743e54 100644 --- a/Source/Core/Core/Core.vcproj +++ b/Source/Core/Core/Core.vcproj @@ -1111,10 +1111,6 @@ RelativePath=".\Src\IPC_HLE\WII_IPC_HLE_Device_fs.h" > - - @@ -1356,6 +1352,10 @@ RelativePath=".\Src\IPC_HLE\WII_IPC_HLE_Device_fs.cpp" > + + diff --git a/Source/Core/DolphinWX/Src/GameListCtrl.cpp b/Source/Core/DolphinWX/Src/GameListCtrl.cpp index e8ff6fe555..45f7c71b3f 100644 --- a/Source/Core/DolphinWX/Src/GameListCtrl.cpp +++ b/Source/Core/DolphinWX/Src/GameListCtrl.cpp @@ -334,6 +334,7 @@ void CGameListCtrl::SetBackgroundColor() void CGameListCtrl::ScanForISOs(bool loadcache) { +#if 0 FILE * cacheFile; bool scanISO = true; if (loadcache) @@ -358,6 +359,7 @@ void CGameListCtrl::ScanForISOs(bool loadcache) } } m_ISOFiles.clear(); + if (!scanISO) { // TODO: complete cache loading here. this means ADDING THE BANNER >_< @@ -483,6 +485,8 @@ void CGameListCtrl::ScanForISOs(bool loadcache) } } else +#endif + { CFileSearch::XStringVector Directories(SConfig::GetInstance().m_ISOFolder); @@ -528,6 +532,7 @@ void CGameListCtrl::ScanForISOs(bool loadcache) GameListItem ISOFile(rFilenames[i]); if (ISOFile.IsValid()) { +#if 0 if(cacheFile) { fseek(cacheFile, 0L, SEEK_END); @@ -547,13 +552,16 @@ void CGameListCtrl::ScanForISOs(bool loadcache) // TODO: add the banner saving TO 1 FILE AND JPG as well & make the cache MUCH better. // This is ugly as fuck } +#endif 0 m_ISOFiles.push_back(ISOFile); } else PanicAlert("Invalid ISO file %s", rFilenames[i].c_str()); } } +#if 0 fclose (cacheFile); +#endif } std::sort(m_ISOFiles.begin(), m_ISOFiles.end()); } diff --git a/Source/Core/DolphinWX/Src/ISOFile.cpp b/Source/Core/DolphinWX/Src/ISOFile.cpp index 8c45f3b5ac..cf520939e1 100644 --- a/Source/Core/DolphinWX/Src/ISOFile.cpp +++ b/Source/Core/DolphinWX/Src/ISOFile.cpp @@ -17,19 +17,22 @@ #include #include +#include #include "Globals.h" #include "FileUtil.h" #include "ISOFile.h" +#include "StringUtil.h" #include "VolumeCreator.h" #include "Filesystem.h" #include "BannerLoader.h" #include "FileSearch.h" #include "CompressedBlob.h" +#include "ChunkFile.h" #include "../resources/no_banner.cpp" -#include +#define CACHE_REVISION 0x103 #define DVD_BANNER_WIDTH 96 #define DVD_BANNER_HEIGHT 32 @@ -37,73 +40,125 @@ static u32 g_ImageTemp[DVD_BANNER_WIDTH * DVD_BANNER_HEIGHT]; GameListItem::GameListItem(const std::string& _rFileName) - : m_FileName(_rFileName), - m_FileSize(0), - m_Valid(false), - m_BlobCompressed(false) + : m_FileName(_rFileName) + , m_FileSize(0) + , m_Valid(false) + , m_BlobCompressed(false) + , m_pImage(NULL) + , m_ImageSize(0) { - DiscIO::IVolume* pVolume = DiscIO::CreateVolumeFromFilename(_rFileName); - if (pVolume != NULL) + if (LoadFromCache()) { - m_Name = _rFileName; - m_Country = pVolume->GetCountry(); - m_FileSize = File::GetSize(_rFileName.c_str()); - m_VolumeSize = pVolume->GetSize(); - m_Name = pVolume->GetName(); - m_UniqueID = pVolume->GetUniqueID(); - m_BlobCompressed = DiscIO::IsCompressedBlob(_rFileName.c_str()); + m_Valid = true; + } + else + { + DiscIO::IVolume* pVolume = DiscIO::CreateVolumeFromFilename(_rFileName); - // check if we can get some infos from the banner file too - DiscIO::IFileSystem* pFileSystem = DiscIO::CreateFileSystem(pVolume); - - if (pFileSystem != NULL) + if (pVolume != NULL) { - DiscIO::IBannerLoader* pBannerLoader = DiscIO::CreateBannerLoader(*pFileSystem); + m_Name = _rFileName; + m_Country = pVolume->GetCountry(); + m_FileSize = File::GetSize(_rFileName.c_str()); + m_VolumeSize = pVolume->GetSize(); + m_Name = pVolume->GetName(); + m_UniqueID = pVolume->GetUniqueID(); + m_BlobCompressed = DiscIO::IsCompressedBlob(_rFileName.c_str()); - if (pBannerLoader != NULL) + // check if we can get some infos from the banner file too + DiscIO::IFileSystem* pFileSystem = DiscIO::CreateFileSystem(pVolume); + + if (pFileSystem != NULL) { - if (pBannerLoader->IsValid()) + DiscIO::IBannerLoader* pBannerLoader = DiscIO::CreateBannerLoader(*pFileSystem); + + if (pBannerLoader != NULL) { - pBannerLoader->GetName(m_Name, 0); //m_Country == DiscIO::IVolume::COUNTRY_JAP ? 1 : 0); - pBannerLoader->GetCompany(m_Company); - pBannerLoader->GetDescription(m_Description); - if (pBannerLoader->GetBanner(g_ImageTemp)) + if (pBannerLoader->IsValid()) { - unsigned char* pImage = (unsigned char*)malloc(DVD_BANNER_WIDTH * DVD_BANNER_HEIGHT * 3); - - for (size_t i = 0; i < DVD_BANNER_WIDTH * DVD_BANNER_HEIGHT; i++) + pBannerLoader->GetName(m_Name, 0); //m_Country == DiscIO::IVolume::COUNTRY_JAP ? 1 : 0); + pBannerLoader->GetCompany(m_Company); + pBannerLoader->GetDescription(m_Description); + if (pBannerLoader->GetBanner(g_ImageTemp)) { - pImage[i * 3 + 0] = (g_ImageTemp[i] & 0xFF0000) >> 16; - pImage[i * 3 + 1] = (g_ImageTemp[i] & 0x00FF00) >> 8; - pImage[i * 3 + 2] = (g_ImageTemp[i] & 0x0000FF) >> 0; + m_ImageSize = DVD_BANNER_WIDTH * DVD_BANNER_HEIGHT * 3; + m_pImage = new u8[m_ImageSize]; //(u8*)malloc(m_ImageSize); + + for (size_t i = 0; i < DVD_BANNER_WIDTH * DVD_BANNER_HEIGHT; i++) + { + m_pImage[i * 3 + 0] = (g_ImageTemp[i] & 0xFF0000) >> 16; + m_pImage[i * 3 + 1] = (g_ImageTemp[i] & 0x00FF00) >> 8; + m_pImage[i * 3 + 2] = (g_ImageTemp[i] & 0x0000FF) >> 0; + } } - - m_Image.Create(DVD_BANNER_WIDTH, DVD_BANNER_HEIGHT, pImage); } - } - else - { - // default banner - wxMemoryInputStream istream(no_banner_png, sizeof no_banner_png); - wxImage iNoBanner(istream, wxBITMAP_TYPE_PNG); - m_Image = iNoBanner; - + + delete pBannerLoader; } - delete pBannerLoader; + delete pFileSystem; } - delete pFileSystem; - } - delete pVolume; + delete pVolume; - m_Valid = true; + m_Valid = true; + + SaveToCache(); + } + } + + // i am not sure if this is a leak or if wxImage will release the code + if (m_pImage) + { +#if !defined(OSX64) + m_Image.Create(DVD_BANNER_WIDTH, DVD_BANNER_HEIGHT, m_pImage); +#endif + } + else + { + // default banner + wxMemoryInputStream istream(no_banner_png, sizeof no_banner_png); + wxImage iNoBanner(istream, wxBITMAP_TYPE_PNG); + m_Image = iNoBanner; } } GameListItem::~GameListItem() -{} +{ +} +bool GameListItem::LoadFromCache() +{ + return CChunkFileReader::Load(CreateCacheFilename(), CACHE_REVISION, *this); +} +void GameListItem::SaveToCache() +{ + CChunkFileReader::Save(CreateCacheFilename(), CACHE_REVISION, *this); +} + +void GameListItem::DoState(PointerWrap &p) +{ + p.Do(m_Name); + p.Do(m_Company); + p.Do(m_Description); + p.Do(m_UniqueID); + p.Do(m_FileSize); + p.Do(m_VolumeSize); + p.Do(m_Country); + p.Do(m_BlobCompressed); + p.DoBuffer(&m_pImage, m_ImageSize); +} + +std::string GameListItem::CreateCacheFilename() +{ + std::string Filename; + SplitPath(m_FileName, NULL, &Filename, NULL); + Filename.append(".cache"); + + std::string fullname("ISOCache\\"); + fullname += Filename; + return fullname; +} diff --git a/Source/Core/DolphinWX/Src/ISOFile.h b/Source/Core/DolphinWX/Src/ISOFile.h index 916b285730..920844e25f 100644 --- a/Source/Core/DolphinWX/Src/ISOFile.h +++ b/Source/Core/DolphinWX/Src/ISOFile.h @@ -20,6 +20,7 @@ #include "Volume.h" +class PointerWrap; class GameListItem { public: @@ -36,11 +37,13 @@ public: bool IsCompressed() const {return m_BlobCompressed;} u64 GetFileSize() const {return m_FileSize;} u64 GetVolumeSize() const {return m_VolumeSize;} - #if !defined(OSX64) const wxImage& GetImage() const {return m_Image;} #endif + void DoState(PointerWrap &p); + +private: std::string m_FileName; std::string m_Name; std::string m_Company; @@ -51,13 +54,21 @@ public: u64 m_VolumeSize; DiscIO::IVolume::ECountry m_Country; + bool m_BlobCompressed; + + u32 m_ImageSize; + u8* m_pImage; #if !defined(OSX64) wxImage m_Image; #endif bool m_Valid; - bool m_BlobCompressed; + bool LoadFromCache(); + void SaveToCache(); + + + std::string CreateCacheFilename(); };