729 lines
20 KiB
C
729 lines
20 KiB
C
|
// Emacs style mode select -*- C++ -*-
|
||
|
//-----------------------------------------------------------------------------
|
||
|
//
|
||
|
// $Id:$
|
||
|
//
|
||
|
// Copyright (C) 1993-1996 by id Software, Inc.
|
||
|
//
|
||
|
// This source is available for distribution and/or modification
|
||
|
// only under the terms of the DOOM Source Code License as
|
||
|
// published by id Software. All rights reserved.
|
||
|
//
|
||
|
// The source is distributed in the hope that it will be useful,
|
||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
|
||
|
// for more details.
|
||
|
//
|
||
|
// $Log:$
|
||
|
//
|
||
|
// DESCRIPTION:
|
||
|
// All the clipping: columns, horizontal spans, sky columns.
|
||
|
//
|
||
|
//-----------------------------------------------------------------------------
|
||
|
|
||
|
|
||
|
#include "doom_config.h"
|
||
|
|
||
|
|
||
|
|
||
|
#include "i_system.h"
|
||
|
#include "doomdef.h"
|
||
|
#include "doomstat.h"
|
||
|
#include "r_local.h"
|
||
|
#include "r_sky.h"
|
||
|
|
||
|
|
||
|
#define HEIGHTBITS 12
|
||
|
#define HEIGHTUNIT (1<<HEIGHTBITS)
|
||
|
|
||
|
|
||
|
// OPTIMIZE: closed two sided lines as single sided
|
||
|
|
||
|
// True if any of the segs textures might be visible.
|
||
|
doom_boolean segtextured;
|
||
|
|
||
|
// False if the back side is the same plane.
|
||
|
doom_boolean markfloor;
|
||
|
doom_boolean markceiling;
|
||
|
|
||
|
doom_boolean maskedtexture;
|
||
|
int toptexture;
|
||
|
int bottomtexture;
|
||
|
int midtexture;
|
||
|
|
||
|
angle_t rw_normalangle;
|
||
|
// angle to line origin
|
||
|
int rw_angle1;
|
||
|
|
||
|
//
|
||
|
// regular wall
|
||
|
//
|
||
|
int rw_x;
|
||
|
int rw_stopx;
|
||
|
angle_t rw_centerangle;
|
||
|
fixed_t rw_offset;
|
||
|
fixed_t rw_distance;
|
||
|
fixed_t rw_scale;
|
||
|
fixed_t rw_scalestep;
|
||
|
fixed_t rw_midtexturemid;
|
||
|
fixed_t rw_toptexturemid;
|
||
|
fixed_t rw_bottomtexturemid;
|
||
|
|
||
|
int worldtop;
|
||
|
int worldbottom;
|
||
|
int worldhigh;
|
||
|
int worldlow;
|
||
|
|
||
|
fixed_t pixhigh;
|
||
|
fixed_t pixlow;
|
||
|
fixed_t pixhighstep;
|
||
|
fixed_t pixlowstep;
|
||
|
|
||
|
fixed_t topfrac;
|
||
|
fixed_t topstep;
|
||
|
|
||
|
fixed_t bottomfrac;
|
||
|
fixed_t bottomstep;
|
||
|
|
||
|
lighttable_t** walllights;
|
||
|
|
||
|
short* maskedtexturecol;
|
||
|
|
||
|
|
||
|
//
|
||
|
// R_RenderMaskedSegRange
|
||
|
//
|
||
|
void R_RenderMaskedSegRange(drawseg_t* ds, int x1, int x2)
|
||
|
{
|
||
|
unsigned index;
|
||
|
column_t* col;
|
||
|
int lightnum;
|
||
|
int texnum;
|
||
|
|
||
|
// 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;
|
||
|
texnum = texturetranslation[curline->sidedef->midtexture];
|
||
|
|
||
|
lightnum = (frontsector->lightlevel >> LIGHTSEGSHIFT) + extralight;
|
||
|
|
||
|
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;
|
||
|
|
||
|
rw_scalestep = ds->scalestep;
|
||
|
spryscale = ds->scale1 + (x1 - ds->x1) * rw_scalestep;
|
||
|
mfloorclip = ds->sprbottomclip;
|
||
|
mceilingclip = ds->sprtopclip;
|
||
|
|
||
|
// find positioning
|
||
|
if (curline->linedef->flags & ML_DONTPEGBOTTOM)
|
||
|
{
|
||
|
dc_texturemid = frontsector->floorheight > backsector->floorheight
|
||
|
? frontsector->floorheight : backsector->floorheight;
|
||
|
dc_texturemid = dc_texturemid + textureheight[texnum] - viewz;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
dc_texturemid = frontsector->ceilingheight < backsector->ceilingheight
|
||
|
? frontsector->ceilingheight : backsector->ceilingheight;
|
||
|
dc_texturemid = dc_texturemid - viewz;
|
||
|
}
|
||
|
dc_texturemid += curline->sidedef->rowoffset;
|
||
|
|
||
|
if (fixedcolormap)
|
||
|
dc_colormap = fixedcolormap;
|
||
|
|
||
|
// draw the columns
|
||
|
for (dc_x = x1; dc_x <= x2; dc_x++)
|
||
|
{
|
||
|
// calculate lighting
|
||
|
if (maskedtexturecol[dc_x] != DOOM_MAXSHORT)
|
||
|
{
|
||
|
if (!fixedcolormap)
|
||
|
{
|
||
|
index = spryscale >> LIGHTSCALESHIFT;
|
||
|
|
||
|
if (index >= MAXLIGHTSCALE)
|
||
|
index = MAXLIGHTSCALE - 1;
|
||
|
|
||
|
dc_colormap = walllights[index];
|
||
|
}
|
||
|
|
||
|
sprtopscreen = centeryfrac - FixedMul(dc_texturemid, spryscale);
|
||
|
dc_iscale = 0xffffffffu / (unsigned)spryscale;
|
||
|
|
||
|
// draw the texture
|
||
|
col = (column_t*)(
|
||
|
(byte*)R_GetColumn(texnum, maskedtexturecol[dc_x]) - 3);
|
||
|
|
||
|
R_DrawMaskedColumn(col);
|
||
|
maskedtexturecol[dc_x] = DOOM_MAXSHORT;
|
||
|
}
|
||
|
spryscale += 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;
|
||
|
|
||
|
for (; rw_x < rw_stopx; rw_x++)
|
||
|
{
|
||
|
// mark floor / ceiling areas
|
||
|
yl = (topfrac + HEIGHTUNIT - 1) >> HEIGHTBITS;
|
||
|
|
||
|
// no space above wall?
|
||
|
if (yl < ceilingclip[rw_x] + 1)
|
||
|
yl = ceilingclip[rw_x] + 1;
|
||
|
|
||
|
if (markceiling)
|
||
|
{
|
||
|
top = ceilingclip[rw_x] + 1;
|
||
|
bottom = yl - 1;
|
||
|
|
||
|
if (bottom >= floorclip[rw_x])
|
||
|
bottom = floorclip[rw_x] - 1;
|
||
|
|
||
|
if (top <= bottom)
|
||
|
{
|
||
|
ceilingplane->top[rw_x] = top;
|
||
|
ceilingplane->bottom[rw_x] = bottom;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
yh = bottomfrac >> HEIGHTBITS;
|
||
|
|
||
|
if (yh >= floorclip[rw_x])
|
||
|
yh = floorclip[rw_x] - 1;
|
||
|
|
||
|
if (markfloor)
|
||
|
{
|
||
|
top = yh + 1;
|
||
|
bottom = floorclip[rw_x] - 1;
|
||
|
if (top <= ceilingclip[rw_x])
|
||
|
top = ceilingclip[rw_x] + 1;
|
||
|
if (top <= bottom)
|
||
|
{
|
||
|
floorplane->top[rw_x] = top;
|
||
|
floorplane->bottom[rw_x] = bottom;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// texturecolumn and lighting are independent of wall tiers
|
||
|
if (segtextured)
|
||
|
{
|
||
|
// calculate texture offset
|
||
|
angle = (rw_centerangle + xtoviewangle[rw_x]) >> ANGLETOFINESHIFT;
|
||
|
texturecolumn = rw_offset - FixedMul(finetangent[angle], rw_distance);
|
||
|
texturecolumn >>= FRACBITS;
|
||
|
// calculate lighting
|
||
|
index = rw_scale >> LIGHTSCALESHIFT;
|
||
|
|
||
|
if (index >= MAXLIGHTSCALE)
|
||
|
index = MAXLIGHTSCALE - 1;
|
||
|
|
||
|
dc_colormap = walllights[index];
|
||
|
dc_x = rw_x;
|
||
|
dc_iscale = 0xffffffffu / (unsigned)rw_scale;
|
||
|
}
|
||
|
|
||
|
// draw the wall tiers
|
||
|
if (midtexture)
|
||
|
{
|
||
|
// single sided line
|
||
|
dc_yl = yl;
|
||
|
dc_yh = yh;
|
||
|
dc_texturemid = rw_midtexturemid;
|
||
|
dc_source = R_GetColumn(midtexture, texturecolumn);
|
||
|
colfunc();
|
||
|
ceilingclip[rw_x] = viewheight;
|
||
|
floorclip[rw_x] = -1;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// two sided line
|
||
|
if (toptexture)
|
||
|
{
|
||
|
// top wall
|
||
|
mid = pixhigh >> HEIGHTBITS;
|
||
|
pixhigh += pixhighstep;
|
||
|
|
||
|
if (mid >= floorclip[rw_x])
|
||
|
mid = floorclip[rw_x] - 1;
|
||
|
|
||
|
if (mid >= yl)
|
||
|
{
|
||
|
dc_yl = yl;
|
||
|
dc_yh = mid;
|
||
|
dc_texturemid = rw_toptexturemid;
|
||
|
dc_source = R_GetColumn(toptexture, texturecolumn);
|
||
|
colfunc();
|
||
|
ceilingclip[rw_x] = mid;
|
||
|
}
|
||
|
else
|
||
|
ceilingclip[rw_x] = yl - 1;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// no top wall
|
||
|
if (markceiling)
|
||
|
ceilingclip[rw_x] = yl - 1;
|
||
|
}
|
||
|
|
||
|
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;
|
||
|
|
||
|
if (mid <= yh)
|
||
|
{
|
||
|
dc_yl = mid;
|
||
|
dc_yh = yh;
|
||
|
dc_texturemid = rw_bottomtexturemid;
|
||
|
dc_source = R_GetColumn(bottomtexture,
|
||
|
texturecolumn);
|
||
|
colfunc();
|
||
|
floorclip[rw_x] = mid;
|
||
|
}
|
||
|
else
|
||
|
floorclip[rw_x] = yh + 1;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// no bottom wall
|
||
|
if (markfloor)
|
||
|
floorclip[rw_x] = yh + 1;
|
||
|
}
|
||
|
|
||
|
if (maskedtexture)
|
||
|
{
|
||
|
// save texturecol
|
||
|
// for backdrawing of masked mid texture
|
||
|
maskedtexturecol[rw_x] = texturecolumn;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
rw_scale += rw_scalestep;
|
||
|
topfrac += topstep;
|
||
|
bottomfrac += 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 (ds_p == &drawsegs[MAXDRAWSEGS])
|
||
|
return;
|
||
|
|
||
|
#ifdef RANGECHECK
|
||
|
if (start >= viewwidth || start > stop)
|
||
|
{
|
||
|
//I_Error("Error: Bad R_RenderWallRange: %i to %i", start, stop);
|
||
|
|
||
|
doom_strcpy(error_buf, "Error: Bad R_RenderWallRange: ");
|
||
|
doom_concat(error_buf, doom_itoa(start, 10));
|
||
|
doom_concat(error_buf, " to ");
|
||
|
doom_concat(error_buf, doom_itoa(stop, 10));
|
||
|
I_Error(error_buf);
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
sidedef = curline->sidedef;
|
||
|
linedef = curline->linedef;
|
||
|
|
||
|
// mark the segment as visible for auto map
|
||
|
linedef->flags |= ML_MAPPED;
|
||
|
|
||
|
// calculate rw_distance for scale calculation
|
||
|
rw_normalangle = curline->angle + ANG90;
|
||
|
offsetangle = (angle_t)doom_abs((int)rw_normalangle - (int)rw_angle1);
|
||
|
|
||
|
if (offsetangle > ANG90)
|
||
|
offsetangle = ANG90;
|
||
|
|
||
|
distangle = ANG90 - offsetangle;
|
||
|
hyp = R_PointToDist(curline->v1->x, curline->v1->y);
|
||
|
sineval = finesine[distangle >> ANGLETOFINESHIFT];
|
||
|
rw_distance = FixedMul(hyp, sineval);
|
||
|
|
||
|
|
||
|
ds_p->x1 = rw_x = start;
|
||
|
ds_p->x2 = stop;
|
||
|
ds_p->curline = curline;
|
||
|
rw_stopx = stop + 1;
|
||
|
|
||
|
// 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]);
|
||
|
ds_p->scalestep = rw_scalestep =
|
||
|
(ds_p->scale2 - rw_scale) / (stop - start);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// UNUSED: try to fix the stretched line bug
|
||
|
#if 0
|
||
|
if (rw_distance < FRACUNIT / 2)
|
||
|
{
|
||
|
fixed_t trx, try;
|
||
|
fixed_t gxt, gyt;
|
||
|
|
||
|
trx = curline->v1->x - viewx;
|
||
|
try = curline->v1->y - viewy;
|
||
|
|
||
|
gxt = FixedMul(trx, viewcos);
|
||
|
gyt = -FixedMul(try, viewsin);
|
||
|
ds_p->scale1 = FixedDiv(projection, gxt - gyt) << detailshift;
|
||
|
}
|
||
|
#endif
|
||
|
ds_p->scale2 = ds_p->scale1;
|
||
|
}
|
||
|
|
||
|
// calculate texture boundaries
|
||
|
// and decide if floor / ceiling marks are needed
|
||
|
worldtop = frontsector->ceilingheight - viewz;
|
||
|
worldbottom = frontsector->floorheight - viewz;
|
||
|
|
||
|
midtexture = toptexture = bottomtexture = maskedtexture = 0;
|
||
|
ds_p->maskedtexturecol = 0;
|
||
|
|
||
|
if (!backsector)
|
||
|
{
|
||
|
// single sided line
|
||
|
midtexture = texturetranslation[sidedef->midtexture];
|
||
|
// a single sided line is terminal, so it must mark ends
|
||
|
markfloor = markceiling = true;
|
||
|
if (linedef->flags & ML_DONTPEGBOTTOM)
|
||
|
{
|
||
|
vtop = frontsector->floorheight +
|
||
|
textureheight[sidedef->midtexture];
|
||
|
// bottom of texture at bottom
|
||
|
rw_midtexturemid = vtop - viewz;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// top of texture at top
|
||
|
rw_midtexturemid = worldtop;
|
||
|
}
|
||
|
rw_midtexturemid += sidedef->rowoffset;
|
||
|
|
||
|
ds_p->silhouette = SIL_BOTH;
|
||
|
ds_p->sprtopclip = screenheightarray;
|
||
|
ds_p->sprbottomclip = negonearray;
|
||
|
ds_p->bsilheight = DOOM_MAXINT;
|
||
|
ds_p->tsilheight = DOOM_MININT;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// two sided line
|
||
|
ds_p->sprtopclip = ds_p->sprbottomclip = 0;
|
||
|
ds_p->silhouette = 0;
|
||
|
|
||
|
if (frontsector->floorheight > backsector->floorheight)
|
||
|
{
|
||
|
ds_p->silhouette = SIL_BOTTOM;
|
||
|
ds_p->bsilheight = frontsector->floorheight;
|
||
|
}
|
||
|
else if (backsector->floorheight > viewz)
|
||
|
{
|
||
|
ds_p->silhouette = SIL_BOTTOM;
|
||
|
ds_p->bsilheight = DOOM_MAXINT;
|
||
|
// ds_p->sprbottomclip = negonearray;
|
||
|
}
|
||
|
|
||
|
if (frontsector->ceilingheight < backsector->ceilingheight)
|
||
|
{
|
||
|
ds_p->silhouette |= SIL_TOP;
|
||
|
ds_p->tsilheight = frontsector->ceilingheight;
|
||
|
}
|
||
|
else if (backsector->ceilingheight < viewz)
|
||
|
{
|
||
|
ds_p->silhouette |= SIL_TOP;
|
||
|
ds_p->tsilheight = DOOM_MININT;
|
||
|
// ds_p->sprtopclip = screenheightarray;
|
||
|
}
|
||
|
|
||
|
if (backsector->ceilingheight <= frontsector->floorheight)
|
||
|
{
|
||
|
ds_p->sprbottomclip = negonearray;
|
||
|
ds_p->bsilheight = DOOM_MAXINT;
|
||
|
ds_p->silhouette |= SIL_BOTTOM;
|
||
|
}
|
||
|
|
||
|
if (backsector->floorheight >= frontsector->ceilingheight)
|
||
|
{
|
||
|
ds_p->sprtopclip = screenheightarray;
|
||
|
ds_p->tsilheight = DOOM_MININT;
|
||
|
ds_p->silhouette |= SIL_TOP;
|
||
|
}
|
||
|
|
||
|
worldhigh = backsector->ceilingheight - viewz;
|
||
|
worldlow = backsector->floorheight - viewz;
|
||
|
|
||
|
// hack to allow height changes in outdoor areas
|
||
|
if (frontsector->ceilingpic == skyflatnum
|
||
|
&& backsector->ceilingpic == skyflatnum)
|
||
|
{
|
||
|
worldtop = worldhigh;
|
||
|
}
|
||
|
|
||
|
if (worldlow != worldbottom
|
||
|
|| backsector->floorpic != frontsector->floorpic
|
||
|
|| backsector->lightlevel != frontsector->lightlevel)
|
||
|
{
|
||
|
markfloor = true;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// same plane on both sides
|
||
|
markfloor = false;
|
||
|
}
|
||
|
|
||
|
if (worldhigh != worldtop
|
||
|
|| backsector->ceilingpic != frontsector->ceilingpic
|
||
|
|| backsector->lightlevel != frontsector->lightlevel)
|
||
|
{
|
||
|
markceiling = true;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// same plane on both sides
|
||
|
markceiling = false;
|
||
|
}
|
||
|
|
||
|
if (backsector->ceilingheight <= frontsector->floorheight
|
||
|
|| backsector->floorheight >= frontsector->ceilingheight)
|
||
|
{
|
||
|
// closed door
|
||
|
markceiling = markfloor = true;
|
||
|
}
|
||
|
|
||
|
if (worldhigh < worldtop)
|
||
|
{
|
||
|
// top texture
|
||
|
toptexture = texturetranslation[sidedef->toptexture];
|
||
|
if (linedef->flags & ML_DONTPEGTOP)
|
||
|
{
|
||
|
// top of texture at top
|
||
|
rw_toptexturemid = worldtop;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
vtop =
|
||
|
backsector->ceilingheight
|
||
|
+ textureheight[sidedef->toptexture];
|
||
|
|
||
|
// bottom of texture
|
||
|
rw_toptexturemid = vtop - viewz;
|
||
|
}
|
||
|
}
|
||
|
if (worldlow > worldbottom)
|
||
|
{
|
||
|
// bottom texture
|
||
|
bottomtexture = texturetranslation[sidedef->bottomtexture];
|
||
|
|
||
|
if (linedef->flags & ML_DONTPEGBOTTOM)
|
||
|
{
|
||
|
// bottom of texture at bottom
|
||
|
// top of texture at top
|
||
|
rw_bottomtexturemid = worldtop;
|
||
|
}
|
||
|
else // top of texture at top
|
||
|
rw_bottomtexturemid = worldlow;
|
||
|
}
|
||
|
rw_toptexturemid += sidedef->rowoffset;
|
||
|
rw_bottomtexturemid += sidedef->rowoffset;
|
||
|
|
||
|
// allocate space for masked texture tables
|
||
|
if (sidedef->midtexture)
|
||
|
{
|
||
|
// masked midtexture
|
||
|
maskedtexture = true;
|
||
|
ds_p->maskedtexturecol = maskedtexturecol = lastopening - rw_x;
|
||
|
lastopening += rw_stopx - rw_x;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// calculate rw_offset (only needed for textured lines)
|
||
|
segtextured = midtexture | toptexture | bottomtexture | maskedtexture;
|
||
|
|
||
|
if (segtextured)
|
||
|
{
|
||
|
offsetangle = rw_normalangle - rw_angle1;
|
||
|
|
||
|
if (offsetangle > ANG180)
|
||
|
#pragma warning(push)
|
||
|
#pragma warning(disable : 4146)
|
||
|
offsetangle = -offsetangle;
|
||
|
#pragma warning(pop)
|
||
|
|
||
|
if (offsetangle > ANG90)
|
||
|
offsetangle = ANG90;
|
||
|
|
||
|
sineval = finesine[offsetangle >> ANGLETOFINESHIFT];
|
||
|
rw_offset = FixedMul(hyp, sineval);
|
||
|
|
||
|
if (rw_normalangle - rw_angle1 < ANG180)
|
||
|
rw_offset = -rw_offset;
|
||
|
|
||
|
rw_offset += sidedef->textureoffset + curline->offset;
|
||
|
rw_centerangle = ANG90 + viewangle - rw_normalangle;
|
||
|
|
||
|
// calculate light table
|
||
|
// use different light tables
|
||
|
// for horizontal / vertical / diagonal
|
||
|
// OPTIMIZE: get rid of LIGHTSEGSHIFT globally
|
||
|
if (!fixedcolormap)
|
||
|
{
|
||
|
lightnum = (frontsector->lightlevel >> LIGHTSEGSHIFT) + extralight;
|
||
|
|
||
|
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->floorheight >= viewz)
|
||
|
{
|
||
|
// above view plane
|
||
|
markfloor = false;
|
||
|
}
|
||
|
|
||
|
if (frontsector->ceilingheight <= viewz
|
||
|
&& frontsector->ceilingpic != skyflatnum)
|
||
|
{
|
||
|
// below view plane
|
||
|
markceiling = false;
|
||
|
}
|
||
|
|
||
|
|
||
|
// calculate incremental stepping values for texture edges
|
||
|
worldtop >>= 4;
|
||
|
worldbottom >>= 4;
|
||
|
|
||
|
topstep = -FixedMul(rw_scalestep, worldtop);
|
||
|
topfrac = (centeryfrac >> 4) - FixedMul(worldtop, rw_scale);
|
||
|
|
||
|
bottomstep = -FixedMul(rw_scalestep, worldbottom);
|
||
|
bottomfrac = (centeryfrac >> 4) - FixedMul(worldbottom, rw_scale);
|
||
|
|
||
|
if (backsector)
|
||
|
{
|
||
|
worldhigh >>= 4;
|
||
|
worldlow >>= 4;
|
||
|
|
||
|
if (worldhigh < worldtop)
|
||
|
{
|
||
|
pixhigh = (centeryfrac >> 4) - FixedMul(worldhigh, rw_scale);
|
||
|
pixhighstep = -FixedMul(rw_scalestep, worldhigh);
|
||
|
}
|
||
|
|
||
|
if (worldlow > worldbottom)
|
||
|
{
|
||
|
pixlow = (centeryfrac >> 4) - FixedMul(worldlow, rw_scale);
|
||
|
pixlowstep = -FixedMul(rw_scalestep, worldlow);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// render it
|
||
|
if (markceiling)
|
||
|
ceilingplane = R_CheckPlane(ceilingplane, rw_x, rw_stopx - 1);
|
||
|
|
||
|
if (markfloor)
|
||
|
floorplane = R_CheckPlane(floorplane, rw_x, rw_stopx - 1);
|
||
|
|
||
|
R_RenderSegLoop();
|
||
|
|
||
|
// save sprite clipping info
|
||
|
if (((ds_p->silhouette & SIL_TOP) || maskedtexture)
|
||
|
&& !ds_p->sprtopclip)
|
||
|
{
|
||
|
doom_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)
|
||
|
{
|
||
|
doom_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;
|
||
|
ds_p->tsilheight = DOOM_MININT;
|
||
|
}
|
||
|
if (maskedtexture && !(ds_p->silhouette & SIL_BOTTOM))
|
||
|
{
|
||
|
ds_p->silhouette |= SIL_BOTTOM;
|
||
|
ds_p->bsilheight = DOOM_MAXINT;
|
||
|
}
|
||
|
ds_p++;
|
||
|
}
|