1 // Emacs style mode select   -*- C++ -*-
2 //-----------------------------------------------------------------------------
3 //
4 // $Id: r_draw.c 1440 2019-05-19 02:31:03Z wesleyjohnson $
5 //
6 // Copyright (C) 1993-1996 by id Software, Inc.
7 // Portions Copyright (C) 1998-2016 by DooM Legacy Team.
8 //
9 // This program is free software; you can redistribute it and/or
10 // modify it under the terms of the GNU General Public License
11 // as published by the Free Software Foundation; either version 2
12 // of the License, or (at your option) any later version.
13 //
14 // This program is distributed in the hope that it will be useful,
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 // GNU General Public License for more details.
18 //
19 //
20 // $Log: r_draw.c,v $
21 // Revision 1.14  2003/06/10 23:36:09  ssntails
22 // Variable flat support (32x32 to 2048x2048)
23 //
24 // Revision 1.13  2001/08/06 23:57:09  stroggonmeth
25 // Removed portal code, improved 3D floors in hardware mode.
26 //
27 // Revision 1.12  2001/04/01 17:35:06  bpereira
28 //
29 // Revision 1.11  2001/03/13 22:14:20  stroggonmeth
30 // Long time no commit. 3D floors, FraggleScript, portals, ect.
31 //
32 // Revision 1.10  2001/02/24 13:35:21  bpereira
33 //
34 // Revision 1.9  2001/01/25 22:15:44  bpereira
35 // added heretic support
36 //
37 // Revision 1.8  2000/11/09 17:56:20  stroggonmeth
38 // Revision 1.7  2000/11/03 03:48:54  stroggonmeth
39 //
40 // Revision 1.6  2000/11/02 17:50:09  stroggonmeth
41 // Big 3Dfloors & FraggleScript commit!!
42 //
43 // Revision 1.5  2000/07/01 09:23:49  bpereira
44 //
45 // Revision 1.4  2000/04/07 18:47:09  hurdler
46 // There is still a problem with the asm code and boom colormap
47 // At least, with this little modif, it compiles on my Linux box
48 //
49 // Revision 1.3  2000/04/06 21:06:19  stroggonmeth
50 // Optimized extra_colormap code...
51 // Added #ifdefs for older water code.
52 //
53 // Revision 1.2  2000/02/27 00:42:10  hurdler
54 // Revision 1.1.1.1  2000/02/22 20:32:32  hurdler
55 // Initial import into CVS (v1.29 pr3)
56 //
57 //
58 // DESCRIPTION:
59 //      span / column drawer functions, for 8bpp and 16bpp
60 //
61 //      All drawing to the view buffer is accomplished in this file.
62 //      The other refresh files only know about ccordinates,
63 //      not the architecture of the frame buffer.
64 //      The frame buffer is a linear one, and we need only the base address.
65 //
66 //-----------------------------------------------------------------------------
67 
68 
69 #include "doomincl.h"
70 #include "doomstat.h"
71 #include "r_local.h"
72 #include "st_stuff.h"
73   //added:24-01-98:need ST_HEIGHT
74 #include "i_video.h"
75 #include "v_video.h"
76 #include "w_wad.h"
77 #include "z_zone.h"
78 #include "console.h"
79   //Som: Until I get buffering finished
80 #include "r_draw.h"
81 #include "r_data.h"
82 
83 #ifdef HWRENDER
84 #include "hardware/hw_main.h"
85 #endif
86 
87 // ==========================================================================
88 //                     COMMON DATA FOR 8bpp AND 16bpp
89 // ==========================================================================
90 
91 // [WDJ] rdraw_ are "render drawing window" variables, which have the
92 // dimensions of the window into which the span and column routines draw.
93 // (view is already used by player, window is also used, rw_ is used)
94 byte*           viewimage;
95 int             rdraw_viewwidth;		// was viewwidth
96                         // width used by drawing routines
97                         // half of pixel width when low res
98 int             rdraw_scaledviewwidth;		// was scaledrviewwidth
99                         // width of view window in pixels
100 int             rdraw_viewheight;		// was viewheight
101                         // height of view window in rows (pixels)
102 // position of smaller rdraw_view window within vid window
103 int             viewwindowx;
104 int             viewwindowy;
105 
106                 // pointer to the start of each line of the screen,
107 byte*           ylookup[MAXVIDHEIGHT];
108 
109 byte*           ylookup1[MAXVIDHEIGHT]; // for view1 (splitscreen)
110 byte*           ylookup2[MAXVIDHEIGHT]; // for view2 (splitscreen)
111 
112                  // x byte offset for columns inside the viewwindow
113                 // so the first column starts at (SCRWIDTH-VIEWWIDTH)/2
114 int             columnofs[MAXVIDWIDTH];
115 
116 #ifdef HORIZONTALDRAW
117 //Fab 17-06-98: horizontal column drawer optimisation
118 byte*           yhlookup[MAXVIDWIDTH];
119 int             hcolumnofs[MAXVIDHEIGHT];
120 #endif
121 
122 byte            dr_alpha;  // translucent and fog alpha, 0..255
123 #ifdef ENABLE_DRAW_ALPHA
124 byte            dr_alpha_mode;  // alpha combine modes
125 byte            dr_alpha_background;  // alpha applied to background
126 byte            dr_color8;
127 RGBA_t          dr_color;  // draw alpha
128 #endif
129 
130 // =========================================================================
131 //                      COLUMN DRAWING CODE STUFF
132 // =========================================================================
133 
134 lighttable_t*           dc_colormap;
135 int                     dc_x;
136 int                     dc_yl;
137 int                     dc_yh;
138 
139 fixed_t                 dc_iscale;
140 fixed_t                 dc_texturemid;
141 
142 byte*                   dc_source;
143 
144 
145 // -----------------------
146 // translucency stuff here
147 // -----------------------
148 // The number of translucency tables that are used.
149 #define NUM_TRANSLUCENTTABLES  5
150 
151 byte*                   translucenttables;    // translucency tables
152 
153 // R_DrawTransColumn uses this
154 byte*                   dc_translucentmap;    // one of the translucency tables
155 byte                    dc_translucent_index;
156 
157 
158 // ----------------------
159 // skin translation stuff
160 // ----------------------
161 
162 // [WDJ] player skin translation, skintranstables[NUMSKINCOLORS-1][256]
163 // Does not translate color 0
164 byte*                   skintranstables;  // player skin translation tables
165 
166 // R_DrawTranslatedColumn uses this
167 byte*                   dc_skintran; // ptr to one skintranstables table
168 
169 
170 struct r_lightlist_s*   dc_lightlist = NULL;
171 int                     dc_numlights = 0;
172 int                     dc_maxlights;
173 
174 int     dc_texheight;
175 
176 // =========================================================================
177 //                      SPAN DRAWING CODE STUFF
178 // =========================================================================
179 
180 int                     ds_y;
181 int                     ds_x1;
182 int                     ds_x2;
183 
184 lighttable_t*           ds_colormap;
185 
186 fixed_t                 ds_xfrac;
187 fixed_t                 ds_yfrac;
188 fixed_t                 ds_xstep;
189 fixed_t                 ds_ystep;
190 
191 byte*                   ds_source;      // start of a 64*64 tile image
192 byte*                   ds_translucentmap;    // one of the translucency tables
193 
194 // Variable flat sizes SSNTails 06-10-2003
195 unsigned int flatsize;
196 unsigned int flatbitsz;  // flat bit size, flatsize = 2**flatbitsz
197 unsigned int flatfracbits; // FRACBITS - flatbitsz
198 unsigned int flat_ymask;   // index mask, = (flatsize-1)<<flatbitsz
199 fixed_t      flat_imask;   // index mask, = (flatsize<<FRACBITS) - 1
200 
201 
202 // ==========================================================================
203 //                        OLD DOOM FUZZY EFFECT
204 // ==========================================================================
205 
206 //
207 // Spectre/Invisibility.
208 //
209 #define FUZZTABLE     50
210 #define FUZZOFF       (1)
211 
212 static  int fuzzoffset[FUZZTABLE] =
213 {
214     FUZZOFF,-FUZZOFF,FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,
215     FUZZOFF,FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,
216     FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,-FUZZOFF,-FUZZOFF,-FUZZOFF,
217     FUZZOFF,-FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,
218     FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,-FUZZOFF,FUZZOFF,
219     FUZZOFF,-FUZZOFF,-FUZZOFF,-FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,
220     FUZZOFF,FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,FUZZOFF
221 };
222 
223 static  int fuzzpos = 0;     // move through the fuzz table
224 
225 
226 //  fuzzoffsets are dependent upon vid width, for optimising purpose
227 //  this is called by SCR_Recalc() whenever the screen size changes
228 //
R_RecalcFuzzOffsets(void)229 void R_RecalcFuzzOffsets (void)
230 {
231     int i;
232 //    int offset = 1; // Doom original
233 //    int offset = vid.width // as in ver 1.42 (which seems wrong)
234     int offset = (((vid.width * 2) / BASEVIDWIDTH) + 1)/2;  // proportional rounded
235     offset *= vid.bytepp;
236     for (i=0;i<FUZZTABLE;i++)
237     {
238         fuzzoffset[i] = (fuzzoffset[i] < 0) ? -offset : offset;
239     }
240 }
241 
242 
243 // =========================================================================
244 //                   TRANSLATION COLORMAP CODE
245 // =========================================================================
246 
247 char *Color_Names[NUMSKINCOLORS]={
248    "Green",
249    "Gray" ,
250    "Brown",
251    "Red"  ,
252    "light gray" ,
253    "light brown",
254    "light red"  ,
255    "light blue" ,
256    "Blue"       ,
257    "Yellow"     ,
258    "Beige"
259 };
260 
261 CV_PossibleValue_t Color_cons_t[]={{0,NULL},{1,NULL},{2,NULL},{3,NULL},
262                                    {4,NULL},{5,NULL},{6,NULL},{7,NULL},
263                                    {8,NULL},{9,NULL},{10,NULL},{0,NULL}};
264 
265 // [WDJ] Preparation for these skin tables being read from files.
266 
267 typedef struct {
268   byte  num_using_ramp1;      // number of trans using ramp1
269   byte  skin_ramp_colornum1;  // ramp1 start
270   byte  skin_ramp_colornum2;  // ramp2 start
271 } skin_trans_entry_t;
272 
273 typedef struct {
274    byte      range_start, range_end; // translate in this range
275    skin_trans_entry_t  skin[NUMSKINCOLORS];  // skin translation
276 } skin_trans_desc_t;
277 
278 skin_trans_desc_t  doom_skins =
279 {
280    0x70, 0x7f,       // range of original green
281  {
282   { 16, 0x60, 0x60}, // gray
283   { 16, 0x40, 0x40}, // brown
284   { 16, 0x20, 0x20}, // red
285   { 16, 0x58, 0x58}, // light gray
286   { 16, 0x38, 0x38}, // light brown
287   { 16, 0xb0, 0xb0}, // light red
288   { 16, 0xc0, 0xc0}, // light blue
289   {  9, 0xc7, 0xf0}, // dark blue
290   {  8, 0xe0, 0xa0}, // yellow
291   { 16, 0x80, 0x80}  // beige
292  }
293 };
294 
295 skin_trans_desc_t  heretic_skins =
296 {
297    225, 240,	// range of original player color
298  {
299   { 15, 0, 0}, // gray
300   { 15, 67, 67}, // brown
301   { 15, 145, 145}, // red
302   { 15, 9, 9}, // light gray
303   { 15, 74, 74}, // light brown
304   { 15, 150, 150}, // light red
305   { 15, 192, 192}, // light blue
306   { 15, 185, 185}, // dark blue
307   { 15, 114, 114}, // yellow
308   { 15, 95, 95}  // beige
309  }
310 };
311 
312 //  Creates the translation tables to map the green color ramp to
313 //  another ramp (gray, brown, red, ...)
314 //
315 //  This is precalculated for drawing the player sprites in the player's
316 //  chosen color
317 //
R_Init_TranslationTables(void)318 void R_Init_TranslationTables (void)
319 {
320     skin_trans_desc_t  * skindesc = & doom_skins;
321     int i;
322     // Each translucent table is 256x256, has size 65536 = 0x10000.
323 
324     //added:11-01-98: load here the transparency lookup tables 'TINTTAB'
325     // NOTE: the TINTTAB resource MUST BE aligned on 64k for the asm optimised
326     //       (in other words, translucenttables pointer low word is 0)
327     translucenttables = Z_MallocAlign (NUM_TRANSLUCENTTABLES*0x10000, PU_STATIC, 0, 16);
328 
329     // load in translucency tables
330     if( gamemode == heretic )
331     {
332         skindesc = & heretic_skins; // skin translation desc
333         W_ReadLump( W_GetNumForName("TINTTAB"), translucenttables );
334         W_ReadLump( W_GetNumForName("TINTTAB"), translucenttables+0x10000 );
335         W_ReadLump( W_GetNumForName("TINTTAB"), translucenttables+0x20000 );
336         W_ReadLump( W_GetNumForName("TINTTAB"), translucenttables+0x30000 );
337         W_ReadLump( W_GetNumForName("TINTTAB"), translucenttables+0x40000 );
338     }
339     else
340     {
341         skindesc = & doom_skins;  // skin translation desc
342         W_ReadLump( W_GetNumForName("TRANSMED"), translucenttables );
343         W_ReadLump( W_GetNumForName("TRANSMOR"), translucenttables+0x10000 );
344         W_ReadLump( W_GetNumForName("TRANSHI"),  translucenttables+0x20000 );
345         W_ReadLump( W_GetNumForName("TRANSFIR"), translucenttables+0x30000 );
346         W_ReadLump( W_GetNumForName("TRANSFX1"), translucenttables+0x40000 );
347     }
348 
349     // no translate table for color 0
350     skintranstables = Z_MallocAlign (256*(NUMSKINCOLORS-1), PU_STATIC, 0, 8);
351 
352     // [WDJ] skin desc based skin translation generation
353     int sk;
354     for (sk = 1; sk<NUMSKINCOLORS; sk++)
355     {
356         // sk=0 is original skin, and does not appear in translation tables
357         byte * trantab = SKIN_TO_SKINMAP( sk );
358         skin_trans_entry_t * skintr = & skindesc->skin[sk-1]; // skins 1..
359         for (i=0 ; i<256 ; i++)
360         {
361             byte newcolor = i; // default is to keep the color the same
362             if ( i >= skindesc->range_start && i <= skindesc->range_end )
363             {
364                 int ri = i - skindesc->range_start; // ramp index
365                 // new color is color_start + ramp index
366                 newcolor = ( ri < skintr->num_using_ramp1 )?
367                     skintr->skin_ramp_colornum1
368                     : (skintr->skin_ramp_colornum2 - skintr->num_using_ramp1);
369                 newcolor += ri;
370             }
371             trantab[i] = newcolor;
372         }
373     }
374 }
375 
376 // Changes in drawmode
R_Setup_Drawmode(void)377 void  R_Setup_Drawmode( void )
378 {
379     R_PrecacheLevel();
380     R_rdata_setup_rendermode();
381 }
382 
383 
384 // ==========================================================================
385 //               COMMON DRAWER FOR 8 AND 16 BIT COLOR MODES
386 // ==========================================================================
387 
388 // in a perfect world, all routines would be compatible for either mode,
389 // and optimised enough
390 //
391 // in reality, the few routines that can work for either mode, are
392 // put here
393 
394 
395 // R_Init_ViewBuffer
396 // Creates lookup tables for getting the framebuffer address
397 //  of a pixel to draw.
398 //
R_Init_ViewBuffer(int width,int height)399 void R_Init_ViewBuffer ( int   width,
400                         int   height )
401 {
402     // ViewBuffer may be smaller than video or screen buffers
403     int  bytesperpixel = vid.bytepp;  // smaller code
404     int  i;
405 
406     if (bytesperpixel<1 || bytesperpixel>4)
407     {
408         I_Error ("R_Init_ViewBuffer : Invalid bytesperpixel value %d\n",
409                  bytesperpixel);
410     }
411 
412     // Handle resize,
413     //  e.g. smaller view windows
414     //  with border and/or status bar.
415     viewwindowx = (vid.width-width) >> 1;
416 
417     // Column offset for those columns of the view window, but
418     // relative to the entire screen
419     for (i=0 ; i<width ; i++)
420         columnofs[i] = (viewwindowx + i) * bytesperpixel;
421 
422     // Same with base row offset.
423     if (width == vid.width)
424         viewwindowy = 0;
425     else
426         viewwindowy = (vid.height - stbar_height - height) >> 1;
427 
428     // [WDJ] Table fixed for all bpp, bytepp, and padding
429     // Precalculate all row offsets for screen[0] buffer.
430     for (i=0 ; i<height ; i++)
431     {
432         ylookup[i] = ylookup1[i] = vid.display + (i+viewwindowy)*vid.ybytes;
433                      ylookup2[i] = vid.display + (i+(vid.height>>1))*vid.ybytes; // for splitscreen
434     }
435 
436 
437 #ifdef HORIZONTALDRAW
438     //Fab 17-06-98
439     // create similar lookup tables for horizontal column draw optimisation
440     // [WDJ] assumes screen buffer is width x height, not padded
441     // This is not directly compatible with any screen buffer
442 
443     // (the first column is the bottom line)
444     for (i=0; i<width; i++)
445         yhlookup[i] = screens[2] + ((width-i-1) * bytesperpixel * height);
446 
447     for (i=0; i<height; i++)
448         hcolumnofs[i] = i * bytesperpixel;
449 #endif
450 }
451 
452 
453 //
454 // Store the lumpnumber of the viewborder patches.
455 //
456 lumpnum_t  viewborderlump[8];
457 
R_Init_ViewBorder(void)458 void R_Init_ViewBorder (void)
459 {
460     if( EN_heretic_hexen )
461     {   // Heretic, Hexen
462         viewborderlump[BRDR_T]  = W_GetNumForName ("bordt");
463         viewborderlump[BRDR_B]  = W_GetNumForName ("bordb");
464         viewborderlump[BRDR_L]  = W_GetNumForName ("bordl");
465         viewborderlump[BRDR_R]  = W_GetNumForName ("bordr");
466         viewborderlump[BRDR_TL] = W_GetNumForName ("bordtl");
467         viewborderlump[BRDR_BL] = W_GetNumForName ("bordbl");
468         viewborderlump[BRDR_TR] = W_GetNumForName ("bordtr");
469         viewborderlump[BRDR_BR] = W_GetNumForName ("bordbr");
470     }
471     else
472     {   // Doom
473         viewborderlump[BRDR_T]  = W_GetNumForName ("brdr_t");
474         viewborderlump[BRDR_B]  = W_GetNumForName ("brdr_b");
475         viewborderlump[BRDR_L]  = W_GetNumForName ("brdr_l");
476         viewborderlump[BRDR_R]  = W_GetNumForName ("brdr_r");
477         viewborderlump[BRDR_TL] = W_GetNumForName ("brdr_tl");
478         viewborderlump[BRDR_BL] = W_GetNumForName ("brdr_bl");
479         viewborderlump[BRDR_TR] = W_GetNumForName ("brdr_tr");
480         viewborderlump[BRDR_BR] = W_GetNumForName ("brdr_br");
481     }
482 }
483 
484 
485 //
486 // R_FillBackScreen
487 // Fills the back screen with a pattern for variable screen sizes
488 // Also draws a beveled edge.
489 //
R_FillBackScreen(void)490 void R_FillBackScreen (void)
491 {
492     patch_t*    patch;
493     byte*       src;
494     byte*       dest;  // within video buffer
495     int         x, y;
496     int         step,boff;
497 
498     //faB: quickfix, don't cache lumps in both modes
499     if( rendermode != render_soft )
500         return;
501 
502      //added:08-01-98:draw pattern around the status bar too (when hires),
503     //                so return only when in full-screen without status bar.
504     if ((rdraw_scaledviewwidth == vid.width)&&(rdraw_viewheight==vid.height))
505         return;
506 
507     // draw pattern around the status bar
508     src  = scr_borderflat;
509     dest = screens[1];  // background buffer
510 
511     // [WDJ] Draw for all bpp, bytepp, and padding
512     for (y=0 ; y<vid.height ; y++)
513     {
514         // repeatly draw a 64 pixel wide flat
515         dest = screens[1] + (y * vid.ybytes);  // within screen buffer
516         for (x=0 ; x<(vid.width/64) ; x++)
517         {
518 //            memcpy (dest, src+((y&63)<<6), 64);
519             V_DrawPixels( dest, 0, 64, &src[(y & 63) << 6]);
520             dest += (64 * vid.bytepp);
521         }
522 
523         if (vid.width&63)
524         {
525 //            memcpy (dest, src+((y&63)<<6), vid.width&63);
526             V_DrawPixels( dest, 0, 64, &src[(y & 63) << 6]);
527         }
528     }
529 
530     //added:08-01-98:dont draw the borders when viewwidth is full vid.width.
531     if (rdraw_scaledviewwidth == vid.width)
532        return;
533 
534     // viewwindow borders
535     if( EN_heretic )
536     {
537         step = 16;
538         boff = 4; // borderoffset
539     }
540     else
541     {
542         step = 8;
543         boff = 8;
544     }
545 
546     // Draw to screen1
547     // top
548     patch = W_CacheLumpNum (viewborderlump[BRDR_T],PU_CACHE);
549     for (x=viewwindowx; x<(viewwindowx+rdraw_scaledviewwidth); x+=step)
550         V_DrawPatch (x, viewwindowy-boff, 1, patch);
551     // bottom
552     patch = W_CacheLumpNum (viewborderlump[BRDR_B],PU_CACHE);
553     for (x=viewwindowx; x<(viewwindowx+rdraw_scaledviewwidth); x+=step)
554         V_DrawPatch (x, viewwindowy+rdraw_viewheight, 1, patch);
555     patch = W_CacheLumpNum (viewborderlump[BRDR_L],PU_CACHE);
556     // Vertical edge is not an even multiple, so draw last aligned.
557     // left
558     for (y=viewwindowy; y<(viewwindowy+rdraw_viewheight-step); y+=step)
559         V_DrawPatch (viewwindowx-boff, y, 1, patch);
560     V_DrawPatch (viewwindowx-boff, (viewwindowy+rdraw_viewheight-step), 1, patch);
561     // right
562     patch = W_CacheLumpNum (viewborderlump[BRDR_R],PU_CACHE);
563     for (y=viewwindowy; y<(viewwindowy+rdraw_viewheight-step); y+=step)
564         V_DrawPatch (viewwindowx+rdraw_scaledviewwidth, y, 1, patch);
565     V_DrawPatch (viewwindowx+rdraw_scaledviewwidth, (viewwindowy+rdraw_viewheight-step), 1, patch);
566 
567     // Draw beveled corners.
568     V_DrawPatch (viewwindowx-boff,
569                  viewwindowy-boff,
570                  1,
571                  W_CacheLumpNum (viewborderlump[BRDR_TL],PU_CACHE));
572 
573     V_DrawPatch (viewwindowx+rdraw_scaledviewwidth,
574                  viewwindowy-boff,
575                  1,
576                  W_CacheLumpNum (viewborderlump[BRDR_TR],PU_CACHE));
577 
578     V_DrawPatch (viewwindowx-boff,
579                  viewwindowy+rdraw_viewheight,
580                  1,
581                  W_CacheLumpNum (viewborderlump[BRDR_BL],PU_CACHE));
582 
583     V_DrawPatch (viewwindowx+rdraw_scaledviewwidth,
584                  viewwindowy+rdraw_viewheight,
585                  1,
586                  W_CacheLumpNum (viewborderlump[BRDR_BR],PU_CACHE));
587 }
588 
589 
590 //
591 // Copy a screen buffer.
592 //
R_VideoErase(unsigned ofs,int count)593 void R_VideoErase (unsigned ofs, int count)
594 {
595     // LFB copy.
596     // This might not be a good idea if memcpy is not optimal,
597     //  e.g. byte by byte on a 32bit CPU, as GNU GCC/Linux libc did
598     //  at one point.
599     memcpy (screens[0]+ofs, screens[1]+ofs, count);
600 }
601 
602 
603 //
604 // R_DrawViewBorder
605 // Draws the border around the view
606 //  for different size windows?
607 //
R_DrawViewBorder(void)608 void R_DrawViewBorder (void)
609 {
610     int  top;
611     int  topbytes;
612     int  side;
613     int  ofs;
614 
615 #ifdef HWRENDER // not win32 only 19990829 by Kin
616     if (rendermode != render_soft)
617     {
618         HWR_DrawViewBorder (0);  // 0 means draw all
619         return;
620     }
621 #endif
622 
623 
624 #ifdef DEBUG
625     debug_Printf("RDVB: vidwidth %d vidheight %d rdraw_scaledviewwidth %d rdraw_viewheight %d\n",
626              vid.width,vid.height,rdraw_scaledviewwidth,rdraw_viewheight);
627 #endif
628 
629      //added:08-01-98: draw the backtile pattern around the status bar too
630     //                 (when statusbar width is shorter than vid.width)
631     /*
632     if( (vid.width>ST_WIDTH) && (vid.height!=rdraw_viewheight) )
633     {
634         ofs  = (vid.height - stbar_height) * vid.ybytes;
635         side = (vid.width-ST_WIDTH)>>1;
636         R_VideoErase(ofs,side);
637 
638         ofs += (vid.width-side);
639         for (i=1;i<stbar_height;i++)
640         {
641             R_VideoErase(ofs,side<<1);  //wraparound right to left border
642             ofs += vid.width;
643         }
644         R_VideoErase(ofs,side);
645     }*/
646 
647     if (rdraw_scaledviewwidth == vid.width)
648         return;
649 
650     // rdraw_viewheight is the height of the window within the border
651     // draw view border
652     top  = (vid.height - stbar_height - rdraw_viewheight) >>1;
653     topbytes = top * vid.ybytes;
654     side = (vid.width-rdraw_scaledviewwidth) >>1;
655 
656     // copy background to display screen
657     // [WDJ] cannot wrap around because some video cards pad the video buffer
658     // copy top
659     R_VideoErase (0, topbytes);
660 
661     // copy bottom
662     R_VideoErase ((rdraw_viewheight+top)*vid.ybytes, topbytes);
663 
664     //added:05-02-98:simpler using our new VID_Blit routine
665     // copy left side
666     VID_BlitLinearScreen(screens[1]+topbytes, screens[0]+topbytes,
667                          side * vid.bytepp, rdraw_viewheight, vid.ybytes, vid.ybytes);
668 
669     // copy right side
670     ofs = topbytes + ((vid.width-side)*vid.bytepp);
671     VID_BlitLinearScreen(screens[1]+ofs, screens[0]+ofs,
672                          side * vid.bytepp, rdraw_viewheight, vid.ybytes, vid.ybytes);
673 
674 #ifdef DIRTY_RECT
675     // useless, old dirty rectangle stuff
676     //V_MarkRect (0,0,vid.width, vid.height - stbar_height);
677 #endif
678 }
679 
680 // SoM: This is for 3D floors that cast shadows on walls.
681 // This function just cuts the column up into sections and calls
682 // R_DrawColumn
R_DrawColumnShadowed(void)683 void R_DrawColumnShadowed(void)
684 {
685     int count;
686 //    int realyh, realyl;
687     int realyh;
688     int i;
689     int height, bheight = 0;
690     int solid = 0;
691 
692     realyh = dc_yh;
693 //    realyl = dc_yl;
694 
695     count = dc_yh - dc_yl;
696 
697     // Zero length, column does not exceed a pixel.
698     if (count < 0)
699         return;
700 
701 #ifdef RANGECHECK
702     // [WDJ] Draw window is actually rdraw_viewwidth and rdraw_viewheight
703     if ((unsigned) dc_x >= rdraw_viewwidth || dc_yl < 0 || dc_yh >= rdraw_viewheight)
704     {
705         I_SoftError("R_DrawShadowedColumn: %i to %i at %i\n", dc_yl, dc_yh, dc_x);
706         return;
707     }
708 #endif
709 
710     // SoM: This runs through the lightlist from top to bottom and cuts up
711     // the column accordingly.
712     for (i = 0; i < dc_numlights; i++)
713     {
714         // If the height of the light is above the column, get the colormap
715         // anyway because the lighting of the top should be affected.
716         solid = dc_lightlist[i].flags & FF_CUTSOLIDS;
717 
718         height = dc_lightlist[i].height >> 12;
719         if (solid)
720             bheight = dc_lightlist[i].botheight >> 12;
721         if (height <= dc_yl)
722         {
723             dc_colormap = dc_lightlist[i].rcolormap;
724             if (solid && dc_yl < bheight)
725                 dc_yl = bheight;
726             continue;
727         }
728         // Found a break in the column!
729         dc_yh = height;
730 
731         if (dc_yh > realyh)
732             dc_yh = realyh;
733         basecolfunc();  // R_DrawColumn_x
734         if (solid)
735             dc_yl = bheight;
736         else
737             dc_yl = dc_yh + 1;
738 
739         dc_colormap = dc_lightlist[i].rcolormap;
740     }
741     dc_yh = realyh;
742     if (dc_yl <= realyh)
743         basecolfunc();  // R_DrawColumn_x
744 }
745 
746 
747 // ==========================================================================
748 //                   INCLUDE 8bpp DRAWING CODE HERE
749 // ==========================================================================
750 
751 #include "r_draw8.c"
752 
753 
754 // ==========================================================================
755 //                   INCLUDE 16bpp DRAWING CODE HERE
756 // ==========================================================================
757 
758 #if defined( ENABLE_DRAW15 ) || defined( ENABLE_DRAW16 )
759 #include "r_draw16.c"
760 #endif
761 
762 
763 // ==========================================================================
764 //                   INCLUDE 24bpp DRAWING CODE HERE
765 // ==========================================================================
766 
767 #ifdef ENABLE_DRAW24
768 #include "r_draw24.c"
769 #endif
770 
771 
772 // ==========================================================================
773 //                   INCLUDE 32bpp DRAWING CODE HERE
774 // ==========================================================================
775 
776 #ifdef ENABLE_DRAW32
777 #include "r_draw32.c"
778 #endif
779 
780