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 "TxDbg.h"
|
||||
|
||||
#define TXCACHE_FORMAT_VERSION UNDEFINED_1
|
||||
|
||||
class TxCacheImpl
|
||||
{
|
||||
public:
|
||||
virtual ~TxCacheImpl() = default;
|
||||
|
||||
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 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 bool isCached(Checksum checksum, N64FormatSize n64FmtSz) const = 0;
|
||||
virtual void clear() = 0;
|
||||
virtual bool empty() const = 0;
|
||||
virtual uint32 getOptions() const = 0;
|
||||
|
@ -68,12 +70,12 @@ public:
|
|||
~TxMemoryCache();
|
||||
|
||||
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 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;
|
||||
bool isCached(Checksum checksum, N64FormatSize n64FmtSz) const override;
|
||||
void clear() override;
|
||||
bool empty() const override { return _cache.empty(); }
|
||||
|
||||
|
@ -95,12 +97,15 @@ private:
|
|||
uint64 _cacheLimit;
|
||||
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;
|
||||
|
||||
uint8 *_gzdest0 = nullptr;
|
||||
uint8 *_gzdest1 = nullptr;
|
||||
uint32 _gzdestLen = 0;
|
||||
bool _isOldVersion = false;
|
||||
};
|
||||
|
||||
TxMemoryCache::TxMemoryCache(uint32 options,
|
||||
|
@ -133,11 +138,11 @@ TxMemoryCache::~TxMemoryCache()
|
|||
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. */
|
||||
|
||||
if (!checksum || !info->data || _cache.find(checksum) != _cache.end())
|
||||
if (!checksum || !info->data || find(checksum, info->n64_format_size) != _cache.end())
|
||||
return false;
|
||||
|
||||
uint8 *dest = info->data;
|
||||
|
@ -206,7 +211,7 @@ bool TxMemoryCache::add(Checksum checksum, GHQTexInfo *info, int dataSize)
|
|||
memcpy(tmpdata, dest, dataSize);
|
||||
|
||||
/* copy it */
|
||||
memcpy(&txCache->info, info, sizeof(GHQTexInfo));
|
||||
txCache->info = *info;
|
||||
txCache->info.data = tmpdata;
|
||||
txCache->info.format = format;
|
||||
txCache->size = dataSize;
|
||||
|
@ -221,7 +226,7 @@ bool TxMemoryCache::add(Checksum checksum, GHQTexInfo *info, int dataSize)
|
|||
|
||||
#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,
|
||||
_cache.size(), checksum._palette, checksum._texture,
|
||||
info->width, info->height, info->format & 0xffff, (double)_totalSize / 1000000);
|
||||
|
||||
if (_cacheLimit != 0) {
|
||||
|
@ -239,16 +244,31 @@ bool TxMemoryCache::add(Checksum checksum, GHQTexInfo *info, int dataSize)
|
|||
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())
|
||||
return false;
|
||||
|
||||
/* find a match in cache */
|
||||
auto itMap = _cache.find(checksum);
|
||||
if (itMap != _cache.end()) {
|
||||
auto itMap = find(checksum, n64FmtSz);
|
||||
if (itMap == _cache.end())
|
||||
return false;
|
||||
|
||||
/* yep, we've got it. */
|
||||
memcpy(info, &(((*itMap).second)->info), sizeof(GHQTexInfo));
|
||||
*info = ((*itMap).second)->info;
|
||||
|
||||
/* push it to the back of the list */
|
||||
if (_cacheLimit != 0) {
|
||||
|
@ -271,9 +291,6 @@ bool TxMemoryCache::get(Checksum checksum, GHQTexInfo *info)
|
|||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
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");
|
||||
DBG_INFO(80, wst("gzfp:%x file:%ls\n"), gzfp, filename);
|
||||
if (gzfp) {
|
||||
/* write current version */
|
||||
int version = TXCACHE_FORMAT_VERSION;
|
||||
gzwrite(gzfp, &version, 4);
|
||||
|
||||
/* write header to determine config match */
|
||||
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.pixel_type), 2);
|
||||
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, 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. */
|
||||
int dataSize;
|
||||
uint64 checksum;
|
||||
int tmpconfig;
|
||||
|
||||
int version = 0;
|
||||
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) {
|
||||
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.pixel_type, 2);
|
||||
gzread(gzfp, &tmpInfo.is_hires_tex, 1);
|
||||
if (!_isOldVersion)
|
||||
gzread(gzfp, &tmpInfo.n64_format_size._formatsize, 2);
|
||||
|
||||
gzread(gzfp, &dataSize, 4);
|
||||
|
||||
|
@ -445,7 +479,7 @@ bool TxMemoryCache::del(Checksum checksum)
|
|||
delete (*itMap).second;
|
||||
_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;
|
||||
}
|
||||
|
@ -453,9 +487,9 @@ bool TxMemoryCache::del(Checksum checksum)
|
|||
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()
|
||||
|
@ -485,12 +519,12 @@ public:
|
|||
~TxFileStorage() = default;
|
||||
|
||||
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 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;
|
||||
bool isCached(Checksum checksum, N64FormatSize n64FmtSz) const override;
|
||||
void clear() override;
|
||||
bool empty() const override { return _storage.empty(); }
|
||||
|
||||
|
@ -513,8 +547,19 @@ private:
|
|||
dispInfoFuncExt _callback;
|
||||
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::const_iterator find(Checksum checksum, N64FormatSize n64FmtSz) const;
|
||||
|
||||
uint8 *_gzdest0 = nullptr;
|
||||
uint8 *_gzdest1 = nullptr;
|
||||
|
@ -524,12 +569,15 @@ private:
|
|||
std::ofstream _outfile;
|
||||
int64 _storagePos = 0;
|
||||
bool _dirty = false;
|
||||
bool _isOldVersion = false;
|
||||
static const int _fakeConfig;
|
||||
static const int64 _initialPos;
|
||||
static const int64 _initialPosOld;
|
||||
};
|
||||
|
||||
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,
|
||||
const wchar_t *cachePath,
|
||||
|
@ -594,6 +642,8 @@ bool TxFileStorage::open(bool forRead)
|
|||
if (!_outfile.good())
|
||||
return false;
|
||||
|
||||
const int version = TXCACHE_FORMAT_VERSION;
|
||||
FWRITE(version);
|
||||
FWRITE(_fakeConfig);
|
||||
_storagePos = _initialPos;
|
||||
FWRITE(_storagePos);
|
||||
|
@ -616,6 +666,8 @@ void TxFileStorage::clear()
|
|||
_outfile.close();
|
||||
|
||||
_outfile.open(_fullPath, std::ofstream::out | std::ofstream::binary | std::ofstream::trunc);
|
||||
const int version = TXCACHE_FORMAT_VERSION;
|
||||
FWRITE(version);
|
||||
FWRITE(_fakeConfig);
|
||||
_storagePos = _initialPos;
|
||||
FWRITE(_storagePos);
|
||||
|
@ -632,6 +684,7 @@ bool TxFileStorage::writeData(uint32 dataSize, const GHQTexInfo & info)
|
|||
FWRITE(info.texture_format);
|
||||
FWRITE(info.pixel_type);
|
||||
FWRITE(info.is_hires_tex);
|
||||
FWRITE(info.n64_format_size._formatsize);
|
||||
FWRITE(dataSize);
|
||||
_outfile.write((char*)info.data, dataSize);
|
||||
return _outfile.good();
|
||||
|
@ -645,6 +698,8 @@ bool TxFileStorage::readData(GHQTexInfo & info)
|
|||
FREAD(info.texture_format);
|
||||
FREAD(info.pixel_type);
|
||||
FREAD(info.is_hires_tex);
|
||||
if (!_isOldVersion)
|
||||
FREAD(info.n64_format_size._formatsize);
|
||||
|
||||
uint32 dataSize = 0U;
|
||||
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. */
|
||||
|
||||
if (!checksum || !info->data || _storage.find(checksum) != _storage.end())
|
||||
if (!checksum || !info->data || isCached(checksum, info->n64_format_size))
|
||||
return false;
|
||||
|
||||
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);
|
||||
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))
|
||||
return false;
|
||||
_storagePos = _outfile.tellp();
|
||||
|
@ -733,7 +792,7 @@ bool TxFileStorage::add(Checksum checksum, GHQTexInfo *info, int dataSize)
|
|||
|
||||
#ifdef DEBUG
|
||||
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);
|
||||
#endif
|
||||
|
||||
|
@ -743,13 +802,26 @@ bool TxFileStorage::add(Checksum checksum, GHQTexInfo *info, int dataSize)
|
|||
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())
|
||||
return false;
|
||||
|
||||
/* find a match in storage */
|
||||
auto itMap = _storage.find(checksum);
|
||||
auto itMap = find(checksum, n64FmtSz);
|
||||
if (itMap == _storage.end())
|
||||
return false;
|
||||
|
||||
|
@ -757,7 +829,7 @@ bool TxFileStorage::get(Checksum checksum, GHQTexInfo *info)
|
|||
if (!open(true))
|
||||
return false;
|
||||
|
||||
_infile.seekg(itMap->second, std::ifstream::beg);
|
||||
_infile.seekg(itMap->second._offset, std::ifstream::beg);
|
||||
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);
|
||||
|
||||
int version = TXCACHE_FORMAT_VERSION;
|
||||
FWRITE(version);
|
||||
FWRITE(config);
|
||||
FWRITE(_storagePos);
|
||||
_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"));
|
||||
for (auto& item : _storage) {
|
||||
FWRITE(item.first);
|
||||
FWRITE(item.second);
|
||||
FWRITE(item.second._data);
|
||||
}
|
||||
_outfile.close();
|
||||
if (_callback)
|
||||
|
@ -813,9 +887,14 @@ bool TxFileStorage::load(const wchar_t *path, const wchar_t *filename, int confi
|
|||
if (!open(true))
|
||||
return false;
|
||||
|
||||
int version = 0;
|
||||
int tmpconfig = 0;
|
||||
/* read header to determine config match */
|
||||
/* read version */
|
||||
_infile.seekg(0L, std::ifstream::beg);
|
||||
FREAD(version);
|
||||
if (version == TXCACHE_FORMAT_VERSION) {
|
||||
_isOldVersion = false;
|
||||
/* read header to determine config match */
|
||||
FREAD(tmpconfig);
|
||||
FREAD(_storagePos);
|
||||
if (tmpconfig == _fakeConfig) {
|
||||
|
@ -824,8 +903,22 @@ bool TxFileStorage::load(const wchar_t *path, const wchar_t *filename, int confi
|
|||
} else if (tmpconfig != config && !force)
|
||||
return false;
|
||||
|
||||
if (_storagePos <= sizeof(config) + sizeof(_storagePos))
|
||||
if (_storagePos <= _initialPos)
|
||||
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);
|
||||
|
||||
int storageSize = 0;
|
||||
|
@ -849,9 +942,9 @@ bool TxFileStorage::load(const wchar_t *path, const wchar_t *filename, int confi
|
|||
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 *************************************/
|
||||
|
@ -886,9 +979,9 @@ bool TxCache::add(Checksum checksum, GHQTexInfo *info, int 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
|
||||
|
@ -921,9 +1014,9 @@ bool TxCache::del(Checksum 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()
|
||||
|
|
|
@ -31,27 +31,6 @@
|
|||
#include "TxInternal.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 TxCache
|
||||
|
@ -66,8 +45,8 @@ protected:
|
|||
|
||||
bool save();
|
||||
bool load(bool force);
|
||||
bool del(Checksum checksum); /* checksum hi:palette low:texture */
|
||||
bool isCached(Checksum checksum); /* checksum hi:palette low:texture */
|
||||
bool del(Checksum checksum);
|
||||
bool isCached(Checksum checksum, N64FormatSize n64FmtSz) const;
|
||||
void clear();
|
||||
uint64 size() const; // number of elements
|
||||
uint64 totalSize() const; // size of elements in bytes
|
||||
|
@ -82,7 +61,7 @@ public:
|
|||
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 get(Checksum checksum, N64FormatSize n64FmtSz, GHQTexInfo *info);
|
||||
bool empty() const;
|
||||
};
|
||||
|
||||
|
|
|
@ -164,7 +164,7 @@ TxFilter::TxFilter(int maxwidth,
|
|||
}
|
||||
|
||||
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 *tmptex = _tex1;
|
||||
|
@ -186,7 +186,7 @@ TxFilter::filter(uint8 *src, int srcwidth, int srcheight, ColorFormat srcformat,
|
|||
|
||||
/* check if we have it in cache */
|
||||
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);
|
||||
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->height = srcheight;
|
||||
info->is_hires_tex = 0;
|
||||
info->n64_format_size = n64FmtSz;
|
||||
setTextureFormat(destformat, info);
|
||||
|
||||
/* cache the texture. */
|
||||
|
@ -463,7 +464,7 @@ TxFilter::filter(uint8 *src, int srcwidth, int srcheight, ColorFormat srcformat,
|
|||
}
|
||||
|
||||
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.
|
||||
* 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"),
|
||||
(uint32)(r_crc64 >> 32), (uint32)(r_crc64 & 0xffffffff),
|
||||
r_crc64._palette, r_crc64._texture,
|
||||
(uint32)(g64crc >> 32), (uint32)(g64crc & 0xffffffff));
|
||||
|
||||
#if HIRES_TEXTURE
|
||||
/* check if we have it in hires memory cache. */
|
||||
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);
|
||||
|
||||
/* TODO: Enable emulation for special N64 combiner modes. There are few ways
|
||||
|
@ -509,8 +510,8 @@ TxFilter::hirestex(uint64 g64crc, uint64 r_crc64, uint16 *palette, GHQTexInfo *i
|
|||
|
||||
return 1; /* yep, got it */
|
||||
}
|
||||
if (_txHiResLoader->get((r_crc64 >> 32), info) ||
|
||||
_txHiResLoader->get((r_crc64 & 0xffffffff), info)) {
|
||||
if (_txHiResLoader->get(r_crc64._palette, n64FmtSz, 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);
|
||||
|
||||
/* for true CI textures, we use the passed in palette to convert to
|
||||
|
@ -543,6 +544,7 @@ TxFilter::hirestex(uint64 g64crc, uint64 r_crc64, uint16 *palette, GHQTexInfo *i
|
|||
info->width = width;
|
||||
info->height = height;
|
||||
info->is_hires_tex = 1;
|
||||
info->n64_format_size = n64FmtSz;
|
||||
setTextureFormat(format, info);
|
||||
|
||||
/* 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 */
|
||||
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);
|
||||
return 1; /* yep, we've got it */
|
||||
}
|
||||
|
@ -579,7 +581,7 @@ TxFilter::checksum64(uint8 *src, int width, int height, int size, int rowStride,
|
|||
}
|
||||
|
||||
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);
|
||||
if (!_initialized)
|
||||
|
@ -588,9 +590,9 @@ TxFilter::dmptx(uint8 *src, int width, int height, int rowStridePixel, ColorForm
|
|||
if (!(_options & DUMP_TEX))
|
||||
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"),
|
||||
(uint32)(r_crc64 >> 32), (uint32)(r_crc64 & 0xffffffff));
|
||||
r_crc64._palette, r_crc64._texture);
|
||||
|
||||
if (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)
|
||||
return 0;
|
||||
|
||||
if ((n64fmt >> 8) == 0x2) {
|
||||
if (n64FmtSz._format == 0x2) {
|
||||
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);
|
||||
} else {
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -70,13 +70,15 @@ public:
|
|||
int srcheight,
|
||||
ColorFormat srcformat,
|
||||
uint64 g64crc, /* glide64 crc, 64bit for future use */
|
||||
N64FormatSize n64FmtSz,
|
||||
GHQTexInfo *info);
|
||||
boolean hirestex(uint64 g64crc, /* glide64 crc, 64bit for future use */
|
||||
uint64 r_crc64, /* checksum hi:palette low:texture */
|
||||
Checksum r_crc64,
|
||||
uint16 *palette,
|
||||
N64FormatSize n64FmtSz,
|
||||
GHQTexInfo *info);
|
||||
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();
|
||||
void dumpcache();
|
||||
};
|
||||
|
|
|
@ -57,20 +57,20 @@ txfilter_shutdown(void)
|
|||
|
||||
TAPI boolean TAPIENTRY
|
||||
txfilter_filter(uint8 *src, int srcwidth, int srcheight, uint16 srcformat,
|
||||
uint64 g64crc, GHQTexInfo *info)
|
||||
uint64 g64crc, N64FormatSize n64FmtSz, GHQTexInfo *info)
|
||||
{
|
||||
if (txFilter)
|
||||
return txFilter->filter(src, srcwidth, srcheight, ColorFormat(u32(srcformat)),
|
||||
g64crc, info);
|
||||
g64crc, n64FmtSz, info);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
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)
|
||||
return txFilter->hirestex(g64crc, r_crc64, palette, info);
|
||||
return txFilter->hirestex(g64crc, r_crc64, palette, n64FmtSz, info);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -85,10 +85,10 @@ txfilter_checksum(uint8 *src, int width, int height, int size, int rowStride, ui
|
|||
}
|
||||
|
||||
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)
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -45,6 +45,9 @@
|
|||
#define CHDIR(a) chdir(a)
|
||||
#endif
|
||||
|
||||
typedef unsigned char uint8;
|
||||
typedef unsigned short uint16;
|
||||
typedef unsigned int uint32;
|
||||
#ifdef __MSC__
|
||||
typedef __int64 int64;
|
||||
typedef unsigned __int64 uint64;
|
||||
|
@ -100,21 +103,77 @@ typedef unsigned char boolean;
|
|||
#define GZ_HIRESTEXCACHE 0x00800000
|
||||
#define DUMP_TEXCACHE 0x01000000
|
||||
#define DUMP_HIRESTEXCACHE 0x02000000
|
||||
#define TILE_HIRESTEX 0x04000000
|
||||
#define UNDEFINED_0 0x08000000
|
||||
#define UNDEFINED_0 0x04000000
|
||||
#define UNDEFINED_1 0x08000000
|
||||
#define FORCE16BPP_HIRESTEX 0x10000000
|
||||
#define FORCE16BPP_TEX 0x20000000
|
||||
#define LET_TEXARTISTS_FLY 0x40000000 /* a little freedom for texture artists */
|
||||
#define DUMP_TEX 0x80000000
|
||||
|
||||
struct GHQTexInfo {
|
||||
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;
|
||||
struct Checksum
|
||||
{
|
||||
union
|
||||
{
|
||||
uint64 _checksum; /* checksum hi:palette low:texture */
|
||||
struct
|
||||
{
|
||||
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.
|
||||
|
@ -155,10 +214,6 @@ typedef void (*dispInfoFuncExt)(const wchar_t *format, ...);
|
|||
#endif
|
||||
#endif // OS_WINDOWS
|
||||
|
||||
typedef unsigned char uint8;
|
||||
typedef unsigned short uint16;
|
||||
typedef unsigned int uint32;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"{
|
||||
#endif
|
||||
|
@ -173,16 +228,16 @@ txfilter_shutdown(void);
|
|||
|
||||
TAPI boolean TAPIENTRY
|
||||
txfilter_filter(uint8 *src, int srcwidth, int srcheight, uint16 srcformat,
|
||||
uint64 g64crc, GHQTexInfo *info);
|
||||
uint64 g64crc, N64FormatSize n64FmtSz, GHQTexInfo *info);
|
||||
|
||||
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
|
||||
txfilter_checksum(uint8 *src, int width, int height, int size, int rowStride, uint8 *palette);
|
||||
|
||||
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
|
||||
txfilter_reloadhirestex();
|
||||
|
|
|
@ -97,7 +97,6 @@ int TxHiResCache::_getConfig() const
|
|||
{
|
||||
return getOptions() &
|
||||
(HIRESTEXTURES_MASK |
|
||||
TILE_HIRESTEX |
|
||||
FORCE16BPP_HIRESTEX |
|
||||
GZ_HIRESTEXCACHE |
|
||||
FILE_HIRESTEXCACHE |
|
||||
|
@ -251,7 +250,7 @@ TxHiResCache::LoadResult TxHiResCache::_loadHiResTextures(const wchar_t * dir_pa
|
|||
chksum64 <<= 32;
|
||||
chksum64 |= (uint64)chksum;
|
||||
}
|
||||
if (isCached(chksum64)) {
|
||||
if (isCached(chksum64, N64FormatSize(fmt, siz))) {
|
||||
#if !DEBUG
|
||||
INFO(80, wst("-----\n"));
|
||||
INFO(80, wst("file: %s\n"), fname);
|
||||
|
@ -281,6 +280,7 @@ TxHiResCache::LoadResult TxHiResCache::_loadHiResTextures(const wchar_t * dir_pa
|
|||
tmpInfo.width = width;
|
||||
tmpInfo.height = height;
|
||||
tmpInfo.is_hires_tex = 1;
|
||||
tmpInfo.n64_format_size = N64FormatSize(fmt, siz);
|
||||
setTextureFormat(format, &tmpInfo);
|
||||
|
||||
/* remove redundant in cache */
|
||||
|
@ -325,7 +325,7 @@ bool TxHiResCache::add(Checksum checksum, GHQTexInfo *info, int 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);
|
||||
bool empty() const 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;
|
||||
void dump() override;
|
||||
};
|
||||
|
|
|
@ -571,4 +571,3 @@ uint8_t* TxHiResLoader::loadFileInfoTex(char* fname,
|
|||
|
||||
return tex;
|
||||
}
|
||||
|
||||
|
|
|
@ -42,7 +42,7 @@ public:
|
|||
|
||||
virtual bool empty() const = 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 void dump() = 0;
|
||||
};
|
||||
|
|
|
@ -49,30 +49,44 @@ bool TxHiResNoCache::empty() const
|
|||
return _filesIndex.empty();
|
||||
}
|
||||
|
||||
bool TxHiResNoCache::get(Checksum checksum, GHQTexInfo *info)
|
||||
TxHiResNoCache::FileIndexMap::const_iterator TxHiResNoCache::findFile(Checksum checksum, N64FormatSize n64FmtSz) const
|
||||
{
|
||||
if (!checksum) {
|
||||
return false;
|
||||
auto range = _filesIndex.equal_range(checksum);
|
||||
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._checksum & 0xffffffff;
|
||||
uint32 palchksum = checksum._checksum >> 32;
|
||||
#endif
|
||||
uint32 chksum = checksum._texture;
|
||||
uint32 palchksum = checksum._palette;
|
||||
|
||||
/* loop over each file from the index and try to match it with checksum */
|
||||
auto indexEntry = _filesIndex.find(checksum);
|
||||
if (indexEntry == _filesIndex.end()) {
|
||||
auto indexEntry = findFile(checksum, n64FmtSz);
|
||||
if (indexEntry == _filesIndex.cend()) {
|
||||
DBG_INFO(80, wst("TxNoCache::get: chksum:%08X %08X not found\n"), chksum, palchksum);
|
||||
return false;
|
||||
}
|
||||
|
||||
fileIndexEntry_t& entry = indexEntry->second;
|
||||
auto entry = indexEntry->second;
|
||||
|
||||
/* make sure to not load the same texture twice */
|
||||
auto loadedTexMap = _loadedTex.find(checksum);
|
||||
if (loadedTexMap != _loadedTex.end()) {
|
||||
auto findTex = [n64FmtSz, this](Checksum checksum)
|
||||
{
|
||||
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);
|
||||
*info = loadedTexMap->second;
|
||||
return true;
|
||||
|
@ -113,6 +127,7 @@ bool TxHiResNoCache::get(Checksum checksum, GHQTexInfo *info)
|
|||
info->width = width;
|
||||
info->height = height;
|
||||
info->is_hires_tex = 1;
|
||||
info->n64_format_size = n64FmtSz;
|
||||
setTextureFormat(format, info);
|
||||
|
||||
/* add to loaded textures */
|
||||
|
@ -180,9 +195,8 @@ bool TxHiResNoCache::_createFileIndexInDir(tx_wstring directory, bool update)
|
|||
|
||||
uint64 chksum64 = 0;
|
||||
uint32 chksum = 0, palchksum = 0, length = 0;
|
||||
fileIndexEntry_t entry;
|
||||
FileIndexEntry entry;
|
||||
entry.fmt = entry.siz = 0;
|
||||
bool ret = false;
|
||||
|
||||
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 */
|
||||
ret = _filesIndex.insert(std::map<uint64, fileIndexEntry_t>::value_type(chksum64, entry)).second;
|
||||
if (!ret) {
|
||||
if (findFile(chksum64, N64FormatSize(entry.fmt, entry.siz)) != _filesIndex.cend()) {
|
||||
/* technically we should probably fail here,
|
||||
* however HTS & HTC both don't fail when there are duplicates,
|
||||
* 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());
|
||||
} 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());
|
||||
}
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ class TxHiResNoCache : public TxHiResLoader
|
|||
bool _createFileIndexInDir(tx_wstring directory, bool update);
|
||||
void _clear();
|
||||
|
||||
struct fileIndexEntry_t
|
||||
struct FileIndexEntry
|
||||
{
|
||||
char fname[MAX_PATH];
|
||||
tx_wstring directory;
|
||||
|
@ -21,8 +21,10 @@ class TxHiResNoCache : public TxHiResLoader
|
|||
tx_wstring _fullTexPath;
|
||||
tx_wstring _ident;
|
||||
char _identc[MAX_PATH];
|
||||
std::map<uint64, fileIndexEntry_t> _filesIndex;
|
||||
std::map<uint64, GHQTexInfo> _loadedTex;
|
||||
using FileIndexMap = std::multimap<uint64, FileIndexEntry>;
|
||||
FileIndexMap _filesIndex;
|
||||
FileIndexMap::const_iterator findFile(Checksum checksum, N64FormatSize n64FmtSz) const;
|
||||
std::multimap<uint64, GHQTexInfo> _loadedTex;
|
||||
dispInfoFuncExt _callback;
|
||||
public:
|
||||
~TxHiResNoCache();
|
||||
|
@ -37,7 +39,7 @@ class TxHiResNoCache : public TxHiResLoader
|
|||
dispInfoFuncExt callback);
|
||||
bool empty() const override;
|
||||
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;
|
||||
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);
|
||||
if (res)
|
||||
|
|
|
@ -37,7 +37,7 @@ private:
|
|||
public:
|
||||
~TxTexCache();
|
||||
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();
|
||||
};
|
||||
|
||||
|
|
|
@ -994,11 +994,10 @@ bool TextureCache::_loadHiresBackground(CachedTexture *_pTexture, u64 & _ricecrc
|
|||
}
|
||||
|
||||
_ricecrc = txfilter_checksum(addr, tile_width,
|
||||
tile_height, (unsigned short)(gSP.bgImage.format << 8 | gSP.bgImage.size),
|
||||
bpl, paladdr);
|
||||
tile_height, gSP.bgImage.size, bpl, paladdr);
|
||||
GHQTexInfo ghqTexInfo;
|
||||
// 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.format = gfxContext.convertInternalTextureFormat(ghqTexInfo.format);
|
||||
Context::InitTextureParams params;
|
||||
|
@ -1096,7 +1095,7 @@ void TextureCache::_loadBackground(CachedTexture *pTexture)
|
|||
config.hotkeys.enabledKeys[Config::HotKey::hkTexDump] != 0) {
|
||||
txfilter_dmptx((u8*)pDest, pTexture->width, pTexture->height,
|
||||
pTexture->width, (u16)u32(glInternalFormat),
|
||||
(unsigned short)(pTexture->format << 8 | pTexture->size),
|
||||
N64FormatSize(pTexture->format, pTexture->size),
|
||||
ricecrc);
|
||||
}
|
||||
|
||||
|
@ -1106,7 +1105,7 @@ void TextureCache::_loadBackground(CachedTexture *pTexture)
|
|||
TFH.isInited()) {
|
||||
GHQTexInfo ghqTexInfo;
|
||||
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) {
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
_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;
|
||||
// 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.format = gfxContext.convertInternalTextureFormat(ghqTexInfo.format);
|
||||
Context::InitTextureParams params;
|
||||
|
@ -1491,7 +1490,7 @@ void TextureCache::_loadFast(u32 _tile, CachedTexture *_pTexture)
|
|||
config.hotkeys.enabledKeys[Config::HotKey::hkTexDump] != 0) {
|
||||
txfilter_dmptx((u8*)m_tempTextureHolder.data(), tmptex.width, tmptex.height,
|
||||
tmptex.width, (u16)u32(glInternalFormat),
|
||||
(unsigned short)(_pTexture->format << 8 | _pTexture->size),
|
||||
N64FormatSize(_pTexture->format, _pTexture->size),
|
||||
ricecrc);
|
||||
}
|
||||
|
||||
|
@ -1518,6 +1517,7 @@ void TextureCache::_loadFast(u32 _tile, CachedTexture *_pTexture)
|
|||
GHQTexInfo ghqTexInfo;
|
||||
if (txfilter_filter((u8*)m_tempTextureHolder.data(), tmptex.width, tmptex.height,
|
||||
(u16)u32(glInternalFormat), (uint64)_pTexture->crc,
|
||||
N64FormatSize(_pTexture->format, _pTexture->size),
|
||||
&ghqTexInfo) != 0 && ghqTexInfo.data != nullptr) {
|
||||
if (ghqTexInfo.width % 2 != 0 &&
|
||||
ghqTexInfo.format != u32(internalcolorFormat::RGBA8) &&
|
||||
|
@ -1665,7 +1665,7 @@ void TextureCache::_loadAccurate(u32 _tile, CachedTexture *_pTexture)
|
|||
config.hotkeys.enabledKeys[Config::HotKey::hkTexDump] != 0) {
|
||||
txfilter_dmptx((u8*)(m_tempTextureHolder.data() + texDataOffset), tmptex.width, tmptex.height,
|
||||
tmptex.width, (u16)u32(glInternalFormat),
|
||||
(unsigned short)(_pTexture->format << 8 | _pTexture->size),
|
||||
N64FormatSize(_pTexture->format, _pTexture->size),
|
||||
ricecrc);
|
||||
}
|
||||
|
||||
|
@ -1723,7 +1723,7 @@ void TextureCache::_loadAccurate(u32 _tile, CachedTexture *_pTexture)
|
|||
config.hotkeys.enabledKeys[Config::HotKey::hkTexDump] != 0) {
|
||||
txfilter_dmptx((u8*)m_tempTextureHolder.data(), tmptex.width, tmptex.height,
|
||||
tmptex.width, (u16)u32(glInternalFormat),
|
||||
(unsigned short)(_pTexture->format << 8 | _pTexture->size),
|
||||
N64FormatSize(_pTexture->format, _pTexture->size),
|
||||
ricecrc);
|
||||
}
|
||||
|
||||
|
@ -1750,6 +1750,7 @@ void TextureCache::_loadAccurate(u32 _tile, CachedTexture *_pTexture)
|
|||
GHQTexInfo ghqTexInfo;
|
||||
if (txfilter_filter((u8*)m_tempTextureHolder.data(), tmptex.width, tmptex.height,
|
||||
(u16)u32(glInternalFormat), (uint64)_pTexture->crc,
|
||||
N64FormatSize(_pTexture->format, _pTexture->size),
|
||||
&ghqTexInfo) != 0 && ghqTexInfo.data != nullptr) {
|
||||
if (ghqTexInfo.width % 2 != 0 &&
|
||||
ghqTexInfo.format != u32(internalcolorFormat::RGBA8) &&
|
||||
|
|
Loading…
Reference in New Issue
Block a user