mirror of
https://github.com/blawar/GLideN64.git
synced 2024-06-30 08:24:05 +00:00
File stream implementation of TxCache.
This commit is contained in:
parent
dee7065982
commit
b697393cab
|
@ -87,6 +87,9 @@ void Config::resetToDefaults()
|
|||
textureFilter.txCacheCompression = 1;
|
||||
textureFilter.txSaveCache = 1;
|
||||
|
||||
textureFilter.txEnhancedTextureFileStorage = 0;
|
||||
textureFilter.txHiresTextureFileStorage = 0;
|
||||
|
||||
api().GetUserDataPath(textureFilter.txPath);
|
||||
gln_wcscat(textureFilter.txPath, wst("/hires_texture"));
|
||||
api().GetUserCachePath(textureFilter.txCachePath);
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
#include "Types.h"
|
||||
|
||||
#define CONFIG_WITH_PROFILES 23U
|
||||
#define CONFIG_VERSION_CURRENT 26U
|
||||
#define CONFIG_VERSION_CURRENT 27U
|
||||
|
||||
#define BILINEAR_3POINT 0
|
||||
#define BILINEAR_STANDARD 1
|
||||
|
@ -147,6 +147,9 @@ struct Config
|
|||
u32 txCacheCompression; // Zip textures cache
|
||||
u32 txSaveCache; // Save texture cache to hard disk
|
||||
|
||||
u32 txEnhancedTextureFileStorage; // Use file storage instead of memory cache for enhanced textures.
|
||||
u32 txHiresTextureFileStorage; // Use file storage instead of memory cache for hires textures.
|
||||
|
||||
wchar_t txPath[PLUGIN_PATH_SIZE]; // Path to texture packs
|
||||
wchar_t txCachePath[PLUGIN_PATH_SIZE]; // Path to store texture cache, that is .htc files
|
||||
wchar_t txDumpPath[PLUGIN_PATH_SIZE]; // Path to store texture dumps
|
||||
|
|
|
@ -92,8 +92,9 @@ typedef unsigned char boolean;
|
|||
#define RICE_HIRESTEXTURES 0x00020000
|
||||
#define JABO_HIRESTEXTURES 0x00030000
|
||||
|
||||
//#define COMPRESS_TEX 0x00100000 // Not used anymore
|
||||
//#define COMPRESS_HIRESTEX 0x00200000 // Not used anymore
|
||||
#define FILE_CACHE_MASK 0x00300000
|
||||
#define FILE_TEXCACHE 0x00100000
|
||||
#define FILE_HIRESTEXCACHE 0x00200000
|
||||
#define GZ_TEXCACHE 0x00400000
|
||||
#define GZ_HIRESTEXCACHE 0x00800000
|
||||
#define DUMP_TEXCACHE 0x01000000
|
||||
|
@ -106,18 +107,13 @@ typedef unsigned char boolean;
|
|||
#define DUMP_TEX 0x80000000
|
||||
|
||||
struct GHQTexInfo {
|
||||
unsigned char *data;
|
||||
int width;
|
||||
int height;
|
||||
unsigned int format;
|
||||
unsigned short texture_format;
|
||||
unsigned short pixel_type;
|
||||
unsigned char is_hires_tex;
|
||||
|
||||
GHQTexInfo() :
|
||||
data(NULL), width(0), height(0), format(0),
|
||||
texture_format(0), pixel_type(0), is_hires_tex(0)
|
||||
{}
|
||||
unsigned char *data = nullptr;
|
||||
int width = 0;
|
||||
int height = 0;
|
||||
unsigned int format = 0;
|
||||
unsigned short texture_format = 0;
|
||||
unsigned short pixel_type = 0;
|
||||
unsigned char is_hires_tex = 0;
|
||||
};
|
||||
|
||||
/* Callback to display hires texture info.
|
||||
|
|
|
@ -25,13 +25,17 @@
|
|||
#pragma warning(disable: 4786)
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
#include "TxCache.h"
|
||||
#include "TxDbg.h"
|
||||
#include <osal_files.h>
|
||||
#include <fstream>
|
||||
#include <unordered_map>
|
||||
#include <zlib.h>
|
||||
#include <memory.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <osal_files.h>
|
||||
|
||||
#include "TxCache.h"
|
||||
#include "TxDbg.h"
|
||||
|
||||
class TxCacheImpl
|
||||
{
|
||||
|
@ -41,27 +45,33 @@ public:
|
|||
virtual bool add(Checksum checksum, GHQTexInfo *info, int dataSize = 0) = 0;
|
||||
virtual bool get(Checksum checksum, GHQTexInfo *info) = 0;
|
||||
virtual bool save(const wchar_t *path, const wchar_t *filename, const int config) = 0;
|
||||
virtual bool load(const wchar_t *path, const wchar_t *filename, const int config, boolean force) = 0;
|
||||
virtual bool load(const wchar_t *path, const wchar_t *filename, const int config, bool force) = 0;
|
||||
virtual bool del(Checksum checksum) = 0;
|
||||
virtual bool isCached(Checksum checksum) = 0;
|
||||
virtual void clear() = 0;
|
||||
virtual bool empty() const = 0;
|
||||
virtual uint32 getOptions() const = 0;
|
||||
virtual void setOptions(uint32 options) = 0;
|
||||
|
||||
virtual uint64 size() const = 0;
|
||||
virtual uint64 totalSize() const = 0;
|
||||
virtual uint64 cacheLimit() const = 0;
|
||||
};
|
||||
|
||||
|
||||
/************************** TxMemoryCache *************************************/
|
||||
|
||||
class TxMemoryCache : public TxCacheImpl
|
||||
{
|
||||
public:
|
||||
TxMemoryCache(uint32 & _options, uint64 cacheLimit, dispInfoFuncExt callback);
|
||||
~TxMemoryCache();
|
||||
|
||||
bool add(Checksum checksum, GHQTexInfo *info, int dataSize = 0) override;
|
||||
bool get(Checksum checksum, GHQTexInfo *info) override;
|
||||
|
||||
bool save(const wchar_t *path, const wchar_t *filename, const int config) override;
|
||||
bool load(const wchar_t *path, const wchar_t *filename, const int config, boolean force) override;
|
||||
bool load(const wchar_t *path, const wchar_t *filename, const int config, bool force) override;
|
||||
bool del(Checksum checksum) override;
|
||||
bool isCached(Checksum checksum) override;
|
||||
void clear() override;
|
||||
|
@ -70,6 +80,8 @@ public:
|
|||
uint64 size() const override { return _cache.size(); }
|
||||
uint64 totalSize() const override { return _totalSize; }
|
||||
uint64 cacheLimit() const override { return _cacheLimit; }
|
||||
uint32 getOptions() const override { return _options; }
|
||||
void setOptions(uint32 options) override { _options = options; }
|
||||
|
||||
private:
|
||||
struct TXCACHE {
|
||||
|
@ -78,7 +90,7 @@ private:
|
|||
std::list<uint64>::iterator it;
|
||||
};
|
||||
|
||||
uint32 & _options;
|
||||
uint32 _options;
|
||||
dispInfoFuncExt _callback;
|
||||
uint64 _cacheLimit;
|
||||
uint64 _totalSize;
|
||||
|
@ -115,6 +127,12 @@ TxMemoryCache::TxMemoryCache(uint32 & options,
|
|||
}
|
||||
}
|
||||
|
||||
TxMemoryCache::~TxMemoryCache()
|
||||
{
|
||||
/* free memory, clean up, etc */
|
||||
clear();
|
||||
}
|
||||
|
||||
bool TxMemoryCache::add(Checksum checksum, GHQTexInfo *info, int dataSize)
|
||||
{
|
||||
/* NOTE: dataSize must be provided if info->data is zlib compressed. */
|
||||
|
@ -147,7 +165,6 @@ bool TxMemoryCache::add(Checksum checksum, GHQTexInfo *info, int dataSize)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/* if cache size exceeds limit, remove old cache */
|
||||
if (_cacheLimit != 0) {
|
||||
_totalSize += dataSize;
|
||||
|
@ -342,7 +359,7 @@ bool TxMemoryCache::save(const wchar_t *path, const wchar_t *filename, int confi
|
|||
return !_cache.empty();
|
||||
}
|
||||
|
||||
bool TxMemoryCache::load(const wchar_t *path, const wchar_t *filename, int config, boolean force)
|
||||
bool TxMemoryCache::load(const wchar_t *path, const wchar_t *filename, int config, bool force)
|
||||
{
|
||||
/* find it on disk */
|
||||
char cbuf[MAX_PATH];
|
||||
|
@ -455,15 +472,396 @@ void TxMemoryCache::clear()
|
|||
_cache.clear();
|
||||
}
|
||||
|
||||
if (!_cachelist.empty()) _cachelist.clear();
|
||||
if (!_cachelist.empty())
|
||||
_cachelist.clear();
|
||||
|
||||
_totalSize = 0;
|
||||
}
|
||||
|
||||
/************************** TxFileCache *************************************/
|
||||
|
||||
class TxFileCache : public TxCacheImpl
|
||||
{
|
||||
public:
|
||||
TxFileCache(uint32 & _options, const wchar_t *cachePath, dispInfoFuncExt callback);
|
||||
~TxFileCache() = default;
|
||||
|
||||
bool add(Checksum checksum, GHQTexInfo *info, int dataSize = 0) override;
|
||||
bool get(Checksum checksum, GHQTexInfo *info) override;
|
||||
|
||||
bool save(const wchar_t *path, const wchar_t *filename, const int config) override;
|
||||
bool load(const wchar_t *path, const wchar_t *filename, const int config, bool force) override;
|
||||
bool del(Checksum checksum) override { return false; }
|
||||
bool isCached(Checksum checksum) override;
|
||||
void clear() override;
|
||||
bool empty() const override { return _cache.empty(); }
|
||||
|
||||
uint64 size() const override { return _cache.size(); }
|
||||
uint64 totalSize() const override { return _totalSize; }
|
||||
uint64 cacheLimit() const override { return 0UL; }
|
||||
uint32 getOptions() const override { return _options; }
|
||||
void setOptions(uint32 options) override { _options = options; }
|
||||
|
||||
private:
|
||||
bool open(bool forRead);
|
||||
bool writeData(uint32 destLen, const GHQTexInfo & info);
|
||||
bool readData(GHQTexInfo & info);
|
||||
void buildFullPath();
|
||||
|
||||
uint32 _options;
|
||||
tx_wstring _cachePath;
|
||||
tx_wstring _filename;
|
||||
std::string _fullPath;
|
||||
dispInfoFuncExt _callback;
|
||||
uint64 _totalSize = 0;
|
||||
|
||||
using CacheMap = std::unordered_map<uint64, int64>;
|
||||
CacheMap _cache;
|
||||
|
||||
uint8 *_gzdest0 = nullptr;
|
||||
uint8 *_gzdest1 = nullptr;
|
||||
uint32 _gzdestLen = 0;
|
||||
|
||||
std::ifstream _infile;
|
||||
std::ofstream _outfile;
|
||||
int64 _cachePos = 0;
|
||||
bool _dirty = false;
|
||||
static const int _fakeConfig;
|
||||
static const int64 _initialPos;
|
||||
};
|
||||
|
||||
const int TxFileCache::_fakeConfig = -1;
|
||||
const int64 TxFileCache::_initialPos = sizeof(int64) + sizeof(int);
|
||||
|
||||
TxFileCache::TxFileCache(uint32 & options,
|
||||
const wchar_t *cachePath,
|
||||
dispInfoFuncExt callback)
|
||||
: _options(options)
|
||||
, _callback(callback)
|
||||
{
|
||||
/* save path name */
|
||||
if (cachePath)
|
||||
_cachePath.assign(cachePath);
|
||||
|
||||
/* zlib memory buffers to (de)compress hires textures */
|
||||
if (_options & (GZ_TEXCACHE | GZ_HIRESTEXCACHE)) {
|
||||
_gzdest0 = TxMemBuf::getInstance()->get(0);
|
||||
_gzdest1 = TxMemBuf::getInstance()->get(1);
|
||||
_gzdestLen = (TxMemBuf::getInstance()->size_of(0) < TxMemBuf::getInstance()->size_of(1)) ?
|
||||
TxMemBuf::getInstance()->size_of(0) : TxMemBuf::getInstance()->size_of(1);
|
||||
|
||||
if (!_gzdest0 || !_gzdest1 || !_gzdestLen) {
|
||||
_options &= ~(GZ_TEXCACHE | GZ_HIRESTEXCACHE);
|
||||
_gzdest0 = nullptr;
|
||||
_gzdest1 = nullptr;
|
||||
_gzdestLen = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#define FWRITE(a) _outfile.write((char*)(&a), sizeof(a))
|
||||
#define FREAD(a) _infile.read((char*)(&a), sizeof(a))
|
||||
|
||||
void TxFileCache::buildFullPath()
|
||||
{
|
||||
char cbuf[MAX_PATH*2];
|
||||
tx_wstring filename = _cachePath + OSAL_DIR_SEPARATOR_STR + _filename;
|
||||
wcstombs(cbuf, filename.c_str(), MAX_PATH*2);
|
||||
_fullPath = cbuf;
|
||||
}
|
||||
|
||||
bool TxFileCache::open(bool forRead)
|
||||
{
|
||||
if (_infile.is_open())
|
||||
_infile.close();
|
||||
if (_outfile.is_open())
|
||||
_outfile.close();
|
||||
|
||||
if (forRead) {
|
||||
/* find it on disk */
|
||||
_infile.open(_fullPath, std::ifstream::in | std::ifstream::binary);
|
||||
DBG_INFO(80, wst("file:%s %s\n"), _fullPath.c_str(), _infile.good() ? "opened for read" : "failed to open");
|
||||
return _infile.good();
|
||||
}
|
||||
|
||||
if (osal_path_existsA(_fullPath.c_str()) != 0) {
|
||||
assert(_cachePos != 0L);
|
||||
_outfile.open(_fullPath, std::ofstream::out | std::ofstream::binary);
|
||||
DBG_INFO(80, wst("file:%s %s\n"), _fullPath.c_str(), _outfile.good() ? "opened for write" : "failed to open");
|
||||
return _outfile.good();
|
||||
}
|
||||
|
||||
if (osal_mkdirp(_cachePath.c_str()) != 0)
|
||||
return false;
|
||||
|
||||
_outfile.open(_fullPath, std::ofstream::out | std::ofstream::binary);
|
||||
DBG_INFO(80, wst("file:%s %s\n"), _fullPath.c_str(), _outfile.good() ? L"created for write" : L"failed to create");
|
||||
if (!_outfile.good())
|
||||
return false;
|
||||
|
||||
FWRITE(_fakeConfig);
|
||||
_cachePos = _initialPos;
|
||||
FWRITE(_cachePos);
|
||||
|
||||
return _outfile.good();
|
||||
}
|
||||
|
||||
void TxFileCache::clear()
|
||||
{
|
||||
if (empty() && osal_path_existsA(_fullPath.c_str()) == 0)
|
||||
return;
|
||||
|
||||
_cache.clear();
|
||||
_cachePos = 0UL;
|
||||
_dirty = false;
|
||||
|
||||
if (_infile.is_open())
|
||||
_infile.close();
|
||||
if (_outfile.is_open())
|
||||
_outfile.close();
|
||||
|
||||
_outfile.open(_fullPath, std::ofstream::out | std::ofstream::binary | std::ofstream::trunc);
|
||||
FWRITE(_fakeConfig);
|
||||
_cachePos = _initialPos;
|
||||
FWRITE(_cachePos);
|
||||
_outfile.close();
|
||||
}
|
||||
|
||||
bool TxFileCache::writeData(uint32 dataSize, const GHQTexInfo & info)
|
||||
{
|
||||
if (info.data == nullptr || dataSize == 0)
|
||||
return false;
|
||||
FWRITE(info.width);
|
||||
FWRITE(info.height);
|
||||
FWRITE(info.format);
|
||||
FWRITE(info.texture_format);
|
||||
FWRITE(info.pixel_type);
|
||||
FWRITE(info.is_hires_tex);
|
||||
FWRITE(dataSize);
|
||||
_outfile.write((char*)info.data, dataSize);
|
||||
return _outfile.good();
|
||||
}
|
||||
|
||||
bool TxFileCache::readData(GHQTexInfo & info)
|
||||
{
|
||||
FREAD(info.width);
|
||||
FREAD(info.height);
|
||||
FREAD(info.format);
|
||||
FREAD(info.texture_format);
|
||||
FREAD(info.pixel_type);
|
||||
FREAD(info.is_hires_tex);
|
||||
|
||||
uint32 dataSize = 0U;
|
||||
FREAD(dataSize);
|
||||
if (dataSize == 0)
|
||||
return false;
|
||||
|
||||
_infile.read((char*)_gzdest0, dataSize);
|
||||
if (!_infile.good())
|
||||
return false;
|
||||
|
||||
/* zlib decompress it */
|
||||
if (info.format & GL_TEXFMT_GZ) {
|
||||
uLongf destLen = _gzdestLen;
|
||||
if (uncompress(_gzdest1, &destLen, _gzdest0, dataSize) != Z_OK) {
|
||||
DBG_INFO(80, wst("Error: zlib decompression failed!\n"));
|
||||
return false;
|
||||
}
|
||||
info.data = _gzdest1;
|
||||
info.format &= ~GL_TEXFMT_GZ;
|
||||
DBG_INFO(80, wst("zlib decompressed: %.02gkb->%.02gkb\n"), dataSize / 1024.0, destLen / 1024.0);
|
||||
}
|
||||
else {
|
||||
info.data = _gzdest0;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TxFileCache::add(Checksum checksum, GHQTexInfo *info, int dataSize)
|
||||
{
|
||||
/* NOTE: dataSize must be provided if info->data is zlib compressed. */
|
||||
|
||||
if (!checksum || !info->data || _cache.find(checksum) != _cache.end())
|
||||
return false;
|
||||
|
||||
if (_infile.is_open() || !_outfile.is_open())
|
||||
if (!open(false))
|
||||
return false;
|
||||
|
||||
if (!_dirty) {
|
||||
// Make position of cache data invalid.
|
||||
// It will prevent attempts to load unsaved cache file.
|
||||
_outfile.seekp(sizeof(_options), std::ofstream::beg);
|
||||
int64 pos = -1;
|
||||
FWRITE(pos);
|
||||
}
|
||||
|
||||
uint8 *dest = info->data;
|
||||
uint32 format = info->format;
|
||||
|
||||
if (dataSize == 0) {
|
||||
dataSize = TxUtil::sizeofTx(info->width, info->height, info->format);
|
||||
|
||||
if (!dataSize)
|
||||
return false;
|
||||
|
||||
if (_options & (GZ_TEXCACHE | GZ_HIRESTEXCACHE)) {
|
||||
/* zlib compress it. compression level:1 (best speed) */
|
||||
uLongf destLen = _gzdestLen;
|
||||
dest = (dest == _gzdest0) ? _gzdest1 : _gzdest0;
|
||||
if (compress2(dest, &destLen, info->data, dataSize, 1) != Z_OK) {
|
||||
dest = info->data;
|
||||
DBG_INFO(80, wst("Error: zlib compression failed!\n"));
|
||||
}
|
||||
else {
|
||||
DBG_INFO(80, wst("zlib compressed: %.02fkb->%.02fkb\n"), dataSize / 1024.0, destLen / 1024.0);
|
||||
dataSize = destLen;
|
||||
format |= GL_TEXFMT_GZ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GHQTexInfo infoToWrite = *info;
|
||||
infoToWrite.data = dest;
|
||||
infoToWrite.format = format;
|
||||
|
||||
_outfile.seekp(_cachePos, std::ofstream::beg);
|
||||
assert(_cachePos == _outfile.tellp());
|
||||
|
||||
_cache.insert(CacheMap::value_type(checksum._checksum, _cachePos));
|
||||
if (!writeData(dataSize, infoToWrite))
|
||||
return false;
|
||||
_cachePos = _outfile.tellp();
|
||||
_dirty = true;
|
||||
|
||||
#ifdef DEBUG
|
||||
DBG_INFO(80, wst("[%5d] added!! crc:%08X %08X %d x %d gfmt:%x total:%.02fmb\n"),
|
||||
_cache.size(), checksum._hi, checksum._low,
|
||||
info->width, info->height, info->format & 0xffff, (double)(_totalSize / 1024) / 1024.0);
|
||||
#endif
|
||||
|
||||
/* total cache size */
|
||||
_totalSize += dataSize;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TxFileCache::get(Checksum checksum, GHQTexInfo *info)
|
||||
{
|
||||
if (!checksum || _cache.empty())
|
||||
return false;
|
||||
|
||||
/* find a match in cache */
|
||||
auto itMap = _cache.find(checksum);
|
||||
if (itMap == _cache.end())
|
||||
return false;
|
||||
|
||||
if (_outfile.is_open() || !_infile.is_open())
|
||||
if (!open(true))
|
||||
return false;
|
||||
|
||||
_infile.seekg(itMap->second, std::ifstream::beg);
|
||||
return readData(*info);
|
||||
}
|
||||
|
||||
bool TxFileCache::save(const wchar_t *path, const wchar_t *filename, int config)
|
||||
{
|
||||
assert(_cachePath == path);
|
||||
if (_filename.empty()) {
|
||||
_filename = filename;
|
||||
buildFullPath();
|
||||
} else
|
||||
assert(_filename == filename);
|
||||
|
||||
if (!_dirty)
|
||||
return true;
|
||||
|
||||
if (_cache.empty() || _cachePos == 0UL)
|
||||
return false;
|
||||
|
||||
if (_infile.is_open() || !_outfile.is_open())
|
||||
if (!open(false))
|
||||
return false;
|
||||
|
||||
_outfile.seekp(0L, std::ofstream::beg);
|
||||
|
||||
FWRITE(config);
|
||||
FWRITE(_cachePos);
|
||||
_outfile.seekp(_cachePos, std::ofstream::beg);
|
||||
int cacheSize = static_cast<int>(_cache.size());
|
||||
FWRITE(cacheSize);
|
||||
if (_callback)
|
||||
(*_callback)(wst("Saving texture storage...\n"));
|
||||
for (auto& item : _cache) {
|
||||
FWRITE(item.first);
|
||||
FWRITE(item.second);
|
||||
}
|
||||
_outfile.close();
|
||||
if (_callback)
|
||||
(*_callback)(wst("Done\n"));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TxFileCache::load(const wchar_t *path, const wchar_t *filename, int config, bool force)
|
||||
{
|
||||
assert(_cachePath == path);
|
||||
if (_filename.empty()) {
|
||||
_filename = filename;
|
||||
buildFullPath();
|
||||
} else
|
||||
assert(_filename == filename);
|
||||
|
||||
if (_outfile.is_open() || !_infile.is_open())
|
||||
if (!open(true))
|
||||
return false;
|
||||
|
||||
int tmpconfig = 0;
|
||||
/* read header to determine config match */
|
||||
_infile.seekg(0L, std::ifstream::beg);
|
||||
FREAD(tmpconfig);
|
||||
FREAD(_cachePos);
|
||||
if (tmpconfig == _fakeConfig) {
|
||||
if (_cachePos != _initialPos)
|
||||
return false;
|
||||
} else if (tmpconfig != config && !force)
|
||||
return false;
|
||||
|
||||
if (_cachePos <= sizeof(config) + sizeof(_cachePos))
|
||||
return false;
|
||||
_infile.seekg(_cachePos, std::ifstream::beg);
|
||||
|
||||
int cacheSize = 0;
|
||||
FREAD(cacheSize);
|
||||
if (cacheSize <= 0)
|
||||
return false;
|
||||
|
||||
if (_callback)
|
||||
(*_callback)(wst("Loading texture storage...\n"));
|
||||
uint64 key;
|
||||
int64 value;
|
||||
for (int i = 0; i < cacheSize; ++i) {
|
||||
FREAD(key);
|
||||
FREAD(value);
|
||||
_cache.insert(CacheMap::value_type(key, value));
|
||||
}
|
||||
if (_callback)
|
||||
(*_callback)(wst("Done\n"));
|
||||
|
||||
_dirty = false;
|
||||
return !_cache.empty();
|
||||
}
|
||||
|
||||
bool TxFileCache::isCached(Checksum checksum)
|
||||
{
|
||||
return _cache.find(checksum) != _cache.end();
|
||||
}
|
||||
|
||||
/************************** TxCache *************************************/
|
||||
|
||||
TxCache::~TxCache()
|
||||
{
|
||||
/* free memory, clean up, etc */
|
||||
clear();
|
||||
}
|
||||
|
||||
TxCache::TxCache(uint32 options,
|
||||
|
@ -471,8 +869,7 @@ TxCache::TxCache(uint32 options,
|
|||
const wchar_t *cachePath,
|
||||
const wchar_t *ident,
|
||||
dispInfoFuncExt callback)
|
||||
: _options(options)
|
||||
, _callback(callback)
|
||||
: _callback(callback)
|
||||
{
|
||||
/* save path name */
|
||||
if (cachePath)
|
||||
|
@ -482,7 +879,10 @@ TxCache::TxCache(uint32 options,
|
|||
if (ident)
|
||||
_ident.assign(ident);
|
||||
|
||||
_pImpl.reset(new TxMemoryCache(_options, cachesize, _callback));
|
||||
if ((options & FILE_CACHE_MASK) == 0)
|
||||
_pImpl.reset(new TxMemoryCache(options, cachesize, _callback));
|
||||
else
|
||||
_pImpl.reset(new TxFileCache(options, cachePath, _callback));
|
||||
}
|
||||
|
||||
bool TxCache::add(Checksum checksum, GHQTexInfo *info, int dataSize)
|
||||
|
@ -510,22 +910,22 @@ uint64 TxCache::cacheLimit() const
|
|||
return _pImpl->cacheLimit();
|
||||
}
|
||||
|
||||
boolean TxCache::save(const wchar_t *path, const wchar_t *filename, const int config)
|
||||
bool TxCache::save()
|
||||
{
|
||||
return _pImpl->save(path, filename, config);
|
||||
return _pImpl->save(_cachePath.c_str(), _getFileName().c_str(), _getConfig());
|
||||
}
|
||||
|
||||
boolean TxCache::load(const wchar_t *path, const wchar_t *filename, const int config, boolean force)
|
||||
bool TxCache::load(bool force)
|
||||
{
|
||||
return _pImpl->load(path, filename, config, force);
|
||||
return _pImpl->load(_cachePath.c_str(), _getFileName().c_str(), _getConfig(), force);
|
||||
}
|
||||
|
||||
boolean TxCache::del(Checksum checksum)
|
||||
bool TxCache::del(Checksum checksum)
|
||||
{
|
||||
return _pImpl->del(checksum);
|
||||
}
|
||||
|
||||
boolean TxCache::isCached(Checksum checksum)
|
||||
bool TxCache::isCached(Checksum checksum)
|
||||
{
|
||||
return _pImpl->isCached(checksum);
|
||||
}
|
||||
|
@ -539,3 +939,13 @@ bool TxCache::empty() const
|
|||
{
|
||||
return _pImpl->empty();
|
||||
}
|
||||
|
||||
uint32 TxCache::getOptions() const
|
||||
{
|
||||
return _pImpl->getOptions();
|
||||
}
|
||||
|
||||
void TxCache::setOptions(uint32 options)
|
||||
{
|
||||
_pImpl->setOptions(options);
|
||||
}
|
||||
|
|
|
@ -60,24 +60,27 @@ private:
|
|||
std::unique_ptr<TxCacheImpl> _pImpl;
|
||||
|
||||
protected:
|
||||
uint32 _options;
|
||||
tx_wstring _ident;
|
||||
tx_wstring _cachePath;
|
||||
dispInfoFuncExt _callback;
|
||||
|
||||
boolean save(const wchar_t *path, const wchar_t *filename, const int config);
|
||||
boolean load(const wchar_t *path, const wchar_t *filename, const int config, boolean force);
|
||||
boolean del(Checksum checksum); /* checksum hi:palette low:texture */
|
||||
boolean isCached(Checksum checksum); /* checksum hi:palette low:texture */
|
||||
bool save();
|
||||
bool load(bool force);
|
||||
bool del(Checksum checksum); /* checksum hi:palette low:texture */
|
||||
bool isCached(Checksum checksum); /* checksum hi:palette low:texture */
|
||||
void clear();
|
||||
uint64 size() const; // number of elements
|
||||
uint64 totalSize() const; // size of elements in bytes
|
||||
uint64 cacheLimit() const;
|
||||
uint32 getOptions() const;
|
||||
void setOptions(uint32 options);
|
||||
|
||||
virtual tx_wstring _getFileName() const = 0;
|
||||
virtual int _getConfig() const = 0;
|
||||
|
||||
public:
|
||||
~TxCache();
|
||||
TxCache(uint32 options, uint64 cacheLimit, const wchar_t *cachePath, const wchar_t *ident,
|
||||
dispInfoFuncExt callback);
|
||||
virtual ~TxCache();
|
||||
TxCache(uint32 options, uint64 cacheLimit, const wchar_t *cachePath, const wchar_t *ident, dispInfoFuncExt callback);
|
||||
bool add(Checksum checksum, GHQTexInfo *info, int dataSize = 0);
|
||||
bool get(Checksum checksum, GHQTexInfo *info);
|
||||
bool empty() const;
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -41,11 +41,11 @@ private:
|
|||
int _maxwidth;
|
||||
int _maxheight;
|
||||
int _maxbpp;
|
||||
boolean _cacheDumped;
|
||||
boolean _abortLoad;
|
||||
TxImage *_txImage;
|
||||
TxQuantize *_txQuantize;
|
||||
TxReSample *_txReSample;
|
||||
bool _abortLoad;
|
||||
bool _cacheDumped;
|
||||
std::unique_ptr<TxImage> _txImage;
|
||||
std::unique_ptr<TxQuantize> _txQuantize;
|
||||
std::unique_ptr<TxReSample> _txReSample;
|
||||
tx_wstring _texPackPath;
|
||||
enum LoadResult {
|
||||
resOk,
|
||||
|
@ -53,9 +53,9 @@ private:
|
|||
resError
|
||||
};
|
||||
LoadResult loadHiResTextures(const wchar_t * dir_path, boolean replace);
|
||||
tx_wstring _getFileName() const;
|
||||
int _getConfig() const;
|
||||
boolean _HiResTexPackPathExists() const;
|
||||
tx_wstring _getFileName() const override;
|
||||
int _getConfig() const override;
|
||||
|
||||
public:
|
||||
~TxHiResCache();
|
||||
|
@ -67,7 +67,7 @@ public:
|
|||
const wchar_t *texPackPath,
|
||||
const wchar_t *ident,
|
||||
dispInfoFuncExt callback);
|
||||
boolean load(boolean replace);
|
||||
bool load(boolean replace);
|
||||
void dump();
|
||||
};
|
||||
|
||||
|
|
|
@ -30,52 +30,60 @@
|
|||
#include <osal_files.h>
|
||||
#include <zlib.h>
|
||||
|
||||
#define TEXCACHE_DUMP_ENABLED (FILE_TEXCACHE|DUMP_TEXCACHE)
|
||||
|
||||
TxTexCache::~TxTexCache()
|
||||
{
|
||||
}
|
||||
|
||||
TxTexCache::TxTexCache(int options, int cachesize, const wchar_t *cachePath, const wchar_t *ident,
|
||||
dispInfoFuncExt callback
|
||||
) : TxCache((options & ~GZ_HIRESTEXCACHE), cachesize, cachePath, ident, callback)
|
||||
dispInfoFuncExt callback)
|
||||
: TxCache((options & ~(GZ_HIRESTEXCACHE | FILE_HIRESTEXCACHE)), cachesize, cachePath, ident, callback)
|
||||
, _cacheDumped(false)
|
||||
{
|
||||
/* assert local options */
|
||||
if (_cachePath.empty() || _ident.empty())
|
||||
_options &= ~DUMP_TEXCACHE;
|
||||
setOptions(getOptions() & ~TEXCACHE_DUMP_ENABLED);
|
||||
|
||||
_cacheDumped = 0;
|
||||
|
||||
if (_options & DUMP_TEXCACHE) {
|
||||
if (getOptions() & TEXCACHE_DUMP_ENABLED) {
|
||||
/* find it on disk */
|
||||
_cacheDumped = TxCache::load(_cachePath.c_str(), _getFileName().c_str(), _getConfig(), 0);
|
||||
_cacheDumped = TxCache::load(false);
|
||||
if (!_cacheDumped)
|
||||
TxCache::clear();
|
||||
}
|
||||
}
|
||||
|
||||
boolean
|
||||
TxTexCache::add(uint64 checksum, GHQTexInfo *info)
|
||||
bool TxTexCache::add(uint64 checksum, GHQTexInfo *info)
|
||||
{
|
||||
const boolean res = TxCache::add(checksum, info);
|
||||
const bool res = TxCache::add(checksum, info);
|
||||
if (res)
|
||||
_cacheDumped = 0;
|
||||
_cacheDumped = false;
|
||||
return res;
|
||||
}
|
||||
|
||||
void
|
||||
TxTexCache::dump()
|
||||
{
|
||||
if ((_options & DUMP_TEXCACHE) && !_cacheDumped) {
|
||||
if ((getOptions() & TEXCACHE_DUMP_ENABLED) && !_cacheDumped) {
|
||||
/* dump cache to disk */
|
||||
_cacheDumped = TxCache::save(_cachePath.c_str(), _getFileName().c_str(), _getConfig());
|
||||
_cacheDumped = TxCache::save();
|
||||
}
|
||||
}
|
||||
|
||||
tx_wstring TxTexCache::_getFileName() const
|
||||
{
|
||||
tx_wstring filename = _ident + wst("_MEMORYCACHE.") + TEXCACHE_EXT;
|
||||
tx_wstring filename = _ident + wst("_MEMORYCACHE.");
|
||||
filename += ((getOptions() & FILE_TEXCACHE) == 0) ? TEXCACHE_EXT : TEXSTREAM_EXT;
|
||||
removeColon(filename);
|
||||
return filename;
|
||||
}
|
||||
|
||||
int TxTexCache::_getConfig() const
|
||||
{
|
||||
return _options & (FILTER_MASK | ENHANCEMENT_MASK | FORCE16BPP_TEX | GZ_TEXCACHE);
|
||||
return getOptions() &
|
||||
(FILTER_MASK |
|
||||
ENHANCEMENT_MASK |
|
||||
FORCE16BPP_TEX |
|
||||
FILE_TEXCACHE |
|
||||
GZ_TEXCACHE);
|
||||
}
|
||||
|
|
|
@ -29,17 +29,15 @@
|
|||
class TxTexCache : public TxCache
|
||||
{
|
||||
private:
|
||||
boolean _cacheDumped;
|
||||
bool _cacheDumped;
|
||||
|
||||
tx_wstring _getFileName() const;
|
||||
int _getConfig() const;
|
||||
tx_wstring _getFileName() const override;
|
||||
int _getConfig() const override;
|
||||
|
||||
public:
|
||||
~TxTexCache();
|
||||
TxTexCache(int options, int cachesize, const wchar_t *cachePath, const wchar_t *ident,
|
||||
dispInfoFuncExt callback);
|
||||
boolean add(uint64 checksum, /* checksum hi:palette low:texture */
|
||||
GHQTexInfo *info);
|
||||
TxTexCache(int options, int cachesize, const wchar_t *cachePath, const wchar_t *ident, dispInfoFuncExt callback);
|
||||
bool add(uint64 checksum /* checksum hi:palette low:texture */, GHQTexInfo *info);
|
||||
void dump();
|
||||
};
|
||||
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
|
||||
/* extension for cache files */
|
||||
#define TEXCACHE_EXT wst("htc")
|
||||
#define TEXSTREAM_EXT wst("hts")
|
||||
|
||||
#include <vector>
|
||||
|
||||
|
|
|
@ -53,10 +53,12 @@ private:
|
|||
#define removeColon(A)
|
||||
#else
|
||||
|
||||
#define tx_wstring std::wstring
|
||||
#define tx_swprintf swprintf
|
||||
#define wst(A) L##A
|
||||
#define wccmp(A, B) A[0] == B[0]
|
||||
|
||||
typedef std::wstring tx_wstring;
|
||||
|
||||
inline
|
||||
void removeColon(tx_wstring& _s)
|
||||
{
|
||||
|
|
|
@ -59,6 +59,10 @@ u32 TextureFilterHandler::_getConfigOptions() const
|
|||
options |= DUMP_TEX;
|
||||
if (config.textureFilter.txDeposterize)
|
||||
options |= DEPOSTERIZE;
|
||||
if (config.textureFilter.txEnhancedTextureFileStorage)
|
||||
options |= FILE_TEXCACHE;
|
||||
if (config.textureFilter.txHiresTextureFileStorage)
|
||||
options |= FILE_HIRESTEXCACHE;
|
||||
return options;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user