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