1 /*
2 * Copyright (C) 1997-2001 Id Software, Inc.
3 *
4 * This program is free software; you can redistribute it and/or modify it under
5 * the terms of the GNU General Public License as published by the Free
6 * Software Foundation; either version 2 of the License, or (at your option)
7 * any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE.
12 *
13 * See the GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along with
16 * this program; if not, write to the Free Software Foundation, Inc., 59
17 * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 *
19 */
20
21 #include "gl_local.h"
22
23 #include "gl_refl.h" /* MPO */
24
25 image_t gltextures[MAX_GLTEXTURES];
26 int numgltextures;
27 int base_textureid; /* gltextures[i] = base_textureid+i */
28
29 static byte intensitytable[256];
30 static unsigned char gammatable[256];
31
32 cvar_t *intensity;
33
34 unsigned d_8to24table[256];
35
36 #ifndef QMAX
37 float d_8to24tablef[256][3];
38 #endif
39
40 qboolean GL_Upload8(byte * data, int width, int height, qboolean mipmap, qboolean is_sky);
41 qboolean GL_Upload32(unsigned *data, int width, int height, qboolean mipmap);
42
43
44 int gl_solid_format = 3;
45 int gl_alpha_format = 4;
46
47 int gl_tex_solid_format = 3;
48 int gl_tex_alpha_format = 4;
49
50 int gl_filter_min = GL_LINEAR_MIPMAP_NEAREST;
51 int gl_filter_max = GL_LINEAR;
52
53 void
GL_SetTexturePalette(unsigned palette[256])54 GL_SetTexturePalette(unsigned palette[256])
55 {
56 int i;
57 unsigned char temptable[768];
58
59 if (qglColorTableEXT) {
60 for (i = 0; i < 256; i++) {
61 temptable[i * 3 + 0] = (palette[i] >> 0) & 0xff;
62 temptable[i * 3 + 1] = (palette[i] >> 8) & 0xff;
63 temptable[i * 3 + 2] = (palette[i] >> 16) & 0xff;
64 }
65
66 qglColorTableEXT(GL_SHARED_TEXTURE_PALETTE_EXT,
67 GL_RGB,
68 256,
69 GL_RGB,
70 GL_UNSIGNED_BYTE,
71 temptable);
72 }
73 }
74
75 /* Knightmare- added some of Psychospaz's shortcuts */
76 GLenum bFunc1 = -1;
77 GLenum bFunc2 = -1;
78 void
GL_BlendFunction(GLenum sfactor,GLenum dfactor)79 GL_BlendFunction(GLenum sfactor, GLenum dfactor)
80 {
81 if (sfactor != bFunc1 || dfactor != bFunc2) {
82 bFunc1 = sfactor;
83 bFunc2 = dfactor;
84
85 qglBlendFunc(bFunc1, bFunc2);
86 }
87 }
88
89 GLenum shadeModelMode = -1;
90
91 void
GL_ShadeModel(GLenum mode)92 GL_ShadeModel(GLenum mode)
93 {
94 if (mode != shadeModelMode) {
95 shadeModelMode = mode;
96 qglShadeModel(mode);
97 }
98 }
99
100 void
GL_EnableMultitexture(qboolean enable)101 GL_EnableMultitexture(qboolean enable)
102 {
103 if (!qglSelectTextureSGIS && !qglActiveTextureARB)
104 return;
105
106 if (enable) {
107 GL_SelectTexture(GL_TEXTURE1);
108 qglEnable(GL_TEXTURE_2D);
109 GL_TexEnv(GL_REPLACE);
110 } else {
111 GL_SelectTexture(GL_TEXTURE1);
112 qglDisable(GL_TEXTURE_2D);
113 GL_TexEnv(GL_REPLACE);
114 }
115
116 GL_SelectTexture(GL_TEXTURE0);
117 GL_TexEnv(GL_REPLACE);
118 }
119
120 void
GL_Enable3dTextureUnit(qboolean enable)121 GL_Enable3dTextureUnit(qboolean enable)
122 {
123 if (!qglSelectTextureSGIS && !qglActiveTextureARB)
124 return;
125
126 if (enable) {
127 GL_SelectTexture(GL_TEXTURE2);
128 qglEnable(GL_TEXTURE_2D);
129 GL_TexEnv(GL_REPLACE);
130 } else {
131 GL_SelectTexture(GL_TEXTURE2);
132 qglDisable(GL_TEXTURE_2D);
133 GL_TexEnv(GL_REPLACE);
134 }
135
136 GL_SelectTexture(GL_TEXTURE0);
137 }
138
139 void
GL_SelectTexture(GLenum texture)140 GL_SelectTexture(GLenum texture)
141 {
142
143 int tmu;
144
145 if (!qglSelectTextureSGIS && !qglActiveTextureARB) {
146 return;
147 }
148 if
149 (texture == GL_TEXTURE0)
150 tmu = 0;
151 else if
152 (texture == GL_TEXTURE1)
153 tmu = 1;
154 else
155 tmu = 2;
156
157 if (tmu == gl_state.currenttmu)
158 return;
159
160 gl_state.currenttmu = tmu;
161
162 if (qglSelectTextureSGIS) {
163 qglSelectTextureSGIS(texture);
164 } else if (qglActiveTextureARB) {
165 qglActiveTextureARB(texture);
166 qglClientActiveTextureARB(texture);
167 }
168 }
169
170 void
GL_TexEnv(GLenum mode)171 GL_TexEnv(GLenum mode)
172 {
173 static int lastmodes[2] = {-1, -1};
174
175 if (mode != lastmodes[gl_state.currenttmu]) {
176 qglTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, mode);
177 lastmodes[gl_state.currenttmu] = mode;
178 }
179 }
180
181 void
GL_Bind(int texnum)182 GL_Bind(int texnum)
183 {
184 extern image_t *draw_chars;
185
186 if (gl_nobind->value && draw_chars) /* performance evaluation option */
187 texnum = draw_chars->texnum;
188 if (gl_state.currenttextures[gl_state.currenttmu] == texnum)
189 return;
190
191 gl_state.currenttextures[gl_state.currenttmu] = texnum;
192 qglBindTexture(GL_TEXTURE_2D, texnum);
193 }
194
195 void
GL_MBind(GLenum target,int texnum)196 GL_MBind(GLenum target, int texnum)
197 {
198
199 GL_SelectTexture(target);
200
201 if (target == GL_TEXTURE0) {
202 if (gl_state.currenttextures[0] == texnum)
203 return;
204 } else if (target == GL_TEXTURE1) {
205 if (gl_state.currenttextures[1] == texnum)
206 return;
207 } else {
208 if (gl_state.currenttextures[2] == texnum)
209 return;
210 }
211
212 GL_Bind(texnum);
213 }
214
215 typedef struct {
216 char *name;
217 int minimize, maximize;
218 } glmode_t;
219
220 glmode_t modes[] = {
221 {"GL_NEAREST", GL_NEAREST, GL_NEAREST},
222 {"GL_LINEAR", GL_LINEAR, GL_LINEAR},
223 {"GL_NEAREST_MIPMAP_NEAREST", GL_NEAREST_MIPMAP_NEAREST, GL_NEAREST},
224 {"GL_LINEAR_MIPMAP_NEAREST", GL_LINEAR_MIPMAP_NEAREST, GL_LINEAR},
225 {"GL_NEAREST_MIPMAP_LINEAR", GL_NEAREST_MIPMAP_LINEAR, GL_NEAREST},
226 {"GL_LINEAR_MIPMAP_LINEAR", GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR}
227 };
228
229 #define NUM_GL_MODES (sizeof(modes) / sizeof (glmode_t))
230
231 typedef struct {
232 char *name;
233 int mode;
234 } gltmode_t;
235
236 gltmode_t gl_alpha_modes[] = {
237 {"default", 4},
238 {"GL_RGBA", GL_RGBA},
239 {"GL_RGBA8", GL_RGBA8},
240 {"GL_RGB5_A1", GL_RGB5_A1},
241 {"GL_RGBA4", GL_RGBA4},
242 {"GL_RGBA2", GL_RGBA2},
243 };
244
245 #define NUM_GL_ALPHA_MODES (sizeof(gl_alpha_modes) / sizeof (gltmode_t))
246
247 gltmode_t gl_solid_modes[] = {
248 {"default", 3},
249 {"GL_RGB", GL_RGB},
250 {"GL_RGB8", GL_RGB8},
251 {"GL_RGB5", GL_RGB5},
252 {"GL_RGB4", GL_RGB4},
253 {"GL_R3_G3_B2", GL_R3_G3_B2},
254 #ifdef GL_RGB2_EXT
255 {"GL_RGB2", GL_RGB2_EXT},
256 #endif
257 };
258
259 #define NUM_GL_SOLID_MODES (sizeof(gl_solid_modes) / sizeof (gltmode_t))
260
261 /*
262 * =============== GL_TextureMode ===============
263 */
264 void
GL_TextureMode(char * string)265 GL_TextureMode(char *string)
266 {
267 int i;
268 image_t *glt;
269
270 for (i = 0; i < NUM_GL_MODES; i++) {
271 if (!Q_stricmp(modes[i].name, string))
272 break;
273 }
274
275 if (i == NUM_GL_MODES) {
276 ri.Con_Printf(PRINT_ALL, "bad filter name\n");
277 return;
278 }
279 gl_filter_min = modes[i].minimize;
280 gl_filter_max = modes[i].maximize;
281 /* anisotropic */
282 /* clamp selected anisotropy */
283 if (gl_config.anisotropic) {
284 if (gl_anisotropic->value > gl_config.max_anisotropy)
285 ri.Cvar_SetValue("gl_anisotropic", gl_config.max_anisotropy);
286 else if (gl_anisotropic->value < 1.0)
287 ri.Cvar_SetValue("gl_anisotropic", 1.0);
288 }
289 /* change all the existing mipmap texture objects */
290 for (i = 0, glt = gltextures; i < numgltextures; i++, glt++) {
291 if (glt->type != it_pic && glt->type != it_sky && glt->type != it_part) {
292 GL_Bind(glt->texnum);
293 qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min);
294 qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max);
295 /* anisotropic */
296 /* Set anisotropic filter if supported and enabled */
297 if (gl_config.anisotropic && gl_anisotropic->value) {
298 qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, gl_anisotropic->value);
299 /* GLfloat largest_supported_anisotropy; */
300 /* qglGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_ EXT,
301 &largest_supported_anisotropy); */
302 /* qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT,
303 largest_supported_anisotropy); */
304 }
305 }
306 }
307 }
308
309
310 /*
311 * =============== GL_TextureAlphaMode ===============
312 */
313 void
GL_TextureAlphaMode(char * string)314 GL_TextureAlphaMode(char *string)
315 {
316 int i;
317
318 for (i = 0; i < NUM_GL_ALPHA_MODES; i++) {
319 if (!Q_stricmp(gl_alpha_modes[i].name, string))
320 break;
321 }
322
323 if (i == NUM_GL_ALPHA_MODES) {
324 ri.Con_Printf(PRINT_ALL, "bad alpha texture mode name\n");
325 return;
326 }
327 gl_tex_alpha_format = gl_alpha_modes[i].mode;
328 }
329
330 /*
331 * =============== GL_TextureSolidMode ===============
332 */
333 void
GL_TextureSolidMode(char * string)334 GL_TextureSolidMode(char *string)
335 {
336 int i;
337
338 for (i = 0; i < NUM_GL_SOLID_MODES; i++) {
339 if (!Q_stricmp(gl_solid_modes[i].name, string))
340 break;
341 }
342
343 if (i == NUM_GL_SOLID_MODES) {
344 ri.Con_Printf(PRINT_ALL, "bad solid texture mode name\n");
345 return;
346 }
347 gl_tex_solid_format = gl_solid_modes[i].mode;
348 }
349
350 /*
351 * =============== GL_ImageList_f ===============
352 */
353 void
GL_ImageList_f(void)354 GL_ImageList_f(void)
355 {
356 int i;
357 image_t *image;
358 int texels;
359 const char *palstrings[2] = {
360 "RGB",
361 "PAL"
362 };
363
364 ri.Con_Printf(PRINT_ALL, "------------------\n");
365 texels = 0;
366
367 for (i = 0, image = gltextures; i < numgltextures; i++, image++) {
368 if (image->texnum <= 0)
369 continue;
370 texels += image->upload_width * image->upload_height;
371 switch (image->type) {
372 case it_skin:
373 ri.Con_Printf(PRINT_ALL, "M");
374 break;
375 case it_sprite:
376 ri.Con_Printf(PRINT_ALL, "S");
377 break;
378 case it_wall:
379 ri.Con_Printf(PRINT_ALL, "W");
380 break;
381 case it_pic:
382 ri.Con_Printf(PRINT_ALL, "P");
383 break;
384 default:
385 ri.Con_Printf(PRINT_ALL, " ");
386 break;
387 }
388
389 ri.Con_Printf(PRINT_ALL, " %3i %3i %s: %s\n",
390 image->upload_width, image->upload_height, palstrings[image->paletted], image->name);
391 }
392 ri.Con_Printf(PRINT_ALL, "Total texel count (not counting mipmaps): %i\n", texels);
393 }
394
395
396 /*
397 *
398 * ============================================================================
399 * =
400 *
401 * scrap allocation
402 *
403 * Allocate all the little status bar obejcts into a single texture to crutch up
404 * inefficient hardware / drivers
405 *
406 * =============================================================================
407 */
408
409 #define MAX_SCRAPS 1
410 #define BLOCK_WIDTH 256
411 #define BLOCK_HEIGHT 256
412 #define IMAGERESMAX 1024
413
414 int scrap_allocated[MAX_SCRAPS][BLOCK_WIDTH];
415 byte scrap_texels[MAX_SCRAPS][BLOCK_WIDTH * BLOCK_HEIGHT];
416 qboolean scrap_dirty;
417
418 /* returns a texture number and the position inside it */
419 int
Scrap_AllocBlock(int w,int h,int * x,int * y)420 Scrap_AllocBlock(int w, int h, int *x, int *y)
421 {
422 int i, j;
423 int best, best2;
424 int texnum;
425
426 for (texnum = 0; texnum < MAX_SCRAPS; texnum++) {
427 best = BLOCK_HEIGHT;
428
429 for (i = 0; i < BLOCK_WIDTH - w; i++) {
430 best2 = 0;
431
432 for (j = 0; j < w; j++) {
433 if (scrap_allocated[texnum][i + j] >= best)
434 break;
435 if (scrap_allocated[texnum][i + j] > best2)
436 best2 = scrap_allocated[texnum][i + j];
437 }
438 if (j == w) { /* this is a valid spot */
439 *x = i;
440 *y = best = best2;
441 }
442 }
443
444 if (best + h > BLOCK_HEIGHT)
445 continue;
446
447 for (i = 0; i < w; i++)
448 scrap_allocated[texnum][*x + i] = best + h;
449
450 return texnum;
451 }
452
453 return -1;
454 /* Sys_Error ("Scrap_AllocBlock: full"); */
455 }
456
457 int scrap_uploads;
458
459 void
Scrap_Upload(void)460 Scrap_Upload(void)
461 {
462 scrap_uploads++;
463 GL_Bind(TEXNUM_SCRAPS);
464 GL_Upload8(scrap_texels[0], BLOCK_WIDTH, BLOCK_HEIGHT, false, false);
465 scrap_dirty = false;
466 }
467
468 /*
469 * =================================================================
470 *
471 * PCX LOADING
472 *
473 * =================================================================
474 */
475
476
477 /*
478 * ============== LoadPCX ==============
479 */
480 void
LoadPCX(char * filename,byte ** pic,byte ** palette,int * width,int * height)481 LoadPCX(char *filename, byte ** pic, byte ** palette, int *width, int *height)
482 {
483 byte *raw;
484 pcx_t *pcx;
485 int x, y;
486 int len;
487 int dataByte, runLength;
488 byte *out, *pix;
489
490 *pic = NULL;
491 *palette = NULL;
492
493 /* load the file */
494 len = ri.FS_LoadFile(filename, (void **)&raw);
495 if (!raw) {
496 ri.Con_Printf(PRINT_DEVELOPER, "Bad pcx file %s\n", filename);
497 return;
498 }
499
500 /* parse the PCX file */
501 pcx = (pcx_t *) raw;
502 pcx->xmin = LittleShort(pcx->xmin);
503 pcx->ymin = LittleShort(pcx->ymin);
504 pcx->xmax = LittleShort(pcx->xmax);
505 pcx->ymax = LittleShort(pcx->ymax);
506 pcx->hres = LittleShort(pcx->hres);
507 pcx->vres = LittleShort(pcx->vres);
508 pcx->bytes_per_line = LittleShort(pcx->bytes_per_line);
509 pcx->palette_type = LittleShort(pcx->palette_type);
510
511 raw = &pcx->data;
512
513 if (pcx->manufacturer != 0x0a
514 || pcx->version != 5
515 || pcx->encoding != 1
516 || pcx->bits_per_pixel != 8
517 || pcx->xmax >= 640
518 || pcx->ymax >= 480) {
519 ri.Con_Printf(PRINT_ALL, "Bad pcx file %s\n", filename);
520 return;
521 }
522 out = malloc((pcx->ymax + 1) * (pcx->xmax + 1));
523
524 *pic = out;
525
526 pix = out;
527
528 if (palette) {
529 *palette = malloc(768);
530 memcpy(*palette, (byte *) pcx + len - 768, 768);
531 }
532 if (width)
533 *width = pcx->xmax + 1;
534 if (height)
535 *height = pcx->ymax + 1;
536
537 for (y = 0; y <= pcx->ymax; y++, pix += pcx->xmax + 1) {
538 for (x = 0; x <= pcx->xmax;) {
539 dataByte = *raw++;
540
541 if ((dataByte & 0xC0) == 0xC0) {
542 runLength = dataByte & 0x3F;
543 dataByte = *raw++;
544 } else
545 runLength = 1;
546
547 while (runLength-- > 0)
548 pix[x++] = dataByte;
549 }
550
551 }
552
553 if (raw - (byte *) pcx > len) {
554 ri.Con_Printf(PRINT_DEVELOPER, "PCX file %s was malformed", filename);
555 free(*pic);
556 *pic = NULL;
557 }
558 ri.FS_FreeFile(pcx);
559 }
560
561 /*
562 * =========================================================
563 *
564 * TARGA LOADING
565 *
566 * =========================================================
567 */
568
569 typedef struct _TargaHeader {
570 unsigned char id_length, colormap_type, image_type;
571 unsigned short colormap_index, colormap_length;
572 unsigned char colormap_size;
573 unsigned short x_origin, y_origin, width, height;
574 unsigned char pixel_size, attributes;
575 } TargaHeader;
576
577
578 /*
579 * ============= LoadTGA =============
580 */
581 /* Definitions for image types */
582 #define TGA_Null 0 /* no image data */
583 #define TGA_Map 1 /* Uncompressed, color-mapped images */
584 #define TGA_RGB 2 /* Uncompressed, RGB images */
585 #define TGA_Mono 3 /* Uncompressed, black and white images */
586 #define TGA_RLEMap 9 /* Runlength encoded color-mapped images */
587 #define TGA_RLERGB 10 /* Runlength encoded RGB images */
588 #define TGA_RLEMono 11 /* Compressed, black and white images */
589 #define TGA_CompMap 32 /* Compressed color-mapped data, using Huffman, Delta, and runlength encoding */
590 #define TGA_CompMap4 33 /* 4-pass quadtree-type process */
591 /* Definitions for interleave flag */
592 #define TGA_IL_None 0 /* non-interleaved */
593 #define TGA_IL_Two 1 /* two-way (even/odd) interleaving */
594 #define TGA_IL_Four 2 /* four way interleaving */
595 #define TGA_IL_Reserved 3 /* reserved */
596 /* Definitions for origin flag */
597 #define TGA_O_UPPER 0 /* Origin in lower left-hand corner */
598 #define TGA_O_LOWER 1 /* Origin in upper left-hand corner */
599 #define MAXCOLORS 16384
600
601 /*
602 * ============= LoadTGA NiceAss: LoadTGA() from Q2Ice, it supports more
603 * formats =============
604 */
605 void
LoadTGA(char * filename,byte ** pic,int * width,int * height)606 LoadTGA(char *filename, byte ** pic, int *width, int *height)
607 {
608 int w, h, x, y, i, temp1, temp2;
609 int realrow, truerow, baserow, size, interleave, origin;
610 int pixel_size, map_idx, mapped, rlencoded, RLE_count, RLE_flag;
611 TargaHeader header;
612 byte tmp[2], r, g, b, a, j, k, l;
613 byte *dst, *ColorMap, *data, *pdata;
614
615 /* load file */
616 ri.FS_LoadFile(filename, (void **)&data);
617
618 if (!data)
619 return;
620
621 pdata = data;
622
623 header.id_length = *pdata++;
624 header.colormap_type = *pdata++;
625 header.image_type = *pdata++;
626
627 tmp[0] = pdata[0];
628 tmp[1] = pdata[1];
629 header.colormap_index = LittleShort(*((short *)tmp));
630 pdata += 2;
631 tmp[0] = pdata[0];
632 tmp[1] = pdata[1];
633 header.colormap_length = LittleShort(*((short *)tmp));
634 pdata += 2;
635 header.colormap_size = *pdata++;
636 header.x_origin = LittleShort(*((short *)pdata));
637 pdata += 2;
638 header.y_origin = LittleShort(*((short *)pdata));
639 pdata += 2;
640 header.width = LittleShort(*((short *)pdata));
641 pdata += 2;
642 header.height = LittleShort(*((short *)pdata));
643 pdata += 2;
644 header.pixel_size = *pdata++;
645 header.attributes = *pdata++;
646
647 if (header.id_length)
648 pdata += header.id_length;
649
650 /* validate TGA type */
651 switch (header.image_type) {
652 case TGA_Map:
653 case TGA_RGB:
654 case TGA_Mono:
655 case TGA_RLEMap:
656 case TGA_RLERGB:
657 case TGA_RLEMono:
658 break;
659 default:
660 ri.Sys_Error(ERR_DROP, "LoadTGA: Only type 1 (map), 2 (RGB), 3 (mono), 9 (RLEmap), 10 (RLERGB), 11 (RLEmono) TGA images supported\n");
661 return;
662 }
663
664 /* validate color depth */
665 switch (header.pixel_size) {
666 case 8:
667 case 15:
668 case 16:
669 case 24:
670 case 32:
671 break;
672 default:
673 ri.Sys_Error(ERR_DROP, "LoadTGA: Only 8, 15, 16, 24 and 32 bit images (with colormaps) supported\n");
674 return;
675 }
676
677 r = g = b = a = l = 0;
678
679 /* if required, read the color map information */
680 ColorMap = NULL;
681 mapped = (header.image_type == TGA_Map || header.image_type == TGA_RLEMap || header.image_type == TGA_CompMap || header.image_type == TGA_CompMap4) && header.colormap_type == 1;
682 if (mapped) {
683 /* validate colormap size */
684 switch (header.colormap_size) {
685 case 8:
686 case 16:
687 case 32:
688 case 24:
689 break;
690 default:
691 ri.Sys_Error(ERR_DROP, "LoadTGA: Only 8, 16, 24 and 32 bit colormaps supported\n");
692 return;
693 }
694
695 temp1 = header.colormap_index;
696 temp2 = header.colormap_length;
697 if ((temp1 + temp2 + 1) >= MAXCOLORS) {
698 ri.FS_FreeFile(data);
699 return;
700 }
701 ColorMap = (byte *) malloc(MAXCOLORS * 4);
702 map_idx = 0;
703 for (i = temp1; i < temp1 + temp2; ++i, map_idx += 4) {
704
705 /* read appropriate number of bytes, break into rgb & put in map */
706 switch (header.colormap_size) {
707 case 8:
708 r = g = b = *pdata++;
709 a = 255;
710 break;
711 case 15:
712 j = *pdata++;
713 k = *pdata++;
714 l = ((unsigned int)k << 8) + j;
715 r = (byte) (((k & 0x7C) >> 2) << 3);
716 g = (byte) ((((k & 0x03) << 3) + ((j & 0xE0) >> 5)) << 3);
717 b = (byte) ((j & 0x1F) << 3);
718 a = 255;
719 break;
720 case 16:
721 j = *pdata++;
722 k = *pdata++;
723 l = ((unsigned int)k << 8) + j;
724 r = (byte) (((k & 0x7C) >> 2) << 3);
725 g = (byte) ((((k & 0x03) << 3) + ((j & 0xE0) >> 5)) << 3);
726 b = (byte) ((j & 0x1F) << 3);
727 a = (k & 0x80) ? 255 : 0;
728 break;
729 case 24:
730 b = *pdata++;
731 g = *pdata++;
732 r = *pdata++;
733 a = 255;
734 l = 0;
735 break;
736 case 32:
737 b = *pdata++;
738 g = *pdata++;
739 r = *pdata++;
740 a = *pdata++;
741 l = 0;
742 break;
743 }
744 ColorMap[map_idx + 0] = r;
745 ColorMap[map_idx + 1] = g;
746 ColorMap[map_idx + 2] = b;
747 ColorMap[map_idx + 3] = a;
748 }
749 }
750 /* check run-length encoding */
751 rlencoded = header.image_type == TGA_RLEMap || header.image_type == TGA_RLERGB || header.image_type == TGA_RLEMono;
752 RLE_count = 0;
753 RLE_flag = 0;
754
755 w = header.width;
756 h = header.height;
757
758 if (width)
759 *width = w;
760 if (height)
761 *height = h;
762
763 size = w * h * 4;
764 *pic = (byte *) malloc(size);
765
766 memset(*pic, 0, size);
767
768 /* read the Targa file body and convert to portable format */
769 pixel_size = header.pixel_size;
770 origin = (header.attributes & 0x20) >> 5;
771 interleave = (header.attributes & 0xC0) >> 6;
772 truerow = 0;
773 baserow = 0;
774 for (y = 0; y < h; y++) {
775 realrow = truerow;
776 if (origin == TGA_O_UPPER)
777 realrow = h - realrow - 1;
778
779 dst = *pic + realrow * w * 4;
780
781 for (x = 0; x < w; x++) {
782 /* check if run length encoded */
783 if (rlencoded) {
784 if (!RLE_count) {
785 /* have to restart run */
786 i = *pdata++;
787 RLE_flag = (i & 0x80);
788 if (!RLE_flag) {
789 /* stream of unencoded pixels */
790 RLE_count = i + 1;
791 } else {
792 /* single pixel replicated */
793 RLE_count = i - 127;
794 }
795 /* decrement count & get pixel */
796 --RLE_count;
797 } else {
798
799 /* have already read count & (at least) first pixel */
800 --RLE_count;
801 if (RLE_flag)
802 /* replicated pixels */
803 goto PixEncode;
804 }
805 }
806 /* read appropriate number of bytes, break into RGB */
807 switch (pixel_size) {
808 case 8:
809 r = g = b = l = *pdata++;
810 a = 255;
811 break;
812 case 15:
813 j = *pdata++;
814 k = *pdata++;
815 l = ((unsigned int)k << 8) + j;
816 r = (byte) (((k & 0x7C) >> 2) << 3);
817 g = (byte) ((((k & 0x03) << 3) + ((j & 0xE0) >> 5)) << 3);
818 b = (byte) ((j & 0x1F) << 3);
819 a = 255;
820 break;
821 case 16:
822 j = *pdata++;
823 k = *pdata++;
824 l = ((unsigned int)k << 8) + j;
825 r = (byte) (((k & 0x7C) >> 2) << 3);
826 g = (byte) ((((k & 0x03) << 3) + ((j & 0xE0) >> 5)) << 3);
827 b = (byte) ((j & 0x1F) << 3);
828 a = 255;
829 break;
830 case 24:
831 b = *pdata++;
832 g = *pdata++;
833 r = *pdata++;
834 a = 255;
835 l = 0;
836 break;
837 case 32:
838 b = *pdata++;
839 g = *pdata++;
840 r = *pdata++;
841 a = *pdata++;
842 l = 0;
843 break;
844 default:
845 ri.Sys_Error(ERR_DROP, "Illegal pixel_size '%d' in file '%s'\n", filename);
846 return;
847 }
848
849 PixEncode:
850 if (mapped) {
851 map_idx = l * 4;
852 *dst++ = ColorMap[map_idx + 0];
853 *dst++ = ColorMap[map_idx + 1];
854 *dst++ = ColorMap[map_idx + 2];
855 *dst++ = ColorMap[map_idx + 3];
856 } else {
857 *dst++ = r;
858 *dst++ = g;
859 *dst++ = b;
860 *dst++ = a;
861 }
862 }
863
864 if (interleave == TGA_IL_Four)
865 truerow += 4;
866 else if (interleave == TGA_IL_Two)
867 truerow += 2;
868 else
869 truerow++;
870
871 if (truerow >= h)
872 truerow = ++baserow;
873 }
874
875 if (mapped)
876 free(ColorMap);
877
878 ri.FS_FreeFile(data);
879 }
880
881 /*
882 * =================================================================
883 *
884 * JPEG LOADING
885 *
886 * By Robert 'Heffo' Heffernan
887 *
888 * =================================================================
889 */
890
891 void
jpg_null(j_decompress_ptr cinfo)892 jpg_null(j_decompress_ptr cinfo)
893 {
894 }
895
896 boolean
jpg_fill_input_buffer(j_decompress_ptr cinfo)897 jpg_fill_input_buffer(j_decompress_ptr cinfo)
898 {
899 ri.Con_Printf(PRINT_ALL, "Premature end of JPEG data\n");
900 return 1;
901 }
902
903 void
jpg_skip_input_data(j_decompress_ptr cinfo,long num_bytes)904 jpg_skip_input_data(j_decompress_ptr cinfo, long num_bytes)
905 {
906
907 cinfo->src->next_input_byte += (size_t) num_bytes;
908 cinfo->src->bytes_in_buffer -= (size_t) num_bytes;
909
910 if (cinfo->src->bytes_in_buffer < 0)
911 ri.Con_Printf(PRINT_ALL, "Premature end of JPEG data\n");
912 }
913
914 void
local_jpeg_mem_src(j_decompress_ptr cinfo,byte * mem,int len)915 local_jpeg_mem_src(j_decompress_ptr cinfo, byte * mem, int len)
916 {
917 cinfo->src = (struct jpeg_source_mgr *)(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, sizeof(struct jpeg_source_mgr));
918 cinfo->src->init_source = jpg_null;
919 cinfo->src->fill_input_buffer = jpg_fill_input_buffer;
920 cinfo->src->skip_input_data = jpg_skip_input_data;
921 cinfo->src->resync_to_restart = jpeg_resync_to_restart;
922 cinfo->src->term_source = jpg_null;
923 cinfo->src->bytes_in_buffer = len;
924 cinfo->src->next_input_byte = mem;
925 }
926
927 /*
928 * ============== LoadJPG ==============
929 */
930 void
LoadJPG(char * filename,byte ** pic,int * width,int * height)931 LoadJPG(char *filename, byte ** pic, int *width, int *height)
932 {
933 struct jpeg_decompress_struct cinfo;
934 struct jpeg_error_mgr jerr;
935 byte *rawdata, *rgbadata, *scanline, *p, *q;
936 int rawsize, i;
937
938 *pic = NULL;
939
940 /* Load JPEG file into memory */
941 rawsize = ri.FS_LoadFile(filename, (void **)&rawdata);
942 if (!rawdata)
943 return;
944
945 /* Knightmare- check for bad data */
946 if (rawdata[6] != 'J'
947 || rawdata[7] != 'F'
948 || rawdata[8] != 'I'
949 || rawdata[9] != 'F') {
950 ri.Con_Printf(PRINT_ALL, "Bad jpg file %s\n", filename);
951 ri.FS_FreeFile(rawdata);
952 return;
953 }
954 /* Initialise libJpeg Object */
955 cinfo.err = jpeg_std_error(&jerr);
956 jpeg_create_decompress(&cinfo);
957
958 /* Feed JPEG memory into the libJpeg Object */
959 local_jpeg_mem_src(&cinfo, rawdata, rawsize);
960
961 /* Process JPEG header */
962 jpeg_read_header(&cinfo, true);
963
964 /* Start Decompression */
965 jpeg_start_decompress(&cinfo);
966
967 /* Check Colour Components */
968 if (cinfo.output_components != 3) {
969 ri.Con_Printf(PRINT_ALL, "Invalid JPEG colour components\n");
970 jpeg_destroy_decompress(&cinfo);
971 ri.FS_FreeFile(rawdata);
972 return;
973 }
974 /* Allocate Memory for decompressed image */
975 rgbadata = malloc(cinfo.output_width * cinfo.output_height * 4);
976 if (!rgbadata) {
977 ri.Con_Printf(PRINT_ALL, "Insufficient RAM for JPEG buffer\n");
978 jpeg_destroy_decompress(&cinfo);
979 ri.FS_FreeFile(rawdata);
980 return;
981 }
982 /* Pass sizes to output */
983 *width = cinfo.output_width;
984 *height = cinfo.output_height;
985
986 /* Allocate Scanline buffer */
987 scanline = malloc(cinfo.output_width * 3);
988 if (!scanline) {
989 ri.Con_Printf(PRINT_ALL, "Insufficient RAM for JPEG scanline buffer\n");
990 free(rgbadata);
991 jpeg_destroy_decompress(&cinfo);
992 ri.FS_FreeFile(rawdata);
993 return;
994 }
995 /* Read Scanlines, and expand from RGB to RGBA */
996 q = rgbadata;
997 while (cinfo.output_scanline < cinfo.output_height) {
998 p = scanline;
999 jpeg_read_scanlines(&cinfo, &scanline, 1);
1000
1001 for (i = 0; i < cinfo.output_width; i++) {
1002 q[0] = p[0];
1003 q[1] = p[1];
1004 q[2] = p[2];
1005 q[3] = 255;
1006
1007 p += 3;
1008 q += 4;
1009 }
1010 }
1011
1012 /* Free the scanline buffer */
1013 free(scanline);
1014
1015 /* Finish Decompression */
1016 jpeg_finish_decompress(&cinfo);
1017
1018 /* Destroy JPEG object */
1019 jpeg_destroy_decompress(&cinfo);
1020
1021 /* Return the 'rgbadata' */
1022 *pic = rgbadata;
1023 }
1024
1025
1026 /*
1027 * =============================================================
1028 *
1029 * PNG STUFF
1030 *
1031 * =============================================================
1032 */
1033
1034 typedef struct png_s { /* TPng = class(TGraphic) */
1035 char *tmpBuf;
1036 int tmpi;
1037 long FBgColor; /* DL Background color Added 30/05/2000 */
1038 int FTransparent; /* DL Is this Image Transparent Added 30/05/2000 */
1039 long FRowBytes; /* DL Added 30/05/2000 */
1040 double FGamma; /* DL Added 07/06/2000 */
1041 double FScreenGamma; /* DL Added 07/06/2000 */
1042 char *FRowPtrs; /* DL Changed for consistancy 30/05/2000 */
1043 char *Data; /* property Data: pByte read fData; */
1044 char *Title;
1045 char *Author;
1046 char *Description;
1047 int BitDepth;
1048 int BytesPerPixel;
1049 int ColorType;
1050 unsigned long Height;
1051 unsigned long Width;
1052 int Interlace;
1053 int Compression;
1054 int Filter;
1055 double LastModified;
1056 int Transparent;
1057 } png_t;
1058
1059 png_t *my_png = 0;
1060 unsigned char *pngbytes;
1061
1062 void
InitializeDemData()1063 InitializeDemData()
1064 {
1065 long *cvaluep;/* ub */
1066 long y;
1067
1068 /* Initialize Data and RowPtrs */
1069 if (my_png->Data) {
1070 free(my_png->Data);
1071 my_png->Data = 0;
1072 }
1073 if (my_png->FRowPtrs) {
1074 free(my_png->FRowPtrs);
1075 my_png->FRowPtrs = 0;
1076 }
1077 my_png->Data = malloc(my_png->Height * my_png->FRowBytes); /* DL Added 30/5/2000 */
1078 my_png->FRowPtrs = malloc(sizeof(void *) * my_png->Height);
1079
1080 if ((my_png->Data) && (my_png->FRowPtrs)) {
1081 cvaluep = (long *)my_png->FRowPtrs;
1082 for (y = 0; y < my_png->Height; y++) {
1083 cvaluep[y] = (long)my_png->Data + (y * (long)my_png->FRowBytes); /* DL Added 08/07/2000 */
1084 }
1085 }
1086 }
1087
1088 void
mypng_struct_create()1089 mypng_struct_create()
1090 {
1091 if (my_png)
1092 return;
1093 my_png = malloc(sizeof(png_t));
1094 my_png->Data = 0;
1095 my_png->FRowPtrs = 0;
1096 my_png->Height = 0;
1097 my_png->Width = 0;
1098 my_png->ColorType = PNG_COLOR_TYPE_RGB;
1099 my_png->Interlace = PNG_INTERLACE_NONE;
1100 my_png->Compression = PNG_COMPRESSION_TYPE_DEFAULT;
1101 my_png->Filter = PNG_FILTER_TYPE_DEFAULT;
1102 }
1103
1104 void
mypng_struct_destroy(qboolean keepData)1105 mypng_struct_destroy(qboolean keepData)
1106 {
1107 if (!my_png)
1108 return;
1109 if (my_png->Data && !keepData)
1110 free(my_png->Data);
1111 if (my_png->FRowPtrs)
1112 free(my_png->FRowPtrs);
1113 free(my_png);
1114 my_png = 0;
1115 }
1116
1117 /*
1118 * =============================================================
1119 *
1120 * fReadData
1121 *
1122 * =============================================================
1123 */
1124
1125 void PNGAPI
fReadData(png_structp png,png_bytep data,png_size_t length)1126 fReadData(png_structp png, png_bytep data, png_size_t length)
1127 { /* called by pnglib */
1128 int i;
1129
1130 for (i = 0; i < length; i++)
1131 data[i] = my_png->tmpBuf[my_png->tmpi++]; /* give pnglib a some more bytes */
1132 }
1133
1134 /*
1135 * =============================================================
1136 *
1137 * LoadPNG
1138 *
1139 * =============================================================
1140 */
1141
1142 void
LoadPNG(char * filename,byte ** pic,int * width,int * height)1143 LoadPNG(char *filename, byte ** pic, int *width, int *height)
1144 {
1145 png_structp png;
1146 png_infop pnginfo;
1147 byte ioBuffer [8192];
1148 int len;
1149 byte *raw;
1150
1151 *pic = 0;
1152
1153 len = ri.FS_LoadFile(filename, (void **)&raw);
1154
1155 if (!raw) {
1156 ri.Con_Printf(PRINT_DEVELOPER, "Bad png file %s\n", filename);
1157 return;
1158 }
1159 if (png_sig_cmp(raw, 0, 4))
1160 return;
1161
1162 png = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
1163 if (!png)
1164 return;
1165
1166 pnginfo = png_create_info_struct(png);
1167
1168 if (!pnginfo) {
1169 png_destroy_read_struct(&png, &pnginfo, 0);
1170 return;
1171 }
1172 png_set_sig_bytes(png, 0 /* sizeof( sig ) */ );
1173
1174 mypng_struct_create(); /* creates the my_png struct */
1175
1176 my_png->tmpBuf = (char *)raw; /* buf = whole file content */
1177 my_png->tmpi = 0;
1178
1179 png_set_read_fn(png, ioBuffer, fReadData);
1180
1181 png_read_info(png, pnginfo);
1182
1183 png_get_IHDR(png, pnginfo, &my_png->Width, &my_png->Height, &my_png->BitDepth, &my_png->ColorType, &my_png->Interlace, &my_png->Compression, &my_png->Filter);
1184
1185 /* ...removed bgColor code here... */
1186 if (my_png->ColorType == PNG_COLOR_TYPE_PALETTE)
1187 png_set_palette_to_rgb(png);
1188 if (my_png->ColorType == PNG_COLOR_TYPE_GRAY && my_png->BitDepth < 8)
1189 png_set_gray_1_2_4_to_8(png);
1190
1191 /* Add alpha channel if present */
1192 if (png_get_valid(png, pnginfo, PNG_INFO_tRNS))
1193 png_set_tRNS_to_alpha(png);
1194
1195 /* hax: expand 24bit to 32bit */
1196 if (my_png->BitDepth == 8 && my_png->ColorType == PNG_COLOR_TYPE_RGB)
1197 png_set_filler(png, 255, PNG_FILLER_AFTER);
1198
1199 if ((my_png->ColorType == PNG_COLOR_TYPE_GRAY) || (my_png->ColorType == PNG_COLOR_TYPE_GRAY_ALPHA))
1200 png_set_gray_to_rgb(png);
1201
1202
1203 if (my_png->BitDepth < 8)
1204 png_set_expand(png);
1205
1206 /* update the info structure */
1207 png_read_update_info(png, pnginfo);
1208
1209 my_png->FRowBytes = png_get_rowbytes(png, pnginfo);
1210 my_png->BytesPerPixel = png_get_channels(png, pnginfo); /* DL Added 30/08/2000 */
1211
1212 InitializeDemData();
1213 if ((my_png->Data) && (my_png->FRowPtrs))
1214 png_read_image(png, (png_bytepp) my_png->FRowPtrs);
1215
1216 png_read_end(png, pnginfo); /* read last information chunks */
1217
1218 png_destroy_read_struct(&png, &pnginfo, 0);
1219
1220
1221 /* only load 32 bit by now... */
1222 if (my_png->BitDepth == 8) {
1223 *pic = (byte *)my_png->Data;
1224 *width = my_png->Width;
1225 *height = my_png->Height;
1226 } else {
1227 ri.Con_Printf(PRINT_DEVELOPER, "Bad png color depth: %s\n", filename);
1228 *pic = NULL;
1229 free(my_png->Data);
1230 }
1231
1232 mypng_struct_destroy(true);
1233 ri.FS_FreeFile((void *)raw);
1234 }
1235
1236 /*
1237 * ====================================================================
1238 *
1239 * IMAGE FLOOD FILLING
1240 *
1241 * ====================================================================
1242 */
1243
1244
1245 /*
1246 * ================= Mod_FloodFillSkin
1247 *
1248 * Fill background pixels so mipmapping doesn't have haloes =================
1249 */
1250
1251 typedef struct {
1252 short x, y;
1253 } floodfill_t;
1254
1255 /* must be a power of 2 */
1256 #define FLOODFILL_FIFO_SIZE 0x1000
1257 #define FLOODFILL_FIFO_MASK (FLOODFILL_FIFO_SIZE - 1)
1258
1259 #define FLOODFILL_STEP( off, dx, dy ) \
1260 { \
1261 if (pos[off] == fillcolor) \
1262 { \
1263 pos[off] = 255; \
1264 fifo[inpt].x = x + (dx), fifo[inpt].y = y + (dy); \
1265 inpt = (inpt + 1) & FLOODFILL_FIFO_MASK; \
1266 } \
1267 else if (pos[off] != 255) fdc = pos[off]; \
1268 }
1269
1270 void
R_FloodFillSkin(byte * skin,int skinwidth,int skinheight)1271 R_FloodFillSkin(byte * skin, int skinwidth, int skinheight)
1272 {
1273 byte fillcolor = *skin; /* assume this is the pixel to fill */
1274 floodfill_t fifo[FLOODFILL_FIFO_SIZE];
1275 int inpt = 0, outpt = 0;
1276 int filledcolor = -1;
1277 int i;
1278
1279 if (filledcolor == -1) {
1280 filledcolor = 0;
1281 /* attempt to find opaque black */
1282 for (i = 0; i < 256; ++i)
1283 if (d_8to24table[i] == (255 << 0)) { /* alpha 1.0 */
1284 filledcolor = i;
1285 break;
1286 }
1287 }
1288
1289 /* can't fill to filled color or to transparent color (used as visited marker) */
1290 if ((fillcolor == filledcolor) || (fillcolor == 255)) {
1291
1292 /* printf( "not filling skin from %d to %d\n", fillcolor, filledcolor ); */
1293 return;
1294 }
1295 fifo[inpt].x = 0, fifo[inpt].y = 0;
1296 inpt = (inpt + 1) & FLOODFILL_FIFO_MASK;
1297
1298 while (outpt != inpt) {
1299 int x = fifo[outpt].x, y = fifo[outpt].y;
1300 int fdc = filledcolor;
1301 byte *pos = &skin[x + skinwidth * y];
1302
1303 outpt = (outpt + 1) & FLOODFILL_FIFO_MASK;
1304
1305 if (x > 0)
1306 FLOODFILL_STEP(-1, -1, 0);
1307 if (x < skinwidth - 1)
1308 FLOODFILL_STEP(1, 1, 0);
1309 if (y > 0)
1310 FLOODFILL_STEP(-skinwidth, 0, -1);
1311 if (y < skinheight - 1)
1312 FLOODFILL_STEP(skinwidth, 0, 1);
1313 skin[x + skinwidth * y] = fdc;
1314 }
1315 }
1316
1317 /* ======================================================= */
1318
1319
1320 /*
1321 * ================ GL_ResampleTexture ================
1322 */
1323 void
GL_ResampleTexture(unsigned * in,int inwidth,int inheight,unsigned * out,int outwidth,int outheight)1324 GL_ResampleTexture(unsigned *in, int inwidth, int inheight, unsigned *out, int outwidth, int outheight)
1325 {
1326 int i, j;
1327 unsigned *inrow, *inrow2;
1328 unsigned frac, fracstep;
1329 unsigned p1[1024], p2[1024];
1330 byte *pix1, *pix2, *pix3, *pix4;
1331
1332 fracstep = inwidth * 0x10000 / outwidth;
1333
1334 frac = fracstep >> 2;
1335 for (i = 0; i < outwidth; i++) {
1336 p1[i] = 4 * (frac >> 16);
1337 frac += fracstep;
1338 }
1339 frac = 3 * (fracstep >> 2);
1340 for (i = 0; i < outwidth; i++) {
1341 p2[i] = 4 * (frac >> 16);
1342 frac += fracstep;
1343 }
1344
1345 for (i = 0; i < outheight; i++, out += outwidth) {
1346 inrow = in + inwidth * (int)((i + 0.25) * inheight / outheight);
1347 inrow2 = in + inwidth * (int)((i + 0.75) * inheight / outheight);
1348 frac = fracstep >> 1;
1349 for (j = 0; j < outwidth; j++) {
1350 pix1 = (byte *) inrow + p1[j];
1351 pix2 = (byte *) inrow + p2[j];
1352 pix3 = (byte *) inrow2 + p1[j];
1353 pix4 = (byte *) inrow2 + p2[j];
1354 ((byte *) (out + j))[0] = (pix1[0] + pix2[0] + pix3[0] + pix4[0]) >> 2;
1355 ((byte *) (out + j))[1] = (pix1[1] + pix2[1] + pix3[1] + pix4[1]) >> 2;
1356 ((byte *) (out + j))[2] = (pix1[2] + pix2[2] + pix3[2] + pix4[2]) >> 2;
1357 ((byte *) (out + j))[3] = (pix1[3] + pix2[3] + pix3[3] + pix4[3]) >> 2;
1358 }
1359 }
1360 }
1361
1362 /*
1363 * ================ GL_LightScaleTexture
1364 *
1365 * Scale up the pixel values in a texture to increase the lighting range
1366 * ================
1367 */
1368 void
GL_LightScaleTexture(unsigned * in,int inwidth,int inheight,qboolean only_gamma)1369 GL_LightScaleTexture(unsigned *in, int inwidth, int inheight, qboolean only_gamma)
1370 {
1371 if (only_gamma) {
1372 double i, c;
1373 byte *p;
1374
1375 p = (byte *) in;
1376
1377 c = inwidth * inheight;
1378 for (i = 0; i < c; i++, p += 4) {
1379 p[0] = gammatable[p[0]];
1380 p[1] = gammatable[p[1]];
1381 p[2] = gammatable[p[2]];
1382 }
1383 } else {
1384 double i, c;
1385 byte *p;
1386
1387 p = (byte *) in;
1388
1389 c = inwidth * inheight;
1390 for (i = 0; i < c; i++, p += 4) {
1391 p[0] = gammatable[intensitytable[p[0]]];
1392 p[1] = gammatable[intensitytable[p[1]]];
1393 p[2] = gammatable[intensitytable[p[2]]];
1394 }
1395 }
1396 }
1397
1398 /*
1399 * ================ GL_MipMap
1400 *
1401 * Operates in place, quartering the size of the texture ================
1402 */
1403 void
GL_MipMap(byte * in,int width,int height)1404 GL_MipMap(byte * in, int width, int height)
1405 {
1406 int i, j;
1407 byte *out;
1408
1409 width <<= 2;
1410 height >>= 1;
1411 out = in;
1412 for (i = 0; i < height; i++, in += width) {
1413 for (j = 0; j < width; j += 8, out += 4, in += 8) {
1414 out[0] = (in[0] + in[4] + in[width + 0] + in[width + 4]) >> 2;
1415 out[1] = (in[1] + in[5] + in[width + 1] + in[width + 5]) >> 2;
1416 out[2] = (in[2] + in[6] + in[width + 2] + in[width + 6]) >> 2;
1417 out[3] = (in[3] + in[7] + in[width + 3] + in[width + 7]) >> 2;
1418 }
1419 }
1420 }
1421
1422 /*
1423 * =============== GL_Upload32
1424 *
1425 * Returns has_alpha ===============
1426 */
1427 void
GL_BuildPalettedTexture(unsigned char * paletted_texture,unsigned char * scaled,int scaled_width,int scaled_height)1428 GL_BuildPalettedTexture(unsigned char *paletted_texture, unsigned char *scaled, int scaled_width, int scaled_height)
1429 {
1430 double i;
1431
1432 for (i = 0; i < (double)(scaled_width) * (double)(scaled_height); i++) {
1433 unsigned int r , g, b, c;
1434
1435 r = (scaled[0] >> 3) & 31;
1436 g = (scaled[1] >> 2) & 63;
1437 b = (scaled[2] >> 3) & 31;
1438
1439 c = r | (g << 5) | (b << 11);
1440
1441 paletted_texture[(int)(i)] = gl_state.d_16to8table[c];
1442
1443 scaled += 4;
1444 }
1445 }
1446
1447 /*
1448 * =============== here starts modified code by Heffo/changes by Nexus
1449 * ===============
1450 */
1451
1452
1453 int upload_width, upload_height;
1454 qboolean uploaded_paletted;
1455
1456 int
nearest_power_of_2(int size)1457 nearest_power_of_2(int size)
1458 {
1459 int i = 2;
1460
1461 /* NeVo - infinite loop bug-fix */
1462 if (size == 1)
1463 return size;
1464
1465 while (1) {
1466 i <<= 1;
1467 if (size == i)
1468 return i;
1469 if (size > i && size < (i << 1)) {
1470 if (size >= ((i + (i << 1)) / 2))
1471 return i << 1;
1472 else
1473 return i;
1474 }
1475 };
1476 }
1477
1478 extern cvar_t *gl_lightmap_texture_saturation; /* jitsaturation */
1479 void
desaturate_texture(unsigned * udata,int width,int height)1480 desaturate_texture(unsigned *udata, int width, int height)
1481 { /* jitsaturation */
1482 int i, size;
1483 float r, g, b, v, s;
1484 unsigned char *data;
1485
1486 data = (unsigned char *)udata;
1487
1488 s = gl_lightmap_texture_saturation->value;
1489
1490 size = width * height * 4;
1491
1492 for (i = 0; i < size; i += 4) {
1493 r = data[i];
1494 g = data[i + 1];
1495 b = data[i + 2];
1496 v = r * 0.30 + g * 0.59 + b * 0.11;
1497
1498 data[i] = (1 - s) * v + s * r;
1499 data[i + 1] = (1 - s) * v + s * g;
1500 data[i + 2] = (1 - s) * v + s * b;
1501 }
1502 }
1503
1504 /*
1505 * =============== GL_Upload32
1506 *
1507 * Returns has_alpha ===============
1508 */
1509 qboolean
GL_Upload32(unsigned * data,int width,int height,qboolean mipmap)1510 GL_Upload32(unsigned *data, int width, int height, qboolean mipmap)
1511 {
1512 int samples;
1513 unsigned *scaled;
1514 int scaled_width = 0, scaled_height = 0;
1515 int i, c;
1516 byte *scan;
1517 int comp = 0;
1518
1519 uploaded_paletted = false;
1520
1521 /* don't ever bother with maxtexsize textures */
1522 if (qglColorTableEXT && gl_ext_palettedtexture->value) { /* palettedtexture is limited to 256 */
1523 clamp(scaled_width, 1, 256);
1524 clamp(scaled_height, 1, 256);
1525 } else {
1526 clamp(scaled_width, 1, gl_state.maxtexsize);
1527 clamp(scaled_height, 1, gl_state.maxtexsize);
1528 }
1529
1530 /* scan the texture for any non-255 alpha */
1531 c = width * height;
1532 scan = ((byte *) data) + 3;
1533 samples = gl_solid_format;
1534 for (i = 0; i < c; i++, scan += 4) {
1535 if (*scan != 255) {
1536 samples = gl_alpha_format;
1537 break;
1538 }
1539 }
1540
1541 /* Heffo - ARB Texture Compression */
1542 qglHint(GL_TEXTURE_COMPRESSION_HINT_ARB, GL_NICEST);
1543 if (samples == gl_solid_format)
1544 comp = (gl_state.texture_compression) ? GL_COMPRESSED_RGB_ARB : gl_tex_solid_format;
1545 else if (samples == gl_alpha_format)
1546 comp = (gl_state.texture_compression) ? GL_COMPRESSED_RGBA_ARB : gl_tex_alpha_format;
1547
1548
1549 /* find sizes to scale to */
1550 {
1551 int max_size;
1552
1553 qglGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_size);
1554 scaled_width = nearest_power_of_2(width);
1555 scaled_height = nearest_power_of_2(height);
1556
1557 if (scaled_width > max_size)
1558 scaled_width = max_size;
1559 if (scaled_height > max_size)
1560 scaled_height = max_size;
1561
1562 if (scaled_width < 2)
1563 scaled_width = 2;
1564 if (scaled_height < 2)
1565 scaled_height = 2;
1566 }
1567
1568 /* let people sample down the world textures for speed */
1569 if (mipmap && (int)gl_picmip->value > 0) {
1570 int maxsize;
1571
1572 if ((int)gl_picmip->value == 1) /* clamp to 512x512 */
1573 maxsize = 512;
1574 else if ((int)gl_picmip->value == 2) /* clamp to 256x256 */
1575 maxsize = 256;
1576 else /* clamp to 128x128 */
1577 maxsize = 128;
1578
1579 while (1) {
1580 if (scaled_width <= maxsize && scaled_height <= maxsize)
1581 break;
1582 scaled_width >>= 1;
1583 scaled_height >>= 1;
1584 }
1585 }
1586 if (scaled_width != width || scaled_height != height) {
1587 scaled = malloc((scaled_width * scaled_height) * 4);
1588 GL_ResampleTexture(data, width, height, scaled, scaled_width, scaled_height);
1589 } else {
1590 scaled_width = width;
1591 scaled_height = height;
1592 scaled = data;
1593 }
1594
1595 if (gl_lightmap_texture_saturation->value < 1) /* jitsaturation */
1596 desaturate_texture(scaled, scaled_width, scaled_height);
1597
1598 if (mipmap) {
1599 if (!gl_state.hwgamma)
1600 if (brightenTexture)
1601 GL_LightScaleTexture(scaled, scaled_width, scaled_height, !mipmap);
1602
1603 if (gl_state.sgis_mipmap) {
1604 qglTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS, true);
1605 qglTexImage2D(GL_TEXTURE_2D, 0, comp, scaled_width, scaled_height, 0,
1606 GL_RGBA, GL_UNSIGNED_BYTE, scaled);
1607 } else
1608 gluBuild2DMipmaps(GL_TEXTURE_2D, samples, scaled_width, scaled_height,
1609 GL_RGBA, GL_UNSIGNED_BYTE, scaled);
1610 } else {
1611 if (!gl_state.hwgamma)
1612 if (brightenTexture)
1613 GL_LightScaleTexture(scaled, scaled_width, scaled_height, !mipmap);
1614 qglTexImage2D(GL_TEXTURE_2D, 0, comp, scaled_width, scaled_height, 0,
1615 GL_RGBA, GL_UNSIGNED_BYTE, scaled);
1616 }
1617
1618 if (scaled_width != width || scaled_height != height)
1619 free(scaled);
1620
1621
1622 upload_width = scaled_width;
1623 upload_height = scaled_height;
1624
1625 qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, (mipmap) ? gl_filter_min : gl_filter_max);
1626 qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max);
1627
1628
1629 if (mipmap) {
1630
1631 /* Set anisotropic filter if supported and enabled Knightmare */
1632 if (gl_config.anisotropic && gl_anisotropic->value)
1633 qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, gl_anisotropic->value);
1634 else
1635 qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max);
1636
1637 }
1638 return (samples == gl_alpha_format);
1639 }
1640
1641
1642 /*
1643 * =============== GL_Upload8
1644 *
1645 * Returns has_alpha ===============
1646 */
1647
1648 qboolean
GL_Upload8(byte * data,int width,int height,qboolean mipmap,qboolean is_sky)1649 GL_Upload8(byte * data, int width, int height, qboolean mipmap, qboolean is_sky)
1650 {
1651 unsigned trans[512 * 256];
1652 int i, s;
1653 int p;
1654
1655 s = width * height;
1656
1657 if (s > sizeof(trans) / 4)
1658 ri.Sys_Error(ERR_DROP, "GL_Upload8: too large");
1659
1660 /*
1661 if ( is_sky ) {
1662 qglTexImage2D( GL_TEXTURE_2D, 0,
1663 GL_COLOR_INDEX8_EXT, width, height, 0, GL_COLOR_INDEX,
1664 GL_UNSIGNED_BYTE, data );
1665 qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_max);
1666 qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max);
1667 } else
1668 */
1669 {
1670 for (i = 0; i < s; i++) {
1671 p = data[i];
1672 trans[i] = d_8to24table[p];
1673
1674 if (p == 255) { /* transparent, so scan around for another color */
1675 /* to avoid alpha fringes */
1676 /*
1677 * FIXME: do a full flood fill so mips
1678 * work...
1679 */
1680 if (i > width && data[i - width] != 255)
1681 p = data[i - width];
1682 else if (i < s - width && data[i + width] != 255)
1683 p = data[i + width];
1684 else if (i > 0 && data[i - 1] != 255)
1685 p = data[i - 1];
1686 else if (i < s - 1 && data[i + 1] != 255)
1687 p = data[i + 1];
1688 else
1689 p = 0;
1690 /* copy rgb components */
1691 ((byte *) & trans[i])[0] = ((byte *) & d_8to24table[p])[0];
1692 ((byte *) & trans[i])[1] = ((byte *) & d_8to24table[p])[1];
1693 ((byte *) & trans[i])[2] = ((byte *) & d_8to24table[p])[2];
1694 }
1695 }
1696
1697 return GL_Upload32(trans, width, height, mipmap);
1698 }
1699 }
1700
1701 /*
1702 * ================ GL_LoadPic
1703 *
1704 * This is also used as an entry point for the generated r_notexture
1705 * ================
1706 */
1707 image_t *
GL_LoadPic(char * name,byte * pic,int width,int height,imagetype_t type,int bits)1708 GL_LoadPic(char *name, byte * pic, int width, int height, imagetype_t type, int bits)
1709 {
1710 image_t *image;
1711 int i;
1712 #ifdef RETEX
1713 /* NiceAss: Nexus'added vars for texture scaling */
1714 miptex_t *mt;
1715 int len;
1716 char s[128];
1717 #endif
1718
1719 /* find a free image_t */
1720 for (i = 0, image = gltextures; i < numgltextures; i++, image++) {
1721 if (!image->texnum)
1722 break;
1723 }
1724 if (i == numgltextures) {
1725 if (numgltextures == MAX_GLTEXTURES)
1726 ri.Sys_Error(ERR_DROP, "MAX_GLTEXTURES");
1727 numgltextures++;
1728 }
1729 image = &gltextures[i];
1730
1731 if (strlen(name) >= sizeof(image->name))
1732 ri.Sys_Error(ERR_DROP, "Draw_LoadPic: \"%s\" is too long", name);
1733 Q_strncpyz(image->name, name, sizeof(image->name));
1734 image->registration_sequence = registration_sequence;
1735
1736 image->width = width;
1737 image->height = height;
1738 image->type = type;
1739
1740 image->replace_scale = 1.0;
1741
1742 #ifdef RETEX
1743 /* NiceAss: Nexus's image replacement scaling code */
1744 len = strlen(name);
1745 Q_strncpyz(s, name, sizeof(s));
1746
1747 if (!strcmp(s + len - 4, ".tga") || !strcmp(s + len - 4, ".png") || !strcmp(s + len - 4, ".jpg")) {
1748 s[len - 3] = 'w';
1749 s[len - 2] = 'a';
1750 s[len - 1] = 'l'; /* replace extension */
1751 ri.FS_LoadFile(s, (void **)&mt); /* load .wal file */
1752
1753 if (mt) {
1754 image->width = LittleLong(mt->width); /* grab size from wal */
1755 image->height = LittleLong(mt->height);
1756 ri.FS_FreeFile((void *)mt); /* free the picture */
1757 } else { /* if it's replacing a PCX image */
1758 byte *pic, *palette;
1759 int pcxwidth , pcxheight;
1760
1761 s[len - 3] = 'p';
1762 s[len - 2] = 'c';
1763 s[len - 1] = 'x'; /* replace extension */
1764 LoadPCX(s, &pic, &palette, &pcxwidth, &pcxheight); /* load .pcx file */
1765
1766 if (pcxwidth > 0 && pcxheight > 0) {
1767 image->replace_scale = ((float)pcxwidth / image->width + (float)pcxheight / image->height) * 0.5;
1768 if (image->replace_scale == 0.0)
1769 image->replace_scale = 1.0;
1770 image->replace_scale = MIN(image->replace_scale, 1.0);
1771 }
1772 if (pic)
1773 free(pic);
1774 if (palette)
1775 free(palette);
1776 }
1777 }
1778 #endif
1779
1780 if (type == it_skin && bits == 8)
1781 R_FloodFillSkin(pic, width, height);
1782
1783 /* load little pics into the scrap */
1784 if (image->type == it_pic && bits == 8 && image->width < 64 && image->height < 64) {
1785 int x , y;
1786 int i , j, k;
1787 int texnum;
1788
1789 texnum = Scrap_AllocBlock(image->width, image->height, &x, &y);
1790 if (texnum == -1)
1791 goto nonscrap;
1792 scrap_dirty = true;
1793
1794 /* copy the texels into the scrap block */
1795 k = 0;
1796 for (i = 0; i < image->height; i++)
1797 for (j = 0; j < image->width; j++, k++)
1798 scrap_texels[texnum][(y + i) * BLOCK_WIDTH + x + j] = pic[k];
1799 image->texnum = TEXNUM_SCRAPS + texnum;
1800 image->scrap = true;
1801 image->has_alpha = true;
1802 image->sl = (x + 0.01) / (float)BLOCK_WIDTH;
1803 image->sh = (x + image->width - 0.01) / (float)BLOCK_WIDTH;
1804 image->tl = (y + 0.01) / (float)BLOCK_WIDTH;
1805 image->th = (y + image->height - 0.01) / (float)BLOCK_WIDTH;
1806 } else {
1807 nonscrap:
1808 image->scrap = false;
1809 image->texnum = TEXNUM_IMAGES + (image - gltextures);
1810 GL_Bind(image->texnum);
1811 if (bits == 8)
1812 image->has_alpha =
1813 GL_Upload8(pic, width, height, (image->type != it_pic && image->type != it_sky),
1814 image->type == it_sky);
1815 else
1816 image->has_alpha =
1817 GL_Upload32((unsigned *)pic, width, height,
1818 (image->type != it_pic && image->type != it_sky));
1819 image->upload_width = upload_width; /* after power of 2 and scales */
1820 image->upload_height = upload_height;
1821 image->paletted = uploaded_paletted;
1822 image->sl = 0;
1823 image->sh = 1;
1824 image->tl = 0;
1825 image->th = 1;
1826 }
1827
1828 return image;
1829 }
1830
1831 /*
1832 * ================ GL_LoadWal ================
1833 */
1834 image_t *
GL_LoadWal(char * name)1835 GL_LoadWal(char *name)
1836 {
1837 miptex_t *mt;
1838 int width, height, ofs;
1839 image_t *image;
1840
1841 ri.FS_LoadFile(name, (void **)&mt);
1842 if (!mt) {
1843 ri.Con_Printf(PRINT_ALL, "GL_FindImage: can't load %s\n", name);
1844 return r_notexture;
1845 }
1846 width = LittleLong(mt->width);
1847 height = LittleLong(mt->height);
1848 ofs = LittleLong(mt->offsets[0]);
1849
1850
1851 image = GL_LoadPic(name, (byte *) mt + ofs, width, height, it_wall, 8);
1852
1853 ri.FS_FreeFile((void *)mt);
1854
1855 return image;
1856 }
1857
1858 /*
1859 * =============== GL_FindImage
1860 *
1861 * Finds or loads the given image ===============
1862 */
1863 #define IMAGETYPES 3
1864 char *image_types[IMAGETYPES] = {
1865 ".png",
1866 ".tga",
1867 ".jpg"
1868 };
1869
1870 image_t *
GL_FindImage(char * name,imagetype_t type)1871 GL_FindImage(char *name, imagetype_t type)
1872 {
1873 image_t *image;
1874 int i, len;
1875 byte *pic, *palette;
1876 int width, height;
1877 char *ptr;
1878
1879 if (!name)
1880 return NULL;
1881 /* ri.Sys_Error (ERR_DROP, "GL_FindImage: NULL name"); */
1882 len = strlen(name);
1883 if (len < 5)
1884 return NULL;
1885 /* ri.Sys_Error (ERR_DROP, "GL_FindImage: bad name: %s", name); */
1886
1887 /* fix backslashes */
1888 while ((ptr=strchr(name,'\\'))) {
1889 *ptr = '/';
1890 }
1891
1892 /* look for it */
1893 for (i = 0, image = gltextures; i < numgltextures; i++, image++) {
1894 if (!strcmp(name, image->name)) {
1895 image->registration_sequence = registration_sequence;
1896 return image;
1897 }
1898 }
1899
1900 /* load the pic from disk */
1901 pic = NULL;
1902 palette = NULL;
1903 image = NULL;
1904 if (!strcmp(name + len - 4, ".pcx")) {
1905 char basename[MAX_QPATH];
1906
1907 Com_sprintf(basename, sizeof(basename), "%s", name);
1908 basename[strlen(basename) - 4] = 0;
1909
1910 /*
1911 * only try to overwrite pcxs, others are specified in model
1912 * files etc
1913 */
1914 for (i = 0; i < IMAGETYPES && !image; i++)
1915 image = GL_FindImage(va("%s%s", basename, image_types[i]), type);
1916
1917 if (!image) {
1918 LoadPCX(name, &pic, &palette, &width, &height);
1919 if (!pic)
1920 return NULL; /* ri.Sys_Error (ERR_DROP, "GL_FindImage: can't load %s", name); */
1921 image = GL_LoadPic(name, pic, width, height, type, 8);
1922 }
1923 } else if (!strcmp(name + len - 4, ".wal")) {
1924 char basename[MAX_QPATH];
1925
1926 Com_sprintf(basename, sizeof(basename), "%s", name);
1927 basename[strlen(basename) - 4] = 0;
1928
1929 /* only try to overwrite pcxs, others are specified in model files etc */
1930 for (i = 0; i < IMAGETYPES && !image; i++)
1931 image = GL_FindImage(va("%s%s", basename, image_types[i]), type);
1932
1933 if (!image) {
1934 image = GL_LoadWal(name);
1935 }
1936 } else {
1937 if (!strcmp(name + len - 4, ".png")) { /* heffo hax0r */
1938 LoadPNG(name, &pic, &width, &height);
1939 if (!pic)
1940 return NULL;
1941 /* ri.Sys_Error (ERR_DROP, "GL_FindImage: can't load %s", name); */
1942 image = GL_LoadPic(name, pic, width, height, type, 32);
1943 } else if (!strcmp(name + len - 4, ".tga")) {
1944 LoadTGA(name, &pic, &width, &height);
1945 if (!pic)
1946 return NULL;
1947 /* ri.Sys_Error (ERR_DROP, "GL_FindImage: can't load %s", name); */
1948 image = GL_LoadPic(name, pic, width, height, type, 32);
1949 } else if (!strcmp(name + len - 4, ".jpg")) {
1950 LoadJPG(name, &pic, &width, &height);
1951 if (!pic)
1952 return NULL;
1953 /* ri.Sys_Error (ERR_DROP, "GL_FindImage: can't load %s", name); */
1954 image = GL_LoadPic(name, pic, width, height, type, 32);
1955 } else
1956 return NULL;
1957 /* ri.Sys_Error (ERR_DROP, "GL_FindImage: bad extension on: %s", name); */
1958 }
1959
1960 if (pic)
1961 free(pic);
1962 if (palette)
1963 free(palette);
1964 return image;
1965 }
1966
1967 /*
1968 * =============== R_RegisterSkin ===============
1969 */
1970 struct image_s *
R_RegisterSkin(char * name)1971 R_RegisterSkin(char *name)
1972 {
1973 return GL_FindImage(name, it_skin);
1974 }
1975
1976 /*
1977 * ================ GL_FreeUnusedImages
1978 *
1979 * Any image that was not touched on this registration sequence will be freed.
1980 * ================
1981 */
1982 void
GL_FreeUnusedImages(void)1983 GL_FreeUnusedImages(void)
1984 {
1985 int i;
1986 image_t *image;
1987
1988 /* never free r_notexture or particle texture[s] */
1989 r_notexture->registration_sequence = registration_sequence;
1990 #ifdef QMAX
1991 r_particlebeam->registration_sequence = registration_sequence;
1992 #else
1993 r_particletexture->registration_sequence = registration_sequence;
1994 #endif
1995 /* MH - detail textures begin */
1996 /* never free detail texture */
1997 r_detailtexture->registration_sequence = registration_sequence;
1998 /* MH - detail textures end */
1999 r_shelltexture->registration_sequence = registration_sequence; /* c14 added shell texture */
2000 r_radarmap->registration_sequence = registration_sequence;
2001 r_around->registration_sequence = registration_sequence;
2002 r_lblendimage->registration_sequence = registration_sequence;
2003 r_caustictexture->registration_sequence = registration_sequence;
2004 r_bholetexture->registration_sequence = registration_sequence;
2005 #ifdef QMAX
2006 for (i = 0; i < PARTICLE_TYPES; i++)
2007 if (r_particletextures[i]) /* dont mess with null ones silly :p */
2008 r_particletextures[i]->registration_sequence = registration_sequence;
2009 #endif
2010
2011 for (i = 0, image = gltextures; i < numgltextures; i++, image++) {
2012 if (image->registration_sequence == registration_sequence)
2013 continue; /* used this sequence */
2014 if (!image->registration_sequence)
2015 continue; /* free image_t slot */
2016 if (image->type == it_pic)
2017 continue; /* don't free pics */
2018 /* free it */
2019 qglDeleteTextures(1, (GLuint *)&image->texnum);
2020 memset(image, 0, sizeof(*image));
2021 }
2022 }
2023
2024
2025 /*
2026 * =============== Draw_GetPalette ===============
2027 */
2028 #ifndef QMAX
2029 byte default_pal[768] = {
2030
2031 0, 0, 0, 15, 15, 15, 31, 31, 31, 47, 47, 47,
2032 63, 63, 63, 75, 75, 75, 91, 91, 91, 107, 107, 107,
2033 123, 123, 123, 139, 139, 139, 155, 155, 155, 171, 171, 171,
2034 187, 187, 187, 203, 203, 203, 219, 219, 219, 235, 235, 235,
2035 99, 75, 35, 91, 67, 31, 83, 63, 31, 79, 59, 27,
2036 71, 55, 27, 63, 47, 23, 59, 43, 23, 51, 39, 19,
2037 47, 35, 19, 43, 31, 19, 39, 27, 15, 35, 23, 15,
2038 27, 19, 11, 23, 15, 11, 19, 15, 7, 15, 11, 7,
2039 95, 95, 111, 91, 91, 103, 91, 83, 95, 87, 79, 91,
2040 83, 75, 83, 79, 71, 75, 71, 63, 67, 63, 59, 59,
2041 59, 55, 55, 51, 47, 47, 47, 43, 43, 39, 39, 39,
2042 35, 35, 35, 27, 27, 27, 23, 23, 23, 19, 19, 19,
2043 143, 119, 83, 123, 99, 67, 115, 91, 59, 103, 79, 47,
2044 207, 151, 75, 167, 123, 59, 139, 103, 47, 111, 83, 39,
2045 235, 159, 39, 203, 139, 35, 175, 119, 31, 147, 99, 27,
2046 119, 79, 23, 91, 59, 15, 63, 39, 11, 35, 23, 7,
2047 167, 59, 43, 159, 47, 35, 151, 43, 27, 139, 39, 19,
2048 127, 31, 15, 115, 23, 11, 103, 23, 7, 87, 19, 0,
2049 75, 15, 0, 67, 15, 0, 59, 15, 0, 51, 11, 0,
2050 43, 11, 0, 35, 11, 0, 27, 7, 0, 19, 7, 0,
2051 123, 95, 75, 115, 87, 67, 107, 83, 63, 103, 79, 59,
2052 95, 71, 55, 87, 67, 51, 83, 63, 47, 75, 55, 43,
2053 67, 51, 39, 63, 47, 35, 55, 39, 27, 47, 35, 23,
2054 39, 27, 19, 31, 23, 15, 23, 15, 11, 15, 11, 7,
2055 111, 59, 23, 95, 55, 23, 83, 47, 23, 67, 43, 23,
2056 55, 35, 19, 39, 27, 15, 27, 19, 11, 15, 11, 7,
2057 179, 91, 79, 191, 123, 111, 203, 155, 147, 215, 187, 183,
2058 203, 215, 223, 179, 199, 211, 159, 183, 195, 135, 167, 183,
2059 115, 151, 167, 91, 135, 155, 71, 119, 139, 47, 103, 127,
2060 23, 83, 111, 19, 75, 103, 15, 67, 91, 11, 63, 83,
2061 7, 55, 75, 7, 47, 63, 7, 39, 51, 0, 31, 43,
2062 0, 23, 31, 0, 15, 19, 0, 7, 11, 0, 0, 0,
2063 139, 87, 87, 131, 79, 79, 123, 71, 71, 115, 67, 67,
2064 107, 59, 59, 99, 51, 51, 91, 47, 47, 87, 43, 43,
2065 75, 35, 35, 63, 31, 31, 51, 27, 27, 43, 19, 19,
2066 31, 15, 15, 19, 11, 11, 11, 7, 7, 0, 0, 0,
2067 151, 159, 123, 143, 151, 115, 135, 139, 107, 127, 131, 99,
2068 119, 123, 95, 115, 115, 87, 107, 107, 79, 99, 99, 71,
2069 91, 91, 67, 79, 79, 59, 67, 67, 51, 55, 55, 43,
2070 47, 47, 35, 35, 35, 27, 23, 23, 19, 15, 15, 11,
2071 159, 75, 63, 147, 67, 55, 139, 59, 47, 127, 55, 39,
2072 119, 47, 35, 107, 43, 27, 99, 35, 23, 87, 31, 19,
2073 79, 27, 15, 67, 23, 11, 55, 19, 11, 43, 15, 7,
2074 31, 11, 7, 23, 7, 0, 11, 0, 0, 0, 0, 0,
2075 119, 123, 207, 111, 115, 195, 103, 107, 183, 99, 99, 167,
2076 91, 91, 155, 83, 87, 143, 75, 79, 127, 71, 71, 115,
2077 63, 63, 103, 55, 55, 87, 47, 47, 75, 39, 39, 63,
2078 35, 31, 47, 27, 23, 35, 19, 15, 23, 11, 7, 7,
2079 155, 171, 123, 143, 159, 111, 135, 151, 99, 123, 139, 87,
2080 115, 131, 75, 103, 119, 67, 95, 111, 59, 87, 103, 51,
2081 75, 91, 39, 63, 79, 27, 55, 67, 19, 47, 59, 11,
2082 35, 47, 7, 27, 35, 0, 19, 23, 0, 11, 15, 0,
2083 0, 255, 0, 35, 231, 15, 63, 211, 27, 83, 187, 39,
2084 95, 167, 47, 95, 143, 51, 95, 123, 51, 255, 255, 255,
2085 255, 255, 211, 255, 255, 167, 255, 255, 127, 255, 255, 83,
2086 255, 255, 39, 255, 235, 31, 255, 215, 23, 255, 191, 15,
2087 255, 171, 7, 255, 147, 0, 239, 127, 0, 227, 107, 0,
2088 211, 87, 0, 199, 71, 0, 183, 59, 0, 171, 43, 0,
2089 155, 31, 0, 143, 23, 0, 127, 15, 0, 115, 7, 0,
2090 95, 0, 0, 71, 0, 0, 47, 0, 0, 27, 0, 0,
2091 239, 0, 0, 55, 55, 255, 255, 0, 0, 0, 0, 255,
2092 43, 43, 35, 27, 27, 23, 19, 19, 15, 235, 151, 127,
2093 195, 115, 83, 159, 87, 51, 123, 63, 27, 235, 211, 199,
2094 199, 171, 155, 167, 139, 119, 135, 107, 87, 159, 91, 83
2095 };
2096 #endif
2097
2098 int
Draw_GetPalette(void)2099 Draw_GetPalette(void)
2100 {
2101 int i;
2102 int r, g, b;
2103 unsigned v;
2104 byte *pic, *pal;
2105 int width, height;
2106 #ifndef QMAX
2107 byte default_pal[768];
2108 #endif
2109
2110 /* get the palette */
2111
2112 LoadPCX("pics/colormap.pcx", &pic, &pal, &width, &height);
2113 if (!pal) {
2114 ri.Sys_Error(ERR_FATAL, "Couldn't load pics/colormap.pcx");
2115 } else
2116 for (i = 0; i < 256; i++) {
2117 r = pal[i * 3 + 0];
2118 g = pal[i * 3 + 1];
2119 b = pal[i * 3 + 2];
2120
2121 v = (255 << 24) + (r << 0) + (g << 8) + (b << 16);
2122 d_8to24table[i] = LittleLong(v);
2123 #ifndef QMAX
2124 d_8to24tablef[i][0] = r * 0.003921568627450980392156862745098;
2125 d_8to24tablef[i][1] = g * 0.003921568627450980392156862745098;
2126 d_8to24tablef[i][2] = b * 0.003921568627450980392156862745098;
2127 #endif
2128 }
2129
2130 d_8to24table[255] &= LittleLong(0xffffff); /* 255 is transparent */
2131
2132 #ifdef QMAX
2133 free(pic);
2134 free(pal);
2135 #else
2136 if (pic)
2137 free(pic);
2138 if (pal != default_pal)
2139 free(pal);
2140 #endif
2141
2142 return 0;
2143 }
2144
2145
2146 /*
2147 * =============== GL_InitImages ===============
2148 */
2149 void
GL_InitImages(void)2150 GL_InitImages(void)
2151 {
2152 int i, j;
2153 float g = vid_gamma->value;
2154
2155 registration_sequence = 1;
2156
2157 /* init intensity conversions */
2158 /* Vic - begin */
2159 if (gl_config.mtexcombine)
2160 intensity = ri.Cvar_Get("intensity", "1.5", CVAR_ARCHIVE);
2161 else
2162 intensity = ri.Cvar_Get("intensity", "2", CVAR_ARCHIVE);
2163 /* Vic - end */
2164
2165 if (intensity->value <= 1)
2166 ri.Cvar_Set("intensity", "1");
2167
2168 gl_state.inverse_intensity = 1 / intensity->value;
2169
2170 Draw_GetPalette();
2171
2172 if (qglColorTableEXT) {
2173 ri.FS_LoadFile("pics/16to8.dat",
2174 (void **)&gl_state.d_16to8table);
2175 if (!gl_state.d_16to8table)
2176 ri.Sys_Error(ERR_FATAL, "Couldn't load pics/16to8.pcx");
2177 }
2178 if (gl_config.renderer & (GL_RENDERER_VOODOO | GL_RENDERER_VOODOO2)) {
2179 g = 1.0;
2180 }
2181 for (i = 0; i < 256; i++) {
2182 if (g == 1 || gl_state.hwgamma) {
2183 gammatable[i] = i;
2184 } else {
2185 float inf;
2186
2187 inf = 255 * pow((i + 0.5) * DIV255, g) + 0.5;
2188 if (inf < 0)
2189 inf = 0;
2190 if (inf > 255)
2191 inf = 255;
2192 gammatable[i] = inf;
2193 }
2194 }
2195
2196 for (i = 0; i < 256; i++) {
2197 j = i * intensity->value;
2198 if (j > 255)
2199 j = 255;
2200 intensitytable[i] = j;
2201 }
2202
2203 R_InitBloomTextures(); /* BLOOMS */
2204 }
2205
2206 /*
2207 * =============== GL_ShutdownImages ===============
2208 */
2209 void
GL_ShutdownImages(void)2210 GL_ShutdownImages(void)
2211 {
2212 int i;
2213 image_t *image;
2214
2215 for (i = 0, image = gltextures; i < numgltextures; i++, image++) {
2216 if (!image->registration_sequence)
2217 continue; /* free image_t slot */
2218 /* free it */
2219 qglDeleteTextures(1, (GLuint *)&image->texnum);
2220 memset(image, 0, sizeof(*image));
2221 }
2222 }
2223