From d6722faee646f200be56c2135de45b6ff9bf1018 Mon Sep 17 00:00:00 2001 From: zilmar Date: Fri, 5 Feb 2016 04:35:02 +1100 Subject: [PATCH] [Glide64] Clean up GlideHQ/TxHiResCache.cpp --- Source/GlideHQ/TxHiResCache.cpp | 1771 ++++++++++++++++--------------- 1 file changed, 888 insertions(+), 883 deletions(-) diff --git a/Source/GlideHQ/TxHiResCache.cpp b/Source/GlideHQ/TxHiResCache.cpp index 592ee5f86..c691384dc 100644 --- a/Source/GlideHQ/TxHiResCache.cpp +++ b/Source/GlideHQ/TxHiResCache.cpp @@ -28,7 +28,7 @@ #pragma warning(disable: 4786) #endif -/* dump processed hirestextures to disk +/* dump processed hirestextures to disk * (0:disable, 1:enable) */ #define DUMP_CACHE 1 @@ -67,1004 +67,1009 @@ TxHiResCache::~TxHiResCache() { #if DUMP_CACHE - if ((_options & DUMP_HIRESTEXCACHE) && !_haveCache && !_abortLoad) { - /* dump cache to disk */ - std::wstring filename = _ident + L"_HIRESTEXTURES.dat"; + if ((_options & DUMP_HIRESTEXCACHE) && !_haveCache && !_abortLoad) { + /* dump cache to disk */ + std::wstring filename = _ident + L"_HIRESTEXTURES.dat"; - CPath cachepath(stdstr().FromUTF16(_path.c_str()).c_str(),""); - cachepath.AppendDirectory("cache"); - int config = _options & (HIRESTEXTURES_MASK|COMPRESS_HIRESTEX|COMPRESSION_MASK|TILE_HIRESTEX|FORCE16BPP_HIRESTEX|GZ_HIRESTEXCACHE|LET_TEXARTISTS_FLY); + CPath cachepath(stdstr().FromUTF16(_path.c_str()).c_str(), ""); + cachepath.AppendDirectory("cache"); + int config = _options & (HIRESTEXTURES_MASK | COMPRESS_HIRESTEX | COMPRESSION_MASK | TILE_HIRESTEX | FORCE16BPP_HIRESTEX | GZ_HIRESTEXCACHE | LET_TEXARTISTS_FLY); - TxCache::save(stdstr((std::string &)cachepath).ToUTF16().c_str(), filename.c_str(), config); - } + TxCache::save(stdstr((std::string &)cachepath).ToUTF16().c_str(), filename.c_str(), config); + } #endif - delete _txImage; - delete _txQuantize; - delete _txReSample; + delete _txImage; + delete _txQuantize; + delete _txReSample; } TxHiResCache::TxHiResCache(int maxwidth, int maxheight, int maxbpp, int options, - const wchar_t *path, const wchar_t *ident, - dispInfoFuncExt callback - ) : TxCache((options & ~GZ_TEXCACHE), 0, path, ident, callback) + const wchar_t *path, const wchar_t *ident, + dispInfoFuncExt callback + ) : TxCache((options & ~GZ_TEXCACHE), 0, path, ident, callback) { - _txImage = new TxImage(); - _txQuantize = new TxQuantize(); - _txReSample = new TxReSample(); + _txImage = new TxImage(); + _txQuantize = new TxQuantize(); + _txReSample = new TxReSample(); - _maxwidth = maxwidth; - _maxheight = maxheight; - _maxbpp = maxbpp; - _abortLoad = 0; - _haveCache = 0; + _maxwidth = maxwidth; + _maxheight = maxheight; + _maxbpp = maxbpp; + _abortLoad = 0; + _haveCache = 0; - /* assert local options */ - if (!(_options & COMPRESS_HIRESTEX)) - _options &= ~COMPRESSION_MASK; + /* assert local options */ + if (!(_options & COMPRESS_HIRESTEX)) + _options &= ~COMPRESSION_MASK; - if (_path.empty() || _ident.empty()) { - _options &= ~DUMP_HIRESTEXCACHE; - return; - } + if (_path.empty() || _ident.empty()) { + _options &= ~DUMP_HIRESTEXCACHE; + return; + } #if DUMP_CACHE - /* read in hires texture cache */ - if (_options & DUMP_HIRESTEXCACHE) { - /* find it on disk */ - std::wstring filename = _ident + L"_HIRESTEXTURES.dat"; - CPath cachepath(stdstr().FromUTF16(_path.c_str()).c_str(),""); - cachepath.AppendDirectory("cache"); - int config = _options & (HIRESTEXTURES_MASK|COMPRESS_HIRESTEX|COMPRESSION_MASK|TILE_HIRESTEX|FORCE16BPP_HIRESTEX|GZ_HIRESTEXCACHE|LET_TEXARTISTS_FLY); + /* read in hires texture cache */ + if (_options & DUMP_HIRESTEXCACHE) { + /* find it on disk */ + std::wstring filename = _ident + L"_HIRESTEXTURES.dat"; + CPath cachepath(stdstr().FromUTF16(_path.c_str()).c_str(), ""); + cachepath.AppendDirectory("cache"); + int config = _options & (HIRESTEXTURES_MASK | COMPRESS_HIRESTEX | COMPRESSION_MASK | TILE_HIRESTEX | FORCE16BPP_HIRESTEX | GZ_HIRESTEXCACHE | LET_TEXARTISTS_FLY); - _haveCache = TxCache::load(stdstr((std::string &)cachepath).ToUTF16().c_str(), filename.c_str(), config); - } + _haveCache = TxCache::load(stdstr((std::string &)cachepath).ToUTF16().c_str(), filename.c_str(), config); + } #endif - /* read in hires textures */ - if (!_haveCache) TxHiResCache::load(0); + /* read in hires textures */ + if (!_haveCache) TxHiResCache::load(0); } boolean TxHiResCache::empty() { - return _cache.empty(); + return _cache.empty(); } boolean TxHiResCache::load(boolean replace) /* 0 : reload, 1 : replace partial */ { - if (!_path.empty() && !_ident.empty()) { + if (!_path.empty() && !_ident.empty()) { + if (!replace) TxCache::clear(); - if (!replace) TxCache::clear(); + CPath dir_path(stdstr().FromUTF16(_path.c_str()).c_str(), ""); - CPath dir_path(stdstr().FromUTF16(_path.c_str()).c_str(),""); + switch (_options & HIRESTEXTURES_MASK) { + case GHQ_HIRESTEXTURES: + break; + case RICE_HIRESTEXTURES: + INFO(80, L"-----\n"); + INFO(80, L"using Rice hires texture format...\n"); + INFO(80, L" must be one of the following;\n"); + INFO(80, L" 1) *_rgb.png + *_a.png\n"); + INFO(80, L" 2) *_all.png\n"); + INFO(80, L" 3) *_ciByRGBA.png\n"); + INFO(80, L" 4) *_allciByRGBA.png\n"); + INFO(80, L" 5) *_ci.bmp\n"); + INFO(80, L" usage of only 2) and 3) highly recommended!\n"); + INFO(80, L" folder names must be in US-ASCII characters!\n"); - switch (_options & HIRESTEXTURES_MASK) { - case GHQ_HIRESTEXTURES: - break; - case RICE_HIRESTEXTURES: - INFO(80, L"-----\n"); - INFO(80, L"using Rice hires texture format...\n"); - INFO(80, L" must be one of the following;\n"); - INFO(80, L" 1) *_rgb.png + *_a.png\n"); - INFO(80, L" 2) *_all.png\n"); - INFO(80, L" 3) *_ciByRGBA.png\n"); - INFO(80, L" 4) *_allciByRGBA.png\n"); - INFO(80, L" 5) *_ci.bmp\n"); - INFO(80, L" usage of only 2) and 3) highly recommended!\n"); - INFO(80, L" folder names must be in US-ASCII characters!\n"); + dir_path.AppendDirectory(stdstr().FromUTF16(_ident.c_str()).c_str()); + loadHiResTextures(dir_path, replace); + break; + case JABO_HIRESTEXTURES: + ; + } - dir_path.AppendDirectory(stdstr().FromUTF16(_ident.c_str()).c_str()); - loadHiResTextures(dir_path, replace); - break; - case JABO_HIRESTEXTURES: - ; + return 1; } - return 1; - } - - return 0; + return 0; } boolean TxHiResCache::loadHiResTextures(LPCSTR dir_path, boolean replace) { - DBG_INFO(80, L"-----\n"); - DBG_INFO(80, L"path: %s\n", stdstr(dir_path).ToUTF16().c_str()); + DBG_INFO(80, L"-----\n"); + DBG_INFO(80, L"path: %s\n", stdstr(dir_path).ToUTF16().c_str()); - CPath TextureDir(dir_path,""); + CPath TextureDir(dir_path, ""); - /* find it on disk */ - if (!TextureDir.DirectoryExists()) - { - INFO(80, L"Error: path not found!\n"); - return 0; - } - - /* recursive read into sub-directory */ - TextureDir.SetNameExtension("*.*"); - if (TextureDir.FindFirst(_A_SUBDIR)) - { - do - { - loadHiResTextures(TextureDir, replace); - } while (TextureDir.FindNext()); - } - - TextureDir.SetNameExtension("*.*"); - if (TextureDir.FindFirst()) - { - do - { - if (KBHIT(0x1B)) { - _abortLoad = 1; - if (_callback) (*_callback)(L"Aborted loading hiresolution texture!\n"); - INFO(80, L"Error: aborted loading hiresolution texture!\n"); - } - if (_abortLoad) break; - - DBG_INFO(80, L"-----\n"); - DBG_INFO(80, L"file: %ls\n", stdstr(TextureDir.GetNameExtension().c_str()).ToUTF16().c_str()); - - int width = 0, height = 0; - uint16 format = 0; - uint8 *tex = NULL; - int tmpwidth = 0, tmpheight = 0; - uint16 tmpformat = 0; - uint8 *tmptex= NULL; - int untiled_width = 0, untiled_height = 0; - uint16 destformat = 0; - - /* Rice hi-res textures: begin - */ - uint32 chksum = 0, fmt = 0, siz = 0, palchksum = 0; - char *pfname = NULL, fname[MAX_PATH]; - std::string ident; - FILE *fp = NULL; - - wcstombs(fname, _ident.c_str(), MAX_PATH); - /* XXX case sensitivity fiasco! - * files must use _a, _rgb, _all, _allciByRGBA, _ciByRGBA, _ci - * and file extensions must be in lower case letters! */ -#ifdef _WIN32 - { - unsigned int i; - for (i = 0; i < strlen(fname); i++) fname[i] = (char)tolower(fname[i]); - } -#endif - ident.assign(fname); - - /* read in Rice's file naming convention */ - #define CRCFMTSIZ_LEN 13 - #define PALCRC_LEN 9 - wcstombs(fname, stdstr(TextureDir.GetNameExtension()).ToUTF16().c_str(), MAX_PATH); - /* XXX case sensitivity fiasco! - * files must use _a, _rgb, _all, _allciByRGBA, _ciByRGBA, _ci - * and file extensions must be in lower case letters! */ -#ifdef _WIN32 - { - unsigned int i; - for (i = 0; i < strlen(fname); i++) fname[i] = (char)tolower(fname[i]); - } -#endif - pfname = fname + strlen(fname) - 4; - if (!(pfname == strstr(fname, ".png") || - pfname == strstr(fname, ".bmp") || - pfname == strstr(fname, ".dds"))) - { - #if !DEBUG - INFO(80, L"-----\n"); - INFO(80, L"path: %ls\n", stdstr(dir_path).ToUTF16().c_str()); - INFO(80, L"file: %ls\n", TextureDir.GetNameExtension().ToUTF16().c_str()); - #endif - INFO(80, L"Error: not png or bmp or dds!\n"); - continue; - } - pfname = strstr(fname, ident.c_str()); - if (pfname != fname) pfname = 0; - if (pfname) { - if (sscanf(pfname + ident.size(), "#%08X#%01X#%01X#%08X", &chksum, &fmt, &siz, &palchksum) == 4) - pfname += (ident.size() + CRCFMTSIZ_LEN + PALCRC_LEN); - else if (sscanf(pfname + ident.size(), "#%08X#%01X#%01X", &chksum, &fmt, &siz) == 3) - pfname += (ident.size() + CRCFMTSIZ_LEN); - else - pfname = 0; - } - if (!pfname) { - #if !DEBUG - INFO(80, L"-----\n"); - INFO(80, L"path: %ls\n", stdstr(dir_path).ToUTF16().c_str()); - INFO(80, L"file: %ls\n", TextureDir.GetNameExtension().ToUTF16().c_str()); - #endif - INFO(80, L"Error: not Rice texture naming convention!\n"); - continue; - } - if (!chksum) { - #if !DEBUG - INFO(80, L"-----\n"); - INFO(80, L"path: %ls\n", stdstr(dir_path).ToUTF16().c_str()); - INFO(80, L"file: %ls\n", TextureDir.GetNameExtension().ToUTF16().c_str()); - #endif - INFO(80, L"Error: crc32 = 0!\n"); - continue; - } - - /* check if we already have it in hires texture cache */ - if (!replace) { - uint64 chksum64 = (uint64)palchksum; - chksum64 <<= 32; - chksum64 |= (uint64)chksum; - if (TxCache::is_cached(chksum64)) { - #if !DEBUG - INFO(80, L"-----\n"); - INFO(80, L"path: %ls\n", stdstr(dir_path).ToUTF16().c_str()); - INFO(80, L"file: %ls\n", TextureDir.GetNameExtension().ToUTF16().c_str()); - #endif - INFO(80, L"Error: already cached! duplicate texture!\n"); - continue; - } - } - - DBG_INFO(80, L"rom: %ls chksum:%08X %08X fmt:%x size:%x\n", _ident.c_str(), chksum, palchksum, fmt, siz); - - /* Deal with the wackiness some texture packs utilize Rice format. - * Read in the following order: _a.* + _rgb.*, _all.png _ciByRGBA.png, - * _allciByRGBA.png, and _ci.bmp. PNG are prefered over BMP. - * - * For some reason there are texture packs that include them all. Some - * even have RGB textures named as _all.* and ARGB textures named as - * _rgb.*... Someone pleeeez write a GOOD guideline for the texture - * designers!!! - * - * We allow hires textures to have higher bpp than the N64 originals. - */ - /* N64 formats - * Format: 0 - RGBA, 1 - YUV, 2 - CI, 3 - IA, 4 - I - * Size: 0 - 4bit, 1 - 8bit, 2 - 16bit, 3 - 32 bit - */ - - /* - * read in _rgb.* and _a.* - */ - if (pfname == strstr(fname, "_rgb.") || pfname == strstr(fname, "_a.")) { - strcpy(pfname, "_rgb.png"); - CPath TargetFile(dir_path,fname); - if (!TargetFile.Exists()) - { - strcpy(pfname, "_rgb.bmp"); - TargetFile = CPath(dir_path,fname); - if (!TargetFile.Exists()) - { - #if !DEBUG - INFO(80, L"-----\n"); - INFO(80, L"path: %ls\n", stdstr(dir_path).ToUTF16().c_str()); - INFO(80, L"file: %ls\n", TextureDir.GetNameExtension().ToUTF16().c_str()); - #endif - INFO(80, L"Error: missing _rgb.*! _a.* must be paired with _rgb.*!\n"); - continue; - } - } - /* _a.png */ - strcpy(pfname, "_a.png"); - TargetFile = CPath(dir_path,fname); - if ((fp = fopen(TargetFile, "rb")) != NULL) { - tmptex = _txImage->readPNG(fp, &tmpwidth, &tmpheight, &tmpformat); - fclose(fp); - } - if (!tmptex) { - /* _a.bmp */ - strcpy(pfname, "_a.bmp"); - TargetFile = CPath(dir_path,fname); - if ((fp = fopen(TargetFile, "rb")) != NULL) { - tmptex = _txImage->readBMP(fp, &tmpwidth, &tmpheight, &tmpformat); - fclose(fp); - } - } - /* _rgb.png */ - strcpy(pfname, "_rgb.png"); - TargetFile = CPath(dir_path,fname); - if ((fp = fopen(TargetFile, "rb")) != NULL) { - tex = _txImage->readPNG(fp, &width, &height, &format); - fclose(fp); - } - if (!tex) { - /* _rgb.bmp */ - strcpy(pfname, "_rgb.bmp"); - TargetFile = CPath(dir_path,fname); - if ((fp = fopen(TargetFile, "rb")) != NULL) { - tex = _txImage->readBMP(fp, &width, &height, &format); - fclose(fp); - } - } - if (tmptex) { - /* check if _rgb.* and _a.* have matching size and format. */ - if (!tex || width != tmpwidth || height != tmpheight || - format != GR_TEXFMT_ARGB_8888 || tmpformat != GR_TEXFMT_ARGB_8888) { -#if !DEBUG - INFO(80, L"-----\n"); - INFO(80, L"path: %ls\n", stdstr(dir_path).ToUTF16().c_str()); - INFO(80, L"file: %ls\n", TextureDir.GetNameExtension().ToUTF16().c_str()); -#endif - if (!tex) { - INFO(80, L"Error: missing _rgb.*!\n"); - } else if (width != tmpwidth || height != tmpheight) { - INFO(80, L"Error: _rgb.* and _a.* have mismatched width or height!\n"); - } else if (format != GR_TEXFMT_ARGB_8888 || tmpformat != GR_TEXFMT_ARGB_8888) { - INFO(80, L"Error: _rgb.* or _a.* not in 32bit color!\n"); - } - if (tex) free(tex); - if (tmptex) free(tmptex); - tex = NULL; - tmptex = NULL; - continue; - } - } - /* make adjustments */ - if (tex) { - if (tmptex) { - /* merge (A)RGB and A comp */ - DBG_INFO(80, L"merge (A)RGB and A comp\n"); - int i; - for (i = 0; i < height * width; i++) { -#if 1 - /* use R comp for alpha. this is what Rice uses. sigh... */ - ((uint32*)tex)[i] &= 0x00ffffff; - ((uint32*)tex)[i] |= ((((uint32*)tmptex)[i] & 0x00ff0000) << 8); -#endif -#if 0 - /* use libpng style grayscale conversion */ - uint32 texel = ((uint32*)tmptex)[i]; - uint32 acomp = (((texel >> 16) & 0xff) * 6969 + - ((texel >> 8) & 0xff) * 23434 + - ((texel ) & 0xff) * 2365) / 32768; - ((uint32*)tex)[i] = (acomp << 24) | (((uint32*)tex)[i] & 0x00ffffff); -#endif -#if 0 - /* use the standard NTSC gray scale conversion */ - uint32 texel = ((uint32*)tmptex)[i]; - uint32 acomp = (((texel >> 16) & 0xff) * 299 + - ((texel >> 8) & 0xff) * 587 + - ((texel ) & 0xff) * 114) / 1000; - ((uint32*)tex)[i] = (acomp << 24) | (((uint32*)tex)[i] & 0x00ffffff); -#endif - } - free(tmptex); - tmptex = NULL; - } else { - /* clobber A comp. never a question of alpha. only RGB used. */ -#if !DEBUG - INFO(80, L"-----\n"); - INFO(80, L"path: %ls\n", stdstr(dir_path).ToUTF16().c_str()); - INFO(80, L"file: %ls\n", TextureDir.GetNameExtension().ToUTF16().c_str()); -#endif - INFO(80, L"Warning: missing _a.*! only using _rgb.*. treat as opaque texture.\n"); - int i; - for (i = 0; i < height * width; i++) { - ((uint32*)tex)[i] |= 0xff000000; - } - } - } - } else - - /* - * read in _all.png, _all.dds, _allciByRGBA.png, _allciByRGBA.dds - * _ciByRGBA.png, _ciByRGBA.dds, _ci.bmp - */ - if (pfname == strstr(fname, "_all.png") || - pfname == strstr(fname, "_all.dds") || -#ifdef _WIN32 - pfname == strstr(fname, "_allcibyrgba.png") || - pfname == strstr(fname, "_allcibyrgba.dds") || - pfname == strstr(fname, "_cibyrgba.png") || - pfname == strstr(fname, "_cibyrgba.dds") || -#else - pfname == strstr(fname, "_allciByRGBA.png") || - pfname == strstr(fname, "_allciByRGBA.dds") || - pfname == strstr(fname, "_ciByRGBA.png") || - pfname == strstr(fname, "_ciByRGBA.dds") || -#endif - pfname == strstr(fname, "_ci.bmp")) { - CPath TargetFile(dir_path,fname); - if ((fp = fopen(TargetFile, "rb")) != NULL) { - if (strstr(fname, ".png")) tex = _txImage->readPNG(fp, &width, &height, &format); - else if (strstr(fname, ".dds")) tex = _txImage->readDDS(fp, &width, &height, &format); - else tex = _txImage->readBMP(fp, &width, &height, &format); - fclose(fp); - } - /* XXX: auto-adjustment of dxt dds textures unsupported for now */ - if (tex && strstr(fname, ".dds")) { - const float aspectratio = (width > height) ? (float)width/(float)height : (float)height/(float)width; - if (!(aspectratio == 1.0 || - aspectratio == 2.0 || - aspectratio == 4.0 || - aspectratio == 8.0)) { - free(tex); - tex = NULL; -#if !DEBUG - INFO(80, L"-----\n"); - INFO(80, L"path: %ls\n", stdstr(dir_path).ToUTF16().c_str()); - INFO(80, L"file: %ls\n", TextureDir.GetNameExtension().ToUTF16().c_str()); -#endif - INFO(80, L"Error: W:H aspect ratio range not 8:1 - 1:8!\n"); - continue; - } - if (width != _txReSample->nextPow2(width) || - height != _txReSample->nextPow2(height)) { - free(tex); - tex = NULL; -#if !DEBUG - INFO(80, L"-----\n"); - INFO(80, L"path: %ls\n", stdstr(dir_path).ToUTF16().c_str()); - INFO(80, L"file: %ls\n", TextureDir.GetNameExtension().ToUTF16().c_str()); -#endif - INFO(80, L"Error: not power of 2 size!\n"); - continue; - } - } + /* find it on disk */ + if (!TextureDir.DirectoryExists()) + { + INFO(80, L"Error: path not found!\n"); + return 0; } - /* if we do not have a texture at this point we are screwed */ - if (!tex) { -#if !DEBUG - INFO(80, L"-----\n"); - INFO(80, L"path: %ls\n", stdstr(dir_path).ToUTF16().c_str()); - INFO(80, L"file: %ls\n", TextureDir.GetNameExtension().ToUTF16().c_str()); -#endif - INFO(80, L"Error: load failed!\n"); - continue; - } - DBG_INFO(80, L"read in as %d x %d gfmt:%x\n", tmpwidth, tmpheight, tmpformat); - - /* check if size and format are OK */ - if (!(format == GR_TEXFMT_ARGB_8888 || - format == GR_TEXFMT_P_8 || - format == GR_TEXFMT_ARGB_CMP_DXT1 || - format == GR_TEXFMT_ARGB_CMP_DXT3 || - format == GR_TEXFMT_ARGB_CMP_DXT5) || - (width * height) < 4) { /* TxQuantize requirement: width * height must be 4 or larger. */ - free(tex); - tex = NULL; -#if !DEBUG - INFO(80, L"-----\n"); - INFO(80, L"path: %ls\n", stdstr(dir_path).ToUTF16().c_str()); - INFO(80, L"file: %ls\n", TextureDir.GetNameExtension().ToUTF16().c_str()); -#endif - INFO(80, L"Error: not width * height > 4 or 8bit palette color or 32bpp or dxt1 or dxt3 or dxt5!\n"); - continue; + /* recursive read into sub-directory */ + TextureDir.SetNameExtension("*.*"); + if (TextureDir.FindFirst(_A_SUBDIR)) + { + do + { + loadHiResTextures(TextureDir, replace); + } while (TextureDir.FindNext()); } - /* analyze and determine best format to quantize */ - if (format == GR_TEXFMT_ARGB_8888) { - int i; - int alphabits = 0; - int fullalpha = 0; - boolean intensity = 1; - - if (!(_options & LET_TEXARTISTS_FLY)) { - /* HACK ALERT! */ - /* Account for Rice's weirdness with fmt:0 siz:2 textures. - * Although the conditions are relaxed with other formats, - * the D3D RGBA5551 surface is used for this format in certain - * cases. See Nintemod's SuperMario64 life gauge and power - * meter. The same goes for fmt:2 textures. See Mollymutt's - * PaperMario text. */ - if ((fmt == 0 && siz == 2) || fmt == 2) { - DBG_INFO(80, L"Remove black, white, etc borders along the alpha edges.\n"); - /* round A comp */ - for (i = 0; i < height * width; i++) { - uint32 texel = ((uint32*)tex)[i]; - ((uint32*)tex)[i] = ((texel & 0xff000000) == 0xff000000 ? 0xff000000 : 0) | - (texel & 0x00ffffff); - } - /* Substitute texel color with the average of the surrounding - * opaque texels. This removes borders regardless of hardware - * texture filtering (bilinear, etc). */ - int j; - for (i = 0; i < height; i++) { - for (j = 0; j < width; j++) { - uint32 texel = ((uint32*)tex)[i * width + j]; - if ((texel & 0xff000000) != 0xff000000) { - uint32 tmptexel[8]; - uint32 k, numtexel, r, g, b; - numtexel = r = g = b = 0; - memset(&tmptexel, 0, sizeof(tmptexel)); - if (i > 0) { - tmptexel[0] = ((uint32*)tex)[(i - 1) * width + j]; /* north */ - if (j > 0) tmptexel[1] = ((uint32*)tex)[(i - 1) * width + j - 1]; /* north-west */ - if (j < width - 1) tmptexel[2] = ((uint32*)tex)[(i - 1) * width + j + 1]; /* north-east */ - } - if (i < height - 1) { - tmptexel[3] = ((uint32*)tex)[(i + 1) * width + j]; /* south */ - if (j > 0) tmptexel[4] = ((uint32*)tex)[(i + 1) * width + j - 1]; /* south-west */ - if (j < width - 1) tmptexel[5] = ((uint32*)tex)[(i + 1) * width + j + 1]; /* south-east */ - } - if (j > 0) tmptexel[6] = ((uint32*)tex)[i * width + j - 1]; /* west */ - if (j < width - 1) tmptexel[7] = ((uint32*)tex)[i * width + j + 1]; /* east */ - for (k = 0; k < 8; k++) { - if ((tmptexel[k] & 0xff000000) == 0xff000000) { - r += ((tmptexel[k] & 0x00ff0000) >> 16); - g += ((tmptexel[k] & 0x0000ff00) >> 8); - b += ((tmptexel[k] & 0x000000ff) ); - numtexel++; - } - } - if (numtexel) { - ((uint32*)tex)[i * width + j] = ((r / numtexel) << 16) | - ((g / numtexel) << 8) | - ((b / numtexel) ); - } else { - ((uint32*)tex)[i * width + j] = texel & 0x00ffffff; - } - } + TextureDir.SetNameExtension("*.*"); + if (TextureDir.FindFirst()) + { + do + { + if (KBHIT(0x1B)) { + _abortLoad = 1; + if (_callback) (*_callback)(L"Aborted loading hiresolution texture!\n"); + INFO(80, L"Error: aborted loading hiresolution texture!\n"); } - } - } - } + if (_abortLoad) break; - /* simple analysis of texture */ - for (i = 0; i < height * width; i++) { - uint32 texel = ((uint32*)tex)[i]; - if (alphabits != 8) { -#if AGGRESSIVE_QUANTIZATION - if ((texel & 0xff000000) < 0x00000003) { - alphabits = 1; - fullalpha++; - } else if ((texel & 0xff000000) < 0xfe000000) { - alphabits = 8; - } + DBG_INFO(80, L"-----\n"); + DBG_INFO(80, L"file: %ls\n", stdstr(TextureDir.GetNameExtension().c_str()).ToUTF16().c_str()); + + int width = 0, height = 0; + uint16 format = 0; + uint8 *tex = NULL; + int tmpwidth = 0, tmpheight = 0; + uint16 tmpformat = 0; + uint8 *tmptex = NULL; + int untiled_width = 0, untiled_height = 0; + uint16 destformat = 0; + + /* Rice hi-res textures: begin + */ + uint32 chksum = 0, fmt = 0, siz = 0, palchksum = 0; + char *pfname = NULL, fname[MAX_PATH]; + std::string ident; + FILE *fp = NULL; + + wcstombs(fname, _ident.c_str(), MAX_PATH); + /* XXX case sensitivity fiasco! + * files must use _a, _rgb, _all, _allciByRGBA, _ciByRGBA, _ci + * and file extensions must be in lower case letters! */ +#ifdef _WIN32 + { + unsigned int i; + for (i = 0; i < strlen(fname); i++) fname[i] = (char)tolower(fname[i]); + } +#endif + ident.assign(fname); + + /* read in Rice's file naming convention */ +#define CRCFMTSIZ_LEN 13 +#define PALCRC_LEN 9 + wcstombs(fname, stdstr(TextureDir.GetNameExtension()).ToUTF16().c_str(), MAX_PATH); + /* XXX case sensitivity fiasco! + * files must use _a, _rgb, _all, _allciByRGBA, _ciByRGBA, _ci + * and file extensions must be in lower case letters! */ +#ifdef _WIN32 + { + unsigned int i; + for (i = 0; i < strlen(fname); i++) fname[i] = (char)tolower(fname[i]); + } +#endif + pfname = fname + strlen(fname) - 4; + if (!(pfname == strstr(fname, ".png") || + pfname == strstr(fname, ".bmp") || + pfname == strstr(fname, ".dds"))) + { +#if !DEBUG + INFO(80, L"-----\n"); + INFO(80, L"path: %ls\n", stdstr(dir_path).ToUTF16().c_str()); + INFO(80, L"file: %ls\n", TextureDir.GetNameExtension().ToUTF16().c_str()); +#endif + INFO(80, L"Error: not png or bmp or dds!\n"); + continue; + } + pfname = strstr(fname, ident.c_str()); + if (pfname != fname) pfname = 0; + if (pfname) { + if (sscanf(pfname + ident.size(), "#%08X#%01X#%01X#%08X", &chksum, &fmt, &siz, &palchksum) == 4) + pfname += (ident.size() + CRCFMTSIZ_LEN + PALCRC_LEN); + else if (sscanf(pfname + ident.size(), "#%08X#%01X#%01X", &chksum, &fmt, &siz) == 3) + pfname += (ident.size() + CRCFMTSIZ_LEN); + else + pfname = 0; + } + if (!pfname) { +#if !DEBUG + INFO(80, L"-----\n"); + INFO(80, L"path: %ls\n", stdstr(dir_path).ToUTF16().c_str()); + INFO(80, L"file: %ls\n", TextureDir.GetNameExtension().ToUTF16().c_str()); +#endif + INFO(80, L"Error: not Rice texture naming convention!\n"); + continue; + } + if (!chksum) { +#if !DEBUG + INFO(80, L"-----\n"); + INFO(80, L"path: %ls\n", stdstr(dir_path).ToUTF16().c_str()); + INFO(80, L"file: %ls\n", TextureDir.GetNameExtension().ToUTF16().c_str()); +#endif + INFO(80, L"Error: crc32 = 0!\n"); + continue; + } + + /* check if we already have it in hires texture cache */ + if (!replace) { + uint64 chksum64 = (uint64)palchksum; + chksum64 <<= 32; + chksum64 |= (uint64)chksum; + if (TxCache::is_cached(chksum64)) { +#if !DEBUG + INFO(80, L"-----\n"); + INFO(80, L"path: %ls\n", stdstr(dir_path).ToUTF16().c_str()); + INFO(80, L"file: %ls\n", TextureDir.GetNameExtension().ToUTF16().c_str()); +#endif + INFO(80, L"Error: already cached! duplicate texture!\n"); + continue; + } + } + + DBG_INFO(80, L"rom: %ls chksum:%08X %08X fmt:%x size:%x\n", _ident.c_str(), chksum, palchksum, fmt, siz); + + /* Deal with the wackiness some texture packs utilize Rice format. + * Read in the following order: _a.* + _rgb.*, _all.png _ciByRGBA.png, + * _allciByRGBA.png, and _ci.bmp. PNG are prefered over BMP. + * + * For some reason there are texture packs that include them all. Some + * even have RGB textures named as _all.* and ARGB textures named as + * _rgb.*... Someone pleeeez write a GOOD guideline for the texture + * designers!!! + * + * We allow hires textures to have higher bpp than the N64 originals. + */ + /* N64 formats + * Format: 0 - RGBA, 1 - YUV, 2 - CI, 3 - IA, 4 - I + * Size: 0 - 4bit, 1 - 8bit, 2 - 16bit, 3 - 32 bit + */ + + /* + * read in _rgb.* and _a.* + */ + if (pfname == strstr(fname, "_rgb.") || pfname == strstr(fname, "_a.")) { + strcpy(pfname, "_rgb.png"); + CPath TargetFile(dir_path, fname); + if (!TargetFile.Exists()) + { + strcpy(pfname, "_rgb.bmp"); + TargetFile = CPath(dir_path, fname); + if (!TargetFile.Exists()) + { +#if !DEBUG + INFO(80, L"-----\n"); + INFO(80, L"path: %ls\n", stdstr(dir_path).ToUTF16().c_str()); + INFO(80, L"file: %ls\n", TextureDir.GetNameExtension().ToUTF16().c_str()); +#endif + INFO(80, L"Error: missing _rgb.*! _a.* must be paired with _rgb.*!\n"); + continue; + } + } + /* _a.png */ + strcpy(pfname, "_a.png"); + TargetFile = CPath(dir_path, fname); + if ((fp = fopen(TargetFile, "rb")) != NULL) { + tmptex = _txImage->readPNG(fp, &tmpwidth, &tmpheight, &tmpformat); + fclose(fp); + } + if (!tmptex) { + /* _a.bmp */ + strcpy(pfname, "_a.bmp"); + TargetFile = CPath(dir_path, fname); + if ((fp = fopen(TargetFile, "rb")) != NULL) { + tmptex = _txImage->readBMP(fp, &tmpwidth, &tmpheight, &tmpformat); + fclose(fp); + } + } + /* _rgb.png */ + strcpy(pfname, "_rgb.png"); + TargetFile = CPath(dir_path, fname); + if ((fp = fopen(TargetFile, "rb")) != NULL) { + tex = _txImage->readPNG(fp, &width, &height, &format); + fclose(fp); + } + if (!tex) { + /* _rgb.bmp */ + strcpy(pfname, "_rgb.bmp"); + TargetFile = CPath(dir_path, fname); + if ((fp = fopen(TargetFile, "rb")) != NULL) { + tex = _txImage->readBMP(fp, &width, &height, &format); + fclose(fp); + } + } + if (tmptex) { + /* check if _rgb.* and _a.* have matching size and format. */ + if (!tex || width != tmpwidth || height != tmpheight || + format != GR_TEXFMT_ARGB_8888 || tmpformat != GR_TEXFMT_ARGB_8888) { +#if !DEBUG + INFO(80, L"-----\n"); + INFO(80, L"path: %ls\n", stdstr(dir_path).ToUTF16().c_str()); + INFO(80, L"file: %ls\n", TextureDir.GetNameExtension().ToUTF16().c_str()); +#endif + if (!tex) { + INFO(80, L"Error: missing _rgb.*!\n"); + } + else if (width != tmpwidth || height != tmpheight) { + INFO(80, L"Error: _rgb.* and _a.* have mismatched width or height!\n"); + } + else if (format != GR_TEXFMT_ARGB_8888 || tmpformat != GR_TEXFMT_ARGB_8888) { + INFO(80, L"Error: _rgb.* or _a.* not in 32bit color!\n"); + } + if (tex) free(tex); + if (tmptex) free(tmptex); + tex = NULL; + tmptex = NULL; + continue; + } + } + /* make adjustments */ + if (tex) { + if (tmptex) { + /* merge (A)RGB and A comp */ + DBG_INFO(80, L"merge (A)RGB and A comp\n"); + int i; + for (i = 0; i < height * width; i++) { +#if 1 + /* use R comp for alpha. this is what Rice uses. sigh... */ + ((uint32*)tex)[i] &= 0x00ffffff; + ((uint32*)tex)[i] |= ((((uint32*)tmptex)[i] & 0x00ff0000) << 8); +#endif +#if 0 + /* use libpng style grayscale conversion */ + uint32 texel = ((uint32*)tmptex)[i]; + uint32 acomp = (((texel >> 16) & 0xff) * 6969 + + ((texel >> 8) & 0xff) * 23434 + + ((texel ) & 0xff) * 2365) / 32768; + ((uint32*)tex)[i] = (acomp << 24) | (((uint32*)tex)[i] & 0x00ffffff); +#endif +#if 0 + /* use the standard NTSC gray scale conversion */ + uint32 texel = ((uint32*)tmptex)[i]; + uint32 acomp = (((texel >> 16) & 0xff) * 299 + + ((texel >> 8) & 0xff) * 587 + + ((texel ) & 0xff) * 114) / 1000; + ((uint32*)tex)[i] = (acomp << 24) | (((uint32*)tex)[i] & 0x00ffffff); +#endif + } + free(tmptex); + tmptex = NULL; + } + else { + /* clobber A comp. never a question of alpha. only RGB used. */ +#if !DEBUG + INFO(80, L"-----\n"); + INFO(80, L"path: %ls\n", stdstr(dir_path).ToUTF16().c_str()); + INFO(80, L"file: %ls\n", TextureDir.GetNameExtension().ToUTF16().c_str()); +#endif + INFO(80, L"Warning: missing _a.*! only using _rgb.*. treat as opaque texture.\n"); + int i; + for (i = 0; i < height * width; i++) { + ((uint32*)tex)[i] |= 0xff000000; + } + } + } + } + else + + /* + * read in _all.png, _all.dds, _allciByRGBA.png, _allciByRGBA.dds + * _ciByRGBA.png, _ciByRGBA.dds, _ci.bmp + */ + if (pfname == strstr(fname, "_all.png") || + pfname == strstr(fname, "_all.dds") || +#ifdef _WIN32 + pfname == strstr(fname, "_allcibyrgba.png") || + pfname == strstr(fname, "_allcibyrgba.dds") || + pfname == strstr(fname, "_cibyrgba.png") || + pfname == strstr(fname, "_cibyrgba.dds") || #else - if ((texel & 0xff000000) == 0x00000000) { - alphabits = 1; - fullalpha++; - } else if ((texel & 0xff000000) != 0xff000000) { - alphabits = 8; - } + pfname == strstr(fname, "_allciByRGBA.png") || + pfname == strstr(fname, "_allciByRGBA.dds") || + pfname == strstr(fname, "_ciByRGBA.png") || + pfname == strstr(fname, "_ciByRGBA.dds") || #endif - } - if (intensity) { - int rcomp = (texel >> 16) & 0xff; - int gcomp = (texel >> 8) & 0xff; - int bcomp = (texel ) & 0xff; + pfname == strstr(fname, "_ci.bmp")) { + CPath TargetFile(dir_path, fname); + if ((fp = fopen(TargetFile, "rb")) != NULL) { + if (strstr(fname, ".png")) tex = _txImage->readPNG(fp, &width, &height, &format); + else if (strstr(fname, ".dds")) tex = _txImage->readDDS(fp, &width, &height, &format); + else tex = _txImage->readBMP(fp, &width, &height, &format); + fclose(fp); + } + /* XXX: auto-adjustment of dxt dds textures unsupported for now */ + if (tex && strstr(fname, ".dds")) { + const float aspectratio = (width > height) ? (float)width / (float)height : (float)height / (float)width; + if (!(aspectratio == 1.0 || + aspectratio == 2.0 || + aspectratio == 4.0 || + aspectratio == 8.0)) { + free(tex); + tex = NULL; +#if !DEBUG + INFO(80, L"-----\n"); + INFO(80, L"path: %ls\n", stdstr(dir_path).ToUTF16().c_str()); + INFO(80, L"file: %ls\n", TextureDir.GetNameExtension().ToUTF16().c_str()); +#endif + INFO(80, L"Error: W:H aspect ratio range not 8:1 - 1:8!\n"); + continue; + } + if (width != _txReSample->nextPow2(width) || + height != _txReSample->nextPow2(height)) { + free(tex); + tex = NULL; +#if !DEBUG + INFO(80, L"-----\n"); + INFO(80, L"path: %ls\n", stdstr(dir_path).ToUTF16().c_str()); + INFO(80, L"file: %ls\n", TextureDir.GetNameExtension().ToUTF16().c_str()); +#endif + INFO(80, L"Error: not power of 2 size!\n"); + continue; + } + } + } + + /* if we do not have a texture at this point we are screwed */ + if (!tex) { +#if !DEBUG + INFO(80, L"-----\n"); + INFO(80, L"path: %ls\n", stdstr(dir_path).ToUTF16().c_str()); + INFO(80, L"file: %ls\n", TextureDir.GetNameExtension().ToUTF16().c_str()); +#endif + INFO(80, L"Error: load failed!\n"); + continue; + } + DBG_INFO(80, L"read in as %d x %d gfmt:%x\n", tmpwidth, tmpheight, tmpformat); + + /* check if size and format are OK */ + if (!(format == GR_TEXFMT_ARGB_8888 || + format == GR_TEXFMT_P_8 || + format == GR_TEXFMT_ARGB_CMP_DXT1 || + format == GR_TEXFMT_ARGB_CMP_DXT3 || + format == GR_TEXFMT_ARGB_CMP_DXT5) || + (width * height) < 4) { /* TxQuantize requirement: width * height must be 4 or larger. */ + free(tex); + tex = NULL; +#if !DEBUG + INFO(80, L"-----\n"); + INFO(80, L"path: %ls\n", stdstr(dir_path).ToUTF16().c_str()); + INFO(80, L"file: %ls\n", TextureDir.GetNameExtension().ToUTF16().c_str()); +#endif + INFO(80, L"Error: not width * height > 4 or 8bit palette color or 32bpp or dxt1 or dxt3 or dxt5!\n"); + continue; + } + + /* analyze and determine best format to quantize */ + if (format == GR_TEXFMT_ARGB_8888) { + int i; + int alphabits = 0; + int fullalpha = 0; + boolean intensity = 1; + + if (!(_options & LET_TEXARTISTS_FLY)) { + /* HACK ALERT! */ + /* Account for Rice's weirdness with fmt:0 siz:2 textures. + * Although the conditions are relaxed with other formats, + * the D3D RGBA5551 surface is used for this format in certain + * cases. See Nintemod's SuperMario64 life gauge and power + * meter. The same goes for fmt:2 textures. See Mollymutt's + * PaperMario text. */ + if ((fmt == 0 && siz == 2) || fmt == 2) { + DBG_INFO(80, L"Remove black, white, etc borders along the alpha edges.\n"); + /* round A comp */ + for (i = 0; i < height * width; i++) { + uint32 texel = ((uint32*)tex)[i]; + ((uint32*)tex)[i] = ((texel & 0xff000000) == 0xff000000 ? 0xff000000 : 0) | + (texel & 0x00ffffff); + } + /* Substitute texel color with the average of the surrounding + * opaque texels. This removes borders regardless of hardware + * texture filtering (bilinear, etc). */ + int j; + for (i = 0; i < height; i++) { + for (j = 0; j < width; j++) { + uint32 texel = ((uint32*)tex)[i * width + j]; + if ((texel & 0xff000000) != 0xff000000) { + uint32 tmptexel[8]; + uint32 k, numtexel, r, g, b; + numtexel = r = g = b = 0; + memset(&tmptexel, 0, sizeof(tmptexel)); + if (i > 0) { + tmptexel[0] = ((uint32*)tex)[(i - 1) * width + j]; /* north */ + if (j > 0) tmptexel[1] = ((uint32*)tex)[(i - 1) * width + j - 1]; /* north-west */ + if (j < width - 1) tmptexel[2] = ((uint32*)tex)[(i - 1) * width + j + 1]; /* north-east */ + } + if (i < height - 1) { + tmptexel[3] = ((uint32*)tex)[(i + 1) * width + j]; /* south */ + if (j > 0) tmptexel[4] = ((uint32*)tex)[(i + 1) * width + j - 1]; /* south-west */ + if (j < width - 1) tmptexel[5] = ((uint32*)tex)[(i + 1) * width + j + 1]; /* south-east */ + } + if (j > 0) tmptexel[6] = ((uint32*)tex)[i * width + j - 1]; /* west */ + if (j < width - 1) tmptexel[7] = ((uint32*)tex)[i * width + j + 1]; /* east */ + for (k = 0; k < 8; k++) { + if ((tmptexel[k] & 0xff000000) == 0xff000000) { + r += ((tmptexel[k] & 0x00ff0000) >> 16); + g += ((tmptexel[k] & 0x0000ff00) >> 8); + b += ((tmptexel[k] & 0x000000ff)); + numtexel++; + } + } + if (numtexel) { + ((uint32*)tex)[i * width + j] = ((r / numtexel) << 16) | + ((g / numtexel) << 8) | + ((b / numtexel)); + } + else { + ((uint32*)tex)[i * width + j] = texel & 0x00ffffff; + } + } + } + } + } + } + + /* simple analysis of texture */ + for (i = 0; i < height * width; i++) { + uint32 texel = ((uint32*)tex)[i]; + if (alphabits != 8) { #if AGGRESSIVE_QUANTIZATION - if (abs(rcomp - gcomp) > 8 || abs(rcomp - bcomp) > 8 || abs(gcomp - bcomp) > 8) intensity = 0; + if ((texel & 0xff000000) < 0x00000003) { + alphabits = 1; + fullalpha++; + } + else if ((texel & 0xff000000) < 0xfe000000) { + alphabits = 8; + } #else - if (rcomp != gcomp || rcomp != bcomp || gcomp != bcomp) intensity = 0; + if ((texel & 0xff000000) == 0x00000000) { + alphabits = 1; + fullalpha++; + } + else if ((texel & 0xff000000) != 0xff000000) { + alphabits = 8; + } #endif - } - if (!intensity && alphabits == 8) break; - } - DBG_INFO(80, L"required alpha bits:%d zero acomp texels:%d rgb as intensity:%d\n", alphabits, fullalpha, intensity); + } + if (intensity) { + int rcomp = (texel >> 16) & 0xff; + int gcomp = (texel >> 8) & 0xff; + int bcomp = (texel)& 0xff; +#if AGGRESSIVE_QUANTIZATION + if (abs(rcomp - gcomp) > 8 || abs(rcomp - bcomp) > 8 || abs(gcomp - bcomp) > 8) intensity = 0; +#else + if (rcomp != gcomp || rcomp != bcomp || gcomp != bcomp) intensity = 0; +#endif + } + if (!intensity && alphabits == 8) break; + } + DBG_INFO(80, L"required alpha bits:%d zero acomp texels:%d rgb as intensity:%d\n", alphabits, fullalpha, intensity); - /* preparations based on above analysis */ + /* preparations based on above analysis */ #if !REDUCE_TEXTURE_FOOTPRINT - if (_maxbpp < 32 || _options & (FORCE16BPP_HIRESTEX|COMPRESSION_MASK)) { + if (_maxbpp < 32 || _options & (FORCE16BPP_HIRESTEX | COMPRESSION_MASK)) { #endif - if (alphabits == 0) destformat = GR_TEXFMT_RGB_565; - else if (alphabits == 1) destformat = GR_TEXFMT_ARGB_1555; - else destformat = GR_TEXFMT_ARGB_8888; + if (alphabits == 0) destformat = GR_TEXFMT_RGB_565; + else if (alphabits == 1) destformat = GR_TEXFMT_ARGB_1555; + else destformat = GR_TEXFMT_ARGB_8888; #if !REDUCE_TEXTURE_FOOTPRINT - } else { - destformat = GR_TEXFMT_ARGB_8888; - } + } + else { + destformat = GR_TEXFMT_ARGB_8888; + } #endif - if (fmt == 4 && alphabits == 0) { - destformat = GR_TEXFMT_ARGB_8888; - /* Rice I format; I = (R + G + B) / 3 */ - for (i = 0; i < height * width; i++) { - uint32 texel = ((uint32*)tex)[i]; - uint32 icomp = (((texel >> 16) & 0xff) + - ((texel >> 8) & 0xff) + - ((texel ) & 0xff)) / 3; - ((uint32*)tex)[i] = (icomp << 24) | (texel & 0x00ffffff); - } - } - if (intensity) { - if (alphabits == 0) { - if (fmt == 4) destformat = GR_TEXFMT_ALPHA_8; - else destformat = GR_TEXFMT_INTENSITY_8; - } else { - destformat = GR_TEXFMT_ALPHA_INTENSITY_88; - } - } + if (fmt == 4 && alphabits == 0) { + destformat = GR_TEXFMT_ARGB_8888; + /* Rice I format; I = (R + G + B) / 3 */ + for (i = 0; i < height * width; i++) { + uint32 texel = ((uint32*)tex)[i]; + uint32 icomp = (((texel >> 16) & 0xff) + + ((texel >> 8) & 0xff) + + ((texel)& 0xff)) / 3; + ((uint32*)tex)[i] = (icomp << 24) | (texel & 0x00ffffff); + } + } + if (intensity) { + if (alphabits == 0) { + if (fmt == 4) destformat = GR_TEXFMT_ALPHA_8; + else destformat = GR_TEXFMT_INTENSITY_8; + } + else { + destformat = GR_TEXFMT_ALPHA_INTENSITY_88; + } + } - DBG_INFO(80, L"best gfmt:%x\n", destformat); - } - /* - * Rice hi-res textures: end */ - - - /* XXX: only ARGB8888 for now. comeback to this later... */ - if (format == GR_TEXFMT_ARGB_8888) { + DBG_INFO(80, L"best gfmt:%x\n", destformat); + } + /* + * Rice hi-res textures: end */ + /* XXX: only ARGB8888 for now. comeback to this later... */ + if (format == GR_TEXFMT_ARGB_8888) { #if TEXTURE_TILING - /* Glide64 style texture tiling */ - /* NOTE: narrow wide textures can be tiled into 256x256 size textures */ + /* Glide64 style texture tiling */ + /* NOTE: narrow wide textures can be tiled into 256x256 size textures */ - /* adjust texture size to allow tiling for V1, Rush, V2, Banshee, V3 */ - /* NOTE: we skip this for palette textures that need minification - * becasue it will look ugly. */ + /* adjust texture size to allow tiling for V1, Rush, V2, Banshee, V3 */ + /* NOTE: we skip this for palette textures that need minification + * becasue it will look ugly. */ - /* minification */ + /* minification */ { - int ratio = 1; + int ratio = 1; - /* minification to enable glide64 style texture tiling */ - /* determine the minification ratio to tile the texture into 256x256 size */ - if ((_options & TILE_HIRESTEX) && _maxwidth >= 256 && _maxheight >= 256) { - DBG_INFO(80, L"determine minification ratio to tile\n"); - tmpwidth = width; - tmpheight = height; - if (height > 256) { - ratio = ((height - 1) >> 8) + 1; - tmpwidth = width / ratio; - tmpheight = height / ratio; - DBG_INFO(80, L"height > 256, minification ratio:%d %d x %d -> %d x %d\n", - ratio, width, height, tmpwidth, tmpheight); + /* minification to enable glide64 style texture tiling */ + /* determine the minification ratio to tile the texture into 256x256 size */ + if ((_options & TILE_HIRESTEX) && _maxwidth >= 256 && _maxheight >= 256) { + DBG_INFO(80, L"determine minification ratio to tile\n"); + tmpwidth = width; + tmpheight = height; + if (height > 256) { + ratio = ((height - 1) >> 8) + 1; + tmpwidth = width / ratio; + tmpheight = height / ratio; + DBG_INFO(80, L"height > 256, minification ratio:%d %d x %d -> %d x %d\n", + ratio, width, height, tmpwidth, tmpheight); + } + if (tmpwidth > 256 && (((tmpwidth - 1) >> 8) + 1) * tmpheight > 256) { + ratio *= ((((((tmpwidth - 1) >> 8) + 1) * tmpheight) - 1) >> 8) + 1; + DBG_INFO(80, L"width > 256, minification ratio:%d %d x %d -> %d x %d\n", + ratio, width, height, width / ratio, height / ratio); + } } - if (tmpwidth > 256 && (((tmpwidth - 1) >> 8) + 1) * tmpheight > 256) { - ratio *= ((((((tmpwidth - 1) >> 8) + 1) * tmpheight) - 1) >> 8) + 1; - DBG_INFO(80, L"width > 256, minification ratio:%d %d x %d -> %d x %d\n", - ratio, width, height, width / ratio, height / ratio); + else { + /* normal minification to fit max texture size */ + if (width > _maxwidth || height > _maxheight) { + DBG_INFO(80, L"determine minification ratio to fit max texture size\n"); + tmpwidth = width; + tmpheight = height; + while (tmpwidth > _maxwidth) { + tmpheight >>= 1; + tmpwidth >>= 1; + ratio <<= 1; + } + while (tmpheight > _maxheight) { + tmpheight >>= 1; + tmpwidth >>= 1; + ratio <<= 1; + } + DBG_INFO(80, L"minification ratio:%d %d x %d -> %d x %d\n", + ratio, width, height, tmpwidth, tmpheight); + } } - } else { - /* normal minification to fit max texture size */ - if (width > _maxwidth || height > _maxheight) { - DBG_INFO(80, L"determine minification ratio to fit max texture size\n"); - tmpwidth = width; - tmpheight = height; - while (tmpwidth > _maxwidth) { - tmpheight >>= 1; - tmpwidth >>= 1; - ratio <<= 1; - } - while (tmpheight > _maxheight) { - tmpheight >>= 1; - tmpwidth >>= 1; - ratio <<= 1; - } - DBG_INFO(80, L"minification ratio:%d %d x %d -> %d x %d\n", - ratio, width, height, tmpwidth, tmpheight); - } - } - if (ratio > 1) { - if (!_txReSample->minify(&tex, &width, &height, ratio)) { - free(tex); - tex = NULL; - DBG_INFO(80, L"Error: minification failed!\n"); - continue; + if (ratio > 1) { + if (!_txReSample->minify(&tex, &width, &height, ratio)) { + free(tex); + tex = NULL; + DBG_INFO(80, L"Error: minification failed!\n"); + continue; + } } - } } /* tiling */ if ((_options & TILE_HIRESTEX) && _maxwidth >= 256 && _maxheight >= 256) { - boolean usetile = 0; + boolean usetile = 0; - /* to tile or not to tile, that is the question */ - if (width > 256 && height <= 128 && (((width - 1) >> 8) + 1) * height <= 256) { + /* to tile or not to tile, that is the question */ + if (width > 256 && height <= 128 && (((width - 1) >> 8) + 1) * height <= 256) { + if (width > _maxwidth) usetile = 1; + else { + /* tile if the tiled texture memory footprint is smaller */ + int tilewidth = 256; + int tileheight = _txReSample->nextPow2((((width - 1) >> 8) + 1) * height); + tmpwidth = width; + tmpheight = height; - if (width > _maxwidth) usetile = 1; - else { - /* tile if the tiled texture memory footprint is smaller */ - int tilewidth = 256; - int tileheight = _txReSample->nextPow2((((width - 1) >> 8) + 1) * height); - tmpwidth = width; - tmpheight = height; + /* 3dfx Glide3 tmpheight, W:H aspect ratio range (8:1 - 1:8) */ + if (tilewidth > (tileheight << 3)) tileheight = tilewidth >> 3; - /* 3dfx Glide3 tmpheight, W:H aspect ratio range (8:1 - 1:8) */ - if (tilewidth > (tileheight << 3)) tileheight = tilewidth >> 3; + /* HACKALERT: see TxReSample::pow2(); */ + if (tmpwidth > 64) tmpwidth -= 4; + else if (tmpwidth > 16) tmpwidth -= 2; + else if (tmpwidth > 4) tmpwidth -= 1; - /* HACKALERT: see TxReSample::pow2(); */ - if (tmpwidth > 64) tmpwidth -= 4; - else if (tmpwidth > 16) tmpwidth -= 2; - else if (tmpwidth > 4) tmpwidth -= 1; + if (tmpheight > 64) tmpheight -= 4; + else if (tmpheight > 16) tmpheight -= 2; + else if (tmpheight > 4) tmpheight -= 1; - if (tmpheight > 64) tmpheight -= 4; - else if (tmpheight > 16) tmpheight -= 2; - else if (tmpheight > 4) tmpheight -= 1; + tmpwidth = _txReSample->nextPow2(tmpwidth); + tmpheight = _txReSample->nextPow2(tmpheight); - tmpwidth = _txReSample->nextPow2(tmpwidth); - tmpheight = _txReSample->nextPow2(tmpheight); - - /* 3dfx Glide3 tmpheight, W:H aspect ratio range (8:1 - 1:8) */ - if (tmpwidth > tmpheight) { - if (tmpwidth > (tmpheight << 3)) tmpheight = tmpwidth >> 3; - } else { - if (tmpheight > (tmpwidth << 3)) tmpwidth = tmpheight >> 3; - } - - usetile = (tilewidth * tileheight < tmpwidth * tmpheight); - } - - } - - /* tile it! do the actual tiling into 256x256 size */ - if (usetile) { - DBG_INFO(80, L"Glide64 style texture tiling\n"); - - int x, y, z, ratio, offset; - offset = 0; - ratio = ((width - 1) >> 8) + 1; - tmptex = (uint8 *)malloc(_txUtil->sizeofTx(256, height * ratio, format)); - if (tmptex) { - for (x = 0; x < ratio; x++) { - for (y = 0; y < height; y++) { - if (x < ratio - 1) { - memcpy(&tmptex[offset << 2], &tex[(x * 256 + y * width) << 2], 256 << 2); - } else { - for (z = 0; z < width - 256 * (ratio - 1); z++) { - ((uint32*)tmptex)[offset + z] = ((uint32*)tex)[x * 256 + y * width + z]; + /* 3dfx Glide3 tmpheight, W:H aspect ratio range (8:1 - 1:8) */ + if (tmpwidth > tmpheight) { + if (tmpwidth > (tmpheight << 3)) tmpheight = tmpwidth >> 3; } - for (; z < 256; z++) { - ((uint32*)tmptex)[offset + z] = ((uint32*)tmptex)[offset + z - 1]; + else { + if (tmpheight > (tmpwidth << 3)) tmpwidth = tmpheight >> 3; } - } - offset += 256; + + usetile = (tilewidth * tileheight < tmpwidth * tmpheight); + } + } + + /* tile it! do the actual tiling into 256x256 size */ + if (usetile) { + DBG_INFO(80, L"Glide64 style texture tiling\n"); + + int x, y, z, ratio, offset; + offset = 0; + ratio = ((width - 1) >> 8) + 1; + tmptex = (uint8 *)malloc(_txUtil->sizeofTx(256, height * ratio, format)); + if (tmptex) { + for (x = 0; x < ratio; x++) { + for (y = 0; y < height; y++) { + if (x < ratio - 1) { + memcpy(&tmptex[offset << 2], &tex[(x * 256 + y * width) << 2], 256 << 2); + } + else { + for (z = 0; z < width - 256 * (ratio - 1); z++) { + ((uint32*)tmptex)[offset + z] = ((uint32*)tex)[x * 256 + y * width + z]; + } + for (; z < 256; z++) { + ((uint32*)tmptex)[offset + z] = ((uint32*)tmptex)[offset + z - 1]; + } + } + offset += 256; + } + } + free(tex); + tex = tmptex; + untiled_width = width; + untiled_height = height; + width = 256; + height *= ratio; + DBG_INFO(80, L"Tiled: %d x %d -> %d x %d\n", untiled_width, untiled_height, width, height); } - } - free(tex); - tex = tmptex; - untiled_width = width; - untiled_height = height; - width = 256; - height *= ratio; - DBG_INFO(80, L"Tiled: %d x %d -> %d x %d\n", untiled_width, untiled_height, width, height); } - } } #else /* TEXTURE_TILING */ - /* minification */ - if (width > _maxwidth || height > _maxheight) { - int ratio = 1; - if (width / _maxwidth > height / _maxheight) { - ratio = (int)ceil((double)width / _maxwidth); - } else { - ratio = (int)ceil((double)height / _maxheight); - } - if (!_txReSample->minify(&tex, &width, &height, ratio)) { - free(tex); - tex = NULL; - DBG_INFO(80, L"Error: minification failed!\n"); - continue; - } - } + /* minification */ + if (width > _maxwidth || height > _maxheight) { + int ratio = 1; + if (width / _maxwidth > height / _maxheight) { + ratio = (int)ceil((double)width / _maxwidth); + } else { + ratio = (int)ceil((double)height / _maxheight); + } + if (!_txReSample->minify(&tex, &width, &height, ratio)) { + free(tex); + tex = NULL; + DBG_INFO(80, L"Error: minification failed!\n"); + continue; + } + } #endif /* TEXTURE_TILING */ - /* texture compression */ - if ((_options & COMPRESSION_MASK) && - (width >= 64 && height >= 64) /* Texture compression is not suitable for low pixel coarse detail - * textures. The assumption here is that textures larger than 64x64 - * have enough detail to produce decent quality when compressed. The - * down side is that narrow stripped textures that the N64 often use - * for large background textures are also ignored. It would be more - * reasonable if decisions are made based on fourier-transform - * spectrum or RMS error. - * - * NOTE: texture size must be checked before expanding to pow2 size. - */ - ) { - int dataSize = 0; - int compressionType = _options & COMPRESSION_MASK; + /* texture compression */ + if ((_options & COMPRESSION_MASK) && + (width >= 64 && height >= 64) /* Texture compression is not suitable for low pixel coarse detail + * textures. The assumption here is that textures larger than 64x64 + * have enough detail to produce decent quality when compressed. The + * down side is that narrow stripped textures that the N64 often use + * for large background textures are also ignored. It would be more + * reasonable if decisions are made based on fourier-transform + * spectrum or RMS error. + * + * NOTE: texture size must be checked before expanding to pow2 size. + */ + ) { + int dataSize = 0; + int compressionType = _options & COMPRESSION_MASK; #if POW2_TEXTURES #if (POW2_TEXTURES == 2) - /* 3dfx Glide3x aspect ratio (8:1 - 1:8) */ - if (!_txReSample->nextPow2(&tex, &width , &height, 32, 1)) { + /* 3dfx Glide3x aspect ratio (8:1 - 1:8) */ + if (!_txReSample->nextPow2(&tex, &width, &height, 32, 1)) { #else - /* normal pow2 expansion */ - if (!_txReSample->nextPow2(&tex, &width , &height, 32, 0)) { + /* normal pow2 expansion */ + if (!_txReSample->nextPow2(&tex, &width, &height, 32, 0)) { #endif - free(tex); - tex = NULL; - DBG_INFO(80, L"Error: aspect ratio adjustment failed!\n"); - continue; - } + free(tex); + tex = NULL; + DBG_INFO(80, L"Error: aspect ratio adjustment failed!\n"); + continue; + } #endif - switch (_options & COMPRESSION_MASK) { - case S3TC_COMPRESSION: - switch (destformat) { - case GR_TEXFMT_ARGB_8888: + switch (_options & COMPRESSION_MASK) { + case S3TC_COMPRESSION: + switch (destformat) { + case GR_TEXFMT_ARGB_8888: #if GLIDE64_DXTN - case GR_TEXFMT_ARGB_1555: /* for ARGB1555 use DXT5 instead of DXT1 */ + case GR_TEXFMT_ARGB_1555: /* for ARGB1555 use DXT5 instead of DXT1 */ #endif - case GR_TEXFMT_ALPHA_INTENSITY_88: - dataSize = width * height; - break; + case GR_TEXFMT_ALPHA_INTENSITY_88: + dataSize = width * height; + break; #if !GLIDE64_DXTN - case GR_TEXFMT_ARGB_1555: + case GR_TEXFMT_ARGB_1555: #endif - case GR_TEXFMT_RGB_565: - case GR_TEXFMT_INTENSITY_8: - dataSize = (width * height) >> 1; - break; - case GR_TEXFMT_ALPHA_8: /* no size benefit with dxtn */ - ; - } - break; - case FXT1_COMPRESSION: - switch (destformat) { - case GR_TEXFMT_ARGB_1555: - case GR_TEXFMT_RGB_565: - case GR_TEXFMT_INTENSITY_8: - dataSize = (width * height) >> 1; - break; - /* XXX: textures that use 8bit alpha channel look bad with the current - * fxt1 library, so we substitute it with dxtn for now. afaik all gfx - * cards that support fxt1 also support dxtn. (3dfx and Intel) */ - case GR_TEXFMT_ALPHA_INTENSITY_88: - case GR_TEXFMT_ARGB_8888: - compressionType = S3TC_COMPRESSION; - dataSize = width * height; - break; - case GR_TEXFMT_ALPHA_8: /* no size benefit with dxtn */ - ; - } - } - /* compress it! */ - if (dataSize) { + case GR_TEXFMT_RGB_565: + case GR_TEXFMT_INTENSITY_8: + dataSize = (width * height) >> 1; + break; + case GR_TEXFMT_ALPHA_8: /* no size benefit with dxtn */ + ; + } + break; + case FXT1_COMPRESSION: + switch (destformat) { + case GR_TEXFMT_ARGB_1555: + case GR_TEXFMT_RGB_565: + case GR_TEXFMT_INTENSITY_8: + dataSize = (width * height) >> 1; + break; + /* XXX: textures that use 8bit alpha channel look bad with the current + * fxt1 library, so we substitute it with dxtn for now. afaik all gfx + * cards that support fxt1 also support dxtn. (3dfx and Intel) */ + case GR_TEXFMT_ALPHA_INTENSITY_88: + case GR_TEXFMT_ARGB_8888: + compressionType = S3TC_COMPRESSION; + dataSize = width * height; + break; + case GR_TEXFMT_ALPHA_8: /* no size benefit with dxtn */ + ; + } + } + /* compress it! */ + if (dataSize) { #if 0 /* TEST: dither before compression for better results with gradients */ + tmptex = (uint8 *)malloc(_txUtil->sizeofTx(width, height, destformat)); + if (tmptex) { + if (_txQuantize->quantize(tex, tmptex, width, height, GR_TEXFMT_ARGB_8888, destformat, 0)) + _txQuantize->quantize(tmptex, tex, width, height, destformat, GR_TEXFMT_ARGB_8888, 0); + free(tmptex); + } +#endif + tmptex = (uint8 *)malloc(dataSize); + if (tmptex) { + if (_txQuantize->compress(tex, tmptex, + width, height, destformat, + &tmpwidth, &tmpheight, &tmpformat, + compressionType)) { + free(tex); + tex = tmptex; + width = tmpwidth; + height = tmpheight; + format = destformat = tmpformat; + } + else { + free(tmptex); + } + } + } + } + else { +#if POW2_TEXTURES +#if (POW2_TEXTURES == 2) + /* 3dfx Glide3x aspect ratio (8:1 - 1:8) */ + if (!_txReSample->nextPow2(&tex, &width, &height, 32, 1)) { +#else + /* normal pow2 expansion */ + if (!_txReSample->nextPow2(&tex, &width, &height, 32, 0)) { +#endif + free(tex); + tex = NULL; + DBG_INFO(80, L"Error: aspect ratio adjustment failed!\n"); + continue; + } +#endif + } + + /* quantize */ + { tmptex = (uint8 *)malloc(_txUtil->sizeofTx(width, height, destformat)); if (tmptex) { - if (_txQuantize->quantize(tex, tmptex, width, height, GR_TEXFMT_ARGB_8888, destformat, 0)) - _txQuantize->quantize(tmptex, tex, width, height, destformat, GR_TEXFMT_ARGB_8888, 0); - free(tmptex); - } + switch (destformat) { + case GR_TEXFMT_ARGB_8888: + case GR_TEXFMT_ARGB_4444: +#if !REDUCE_TEXTURE_FOOTPRINT + if (_maxbpp < 32 || _options & FORCE16BPP_HIRESTEX) #endif - tmptex = (uint8 *)malloc(dataSize); - if (tmptex) { - if (_txQuantize->compress(tex, tmptex, - width, height, destformat, - &tmpwidth, &tmpheight, &tmpformat, - compressionType)) { - free(tex); - tex = tmptex; - width = tmpwidth; - height = tmpheight; - format = destformat = tmpformat; - } else { - free(tmptex); - } - } - } - - } else { - -#if POW2_TEXTURES -#if (POW2_TEXTURES == 2) - /* 3dfx Glide3x aspect ratio (8:1 - 1:8) */ - if (!_txReSample->nextPow2(&tex, &width , &height, 32, 1)) { + destformat = GR_TEXFMT_ARGB_4444; + break; + case GR_TEXFMT_ARGB_1555: +#if !REDUCE_TEXTURE_FOOTPRINT + if (_maxbpp < 32 || _options & FORCE16BPP_HIRESTEX) +#endif + destformat = GR_TEXFMT_ARGB_1555; + break; + case GR_TEXFMT_RGB_565: +#if !REDUCE_TEXTURE_FOOTPRINT + if (_maxbpp < 32 || _options & FORCE16BPP_HIRESTEX) +#endif + destformat = GR_TEXFMT_RGB_565; + break; + case GR_TEXFMT_ALPHA_INTENSITY_88: + case GR_TEXFMT_ALPHA_INTENSITY_44: +#if !REDUCE_TEXTURE_FOOTPRINT + destformat = GR_TEXFMT_ALPHA_INTENSITY_88; #else - /* normal pow2 expansion */ - if (!_txReSample->nextPow2(&tex, &width , &height, 32, 0)) { + destformat = GR_TEXFMT_ALPHA_INTENSITY_44; #endif - free(tex); - tex = NULL; - DBG_INFO(80, L"Error: aspect ratio adjustment failed!\n"); - continue; - } -#endif - } - - /* quantize */ - { - tmptex = (uint8 *)malloc(_txUtil->sizeofTx(width, height, destformat)); - if (tmptex) { - switch (destformat) { - case GR_TEXFMT_ARGB_8888: - case GR_TEXFMT_ARGB_4444: -#if !REDUCE_TEXTURE_FOOTPRINT - if (_maxbpp < 32 || _options & FORCE16BPP_HIRESTEX) -#endif - destformat = GR_TEXFMT_ARGB_4444; - break; - case GR_TEXFMT_ARGB_1555: -#if !REDUCE_TEXTURE_FOOTPRINT - if (_maxbpp < 32 || _options & FORCE16BPP_HIRESTEX) -#endif - destformat = GR_TEXFMT_ARGB_1555; - break; - case GR_TEXFMT_RGB_565: -#if !REDUCE_TEXTURE_FOOTPRINT - if (_maxbpp < 32 || _options & FORCE16BPP_HIRESTEX) -#endif - destformat = GR_TEXFMT_RGB_565; - break; - case GR_TEXFMT_ALPHA_INTENSITY_88: - case GR_TEXFMT_ALPHA_INTENSITY_44: -#if !REDUCE_TEXTURE_FOOTPRINT - destformat = GR_TEXFMT_ALPHA_INTENSITY_88; -#else - destformat = GR_TEXFMT_ALPHA_INTENSITY_44; -#endif - break; - case GR_TEXFMT_ALPHA_8: - destformat = GR_TEXFMT_ALPHA_8; /* yes, this is correct. ALPHA_8 instead of INTENSITY_8 */ - break; - case GR_TEXFMT_INTENSITY_8: - destformat = GR_TEXFMT_INTENSITY_8; + break; + case GR_TEXFMT_ALPHA_8: + destformat = GR_TEXFMT_ALPHA_8; /* yes, this is correct. ALPHA_8 instead of INTENSITY_8 */ + break; + case GR_TEXFMT_INTENSITY_8: + destformat = GR_TEXFMT_INTENSITY_8; + } + if (_txQuantize->quantize(tex, tmptex, width, height, GR_TEXFMT_ARGB_8888, destformat, 0)) { + format = destformat; + free(tex); + tex = tmptex; + } } - if (_txQuantize->quantize(tex, tmptex, width, height, GR_TEXFMT_ARGB_8888, destformat, 0)) { - format = destformat; - free(tex); - tex = tmptex; - } - } } + } - } - - - /* last minute validations */ - if (!tex || !chksum || !width || !height || !format || width > _maxwidth || height > _maxheight) { + /* last minute validations */ + if (!tex || !chksum || !width || !height || !format || width > _maxwidth || height > _maxheight) { #if !DEBUG - INFO(80, L"-----\n"); - INFO(80, L"path: %ls\n", stdstr(dir_path).ToUTF16().c_str()); - INFO(80, L"file: %ls\n", TextureDir.GetNameExtension().ToUTF16().c_str()); + INFO(80, L"-----\n"); + INFO(80, L"path: %ls\n", stdstr(dir_path).ToUTF16().c_str()); + INFO(80, L"file: %ls\n", TextureDir.GetNameExtension().ToUTF16().c_str()); #endif - if (tex) { - free(tex); - tex = NULL; - INFO(80, L"Error: bad format or size! %d x %d gfmt:%x\n", width, height, format); - } else { - INFO(80, L"Error: load failed!!\n"); - } - continue; - } + if (tex) { + free(tex); + tex = NULL; + INFO(80, L"Error: bad format or size! %d x %d gfmt:%x\n", width, height, format); + } + else { + INFO(80, L"Error: load failed!!\n"); + } + continue; + } - /* load it into hires texture cache. */ + /* load it into hires texture cache. */ { - uint64 chksum64 = (uint64)palchksum; - chksum64 <<= 32; - chksum64 |= (uint64)chksum; + uint64 chksum64 = (uint64)palchksum; + chksum64 <<= 32; + chksum64 |= (uint64)chksum; - GHQTexInfo tmpInfo; - memset(&tmpInfo, 0, sizeof(GHQTexInfo)); + GHQTexInfo tmpInfo; + memset(&tmpInfo, 0, sizeof(GHQTexInfo)); - tmpInfo.data = tex; - tmpInfo.width = width; - tmpInfo.height = height; - tmpInfo.format = format; - tmpInfo.largeLodLog2 = _txUtil->grLodLog2(width, height); - tmpInfo.smallLodLog2 = tmpInfo.largeLodLog2; - tmpInfo.aspectRatioLog2 = _txUtil->grAspectRatioLog2(width, height); - tmpInfo.is_hires_tex = 1; + tmpInfo.data = tex; + tmpInfo.width = width; + tmpInfo.height = height; + tmpInfo.format = format; + tmpInfo.largeLodLog2 = _txUtil->grLodLog2(width, height); + tmpInfo.smallLodLog2 = tmpInfo.largeLodLog2; + tmpInfo.aspectRatioLog2 = _txUtil->grAspectRatioLog2(width, height); + tmpInfo.is_hires_tex = 1; #if TEXTURE_TILING - /* Glide64 style texture tiling. */ - if (untiled_width && untiled_height) { - tmpInfo.tiles = ((untiled_width - 1) >> 8) + 1; - tmpInfo.untiled_width = untiled_width; - tmpInfo.untiled_height = untiled_height; - } + /* Glide64 style texture tiling. */ + if (untiled_width && untiled_height) { + tmpInfo.tiles = ((untiled_width - 1) >> 8) + 1; + tmpInfo.untiled_width = untiled_width; + tmpInfo.untiled_height = untiled_height; + } #endif - /* remove redundant in cache */ - if (replace && TxCache::del(chksum64)) { - DBG_INFO(80, L"removed duplicate old cache.\n"); - } - - /* add to cache */ - if (TxCache::add(chksum64, &tmpInfo)) { - /* Callback to display hires texture info. - * Gonetz */ - if (_callback) { - wchar_t tmpbuf[MAX_PATH]; - mbstowcs(tmpbuf, fname, MAX_PATH); - (*_callback)(L"[%d] total mem:%.2fmb - %ls\n", _cache.size(), (float)_totalSize/1000000, tmpbuf); + /* remove redundant in cache */ + if (replace && TxCache::del(chksum64)) { + DBG_INFO(80, L"removed duplicate old cache.\n"); } - DBG_INFO(80, L"texture loaded!\n"); - } - free(tex); - } - } while (TextureDir.FindNext()); - } - return 1; -} + /* add to cache */ + if (TxCache::add(chksum64, &tmpInfo)) { + /* Callback to display hires texture info. + * Gonetz */ + if (_callback) { + wchar_t tmpbuf[MAX_PATH]; + mbstowcs(tmpbuf, fname, MAX_PATH); + (*_callback)(L"[%d] total mem:%.2fmb - %ls\n", _cache.size(), (float)_totalSize / 1000000, tmpbuf); + } + DBG_INFO(80, L"texture loaded!\n"); + } + free(tex); + } + } while (TextureDir.FindNext()); + } + return 1; + } \ No newline at end of file