icculus quake2 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 //=============================================================================
29 
30 /*
31 ================
32 Draw_FindPic
33 ================
34 */
36 {
37  image_t *image;
38  char fullname[MAX_QPATH];
39 
40  if (name[0] != '/' && name[0] != '\\')
41  {
42  Com_sprintf (fullname, sizeof(fullname), "pics/%s.pcx", name);
43  image = R_FindImage (fullname, it_pic);
44  }
45  else
46  image = R_FindImage (name+1, it_pic);
47 
48  return image;
49 }
50 
51 
52 
53 /*
54 ===============
55 Draw_InitLocal
56 ===============
57 */
58 void Draw_InitLocal (void)
59 {
60  draw_chars = Draw_FindPic ("conchars");
61 }
62 
63 
64 
65 /*
66 ================
67 Draw_Char
68 
69 Draws one 8*8 graphics character
70 It can be clipped to the top of the screen to allow the console to be
71 smoothly scrolled off.
72 ================
73 */
74 void Draw_Char (int x, int y, int num)
75 {
76  byte *dest;
77  byte *source;
78  int drawline;
79  int row, col;
80 
81  num &= 255;
82 
83  if (num == 32 || num == 32+128)
84  return;
85 
86  if (y <= -8)
87  return; // totally off screen
88 
89 // if ( ( y + 8 ) >= vid.height )
90  if ( ( y + 8 ) > vid.height ) // PGM - status text was missing in sw...
91  return;
92 
93 #ifdef PARANOID
94  if (y > vid.height - 8 || x < 0 || x > vid.width - 8)
95  ri.Sys_Error (ERR_FATAL,"Con_DrawCharacter: (%i, %i)", x, y);
96  if (num < 0 || num > 255)
97  ri.Sys_Error (ERR_FATAL,"Con_DrawCharacter: char %i", num);
98 #endif
99 
100  row = num>>4;
101  col = num&15;
102  source = draw_chars->pixels[0] + (row<<10) + (col<<3);
103 
104  if (y < 0)
105  { // clipped
106  drawline = 8 + y;
107  source -= 128*y;
108  y = 0;
109  }
110  else
111  drawline = 8;
112 
113 
114  dest = vid.buffer + y*vid.rowbytes + x;
115 
116  while (drawline--)
117  {
118  if (source[0] != TRANSPARENT_COLOR)
119  dest[0] = source[0];
120  if (source[1] != TRANSPARENT_COLOR)
121  dest[1] = source[1];
122  if (source[2] != TRANSPARENT_COLOR)
123  dest[2] = source[2];
124  if (source[3] != TRANSPARENT_COLOR)
125  dest[3] = source[3];
126  if (source[4] != TRANSPARENT_COLOR)
127  dest[4] = source[4];
128  if (source[5] != TRANSPARENT_COLOR)
129  dest[5] = source[5];
130  if (source[6] != TRANSPARENT_COLOR)
131  dest[6] = source[6];
132  if (source[7] != TRANSPARENT_COLOR)
133  dest[7] = source[7];
134  source += 128;
135  dest += vid.rowbytes;
136  }
137 }
138 
139 /*
140 =============
141 Draw_GetPicSize
142 =============
143 */
144 void Draw_GetPicSize (int *w, int *h, char *pic)
145 {
146  image_t *gl;
147 
148  gl = Draw_FindPic (pic);
149  if (!gl)
150  {
151  *w = *h = -1;
152  return;
153  }
154  *w = gl->width;
155  *h = gl->height;
156 }
157 
158 /*
159 =============
160 Draw_StretchPicImplementation
161 =============
162 */
163 void Draw_StretchPicImplementation (int x, int y, int w, int h, image_t *pic)
164 {
165  byte *dest, *source;
166  int v, u, sv;
167  int height;
168  int f, fstep;
169  int skip;
170 
171  if ((x < 0) ||
172  (x + w > vid.width) ||
173  (y + h > vid.height))
174  {
175  ri.Sys_Error (ERR_FATAL,"Draw_Pic: bad coordinates");
176  }
177 
178  height = h;
179  if (y < 0)
180  {
181  skip = -y;
182  height += y;
183  y = 0;
184  }
185  else
186  skip = 0;
187 
188  dest = vid.buffer + y * vid.rowbytes + x;
189 
190  for (v=0 ; v<height ; v++, dest += vid.rowbytes)
191  {
192  sv = (skip + v)*pic->height/h;
193  source = pic->pixels[0] + sv*pic->width;
194  if (w == pic->width)
195  memcpy (dest, source, w);
196  else
197  {
198  f = 0;
199  fstep = pic->width*0x10000/w;
200  for (u=0 ; u<w ; u+=4)
201  {
202  dest[u] = source[f>>16];
203  f += fstep;
204  dest[u+1] = source[f>>16];
205  f += fstep;
206  dest[u+2] = source[f>>16];
207  f += fstep;
208  dest[u+3] = source[f>>16];
209  f += fstep;
210  }
211  }
212  }
213 }
214 
215 /*
216 =============
217 Draw_StretchPic
218 =============
219 */
220 void Draw_StretchPic (int x, int y, int w, int h, char *name)
221 {
222  image_t *pic;
223 
224  pic = Draw_FindPic (name);
225  if (!pic)
226  {
227  ri.Con_Printf (PRINT_ALL, "Can't find pic: %s\n", name);
228  return;
229  }
230  Draw_StretchPicImplementation (x, y, w, h, pic);
231 }
232 
233 /*
234 =============
235 Draw_StretchRaw
236 =============
237 */
238 void Draw_StretchRaw (int x, int y, int w, int h, int cols, int rows, byte *data)
239 {
240  image_t pic;
241 
242  pic.pixels[0] = data;
243  pic.width = cols;
244  pic.height = rows;
245  Draw_StretchPicImplementation (x, y, w, h, &pic);
246 }
247 
248 /*
249 =============
250 Draw_Pic
251 =============
252 */
253 void Draw_Pic (int x, int y, char *name)
254 {
255  image_t *pic;
256  byte *dest, *source;
257  int v, u;
258  int tbyte;
259  int height;
260 
261  pic = Draw_FindPic (name);
262  if (!pic)
263  {
264  ri.Con_Printf (PRINT_ALL, "Can't find pic: %s\n", name);
265  return;
266  }
267 
268  if ((x < 0) ||
269  (x + pic->width > vid.width) ||
270  (y + pic->height > vid.height))
271  return; // ri.Sys_Error (ERR_FATAL,"Draw_Pic: bad coordinates");
272 
273  height = pic->height;
274  source = pic->pixels[0];
275  if (y < 0)
276  {
277  height += y;
278  source += pic->width*-y;
279  y = 0;
280  }
281 
282  dest = vid.buffer + y * vid.rowbytes + x;
283 
284  if (!pic->transparent)
285  {
286  for (v=0 ; v<height ; v++)
287  {
288  memcpy (dest, source, pic->width);
289  dest += vid.rowbytes;
290  source += pic->width;
291  }
292  }
293  else
294  {
295  if (pic->width & 7)
296  { // general
297  for (v=0 ; v<height ; v++)
298  {
299  for (u=0 ; u<pic->width ; u++)
300  if ( (tbyte=source[u]) != TRANSPARENT_COLOR)
301  dest[u] = tbyte;
302 
303  dest += vid.rowbytes;
304  source += pic->width;
305  }
306  }
307  else
308  { // unwound
309  for (v=0 ; v<height ; v++)
310  {
311  for (u=0 ; u<pic->width ; u+=8)
312  {
313  if ( (tbyte=source[u]) != TRANSPARENT_COLOR)
314  dest[u] = tbyte;
315  if ( (tbyte=source[u+1]) != TRANSPARENT_COLOR)
316  dest[u+1] = tbyte;
317  if ( (tbyte=source[u+2]) != TRANSPARENT_COLOR)
318  dest[u+2] = tbyte;
319  if ( (tbyte=source[u+3]) != TRANSPARENT_COLOR)
320  dest[u+3] = tbyte;
321  if ( (tbyte=source[u+4]) != TRANSPARENT_COLOR)
322  dest[u+4] = tbyte;
323  if ( (tbyte=source[u+5]) != TRANSPARENT_COLOR)
324  dest[u+5] = tbyte;
325  if ( (tbyte=source[u+6]) != TRANSPARENT_COLOR)
326  dest[u+6] = tbyte;
327  if ( (tbyte=source[u+7]) != TRANSPARENT_COLOR)
328  dest[u+7] = tbyte;
329  }
330  dest += vid.rowbytes;
331  source += pic->width;
332  }
333  }
334  }
335 }
336 
337 /*
338 =============
339 Draw_TileClear
340 
341 This repeats a 64*64 tile graphic to fill the screen around a sized down
342 refresh window.
343 =============
344 */
345 void Draw_TileClear (int x, int y, int w, int h, char *name)
346 {
347  int i, j;
348  byte *psrc;
349  byte *pdest;
350  image_t *pic;
351  int x2;
352 
353  if (x < 0)
354  {
355  w += x;
356  x = 0;
357  }
358  if (y < 0)
359  {
360  h += y;
361  y = 0;
362  }
363  if (x + w > vid.width)
364  w = vid.width - x;
365  if (y + h > vid.height)
366  h = vid.height - y;
367  if (w <= 0 || h <= 0)
368  return;
369 
370  pic = Draw_FindPic (name);
371  if (!pic)
372  {
373  ri.Con_Printf (PRINT_ALL, "Can't find pic: %s\n", name);
374  return;
375  }
376  x2 = x + w;
377  pdest = vid.buffer + y*vid.rowbytes;
378  for (i=0 ; i<h ; i++, pdest += vid.rowbytes)
379  {
380  psrc = pic->pixels[0] + pic->width * ((i+y)&63);
381  for (j=x ; j<x2 ; j++)
382  pdest[j] = psrc[j&63];
383  }
384 }
385 
386 
387 /*
388 =============
389 Draw_Fill
390 
391 Fills a box of pixels with a single color
392 =============
393 */
394 void Draw_Fill (int x, int y, int w, int h, int c)
395 {
396  byte *dest;
397  int u, v;
398 
399  if (x+w > vid.width)
400  w = vid.width - x;
401  if (y+h > vid.height)
402  h = vid.height - y;
403  if (x < 0)
404  {
405  w += x;
406  x = 0;
407  }
408  if (y < 0)
409  {
410  h += y;
411  y = 0;
412  }
413  if (w < 0 || h < 0)
414  return;
415  dest = vid.buffer + y*vid.rowbytes + x;
416  for (v=0 ; v<h ; v++, dest += vid.rowbytes)
417  for (u=0 ; u<w ; u++)
418  dest[u] = c;
419 }
420 //=============================================================================
421 
422 /*
423 ================
424 Draw_FadeScreen
425 
426 ================
427 */
428 void Draw_FadeScreen (void)
429 {
430  int x,y;
431  byte *pbuf;
432  int t;
433 
434  for (y=0 ; y<vid.height ; y++)
435  {
436  pbuf = (byte *)(vid.buffer + vid.rowbytes*y);
437  t = (y & 1) << 1;
438 
439  for (x=0 ; x<vid.width ; x++)
440  {
441  if ((x & 3) != t)
442  pbuf[x] = 0;
443  }
444  }
445 }
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:73
viddef_t::buffer
pixel_t * buffer
Definition: r_local.h:88
Draw_StretchRaw
void Draw_StretchRaw(int x, int y, int w, int h, int cols, int rows, byte *data)
Definition: r_draw.c:238
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
R_FindImage
image_t * R_FindImage(char *name, imagetype_t type)
Definition: r_image.c:497
x
GLint GLenum GLint x
Definition: qgl_win.c:116
viddef_t::width
int width
Definition: vid.h:29
i
int i
Definition: q_shared.c:305
viddef_t::height
int height
Definition: vid.h:29
Draw_Char
void Draw_Char(int x, int y, int num)
Definition: r_draw.c:74
r_local.h
j
GLint j
Definition: qgl_win.c:150
Draw_Fill
void Draw_Fill(int x, int y, int w, int h, int c)
Definition: r_draw.c:394
refimport_t::Con_Printf
void(* Con_Printf)(int print_level, char *str,...)
Definition: ref.h:228
PRINT_ALL
#define PRINT_ALL
Definition: qcommon.h:743
Draw_FadeScreen
void Draw_FadeScreen(void)
Definition: r_draw.c:428
Draw_InitLocal
void Draw_InitLocal(void)
Definition: r_draw.c:58
it_pic
@ it_pic
Definition: r_local.h:61
viddef_t::rowbytes
int rowbytes
Definition: r_local.h:91
image_s::height
int height
Definition: r_local.h:69
Draw_StretchPicImplementation
void Draw_StretchPicImplementation(int x, int y, int w, int h, image_t *pic)
Definition: r_draw.c:163
t
GLdouble t
Definition: qgl_win.c:328
refimport_t::Sys_Error
void(* Sys_Error)(int err_level, char *str,...)
Definition: ref.h:220
Draw_TileClear
void Draw_TileClear(int x, int y, int w, int h, char *name)
Definition: r_draw.c:345
image_s::pixels
byte * pixels[4]
Definition: r_local.h:72
image_s::width
int width
Definition: r_local.h:69
image_s::transparent
qboolean transparent
Definition: r_local.h:70
name
cvar_t * name
Definition: cl_main.c:94
ERR_FATAL
#define ERR_FATAL
Definition: qcommon.h:735
y
GLint y
Definition: qgl_win.c:115
Draw_GetPicSize
void Draw_GetPicSize(int *w, int *h, char *pic)
Definition: r_draw.c:144
Draw_Pic
void Draw_Pic(int x, int y, char *name)
Definition: r_draw.c:253
Draw_FindPic
image_t * Draw_FindPic(char *name)
Definition: r_draw.c:35
w
GLdouble GLdouble GLdouble w
Definition: qgl_win.c:291
image_s
Definition: r_local.h:65
Draw_StretchPic
void Draw_StretchPic(int x, int y, int w, int h, char *name)
Definition: r_draw.c:220
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:1236
vid
viddef_t vid
Definition: r_main.c:24