vkQuake2 doxygen  1.0 dev
r_draw.c
Go to the documentation of this file.
1 /*
2 Copyright (C) 1997-2001 Id Software, Inc.
3 
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
8 
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or 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
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 
19 */
20 
21 // draw.c
22 
23 #include "r_local.h"
24 
25 
26 image_t *draw_chars; // 8*8 graphic characters
27 
28 #define COLORLEVELS 64
29 #define PALBRIGHTS 0 //qb: wow, Q2 doesn't have fullbrights?
30 
31 
32 /*
33 ================
34 Draw_FindPic
35 ================
36 */
38 {
39  image_t *image;
40  char fullname[MAX_QPATH];
41 
42  if (name[0] != '/' && name[0] != '\\')
43  {
44  Com_sprintf(fullname, sizeof(fullname), "pics/%s.pcx", name);
45  image = R_FindImage(fullname, it_pic);
46  }
47  else
48  image = R_FindImage(name + 1, it_pic);
49 
50  return image;
51 }
52 
53 
54 
55 void Draw_8to24(byte *palette)
56 {
57  byte *pal;
58  unsigned r, g, b;
59  unsigned v;
60  unsigned short i;
61  byte *table;
62  float gamma = 0;
63 
64  //
65  // 8 8 8 encoding
66  //
67  pal = palette;
68  table = (byte *)d_8to24tabble;
69  for (i = 0; i<256; i++)
70  {
71  // Con_Printf ("."); // loop an indicator
72  r = pal[0];
73  g = pal[1];
74  b = pal[2];
75 
76  if (r>255) r = 255;
77  if (g > 255) g = 255;
78  if (b > 255) b = 255;
79  pal += 3;
80  v = (255 << 24) + (r << 0) + (g << 8) + (b << 16);
81  *table++ = v;
82  }
83 
84  // The 15-bit table we use is actually made elsewhere (it's palmap)
85 
86  d_8to24tabble[255] &= 0xffffff; // 255 is transparent
87  //qb: gray is the new black.. d_8to24tabble[0] &= 0x000000; // black is black
88 }
89 
90 // leilei - Colored Lights
91 byte palmap2[64][64][64]; // Higher quality for lighting
92 
93 //Sys_Error("butts");
94 // this is just a lookup table version of the above
95 
96 int FindColor(int r, int g, int b)
97 {
98  int bestcolor;
99 
100  if (r > 255)r = 255; if (r < 0)r = 0;
101  if (g > 255)g = 255; if (g < 0)g = 0;
102  if (b > 255)b = 255; if (b < 0)b = 0;
103  bestcolor = palmap2[r >> 3][g >> 3][b >> 3];
104  return bestcolor;
105 }
106 
107 
108 
109 
110 // o^_^o
111 
112 /*
113 ===============
114 BestColor
115 
116 comes from lumpy
117 ===============
118 */
119 
120 
121 /*
122 =============
123 R_CalcPalette
124 
125 =============
126 
127 byte *thepalette;
128 
129 void R_GetPalette(void)
130 {
131  thepalette = (byte *)d_8to24table;
132 }
133 */
134 
135 byte BestColor(int r, int g, int b, int start, int stop)
136 {
137  int i;
138  int dr, dg, db;
139  int bestdistortion, distortion;
140  int berstcolor;
141  byte *pal;
142 
143  //
144  // let any color go to 0 as a last resort
145  //
146  // R_GetPalette();
147  bestdistortion = 256 * 256 * 4;
148  berstcolor = 0;
149 
150  if (r > 255) r = 255;
151  if (g > 255) g = 255;
152  if (b > 255) b = 255;
153 
154  pal = (byte *)d_8to24table + start * 4;
155  for (i = start; i <= stop; i++)
156  {
157  dr = r - (int)pal[0];
158  dg = g - (int)pal[1];
159  db = b - (int)pal[2];
160  pal += 4;
161  distortion = dr*dr + dg*dg + db*db + dr * 5 + dg * 5 + db * 5; //qb: this will increase color sensitity at low brightness. Added + dr + dg + db
162  if (distortion < bestdistortion)
163  {
164  if (!distortion)
165  return i; // perfect match
166 
167  bestdistortion = distortion;
168  berstcolor = i;
169  }
170  }
171  return berstcolor;
172 }
173 
174 void Draw_InitRGBMap(void)
175 {
176  int r, g, b;
177  float ra, ga, ba, ia;
178  int beastcolor;
179  float mypow = 1 / 1.3;
180  float mydiv = 200;
181  float mysat = r_lightsaturation->value; // was 1.6;
182 
183  // Make the 18-bit lookup table here
184  // This is a HUGE 256kb table, the biggest there is here
185  // TODO: Option to enable this
186 
187  {
188  Draw_8to24((byte *)d_8to24table);
189  for (r = 0; r < 256; r += 4)
190  {
191  for (g = 0; g < 256; g += 4)
192  {
193  for (b = 0; b < 256; b += 4)
194  {
195  // 3dfx gamma hack, trying to match the saturation and gamma of the refgl+3dfxgl combo so many q2 players are familiar with
196 
197  ra = pow(r / mydiv, mypow) * mydiv;
198  ga = pow(g / mydiv, mypow) * mydiv;
199  ba = pow(b / mydiv, mypow) * mydiv;
200 
201  ia = (ra * 0.333) + (ga * 0.333) + (ba * 0.333);
202  ra = ia + (ra - ia) * mysat;
203  ga = ia + (ga - ia) * mysat;
204  ba = ia + (ba - ia) * mysat;
205  //beastcolor = BestColor (pow(ra / mydiv, mypow) * mydiv, pow(ga / mydiv, mypow) * mydiv, pow(ba / mydiv, mypow) * mydiv, 1, 254);
206  beastcolor = BestColor((int)ra, (int)ga, (int)ba, 1, 254);
207  //beastcolor = BestColor (ra, ga, ba, 1, 254);
208  palmap2[r >> 2][g >> 2][b >> 2] = beastcolor;
209 
210  }
211  }
212  }
213  }
214 }
215 
216 
217 /*
218 ===============
219 Draw_InitLocal
220 ===============
221 */
222 void Draw_InitLocal(void)
223 {
224  draw_chars = Draw_FindPic("conchars");
225  // Knightmare- error out instead of crashing if we can't load this
226  if (!draw_chars)
227  ri.Sys_Error(ERR_FATAL, "Couldn't load pics/conchars.pcx");
228  // end Knightmare
229 }
230 
231 
232 
233 /*
234 ================
235 Draw_Char
236 
237 Draws one 8*8 graphics character
238 It can be clipped to the top of the screen to allow the console to be
239 smoothly scrolled off.
240 ================
241 */
242 void Draw_Char(int x, int y, int num)
243 {
244  byte *dest;
245  byte *source;
246  byte *src;
247  int drawline;
248  int row, col, f, i, v, skip = 0;
249  int fstep, tbyte, sv;
250 
251  num &= 255;
252 
253  if (num == 32 || num == 32 + 128)
254  return;
255 
256  if (y <= -8)
257  return; // totally off screen
258 
259  // if ( ( y + 8 ) >= vid.height )
260  if ((y + 8) > vid.height) // PGM - status text was missing in sw...
261  return;
262 
263  cvar_t *scale = ri.Cvar_Get("hudscale", "1", 0);
264 
265 #ifdef PARANOID
266  if (y > vid.height - 8 || x < 0 || x > vid.width - 8)
267  ri.Sys_Error(ERR_FATAL, "Con_DrawCharacter: (%i, %i)", x, y);
268  if (num < 0 || num > 255)
269  ri.Sys_Error(ERR_FATAL, "Con_DrawCharacter: char %i", num);
270 #endif
271 
272  row = num >> 4;
273  col = num & 15;
274  source = draw_chars->pixels[0] + (row << 10) + (col << 3);
275 
276  if (y < 0)
277  { // clipped
278  skip = y;
279  drawline = 8 * scale->value + y;
280  source -= 128 * y;
281  y = 0;
282  }
283  else
284  drawline = 8 * scale->value;
285 
286  dest = vid.buffer + y*vid.rowbytes + x;
287  fstep = 0x8000 / scale->value;
288 
289  for (v = 0; v < drawline; v++, dest += vid.rowbytes)
290  {
291  sv = (skip + v) / scale->value;
292  src = source + sv * draw_chars->width;
293  f = 0;
294 
295  for (i = 0; i < 8 * scale->value; i += 4)
296  {
297  if ((tbyte = src[f >> 15]) != TRANSPARENT_COLOR)
298  dest[i] = tbyte;
299  f += fstep;
300 
301  if ((tbyte = src[f >> 15]) != TRANSPARENT_COLOR)
302  dest[i + 1] = tbyte;
303  f += fstep;
304 
305  if ((tbyte = src[f >> 15]) != TRANSPARENT_COLOR)
306  dest[i + 2] = tbyte;
307  f += fstep;
308 
309  if ((tbyte = src[f >> 15]) != TRANSPARENT_COLOR)
310  dest[i + 3] = tbyte;
311  f += fstep;
312  }
313  }
314 }
315 
316 /*
317 =============
318 Draw_GetPicSize
319 =============
320 */
321 void Draw_GetPicSize(int *w, int *h, char *pic)
322 {
323  image_t *gl;
324 
325  gl = Draw_FindPic(pic);
326  if (!gl)
327  {
328  *w = *h = -1;
329  return;
330  }
331  cvar_t *scale = ri.Cvar_Get("hudscale", "1", 0);
332 
333  *w = gl->width*scale->value;
334  *h = gl->height*scale->value;
335 }
336 
337 /*
338 =============
339 Draw_StretchPicImplementation
340 =============
341 */
342 void Draw_StretchPicImplementation(int x, int y, int w, int h, image_t *pic)
343 {
344  byte *dest, *source;
345  int v, u, sv;
346  int height;
347  int f, fstep;
348  int skip;
349  int tbyte;
350 
351  w = (int)(w / 4) * 4; //qb: for DIB, sigh... probably should be 'ifdef DIB'
352  if ((x < 0) ||
353  (x + w > vid.width) ||
354  (y + h > vid.height))
355  {
356  ri.Sys_Error(ERR_FATAL, "Draw_Pic: bad coordinates");
357  }
358 
359  height = h;
360  if (y < 0)
361  {
362  skip = -y;
363  height += y;
364  y = 0;
365  }
366  else
367  skip = 0;
368 
369  dest = vid.buffer + y * vid.rowbytes + x;
370 
371  for (v = 0; v < height; v++, dest += vid.rowbytes)
372  {
373  sv = (skip + v)*pic->height / h;
374  source = pic->pixels[0] + sv*pic->width;
375  if (w == pic->width)
376  memcpy(dest, source, w);
377  else
378  {
379  f = 0;
380  fstep = pic->width * 0x10000 / w;
381  for (u = 0; u < w; u += 4)
382  {
383  if((tbyte = source[f >> 16]) != TRANSPARENT_COLOR)
384  dest[u] = tbyte;
385  f += fstep;
386  if ((tbyte = source[f >> 16]) != TRANSPARENT_COLOR)
387  dest[u + 1] = tbyte;
388  f += fstep;
389  if ((tbyte = source[f >> 16]) != TRANSPARENT_COLOR)
390  dest[u + 2] = tbyte;
391  f += fstep;
392  if ((tbyte = source[f >> 16]) != TRANSPARENT_COLOR)
393  dest[u + 3] = tbyte;
394  f += fstep;
395  }
396  }
397  }
398 }
399 
400 /*
401 =============
402 Draw_StretchPic
403 =============
404 */
405 void Draw_StretchPic(int x, int y, int w, int h, char *name)
406 {
407  image_t *pic;
408 
409  pic = Draw_FindPic(name);
410  if (!pic)
411  {
412  ri.Con_Printf(PRINT_ALL, "Can't find pic: %s\n", name);
413  return;
414  }
415  Draw_StretchPicImplementation(x, y, w, h, pic);
416 }
417 
418 /*
419 =============
420 Draw_StretchRaw
421 =============
422 */
423 void Draw_StretchRaw(int x, int y, int w, int h, int cols, int rows, byte *data)
424 {
425  image_t pic;
426 
427  pic.pixels[0] = data;
428  pic.width = cols;
429  pic.height = rows;
430  Draw_StretchPicImplementation(x, y, w, h, &pic);
431 }
432 
433 /*
434 =============
435 Draw_Pic
436 =============
437 */
438 void Draw_Pic(int x, int y, char *name)
439 {
440  image_t *pic;
441  byte *dest, *source;
442  int v, u;
443  int tbyte;
444  int height;
445 
446  pic = Draw_FindPic(name);
447  if (!pic)
448  {
449  ri.Con_Printf(PRINT_ALL, "Can't find pic: %s\n", name);
450  return;
451  }
452 
453  cvar_t *scale = ri.Cvar_Get("hudscale", "1", 0);
454  if (scale->value > 1.f)
455  {
456  Draw_StretchPicImplementation(x, y, pic->width*scale->value, pic->height*scale->value, pic);
457  return;
458  }
459 
460  if ((x < 0) ||
461  (x + pic->width > vid.width) ||
462  (y + pic->height > vid.height))
463  return; // ri.Sys_Error (ERR_FATAL,"Draw_Pic: bad coordinates");
464 
465  height = pic->height;
466  source = pic->pixels[0];
467  if (y < 0)
468  {
469  height += y;
470  source += pic->width*-y;
471  y = 0;
472  }
473 
474  dest = vid.buffer + y * vid.rowbytes + x;
475 
476  if (!pic->transparent)
477  {
478  for (v = 0; v < height; v++)
479  {
480  memcpy(dest, source, pic->width);
481  dest += vid.rowbytes;
482  source += pic->width;
483  }
484  }
485  else
486  {
487  if (pic->width & 7)
488  { // general
489  for (v = 0; v < height; v++)
490  {
491  for (u = 0; u < pic->width; u++)
492  if ((tbyte = source[u]) != TRANSPARENT_COLOR)
493  dest[u] = tbyte;
494 
495  dest += vid.rowbytes;
496  source += pic->width;
497  }
498  }
499  else
500  { // unwound
501  for (v = 0; v < height; v++)
502  {
503  for (u = 0; u < pic->width; u += 8)
504  {
505  if ((tbyte = source[u]) != TRANSPARENT_COLOR)
506  dest[u] = tbyte;
507  if ((tbyte = source[u + 1]) != TRANSPARENT_COLOR)
508  dest[u + 1] = tbyte;
509  if ((tbyte = source[u + 2]) != TRANSPARENT_COLOR)
510  dest[u + 2] = tbyte;
511  if ((tbyte = source[u + 3]) != TRANSPARENT_COLOR)
512  dest[u + 3] = tbyte;
513  if ((tbyte = source[u + 4]) != TRANSPARENT_COLOR)
514  dest[u + 4] = tbyte;
515  if ((tbyte = source[u + 5]) != TRANSPARENT_COLOR)
516  dest[u + 5] = tbyte;
517  if ((tbyte = source[u + 6]) != TRANSPARENT_COLOR)
518  dest[u + 6] = tbyte;
519  if ((tbyte = source[u + 7]) != TRANSPARENT_COLOR)
520  dest[u + 7] = tbyte;
521  }
522  dest += vid.rowbytes;
523  source += pic->width;
524  }
525  }
526  }
527 }
528 
529 /*
530 =============
531 Draw_TileClear
532 
533 This repeats a 64*64 tile graphic to fill the screen around a sized down
534 refresh window.
535 =============
536 */
537 void Draw_TileClear(int x, int y, int w, int h, char *name)
538 {
539  int i, j;
540  byte *psrc;
541  byte *pdest;
542  image_t *pic;
543  int x2;
544 
545  if (x < 0)
546  {
547  w += x;
548  x = 0;
549  }
550  if (y < 0)
551  {
552  h += y;
553  y = 0;
554  }
555  if (x + w > vid.width)
556  w = vid.width - x;
557  if (y + h > vid.height)
558  h = vid.height - y;
559  if (w <= 0 || h <= 0)
560  return;
561 
562  pic = Draw_FindPic(name);
563  if (!pic)
564  {
565  ri.Con_Printf(PRINT_ALL, "Can't find pic: %s\n", name);
566  return;
567  }
568  x2 = x + w;
570  for (i = 0; i < h; i++, pdest += vid.rowbytes)
571  {
572  psrc = pic->pixels[0] + pic->width * ((i + y) & 63);
573  for (j = x; j < x2; j++)
574  pdest[j] = psrc[j & 63];
575  }
576 }
577 
578 
579 /*
580 =============
581 Draw_Fill
582 
583 Fills a box of pixels with a single color
584 =============
585 */
586 void Draw_Fill(int x, int y, int w, int h, int c)
587 {
588  byte *dest;
589  int u, v;
590 
591  if (x + w > vid.width)
592  w = vid.width - x;
593  if (y + h > vid.height)
594  h = vid.height - y;
595  if (x < 0)
596  {
597  w += x;
598  x = 0;
599  }
600  if (y < 0)
601  {
602  h += y;
603  y = 0;
604  }
605  if (w < 0 || h < 0)
606  return;
607  dest = vid.buffer + y*vid.rowbytes + x;
608  for (v = 0; v < h; v++, dest += vid.rowbytes)
609  for (u = 0; u < w; u++)
610  dest[u] = c;
611 }
612 //=============================================================================
613 
614 /*
615 ================
616 Draw_FadeScreen
617 
618 ================
619 */
620 void Draw_FadeScreen(void)
621 {
622  int x, y;
623  byte *pbuf;
624  int t;
625 
626  for (y = 0; y < vid.height; y++)
627  {
628  pbuf = (byte *)(vid.buffer + vid.rowbytes*y);
629  t = (y & 1) << 1;
630 
631  for (x = 0; x < vid.width; x++)
632  {
633  if ((x & 3) != t)
634  pbuf[x] = 0;
635  }
636  }
637 }
sv
server_t sv
Definition: sv_init.c:24
height
GLsizei height
Definition: qgl_win.c:69
MAX_QPATH
#define MAX_QPATH
Definition: q_shared.h:80
int
CONST PIXELFORMATDESCRIPTOR int
Definition: qgl_win.c:35
viddef_t::buffer
pixel_t * buffer
Definition: r_local.h:94
Draw_StretchRaw
void Draw_StretchRaw(int x, int y, int w, int h, int cols, int rows, byte *data)
Definition: r_draw.c:423
ri
refimport_t ri
Definition: r_main.c:25
v
GLdouble v
Definition: qgl_win.c:143
x2
GLdouble GLdouble x2
Definition: qgl_win.c:301
refimport_t::Cvar_Get
cvar_t *(* Cvar_Get)(char *name, char *value, int flags)
Definition: ref.h:216
R_FindImage
image_t * R_FindImage(char *name, imagetype_t type)
Definition: r_image.c:491
x
GLint GLenum GLint x
Definition: qgl_win.c:116
i
int i
Definition: q_shared.c:305
Draw_Char
void Draw_Char(int x, int y, int num)
Definition: r_draw.c:242
r_local.h
skip
static void skip(vorb *z, int n)
Definition: stb_vorbis.c:1336
cvar_s
Definition: q_shared.h:324
BestColor
byte BestColor(int r, int g, int b, int start, int stop)
Definition: r_draw.c:135
j
GLint j
Definition: qgl_win.c:150
d_8to24tabble
unsigned d_8to24tabble[256]
Definition: r_main.c:28
Draw_8to24
void Draw_8to24(byte *palette)
Definition: r_draw.c:55
Draw_Fill
void Draw_Fill(int x, int y, int w, int h, int c)
Definition: r_draw.c:586
Draw_InitRGBMap
void Draw_InitRGBMap(void)
Definition: r_draw.c:174
refimport_t::Con_Printf
void(* Con_Printf)(int print_level, char *str,...)
Definition: ref.h:202
u
static int u
Definition: r_part.c:472
PRINT_ALL
#define PRINT_ALL
Definition: qcommon.h:751
Draw_FadeScreen
void Draw_FadeScreen(void)
Definition: r_draw.c:620
Draw_InitLocal
void Draw_InitLocal(void)
Definition: r_draw.c:222
it_pic
@ it_pic
Definition: r_local.h:67
viddef_t::rowbytes
int rowbytes
Definition: r_local.h:97
r
GLdouble GLdouble r
Definition: qgl_win.c:336
image_s::height
int height
Definition: r_local.h:75
viddef_t::width
unsigned width
Definition: vid.h:29
Draw_StretchPicImplementation
void Draw_StretchPicImplementation(int x, int y, int w, int h, image_t *pic)
Definition: r_draw.c:342
t
GLdouble t
Definition: qgl_win.c:328
refimport_t::Sys_Error
void(* Sys_Error)(int err_level, char *str,...)
Definition: ref.h:194
palmap2
byte palmap2[64][64][64]
Definition: r_draw.c:91
viddef_t::height
unsigned height
Definition: vid.h:29
cvar_s::value
float value
Definition: q_shared.h:331
Draw_TileClear
void Draw_TileClear(int x, int y, int w, int h, char *name)
Definition: r_draw.c:537
image_s::pixels
byte * pixels[4]
Definition: r_local.h:78
image_s::width
int width
Definition: r_local.h:75
image_s::transparent
qboolean transparent
Definition: r_local.h:76
name
cvar_t * name
Definition: cl_main.c:79
ERR_FATAL
#define ERR_FATAL
Definition: qcommon.h:743
y
GLint y
Definition: qgl_win.c:115
d_8to24table
unsigned d_8to24table[256]
Definition: r_main.c:27
pdest
static byte * pdest
Definition: r_part.c:470
Draw_GetPicSize
void Draw_GetPicSize(int *w, int *h, char *pic)
Definition: r_draw.c:321
Draw_Pic
void Draw_Pic(int x, int y, char *name)
Definition: r_draw.c:438
Draw_FindPic
image_t * Draw_FindPic(char *name)
Definition: r_draw.c:37
FindColor
int FindColor(int r, int g, int b)
Definition: r_draw.c:96
w
GLdouble GLdouble GLdouble w
Definition: qgl_win.c:291
image_s
Definition: r_local.h:71
Draw_StretchPic
void Draw_StretchPic(int x, int y, int w, int h, char *name)
Definition: r_draw.c:405
r_lightsaturation
cvar_t * r_lightsaturation
Definition: r_main.c:155
TRANSPARENT_COLOR
#define TRANSPARENT_COLOR
Definition: asm_i386.h:78
draw_chars
image_t * draw_chars
Definition: r_draw.c:26
Com_sprintf
void Com_sprintf(char *dest, int size, char *fmt,...)
Definition: q_shared.c:1223
vid
viddef_t vid
Definition: r_main.c:24