1
2 //**************************************************************************
3 //**
4 //** r_draw.c : Heretic 2 : Raven Software, Corp.
5 //**
6 //** $RCSfile: r_draw.c,v $
7 //** $Revision: 1.11 $
8 //** $Date: 96/01/06 18:37:37 $
9 //** $Author: bgokey $
10 //**
11 //**************************************************************************
12
13 #include "h2def.h"
14 #include "r_local.h"
15
16 /*
17
18 All drawing to the view buffer is accomplished in this file. The other refresh
19 files only know about ccordinates, not the architecture of the frame buffer.
20
21 */
22
23 byte *viewimage;
24 int viewwidth, scaledviewwidth, viewheight, viewwindowx, viewwindowy;
25 byte *ylookup[MAXHEIGHT];
26 int columnofs[MAXWIDTH];
27 //byte translations[3][256]; // color tables for different players
28 byte *tinttable; // used for translucent sprites
29
30 /*
31 ==================
32 =
33 = R_DrawColumn
34 =
35 = Source is the top of the column to scale
36 =
37 ==================
38 */
39
40 lighttable_t *dc_colormap;
41 int dc_x;
42 int dc_yl;
43 int dc_yh;
44 fixed_t dc_iscale;
45 fixed_t dc_texturemid;
46 byte *dc_source; // first pixel in a column (possibly virtual)
47
48 int dccount; // just for profiling
49
50 #ifndef __WATCOMC__
51 //#ifndef __i386
52 #ifndef __m68k
R_DrawColumn(void)53 void R_DrawColumn (void)
54 {
55 int count;
56 byte *dest;
57 fixed_t frac, fracstep;
58
59 count = dc_yh - dc_yl;
60 if (count < 0)
61 return;
62
63 #ifdef RANGECHECK
64 if ((unsigned)dc_x >= SCREENWIDTH || dc_yl < 0 || dc_yh >= SCREENHEIGHT)
65 I_Error ("R_DrawColumn: %i to %i at %i", dc_yl, dc_yh, dc_x);
66 #endif
67
68 dest = ylookup[dc_yl] + columnofs[dc_x];
69
70 fracstep = dc_iscale;
71 frac = dc_texturemid + (dc_yl-centery)*fracstep;
72
73 do
74 {
75 *dest = dc_colormap[dc_source[(frac>>FRACBITS)&127]];
76 dest += SCREENWIDTH;
77 frac += fracstep;
78 } while (count--);
79 }
80 #endif // __m68k
81 //#endif // __i386
82 #endif
83
R_DrawColumnLow(void)84 void R_DrawColumnLow (void)
85 {
86 int count;
87 byte *dest;
88 fixed_t frac, fracstep;
89
90 count = dc_yh - dc_yl;
91 if (count < 0)
92 return;
93
94 #ifdef RANGECHECK
95 if ((unsigned)dc_x >= SCREENWIDTH || dc_yl < 0 || dc_yh >= SCREENHEIGHT)
96 I_Error ("R_DrawColumn: %i to %i at %i", dc_yl, dc_yh, dc_x);
97 // dccount++;
98 #endif
99
100 dest = ylookup[dc_yl] + columnofs[dc_x];
101
102 fracstep = dc_iscale;
103 frac = dc_texturemid + (dc_yl-centery)*fracstep;
104
105 do
106 {
107 *dest = dc_colormap[dc_source[(frac>>FRACBITS)&127]];
108 dest += SCREENWIDTH;
109 frac += fracstep;
110 } while (count--);
111 }
112
113 /*
114 #define FUZZTABLE 50
115 #define FUZZOFF (SCREENWIDTH)
116 int fuzzoffset[FUZZTABLE] = {
117 FUZZOFF,-FUZZOFF,FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,-FUZZOFF,-FUZZOFF,-FUZZOFF,FUZZOFF,-FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,-FUZZOFF,-FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,FUZZOFF
118 };
119 int fuzzpos = 0;
120 */
121
122 #ifndef __WATCOMC__
R_DrawFuzzColumn(void)123 void R_DrawFuzzColumn (void)
124 {
125 int count;
126 byte *dest;
127 fixed_t frac, fracstep;
128
129 if (!dc_yl)
130 dc_yl = 1;
131 if (dc_yh == viewheight-1)
132 dc_yh = viewheight - 2;
133
134 count = dc_yh - dc_yl;
135 if (count < 0)
136 return;
137
138 #ifdef RANGECHECK
139 if ((unsigned)dc_x >= SCREENWIDTH || dc_yl < 0 || dc_yh >= SCREENHEIGHT)
140 I_Error ("R_DrawFuzzColumn: %i to %i at %i", dc_yl, dc_yh, dc_x);
141 #endif
142
143 dest = ylookup[dc_yl] + columnofs[dc_x];
144
145 fracstep = dc_iscale;
146 frac = dc_texturemid + (dc_yl-centery)*fracstep;
147
148 // OLD FUZZY INVISO SPRITE STUFF
149 /* do
150 {
151 *dest = colormaps[6*256+dest[fuzzoffset[fuzzpos]]];
152 if (++fuzzpos == FUZZTABLE)
153 fuzzpos = 0;
154 dest += SCREENWIDTH;
155 frac += fracstep;
156 } while (count--);
157 */
158
159 do
160 {
161 *dest = tinttable[*dest+
162 (dc_colormap[dc_source[(frac>>FRACBITS)&127]]<<8)];
163 dest += SCREENWIDTH;
164 frac += fracstep;
165 } while(count--);
166 }
167 #endif
168
169 //============================================================================
170 //
171 // R_DrawAltFuzzColumn
172 //
173 //============================================================================
174
R_DrawAltFuzzColumn(void)175 void R_DrawAltFuzzColumn (void)
176 {
177 int count;
178 byte *dest;
179 fixed_t frac, fracstep;
180
181 if (!dc_yl)
182 dc_yl = 1;
183 if (dc_yh == viewheight-1)
184 dc_yh = viewheight - 2;
185
186 count = dc_yh - dc_yl;
187 if (count < 0)
188 return;
189
190 #ifdef RANGECHECK
191 if ((unsigned)dc_x >= SCREENWIDTH || dc_yl < 0 || dc_yh >= SCREENHEIGHT)
192 I_Error ("R_DrawFuzzColumn: %i to %i at %i", dc_yl, dc_yh, dc_x);
193 #endif
194
195 dest = ylookup[dc_yl] + columnofs[dc_x];
196
197 fracstep = dc_iscale;
198 frac = dc_texturemid + (dc_yl-centery)*fracstep;
199
200 do
201 {
202 *dest = tinttable[((*dest)<<8)
203 +dc_colormap[dc_source[(frac>>FRACBITS)&127]]];
204 dest += SCREENWIDTH;
205 frac += fracstep;
206 } while(count--);
207 }
208
209 /*
210 ========================
211 =
212 = R_DrawTranslatedColumn
213 =
214 ========================
215 */
216
217 byte *dc_translation;
218 byte *translationtables;
219
R_DrawTranslatedColumn(void)220 void R_DrawTranslatedColumn (void)
221 {
222 int count;
223 byte *dest;
224 fixed_t frac, fracstep;
225
226 count = dc_yh - dc_yl;
227 if (count < 0)
228 return;
229
230 #ifdef RANGECHECK
231 if ((unsigned)dc_x >= SCREENWIDTH || dc_yl < 0 || dc_yh >= SCREENHEIGHT)
232 I_Error ("R_DrawColumn: %i to %i at %i", dc_yl, dc_yh, dc_x);
233 #endif
234
235 dest = ylookup[dc_yl] + columnofs[dc_x];
236
237 fracstep = dc_iscale;
238 frac = dc_texturemid + (dc_yl-centery)*fracstep;
239
240 do
241 {
242 *dest = dc_colormap[dc_translation[dc_source[frac>>FRACBITS]]];
243 dest += SCREENWIDTH;
244 frac += fracstep;
245 } while (count--);
246 }
247
248 //============================================================================
249 //
250 // R_DrawTranslatedFuzzColumn
251 //
252 //============================================================================
253
R_DrawTranslatedFuzzColumn(void)254 void R_DrawTranslatedFuzzColumn (void)
255 {
256 int count;
257 byte *dest;
258 fixed_t frac, fracstep;
259
260 count = dc_yh - dc_yl;
261 if (count < 0)
262 return;
263
264 #ifdef RANGECHECK
265 if ((unsigned)dc_x >= SCREENWIDTH || dc_yl < 0 || dc_yh >= SCREENHEIGHT)
266 I_Error ("R_DrawColumn: %i to %i at %i", dc_yl, dc_yh, dc_x);
267 #endif
268
269 dest = ylookup[dc_yl] + columnofs[dc_x];
270
271 fracstep = dc_iscale;
272 frac = dc_texturemid + (dc_yl-centery)*fracstep;
273
274 do
275 {
276 *dest = tinttable[((*dest)<<8)
277 +dc_colormap[dc_translation[dc_source[frac>>FRACBITS]]]];
278 dest += SCREENWIDTH;
279 frac += fracstep;
280 } while (count--);
281 }
282
283 //============================================================================
284 //
285 // R_DrawTranslatedAltFuzzColumn
286 //
287 //============================================================================
288
289 /*
290 void R_DrawTranslatedAltFuzzColumn (void)
291 {
292 int count;
293 byte *dest;
294 fixed_t frac, fracstep;
295
296 count = dc_yh - dc_yl;
297 if (count < 0)
298 return;
299
300 #ifdef RANGECHECK
301 if ((unsigned)dc_x >= SCREENWIDTH || dc_yl < 0 || dc_yh >= SCREENHEIGHT)
302 I_Error ("R_DrawColumn: %i to %i at %i", dc_yl, dc_yh, dc_x);
303 #endif
304
305 dest = ylookup[dc_yl] + columnofs[dc_x];
306
307 fracstep = dc_iscale;
308 frac = dc_texturemid + (dc_yl-centery)*fracstep;
309
310 do
311 {
312 *dest = tinttable[*dest
313 +(dc_colormap[dc_translation[dc_source[frac>>FRACBITS]]]<<8)];
314 dest += SCREENWIDTH;
315 frac += fracstep;
316 } while (count--);
317 }
318 */
319
320 //--------------------------------------------------------------------------
321 //
322 // PROC R_InitTranslationTables
323 //
324 //--------------------------------------------------------------------------
325
R_InitTranslationTables(void)326 void R_InitTranslationTables (void)
327 {
328 int i;
329 byte *transLump;
330
331 // Load tint table
332 tinttable = W_CacheLumpName("TINTTAB", PU_STATIC);
333
334 // Allocate translation tables
335 translationtables = Z_Malloc(256*3*(MAXPLAYERS-1)+255,
336 PU_STATIC, 0);
337 translationtables = (byte *)(((int)translationtables+255)&~255);
338
339 for(i = 0; i < 3*(MAXPLAYERS-1); i++)
340 {
341 transLump = W_CacheLumpNum(W_GetNumForName("trantbl0")+i, PU_STATIC);
342 memcpy(translationtables+i*256, transLump, 256);
343 Z_Free(transLump);
344 }
345 }
346
347 /*
348 ================
349 =
350 = R_DrawSpan
351 =
352 ================
353 */
354
355 int ds_y;
356 int ds_x1;
357 int ds_x2;
358 lighttable_t *ds_colormap;
359 fixed_t ds_xfrac;
360 fixed_t ds_yfrac;
361 fixed_t ds_xstep;
362 fixed_t ds_ystep;
363 byte *ds_source; // start of a 64*64 tile image
364
365 int dscount; // just for profiling
366
367 #ifndef __WATCOMC__
368 //#ifndef __i386
369 #ifndef __m68k
R_DrawSpan(void)370 void R_DrawSpan (void)
371 {
372 fixed_t xfrac, yfrac;
373 byte *dest;
374 int count, spot;
375
376 #ifdef RANGECHECK
377 if (ds_x2 < ds_x1 || ds_x1<0 || ds_x2>=SCREENWIDTH
378 || (unsigned)ds_y>SCREENHEIGHT)
379 I_Error ("R_DrawSpan: %i to %i at %i",ds_x1,ds_x2,ds_y);
380 // dscount++;
381 #endif
382
383 xfrac = ds_xfrac;
384 yfrac = ds_yfrac;
385
386 dest = ylookup[ds_y] + columnofs[ds_x1];
387 count = ds_x2 - ds_x1;
388 do
389 {
390 spot = ((yfrac>>(16-6))&(63*64)) + ((xfrac>>16)&63);
391 *dest++ = ds_colormap[ds_source[spot]];
392 xfrac += ds_xstep;
393 yfrac += ds_ystep;
394 } while (count--);
395 }
396 #endif
397 //#endif
398 #endif
399
R_DrawSpanLow(void)400 void R_DrawSpanLow (void)
401 {
402 fixed_t xfrac, yfrac;
403 byte *dest;
404 int count, spot;
405
406 #ifdef RANGECHECK
407 if (ds_x2 < ds_x1 || ds_x1<0 || ds_x2>=SCREENWIDTH
408 || (unsigned)ds_y>SCREENHEIGHT)
409 I_Error ("R_DrawSpan: %i to %i at %i",ds_x1,ds_x2,ds_y);
410 // dscount++;
411 #endif
412
413 xfrac = ds_xfrac;
414 yfrac = ds_yfrac;
415
416 dest = ylookup[ds_y] + columnofs[ds_x1];
417 count = ds_x2 - ds_x1;
418 do
419 {
420 spot = ((yfrac>>(16-6))&(63*64)) + ((xfrac>>16)&63);
421 *dest++ = ds_colormap[ds_source[spot]];
422 xfrac += ds_xstep;
423 yfrac += ds_ystep;
424 } while (count--);
425 }
426
427
428
429 /*
430 ================
431 =
432 = R_InitBuffer
433 =
434 =================
435 */
436
R_InitBuffer(int width,int height)437 void R_InitBuffer (int width, int height)
438 {
439 int i;
440
441 viewwindowx = (SCREENWIDTH-width) >> 1;
442 for (i=0 ; i<width ; i++)
443 columnofs[i] = viewwindowx + i;
444 if (width == SCREENWIDTH)
445 viewwindowy = 0;
446 else
447 viewwindowy = (SCREENHEIGHT-SBARHEIGHT-height) >> 1;
448 for (i=0 ; i<height ; i++)
449 ylookup[i] = screen + (i+viewwindowy)*SCREENWIDTH;
450 }
451
452
453 /*
454 ==================
455 =
456 = R_DrawViewBorder
457 =
458 = Draws the border around the view for different size windows
459 ==================
460 */
461
462 boolean BorderNeedRefresh;
463
R_DrawViewBorder(void)464 void R_DrawViewBorder (void)
465 {
466 byte *src, *dest;
467 int x,y;
468
469 if (scaledviewwidth == SCREENWIDTH)
470 return;
471
472 src = W_CacheLumpName("F_022", PU_CACHE);
473 dest = screen;
474
475 for (y=0 ; y<SCREENHEIGHT-SBARHEIGHT ; y++)
476 {
477 for (x=0 ; x<SCREENWIDTH/64 ; x++)
478 {
479 memcpy (dest, src+((y&63)<<6), 64);
480 dest += 64;
481 }
482 if (SCREENWIDTH&63)
483 {
484 memcpy (dest, src+((y&63)<<6), SCREENWIDTH&63);
485 dest += (SCREENWIDTH&63);
486 }
487 }
488 for(x=viewwindowx; x < viewwindowx+viewwidth; x += 16)
489 {
490 V_DrawPatch(x, viewwindowy-4, W_CacheLumpName("bordt", PU_CACHE));
491 V_DrawPatch(x, viewwindowy+viewheight, W_CacheLumpName("bordb",
492 PU_CACHE));
493 }
494 for(y=viewwindowy; y < viewwindowy+viewheight; y += 16)
495 {
496 V_DrawPatch(viewwindowx-4, y, W_CacheLumpName("bordl", PU_CACHE));
497 V_DrawPatch(viewwindowx+viewwidth, y, W_CacheLumpName("bordr",
498 PU_CACHE));
499 }
500 V_DrawPatch(viewwindowx-4, viewwindowy-4, W_CacheLumpName("bordtl",
501 PU_CACHE));
502 V_DrawPatch(viewwindowx+viewwidth, viewwindowy-4,
503 W_CacheLumpName("bordtr", PU_CACHE));
504 V_DrawPatch(viewwindowx+viewwidth, viewwindowy+viewheight,
505 W_CacheLumpName("bordbr", PU_CACHE));
506 V_DrawPatch(viewwindowx-4, viewwindowy+viewheight,
507 W_CacheLumpName("bordbl", PU_CACHE));
508 }
509
510 /*
511 ==================
512 =
513 = R_DrawTopBorder
514 =
515 = Draws the top border around the view for different size windows
516 ==================
517 */
518
519 boolean BorderTopRefresh;
520
R_DrawTopBorder(void)521 void R_DrawTopBorder (void)
522 {
523 byte *src, *dest;
524 int x,y;
525
526 if (scaledviewwidth == SCREENWIDTH)
527 return;
528
529 /* if(shareware)
530 {
531 src = W_CacheLumpName ("FLOOR04", PU_CACHE);
532 }
533 else
534 {
535 src = W_CacheLumpName ("FLAT513", PU_CACHE);
536 }
537 */
538 src = W_CacheLumpName("F_022", PU_CACHE);
539 dest = screen;
540
541 for (y=0 ; y<34 ; y++)
542 {
543 for (x=0 ; x<SCREENWIDTH/64 ; x++)
544 {
545 memcpy (dest, src+((y&63)<<6), 64);
546 dest += 64;
547 }
548 if (SCREENWIDTH&63)
549 {
550 memcpy (dest, src+((y&63)<<6), SCREENWIDTH&63);
551 dest += (SCREENWIDTH&63);
552 }
553 }
554 if(viewwindowy < 35)
555 {
556 for(x=viewwindowx; x < viewwindowx+viewwidth; x += 16)
557 {
558 V_DrawPatch(x, viewwindowy-4, W_CacheLumpName("bordt", PU_CACHE));
559 }
560 V_DrawPatch(viewwindowx-4, viewwindowy, W_CacheLumpName("bordl",
561 PU_CACHE));
562 V_DrawPatch(viewwindowx+viewwidth, viewwindowy,
563 W_CacheLumpName("bordr", PU_CACHE));
564 V_DrawPatch(viewwindowx-4, viewwindowy+16, W_CacheLumpName("bordl",
565 PU_CACHE));
566 V_DrawPatch(viewwindowx+viewwidth, viewwindowy+16,
567 W_CacheLumpName("bordr", PU_CACHE));
568
569 V_DrawPatch(viewwindowx-4, viewwindowy-4, W_CacheLumpName("bordtl",
570 PU_CACHE));
571 V_DrawPatch(viewwindowx+viewwidth, viewwindowy-4,
572 W_CacheLumpName("bordtr", PU_CACHE));
573 }
574 }
575
576
577