FS#8961 - Anti-Aliased Fonts.
[kugel-rb/myfork.git] / apps / plugins / doom / r_segs.c
blobf3bd81e9218e4f4f086ceb25a7ead55c0c363ed8
1 /* Emacs style mode select -*- C++ -*-
2 *-----------------------------------------------------------------------------
5 * PrBoom a Doom port merged with LxDoom and LSDLDoom
6 * based on BOOM, a modified and improved DOOM engine
7 * Copyright (C) 1999 by
8 * id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
9 * Copyright (C) 1999-2000 by
10 * Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
25 * 02111-1307, USA.
27 * DESCRIPTION:
28 * All the clipping: columns, horizontal spans, sky columns.
30 *-----------------------------------------------------------------------------*/
32 // 4/25/98, 5/2/98 killough: reformatted, beautified
34 #include "doomstat.h"
35 #include "r_main.h"
36 #include "r_bsp.h"
37 #include "r_plane.h"
38 #include "r_things.h"
39 #include "r_draw.h"
40 #include "w_wad.h"
41 //#include "lprintf.h"
42 #include "rockmacros.h"
44 // OPTIMIZE: closed two sided lines as single sided
46 // killough 1/6/98: replaced globals with statics where appropriate
48 // True if any of the segs textures might be visible.
49 boolean segtextured;
50 boolean markfloor; // False if the back side is the same plane.
51 boolean markceiling;
52 static boolean maskedtexture;
53 static int toptexture;
54 static int bottomtexture;
55 static int midtexture;
57 static fixed_t toptexheight, midtexheight, bottomtexheight; // cph
59 angle_t rw_normalangle;// angle to line origin
60 int rw_angle1;
61 fixed_t rw_distance;
62 lighttable_t** walllights;
65 // regular wall
67 int rw_x;
68 int rw_stopx;
69 static angle_t rw_centerangle;
70 static fixed_t rw_offset;
71 static fixed_t rw_scale;
72 static fixed_t rw_scalestep;
73 static fixed_t rw_midtexturemid;
74 static fixed_t rw_toptexturemid;
75 static fixed_t rw_bottomtexturemid;
76 static int worldtop;
77 static int worldbottom;
78 static int worldhigh;
79 static int worldlow;
80 static fixed_t pixhigh;
81 static fixed_t pixlow;
82 static fixed_t pixhighstep;
83 static fixed_t pixlowstep;
84 static fixed_t topfrac;
85 static fixed_t topstep;
86 static fixed_t bottomfrac;
87 static fixed_t bottomstep;
88 static short *maskedtexturecol;
91 // R_ScaleFromGlobalAngle
92 // Returns the texture mapping scale
93 // for the current line (horizontal span)
94 // at the given angle.
95 // rw_distance must be calculated first.
97 // killough 5/2/98: reformatted, cleaned up
98 // CPhipps - moved here from r_main.c
100 static fixed_t R_ScaleFromGlobalAngle(angle_t visangle)
102 int anglea = ANG90 + (visangle-viewangle);
103 int angleb = ANG90 + (visangle-rw_normalangle);
104 int den = FixedMul(rw_distance, finesine[anglea>>ANGLETOFINESHIFT]);
105 // proff 11/06/98: Changed for high-res
106 fixed_t num = FixedMul(projectiony, finesine[angleb>>ANGLETOFINESHIFT]);
107 return den > num>>16 ? (num = FixedDiv(num, den)) > 64*FRACUNIT ?
108 64*FRACUNIT : num < 256 ? 256 : num : 64*FRACUNIT;
112 // R_RenderMaskedSegRange
115 int fake_contrast IBSS_ATTR;
117 void R_RenderMaskedSegRange(drawseg_t *ds, int x1, int x2)
119 column_t *col;
120 int lightnum;
121 int texnum;
122 sector_t tempsec; // killough 4/13/98
124 // Calculate light table.
125 // Use different light tables
126 // for horizontal / vertical / diagonal. Diagonal?
128 curline = ds->curline; // OPTIMIZE: get rid of LIGHTSEGSHIFT globally
130 // killough 4/11/98: draw translucent 2s normal textures
132 colfunc = R_DrawColumn;
133 if (curline->linedef->tranlump >= 0 && general_translucency)
135 colfunc = R_DrawTLColumn;
136 tranmap = main_tranmap;
137 if (curline->linedef->tranlump > 0)
138 tranmap = W_CacheLumpNum(curline->linedef->tranlump-1);
141 // killough 4/11/98: end translucent 2s normal code
143 frontsector = curline->frontsector;
144 backsector = curline->backsector;
146 texnum = texturetranslation[curline->sidedef->midtexture];
148 // killough 4/13/98: get correct lightlevel for 2s normal textures
149 lightnum = (R_FakeFlat(frontsector, &tempsec, NULL, NULL, false)
150 ->lightlevel >> LIGHTSEGSHIFT)+extralight;
152 /* cph - ...what is this for? adding contrast to rooms?
153 * It looks crap in outdoor areas */
154 if (fake_contrast)
156 if (curline->v1->y == curline->v2->y)
157 lightnum--;
158 else
159 if (curline->v1->x == curline->v2->x)
160 lightnum++;
163 walllights = lightnum >= LIGHTLEVELS ? scalelight[LIGHTLEVELS-1] :
164 lightnum < 0 ? scalelight[0] : scalelight[lightnum];
166 maskedtexturecol = ds->maskedtexturecol;
168 rw_scalestep = ds->scalestep;
169 spryscale = ds->scale1 + (x1 - ds->x1)*rw_scalestep;
170 mfloorclip = ds->sprbottomclip;
171 mceilingclip = ds->sprtopclip;
173 // find positioning
174 if (curline->linedef->flags & ML_DONTPEGBOTTOM)
176 dc_texturemid = frontsector->floorheight > backsector->floorheight
177 ? frontsector->floorheight : backsector->floorheight;
178 dc_texturemid = dc_texturemid + textureheight[texnum] - viewz;
180 else
182 dc_texturemid =frontsector->ceilingheight<backsector->ceilingheight
183 ? frontsector->ceilingheight : backsector->ceilingheight;
184 dc_texturemid = dc_texturemid - viewz;
187 dc_texturemid += curline->sidedef->rowoffset;
189 if (fixedcolormap)
190 dc_colormap = fixedcolormap;
192 // draw the columns
193 for (dc_x = x1 ; dc_x <= x2 ; dc_x++, spryscale += rw_scalestep)
194 if (maskedtexturecol[dc_x] != SHRT_MAX)
196 if (!fixedcolormap) // calculate lighting
198 unsigned index = spryscale>>LIGHTSCALESHIFT;
200 if (index >= MAXLIGHTSCALE )
201 index = MAXLIGHTSCALE-1;
203 dc_colormap = walllights[index];
206 // killough 3/2/98:
208 // This calculation used to overflow and cause crashes in Doom:
210 // sprtopscreen = centeryfrac - FixedMul(dc_texturemid, spryscale);
212 // This code fixes it, by using double-precision intermediate
213 // arithmetic and by skipping the drawing of 2s normals whose
214 // mapping to screen coordinates is totally out of range:
217 int_64_t t = ((int_64_t) centeryfrac << FRACBITS) -
218 (int_64_t) dc_texturemid * spryscale;
219 if (t + (int_64_t) textureheight[texnum] * spryscale < 0 ||
220 t > (int_64_t) SCREENHEIGHT << FRACBITS*2)
221 continue; // skip if the texture is out of screen's range
222 sprtopscreen = (long)(t >> FRACBITS);
225 dc_iscale = 0xffffffffu / (unsigned) spryscale;
227 // killough 1/25/98: here's where Medusa came in, because
228 // it implicitly assumed that the column was all one patch.
229 // Originally, Doom did not construct complete columns for
230 // multipatched textures, so there were no header or trailer
231 // bytes in the column referred to below, which explains
232 // the Medusa effect. The fix is to construct true columns
233 // when forming multipatched textures (see r_data.c).
235 // draw the texture
236 col = (column_t *)((byte *)
237 R_GetColumn(texnum,maskedtexturecol[dc_x]) - 3);
238 R_DrawMaskedColumn (col);
239 maskedtexturecol[dc_x] = SHRT_MAX;
242 // Except for main_tranmap, mark others purgable at this point
243 if (curline->linedef->tranlump > 0 && general_translucency)
244 W_UnlockLumpNum(curline->linedef->tranlump-1); // cph - unlock it
248 // R_RenderSegLoop
249 // Draws zero, one, or two textures (and possibly a masked texture) for walls.
250 // Can draw or mark the starting pixel of floor and ceiling textures.
251 // CALLED: CORE LOOPING ROUTINE.
254 extern byte solidcol[MAX_SCREENWIDTH];
255 #define HEIGHTBITS 12
256 #define HEIGHTUNIT (1<<HEIGHTBITS)
257 static int didsolidcol; /* True if at least one column was marked solid */
259 static void R_RenderSegLoop (void)
261 fixed_t texturecolumn = 0; // shut up compiler warning
262 for ( ; rw_x < rw_stopx ; rw_x++)
265 // mark floor / ceiling areas
267 int yh = bottomfrac>>HEIGHTBITS;
268 int yl = (topfrac+HEIGHTUNIT-1)>>HEIGHTBITS;
270 // no space above wall?
271 int bottom,top = ceilingclip[rw_x]+1;
273 if (yl < top)
274 yl = top;
276 if (markceiling)
278 bottom = yl-1;
280 if (bottom >= floorclip[rw_x])
281 bottom = floorclip[rw_x]-1;
283 if (top <= bottom)
285 ceilingplane->top[rw_x] = top;
286 ceilingplane->bottom[rw_x] = bottom;
290 // yh = bottomfrac>>HEIGHTBITS;
292 bottom = floorclip[rw_x]-1;
293 if (yh > bottom)
294 yh = bottom;
296 if (markfloor)
299 top = yh < ceilingclip[rw_x] ? ceilingclip[rw_x] : yh;
301 if (++top <= bottom)
303 floorplane->top[rw_x] = top;
304 floorplane->bottom[rw_x] = bottom;
308 // texturecolumn and lighting are independent of wall tiers
309 if (segtextured)
311 unsigned index;
313 // calculate texture offset
314 angle_t angle =(rw_centerangle+xtoviewangle[rw_x])>>ANGLETOFINESHIFT;
316 texturecolumn = rw_offset-FixedMul(finetangent[angle],rw_distance);
317 texturecolumn >>= FRACBITS;
318 // calculate lighting
319 index = rw_scale>>LIGHTSCALESHIFT;
321 if (index >= MAXLIGHTSCALE )
322 index = MAXLIGHTSCALE-1;
324 dc_colormap = walllights[index];
325 dc_x = rw_x;
326 dc_iscale = 0xffffffffu / (unsigned)rw_scale;
329 // draw the wall tiers
330 if (midtexture)
333 dc_yl = yl; // single sided line
334 dc_yh = yh;
335 dc_texturemid = rw_midtexturemid;
336 dc_source = R_GetColumn(midtexture, texturecolumn);
337 dc_texheight = midtexheight;
338 colfunc ();
339 ceilingclip[rw_x] = viewheight;
340 floorclip[rw_x] = -1;
342 else
345 // two sided line
346 if (toptexture)
348 // top wall
349 int mid = pixhigh>>HEIGHTBITS;
350 pixhigh += pixhighstep;
352 if (mid >= floorclip[rw_x])
353 mid = floorclip[rw_x]-1;
355 if (mid >= yl)
357 dc_yl = yl;
358 dc_yh = mid;
359 dc_texturemid = rw_toptexturemid;
360 dc_source = R_GetColumn(toptexture,texturecolumn);
361 dc_texheight = toptexheight;
362 colfunc ();
363 ceilingclip[rw_x] = mid;
365 else
366 ceilingclip[rw_x] = yl-1;
368 else // no top wall
371 if (markceiling)
372 ceilingclip[rw_x] = yl-1;
375 if (bottomtexture) // bottom wall
377 int mid = (pixlow+HEIGHTUNIT-1)>>HEIGHTBITS;
378 pixlow += pixlowstep;
380 // no space above wall?
381 if (mid <= ceilingclip[rw_x])
382 mid = ceilingclip[rw_x]+1;
384 if (mid <= yh)
386 dc_yl = mid;
387 dc_yh = yh;
388 dc_texturemid = rw_bottomtexturemid;
389 dc_source = R_GetColumn(bottomtexture,
390 texturecolumn);
391 dc_texheight = bottomtexheight;
392 colfunc ();
393 floorclip[rw_x] = mid;
395 else
396 floorclip[rw_x] = yh+1;
398 else // no bottom wall
400 if (markfloor)
401 floorclip[rw_x] = yh+1;
404 // cph - if we completely blocked further sight through this column,
405 // add this info to the solid columns array for r_bsp.c
406 if ((markceiling || markfloor) &&
407 (floorclip[rw_x] <= ceilingclip[rw_x] + 1))
409 solidcol[rw_x] = 1;
410 didsolidcol = 1;
413 // save texturecol for backdrawing of masked mid texture
414 if (maskedtexture)
415 maskedtexturecol[rw_x] = texturecolumn;
418 rw_scale += rw_scalestep;
419 topfrac += topstep;
420 bottomfrac += bottomstep;
424 // killough 5/2/98: move from r_main.c, made static, simplified
426 static fixed_t R_PointToDist(fixed_t x, fixed_t y)
428 fixed_t dx = D_abs(x - viewx);
429 fixed_t dy = D_abs(y - viewy);
431 if (dy > dx)
433 fixed_t t = dx;
434 dx = dy;
435 dy = t;
438 return FixedDiv(dx, finesine[(tantoangle[FixedDiv(dy,dx) >> DBITS]
439 + ANG90) >> ANGLETOFINESHIFT]);
443 // R_StoreWallRange
444 // A wall segment will be drawn
445 // between start and stop pixels (inclusive).
447 void R_StoreWallRange(const int start, const int stop)
449 fixed_t hyp;
450 fixed_t sineval;
451 angle_t distangle, offsetangle;
453 if (ds_p == drawsegs+maxdrawsegs) // killough 1/98 -- fix 2s line HOM
455 unsigned pos = ds_p - drawsegs; // jff 8/9/98 fix from ZDOOM1.14a
456 unsigned newmax = maxdrawsegs ? maxdrawsegs*2 : 128; // killough
457 drawsegs = realloc(drawsegs,newmax*sizeof(*drawsegs));
458 ds_p = drawsegs + pos; // jff 8/9/98 fix from ZDOOM1.14a
459 maxdrawsegs = newmax;
462 if(curline->miniseg == false) // figgi -- skip minisegs
463 curline->linedef->flags |= ML_MAPPED;
466 #ifdef RANGECHECK
468 if (start >=viewwidth || start > stop)
469 I_Error ("Bad R_RenderWallRange: %i to %i", start , stop);
470 #endif
472 sidedef = curline->sidedef;
473 linedef = curline->linedef;
475 // mark the segment as visible for auto map
476 linedef->flags |= ML_MAPPED;
478 // calculate rw_distance for scale calculation
479 rw_normalangle = curline->angle + ANG90;
481 offsetangle = D_abs(rw_normalangle-rw_angle1);
483 if (offsetangle > ANG90)
484 offsetangle = ANG90;
486 distangle = ANG90 - offsetangle;
487 hyp = (viewx==curline->v1->x && viewy==curline->v1->y)?
488 0 : R_PointToDist (curline->v1->x, curline->v1->y);
489 sineval = finesine[distangle>>ANGLETOFINESHIFT];
490 rw_distance = FixedMul(hyp, sineval);
492 ds_p->x1 = rw_x = start;
493 ds_p->x2 = stop;
494 ds_p->curline = curline;
495 rw_stopx = stop+1;
497 { // killough 1/6/98, 2/1/98: remove limit on openings
498 extern short *openings;
499 extern size_t maxopenings;
500 size_t pos = lastopening - openings;
501 size_t need = (rw_stopx - start)*4 + pos;
502 if (need > maxopenings)
504 drawseg_t *ds; //jff 8/9/98 needed for fix from ZDoom
505 short *oldopenings = openings;
506 short *oldlast = lastopening;
509 maxopenings = maxopenings ? maxopenings*2 : 16384;
510 while (need > maxopenings);
511 openings = realloc(openings, maxopenings * sizeof(*openings));
512 lastopening = openings + pos;
514 // jff 8/9/98 borrowed fix for openings from ZDOOM1.14
515 // [RH] We also need to adjust the openings pointers that
516 // were already stored in drawsegs.
517 for (ds = drawsegs; ds < ds_p; ds++)
519 #define ADJUST(p) if (ds->p + ds->x1 >= oldopenings && ds->p + ds->x1 <= oldlast)\
520 ds->p = ds->p - oldopenings + openings;
521 ADJUST (maskedtexturecol);
522 ADJUST (sprtopclip);
523 ADJUST (sprbottomclip);
525 #undef ADJUST
527 } // killough: end of code to remove limits on openings
529 // calculate scale at both ends and step
531 ds_p->scale1 = rw_scale =
532 R_ScaleFromGlobalAngle (viewangle + xtoviewangle[start]);
534 if (stop > start)
536 ds_p->scale2 = R_ScaleFromGlobalAngle (viewangle + xtoviewangle[stop]);
537 ds_p->scalestep = rw_scalestep = (ds_p->scale2-rw_scale) / (stop-start);
539 else
540 ds_p->scale2 = ds_p->scale1;
542 // calculate texture boundaries
543 // and decide if floor / ceiling marks are needed
545 worldtop = frontsector->ceilingheight - viewz;
546 worldbottom = frontsector->floorheight - viewz;
548 midtexture = toptexture = bottomtexture = maskedtexture = 0;
549 ds_p->maskedtexturecol = NULL;
551 if (!backsector)
553 // single sided line
554 midtexture = texturetranslation[sidedef->midtexture];
555 midtexheight = (linedef->r_flags & RF_MID_TILE) ? 0 : textureheight[midtexture] >> FRACBITS;
557 // a single sided line is terminal, so it must mark ends
558 markfloor = markceiling = true;
560 if (linedef->flags & ML_DONTPEGBOTTOM)
561 { // bottom of texture at bottom
562 fixed_t vtop = frontsector->floorheight +
563 textureheight[sidedef->midtexture];
564 rw_midtexturemid = vtop - viewz;
566 else // top of texture at top
567 rw_midtexturemid = worldtop;
569 rw_midtexturemid += FixedMod(sidedef->rowoffset, textureheight[midtexture]);
571 ds_p->silhouette = SIL_BOTH;
572 ds_p->sprtopclip = screenheightarray;
573 ds_p->sprbottomclip = negonearray;
574 ds_p->bsilheight = INT_MAX;
575 ds_p->tsilheight = INT_MIN;
577 else // two sided line
579 ds_p->sprtopclip = ds_p->sprbottomclip = NULL;
580 ds_p->silhouette = 0;
582 if (linedef->r_flags & RF_CLOSED)
583 { /* cph - closed 2S line e.g. door */
584 // cph - killough's (outdated) comment follows - this deals with both
585 // "automap fixes", his and mine
586 // killough 1/17/98: this test is required if the fix
587 // for the automap bug (r_bsp.c) is used, or else some
588 // sprites will be displayed behind closed doors. That
589 // fix prevents lines behind closed doors with dropoffs
590 // from being displayed on the automap.
592 ds_p->silhouette = SIL_BOTH;
593 ds_p->sprbottomclip = negonearray;
594 ds_p->bsilheight = INT_MAX;
595 ds_p->sprtopclip = screenheightarray;
596 ds_p->tsilheight = INT_MIN;
599 else
600 { /* not solid - old code */
602 if (frontsector->floorheight > backsector->floorheight)
604 ds_p->silhouette = SIL_BOTTOM;
605 ds_p->bsilheight = frontsector->floorheight;
607 else
608 if (backsector->floorheight > viewz)
610 ds_p->silhouette = SIL_BOTTOM;
611 ds_p->bsilheight = INT_MAX;
614 if (frontsector->ceilingheight < backsector->ceilingheight)
616 ds_p->silhouette |= SIL_TOP;
617 ds_p->tsilheight = frontsector->ceilingheight;
619 else
620 if (backsector->ceilingheight < viewz)
622 ds_p->silhouette |= SIL_TOP;
623 ds_p->tsilheight = INT_MIN;
627 worldhigh = backsector->ceilingheight - viewz;
628 worldlow = backsector->floorheight - viewz;
630 // hack to allow height changes in outdoor areas
631 if (frontsector->ceilingpic == skyflatnum
632 && backsector->ceilingpic == skyflatnum)
633 worldtop = worldhigh;
635 markfloor = worldlow != worldbottom
636 || backsector->floorpic != frontsector->floorpic
637 || backsector->lightlevel != frontsector->lightlevel
639 // killough 3/7/98: Add checks for (x,y) offsets
640 || backsector->floor_xoffs != frontsector->floor_xoffs
641 || backsector->floor_yoffs != frontsector->floor_yoffs
643 // killough 4/15/98: prevent 2s normals
644 // from bleeding through deep water
645 || frontsector->heightsec != -1
647 // killough 4/17/98: draw floors if different light levels
648 || backsector->floorlightsec != frontsector->floorlightsec
651 markceiling = worldhigh != worldtop
652 || backsector->ceilingpic != frontsector->ceilingpic
653 || backsector->lightlevel != frontsector->lightlevel
655 // killough 3/7/98: Add checks for (x,y) offsets
656 || backsector->ceiling_xoffs != frontsector->ceiling_xoffs
657 || backsector->ceiling_yoffs != frontsector->ceiling_yoffs
659 // killough 4/15/98: prevent 2s normals
660 // from bleeding through fake ceilings
661 || (frontsector->heightsec != -1 &&
662 frontsector->ceilingpic!=skyflatnum)
664 // killough 4/17/98: draw ceilings if different light levels
665 || backsector->ceilinglightsec != frontsector->ceilinglightsec
668 if (backsector->ceilingheight <= frontsector->floorheight
669 || backsector->floorheight >= frontsector->ceilingheight)
670 markceiling = markfloor = true; // closed door
672 if (worldhigh < worldtop) // top texture
674 toptexture = texturetranslation[sidedef->toptexture];
675 toptexheight = (linedef->r_flags & RF_TOP_TILE) ? 0 : textureheight[toptexture] >> FRACBITS;
676 rw_toptexturemid = linedef->flags & ML_DONTPEGTOP ? worldtop :
677 backsector->ceilingheight+textureheight[sidedef->toptexture]-viewz;
678 rw_toptexturemid += FixedMod(sidedef->rowoffset, textureheight[toptexture]);
681 if (worldlow > worldbottom) // bottom texture
683 bottomtexture = texturetranslation[sidedef->bottomtexture];
684 bottomtexheight = (linedef->r_flags & RF_BOT_TILE) ? 0 : textureheight[bottomtexture] >> FRACBITS;
685 rw_bottomtexturemid = linedef->flags & ML_DONTPEGBOTTOM ? worldtop :
686 worldlow;
687 rw_bottomtexturemid += FixedMod(sidedef->rowoffset, textureheight[bottomtexture]);
690 // allocate space for masked texture tables
691 if (sidedef->midtexture) // masked midtexture
693 maskedtexture = true;
694 ds_p->maskedtexturecol = maskedtexturecol = lastopening - rw_x;
695 lastopening += rw_stopx - rw_x;
699 // calculate rw_offset (only needed for textured lines)
700 segtextured = midtexture | toptexture | bottomtexture | maskedtexture;
702 if (segtextured)
704 offsetangle = rw_normalangle-rw_angle1;
706 if (offsetangle > ANG180)
707 offsetangle = 0-offsetangle;
709 if (offsetangle > ANG90)
710 offsetangle = ANG90;
712 sineval = finesine[offsetangle >>ANGLETOFINESHIFT];
713 rw_offset = FixedMul (hyp, sineval);
715 if (rw_normalangle-rw_angle1 < ANG180)
716 rw_offset = -rw_offset;
718 rw_offset += sidedef->textureoffset + curline->offset;
720 rw_centerangle = ANG90 + viewangle - rw_normalangle;
722 // calculate light table
723 // use different light tables
724 // for horizontal / vertical / diagonal
725 // OPTIMIZE: get rid of LIGHTSEGSHIFT globally
726 if (!fixedcolormap)
728 int lightnum = (frontsector->lightlevel >> LIGHTSEGSHIFT)+extralight;
730 /* cph - ...what is this for? adding contrast to rooms?
731 * It looks crap in outdoor areas */
732 if (fake_contrast)
734 if (curline->v1->y == curline->v2->y)
735 lightnum--;
736 else if (curline->v1->x == curline->v2->x)
737 lightnum++;
740 if (lightnum < 0)
741 walllights = scalelight[0];
742 else if (lightnum >= LIGHTLEVELS)
743 walllights = scalelight[LIGHTLEVELS-1];
744 else
745 walllights = scalelight[lightnum];
749 // if a floor / ceiling plane is on the wrong side of the view
750 // plane, it is definitely invisible and doesn't need to be marked.
752 // killough 3/7/98: add deep water check
753 if (frontsector->heightsec == -1)
755 if (frontsector->floorheight >= viewz) // above view plane
756 markfloor = false;
757 if (frontsector->ceilingheight <= viewz &&
758 frontsector->ceilingpic != skyflatnum) // below view plane
759 markceiling = false;
762 // calculate incremental stepping values for texture edges
763 worldtop >>= 4;
764 worldbottom >>= 4;
766 topstep = -FixedMul (rw_scalestep, worldtop);
767 topfrac = (centeryfrac>>4) - FixedMul (worldtop, rw_scale);
769 bottomstep = -FixedMul (rw_scalestep,worldbottom);
770 bottomfrac = (centeryfrac>>4) - FixedMul (worldbottom, rw_scale);
772 if (backsector)
774 worldhigh >>= 4;
775 worldlow >>= 4;
777 if (worldhigh < worldtop)
779 pixhigh = (centeryfrac>>4) - FixedMul (worldhigh, rw_scale);
780 pixhighstep = -FixedMul (rw_scalestep,worldhigh);
782 if (worldlow > worldbottom)
784 pixlow = (centeryfrac>>4) - FixedMul (worldlow, rw_scale);
785 pixlowstep = -FixedMul (rw_scalestep,worldlow);
789 // render it
790 if (markceiling)
792 if (ceilingplane) // killough 4/11/98: add NULL ptr checks
793 ceilingplane = R_CheckPlane (ceilingplane, rw_x, rw_stopx-1);
794 else
795 markceiling = 0;
798 if (markfloor)
800 if (floorplane) // killough 4/11/98: add NULL ptr checks
801 /* cph 2003/04/18 - ceilingplane and floorplane might be the same
802 * visplane (e.g. if both skies); R_CheckPlane doesn't know about
803 * modifications to the plane that might happen in parallel with the check
804 * being made, so we have to override it and split them anyway if that is
805 * a possibility, otherwise the floor marking would overwrite the ceiling
806 * marking, resulting in HOM. */
807 if (markceiling && ceilingplane == floorplane)
808 floorplane = R_DupPlane (floorplane, rw_x, rw_stopx-1);
809 else
810 floorplane = R_CheckPlane (floorplane, rw_x, rw_stopx-1);
811 else
812 markfloor = 0;
815 didsolidcol = 0;
816 R_RenderSegLoop();
818 /* cph - if a column was made solid by this wall, we _must_ save full clipping info */
819 if (backsector && didsolidcol)
821 if (!(ds_p->silhouette & SIL_BOTTOM))
823 ds_p->silhouette |= SIL_BOTTOM;
824 ds_p->bsilheight = backsector->floorheight;
826 if (!(ds_p->silhouette & SIL_TOP))
828 ds_p->silhouette |= SIL_TOP;
829 ds_p->tsilheight = backsector->ceilingheight;
833 // save sprite clipping info
834 if ((ds_p->silhouette & SIL_TOP || maskedtexture) && !ds_p->sprtopclip)
836 memcpy (lastopening, ceilingclip+start, 2*(rw_stopx-start));
837 ds_p->sprtopclip = lastopening - start;
838 lastopening += rw_stopx - start;
840 if ((ds_p->silhouette & SIL_BOTTOM || maskedtexture) && !ds_p->sprbottomclip)
842 memcpy (lastopening, floorclip+start, 2*(rw_stopx-start));
843 ds_p->sprbottomclip = lastopening - start;
844 lastopening += rw_stopx - start;
846 if (maskedtexture && !(ds_p->silhouette & SIL_TOP))
848 ds_p->silhouette |= SIL_TOP;
849 ds_p->tsilheight = INT_MIN;
851 if (maskedtexture && !(ds_p->silhouette & SIL_BOTTOM))
853 ds_p->silhouette |= SIL_BOTTOM;
854 ds_p->bsilheight = INT_MAX;
856 ds_p++;