mirror of
https://github.com/blawar/GLideN64.git
synced 2024-07-04 10:03:36 +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