gthread.lo is made for fxgasm even though it is not used.
Otherwise, everything has to be compiled twice.
2.) Added lots of .cvsignore files, so that cvs doesn't complain that
it doesn't know about makefile.autoconf.in.
3.) Remove libtool, since it is autogenerated.
4.) Update the binary files in h5/glide3/tests. The repository files
were corrupted.
5.) Hook the texture utility library texus2 in as an option. This is
required for compressed textures. The default is the old texture
library.
6.) Implemented a texus2 function which sets an error handler.
519 lines
16 KiB
C
519 lines
16 KiB
C
|
|
/*
|
|
** Copyright (c) 1995, 3Dfx Interactive, Inc.
|
|
** All Rights Reserved.
|
|
**
|
|
** This is UNPUBLISHED PROPRIETARY SOURCE CODE of 3Dfx Interactive, Inc.;
|
|
** the contents of this file may not be disclosed to third parties, copied or
|
|
** duplicated in any form, in whole or in part, without the prior written
|
|
** permission of 3Dfx Interactive, Inc.
|
|
**
|
|
** RESTRICTED RIGHTS LEGEND:
|
|
** 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.
|
|
**
|
|
** $Revision$
|
|
** $Date$
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <math.h>
|
|
|
|
#include "texusint.h"
|
|
|
|
int txVerbose = 0;
|
|
|
|
/* These are all the formats listed in TexUS.h */
|
|
char *Format_Name[] = {
|
|
"rgb332", // 0x0 TEXFMT_RGB_332
|
|
"yiq", // 0x1 TEXFMT_YIQ_422
|
|
"a8", // 0x2 TEXFMT_A_8
|
|
"i8", // 0x3 TEXFMT_I_8
|
|
"ai44", // 0x4 TEXFMT_A_44
|
|
"p8", // 0x5 TEXFMT_P_8
|
|
"p6666", // 0x6 TEXFMT_P_8_6666
|
|
"rsvd2", // 0x7 TEXFMT_RSVD2
|
|
"argb8332", // 0x8 TEXFMT_ARGB_8332
|
|
"ayiq8422", // 0x9 TEXFMT_AYIQ_8422
|
|
"rgb565", // 0xa TEXFMT_RGB_565
|
|
"argb1555", // 0xb TEXFMT_ARGB_1555
|
|
"argb4444", // 0xc TEXFMT_ARGB_4444
|
|
"ai88", // 0xd TEXFMT_AI_88
|
|
"ap88", // 0xe TEXFMT_AP_88
|
|
"rsvd4", // 0xf TEXFMT_RSVD4
|
|
"unknown", // skipped 0x10 for some reason in texus.h
|
|
"fxt1", // 0x11 TEXFMT_ARGB_CMP_FXT1
|
|
"argb8888", // 0x12 TEXFMT_ARGB_8888
|
|
"yuyv422", // 0x13 TEXFMT_YUYV_422
|
|
"uyvy422", // 0x14 TEXFMT_UYVY_422
|
|
"ayuv444", // 0x15 TEXFMT_AYUV_444
|
|
"dxt1", // 0x16 TEXFMT_ARGB_CMP_DXT1
|
|
"dxt2", // 0x17 TEXFMT_ARGB_CMP_DXT2
|
|
"dxt3", // 0x18 TEXFMT_ARGB_CMP_DXT3
|
|
"dxt4", // 0x19 TEXFMT_ARGB_CMP_DXT4
|
|
"dxt5", // 0x1a TEXFMT_ARGB_CMP_DXT5
|
|
};
|
|
|
|
int
|
|
txLog2(int n)
|
|
{
|
|
switch (n) {
|
|
case 1: return 0;
|
|
case 2: return 1;
|
|
case 4: return 2;
|
|
case 8: return 3;
|
|
case 16: return 4;
|
|
case 32: return 5;
|
|
case 64: return 6;
|
|
case 128: return 7;
|
|
case 256: return 8;
|
|
}
|
|
|
|
txPanic("Bad arg to Log2\n");
|
|
return 0; // to keep compiler quiet.
|
|
}
|
|
|
|
int
|
|
txFloorPow2(int n)
|
|
{
|
|
// Find next smallest integer which is also a power of 2.
|
|
|
|
int i;
|
|
|
|
if ((n & (n -1)) == 0) {
|
|
return n; // already a power of 2.
|
|
}
|
|
|
|
for (i=1; i<= n; i+=i);
|
|
return i>>1;
|
|
}
|
|
|
|
int
|
|
txCeilPow2(int n)
|
|
{
|
|
// Find next smallest integer which is also a power of 2.
|
|
|
|
int i;
|
|
|
|
if ((n & (n -1)) == 0) return n; // already a power of 2.
|
|
|
|
for (i=1; i<= n; i+=i);
|
|
return i;
|
|
}
|
|
|
|
extern TxErrorCallbackFnc_t _txErrorCallback;
|
|
|
|
void
|
|
txPanic(char *message)
|
|
{
|
|
_txErrorCallback( message, FXTRUE );
|
|
}
|
|
|
|
void
|
|
txError(char *message)
|
|
{
|
|
_txErrorCallback( message, FXFALSE );
|
|
}
|
|
|
|
extern void _txDefaultErrorCallback( const char *string, FxBool fatal );
|
|
|
|
void
|
|
txErrorSetCallback( TxErrorCallbackFnc_t fnc,
|
|
TxErrorCallbackFnc_t *old_fnc)
|
|
{
|
|
if (old_fnc) {
|
|
*old_fnc = _txErrorCallback;
|
|
}
|
|
if (fnc) {
|
|
_txErrorCallback = fnc;
|
|
} else {
|
|
_txErrorCallback = _txDefaultErrorCallback;
|
|
}
|
|
}
|
|
|
|
int
|
|
txGCD(int a, int b)
|
|
{
|
|
// Greatest common divisor, used in resampling.
|
|
|
|
if (b > a) { int t; t = a; a = b; b = t;}
|
|
|
|
// a>b here.
|
|
|
|
while (b > 0) {
|
|
int t;
|
|
|
|
t = a % b;
|
|
a = b;
|
|
b = t;
|
|
}
|
|
return a;
|
|
}
|
|
|
|
void
|
|
txYABtoPal256(long *palette, const long* yabTable)
|
|
{
|
|
// Convert YAB table to a 256 color palette
|
|
// Assume yabTable[] has first 16Y's, 12 A's, 12 B's
|
|
|
|
const long *Y = yabTable;
|
|
const long *A = yabTable + 16;
|
|
const long *B = yabTable + 16 + 12;
|
|
int i;
|
|
|
|
for (i=0; i<256; i++) {
|
|
int iy, ia, ib, r, g, b;
|
|
|
|
iy = (i >> 4) & 0xF;
|
|
ia = (i >> 2) & 0x3;
|
|
ib = (i >> 0) & 0x3;
|
|
|
|
r = Y[iy] + A[3*ia + 0] + B[3*ib + 0];
|
|
g = Y[iy] + A[3*ia + 1] + B[3*ib + 1];
|
|
b = Y[iy] + A[3*ia + 2] + B[3*ib + 2];
|
|
|
|
if (r < 0) r = 0; if (r > 255) r = 255;
|
|
if (g < 0) g = 0; if (g > 255) g = 255;
|
|
if (b < 0) b = 0; if (b > 255) b = 255;
|
|
|
|
palette[i] = (r << 16) | (g << 8) | b;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* The following table was generated from this piece of code:
|
|
|
|
main()
|
|
{
|
|
int i;
|
|
|
|
printf("static int _explode3[256+256+4] = {\n");
|
|
|
|
for (i=-255; i<256; i++) {
|
|
int k;
|
|
int bits;
|
|
|
|
k = (i < 0) ? -i : i;
|
|
bits = 0;
|
|
|
|
if (k & 0x01) bits += 0x00000001 << 0;
|
|
if (k & 0x02) bits += 0x00000001 << 3;
|
|
if (k & 0x04) bits += 0x00000001 << 6;
|
|
if (k & 0x08) bits += 0x00000001 << 9;
|
|
if (k & 0x10) bits += 0x00000001 << 12;
|
|
if (k & 0x20) bits += 0x00000001 << 15;
|
|
if (k & 0x40) bits += 0x00000001 << 18;
|
|
if (k & 0x80) bits += 0x00000001 << 21;
|
|
|
|
// explode3[i] = bits;
|
|
printf("0x%.06x,", bits);
|
|
if (((i + 255) % 8) == 7) printf("\n");
|
|
}
|
|
printf("\n};\n");
|
|
printf("static int *explode3 = &_explode3[255];\n");
|
|
}
|
|
*/
|
|
|
|
int _explode3[255+256] = {
|
|
0x249249,0x249248,0x249241,0x249240,0x249209,0x249208,0x249201,0x249200,
|
|
0x249049,0x249048,0x249041,0x249040,0x249009,0x249008,0x249001,0x249000,
|
|
0x248249,0x248248,0x248241,0x248240,0x248209,0x248208,0x248201,0x248200,
|
|
0x248049,0x248048,0x248041,0x248040,0x248009,0x248008,0x248001,0x248000,
|
|
0x241249,0x241248,0x241241,0x241240,0x241209,0x241208,0x241201,0x241200,
|
|
0x241049,0x241048,0x241041,0x241040,0x241009,0x241008,0x241001,0x241000,
|
|
0x240249,0x240248,0x240241,0x240240,0x240209,0x240208,0x240201,0x240200,
|
|
0x240049,0x240048,0x240041,0x240040,0x240009,0x240008,0x240001,0x240000,
|
|
0x209249,0x209248,0x209241,0x209240,0x209209,0x209208,0x209201,0x209200,
|
|
0x209049,0x209048,0x209041,0x209040,0x209009,0x209008,0x209001,0x209000,
|
|
0x208249,0x208248,0x208241,0x208240,0x208209,0x208208,0x208201,0x208200,
|
|
0x208049,0x208048,0x208041,0x208040,0x208009,0x208008,0x208001,0x208000,
|
|
0x201249,0x201248,0x201241,0x201240,0x201209,0x201208,0x201201,0x201200,
|
|
0x201049,0x201048,0x201041,0x201040,0x201009,0x201008,0x201001,0x201000,
|
|
0x200249,0x200248,0x200241,0x200240,0x200209,0x200208,0x200201,0x200200,
|
|
0x200049,0x200048,0x200041,0x200040,0x200009,0x200008,0x200001,0x200000,
|
|
0x049249,0x049248,0x049241,0x049240,0x049209,0x049208,0x049201,0x049200,
|
|
0x049049,0x049048,0x049041,0x049040,0x049009,0x049008,0x049001,0x049000,
|
|
0x048249,0x048248,0x048241,0x048240,0x048209,0x048208,0x048201,0x048200,
|
|
0x048049,0x048048,0x048041,0x048040,0x048009,0x048008,0x048001,0x048000,
|
|
0x041249,0x041248,0x041241,0x041240,0x041209,0x041208,0x041201,0x041200,
|
|
0x041049,0x041048,0x041041,0x041040,0x041009,0x041008,0x041001,0x041000,
|
|
0x040249,0x040248,0x040241,0x040240,0x040209,0x040208,0x040201,0x040200,
|
|
0x040049,0x040048,0x040041,0x040040,0x040009,0x040008,0x040001,0x040000,
|
|
0x009249,0x009248,0x009241,0x009240,0x009209,0x009208,0x009201,0x009200,
|
|
0x009049,0x009048,0x009041,0x009040,0x009009,0x009008,0x009001,0x009000,
|
|
0x008249,0x008248,0x008241,0x008240,0x008209,0x008208,0x008201,0x008200,
|
|
0x008049,0x008048,0x008041,0x008040,0x008009,0x008008,0x008001,0x008000,
|
|
0x001249,0x001248,0x001241,0x001240,0x001209,0x001208,0x001201,0x001200,
|
|
0x001049,0x001048,0x001041,0x001040,0x001009,0x001008,0x001001,0x001000,
|
|
0x000249,0x000248,0x000241,0x000240,0x000209,0x000208,0x000201,0x000200,
|
|
0x000049,0x000048,0x000041,0x000040,0x000009,0x000008,0x000001,0x000000,
|
|
0x000001,0x000008,0x000009,0x000040,0x000041,0x000048,0x000049,0x000200,
|
|
0x000201,0x000208,0x000209,0x000240,0x000241,0x000248,0x000249,0x001000,
|
|
0x001001,0x001008,0x001009,0x001040,0x001041,0x001048,0x001049,0x001200,
|
|
0x001201,0x001208,0x001209,0x001240,0x001241,0x001248,0x001249,0x008000,
|
|
0x008001,0x008008,0x008009,0x008040,0x008041,0x008048,0x008049,0x008200,
|
|
0x008201,0x008208,0x008209,0x008240,0x008241,0x008248,0x008249,0x009000,
|
|
0x009001,0x009008,0x009009,0x009040,0x009041,0x009048,0x009049,0x009200,
|
|
0x009201,0x009208,0x009209,0x009240,0x009241,0x009248,0x009249,0x040000,
|
|
0x040001,0x040008,0x040009,0x040040,0x040041,0x040048,0x040049,0x040200,
|
|
0x040201,0x040208,0x040209,0x040240,0x040241,0x040248,0x040249,0x041000,
|
|
0x041001,0x041008,0x041009,0x041040,0x041041,0x041048,0x041049,0x041200,
|
|
0x041201,0x041208,0x041209,0x041240,0x041241,0x041248,0x041249,0x048000,
|
|
0x048001,0x048008,0x048009,0x048040,0x048041,0x048048,0x048049,0x048200,
|
|
0x048201,0x048208,0x048209,0x048240,0x048241,0x048248,0x048249,0x049000,
|
|
0x049001,0x049008,0x049009,0x049040,0x049041,0x049048,0x049049,0x049200,
|
|
0x049201,0x049208,0x049209,0x049240,0x049241,0x049248,0x049249,0x200000,
|
|
0x200001,0x200008,0x200009,0x200040,0x200041,0x200048,0x200049,0x200200,
|
|
0x200201,0x200208,0x200209,0x200240,0x200241,0x200248,0x200249,0x201000,
|
|
0x201001,0x201008,0x201009,0x201040,0x201041,0x201048,0x201049,0x201200,
|
|
0x201201,0x201208,0x201209,0x201240,0x201241,0x201248,0x201249,0x208000,
|
|
0x208001,0x208008,0x208009,0x208040,0x208041,0x208048,0x208049,0x208200,
|
|
0x208201,0x208208,0x208209,0x208240,0x208241,0x208248,0x208249,0x209000,
|
|
0x209001,0x209008,0x209009,0x209040,0x209041,0x209048,0x209049,0x209200,
|
|
0x209201,0x209208,0x209209,0x209240,0x209241,0x209248,0x209249,0x240000,
|
|
0x240001,0x240008,0x240009,0x240040,0x240041,0x240048,0x240049,0x240200,
|
|
0x240201,0x240208,0x240209,0x240240,0x240241,0x240248,0x240249,0x241000,
|
|
0x241001,0x241008,0x241009,0x241040,0x241041,0x241048,0x241049,0x241200,
|
|
0x241201,0x241208,0x241209,0x241240,0x241241,0x241248,0x241249,0x248000,
|
|
0x248001,0x248008,0x248009,0x248040,0x248041,0x248048,0x248049,0x248200,
|
|
0x248201,0x248208,0x248209,0x248240,0x248241,0x248248,0x248249,0x249000,
|
|
0x249001,0x249008,0x249009,0x249040,0x249041,0x249048,0x249049,0x249200,
|
|
0x249201,0x249208,0x249209,0x249240,0x249241,0x249248,0x249249,
|
|
};
|
|
int *explode3 = &_explode3[255];
|
|
|
|
int
|
|
txNearestColor(long ir, long ig, long ib, const FxU32 *pal, int ncolors)
|
|
{
|
|
int i, d;
|
|
int mindist, minpos; // closest distance to input
|
|
|
|
if (&explode3[-255] != &_explode3[0])
|
|
txPanic("Bad explode\n");
|
|
|
|
mindist = DISTANCE((*pal>>16)&0xff, (*pal>>8)&0xff, (*pal)&0xff,
|
|
ir, ig, ib);
|
|
minpos = 0;
|
|
pal ++;
|
|
|
|
/* Find closest color */
|
|
for (i=1; i<ncolors; i++, pal ++) {
|
|
d = DISTANCE((*pal>>16)&0xff, (*pal>>8)&0xff, (*pal)&0xff,
|
|
ir, ig, ib);
|
|
if (d < mindist) { mindist = d; minpos = i; }
|
|
}
|
|
return minpos; // best fit color is returned.
|
|
}
|
|
|
|
#ifdef GLIDE3
|
|
int
|
|
txAspectRatio(int w, int h)
|
|
{
|
|
int ar;
|
|
|
|
ar = (w >= h) ? (((w/h) << 4) | 1) : ((1 << 4) | (h/w));
|
|
switch (ar) {
|
|
case 0x81: return 6;
|
|
case 0x41: return 5;
|
|
case 0x21: return 4;
|
|
case 0x11: return 3;
|
|
case 0x12: return 2;
|
|
case 0x14: return 1;
|
|
case 0x18: return 0;
|
|
}
|
|
return 0;
|
|
}
|
|
#else
|
|
int
|
|
txAspectRatio(int w, int h)
|
|
{
|
|
int ar;
|
|
|
|
ar = (w >= h) ? (((w/h) << 4) | 1) : ((1 << 4) | (h/w));
|
|
switch (ar) {
|
|
case 0x81: return 0;
|
|
case 0x41: return 1;
|
|
case 0x21: return 2;
|
|
case 0x11: return 3;
|
|
case 0x12: return 4;
|
|
case 0x14: return 5;
|
|
case 0x18: return 6;
|
|
}
|
|
return 0;
|
|
}
|
|
#endif /* GLIDE3 */
|
|
|
|
void
|
|
txRectCopy(FxU8 *dst, int dstStride, const FxU8 *src, int srcStride,
|
|
int width, int height)
|
|
{
|
|
// Copy a rectangular region from src to dst, each with different strides.
|
|
|
|
while (height--) {
|
|
int i;
|
|
for (i=0; i<width; i++) {
|
|
dst[i] = src[i];
|
|
}
|
|
dst += dstStride;
|
|
src += srcStride;
|
|
}
|
|
}
|
|
|
|
int
|
|
txMemRequired(TxMip *txMip)
|
|
{
|
|
/* Tell me how much memory is need to hold this mipmap */
|
|
int w, h, memsize, i;
|
|
|
|
w = txMip->width;
|
|
h = txMip->height;
|
|
memsize = 0;
|
|
|
|
for (i=0; i<txMip->depth; i++) {
|
|
memsize += txTexCalcMapSize( w, h, txMip->format );
|
|
if (w > 1) w >>= 1;
|
|
if (h > 1) h >>= 1;
|
|
}
|
|
return memsize;
|
|
}
|
|
|
|
FxBool
|
|
txMipAlloc(TxMip *txMip)
|
|
{
|
|
int i, w, h;
|
|
FxU8 *data;
|
|
|
|
txMip->size = txMemRequired(txMip);
|
|
|
|
data = (FxU8 *) txMalloc(txMip->size);
|
|
if (data == NULL) return FXFALSE;
|
|
w = txMip->width;
|
|
h = txMip->height;
|
|
|
|
for (i=0; i<TX_MAX_LEVEL; i++) {
|
|
if (i >= txMip->depth) {
|
|
txMip->data[i] = NULL;
|
|
continue;
|
|
}
|
|
txMip->data[i] = data;
|
|
data += txTexCalcMapSize( w, h, txMip->format );
|
|
if (w > 1) w >>= 1;
|
|
if (h > 1) h >>= 1;
|
|
}
|
|
return FXTRUE;
|
|
}
|
|
|
|
FxBool
|
|
txMipSetMipPointers(TxMip *txMip)
|
|
{
|
|
int i, w, h;
|
|
FxU8 *data = txMip->data[0];
|
|
|
|
txMip->size = txMemRequired(txMip);
|
|
|
|
w = txMip->width;
|
|
h = txMip->height;
|
|
|
|
for (i=0; i<TX_MAX_LEVEL; i++) {
|
|
if (i >= txMip->depth) {
|
|
txMip->data[i] = NULL;
|
|
continue;
|
|
}
|
|
txMip->data[i] = data;
|
|
data += txTexCalcMapSize( w, h, txMip->format );
|
|
if (w > 1) w >>= 1;
|
|
if (h > 1) h >>= 1;
|
|
}
|
|
return FXTRUE;
|
|
}
|
|
|
|
void
|
|
txBasename(const char *name, char* basename)
|
|
{
|
|
/* Strip the pathname and leave us with filename.ext */
|
|
char *s;
|
|
const char *p, *slash;
|
|
|
|
/* Find the last slash */
|
|
for (p = slash = name; *p; p++) {
|
|
if ((*p == '/') || (*p == '\\')) slash = p + 1;
|
|
}
|
|
|
|
/* Copy everything after the last slash to output */
|
|
strcpy(basename, slash);
|
|
|
|
// Walk to end of string */
|
|
for (s = basename; *s; s++);
|
|
|
|
// Walk backwards; replace any . with 0
|
|
while (--s >= basename) {
|
|
if (*s == '.') {*s = 0; break;}
|
|
}
|
|
}
|
|
|
|
void
|
|
txPathAndBasename(const char *name, char* basename)
|
|
{
|
|
/* Strip the extension and leave us with path,basename */
|
|
char *s;
|
|
|
|
strcpy(basename, name);
|
|
|
|
/* Walk to the end of the string */
|
|
for (s = basename; *s; s++);
|
|
|
|
/* Walk backwards; stop when you hit a slash; replace any . with 0. */
|
|
while (--s >= basename) {
|
|
if ((*s == '/') || (*s == '\\')) break;
|
|
if (*s == '.') {*s = 0; break;}
|
|
|
|
}
|
|
}
|
|
|
|
void
|
|
txExtension(const char *name, char *extname)
|
|
{
|
|
const char *p, *ext;
|
|
|
|
ext = NULL;
|
|
for (p = name; *p; p++) {
|
|
if (*p == '.') ext = p;
|
|
}
|
|
|
|
if (ext)
|
|
while (*ext) *extname++ = *ext++;
|
|
|
|
*extname = 0;
|
|
}
|
|
|
|
void
|
|
txMipFree( TxMip *mip )
|
|
{
|
|
int i;
|
|
|
|
txFree( mip->data[0] );
|
|
for( i = 0; i < TX_MAX_LEVEL; i++ )
|
|
mip->data[i] = NULL;
|
|
}
|
|
|
|
void *txMalloc( size_t size )
|
|
{
|
|
return malloc( size );
|
|
}
|
|
|
|
void txFree( void *ptr )
|
|
{
|
|
free( ptr );
|
|
}
|
|
|
|
void *txRealloc( void *ptr, size_t size )
|
|
{
|
|
return realloc( ptr, size );
|
|
}
|
|
|