debian/0000755000000000000000000000000012210642414007162 5ustar debian/source/0000755000000000000000000000000012210623037010462 5ustar debian/source/format0000644000000000000000000000001412210623037011670 0ustar 3.0 (quilt) debian/source/include-binaries0000644000000000000000000000004012210623037013614 0ustar debian/upstream-signing-key.pgp debian/control0000644000000000000000000000373512210623037010575 0ustar Source: mupen64plus-video-glide64mk2 Section: games Priority: optional Maintainer: Tobias Loose Uploaders: Sven Eckelmann Standards-Version: 3.9.4 Homepage: http://code.google.com/p/mupen64plus/ Vcs-Git: git://anonscm.debian.org/collab-maint/mupen64plus-video-glide64mk2.git Vcs-Browser: http://anonscm.debian.org/gitweb/?p=collab-maint/mupen64plus-video-glide64mk2.git Build-Depends: debhelper (>= 9.20130604), dpkg-dev (>= 1.16.1.1), libboost-filesystem-dev, libboost-system-dev, libgl1-mesa-dev | libgl-dev, libmupen64plus-dev (>= 2.0), libpng-dev, libsdl2-dev, pkg-config, zlib1g-dev | libz-dev, Package: mupen64plus-video-glide64mk2 Architecture: any-i386 any-amd64 Multi-Arch: same Pre-Depends: ${misc:Pre-Depends}, Depends: ${misc:Depends}, ${shlibs:Depends}, libtxc-dxtn0, mupen64plus-config-abi-2.2, mupen64plus-gfx-abi-2.2, mupen64plus-vidext-abi-3, Provides: mupen64plus-video, Breaks: libmupen64plus2 (<< 2.0), Description: Glide64Mk2 high-level graphics emulation for mupen64plus High-level graphics emulation plugin for known microcodes based on Glide. This version includes a Glide-to-OpenGL wrapper which makes it independent of Voodoo cards. It supports advanced graphics effects of the N64 and loading of high resolution texture packs. . It is based on Glide64 Napalm which was ported to Linux and amd64. Package: mupen64plus-video-glide64mk2-dbg Section: debug Priority: extra Architecture: any-i386 any-amd64 Multi-Arch: same Pre-Depends: ${misc:Pre-Depends}, Depends: ${misc:Depends}, mupen64plus-video-glide64mk2 (= ${binary:Version}), Description: Glide64Mk2 graphics hle for mupen64plus debug symbols package High-level graphics emulation plugin for known microcodes based on Glide. This version includes a Glide-to-OpenGL wrapper which makes it independent of Voodoo cards. It supports advanced graphics effects of the N64 and loading of high resolution texture packs. . This package contains the debug files. debian/mupen64plus-video-glide64mk2.install0000644000000000000000000000006412210623037015726 0ustar usr/lib/*/mupen64plus/ usr/share/games/mupen64plus/ debian/compat0000644000000000000000000000000212210623037010360 0ustar 9 debian/get-orig-source.sh0000755000000000000000000000147112210623037012537 0ustar #! /bin/sh set -e if [ -z "$DIR" ]; then DIR=mupen64plus-video-glide64mk2 fi if [ -z "$OWNER" ]; then OWNER=richard42 fi # try to download source package if [ "$1" != "snapshot" ]; then uscan --verbose --force-download else MODULE="${OWNER}/${DIR}" TMP="`mktemp -t -d`" hg clone --noupdate "http://bitbucket.org/${MODULE}" "${TMP}" REV="`hg --repository "${TMP}" log -r tip --template '{latesttag}+{latesttagdistance}+{node|short}\n'`" LONGREV="`hg --repository "${TMP}" log -r tip --template '{node}\n'`" TARNAME="${DIR}_${REV}.orig.tar" echo "${LONGREV}" EXCLUDE="--exclude ${TMP}/.hgtags --exclude ${TMP}/.hg_archival.txt --exclude ${TMP}/.hgignore" hg --repository "${TMP}" archive --no-decode --type tar --prefix "${DIR}-${REV}/" ${EXCLUDE} -r tip "${TARNAME}" gzip -n -f "${TARNAME}" rm -rf "${TMP}" fi debian/rules0000755000000000000000000000312512210623037010243 0ustar #!/usr/bin/make -f # -*- makefile -*- export DEB_BUILD_MAINT_OPTIONS=hardening=+all,-pie export DEB_CFLAGS_MAINT_APPEND=-flto export DEB_LDFLAGS_MAINT_APPEND=-Wl,--as-needed DEB_HOST_MULTIARCH ?= $(shell dpkg-architecture -qDEB_HOST_MULTIARCH) DEB_HOST_GNU_CPU ?= $(shell dpkg-architecture -qDEB_HOST_GNU_CPU) DEB_HOST_ARCH_OS ?= $(shell dpkg-architecture -qDEB_HOST_ARCH_OS) MAKEOPTIONS = V=1 UNAME='$(DEB_HOST_ARCH_OS)' HOST_CPU='$(DEB_HOST_GNU_CPU)' APIDIR=/usr/include/mupen64plus/ DEBUG=1 PREFIX=/usr/ LIBDIR="/usr/lib/$(DEB_HOST_MULTIARCH)" PIC=1 OPTFLAGS="-DNDEBUG" SHAREDIR="/usr/share/games/mupen64plus/" SDL_CONFIG=sdl2-config TXCDXTN=1 DBG_PACKAGE=$(shell dpkg-parsechangelog|grep '^Source: '|sed 's/^Source:\s*//')-dbg binary binary-arch binary-indep build build-arch build-indep clean install install-arch install-indep: dh $@ --sourcedirectory="projects/unix" --parallel --list-missing get-orig-source: $(CURDIR)/debian/get-orig-source.sh override_dh_auto_test: # otherwise dh_auto_test fails with debhelper 9.20130624 override_dh_auto_clean: dh_auto_clean -- $(MAKEOPTIONS) override_dh_auto_build: dh_auto_build -- all $(MAKEOPTIONS) override_dh_auto_install: dh_auto_install -- $(MAKEOPTIONS) override_dh_strip: dh_strip -a --dbg-package="$(DBG_PACKAGE)" override_dh_installchangelogs: dh_installchangelogs RELEASE .PHONY: binary binary-arch binary-indep build build-arch build-indep clean install install-arch install-indep \ get-orig-source override_dh_auto_clean override_dh_auto_test override_dh_auto_build override_dh_auto_install override_dh_strip override_dh_installchangelogs debian/patches/0000755000000000000000000000000012210623037010611 5ustar debian/patches/s3tc_removal.patch0000644000000000000000000004130212210623037014233 0ustar Description: Allow to replace patented S3TC algorithm with compatible txc_dxtn Origin: upstream, https://bitbucket.org/richard42/mupen64plus-video-glide64mk2/commits/0ea303a31ffd757110a69b9c6213dacdedff13c2/ Author: Sven Eckelmann --- diff --git a/projects/unix/Makefile b/projects/unix/Makefile index fe15b081981349b73427fe860e824a82fc912470..59840c13d50d15ae18a6f61b0ac3f13abaf1e38d 100644 --- a/projects/unix/Makefile +++ b/projects/unix/Makefile @@ -219,7 +219,6 @@ endif CFLAGS += $(LIBPNG_CFLAGS) LDLIBS += $(LIBPNG_LDLIBS) - # search for OpenGL libraries ifeq ($(OS), OSX) GL_LDLIBS = -framework OpenGL @@ -370,12 +369,17 @@ SOURCE += \ $(SRCDIR)/GlideHQ/TxReSample.cpp \ $(SRCDIR)/GlideHQ/TxDbg.cpp \ $(SRCDIR)/GlideHQ/tc-1.1+/fxt1.c \ - $(SRCDIR)/GlideHQ/tc-1.1+/dxtn.c \ $(SRCDIR)/GlideHQ/tc-1.1+/wrapper.c \ $(SRCDIR)/GlideHQ/tc-1.1+/texstore.c CPPFLAGS += -DTEXTURE_FILTER # -DDUMP_CACHE LDLIBS += -lboost_filesystem$(BOOST_SUFFIX) -lboost_system$(BOOST_SUFFIX) + + ifeq ($(TXCDXTN), 1) + CPPFLAGS += -DTXCDXTN_EXTERNAL + else + SOURCE += $(SRCDIR)/GlideHQ/tc-1.1+/dxtn.c + endif endif ifeq ($(OS),MINGW) @@ -412,6 +416,7 @@ targets: @echo " PIC=(1|0) == Force enable/disable of position independent code" @echo " POSTFIX=name == String added to the name of the the build (default: '')" @echo " HIRES=(1|0) == Enables/Disables support for hires textures and texture filters (default: 1)" + @echo " TXCDXTN=(1|0) == Enable/Disable external txc_dxtn library (default: 0)" @echo " Install Options:" @echo " PREFIX=path == install/uninstall prefix (default: /usr/local)" @echo " SHAREDIR=path == path to install shared data files (default: PREFIX/share/mupen64plus)" diff --git a/src/Glide64/m64p.h b/src/Glide64/m64p.h index 3f47cf6a10c82ebaa9b0e4f2b30d2deecfb36735..dd6e89170dad08249e176fd66c176f30c767e35c 100755 --- a/src/Glide64/m64p.h +++ b/src/Glide64/m64p.h @@ -38,7 +38,13 @@ #define CONFIG_API_VERSION 0x020000 #define VIDEXT_API_VERSION 0x030000 +#ifdef __cplusplus +extern "C" { +#endif void WriteLog(m64p_msg_level level, const char *msg, ...); +#ifdef __cplusplus +} +#endif //The Glide API originally used an integer to pick an enumerated resolution. //To accomodate arbitrary resolutions, pack it into a 32-bit struct diff --git a/src/Glide64/osal_dynamiclib.h b/src/Glide64/osal_dynamiclib.h index c24377b178e0cebd91b181a408dde34b2d6339f7..7be0cab272df0715eb578fc14a3b994474a59bfc 100755 --- a/src/Glide64/osal_dynamiclib.h +++ b/src/Glide64/osal_dynamiclib.h @@ -1,5 +1,5 @@ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Mupen64plus-core - osal/dynamiclib.h * + * Mupen64plus-video-glide64mk2 - osal_dynamiclib.h * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2009 Richard Goedeken * * * @@ -22,14 +22,18 @@ #if !defined(OSAL_DYNAMICLIB_H) #define OSAL_DYNAMICLIB_H +#include "m64p_types.h" + #ifdef __cplusplus extern "C" { #endif -#include "m64p_types.h" +m64p_error osal_dynlib_open(m64p_dynlib_handle *pLibHandle, const char *pccLibraryPath); void * osal_dynlib_getproc(m64p_dynlib_handle LibHandle, const char *pccProcedureName); +m64p_error osal_dynlib_close(m64p_dynlib_handle LibHandle); + #ifdef __cplusplus } #endif diff --git a/src/Glide64/osal_dynamiclib_unix.c b/src/Glide64/osal_dynamiclib_unix.c index b3b7ba52dc690d42dbc06204afe1232c465e388f..25562c47923e1ade77c199bd57144cb52b40228b 100755 --- a/src/Glide64/osal_dynamiclib_unix.c +++ b/src/Glide64/osal_dynamiclib_unix.c @@ -1,5 +1,5 @@ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Mupen64plus-core - osal/dynamiclib_unix.c * + * Mupen64plus-video-glide64mk2 - osal_dynamiclib_unix.c * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2009 Richard Goedeken * * * @@ -20,12 +20,33 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include +#include #include #include #include "m64p_types.h" +#include "m64p.h" #include "osal_dynamiclib.h" +m64p_error osal_dynlib_open(m64p_dynlib_handle *pLibHandle, const char *pccLibraryPath) +{ + if (pLibHandle == NULL || pccLibraryPath == NULL) + return M64ERR_INPUT_ASSERT; + + *pLibHandle = dlopen(pccLibraryPath, RTLD_NOW); + + if (*pLibHandle == NULL) + { + /* only print an error message if there is a directory separator (/) in the pathname */ + /* this prevents us from throwing an error for the use case where Mupen64Plus is not installed */ + if (strchr(pccLibraryPath, '/') != NULL) + WriteLog(M64MSG_ERROR, "dlopen('%s') failed: %s", pccLibraryPath, dlerror()); + return M64ERR_INPUT_NOT_FOUND; + } + + return M64ERR_SUCCESS; +} + void * osal_dynlib_getproc(m64p_dynlib_handle LibHandle, const char *pccProcedureName) { if (pccProcedureName == NULL) @@ -34,4 +55,17 @@ void * osal_dynlib_getproc(m64p_dynlib_handle LibHandle, const char *pccProcedur return dlsym(LibHandle, pccProcedureName); } +m64p_error osal_dynlib_close(m64p_dynlib_handle LibHandle) +{ + int rval = dlclose(LibHandle); + + if (rval != 0) + { + WriteLog(M64MSG_ERROR, "dlclose() failed: %s", dlerror()); + return M64ERR_INTERNAL; + } + + return M64ERR_SUCCESS; +} + diff --git a/src/Glide64/osal_dynamiclib_win32.c b/src/Glide64/osal_dynamiclib_win32.c index 685d717c9936055cdf5b20e3af6368f5bd1fb48c..a75c238c48141c9b69a9e8f77f2a14cc028ff78b 100755 --- a/src/Glide64/osal_dynamiclib_win32.c +++ b/src/Glide64/osal_dynamiclib_win32.c @@ -1,5 +1,5 @@ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Mupen64plus-ui-console - osal_dynamiclib_win32.c * + * Mupen64plus-video-glide64mk2 - osal_dynamiclib_win32.c * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2009 Richard Goedeken * * * @@ -24,6 +24,7 @@ #include #include "m64p_types.h" +#include "m64p.h" #include "osal_dynamiclib.h" m64p_error osal_dynlib_open(m64p_dynlib_handle *pLibHandle, const char *pccLibraryPath) @@ -39,7 +40,7 @@ m64p_error osal_dynlib_open(m64p_dynlib_handle *pLibHandle, const char *pccLibra DWORD dwErr = GetLastError(); FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, dwErr, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &pchErrMsg, 0, NULL); - fprintf(stderr, "LoadLibrary('%s') error: %s\n", pccLibraryPath, pchErrMsg); + WriteLog(M64MSG_ERROR, "LoadLibrary('%s') error: %s", pccLibraryPath, pchErrMsg); LocalFree(pchErrMsg); return M64ERR_INPUT_NOT_FOUND; } @@ -65,7 +66,7 @@ m64p_error osal_dynlib_close(m64p_dynlib_handle LibHandle) DWORD dwErr = GetLastError(); FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, dwErr, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &pchErrMsg, 0, NULL); - fprintf(stderr, "FreeLibrary() error: %s\n", pchErrMsg); + WriteLog(M64MSG_ERROR, "FreeLibrary() error: %s", pchErrMsg); LocalFree(pchErrMsg); return M64ERR_INTERNAL; } diff --git a/src/GlideHQ/TxQuantize.cpp b/src/GlideHQ/TxQuantize.cpp index b21db71ac95a27e7c18a2329c312f5dbeeb3bb12..02483cb581992841c2d913adcc981a034e9a68f2 100644 --- a/src/GlideHQ/TxQuantize.cpp +++ b/src/GlideHQ/TxQuantize.cpp @@ -41,7 +41,7 @@ TxQuantize::TxQuantize() /* get dxtn extensions */ _tx_compress_fxt1 = TxLoadLib::getInstance()->getfxtCompressTexFuncExt(); - _tx_compress_dxtn = TxLoadLib::getInstance()->getdxtCompressTexFuncExt(); + _tx_compress_dxtn_rgba = TxLoadLib::getInstance()->getdxtCompressTexFuncExt(); } @@ -1990,7 +1990,7 @@ TxQuantize::DXTn(uint8 *src, uint8 *dest, boolean bRet = 0; - if (_tx_compress_dxtn && + if (_tx_compress_dxtn_rgba && srcwidth >= 4 && srcheight >= 4) { /* compress to dxtn * width and height must be larger than 4 @@ -2038,7 +2038,7 @@ TxQuantize::DXTn(uint8 *src, uint8 *dest, unsigned int srcStride = (srcwidth * blkheight) << 2; unsigned int destStride = dstRowStride * blkrow; for (i = 0; i < numcore - 1; i++) { - thrd[i] = new std::thread(std::bind(_tx_compress_dxtn, + thrd[i] = new std::thread(std::bind(_tx_compress_dxtn_rgba, 4, srcwidth, blkheight, @@ -2049,7 +2049,7 @@ TxQuantize::DXTn(uint8 *src, uint8 *dest, src += srcStride; dest += destStride; } - thrd[i] = new std::thread(std::bind(_tx_compress_dxtn, + thrd[i] = new std::thread(std::bind(_tx_compress_dxtn_rgba, 4, srcwidth, srcheight - blkheight * i, @@ -2062,7 +2062,7 @@ TxQuantize::DXTn(uint8 *src, uint8 *dest, delete thrd[i]; } } else { - (*_tx_compress_dxtn)(4, /* comps: ARGB8888=4, RGB888=3 */ + (*_tx_compress_dxtn_rgba)(4, /* comps: ARGB8888=4, RGB888=3 */ srcwidth, /* width */ srcheight, /* height */ src, /* source */ @@ -2072,7 +2072,7 @@ TxQuantize::DXTn(uint8 *src, uint8 *dest, * others = 16 bytes per 4x4 texel */ } #else - (*_tx_compress_dxtn)(4, /* comps: ARGB8888=4, RGB888=3 */ + (*_tx_compress_dxtn_rgba)(4, /* comps: ARGB8888=4, RGB888=3 */ srcwidth, /* width */ srcheight, /* height */ src, /* source */ diff --git a/src/GlideHQ/TxQuantize.h b/src/GlideHQ/TxQuantize.h index d3c6ae6dc6da7c266c4baad5e6a490a4c8ed2a68..e14990f4150f22c86dd43cf5c8a520829ad082a7 100644 --- a/src/GlideHQ/TxQuantize.h +++ b/src/GlideHQ/TxQuantize.h @@ -38,7 +38,7 @@ private: int _numcore; fxtCompressTexFuncExt _tx_compress_fxt1; - dxtCompressTexFuncExt _tx_compress_dxtn; + dxtCompressTexFuncExt _tx_compress_dxtn_rgba; /* fast optimized... well, sort of. */ void ARGB1555_ARGB8888(uint32* src, uint32* dst, int width, int height); diff --git a/src/GlideHQ/TxUtil.cpp b/src/GlideHQ/TxUtil.cpp index 9ad7e448b01b58422bf35a40d64e3b0891f80199..411a25efb15951be9932b98937a2d63710f86e66 100644 --- a/src/GlideHQ/TxUtil.cpp +++ b/src/GlideHQ/TxUtil.cpp @@ -42,14 +42,14 @@ TxLoadLib::TxLoadLib() _dxtnlib = LoadLibrary("dxtn"); if (_dxtnlib) { - if (!_tx_compress_dxtn) - _tx_compress_dxtn = (dxtCompressTexFuncExt)DLSYM(_dxtnlib, "tx_compress_dxtn"); + if (!_tx_compress_dxtn_rgba) + _tx_compress_dxtn_rgba = (dxtCompressTexFuncExt)DLSYM(_dxtnlib, "tx_compress_dxtn_rgba"); if (!_tx_compress_fxt1) _tx_compress_fxt1 = (fxtCompressTexFuncExt)DLSYM(_dxtnlib, "fxt1_encode"); } #else - _tx_compress_dxtn = tx_compress_dxtn; + _tx_compress_dxtn_rgba = tx_compress_dxtn_rgba; _tx_compress_fxt1 = fxt1_encode; #endif @@ -74,7 +74,7 @@ TxLoadLib::getfxtCompressTexFuncExt() dxtCompressTexFuncExt TxLoadLib::getdxtCompressTexFuncExt() { - return _tx_compress_dxtn; + return _tx_compress_dxtn_rgba; } diff --git a/src/GlideHQ/TxUtil.h b/src/GlideHQ/TxUtil.h index b89f660dfb86a34b16d3ef44221af9d95b9fa4df..7f9c5f4fdd7c08f8d5a8b472b7b5594e4ec8d655 100644 --- a/src/GlideHQ/TxUtil.h +++ b/src/GlideHQ/TxUtil.h @@ -34,7 +34,7 @@ #ifdef __cplusplus extern "C"{ #endif -void tx_compress_dxtn(int srccomps, int width, int height, +void tx_compress_dxtn_rgba(int srccomps, int width, int height, const void *source, int destformat, void *dest, int destRowStride); @@ -62,7 +62,7 @@ private: HMODULE _dxtnlib; #endif fxtCompressTexFuncExt _tx_compress_fxt1; - dxtCompressTexFuncExt _tx_compress_dxtn; + dxtCompressTexFuncExt _tx_compress_dxtn_rgba; TxLoadLib(); public: static TxLoadLib* getInstance() { diff --git a/src/GlideHQ/tc-1.1+/texstore.c b/src/GlideHQ/tc-1.1+/texstore.c index 5dead259147eaeffce28076e92fb2a981ea451ec..69a6b39bc3a951421799a0b7115f325c7ed55723 100644 --- a/src/GlideHQ/tc-1.1+/texstore.c +++ b/src/GlideHQ/tc-1.1+/texstore.c @@ -33,7 +33,6 @@ #include "types.h" #include "internal.h" - void _mesa_upscale_teximage2d (unsigned int inWidth, unsigned int inHeight, unsigned int outWidth, unsigned int outHeight, diff --git a/src/GlideHQ/tc-1.1+/wrapper.c b/src/GlideHQ/tc-1.1+/wrapper.c index 0a171ee4fabcc4a26aa64b35f659b2cdb4898011..d3a78fe73d6809567b58ca680648fb5983a03c49 100644 --- a/src/GlideHQ/tc-1.1+/wrapper.c +++ b/src/GlideHQ/tc-1.1+/wrapper.c @@ -21,18 +21,62 @@ #include +#include #include "types.h" #include "internal.h" -#include "dxtn.h" +#include "../../Glide64/m64p.h" +typedef void (*dxtCompressTexFuncExt)(int srccomps, int width, + int height, const byte *srcPixData, + int destformat, byte *dest, + int dstRowStride); +static dxtCompressTexFuncExt _tx_compress_dxtn = NULL; + +#ifdef TXCDXTN_EXTERNAL + +#include "../../Glide64/osal_dynamiclib.h" + +#if defined(_WIN32) || defined(WIN32) +#define DXTN_LIBNAME "dxtn.dll" +#elif defined(__DJGPP__) +#define DXTN_LIBNAME "dxtn.dxe" +#else +#define DXTN_LIBNAME "libtxc_dxtn.so" +#endif + +static m64p_dynlib_handle dxtn_lib_handle; + +static void tx_compress_dxtn_init() +{ + m64p_error rval; + + if (_tx_compress_dxtn) + return; + + rval = osal_dynlib_open(&dxtn_lib_handle, DXTN_LIBNAME); + if (rval != M64ERR_SUCCESS) { + WriteLog(M64MSG_WARNING, "Failed to open %s", DXTN_LIBNAME); + return; + } + + _tx_compress_dxtn = osal_dynlib_getproc(dxtn_lib_handle, "tx_compress_dxtn"); + if (!_tx_compress_dxtn) { + WriteLog(M64MSG_WARNING, "Shared library '%s' invalid; no PluginGetVersion() function found.", DXTN_LIBNAME, "tx_compress_dxtn"); + osal_dynlib_close(dxtn_lib_handle); + return; + } +} + +#else + +#include "dxtn.h" #define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0 #define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1 #define GL_COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2 #define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3 - TAPI void TAPIENTRY fetch_2d_texel_rgb_dxt1 (int texImage_RowStride, const byte *texImage_Data, @@ -73,7 +117,7 @@ fetch_2d_texel_rgba_dxt5 (int texImage_RowStride, } -TAPI void TAPIENTRY +static tx_compress_dxtn (int srccomps, int width, int height, const byte *source, int destformat, byte *dest, int destRowStride) @@ -105,3 +149,38 @@ tx_compress_dxtn (int srccomps, int width, int height, assert(0); } } + +static void tx_compress_dxtn_init() +{ + _tx_compress_dxtn = tx_compress_dxtn; +} + +#endif + + +TAPI void TAPIENTRY +tx_compress_dxtn_rgba(int srccomps, int width, int height, + const byte *source, int destformat, byte *dest, + int destRowStride) +{ + int srcRowStride = width * srccomps; + void *newSource = NULL; + + tx_compress_dxtn_init(); + if (!_tx_compress_dxtn) { + WriteLog(M64MSG_ERROR, "Failed to initialize S3TC compressor"); + return; + } + + assert(srccomps == 3 || srccomps == 4); + + if (srccomps == 3) + newSource = reorder_source_3_alloc(source, width, height, srcRowStride); + if (srccomps == 4) + newSource = reorder_source_4_alloc(source, width, height, srcRowStride); + + _tx_compress_dxtn(srccomps, width, height, newSource, destformat, dest, + destRowStride); + + free(newSource); +} diff --git a/src/Glitch64/main.h b/src/Glitch64/main.h index 5b203ed22058e9c95b816b95c30778909cc39373..361c597f746d7603e529b36734727aaf7dd6f22c 100644 --- a/src/Glitch64/main.h +++ b/src/Glitch64/main.h @@ -24,7 +24,13 @@ #include #define LOG(...) WriteLog(M64MSG_VERBOSE, __VA_ARGS__) +#ifdef __cplusplus +extern "C" { +#endif void WriteLog(m64p_msg_level level, const char *msg, ...); +#ifdef __cplusplus +} +#endif #ifndef _WIN32 debian/patches/series0000644000000000000000000000017112210623037012025 0ustar mesa_fxt1.patch s3tc_removal.patch init_quit.patch load_hires_cache.patch kfreebsd_hurd_support.patch path_max_war.patch debian/patches/init_quit.patch0000644000000000000000000000276712210623037013653 0ustar Description: Video plugin should call VidExt_Quit when it is done Origin: upstream, https://bitbucket.org/richard42/mupen64plus-video-glide64mk2/commits/753991c466983154780fa4239f046397d44dbaf9/ Author: Richard Goedeken --- diff --git a/src/Glide64/Main.cpp b/src/Glide64/Main.cpp index 3a5e47a462bdeed9c8995c38cb097eef1edaa9c4..fabaa3091d74ee0fb41816bd650d2908d14b371d 100644 --- a/src/Glide64/Main.cpp +++ b/src/Glide64/Main.cpp @@ -1407,7 +1407,6 @@ EXPORT m64p_error CALL PluginStartup(m64p_dynlib_handle CoreLibHandle, void *Con if (configDir) { SetConfigDir(configDir); - CoreVideo_Init(); ReadSettings(); return M64ERR_SUCCESS; } diff --git a/src/Glitch64/glitchmain.cpp b/src/Glitch64/glitchmain.cpp index da75486c894f0149d2b38ec5d74857a790d4c0d3..773a4db4d2396a44821361ba64ba676eafa6e9ea 100644 --- a/src/Glitch64/glitchmain.cpp +++ b/src/Glitch64/glitchmain.cpp @@ -497,7 +497,7 @@ grSstWinOpen( // ZIGGY viewport_offset is WIN32 specific, with SDL just set it to zero viewport_offset = 0; //-10 //-20; - // ZIGGY not sure, but it might be better to let the system choose + CoreVideo_Init(); CoreVideo_GL_SetAttribute(M64P_GL_DOUBLEBUFFER, 1); CoreVideo_GL_SetAttribute(M64P_GL_SWAP_CONTROL, vsync); CoreVideo_GL_SetAttribute(M64P_GL_BUFFER_SIZE, 16); @@ -798,6 +798,9 @@ grSstWinClose( GrContext_t context ) //SDL_QuitSubSystem(SDL_INIT_VIDEO); //sleep(2); #endif + + CoreVideo_Quit(); + return FXTRUE; } debian/patches/load_hires_cache.patch0000644000000000000000000000116712210623037015073 0ustar Description: Enable the dump_cache to allow loading of dat files Author: Sven Eckelmann --- diff --git a/projects/unix/Makefile b/projects/unix/Makefile index 59840c13d50d15ae18a6f61b0ac3f13abaf1e38d..a4389aeaaa3c31a3ca5690f31eade6c6e78f0702 100644 --- a/projects/unix/Makefile +++ b/projects/unix/Makefile @@ -372,7 +372,7 @@ SOURCE += \ $(SRCDIR)/GlideHQ/tc-1.1+/wrapper.c \ $(SRCDIR)/GlideHQ/tc-1.1+/texstore.c -CPPFLAGS += -DTEXTURE_FILTER # -DDUMP_CACHE +CPPFLAGS += -DTEXTURE_FILTER -DDUMP_CACHE LDLIBS += -lboost_filesystem$(BOOST_SUFFIX) -lboost_system$(BOOST_SUFFIX) ifeq ($(TXCDXTN), 1) debian/patches/kfreebsd_hurd_support.patch0000644000000000000000000000150212210623037016233 0ustar Description: Allow to compile under kFreeBSD and Hurd Author: Sven Eckelmann --- diff --git a/src/Glitch64/inc/glidesys.h b/src/Glitch64/inc/glidesys.h index b19845a9a81fc5cfb984c63b2b97e33a57183866..12d0fcbd6a44b95ad75973e4942df7833b3b0356 100644 --- a/src/Glitch64/inc/glidesys.h +++ b/src/Glitch64/inc/glidesys.h @@ -110,7 +110,8 @@ n** ----------------------------------------------------------------------- /* Check for OS */ #if defined(__IRIX__) || defined(__sparc__) || defined(__linux__) || \ - defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) + defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || \ + defined(__FreeBSD_kernel__) || defined(__GNU__) # define GLIDE_OS GLIDE_OS_UNIX #elif defined(__DOS__) # define GLIDE_OS GLIDE_OS_DOS32 debian/patches/path_max_war.patch0000644000000000000000000000165312210623037014311 0ustar Description: Add a workaround for systems not defining PATH_MAX Author: Sven Eckelmann --- diff --git a/src/Glide64/Ini.cpp b/src/Glide64/Ini.cpp index b371a08ea43f98def56c91e468efc3b460a26a10..9f05f907d2fb7196ade607c4b6a93291c980ee5f 100755 --- a/src/Glide64/Ini.cpp +++ b/src/Glide64/Ini.cpp @@ -59,6 +59,9 @@ #define PATH_MAX _MAX_PATH #define stricmp _stricmp #endif +#ifndef PATH_MAX + #define PATH_MAX 4096 +#endif FILE *ini; int sectionstart; diff --git a/src/Glide64/Main.cpp b/src/Glide64/Main.cpp index fabaa3091d74ee0fb41816bd650d2908d14b371d..2fbdca40aaf8d392672da348814f776ad52dd04b 100644 --- a/src/Glide64/Main.cpp +++ b/src/Glide64/Main.cpp @@ -55,6 +55,9 @@ #include #define PATH_MAX MAX_PATH #endif +#ifndef PATH_MAX + #define PATH_MAX 4096 +#endif #include "osal_dynamiclib.h" #ifdef TEXTURE_FILTER // Hiroshi Morii #include debian/patches/mesa_fxt1.patch0000644000000000000000000023740412210623037013533 0ustar Description: Avoid wrong colors in compressed fxt1 textures Mesa mesa-7.8.1-24878-g3998cfa has better support for fxt1 and can even make the YUV/ARGB hacks unnecessary. Origin: upstream, https://bitbucket.org/richard42/mupen64plus-video-glide64mk2/commits/1538e5a5189c6d2df4748e70430ba30d6b21d709/ Author: Sven Eckelmann --- diff --git a/src/GlideHQ/tc-1.1+/fxt1.c b/src/GlideHQ/tc-1.1+/fxt1.c index 623e69c765713e94967c591b35e45ab87ae08631..d39e7494a01b5b8c6b20afeade7063be78d82c81 100644 --- a/src/GlideHQ/tc-1.1+/fxt1.c +++ b/src/GlideHQ/tc-1.1+/fxt1.c @@ -1,8 +1,7 @@ /* - * FXT1 codec - * Version: 1.1 + * Mesa 3-D graphics library * - * Copyright (C) 2004 Daniel Borca All Rights Reserved. + * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -17,18 +16,21 @@ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * DANIEL BORCA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN - * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. */ -/* Copyright (C) 2007 Hiroshi Morii - * Added support for ARGB inputs. +/** + * \file texcompress_fxt1.c + * GL_3DFX_texture_compression_FXT1 support. */ #include #include +#include #include "types.h" #include "internal.h" @@ -54,1122 +56,1093 @@ #define LL_RMS_E 255 /* fault tolerance (maximum error) */ #define ALPHA_TS 2 /* alpha threshold: (255 - ALPHA_TS) deemed opaque */ #define ISTBLACK(v) (*((dword *)(v)) == 0) -#define COPY_4UBV(DST, SRC) *((dword *)(DST)) = *((dword *)(SRC)) static int fxt1_bestcol (float vec[][MAX_COMP], int nv, - byte input[MAX_COMP], int nc) + byte input[MAX_COMP], int nc) { - int i, j, best = -1; - float err = 1e9; /* big enough */ + int i, j, best = -1; + float err = 1e9; /* big enough */ - for (j = 0; j < nv; j++) { - float e = 0.0F; - for (i = 0; i < nc; i++) { - e += (vec[j][i] - input[i]) * (vec[j][i] - input[i]); - } - if (e < err) { - err = e; - best = j; - } - } + for (j = 0; j < nv; j++) { + float e = 0.0F; + for (i = 0; i < nc; i++) { + e += (vec[j][i] - input[i]) * (vec[j][i] - input[i]); + } + if (e < err) { + err = e; + best = j; + } + } - return best; + return best; } static int fxt1_worst (float vec[MAX_COMP], - byte input[N_TEXELS][MAX_COMP], int nc, int n) + byte input[N_TEXELS][MAX_COMP], int nc, int n) { - int i, k, worst = -1; - float err = -1.0F; /* small enough */ + int i, k, worst = -1; + float err = -1.0F; /* small enough */ - for (k = 0; k < n; k++) { - float e = 0.0F; - for (i = 0; i < nc; i++) { - e += (vec[i] - input[k][i]) * (vec[i] - input[k][i]); - } - if (e > err) { - err = e; - worst = k; - } - } + for (k = 0; k < n; k++) { + float e = 0.0F; + for (i = 0; i < nc; i++) { + e += (vec[i] - input[k][i]) * (vec[i] - input[k][i]); + } + if (e > err) { + err = e; + worst = k; + } + } - return worst; + return worst; } static int fxt1_variance (double variance[MAX_COMP], - byte input[N_TEXELS][MAX_COMP], int nc, int n) + byte input[N_TEXELS][MAX_COMP], int nc, int n) { - int i, k, best = 0; - dword sx, sx2; - double var, maxvar = -1; /* small enough */ - double teenth = 1.0 / n; + int i, k, best = 0; + int sx, sx2; + double var, maxvar = -1; /* small enough */ + double teenth = 1.0 / n; - for (i = 0; i < nc; i++) { - sx = sx2 = 0; - for (k = 0; k < n; k++) { - int t = input[k][i]; - sx += t; - sx2 += t * t; - } - var = sx2 * teenth - sx * sx * teenth * teenth; - if (maxvar < var) { - maxvar = var; - best = i; - } - if (variance) { - variance[i] = var; - } - } + for (i = 0; i < nc; i++) { + sx = sx2 = 0; + for (k = 0; k < n; k++) { + int t = input[k][i]; + sx += t; + sx2 += t * t; + } + var = sx2 * teenth - sx * sx * teenth * teenth; + if (maxvar < var) { + maxvar = var; + best = i; + } + if (variance) { + variance[i] = var; + } + } - return best; + return best; } static int fxt1_choose (float vec[][MAX_COMP], int nv, - byte input[N_TEXELS][MAX_COMP], int nc, int n) + byte input[N_TEXELS][MAX_COMP], int nc, int n) { #if 0 - /* Choose colors from a grid. - */ - int i, j; + /* Choose colors from a grid. + */ + int i, j; - for (j = 0; j < nv; j++) { - int m = j * (n - 1) / (nv - 1); - for (i = 0; i < nc; i++) { - vec[j][i] = input[m][i]; - } - } + for (j = 0; j < nv; j++) { + int m = j * (n - 1) / (nv - 1); + for (i = 0; i < nc; i++) { + vec[j][i] = input[m][i]; + } + } #else - /* Our solution here is to find the darkest and brightest colors in - * the 8x4 tile and use those as the two representative colors. - * There are probably better algorithms to use (histogram-based). - */ - int i, j, k; -#ifndef YUV - int minSum = 2000; /* big enough */ -#else - int minSum = 2000000; -#endif - int maxSum = -1; /* small enough */ - int minCol = 0; /* phoudoin: silent compiler! */ - int maxCol = 0; /* phoudoin: silent compiler! */ + /* Our solution here is to find the darkest and brightest colors in + * the 8x4 tile and use those as the two representative colors. + * There are probably better algorithms to use (histogram-based). + */ + int i, j, k; + int minSum = 2000; /* big enough */ + int maxSum = -1; /* small enough */ + int minCol = 0; /* phoudoin: silent compiler! */ + int maxCol = 0; /* phoudoin: silent compiler! */ - struct { - int flag; - dword key; - int freq; - int idx; - } hist[N_TEXELS]; - int lenh = 0; + struct { + int flag; + int key; + int freq; + int idx; + } hist[N_TEXELS]; + int lenh = 0; - memset(hist, 0, sizeof(hist)); + memset(hist, 0, sizeof(hist)); - for (k = 0; k < n; k++) { - int l; - dword key = 0; - int sum = 0; - for (i = 0; i < nc; i++) { - key <<= 8; - key |= input[k][i]; -#ifndef YUV - sum += input[k][i]; -#else - /* RGB to YUV conversion according to CCIR 601 specs - * Y = 0.299R+0.587G+0.114B - * U = 0.713(R - Y) = 0.500R-0.419G-0.081B - * V = 0.564(B - Y) = -0.169R-0.331G+0.500B - */ - sum = 299 * input[k][RCOMP] + 587 * input[k][GCOMP] + 114 * input[k][BCOMP]; -#endif - } - for (l = 0; l < n; l++) { - if (!hist[l].flag) { - /* alloc new slot */ - hist[l].flag = !0; - hist[l].key = key; - hist[l].freq = 1; - hist[l].idx = k; - lenh = l + 1; - break; - } else if (hist[l].key == key) { - hist[l].freq++; - break; - } - } - if (minSum > sum) { - minSum = sum; - minCol = k; - } - if (maxSum < sum) { - maxSum = sum; - maxCol = k; - } - } + for (k = 0; k < n; k++) { + int l; + int key = 0; + int sum = 0; + for (i = 0; i < nc; i++) { + key <<= 8; + key |= input[k][i]; + sum += input[k][i]; + } + for (l = 0; l < n; l++) { + if (!hist[l].flag) { + /* alloc new slot */ + hist[l].flag = !0; + hist[l].key = key; + hist[l].freq = 1; + hist[l].idx = k; + lenh = l + 1; + break; + } else if (hist[l].key == key) { + hist[l].freq++; + break; + } + } + if (minSum > sum) { + minSum = sum; + minCol = k; + } + if (maxSum < sum) { + maxSum = sum; + maxCol = k; + } + } - if (lenh <= nv) { - for (j = 0; j < lenh; j++) { - for (i = 0; i < nc; i++) { - vec[j][i] = (float)input[hist[j].idx][i]; - } - } - for (; j < nv; j++) { - for (i = 0; i < nc; i++) { - vec[j][i] = vec[0][i]; - } - } - return 0; - } + if (lenh <= nv) { + for (j = 0; j < lenh; j++) { + for (i = 0; i < nc; i++) { + vec[j][i] = (float)input[hist[j].idx][i]; + } + } + for (; j < nv; j++) { + for (i = 0; i < nc; i++) { + vec[j][i] = vec[0][i]; + } + } + return 0; + } - for (j = 0; j < nv; j++) { - for (i = 0; i < nc; i++) { - vec[j][i] = ((nv - 1 - j) * input[minCol][i] + j * input[maxCol][i] + (nv - 1) / 2) / (float)(nv - 1); - } - } + for (j = 0; j < nv; j++) { + for (i = 0; i < nc; i++) { + vec[j][i] = ((nv - 1 - j) * input[minCol][i] + j * input[maxCol][i] + (nv - 1) / 2) / (float)(nv - 1); + } + } #endif - return !0; + return !0; } static int fxt1_lloyd (float vec[][MAX_COMP], int nv, - byte input[N_TEXELS][MAX_COMP], int nc, int n) + byte input[N_TEXELS][MAX_COMP], int nc, int n) { - /* Use the generalized lloyd's algorithm for VQ: - * find 4 color vectors. - * - * for each sample color - * sort to nearest vector. - * - * replace each vector with the centroid of it's matching colors. - * - * repeat until RMS doesn't improve. - * - * if a color vector has no samples, or becomes the same as another - * vector, replace it with the color which is farthest from a sample. - * - * vec[][MAX_COMP] initial vectors and resulting colors - * nv number of resulting colors required - * input[N_TEXELS][MAX_COMP] input texels - * nc number of components in input / vec - * n number of input samples - */ + /* Use the generalized lloyd's algorithm for VQ: + * find 4 color vectors. + * + * for each sample color + * sort to nearest vector. + * + * replace each vector with the centroid of its matching colors. + * + * repeat until RMS doesn't improve. + * + * if a color vector has no samples, or becomes the same as another + * vector, replace it with the color which is farthest from a sample. + * + * vec[][MAX_COMP] initial vectors and resulting colors + * nv number of resulting colors required + * input[N_TEXELS][MAX_COMP] input texels + * nc number of components in input / vec + * n number of input samples + */ - int sum[MAX_VECT][MAX_COMP]; /* used to accumulate closest texels */ - int cnt[MAX_VECT]; /* how many times a certain vector was chosen */ - float error, lasterror = 1e9; + int sum[MAX_VECT][MAX_COMP]; /* used to accumulate closest texels */ + int cnt[MAX_VECT]; /* how many times a certain vector was chosen */ + float error, lasterror = 1e9; - int i, j, k, rep; + int i, j, k, rep; - /* the quantizer */ - for (rep = 0; rep < LL_N_REP; rep++) { - /* reset sums & counters */ - for (j = 0; j < nv; j++) { - for (i = 0; i < nc; i++) { - sum[j][i] = 0; - } - cnt[j] = 0; - } - error = 0; + /* the quantizer */ + for (rep = 0; rep < LL_N_REP; rep++) { + /* reset sums & counters */ + for (j = 0; j < nv; j++) { + for (i = 0; i < nc; i++) { + sum[j][i] = 0; + } + cnt[j] = 0; + } + error = 0; - /* scan whole block */ - for (k = 0; k < n; k++) { + /* scan whole block */ + for (k = 0; k < n; k++) { #if 1 - int best = -1; - float err = 1e9; /* big enough */ - /* determine best vector */ - for (j = 0; j < nv; j++) { - float e = (vec[j][0] - input[k][0]) * (vec[j][0] - input[k][0]) + - (vec[j][1] - input[k][1]) * (vec[j][1] - input[k][1]) + - (vec[j][2] - input[k][2]) * (vec[j][2] - input[k][2]); - if (nc == 4) { - e += (vec[j][3] - input[k][3]) * (vec[j][3] - input[k][3]); - } - if (e < err) { - err = e; - best = j; - } - } + int best = -1; + float err = 1e9; /* big enough */ + /* determine best vector */ + for (j = 0; j < nv; j++) { + float e = (vec[j][0] - input[k][0]) * (vec[j][0] - input[k][0]) + + (vec[j][1] - input[k][1]) * (vec[j][1] - input[k][1]) + + (vec[j][2] - input[k][2]) * (vec[j][2] - input[k][2]); + if (nc == 4) { + e += (vec[j][3] - input[k][3]) * (vec[j][3] - input[k][3]); + } + if (e < err) { + err = e; + best = j; + } + } #else - int best = fxt1_bestcol(vec, nv, input[k], nc, &err); + int best = fxt1_bestcol(vec, nv, input[k], nc, &err); #endif - /* add in closest color */ - for (i = 0; i < nc; i++) { - sum[best][i] += input[k][i]; - } - /* mark this vector as used */ - cnt[best]++; - /* accumulate error */ - error += err; - } + assert(best >= 0); + /* add in closest color */ + for (i = 0; i < nc; i++) { + sum[best][i] += input[k][i]; + } + /* mark this vector as used */ + cnt[best]++; + /* accumulate error */ + error += err; + } - /* check RMS */ - if ((error < LL_RMS_E) || - ((error < lasterror) && ((lasterror - error) < LL_RMS_D))) { - return !0; /* good match */ - } - lasterror = error; + /* check RMS */ + if ((error < LL_RMS_E) || + ((error < lasterror) && ((lasterror - error) < LL_RMS_D))) { + return !0; /* good match */ + } + lasterror = error; - /* move each vector to the barycenter of its closest colors */ - for (j = 0; j < nv; j++) { - if (cnt[j]) { - float div = 1.0F / cnt[j]; - for (i = 0; i < nc; i++) { - vec[j][i] = div * sum[j][i]; - } - } else { - /* this vec has no samples or is identical with a previous vec */ - int worst = fxt1_worst(vec[j], input, nc, n); - for (i = 0; i < nc; i++) { - vec[j][i] = input[worst][i]; - } - } - } - } + /* move each vector to the barycenter of its closest colors */ + for (j = 0; j < nv; j++) { + if (cnt[j]) { + float div = 1.0F / cnt[j]; + for (i = 0; i < nc; i++) { + vec[j][i] = div * sum[j][i]; + } + } else { + /* this vec has no samples or is identical with a previous vec */ + int worst = fxt1_worst(vec[j], input, nc, n); + for (i = 0; i < nc; i++) { + vec[j][i] = input[worst][i]; + } + } + } + } - return 0; /* could not converge fast enough */ + return 0; /* could not converge fast enough */ } static void fxt1_quantize_CHROMA (dword *cc, - byte input[N_TEXELS][MAX_COMP]) + byte input[N_TEXELS][MAX_COMP]) { - const int n_vect = 4; /* 4 base vectors to find */ - const int n_comp = 3; /* 3 components: R, G, B */ - float vec[MAX_VECT][MAX_COMP]; - int i, j, k; - qword hi; /* high quadword */ - dword lohi, lolo; /* low quadword: hi dword, lo dword */ + const int n_vect = 4; /* 4 base vectors to find */ + const int n_comp = 3; /* 3 components: R, G, B */ + float vec[MAX_VECT][MAX_COMP]; + int i, j, k; + qword hi; /* high quadword */ + dword lohi, lolo; /* low quadword: hi dword, lo dword */ - if (fxt1_choose(vec, n_vect, input, n_comp, N_TEXELS) != 0) { - fxt1_lloyd(vec, n_vect, input, n_comp, N_TEXELS); - } + if (fxt1_choose(vec, n_vect, input, n_comp, N_TEXELS) != 0) { + fxt1_lloyd(vec, n_vect, input, n_comp, N_TEXELS); + } - Q_MOV32(hi, 4); /* cc-chroma = "010" + unused bit */ - for (j = n_vect - 1; j >= 0; j--) { - for (i = 0; i < n_comp; i++) { - /* add in colors */ - Q_SHL(hi, 5); - Q_OR32(hi, (dword)(vec[j][i] / 8.0F)); - } - } - ((qword *)cc)[1] = hi; + Q_MOV32(hi, 4); /* cc-chroma = "010" + unused bit */ + for (j = n_vect - 1; j >= 0; j--) { + for (i = 0; i < n_comp; i++) { + /* add in colors */ + Q_SHL(hi, 5); + Q_OR32(hi, (dword)(vec[j][i] / 8.0F)); + } + } + ((qword *)cc)[1] = hi; - lohi = lolo = 0; - /* right microtile */ - for (k = N_TEXELS - 1; k >= N_TEXELS / 2; k--) { - lohi <<= 2; - lohi |= fxt1_bestcol(vec, n_vect, input[k], n_comp); - } - /* left microtile */ - for (; k >= 0; k--) { - lolo <<= 2; - lolo |= fxt1_bestcol(vec, n_vect, input[k], n_comp); - } - cc[1] = lohi; - cc[0] = lolo; + lohi = lolo = 0; + /* right microtile */ + for (k = N_TEXELS - 1; k >= N_TEXELS/2; k--) { + lohi <<= 2; + lohi |= fxt1_bestcol(vec, n_vect, input[k], n_comp); + } + /* left microtile */ + for (; k >= 0; k--) { + lolo <<= 2; + lolo |= fxt1_bestcol(vec, n_vect, input[k], n_comp); + } + cc[1] = lohi; + cc[0] = lolo; } static void fxt1_quantize_ALPHA0 (dword *cc, - byte input[N_TEXELS][MAX_COMP], - byte reord[N_TEXELS][MAX_COMP], int n) + byte input[N_TEXELS][MAX_COMP], + byte reord[N_TEXELS][MAX_COMP], int n) { - const int n_vect = 3; /* 3 base vectors to find */ - const int n_comp = 4; /* 4 components: R, G, B, A */ - float vec[MAX_VECT][MAX_COMP]; - int i, j, k; - qword hi; /* high quadword */ - dword lohi, lolo; /* low quadword: hi dword, lo dword */ + const int n_vect = 3; /* 3 base vectors to find */ + const int n_comp = 4; /* 4 components: R, G, B, A */ + float vec[MAX_VECT][MAX_COMP]; + int i, j, k; + qword hi; /* high quadword */ + dword lohi, lolo; /* low quadword: hi dword, lo dword */ - /* the last vector indicates zero */ - for (i = 0; i < n_comp; i++) { - vec[n_vect][i] = 0; - } + /* the last vector indicates zero */ + for (i = 0; i < n_comp; i++) { + vec[n_vect][i] = 0; + } - /* the first n texels in reord are guaranteed to be non-zero */ - if (fxt1_choose(vec, n_vect, reord, n_comp, n) != 0) { - fxt1_lloyd(vec, n_vect, reord, n_comp, n); - } + /* the first n texels in reord are guaranteed to be non-zero */ + if (fxt1_choose(vec, n_vect, reord, n_comp, n) != 0) { + fxt1_lloyd(vec, n_vect, reord, n_comp, n); + } - Q_MOV32(hi, 6); /* alpha = "011" + lerp = 0 */ - for (j = n_vect - 1; j >= 0; j--) { - /* add in alphas */ - Q_SHL(hi, 5); - Q_OR32(hi, (dword)(vec[j][ACOMP] / 8.0F)); - } - for (j = n_vect - 1; j >= 0; j--) { - for (i = 0; i < n_comp - 1; i++) { - /* add in colors */ - Q_SHL(hi, 5); - Q_OR32(hi, (dword)(vec[j][i] / 8.0F)); - } - } - ((qword *)cc)[1] = hi; + Q_MOV32(hi, 6); /* alpha = "011" + lerp = 0 */ + for (j = n_vect - 1; j >= 0; j--) { + /* add in alphas */ + Q_SHL(hi, 5); + Q_OR32(hi, (dword)(vec[j][ACOMP] / 8.0F)); + } + for (j = n_vect - 1; j >= 0; j--) { + for (i = 0; i < n_comp - 1; i++) { + /* add in colors */ + Q_SHL(hi, 5); + Q_OR32(hi, (dword)(vec[j][i] / 8.0F)); + } + } + ((qword *)cc)[1] = hi; - lohi = lolo = 0; - /* right microtile */ - for (k = N_TEXELS - 1; k >= N_TEXELS / 2; k--) { - lohi <<= 2; - lohi |= fxt1_bestcol(vec, n_vect + 1, input[k], n_comp); - } - /* left microtile */ - for (; k >= 0; k--) { - lolo <<= 2; - lolo |= fxt1_bestcol(vec, n_vect + 1, input[k], n_comp); - } - cc[1] = lohi; - cc[0] = lolo; + lohi = lolo = 0; + /* right microtile */ + for (k = N_TEXELS - 1; k >= N_TEXELS/2; k--) { + lohi <<= 2; + lohi |= fxt1_bestcol(vec, n_vect + 1, input[k], n_comp); + } + /* left microtile */ + for (; k >= 0; k--) { + lolo <<= 2; + lolo |= fxt1_bestcol(vec, n_vect + 1, input[k], n_comp); + } + cc[1] = lohi; + cc[0] = lolo; } static void fxt1_quantize_ALPHA1 (dword *cc, - byte input[N_TEXELS][MAX_COMP]) + byte input[N_TEXELS][MAX_COMP]) { - const int n_vect = 3; /* highest vector number in each microtile */ - const int n_comp = 4; /* 4 components: R, G, B, A */ - float vec[1 + 1 + 1][MAX_COMP]; /* 1.5 extrema for each sub-block */ - float b, iv[MAX_COMP]; /* interpolation vector */ - int i, j, k; - qword hi; /* high quadword */ - dword lohi, lolo; /* low quadword: hi dword, lo dword */ + const int n_vect = 3; /* highest vector number in each microtile */ + const int n_comp = 4; /* 4 components: R, G, B, A */ + float vec[1 + 1 + 1][MAX_COMP]; /* 1.5 extrema for each sub-block */ + float b, iv[MAX_COMP]; /* interpolation vector */ + int i, j, k; + qword hi; /* high quadword */ + dword lohi, lolo; /* low quadword: hi dword, lo dword */ - int minSum; - int maxSum; - int minColL = 0, maxColL = 0; - int minColR = 0, maxColR = 0; - int sumL = 0, sumR = 0; + int minSum; + int maxSum; + int minColL = 0, maxColL = 0; + int minColR = 0, maxColR = 0; + int sumL = 0, sumR = 0; + int nn_comp; + /* Our solution here is to find the darkest and brightest colors in + * the 4x4 tile and use those as the two representative colors. + * There are probably better algorithms to use (histogram-based). + */ + nn_comp = n_comp; + while ((minColL == maxColL) && nn_comp) { + minSum = 2000; /* big enough */ + maxSum = -1; /* small enough */ + for (k = 0; k < N_TEXELS / 2; k++) { + int sum = 0; + for (i = 0; i < nn_comp; i++) { + sum += input[k][i]; + } + if (minSum > sum) { + minSum = sum; + minColL = k; + } + if (maxSum < sum) { + maxSum = sum; + maxColL = k; + } + sumL += sum; + } + + nn_comp--; + } - /* Our solution here is to find the darkest and brightest colors in - * the 4x4 tile and use those as the two representative colors. - * There are probably better algorithms to use (histogram-based). - */ -#ifndef YUV - minSum = 2000; /* big enough */ -#else - minSum = 2000000; -#endif - maxSum = -1; /* small enough */ - for (k = 0; k < N_TEXELS / 2; k++) { - int sum = 0; -#ifndef YUV - for (i = 0; i < n_comp; i++) { - sum += input[k][i]; - } -#else - sum = 299 * input[k][RCOMP] + 587 * input[k][GCOMP] + 114 * input[k][BCOMP]; -#endif - if (minSum > sum) { - minSum = sum; - minColL = k; - } - if (maxSum < sum) { - maxSum = sum; - maxColL = k; - } - sumL += sum; - } -#ifndef YUV - minSum = 2000; /* big enough */ -#else - minSum = 2000000; -#endif - maxSum = -1; /* small enough */ - for (; k < N_TEXELS; k++) { - int sum = 0; -#ifndef YUV - for (i = 0; i < n_comp; i++) { - sum += input[k][i]; - } -#else - sum = 299 * input[k][RCOMP] + 587 * input[k][GCOMP] + 114 * input[k][BCOMP]; -#endif - if (minSum > sum) { - minSum = sum; - minColR = k; - } - if (maxSum < sum) { - maxSum = sum; - maxColR = k; - } - sumR += sum; - } + nn_comp = n_comp; + while ((minColR == maxColR) && nn_comp) { + minSum = 2000; /* big enough */ + maxSum = -1; /* small enough */ + for (k = N_TEXELS / 2; k < N_TEXELS; k++) { + int sum = 0; + for (i = 0; i < nn_comp; i++) { + sum += input[k][i]; + } + if (minSum > sum) { + minSum = sum; + minColR = k; + } + if (maxSum < sum) { + maxSum = sum; + maxColR = k; + } + sumR += sum; + } - /* choose the common vector (yuck!) */ - { - int j1, j2; - int v1 = 0, v2 = 0; - float err = 1e9; /* big enough */ - float tv[2 * 2][MAX_COMP]; /* 2 extrema for each sub-block */ - for (i = 0; i < n_comp; i++) { - tv[0][i] = input[minColL][i]; - tv[1][i] = input[maxColL][i]; - tv[2][i] = input[minColR][i]; - tv[3][i] = input[maxColR][i]; - } - for (j1 = 0; j1 < 2; j1++) { - for (j2 = 2; j2 < 4; j2++) { - float e = 0.0F; - for (i = 0; i < n_comp; i++) { - e += (tv[j1][i] - tv[j2][i]) * (tv[j1][i] - tv[j2][i]); - } - if (e < err) { - err = e; - v1 = j1; - v2 = j2; - } - } - } - for (i = 0; i < n_comp; i++) { - vec[0][i] = tv[1 - v1][i]; - vec[1][i] = (tv[v1][i] * sumL + tv[v2][i] * sumR) / (sumL + sumR); - vec[2][i] = tv[5 - v2][i]; - } - } + nn_comp--; + } - /* left microtile */ - cc[0] = 0; - if (minColL != maxColL) { - /* compute interpolation vector */ - MAKEIVEC(n_vect, n_comp, iv, b, vec[0], vec[1]); + /* choose the common vector (yuck!) */ + { + int j1, j2; + int v1 = 0, v2 = 0; + float err = 1e9; /* big enough */ + float tv[2 * 2][MAX_COMP]; /* 2 extrema for each sub-block */ + for (i = 0; i < n_comp; i++) { + tv[0][i] = input[minColL][i]; + tv[1][i] = input[maxColL][i]; + tv[2][i] = input[minColR][i]; + tv[3][i] = input[maxColR][i]; + } + for (j1 = 0; j1 < 2; j1++) { + for (j2 = 2; j2 < 4; j2++) { + float e = 0.0F; + for (i = 0; i < n_comp; i++) { + e += (tv[j1][i] - tv[j2][i]) * (tv[j1][i] - tv[j2][i]); + } + if (e < err) { + err = e; + v1 = j1; + v2 = j2; + } + } + } + for (i = 0; i < n_comp; i++) { + vec[0][i] = tv[1 - v1][i]; + vec[1][i] = (tv[v1][i] * sumL + tv[v2][i] * sumR) / (sumL + sumR); + vec[2][i] = tv[5 - v2][i]; + } + } - /* add in texels */ - lolo = 0; - for (k = N_TEXELS / 2 - 1; k >= 0; k--) { - int texel; - /* interpolate color */ - CALCCDOT(texel, n_vect, n_comp, iv, b, input[k]); - /* add in texel */ - lolo <<= 2; - lolo |= texel; - } + /* left microtile */ + cc[0] = 0; + if (minColL != maxColL) { + /* compute interpolation vector */ + MAKEIVEC(n_vect, n_comp, iv, b, vec[0], vec[1]); - cc[0] = lolo; - } + /* add in texels */ + lolo = 0; + for (k = N_TEXELS / 2 - 1; k >= 0; k--) { + int texel; + /* interpolate color */ + CALCCDOT(texel, n_vect, n_comp, iv, b, input[k]); + /* add in texel */ + lolo <<= 2; + lolo |= texel; + } + + cc[0] = lolo; + } - /* right microtile */ - cc[1] = 0; - if (minColR != maxColR) { - /* compute interpolation vector */ - MAKEIVEC(n_vect, n_comp, iv, b, vec[2], vec[1]); + /* right microtile */ + cc[1] = 0; + if (minColR != maxColR) { + /* compute interpolation vector */ + MAKEIVEC(n_vect, n_comp, iv, b, vec[2], vec[1]); - /* add in texels */ - lohi = 0; - for (k = N_TEXELS - 1; k >= N_TEXELS / 2; k--) { - int texel; - /* interpolate color */ - CALCCDOT(texel, n_vect, n_comp, iv, b, input[k]); - /* add in texel */ - lohi <<= 2; - lohi |= texel; - } + /* add in texels */ + lohi = 0; + for (k = N_TEXELS - 1; k >= N_TEXELS / 2; k--) { + int texel; + /* interpolate color */ + CALCCDOT(texel, n_vect, n_comp, iv, b, input[k]); + /* add in texel */ + lohi <<= 2; + lohi |= texel; + } - cc[1] = lohi; - } + cc[1] = lohi; + } - Q_MOV32(hi, 7); /* alpha = "011" + lerp = 1 */ - for (j = n_vect - 1; j >= 0; j--) { - /* add in alphas */ - Q_SHL(hi, 5); - Q_OR32(hi, (dword)(vec[j][ACOMP] / 8.0F)); - } - for (j = n_vect - 1; j >= 0; j--) { - for (i = 0; i < n_comp - 1; i++) { - /* add in colors */ - Q_SHL(hi, 5); - Q_OR32(hi, (dword)(vec[j][i] / 8.0F)); - } - } - ((qword *)cc)[1] = hi; + Q_MOV32(hi, 7); /* alpha = "011" + lerp = 1 */ + for (j = n_vect - 1; j >= 0; j--) { + /* add in alphas */ + Q_SHL(hi, 5); + Q_OR32(hi, (dword)(vec[j][ACOMP] / 8.0F)); + } + for (j = n_vect - 1; j >= 0; j--) { + for (i = 0; i < n_comp - 1; i++) { + /* add in colors */ + Q_SHL(hi, 5); + Q_OR32(hi, (dword)(vec[j][i] / 8.0F)); + } + } + ((qword *)cc)[1] = hi; } static void fxt1_quantize_HI (dword *cc, - byte input[N_TEXELS][MAX_COMP], - byte reord[N_TEXELS][MAX_COMP], int n) + byte input[N_TEXELS][MAX_COMP], + byte reord[N_TEXELS][MAX_COMP], int n) { - const int n_vect = 6; /* highest vector number */ - const int n_comp = 3; /* 3 components: R, G, B */ - float b = 0.0F; /* phoudoin: silent compiler! */ - float iv[MAX_COMP]; /* interpolation vector */ - int i, k; - dword hihi; /* high quadword: hi dword */ + const int n_vect = 6; /* highest vector number */ + const int n_comp = 3; /* 3 components: R, G, B */ + float b = 0.0F; /* phoudoin: silent compiler! */ + float iv[MAX_COMP]; /* interpolation vector */ + int i, k; + dword hihi; /* high quadword: hi dword */ -#ifndef YUV - int minSum = 2000; /* big enough */ -#else - int minSum = 2000000; -#endif - int maxSum = -1; /* small enough */ - int minCol = 0; /* phoudoin: silent compiler! */ - int maxCol = 0; /* phoudoin: silent compiler! */ + int minSum = 2000; /* big enough */ + int maxSum = -1; /* small enough */ + int minCol = 0; /* phoudoin: silent compiler! */ + int maxCol = 0; /* phoudoin: silent compiler! */ - /* Our solution here is to find the darkest and brightest colors in - * the 8x4 tile and use those as the two representative colors. - * There are probably better algorithms to use (histogram-based). - */ - for (k = 0; k < n; k++) { - int sum = 0; -#ifndef YUV - for (i = 0; i < n_comp; i++) { - sum += reord[k][i]; - } -#else - sum = 299 * input[k][RCOMP] + 587 * input[k][GCOMP] + 114 * input[k][BCOMP]; -#endif - if (minSum > sum) { - minSum = sum; - minCol = k; - } - if (maxSum < sum) { - maxSum = sum; - maxCol = k; - } - } + /* Our solution here is to find the darkest and brightest colors in + * the 8x4 tile and use those as the two representative colors. + * There are probably better algorithms to use (histogram-based). + */ + for (k = 0; k < n; k++) { + int sum = 0; + for (i = 0; i < n_comp; i++) { + sum += reord[k][i]; + } + if (minSum > sum) { + minSum = sum; + minCol = k; + } + if (maxSum < sum) { + maxSum = sum; + maxCol = k; + } + } - hihi = 0; /* cc-hi = "00" */ - for (i = 0; i < n_comp; i++) { - /* add in colors */ - hihi <<= 5; - hihi |= reord[maxCol][i] >> 3; - } - for (i = 0; i < n_comp; i++) { - /* add in colors */ - hihi <<= 5; - hihi |= reord[minCol][i] >> 3; - } - cc[3] = hihi; - cc[0] = cc[1] = cc[2] = 0; + hihi = 0; /* cc-hi = "00" */ + for (i = 0; i < n_comp; i++) { + /* add in colors */ + hihi <<= 5; + hihi |= reord[maxCol][i] >> 3; + } + for (i = 0; i < n_comp; i++) { + /* add in colors */ + hihi <<= 5; + hihi |= reord[minCol][i] >> 3; + } + cc[3] = hihi; + cc[0] = cc[1] = cc[2] = 0; - /* compute interpolation vector */ - if (minCol != maxCol) { - MAKEIVEC(n_vect, n_comp, iv, b, reord[minCol], reord[maxCol]); - } + /* compute interpolation vector */ + if (minCol != maxCol) { + MAKEIVEC(n_vect, n_comp, iv, b, reord[minCol], reord[maxCol]); + } - /* add in texels */ - for (k = N_TEXELS - 1; k >= 0; k--) { - int t = k * 3; - dword *kk = (dword *)((byte *)cc + t / 8); - int texel = n_vect + 1; /* transparent black */ + /* add in texels */ + for (k = N_TEXELS - 1; k >= 0; k--) { + int t = k * 3; + dword *kk = (dword *)((char *)cc + t / 8); + int texel = n_vect + 1; /* transparent black */ - if (!ISTBLACK(input[k])) { - if (minCol != maxCol) { - /* interpolate color */ - CALCCDOT(texel, n_vect, n_comp, iv, b, input[k]); - /* add in texel */ - kk[0] |= texel << (t & 7); - } - } else { - /* add in texel */ - kk[0] |= texel << (t & 7); - } - } + if (!ISTBLACK(input[k])) { + if (minCol != maxCol) { + /* interpolate color */ + CALCCDOT(texel, n_vect, n_comp, iv, b, input[k]); + /* add in texel */ + kk[0] |= texel << (t & 7); + } + } else { + /* add in texel */ + kk[0] |= texel << (t & 7); + } + } } static void fxt1_quantize_MIXED1 (dword *cc, - byte input[N_TEXELS][MAX_COMP]) + byte input[N_TEXELS][MAX_COMP]) { - const int n_vect = 2; /* highest vector number in each microtile */ - const int n_comp = 3; /* 3 components: R, G, B */ - byte vec[2 * 2][MAX_COMP]; /* 2 extrema for each sub-block */ - float b, iv[MAX_COMP]; /* interpolation vector */ - int i, j, k; - qword hi; /* high quadword */ - dword lohi, lolo; /* low quadword: hi dword, lo dword */ + const int n_vect = 2; /* highest vector number in each microtile */ + const int n_comp = 3; /* 3 components: R, G, B */ + byte vec[2 * 2][MAX_COMP]; /* 2 extrema for each sub-block */ + float b, iv[MAX_COMP]; /* interpolation vector */ + int i, j, k; + qword hi; /* high quadword */ + dword lohi, lolo; /* low quadword: hi dword, lo dword */ - int minSum; - int maxSum; - int minColL = 0, maxColL = -1; - int minColR = 0, maxColR = -1; + int minSum; + int maxSum; + int minColL = 0, maxColL = -1; + int minColR = 0, maxColR = -1; - /* Our solution here is to find the darkest and brightest colors in - * the 4x4 tile and use those as the two representative colors. - * There are probably better algorithms to use (histogram-based). - */ -#ifndef YUV - minSum = 2000; /* big enough */ -#else - minSum = 2000000; -#endif - maxSum = -1; /* small enough */ - for (k = 0; k < N_TEXELS / 2; k++) { - if (!ISTBLACK(input[k])) { - int sum = 0; -#ifndef YUV - for (i = 0; i < n_comp; i++) { - sum += input[k][i]; - } -#else - sum = 299 * input[k][RCOMP] + 587 * input[k][GCOMP] + 114 * input[k][BCOMP]; -#endif - if (minSum > sum) { - minSum = sum; - minColL = k; - } - if (maxSum < sum) { - maxSum = sum; - maxColL = k; - } - } - } -#ifndef YUV - minSum = 2000; /* big enough */ -#else - minSum = 2000000; -#endif - maxSum = -1; /* small enough */ - for (; k < N_TEXELS; k++) { - if (!ISTBLACK(input[k])) { - int sum = 0; -#ifndef YUV - for (i = 0; i < n_comp; i++) { - sum += input[k][i]; - } -#else - sum = 299 * input[k][RCOMP] + 587 * input[k][GCOMP] + 114 * input[k][BCOMP]; -#endif - if (minSum > sum) { - minSum = sum; - minColR = k; - } - if (maxSum < sum) { - maxSum = sum; - maxColR = k; - } - } - } + /* Our solution here is to find the darkest and brightest colors in + * the 4x4 tile and use those as the two representative colors. + * There are probably better algorithms to use (histogram-based). + */ + minSum = 2000; /* big enough */ + maxSum = -1; /* small enough */ + for (k = 0; k < N_TEXELS / 2; k++) { + if (!ISTBLACK(input[k])) { + int sum = 0; + for (i = 0; i < n_comp; i++) { + sum += input[k][i]; + } + if (minSum > sum) { + minSum = sum; + minColL = k; + } + if (maxSum < sum) { + maxSum = sum; + maxColL = k; + } + } + } + minSum = 2000; /* big enough */ + maxSum = -1; /* small enough */ + for (; k < N_TEXELS; k++) { + if (!ISTBLACK(input[k])) { + int sum = 0; + for (i = 0; i < n_comp; i++) { + sum += input[k][i]; + } + if (minSum > sum) { + minSum = sum; + minColR = k; + } + if (maxSum < sum) { + maxSum = sum; + maxColR = k; + } + } + } - /* left microtile */ - if (maxColL == -1) { - /* all transparent black */ - cc[0] = 0xFFFFFFFF; - for (i = 0; i < n_comp; i++) { - vec[0][i] = 0; - vec[1][i] = 0; - } - } else { - cc[0] = 0; - for (i = 0; i < n_comp; i++) { - vec[0][i] = input[minColL][i]; - vec[1][i] = input[maxColL][i]; - } - if (minColL != maxColL) { - /* compute interpolation vector */ - MAKEIVEC(n_vect, n_comp, iv, b, vec[0], vec[1]); + /* left microtile */ + if (maxColL == -1) { + /* all transparent black */ + cc[0] = ~0u; + for (i = 0; i < n_comp; i++) { + vec[0][i] = 0; + vec[1][i] = 0; + } + } else { + cc[0] = 0; + for (i = 0; i < n_comp; i++) { + vec[0][i] = input[minColL][i]; + vec[1][i] = input[maxColL][i]; + } + if (minColL != maxColL) { + /* compute interpolation vector */ + MAKEIVEC(n_vect, n_comp, iv, b, vec[0], vec[1]); - /* add in texels */ - lolo = 0; - for (k = N_TEXELS / 2 - 1; k >= 0; k--) { - int texel = n_vect + 1; /* transparent black */ - if (!ISTBLACK(input[k])) { - /* interpolate color */ - CALCCDOT(texel, n_vect, n_comp, iv, b, input[k]); - } - /* add in texel */ - lolo <<= 2; - lolo |= texel; - } - cc[0] = lolo; - } - } + /* add in texels */ + lolo = 0; + for (k = N_TEXELS / 2 - 1; k >= 0; k--) { + int texel = n_vect + 1; /* transparent black */ + if (!ISTBLACK(input[k])) { + /* interpolate color */ + CALCCDOT(texel, n_vect, n_comp, iv, b, input[k]); + } + /* add in texel */ + lolo <<= 2; + lolo |= texel; + } + cc[0] = lolo; + } + } - /* right microtile */ - if (maxColR == -1) { - /* all transparent black */ - cc[1] = 0xFFFFFFFF; - for (i = 0; i < n_comp; i++) { - vec[2][i] = 0; - vec[3][i] = 0; - } - } else { - cc[1] = 0; - for (i = 0; i < n_comp; i++) { - vec[2][i] = input[minColR][i]; - vec[3][i] = input[maxColR][i]; - } - if (minColR != maxColR) { - /* compute interpolation vector */ - MAKEIVEC(n_vect, n_comp, iv, b, vec[2], vec[3]); + /* right microtile */ + if (maxColR == -1) { + /* all transparent black */ + cc[1] = ~0u; + for (i = 0; i < n_comp; i++) { + vec[2][i] = 0; + vec[3][i] = 0; + } + } else { + cc[1] = 0; + for (i = 0; i < n_comp; i++) { + vec[2][i] = input[minColR][i]; + vec[3][i] = input[maxColR][i]; + } + if (minColR != maxColR) { + /* compute interpolation vector */ + MAKEIVEC(n_vect, n_comp, iv, b, vec[2], vec[3]); - /* add in texels */ - lohi = 0; - for (k = N_TEXELS - 1; k >= N_TEXELS / 2; k--) { - int texel = n_vect + 1; /* transparent black */ - if (!ISTBLACK(input[k])) { - /* interpolate color */ - CALCCDOT(texel, n_vect, n_comp, iv, b, input[k]); - } - /* add in texel */ - lohi <<= 2; - lohi |= texel; - } - cc[1] = lohi; - } - } + /* add in texels */ + lohi = 0; + for (k = N_TEXELS - 1; k >= N_TEXELS / 2; k--) { + int texel = n_vect + 1; /* transparent black */ + if (!ISTBLACK(input[k])) { + /* interpolate color */ + CALCCDOT(texel, n_vect, n_comp, iv, b, input[k]); + } + /* add in texel */ + lohi <<= 2; + lohi |= texel; + } + cc[1] = lohi; + } + } - Q_MOV32(hi, 9 | (vec[3][GCOMP] & 4) | ((vec[1][GCOMP] >> 1) & 2)); /* chroma = "1" */ - for (j = 2 * 2 - 1; j >= 0; j--) { - for (i = 0; i < n_comp; i++) { - /* add in colors */ - Q_SHL(hi, 5); - Q_OR32(hi, vec[j][i] >> 3); - } - } - ((qword *)cc)[1] = hi; + Q_MOV32(hi, 9 | (vec[3][GCOMP] & 4) | ((vec[1][GCOMP] >> 1) & 2)); /* chroma = "1" */ + for (j = 2 * 2 - 1; j >= 0; j--) { + for (i = 0; i < n_comp; i++) { + /* add in colors */ + Q_SHL(hi, 5); + Q_OR32(hi, vec[j][i] >> 3); + } + } + ((qword *)cc)[1] = hi; } static void fxt1_quantize_MIXED0 (dword *cc, - byte input[N_TEXELS][MAX_COMP]) + byte input[N_TEXELS][MAX_COMP]) { - const int n_vect = 3; /* highest vector number in each microtile */ - const int n_comp = 3; /* 3 components: R, G, B */ - byte vec[2 * 2][MAX_COMP]; /* 2 extrema for each sub-block */ - float b, iv[MAX_COMP]; /* interpolation vector */ - int i, j, k; - qword hi; /* high quadword */ - dword lohi, lolo; /* low quadword: hi dword, lo dword */ + const int n_vect = 3; /* highest vector number in each microtile */ + const int n_comp = 3; /* 3 components: R, G, B */ + byte vec[2 * 2][MAX_COMP]; /* 2 extrema for each sub-block */ + float b, iv[MAX_COMP]; /* interpolation vector */ + int i, j, k; + qword hi; /* high quadword */ + dword lohi, lolo; /* low quadword: hi dword, lo dword */ - int minColL = 0, maxColL = 0; - int minColR = 0, maxColR = 0; + int minColL = 0, maxColL = 0; + int minColR = 0, maxColR = 0; #if 0 - int minSum; - int maxSum; + int minSum; + int maxSum; - /* Our solution here is to find the darkest and brightest colors in - * the 4x4 tile and use those as the two representative colors. - * There are probably better algorithms to use (histogram-based). - */ -#ifndef YUV - minSum = 2000; /* big enough */ + /* Our solution here is to find the darkest and brightest colors in + * the 4x4 tile and use those as the two representative colors. + * There are probably better algorithms to use (histogram-based). + */ + minSum = 2000; /* big enough */ + maxSum = -1; /* small enough */ + for (k = 0; k < N_TEXELS / 2; k++) { + int sum = 0; + for (i = 0; i < n_comp; i++) { + sum += input[k][i]; + } + if (minSum > sum) { + minSum = sum; + minColL = k; + } + if (maxSum < sum) { + maxSum = sum; + maxColL = k; + } + } + minSum = 2000; /* big enough */ + maxSum = -1; /* small enough */ + for (; k < N_TEXELS; k++) { + int sum = 0; + for (i = 0; i < n_comp; i++) { + sum += input[k][i]; + } + if (minSum > sum) { + minSum = sum; + minColR = k; + } + if (maxSum < sum) { + maxSum = sum; + maxColR = k; + } + } #else - minSum = 2000000; -#endif - maxSum = -1; /* small enough */ - for (k = 0; k < N_TEXELS / 2; k++) { - int sum = 0; -#ifndef YUV - for (i = 0; i < n_comp; i++) { - sum += input[k][i]; - } -#else - sum = 299 * input[k][RCOMP] + 587 * input[k][GCOMP] + 114 * input[k][BCOMP]; -#endif - if (minSum > sum) { - minSum = sum; - minColL = k; - } - if (maxSum < sum) { - maxSum = sum; - maxColL = k; - } - } - minSum = 2000; /* big enough */ - maxSum = -1; /* small enough */ - for (; k < N_TEXELS; k++) { - int sum = 0; -#ifndef YUV - for (i = 0; i < n_comp; i++) { - sum += input[k][i]; - } -#else - sum = 299 * input[k][RCOMP] + 587 * input[k][GCOMP] + 114 * input[k][BCOMP]; -#endif - if (minSum > sum) { - minSum = sum; - minColR = k; - } - if (maxSum < sum) { - maxSum = sum; - maxColR = k; - } - } -#else - int minVal; - int maxVal; - int maxVarL = fxt1_variance(NULL, input, n_comp, N_TEXELS / 2); - int maxVarR = fxt1_variance(NULL, &input[N_TEXELS / 2], n_comp, N_TEXELS / 2); + int minVal; + int maxVal; + int maxVarL = fxt1_variance(NULL, input, n_comp, N_TEXELS / 2); + int maxVarR = fxt1_variance(NULL, &input[N_TEXELS / 2], n_comp, N_TEXELS / 2); - /* Scan the channel with max variance for lo & hi - * and use those as the two representative colors. - */ - minVal = 2000; /* big enough */ - maxVal = -1; /* small enough */ - for (k = 0; k < N_TEXELS / 2; k++) { - int t = input[k][maxVarL]; - if (minVal > t) { - minVal = t; - minColL = k; - } - if (maxVal < t) { - maxVal = t; - maxColL = k; - } - } - minVal = 2000; /* big enough */ - maxVal = -1; /* small enough */ - for (; k < N_TEXELS; k++) { - int t = input[k][maxVarR]; - if (minVal > t) { - minVal = t; - minColR = k; - } - if (maxVal < t) { - maxVal = t; - maxColR = k; - } - } + /* Scan the channel with max variance for lo & hi + * and use those as the two representative colors. + */ + minVal = 2000; /* big enough */ + maxVal = -1; /* small enough */ + for (k = 0; k < N_TEXELS / 2; k++) { + int t = input[k][maxVarL]; + if (minVal > t) { + minVal = t; + minColL = k; + } + if (maxVal < t) { + maxVal = t; + maxColL = k; + } + } + minVal = 2000; /* big enough */ + maxVal = -1; /* small enough */ + for (; k < N_TEXELS; k++) { + int t = input[k][maxVarR]; + if (minVal > t) { + minVal = t; + minColR = k; + } + if (maxVal < t) { + maxVal = t; + maxColR = k; + } + } #endif - /* left microtile */ - cc[0] = 0; - for (i = 0; i < n_comp; i++) { - vec[0][i] = input[minColL][i]; - vec[1][i] = input[maxColL][i]; - } - if (minColL != maxColL) { - /* compute interpolation vector */ - MAKEIVEC(n_vect, n_comp, iv, b, vec[0], vec[1]); + /* left microtile */ + cc[0] = 0; + for (i = 0; i < n_comp; i++) { + vec[0][i] = input[minColL][i]; + vec[1][i] = input[maxColL][i]; + } + if (minColL != maxColL) { + /* compute interpolation vector */ + MAKEIVEC(n_vect, n_comp, iv, b, vec[0], vec[1]); - /* add in texels */ - lolo = 0; - for (k = N_TEXELS / 2 - 1; k >= 0; k--) { - int texel; - /* interpolate color */ - CALCCDOT(texel, n_vect, n_comp, iv, b, input[k]); - /* add in texel */ - lolo <<= 2; - lolo |= texel; - } + /* add in texels */ + lolo = 0; + for (k = N_TEXELS / 2 - 1; k >= 0; k--) { + int texel; + /* interpolate color */ + CALCCDOT(texel, n_vect, n_comp, iv, b, input[k]); + /* add in texel */ + lolo <<= 2; + lolo |= texel; + } - /* funky encoding for LSB of green */ - if ((int)((lolo >> 1) & 1) != (((vec[1][GCOMP] ^ vec[0][GCOMP]) >> 2) & 1)) { - for (i = 0; i < n_comp; i++) { - vec[1][i] = input[minColL][i]; - vec[0][i] = input[maxColL][i]; - } - lolo = ~lolo; - } + /* funky encoding for LSB of green */ + if ((int)((lolo >> 1) & 1) != (((vec[1][GCOMP] ^ vec[0][GCOMP]) >> 2) & 1)) { + for (i = 0; i < n_comp; i++) { + vec[1][i] = input[minColL][i]; + vec[0][i] = input[maxColL][i]; + } + lolo = ~lolo; + } + + cc[0] = lolo; + } - cc[0] = lolo; - } + /* right microtile */ + cc[1] = 0; + for (i = 0; i < n_comp; i++) { + vec[2][i] = input[minColR][i]; + vec[3][i] = input[maxColR][i]; + } + if (minColR != maxColR) { + /* compute interpolation vector */ + MAKEIVEC(n_vect, n_comp, iv, b, vec[2], vec[3]); - /* right microtile */ - cc[1] = 0; - for (i = 0; i < n_comp; i++) { - vec[2][i] = input[minColR][i]; - vec[3][i] = input[maxColR][i]; - } - if (minColR != maxColR) { - /* compute interpolation vector */ - MAKEIVEC(n_vect, n_comp, iv, b, vec[2], vec[3]); + /* add in texels */ + lohi = 0; + for (k = N_TEXELS - 1; k >= N_TEXELS / 2; k--) { + int texel; + /* interpolate color */ + CALCCDOT(texel, n_vect, n_comp, iv, b, input[k]); + /* add in texel */ + lohi <<= 2; + lohi |= texel; + } - /* add in texels */ - lohi = 0; - for (k = N_TEXELS - 1; k >= N_TEXELS / 2; k--) { - int texel; - /* interpolate color */ - CALCCDOT(texel, n_vect, n_comp, iv, b, input[k]); - /* add in texel */ - lohi <<= 2; - lohi |= texel; - } + /* funky encoding for LSB of green */ + if ((int)((lohi >> 1) & 1) != (((vec[3][GCOMP] ^ vec[2][GCOMP]) >> 2) & 1)) { + for (i = 0; i < n_comp; i++) { + vec[3][i] = input[minColR][i]; + vec[2][i] = input[maxColR][i]; + } + lohi = ~lohi; + } - /* funky encoding for LSB of green */ - if ((int)((lohi >> 1) & 1) != (((vec[3][GCOMP] ^ vec[2][GCOMP]) >> 2) & 1)) { - for (i = 0; i < n_comp; i++) { - vec[3][i] = input[minColR][i]; - vec[2][i] = input[maxColR][i]; - } - lohi = ~lohi; - } + cc[1] = lohi; + } - cc[1] = lohi; - } - - Q_MOV32(hi, 8 | (vec[3][GCOMP] & 4) | ((vec[1][GCOMP] >> 1) & 2)); /* chroma = "1" */ - for (j = 2 * 2 - 1; j >= 0; j--) { - for (i = 0; i < n_comp; i++) { - /* add in colors */ - Q_SHL(hi, 5); - Q_OR32(hi, vec[j][i] >> 3); - } - } - ((qword *)cc)[1] = hi; + Q_MOV32(hi, 8 | (vec[3][GCOMP] & 4) | ((vec[1][GCOMP] >> 1) & 2)); /* chroma = "1" */ + for (j = 2 * 2 - 1; j >= 0; j--) { + for (i = 0; i < n_comp; i++) { + /* add in colors */ + Q_SHL(hi, 5); + Q_OR32(hi, vec[j][i] >> 3); + } + } + ((qword *)cc)[1] = hi; } static void fxt1_quantize (dword *cc, const byte *lines[], int comps) { - int trualpha; - byte reord[N_TEXELS][MAX_COMP]; + int trualpha; + byte reord[N_TEXELS][MAX_COMP]; - byte input[N_TEXELS][MAX_COMP]; -#ifndef ARGB - int i; -#endif - int k, l; + byte input[N_TEXELS][MAX_COMP]; + int i, k, l; - if (comps == 3) { - /* make the whole block opaque */ - memset(input, -1, sizeof(input)); - } + if (comps == 3) { + /* make the whole block opaque */ + memset(input, -1, sizeof(input)); + } - /* 8 texels each line */ -#ifndef ARGB - for (l = 0; l < 4; l++) { - for (k = 0; k < 4; k++) { - for (i = 0; i < comps; i++) { - input[k + l * 4][i] = *lines[l]++; - } - } - for (; k < 8; k++) { - for (i = 0; i < comps; i++) { - input[k + l * 4 + 12][i] = *lines[l]++; - } - } - } -#else - /* H.Morii - support for ARGB inputs */ - for (l = 0; l < 4; l++) { - for (k = 0; k < 4; k++) { - input[k + l * 4][2] = *lines[l]++; - input[k + l * 4][1] = *lines[l]++; - input[k + l * 4][0] = *lines[l]++; - if (comps == 4) input[k + l * 4][3] = *lines[l]++; - } - for (; k < 8; k++) { - input[k + l * 4 + 12][2] = *lines[l]++; - input[k + l * 4 + 12][1] = *lines[l]++; - input[k + l * 4 + 12][0] = *lines[l]++; - if (comps == 4) input[k + l * 4 + 12][3] = *lines[l]++; - } - } -#endif + /* 8 texels each line */ + for (l = 0; l < 4; l++) { + for (k = 0; k < 4; k++) { + for (i = 0; i < comps; i++) { + input[k + l * 4][i] = *lines[l]++; + } + } + for (; k < 8; k++) { + for (i = 0; i < comps; i++) { + input[k + l * 4 + 12][i] = *lines[l]++; + } + } + } - /* block layout: - * 00, 01, 02, 03, 08, 09, 0a, 0b - * 10, 11, 12, 13, 18, 19, 1a, 1b - * 04, 05, 06, 07, 0c, 0d, 0e, 0f - * 14, 15, 16, 17, 1c, 1d, 1e, 1f - */ + /* block layout: + * 00, 01, 02, 03, 08, 09, 0a, 0b + * 10, 11, 12, 13, 18, 19, 1a, 1b + * 04, 05, 06, 07, 0c, 0d, 0e, 0f + * 14, 15, 16, 17, 1c, 1d, 1e, 1f + */ - /* [dBorca] - * stupidity flows forth from this - */ - l = N_TEXELS; - trualpha = 0; - if (comps == 4) { - /* skip all transparent black texels */ - l = 0; - for (k = 0; k < N_TEXELS; k++) { - /* test all components against 0 */ - if (!ISTBLACK(input[k])) { - /* texel is not transparent black */ - COPY_4UBV(reord[l], input[k]); - if (reord[l][ACOMP] < (255 - ALPHA_TS)) { - /* non-opaque texel */ - trualpha = !0; - } - l++; - } - } - } + /* [dBorca] + * stupidity flows forth from this + */ + l = N_TEXELS; + trualpha = 0; + if (comps == 4) { + /* skip all transparent black texels */ + l = 0; + for (k = 0; k < N_TEXELS; k++) { + /* test all components against 0 */ + if (!ISTBLACK(input[k])) { + /* texel is not transparent black */ + COPY_4UBV(reord[l], input[k]); + if (reord[l][ACOMP] < (255 - ALPHA_TS)) { + /* non-opaque texel */ + trualpha = !0; + } + l++; + } + } + } #if 0 - if (trualpha) { - fxt1_quantize_ALPHA0(cc, input, reord, l); - } else if (l == 0) { - cc[0] = cc[1] = cc[2] = -1; - cc[3] = 0; - } else if (l < N_TEXELS) { - fxt1_quantize_HI(cc, input, reord, l); - } else { - fxt1_quantize_CHROMA(cc, input); - } - (void)fxt1_quantize_ALPHA1; - (void)fxt1_quantize_MIXED1; - (void)fxt1_quantize_MIXED0; + if (trualpha) { + fxt1_quantize_ALPHA0(cc, input, reord, l); + } else if (l == 0) { + cc[0] = cc[1] = cc[2] = -1; + cc[3] = 0; + } else if (l < N_TEXELS) { + fxt1_quantize_HI(cc, input, reord, l); + } else { + fxt1_quantize_CHROMA(cc, input); + } + (void)fxt1_quantize_ALPHA1; + (void)fxt1_quantize_MIXED1; + (void)fxt1_quantize_MIXED0; #else - if (trualpha) { - fxt1_quantize_ALPHA1(cc, input); - } else if (l == 0) { - cc[0] = cc[1] = cc[2] = 0xFFFFFFFF; - cc[3] = 0; - } else if (l < N_TEXELS) { - fxt1_quantize_MIXED1(cc, input); - } else { - fxt1_quantize_MIXED0(cc, input); - } - (void)fxt1_quantize_ALPHA0; - (void)fxt1_quantize_HI; - (void)fxt1_quantize_CHROMA; + if (trualpha) { + fxt1_quantize_ALPHA1(cc, input); + } else if (l == 0) { + cc[0] = cc[1] = cc[2] = ~0u; + cc[3] = 0; + } else if (l < N_TEXELS) { + fxt1_quantize_MIXED1(cc, input); + } else { + fxt1_quantize_MIXED0(cc, input); + } + (void)fxt1_quantize_ALPHA0; + (void)fxt1_quantize_HI; + (void)fxt1_quantize_CHROMA; #endif } -TAPI int TAPIENTRY -fxt1_encode (int width, int height, int comps, - const void *source, int srcRowStride, - void *dest, int destRowStride) + +/** + * Upscale an image by replication, not (typical) stretching. + * We use this when the image width or height is less than a + * certain size (4, 8) and we need to upscale an image. + */ +static void +upscale_teximage2d(int inWidth, int inHeight, + int outWidth, int outHeight, + int comps, const byte *src, int srcRowStride, + byte *dest ) { - int x, y; - const byte *data; - dword *encoded = (dword *)dest; - void *newSource = NULL; + int i, j, k; - /* Replicate image if width is not M8 or height is not M4 */ - if ((width & 7) | (height & 3)) { - int newWidth = (width + 7) & ~7; - int newHeight = (height + 3) & ~3; - newSource = malloc(comps * newWidth * newHeight * sizeof(byte *)); - _mesa_upscale_teximage2d(width, height, newWidth, newHeight, - comps, (const byte *)source, - srcRowStride, (byte *)newSource); - source = newSource; - width = newWidth; - height = newHeight; - srcRowStride = comps * newWidth; - } + assert(outWidth >= inWidth); + assert(outHeight >= inHeight); +#if 0 + ASSERT(inWidth == 1 || inWidth == 2 || inHeight == 1 || inHeight == 2); + ASSERT((outWidth & 3) == 0); + ASSERT((outHeight & 3) == 0); +#endif - data = (const byte *)source; - destRowStride = (destRowStride - width * 2) / 4; - for (y = 0; y < height; y += 4) { - unsigned int offs = 0 + (y + 0) * srcRowStride; - for (x = 0; x < width; x += 8) { - const byte *lines[4]; - lines[0] = &data[offs]; - lines[1] = lines[0] + srcRowStride; - lines[2] = lines[1] + srcRowStride; - lines[3] = lines[2] + srcRowStride; - offs += 8 * comps; - fxt1_quantize(encoded, lines, comps); - /* 128 bits per 8x4 block */ - encoded += 4; - } - encoded += destRowStride; - } + for (i = 0; i < outHeight; i++) { + const int ii = i % inHeight; + for (j = 0; j < outWidth; j++) { + const int jj = j % inWidth; + for (k = 0; k < comps; k++) { + dest[(i * outWidth + j) * comps + k] + = src[ii * srcRowStride + jj * comps + k]; + } + } + } +} - if (newSource != NULL) { - free(newSource); - } +TAPI void TAPIENTRY +fxt1_encode (dword width, dword height, int comps, + const void *source, int srcRowStride, + void *dest, int destRowStride) +{ + dword x, y; + const byte *data; + dword *encoded = (dword *)dest; + void *newSource = NULL, *newSourcetmp = NULL; - return 0; + assert(comps == 3 || comps == 4); + + if (comps == 3) + newSource = reorder_source_3_alloc(source, width, height, srcRowStride); + if (comps == 4) + newSource = reorder_source_4_alloc(source, width, height, srcRowStride); + if (!newSource) + goto cleanUp; + source = newSource; + + /* Replicate image if width is not M8 or height is not M4 */ + if ((width & 7) | (height & 3)) { + int newWidth = (width + 7) & ~7; + int newHeight = (height + 3) & ~3; + newSourcetmp = malloc(comps * newWidth * newHeight * sizeof(byte)); + free(newSource); + newSource = newSourcetmp; + if (!newSource) { + goto cleanUp; + } + upscale_teximage2d(width, height, newWidth, newHeight, + comps, (const byte *) source, + srcRowStride, (byte *) newSource); + source = newSource; + width = newWidth; + height = newHeight; + srcRowStride = comps * newWidth; + } + + data = (const byte *) source; + destRowStride = (destRowStride - width * 2) / 4; + for (y = 0; y < height; y += 4) { + dword offs = 0 + (y + 0) * srcRowStride; + for (x = 0; x < width; x += 8) { + const byte *lines[4]; + lines[0] = &data[offs]; + lines[1] = lines[0] + srcRowStride; + lines[2] = lines[1] + srcRowStride; + lines[3] = lines[2] + srcRowStride; + offs += 8 * comps; + fxt1_quantize(encoded, lines, comps); + /* 128 bits per 8x4 block */ + encoded += 4; + } + encoded += destRowStride; + } + + cleanUp: + free(newSource); } @@ -1183,22 +1156,22 @@ fxt1_encode (int width, int height, int comps, /* lookup table for scaling 5 bit colors up to 8 bits */ static const byte _rgb_scale_5[] = { - 0, 8, 16, 25, 33, 41, 49, 58, - 66, 74, 82, 90, 99, 107, 115, 123, - 132, 140, 148, 156, 165, 173, 181, 189, - 197, 206, 214, 222, 230, 239, 247, 255 + 0, 8, 16, 25, 33, 41, 49, 58, + 66, 74, 82, 90, 99, 107, 115, 123, + 132, 140, 148, 156, 165, 173, 181, 189, + 197, 206, 214, 222, 230, 239, 247, 255 }; /* lookup table for scaling 6 bit colors up to 8 bits */ static const byte _rgb_scale_6[] = { - 0, 4, 8, 12, 16, 20, 24, 28, - 32, 36, 40, 45, 49, 53, 57, 61, - 65, 69, 73, 77, 81, 85, 89, 93, - 97, 101, 105, 109, 113, 117, 121, 125, - 130, 134, 138, 142, 146, 150, 154, 158, - 162, 166, 170, 174, 178, 182, 186, 190, - 194, 198, 202, 206, 210, 215, 219, 223, - 227, 231, 235, 239, 243, 247, 251, 255 + 0, 4, 8, 12, 16, 20, 24, 28, + 32, 36, 40, 45, 49, 53, 57, 61, + 65, 69, 73, 77, 81, 85, 89, 93, + 97, 101, 105, 109, 113, 117, 121, 125, + 130, 134, 138, 142, 146, 150, 154, 158, + 162, 166, 170, 174, 178, 182, 186, 190, + 194, 198, 202, 206, 210, 215, 219, 223, + 227, 231, 235, 239, 243, 247, 251, 255 }; @@ -1206,254 +1179,251 @@ static const byte _rgb_scale_6[] = { #define UP5(c) _rgb_scale_5[(c) & 31] #define UP6(c, b) _rgb_scale_6[(((c) & 31) << 1) | ((b) & 1)] #define LERP(n, t, c0, c1) (((n) - (t)) * (c0) + (t) * (c1) + (n) / 2) / (n) -#define ZERO_4UBV(v) *((dword *)(v)) = 0 static void fxt1_decode_1HI (const byte *code, int t, byte *rgba) { - const dword *cc; + const dword *cc; - t *= 3; - cc = (const dword *)(code + t / 8); - t = (cc[0] >> (t & 7)) & 7; + t *= 3; + cc = (const dword *)(code + t / 8); + t = (cc[0] >> (t & 7)) & 7; - if (t == 7) { - ZERO_4UBV(rgba); - } else { - cc = (const dword *)(code + 12); - if (t == 0) { - rgba[BCOMP] = UP5(CC_SEL(cc, 0)); - rgba[GCOMP] = UP5(CC_SEL(cc, 5)); - rgba[RCOMP] = UP5(CC_SEL(cc, 10)); - } else if (t == 6) { - rgba[BCOMP] = UP5(CC_SEL(cc, 15)); - rgba[GCOMP] = UP5(CC_SEL(cc, 20)); - rgba[RCOMP] = UP5(CC_SEL(cc, 25)); - } else { - rgba[BCOMP] = LERP(6, t, UP5(CC_SEL(cc, 0)), UP5(CC_SEL(cc, 15))); - rgba[GCOMP] = LERP(6, t, UP5(CC_SEL(cc, 5)), UP5(CC_SEL(cc, 20))); - rgba[RCOMP] = LERP(6, t, UP5(CC_SEL(cc, 10)), UP5(CC_SEL(cc, 25))); - } - rgba[ACOMP] = 255; - } + if (t == 7) { + rgba[RCOMP] = rgba[GCOMP] = rgba[BCOMP] = rgba[ACOMP] = 0; + } else { + byte r, g, b; + cc = (const dword *)(code + 12); + if (t == 0) { + b = UP5(CC_SEL(cc, 0)); + g = UP5(CC_SEL(cc, 5)); + r = UP5(CC_SEL(cc, 10)); + } else if (t == 6) { + b = UP5(CC_SEL(cc, 15)); + g = UP5(CC_SEL(cc, 20)); + r = UP5(CC_SEL(cc, 25)); + } else { + b = LERP(6, t, UP5(CC_SEL(cc, 0)), UP5(CC_SEL(cc, 15))); + g = LERP(6, t, UP5(CC_SEL(cc, 5)), UP5(CC_SEL(cc, 20))); + r = LERP(6, t, UP5(CC_SEL(cc, 10)), UP5(CC_SEL(cc, 25))); + } + rgba[RCOMP] = r; + rgba[GCOMP] = g; + rgba[BCOMP] = b; + rgba[ACOMP] = 255; + } } static void fxt1_decode_1CHROMA (const byte *code, int t, byte *rgba) { - const dword *cc; - dword kk; + const dword *cc; + dword kk; - cc = (const dword *)code; - if (t & 16) { - cc++; - t &= 15; - } - t = (cc[0] >> (t * 2)) & 3; + cc = (const dword *)code; + if (t & 16) { + cc++; + t &= 15; + } + t = (cc[0] >> (t * 2)) & 3; - t *= 15; - cc = (const dword *)(code + 8 + t / 8); - kk = cc[0] >> (t & 7); - rgba[BCOMP] = UP5(kk); - rgba[GCOMP] = UP5(kk >> 5); - rgba[RCOMP] = UP5(kk >> 10); - rgba[ACOMP] = 255; + t *= 15; + cc = (const dword *)(code + 8 + t / 8); + kk = cc[0] >> (t & 7); + rgba[BCOMP] = UP5(kk); + rgba[GCOMP] = UP5(kk >> 5); + rgba[RCOMP] = UP5(kk >> 10); + rgba[ACOMP] = 255; } static void fxt1_decode_1MIXED (const byte *code, int t, byte *rgba) { - const dword *cc; - int col[2][3]; - int glsb, selb; + const dword *cc; + dword col[2][3]; + int glsb, selb; - cc = (const dword *)code; - if (t & 16) { - t &= 15; - t = (cc[1] >> (t * 2)) & 3; - /* col 2 */ - col[0][BCOMP] = (*(const dword *)(code + 11)) >> 6; - col[0][GCOMP] = CC_SEL(cc, 99); - col[0][RCOMP] = CC_SEL(cc, 104); - /* col 3 */ - col[1][BCOMP] = CC_SEL(cc, 109); - col[1][GCOMP] = CC_SEL(cc, 114); - col[1][RCOMP] = CC_SEL(cc, 119); - glsb = CC_SEL(cc, 126); - selb = CC_SEL(cc, 33); - } else { - t = (cc[0] >> (t * 2)) & 3; - /* col 0 */ - col[0][BCOMP] = CC_SEL(cc, 64); - col[0][GCOMP] = CC_SEL(cc, 69); - col[0][RCOMP] = CC_SEL(cc, 74); - /* col 1 */ - col[1][BCOMP] = CC_SEL(cc, 79); - col[1][GCOMP] = CC_SEL(cc, 84); - col[1][RCOMP] = CC_SEL(cc, 89); - glsb = CC_SEL(cc, 125); - selb = CC_SEL(cc, 1); - } + cc = (const dword *)code; + if (t & 16) { + t &= 15; + t = (cc[1] >> (t * 2)) & 3; + /* col 2 */ + col[0][BCOMP] = (*(const dword *)(code + 11)) >> 6; + col[0][GCOMP] = CC_SEL(cc, 99); + col[0][RCOMP] = CC_SEL(cc, 104); + /* col 3 */ + col[1][BCOMP] = CC_SEL(cc, 109); + col[1][GCOMP] = CC_SEL(cc, 114); + col[1][RCOMP] = CC_SEL(cc, 119); + glsb = CC_SEL(cc, 126); + selb = CC_SEL(cc, 33); + } else { + t = (cc[0] >> (t * 2)) & 3; + /* col 0 */ + col[0][BCOMP] = CC_SEL(cc, 64); + col[0][GCOMP] = CC_SEL(cc, 69); + col[0][RCOMP] = CC_SEL(cc, 74); + /* col 1 */ + col[1][BCOMP] = CC_SEL(cc, 79); + col[1][GCOMP] = CC_SEL(cc, 84); + col[1][RCOMP] = CC_SEL(cc, 89); + glsb = CC_SEL(cc, 125); + selb = CC_SEL(cc, 1); + } - if (CC_SEL(cc, 124) & 1) { - /* alpha[0] == 1 */ + if (CC_SEL(cc, 124) & 1) { + /* alpha[0] == 1 */ - if (t == 3) { - ZERO_4UBV(rgba); - } else { - if (t == 0) { - rgba[BCOMP] = UP5(col[0][BCOMP]); - rgba[GCOMP] = UP5(col[0][GCOMP]); - rgba[RCOMP] = UP5(col[0][RCOMP]); - } else if (t == 2) { - rgba[BCOMP] = UP5(col[1][BCOMP]); - rgba[GCOMP] = UP6(col[1][GCOMP], glsb); - rgba[RCOMP] = UP5(col[1][RCOMP]); - } else { - rgba[BCOMP] = (UP5(col[0][BCOMP]) + UP5(col[1][BCOMP])) / 2; - rgba[GCOMP] = (UP5(col[0][GCOMP]) + UP6(col[1][GCOMP], glsb)) / 2; - rgba[RCOMP] = (UP5(col[0][RCOMP]) + UP5(col[1][RCOMP])) / 2; - } - rgba[ACOMP] = 255; - } - } else { - /* alpha[0] == 0 */ - - if (t == 0) { - rgba[BCOMP] = UP5(col[0][BCOMP]); - rgba[GCOMP] = UP6(col[0][GCOMP], glsb ^ selb); - rgba[RCOMP] = UP5(col[0][RCOMP]); - } else if (t == 3) { - rgba[BCOMP] = UP5(col[1][BCOMP]); - rgba[GCOMP] = UP6(col[1][GCOMP], glsb); - rgba[RCOMP] = UP5(col[1][RCOMP]); - } else { - rgba[BCOMP] = LERP(3, t, UP5(col[0][BCOMP]), UP5(col[1][BCOMP])); - rgba[GCOMP] = LERP(3, t, UP6(col[0][GCOMP], glsb ^ selb), - UP6(col[1][GCOMP], glsb)); - rgba[RCOMP] = LERP(3, t, UP5(col[0][RCOMP]), UP5(col[1][RCOMP])); - } - rgba[ACOMP] = 255; - } + if (t == 3) { + /* zero */ + rgba[RCOMP] = rgba[BCOMP] = rgba[GCOMP] = rgba[ACOMP] = 0; + } else { + byte r, g, b; + if (t == 0) { + b = UP5(col[0][BCOMP]); + g = UP5(col[0][GCOMP]); + r = UP5(col[0][RCOMP]); + } else if (t == 2) { + b = UP5(col[1][BCOMP]); + g = UP6(col[1][GCOMP], glsb); + r = UP5(col[1][RCOMP]); + } else { + b = (UP5(col[0][BCOMP]) + UP5(col[1][BCOMP])) / 2; + g = (UP5(col[0][GCOMP]) + UP6(col[1][GCOMP], glsb)) / 2; + r = (UP5(col[0][RCOMP]) + UP5(col[1][RCOMP])) / 2; + } + rgba[RCOMP] = r; + rgba[GCOMP] = g; + rgba[BCOMP] = b; + rgba[ACOMP] = 255; + } + } else { + /* alpha[0] == 0 */ + byte r, g, b; + if (t == 0) { + b = UP5(col[0][BCOMP]); + g = UP6(col[0][GCOMP], glsb ^ selb); + r = UP5(col[0][RCOMP]); + } else if (t == 3) { + b = UP5(col[1][BCOMP]); + g = UP6(col[1][GCOMP], glsb); + r = UP5(col[1][RCOMP]); + } else { + b = LERP(3, t, UP5(col[0][BCOMP]), UP5(col[1][BCOMP])); + g = LERP(3, t, UP6(col[0][GCOMP], glsb ^ selb), + UP6(col[1][GCOMP], glsb)); + r = LERP(3, t, UP5(col[0][RCOMP]), UP5(col[1][RCOMP])); + } + rgba[RCOMP] = r; + rgba[GCOMP] = g; + rgba[BCOMP] = b; + rgba[ACOMP] = 255; + } } static void fxt1_decode_1ALPHA (const byte *code, int t, byte *rgba) { - const dword *cc; + const dword *cc; + byte r, g, b, a; - cc = (const dword *)code; - if (CC_SEL(cc, 124) & 1) { - /* lerp == 1 */ - int col0[4]; + cc = (const dword *)code; + if (CC_SEL(cc, 124) & 1) { + /* lerp == 1 */ + dword col0[4]; - if (t & 16) { - t &= 15; - t = (cc[1] >> (t * 2)) & 3; - /* col 2 */ - col0[BCOMP] = (*(const dword *)(code + 11)) >> 6; - col0[GCOMP] = CC_SEL(cc, 99); - col0[RCOMP] = CC_SEL(cc, 104); - col0[ACOMP] = CC_SEL(cc, 119); - } else { - t = (cc[0] >> (t * 2)) & 3; - /* col 0 */ - col0[BCOMP] = CC_SEL(cc, 64); - col0[GCOMP] = CC_SEL(cc, 69); - col0[RCOMP] = CC_SEL(cc, 74); - col0[ACOMP] = CC_SEL(cc, 109); - } + if (t & 16) { + t &= 15; + t = (cc[1] >> (t * 2)) & 3; + /* col 2 */ + col0[BCOMP] = (*(const dword *)(code + 11)) >> 6; + col0[GCOMP] = CC_SEL(cc, 99); + col0[RCOMP] = CC_SEL(cc, 104); + col0[ACOMP] = CC_SEL(cc, 119); + } else { + t = (cc[0] >> (t * 2)) & 3; + /* col 0 */ + col0[BCOMP] = CC_SEL(cc, 64); + col0[GCOMP] = CC_SEL(cc, 69); + col0[RCOMP] = CC_SEL(cc, 74); + col0[ACOMP] = CC_SEL(cc, 109); + } - if (t == 0) { - rgba[BCOMP] = UP5(col0[BCOMP]); - rgba[GCOMP] = UP5(col0[GCOMP]); - rgba[RCOMP] = UP5(col0[RCOMP]); - rgba[ACOMP] = UP5(col0[ACOMP]); - } else if (t == 3) { - rgba[BCOMP] = UP5(CC_SEL(cc, 79)); - rgba[GCOMP] = UP5(CC_SEL(cc, 84)); - rgba[RCOMP] = UP5(CC_SEL(cc, 89)); - rgba[ACOMP] = UP5(CC_SEL(cc, 114)); - } else { - rgba[BCOMP] = LERP(3, t, UP5(col0[BCOMP]), UP5(CC_SEL(cc, 79))); - rgba[GCOMP] = LERP(3, t, UP5(col0[GCOMP]), UP5(CC_SEL(cc, 84))); - rgba[RCOMP] = LERP(3, t, UP5(col0[RCOMP]), UP5(CC_SEL(cc, 89))); - rgba[ACOMP] = LERP(3, t, UP5(col0[ACOMP]), UP5(CC_SEL(cc, 114))); - } - } else { - /* lerp == 0 */ + if (t == 0) { + b = UP5(col0[BCOMP]); + g = UP5(col0[GCOMP]); + r = UP5(col0[RCOMP]); + a = UP5(col0[ACOMP]); + } else if (t == 3) { + b = UP5(CC_SEL(cc, 79)); + g = UP5(CC_SEL(cc, 84)); + r = UP5(CC_SEL(cc, 89)); + a = UP5(CC_SEL(cc, 114)); + } else { + b = LERP(3, t, UP5(col0[BCOMP]), UP5(CC_SEL(cc, 79))); + g = LERP(3, t, UP5(col0[GCOMP]), UP5(CC_SEL(cc, 84))); + r = LERP(3, t, UP5(col0[RCOMP]), UP5(CC_SEL(cc, 89))); + a = LERP(3, t, UP5(col0[ACOMP]), UP5(CC_SEL(cc, 114))); + } + } else { + /* lerp == 0 */ - if (t & 16) { - cc++; - t &= 15; - } - t = (cc[0] >> (t * 2)) & 3; + if (t & 16) { + cc++; + t &= 15; + } + t = (cc[0] >> (t * 2)) & 3; - if (t == 3) { - ZERO_4UBV(rgba); - } else { - dword kk; - cc = (const dword *)code; - rgba[ACOMP] = UP5(cc[3] >> (t * 5 + 13)); - t *= 15; - cc = (const dword *)(code + 8 + t / 8); - kk = cc[0] >> (t & 7); - rgba[BCOMP] = UP5(kk); - rgba[GCOMP] = UP5(kk >> 5); - rgba[RCOMP] = UP5(kk >> 10); - } - } + if (t == 3) { + /* zero */ + r = g = b = a = 0; + } else { + dword kk; + cc = (const dword *)code; + a = UP5(cc[3] >> (t * 5 + 13)); + t *= 15; + cc = (const dword *)(code + 8 + t / 8); + kk = cc[0] >> (t & 7); + b = UP5(kk); + g = UP5(kk >> 5); + r = UP5(kk >> 10); + } + } + rgba[RCOMP] = r; + rgba[GCOMP] = g; + rgba[BCOMP] = b; + rgba[ACOMP] = a; } TAPI void TAPIENTRY -fxt1_decode_1 (const void *texture, int stride, - int i, int j, byte *rgba) +fxt1_decode_1 (const void *texture, int stride, /* in pixels */ + int i, int j, byte *rgba) { - static void (*decode_1[]) (const byte *, int, byte *) = { - fxt1_decode_1HI, /* cc-high = "00?" */ - fxt1_decode_1HI, /* cc-high = "00?" */ - fxt1_decode_1CHROMA, /* cc-chroma = "010" */ - fxt1_decode_1ALPHA, /* alpha = "011" */ - fxt1_decode_1MIXED, /* mixed = "1??" */ - fxt1_decode_1MIXED, /* mixed = "1??" */ - fxt1_decode_1MIXED, /* mixed = "1??" */ - fxt1_decode_1MIXED /* mixed = "1??" */ - }; + static void (*decode_1[]) (const byte *, int, byte *) = { + fxt1_decode_1HI, /* cc-high = "00?" */ + fxt1_decode_1HI, /* cc-high = "00?" */ + fxt1_decode_1CHROMA, /* cc-chroma = "010" */ + fxt1_decode_1ALPHA, /* alpha = "011" */ + fxt1_decode_1MIXED, /* mixed = "1??" */ + fxt1_decode_1MIXED, /* mixed = "1??" */ + fxt1_decode_1MIXED, /* mixed = "1??" */ + fxt1_decode_1MIXED /* mixed = "1??" */ + }; - const byte *code = (const byte *)texture + - ((j / 4) * (stride / 8) + (i / 8)) * 16; - int mode = CC_SEL(code, 125); - int t = i & 7; + const byte *code = (const byte *)texture + + ((j / 4) * (stride / 8) + (i / 8)) * 16; + int mode = CC_SEL(code, 125); + int t = i & 7; - if (t & 4) { - t += 12; - } - t += (j & 3) * 4; + if (t & 4) { + t += 12; + } + t += (j & 3) * 4; - decode_1[mode](code, t, rgba); - -#if VERBOSE - { - extern int cc_chroma; - extern int cc_alpha; - extern int cc_high; - extern int cc_mixed; - static int *cctype[] = { - &cc_high, - &cc_high, - &cc_chroma, - &cc_alpha, - &cc_mixed, - &cc_mixed, - &cc_mixed, - &cc_mixed - }; - (*cctype[mode])++; - } -#endif + decode_1[mode](code, t, rgba); } diff --git a/src/GlideHQ/tc-1.1+/fxt1.h b/src/GlideHQ/tc-1.1+/fxt1.h index c2919bbac08187f408002af43b9b6d1873a1e19a..b1fe32cbbc6902fa6ed70fbd9e55e95c663944e6 100644 --- a/src/GlideHQ/tc-1.1+/fxt1.h +++ b/src/GlideHQ/tc-1.1+/fxt1.h @@ -26,13 +26,13 @@ #ifndef FXT1_H_included #define FXT1_H_included -TAPI int TAPIENTRY -fxt1_encode (int width, int height, int comps, +TAPI void TAPIENTRY +fxt1_encode (unsigned int width, unsigned int height, int comps, const void *source, int srcRowStride, void *dest, int destRowStride); TAPI void TAPIENTRY -fxt1_decode_1 (const void *texture, int stride /* in pixels */, - int i, int j, byte *rgba); +fxt1_decode_1 (const void *texture, int stride, + int i, int j, byte *rgba); #endif diff --git a/src/GlideHQ/tc-1.1+/internal.h b/src/GlideHQ/tc-1.1+/internal.h index f1cd6dca9285ef659cc283e4a07bdb705bedfc9a..3bb5fa59cc817dce4d1ef0ddec02b625ab288728 100644 --- a/src/GlideHQ/tc-1.1+/internal.h +++ b/src/GlideHQ/tc-1.1+/internal.h @@ -23,6 +23,8 @@ #ifndef INTERNAL_H_included #define INTERNAL_H_included +#include + /*****************************************************************************\ * DLL stuff \*****************************************************************************/ @@ -40,34 +42,42 @@ * 64bit types on 32bit machine \*****************************************************************************/ -#if (defined(__GNUC__) && !defined(__cplusplus)) || defined(__MSC__) +/* + * Define a 64-bit unsigned integer type and macros + */ +#if 1 -typedef unsigned long long qword; +#define Q_NATIVE 1 + +typedef uint64_t qword; #define Q_MOV32(a, b) a = b #define Q_OR32(a, b) a |= b #define Q_SHL(a, c) a <<= c -#else /* !__GNUC__ */ +#else + +#define Q_NATIVE 0 typedef struct { - dword lo, hi; + dword lo, hi; } qword; #define Q_MOV32(a, b) a.lo = b #define Q_OR32(a, b) a.lo |= b -#define Q_SHL(a, c) \ - do { \ - if ((c) >= 32) { \ - a.hi = a.lo << ((c) - 32); \ - a.lo = 0; \ - } else { \ - a.hi = (a.hi << (c)) | (a.lo >> (32 - (c)));\ - a.lo <<= c; \ - } \ - } while (0) -#endif /* !__GNUC__ */ +#define Q_SHL(a, c) \ + do { \ + if ((c) >= 32) { \ + a.hi = a.lo << ((c) - 32); \ + a.lo = 0; \ + } else { \ + a.hi = (a.hi << (c)) | (a.lo >> (32 - (c))); \ + a.lo <<= (c); \ + } \ + } while (0) + +#endif /*****************************************************************************\ @@ -86,47 +96,56 @@ typedef struct { #define F(i) (float)1 /* can be used to obtain an oblong metric: 0.30 / 0.59 / 0.11 */ #define SAFECDOT 1 /* for paranoids */ -#define MAKEIVEC(NV, NC, IV, B, V0, V1) \ - do { \ - /* compute interpolation vector */\ - float d2 = 0.0F; \ - float rd2; \ - \ - for (i = 0; i < NC; i++) { \ - IV[i] = (V1[i] - V0[i]) * F(i);\ - d2 += IV[i] * IV[i]; \ - } \ - rd2 = (float)NV / d2; \ - B = 0; \ - for (i = 0; i < NC; i++) { \ - IV[i] *= F(i); \ - B -= IV[i] * V0[i]; \ - IV[i] *= rd2; \ - } \ - B = B * rd2 + 0.5F; \ - } while (0) +#define MAKEIVEC(NV, NC, IV, B, V0, V1) \ + do { \ + /* compute interpolation vector */ \ + float d2 = 0.0F; \ + float rd2; \ + \ + for (i = 0; i < NC; i++) { \ + IV[i] = (V1[i] - V0[i]) * F(i); \ + d2 += IV[i] * IV[i]; \ + } \ + rd2 = (float)NV / d2; \ + B = 0; \ + for (i = 0; i < NC; i++) { \ + IV[i] *= F(i); \ + B -= IV[i] * V0[i]; \ + IV[i] *= rd2; \ + } \ + B = B * rd2 + 0.5f; \ + } while (0) #define CALCCDOT(TEXEL, NV, NC, IV, B, V)\ - do { \ - float dot = 0.0F; \ - for (i = 0; i < NC; i++) { \ - dot += V[i] * IV[i]; \ - } \ - TEXEL = (int)(dot + B); \ - if (SAFECDOT) { \ - if (TEXEL < 0) { \ - TEXEL = 0; \ - } else if (TEXEL > NV) { \ - TEXEL = NV; \ - } \ - } \ - } while (0) + do { \ + float dot = 0.0F; \ + for (i = 0; i < NC; i++) { \ + dot += V[i] * IV[i]; \ + } \ + TEXEL = (int)(dot + B); \ + if (SAFECDOT) { \ + if (TEXEL < 0) { \ + TEXEL = 0; \ + } else if (TEXEL > NV) { \ + TEXEL = NV; \ + } \ + } \ + } while (0) /*****************************************************************************\ * Utility functions \*****************************************************************************/ +/** Copy a 4-element vector */ +#define COPY_4V( DST, SRC ) \ +do { \ + (DST)[0] = (SRC)[0]; \ + (DST)[1] = (SRC)[1]; \ + (DST)[2] = (SRC)[2]; \ + (DST)[3] = (SRC)[3]; \ +} while (0) + void _mesa_upscale_teximage2d (unsigned int inWidth, unsigned int inHeight, unsigned int outWidth, unsigned int outHeight, @@ -134,4 +153,21 @@ _mesa_upscale_teximage2d (unsigned int inWidth, unsigned int inHeight, const byte *src, int srcRowStride, unsigned char *dest); +/** Copy a 4-element unsigned byte vector */ +static inline void +COPY_4UBV(uint8_t dst[4], const uint8_t src[4]) +{ +#if defined(__i386__) + *((uint32_t *) dst) = *((uint32_t *) src); +#else + /* The uint32_t cast might fail if DST or SRC are not dword-aligned (RISC) */ + COPY_4V(dst, src); +#endif +} + +void reorder_source_3(byte *tex, dword width, dword height, int srcRowStride); +void *reorder_source_3_alloc(const byte *source, dword width, dword height, int srcRowStride); +void reorder_source_4(byte *tex, dword width, dword height, int srcRowStride); +void *reorder_source_4_alloc(const byte *source, dword width, dword height, int srcRowStride); + #endif diff --git a/src/GlideHQ/tc-1.1+/texstore.c b/src/GlideHQ/tc-1.1+/texstore.c index 2eb0306feb17018afad7714dc9eabd398fd18543..5dead259147eaeffce28076e92fb2a981ea451ec 100644 --- a/src/GlideHQ/tc-1.1+/texstore.c +++ b/src/GlideHQ/tc-1.1+/texstore.c @@ -27,6 +27,8 @@ */ #include +#include +#include #include "types.h" #include "internal.h" @@ -91,3 +93,67 @@ _mesa_upscale_teximage2d (unsigned int inWidth, unsigned int inHeight, } #endif } + +void reorder_source_3(byte *tex, dword width, dword height, int srcRowStride) +{ + byte *line; + byte t; + dword i, j; + + for (i = 0; i < height; i++) { + line = &tex[srcRowStride * i]; + for (j = 0; j < width; j++) { + t = line[2]; + line[2] = line[0]; + line[0] = t; + line += 3; + } + } +} + +void *reorder_source_3_alloc(const byte *source, dword width, dword height, int srcRowStride) +{ + byte *tex; + + tex = malloc(height * srcRowStride); + if (!tex) + goto out; + + memcpy(tex, source, height * srcRowStride); + reorder_source_3(tex, width, height, srcRowStride); + +out: + return tex; +} + +void reorder_source_4(byte *tex, dword width, dword height, int srcRowStride) +{ + byte *line; + byte t; + dword i, j; + + for (i = 0; i < height; i++) { + line = &tex[srcRowStride * i]; + for (j = 0; j < width; j++) { + t = line[2]; + line[2] = line[0]; + line[0] = t; + line += 4; + } + } +} + +void *reorder_source_4_alloc(const byte *source, dword width, dword height, int srcRowStride) +{ + byte *tex; + + tex = malloc(height * srcRowStride); + if (!tex) + goto out; + + memcpy(tex, source, height * srcRowStride); + reorder_source_4(tex, width, height, srcRowStride); + +out: + return tex; +} debian/watch0000644000000000000000000000033012210623037010207 0ustar version=3 opts="pgpsigurlmangle=s/$/.asc/" \ http://bitbucket.org/richard42/mupen64plus-video-glide64mk2/downloads/ \ /richard42/mupen64plus-video-glide64mk2/downloads/mupen64plus-video-glide64mk2-src-(.*).tar.gz debian/copyright0000644000000000000000000003630412210623037011123 0ustar Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ Upstream-Name: mupen64plus-video-glide64mk2 Upstream-Contact: Richard 'Richard42' Goedeken Source: http://bitbucket.org/richard42/mupen64plus-video-glide64mk2/ Files: * Copyright: 2012-2013, Richard 'Richard42' Goedeken License: GPL-2+ Files: src/* Copyright: 2001-2002, Dave2001 2003-2009, Sergey 'Gonetz' Lipski 2007, Hiroshi 'KoolSmoky' Morii License: GPL-2+ Files: src/Glide64/Config.* Copyright: 2001-2002, Dave2001 2010, Jon 'wahrhaft' Ring License: GPL-2+ Files: src/*/m64p.h Copyright: 2010, Jon 'wahrhaft' Ring License: GPL-2+ Files: src/Glide64/osal_* Copyright: 2009, Richard 'Richard42' Goedeken License: GPL-2+ Files: src/Glide64/winlnxdefs. Copyright: 2002, Dave2001 2003-2009, Sergey 'Gonetz' Lipski 2012-2013, Jon 'wahrhaft' Ring 2012-2013, balrog License: GPL-2+ Files: projects/unix/Makefile Copyright: 2007-2008, Jesse 'DarkJezter' Dean 2007-2008, Scott 'Tillin9' Knauert 2007-2009, Richard 'Richard42' Goedeken 2010, Jon 'wahrhaft' Ring License: GPL-2+ Files: src/Glitch64/inc/* Copyright: 1999, 3DFX INTERACTIVE, INC. License: other 3DFX GLIDE Source Code General Public License . 1. PREAMBLE . This license is for software that provides a 3D graphics application program interface (API).The license is intended to offer terms similar to some standard General Public Licenses designed to foster open standards and unrestricted accessibility to source code. Some of these licenses require that, as a condition of the license of the software, any derivative works (that is, new software which is a work containing the original program or a portion of it) must be available for general use, without restriction other than for a minor transfer fee, and that the source code for such derivative works must likewise be made available. The only restriction is that such derivative works must be subject to the same General Public License terms as the original work. . This 3dfx GLIDE Source Code General Public License differs from the standard licenses of this type in that it does not require the entire derivative work to be made available under the terms of this license nor is the recipient required to make available the source code for the entire derivative work. Rather, the license is limited to only the identifiable portion of the derivative work that is derived from the licensed software. The precise terms and conditions for copying, distribution and modification follow. . 2. DEFINITIONS . 2.1 This License applies to any program (or other "work") which contains a notice placed by the copyright holder saying it may be distributed under the terms of this 3dfx GLIDE Source Code General Public License. . 2.2 The term "Program" as used in this Agreement refers to 3DFX's GLIDE source code and object code and any Derivative Work. . 2.3 "Derivative Work" means, for the purpose of the License, that portion of any work that contains the Program or the identifiable portion of a work that is derived from the Program, either verbatim or with modifications and/or translated into another language, and that performs 3D graphics API operations. It does not include any other portions of a work. . 2.4 "Modifications of the Program" means any work, which includes a Derivative Work, and includes the whole of such work. . 2.5 "License" means this 3dfx GLIDE Source Code General Public License. . 2.6 The "Source Code" for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, any associated interface definition files, and the scripts used to control compilation and installation of the executable work. . 2.7 "3dfx" means 3dfx Interactive, Inc. . 3. LICENSED ACTIVITIES . 3.1 COPYING - You may copy and distribute verbatim copies of the Program's Source Code as you receive it, in any medium, subject to the provision of section 3.3 and provided also that: . (a) you conspicuously and appropriately publish on each copy an appropriate copyright notice (3dfx Interactive, Inc. 1999), a notice that recipients who wish to copy, distribute or modify the Program can only do so subject to this License, and a disclaimer of warranty as set forth in section 5; . (b) keep intact all the notices that refer to this License and to the absence of any warranty; and . (c) do not make any use of the GLIDE trademark without the prior written permission of 3dfx, and . (d) give all recipients of the Program a copy of this License along with the Program or instructions on how to easily receive a copy of this License. . 3.2 MODIFICATION OF THE PROGRAM/DERIVATIVE WORKS - You may modify your copy or copies of the Program or any portion of it, and copy and distribute such modifications subject to the provisions of section 3.3 and provided that you also meet all of the following conditions: . (a) you conspicuously and appropriately publish on each copy of a Derivative Work an appropriate copyright notice, a notice that recipients who wish to copy, distribute or modify the Derivative Work can only do so subject to this License, and a disclaimer of warranty as set forth in section 5; . (b) keep intact all the notices that refer to this License and to the absence of any warranty; and . (c) give all recipients of the Derivative Work a copy of this License along with the Derivative Work or instructions on how to easily receive a copy of this License. . (d) You must cause the modified files of the Derivative Work to carry prominent notices stating that you changed the files and the date of any change. . (e) You must cause any Derivative Work that you distribute or publish to be licensed at no charge to all third parties under the terms of this License. . (f) You do not make any use of the GLIDE trademark without the prior written permission of 3dfx. . (g) If the Derivative Work normally reads commands interactively when run, you must cause it, when started running for such interactive use, to print or display an announcement as follows: . "COPYRIGHT 3DFX INTERACTIVE, INC. 1999, ALL RIGHTS RESERVED THIS SOFTWARE IS FREE AND PROVIDED "AS IS," WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED. THERE IS NO RIGHT TO USE THE GLIDE TRADEMARK WITHOUT PRIOR WRITTEN PERMISSION OF 3DFX INTERACTIVE, INC. SEE THE 3DFX GLIDE GENERAL PUBLIC LICENSE FOR A FULL TEXT OF THE DISTRIBUTION AND NON-WARRANTY PROVISIONS (REQUEST COPY FROM INFO@3DFX.COM)." . (h) The requirements of this section 3.2 do not apply to the modified work as a whole but only to the Derivative Work. It is not the intent of this License to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of Derivative Works. . 3.3 DISTRIBUTION . (a) All copies of the Program or Derivative Works which are distributed must include in the file headers the following language verbatim: . "THIS SOFTWARE IS SUBJECT TO COPYRIGHT PROTECTION AND IS OFFERED ONLY PURSUANT TO THE 3DFX GLIDE GENERAL PUBLIC LICENSE. THERE IS NO RIGHT TO USE THE GLIDE TRADEMARK WITHOUT PRIOR WRITTEN PERMISSION OF 3DFX INTERACTIVE, INC. A COPY OF THIS LICENSE MAY BE OBTAINED FROM THE DISTRIBUTOR OR BY CONTACTING 3DFX INTERACTIVE INC (info@3dfx.com). THIS PROGRAM. IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED. SEE THE 3DFX GLIDE GENERAL PUBLIC LICENSE FOR A FULL TEXT OF THE NON-WARRANTY PROVISIONS. . USE, DUPLICATION OR DISCLOSURE BY THE GOVERNMENT IS SUBJECT TO RESTRICTIONS AS SET FORTH IN SUBDIVISION (C)(1)(II) OF THE RIGHTS IN TECHNICAL DATA AND COMPUTER SOFTWARE CLAUSE AT DFARS 252.227-7013, AND/OR IN SIMILAR OR SUCCESSOR CLAUSES IN THE FAR, DOD OR NASA FAR SUPPLEMENT. UNPUBLISHED RIGHTS RESERVED UNDER THE COPYRIGHT LAWS OF THE UNITED STATES. . COPYRIGHT 3DFX INTERACTIVE, INC. 1999, ALL RIGHTS RESERVED" . (b) You may distribute the Program or a Derivative Work in object code or executable form under the terms of Sections 3.1 and 3.2 provided that you also do one of the following: . (1) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 3.1 and 3.2; or, . (2) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 3.1 and 3.2 on a medium customarily used for software interchange; or, . (3) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection 3.3(b)(2) above.) . (c) The source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable code. . (d) If distribution of executable code or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. . (e) Each time you redistribute the Program or any Derivative Work, the recipient automatically receives a license from 3dfx and successor licensors to copy, distribute or modify the Program and Derivative Works subject to the terms and conditions of the License. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. . (f) You may not make any use of the GLIDE trademark without the prior written permission of 3dfx. . (g) You may not copy, modify, sublicense, or distribute the Program or any Derivative Works except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program or any Derivative Works is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. . 4. MISCELLANEOUS . 4.1 Acceptance of this License is voluntary. By using, modifying or distributing the Program or any Derivative Work, you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. Nothing else grants you permission to modify or distribute the Program or Derivative Works and doing so without acceptance of this License is in violation of the U.S. and international copyright laws. . 4.2 If the distribution and/or use of the Program or Derivative Works is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. . 4.3 This License is to be construed according to the laws of the State of California and you consent to personal jurisdiction in the State of California in the event it is necessary to enforce the provisions of this License. . 5. NO WARRANTIES . 5.1 TO THE EXTENT PERMITTED BY APPLICABLE LAW, THERE IS NO WARRANTY FOR THE PROGRAM. OR DERIVATIVE WORKS THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM AND ANY DERIVATIVE WORKS"AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM AND ANY DERIVATIVE WORK IS WITH YOU. SHOULD THE PROGRAM OR ANY DERIVATIVE WORK PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. . 5.2 IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW WILL 3DFX INTERACTIVE, INC., OR ANY OTHER COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM OR DERIVATIVE WORKS AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM OR DERIVATIVE WORKS (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM OR DERIVATIVE WORKS TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. Files: src/Glitch64/* Copyright: 2007, Hiroshi 'KoolSmoky' Morii License: GPL-2+ Files: src/Glitch64/TextureFilters.cpp src/GlideHQ/TextureFilters_?q2x.* Copyright: 2003, Rice1964 License: GPL-2+ Files: src/tc-1.1+/* Copyright: 2007, Daniel Borca 2007, Hiroshi 'KoolSmoky' Morii License: GPL-2+ Files: src/tc-1.1+/texstore.c Copyright: 1999-2004, Brian Paul 2007, Hiroshi 'KoolSmoky' Morii License: GPL-2+ Files: debian/* Copyright: 2009-2013, Sven Eckelmann 2009-2013, Tobias Loose License: GPL-2+ License: GPL-2+ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. . This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. . You should have received a copy of the GNU General Public License along with this package; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA . On Debian systems, the full text of the GNU General Public License version 2 can be found in the file `/usr/share/common-licenses/GPL-2'. debian/gbp.conf0000644000000000000000000000005712210623037010603 0ustar [DEFAULT] pristine-tar = True sign-tags = True debian/changelog0000644000000000000000000000110612210623037011032 0ustar mupen64plus-video-glide64mk2 (2.0-2) unstable; urgency=low * debian/patches: - Add load_hires_cache.patch, Enable the dump_cache to allow loading of *.dat files - Add kfreebsd_hurd_support.patch, Allow to compile under kFreeBSD and Hurd - Add path_max_war.patch, Add a workaround for systems not defining PATH_MAX -- Sven Eckelmann Sun, 01 Sep 2013 13:06:09 +0200 mupen64plus-video-glide64mk2 (2.0-1) unstable; urgency=low * Initial release (Closes: #714994) -- Sven Eckelmann Wed, 10 Jul 2013 23:25:40 +0200 debian/upstream-signing-key.pgp0000644000000000000000000000220212210623037013750 0ustar  Q$u!l r@a `d0\k#͸>æl_qͩVWD㉯w(Ra =ؠz;s=CawtBEj8,1!KZ\WIC\TzRY'ݵC–I2 (m.Taq5J\3!]W|mWhgLtg{mgk'!E(Ǟi"Mz>_l]4QLh ub3,=dbSvڟ9(rO``QY2Richard Goedeken 7!Q$u    [&zHfZ