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