2014-03-15 16:59:03 +00:00
// SONIC ROBO BLAST 2
//-----------------------------------------------------------------------------
// Copyright (C) 1993-1996 by id Software, Inc.
// Copyright (C) 1998-2000 by DooM Legacy Team.
2018-11-25 12:35:38 +00:00
// Copyright (C) 1999-2018 by Sonic Team Junior.
2014-03-15 16:59:03 +00:00
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
// See the 'LICENSE' file for more details.
//-----------------------------------------------------------------------------
/// \file r_segs.c
/// \brief All the clipping: columns, horizontal spans, sky columns
# include "doomdef.h"
# include "r_local.h"
# include "r_sky.h"
# include "r_splats.h"
# include "w_wad.h"
# include "z_zone.h"
# include "d_netcmd.h"
# include "m_misc.h"
# include "p_local.h" // Camera...
2015-10-10 16:57:35 +00:00
# include "p_slopes.h"
2014-03-15 16:59:03 +00:00
# include "console.h" // con_clipviewtop
// OPTIMIZE: closed two sided lines as single sided
// True if any of the segs textures might be visible.
static boolean segtextured ;
static boolean markfloor ; // False if the back side is the same plane.
static boolean markceiling ;
static boolean maskedtexture ;
static INT32 toptexture , bottomtexture , midtexture ;
static INT32 numthicksides , numbackffloors ;
angle_t rw_normalangle ;
// angle to line origin
angle_t rw_angle1 ;
fixed_t rw_distance ;
//
// regular wall
//
static INT32 rw_x , rw_stopx ;
static angle_t rw_centerangle ;
static fixed_t rw_offset ;
static fixed_t rw_offset2 ; // for splats
static fixed_t rw_scale , rw_scalestep ;
static fixed_t rw_midtexturemid , rw_toptexturemid , rw_bottomtexturemid ;
static INT32 worldtop , worldbottom , worldhigh , worldlow ;
2015-04-20 03:20:54 +00:00
static INT32 worldtopslope , worldbottomslope , worldhighslope , worldlowslope ; // worldtop/bottom at end of slope
2015-05-03 20:47:40 +00:00
static fixed_t rw_toptextureslide , rw_midtextureslide , rw_bottomtextureslide ; // Defines how to adjust Y offsets along the wall for slopes
2015-05-04 20:15:57 +00:00
static fixed_t rw_midtextureback , rw_midtexturebackslide ; // Values for masked midtexture height calculation
2014-03-15 16:59:03 +00:00
static fixed_t pixhigh , pixlow , pixhighstep , pixlowstep ;
static fixed_t topfrac , topstep ;
static fixed_t bottomfrac , bottomstep ;
static lighttable_t * * walllights ;
static INT16 * maskedtexturecol ;
2015-05-04 20:15:57 +00:00
static fixed_t * maskedtextureheight = NULL ;
2014-03-15 16:59:03 +00:00
// ==========================================================================
// R_Splats Wall Splats Drawer
// ==========================================================================
# ifdef WALLSPLATS
static INT16 last_ceilingclip [ MAXVIDWIDTH ] ;
static INT16 last_floorclip [ MAXVIDWIDTH ] ;
static void R_DrawSplatColumn ( column_t * column )
{
INT32 topscreen , bottomscreen ;
fixed_t basetexturemid ;
INT32 topdelta , prevdelta = - 1 ;
basetexturemid = dc_texturemid ;
for ( ; column - > topdelta ! = 0xff ; )
{
// calculate unclipped screen coordinates for post
topdelta = column - > topdelta ;
if ( topdelta < = prevdelta )
topdelta + = prevdelta ;
prevdelta = topdelta ;
topscreen = sprtopscreen + spryscale * topdelta ;
bottomscreen = topscreen + spryscale * column - > length ;
dc_yl = ( topscreen + FRACUNIT - 1 ) > > FRACBITS ;
dc_yh = ( bottomscreen - 1 ) > > FRACBITS ;
if ( dc_yh > = last_floorclip [ dc_x ] )
dc_yh = last_floorclip [ dc_x ] - 1 ;
if ( dc_yl < = last_ceilingclip [ dc_x ] )
dc_yl = last_ceilingclip [ dc_x ] + 1 ;
if ( dc_yl < = dc_yh & & dl_yh < vid . height & & yh > 0 )
{
dc_source = ( UINT8 * ) column + 3 ;
dc_texturemid = basetexturemid - ( topdelta < < FRACBITS ) ;
// Drawn by R_DrawColumn.
colfunc ( ) ;
}
column = ( column_t * ) ( ( UINT8 * ) column + column - > length + 4 ) ;
}
dc_texturemid = basetexturemid ;
}
static void R_DrawWallSplats ( void )
{
wallsplat_t * splat ;
seg_t * seg ;
angle_t angle , angle1 , angle2 ;
INT32 x1 , x2 ;
size_t pindex ;
column_t * col ;
patch_t * patch ;
fixed_t texturecolumn ;
splat = ( wallsplat_t * ) linedef - > splats ;
I_Assert ( splat ! = NULL ) ;
seg = ds_p - > curline ;
// draw all splats from the line that touches the range of the seg
for ( ; splat ; splat = splat - > next )
{
angle1 = R_PointToAngle ( splat - > v1 . x , splat - > v1 . y ) ;
angle2 = R_PointToAngle ( splat - > v2 . x , splat - > v2 . y ) ;
angle1 = ( angle1 - viewangle + ANGLE_90 ) > > ANGLETOFINESHIFT ;
angle2 = ( angle2 - viewangle + ANGLE_90 ) > > ANGLETOFINESHIFT ;
// out of the viewangletox lut
/// \todo clip it to the screen
if ( angle1 > FINEANGLES / 2 | | angle2 > FINEANGLES / 2 )
continue ;
x1 = viewangletox [ angle1 ] ;
x2 = viewangletox [ angle2 ] ;
if ( x1 > = x2 )
continue ; // does not cross a pixel
// splat is not in this seg range
if ( x2 < ds_p - > x1 | | x1 > ds_p - > x2 )
continue ;
if ( x1 < ds_p - > x1 )
x1 = ds_p - > x1 ;
if ( x2 > ds_p - > x2 )
x2 = ds_p - > x2 ;
if ( x2 < = x1 )
continue ;
// calculate incremental stepping values for texture edges
rw_scalestep = ds_p - > scalestep ;
spryscale = ds_p - > scale1 + ( x1 - ds_p - > x1 ) * rw_scalestep ;
mfloorclip = floorclip ;
mceilingclip = ceilingclip ;
patch = W_CachePatchNum ( splat - > patch , PU_CACHE ) ;
dc_texturemid = splat - > top + ( SHORT ( patch - > height ) < < ( FRACBITS - 1 ) ) - viewz ;
if ( splat - > yoffset )
dc_texturemid + = * splat - > yoffset ;
sprtopscreen = centeryfrac - FixedMul ( dc_texturemid , spryscale ) ;
// set drawing mode
switch ( splat - > flags & SPLATDRAWMODE_MASK )
{
case SPLATDRAWMODE_OPAQUE :
colfunc = basecolfunc ;
break ;
case SPLATDRAWMODE_TRANS :
if ( ! cv_translucency . value )
colfunc = basecolfunc ;
else
{
2015-10-12 14:10:43 +00:00
dc_transmap = transtables + ( ( tr_trans50 - 1 ) < < FF_TRANSSHIFT ) ;
2014-03-15 16:59:03 +00:00
colfunc = fuzzcolfunc ;
}
break ;
case SPLATDRAWMODE_SHADE :
colfunc = shadecolfunc ;
break ;
}
dc_texheight = 0 ;
// draw the columns
for ( dc_x = x1 ; dc_x < = x2 ; dc_x + + , spryscale + = rw_scalestep )
{
2016-04-05 14:33:55 +00:00
pindex = FixedMul ( spryscale , FixedDiv ( 640 , vid . width ) ) > > LIGHTSCALESHIFT ;
2014-03-15 16:59:03 +00:00
if ( pindex > = MAXLIGHTSCALE )
pindex = MAXLIGHTSCALE - 1 ;
dc_colormap = walllights [ pindex ] ;
2018-08-10 18:31:30 +00:00
if ( encoremap & & ! ( seg - > linedef - > flags & ML_TFERLINE ) )
2018-07-23 22:50:41 +00:00
dc_colormap + = ( 256 * 32 ) ;
2014-03-15 16:59:03 +00:00
if ( frontsector - > extra_colormap )
dc_colormap = frontsector - > extra_colormap - > colormap + ( dc_colormap - colormaps ) ;
sprtopscreen = centeryfrac - FixedMul ( dc_texturemid , spryscale ) ;
dc_iscale = 0xffffffffu / ( unsigned ) spryscale ;
// find column of patch, from perspective
angle = ( rw_centerangle + xtoviewangle [ dc_x ] ) > > ANGLETOFINESHIFT ;
texturecolumn = rw_offset2 - splat - > offset
- FixedMul ( FINETANGENT ( angle ) , rw_distance ) ;
// FIXME!
texturecolumn > > = FRACBITS ;
if ( texturecolumn < 0 | | texturecolumn > = SHORT ( patch - > width ) )
continue ;
// draw the texture
col = ( column_t * ) ( ( UINT8 * ) patch + LONG ( patch - > columnofs [ texturecolumn ] ) ) ;
R_DrawSplatColumn ( col ) ;
}
} // next splat
colfunc = basecolfunc ;
}
# endif //WALLSPLATS
// ==========================================================================
// R_RenderMaskedSegRange
// ==========================================================================
// If we have a multi-patch texture on a 2sided wall (rare) then we draw
// it using R_DrawColumn, else we draw it using R_DrawMaskedColumn, this
// way we don't have to store extra post_t info with each column for
// multi-patch textures. They are not normally needed as multi-patch
// textures don't have holes in it. At least not for now.
static INT32 column2s_length ; // column->length : for multi-patch on 2sided wall = texture->height
static void R_Render2sidedMultiPatchColumn ( column_t * column )
{
INT32 topscreen , bottomscreen ;
topscreen = sprtopscreen ; // + spryscale*column->topdelta; topdelta is 0 for the wall
bottomscreen = topscreen + spryscale * column2s_length ;
dc_yl = ( sprtopscreen + FRACUNIT - 1 ) > > FRACBITS ;
dc_yh = ( bottomscreen - 1 ) > > FRACBITS ;
if ( windowtop ! = INT32_MAX & & windowbottom ! = INT32_MAX )
{
dc_yl = ( ( windowtop + FRACUNIT ) > > FRACBITS ) ;
dc_yh = ( windowbottom - 1 ) > > FRACBITS ;
}
if ( dc_yh > = mfloorclip [ dc_x ] )
dc_yh = mfloorclip [ dc_x ] - 1 ;
if ( dc_yl < = mceilingclip [ dc_x ] )
dc_yl = mceilingclip [ dc_x ] + 1 ;
if ( dc_yl > = vid . height | | dc_yh < 0 )
return ;
if ( dc_yl < = dc_yh & & dc_yh < vid . height & & dc_yh > 0 )
{
dc_source = ( UINT8 * ) column + 3 ;
if ( colfunc = = wallcolfunc )
twosmultipatchfunc ( ) ;
2016-11-16 18:43:25 +00:00
else if ( colfunc = = fuzzcolfunc )
twosmultipatchtransfunc ( ) ;
2014-03-15 16:59:03 +00:00
else
colfunc ( ) ;
}
}
void R_RenderMaskedSegRange ( drawseg_t * ds , INT32 x1 , INT32 x2 )
{
size_t pindex ;
column_t * col ;
INT32 lightnum , texnum , i ;
fixed_t height , realbot ;
lightlist_t * light ;
r_lightlist_t * rlight ;
void ( * colfunc_2s ) ( column_t * ) ;
line_t * ldef ;
sector_t * front , * back ;
INT32 times , repeats ;
2016-05-02 12:29:30 +00:00
INT64 overflow_test ;
2016-03-19 23:19:05 +00:00
INT32 range ;
2014-03-15 16:59:03 +00:00
// Calculate light table.
// Use different light tables
// for horizontal / vertical / diagonal. Diagonal?
// OPTIMIZE: get rid of LIGHTSEGSHIFT globally
curline = ds - > curline ;
frontsector = curline - > frontsector ;
backsector = curline - > backsector ;
2016-12-16 21:38:53 +00:00
texnum = R_GetTextureNum ( curline - > sidedef - > midtexture ) ;
2014-03-15 16:59:03 +00:00
windowbottom = windowtop = sprbotscreen = INT32_MAX ;
// hack translucent linedef types (900-909 for transtables 1-9)
ldef = curline - > linedef ;
switch ( ldef - > special )
{
case 900 :
case 901 :
case 902 :
case 903 :
case 904 :
case 905 :
case 906 :
case 907 :
case 908 :
2015-10-12 14:10:43 +00:00
dc_transmap = transtables + ( ( ldef - > special - 900 ) < < FF_TRANSSHIFT ) ;
2014-03-15 16:59:03 +00:00
colfunc = fuzzcolfunc ;
break ;
case 909 :
colfunc = R_DrawFogColumn_8 ;
windowtop = frontsector - > ceilingheight ;
windowbottom = frontsector - > floorheight ;
break ;
default :
colfunc = wallcolfunc ;
break ;
}
if ( curline - > polyseg & & curline - > polyseg - > translucency > 0 )
{
if ( curline - > polyseg - > translucency > = NUMTRANSMAPS )
return ;
2015-10-12 14:10:43 +00:00
dc_transmap = transtables + ( ( curline - > polyseg - > translucency - 1 ) < < FF_TRANSSHIFT ) ;
2014-03-15 16:59:03 +00:00
colfunc = fuzzcolfunc ;
}
2016-03-19 23:19:05 +00:00
range = max ( ds - > x2 - ds - > x1 , 1 ) ;
2014-03-15 16:59:03 +00:00
rw_scalestep = ds - > scalestep ;
spryscale = ds - > scale1 + ( x1 - ds - > x1 ) * rw_scalestep ;
2016-12-17 19:59:54 +00:00
// Texture must be cached before setting colfunc_2s,
// otherwise texture[texnum]->holes may be false when it shouldn't be
R_CheckTextureCache ( texnum ) ;
2014-03-15 16:59:03 +00:00
// handle case where multipatch texture is drawn on a 2sided wall, multi-patch textures
// are not stored per-column with post info in SRB2
if ( textures [ texnum ] - > holes )
colfunc_2s = R_DrawMaskedColumn ; // render the usual 2sided single-patch packed texture
else
{
colfunc_2s = R_Render2sidedMultiPatchColumn ; // render multipatch with no holes (no post_t info)
column2s_length = textures [ texnum ] - > height ;
}
// Setup lighting based on the presence/lack-of 3D floors.
dc_numlights = 0 ;
if ( frontsector - > numlights )
{
dc_numlights = frontsector - > numlights ;
if ( dc_numlights > = dc_maxlights )
{
dc_maxlights = dc_numlights ;
dc_lightlist = Z_Realloc ( dc_lightlist , sizeof ( * dc_lightlist ) * dc_maxlights , PU_STATIC , NULL ) ;
}
for ( i = 0 ; i < dc_numlights ; i + + )
{
2016-03-18 20:33:16 +00:00
fixed_t leftheight , rightheight ;
2014-03-15 16:59:03 +00:00
light = & frontsector - > lightlist [ i ] ;
rlight = & dc_lightlist [ i ] ;
2016-03-18 20:33:16 +00:00
if ( light - > slope ) {
leftheight = P_GetZAt ( light - > slope , ds - > leftpos . x , ds - > leftpos . y ) ;
rightheight = P_GetZAt ( light - > slope , ds - > rightpos . x , ds - > rightpos . y ) ;
} else
leftheight = rightheight = light - > height ;
leftheight - = viewz ;
rightheight - = viewz ;
rlight - > height = ( centeryfrac ) - FixedMul ( leftheight , ds - > scale1 ) ;
rlight - > heightstep = ( centeryfrac ) - FixedMul ( rightheight , ds - > scale2 ) ;
2016-03-19 23:19:05 +00:00
rlight - > heightstep = ( rlight - > heightstep - rlight - > height ) / ( range ) ;
2016-03-18 20:33:16 +00:00
//if (x1 > ds->x1)
//rlight->height -= (x1 - ds->x1)*rlight->heightstep;
2016-12-31 20:44:16 +00:00
rlight - > startheight = rlight - > height ; // keep starting value here to reset for each repeat
2014-03-15 16:59:03 +00:00
rlight - > lightlevel = * light - > lightlevel ;
rlight - > extra_colormap = light - > extra_colormap ;
rlight - > flags = light - > flags ;
if ( rlight - > flags & FF_FOG | | ( rlight - > extra_colormap & & rlight - > extra_colormap - > fog ) )
lightnum = ( rlight - > lightlevel > > LIGHTSEGSHIFT ) ;
else if ( colfunc = = fuzzcolfunc )
lightnum = LIGHTLEVELS - 1 ;
else
lightnum = ( rlight - > lightlevel > > LIGHTSEGSHIFT ) ;
if ( rlight - > extra_colormap & & rlight - > extra_colormap - > fog )
;
else if ( curline - > v1 - > y = = curline - > v2 - > y )
lightnum - - ;
else if ( curline - > v1 - > x = = curline - > v2 - > x )
lightnum + + ;
rlight - > lightnum = lightnum ;
}
}
else
{
if ( colfunc = = fuzzcolfunc )
{
if ( frontsector - > extra_colormap & & frontsector - > extra_colormap - > fog )
lightnum = ( frontsector - > lightlevel > > LIGHTSEGSHIFT ) ;
else
lightnum = LIGHTLEVELS - 1 ;
}
else
lightnum = ( frontsector - > lightlevel > > LIGHTSEGSHIFT ) ;
if ( colfunc = = R_DrawFogColumn_8
| | ( frontsector - > extra_colormap & & frontsector - > extra_colormap - > fog ) )
;
else if ( curline - > v1 - > y = = curline - > v2 - > y )
lightnum - - ;
else if ( curline - > v1 - > x = = curline - > v2 - > x )
lightnum + + ;
if ( lightnum < 0 )
walllights = scalelight [ 0 ] ;
else if ( lightnum > = LIGHTLEVELS )
walllights = scalelight [ LIGHTLEVELS - 1 ] ;
else
walllights = scalelight [ lightnum ] ;
}
maskedtexturecol = ds - > maskedtexturecol ;
mfloorclip = ds - > sprbottomclip ;
mceilingclip = ds - > sprtopclip ;
if ( frontsector - > heightsec ! = - 1 )
front = & sectors [ frontsector - > heightsec ] ;
else
front = frontsector ;
if ( backsector - > heightsec ! = - 1 )
back = & sectors [ backsector - > heightsec ] ;
else
back = backsector ;
if ( ds - > curline - > sidedef - > repeatcnt )
repeats = 1 + ds - > curline - > sidedef - > repeatcnt ;
else if ( ldef - > flags & ML_EFFECT5 )
{
fixed_t high , low ;
if ( front - > ceilingheight > back - > ceilingheight )
high = back - > ceilingheight ;
else
high = front - > ceilingheight ;
if ( front - > floorheight > back - > floorheight )
low = front - > floorheight ;
else
low = back - > floorheight ;
repeats = ( high - low ) / textureheight [ texnum ] ;
if ( ( high - low ) % textureheight [ texnum ] )
repeats + + ; // tile an extra time to fill the gap -- Monster Iestyn
}
else
repeats = 1 ;
for ( times = 0 ; times < repeats ; times + + )
{
if ( times > 0 )
{
rw_scalestep = ds - > scalestep ;
spryscale = ds - > scale1 + ( x1 - ds - > x1 ) * rw_scalestep ;
2016-12-31 20:44:16 +00:00
if ( dc_numlights )
{ // reset all lights to their starting heights
for ( i = 0 ; i < dc_numlights ; i + + )
{
rlight = & dc_lightlist [ i ] ;
rlight - > height = rlight - > startheight ;
}
}
2014-03-15 16:59:03 +00:00
}
dc_texheight = textureheight [ texnum ] > > FRACBITS ;
// draw the columns
for ( dc_x = x1 ; dc_x < = x2 ; dc_x + + )
{
2015-05-04 20:15:57 +00:00
dc_texturemid = ds - > maskedtextureheight [ dc_x ] ;
2015-05-04 22:45:02 +00:00
if ( ! ! ( curline - > linedef - > flags & ML_DONTPEGBOTTOM ) ^ ! ! ( curline - > linedef - > flags & ML_EFFECT3 ) )
2015-05-04 20:15:57 +00:00
dc_texturemid + = ( textureheight [ texnum ] ) * times + textureheight [ texnum ] ;
else
dc_texturemid - = ( textureheight [ texnum ] ) * times ;
2014-03-15 16:59:03 +00:00
// calculate lighting
if ( maskedtexturecol [ dc_x ] ! = INT16_MAX )
{
2016-05-02 12:29:30 +00:00
// Check for overflows first
overflow_test = ( INT64 ) centeryfrac - ( ( ( INT64 ) dc_texturemid * spryscale ) > > FRACBITS ) ;
if ( overflow_test < 0 ) overflow_test = - overflow_test ;
if ( ( UINT64 ) overflow_test & 0xFFFFFFFF80000000ULL )
{
// Eh, no, go away, don't waste our time
2016-05-05 16:49:57 +00:00
if ( dc_numlights )
{
for ( i = 0 ; i < dc_numlights ; i + + )
{
rlight = & dc_lightlist [ i ] ;
rlight - > height + = rlight - > heightstep ;
}
}
2016-05-02 12:29:30 +00:00
spryscale + = rw_scalestep ;
continue ;
}
2014-03-15 16:59:03 +00:00
if ( dc_numlights )
{
lighttable_t * * xwalllights ;
sprbotscreen = INT32_MAX ;
sprtopscreen = windowtop = ( centeryfrac - FixedMul ( dc_texturemid , spryscale ) ) ;
realbot = windowbottom = FixedMul ( textureheight [ texnum ] , spryscale ) + sprtopscreen ;
dc_iscale = 0xffffffffu / ( unsigned ) spryscale ;
// draw the texture
col = ( column_t * ) ( ( UINT8 * ) R_GetColumn ( texnum , maskedtexturecol [ dc_x ] ) - 3 ) ;
for ( i = 0 ; i < dc_numlights ; i + + )
{
rlight = & dc_lightlist [ i ] ;
if ( ( rlight - > flags & FF_NOSHADE ) )
continue ;
if ( rlight - > lightnum < 0 )
xwalllights = scalelight [ 0 ] ;
else if ( rlight - > lightnum > = LIGHTLEVELS )
xwalllights = scalelight [ LIGHTLEVELS - 1 ] ;
else
xwalllights = scalelight [ rlight - > lightnum ] ;
2015-01-01 19:50:31 +00:00
pindex = FixedMul ( spryscale , FixedDiv ( 640 , vid . width ) ) > > LIGHTSCALESHIFT ;
2014-03-15 16:59:03 +00:00
if ( pindex > = MAXLIGHTSCALE )
pindex = MAXLIGHTSCALE - 1 ;
if ( rlight - > extra_colormap )
rlight - > rcolormap = rlight - > extra_colormap - > colormap + ( xwalllights [ pindex ] - colormaps ) ;
else
rlight - > rcolormap = xwalllights [ pindex ] ;
height = rlight - > height ;
2018-10-13 17:57:40 +00:00
rlight - > height + = rlight - > heightstep ;
2014-03-15 16:59:03 +00:00
if ( height < = windowtop )
{
dc_colormap = rlight - > rcolormap ;
2018-08-10 18:31:30 +00:00
if ( encoremap & & ! ( ldef - > flags & ML_TFERLINE ) )
2018-07-23 22:50:41 +00:00
dc_colormap + = ( 256 * 32 ) ;
2014-03-15 16:59:03 +00:00
continue ;
}
windowbottom = height ;
if ( windowbottom > = realbot )
{
windowbottom = realbot ;
colfunc_2s ( col ) ;
for ( i + + ; i < dc_numlights ; i + + )
{
rlight = & dc_lightlist [ i ] ;
rlight - > height + = rlight - > heightstep ;
}
continue ;
}
colfunc_2s ( col ) ;
windowtop = windowbottom + 1 ;
dc_colormap = rlight - > rcolormap ;
2018-08-10 18:31:30 +00:00
if ( encoremap & & ! ( ldef - > flags & ML_TFERLINE ) )
2018-07-23 22:50:41 +00:00
dc_colormap + = ( 256 * 32 ) ;
2014-03-15 16:59:03 +00:00
}
windowbottom = realbot ;
if ( windowtop < windowbottom )
colfunc_2s ( col ) ;
spryscale + = rw_scalestep ;
continue ;
}
// calculate lighting
2015-01-01 19:50:31 +00:00
pindex = FixedMul ( spryscale , FixedDiv ( 640 , vid . width ) ) > > LIGHTSCALESHIFT ;
2014-03-15 16:59:03 +00:00
if ( pindex > = MAXLIGHTSCALE )
pindex = MAXLIGHTSCALE - 1 ;
dc_colormap = walllights [ pindex ] ;
2018-08-10 18:31:30 +00:00
if ( encoremap & & ! ( ldef - > flags & ML_TFERLINE ) )
2018-07-23 22:50:41 +00:00
dc_colormap + = ( 256 * 32 ) ;
2014-03-15 16:59:03 +00:00
if ( frontsector - > extra_colormap )
dc_colormap = frontsector - > extra_colormap - > colormap + ( dc_colormap - colormaps ) ;
sprtopscreen = centeryfrac - FixedMul ( dc_texturemid , spryscale ) ;
dc_iscale = 0xffffffffu / ( unsigned ) spryscale ;
// draw the texture
col = ( column_t * ) ( ( UINT8 * ) R_GetColumn ( texnum , maskedtexturecol [ dc_x ] ) - 3 ) ;
2014-11-12 00:55:07 +00:00
//#ifdef POLYOBJECTS_PLANES
#if 0 // Disabling this allows inside edges to render below the planes, for until the clipping is fixed to work right when POs are near the camera. -Red
2014-03-15 16:59:03 +00:00
if ( curline - > dontrenderme & & curline - > polyseg & & ( curline - > polyseg - > flags & POF_RENDERPLANES ) )
{
fixed_t my_topscreen ;
fixed_t my_bottomscreen ;
fixed_t my_yl , my_yh ;
my_topscreen = sprtopscreen + spryscale * col - > topdelta ;
my_bottomscreen = sprbotscreen = = INT32_MAX ? my_topscreen + spryscale * col - > length
: sprbotscreen + spryscale * col - > length ;
my_yl = ( my_topscreen + FRACUNIT - 1 ) > > FRACBITS ;
my_yh = ( my_bottomscreen - 1 ) > > FRACBITS ;
// CONS_Debug(DBG_RENDER, "my_topscreen: %d\nmy_bottomscreen: %d\nmy_yl: %d\nmy_yh: %d\n", my_topscreen, my_bottomscreen, my_yl, my_yh);
if ( numffloors )
{
INT32 top = my_yl ;
INT32 bottom = my_yh ;
for ( i = 0 ; i < numffloors ; i + + )
{
2014-11-12 00:55:07 +00:00
if ( ! ffloor [ i ] . polyobj | | ffloor [ i ] . polyobj ! = curline - > polyseg )
2014-03-15 16:59:03 +00:00
continue ;
if ( ffloor [ i ] . height < viewz )
{
INT32 top_w = ffloor [ i ] . plane - > top [ dc_x ] ;
// CONS_Debug(DBG_RENDER, "Leveltime : %d\n", leveltime);
// CONS_Debug(DBG_RENDER, "Top is %d, top_w is %d\n", top, top_w);
if ( top_w < top )
{
ffloor [ i ] . plane - > top [ dc_x ] = ( INT16 ) top ;
ffloor [ i ] . plane - > picnum = 0 ;
}
// CONS_Debug(DBG_RENDER, "top_w is now %d\n", ffloor[i].plane->top[dc_x]);
}
else if ( ffloor [ i ] . height > viewz )
{
INT32 bottom_w = ffloor [ i ] . plane - > bottom [ dc_x ] ;
if ( bottom_w > bottom )
{
ffloor [ i ] . plane - > bottom [ dc_x ] = ( INT16 ) bottom ;
ffloor [ i ] . plane - > picnum = 0 ;
}
}
}
}
}
else
# endif
colfunc_2s ( col ) ;
}
spryscale + = rw_scalestep ;
}
}
colfunc = wallcolfunc ;
}
2014-11-12 00:55:07 +00:00
// Loop through R_DrawMaskedColumn calls
static void R_DrawRepeatMaskedColumn ( column_t * col )
{
2017-01-30 21:08:13 +00:00
while ( sprtopscreen < sprbotscreen ) {
2014-11-12 00:55:07 +00:00
R_DrawMaskedColumn ( col ) ;
2017-01-31 22:10:31 +00:00
if ( ( INT64 ) sprtopscreen + dc_texheight * spryscale > ( INT64 ) INT32_MAX ) // prevent overflow
sprtopscreen = INT32_MAX ;
else
sprtopscreen + = dc_texheight * spryscale ;
2017-01-30 21:08:13 +00:00
}
2014-11-12 00:55:07 +00:00
}
2014-03-15 16:59:03 +00:00
//
// R_RenderThickSideRange
// Renders all the thick sides in the given range.
void R_RenderThickSideRange ( drawseg_t * ds , INT32 x1 , INT32 x2 , ffloor_t * pfloor )
{
size_t pindex ;
column_t * col ;
INT32 lightnum ;
INT32 texnum ;
sector_t tempsec ;
INT32 templight ;
INT32 i , p ;
fixed_t bottombounds = viewheight < < FRACBITS ;
fixed_t topbounds = ( con_clipviewtop - 1 ) < < FRACBITS ;
fixed_t offsetvalue = 0 ;
lightlist_t * light ;
r_lightlist_t * rlight ;
2016-03-19 23:19:05 +00:00
INT32 range ;
2014-03-15 16:59:03 +00:00
line_t * newline = NULL ;
2015-05-17 04:04:54 +00:00
// Render FOF sides kinda like normal sides, with the frac and step and everything
2016-05-05 09:31:53 +00:00
// NOTE: INT64 instead of fixed_t because overflow concerns
INT64 top_frac , top_step , bottom_frac , bottom_step ;
2016-08-29 21:42:06 +00:00
// skew FOF walls with slopes?
boolean slopeskew = false ;
fixed_t ffloortextureslide = 0 ;
INT32 oldx = - 1 ;
fixed_t left_top , left_bottom ; // needed here for slope skewing
pslope_t * skewslope = NULL ;
2014-03-15 16:59:03 +00:00
void ( * colfunc_2s ) ( column_t * ) ;
// Calculate light table.
// Use different light tables
// for horizontal / vertical / diagonal. Diagonal?
// OPTIMIZE: get rid of LIGHTSEGSHIFT globally
curline = ds - > curline ;
backsector = pfloor - > target ;
frontsector = curline - > frontsector = = pfloor - > target ? curline - > backsector : curline - > frontsector ;
2016-12-16 21:38:53 +00:00
texnum = R_GetTextureNum ( sides [ pfloor - > master - > sidenum [ 0 ] ] . midtexture ) ;
2014-03-15 16:59:03 +00:00
colfunc = wallcolfunc ;
if ( pfloor - > master - > flags & ML_TFERLINE )
{
size_t linenum = curline - > linedef - backsector - > lines [ 0 ] ;
newline = pfloor - > master - > frontsector - > lines [ 0 ] + linenum ;
2016-12-16 21:38:53 +00:00
texnum = R_GetTextureNum ( sides [ newline - > sidenum [ 0 ] ] . midtexture ) ;
2014-03-15 16:59:03 +00:00
}
if ( pfloor - > flags & FF_TRANSLUCENT )
{
boolean fuzzy = true ;
// Hacked up support for alpha value in software mode Tails 09-24-2002
if ( pfloor - > alpha < 12 )
return ; // Don't even draw it
else if ( pfloor - > alpha < 38 )
2015-10-12 14:10:43 +00:00
dc_transmap = transtables + ( ( tr_trans90 - 1 ) < < FF_TRANSSHIFT ) ;
2014-03-15 16:59:03 +00:00
else if ( pfloor - > alpha < 64 )
2015-10-12 14:10:43 +00:00
dc_transmap = transtables + ( ( tr_trans80 - 1 ) < < FF_TRANSSHIFT ) ;
2014-03-15 16:59:03 +00:00
else if ( pfloor - > alpha < 89 )
2015-10-12 14:10:43 +00:00
dc_transmap = transtables + ( ( tr_trans70 - 1 ) < < FF_TRANSSHIFT ) ;
2014-03-15 16:59:03 +00:00
else if ( pfloor - > alpha < 115 )
2015-10-12 14:10:43 +00:00
dc_transmap = transtables + ( ( tr_trans60 - 1 ) < < FF_TRANSSHIFT ) ;
2014-03-15 16:59:03 +00:00
else if ( pfloor - > alpha < 140 )
2015-10-12 14:10:43 +00:00
dc_transmap = transtables + ( ( tr_trans50 - 1 ) < < FF_TRANSSHIFT ) ;
2014-03-15 16:59:03 +00:00
else if ( pfloor - > alpha < 166 )
2015-10-12 14:10:43 +00:00
dc_transmap = transtables + ( ( tr_trans40 - 1 ) < < FF_TRANSSHIFT ) ;
2014-03-15 16:59:03 +00:00
else if ( pfloor - > alpha < 192 )
2015-10-12 14:10:43 +00:00
dc_transmap = transtables + ( ( tr_trans30 - 1 ) < < FF_TRANSSHIFT ) ;
2014-03-15 16:59:03 +00:00
else if ( pfloor - > alpha < 217 )
2015-10-12 14:10:43 +00:00
dc_transmap = transtables + ( ( tr_trans20 - 1 ) < < FF_TRANSSHIFT ) ;
2014-03-15 16:59:03 +00:00
else if ( pfloor - > alpha < 243 )
2015-10-12 14:10:43 +00:00
dc_transmap = transtables + ( ( tr_trans10 - 1 ) < < FF_TRANSSHIFT ) ;
2014-03-15 16:59:03 +00:00
else
fuzzy = false ; // Opaque
if ( fuzzy )
colfunc = fuzzcolfunc ;
}
else if ( pfloor - > flags & FF_FOG )
colfunc = R_DrawFogColumn_8 ;
2016-03-19 23:19:05 +00:00
range = max ( ds - > x2 - ds - > x1 , 1 ) ;
2014-03-15 16:59:03 +00:00
//SoM: Moved these up here so they are available for my lightlist calculations
rw_scalestep = ds - > scalestep ;
spryscale = ds - > scale1 + ( x1 - ds - > x1 ) * rw_scalestep ;
dc_numlights = 0 ;
if ( frontsector - > numlights )
{
dc_numlights = frontsector - > numlights ;
if ( dc_numlights > dc_maxlights )
{
dc_maxlights = dc_numlights ;
dc_lightlist = Z_Realloc ( dc_lightlist , sizeof ( * dc_lightlist ) * dc_maxlights , PU_STATIC , NULL ) ;
}
for ( i = p = 0 ; i < dc_numlights ; i + + )
{
2016-03-07 20:42:25 +00:00
fixed_t leftheight , rightheight ;
fixed_t pfloorleft , pfloorright ;
2016-05-05 09:31:53 +00:00
INT64 overflow_test ;
2014-03-15 16:59:03 +00:00
light = & frontsector - > lightlist [ i ] ;
rlight = & dc_lightlist [ p ] ;
2016-03-07 20:42:25 +00:00
2018-10-13 17:57:40 +00:00
# define SLOPEPARAMS(slope, end1, end2, normalheight) \
if ( slope ) { \
end1 = P_GetZAt ( slope , ds - > leftpos . x , ds - > leftpos . y ) ; \
end2 = P_GetZAt ( slope , ds - > rightpos . x , ds - > rightpos . y ) ; \
} else \
end1 = end2 = normalheight ;
SLOPEPARAMS ( light - > slope , leftheight , rightheight , light - > height )
SLOPEPARAMS ( * pfloor - > b_slope , pfloorleft , pfloorright , * pfloor - > bottomheight )
2016-03-07 20:42:25 +00:00
if ( leftheight < pfloorleft & & rightheight < pfloorright )
continue ;
2014-03-15 16:59:03 +00:00
2018-10-13 17:57:40 +00:00
SLOPEPARAMS ( * pfloor - > t_slope , pfloorleft , pfloorright , * pfloor - > topheight )
2016-03-07 20:42:25 +00:00
if ( leftheight > pfloorleft & & rightheight > pfloorright & & i + 1 < dc_numlights )
{
lightlist_t * nextlight = & frontsector - > lightlist [ i + 1 ] ;
2019-05-03 15:38:59 +00:00
if ( ( nextlight - > slope ? P_GetZAt ( nextlight - > slope , ds - > leftpos . x , ds - > leftpos . y ) : nextlight - > height ) > pfloorleft
& & ( nextlight - > slope ? P_GetZAt ( nextlight - > slope , ds - > rightpos . x , ds - > rightpos . y ) : nextlight - > height ) > pfloorright )
2016-03-07 20:42:25 +00:00
continue ;
}
leftheight - = viewz ;
rightheight - = viewz ;
2016-05-05 09:31:53 +00:00
2019-03-25 18:54:47 +00:00
# define CLAMPMAX INT32_MAX
# define CLAMPMIN (-INT32_MAX) // This is not INT32_MIN on purpose! INT32_MIN makes the drawers freak out.
// Monster Iestyn (25/03/18): do not skip these lights if they fail overflow test, just clamp them instead so they behave.
overflow_test = ( INT64 ) centeryfrac - ( ( ( INT64 ) leftheight * ds - > scale1 ) > > FRACBITS ) ;
if ( overflow_test > ( INT64 ) CLAMPMAX ) rlight - > height = CLAMPMAX ;
else if ( overflow_test > ( INT64 ) CLAMPMIN ) rlight - > height = ( fixed_t ) overflow_test ;
else rlight - > height = CLAMPMIN ;
overflow_test = ( INT64 ) centeryfrac - ( ( ( INT64 ) rightheight * ds - > scale2 ) > > FRACBITS ) ;
if ( overflow_test > ( INT64 ) CLAMPMAX ) rlight - > heightstep = CLAMPMAX ;
else if ( overflow_test > ( INT64 ) CLAMPMIN ) rlight - > heightstep = ( fixed_t ) overflow_test ;
else rlight - > heightstep = CLAMPMIN ;
2016-03-19 23:19:05 +00:00
rlight - > heightstep = ( rlight - > heightstep - rlight - > height ) / ( range ) ;
2014-03-15 16:59:03 +00:00
rlight - > flags = light - > flags ;
if ( light - > flags & FF_CUTLEVEL )
{
2018-10-13 17:57:40 +00:00
SLOPEPARAMS ( * light - > caster - > b_slope , leftheight , rightheight , * light - > caster - > bottomheight )
2018-11-23 22:40:28 +00:00
# undef SLOPEPARAMS
2016-03-07 20:42:25 +00:00
leftheight - = viewz ;
rightheight - = viewz ;
2019-03-25 18:54:47 +00:00
// Monster Iestyn (25/03/18): do not skip these lights if they fail overflow test, just clamp them instead so they behave.
overflow_test = ( INT64 ) centeryfrac - ( ( ( INT64 ) leftheight * ds - > scale1 ) > > FRACBITS ) ;
if ( overflow_test > ( INT64 ) CLAMPMAX ) rlight - > botheight = CLAMPMAX ;
else if ( overflow_test > ( INT64 ) CLAMPMIN ) rlight - > botheight = ( fixed_t ) overflow_test ;
else rlight - > botheight = CLAMPMIN ;
2016-05-05 09:31:53 +00:00
2019-03-25 18:54:47 +00:00
overflow_test = ( INT64 ) centeryfrac - ( ( ( INT64 ) rightheight * ds - > scale2 ) > > FRACBITS ) ;
if ( overflow_test > ( INT64 ) CLAMPMAX ) rlight - > botheightstep = CLAMPMAX ;
else if ( overflow_test > ( INT64 ) CLAMPMIN ) rlight - > botheightstep = ( fixed_t ) overflow_test ;
else rlight - > botheightstep = CLAMPMIN ;
2016-03-19 23:19:05 +00:00
rlight - > botheightstep = ( rlight - > botheightstep - rlight - > botheight ) / ( range ) ;
2014-03-15 16:59:03 +00:00
}
rlight - > lightlevel = * light - > lightlevel ;
rlight - > extra_colormap = light - > extra_colormap ;
// Check if the current light effects the colormap/lightlevel
if ( pfloor - > flags & FF_FOG )
rlight - > lightnum = ( pfloor - > master - > frontsector - > lightlevel > > LIGHTSEGSHIFT ) ;
else
rlight - > lightnum = ( rlight - > lightlevel > > LIGHTSEGSHIFT ) ;
if ( pfloor - > flags & FF_FOG | | rlight - > flags & FF_FOG | | ( rlight - > extra_colormap & & rlight - > extra_colormap - > fog ) )
;
else if ( curline - > v1 - > y = = curline - > v2 - > y )
rlight - > lightnum - - ;
else if ( curline - > v1 - > x = = curline - > v2 - > x )
rlight - > lightnum + + ;
p + + ;
}
dc_numlights = p ;
}
else
{
// Get correct light level!
if ( ( frontsector - > extra_colormap & & frontsector - > extra_colormap - > fog ) )
lightnum = ( frontsector - > lightlevel > > LIGHTSEGSHIFT ) ;
else if ( pfloor - > flags & FF_FOG )
lightnum = ( pfloor - > master - > frontsector - > lightlevel > > LIGHTSEGSHIFT ) ;
else if ( colfunc = = fuzzcolfunc )
lightnum = LIGHTLEVELS - 1 ;
else
lightnum = R_FakeFlat ( frontsector , & tempsec , & templight , & templight , false )
- > lightlevel > > LIGHTSEGSHIFT ;
if ( pfloor - > flags & FF_FOG | | ( frontsector - > extra_colormap & & frontsector - > extra_colormap - > fog ) ) ;
else if ( curline - > v1 - > y = = curline - > v2 - > y )
lightnum - - ;
else if ( curline - > v1 - > x = = curline - > v2 - > x )
lightnum + + ;
if ( lightnum < 0 )
walllights = scalelight [ 0 ] ;
else if ( lightnum > = LIGHTLEVELS )
walllights = scalelight [ LIGHTLEVELS - 1 ] ;
else
walllights = scalelight [ lightnum ] ;
}
maskedtexturecol = ds - > thicksidecol ;
mfloorclip = ds - > sprbottomclip ;
mceilingclip = ds - > sprtopclip ;
dc_texheight = textureheight [ texnum ] > > FRACBITS ;
2016-08-29 21:42:06 +00:00
// calculate both left ends
if ( * pfloor - > t_slope )
left_top = P_GetZAt ( * pfloor - > t_slope , ds - > leftpos . x , ds - > leftpos . y ) - viewz ;
else
left_top = * pfloor - > topheight - viewz ;
if ( * pfloor - > b_slope )
left_bottom = P_GetZAt ( * pfloor - > b_slope , ds - > leftpos . x , ds - > leftpos . y ) - viewz ;
else
left_bottom = * pfloor - > bottomheight - viewz ;
skewslope = * pfloor - > t_slope ; // skew using top slope by default
2016-08-29 22:24:59 +00:00
if ( newline )
{
if ( newline - > flags & ML_DONTPEGTOP )
slopeskew = true ;
}
2016-08-29 22:21:57 +00:00
else if ( pfloor - > master - > flags & ML_DONTPEGTOP )
slopeskew = true ;
if ( slopeskew )
dc_texturemid = left_top ;
else
dc_texturemid = * pfloor - > topheight - viewz ;
2014-03-15 16:59:03 +00:00
if ( newline )
{
offsetvalue = sides [ newline - > sidenum [ 0 ] ] . rowoffset ;
if ( newline - > flags & ML_DONTPEGBOTTOM )
2016-08-29 21:42:06 +00:00
{
2016-08-29 22:21:57 +00:00
skewslope = * pfloor - > b_slope ; // skew using bottom slope
if ( slopeskew )
dc_texturemid = left_bottom ;
else
offsetvalue - = * pfloor - > topheight - * pfloor - > bottomheight ;
}
2014-03-15 16:59:03 +00:00
}
else
{
offsetvalue = sides [ pfloor - > master - > sidenum [ 0 ] ] . rowoffset ;
if ( curline - > linedef - > flags & ML_DONTPEGBOTTOM )
2016-08-29 21:42:06 +00:00
{
2016-08-29 22:21:57 +00:00
skewslope = * pfloor - > b_slope ; // skew using bottom slope
if ( slopeskew )
dc_texturemid = left_bottom ;
else
offsetvalue - = * pfloor - > topheight - * pfloor - > bottomheight ;
}
2016-08-29 21:42:06 +00:00
}
if ( slopeskew )
{
angle_t lineangle = R_PointToAngle2 ( curline - > v1 - > x , curline - > v1 - > y , curline - > v2 - > x , curline - > v2 - > y ) ;
if ( skewslope )
ffloortextureslide = FixedMul ( skewslope - > zdelta , FINECOSINE ( ( lineangle - skewslope - > xydirection ) > > ANGLETOFINESHIFT ) ) ;
2014-03-15 16:59:03 +00:00
}
dc_texturemid + = offsetvalue ;
2016-12-17 19:59:54 +00:00
// Texture must be cached before setting colfunc_2s,
// otherwise texture[texnum]->holes may be false when it shouldn't be
R_CheckTextureCache ( texnum ) ;
2014-03-15 16:59:03 +00:00
//faB: handle case where multipatch texture is drawn on a 2sided wall, multi-patch textures
// are not stored per-column with post info anymore in Doom Legacy
if ( textures [ texnum ] - > holes )
2014-11-12 00:55:07 +00:00
colfunc_2s = R_DrawRepeatMaskedColumn ; //render the usual 2sided single-patch packed texture
2014-03-15 16:59:03 +00:00
else
{
colfunc_2s = R_Render2sidedMultiPatchColumn ; //render multipatch with no holes (no post_t info)
column2s_length = textures [ texnum ] - > height ;
}
2015-05-17 04:04:54 +00:00
// Set heights according to plane, or slope, whichever
{
2016-08-29 21:42:06 +00:00
fixed_t right_top , right_bottom ;
2015-05-17 04:04:54 +00:00
2016-08-29 21:42:06 +00:00
// calculate right ends now
2016-05-02 12:29:30 +00:00
if ( * pfloor - > t_slope )
right_top = P_GetZAt ( * pfloor - > t_slope , ds - > rightpos . x , ds - > rightpos . y ) - viewz ;
else
2016-08-29 21:42:06 +00:00
right_top = * pfloor - > topheight - viewz ;
2015-05-17 04:04:54 +00:00
2016-05-02 12:29:30 +00:00
if ( * pfloor - > b_slope )
right_bottom = P_GetZAt ( * pfloor - > b_slope , ds - > rightpos . x , ds - > rightpos . y ) - viewz ;
else
2016-08-29 21:42:06 +00:00
right_bottom = * pfloor - > bottomheight - viewz ;
2016-05-02 12:29:30 +00:00
2016-05-05 09:31:53 +00:00
// using INT64 to avoid 32bit overflow
top_frac = ( INT64 ) centeryfrac - ( ( ( INT64 ) left_top * ds - > scale1 ) > > FRACBITS ) ;
bottom_frac = ( INT64 ) centeryfrac - ( ( ( INT64 ) left_bottom * ds - > scale1 ) > > FRACBITS ) ;
top_step = ( INT64 ) centeryfrac - ( ( ( INT64 ) right_top * ds - > scale2 ) > > FRACBITS ) ;
bottom_step = ( INT64 ) centeryfrac - ( ( ( INT64 ) right_bottom * ds - > scale2 ) > > FRACBITS ) ;
2015-05-17 04:04:54 +00:00
2016-03-19 23:19:05 +00:00
top_step = ( top_step - top_frac ) / ( range ) ;
bottom_step = ( bottom_step - bottom_frac ) / ( range ) ;
2015-05-17 04:04:54 +00:00
top_frac + = top_step * ( x1 - ds - > x1 ) ;
bottom_frac + = bottom_step * ( x1 - ds - > x1 ) ;
}
2014-03-15 16:59:03 +00:00
// draw the columns
for ( dc_x = x1 ; dc_x < = x2 ; dc_x + + )
{
if ( maskedtexturecol [ dc_x ] ! = INT16_MAX )
{
2016-08-29 21:42:06 +00:00
if ( ffloortextureslide ) { // skew FOF walls
if ( oldx ! = - 1 )
dc_texturemid + = FixedMul ( ffloortextureslide , ( maskedtexturecol [ oldx ] - maskedtexturecol [ dc_x ] ) < < FRACBITS ) ;
oldx = dc_x ;
}
2018-10-13 14:37:11 +00:00
// Calculate bounds
// clamp the values if necessary to avoid overflows and rendering glitches caused by them
2014-03-15 16:59:03 +00:00
2018-10-13 14:37:11 +00:00
if ( top_frac > ( INT64 ) CLAMPMAX ) sprtopscreen = windowtop = CLAMPMAX ;
else if ( top_frac > ( INT64 ) CLAMPMIN ) sprtopscreen = windowtop = ( fixed_t ) top_frac ;
else sprtopscreen = windowtop = CLAMPMIN ;
if ( bottom_frac > ( INT64 ) CLAMPMAX ) sprbotscreen = windowbottom = CLAMPMAX ;
else if ( bottom_frac > ( INT64 ) CLAMPMIN ) sprbotscreen = windowbottom = ( fixed_t ) bottom_frac ;
else sprbotscreen = windowbottom = CLAMPMIN ;
top_frac + = top_step ;
bottom_frac + = bottom_step ;
2014-03-15 16:59:03 +00:00
2018-10-13 14:37:11 +00:00
// SoM: If column is out of range, why bother with it??
if ( windowbottom < topbounds | | windowtop > bottombounds )
{
if ( dc_numlights )
2014-03-15 16:59:03 +00:00
{
for ( i = 0 ; i < dc_numlights ; i + + )
{
rlight = & dc_lightlist [ i ] ;
rlight - > height + = rlight - > heightstep ;
if ( rlight - > flags & FF_CUTLEVEL )
rlight - > botheight + = rlight - > botheightstep ;
}
}
2018-10-13 14:37:11 +00:00
spryscale + = rw_scalestep ;
continue ;
}
2014-03-15 16:59:03 +00:00
2018-10-13 14:37:11 +00:00
dc_iscale = 0xffffffffu / ( unsigned ) spryscale ;
2014-03-15 16:59:03 +00:00
2018-10-13 14:37:11 +00:00
// Get data for the column
col = ( column_t * ) ( ( UINT8 * ) R_GetColumn ( texnum , maskedtexturecol [ dc_x ] ) - 3 ) ;
// SoM: New code does not rely on R_DrawColumnShadowed_8 which
// will (hopefully) put less strain on the stack.
if ( dc_numlights )
{
lighttable_t * * xwalllights ;
fixed_t height ;
fixed_t bheight = 0 ;
INT32 solid = 0 ;
INT32 lighteffect = 0 ;
2014-03-15 16:59:03 +00:00
for ( i = 0 ; i < dc_numlights ; i + + )
{
// Check if the current light effects the colormap/lightlevel
rlight = & dc_lightlist [ i ] ;
lighteffect = ! ( dc_lightlist [ i ] . flags & FF_NOSHADE ) ;
if ( lighteffect )
{
lightnum = rlight - > lightnum ;
if ( lightnum < 0 )
xwalllights = scalelight [ 0 ] ;
else if ( lightnum > = LIGHTLEVELS )
xwalllights = scalelight [ LIGHTLEVELS - 1 ] ;
else
xwalllights = scalelight [ lightnum ] ;
2016-04-05 14:33:55 +00:00
pindex = FixedMul ( spryscale , FixedDiv ( 640 , vid . width ) ) > > LIGHTSCALESHIFT ;
2014-03-15 16:59:03 +00:00
2018-10-13 14:37:11 +00:00
if ( pindex > = MAXLIGHTSCALE )
2014-03-15 16:59:03 +00:00
pindex = MAXLIGHTSCALE - 1 ;
if ( pfloor - > flags & FF_FOG )
{
if ( pfloor - > master - > frontsector - > extra_colormap )
rlight - > rcolormap = pfloor - > master - > frontsector - > extra_colormap - > colormap + ( xwalllights [ pindex ] - colormaps ) ;
else
rlight - > rcolormap = xwalllights [ pindex ] ;
}
else
{
if ( rlight - > extra_colormap )
rlight - > rcolormap = rlight - > extra_colormap - > colormap + ( xwalllights [ pindex ] - colormaps ) ;
else
rlight - > rcolormap = xwalllights [ pindex ] ;
}
}
2016-04-20 19:26:41 +00:00
solid = 0 ; // don't carry over solid-cutting flag from the previous light
2014-03-15 16:59:03 +00:00
// Check if the current light can cut the current 3D floor.
if ( rlight - > flags & FF_CUTSOLIDS & & ! ( pfloor - > flags & FF_EXTRA ) )
solid = 1 ;
else if ( rlight - > flags & FF_CUTEXTRA & & pfloor - > flags & FF_EXTRA )
{
if ( rlight - > flags & FF_EXTRA )
{
// The light is from an extra 3D floor... Check the flags so
// there are no undesired cuts.
if ( ( rlight - > flags & ( FF_FOG | FF_SWIMMABLE ) ) = = ( pfloor - > flags & ( FF_FOG | FF_SWIMMABLE ) ) )
solid = 1 ;
}
else
solid = 1 ;
}
else
solid = 0 ;
height = rlight - > height ;
2018-10-13 17:57:40 +00:00
rlight - > height + = rlight - > heightstep ;
2014-03-15 16:59:03 +00:00
if ( solid )
{
bheight = rlight - > botheight - ( FRACUNIT > > 1 ) ;
2018-10-13 17:57:40 +00:00
rlight - > botheight + = rlight - > botheightstep ;
2014-03-15 16:59:03 +00:00
}
if ( height < = windowtop )
{
if ( lighteffect )
2018-07-23 22:50:41 +00:00
{
2014-03-15 16:59:03 +00:00
dc_colormap = rlight - > rcolormap ;
2018-08-10 18:31:30 +00:00
if ( encoremap & & ! ( curline - > linedef - > flags & ML_TFERLINE ) )
2018-07-23 22:50:41 +00:00
dc_colormap + = ( 256 * 32 ) ;
}
2014-03-15 16:59:03 +00:00
if ( solid & & windowtop < bheight )
windowtop = bheight ;
continue ;
}
windowbottom = height ;
if ( windowbottom > = sprbotscreen )
{
windowbottom = sprbotscreen ;
2018-10-13 14:37:11 +00:00
// draw the texture
2014-03-15 16:59:03 +00:00
colfunc_2s ( col ) ;
for ( i + + ; i < dc_numlights ; i + + )
{
rlight = & dc_lightlist [ i ] ;
rlight - > height + = rlight - > heightstep ;
if ( rlight - > flags & FF_CUTLEVEL )
rlight - > botheight + = rlight - > botheightstep ;
}
continue ;
}
2018-10-13 14:37:11 +00:00
// draw the texture
2014-03-15 16:59:03 +00:00
colfunc_2s ( col ) ;
if ( solid )
windowtop = bheight ;
else
windowtop = windowbottom + 1 ;
if ( lighteffect )
2018-07-23 22:50:41 +00:00
{
2014-03-15 16:59:03 +00:00
dc_colormap = rlight - > rcolormap ;
2018-08-10 18:31:30 +00:00
if ( encoremap & & ! ( curline - > linedef - > flags & ML_TFERLINE ) )
2018-07-23 22:50:41 +00:00
dc_colormap + = ( 256 * 32 ) ;
}
2014-03-15 16:59:03 +00:00
}
windowbottom = sprbotscreen ;
2018-10-13 14:37:11 +00:00
// draw the texture, if there is any space left
2014-03-15 16:59:03 +00:00
if ( windowtop < windowbottom )
colfunc_2s ( col ) ;
spryscale + = rw_scalestep ;
continue ;
}
// calculate lighting
2016-04-05 14:33:55 +00:00
pindex = FixedMul ( spryscale , FixedDiv ( 640 , vid . width ) ) > > LIGHTSCALESHIFT ;
2014-03-15 16:59:03 +00:00
if ( pindex > = MAXLIGHTSCALE )
pindex = MAXLIGHTSCALE - 1 ;
dc_colormap = walllights [ pindex ] ;
2018-11-19 22:12:26 +00:00
2018-08-10 18:31:30 +00:00
if ( encoremap & & ! ( curline - > linedef - > flags & ML_TFERLINE ) )
2018-07-23 22:50:41 +00:00
dc_colormap + = ( 256 * 32 ) ;
2018-11-29 13:49:50 +00:00
2014-03-15 16:59:03 +00:00
if ( pfloor - > flags & FF_FOG & & pfloor - > master - > frontsector - > extra_colormap )
dc_colormap = pfloor - > master - > frontsector - > extra_colormap - > colormap + ( dc_colormap - colormaps ) ;
2018-11-19 22:12:26 +00:00
else if ( frontsector - > extra_colormap )
dc_colormap = frontsector - > extra_colormap - > colormap + ( dc_colormap - colormaps ) ;
2014-03-15 16:59:03 +00:00
// draw the texture
colfunc_2s ( col ) ;
spryscale + = rw_scalestep ;
}
}
colfunc = wallcolfunc ;
2016-05-05 13:33:19 +00:00
# undef CLAMPMAX
# undef CLAMPMIN
2014-03-15 16:59:03 +00:00
}
//
// R_RenderSegLoop
// Draws zero, one, or two textures (and possibly a masked
// texture) for walls.
// Can draw or mark the starting pixel of floor and ceiling
// textures.
// CALLED: CORE LOOPING ROUTINE.
//
# define HEIGHTBITS 12
# define HEIGHTUNIT (1<<HEIGHTBITS)
//profile stuff ---------------------------------------------------------
//#define TIMING
# ifdef TIMING
# include "p5prof.h"
INT64 mycount ;
INT64 mytotal = 0 ;
UINT32 nombre = 100000 ;
//static char runtest[10][80];
# endif
//profile stuff ---------------------------------------------------------
static void R_RenderSegLoop ( void )
{
angle_t angle ;
size_t pindex ;
INT32 yl ;
INT32 yh ;
INT32 mid ;
fixed_t texturecolumn = 0 ;
2015-05-03 20:47:40 +00:00
fixed_t oldtexturecolumn = - 1 ;
2014-03-15 16:59:03 +00:00
INT32 top ;
INT32 bottom ;
INT32 i ;
for ( ; rw_x < rw_stopx ; rw_x + + )
{
// mark floor / ceiling areas
yl = ( topfrac + HEIGHTUNIT - 1 ) > > HEIGHTBITS ;
// no space above wall?
top = ceilingclip [ rw_x ] + 1 ;
// no space above wall?
if ( yl < top )
yl = top ;
if ( markceiling )
{
bottom = yl - 1 ;
if ( bottom > = floorclip [ rw_x ] )
bottom = floorclip [ rw_x ] - 1 ;
2018-10-07 03:37:27 +00:00
if ( top < = bottom & & ceilingplane )
2014-03-15 16:59:03 +00:00
{
ceilingplane - > top [ rw_x ] = ( INT16 ) top ;
ceilingplane - > bottom [ rw_x ] = ( INT16 ) bottom ;
}
}
yh = bottomfrac > > HEIGHTBITS ;
bottom = floorclip [ rw_x ] - 1 ;
if ( yh > bottom )
yh = bottom ;
if ( markfloor )
{
2018-12-14 17:08:25 +00:00
top = yh < ceilingclip [ rw_x ] ? ceilingclip [ rw_x ] : yh ;
2014-03-15 16:59:03 +00:00
if ( + + top < = bottom & & floorplane )
{
floorplane - > top [ rw_x ] = ( INT16 ) top ;
floorplane - > bottom [ rw_x ] = ( INT16 ) bottom ;
}
}
if ( numffloors )
{
firstseg - > frontscale [ rw_x ] = frontscale [ rw_x ] ;
top = ceilingclip [ rw_x ] + 1 ; // PRBoom
bottom = floorclip [ rw_x ] - 1 ; // PRBoom
for ( i = 0 ; i < numffloors ; i + + )
{
2015-01-01 19:50:31 +00:00
if ( ffloor [ i ] . polyobj & & ( ! curline - > polyseg | | ffloor [ i ] . polyobj ! = curline - > polyseg ) )
continue ;
2014-11-12 00:55:07 +00:00
// FIXME hack to fix planes disappearing when a seg goes behind the camera. This NEEDS to be changed to be done properly. -Red
if ( curline - > polyseg ) {
if ( ffloor [ i ] . plane - > minx > rw_x )
ffloor [ i ] . plane - > minx = rw_x ;
else if ( ffloor [ i ] . plane - > maxx < rw_x )
ffloor [ i ] . plane - > maxx = rw_x ;
}
2014-03-15 16:59:03 +00:00
if ( ffloor [ i ] . height < viewz )
{
INT32 top_w = ( ffloor [ i ] . f_frac > > HEIGHTBITS ) + 1 ;
INT32 bottom_w = ffloor [ i ] . f_clip [ rw_x ] ;
if ( top_w < top )
top_w = top ;
if ( bottom_w > bottom )
bottom_w = bottom ;
2014-11-12 00:55:07 +00:00
// Polyobject-specific hack to fix plane leaking -Red
if ( curline - > polyseg & & ffloor [ i ] . polyobj & & ffloor [ i ] . polyobj = = curline - > polyseg & & top_w > = bottom_w ) {
ffloor [ i ] . plane - > top [ rw_x ] = ffloor [ i ] . plane - > bottom [ rw_x ] = 0xFFFF ;
} else
2014-03-15 16:59:03 +00:00
if ( top_w < = bottom_w )
{
ffloor [ i ] . plane - > top [ rw_x ] = ( INT16 ) top_w ;
ffloor [ i ] . plane - > bottom [ rw_x ] = ( INT16 ) bottom_w ;
}
}
else if ( ffloor [ i ] . height > viewz )
{
INT32 top_w = ffloor [ i ] . c_clip [ rw_x ] + 1 ;
INT32 bottom_w = ( ffloor [ i ] . f_frac > > HEIGHTBITS ) ;
if ( top_w < top )
top_w = top ;
if ( bottom_w > bottom )
bottom_w = bottom ;
2014-11-12 00:55:07 +00:00
// Polyobject-specific hack to fix plane leaking -Red
if ( curline - > polyseg & & ffloor [ i ] . polyobj & & ffloor [ i ] . polyobj = = curline - > polyseg & & top_w > = bottom_w ) {
ffloor [ i ] . plane - > top [ rw_x ] = ffloor [ i ] . plane - > bottom [ rw_x ] = 0xFFFF ;
} else
2014-03-15 16:59:03 +00:00
if ( top_w < = bottom_w )
{
ffloor [ i ] . plane - > top [ rw_x ] = ( INT16 ) top_w ;
ffloor [ i ] . plane - > bottom [ rw_x ] = ( INT16 ) bottom_w ;
}
}
}
}
//SoM: Calculate offsets for Thick fake floors.
// calculate texture offset
angle = ( rw_centerangle + xtoviewangle [ rw_x ] ) > > ANGLETOFINESHIFT ;
texturecolumn = rw_offset - FixedMul ( FINETANGENT ( angle ) , rw_distance ) ;
2015-05-03 20:47:40 +00:00
if ( oldtexturecolumn ! = - 1 ) {
2015-05-04 20:15:57 +00:00
rw_bottomtexturemid + = FixedMul ( rw_bottomtextureslide , oldtexturecolumn - texturecolumn ) ;
rw_midtexturemid + = FixedMul ( rw_midtextureslide , oldtexturecolumn - texturecolumn ) ;
rw_toptexturemid + = FixedMul ( rw_toptextureslide , oldtexturecolumn - texturecolumn ) ;
rw_midtextureback + = FixedMul ( rw_midtexturebackslide , oldtexturecolumn - texturecolumn ) ;
2015-05-03 20:47:40 +00:00
}
oldtexturecolumn = texturecolumn ;
2014-03-15 16:59:03 +00:00
texturecolumn > > = FRACBITS ;
// texturecolumn and lighting are independent of wall tiers
if ( segtextured )
{
// calculate lighting
2015-01-01 19:50:31 +00:00
pindex = FixedMul ( rw_scale , FixedDiv ( 640 , vid . width ) ) > > LIGHTSCALESHIFT ;
2014-03-15 16:59:03 +00:00
if ( pindex > = MAXLIGHTSCALE )
pindex = MAXLIGHTSCALE - 1 ;
dc_colormap = walllights [ pindex ] ;
2018-08-10 18:31:30 +00:00
if ( encoremap & & ! ( curline - > linedef - > flags & ML_TFERLINE ) )
2018-07-23 22:50:41 +00:00
dc_colormap + = ( 256 * 32 ) ;
2014-03-15 16:59:03 +00:00
dc_x = rw_x ;
dc_iscale = 0xffffffffu / ( unsigned ) rw_scale ;
if ( frontsector - > extra_colormap )
dc_colormap = frontsector - > extra_colormap - > colormap + ( dc_colormap - colormaps ) ;
}
if ( dc_numlights )
{
lighttable_t * * xwalllights ;
for ( i = 0 ; i < dc_numlights ; i + + )
{
INT32 lightnum ;
lightnum = ( dc_lightlist [ i ] . lightlevel > > LIGHTSEGSHIFT ) ;
if ( dc_lightlist [ i ] . extra_colormap )
;
else if ( curline - > v1 - > y = = curline - > v2 - > y )
lightnum - - ;
else if ( curline - > v1 - > x = = curline - > v2 - > x )
lightnum + + ;
if ( lightnum < 0 )
xwalllights = scalelight [ 0 ] ;
else if ( lightnum > = LIGHTLEVELS )
xwalllights = scalelight [ LIGHTLEVELS - 1 ] ;
else
xwalllights = scalelight [ lightnum ] ;
2015-01-01 19:50:31 +00:00
pindex = FixedMul ( rw_scale , FixedDiv ( 640 , vid . width ) ) > > LIGHTSCALESHIFT ;
2014-03-15 16:59:03 +00:00
if ( pindex > = MAXLIGHTSCALE )
pindex = MAXLIGHTSCALE - 1 ;
if ( dc_lightlist [ i ] . extra_colormap )
dc_lightlist [ i ] . rcolormap = dc_lightlist [ i ] . extra_colormap - > colormap + ( xwalllights [ pindex ] - colormaps ) ;
else
dc_lightlist [ i ] . rcolormap = xwalllights [ pindex ] ;
colfunc = R_DrawColumnShadowed_8 ;
}
}
frontscale [ rw_x ] = rw_scale ;
// draw the wall tiers
2016-05-30 20:53:29 +00:00
if ( midtexture )
2014-03-15 16:59:03 +00:00
{
// single sided line
2016-05-30 20:53:29 +00:00
if ( yl < = yh & & yh > = 0 & & yl < viewheight )
{
dc_yl = yl ;
dc_yh = yh ;
dc_texturemid = rw_midtexturemid ;
dc_source = R_GetColumn ( midtexture , texturecolumn ) ;
dc_texheight = textureheight [ midtexture ] > > FRACBITS ;
2014-03-15 16:59:03 +00:00
2016-05-30 20:53:29 +00:00
//profile stuff ---------------------------------------------------------
2014-03-15 16:59:03 +00:00
# ifdef TIMING
2016-05-30 20:53:29 +00:00
ProfZeroTimer ( ) ;
2014-03-15 16:59:03 +00:00
# endif
2016-05-30 20:53:29 +00:00
colfunc ( ) ;
2014-03-15 16:59:03 +00:00
# ifdef TIMING
2016-05-30 20:53:29 +00:00
RDMSR ( 0x10 , & mycount ) ;
mytotal + = mycount ; //64bit add
2014-03-15 16:59:03 +00:00
2016-05-30 20:53:29 +00:00
if ( nombre - - = = 0 )
I_Error ( " R_DrawColumn CPU Spy reports: 0x%d %d \n " , * ( ( INT32 * ) & mytotal + 1 ) ,
( INT32 ) mytotal ) ;
2014-03-15 16:59:03 +00:00
# endif
2016-05-30 20:53:29 +00:00
//profile stuff ---------------------------------------------------------
2014-03-15 16:59:03 +00:00
2016-05-30 20:53:29 +00:00
// dont draw anything more for this column, since
// a midtexture blocks the view
ceilingclip [ rw_x ] = ( INT16 ) viewheight ;
floorclip [ rw_x ] = - 1 ;
}
else
{
2016-05-31 15:08:29 +00:00
// note: don't use min/max macros, since casting from INT32 to INT16 is involved here
2016-05-30 21:53:22 +00:00
if ( markceiling )
2016-07-20 14:11:36 +00:00
ceilingclip [ rw_x ] = ( yl > = 0 ) ? ( ( yl > viewheight ) ? ( INT16 ) viewheight : ( INT16 ) ( ( INT16 ) yl - 1 ) ) : - 1 ;
2016-05-31 15:08:29 +00:00
if ( markfloor )
floorclip [ rw_x ] = ( yh < viewheight ) ? ( ( yh < - 1 ) ? - 1 : ( INT16 ) ( ( INT16 ) yh + 1 ) ) : ( INT16 ) viewheight ;
2016-05-30 20:53:29 +00:00
}
2014-03-15 16:59:03 +00:00
}
else
{
// two sided line
if ( toptexture )
{
// top wall
mid = pixhigh > > HEIGHTBITS ;
pixhigh + = pixhighstep ;
if ( mid > = floorclip [ rw_x ] )
mid = floorclip [ rw_x ] - 1 ;
2016-05-31 15:08:29 +00:00
if ( mid > = yl ) // back ceiling lower than front ceiling ?
2014-03-15 16:59:03 +00:00
{
2016-05-31 15:08:29 +00:00
if ( yl > = viewheight ) // entirely off bottom of screen
ceilingclip [ rw_x ] = ( INT16 ) viewheight ;
else if ( mid > = 0 ) // safe to draw top texture
2016-05-30 20:53:29 +00:00
{
dc_yl = yl ;
dc_yh = mid ;
dc_texturemid = rw_toptexturemid ;
dc_source = R_GetColumn ( toptexture , texturecolumn ) ;
dc_texheight = textureheight [ toptexture ] > > FRACBITS ;
colfunc ( ) ;
ceilingclip [ rw_x ] = ( INT16 ) mid ;
}
2016-05-31 15:08:29 +00:00
else // entirely off top of screen
2016-05-30 21:53:22 +00:00
ceilingclip [ rw_x ] = - 1 ;
2014-03-15 16:59:03 +00:00
}
else
2016-07-20 14:11:36 +00:00
ceilingclip [ rw_x ] = ( yl > = 0 ) ? ( ( yl > viewheight ) ? ( INT16 ) viewheight : ( INT16 ) ( ( INT16 ) yl - 1 ) ) : - 1 ;
2014-03-15 16:59:03 +00:00
}
else if ( markceiling ) // no top wall
2016-07-20 14:11:36 +00:00
ceilingclip [ rw_x ] = ( yl > = 0 ) ? ( ( yl > viewheight ) ? ( INT16 ) viewheight : ( INT16 ) ( ( INT16 ) yl - 1 ) ) : - 1 ;
2014-03-15 16:59:03 +00:00
if ( bottomtexture )
{
// bottom wall
mid = ( pixlow + HEIGHTUNIT - 1 ) > > HEIGHTBITS ;
pixlow + = pixlowstep ;
// no space above wall?
if ( mid < = ceilingclip [ rw_x ] )
mid = ceilingclip [ rw_x ] + 1 ;
2016-05-31 15:08:29 +00:00
if ( mid < = yh ) // back floor higher than front floor ?
2014-03-15 16:59:03 +00:00
{
2016-05-31 15:08:29 +00:00
if ( yh < 0 ) // entirely off top of screen
floorclip [ rw_x ] = - 1 ;
else if ( mid < viewheight ) // safe to draw bottom texture
2016-05-30 20:53:29 +00:00
{
dc_yl = mid ;
dc_yh = yh ;
dc_texturemid = rw_bottomtexturemid ;
dc_source = R_GetColumn ( bottomtexture ,
texturecolumn ) ;
dc_texheight = textureheight [ bottomtexture ] > > FRACBITS ;
colfunc ( ) ;
floorclip [ rw_x ] = ( INT16 ) mid ;
}
2016-05-31 15:08:29 +00:00
else // entirely off bottom of screen
2016-05-30 21:53:22 +00:00
floorclip [ rw_x ] = ( INT16 ) viewheight ;
2014-03-15 16:59:03 +00:00
}
else
2016-05-31 15:08:29 +00:00
floorclip [ rw_x ] = ( yh < viewheight ) ? ( ( yh < - 1 ) ? - 1 : ( INT16 ) ( ( INT16 ) yh + 1 ) ) : ( INT16 ) viewheight ;
2014-03-15 16:59:03 +00:00
}
else if ( markfloor ) // no bottom wall
2016-05-31 15:08:29 +00:00
floorclip [ rw_x ] = ( yh < viewheight ) ? ( ( yh < - 1 ) ? - 1 : ( INT16 ) ( ( INT16 ) yh + 1 ) ) : ( INT16 ) viewheight ;
2014-03-15 16:59:03 +00:00
}
if ( maskedtexture | | numthicksides )
{
// save texturecol
// for backdrawing of masked mid texture
maskedtexturecol [ rw_x ] = ( INT16 ) texturecolumn ;
2015-05-04 20:15:57 +00:00
2015-05-04 21:40:02 +00:00
if ( maskedtextureheight ! = NULL ) {
2015-05-04 22:45:02 +00:00
maskedtextureheight [ rw_x ] = ( ! ! ( curline - > linedef - > flags & ML_DONTPEGBOTTOM ) ^ ! ! ( curline - > linedef - > flags & ML_EFFECT3 ) ?
2015-05-04 20:15:57 +00:00
max ( rw_midtexturemid , rw_midtextureback ) :
min ( rw_midtexturemid , rw_midtextureback ) ) ;
}
2014-03-15 16:59:03 +00:00
}
if ( dc_numlights )
{
for ( i = 0 ; i < dc_numlights ; i + + )
{
dc_lightlist [ i ] . height + = dc_lightlist [ i ] . heightstep ;
2016-04-20 17:04:51 +00:00
if ( dc_lightlist [ i ] . flags & FF_CUTSOLIDS )
2014-03-15 16:59:03 +00:00
dc_lightlist [ i ] . botheight + = dc_lightlist [ i ] . botheightstep ;
}
}
for ( i = 0 ; i < numffloors ; i + + )
ffloor [ i ] . f_frac + = ffloor [ i ] . f_step ;
for ( i = 0 ; i < numbackffloors ; i + + )
{
2018-12-14 17:08:25 +00:00
ffloor [ i ] . f_clip [ rw_x ] = ffloor [ i ] . c_clip [ rw_x ] = ( INT16 ) ( ( ffloor [ i ] . b_frac > > HEIGHTBITS ) & 0xFFFF ) ;
2014-03-15 16:59:03 +00:00
ffloor [ i ] . b_frac + = ffloor [ i ] . b_step ;
}
rw_scale + = rw_scalestep ;
topfrac + = topstep ;
bottomfrac + = bottomstep ;
}
}
2018-12-09 22:34:17 +00:00
// Uses precalculated seg->length
static INT64 R_CalcSegDist ( seg_t * seg , INT64 x2 , INT64 y2 )
{
if ( ! seg - > linedef - > dy )
2018-12-20 19:15:19 +00:00
return llabs ( y2 - seg - > v1 - > y ) ;
2018-12-09 22:34:17 +00:00
else if ( ! seg - > linedef - > dx )
2018-12-20 19:15:19 +00:00
return llabs ( x2 - seg - > v1 - > x ) ;
2018-12-09 22:34:17 +00:00
else
{
INT64 dx = ( seg - > v2 - > x ) - ( seg - > v1 - > x ) ;
INT64 dy = ( seg - > v2 - > y ) - ( seg - > v1 - > y ) ;
INT64 vdx = x2 - ( seg - > v1 - > x ) ;
INT64 vdy = y2 - ( seg - > v1 - > y ) ;
return ( ( dy * vdx ) - ( dx * vdy ) ) / ( seg - > length ) ;
}
}
2014-03-15 16:59:03 +00:00
//
// R_StoreWallRange
// A wall segment will be drawn
// between start and stop pixels (inclusive).
//
void R_StoreWallRange ( INT32 start , INT32 stop )
{
fixed_t hyp ;
fixed_t sineval ;
angle_t distangle , offsetangle ;
2018-12-09 22:34:17 +00:00
boolean longboi ;
2014-03-15 16:59:03 +00:00
INT32 lightnum ;
INT32 i , p ;
lightlist_t * light ;
r_lightlist_t * rlight ;
2016-03-19 23:19:05 +00:00
INT32 range ;
2015-04-20 03:20:54 +00:00
vertex_t segleft , segright ;
2015-05-03 20:47:40 +00:00
fixed_t ceilingfrontslide , floorfrontslide , ceilingbackslide , floorbackslide ;
2014-03-15 16:59:03 +00:00
static size_t maxdrawsegs = 0 ;
2016-03-19 22:25:49 +00:00
maskedtextureheight = NULL ;
2015-10-10 16:57:35 +00:00
//initialize segleft and segright
memset ( & segleft , 0x00 , sizeof ( segleft ) ) ;
memset ( & segright , 0x00 , sizeof ( segright ) ) ;
2014-03-15 16:59:03 +00:00
if ( ds_p = = drawsegs + maxdrawsegs )
{
size_t pos = ds_p - drawsegs ;
size_t newmax = maxdrawsegs ? maxdrawsegs * 2 : 128 ;
if ( firstseg )
firstseg = ( drawseg_t * ) ( firstseg - drawsegs ) ;
drawsegs = Z_Realloc ( drawsegs , newmax * sizeof ( * drawsegs ) , PU_STATIC , NULL ) ;
ds_p = drawsegs + pos ;
maxdrawsegs = newmax ;
if ( firstseg )
firstseg = drawsegs + ( size_t ) firstseg ;
}
sidedef = curline - > sidedef ;
linedef = curline - > linedef ;
// calculate rw_distance for scale calculation
rw_normalangle = curline - > angle + ANGLE_90 ;
offsetangle = abs ( ( INT32 ) ( rw_normalangle - rw_angle1 ) ) ;
if ( offsetangle > ANGLE_90 )
offsetangle = ANGLE_90 ;
distangle = ANGLE_90 - offsetangle ;
sineval = FINESINE ( distangle > > ANGLETOFINESHIFT ) ;
2018-12-09 22:34:17 +00:00
hyp = R_PointToDist ( curline - > v1 - > x , curline - > v1 - > y ) ;
rw_distance = FixedMul ( hyp , sineval ) ;
longboi = ( hyp > = INT32_MAX ) ;
// big room fix
if ( longboi )
rw_distance = ( fixed_t ) R_CalcSegDist ( curline , viewx , viewy ) ;
2014-03-15 16:59:03 +00:00
ds_p - > x1 = rw_x = start ;
ds_p - > x2 = stop ;
ds_p - > curline = curline ;
rw_stopx = stop + 1 ;
//SoM: Code to remove limits on openings.
{
size_t pos = lastopening - openings ;
size_t need = ( rw_stopx - start ) * 4 + pos ;
if ( need > maxopenings )
{
drawseg_t * ds ; //needed for fix from *cough* zdoom *cough*
INT16 * oldopenings = openings ;
INT16 * oldlast = lastopening ;
do
maxopenings = maxopenings ? maxopenings * 2 : 16384 ;
while ( need > maxopenings ) ;
openings = Z_Realloc ( openings , maxopenings * sizeof ( * openings ) , PU_STATIC , NULL ) ;
lastopening = openings + pos ;
// borrowed fix from *cough* zdoom *cough*
// [RH] We also need to adjust the openings pointers that
// were already stored in drawsegs.
for ( ds = drawsegs ; ds < ds_p ; ds + + )
{
# define ADJUST(p) if (ds->p + ds->x1 >= oldopenings && ds->p + ds->x1 <= oldlast) ds->p = ds->p - oldopenings + openings;
ADJUST ( maskedtexturecol ) ;
ADJUST ( sprtopclip ) ;
ADJUST ( sprbottomclip ) ;
ADJUST ( thicksidecol ) ;
# undef ADJUST
}
}
} // end of code to remove limits on openings
// calculate scale at both ends and step
ds_p - > scale1 = rw_scale = R_ScaleFromGlobalAngle ( viewangle + xtoviewangle [ start ] ) ;
if ( stop > start )
{
ds_p - > scale2 = R_ScaleFromGlobalAngle ( viewangle + xtoviewangle [ stop ] ) ;
2016-03-19 23:19:05 +00:00
range = stop - start ;
2014-03-15 16:59:03 +00:00
}
else
{
// UNUSED: try to fix the stretched line bug
#if 0
if ( rw_distance < FRACUNIT / 2 )
{
fixed_t tr_x , tr_y ;
fixed_t gxt , gyt ;
CONS_Debug ( DBG_RENDER , " TRYING TO FIX THE STRETCHED ETC \n " ) ;
tr_x = curline - > v1 - > x - viewx ;
tr_y = curline - > v1 - > y - viewy ;
gxt = FixedMul ( tr_x , viewcos ) ;
gyt = - FixedMul ( tr_y , viewsin ) ;
ds_p - > scale1 = FixedDiv ( projection , gxt - gyt ) ;
}
# endif
ds_p - > scale2 = ds_p - > scale1 ;
2016-03-19 23:19:05 +00:00
range = 1 ;
2014-03-15 16:59:03 +00:00
}
2016-03-19 23:19:05 +00:00
ds_p - > scalestep = rw_scalestep = ( ds_p - > scale2 - rw_scale ) / ( range ) ;
2014-03-15 16:59:03 +00:00
// calculate texture boundaries
// and decide if floor / ceiling marks are needed
2015-04-20 03:20:54 +00:00
// Figure out map coordinates of where start and end are mapping to on seg, so we can clip right for slope bullshit
2015-05-17 04:55:49 +00:00
if ( frontsector - > hasslope | | ( backsector & & backsector - > hasslope ) ) // Commenting this out for FOFslop. -Red
2015-05-17 03:32:12 +00:00
{
2015-04-20 03:20:54 +00:00
angle_t temp ;
// left
temp = xtoviewangle [ start ] + viewangle ;
2015-04-30 05:41:29 +00:00
{
2015-04-20 03:20:54 +00:00
// Both lines can be written in slope-intercept form, so figure out line intersection
float a1 , b1 , c1 , a2 , b2 , c2 , det ; // 1 is the seg, 2 is the view angle vector...
2015-04-30 05:41:29 +00:00
///TODO: convert to FPU
2015-04-20 03:20:54 +00:00
a1 = FIXED_TO_FLOAT ( curline - > v2 - > y - curline - > v1 - > y ) ;
b1 = FIXED_TO_FLOAT ( curline - > v1 - > x - curline - > v2 - > x ) ;
c1 = a1 * FIXED_TO_FLOAT ( curline - > v1 - > x ) + b1 * FIXED_TO_FLOAT ( curline - > v1 - > y ) ;
a2 = - FIXED_TO_FLOAT ( FINESINE ( temp > > ANGLETOFINESHIFT ) ) ;
b2 = FIXED_TO_FLOAT ( FINECOSINE ( temp > > ANGLETOFINESHIFT ) ) ;
c2 = a2 * FIXED_TO_FLOAT ( viewx ) + b2 * FIXED_TO_FLOAT ( viewy ) ;
det = a1 * b2 - a2 * b1 ;
2015-05-17 04:04:54 +00:00
ds_p - > leftpos . x = segleft . x = FLOAT_TO_FIXED ( ( b2 * c1 - b1 * c2 ) / det ) ;
ds_p - > leftpos . y = segleft . y = FLOAT_TO_FIXED ( ( a1 * c2 - a2 * c1 ) / det ) ;
2015-04-20 03:20:54 +00:00
}
// right
temp = xtoviewangle [ stop ] + viewangle ;
2015-04-30 05:41:29 +00:00
{
2015-04-20 03:20:54 +00:00
// Both lines can be written in slope-intercept form, so figure out line intersection
float a1 , b1 , c1 , a2 , b2 , c2 , det ; // 1 is the seg, 2 is the view angle vector...
2015-04-30 05:41:29 +00:00
///TODO: convert to FPU
2015-04-20 03:20:54 +00:00
a1 = FIXED_TO_FLOAT ( curline - > v2 - > y - curline - > v1 - > y ) ;
b1 = FIXED_TO_FLOAT ( curline - > v1 - > x - curline - > v2 - > x ) ;
c1 = a1 * FIXED_TO_FLOAT ( curline - > v1 - > x ) + b1 * FIXED_TO_FLOAT ( curline - > v1 - > y ) ;
a2 = - FIXED_TO_FLOAT ( FINESINE ( temp > > ANGLETOFINESHIFT ) ) ;
b2 = FIXED_TO_FLOAT ( FINECOSINE ( temp > > ANGLETOFINESHIFT ) ) ;
c2 = a2 * FIXED_TO_FLOAT ( viewx ) + b2 * FIXED_TO_FLOAT ( viewy ) ;
det = a1 * b2 - a2 * b1 ;
2015-05-17 04:04:54 +00:00
ds_p - > rightpos . x = segright . x = FLOAT_TO_FIXED ( ( b2 * c1 - b1 * c2 ) / det ) ;
ds_p - > rightpos . y = segright . y = FLOAT_TO_FIXED ( ( a1 * c2 - a2 * c1 ) / det ) ;
2015-04-20 03:20:54 +00:00
}
}
if ( frontsector - > c_slope ) {
worldtop = P_GetZAt ( frontsector - > c_slope , segleft . x , segleft . y ) - viewz ;
worldtopslope = P_GetZAt ( frontsector - > c_slope , segright . x , segright . y ) - viewz ;
} else {
worldtopslope =
worldtop = frontsector - > ceilingheight - viewz ;
}
if ( frontsector - > f_slope ) {
worldbottom = P_GetZAt ( frontsector - > f_slope , segleft . x , segleft . y ) - viewz ;
worldbottomslope = P_GetZAt ( frontsector - > f_slope , segright . x , segright . y ) - viewz ;
} else {
worldbottomslope =
worldbottom = frontsector - > floorheight - viewz ;
}
2014-03-15 16:59:03 +00:00
midtexture = toptexture = bottomtexture = maskedtexture = 0 ;
ds_p - > maskedtexturecol = NULL ;
ds_p - > numthicksides = numthicksides = 0 ;
ds_p - > thicksidecol = NULL ;
ds_p - > tsilheight = 0 ;
numbackffloors = 0 ;
for ( i = 0 ; i < MAXFFLOORS ; i + + )
ds_p - > thicksides [ i ] = NULL ;
if ( numffloors )
{
for ( i = 0 ; i < numffloors ; i + + )
{
2015-01-01 19:50:31 +00:00
if ( ffloor [ i ] . polyobj & & ( ! ds_p - > curline - > polyseg | | ffloor [ i ] . polyobj ! = ds_p - > curline - > polyseg ) )
continue ;
2015-05-17 03:32:12 +00:00
if ( ffloor [ i ] . slope ) {
ffloor [ i ] . f_pos = P_GetZAt ( ffloor [ i ] . slope , segleft . x , segleft . y ) - viewz ;
ffloor [ i ] . f_pos_slope = P_GetZAt ( ffloor [ i ] . slope , segright . x , segright . y ) - viewz ;
} else
ffloor [ i ] . f_pos_slope =
2014-03-15 16:59:03 +00:00
ffloor [ i ] . f_pos = ffloor [ i ] . height - viewz ;
}
}
2015-05-03 20:47:40 +00:00
// Set up texture Y offset slides for sloped walls
rw_toptextureslide = rw_midtextureslide = rw_bottomtextureslide = 0 ;
ceilingfrontslide = floorfrontslide = ceilingbackslide = floorbackslide = 0 ;
{
angle_t lineangle = R_PointToAngle2 ( curline - > v1 - > x , curline - > v1 - > y , curline - > v2 - > x , curline - > v2 - > y ) ;
if ( frontsector - > f_slope )
floorfrontslide = FixedMul ( frontsector - > f_slope - > zdelta , FINECOSINE ( ( lineangle - frontsector - > f_slope - > xydirection ) > > ANGLETOFINESHIFT ) ) ;
if ( frontsector - > c_slope )
ceilingfrontslide = FixedMul ( frontsector - > c_slope - > zdelta , FINECOSINE ( ( lineangle - frontsector - > c_slope - > xydirection ) > > ANGLETOFINESHIFT ) ) ;
if ( backsector & & backsector - > f_slope )
floorbackslide = FixedMul ( backsector - > f_slope - > zdelta , FINECOSINE ( ( lineangle - backsector - > f_slope - > xydirection ) > > ANGLETOFINESHIFT ) ) ;
if ( backsector & & backsector - > c_slope )
ceilingbackslide = FixedMul ( backsector - > c_slope - > zdelta , FINECOSINE ( ( lineangle - backsector - > c_slope - > xydirection ) > > ANGLETOFINESHIFT ) ) ;
}
2014-03-15 16:59:03 +00:00
if ( ! backsector )
{
2016-12-16 21:38:53 +00:00
fixed_t texheight ;
2014-03-15 16:59:03 +00:00
// single sided line
2016-12-16 21:38:53 +00:00
midtexture = R_GetTextureNum ( sidedef - > midtexture ) ;
texheight = textureheight [ midtexture ] ;
2014-03-15 16:59:03 +00:00
// a single sided line is terminal, so it must mark ends
markfloor = markceiling = true ;
2016-06-12 17:47:27 +00:00
if ( linedef - > flags & ML_EFFECT2 ) {
2015-05-04 22:45:02 +00:00
if ( linedef - > flags & ML_DONTPEGBOTTOM )
2016-12-16 21:38:53 +00:00
rw_midtexturemid = frontsector - > floorheight + texheight - viewz ;
2015-05-04 22:45:02 +00:00
else
2016-06-09 19:37:36 +00:00
rw_midtexturemid = frontsector - > ceilingheight - viewz ;
2015-05-04 22:45:02 +00:00
}
2016-06-09 19:37:36 +00:00
else
2014-03-15 16:59:03 +00:00
if ( linedef - > flags & ML_DONTPEGBOTTOM )
{
2016-12-16 21:38:53 +00:00
rw_midtexturemid = worldbottom + texheight ;
2015-05-03 20:47:40 +00:00
rw_midtextureslide = floorfrontslide ;
2014-03-15 16:59:03 +00:00
}
else
{
// top of texture at top
rw_midtexturemid = worldtop ;
2015-05-03 20:47:40 +00:00
rw_midtextureslide = ceilingfrontslide ;
2014-03-15 16:59:03 +00:00
}
rw_midtexturemid + = sidedef - > rowoffset ;
ds_p - > silhouette = SIL_BOTH ;
ds_p - > sprtopclip = screenheightarray ;
ds_p - > sprbottomclip = negonearray ;
ds_p - > bsilheight = INT32_MAX ;
ds_p - > tsilheight = INT32_MIN ;
}
else
{
// two sided line
2015-04-30 05:38:51 +00:00
if ( backsector - > c_slope ) {
worldhigh = P_GetZAt ( backsector - > c_slope , segleft . x , segleft . y ) - viewz ;
worldhighslope = P_GetZAt ( backsector - > c_slope , segright . x , segright . y ) - viewz ;
} else {
worldhighslope =
worldhigh = backsector - > ceilingheight - viewz ;
}
if ( backsector - > f_slope ) {
worldlow = P_GetZAt ( backsector - > f_slope , segleft . x , segleft . y ) - viewz ;
worldlowslope = P_GetZAt ( backsector - > f_slope , segright . x , segright . y ) - viewz ;
} else {
worldlowslope =
worldlow = backsector - > floorheight - viewz ;
}
// hack to allow height changes in outdoor areas
if ( frontsector - > ceilingpic = = skyflatnum
& & backsector - > ceilingpic = = skyflatnum )
{
2016-05-03 14:26:54 +00:00
worldtopslope = worldhighslope =
worldtop = worldhigh ;
2015-04-30 05:38:51 +00:00
}
2014-03-15 16:59:03 +00:00
ds_p - > sprtopclip = ds_p - > sprbottomclip = NULL ;
ds_p - > silhouette = 0 ;
2015-04-30 05:38:51 +00:00
if (
worldbottomslope > worldlowslope | |
worldbottom > worldlow )
2014-03-15 16:59:03 +00:00
{
ds_p - > silhouette = SIL_BOTTOM ;
2016-03-12 19:59:32 +00:00
if ( ( backsector - > f_slope ? P_GetZAt ( backsector - > f_slope , viewx , viewy ) : backsector - > floorheight ) > viewz )
ds_p - > bsilheight = INT32_MAX ;
else
ds_p - > bsilheight = ( frontsector - > f_slope ? INT32_MAX : frontsector - > floorheight ) ;
2014-03-15 16:59:03 +00:00
}
2015-04-30 05:38:51 +00:00
else if ( ( backsector - > f_slope ? P_GetZAt ( backsector - > f_slope , viewx , viewy ) : backsector - > floorheight ) > viewz )
2014-03-15 16:59:03 +00:00
{
ds_p - > silhouette = SIL_BOTTOM ;
ds_p - > bsilheight = INT32_MAX ;
// ds_p->sprbottomclip = negonearray;
}
2015-04-30 05:38:51 +00:00
if (
worldtopslope < worldhighslope | |
worldtop < worldhigh )
2014-03-15 16:59:03 +00:00
{
ds_p - > silhouette | = SIL_TOP ;
2016-03-12 19:59:32 +00:00
if ( ( backsector - > c_slope ? P_GetZAt ( backsector - > c_slope , viewx , viewy ) : backsector - > ceilingheight ) < viewz )
ds_p - > tsilheight = INT32_MIN ;
else
ds_p - > tsilheight = ( frontsector - > c_slope ? INT32_MIN : frontsector - > ceilingheight ) ;
2014-03-15 16:59:03 +00:00
}
2015-04-30 05:38:51 +00:00
else if ( ( backsector - > c_slope ? P_GetZAt ( backsector - > c_slope , viewx , viewy ) : backsector - > ceilingheight ) < viewz )
2014-03-15 16:59:03 +00:00
{
ds_p - > silhouette | = SIL_TOP ;
ds_p - > tsilheight = INT32_MIN ;
// ds_p->sprtopclip = screenheightarray;
}
2018-10-07 03:37:27 +00:00
if ( viewsector ! = frontsector & & viewsector ! = backsector )
2014-03-15 16:59:03 +00:00
{
2018-10-06 20:22:36 +00:00
if ( worldhigh < = worldbottom & & worldhighslope < = worldbottomslope )
2014-03-15 16:59:03 +00:00
{
ds_p - > sprbottomclip = negonearray ;
ds_p - > bsilheight = INT32_MAX ;
ds_p - > silhouette | = SIL_BOTTOM ;
}
2018-10-06 20:22:36 +00:00
if ( worldlow > = worldtop & & worldlowslope > = worldtopslope )
{
2014-03-15 16:59:03 +00:00
ds_p - > sprtopclip = screenheightarray ;
ds_p - > tsilheight = INT32_MIN ;
ds_p - > silhouette | = SIL_TOP ;
}
2018-10-06 20:22:36 +00:00
//SoM: 3/25/2000: This code fixes an automap bug that didn't check
// frontsector->ceiling and backsector->floor to see if a door was closed.
// Without the following code, sprites get displayed behind closed doors.
{
if ( doorclosed | | ( worldhigh < = worldbottom & & worldhighslope < = worldbottomslope ) )
{
ds_p - > sprbottomclip = negonearray ;
ds_p - > bsilheight = INT32_MAX ;
ds_p - > silhouette | = SIL_BOTTOM ;
}
if ( doorclosed | | ( worldlow > = worldtop & & worldlowslope > = worldtopslope ) )
{ // killough 1/17/98, 2/8/98
ds_p - > sprtopclip = screenheightarray ;
ds_p - > tsilheight = INT32_MIN ;
ds_p - > silhouette | = SIL_TOP ;
}
}
2014-03-15 16:59:03 +00:00
}
if ( worldlow ! = worldbottom
2015-04-20 03:20:54 +00:00
| | worldlowslope ! = worldbottomslope
2015-04-20 07:10:14 +00:00
| | backsector - > f_slope ! = frontsector - > f_slope
2014-03-15 16:59:03 +00:00
| | backsector - > floorpic ! = frontsector - > floorpic
| | backsector - > lightlevel ! = frontsector - > lightlevel
//SoM: 3/22/2000: Check floor x and y offsets.
| | backsector - > floor_xoffs ! = frontsector - > floor_xoffs
| | backsector - > floor_yoffs ! = frontsector - > floor_yoffs
| | backsector - > floorpic_angle ! = frontsector - > floorpic_angle
//SoM: 3/22/2000: Prevents bleeding.
| | frontsector - > heightsec ! = - 1
| | backsector - > floorlightsec ! = frontsector - > floorlightsec
//SoM: 4/3/2000: Check for colormaps
| | frontsector - > extra_colormap ! = backsector - > extra_colormap
| | ( frontsector - > ffloors ! = backsector - > ffloors & & frontsector - > tag ! = backsector - > tag ) )
{
markfloor = true ;
}
else
{
// same plane on both sides
markfloor = false ;
}
if ( worldhigh ! = worldtop
2015-04-20 03:20:54 +00:00
| | worldhighslope ! = worldtopslope
2015-04-20 07:10:14 +00:00
| | backsector - > c_slope ! = frontsector - > c_slope
2014-03-15 16:59:03 +00:00
| | backsector - > ceilingpic ! = frontsector - > ceilingpic
| | backsector - > lightlevel ! = frontsector - > lightlevel
//SoM: 3/22/2000: Check floor x and y offsets.
| | backsector - > ceiling_xoffs ! = frontsector - > ceiling_xoffs
| | backsector - > ceiling_yoffs ! = frontsector - > ceiling_yoffs
| | backsector - > ceilingpic_angle ! = frontsector - > ceilingpic_angle
//SoM: 3/22/2000: Prevents bleeding.
| | ( frontsector - > heightsec ! = - 1 & & frontsector - > ceilingpic ! = skyflatnum )
2016-03-29 21:44:16 +00:00
| | backsector - > ceilinglightsec ! = frontsector - > ceilinglightsec
2014-03-15 16:59:03 +00:00
//SoM: 4/3/2000: Check for colormaps
| | frontsector - > extra_colormap ! = backsector - > extra_colormap
| | ( frontsector - > ffloors ! = backsector - > ffloors & & frontsector - > tag ! = backsector - > tag ) )
{
markceiling = true ;
}
else
{
// same plane on both sides
markceiling = false ;
}
if ( backsector - > ceilingheight < = frontsector - > floorheight | |
backsector - > floorheight > = frontsector - > ceilingheight )
{
// closed door
markceiling = markfloor = true ;
}
// check TOP TEXTURE
2015-04-20 03:20:54 +00:00
if ( worldhigh < worldtop
2015-05-17 00:59:52 +00:00
| | worldhighslope < worldtopslope
2015-04-20 03:20:54 +00:00
)
2014-03-15 16:59:03 +00:00
{
2016-12-16 21:38:53 +00:00
fixed_t texheight ;
2014-03-15 16:59:03 +00:00
// top texture
if ( ( linedef - > flags & ( ML_DONTPEGTOP ) & & ( linedef - > flags & ML_DONTPEGBOTTOM ) )
& & linedef - > sidenum [ 1 ] ! = 0xffff )
{
// Special case... use offsets from 2nd side but only if it has a texture.
side_t * def = & sides [ linedef - > sidenum [ 1 ] ] ;
2016-12-16 21:38:53 +00:00
toptexture = R_GetTextureNum ( def - > toptexture ) ;
2014-03-15 16:59:03 +00:00
if ( ! toptexture ) //Second side has no texture, use the first side's instead.
2016-12-16 21:38:53 +00:00
toptexture = R_GetTextureNum ( sidedef - > toptexture ) ;
texheight = textureheight [ toptexture ] ;
}
else
{
toptexture = R_GetTextureNum ( sidedef - > toptexture ) ;
texheight = textureheight [ toptexture ] ;
}
if ( ! ( linedef - > flags & ML_EFFECT1 ) ) { // Ignore slopes for lower/upper textures unless flag is checked
2014-03-15 16:59:03 +00:00
if ( linedef - > flags & ML_DONTPEGTOP )
2016-12-16 21:38:53 +00:00
rw_toptexturemid = frontsector - > ceilingheight - viewz ;
2014-03-15 16:59:03 +00:00
else
2016-12-16 21:38:53 +00:00
rw_toptexturemid = backsector - > ceilingheight - viewz ;
} else
if ( linedef - > flags & ML_DONTPEGTOP )
{
// top of texture at top
rw_toptexturemid = worldtop ;
rw_toptextureslide = ceilingfrontslide ;
2014-03-15 16:59:03 +00:00
}
else
{
2016-12-16 21:38:53 +00:00
rw_toptexturemid = worldhigh + texheight ;
rw_toptextureslide = ceilingbackslide ;
2014-03-15 16:59:03 +00:00
}
}
// check BOTTOM TEXTURE
2015-04-20 03:20:54 +00:00
if ( worldlow > worldbottom
2015-05-17 00:59:52 +00:00
| | worldlowslope > worldbottomslope
2015-04-20 03:20:54 +00:00
) //seulement si VISIBLE!!!
2014-03-15 16:59:03 +00:00
{
// bottom texture
2016-12-16 21:38:53 +00:00
bottomtexture = R_GetTextureNum ( sidedef - > bottomtexture ) ;
2014-03-15 16:59:03 +00:00
2015-05-04 22:45:02 +00:00
if ( ! ( linedef - > flags & ML_EFFECT1 ) ) { // Ignore slopes for lower/upper textures unless flag is checked
if ( linedef - > flags & ML_DONTPEGBOTTOM )
rw_bottomtexturemid = frontsector - > floorheight - viewz ;
else
rw_bottomtexturemid = backsector - > floorheight - viewz ;
} else
2014-03-15 16:59:03 +00:00
if ( linedef - > flags & ML_DONTPEGBOTTOM )
{
// bottom of texture at bottom
// top of texture at top
2015-05-04 21:40:02 +00:00
rw_bottomtexturemid = worldbottom ;
2015-05-03 20:47:40 +00:00
rw_bottomtextureslide = floorfrontslide ;
2014-03-15 16:59:03 +00:00
}
2015-05-03 20:47:40 +00:00
else { // top of texture at top
2014-03-15 16:59:03 +00:00
rw_bottomtexturemid = worldlow ;
2015-05-03 20:47:40 +00:00
rw_bottomtextureslide = floorbackslide ;
}
2014-03-15 16:59:03 +00:00
}
rw_toptexturemid + = sidedef - > rowoffset ;
rw_bottomtexturemid + = sidedef - > rowoffset ;
// allocate space for masked texture tables
if ( frontsector & & backsector & & frontsector - > tag ! = backsector - > tag & & ( backsector - > ffloors | | frontsector - > ffloors ) )
{
ffloor_t * rover ;
ffloor_t * r2 ;
fixed_t lowcut , highcut ;
2015-05-17 03:32:12 +00:00
fixed_t lowcutslope , highcutslope ;
// Used for height comparisons and etc across FOFs and slopes
fixed_t high1 , highslope1 , low1 , lowslope1 , high2 , highslope2 , low2 , lowslope2 ;
2014-03-15 16:59:03 +00:00
//markceiling = markfloor = true;
maskedtexture = true ;
ds_p - > thicksidecol = maskedtexturecol = lastopening - rw_x ;
lastopening + = rw_stopx - rw_x ;
2015-05-17 03:32:12 +00:00
lowcut = max ( worldbottom , worldlow ) + viewz ;
highcut = min ( worldtop , worldhigh ) + viewz ;
lowcutslope = max ( worldbottomslope , worldlowslope ) + viewz ;
highcutslope = min ( worldtopslope , worldhighslope ) + viewz ;
2014-03-15 16:59:03 +00:00
if ( frontsector - > ffloors & & backsector - > ffloors )
{
i = 0 ;
for ( rover = backsector - > ffloors ; rover & & i < MAXFFLOORS ; rover = rover - > next )
{
if ( ! ( rover - > flags & FF_RENDERSIDES ) | | ! ( rover - > flags & FF_EXISTS ) )
continue ;
if ( rover - > flags & FF_INVERTSIDES )
continue ;
if ( rover - > norender = = leveltime )
continue ;
2015-05-17 03:32:12 +00:00
if ( * rover - > t_slope ) {
high1 = P_GetZAt ( * rover - > t_slope , segleft . x , segleft . y ) ;
highslope1 = P_GetZAt ( * rover - > t_slope , segright . x , segright . y ) ;
} else
high1 = highslope1 = * rover - > topheight ;
if ( * rover - > b_slope ) {
low1 = P_GetZAt ( * rover - > b_slope , segleft . x , segleft . y ) ;
lowslope1 = P_GetZAt ( * rover - > b_slope , segright . x , segright . y ) ;
} else
low1 = lowslope1 = * rover - > bottomheight ;
if ( ( high1 < lowcut & & highslope1 < lowcutslope ) | | ( low1 > highcut & & lowslope1 > highcutslope ) )
continue ;
2014-03-15 16:59:03 +00:00
for ( r2 = frontsector - > ffloors ; r2 ; r2 = r2 - > next )
{
2016-03-01 19:55:13 +00:00
if ( ! ( r2 - > flags & FF_EXISTS ) | | ! ( r2 - > flags & FF_RENDERSIDES ) )
2014-03-15 16:59:03 +00:00
continue ;
if ( r2 - > norender = = leveltime )
continue ;
if ( rover - > flags & FF_EXTRA )
{
if ( ! ( r2 - > flags & FF_CUTEXTRA ) )
continue ;
if ( r2 - > flags & FF_EXTRA & & ( r2 - > flags & ( FF_TRANSLUCENT | FF_FOG ) ) ! = ( rover - > flags & ( FF_TRANSLUCENT | FF_FOG ) ) )
continue ;
}
else
{
if ( ! ( r2 - > flags & FF_CUTSOLIDS ) )
continue ;
}
2015-05-17 03:32:12 +00:00
if ( * r2 - > t_slope ) {
high2 = P_GetZAt ( * r2 - > t_slope , segleft . x , segleft . y ) ;
highslope2 = P_GetZAt ( * r2 - > t_slope , segright . x , segright . y ) ;
} else
high2 = highslope2 = * r2 - > topheight ;
if ( * r2 - > b_slope ) {
low2 = P_GetZAt ( * r2 - > b_slope , segleft . x , segleft . y ) ;
lowslope2 = P_GetZAt ( * r2 - > b_slope , segright . x , segright . y ) ;
} else
low2 = lowslope2 = * r2 - > bottomheight ;
2016-03-29 17:59:56 +00:00
if ( ( high2 < lowcut | | highslope2 < lowcutslope ) | | ( low2 > highcut | | lowslope2 > highcutslope ) )
2016-03-01 19:55:13 +00:00
continue ;
2016-03-29 17:59:56 +00:00
if ( ( high1 > high2 | | highslope1 > highslope2 ) | | ( low1 < low2 | | lowslope1 < lowslope2 ) )
2015-05-17 03:32:12 +00:00
continue ;
2014-03-15 16:59:03 +00:00
break ;
}
if ( r2 )
continue ;
ds_p - > thicksides [ i ] = rover ;
i + + ;
}
for ( rover = frontsector - > ffloors ; rover & & i < MAXFFLOORS ; rover = rover - > next )
{
if ( ! ( rover - > flags & FF_RENDERSIDES ) | | ! ( rover - > flags & FF_EXISTS ) )
continue ;
if ( ! ( rover - > flags & FF_ALLSIDES ) )
continue ;
if ( rover - > norender = = leveltime )
continue ;
2015-05-17 03:32:12 +00:00
if ( * rover - > t_slope ) {
high1 = P_GetZAt ( * rover - > t_slope , segleft . x , segleft . y ) ;
highslope1 = P_GetZAt ( * rover - > t_slope , segright . x , segright . y ) ;
} else
high1 = highslope1 = * rover - > topheight ;
if ( * rover - > b_slope ) {
low1 = P_GetZAt ( * rover - > b_slope , segleft . x , segleft . y ) ;
lowslope1 = P_GetZAt ( * rover - > b_slope , segright . x , segright . y ) ;
} else
low1 = lowslope1 = * rover - > bottomheight ;
if ( ( high1 < lowcut & & highslope1 < lowcutslope ) | | ( low1 > highcut & & lowslope1 > highcutslope ) )
continue ;
2014-03-15 16:59:03 +00:00
for ( r2 = backsector - > ffloors ; r2 ; r2 = r2 - > next )
{
2016-03-01 19:55:13 +00:00
if ( ! ( r2 - > flags & FF_EXISTS ) | | ! ( r2 - > flags & FF_RENDERSIDES ) )
2014-03-15 16:59:03 +00:00
continue ;
if ( r2 - > norender = = leveltime )
continue ;
if ( rover - > flags & FF_EXTRA )
{
if ( ! ( r2 - > flags & FF_CUTEXTRA ) )
continue ;
if ( r2 - > flags & FF_EXTRA & & ( r2 - > flags & ( FF_TRANSLUCENT | FF_FOG ) ) ! = ( rover - > flags & ( FF_TRANSLUCENT | FF_FOG ) ) )
continue ;
}
else
{
if ( ! ( r2 - > flags & FF_CUTSOLIDS ) )
continue ;
}
2015-05-17 03:32:12 +00:00
if ( * r2 - > t_slope ) {
high2 = P_GetZAt ( * r2 - > t_slope , segleft . x , segleft . y ) ;
highslope2 = P_GetZAt ( * r2 - > t_slope , segright . x , segright . y ) ;
} else
high2 = highslope2 = * r2 - > topheight ;
if ( * r2 - > b_slope ) {
low2 = P_GetZAt ( * r2 - > b_slope , segleft . x , segleft . y ) ;
lowslope2 = P_GetZAt ( * r2 - > b_slope , segright . x , segright . y ) ;
} else
low2 = lowslope2 = * r2 - > bottomheight ;
2016-03-29 17:59:56 +00:00
if ( ( high2 < lowcut | | highslope2 < lowcutslope ) | | ( low2 > highcut | | lowslope2 > highcutslope ) )
2016-03-01 19:55:13 +00:00
continue ;
2016-03-29 17:59:56 +00:00
if ( ( high1 > high2 | | highslope1 > highslope2 ) | | ( low1 < low2 | | lowslope1 < lowslope2 ) )
2015-05-17 03:32:12 +00:00
continue ;
2014-03-15 16:59:03 +00:00
break ;
}
if ( r2 )
continue ;
ds_p - > thicksides [ i ] = rover ;
i + + ;
}
}
else if ( backsector - > ffloors )
{
for ( rover = backsector - > ffloors , i = 0 ; rover & & i < MAXFFLOORS ; rover = rover - > next )
{
if ( ! ( rover - > flags & FF_RENDERSIDES ) | | ! ( rover - > flags & FF_EXISTS ) | | rover - > flags & FF_INVERTSIDES )
continue ;
if ( rover - > norender = = leveltime )
continue ;
2015-05-17 03:32:12 +00:00
// Oy vey.
if ( ( ( * rover - > t_slope ? P_GetZAt ( * rover - > t_slope , segleft . x , segleft . y ) : * rover - > topheight ) < = worldbottom + viewz
& & ( * rover - > t_slope ? P_GetZAt ( * rover - > t_slope , segright . x , segright . y ) : * rover - > topheight ) < = worldbottomslope + viewz )
| | ( ( * rover - > b_slope ? P_GetZAt ( * rover - > b_slope , segleft . x , segleft . y ) : * rover - > bottomheight ) > = worldtop + viewz
& & ( * rover - > b_slope ? P_GetZAt ( * rover - > b_slope , segright . x , segright . y ) : * rover - > bottomheight ) > = worldtopslope + viewz ) )
continue ;
2014-03-15 16:59:03 +00:00
ds_p - > thicksides [ i ] = rover ;
i + + ;
}
}
else if ( frontsector - > ffloors )
{
for ( rover = frontsector - > ffloors , i = 0 ; rover & & i < MAXFFLOORS ; rover = rover - > next )
{
if ( ! ( rover - > flags & FF_RENDERSIDES ) | | ! ( rover - > flags & FF_EXISTS ) | | ! ( rover - > flags & FF_ALLSIDES ) )
continue ;
2015-05-17 03:32:12 +00:00
if ( rover - > norender = = leveltime )
continue ;
// Oy vey.
if ( ( ( * rover - > t_slope ? P_GetZAt ( * rover - > t_slope , segleft . x , segleft . y ) : * rover - > topheight ) < = worldbottom + viewz
& & ( * rover - > t_slope ? P_GetZAt ( * rover - > t_slope , segright . x , segright . y ) : * rover - > topheight ) < = worldbottomslope + viewz )
| | ( ( * rover - > b_slope ? P_GetZAt ( * rover - > b_slope , segleft . x , segleft . y ) : * rover - > bottomheight ) > = worldtop + viewz
& & ( * rover - > b_slope ? P_GetZAt ( * rover - > b_slope , segright . x , segright . y ) : * rover - > bottomheight ) > = worldtopslope + viewz ) )
continue ;
if ( ( ( * rover - > t_slope ? P_GetZAt ( * rover - > t_slope , segleft . x , segleft . y ) : * rover - > topheight ) < = worldlow + viewz
& & ( * rover - > t_slope ? P_GetZAt ( * rover - > t_slope , segright . x , segright . y ) : * rover - > topheight ) < = worldlowslope + viewz )
| | ( ( * rover - > b_slope ? P_GetZAt ( * rover - > b_slope , segleft . x , segleft . y ) : * rover - > bottomheight ) > = worldhigh + viewz
& & ( * rover - > b_slope ? P_GetZAt ( * rover - > b_slope , segright . x , segright . y ) : * rover - > bottomheight ) > = worldhighslope + viewz ) )
continue ;
2014-03-15 16:59:03 +00:00
ds_p - > thicksides [ i ] = rover ;
i + + ;
}
}
ds_p - > numthicksides = numthicksides = i ;
}
2016-12-16 21:38:53 +00:00
if ( sidedef - > midtexture > 0 & & sidedef - > midtexture < numtextures )
2014-03-15 16:59:03 +00:00
{
// masked midtexture
if ( ! ds_p - > thicksidecol )
{
ds_p - > maskedtexturecol = maskedtexturecol = lastopening - rw_x ;
lastopening + = rw_stopx - rw_x ;
}
else
ds_p - > maskedtexturecol = ds_p - > thicksidecol ;
2016-05-24 21:11:48 +00:00
maskedtextureheight = ds_p - > maskedtextureheight ; // note to red, this == &(ds_p->maskedtextureheight[0])
2015-05-04 20:15:57 +00:00
2016-06-09 21:07:43 +00:00
if ( curline - > polyseg ) { // use REAL front and back floors please, so midtexture rendering isn't mucked up
rw_midtextureslide = rw_midtexturebackslide = 0 ;
if ( ! ! ( linedef - > flags & ML_DONTPEGBOTTOM ) ^ ! ! ( linedef - > flags & ML_EFFECT3 ) )
rw_midtexturemid = rw_midtextureback = max ( curline - > frontsector - > floorheight , curline - > backsector - > floorheight ) - viewz ;
else
rw_midtexturemid = rw_midtextureback = min ( curline - > frontsector - > ceilingheight , curline - > backsector - > ceilingheight ) - viewz ;
} else
2015-05-04 20:15:57 +00:00
// Set midtexture starting height
2015-05-04 22:45:02 +00:00
if ( linedef - > flags & ML_EFFECT2 ) { // Ignore slopes when texturing
rw_midtextureslide = rw_midtexturebackslide = 0 ;
if ( ! ! ( linedef - > flags & ML_DONTPEGBOTTOM ) ^ ! ! ( linedef - > flags & ML_EFFECT3 ) )
rw_midtexturemid = rw_midtextureback = max ( frontsector - > floorheight , backsector - > floorheight ) - viewz ;
else
rw_midtexturemid = rw_midtextureback = min ( frontsector - > ceilingheight , backsector - > ceilingheight ) - viewz ;
} else if ( ! ! ( linedef - > flags & ML_DONTPEGBOTTOM ) ^ ! ! ( linedef - > flags & ML_EFFECT3 ) ) {
2015-05-04 20:15:57 +00:00
rw_midtexturemid = worldbottom ;
rw_midtextureslide = floorfrontslide ;
rw_midtextureback = worldlow ;
rw_midtexturebackslide = floorbackslide ;
} else {
rw_midtexturemid = worldtop ;
rw_midtextureslide = ceilingfrontslide ;
rw_midtextureback = worldhigh ;
rw_midtexturebackslide = ceilingbackslide ;
}
2015-05-04 21:40:02 +00:00
rw_midtexturemid + = sidedef - > rowoffset ;
rw_midtextureback + = sidedef - > rowoffset ;
2015-05-04 20:15:57 +00:00
2014-03-15 16:59:03 +00:00
maskedtexture = true ;
}
}
// calculate rw_offset (only needed for textured lines)
segtextured = midtexture | | toptexture | | bottomtexture | | maskedtexture | | ( numthicksides > 0 ) ;
if ( segtextured )
{
offsetangle = rw_normalangle - rw_angle1 ;
if ( offsetangle > ANGLE_180 )
offsetangle = - ( signed ) offsetangle ;
if ( offsetangle > ANGLE_90 )
offsetangle = ANGLE_90 ;
2018-12-09 22:34:17 +00:00
sineval = FINESINE ( offsetangle > > ANGLETOFINESHIFT ) ;
rw_offset = FixedMul ( hyp , sineval ) ;
// big room fix
if ( longboi )
{
INT64 dx = ( curline - > v2 - > x ) - ( curline - > v1 - > x ) ;
INT64 dy = ( curline - > v2 - > y ) - ( curline - > v1 - > y ) ;
INT64 vdx = viewx - ( curline - > v1 - > x ) ;
INT64 vdy = viewy - ( curline - > v1 - > y ) ;
rw_offset = ( ( dx * vdx - dy * vdy ) ) / ( curline - > length ) ;
}
2014-03-15 16:59:03 +00:00
if ( rw_normalangle - rw_angle1 < ANGLE_180 )
rw_offset = - rw_offset ;
/// don't use texture offset for splats
rw_offset2 = rw_offset + curline - > offset ;
rw_offset + = sidedef - > textureoffset + curline - > offset ;
rw_centerangle = ANGLE_90 + viewangle - rw_normalangle ;
// calculate light table
// use different light tables
// for horizontal / vertical / diagonal
// OPTIMIZE: get rid of LIGHTSEGSHIFT globally
lightnum = ( frontsector - > lightlevel > > LIGHTSEGSHIFT ) ;
if ( curline - > v1 - > y = = curline - > v2 - > y )
lightnum - - ;
else if ( curline - > v1 - > x = = curline - > v2 - > x )
lightnum + + ;
if ( lightnum < 0 )
walllights = scalelight [ 0 ] ;
else if ( lightnum > = LIGHTLEVELS )
walllights = scalelight [ LIGHTLEVELS - 1 ] ;
else
walllights = scalelight [ lightnum ] ;
}
// if a floor / ceiling plane is on the wrong side
// of the view plane, it is definitely invisible
// and doesn't need to be marked.
if ( frontsector - > heightsec = = - 1 )
{
2015-04-20 07:10:14 +00:00
if ( (
frontsector - > f_slope ? P_GetZAt ( frontsector - > f_slope , viewx , viewy ) :
frontsector - > floorheight ) > = viewz )
2014-03-15 16:59:03 +00:00
{
// above view plane
markfloor = false ;
}
2015-04-20 07:10:14 +00:00
if ( (
frontsector - > c_slope ? P_GetZAt ( frontsector - > c_slope , viewx , viewy ) :
frontsector - > ceilingheight ) < = viewz & &
2014-03-15 16:59:03 +00:00
frontsector - > ceilingpic ! = skyflatnum )
{
// below view plane
markceiling = false ;
}
}
// calculate incremental stepping values for texture edges
worldtop > > = 4 ;
worldbottom > > = 4 ;
2015-04-20 03:20:54 +00:00
worldtopslope > > = 4 ;
worldbottomslope > > = 4 ;
2014-03-15 16:59:03 +00:00
2018-07-08 19:44:01 +00:00
if ( linedef - > special = = 41 ) { // HORIZON LINES
topstep = bottomstep = 0 ;
topfrac = bottomfrac = ( centeryfrac > > 4 ) ;
topfrac + + ; // Prevent 1px HOM
} else {
topstep = - FixedMul ( rw_scalestep , worldtop ) ;
topfrac = ( centeryfrac > > 4 ) - FixedMul ( worldtop , rw_scale ) ;
2014-03-15 16:59:03 +00:00
2018-07-08 19:44:01 +00:00
bottomstep = - FixedMul ( rw_scalestep , worldbottom ) ;
bottomfrac = ( centeryfrac > > 4 ) - FixedMul ( worldbottom , rw_scale ) ;
2014-03-15 16:59:03 +00:00
2018-07-08 19:44:01 +00:00
if ( frontsector - > c_slope ) {
fixed_t topfracend = ( centeryfrac > > 4 ) - FixedMul ( worldtopslope , ds_p - > scale2 ) ;
topstep = ( topfracend - topfrac ) / ( range ) ;
}
if ( frontsector - > f_slope ) {
fixed_t bottomfracend = ( centeryfrac > > 4 ) - FixedMul ( worldbottomslope , ds_p - > scale2 ) ;
bottomstep = ( bottomfracend - bottomfrac ) / ( range ) ;
}
}
2015-04-20 03:20:54 +00:00
2014-03-15 16:59:03 +00:00
dc_numlights = 0 ;
if ( frontsector - > numlights )
{
dc_numlights = frontsector - > numlights ;
if ( dc_numlights > = dc_maxlights )
{
dc_maxlights = dc_numlights ;
dc_lightlist = Z_Realloc ( dc_lightlist , sizeof ( * dc_lightlist ) * dc_maxlights , PU_STATIC , NULL ) ;
}
for ( i = p = 0 ; i < dc_numlights ; i + + )
{
2015-05-18 04:51:38 +00:00
fixed_t leftheight , rightheight ;
2014-03-15 16:59:03 +00:00
light = & frontsector - > lightlist [ i ] ;
rlight = & dc_lightlist [ p ] ;
2015-05-18 04:51:38 +00:00
if ( light - > slope ) {
leftheight = P_GetZAt ( light - > slope , segleft . x , segleft . y ) ;
rightheight = P_GetZAt ( light - > slope , segright . x , segright . y ) ;
// Flag sector as having slopes
frontsector - > hasslope = true ;
} else
leftheight = rightheight = light - > height ;
leftheight - = viewz ;
rightheight - = viewz ;
leftheight > > = 4 ;
rightheight > > = 4 ;
2014-03-15 16:59:03 +00:00
if ( i ! = 0 )
{
2015-05-18 04:51:38 +00:00
if ( leftheight < worldbottom & & rightheight < worldbottomslope )
continue ;
if ( leftheight > worldtop & & rightheight > worldtopslope & & i + 1 < dc_numlights & & frontsector - > lightlist [ i + 1 ] . height > frontsector - > ceilingheight )
continue ;
2014-03-15 16:59:03 +00:00
}
2015-05-18 04:51:38 +00:00
rlight - > height = ( centeryfrac > > 4 ) - FixedMul ( leftheight , rw_scale ) ;
rlight - > heightstep = ( centeryfrac > > 4 ) - FixedMul ( rightheight , ds_p - > scale2 ) ;
2016-03-19 23:19:05 +00:00
rlight - > heightstep = ( rlight - > heightstep - rlight - > height ) / ( range ) ;
2014-03-15 16:59:03 +00:00
rlight - > flags = light - > flags ;
2016-04-20 17:04:51 +00:00
if ( light - > caster & & light - > caster - > flags & FF_CUTSOLIDS )
2014-03-15 16:59:03 +00:00
{
2015-05-18 04:51:38 +00:00
if ( * light - > caster - > b_slope ) {
leftheight = P_GetZAt ( * light - > caster - > b_slope , segleft . x , segleft . y ) ;
rightheight = P_GetZAt ( * light - > caster - > b_slope , segright . x , segright . y ) ;
// Flag sector as having slopes
frontsector - > hasslope = true ;
} else
leftheight = rightheight = * light - > caster - > bottomheight ;
leftheight - = viewz ;
rightheight - = viewz ;
leftheight > > = 4 ;
rightheight > > = 4 ;
rlight - > botheight = ( centeryfrac > > 4 ) - FixedMul ( leftheight , rw_scale ) ;
rlight - > botheightstep = ( centeryfrac > > 4 ) - FixedMul ( rightheight , ds_p - > scale2 ) ;
2016-03-19 23:19:05 +00:00
rlight - > botheightstep = ( rlight - > botheightstep - rlight - > botheight ) / ( range ) ;
2015-05-18 04:51:38 +00:00
2014-03-15 16:59:03 +00:00
}
rlight - > lightlevel = * light - > lightlevel ;
rlight - > extra_colormap = light - > extra_colormap ;
p + + ;
}
dc_numlights = p ;
}
if ( numffloors )
{
for ( i = 0 ; i < numffloors ; i + + )
{
ffloor [ i ] . f_pos > > = 4 ;
2015-05-17 03:32:12 +00:00
ffloor [ i ] . f_pos_slope > > = 4 ;
ffloor [ i ] . f_frac = ( centeryfrac > > 4 ) - FixedMul ( ffloor [ i ] . f_pos , rw_scale ) ;
2016-03-19 23:19:05 +00:00
ffloor [ i ] . f_step = ( ( centeryfrac > > 4 ) - FixedMul ( ffloor [ i ] . f_pos_slope , ds_p - > scale2 ) - ffloor [ i ] . f_frac ) / ( range ) ;
2014-03-15 16:59:03 +00:00
}
}
if ( backsector )
{
worldhigh > > = 4 ;
worldlow > > = 4 ;
2015-04-20 03:20:54 +00:00
worldhighslope > > = 4 ;
worldlowslope > > = 4 ;
2014-03-15 16:59:03 +00:00
2016-04-25 17:48:14 +00:00
if ( toptexture )
2014-03-15 16:59:03 +00:00
{
pixhigh = ( centeryfrac > > 4 ) - FixedMul ( worldhigh , rw_scale ) ;
pixhighstep = - FixedMul ( rw_scalestep , worldhigh ) ;
2015-04-20 03:20:54 +00:00
if ( backsector - > c_slope ) {
fixed_t topfracend = ( centeryfrac > > 4 ) - FixedMul ( worldhighslope , ds_p - > scale2 ) ;
2016-03-19 23:19:05 +00:00
pixhighstep = ( topfracend - pixhigh ) / ( range ) ;
2015-04-20 03:20:54 +00:00
}
2014-03-15 16:59:03 +00:00
}
2016-04-25 17:48:14 +00:00
if ( bottomtexture )
2014-03-15 16:59:03 +00:00
{
pixlow = ( centeryfrac > > 4 ) - FixedMul ( worldlow , rw_scale ) ;
pixlowstep = - FixedMul ( rw_scalestep , worldlow ) ;
2015-04-20 03:20:54 +00:00
if ( backsector - > f_slope ) {
fixed_t bottomfracend = ( centeryfrac > > 4 ) - FixedMul ( worldlowslope , ds_p - > scale2 ) ;
2016-03-19 23:19:05 +00:00
pixlowstep = ( bottomfracend - pixlow ) / ( range ) ;
2015-04-20 03:20:54 +00:00
}
2014-03-15 16:59:03 +00:00
}
{
ffloor_t * rover ;
2016-03-29 17:59:56 +00:00
fixed_t roverleft , roverright ;
2015-05-17 03:32:12 +00:00
fixed_t planevistest ;
2015-10-10 16:57:35 +00:00
i = 0 ;
2014-03-15 16:59:03 +00:00
if ( backsector - > ffloors )
{
for ( rover = backsector - > ffloors ; rover & & i < MAXFFLOORS ; rover = rover - > next )
{
if ( ! ( rover - > flags & FF_EXISTS ) | | ! ( rover - > flags & FF_RENDERPLANES ) )
continue ;
if ( rover - > norender = = leveltime )
continue ;
2015-05-17 04:55:49 +00:00
// Let the renderer know this sector is sloped.
if ( * rover - > b_slope | | * rover - > t_slope )
backsector - > hasslope = true ;
2016-03-29 17:59:56 +00:00
roverleft = ( * rover - > b_slope ? P_GetZAt ( * rover - > b_slope , segleft . x , segleft . y ) : * rover - > bottomheight ) - viewz ;
roverright = ( * rover - > b_slope ? P_GetZAt ( * rover - > b_slope , segright . x , segright . y ) : * rover - > bottomheight ) - viewz ;
2015-05-17 03:32:12 +00:00
planevistest = ( * rover - > b_slope ? P_GetZAt ( * rover - > b_slope , viewx , viewy ) : * rover - > bottomheight ) ;
2016-03-29 17:59:56 +00:00
if ( ( roverleft > > 4 < = worldhigh | | roverright > > 4 < = worldhighslope ) & &
( roverleft > > 4 > = worldlow | | roverright > > 4 > = worldlowslope ) & &
2015-05-17 03:32:12 +00:00
( ( viewz < planevistest & & ! ( rover - > flags & FF_INVERTPLANES ) ) | |
( viewz > planevistest & & ( rover - > flags & FF_BOTHPLANES ) ) ) )
{
2015-05-22 03:13:51 +00:00
//ffloor[i].slope = *rover->b_slope;
2016-03-29 17:59:56 +00:00
ffloor [ i ] . b_pos = roverleft ;
ffloor [ i ] . b_pos_slope = roverright ;
2015-05-17 03:32:12 +00:00
ffloor [ i ] . b_pos > > = 4 ;
ffloor [ i ] . b_pos_slope > > = 4 ;
ffloor [ i ] . b_frac = ( centeryfrac > > 4 ) - FixedMul ( ffloor [ i ] . b_pos , rw_scale ) ;
ffloor [ i ] . b_step = ( centeryfrac > > 4 ) - FixedMul ( ffloor [ i ] . b_pos_slope , ds_p - > scale2 ) ;
2016-03-19 23:19:05 +00:00
ffloor [ i ] . b_step = ( ffloor [ i ] . b_step - ffloor [ i ] . b_frac ) / ( range ) ;
2015-05-17 03:32:12 +00:00
i + + ;
}
if ( i > = MAXFFLOORS )
break ;
2016-03-29 17:59:56 +00:00
roverleft = ( * rover - > t_slope ? P_GetZAt ( * rover - > t_slope , segleft . x , segleft . y ) : * rover - > topheight ) - viewz ;
roverright = ( * rover - > t_slope ? P_GetZAt ( * rover - > t_slope , segright . x , segright . y ) : * rover - > topheight ) - viewz ;
2015-05-17 03:32:12 +00:00
planevistest = ( * rover - > t_slope ? P_GetZAt ( * rover - > t_slope , viewx , viewy ) : * rover - > topheight ) ;
2016-03-29 17:59:56 +00:00
if ( ( roverleft > > 4 < = worldhigh | | roverright > > 4 < = worldhighslope ) & &
( roverleft > > 4 > = worldlow | | roverright > > 4 > = worldlowslope ) & &
2015-05-17 03:32:12 +00:00
( ( viewz > planevistest & & ! ( rover - > flags & FF_INVERTPLANES ) ) | |
( viewz < planevistest & & ( rover - > flags & FF_BOTHPLANES ) ) ) )
{
2015-05-22 03:13:51 +00:00
//ffloor[i].slope = *rover->t_slope;
2016-03-29 17:59:56 +00:00
ffloor [ i ] . b_pos = roverleft ;
ffloor [ i ] . b_pos_slope = roverright ;
2015-05-17 03:32:12 +00:00
ffloor [ i ] . b_pos > > = 4 ;
ffloor [ i ] . b_pos_slope > > = 4 ;
ffloor [ i ] . b_frac = ( centeryfrac > > 4 ) - FixedMul ( ffloor [ i ] . b_pos , rw_scale ) ;
ffloor [ i ] . b_step = ( centeryfrac > > 4 ) - FixedMul ( ffloor [ i ] . b_pos_slope , ds_p - > scale2 ) ;
2016-03-19 23:19:05 +00:00
ffloor [ i ] . b_step = ( ffloor [ i ] . b_step - ffloor [ i ] . b_frac ) / ( range ) ;
2015-05-17 03:32:12 +00:00
i + + ;
}
2014-03-15 16:59:03 +00:00
}
}
else if ( frontsector & & frontsector - > ffloors )
{
for ( rover = frontsector - > ffloors ; rover & & i < MAXFFLOORS ; rover = rover - > next )
{
if ( ! ( rover - > flags & FF_EXISTS ) | | ! ( rover - > flags & FF_RENDERPLANES ) )
continue ;
if ( rover - > norender = = leveltime )
continue ;
2015-05-17 03:32:12 +00:00
2015-05-17 04:55:49 +00:00
// Let the renderer know this sector is sloped.
if ( * rover - > b_slope | | * rover - > t_slope )
frontsector - > hasslope = true ;
2016-03-29 17:59:56 +00:00
roverleft = ( * rover - > b_slope ? P_GetZAt ( * rover - > b_slope , segleft . x , segleft . y ) : * rover - > bottomheight ) - viewz ;
roverright = ( * rover - > b_slope ? P_GetZAt ( * rover - > b_slope , segright . x , segright . y ) : * rover - > bottomheight ) - viewz ;
2015-05-17 03:32:12 +00:00
planevistest = ( * rover - > b_slope ? P_GetZAt ( * rover - > b_slope , viewx , viewy ) : * rover - > bottomheight ) ;
2016-03-29 17:59:56 +00:00
if ( ( roverleft > > 4 < = worldhigh | | roverright > > 4 < = worldhighslope ) & &
( roverleft > > 4 > = worldlow | | roverright > > 4 > = worldlowslope ) & &
2015-05-17 03:32:12 +00:00
( ( viewz < planevistest & & ! ( rover - > flags & FF_INVERTPLANES ) ) | |
( viewz > planevistest & & ( rover - > flags & FF_BOTHPLANES ) ) ) )
{
2015-05-22 03:13:51 +00:00
//ffloor[i].slope = *rover->b_slope;
2016-03-29 17:59:56 +00:00
ffloor [ i ] . b_pos = roverleft ;
ffloor [ i ] . b_pos_slope = roverright ;
2015-05-17 03:32:12 +00:00
ffloor [ i ] . b_pos > > = 4 ;
ffloor [ i ] . b_pos_slope > > = 4 ;
ffloor [ i ] . b_frac = ( centeryfrac > > 4 ) - FixedMul ( ffloor [ i ] . b_pos , rw_scale ) ;
ffloor [ i ] . b_step = ( centeryfrac > > 4 ) - FixedMul ( ffloor [ i ] . b_pos_slope , ds_p - > scale2 ) ;
2016-03-19 23:19:05 +00:00
ffloor [ i ] . b_step = ( ffloor [ i ] . b_step - ffloor [ i ] . b_frac ) / ( range ) ;
2015-05-17 03:32:12 +00:00
i + + ;
}
if ( i > = MAXFFLOORS )
break ;
2016-03-29 17:59:56 +00:00
roverleft = ( * rover - > t_slope ? P_GetZAt ( * rover - > t_slope , segleft . x , segleft . y ) : * rover - > topheight ) - viewz ;
roverright = ( * rover - > t_slope ? P_GetZAt ( * rover - > t_slope , segright . x , segright . y ) : * rover - > topheight ) - viewz ;
2015-05-17 03:32:12 +00:00
planevistest = ( * rover - > t_slope ? P_GetZAt ( * rover - > t_slope , viewx , viewy ) : * rover - > topheight ) ;
2016-03-29 17:59:56 +00:00
if ( ( roverleft > > 4 < = worldhigh | | roverright > > 4 < = worldhighslope ) & &
( roverleft > > 4 > = worldlow | | roverright > > 4 > = worldlowslope ) & &
2015-05-17 03:32:12 +00:00
( ( viewz > planevistest & & ! ( rover - > flags & FF_INVERTPLANES ) ) | |
( viewz < planevistest & & ( rover - > flags & FF_BOTHPLANES ) ) ) )
{
2015-05-22 03:13:51 +00:00
//ffloor[i].slope = *rover->t_slope;
2016-03-29 17:59:56 +00:00
ffloor [ i ] . b_pos = roverleft ;
ffloor [ i ] . b_pos_slope = roverright ;
2015-05-17 03:32:12 +00:00
ffloor [ i ] . b_pos > > = 4 ;
ffloor [ i ] . b_pos_slope > > = 4 ;
ffloor [ i ] . b_frac = ( centeryfrac > > 4 ) - FixedMul ( ffloor [ i ] . b_pos , rw_scale ) ;
ffloor [ i ] . b_step = ( centeryfrac > > 4 ) - FixedMul ( ffloor [ i ] . b_pos_slope , ds_p - > scale2 ) ;
2016-03-19 23:19:05 +00:00
ffloor [ i ] . b_step = ( ffloor [ i ] . b_step - ffloor [ i ] . b_frac ) / ( range ) ;
2015-05-17 03:32:12 +00:00
i + + ;
}
2014-03-15 16:59:03 +00:00
}
}
if ( curline - > polyseg & & frontsector & & ( curline - > polyseg - > flags & POF_RENDERPLANES ) )
{
2015-01-01 19:50:31 +00:00
while ( i < numffloors & & ffloor [ i ] . polyobj ! = curline - > polyseg ) i + + ;
if ( i < numffloors & & backsector - > floorheight < = frontsector - > ceilingheight & &
2014-03-15 16:59:03 +00:00
backsector - > floorheight > = frontsector - > floorheight & &
( viewz < backsector - > floorheight ) )
{
if ( ffloor [ i ] . plane - > minx > ds_p - > x1 )
ffloor [ i ] . plane - > minx = ds_p - > x1 ;
if ( ffloor [ i ] . plane - > maxx < ds_p - > x2 )
ffloor [ i ] . plane - > maxx = ds_p - > x2 ;
2015-05-22 03:13:51 +00:00
ffloor [ i ] . slope = NULL ;
2014-03-15 16:59:03 +00:00
ffloor [ i ] . b_pos = backsector - > floorheight ;
ffloor [ i ] . b_pos = ( ffloor [ i ] . b_pos - viewz ) > > 4 ;
ffloor [ i ] . b_step = FixedMul ( - rw_scalestep , ffloor [ i ] . b_pos ) ;
ffloor [ i ] . b_frac = ( centeryfrac > > 4 ) - FixedMul ( ffloor [ i ] . b_pos , rw_scale ) ;
i + + ;
}
2015-01-01 19:50:31 +00:00
if ( i < numffloors & & backsector - > ceilingheight > = frontsector - > floorheight & &
2014-03-15 16:59:03 +00:00
backsector - > ceilingheight < = frontsector - > ceilingheight & &
( viewz > backsector - > ceilingheight ) )
{
if ( ffloor [ i ] . plane - > minx > ds_p - > x1 )
ffloor [ i ] . plane - > minx = ds_p - > x1 ;
if ( ffloor [ i ] . plane - > maxx < ds_p - > x2 )
ffloor [ i ] . plane - > maxx = ds_p - > x2 ;
2015-05-22 03:13:51 +00:00
ffloor [ i ] . slope = NULL ;
2014-03-15 16:59:03 +00:00
ffloor [ i ] . b_pos = backsector - > ceilingheight ;
ffloor [ i ] . b_pos = ( ffloor [ i ] . b_pos - viewz ) > > 4 ;
ffloor [ i ] . b_step = FixedMul ( - rw_scalestep , ffloor [ i ] . b_pos ) ;
ffloor [ i ] . b_frac = ( centeryfrac > > 4 ) - FixedMul ( ffloor [ i ] . b_pos , rw_scale ) ;
i + + ;
}
}
numbackffloors = i ;
}
}
// get a new or use the same visplane
if ( markceiling )
{
if ( ceilingplane ) //SoM: 3/29/2000: Check for null ceiling planes
ceilingplane = R_CheckPlane ( ceilingplane , rw_x , rw_stopx - 1 ) ;
else
2018-12-14 17:08:25 +00:00
markceiling = false ;
2019-01-12 02:45:59 +00:00
// Don't mark ceiling flat lines for polys unless this line has an upper texture, otherwise we get flat leakage pulling downward
// (If it DOES have an upper texture and we do this, the ceiling won't render at all)
if ( curline - > polyseg & & ! curline - > sidedef - > toptexture )
2018-12-14 17:08:25 +00:00
markceiling = false ;
2014-03-15 16:59:03 +00:00
}
// get a new or use the same visplane
if ( markfloor )
{
if ( floorplane ) //SoM: 3/29/2000: Check for null planes
floorplane = R_CheckPlane ( floorplane , rw_x , rw_stopx - 1 ) ;
else
2018-12-14 17:08:25 +00:00
markfloor = false ;
2019-01-12 02:45:59 +00:00
// Don't mark floor flat lines for polys unless this line has a lower texture, otherwise we get flat leakage pulling upward
// (If it DOES have a lower texture and we do this, the floor won't render at all)
if ( curline - > polyseg & & ! curline - > sidedef - > bottomtexture )
2018-12-14 17:08:25 +00:00
markfloor = false ;
2014-03-15 16:59:03 +00:00
}
ds_p - > numffloorplanes = 0 ;
if ( numffloors )
{
if ( ! firstseg )
{
ds_p - > numffloorplanes = numffloors ;
for ( i = 0 ; i < numffloors ; i + + )
{
ds_p - > ffloorplanes [ i ] = ffloor [ i ] . plane =
R_CheckPlane ( ffloor [ i ] . plane , rw_x , rw_stopx - 1 ) ;
}
firstseg = ds_p ;
}
else
{
for ( i = 0 ; i < numffloors ; i + + )
R_ExpandPlane ( ffloor [ i ] . plane , rw_x , rw_stopx - 1 ) ;
}
}
# ifdef WALLSPLATS
if ( linedef - > splats & & cv_splats . value )
{
// Isn't a bit wasteful to copy the ENTIRE array for every drawseg?
M_Memcpy ( last_ceilingclip + ds_p - > x1 , ceilingclip + ds_p - > x1 ,
sizeof ( INT16 ) * ( ds_p - > x2 - ds_p - > x1 + 1 ) ) ;
M_Memcpy ( last_floorclip + ds_p - > x1 , floorclip + ds_p - > x1 ,
sizeof ( INT16 ) * ( ds_p - > x2 - ds_p - > x1 + 1 ) ) ;
R_RenderSegLoop ( ) ;
R_DrawWallSplats ( ) ;
}
else
# endif
R_RenderSegLoop ( ) ;
colfunc = wallcolfunc ;
2016-02-06 18:57:26 +00:00
if ( portalline ) // if curline is a portal, set portalrender for drawseg
ds_p - > portalpass = portalrender + 1 ;
else
ds_p - > portalpass = 0 ;
2014-03-15 16:59:03 +00:00
// save sprite clipping info
if ( ( ( ds_p - > silhouette & SIL_TOP ) | | maskedtexture ) & & ! ds_p - > sprtopclip )
{
M_Memcpy ( lastopening , ceilingclip + start , 2 * ( rw_stopx - start ) ) ;
ds_p - > sprtopclip = lastopening - start ;
lastopening + = rw_stopx - start ;
}
if ( ( ( ds_p - > silhouette & SIL_BOTTOM ) | | maskedtexture ) & & ! ds_p - > sprbottomclip )
{
M_Memcpy ( lastopening , floorclip + start , 2 * ( rw_stopx - start ) ) ;
ds_p - > sprbottomclip = lastopening - start ;
lastopening + = rw_stopx - start ;
}
if ( maskedtexture & & ! ( ds_p - > silhouette & SIL_TOP ) )
{
ds_p - > silhouette | = SIL_TOP ;
2016-12-16 21:38:53 +00:00
ds_p - > tsilheight = ( sidedef - > midtexture > 0 & & sidedef - > midtexture < numtextures ) ? INT32_MIN : INT32_MAX ;
2014-03-15 16:59:03 +00:00
}
if ( maskedtexture & & ! ( ds_p - > silhouette & SIL_BOTTOM ) )
{
ds_p - > silhouette | = SIL_BOTTOM ;
2016-12-16 21:38:53 +00:00
ds_p - > bsilheight = ( sidedef - > midtexture > 0 & & sidedef - > midtexture < numtextures ) ? INT32_MAX : INT32_MIN ;
2014-03-15 16:59:03 +00:00
}
ds_p + + ;
}