Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
5131 | clevermous | 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 |
||
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 |
||
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 |
||
322 | { |
||
323 | for (u=0 ; 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 |
||
361 | { |
||
362 | for (u=0 ; 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 |
||
373 | { |
||
374 | for (u=0 ; u |
||
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 |
||
404 | { |
||
405 | for (u=0 ; 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 |
||
448 | { |
||
449 | for (u=0 ; 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 |
||
460 | { |
||
461 | for (u=0 ; u |
||
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 |
||
491 | { |
||
492 | for (u=0 ; 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 | // hack the version number directly into the pic |
||
551 | #ifdef _WIN32 |
||
552 | sprintf (ver, "(WinQuake) %4.2f", (float)VERSION); |
||
553 | dest = conback->data + 320*186 + 320 - 11 - 8*strlen(ver); |
||
554 | #elif defined(X11) |
||
555 | sprintf (ver, "(X11 Quake %2.2f) %4.2f", (float)X11_VERSION, (float)VERSION); |
||
556 | dest = conback->data + 320*186 + 320 - 11 - 8*strlen(ver); |
||
557 | #elif defined(__linux__) |
||
558 | sprintf (ver, "(Linux Quake %2.2f) %4.2f", (float)LINUX_VERSION, (float)VERSION); |
||
559 | dest = conback->data + 320*186 + 320 - 11 - 8*strlen(ver); |
||
560 | #else |
||
561 | dest = conback->data + 320 - 43 + 320*186; |
||
562 | sprintf (ver, "%4.2f", VERSION); |
||
563 | #endif |
||
564 | |||
565 | for (x=0 ; x |
||
566 | Draw_CharToConback (ver[x], dest+(x<<3)); |
||
567 | |||
568 | // draw the pic |
||
569 | if (r_pixbytes == 1) |
||
570 | { |
||
571 | dest = vid.conbuffer; |
||
572 | |||
573 | for (y=0 ; y |
||
574 | { |
||
575 | v = (vid.conheight - lines + y)*200/vid.conheight; |
||
576 | src = conback->data + v*320; |
||
577 | if (vid.conwidth == 320) |
||
578 | memcpy (dest, src, vid.conwidth); |
||
579 | else |
||
580 | { |
||
581 | f = 0; |
||
582 | fstep = 320*0x10000/vid.conwidth; |
||
583 | for (x=0 ; x |
||
584 | { |
||
585 | dest[x] = src[f>>16]; |
||
586 | f += fstep; |
||
587 | dest[x+1] = src[f>>16]; |
||
588 | f += fstep; |
||
589 | dest[x+2] = src[f>>16]; |
||
590 | f += fstep; |
||
591 | dest[x+3] = src[f>>16]; |
||
592 | f += fstep; |
||
593 | } |
||
594 | } |
||
595 | } |
||
596 | } |
||
597 | else |
||
598 | { |
||
599 | pusdest = (unsigned short *)vid.conbuffer; |
||
600 | |||
601 | for (y=0 ; y |
||
602 | { |
||
603 | // FIXME: pre-expand to native format? |
||
604 | // FIXME: does the endian switching go away in production? |
||
605 | v = (vid.conheight - lines + y)*200/vid.conheight; |
||
606 | src = conback->data + v*320; |
||
607 | f = 0; |
||
608 | fstep = 320*0x10000/vid.conwidth; |
||
609 | for (x=0 ; x |
||
610 | { |
||
611 | pusdest[x] = d_8to16table[src[f>>16]]; |
||
612 | f += fstep; |
||
613 | pusdest[x+1] = d_8to16table[src[f>>16]]; |
||
614 | f += fstep; |
||
615 | pusdest[x+2] = d_8to16table[src[f>>16]]; |
||
616 | f += fstep; |
||
617 | pusdest[x+3] = d_8to16table[src[f>>16]]; |
||
618 | f += fstep; |
||
619 | } |
||
620 | } |
||
621 | } |
||
622 | } |
||
623 | |||
624 | |||
625 | /* |
||
626 | ============== |
||
627 | R_DrawRect8 |
||
628 | ============== |
||
629 | */ |
||
630 | void R_DrawRect8 (vrect_t *prect, int rowbytes, byte *psrc, |
||
631 | int transparent) |
||
632 | { |
||
633 | byte t; |
||
634 | int i, j, srcdelta, destdelta; |
||
635 | byte *pdest; |
||
636 | |||
637 | pdest = vid.buffer + (prect->y * vid.rowbytes) + prect->x; |
||
638 | |||
639 | srcdelta = rowbytes - prect->width; |
||
640 | destdelta = vid.rowbytes - prect->width; |
||
641 | |||
642 | if (transparent) |
||
643 | { |
||
644 | for (i=0 ; i |
||
645 | { |
||
646 | for (j=0 ; j |
||
647 | { |
||
648 | t = *psrc; |
||
649 | if (t != TRANSPARENT_COLOR) |
||
650 | { |
||
651 | *pdest = t; |
||
652 | } |
||
653 | |||
654 | psrc++; |
||
655 | pdest++; |
||
656 | } |
||
657 | |||
658 | psrc += srcdelta; |
||
659 | pdest += destdelta; |
||
660 | } |
||
661 | } |
||
662 | else |
||
663 | { |
||
664 | for (i=0 ; i |
||
665 | { |
||
666 | memcpy (pdest, psrc, prect->width); |
||
667 | psrc += rowbytes; |
||
668 | pdest += vid.rowbytes; |
||
669 | } |
||
670 | } |
||
671 | } |
||
672 | |||
673 | |||
674 | /* |
||
675 | ============== |
||
676 | R_DrawRect16 |
||
677 | ============== |
||
678 | */ |
||
679 | void R_DrawRect16 (vrect_t *prect, int rowbytes, byte *psrc, |
||
680 | int transparent) |
||
681 | { |
||
682 | byte t; |
||
683 | int i, j, srcdelta, destdelta; |
||
684 | unsigned short *pdest; |
||
685 | |||
686 | // FIXME: would it be better to pre-expand native-format versions? |
||
687 | |||
688 | pdest = (unsigned short *)vid.buffer + |
||
689 | (prect->y * (vid.rowbytes >> 1)) + prect->x; |
||
690 | |||
691 | srcdelta = rowbytes - prect->width; |
||
692 | destdelta = (vid.rowbytes >> 1) - prect->width; |
||
693 | |||
694 | if (transparent) |
||
695 | { |
||
696 | for (i=0 ; i |
||
697 | { |
||
698 | for (j=0 ; j |
||
699 | { |
||
700 | t = *psrc; |
||
701 | if (t != TRANSPARENT_COLOR) |
||
702 | { |
||
703 | *pdest = d_8to16table[t]; |
||
704 | } |
||
705 | |||
706 | psrc++; |
||
707 | pdest++; |
||
708 | } |
||
709 | |||
710 | psrc += srcdelta; |
||
711 | pdest += destdelta; |
||
712 | } |
||
713 | } |
||
714 | else |
||
715 | { |
||
716 | for (i=0 ; i |
||
717 | { |
||
718 | for (j=0 ; j |
||
719 | { |
||
720 | *pdest = d_8to16table[*psrc]; |
||
721 | psrc++; |
||
722 | pdest++; |
||
723 | } |
||
724 | |||
725 | psrc += srcdelta; |
||
726 | pdest += destdelta; |
||
727 | } |
||
728 | } |
||
729 | } |
||
730 | |||
731 | |||
732 | /* |
||
733 | ============= |
||
734 | Draw_TileClear |
||
735 | |||
736 | This repeats a 64*64 tile graphic to fill the screen around a sized down |
||
737 | refresh window. |
||
738 | ============= |
||
739 | */ |
||
740 | void Draw_TileClear (int x, int y, int w, int h) |
||
741 | { |
||
742 | int width, height, tileoffsetx, tileoffsety; |
||
743 | byte *psrc; |
||
744 | vrect_t vr; |
||
745 | |||
746 | r_rectdesc.rect.x = x; |
||
747 | r_rectdesc.rect.y = y; |
||
748 | r_rectdesc.rect.width = w; |
||
749 | r_rectdesc.rect.height = h; |
||
750 | |||
751 | vr.y = r_rectdesc.rect.y; |
||
752 | height = r_rectdesc.rect.height; |
||
753 | |||
754 | tileoffsety = vr.y % r_rectdesc.height; |
||
755 | |||
756 | while (height > 0) |
||
757 | { |
||
758 | vr.x = r_rectdesc.rect.x; |
||
759 | width = r_rectdesc.rect.width; |
||
760 | |||
761 | if (tileoffsety != 0) |
||
762 | vr.height = r_rectdesc.height - tileoffsety; |
||
763 | else |
||
764 | vr.height = r_rectdesc.height; |
||
765 | |||
766 | if (vr.height > height) |
||
767 | vr.height = height; |
||
768 | |||
769 | tileoffsetx = vr.x % r_rectdesc.width; |
||
770 | |||
771 | while (width > 0) |
||
772 | { |
||
773 | if (tileoffsetx != 0) |
||
774 | vr.width = r_rectdesc.width - tileoffsetx; |
||
775 | else |
||
776 | vr.width = r_rectdesc.width; |
||
777 | |||
778 | if (vr.width > width) |
||
779 | vr.width = width; |
||
780 | |||
781 | psrc = r_rectdesc.ptexbytes + |
||
782 | (tileoffsety * r_rectdesc.rowbytes) + tileoffsetx; |
||
783 | |||
784 | if (r_pixbytes == 1) |
||
785 | { |
||
786 | R_DrawRect8 (&vr, r_rectdesc.rowbytes, psrc, 0); |
||
787 | } |
||
788 | else |
||
789 | { |
||
790 | R_DrawRect16 (&vr, r_rectdesc.rowbytes, psrc, 0); |
||
791 | } |
||
792 | |||
793 | vr.x += vr.width; |
||
794 | width -= vr.width; |
||
795 | tileoffsetx = 0; // only the left tile can be left-clipped |
||
796 | } |
||
797 | |||
798 | vr.y += vr.height; |
||
799 | height -= vr.height; |
||
800 | tileoffsety = 0; // only the top tile can be top-clipped |
||
801 | } |
||
802 | } |
||
803 | |||
804 | |||
805 | /* |
||
806 | ============= |
||
807 | Draw_Fill |
||
808 | |||
809 | Fills a box of pixels with a single color |
||
810 | ============= |
||
811 | */ |
||
812 | void Draw_Fill (int x, int y, int w, int h, int c) |
||
813 | { |
||
814 | byte *dest; |
||
815 | unsigned short *pusdest; |
||
816 | unsigned uc; |
||
817 | int u, v; |
||
818 | |||
819 | if (r_pixbytes == 1) |
||
820 | { |
||
821 | dest = vid.buffer + y*vid.rowbytes + x; |
||
822 | for (v=0 ; v |
||
823 | for (u=0 ; u |
||
824 | dest[u] = c; |
||
825 | } |
||
826 | else |
||
827 | { |
||
828 | uc = d_8to16table[c]; |
||
829 | |||
830 | pusdest = (unsigned short *)vid.buffer + y * (vid.rowbytes >> 1) + x; |
||
831 | for (v=0 ; v |
||
832 | for (u=0 ; u |
||
833 | pusdest[u] = uc; |
||
834 | } |
||
835 | } |
||
836 | //============================================================================= |
||
837 | |||
838 | /* |
||
839 | ================ |
||
840 | Draw_FadeScreen |
||
841 | |||
842 | ================ |
||
843 | */ |
||
844 | void Draw_FadeScreen (void) |
||
845 | { |
||
846 | int x,y; |
||
847 | byte *pbuf; |
||
848 | |||
849 | VID_UnlockBuffer (); |
||
850 | S_ExtraUpdate (); |
||
851 | VID_LockBuffer (); |
||
852 | |||
853 | for (y=0 ; y |
||
854 | { |
||
855 | int t; |
||
856 | |||
857 | pbuf = (byte *)(vid.buffer + vid.rowbytes*y); |
||
858 | t = (y & 1) << 1; |
||
859 | |||
860 | for (x=0 ; x |
||
861 | { |
||
862 | if ((x & 3) != t) |
||
863 | pbuf[x] = 0; |
||
864 | } |
||
865 | } |
||
866 | |||
867 | VID_UnlockBuffer (); |
||
868 | S_ExtraUpdate (); |
||
869 | VID_LockBuffer (); |
||
870 | } |
||
871 | |||
872 | //============================================================================= |
||
873 | |||
874 | /* |
||
875 | ================ |
||
876 | Draw_BeginDisc |
||
877 | |||
878 | Draws the little blue disc in the corner of the screen. |
||
879 | Call before beginning any disc IO. |
||
880 | ================ |
||
881 | */ |
||
882 | void Draw_BeginDisc (void) |
||
883 | { |
||
884 | |||
885 | D_BeginDirectRect (vid.width - 24, 0, draw_disc->data, 24, 24); |
||
886 | } |
||
887 | |||
888 | |||
889 | /* |
||
890 | ================ |
||
891 | Draw_EndDisc |
||
892 | |||
893 | Erases the disc icon. |
||
894 | Call after completing any disc IO |
||
895 | ================ |
||
896 | */ |
||
897 | void Draw_EndDisc (void) |
||
898 | { |
||
899 | |||
900 | D_EndDirectRect (vid.width - 24, 0, 24, 24); |
||
901 | }><>3)); |
||
902 |