[Glide64] Clean up GlideHQ/TxCache.cpp
This commit is contained in:
parent
612bbb71e5
commit
0ebcf6d608
|
@ -33,400 +33,400 @@
|
||||||
|
|
||||||
TxCache::~TxCache()
|
TxCache::~TxCache()
|
||||||
{
|
{
|
||||||
/* free memory, clean up, etc */
|
/* free memory, clean up, etc */
|
||||||
clear();
|
clear();
|
||||||
|
|
||||||
delete _txUtil;
|
delete _txUtil;
|
||||||
}
|
}
|
||||||
|
|
||||||
TxCache::TxCache(int options, int cachesize, const wchar_t *path, const wchar_t *ident,
|
TxCache::TxCache(int options, int cachesize, const wchar_t *path, const wchar_t *ident,
|
||||||
dispInfoFuncExt callback)
|
dispInfoFuncExt callback)
|
||||||
{
|
{
|
||||||
_txUtil = new TxUtil();
|
_txUtil = new TxUtil();
|
||||||
|
|
||||||
_options = options;
|
_options = options;
|
||||||
_cacheSize = cachesize;
|
_cacheSize = cachesize;
|
||||||
_callback = callback;
|
_callback = callback;
|
||||||
_totalSize = 0;
|
_totalSize = 0;
|
||||||
|
|
||||||
/* save path name */
|
/* save path name */
|
||||||
if (path)
|
if (path)
|
||||||
_path.assign(path);
|
_path.assign(path);
|
||||||
|
|
||||||
/* save ROM name */
|
/* save ROM name */
|
||||||
if (ident)
|
if (ident)
|
||||||
_ident.assign(ident);
|
_ident.assign(ident);
|
||||||
|
|
||||||
/* zlib memory buffers to (de)compress hires textures */
|
/* zlib memory buffers to (de)compress hires textures */
|
||||||
if (_options & (GZ_TEXCACHE|GZ_HIRESTEXCACHE)) {
|
if (_options & (GZ_TEXCACHE | GZ_HIRESTEXCACHE)) {
|
||||||
_gzdest0 = TxMemBuf::getInstance()->get(0);
|
_gzdest0 = TxMemBuf::getInstance()->get(0);
|
||||||
_gzdest1 = TxMemBuf::getInstance()->get(1);
|
_gzdest1 = TxMemBuf::getInstance()->get(1);
|
||||||
_gzdestLen = (TxMemBuf::getInstance()->size_of(0) < TxMemBuf::getInstance()->size_of(1)) ?
|
_gzdestLen = (TxMemBuf::getInstance()->size_of(0) < TxMemBuf::getInstance()->size_of(1)) ?
|
||||||
TxMemBuf::getInstance()->size_of(0) : TxMemBuf::getInstance()->size_of(1);
|
TxMemBuf::getInstance()->size_of(0) : TxMemBuf::getInstance()->size_of(1);
|
||||||
|
|
||||||
if (!_gzdest0 || !_gzdest1 || !_gzdestLen) {
|
if (!_gzdest0 || !_gzdest1 || !_gzdestLen) {
|
||||||
_options &= ~(GZ_TEXCACHE|GZ_HIRESTEXCACHE);
|
_options &= ~(GZ_TEXCACHE | GZ_HIRESTEXCACHE);
|
||||||
_gzdest0 = NULL;
|
_gzdest0 = NULL;
|
||||||
_gzdest1 = NULL;
|
_gzdest1 = NULL;
|
||||||
_gzdestLen = 0;
|
_gzdestLen = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean
|
boolean
|
||||||
TxCache::add(uint64 checksum, GHQTexInfo *info, int dataSize)
|
TxCache::add(uint64 checksum, GHQTexInfo *info, int dataSize)
|
||||||
{
|
{
|
||||||
/* NOTE: dataSize must be provided if info->data is zlib compressed. */
|
/* NOTE: dataSize must be provided if info->data is zlib compressed. */
|
||||||
|
|
||||||
if (!checksum || !info->data) return 0;
|
if (!checksum || !info->data) return 0;
|
||||||
|
|
||||||
uint8 *dest = info->data;
|
uint8 *dest = info->data;
|
||||||
uint16 format = info->format;
|
uint16 format = info->format;
|
||||||
|
|
||||||
if (!dataSize) {
|
if (!dataSize) {
|
||||||
dataSize = _txUtil->sizeofTx(info->width, info->height, info->format);
|
dataSize = _txUtil->sizeofTx(info->width, info->height, info->format);
|
||||||
|
|
||||||
if (!dataSize) return 0;
|
if (!dataSize) return 0;
|
||||||
|
|
||||||
if (_options & (GZ_TEXCACHE|GZ_HIRESTEXCACHE)) {
|
if (_options & (GZ_TEXCACHE | GZ_HIRESTEXCACHE)) {
|
||||||
/* zlib compress it. compression level:1 (best speed) */
|
/* zlib compress it. compression level:1 (best speed) */
|
||||||
uLongf destLen = _gzdestLen;
|
uLongf destLen = _gzdestLen;
|
||||||
dest = (dest == _gzdest0) ? _gzdest1 : _gzdest0;
|
dest = (dest == _gzdest0) ? _gzdest1 : _gzdest0;
|
||||||
if (compress2(dest, &destLen, info->data, dataSize, 1) != Z_OK) {
|
if (compress2(dest, &destLen, info->data, dataSize, 1) != Z_OK) {
|
||||||
dest = info->data;
|
dest = info->data;
|
||||||
DBG_INFO(80, L"Error: zlib compression failed!\n");
|
DBG_INFO(80, L"Error: zlib compression failed!\n");
|
||||||
} else {
|
}
|
||||||
DBG_INFO(80, L"zlib compressed: %.02fkb->%.02fkb\n", (float)dataSize/1000, (float)destLen/1000);
|
else {
|
||||||
dataSize = destLen;
|
DBG_INFO(80, L"zlib compressed: %.02fkb->%.02fkb\n", (float)dataSize / 1000, (float)destLen / 1000);
|
||||||
format |= GR_TEXFMT_GZ;
|
dataSize = destLen;
|
||||||
}
|
format |= GR_TEXFMT_GZ;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* if cache size exceeds limit, remove old cache */
|
|
||||||
if (_cacheSize > 0) {
|
|
||||||
_totalSize += dataSize;
|
|
||||||
if ((_totalSize > _cacheSize) && !_cachelist.empty()) {
|
|
||||||
/* _cachelist is arranged so that frequently used textures are in the back */
|
|
||||||
std::list<uint64>::iterator itList = _cachelist.begin();
|
|
||||||
while (itList != _cachelist.end()) {
|
|
||||||
/* find it in _cache */
|
|
||||||
std::map<uint64, TXCACHE*>::iterator itMap = _cache.find(*itList);
|
|
||||||
if (itMap != _cache.end()) {
|
|
||||||
/* yep we have it. remove it. */
|
|
||||||
_totalSize -= (*itMap).second->size;
|
|
||||||
free((*itMap).second->info.data);
|
|
||||||
delete (*itMap).second;
|
|
||||||
_cache.erase(itMap);
|
|
||||||
}
|
}
|
||||||
itList++;
|
|
||||||
|
|
||||||
/* check if memory cache has enough space */
|
|
||||||
if (_totalSize <= _cacheSize)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
/* remove from _cachelist */
|
|
||||||
_cachelist.erase(_cachelist.begin(), itList);
|
|
||||||
|
|
||||||
DBG_INFO(80, L"+++++++++\n");
|
|
||||||
}
|
}
|
||||||
_totalSize -= dataSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* cache it */
|
/* if cache size exceeds limit, remove old cache */
|
||||||
uint8 *tmpdata = (uint8*)malloc(dataSize);
|
if (_cacheSize > 0) {
|
||||||
if (tmpdata) {
|
_totalSize += dataSize;
|
||||||
TXCACHE *txCache = new TXCACHE;
|
if ((_totalSize > _cacheSize) && !_cachelist.empty()) {
|
||||||
if (txCache) {
|
/* _cachelist is arranged so that frequently used textures are in the back */
|
||||||
/* we can directly write as we filter, but for now we get away
|
std::list<uint64>::iterator itList = _cachelist.begin();
|
||||||
* with doing memcpy after all the filtering is done.
|
while (itList != _cachelist.end()) {
|
||||||
*/
|
/* find it in _cache */
|
||||||
memcpy(tmpdata, dest, dataSize);
|
std::map<uint64, TXCACHE*>::iterator itMap = _cache.find(*itList);
|
||||||
|
if (itMap != _cache.end()) {
|
||||||
|
/* yep we have it. remove it. */
|
||||||
|
_totalSize -= (*itMap).second->size;
|
||||||
|
free((*itMap).second->info.data);
|
||||||
|
delete (*itMap).second;
|
||||||
|
_cache.erase(itMap);
|
||||||
|
}
|
||||||
|
itList++;
|
||||||
|
|
||||||
/* copy it */
|
/* check if memory cache has enough space */
|
||||||
memcpy(&txCache->info, info, sizeof(GHQTexInfo));
|
if (_totalSize <= _cacheSize)
|
||||||
txCache->info.data = tmpdata;
|
break;
|
||||||
txCache->info.format = format;
|
}
|
||||||
txCache->size = dataSize;
|
/* remove from _cachelist */
|
||||||
|
_cachelist.erase(_cachelist.begin(), itList);
|
||||||
|
|
||||||
/* add to cache */
|
DBG_INFO(80, L"+++++++++\n");
|
||||||
if (_cacheSize > 0) {
|
}
|
||||||
_cachelist.push_back(checksum);
|
_totalSize -= dataSize;
|
||||||
txCache->it = --(_cachelist.end());
|
}
|
||||||
}
|
|
||||||
/* _cache[checksum] = txCache; */
|
/* cache it */
|
||||||
_cache.insert(std::map<uint64, TXCACHE*>::value_type(checksum, txCache));
|
uint8 *tmpdata = (uint8*)malloc(dataSize);
|
||||||
|
if (tmpdata) {
|
||||||
|
TXCACHE *txCache = new TXCACHE;
|
||||||
|
if (txCache) {
|
||||||
|
/* we can directly write as we filter, but for now we get away
|
||||||
|
* with doing memcpy after all the filtering is done.
|
||||||
|
*/
|
||||||
|
memcpy(tmpdata, dest, dataSize);
|
||||||
|
|
||||||
|
/* copy it */
|
||||||
|
memcpy(&txCache->info, info, sizeof(GHQTexInfo));
|
||||||
|
txCache->info.data = tmpdata;
|
||||||
|
txCache->info.format = format;
|
||||||
|
txCache->size = dataSize;
|
||||||
|
|
||||||
|
/* add to cache */
|
||||||
|
if (_cacheSize > 0) {
|
||||||
|
_cachelist.push_back(checksum);
|
||||||
|
txCache->it = --(_cachelist.end());
|
||||||
|
}
|
||||||
|
/* _cache[checksum] = txCache; */
|
||||||
|
_cache.insert(std::map<uint64, TXCACHE*>::value_type(checksum, txCache));
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
DBG_INFO(80, L"[%5d] added!! crc:%08X %08X %d x %d gfmt:%x total:%.02fmb\n",
|
DBG_INFO(80, L"[%5d] added!! crc:%08X %08X %d x %d gfmt:%x total:%.02fmb\n",
|
||||||
_cache.size(), (uint32)(checksum >> 32), (uint32)(checksum & 0xffffffff),
|
_cache.size(), (uint32)(checksum >> 32), (uint32)(checksum & 0xffffffff),
|
||||||
info->width, info->height, info->format, (float)_totalSize/1000000);
|
info->width, info->height, info->format, (float)_totalSize/1000000);
|
||||||
|
|
||||||
DBG_INFO(80, L"smalllodlog2:%d largelodlog2:%d aspectratiolog2:%d\n",
|
DBG_INFO(80, L"smalllodlog2:%d largelodlog2:%d aspectratiolog2:%d\n",
|
||||||
txCache->info.smallLodLog2, txCache->info.largeLodLog2, txCache->info.aspectRatioLog2);
|
txCache->info.smallLodLog2, txCache->info.largeLodLog2, txCache->info.aspectRatioLog2);
|
||||||
|
|
||||||
if (info->tiles) {
|
if (info->tiles) {
|
||||||
DBG_INFO(80, L"tiles:%d un-tiled size:%d x %d\n", info->tiles, info->untiled_width, info->untiled_height);
|
DBG_INFO(80, L"tiles:%d un-tiled size:%d x %d\n", info->tiles, info->untiled_width, info->untiled_height);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_cacheSize > 0) {
|
if (_cacheSize > 0) {
|
||||||
DBG_INFO(80, L"cache max config:%.02fmb\n", (float)_cacheSize/1000000);
|
DBG_INFO(80, L"cache max config:%.02fmb\n", (float)_cacheSize/1000000);
|
||||||
|
|
||||||
if (_cache.size() != _cachelist.size()) {
|
if (_cache.size() != _cachelist.size()) {
|
||||||
DBG_INFO(80, L"Error: cache/cachelist mismatch! (%d/%d)\n", _cache.size(), _cachelist.size());
|
DBG_INFO(80, L"Error: cache/cachelist mismatch! (%d/%d)\n", _cache.size(), _cachelist.size());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* total cache size */
|
/* total cache size */
|
||||||
_totalSize += dataSize;
|
_totalSize += dataSize;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
free(tmpdata);
|
free(tmpdata);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean
|
boolean
|
||||||
TxCache::get(uint64 checksum, GHQTexInfo *info)
|
TxCache::get(uint64 checksum, GHQTexInfo *info)
|
||||||
{
|
{
|
||||||
if (!checksum || _cache.empty()) return 0;
|
if (!checksum || _cache.empty()) return 0;
|
||||||
|
|
||||||
/* find a match in cache */
|
/* find a match in cache */
|
||||||
std::map<uint64, TXCACHE*>::iterator itMap = _cache.find(checksum);
|
std::map<uint64, TXCACHE*>::iterator itMap = _cache.find(checksum);
|
||||||
if (itMap != _cache.end()) {
|
if (itMap != _cache.end()) {
|
||||||
/* yep, we've got it. */
|
/* yep, we've got it. */
|
||||||
memcpy(info, &(((*itMap).second)->info), sizeof(GHQTexInfo));
|
memcpy(info, &(((*itMap).second)->info), sizeof(GHQTexInfo));
|
||||||
|
|
||||||
/* push it to the back of the list */
|
/* push it to the back of the list */
|
||||||
if (_cacheSize > 0) {
|
if (_cacheSize > 0) {
|
||||||
_cachelist.erase(((*itMap).second)->it);
|
_cachelist.erase(((*itMap).second)->it);
|
||||||
_cachelist.push_back(checksum);
|
_cachelist.push_back(checksum);
|
||||||
((*itMap).second)->it = --(_cachelist.end());
|
((*itMap).second)->it = --(_cachelist.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
/* zlib decompress it */
|
||||||
|
if (info->format & GR_TEXFMT_GZ) {
|
||||||
|
uLongf destLen = _gzdestLen;
|
||||||
|
uint8 *dest = (_gzdest0 == info->data) ? _gzdest1 : _gzdest0;
|
||||||
|
if (uncompress(dest, &destLen, info->data, ((*itMap).second)->size) != Z_OK) {
|
||||||
|
DBG_INFO(80, L"Error: zlib decompression failed!\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
info->data = dest;
|
||||||
|
info->format &= ~GR_TEXFMT_GZ;
|
||||||
|
DBG_INFO(80, L"zlib decompressed: %.02fkb->%.02fkb\n", (float)(((*itMap).second)->size) / 1000, (float)destLen / 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* zlib decompress it */
|
return 0;
|
||||||
if (info->format & GR_TEXFMT_GZ) {
|
|
||||||
uLongf destLen = _gzdestLen;
|
|
||||||
uint8 *dest = (_gzdest0 == info->data) ? _gzdest1 : _gzdest0;
|
|
||||||
if (uncompress(dest, &destLen, info->data, ((*itMap).second)->size) != Z_OK) {
|
|
||||||
DBG_INFO(80, L"Error: zlib decompression failed!\n");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
info->data = dest;
|
|
||||||
info->format &= ~GR_TEXFMT_GZ;
|
|
||||||
DBG_INFO(80, L"zlib decompressed: %.02fkb->%.02fkb\n", (float)(((*itMap).second)->size)/1000, (float)destLen/1000);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean
|
boolean
|
||||||
TxCache::save(const wchar_t *path, const wchar_t *filename, int config)
|
TxCache::save(const wchar_t *path, const wchar_t *filename, int config)
|
||||||
{
|
{
|
||||||
if (!_cache.empty()) {
|
if (!_cache.empty()) {
|
||||||
/* dump cache to disk */
|
/* dump cache to disk */
|
||||||
char cbuf[MAX_PATH];
|
char cbuf[MAX_PATH];
|
||||||
|
|
||||||
CPath cachepath(stdstr().FromUTF16(path),"");
|
CPath cachepath(stdstr().FromUTF16(path), "");
|
||||||
cachepath.DirectoryCreate();
|
cachepath.DirectoryCreate();
|
||||||
|
|
||||||
/* Ugly hack to enable fopen/gzopen in Win9x */
|
/* Ugly hack to enable fopen/gzopen in Win9x */
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
wchar_t curpath[MAX_PATH];
|
wchar_t curpath[MAX_PATH];
|
||||||
GETCWD(MAX_PATH, curpath);
|
GETCWD(MAX_PATH, curpath);
|
||||||
cachepath.ChangeDirectory();
|
cachepath.ChangeDirectory();
|
||||||
#else
|
#else
|
||||||
char curpath[MAX_PATH];
|
char curpath[MAX_PATH];
|
||||||
wcstombs(cbuf, cachepath.wstring().c_str(), MAX_PATH);
|
wcstombs(cbuf, cachepath.wstring().c_str(), MAX_PATH);
|
||||||
GETCWD(MAX_PATH, curpath);
|
GETCWD(MAX_PATH, curpath);
|
||||||
CHDIR(cbuf);
|
CHDIR(cbuf);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
wcstombs(cbuf, filename, MAX_PATH);
|
wcstombs(cbuf, filename, MAX_PATH);
|
||||||
|
|
||||||
gzFile gzfp = gzopen(cbuf, "wb1");
|
gzFile gzfp = gzopen(cbuf, "wb1");
|
||||||
DBG_INFO(80, L"gzfp:%x file:%ls\n", gzfp, filename);
|
DBG_INFO(80, L"gzfp:%x file:%ls\n", gzfp, filename);
|
||||||
if (gzfp) {
|
if (gzfp) {
|
||||||
/* write header to determine config match */
|
/* write header to determine config match */
|
||||||
gzwrite(gzfp, &config, 4);
|
gzwrite(gzfp, &config, 4);
|
||||||
|
|
||||||
std::map<uint64, TXCACHE*>::iterator itMap = _cache.begin();
|
std::map<uint64, TXCACHE*>::iterator itMap = _cache.begin();
|
||||||
while (itMap != _cache.end()) {
|
while (itMap != _cache.end()) {
|
||||||
uint8 *dest = (*itMap).second->info.data;
|
uint8 *dest = (*itMap).second->info.data;
|
||||||
uint32 destLen = (*itMap).second->size;
|
uint32 destLen = (*itMap).second->size;
|
||||||
uint16 format = (*itMap).second->info.format;
|
uint16 format = (*itMap).second->info.format;
|
||||||
|
|
||||||
/* to keep things simple, we save the texture data in a zlib uncompressed state. */
|
/* to keep things simple, we save the texture data in a zlib uncompressed state. */
|
||||||
/* sigh... for those who cannot wait the extra few seconds. changed to keep
|
/* sigh... for those who cannot wait the extra few seconds. changed to keep
|
||||||
* texture data in a zlib compressed state. if the GZ_TEXCACHE or GZ_HIRESTEXCACHE
|
* texture data in a zlib compressed state. if the GZ_TEXCACHE or GZ_HIRESTEXCACHE
|
||||||
* option is toggled, the cache will need to be rebuilt.
|
* option is toggled, the cache will need to be rebuilt.
|
||||||
*/
|
*/
|
||||||
/*if (format & GR_TEXFMT_GZ) {
|
/*if (format & GR_TEXFMT_GZ) {
|
||||||
dest = _gzdest0;
|
dest = _gzdest0;
|
||||||
destLen = _gzdestLen;
|
destLen = _gzdestLen;
|
||||||
if (dest && destLen) {
|
if (dest && destLen) {
|
||||||
if (uncompress(dest, &destLen, (*itMap).second->info.data, (*itMap).second->size) != Z_OK) {
|
if (uncompress(dest, &destLen, (*itMap).second->info.data, (*itMap).second->size) != Z_OK) {
|
||||||
dest = NULL;
|
dest = NULL;
|
||||||
destLen = 0;
|
destLen = 0;
|
||||||
|
}
|
||||||
|
format &= ~GR_TEXFMT_GZ;
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
|
||||||
|
if (dest && destLen) {
|
||||||
|
/* texture checksum */
|
||||||
|
gzwrite(gzfp, &((*itMap).first), 8);
|
||||||
|
|
||||||
|
/* other texture info */
|
||||||
|
gzwrite(gzfp, &((*itMap).second->info.width), 4);
|
||||||
|
gzwrite(gzfp, &((*itMap).second->info.height), 4);
|
||||||
|
gzwrite(gzfp, &format, 2);
|
||||||
|
|
||||||
|
gzwrite(gzfp, &((*itMap).second->info.smallLodLog2), 4);
|
||||||
|
gzwrite(gzfp, &((*itMap).second->info.largeLodLog2), 4);
|
||||||
|
gzwrite(gzfp, &((*itMap).second->info.aspectRatioLog2), 4);
|
||||||
|
|
||||||
|
gzwrite(gzfp, &((*itMap).second->info.tiles), 4);
|
||||||
|
gzwrite(gzfp, &((*itMap).second->info.untiled_width), 4);
|
||||||
|
gzwrite(gzfp, &((*itMap).second->info.untiled_height), 4);
|
||||||
|
|
||||||
|
gzwrite(gzfp, &((*itMap).second->info.is_hires_tex), 1);
|
||||||
|
|
||||||
|
gzwrite(gzfp, &destLen, 4);
|
||||||
|
gzwrite(gzfp, dest, destLen);
|
||||||
|
}
|
||||||
|
|
||||||
|
itMap++;
|
||||||
|
|
||||||
|
/* not ready yet */
|
||||||
|
/*if (_callback)
|
||||||
|
(*_callback)(L"Total textures saved to HDD: %d\n", std::distance(itMap, _cache.begin()));*/
|
||||||
}
|
}
|
||||||
format &= ~GR_TEXFMT_GZ;
|
gzclose(gzfp);
|
||||||
}
|
|
||||||
}*/
|
|
||||||
|
|
||||||
if (dest && destLen) {
|
|
||||||
/* texture checksum */
|
|
||||||
gzwrite(gzfp, &((*itMap).first), 8);
|
|
||||||
|
|
||||||
/* other texture info */
|
|
||||||
gzwrite(gzfp, &((*itMap).second->info.width), 4);
|
|
||||||
gzwrite(gzfp, &((*itMap).second->info.height), 4);
|
|
||||||
gzwrite(gzfp, &format, 2);
|
|
||||||
|
|
||||||
gzwrite(gzfp, &((*itMap).second->info.smallLodLog2), 4);
|
|
||||||
gzwrite(gzfp, &((*itMap).second->info.largeLodLog2), 4);
|
|
||||||
gzwrite(gzfp, &((*itMap).second->info.aspectRatioLog2), 4);
|
|
||||||
|
|
||||||
gzwrite(gzfp, &((*itMap).second->info.tiles), 4);
|
|
||||||
gzwrite(gzfp, &((*itMap).second->info.untiled_width), 4);
|
|
||||||
gzwrite(gzfp, &((*itMap).second->info.untiled_height), 4);
|
|
||||||
|
|
||||||
gzwrite(gzfp, &((*itMap).second->info.is_hires_tex), 1);
|
|
||||||
|
|
||||||
gzwrite(gzfp, &destLen, 4);
|
|
||||||
gzwrite(gzfp, dest, destLen);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
itMap++;
|
CHDIR(curpath);
|
||||||
|
|
||||||
/* not ready yet */
|
|
||||||
/*if (_callback)
|
|
||||||
(*_callback)(L"Total textures saved to HDD: %d\n", std::distance(itMap, _cache.begin()));*/
|
|
||||||
}
|
|
||||||
gzclose(gzfp);
|
|
||||||
}
|
}
|
||||||
|
return _cache.empty();
|
||||||
CHDIR(curpath);
|
|
||||||
}
|
|
||||||
return _cache.empty();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean
|
boolean
|
||||||
TxCache::load(const wchar_t *path, const wchar_t *filename, int config)
|
TxCache::load(const wchar_t *path, const wchar_t *filename, int config)
|
||||||
{
|
{
|
||||||
/* find it on disk */
|
/* find it on disk */
|
||||||
CPath cbuf(stdstr().FromUTF16(path).c_str(),stdstr().FromUTF16(filename).c_str());
|
CPath cbuf(stdstr().FromUTF16(path).c_str(), stdstr().FromUTF16(filename).c_str());
|
||||||
|
|
||||||
gzFile gzfp = gzopen(cbuf, "rb");
|
gzFile gzfp = gzopen(cbuf, "rb");
|
||||||
DBG_INFO(80, L"gzfp:%x file:%ls\n", gzfp, filename);
|
DBG_INFO(80, L"gzfp:%x file:%ls\n", gzfp, filename);
|
||||||
if (gzfp) {
|
if (gzfp) {
|
||||||
/* yep, we have it. load it into memory cache. */
|
/* yep, we have it. load it into memory cache. */
|
||||||
int dataSize;
|
int dataSize;
|
||||||
uint64 checksum;
|
uint64 checksum;
|
||||||
GHQTexInfo tmpInfo;
|
GHQTexInfo tmpInfo;
|
||||||
int tmpconfig;
|
int tmpconfig;
|
||||||
/* read header to determine config match */
|
/* read header to determine config match */
|
||||||
gzread(gzfp, &tmpconfig, 4);
|
gzread(gzfp, &tmpconfig, 4);
|
||||||
|
|
||||||
if (tmpconfig == config) {
|
if (tmpconfig == config) {
|
||||||
do {
|
do {
|
||||||
memset(&tmpInfo, 0, sizeof(GHQTexInfo));
|
memset(&tmpInfo, 0, sizeof(GHQTexInfo));
|
||||||
|
|
||||||
gzread(gzfp, &checksum, 8);
|
gzread(gzfp, &checksum, 8);
|
||||||
|
|
||||||
gzread(gzfp, &tmpInfo.width, 4);
|
gzread(gzfp, &tmpInfo.width, 4);
|
||||||
gzread(gzfp, &tmpInfo.height, 4);
|
gzread(gzfp, &tmpInfo.height, 4);
|
||||||
gzread(gzfp, &tmpInfo.format, 2);
|
gzread(gzfp, &tmpInfo.format, 2);
|
||||||
|
|
||||||
gzread(gzfp, &tmpInfo.smallLodLog2, 4);
|
gzread(gzfp, &tmpInfo.smallLodLog2, 4);
|
||||||
gzread(gzfp, &tmpInfo.largeLodLog2, 4);
|
gzread(gzfp, &tmpInfo.largeLodLog2, 4);
|
||||||
gzread(gzfp, &tmpInfo.aspectRatioLog2, 4);
|
gzread(gzfp, &tmpInfo.aspectRatioLog2, 4);
|
||||||
|
|
||||||
gzread(gzfp, &tmpInfo.tiles, 4);
|
gzread(gzfp, &tmpInfo.tiles, 4);
|
||||||
gzread(gzfp, &tmpInfo.untiled_width, 4);
|
gzread(gzfp, &tmpInfo.untiled_width, 4);
|
||||||
gzread(gzfp, &tmpInfo.untiled_height, 4);
|
gzread(gzfp, &tmpInfo.untiled_height, 4);
|
||||||
|
|
||||||
gzread(gzfp, &tmpInfo.is_hires_tex, 1);
|
gzread(gzfp, &tmpInfo.is_hires_tex, 1);
|
||||||
|
|
||||||
gzread(gzfp, &dataSize, 4);
|
gzread(gzfp, &dataSize, 4);
|
||||||
|
|
||||||
tmpInfo.data = (uint8*)malloc(dataSize);
|
tmpInfo.data = (uint8*)malloc(dataSize);
|
||||||
if (tmpInfo.data) {
|
if (tmpInfo.data) {
|
||||||
gzread(gzfp, tmpInfo.data, dataSize);
|
gzread(gzfp, tmpInfo.data, dataSize);
|
||||||
|
|
||||||
/* add to memory cache */
|
/* add to memory cache */
|
||||||
add(checksum, &tmpInfo, (tmpInfo.format & GR_TEXFMT_GZ) ? dataSize : 0);
|
add(checksum, &tmpInfo, (tmpInfo.format & GR_TEXFMT_GZ) ? dataSize : 0);
|
||||||
|
|
||||||
free(tmpInfo.data);
|
free(tmpInfo.data);
|
||||||
} else {
|
}
|
||||||
gzseek(gzfp, dataSize, SEEK_CUR);
|
else {
|
||||||
|
gzseek(gzfp, dataSize, SEEK_CUR);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* skip in between to prevent the loop from being tied down to vsync */
|
||||||
|
if (_callback && (!(_cache.size() % 100) || gzeof(gzfp)))
|
||||||
|
(*_callback)(L"[%d] total mem:%.02fmb - %ls\n", _cache.size(), (float)_totalSize / 1000000, filename);
|
||||||
|
} while (!gzeof(gzfp));
|
||||||
|
gzclose(gzfp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* skip in between to prevent the loop from being tied down to vsync */
|
|
||||||
if (_callback && (!(_cache.size() % 100) || gzeof(gzfp)))
|
|
||||||
(*_callback)(L"[%d] total mem:%.02fmb - %ls\n", _cache.size(), (float)_totalSize/1000000, filename);
|
|
||||||
|
|
||||||
} while (!gzeof(gzfp));
|
|
||||||
gzclose(gzfp);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return !_cache.empty();
|
return !_cache.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean
|
boolean
|
||||||
TxCache::del(uint64 checksum)
|
TxCache::del(uint64 checksum)
|
||||||
{
|
{
|
||||||
if (!checksum || _cache.empty()) return 0;
|
if (!checksum || _cache.empty()) return 0;
|
||||||
|
|
||||||
std::map<uint64, TXCACHE*>::iterator itMap = _cache.find(checksum);
|
std::map<uint64, TXCACHE*>::iterator itMap = _cache.find(checksum);
|
||||||
if (itMap != _cache.end()) {
|
if (itMap != _cache.end()) {
|
||||||
|
/* for texture cache (not hi-res cache) */
|
||||||
|
if (!_cachelist.empty()) _cachelist.erase(((*itMap).second)->it);
|
||||||
|
|
||||||
/* for texture cache (not hi-res cache) */
|
/* remove from cache */
|
||||||
if (!_cachelist.empty()) _cachelist.erase(((*itMap).second)->it);
|
free((*itMap).second->info.data);
|
||||||
|
_totalSize -= (*itMap).second->size;
|
||||||
|
delete (*itMap).second;
|
||||||
|
_cache.erase(itMap);
|
||||||
|
|
||||||
/* remove from cache */
|
DBG_INFO(80, L"removed from cache: checksum = %08X %08X\n", (uint32)(checksum & 0xffffffff), (uint32)(checksum >> 32));
|
||||||
free((*itMap).second->info.data);
|
|
||||||
_totalSize -= (*itMap).second->size;
|
|
||||||
delete (*itMap).second;
|
|
||||||
_cache.erase(itMap);
|
|
||||||
|
|
||||||
DBG_INFO(80, L"removed from cache: checksum = %08X %08X\n", (uint32)(checksum & 0xffffffff), (uint32)(checksum >> 32));
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
return 1;
|
return 0;
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean
|
boolean
|
||||||
TxCache::is_cached(uint64 checksum)
|
TxCache::is_cached(uint64 checksum)
|
||||||
{
|
{
|
||||||
std::map<uint64, TXCACHE*>::iterator itMap = _cache.find(checksum);
|
std::map<uint64, TXCACHE*>::iterator itMap = _cache.find(checksum);
|
||||||
if (itMap != _cache.end()) return 1;
|
if (itMap != _cache.end()) return 1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
TxCache::clear()
|
TxCache::clear()
|
||||||
{
|
{
|
||||||
if (!_cache.empty()) {
|
if (!_cache.empty()) {
|
||||||
std::map<uint64, TXCACHE*>::iterator itMap = _cache.begin();
|
std::map<uint64, TXCACHE*>::iterator itMap = _cache.begin();
|
||||||
while (itMap != _cache.end()) {
|
while (itMap != _cache.end()) {
|
||||||
free((*itMap).second->info.data);
|
free((*itMap).second->info.data);
|
||||||
delete (*itMap).second;
|
delete (*itMap).second;
|
||||||
itMap++;
|
itMap++;
|
||||||
|
}
|
||||||
|
_cache.clear();
|
||||||
}
|
}
|
||||||
_cache.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!_cachelist.empty()) _cachelist.clear();
|
if (!_cachelist.empty()) _cachelist.clear();
|
||||||
|
|
||||||
_totalSize = 0;
|
_totalSize = 0;
|
||||||
}
|
}
|
Loading…
Reference in New Issue