mirror of
https://github.com/id-Software/DOOM-3-BFG.git
synced 2024-11-22 04:12:09 +00:00
718 lines
19 KiB
C++
718 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((long)(::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 = -offsetangle; // ALANHACK UNSIGNED
|
|
|
|
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++;
|
|
}
|
|
|
|
|