📄 r_segs.c
字号:
// between start and stop pixels (inclusive).
//
void R_StoreWallRange( int start, int stop, PBUFFER ViewWindowBuffer/*DQ*/ )
{
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 > stop)
{
int hold;
hold = start;
start = stop;
stop = hold;
//WriteDebug("R_StoreWallRange ASS BACKWARDS...\n");
}
if (start >= viewwidth)
{
WriteDebug("R_StoreWallRange start >= viewwidth...\n");
return;
}
//I_Error ("Bad R_StoreWallRange: %i to %i : %i ", start , stop, viewwidth);
#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 = abs(rw_normalangle-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 = NULL;
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 = MAXINT;
ds_p->tsilheight = MININT;
}
else
{
// two sided line
ds_p->sprtopclip = ds_p->sprbottomclip = NULL;
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 = 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 = MININT;
// ds_p->sprtopclip = screenheightarray;
}
if (backsector->ceilingheight <= frontsector->floorheight)
{
ds_p->sprbottomclip = negonearray;
ds_p->bsilheight = MAXINT;
ds_p->silhouette |= SIL_BOTTOM;
}
if (backsector->floorheight >= frontsector->ceilingheight)
{
ds_p->sprtopclip = screenheightarray;
ds_p->tsilheight = 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)
offsetangle = (offsetangle * -1);
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 (ViewWindowBuffer/*DQ*/);
// save sprite clipping info
if ( ((ds_p->silhouette & SIL_TOP) || maskedtexture) && !ds_p->sprtopclip)
{
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)
{
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 = MININT;
}
if (maskedtexture && !(ds_p->silhouette&SIL_BOTTOM))
{
ds_p->silhouette |= SIL_BOTTOM;
ds_p->bsilheight = MAXINT;
}
ds_p++;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -