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