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
28 * All the clipping: columns, horizontal spans, sky columns.
30 *-----------------------------------------------------------------------------*/
32 // 4/25/98, 5/2/98 killough: reformatted, beautified
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.
50 boolean markfloor
; // False if the back side is the same plane.
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
62 lighttable_t
** walllights
;
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
;
77 static int worldbottom
;
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
)
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 */
156 if (curline
->v1
->y
== curline
->v2
->y
)
159 if (curline
->v1
->x
== curline
->v2
->x
)
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
;
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
;
182 dc_texturemid
=frontsector
->ceilingheight
<backsector
->ceilingheight
183 ? frontsector
->ceilingheight
: backsector
->ceilingheight
;
184 dc_texturemid
= dc_texturemid
- viewz
;
187 dc_texturemid
+= curline
->sidedef
->rowoffset
;
190 dc_colormap
= fixedcolormap
;
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
];
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).
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
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;
280 if (bottom
>= floorclip
[rw_x
])
281 bottom
= floorclip
[rw_x
]-1;
285 ceilingplane
->top
[rw_x
] = top
;
286 ceilingplane
->bottom
[rw_x
] = bottom
;
290 // yh = bottomfrac>>HEIGHTBITS;
292 bottom
= floorclip
[rw_x
]-1;
299 top
= yh
< ceilingclip
[rw_x
] ? ceilingclip
[rw_x
] : yh
;
303 floorplane
->top
[rw_x
] = top
;
304 floorplane
->bottom
[rw_x
] = bottom
;
308 // texturecolumn and lighting are independent of wall tiers
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
];
326 dc_iscale
= 0xffffffffu
/ (unsigned)rw_scale
;
329 // draw the wall tiers
333 dc_yl
= yl
; // single sided line
335 dc_texturemid
= rw_midtexturemid
;
336 dc_source
= R_GetColumn(midtexture
, texturecolumn
);
337 dc_texheight
= midtexheight
;
339 ceilingclip
[rw_x
] = viewheight
;
340 floorclip
[rw_x
] = -1;
349 int mid
= pixhigh
>>HEIGHTBITS
;
350 pixhigh
+= pixhighstep
;
352 if (mid
>= floorclip
[rw_x
])
353 mid
= floorclip
[rw_x
]-1;
359 dc_texturemid
= rw_toptexturemid
;
360 dc_source
= R_GetColumn(toptexture
,texturecolumn
);
361 dc_texheight
= toptexheight
;
363 ceilingclip
[rw_x
] = mid
;
366 ceilingclip
[rw_x
] = yl
-1;
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;
388 dc_texturemid
= rw_bottomtexturemid
;
389 dc_source
= R_GetColumn(bottomtexture
,
391 dc_texheight
= bottomtexheight
;
393 floorclip
[rw_x
] = mid
;
396 floorclip
[rw_x
] = yh
+1;
398 else // no bottom wall
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))
413 // save texturecol for backdrawing of masked mid texture
415 maskedtexturecol
[rw_x
] = texturecolumn
;
418 rw_scale
+= rw_scalestep
;
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
);
438 return FixedDiv(dx
, finesine
[(tantoangle
[FixedDiv(dy
,dx
) >> DBITS
]
439 + ANG90
) >> ANGLETOFINESHIFT
]);
444 // A wall segment will be drawn
445 // between start and stop pixels (inclusive).
447 void R_StoreWallRange(const int start
, const int stop
)
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
;
468 if (start
>=viewwidth
|| start
> stop
)
469 I_Error ("Bad R_RenderWallRange: %i to %i", start
, stop
);
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
)
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
;
494 ds_p
->curline
= curline
;
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
);
523 ADJUST (sprbottomclip
);
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
]);
536 ds_p
->scale2
= R_ScaleFromGlobalAngle (viewangle
+ xtoviewangle
[stop
]);
537 ds_p
->scalestep
= rw_scalestep
= (ds_p
->scale2
-rw_scale
) / (stop
-start
);
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
;
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
;
600 { /* not solid - old code */
602 if (frontsector
->floorheight
> backsector
->floorheight
)
604 ds_p
->silhouette
= SIL_BOTTOM
;
605 ds_p
->bsilheight
= frontsector
->floorheight
;
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
;
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
:
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
;
704 offsetangle
= rw_normalangle
-rw_angle1
;
706 if (offsetangle
> ANG180
)
707 offsetangle
= 0-offsetangle
;
709 if (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
728 int lightnum
= (frontsector
->lightlevel
>> LIGHTSEGSHIFT
)+extralight
;
730 /* cph - ...what is this for? adding contrast to rooms?
731 * It looks crap in outdoor areas */
734 if (curline
->v1
->y
== curline
->v2
->y
)
736 else if (curline
->v1
->x
== curline
->v2
->x
)
741 walllights
= scalelight
[0];
742 else if (lightnum
>= LIGHTLEVELS
)
743 walllights
= scalelight
[LIGHTLEVELS
-1];
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
757 if (frontsector
->ceilingheight
<= viewz
&&
758 frontsector
->ceilingpic
!= skyflatnum
) // below view plane
762 // calculate incremental stepping values for texture edges
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
);
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
);
792 if (ceilingplane
) // killough 4/11/98: add NULL ptr checks
793 ceilingplane
= R_CheckPlane (ceilingplane
, rw_x
, rw_stopx
-1);
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);
810 floorplane
= R_CheckPlane (floorplane
, rw_x
, rw_stopx
-1);
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
;