mirror of
https://github.com/blawar/GLideN64.git
synced 2024-07-07 03:13:49 +00:00
Add GLideNHQ module.
This commit is contained in:
parent
eb0e3ca25a
commit
2b987923af
87
GLideNHQ/CMakeLists.txt
Normal file
87
GLideNHQ/CMakeLists.txt
Normal file
|
@ -0,0 +1,87 @@
|
||||||
|
cmake_minimum_required(VERSION 2.6)
|
||||||
|
|
||||||
|
project( GLideNHQ )
|
||||||
|
|
||||||
|
set(GLideNHQ_SOURCES
|
||||||
|
Ext_TxFilter.cpp
|
||||||
|
TextureFilters.cpp
|
||||||
|
TextureFilters_2xsai.cpp
|
||||||
|
TextureFilters_hq2x.cpp
|
||||||
|
TextureFilters_hq4x.cpp
|
||||||
|
TxCache.cpp
|
||||||
|
TxDbg.cpp
|
||||||
|
TxFilter.cpp
|
||||||
|
TxFilterExport.cpp
|
||||||
|
TxHiResCache.cpp
|
||||||
|
TxImage.cpp
|
||||||
|
TxQuantize.cpp
|
||||||
|
TxReSample.cpp
|
||||||
|
TxTexCache.cpp
|
||||||
|
TxUtil.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
include_directories( inc )
|
||||||
|
|
||||||
|
set(Boost_USE_STATIC_LIBS ON)
|
||||||
|
set(Boost_USE_MULTITHREADED ON)
|
||||||
|
find_package(Boost COMPONENTS thread filesystem system REQUIRED)
|
||||||
|
include_directories(${Boost_INCLUDE_DIRS})
|
||||||
|
|
||||||
|
if(WIN32)
|
||||||
|
LINK_DIRECTORIES( lib )
|
||||||
|
add_definitions(
|
||||||
|
-DWIN32
|
||||||
|
-D_CRT_SECURE_NO_WARNINGS
|
||||||
|
)
|
||||||
|
endif(WIN32)
|
||||||
|
|
||||||
|
|
||||||
|
if (WIN32 AND __COMPILER_GNU)
|
||||||
|
# mingw-gcc fails to link boost::thread
|
||||||
|
add_definitions(-DBOOST_THREAD_USE_LIB)
|
||||||
|
endif (WIN32 AND __COMPILER_GNU)
|
||||||
|
|
||||||
|
# Build type
|
||||||
|
|
||||||
|
if( NOT CMAKE_BUILD_TYPE)
|
||||||
|
set( CMAKE_BUILD_TYPE Release)
|
||||||
|
endif( NOT CMAKE_BUILD_TYPE)
|
||||||
|
|
||||||
|
if( CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||||
|
set( CMAKE_BUILD_TYPE Debug)
|
||||||
|
set( DEBUG_BUILD TRUE)
|
||||||
|
add_definitions(
|
||||||
|
-DDEBUG
|
||||||
|
)
|
||||||
|
endif( CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||||
|
|
||||||
|
find_package(OpenGL REQUIRED)
|
||||||
|
include_directories(${OpenGL_INCLUDE_DIRS})
|
||||||
|
link_directories(${OpenGL_LIBRARY_DIRS})
|
||||||
|
add_definitions(${OpenGL_DEFINITIONS})
|
||||||
|
if(NOT OPENGL_FOUND)
|
||||||
|
message(ERROR " OPENGL not found!")
|
||||||
|
endif(NOT OPENGL_FOUND)
|
||||||
|
|
||||||
|
SET(GCC_CPP11_COMPILE_FLAGS "-std=c++0x -static-libgcc -static-libstdc++")
|
||||||
|
SET( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${GCC_CPP11_COMPILE_FLAGS}" )
|
||||||
|
SET(GCC_STATIC_LINK_FLAGS "-static-libgcc -static-libstdc++")
|
||||||
|
SET( CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${GCC_STATIC_LINK_FLAGS}" )
|
||||||
|
|
||||||
|
add_library( GLideNHQ STATIC ${GLideNHQ_SOURCES})
|
||||||
|
|
||||||
|
SET_TARGET_PROPERTIES(
|
||||||
|
GLideNHQ
|
||||||
|
PROPERTIES
|
||||||
|
LINKER_LANGUAGE CXX # Or else we get an error message, because cmake can't figure out from the ".o"-suffix that it is a C-linker we need.
|
||||||
|
PREFIX ""
|
||||||
|
LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/plugin
|
||||||
|
)
|
||||||
|
|
||||||
|
if( CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||||
|
target_link_libraries(GLideNHQ ${OPENGL_LIBRARIES} ${Boost_LIBRARIES} libpng zlib )
|
||||||
|
endif( CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||||
|
|
||||||
|
if( CMAKE_BUILD_TYPE STREQUAL "Release")
|
||||||
|
target_link_libraries(GLideNHQ ${OPENGL_LIBRARIES} ${Boost_LIBRARIES} libpngd zlibd )
|
||||||
|
endif( CMAKE_BUILD_TYPE STREQUAL "Debug")
|
172
GLideNHQ/Ext_TxFilter.cpp
Normal file
172
GLideNHQ/Ext_TxFilter.cpp
Normal file
|
@ -0,0 +1,172 @@
|
||||||
|
/*
|
||||||
|
* Texture Filtering
|
||||||
|
* Version: 1.0
|
||||||
|
*
|
||||||
|
* Copyright (C) 2007 Hiroshi Morii All Rights Reserved.
|
||||||
|
* Email koolsmoky(at)users.sourceforge.net
|
||||||
|
* Web http://www.3dfxzone.it/koolsmoky
|
||||||
|
*
|
||||||
|
* this 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, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* this 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 GNU Make; see the file COPYING. If not, write to
|
||||||
|
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <memory.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "Ext_TxFilter.h"
|
||||||
|
|
||||||
|
typedef boolean (*txfilter_init)(int maxwidth, int maxheight, int maxbpp,
|
||||||
|
int options, int cachesize,
|
||||||
|
wchar_t *path, wchar_t *ident,
|
||||||
|
dispInfoFuncExt callback);
|
||||||
|
|
||||||
|
typedef void (*txfilter_shutdown)(void);
|
||||||
|
|
||||||
|
typedef boolean (*txfilter_filter)(unsigned char *src, int srcwidth, int srcheight, unsigned short srcformat,
|
||||||
|
uint64 g64crc, GHQTexInfo *info);
|
||||||
|
|
||||||
|
typedef boolean (*txfilter_hirestex)(uint64 g64crc, uint64 r_crc64, unsigned short *palette, GHQTexInfo *info);
|
||||||
|
|
||||||
|
typedef uint64 (*txfilter_checksum)(unsigned char *src, int width, int height, int size, int rowStride, unsigned char *palette);
|
||||||
|
|
||||||
|
typedef boolean (*txfilter_dmptx)(unsigned char *src, int width, int height, int rowStridePixel, unsigned short gfmt, unsigned short n64fmt, uint64 r_crc64);
|
||||||
|
|
||||||
|
typedef boolean (*txfilter_reloadhirestex)();
|
||||||
|
|
||||||
|
static struct {
|
||||||
|
TXHMODULE lib;
|
||||||
|
txfilter_init init;
|
||||||
|
txfilter_shutdown shutdown;
|
||||||
|
txfilter_filter filter;
|
||||||
|
txfilter_hirestex hirestex;
|
||||||
|
txfilter_checksum checksum;
|
||||||
|
txfilter_dmptx dmptx;
|
||||||
|
txfilter_reloadhirestex reloadhirestex;
|
||||||
|
} txfilter;
|
||||||
|
|
||||||
|
void ext_ghq_shutdown(void)
|
||||||
|
{
|
||||||
|
if (txfilter.shutdown)
|
||||||
|
(*txfilter.shutdown)();
|
||||||
|
|
||||||
|
if (txfilter.lib) {
|
||||||
|
DLCLOSE(txfilter.lib);
|
||||||
|
memset(&txfilter, 0, sizeof(txfilter));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean ext_ghq_init(int maxwidth, int maxheight, int maxbpp, int options, int cachesize,
|
||||||
|
wchar_t *path, wchar_t *ident,
|
||||||
|
dispInfoFuncExt callback)
|
||||||
|
{
|
||||||
|
boolean bRet = 0;
|
||||||
|
|
||||||
|
if (!txfilter.lib) {
|
||||||
|
wchar_t curpath[MAX_PATH];
|
||||||
|
wcscpy(curpath, path);
|
||||||
|
#ifdef WIN32
|
||||||
|
#ifdef GHQCHK
|
||||||
|
wcscat(curpath, L"\\ghqchk.dll");
|
||||||
|
#else
|
||||||
|
wcscat(curpath, L"\\GlideHQ.dll");
|
||||||
|
#endif
|
||||||
|
txfilter.lib = DLOPEN(curpath);
|
||||||
|
#else
|
||||||
|
char cbuf[MAX_PATH];
|
||||||
|
#ifdef GHQCHK
|
||||||
|
wcscat(curpath, L"/ghqchk.so");
|
||||||
|
#else
|
||||||
|
wcscat(curpath, L"/GlideHQ.so");
|
||||||
|
#endif
|
||||||
|
wcstombs(cbuf, curpath, MAX_PATH);
|
||||||
|
txfilter.lib = DLOPEN(cbuf);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
if (txfilter.lib) {
|
||||||
|
if (!txfilter.init)
|
||||||
|
txfilter.init = (txfilter_init)DLSYM(txfilter.lib, "txfilter_init");
|
||||||
|
if (!txfilter.shutdown)
|
||||||
|
txfilter.shutdown = (txfilter_shutdown)DLSYM(txfilter.lib, "txfilter_shutdown");
|
||||||
|
if (!txfilter.filter)
|
||||||
|
txfilter.filter = (txfilter_filter)DLSYM(txfilter.lib, "txfilter");
|
||||||
|
if (!txfilter.hirestex)
|
||||||
|
txfilter.hirestex = (txfilter_hirestex)DLSYM(txfilter.lib, "txfilter_hirestex");
|
||||||
|
if (!txfilter.checksum)
|
||||||
|
txfilter.checksum = (txfilter_checksum)DLSYM(txfilter.lib, "txfilter_checksum");
|
||||||
|
if (!txfilter.dmptx)
|
||||||
|
txfilter.dmptx = (txfilter_dmptx)DLSYM(txfilter.lib, "txfilter_dmptx");
|
||||||
|
if (!txfilter.reloadhirestex)
|
||||||
|
txfilter.reloadhirestex = (txfilter_reloadhirestex)DLSYM(txfilter.lib, "txfilter_reloadhirestex");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (txfilter.init && txfilter.shutdown && txfilter.filter &&
|
||||||
|
txfilter.hirestex && txfilter.checksum /*&& txfilter.dmptx && txfilter.reloadhirestex */)
|
||||||
|
bRet = (*txfilter.init)(maxwidth, maxheight, maxbpp, options, cachesize, path, ident, callback);
|
||||||
|
else
|
||||||
|
ext_ghq_shutdown();
|
||||||
|
|
||||||
|
return bRet;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean ext_ghq_txfilter(unsigned char *src, int srcwidth, int srcheight, unsigned short srcformat,
|
||||||
|
uint64 g64crc, GHQTexInfo *info)
|
||||||
|
{
|
||||||
|
boolean ret = 0;
|
||||||
|
|
||||||
|
if (txfilter.filter)
|
||||||
|
ret = (*txfilter.filter)(src, srcwidth, srcheight, srcformat,
|
||||||
|
g64crc, info);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean ext_ghq_hirestex(uint64 g64crc, uint64 r_crc64, unsigned short *palette, GHQTexInfo *info)
|
||||||
|
{
|
||||||
|
boolean ret = 0;
|
||||||
|
|
||||||
|
if (txfilter.hirestex)
|
||||||
|
ret = (*txfilter.hirestex)(g64crc, r_crc64, palette, info);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64 ext_ghq_checksum(unsigned char *src, int width, int height, int size, int rowStride, unsigned char *palette)
|
||||||
|
{
|
||||||
|
uint64 ret = 0;
|
||||||
|
|
||||||
|
if (txfilter.checksum)
|
||||||
|
ret = (*txfilter.checksum)(src, width, height, size, rowStride, palette);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean ext_ghq_dmptx(unsigned char *src, int width, int height, int rowStridePixel, unsigned short gfmt, unsigned short n64fmt, uint64 r_crc64)
|
||||||
|
{
|
||||||
|
boolean ret = 0;
|
||||||
|
|
||||||
|
if (txfilter.dmptx)
|
||||||
|
ret = (*txfilter.dmptx)(src, width, height, rowStridePixel, gfmt, n64fmt, r_crc64);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean ext_ghq_reloadhirestex()
|
||||||
|
{
|
||||||
|
boolean ret = 0;
|
||||||
|
|
||||||
|
if (txfilter.reloadhirestex)
|
||||||
|
ret = (*txfilter.reloadhirestex)();
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
211
GLideNHQ/Ext_TxFilter.h
Normal file
211
GLideNHQ/Ext_TxFilter.h
Normal file
|
@ -0,0 +1,211 @@
|
||||||
|
/*
|
||||||
|
* Texture Filtering
|
||||||
|
* Version: 1.0
|
||||||
|
*
|
||||||
|
* Copyright (C) 2007 Hiroshi Morii All Rights Reserved.
|
||||||
|
* Email koolsmoky(at)users.sourceforge.net
|
||||||
|
* Web http://www.3dfxzone.it/koolsmoky
|
||||||
|
*
|
||||||
|
* this 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, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* this 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 GNU Make; see the file COPYING. If not, write to
|
||||||
|
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __EXT_TXFILTER_H__
|
||||||
|
#define __EXT_TXFILTER_H__
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
#include <windows.h>
|
||||||
|
#define TXHMODULE HMODULE
|
||||||
|
#define DLOPEN(a) LoadLibraryW(a)
|
||||||
|
#define DLCLOSE(a) FreeLibrary(a)
|
||||||
|
#define DLSYM(a, b) GetProcAddress(a, b)
|
||||||
|
#define GETCWD(a, b) GetCurrentDirectoryW(a, b)
|
||||||
|
#define CHDIR(a) SetCurrentDirectoryW(a)
|
||||||
|
#else
|
||||||
|
#include <iostream>
|
||||||
|
#include <dlfcn.h>
|
||||||
|
#define MAX_PATH 4095
|
||||||
|
#define TXHMODULE void*
|
||||||
|
#define DLOPEN(a) dlopen(a, RTLD_LAZY|RTLD_GLOBAL)
|
||||||
|
#define DLCLOSE(a) dlclose(a)
|
||||||
|
#define DLSYM(a, b) dlsym(a, b)
|
||||||
|
#define GETCWD(a, b) getcwd(b, a)
|
||||||
|
#define CHDIR(a) chdir(a)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __MSC__
|
||||||
|
typedef __int64 int64;
|
||||||
|
typedef unsigned __int64 uint64;
|
||||||
|
#else
|
||||||
|
typedef long long int64;
|
||||||
|
typedef unsigned long long uint64;
|
||||||
|
typedef unsigned char boolean;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define NO_OPTIONS 0x00000000
|
||||||
|
|
||||||
|
#define FILTER_MASK 0x000000ff
|
||||||
|
#define NO_FILTER 0x00000000
|
||||||
|
#define SMOOTH_FILTER_MASK 0x0000000f
|
||||||
|
#define NO_SMOOTH_FILTER 0x00000000
|
||||||
|
#define SMOOTH_FILTER_1 0x00000001
|
||||||
|
#define SMOOTH_FILTER_2 0x00000002
|
||||||
|
#define SMOOTH_FILTER_3 0x00000003
|
||||||
|
#define SMOOTH_FILTER_4 0x00000004
|
||||||
|
#define SHARP_FILTER_MASK 0x000000f0
|
||||||
|
#define NO_SHARP_FILTER 0x00000000
|
||||||
|
#define SHARP_FILTER_1 0x00000010
|
||||||
|
#define SHARP_FILTER_2 0x00000020
|
||||||
|
|
||||||
|
#define ENHANCEMENT_MASK 0x00000f00
|
||||||
|
#define NO_ENHANCEMENT 0x00000000
|
||||||
|
#define X2_ENHANCEMENT 0x00000100
|
||||||
|
#define X2SAI_ENHANCEMENT 0x00000200
|
||||||
|
#define HQ2X_ENHANCEMENT 0x00000300
|
||||||
|
#define LQ2X_ENHANCEMENT 0x00000400
|
||||||
|
#define HQ4X_ENHANCEMENT 0x00000500
|
||||||
|
#define HQ2XS_ENHANCEMENT 0x00000600
|
||||||
|
#define LQ2XS_ENHANCEMENT 0x00000700
|
||||||
|
|
||||||
|
#define COMPRESSION_MASK 0x0000f000
|
||||||
|
#define NO_COMPRESSION 0x00000000
|
||||||
|
#define FXT1_COMPRESSION 0x00001000
|
||||||
|
#define NCC_COMPRESSION 0x00002000
|
||||||
|
#define S3TC_COMPRESSION 0x00003000
|
||||||
|
|
||||||
|
#define HIRESTEXTURES_MASK 0x000f0000
|
||||||
|
#define NO_HIRESTEXTURES 0x00000000
|
||||||
|
#define GHQ_HIRESTEXTURES 0x00010000
|
||||||
|
#define RICE_HIRESTEXTURES 0x00020000
|
||||||
|
#define JABO_HIRESTEXTURES 0x00030000
|
||||||
|
|
||||||
|
#define COMPRESS_TEX 0x00100000
|
||||||
|
#define COMPRESS_HIRESTEX 0x00200000
|
||||||
|
#define GZ_TEXCACHE 0x00400000
|
||||||
|
#define GZ_HIRESTEXCACHE 0x00800000
|
||||||
|
#define DUMP_TEXCACHE 0x01000000
|
||||||
|
#define DUMP_HIRESTEXCACHE 0x02000000
|
||||||
|
#define TILE_HIRESTEX 0x04000000
|
||||||
|
#define UNDEFINED_0 0x08000000
|
||||||
|
#define FORCE16BPP_HIRESTEX 0x10000000
|
||||||
|
#define FORCE16BPP_TEX 0x20000000
|
||||||
|
#define LET_TEXARTISTS_FLY 0x40000000 /* a little freedom for texture artists */
|
||||||
|
#define DUMP_TEX 0x80000000
|
||||||
|
|
||||||
|
#ifndef __GLIDE_H__ /* GLIDE3 */
|
||||||
|
/* from 3Dfx Interactive Inc. glide.h */
|
||||||
|
#define GR_TEXFMT_ALPHA_8 0x2
|
||||||
|
#define GR_TEXFMT_INTENSITY_8 0x3
|
||||||
|
|
||||||
|
#define GR_TEXFMT_ALPHA_INTENSITY_44 0x4
|
||||||
|
#define GR_TEXFMT_P_8 0x5
|
||||||
|
|
||||||
|
#define GR_TEXFMT_RGB_565 0xa
|
||||||
|
#define GR_TEXFMT_ARGB_1555 0xb
|
||||||
|
#define GR_TEXFMT_ARGB_4444 0xc
|
||||||
|
#define GR_TEXFMT_ALPHA_INTENSITY_88 0xd
|
||||||
|
|
||||||
|
/* from 3Dfx Interactive Inc. g3ext.h */
|
||||||
|
#define GR_TEXFMT_ARGB_CMP_FXT1 0x11
|
||||||
|
|
||||||
|
#define GR_TEXFMT_ARGB_8888 0x12
|
||||||
|
|
||||||
|
#define GR_TEXFMT_ARGB_CMP_DXT1 0x16
|
||||||
|
#define GR_TEXFMT_ARGB_CMP_DXT3 0x18
|
||||||
|
#define GR_TEXFMT_ARGB_CMP_DXT5 0x1A
|
||||||
|
#endif /* GLIDE3 */
|
||||||
|
|
||||||
|
struct GHQTexInfo {
|
||||||
|
unsigned char *data;
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
unsigned short format;
|
||||||
|
|
||||||
|
int smallLodLog2;
|
||||||
|
int largeLodLog2;
|
||||||
|
int aspectRatioLog2;
|
||||||
|
|
||||||
|
int tiles;
|
||||||
|
int untiled_width;
|
||||||
|
int untiled_height;
|
||||||
|
|
||||||
|
unsigned char is_hires_tex;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Callback to display hires texture info.
|
||||||
|
* Gonetz <gonetz(at)ngs.ru>
|
||||||
|
*
|
||||||
|
* void DispInfo(const char *format, ...)
|
||||||
|
* {
|
||||||
|
* va_list args;
|
||||||
|
* char buf[INFO_BUF];
|
||||||
|
*
|
||||||
|
* va_start(args, format);
|
||||||
|
* vsprintf(buf, format, args);
|
||||||
|
* va_end(args);
|
||||||
|
*
|
||||||
|
* printf(buf);
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
#define INFO_BUF 4095
|
||||||
|
typedef void (*dispInfoFuncExt)(const wchar_t *format, ...);
|
||||||
|
|
||||||
|
#ifndef TXFILTER_DLL
|
||||||
|
boolean ext_ghq_init(int maxwidth, /* maximum texture width supported by hardware */
|
||||||
|
int maxheight,/* maximum texture height supported by hardware */
|
||||||
|
int maxbpp, /* maximum texture bpp supported by hardware */
|
||||||
|
int options, /* options */
|
||||||
|
int cachesize,/* cache textures to system memory */
|
||||||
|
wchar_t *path, /* plugin directory. must be smaller than MAX_PATH */
|
||||||
|
wchar_t *ident, /* name of ROM. must be no longer than 64 in character. */
|
||||||
|
dispInfoFuncExt callback /* callback function to display info */
|
||||||
|
);
|
||||||
|
|
||||||
|
void ext_ghq_shutdown(void);
|
||||||
|
|
||||||
|
boolean ext_ghq_txfilter(unsigned char *src, /* input texture */
|
||||||
|
int srcwidth, /* width of input texture */
|
||||||
|
int srcheight, /* height of input texture */
|
||||||
|
unsigned short srcformat, /* format of input texture */
|
||||||
|
uint64 g64crc, /* glide64 crc */
|
||||||
|
GHQTexInfo *info /* output */
|
||||||
|
);
|
||||||
|
|
||||||
|
boolean ext_ghq_hirestex(uint64 g64crc, /* glide64 crc */
|
||||||
|
uint64 r_crc64, /* checksum hi:palette low:texture */
|
||||||
|
unsigned short *palette, /* palette for CI textures */
|
||||||
|
GHQTexInfo *info /* output */
|
||||||
|
);
|
||||||
|
|
||||||
|
uint64 ext_ghq_checksum(unsigned char *src, /* input texture */
|
||||||
|
int width, /* width of texture */
|
||||||
|
int height, /* height of texture */
|
||||||
|
int size, /* type of texture pixel */
|
||||||
|
int rowStride, /* row stride in bytes */
|
||||||
|
unsigned char *palette /* palette */
|
||||||
|
);
|
||||||
|
|
||||||
|
boolean ext_ghq_dmptx(unsigned char *src, /* input texture (must be in 3Dfx Glide format) */
|
||||||
|
int width, /* width of texture */
|
||||||
|
int height, /* height of texture */
|
||||||
|
int rowStridePixel, /* row stride of input texture in pixels */
|
||||||
|
unsigned short gfmt, /* glide format of input texture */
|
||||||
|
unsigned short n64fmt,/* N64 format hi:format low:size */
|
||||||
|
uint64 r_crc64 /* checksum hi:palette low:texture */
|
||||||
|
);
|
||||||
|
|
||||||
|
boolean ext_ghq_reloadhirestex();
|
||||||
|
#endif /* TXFILTER_DLL */
|
||||||
|
|
||||||
|
#endif /* __EXT_TXFILTER_H__ */
|
79
GLideNHQ/GlideHQ.rc
Normal file
79
GLideNHQ/GlideHQ.rc
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
/*
|
||||||
|
* Texture Filtering
|
||||||
|
* Version: 1.0
|
||||||
|
*
|
||||||
|
* Copyright (C) 2007 Hiroshi Morii All Rights Reserved.
|
||||||
|
* Email koolsmoky(at)users.sourceforge.net
|
||||||
|
* Web http://www.3dfxzone.it/koolsmoky
|
||||||
|
*
|
||||||
|
* this 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, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* this 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 GNU Make; see the file COPYING. If not, write to
|
||||||
|
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "bldno.h"
|
||||||
|
|
||||||
|
#define ID(id) id
|
||||||
|
|
||||||
|
#define VS_FILE_INFO ID(16) /* Version stamp res type */
|
||||||
|
#define VS_VERSION_INFO ID(1) /* Version stamp res ID */
|
||||||
|
#define VS_USER_DEFINED ID(100) /* User-defined res IDs */
|
||||||
|
|
||||||
|
#define VOS_DOS_WINDOWS32 0x00010004L
|
||||||
|
#define VFT_DLL 0x00000002L
|
||||||
|
#define VER_PRERELEASE 0
|
||||||
|
#define VER_PRIVATEBUILD 0
|
||||||
|
#define VER_DEBUG 0
|
||||||
|
|
||||||
|
#define VERSIONNAME "GlideHQ.dll\0"
|
||||||
|
#define PRODNAME "GlideHQ\0"
|
||||||
|
#define DESCRIPT "Texture filtering DLL\0"
|
||||||
|
#define COPYRIGHTSTR "Copyright (C) 2007 Hiroshi Morii\0"
|
||||||
|
#define CONTACTSTR "Hiroshi Morii <koolsmoky@users.sourceforge.net> http://www.3dfxzone.it/koolsmoky\0"
|
||||||
|
|
||||||
|
#define MANVERSION 1
|
||||||
|
#define MANREVISION 02
|
||||||
|
#define MINVERSION 00
|
||||||
|
|
||||||
|
#define VERSIONSTR "1.02.00." BUILD_NUMBER_STR
|
||||||
|
|
||||||
|
VS_VERSION_INFO VERSIONINFO
|
||||||
|
FILEVERSION MANVERSION, MANREVISION, 0, BUILD_NUMBER
|
||||||
|
PRODUCTVERSION MANVERSION, MANREVISION, 0, BUILD_NUMBER
|
||||||
|
FILEFLAGSMASK 0x0030003FL
|
||||||
|
FILEFLAGS (VER_PRIVATEBUILD|VER_PRERELEASE|VER_DEBUG)
|
||||||
|
|
||||||
|
FILEOS VOS_DOS_WINDOWS32
|
||||||
|
FILETYPE VFT_DLL
|
||||||
|
FILESUBTYPE 0
|
||||||
|
BEGIN
|
||||||
|
BLOCK "StringFileInfo"
|
||||||
|
BEGIN
|
||||||
|
BLOCK "040904E4"
|
||||||
|
BEGIN
|
||||||
|
VALUE "FileDescription", DESCRIPT
|
||||||
|
VALUE "FileVersion", VERSIONSTR
|
||||||
|
VALUE "InternalName", VERSIONNAME
|
||||||
|
VALUE "LegalCopyright", COPYRIGHTSTR
|
||||||
|
VALUE "OriginalFilename", VERSIONNAME
|
||||||
|
VALUE "ProductName", PRODNAME
|
||||||
|
VALUE "ProductVersion", VERSIONSTR
|
||||||
|
VALUE "Contact", CONTACTSTR
|
||||||
|
END
|
||||||
|
END
|
||||||
|
BLOCK "VarFileInfo"
|
||||||
|
BEGIN
|
||||||
|
/* the following line should be extended for localized versions */
|
||||||
|
VALUE "Translation", 0x409, 1252
|
||||||
|
END
|
||||||
|
END
|
126
GLideNHQ/Makefile.gcc
Normal file
126
GLideNHQ/Makefile.gcc
Normal file
|
@ -0,0 +1,126 @@
|
||||||
|
# This MUST be processed by GNU make
|
||||||
|
#
|
||||||
|
# Texture Filtering Linux Makefile
|
||||||
|
# Version: 1.0
|
||||||
|
#
|
||||||
|
# Copyright (C) 2007 Hiroshi Morii All Rights Reserved.
|
||||||
|
# Email koolsmoky(at)users.sourceforge.net
|
||||||
|
# Web http://www.3dfxzone.it/koolsmoky
|
||||||
|
#
|
||||||
|
# this 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, or (at your option)
|
||||||
|
# any later version.
|
||||||
|
#
|
||||||
|
# this 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 GNU Make; see the file COPYING. If not, write to
|
||||||
|
# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
#
|
||||||
|
|
||||||
|
#
|
||||||
|
# Available options:
|
||||||
|
#
|
||||||
|
# Environment variables:
|
||||||
|
# DEBUG=1 enable debugging checks and messages
|
||||||
|
# default = no
|
||||||
|
#
|
||||||
|
# Environment variables:
|
||||||
|
#
|
||||||
|
# Targets:
|
||||||
|
# all: build dynamic module
|
||||||
|
# clean: remove object files
|
||||||
|
# realclean: remove all generated files
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# Requirements:
|
||||||
|
#
|
||||||
|
# Compiler:
|
||||||
|
# GCC 4.2
|
||||||
|
#
|
||||||
|
# Libraries:
|
||||||
|
# boost 1.41.0 (http://www.boost.org) bjam --toolset=gcc link=static runtime-link=static variant=release,debug stage
|
||||||
|
# libpng 1.4.1 (http://www.libpng.org) static library
|
||||||
|
# zlib 1.2.3 (http://www.zlib.org) static library
|
||||||
|
# tc 1.1+ patched for ARGB input and ATI Radeon workaround
|
||||||
|
#
|
||||||
|
|
||||||
|
#
|
||||||
|
# GCC does not have SEH (structured exception handling)
|
||||||
|
#
|
||||||
|
|
||||||
|
.PHONY: all clean realclean
|
||||||
|
|
||||||
|
DLLNAME = GlideHQ.so
|
||||||
|
|
||||||
|
# libpng and zlib headers & libraries
|
||||||
|
EXT_INC = ./inc
|
||||||
|
EXT_LIB = ./lib
|
||||||
|
|
||||||
|
# boost library & headers
|
||||||
|
BOOST_INC = ../boost_1_41_0
|
||||||
|
BOOST_LIB = ../boost_1_41_0/stage/lib
|
||||||
|
|
||||||
|
CC = g++
|
||||||
|
CFLAGS = -Wall -W -pedantic -ansi -Wno-long-long
|
||||||
|
CFLAGS += -O3 -ffast-math -funroll-loops
|
||||||
|
#CFLAGS += -fexpensive-optimizations -march=k6
|
||||||
|
CFLAGS += -I. -I$(EXT_INC) -I$(BOOST_INC)
|
||||||
|
CFLAGS += -fPIC -DPIC
|
||||||
|
#CFLAGS += -DTXFILTER_DLL
|
||||||
|
|
||||||
|
ifdef DEBUG
|
||||||
|
CFLAGS += -DDEBUG
|
||||||
|
endif
|
||||||
|
|
||||||
|
LD = g++
|
||||||
|
LDFLAGS = -shared -lstdc++ -lpthread
|
||||||
|
LDLIBS = $(EXT_LIB)/libdxtn.a $(EXT_LIB)/libpng.a $(EXT_LIB)/libz.a $(BOOST_LIB)/libboost_filesystem-gcc42-mt-s.a $(BOOST_LIB)/libboost_system-gcc42-mt-s.a $(BOOST_LIB)/libboost_thread-gcc42-mt-s.a
|
||||||
|
|
||||||
|
RM = rm
|
||||||
|
|
||||||
|
SOURCES = \
|
||||||
|
TxFilterExport.cpp \
|
||||||
|
TxFilter.cpp \
|
||||||
|
TxCache.cpp \
|
||||||
|
TxTexCache.cpp \
|
||||||
|
TxHiResCache.cpp \
|
||||||
|
TxQuantize.cpp \
|
||||||
|
TxUtil.cpp \
|
||||||
|
TextureFilters.cpp \
|
||||||
|
TextureFilters_2xsai.cpp \
|
||||||
|
TextureFilters_hq2x.cpp \
|
||||||
|
TextureFilters_hq4x.cpp \
|
||||||
|
TxImage.cpp \
|
||||||
|
TxReSample.cpp \
|
||||||
|
TxDbg.cpp
|
||||||
|
|
||||||
|
OBJECTS = $(SOURCES:.cpp=.o)
|
||||||
|
|
||||||
|
.cpp.o:
|
||||||
|
$(CC) -o $@ $(CFLAGS) -c $<
|
||||||
|
|
||||||
|
all: $(DLLNAME)
|
||||||
|
|
||||||
|
$(DLLNAME): $(OBJECTS)
|
||||||
|
$(LD) -o $@ $(LDFLAGS) $^ $(LDLIBS)
|
||||||
|
|
||||||
|
$(OBJECTS): $(SOURCES) bldno.h
|
||||||
|
|
||||||
|
bldno.h: bldno.exe
|
||||||
|
./$< > $@
|
||||||
|
|
||||||
|
bldno.exe: bldno.cpp
|
||||||
|
$(CC) -o $@ $(CFLAGS) $<
|
||||||
|
|
||||||
|
clean:
|
||||||
|
-$(RM) *.o
|
||||||
|
|
||||||
|
realclean: clean
|
||||||
|
-$(RM) $(DLLNAME) bldno.exe bldno.h
|
||||||
|
|
||||||
|
-include depend
|
144
GLideNHQ/Makefile.vc8
Normal file
144
GLideNHQ/Makefile.vc8
Normal file
|
@ -0,0 +1,144 @@
|
||||||
|
# This MUST be processed by GNU make
|
||||||
|
#
|
||||||
|
# Texture Filtering MSVC Makefile
|
||||||
|
# Version: 1.0
|
||||||
|
#
|
||||||
|
# Copyright (C) 2007 Hiroshi Morii All Rights Reserved.
|
||||||
|
# Email koolsmoky(at)users.sourceforge.net
|
||||||
|
# Web http://www.3dfxzone.it/koolsmoky
|
||||||
|
#
|
||||||
|
# this 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, or (at your option)
|
||||||
|
# any later version.
|
||||||
|
#
|
||||||
|
# this 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 GNU Make; see the file COPYING. If not, write to
|
||||||
|
# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
#
|
||||||
|
|
||||||
|
#
|
||||||
|
# Available options:
|
||||||
|
#
|
||||||
|
# Environment variables:
|
||||||
|
# DEBUG=1 enable debugging checks and messages
|
||||||
|
# default = no
|
||||||
|
#
|
||||||
|
# Targets:
|
||||||
|
# all: build everything
|
||||||
|
# clean: remove object files
|
||||||
|
# realclean: remove all generated files
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# Requirements:
|
||||||
|
#
|
||||||
|
# Compiler:
|
||||||
|
# Microsoft VisualC++ 8.0 (VS2005)
|
||||||
|
#
|
||||||
|
# Libraries:
|
||||||
|
# boost 1.41.0 (http://www.boost.org) bjam --toolset=msvc-8.0 link=static runtime-link=static variant=release,debug stage
|
||||||
|
# libpng 1.4.1 (http://www.libpng.org) built with /MT or /MTd switch
|
||||||
|
# zlib 1.2.3 (http://www.zlib.org) built with /MT or /MTd switch
|
||||||
|
# tc 1.1+ patched for ARGB input and ATI Radeon workaround
|
||||||
|
#
|
||||||
|
# All libraries must be built with /MT or /MTd switch and statically linked.
|
||||||
|
# If you need any help feel free to drop me a line.
|
||||||
|
#
|
||||||
|
|
||||||
|
.PHONY: all clean realclean
|
||||||
|
.SUFFIXES: .cpp .obj .rc .res
|
||||||
|
|
||||||
|
# RESNAME = txfilter.res
|
||||||
|
# DLLNAME = txfilter.dll
|
||||||
|
# LIBNAME = txfilter.lib
|
||||||
|
# EXPNAME = txfilter.exp
|
||||||
|
RESNAME = GlideHQ.res
|
||||||
|
DLLNAME = GlideHQ.dll
|
||||||
|
LIBNAME = GlideHQ.lib
|
||||||
|
EXPNAME = GlideHQ.exp
|
||||||
|
|
||||||
|
# libpng and zlib headers & libraries
|
||||||
|
EXT_INC = ./inc
|
||||||
|
EXT_LIB = ./lib
|
||||||
|
|
||||||
|
# boost library & headers
|
||||||
|
BOOST_INC = ../boost_1_41_0
|
||||||
|
BOOST_LIB = ../boost_1_41_0/stage/lib
|
||||||
|
|
||||||
|
CC = cl
|
||||||
|
AS = nasm
|
||||||
|
LD = _link # change this to suite your build environment
|
||||||
|
RC = rc
|
||||||
|
|
||||||
|
UNLINK = $(RM) $(1)
|
||||||
|
|
||||||
|
LDFLAGS = -nologo -dll -opt:WIN98 -machine:X86 -nodefaultlib
|
||||||
|
|
||||||
|
ASFLAGS = -O6 -fwin32 -D__WIN32__ --prefix _
|
||||||
|
ASFLAGS += $(CDEFS)
|
||||||
|
|
||||||
|
CFLAGS = -nologo -W3 -WX -D__MSC__ -DWIN32 -D_WINDOWS -D_WINDLL -EHa -D_CRT_SECURE_NO_DEPRECATE -DTXFILTER_DLL
|
||||||
|
|
||||||
|
LDLIBS = user32.lib kernel32.lib
|
||||||
|
ifdef DEBUG
|
||||||
|
CFLAGS += -Zi -DDEBUG -MTd
|
||||||
|
LDLIBS += $(EXT_LIB)/dxtnd.lib $(EXT_LIB)/libpngd.lib $(EXT_LIB)/zlibd.lib LIBCMTD.LIB LIBCPMTD.LIB $(BOOST_LIB)/libboost_filesystem-vc80-mt-sgd.lib $(BOOST_LIB)/libboost_system-vc80-mt-sgd.lib $(BOOST_LIB)/libboost_thread-vc80-mt-sgd.lib
|
||||||
|
OPTFLAGS ?= -Od
|
||||||
|
else
|
||||||
|
CFLAGS += -DNDEBUG -GL -MT
|
||||||
|
LDFLAGS += -ltcg:STATUS
|
||||||
|
LDLIBS += $(EXT_LIB)/dxtn.lib $(EXT_LIB)/libpng.lib $(EXT_LIB)/zlib.lib LIBCMT.LIB LIBCPMT.LIB $(BOOST_LIB)/libboost_filesystem-vc80-mt-s.lib $(BOOST_LIB)/libboost_system-vc80-mt-s.lib $(BOOST_LIB)/libboost_thread-vc80-mt-s.lib
|
||||||
|
OPTFLAGS ?= -O2
|
||||||
|
endif
|
||||||
|
|
||||||
|
CFLAGS += -I. -I$(EXT_INC) -I$(BOOST_INC)
|
||||||
|
CFLAGS += $(CDEFS) $(OPTFLAGS)
|
||||||
|
|
||||||
|
SOURCES = \
|
||||||
|
TxFilterExport.cpp \
|
||||||
|
TxFilter.cpp \
|
||||||
|
TxCache.cpp \
|
||||||
|
TxTexCache.cpp \
|
||||||
|
TxHiResCache.cpp \
|
||||||
|
TxQuantize.cpp \
|
||||||
|
TxUtil.cpp \
|
||||||
|
TextureFilters.cpp \
|
||||||
|
TextureFilters_2xsai.cpp \
|
||||||
|
TextureFilters_hq2x.cpp \
|
||||||
|
TextureFilters_hq4x.cpp \
|
||||||
|
TxImage.cpp \
|
||||||
|
TxReSample.cpp \
|
||||||
|
TxDbg.cpp
|
||||||
|
|
||||||
|
|
||||||
|
OBJECTS = $(SOURCES:.cpp=.obj)
|
||||||
|
|
||||||
|
.cpp.obj:
|
||||||
|
$(CC) -Fo$@ $(CFLAGS) -c $<
|
||||||
|
|
||||||
|
.rc.res:
|
||||||
|
$(RC) -Fo$@ $(CDEFS) $<
|
||||||
|
|
||||||
|
all: $(DLLNAME)
|
||||||
|
|
||||||
|
$(DLLNAME): $(OBJECTS) $(RESNAME)
|
||||||
|
$(LD) -out:$@ $(LDFLAGS) $(OBJECTS) $(LDLIBS) $(RESNAME)
|
||||||
|
|
||||||
|
$(OBJECTS): $(SOURCES) bldno.h
|
||||||
|
|
||||||
|
bldno.h: bldno.exe
|
||||||
|
./$< > $@
|
||||||
|
|
||||||
|
bldno.exe: bldno.cpp
|
||||||
|
$(CC) -o $@ $(CFLAGS) $<
|
||||||
|
|
||||||
|
clean:
|
||||||
|
-$(RM) *.obj *.pdb $(RESNAME) bldno.h *.ilk
|
||||||
|
|
||||||
|
realclean: clean
|
||||||
|
-$(RM) $(DLLNAME) $(LIBNAME) $(EXPNAME) bldno.exe
|
94
GLideNHQ/README.txt
Normal file
94
GLideNHQ/README.txt
Normal file
|
@ -0,0 +1,94 @@
|
||||||
|
/*
|
||||||
|
* GlideHQ (Texture enhancer library for Glide64)
|
||||||
|
* Version: 1.5
|
||||||
|
*
|
||||||
|
* Copyright (C) 2007 Hiroshi Morii aka KoolSmoky All Rights Reserved.
|
||||||
|
* Email koolsmoky(at)users.sourceforge.net
|
||||||
|
* Web http://www.3dfxzone.it/koolsmoky
|
||||||
|
*
|
||||||
|
* this 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, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* this 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 GNU Make; see the file COPYING. If not, write to
|
||||||
|
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
About:
|
||||||
|
This is a realtime texture enhancer library with hi-resolution texture
|
||||||
|
pack support for Glide64 (http://glide64.emuxhaven.net). Traditional and
|
||||||
|
non-traditional techniques have been used to achieve speed and high image
|
||||||
|
quality even on a 9 year old 3Dfx Voodoo2.
|
||||||
|
|
||||||
|
Although the 3Dfx Glide3x texture format naming conventions are used, the
|
||||||
|
library can be expanded for generic use.
|
||||||
|
|
||||||
|
Supported:
|
||||||
|
OS: 32bit Linux and MS Windows
|
||||||
|
Enhancers: Hq4x, Hq2x, Hq2xS, Lq2x, Lq2xS, Super2xSai, x2
|
||||||
|
Filters: Smooth (1,2,3,4), Sharp (1,2)
|
||||||
|
Compressors: FXT1, S3TC
|
||||||
|
Input formats: GR_TEXFMT_ALPHA_8,
|
||||||
|
GR_TEXFMT_RGB_565,
|
||||||
|
GR_TEXFMT_ARGB_1555,
|
||||||
|
GR_TEXFMT_ARGB_4444,
|
||||||
|
GR_TEXFMT_ARGB_8888,
|
||||||
|
GR_TEXFMT_ALPHA_INTENSITY_44,
|
||||||
|
GR_TEXFMT_ALPHA_INTENSITY_88
|
||||||
|
Output formats: Same as input unless compression or hires packs are used.
|
||||||
|
Hires texture packs: Rice format (Jabo and GlideHQ format coming later)
|
||||||
|
|
||||||
|
Acknowledgments:
|
||||||
|
I hope you enjoy GlideHQ (texture enhancer library for Glide64). Greatest
|
||||||
|
thanks to Gonetz for making this happen in his busy time. We've rushed
|
||||||
|
everything to share the eye-candy with all of you N64 emulation fans. I
|
||||||
|
would also like to thank a great friend of mine, Daniel Borca for providing
|
||||||
|
the texture compression code, Maxim Stepin (hq2x 4x), and Derek Liauw Kie Fa
|
||||||
|
(2xSaI) for the filtering engines, Rice for his N64 graphics plugin source
|
||||||
|
code, and Mudlord for the hq2xS lq2xS code. GlideHQ also uses the boost C++
|
||||||
|
libraries, zlib general purpose compression library, and the Portable Network
|
||||||
|
Graphics library. Thanks to all the developers for making them available. And
|
||||||
|
special thanks to the Glide64 beta testing crew. Without their feedbacks
|
||||||
|
this library would not have seen daylight. Thank you all.
|
||||||
|
|
||||||
|
The source code for GlideHQ is released in hopes that it will be improved.
|
||||||
|
I know the coding is not on par after so much late night caffeine boosts.
|
||||||
|
If you have suggestions or modifications, please feel free to post them on
|
||||||
|
the Glide64 forum at emuxhaven.
|
||||||
|
|
||||||
|
Porting the library to other platforms should not be so hard. The coding is
|
||||||
|
done with cross platform compatibility in mind and will build with GCC and
|
||||||
|
GNU make. Currently supported are 32bit Linux and MS Windows.
|
||||||
|
|
||||||
|
If you are looking for driver updates for your 3Dfx Interactive Inc. gfx
|
||||||
|
card, grab them from the forums at http://www.3dfxzone.it/enboard/
|
||||||
|
Unbelievable as it seems, drivers are still being updated after 6 years
|
||||||
|
from 3Dfx's demise.
|
||||||
|
|
||||||
|
I know N64 rules, anyone up for PSX? :))
|
||||||
|
|
||||||
|
-KoolSmoky
|
||||||
|
|
||||||
|
References:
|
||||||
|
[1] R.W. Floyd & L. Steinberg, An adaptive algorithm for spatial grey scale,
|
||||||
|
Proceedings of the Society of Information Display 17, pp75-77, 1976
|
||||||
|
[2] Ken Turkowski, Filters for Common Resampling Tasks, Apple Computer 1990
|
||||||
|
http://www.worldserver.com/turk/computergraphics/ResamplingFilters.pdf
|
||||||
|
[3] Don P. Mitchell and Arun N. Netravali, Reconstruction Filters in Computer
|
||||||
|
Graphics, SIGGRAPH '88, Proceedings of the 15th annual conference on
|
||||||
|
Computer graphics and interactive techniques, pp221-228, 1988
|
||||||
|
[4] J. F. Kaiser and W. A. Reed, Data smoothing using low-pass digital
|
||||||
|
filters, Rev. Sci. instrum. 48 (11), pp1447-1457, 1977
|
||||||
|
[5] Maxim Stepin, hq4x Magnification Filter, http://www.hiend3d.com/hq4x.html
|
||||||
|
[6] Derek Liauw Kie Fa, 2xSaI, http://elektron.its.tudelft.nl/~dalikifa
|
||||||
|
[7] Dirk Stevens, Eagle engine http://www.retrofx.com/rfxtech.html
|
||||||
|
[8] 3DFX_texture_compression_FXT1 and EXT_texture_compression_s3tc extension
|
||||||
|
specs from the OpenGL Extension Registry. http://oss.sgi.com/projects/
|
||||||
|
ogl-sample/registry/
|
715
GLideNHQ/TextureFilters.cpp
Normal file
715
GLideNHQ/TextureFilters.cpp
Normal file
|
@ -0,0 +1,715 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2003 Rice1964
|
||||||
|
|
||||||
|
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 program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Copyright (C) 2007 Hiroshi Morii <koolsmoky(at)users.sourceforge.net>
|
||||||
|
* Modified for the Texture Filtering library
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include "TextureFilters.h"
|
||||||
|
|
||||||
|
/************************************************************************/
|
||||||
|
/* 2X filters */
|
||||||
|
/************************************************************************/
|
||||||
|
|
||||||
|
#define DWORD_MAKE(r, g, b, a) ((uint32) (((a) << 24) | ((r) << 16) | ((g) << 8) | (b)))
|
||||||
|
#define WORD_MAKE(r, g, b, a) ((uint16) (((a) << 12) | ((r) << 8) | ((g) << 4) | (b)))
|
||||||
|
|
||||||
|
// Basic 2x R8G8B8A8 filter with interpolation
|
||||||
|
|
||||||
|
void Texture2x_32(uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height)
|
||||||
|
{
|
||||||
|
uint32 *pDst1, *pDst2;
|
||||||
|
uint32 *pSrc, *pSrc2;
|
||||||
|
uint32 nWidth = width;
|
||||||
|
uint32 nHeight = height;
|
||||||
|
|
||||||
|
uint32 b1;
|
||||||
|
uint32 g1;
|
||||||
|
uint32 r1;
|
||||||
|
uint32 a1;
|
||||||
|
uint32 b2;
|
||||||
|
uint32 g2;
|
||||||
|
uint32 r2;
|
||||||
|
uint32 a2;
|
||||||
|
uint32 b3;
|
||||||
|
uint32 g3;
|
||||||
|
uint32 r3;
|
||||||
|
uint32 a3;
|
||||||
|
uint32 b4;
|
||||||
|
uint32 g4;
|
||||||
|
uint32 r4;
|
||||||
|
uint32 a4;
|
||||||
|
|
||||||
|
uint32 xSrc;
|
||||||
|
uint32 ySrc;
|
||||||
|
|
||||||
|
for (ySrc = 0; ySrc < nHeight; ySrc++)
|
||||||
|
{
|
||||||
|
pSrc = (uint32*)(((uint8*)srcPtr)+ySrc*srcPitch);
|
||||||
|
pSrc2 = (uint32*)(((uint8*)srcPtr)+(ySrc+1)*srcPitch);
|
||||||
|
pDst1 = (uint32*)(((uint8*)dstPtr)+(ySrc*2)*dstPitch);
|
||||||
|
pDst2 = (uint32*)(((uint8*)dstPtr)+(ySrc*2+1)*dstPitch);
|
||||||
|
|
||||||
|
for (xSrc = 0; xSrc < nWidth; xSrc++)
|
||||||
|
{
|
||||||
|
b1 = (pSrc[xSrc]>>0)&0xFF;
|
||||||
|
g1 = (pSrc[xSrc]>>8)&0xFF;
|
||||||
|
r1 = (pSrc[xSrc]>>16)&0xFF;
|
||||||
|
a1 = (pSrc[xSrc]>>24)&0xFF;
|
||||||
|
|
||||||
|
if( xSrc<nWidth-1 )
|
||||||
|
{
|
||||||
|
b2 = (pSrc[xSrc+1]>>0)&0xFF;
|
||||||
|
g2 = (pSrc[xSrc+1]>>8)&0xFF;
|
||||||
|
r2 = (pSrc[xSrc+1]>>16)&0xFF;
|
||||||
|
a2 = (pSrc[xSrc+1]>>24)&0xFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( ySrc<nHeight-1 )
|
||||||
|
{
|
||||||
|
b3 = (pSrc2[xSrc]>>0)&0xFF;
|
||||||
|
g3 = (pSrc2[xSrc]>>8)&0xFF;
|
||||||
|
r3 = (pSrc2[xSrc]>>16)&0xFF;
|
||||||
|
a3 = (pSrc2[xSrc]>>24)&0xFF;
|
||||||
|
if( xSrc<nWidth-1 )
|
||||||
|
{
|
||||||
|
b4 = (pSrc2[xSrc+1]>>0)&0xFF;
|
||||||
|
g4 = (pSrc2[xSrc+1]>>8)&0xFF;
|
||||||
|
r4 = (pSrc2[xSrc+1]>>16)&0xFF;
|
||||||
|
a4 = (pSrc2[xSrc+1]>>24)&0xFF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Pixel 1
|
||||||
|
pDst1[xSrc*2] = pSrc[xSrc];
|
||||||
|
|
||||||
|
// Pixel 2
|
||||||
|
if( xSrc<nWidth-1 )
|
||||||
|
{
|
||||||
|
pDst1[xSrc*2+1] = DWORD_MAKE((r1+r2)/2, (g1+g2)/2, (b1+b2)/2, (a1+a2)/2);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
pDst1[xSrc*2+1] = pSrc[xSrc];
|
||||||
|
|
||||||
|
|
||||||
|
// Pixel 3
|
||||||
|
if( ySrc<nHeight-1 )
|
||||||
|
{
|
||||||
|
pDst2[xSrc*2] = DWORD_MAKE((r1+r3)/2, (g1+g3)/2, (b1+b3)/2, (a1+a3)/2);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
pDst2[xSrc*2] = pSrc[xSrc];
|
||||||
|
|
||||||
|
// Pixel 4
|
||||||
|
if( xSrc<nWidth-1 )
|
||||||
|
{
|
||||||
|
if( ySrc<nHeight-1 )
|
||||||
|
{
|
||||||
|
pDst2[xSrc*2+1] = DWORD_MAKE((r1+r2+r3+r4)/4, (g1+g2+g3+g4)/4, (b1+b2+b3+b4)/4, (a1+a2+a3+a4)/4);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pDst2[xSrc*2+1] = DWORD_MAKE((r1+r2)/2, (g1+g2)/2, (b1+b2)/2, (a1+a2)/2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if( ySrc<nHeight-1 )
|
||||||
|
{
|
||||||
|
pDst2[xSrc*2+1] = DWORD_MAKE((r1+r3)/2, (g1+g3)/2, (b1+b3)/2, (a1+a3)/2);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
pDst2[xSrc*2+1] = pSrc[xSrc];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if !_16BPP_HACK
|
||||||
|
// Basic 2x R4G4B4A4 filter with interpolation
|
||||||
|
void Texture2x_16(uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height)
|
||||||
|
{
|
||||||
|
uint16 *pDst1, *pDst2;
|
||||||
|
uint16 *pSrc, *pSrc2;
|
||||||
|
uint32 nWidth = width;
|
||||||
|
uint32 nHeight = height;
|
||||||
|
|
||||||
|
uint16 b1;
|
||||||
|
uint16 g1;
|
||||||
|
uint16 r1;
|
||||||
|
uint16 a1;
|
||||||
|
uint16 b2;
|
||||||
|
uint16 g2;
|
||||||
|
uint16 r2;
|
||||||
|
uint16 a2;
|
||||||
|
uint16 b3;
|
||||||
|
uint16 g3;
|
||||||
|
uint16 r3;
|
||||||
|
uint16 a3;
|
||||||
|
uint16 b4;
|
||||||
|
uint16 g4;
|
||||||
|
uint16 r4;
|
||||||
|
uint16 a4;
|
||||||
|
|
||||||
|
uint16 xSrc;
|
||||||
|
uint16 ySrc;
|
||||||
|
|
||||||
|
for (ySrc = 0; ySrc < nHeight; ySrc++)
|
||||||
|
{
|
||||||
|
pSrc = (uint16*)(((uint8*)srcPtr)+ySrc*srcPitch);
|
||||||
|
pSrc2 = (uint16*)(((uint8*)srcPtr)+(ySrc+1)*srcPitch);
|
||||||
|
pDst1 = (uint16*)(((uint8*)dstPtr)+(ySrc*2)*dstPitch);
|
||||||
|
pDst2 = (uint16*)(((uint8*)dstPtr)+(ySrc*2+1)*dstPitch);
|
||||||
|
|
||||||
|
for (xSrc = 0; xSrc < nWidth; xSrc++)
|
||||||
|
{
|
||||||
|
b1 = (pSrc[xSrc]>> 0)&0xF;
|
||||||
|
g1 = (pSrc[xSrc]>> 4)&0xF;
|
||||||
|
r1 = (pSrc[xSrc]>> 8)&0xF;
|
||||||
|
a1 = (pSrc[xSrc]>>12)&0xF;
|
||||||
|
|
||||||
|
if( xSrc<nWidth-1 )
|
||||||
|
{
|
||||||
|
b2 = (pSrc[xSrc+1]>> 0)&0xF;
|
||||||
|
g2 = (pSrc[xSrc+1]>> 4)&0xF;
|
||||||
|
r2 = (pSrc[xSrc+1]>> 8)&0xF;
|
||||||
|
a2 = (pSrc[xSrc+1]>>12)&0xF;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( ySrc<nHeight-1 )
|
||||||
|
{
|
||||||
|
b3 = (pSrc2[xSrc]>> 0)&0xF;
|
||||||
|
g3 = (pSrc2[xSrc]>> 4)&0xF;
|
||||||
|
r3 = (pSrc2[xSrc]>> 8)&0xF;
|
||||||
|
a3 = (pSrc2[xSrc]>>12)&0xF;
|
||||||
|
if( xSrc<nWidth-1 )
|
||||||
|
{
|
||||||
|
b4 = (pSrc2[xSrc+1]>> 0)&0xF;
|
||||||
|
g4 = (pSrc2[xSrc+1]>> 4)&0xF;
|
||||||
|
r4 = (pSrc2[xSrc+1]>> 8)&0xF;
|
||||||
|
a4 = (pSrc2[xSrc+1]>>12)&0xF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pixel 1
|
||||||
|
pDst1[xSrc*2] = pSrc[xSrc];
|
||||||
|
|
||||||
|
// Pixel 2
|
||||||
|
if( xSrc<nWidth-1 )
|
||||||
|
{
|
||||||
|
pDst1[xSrc*2+1] = WORD_MAKE((r1+r2)/2, (g1+g2)/2, (b1+b2)/2, (a1+a2)/2);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
pDst1[xSrc*2+1] = pSrc[xSrc];
|
||||||
|
|
||||||
|
|
||||||
|
// Pixel 3
|
||||||
|
if( ySrc<nHeight-1 )
|
||||||
|
{
|
||||||
|
pDst2[xSrc*2] = WORD_MAKE((r1+r3)/2, (g1+g3)/2, (b1+b3)/2, (a1+a3)/2);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
pDst2[xSrc*2] = pSrc[xSrc];
|
||||||
|
|
||||||
|
// Pixel 4
|
||||||
|
if( xSrc<nWidth-1 )
|
||||||
|
{
|
||||||
|
if( ySrc<nHeight-1 )
|
||||||
|
{
|
||||||
|
pDst2[xSrc*2+1] = WORD_MAKE((r1+r2+r3+r4)/4, (g1+g2+g3+g4)/4, (b1+b2+b3+b4)/4, (a1+a2+a3+a4)/4);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pDst2[xSrc*2+1] = WORD_MAKE((r1+r2)/2, (g1+g2)/2, (b1+b2)/2, (a1+a2)/2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if( ySrc<nHeight-1 )
|
||||||
|
{
|
||||||
|
pDst2[xSrc*2+1] = WORD_MAKE((r1+r3)/2, (g1+g3)/2, (b1+b3)/2, (a1+a3)/2);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
pDst2[xSrc*2+1] = pSrc[xSrc];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* !_16BPP_HACK */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sharp filters
|
||||||
|
* Hiroshi Morii <koolsmoky@users.sourceforge.net>
|
||||||
|
*/
|
||||||
|
void SharpFilter_8888(uint32 *src, uint32 srcwidth, uint32 srcheight, uint32 *dest, uint32 filter)
|
||||||
|
{
|
||||||
|
// NOTE: for now we get away with copying the boundaries
|
||||||
|
// filter the boundaries if we face problems
|
||||||
|
|
||||||
|
uint32 mul1, mul2, mul3, shift4;
|
||||||
|
|
||||||
|
uint32 x,y,z;
|
||||||
|
uint32 *_src1, *_src2, *_src3, *_dest;
|
||||||
|
uint32 val[4];
|
||||||
|
uint32 t1,t2,t3,t4,t5,t6,t7,t8,t9;
|
||||||
|
|
||||||
|
switch( filter )
|
||||||
|
{
|
||||||
|
case SHARP_FILTER_2:
|
||||||
|
mul1=1;
|
||||||
|
mul2=8;
|
||||||
|
mul3=12;
|
||||||
|
shift4=2;
|
||||||
|
break;
|
||||||
|
case SHARP_FILTER_1:
|
||||||
|
default:
|
||||||
|
mul1=1;
|
||||||
|
mul2=8;
|
||||||
|
mul3=16;
|
||||||
|
shift4=3;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// setup rows
|
||||||
|
_src1 = src;
|
||||||
|
_src2 = _src1 + srcwidth;
|
||||||
|
_src3 = _src2 + srcwidth;
|
||||||
|
_dest = dest;
|
||||||
|
|
||||||
|
// copy the first row
|
||||||
|
memcpy(_dest, _src1, (srcwidth << 2));
|
||||||
|
_dest += srcwidth;
|
||||||
|
// filter 2nd row to 1 row before the last
|
||||||
|
for (y = 1; y < srcheight-1; y++) {
|
||||||
|
// copy the first pixel
|
||||||
|
_dest[0] = *_src2;
|
||||||
|
// filter 2nd pixel to 1 pixel before last
|
||||||
|
for (x = 1; x < srcwidth-1; x++) {
|
||||||
|
for (z=0; z<4; z++) {
|
||||||
|
t1 = *((uint8*)(_src1+x-1)+z);
|
||||||
|
t2 = *((uint8*)(_src1+x )+z);
|
||||||
|
t3 = *((uint8*)(_src1+x+1)+z);
|
||||||
|
t4 = *((uint8*)(_src2+x-1)+z);
|
||||||
|
t5 = *((uint8*)(_src2+x )+z);
|
||||||
|
t6 = *((uint8*)(_src2+x+1)+z);
|
||||||
|
t7 = *((uint8*)(_src3+x-1)+z);
|
||||||
|
t8 = *((uint8*)(_src3+x )+z);
|
||||||
|
t9 = *((uint8*)(_src3+x+1)+z);
|
||||||
|
|
||||||
|
if( (t5*mul2) > (t1+t3+t7+t9+t2+t4+t6+t8)*mul1 ) {
|
||||||
|
val[z]= ((t5*mul3) - (t1+t3+t7+t9+t2+t4+t6+t8)*mul1)>>shift4;
|
||||||
|
if (val[z] > 0xFF) val[z] = 0xFF;
|
||||||
|
} else {
|
||||||
|
val[z] = t5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_dest[x] = val[0]|(val[1]<<8)|(val[2]<<16)|(val[3]<<24);
|
||||||
|
}
|
||||||
|
// copy the ending pixel
|
||||||
|
_dest[srcwidth-1] = *(_src3 - 1);
|
||||||
|
// next row
|
||||||
|
_src1 += srcwidth;
|
||||||
|
_src2 += srcwidth;
|
||||||
|
_src3 += srcwidth;
|
||||||
|
_dest += srcwidth;
|
||||||
|
}
|
||||||
|
// copy the last row
|
||||||
|
memcpy(_dest, _src2, (srcwidth << 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
#if !_16BPP_HACK
|
||||||
|
void SharpFilter_4444(uint16 *src, uint32 srcwidth, uint32 srcheight, uint16 *dest, uint32 filter)
|
||||||
|
{
|
||||||
|
// NOTE: for now we get away with copying the boundaries
|
||||||
|
// filter the boundaries if we face problems
|
||||||
|
|
||||||
|
uint16 mul1, mul2, mul3, shift4;
|
||||||
|
|
||||||
|
uint32 x,y,z;
|
||||||
|
uint16 *_src1, *_src2, *_src3, *_dest;
|
||||||
|
uint16 val[4];
|
||||||
|
uint16 t1,t2,t3,t4,t5,t6,t7,t8,t9;
|
||||||
|
|
||||||
|
switch( filter ) {
|
||||||
|
case SHARP_FILTER_2:
|
||||||
|
mul1=1;
|
||||||
|
mul2=8;
|
||||||
|
mul3=12;
|
||||||
|
shift4=2;
|
||||||
|
break;
|
||||||
|
case SHARP_FILTER_1:
|
||||||
|
default:
|
||||||
|
mul1=1;
|
||||||
|
mul2=8;
|
||||||
|
mul3=16;
|
||||||
|
shift4=3;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// setup rows
|
||||||
|
_src1 = src;
|
||||||
|
_src2 = _src1 + srcwidth;
|
||||||
|
_src3 = _src2 + srcwidth;
|
||||||
|
_dest = dest;
|
||||||
|
|
||||||
|
// copy the first row
|
||||||
|
memcpy(_dest, _src1, (srcwidth << 1));
|
||||||
|
_dest += srcwidth;
|
||||||
|
// filter 2nd row to 1 row before the last
|
||||||
|
for( y = 1; y < srcheight - 1; y++) {
|
||||||
|
// copy the first pixel
|
||||||
|
_dest[0] = *_src2;
|
||||||
|
// filter 2nd pixel to 1 pixel before last
|
||||||
|
for( x = 1; x < srcwidth - 1; x++) {
|
||||||
|
for( z = 0; z < 4; z++ ) {
|
||||||
|
/* Hiroshi Morii <koolsmoky@users.sourceforge.net>
|
||||||
|
* Read the entire 16bit pixel and then extract the A,R,G,B components.
|
||||||
|
*/
|
||||||
|
uint32 shift = z << 2;
|
||||||
|
t1 = ((*((uint16*)(_src1+x-1))) >> shift) & 0xF;
|
||||||
|
t2 = ((*((uint16*)(_src1+x ))) >> shift) & 0xF;
|
||||||
|
t3 = ((*((uint16*)(_src1+x+1))) >> shift) & 0xF;
|
||||||
|
t4 = ((*((uint16*)(_src2+x-1))) >> shift) & 0xF;
|
||||||
|
t5 = ((*((uint16*)(_src2+x ))) >> shift) & 0xF;
|
||||||
|
t6 = ((*((uint16*)(_src2+x+1))) >> shift) & 0xF;
|
||||||
|
t7 = ((*((uint16*)(_src3+x-1))) >> shift) & 0xF;
|
||||||
|
t8 = ((*((uint16*)(_src3+x ))) >> shift) & 0xF;
|
||||||
|
t9 = ((*((uint16*)(_src3+x+1))) >> shift) & 0xF;
|
||||||
|
|
||||||
|
if( (t5*mul2) > (t1+t3+t7+t9+t2+t4+t6+t8)*mul1 ) {
|
||||||
|
val[z] = ((t5*mul3) - (t1+t3+t7+t9+t2+t4+t6+t8)*mul1)>>shift4;
|
||||||
|
if (val[z] > 0xF) val[z] = 0xF;
|
||||||
|
} else {
|
||||||
|
val[z] = t5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_dest[x] = val[0]|(val[1]<<4)|(val[2]<<8)|(val[3]<<12);
|
||||||
|
}
|
||||||
|
// copy the ending pixel
|
||||||
|
_dest[srcwidth-1] = *(_src3 - 1);
|
||||||
|
// next row
|
||||||
|
_src1 += srcwidth;
|
||||||
|
_src2 += srcwidth;
|
||||||
|
_src3 += srcwidth;
|
||||||
|
_dest += srcwidth;
|
||||||
|
}
|
||||||
|
// copy the last row
|
||||||
|
memcpy(_dest, _src2, (srcwidth << 1));
|
||||||
|
}
|
||||||
|
#endif /* !_16BPP_HACK */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Smooth filters
|
||||||
|
* Hiroshi Morii <koolsmoky@users.sourceforge.net>
|
||||||
|
*/
|
||||||
|
void SmoothFilter_8888(uint32 *src, uint32 srcwidth, uint32 srcheight, uint32 *dest, uint32 filter)
|
||||||
|
{
|
||||||
|
// NOTE: for now we get away with copying the boundaries
|
||||||
|
// filter the boundaries if we face problems
|
||||||
|
|
||||||
|
uint32 mul1, mul2, mul3, shift4;
|
||||||
|
|
||||||
|
uint32 x,y,z;
|
||||||
|
uint32 *_src1, *_src2, *_src3, *_dest;
|
||||||
|
uint32 val[4];
|
||||||
|
uint32 t1,t2,t3,t4,t5,t6,t7,t8,t9;
|
||||||
|
|
||||||
|
switch( filter ) {
|
||||||
|
case SMOOTH_FILTER_4:
|
||||||
|
mul1=1;
|
||||||
|
mul2=2;
|
||||||
|
mul3=4;
|
||||||
|
shift4=4;
|
||||||
|
break;
|
||||||
|
case SMOOTH_FILTER_3:
|
||||||
|
mul1=1;
|
||||||
|
mul2=1;
|
||||||
|
mul3=8;
|
||||||
|
shift4=4;
|
||||||
|
break;
|
||||||
|
case SMOOTH_FILTER_2:
|
||||||
|
mul1=1;
|
||||||
|
mul2=1;
|
||||||
|
mul3=2;
|
||||||
|
shift4=2;
|
||||||
|
break;
|
||||||
|
case SMOOTH_FILTER_1:
|
||||||
|
default:
|
||||||
|
mul1=1;
|
||||||
|
mul2=1;
|
||||||
|
mul3=6;
|
||||||
|
shift4=3;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (filter) {
|
||||||
|
case SMOOTH_FILTER_3:
|
||||||
|
case SMOOTH_FILTER_4:
|
||||||
|
// setup rows
|
||||||
|
_src1 = src;
|
||||||
|
_src2 = _src1 + srcwidth;
|
||||||
|
_src3 = _src2 + srcwidth;
|
||||||
|
_dest = dest;
|
||||||
|
// copy the first row
|
||||||
|
memcpy(_dest, _src1, (srcwidth << 2));
|
||||||
|
_dest += srcwidth;
|
||||||
|
// filter 2nd row to 1 row before the last
|
||||||
|
for (y = 1; y < srcheight - 1; y++){
|
||||||
|
// copy the first pixel
|
||||||
|
_dest[0] = _src2[0];
|
||||||
|
// filter 2nd pixel to 1 pixel before last
|
||||||
|
for (x = 1; x < srcwidth - 1; x++) {
|
||||||
|
for (z = 0; z < 4; z++ ) {
|
||||||
|
t1 = *((uint8*)(_src1+x-1)+z);
|
||||||
|
t2 = *((uint8*)(_src1+x )+z);
|
||||||
|
t3 = *((uint8*)(_src1+x+1)+z);
|
||||||
|
t4 = *((uint8*)(_src2+x-1)+z);
|
||||||
|
t5 = *((uint8*)(_src2+x )+z);
|
||||||
|
t6 = *((uint8*)(_src2+x+1)+z);
|
||||||
|
t7 = *((uint8*)(_src3+x-1)+z);
|
||||||
|
t8 = *((uint8*)(_src3+x )+z);
|
||||||
|
t9 = *((uint8*)(_src3+x+1)+z);
|
||||||
|
/* the component value must not overflow 0xFF */
|
||||||
|
val[z] = ((t1+t3+t7+t9)*mul1+((t2+t4+t6+t8)*mul2)+(t5*mul3))>>shift4;
|
||||||
|
if (val[z] > 0xFF) val[z] = 0xFF;
|
||||||
|
}
|
||||||
|
_dest[x] = val[0]|(val[1]<<8)|(val[2]<<16)|(val[3]<<24);
|
||||||
|
}
|
||||||
|
// copy the ending pixel
|
||||||
|
_dest[srcwidth-1] = *(_src3 - 1);
|
||||||
|
// next row
|
||||||
|
_src1 += srcwidth;
|
||||||
|
_src2 += srcwidth;
|
||||||
|
_src3 += srcwidth;
|
||||||
|
_dest += srcwidth;
|
||||||
|
}
|
||||||
|
// copy the last row
|
||||||
|
memcpy(_dest, _src2, (srcwidth << 2));
|
||||||
|
break;
|
||||||
|
case SMOOTH_FILTER_1:
|
||||||
|
case SMOOTH_FILTER_2:
|
||||||
|
default:
|
||||||
|
// setup rows
|
||||||
|
_src1 = src;
|
||||||
|
_src2 = _src1 + srcwidth;
|
||||||
|
_src3 = _src2 + srcwidth;
|
||||||
|
_dest = dest;
|
||||||
|
// copy the first row
|
||||||
|
memcpy(_dest, _src1, (srcwidth << 2));
|
||||||
|
_dest += srcwidth;
|
||||||
|
// filter 2nd row to 1 row before the last
|
||||||
|
for (y = 1; y < srcheight - 1; y++) {
|
||||||
|
// filter 1st pixel to the last
|
||||||
|
if (y & 1) {
|
||||||
|
for( x = 0; x < srcwidth; x++) {
|
||||||
|
for( z = 0; z < 4; z++ ) {
|
||||||
|
t2 = *((uint8*)(_src1+x )+z);
|
||||||
|
t5 = *((uint8*)(_src2+x )+z);
|
||||||
|
t8 = *((uint8*)(_src3+x )+z);
|
||||||
|
/* the component value must not overflow 0xFF */
|
||||||
|
val[z] = ((t2+t8)*mul2+(t5*mul3))>>shift4;
|
||||||
|
if (val[z] > 0xFF) val[z] = 0xFF;
|
||||||
|
}
|
||||||
|
_dest[x] = val[0]|(val[1]<<8)|(val[2]<<16)|(val[3]<<24);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
memcpy(_dest, _src2, (srcwidth << 2));
|
||||||
|
}
|
||||||
|
// next row
|
||||||
|
_src1 += srcwidth;
|
||||||
|
_src2 += srcwidth;
|
||||||
|
_src3 += srcwidth;
|
||||||
|
_dest += srcwidth;
|
||||||
|
}
|
||||||
|
// copy the last row
|
||||||
|
memcpy(_dest, _src2, (srcwidth << 2));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if !_16BPP_HACK
|
||||||
|
void SmoothFilter_4444(uint16 *src, uint32 srcwidth, uint32 srcheight, uint16 *dest, uint32 filter)
|
||||||
|
{
|
||||||
|
// NOTE: for now we get away with copying the boundaries
|
||||||
|
// filter the boundaries if we face problems
|
||||||
|
|
||||||
|
uint16 mul1, mul2, mul3, shift4;
|
||||||
|
|
||||||
|
uint32 x,y,z;
|
||||||
|
uint16 *_src1, *_src2, *_src3, *_dest;
|
||||||
|
uint16 val[4];
|
||||||
|
uint16 t1,t2,t3,t4,t5,t6,t7,t8,t9;
|
||||||
|
|
||||||
|
switch( filter ) {
|
||||||
|
case SMOOTH_FILTER_4:
|
||||||
|
mul1=1;
|
||||||
|
mul2=2;
|
||||||
|
mul3=4;
|
||||||
|
shift4=4;
|
||||||
|
break;
|
||||||
|
case SMOOTH_FILTER_3:
|
||||||
|
mul1=1;
|
||||||
|
mul2=1;
|
||||||
|
mul3=8;
|
||||||
|
shift4=4;
|
||||||
|
break;
|
||||||
|
case SMOOTH_FILTER_2:
|
||||||
|
mul1=1;
|
||||||
|
mul2=1;
|
||||||
|
mul3=2;
|
||||||
|
shift4=2;
|
||||||
|
break;
|
||||||
|
case SMOOTH_FILTER_1:
|
||||||
|
default:
|
||||||
|
mul1=1;
|
||||||
|
mul2=1;
|
||||||
|
mul3=6;
|
||||||
|
shift4=3;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (filter) {
|
||||||
|
case SMOOTH_FILTER_3:
|
||||||
|
case SMOOTH_FILTER_4:
|
||||||
|
// setup rows
|
||||||
|
_src1 = src;
|
||||||
|
_src2 = _src1 + srcwidth;
|
||||||
|
_src3 = _src2 + srcwidth;
|
||||||
|
_dest = dest;
|
||||||
|
// copy the first row
|
||||||
|
memcpy(_dest, _src1, (srcwidth << 1));
|
||||||
|
_dest += srcwidth;
|
||||||
|
// filter 2nd row to 1 row before the last
|
||||||
|
for (y = 1; y < srcheight - 1; y++) {
|
||||||
|
// copy the first pixel
|
||||||
|
_dest[0] = *_src2;
|
||||||
|
// filter 2nd pixel to 1 pixel before last
|
||||||
|
for (x = 1; x < srcwidth - 1; x++) {
|
||||||
|
for (z = 0; z < 4; z++ ) {
|
||||||
|
/* Read the entire 16bit pixel and then extract the A,R,G,B components. */
|
||||||
|
uint32 shift = z << 2;
|
||||||
|
t1 = ((*(uint16*)(_src1+x-1)) >> shift) & 0xF;
|
||||||
|
t2 = ((*(uint16*)(_src1+x )) >> shift) & 0xF;
|
||||||
|
t3 = ((*(uint16*)(_src1+x+1)) >> shift) & 0xF;
|
||||||
|
t4 = ((*(uint16*)(_src2+x-1)) >> shift) & 0xF;
|
||||||
|
t5 = ((*(uint16*)(_src2+x )) >> shift) & 0xF;
|
||||||
|
t6 = ((*(uint16*)(_src2+x+1)) >> shift) & 0xF;
|
||||||
|
t7 = ((*(uint16*)(_src3+x-1)) >> shift) & 0xF;
|
||||||
|
t8 = ((*(uint16*)(_src3+x )) >> shift) & 0xF;
|
||||||
|
t9 = ((*(uint16*)(_src3+x+1)) >> shift) & 0xF;
|
||||||
|
/* the component value must not overflow 0xF */
|
||||||
|
val[z] = ((t1+t3+t7+t9)*mul1+((t2+t4+t6+t8)*mul2)+(t5*mul3))>>shift4;
|
||||||
|
if (val[z] > 0xF) val[z] = 0xF;
|
||||||
|
}
|
||||||
|
_dest[x] = val[0]|(val[1]<<4)|(val[2]<<8)|(val[3]<<12);
|
||||||
|
}
|
||||||
|
// copy the ending pixel
|
||||||
|
_dest[srcwidth-1] = *(_src3 - 1);
|
||||||
|
// next row
|
||||||
|
_src1 += srcwidth;
|
||||||
|
_src2 += srcwidth;
|
||||||
|
_src3 += srcwidth;
|
||||||
|
_dest += srcwidth;
|
||||||
|
}
|
||||||
|
// copy the last row
|
||||||
|
memcpy(_dest, _src2, (srcwidth << 1));
|
||||||
|
break;
|
||||||
|
case SMOOTH_FILTER_1:
|
||||||
|
case SMOOTH_FILTER_2:
|
||||||
|
default:
|
||||||
|
// setup rows
|
||||||
|
_src1 = src;
|
||||||
|
_src2 = _src1 + srcwidth;
|
||||||
|
_src3 = _src2 + srcwidth;
|
||||||
|
_dest = dest;
|
||||||
|
// copy the first row
|
||||||
|
memcpy(_dest, _src1, (srcwidth << 1));
|
||||||
|
_dest += srcwidth;
|
||||||
|
// filter 2nd row to 1 row before the last
|
||||||
|
for( y = 1; y < srcheight - 1; y++) {
|
||||||
|
if (y & 1) {
|
||||||
|
for( x = 0; x < srcwidth; x++) {
|
||||||
|
for( z = 0; z < 4; z++ ) {
|
||||||
|
/* Read the entire 16bit pixel and then extract the A,R,G,B components. */
|
||||||
|
uint32 shift = z << 2;
|
||||||
|
t2 = ((*(uint16*)(_src1+x)) >> shift) & 0xF;
|
||||||
|
t5 = ((*(uint16*)(_src2+x)) >> shift) & 0xF;
|
||||||
|
t8 = ((*(uint16*)(_src3+x)) >> shift) & 0xF;
|
||||||
|
/* the component value must not overflow 0xF */
|
||||||
|
val[z] = ((t2+t8)*mul2+(t5*mul3))>>shift4;
|
||||||
|
if (val[z] > 0xF) val[z] = 0xF;
|
||||||
|
}
|
||||||
|
_dest[x] = val[0]|(val[1]<<4)|(val[2]<<8)|(val[3]<<12);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
memcpy(_dest, _src2, (srcwidth << 1));
|
||||||
|
}
|
||||||
|
// next row
|
||||||
|
_src1 += srcwidth;
|
||||||
|
_src2 += srcwidth;
|
||||||
|
_src3 += srcwidth;
|
||||||
|
_dest += srcwidth;
|
||||||
|
}
|
||||||
|
// copy the last row
|
||||||
|
memcpy(_dest, _src2, (srcwidth << 1));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* !_16BPP_HACK */
|
||||||
|
|
||||||
|
void filter_8888(uint32 *src, uint32 srcwidth, uint32 srcheight, uint32 *dest, uint32 filter) {
|
||||||
|
switch (filter & ENHANCEMENT_MASK) {
|
||||||
|
case HQ4X_ENHANCEMENT:
|
||||||
|
hq4x_8888((uint8*)src, (uint8*)dest, srcwidth, srcheight, srcwidth, (srcwidth << 4));
|
||||||
|
return;
|
||||||
|
case HQ2X_ENHANCEMENT:
|
||||||
|
hq2x_32((uint8*)src, (srcwidth << 2), (uint8*)dest, (srcwidth << 3), srcwidth, srcheight);
|
||||||
|
return;
|
||||||
|
case HQ2XS_ENHANCEMENT:
|
||||||
|
hq2xS_32((uint8*)src, (srcwidth << 2), (uint8*)dest, (srcwidth << 3), srcwidth, srcheight);
|
||||||
|
return;
|
||||||
|
case LQ2X_ENHANCEMENT:
|
||||||
|
lq2x_32((uint8*)src, (srcwidth << 2), (uint8*)dest, (srcwidth << 3), srcwidth, srcheight);
|
||||||
|
return;
|
||||||
|
case LQ2XS_ENHANCEMENT:
|
||||||
|
lq2xS_32((uint8*)src, (srcwidth << 2), (uint8*)dest, (srcwidth << 3), srcwidth, srcheight);
|
||||||
|
return;
|
||||||
|
case X2SAI_ENHANCEMENT:
|
||||||
|
Super2xSaI_8888((uint32*)src, (uint32*)dest, srcwidth, srcheight, srcwidth);
|
||||||
|
return;
|
||||||
|
case X2_ENHANCEMENT:
|
||||||
|
Texture2x_32((uint8*)src, (srcwidth << 2), (uint8*)dest, (srcwidth << 3), srcwidth, srcheight);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (filter & (SMOOTH_FILTER_MASK|SHARP_FILTER_MASK)) {
|
||||||
|
case SMOOTH_FILTER_1:
|
||||||
|
case SMOOTH_FILTER_2:
|
||||||
|
case SMOOTH_FILTER_3:
|
||||||
|
case SMOOTH_FILTER_4:
|
||||||
|
SmoothFilter_8888((uint32*)src, srcwidth, srcheight, (uint32*)dest, (filter & SMOOTH_FILTER_MASK));
|
||||||
|
return;
|
||||||
|
case SHARP_FILTER_1:
|
||||||
|
case SHARP_FILTER_2:
|
||||||
|
SharpFilter_8888((uint32*)src, srcwidth, srcheight, (uint32*)dest, (filter & SHARP_FILTER_MASK));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
81
GLideNHQ/TextureFilters.h
Normal file
81
GLideNHQ/TextureFilters.h
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
/*
|
||||||
|
* Texture Filtering
|
||||||
|
* Version: 1.0
|
||||||
|
*
|
||||||
|
* Copyright (C) 2007 Hiroshi Morii All Rights Reserved.
|
||||||
|
* Email koolsmoky(at)users.sourceforge.net
|
||||||
|
* Web http://www.3dfxzone.it/koolsmoky
|
||||||
|
*
|
||||||
|
* this 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, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* this 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 GNU Make; see the file COPYING. If not, write to
|
||||||
|
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __TEXTUREFILTERS_H__
|
||||||
|
#define __TEXTUREFILTERS_H__
|
||||||
|
|
||||||
|
/* 16bpp filters are somewhat buggy and output image is not clean.
|
||||||
|
* Since there's not much time, we'll just convert them to ARGB8888
|
||||||
|
* and use 32bpp filters until fixed.
|
||||||
|
* (1:enable hack, 0:disable hack) */
|
||||||
|
#define _16BPP_HACK 1
|
||||||
|
|
||||||
|
#include "TxInternal.h"
|
||||||
|
|
||||||
|
/* enhancers */
|
||||||
|
void hq4x_8888(unsigned char * pIn, unsigned char * pOut, int Xres, int Yres, int SrcPPL, int BpL);
|
||||||
|
|
||||||
|
void hq2x_32(uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height);
|
||||||
|
void hq2xS_32(uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height);
|
||||||
|
|
||||||
|
void lq2x_32(uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height);
|
||||||
|
void lq2xS_32(uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height);
|
||||||
|
|
||||||
|
void Super2xSaI_8888(uint32 *srcPtr, uint32 *destPtr, uint32 width, uint32 height, uint32 pitch);
|
||||||
|
|
||||||
|
void Texture2x_32(uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height);
|
||||||
|
|
||||||
|
/* filters */
|
||||||
|
void SharpFilter_8888(uint32 *src, uint32 srcwidth, uint32 srcheight, uint32 *dest, uint32 filter);
|
||||||
|
|
||||||
|
void SmoothFilter_8888(uint32 *src, uint32 srcwidth, uint32 srcheight, uint32 *dest, uint32 filter);
|
||||||
|
|
||||||
|
/* helper */
|
||||||
|
void filter_8888(uint32 *src, uint32 srcwidth, uint32 srcheight, uint32 *dest, uint32 filter);
|
||||||
|
|
||||||
|
#if !_16BPP_HACK
|
||||||
|
void hq4x_init(void);
|
||||||
|
void hq4x_4444(unsigned char * pIn, unsigned char * pOut, int Xres, int Yres, int SrcPPL, int BpL);
|
||||||
|
void hq4x_1555(unsigned char * pIn, unsigned char * pOut, int Xres, int Yres, int SrcPPL, int BpL);
|
||||||
|
void hq4x_565 (unsigned char * pIn, unsigned char * pOut, int Xres, int Yres, int SrcPPL, int BpL);
|
||||||
|
|
||||||
|
void hq2x_16(uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height);
|
||||||
|
void hq2xS_16(uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height);
|
||||||
|
|
||||||
|
void lq2x_16(uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height);
|
||||||
|
void lq2xS_16(uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height);
|
||||||
|
|
||||||
|
void Super2xSaI_4444(uint16 *srcPtr, uint16 *destPtr, uint32 width, uint32 height, uint32 pitch);
|
||||||
|
void Super2xSaI_1555(uint16 *srcPtr, uint16 *destPtr, uint32 width, uint32 height, uint32 pitch);
|
||||||
|
void Super2xSaI_565 (uint16 *srcPtr, uint16 *destPtr, uint32 width, uint32 height, uint32 pitch);
|
||||||
|
void Super2xSaI_8 (uint8 *srcPtr, uint8 *destPtr, uint32 width, uint32 height, uint32 pitch);
|
||||||
|
|
||||||
|
void Texture2x_16(uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height);
|
||||||
|
|
||||||
|
void SharpFilter_4444(uint16 *src, uint32 srcwidth, uint32 srcheight, uint16 *dest, uint32 filter);
|
||||||
|
|
||||||
|
void SmoothFilter_4444(uint16 *src, uint32 srcwidth, uint32 srcheight, uint16 *dest, uint32 filter);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __TEXTUREFILTERS_H__ */
|
155
GLideNHQ/TextureFilters_2xsai.cpp
Normal file
155
GLideNHQ/TextureFilters_2xsai.cpp
Normal file
|
@ -0,0 +1,155 @@
|
||||||
|
/*
|
||||||
|
* Texture Filtering
|
||||||
|
* Version: 1.0
|
||||||
|
*
|
||||||
|
* Copyright (C) 2007 Hiroshi Morii All Rights Reserved.
|
||||||
|
* Email koolsmoky(at)users.sourceforge.net
|
||||||
|
* Web http://www.3dfxzone.it/koolsmoky
|
||||||
|
*
|
||||||
|
* this 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, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* this 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 GNU Make; see the file COPYING. If not, write to
|
||||||
|
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Based on Derek Liauw Kie Fa and Rice1964 Super2xSaI code */
|
||||||
|
|
||||||
|
#include "TextureFilters.h"
|
||||||
|
|
||||||
|
#define GET_RESULT(A, B, C, D) ((A != C || A != D) - (B != C || B != D))
|
||||||
|
|
||||||
|
void Super2xSaI_8888(uint32 *srcPtr, uint32 *destPtr, uint32 width, uint32 height, uint32 pitch)
|
||||||
|
{
|
||||||
|
#define SAI_INTERPOLATE_8888(A, B) ((A & 0xFEFEFEFE) >> 1) + ((B & 0xFEFEFEFE) >> 1) + (A & B & 0x01010101)
|
||||||
|
#define SAI_Q_INTERPOLATE_8888(A, B, C, D) ((A & 0xFCFCFCFC) >> 2) + ((B & 0xFCFCFCFC) >> 2) + ((C & 0xFCFCFCFC) >> 2) + ((D & 0xFCFCFCFC) >> 2) \
|
||||||
|
+ ((((A & 0x03030303) + (B & 0x03030303) + (C & 0x03030303) + (D & 0x03030303)) >> 2) & 0x03030303)
|
||||||
|
|
||||||
|
#define SAI_INTERPOLATE SAI_INTERPOLATE_8888
|
||||||
|
#define SAI_Q_INTERPOLATE SAI_Q_INTERPOLATE_8888
|
||||||
|
|
||||||
|
uint32 destWidth = width << 1;
|
||||||
|
uint32 destHeight = height << 1;
|
||||||
|
|
||||||
|
uint32 color4, color5, color6;
|
||||||
|
uint32 color1, color2, color3;
|
||||||
|
uint32 colorA0, colorA1, colorA2, colorA3;
|
||||||
|
uint32 colorB0, colorB1, colorB2, colorB3;
|
||||||
|
uint32 colorS1, colorS2;
|
||||||
|
uint32 product1a, product1b, product2a, product2b;
|
||||||
|
|
||||||
|
#include "TextureFilters_2xsai.h"
|
||||||
|
|
||||||
|
#undef SAI_INTERPOLATE
|
||||||
|
#undef SAI_Q_INTERPOLATE
|
||||||
|
}
|
||||||
|
|
||||||
|
#if !_16BPP_HACK
|
||||||
|
void Super2xSaI_4444(uint16 *srcPtr, uint16 *destPtr, uint32 width, uint32 height, uint32 pitch)
|
||||||
|
{
|
||||||
|
#define SAI_INTERPOLATE_4444(A, B) ((A & 0xEEEE) >> 1) + ((B & 0xEEEE) >> 1) + (A & B & 0x1111)
|
||||||
|
#define SAI_Q_INTERPOLATE_4444(A, B, C, D) ((A & 0xCCCC) >> 2) + ((B & 0xCCCC) >> 2) + ((C & 0xCCCC) >> 2) + ((D & 0xCCCC) >> 2) \
|
||||||
|
+ ((((A & 0x3333) + (B & 0x3333) + (C & 0x3333) + (D & 0x3333)) >> 2) & 0x3333)
|
||||||
|
|
||||||
|
#define SAI_INTERPOLATE SAI_INTERPOLATE_4444
|
||||||
|
#define SAI_Q_INTERPOLATE SAI_Q_INTERPOLATE_4444
|
||||||
|
|
||||||
|
uint32 destWidth = width << 1;
|
||||||
|
uint32 destHeight = height << 1;
|
||||||
|
|
||||||
|
uint16 color4, color5, color6;
|
||||||
|
uint16 color1, color2, color3;
|
||||||
|
uint16 colorA0, colorA1, colorA2, colorA3;
|
||||||
|
uint16 colorB0, colorB1, colorB2, colorB3;
|
||||||
|
uint16 colorS1, colorS2;
|
||||||
|
uint16 product1a, product1b, product2a, product2b;
|
||||||
|
|
||||||
|
#include "TextureFilters_2xsai.h"
|
||||||
|
|
||||||
|
#undef SAI_INTERPOLATE
|
||||||
|
#undef SAI_Q_INTERPOLATE
|
||||||
|
}
|
||||||
|
|
||||||
|
void Super2xSaI_1555(uint16 *srcPtr, uint16 *destPtr, uint32 width, uint32 height, uint32 pitch)
|
||||||
|
{
|
||||||
|
#define SAI_INTERPOLATE_1555(A, B) ((A & 0x7BDE) >> 1) + ((B & 0x7BDE) >> 1) + (A & B & 0x8421)
|
||||||
|
#define SAI_Q_INTERPOLATE_1555(A, B, C, D) ((A & 0x739C) >> 2) + ((B & 0x739C) >> 2) + ((C & 0x739C) >> 2) + ((D & 0x739C) >> 2) \
|
||||||
|
+ ((((A & 0x8C63) + (B & 0x8C63) + (C & 0x8C63) + (D & 0x8C63)) >> 2) & 0x8C63)
|
||||||
|
|
||||||
|
#define SAI_INTERPOLATE SAI_INTERPOLATE_1555
|
||||||
|
#define SAI_Q_INTERPOLATE SAI_Q_INTERPOLATE_1555
|
||||||
|
|
||||||
|
uint32 destWidth = width << 1;
|
||||||
|
uint32 destHeight = height << 1;
|
||||||
|
|
||||||
|
uint16 color4, color5, color6;
|
||||||
|
uint16 color1, color2, color3;
|
||||||
|
uint16 colorA0, colorA1, colorA2, colorA3;
|
||||||
|
uint16 colorB0, colorB1, colorB2, colorB3;
|
||||||
|
uint16 colorS1, colorS2;
|
||||||
|
uint16 product1a, product1b, product2a, product2b;
|
||||||
|
|
||||||
|
#include "TextureFilters_2xsai.h"
|
||||||
|
|
||||||
|
#undef SAI_INTERPOLATE
|
||||||
|
#undef SAI_Q_INTERPOLATE
|
||||||
|
}
|
||||||
|
|
||||||
|
void Super2xSaI_565(uint16 *srcPtr, uint16 *destPtr, uint32 width, uint32 height, uint32 pitch)
|
||||||
|
{
|
||||||
|
#define SAI_INTERPOLATE_565(A, B) ((A & 0xF7DE) >> 1) + ((B & 0xF7DE) >> 1) + (A & B & 0x0821)
|
||||||
|
#define SAI_Q_INTERPOLATE_565(A, B, C, D) ((A & 0xE79C) >> 2) + ((B & 0xE79C) >> 2) + ((C & 0xE79C) >> 2) + ((D & 0xE79C) >> 2) \
|
||||||
|
+ ((((A & 0x1863) + (B & 0x1863) + (C & 0x1863) + (D & 0x1863)) >> 2) & 0x1863)
|
||||||
|
|
||||||
|
#define SAI_INTERPOLATE SAI_INTERPOLATE_565
|
||||||
|
#define SAI_Q_INTERPOLATE SAI_Q_INTERPOLATE_565
|
||||||
|
|
||||||
|
uint32 destWidth = width << 1;
|
||||||
|
uint32 destHeight = height << 1;
|
||||||
|
|
||||||
|
uint16 color4, color5, color6;
|
||||||
|
uint16 color1, color2, color3;
|
||||||
|
uint16 colorA0, colorA1, colorA2, colorA3;
|
||||||
|
uint16 colorB0, colorB1, colorB2, colorB3;
|
||||||
|
uint16 colorS1, colorS2;
|
||||||
|
uint16 product1a, product1b, product2a, product2b;
|
||||||
|
|
||||||
|
#include "TextureFilters_2xsai.h"
|
||||||
|
|
||||||
|
#undef SAI_INTERPOLATE
|
||||||
|
#undef SAI_Q_INTERPOLATE
|
||||||
|
}
|
||||||
|
|
||||||
|
void Super2xSaI_8(uint8 *srcPtr, uint8 *destPtr, uint32 width, uint32 height, uint32 pitch)
|
||||||
|
{
|
||||||
|
#define SAI_INTERPOLATE_8(A, B) ((A & 0xFE) >> 1) + ((B & 0xFE) >> 1) + (A & B & 0x01)
|
||||||
|
#define SAI_Q_INTERPOLATE_8(A, B, C, D) ((A & 0xFC) >> 2) + ((B & 0xFC) >> 2) + ((C & 0xFC) >> 2) + ((D & 0xFC) >> 2) \
|
||||||
|
+ ((((A & 0x03) + (B & 0x03) + (C & 0x03) + (D & 0x03)) >> 2) & 0x03)
|
||||||
|
|
||||||
|
#define SAI_INTERPOLATE SAI_INTERPOLATE_8
|
||||||
|
#define SAI_Q_INTERPOLATE SAI_Q_INTERPOLATE_8
|
||||||
|
|
||||||
|
uint32 destWidth = width << 1;
|
||||||
|
uint32 destHeight = height << 1;
|
||||||
|
|
||||||
|
uint8 color4, color5, color6;
|
||||||
|
uint8 color1, color2, color3;
|
||||||
|
uint8 colorA0, colorA1, colorA2, colorA3;
|
||||||
|
uint8 colorB0, colorB1, colorB2, colorB3;
|
||||||
|
uint8 colorS1, colorS2;
|
||||||
|
uint8 product1a, product1b, product2a, product2b;
|
||||||
|
|
||||||
|
#include "TextureFilters_2xsai.h"
|
||||||
|
|
||||||
|
#undef SAI_INTERPOLATE
|
||||||
|
#undef SAI_Q_INTERPOLATE
|
||||||
|
}
|
||||||
|
#endif /* !_16BPP_HACK */
|
145
GLideNHQ/TextureFilters_2xsai.h
Normal file
145
GLideNHQ/TextureFilters_2xsai.h
Normal file
|
@ -0,0 +1,145 @@
|
||||||
|
/*
|
||||||
|
* Texture Filtering
|
||||||
|
* Version: 1.0
|
||||||
|
*
|
||||||
|
* Copyright (C) 2007 Hiroshi Morii All Rights Reserved.
|
||||||
|
* Email koolsmoky(at)users.sourceforge.net
|
||||||
|
* Web http://www.3dfxzone.it/koolsmoky
|
||||||
|
*
|
||||||
|
* this 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, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* this 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 GNU Make; see the file COPYING. If not, write to
|
||||||
|
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Based on Derek Liauw Kie Fa and Rice1964 Super2xSaI code */
|
||||||
|
|
||||||
|
int row0, row1, row2, row3;
|
||||||
|
int col0, col1, col2, col3;
|
||||||
|
|
||||||
|
uint16 x;
|
||||||
|
uint16 y;
|
||||||
|
|
||||||
|
for (y = 0; y < height; y++) {
|
||||||
|
if ((y > 0) && (y < height - 1)) {
|
||||||
|
row0 = width;
|
||||||
|
row0 = -row0;
|
||||||
|
row1 = 0;
|
||||||
|
row2 = width;
|
||||||
|
row3 = (y == height - 2 ? width : width << 1);
|
||||||
|
} else {
|
||||||
|
row0 = 0;
|
||||||
|
row1 = 0;
|
||||||
|
row2 = 0;
|
||||||
|
row3 = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (x = 0; x < width; x++) {
|
||||||
|
//--------------------------------------- B0 B1 B2 B3
|
||||||
|
// 4 5 6 S2
|
||||||
|
// 1 2 3 S1
|
||||||
|
// A0 A1 A2 A3
|
||||||
|
if ((x > 0) && (x < width - 1)) {
|
||||||
|
col0 = -1;
|
||||||
|
col1 = 0;
|
||||||
|
col2 = 1;
|
||||||
|
col3 = (x == width - 2 ? 1 : 2);
|
||||||
|
} else {
|
||||||
|
col0 = 0;
|
||||||
|
col1 = 0;
|
||||||
|
col2 = 0;
|
||||||
|
col3 = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
colorB0 = *(srcPtr + col0 + row0);
|
||||||
|
colorB1 = *(srcPtr + col1 + row0);
|
||||||
|
colorB2 = *(srcPtr + col2 + row0);
|
||||||
|
colorB3 = *(srcPtr + col3 + row0);
|
||||||
|
|
||||||
|
color4 = *(srcPtr + col0 + row1);
|
||||||
|
color5 = *(srcPtr + col1 + row1);
|
||||||
|
color6 = *(srcPtr + col2 + row1);
|
||||||
|
colorS2 = *(srcPtr + col3 + row1);
|
||||||
|
|
||||||
|
color1 = *(srcPtr + col0 + row2);
|
||||||
|
color2 = *(srcPtr + col1 + row2);
|
||||||
|
color3 = *(srcPtr + col2 + row2);
|
||||||
|
colorS1 = *(srcPtr + col3 + row2);
|
||||||
|
|
||||||
|
colorA0 = *(srcPtr + col0 + row3);
|
||||||
|
colorA1 = *(srcPtr + col1 + row3);
|
||||||
|
colorA2 = *(srcPtr + col2 + row3);
|
||||||
|
colorA3 = *(srcPtr + col3 + row3);
|
||||||
|
|
||||||
|
//--------------------------------------
|
||||||
|
if (color2 == color6 && color5 != color3)
|
||||||
|
product2b = product1b = color2;
|
||||||
|
else if (color5 == color3 && color2 != color6)
|
||||||
|
product2b = product1b = color5;
|
||||||
|
else if (color5 == color3 && color2 == color6) {
|
||||||
|
int r = 0;
|
||||||
|
|
||||||
|
r += GET_RESULT(color6, color5, color1, colorA1);
|
||||||
|
r += GET_RESULT(color6, color5, color4, colorB1);
|
||||||
|
r += GET_RESULT(color6, color5, colorA2, colorS1);
|
||||||
|
r += GET_RESULT(color6, color5, colorB2, colorS2);
|
||||||
|
|
||||||
|
if (r > 0)
|
||||||
|
product2b = product1b = color6;
|
||||||
|
else if (r < 0)
|
||||||
|
product2b = product1b = color5;
|
||||||
|
else
|
||||||
|
product2b = product1b = SAI_INTERPOLATE(color5, color6);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
if (color6 == color3 && color3 == colorA1 && color2 != colorA2 && color3 != colorA0)
|
||||||
|
product2b = SAI_Q_INTERPOLATE(color3, color3, color3, color2);
|
||||||
|
else if (color5 == color2 && color2 == colorA2 && colorA1 != color3 && color2 != colorA3)
|
||||||
|
product2b = SAI_Q_INTERPOLATE(color2, color2, color2, color3);
|
||||||
|
else
|
||||||
|
product2b = SAI_INTERPOLATE(color2, color3);
|
||||||
|
|
||||||
|
if (color6 == color3 && color6 == colorB1 && color5 != colorB2 && color6 != colorB0)
|
||||||
|
product1b = SAI_Q_INTERPOLATE(color6, color6, color6, color5);
|
||||||
|
else if (color5 == color2 && color5 == colorB2 && colorB1 != color6 && color5 != colorB3)
|
||||||
|
product1b = SAI_Q_INTERPOLATE(color6, color5, color5, color5);
|
||||||
|
else
|
||||||
|
product1b = SAI_INTERPOLATE(color5, color6);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (color5 == color3 && color2 != color6 && color4 == color5 && color5 != colorA2)
|
||||||
|
product2a = SAI_INTERPOLATE(color2, color5);
|
||||||
|
else if (color5 == color1 && color6 == color5 && color4 != color2 && color5 != colorA0)
|
||||||
|
product2a = SAI_INTERPOLATE(color2, color5);
|
||||||
|
else
|
||||||
|
product2a = color2;
|
||||||
|
|
||||||
|
if (color2 == color6 && color5 != color3 && color1 == color2 && color2 != colorB2)
|
||||||
|
product1a = SAI_INTERPOLATE(color2, color5);
|
||||||
|
else if (color4 == color2 && color3 == color2 && color1 != color5 && color2 != colorB0)
|
||||||
|
product1a = SAI_INTERPOLATE(color2, color5);
|
||||||
|
else
|
||||||
|
product1a = color5;
|
||||||
|
|
||||||
|
|
||||||
|
destPtr[0] = product1a;
|
||||||
|
destPtr[1] = product1b;
|
||||||
|
destPtr[destWidth] = product2a;
|
||||||
|
destPtr[destWidth + 1] = product2b;
|
||||||
|
|
||||||
|
srcPtr++;
|
||||||
|
destPtr += 2;
|
||||||
|
}
|
||||||
|
srcPtr += (pitch-width);
|
||||||
|
destPtr += (((pitch-width)<<1)+(pitch<<1));
|
||||||
|
}
|
1510
GLideNHQ/TextureFilters_hq2x.cpp
Normal file
1510
GLideNHQ/TextureFilters_hq2x.cpp
Normal file
File diff suppressed because it is too large
Load Diff
1847
GLideNHQ/TextureFilters_hq2x.h
Normal file
1847
GLideNHQ/TextureFilters_hq2x.h
Normal file
File diff suppressed because it is too large
Load Diff
892
GLideNHQ/TextureFilters_hq4x.cpp
Normal file
892
GLideNHQ/TextureFilters_hq4x.cpp
Normal file
|
@ -0,0 +1,892 @@
|
||||||
|
/*
|
||||||
|
* Texture Filtering
|
||||||
|
* Version: 1.0
|
||||||
|
*
|
||||||
|
* Copyright (C) 2007 Hiroshi Morii All Rights Reserved.
|
||||||
|
* Email koolsmoky(at)users.sourceforge.net
|
||||||
|
* Web http://www.3dfxzone.it/koolsmoky
|
||||||
|
*
|
||||||
|
* this 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, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* this 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 GNU Make; see the file COPYING. If not, write to
|
||||||
|
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Based on Maxim Stepin and Rice1964 hq4x code */
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "TextureFilters.h"
|
||||||
|
|
||||||
|
#if !_16BPP_HACK
|
||||||
|
static uint32 RGB444toYUV[4096];
|
||||||
|
#define RGB444toYUV(val) RGB444toYUV[val & 0x0FFF] /* val = ARGB4444 */
|
||||||
|
|
||||||
|
/*inline static uint32 RGB444toYUV(uint32 val)
|
||||||
|
{
|
||||||
|
uint32 r, g, b, Y, u, v;
|
||||||
|
|
||||||
|
r = (val & 0x0F00) >> 4;
|
||||||
|
g = (val & 0x00F0);
|
||||||
|
b = val & 0x000F;
|
||||||
|
r |= r >> 4;
|
||||||
|
g |= g >> 4;
|
||||||
|
b |= b << 4;
|
||||||
|
|
||||||
|
Y = (r + g + b) >> 2;
|
||||||
|
u = 128 + ((r - b) >> 2);
|
||||||
|
v = 128 + ((2*g - r - b)>>3);
|
||||||
|
|
||||||
|
return ((Y << 16) | (u << 8) | v);
|
||||||
|
}*/
|
||||||
|
|
||||||
|
static uint32 RGB555toYUV(uint32 val)
|
||||||
|
{
|
||||||
|
uint32 r, g, b, Y, u, v;
|
||||||
|
|
||||||
|
r = (val & 0x7C00) >> 7;
|
||||||
|
g = (val & 0x03E0) >> 2;
|
||||||
|
b = (val & 0x001F) << 3;
|
||||||
|
r |= r >> 5;
|
||||||
|
g |= g >> 5;
|
||||||
|
b |= b >> 5;
|
||||||
|
|
||||||
|
Y = (r + g + b) >> 2;
|
||||||
|
u = 128 + ((r - b) >> 2);
|
||||||
|
v = 128 + ((2*g - r - b)>>3);
|
||||||
|
|
||||||
|
return ((Y << 16) | (u << 8) | v);
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32 RGB565toYUV(uint32 val)
|
||||||
|
{
|
||||||
|
uint32 r, g, b, Y, u, v;
|
||||||
|
|
||||||
|
r = (val & 0xF800) >> 8;
|
||||||
|
g = (val & 0x07E0) >> 3;
|
||||||
|
b = (val & 0x001F) << 3;
|
||||||
|
r |= r >> 5;
|
||||||
|
g |= g >> 6;
|
||||||
|
b |= b >> 5;
|
||||||
|
|
||||||
|
Y = (r + g + b) >> 2;
|
||||||
|
u = 128 + ((r - b) >> 2);
|
||||||
|
v = 128 + ((2*g - r - b)>>3);
|
||||||
|
|
||||||
|
return ((Y << 16) | (u << 8) | v);
|
||||||
|
}
|
||||||
|
#endif /* !_16BPP_HACK */
|
||||||
|
|
||||||
|
static uint32 RGB888toYUV(uint32 val)
|
||||||
|
{
|
||||||
|
#if 0
|
||||||
|
uint32 Yuv;
|
||||||
|
|
||||||
|
__asm {
|
||||||
|
mov eax, dword ptr [val];
|
||||||
|
mov ebx, eax;
|
||||||
|
mov ecx, eax;
|
||||||
|
and ebx, 0x000000ff; // b
|
||||||
|
and eax, 0x00ff0000; // r
|
||||||
|
and ecx, 0x0000ff00; // g
|
||||||
|
shl ebx, 14;
|
||||||
|
shr eax, 2;
|
||||||
|
shl ecx, 6;
|
||||||
|
mov edx, ebx;
|
||||||
|
add edx, eax;
|
||||||
|
add edx, ecx;
|
||||||
|
and edx, 0xffff0000;
|
||||||
|
|
||||||
|
sub eax, ebx;
|
||||||
|
add eax, 0x00800000;
|
||||||
|
shr eax, 8;
|
||||||
|
or edx, eax;
|
||||||
|
sub eax, 0x00800000;
|
||||||
|
and edx, 0xffffff00;
|
||||||
|
|
||||||
|
add ecx, 0x00800000;
|
||||||
|
shr ecx, 5;
|
||||||
|
shr ebx, 7;
|
||||||
|
add eax, ebx;
|
||||||
|
sub ecx, eax;
|
||||||
|
shr ecx, 11;
|
||||||
|
or edx, ecx;
|
||||||
|
|
||||||
|
mov dword ptr [Yuv], edx;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Yuv;
|
||||||
|
#else
|
||||||
|
uint32 r, g, b, Y, u, v;
|
||||||
|
|
||||||
|
r = (val & 0x00ff0000) >> 16;
|
||||||
|
g = (val & 0x0000ff00) >> 8;
|
||||||
|
b = val & 0x000000ff;
|
||||||
|
|
||||||
|
Y = (r + g + b) >> 2;
|
||||||
|
u = (0x00000200 + r - b) >> 2;
|
||||||
|
v = (0x00000400 + (g << 1) - r - b) >> 3;
|
||||||
|
|
||||||
|
return ((Y << 16) | (u << 8) | v);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#define Ymask 0x00FF0000
|
||||||
|
#define Umask 0x0000FF00
|
||||||
|
#define Vmask 0x000000FF
|
||||||
|
#define trY 0x00300000 // ?
|
||||||
|
#define trU 0x00000700 // ??
|
||||||
|
#define trV 0x00000006 // ???
|
||||||
|
|
||||||
|
#define HQ4X_INTERP1(n, b) \
|
||||||
|
static void hq4x_Interp1_##n (uint8 * pc, uint##b p1, uint##b p2) \
|
||||||
|
{ \
|
||||||
|
/* *((uint##b*)pc) = (p1*3+p2) >> 2; */ \
|
||||||
|
*((uint##b*)pc) = INTERP_##n##_MASK_1_3((INTERP_##n##_MASK_1_3(p1)*3 + INTERP_##n##_MASK_1_3(p2)) / 4) \
|
||||||
|
| INTERP_##n##_MASK_SHIFTBACK_2_4((INTERP_##n##_MASK_SHIFT_2_4(p1)*3 + INTERP_##n##_MASK_SHIFT_2_4(p2)) / 4 ); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define HQ4X_INTERP2(n, b) \
|
||||||
|
static void hq4x_Interp2_##n (uint8 * pc, uint##b p1, uint##b p2, uint##b p3) \
|
||||||
|
{ \
|
||||||
|
/**((uint##b*)pc) = (p1*2+p2+p3) >> 2;*/ \
|
||||||
|
*((uint##b*)pc) = INTERP_##n##_MASK_1_3((INTERP_##n##_MASK_1_3(p1)*2 + INTERP_##n##_MASK_1_3(p2) + INTERP_##n##_MASK_1_3(p3)) / 4) \
|
||||||
|
| INTERP_##n##_MASK_SHIFTBACK_2_4((INTERP_##n##_MASK_SHIFT_2_4(p1)*2 + INTERP_##n##_MASK_SHIFT_2_4(p2) + INTERP_##n##_MASK_SHIFT_2_4(p3)) / 4); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define HQ4X_INTERP3(n, b) \
|
||||||
|
static void hq4x_Interp3_##n (uint8 * pc, uint##b p1, uint##b p2) \
|
||||||
|
{ \
|
||||||
|
/**((uint##b*)pc) = (p1*7+p2)/8;*/ \
|
||||||
|
*((uint##b*)pc) = INTERP_##n##_MASK_1_3((INTERP_##n##_MASK_1_3(p1)*7 + INTERP_##n##_MASK_1_3(p2)) / 8) \
|
||||||
|
| INTERP_##n##_MASK_SHIFTBACK_2_4((INTERP_##n##_MASK_SHIFT_2_4(p1)*7 + INTERP_##n##_MASK_SHIFT_2_4(p2)) / 8); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define HQ4X_INTERP5(n, b) \
|
||||||
|
static void hq4x_Interp5_##n (uint8 * pc, uint##b p1, uint##b p2) \
|
||||||
|
{ \
|
||||||
|
/**((uint##b*)pc) = (p1+p2) >> 1;*/ \
|
||||||
|
*((uint##b*)pc) = INTERP_##n##_MASK_1_3((INTERP_##n##_MASK_1_3(p1) + INTERP_##n##_MASK_1_3(p2)) / 2) \
|
||||||
|
| INTERP_##n##_MASK_SHIFTBACK_2_4((INTERP_##n##_MASK_SHIFT_2_4(p1) + INTERP_##n##_MASK_SHIFT_2_4(p2)) / 2); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define HQ4X_INTERP6(n, b) \
|
||||||
|
static void hq4x_Interp6_##n (uint8 * pc, uint##b p1, uint##b p2, uint##b p3) \
|
||||||
|
{ \
|
||||||
|
/**((uint##b*)pc) = (p1*5+p2*2+p3)/8;*/ \
|
||||||
|
*((uint##b*)pc) = INTERP_##n##_MASK_1_3((INTERP_##n##_MASK_1_3(p1)*5 + INTERP_##n##_MASK_1_3(p2)*2 + INTERP_##n##_MASK_1_3(p3)) / 8) \
|
||||||
|
| INTERP_##n##_MASK_SHIFTBACK_2_4((INTERP_##n##_MASK_SHIFT_2_4(p1)*5 + INTERP_##n##_MASK_SHIFT_2_4(p2)*2 + INTERP_##n##_MASK_SHIFT_2_4(p3)) / 8); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define HQ4X_INTERP7(n, b) \
|
||||||
|
static void hq4x_Interp7_##n (uint8 * pc, uint##b p1, uint##b p2, uint##b p3) \
|
||||||
|
{ \
|
||||||
|
/**((uint##b*)pc) = (p1*6+p2+p3)/8;*/ \
|
||||||
|
*((uint##b*)pc) = INTERP_##n##_MASK_1_3((INTERP_##n##_MASK_1_3(p1)*6 + INTERP_##n##_MASK_1_3(p2) + INTERP_##n##_MASK_1_3(p3)) / 8) \
|
||||||
|
| INTERP_##n##_MASK_SHIFTBACK_2_4((INTERP_##n##_MASK_SHIFT_2_4(p1)*6 + INTERP_##n##_MASK_SHIFT_2_4(p2) + INTERP_##n##_MASK_SHIFT_2_4(p3)) / 8); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define HQ4X_INTERP8(n, b) \
|
||||||
|
static void hq4x_Interp8_##n (uint8 * pc, uint##b p1, uint##b p2) \
|
||||||
|
{ \
|
||||||
|
/**((uint##b*)pc) = (p1*5+p2*3)/8;*/ \
|
||||||
|
*((uint##b*)pc) = INTERP_##n##_MASK_1_3((INTERP_##n##_MASK_1_3(p1)*5 + INTERP_##n##_MASK_1_3(p2)*3) / 8) \
|
||||||
|
| INTERP_##n##_MASK_SHIFTBACK_2_4((INTERP_##n##_MASK_SHIFT_2_4(p1)*5 + INTERP_##n##_MASK_SHIFT_2_4(p2)*3) / 8); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#if !_16BPP_HACK
|
||||||
|
#define INTERP_4444_MASK_1_3(v) (v & 0x0F0F)
|
||||||
|
#define INTERP_4444_MASK_SHIFT_2_4(v) ((v & 0xF0F0) >> 4)
|
||||||
|
#define INTERP_4444_MASK_SHIFTBACK_2_4(v) (INTERP_4444_MASK_1_3(v) << 4)
|
||||||
|
HQ4X_INTERP1(4444, 16)
|
||||||
|
HQ4X_INTERP2(4444, 16)
|
||||||
|
HQ4X_INTERP3(4444, 16)
|
||||||
|
HQ4X_INTERP5(4444, 16)
|
||||||
|
HQ4X_INTERP6(4444, 16)
|
||||||
|
HQ4X_INTERP7(4444, 16)
|
||||||
|
HQ4X_INTERP8(4444, 16)
|
||||||
|
|
||||||
|
#define INTERP_1555_MASK_1_3(v) (v & 0x7C1F)
|
||||||
|
#define INTERP_1555_MASK_SHIFT_2_4(v) ((v & 0x83E0) >> 5)
|
||||||
|
#define INTERP_1555_MASK_SHIFTBACK_2_4(v) (INTERP_1555_MASK_1_3(v) << 5)
|
||||||
|
HQ4X_INTERP1(1555, 16)
|
||||||
|
HQ4X_INTERP2(1555, 16)
|
||||||
|
HQ4X_INTERP3(1555, 16)
|
||||||
|
HQ4X_INTERP5(1555, 16)
|
||||||
|
HQ4X_INTERP6(1555, 16)
|
||||||
|
HQ4X_INTERP7(1555, 16)
|
||||||
|
HQ4X_INTERP8(1555, 16)
|
||||||
|
|
||||||
|
#define INTERP_565_MASK_1_3(v) (v & 0xF81F)
|
||||||
|
#define INTERP_565_MASK_SHIFT_2_4(v) ((v & 0x7E0) >> 5)
|
||||||
|
#define INTERP_565_MASK_SHIFTBACK_2_4(v) (INTERP_565_MASK_1_3(v) << 5)
|
||||||
|
HQ4X_INTERP1(565, 16)
|
||||||
|
HQ4X_INTERP2(565, 16)
|
||||||
|
HQ4X_INTERP3(565, 16)
|
||||||
|
HQ4X_INTERP5(565, 16)
|
||||||
|
HQ4X_INTERP6(565, 16)
|
||||||
|
HQ4X_INTERP7(565, 16)
|
||||||
|
HQ4X_INTERP8(565, 16)
|
||||||
|
#endif /* !_16BPP_HACK */
|
||||||
|
|
||||||
|
#define INTERP_8888_MASK_1_3(v) (v & 0x00FF00FF)
|
||||||
|
#define INTERP_8888_MASK_SHIFT_2_4(v) ((v & 0xFF00FF00) >> 8)
|
||||||
|
#define INTERP_8888_MASK_SHIFTBACK_2_4(v) (INTERP_8888_MASK_1_3(v) << 8)
|
||||||
|
HQ4X_INTERP1(8888, 32)
|
||||||
|
HQ4X_INTERP2(8888, 32)
|
||||||
|
HQ4X_INTERP3(8888, 32)
|
||||||
|
HQ4X_INTERP5(8888, 32)
|
||||||
|
HQ4X_INTERP6(8888, 32)
|
||||||
|
HQ4X_INTERP7(8888, 32)
|
||||||
|
HQ4X_INTERP8(8888, 32)
|
||||||
|
|
||||||
|
#define PIXEL00_0 *((int*)(pOut)) = c[5];
|
||||||
|
#define PIXEL00_11 hq4x_Interp1(pOut, c[5], c[4]);
|
||||||
|
#define PIXEL00_12 hq4x_Interp1(pOut, c[5], c[2]);
|
||||||
|
#define PIXEL00_20 hq4x_Interp2(pOut, c[5], c[2], c[4]);
|
||||||
|
#define PIXEL00_50 hq4x_Interp5(pOut, c[2], c[4]);
|
||||||
|
#define PIXEL00_80 hq4x_Interp8(pOut, c[5], c[1]);
|
||||||
|
#define PIXEL00_81 hq4x_Interp8(pOut, c[5], c[4]);
|
||||||
|
#define PIXEL00_82 hq4x_Interp8(pOut, c[5], c[2]);
|
||||||
|
#define PIXEL01_0 *((int*)(pOut+BPP)) = c[5];
|
||||||
|
#define PIXEL01_10 hq4x_Interp1(pOut+BPP, c[5], c[1]);
|
||||||
|
#define PIXEL01_12 hq4x_Interp1(pOut+BPP, c[5], c[2]);
|
||||||
|
#define PIXEL01_14 hq4x_Interp1(pOut+BPP, c[2], c[5]);
|
||||||
|
#define PIXEL01_21 hq4x_Interp2(pOut+BPP, c[2], c[5], c[4]);
|
||||||
|
#define PIXEL01_31 hq4x_Interp3(pOut+BPP, c[5], c[4]);
|
||||||
|
#define PIXEL01_50 hq4x_Interp5(pOut+BPP, c[2], c[5]);
|
||||||
|
#define PIXEL01_60 hq4x_Interp6(pOut+BPP, c[5], c[2], c[4]);
|
||||||
|
#define PIXEL01_61 hq4x_Interp6(pOut+BPP, c[5], c[2], c[1]);
|
||||||
|
#define PIXEL01_82 hq4x_Interp8(pOut+BPP, c[5], c[2]);
|
||||||
|
#define PIXEL01_83 hq4x_Interp8(pOut+BPP, c[2], c[4]);
|
||||||
|
#define PIXEL02_0 *((int*)(pOut+BPP2)) = c[5];
|
||||||
|
#define PIXEL02_10 hq4x_Interp1(pOut+BPP2, c[5], c[3]);
|
||||||
|
#define PIXEL02_11 hq4x_Interp1(pOut+BPP2, c[5], c[2]);
|
||||||
|
#define PIXEL02_13 hq4x_Interp1(pOut+BPP2, c[2], c[5]);
|
||||||
|
#define PIXEL02_21 hq4x_Interp2(pOut+BPP2, c[2], c[5], c[6]);
|
||||||
|
#define PIXEL02_32 hq4x_Interp3(pOut+BPP2, c[5], c[6]);
|
||||||
|
#define PIXEL02_50 hq4x_Interp5(pOut+BPP2, c[2], c[5]);
|
||||||
|
#define PIXEL02_60 hq4x_Interp6(pOut+BPP2, c[5], c[2], c[6]);
|
||||||
|
#define PIXEL02_61 hq4x_Interp6(pOut+BPP2, c[5], c[2], c[3]);
|
||||||
|
#define PIXEL02_81 hq4x_Interp8(pOut+BPP2, c[5], c[2]);
|
||||||
|
#define PIXEL02_83 hq4x_Interp8(pOut+BPP2, c[2], c[6]);
|
||||||
|
#define PIXEL03_0 *((int*)(pOut+BPP3)) = c[5];
|
||||||
|
#define PIXEL03_11 hq4x_Interp1(pOut+BPP3, c[5], c[2]);
|
||||||
|
#define PIXEL03_12 hq4x_Interp1(pOut+BPP3, c[5], c[6]);
|
||||||
|
#define PIXEL03_20 hq4x_Interp2(pOut+BPP3, c[5], c[2], c[6]);
|
||||||
|
#define PIXEL03_50 hq4x_Interp5(pOut+BPP3, c[2], c[6]);
|
||||||
|
#define PIXEL03_80 hq4x_Interp8(pOut+BPP3, c[5], c[3]);
|
||||||
|
#define PIXEL03_81 hq4x_Interp8(pOut+BPP3, c[5], c[2]);
|
||||||
|
#define PIXEL03_82 hq4x_Interp8(pOut+BPP3, c[5], c[6]);
|
||||||
|
#define PIXEL10_0 *((int*)(pOut+BpL)) = c[5];
|
||||||
|
#define PIXEL10_10 hq4x_Interp1(pOut+BpL, c[5], c[1]);
|
||||||
|
#define PIXEL10_11 hq4x_Interp1(pOut+BpL, c[5], c[4]);
|
||||||
|
#define PIXEL10_13 hq4x_Interp1(pOut+BpL, c[4], c[5]);
|
||||||
|
#define PIXEL10_21 hq4x_Interp2(pOut+BpL, c[4], c[5], c[2]);
|
||||||
|
#define PIXEL10_32 hq4x_Interp3(pOut+BpL, c[5], c[2]);
|
||||||
|
#define PIXEL10_50 hq4x_Interp5(pOut+BpL, c[4], c[5]);
|
||||||
|
#define PIXEL10_60 hq4x_Interp6(pOut+BpL, c[5], c[4], c[2]);
|
||||||
|
#define PIXEL10_61 hq4x_Interp6(pOut+BpL, c[5], c[4], c[1]);
|
||||||
|
#define PIXEL10_81 hq4x_Interp8(pOut+BpL, c[5], c[4]);
|
||||||
|
#define PIXEL10_83 hq4x_Interp8(pOut+BpL, c[4], c[2]);
|
||||||
|
#define PIXEL11_0 *((int*)(pOut+BpL+BPP)) = c[5];
|
||||||
|
#define PIXEL11_30 hq4x_Interp3(pOut+BpL+BPP, c[5], c[1]);
|
||||||
|
#define PIXEL11_31 hq4x_Interp3(pOut+BpL+BPP, c[5], c[4]);
|
||||||
|
#define PIXEL11_32 hq4x_Interp3(pOut+BpL+BPP, c[5], c[2]);
|
||||||
|
#define PIXEL11_70 hq4x_Interp7(pOut+BpL+BPP, c[5], c[4], c[2]);
|
||||||
|
#define PIXEL12_0 *((int*)(pOut+BpL+BPP2)) = c[5];
|
||||||
|
#define PIXEL12_30 hq4x_Interp3(pOut+BpL+BPP2, c[5], c[3]);
|
||||||
|
#define PIXEL12_31 hq4x_Interp3(pOut+BpL+BPP2, c[5], c[2]);
|
||||||
|
#define PIXEL12_32 hq4x_Interp3(pOut+BpL+BPP2, c[5], c[6]);
|
||||||
|
#define PIXEL12_70 hq4x_Interp7(pOut+BpL+BPP2, c[5], c[6], c[2]);
|
||||||
|
#define PIXEL13_0 *((int*)(pOut+BpL+BPP3)) = c[5];
|
||||||
|
#define PIXEL13_10 hq4x_Interp1(pOut+BpL+BPP3, c[5], c[3]);
|
||||||
|
#define PIXEL13_12 hq4x_Interp1(pOut+BpL+BPP3, c[5], c[6]);
|
||||||
|
#define PIXEL13_14 hq4x_Interp1(pOut+BpL+BPP3, c[6], c[5]);
|
||||||
|
#define PIXEL13_21 hq4x_Interp2(pOut+BpL+BPP3, c[6], c[5], c[2]);
|
||||||
|
#define PIXEL13_31 hq4x_Interp3(pOut+BpL+BPP3, c[5], c[2]);
|
||||||
|
#define PIXEL13_50 hq4x_Interp5(pOut+BpL+BPP3, c[6], c[5]);
|
||||||
|
#define PIXEL13_60 hq4x_Interp6(pOut+BpL+BPP3, c[5], c[6], c[2]);
|
||||||
|
#define PIXEL13_61 hq4x_Interp6(pOut+BpL+BPP3, c[5], c[6], c[3]);
|
||||||
|
#define PIXEL13_82 hq4x_Interp8(pOut+BpL+BPP3, c[5], c[6]);
|
||||||
|
#define PIXEL13_83 hq4x_Interp8(pOut+BpL+BPP3, c[6], c[2]);
|
||||||
|
#define PIXEL20_0 *((int*)(pOut+BpL+BpL)) = c[5];
|
||||||
|
#define PIXEL20_10 hq4x_Interp1(pOut+BpL+BpL, c[5], c[7]);
|
||||||
|
#define PIXEL20_12 hq4x_Interp1(pOut+BpL+BpL, c[5], c[4]);
|
||||||
|
#define PIXEL20_14 hq4x_Interp1(pOut+BpL+BpL, c[4], c[5]);
|
||||||
|
#define PIXEL20_21 hq4x_Interp2(pOut+BpL+BpL, c[4], c[5], c[8]);
|
||||||
|
#define PIXEL20_31 hq4x_Interp3(pOut+BpL+BpL, c[5], c[8]);
|
||||||
|
#define PIXEL20_50 hq4x_Interp5(pOut+BpL+BpL, c[4], c[5]);
|
||||||
|
#define PIXEL20_60 hq4x_Interp6(pOut+BpL+BpL, c[5], c[4], c[8]);
|
||||||
|
#define PIXEL20_61 hq4x_Interp6(pOut+BpL+BpL, c[5], c[4], c[7]);
|
||||||
|
#define PIXEL20_82 hq4x_Interp8(pOut+BpL+BpL, c[5], c[4]);
|
||||||
|
#define PIXEL20_83 hq4x_Interp8(pOut+BpL+BpL, c[4], c[8]);
|
||||||
|
#define PIXEL21_0 *((int*)(pOut+BpL+BpL+BPP)) = c[5];
|
||||||
|
#define PIXEL21_30 hq4x_Interp3(pOut+BpL+BpL+BPP, c[5], c[7]);
|
||||||
|
#define PIXEL21_31 hq4x_Interp3(pOut+BpL+BpL+BPP, c[5], c[8]);
|
||||||
|
#define PIXEL21_32 hq4x_Interp3(pOut+BpL+BpL+BPP, c[5], c[4]);
|
||||||
|
#define PIXEL21_70 hq4x_Interp7(pOut+BpL+BpL+BPP, c[5], c[4], c[8]);
|
||||||
|
#define PIXEL22_0 *((int*)(pOut+BpL+BpL+BPP2)) = c[5];
|
||||||
|
#define PIXEL22_30 hq4x_Interp3(pOut+BpL+BpL+BPP2, c[5], c[9]);
|
||||||
|
#define PIXEL22_31 hq4x_Interp3(pOut+BpL+BpL+BPP2, c[5], c[6]);
|
||||||
|
#define PIXEL22_32 hq4x_Interp3(pOut+BpL+BpL+BPP2, c[5], c[8]);
|
||||||
|
#define PIXEL22_70 hq4x_Interp7(pOut+BpL+BpL+BPP2, c[5], c[6], c[8]);
|
||||||
|
#define PIXEL23_0 *((int*)(pOut+BpL+BpL+BPP3)) = c[5];
|
||||||
|
#define PIXEL23_10 hq4x_Interp1(pOut+BpL+BpL+BPP3, c[5], c[9]);
|
||||||
|
#define PIXEL23_11 hq4x_Interp1(pOut+BpL+BpL+BPP3, c[5], c[6]);
|
||||||
|
#define PIXEL23_13 hq4x_Interp1(pOut+BpL+BpL+BPP3, c[6], c[5]);
|
||||||
|
#define PIXEL23_21 hq4x_Interp2(pOut+BpL+BpL+BPP3, c[6], c[5], c[8]);
|
||||||
|
#define PIXEL23_32 hq4x_Interp3(pOut+BpL+BpL+BPP3, c[5], c[8]);
|
||||||
|
#define PIXEL23_50 hq4x_Interp5(pOut+BpL+BpL+BPP3, c[6], c[5]);
|
||||||
|
#define PIXEL23_60 hq4x_Interp6(pOut+BpL+BpL+BPP3, c[5], c[6], c[8]);
|
||||||
|
#define PIXEL23_61 hq4x_Interp6(pOut+BpL+BpL+BPP3, c[5], c[6], c[9]);
|
||||||
|
#define PIXEL23_81 hq4x_Interp8(pOut+BpL+BpL+BPP3, c[5], c[6]);
|
||||||
|
#define PIXEL23_83 hq4x_Interp8(pOut+BpL+BpL+BPP3, c[6], c[8]);
|
||||||
|
#define PIXEL30_0 *((int*)(pOut+BpL+BpL+BpL)) = c[5];
|
||||||
|
#define PIXEL30_11 hq4x_Interp1(pOut+BpL+BpL+BpL, c[5], c[8]);
|
||||||
|
#define PIXEL30_12 hq4x_Interp1(pOut+BpL+BpL+BpL, c[5], c[4]);
|
||||||
|
#define PIXEL30_20 hq4x_Interp2(pOut+BpL+BpL+BpL, c[5], c[8], c[4]);
|
||||||
|
#define PIXEL30_50 hq4x_Interp5(pOut+BpL+BpL+BpL, c[8], c[4]);
|
||||||
|
#define PIXEL30_80 hq4x_Interp8(pOut+BpL+BpL+BpL, c[5], c[7]);
|
||||||
|
#define PIXEL30_81 hq4x_Interp8(pOut+BpL+BpL+BpL, c[5], c[8]);
|
||||||
|
#define PIXEL30_82 hq4x_Interp8(pOut+BpL+BpL+BpL, c[5], c[4]);
|
||||||
|
#define PIXEL31_0 *((int*)(pOut+BpL+BpL+BpL+BPP)) = c[5];
|
||||||
|
#define PIXEL31_10 hq4x_Interp1(pOut+BpL+BpL+BpL+BPP, c[5], c[7]);
|
||||||
|
#define PIXEL31_11 hq4x_Interp1(pOut+BpL+BpL+BpL+BPP, c[5], c[8]);
|
||||||
|
#define PIXEL31_13 hq4x_Interp1(pOut+BpL+BpL+BpL+BPP, c[8], c[5]);
|
||||||
|
#define PIXEL31_21 hq4x_Interp2(pOut+BpL+BpL+BpL+BPP, c[8], c[5], c[4]);
|
||||||
|
#define PIXEL31_32 hq4x_Interp3(pOut+BpL+BpL+BpL+BPP, c[5], c[4]);
|
||||||
|
#define PIXEL31_50 hq4x_Interp5(pOut+BpL+BpL+BpL+BPP, c[8], c[5]);
|
||||||
|
#define PIXEL31_60 hq4x_Interp6(pOut+BpL+BpL+BpL+BPP, c[5], c[8], c[4]);
|
||||||
|
#define PIXEL31_61 hq4x_Interp6(pOut+BpL+BpL+BpL+BPP, c[5], c[8], c[7]);
|
||||||
|
#define PIXEL31_81 hq4x_Interp8(pOut+BpL+BpL+BpL+BPP, c[5], c[8]);
|
||||||
|
#define PIXEL31_83 hq4x_Interp8(pOut+BpL+BpL+BpL+BPP, c[8], c[4]);
|
||||||
|
#define PIXEL32_0 *((int*)(pOut+BpL+BpL+BpL+BPP2)) = c[5];
|
||||||
|
#define PIXEL32_10 hq4x_Interp1(pOut+BpL+BpL+BpL+BPP2, c[5], c[9]);
|
||||||
|
#define PIXEL32_12 hq4x_Interp1(pOut+BpL+BpL+BpL+BPP2, c[5], c[8]);
|
||||||
|
#define PIXEL32_14 hq4x_Interp1(pOut+BpL+BpL+BpL+BPP2, c[8], c[5]);
|
||||||
|
#define PIXEL32_21 hq4x_Interp2(pOut+BpL+BpL+BpL+BPP2, c[8], c[5], c[6]);
|
||||||
|
#define PIXEL32_31 hq4x_Interp3(pOut+BpL+BpL+BpL+BPP2, c[5], c[6]);
|
||||||
|
#define PIXEL32_50 hq4x_Interp5(pOut+BpL+BpL+BpL+BPP2, c[8], c[5]);
|
||||||
|
#define PIXEL32_60 hq4x_Interp6(pOut+BpL+BpL+BpL+BPP2, c[5], c[8], c[6]);
|
||||||
|
#define PIXEL32_61 hq4x_Interp6(pOut+BpL+BpL+BpL+BPP2, c[5], c[8], c[9]);
|
||||||
|
#define PIXEL32_82 hq4x_Interp8(pOut+BpL+BpL+BpL+BPP2, c[5], c[8]);
|
||||||
|
#define PIXEL32_83 hq4x_Interp8(pOut+BpL+BpL+BpL+BPP2, c[8], c[6]);
|
||||||
|
#define PIXEL33_0 *((int*)(pOut+BpL+BpL+BpL+BPP3)) = c[5];
|
||||||
|
#define PIXEL33_11 hq4x_Interp1(pOut+BpL+BpL+BpL+BPP3, c[5], c[6]);
|
||||||
|
#define PIXEL33_12 hq4x_Interp1(pOut+BpL+BpL+BpL+BPP3, c[5], c[8]);
|
||||||
|
#define PIXEL33_20 hq4x_Interp2(pOut+BpL+BpL+BpL+BPP3, c[5], c[8], c[6]);
|
||||||
|
#define PIXEL33_50 hq4x_Interp5(pOut+BpL+BpL+BpL+BPP3, c[8], c[6]);
|
||||||
|
#define PIXEL33_80 hq4x_Interp8(pOut+BpL+BpL+BpL+BPP3, c[5], c[9]);
|
||||||
|
#define PIXEL33_81 hq4x_Interp8(pOut+BpL+BpL+BpL+BPP3, c[5], c[6]);
|
||||||
|
#define PIXEL33_82 hq4x_Interp8(pOut+BpL+BpL+BpL+BPP3, c[5], c[8]);
|
||||||
|
|
||||||
|
#define HQ4X_DIFF(n, b) \
|
||||||
|
static int Diff_##n (uint##b w1, uint##b w2) \
|
||||||
|
{ \
|
||||||
|
int YUV1, YUV2; \
|
||||||
|
YUV1 = RGB##n##toYUV(w1); \
|
||||||
|
YUV2 = RGB##n##toYUV(w2); \
|
||||||
|
return ( ( abs((YUV1 & Ymask) - (YUV2 & Ymask)) > trY ) || \
|
||||||
|
( abs((YUV1 & Umask) - (YUV2 & Umask)) > trU ) || \
|
||||||
|
( abs((YUV1 & Vmask) - (YUV2 & Vmask)) > trV ) ); \
|
||||||
|
}
|
||||||
|
|
||||||
|
HQ4X_DIFF(888, 32)
|
||||||
|
|
||||||
|
#if !_16BPP_HACK
|
||||||
|
HQ4X_DIFF(444, 16)
|
||||||
|
HQ4X_DIFF(555, 16)
|
||||||
|
HQ4X_DIFF(565, 16)
|
||||||
|
|
||||||
|
void hq4x_4444(unsigned char * pIn, unsigned char * pOut, int Xres, int Yres, int SrcPPL, int BpL)
|
||||||
|
{
|
||||||
|
#define hq4x_Interp1 hq4x_Interp1_4444
|
||||||
|
#define hq4x_Interp2 hq4x_Interp2_4444
|
||||||
|
#define hq4x_Interp3 hq4x_Interp3_4444
|
||||||
|
#define hq4x_Interp4 hq4x_Interp4_4444
|
||||||
|
#define hq4x_Interp5 hq4x_Interp5_4444
|
||||||
|
#define hq4x_Interp6 hq4x_Interp6_4444
|
||||||
|
#define hq4x_Interp7 hq4x_Interp7_4444
|
||||||
|
#define hq4x_Interp8 hq4x_Interp8_4444
|
||||||
|
#define Diff Diff_444
|
||||||
|
#define BPP 2
|
||||||
|
#define BPP2 4
|
||||||
|
#define BPP3 6
|
||||||
|
|
||||||
|
int i, j, k;
|
||||||
|
int prevline, nextline;
|
||||||
|
uint16 w[10];
|
||||||
|
uint16 c[10];
|
||||||
|
|
||||||
|
int pattern;
|
||||||
|
int flag;
|
||||||
|
|
||||||
|
int YUV1, YUV2;
|
||||||
|
|
||||||
|
// +----+----+----+
|
||||||
|
// | | | |
|
||||||
|
// | w1 | w2 | w3 |
|
||||||
|
// +----+----+----+
|
||||||
|
// | | | |
|
||||||
|
// | w4 | w5 | w6 |
|
||||||
|
// +----+----+----+
|
||||||
|
// | | | |
|
||||||
|
// | w7 | w8 | w9 |
|
||||||
|
// +----+----+----+
|
||||||
|
|
||||||
|
for (j = 0; j < Yres; j++) {
|
||||||
|
if (j>0) prevline = -SrcPPL*2; else prevline = 0;
|
||||||
|
if (j<Yres-1) nextline = SrcPPL*2; else nextline = 0;
|
||||||
|
|
||||||
|
for (i=0; i<Xres; i++) {
|
||||||
|
w[2] = *((uint16*)(pIn + prevline));
|
||||||
|
w[5] = *((uint16*)pIn);
|
||||||
|
w[8] = *((uint16*)(pIn + nextline));
|
||||||
|
|
||||||
|
if (i>0) {
|
||||||
|
w[1] = *((uint16*)(pIn + prevline - 2));
|
||||||
|
w[4] = *((uint16*)(pIn - 2));
|
||||||
|
w[7] = *((uint16*)(pIn + nextline - 2));
|
||||||
|
} else {
|
||||||
|
w[1] = w[2];
|
||||||
|
w[4] = w[5];
|
||||||
|
w[7] = w[8];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i<Xres-1) {
|
||||||
|
w[3] = *((uint16*)(pIn + prevline + 2));
|
||||||
|
w[6] = *((uint16*)(pIn + 2));
|
||||||
|
w[9] = *((uint16*)(pIn + nextline + 2));
|
||||||
|
} else {
|
||||||
|
w[3] = w[2];
|
||||||
|
w[6] = w[5];
|
||||||
|
w[9] = w[8];
|
||||||
|
}
|
||||||
|
|
||||||
|
pattern = 0;
|
||||||
|
flag = 1;
|
||||||
|
|
||||||
|
YUV1 = RGB444toYUV(w[5]);
|
||||||
|
|
||||||
|
for (k=1; k<=9; k++) {
|
||||||
|
if (k==5) continue;
|
||||||
|
|
||||||
|
if ( w[k] != w[5] ) {
|
||||||
|
YUV2 = RGB444toYUV(w[k]);
|
||||||
|
if ( ( abs((YUV1 & Ymask) - (YUV2 & Ymask)) > trY ) ||
|
||||||
|
( abs((YUV1 & Umask) - (YUV2 & Umask)) > trU ) ||
|
||||||
|
( abs((YUV1 & Vmask) - (YUV2 & Vmask)) > trV ) )
|
||||||
|
pattern |= flag;
|
||||||
|
}
|
||||||
|
flag <<= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (k=1; k<=9; k++)
|
||||||
|
c[k] = w[k];
|
||||||
|
|
||||||
|
#include "TextureFilters_hq4x.h"
|
||||||
|
|
||||||
|
pIn+=2;
|
||||||
|
pOut+=8;
|
||||||
|
}
|
||||||
|
pIn += 2*(SrcPPL-Xres);
|
||||||
|
pOut+= 8*(SrcPPL-Xres);
|
||||||
|
pOut+=BpL;
|
||||||
|
pOut+=BpL;
|
||||||
|
pOut+=BpL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef BPP
|
||||||
|
#undef BPP2
|
||||||
|
#undef BPP3
|
||||||
|
#undef Diff
|
||||||
|
#undef hq4x_Interp1
|
||||||
|
#undef hq4x_Interp2
|
||||||
|
#undef hq4x_Interp3
|
||||||
|
#undef hq4x_Interp4
|
||||||
|
#undef hq4x_Interp5
|
||||||
|
#undef hq4x_Interp6
|
||||||
|
#undef hq4x_Interp7
|
||||||
|
#undef hq4x_Interp8
|
||||||
|
}
|
||||||
|
|
||||||
|
void hq4x_1555(unsigned char * pIn, unsigned char * pOut, int Xres, int Yres, int SrcPPL, int BpL)
|
||||||
|
{
|
||||||
|
#define hq4x_Interp1 hq4x_Interp1_1555
|
||||||
|
#define hq4x_Interp2 hq4x_Interp2_1555
|
||||||
|
#define hq4x_Interp3 hq4x_Interp3_1555
|
||||||
|
#define hq4x_Interp4 hq4x_Interp4_1555
|
||||||
|
#define hq4x_Interp5 hq4x_Interp5_1555
|
||||||
|
#define hq4x_Interp6 hq4x_Interp6_1555
|
||||||
|
#define hq4x_Interp7 hq4x_Interp7_1555
|
||||||
|
#define hq4x_Interp8 hq4x_Interp8_1555
|
||||||
|
#define Diff Diff_555
|
||||||
|
#define BPP 2
|
||||||
|
#define BPP2 4
|
||||||
|
#define BPP3 6
|
||||||
|
|
||||||
|
int i, j, k;
|
||||||
|
int prevline, nextline;
|
||||||
|
uint16 w[10];
|
||||||
|
uint16 c[10];
|
||||||
|
|
||||||
|
int pattern;
|
||||||
|
int flag;
|
||||||
|
|
||||||
|
int YUV1, YUV2;
|
||||||
|
|
||||||
|
// +----+----+----+
|
||||||
|
// | | | |
|
||||||
|
// | w1 | w2 | w3 |
|
||||||
|
// +----+----+----+
|
||||||
|
// | | | |
|
||||||
|
// | w4 | w5 | w6 |
|
||||||
|
// +----+----+----+
|
||||||
|
// | | | |
|
||||||
|
// | w7 | w8 | w9 |
|
||||||
|
// +----+----+----+
|
||||||
|
|
||||||
|
for (j = 0; j < Yres; j++) {
|
||||||
|
if (j>0) prevline = -SrcPPL*2; else prevline = 0;
|
||||||
|
if (j<Yres-1) nextline = SrcPPL*2; else nextline = 0;
|
||||||
|
|
||||||
|
for (i=0; i<Xres; i++) {
|
||||||
|
w[2] = *((uint16*)(pIn + prevline));
|
||||||
|
w[5] = *((uint16*)pIn);
|
||||||
|
w[8] = *((uint16*)(pIn + nextline));
|
||||||
|
|
||||||
|
if (i>0) {
|
||||||
|
w[1] = *((uint16*)(pIn + prevline - 2));
|
||||||
|
w[4] = *((uint16*)(pIn - 2));
|
||||||
|
w[7] = *((uint16*)(pIn + nextline - 2));
|
||||||
|
} else {
|
||||||
|
w[1] = w[2];
|
||||||
|
w[4] = w[5];
|
||||||
|
w[7] = w[8];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i<Xres-1) {
|
||||||
|
w[3] = *((uint16*)(pIn + prevline + 2));
|
||||||
|
w[6] = *((uint16*)(pIn + 2));
|
||||||
|
w[9] = *((uint16*)(pIn + nextline + 2));
|
||||||
|
} else {
|
||||||
|
w[3] = w[2];
|
||||||
|
w[6] = w[5];
|
||||||
|
w[9] = w[8];
|
||||||
|
}
|
||||||
|
|
||||||
|
pattern = 0;
|
||||||
|
flag = 1;
|
||||||
|
|
||||||
|
YUV1 = RGB555toYUV(w[5]);
|
||||||
|
|
||||||
|
for (k=1; k<=9; k++) {
|
||||||
|
if (k==5) continue;
|
||||||
|
|
||||||
|
if ( w[k] != w[5] ) {
|
||||||
|
YUV2 = RGB555toYUV(w[k]);
|
||||||
|
if ( ( abs((YUV1 & Ymask) - (YUV2 & Ymask)) > trY ) ||
|
||||||
|
( abs((YUV1 & Umask) - (YUV2 & Umask)) > trU ) ||
|
||||||
|
( abs((YUV1 & Vmask) - (YUV2 & Vmask)) > trV ) )
|
||||||
|
pattern |= flag;
|
||||||
|
}
|
||||||
|
flag <<= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (k=1; k<=9; k++)
|
||||||
|
c[k] = w[k];
|
||||||
|
|
||||||
|
#include "TextureFilters_hq4x.h"
|
||||||
|
|
||||||
|
pIn+=2;
|
||||||
|
pOut+=8;
|
||||||
|
}
|
||||||
|
pIn += 2*(SrcPPL-Xres);
|
||||||
|
pOut+= 8*(SrcPPL-Xres);
|
||||||
|
pOut+=BpL;
|
||||||
|
pOut+=BpL;
|
||||||
|
pOut+=BpL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef BPP
|
||||||
|
#undef BPP2
|
||||||
|
#undef BPP3
|
||||||
|
#undef Diff
|
||||||
|
#undef hq4x_Interp1
|
||||||
|
#undef hq4x_Interp2
|
||||||
|
#undef hq4x_Interp3
|
||||||
|
#undef hq4x_Interp4
|
||||||
|
#undef hq4x_Interp5
|
||||||
|
#undef hq4x_Interp6
|
||||||
|
#undef hq4x_Interp7
|
||||||
|
#undef hq4x_Interp8
|
||||||
|
}
|
||||||
|
|
||||||
|
void hq4x_565(unsigned char * pIn, unsigned char * pOut, int Xres, int Yres, int SrcPPL, int BpL)
|
||||||
|
{
|
||||||
|
#define hq4x_Interp1 hq4x_Interp1_565
|
||||||
|
#define hq4x_Interp2 hq4x_Interp2_565
|
||||||
|
#define hq4x_Interp3 hq4x_Interp3_565
|
||||||
|
#define hq4x_Interp4 hq4x_Interp4_565
|
||||||
|
#define hq4x_Interp5 hq4x_Interp5_565
|
||||||
|
#define hq4x_Interp6 hq4x_Interp6_565
|
||||||
|
#define hq4x_Interp7 hq4x_Interp7_565
|
||||||
|
#define hq4x_Interp8 hq4x_Interp8_565
|
||||||
|
#define Diff Diff_565
|
||||||
|
#define BPP 2
|
||||||
|
#define BPP2 4
|
||||||
|
#define BPP3 6
|
||||||
|
|
||||||
|
int i, j, k;
|
||||||
|
int prevline, nextline;
|
||||||
|
uint16 w[10];
|
||||||
|
uint16 c[10];
|
||||||
|
|
||||||
|
int pattern;
|
||||||
|
int flag;
|
||||||
|
|
||||||
|
int YUV1, YUV2;
|
||||||
|
|
||||||
|
// +----+----+----+
|
||||||
|
// | | | |
|
||||||
|
// | w1 | w2 | w3 |
|
||||||
|
// +----+----+----+
|
||||||
|
// | | | |
|
||||||
|
// | w4 | w5 | w6 |
|
||||||
|
// +----+----+----+
|
||||||
|
// | | | |
|
||||||
|
// | w7 | w8 | w9 |
|
||||||
|
// +----+----+----+
|
||||||
|
|
||||||
|
for (j = 0; j < Yres; j++) {
|
||||||
|
if (j>0) prevline = -SrcPPL*2; else prevline = 0;
|
||||||
|
if (j<Yres-1) nextline = SrcPPL*2; else nextline = 0;
|
||||||
|
|
||||||
|
for (i=0; i<Xres; i++) {
|
||||||
|
w[2] = *((uint16*)(pIn + prevline));
|
||||||
|
w[5] = *((uint16*)pIn);
|
||||||
|
w[8] = *((uint16*)(pIn + nextline));
|
||||||
|
|
||||||
|
if (i>0) {
|
||||||
|
w[1] = *((uint16*)(pIn + prevline - 2));
|
||||||
|
w[4] = *((uint16*)(pIn - 2));
|
||||||
|
w[7] = *((uint16*)(pIn + nextline - 2));
|
||||||
|
} else {
|
||||||
|
w[1] = w[2];
|
||||||
|
w[4] = w[5];
|
||||||
|
w[7] = w[8];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i<Xres-1) {
|
||||||
|
w[3] = *((uint16*)(pIn + prevline + 2));
|
||||||
|
w[6] = *((uint16*)(pIn + 2));
|
||||||
|
w[9] = *((uint16*)(pIn + nextline + 2));
|
||||||
|
} else {
|
||||||
|
w[3] = w[2];
|
||||||
|
w[6] = w[5];
|
||||||
|
w[9] = w[8];
|
||||||
|
}
|
||||||
|
|
||||||
|
pattern = 0;
|
||||||
|
flag = 1;
|
||||||
|
|
||||||
|
YUV1 = RGB565toYUV(w[5]);
|
||||||
|
|
||||||
|
for (k=1; k<=9; k++) {
|
||||||
|
if (k==5) continue;
|
||||||
|
|
||||||
|
if ( w[k] != w[5] ) {
|
||||||
|
YUV2 = RGB565toYUV(w[k]);
|
||||||
|
if ( ( abs((YUV1 & Ymask) - (YUV2 & Ymask)) > trY ) ||
|
||||||
|
( abs((YUV1 & Umask) - (YUV2 & Umask)) > trU ) ||
|
||||||
|
( abs((YUV1 & Vmask) - (YUV2 & Vmask)) > trV ) )
|
||||||
|
pattern |= flag;
|
||||||
|
}
|
||||||
|
flag <<= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (k=1; k<=9; k++)
|
||||||
|
c[k] = w[k];
|
||||||
|
|
||||||
|
#include "TextureFilters_hq4x.h"
|
||||||
|
|
||||||
|
pIn+=2;
|
||||||
|
pOut+=8;
|
||||||
|
}
|
||||||
|
pIn += 2*(SrcPPL-Xres);
|
||||||
|
pOut+= 8*(SrcPPL-Xres);
|
||||||
|
pOut+=BpL;
|
||||||
|
pOut+=BpL;
|
||||||
|
pOut+=BpL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef BPP
|
||||||
|
#undef BPP2
|
||||||
|
#undef BPP3
|
||||||
|
#undef Diff
|
||||||
|
#undef hq4x_Interp1
|
||||||
|
#undef hq4x_Interp2
|
||||||
|
#undef hq4x_Interp3
|
||||||
|
#undef hq4x_Interp4
|
||||||
|
#undef hq4x_Interp5
|
||||||
|
#undef hq4x_Interp6
|
||||||
|
#undef hq4x_Interp7
|
||||||
|
#undef hq4x_Interp8
|
||||||
|
}
|
||||||
|
#endif /* !_16BPP_HACK */
|
||||||
|
|
||||||
|
void hq4x_8888(unsigned char * pIn, unsigned char * pOut, int Xres, int Yres, int SrcPPL, int BpL)
|
||||||
|
{
|
||||||
|
#define hq4x_Interp1 hq4x_Interp1_8888
|
||||||
|
#define hq4x_Interp2 hq4x_Interp2_8888
|
||||||
|
#define hq4x_Interp3 hq4x_Interp3_8888
|
||||||
|
#define hq4x_Interp4 hq4x_Interp4_8888
|
||||||
|
#define hq4x_Interp5 hq4x_Interp5_8888
|
||||||
|
#define hq4x_Interp6 hq4x_Interp6_8888
|
||||||
|
#define hq4x_Interp7 hq4x_Interp7_8888
|
||||||
|
#define hq4x_Interp8 hq4x_Interp8_8888
|
||||||
|
#define Diff Diff_888
|
||||||
|
#define BPP 4
|
||||||
|
#define BPP2 8
|
||||||
|
#define BPP3 12
|
||||||
|
|
||||||
|
int i, j, k;
|
||||||
|
int prevline, nextline;
|
||||||
|
uint32 w[10];
|
||||||
|
uint32 c[10];
|
||||||
|
|
||||||
|
int pattern;
|
||||||
|
int flag;
|
||||||
|
|
||||||
|
int YUV1, YUV2;
|
||||||
|
|
||||||
|
// +----+----+----+
|
||||||
|
// | | | |
|
||||||
|
// | w1 | w2 | w3 |
|
||||||
|
// +----+----+----+
|
||||||
|
// | | | |
|
||||||
|
// | w4 | w5 | w6 |
|
||||||
|
// +----+----+----+
|
||||||
|
// | | | |
|
||||||
|
// | w7 | w8 | w9 |
|
||||||
|
// +----+----+----+
|
||||||
|
|
||||||
|
for (j = 0; j < Yres; j++) {
|
||||||
|
if (j>0) prevline = -SrcPPL*4; else prevline = 0;
|
||||||
|
if (j<Yres-1) nextline = SrcPPL*4; else nextline = 0;
|
||||||
|
|
||||||
|
for (i=0; i<Xres; i++) {
|
||||||
|
w[2] = *((uint32*)(pIn + prevline));
|
||||||
|
w[5] = *((uint32*)pIn);
|
||||||
|
w[8] = *((uint32*)(pIn + nextline));
|
||||||
|
|
||||||
|
if (i>0) {
|
||||||
|
w[1] = *((uint32*)(pIn + prevline - 4));
|
||||||
|
w[4] = *((uint32*)(pIn - 4));
|
||||||
|
w[7] = *((uint32*)(pIn + nextline - 4));
|
||||||
|
} else {
|
||||||
|
w[1] = w[2];
|
||||||
|
w[4] = w[5];
|
||||||
|
w[7] = w[8];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i<Xres-1) {
|
||||||
|
w[3] = *((uint32*)(pIn + prevline + 4));
|
||||||
|
w[6] = *((uint32*)(pIn + 4));
|
||||||
|
w[9] = *((uint32*)(pIn + nextline + 4));
|
||||||
|
} else {
|
||||||
|
w[3] = w[2];
|
||||||
|
w[6] = w[5];
|
||||||
|
w[9] = w[8];
|
||||||
|
}
|
||||||
|
|
||||||
|
pattern = 0;
|
||||||
|
flag = 1;
|
||||||
|
|
||||||
|
YUV1 = RGB888toYUV(w[5]);
|
||||||
|
|
||||||
|
for (k=1; k<=9; k++) {
|
||||||
|
if (k==5) continue;
|
||||||
|
|
||||||
|
if ( w[k] != w[5] ) {
|
||||||
|
YUV2 = RGB888toYUV(w[k]);
|
||||||
|
if ( ( abs((YUV1 & Ymask) - (YUV2 & Ymask)) > trY ) ||
|
||||||
|
( abs((YUV1 & Umask) - (YUV2 & Umask)) > trU ) ||
|
||||||
|
( abs((YUV1 & Vmask) - (YUV2 & Vmask)) > trV ) )
|
||||||
|
pattern |= flag;
|
||||||
|
}
|
||||||
|
flag <<= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (k=1; k<=9; k++)
|
||||||
|
c[k] = w[k];
|
||||||
|
|
||||||
|
#include "TextureFilters_hq4x.h"
|
||||||
|
|
||||||
|
pIn+=4;
|
||||||
|
pOut+=16;
|
||||||
|
}
|
||||||
|
|
||||||
|
pIn += 4*(SrcPPL-Xres);
|
||||||
|
pOut+= 16*(SrcPPL-Xres);
|
||||||
|
pOut+=BpL;
|
||||||
|
pOut+=BpL;
|
||||||
|
pOut+=BpL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef BPP
|
||||||
|
#undef BPP2
|
||||||
|
#undef BPP3
|
||||||
|
#undef Diff
|
||||||
|
#undef hq4x_Interp1
|
||||||
|
#undef hq4x_Interp2
|
||||||
|
#undef hq4x_Interp3
|
||||||
|
#undef hq4x_Interp4
|
||||||
|
#undef hq4x_Interp5
|
||||||
|
#undef hq4x_Interp6
|
||||||
|
#undef hq4x_Interp7
|
||||||
|
#undef hq4x_Interp8
|
||||||
|
}
|
||||||
|
|
||||||
|
#if !_16BPP_HACK
|
||||||
|
void hq4x_init(void)
|
||||||
|
{
|
||||||
|
static int done = 0;
|
||||||
|
int r, g, b, Y, u, v, i, j, k;
|
||||||
|
|
||||||
|
if (done ) return;
|
||||||
|
|
||||||
|
for (i = 0; i < 16; i++) {
|
||||||
|
for (j = 0; j < 16; j++) {
|
||||||
|
for (k = 0; k < 16; k++) {
|
||||||
|
r = (i << 4) | i;
|
||||||
|
g = (j << 4) | j;
|
||||||
|
b = (k << 4) | k;
|
||||||
|
|
||||||
|
/* Microsoft's RGB888->YUV conversion */
|
||||||
|
/*Y = ((( 66 * r + 129 * g + 25 * b + 128) >> 8) + 16) & 0xFF;
|
||||||
|
u = ((( -38 * r - 74 * g + 112 * b + 128) >> 8) + 128) & 0xFF;
|
||||||
|
v = ((( 112 * r - 94 * g - 18 * b + 128) >> 8) + 128) & 0xFF;*/
|
||||||
|
|
||||||
|
Y = (r + g + b) >> 2;
|
||||||
|
u = 128 + ((r - b) >> 2);
|
||||||
|
v = 128 + ((-r + 2*g -b)>>3);
|
||||||
|
|
||||||
|
RGB444toYUV[(i << 8) | (j << 4) | k] = (Y << 16) | (u << 8) | v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
done = 1;
|
||||||
|
}
|
||||||
|
#endif /* !_16BPP_HACK */
|
4999
GLideNHQ/TextureFilters_hq4x.h
Normal file
4999
GLideNHQ/TextureFilters_hq4x.h
Normal file
File diff suppressed because it is too large
Load Diff
1307
GLideNHQ/TextureFilters_lq2x.h
Normal file
1307
GLideNHQ/TextureFilters_lq2x.h
Normal file
File diff suppressed because it is too large
Load Diff
449
GLideNHQ/TxCache.cpp
Normal file
449
GLideNHQ/TxCache.cpp
Normal file
|
@ -0,0 +1,449 @@
|
||||||
|
/*
|
||||||
|
* Texture Filtering
|
||||||
|
* Version: 1.0
|
||||||
|
*
|
||||||
|
* Copyright (C) 2007 Hiroshi Morii All Rights Reserved.
|
||||||
|
* Email koolsmoky(at)users.sourceforge.net
|
||||||
|
* Web http://www.3dfxzone.it/koolsmoky
|
||||||
|
*
|
||||||
|
* this 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, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* this 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 GNU Make; see the file COPYING. If not, write to
|
||||||
|
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef __MSC__
|
||||||
|
#pragma warning(disable: 4786)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "TxCache.h"
|
||||||
|
#include "TxDbg.h"
|
||||||
|
#include <zlib.h>
|
||||||
|
#include <boost/filesystem.hpp>
|
||||||
|
|
||||||
|
TxCache::~TxCache()
|
||||||
|
{
|
||||||
|
/* free memory, clean up, etc */
|
||||||
|
clear();
|
||||||
|
|
||||||
|
delete _txUtil;
|
||||||
|
}
|
||||||
|
|
||||||
|
TxCache::TxCache(int options, int cachesize, const wchar_t *path, const wchar_t *ident,
|
||||||
|
dispInfoFuncExt callback)
|
||||||
|
{
|
||||||
|
_txUtil = new TxUtil();
|
||||||
|
|
||||||
|
_options = options;
|
||||||
|
_cacheSize = cachesize;
|
||||||
|
_callback = callback;
|
||||||
|
_totalSize = 0;
|
||||||
|
|
||||||
|
/* save path name */
|
||||||
|
if (path)
|
||||||
|
_path.assign(path);
|
||||||
|
|
||||||
|
/* save ROM name */
|
||||||
|
if (ident)
|
||||||
|
_ident.assign(ident);
|
||||||
|
|
||||||
|
/* zlib memory buffers to (de)compress hires textures */
|
||||||
|
if (_options & (GZ_TEXCACHE|GZ_HIRESTEXCACHE)) {
|
||||||
|
_gzdest0 = TxMemBuf::getInstance()->get(0);
|
||||||
|
_gzdest1 = TxMemBuf::getInstance()->get(1);
|
||||||
|
_gzdestLen = (TxMemBuf::getInstance()->size_of(0) < TxMemBuf::getInstance()->size_of(1)) ?
|
||||||
|
TxMemBuf::getInstance()->size_of(0) : TxMemBuf::getInstance()->size_of(1);
|
||||||
|
|
||||||
|
if (!_gzdest0 || !_gzdest1 || !_gzdestLen) {
|
||||||
|
_options &= ~(GZ_TEXCACHE|GZ_HIRESTEXCACHE);
|
||||||
|
_gzdest0 = NULL;
|
||||||
|
_gzdest1 = NULL;
|
||||||
|
_gzdestLen = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean
|
||||||
|
TxCache::add(uint64 checksum, GHQTexInfo *info, int dataSize)
|
||||||
|
{
|
||||||
|
/* NOTE: dataSize must be provided if info->data is zlib compressed. */
|
||||||
|
|
||||||
|
if (!checksum || !info->data) return 0;
|
||||||
|
|
||||||
|
uint8 *dest = info->data;
|
||||||
|
uint16 format = info->format;
|
||||||
|
|
||||||
|
if (!dataSize) {
|
||||||
|
dataSize = _txUtil->sizeofTx(info->width, info->height, info->format);
|
||||||
|
|
||||||
|
if (!dataSize) return 0;
|
||||||
|
|
||||||
|
if (_options & (GZ_TEXCACHE|GZ_HIRESTEXCACHE)) {
|
||||||
|
/* zlib compress it. compression level:1 (best speed) */
|
||||||
|
uint32 destLen = _gzdestLen;
|
||||||
|
dest = (dest == _gzdest0) ? _gzdest1 : _gzdest0;
|
||||||
|
if (compress2(dest, &destLen, info->data, dataSize, 1) != Z_OK) {
|
||||||
|
dest = info->data;
|
||||||
|
DBG_INFO(80, L"Error: zlib compression failed!\n");
|
||||||
|
} else {
|
||||||
|
DBG_INFO(80, L"zlib compressed: %.02fkb->%.02fkb\n", (float)dataSize/1000, (float)destLen/1000);
|
||||||
|
dataSize = destLen;
|
||||||
|
format |= GR_TEXFMT_GZ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if cache size exceeds limit, remove old cache */
|
||||||
|
if (_cacheSize > 0) {
|
||||||
|
_totalSize += dataSize;
|
||||||
|
if ((_totalSize > _cacheSize) && !_cachelist.empty()) {
|
||||||
|
/* _cachelist is arranged so that frequently used textures are in the back */
|
||||||
|
std::list<uint64>::iterator itList = _cachelist.begin();
|
||||||
|
while (itList != _cachelist.end()) {
|
||||||
|
/* find it in _cache */
|
||||||
|
std::map<uint64, TXCACHE*>::iterator itMap = _cache.find(*itList);
|
||||||
|
if (itMap != _cache.end()) {
|
||||||
|
/* yep we have it. remove it. */
|
||||||
|
_totalSize -= (*itMap).second->size;
|
||||||
|
free((*itMap).second->info.data);
|
||||||
|
delete (*itMap).second;
|
||||||
|
_cache.erase(itMap);
|
||||||
|
}
|
||||||
|
itList++;
|
||||||
|
|
||||||
|
/* check if memory cache has enough space */
|
||||||
|
if (_totalSize <= _cacheSize)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* remove from _cachelist */
|
||||||
|
_cachelist.erase(_cachelist.begin(), itList);
|
||||||
|
|
||||||
|
DBG_INFO(80, L"+++++++++\n");
|
||||||
|
}
|
||||||
|
_totalSize -= dataSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* cache it */
|
||||||
|
uint8 *tmpdata = (uint8*)malloc(dataSize);
|
||||||
|
if (tmpdata) {
|
||||||
|
TXCACHE *txCache = new TXCACHE;
|
||||||
|
if (txCache) {
|
||||||
|
/* we can directly write as we filter, but for now we get away
|
||||||
|
* with doing memcpy after all the filtering is done.
|
||||||
|
*/
|
||||||
|
memcpy(tmpdata, dest, dataSize);
|
||||||
|
|
||||||
|
/* copy it */
|
||||||
|
memcpy(&txCache->info, info, sizeof(GHQTexInfo));
|
||||||
|
txCache->info.data = tmpdata;
|
||||||
|
txCache->info.format = format;
|
||||||
|
txCache->size = dataSize;
|
||||||
|
|
||||||
|
/* add to cache */
|
||||||
|
if (_cacheSize > 0) {
|
||||||
|
_cachelist.push_back(checksum);
|
||||||
|
txCache->it = --(_cachelist.end());
|
||||||
|
}
|
||||||
|
/* _cache[checksum] = txCache; */
|
||||||
|
_cache.insert(std::map<uint64, TXCACHE*>::value_type(checksum, txCache));
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
DBG_INFO(80, L"[%5d] added!! crc:%08X %08X %d x %d gfmt:%x total:%.02fmb\n",
|
||||||
|
_cache.size(), (uint32)(checksum >> 32), (uint32)(checksum & 0xffffffff),
|
||||||
|
info->width, info->height, info->format, (float)_totalSize/1000000);
|
||||||
|
|
||||||
|
DBG_INFO(80, L"smalllodlog2:%d largelodlog2:%d aspectratiolog2:%d\n",
|
||||||
|
txCache->info.smallLodLog2, txCache->info.largeLodLog2, txCache->info.aspectRatioLog2);
|
||||||
|
|
||||||
|
if (info->tiles) {
|
||||||
|
DBG_INFO(80, L"tiles:%d un-tiled size:%d x %d\n", info->tiles, info->untiled_width, info->untiled_height);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_cacheSize > 0) {
|
||||||
|
DBG_INFO(80, L"cache max config:%.02fmb\n", (float)_cacheSize/1000000);
|
||||||
|
|
||||||
|
if (_cache.size() != _cachelist.size()) {
|
||||||
|
DBG_INFO(80, L"Error: cache/cachelist mismatch! (%d/%d)\n", _cache.size(), _cachelist.size());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* total cache size */
|
||||||
|
_totalSize += dataSize;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
free(tmpdata);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean
|
||||||
|
TxCache::get(uint64 checksum, GHQTexInfo *info)
|
||||||
|
{
|
||||||
|
if (!checksum || _cache.empty()) return 0;
|
||||||
|
|
||||||
|
/* find a match in cache */
|
||||||
|
std::map<uint64, TXCACHE*>::iterator itMap = _cache.find(checksum);
|
||||||
|
if (itMap != _cache.end()) {
|
||||||
|
/* yep, we've got it. */
|
||||||
|
memcpy(info, &(((*itMap).second)->info), sizeof(GHQTexInfo));
|
||||||
|
|
||||||
|
/* push it to the back of the list */
|
||||||
|
if (_cacheSize > 0) {
|
||||||
|
_cachelist.erase(((*itMap).second)->it);
|
||||||
|
_cachelist.push_back(checksum);
|
||||||
|
((*itMap).second)->it = --(_cachelist.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
/* zlib decompress it */
|
||||||
|
if (info->format & GR_TEXFMT_GZ) {
|
||||||
|
uint32 destLen = _gzdestLen;
|
||||||
|
uint8 *dest = (_gzdest0 == info->data) ? _gzdest1 : _gzdest0;
|
||||||
|
if (uncompress(dest, &destLen, info->data, ((*itMap).second)->size) != Z_OK) {
|
||||||
|
DBG_INFO(80, L"Error: zlib decompression failed!\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
info->data = dest;
|
||||||
|
info->format &= ~GR_TEXFMT_GZ;
|
||||||
|
DBG_INFO(80, L"zlib decompressed: %.02fkb->%.02fkb\n", (float)(((*itMap).second)->size)/1000, (float)destLen/1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean
|
||||||
|
TxCache::save(const wchar_t *path, const wchar_t *filename, int config)
|
||||||
|
{
|
||||||
|
if (!_cache.empty()) {
|
||||||
|
/* dump cache to disk */
|
||||||
|
char cbuf[MAX_PATH];
|
||||||
|
|
||||||
|
boost::filesystem::wpath cachepath(path);
|
||||||
|
boost::filesystem::create_directory(cachepath);
|
||||||
|
|
||||||
|
/* Ugly hack to enable fopen/gzopen in Win9x */
|
||||||
|
#ifdef WIN32
|
||||||
|
wchar_t curpath[MAX_PATH];
|
||||||
|
GETCWD(MAX_PATH, curpath);
|
||||||
|
CHDIR(cachepath.wstring().c_str());
|
||||||
|
#else
|
||||||
|
char curpath[MAX_PATH];
|
||||||
|
wcstombs(cbuf, cachepath.string().c_str(), MAX_PATH);
|
||||||
|
GETCWD(MAX_PATH, curpath);
|
||||||
|
CHDIR(cbuf);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
wcstombs(cbuf, filename, MAX_PATH);
|
||||||
|
|
||||||
|
gzFile gzfp = gzopen(cbuf, "wb1");
|
||||||
|
DBG_INFO(80, L"gzfp:%x file:%ls\n", gzfp, filename);
|
||||||
|
if (gzfp) {
|
||||||
|
/* write header to determine config match */
|
||||||
|
gzwrite(gzfp, &config, 4);
|
||||||
|
|
||||||
|
std::map<uint64, TXCACHE*>::iterator itMap = _cache.begin();
|
||||||
|
while (itMap != _cache.end()) {
|
||||||
|
uint8 *dest = (*itMap).second->info.data;
|
||||||
|
uint32 destLen = (*itMap).second->size;
|
||||||
|
uint16 format = (*itMap).second->info.format;
|
||||||
|
|
||||||
|
/* to keep things simple, we save the texture data in a zlib uncompressed state. */
|
||||||
|
/* sigh... for those who cannot wait the extra few seconds. changed to keep
|
||||||
|
* texture data in a zlib compressed state. if the GZ_TEXCACHE or GZ_HIRESTEXCACHE
|
||||||
|
* option is toggled, the cache will need to be rebuilt.
|
||||||
|
*/
|
||||||
|
/*if (format & GR_TEXFMT_GZ) {
|
||||||
|
dest = _gzdest0;
|
||||||
|
destLen = _gzdestLen;
|
||||||
|
if (dest && destLen) {
|
||||||
|
if (uncompress(dest, &destLen, (*itMap).second->info.data, (*itMap).second->size) != Z_OK) {
|
||||||
|
dest = NULL;
|
||||||
|
destLen = 0;
|
||||||
|
}
|
||||||
|
format &= ~GR_TEXFMT_GZ;
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
|
||||||
|
if (dest && destLen) {
|
||||||
|
/* texture checksum */
|
||||||
|
gzwrite(gzfp, &((*itMap).first), 8);
|
||||||
|
|
||||||
|
/* other texture info */
|
||||||
|
gzwrite(gzfp, &((*itMap).second->info.width), 4);
|
||||||
|
gzwrite(gzfp, &((*itMap).second->info.height), 4);
|
||||||
|
gzwrite(gzfp, &format, 2);
|
||||||
|
|
||||||
|
gzwrite(gzfp, &((*itMap).second->info.smallLodLog2), 4);
|
||||||
|
gzwrite(gzfp, &((*itMap).second->info.largeLodLog2), 4);
|
||||||
|
gzwrite(gzfp, &((*itMap).second->info.aspectRatioLog2), 4);
|
||||||
|
|
||||||
|
gzwrite(gzfp, &((*itMap).second->info.tiles), 4);
|
||||||
|
gzwrite(gzfp, &((*itMap).second->info.untiled_width), 4);
|
||||||
|
gzwrite(gzfp, &((*itMap).second->info.untiled_height), 4);
|
||||||
|
|
||||||
|
gzwrite(gzfp, &((*itMap).second->info.is_hires_tex), 1);
|
||||||
|
|
||||||
|
gzwrite(gzfp, &destLen, 4);
|
||||||
|
gzwrite(gzfp, dest, destLen);
|
||||||
|
}
|
||||||
|
|
||||||
|
itMap++;
|
||||||
|
|
||||||
|
/* not ready yet */
|
||||||
|
/*if (_callback)
|
||||||
|
(*_callback)(L"Total textures saved to HDD: %d\n", std::distance(itMap, _cache.begin()));*/
|
||||||
|
}
|
||||||
|
gzclose(gzfp);
|
||||||
|
}
|
||||||
|
|
||||||
|
CHDIR(curpath);
|
||||||
|
}
|
||||||
|
|
||||||
|
return _cache.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean
|
||||||
|
TxCache::load(const wchar_t *path, const wchar_t *filename, int config)
|
||||||
|
{
|
||||||
|
/* find it on disk */
|
||||||
|
char cbuf[MAX_PATH];
|
||||||
|
|
||||||
|
boost::filesystem::wpath cachepath(path);
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
wchar_t curpath[MAX_PATH];
|
||||||
|
GETCWD(MAX_PATH, curpath);
|
||||||
|
CHDIR(cachepath.wstring().c_str());
|
||||||
|
#else
|
||||||
|
char curpath[MAX_PATH];
|
||||||
|
wcstombs(cbuf, cachepath.string().c_str(), MAX_PATH);
|
||||||
|
GETCWD(MAX_PATH, curpath);
|
||||||
|
CHDIR(cbuf);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
wcstombs(cbuf, filename, MAX_PATH);
|
||||||
|
|
||||||
|
gzFile gzfp = gzopen(cbuf, "rb");
|
||||||
|
DBG_INFO(80, L"gzfp:%x file:%ls\n", gzfp, filename);
|
||||||
|
if (gzfp) {
|
||||||
|
/* yep, we have it. load it into memory cache. */
|
||||||
|
int dataSize;
|
||||||
|
uint64 checksum;
|
||||||
|
GHQTexInfo tmpInfo;
|
||||||
|
int tmpconfig;
|
||||||
|
/* read header to determine config match */
|
||||||
|
gzread(gzfp, &tmpconfig, 4);
|
||||||
|
|
||||||
|
if (tmpconfig == config) {
|
||||||
|
do {
|
||||||
|
memset(&tmpInfo, 0, sizeof(GHQTexInfo));
|
||||||
|
|
||||||
|
gzread(gzfp, &checksum, 8);
|
||||||
|
|
||||||
|
gzread(gzfp, &tmpInfo.width, 4);
|
||||||
|
gzread(gzfp, &tmpInfo.height, 4);
|
||||||
|
gzread(gzfp, &tmpInfo.format, 2);
|
||||||
|
|
||||||
|
gzread(gzfp, &tmpInfo.smallLodLog2, 4);
|
||||||
|
gzread(gzfp, &tmpInfo.largeLodLog2, 4);
|
||||||
|
gzread(gzfp, &tmpInfo.aspectRatioLog2, 4);
|
||||||
|
|
||||||
|
gzread(gzfp, &tmpInfo.tiles, 4);
|
||||||
|
gzread(gzfp, &tmpInfo.untiled_width, 4);
|
||||||
|
gzread(gzfp, &tmpInfo.untiled_height, 4);
|
||||||
|
|
||||||
|
gzread(gzfp, &tmpInfo.is_hires_tex, 1);
|
||||||
|
|
||||||
|
gzread(gzfp, &dataSize, 4);
|
||||||
|
|
||||||
|
tmpInfo.data = (uint8*)malloc(dataSize);
|
||||||
|
if (tmpInfo.data) {
|
||||||
|
gzread(gzfp, tmpInfo.data, dataSize);
|
||||||
|
|
||||||
|
/* add to memory cache */
|
||||||
|
add(checksum, &tmpInfo, (tmpInfo.format & GR_TEXFMT_GZ) ? dataSize : 0);
|
||||||
|
|
||||||
|
free(tmpInfo.data);
|
||||||
|
} else {
|
||||||
|
gzseek(gzfp, dataSize, SEEK_CUR);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* skip in between to prevent the loop from being tied down to vsync */
|
||||||
|
if (_callback && (!(_cache.size() % 100) || gzeof(gzfp)))
|
||||||
|
(*_callback)(L"[%d] total mem:%.02fmb - %ls\n", _cache.size(), (float)_totalSize/1000000, filename);
|
||||||
|
|
||||||
|
} while (!gzeof(gzfp));
|
||||||
|
gzclose(gzfp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CHDIR(curpath);
|
||||||
|
|
||||||
|
return !_cache.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean
|
||||||
|
TxCache::del(uint64 checksum)
|
||||||
|
{
|
||||||
|
if (!checksum || _cache.empty()) return 0;
|
||||||
|
|
||||||
|
std::map<uint64, TXCACHE*>::iterator itMap = _cache.find(checksum);
|
||||||
|
if (itMap != _cache.end()) {
|
||||||
|
|
||||||
|
/* for texture cache (not hi-res cache) */
|
||||||
|
if (!_cachelist.empty()) _cachelist.erase(((*itMap).second)->it);
|
||||||
|
|
||||||
|
/* remove from cache */
|
||||||
|
free((*itMap).second->info.data);
|
||||||
|
_totalSize -= (*itMap).second->size;
|
||||||
|
delete (*itMap).second;
|
||||||
|
_cache.erase(itMap);
|
||||||
|
|
||||||
|
DBG_INFO(80, L"removed from cache: checksum = %08X %08X\n", (uint32)(checksum & 0xffffffff), (uint32)(checksum >> 32));
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean
|
||||||
|
TxCache::is_cached(uint64 checksum)
|
||||||
|
{
|
||||||
|
std::map<uint64, TXCACHE*>::iterator itMap = _cache.find(checksum);
|
||||||
|
if (itMap != _cache.end()) return 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
TxCache::clear()
|
||||||
|
{
|
||||||
|
if (!_cache.empty()) {
|
||||||
|
std::map<uint64, TXCACHE*>::iterator itMap = _cache.begin();
|
||||||
|
while (itMap != _cache.end()) {
|
||||||
|
free((*itMap).second->info.data);
|
||||||
|
delete (*itMap).second;
|
||||||
|
itMap++;
|
||||||
|
}
|
||||||
|
_cache.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_cachelist.empty()) _cachelist.clear();
|
||||||
|
|
||||||
|
_totalSize = 0;
|
||||||
|
}
|
69
GLideNHQ/TxCache.h
Normal file
69
GLideNHQ/TxCache.h
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
/*
|
||||||
|
* Texture Filtering
|
||||||
|
* Version: 1.0
|
||||||
|
*
|
||||||
|
* Copyright (C) 2007 Hiroshi Morii All Rights Reserved.
|
||||||
|
* Email koolsmoky(at)users.sourceforge.net
|
||||||
|
* Web http://www.3dfxzone.it/koolsmoky
|
||||||
|
*
|
||||||
|
* this 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, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* this 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 GNU Make; see the file COPYING. If not, write to
|
||||||
|
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __TXCACHE_H__
|
||||||
|
#define __TXCACHE_H__
|
||||||
|
|
||||||
|
#include "TxInternal.h"
|
||||||
|
#include "TxUtil.h"
|
||||||
|
#include <list>
|
||||||
|
#include <map>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
class TxCache
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
std::list<uint64> _cachelist;
|
||||||
|
uint8 *_gzdest0;
|
||||||
|
uint8 *_gzdest1;
|
||||||
|
uint32 _gzdestLen;
|
||||||
|
protected:
|
||||||
|
int _options;
|
||||||
|
std::wstring _ident;
|
||||||
|
std::wstring _path;
|
||||||
|
dispInfoFuncExt _callback;
|
||||||
|
TxUtil *_txUtil;
|
||||||
|
struct TXCACHE {
|
||||||
|
int size;
|
||||||
|
GHQTexInfo info;
|
||||||
|
std::list<uint64>::iterator it;
|
||||||
|
};
|
||||||
|
int _totalSize;
|
||||||
|
int _cacheSize;
|
||||||
|
std::map<uint64, TXCACHE*> _cache;
|
||||||
|
boolean save(const wchar_t *path, const wchar_t *filename, const int config);
|
||||||
|
boolean load(const wchar_t *path, const wchar_t *filename, const int config);
|
||||||
|
boolean del(uint64 checksum); /* checksum hi:palette low:texture */
|
||||||
|
boolean is_cached(uint64 checksum); /* checksum hi:palette low:texture */
|
||||||
|
void clear();
|
||||||
|
public:
|
||||||
|
~TxCache();
|
||||||
|
TxCache(int options, int cachesize, const wchar_t *path, const wchar_t *ident,
|
||||||
|
dispInfoFuncExt callback);
|
||||||
|
boolean add(uint64 checksum, /* checksum hi:palette low:texture */
|
||||||
|
GHQTexInfo *info, int dataSize = 0);
|
||||||
|
boolean get(uint64 checksum, /* checksum hi:palette low:texture */
|
||||||
|
GHQTexInfo *info);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* __TXCACHE_H__ */
|
75
GLideNHQ/TxDbg.cpp
Normal file
75
GLideNHQ/TxDbg.cpp
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
/*
|
||||||
|
* Texture Filtering
|
||||||
|
* Version: 1.0
|
||||||
|
*
|
||||||
|
* Copyright (C) 2007 Hiroshi Morii All Rights Reserved.
|
||||||
|
* Email koolsmoky(at)users.sourceforge.net
|
||||||
|
* Web http://www.3dfxzone.it/koolsmoky
|
||||||
|
*
|
||||||
|
* this 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, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* this 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 GNU Make; see the file COPYING. If not, write to
|
||||||
|
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define DBG_LEVEL 80
|
||||||
|
|
||||||
|
#include "TxDbg.h"
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <boost/format.hpp>
|
||||||
|
|
||||||
|
TxDbg::TxDbg()
|
||||||
|
{
|
||||||
|
_level = DBG_LEVEL;
|
||||||
|
|
||||||
|
if (!_dbgfile)
|
||||||
|
#ifdef GHQCHK
|
||||||
|
_dbgfile = fopen("ghqchk.txt", "w");
|
||||||
|
#else
|
||||||
|
_dbgfile = fopen("glidehq.dbg", "w");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
TxDbg::~TxDbg()
|
||||||
|
{
|
||||||
|
if (_dbgfile) {
|
||||||
|
fclose(_dbgfile);
|
||||||
|
_dbgfile = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
_level = DBG_LEVEL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
TxDbg::output(const int level, const wchar_t *format, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
//wchar_t newformat[4095];
|
||||||
|
std::wstring newformat;
|
||||||
|
|
||||||
|
if (level > _level)
|
||||||
|
return;
|
||||||
|
|
||||||
|
va_start(args, format);
|
||||||
|
//swprintf(newformat, 4095, L"%d:\t", level);
|
||||||
|
//wcscat(newformat, format);
|
||||||
|
//vfwprintf(_dbgfile, newformat, args);
|
||||||
|
newformat = boost::str(boost::wformat(L"%d:\t%ls") % level % format);
|
||||||
|
vfwprintf(_dbgfile, newformat.c_str(), args);
|
||||||
|
fflush(_dbgfile);
|
||||||
|
#ifdef GHQCHK
|
||||||
|
//vwprintf(newformat, args);
|
||||||
|
vwprintf(newformat.c_str(), args);
|
||||||
|
#endif
|
||||||
|
va_end(args);
|
||||||
|
}
|
61
GLideNHQ/TxDbg.h
Normal file
61
GLideNHQ/TxDbg.h
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
/*
|
||||||
|
* Texture Filtering
|
||||||
|
* Version: 1.0
|
||||||
|
*
|
||||||
|
* Copyright (C) 2007 Hiroshi Morii All Rights Reserved.
|
||||||
|
* Email koolsmoky(at)users.sourceforge.net
|
||||||
|
* Web http://www.3dfxzone.it/koolsmoky
|
||||||
|
*
|
||||||
|
* this 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, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* this 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 GNU Make; see the file COPYING. If not, write to
|
||||||
|
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __TXDBG_H__
|
||||||
|
#define __TXDBG_H__
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "TxInternal.h"
|
||||||
|
|
||||||
|
class TxDbg
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
FILE* _dbgfile;
|
||||||
|
int _level;
|
||||||
|
TxDbg();
|
||||||
|
public:
|
||||||
|
static TxDbg* getInstance() {
|
||||||
|
static TxDbg txDbg;
|
||||||
|
return &txDbg;
|
||||||
|
}
|
||||||
|
~TxDbg();
|
||||||
|
void output(const int level, const wchar_t *format, ...);
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
#define DBG_INFO TxDbg::getInstance()->output
|
||||||
|
#define INFO DBG_INFO
|
||||||
|
#else
|
||||||
|
#define DBG_INFO(A, ...)
|
||||||
|
#ifdef GHQCHK
|
||||||
|
#define INFO TxDbg::getInstance()->output
|
||||||
|
#else
|
||||||
|
#if 0 /* XXX enable this to log basic hires texture checks */
|
||||||
|
#define INFO TxDbg::getInstance()->output
|
||||||
|
#else
|
||||||
|
#define INFO DBG_INFO
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __TXDBG_H__ */
|
683
GLideNHQ/TxFilter.cpp
Normal file
683
GLideNHQ/TxFilter.cpp
Normal file
|
@ -0,0 +1,683 @@
|
||||||
|
/*
|
||||||
|
* Texture Filtering
|
||||||
|
* Version: 1.0
|
||||||
|
*
|
||||||
|
* Copyright (C) 2007 Hiroshi Morii All Rights Reserved.
|
||||||
|
* Email koolsmoky(at)users.sourceforge.net
|
||||||
|
* Web http://www.3dfxzone.it/koolsmoky
|
||||||
|
*
|
||||||
|
* this 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, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* this 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 GNU Make; see the file COPYING. If not, write to
|
||||||
|
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef __MSC__
|
||||||
|
#pragma warning(disable: 4786)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "TxFilter.h"
|
||||||
|
#include "TextureFilters.h"
|
||||||
|
#include "TxDbg.h"
|
||||||
|
#include "bldno.h"
|
||||||
|
#include <boost/thread.hpp>
|
||||||
|
#include <boost/bind.hpp>
|
||||||
|
#include <boost/format.hpp>
|
||||||
|
|
||||||
|
void TxFilter::clear()
|
||||||
|
{
|
||||||
|
/* clear hires texture cache */
|
||||||
|
delete _txHiResCache;
|
||||||
|
|
||||||
|
/* clear texture cache */
|
||||||
|
delete _txTexCache;
|
||||||
|
|
||||||
|
/* free memory */
|
||||||
|
TxMemBuf::getInstance()->shutdown();
|
||||||
|
|
||||||
|
/* clear other stuff */
|
||||||
|
delete _txImage;
|
||||||
|
delete _txQuantize;
|
||||||
|
delete _txUtil;
|
||||||
|
}
|
||||||
|
|
||||||
|
TxFilter::~TxFilter()
|
||||||
|
{
|
||||||
|
clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
TxFilter::TxFilter(int maxwidth, int maxheight, int maxbpp, int options,
|
||||||
|
int cachesize, wchar_t *path, wchar_t *ident,
|
||||||
|
dispInfoFuncExt callback)
|
||||||
|
{
|
||||||
|
/* HACKALERT: the emulator misbehaves and sometimes forgets to shutdown */
|
||||||
|
if ((ident && wcscmp(ident, L"DEFAULT") != 0 && _ident.compare(ident) == 0) &&
|
||||||
|
_maxwidth == maxwidth &&
|
||||||
|
_maxheight == maxheight &&
|
||||||
|
_maxbpp == maxbpp &&
|
||||||
|
_options == options &&
|
||||||
|
_cacheSize == cachesize) return;
|
||||||
|
clear(); /* gcc does not allow the destructor to be called */
|
||||||
|
|
||||||
|
/* shamelessness :P this first call to the debug output message creates
|
||||||
|
* a file in the executable directory. */
|
||||||
|
INFO(0, L"------------------------------------------------------------------\n");
|
||||||
|
#ifdef GHQCHK
|
||||||
|
INFO(0, L" GlideHQ Hires Texture Checker 1.02.00.%d\n", BUILD_NUMBER);
|
||||||
|
#else
|
||||||
|
INFO(0, L" GlideHQ version 1.02.00.%d\n", BUILD_NUMBER);
|
||||||
|
#endif
|
||||||
|
INFO(0, L" Copyright (C) 2010 Hiroshi Morii All Rights Reserved\n");
|
||||||
|
INFO(0, L" email : koolsmoky(at)users.sourceforge.net\n");
|
||||||
|
INFO(0, L" website : http://www.3dfxzone.it/koolsmoky\n");
|
||||||
|
INFO(0, L"\n");
|
||||||
|
INFO(0, L" Glide64 official website : http://glide64.emuxhaven.net\n");
|
||||||
|
INFO(0, L"------------------------------------------------------------------\n");
|
||||||
|
|
||||||
|
_options = options;
|
||||||
|
|
||||||
|
_txImage = new TxImage();
|
||||||
|
_txQuantize = new TxQuantize();
|
||||||
|
_txUtil = new TxUtil();
|
||||||
|
|
||||||
|
/* get number of CPU cores. */
|
||||||
|
_numcore = _txUtil->getNumberofProcessors();
|
||||||
|
|
||||||
|
_initialized = 0;
|
||||||
|
|
||||||
|
_tex1 = NULL;
|
||||||
|
_tex2 = NULL;
|
||||||
|
|
||||||
|
/* XXX: anything larger than 1024 * 1024 is overkill */
|
||||||
|
_maxwidth = maxwidth > 1024 ? 1024 : maxwidth;
|
||||||
|
_maxheight = maxheight > 1024 ? 1024 : maxheight;
|
||||||
|
_maxbpp = maxbpp;
|
||||||
|
|
||||||
|
_cacheSize = cachesize;
|
||||||
|
|
||||||
|
/* TODO: validate options and do overrides here*/
|
||||||
|
|
||||||
|
/* save path name */
|
||||||
|
if (path)
|
||||||
|
_path.assign(path);
|
||||||
|
|
||||||
|
/* save ROM name */
|
||||||
|
if (ident && wcscmp(ident, L"DEFAULT") != 0)
|
||||||
|
_ident.assign(ident);
|
||||||
|
|
||||||
|
/* check for dxtn extensions */
|
||||||
|
if (!TxLoadLib::getInstance()->getdxtCompressTexFuncExt())
|
||||||
|
_options &= ~S3TC_COMPRESSION;
|
||||||
|
|
||||||
|
if (!TxLoadLib::getInstance()->getfxtCompressTexFuncExt())
|
||||||
|
_options &= ~FXT1_COMPRESSION;
|
||||||
|
|
||||||
|
switch (options & COMPRESSION_MASK) {
|
||||||
|
case FXT1_COMPRESSION:
|
||||||
|
case S3TC_COMPRESSION:
|
||||||
|
break;
|
||||||
|
case NCC_COMPRESSION:
|
||||||
|
default:
|
||||||
|
_options &= ~COMPRESSION_MASK;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TxMemBuf::getInstance()->init(_maxwidth, _maxheight)) {
|
||||||
|
if (!_tex1)
|
||||||
|
_tex1 = TxMemBuf::getInstance()->get(0);
|
||||||
|
|
||||||
|
if (!_tex2)
|
||||||
|
_tex2 = TxMemBuf::getInstance()->get(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if !_16BPP_HACK
|
||||||
|
/* initialize hq4x filter */
|
||||||
|
hq4x_init();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* initialize texture cache in bytes. 128Mb will do nicely in most cases */
|
||||||
|
_txTexCache = new TxTexCache(_options, _cacheSize, _path.c_str(), _ident.c_str(), callback);
|
||||||
|
|
||||||
|
/* hires texture */
|
||||||
|
#if HIRES_TEXTURE
|
||||||
|
_txHiResCache = new TxHiResCache(_maxwidth, _maxheight, _maxbpp, _options, _path.c_str(), _ident.c_str(), callback);
|
||||||
|
|
||||||
|
if (_txHiResCache->empty())
|
||||||
|
_options &= ~HIRESTEXTURES_MASK;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!(_options & COMPRESS_TEX))
|
||||||
|
_options &= ~COMPRESSION_MASK;
|
||||||
|
|
||||||
|
if (_tex1 && _tex2)
|
||||||
|
_initialized = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean
|
||||||
|
TxFilter::filter(uint8 *src, int srcwidth, int srcheight, uint16 srcformat, uint64 g64crc, GHQTexInfo *info)
|
||||||
|
{
|
||||||
|
uint8 *texture = src;
|
||||||
|
uint8 *tmptex = _tex1;
|
||||||
|
uint16 destformat = srcformat;
|
||||||
|
|
||||||
|
/* We need to be initialized first! */
|
||||||
|
if (!_initialized) return 0;
|
||||||
|
|
||||||
|
/* find cached textures */
|
||||||
|
if (_cacheSize) {
|
||||||
|
|
||||||
|
/* calculate checksum of source texture */
|
||||||
|
if (!g64crc)
|
||||||
|
g64crc = (uint64)(_txUtil->checksumTx(texture, srcwidth, srcheight, srcformat));
|
||||||
|
|
||||||
|
DBG_INFO(80, L"filter: crc:%08X %08X %d x %d gfmt:%x\n",
|
||||||
|
(uint32)(g64crc >> 32), (uint32)(g64crc & 0xffffffff), srcwidth, srcheight, srcformat);
|
||||||
|
|
||||||
|
#if 0 /* use hirestex to retrieve cached textures. */
|
||||||
|
/* check if we have it in cache */
|
||||||
|
if (!(g64crc & 0xffffffff00000000) && /* we reach here only when there is no hires texture for this crc */
|
||||||
|
_txTexCache->get(g64crc, info)) {
|
||||||
|
DBG_INFO(80, L"cache hit: %d x %d gfmt:%x\n", info->width, info->height, info->format);
|
||||||
|
return 1; /* yep, we've got it */
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Leave small textures alone because filtering makes little difference.
|
||||||
|
* Moreover, some filters require at least 4 * 4 to work.
|
||||||
|
* Bypass _options to do ARGB8888->16bpp if _maxbpp=16 or forced color reduction.
|
||||||
|
*/
|
||||||
|
if ((srcwidth >= 4 && srcheight >= 4) &&
|
||||||
|
((_options & (FILTER_MASK|ENHANCEMENT_MASK|COMPRESSION_MASK)) ||
|
||||||
|
(srcformat == GR_TEXFMT_ARGB_8888 && (_maxbpp < 32 || _options & FORCE16BPP_TEX)))) {
|
||||||
|
|
||||||
|
#if !_16BPP_HACK
|
||||||
|
/* convert textures to a format that the compressor accepts (ARGB8888) */
|
||||||
|
if (_options & COMPRESSION_MASK) {
|
||||||
|
#endif
|
||||||
|
if (srcformat != GR_TEXFMT_ARGB_8888) {
|
||||||
|
if (!_txQuantize->quantize(texture, tmptex, srcwidth, srcheight, srcformat, GR_TEXFMT_ARGB_8888)) {
|
||||||
|
DBG_INFO(80, L"Error: unsupported format! gfmt:%x\n", srcformat);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
texture = tmptex;
|
||||||
|
destformat = GR_TEXFMT_ARGB_8888;
|
||||||
|
}
|
||||||
|
#if !_16BPP_HACK
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
switch (destformat) {
|
||||||
|
case GR_TEXFMT_ARGB_8888:
|
||||||
|
|
||||||
|
/*
|
||||||
|
* prepare texture enhancements (x2, x4 scalers)
|
||||||
|
*/
|
||||||
|
int scale_shift = 0, num_filters = 0;
|
||||||
|
uint32 filter = 0;
|
||||||
|
|
||||||
|
if ((_options & ENHANCEMENT_MASK) == HQ4X_ENHANCEMENT) {
|
||||||
|
if (srcwidth <= (_maxwidth >> 2) && srcheight <= (_maxheight >> 2)) {
|
||||||
|
filter |= HQ4X_ENHANCEMENT;
|
||||||
|
scale_shift = 2;
|
||||||
|
num_filters++;
|
||||||
|
} else if (srcwidth <= (_maxwidth >> 1) && srcheight <= (_maxheight >> 1)) {
|
||||||
|
filter |= HQ2X_ENHANCEMENT;
|
||||||
|
scale_shift = 1;
|
||||||
|
num_filters++;
|
||||||
|
}
|
||||||
|
} else if (_options & ENHANCEMENT_MASK) {
|
||||||
|
if (srcwidth <= (_maxwidth >> 1) && srcheight <= (_maxheight >> 1)) {
|
||||||
|
filter |= (_options & ENHANCEMENT_MASK);
|
||||||
|
scale_shift = 1;
|
||||||
|
num_filters++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* prepare texture filters
|
||||||
|
*/
|
||||||
|
if (_options & (SMOOTH_FILTER_MASK|SHARP_FILTER_MASK)) {
|
||||||
|
filter |= (_options & (SMOOTH_FILTER_MASK|SHARP_FILTER_MASK));
|
||||||
|
num_filters++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* execute texture enhancements and filters
|
||||||
|
*/
|
||||||
|
while (num_filters > 0) {
|
||||||
|
|
||||||
|
tmptex = (texture == _tex1) ? _tex2 : _tex1;
|
||||||
|
|
||||||
|
uint8 *_texture = texture;
|
||||||
|
uint8 *_tmptex = tmptex;
|
||||||
|
|
||||||
|
unsigned int numcore = _numcore;
|
||||||
|
unsigned int blkrow = 0;
|
||||||
|
while (numcore > 1 && blkrow == 0) {
|
||||||
|
blkrow = (srcheight >> 2) / numcore;
|
||||||
|
numcore--;
|
||||||
|
}
|
||||||
|
if (blkrow > 0 && numcore > 1) {
|
||||||
|
boost::thread *thrd[MAX_NUMCORE];
|
||||||
|
unsigned int i;
|
||||||
|
int blkheight = blkrow << 2;
|
||||||
|
unsigned int srcStride = (srcwidth * blkheight) << 2;
|
||||||
|
unsigned int destStride = srcStride << scale_shift << scale_shift;
|
||||||
|
for (i = 0; i < numcore - 1; i++) {
|
||||||
|
thrd[i] = new boost::thread(boost::bind(filter_8888,
|
||||||
|
(uint32*)_texture,
|
||||||
|
srcwidth,
|
||||||
|
blkheight,
|
||||||
|
(uint32*)_tmptex,
|
||||||
|
filter));
|
||||||
|
_texture += srcStride;
|
||||||
|
_tmptex += destStride;
|
||||||
|
}
|
||||||
|
thrd[i] = new boost::thread(boost::bind(filter_8888,
|
||||||
|
(uint32*)_texture,
|
||||||
|
srcwidth,
|
||||||
|
srcheight - blkheight * i,
|
||||||
|
(uint32*)_tmptex,
|
||||||
|
filter));
|
||||||
|
for (i = 0; i < numcore; i++) {
|
||||||
|
thrd[i]->join();
|
||||||
|
delete thrd[i];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
filter_8888((uint32*)_texture, srcwidth, srcheight, (uint32*)_tmptex, filter);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filter & ENHANCEMENT_MASK) {
|
||||||
|
srcwidth <<= scale_shift;
|
||||||
|
srcheight <<= scale_shift;
|
||||||
|
filter &= ~ENHANCEMENT_MASK;
|
||||||
|
scale_shift = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
texture = tmptex;
|
||||||
|
num_filters--;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* texture compression
|
||||||
|
*/
|
||||||
|
/* ignored if we only have texture compression option on.
|
||||||
|
* only done when texture enhancer is used. see constructor. */
|
||||||
|
if ((_options & COMPRESSION_MASK) &&
|
||||||
|
(srcwidth >= 64 && srcheight >= 64) /* Texture compression is not suitable for low pixel coarse detail
|
||||||
|
* textures. The assumption here is that textures larger than 64x64
|
||||||
|
* have enough detail to produce decent quality when compressed. The
|
||||||
|
* down side is that narrow stripped textures that the N64 often use
|
||||||
|
* for large background textures are also ignored. It would be more
|
||||||
|
* reasonable if decisions are made based on fourier-transform
|
||||||
|
* spectrum or RMS error.
|
||||||
|
*/
|
||||||
|
) {
|
||||||
|
int compressionType = _options & COMPRESSION_MASK;
|
||||||
|
int tmpwidth, tmpheight;
|
||||||
|
uint16 tmpformat;
|
||||||
|
/* XXX: textures that use 8bit alpha channel look bad with the current
|
||||||
|
* fxt1 library, so we substitute it with dxtn for now. afaik all gfx
|
||||||
|
* cards that support fxt1 also support dxtn. (3dfx and Intel) */
|
||||||
|
if ((destformat == GR_TEXFMT_ALPHA_INTENSITY_88) ||
|
||||||
|
(destformat == GR_TEXFMT_ARGB_8888) ||
|
||||||
|
(destformat == GR_TEXFMT_ALPHA_8)) {
|
||||||
|
compressionType = S3TC_COMPRESSION;
|
||||||
|
}
|
||||||
|
tmptex = (texture == _tex1) ? _tex2 : _tex1;
|
||||||
|
if (_txQuantize->compress(texture, tmptex,
|
||||||
|
srcwidth, srcheight, srcformat,
|
||||||
|
&tmpwidth, &tmpheight, &tmpformat,
|
||||||
|
compressionType)) {
|
||||||
|
srcwidth = tmpwidth;
|
||||||
|
srcheight = tmpheight;
|
||||||
|
destformat = tmpformat;
|
||||||
|
texture = tmptex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* texture (re)conversions
|
||||||
|
*/
|
||||||
|
if (destformat == GR_TEXFMT_ARGB_8888) {
|
||||||
|
if (srcformat == GR_TEXFMT_ARGB_8888 && (_maxbpp < 32 || _options & FORCE16BPP_TEX)) srcformat = GR_TEXFMT_ARGB_4444;
|
||||||
|
if (srcformat != GR_TEXFMT_ARGB_8888) {
|
||||||
|
tmptex = (texture == _tex1) ? _tex2 : _tex1;
|
||||||
|
if (!_txQuantize->quantize(texture, tmptex, srcwidth, srcheight, GR_TEXFMT_ARGB_8888, srcformat)) {
|
||||||
|
DBG_INFO(80, L"Error: unsupported format! gfmt:%x\n", srcformat);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
texture = tmptex;
|
||||||
|
destformat = srcformat;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
#if !_16BPP_HACK
|
||||||
|
case GR_TEXFMT_ARGB_4444:
|
||||||
|
|
||||||
|
int scale_shift = 0;
|
||||||
|
tmptex = (texture == _tex1) ? _tex2 : _tex1;
|
||||||
|
|
||||||
|
switch (_options & ENHANCEMENT_MASK) {
|
||||||
|
case HQ4X_ENHANCEMENT:
|
||||||
|
if (srcwidth <= (_maxwidth >> 2) && srcheight <= (_maxheight >> 2)) {
|
||||||
|
hq4x_4444((uint8*)texture, (uint8*)tmptex, srcwidth, srcheight, srcwidth, srcwidth * 4 * 2);
|
||||||
|
scale_shift = 2;
|
||||||
|
}/* else if (srcwidth <= (_maxwidth >> 1) && srcheight <= (_maxheight >> 1)) {
|
||||||
|
hq2x_16((uint8*)texture, srcwidth * 2, (uint8*)tmptex, srcwidth * 2 * 2, srcwidth, srcheight);
|
||||||
|
scale_shift = 1;
|
||||||
|
}*/
|
||||||
|
break;
|
||||||
|
case HQ2X_ENHANCEMENT:
|
||||||
|
if (srcwidth <= (_maxwidth >> 1) && srcheight <= (_maxheight >> 1)) {
|
||||||
|
hq2x_16((uint8*)texture, srcwidth * 2, (uint8*)tmptex, srcwidth * 2 * 2, srcwidth, srcheight);
|
||||||
|
scale_shift = 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case HQ2XS_ENHANCEMENT:
|
||||||
|
if (srcwidth <= (_maxwidth >> 1) && srcheight <= (_maxheight >> 1)) {
|
||||||
|
hq2xS_16((uint8*)texture, srcwidth * 2, (uint8*)tmptex, srcwidth * 2 * 2, srcwidth, srcheight);
|
||||||
|
scale_shift = 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case LQ2X_ENHANCEMENT:
|
||||||
|
if (srcwidth <= (_maxwidth >> 1) && srcheight <= (_maxheight >> 1)) {
|
||||||
|
lq2x_16((uint8*)texture, srcwidth * 2, (uint8*)tmptex, srcwidth * 2 * 2, srcwidth, srcheight);
|
||||||
|
scale_shift = 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case LQ2XS_ENHANCEMENT:
|
||||||
|
if (srcwidth <= (_maxwidth >> 1) && srcheight <= (_maxheight >> 1)) {
|
||||||
|
lq2xS_16((uint8*)texture, srcwidth * 2, (uint8*)tmptex, srcwidth * 2 * 2, srcwidth, srcheight);
|
||||||
|
scale_shift = 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case X2SAI_ENHANCEMENT:
|
||||||
|
if (srcwidth <= (_maxwidth >> 1) && srcheight <= (_maxheight >> 1)) {
|
||||||
|
Super2xSaI_4444((uint16*)texture, (uint16*)tmptex, srcwidth, srcheight, srcwidth);
|
||||||
|
scale_shift = 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case X2_ENHANCEMENT:
|
||||||
|
if (srcwidth <= (_maxwidth >> 1) && srcheight <= (_maxheight >> 1)) {
|
||||||
|
Texture2x_16((uint8*)texture, srcwidth * 2, (uint8*)tmptex, srcwidth * 2 * 2, srcwidth, srcheight);
|
||||||
|
scale_shift = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (scale_shift) {
|
||||||
|
srcwidth <<= scale_shift;
|
||||||
|
srcheight <<= scale_shift;
|
||||||
|
texture = tmptex;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_options & SMOOTH_FILTER_MASK) {
|
||||||
|
tmptex = (texture == _tex1) ? _tex2 : _tex1;
|
||||||
|
SmoothFilter_4444((uint16*)texture, srcwidth, srcheight, (uint16*)tmptex, (_options & SMOOTH_FILTER_MASK));
|
||||||
|
texture = tmptex;
|
||||||
|
} else if (_options & SHARP_FILTER_MASK) {
|
||||||
|
tmptex = (texture == _tex1) ? _tex2 : _tex1;
|
||||||
|
SharpFilter_4444((uint16*)texture, srcwidth, srcheight, (uint16*)tmptex, (_options & SHARP_FILTER_MASK));
|
||||||
|
texture = tmptex;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case GR_TEXFMT_ARGB_1555:
|
||||||
|
break;
|
||||||
|
case GR_TEXFMT_RGB_565:
|
||||||
|
break;
|
||||||
|
case GR_TEXFMT_ALPHA_8:
|
||||||
|
break;
|
||||||
|
#endif /* _16BPP_HACK */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* fill in the texture info. */
|
||||||
|
info->data = texture;
|
||||||
|
info->width = srcwidth;
|
||||||
|
info->height = srcheight;
|
||||||
|
info->format = destformat;
|
||||||
|
info->smallLodLog2 = _txUtil->grLodLog2(srcwidth, srcheight);
|
||||||
|
info->largeLodLog2 = info->smallLodLog2;
|
||||||
|
info->aspectRatioLog2 = _txUtil->grAspectRatioLog2(srcwidth, srcheight);
|
||||||
|
info->is_hires_tex = 0;
|
||||||
|
|
||||||
|
/* cache the texture. */
|
||||||
|
if (_cacheSize) _txTexCache->add(g64crc, info);
|
||||||
|
|
||||||
|
DBG_INFO(80, L"filtered texture: %d x %d gfmt:%x\n", info->width, info->height, info->format);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean
|
||||||
|
TxFilter::hirestex(uint64 g64crc, uint64 r_crc64, uint16 *palette, GHQTexInfo *info)
|
||||||
|
{
|
||||||
|
/* NOTE: Rice CRC32 sometimes return the same value for different textures.
|
||||||
|
* As a workaround, Glide64 CRC32 is used for the key for NON-hires
|
||||||
|
* texture cache.
|
||||||
|
*
|
||||||
|
* r_crc64 = hi:palette low:texture
|
||||||
|
* (separate crc. doesn't necessary have to be rice crc)
|
||||||
|
* g64crc = texture + palette glide64 crc32
|
||||||
|
* (can be any other crc if robust)
|
||||||
|
*/
|
||||||
|
|
||||||
|
DBG_INFO(80, L"hirestex: r_crc64:%08X %08X, g64crc:%08X %08X\n",
|
||||||
|
(uint32)(r_crc64 >> 32), (uint32)(r_crc64 & 0xffffffff),
|
||||||
|
(uint32)(g64crc >> 32), (uint32)(g64crc & 0xffffffff));
|
||||||
|
|
||||||
|
#if HIRES_TEXTURE
|
||||||
|
/* check if we have it in hires memory cache. */
|
||||||
|
if ((_options & HIRESTEXTURES_MASK) && r_crc64) {
|
||||||
|
if (_txHiResCache->get(r_crc64, info)) {
|
||||||
|
DBG_INFO(80, L"hires hit: %d x %d gfmt:%x\n", info->width, info->height, info->format);
|
||||||
|
|
||||||
|
/* TODO: Enable emulation for special N64 combiner modes. There are few ways
|
||||||
|
* to get this done. Also applies for CI textures below.
|
||||||
|
*
|
||||||
|
* Solution 1. Load the hiresolution textures in ARGB8888 (or A8, IA88) format
|
||||||
|
* to cache. When a cache is hit, then we take the modes passed in from Glide64
|
||||||
|
* (also TODO) and apply the modification. Then we do color reduction or format
|
||||||
|
* conversion or compression if desired and stuff it into the non-hires texture
|
||||||
|
* cache.
|
||||||
|
*
|
||||||
|
* Solution 2. When a cache is hit and if the combiner modes are present,
|
||||||
|
* convert the texture to ARGB4444 and pass it back to Glide64 to process.
|
||||||
|
* If a texture is compressed, it needs to be decompressed first. Then add
|
||||||
|
* the processed texture to the non-hires texture cache.
|
||||||
|
*
|
||||||
|
* Solution 3. Hybrid of the above 2. Load the textures in ARGB8888 (A8, IA88)
|
||||||
|
* format. Convert the texture to ARGB4444 and pass it back to Glide64 when
|
||||||
|
* the combiner modes are present. Get the processed texture back from Glide64
|
||||||
|
* and compress if desired and add it to the non-hires texture cache.
|
||||||
|
*
|
||||||
|
* Solution 4. Take the easy way out and forget about this whole thing.
|
||||||
|
*/
|
||||||
|
|
||||||
|
return 1; /* yep, got it */
|
||||||
|
}
|
||||||
|
if (_txHiResCache->get((r_crc64 & 0xffffffff), info)) {
|
||||||
|
DBG_INFO(80, L"hires hit: %d x %d gfmt:%x\n", info->width, info->height, info->format);
|
||||||
|
|
||||||
|
/* for true CI textures, we use the passed in palette to convert to
|
||||||
|
* ARGB1555 and add it to memory cache.
|
||||||
|
*
|
||||||
|
* NOTE: we do this AFTER all other texture cache searches because
|
||||||
|
* only a few texture packs actually use true CI textures.
|
||||||
|
*
|
||||||
|
* NOTE: the pre-converted palette from Glide64 is in RGBA5551 format.
|
||||||
|
* A comp comes before RGB comp.
|
||||||
|
*/
|
||||||
|
if (palette && info->format == GR_TEXFMT_P_8) {
|
||||||
|
DBG_INFO(80, L"found GR_TEXFMT_P_8 format. Need conversion!!\n");
|
||||||
|
|
||||||
|
int width = info->width;
|
||||||
|
int height = info->height;
|
||||||
|
uint16 format = info->format;
|
||||||
|
/* XXX: avoid collision with zlib compression buffer in TxHiResTexture::get */
|
||||||
|
uint8 *texture = info->data;
|
||||||
|
uint8 *tmptex = (texture == _tex1) ? _tex2 : _tex1;
|
||||||
|
|
||||||
|
/* use palette and convert to 16bit format */
|
||||||
|
_txQuantize->P8_16BPP((uint32*)texture, (uint32*)tmptex, info->width, info->height, (uint32*)palette);
|
||||||
|
texture = tmptex;
|
||||||
|
format = GR_TEXFMT_ARGB_1555;
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
/* XXX: compressed if memory cache compression is ON */
|
||||||
|
if (_options & COMPRESSION_MASK) {
|
||||||
|
tmptex = (texture == _tex1) ? _tex2 : _tex1;
|
||||||
|
if (_txQuantize->quantize(texture, tmptex, info->width, info->height, format, GR_TEXFMT_ARGB_8888)) {
|
||||||
|
texture = tmptex;
|
||||||
|
format = GR_TEXFMT_ARGB_8888;
|
||||||
|
}
|
||||||
|
if (format == GR_TEXFMT_ARGB_8888) {
|
||||||
|
tmptex = (texture == _tex1) ? _tex2 : _tex1;
|
||||||
|
if (_txQuantize->compress(texture, tmptex,
|
||||||
|
info->width, info->height, GR_TEXFMT_ARGB_1555,
|
||||||
|
&width, &height, &format,
|
||||||
|
_options & COMPRESSION_MASK)) {
|
||||||
|
texture = tmptex;
|
||||||
|
} else {
|
||||||
|
/*if (!_txQuantize->quantize(texture, tmptex, info->width, info->height, GR_TEXFMT_ARGB_8888, GR_TEXFMT_ARGB_1555)) {
|
||||||
|
DBG_INFO(80, L"Error: unsupported format! gfmt:%x\n", format);
|
||||||
|
return 0;
|
||||||
|
}*/
|
||||||
|
texture = tmptex;
|
||||||
|
format = GR_TEXFMT_ARGB_1555;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* fill in the required info to return */
|
||||||
|
info->data = texture;
|
||||||
|
info->width = width;
|
||||||
|
info->height = height;
|
||||||
|
info->format = format;
|
||||||
|
info->smallLodLog2 = _txUtil->grLodLog2(width, height);
|
||||||
|
info->largeLodLog2 = info->smallLodLog2;
|
||||||
|
info->aspectRatioLog2 = _txUtil->grAspectRatioLog2(width, height);
|
||||||
|
info->is_hires_tex = 1;
|
||||||
|
|
||||||
|
/* XXX: add to hires texture cache!!! */
|
||||||
|
_txHiResCache->add(r_crc64, info);
|
||||||
|
|
||||||
|
DBG_INFO(80, L"GR_TEXFMT_P_8 loaded as gfmt:%x!\n", format);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* check if we have it in memory cache */
|
||||||
|
if (_cacheSize && g64crc) {
|
||||||
|
if (_txTexCache->get(g64crc, info)) {
|
||||||
|
DBG_INFO(80, L"cache hit: %d x %d gfmt:%x\n", info->width, info->height, info->format);
|
||||||
|
return 1; /* yep, we've got it */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DBG_INFO(80, L"no cache hits.\n");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64
|
||||||
|
TxFilter::checksum64(uint8 *src, int width, int height, int size, int rowStride, uint8 *palette)
|
||||||
|
{
|
||||||
|
if (_options & (HIRESTEXTURES_MASK|DUMP_TEX))
|
||||||
|
return _txUtil->checksum64(src, width, height, size, rowStride, palette);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean
|
||||||
|
TxFilter::dmptx(uint8 *src, int width, int height, int rowStridePixel, uint16 gfmt, uint16 n64fmt, uint64 r_crc64)
|
||||||
|
{
|
||||||
|
if (!_initialized)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (!(_options & DUMP_TEX))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
DBG_INFO(80, L"gfmt = %02x n64fmt = %02x\n", gfmt, n64fmt);
|
||||||
|
DBG_INFO(80, L"hirestex: r_crc64:%08X %08X\n",
|
||||||
|
(uint32)(r_crc64 >> 32), (uint32)(r_crc64 & 0xffffffff));
|
||||||
|
|
||||||
|
if (!_txQuantize->quantize(src, _tex1, rowStridePixel, height, (gfmt & 0x00ff), GR_TEXFMT_ARGB_8888))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
src = _tex1;
|
||||||
|
|
||||||
|
if (!_path.empty() && !_ident.empty()) {
|
||||||
|
/* dump it to disk */
|
||||||
|
FILE *fp = NULL;
|
||||||
|
std::wstring tmpbuf;
|
||||||
|
|
||||||
|
/* create directories */
|
||||||
|
tmpbuf.assign(_path + L"/texture_dump");
|
||||||
|
if (!boost::filesystem::exists(tmpbuf) &&
|
||||||
|
!boost::filesystem::create_directory(tmpbuf))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
tmpbuf.append(L"/" + _ident);
|
||||||
|
if (!boost::filesystem::exists(tmpbuf) &&
|
||||||
|
!boost::filesystem::create_directory(tmpbuf))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
tmpbuf.append(L"/GlideHQ");
|
||||||
|
if (!boost::filesystem::exists(tmpbuf) &&
|
||||||
|
!boost::filesystem::create_directory(tmpbuf))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if ((n64fmt >> 8) == 0x2) {
|
||||||
|
tmpbuf.append(boost::str(boost::wformat(L"/%ls#%08X#%01X#%01X#%08X_ciByRGBA.png")
|
||||||
|
% _ident.c_str() % (uint32)(r_crc64 & 0xffffffff) % (n64fmt >> 8) % (n64fmt & 0xf) % (uint32)(r_crc64 >> 32)));
|
||||||
|
} else {
|
||||||
|
tmpbuf.append(boost::str(boost::wformat(L"/%ls#%08X#%01X#%01X_all.png")
|
||||||
|
% _ident.c_str() % (uint32)(r_crc64 & 0xffffffff) % (n64fmt >> 8) % (n64fmt & 0xf)));
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
if ((fp = _wfopen(tmpbuf.c_str(), L"wb")) != NULL) {
|
||||||
|
#else
|
||||||
|
char cbuf[MAX_PATH];
|
||||||
|
wcstombs(cbuf, tmpbuf.c_str(), MAX_PATH);
|
||||||
|
if ((fp = fopen(cbuf, "wb")) != NULL) {
|
||||||
|
#endif
|
||||||
|
_txImage->writePNG(src, fp, width, height, (rowStridePixel << 2), 0x0003, 0);
|
||||||
|
fclose(fp);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean
|
||||||
|
TxFilter::reloadhirestex()
|
||||||
|
{
|
||||||
|
DBG_INFO(80, L"Reload hires textures from texture pack.\n");
|
||||||
|
|
||||||
|
if (_txHiResCache->load(0)) {
|
||||||
|
if (_txHiResCache->empty()) _options &= ~HIRESTEXTURES_MASK;
|
||||||
|
else _options |= HIRESTEXTURES_MASK;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
81
GLideNHQ/TxFilter.h
Normal file
81
GLideNHQ/TxFilter.h
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
/*
|
||||||
|
* Texture Filtering
|
||||||
|
* Version: 1.0
|
||||||
|
*
|
||||||
|
* Copyright (C) 2007 Hiroshi Morii All Rights Reserved.
|
||||||
|
* Email koolsmoky(at)users.sourceforge.net
|
||||||
|
* Web http://www.3dfxzone.it/koolsmoky
|
||||||
|
*
|
||||||
|
* this 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, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* this 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 GNU Make; see the file COPYING. If not, write to
|
||||||
|
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __TXFILTER_H__
|
||||||
|
#define __TXFILTER_H__
|
||||||
|
|
||||||
|
#include "TxInternal.h"
|
||||||
|
#include "TxQuantize.h"
|
||||||
|
#include "TxHiResCache.h"
|
||||||
|
#include "TxTexCache.h"
|
||||||
|
#include "TxUtil.h"
|
||||||
|
#include "TxImage.h"
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
class TxFilter
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
int _numcore;
|
||||||
|
|
||||||
|
uint8 *_tex1;
|
||||||
|
uint8 *_tex2;
|
||||||
|
int _maxwidth;
|
||||||
|
int _maxheight;
|
||||||
|
int _maxbpp;
|
||||||
|
int _options;
|
||||||
|
int _cacheSize;
|
||||||
|
std::wstring _ident;
|
||||||
|
std::wstring _path;
|
||||||
|
TxQuantize *_txQuantize;
|
||||||
|
TxTexCache *_txTexCache;
|
||||||
|
TxHiResCache *_txHiResCache;
|
||||||
|
TxUtil *_txUtil;
|
||||||
|
TxImage *_txImage;
|
||||||
|
boolean _initialized;
|
||||||
|
void clear();
|
||||||
|
public:
|
||||||
|
~TxFilter();
|
||||||
|
TxFilter(int maxwidth,
|
||||||
|
int maxheight,
|
||||||
|
int maxbpp,
|
||||||
|
int options,
|
||||||
|
int cachesize,
|
||||||
|
wchar_t *path,
|
||||||
|
wchar_t *ident,
|
||||||
|
dispInfoFuncExt callback);
|
||||||
|
boolean filter(uint8 *src,
|
||||||
|
int srcwidth,
|
||||||
|
int srcheight,
|
||||||
|
uint16 srcformat,
|
||||||
|
uint64 g64crc, /* glide64 crc, 64bit for future use */
|
||||||
|
GHQTexInfo *info);
|
||||||
|
boolean hirestex(uint64 g64crc, /* glide64 crc, 64bit for future use */
|
||||||
|
uint64 r_crc64, /* checksum hi:palette low:texture */
|
||||||
|
uint16 *palette,
|
||||||
|
GHQTexInfo *info);
|
||||||
|
uint64 checksum64(uint8 *src, int width, int height, int size, int rowStride, uint8 *palette);
|
||||||
|
boolean dmptx(uint8 *src, int width, int height, int rowStridePixel, uint16 gfmt, uint16 n64fmt, uint64 r_crc64);
|
||||||
|
boolean reloadhirestex();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* __TXFILTER_H__ */
|
106
GLideNHQ/TxFilterExport.cpp
Normal file
106
GLideNHQ/TxFilterExport.cpp
Normal file
|
@ -0,0 +1,106 @@
|
||||||
|
/*
|
||||||
|
* Texture Filtering
|
||||||
|
* Version: 1.0
|
||||||
|
*
|
||||||
|
* Copyright (C) 2007 Hiroshi Morii All Rights Reserved.
|
||||||
|
* Email koolsmoky(at)users.sourceforge.net
|
||||||
|
* Web http://www.3dfxzone.it/koolsmoky
|
||||||
|
*
|
||||||
|
* this 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, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* this 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 GNU Make; see the file COPYING. If not, write to
|
||||||
|
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef __MSC__
|
||||||
|
#pragma warning(disable: 4786)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "TxFilter.h"
|
||||||
|
|
||||||
|
TxFilter *txFilter = NULL;
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
TAPI boolean TAPIENTRY
|
||||||
|
txfilter_init(int maxwidth, int maxheight, int maxbpp, int options, int cachesize,
|
||||||
|
wchar_t *path, wchar_t*ident,
|
||||||
|
dispInfoFuncExt callback)
|
||||||
|
{
|
||||||
|
if (txFilter) return 0;
|
||||||
|
|
||||||
|
txFilter = new TxFilter(maxwidth, maxheight, maxbpp, options, cachesize,
|
||||||
|
path, ident, callback);
|
||||||
|
|
||||||
|
return (txFilter ? 1 : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
TAPI void TAPIENTRY
|
||||||
|
txfilter_shutdown(void)
|
||||||
|
{
|
||||||
|
if (txFilter) delete txFilter;
|
||||||
|
|
||||||
|
txFilter = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
TAPI boolean TAPIENTRY
|
||||||
|
txfilter(uint8 *src, int srcwidth, int srcheight, uint16 srcformat,
|
||||||
|
uint64 g64crc, GHQTexInfo *info)
|
||||||
|
{
|
||||||
|
if (txFilter)
|
||||||
|
return txFilter->filter(src, srcwidth, srcheight, srcformat,
|
||||||
|
g64crc, info);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
TAPI boolean TAPIENTRY
|
||||||
|
txfilter_hirestex(uint64 g64crc, uint64 r_crc64, uint16 *palette, GHQTexInfo *info)
|
||||||
|
{
|
||||||
|
if (txFilter)
|
||||||
|
return txFilter->hirestex(g64crc, r_crc64, palette, info);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
TAPI uint64 TAPIENTRY
|
||||||
|
txfilter_checksum(uint8 *src, int width, int height, int size, int rowStride, uint8 *palette)
|
||||||
|
{
|
||||||
|
if (txFilter)
|
||||||
|
return txFilter->checksum64(src, width, height, size, rowStride, palette);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
TAPI boolean TAPIENTRY
|
||||||
|
txfilter_dmptx(uint8 *src, int width, int height, int rowStridePixel, uint16 gfmt, uint16 n64fmt, uint64 r_crc64)
|
||||||
|
{
|
||||||
|
if (txFilter)
|
||||||
|
return txFilter->dmptx(src, width, height, rowStridePixel, gfmt, n64fmt, r_crc64);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
TAPI boolean TAPIENTRY
|
||||||
|
txfilter_reloadhirestex()
|
||||||
|
{
|
||||||
|
if (txFilter)
|
||||||
|
return txFilter->reloadhirestex();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
1080
GLideNHQ/TxHiResCache.cpp
Normal file
1080
GLideNHQ/TxHiResCache.cpp
Normal file
File diff suppressed because it is too large
Load Diff
60
GLideNHQ/TxHiResCache.h
Normal file
60
GLideNHQ/TxHiResCache.h
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
/*
|
||||||
|
* Texture Filtering
|
||||||
|
* Version: 1.0
|
||||||
|
*
|
||||||
|
* Copyright (C) 2007 Hiroshi Morii All Rights Reserved.
|
||||||
|
* Email koolsmoky(at)users.sourceforge.net
|
||||||
|
* Web http://www.3dfxzone.it/koolsmoky
|
||||||
|
*
|
||||||
|
* this 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, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* this 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 GNU Make; see the file COPYING. If not, write to
|
||||||
|
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __TXHIRESCACHE_H__
|
||||||
|
#define __TXHIRESCACHE_H__
|
||||||
|
|
||||||
|
/* support hires textures
|
||||||
|
* 0: disable
|
||||||
|
* 1: enable
|
||||||
|
*/
|
||||||
|
#define HIRES_TEXTURE 1
|
||||||
|
|
||||||
|
#include "TxCache.h"
|
||||||
|
#include "TxQuantize.h"
|
||||||
|
#include "TxImage.h"
|
||||||
|
#include "TxReSample.h"
|
||||||
|
#include <boost/filesystem.hpp>
|
||||||
|
|
||||||
|
class TxHiResCache : public TxCache
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
int _maxwidth;
|
||||||
|
int _maxheight;
|
||||||
|
int _maxbpp;
|
||||||
|
boolean _haveCache;
|
||||||
|
boolean _abortLoad;
|
||||||
|
TxImage *_txImage;
|
||||||
|
TxQuantize *_txQuantize;
|
||||||
|
TxReSample *_txReSample;
|
||||||
|
boolean loadHiResTextures(boost::filesystem::wpath dir_path, boolean replace);
|
||||||
|
public:
|
||||||
|
~TxHiResCache();
|
||||||
|
TxHiResCache(int maxwidth, int maxheight, int maxbpp, int options,
|
||||||
|
const wchar_t *path, const wchar_t *ident,
|
||||||
|
dispInfoFuncExt callback);
|
||||||
|
boolean empty();
|
||||||
|
boolean load(boolean replace);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* __TXHIRESCACHE_H__ */
|
799
GLideNHQ/TxImage.cpp
Normal file
799
GLideNHQ/TxImage.cpp
Normal file
|
@ -0,0 +1,799 @@
|
||||||
|
/*
|
||||||
|
* Texture Filtering
|
||||||
|
* Version: 1.0
|
||||||
|
*
|
||||||
|
* Copyright (C) 2007 Hiroshi Morii All Rights Reserved.
|
||||||
|
* Email koolsmoky(at)users.sourceforge.net
|
||||||
|
* Web http://www.3dfxzone.it/koolsmoky
|
||||||
|
*
|
||||||
|
* this 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, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* this 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 GNU Make; see the file COPYING. If not, write to
|
||||||
|
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* use power of 2 texture size
|
||||||
|
* (0:disable, 1:enable, 2:3dfx) */
|
||||||
|
#define POW2_TEXTURES 0
|
||||||
|
|
||||||
|
/* check 8 bytes. use a larger value if needed. */
|
||||||
|
#define PNG_CHK_BYTES 8
|
||||||
|
|
||||||
|
#include "TxImage.h"
|
||||||
|
#include "TxReSample.h"
|
||||||
|
#include "TxDbg.h"
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
boolean
|
||||||
|
TxImage::getPNGInfo(FILE *fp, png_structp *png_ptr, png_infop *info_ptr)
|
||||||
|
{
|
||||||
|
unsigned char sig[PNG_CHK_BYTES];
|
||||||
|
|
||||||
|
/* check for valid file pointer */
|
||||||
|
if (!fp)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* check if file is PNG */
|
||||||
|
if (fread(sig, 1, PNG_CHK_BYTES, fp) != PNG_CHK_BYTES)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (png_sig_cmp(sig, 0, PNG_CHK_BYTES) != 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* get PNG file info */
|
||||||
|
*png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
|
||||||
|
if (!*png_ptr)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
*info_ptr = png_create_info_struct(*png_ptr);
|
||||||
|
if (!*info_ptr) {
|
||||||
|
png_destroy_read_struct(png_ptr, NULL, NULL);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (setjmp(png_jmpbuf(*png_ptr))) {
|
||||||
|
DBG_INFO(80, L"error reading png!\n");
|
||||||
|
png_destroy_read_struct(png_ptr, info_ptr, NULL);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
png_init_io(*png_ptr, fp);
|
||||||
|
png_set_sig_bytes(*png_ptr, PNG_CHK_BYTES);
|
||||||
|
png_read_info(*png_ptr, *info_ptr);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8*
|
||||||
|
TxImage::readPNG(FILE* fp, int* width, int* height, uint16* format)
|
||||||
|
{
|
||||||
|
/* NOTE: returned image format is GR_TEXFMT_ARGB_8888 */
|
||||||
|
|
||||||
|
png_structp png_ptr;
|
||||||
|
png_infop info_ptr;
|
||||||
|
uint8 *image = NULL;
|
||||||
|
int bit_depth, color_type, interlace_type, compression_type, filter_type,
|
||||||
|
row_bytes, o_width, o_height, num_pas;
|
||||||
|
|
||||||
|
/* initialize */
|
||||||
|
*width = 0;
|
||||||
|
*height = 0;
|
||||||
|
*format = 0;
|
||||||
|
|
||||||
|
/* check if we have a valid png file */
|
||||||
|
if (!fp)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (!getPNGInfo(fp, &png_ptr, &info_ptr)) {
|
||||||
|
INFO(80, L"error reading png file! png image is corrupt.\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
png_get_IHDR(png_ptr, info_ptr,
|
||||||
|
(png_uint_32*)&o_width, (png_uint_32*)&o_height, &bit_depth, &color_type,
|
||||||
|
&interlace_type, &compression_type, &filter_type);
|
||||||
|
|
||||||
|
DBG_INFO(80, L"png format %d x %d bitdepth:%d color:%x interlace:%x compression:%x filter:%x\n",
|
||||||
|
o_width, o_height, bit_depth, color_type,
|
||||||
|
interlace_type, compression_type, filter_type);
|
||||||
|
|
||||||
|
/* transformations */
|
||||||
|
|
||||||
|
/* Rice hi-res textures
|
||||||
|
* _all.png
|
||||||
|
* _rgb.png, _a.png
|
||||||
|
* _ciByRGBA.png
|
||||||
|
* _allciByRGBA.png
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* strip if color channel is larger than 8 bits */
|
||||||
|
if (bit_depth > 8) {
|
||||||
|
png_set_strip_16(png_ptr);
|
||||||
|
bit_depth = 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
/* These are not really required per Rice format spec,
|
||||||
|
* but is done just in case someone uses them.
|
||||||
|
*/
|
||||||
|
/* convert palette color to rgb color */
|
||||||
|
if (color_type == PNG_COLOR_TYPE_PALETTE) {
|
||||||
|
png_set_palette_to_rgb(png_ptr);
|
||||||
|
color_type = PNG_COLOR_TYPE_RGB;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* expand 1,2,4 bit gray scale to 8 bit gray scale */
|
||||||
|
if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
|
||||||
|
png_set_expand_gray_1_2_4_to_8(png_ptr);
|
||||||
|
|
||||||
|
/* convert gray scale or gray scale + alpha to rgb color */
|
||||||
|
if (color_type == PNG_COLOR_TYPE_GRAY ||
|
||||||
|
color_type == PNG_COLOR_TYPE_GRAY_ALPHA) {
|
||||||
|
png_set_gray_to_rgb(png_ptr);
|
||||||
|
color_type = PNG_COLOR_TYPE_RGB;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* add alpha channel if any */
|
||||||
|
if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
|
||||||
|
png_set_tRNS_to_alpha(png_ptr);
|
||||||
|
color_type = PNG_COLOR_TYPE_RGB_ALPHA;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* convert rgb to rgba */
|
||||||
|
if (color_type == PNG_COLOR_TYPE_RGB) {
|
||||||
|
png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER);
|
||||||
|
color_type = PNG_COLOR_TYPE_RGB_ALPHA;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* punt invalid formats */
|
||||||
|
if (color_type != PNG_COLOR_TYPE_RGB_ALPHA) {
|
||||||
|
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
|
||||||
|
DBG_INFO(80, L"Error: not PNG_COLOR_TYPE_RGB_ALPHA format!\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*png_color_8p sig_bit;
|
||||||
|
if (png_get_sBIT(png_ptr, info_ptr, &sig_bit))
|
||||||
|
png_set_shift(png_ptr, sig_bit);*/
|
||||||
|
|
||||||
|
/* convert rgba to bgra */
|
||||||
|
png_set_bgr(png_ptr);
|
||||||
|
|
||||||
|
/* turn on interlace handling to cope with the weirdness
|
||||||
|
* of texture authors using interlaced format */
|
||||||
|
num_pas = png_set_interlace_handling(png_ptr);
|
||||||
|
|
||||||
|
/* update info structure */
|
||||||
|
png_read_update_info(png_ptr, info_ptr);
|
||||||
|
|
||||||
|
/* we only get here if ARGB8888 */
|
||||||
|
row_bytes = png_get_rowbytes(png_ptr, info_ptr);
|
||||||
|
|
||||||
|
/* allocate memory to read in image */
|
||||||
|
image = (uint8*)malloc(row_bytes * o_height);
|
||||||
|
|
||||||
|
/* read in image */
|
||||||
|
if (image) {
|
||||||
|
int pas, i;
|
||||||
|
uint8* tmpimage;
|
||||||
|
|
||||||
|
for (pas = 0; pas < num_pas; pas++) { /* deal with interlacing */
|
||||||
|
tmpimage = image;
|
||||||
|
|
||||||
|
for (i = 0; i < o_height; i++) {
|
||||||
|
/* copy row */
|
||||||
|
png_read_rows(png_ptr, &tmpimage, NULL, 1);
|
||||||
|
tmpimage += row_bytes;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* read rest of the info structure */
|
||||||
|
png_read_end(png_ptr, info_ptr);
|
||||||
|
|
||||||
|
*width = (row_bytes >> 2);
|
||||||
|
*height = o_height;
|
||||||
|
*format = GR_TEXFMT_ARGB_8888;
|
||||||
|
|
||||||
|
#if POW2_TEXTURES
|
||||||
|
/* next power of 2 size conversions */
|
||||||
|
/* NOTE: I can do this in the above loop for faster operations, but some
|
||||||
|
* texture packs require a workaround. see HACKALERT in nextPow2().
|
||||||
|
*/
|
||||||
|
|
||||||
|
TxReSample txReSample = new TxReSample; // XXX: temporary. move to a better place.
|
||||||
|
|
||||||
|
#if (POW2_TEXTURES == 2)
|
||||||
|
if (!txReSample->nextPow2(&image, width, height, 32, 1)) {
|
||||||
|
#else
|
||||||
|
if (!txReSample->nextPow2(&image, width, height, 32, 0)) {
|
||||||
|
#endif
|
||||||
|
if (image) {
|
||||||
|
free(image);
|
||||||
|
image = NULL;
|
||||||
|
}
|
||||||
|
*width = 0;
|
||||||
|
*height = 0;
|
||||||
|
*format = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
delete txReSample;
|
||||||
|
|
||||||
|
#endif /* POW2_TEXTURES */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* clean up */
|
||||||
|
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
if (!image) {
|
||||||
|
DBG_INFO(80, L"Error: failed to load png image!\n");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return image;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean
|
||||||
|
TxImage::writePNG(uint8* src, FILE* fp, int width, int height, int rowStride, uint16 format, uint8 *palette)
|
||||||
|
{
|
||||||
|
png_structp png_ptr;
|
||||||
|
png_infop info_ptr;
|
||||||
|
png_color_8 sig_bit;
|
||||||
|
png_colorp palette_ptr;
|
||||||
|
png_bytep trans_ptr;//, tex_ptr;
|
||||||
|
int bit_depth, color_type, row_bytes, num_palette;
|
||||||
|
int i;
|
||||||
|
//uint16 srcfmt, destfmt;
|
||||||
|
|
||||||
|
if (!src || !fp)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
|
||||||
|
if (png_ptr == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
info_ptr = png_create_info_struct(png_ptr);
|
||||||
|
if (info_ptr == NULL) {
|
||||||
|
png_destroy_write_struct(&png_ptr, NULL);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (setjmp(png_ptr->jmpbuf)) {
|
||||||
|
png_destroy_write_struct(&png_ptr, &info_ptr);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
png_init_io(png_ptr, fp);
|
||||||
|
|
||||||
|
/* TODO: images must be converted to RGBA8888 or CI8,
|
||||||
|
* palettes need to be separated to A and RGB. */
|
||||||
|
|
||||||
|
/* N64 formats
|
||||||
|
* Format: 0 - RGBA, 1 - YUV, 2 - CI, 3 - IA, 4 - I
|
||||||
|
* Size: 0 - 4bit, 1 - 8bit, 2 - 16bit, 3 - 32 bit
|
||||||
|
* format = (Format << 8 | Size);
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* each channel is saved in 8bits for consistency */
|
||||||
|
switch (format) {
|
||||||
|
case 0x0002:/* RGBA5551 */
|
||||||
|
bit_depth = 8;
|
||||||
|
sig_bit.red = 5;
|
||||||
|
sig_bit.green = 5;
|
||||||
|
sig_bit.blue = 5;
|
||||||
|
sig_bit.alpha = 1;
|
||||||
|
color_type = PNG_COLOR_TYPE_RGB_ALPHA;
|
||||||
|
break;
|
||||||
|
case 0x0003:/* RGBA8888 */
|
||||||
|
case 0x0302:/* IA88 */
|
||||||
|
bit_depth = 8;
|
||||||
|
sig_bit.red = 8;
|
||||||
|
sig_bit.green = 8;
|
||||||
|
sig_bit.blue = 8;
|
||||||
|
sig_bit.alpha = 8;
|
||||||
|
color_type = PNG_COLOR_TYPE_RGB_ALPHA;
|
||||||
|
break;
|
||||||
|
case 0x0300:/* IA31 */
|
||||||
|
bit_depth = 8;
|
||||||
|
sig_bit.red = 3;
|
||||||
|
sig_bit.green = 3;
|
||||||
|
sig_bit.blue = 3;
|
||||||
|
sig_bit.alpha = 1;
|
||||||
|
color_type = PNG_COLOR_TYPE_RGB_ALPHA;
|
||||||
|
break;
|
||||||
|
case 0x0301:/* IA44 */
|
||||||
|
bit_depth = 8;
|
||||||
|
sig_bit.red = 4;
|
||||||
|
sig_bit.green = 4;
|
||||||
|
sig_bit.blue = 4;
|
||||||
|
sig_bit.alpha = 4;
|
||||||
|
color_type = PNG_COLOR_TYPE_RGB_ALPHA;
|
||||||
|
break;
|
||||||
|
case 0x0400:/* I4 */
|
||||||
|
bit_depth = 8;
|
||||||
|
sig_bit.red = 4;
|
||||||
|
sig_bit.green = 4;
|
||||||
|
sig_bit.blue = 4;
|
||||||
|
color_type = PNG_COLOR_TYPE_RGB;
|
||||||
|
break;
|
||||||
|
case 0x0401:/* I8 */
|
||||||
|
case 0x0402:/* I16 */
|
||||||
|
bit_depth = 8;
|
||||||
|
sig_bit.red = 8;
|
||||||
|
sig_bit.green = 8;
|
||||||
|
sig_bit.blue = 8;
|
||||||
|
color_type = PNG_COLOR_TYPE_RGB;
|
||||||
|
break;
|
||||||
|
case 0x0200:/* CI4 */
|
||||||
|
bit_depth = 8;
|
||||||
|
num_palette = 16;
|
||||||
|
color_type = PNG_COLOR_TYPE_PALETTE;
|
||||||
|
break;
|
||||||
|
case 0x0201:/* CI8 */
|
||||||
|
bit_depth = 8;
|
||||||
|
num_palette = 256;
|
||||||
|
color_type = PNG_COLOR_TYPE_PALETTE;
|
||||||
|
break;
|
||||||
|
case 0x0102:/* YUV ? */
|
||||||
|
case 0x0103:
|
||||||
|
default:
|
||||||
|
/* unsupported format */
|
||||||
|
png_destroy_write_struct(&png_ptr, &info_ptr);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (color_type) {
|
||||||
|
case PNG_COLOR_TYPE_RGB_ALPHA:
|
||||||
|
case PNG_COLOR_TYPE_RGB:
|
||||||
|
//row_bytes = (bit_depth * width) >> 1;
|
||||||
|
row_bytes = rowStride;
|
||||||
|
png_set_bgr(png_ptr);
|
||||||
|
png_set_sBIT(png_ptr, info_ptr, &sig_bit);
|
||||||
|
break;
|
||||||
|
case PNG_COLOR_TYPE_PALETTE:
|
||||||
|
//row_bytes = (bit_depth * width) >> 3;
|
||||||
|
row_bytes = rowStride;
|
||||||
|
png_set_PLTE(png_ptr, info_ptr, palette_ptr, num_palette);
|
||||||
|
png_set_tRNS(png_ptr, info_ptr, trans_ptr, num_palette, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
//png_set_filter(png_ptr, 0, PNG_ALL_FILTERS);
|
||||||
|
|
||||||
|
//if (bit_depth == 16)
|
||||||
|
// png_set_swap(png_ptr);
|
||||||
|
|
||||||
|
//if (bit_depth < 8)
|
||||||
|
// png_set_packswap(png_ptr);
|
||||||
|
|
||||||
|
png_set_IHDR(png_ptr, info_ptr, width, height,
|
||||||
|
bit_depth, color_type, PNG_INTERLACE_NONE,
|
||||||
|
PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
|
||||||
|
|
||||||
|
//png_set_gAMA(png_ptr, info_ptr, 1.0);
|
||||||
|
|
||||||
|
png_write_info(png_ptr, info_ptr);
|
||||||
|
for (i = 0; i < height; i++) {
|
||||||
|
png_write_row(png_ptr, (png_bytep)src);
|
||||||
|
src += row_bytes;
|
||||||
|
}
|
||||||
|
png_write_end(png_ptr, info_ptr);
|
||||||
|
|
||||||
|
png_destroy_write_struct(&png_ptr, &info_ptr);
|
||||||
|
|
||||||
|
//if (tex_ptr) delete [] tex_ptr;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean
|
||||||
|
TxImage::getBMPInfo(FILE* fp, BITMAPFILEHEADER* bmp_fhdr, BITMAPINFOHEADER* bmp_ihdr)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* read in BITMAPFILEHEADER
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* is this a BMP file? */
|
||||||
|
if (fread(&bmp_fhdr->bfType, 2, 1, fp) != 1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (memcmp(&bmp_fhdr->bfType, "BM", 2) != 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* get file size */
|
||||||
|
if (fread(&bmp_fhdr->bfSize, 4, 1, fp) != 1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* reserved 1 */
|
||||||
|
if (fread(&bmp_fhdr->bfReserved1, 2, 1, fp) != 1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* reserved 2 */
|
||||||
|
if (fread(&bmp_fhdr->bfReserved2, 2, 1, fp) != 1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* offset to the image data */
|
||||||
|
if (fread(&bmp_fhdr->bfOffBits, 4, 1, fp) != 1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* read in BITMAPINFOHEADER
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* size of BITMAPINFOHEADER */
|
||||||
|
if (fread(&bmp_ihdr->biSize, 4, 1, fp) != 1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* is this a Windows BMP? */
|
||||||
|
if (bmp_ihdr->biSize != 40)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* width of the bitmap in pixels */
|
||||||
|
if (fread(&bmp_ihdr->biWidth, 4, 1, fp) != 1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* height of the bitmap in pixels */
|
||||||
|
if (fread(&bmp_ihdr->biHeight, 4, 1, fp) != 1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* number of planes (always 1) */
|
||||||
|
if (fread(&bmp_ihdr->biPlanes, 2, 1, fp) != 1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* number of bits-per-pixel. (1, 4, 8, 16, 24, 32) */
|
||||||
|
if (fread(&bmp_ihdr->biBitCount, 2, 1, fp) != 1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* compression for a compressed bottom-up bitmap
|
||||||
|
* 0 : uncompressed format
|
||||||
|
* 1 : run-length encoded 4 bpp format
|
||||||
|
* 2 : run-length encoded 8 bpp format
|
||||||
|
* 3 : bitfield
|
||||||
|
*/
|
||||||
|
if (fread(&bmp_ihdr->biCompression, 4, 1, fp) != 1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* size of the image in bytes */
|
||||||
|
if (fread(&bmp_ihdr->biSizeImage, 4, 1, fp) != 1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* horizontal resolution in pixels-per-meter */
|
||||||
|
if (fread(&bmp_ihdr->biXPelsPerMeter, 4, 1, fp) != 1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* vertical resolution in pixels-per-meter */
|
||||||
|
if (fread(&bmp_ihdr->biYPelsPerMeter, 4, 1, fp) != 1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* number of color indexes in the color table that are actually used */
|
||||||
|
if (fread(&bmp_ihdr->biClrUsed, 4, 1, fp) != 1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* the number of color indexes that are required for displaying */
|
||||||
|
if (fread(&bmp_ihdr->biClrImportant, 4, 1, fp) != 1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8*
|
||||||
|
TxImage::readBMP(FILE* fp, int* width, int* height, uint16* format)
|
||||||
|
{
|
||||||
|
/* NOTE: returned image format;
|
||||||
|
* 4, 8bit palette bmp -> GR_TEXFMT_P_8
|
||||||
|
* 24, 32bit bmp -> GR_TEXFMT_ARGB_8888
|
||||||
|
*/
|
||||||
|
|
||||||
|
uint8 *image = NULL;
|
||||||
|
uint8 *image_row = NULL;
|
||||||
|
uint8 *tmpimage = NULL;
|
||||||
|
int row_bytes, pos, i, j;
|
||||||
|
/* Windows Bitmap */
|
||||||
|
BITMAPFILEHEADER bmp_fhdr;
|
||||||
|
BITMAPINFOHEADER bmp_ihdr;
|
||||||
|
|
||||||
|
/* initialize */
|
||||||
|
*width = 0;
|
||||||
|
*height = 0;
|
||||||
|
*format = 0;
|
||||||
|
|
||||||
|
/* check if we have a valid bmp file */
|
||||||
|
if (!fp)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (!getBMPInfo(fp, &bmp_fhdr, &bmp_ihdr)) {
|
||||||
|
INFO(80, L"error reading bitmap file! bitmap image is corrupt.\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
DBG_INFO(80, L"bmp format %d x %d bitdepth:%d compression:%x offset:%d\n",
|
||||||
|
bmp_ihdr.biWidth, bmp_ihdr.biHeight, bmp_ihdr.biBitCount,
|
||||||
|
bmp_ihdr.biCompression, bmp_fhdr.bfOffBits);
|
||||||
|
|
||||||
|
/* rowStride in bytes */
|
||||||
|
row_bytes = (bmp_ihdr.biWidth * bmp_ihdr.biBitCount) >> 3;
|
||||||
|
/* align to 4bytes boundary */
|
||||||
|
row_bytes = (row_bytes + 3) & ~3;
|
||||||
|
|
||||||
|
/* Rice hi-res textures */
|
||||||
|
if (!(bmp_ihdr.biBitCount == 8 || bmp_ihdr.biBitCount == 4 || bmp_ihdr.biBitCount == 32 || bmp_ihdr.biBitCount == 24) ||
|
||||||
|
bmp_ihdr.biCompression != 0) {
|
||||||
|
DBG_INFO(80, L"Error: incompatible bitmap format!\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (bmp_ihdr.biBitCount) {
|
||||||
|
case 8:
|
||||||
|
case 32:
|
||||||
|
/* 8 bit, 32 bit bitmap */
|
||||||
|
image = (uint8*)malloc(row_bytes * bmp_ihdr.biHeight);
|
||||||
|
if (image) {
|
||||||
|
tmpimage = image;
|
||||||
|
pos = bmp_fhdr.bfOffBits + row_bytes * (bmp_ihdr.biHeight - 1);
|
||||||
|
for (i = 0; i < bmp_ihdr.biHeight; i++) {
|
||||||
|
/* read in image */
|
||||||
|
fseek(fp, pos, SEEK_SET);
|
||||||
|
fread(tmpimage, row_bytes, 1, fp);
|
||||||
|
tmpimage += row_bytes;
|
||||||
|
pos -= row_bytes;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
/* 4bit bitmap */
|
||||||
|
image = (uint8*)malloc((row_bytes * bmp_ihdr.biHeight) << 1);
|
||||||
|
image_row = (uint8*)malloc(row_bytes);
|
||||||
|
if (image && image_row) {
|
||||||
|
tmpimage = image;
|
||||||
|
pos = bmp_fhdr.bfOffBits + row_bytes * (bmp_ihdr.biHeight - 1);
|
||||||
|
for (i = 0; i < bmp_ihdr.biHeight; i++) {
|
||||||
|
/* read in image */
|
||||||
|
fseek(fp, pos, SEEK_SET);
|
||||||
|
fread(image_row, row_bytes, 1, fp);
|
||||||
|
/* expand 4bpp to 8bpp. stuff 4bit values into 8bit comps. */
|
||||||
|
for (j = 0; j < row_bytes; j++) {
|
||||||
|
tmpimage[j << 1] = image_row[j] & 0x0f;
|
||||||
|
tmpimage[(j << 1) + 1] = (image_row[j] & 0xf0) >> 4;
|
||||||
|
}
|
||||||
|
tmpimage += (row_bytes << 1);
|
||||||
|
pos -= row_bytes;
|
||||||
|
}
|
||||||
|
free(image_row);
|
||||||
|
} else {
|
||||||
|
if (image_row) free(image_row);
|
||||||
|
if (image) free(image);
|
||||||
|
image = NULL;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 24:
|
||||||
|
/* 24 bit bitmap */
|
||||||
|
image = (uint8*)malloc((bmp_ihdr.biWidth * bmp_ihdr.biHeight) << 2);
|
||||||
|
image_row = (uint8*)malloc(row_bytes);
|
||||||
|
if (image && image_row) {
|
||||||
|
tmpimage = image;
|
||||||
|
pos = bmp_fhdr.bfOffBits + row_bytes * (bmp_ihdr.biHeight - 1);
|
||||||
|
for (i = 0; i < bmp_ihdr.biHeight; i++) {
|
||||||
|
/* read in image */
|
||||||
|
fseek(fp, pos, SEEK_SET);
|
||||||
|
fread(image_row, row_bytes, 1, fp);
|
||||||
|
/* convert 24bpp to 32bpp. */
|
||||||
|
for (j = 0; j < bmp_ihdr.biWidth; j++) {
|
||||||
|
tmpimage[(j << 2)] = image_row[j * 3];
|
||||||
|
tmpimage[(j << 2) + 1] = image_row[j * 3 + 1];
|
||||||
|
tmpimage[(j << 2) + 2] = image_row[j * 3 + 2];
|
||||||
|
tmpimage[(j << 2) + 3] = 0xFF;
|
||||||
|
}
|
||||||
|
tmpimage += (bmp_ihdr.biWidth << 2);
|
||||||
|
pos -= row_bytes;
|
||||||
|
}
|
||||||
|
free(image_row);
|
||||||
|
} else {
|
||||||
|
if (image_row) free(image_row);
|
||||||
|
if (image) free(image);
|
||||||
|
image = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (image) {
|
||||||
|
*width = (row_bytes << 3) / bmp_ihdr.biBitCount;
|
||||||
|
*height = bmp_ihdr.biHeight;
|
||||||
|
|
||||||
|
switch (bmp_ihdr.biBitCount) {
|
||||||
|
case 8:
|
||||||
|
case 4:
|
||||||
|
*format = GR_TEXFMT_P_8;
|
||||||
|
break;
|
||||||
|
case 32:
|
||||||
|
case 24:
|
||||||
|
*format = GR_TEXFMT_ARGB_8888;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if POW2_TEXTURES
|
||||||
|
/* next power of 2 size conversions */
|
||||||
|
/* NOTE: I can do this in the above loop for faster operations, but some
|
||||||
|
* texture packs require a workaround. see HACKALERT in nextPow2().
|
||||||
|
*/
|
||||||
|
|
||||||
|
TxReSample txReSample = new TxReSample; // XXX: temporary. move to a better place.
|
||||||
|
|
||||||
|
#if (POW2_TEXTURES == 2)
|
||||||
|
if (!txReSample->nextPow2(&image, width, height, 8, 1)) {
|
||||||
|
#else
|
||||||
|
if (!txReSample->nextPow2(&image, width, height, 8, 0)) {
|
||||||
|
#endif
|
||||||
|
if (image) {
|
||||||
|
free(image);
|
||||||
|
image = NULL;
|
||||||
|
}
|
||||||
|
*width = 0;
|
||||||
|
*height = 0;
|
||||||
|
*format = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
delete txReSample;
|
||||||
|
|
||||||
|
#endif /* POW2_TEXTURES */
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
if (!image) {
|
||||||
|
DBG_INFO(80, L"Error: failed to load bmp image!\n");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return image;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean
|
||||||
|
TxImage::getDDSInfo(FILE *fp, DDSFILEHEADER *dds_fhdr)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* read in DDSFILEHEADER
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* is this a DDS file? */
|
||||||
|
if (fread(&dds_fhdr->dwMagic, 4, 1, fp) != 1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (memcmp(&dds_fhdr->dwMagic, "DDS ", 4) != 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (fread(&dds_fhdr->dwSize, 4, 1, fp) != 1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* get file flags */
|
||||||
|
if (fread(&dds_fhdr->dwFlags, 4, 1, fp) != 1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* height of dds in pixels */
|
||||||
|
if (fread(&dds_fhdr->dwHeight, 4, 1, fp) != 1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* width of dds in pixels */
|
||||||
|
if (fread(&dds_fhdr->dwWidth, 4, 1, fp) != 1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (fread(&dds_fhdr->dwLinearSize, 4, 1, fp) != 1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (fread(&dds_fhdr->dwDepth, 4, 1, fp) != 1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (fread(&dds_fhdr->dwMipMapCount, 4, 1, fp) != 1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (fread(&dds_fhdr->dwReserved1, 4 * 11, 1, fp) != 1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (fread(&dds_fhdr->ddpf.dwSize, 4, 1, fp) != 1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (fread(&dds_fhdr->ddpf.dwFlags, 4, 1, fp) != 1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (fread(&dds_fhdr->ddpf.dwFourCC, 4, 1, fp) != 1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (fread(&dds_fhdr->ddpf.dwRGBBitCount, 4, 1, fp) != 1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (fread(&dds_fhdr->ddpf.dwRBitMask, 4, 1, fp) != 1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (fread(&dds_fhdr->ddpf.dwGBitMask, 4, 1, fp) != 1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (fread(&dds_fhdr->ddpf.dwBBitMask, 4, 1, fp) != 1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (fread(&dds_fhdr->ddpf.dwRGBAlphaBitMask, 4, 1, fp) != 1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (fread(&dds_fhdr->dwCaps1, 4, 1, fp) != 1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (fread(&dds_fhdr->dwCaps2, 4, 1, fp) != 1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8*
|
||||||
|
TxImage::readDDS(FILE* fp, int* width, int* height, uint16* format)
|
||||||
|
{
|
||||||
|
uint8 *image = NULL;
|
||||||
|
DDSFILEHEADER dds_fhdr;
|
||||||
|
uint16 tmpformat = 0;
|
||||||
|
|
||||||
|
/* initialize */
|
||||||
|
*width = 0;
|
||||||
|
*height = 0;
|
||||||
|
*format = 0;
|
||||||
|
|
||||||
|
/* check if we have a valid dds file */
|
||||||
|
if (!fp)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (!getDDSInfo(fp, &dds_fhdr)) {
|
||||||
|
INFO(80, L"error reading dds file! dds image is corrupt.\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
DBG_INFO(80, L"dds format %d x %d HeaderSize %d LinearSize %d\n",
|
||||||
|
dds_fhdr.dwWidth, dds_fhdr.dwHeight, dds_fhdr.dwSize, dds_fhdr.dwLinearSize);
|
||||||
|
|
||||||
|
if (!(dds_fhdr.dwFlags & (DDSD_CAPS|DDSD_WIDTH|DDSD_HEIGHT|DDSD_PIXELFORMAT|DDSD_LINEARSIZE))) {
|
||||||
|
DBG_INFO(80, L"Error: incompatible dds format!\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((dds_fhdr.dwFlags & DDSD_MIPMAPCOUNT) && dds_fhdr.dwMipMapCount != 1) {
|
||||||
|
DBG_INFO(80, L"Error: mipmapped dds not supported!\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!((dds_fhdr.ddpf.dwFlags & DDPF_FOURCC) && dds_fhdr.dwCaps2 == 0)) {
|
||||||
|
DBG_INFO(80, L"Error: not fourcc standard texture!\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (memcmp(&dds_fhdr.ddpf.dwFourCC, "DXT1", 4) == 0) {
|
||||||
|
DBG_INFO(80, L"DXT1 format\n");
|
||||||
|
/* compensate for missing LinearSize */
|
||||||
|
dds_fhdr.dwLinearSize = (dds_fhdr.dwWidth * dds_fhdr.dwHeight) >> 1;
|
||||||
|
tmpformat = GR_TEXFMT_ARGB_CMP_DXT1;
|
||||||
|
} else if (memcmp(&dds_fhdr.ddpf.dwFourCC, "DXT3", 4) == 0) {
|
||||||
|
DBG_INFO(80, L"DXT3 format\n");
|
||||||
|
dds_fhdr.dwLinearSize = dds_fhdr.dwWidth * dds_fhdr.dwHeight;
|
||||||
|
tmpformat = GR_TEXFMT_ARGB_CMP_DXT3;
|
||||||
|
} else if (memcmp(&dds_fhdr.ddpf.dwFourCC, "DXT5", 4) == 0) {
|
||||||
|
DBG_INFO(80, L"DXT5 format\n");
|
||||||
|
dds_fhdr.dwLinearSize = dds_fhdr.dwWidth * dds_fhdr.dwHeight;
|
||||||
|
tmpformat = GR_TEXFMT_ARGB_CMP_DXT5;
|
||||||
|
} else {
|
||||||
|
DBG_INFO(80, L"Error: not DXT1 or DXT3 or DXT5 format!\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* read in image */
|
||||||
|
image = (uint8*)malloc(dds_fhdr.dwLinearSize);
|
||||||
|
if (image) {
|
||||||
|
*width = dds_fhdr.dwWidth;
|
||||||
|
*height = dds_fhdr.dwHeight;
|
||||||
|
*format = tmpformat;
|
||||||
|
|
||||||
|
fseek(fp, 128, SEEK_SET); /* size of header is 128 bytes */
|
||||||
|
fread(image, dds_fhdr.dwLinearSize, 1, fp);
|
||||||
|
}
|
||||||
|
|
||||||
|
return image;
|
||||||
|
}
|
116
GLideNHQ/TxImage.h
Normal file
116
GLideNHQ/TxImage.h
Normal file
|
@ -0,0 +1,116 @@
|
||||||
|
/*
|
||||||
|
* Texture Filtering
|
||||||
|
* Version: 1.0
|
||||||
|
*
|
||||||
|
* Copyright (C) 2007 Hiroshi Morii All Rights Reserved.
|
||||||
|
* Email koolsmoky(at)users.sourceforge.net
|
||||||
|
* Web http://www.3dfxzone.it/koolsmoky
|
||||||
|
*
|
||||||
|
* this 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, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* this 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 GNU Make; see the file COPYING. If not, write to
|
||||||
|
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __TXIMAGE_H__
|
||||||
|
#define __TXIMAGE_H__
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <png.h>
|
||||||
|
#include "TxInternal.h"
|
||||||
|
|
||||||
|
#ifndef WIN32
|
||||||
|
typedef struct tagBITMAPFILEHEADER {
|
||||||
|
unsigned short bfType;
|
||||||
|
unsigned long bfSize;
|
||||||
|
unsigned short bfReserved1;
|
||||||
|
unsigned short bfReserved2;
|
||||||
|
unsigned long bfOffBits;
|
||||||
|
} BITMAPFILEHEADER;
|
||||||
|
|
||||||
|
typedef struct tagBITMAPINFOHEADER {
|
||||||
|
unsigned long biSize;
|
||||||
|
long biWidth;
|
||||||
|
long biHeight;
|
||||||
|
unsigned short biPlanes;
|
||||||
|
unsigned short biBitCount;
|
||||||
|
unsigned long biCompression;
|
||||||
|
unsigned long biSizeImage;
|
||||||
|
long biXPelsPerMeter;
|
||||||
|
long biYPelsPerMeter;
|
||||||
|
unsigned long biClrUsed;
|
||||||
|
unsigned long biClrImportant;
|
||||||
|
} BITMAPINFOHEADER;
|
||||||
|
#else
|
||||||
|
typedef struct tagBITMAPFILEHEADER BITMAPFILEHEADER;
|
||||||
|
typedef struct tagBITMAPINFOHEADER BITMAPINFOHEADER;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define DDSD_CAPS 0x00000001
|
||||||
|
#define DDSD_HEIGHT 0x00000002
|
||||||
|
#define DDSD_WIDTH 0x00000004
|
||||||
|
#define DDSD_PITCH 0x00000008
|
||||||
|
#define DDSD_PIXELFORMAT 0x00001000
|
||||||
|
#define DDSD_MIPMAPCOUNT 0x00020000
|
||||||
|
#define DDSD_LINEARSIZE 0x00080000
|
||||||
|
#define DDSD_DEPTH 0x00800000
|
||||||
|
|
||||||
|
#define DDPF_ALPHAPIXELS 0x00000001
|
||||||
|
#define DDPF_FOURCC 0x00000004
|
||||||
|
#define DDPF_RGB 0x00000040
|
||||||
|
|
||||||
|
#define DDSCAPS_COMPLEX 0x00000008
|
||||||
|
#define DDSCAPS_TEXTURE 0x00001000
|
||||||
|
#define DDSCAPS_MIPMAP 0x00400000
|
||||||
|
|
||||||
|
typedef struct tagDDSPIXELFORMAT {
|
||||||
|
unsigned long dwSize;
|
||||||
|
unsigned long dwFlags;
|
||||||
|
unsigned long dwFourCC;
|
||||||
|
unsigned long dwRGBBitCount;
|
||||||
|
unsigned long dwRBitMask;
|
||||||
|
unsigned long dwGBitMask;
|
||||||
|
unsigned long dwBBitMask;
|
||||||
|
unsigned long dwRGBAlphaBitMask;
|
||||||
|
} DDSPIXELFORMAT;
|
||||||
|
|
||||||
|
typedef struct tagDDSFILEHEADER {
|
||||||
|
unsigned long dwMagic;
|
||||||
|
unsigned long dwSize;
|
||||||
|
unsigned long dwFlags;
|
||||||
|
unsigned long dwHeight;
|
||||||
|
unsigned long dwWidth;
|
||||||
|
unsigned long dwLinearSize;
|
||||||
|
unsigned long dwDepth;
|
||||||
|
unsigned long dwMipMapCount;
|
||||||
|
unsigned long dwReserved1[11];
|
||||||
|
DDSPIXELFORMAT ddpf;
|
||||||
|
unsigned long dwCaps1;
|
||||||
|
unsigned long dwCaps2;
|
||||||
|
} DDSFILEHEADER;
|
||||||
|
|
||||||
|
class TxImage
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
boolean getPNGInfo(FILE *fp, png_structp *png_ptr, png_infop *info_ptr);
|
||||||
|
boolean getBMPInfo(FILE *fp, BITMAPFILEHEADER *bmp_fhdr, BITMAPINFOHEADER *bmp_ihdr);
|
||||||
|
boolean getDDSInfo(FILE *fp, DDSFILEHEADER *dds_fhdr);
|
||||||
|
public:
|
||||||
|
TxImage() {}
|
||||||
|
~TxImage() {}
|
||||||
|
uint8* readPNG(FILE* fp, int* width, int* height, uint16* format);
|
||||||
|
boolean writePNG(uint8* src, FILE* fp, int width, int height, int rowStride, uint16 format, uint8 *palette);
|
||||||
|
uint8* readBMP(FILE* fp, int* width, int* height, uint16* format);
|
||||||
|
uint8* readDDS(FILE* fp, int* width, int* height, uint16* format);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* __TXIMAGE_H__ */
|
100
GLideNHQ/TxInternal.h
Normal file
100
GLideNHQ/TxInternal.h
Normal file
|
@ -0,0 +1,100 @@
|
||||||
|
/*
|
||||||
|
* Texture Filtering
|
||||||
|
* Version: 1.0
|
||||||
|
*
|
||||||
|
* Copyright (C) 2007 Hiroshi Morii All Rights Reserved.
|
||||||
|
* Email koolsmoky(at)users.sourceforge.net
|
||||||
|
* Web http://www.3dfxzone.it/koolsmoky
|
||||||
|
*
|
||||||
|
* this 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, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* this 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 GNU Make; see the file COPYING. If not, write to
|
||||||
|
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __INTERNAL_H__
|
||||||
|
#define __INTERNAL_H__
|
||||||
|
|
||||||
|
#include "Ext_TxFilter.h"
|
||||||
|
|
||||||
|
/* dll exports */
|
||||||
|
#ifdef TXFILTER_DLL
|
||||||
|
#define TAPI __declspec(dllexport)
|
||||||
|
#define TAPIENTRY
|
||||||
|
#else
|
||||||
|
#define TAPI
|
||||||
|
#define TAPIENTRY
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef unsigned char uint8;
|
||||||
|
typedef unsigned short uint16;
|
||||||
|
typedef unsigned long uint32;
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
#define KBHIT(key) ((GetAsyncKeyState(key) & 0x8001) == 0x8001)
|
||||||
|
#else
|
||||||
|
#define KBHIT(key) (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* from OpenGL glext.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
|
||||||
|
|
||||||
|
/* for explicit fxt1 compression */
|
||||||
|
#define CC_CHROMA 0x0
|
||||||
|
#define CC_HI 0x1
|
||||||
|
#define CC_ALPHA 0x2
|
||||||
|
|
||||||
|
/* in-memory zlib texture compression */
|
||||||
|
#define GR_TEXFMT_GZ 0x8000
|
||||||
|
|
||||||
|
#if 0 /* this is here to remind me of other formats */
|
||||||
|
/* from 3Dfx Interactive Inc. glide.h */
|
||||||
|
#define GR_TEXFMT_8BIT 0x0
|
||||||
|
#define GR_TEXFMT_RGB_332 GR_TEXFMT_8BIT
|
||||||
|
#define GR_TEXFMT_YIQ_422 0x1
|
||||||
|
#define GR_TEXFMT_ALPHA_8 0x2 /* (0..0xFF) alpha */
|
||||||
|
#define GR_TEXFMT_INTENSITY_8 0x3 /* (0..0xFF) intensity */
|
||||||
|
#define GR_TEXFMT_ALPHA_INTENSITY_44 0x4
|
||||||
|
#define GR_TEXFMT_P_8 0x5 /* 8-bit palette */
|
||||||
|
#define GR_TEXFMT_RSVD0 0x6 /* GR_TEXFMT_P_8_RGBA */
|
||||||
|
#define GR_TEXFMT_P_8_6666 GR_TEXFMT_RSVD0
|
||||||
|
#define GR_TEXFMT_P_8_6666_EXT GR_TEXFMT_RSVD0
|
||||||
|
#define GR_TEXFMT_RSVD1 0x7
|
||||||
|
#define GR_TEXFMT_16BIT 0x8
|
||||||
|
#define GR_TEXFMT_ARGB_8332 GR_TEXFMT_16BIT
|
||||||
|
#define GR_TEXFMT_AYIQ_8422 0x9
|
||||||
|
#define GR_TEXFMT_RGB_565 0xa
|
||||||
|
#define GR_TEXFMT_ARGB_1555 0xb
|
||||||
|
#define GR_TEXFMT_ARGB_4444 0xc
|
||||||
|
#define GR_TEXFMT_ALPHA_INTENSITY_88 0xd
|
||||||
|
#define GR_TEXFMT_AP_88 0xe /* 8-bit alpha 8-bit palette */
|
||||||
|
#define GR_TEXFMT_RSVD2 0xf
|
||||||
|
#define GR_TEXFMT_RSVD4 GR_TEXFMT_RSVD2
|
||||||
|
|
||||||
|
/* from 3Dfx Interactive Inc. g3ext.h */
|
||||||
|
#define GR_TEXFMT_ARGB_CMP_FXT1 0x11
|
||||||
|
#define GR_TEXFMT_ARGB_8888 0x12
|
||||||
|
#define GR_TEXFMT_YUYV_422 0x13
|
||||||
|
#define GR_TEXFMT_UYVY_422 0x14
|
||||||
|
#define GR_TEXFMT_AYUV_444 0x15
|
||||||
|
#define GR_TEXFMT_ARGB_CMP_DXT1 0x16
|
||||||
|
#define GR_TEXFMT_ARGB_CMP_DXT2 0x17
|
||||||
|
#define GR_TEXFMT_ARGB_CMP_DXT3 0x18
|
||||||
|
#define GR_TEXFMT_ARGB_CMP_DXT4 0x19
|
||||||
|
#define GR_TEXFMT_ARGB_CMP_DXT5 0x1A
|
||||||
|
#define GR_TEXTFMT_RGB_888 0xFF
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __INTERNAL_H__ */
|
2394
GLideNHQ/TxQuantize.cpp
Normal file
2394
GLideNHQ/TxQuantize.cpp
Normal file
File diff suppressed because it is too large
Load Diff
99
GLideNHQ/TxQuantize.h
Normal file
99
GLideNHQ/TxQuantize.h
Normal file
|
@ -0,0 +1,99 @@
|
||||||
|
/*
|
||||||
|
* Texture Filtering
|
||||||
|
* Version: 1.0
|
||||||
|
*
|
||||||
|
* Copyright (C) 2007 Hiroshi Morii All Rights Reserved.
|
||||||
|
* Email koolsmoky(at)users.sourceforge.net
|
||||||
|
* Web http://www.3dfxzone.it/koolsmoky
|
||||||
|
*
|
||||||
|
* this 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, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* this 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 GNU Make; see the file COPYING. If not, write to
|
||||||
|
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __TXQUANTIZE_H__
|
||||||
|
#define __TXQUANTIZE_H__
|
||||||
|
|
||||||
|
/* Glide64 DXTn workaround
|
||||||
|
* (0:disable, 1:enable) */
|
||||||
|
#define GLIDE64_DXTN 1
|
||||||
|
|
||||||
|
#include "TxInternal.h"
|
||||||
|
#include "TxUtil.h"
|
||||||
|
|
||||||
|
class TxQuantize
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
TxUtil *_txUtil;
|
||||||
|
int _numcore;
|
||||||
|
|
||||||
|
fxtCompressTexFuncExt _tx_compress_fxt1;
|
||||||
|
dxtCompressTexFuncExt _tx_compress_dxtn;
|
||||||
|
|
||||||
|
/* fast optimized... well, sort of. */
|
||||||
|
void ARGB1555_ARGB8888(uint32* src, uint32* dst, int width, int height);
|
||||||
|
void ARGB4444_ARGB8888(uint32* src, uint32* dst, int width, int height);
|
||||||
|
void RGB565_ARGB8888(uint32* src, uint32* dst, int width, int height);
|
||||||
|
void A8_ARGB8888(uint32* src, uint32* dst, int width, int height);
|
||||||
|
void AI44_ARGB8888(uint32* src, uint32* dst, int width, int height);
|
||||||
|
void AI88_ARGB8888(uint32* src, uint32* dst, int width, int height);
|
||||||
|
|
||||||
|
void ARGB8888_ARGB1555(uint32* src, uint32* dst, int width, int height);
|
||||||
|
void ARGB8888_ARGB4444(uint32* src, uint32* dst, int width, int height);
|
||||||
|
void ARGB8888_RGB565(uint32* src, uint32* dst, int width, int height);
|
||||||
|
void ARGB8888_A8(uint32* src, uint32* dst, int width, int height);
|
||||||
|
void ARGB8888_AI44(uint32* src, uint32* dst, int width, int height);
|
||||||
|
void ARGB8888_AI88(uint32* src, uint32* dst, int width, int height);
|
||||||
|
|
||||||
|
/* quality */
|
||||||
|
void ARGB8888_RGB565_ErrD(uint32* src, uint32* dst, int width, int height);
|
||||||
|
void ARGB8888_ARGB1555_ErrD(uint32* src, uint32* dst, int width, int height);
|
||||||
|
void ARGB8888_ARGB4444_ErrD(uint32* src, uint32* dst, int width, int height);
|
||||||
|
void ARGB8888_AI44_ErrD(uint32* src, uint32* dst, int width, int height);
|
||||||
|
void ARGB8888_AI88_Slow(uint32* src, uint32* dst, int width, int height);
|
||||||
|
void ARGB8888_I8_Slow(uint32* src, uint32* dst, int width, int height);
|
||||||
|
|
||||||
|
/* compressors */
|
||||||
|
boolean FXT1(uint8 *src, uint8 *dest,
|
||||||
|
int srcwidth, int srcheight, uint16 srcformat,
|
||||||
|
int *destwidth, int *destheight, uint16 *destformat);
|
||||||
|
boolean DXTn(uint8 *src, uint8 *dest,
|
||||||
|
int srcwidth, int srcheight, uint16 srcformat,
|
||||||
|
int *destwidth, int *destheight, uint16 *destformat);
|
||||||
|
|
||||||
|
public:
|
||||||
|
TxQuantize();
|
||||||
|
~TxQuantize();
|
||||||
|
|
||||||
|
/* others */
|
||||||
|
void P8_16BPP(uint32* src, uint32* dst, int width, int height, uint32* palette);
|
||||||
|
|
||||||
|
boolean quantize(uint8* src, uint8* dest, int width, int height, uint16 srcformat, uint16 destformat, boolean fastQuantizer = 1);
|
||||||
|
|
||||||
|
boolean compress(uint8 *src, uint8 *dest,
|
||||||
|
int srcwidth, int srcheight, uint16 srcformat,
|
||||||
|
int *destwidth, int *destheight, uint16 *destformat,
|
||||||
|
int compressionType);
|
||||||
|
|
||||||
|
|
||||||
|
#if 0 /* unused */
|
||||||
|
void ARGB8888_I8(uint32* src, uint32* dst, int width, int height);
|
||||||
|
void I8_ARGB8888(uint32* src, uint32* dst, int width, int height);
|
||||||
|
|
||||||
|
void ARGB1555_ABGR8888(uint32* src, uint32* dst, int width, int height);
|
||||||
|
void ARGB4444_ABGR8888(uint32* src, uint32* dst, int width, int height);
|
||||||
|
void ARGB8888_ABGR8888(uint32* src, uint32* dst, int width, int height);
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* __TXQUANTIZE_H__ */
|
417
GLideNHQ/TxReSample.cpp
Normal file
417
GLideNHQ/TxReSample.cpp
Normal file
|
@ -0,0 +1,417 @@
|
||||||
|
/*
|
||||||
|
* Texture Filtering
|
||||||
|
* Version: 1.0
|
||||||
|
*
|
||||||
|
* Copyright (C) 2007 Hiroshi Morii All Rights Reserved.
|
||||||
|
* Email koolsmoky(at)users.sourceforge.net
|
||||||
|
* Web http://www.3dfxzone.it/koolsmoky
|
||||||
|
*
|
||||||
|
* this 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, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* this 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 GNU Make; see the file COPYING. If not, write to
|
||||||
|
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "TxReSample.h"
|
||||||
|
#include "TxDbg.h"
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <memory.h>
|
||||||
|
|
||||||
|
#define _USE_MATH_DEFINES
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
#ifndef M_PI
|
||||||
|
#define M_PI 3.14159265358979323846
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int
|
||||||
|
TxReSample::nextPow2(int num)
|
||||||
|
{
|
||||||
|
num = num - 1;
|
||||||
|
num = num | (num >> 1);
|
||||||
|
num = num | (num >> 2);
|
||||||
|
num = num | (num >> 4);
|
||||||
|
num = num | (num >> 8);
|
||||||
|
num = num | (num >> 16);
|
||||||
|
/*num = num | (num >> 32);*//* for 64bit architecture */
|
||||||
|
num = num + 1;
|
||||||
|
|
||||||
|
return num;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean
|
||||||
|
TxReSample::nextPow2(uint8** image, int* width, int* height, int bpp, boolean use_3dfx = 0)
|
||||||
|
{
|
||||||
|
/* NOTE: bpp must be one of the follwing: 8, 16, 24, 32 bits per pixel */
|
||||||
|
|
||||||
|
if (!*image || !*width || !*height || !bpp)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
int row_bytes = ((*width * bpp) >> 3);
|
||||||
|
int o_row_bytes = row_bytes;
|
||||||
|
int o_width = *width;
|
||||||
|
int n_width = *width;
|
||||||
|
int o_height = *height;
|
||||||
|
int n_height = *height;
|
||||||
|
|
||||||
|
/* HACKALERT: I have explicitly subtracted (n) from width/height to
|
||||||
|
* adjust textures that have (n) pixel larger width/height than
|
||||||
|
* power of 2 size. This is a dirty hack for textures that have
|
||||||
|
* munged aspect ratio by (n) pixel to the original.
|
||||||
|
*/
|
||||||
|
if (n_width > 64) n_width -= 4;
|
||||||
|
else if (n_width > 16) n_width -= 2;
|
||||||
|
else if (n_width > 4) n_width -= 1;
|
||||||
|
|
||||||
|
if (n_height > 64) n_height -= 4;
|
||||||
|
else if (n_height > 16) n_height -= 2;
|
||||||
|
else if (n_height > 4) n_height -= 1;
|
||||||
|
|
||||||
|
n_width = nextPow2(n_width);
|
||||||
|
n_height = nextPow2(n_height);
|
||||||
|
row_bytes = (n_width * bpp) >> 3;
|
||||||
|
|
||||||
|
/* 3dfx Glide3 format, W:H aspect ratio range (8:1 - 1:8) */
|
||||||
|
if (use_3dfx) {
|
||||||
|
if (n_width > n_height) {
|
||||||
|
if (n_width > (n_height << 3))
|
||||||
|
n_height = n_width >> 3;
|
||||||
|
} else {
|
||||||
|
if (n_height > (n_width << 3)) {
|
||||||
|
n_width = n_height >> 3;
|
||||||
|
row_bytes = (n_width * bpp) >> 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DBG_INFO(80, L"using 3dfx W:H aspect ratio range (8:1 - 1:8).\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* do we really need to do this ? */
|
||||||
|
if (o_width == n_width && o_height == n_height)
|
||||||
|
return 1; /* nope */
|
||||||
|
|
||||||
|
DBG_INFO(80, L"expand image to next power of 2 dimensions. %d x %d -> %d x %d\n",
|
||||||
|
o_width, o_height, n_width, n_height);
|
||||||
|
|
||||||
|
if (o_width > n_width)
|
||||||
|
o_width = n_width;
|
||||||
|
|
||||||
|
if (o_height > n_height)
|
||||||
|
o_height = n_height;
|
||||||
|
|
||||||
|
/* allocate memory to read in image */
|
||||||
|
uint8 *pow2image = (uint8*)malloc(row_bytes * n_height);
|
||||||
|
|
||||||
|
/* read in image */
|
||||||
|
if (pow2image) {
|
||||||
|
int i, j;
|
||||||
|
uint8 *tmpimage = *image, *tmppow2image = pow2image;
|
||||||
|
|
||||||
|
for (i = 0; i < o_height; i++) {
|
||||||
|
/* copy row */
|
||||||
|
memcpy(tmppow2image, tmpimage, ((o_width * bpp) >> 3));
|
||||||
|
|
||||||
|
/* expand to pow2 size by replication */
|
||||||
|
for(j = ((o_width * bpp) >> 3); j < row_bytes; j++)
|
||||||
|
tmppow2image[j] = tmppow2image[j - (bpp >> 3)];
|
||||||
|
|
||||||
|
tmppow2image += row_bytes;
|
||||||
|
tmpimage += o_row_bytes;
|
||||||
|
}
|
||||||
|
/* expand to pow2 size by replication */
|
||||||
|
for (i = o_height; i < n_height; i++)
|
||||||
|
memcpy(&pow2image[row_bytes * i], &pow2image[row_bytes * (i - 1)], row_bytes);
|
||||||
|
|
||||||
|
free(*image);
|
||||||
|
|
||||||
|
*image = pow2image;
|
||||||
|
*height = n_height;
|
||||||
|
*width = n_width;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ken Turkowski
|
||||||
|
* Filters for Common Resampling Tasks
|
||||||
|
* Apple Computer 1990
|
||||||
|
*/
|
||||||
|
double
|
||||||
|
TxReSample::tent(double x)
|
||||||
|
{
|
||||||
|
if (x < 0.0) x = -x;
|
||||||
|
if (x < 1.0) return (1.0 - x);
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
double
|
||||||
|
TxReSample::gaussian(double x)
|
||||||
|
{
|
||||||
|
if (x < 0) x = -x;
|
||||||
|
if (x < 2.0) return pow(2.0, -2.0 * x * x);
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
double
|
||||||
|
TxReSample::sinc(double x)
|
||||||
|
{
|
||||||
|
if (x == 0) return 1.0;
|
||||||
|
x *= M_PI;
|
||||||
|
return (sin(x) / x);
|
||||||
|
}
|
||||||
|
|
||||||
|
double
|
||||||
|
TxReSample::lanczos3(double x)
|
||||||
|
{
|
||||||
|
if (x < 0) x = -x;
|
||||||
|
if (x < 3.0) return (sinc(x) * sinc(x/3.0));
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Don P. Mitchell and Arun N. Netravali
|
||||||
|
* Reconstruction Filters in Computer Graphics
|
||||||
|
* SIGGRAPH '88
|
||||||
|
* Proceedings of the 15th annual conference on Computer
|
||||||
|
* graphics and interactive techniques, pp221-228, 1988
|
||||||
|
*/
|
||||||
|
double
|
||||||
|
TxReSample::mitchell(double x)
|
||||||
|
{
|
||||||
|
if (x < 0) x = -x;
|
||||||
|
if (x < 2.0) {
|
||||||
|
const double B = 1.0 / 3.0;
|
||||||
|
const double C = 1.0 / 3.0;
|
||||||
|
if (x < 1.0) {
|
||||||
|
x = (((12.0 - 9.0 * B - 6.0 * C) * (x * x * x))
|
||||||
|
+ ((-18.0 + 12.0 * B + 6.0 * C) * (x * x))
|
||||||
|
+ (6.0 - 2.0 * B));
|
||||||
|
} else {
|
||||||
|
x = (((-1.0 * B - 6.0 * C) * (x * x * x))
|
||||||
|
+ ((6.0 * B + 30.0 * C) * (x * x))
|
||||||
|
+ ((-12.0 * B - 48.0 * C) * x)
|
||||||
|
+ (8.0 * B + 24.0 * C));
|
||||||
|
}
|
||||||
|
return (x / 6.0);
|
||||||
|
}
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* J. F. Kaiser and W. A. Reed
|
||||||
|
* Data smoothing using low-pass digital filters
|
||||||
|
* Rev. Sci. instrum. 48 (11), pp1447-1457, 1977
|
||||||
|
*/
|
||||||
|
double
|
||||||
|
TxReSample::besselI0(double x)
|
||||||
|
{
|
||||||
|
/* zero-order modified bessel function of the first kind */
|
||||||
|
const double eps_coeff = 1E-16; /* small enough */
|
||||||
|
double xh, sum, pow, ds;
|
||||||
|
xh = 0.5 * x;
|
||||||
|
sum = 1.0;
|
||||||
|
pow = 1.0;
|
||||||
|
ds = 1.0;
|
||||||
|
int k = 0;
|
||||||
|
while (ds > sum * eps_coeff) {
|
||||||
|
k++;
|
||||||
|
pow *= (xh / k);
|
||||||
|
ds = pow * pow;
|
||||||
|
sum = sum + ds;
|
||||||
|
}
|
||||||
|
return sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
double
|
||||||
|
TxReSample::kaiser(double x)
|
||||||
|
{
|
||||||
|
const double alpha = 4.0;
|
||||||
|
const double half_window = 5.0;
|
||||||
|
const double ratio = x / half_window;
|
||||||
|
return sinc(x) * besselI0(alpha * sqrt(1 - ratio * ratio)) / besselI0(alpha);
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean
|
||||||
|
TxReSample::minify(uint8 **src, int *width, int *height, int ratio)
|
||||||
|
{
|
||||||
|
/* NOTE: src must be ARGB8888, ratio is the inverse representation */
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
if (!*src || ratio < 2) return 0;
|
||||||
|
|
||||||
|
/* Box filtering.
|
||||||
|
* It would be nice to do Kaiser filtering.
|
||||||
|
* N64 uses narrow strip textures which makes it hard to filter effectively.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int x, y, x2, y2, offset, numtexel;
|
||||||
|
uint32 A, R, G, B, texel;
|
||||||
|
|
||||||
|
int tmpwidth = *width / ratio;
|
||||||
|
int tmpheight = *height / ratio;
|
||||||
|
|
||||||
|
uint8 *tmptex = (uint8*)malloc((tmpwidth * tmpheight) << 2);
|
||||||
|
|
||||||
|
if (tmptex) {
|
||||||
|
numtexel = ratio * ratio;
|
||||||
|
for (y = 0; y < tmpheight; y++) {
|
||||||
|
offset = ratio * y * *width;
|
||||||
|
for (x = 0; x < tmpwidth; x++) {
|
||||||
|
A = R = G = B = 0;
|
||||||
|
for (y2 = 0; y2 < ratio; y2++) {
|
||||||
|
for (x2 = 0; x2 < ratio; x2++) {
|
||||||
|
texel = ((uint32*)*src)[offset + *width * y2 + x2];
|
||||||
|
A += (texel >> 24);
|
||||||
|
R += ((texel >> 16) & 0x000000ff);
|
||||||
|
G += ((texel >> 8) & 0x000000ff);
|
||||||
|
B += (texel & 0x000000ff);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
A = (A + ratio) / numtexel;
|
||||||
|
R = (R + ratio) / numtexel;
|
||||||
|
G = (G + ratio) / numtexel;
|
||||||
|
B = (B + ratio) / numtexel;
|
||||||
|
((uint32*)tmptex)[y * tmpwidth + x] = ((A << 24) | (R << 16) | (G << 8) | B);
|
||||||
|
offset += ratio;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(*src);
|
||||||
|
*src = tmptex;
|
||||||
|
*width = tmpwidth;
|
||||||
|
*height = tmpheight;
|
||||||
|
|
||||||
|
DBG_INFO(80, L"minification ratio:%d -> %d x %d\n", ratio, *width, *height);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
DBG_INFO(80, L"Error: failed minification!\n");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
if (!*src || ratio < 2) return 0;
|
||||||
|
|
||||||
|
/* Image Resampling */
|
||||||
|
|
||||||
|
/* half width of filter window.
|
||||||
|
* NOTE: must be 1.0 or larger.
|
||||||
|
*
|
||||||
|
* kaiser-bessel 5, lanczos3 3, mitchell 2, gaussian 1.5, tent 1
|
||||||
|
*/
|
||||||
|
double half_window = 5.0;
|
||||||
|
|
||||||
|
int x, y, x2, y2, z;
|
||||||
|
double A, R, G, B;
|
||||||
|
uint32 texel;
|
||||||
|
|
||||||
|
int tmpwidth = *width / ratio;
|
||||||
|
int tmpheight = *height / ratio;
|
||||||
|
|
||||||
|
/* resampled destination */
|
||||||
|
uint8 *tmptex = (uint8*)malloc((tmpwidth * tmpheight) << 2);
|
||||||
|
if (!tmptex) return 0;
|
||||||
|
|
||||||
|
/* work buffer. single row */
|
||||||
|
uint8 *workbuf = (uint8*)malloc(*width << 2);
|
||||||
|
if (!workbuf) {
|
||||||
|
free(tmptex);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* prepare filter lookup table. only half width required for symetric filters. */
|
||||||
|
double *weight = (double*)malloc((int)((half_window * ratio) * sizeof(double)));
|
||||||
|
if (!weight) {
|
||||||
|
free(tmptex);
|
||||||
|
free(workbuf);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
for (x = 0; x < half_window * ratio; x++) {
|
||||||
|
//weight[x] = tent((double)x / ratio) / ratio;
|
||||||
|
//weight[x] = gaussian((double)x / ratio) / ratio;
|
||||||
|
//weight[x] = lanczos3((double)x / ratio) / ratio;
|
||||||
|
//weight[x] = mitchell((double)x / ratio) / ratio;
|
||||||
|
weight[x] = kaiser((double)x / ratio) / ratio;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* linear convolution */
|
||||||
|
for (y = 0; y < tmpheight; y++) {
|
||||||
|
for (x = 0; x < *width; x++) {
|
||||||
|
texel = ((uint32*)*src)[y * ratio * *width + x];
|
||||||
|
A = (double)(texel >> 24) * weight[0];
|
||||||
|
R = (double)((texel >> 16) & 0xff) * weight[0];
|
||||||
|
G = (double)((texel >> 8) & 0xff) * weight[0];
|
||||||
|
B = (double)((texel ) & 0xff) * weight[0];
|
||||||
|
for (y2 = 1; y2 < half_window * ratio; y2++) {
|
||||||
|
z = y * ratio + y2;
|
||||||
|
if (z >= *height) z = *height - 1;
|
||||||
|
texel = ((uint32*)*src)[z * *width + x];
|
||||||
|
A += (double)(texel >> 24) * weight[y2];
|
||||||
|
R += (double)((texel >> 16) & 0xff) * weight[y2];
|
||||||
|
G += (double)((texel >> 8) & 0xff) * weight[y2];
|
||||||
|
B += (double)((texel ) & 0xff) * weight[y2];
|
||||||
|
z = y * ratio - y2;
|
||||||
|
if (z < 0) z = 0;
|
||||||
|
texel = ((uint32*)*src)[z * *width + x];
|
||||||
|
A += (double)(texel >> 24) * weight[y2];
|
||||||
|
R += (double)((texel >> 16) & 0xff) * weight[y2];
|
||||||
|
G += (double)((texel >> 8) & 0xff) * weight[y2];
|
||||||
|
B += (double)((texel ) & 0xff) * weight[y2];
|
||||||
|
}
|
||||||
|
if (A < 0) A = 0; else if (A > 255) A = 255;
|
||||||
|
if (R < 0) R = 0; else if (R > 255) R = 255;
|
||||||
|
if (G < 0) G = 0; else if (G > 255) G = 255;
|
||||||
|
if (B < 0) B = 0; else if (B > 255) B = 255;
|
||||||
|
((uint32*)workbuf)[x] = (((uint32)A << 24) | ((uint32)R << 16) | ((uint32)G << 8) | (uint32)B);
|
||||||
|
}
|
||||||
|
for (x = 0; x < tmpwidth; x++) {
|
||||||
|
texel = ((uint32*)workbuf)[x * ratio];
|
||||||
|
A = (double)(texel >> 24) * weight[0];
|
||||||
|
R = (double)((texel >> 16) & 0xff) * weight[0];
|
||||||
|
G = (double)((texel >> 8) & 0xff) * weight[0];
|
||||||
|
B = (double)((texel ) & 0xff) * weight[0];
|
||||||
|
for (x2 = 1; x2 < half_window * ratio; x2++) {
|
||||||
|
z = x * ratio + x2;
|
||||||
|
if (z >= *width) z = *width - 1;
|
||||||
|
texel = ((uint32*)workbuf)[z];
|
||||||
|
A += (double)(texel >> 24) * weight[x2];
|
||||||
|
R += (double)((texel >> 16) & 0xff) * weight[x2];
|
||||||
|
G += (double)((texel >> 8) & 0xff) * weight[x2];
|
||||||
|
B += (double)((texel ) & 0xff) * weight[x2];
|
||||||
|
z = x * ratio - x2;
|
||||||
|
if (z < 0) z = 0;
|
||||||
|
texel = ((uint32*)workbuf)[z];
|
||||||
|
A += (double)(texel >> 24) * weight[x2];
|
||||||
|
R += (double)((texel >> 16) & 0xff) * weight[x2];
|
||||||
|
G += (double)((texel >> 8) & 0xff) * weight[x2];
|
||||||
|
B += (double)((texel ) & 0xff) * weight[x2];
|
||||||
|
}
|
||||||
|
if (A < 0) A = 0; else if (A > 255) A = 255;
|
||||||
|
if (R < 0) R = 0; else if (R > 255) R = 255;
|
||||||
|
if (G < 0) G = 0; else if (G > 255) G = 255;
|
||||||
|
if (B < 0) B = 0; else if (B > 255) B = 255;
|
||||||
|
((uint32*)tmptex)[y * tmpwidth + x] = (((uint32)A << 24) | ((uint32)R << 16) | ((uint32)G << 8) | (uint32)B);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
free(*src);
|
||||||
|
*src = tmptex;
|
||||||
|
free(weight);
|
||||||
|
free(workbuf);
|
||||||
|
*width = tmpwidth;
|
||||||
|
*height = tmpheight;
|
||||||
|
|
||||||
|
DBG_INFO(80, L"minification ratio:%d -> %d x %d\n", ratio, *width, *height);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
#endif
|
||||||
|
}
|
45
GLideNHQ/TxReSample.h
Normal file
45
GLideNHQ/TxReSample.h
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
/*
|
||||||
|
* Texture Filtering
|
||||||
|
* Version: 1.0
|
||||||
|
*
|
||||||
|
* Copyright (C) 2007 Hiroshi Morii All Rights Reserved.
|
||||||
|
* Email koolsmoky(at)users.sourceforge.net
|
||||||
|
* Web http://www.3dfxzone.it/koolsmoky
|
||||||
|
*
|
||||||
|
* this 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, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* this 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 GNU Make; see the file COPYING. If not, write to
|
||||||
|
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __TXRESAMPLE_H__
|
||||||
|
#define __TXRESAMPLE_H__
|
||||||
|
|
||||||
|
#include "TxInternal.h"
|
||||||
|
|
||||||
|
class TxReSample
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
double tent(double x);
|
||||||
|
double gaussian(double x);
|
||||||
|
double sinc(double x);
|
||||||
|
double lanczos3(double x);
|
||||||
|
double mitchell(double x);
|
||||||
|
double besselI0(double x);
|
||||||
|
double kaiser(double x);
|
||||||
|
public:
|
||||||
|
boolean minify(uint8 **src, int *width, int *height, int ratio);
|
||||||
|
boolean nextPow2(uint8** image, int* width, int* height, int bpp, boolean use_3dfx);
|
||||||
|
int nextPow2(int num);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* __TXRESAMPLE_H__ */
|
79
GLideNHQ/TxTexCache.cpp
Normal file
79
GLideNHQ/TxTexCache.cpp
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
/*
|
||||||
|
* Texture Filtering
|
||||||
|
* Version: 1.0
|
||||||
|
*
|
||||||
|
* Copyright (C) 2007 Hiroshi Morii All Rights Reserved.
|
||||||
|
* Email koolsmoky(at)users.sourceforge.net
|
||||||
|
* Web http://www.3dfxzone.it/koolsmoky
|
||||||
|
*
|
||||||
|
* this 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, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* this 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 GNU Make; see the file COPYING. If not, write to
|
||||||
|
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef __MSC__
|
||||||
|
#pragma warning(disable: 4786)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* dump cache to disk (0:disable, 1:enable) */
|
||||||
|
#define DUMP_CACHE 1
|
||||||
|
|
||||||
|
#include "TxTexCache.h"
|
||||||
|
#include "TxDbg.h"
|
||||||
|
#include <zlib.h>
|
||||||
|
#include <string>
|
||||||
|
#include <boost/filesystem.hpp>
|
||||||
|
|
||||||
|
TxTexCache::~TxTexCache()
|
||||||
|
{
|
||||||
|
#if DUMP_CACHE
|
||||||
|
if (_options & DUMP_TEXCACHE) {
|
||||||
|
/* dump cache to disk */
|
||||||
|
std::wstring filename = _ident + L"_MEMORYCACHE.dat";
|
||||||
|
boost::filesystem::wpath cachepath(_path);
|
||||||
|
cachepath /= boost::filesystem::wpath(L"cache");
|
||||||
|
int config = _options & (FILTER_MASK|ENHANCEMENT_MASK|COMPRESS_TEX|COMPRESSION_MASK|FORCE16BPP_TEX|GZ_TEXCACHE);
|
||||||
|
|
||||||
|
TxCache::save(cachepath.wstring().c_str(), filename.c_str(), config);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
TxTexCache::TxTexCache(int options, int cachesize, const wchar_t *path, const wchar_t *ident,
|
||||||
|
dispInfoFuncExt callback
|
||||||
|
) : TxCache((options & ~GZ_HIRESTEXCACHE), cachesize, path, ident, callback)
|
||||||
|
{
|
||||||
|
/* assert local options */
|
||||||
|
if (_path.empty() || _ident.empty() || !_cacheSize)
|
||||||
|
_options &= ~DUMP_TEXCACHE;
|
||||||
|
|
||||||
|
#if DUMP_CACHE
|
||||||
|
if (_options & DUMP_TEXCACHE) {
|
||||||
|
/* find it on disk */
|
||||||
|
std::wstring filename = _ident + L"_MEMORYCACHE.dat";
|
||||||
|
boost::filesystem::wpath cachepath(_path);
|
||||||
|
cachepath /= boost::filesystem::wpath(L"cache");
|
||||||
|
int config = _options & (FILTER_MASK|ENHANCEMENT_MASK|COMPRESS_TEX|COMPRESSION_MASK|FORCE16BPP_TEX|GZ_TEXCACHE);
|
||||||
|
|
||||||
|
TxCache::load(cachepath.wstring().c_str(), filename.c_str(), config);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean
|
||||||
|
TxTexCache::add(uint64 checksum, GHQTexInfo *info)
|
||||||
|
{
|
||||||
|
if (_cacheSize <= 0) return 0;
|
||||||
|
|
||||||
|
return TxCache::add(checksum, info);
|
||||||
|
}
|
39
GLideNHQ/TxTexCache.h
Normal file
39
GLideNHQ/TxTexCache.h
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
/*
|
||||||
|
* Texture Filtering
|
||||||
|
* Version: 1.0
|
||||||
|
*
|
||||||
|
* Copyright (C) 2007 Hiroshi Morii All Rights Reserved.
|
||||||
|
* Email koolsmoky(at)users.sourceforge.net
|
||||||
|
* Web http://www.3dfxzone.it/koolsmoky
|
||||||
|
*
|
||||||
|
* this 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, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* this 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 GNU Make; see the file COPYING. If not, write to
|
||||||
|
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __TXTEXCACHE_H__
|
||||||
|
#define __TXTEXCACHE_H__
|
||||||
|
|
||||||
|
#include "TxCache.h"
|
||||||
|
|
||||||
|
class TxTexCache : public TxCache
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
~TxTexCache();
|
||||||
|
TxTexCache(int options, int cachesize, const wchar_t *path, const wchar_t *ident,
|
||||||
|
dispInfoFuncExt callback);
|
||||||
|
boolean add(uint64 checksum, /* checksum hi:palette low:texture */
|
||||||
|
GHQTexInfo *info);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* __TXTEXCACHE_H__ */
|
1006
GLideNHQ/TxUtil.cpp
Normal file
1006
GLideNHQ/TxUtil.cpp
Normal file
File diff suppressed because it is too large
Load Diff
121
GLideNHQ/TxUtil.h
Normal file
121
GLideNHQ/TxUtil.h
Normal file
|
@ -0,0 +1,121 @@
|
||||||
|
/*
|
||||||
|
* Texture Filtering
|
||||||
|
* Version: 1.0
|
||||||
|
*
|
||||||
|
* Copyright (C) 2007 Hiroshi Morii All Rights Reserved.
|
||||||
|
* Email koolsmoky(at)users.sourceforge.net
|
||||||
|
* Web http://www.3dfxzone.it/koolsmoky
|
||||||
|
*
|
||||||
|
* this 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, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* this 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 GNU Make; see the file COPYING. If not, write to
|
||||||
|
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __TXUTIL_H__
|
||||||
|
#define __TXUTIL_H__
|
||||||
|
|
||||||
|
/* maximum number of CPU cores allowed */
|
||||||
|
#define MAX_NUMCORE 8
|
||||||
|
|
||||||
|
#include "TxInternal.h"
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#ifndef DXTN_DLL
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"{
|
||||||
|
#endif
|
||||||
|
void tx_compress_dxtn(int srccomps, int width, int height,
|
||||||
|
const void *source, int destformat, void *dest,
|
||||||
|
int destRowStride);
|
||||||
|
|
||||||
|
int fxt1_encode(int width, int height, int comps,
|
||||||
|
const void *source, int srcRowStride,
|
||||||
|
void *dest, int destRowStride);
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif /* DXTN_DLL */
|
||||||
|
|
||||||
|
typedef void (*dxtCompressTexFuncExt)(int srccomps, int width,
|
||||||
|
int height, const void *srcPixData,
|
||||||
|
int destformat, void *dest,
|
||||||
|
int dstRowStride);
|
||||||
|
|
||||||
|
typedef int (*fxtCompressTexFuncExt)(int width, int height, int comps,
|
||||||
|
const void *source, int srcRowStride,
|
||||||
|
void *dest, int destRowStride);
|
||||||
|
|
||||||
|
class TxLoadLib
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
#ifdef DXTN_DLL
|
||||||
|
HMODULE _dxtnlib;
|
||||||
|
#endif
|
||||||
|
fxtCompressTexFuncExt _tx_compress_fxt1;
|
||||||
|
dxtCompressTexFuncExt _tx_compress_dxtn;
|
||||||
|
TxLoadLib();
|
||||||
|
public:
|
||||||
|
static TxLoadLib* getInstance() {
|
||||||
|
static TxLoadLib txLoadLib;
|
||||||
|
return &txLoadLib;
|
||||||
|
}
|
||||||
|
~TxLoadLib();
|
||||||
|
fxtCompressTexFuncExt getfxtCompressTexFuncExt();
|
||||||
|
dxtCompressTexFuncExt getdxtCompressTexFuncExt();
|
||||||
|
};
|
||||||
|
|
||||||
|
class TxUtil
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
uint32 Adler32(const uint8* data, int Len, uint32 Adler);
|
||||||
|
uint32 Adler32(const uint8* src, int width, int height, int size, int rowStride);
|
||||||
|
uint32 RiceCRC32(const uint8* src, int width, int height, int size, int rowStride);
|
||||||
|
boolean RiceCRC32_CI4(const uint8* src, int width, int height, int size, int rowStride,
|
||||||
|
uint32* crc32, uint32* cimax);
|
||||||
|
boolean RiceCRC32_CI8(const uint8* src, int width, int height, int size, int rowStride,
|
||||||
|
uint32* crc32, uint32* cimax);
|
||||||
|
int log2(int num);
|
||||||
|
public:
|
||||||
|
TxUtil() { }
|
||||||
|
~TxUtil() { }
|
||||||
|
int sizeofTx(int width, int height, uint16 format);
|
||||||
|
uint32 checksumTx(uint8 *data, int width, int height, uint16 format);
|
||||||
|
#if 0 /* unused */
|
||||||
|
uint32 chkAlpha(uint32* src, int width, int height);
|
||||||
|
#endif
|
||||||
|
uint32 checksum(uint8 *src, int width, int height, int size, int rowStride);
|
||||||
|
uint64 checksum64(uint8 *src, int width, int height, int size, int rowStride, uint8 *palette);
|
||||||
|
int grLodLog2(int w, int h);
|
||||||
|
int grAspectRatioLog2(int w, int h);
|
||||||
|
int getNumberofProcessors();
|
||||||
|
};
|
||||||
|
|
||||||
|
class TxMemBuf
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
uint8 *_tex[2];
|
||||||
|
uint32 _size[2];
|
||||||
|
TxMemBuf();
|
||||||
|
public:
|
||||||
|
static TxMemBuf* getInstance() {
|
||||||
|
static TxMemBuf txMemBuf;
|
||||||
|
return &txMemBuf;
|
||||||
|
}
|
||||||
|
~TxMemBuf();
|
||||||
|
boolean init(int maxwidth, int maxheight);
|
||||||
|
void shutdown(void);
|
||||||
|
uint8 *get(unsigned int num);
|
||||||
|
uint32 size_of(unsigned int num);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* __TXUTIL_H__ */
|
27
GLideNHQ/bldno.cpp
Normal file
27
GLideNHQ/bldno.cpp
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
int main (void)
|
||||||
|
{
|
||||||
|
struct tm locTime;
|
||||||
|
time_t sysTime;
|
||||||
|
char *build;
|
||||||
|
|
||||||
|
time(&sysTime);
|
||||||
|
locTime = *localtime(&sysTime);
|
||||||
|
|
||||||
|
if ((build = getenv("BUILD_NUMBER")) != NULL) {
|
||||||
|
printf("#define BUILD_NUMBER %s\n", build);
|
||||||
|
printf("#define BUILD_NUMBER_STR \"%s\"\n", build);
|
||||||
|
} else {
|
||||||
|
unsigned short magic;
|
||||||
|
magic = (locTime.tm_yday << 7) |
|
||||||
|
(locTime.tm_hour << 2) |
|
||||||
|
(locTime.tm_min / 15);
|
||||||
|
printf("#define BUILD_NUMBER %d\n", magic);
|
||||||
|
printf("#define BUILD_NUMBER_STR \"%d\"\n", magic);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
2
GLideNHQ/bldno.h
Normal file
2
GLideNHQ/bldno.h
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
#define BUILD_NUMBER 13480
|
||||||
|
#define BUILD_NUMBER_STR "13480"
|
339
GLideNHQ/gpl-2.0.txt
Normal file
339
GLideNHQ/gpl-2.0.txt
Normal file
|
@ -0,0 +1,339 @@
|
||||||
|
GNU GENERAL PUBLIC LICENSE
|
||||||
|
Version 2, June 1991
|
||||||
|
|
||||||
|
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
Preamble
|
||||||
|
|
||||||
|
The licenses for most software are designed to take away your
|
||||||
|
freedom to share and change it. By contrast, the GNU General Public
|
||||||
|
License is intended to guarantee your freedom to share and change free
|
||||||
|
software--to make sure the software is free for all its users. This
|
||||||
|
General Public License applies to most of the Free Software
|
||||||
|
Foundation's software and to any other program whose authors commit to
|
||||||
|
using it. (Some other Free Software Foundation software is covered by
|
||||||
|
the GNU Lesser General Public License instead.) You can apply it to
|
||||||
|
your programs, too.
|
||||||
|
|
||||||
|
When we speak of free software, we are referring to freedom, not
|
||||||
|
price. Our General Public Licenses are designed to make sure that you
|
||||||
|
have the freedom to distribute copies of free software (and charge for
|
||||||
|
this service if you wish), that you receive source code or can get it
|
||||||
|
if you want it, that you can change the software or use pieces of it
|
||||||
|
in new free programs; and that you know you can do these things.
|
||||||
|
|
||||||
|
To protect your rights, we need to make restrictions that forbid
|
||||||
|
anyone to deny you these rights or to ask you to surrender the rights.
|
||||||
|
These restrictions translate to certain responsibilities for you if you
|
||||||
|
distribute copies of the software, or if you modify it.
|
||||||
|
|
||||||
|
For example, if you distribute copies of such a program, whether
|
||||||
|
gratis or for a fee, you must give the recipients all the rights that
|
||||||
|
you have. You must make sure that they, too, receive or can get the
|
||||||
|
source code. And you must show them these terms so they know their
|
||||||
|
rights.
|
||||||
|
|
||||||
|
We protect your rights with two steps: (1) copyright the software, and
|
||||||
|
(2) offer you this license which gives you legal permission to copy,
|
||||||
|
distribute and/or modify the software.
|
||||||
|
|
||||||
|
Also, for each author's protection and ours, we want to make certain
|
||||||
|
that everyone understands that there is no warranty for this free
|
||||||
|
software. If the software is modified by someone else and passed on, we
|
||||||
|
want its recipients to know that what they have is not the original, so
|
||||||
|
that any problems introduced by others will not reflect on the original
|
||||||
|
authors' reputations.
|
||||||
|
|
||||||
|
Finally, any free program is threatened constantly by software
|
||||||
|
patents. We wish to avoid the danger that redistributors of a free
|
||||||
|
program will individually obtain patent licenses, in effect making the
|
||||||
|
program proprietary. To prevent this, we have made it clear that any
|
||||||
|
patent must be licensed for everyone's free use or not licensed at all.
|
||||||
|
|
||||||
|
The precise terms and conditions for copying, distribution and
|
||||||
|
modification follow.
|
||||||
|
|
||||||
|
GNU GENERAL PUBLIC LICENSE
|
||||||
|
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||||
|
|
||||||
|
0. 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 General Public License. The "Program", below,
|
||||||
|
refers to any such program or work, and a "work based on the Program"
|
||||||
|
means either the Program or any derivative work under copyright law:
|
||||||
|
that is to say, a work containing the Program or a portion of it,
|
||||||
|
either verbatim or with modifications and/or translated into another
|
||||||
|
language. (Hereinafter, translation is included without limitation in
|
||||||
|
the term "modification".) Each licensee is addressed as "you".
|
||||||
|
|
||||||
|
Activities other than copying, distribution and modification are not
|
||||||
|
covered by this License; they are outside its scope. The act of
|
||||||
|
running the Program is not restricted, and the output from the Program
|
||||||
|
is covered only if its contents constitute a work based on the
|
||||||
|
Program (independent of having been made by running the Program).
|
||||||
|
Whether that is true depends on what the Program does.
|
||||||
|
|
||||||
|
1. You may copy and distribute verbatim copies of the Program's
|
||||||
|
source code as you receive it, in any medium, provided that you
|
||||||
|
conspicuously and appropriately publish on each copy an appropriate
|
||||||
|
copyright notice and disclaimer of warranty; keep intact all the
|
||||||
|
notices that refer to this License and to the absence of any warranty;
|
||||||
|
and give any other recipients of the Program a copy of this License
|
||||||
|
along with the Program.
|
||||||
|
|
||||||
|
You may charge a fee for the physical act of transferring a copy, and
|
||||||
|
you may at your option offer warranty protection in exchange for a fee.
|
||||||
|
|
||||||
|
2. You may modify your copy or copies of the Program or any portion
|
||||||
|
of it, thus forming a work based on the Program, and copy and
|
||||||
|
distribute such modifications or work under the terms of Section 1
|
||||||
|
above, provided that you also meet all of these conditions:
|
||||||
|
|
||||||
|
a) You must cause the modified files to carry prominent notices
|
||||||
|
stating that you changed the files and the date of any change.
|
||||||
|
|
||||||
|
b) You must cause any work that you distribute or publish, that in
|
||||||
|
whole or in part contains or is derived from the Program or any
|
||||||
|
part thereof, to be licensed as a whole at no charge to all third
|
||||||
|
parties under the terms of this License.
|
||||||
|
|
||||||
|
c) If the modified program normally reads commands interactively
|
||||||
|
when run, you must cause it, when started running for such
|
||||||
|
interactive use in the most ordinary way, to print or display an
|
||||||
|
announcement including an appropriate copyright notice and a
|
||||||
|
notice that there is no warranty (or else, saying that you provide
|
||||||
|
a warranty) and that users may redistribute the program under
|
||||||
|
these conditions, and telling the user how to view a copy of this
|
||||||
|
License. (Exception: if the Program itself is interactive but
|
||||||
|
does not normally print such an announcement, your work based on
|
||||||
|
the Program is not required to print an announcement.)
|
||||||
|
|
||||||
|
These requirements apply to the modified work as a whole. If
|
||||||
|
identifiable sections of that work are not derived from the Program,
|
||||||
|
and can be reasonably considered independent and separate works in
|
||||||
|
themselves, then this License, and its terms, do not apply to those
|
||||||
|
sections when you distribute them as separate works. But when you
|
||||||
|
distribute the same sections as part of a whole which is a work based
|
||||||
|
on the Program, the distribution of the whole must be on the terms of
|
||||||
|
this License, whose permissions for other licensees extend to the
|
||||||
|
entire whole, and thus to each and every part regardless of who wrote it.
|
||||||
|
|
||||||
|
Thus, it is not the intent of this section 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 or
|
||||||
|
collective works based on the Program.
|
||||||
|
|
||||||
|
In addition, mere aggregation of another work not based on the Program
|
||||||
|
with the Program (or with a work based on the Program) on a volume of
|
||||||
|
a storage or distribution medium does not bring the other work under
|
||||||
|
the scope of this License.
|
||||||
|
|
||||||
|
3. You may copy and distribute the Program (or a work based on it,
|
||||||
|
under Section 2) in object code or executable form under the terms of
|
||||||
|
Sections 1 and 2 above provided that you also do one of the following:
|
||||||
|
|
||||||
|
a) Accompany it with the complete corresponding machine-readable
|
||||||
|
source code, which must be distributed under the terms of Sections
|
||||||
|
1 and 2 above on a medium customarily used for software interchange; or,
|
||||||
|
|
||||||
|
b) 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 1 and 2 above on a medium
|
||||||
|
customarily used for software interchange; or,
|
||||||
|
|
||||||
|
c) 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 b above.)
|
||||||
|
|
||||||
|
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, plus any
|
||||||
|
associated interface definition files, plus the scripts used to
|
||||||
|
control compilation and installation of the executable. However, as a
|
||||||
|
special exception, 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.
|
||||||
|
|
||||||
|
If distribution of executable 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.
|
||||||
|
|
||||||
|
4. You may not copy, modify, sublicense, or distribute the Program
|
||||||
|
except as expressly provided under this License. Any attempt
|
||||||
|
otherwise to copy, modify, sublicense or distribute the Program 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.
|
||||||
|
|
||||||
|
5. You are not required to accept this License, since you have not
|
||||||
|
signed it. However, nothing else grants you permission to modify or
|
||||||
|
distribute the Program or its derivative works. These actions are
|
||||||
|
prohibited by law if you do not accept this License. Therefore, by
|
||||||
|
modifying or distributing the Program (or any work based on the
|
||||||
|
Program), 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.
|
||||||
|
|
||||||
|
6. Each time you redistribute the Program (or any work based on the
|
||||||
|
Program), the recipient automatically receives a license from the
|
||||||
|
original licensor to copy, distribute or modify the Program subject to
|
||||||
|
these terms and conditions. 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.
|
||||||
|
|
||||||
|
7. If, as a consequence of a court judgment or allegation of patent
|
||||||
|
infringement or for any other reason (not limited to patent issues),
|
||||||
|
conditions are imposed on you (whether by court order, agreement or
|
||||||
|
otherwise) that contradict the conditions of this License, they do not
|
||||||
|
excuse you from the conditions of this License. If you cannot
|
||||||
|
distribute so as to satisfy simultaneously your obligations under this
|
||||||
|
License and any other pertinent obligations, then as a consequence you
|
||||||
|
may not distribute the Program at all. For example, if a patent
|
||||||
|
license would not permit royalty-free redistribution of the Program by
|
||||||
|
all those who receive copies directly or indirectly through you, then
|
||||||
|
the only way you could satisfy both it and this License would be to
|
||||||
|
refrain entirely from distribution of the Program.
|
||||||
|
|
||||||
|
If any portion of this section is held invalid or unenforceable under
|
||||||
|
any particular circumstance, the balance of the section is intended to
|
||||||
|
apply and the section as a whole is intended to apply in other
|
||||||
|
circumstances.
|
||||||
|
|
||||||
|
It is not the purpose of this section to induce you to infringe any
|
||||||
|
patents or other property right claims or to contest validity of any
|
||||||
|
such claims; this section has the sole purpose of protecting the
|
||||||
|
integrity of the free software distribution system, which is
|
||||||
|
implemented by public license practices. Many people have made
|
||||||
|
generous contributions to the wide range of software distributed
|
||||||
|
through that system in reliance on consistent application of that
|
||||||
|
system; it is up to the author/donor to decide if he or she is willing
|
||||||
|
to distribute software through any other system and a licensee cannot
|
||||||
|
impose that choice.
|
||||||
|
|
||||||
|
This section is intended to make thoroughly clear what is believed to
|
||||||
|
be a consequence of the rest of this License.
|
||||||
|
|
||||||
|
8. If the distribution and/or use of the Program 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.
|
||||||
|
|
||||||
|
9. The Free Software Foundation may publish revised and/or new versions
|
||||||
|
of the General Public License from time to time. Such new versions will
|
||||||
|
be similar in spirit to the present version, but may differ in detail to
|
||||||
|
address new problems or concerns.
|
||||||
|
|
||||||
|
Each version is given a distinguishing version number. If the Program
|
||||||
|
specifies a version number of this License which applies to it and "any
|
||||||
|
later version", you have the option of following the terms and conditions
|
||||||
|
either of that version or of any later version published by the Free
|
||||||
|
Software Foundation. If the Program does not specify a version number of
|
||||||
|
this License, you may choose any version ever published by the Free Software
|
||||||
|
Foundation.
|
||||||
|
|
||||||
|
10. If you wish to incorporate parts of the Program into other free
|
||||||
|
programs whose distribution conditions are different, write to the author
|
||||||
|
to ask for permission. For software which is copyrighted by the Free
|
||||||
|
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||||
|
make exceptions for this. Our decision will be guided by the two goals
|
||||||
|
of preserving the free status of all derivatives of our free software and
|
||||||
|
of promoting the sharing and reuse of software generally.
|
||||||
|
|
||||||
|
NO WARRANTY
|
||||||
|
|
||||||
|
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||||
|
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||||
|
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||||
|
PROVIDE THE PROGRAM "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 IS WITH YOU. SHOULD THE
|
||||||
|
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||||
|
REPAIR OR CORRECTION.
|
||||||
|
|
||||||
|
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||||
|
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||||
|
REDISTRIBUTE THE PROGRAM 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 (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 TO OPERATE WITH ANY OTHER
|
||||||
|
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||||
|
POSSIBILITY OF SUCH DAMAGES.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
How to Apply These Terms to Your New Programs
|
||||||
|
|
||||||
|
If you develop a new program, and you want it to be of the greatest
|
||||||
|
possible use to the public, the best way to achieve this is to make it
|
||||||
|
free software which everyone can redistribute and change under these terms.
|
||||||
|
|
||||||
|
To do so, attach the following notices to the program. It is safest
|
||||||
|
to attach them to the start of each source file to most effectively
|
||||||
|
convey the exclusion of warranty; and each file should have at least
|
||||||
|
the "copyright" line and a pointer to where the full notice is found.
|
||||||
|
|
||||||
|
<one line to give the program's name and a brief idea of what it does.>
|
||||||
|
Copyright (C) <year> <name of author>
|
||||||
|
|
||||||
|
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 program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
|
||||||
|
Also add information on how to contact you by electronic and paper mail.
|
||||||
|
|
||||||
|
If the program is interactive, make it output a short notice like this
|
||||||
|
when it starts in an interactive mode:
|
||||||
|
|
||||||
|
Gnomovision version 69, Copyright (C) year name of author
|
||||||
|
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||||
|
This is free software, and you are welcome to redistribute it
|
||||||
|
under certain conditions; type `show c' for details.
|
||||||
|
|
||||||
|
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||||
|
parts of the General Public License. Of course, the commands you use may
|
||||||
|
be called something other than `show w' and `show c'; they could even be
|
||||||
|
mouse-clicks or menu items--whatever suits your program.
|
||||||
|
|
||||||
|
You should also get your employer (if you work as a programmer) or your
|
||||||
|
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||||
|
necessary. Here is a sample; alter the names:
|
||||||
|
|
||||||
|
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||||
|
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||||
|
|
||||||
|
<signature of Ty Coon>, 1 April 1989
|
||||||
|
Ty Coon, President of Vice
|
||||||
|
|
||||||
|
This General Public License does not permit incorporating your program into
|
||||||
|
proprietary programs. If your program is a subroutine library, you may
|
||||||
|
consider it more useful to permit linking proprietary applications with the
|
||||||
|
library. If this is what you want to do, use the GNU Lesser General
|
||||||
|
Public License instead of this License.
|
2686
GLideNHQ/inc/png.h
Normal file
2686
GLideNHQ/inc/png.h
Normal file
File diff suppressed because it is too large
Load Diff
1510
GLideNHQ/inc/pngconf.h
Normal file
1510
GLideNHQ/inc/pngconf.h
Normal file
File diff suppressed because it is too large
Load Diff
332
GLideNHQ/inc/zconf.h
Normal file
332
GLideNHQ/inc/zconf.h
Normal file
|
@ -0,0 +1,332 @@
|
||||||
|
/* zconf.h -- configuration of the zlib compression library
|
||||||
|
* Copyright (C) 1995-2005 Jean-loup Gailly.
|
||||||
|
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* @(#) $Id$ */
|
||||||
|
|
||||||
|
#ifndef ZCONF_H
|
||||||
|
#define ZCONF_H
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If you *really* need a unique prefix for all types and library functions,
|
||||||
|
* compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
|
||||||
|
*/
|
||||||
|
#ifdef Z_PREFIX
|
||||||
|
# define deflateInit_ z_deflateInit_
|
||||||
|
# define deflate z_deflate
|
||||||
|
# define deflateEnd z_deflateEnd
|
||||||
|
# define inflateInit_ z_inflateInit_
|
||||||
|
# define inflate z_inflate
|
||||||
|
# define inflateEnd z_inflateEnd
|
||||||
|
# define deflateInit2_ z_deflateInit2_
|
||||||
|
# define deflateSetDictionary z_deflateSetDictionary
|
||||||
|
# define deflateCopy z_deflateCopy
|
||||||
|
# define deflateReset z_deflateReset
|
||||||
|
# define deflateParams z_deflateParams
|
||||||
|
# define deflateBound z_deflateBound
|
||||||
|
# define deflatePrime z_deflatePrime
|
||||||
|
# define inflateInit2_ z_inflateInit2_
|
||||||
|
# define inflateSetDictionary z_inflateSetDictionary
|
||||||
|
# define inflateSync z_inflateSync
|
||||||
|
# define inflateSyncPoint z_inflateSyncPoint
|
||||||
|
# define inflateCopy z_inflateCopy
|
||||||
|
# define inflateReset z_inflateReset
|
||||||
|
# define inflateBack z_inflateBack
|
||||||
|
# define inflateBackEnd z_inflateBackEnd
|
||||||
|
# define compress z_compress
|
||||||
|
# define compress2 z_compress2
|
||||||
|
# define compressBound z_compressBound
|
||||||
|
# define uncompress z_uncompress
|
||||||
|
# define adler32 z_adler32
|
||||||
|
# define crc32 z_crc32
|
||||||
|
# define get_crc_table z_get_crc_table
|
||||||
|
# define zError z_zError
|
||||||
|
|
||||||
|
# define alloc_func z_alloc_func
|
||||||
|
# define free_func z_free_func
|
||||||
|
# define in_func z_in_func
|
||||||
|
# define out_func z_out_func
|
||||||
|
# define Byte z_Byte
|
||||||
|
# define uInt z_uInt
|
||||||
|
# define uLong z_uLong
|
||||||
|
# define Bytef z_Bytef
|
||||||
|
# define charf z_charf
|
||||||
|
# define intf z_intf
|
||||||
|
# define uIntf z_uIntf
|
||||||
|
# define uLongf z_uLongf
|
||||||
|
# define voidpf z_voidpf
|
||||||
|
# define voidp z_voidp
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__MSDOS__) && !defined(MSDOS)
|
||||||
|
# define MSDOS
|
||||||
|
#endif
|
||||||
|
#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2)
|
||||||
|
# define OS2
|
||||||
|
#endif
|
||||||
|
#if defined(_WINDOWS) && !defined(WINDOWS)
|
||||||
|
# define WINDOWS
|
||||||
|
#endif
|
||||||
|
#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__)
|
||||||
|
# ifndef WIN32
|
||||||
|
# define WIN32
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32)
|
||||||
|
# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__)
|
||||||
|
# ifndef SYS16BIT
|
||||||
|
# define SYS16BIT
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Compile with -DMAXSEG_64K if the alloc function cannot allocate more
|
||||||
|
* than 64k bytes at a time (needed on systems with 16-bit int).
|
||||||
|
*/
|
||||||
|
#ifdef SYS16BIT
|
||||||
|
# define MAXSEG_64K
|
||||||
|
#endif
|
||||||
|
#ifdef MSDOS
|
||||||
|
# define UNALIGNED_OK
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __STDC_VERSION__
|
||||||
|
# ifndef STDC
|
||||||
|
# define STDC
|
||||||
|
# endif
|
||||||
|
# if __STDC_VERSION__ >= 199901L
|
||||||
|
# ifndef STDC99
|
||||||
|
# define STDC99
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus))
|
||||||
|
# define STDC
|
||||||
|
#endif
|
||||||
|
#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__))
|
||||||
|
# define STDC
|
||||||
|
#endif
|
||||||
|
#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32))
|
||||||
|
# define STDC
|
||||||
|
#endif
|
||||||
|
#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__))
|
||||||
|
# define STDC
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */
|
||||||
|
# define STDC
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef STDC
|
||||||
|
# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
|
||||||
|
# define const /* note: need a more gentle solution here */
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Some Mac compilers merge all .h files incorrectly: */
|
||||||
|
#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__)
|
||||||
|
# define NO_DUMMY_DECL
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Maximum value for memLevel in deflateInit2 */
|
||||||
|
#ifndef MAX_MEM_LEVEL
|
||||||
|
# ifdef MAXSEG_64K
|
||||||
|
# define MAX_MEM_LEVEL 8
|
||||||
|
# else
|
||||||
|
# define MAX_MEM_LEVEL 9
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Maximum value for windowBits in deflateInit2 and inflateInit2.
|
||||||
|
* WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
|
||||||
|
* created by gzip. (Files created by minigzip can still be extracted by
|
||||||
|
* gzip.)
|
||||||
|
*/
|
||||||
|
#ifndef MAX_WBITS
|
||||||
|
# define MAX_WBITS 15 /* 32K LZ77 window */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* The memory requirements for deflate are (in bytes):
|
||||||
|
(1 << (windowBits+2)) + (1 << (memLevel+9))
|
||||||
|
that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values)
|
||||||
|
plus a few kilobytes for small objects. For example, if you want to reduce
|
||||||
|
the default memory requirements from 256K to 128K, compile with
|
||||||
|
make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
|
||||||
|
Of course this will generally degrade compression (there's no free lunch).
|
||||||
|
|
||||||
|
The memory requirements for inflate are (in bytes) 1 << windowBits
|
||||||
|
that is, 32K for windowBits=15 (default value) plus a few kilobytes
|
||||||
|
for small objects.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Type declarations */
|
||||||
|
|
||||||
|
#ifndef OF /* function prototypes */
|
||||||
|
# ifdef STDC
|
||||||
|
# define OF(args) args
|
||||||
|
# else
|
||||||
|
# define OF(args) ()
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* The following definitions for FAR are needed only for MSDOS mixed
|
||||||
|
* model programming (small or medium model with some far allocations).
|
||||||
|
* This was tested only with MSC; for other MSDOS compilers you may have
|
||||||
|
* to define NO_MEMCPY in zutil.h. If you don't need the mixed model,
|
||||||
|
* just define FAR to be empty.
|
||||||
|
*/
|
||||||
|
#ifdef SYS16BIT
|
||||||
|
# if defined(M_I86SM) || defined(M_I86MM)
|
||||||
|
/* MSC small or medium model */
|
||||||
|
# define SMALL_MEDIUM
|
||||||
|
# ifdef _MSC_VER
|
||||||
|
# define FAR _far
|
||||||
|
# else
|
||||||
|
# define FAR far
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
# if (defined(__SMALL__) || defined(__MEDIUM__))
|
||||||
|
/* Turbo C small or medium model */
|
||||||
|
# define SMALL_MEDIUM
|
||||||
|
# ifdef __BORLANDC__
|
||||||
|
# define FAR _far
|
||||||
|
# else
|
||||||
|
# define FAR far
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(WINDOWS) || defined(WIN32)
|
||||||
|
/* If building or using zlib as a DLL, define ZLIB_DLL.
|
||||||
|
* This is not mandatory, but it offers a little performance increase.
|
||||||
|
*/
|
||||||
|
# ifdef ZLIB_DLL
|
||||||
|
# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500))
|
||||||
|
# ifdef ZLIB_INTERNAL
|
||||||
|
# define ZEXTERN extern __declspec(dllexport)
|
||||||
|
# else
|
||||||
|
# define ZEXTERN extern __declspec(dllimport)
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
# endif /* ZLIB_DLL */
|
||||||
|
/* If building or using zlib with the WINAPI/WINAPIV calling convention,
|
||||||
|
* define ZLIB_WINAPI.
|
||||||
|
* Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI.
|
||||||
|
*/
|
||||||
|
# ifdef ZLIB_WINAPI
|
||||||
|
# ifdef FAR
|
||||||
|
# undef FAR
|
||||||
|
# endif
|
||||||
|
# include <windows.h>
|
||||||
|
/* No need for _export, use ZLIB.DEF instead. */
|
||||||
|
/* For complete Windows compatibility, use WINAPI, not __stdcall. */
|
||||||
|
# define ZEXPORT WINAPI
|
||||||
|
# ifdef WIN32
|
||||||
|
# define ZEXPORTVA WINAPIV
|
||||||
|
# else
|
||||||
|
# define ZEXPORTVA FAR CDECL
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined (__BEOS__)
|
||||||
|
# ifdef ZLIB_DLL
|
||||||
|
# ifdef ZLIB_INTERNAL
|
||||||
|
# define ZEXPORT __declspec(dllexport)
|
||||||
|
# define ZEXPORTVA __declspec(dllexport)
|
||||||
|
# else
|
||||||
|
# define ZEXPORT __declspec(dllimport)
|
||||||
|
# define ZEXPORTVA __declspec(dllimport)
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef ZEXTERN
|
||||||
|
# define ZEXTERN extern
|
||||||
|
#endif
|
||||||
|
#ifndef ZEXPORT
|
||||||
|
# define ZEXPORT
|
||||||
|
#endif
|
||||||
|
#ifndef ZEXPORTVA
|
||||||
|
# define ZEXPORTVA
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef FAR
|
||||||
|
# define FAR
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(__MACTYPES__)
|
||||||
|
typedef unsigned char Byte; /* 8 bits */
|
||||||
|
#endif
|
||||||
|
typedef unsigned int uInt; /* 16 bits or more */
|
||||||
|
typedef unsigned long uLong; /* 32 bits or more */
|
||||||
|
|
||||||
|
#ifdef SMALL_MEDIUM
|
||||||
|
/* Borland C/C++ and some old MSC versions ignore FAR inside typedef */
|
||||||
|
# define Bytef Byte FAR
|
||||||
|
#else
|
||||||
|
typedef Byte FAR Bytef;
|
||||||
|
#endif
|
||||||
|
typedef char FAR charf;
|
||||||
|
typedef int FAR intf;
|
||||||
|
typedef uInt FAR uIntf;
|
||||||
|
typedef uLong FAR uLongf;
|
||||||
|
|
||||||
|
#ifdef STDC
|
||||||
|
typedef void const *voidpc;
|
||||||
|
typedef void FAR *voidpf;
|
||||||
|
typedef void *voidp;
|
||||||
|
#else
|
||||||
|
typedef Byte const *voidpc;
|
||||||
|
typedef Byte FAR *voidpf;
|
||||||
|
typedef Byte *voidp;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if 0 /* HAVE_UNISTD_H -- this line is updated by ./configure */
|
||||||
|
# include <sys/types.h> /* for off_t */
|
||||||
|
# include <unistd.h> /* for SEEK_* and off_t */
|
||||||
|
# ifdef VMS
|
||||||
|
# include <unixio.h> /* for off_t */
|
||||||
|
# endif
|
||||||
|
# define z_off_t off_t
|
||||||
|
#endif
|
||||||
|
#ifndef SEEK_SET
|
||||||
|
# define SEEK_SET 0 /* Seek from beginning of file. */
|
||||||
|
# define SEEK_CUR 1 /* Seek from current position. */
|
||||||
|
# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */
|
||||||
|
#endif
|
||||||
|
#ifndef z_off_t
|
||||||
|
# define z_off_t long
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__OS400__)
|
||||||
|
# define NO_vsnprintf
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__MVS__)
|
||||||
|
# define NO_vsnprintf
|
||||||
|
# ifdef FAR
|
||||||
|
# undef FAR
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* MVS linker does not support external names larger than 8 bytes */
|
||||||
|
#if defined(__MVS__)
|
||||||
|
# pragma map(deflateInit_,"DEIN")
|
||||||
|
# pragma map(deflateInit2_,"DEIN2")
|
||||||
|
# pragma map(deflateEnd,"DEEND")
|
||||||
|
# pragma map(deflateBound,"DEBND")
|
||||||
|
# pragma map(inflateInit_,"ININ")
|
||||||
|
# pragma map(inflateInit2_,"ININ2")
|
||||||
|
# pragma map(inflateEnd,"INEND")
|
||||||
|
# pragma map(inflateSync,"INSY")
|
||||||
|
# pragma map(inflateSetDictionary,"INSEDI")
|
||||||
|
# pragma map(compressBound,"CMBND")
|
||||||
|
# pragma map(inflate_table,"INTABL")
|
||||||
|
# pragma map(inflate_fast,"INFA")
|
||||||
|
# pragma map(inflate_copyright,"INCOPY")
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* ZCONF_H */
|
1357
GLideNHQ/inc/zlib.h
Normal file
1357
GLideNHQ/inc/zlib.h
Normal file
File diff suppressed because it is too large
Load Diff
BIN
GLideNHQ/lib/dxtn.lib
Normal file
BIN
GLideNHQ/lib/dxtn.lib
Normal file
Binary file not shown.
BIN
GLideNHQ/lib/dxtnd.lib
Normal file
BIN
GLideNHQ/lib/dxtnd.lib
Normal file
Binary file not shown.
BIN
GLideNHQ/lib/libpng.lib
Normal file
BIN
GLideNHQ/lib/libpng.lib
Normal file
Binary file not shown.
BIN
GLideNHQ/lib/libpngd.lib
Normal file
BIN
GLideNHQ/lib/libpngd.lib
Normal file
Binary file not shown.
BIN
GLideNHQ/lib/zlib.lib
Normal file
BIN
GLideNHQ/lib/zlib.lib
Normal file
Binary file not shown.
BIN
GLideNHQ/lib/zlibd.lib
Normal file
BIN
GLideNHQ/lib/zlibd.lib
Normal file
Binary file not shown.
94
GLideNHQ/tc-1.1+/Makefile.gcc
Normal file
94
GLideNHQ/tc-1.1+/Makefile.gcc
Normal file
|
@ -0,0 +1,94 @@
|
||||||
|
# Texture compression Linux makefile
|
||||||
|
# Version: 1.1+
|
||||||
|
#
|
||||||
|
# Copyright (C) 2004 Daniel Borca All Rights Reserved.
|
||||||
|
#
|
||||||
|
# Copyright (C) 2007 Hiroshi Morii <koolsmoky(at)users.sourceforge.net>
|
||||||
|
# Added support for RGBA input, DXT3,5 workaround for ATI Radeons,
|
||||||
|
# and _mesa_upscale_teximage2d speedup.
|
||||||
|
#
|
||||||
|
# this 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, or (at your option)
|
||||||
|
# any later version.
|
||||||
|
#
|
||||||
|
# this 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 GNU Make; see the file COPYING. If not, write to
|
||||||
|
# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Available options:
|
||||||
|
#
|
||||||
|
# Environment variables:
|
||||||
|
# ARGB=1 enable support for ARGB inputs
|
||||||
|
# default = no
|
||||||
|
# RADEON=1 enable DXT3,5 workaround for ATI Radeon
|
||||||
|
# default = no
|
||||||
|
# YUV=1 use YUV to determine representative color
|
||||||
|
# default = no
|
||||||
|
#
|
||||||
|
# Targets:
|
||||||
|
# all: build dynamic module
|
||||||
|
# clean: remove object files
|
||||||
|
# realclean: remove all generated files
|
||||||
|
#
|
||||||
|
|
||||||
|
|
||||||
|
.PHONY: all clean realclean
|
||||||
|
|
||||||
|
DLLNAME = libdxtn.a
|
||||||
|
|
||||||
|
CC = gcc
|
||||||
|
CFLAGS = -Wall -W -pedantic -ansi -Wno-long-long
|
||||||
|
CFLAGS += -O3 -ffast-math -funroll-loops
|
||||||
|
#CFLAGS += -fomit-frame-pointer -fexpensive-optimizations
|
||||||
|
CFLAGS += -fPIC -DPIC
|
||||||
|
AR = ar
|
||||||
|
RANLIB = ranlib
|
||||||
|
|
||||||
|
ifdef ARGB
|
||||||
|
CFLAGS += -DARGB
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifdef RADEON
|
||||||
|
CFLAGS += -DRADEON
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifdef YUV
|
||||||
|
CFLAGS += -DYUV
|
||||||
|
endif
|
||||||
|
|
||||||
|
LD = gcc
|
||||||
|
LDFLAGS = -static
|
||||||
|
LDLIBS =
|
||||||
|
|
||||||
|
SOURCES = \
|
||||||
|
fxt1.c \
|
||||||
|
dxtn.c \
|
||||||
|
wrapper.c \
|
||||||
|
texstore.c
|
||||||
|
|
||||||
|
OBJECTS = $(SOURCES:.c=.o)
|
||||||
|
|
||||||
|
.c.o:
|
||||||
|
$(CC) -o $@ $(CFLAGS) -c $<
|
||||||
|
|
||||||
|
all: $(DLLNAME)
|
||||||
|
|
||||||
|
$(DLLNAME): $(OBJECTS)
|
||||||
|
$(AR) rc $@ $(OBJECTS)
|
||||||
|
$(RANLIB) $@
|
||||||
|
|
||||||
|
clean:
|
||||||
|
-$(RM) $(OBJECTS)
|
||||||
|
|
||||||
|
realclean: clean
|
||||||
|
-$(RM) $(DLLNAME)
|
||||||
|
|
||||||
|
-include depend
|
143
GLideNHQ/tc-1.1+/Makefile.vc8
Normal file
143
GLideNHQ/tc-1.1+/Makefile.vc8
Normal file
|
@ -0,0 +1,143 @@
|
||||||
|
# Texture compression Win32 makefile
|
||||||
|
# Version: 1.1+
|
||||||
|
#
|
||||||
|
# Copyright (C) 2004 Daniel Borca All Rights Reserved.
|
||||||
|
#
|
||||||
|
# Copyright (C) 2007 Hiroshi Morii <koolsmoky(at)users.sourceforge.net>
|
||||||
|
# Added support for RGBA input, DXT3,5 workaround for ATI Radeons,
|
||||||
|
# and _mesa_upscale_teximage2d speedup.
|
||||||
|
#
|
||||||
|
# this 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, or (at your option)
|
||||||
|
# any later version.
|
||||||
|
#
|
||||||
|
# this 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 GNU Make; see the file COPYING. If not, write to
|
||||||
|
# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# This makefile MUST be processed by GNU make!!!
|
||||||
|
#
|
||||||
|
# Available options:
|
||||||
|
#
|
||||||
|
# Environment variables:
|
||||||
|
# DEBUG=1 enable debugging checks and messages
|
||||||
|
# default = no
|
||||||
|
# DLL=1 build dll
|
||||||
|
# default = no
|
||||||
|
# ARGB=1 enable support for ARGB inputs
|
||||||
|
# default = no
|
||||||
|
# RADEON=1 enable DXT3,5 workaround for ATI Radeon
|
||||||
|
# default = no
|
||||||
|
# YUV=1 use YUV to determine representative color
|
||||||
|
# default = no
|
||||||
|
#
|
||||||
|
# Targets:
|
||||||
|
# all: build everything
|
||||||
|
# clean: remove object files
|
||||||
|
# realclean: remove all generated files
|
||||||
|
#
|
||||||
|
|
||||||
|
.PHONY: all clean realclean
|
||||||
|
.SUFFIXES: .c .obj
|
||||||
|
|
||||||
|
ifdef DLL
|
||||||
|
DLLNAME = dxtn.dll
|
||||||
|
else
|
||||||
|
ifdef DEBUG
|
||||||
|
DLLNAME = dxtnd.lib
|
||||||
|
else
|
||||||
|
DLLNAME = dxtn.lib
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
CC = cl
|
||||||
|
AS = nasm
|
||||||
|
ifdef DLL
|
||||||
|
LD = _link
|
||||||
|
else
|
||||||
|
LD = lib
|
||||||
|
endif
|
||||||
|
RC = rc
|
||||||
|
|
||||||
|
#ifeq ($(wildcard $(addsuffix /rm.exe,$(subst ;, ,$(PATH)))),)
|
||||||
|
#UNLINK = del $(subst /,\,$(1))
|
||||||
|
#else
|
||||||
|
UNLINK = $(RM) $(1)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
LDFLAGS = -nologo -machine:X86 -nodefaultlib
|
||||||
|
|
||||||
|
ifdef DLL
|
||||||
|
LDFLAGS += -dll -opt:WIN98
|
||||||
|
endif
|
||||||
|
|
||||||
|
ASFLAGS = -O6 -fwin32 -D__WIN32__ --prefix _
|
||||||
|
ASFLAGS += $(CDEFS)
|
||||||
|
|
||||||
|
CFLAGS = -nologo -W3 -WX -D__MSC__=1 -D_CRT_SECURE_NO_DEPRECATE
|
||||||
|
|
||||||
|
ifdef ARGB
|
||||||
|
CFLAGS += -DARGB
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifdef RADEON
|
||||||
|
CFLAGS += -DRADEON
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifdef YUV
|
||||||
|
CFLAGS += -DYUV
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifdef DLL
|
||||||
|
CFLAGS += -D__WIN32__
|
||||||
|
LDLIBS = user32.lib kernel32.lib
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifdef DEBUG
|
||||||
|
CFLAGS += -MTd -Zi -DDEBUG
|
||||||
|
#LDFLAGS += -debug
|
||||||
|
ifdef DLL
|
||||||
|
LDLIBS += LIBCMTD.lib
|
||||||
|
endif
|
||||||
|
OPTFLAGS ?= -Od
|
||||||
|
else
|
||||||
|
CFLAGS += -DNDEBUG -MT -GL
|
||||||
|
LDFLAGS += -ltcg:STATUS
|
||||||
|
ifdef DLL
|
||||||
|
LDLIBS += LIBCMT.lib
|
||||||
|
endif
|
||||||
|
OPTFLAGS ?= -O2
|
||||||
|
endif
|
||||||
|
|
||||||
|
CFLAGS += -I.
|
||||||
|
CFLAGS += $(CDEFS) $(OPTFLAGS)
|
||||||
|
|
||||||
|
SOURCE = \
|
||||||
|
fxt1.c \
|
||||||
|
dxtn.c \
|
||||||
|
wrapper.c \
|
||||||
|
texstore.c
|
||||||
|
|
||||||
|
OBJECTS = $(SOURCE:.c=.obj)
|
||||||
|
|
||||||
|
.c.obj:
|
||||||
|
$(CC) -Fo$@ $(CFLAGS) -c $<
|
||||||
|
|
||||||
|
all: $(DLLNAME)
|
||||||
|
|
||||||
|
$(DLLNAME): $(OBJECTS)
|
||||||
|
$(LD) -out:$@ $(LDFLAGS) $^ $(LDLIBS)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
-$(RM) *.obj
|
||||||
|
|
||||||
|
realclean: clean
|
||||||
|
-$(RM) $(DLLNAME)
|
||||||
|
-$(RM) *.pdb
|
884
GLideNHQ/tc-1.1+/dxtn.c
Normal file
884
GLideNHQ/tc-1.1+/dxtn.c
Normal file
|
@ -0,0 +1,884 @@
|
||||||
|
/*
|
||||||
|
* DXTn codec
|
||||||
|
* Version: 1.1
|
||||||
|
*
|
||||||
|
* Copyright (C) 2004 Daniel Borca All Rights Reserved.
|
||||||
|
*
|
||||||
|
* this 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, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* this 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 GNU Make; see the file COPYING. If not, write to
|
||||||
|
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Copyright (C) 2007 Hiroshi Morii <koolsmoky(at)users.sourceforge.net>
|
||||||
|
* Added support for ARGB inputs, DXT3,5 workaround for ATI Radeons, and
|
||||||
|
* YUV conversions to determine representative colors.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "types.h"
|
||||||
|
#include "internal.h"
|
||||||
|
#include "dxtn.h"
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************\
|
||||||
|
* DXTn encoder
|
||||||
|
*
|
||||||
|
* The encoder was built by reversing the decoder,
|
||||||
|
* and is vaguely based on FXT1 codec. Note that this code
|
||||||
|
* is merely a proof of concept, since it is highly UNoptimized!
|
||||||
|
\***************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
#define MAX_COMP 4 /* ever needed maximum number of components in texel */
|
||||||
|
#define MAX_VECT 4 /* ever needed maximum number of base vectors to find */
|
||||||
|
#define N_TEXELS 16 /* number of texels in a block (always 16) */
|
||||||
|
#define COLOR565(v) (word)((((v)[RCOMP] & 0xf8) << 8) | (((v)[GCOMP] & 0xfc) << 3) | ((v)[BCOMP] >> 3))
|
||||||
|
|
||||||
|
|
||||||
|
static const int dxtn_color_tlat[2][4] = {
|
||||||
|
{ 0, 2, 3, 1 },
|
||||||
|
{ 0, 2, 1, 3 }
|
||||||
|
};
|
||||||
|
|
||||||
|
static const int dxtn_alpha_tlat[2][8] = {
|
||||||
|
{ 0, 2, 3, 4, 5, 6, 7, 1 },
|
||||||
|
{ 0, 2, 3, 4, 5, 1, 6, 7 }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
dxt1_rgb_quantize (dword *cc, const byte *lines[], int comps)
|
||||||
|
{
|
||||||
|
float b, iv[MAX_COMP]; /* interpolation vector */
|
||||||
|
|
||||||
|
dword hi; /* high doubleword */
|
||||||
|
int color0, color1;
|
||||||
|
int n_vect;
|
||||||
|
const int n_comp = 3;
|
||||||
|
int black = 0;
|
||||||
|
|
||||||
|
#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! */
|
||||||
|
|
||||||
|
byte input[N_TEXELS][MAX_COMP];
|
||||||
|
int i, k, l;
|
||||||
|
|
||||||
|
/* make the whole block opaque */
|
||||||
|
/* we will NEVER reference ACOMP of any pixel */
|
||||||
|
|
||||||
|
/* 4 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]++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#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]++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* 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).
|
||||||
|
*/
|
||||||
|
for (k = 0; k < N_TEXELS; k++) {
|
||||||
|
int sum = 0;
|
||||||
|
#ifndef YUV
|
||||||
|
for (i = 0; i < n_comp; i++) {
|
||||||
|
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
|
||||||
|
if (minSum > sum) {
|
||||||
|
minSum = sum;
|
||||||
|
minCol = k;
|
||||||
|
}
|
||||||
|
if (maxSum < sum) {
|
||||||
|
maxSum = sum;
|
||||||
|
maxCol = k;
|
||||||
|
}
|
||||||
|
if (sum == 0) {
|
||||||
|
black = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
color0 = COLOR565(input[minCol]);
|
||||||
|
color1 = COLOR565(input[maxCol]);
|
||||||
|
|
||||||
|
if (color0 == color1) {
|
||||||
|
/* we'll use 3-vector */
|
||||||
|
cc[0] = color0 | (color1 << 16);
|
||||||
|
hi = black ? -1 : 0;
|
||||||
|
} else {
|
||||||
|
if (black && ((color0 == 0) || (color1 == 0))) {
|
||||||
|
/* we still can use 4-vector */
|
||||||
|
black = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (black ^ (color0 <= color1)) {
|
||||||
|
int aux;
|
||||||
|
aux = color0;
|
||||||
|
color0 = color1;
|
||||||
|
color1 = aux;
|
||||||
|
aux = minCol;
|
||||||
|
minCol = maxCol;
|
||||||
|
maxCol = aux;
|
||||||
|
}
|
||||||
|
n_vect = (color0 <= color1) ? 2 : 3;
|
||||||
|
|
||||||
|
MAKEIVEC(n_vect, n_comp, iv, b, input[minCol], input[maxCol]);
|
||||||
|
|
||||||
|
/* add in texels */
|
||||||
|
cc[0] = color0 | (color1 << 16);
|
||||||
|
hi = 0;
|
||||||
|
for (k = N_TEXELS - 1; k >= 0; k--) {
|
||||||
|
int texel = 3;
|
||||||
|
int sum = 0;
|
||||||
|
if (black) {
|
||||||
|
for (i = 0; i < n_comp; i++) {
|
||||||
|
sum += input[k][i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!black || sum) {
|
||||||
|
/* interpolate color */
|
||||||
|
CALCCDOT(texel, n_vect, n_comp, iv, b, input[k]);
|
||||||
|
texel = dxtn_color_tlat[black][texel];
|
||||||
|
}
|
||||||
|
/* add in texel */
|
||||||
|
hi <<= 2;
|
||||||
|
hi |= texel;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cc[1] = hi;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
dxt1_rgba_quantize (dword *cc, const byte *lines[], int comps)
|
||||||
|
{
|
||||||
|
float b, iv[MAX_COMP]; /* interpolation vector */
|
||||||
|
|
||||||
|
dword hi; /* high doubleword */
|
||||||
|
int color0, color1;
|
||||||
|
int n_vect;
|
||||||
|
const int n_comp = 3;
|
||||||
|
int transparent = 0;
|
||||||
|
|
||||||
|
#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! */
|
||||||
|
|
||||||
|
byte input[N_TEXELS][MAX_COMP];
|
||||||
|
int i, k, l;
|
||||||
|
|
||||||
|
if (comps == 3) {
|
||||||
|
/* make the whole block opaque */
|
||||||
|
memset(input, -1, sizeof(input));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 4 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]++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#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]++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* 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).
|
||||||
|
*/
|
||||||
|
for (k = 0; 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;
|
||||||
|
minCol = k;
|
||||||
|
}
|
||||||
|
if (maxSum < sum) {
|
||||||
|
maxSum = sum;
|
||||||
|
maxCol = k;
|
||||||
|
}
|
||||||
|
if (input[k][ACOMP] < 128) {
|
||||||
|
transparent = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
color0 = COLOR565(input[minCol]);
|
||||||
|
color1 = COLOR565(input[maxCol]);
|
||||||
|
|
||||||
|
if (color0 == color1) {
|
||||||
|
/* we'll use 3-vector */
|
||||||
|
cc[0] = color0 | (color1 << 16);
|
||||||
|
hi = transparent ? -1 : 0;
|
||||||
|
} else {
|
||||||
|
if (transparent ^ (color0 <= color1)) {
|
||||||
|
int aux;
|
||||||
|
aux = color0;
|
||||||
|
color0 = color1;
|
||||||
|
color1 = aux;
|
||||||
|
aux = minCol;
|
||||||
|
minCol = maxCol;
|
||||||
|
maxCol = aux;
|
||||||
|
}
|
||||||
|
n_vect = (color0 <= color1) ? 2 : 3;
|
||||||
|
|
||||||
|
MAKEIVEC(n_vect, n_comp, iv, b, input[minCol], input[maxCol]);
|
||||||
|
|
||||||
|
/* add in texels */
|
||||||
|
cc[0] = color0 | (color1 << 16);
|
||||||
|
hi = 0;
|
||||||
|
for (k = N_TEXELS - 1; k >= 0; k--) {
|
||||||
|
int texel = 3;
|
||||||
|
if (input[k][ACOMP] >= 128) {
|
||||||
|
/* interpolate color */
|
||||||
|
CALCCDOT(texel, n_vect, n_comp, iv, b, input[k]);
|
||||||
|
texel = dxtn_color_tlat[transparent][texel];
|
||||||
|
}
|
||||||
|
/* add in texel */
|
||||||
|
hi <<= 2;
|
||||||
|
hi |= texel;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cc[1] = hi;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
dxt3_rgba_quantize (dword *cc, const byte *lines[], int comps)
|
||||||
|
{
|
||||||
|
float b, iv[MAX_COMP]; /* interpolation vector */
|
||||||
|
|
||||||
|
dword lolo, lohi; /* low quadword: lo dword, hi dword */
|
||||||
|
dword hihi; /* high quadword: high dword */
|
||||||
|
int color0, color1;
|
||||||
|
const int n_vect = 3;
|
||||||
|
const int n_comp = 3;
|
||||||
|
|
||||||
|
#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! */
|
||||||
|
|
||||||
|
byte input[N_TEXELS][MAX_COMP];
|
||||||
|
int i, k, l;
|
||||||
|
|
||||||
|
if (comps == 3) {
|
||||||
|
/* make the whole block opaque */
|
||||||
|
memset(input, -1, sizeof(input));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 4 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]++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#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]++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* 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).
|
||||||
|
*/
|
||||||
|
for (k = 0; 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;
|
||||||
|
minCol = k;
|
||||||
|
}
|
||||||
|
if (maxSum < sum) {
|
||||||
|
maxSum = sum;
|
||||||
|
maxCol = k;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* add in alphas */
|
||||||
|
lolo = lohi = 0;
|
||||||
|
for (k = N_TEXELS - 1; k >= N_TEXELS / 2; k--) {
|
||||||
|
/* add in alpha */
|
||||||
|
lohi <<= 4;
|
||||||
|
lohi |= input[k][ACOMP] >> 4;
|
||||||
|
}
|
||||||
|
cc[1] = lohi;
|
||||||
|
for (; k >= 0; k--) {
|
||||||
|
/* add in alpha */
|
||||||
|
lolo <<= 4;
|
||||||
|
lolo |= input[k][ACOMP] >> 4;
|
||||||
|
}
|
||||||
|
cc[0] = lolo;
|
||||||
|
|
||||||
|
color0 = COLOR565(input[minCol]);
|
||||||
|
color1 = COLOR565(input[maxCol]);
|
||||||
|
|
||||||
|
#ifdef RADEON
|
||||||
|
/* H.Morii - Workaround for ATI Radeon
|
||||||
|
* According to the OpenGL EXT_texture_compression_s3tc specs,
|
||||||
|
* the encoding of the RGB components for DXT3 and DXT5 formats
|
||||||
|
* use the non-transparent encodings of DXT1 but treated as
|
||||||
|
* though color0 > color1, regardless of the actual values of
|
||||||
|
* color0 and color1. ATI Radeons however require the values to
|
||||||
|
* be color0 > color1.
|
||||||
|
*/
|
||||||
|
if (color0 < color1) {
|
||||||
|
int aux;
|
||||||
|
aux = color0;
|
||||||
|
color0 = color1;
|
||||||
|
color1 = aux;
|
||||||
|
aux = minCol;
|
||||||
|
minCol = maxCol;
|
||||||
|
maxCol = aux;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
cc[2] = color0 | (color1 << 16);
|
||||||
|
|
||||||
|
hihi = 0;
|
||||||
|
if (color0 != color1) {
|
||||||
|
MAKEIVEC(n_vect, n_comp, iv, b, input[minCol], input[maxCol]);
|
||||||
|
|
||||||
|
/* add in texels */
|
||||||
|
for (k = N_TEXELS - 1; k >= 0; k--) {
|
||||||
|
int texel;
|
||||||
|
/* interpolate color */
|
||||||
|
CALCCDOT(texel, n_vect, n_comp, iv, b, input[k]);
|
||||||
|
texel = dxtn_color_tlat[0][texel];
|
||||||
|
/* add in texel */
|
||||||
|
hihi <<= 2;
|
||||||
|
hihi |= texel;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cc[3] = hihi;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
dxt5_rgba_quantize (dword *cc, const byte *lines[], int comps)
|
||||||
|
{
|
||||||
|
float b, iv[MAX_COMP]; /* interpolation vector */
|
||||||
|
|
||||||
|
qword lo; /* low quadword */
|
||||||
|
dword hihi; /* high quadword: high dword */
|
||||||
|
int color0, color1;
|
||||||
|
const int n_vect = 3;
|
||||||
|
const int n_comp = 3;
|
||||||
|
|
||||||
|
#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 alpha0 = 2000; /* big enough */
|
||||||
|
int alpha1 = -1; /* small enough */
|
||||||
|
int anyZero = 0, anyOne = 0;
|
||||||
|
int a_vect;
|
||||||
|
|
||||||
|
byte input[N_TEXELS][MAX_COMP];
|
||||||
|
int i, k, l;
|
||||||
|
|
||||||
|
if (comps == 3) {
|
||||||
|
/* make the whole block opaque */
|
||||||
|
memset(input, -1, sizeof(input));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 4 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]++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#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]++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* 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).
|
||||||
|
*/
|
||||||
|
for (k = 0; 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;
|
||||||
|
minCol = k;
|
||||||
|
}
|
||||||
|
if (maxSum < sum) {
|
||||||
|
maxSum = sum;
|
||||||
|
maxCol = k;
|
||||||
|
}
|
||||||
|
if (alpha0 > input[k][ACOMP]) {
|
||||||
|
alpha0 = input[k][ACOMP];
|
||||||
|
}
|
||||||
|
if (alpha1 < input[k][ACOMP]) {
|
||||||
|
alpha1 = input[k][ACOMP];
|
||||||
|
}
|
||||||
|
if (input[k][ACOMP] == 0) {
|
||||||
|
anyZero = 1;
|
||||||
|
}
|
||||||
|
if (input[k][ACOMP] == 255) {
|
||||||
|
anyOne = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* add in alphas */
|
||||||
|
if (alpha0 == alpha1) {
|
||||||
|
/* we'll use 6-vector */
|
||||||
|
cc[0] = alpha0 | (alpha1 << 8);
|
||||||
|
cc[1] = 0;
|
||||||
|
} else {
|
||||||
|
if (anyZero && ((alpha0 == 0) || (alpha1 == 0))) {
|
||||||
|
/* we still might use 8-vector */
|
||||||
|
anyZero = 0;
|
||||||
|
}
|
||||||
|
if (anyOne && ((alpha0 == 255) || (alpha1 == 255))) {
|
||||||
|
/* we still might use 8-vector */
|
||||||
|
anyOne = 0;
|
||||||
|
}
|
||||||
|
if ((anyZero | anyOne) ^ (alpha0 <= alpha1)) {
|
||||||
|
int aux;
|
||||||
|
aux = alpha0;
|
||||||
|
alpha0 = alpha1;
|
||||||
|
alpha1 = aux;
|
||||||
|
}
|
||||||
|
a_vect = (alpha0 <= alpha1) ? 5 : 7;
|
||||||
|
|
||||||
|
/* compute interpolation vector */
|
||||||
|
iv[ACOMP] = (float)a_vect / (alpha1 - alpha0);
|
||||||
|
b = -iv[ACOMP] * alpha0 + 0.5F;
|
||||||
|
|
||||||
|
/* add in alphas */
|
||||||
|
Q_MOV32(lo, 0);
|
||||||
|
for (k = N_TEXELS - 1; k >= 0; k--) {
|
||||||
|
int texel = -1;
|
||||||
|
if (anyZero | anyOne) {
|
||||||
|
if (input[k][ACOMP] == 0) {
|
||||||
|
texel = 6;
|
||||||
|
} else if (input[k][ACOMP] == 255) {
|
||||||
|
texel = 7;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* interpolate alpha */
|
||||||
|
if (texel == -1) {
|
||||||
|
float dot = input[k][ACOMP] * iv[ACOMP];
|
||||||
|
texel = (int)(dot + b);
|
||||||
|
#if SAFECDOT
|
||||||
|
if (texel < 0) {
|
||||||
|
texel = 0;
|
||||||
|
} else if (texel > a_vect) {
|
||||||
|
texel = a_vect;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
texel = dxtn_alpha_tlat[anyZero | anyOne][texel];
|
||||||
|
}
|
||||||
|
/* add in texel */
|
||||||
|
Q_SHL(lo, 3);
|
||||||
|
Q_OR32(lo, texel);
|
||||||
|
}
|
||||||
|
Q_SHL(lo, 16);
|
||||||
|
Q_OR32(lo, alpha0 | (alpha1 << 8));
|
||||||
|
((qword *)cc)[0] = lo;
|
||||||
|
}
|
||||||
|
|
||||||
|
color0 = COLOR565(input[minCol]);
|
||||||
|
color1 = COLOR565(input[maxCol]);
|
||||||
|
|
||||||
|
#ifdef RADEON /* H.Morii - Workaround for ATI Radeon */
|
||||||
|
if (color0 < color1) {
|
||||||
|
int aux;
|
||||||
|
aux = color0;
|
||||||
|
color0 = color1;
|
||||||
|
color1 = aux;
|
||||||
|
aux = minCol;
|
||||||
|
minCol = maxCol;
|
||||||
|
maxCol = aux;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
cc[2] = color0 | (color1 << 16);
|
||||||
|
|
||||||
|
hihi = 0;
|
||||||
|
if (color0 != color1) {
|
||||||
|
MAKEIVEC(n_vect, n_comp, iv, b, input[minCol], input[maxCol]);
|
||||||
|
|
||||||
|
/* add in texels */
|
||||||
|
for (k = N_TEXELS - 1; k >= 0; k--) {
|
||||||
|
int texel;
|
||||||
|
/* interpolate color */
|
||||||
|
CALCCDOT(texel, n_vect, n_comp, iv, b, input[k]);
|
||||||
|
texel = dxtn_color_tlat[0][texel];
|
||||||
|
/* add in texel */
|
||||||
|
hihi <<= 2;
|
||||||
|
hihi |= texel;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cc[3] = hihi;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define ENCODER(dxtn, n) \
|
||||||
|
int TAPIENTRY \
|
||||||
|
dxtn##_encode (int width, int height, int comps, \
|
||||||
|
const void *source, int srcRowStride, \
|
||||||
|
void *dest, int destRowStride) \
|
||||||
|
{ \
|
||||||
|
int x, y; \
|
||||||
|
const byte *data; \
|
||||||
|
dword *encoded = (dword *)dest; \
|
||||||
|
void *newSource = NULL; \
|
||||||
|
\
|
||||||
|
/* Replicate image if width is not M4 or height is not M4 */ \
|
||||||
|
if ((width & 3) | (height & 3)) { \
|
||||||
|
int newWidth = (width + 3) & ~3; \
|
||||||
|
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; \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
data = (const byte *)source; \
|
||||||
|
destRowStride = (destRowStride - width * n) / 4; \
|
||||||
|
for (y = 0; y < height; y += 4) { \
|
||||||
|
unsigned int offs = 0 + (y + 0) * srcRowStride; \
|
||||||
|
for (x = 0; x < width; x += 4) { \
|
||||||
|
const byte *lines[4]; \
|
||||||
|
lines[0] = &data[offs]; \
|
||||||
|
lines[1] = lines[0] + srcRowStride; \
|
||||||
|
lines[2] = lines[1] + srcRowStride; \
|
||||||
|
lines[3] = lines[2] + srcRowStride; \
|
||||||
|
offs += 4 * comps; \
|
||||||
|
dxtn##_quantize(encoded, lines, comps); \
|
||||||
|
/* 4x4 block */ \
|
||||||
|
encoded += n; \
|
||||||
|
} \
|
||||||
|
encoded += destRowStride; \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
if (newSource != NULL) { \
|
||||||
|
free(newSource); \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
return 0; \
|
||||||
|
}
|
||||||
|
|
||||||
|
ENCODER(dxt1_rgb, 2)
|
||||||
|
ENCODER(dxt1_rgba, 2)
|
||||||
|
ENCODER(dxt3_rgba, 4)
|
||||||
|
ENCODER(dxt5_rgba, 4)
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************\
|
||||||
|
* DXTn decoder
|
||||||
|
*
|
||||||
|
* The decoder is based on GL_EXT_texture_compression_s3tc
|
||||||
|
* specification and serves as a concept for the encoder.
|
||||||
|
\***************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/* lookup table for scaling 4 bit colors up to 8 bits */
|
||||||
|
static const byte _rgb_scale_4[] = {
|
||||||
|
0, 17, 34, 51, 68, 85, 102, 119,
|
||||||
|
136, 153, 170, 187, 204, 221, 238, 255
|
||||||
|
};
|
||||||
|
|
||||||
|
/* 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
|
||||||
|
};
|
||||||
|
|
||||||
|
/* 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
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#define CC_SEL(cc, which) (((dword *)(cc))[(which) / 32] >> ((which) & 31))
|
||||||
|
#define UP4(c) _rgb_scale_4[(c) & 15]
|
||||||
|
#define UP5(c) _rgb_scale_5[(c) & 31]
|
||||||
|
#define UP6(c) _rgb_scale_6[(c) & 63]
|
||||||
|
#define ZERO_4UBV(v) *((dword *)(v)) = 0
|
||||||
|
|
||||||
|
|
||||||
|
void TAPIENTRY
|
||||||
|
dxt1_rgb_decode_1 (const void *texture, int stride,
|
||||||
|
int i, int j, byte *rgba)
|
||||||
|
{
|
||||||
|
const byte *src = (const byte *)texture
|
||||||
|
+ ((j / 4) * ((stride + 3) / 4) + i / 4) * 8;
|
||||||
|
const int code = (src[4 + (j & 3)] >> ((i & 3) * 2)) & 0x3;
|
||||||
|
if (code == 0) {
|
||||||
|
rgba[RCOMP] = UP5(CC_SEL(src, 11));
|
||||||
|
rgba[GCOMP] = UP6(CC_SEL(src, 5));
|
||||||
|
rgba[BCOMP] = UP5(CC_SEL(src, 0));
|
||||||
|
} else if (code == 1) {
|
||||||
|
rgba[RCOMP] = UP5(CC_SEL(src, 27));
|
||||||
|
rgba[GCOMP] = UP6(CC_SEL(src, 21));
|
||||||
|
rgba[BCOMP] = UP5(CC_SEL(src, 16));
|
||||||
|
} else {
|
||||||
|
const word col0 = src[0] | (src[1] << 8);
|
||||||
|
const word col1 = src[2] | (src[3] << 8);
|
||||||
|
if (col0 > col1) {
|
||||||
|
if (code == 2) {
|
||||||
|
rgba[RCOMP] = (UP5(col0 >> 11) * 2 + UP5(col1 >> 11)) / 3;
|
||||||
|
rgba[GCOMP] = (UP6(col0 >> 5) * 2 + UP6(col1 >> 5)) / 3;
|
||||||
|
rgba[BCOMP] = (UP5(col0 ) * 2 + UP5(col1 )) / 3;
|
||||||
|
} else {
|
||||||
|
rgba[RCOMP] = (UP5(col0 >> 11) + 2 * UP5(col1 >> 11)) / 3;
|
||||||
|
rgba[GCOMP] = (UP6(col0 >> 5) + 2 * UP6(col1 >> 5)) / 3;
|
||||||
|
rgba[BCOMP] = (UP5(col0 ) + 2 * UP5(col1 )) / 3;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (code == 2) {
|
||||||
|
rgba[RCOMP] = (UP5(col0 >> 11) + UP5(col1 >> 11)) / 2;
|
||||||
|
rgba[GCOMP] = (UP6(col0 >> 5) + UP6(col1 >> 5)) / 2;
|
||||||
|
rgba[BCOMP] = (UP5(col0 ) + UP5(col1 )) / 2;
|
||||||
|
} else {
|
||||||
|
ZERO_4UBV(rgba);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rgba[ACOMP] = 255;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void TAPIENTRY
|
||||||
|
dxt1_rgba_decode_1 (const void *texture, int stride,
|
||||||
|
int i, int j, byte *rgba)
|
||||||
|
{
|
||||||
|
/* Same as rgb_dxt1 above, except alpha=0 if col0<=col1 and code=3. */
|
||||||
|
const byte *src = (const byte *)texture
|
||||||
|
+ ((j / 4) * ((stride + 3) / 4) + i / 4) * 8;
|
||||||
|
const int code = (src[4 + (j & 3)] >> ((i & 3) * 2)) & 0x3;
|
||||||
|
if (code == 0) {
|
||||||
|
rgba[RCOMP] = UP5(CC_SEL(src, 11));
|
||||||
|
rgba[GCOMP] = UP6(CC_SEL(src, 5));
|
||||||
|
rgba[BCOMP] = UP5(CC_SEL(src, 0));
|
||||||
|
rgba[ACOMP] = 255;
|
||||||
|
} else if (code == 1) {
|
||||||
|
rgba[RCOMP] = UP5(CC_SEL(src, 27));
|
||||||
|
rgba[GCOMP] = UP6(CC_SEL(src, 21));
|
||||||
|
rgba[BCOMP] = UP5(CC_SEL(src, 16));
|
||||||
|
rgba[ACOMP] = 255;
|
||||||
|
} else {
|
||||||
|
const word col0 = src[0] | (src[1] << 8);
|
||||||
|
const word col1 = src[2] | (src[3] << 8);
|
||||||
|
if (col0 > col1) {
|
||||||
|
if (code == 2) {
|
||||||
|
rgba[RCOMP] = (UP5(col0 >> 11) * 2 + UP5(col1 >> 11)) / 3;
|
||||||
|
rgba[GCOMP] = (UP6(col0 >> 5) * 2 + UP6(col1 >> 5)) / 3;
|
||||||
|
rgba[BCOMP] = (UP5(col0 ) * 2 + UP5(col1 )) / 3;
|
||||||
|
} else {
|
||||||
|
rgba[RCOMP] = (UP5(col0 >> 11) + 2 * UP5(col1 >> 11)) / 3;
|
||||||
|
rgba[GCOMP] = (UP6(col0 >> 5) + 2 * UP6(col1 >> 5)) / 3;
|
||||||
|
rgba[BCOMP] = (UP5(col0 ) + 2 * UP5(col1 )) / 3;
|
||||||
|
}
|
||||||
|
rgba[ACOMP] = 255;
|
||||||
|
} else {
|
||||||
|
if (code == 2) {
|
||||||
|
rgba[RCOMP] = (UP5(col0 >> 11) + UP5(col1 >> 11)) / 2;
|
||||||
|
rgba[GCOMP] = (UP6(col0 >> 5) + UP6(col1 >> 5)) / 2;
|
||||||
|
rgba[BCOMP] = (UP5(col0 ) + UP5(col1 )) / 2;
|
||||||
|
rgba[ACOMP] = 255;
|
||||||
|
} else {
|
||||||
|
ZERO_4UBV(rgba);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void TAPIENTRY
|
||||||
|
dxt3_rgba_decode_1 (const void *texture, int stride,
|
||||||
|
int i, int j, byte *rgba)
|
||||||
|
{
|
||||||
|
const byte *src = (const byte *)texture
|
||||||
|
+ ((j / 4) * ((stride + 3) / 4) + i / 4) * 16;
|
||||||
|
const int code = (src[12 + (j & 3)] >> ((i & 3) * 2)) & 0x3;
|
||||||
|
const dword *cc = (const dword *)(src + 8);
|
||||||
|
if (code == 0) {
|
||||||
|
rgba[RCOMP] = UP5(CC_SEL(cc, 11));
|
||||||
|
rgba[GCOMP] = UP6(CC_SEL(cc, 5));
|
||||||
|
rgba[BCOMP] = UP5(CC_SEL(cc, 0));
|
||||||
|
} else if (code == 1) {
|
||||||
|
rgba[RCOMP] = UP5(CC_SEL(cc, 27));
|
||||||
|
rgba[GCOMP] = UP6(CC_SEL(cc, 21));
|
||||||
|
rgba[BCOMP] = UP5(CC_SEL(cc, 16));
|
||||||
|
} else if (code == 2) {
|
||||||
|
/* (col0 * (4 - code) + col1 * (code - 1)) / 3 */
|
||||||
|
rgba[RCOMP] = (UP5(CC_SEL(cc, 11)) * 2 + UP5(CC_SEL(cc, 27))) / 3;
|
||||||
|
rgba[GCOMP] = (UP6(CC_SEL(cc, 5)) * 2 + UP6(CC_SEL(cc, 21))) / 3;
|
||||||
|
rgba[BCOMP] = (UP5(CC_SEL(cc, 0)) * 2 + UP5(CC_SEL(cc, 16))) / 3;
|
||||||
|
} else {
|
||||||
|
rgba[RCOMP] = (UP5(CC_SEL(cc, 11)) + 2 * UP5(CC_SEL(cc, 27))) / 3;
|
||||||
|
rgba[GCOMP] = (UP6(CC_SEL(cc, 5)) + 2 * UP6(CC_SEL(cc, 21))) / 3;
|
||||||
|
rgba[BCOMP] = (UP5(CC_SEL(cc, 0)) + 2 * UP5(CC_SEL(cc, 16))) / 3;
|
||||||
|
}
|
||||||
|
rgba[ACOMP] = UP4(src[((j & 3) * 4 + (i & 3)) / 2] >> ((i & 1) * 4));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void TAPIENTRY
|
||||||
|
dxt5_rgba_decode_1 (const void *texture, int stride,
|
||||||
|
int i, int j, byte *rgba)
|
||||||
|
{
|
||||||
|
const byte *src = (const byte *)texture
|
||||||
|
+ ((j / 4) * ((stride + 3) / 4) + i / 4) * 16;
|
||||||
|
const int code = (src[12 + (j & 3)] >> ((i & 3) * 2)) & 0x3;
|
||||||
|
const dword *cc = (const dword *)(src + 8);
|
||||||
|
const byte alpha0 = src[0];
|
||||||
|
const byte alpha1 = src[1];
|
||||||
|
const int alphaShift = (((j & 3) * 4) + (i & 3)) * 3 + 16;
|
||||||
|
const int acode = ((alphaShift == 31)
|
||||||
|
? CC_SEL(src + 2, alphaShift - 16)
|
||||||
|
: CC_SEL(src, alphaShift)) & 0x7;
|
||||||
|
if (code == 0) {
|
||||||
|
rgba[RCOMP] = UP5(CC_SEL(cc, 11));
|
||||||
|
rgba[GCOMP] = UP6(CC_SEL(cc, 5));
|
||||||
|
rgba[BCOMP] = UP5(CC_SEL(cc, 0));
|
||||||
|
} else if (code == 1) {
|
||||||
|
rgba[RCOMP] = UP5(CC_SEL(cc, 27));
|
||||||
|
rgba[GCOMP] = UP6(CC_SEL(cc, 21));
|
||||||
|
rgba[BCOMP] = UP5(CC_SEL(cc, 16));
|
||||||
|
} else if (code == 2) {
|
||||||
|
/* (col0 * (4 - code) + col1 * (code - 1)) / 3 */
|
||||||
|
rgba[RCOMP] = (UP5(CC_SEL(cc, 11)) * 2 + UP5(CC_SEL(cc, 27))) / 3;
|
||||||
|
rgba[GCOMP] = (UP6(CC_SEL(cc, 5)) * 2 + UP6(CC_SEL(cc, 21))) / 3;
|
||||||
|
rgba[BCOMP] = (UP5(CC_SEL(cc, 0)) * 2 + UP5(CC_SEL(cc, 16))) / 3;
|
||||||
|
} else {
|
||||||
|
rgba[RCOMP] = (UP5(CC_SEL(cc, 11)) + 2 * UP5(CC_SEL(cc, 27))) / 3;
|
||||||
|
rgba[GCOMP] = (UP6(CC_SEL(cc, 5)) + 2 * UP6(CC_SEL(cc, 21))) / 3;
|
||||||
|
rgba[BCOMP] = (UP5(CC_SEL(cc, 0)) + 2 * UP5(CC_SEL(cc, 16))) / 3;
|
||||||
|
}
|
||||||
|
if (acode == 0) {
|
||||||
|
rgba[ACOMP] = alpha0;
|
||||||
|
} else if (acode == 1) {
|
||||||
|
rgba[ACOMP] = alpha1;
|
||||||
|
} else if (alpha0 > alpha1) {
|
||||||
|
rgba[ACOMP] = ((8 - acode) * alpha0 + (acode - 1) * alpha1) / 7;
|
||||||
|
} else if (acode == 6) {
|
||||||
|
rgba[ACOMP] = 0;
|
||||||
|
} else if (acode == 7) {
|
||||||
|
rgba[ACOMP] = 255;
|
||||||
|
} else {
|
||||||
|
rgba[ACOMP] = ((6 - acode) * alpha0 + (acode - 1) * alpha1) / 5;
|
||||||
|
}
|
||||||
|
}
|
62
GLideNHQ/tc-1.1+/dxtn.h
Normal file
62
GLideNHQ/tc-1.1+/dxtn.h
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
/*
|
||||||
|
* DXTn codec
|
||||||
|
* Version: 1.1
|
||||||
|
*
|
||||||
|
* Copyright (C) 2004 Daniel Borca All Rights Reserved.
|
||||||
|
*
|
||||||
|
* this 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, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* this 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 GNU Make; see the file COPYING. If not, write to
|
||||||
|
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef DXTN_H_included
|
||||||
|
#define DXTN_H_included
|
||||||
|
|
||||||
|
TAPI int TAPIENTRY
|
||||||
|
dxt1_rgb_encode (int width, int height, int comps,
|
||||||
|
const void *source, int srcRowStride,
|
||||||
|
void *dest, int destRowStride);
|
||||||
|
|
||||||
|
TAPI int TAPIENTRY
|
||||||
|
dxt1_rgba_encode (int width, int height, int comps,
|
||||||
|
const void *source, int srcRowStride,
|
||||||
|
void *dest, int destRowStride);
|
||||||
|
|
||||||
|
TAPI int TAPIENTRY
|
||||||
|
dxt3_rgba_encode (int width, int height, int comps,
|
||||||
|
const void *source, int srcRowStride,
|
||||||
|
void *dest, int destRowStride);
|
||||||
|
|
||||||
|
TAPI int TAPIENTRY
|
||||||
|
dxt5_rgba_encode (int width, int height, int comps,
|
||||||
|
const void *source, int srcRowStride,
|
||||||
|
void *dest, int destRowStride);
|
||||||
|
|
||||||
|
TAPI void TAPIENTRY
|
||||||
|
dxt1_rgb_decode_1 (const void *texture, int stride /* in pixels */,
|
||||||
|
int i, int j, byte *rgba);
|
||||||
|
|
||||||
|
TAPI void TAPIENTRY
|
||||||
|
dxt1_rgba_decode_1 (const void *texture, int stride /* in pixels */,
|
||||||
|
int i, int j, byte *rgba);
|
||||||
|
|
||||||
|
TAPI void TAPIENTRY
|
||||||
|
dxt3_rgba_decode_1 (const void *texture, int stride /* in pixels */,
|
||||||
|
int i, int j, byte *rgba);
|
||||||
|
|
||||||
|
TAPI void TAPIENTRY
|
||||||
|
dxt5_rgba_decode_1 (const void *texture, int stride /* in pixels */,
|
||||||
|
int i, int j, byte *rgba);
|
||||||
|
|
||||||
|
#endif
|
1459
GLideNHQ/tc-1.1+/fxt1.c
Normal file
1459
GLideNHQ/tc-1.1+/fxt1.c
Normal file
File diff suppressed because it is too large
Load Diff
38
GLideNHQ/tc-1.1+/fxt1.h
Normal file
38
GLideNHQ/tc-1.1+/fxt1.h
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
/*
|
||||||
|
* FXT1 codec
|
||||||
|
* Version: 1.1
|
||||||
|
*
|
||||||
|
* Copyright (C) 2004 Daniel Borca 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"),
|
||||||
|
* to deal in the Software without restriction, including without limitation
|
||||||
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
* and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
* Software is furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included
|
||||||
|
* in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef FXT1_H_included
|
||||||
|
#define FXT1_H_included
|
||||||
|
|
||||||
|
TAPI int TAPIENTRY
|
||||||
|
fxt1_encode (int width, 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);
|
||||||
|
|
||||||
|
#endif
|
244
GLideNHQ/tc-1.1+/fxt1license.txt
Normal file
244
GLideNHQ/tc-1.1+/fxt1license.txt
Normal file
|
@ -0,0 +1,244 @@
|
||||||
|
3DFX FXT1 Source Code General Public License
|
||||||
|
|
||||||
|
|
||||||
|
1. PREAMBLE
|
||||||
|
|
||||||
|
This license is for software that provides texture compression and
|
||||||
|
decompression, particularly in the context of video games. 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 FXT1 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 FXT1 Source Code General
|
||||||
|
Public License.
|
||||||
|
|
||||||
|
2.2 The term "Program" as used in this Agreement refers to 3DFX's
|
||||||
|
FXT1 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 texture compression and decompression. 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 FXT1 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) 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) 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. SEE THE 3DFX FXT1 GENERAL PUBLIC LICENSE
|
||||||
|
FOR A FULL TEXT OF THE DISTRIBUTION AND NON-WARRANTY PROVISIONS
|
||||||
|
(REQUEST COPY FROM INFO@3DFX.COM)."
|
||||||
|
|
||||||
|
(g) 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 FXT1 GENERAL PUBLIC LICENSE. 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 FXT1 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 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.
|
||||||
|
|
137
GLideNHQ/tc-1.1+/internal.h
Normal file
137
GLideNHQ/tc-1.1+/internal.h
Normal file
|
@ -0,0 +1,137 @@
|
||||||
|
/*
|
||||||
|
* Texture compression
|
||||||
|
* Version: 1.0
|
||||||
|
*
|
||||||
|
* Copyright (C) 2004 Daniel Borca All Rights Reserved.
|
||||||
|
*
|
||||||
|
* this 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, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* this 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 GNU Make; see the file COPYING. If not, write to
|
||||||
|
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef INTERNAL_H_included
|
||||||
|
#define INTERNAL_H_included
|
||||||
|
|
||||||
|
/*****************************************************************************\
|
||||||
|
* DLL stuff
|
||||||
|
\*****************************************************************************/
|
||||||
|
|
||||||
|
#ifdef __WIN32__
|
||||||
|
#define TAPI __declspec(dllexport)
|
||||||
|
#define TAPIENTRY /*__stdcall*/
|
||||||
|
#else
|
||||||
|
#define TAPI
|
||||||
|
#define TAPIENTRY
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************\
|
||||||
|
* 64bit types on 32bit machine
|
||||||
|
\*****************************************************************************/
|
||||||
|
|
||||||
|
#if (defined(__GNUC__) && !defined(__cplusplus)) || defined(__MSC__)
|
||||||
|
|
||||||
|
typedef unsigned long long qword;
|
||||||
|
|
||||||
|
#define Q_MOV32(a, b) a = b
|
||||||
|
#define Q_OR32(a, b) a |= b
|
||||||
|
#define Q_SHL(a, c) a <<= c
|
||||||
|
|
||||||
|
#else /* !__GNUC__ */
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
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__ */
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************\
|
||||||
|
* Config
|
||||||
|
\*****************************************************************************/
|
||||||
|
|
||||||
|
#define RCOMP 0
|
||||||
|
#define GCOMP 1
|
||||||
|
#define BCOMP 2
|
||||||
|
#define ACOMP 3
|
||||||
|
|
||||||
|
/*****************************************************************************\
|
||||||
|
* Metric
|
||||||
|
\*****************************************************************************/
|
||||||
|
|
||||||
|
#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 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)
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************\
|
||||||
|
* Utility functions
|
||||||
|
\*****************************************************************************/
|
||||||
|
|
||||||
|
void
|
||||||
|
_mesa_upscale_teximage2d (unsigned int inWidth, unsigned int inHeight,
|
||||||
|
unsigned int outWidth, unsigned int outHeight,
|
||||||
|
unsigned int comps,
|
||||||
|
const byte *src, int srcRowStride,
|
||||||
|
unsigned char *dest);
|
||||||
|
|
||||||
|
#endif
|
93
GLideNHQ/tc-1.1+/texstore.c
Normal file
93
GLideNHQ/tc-1.1+/texstore.c
Normal file
|
@ -0,0 +1,93 @@
|
||||||
|
/*
|
||||||
|
* Mesa 3-D graphics library
|
||||||
|
* Version: 6.3
|
||||||
|
*
|
||||||
|
* Copyright (C) 1999-2004 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"),
|
||||||
|
* to deal in the Software without restriction, including without limitation
|
||||||
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
* and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
* Software is furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included
|
||||||
|
* in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
* BRIAN PAUL 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 <koolsmoky(at)users.sourceforge.net>
|
||||||
|
* _mesa_upscale_teximage2d speedup
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
#include "types.h"
|
||||||
|
#include "internal.h"
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
_mesa_upscale_teximage2d (unsigned int inWidth, unsigned int inHeight,
|
||||||
|
unsigned int outWidth, unsigned int outHeight,
|
||||||
|
unsigned int comps,
|
||||||
|
const byte *src, int srcRowStride,
|
||||||
|
byte *dest)
|
||||||
|
{
|
||||||
|
unsigned int i, j, k;
|
||||||
|
|
||||||
|
assert(outWidth >= inWidth);
|
||||||
|
assert(outHeight >= inHeight);
|
||||||
|
|
||||||
|
#if 1 /* H.Morii - faster loops */
|
||||||
|
for (i = 0; i < inHeight; i++) {
|
||||||
|
for (j = 0; j < inWidth; j++) {
|
||||||
|
const int aa = (i * outWidth + j) * comps;
|
||||||
|
const int bb = i * srcRowStride + j * comps;
|
||||||
|
for (k = 0; k < comps; k++) {
|
||||||
|
dest[aa + k] = src[bb + k];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (; j < outWidth; j++) {
|
||||||
|
const int aa = (i * outWidth + j) * comps;
|
||||||
|
const int bb = i * srcRowStride + (j - inWidth) * comps;
|
||||||
|
for (k = 0; k < comps; k++) {
|
||||||
|
dest[aa + k] = src[bb + k];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (; i < outHeight; i++) {
|
||||||
|
for (j = 0; j < inWidth; j++) {
|
||||||
|
const int aa = (i * outWidth + j) * comps;
|
||||||
|
const int bb = (i - inHeight) * srcRowStride + j * comps;
|
||||||
|
for (k = 0; k < comps; k++) {
|
||||||
|
dest[aa + k] = src[bb + k];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (; j < outWidth; j++) {
|
||||||
|
const int aa = (i * outWidth + j) * comps;
|
||||||
|
const int bb = (i - inHeight) * srcRowStride + (j - inWidth) * comps;
|
||||||
|
for (k = 0; k < comps; k++) {
|
||||||
|
dest[aa + k] = src[bb + k];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
for (i = 0; i < outHeight; i++) {
|
||||||
|
const int ii = i % inHeight;
|
||||||
|
for (j = 0; j < outWidth; j++) {
|
||||||
|
const int jj = j % inWidth;
|
||||||
|
const int aa = (i * outWidth + j) * comps;
|
||||||
|
const int bb = ii * srcRowStride + jj * comps;
|
||||||
|
for (k = 0; k < comps; k++) {
|
||||||
|
dest[aa + k] = src[bb + k];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
11
GLideNHQ/tc-1.1+/types.h
Normal file
11
GLideNHQ/tc-1.1+/types.h
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
#ifndef TYPES_H_included
|
||||||
|
#define TYPES_H_included
|
||||||
|
|
||||||
|
/*****************************************************************************\
|
||||||
|
* 32bit types
|
||||||
|
\*****************************************************************************/
|
||||||
|
typedef unsigned char byte; /* 8-bit */
|
||||||
|
typedef unsigned short word; /* 16-bit */
|
||||||
|
typedef unsigned int dword; /* 32-bit */
|
||||||
|
|
||||||
|
#endif
|
110
GLideNHQ/tc-1.1+/wrapper.c
Normal file
110
GLideNHQ/tc-1.1+/wrapper.c
Normal file
|
@ -0,0 +1,110 @@
|
||||||
|
/*
|
||||||
|
* Texture compression
|
||||||
|
* Version: 1.0
|
||||||
|
*
|
||||||
|
* Copyright (C) 2004 Daniel Borca All Rights Reserved.
|
||||||
|
*
|
||||||
|
* this 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, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* this 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 GNU Make; see the file COPYING. If not, write to
|
||||||
|
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
#include "types.h"
|
||||||
|
#include "internal.h"
|
||||||
|
#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,
|
||||||
|
int i, int j,
|
||||||
|
byte *texel)
|
||||||
|
{
|
||||||
|
dxt1_rgb_decode_1(texImage_Data, texImage_RowStride, i, j, texel);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TAPI void TAPIENTRY
|
||||||
|
fetch_2d_texel_rgba_dxt1 (int texImage_RowStride,
|
||||||
|
const byte *texImage_Data,
|
||||||
|
int i, int j,
|
||||||
|
byte *texel)
|
||||||
|
{
|
||||||
|
dxt1_rgba_decode_1(texImage_Data, texImage_RowStride, i, j, texel);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TAPI void TAPIENTRY
|
||||||
|
fetch_2d_texel_rgba_dxt3 (int texImage_RowStride,
|
||||||
|
const byte *texImage_Data,
|
||||||
|
int i, int j,
|
||||||
|
byte *texel)
|
||||||
|
{
|
||||||
|
dxt3_rgba_decode_1(texImage_Data, texImage_RowStride, i, j, texel);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TAPI void TAPIENTRY
|
||||||
|
fetch_2d_texel_rgba_dxt5 (int texImage_RowStride,
|
||||||
|
const byte *texImage_Data,
|
||||||
|
int i, int j,
|
||||||
|
byte *texel)
|
||||||
|
{
|
||||||
|
dxt5_rgba_decode_1(texImage_Data, texImage_RowStride, i, j, texel);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TAPI void TAPIENTRY
|
||||||
|
tx_compress_dxtn (int srccomps, int width, int height,
|
||||||
|
const byte *source, int destformat, byte *dest,
|
||||||
|
int destRowStride)
|
||||||
|
{
|
||||||
|
int srcRowStride = width * srccomps;
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
switch (destformat) {
|
||||||
|
case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
|
||||||
|
rv = dxt1_rgb_encode(width, height, srccomps,
|
||||||
|
source, srcRowStride,
|
||||||
|
dest, destRowStride);
|
||||||
|
break;
|
||||||
|
case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
|
||||||
|
rv = dxt1_rgba_encode(width, height, srccomps,
|
||||||
|
source, srcRowStride,
|
||||||
|
dest, destRowStride);
|
||||||
|
break;
|
||||||
|
case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
|
||||||
|
rv = dxt3_rgba_encode(width, height, srccomps,
|
||||||
|
source, srcRowStride,
|
||||||
|
dest, destRowStride);
|
||||||
|
break;
|
||||||
|
case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
|
||||||
|
rv = dxt5_rgba_encode(width, height, srccomps,
|
||||||
|
source, srcRowStride,
|
||||||
|
dest, destRowStride);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*return rv;*/
|
||||||
|
}
|
70
GLideNHQ/test/Makefile.gcc
Normal file
70
GLideNHQ/test/Makefile.gcc
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
# This MUST be processed by GNU make
|
||||||
|
#
|
||||||
|
# Texture Filtering Test Linux Makefile
|
||||||
|
# Version: 1.0
|
||||||
|
#
|
||||||
|
# Copyright (C) 2007 Hiroshi Morii All Rights Reserved.
|
||||||
|
# Email koolsmoky(at)users.sourceforge.net
|
||||||
|
# Web http://www.3dfxzone.it/koolsmoky
|
||||||
|
#
|
||||||
|
# this 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, or (at your option)
|
||||||
|
# any later version.
|
||||||
|
#
|
||||||
|
# this 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 GNU Make; see the file COPYING. If not, write to
|
||||||
|
# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
#
|
||||||
|
|
||||||
|
#
|
||||||
|
# Available options:
|
||||||
|
#
|
||||||
|
# Environment variables:
|
||||||
|
#
|
||||||
|
# Targets:
|
||||||
|
# all: build dynamic module
|
||||||
|
# clean: remove object files
|
||||||
|
# realclean: remove all generated files
|
||||||
|
#
|
||||||
|
|
||||||
|
#
|
||||||
|
# GCC does not have SEH (structured exception handling)
|
||||||
|
#
|
||||||
|
|
||||||
|
.PHONY: all clean realclean
|
||||||
|
|
||||||
|
CC = g++
|
||||||
|
CFLAGS += -I. -I../
|
||||||
|
CFLAGS += -fPIC -DPIC
|
||||||
|
CFLAGS += -DGHQCHK=1
|
||||||
|
|
||||||
|
LD = g++
|
||||||
|
LDFLAGS += -ldl -lstdc++
|
||||||
|
|
||||||
|
RM = rm
|
||||||
|
|
||||||
|
SOURCES = \
|
||||||
|
test.cpp \
|
||||||
|
../Ext_TxFilter.cpp
|
||||||
|
|
||||||
|
OBJECTS = $(SOURCES:.cpp=.o)
|
||||||
|
|
||||||
|
.cpp.o:
|
||||||
|
$(CC) -o $@ $(CFLAGS) -c $<
|
||||||
|
|
||||||
|
all: test.exe
|
||||||
|
|
||||||
|
test.exe: $(OBJECTS)
|
||||||
|
$(LD) -o $@ $(LDFLAGS) $^
|
||||||
|
|
||||||
|
clean:
|
||||||
|
-$(RM) *.o
|
||||||
|
|
||||||
|
realclean: clean
|
||||||
|
-$(RM) test.exe
|
68
GLideNHQ/test/Makefile.vc8
Normal file
68
GLideNHQ/test/Makefile.vc8
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
# This MUST be processed by GNU make
|
||||||
|
#
|
||||||
|
# Texture Filtering Test MSVC Makefile
|
||||||
|
# Version: 1.0
|
||||||
|
#
|
||||||
|
# Copyright (C) 2007 Hiroshi Morii All Rights Reserved.
|
||||||
|
# Email koolsmoky(at)users.sourceforge.net
|
||||||
|
# Web http://www.3dfxzone.it/koolsmoky
|
||||||
|
#
|
||||||
|
# this 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, or (at your option)
|
||||||
|
# any later version.
|
||||||
|
#
|
||||||
|
# this 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 GNU Make; see the file COPYING. If not, write to
|
||||||
|
# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
#
|
||||||
|
|
||||||
|
#
|
||||||
|
# Available options:
|
||||||
|
#
|
||||||
|
# Targets:
|
||||||
|
# all: build everything
|
||||||
|
# clean: remove object files
|
||||||
|
# realclean: remove all generated files
|
||||||
|
#
|
||||||
|
|
||||||
|
.PHONY: all clean realclean
|
||||||
|
.SUFFIXES: .cpp .obj
|
||||||
|
|
||||||
|
CC = cl
|
||||||
|
LD = _link # change this to suite your build environment
|
||||||
|
|
||||||
|
UNLINK = $(RM) $(1)
|
||||||
|
|
||||||
|
CFLAGS += -D__MSC__ -DWIN32 -D_CONSOLE -EHa -D_CRT_SECURE_NO_DEPRECATE
|
||||||
|
CFLAGS += -I. -I../
|
||||||
|
CFLAGS += -DGHQCHK=1
|
||||||
|
|
||||||
|
#LDFLAGS += -ltcg:STATUS
|
||||||
|
|
||||||
|
SOURCES = \
|
||||||
|
test.cpp \
|
||||||
|
../Ext_TxFilter.cpp
|
||||||
|
|
||||||
|
OBJECTS = $(SOURCES:.cpp=.obj)
|
||||||
|
|
||||||
|
.cpp.obj:
|
||||||
|
$(CC) -Fo$@ $(CFLAGS) -c $<
|
||||||
|
|
||||||
|
all: test.exe
|
||||||
|
|
||||||
|
test.exe: $(OBJECTS)
|
||||||
|
$(LD) -out:$@ $(LDFLAGS) $(OBJECTS)
|
||||||
|
|
||||||
|
$(OBJECTS): $(SOURCES)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
-$(RM) *.obj *.pdb *.ilk
|
||||||
|
|
||||||
|
realclean: clean
|
||||||
|
-$(RM) test.exe
|
120
GLideNHQ/test/test.cpp
Normal file
120
GLideNHQ/test/test.cpp
Normal file
|
@ -0,0 +1,120 @@
|
||||||
|
/*
|
||||||
|
* Texture Filtering
|
||||||
|
* Version: 1.0
|
||||||
|
*
|
||||||
|
* Copyright (C) 2007 Hiroshi Morii All Rights Reserved.
|
||||||
|
* Email koolsmoky(at)users.sourceforge.net
|
||||||
|
* Web http://www.3dfxzone.it/koolsmoky
|
||||||
|
*
|
||||||
|
* this 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, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* this 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 GNU Make; see the file COPYING. If not, write to
|
||||||
|
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "Ext_TxFilter.h"
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
void DisplayLoadProgress(const wchar_t *format, ...)
|
||||||
|
{
|
||||||
|
#if 0
|
||||||
|
va_list args;
|
||||||
|
wchar_t wbuf[INFO_BUF];
|
||||||
|
char buf[INFO_BUF];
|
||||||
|
|
||||||
|
/* process input */
|
||||||
|
va_start(args, format);
|
||||||
|
vswprintf(wbuf, format, args);
|
||||||
|
va_end(args);
|
||||||
|
|
||||||
|
/* XXX: convert to multibyte */
|
||||||
|
wcstombs(buf, wbuf, INFO_BUF);
|
||||||
|
printf(buf);
|
||||||
|
#else
|
||||||
|
static unsigned int i = 0;
|
||||||
|
i++;
|
||||||
|
if (i == 1) printf("\b-");
|
||||||
|
else if (i == 2) printf("\b\\");
|
||||||
|
else if (i == 3) printf("\b|");
|
||||||
|
else {
|
||||||
|
printf("\b/");
|
||||||
|
i = 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char* argv[])
|
||||||
|
{
|
||||||
|
float dummy = 1.1; /* force the compiler to load floating point support */
|
||||||
|
boolean bret = 0;
|
||||||
|
int options = 0;
|
||||||
|
|
||||||
|
/* Plugin path */
|
||||||
|
wchar_t path[MAX_PATH];
|
||||||
|
#ifdef WIN32
|
||||||
|
GETCWD(MAX_PATH, path);
|
||||||
|
#else
|
||||||
|
char cbuf[MAX_PATH];
|
||||||
|
GETCWD(MAX_PATH, cbuf);
|
||||||
|
mbstowcs(path, cbuf, MAX_PATH);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* ROM name */
|
||||||
|
wchar_t name[21] = L"DEFAULT";
|
||||||
|
|
||||||
|
printf("------------------------------------------------------------------\n");
|
||||||
|
printf(" GlideHQ Hires Texture Checker version 1.2\n");
|
||||||
|
printf(" Copyright (C) 2010 Hiroshi Morii All Rights Reserved\n");
|
||||||
|
printf(" email : koolsmoky(at)users.sourceforge.net\n");
|
||||||
|
printf(" website : http://www.3dfxzone.it/koolsmoky\n");
|
||||||
|
printf("\n");
|
||||||
|
printf(" Glide64 official website : http://glide64.emuxhaven.net\n");
|
||||||
|
printf("\n");
|
||||||
|
printf(" Usage: ghqchk.exe \"INTERNAL ROM NAME\"\n");
|
||||||
|
printf("------------------------------------------------------------------\n");
|
||||||
|
|
||||||
|
if (argc != 2) return 0;
|
||||||
|
|
||||||
|
printf("Checking \"%s\"... ", argv[1]);
|
||||||
|
|
||||||
|
mbstowcs(name, argv[1], 21);
|
||||||
|
|
||||||
|
//options |= COMPRESS_TEX;
|
||||||
|
//options |= COMPRESS_HIRESTEX;
|
||||||
|
//options |= S3TC_COMPRESSION;
|
||||||
|
//options |= TILE_HIRESTEX;
|
||||||
|
//options |= FORCE16BPP_TEX;
|
||||||
|
//options |= FORCE16BPP_HIRESTEX;
|
||||||
|
//options |= GZ_TEXCACHE;
|
||||||
|
options |= GZ_HIRESTEXCACHE;
|
||||||
|
//options |= (DUMP_TEXCACHE|DUMP_HIRESTEXCACHE);
|
||||||
|
options |= LET_TEXARTISTS_FLY;
|
||||||
|
//options |= DUMP_TEX;
|
||||||
|
options |= RICE_HIRESTEXTURES;
|
||||||
|
|
||||||
|
bret = ext_ghq_init(1024, // max texture width supported by hardware
|
||||||
|
1024, // max texture height supported by hardware
|
||||||
|
32, // max texture bpp supported by hardware
|
||||||
|
options,
|
||||||
|
0, // cache texture to system memory
|
||||||
|
path, // plugin path
|
||||||
|
name, // name of ROM. must be no longer than 256 characters
|
||||||
|
DisplayLoadProgress);
|
||||||
|
|
||||||
|
ext_ghq_shutdown();
|
||||||
|
|
||||||
|
printf("\bDone!\nLogged to ghqchk.txt\n");
|
||||||
|
|
||||||
|
return bret;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user