diff options
Diffstat (limited to 'apps/plugins/sdl/progs/quake/draw.c')
-rw-r--r-- | apps/plugins/sdl/progs/quake/draw.c | 890 |
1 files changed, 890 insertions, 0 deletions
diff --git a/apps/plugins/sdl/progs/quake/draw.c b/apps/plugins/sdl/progs/quake/draw.c new file mode 100644 index 0000000000..2a2f65bf4c --- /dev/null +++ b/apps/plugins/sdl/progs/quake/draw.c | |||
@@ -0,0 +1,890 @@ | |||
1 | /* | ||
2 | Copyright (C) 1996-1997 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 -- this is the only file outside the refresh that touches the | ||
22 | // vid buffer | ||
23 | |||
24 | #include "quakedef.h" | ||
25 | |||
26 | typedef struct { | ||
27 | vrect_t rect; | ||
28 | int width; | ||
29 | int height; | ||
30 | byte *ptexbytes; | ||
31 | int rowbytes; | ||
32 | } rectdesc_t; | ||
33 | |||
34 | static rectdesc_t r_rectdesc; | ||
35 | |||
36 | byte *draw_chars; // 8*8 graphic characters | ||
37 | qpic_t *draw_disc; | ||
38 | qpic_t *draw_backtile; | ||
39 | |||
40 | //============================================================================= | ||
41 | /* Support Routines */ | ||
42 | |||
43 | typedef struct cachepic_s | ||
44 | { | ||
45 | char name[MAX_QPATH]; | ||
46 | cache_user_t cache; | ||
47 | } cachepic_t; | ||
48 | |||
49 | #define MAX_CACHED_PICS 128 | ||
50 | cachepic_t menu_cachepics[MAX_CACHED_PICS]; | ||
51 | int menu_numcachepics; | ||
52 | |||
53 | |||
54 | qpic_t *Draw_PicFromWad (char *name) | ||
55 | { | ||
56 | return W_GetLumpName (name); | ||
57 | } | ||
58 | |||
59 | /* | ||
60 | ================ | ||
61 | Draw_CachePic | ||
62 | ================ | ||
63 | */ | ||
64 | qpic_t *Draw_CachePic (char *path) | ||
65 | { | ||
66 | cachepic_t *pic; | ||
67 | int i; | ||
68 | qpic_t *dat; | ||
69 | |||
70 | for (pic=menu_cachepics, i=0 ; i<menu_numcachepics ; pic++, i++) | ||
71 | if (!strcmp (path, pic->name)) | ||
72 | break; | ||
73 | |||
74 | if (i == menu_numcachepics) | ||
75 | { | ||
76 | if (menu_numcachepics == MAX_CACHED_PICS) | ||
77 | Sys_Error ("menu_numcachepics == MAX_CACHED_PICS"); | ||
78 | menu_numcachepics++; | ||
79 | strcpy (pic->name, path); | ||
80 | } | ||
81 | |||
82 | dat = Cache_Check (&pic->cache); | ||
83 | |||
84 | if (dat) | ||
85 | return dat; | ||
86 | |||
87 | // | ||
88 | // load the pic from disk | ||
89 | // | ||
90 | COM_LoadCacheFile (path, &pic->cache); | ||
91 | |||
92 | dat = (qpic_t *)pic->cache.data; | ||
93 | if (!dat) | ||
94 | { | ||
95 | Sys_Error ("Draw_CachePic: failed to load %s", path); | ||
96 | } | ||
97 | |||
98 | SwapPic (dat); | ||
99 | |||
100 | return dat; | ||
101 | } | ||
102 | |||
103 | |||
104 | |||
105 | /* | ||
106 | =============== | ||
107 | Draw_Init | ||
108 | =============== | ||
109 | */ | ||
110 | void Draw_Init (void) | ||
111 | { | ||
112 | int i; | ||
113 | |||
114 | draw_chars = W_GetLumpName ("conchars"); | ||
115 | draw_disc = W_GetLumpName ("disc"); | ||
116 | draw_backtile = W_GetLumpName ("backtile"); | ||
117 | |||
118 | r_rectdesc.width = draw_backtile->width; | ||
119 | r_rectdesc.height = draw_backtile->height; | ||
120 | r_rectdesc.ptexbytes = draw_backtile->data; | ||
121 | r_rectdesc.rowbytes = draw_backtile->width; | ||
122 | } | ||
123 | |||
124 | |||
125 | |||
126 | /* | ||
127 | ================ | ||
128 | Draw_Character | ||
129 | |||
130 | Draws one 8*8 graphics character with 0 being transparent. | ||
131 | It can be clipped to the top of the screen to allow the console to be | ||
132 | smoothly scrolled off. | ||
133 | ================ | ||
134 | */ | ||
135 | void Draw_Character (int x, int y, int num) | ||
136 | { | ||
137 | byte *dest; | ||
138 | byte *source; | ||
139 | unsigned short *pusdest; | ||
140 | int drawline; | ||
141 | int row, col; | ||
142 | |||
143 | num &= 255; | ||
144 | |||
145 | if (y <= -8) | ||
146 | return; // totally off screen | ||
147 | |||
148 | #ifdef PARANOID | ||
149 | if (y > vid.height - 8 || x < 0 || x > vid.width - 8) | ||
150 | Sys_Error ("Con_DrawCharacter: (%i, %i)", x, y); | ||
151 | if (num < 0 || num > 255) | ||
152 | Sys_Error ("Con_DrawCharacter: char %i", num); | ||
153 | #endif | ||
154 | |||
155 | row = num>>4; | ||
156 | col = num&15; | ||
157 | source = draw_chars + (row<<10) + (col<<3); | ||
158 | |||
159 | if (y < 0) | ||
160 | { // clipped | ||
161 | drawline = 8 + y; | ||
162 | source -= 128*y; | ||
163 | y = 0; | ||
164 | } | ||
165 | else | ||
166 | drawline = 8; | ||
167 | |||
168 | |||
169 | if (r_pixbytes == 1) | ||
170 | { | ||
171 | dest = vid.conbuffer + y*vid.conrowbytes + x; | ||
172 | |||
173 | while (drawline--) | ||
174 | { | ||
175 | if (source[0]) | ||
176 | dest[0] = source[0]; | ||
177 | if (source[1]) | ||
178 | dest[1] = source[1]; | ||
179 | if (source[2]) | ||
180 | dest[2] = source[2]; | ||
181 | if (source[3]) | ||
182 | dest[3] = source[3]; | ||
183 | if (source[4]) | ||
184 | dest[4] = source[4]; | ||
185 | if (source[5]) | ||
186 | dest[5] = source[5]; | ||
187 | if (source[6]) | ||
188 | dest[6] = source[6]; | ||
189 | if (source[7]) | ||
190 | dest[7] = source[7]; | ||
191 | source += 128; | ||
192 | dest += vid.conrowbytes; | ||
193 | } | ||
194 | } | ||
195 | else | ||
196 | { | ||
197 | // FIXME: pre-expand to native format? | ||
198 | pusdest = (unsigned short *) | ||
199 | ((byte *)vid.conbuffer + y*vid.conrowbytes + (x<<1)); | ||
200 | |||
201 | while (drawline--) | ||
202 | { | ||
203 | if (source[0]) | ||
204 | pusdest[0] = d_8to16table[source[0]]; | ||
205 | if (source[1]) | ||
206 | pusdest[1] = d_8to16table[source[1]]; | ||
207 | if (source[2]) | ||
208 | pusdest[2] = d_8to16table[source[2]]; | ||
209 | if (source[3]) | ||
210 | pusdest[3] = d_8to16table[source[3]]; | ||
211 | if (source[4]) | ||
212 | pusdest[4] = d_8to16table[source[4]]; | ||
213 | if (source[5]) | ||
214 | pusdest[5] = d_8to16table[source[5]]; | ||
215 | if (source[6]) | ||
216 | pusdest[6] = d_8to16table[source[6]]; | ||
217 | if (source[7]) | ||
218 | pusdest[7] = d_8to16table[source[7]]; | ||
219 | |||
220 | source += 128; | ||
221 | pusdest += (vid.conrowbytes >> 1); | ||
222 | } | ||
223 | } | ||
224 | } | ||
225 | |||
226 | /* | ||
227 | ================ | ||
228 | Draw_String | ||
229 | ================ | ||
230 | */ | ||
231 | void Draw_String (int x, int y, char *str) | ||
232 | { | ||
233 | while (*str) | ||
234 | { | ||
235 | Draw_Character (x, y, *str); | ||
236 | str++; | ||
237 | x += 8; | ||
238 | } | ||
239 | } | ||
240 | |||
241 | /* | ||
242 | ================ | ||
243 | Draw_DebugChar | ||
244 | |||
245 | Draws a single character directly to the upper right corner of the screen. | ||
246 | This is for debugging lockups by drawing different chars in different parts | ||
247 | of the code. | ||
248 | ================ | ||
249 | */ | ||
250 | void Draw_DebugChar (char num) | ||
251 | { | ||
252 | byte *dest; | ||
253 | byte *source; | ||
254 | int drawline; | ||
255 | extern byte *draw_chars; | ||
256 | int row, col; | ||
257 | |||
258 | if (!vid.direct) | ||
259 | return; // don't have direct FB access, so no debugchars... | ||
260 | |||
261 | drawline = 8; | ||
262 | |||
263 | row = num>>4; | ||
264 | col = num&15; | ||
265 | source = draw_chars + (row<<10) + (col<<3); | ||
266 | |||
267 | dest = vid.direct + 312; | ||
268 | |||
269 | while (drawline--) | ||
270 | { | ||
271 | dest[0] = source[0]; | ||
272 | dest[1] = source[1]; | ||
273 | dest[2] = source[2]; | ||
274 | dest[3] = source[3]; | ||
275 | dest[4] = source[4]; | ||
276 | dest[5] = source[5]; | ||
277 | dest[6] = source[6]; | ||
278 | dest[7] = source[7]; | ||
279 | source += 128; | ||
280 | dest += 320; | ||
281 | } | ||
282 | } | ||
283 | |||
284 | /* | ||
285 | ============= | ||
286 | Draw_Pic | ||
287 | ============= | ||
288 | */ | ||
289 | void Draw_Pic (int x, int y, qpic_t *pic) | ||
290 | { | ||
291 | byte *dest, *source; | ||
292 | unsigned short *pusdest; | ||
293 | int v, u; | ||
294 | |||
295 | if ((x < 0) || | ||
296 | (x + pic->width > vid.width) || | ||
297 | (y < 0) || | ||
298 | (y + pic->height > vid.height)) | ||
299 | { | ||
300 | Sys_Error ("Draw_Pic: bad coordinates"); | ||
301 | } | ||
302 | |||
303 | source = pic->data; | ||
304 | |||
305 | if (r_pixbytes == 1) | ||
306 | { | ||
307 | dest = vid.buffer + y * vid.rowbytes + x; | ||
308 | |||
309 | for (v=0 ; v<pic->height ; v++) | ||
310 | { | ||
311 | Q_memcpy (dest, source, pic->width); | ||
312 | dest += vid.rowbytes; | ||
313 | source += pic->width; | ||
314 | } | ||
315 | } | ||
316 | else | ||
317 | { | ||
318 | // FIXME: pretranslate at load time? | ||
319 | pusdest = (unsigned short *)vid.buffer + y * (vid.rowbytes >> 1) + x; | ||
320 | |||
321 | for (v=0 ; v<pic->height ; v++) | ||
322 | { | ||
323 | for (u=0 ; u<pic->width ; u++) | ||
324 | { | ||
325 | pusdest[u] = d_8to16table[source[u]]; | ||
326 | } | ||
327 | |||
328 | pusdest += vid.rowbytes >> 1; | ||
329 | source += pic->width; | ||
330 | } | ||
331 | } | ||
332 | } | ||
333 | |||
334 | |||
335 | /* | ||
336 | ============= | ||
337 | Draw_TransPic | ||
338 | ============= | ||
339 | */ | ||
340 | void Draw_TransPic (int x, int y, qpic_t *pic) | ||
341 | { | ||
342 | byte *dest, *source, tbyte; | ||
343 | unsigned short *pusdest; | ||
344 | int v, u; | ||
345 | |||
346 | if (x < 0 || (unsigned)(x + pic->width) > vid.width || y < 0 || | ||
347 | (unsigned)(y + pic->height) > vid.height) | ||
348 | { | ||
349 | Sys_Error ("Draw_TransPic: bad coordinates"); | ||
350 | } | ||
351 | |||
352 | source = pic->data; | ||
353 | |||
354 | if (r_pixbytes == 1) | ||
355 | { | ||
356 | dest = vid.buffer + y * vid.rowbytes + x; | ||
357 | |||
358 | if (pic->width & 7) | ||
359 | { // general | ||
360 | for (v=0 ; v<pic->height ; v++) | ||
361 | { | ||
362 | for (u=0 ; u<pic->width ; u++) | ||
363 | if ( (tbyte=source[u]) != TRANSPARENT_COLOR) | ||
364 | dest[u] = tbyte; | ||
365 | |||
366 | dest += vid.rowbytes; | ||
367 | source += pic->width; | ||
368 | } | ||
369 | } | ||
370 | else | ||
371 | { // unwound | ||
372 | for (v=0 ; v<pic->height ; v++) | ||
373 | { | ||
374 | for (u=0 ; u<pic->width ; u+=8) | ||
375 | { | ||
376 | if ( (tbyte=source[u]) != TRANSPARENT_COLOR) | ||
377 | dest[u] = tbyte; | ||
378 | if ( (tbyte=source[u+1]) != TRANSPARENT_COLOR) | ||
379 | dest[u+1] = tbyte; | ||
380 | if ( (tbyte=source[u+2]) != TRANSPARENT_COLOR) | ||
381 | dest[u+2] = tbyte; | ||
382 | if ( (tbyte=source[u+3]) != TRANSPARENT_COLOR) | ||
383 | dest[u+3] = tbyte; | ||
384 | if ( (tbyte=source[u+4]) != TRANSPARENT_COLOR) | ||
385 | dest[u+4] = tbyte; | ||
386 | if ( (tbyte=source[u+5]) != TRANSPARENT_COLOR) | ||
387 | dest[u+5] = tbyte; | ||
388 | if ( (tbyte=source[u+6]) != TRANSPARENT_COLOR) | ||
389 | dest[u+6] = tbyte; | ||
390 | if ( (tbyte=source[u+7]) != TRANSPARENT_COLOR) | ||
391 | dest[u+7] = tbyte; | ||
392 | } | ||
393 | dest += vid.rowbytes; | ||
394 | source += pic->width; | ||
395 | } | ||
396 | } | ||
397 | } | ||
398 | else | ||
399 | { | ||
400 | // FIXME: pretranslate at load time? | ||
401 | pusdest = (unsigned short *)vid.buffer + y * (vid.rowbytes >> 1) + x; | ||
402 | |||
403 | for (v=0 ; v<pic->height ; v++) | ||
404 | { | ||
405 | for (u=0 ; u<pic->width ; u++) | ||
406 | { | ||
407 | tbyte = source[u]; | ||
408 | |||
409 | if (tbyte != TRANSPARENT_COLOR) | ||
410 | { | ||
411 | pusdest[u] = d_8to16table[tbyte]; | ||
412 | } | ||
413 | } | ||
414 | |||
415 | pusdest += vid.rowbytes >> 1; | ||
416 | source += pic->width; | ||
417 | } | ||
418 | } | ||
419 | } | ||
420 | |||
421 | |||
422 | /* | ||
423 | ============= | ||
424 | Draw_TransPicTranslate | ||
425 | ============= | ||
426 | */ | ||
427 | void Draw_TransPicTranslate (int x, int y, qpic_t *pic, byte *translation) | ||
428 | { | ||
429 | byte *dest, *source, tbyte; | ||
430 | unsigned short *pusdest; | ||
431 | int v, u; | ||
432 | |||
433 | if (x < 0 || (unsigned)(x + pic->width) > vid.width || y < 0 || | ||
434 | (unsigned)(y + pic->height) > vid.height) | ||
435 | { | ||
436 | Sys_Error ("Draw_TransPic: bad coordinates"); | ||
437 | } | ||
438 | |||
439 | source = pic->data; | ||
440 | |||
441 | if (r_pixbytes == 1) | ||
442 | { | ||
443 | dest = vid.buffer + y * vid.rowbytes + x; | ||
444 | |||
445 | if (pic->width & 7) | ||
446 | { // general | ||
447 | for (v=0 ; v<pic->height ; v++) | ||
448 | { | ||
449 | for (u=0 ; u<pic->width ; u++) | ||
450 | if ( (tbyte=source[u]) != TRANSPARENT_COLOR) | ||
451 | dest[u] = translation[tbyte]; | ||
452 | |||
453 | dest += vid.rowbytes; | ||
454 | source += pic->width; | ||
455 | } | ||
456 | } | ||
457 | else | ||
458 | { // unwound | ||
459 | for (v=0 ; v<pic->height ; v++) | ||
460 | { | ||
461 | for (u=0 ; u<pic->width ; u+=8) | ||
462 | { | ||
463 | if ( (tbyte=source[u]) != TRANSPARENT_COLOR) | ||
464 | dest[u] = translation[tbyte]; | ||
465 | if ( (tbyte=source[u+1]) != TRANSPARENT_COLOR) | ||
466 | dest[u+1] = translation[tbyte]; | ||
467 | if ( (tbyte=source[u+2]) != TRANSPARENT_COLOR) | ||
468 | dest[u+2] = translation[tbyte]; | ||
469 | if ( (tbyte=source[u+3]) != TRANSPARENT_COLOR) | ||
470 | dest[u+3] = translation[tbyte]; | ||
471 | if ( (tbyte=source[u+4]) != TRANSPARENT_COLOR) | ||
472 | dest[u+4] = translation[tbyte]; | ||
473 | if ( (tbyte=source[u+5]) != TRANSPARENT_COLOR) | ||
474 | dest[u+5] = translation[tbyte]; | ||
475 | if ( (tbyte=source[u+6]) != TRANSPARENT_COLOR) | ||
476 | dest[u+6] = translation[tbyte]; | ||
477 | if ( (tbyte=source[u+7]) != TRANSPARENT_COLOR) | ||
478 | dest[u+7] = translation[tbyte]; | ||
479 | } | ||
480 | dest += vid.rowbytes; | ||
481 | source += pic->width; | ||
482 | } | ||
483 | } | ||
484 | } | ||
485 | else | ||
486 | { | ||
487 | // FIXME: pretranslate at load time? | ||
488 | pusdest = (unsigned short *)vid.buffer + y * (vid.rowbytes >> 1) + x; | ||
489 | |||
490 | for (v=0 ; v<pic->height ; v++) | ||
491 | { | ||
492 | for (u=0 ; u<pic->width ; u++) | ||
493 | { | ||
494 | tbyte = source[u]; | ||
495 | |||
496 | if (tbyte != TRANSPARENT_COLOR) | ||
497 | { | ||
498 | pusdest[u] = d_8to16table[tbyte]; | ||
499 | } | ||
500 | } | ||
501 | |||
502 | pusdest += vid.rowbytes >> 1; | ||
503 | source += pic->width; | ||
504 | } | ||
505 | } | ||
506 | } | ||
507 | |||
508 | |||
509 | void Draw_CharToConback (int num, byte *dest) | ||
510 | { | ||
511 | int row, col; | ||
512 | byte *source; | ||
513 | int drawline; | ||
514 | int x; | ||
515 | |||
516 | row = num>>4; | ||
517 | col = num&15; | ||
518 | source = draw_chars + (row<<10) + (col<<3); | ||
519 | |||
520 | drawline = 8; | ||
521 | |||
522 | while (drawline--) | ||
523 | { | ||
524 | for (x=0 ; x<8 ; x++) | ||
525 | if (source[x]) | ||
526 | dest[x] = 0x60 + source[x]; | ||
527 | source += 128; | ||
528 | dest += 320; | ||
529 | } | ||
530 | |||
531 | } | ||
532 | |||
533 | /* | ||
534 | ================ | ||
535 | Draw_ConsoleBackground | ||
536 | |||
537 | ================ | ||
538 | */ | ||
539 | void Draw_ConsoleBackground (int lines) | ||
540 | { | ||
541 | int x, y, v; | ||
542 | byte *src, *dest; | ||
543 | unsigned short *pusdest; | ||
544 | int f, fstep; | ||
545 | qpic_t *conback; | ||
546 | char ver[100]; | ||
547 | |||
548 | conback = Draw_CachePic ("gfx/conback.lmp"); | ||
549 | |||
550 | dest = conback->data + 320 - 43 + 320*186; | ||
551 | sprintf (ver, "%.2f", (float)VERSION); | ||
552 | |||
553 | for (x=0 ; x<strlen(ver) ; x++) | ||
554 | Draw_CharToConback (ver[x], dest+(x<<3)); | ||
555 | |||
556 | // draw the pic | ||
557 | if (r_pixbytes == 1) | ||
558 | { | ||
559 | dest = vid.conbuffer; | ||
560 | |||
561 | for (y=0 ; y<lines ; y++, dest += vid.conrowbytes) | ||
562 | { | ||
563 | v = (vid.conheight - lines + y)*200/vid.conheight; | ||
564 | src = conback->data + v*320; | ||
565 | if (vid.conwidth == 320) | ||
566 | memcpy (dest, src, vid.conwidth); | ||
567 | else | ||
568 | { | ||
569 | f = 0; | ||
570 | fstep = 320*0x10000/vid.conwidth; | ||
571 | for (x=0 ; x<vid.conwidth ; x+=4) | ||
572 | { | ||
573 | dest[x] = src[f>>16]; | ||
574 | f += fstep; | ||
575 | dest[x+1] = src[f>>16]; | ||
576 | f += fstep; | ||
577 | dest[x+2] = src[f>>16]; | ||
578 | f += fstep; | ||
579 | dest[x+3] = src[f>>16]; | ||
580 | f += fstep; | ||
581 | } | ||
582 | } | ||
583 | } | ||
584 | } | ||
585 | else | ||
586 | { | ||
587 | pusdest = (unsigned short *)vid.conbuffer; | ||
588 | |||
589 | for (y=0 ; y<lines ; y++, pusdest += (vid.conrowbytes >> 1)) | ||
590 | { | ||
591 | // FIXME: pre-expand to native format? | ||
592 | // FIXME: does the endian switching go away in production? | ||
593 | v = (vid.conheight - lines + y)*200/vid.conheight; | ||
594 | src = conback->data + v*320; | ||
595 | f = 0; | ||
596 | fstep = 320*0x10000/vid.conwidth; | ||
597 | for (x=0 ; x<vid.conwidth ; x+=4) | ||
598 | { | ||
599 | pusdest[x] = d_8to16table[src[f>>16]]; | ||
600 | f += fstep; | ||
601 | pusdest[x+1] = d_8to16table[src[f>>16]]; | ||
602 | f += fstep; | ||
603 | pusdest[x+2] = d_8to16table[src[f>>16]]; | ||
604 | f += fstep; | ||
605 | pusdest[x+3] = d_8to16table[src[f>>16]]; | ||
606 | f += fstep; | ||
607 | } | ||
608 | } | ||
609 | } | ||
610 | } | ||
611 | |||
612 | |||
613 | /* | ||
614 | ============== | ||
615 | R_DrawRect8 | ||
616 | ============== | ||
617 | */ | ||
618 | void R_DrawRect8 (vrect_t *prect, int rowbytes, byte *psrc, | ||
619 | int transparent) | ||
620 | { | ||
621 | byte t; | ||
622 | int i, j, srcdelta, destdelta; | ||
623 | byte *pdest; | ||
624 | |||
625 | pdest = vid.buffer + (prect->y * vid.rowbytes) + prect->x; | ||
626 | |||
627 | srcdelta = rowbytes - prect->width; | ||
628 | destdelta = vid.rowbytes - prect->width; | ||
629 | |||
630 | if (transparent) | ||
631 | { | ||
632 | for (i=0 ; i<prect->height ; i++) | ||
633 | { | ||
634 | for (j=0 ; j<prect->width ; j++) | ||
635 | { | ||
636 | t = *psrc; | ||
637 | if (t != TRANSPARENT_COLOR) | ||
638 | { | ||
639 | *pdest = t; | ||
640 | } | ||
641 | |||
642 | psrc++; | ||
643 | pdest++; | ||
644 | } | ||
645 | |||
646 | psrc += srcdelta; | ||
647 | pdest += destdelta; | ||
648 | } | ||
649 | } | ||
650 | else | ||
651 | { | ||
652 | for (i=0 ; i<prect->height ; i++) | ||
653 | { | ||
654 | memcpy (pdest, psrc, prect->width); | ||
655 | psrc += rowbytes; | ||
656 | pdest += vid.rowbytes; | ||
657 | } | ||
658 | } | ||
659 | } | ||
660 | |||
661 | |||
662 | /* | ||
663 | ============== | ||
664 | R_DrawRect16 | ||
665 | ============== | ||
666 | */ | ||
667 | void R_DrawRect16 (vrect_t *prect, int rowbytes, byte *psrc, | ||
668 | int transparent) | ||
669 | { | ||
670 | byte t; | ||
671 | int i, j, srcdelta, destdelta; | ||
672 | unsigned short *pdest; | ||
673 | |||
674 | // FIXME: would it be better to pre-expand native-format versions? | ||
675 | |||
676 | pdest = (unsigned short *)vid.buffer + | ||
677 | (prect->y * (vid.rowbytes >> 1)) + prect->x; | ||
678 | |||
679 | srcdelta = rowbytes - prect->width; | ||
680 | destdelta = (vid.rowbytes >> 1) - prect->width; | ||
681 | |||
682 | if (transparent) | ||
683 | { | ||
684 | for (i=0 ; i<prect->height ; i++) | ||
685 | { | ||
686 | for (j=0 ; j<prect->width ; j++) | ||
687 | { | ||
688 | t = *psrc; | ||
689 | if (t != TRANSPARENT_COLOR) | ||
690 | { | ||
691 | *pdest = d_8to16table[t]; | ||
692 | } | ||
693 | |||
694 | psrc++; | ||
695 | pdest++; | ||
696 | } | ||
697 | |||
698 | psrc += srcdelta; | ||
699 | pdest += destdelta; | ||
700 | } | ||
701 | } | ||
702 | else | ||
703 | { | ||
704 | for (i=0 ; i<prect->height ; i++) | ||
705 | { | ||
706 | for (j=0 ; j<prect->width ; j++) | ||
707 | { | ||
708 | *pdest = d_8to16table[*psrc]; | ||
709 | psrc++; | ||
710 | pdest++; | ||
711 | } | ||
712 | |||
713 | psrc += srcdelta; | ||
714 | pdest += destdelta; | ||
715 | } | ||
716 | } | ||
717 | } | ||
718 | |||
719 | |||
720 | /* | ||
721 | ============= | ||
722 | Draw_TileClear | ||
723 | |||
724 | This repeats a 64*64 tile graphic to fill the screen around a sized down | ||
725 | refresh window. | ||
726 | ============= | ||
727 | */ | ||
728 | void Draw_TileClear (int x, int y, int w, int h) | ||
729 | { | ||
730 | int width, height, tileoffsetx, tileoffsety; | ||
731 | byte *psrc; | ||
732 | vrect_t vr; | ||
733 | |||
734 | r_rectdesc.rect.x = x; | ||
735 | r_rectdesc.rect.y = y; | ||
736 | r_rectdesc.rect.width = w; | ||
737 | r_rectdesc.rect.height = h; | ||
738 | |||
739 | vr.y = r_rectdesc.rect.y; | ||
740 | height = r_rectdesc.rect.height; | ||
741 | |||
742 | tileoffsety = vr.y % r_rectdesc.height; | ||
743 | |||
744 | while (height > 0) | ||
745 | { | ||
746 | vr.x = r_rectdesc.rect.x; | ||
747 | width = r_rectdesc.rect.width; | ||
748 | |||
749 | if (tileoffsety != 0) | ||
750 | vr.height = r_rectdesc.height - tileoffsety; | ||
751 | else | ||
752 | vr.height = r_rectdesc.height; | ||
753 | |||
754 | if (vr.height > height) | ||
755 | vr.height = height; | ||
756 | |||
757 | tileoffsetx = vr.x % r_rectdesc.width; | ||
758 | |||
759 | while (width > 0) | ||
760 | { | ||
761 | if (tileoffsetx != 0) | ||
762 | vr.width = r_rectdesc.width - tileoffsetx; | ||
763 | else | ||
764 | vr.width = r_rectdesc.width; | ||
765 | |||
766 | if (vr.width > width) | ||
767 | vr.width = width; | ||
768 | |||
769 | psrc = r_rectdesc.ptexbytes + | ||
770 | (tileoffsety * r_rectdesc.rowbytes) + tileoffsetx; | ||
771 | |||
772 | if (r_pixbytes == 1) | ||
773 | { | ||
774 | R_DrawRect8 (&vr, r_rectdesc.rowbytes, psrc, 0); | ||
775 | } | ||
776 | else | ||
777 | { | ||
778 | R_DrawRect16 (&vr, r_rectdesc.rowbytes, psrc, 0); | ||
779 | } | ||
780 | |||
781 | vr.x += vr.width; | ||
782 | width -= vr.width; | ||
783 | tileoffsetx = 0; // only the left tile can be left-clipped | ||
784 | } | ||
785 | |||
786 | vr.y += vr.height; | ||
787 | height -= vr.height; | ||
788 | tileoffsety = 0; // only the top tile can be top-clipped | ||
789 | } | ||
790 | } | ||
791 | |||
792 | |||
793 | /* | ||
794 | ============= | ||
795 | Draw_Fill | ||
796 | |||
797 | Fills a box of pixels with a single color | ||
798 | ============= | ||
799 | */ | ||
800 | void Draw_Fill (int x, int y, int w, int h, int c) | ||
801 | { | ||
802 | byte *dest; | ||
803 | unsigned short *pusdest; | ||
804 | unsigned uc; | ||
805 | int u, v; | ||
806 | |||
807 | if (r_pixbytes == 1) | ||
808 | { | ||
809 | dest = vid.buffer + y*vid.rowbytes + x; | ||
810 | for (v=0 ; v<h ; v++, dest += vid.rowbytes) | ||
811 | for (u=0 ; u<w ; u++) | ||
812 | dest[u] = c; | ||
813 | } | ||
814 | else | ||
815 | { | ||
816 | uc = d_8to16table[c]; | ||
817 | |||
818 | pusdest = (unsigned short *)vid.buffer + y * (vid.rowbytes >> 1) + x; | ||
819 | for (v=0 ; v<h ; v++, pusdest += (vid.rowbytes >> 1)) | ||
820 | for (u=0 ; u<w ; u++) | ||
821 | pusdest[u] = uc; | ||
822 | } | ||
823 | } | ||
824 | //============================================================================= | ||
825 | |||
826 | /* | ||
827 | ================ | ||
828 | Draw_FadeScreen | ||
829 | |||
830 | ================ | ||
831 | */ | ||
832 | void Draw_FadeScreen (void) | ||
833 | { | ||
834 | int x,y; | ||
835 | byte *pbuf; | ||
836 | |||
837 | VID_UnlockBuffer (); | ||
838 | S_ExtraUpdate (); | ||
839 | VID_LockBuffer (); | ||
840 | |||
841 | for (y=0 ; y<vid.height ; y++) | ||
842 | { | ||
843 | int t; | ||
844 | |||
845 | pbuf = (byte *)(vid.buffer + vid.rowbytes*y); | ||
846 | t = (y & 1) << 1; | ||
847 | |||
848 | for (x=0 ; x<vid.width ; x++) | ||
849 | { | ||
850 | if ((x & 3) != t) | ||
851 | pbuf[x] = 0; | ||
852 | } | ||
853 | } | ||
854 | |||
855 | VID_UnlockBuffer (); | ||
856 | S_ExtraUpdate (); | ||
857 | VID_LockBuffer (); | ||
858 | } | ||
859 | |||
860 | //============================================================================= | ||
861 | |||
862 | /* | ||
863 | ================ | ||
864 | Draw_BeginDisc | ||
865 | |||
866 | Draws the little blue disc in the corner of the screen. | ||
867 | Call before beginning any disc IO. | ||
868 | ================ | ||
869 | */ | ||
870 | void Draw_BeginDisc (void) | ||
871 | { | ||
872 | |||
873 | D_BeginDirectRect (vid.width - 24, 0, draw_disc->data, 24, 24); | ||
874 | } | ||
875 | |||
876 | |||
877 | /* | ||
878 | ================ | ||
879 | Draw_EndDisc | ||
880 | |||
881 | Erases the disc icon. | ||
882 | Call after completing any disc IO | ||
883 | ================ | ||
884 | */ | ||
885 | void Draw_EndDisc (void) | ||
886 | { | ||
887 | |||
888 | D_EndDirectRect (vid.width - 24, 0, 24, 24); | ||
889 | } | ||
890 | |||