source: trunk/src/opengl/glide/sst1/texus/util.c

Last change on this file was 2885, checked in by sandervl, 26 years ago

Created new Voodoo 1 Glide dir

File size: 15.8 KB
Line 
1
2/*
3** THIS SOFTWARE IS SUBJECT TO COPYRIGHT PROTECTION AND IS OFFERED ONLY
4** PURSUANT TO THE 3DFX GLIDE GENERAL PUBLIC LICENSE. THERE IS NO RIGHT
5** TO USE THE GLIDE TRADEMARK WITHOUT PRIOR WRITTEN PERMISSION OF 3DFX
6** INTERACTIVE, INC. A COPY OF THIS LICENSE MAY BE OBTAINED FROM THE
7** DISTRIBUTOR OR BY CONTACTING 3DFX INTERACTIVE INC(info@3dfx.com).
8** THIS PROGRAM IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
9** EXPRESSED OR IMPLIED. SEE THE 3DFX GLIDE GENERAL PUBLIC LICENSE FOR A
10** FULL TEXT OF THE NON-WARRANTY PROVISIONS.
11**
12** USE, DUPLICATION OR DISCLOSURE BY THE GOVERNMENT IS SUBJECT TO
13** RESTRICTIONS AS SET FORTH IN SUBDIVISION (C)(1)(II) OF THE RIGHTS IN
14** TECHNICAL DATA AND COMPUTER SOFTWARE CLAUSE AT DFARS 252.227-7013,
15** AND/OR IN SIMILAR OR SUCCESSOR CLAUSES IN THE FAR, DOD OR NASA FAR
16** SUPPLEMENT. UNPUBLISHED RIGHTS RESERVED UNDER THE COPYRIGHT LAWS OF
17** THE UNITED STATES.
18**
19** COPYRIGHT 3DFX INTERACTIVE, INC. 1999, ALL RIGHTS RESERVED
20**
21** $Revision: 1.1 $
22** $Date: 2000-02-25 00:31:40 $
23*/
24
25#include <stdio.h>
26#include <stdlib.h>
27#include <string.h>
28#include <math.h>
29
30#include "texusint.h"
31
32int txVerbose = 0;
33
34char *Format_Name[] = {
35 "rgb332", // GR_TEXFMT_RGB_332
36 "yiq", // GR_TEXFMT_YIQ_422
37 "a8", // GR_TEXFMT_ALPHA_8
38 "i8", // GR_TEXFMT_INTENSITY_8
39 "ai44", // GR_TEXFMT_ALPHA_INTENSITY_44
40 "p8", // GR_TEXFMT_P_8
41 "rsvd1", // GR_TEXFMT_RSVD1
42 "rsvd2", // GR_TEXFMT_RSVD2
43 "argb8332", // GR_TEXFMT_ARGB_8332
44 "ayiq8422", // GR_TEXFMT_AYIQ_8422
45 "rgb565", // GR_TEXFMT_RGB_565
46 "argb1555", // GR_TEXFMT_ARGB_1555
47 "argb4444", // GR_TEXFMT_ARGB_4444
48 "ai88", // GR_TEXFMT_ALPHA_INTENSITY_88
49 "ap88", // GR_TEXFMT_AP_88
50 "rsvd4", // GR_TEXFMT_RSVD4
51 "argb8888", // GR_TEXFMT_ARGB_8888
52};
53
54
55int
56txLog2(int n)
57{
58 switch (n) {
59 case 1: return 0;
60 case 2: return 1;
61 case 4: return 2;
62 case 8: return 3;
63 case 16: return 4;
64 case 32: return 5;
65 case 64: return 6;
66 case 128: return 7;
67 case 256: return 8;
68 }
69
70 txPanic("Bad arg to Log2\n");
71 return 0; // to keep compiler quiet.
72}
73
74int
75txFloorPow2(int n)
76{
77 // Find next smallest integer which is also a power of 2.
78
79 int i;
80
81 if ((n & (n -1)) == 0) {
82 return n; // already a power of 2.
83 }
84
85 for (i=1; i<= n; i+=i);
86 return i>>1;
87}
88
89int
90txCeilPow2(int n)
91{
92 // Find next smallest integer which is also a power of 2.
93
94 int i;
95
96 if ((n & (n -1)) == 0) return n; // already a power of 2.
97
98 for (i=1; i<= n; i+=i);
99 return i;
100}
101
102extern TxErrorCallbackFnc_t _txErrorCallback;
103
104void
105txPanic(char *message)
106{
107 _txErrorCallback( message, FXTRUE );
108}
109
110void
111txError(char *message)
112{
113 _txErrorCallback( message, FXFALSE );
114}
115
116int
117txGCD(int a, int b)
118{
119 // Greatest common divisor, used in resampling.
120
121 if (b > a) { int t; t = a; a = b; b = t;}
122
123 // a>b here.
124
125 while (b > 0) {
126 int t;
127
128 t = a % b;
129 a = b;
130 b = t;
131 }
132 return a;
133}
134
135void
136txYABtoPal256(long *palette, const long* yabTable)
137{
138 // Convert YAB table to a 256 color palette
139 // Assume yabTable[] has first 16Y's, 12 A's, 12 B's
140
141 const long *Y = yabTable;
142 const long *A = yabTable + 16;
143 const long *B = yabTable + 16 + 12;
144 int i;
145
146 for (i=0; i<256; i++) {
147 int iy, ia, ib, r, g, b;
148
149 iy = (i >> 4) & 0xF;
150 ia = (i >> 2) & 0x3;
151 ib = (i >> 0) & 0x3;
152
153 r = Y[iy] + A[3*ia + 0] + B[3*ib + 0];
154 g = Y[iy] + A[3*ia + 1] + B[3*ib + 1];
155 b = Y[iy] + A[3*ia + 2] + B[3*ib + 2];
156
157 if (r < 0) r = 0; if (r > 255) r = 255;
158 if (g < 0) g = 0; if (g > 255) g = 255;
159 if (b < 0) b = 0; if (b > 255) b = 255;
160
161 palette[i] = (r << 16) | (g << 8) | b;
162 }
163}
164
165/*
166 * The following table was generated from this piece of code:
167
168main()
169{
170 int i;
171
172 printf("static int _explode3[256+256+4] = {\n");
173
174 for (i=-255; i<256; i++) {
175 int k;
176 int bits;
177
178 k = (i < 0) ? -i : i;
179 bits = 0;
180
181 if (k & 0x01) bits += 0x00000001 << 0;
182 if (k & 0x02) bits += 0x00000001 << 3;
183 if (k & 0x04) bits += 0x00000001 << 6;
184 if (k & 0x08) bits += 0x00000001 << 9;
185 if (k & 0x10) bits += 0x00000001 << 12;
186 if (k & 0x20) bits += 0x00000001 << 15;
187 if (k & 0x40) bits += 0x00000001 << 18;
188 if (k & 0x80) bits += 0x00000001 << 21;
189
190 // explode3[i] = bits;
191 printf("0x%.06x,", bits);
192 if (((i + 255) % 8) == 7) printf("\n");
193 }
194 printf("\n};\n");
195 printf("static int *explode3 = &_explode3[255];\n");
196}
197 */
198
199int _explode3[255+256] = {
2000x249249,0x249248,0x249241,0x249240,0x249209,0x249208,0x249201,0x249200,
2010x249049,0x249048,0x249041,0x249040,0x249009,0x249008,0x249001,0x249000,
2020x248249,0x248248,0x248241,0x248240,0x248209,0x248208,0x248201,0x248200,
2030x248049,0x248048,0x248041,0x248040,0x248009,0x248008,0x248001,0x248000,
2040x241249,0x241248,0x241241,0x241240,0x241209,0x241208,0x241201,0x241200,
2050x241049,0x241048,0x241041,0x241040,0x241009,0x241008,0x241001,0x241000,
2060x240249,0x240248,0x240241,0x240240,0x240209,0x240208,0x240201,0x240200,
2070x240049,0x240048,0x240041,0x240040,0x240009,0x240008,0x240001,0x240000,
2080x209249,0x209248,0x209241,0x209240,0x209209,0x209208,0x209201,0x209200,
2090x209049,0x209048,0x209041,0x209040,0x209009,0x209008,0x209001,0x209000,
2100x208249,0x208248,0x208241,0x208240,0x208209,0x208208,0x208201,0x208200,
2110x208049,0x208048,0x208041,0x208040,0x208009,0x208008,0x208001,0x208000,
2120x201249,0x201248,0x201241,0x201240,0x201209,0x201208,0x201201,0x201200,
2130x201049,0x201048,0x201041,0x201040,0x201009,0x201008,0x201001,0x201000,
2140x200249,0x200248,0x200241,0x200240,0x200209,0x200208,0x200201,0x200200,
2150x200049,0x200048,0x200041,0x200040,0x200009,0x200008,0x200001,0x200000,
2160x049249,0x049248,0x049241,0x049240,0x049209,0x049208,0x049201,0x049200,
2170x049049,0x049048,0x049041,0x049040,0x049009,0x049008,0x049001,0x049000,
2180x048249,0x048248,0x048241,0x048240,0x048209,0x048208,0x048201,0x048200,
2190x048049,0x048048,0x048041,0x048040,0x048009,0x048008,0x048001,0x048000,
2200x041249,0x041248,0x041241,0x041240,0x041209,0x041208,0x041201,0x041200,
2210x041049,0x041048,0x041041,0x041040,0x041009,0x041008,0x041001,0x041000,
2220x040249,0x040248,0x040241,0x040240,0x040209,0x040208,0x040201,0x040200,
2230x040049,0x040048,0x040041,0x040040,0x040009,0x040008,0x040001,0x040000,
2240x009249,0x009248,0x009241,0x009240,0x009209,0x009208,0x009201,0x009200,
2250x009049,0x009048,0x009041,0x009040,0x009009,0x009008,0x009001,0x009000,
2260x008249,0x008248,0x008241,0x008240,0x008209,0x008208,0x008201,0x008200,
2270x008049,0x008048,0x008041,0x008040,0x008009,0x008008,0x008001,0x008000,
2280x001249,0x001248,0x001241,0x001240,0x001209,0x001208,0x001201,0x001200,
2290x001049,0x001048,0x001041,0x001040,0x001009,0x001008,0x001001,0x001000,
2300x000249,0x000248,0x000241,0x000240,0x000209,0x000208,0x000201,0x000200,
2310x000049,0x000048,0x000041,0x000040,0x000009,0x000008,0x000001,0x000000,
2320x000001,0x000008,0x000009,0x000040,0x000041,0x000048,0x000049,0x000200,
2330x000201,0x000208,0x000209,0x000240,0x000241,0x000248,0x000249,0x001000,
2340x001001,0x001008,0x001009,0x001040,0x001041,0x001048,0x001049,0x001200,
2350x001201,0x001208,0x001209,0x001240,0x001241,0x001248,0x001249,0x008000,
2360x008001,0x008008,0x008009,0x008040,0x008041,0x008048,0x008049,0x008200,
2370x008201,0x008208,0x008209,0x008240,0x008241,0x008248,0x008249,0x009000,
2380x009001,0x009008,0x009009,0x009040,0x009041,0x009048,0x009049,0x009200,
2390x009201,0x009208,0x009209,0x009240,0x009241,0x009248,0x009249,0x040000,
2400x040001,0x040008,0x040009,0x040040,0x040041,0x040048,0x040049,0x040200,
2410x040201,0x040208,0x040209,0x040240,0x040241,0x040248,0x040249,0x041000,
2420x041001,0x041008,0x041009,0x041040,0x041041,0x041048,0x041049,0x041200,
2430x041201,0x041208,0x041209,0x041240,0x041241,0x041248,0x041249,0x048000,
2440x048001,0x048008,0x048009,0x048040,0x048041,0x048048,0x048049,0x048200,
2450x048201,0x048208,0x048209,0x048240,0x048241,0x048248,0x048249,0x049000,
2460x049001,0x049008,0x049009,0x049040,0x049041,0x049048,0x049049,0x049200,
2470x049201,0x049208,0x049209,0x049240,0x049241,0x049248,0x049249,0x200000,
2480x200001,0x200008,0x200009,0x200040,0x200041,0x200048,0x200049,0x200200,
2490x200201,0x200208,0x200209,0x200240,0x200241,0x200248,0x200249,0x201000,
2500x201001,0x201008,0x201009,0x201040,0x201041,0x201048,0x201049,0x201200,
2510x201201,0x201208,0x201209,0x201240,0x201241,0x201248,0x201249,0x208000,
2520x208001,0x208008,0x208009,0x208040,0x208041,0x208048,0x208049,0x208200,
2530x208201,0x208208,0x208209,0x208240,0x208241,0x208248,0x208249,0x209000,
2540x209001,0x209008,0x209009,0x209040,0x209041,0x209048,0x209049,0x209200,
2550x209201,0x209208,0x209209,0x209240,0x209241,0x209248,0x209249,0x240000,
2560x240001,0x240008,0x240009,0x240040,0x240041,0x240048,0x240049,0x240200,
2570x240201,0x240208,0x240209,0x240240,0x240241,0x240248,0x240249,0x241000,
2580x241001,0x241008,0x241009,0x241040,0x241041,0x241048,0x241049,0x241200,
2590x241201,0x241208,0x241209,0x241240,0x241241,0x241248,0x241249,0x248000,
2600x248001,0x248008,0x248009,0x248040,0x248041,0x248048,0x248049,0x248200,
2610x248201,0x248208,0x248209,0x248240,0x248241,0x248248,0x248249,0x249000,
2620x249001,0x249008,0x249009,0x249040,0x249041,0x249048,0x249049,0x249200,
2630x249201,0x249208,0x249209,0x249240,0x249241,0x249248,0x249249,
264};
265int *explode3 = &_explode3[255];
266
267int
268txNearestColor(long ir, long ig, long ib, const FxU32 *pal, int ncolors)
269{
270 int i, d;
271 int mindist, minpos; // closest distance to input
272
273 if (&explode3[-255] != &_explode3[0])
274 txPanic("Bad explode\n");
275
276 mindist = DISTANCE((*pal>>16)&0xff, (*pal>>8)&0xff, (*pal)&0xff,
277 ir, ig, ib);
278 minpos = 0;
279 pal ++;
280
281 /* Find closest color */
282 for (i=1; i<ncolors; i++, pal ++) {
283 d = DISTANCE((*pal>>16)&0xff, (*pal>>8)&0xff, (*pal)&0xff,
284 ir, ig, ib);
285 if (d < mindist) { mindist = d; minpos = i; }
286 }
287 return minpos; // best fit color is returned.
288}
289
290#ifdef GLIDE3
291int
292txAspectRatio(int w, int h)
293{
294 int ar;
295
296 ar = (w >= h) ? (((w/h) << 4) | 1) : ((1 << 4) | (h/w));
297 switch (ar) {
298 case 0x81: return 6;
299 case 0x41: return 5;
300 case 0x21: return 4;
301 case 0x11: return 3;
302 case 0x12: return 2;
303 case 0x14: return 1;
304 case 0x18: return 0;
305 }
306 return 0;
307}
308#else
309int
310txAspectRatio(int w, int h)
311{
312 int ar;
313
314 ar = (w >= h) ? (((w/h) << 4) | 1) : ((1 << 4) | (h/w));
315 switch (ar) {
316 case 0x81: return 0;
317 case 0x41: return 1;
318 case 0x21: return 2;
319 case 0x11: return 3;
320 case 0x12: return 4;
321 case 0x14: return 5;
322 case 0x18: return 6;
323 }
324 return 0;
325}
326#endif /* GLIDE3 */
327
328void
329txRectCopy(FxU8 *dst, int dstStride, const FxU8 *src, int srcStride,
330 int width, int height)
331{
332 // Copy a rectangular region from src to dst, each with different strides.
333
334 while (height--) {
335 int i;
336 for (i=0; i<width; i++) {
337 dst[i] = src[i];
338 }
339 dst += dstStride;
340 src += srcStride;
341 }
342}
343
344int
345txMemRequired(TxMip *txMip)
346{
347 /* Tell me how much memory is need to hold this mipmap */
348 int w, h, memsize, i;
349
350 w = txMip->width;
351 h = txMip->height;
352 memsize = 0;
353
354 for (i=0; i<txMip->depth; i++) {
355 memsize += (w * h);
356 if (w > 1) w >>= 1;
357 if (h > 1) h >>= 1;
358 }
359 return memsize * GR_TEXFMT_SIZE(txMip->format);
360}
361
362FxBool
363txMipAlloc(TxMip *txMip)
364{
365 int i, w, h;
366 FxU8 *data;
367
368 txMip->size = txMemRequired(txMip);
369
370 data = (FxU8 *) txMalloc(txMip->size);
371 if (data == NULL) return FXFALSE;
372 w = txMip->width;
373 h = txMip->height;
374
375 for (i=0; i<TX_MAX_LEVEL; i++) {
376 if (i >= txMip->depth) {
377 txMip->data[i] = NULL;
378 continue;
379 }
380 txMip->data[i] = data;
381 data += (w * h * GR_TEXFMT_SIZE(txMip->format));
382 if (w > 1) w >>= 1;
383 if (h > 1) h >>= 1;
384 }
385 return FXTRUE;
386}
387
388FxBool
389txMipSetMipPointers(TxMip *txMip)
390{
391 int i, w, h;
392 FxU8 *data = txMip->data[0];
393
394 txMip->size = txMemRequired(txMip);
395
396 w = txMip->width;
397 h = txMip->height;
398
399 for (i=0; i<TX_MAX_LEVEL; i++) {
400 if (i >= txMip->depth) {
401 txMip->data[i] = NULL;
402 continue;
403 }
404 txMip->data[i] = data;
405 data += (w * h * GR_TEXFMT_SIZE(txMip->format));
406 if (w > 1) w >>= 1;
407 if (h > 1) h >>= 1;
408 }
409 return FXTRUE;
410}
411
412void
413txBasename(const char *name, char* basename)
414{
415 /* Strip the pathname and leave us with filename.ext */
416 char *s;
417 const char *p, *slash;
418
419 /* Find the last slash */
420 for (p = slash = name; *p; p++) {
421 if ((*p == '/') || (*p == '\\')) slash = p + 1;
422 }
423
424 /* Copy everything after the last slash to output */
425 strcpy(basename, slash);
426
427 // Walk to end of string */
428 for (s = basename; *s; s++);
429
430 // Walk backwards; replace any . with 0
431 while (--s >= basename) {
432 if (*s == '.') {*s = 0; break;}
433 }
434}
435
436void
437txPathAndBasename(const char *name, char* basename)
438{
439 /* Strip the extension and leave us with path,basename */
440 char *s;
441
442 strcpy(basename, name);
443
444 /* Walk to the end of the string */
445 for (s = basename; *s; s++);
446
447 /* Walk backwards; stop when you hit a slash; replace any . with 0. */
448 while (--s >= basename) {
449 if ((*s == '/') || (*s == '\\')) break;
450 if (*s == '.') {*s = 0; break;}
451
452 }
453}
454
455void
456txExtension(const char *name, char *extname)
457{
458 const char *p, *ext;
459
460 ext = NULL;
461 for (p = name; *p; p++) {
462 if (*p == '.') ext = p;
463 }
464
465 if (ext)
466 while (*ext) *extname++ = *ext++;
467
468 *extname = 0;
469}
470
471void
472txMipFree( TxMip *mip )
473{
474 int i;
475
476 txFree( mip->data[0] );
477 for( i = 0; i < TX_MAX_LEVEL; i++ )
478 mip->data[i] = NULL;
479}
480
481void *txMalloc( size_t size )
482{
483 return malloc( size );
484}
485
486void txFree( void *ptr )
487{
488 free( ptr );
489}
490
491void *txRealloc( void *ptr, size_t size )
492{
493 return realloc( ptr, size );
494}
495
Note: See TracBrowser for help on using the repository browser.