mirror of
https://github.com/blawar/GLideN64.git
synced 2024-06-30 08:24:05 +00:00
Add support for HD textures, which have the same checksum but different format or size.
See #2569 for details.
This commit is contained in:
parent
555fbac213
commit
58faa2874a
|
@ -37,17 +37,19 @@
|
||||||
#include "TxCache.h"
|
#include "TxCache.h"
|
||||||
#include "TxDbg.h"
|
#include "TxDbg.h"
|
||||||
|
|
||||||
|
#define TXCACHE_FORMAT_VERSION UNDEFINED_1
|
||||||
|
|
||||||
class TxCacheImpl
|
class TxCacheImpl
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual ~TxCacheImpl() = default;
|
virtual ~TxCacheImpl() = default;
|
||||||
|
|
||||||
virtual bool add(Checksum checksum, GHQTexInfo *info, int dataSize = 0) = 0;
|
virtual bool add(Checksum checksum, GHQTexInfo *info, int dataSize = 0) = 0;
|
||||||
virtual bool get(Checksum checksum, GHQTexInfo *info) = 0;
|
virtual bool get(Checksum checksum, N64FormatSize n64FmtSz, GHQTexInfo *info) = 0;
|
||||||
virtual bool save(const wchar_t *path, const wchar_t *filename, const int config) = 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, bool 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 del(Checksum checksum) = 0;
|
||||||
virtual bool isCached(Checksum checksum) = 0;
|
virtual bool isCached(Checksum checksum, N64FormatSize n64FmtSz) const = 0;
|
||||||
virtual void clear() = 0;
|
virtual void clear() = 0;
|
||||||
virtual bool empty() const = 0;
|
virtual bool empty() const = 0;
|
||||||
virtual uint32 getOptions() const = 0;
|
virtual uint32 getOptions() const = 0;
|
||||||
|
@ -68,12 +70,12 @@ public:
|
||||||
~TxMemoryCache();
|
~TxMemoryCache();
|
||||||
|
|
||||||
bool add(Checksum checksum, GHQTexInfo *info, int dataSize = 0) override;
|
bool add(Checksum checksum, GHQTexInfo *info, int dataSize = 0) override;
|
||||||
bool get(Checksum checksum, GHQTexInfo *info) override;
|
bool get(Checksum checksum, N64FormatSize n64FmtSz, GHQTexInfo *info) override;
|
||||||
|
|
||||||
bool save(const wchar_t *path, const wchar_t *filename, const int config) 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 load(const wchar_t *path, const wchar_t *filename, const int config, bool force) override;
|
||||||
bool del(Checksum checksum) override;
|
bool del(Checksum checksum) override;
|
||||||
bool isCached(Checksum checksum) override;
|
bool isCached(Checksum checksum, N64FormatSize n64FmtSz) const override;
|
||||||
void clear() override;
|
void clear() override;
|
||||||
bool empty() const override { return _cache.empty(); }
|
bool empty() const override { return _cache.empty(); }
|
||||||
|
|
||||||
|
@ -95,12 +97,15 @@ private:
|
||||||
uint64 _cacheLimit;
|
uint64 _cacheLimit;
|
||||||
uint64 _totalSize;
|
uint64 _totalSize;
|
||||||
|
|
||||||
std::map<uint64, TXCACHE*> _cache;
|
using Cache = std::multimap<uint64, TXCACHE*>;
|
||||||
|
Cache _cache;
|
||||||
|
Cache::const_iterator find(Checksum checksum, N64FormatSize n64FmtSz) const;
|
||||||
std::list<uint64> _cachelist;
|
std::list<uint64> _cachelist;
|
||||||
|
|
||||||
uint8 *_gzdest0 = nullptr;
|
uint8 *_gzdest0 = nullptr;
|
||||||
uint8 *_gzdest1 = nullptr;
|
uint8 *_gzdest1 = nullptr;
|
||||||
uint32 _gzdestLen = 0;
|
uint32 _gzdestLen = 0;
|
||||||
|
bool _isOldVersion = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
TxMemoryCache::TxMemoryCache(uint32 options,
|
TxMemoryCache::TxMemoryCache(uint32 options,
|
||||||
|
@ -133,11 +138,11 @@ TxMemoryCache::~TxMemoryCache()
|
||||||
clear();
|
clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TxMemoryCache::add(Checksum checksum, GHQTexInfo *info, int dataSize)
|
bool TxMemoryCache::add(Checksum 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 || _cache.find(checksum) != _cache.end())
|
if (!checksum || !info->data || find(checksum, info->n64_format_size) != _cache.end())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
uint8 *dest = info->data;
|
uint8 *dest = info->data;
|
||||||
|
@ -206,7 +211,7 @@ bool TxMemoryCache::add(Checksum checksum, GHQTexInfo *info, int dataSize)
|
||||||
memcpy(tmpdata, dest, dataSize);
|
memcpy(tmpdata, dest, dataSize);
|
||||||
|
|
||||||
/* copy it */
|
/* copy it */
|
||||||
memcpy(&txCache->info, info, sizeof(GHQTexInfo));
|
txCache->info = *info;
|
||||||
txCache->info.data = tmpdata;
|
txCache->info.data = tmpdata;
|
||||||
txCache->info.format = format;
|
txCache->info.format = format;
|
||||||
txCache->size = dataSize;
|
txCache->size = dataSize;
|
||||||
|
@ -221,7 +226,7 @@ bool TxMemoryCache::add(Checksum checksum, GHQTexInfo *info, int dataSize)
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
DBG_INFO(80, wst("[%5d] added!! crc:%08X %08X %d x %d gfmt:%x total:%.02fmb\n"),
|
DBG_INFO(80, wst("[%5d] added!! crc:%08X %08X %d x %d gfmt:%x total:%.02fmb\n"),
|
||||||
_cache.size(), checksum._hi, checksum._low,
|
_cache.size(), checksum._palette, checksum._texture,
|
||||||
info->width, info->height, info->format & 0xffff, (double)_totalSize / 1000000);
|
info->width, info->height, info->format & 0xffff, (double)_totalSize / 1000000);
|
||||||
|
|
||||||
if (_cacheLimit != 0) {
|
if (_cacheLimit != 0) {
|
||||||
|
@ -239,41 +244,53 @@ bool TxMemoryCache::add(Checksum checksum, GHQTexInfo *info, int dataSize)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TxMemoryCache::get(Checksum checksum, GHQTexInfo *info)
|
TxMemoryCache::Cache::const_iterator TxMemoryCache::find(Checksum checksum, N64FormatSize n64FmtSz) const
|
||||||
|
{
|
||||||
|
if (_isOldVersion)
|
||||||
|
return _cache.find(checksum);
|
||||||
|
|
||||||
|
auto range = _cache.equal_range(checksum);
|
||||||
|
for (auto it = range.first; it != range.second; ++it) {
|
||||||
|
if (it->second->info.n64_format_size.formatsize() == n64FmtSz.formatsize())
|
||||||
|
return it;
|
||||||
|
}
|
||||||
|
return _cache.cend();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TxMemoryCache::get(Checksum checksum, N64FormatSize n64FmtSz, GHQTexInfo *info)
|
||||||
{
|
{
|
||||||
if (!checksum || _cache.empty())
|
if (!checksum || _cache.empty())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
/* find a match in cache */
|
/* find a match in cache */
|
||||||
auto itMap = _cache.find(checksum);
|
auto itMap = find(checksum, n64FmtSz);
|
||||||
if (itMap != _cache.end()) {
|
if (itMap == _cache.end())
|
||||||
/* yep, we've got it. */
|
return false;
|
||||||
memcpy(info, &(((*itMap).second)->info), sizeof(GHQTexInfo));
|
|
||||||
|
|
||||||
/* push it to the back of the list */
|
/* yep, we've got it. */
|
||||||
if (_cacheLimit != 0) {
|
*info = ((*itMap).second)->info;
|
||||||
_cachelist.erase(((*itMap).second)->it);
|
|
||||||
_cachelist.push_back(checksum);
|
|
||||||
((*itMap).second)->it = --(_cachelist.end());
|
|
||||||
}
|
|
||||||
|
|
||||||
/* zlib decompress it */
|
/* push it to the back of the list */
|
||||||
if (info->format & GL_TEXFMT_GZ) {
|
if (_cacheLimit != 0) {
|
||||||
uLongf destLen = _gzdestLen;
|
_cachelist.erase(((*itMap).second)->it);
|
||||||
uint8 *dest = (_gzdest0 == info->data) ? _gzdest1 : _gzdest0;
|
_cachelist.push_back(checksum);
|
||||||
if (uncompress(dest, &destLen, info->data, ((*itMap).second)->size) != Z_OK) {
|
((*itMap).second)->it = --(_cachelist.end());
|
||||||
DBG_INFO(80, wst("Error: zlib decompression failed!\n"));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
info->data = dest;
|
|
||||||
info->format &= ~GL_TEXFMT_GZ;
|
|
||||||
DBG_INFO(80, wst("zlib decompressed: %.02fkb->%.02fkb\n"), (float)(((*itMap).second)->size) / 1000, (float)destLen / 1000);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
/* zlib decompress it */
|
||||||
|
if (info->format & GL_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, wst("Error: zlib decompression failed!\n"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
info->data = dest;
|
||||||
|
info->format &= ~GL_TEXFMT_GZ;
|
||||||
|
DBG_INFO(80, wst("zlib decompressed: %.02fkb->%.02fkb\n"), (float)(((*itMap).second)->size) / 1000, (float)destLen / 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TxMemoryCache::save(const wchar_t *path, const wchar_t *filename, int config)
|
bool TxMemoryCache::save(const wchar_t *path, const wchar_t *filename, int config)
|
||||||
|
@ -302,6 +319,10 @@ bool TxMemoryCache::save(const wchar_t *path, const wchar_t *filename, int confi
|
||||||
gzFile gzfp = gzopen(cbuf, "wb1");
|
gzFile gzfp = gzopen(cbuf, "wb1");
|
||||||
DBG_INFO(80, wst("gzfp:%x file:%ls\n"), gzfp, filename);
|
DBG_INFO(80, wst("gzfp:%x file:%ls\n"), gzfp, filename);
|
||||||
if (gzfp) {
|
if (gzfp) {
|
||||||
|
/* write current version */
|
||||||
|
int version = TXCACHE_FORMAT_VERSION;
|
||||||
|
gzwrite(gzfp, &version, 4);
|
||||||
|
|
||||||
/* write header to determine config match */
|
/* write header to determine config match */
|
||||||
gzwrite(gzfp, &config, 4);
|
gzwrite(gzfp, &config, 4);
|
||||||
|
|
||||||
|
@ -340,6 +361,7 @@ bool TxMemoryCache::save(const wchar_t *path, const wchar_t *filename, int confi
|
||||||
gzwrite(gzfp, &((*itMap).second->info.texture_format), 2);
|
gzwrite(gzfp, &((*itMap).second->info.texture_format), 2);
|
||||||
gzwrite(gzfp, &((*itMap).second->info.pixel_type), 2);
|
gzwrite(gzfp, &((*itMap).second->info.pixel_type), 2);
|
||||||
gzwrite(gzfp, &((*itMap).second->info.is_hires_tex), 1);
|
gzwrite(gzfp, &((*itMap).second->info.is_hires_tex), 1);
|
||||||
|
gzwrite(gzfp, &((*itMap).second->info.n64_format_size._formatsize), 2);
|
||||||
|
|
||||||
gzwrite(gzfp, &destLen, 4);
|
gzwrite(gzfp, &destLen, 4);
|
||||||
gzwrite(gzfp, dest, destLen);
|
gzwrite(gzfp, dest, destLen);
|
||||||
|
@ -382,9 +404,19 @@ bool TxMemoryCache::load(const wchar_t *path, const wchar_t *filename, int confi
|
||||||
/* 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;
|
||||||
int tmpconfig;
|
|
||||||
/* read header to determine config match */
|
int version = 0;
|
||||||
gzread(gzfp, &tmpconfig, 4);
|
int tmpconfig = 0;
|
||||||
|
/* read version */
|
||||||
|
gzread(gzfp, &version, 4);
|
||||||
|
if (version == TXCACHE_FORMAT_VERSION) {
|
||||||
|
_isOldVersion = false;
|
||||||
|
/* read header to determine config match */
|
||||||
|
gzread(gzfp, &tmpconfig, 4);
|
||||||
|
} else {
|
||||||
|
_isOldVersion = true;
|
||||||
|
tmpconfig = version;
|
||||||
|
}
|
||||||
|
|
||||||
if (tmpconfig == config || force) {
|
if (tmpconfig == config || force) {
|
||||||
do {
|
do {
|
||||||
|
@ -398,6 +430,8 @@ bool TxMemoryCache::load(const wchar_t *path, const wchar_t *filename, int confi
|
||||||
gzread(gzfp, &tmpInfo.texture_format, 2);
|
gzread(gzfp, &tmpInfo.texture_format, 2);
|
||||||
gzread(gzfp, &tmpInfo.pixel_type, 2);
|
gzread(gzfp, &tmpInfo.pixel_type, 2);
|
||||||
gzread(gzfp, &tmpInfo.is_hires_tex, 1);
|
gzread(gzfp, &tmpInfo.is_hires_tex, 1);
|
||||||
|
if (!_isOldVersion)
|
||||||
|
gzread(gzfp, &tmpInfo.n64_format_size._formatsize, 2);
|
||||||
|
|
||||||
gzread(gzfp, &dataSize, 4);
|
gzread(gzfp, &dataSize, 4);
|
||||||
|
|
||||||
|
@ -445,7 +479,7 @@ bool TxMemoryCache::del(Checksum checksum)
|
||||||
delete (*itMap).second;
|
delete (*itMap).second;
|
||||||
_cache.erase(itMap);
|
_cache.erase(itMap);
|
||||||
|
|
||||||
DBG_INFO(80, wst("removed from cache: checksum = %08X %08X\n"), checksum._low, checksum._hi);
|
DBG_INFO(80, wst("removed from cache: checksum = %08X %08X\n"), checksum._palette, checksum._texture);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -453,9 +487,9 @@ bool TxMemoryCache::del(Checksum checksum)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TxMemoryCache::isCached(Checksum checksum)
|
bool TxMemoryCache::isCached(Checksum checksum, N64FormatSize n64FmtSz) const
|
||||||
{
|
{
|
||||||
return _cache.find(checksum) != _cache.end();
|
return find(checksum, n64FmtSz) != _cache.cend();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TxMemoryCache::clear()
|
void TxMemoryCache::clear()
|
||||||
|
@ -485,12 +519,12 @@ public:
|
||||||
~TxFileStorage() = default;
|
~TxFileStorage() = default;
|
||||||
|
|
||||||
bool add(Checksum checksum, GHQTexInfo *info, int dataSize = 0) override;
|
bool add(Checksum checksum, GHQTexInfo *info, int dataSize = 0) override;
|
||||||
bool get(Checksum checksum, GHQTexInfo *info) override;
|
bool get(Checksum checksum, N64FormatSize n64FmtSz, GHQTexInfo *info) override;
|
||||||
|
|
||||||
bool save(const wchar_t *path, const wchar_t *filename, const int config) 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 load(const wchar_t *path, const wchar_t *filename, const int config, bool force) override;
|
||||||
bool del(Checksum checksum) override { return false; }
|
bool del(Checksum checksum) override { return false; }
|
||||||
bool isCached(Checksum checksum) override;
|
bool isCached(Checksum checksum, N64FormatSize n64FmtSz) const override;
|
||||||
void clear() override;
|
void clear() override;
|
||||||
bool empty() const override { return _storage.empty(); }
|
bool empty() const override { return _storage.empty(); }
|
||||||
|
|
||||||
|
@ -513,8 +547,19 @@ private:
|
||||||
dispInfoFuncExt _callback;
|
dispInfoFuncExt _callback;
|
||||||
uint64 _totalSize = 0;
|
uint64 _totalSize = 0;
|
||||||
|
|
||||||
using StorageMap = std::unordered_map<uint64, int64>;
|
union StorageOffset
|
||||||
|
{
|
||||||
|
StorageOffset() : _data(0U) {}
|
||||||
|
StorageOffset(int64 data) : _data(data) {}
|
||||||
|
struct {
|
||||||
|
int64 _offset : 48;
|
||||||
|
int64 _formatsize : 16;
|
||||||
|
};
|
||||||
|
int64 _data;
|
||||||
|
};
|
||||||
|
using StorageMap = std::unordered_multimap<uint64, StorageOffset>;
|
||||||
StorageMap _storage;
|
StorageMap _storage;
|
||||||
|
StorageMap::const_iterator find(Checksum checksum, N64FormatSize n64FmtSz) const;
|
||||||
|
|
||||||
uint8 *_gzdest0 = nullptr;
|
uint8 *_gzdest0 = nullptr;
|
||||||
uint8 *_gzdest1 = nullptr;
|
uint8 *_gzdest1 = nullptr;
|
||||||
|
@ -524,12 +569,15 @@ private:
|
||||||
std::ofstream _outfile;
|
std::ofstream _outfile;
|
||||||
int64 _storagePos = 0;
|
int64 _storagePos = 0;
|
||||||
bool _dirty = false;
|
bool _dirty = false;
|
||||||
|
bool _isOldVersion = false;
|
||||||
static const int _fakeConfig;
|
static const int _fakeConfig;
|
||||||
static const int64 _initialPos;
|
static const int64 _initialPos;
|
||||||
|
static const int64 _initialPosOld;
|
||||||
};
|
};
|
||||||
|
|
||||||
const int TxFileStorage::_fakeConfig = -1;
|
const int TxFileStorage::_fakeConfig = -1;
|
||||||
const int64 TxFileStorage::_initialPos = sizeof(int64) + sizeof(int);
|
const int64 TxFileStorage::_initialPos = sizeof(int64) + sizeof(int) + sizeof(int); // offset + version + config
|
||||||
|
const int64 TxFileStorage::_initialPosOld = sizeof(int64) + sizeof(int); // offset + config
|
||||||
|
|
||||||
TxFileStorage::TxFileStorage(uint32 options,
|
TxFileStorage::TxFileStorage(uint32 options,
|
||||||
const wchar_t *cachePath,
|
const wchar_t *cachePath,
|
||||||
|
@ -594,6 +642,8 @@ bool TxFileStorage::open(bool forRead)
|
||||||
if (!_outfile.good())
|
if (!_outfile.good())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
const int version = TXCACHE_FORMAT_VERSION;
|
||||||
|
FWRITE(version);
|
||||||
FWRITE(_fakeConfig);
|
FWRITE(_fakeConfig);
|
||||||
_storagePos = _initialPos;
|
_storagePos = _initialPos;
|
||||||
FWRITE(_storagePos);
|
FWRITE(_storagePos);
|
||||||
|
@ -616,6 +666,8 @@ void TxFileStorage::clear()
|
||||||
_outfile.close();
|
_outfile.close();
|
||||||
|
|
||||||
_outfile.open(_fullPath, std::ofstream::out | std::ofstream::binary | std::ofstream::trunc);
|
_outfile.open(_fullPath, std::ofstream::out | std::ofstream::binary | std::ofstream::trunc);
|
||||||
|
const int version = TXCACHE_FORMAT_VERSION;
|
||||||
|
FWRITE(version);
|
||||||
FWRITE(_fakeConfig);
|
FWRITE(_fakeConfig);
|
||||||
_storagePos = _initialPos;
|
_storagePos = _initialPos;
|
||||||
FWRITE(_storagePos);
|
FWRITE(_storagePos);
|
||||||
|
@ -632,6 +684,7 @@ bool TxFileStorage::writeData(uint32 dataSize, const GHQTexInfo & info)
|
||||||
FWRITE(info.texture_format);
|
FWRITE(info.texture_format);
|
||||||
FWRITE(info.pixel_type);
|
FWRITE(info.pixel_type);
|
||||||
FWRITE(info.is_hires_tex);
|
FWRITE(info.is_hires_tex);
|
||||||
|
FWRITE(info.n64_format_size._formatsize);
|
||||||
FWRITE(dataSize);
|
FWRITE(dataSize);
|
||||||
_outfile.write((char*)info.data, dataSize);
|
_outfile.write((char*)info.data, dataSize);
|
||||||
return _outfile.good();
|
return _outfile.good();
|
||||||
|
@ -645,6 +698,8 @@ bool TxFileStorage::readData(GHQTexInfo & info)
|
||||||
FREAD(info.texture_format);
|
FREAD(info.texture_format);
|
||||||
FREAD(info.pixel_type);
|
FREAD(info.pixel_type);
|
||||||
FREAD(info.is_hires_tex);
|
FREAD(info.is_hires_tex);
|
||||||
|
if (!_isOldVersion)
|
||||||
|
FREAD(info.n64_format_size._formatsize);
|
||||||
|
|
||||||
uint32 dataSize = 0U;
|
uint32 dataSize = 0U;
|
||||||
FREAD(dataSize);
|
FREAD(dataSize);
|
||||||
|
@ -679,7 +734,7 @@ bool TxFileStorage::add(Checksum 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 || _storage.find(checksum) != _storage.end())
|
if (!checksum || !info->data || isCached(checksum, info->n64_format_size))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (_infile.is_open() || !_outfile.is_open())
|
if (_infile.is_open() || !_outfile.is_open())
|
||||||
|
@ -724,8 +779,12 @@ bool TxFileStorage::add(Checksum checksum, GHQTexInfo *info, int dataSize)
|
||||||
|
|
||||||
_outfile.seekp(_storagePos, std::ofstream::beg);
|
_outfile.seekp(_storagePos, std::ofstream::beg);
|
||||||
assert(_storagePos == _outfile.tellp());
|
assert(_storagePos == _outfile.tellp());
|
||||||
|
assert(_storagePos < 0xFFFFFFFFFFFFFF);
|
||||||
|
|
||||||
_storage.insert(StorageMap::value_type(checksum._checksum, _storagePos));
|
StorageOffset offset;
|
||||||
|
offset._formatsize = info->n64_format_size.formatsize();
|
||||||
|
offset._offset = _storagePos;
|
||||||
|
_storage.insert(StorageMap::value_type(checksum._checksum, offset));
|
||||||
if (!writeData(dataSize, infoToWrite))
|
if (!writeData(dataSize, infoToWrite))
|
||||||
return false;
|
return false;
|
||||||
_storagePos = _outfile.tellp();
|
_storagePos = _outfile.tellp();
|
||||||
|
@ -733,7 +792,7 @@ bool TxFileStorage::add(Checksum checksum, GHQTexInfo *info, int dataSize)
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
DBG_INFO(80, wst("[%5d] added!! crc:%08X %08X %d x %d gfmt:%x total:%.02fmb\n"),
|
DBG_INFO(80, wst("[%5d] added!! crc:%08X %08X %d x %d gfmt:%x total:%.02fmb\n"),
|
||||||
_storage.size(), checksum._hi, checksum._low,
|
_storage.size(), checksum._palette, checksum._texture,
|
||||||
info->width, info->height, info->format & 0xffff, (double)(_totalSize / 1024) / 1024.0);
|
info->width, info->height, info->format & 0xffff, (double)(_totalSize / 1024) / 1024.0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -743,13 +802,26 @@ bool TxFileStorage::add(Checksum checksum, GHQTexInfo *info, int dataSize)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TxFileStorage::get(Checksum checksum, GHQTexInfo *info)
|
TxFileStorage::StorageMap::const_iterator TxFileStorage::find(Checksum checksum, N64FormatSize n64FmtSz) const
|
||||||
|
{
|
||||||
|
if (_isOldVersion)
|
||||||
|
return _storage.find(checksum);
|
||||||
|
|
||||||
|
auto range = _storage.equal_range(checksum);
|
||||||
|
for (auto it = range.first; it != range.second; ++it) {
|
||||||
|
if (static_cast<uint16>(it->second._formatsize) == n64FmtSz.formatsize())
|
||||||
|
return it;
|
||||||
|
}
|
||||||
|
return _storage.cend();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TxFileStorage::get(Checksum checksum, N64FormatSize n64FmtSz, GHQTexInfo *info)
|
||||||
{
|
{
|
||||||
if (!checksum || _storage.empty())
|
if (!checksum || _storage.empty())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
/* find a match in storage */
|
/* find a match in storage */
|
||||||
auto itMap = _storage.find(checksum);
|
auto itMap = find(checksum, n64FmtSz);
|
||||||
if (itMap == _storage.end())
|
if (itMap == _storage.end())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -757,7 +829,7 @@ bool TxFileStorage::get(Checksum checksum, GHQTexInfo *info)
|
||||||
if (!open(true))
|
if (!open(true))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
_infile.seekg(itMap->second, std::ifstream::beg);
|
_infile.seekg(itMap->second._offset, std::ifstream::beg);
|
||||||
return readData(*info);
|
return readData(*info);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -782,6 +854,8 @@ bool TxFileStorage::save(const wchar_t *path, const wchar_t *filename, int confi
|
||||||
|
|
||||||
_outfile.seekp(0L, std::ofstream::beg);
|
_outfile.seekp(0L, std::ofstream::beg);
|
||||||
|
|
||||||
|
int version = TXCACHE_FORMAT_VERSION;
|
||||||
|
FWRITE(version);
|
||||||
FWRITE(config);
|
FWRITE(config);
|
||||||
FWRITE(_storagePos);
|
FWRITE(_storagePos);
|
||||||
_outfile.seekp(_storagePos, std::ofstream::beg);
|
_outfile.seekp(_storagePos, std::ofstream::beg);
|
||||||
|
@ -791,7 +865,7 @@ bool TxFileStorage::save(const wchar_t *path, const wchar_t *filename, int confi
|
||||||
(*_callback)(wst("Saving texture storage...\n"));
|
(*_callback)(wst("Saving texture storage...\n"));
|
||||||
for (auto& item : _storage) {
|
for (auto& item : _storage) {
|
||||||
FWRITE(item.first);
|
FWRITE(item.first);
|
||||||
FWRITE(item.second);
|
FWRITE(item.second._data);
|
||||||
}
|
}
|
||||||
_outfile.close();
|
_outfile.close();
|
||||||
if (_callback)
|
if (_callback)
|
||||||
|
@ -813,19 +887,38 @@ bool TxFileStorage::load(const wchar_t *path, const wchar_t *filename, int confi
|
||||||
if (!open(true))
|
if (!open(true))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
int version = 0;
|
||||||
int tmpconfig = 0;
|
int tmpconfig = 0;
|
||||||
/* read header to determine config match */
|
/* read version */
|
||||||
_infile.seekg(0L, std::ifstream::beg);
|
_infile.seekg(0L, std::ifstream::beg);
|
||||||
FREAD(tmpconfig);
|
FREAD(version);
|
||||||
FREAD(_storagePos);
|
if (version == TXCACHE_FORMAT_VERSION) {
|
||||||
if (tmpconfig == _fakeConfig) {
|
_isOldVersion = false;
|
||||||
if (_storagePos != _initialPos)
|
/* read header to determine config match */
|
||||||
|
FREAD(tmpconfig);
|
||||||
|
FREAD(_storagePos);
|
||||||
|
if (tmpconfig == _fakeConfig) {
|
||||||
|
if (_storagePos != _initialPos)
|
||||||
|
return false;
|
||||||
|
} else if (tmpconfig != config && !force)
|
||||||
return false;
|
return false;
|
||||||
} else if (tmpconfig != config && !force)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (_storagePos <= sizeof(config) + sizeof(_storagePos))
|
if (_storagePos <= _initialPos)
|
||||||
return false;
|
return false;
|
||||||
|
} else {
|
||||||
|
_isOldVersion = true;
|
||||||
|
tmpconfig = version;
|
||||||
|
FREAD(_storagePos);
|
||||||
|
if (tmpconfig == _fakeConfig) {
|
||||||
|
if (_storagePos != _initialPosOld)
|
||||||
|
return false;
|
||||||
|
} else if (tmpconfig != config && !force)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (_storagePos <= _initialPosOld)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
_infile.seekg(_storagePos, std::ifstream::beg);
|
_infile.seekg(_storagePos, std::ifstream::beg);
|
||||||
|
|
||||||
int storageSize = 0;
|
int storageSize = 0;
|
||||||
|
@ -849,9 +942,9 @@ bool TxFileStorage::load(const wchar_t *path, const wchar_t *filename, int confi
|
||||||
return !_storage.empty();
|
return !_storage.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TxFileStorage::isCached(Checksum checksum)
|
bool TxFileStorage::isCached(Checksum checksum, N64FormatSize n64FmtSz) const
|
||||||
{
|
{
|
||||||
return _storage.find(checksum) != _storage.end();
|
return find(checksum, n64FmtSz) != _storage.cend();
|
||||||
}
|
}
|
||||||
|
|
||||||
/************************** TxCache *************************************/
|
/************************** TxCache *************************************/
|
||||||
|
@ -886,9 +979,9 @@ bool TxCache::add(Checksum checksum, GHQTexInfo *info, int dataSize)
|
||||||
return _pImpl->add(checksum, info, dataSize);
|
return _pImpl->add(checksum, info, dataSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TxCache::get(Checksum checksum, GHQTexInfo *info)
|
bool TxCache::get(Checksum checksum, N64FormatSize n64FmtSz, GHQTexInfo *info)
|
||||||
{
|
{
|
||||||
return _pImpl->get(checksum, info);
|
return _pImpl->get(checksum, n64FmtSz, info);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64 TxCache::size() const
|
uint64 TxCache::size() const
|
||||||
|
@ -921,9 +1014,9 @@ bool TxCache::del(Checksum checksum)
|
||||||
return _pImpl->del(checksum);
|
return _pImpl->del(checksum);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TxCache::isCached(Checksum checksum)
|
bool TxCache::isCached(Checksum checksum, N64FormatSize n64FmtSz) const
|
||||||
{
|
{
|
||||||
return _pImpl->isCached(checksum);
|
return _pImpl->isCached(checksum, n64FmtSz);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TxCache::clear()
|
void TxCache::clear()
|
||||||
|
|
|
@ -31,27 +31,6 @@
|
||||||
#include "TxInternal.h"
|
#include "TxInternal.h"
|
||||||
#include "TxUtil.h"
|
#include "TxUtil.h"
|
||||||
|
|
||||||
struct Checksum
|
|
||||||
{
|
|
||||||
union
|
|
||||||
{
|
|
||||||
uint64 _checksum; /* checksum hi:palette low:texture */
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
uint32 _low;
|
|
||||||
uint32 _hi;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
Checksum(uint64 checksum) : _checksum(checksum) {}
|
|
||||||
operator bool() {
|
|
||||||
return _checksum != 0;
|
|
||||||
}
|
|
||||||
operator uint64() {
|
|
||||||
return _checksum;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class TxCacheImpl;
|
class TxCacheImpl;
|
||||||
|
|
||||||
class TxCache
|
class TxCache
|
||||||
|
@ -66,8 +45,8 @@ protected:
|
||||||
|
|
||||||
bool save();
|
bool save();
|
||||||
bool load(bool force);
|
bool load(bool force);
|
||||||
bool del(Checksum checksum); /* checksum hi:palette low:texture */
|
bool del(Checksum checksum);
|
||||||
bool isCached(Checksum checksum); /* checksum hi:palette low:texture */
|
bool isCached(Checksum checksum, N64FormatSize n64FmtSz) const;
|
||||||
void clear();
|
void clear();
|
||||||
uint64 size() const; // number of elements
|
uint64 size() const; // number of elements
|
||||||
uint64 totalSize() const; // size of elements in bytes
|
uint64 totalSize() const; // size of elements in bytes
|
||||||
|
@ -82,7 +61,7 @@ public:
|
||||||
virtual ~TxCache();
|
virtual ~TxCache();
|
||||||
TxCache(uint32 options, uint64 cacheLimit, const wchar_t *cachePath, const wchar_t *ident, dispInfoFuncExt callback);
|
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 add(Checksum checksum, GHQTexInfo *info, int dataSize = 0);
|
||||||
bool get(Checksum checksum, GHQTexInfo *info);
|
bool get(Checksum checksum, N64FormatSize n64FmtSz, GHQTexInfo *info);
|
||||||
bool empty() const;
|
bool empty() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -164,7 +164,7 @@ TxFilter::TxFilter(int maxwidth,
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean
|
boolean
|
||||||
TxFilter::filter(uint8 *src, int srcwidth, int srcheight, ColorFormat srcformat, uint64 g64crc, GHQTexInfo *info)
|
TxFilter::filter(uint8 *src, int srcwidth, int srcheight, ColorFormat srcformat, uint64 g64crc, N64FormatSize n64FmtSz, GHQTexInfo *info)
|
||||||
{
|
{
|
||||||
uint8 *texture = src;
|
uint8 *texture = src;
|
||||||
uint8 *tmptex = _tex1;
|
uint8 *tmptex = _tex1;
|
||||||
|
@ -186,7 +186,7 @@ TxFilter::filter(uint8 *src, int srcwidth, int srcheight, ColorFormat srcformat,
|
||||||
|
|
||||||
/* check if we have it in cache */
|
/* check if we have it in cache */
|
||||||
if ((g64crc & 0xffffffff00000000) == 0 && /* we reach here only when there is no hires texture for this crc */
|
if ((g64crc & 0xffffffff00000000) == 0 && /* we reach here only when there is no hires texture for this crc */
|
||||||
_txTexCache->get(g64crc, info)) {
|
_txTexCache->get(g64crc, n64FmtSz, info)) {
|
||||||
DBG_INFO(80, wst("cache hit: %d x %d gfmt:%x\n"), info->width, info->height, info->format);
|
DBG_INFO(80, wst("cache hit: %d x %d gfmt:%x\n"), info->width, info->height, info->format);
|
||||||
return 1; /* yep, we've got it */
|
return 1; /* yep, we've got it */
|
||||||
}
|
}
|
||||||
|
@ -451,6 +451,7 @@ TxFilter::filter(uint8 *src, int srcwidth, int srcheight, ColorFormat srcformat,
|
||||||
info->width = srcwidth;
|
info->width = srcwidth;
|
||||||
info->height = srcheight;
|
info->height = srcheight;
|
||||||
info->is_hires_tex = 0;
|
info->is_hires_tex = 0;
|
||||||
|
info->n64_format_size = n64FmtSz;
|
||||||
setTextureFormat(destformat, info);
|
setTextureFormat(destformat, info);
|
||||||
|
|
||||||
/* cache the texture. */
|
/* cache the texture. */
|
||||||
|
@ -463,7 +464,7 @@ TxFilter::filter(uint8 *src, int srcwidth, int srcheight, ColorFormat srcformat,
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean
|
boolean
|
||||||
TxFilter::hirestex(uint64 g64crc, uint64 r_crc64, uint16 *palette, GHQTexInfo *info)
|
TxFilter::hirestex(uint64 g64crc, Checksum r_crc64, uint16 *palette, N64FormatSize n64FmtSz, GHQTexInfo *info)
|
||||||
{
|
{
|
||||||
/* NOTE: Rice CRC32 sometimes return the same value for different textures.
|
/* NOTE: Rice CRC32 sometimes return the same value for different textures.
|
||||||
* As a workaround, Glide64 CRC32 is used for the key for NON-hires
|
* As a workaround, Glide64 CRC32 is used for the key for NON-hires
|
||||||
|
@ -476,13 +477,13 @@ TxFilter::hirestex(uint64 g64crc, uint64 r_crc64, uint16 *palette, GHQTexInfo *i
|
||||||
*/
|
*/
|
||||||
|
|
||||||
DBG_INFO(80, wst("hirestex: r_crc64:%08X %08X, g64crc:%08X %08X\n"),
|
DBG_INFO(80, wst("hirestex: r_crc64:%08X %08X, g64crc:%08X %08X\n"),
|
||||||
(uint32)(r_crc64 >> 32), (uint32)(r_crc64 & 0xffffffff),
|
r_crc64._palette, r_crc64._texture,
|
||||||
(uint32)(g64crc >> 32), (uint32)(g64crc & 0xffffffff));
|
(uint32)(g64crc >> 32), (uint32)(g64crc & 0xffffffff));
|
||||||
|
|
||||||
#if HIRES_TEXTURE
|
#if HIRES_TEXTURE
|
||||||
/* check if we have it in hires memory cache. */
|
/* check if we have it in hires memory cache. */
|
||||||
if ((_options & HIRESTEXTURES_MASK) && r_crc64) {
|
if ((_options & HIRESTEXTURES_MASK) && r_crc64) {
|
||||||
if (_txHiResLoader->get(r_crc64, info)) {
|
if (_txHiResLoader->get(r_crc64, n64FmtSz, info)) {
|
||||||
DBG_INFO(80, wst("hires hit: %d x %d gfmt:%x\n"), info->width, info->height, info->format);
|
DBG_INFO(80, wst("hires hit: %d x %d gfmt:%x\n"), info->width, info->height, info->format);
|
||||||
|
|
||||||
/* TODO: Enable emulation for special N64 combiner modes. There are few ways
|
/* TODO: Enable emulation for special N64 combiner modes. There are few ways
|
||||||
|
@ -509,11 +510,11 @@ TxFilter::hirestex(uint64 g64crc, uint64 r_crc64, uint16 *palette, GHQTexInfo *i
|
||||||
|
|
||||||
return 1; /* yep, got it */
|
return 1; /* yep, got it */
|
||||||
}
|
}
|
||||||
if (_txHiResLoader->get((r_crc64 >> 32), info) ||
|
if (_txHiResLoader->get(r_crc64._palette, n64FmtSz, info) ||
|
||||||
_txHiResLoader->get((r_crc64 & 0xffffffff), info)) {
|
_txHiResLoader->get(r_crc64._texture, n64FmtSz, info)) {
|
||||||
DBG_INFO(80, wst("hires hit: %d x %d gfmt:%x\n"), info->width, info->height, info->format);
|
DBG_INFO(80, wst("hires hit: %d x %d gfmt:%x\n"), info->width, info->height, info->format);
|
||||||
|
|
||||||
/* for true CI textures, we use the passed in palette to convert to
|
/* for true CI textures, we use the passed in palette to convert to
|
||||||
* ARGB1555 and add it to memory cache.
|
* ARGB1555 and add it to memory cache.
|
||||||
*
|
*
|
||||||
* NOTE: we do this AFTER all other texture cache searches because
|
* NOTE: we do this AFTER all other texture cache searches because
|
||||||
|
@ -543,6 +544,7 @@ TxFilter::hirestex(uint64 g64crc, uint64 r_crc64, uint16 *palette, GHQTexInfo *i
|
||||||
info->width = width;
|
info->width = width;
|
||||||
info->height = height;
|
info->height = height;
|
||||||
info->is_hires_tex = 1;
|
info->is_hires_tex = 1;
|
||||||
|
info->n64_format_size = n64FmtSz;
|
||||||
setTextureFormat(format, info);
|
setTextureFormat(format, info);
|
||||||
|
|
||||||
/* XXX: add to hires texture cache!!! */
|
/* XXX: add to hires texture cache!!! */
|
||||||
|
@ -558,7 +560,7 @@ TxFilter::hirestex(uint64 g64crc, uint64 r_crc64, uint16 *palette, GHQTexInfo *i
|
||||||
|
|
||||||
/* check if we have it in memory cache */
|
/* check if we have it in memory cache */
|
||||||
if (_cacheSize && g64crc) {
|
if (_cacheSize && g64crc) {
|
||||||
if (_txTexCache->get(g64crc, info)) {
|
if (_txTexCache->get(g64crc, n64FmtSz, info)) {
|
||||||
DBG_INFO(80, wst("cache hit: %d x %d gfmt:%x\n"), info->width, info->height, info->format);
|
DBG_INFO(80, wst("cache hit: %d x %d gfmt:%x\n"), info->width, info->height, info->format);
|
||||||
return 1; /* yep, we've got it */
|
return 1; /* yep, we've got it */
|
||||||
}
|
}
|
||||||
|
@ -579,7 +581,7 @@ TxFilter::checksum64(uint8 *src, int width, int height, int size, int rowStride,
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean
|
boolean
|
||||||
TxFilter::dmptx(uint8 *src, int width, int height, int rowStridePixel, ColorFormat gfmt, uint16 n64fmt, uint64 r_crc64)
|
TxFilter::dmptx(uint8 *src, int width, int height, int rowStridePixel, ColorFormat gfmt, N64FormatSize n64FmtSz, Checksum r_crc64)
|
||||||
{
|
{
|
||||||
assert(gfmt != graphics::colorFormat::RGBA);
|
assert(gfmt != graphics::colorFormat::RGBA);
|
||||||
if (!_initialized)
|
if (!_initialized)
|
||||||
|
@ -588,9 +590,9 @@ TxFilter::dmptx(uint8 *src, int width, int height, int rowStridePixel, ColorForm
|
||||||
if (!(_options & DUMP_TEX))
|
if (!(_options & DUMP_TEX))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
DBG_INFO(80, wst("gfmt = %02x n64fmt = %02x\n"), u32(gfmt), n64fmt);
|
DBG_INFO(80, wst("gfmt = %02x n64fmt = %02x\n"), u32(gfmt), n64FmtSz._format);
|
||||||
DBG_INFO(80, wst("hirestex: r_crc64:%08X %08X\n"),
|
DBG_INFO(80, wst("hirestex: r_crc64:%08X %08X\n"),
|
||||||
(uint32)(r_crc64 >> 32), (uint32)(r_crc64 & 0xffffffff));
|
r_crc64._palette, r_crc64._texture);
|
||||||
|
|
||||||
if (gfmt != graphics::internalcolorFormat::RGBA8) {
|
if (gfmt != graphics::internalcolorFormat::RGBA8) {
|
||||||
if (!_txQuantize->quantize(src, _tex1, rowStridePixel, height, gfmt, graphics::internalcolorFormat::RGBA8))
|
if (!_txQuantize->quantize(src, _tex1, rowStridePixel, height, gfmt, graphics::internalcolorFormat::RGBA8))
|
||||||
|
@ -611,13 +613,13 @@ TxFilter::dmptx(uint8 *src, int width, int height, int rowStridePixel, ColorForm
|
||||||
if (!osal_path_existsW(tmpbuf.c_str()) && osal_mkdirp(tmpbuf.c_str()) != 0)
|
if (!osal_path_existsW(tmpbuf.c_str()) && osal_mkdirp(tmpbuf.c_str()) != 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if ((n64fmt >> 8) == 0x2) {
|
if (n64FmtSz._format == 0x2) {
|
||||||
wchar_t wbuf[256];
|
wchar_t wbuf[256];
|
||||||
tx_swprintf(wbuf, 256, wst("/%ls#%08X#%01X#%01X#%08X_ciByRGBA.png"), _ident.c_str(), (uint32)(r_crc64 & 0xffffffff), (n64fmt >> 8), (n64fmt & 0xf), (uint32)(r_crc64 >> 32));
|
tx_swprintf(wbuf, 256, wst("/%ls#%08X#%01X#%01X#%08X_ciByRGBA.png"), _ident.c_str(), r_crc64._texture, n64FmtSz._format, n64FmtSz._size, r_crc64._palette);
|
||||||
tmpbuf.append(wbuf);
|
tmpbuf.append(wbuf);
|
||||||
} else {
|
} else {
|
||||||
wchar_t wbuf[256];
|
wchar_t wbuf[256];
|
||||||
tx_swprintf(wbuf, 256, wst("/%ls#%08X#%01X#%01X_all.png"), _ident.c_str(), (uint32)(r_crc64 & 0xffffffff), (n64fmt >> 8), (n64fmt & 0xf));
|
tx_swprintf(wbuf, 256, wst("/%ls#%08X#%01X#%01X_all.png"), _ident.c_str(), r_crc64._texture, n64FmtSz._format, n64FmtSz._size);
|
||||||
tmpbuf.append(wbuf);
|
tmpbuf.append(wbuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -70,13 +70,15 @@ public:
|
||||||
int srcheight,
|
int srcheight,
|
||||||
ColorFormat srcformat,
|
ColorFormat srcformat,
|
||||||
uint64 g64crc, /* glide64 crc, 64bit for future use */
|
uint64 g64crc, /* glide64 crc, 64bit for future use */
|
||||||
|
N64FormatSize n64FmtSz,
|
||||||
GHQTexInfo *info);
|
GHQTexInfo *info);
|
||||||
boolean hirestex(uint64 g64crc, /* glide64 crc, 64bit for future use */
|
boolean hirestex(uint64 g64crc, /* glide64 crc, 64bit for future use */
|
||||||
uint64 r_crc64, /* checksum hi:palette low:texture */
|
Checksum r_crc64,
|
||||||
uint16 *palette,
|
uint16 *palette,
|
||||||
|
N64FormatSize n64FmtSz,
|
||||||
GHQTexInfo *info);
|
GHQTexInfo *info);
|
||||||
uint64 checksum64(uint8 *src, int width, int height, int size, int rowStride, uint8 *palette);
|
uint64 checksum64(uint8 *src, int width, int height, int size, int rowStride, uint8 *palette);
|
||||||
boolean dmptx(uint8 *src, int width, int height, int rowStridePixel, ColorFormat gfmt, uint16 n64fmt, uint64 r_crc64);
|
boolean dmptx(uint8 *src, int width, int height, int rowStridePixel, ColorFormat gfmt, N64FormatSize n64FmtSz, Checksum r_crc64);
|
||||||
boolean reloadhirestex();
|
boolean reloadhirestex();
|
||||||
void dumpcache();
|
void dumpcache();
|
||||||
};
|
};
|
||||||
|
|
|
@ -57,20 +57,20 @@ txfilter_shutdown(void)
|
||||||
|
|
||||||
TAPI boolean TAPIENTRY
|
TAPI boolean TAPIENTRY
|
||||||
txfilter_filter(uint8 *src, int srcwidth, int srcheight, uint16 srcformat,
|
txfilter_filter(uint8 *src, int srcwidth, int srcheight, uint16 srcformat,
|
||||||
uint64 g64crc, GHQTexInfo *info)
|
uint64 g64crc, N64FormatSize n64FmtSz, GHQTexInfo *info)
|
||||||
{
|
{
|
||||||
if (txFilter)
|
if (txFilter)
|
||||||
return txFilter->filter(src, srcwidth, srcheight, ColorFormat(u32(srcformat)),
|
return txFilter->filter(src, srcwidth, srcheight, ColorFormat(u32(srcformat)),
|
||||||
g64crc, info);
|
g64crc, n64FmtSz, info);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
TAPI boolean TAPIENTRY
|
TAPI boolean TAPIENTRY
|
||||||
txfilter_hirestex(uint64 g64crc, uint64 r_crc64, uint16 *palette, GHQTexInfo *info)
|
txfilter_hirestex(uint64 g64crc, Checksum r_crc64, uint16 *palette, N64FormatSize n64FmtSz, GHQTexInfo *info)
|
||||||
{
|
{
|
||||||
if (txFilter)
|
if (txFilter)
|
||||||
return txFilter->hirestex(g64crc, r_crc64, palette, info);
|
return txFilter->hirestex(g64crc, r_crc64, palette, n64FmtSz, info);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -85,10 +85,10 @@ txfilter_checksum(uint8 *src, int width, int height, int size, int rowStride, ui
|
||||||
}
|
}
|
||||||
|
|
||||||
TAPI boolean TAPIENTRY
|
TAPI boolean TAPIENTRY
|
||||||
txfilter_dmptx(uint8 *src, int width, int height, int rowStridePixel, uint16 gfmt, uint16 n64fmt, uint64 r_crc64)
|
txfilter_dmptx(uint8 *src, int width, int height, int rowStridePixel, uint16 gfmt, N64FormatSize n64FmtSz, Checksum r_crc64)
|
||||||
{
|
{
|
||||||
if (txFilter)
|
if (txFilter)
|
||||||
return txFilter->dmptx(src, width, height, rowStridePixel, ColorFormat(u32(gfmt)), n64fmt, r_crc64);
|
return txFilter->dmptx(src, width, height, rowStridePixel, ColorFormat(u32(gfmt)), n64FmtSz, r_crc64);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,6 +45,9 @@
|
||||||
#define CHDIR(a) chdir(a)
|
#define CHDIR(a) chdir(a)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
typedef unsigned char uint8;
|
||||||
|
typedef unsigned short uint16;
|
||||||
|
typedef unsigned int uint32;
|
||||||
#ifdef __MSC__
|
#ifdef __MSC__
|
||||||
typedef __int64 int64;
|
typedef __int64 int64;
|
||||||
typedef unsigned __int64 uint64;
|
typedef unsigned __int64 uint64;
|
||||||
|
@ -100,21 +103,77 @@ typedef unsigned char boolean;
|
||||||
#define GZ_HIRESTEXCACHE 0x00800000
|
#define GZ_HIRESTEXCACHE 0x00800000
|
||||||
#define DUMP_TEXCACHE 0x01000000
|
#define DUMP_TEXCACHE 0x01000000
|
||||||
#define DUMP_HIRESTEXCACHE 0x02000000
|
#define DUMP_HIRESTEXCACHE 0x02000000
|
||||||
#define TILE_HIRESTEX 0x04000000
|
#define UNDEFINED_0 0x04000000
|
||||||
#define UNDEFINED_0 0x08000000
|
#define UNDEFINED_1 0x08000000
|
||||||
#define FORCE16BPP_HIRESTEX 0x10000000
|
#define FORCE16BPP_HIRESTEX 0x10000000
|
||||||
#define FORCE16BPP_TEX 0x20000000
|
#define FORCE16BPP_TEX 0x20000000
|
||||||
#define LET_TEXARTISTS_FLY 0x40000000 /* a little freedom for texture artists */
|
#define LET_TEXARTISTS_FLY 0x40000000 /* a little freedom for texture artists */
|
||||||
#define DUMP_TEX 0x80000000
|
#define DUMP_TEX 0x80000000
|
||||||
|
|
||||||
struct GHQTexInfo {
|
struct Checksum
|
||||||
unsigned char *data = nullptr;
|
{
|
||||||
int width = 0;
|
union
|
||||||
int height = 0;
|
{
|
||||||
unsigned int format = 0;
|
uint64 _checksum; /* checksum hi:palette low:texture */
|
||||||
unsigned short texture_format = 0;
|
struct
|
||||||
unsigned short pixel_type = 0;
|
{
|
||||||
unsigned char is_hires_tex = 0;
|
uint32 _texture;
|
||||||
|
uint32 _palette;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
Checksum(uint64 checksum) : _checksum(checksum) {}
|
||||||
|
Checksum(uint32 texture, uint32 palette) : _texture(texture), _palette(palette) {}
|
||||||
|
|
||||||
|
operator bool() const {
|
||||||
|
return _checksum != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
operator uint64() const {
|
||||||
|
return _checksum;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct N64FormatSize
|
||||||
|
{
|
||||||
|
union
|
||||||
|
{
|
||||||
|
uint16 _formatsize;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint8 _format;
|
||||||
|
uint8 _size;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
N64FormatSize(uint16 n64format, uint16 n64size) :
|
||||||
|
_format(static_cast<uint8>(n64format)),
|
||||||
|
_size(static_cast<uint8>(n64size))
|
||||||
|
{}
|
||||||
|
|
||||||
|
uint16 formatsize() const
|
||||||
|
{
|
||||||
|
return _formatsize;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator==(const N64FormatSize& _other) const
|
||||||
|
{
|
||||||
|
return _other._formatsize == _formatsize;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct GHQTexInfo
|
||||||
|
{
|
||||||
|
GHQTexInfo() {}
|
||||||
|
~GHQTexInfo() {}
|
||||||
|
unsigned char *data{ nullptr };
|
||||||
|
unsigned int width{ 0u };
|
||||||
|
unsigned int height{ 0u };
|
||||||
|
unsigned int format{ 0u };
|
||||||
|
unsigned short texture_format{ 0u };
|
||||||
|
unsigned short pixel_type{ 0u };
|
||||||
|
unsigned char is_hires_tex{ 0u };
|
||||||
|
N64FormatSize n64_format_size{ 0u, 0u };
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Callback to display hires texture info.
|
/* Callback to display hires texture info.
|
||||||
|
@ -155,10 +214,6 @@ typedef void (*dispInfoFuncExt)(const wchar_t *format, ...);
|
||||||
#endif
|
#endif
|
||||||
#endif // OS_WINDOWS
|
#endif // OS_WINDOWS
|
||||||
|
|
||||||
typedef unsigned char uint8;
|
|
||||||
typedef unsigned short uint16;
|
|
||||||
typedef unsigned int uint32;
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C"{
|
extern "C"{
|
||||||
#endif
|
#endif
|
||||||
|
@ -173,16 +228,16 @@ txfilter_shutdown(void);
|
||||||
|
|
||||||
TAPI boolean TAPIENTRY
|
TAPI boolean TAPIENTRY
|
||||||
txfilter_filter(uint8 *src, int srcwidth, int srcheight, uint16 srcformat,
|
txfilter_filter(uint8 *src, int srcwidth, int srcheight, uint16 srcformat,
|
||||||
uint64 g64crc, GHQTexInfo *info);
|
uint64 g64crc, N64FormatSize n64FmtSz, GHQTexInfo *info);
|
||||||
|
|
||||||
TAPI boolean TAPIENTRY
|
TAPI boolean TAPIENTRY
|
||||||
txfilter_hirestex(uint64 g64crc, uint64 r_crc64, uint16 *palette, GHQTexInfo *info);
|
txfilter_hirestex(uint64 g64crc, Checksum r_crc64, uint16 *palette, N64FormatSize n64FmtSz, GHQTexInfo *info);
|
||||||
|
|
||||||
TAPI uint64 TAPIENTRY
|
TAPI uint64 TAPIENTRY
|
||||||
txfilter_checksum(uint8 *src, int width, int height, int size, int rowStride, uint8 *palette);
|
txfilter_checksum(uint8 *src, int width, int height, int size, int rowStride, uint8 *palette);
|
||||||
|
|
||||||
TAPI boolean TAPIENTRY
|
TAPI boolean TAPIENTRY
|
||||||
txfilter_dmptx(uint8 *src, int width, int height, int rowStridePixel, uint16 gfmt, uint16 n64fmt, uint64 r_crc64);
|
txfilter_dmptx(uint8 *src, int width, int height, int rowStridePixel, uint16 gfmt, N64FormatSize n64FmtSz, Checksum r_crc64);
|
||||||
|
|
||||||
TAPI boolean TAPIENTRY
|
TAPI boolean TAPIENTRY
|
||||||
txfilter_reloadhirestex();
|
txfilter_reloadhirestex();
|
||||||
|
|
|
@ -97,7 +97,6 @@ int TxHiResCache::_getConfig() const
|
||||||
{
|
{
|
||||||
return getOptions() &
|
return getOptions() &
|
||||||
(HIRESTEXTURES_MASK |
|
(HIRESTEXTURES_MASK |
|
||||||
TILE_HIRESTEX |
|
|
||||||
FORCE16BPP_HIRESTEX |
|
FORCE16BPP_HIRESTEX |
|
||||||
GZ_HIRESTEXCACHE |
|
GZ_HIRESTEXCACHE |
|
||||||
FILE_HIRESTEXCACHE |
|
FILE_HIRESTEXCACHE |
|
||||||
|
@ -251,7 +250,7 @@ TxHiResCache::LoadResult TxHiResCache::_loadHiResTextures(const wchar_t * dir_pa
|
||||||
chksum64 <<= 32;
|
chksum64 <<= 32;
|
||||||
chksum64 |= (uint64)chksum;
|
chksum64 |= (uint64)chksum;
|
||||||
}
|
}
|
||||||
if (isCached(chksum64)) {
|
if (isCached(chksum64, N64FormatSize(fmt, siz))) {
|
||||||
#if !DEBUG
|
#if !DEBUG
|
||||||
INFO(80, wst("-----\n"));
|
INFO(80, wst("-----\n"));
|
||||||
INFO(80, wst("file: %s\n"), fname);
|
INFO(80, wst("file: %s\n"), fname);
|
||||||
|
@ -281,6 +280,7 @@ TxHiResCache::LoadResult TxHiResCache::_loadHiResTextures(const wchar_t * dir_pa
|
||||||
tmpInfo.width = width;
|
tmpInfo.width = width;
|
||||||
tmpInfo.height = height;
|
tmpInfo.height = height;
|
||||||
tmpInfo.is_hires_tex = 1;
|
tmpInfo.is_hires_tex = 1;
|
||||||
|
tmpInfo.n64_format_size = N64FormatSize(fmt, siz);
|
||||||
setTextureFormat(format, &tmpInfo);
|
setTextureFormat(format, &tmpInfo);
|
||||||
|
|
||||||
/* remove redundant in cache */
|
/* remove redundant in cache */
|
||||||
|
@ -325,7 +325,7 @@ bool TxHiResCache::add(Checksum checksum, GHQTexInfo *info, int dataSize)
|
||||||
return TxCache::add(checksum, info, dataSize);
|
return TxCache::add(checksum, info, dataSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TxHiResCache::get(Checksum checksum, GHQTexInfo *info)
|
bool TxHiResCache::get(Checksum checksum, N64FormatSize n64FmtSz, GHQTexInfo *info)
|
||||||
{
|
{
|
||||||
return TxCache::get(checksum, info);
|
return TxCache::get(checksum, n64FmtSz, info);
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,7 +60,7 @@ public:
|
||||||
dispInfoFuncExt callback);
|
dispInfoFuncExt callback);
|
||||||
bool empty() const override;
|
bool empty() const override;
|
||||||
bool add(Checksum checksum, GHQTexInfo *info, int dataSize = 0) override;
|
bool add(Checksum checksum, GHQTexInfo *info, int dataSize = 0) override;
|
||||||
bool get(Checksum checksum, GHQTexInfo *info) override;
|
bool get(Checksum checksum, N64FormatSize n64FmtSz, GHQTexInfo *info) override;
|
||||||
bool reload() override;
|
bool reload() override;
|
||||||
void dump() override;
|
void dump() override;
|
||||||
};
|
};
|
||||||
|
|
|
@ -571,4 +571,3 @@ uint8_t* TxHiResLoader::loadFileInfoTex(char* fname,
|
||||||
|
|
||||||
return tex;
|
return tex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,7 @@ class TxHiResLoader
|
||||||
protected:
|
protected:
|
||||||
uint32_t checkFileName(char* ident, char* fname, uint32_t* pChksum, uint32_t* pPalchksum, uint32_t* pFmt, uint32_t* pSiz);
|
uint32_t checkFileName(char* ident, char* fname, uint32_t* pChksum, uint32_t* pPalchksum, uint32_t* pFmt, uint32_t* pSiz);
|
||||||
uint8_t* loadFileInfoTex(char* fname, int siz, int* pWidth, int* pHeight, uint32_t fmt, ColorFormat* pFormat);
|
uint8_t* loadFileInfoTex(char* fname, int siz, int* pWidth, int* pHeight, uint32_t fmt, ColorFormat* pFormat);
|
||||||
|
|
||||||
std::unique_ptr<TxImage> _txImage;
|
std::unique_ptr<TxImage> _txImage;
|
||||||
std::unique_ptr<TxQuantize> _txQuantize;
|
std::unique_ptr<TxQuantize> _txQuantize;
|
||||||
std::unique_ptr<TxReSample> _txReSample;
|
std::unique_ptr<TxReSample> _txReSample;
|
||||||
|
@ -42,7 +42,7 @@ public:
|
||||||
|
|
||||||
virtual bool empty() const = 0;
|
virtual bool empty() const = 0;
|
||||||
virtual bool add(Checksum checksum, GHQTexInfo *info, int dataSize = 0) = 0;
|
virtual bool add(Checksum checksum, GHQTexInfo *info, int dataSize = 0) = 0;
|
||||||
virtual bool get(Checksum checksum, GHQTexInfo *info) = 0;
|
virtual bool get(Checksum checksum, N64FormatSize n64FmtSz, GHQTexInfo *info) = 0;
|
||||||
virtual bool reload() = 0;
|
virtual bool reload() = 0;
|
||||||
virtual void dump() = 0;
|
virtual void dump() = 0;
|
||||||
};
|
};
|
||||||
|
|
|
@ -49,30 +49,44 @@ bool TxHiResNoCache::empty() const
|
||||||
return _filesIndex.empty();
|
return _filesIndex.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TxHiResNoCache::get(Checksum checksum, GHQTexInfo *info)
|
TxHiResNoCache::FileIndexMap::const_iterator TxHiResNoCache::findFile(Checksum checksum, N64FormatSize n64FmtSz) const
|
||||||
{
|
{
|
||||||
if (!checksum) {
|
auto range = _filesIndex.equal_range(checksum);
|
||||||
return false;
|
for (auto it = range.first; it != range.second; ++it) {
|
||||||
|
if (N64FormatSize(it->second.fmt, it->second.siz).formatsize() == n64FmtSz.formatsize())
|
||||||
|
return it;
|
||||||
}
|
}
|
||||||
|
return _filesIndex.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TxHiResNoCache::get(Checksum checksum, N64FormatSize n64FmtSz, GHQTexInfo *info)
|
||||||
|
{
|
||||||
|
if (!checksum)
|
||||||
|
return false;
|
||||||
|
|
||||||
#ifdef DEBUG
|
uint32 chksum = checksum._texture;
|
||||||
uint32 chksum = checksum._checksum & 0xffffffff;
|
uint32 palchksum = checksum._palette;
|
||||||
uint32 palchksum = checksum._checksum >> 32;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* loop over each file from the index and try to match it with checksum */
|
/* loop over each file from the index and try to match it with checksum */
|
||||||
auto indexEntry = _filesIndex.find(checksum);
|
auto indexEntry = findFile(checksum, n64FmtSz);
|
||||||
if (indexEntry == _filesIndex.end()) {
|
if (indexEntry == _filesIndex.cend()) {
|
||||||
DBG_INFO(80, wst("TxNoCache::get: chksum:%08X %08X not found\n"), chksum, palchksum);
|
DBG_INFO(80, wst("TxNoCache::get: chksum:%08X %08X not found\n"), chksum, palchksum);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
fileIndexEntry_t& entry = indexEntry->second;
|
auto entry = indexEntry->second;
|
||||||
|
|
||||||
/* make sure to not load the same texture twice */
|
/* make sure to not load the same texture twice */
|
||||||
auto loadedTexMap = _loadedTex.find(checksum);
|
auto findTex = [n64FmtSz, this](Checksum checksum)
|
||||||
if (loadedTexMap != _loadedTex.end()) {
|
{
|
||||||
|
auto range = _loadedTex.equal_range(checksum);
|
||||||
|
for (auto it = range.first; it != range.second; ++it) {
|
||||||
|
if (it->second.n64_format_size == n64FmtSz)
|
||||||
|
return it;
|
||||||
|
}
|
||||||
|
return _loadedTex.end();
|
||||||
|
};
|
||||||
|
if (auto loadedTexMap = findTex(checksum); loadedTexMap != _loadedTex.end()) {
|
||||||
DBG_INFO(80, wst("TxNoCache::get: cached chksum:%08X %08X found\n"), chksum, palchksum);
|
DBG_INFO(80, wst("TxNoCache::get: cached chksum:%08X %08X found\n"), chksum, palchksum);
|
||||||
*info = loadedTexMap->second;
|
*info = loadedTexMap->second;
|
||||||
return true;
|
return true;
|
||||||
|
@ -113,6 +127,7 @@ bool TxHiResNoCache::get(Checksum checksum, GHQTexInfo *info)
|
||||||
info->width = width;
|
info->width = width;
|
||||||
info->height = height;
|
info->height = height;
|
||||||
info->is_hires_tex = 1;
|
info->is_hires_tex = 1;
|
||||||
|
info->n64_format_size = n64FmtSz;
|
||||||
setTextureFormat(format, info);
|
setTextureFormat(format, info);
|
||||||
|
|
||||||
/* add to loaded textures */
|
/* add to loaded textures */
|
||||||
|
@ -180,9 +195,8 @@ bool TxHiResNoCache::_createFileIndexInDir(tx_wstring directory, bool update)
|
||||||
|
|
||||||
uint64 chksum64 = 0;
|
uint64 chksum64 = 0;
|
||||||
uint32 chksum = 0, palchksum = 0, length = 0;
|
uint32 chksum = 0, palchksum = 0, length = 0;
|
||||||
fileIndexEntry_t entry;
|
FileIndexEntry entry;
|
||||||
entry.fmt = entry.siz = 0;
|
entry.fmt = entry.siz = 0;
|
||||||
bool ret = false;
|
|
||||||
|
|
||||||
wcstombs(entry.fname, foundfilename, MAX_PATH);
|
wcstombs(entry.fname, foundfilename, MAX_PATH);
|
||||||
|
|
||||||
|
@ -205,14 +219,14 @@ bool TxHiResNoCache::_createFileIndexInDir(tx_wstring directory, bool update)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* try to add entry to file index */
|
/* try to add entry to file index */
|
||||||
ret = _filesIndex.insert(std::map<uint64, fileIndexEntry_t>::value_type(chksum64, entry)).second;
|
if (findFile(chksum64, N64FormatSize(entry.fmt, entry.siz)) != _filesIndex.cend()) {
|
||||||
if (!ret) {
|
|
||||||
/* technically we should probably fail here,
|
/* technically we should probably fail here,
|
||||||
* however HTS & HTC both don't fail when there are duplicates,
|
* however HTS & HTC both don't fail when there are duplicates,
|
||||||
* so to maintain backwards compatability, we won't either
|
* so to maintain backwards compatability, we won't either
|
||||||
*/
|
*/
|
||||||
DBG_INFO(80, wst("TxNoCache::_createFileIndexInDir: failed to add cksum:%08X %08X file:%ls\n"), chksum, palchksum, texturefilename.c_str());
|
DBG_INFO(80, wst("TxNoCache::_createFileIndexInDir: failed to add cksum:%08X %08X file:%ls\n"), chksum, palchksum, texturefilename.c_str());
|
||||||
} else {
|
} else {
|
||||||
|
_filesIndex.insert(std::map<uint64, FileIndexEntry>::value_type(chksum64, entry));
|
||||||
DBG_INFO(80, wst("TxNoCache::_createFileIndexInDir: added cksum:%08X %08X file:%ls\n"), chksum, palchksum, texturefilename.c_str());
|
DBG_INFO(80, wst("TxNoCache::_createFileIndexInDir: added cksum:%08X %08X file:%ls\n"), chksum, palchksum, texturefilename.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ class TxHiResNoCache : public TxHiResLoader
|
||||||
bool _createFileIndexInDir(tx_wstring directory, bool update);
|
bool _createFileIndexInDir(tx_wstring directory, bool update);
|
||||||
void _clear();
|
void _clear();
|
||||||
|
|
||||||
struct fileIndexEntry_t
|
struct FileIndexEntry
|
||||||
{
|
{
|
||||||
char fname[MAX_PATH];
|
char fname[MAX_PATH];
|
||||||
tx_wstring directory;
|
tx_wstring directory;
|
||||||
|
@ -21,8 +21,10 @@ class TxHiResNoCache : public TxHiResLoader
|
||||||
tx_wstring _fullTexPath;
|
tx_wstring _fullTexPath;
|
||||||
tx_wstring _ident;
|
tx_wstring _ident;
|
||||||
char _identc[MAX_PATH];
|
char _identc[MAX_PATH];
|
||||||
std::map<uint64, fileIndexEntry_t> _filesIndex;
|
using FileIndexMap = std::multimap<uint64, FileIndexEntry>;
|
||||||
std::map<uint64, GHQTexInfo> _loadedTex;
|
FileIndexMap _filesIndex;
|
||||||
|
FileIndexMap::const_iterator findFile(Checksum checksum, N64FormatSize n64FmtSz) const;
|
||||||
|
std::multimap<uint64, GHQTexInfo> _loadedTex;
|
||||||
dispInfoFuncExt _callback;
|
dispInfoFuncExt _callback;
|
||||||
public:
|
public:
|
||||||
~TxHiResNoCache();
|
~TxHiResNoCache();
|
||||||
|
@ -37,7 +39,7 @@ class TxHiResNoCache : public TxHiResLoader
|
||||||
dispInfoFuncExt callback);
|
dispInfoFuncExt callback);
|
||||||
bool empty() const override;
|
bool empty() const override;
|
||||||
bool add(Checksum checksum, GHQTexInfo *info, int dataSize = 0) override { return false; }
|
bool add(Checksum checksum, GHQTexInfo *info, int dataSize = 0) override { return false; }
|
||||||
bool get(Checksum checksum, GHQTexInfo *info) override;
|
bool get(Checksum checksum, N64FormatSize n64FmtSz, GHQTexInfo *info) override;
|
||||||
bool reload() override;
|
bool reload() override;
|
||||||
void dump() override { };
|
void dump() override { };
|
||||||
};
|
};
|
||||||
|
|
|
@ -53,7 +53,7 @@ TxTexCache::TxTexCache(int options, int cachesize, const wchar_t *cachePath, con
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TxTexCache::add(uint64 checksum, GHQTexInfo *info)
|
bool TxTexCache::add(Checksum checksum, GHQTexInfo *info)
|
||||||
{
|
{
|
||||||
const bool res = TxCache::add(checksum, info);
|
const bool res = TxCache::add(checksum, info);
|
||||||
if (res)
|
if (res)
|
||||||
|
|
|
@ -37,7 +37,7 @@ private:
|
||||||
public:
|
public:
|
||||||
~TxTexCache();
|
~TxTexCache();
|
||||||
TxTexCache(int options, int cachesize, const wchar_t *cachePath, const wchar_t *ident, dispInfoFuncExt callback);
|
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);
|
bool add(Checksum checksum, GHQTexInfo *info);
|
||||||
void dump();
|
void dump();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -994,11 +994,10 @@ bool TextureCache::_loadHiresBackground(CachedTexture *_pTexture, u64 & _ricecrc
|
||||||
}
|
}
|
||||||
|
|
||||||
_ricecrc = txfilter_checksum(addr, tile_width,
|
_ricecrc = txfilter_checksum(addr, tile_width,
|
||||||
tile_height, (unsigned short)(gSP.bgImage.format << 8 | gSP.bgImage.size),
|
tile_height, gSP.bgImage.size, bpl, paladdr);
|
||||||
bpl, paladdr);
|
|
||||||
GHQTexInfo ghqTexInfo;
|
GHQTexInfo ghqTexInfo;
|
||||||
// TODO: fix problem with zero texture dimensions on GLideNHQ side.
|
// TODO: fix problem with zero texture dimensions on GLideNHQ side.
|
||||||
if (txfilter_hirestex(_pTexture->crc, _ricecrc, palette, &ghqTexInfo) &&
|
if (txfilter_hirestex(_pTexture->crc, _ricecrc, palette, N64FormatSize(_pTexture->format, _pTexture->size), &ghqTexInfo) &&
|
||||||
ghqTexInfo.width != 0 && ghqTexInfo.height != 0) {
|
ghqTexInfo.width != 0 && ghqTexInfo.height != 0) {
|
||||||
ghqTexInfo.format = gfxContext.convertInternalTextureFormat(ghqTexInfo.format);
|
ghqTexInfo.format = gfxContext.convertInternalTextureFormat(ghqTexInfo.format);
|
||||||
Context::InitTextureParams params;
|
Context::InitTextureParams params;
|
||||||
|
@ -1096,7 +1095,7 @@ void TextureCache::_loadBackground(CachedTexture *pTexture)
|
||||||
config.hotkeys.enabledKeys[Config::HotKey::hkTexDump] != 0) {
|
config.hotkeys.enabledKeys[Config::HotKey::hkTexDump] != 0) {
|
||||||
txfilter_dmptx((u8*)pDest, pTexture->width, pTexture->height,
|
txfilter_dmptx((u8*)pDest, pTexture->width, pTexture->height,
|
||||||
pTexture->width, (u16)u32(glInternalFormat),
|
pTexture->width, (u16)u32(glInternalFormat),
|
||||||
(unsigned short)(pTexture->format << 8 | pTexture->size),
|
N64FormatSize(pTexture->format, pTexture->size),
|
||||||
ricecrc);
|
ricecrc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1106,7 +1105,7 @@ void TextureCache::_loadBackground(CachedTexture *pTexture)
|
||||||
TFH.isInited()) {
|
TFH.isInited()) {
|
||||||
GHQTexInfo ghqTexInfo;
|
GHQTexInfo ghqTexInfo;
|
||||||
if (txfilter_filter((u8*)pDest, pTexture->width, pTexture->height,
|
if (txfilter_filter((u8*)pDest, pTexture->width, pTexture->height,
|
||||||
(u16)u32(glInternalFormat), (uint64)pTexture->crc, &ghqTexInfo) != 0 &&
|
(u16)u32(glInternalFormat), pTexture->crc, N64FormatSize(pTexture->format, pTexture->size), &ghqTexInfo) != 0 &&
|
||||||
ghqTexInfo.data != nullptr) {
|
ghqTexInfo.data != nullptr) {
|
||||||
|
|
||||||
if (ghqTexInfo.width % 2 != 0 &&
|
if (ghqTexInfo.width % 2 != 0 &&
|
||||||
|
@ -1220,10 +1219,10 @@ bool TextureCache::_loadHiresTexture(u32 _tile, CachedTexture *_pTexture, u64 &
|
||||||
// palette = (rdp.pal_8 + (gSP.textureTile[_t]->palette << 4));
|
// palette = (rdp.pal_8 + (gSP.textureTile[_t]->palette << 4));
|
||||||
}
|
}
|
||||||
|
|
||||||
_ricecrc = txfilter_checksum(addr, width, height, (unsigned short)(_pTexture->format << 8 | _pTexture->size), bpl, paladdr);
|
_ricecrc = txfilter_checksum(addr, width, height, _pTexture->size, bpl, paladdr);
|
||||||
GHQTexInfo ghqTexInfo;
|
GHQTexInfo ghqTexInfo;
|
||||||
// TODO: fix problem with zero texture dimensions on GLideNHQ side.
|
// TODO: fix problem with zero texture dimensions on GLideNHQ side.
|
||||||
if (txfilter_hirestex(_pTexture->crc, _ricecrc, palette, &ghqTexInfo) &&
|
if (txfilter_hirestex(_pTexture->crc, _ricecrc, palette, N64FormatSize(_pTexture->format, _pTexture->size), &ghqTexInfo) &&
|
||||||
ghqTexInfo.width != 0 && ghqTexInfo.height != 0) {
|
ghqTexInfo.width != 0 && ghqTexInfo.height != 0) {
|
||||||
ghqTexInfo.format = gfxContext.convertInternalTextureFormat(ghqTexInfo.format);
|
ghqTexInfo.format = gfxContext.convertInternalTextureFormat(ghqTexInfo.format);
|
||||||
Context::InitTextureParams params;
|
Context::InitTextureParams params;
|
||||||
|
@ -1491,7 +1490,7 @@ void TextureCache::_loadFast(u32 _tile, CachedTexture *_pTexture)
|
||||||
config.hotkeys.enabledKeys[Config::HotKey::hkTexDump] != 0) {
|
config.hotkeys.enabledKeys[Config::HotKey::hkTexDump] != 0) {
|
||||||
txfilter_dmptx((u8*)m_tempTextureHolder.data(), tmptex.width, tmptex.height,
|
txfilter_dmptx((u8*)m_tempTextureHolder.data(), tmptex.width, tmptex.height,
|
||||||
tmptex.width, (u16)u32(glInternalFormat),
|
tmptex.width, (u16)u32(glInternalFormat),
|
||||||
(unsigned short)(_pTexture->format << 8 | _pTexture->size),
|
N64FormatSize(_pTexture->format, _pTexture->size),
|
||||||
ricecrc);
|
ricecrc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1518,6 +1517,7 @@ void TextureCache::_loadFast(u32 _tile, CachedTexture *_pTexture)
|
||||||
GHQTexInfo ghqTexInfo;
|
GHQTexInfo ghqTexInfo;
|
||||||
if (txfilter_filter((u8*)m_tempTextureHolder.data(), tmptex.width, tmptex.height,
|
if (txfilter_filter((u8*)m_tempTextureHolder.data(), tmptex.width, tmptex.height,
|
||||||
(u16)u32(glInternalFormat), (uint64)_pTexture->crc,
|
(u16)u32(glInternalFormat), (uint64)_pTexture->crc,
|
||||||
|
N64FormatSize(_pTexture->format, _pTexture->size),
|
||||||
&ghqTexInfo) != 0 && ghqTexInfo.data != nullptr) {
|
&ghqTexInfo) != 0 && ghqTexInfo.data != nullptr) {
|
||||||
if (ghqTexInfo.width % 2 != 0 &&
|
if (ghqTexInfo.width % 2 != 0 &&
|
||||||
ghqTexInfo.format != u32(internalcolorFormat::RGBA8) &&
|
ghqTexInfo.format != u32(internalcolorFormat::RGBA8) &&
|
||||||
|
@ -1665,7 +1665,7 @@ void TextureCache::_loadAccurate(u32 _tile, CachedTexture *_pTexture)
|
||||||
config.hotkeys.enabledKeys[Config::HotKey::hkTexDump] != 0) {
|
config.hotkeys.enabledKeys[Config::HotKey::hkTexDump] != 0) {
|
||||||
txfilter_dmptx((u8*)(m_tempTextureHolder.data() + texDataOffset), tmptex.width, tmptex.height,
|
txfilter_dmptx((u8*)(m_tempTextureHolder.data() + texDataOffset), tmptex.width, tmptex.height,
|
||||||
tmptex.width, (u16)u32(glInternalFormat),
|
tmptex.width, (u16)u32(glInternalFormat),
|
||||||
(unsigned short)(_pTexture->format << 8 | _pTexture->size),
|
N64FormatSize(_pTexture->format, _pTexture->size),
|
||||||
ricecrc);
|
ricecrc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1723,7 +1723,7 @@ void TextureCache::_loadAccurate(u32 _tile, CachedTexture *_pTexture)
|
||||||
config.hotkeys.enabledKeys[Config::HotKey::hkTexDump] != 0) {
|
config.hotkeys.enabledKeys[Config::HotKey::hkTexDump] != 0) {
|
||||||
txfilter_dmptx((u8*)m_tempTextureHolder.data(), tmptex.width, tmptex.height,
|
txfilter_dmptx((u8*)m_tempTextureHolder.data(), tmptex.width, tmptex.height,
|
||||||
tmptex.width, (u16)u32(glInternalFormat),
|
tmptex.width, (u16)u32(glInternalFormat),
|
||||||
(unsigned short)(_pTexture->format << 8 | _pTexture->size),
|
N64FormatSize(_pTexture->format, _pTexture->size),
|
||||||
ricecrc);
|
ricecrc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1750,6 +1750,7 @@ void TextureCache::_loadAccurate(u32 _tile, CachedTexture *_pTexture)
|
||||||
GHQTexInfo ghqTexInfo;
|
GHQTexInfo ghqTexInfo;
|
||||||
if (txfilter_filter((u8*)m_tempTextureHolder.data(), tmptex.width, tmptex.height,
|
if (txfilter_filter((u8*)m_tempTextureHolder.data(), tmptex.width, tmptex.height,
|
||||||
(u16)u32(glInternalFormat), (uint64)_pTexture->crc,
|
(u16)u32(glInternalFormat), (uint64)_pTexture->crc,
|
||||||
|
N64FormatSize(_pTexture->format, _pTexture->size),
|
||||||
&ghqTexInfo) != 0 && ghqTexInfo.data != nullptr) {
|
&ghqTexInfo) != 0 && ghqTexInfo.data != nullptr) {
|
||||||
if (ghqTexInfo.width % 2 != 0 &&
|
if (ghqTexInfo.width % 2 != 0 &&
|
||||||
ghqTexInfo.format != u32(internalcolorFormat::RGBA8) &&
|
ghqTexInfo.format != u32(internalcolorFormat::RGBA8) &&
|
||||||
|
|
Loading…
Reference in New Issue
Block a user