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