1 // Emacs style mode select -*- C++ -*-
2 //-----------------------------------------------------------------------------
3 //
4 // $Id: r_draw8.c 1557 2020-11-17 23:34:31Z wesleyjohnson $
5 //
6 // Copyright (C) 1998-2000 by DooM Legacy Team.
7 // Portions Copyright (C) 2000-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_draw8.c,v $
21 // Revision 1.25 2003/07/13 18:04:57 hurdler
22 // Revision 1.24 2003/07/13 13:16:15 hurdler
23 //
24 // Revision 1.23 2003/06/10 23:36:09 ssntails
25 // Variable flat support (32x32 to 2048x2048)
26 //
27 // Revision 1.22 2002/11/12 00:06:05 ssntails
28 // Support for translated translucent columns in software mode.
29 //
30 // Revision 1.21 2002/01/12 02:21:36 stroggonmeth
31 //
32 // Revision 1.20 2001/08/06 23:57:09 stroggonmeth
33 // Removed portal code, improved 3D floors in hardware mode.
34 //
35 // Revision 1.19 2001/04/02 18:54:32 bpereira
36 // Revision 1.18 2001/04/01 17:35:07 bpereira
37 //
38 // Revision 1.17 2001/03/21 18:24:39 stroggonmeth
39 // Misc changes and fixes. Code cleanup
40 //
41 // Revision 1.16 2001/03/13 22:14:20 stroggonmeth
42 // Long time no commit. 3D floors, FraggleScript, portals, ect.
43 //
44 // Revision 1.15 2001/01/25 22:15:44 bpereira
45 // added heretic support
46 //
47 // Revision 1.14 2000/11/21 21:13:18 stroggonmeth
48 // Optimised 3D floors and fixed crashing bug in high resolutions.
49 //
50 // Revision 1.13 2000/11/06 20:52:16 bpereira
51 //
52 // Revision 1.12 2000/11/02 17:50:09 stroggonmeth
53 // Big 3Dfloors & FraggleScript commit!!
54 //
55 // Revision 1.11 2000/09/28 20:57:17 bpereira
56 // Revision 1.10 2000/04/30 10:30:10 bpereira
57 // Revision 1.9 2000/04/24 20:24:38 bpereira
58 // Revision 1.8 2000/04/18 17:39:39 stroggonmeth
59 // Revision 1.7 2000/04/08 17:29:25 stroggonmeth
60 //
61 // Revision 1.6 2000/04/06 21:06:19 stroggonmeth
62 // Optimized extra_colormap code...
63 // Added #ifdefs for older water code.
64 //
65 // Revision 1.5 2000/04/05 15:47:46 stroggonmeth
66 // Added hack for Dehacked lumps. Transparent sprites are now affected by colormaps.
67 //
68 // Revision 1.4 2000/04/04 19:28:43 stroggonmeth
69 // Global colormaps working. Added a new linedef type 272.
70 //
71 // Revision 1.3 2000/04/04 00:32:47 stroggonmeth
72 // Initial Boom compatability plus few misc changes all around.
73 //
74 // Revision 1.2 2000/02/27 00:42:10 hurdler
75 // Revision 1.1.1.1 2000/02/22 20:32:32 hurdler
76 // Initial import into CVS (v1.29 pr3)
77 //
78 //
79 // DESCRIPTION:
80 // 8bpp span/column drawer functions
81 //
82 // NOTE: no includes because this is included as part of r_draw.c
83 //
84 //-----------------------------------------------------------------------------
85
86 // [WDJ] Window limit checks have been added to all the callers of colfunc().
87
88 // [WDJ] Combine the Boom enhancements into our draw functions,
89 // so modifications do not have to be made in two functions.
90 #define USEBOOMFUNC
91
92
93 // ==========================================================================
94 // COLUMNS
95 // ==========================================================================
96
97 // A column is a vertical slice/span of a wall texture that uses
98 // a has a constant z depth from top to bottom.
99 //
100
101 #ifndef USEASM
R_DrawColumn_8(void)102 void R_DrawColumn_8(void)
103 {
104 register int count;
105 register byte *dest;
106 register fixed_t frac;
107 register fixed_t fracstep;
108
109 count = dc_yh - dc_yl + 1;
110 if (count <= 0)
111 return; // Zero length, column does not exceed a pixel.
112
113 #ifdef RANGECHECK_DRAW_LIMITS
114 // [WDJ] Draw window is actually rdraw_viewwidth and rdraw_viewheight
115 if ((unsigned) dc_x >= rdraw_viewwidth || dc_yl < 0 || dc_yh >= rdraw_viewheight)
116 {
117 I_SoftError("R_DrawColumn: %i to %i at %i\n", dc_yl, dc_yh, dc_x);
118 return;
119 }
120 #endif
121
122 // Framebuffer destination address.
123 // Use ylookup LUT to avoid multiply with ScreenWidth.
124 // Use columnofs LUT for subwindows?
125 dest = ylookup[dc_yl] + columnofs[dc_x];
126
127 // Determine scaling,
128 // which is the only mapping to be done.
129 fracstep = dc_iscale;
130 frac = dc_texturemid + (dc_yl - centery) * fracstep;
131
132 // Inner loop that does the actual texture mapping,
133 // e.g. a DDA-lile scaling.
134 // This is as fast as it gets.
135 #ifdef USEBOOMFUNC
136 // Do two pixels per loop when possible.
137 {
138 register const byte *source = dc_source;
139 register const lighttable_t *colormap = dc_colormap;
140 register int heightmask = dc_texheight - 1;
141 if (dc_texheight & heightmask)
142 {
143 heightmask++;
144 heightmask <<= FRACBITS;
145
146 if (frac < 0)
147 while ((frac += heightmask) < 0);
148 else
149 while (frac >= heightmask)
150 frac -= heightmask;
151
152 do
153 {
154 // Re-map color indices from wall texture column
155 // using a lighting/special effects LUT.
156 // heightmask is the Tutti-Frutti fix -- killough
157
158 *dest = colormap[source[frac >> FRACBITS]];
159 dest += vid.ybytes;
160 if ((frac += fracstep) >= heightmask)
161 frac -= heightmask;
162 }
163 while (--count);
164 }
165 else
166 {
167 while ((count -= 2) >= 0) // texture height is a power of 2 -- killough
168 {
169 *dest = colormap[source[(frac >> FRACBITS) & heightmask]];
170 dest += vid.ybytes;
171 frac += fracstep;
172 *dest = colormap[source[(frac >> FRACBITS) & heightmask]];
173 dest += vid.ybytes;
174 frac += fracstep;
175 }
176 if (count & 1)
177 *dest = colormap[source[(frac >> FRACBITS) & heightmask]];
178 }
179 }
180 #else
181 // Simple loop. Fixed tile 128.
182 do
183 {
184 // Re-map color indices from wall texture column
185 // using a lighting/special effects LUT.
186 *dest = dc_colormap[dc_source[(frac >> FRACBITS) & 127]];
187
188 dest += vid.ybytes;
189 frac += fracstep;
190
191 }
192 while (--count);
193 #endif
194 }
195 #endif
196
197
198 #ifndef USEASM
R_DrawSkyColumn_8(void)199 void R_DrawSkyColumn_8(void)
200 {
201 register int count;
202 register byte *dest;
203 register fixed_t frac;
204 register fixed_t fracstep;
205
206 #ifdef USEBOOMFUNC
207 count = dc_yh - dc_yl + 1;
208 if (count <= 0)
209 return; // Zero length, column does not exceed a pixel.
210 // while(--count)
211 #else
212 count = dc_yh - dc_yl;
213 if (count < 0)
214 return; // Zero length, column does not exceed a pixel.
215 // while(count--)
216 #endif
217
218 #ifdef RANGECHECK_DRAW_LIMITS
219 // [WDJ] Draw window is actually rdraw_viewwidth and rdraw_viewheight
220 if ((unsigned) dc_x >= rdraw_viewwidth || dc_yl < 0 || dc_yh >= rdraw_viewheight)
221 {
222 I_SoftError("R_DrawSkyColumn: %i to %i at %i\n", dc_yl, dc_yh, dc_x);
223 return;
224 }
225 #endif
226
227 // Framebuffer destination address.
228 // Use ylookup LUT to avoid multiply with ScreenWidth.
229 // Use columnofs LUT for subwindows?
230 dest = ylookup[dc_yl] + columnofs[dc_x];
231
232 // Determine scaling,
233 // which is the only mapping to be done.
234 fracstep = dc_iscale;
235 frac = dc_texturemid + (dc_yl - centery) * fracstep;
236
237 // Inner loop that does the actual texture mapping,
238 // e.g. a DDA-lile scaling.
239 // This is as fast as it gets.
240
241 // [WDJ] FIXME: heightmask=255 is wrong, height is 128 or 240. Looking up, this could segfault.
242 #ifdef USEBOOMFUNC
243 // Do two pixels per loop when possible.
244 {
245 register const byte *source = dc_source;
246 register const lighttable_t *colormap = dc_colormap;
247 register int heightmask = 255;
248 if (dc_texheight & heightmask)
249 {
250 heightmask++;
251 heightmask <<= FRACBITS;
252
253 if (frac < 0)
254 while ((frac += heightmask) < 0);
255 else
256 while (frac >= heightmask)
257 frac -= heightmask;
258
259 do
260 {
261 // Re-map color indices from wall texture column
262 // using a lighting/special effects LUT.
263 // heightmask is the Tutti-Frutti fix -- killough
264
265 *dest = colormap[source[frac >> FRACBITS]];
266 dest += vid.ybytes;
267 if ((frac += fracstep) >= heightmask)
268 frac -= heightmask;
269 }
270 while (--count);
271 }
272 else
273 {
274 while ((count -= 2) >= 0) // texture height is a power of 2 -- killough
275 {
276 *dest = colormap[source[(frac >> FRACBITS) & heightmask]];
277 dest += vid.ybytes;
278 frac += fracstep;
279 *dest = colormap[source[(frac >> FRACBITS) & heightmask]];
280 dest += vid.ybytes;
281 frac += fracstep;
282 }
283 if (count & 1)
284 *dest = colormap[source[(frac >> FRACBITS) & heightmask]];
285 }
286 }
287 #else
288 // Simple loop. Fixed tile 256.
289 do
290 {
291 // Re-map color indices from wall texture column
292 // using a lighting/special effects LUT.
293 *dest = dc_colormap[dc_source[(frac >> FRACBITS) & 255]];
294
295 dest += vid.ybytes;
296 frac += fracstep;
297
298 }
299 while (count--);
300 #endif
301 }
302 #endif
303
304 // The standard Doom 'fuzzy' (blur, shadow) effect
305 // originally used for spectres and when picking up the blur sphere
306 //
307 //#ifndef USEASM // NOT IN ASSEMBLER, TO DO.. IF WORTH IT
R_DrawFuzzColumn_8(void)308 void R_DrawFuzzColumn_8(void)
309 {
310 register int count;
311 register byte *dest;
312 register fixed_t frac;
313 register fixed_t fracstep;
314
315 // Adjust borders. Low...
316 if (dc_yl <= 0)
317 dc_yl = 1;
318
319 // .. and high.
320 if (dc_yh >= rdraw_viewheight - 1)
321 dc_yh = rdraw_viewheight - 2;
322
323 count = dc_yh - dc_yl;
324 if (count < 0)
325 return; // Zero length, column does not exceed a pixel.
326 // while(count--)
327
328 #ifdef RANGECHECK_DRAW_LIMITS
329 // [WDJ] Draw window is actually rdraw_viewwidth and rdraw_viewheight
330 if ((unsigned) dc_x >= rdraw_viewwidth || dc_yl < 0 || dc_yh >= rdraw_viewheight)
331 {
332 I_SoftError("R_DrawFuzzColumn: %i to %i at %i\n", dc_yl, dc_yh, dc_x);
333 return;
334 }
335 #endif
336
337 // Does not work with blocky mode.
338 dest = ylookup[dc_yl] + columnofs[dc_x];
339
340 // Looks familiar.
341 fracstep = dc_iscale;
342 frac = dc_texturemid + (dc_yl - centery) * fracstep;
343
344 do
345 {
346 // Lookup framebuffer, and retrieve a pixel that is either one column
347 // left or right of the current one.
348 // Add index from colormap to index.
349 // Remap existing dest, modify position, dim through LIGHTTABLE[6].
350 // *dest = reg_colormaps[6 * 256 + dest[fuzzoffset[fuzzpos]]];
351 *dest = reg_colormaps[LIGHTTABLE(6) + dest[fuzzoffset[fuzzpos]]];
352
353 // Clamp table lookup index.
354 if (++fuzzpos == FUZZTABLE)
355 fuzzpos = 0;
356
357 dest += vid.ybytes;
358
359 frac += fracstep;
360 }
361 while (count--);
362 }
363
364 //#endif
365
366 #ifndef USEASM
367 // used in tiltview, but never called for now, but who know...
R_DrawSpanNoWrap(void)368 void R_DrawSpanNoWrap(void)
369 {
370 }
371 #endif
372
373 #ifndef USEASM
R_DrawShadeColumn_8(void)374 void R_DrawShadeColumn_8(void)
375 {
376 register int count;
377 register byte *dest;
378 register fixed_t frac;
379 register fixed_t fracstep;
380
381 // [WDJ] This check has been added to all the callers of colfunc().
382 // check out coords for src*
383 // if ((dc_yl < 0) || (dc_x >= vid.width))
384 // return;
385
386 count = dc_yh - dc_yl;
387 if (count < 0)
388 return;
389
390 #ifdef RANGECHECK_DRAW_LIMITS
391 if ((unsigned) dc_x >= rdraw_viewwidth || dc_yl < 0 || dc_yh >= rdraw_viewheight)
392 {
393 I_SoftError("R_DrawShadeColumn: %i to %i at %i\n", dc_yl, dc_yh, dc_x);
394 return;
395 }
396 #endif
397
398 // FIXME. As above.
399 //src = ylookup[dc_yl] + columnofs[dc_x+2];
400 dest = ylookup[dc_yl] + columnofs[dc_x];
401
402 // Looks familiar.
403 fracstep = dc_iscale;
404 frac = dc_texturemid + (dc_yl - centery) * fracstep;
405
406 // Here we do an additional index re-mapping.
407 do
408 {
409 // apply shading/translucent with existing showing through
410 // Remap the existing dest color, dimming it through source LIGHTTABLE.
411 // *dest = *(reg_colormaps + (dc_source[frac >> FRACBITS] << 8) + (*dest));
412 *dest = reg_colormaps[ LIGHTTABLE(dc_source[frac >> FRACBITS]) + (*dest) ];
413
414 dest += vid.ybytes;
415 frac += fracstep;
416 }
417 while (count--);
418 }
419 #endif
420
421 #ifdef ENABLE_DRAW_ALPHA
422 # ifndef ENABLE_DRAW8_USING_12
423 // switch at TRANSLU_REV_ALPHA
424 byte dr8_src_shift[16] = { 8, 8, 8, 8, 8, 8, 8, 8, 8, 0, 0, 0, 0, 0, 0, 0 };
425 byte dr8_dest_shift[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8 };
426 # endif
427
R_DrawAlphaColumn_8(void)428 void R_DrawAlphaColumn_8(void)
429 {
430 register int count;
431 register byte *dest;
432 register fixed_t frac;
433 register fixed_t fracstep;
434 register unsigned int alpha;
435 #ifdef ENABLE_DRAW8_USING_12
436 register unsigned int alpha_r;
437 #endif
438
439 // [WDJ] Source check has been added to all the callers of colfunc().
440
441 count = dc_yh - dc_yl;
442 if (count < 0)
443 return;
444
445 #ifdef RANGECHECK_DRAW_LIMITS
446 if ((unsigned) dc_x >= rdraw_viewwidth || dc_yl < 0 || dc_yh >= rdraw_viewheight)
447 {
448 I_SoftError("R_DrawAlphaColumn: %i to %i at %i\n", dc_yl, dc_yh, dc_x);
449 return;
450 }
451 #endif
452
453 dest = ylookup[dc_yl] + columnofs[dc_x];
454
455 // Looks familiar.
456 fracstep = dc_iscale;
457 frac = dc_texturemid + (dc_yl - centery) * fracstep;
458
459 // Colormap the dr_color at the source.
460
461 #ifdef ENABLE_DRAW8_USING_12
462 switch( dr_alpha_mode )
463 {
464 case 0: // Alpha blend
465 do
466 {
467 // [WDJ] The source is a patch of alpha values, 0..255.
468 alpha = ((dc_source[frac >> FRACBITS] * (unsigned int)dr_alpha) + 0x0080) >> 8; // alpha 0..255
469 if( alpha > 14 )
470 {
471 unsigned int alpha_r = 255 - alpha;
472
473 // Calculate transparency using RGBA
474 register RGBA_t p = pLocalPalette[*dest];
475 register unsigned int p12 = // 12 bit r,g,b color
476 (((((unsigned int)p.s.blue * alpha_r) + ((unsigned int)dr_color.s.blue * alpha) + 0x0080) >> (8+4-0)) & 0x000F)
477 | (((((unsigned int)p.s.green * alpha_r) + ((unsigned int)dr_color.s.green * alpha) + 0x0080) >> (8+4-4)) & 0x00F0)
478 | (((((unsigned int)p.s.red * alpha_r) + ((unsigned int)dr_color.s.red * alpha) + 0x0080) >> (8+4-8)) & 0x0F00);
479 *dest = color12_to_8[p12]; // lookup palette
480 }
481 dest += vid.ybytes;
482 frac += fracstep;
483 }
484 while (count--);
485 break;
486
487 case 1: // Alpha blend with constant background alpha.
488 // Caller must set dr_alpha_background at (255 - dr_alpha) or less.
489 alpha_r = dr_alpha_background;
490 do
491 {
492 // [WDJ] The source is a patch of alpha values, 0..255.
493 alpha = ((dc_source[frac >> FRACBITS] * (unsigned int)dr_alpha) + 0x0080) >> 8; // alpha 0..255
494 if( alpha > 14 )
495 {
496 // Calculate transparency using RGBA
497 register RGBA_t p = pLocalPalette[*dest];
498 register unsigned int p12 = // 12 bit r,g,b color
499 (((((unsigned int)p.s.blue * alpha_r) + ((unsigned int)dr_color.s.blue * alpha) + 0x0080) >> (8+4-0)) & 0x000F)
500 | (((((unsigned int)p.s.green * alpha_r) + ((unsigned int)dr_color.s.green * alpha) + 0x0080) >> (8+4-4)) & 0x00F0)
501 | (((((unsigned int)p.s.red * alpha_r) + ((unsigned int)dr_color.s.red * alpha) + 0x0080) >> (8+4-8)) & 0x0F00);
502 *dest = color12_to_8[p12]; // lookup palette
503 }
504 dest += vid.ybytes;
505 frac += fracstep;
506 }
507 while (count--);
508 break;
509
510 case 2: // Additive alpha
511 do
512 {
513 // [WDJ] The source is a patch of alpha values, 0..255.
514 alpha = ((dc_source[frac >> FRACBITS] * (unsigned int)dr_alpha) + 0x0080) >> 8; // alpha 0..255
515 if( alpha > 14 )
516 {
517 // Calculate transparency using RGBA
518 register RGBA_t p = pLocalPalette[*dest];
519 unsigned int r,g,b;
520 // (0xFF * 0xFF * 0xFF) = 0xFD02FF
521 b = p.s.blue;
522 b += ((((unsigned int)dr_color.s.blue * alpha * (255 - b)) + 0x8000) >> 16);
523 g = p.s.green;
524 g += ((((unsigned int)dr_color.s.green * alpha * (255 - g)) + 0x8000) >> 16);
525 r = p.s.red;
526 r += ((((unsigned int)dr_color.s.red * alpha * (255 - r)) + 0x8000) >> 16);
527
528 register unsigned int p12 = // 12 bit r,g,b color
529 ((b & 0xF0) >> 4) | (g & 0xF0) | ((r & 0xF0) << 4);
530 *dest = color12_to_8[p12]; // lookup palette
531 }
532 dest += vid.ybytes;
533 frac += fracstep;
534 }
535 while (count--);
536 break;
537
538 case 3: // Additive alpha, with background alpha
539 alpha_r = dr_alpha_background;
540 do
541 {
542 // [WDJ] The source is a patch of alpha values, 0..255.
543 alpha = ((dc_source[frac >> FRACBITS] * (unsigned int)dr_alpha) + 0x0080) >> 8; // alpha 0..255
544 if( alpha > 14 )
545 {
546 // Calculate transparency using RGBA
547 register RGBA_t p = pLocalPalette[*dest];
548 unsigned int r,g,b;
549 // (0xFF * 0xFF * 0xFF) = 0xFD02FF
550 b = (p.s.blue * alpha_r)>>8;
551 b += ((((unsigned int)dr_color.s.blue * alpha * (255 - b)) + 0x8000) >> 16);
552 g = (p.s.green * alpha_r)>>8;
553 g += ((((unsigned int)dr_color.s.green * alpha * (255 - g)) + 0x8000) >> 16);
554 r = (p.s.red * alpha_r)>>8;
555 r += ((((unsigned int)dr_color.s.red * alpha * (255 - r)) + 0x8000) >> 16);
556
557 register unsigned int p12 = // 12 bit r,g,b color
558 ((b & 0xF0) >> 4) | (g & 0xF0) | ((r & 0xF0) << 4);
559 *dest = color12_to_8[p12]; // lookup palette
560 }
561 dest += vid.ybytes;
562 frac += fracstep;
563 }
564 while (count--);
565 break;
566
567 case 4: // Additive alpha, limit math
568 do
569 {
570 // [WDJ] The source is a patch of alpha values, 0..255.
571 alpha = (dc_source[frac >> FRACBITS] * (unsigned int)dr_alpha) >> 8;
572 if( alpha > 14 )
573 {
574 // Calculate transparency using RGBA
575 register RGBA_t p = pLocalPalette[*dest];
576 unsigned int r,g,b;
577 b = ((((unsigned int)dr_color.s.blue * alpha ) + 0x0080) >> 8) + p.s.blue;
578 if(b > 255) b = 255;
579 g = ((((unsigned int)dr_color.s.green * alpha ) + 0x0080) >> 8) + p.s.green;
580 if(g > 255) g = 255;
581 r = ((((unsigned int)dr_color.s.red * alpha ) + 0x0080) >> 8) + p.s.red;
582 if(r > 255) r = 255;
583
584 register unsigned int p12 = // 12 bit r,g,b color
585 ((b & 0xF0) >> 4) | (g & 0xF0) | ((r & 0xF0) << 4);
586 *dest = color12_to_8[p12]; // lookup palette
587 }
588 dest += vid.ybytes;
589 frac += fracstep;
590 }
591 while (count--);
592 break;
593 }
594 #else
595 // Without ENABLE_DRAW8_USING_12 there is only a coarse table lookup.
596 do
597 {
598 // Apply the dr_color, using the patch as alpha.
599 // Colormap the dr_color at the source.
600 alpha = ((dc_source[frac >> FRACBITS] * (unsigned int)dr_alpha)) >> 12; // alpha 0..16
601
602 // Select a transparent table to do alpha
603 dc_translucentmap = & translucenttables[ translucent_alpha_table[ alpha ] ];
604 // *dest = reg_colormaps[ dc_translucentmap[ (dr_color8 << dr8_src_shift[alpha]) + ((*dest) << dr8_src_shift[alpha]) ]];
605 *dest = dc_translucentmap[ (dr_color8 << dr8_src_shift[alpha]) + ((*dest) << dr8_src_shift[alpha]) ];
606
607 dest += vid.ybytes;
608 frac += fracstep;
609 }
610 while (count--);
611 #endif
612
613 }
614 #endif
615
616 //
617 // I've made an asm routine for the transparency, because it slows down
618 // a lot in 640x480 with big sprites (bfg on all screen, or transparent
619 // walls on fullscreen)
620 //
621 // [WDJ] asm does not have latest changes
622 #ifndef USEASM
R_DrawTranslucentColumn_8(void)623 void R_DrawTranslucentColumn_8(void)
624 {
625 register int count;
626 register byte *dest;
627 register fixed_t frac;
628 register fixed_t fracstep;
629
630 // [WDJ] This check has been added to all the callers of colfunc().
631 // check out coords for src*
632 // if ((dc_yl < 0) || (dc_x >= vid.width))
633 // return;
634
635 #ifdef USEBOOMFUNC
636 count = dc_yh - dc_yl + 1;
637 if (count <= 0)
638 return; // Zero length, column does not exceed a pixel.
639 #else
640 count = dc_yh - dc_yl;
641 if (count < 0)
642 return; // Zero length, column does not exceed a pixel.
643 #endif
644
645 #ifdef RANGECHECK_DRAW_LIMITS
646 // [WDJ] Draw window is actually rdraw_viewwidth and rdraw_viewheight
647 if ((unsigned) dc_x >= rdraw_viewwidth || dc_yl < 0 || dc_yh >= rdraw_viewheight)
648 {
649 I_SoftError("R_DrawTranslucentColumn: %i to %i at %i\n", dc_yl, dc_yh, dc_x);
650 return;
651 }
652 #endif
653 // FIXME. As above.
654 //src = ylookup[dc_yl] + columnofs[dc_x+2];
655
656 // Framebuffer destination address.
657 // Use ylookup LUT to avoid multiply with ScreenWidth.
658 // Use columnofs LUT for subwindows?
659 dest = ylookup[dc_yl] + columnofs[dc_x];
660
661 // Determine scaling, which is the only mapping to be done.
662 fracstep = dc_iscale;
663 frac = dc_texturemid + (dc_yl - centery) * fracstep;
664
665 #ifdef USEBOOMFUNC
666 // Do two pixels per loop when possible.
667 {
668 register const byte *source = dc_source;
669 register int heightmask = dc_texheight - 1;
670 if (dc_texheight & heightmask)
671 {
672 heightmask++;
673 heightmask <<= FRACBITS;
674
675 if (frac < 0)
676 while ((frac += heightmask) < 0);
677 else
678 while (frac >= heightmask)
679 frac -= heightmask;
680
681 if( dr_alpha < TRANSLU_REV_ALPHA )
682 {
683 do
684 {
685 // Re-map color indices from wall texture column
686 // using a lighting/special effects LUT.
687 // heightmask is the Tutti-Frutti fix -- killough
688
689 *dest = dc_colormap[ dc_translucentmap[ (source[frac >> FRACBITS] << 8) + (*dest) ]];
690 dest += vid.ybytes;
691 if ((frac += fracstep) >= heightmask)
692 frac -= heightmask;
693 }
694 while (--count);
695 }
696 else
697 {
698 do
699 {
700 // alpha >= TRANSLU_REV_ALPHA, reversed translucent table usage
701 *dest = dc_colormap[ dc_translucentmap[ (source[frac >> FRACBITS]) + ((*dest)<<8) ]];
702 dest += vid.ybytes;
703 if ((frac += fracstep) >= heightmask)
704 frac -= heightmask;
705 }
706 while (--count);
707 }
708 }
709 else
710 {
711 if( dr_alpha < TRANSLU_REV_ALPHA )
712 {
713 while ((count -= 2) >= 0) // texture height is a power of 2 -- killough
714 {
715 *dest = dc_colormap[ dc_translucentmap[ (source[frac >> FRACBITS] << 8) + (*dest) ]];
716 dest += vid.ybytes;
717 frac += fracstep;
718 *dest = dc_colormap[ dc_translucentmap[ (source[frac >> FRACBITS] << 8) + (*dest) ]];
719 dest += vid.ybytes;
720 frac += fracstep;
721 }
722 if (count & 1)
723 *dest = dc_colormap[ dc_translucentmap[ (source[frac >> FRACBITS] << 8) + (*dest) ]];
724 }
725 else
726 {
727 while ((count -= 2) >= 0) // texture height is a power of 2 -- killough
728 {
729 // alpha >= TRANSLU_REV_ALPHA, reversed translucent table usage
730 *dest = dc_colormap[ dc_translucentmap[ (source[frac >> FRACBITS]) + ((*dest)<<8) ]];
731 dest += vid.ybytes;
732 frac += fracstep;
733 *dest = dc_colormap[ dc_translucentmap[ (source[frac >> FRACBITS]) + ((*dest)<<8) ]];
734 dest += vid.ybytes;
735 frac += fracstep;
736 }
737 if (count & 1)
738 *dest = dc_colormap[ dc_translucentmap[ (source[frac >> FRACBITS]) + ((*dest)<<8) ]];
739 }
740 }
741 }
742 #else
743 // Simple loops. No Tile.
744 if( dr_alpha < TRANSLU_REV_ALPHA )
745 {
746 // Here we do an additional index re-mapping.
747 do
748 {
749 *dest = dc_colormap[ dc_translucentmap[ (dc_source[frac >> FRACBITS] << 8) + (*dest) ]];
750 dest += vid.ybytes;
751 frac += fracstep;
752 }
753 while (count--);
754 }
755 else
756 {
757 do
758 {
759 // alpha >= TRANSLU_REV_ALPHA, reversed translucent table usage
760 *dest = dc_colormap[ dc_translucentmap[ (dc_source[frac >> FRACBITS]) + ((*dest) << 8) ]];
761 dest += vid.ybytes;
762 frac += fracstep;
763 }
764 while (count--);
765 }
766 #endif
767 }
768 #endif
769
770 // New spiffy function.
771 // Not only does it colormap a sprite,
772 // but does translucency as well.
773 // SSNTails 11-11-2002
774 // Uber-kudos to Cyan Helkaraxe for
775 // helping me get the brain juices flowing!
776 // Called with TRANSLU_hi or TRANSLU_more, or arbitrary by thing TRANSMASK
R_DrawTranslatedTranslucentColumn_8(void)777 void R_DrawTranslatedTranslucentColumn_8(void)
778 {
779 register int count;
780 register fixed_t frac;
781 register fixed_t fracstep;
782 register byte *dest;
783
784 count = dc_yh - dc_yl + 1;
785
786 if (count <= 0) // Zero length, column does not exceed a pixel.
787 return;
788
789 // FIXME. As above.
790 //src = ylookup[dc_yl] + columnofs[dc_x+2];
791 dest = ylookup[dc_yl] + columnofs[dc_x];
792
793 // Looks familiar.
794 fracstep = dc_iscale;
795 frac = dc_texturemid + (dc_yl - centery) * fracstep;
796
797 // Inner loop that does the actual texture mapping,
798 // e.g. a DDA-lile scaling.
799 // This is as fast as it gets.
800
801 {
802 //register const byte *source = dc_source;
803 register int heightmask = dc_texheight - 1;
804 if (dc_texheight & heightmask)
805 {
806 heightmask++;
807 heightmask <<= FRACBITS;
808
809 if (frac < 0)
810 while ((frac += heightmask) < 0);
811 else
812 {
813 while (frac >= heightmask)
814 frac -= heightmask;
815 }
816
817 if( dr_alpha < TRANSLU_REV_ALPHA )
818 {
819 do
820 {
821 // Re-map color indices from wall texture column
822 // using a lighting/special effects LUT.
823 // heightmask is the Tutti-Frutti fix -- killough
824 *dest = dc_colormap[ dc_translucentmap[ (dc_colormap[dc_skintran[dc_source[frac >> FRACBITS]]] << 8) + (*dest) ]];
825 dest += vid.ybytes;
826 if ((frac += fracstep) >= heightmask)
827 frac -= heightmask;
828 }
829 while (--count);
830 }
831 else
832 {
833 do
834 {
835 // alpha >= TRANSLU_REV_ALPHA, reversed translucent table usage
836 *dest = dc_colormap[ dc_translucentmap[ (dc_colormap[dc_skintran[dc_source[frac >> FRACBITS]]]) + ((*dest)<<8) ]];
837 dest += vid.ybytes;
838 if ((frac += fracstep) >= heightmask)
839 frac -= heightmask;
840 }
841 while (--count);
842 }
843 }
844 else
845 {
846 if( dr_alpha < TRANSLU_REV_ALPHA )
847 {
848 while ((count -= 2) >= 0) // texture height is a power of 2 -- killough
849 {
850 *dest = dc_colormap[ dc_translucentmap[ (dc_colormap[dc_skintran[dc_source[frac >> FRACBITS]]] << 8) + (*dest) ]];
851 dest += vid.ybytes;
852 frac += fracstep;
853 *dest = dc_colormap[ dc_translucentmap[ (dc_colormap[dc_skintran[dc_source[frac >> FRACBITS]]] << 8) + (*dest) ]];
854 dest += vid.ybytes;
855 frac += fracstep;
856 }
857 if (count & 1)
858 {
859 *dest = dc_colormap[ dc_translucentmap[ (dc_colormap[dc_skintran[dc_source[frac >> FRACBITS]]] << 8) + (*dest) ]];
860 }
861 }
862 else
863 {
864 while ((count -= 2) >= 0) // texture height is a power of 2 -- killough
865 {
866 // alpha >= TRANSLU_REV_ALPHA, reversed translucent table usage
867 *dest = dc_colormap[ dc_translucentmap[ (dc_colormap[dc_skintran[dc_source[frac >> FRACBITS]]]) + ((*dest)<<8) ]];
868 dest += vid.ybytes;
869 frac += fracstep;
870 *dest = dc_colormap[ dc_translucentmap[ (dc_colormap[dc_skintran[dc_source[frac >> FRACBITS]]]) + ((*dest)<<8) ]];
871 dest += vid.ybytes;
872 frac += fracstep;
873 }
874 if (count & 1)
875 {
876 *dest = dc_colormap[ dc_translucentmap[ (dc_colormap[dc_skintran[dc_source[frac >> FRACBITS]]]) + ((*dest)<<8) ]];
877 }
878 }
879 }
880 }
881 }
882
883 //
884 // Draw columns upto 128high but remap the green ramp to other colors
885 //
886 //#ifndef USEASM // STILL NOT IN ASM, TO DO..
R_DrawTranslatedColumn_8(void)887 void R_DrawTranslatedColumn_8(void)
888 {
889 register int count;
890 register byte *dest;
891 register fixed_t frac;
892 register fixed_t fracstep;
893
894 count = dc_yh - dc_yl;
895 if (count < 0)
896 return;
897
898 #ifdef RANGECHECK_DRAW_LIMITS
899 // [WDJ] Draw window is actually rdraw_viewwidth and rdraw_viewheight
900 if ((unsigned) dc_x >= rdraw_viewwidth || dc_yl < 0 || dc_yh >= rdraw_viewheight)
901 {
902 I_SoftError("R_DrawTranslatedColumn: %i to %i at %i\n", dc_yl, dc_yh, dc_x);
903 return;
904 }
905 #endif
906
907 // FIXME. As above.
908 dest = ylookup[dc_yl] + columnofs[dc_x];
909
910 // Looks familiar.
911 fracstep = dc_iscale;
912 frac = dc_texturemid + (dc_yl - centery) * fracstep;
913
914 // Here we do an additional index re-mapping.
915 do
916 {
917 // Skin Translation tables are used
918 // to map certain colorramps to other ones,
919 // used with PLAYER sprites.
920 // Thus the "green" ramp of the player 0 sprite
921 // is mapped to gray, red, black/indigo.
922 *dest = dc_colormap[dc_skintran[dc_source[frac >> FRACBITS]]];
923
924 dest += vid.ybytes;
925
926 frac += fracstep;
927 }
928 while (count--);
929 }
930
931 //#endif
932
933 // ==========================================================================
934 // SPANS
935 // ==========================================================================
936
937 // Draws the actual span.
938 //
939 //#ifndef USEASM //Hurdler: in tmap.nas the old func is now called R_DrawSpan_8a
940 // [WDJ] Boom func modified several times
R_DrawSpan_8(void)941 void R_DrawSpan_8(void)
942 {
943 // [WDJ] was ULONG=32bit, use uint_fast32_t which can exceed 32bit in size.
944 register uint_fast32_t xfrac;
945 register uint_fast32_t yfrac;
946 register byte *dest;
947 register int count;
948
949 #ifdef RANGECHECK_DRAW_LIMITS
950 if (ds_x2 < ds_x1 || ds_x1 < 0 || ds_x2 >= rdraw_viewwidth || (unsigned) ds_y > rdraw_viewheight)
951 {
952 I_SoftError("R_DrawSpan: %i to %i at %i\n", ds_x1, ds_x2, ds_y);
953 return;
954 }
955 #endif
956
957 xfrac = ds_xfrac & flat_imask;
958 yfrac = ds_yfrac;
959
960 dest = ylookup[ds_y] + columnofs[ds_x1];
961
962 // We do not check for zero spans here?
963 count = ds_x2 - ds_x1;
964
965 // [WDJ] note: prboom has while(count)
966 do
967 {
968 // Lookup pixel from flat texture tile,
969 // re-index using light/colormap.
970 *dest = ds_colormap[ds_source[((yfrac >> flatfracbits) & (flat_ymask)) | (xfrac >> FRACBITS)]];
971 dest++;
972
973 // Next step in u,v.
974 xfrac += ds_xstep;
975 yfrac += ds_ystep;
976 xfrac &= flat_imask;
977 }
978 while (count--);
979 }
980 //#endif USESASM
981
R_DrawTranslucentSpan_8(void)982 void R_DrawTranslucentSpan_8(void)
983 {
984 fixed_t xfrac, yfrac;
985 fixed_t xstep, ystep;
986 byte *dest;
987 int count;
988
989 #ifdef RANGECHECK_DRAW_LIMITS
990 if (ds_x2 < ds_x1 || ds_x1 < 0 || ds_x2 >= rdraw_viewwidth || (unsigned) ds_y > rdraw_viewheight)
991 {
992 I_SoftError("R_DrawTranslucentSpan: %i to %i at %i\n", ds_x1, ds_x2, ds_y);
993 return;
994 }
995 #endif
996
997 xfrac = ds_xfrac & flat_imask;
998 yfrac = ds_yfrac;
999
1000 dest = ylookup[ds_y] + columnofs[ds_x1];
1001
1002 // We do not check for zero spans here?
1003 count = ds_x2 - ds_x1 + 1;
1004
1005 xstep = ds_xstep;
1006 ystep = ds_ystep;
1007
1008 if( dr_alpha < TRANSLU_REV_ALPHA )
1009 {
1010 do
1011 {
1012 // Current texture index in u,v.
1013
1014 // Awesome! 256x256 flats!
1015 // spot = ((yfrac>>(FRACBITS-8))&(0xff00)) + (xfrac>>(FRACBITS));
1016
1017 // Lookup pixel from flat texture tile,
1018 // re-index using light/colormap.
1019 // *dest++ = ds_colormap[ds_source[spot]];
1020 // *dest++ = ds_colormap[*(ds_translucentmap + (ds_source[spot] << 8) + (*dest))];
1021 *dest = ds_colormap[ ds_translucentmap[ (ds_source[((yfrac >> flatfracbits) & (flat_ymask)) | (xfrac >> FRACBITS)] << 8) + (*dest) ]];
1022 dest++; // [WDJ] warning: undetermined order when combined with above
1023
1024 // Next step in u,v.
1025 xfrac += xstep;
1026 yfrac += ystep;
1027 xfrac &= flat_imask;
1028 }
1029 while (--count);
1030 }
1031 else
1032 {
1033 do
1034 {
1035 // alpha >= TRANSLU_REV_ALPHA, reversed translucent table usage
1036 *dest = ds_colormap[ ds_translucentmap[ (ds_source[((yfrac >> flatfracbits) & (flat_ymask)) | (xfrac >> FRACBITS)]) + ((*dest)<<8) ]];
1037 dest++; // [WDJ] warning: undetermined order when combined with above
1038 // Next step in u,v.
1039 xfrac += xstep;
1040 yfrac += ystep;
1041 xfrac &= flat_imask;
1042 }
1043 while (--count);
1044 }
1045 /*
1046 register unsigned position;
1047 unsigned step;
1048
1049 byte *source;
1050 byte *colormap;
1051 byte *transmap;
1052 byte *dest;
1053
1054 unsigned count;
1055 unsigned spot;
1056 unsigned xtemp;
1057 unsigned ytemp;
1058
1059 position = ((ds_xfrac<<10)&0xffff0000) | ((ds_yfrac>>6)&0xffff);
1060 step = ((ds_xstep<<10)&0xffff0000) | ((ds_ystep>>6)&0xffff);
1061
1062 source = ds_source;
1063 colormap = ds_colormap;
1064 transmap = ds_translucentmap;
1065 dest = ylookup[ds_y] + columnofs[ds_x1];
1066 count = ds_x2 - ds_x1 + 1;
1067
1068 while (count >= 4)
1069 {
1070 ytemp = position>>4;
1071 ytemp = ytemp & 0xff00;
1072 xtemp = position>>26;
1073 spot = xtemp | ytemp;
1074 position += step;
1075 dest[0] = colormap[*(transmap + (source[spot] << 8) + (dest[0]))];
1076
1077 ytemp = position>>4;
1078 ytemp = ytemp & 0xff00;
1079 xtemp = position>>26;
1080 spot = xtemp | ytemp;
1081 position += step;
1082 dest[1] = colormap[*(transmap + (source[spot] << 8) + (dest[1]))];
1083
1084 ytemp = position>>4;
1085 ytemp = ytemp & 0xff00;
1086 xtemp = position>>26;
1087 spot = xtemp | ytemp;
1088 position += step;
1089 dest[2] = colormap[*(transmap + (source[spot] << 8) + (dest[2]))];
1090
1091 ytemp = position>>4;
1092 ytemp = ytemp & 0xff00;
1093 xtemp = position>>26;
1094 spot = xtemp | ytemp;
1095 position += step;
1096 dest[3] = colormap[*(transmap + (source[spot] << 8) + (dest[3]))];
1097
1098 dest += 4;
1099 count -= 4;
1100 }
1101
1102 while (count--)
1103 {
1104 ytemp = position>>4;
1105 ytemp = ytemp & 0xff00;
1106 xtemp = position>>26;
1107 spot = xtemp | ytemp;
1108 position += step;
1109 *dest++ = colormap[*(transmap + (source[spot] << 8) + (*dest))];
1110 //count--;
1111 }
1112 */
1113 }
1114
1115 // blend of four translucents to imitate alpha translucent
1116 static byte fog_tran_table[16][4] = {
1117 { TRANSLU_hi, TRANSLU_hi, TRANSLU_hi, TRANSLU_hi }, // 10%
1118 { TRANSLU_hi, TRANSLU_hi, TRANSLU_hi, TRANSLU_hi }, // 10%
1119 { TRANSLU_more, TRANSLU_hi, TRANSLU_hi, TRANSLU_hi }, // 12.5%
1120 { TRANSLU_more, TRANSLU_hi, TRANSLU_more, TRANSLU_hi }, // 15%
1121 { TRANSLU_more, TRANSLU_more, TRANSLU_more, TRANSLU_hi }, // 17.5%
1122 { TRANSLU_more, TRANSLU_more, TRANSLU_more, TRANSLU_more }, // 20%
1123 // { TRANSLU_med, TRANSLU_hi, TRANSLU_hi, TRANSLU_hi }, // 20%
1124 { TRANSLU_med, TRANSLU_hi, TRANSLU_more, TRANSLU_hi }, // 22.5%
1125 { TRANSLU_med, TRANSLU_hi, TRANSLU_more, TRANSLU_hi }, // 22.5%
1126 { TRANSLU_med, TRANSLU_hi, TRANSLU_med, TRANSLU_hi }, // 30%
1127 { TRANSLU_med, TRANSLU_more, TRANSLU_med, TRANSLU_hi }, // 32.5%
1128 { TRANSLU_med, TRANSLU_more, TRANSLU_med, TRANSLU_more }, // 35%
1129 { TRANSLU_med, TRANSLU_more, TRANSLU_med, TRANSLU_more }, // 35%
1130 { TRANSLU_med, TRANSLU_med, TRANSLU_med, TRANSLU_hi }, // 40%
1131 { TRANSLU_med, TRANSLU_med, TRANSLU_med, TRANSLU_more }, // 42.5%
1132 { TRANSLU_med, TRANSLU_med, TRANSLU_med, TRANSLU_more }, // 42.5%
1133 { TRANSLU_med, TRANSLU_med, TRANSLU_med, TRANSLU_med }, // 50%
1134 };
1135
1136 static byte fogstir = 0;
1137
R_DrawFogSpan_8(void)1138 void R_DrawFogSpan_8(void)
1139 {
1140 uint16_t fogcolor = ds_colormap[ ds_source[fog_index] ]; // to allow shift by 8
1141 byte alpha16;
1142 int count, count4;
1143 byte * ftranslucent[4];
1144 byte *dest;
1145
1146 alpha16 = dr_alpha >> 3; // dr_alpha 0..255 => 0..31
1147 if( alpha16 > 15 )
1148 {
1149 if( alpha16 > 31 ) alpha16 = 31;
1150 alpha16 = 31 - alpha16; // high alpha reverse trans
1151 }
1152 fogstir ++;
1153 for( count = 0; count < 4; count++ )
1154 {
1155 byte fogtran = fog_tran_table[ alpha16 ][ (count+fogstir) & 0x03 ];
1156 dc_translucentmap = & translucenttables[ TRANSLU_TABLE_INDEX(fogtran) ];
1157 ftranslucent[count] = // normal table, or rev table
1158 & dc_translucentmap[ (dr_alpha<128) ? (fogcolor<<8) : fogcolor ];
1159 }
1160
1161 count = ds_x2 - ds_x1 + 1;
1162 dest = ylookup[ds_y] + columnofs[ds_x1];
1163
1164 count4 = count>>2;
1165 count -= count4<<2;
1166 if( dr_alpha < 128 )
1167 {
1168 // low alpha, use four translucent tables
1169 while (count4--)
1170 {
1171 *dest = ds_colormap[ ftranslucent[3][ (*dest) ]];
1172 dest ++;
1173 *dest = ds_colormap[ ftranslucent[2][ (*dest) ]];
1174 dest ++;
1175 *dest = ds_colormap[ ftranslucent[1][ (*dest) ]];
1176 dest ++;
1177 *dest = ds_colormap[ ftranslucent[0][ (*dest) ]];
1178 dest ++;
1179 }
1180 while( count-- )
1181 {
1182 *dest = ds_colormap[ ftranslucent[count&0x03][ (*dest) ]];
1183 dest ++;
1184 }
1185 }
1186 else
1187 {
1188 // high alpha, reversed use of four translucent tables
1189 while (count4--)
1190 {
1191 *dest = ds_colormap[ ftranslucent[3][ (*dest) << 8 ]];
1192 dest ++;
1193 *dest = ds_colormap[ ftranslucent[2][ (*dest) << 8 ]];
1194 dest ++;
1195 *dest = ds_colormap[ ftranslucent[1][ (*dest) << 8 ]];
1196 dest ++;
1197 *dest = ds_colormap[ ftranslucent[0][ (*dest) << 8 ]];
1198 dest ++;
1199 }
1200 while( count-- )
1201 {
1202 *dest = ds_colormap[ ftranslucent[count&0x03][ (*dest) << 8 ]];
1203 dest ++;
1204 }
1205 }
1206 }
1207
1208
1209 //SoM: Fog wall.
R_DrawFogColumn_8(void)1210 void R_DrawFogColumn_8(void)
1211 {
1212 // fogcolor blur needs to be kept as 8 bit or else the blur is inadequate
1213 static byte fogcolor_c;
1214 int count, count4, fi;
1215 byte * ftranslucent[4];
1216 byte fc, fc2;
1217 byte alpha16;
1218 uint16_t fogcolor; // to allow shift by 8
1219
1220 fogstir ++;
1221 // fog_index 0.. column height
1222 // always average two pixels of source texture
1223 fi = fog_index + 3;
1224 fc = dc_colormap[ dc_source[fog_index] ];
1225 if( fi >= fog_col_length ) fi -= fog_col_length;
1226 fc2 = dc_colormap[ dc_source[fi] ];
1227 fc = translucenttables[ TRANSLU_TABLE_med + (fc2 << 8) + fc ];
1228 if( fog_init )
1229 {
1230 // init blur
1231 fogcolor_c = fc;
1232 fog_init = 0;
1233 }
1234 else
1235 {
1236 // blur
1237 fogcolor_c = translucenttables[ TRANSLU_TABLE_more + (fc << 8) + fogcolor_c ];
1238 }
1239 fogcolor = dc_colormap[ fogcolor_c ];
1240
1241 alpha16 = dr_alpha >> 3; // dr_alpha 0..255 => 0..31
1242 if( alpha16 > 15 )
1243 {
1244 if( alpha16 > 31 ) alpha16 = 31;
1245 alpha16 = 31 - alpha16; // high alpha reverse trans
1246 }
1247 for( count = 0; count < 4; count++ )
1248 {
1249 byte fogtran = fog_tran_table[ alpha16 ][ (count+fogstir) & 0x03 ];
1250 dc_translucentmap = & translucenttables[ TRANSLU_TABLE_INDEX(fogtran) ];
1251 if( dr_alpha < 128 )
1252 ftranslucent[count] = & dc_translucentmap[ fogcolor << 8 ];
1253 else
1254 ftranslucent[count] = & dc_translucentmap[ fogcolor ]; // rev table
1255 }
1256
1257 count = dc_yh - dc_yl + 1;
1258
1259 // Zero length, column does not exceed a pixel.
1260 if (count < 0)
1261 return;
1262
1263 #ifdef RANGECHECK_DRAW_LIMITS
1264 // [WDJ] Draw window is actually rdraw_viewwidth and rdraw_viewheight
1265 if ((unsigned) dc_x >= rdraw_viewwidth || dc_yl < 0 || dc_yh >= rdraw_viewheight)
1266 {
1267 I_SoftError("R_DrawFogColumn: %i to %i at %i\n", dc_yl, dc_yh, dc_x);
1268 return;
1269 }
1270 #endif
1271
1272 // Framebuffer destination address.
1273 // Use ylookup LUT to avoid multiply with ScreenWidth.
1274 // Use columnofs LUT for subwindows?
1275 byte * dest = ylookup[dc_yl] + columnofs[dc_x];
1276
1277 count4 = count>>2;
1278 count -= count4<<2;
1279 if( dr_alpha < 128 )
1280 {
1281 // low alpha, use four translucent tables
1282 while (count4--)
1283 {
1284 *dest = dc_colormap[ ftranslucent[3][ (*dest) ]];
1285 dest += vid.ybytes;
1286 *dest = dc_colormap[ ftranslucent[2][ (*dest) ]];
1287 dest += vid.ybytes;
1288 *dest = dc_colormap[ ftranslucent[1][ (*dest) ]];
1289 dest += vid.ybytes;
1290 *dest = dc_colormap[ ftranslucent[0][ (*dest) ]];
1291 dest += vid.ybytes;
1292 }
1293 while( count-- )
1294 {
1295 *dest = dc_colormap[ ftranslucent[count&0x03][ (*dest) ]];
1296 dest += vid.ybytes;
1297 }
1298 }
1299 else
1300 {
1301 // high alpha, reversed use of four translucent tables
1302 while (count4--)
1303 {
1304 *dest = dc_colormap[ ftranslucent[3][ (*dest) << 8 ]];
1305 dest += vid.ybytes;
1306 *dest = dc_colormap[ ftranslucent[2][ (*dest) << 8 ]];
1307 dest += vid.ybytes;
1308 *dest = dc_colormap[ ftranslucent[1][ (*dest) << 8 ]];
1309 dest += vid.ybytes;
1310 *dest = dc_colormap[ ftranslucent[0][ (*dest) << 8 ]];
1311 dest += vid.ybytes;
1312 }
1313 while( count-- )
1314 {
1315 *dest = dc_colormap[ ftranslucent[count&0x03][ (*dest) << 8 ]];
1316 dest += vid.ybytes;
1317 }
1318 }
1319 }
1320
1321 #if 0
1322 // [WDJ] Replaced by generic R_DrawColumnShadowed
1323 // SoM: This is for 3D floors that cast shadows on walls.
1324 // This function just cuts the column up into sections and calls
1325 // R_DrawColumn_8
1326 void R_DrawColumnShadowed_8(void)
1327 {
1328 int count;
1329 int realyh, realyl;
1330 int i;
1331 int height, bheight = 0;
1332 int solid = 0;
1333
1334 realyh = dc_yh;
1335 realyl = dc_yl;
1336
1337 count = dc_yh - dc_yl;
1338
1339 // Zero length, column does not exceed a pixel.
1340 if (count < 0)
1341 return;
1342
1343 #ifdef RANGECHECK_DRAW_LIMITS
1344 // [WDJ] Draw window is actually rdraw_viewwidth and rdraw_viewheight
1345 if ((unsigned) dc_x >= rdraw_viewwidth || dc_yl < 0 || dc_yh >= rdraw_viewheight)
1346 {
1347 I_SoftError("R_DrawShadowedColumn: %i to %i at %i\n", dc_yl, dc_yh, dc_x);
1348 return;
1349 }
1350 #endif
1351
1352 // SoM: This runs through the lightlist from top to bottom and cuts up
1353 // the column accordingly.
1354 for (i = 0; i < dc_numlights; i++)
1355 {
1356 // If the height of the light is above the column, get the colormap
1357 // anyway because the lighting of the top should be effected.
1358 solid = dc_lightlist[i].flags & FF_CUTSOLIDS;
1359
1360 height = dc_lightlist[i].height >> 12;
1361 if (solid)
1362 bheight = dc_lightlist[i].botheight >> 12;
1363 if (height <= dc_yl)
1364 {
1365 dc_colormap = dc_lightlist[i].rcolormap;
1366 if (solid && dc_yl < bheight)
1367 dc_yl = bheight;
1368 continue;
1369 }
1370 // Found a break in the column!
1371 dc_yh = height;
1372
1373 if (dc_yh > realyh)
1374 dc_yh = realyh;
1375 R_DrawColumn_8();
1376 if (solid)
1377 dc_yl = bheight;
1378 else
1379 dc_yl = dc_yh + 1;
1380
1381 dc_colormap = dc_lightlist[i].rcolormap;
1382 }
1383 dc_yh = realyh;
1384 if (dc_yl <= realyh)
1385 R_DrawColumn_8();
1386 }
1387 #endif
1388