]> icculus.org git repositories - theoddone33/hheretic.git/blob - base/r_draw.c
cd6656704fc33f1380e0ee172cba9e2cde9c2700
[theoddone33/hheretic.git] / base / r_draw.c
1 // R_draw.c
2
3 #include "doomdef.h"
4 #include "r_local.h"
5
6 #ifdef RENDER3D
7 #include "ogl_def.h"
8 #endif
9
10 /*
11
12 All drawing to the view buffer is accomplished in this file.  The other refresh
13 files only know about ccordinates, not the architecture of the frame buffer.
14
15 */
16
17 byte *viewimage;
18 int viewwidth, scaledviewwidth, viewheight, viewwindowx, viewwindowy;
19 byte *ylookup[MAXHEIGHT];
20 int columnofs[MAXWIDTH];
21 byte translations[3][256]; // color tables for different players
22 byte *tinttable; // used for translucent sprites
23
24 #ifndef RENDER3D
25
26 /*
27 ==================
28 =
29 = R_DrawColumn
30 =
31 = Source is the top of the column to scale
32 =
33 ==================
34 */
35
36 lighttable_t    *dc_colormap;
37 int                             dc_x;
38 int                             dc_yl;
39 int                             dc_yh;
40 fixed_t                 dc_iscale;
41 fixed_t                 dc_texturemid;
42 byte                    *dc_source;             // first pixel in a column (possibly virtual)
43
44 int                             dccount;                // just for profiling
45
46 void R_DrawColumn (void)
47 {
48         int                     count;
49         byte            *dest;
50         fixed_t         frac, fracstep; 
51
52         count = dc_yh - dc_yl;
53         if (count < 0)
54                 return;
55                                 
56 #ifdef RANGECHECK
57         if ((unsigned)dc_x >= SCREENWIDTH || dc_yl < 0 || dc_yh >= SCREENHEIGHT)
58                 I_Error ("R_DrawColumn: %i to %i at %i", dc_yl, dc_yh, dc_x);
59 #endif
60
61         dest = ylookup[dc_yl] + columnofs[dc_x]; 
62         
63         fracstep = dc_iscale;
64         frac = dc_texturemid + (dc_yl-centery)*fracstep;
65
66         do
67         {
68                 *dest = dc_colormap[dc_source[(frac>>FRACBITS)&127]];
69                 dest += SCREENWIDTH;
70                 frac += fracstep;
71         } while (count--);
72 }
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 void R_DrawSpan (void)
285 {
286         fixed_t         xfrac, yfrac;
287         byte            *dest;
288         int                     count, spot;
289         
290 #ifdef RANGECHECK
291         if (ds_x2 < ds_x1 || ds_x1<0 || ds_x2>=SCREENWIDTH 
292         || (unsigned)ds_y>SCREENHEIGHT)
293                 I_Error ("R_DrawSpan: %i to %i at %i",ds_x1,ds_x2,ds_y);
294 //      dscount++;
295 #endif
296         
297         xfrac = ds_xfrac;
298         yfrac = ds_yfrac;
299         
300         dest = ylookup[ds_y] + columnofs[ds_x1];        
301         count = ds_x2 - ds_x1;
302         do
303         {
304                 spot = ((yfrac>>(16-6))&(63*64)) + ((xfrac>>16)&63);
305                 *dest++ = ds_colormap[ds_source[spot]];
306                 xfrac += ds_xstep;
307                 yfrac += ds_ystep;
308         } while (count--);
309 }
310
311 void R_DrawSpanLow (void)
312 {
313         fixed_t         xfrac, yfrac;
314         byte            *dest;
315         int                     count, spot;
316         
317 #ifdef RANGECHECK
318         if (ds_x2 < ds_x1 || ds_x1<0 || ds_x2>=SCREENWIDTH 
319         || (unsigned)ds_y>SCREENHEIGHT)
320                 I_Error ("R_DrawSpan: %i to %i at %i",ds_x1,ds_x2,ds_y);
321 //      dscount++;
322 #endif
323         
324         xfrac = ds_xfrac;
325         yfrac = ds_yfrac;
326         
327         dest = ylookup[ds_y] + columnofs[ds_x1];        
328         count = ds_x2 - ds_x1;
329         do
330         {
331                 spot = ((yfrac>>(16-6))&(63*64)) + ((xfrac>>16)&63);
332                 *dest++ = ds_colormap[ds_source[spot]];
333                 xfrac += ds_xstep;
334                 yfrac += ds_ystep;
335         } while (count--);
336 }
337
338 #endif      // !RENDER3D
339
340 /*
341 ================
342 =
343 = R_InitBuffer
344 =
345 =================
346 */
347
348 void R_InitBuffer (int width, int height)
349 {
350         int             i;
351         
352         viewwindowx = (SCREENWIDTH-width) >> 1;
353         for (i=0 ; i<width ; i++)
354                 columnofs[i] = viewwindowx + i;
355         if (width == SCREENWIDTH)
356                 viewwindowy = 0;
357         else
358                 viewwindowy = (SCREENHEIGHT-SBARHEIGHT-height) >> 1;
359         for (i=0 ; i<height ; i++)
360                 ylookup[i] = screen + (i+viewwindowy)*SCREENWIDTH;
361 }
362
363
364 /*
365 ==================
366 =
367 = R_DrawViewBorder
368 =
369 = Draws the border around the view for different size windows
370 ==================
371 */
372
373 boolean BorderNeedRefresh;
374
375 void R_DrawViewBorder (void)
376 {
377 #ifdef RENDER3D
378     int lump;
379
380 #if 0
381         if (scaledviewwidth == SCREENWIDTH)
382                 return;
383 #else
384     if((scaledviewwidth == 320 && sbarscale == 20) ||
385         (sbarscale != 20 && viewheight == 200))
386         return;
387 #endif
388     // View background.
389     OGL_SetColorAndAlpha(1,1,1,1);
390     if(shareware)
391     {  
392         OGL_SetFlat(W_GetNumForName("FLOOR04")-firstflat);
393     }
394     else
395     {
396         OGL_SetFlat(W_GetNumForName("FLAT513")-firstflat);
397     }
398
399 #if 1
400     OGL_DrawCutRectTiled(0, 0, 320, 200 - SBARHEIGHT, 64, 64,
401                     viewwindowx-4, viewwindowy-4, viewwidth+8, viewheight+8);
402 #else
403     //OGL_DrawRectTiled(0, 0, SCREENWIDTH, SCREENHEIGHT-SBARHEIGHT, 64, 64);
404     OGL_DrawCutRectTiled(0, 0, 320, 200 - (sbarscale==20? SBARHEIGHT : 0)
405                     /**sbarscale/20*/, 64, 64,
406                     viewwindowx-4, viewwindowy-4, viewwidth+8, viewheight+8);
407 #endif
408
409     // The border top.
410     OGL_SetPatch(lump=W_GetNumForName("bordt"));
411     OGL_DrawRectTiled(viewwindowx, viewwindowy-4, viewwidth,
412                       lumptexsizes[lump].h, 16, lumptexsizes[lump].h);
413     // Border bottom.
414     OGL_SetPatch(lump=W_GetNumForName("bordb"));
415     OGL_DrawRectTiled(viewwindowx, viewwindowy+viewheight, viewwidth,
416                       lumptexsizes[lump].h, 16, lumptexsizes[lump].h);
417
418     // Left view border.
419     OGL_SetPatch(lump=W_GetNumForName("bordl"));
420     OGL_DrawRectTiled(viewwindowx-4, viewwindowy, lumptexsizes[lump].w,
421                       viewheight, lumptexsizes[lump].w, 16);
422     // Right view border.
423     OGL_SetPatch(lump=W_GetNumForName("bordr"));
424     OGL_DrawRectTiled(viewwindowx+viewwidth, viewwindowy,
425                       lumptexsizes[lump].w,
426         viewheight, lumptexsizes[lump].w, 16);
427
428     OGL_DrawPatch(viewwindowx-4, viewwindowy-4, W_GetNumForName("bordtl"));
429     OGL_DrawPatch(viewwindowx+viewwidth, viewwindowy-4,
430                   W_GetNumForName("bordtr"));
431     OGL_DrawPatch(viewwindowx+viewwidth, viewwindowy+viewheight,
432                   W_GetNumForName("bordbr"));
433
434     OGL_DrawPatch(viewwindowx-4, viewwindowy+viewheight,
435                   W_GetNumForName("bordbl"));
436
437 #else
438         byte    *src, *dest;
439         int             x,y;
440         
441         if (scaledviewwidth == SCREENWIDTH)
442                 return;
443
444         if(shareware)
445         {
446                 src = W_CacheLumpName ("FLOOR04", PU_CACHE);
447         }
448         else
449         {
450                 src = W_CacheLumpName ("FLAT513", PU_CACHE);
451         }
452         dest = screen;
453         
454         for (y=0 ; y<SCREENHEIGHT-SBARHEIGHT ; y++)
455         {
456                 for (x=0 ; x<SCREENWIDTH/64 ; x++)
457                 {
458                         memcpy (dest, src+((y&63)<<6), 64);
459                         dest += 64;
460                 }
461                 if (SCREENWIDTH&63)
462                 {
463                         memcpy (dest, src+((y&63)<<6), SCREENWIDTH&63);
464                         dest += (SCREENWIDTH&63);
465                 }
466         }
467         for(x=viewwindowx; x < viewwindowx+viewwidth; x += 16)
468         {
469                 V_DrawPatch(x, viewwindowy-4, W_CacheLumpName("bordt", PU_CACHE));
470                 V_DrawPatch(x, viewwindowy+viewheight, W_CacheLumpName("bordb", 
471                         PU_CACHE));
472         }
473         for(y=viewwindowy; y < viewwindowy+viewheight; y += 16)
474         {
475                 V_DrawPatch(viewwindowx-4, y, W_CacheLumpName("bordl", PU_CACHE));
476                 V_DrawPatch(viewwindowx+viewwidth, y, W_CacheLumpName("bordr", 
477                         PU_CACHE));
478         }
479         V_DrawPatch(viewwindowx-4, viewwindowy-4, W_CacheLumpName("bordtl", 
480                 PU_CACHE));
481         V_DrawPatch(viewwindowx+viewwidth, viewwindowy-4, 
482                 W_CacheLumpName("bordtr", PU_CACHE));
483         V_DrawPatch(viewwindowx+viewwidth, viewwindowy+viewheight, 
484                 W_CacheLumpName("bordbr", PU_CACHE));
485         V_DrawPatch(viewwindowx-4, viewwindowy+viewheight, 
486                 W_CacheLumpName("bordbl", PU_CACHE));
487 #endif
488 }
489
490 /*
491 ==================
492 =
493 = R_DrawTopBorder
494 =
495 = Draws the top border around the view for different size windows
496 ==================
497 */
498
499 boolean BorderTopRefresh;
500
501 void R_DrawTopBorder (void)
502 {
503 #ifdef RENDER3D
504     if (scaledviewwidth == SCREENWIDTH)
505         return;
506
507     OGL_SetColorAndAlpha( 1,1,1,1 );
508     if(shareware)
509     {  
510         OGL_SetFlat(W_GetNumForName("FLOOR04")-firstflat);
511     }
512     else
513     {
514         OGL_SetFlat(W_GetNumForName("FLAT513")-firstflat);
515     }
516
517     OGL_DrawRectTiled(0, 0, 320, 64, 64, 64);
518
519     if( viewwindowy < 65 )
520     {
521         int lump;
522         OGL_SetPatch(lump=W_GetNumForName("bordt"));
523         OGL_DrawRectTiled(viewwindowx, viewwindowy-4, viewwidth,
524             lumptexsizes[lump].h, 16, lumptexsizes[lump].h);
525
526         OGL_DrawPatch(viewwindowx-4, viewwindowy, W_GetNumForName("bordl"));
527         OGL_DrawPatch(viewwindowx+viewwidth, viewwindowy,
528                       W_GetNumForName("bordr"));
529         OGL_DrawPatch(viewwindowx-4, viewwindowy+16,
530                       W_GetNumForName("bordl"));
531         OGL_DrawPatch(viewwindowx+viewwidth, viewwindowy+16,
532                       W_GetNumForName("bordr"));
533
534         OGL_DrawPatch(viewwindowx-4, viewwindowy-4,
535                       W_GetNumForName("bordtl"));
536         OGL_DrawPatch(viewwindowx+viewwidth, viewwindowy-4,
537                       W_GetNumForName("bordtr"));//, PU_CACHE));
538     }
539
540 #else
541         byte    *src, *dest;
542         int             x,y;
543         
544         if (scaledviewwidth == SCREENWIDTH)
545                 return;
546
547         if(shareware)
548         {
549                 src = W_CacheLumpName ("FLOOR04", PU_CACHE);
550         }
551         else
552         {
553                 src = W_CacheLumpName ("FLAT513", PU_CACHE);
554         }
555         dest = screen;
556         
557         for (y=0 ; y<30 ; y++)
558         {
559                 for (x=0 ; x<SCREENWIDTH/64 ; x++)
560                 {
561                         memcpy (dest, src+((y&63)<<6), 64);
562                         dest += 64;
563                 }
564                 if (SCREENWIDTH&63)
565                 {
566                         memcpy (dest, src+((y&63)<<6), SCREENWIDTH&63);
567                         dest += (SCREENWIDTH&63);
568                 }
569         }
570         if(viewwindowy < 25)
571         {
572                 for(x=viewwindowx; x < viewwindowx+viewwidth; x += 16)
573                 {
574                         V_DrawPatch(x, viewwindowy-4, W_CacheLumpName("bordt", PU_CACHE));
575                 }
576                 V_DrawPatch(viewwindowx-4, viewwindowy, W_CacheLumpName("bordl", 
577                         PU_CACHE));
578                 V_DrawPatch(viewwindowx+viewwidth, viewwindowy, 
579                         W_CacheLumpName("bordr", PU_CACHE));
580                 V_DrawPatch(viewwindowx-4, viewwindowy+16, W_CacheLumpName("bordl", 
581                         PU_CACHE));
582                 V_DrawPatch(viewwindowx+viewwidth, viewwindowy+16, 
583                         W_CacheLumpName("bordr", PU_CACHE));
584
585                 V_DrawPatch(viewwindowx-4, viewwindowy-4, W_CacheLumpName("bordtl", 
586                         PU_CACHE));
587                 V_DrawPatch(viewwindowx+viewwidth, viewwindowy-4, 
588                         W_CacheLumpName("bordtr", PU_CACHE));
589         }
590 #endif
591 }