This commit is contained in:
Amaro Martínez 2022-03-14 00:45:28 -05:00
commit d96c679436
No known key found for this signature in database
GPG Key ID: 2526D6CBCF6ADD0C
49 changed files with 7047 additions and 435 deletions

View File

@ -1,16 +1,46 @@
GLideN64
========
A new generation, open-source graphics plugin for N64 emulators.
# GLideN64[![Github Badge]][Workflow]
Latest build status for master branch:
[![GLideN64](https://github.com/gonetz/GLideN64/actions/workflows/build.yml/badge.svg?branch=master)](https://github.com/gonetz/GLideN64/actions?query=branch%3Amaster)
*A next generation* ***Graphics Plugin*** *for* ***N64*** *emulators.*
To get Continuous Integration (CI) builds for mupen64plus and zilmar-spec emulators:
* if you have a Github account, log in and click the build status icon, then click on the latest CI run.
* if you don't have a Github account, download the latest build from [the `github-actions` release.](https://github.com/gonetz/GLideN64/releases/tag/github-actions)
---
Choose the between the 32-bit and 64-bit version depending on your emulator version.
If you want to download an earlier build, log into Github and click the status icon.
## Continuous Integration
CI builds have the latest features and fixes, and are generally stable, but may introduce bugs and have incomplete translations.
**CI** builds have the latest`features`/`fixes`, are generally <br>
stable, but may introduce **bugs** and have *incomplete translations*.
<br>
To obtain **CI** builds for the`mupen64plus`& <br>
`zilmar-spec`emulators do the following :
##### With Github
Download them from the latest **[Workflow]**.
##### Without Github
Download them from the latest **[Release]**.
<br>
##### Version
*Choose between `32-bit`/`64-bit`* <br>
*according to your emulator version.*
##### Earlier Builds
*For earlier builds you will have to log in and <br>
download them from an older* ***[Workflow]****.*
<!----------------------------------------------------------------------------->
[Wiki]: https://github.com/gonetz/GLideN64/wiki
[Release]: https://github.com/gonetz/GLideN64/releases/tag/github-actions
[Workflow]: https://github.com/gonetz/GLideN64/actions?query=branch%3Amaster
[Github Badge]: https://github.com/gonetz/GLideN64/actions/workflows/build.yml/badge.svg?branch=master

View File

@ -121,12 +121,14 @@ frameBufferEmulation\N64DepthCompare=1
Good_Name=Jet Force Gemini (E)(U)
frameBufferEmulation\fbInfoDisabled=0
frameBufferEmulation\copyAuxToRDRAM=1
frameBufferEmulation\copyToRDRAM=0
[J%20F%20G%20DISPLAY]
; See Jet Force Gemini for notes
Good_Name=Jet Force Gemini Kiosk Demo (U)
frameBufferEmulation\fbInfoDisabled=0
frameBufferEmulation\copyAuxToRDRAM=1
frameBufferEmulation\copyToRDRAM=0
[J%20WORLD%20SOCCER3]
frameBufferEmulation\N64DepthCompare=1

View File

@ -11,5 +11,9 @@ cmake [-DCMAKE_BUILD_TYPE=Debug] [-DVEC4_OPT=On] [-DCRC_OPT=On] [-DX86_OPT=On] [
-DNOHQ=On - optional parameter. set to build without realtime texture enhancer library (GLideNHQ).
-DUSE_SYSTEM_LIBS=On - optional parameter. set to use system provided libraries for libpng and zlib.
-DMUPENPLUSAPI=On - required parameter. currently cmake build works only for mupen64plus version of the plugin.
-MUPENPLUSAPI_GLIDENUI=On - optional parameter. set it if you need GLideNUI for Mupen64Plus
-DODROID=On - set if you need to build on an Odroid board.
-DVERO4K=On - set if you need to build on the OSMC Vero4k.
-DANDROID=On - set if targeting an Android device
-DMESA=On - set to disable Raspberry Pi autodetection
-DGL_PROFILE=On - set to turn on GL profiling

View File

@ -41,7 +41,7 @@ void ColorBufferToRDRAM::destroy() {
bool ColorBufferToRDRAM::_prepareCopy(u32& _startAddress)
{
if (VI.width == 0 || frameBufferList().getCurrent() == nullptr)
if (VI.width == 0)
return false;
FrameBuffer * pBuffer = frameBufferList().findBuffer(_startAddress);
@ -236,7 +236,7 @@ void ColorBufferToRDRAM::copyToRDRAM(u32 _address, bool _sync)
return;
if (!_prepareCopy(_address))
return;
if (config.frameBufferEmulation.copyToRDRAM == Config::CopyToRDRAM::ctDisable)
if (config.frameBufferEmulation.copyToRDRAM == Config::CopyToRDRAM::ctDisable && config.frameBufferEmulation.fbInfoDisabled != 0)
return;
const u32 numBytes = (m_pCurFrameBuffer->m_width*m_pCurFrameBuffer->m_height) << m_pCurFrameBuffer->m_size >> 1;

View File

@ -204,6 +204,8 @@ const char* Config::hotkeyIniName(u32 _idx)
return "hkOsdRenderingResolution";
case Config::HotKey::hkForceGammaCorrection:
return "hkForceGammaCorrection";
case Config::HotKey::hkInaccurateTexCords:
return "hkInaccurateTexCords";
}
return nullptr;
}
@ -240,6 +242,8 @@ const char* Config::enabledHotkeyIniName(u32 _idx)
return "hkOsdRenderingResolutionEnabled";
case Config::HotKey::hkForceGammaCorrection:
return "hkForceGammaCorrectionEnabled";
case Config::HotKey::hkInaccurateTexCords:
return "hkInaccurateTexCordsEnabled";
}
return nullptr;
}

View File

@ -234,6 +234,7 @@ struct Config
hkOsdInternalResolution,
hkOsdRenderingResolution,
hkForceGammaCorrection,
hkInaccurateTexCords,
hkTotal
};

View File

@ -8,10 +8,6 @@
#include "PluginAPI.h"
#include "FrameBuffer.h"
#ifdef min
#undef min
#endif
bool DisplayWindow::start()
{
if (!_start())

View File

@ -143,7 +143,7 @@ void FrameBuffer::_setAndAttachTexture(ObjectHandle _fbo, CachedTexture *_pTextu
bool FrameBuffer::isAuxiliary() const
{
return m_width != VI.width;
return m_width != VI.width || m_size < G_IM_SIZ_16b;
}
void FrameBuffer::init(u32 _address, u16 _format, u16 _size, u16 _width, bool _cfb)

View File

@ -147,6 +147,7 @@ GBIInfo GBI;
void GBI_Unknown( const Gwords words )
{
DebugMsg(DEBUG_NORMAL, "UNKNOWN GBI COMMAND 0x%02X", _SHIFTR(words.w0, 24, 8));
LOG(LOG_ERROR, "UNKNOWN GBI COMMAND 0x%02X", _SHIFTR(words.w0, 24, 8));
}
void GBIInfo::init()

View File

@ -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,41 +244,53 @@ 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()) {
/* yep, we've got it. */
memcpy(info, &(((*itMap).second)->info), sizeof(GHQTexInfo));
auto itMap = find(checksum, n64FmtSz);
if (itMap == _cache.end())
return false;
/* push it to the back of the list */
if (_cacheLimit != 0) {
_cachelist.erase(((*itMap).second)->it);
_cachelist.push_back(checksum);
((*itMap).second)->it = --(_cachelist.end());
}
/* yep, we've got it. */
*info = ((*itMap).second)->info;
/* 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;
/* push it to the back of the list */
if (_cacheLimit != 0) {
_cachelist.erase(((*itMap).second)->it);
_cachelist.push_back(checksum);
((*itMap).second)->it = --(_cachelist.end());
}
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)
@ -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;
/* read header to determine config match */
gzread(gzfp, &tmpconfig, 4);
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,19 +887,38 @@ 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(tmpconfig);
FREAD(_storagePos);
if (tmpconfig == _fakeConfig) {
if (_storagePos != _initialPos)
FREAD(version);
if (version == TXCACHE_FORMAT_VERSION) {
_isOldVersion = false;
/* 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;
} else if (tmpconfig != config && !force)
return false;
if (_storagePos <= sizeof(config) + sizeof(_storagePos))
return false;
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()

View File

@ -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;
};

View File

@ -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,11 +510,11 @@ 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
/* for true CI textures, we use the passed in palette to convert to
* ARGB1555 and add it to memory cache.
*
* 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->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);
}

View File

@ -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();
};

View File

@ -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;
}

View File

@ -25,6 +25,9 @@
#define __EXT_TXFILTER_H__
#ifdef OS_WINDOWS
#ifndef NOMINMAX
#define NOMINMAX
#endif
#include <windows.h>
#define TXHMODULE HMODULE
#define DLOPEN(a) LoadLibraryW(a)
@ -45,6 +48,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 +106,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 +217,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 +231,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();

View File

@ -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);
}

View File

@ -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;
};

View File

@ -571,4 +571,3 @@ uint8_t* TxHiResLoader::loadFileInfoTex(char* fname,
return tex;
}

View File

@ -23,7 +23,7 @@ class TxHiResLoader
protected:
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);
std::unique_ptr<TxImage> _txImage;
std::unique_ptr<TxQuantize> _txQuantize;
std::unique_ptr<TxReSample> _txReSample;
@ -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;
};

View File

@ -10,7 +10,7 @@ TxHiResNoCache::TxHiResNoCache(int maxwidth,
int options,
const wchar_t *cachePath,
const wchar_t *texPackPath,
const wchar_t *fullTexPath,
const wchar_t *fullTexPath,
const wchar_t *ident,
dispInfoFuncExt callback)
: TxHiResLoader(maxwidth, maxheight, maxbpp, options)
@ -49,33 +49,50 @@ 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()) {
DBG_INFO(80, wst("TxNoCache::get: cached chksum:%08X %08X found\n"), chksum, palchksum);
*info = loadedTexMap->second;
return true;
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();
};
{
auto loadedTexMap = findTex(checksum);
if (loadedTexMap != _loadedTex.end()) {
DBG_INFO(80, wst("TxNoCache::get: cached chksum:%08X %08X found\n"), chksum, palchksum);
*info = loadedTexMap->second;
return true;
}
}
DBG_INFO(80, wst("TxNoCache::get: loading chksum:%08X %08X\n"), chksum, palchksum);
@ -113,6 +130,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 +198,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 +222,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());
}

View File

@ -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 { };
};

View File

@ -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)

View File

@ -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();
};

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,60 @@
#include "../N64.h"
#include "../Config.h"
#include "../RSP.h"
#include "../PluginAPI.h"
#include "../GLideNUI/GLideNUI.h"
#include <DisplayWindow.h>
Config config;
void Config_DoConfig(/*HWND hParent*/)
{
if (ConfigOpen)
return;
wchar_t strIniFolderPath[PLUGIN_PATH_SIZE];
api().FindPluginPath(strIniFolderPath);
#ifdef M64P_GLIDENUI
wchar_t strConfigFolderPath[PLUGIN_PATH_SIZE];
api().GetUserConfigPath(strConfigFolderPath);
if (!IsPathWriteable(strIniFolderPath)) {
CopyConfigFiles(strIniFolderPath, strConfigFolderPath);
api().GetUserConfigPath(strIniFolderPath);
}
#endif // M64P_GLIDENUI
ConfigOpen = true;
const u32 maxMsaa = dwnd().maxMSAALevel();
const u32 maxAnisotropy = dwnd().maxAnisotropy();
const bool bRestart = RunConfig(strIniFolderPath, api().isRomOpen() ? RSP.romname : nullptr, maxMsaa, maxAnisotropy);
if (config.generalEmulation.enableCustomSettings != 0)
LoadCustomRomSettings(strIniFolderPath, RSP.romname);
config.validate();
if (bRestart)
dwnd().restart();
ConfigOpen = false;
}
void Config_LoadConfig()
{
wchar_t strIniFolderPath[PLUGIN_PATH_SIZE];
api().FindPluginPath(strIniFolderPath);
#ifdef M64P_GLIDENUI
wchar_t strConfigFolderPath[PLUGIN_PATH_SIZE];
api().GetUserConfigPath(strConfigFolderPath);
if (!IsPathWriteable(strIniFolderPath)) {
CopyConfigFiles(strIniFolderPath, strConfigFolderPath);
api().GetUserConfigPath(strIniFolderPath);
}
#endif // M64P_GLIDENUI
LoadConfig(strIniFolderPath);
if (config.generalEmulation.enableCustomSettings != 0)
LoadCustomRomSettings(strIniFolderPath, RSP.romname);
config.validate();
}

130
src/GLideNUI/GLideNUI.cpp Normal file
View File

@ -0,0 +1,130 @@
#include <thread>
#include <QApplication>
#include <QTranslator>
#include "GLideNUI.h"
#include "AboutDialog.h"
#include "ConfigDialog.h"
#include "Settings.h"
#include "../Config.h"
#ifdef QT_STATICPLUGIN
#include <QtPlugin>
Q_IMPORT_PLUGIN(QWindowsIntegrationPlugin)
Q_IMPORT_PLUGIN(QICOPlugin)
Q_IMPORT_PLUGIN(QWindowsVistaStylePlugin)
#endif
//#define RUN_DIALOG_IN_THREAD
inline void initMyResource() { Q_INIT_RESOURCE(icon); }
inline void cleanMyResource() { Q_CLEANUP_RESOURCE(icon); }
static
int openConfigDialog(const wchar_t * _strFileName, const char * _romName, unsigned int _maxMSAALevel, float _maxAnisotropy, bool & _accepted)
{
cleanMyResource();
initMyResource();
QString strIniFileName = QString::fromWCharArray(_strFileName);
loadSettings(strIniFileName);
if (config.generalEmulation.enableCustomSettings != 0 && _romName != nullptr && strlen(_romName) != 0)
loadCustomRomSettings(strIniFileName, _romName);
std::unique_ptr<QApplication> pQApp;
QCoreApplication* pApp = QCoreApplication::instance();
if (pApp == nullptr) {
int argc = 0;
char * argv = 0;
pQApp.reset(new QApplication(argc, &argv));
pApp = pQApp.get();
}
QTranslator translator;
if (translator.load(getTranslationFile(), strIniFileName))
pApp->installTranslator(&translator);
ConfigDialog w(Q_NULLPTR, Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint, _maxMSAALevel, _maxAnisotropy);
w.setIniPath(strIniFileName);
w.setRomName(_romName);
w.setTitle();
w.show();
int res = pQApp ? pQApp->exec() : w.exec();
_accepted = w.isAccepted();
return res;
}
static
int openAboutDialog(const wchar_t * _strFileName)
{
cleanMyResource();
initMyResource();
int argc = 0;
char * argv = 0;
QApplication a(argc, &argv);
QTranslator translator;
if (translator.load(getTranslationFile(), QString::fromWCharArray(_strFileName)))
a.installTranslator(&translator);
AboutDialog w(Q_NULLPTR, Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint);
w.show();
return a.exec();
}
bool runConfigThread(const wchar_t * _strFileName, const char * _romName, unsigned int _maxMSAALevel, unsigned int _maxAnisotropy) {
bool accepted = false;
#ifdef RUN_DIALOG_IN_THREAD
std::thread configThread(openConfigDialog, _strFileName, _maxMSAALevel, std::ref(accepted));
configThread.join();
#else
openConfigDialog(_strFileName, _romName, _maxMSAALevel, _maxAnisotropy, accepted);
#endif
return accepted;
}
int runAboutThread(const wchar_t * _strFileName) {
#ifdef RUN_DIALOG_IN_THREAD
std::thread aboutThread(openAboutDialog, _strFileName);
aboutThread.join();
#else
openAboutDialog(_strFileName);
#endif
return 0;
}
#ifdef M64P_GLIDENUI
EXPORT bool CALL IsPathWriteable(const wchar_t * dir)
{
return isPathWriteable(QString::fromWCharArray(dir));
}
EXPORT void CALL CopyConfigFiles(const wchar_t * _srcDir, const wchar_t * _targetDir)
{
return copyConfigFiles(QString::fromWCharArray(_srcDir), QString::fromWCharArray(_targetDir));
}
#endif // M64P_GLIDENUI
EXPORT bool CALL RunConfig(const wchar_t * _strFileName, const char * _romName, unsigned int _maxMSAALevel, unsigned int _maxAnisotropy)
{
return runConfigThread(_strFileName, _romName, _maxMSAALevel, _maxAnisotropy);
}
EXPORT int CALL RunAbout(const wchar_t * _strFileName)
{
return runAboutThread(_strFileName);
}
EXPORT void CALL LoadConfig(const wchar_t * _strFileName)
{
loadSettings(QString::fromWCharArray(_strFileName));
}
EXPORT void CALL LoadCustomRomSettings(const wchar_t * _strFileName, const char * _romName)
{
loadCustomRomSettings(QString::fromWCharArray(_strFileName), _romName);
}

30
src/GLideNUI/GLideNUI.h Normal file
View File

@ -0,0 +1,30 @@
#ifndef GLIDENUII_H
#define GLIDENUII_H
#if defined(__cplusplus)
extern "C" {
#endif
#ifdef OS_WINDOWS
#define EXPORT __declspec(dllexport)
#define CALL __cdecl
#else
#define EXPORT __attribute__((visibility("default")))
#define CALL
#endif
#ifdef M64P_GLIDENUI
EXPORT bool CALL IsPathWriteable(const wchar_t * dir);
EXPORT void CALL CopyConfigFiles(const wchar_t * _srcDir, const wchar_t * _targetDir);
#endif // M64P_GLIDENUI
EXPORT bool CALL RunConfig(const wchar_t * _strFileName, const char * _romName, unsigned int _maxMSAALevel, unsigned int _maxAnisotropy);
EXPORT int CALL RunAbout(const wchar_t * _strFileName);
EXPORT void CALL LoadConfig(const wchar_t * _strFileName);
EXPORT void CALL LoadCustomRomSettings(const wchar_t * _strFileName, const char * _romName);
#if defined(__cplusplus)
}
#endif
#endif // GLIDENUII_H

627
src/GLideNUI/Settings.cpp Normal file
View File

@ -0,0 +1,627 @@
#include <QSettings>
#include <QColor>
#include <QFile>
#ifdef OS_WINDOWS
#include <windows.h>
#else
#include "../winlnxdefs.h"
#endif
#include "../GBI.h"
#include "../Config.h"
#include "Settings.h"
static const char * strIniFileName = "GLideN64.ini";
static const char * strDefaultIniFileName = "GLideN64.default.ini";
static const char * strCustomSettingsFileName = "GLideN64.custom.ini";
static QString strUserProfile("User");
static
void _loadSettings(QSettings & settings)
{
config.version = settings.value("version").toInt();
settings.beginGroup("video");
config.video.fullscreenWidth = settings.value("fullscreenWidth", config.video.fullscreenWidth).toInt();
config.video.fullscreenHeight = settings.value("fullscreenHeight", config.video.fullscreenHeight).toInt();
config.video.windowedWidth = settings.value("windowedWidth", config.video.windowedWidth).toInt();
config.video.windowedHeight = settings.value("windowedHeight", config.video.windowedHeight).toInt();
config.video.fullscreenRefresh = settings.value("fullscreenRefresh", config.video.fullscreenRefresh).toInt();
config.video.multisampling = settings.value("multisampling", config.video.multisampling).toInt();
config.video.maxMultiSampling = settings.value("maxMultiSampling", config.video.maxMultiSampling).toInt();
config.video.fxaa= settings.value("fxaa", config.video.fxaa).toInt();
config.video.verticalSync = settings.value("verticalSync", config.video.verticalSync).toInt();
config.video.threadedVideo = settings.value("threadedVideo", config.video.threadedVideo).toInt();
settings.endGroup();
settings.beginGroup("texture");
config.texture.anisotropy = settings.value("anisotropy", config.texture.anisotropy).toInt();
config.texture.maxAnisotropy = settings.value("maxAnisotropy", config.texture.maxAnisotropy).toInt();
config.texture.bilinearMode = settings.value("bilinearMode", config.texture.bilinearMode).toInt();
config.texture.enableHalosRemoval = settings.value("enableHalosRemoval", config.texture.enableHalosRemoval).toInt();
settings.endGroup();
settings.beginGroup("generalEmulation");
config.generalEmulation.enableDitheringPattern = settings.value("enableDitheringPattern", config.generalEmulation.enableDitheringPattern).toInt();
config.generalEmulation.enableDitheringQuantization = settings.value("enableDitheringQuantization", config.generalEmulation.enableDitheringQuantization).toInt();
config.generalEmulation.enableHiresNoiseDithering = settings.value("enableHiresNoiseDithering", config.generalEmulation.enableHiresNoiseDithering).toInt();
config.generalEmulation.rdramImageDitheringMode = settings.value("rdramImageDitheringMode", config.generalEmulation.rdramImageDitheringMode).toInt();
config.generalEmulation.enableLOD = settings.value("enableLOD", config.generalEmulation.enableLOD).toInt();
config.generalEmulation.enableInaccurateTextureCoordinates = settings.value("enableInaccurateTextureCoordinates", config.generalEmulation.enableInaccurateTextureCoordinates).toInt();
config.generalEmulation.enableHWLighting = settings.value("enableHWLighting", config.generalEmulation.enableHWLighting).toInt();
config.generalEmulation.enableCoverage = settings.value("enableCoverage", config.generalEmulation.enableCoverage).toInt();
config.generalEmulation.enableShadersStorage = settings.value("enableShadersStorage", config.generalEmulation.enableShadersStorage).toInt();
config.generalEmulation.enableLegacyBlending = settings.value("enableLegacyBlending", config.generalEmulation.enableLegacyBlending).toInt(); //ini only
config.generalEmulation.enableHybridFilter = settings.value("enableHybridFilter", config.generalEmulation.enableHybridFilter).toInt(); //ini only
config.generalEmulation.enableFragmentDepthWrite = settings.value("enableFragmentDepthWrite", config.generalEmulation.enableFragmentDepthWrite).toInt(); //ini only
config.generalEmulation.enableCustomSettings = settings.value("enableCustomSettings", config.generalEmulation.enableCustomSettings).toInt();
settings.endGroup();
settings.beginGroup("graphics2D");
config.graphics2D.correctTexrectCoords = settings.value("correctTexrectCoords", config.graphics2D.correctTexrectCoords).toInt();
config.graphics2D.enableNativeResTexrects = settings.value("enableNativeResTexrects", config.graphics2D.enableNativeResTexrects).toInt();
config.graphics2D.bgMode = settings.value("bgMode", config.graphics2D.bgMode).toInt();
config.graphics2D.enableTexCoordBounds = settings.value("enableTexCoordBounds", config.graphics2D.enableTexCoordBounds).toInt();
settings.endGroup();
settings.beginGroup("frameBufferEmulation");
config.frameBufferEmulation.enable = settings.value("enable", config.frameBufferEmulation.enable).toInt();
config.frameBufferEmulation.aspect = settings.value("aspect", config.frameBufferEmulation.aspect).toInt();
config.frameBufferEmulation.nativeResFactor = settings.value("nativeResFactor", config.frameBufferEmulation.nativeResFactor).toInt();
config.frameBufferEmulation.bufferSwapMode = settings.value("bufferSwapMode", config.frameBufferEmulation.bufferSwapMode).toInt();
config.frameBufferEmulation.N64DepthCompare = settings.value("N64DepthCompare", config.frameBufferEmulation.N64DepthCompare).toInt();
config.frameBufferEmulation.forceDepthBufferClear = settings.value("forceDepthBufferClear", config.frameBufferEmulation.forceDepthBufferClear).toInt();
config.frameBufferEmulation.copyAuxToRDRAM = settings.value("copyAuxToRDRAM", config.frameBufferEmulation.copyAuxToRDRAM).toInt();
config.frameBufferEmulation.copyToRDRAM = settings.value("copyToRDRAM", config.frameBufferEmulation.copyToRDRAM).toInt();
config.frameBufferEmulation.copyDepthToRDRAM = settings.value("copyDepthToRDRAM", config.frameBufferEmulation.copyDepthToRDRAM).toInt();
config.frameBufferEmulation.copyFromRDRAM = settings.value("copyFromRDRAM", config.frameBufferEmulation.copyFromRDRAM).toInt();
config.frameBufferEmulation.fbInfoDisabled = settings.value("fbInfoDisabled", config.frameBufferEmulation.fbInfoDisabled).toInt();
config.frameBufferEmulation.fbInfoReadColorChunk = settings.value("fbInfoReadColorChunk", config.frameBufferEmulation.fbInfoReadColorChunk).toInt();
config.frameBufferEmulation.fbInfoReadDepthChunk = settings.value("fbInfoReadDepthChunk", config.frameBufferEmulation.fbInfoReadDepthChunk).toInt();
config.frameBufferEmulation.copyDepthToMainDepthBuffer = settings.value("copyDepthToMainDepthBuffer", config.frameBufferEmulation.copyDepthToMainDepthBuffer).toInt();
config.frameBufferEmulation.enableOverscan = settings.value("enableOverscan", config.frameBufferEmulation.enableOverscan).toInt();
config.frameBufferEmulation.overscanPAL.left = settings.value("overscanPalLeft", config.frameBufferEmulation.overscanPAL.left).toInt();
config.frameBufferEmulation.overscanPAL.right = settings.value("overscanPalRight", config.frameBufferEmulation.overscanPAL.right).toInt();
config.frameBufferEmulation.overscanPAL.top = settings.value("overscanPalTop", config.frameBufferEmulation.overscanPAL.top).toInt();
config.frameBufferEmulation.overscanPAL.bottom= settings.value("overscanPalBottom", config.frameBufferEmulation.overscanPAL.bottom).toInt();
config.frameBufferEmulation.overscanNTSC.left = settings.value("overscanNtscLeft", config.frameBufferEmulation.overscanNTSC.left).toInt();
config.frameBufferEmulation.overscanNTSC.right = settings.value("overscanNtscRight", config.frameBufferEmulation.overscanNTSC.right).toInt();
config.frameBufferEmulation.overscanNTSC.top = settings.value("overscanNtscTop", config.frameBufferEmulation.overscanNTSC.top).toInt();
config.frameBufferEmulation.overscanNTSC.bottom = settings.value("overscanNtscBottom", config.frameBufferEmulation.overscanNTSC.bottom).toInt();
settings.endGroup();
settings.beginGroup("textureFilter");
config.textureFilter.txFilterMode = settings.value("txFilterMode", config.textureFilter.txFilterMode).toInt();
config.textureFilter.txEnhancementMode = settings.value("txEnhancementMode", config.textureFilter.txEnhancementMode).toInt();
config.textureFilter.txDeposterize = settings.value("txDeposterize", config.textureFilter.txDeposterize).toInt();
config.textureFilter.txFilterIgnoreBG = settings.value("txFilterIgnoreBG", config.textureFilter.txFilterIgnoreBG).toInt();
config.textureFilter.txCacheSize = settings.value("txCacheSize", config.textureFilter.txCacheSize).toInt();
config.textureFilter.txHiresEnable = settings.value("txHiresEnable", config.textureFilter.txHiresEnable).toInt();
config.textureFilter.txHiresFullAlphaChannel = settings.value("txHiresFullAlphaChannel", config.textureFilter.txHiresFullAlphaChannel).toInt();
config.textureFilter.txHresAltCRC = settings.value("txHresAltCRC", config.textureFilter.txHresAltCRC).toInt();
config.textureFilter.txForce16bpp = settings.value("txForce16bpp", config.textureFilter.txForce16bpp).toInt();
config.textureFilter.txCacheCompression = settings.value("txCacheCompression", config.textureFilter.txCacheCompression).toInt();
config.textureFilter.txSaveCache = settings.value("txSaveCache", config.textureFilter.txSaveCache).toInt();
config.textureFilter.txEnhancedTextureFileStorage = settings.value("txEnhancedTextureFileStorage", config.textureFilter.txEnhancedTextureFileStorage).toInt();
config.textureFilter.txHiresTextureFileStorage = settings.value("txHiresTextureFileStorage", config.textureFilter.txHiresTextureFileStorage).toInt();
config.textureFilter.txNoTextureFileStorage = settings.value("txNoTextureFileStorage", config.textureFilter.txNoTextureFileStorage).toInt();
config.textureFilter.txHiresVramLimit = settings.value("txHiresVramLimit", config.textureFilter.txHiresVramLimit).toInt();
QString txPath = QString::fromWCharArray(config.textureFilter.txPath);
config.textureFilter.txPath[settings.value("txPath", txPath).toString().toWCharArray(config.textureFilter.txPath)] = L'\0';
QString txCachePath = QString::fromWCharArray(config.textureFilter.txCachePath);
config.textureFilter.txCachePath[settings.value("txCachePath", txCachePath).toString().toWCharArray(config.textureFilter.txCachePath)] = L'\0';
QString txDumpPath = QString::fromWCharArray(config.textureFilter.txDumpPath);
config.textureFilter.txDumpPath[settings.value("txDumpPath", txDumpPath).toString().toWCharArray(config.textureFilter.txDumpPath)] = L'\0';
settings.endGroup();
settings.beginGroup("font");
config.font.name = settings.value("name", config.font.name.c_str()).toString().toLocal8Bit().constData();
config.font.size = settings.value("size", config.font.size).toInt();
QColor fontColor = settings.value("color", QColor(config.font.color[0], config.font.color[1], config.font.color[2])).value<QColor>();
config.font.color[0] = fontColor.red();
config.font.color[1] = fontColor.green();
config.font.color[2] = fontColor.blue();
config.font.color[3] = fontColor.alpha();
config.font.colorf[0] = _FIXED2FLOAT(config.font.color[0], 8);
config.font.colorf[1] = _FIXED2FLOAT(config.font.color[1], 8);
config.font.colorf[2] = _FIXED2FLOAT(config.font.color[2], 8);
config.font.colorf[3] = config.font.color[3] == 0 ? 1.0f : _FIXED2FLOAT(config.font.color[3], 8);
settings.endGroup();
settings.beginGroup("gammaCorrection");
config.gammaCorrection.force = settings.value("force", config.gammaCorrection.force).toInt();
config.gammaCorrection.level = settings.value("level", config.gammaCorrection.level).toFloat();
settings.endGroup();
settings.beginGroup("onScreenDisplay");
config.onScreenDisplay.fps = settings.value("showFPS", config.onScreenDisplay.fps).toInt();
config.onScreenDisplay.vis = settings.value("showVIS", config.onScreenDisplay.vis).toInt();
config.onScreenDisplay.percent = settings.value("showPercent", config.onScreenDisplay.percent).toInt();
config.onScreenDisplay.internalResolution = settings.value("showInternalResolution", config.onScreenDisplay.internalResolution).toInt();
config.onScreenDisplay.renderingResolution = settings.value("showRenderingResolution", config.onScreenDisplay.renderingResolution).toInt();
config.onScreenDisplay.statistics = settings.value("showStatistics", config.onScreenDisplay.statistics).toInt();
config.onScreenDisplay.pos = settings.value("osdPos", config.onScreenDisplay.pos).toInt();
settings.endGroup();
settings.beginGroup("hotkeys");
for (u32 idx = 0; idx < Config::HotKey::hkTotal; ++idx) {
config.hotkeys.keys[idx] = settings.value(Config::hotkeyIniName(idx), config.hotkeys.keys[idx]).toInt();
config.hotkeys.enabledKeys[idx] = settings.value(Config::enabledHotkeyIniName(idx), config.hotkeys.enabledKeys[idx]).toInt();
}
settings.endGroup();
settings.beginGroup("debug");
config.debug.dumpMode = settings.value("dumpMode", config.debug.dumpMode).toInt();
settings.endGroup();
}
static
void _writeSettingsToFile(const QString & filename)
{
// QSettings settings("Emulation", "GLideN64");
QSettings settings(filename, QSettings::IniFormat);
settings.setValue("version", config.version);
settings.setValue("translation", config.translationFile.c_str());
QString profile = settings.value("profile", strUserProfile).toString();
settings.beginGroup(profile);
settings.setValue("version", config.version);
settings.beginGroup("video");
settings.setValue("fullscreenWidth", config.video.fullscreenWidth);
settings.setValue("fullscreenHeight", config.video.fullscreenHeight);
settings.setValue("windowedWidth", config.video.windowedWidth);
settings.setValue("windowedHeight", config.video.windowedHeight);
settings.setValue("fullscreenRefresh", config.video.fullscreenRefresh);
settings.setValue("multisampling", config.video.multisampling);
settings.setValue("maxMultiSampling", config.video.maxMultiSampling);
settings.setValue("fxaa", config.video.fxaa);
settings.setValue("verticalSync", config.video.verticalSync);
settings.setValue("threadedVideo", config.video.threadedVideo);
settings.endGroup();
settings.beginGroup("texture");
settings.setValue("anisotropy", config.texture.anisotropy);
settings.setValue("maxAnisotropy", config.texture.maxAnisotropy);
settings.setValue("bilinearMode", config.texture.bilinearMode);
settings.setValue("enableHalosRemoval", config.texture.enableHalosRemoval);
settings.endGroup();
settings.beginGroup("generalEmulation");
settings.setValue("enableDitheringPattern", config.generalEmulation.enableDitheringPattern);
settings.setValue("enableDitheringQuantization", config.generalEmulation.enableDitheringQuantization);
settings.setValue("enableHiresNoiseDithering", config.generalEmulation.enableHiresNoiseDithering);
settings.setValue("rdramImageDitheringMode", config.generalEmulation.rdramImageDitheringMode);
settings.setValue("enableLOD", config.generalEmulation.enableLOD);
settings.setValue("enableInaccurateTextureCoordinates", config.generalEmulation.enableInaccurateTextureCoordinates);
settings.setValue("enableHWLighting", config.generalEmulation.enableHWLighting);
settings.setValue("enableCoverage", config.generalEmulation.enableCoverage);
settings.setValue("enableShadersStorage", config.generalEmulation.enableShadersStorage);
settings.setValue("enableLegacyBlending", config.generalEmulation.enableLegacyBlending); //ini only
settings.setValue("enableHybridFilter", config.generalEmulation.enableHybridFilter); //ini only
settings.setValue("enableFragmentDepthWrite", config.generalEmulation.enableFragmentDepthWrite); //ini only
settings.setValue("enableCustomSettings", config.generalEmulation.enableCustomSettings);
settings.endGroup();
settings.beginGroup("graphics2D");
settings.setValue("correctTexrectCoords", config.graphics2D.correctTexrectCoords);
settings.setValue("enableNativeResTexrects", config.graphics2D.enableNativeResTexrects);
settings.setValue("bgMode", config.graphics2D.bgMode);
settings.setValue("enableTexCoordBounds", config.graphics2D.enableTexCoordBounds);
settings.endGroup();
settings.beginGroup("frameBufferEmulation");
settings.setValue("enable", config.frameBufferEmulation.enable);
settings.setValue("aspect", config.frameBufferEmulation.aspect);
settings.setValue("nativeResFactor", config.frameBufferEmulation.nativeResFactor);
settings.setValue("bufferSwapMode", config.frameBufferEmulation.bufferSwapMode);
settings.setValue("N64DepthCompare", config.frameBufferEmulation.N64DepthCompare);
settings.setValue("forceDepthBufferClear", config.frameBufferEmulation.forceDepthBufferClear);
settings.setValue("copyAuxToRDRAM", config.frameBufferEmulation.copyAuxToRDRAM);
settings.setValue("copyFromRDRAM", config.frameBufferEmulation.copyFromRDRAM);
settings.setValue("copyToRDRAM", config.frameBufferEmulation.copyToRDRAM);
settings.setValue("copyDepthToRDRAM", config.frameBufferEmulation.copyDepthToRDRAM);
settings.setValue("fbInfoDisabled", config.frameBufferEmulation.fbInfoDisabled);
settings.setValue("fbInfoReadColorChunk", config.frameBufferEmulation.fbInfoReadColorChunk);
settings.setValue("fbInfoReadDepthChunk", config.frameBufferEmulation.fbInfoReadDepthChunk);
settings.setValue("copyDepthToMainDepthBuffer", config.frameBufferEmulation.copyDepthToMainDepthBuffer);
settings.setValue("enableOverscan", config.frameBufferEmulation.enableOverscan);
settings.setValue("overscanPalLeft", config.frameBufferEmulation.overscanPAL.left);
settings.setValue("overscanPalRight", config.frameBufferEmulation.overscanPAL.right);
settings.setValue("overscanPalTop", config.frameBufferEmulation.overscanPAL.top);
settings.setValue("overscanPalBottom", config.frameBufferEmulation.overscanPAL.bottom);
settings.setValue("overscanNtscLeft", config.frameBufferEmulation.overscanNTSC.left);
settings.setValue("overscanNtscRight", config.frameBufferEmulation.overscanNTSC.right);
settings.setValue("overscanNtscTop", config.frameBufferEmulation.overscanNTSC.top);
settings.setValue("overscanNtscBottom", config.frameBufferEmulation.overscanNTSC.bottom);
settings.endGroup();
settings.beginGroup("textureFilter");
settings.setValue("txFilterMode", config.textureFilter.txFilterMode);
settings.setValue("txEnhancementMode", config.textureFilter.txEnhancementMode);
settings.setValue("txDeposterize", config.textureFilter.txDeposterize);
settings.setValue("txFilterIgnoreBG", config.textureFilter.txFilterIgnoreBG);
settings.setValue("txCacheSize", config.textureFilter.txCacheSize);
settings.setValue("txHiresEnable", config.textureFilter.txHiresEnable);
settings.setValue("txHiresFullAlphaChannel", config.textureFilter.txHiresFullAlphaChannel);
settings.setValue("txHresAltCRC", config.textureFilter.txHresAltCRC);
settings.setValue("txForce16bpp", config.textureFilter.txForce16bpp);
settings.setValue("txCacheCompression", config.textureFilter.txCacheCompression);
settings.setValue("txSaveCache", config.textureFilter.txSaveCache);
settings.setValue("txEnhancedTextureFileStorage", config.textureFilter.txEnhancedTextureFileStorage);
settings.setValue("txHiresTextureFileStorage", config.textureFilter.txHiresTextureFileStorage);
settings.setValue("txNoTextureFileStorage", config.textureFilter.txNoTextureFileStorage);
settings.setValue("txHiresVramLimit", config.textureFilter.txHiresVramLimit);
settings.setValue("txPath", QString::fromWCharArray(config.textureFilter.txPath));
settings.setValue("txCachePath", QString::fromWCharArray(config.textureFilter.txCachePath));
settings.setValue("txDumpPath", QString::fromWCharArray(config.textureFilter.txDumpPath));
settings.endGroup();
settings.beginGroup("font");
settings.setValue("name", config.font.name.c_str());
settings.setValue("size", config.font.size);
settings.setValue("color", QColor(config.font.color[0], config.font.color[1], config.font.color[2], config.font.color[3]));
settings.endGroup();
settings.beginGroup("gammaCorrection");
settings.setValue("force", config.gammaCorrection.force);
settings.setValue("level", config.gammaCorrection.level);
settings.endGroup();
settings.beginGroup("onScreenDisplay");
settings.setValue("showFPS", config.onScreenDisplay.fps);
settings.setValue("showVIS", config.onScreenDisplay.vis);
settings.setValue("showPercent", config.onScreenDisplay.percent);
settings.setValue("showInternalResolution", config.onScreenDisplay.internalResolution);
settings.setValue("showRenderingResolution", config.onScreenDisplay.renderingResolution);
settings.setValue("showStatistics", config.onScreenDisplay.statistics);
settings.setValue("osdPos", config.onScreenDisplay.pos);
settings.endGroup();
settings.beginGroup("hotkeys");
for (u32 idx = 0; idx < Config::HotKey::hkTotal; ++idx) {
settings.setValue(Config::hotkeyIniName(idx), config.hotkeys.keys[idx]);
settings.setValue(Config::enabledHotkeyIniName(idx), config.hotkeys.enabledKeys[idx]);
}
settings.endGroup();
settings.beginGroup("debug");
settings.setValue("dumpMode", config.debug.dumpMode);
settings.endGroup();
settings.endGroup();
}
static
void _loadSettingsFromFile(const QString & filename)
{
bool rewriteSettings = false;
{
const u32 hacks = config.generalEmulation.hacks;
QSettings settings(filename, QSettings::IniFormat);
const u32 configVersion = settings.value("version", 0).toInt();
QString configTranslationFile = settings.value("translation", config.translationFile.c_str()).toString();
config.resetToDefaults();
config.generalEmulation.hacks = hacks;
config.translationFile = configTranslationFile.toLocal8Bit().constData();
if (configVersion < CONFIG_WITH_PROFILES) {
_loadSettings(settings);
config.version = CONFIG_VERSION_CURRENT;
settings.clear();
settings.setValue("version", CONFIG_VERSION_CURRENT);
settings.setValue("profile", strUserProfile);
settings.setValue("translation", config.translationFile.c_str());
settings.beginGroup(strUserProfile);
_writeSettingsToFile(filename);
settings.endGroup();
}
QString profile = settings.value("profile", strUserProfile).toString();
if (settings.childGroups().indexOf(profile) >= 0) {
settings.beginGroup(profile);
_loadSettings(settings);
settings.endGroup();
} else
rewriteSettings = true;
if (config.version != CONFIG_VERSION_CURRENT)
rewriteSettings = true;
}
if (rewriteSettings) {
// Keep settings up-to-date
{
QSettings settings(filename, QSettings::IniFormat);
QString profile = settings.value("profile", strUserProfile).toString();
settings.remove(profile);
}
config.version = CONFIG_VERSION_CURRENT;
_writeSettingsToFile(filename);
}
}
void loadSettings(const QString & _strIniFolder)
{
_loadSettingsFromFile(_strIniFolder + "/" + strIniFileName);
}
void writeSettings(const QString & _strIniFolder)
{
_writeSettingsToFile(_strIniFolder + "/" + strIniFileName);
}
void resetSettings(const QString & _strIniFolder)
{
QString defaultSettingsFilename = _strIniFolder + "/" + strDefaultIniFileName;
QFile defaultFile(defaultSettingsFilename);
if (defaultFile.exists()) {
_loadSettingsFromFile(defaultSettingsFilename);
} else {
config.resetToDefaults();
}
}
static
u32 Adler32(u32 crc, const void *buffer, u32 count)
{
u32 s1 = crc & 0xFFFF;
u32 s2 = (crc >> 16) & 0xFFFF;
int k;
const u8 *Buffer = (const u8*)buffer;
if (Buffer == NULL)
return 0;
while (count > 0) {
/* 5552 is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
k = (count < 5552 ? count : 5552);
count -= k;
while (k--) {
s1 += *Buffer++;
s2 += s1;
}
/* 65521 is the largest prime smaller than 65536 */
s1 %= 65521;
s2 %= 65521;
}
return (s2 << 16) | s1;
}
static
QString _getRomName(const char * _strRomName) {
const QByteArray bytes(_strRomName);
bool bASCII = true;
for (int i = 0; i < bytes.length() && bASCII; ++i)
bASCII = bytes.at(i) >= 0;
return bASCII ?
QString::fromLatin1(_strRomName).toUpper() :
QString::number(Adler32(0xFFFFFFFF, bytes.data(), bytes.length()), 16).toUpper();
}
void loadCustomRomSettings(const QString & _strIniFolder, const char * _strRomName)
{
QSettings settings(_strIniFolder + "/" + strCustomSettingsFileName, QSettings::IniFormat);
const QString romName = _getRomName(_strRomName);
if (settings.childGroups().indexOf(romName) < 0)
return;
settings.beginGroup(romName);
_loadSettings(settings);
settings.endGroup();
config.version = CONFIG_VERSION_CURRENT;
}
void saveCustomRomSettings(const QString & _strIniFolder, const char * _strRomName)
{
Config origConfig;
origConfig.resetToDefaults();
std::swap(config, origConfig);
loadSettings(_strIniFolder);
std::swap(config, origConfig);
QSettings settings(_strIniFolder + "/" + strCustomSettingsFileName, QSettings::IniFormat);
const QString romName = _getRomName(_strRomName);
#define WriteCustomSetting(G, S) \
if (origConfig.G.S != config.G.S || \
origConfig.G.S != settings.value(#S, config.G.S).toInt()) \
settings.setValue(#S, config.G.S)
#define WriteCustomSetting2(G, N, S) \
if (origConfig.G.S != config.G.S || \
origConfig.G.S != settings.value(#N, config.G.S).toInt()) \
settings.setValue(#N, config.G.S)
#define WriteCustomSettingF(G, S) \
if (origConfig.G.S != config.G.S || \
origConfig.G.S != settings.value(#S, config.G.S).toFloat()) \
settings.setValue(#S, config.G.S)
#define WriteCustomSettingS(S) \
const QString new##S = QString::fromWCharArray(config.textureFilter.S); \
const QString orig##S = QString::fromWCharArray(origConfig.textureFilter.S); \
if (orig##S != new##S || \
orig##S != settings.value(#S, new##S).toString()) \
settings.setValue(#S, new##S)
settings.beginGroup(romName);
settings.beginGroup("video");
WriteCustomSetting(video, fullscreenWidth);
WriteCustomSetting(video, fullscreenHeight);
WriteCustomSetting(video, windowedWidth);
WriteCustomSetting(video, windowedHeight);
WriteCustomSetting(video, fullscreenRefresh);
WriteCustomSetting(video, multisampling);
WriteCustomSetting(video, fxaa);
WriteCustomSetting(video, verticalSync);
settings.endGroup();
settings.beginGroup("texture");
WriteCustomSetting(texture, anisotropy);
WriteCustomSetting(texture, maxAnisotropy);
WriteCustomSetting(texture, bilinearMode);
WriteCustomSetting(texture, enableHalosRemoval);
settings.endGroup();
settings.beginGroup("generalEmulation");
WriteCustomSetting(generalEmulation, enableDitheringPattern);
WriteCustomSetting(generalEmulation, enableDitheringQuantization);
WriteCustomSetting(generalEmulation, enableHiresNoiseDithering);
WriteCustomSetting(generalEmulation, rdramImageDitheringMode);
WriteCustomSetting(generalEmulation, enableLOD);
WriteCustomSetting(generalEmulation, enableInaccurateTextureCoordinates);
WriteCustomSetting(generalEmulation, enableHWLighting);
WriteCustomSetting(generalEmulation, enableCoverage);
WriteCustomSetting(generalEmulation, enableShadersStorage);
settings.endGroup();
settings.beginGroup("graphics2D");
WriteCustomSetting(graphics2D, correctTexrectCoords);
WriteCustomSetting(graphics2D, enableNativeResTexrects);
WriteCustomSetting(graphics2D, bgMode);
WriteCustomSetting(graphics2D, enableTexCoordBounds);
settings.endGroup();
settings.beginGroup("frameBufferEmulation");
WriteCustomSetting(frameBufferEmulation, enable);
WriteCustomSetting(frameBufferEmulation, aspect);
WriteCustomSetting(frameBufferEmulation, nativeResFactor);
WriteCustomSetting(frameBufferEmulation, bufferSwapMode);
WriteCustomSetting(frameBufferEmulation, N64DepthCompare);
WriteCustomSetting(frameBufferEmulation, forceDepthBufferClear);
WriteCustomSetting(frameBufferEmulation, copyAuxToRDRAM);
WriteCustomSetting(frameBufferEmulation, copyFromRDRAM);
WriteCustomSetting(frameBufferEmulation, copyToRDRAM);
WriteCustomSetting(frameBufferEmulation, copyDepthToRDRAM);
WriteCustomSetting(frameBufferEmulation, fbInfoDisabled);
WriteCustomSetting(frameBufferEmulation, fbInfoReadColorChunk);
WriteCustomSetting(frameBufferEmulation, fbInfoReadDepthChunk);
WriteCustomSetting(frameBufferEmulation, copyDepthToMainDepthBuffer);
WriteCustomSetting(frameBufferEmulation, enableOverscan);
WriteCustomSetting2(frameBufferEmulation, overscanPalLeft, overscanPAL.left);
WriteCustomSetting2(frameBufferEmulation, overscanPalRight, overscanPAL.right);
WriteCustomSetting2(frameBufferEmulation, overscanPalTop, overscanPAL.top);
WriteCustomSetting2(frameBufferEmulation, overscanPalBottom, overscanPAL.bottom);
WriteCustomSetting2(frameBufferEmulation, overscanNtscLeft, overscanNTSC.left);
WriteCustomSetting2(frameBufferEmulation, overscanNtscRight, overscanNTSC.right);
WriteCustomSetting2(frameBufferEmulation, overscanNtscTop, overscanNTSC.top);
WriteCustomSetting2(frameBufferEmulation, overscanNtscBottom, overscanNTSC.bottom);
settings.endGroup();
settings.beginGroup("textureFilter");
WriteCustomSetting(textureFilter, txFilterMode);
WriteCustomSetting(textureFilter, txEnhancementMode);
WriteCustomSetting(textureFilter, txDeposterize);
WriteCustomSetting(textureFilter, txFilterIgnoreBG);
WriteCustomSetting(textureFilter, txCacheSize);
WriteCustomSetting(textureFilter, txEnhancedTextureFileStorage);
WriteCustomSetting(textureFilter, txHiresTextureFileStorage);
WriteCustomSetting(textureFilter, txNoTextureFileStorage);
WriteCustomSetting(textureFilter, txHiresVramLimit);
WriteCustomSetting(textureFilter, txHiresEnable);
WriteCustomSetting(textureFilter, txHiresFullAlphaChannel);
WriteCustomSetting(textureFilter, txHresAltCRC);
WriteCustomSetting(textureFilter, txForce16bpp);
WriteCustomSetting(textureFilter, txCacheCompression);
WriteCustomSetting(textureFilter, txSaveCache);
WriteCustomSettingS(txPath);
WriteCustomSettingS(txCachePath);
WriteCustomSettingS(txDumpPath);
settings.endGroup();
settings.beginGroup("gammaCorrection");
WriteCustomSetting(gammaCorrection, force);
WriteCustomSettingF(gammaCorrection, level);
settings.endGroup();
settings.beginGroup("onScreenDisplay");
WriteCustomSetting2(onScreenDisplay, showFPS, fps);
WriteCustomSetting2(onScreenDisplay, showVIS, vis);
WriteCustomSetting2(onScreenDisplay, showPercent, percent);
WriteCustomSetting2(onScreenDisplay, showInternalResolution, internalResolution);
WriteCustomSetting2(onScreenDisplay, showRenderingResolution, renderingResolution);
WriteCustomSetting2(onScreenDisplay, showStatistics, statistics);
WriteCustomSetting2(onScreenDisplay, osdPos, pos);
settings.endGroup();
settings.beginGroup("hotkeys");
for (u32 idx = 0; idx < Config::HotKey::hkTotal; ++idx) {
if (origConfig.hotkeys.keys[idx] != config.hotkeys.keys[idx] ||
origConfig.hotkeys.keys[idx] != settings.value(Config::hotkeyIniName(idx), config.hotkeys.keys[idx]).toInt()) {
settings.setValue(Config::hotkeyIniName(idx), config.hotkeys.keys[idx]);
}
if (origConfig.hotkeys.enabledKeys[idx] != config.hotkeys.enabledKeys[idx] ||
origConfig.hotkeys.enabledKeys[idx] != settings.value(Config::enabledHotkeyIniName(idx), config.hotkeys.enabledKeys[idx]).toInt()) {
settings.setValue(Config::enabledHotkeyIniName(idx), config.hotkeys.enabledKeys[idx]);
}
}
settings.endGroup();
settings.endGroup();
}
QString getTranslationFile()
{
return config.translationFile.c_str();
}
QStringList getProfiles(const QString & _strIniFolder)
{
QSettings settings(_strIniFolder + "/" + strIniFileName, QSettings::IniFormat);
return settings.childGroups();
}
QString getCurrentProfile(const QString & _strIniFolder)
{
QSettings settings(_strIniFolder + "/" + strIniFileName, QSettings::IniFormat);
return settings.value("profile", strUserProfile).toString();
}
void changeProfile(const QString & _strIniFolder, const QString & _strProfile)
{
{
QSettings settings(_strIniFolder + "/" + strIniFileName, QSettings::IniFormat);
settings.setValue("profile", _strProfile);
}
loadSettings(_strIniFolder);
}
void addProfile(const QString & _strIniFolder, const QString & _strProfile)
{
{
QSettings settings(_strIniFolder + "/" + strIniFileName, QSettings::IniFormat);
settings.setValue("profile", _strProfile);
}
writeSettings(_strIniFolder);
}
void removeProfile(const QString & _strIniFolder, const QString & _strProfile)
{
QSettings settings(_strIniFolder + "/" + strIniFileName, QSettings::IniFormat);
settings.remove(_strProfile);
}
#ifdef M64P_GLIDENUI
#include <QFileInfo>
bool isPathWriteable(const QString dir)
{
QFileInfo path(dir);
return path.isWritable();
}
void copyConfigFiles(const QString _srcDir, const QString _targetDir)
{
QStringList files = {
strIniFileName,
strDefaultIniFileName,
strCustomSettingsFileName
};
for (const QString& file : files) {
if (!QFile::exists(_targetDir + "/" + file)) {
QFile::copy(_srcDir + "/" + file, _targetDir + "/" + file);
}
}
}
#endif // M64P_GLIDENUI

21
src/GLideNUI/Settings.h Normal file
View File

@ -0,0 +1,21 @@
#ifndef SETTINGS_H
#define SETTINGS_H
void loadSettings(const QString & _strIniFolder);
void writeSettings(const QString & _strIniFolder);
void resetSettings(const QString & _strIniFolder);
void loadCustomRomSettings(const QString & _strIniFolder, const char * _strRomName);
void saveCustomRomSettings(const QString & _strIniFolder, const char * _strRomName);
QString getTranslationFile();
QStringList getProfiles(const QString & _strIniFolder);
QString getCurrentProfile(const QString & _strIniFolder);
void changeProfile(const QString & _strIniFolder, const QString & _strProfile);
void addProfile(const QString & _strIniFolder, const QString & _strProfile);
void removeProfile(const QString & _strIniFolder, const QString & _strProfile);
#ifdef M64P_GLIDENUI
bool isPathWriteable(const QString dir);
void copyConfigFiles(const QString _srcDir, const QString _targetDir);
#endif // M64P_GLIDENUI
#endif // SETTINGS_H

4066
src/GLideNUI/configDialog.ui Normal file

File diff suppressed because it is too large Load Diff

View File

@ -2,6 +2,9 @@
#define GLFUNCTIONS_H
#ifdef OS_WINDOWS
#ifndef NOMINMAX
#define NOMINMAX
#endif
#include <windows.h>
//#define FORCE_UNBUFFERED_DRAWER // Debug option.
#elif defined(OS_LINUX)

View File

@ -785,8 +785,7 @@ public:
" return lod_frac; \n"
"} \n"
;
}
else {
} else {
static const std::string strReadTex0 =
"#define READ_TEX0_MIPMAP(name, tex, tcData) \\\n"
"{ \\\n"

View File

@ -795,27 +795,11 @@ public:
"} \n"
;
}
}
else {
if (config.generalEmulation.enableLOD == 0) {
// Fake mipmap
} else {
if (config.texture.bilinearMode == BILINEAR_3POINT) {
m_part =
"uniform lowp int uMaxTile; \n"
"uniform mediump float uMinLod; \n"
" \n"
"mediump float mipmap(out lowp vec4 readtex0, out lowp vec4 readtex1) { \n"
" readtex0 = texture(uTex0, texCoord0); \n"
" readtex1 = texture(uTex1, texCoord1); \n"
" if (uMaxTile == 0) return 1.0; \n"
" return uMinLod; \n"
"} \n"
;
} else {
if (config.texture.bilinearMode == BILINEAR_3POINT)
m_part =
"#define TEX_OFFSET_NORMAL(off, tex, texCoord, lod) texture(tex, texCoord - (off)/texSize) \n"
"#define TEX_OFFSET_MIPMAP(off, tex, texCoord, lod) textureLod(tex, texCoord - (off)/texSize, lod) \n"
"#define READ_TEX_NORMAL(name, tex, texCoord, lod) \\\n"
"#define READ_TEX_NORMAL(name, tex, texCoord, lod) \\\n"
" { \\\n"
" mediump vec2 texSize = vec2(textureSize(tex, int(lod))); \\\n"
" mediump vec2 offset = fract(texCoord*texSize - vec2(0.5)); \\\n"
@ -825,6 +809,10 @@ public:
" lowp vec4 c2 = TEX_OFFSET_NORMAL(vec2(offset.x, offset.y - sign(offset.y)), tex, texCoord, lod); \\\n"
" name = c0 + abs(offset.x)*(c1-c0) + abs(offset.y)*(c2-c0); \\\n"
" } \n"
;
if (config.generalEmulation.enableLOD != 0) {
m_part +=
"#define TEX_OFFSET_MIPMAP(off, tex, texCoord, lod) textureLod(tex, texCoord - (off)/texSize, lod) \n"
"#define READ_TEX_MIPMAP(name, tex, texCoord, lod) \\\n"
" { \\\n"
" mediump vec2 texSize = vec2(textureSize(tex, int(lod))); \\\n"
@ -836,13 +824,68 @@ public:
" name = c0 + abs(offset.x)*(c1-c0) + abs(offset.y)*(c2-c0); \\\n"
" } \n"
;
else
}
} else {
m_part =
"#define TEX_FETCH_NORMAL(tex, texCoord, lod) texture(tex, texCoord) \n"
"#define TEX_FETCH_MIPMAP(tex, texCoord, lod) textureLod(tex, texCoord, lod) \n"
"#define READ_TEX_NORMAL(name, tex, texCoord, lod) name = TEX_FETCH_NORMAL(tex, texCoord, lod) \n"
"#define READ_TEX_MIPMAP(name, tex, texCoord, lod) name = TEX_FETCH_MIPMAP(tex, texCoord, lod) \n"
;
"#define TEX_OFFSET_NORMAL(off, tex, texCoord, lod) texture(tex, texCoord - (off)/texSize) \n"
"#define READ_TEX_NORMAL(name, tex, texCoord, lod) \\\n"
" { \\\n"
" mediump vec2 texSize = vec2(textureSize(tex, int(lod))); \\\n"
" mediump vec2 offset = fract(texCoord*texSize - vec2(0.5)); \\\n"
" offset -= step(1.0, offset.x + offset.y); \\\n"
" lowp vec4 zero = vec4(0.0); \\\n"
" \\\n"
" lowp vec4 p0q0 = TEX_OFFSET_NORMAL(offset, tex, texCoord, lod); \\\n"
" lowp vec4 p1q0 = TEX_OFFSET_NORMAL(vec2(offset.x - sign(offset.x), offset.y), tex, texCoord, lod); \\\n"
" \\\n"
" lowp vec4 p0q1 = TEX_OFFSET_NORMAL(vec2(offset.x, offset.y - sign(offset.y)), tex, texCoord, lod); \\\n"
" lowp vec4 p1q1 = TEX_OFFSET_NORMAL(vec2(offset.x - sign(offset.x), offset.y - sign(offset.y)), tex, texCoord, lod); \\\n"
" \\\n"
" mediump vec2 interpolationFactor = abs(offset); \\\n"
" lowp vec4 pInterp_q0 = mix( p0q0, p1q0, interpolationFactor.x ); \\\n"
" lowp vec4 pInterp_q1 = mix( p0q1, p1q1, interpolationFactor.x ); \\\n"
" name = mix( pInterp_q0, pInterp_q1, interpolationFactor.y ); \\\n"
"} \n"
;
if (config.generalEmulation.enableLOD != 0) {
m_part +=
"#define TEX_OFFSET_MIPMAP(off, tex, texCoord, lod) textureLod(tex, texCoord - (off)/texSize, lod) \n"
"#define READ_TEX_MIPMAP(name, tex, texCoord, lod) \\\n"
" { \\\n"
" mediump vec2 texSize = vec2(textureSize(tex, int(lod))); \\\n"
" mediump vec2 offset = fract(texCoord*texSize - vec2(0.5)); \\\n"
" offset -= step(1.0, offset.x + offset.y); \\\n"
" lowp vec4 zero = vec4(0.0); \\\n"
" \\\n"
" lowp vec4 p0q0 = TEX_OFFSET_MIPMAP(offset, tex, texCoord, lod); \\\n"
" lowp vec4 p1q0 = TEX_OFFSET_MIPMAP(vec2(offset.x - sign(offset.x), offset.y), tex, texCoord, lod); \\\n"
" \\\n"
" lowp vec4 p0q1 = TEX_OFFSET_MIPMAP(vec2(offset.x, offset.y - sign(offset.y)), tex, texCoord, lod); \\\n"
" lowp vec4 p1q1 = TEX_OFFSET_MIPMAP(vec2(offset.x - sign(offset.x), offset.y - sign(offset.y)), tex, texCoord, lod); \\\n"
" \\\n"
" mediump vec2 interpolationFactor = abs(offset); \\\n"
" lowp vec4 pInterp_q0 = mix( p0q0, p1q0, interpolationFactor.x ); \\\n"
" lowp vec4 pInterp_q1 = mix( p0q1, p1q1, interpolationFactor.x ); \\\n"
" name = mix( pInterp_q0, pInterp_q1, interpolationFactor.y ); \\\n"
"} \n"
;
}
}
if (config.generalEmulation.enableLOD == 0) {
// Fake mipmap
m_part +=
"uniform lowp int uMaxTile; \n"
"uniform mediump float uMinLod; \n"
" \n"
"mediump float mipmap(out lowp vec4 readtex0, out lowp vec4 readtex1) { \n"
" READ_TEX_NORMAL(readtex0, uTex0, texCoord0, 0.0); \n"
" READ_TEX_NORMAL(readtex1, uTex1, texCoord1, 0.0); \n"
" if (uMaxTile == 0) return 1.0; \n"
" return uMinLod; \n"
"} \n"
;
} else {
m_part +=
"uniform lowp int uEnableLod; \n"
"uniform mediump float uMinLod; \n"
@ -906,7 +949,7 @@ public:
" } \n"
" return lod_frac; \n"
"} \n"
;
;
}
}
}

View File

@ -1,5 +1,4 @@
#include "glsl_CombinerProgramUniformFactoryAccurate.h"
#include <Config.h>
#include <FrameBuffer.h>
#include <Textures.h>
@ -8,10 +7,6 @@
#include <cmath>
#ifdef min
#undef min
#endif
namespace {
using namespace glsl;
@ -116,8 +111,10 @@ public:
maxTile = std::min(gSP.texture.level, 1u); // Hack for HD textures
uMaxTile.set(maxTile, _force);
bool bNoAtlasTex = maxTile == 0 || gDP.otherMode.textureLOD != G_TL_LOD ||
(gDP.otherMode.textureDetail != G_TD_DETAIL && maxTile == 1);
bool bNoAtlasTex = (_pTexture != nullptr && _pTexture->bHDTexture) ||
maxTile == 0 ||
gDP.otherMode.textureLOD != G_TL_LOD ||
(gDP.otherMode.textureDetail != G_TD_DETAIL && maxTile == 1);
uNoAtlasTex.set(bNoAtlasTex ? 1 : 0, _force);
}
@ -258,8 +255,6 @@ public:
aTexSize[t][0] = pTexture->width * pTexture->hdRatioS;
aTexSize[t][1] = pTexture->height * pTexture->hdRatioT;
aShiftScale[t][0] = calcShiftScaleS(*pTile);
aShiftScale[t][1] = calcShiftScaleT(*pTile);
if (pTile->textureMode != TEXTUREMODE_BGIMAGE && pTile->textureMode != TEXTUREMODE_FRAMEBUFFER_BG) {
float fuls = pTile->fuls;
@ -277,6 +272,9 @@ public:
}
aTexOffset[t][0] = fuls;
aTexOffset[t][1] = fult;
aShiftScale[t][0] = calcShiftScaleS(*pTile);
aShiftScale[t][1] = calcShiftScaleT(*pTile);
}
aHDRatio[t][0] = pTexture->hdRatioS;

View File

@ -8,10 +8,6 @@
#include <cmath>
#ifdef min
#undef min
#endif
namespace {
using namespace glsl;
@ -30,13 +26,6 @@ public:
const bool isNativeRes = config.frameBufferEmulation.nativeResFactor == 1 && config.video.multisampling == 0;
const bool isTexRect = dwnd().getDrawer().getDrawingState() == DrawingState::TexRect;
const bool useTexCoordBounds = isTexRect && !isNativeRes && config.graphics2D.enableTexCoordBounds;
/* At rasterization stage, the N64 places samples on the top left of the fragment while OpenGL */
/* places them in the fragment center. As a result, a normal approach results in shifted texture */
/* coordinates. In native resolution, this difference can be negated by shifting vertices by 0.5. */
/* In higher resolutions, there are more samples than the game intends, so shifting is not very */
/* effective. Still, an heuristic is applied to render texture rectangles as correctly as possible */
/* in higher resolutions too. See issue #2324 for details. */
const float vertexOffset = isNativeRes ? 0.5f : 0.0f;
float texCoordOffset[2][2] = { 0.0f, 0.0f };
if (isTexRect && !isNativeRes) {
float scale[2] = { 0.0f, 0.0f };
@ -109,7 +98,7 @@ public:
}
}
uVertexOffset.set(vertexOffset, vertexOffset, _force);
uVertexOffset.set(0.0, 0.0, _force);
uTexCoordOffset[0].set(texCoordOffset[0][0], texCoordOffset[0][1], _force);
uTexCoordOffset[1].set(texCoordOffset[1][0], texCoordOffset[1][1], _force);
uUseTexCoordBounds.set(useTexCoordBounds ? 1 : 0, _force);

View File

@ -19,7 +19,7 @@ ColorBufferReaderWithBufferStorage::~ColorBufferReaderWithBufferStorage()
void ColorBufferReaderWithBufferStorage::_initBuffers()
{
m_numPBO = config.frameBufferEmulation.copyToRDRAM;
m_numPBO = std::max(1u, config.frameBufferEmulation.copyToRDRAM);
if (m_numPBO > _maxPBO)
m_numPBO = _maxPBO;

View File

@ -28,7 +28,7 @@ void ColorBufferReaderWithPixelBuffer::_destroyBuffers()
void ColorBufferReaderWithPixelBuffer::_initBuffers()
{
m_numPBO = config.frameBufferEmulation.copyToRDRAM;
m_numPBO = std::max(1u, config.frameBufferEmulation.copyToRDRAM);
if (m_numPBO > _maxPBO)
m_numPBO = _maxPBO;

View File

@ -26,10 +26,6 @@
#include <Graphics/OpenGLContext/GraphicBuffer/GraphicBufferWrapper.h>
#endif
#ifdef min
#undef min
#endif
using namespace opengl;
ContextImpl::ContextImpl()
@ -38,7 +34,6 @@ ContextImpl::ContextImpl()
}
ContextImpl::~ContextImpl()
{
}

View File

@ -64,6 +64,9 @@ void GLInfo::init() {
renderer = Renderer::Tegra;
LOG(LOG_VERBOSE, "OpenGL renderer: %s", strRenderer);
if (strstr(strDriverVersion, "ANGLE") != nullptr)
renderer = Renderer::Angle;
int numericVersion = majorVersion * 10 + minorVersion;
if (isGLES2) {
imageTextures = false;
@ -172,6 +175,12 @@ void GLInfo::init() {
config.generalEmulation.enableFragmentDepthWrite = 0;
}
#ifdef OS_ANDROID
if (renderer == Renderer::Angle) {
config.generalEmulation.enableFragmentDepthWrite = 0;
}
#endif
depthTexture = !isGLES2 || Utils::isExtensionSupported(*this, "GL_OES_depth_texture");
noPerspective = Utils::isExtensionSupported(*this, "GL_NV_shader_noperspective_interpolation");
@ -190,7 +199,7 @@ void GLInfo::init() {
#ifdef OS_ANDROID
eglImage = eglImage &&
( (isGLES2 && GraphicBufferWrapper::isSupportAvailable()) || (isGLESX && GraphicBufferWrapper::isPublicSupportAvailable()) ) &&
(renderer != Renderer::PowerVR) && (renderer != Renderer::Tegra);
(renderer != Renderer::PowerVR) && (renderer != Renderer::Tegra) && (renderer != Renderer::Angle);
#endif
if (renderer == Renderer::Intel) {

View File

@ -11,6 +11,7 @@ enum class Renderer {
Intel,
PowerVR,
Tegra,
Angle,
Other
};

View File

@ -1227,7 +1227,7 @@ void GraphicsDrawer::drawTexturedRect(const TexturedRectParams & _params)
return;
}
if (!_canDraw())
if (_params.texrectCmd && !_canDraw())
return;
}

View File

@ -2,6 +2,9 @@
#define COMMONPLUGINAPI_H
#ifdef MUPENPLUSAPI
#ifndef NOMINMAX
#define NOMINMAX
#endif
#include "m64p_plugin.h"
#else
#include "windows/GLideN64_windows.h"
@ -45,6 +48,9 @@ public:
void FindPluginPath(wchar_t * _strPath);
void GetUserDataPath(wchar_t * _strPath);
void GetUserCachePath(wchar_t * _strPath);
#ifdef M64P_GLIDENUI
void GetUserConfigPath(wchar_t * _strPath);
#endif // M64P_GLIDENUI
bool isRomOpen() const { return m_bRomOpen; }
#ifndef MUPENPLUSAPI

View File

@ -28,136 +28,155 @@
using namespace std;
using namespace graphics;
inline u32 GetNone( u64 *src, u16 x, u16 i, u8 palette )
u32 GetNone(u16 offset, u16 x, u16 i, u8 palette)
{
return 0x00000000;
}
inline u32 GetCI4_RGBA8888(u64 *src, u16 x, u16 i, u8 palette)
inline u8 Get4BitPaletteColor(u16 offset, u16 x, u16 i)
{
u8 color4B = ((u8*)src)[(x >> 1) ^ (i << 1)];
u8* tmem8 = reinterpret_cast<u8*>(TMEM);
return tmem8[((offset << 3) + ((x >> 1) ^ (i << 1))) & 0xFFF];
}
u32 GetCI4_RGBA8888(u16 offset, u16 x, u16 i, u8 palette)
{
const u8 color4B = Get4BitPaletteColor(offset, x, i);
return CI4_RGBA8888((x & 1) ? (palette << 4) | (color4B & 0x0F) : (palette << 4) | (color4B >> 4));
}
inline u32 GetCI4_RGBA4444(u64 *src, u16 x, u16 i, u8 palette)
u32 GetCI4_RGBA4444(u16 offset, u16 x, u16 i, u8 palette)
{
u8 color4B = ((u8*)src)[(x >> 1) ^ (i << 1)];
const u8 color4B = Get4BitPaletteColor(offset, x, i);
return CI4_RGBA4444((x & 1) ? (palette << 4) | (color4B & 0x0F) : (palette << 4) | (color4B >> 4));
}
inline u32 GetCI4IA_RGBA4444(u64 *src, u16 x, u16 i, u8 palette)
u32 GetCI4IA_RGBA4444(u16 offset, u16 x, u16 i, u8 palette)
{
u8 color4B = ((u8*)src)[(x>>1)^(i<<1)];
const u8 color4B = Get4BitPaletteColor(offset, x, i);
if (x & 1)
return IA88_RGBA4444( *(u16*)&TMEM[256 + (palette << 4) + (color4B & 0x0F)] );
return IA88_RGBA4444(*(u16*)&TMEM[(0x100 + (palette << 4) + (color4B & 0x0F)) & 0x1FF]);
else
return IA88_RGBA4444( *(u16*)&TMEM[256 + (palette << 4) + (color4B >> 4)] );
return IA88_RGBA4444(*(u16*)&TMEM[(0x100 + (palette << 4) + (color4B >> 4)) & 0x1FF]);
}
inline u32 GetCI4IA_RGBA8888( u64 *src, u16 x, u16 i, u8 palette )
u32 GetCI4IA_RGBA8888(u16 offset, u16 x, u16 i, u8 palette)
{
u8 color4B = ((u8*)src)[(x>>1)^(i<<1)];
const u8 color4B = Get4BitPaletteColor(offset, x, i);
if (x & 1)
return IA88_RGBA8888( *(u16*)&TMEM[256 + (palette << 4) + (color4B & 0x0F)] );
return IA88_RGBA8888(*(u16*)&TMEM[(0x100 + (palette << 4) + (color4B & 0x0F)) & 0x1FF]);
else
return IA88_RGBA8888( *(u16*)&TMEM[256 + (palette << 4) + (color4B >> 4)] );
return IA88_RGBA8888(*(u16*)&TMEM[(0x100 + (palette << 4) + (color4B >> 4)) & 0x1FF]);
}
inline u32 GetCI4RGBA_RGBA5551( u64 *src, u16 x, u16 i, u8 palette )
u32 GetCI4RGBA_RGBA5551(u16 offset, u16 x, u16 i, u8 palette)
{
u8 color4B = ((u8*)src)[(x>>1)^(i<<1)];
const u8 color4B = Get4BitPaletteColor(offset, x, i);
if (x & 1)
return RGBA5551_RGBA5551( *(u16*)&TMEM[256 + (palette << 4) + (color4B & 0x0F)] );
return RGBA5551_RGBA5551(*(u16*)&TMEM[(0x100 + (palette << 4) + (color4B & 0x0F)) & 0x1FF]);
else
return RGBA5551_RGBA5551( *(u16*)&TMEM[256 + (palette << 4) + (color4B >> 4)] );
return RGBA5551_RGBA5551(*(u16*)&TMEM[(0x100 + (palette << 4) + (color4B >> 4)) & 0x1FF]);
}
inline u32 GetCI4RGBA_RGBA8888( u64 *src, u16 x, u16 i, u8 palette )
u32 GetCI4RGBA_RGBA8888(u16 offset, u16 x, u16 i, u8 palette)
{
u8 color4B = ((u8*)src)[(x>>1)^(i<<1)];
const u8 color4B = Get4BitPaletteColor(offset, x, i);
if (x & 1)
return RGBA5551_RGBA8888( *(u16*)&TMEM[256 + (palette << 4) + (color4B & 0x0F)] );
return RGBA5551_RGBA8888(*(u16*)&TMEM[(0x100 + (palette << 4) + (color4B & 0x0F)) & 0x1FF]);
else
return RGBA5551_RGBA8888( *(u16*)&TMEM[256 + (palette << 4) + (color4B >> 4)] );
return RGBA5551_RGBA8888(*(u16*)&TMEM[(0x100 + (palette << 4) + (color4B >> 4)) & 0x1FF]);
}
inline u32 GetIA31_RGBA8888( u64 *src, u16 x, u16 i, u8 palette )
u32 GetIA31_RGBA8888(u16 offset, u16 x, u16 i, u8 palette)
{
u8 color4B = ((u8*)src)[(x>>1)^(i<<1)];
return IA31_RGBA8888( (x & 1) ? (color4B & 0x0F) : (color4B >> 4) );
const u8 color4B = Get4BitPaletteColor(offset, x, i);
return IA31_RGBA8888((x & 1) ? (color4B & 0x0F) : (color4B >> 4));
}
inline u32 GetIA31_RGBA4444( u64 *src, u16 x, u16 i, u8 palette )
u32 GetIA31_RGBA4444(u16 offset, u16 x, u16 i, u8 palette)
{
u8 color4B = ((u8*)src)[(x>>1)^(i<<1)];
return IA31_RGBA4444( (x & 1) ? (color4B & 0x0F) : (color4B >> 4) );
const u8 color4B = Get4BitPaletteColor(offset, x, i);
return IA31_RGBA4444((x & 1) ? (color4B & 0x0F) : (color4B >> 4));
}
inline u32 GetI4_RGBA8888( u64 *src, u16 x, u16 i, u8 palette )
u32 GetI4_RGBA8888(u16 offset, u16 x, u16 i, u8 palette)
{
u8 color4B = ((u8*)src)[(x>>1)^(i<<1)];
return I4_RGBA8888( (x & 1) ? (color4B & 0x0F) : (color4B >> 4) );
const u8 color4B = Get4BitPaletteColor(offset, x, i);
return I4_RGBA8888((x & 1) ? (color4B & 0x0F) : (color4B >> 4));
}
inline u32 GetI4_RGBA4444( u64 *src, u16 x, u16 i, u8 palette )
u32 GetI4_RGBA4444(u16 offset, u16 x, u16 i, u8 palette)
{
u8 color4B = ((u8*)src)[(x>>1)^(i<<1)];
return I4_RGBA4444( (x & 1) ? (color4B & 0x0F) : (color4B >> 4) );
const u8 color4B = Get4BitPaletteColor(offset, x, i);
return I4_RGBA4444((x & 1) ? (color4B & 0x0F) : (color4B >> 4));
}
inline u32 GetCI8IA_RGBA4444( u64 *src, u16 x, u16 i, u8 palette )
inline u8 Get8BitPaletteColor(u16 offset, u16 x, u16 i)
{
return IA88_RGBA4444( *(u16*)&TMEM[256 + ((u8*)src)[x^(i<<1)]] );
u8* tmem8 = reinterpret_cast<u8*>(TMEM);
return tmem8[((offset << 3) + (x ^ (i << 1))) & 0xFFF];
}
inline u32 GetCI8IA_RGBA8888( u64 *src, u16 x, u16 i, u8 palette )
u32 GetCI8IA_RGBA4444(u16 offset, u16 x, u16 i, u8 palette)
{
return IA88_RGBA8888( *(u16*)&TMEM[256 + ((u8*)src)[x^(i<<1)]] );
const u8 color = Get8BitPaletteColor(offset, x, i);
return IA88_RGBA4444(*(u16*)&TMEM[(0x100 + color) & 0x1FF]);
}
inline u32 GetCI8RGBA_RGBA5551( u64 *src, u16 x, u16 i, u8 palette )
u32 GetCI8IA_RGBA8888(u16 offset, u16 x, u16 i, u8 palette)
{
return RGBA5551_RGBA5551( *(u16*)&TMEM[256 + ((u8*)src)[x^(i<<1)]] );
const u8 color = Get8BitPaletteColor(offset, x, i);
return IA88_RGBA8888(*(u16*)&TMEM[(0x100 + color) & 0x1FF]);
}
inline u32 GetCI8RGBA_RGBA8888( u64 *src, u16 x, u16 i, u8 palette )
u32 GetCI8RGBA_RGBA5551(u16 offset, u16 x, u16 i, u8 palette)
{
return RGBA5551_RGBA8888( *(u16*)&TMEM[256 + ((u8*)src)[x^(i<<1)]] );
const u8 color = Get8BitPaletteColor(offset, x, i);
return RGBA5551_RGBA5551(*(u16*)&TMEM[(0x100 + color) & 0x1FF]);
}
inline u32 GetIA44_RGBA8888( u64 *src, u16 x, u16 i, u8 palette )
u32 GetCI8RGBA_RGBA8888(u16 offset, u16 x, u16 i, u8 palette)
{
return IA44_RGBA8888(((u8*)src)[x^(i<<1)]);
const u8 color = Get8BitPaletteColor(offset, x, i);
return RGBA5551_RGBA8888(*(u16*)&TMEM[(0x100 + color) & 0x1FF]);
}
inline u32 GetIA44_RGBA4444( u64 *src, u16 x, u16 i, u8 palette )
u32 GetIA44_RGBA8888(u16 offset, u16 x, u16 i, u8 palette)
{
return IA44_RGBA4444(((u8*)src)[x^(i<<1)]);
const u8 color = Get8BitPaletteColor(offset, x, i);
return IA44_RGBA8888(color);
}
inline u32 GetI8_RGBA8888( u64 *src, u16 x, u16 i, u8 palette )
u32 GetIA44_RGBA4444(u16 offset, u16 x, u16 i, u8 palette)
{
return I8_RGBA8888(((u8*)src)[x^(i<<1)]);
const u8 color = Get8BitPaletteColor(offset, x, i);
return IA44_RGBA4444(color);
}
inline u32 GetI8_RGBA4444( u64 *src, u16 x, u16 i, u8 palette )
u32 GetI8_RGBA8888(u16 offset, u16 x, u16 i, u8 palette)
{
return I8_RGBA4444(((u8*)src)[x^(i<<1)]);
const u8 color = Get8BitPaletteColor(offset, x, i);
return I8_RGBA8888(color);
}
u32 GetI8_RGBA4444(u16 offset, u16 x, u16 i, u8 palette)
{
const u8 color = Get8BitPaletteColor(offset, x, i);
return I8_RGBA4444(color);
}
inline u32 GetI16_RGBA8888(u64 *src, u16 x, u16 i, u8 palette)
inline u16 Get16BitColor(u16 offset, u16 x, u16 i)
{
const u16 tex = ((u16*)src)[x^i];
u16* tmem16 = reinterpret_cast<u16*>(TMEM);
return tmem16[((offset << 2) + (x ^ i)) & 0x7FF];
}
u32 GetI16_RGBA8888(u16 offset, u16 x, u16 i, u8 palette)
{
const u16 tex = Get16BitColor(offset, x, i);
u32 r = tex >> 8;
u32 g = tex & 0xFF;
u32 b = r;
@ -165,9 +184,9 @@ inline u32 GetI16_RGBA8888(u64 *src, u16 x, u16 i, u8 palette)
return (a << 24) | (b << 16) | (g << 8) | r;
}
inline u32 GetI16_RGBA4444(u64 *src, u16 x, u16 i, u8 palette)
u32 GetI16_RGBA4444(u16 offset, u16 x, u16 i, u8 palette)
{
const u16 tex = ((u16*)src)[x^i];
const u16 tex = Get16BitColor(offset, x, i);
u16 r = tex >> 12;
u16 g = tex & 0x0F;
u16 b = r;
@ -175,66 +194,75 @@ inline u32 GetI16_RGBA4444(u64 *src, u16 x, u16 i, u8 palette)
return (a << 12) | (b << 8) | (g << 4) | r;
}
inline u32 GetCI16IA_RGBA8888(u64 *src, u16 x, u16 i, u8 palette)
u32 GetCI16IA_RGBA8888(u16 offset, u16 x, u16 i, u8 palette)
{
const u16 tex = ((u16*)src)[x^i];
const u16 col = (*(u16*)&TMEM[256 + (tex & 0xFF)]);
const u16 tex = Get16BitColor(offset, x, i);
const u16 col = (*(u16*)&TMEM[0x100 + (tex & 0xFF)]);
const u16 c = col >> 8;
const u16 a = col & 0xFF;
return (a << 24) | (c << 16) | (c << 8) | c;
}
inline u32 GetCI16IA_RGBA4444(u64 *src, u16 x, u16 i, u8 palette)
u32 GetCI16IA_RGBA4444(u16 offset, u16 x, u16 i, u8 palette)
{
const u16 tex = ((u16*)src)[x^i];
const u16 col = (*(u16*)&TMEM[256 + (tex & 0xFF)]);
const u16 tex = Get16BitColor(offset, x, i);
const u16 col = (*(u16*)&TMEM[0x100 + (tex & 0xFF)]);
const u16 c = col >> 12;
const u16 a = col & 0x0F;
return (a << 12) | (c << 8) | (c << 4) | c;
}
inline u32 GetCI16RGBA_RGBA8888(u64 *src, u16 x, u16 i, u8 palette)
u32 GetCI16RGBA_RGBA8888(u16 offset, u16 x, u16 i, u8 palette)
{
const u16 tex = (((u16*)src)[x^i])&0xFF;
return RGBA5551_RGBA8888(((u16*)&TMEM[256])[tex << 2]);
const u16 tex = Get16BitColor(offset, x, i) & 0xFF;
return RGBA5551_RGBA8888(((u16*)&TMEM[0x100])[tex << 2]);
}
inline u32 GetCI16RGBA_RGBA5551(u64 *src, u16 x, u16 i, u8 palette)
u32 GetCI16RGBA_RGBA5551(u16 offset, u16 x, u16 i, u8 palette)
{
const u16 tex = (((u16*)src)[x^i]) & 0xFF;
return RGBA5551_RGBA5551(((u16*)&TMEM[256])[tex << 2]);
const u16 tex = Get16BitColor(offset, x, i) & 0xFF;
return RGBA5551_RGBA5551(((u16*)&TMEM[0x100])[tex << 2]);
}
inline u32 GetRGBA5551_RGBA8888(u64 *src, u16 x, u16 i, u8 palette)
u32 GetRGBA5551_RGBA8888(u16 offset, u16 x, u16 i, u8 palette)
{
u16 tex = ((u16*)src)[x^i];
const u16 tex = Get16BitColor(offset, x, i);
return RGBA5551_RGBA8888(tex);
}
inline u32 GetRGBA5551_RGBA5551( u64 *src, u16 x, u16 i, u8 palette )
u32 GetRGBA5551_RGBA5551(u16 offset, u16 x, u16 i, u8 palette)
{
u16 tex = ((u16*)src)[x^i];
const u16 tex = Get16BitColor(offset, x, i);
return RGBA5551_RGBA5551(tex);
}
inline u32 GetIA88_RGBA8888( u64 *src, u16 x, u16 i, u8 palette )
u32 GetIA88_RGBA8888(u16 offset, u16 x, u16 i, u8 palette)
{
return IA88_RGBA8888(((u16*)src)[x^i]);
const u16 tex = Get16BitColor(offset, x, i);
return IA88_RGBA8888(tex);
}
inline u32 GetIA88_RGBA4444( u64 *src, u16 x, u16 i, u8 palette )
u32 GetIA88_RGBA4444(u16 offset, u16 x, u16 i, u8 palette)
{
return IA88_RGBA4444(((u16*)src)[x^i]);
const u16 tex = Get16BitColor(offset, x, i);
return IA88_RGBA4444(tex);
}
inline u32 GetRGBA8888_RGBA8888( u64 *src, u16 x, u16 i, u8 palette )
inline u32 Get32BitColor(u16 offset, u16 x, u16 i)
{
return ((u32*)src)[x^i];
u32* tmem32 = reinterpret_cast<u32*>(TMEM);
return tmem32[((offset << 1) + (x ^ i)) & 0x3FF];
}
inline u32 GetRGBA8888_RGBA4444( u64 *src, u16 x, u16 i, u8 palette )
u32 GetRGBA8888_RGBA8888(u16 offset, u16 x, u16 i, u8 palette)
{
return RGBA8888_RGBA4444(((u32*)src)[x^i]);
return Get32BitColor(offset, x, i);
}
u32 GetRGBA8888_RGBA4444(u16 offset, u16 x, u16 i, u8 palette)
{
const u32 tex = Get32BitColor(offset, x, i);
return RGBA8888_RGBA4444(tex);
}
inline u32 YUV_RGBA8888(u8 y, u8 u, u8 v)
@ -242,7 +270,7 @@ inline u32 YUV_RGBA8888(u8 y, u8 u, u8 v)
return (0xff << 24) | (y << 16) | (v << 8) | u;
}
inline void GetYUV_RGBA8888(u64 * src, u32 * dst, u16 x)
void GetYUV_RGBA8888(u64 * src, u32 * dst, u16 x)
{
const u32 t = (((u32*)src)[x]);
u8 y1 = (u8)t & 0xFF;
@ -255,12 +283,223 @@ inline void GetYUV_RGBA8888(u64 * src, u32 * dst, u16 x)
*(dst++) = c;
}
u32 GetNoneBG(u64 *src, u16 x, u16 i, u8 palette)
{
return 0x00000000;
}
u32 GetCI4_RGBA8888_BG(u64 *src, u16 x, u16 i, u8 palette)
{
u8 color4B = ((u8*)src)[(x >> 1) ^ (i << 1)];
return CI4_RGBA8888((x & 1) ? (palette << 4) | (color4B & 0x0F) : (palette << 4) | (color4B >> 4));
}
u32 GetCI4_RGBA4444_BG(u64 *src, u16 x, u16 i, u8 palette)
{
u8 color4B = ((u8*)src)[(x >> 1) ^ (i << 1)];
return CI4_RGBA4444((x & 1) ? (palette << 4) | (color4B & 0x0F) : (palette << 4) | (color4B >> 4));
}
u32 GetCI4IA_RGBA4444_BG(u64 *src, u16 x, u16 i, u8 palette)
{
u8 color4B = ((u8*)src)[(x >> 1) ^ (i << 1)];
if (x & 1)
return IA88_RGBA4444(*(u16*)&TMEM[256 + (palette << 4) + (color4B & 0x0F)]);
else
return IA88_RGBA4444(*(u16*)&TMEM[256 + (palette << 4) + (color4B >> 4)]);
}
u32 GetCI4IA_RGBA8888_BG(u64 *src, u16 x, u16 i, u8 palette)
{
u8 color4B = ((u8*)src)[(x >> 1) ^ (i << 1)];
if (x & 1)
return IA88_RGBA8888(*(u16*)&TMEM[256 + (palette << 4) + (color4B & 0x0F)]);
else
return IA88_RGBA8888(*(u16*)&TMEM[256 + (palette << 4) + (color4B >> 4)]);
}
u32 GetCI4RGBA_RGBA5551_BG(u64 *src, u16 x, u16 i, u8 palette)
{
u8 color4B = ((u8*)src)[(x >> 1) ^ (i << 1)];
if (x & 1)
return RGBA5551_RGBA5551(*(u16*)&TMEM[256 + (palette << 4) + (color4B & 0x0F)]);
else
return RGBA5551_RGBA5551(*(u16*)&TMEM[256 + (palette << 4) + (color4B >> 4)]);
}
u32 GetCI4RGBA_RGBA8888_BG(u64 *src, u16 x, u16 i, u8 palette)
{
u8 color4B = ((u8*)src)[(x >> 1) ^ (i << 1)];
if (x & 1)
return RGBA5551_RGBA8888(*(u16*)&TMEM[256 + (palette << 4) + (color4B & 0x0F)]);
else
return RGBA5551_RGBA8888(*(u16*)&TMEM[256 + (palette << 4) + (color4B >> 4)]);
}
u32 GetIA31_RGBA8888_BG(u64 *src, u16 x, u16 i, u8 palette)
{
u8 color4B = ((u8*)src)[(x >> 1) ^ (i << 1)];
return IA31_RGBA8888((x & 1) ? (color4B & 0x0F) : (color4B >> 4));
}
u32 GetIA31_RGBA4444_BG(u64 *src, u16 x, u16 i, u8 palette)
{
u8 color4B = ((u8*)src)[(x >> 1) ^ (i << 1)];
return IA31_RGBA4444((x & 1) ? (color4B & 0x0F) : (color4B >> 4));
}
u32 GetI4_RGBA8888_BG(u64 *src, u16 x, u16 i, u8 palette)
{
u8 color4B = ((u8*)src)[(x >> 1) ^ (i << 1)];
return I4_RGBA8888((x & 1) ? (color4B & 0x0F) : (color4B >> 4));
}
u32 GetI4_RGBA4444_BG(u64 *src, u16 x, u16 i, u8 palette)
{
u8 color4B = ((u8*)src)[(x >> 1) ^ (i << 1)];
return I4_RGBA4444((x & 1) ? (color4B & 0x0F) : (color4B >> 4));
}
u32 GetCI8IA_RGBA4444_BG(u64 *src, u16 x, u16 i, u8 palette)
{
return IA88_RGBA4444(*(u16*)&TMEM[256 + ((u8*)src)[x ^ (i << 1)]]);
}
u32 GetCI8IA_RGBA8888_BG(u64 *src, u16 x, u16 i, u8 palette)
{
return IA88_RGBA8888(*(u16*)&TMEM[256 + ((u8*)src)[x ^ (i << 1)]]);
}
u32 GetCI8RGBA_RGBA5551_BG(u64 *src, u16 x, u16 i, u8 palette)
{
return RGBA5551_RGBA5551(*(u16*)&TMEM[256 + ((u8*)src)[x ^ (i << 1)]]);
}
u32 GetCI8RGBA_RGBA8888_BG(u64 *src, u16 x, u16 i, u8 palette)
{
return RGBA5551_RGBA8888(*(u16*)&TMEM[256 + ((u8*)src)[x ^ (i << 1)]]);
}
u32 GetIA44_RGBA8888_BG(u64 *src, u16 x, u16 i, u8 palette)
{
return IA44_RGBA8888(((u8*)src)[x ^ (i << 1)]);
}
u32 GetIA44_RGBA4444_BG(u64 *src, u16 x, u16 i, u8 palette)
{
return IA44_RGBA4444(((u8*)src)[x ^ (i << 1)]);
}
u32 GetI8_RGBA8888_BG(u64 *src, u16 x, u16 i, u8 palette)
{
return I8_RGBA8888(((u8*)src)[x ^ (i << 1)]);
}
u32 GetI8_RGBA4444_BG(u64 *src, u16 x, u16 i, u8 palette)
{
return I8_RGBA4444(((u8*)src)[x ^ (i << 1)]);
}
u32 GetI16_RGBA8888_BG(u64 *src, u16 x, u16 i, u8 palette)
{
const u16 tex = ((u16*)src)[x^i];
u32 r = tex >> 8;
u32 g = tex & 0xFF;
u32 b = r;
u32 a = g;
return (a << 24) | (b << 16) | (g << 8) | r;
}
u32 GetI16_RGBA4444_BG(u64 *src, u16 x, u16 i, u8 palette)
{
const u16 tex = ((u16*)src)[x^i];
u16 r = tex >> 12;
u16 g = tex & 0x0F;
u16 b = r;
u16 a = g;
return (a << 12) | (b << 8) | (g << 4) | r;
}
u32 GetCI16IA_RGBA8888_BG(u64 *src, u16 x, u16 i, u8 palette)
{
const u16 tex = ((u16*)src)[x^i];
const u16 col = (*(u16*)&TMEM[256 + (tex & 0xFF)]);
const u16 c = col >> 8;
const u16 a = col & 0xFF;
return (a << 24) | (c << 16) | (c << 8) | c;
}
u32 GetCI16IA_RGBA4444_BG(u64 *src, u16 x, u16 i, u8 palette)
{
const u16 tex = ((u16*)src)[x^i];
const u16 col = (*(u16*)&TMEM[256 + (tex & 0xFF)]);
const u16 c = col >> 12;
const u16 a = col & 0x0F;
return (a << 12) | (c << 8) | (c << 4) | c;
}
u32 GetCI16RGBA_RGBA8888_BG(u64 *src, u16 x, u16 i, u8 palette)
{
const u16 tex = (((u16*)src)[x^i]) & 0xFF;
return RGBA5551_RGBA8888(((u16*)&TMEM[256])[tex << 2]);
}
u32 GetCI16RGBA_RGBA5551_BG(u64 *src, u16 x, u16 i, u8 palette)
{
const u16 tex = (((u16*)src)[x^i]) & 0xFF;
return RGBA5551_RGBA5551(((u16*)&TMEM[256])[tex << 2]);
}
u32 GetRGBA5551_RGBA8888_BG(u64 *src, u16 x, u16 i, u8 palette)
{
u16 tex = ((u16*)src)[x^i];
return RGBA5551_RGBA8888(tex);
}
u32 GetRGBA5551_RGBA5551_BG(u64 *src, u16 x, u16 i, u8 palette)
{
u16 tex = ((u16*)src)[x^i];
return RGBA5551_RGBA5551(tex);
}
u32 GetIA88_RGBA8888_BG(u64 *src, u16 x, u16 i, u8 palette)
{
return IA88_RGBA8888(((u16*)src)[x^i]);
}
u32 GetIA88_RGBA4444_BG(u64 *src, u16 x, u16 i, u8 palette)
{
return IA88_RGBA4444(((u16*)src)[x^i]);
}
u32 GetRGBA8888_RGBA8888_BG(u64 *src, u16 x, u16 i, u8 palette)
{
return ((u32*)src)[x^i];
}
u32 GetRGBA8888_RGBA4444_BG(u64 *src, u16 x, u16 i, u8 palette)
{
return RGBA8888_RGBA4444(((u32*)src)[x^i]);
}
struct TextureLoadParameters
{
GetTexelFunc Get16;
GetTexelFuncBG Get16BG;
DatatypeParam glType16;
InternalColorFormatParam glInternalFormat16;
GetTexelFunc Get32;
GetTexelFuncBG Get32BG;
DatatypeParam glType32;
InternalColorFormatParam glInternalFormat32;
InternalColorFormatParam autoFormat;
@ -285,125 +524,125 @@ ImageFormat::ImageFormat()
{ // G_TT_NONE
{ // Get16 glType16 glInternalFormat16 Get32 glType32 glInternalFormat32 autoFormat
{ // 4-bit
{ GetI4_RGBA4444, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetI4_RGBA8888, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA4, 4, 8192 }, // RGBA as I
{ GetNone, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetNone, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA4, 4, 8192 }, // YUV
{ GetCI4_RGBA4444, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetCI4_RGBA8888, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA4, 4, 8192 }, // CI without palette
{ GetIA31_RGBA4444, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetIA31_RGBA8888, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA4, 4, 8192 }, // IA
{ GetI4_RGBA4444, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetI4_RGBA8888, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA4, 4, 8192 }, // I
{ GetI4_RGBA4444, GetI4_RGBA4444_BG, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetI4_RGBA8888, GetI4_RGBA8888_BG, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA4, 4, 8192 }, // RGBA as I
{ GetNone, GetNoneBG, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetNone, GetNoneBG, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA4, 4, 8192 }, // YUV
{ GetCI4_RGBA4444, GetCI4_RGBA4444_BG, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetCI4_RGBA8888, GetCI4_RGBA8888_BG, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA4, 4, 8192 }, // CI without palette
{ GetIA31_RGBA4444, GetIA31_RGBA4444_BG, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetIA31_RGBA8888, GetIA31_RGBA8888_BG, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA4, 4, 8192 }, // IA
{ GetI4_RGBA4444, GetI4_RGBA4444_BG, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetI4_RGBA8888, GetI4_RGBA8888_BG, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA4, 4, 8192 }, // I
},
{ // 8-bit
{ GetI8_RGBA4444, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetI8_RGBA8888, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA8, 3, 4096 }, // RGBA as I
{ GetNone, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetNone, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA4, 0, 4096 }, // YUV
{ GetI8_RGBA4444, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetI8_RGBA8888, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA8, 3, 4096 }, // CI without palette
{ GetIA44_RGBA4444, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetIA44_RGBA8888, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA4, 3, 4096 }, // IA
{ GetI8_RGBA4444, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetI8_RGBA8888, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA8, 3, 4096 }, // I
{ GetI8_RGBA4444, GetI8_RGBA4444_BG, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetI8_RGBA8888, GetI8_RGBA8888_BG, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA8, 3, 4096 }, // RGBA as I
{ GetNone, GetNoneBG, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetNone, GetNoneBG, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA4, 0, 4096 }, // YUV
{ GetI8_RGBA4444, GetI8_RGBA4444_BG, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetI8_RGBA8888, GetI8_RGBA8888_BG, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA8, 3, 4096 }, // CI without palette
{ GetIA44_RGBA4444, GetIA44_RGBA4444_BG, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetIA44_RGBA8888, GetIA44_RGBA8888_BG, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA4, 3, 4096 }, // IA
{ GetI8_RGBA4444, GetI8_RGBA4444_BG, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetI8_RGBA8888, GetI8_RGBA8888_BG, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA8, 3, 4096 }, // I
},
{ // 16-bit
{ GetRGBA5551_RGBA5551, datatype::UNSIGNED_SHORT_5_5_5_1, internalcolorFormat::RGB5_A1, GetRGBA5551_RGBA8888, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGB5_A1, 2, 2048 }, // RGBA
{ GetNone, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetNone, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA8, 2, 2048 }, // YUV
{ GetIA88_RGBA4444, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetIA88_RGBA8888, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA8, 2, 2048 }, // CI as IA
{ GetIA88_RGBA4444, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetIA88_RGBA8888, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA8, 2, 2048 }, // IA
{ GetI16_RGBA4444, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetI16_RGBA8888, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA8, 0, 2048 }, // I
{ GetRGBA5551_RGBA5551, GetRGBA5551_RGBA5551_BG, datatype::UNSIGNED_SHORT_5_5_5_1, internalcolorFormat::RGB5_A1, GetRGBA5551_RGBA8888, GetRGBA5551_RGBA8888_BG, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGB5_A1, 2, 2048 }, // RGBA
{ GetNone, GetNoneBG, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetNone, GetNoneBG, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA8, 2, 2048 }, // YUV
{ GetIA88_RGBA4444, GetIA88_RGBA4444_BG, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetIA88_RGBA8888, GetIA88_RGBA8888_BG, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA8, 2, 2048 }, // CI as IA
{ GetIA88_RGBA4444, GetIA88_RGBA4444_BG, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetIA88_RGBA8888, GetIA88_RGBA8888_BG, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA8, 2, 2048 }, // IA
{ GetI16_RGBA4444, GetI16_RGBA4444_BG, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetI16_RGBA8888, GetI16_RGBA8888_BG, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA8, 0, 2048 }, // I
},
{ // 32-bit
{ GetRGBA8888_RGBA4444, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetRGBA8888_RGBA8888, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA8, 2, 1024 }, // RGBA
{ GetNone, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetNone, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA4, 0, 1024 }, // YUV
{ GetNone, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetNone, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA4, 0, 1024 }, // CI
{ GetNone, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetNone, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA4, 0, 1024 }, // IA
{ GetNone, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetNone, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA4, 0, 1024 }, // I
{ GetRGBA8888_RGBA4444, GetRGBA8888_RGBA4444_BG, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetRGBA8888_RGBA8888, GetRGBA8888_RGBA8888_BG, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA8, 2, 1024 }, // RGBA
{ GetNone, GetNoneBG, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetNone, GetNoneBG, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA4, 0, 1024 }, // YUV
{ GetNone, GetNoneBG, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetNone, GetNoneBG, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA4, 0, 1024 }, // CI
{ GetNone, GetNoneBG, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetNone, GetNoneBG, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA4, 0, 1024 }, // IA
{ GetNone, GetNoneBG, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetNone, GetNoneBG, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA4, 0, 1024 }, // I
}
},
// DUMMY
{ // Get16 glType16 glInternalFormat16 Get32 glType32 glInternalFormat32 autoFormat
{ // 4-bit
{ GetCI4RGBA_RGBA5551, datatype::UNSIGNED_SHORT_5_5_5_1, internalcolorFormat::RGB5_A1, GetCI4RGBA_RGBA8888, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGB5_A1, 4, 4096 }, // CI (Banjo-Kazooie uses this, doesn't make sense, but it works...)
{ GetNone, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetNone, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA4, 4, 8192 }, // YUV
{ GetCI4RGBA_RGBA5551, datatype::UNSIGNED_SHORT_5_5_5_1, internalcolorFormat::RGB5_A1, GetCI4RGBA_RGBA8888, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGB5_A1, 4, 4096 }, // CI
{ GetCI4RGBA_RGBA5551, datatype::UNSIGNED_SHORT_5_5_5_1, internalcolorFormat::RGB5_A1, GetCI4RGBA_RGBA8888, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGB5_A1, 4, 4096 }, // IA as CI
{ GetCI4RGBA_RGBA5551, datatype::UNSIGNED_SHORT_5_5_5_1, internalcolorFormat::RGB5_A1, GetCI4RGBA_RGBA8888, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGB5_A1, 4, 4096 }, // I as CI
{ GetCI4RGBA_RGBA5551, GetCI4RGBA_RGBA5551_BG, datatype::UNSIGNED_SHORT_5_5_5_1, internalcolorFormat::RGB5_A1, GetCI4RGBA_RGBA8888, GetCI4RGBA_RGBA8888_BG, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGB5_A1, 4, 4096 }, // CI (Banjo-Kazooie uses this, doesn't make sense, but it works...)
{ GetNone, GetNoneBG, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetNone, GetNoneBG, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA4, 4, 8192 }, // YUV
{ GetCI4RGBA_RGBA5551, GetCI4RGBA_RGBA5551_BG, datatype::UNSIGNED_SHORT_5_5_5_1, internalcolorFormat::RGB5_A1, GetCI4RGBA_RGBA8888, GetCI4RGBA_RGBA8888_BG, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGB5_A1, 4, 4096 }, // CI
{ GetCI4RGBA_RGBA5551, GetCI4RGBA_RGBA5551_BG, datatype::UNSIGNED_SHORT_5_5_5_1, internalcolorFormat::RGB5_A1, GetCI4RGBA_RGBA8888, GetCI4RGBA_RGBA8888_BG, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGB5_A1, 4, 4096 }, // IA as CI
{ GetCI4RGBA_RGBA5551, GetCI4RGBA_RGBA5551_BG, datatype::UNSIGNED_SHORT_5_5_5_1, internalcolorFormat::RGB5_A1, GetCI4RGBA_RGBA8888, GetCI4RGBA_RGBA8888_BG, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGB5_A1, 4, 4096 }, // I as CI
},
{ // 8-bit
{ GetCI8RGBA_RGBA5551, datatype::UNSIGNED_SHORT_5_5_5_1, internalcolorFormat::RGB5_A1, GetCI8RGBA_RGBA8888, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGB5_A1, 3, 2048 }, // RGBA
{ GetNone, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetNone, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA4, 0, 4096 }, // YUV
{ GetCI8RGBA_RGBA5551, datatype::UNSIGNED_SHORT_5_5_5_1, internalcolorFormat::RGB5_A1, GetCI8RGBA_RGBA8888, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGB5_A1, 3, 2048 }, // CI
{ GetCI8RGBA_RGBA5551, datatype::UNSIGNED_SHORT_5_5_5_1, internalcolorFormat::RGB5_A1, GetCI8RGBA_RGBA8888, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGB5_A1, 3, 2048 }, // IA as CI
{ GetCI8RGBA_RGBA5551, datatype::UNSIGNED_SHORT_5_5_5_1, internalcolorFormat::RGB5_A1, GetCI8RGBA_RGBA8888, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGB5_A1, 3, 2048 }, // I as CI
{ GetCI8RGBA_RGBA5551, GetCI8RGBA_RGBA5551_BG, datatype::UNSIGNED_SHORT_5_5_5_1, internalcolorFormat::RGB5_A1, GetCI8RGBA_RGBA8888, GetCI8RGBA_RGBA8888_BG, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGB5_A1, 3, 2048 }, // RGBA
{ GetNone, GetNoneBG, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetNone, GetNoneBG, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA4, 0, 4096 }, // YUV
{ GetCI8RGBA_RGBA5551, GetCI8RGBA_RGBA5551_BG, datatype::UNSIGNED_SHORT_5_5_5_1, internalcolorFormat::RGB5_A1, GetCI8RGBA_RGBA8888, GetCI8RGBA_RGBA8888_BG, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGB5_A1, 3, 2048 }, // CI
{ GetCI8RGBA_RGBA5551, GetCI8RGBA_RGBA5551_BG, datatype::UNSIGNED_SHORT_5_5_5_1, internalcolorFormat::RGB5_A1, GetCI8RGBA_RGBA8888, GetCI8RGBA_RGBA8888_BG, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGB5_A1, 3, 2048 }, // IA as CI
{ GetCI8RGBA_RGBA5551, GetCI8RGBA_RGBA5551_BG, datatype::UNSIGNED_SHORT_5_5_5_1, internalcolorFormat::RGB5_A1, GetCI8RGBA_RGBA8888, GetCI8RGBA_RGBA8888_BG, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGB5_A1, 3, 2048 }, // I as CI
},
{ // 16-bit
{ GetCI16RGBA_RGBA5551, datatype::UNSIGNED_SHORT_5_5_5_1, internalcolorFormat::RGB5_A1, GetRGBA5551_RGBA8888, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGB5_A1, 2, 2048 }, // RGBA
{ GetNone, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetNone, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA8, 2, 2048 }, // YUV
{ GetNone, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetNone, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA4, 0, 2048 }, // CI
{ GetCI16RGBA_RGBA5551, datatype::UNSIGNED_SHORT_5_5_5_1, internalcolorFormat::RGB5_A1, GetCI16RGBA_RGBA8888, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGB5_A1, 2, 2048 }, // IA as CI
{ GetNone, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetNone, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA4, 0, 2048 }, // I
{ GetCI16RGBA_RGBA5551, GetCI16RGBA_RGBA5551_BG, datatype::UNSIGNED_SHORT_5_5_5_1, internalcolorFormat::RGB5_A1, GetRGBA5551_RGBA8888, GetRGBA5551_RGBA8888_BG, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGB5_A1, 2, 2048 }, // RGBA
{ GetNone, GetNoneBG, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetNone, GetNoneBG, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA8, 2, 2048 }, // YUV
{ GetNone, GetNoneBG, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetNone, GetNoneBG, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA4, 0, 2048 }, // CI
{ GetCI16RGBA_RGBA5551, GetCI16RGBA_RGBA5551_BG, datatype::UNSIGNED_SHORT_5_5_5_1, internalcolorFormat::RGB5_A1, GetCI16RGBA_RGBA8888, GetCI16RGBA_RGBA8888_BG, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGB5_A1, 2, 2048 }, // IA as CI
{ GetNone, GetNoneBG, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetNone, GetNoneBG, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA4, 0, 2048 }, // I
},
{ // 32-bit
{ GetRGBA8888_RGBA4444, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetRGBA8888_RGBA8888, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA8, 2, 1024 }, // RGBA
{ GetNone, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetNone, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA4, 0, 1024 }, // YUV
{ GetNone, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetNone, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA4, 0, 1024 }, // CI
{ GetNone, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetNone, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA4, 0, 1024 }, // IA
{ GetNone, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetNone, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA4, 0, 1024 }, // I
{ GetRGBA8888_RGBA4444, GetRGBA8888_RGBA4444_BG, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetRGBA8888_RGBA8888, GetRGBA8888_RGBA8888_BG, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA8, 2, 1024 }, // RGBA
{ GetNone, GetNoneBG, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetNone, GetNoneBG, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA4, 0, 1024 }, // YUV
{ GetNone, GetNoneBG, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetNone, GetNoneBG, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA4, 0, 1024 }, // CI
{ GetNone, GetNoneBG, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetNone, GetNoneBG, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA4, 0, 1024 }, // IA
{ GetNone, GetNoneBG, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetNone, GetNoneBG, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA4, 0, 1024 }, // I
}
},
// G_TT_RGBA16
{ // Get16 glType16 glInternalFormat16 Get32 glType32 glInternalFormat32 autoFormat
{ // 4-bit
{ GetCI4RGBA_RGBA5551, datatype::UNSIGNED_SHORT_5_5_5_1, internalcolorFormat::RGB5_A1, GetCI4RGBA_RGBA8888, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGB5_A1, 4, 4096 }, // CI (Banjo-Kazooie uses this, doesn't make sense, but it works...)
{ GetNone, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetNone, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA4, 4, 8192 }, // YUV
{ GetCI4RGBA_RGBA5551, datatype::UNSIGNED_SHORT_5_5_5_1, internalcolorFormat::RGB5_A1, GetCI4RGBA_RGBA8888, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGB5_A1, 4, 4096 }, // CI
{ GetCI4RGBA_RGBA5551, datatype::UNSIGNED_SHORT_5_5_5_1, internalcolorFormat::RGB5_A1, GetCI4RGBA_RGBA8888, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGB5_A1, 4, 4096 }, // IA as CI
{ GetCI4RGBA_RGBA5551, datatype::UNSIGNED_SHORT_5_5_5_1, internalcolorFormat::RGB5_A1, GetCI4RGBA_RGBA8888, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGB5_A1, 4, 4096 }, // I as CI
{ GetCI4RGBA_RGBA5551, GetCI4RGBA_RGBA5551_BG, datatype::UNSIGNED_SHORT_5_5_5_1, internalcolorFormat::RGB5_A1, GetCI4RGBA_RGBA8888, GetCI4RGBA_RGBA8888_BG, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGB5_A1, 4, 4096 }, // CI (Banjo-Kazooie uses this, doesn't make sense, but it works...)
{ GetNone, GetNoneBG, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetNone, GetNoneBG, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA4, 4, 8192 }, // YUV
{ GetCI4RGBA_RGBA5551, GetCI4RGBA_RGBA5551_BG, datatype::UNSIGNED_SHORT_5_5_5_1, internalcolorFormat::RGB5_A1, GetCI4RGBA_RGBA8888, GetCI4RGBA_RGBA8888_BG, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGB5_A1, 4, 4096 }, // CI
{ GetCI4RGBA_RGBA5551, GetCI4RGBA_RGBA5551_BG, datatype::UNSIGNED_SHORT_5_5_5_1, internalcolorFormat::RGB5_A1, GetCI4RGBA_RGBA8888, GetCI4RGBA_RGBA8888_BG, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGB5_A1, 4, 4096 }, // IA as CI
{ GetCI4RGBA_RGBA5551, GetCI4RGBA_RGBA5551_BG, datatype::UNSIGNED_SHORT_5_5_5_1, internalcolorFormat::RGB5_A1, GetCI4RGBA_RGBA8888, GetCI4RGBA_RGBA8888_BG, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGB5_A1, 4, 4096 }, // I as CI
},
{ // 8-bit
{ GetCI8RGBA_RGBA5551, datatype::UNSIGNED_SHORT_5_5_5_1, internalcolorFormat::RGB5_A1, GetCI8RGBA_RGBA8888, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGB5_A1, 3, 2048 }, // RGBA
{ GetNone, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetNone, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA4, 0, 4096 }, // YUV
{ GetCI8RGBA_RGBA5551, datatype::UNSIGNED_SHORT_5_5_5_1, internalcolorFormat::RGB5_A1, GetCI8RGBA_RGBA8888, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGB5_A1, 3, 2048 }, // CI
{ GetCI8RGBA_RGBA5551, datatype::UNSIGNED_SHORT_5_5_5_1, internalcolorFormat::RGB5_A1, GetCI8RGBA_RGBA8888, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGB5_A1, 3, 2048 }, // IA as CI
{ GetCI8RGBA_RGBA5551, datatype::UNSIGNED_SHORT_5_5_5_1, internalcolorFormat::RGB5_A1, GetCI8RGBA_RGBA8888, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGB5_A1, 3, 2048 }, // I as CI
{ GetCI8RGBA_RGBA5551, GetCI8RGBA_RGBA5551_BG, datatype::UNSIGNED_SHORT_5_5_5_1, internalcolorFormat::RGB5_A1, GetCI8RGBA_RGBA8888, GetCI8RGBA_RGBA8888_BG, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGB5_A1, 3, 2048 }, // RGBA
{ GetNone, GetNoneBG, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetNone, GetNoneBG, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA4, 0, 4096 }, // YUV
{ GetCI8RGBA_RGBA5551, GetCI8RGBA_RGBA5551_BG, datatype::UNSIGNED_SHORT_5_5_5_1, internalcolorFormat::RGB5_A1, GetCI8RGBA_RGBA8888, GetCI8RGBA_RGBA8888_BG, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGB5_A1, 3, 2048 }, // CI
{ GetCI8RGBA_RGBA5551, GetCI8RGBA_RGBA5551_BG, datatype::UNSIGNED_SHORT_5_5_5_1, internalcolorFormat::RGB5_A1, GetCI8RGBA_RGBA8888, GetCI8RGBA_RGBA8888_BG, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGB5_A1, 3, 2048 }, // IA as CI
{ GetCI8RGBA_RGBA5551, GetCI8RGBA_RGBA5551_BG, datatype::UNSIGNED_SHORT_5_5_5_1, internalcolorFormat::RGB5_A1, GetCI8RGBA_RGBA8888, GetCI8RGBA_RGBA8888_BG, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGB5_A1, 3, 2048 }, // I as CI
},
{ // 16-bit
{ GetCI16RGBA_RGBA5551, datatype::UNSIGNED_SHORT_5_5_5_1, internalcolorFormat::RGB5_A1, GetRGBA5551_RGBA8888, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGB5_A1, 2, 2048 }, // RGBA
{ GetNone, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetNone, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA8, 2, 2048 }, // YUV
{ GetNone, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetNone, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA4, 0, 2048 }, // CI
{ GetCI16RGBA_RGBA5551, datatype::UNSIGNED_SHORT_5_5_5_1, internalcolorFormat::RGB5_A1, GetCI16RGBA_RGBA8888, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGB5_A1, 2, 2048 }, // IA as CI
{ GetNone, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetNone, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA4, 0, 2048 }, // I
{ GetCI16RGBA_RGBA5551, GetCI16RGBA_RGBA5551_BG, datatype::UNSIGNED_SHORT_5_5_5_1, internalcolorFormat::RGB5_A1, GetRGBA5551_RGBA8888, GetRGBA5551_RGBA8888_BG, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGB5_A1, 2, 2048 }, // RGBA
{ GetNone, GetNoneBG, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetNone, GetNoneBG, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA8, 2, 2048 }, // YUV
{ GetNone, GetNoneBG, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetNone, GetNoneBG, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA4, 0, 2048 }, // CI
{ GetCI16RGBA_RGBA5551, GetCI16RGBA_RGBA5551_BG, datatype::UNSIGNED_SHORT_5_5_5_1, internalcolorFormat::RGB5_A1, GetCI16RGBA_RGBA8888, GetCI16RGBA_RGBA8888_BG, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGB5_A1, 2, 2048 }, // IA as CI
{ GetNone, GetNoneBG, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetNone, GetNoneBG, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA4, 0, 2048 }, // I
},
{ // 32-bit
{ GetRGBA8888_RGBA4444, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetRGBA8888_RGBA8888, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA8, 2, 1024 }, // RGBA
{ GetNone, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetNone, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA4, 0, 1024 }, // YUV
{ GetNone, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetNone, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA4, 0, 1024 }, // CI
{ GetNone, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetNone, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA4, 0, 1024 }, // IA
{ GetNone, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetNone, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA4, 0, 1024 }, // I
{ GetRGBA8888_RGBA4444, GetRGBA8888_RGBA4444_BG, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetRGBA8888_RGBA8888, GetRGBA8888_RGBA8888_BG, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA8, 2, 1024 }, // RGBA
{ GetNone, GetNoneBG, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetNone, GetNoneBG, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA4, 0, 1024 }, // YUV
{ GetNone, GetNoneBG, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetNone, GetNoneBG, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA4, 0, 1024 }, // CI
{ GetNone, GetNoneBG, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetNone, GetNoneBG, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA4, 0, 1024 }, // IA
{ GetNone, GetNoneBG, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetNone, GetNoneBG, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA4, 0, 1024 }, // I
}
},
// G_TT_IA16
{ // Get16 glType16 glInternalFormat16 Get32 glType32 glInternalFormat32 autoFormat
{ // 4-bit
{ GetCI4IA_RGBA4444, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetCI4IA_RGBA8888, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA8, 4, 4096 }, // IA
{ GetNone, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetNone, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA8, 4, 8192 }, // YUV
{ GetCI4IA_RGBA4444, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetCI4IA_RGBA8888, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA8, 4, 4096 }, // CI
{ GetCI4IA_RGBA4444, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetCI4IA_RGBA8888, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA8, 4, 4096 }, // IA
{ GetCI4IA_RGBA4444, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetCI4IA_RGBA8888, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA8, 4, 4096 }, // I
{ GetCI4IA_RGBA4444, GetCI4IA_RGBA4444_BG, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetCI4IA_RGBA8888, GetCI4IA_RGBA8888_BG, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA8, 4, 4096 }, // IA
{ GetNone, GetNoneBG, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetNone, GetNoneBG, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA8, 4, 8192 }, // YUV
{ GetCI4IA_RGBA4444, GetCI4IA_RGBA4444_BG, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetCI4IA_RGBA8888, GetCI4IA_RGBA8888_BG, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA8, 4, 4096 }, // CI
{ GetCI4IA_RGBA4444, GetCI4IA_RGBA4444_BG, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetCI4IA_RGBA8888, GetCI4IA_RGBA8888_BG, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA8, 4, 4096 }, // IA
{ GetCI4IA_RGBA4444, GetCI4IA_RGBA4444_BG, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetCI4IA_RGBA8888, GetCI4IA_RGBA8888_BG, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA8, 4, 4096 }, // I
},
{ // 8-bit
{ GetCI8IA_RGBA4444, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetCI8IA_RGBA8888, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA8, 3, 2048 }, // RGBA
{ GetNone, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetNone, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA8, 0, 4096 }, // YUV
{ GetCI8IA_RGBA4444, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetCI8IA_RGBA8888, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA8, 3, 2048 }, // CI
{ GetCI8IA_RGBA4444, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetCI8IA_RGBA8888, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA8, 3, 2048 }, // IA
{ GetCI8IA_RGBA4444, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetCI8IA_RGBA8888, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA8, 3, 2048 }, // I
{ GetCI8IA_RGBA4444, GetCI8IA_RGBA4444_BG, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetCI8IA_RGBA8888, GetCI8IA_RGBA8888_BG, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA8, 3, 2048 }, // RGBA
{ GetNone, GetNoneBG, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetNone, GetNoneBG, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA8, 0, 4096 }, // YUV
{ GetCI8IA_RGBA4444, GetCI8IA_RGBA4444_BG, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetCI8IA_RGBA8888, GetCI8IA_RGBA8888_BG, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA8, 3, 2048 }, // CI
{ GetCI8IA_RGBA4444, GetCI8IA_RGBA4444_BG, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetCI8IA_RGBA8888, GetCI8IA_RGBA8888_BG, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA8, 3, 2048 }, // IA
{ GetCI8IA_RGBA4444, GetCI8IA_RGBA4444_BG, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetCI8IA_RGBA8888, GetCI8IA_RGBA8888_BG, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA8, 3, 2048 }, // I
},
{ // 16-bit
{ GetCI16IA_RGBA4444, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetCI16IA_RGBA8888, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA8, 2, 2048 }, // RGBA
{ GetNone, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetNone, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA8, 2, 2048 }, // YUV
{ GetNone, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetNone, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA8, 0, 2048 }, // CI
{ GetCI16IA_RGBA4444, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetCI16IA_RGBA8888, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA8, 2, 2048 }, // IA
{ GetNone, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetNone, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA8, 0, 2048 }, // I
{ GetCI16IA_RGBA4444, GetCI16IA_RGBA4444_BG, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetCI16IA_RGBA8888, GetCI16IA_RGBA8888_BG, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA8, 2, 2048 }, // RGBA
{ GetNone, GetNoneBG, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetNone, GetNoneBG, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA8, 2, 2048 }, // YUV
{ GetNone, GetNoneBG, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetNone, GetNoneBG, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA8, 0, 2048 }, // CI
{ GetCI16IA_RGBA4444, GetCI16IA_RGBA4444_BG, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetCI16IA_RGBA8888, GetCI16IA_RGBA8888_BG, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA8, 2, 2048 }, // IA
{ GetNone, GetNoneBG, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetNone, GetNoneBG, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA8, 0, 2048 }, // I
},
{ // 32-bit
{ GetRGBA8888_RGBA4444, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetRGBA8888_RGBA8888, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA8, 2, 1024 }, // RGBA
{ GetNone, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetNone, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA8, 0, 1024 }, // YUV
{ GetNone, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetNone, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA8, 0, 1024 }, // CI
{ GetNone, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetNone, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA8, 0, 1024 }, // IA
{ GetNone, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetNone, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA8, 0, 1024 }, // I
{ GetRGBA8888_RGBA4444, GetRGBA8888_RGBA4444_BG, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetRGBA8888_RGBA8888, GetRGBA8888_RGBA8888_BG, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA8, 2, 1024 }, // RGBA
{ GetNone, GetNoneBG, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetNone, GetNoneBG, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA8, 0, 1024 }, // YUV
{ GetNone, GetNoneBG, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetNone, GetNoneBG, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA8, 0, 1024 }, // CI
{ GetNone, GetNoneBG, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetNone, GetNoneBG, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA8, 0, 1024 }, // IA
{ GetNone, GetNoneBG, datatype::UNSIGNED_SHORT_4_4_4_4, internalcolorFormat::RGBA4, GetNone, GetNoneBG, datatype::UNSIGNED_BYTE, internalcolorFormat::RGBA8, internalcolorFormat::RGBA8, 0, 1024 }, // I
}
}
};
@ -759,11 +998,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;
@ -799,7 +1037,7 @@ void TextureCache::_loadBackground(CachedTexture *pTexture)
u32 x, y, j, tx, ty;
u16 clampSClamp;
u16 clampTClamp;
GetTexelFunc GetTexel;
GetTexelFuncBG GetTexel;
InternalColorFormatParam glInternalFormat;
DatatypeParam glType;
@ -807,12 +1045,12 @@ void TextureCache::_loadBackground(CachedTexture *pTexture)
ImageFormat::get().tlp[pTexture->format == 2 ? G_TT_RGBA16 : G_TT_NONE][pTexture->size][pTexture->format];
if (loadParams.autoFormat == internalcolorFormat::RGBA8) {
pTexture->textureBytes = (pTexture->width * pTexture->height) << 2;
GetTexel = loadParams.Get32;
GetTexel = loadParams.Get32BG;
glInternalFormat = loadParams.glInternalFormat32;
glType = loadParams.glType32;
} else {
pTexture->textureBytes = (pTexture->width * pTexture->height) << 1;
GetTexel = loadParams.Get16;
GetTexel = loadParams.Get16BG;
glInternalFormat = loadParams.glInternalFormat16;
glType = loadParams.glType16;
}
@ -861,7 +1099,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);
}
@ -871,7 +1109,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 &&
@ -985,10 +1223,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;
@ -1047,7 +1285,6 @@ void TextureCache::_getTextureDestData(CachedTexture& tmptex,
u16 maskTMask, clampTClamp;
u16 x, y, tx, ty;
u32 i, j;
u64 *pSrc;
if (tmptex.maskS > 0) {
clampSClamp = tmptex.clampS ? tmptex.clampWidth - 1 : (tmptex.mirrorS ? (tmptex.width << 1) - 1 : tmptex.width - 1);
@ -1110,7 +1347,7 @@ void TextureCache::_getTextureDestData(CachedTexture& tmptex,
j = 0;
*pLine <<= 1;
for (y = 0; y < tmptex.height; ++y) {
pSrc = &TMEM[tmptex.tMem] + *pLine * y;
u64* pSrc = &TMEM[tmptex.tMem] + *pLine * y;
for (x = 0; x < tmptex.width / 2; x++) {
GetYUV_RGBA8888(pSrc, pDest + j, x);
j += 2;
@ -1122,17 +1359,16 @@ void TextureCache::_getTextureDestData(CachedTexture& tmptex,
for (y = 0; y < tmptex.height; ++y) {
ty = min(y, clampTClamp) & maskTMask;
pSrc = &TMEM[(tmptex.tMem + *pLine * ty) & tMemMask];
u16 tmemOffset = (tmptex.tMem + *pLine * ty) & tMemMask;
i = (ty & 1) << 1;
for (x = 0; x < tmptex.width; ++x) {
tx = min(x, clampSClamp) & maskSMask;
if (glInternalFormat == internalcolorFormat::RGBA8) {
pDest[j++] = GetTexel(pSrc, tx, i, tmptex.palette);
} else {
((u16*)pDest)[j++] = GetTexel(pSrc, tx, i, tmptex.palette);
}
if (glInternalFormat == internalcolorFormat::RGBA8)
pDest[j++] = GetTexel(tmemOffset, tx, i, tmptex.palette);
else
((u16*)pDest)[j++] = GetTexel(tmemOffset, tx, i, tmptex.palette);
}
}
}
@ -1263,7 +1499,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);
}
@ -1290,6 +1526,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) &&
@ -1367,7 +1604,7 @@ void TextureCache::_loadAccurate(u32 _tile, CachedTexture *_pTexture)
bool force32bitFormat = false;
_pTexture->max_level = 0;
if (config.generalEmulation.enableLOD != 0 && currentCombiner()->usesLOD() && gSP.texture.level > 1 && _tile > 0) {
if (currentCombiner()->usesLOD() && gSP.texture.level > 1 && _tile > 0) {
_pTexture->max_level = gDP.otherMode.textureDetail == G_TD_DETAIL ?
static_cast<u8>(gSP.texture.level) :
static_cast<u8>(gSP.texture.level - 1);
@ -1437,7 +1674,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);
}
@ -1495,7 +1732,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);
}
@ -1522,6 +1759,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) &&

View File

@ -13,7 +13,8 @@
#include "Graphics/ObjectHandle.h"
#include "Graphics/Parameter.h"
typedef u32 (*GetTexelFunc)( u64 *src, u16 x, u16 i, u8 palette );
typedef u32 (*GetTexelFunc)(u16 offset, u16 x, u16 i, u8 palette);
typedef u32 (*GetTexelFuncBG)(u64 *src, u16 x, u16 i, u8 palette);
struct GHQTexInfo;
struct CachedTexture

View File

@ -221,6 +221,16 @@ static void checkHotkeys()
dwnd().getDrawer().showMessage("Force gamma correction off\n", Milliseconds(750));
config.gammaCorrection.force = !config.gammaCorrection.force;
}
if (osal_is_key_pressed(config.hotkeys.enabledKeys[Config::hkInaccurateTexCords], 0x0001)) {
config.generalEmulation.enableInaccurateTextureCoordinates = !config.generalEmulation.enableInaccurateTextureCoordinates;
dwnd().stop();
dwnd().start();
if (config.generalEmulation.enableInaccurateTextureCoordinates == 0)
dwnd().getDrawer().showMessage("Disable inaccurate texture coordinates\n", Milliseconds(1000));
else
dwnd().getDrawer().showMessage("Enable inaccurate texture coordinates\n", Milliseconds(1000));
}
}
void VI_UpdateScreen()

View File

@ -50,10 +50,12 @@ void _cutLastPathSeparator(wchar_t * _strPath)
}
static
void _getWSPath(const char * _path, wchar_t * _strPath)
void _getWSPath(const char * _path, wchar_t * _strPath, bool cutLastPathSeperator = false)
{
::mbstowcs(_strPath, _path, PLUGIN_PATH_SIZE);
_cutLastPathSeparator(_strPath);
if (cutLastPathSeperator) {
_cutLastPathSeparator(_strPath);
}
}
void PluginAPI::GetUserDataPath(wchar_t * _strPath)
@ -66,6 +68,13 @@ void PluginAPI::GetUserCachePath(wchar_t * _strPath)
_getWSPath(ConfigGetUserCachePath(), _strPath);
}
#ifdef M64P_GLIDENUI
void PluginAPI::GetUserConfigPath(wchar_t * _strPath)
{
_getWSPath(ConfigGetUserConfigPath(), _strPath);
}
#endif // M64P_GLIDENUI
void PluginAPI::FindPluginPath(wchar_t * _strPath)
{
if (_strPath == nullptr)
@ -91,7 +100,7 @@ void PluginAPI::FindPluginPath(wchar_t * _strPath)
if (line.find("GLideN64") != std::string::npos)
{
_getWSPath(line.c_str(), _strPath);
_getWSPath(line.c_str(), _strPath, true);
maps.close();
return;
}
@ -104,14 +113,14 @@ void PluginAPI::FindPluginPath(wchar_t * _strPath)
int res = readlink("/proc/self/exe", path, 510);
if (res != -1) {
path[res] = 0;
_getWSPath(path, _strPath);
_getWSPath(path, _strPath, true);
}
#elif defined(OS_MAC_OS_X)
#define MAXPATHLEN 256
char path[MAXPATHLEN];
uint32_t pathLen = MAXPATHLEN * 2;
if (_NSGetExecutablePath(path, &pathLen) == 0) {
_getWSPath(path, _strPath);
_getWSPath(path, _strPath, true);
}
#elif defined(OS_ANDROID)
GetUserCachePath(_strPath);

View File

@ -51,6 +51,8 @@ const char* _hotkeyDescription(u32 _idx)
return "Hotkey: toggle OSD rendering resolution";
case Config::HotKey::hkForceGammaCorrection:
return "Hotkey: toggle force gamma correction";
case Config::HotKey::hkInaccurateTexCords:
return "Hotkey: toggle inaccurate texture coordinates";
}
return "Unknown hotkey";
}

View File

@ -1,7 +1,7 @@
#ifndef GLIDEN64_WINDOWS_H
#define GLIDEN64_WINDOWS_H
#include <windows.h>
#include "Platform.h"
extern HWND hWnd;
extern HWND hStatusBar;

View File

@ -1,4 +1,4 @@
#include <Windows.h>
#include "Platform.h"
#include "Config.h"
#include "../GLideNHQ/inc/png.h"
@ -118,6 +118,6 @@ void SaveScreenshot(const wchar_t * _folder, const char * _name, int _width, int
}
if (i == 1000)
return;
write_png_file(fileName, _width, _height, _data);
}