mirror of
https://github.com/id-Software/DOOM-3-BFG.git
synced 2025-03-16 15:41:16 +00:00
783 lines
19 KiB
C++
783 lines
19 KiB
C++
/*
|
|
===========================================================================
|
|
|
|
Doom 3 BFG Edition GPL Source Code
|
|
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
|
|
|
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
|
|
|
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
|
|
|
|
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
|
|
|
===========================================================================
|
|
*/
|
|
|
|
#include "Precompiled.h"
|
|
#include "globaldata.h"
|
|
|
|
|
|
|
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include "i_system.h"
|
|
|
|
#include "doomdef.h"
|
|
#include "doomstat.h"
|
|
|
|
#include "r_local.h"
|
|
#include "r_sky.h"
|
|
|
|
|
|
// OPTIMIZE: closed two sided ::g->lines as single sided
|
|
|
|
// True if any of the ::g->segs textures might be visible.
|
|
|
|
// False if the back side is the same plane.
|
|
|
|
|
|
|
|
// angle to line origin
|
|
|
|
//
|
|
// regular wall
|
|
//
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
// R_RenderMaskedSegRange
|
|
//
|
|
void
|
|
R_RenderMaskedSegRange
|
|
( drawseg_t* ds,
|
|
int x1,
|
|
int x2 )
|
|
{
|
|
unsigned index;
|
|
postColumn_t* col;
|
|
int lightnum;
|
|
int texnum;
|
|
|
|
// Calculate light table.
|
|
// Use different light tables
|
|
// for horizontal / vertical / diagonal. Diagonal?
|
|
// OPTIMIZE: get rid of LIGHTSEGSHIFT globally
|
|
::g->curline = ds->curline;
|
|
::g->frontsector = ::g->curline->frontsector;
|
|
::g->backsector = ::g->curline->backsector;
|
|
texnum = ::g->texturetranslation[::g->curline->sidedef->midtexture];
|
|
|
|
lightnum = ( ::g->frontsector->lightlevel >> LIGHTSEGSHIFT ) +::g->extralight;
|
|
|
|
if( ::g->curline->v1->y == ::g->curline->v2->y )
|
|
{
|
|
lightnum--;
|
|
}
|
|
else if( ::g->curline->v1->x == ::g->curline->v2->x )
|
|
{
|
|
lightnum++;
|
|
}
|
|
|
|
if( lightnum < 0 )
|
|
{
|
|
::g->walllights = ::g->scalelight[0];
|
|
}
|
|
else if( lightnum >= LIGHTLEVELS )
|
|
{
|
|
::g->walllights = ::g->scalelight[LIGHTLEVELS - 1];
|
|
}
|
|
else
|
|
{
|
|
::g->walllights = ::g->scalelight[lightnum];
|
|
}
|
|
|
|
::g->maskedtexturecol = ds->maskedtexturecol;
|
|
|
|
::g->rw_scalestep = ds->scalestep;
|
|
::g->spryscale = ds->scale1 + ( x1 - ds->x1 )*::g->rw_scalestep;
|
|
::g->mfloorclip = ds->sprbottomclip;
|
|
::g->mceilingclip = ds->sprtopclip;
|
|
|
|
// find positioning
|
|
if( ::g->curline->linedef->flags & ML_DONTPEGBOTTOM )
|
|
{
|
|
::g->dc_texturemid = ::g->frontsector->floorheight > ::g->backsector->floorheight
|
|
? ::g->frontsector->floorheight : ::g->backsector->floorheight;
|
|
::g->dc_texturemid = ::g->dc_texturemid + ::g->s_textureheight[texnum] - ::g->viewz;
|
|
}
|
|
else
|
|
{
|
|
::g->dc_texturemid =::g->frontsector->ceilingheight < ::g->backsector->ceilingheight
|
|
? ::g->frontsector->ceilingheight : ::g->backsector->ceilingheight;
|
|
::g->dc_texturemid = ::g->dc_texturemid - ::g->viewz;
|
|
}
|
|
::g->dc_texturemid += ::g->curline->sidedef->rowoffset;
|
|
|
|
if( ::g->fixedcolormap )
|
|
{
|
|
::g->dc_colormap = ::g->fixedcolormap;
|
|
}
|
|
|
|
// draw the columns
|
|
for( ::g->dc_x = x1 ; ::g->dc_x <= x2 ; ::g->dc_x++ )
|
|
{
|
|
// calculate lighting
|
|
if( ::g->maskedtexturecol[::g->dc_x] != SHRT_MAX )
|
|
{
|
|
if( !::g->fixedcolormap )
|
|
{
|
|
index = ::g->spryscale >> LIGHTSCALESHIFT;
|
|
|
|
if( index >= MAXLIGHTSCALE )
|
|
{
|
|
index = MAXLIGHTSCALE - 1;
|
|
}
|
|
|
|
::g->dc_colormap = ::g->walllights[index];
|
|
}
|
|
|
|
::g->sprtopscreen = ::g->centeryfrac - FixedMul( ::g->dc_texturemid, ::g->spryscale );
|
|
::g->dc_iscale = 0xffffffffu / ( unsigned )::g->spryscale;
|
|
|
|
// draw the texture
|
|
col = ( postColumn_t* )(
|
|
( byte* )R_GetColumn( texnum, ::g->maskedtexturecol[::g->dc_x] ) - 3 );
|
|
|
|
R_DrawMaskedColumn( col );
|
|
::g->maskedtexturecol[::g->dc_x] = SHRT_MAX;
|
|
}
|
|
::g->spryscale += ::g->rw_scalestep;
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//
|
|
// 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.
|
|
//
|
|
|
|
void R_RenderSegLoop( void )
|
|
{
|
|
angle_t angle;
|
|
unsigned index;
|
|
int yl;
|
|
int yh;
|
|
int mid;
|
|
fixed_t texturecolumn;
|
|
int top;
|
|
int bottom;
|
|
|
|
texturecolumn = 0; // shut up compiler warning
|
|
|
|
for( ; ::g->rw_x < ::g->rw_stopx ; ::g->rw_x++ )
|
|
{
|
|
// mark floor / ceiling areas
|
|
yl = ( ::g->topfrac + HEIGHTUNIT - 1 ) >> HEIGHTBITS;
|
|
|
|
// no space above wall?
|
|
if( yl < ::g->ceilingclip[::g->rw_x] + 1 )
|
|
{
|
|
yl = ::g->ceilingclip[::g->rw_x] + 1;
|
|
}
|
|
|
|
if( ::g->markceiling )
|
|
{
|
|
top = ::g->ceilingclip[::g->rw_x] + 1;
|
|
bottom = yl - 1;
|
|
|
|
if( bottom >= ::g->floorclip[::g->rw_x] )
|
|
{
|
|
bottom = ::g->floorclip[::g->rw_x] - 1;
|
|
}
|
|
|
|
if( top <= bottom )
|
|
{
|
|
::g->ceilingplane->top[::g->rw_x] = top;
|
|
::g->ceilingplane->bottom[::g->rw_x] = bottom;
|
|
}
|
|
}
|
|
|
|
yh = ::g->bottomfrac >> HEIGHTBITS;
|
|
|
|
if( yh >= ::g->floorclip[::g->rw_x] )
|
|
{
|
|
yh = ::g->floorclip[::g->rw_x] - 1;
|
|
}
|
|
|
|
if( ::g->markfloor )
|
|
{
|
|
top = yh + 1;
|
|
bottom = ::g->floorclip[::g->rw_x] - 1;
|
|
if( top <= ::g->ceilingclip[::g->rw_x] )
|
|
{
|
|
top = ::g->ceilingclip[::g->rw_x] + 1;
|
|
}
|
|
if( top <= bottom )
|
|
{
|
|
::g->floorplane->top[::g->rw_x] = top;
|
|
::g->floorplane->bottom[::g->rw_x] = bottom;
|
|
}
|
|
}
|
|
|
|
// texturecolumn and lighting are independent of wall tiers
|
|
if( ::g->segtextured )
|
|
{
|
|
// calculate texture offset
|
|
angle = ( ::g->rw_centerangle + ::g->xtoviewangle[::g->rw_x] ) >> ANGLETOFINESHIFT;
|
|
texturecolumn = ::g->rw_offset - FixedMul( finetangent[angle], ::g->rw_distance );
|
|
texturecolumn >>= FRACBITS;
|
|
// calculate lighting
|
|
index = ::g->rw_scale >> LIGHTSCALESHIFT;
|
|
|
|
if( index >= MAXLIGHTSCALE )
|
|
{
|
|
index = MAXLIGHTSCALE - 1;
|
|
}
|
|
|
|
::g->dc_colormap = ::g->walllights[index];
|
|
::g->dc_x = ::g->rw_x;
|
|
::g->dc_iscale = 0xffffffffu / ( unsigned )::g->rw_scale;
|
|
}
|
|
|
|
// draw the wall tiers
|
|
if( ::g->midtexture )
|
|
{
|
|
// single sided line
|
|
::g->dc_yl = yl;
|
|
::g->dc_yh = yh;
|
|
::g->dc_texturemid = ::g->rw_midtexturemid;
|
|
::g->dc_source = R_GetColumn( ::g->midtexture, texturecolumn );
|
|
colfunc( ::g->dc_colormap, ::g->dc_source );
|
|
::g->ceilingclip[::g->rw_x] = ::g->viewheight;
|
|
::g->floorclip[::g->rw_x] = -1;
|
|
}
|
|
else
|
|
{
|
|
// two sided line
|
|
if( ::g->toptexture )
|
|
{
|
|
// top wall
|
|
mid = ::g->pixhigh >> HEIGHTBITS;
|
|
::g->pixhigh += ::g->pixhighstep;
|
|
|
|
if( mid >= ::g->floorclip[::g->rw_x] )
|
|
{
|
|
mid = ::g->floorclip[::g->rw_x] - 1;
|
|
}
|
|
|
|
if( mid >= yl )
|
|
{
|
|
::g->dc_yl = yl;
|
|
::g->dc_yh = mid;
|
|
::g->dc_texturemid = ::g->rw_toptexturemid;
|
|
::g->dc_source = R_GetColumn( ::g->toptexture, texturecolumn );
|
|
colfunc( ::g->dc_colormap, ::g->dc_source );
|
|
::g->ceilingclip[::g->rw_x] = mid;
|
|
}
|
|
else
|
|
{
|
|
::g->ceilingclip[::g->rw_x] = yl - 1;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// no top wall
|
|
if( ::g->markceiling )
|
|
{
|
|
::g->ceilingclip[::g->rw_x] = yl - 1;
|
|
}
|
|
}
|
|
|
|
if( ::g->bottomtexture )
|
|
{
|
|
// bottom wall
|
|
mid = ( ::g->pixlow + HEIGHTUNIT - 1 ) >> HEIGHTBITS;
|
|
::g->pixlow += ::g->pixlowstep;
|
|
|
|
// no space above wall?
|
|
if( mid <= ::g->ceilingclip[::g->rw_x] )
|
|
{
|
|
mid = ::g->ceilingclip[::g->rw_x] + 1;
|
|
}
|
|
|
|
if( mid <= yh )
|
|
{
|
|
::g->dc_yl = mid;
|
|
::g->dc_yh = yh;
|
|
::g->dc_texturemid = ::g->rw_bottomtexturemid;
|
|
::g->dc_source = R_GetColumn( ::g->bottomtexture,
|
|
texturecolumn );
|
|
colfunc( ::g->dc_colormap, ::g->dc_source );
|
|
::g->floorclip[::g->rw_x] = mid;
|
|
}
|
|
else
|
|
{
|
|
::g->floorclip[::g->rw_x] = yh + 1;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// no bottom wall
|
|
if( ::g->markfloor )
|
|
{
|
|
::g->floorclip[::g->rw_x] = yh + 1;
|
|
}
|
|
}
|
|
|
|
if( ::g->maskedtexture )
|
|
{
|
|
// save texturecol
|
|
// for backdrawing of masked mid texture
|
|
::g->maskedtexturecol[::g->rw_x] = texturecolumn;
|
|
}
|
|
}
|
|
|
|
::g->rw_scale += ::g->rw_scalestep;
|
|
::g->topfrac += ::g->topstep;
|
|
::g->bottomfrac += ::g->bottomstep;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
//
|
|
// R_StoreWallRange
|
|
// A wall segment will be drawn
|
|
// between start and stop pixels (inclusive).
|
|
//
|
|
void
|
|
R_StoreWallRange
|
|
( int start,
|
|
int stop )
|
|
{
|
|
fixed_t hyp;
|
|
fixed_t sineval;
|
|
angle_t distangle, offsetangle;
|
|
fixed_t vtop;
|
|
int lightnum;
|
|
|
|
// don't overflow and crash
|
|
if( ::g->ds_p == &::g->drawsegs[MAXDRAWSEGS] )
|
|
{
|
|
return;
|
|
}
|
|
|
|
#ifdef RANGECHECK
|
|
if( start >=::g->viewwidth || start > stop )
|
|
{
|
|
I_Error( "Bad R_RenderWallRange: %i to %i", start , stop );
|
|
}
|
|
#endif
|
|
|
|
::g->sidedef = ::g->curline->sidedef;
|
|
::g->linedef = ::g->curline->linedef;
|
|
|
|
// mark the segment as visible for auto map
|
|
::g->linedef->flags |= ML_MAPPED;
|
|
|
|
// calculate ::g->rw_distance for scale calculation
|
|
::g->rw_normalangle = ::g->curline->angle + ANG90;
|
|
offsetangle = abs( ( int )( ::g->rw_normalangle -::g->rw_angle1 ) );
|
|
|
|
if( offsetangle > ANG90 )
|
|
{
|
|
offsetangle = ANG90;
|
|
}
|
|
|
|
distangle = ANG90 - offsetangle;
|
|
hyp = R_PointToDist( ::g->curline->v1->x, ::g->curline->v1->y );
|
|
sineval = finesine[distangle >> ANGLETOFINESHIFT];
|
|
::g->rw_distance = FixedMul( hyp, sineval );
|
|
|
|
|
|
::g->ds_p->x1 = ::g->rw_x = start;
|
|
::g->ds_p->x2 = stop;
|
|
::g->ds_p->curline = ::g->curline;
|
|
::g->rw_stopx = stop + 1;
|
|
|
|
// calculate scale at both ends and step
|
|
extern angle_t GetViewAngle();
|
|
::g->ds_p->scale1 = ::g->rw_scale =
|
|
R_ScaleFromGlobalAngle( GetViewAngle() + ::g->xtoviewangle[start] );
|
|
|
|
if( stop > start )
|
|
{
|
|
::g->ds_p->scale2 = R_ScaleFromGlobalAngle( GetViewAngle() + ::g->xtoviewangle[stop] );
|
|
::g->ds_p->scalestep = ::g->rw_scalestep =
|
|
( ::g->ds_p->scale2 - ::g->rw_scale ) / ( stop - start );
|
|
}
|
|
else
|
|
{
|
|
// UNUSED: try to fix the stretched line bug
|
|
#if 0
|
|
if( ::g->rw_distance < FRACUNIT / 2 )
|
|
{
|
|
fixed_t trx, try;
|
|
fixed_t gxt, gyt;
|
|
|
|
extern fixed_t GetViewX();
|
|
extern fixed_t GetViewY();
|
|
trx = ::g->curline->v1->x - GetViewX();
|
|
try = ::g->curline->v1->y - GetVewY();
|
|
|
|
gxt = FixedMul( trx, ::g->viewcos );
|
|
gyt = -FixedMul( try, ::g->viewsin );
|
|
::g->ds_p->scale1 = FixedDiv( ::g->projection, gxt - gyt ) << ::g->detailshift;
|
|
}
|
|
#endif
|
|
::g->ds_p->scale2 = ::g->ds_p->scale1;
|
|
}
|
|
|
|
// calculate texture boundaries
|
|
// and decide if floor / ceiling marks are needed
|
|
::g->worldtop = ::g->frontsector->ceilingheight - ::g->viewz;
|
|
::g->worldbottom = ::g->frontsector->floorheight - ::g->viewz;
|
|
|
|
::g->midtexture = ::g->toptexture = ::g->bottomtexture = ::g->maskedtexture = 0;
|
|
::g->ds_p->maskedtexturecol = NULL;
|
|
|
|
if( !::g->backsector )
|
|
{
|
|
// single sided line
|
|
::g->midtexture = ::g->texturetranslation[::g->sidedef->midtexture];
|
|
// a single sided line is terminal, so it must mark ends
|
|
::g->markfloor = ::g->markceiling = true;
|
|
if( ::g->linedef->flags & ML_DONTPEGBOTTOM )
|
|
{
|
|
vtop = ::g->frontsector->floorheight +
|
|
::g->s_textureheight[::g->sidedef->midtexture];
|
|
// bottom of texture at bottom
|
|
::g->rw_midtexturemid = vtop - ::g->viewz;
|
|
}
|
|
else
|
|
{
|
|
// top of texture at top
|
|
::g->rw_midtexturemid = ::g->worldtop;
|
|
}
|
|
::g->rw_midtexturemid += ::g->sidedef->rowoffset;
|
|
|
|
::g->ds_p->silhouette = SIL_BOTH;
|
|
::g->ds_p->sprtopclip = ::g->screenheightarray;
|
|
::g->ds_p->sprbottomclip = ::g->negonearray;
|
|
::g->ds_p->bsilheight = MAXINT;
|
|
::g->ds_p->tsilheight = MININT;
|
|
}
|
|
else
|
|
{
|
|
// two sided line
|
|
::g->ds_p->sprtopclip = ::g->ds_p->sprbottomclip = NULL;
|
|
::g->ds_p->silhouette = 0;
|
|
|
|
if( ::g->frontsector->floorheight > ::g->backsector->floorheight )
|
|
{
|
|
::g->ds_p->silhouette = SIL_BOTTOM;
|
|
::g->ds_p->bsilheight = ::g->frontsector->floorheight;
|
|
}
|
|
else if( ::g->backsector->floorheight > ::g->viewz )
|
|
{
|
|
::g->ds_p->silhouette = SIL_BOTTOM;
|
|
::g->ds_p->bsilheight = MAXINT;
|
|
// ::g->ds_p->sprbottomclip = ::g->negonearray;
|
|
}
|
|
|
|
if( ::g->frontsector->ceilingheight < ::g->backsector->ceilingheight )
|
|
{
|
|
::g->ds_p->silhouette |= SIL_TOP;
|
|
::g->ds_p->tsilheight = ::g->frontsector->ceilingheight;
|
|
}
|
|
else if( ::g->backsector->ceilingheight < ::g->viewz )
|
|
{
|
|
::g->ds_p->silhouette |= SIL_TOP;
|
|
::g->ds_p->tsilheight = MININT;
|
|
// ::g->ds_p->sprtopclip = ::g->screenheightarray;
|
|
}
|
|
|
|
if( ::g->backsector->ceilingheight <= ::g->frontsector->floorheight )
|
|
{
|
|
::g->ds_p->sprbottomclip = ::g->negonearray;
|
|
::g->ds_p->bsilheight = MAXINT;
|
|
::g->ds_p->silhouette |= SIL_BOTTOM;
|
|
}
|
|
|
|
if( ::g->backsector->floorheight >= ::g->frontsector->ceilingheight )
|
|
{
|
|
::g->ds_p->sprtopclip = ::g->screenheightarray;
|
|
::g->ds_p->tsilheight = MININT;
|
|
::g->ds_p->silhouette |= SIL_TOP;
|
|
}
|
|
|
|
::g->worldhigh = ::g->backsector->ceilingheight - ::g->viewz;
|
|
::g->worldlow = ::g->backsector->floorheight - ::g->viewz;
|
|
|
|
// hack to allow height changes in outdoor areas
|
|
if( ::g->frontsector->ceilingpic == ::g->skyflatnum
|
|
&& ::g->backsector->ceilingpic == ::g->skyflatnum )
|
|
{
|
|
::g->worldtop = ::g->worldhigh;
|
|
}
|
|
|
|
|
|
if( ::g->worldlow != ::g->worldbottom
|
|
|| ::g->backsector->floorpic != ::g->frontsector->floorpic
|
|
|| ::g->backsector->lightlevel != ::g->frontsector->lightlevel )
|
|
{
|
|
::g->markfloor = true;
|
|
}
|
|
else
|
|
{
|
|
// same plane on both ::g->sides
|
|
::g->markfloor = false;
|
|
}
|
|
|
|
|
|
if( ::g->worldhigh != ::g->worldtop
|
|
|| ::g->backsector->ceilingpic != ::g->frontsector->ceilingpic
|
|
|| ::g->backsector->lightlevel != ::g->frontsector->lightlevel )
|
|
{
|
|
::g->markceiling = true;
|
|
}
|
|
else
|
|
{
|
|
// same plane on both ::g->sides
|
|
::g->markceiling = false;
|
|
}
|
|
|
|
if( ::g->backsector->ceilingheight <= ::g->frontsector->floorheight
|
|
|| ::g->backsector->floorheight >= ::g->frontsector->ceilingheight )
|
|
{
|
|
// closed door
|
|
::g->markceiling = ::g->markfloor = true;
|
|
}
|
|
|
|
|
|
if( ::g->worldhigh < ::g->worldtop )
|
|
{
|
|
// top texture
|
|
::g->toptexture = ::g->texturetranslation[::g->sidedef->toptexture];
|
|
if( ::g->linedef->flags & ML_DONTPEGTOP )
|
|
{
|
|
// top of texture at top
|
|
::g->rw_toptexturemid = ::g->worldtop;
|
|
}
|
|
else
|
|
{
|
|
vtop =
|
|
::g->backsector->ceilingheight
|
|
+ ::g->s_textureheight[::g->sidedef->toptexture];
|
|
|
|
// bottom of texture
|
|
::g->rw_toptexturemid = vtop - ::g->viewz;
|
|
}
|
|
}
|
|
if( ::g->worldlow > ::g->worldbottom )
|
|
{
|
|
// bottom texture
|
|
::g->bottomtexture = ::g->texturetranslation[::g->sidedef->bottomtexture];
|
|
|
|
if( ::g->linedef->flags & ML_DONTPEGBOTTOM )
|
|
{
|
|
// bottom of texture at bottom
|
|
// top of texture at top
|
|
::g->rw_bottomtexturemid = ::g->worldtop;
|
|
}
|
|
else // top of texture at top
|
|
{
|
|
::g->rw_bottomtexturemid = ::g->worldlow;
|
|
}
|
|
}
|
|
::g->rw_toptexturemid += ::g->sidedef->rowoffset;
|
|
::g->rw_bottomtexturemid += ::g->sidedef->rowoffset;
|
|
|
|
// allocate space for masked texture tables
|
|
if( ::g->sidedef->midtexture )
|
|
{
|
|
// masked ::g->midtexture
|
|
::g->maskedtexture = true;
|
|
::g->ds_p->maskedtexturecol = ::g->maskedtexturecol = ::g->lastopening - ::g->rw_x;
|
|
::g->lastopening += ::g->rw_stopx - ::g->rw_x;
|
|
}
|
|
}
|
|
|
|
// calculate ::g->rw_offset (only needed for textured ::g->lines)
|
|
::g->segtextured = ::g->midtexture | ::g->toptexture | ::g->bottomtexture | ::g->maskedtexture;
|
|
|
|
if( ::g->segtextured )
|
|
{
|
|
offsetangle = ::g->rw_normalangle -::g->rw_angle1;
|
|
|
|
if( offsetangle > ANG180 )
|
|
{
|
|
offsetangle = UINT_MAX - offsetangle + 1; // ALANHACK UNSIGNED, SRS - make uint math explicit
|
|
}
|
|
|
|
if( offsetangle > ANG90 )
|
|
{
|
|
offsetangle = ANG90;
|
|
}
|
|
|
|
sineval = finesine[offsetangle >> ANGLETOFINESHIFT];
|
|
::g->rw_offset = FixedMul( hyp, sineval );
|
|
|
|
if( ::g->rw_normalangle -::g->rw_angle1 < ANG180 )
|
|
{
|
|
::g->rw_offset = -::g->rw_offset;
|
|
}
|
|
|
|
::g->rw_offset += ::g->sidedef->textureoffset + ::g->curline->offset;
|
|
::g->rw_centerangle = ANG90 + GetViewAngle() - ::g->rw_normalangle;
|
|
|
|
// calculate light table
|
|
// use different light tables
|
|
// for horizontal / vertical / diagonal
|
|
// OPTIMIZE: get rid of LIGHTSEGSHIFT globally
|
|
if( !::g->fixedcolormap )
|
|
{
|
|
lightnum = ( ::g->frontsector->lightlevel >> LIGHTSEGSHIFT ) +::g->extralight;
|
|
|
|
if( ::g->curline->v1->y == ::g->curline->v2->y )
|
|
{
|
|
lightnum--;
|
|
}
|
|
else if( ::g->curline->v1->x == ::g->curline->v2->x )
|
|
{
|
|
lightnum++;
|
|
}
|
|
|
|
if( lightnum < 0 )
|
|
{
|
|
::g->walllights = ::g->scalelight[0];
|
|
}
|
|
else if( lightnum >= LIGHTLEVELS )
|
|
{
|
|
::g->walllights = ::g->scalelight[LIGHTLEVELS - 1];
|
|
}
|
|
else
|
|
{
|
|
::g->walllights = ::g->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( ::g->frontsector->floorheight >= ::g->viewz )
|
|
{
|
|
// above view plane
|
|
::g->markfloor = false;
|
|
}
|
|
|
|
if( ::g->frontsector->ceilingheight <= ::g->viewz
|
|
&& ::g->frontsector->ceilingpic != ::g->skyflatnum )
|
|
{
|
|
// below view plane
|
|
::g->markceiling = false;
|
|
}
|
|
|
|
|
|
// calculate incremental stepping values for texture edges
|
|
::g->worldtop >>= 4;
|
|
::g->worldbottom >>= 4;
|
|
|
|
::g->topstep = -FixedMul( ::g->rw_scalestep, ::g->worldtop );
|
|
::g->topfrac = ( ::g->centeryfrac >> 4 ) - FixedMul( ::g->worldtop, ::g->rw_scale );
|
|
|
|
::g->bottomstep = -FixedMul( ::g->rw_scalestep, ::g->worldbottom );
|
|
::g->bottomfrac = ( ::g->centeryfrac >> 4 ) - FixedMul( ::g->worldbottom, ::g->rw_scale );
|
|
|
|
if( ::g->backsector )
|
|
{
|
|
::g->worldhigh >>= 4;
|
|
::g->worldlow >>= 4;
|
|
|
|
if( ::g->worldhigh < ::g->worldtop )
|
|
{
|
|
::g->pixhigh = ( ::g->centeryfrac >> 4 ) - FixedMul( ::g->worldhigh, ::g->rw_scale );
|
|
::g->pixhighstep = -FixedMul( ::g->rw_scalestep, ::g->worldhigh );
|
|
}
|
|
|
|
if( ::g->worldlow > ::g->worldbottom )
|
|
{
|
|
::g->pixlow = ( ::g->centeryfrac >> 4 ) - FixedMul( ::g->worldlow, ::g->rw_scale );
|
|
::g->pixlowstep = -FixedMul( ::g->rw_scalestep, ::g->worldlow );
|
|
}
|
|
}
|
|
|
|
// render it
|
|
if( ::g->markceiling )
|
|
{
|
|
::g->ceilingplane = R_CheckPlane( ::g->ceilingplane, ::g->rw_x, ::g->rw_stopx - 1 );
|
|
}
|
|
|
|
if( ::g->markfloor )
|
|
{
|
|
::g->floorplane = R_CheckPlane( ::g->floorplane, ::g->rw_x, ::g->rw_stopx - 1 );
|
|
}
|
|
|
|
R_RenderSegLoop();
|
|
|
|
|
|
// save sprite clipping info
|
|
if( ( ( ::g->ds_p->silhouette & SIL_TOP ) || ::g->maskedtexture )
|
|
&& !::g->ds_p->sprtopclip )
|
|
{
|
|
memcpy( ::g->lastopening, ::g->ceilingclip + start, 2 * ( ::g->rw_stopx - start ) );
|
|
::g->ds_p->sprtopclip = ::g->lastopening - start;
|
|
::g->lastopening += ::g->rw_stopx - start;
|
|
}
|
|
|
|
if( ( ( ::g->ds_p->silhouette & SIL_BOTTOM ) || ::g->maskedtexture )
|
|
&& !::g->ds_p->sprbottomclip )
|
|
{
|
|
memcpy( ::g->lastopening, ::g->floorclip + start, 2 * ( ::g->rw_stopx - start ) );
|
|
::g->ds_p->sprbottomclip = ::g->lastopening - start;
|
|
::g->lastopening += ::g->rw_stopx - start;
|
|
}
|
|
|
|
if( ::g->maskedtexture && !( ::g->ds_p->silhouette & SIL_TOP ) )
|
|
{
|
|
::g->ds_p->silhouette |= SIL_TOP;
|
|
::g->ds_p->tsilheight = MININT;
|
|
}
|
|
if( ::g->maskedtexture && !( ::g->ds_p->silhouette & SIL_BOTTOM ) )
|
|
{
|
|
::g->ds_p->silhouette |= SIL_BOTTOM;
|
|
::g->ds_p->bsilheight = MAXINT;
|
|
}
|
|
::g->ds_p++;
|
|
}
|
|
|
|
|