mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2024-11-22 04:21:23 +00:00
Fix issues related to texture scaling
This commit is contained in:
parent
2747e30f8c
commit
98ba396dbc
9 changed files with 541 additions and 434 deletions
|
@ -1034,6 +1034,191 @@ static boolean HWR_BlendMidtextureSurface(FSurfaceInfo *pSurf)
|
|||
return true;
|
||||
}
|
||||
|
||||
static void HWR_RenderMidtexture(INT32 gl_midtexture, float cliplow, float cliphigh, fixed_t worldtop, fixed_t worldbottom, fixed_t worldhigh, fixed_t worldlow, fixed_t worldtopslope, fixed_t worldbottomslope, fixed_t worldhighslope, fixed_t worldlowslope, UINT32 lightnum, FOutVector *inWallVerts)
|
||||
{
|
||||
FOutVector wallVerts[4];
|
||||
|
||||
FSurfaceInfo Surf;
|
||||
Surf.PolyColor.s.alpha = 255;
|
||||
|
||||
// Determine if it's visible
|
||||
if (!HWR_BlendMidtextureSurface(&Surf))
|
||||
return;
|
||||
|
||||
fixed_t texheight = FixedDiv(textureheight[gl_midtexture], abs(gl_sidedef->scaley_mid));
|
||||
INT32 repeats;
|
||||
|
||||
if (gl_sidedef->repeatcnt)
|
||||
repeats = 1 + gl_sidedef->repeatcnt;
|
||||
else if (gl_linedef->flags & ML_WRAPMIDTEX)
|
||||
{
|
||||
fixed_t high, low;
|
||||
|
||||
if (gl_frontsector->ceilingheight > gl_backsector->ceilingheight)
|
||||
high = gl_backsector->ceilingheight;
|
||||
else
|
||||
high = gl_frontsector->ceilingheight;
|
||||
|
||||
if (gl_frontsector->floorheight > gl_backsector->floorheight)
|
||||
low = gl_frontsector->floorheight;
|
||||
else
|
||||
low = gl_backsector->floorheight;
|
||||
|
||||
repeats = (high - low) / texheight;
|
||||
if ((high - low) % texheight)
|
||||
repeats++; // tile an extra time to fill the gap -- Monster Iestyn
|
||||
}
|
||||
else
|
||||
repeats = 1;
|
||||
|
||||
GLMapTexture_t *grTex = HWR_GetTexture(gl_midtexture);
|
||||
float xscale = FixedToFloat(gl_sidedef->scalex_mid);
|
||||
float yscale = FixedToFloat(gl_sidedef->scaley_mid);
|
||||
|
||||
// SoM: a little note: popentop and popenbottom
|
||||
// record the limits the texture can be displayed in.
|
||||
// polytop and polybottom, are the ideal (i.e. unclipped)
|
||||
// heights of the polygon, and h & l, are the final (clipped)
|
||||
// poly coords.
|
||||
fixed_t popentop, popenbottom, polytop, polybottom, lowcut, highcut;
|
||||
fixed_t popentopslope, popenbottomslope, polytopslope, polybottomslope, lowcutslope, highcutslope;
|
||||
|
||||
// NOTE: With polyobjects, whenever you need to check the properties of the polyobject sector it belongs to,
|
||||
// you must use the linedef's backsector to be correct
|
||||
// From CB
|
||||
if (gl_curline->polyseg)
|
||||
{
|
||||
// Change this when polyobjects support slopes
|
||||
popentop = popentopslope = gl_curline->backsector->ceilingheight;
|
||||
popenbottom = popenbottomslope = gl_curline->backsector->floorheight;
|
||||
}
|
||||
else
|
||||
{
|
||||
popentop = min(worldtop, worldhigh);
|
||||
popenbottom = max(worldbottom, worldlow);
|
||||
popentopslope = min(worldtopslope, worldhighslope);
|
||||
popenbottomslope = max(worldbottomslope, worldlowslope);
|
||||
}
|
||||
|
||||
// Find the wall's coordinates
|
||||
fixed_t midtexheight = texheight * repeats;
|
||||
|
||||
fixed_t rowoffset = FixedDiv(gl_sidedef->rowoffset + gl_sidedef->offsety_mid, abs(gl_sidedef->scaley_mid));
|
||||
|
||||
// Texture is not skewed
|
||||
if (gl_linedef->flags & ML_NOSKEW)
|
||||
{
|
||||
// Peg it to the floor
|
||||
if (gl_linedef->flags & ML_MIDPEG)
|
||||
{
|
||||
polybottom = max(gl_frontsector->floorheight, gl_backsector->floorheight) + rowoffset;
|
||||
polytop = polybottom + midtexheight;
|
||||
}
|
||||
// Peg it to the ceiling
|
||||
else
|
||||
{
|
||||
polytop = min(gl_frontsector->ceilingheight, gl_backsector->ceilingheight) + rowoffset;
|
||||
polybottom = polytop - midtexheight;
|
||||
}
|
||||
|
||||
// The right side's coordinates are the the same as the left side
|
||||
polytopslope = polytop;
|
||||
polybottomslope = polybottom;
|
||||
}
|
||||
// Skew the texture, but peg it to the floor
|
||||
else if (gl_linedef->flags & ML_MIDPEG)
|
||||
{
|
||||
polybottom = popenbottom + rowoffset;
|
||||
polytop = polybottom + midtexheight;
|
||||
polybottomslope = popenbottomslope + rowoffset;
|
||||
polytopslope = polybottomslope + midtexheight;
|
||||
}
|
||||
// Skew it according to the ceiling's slope
|
||||
else
|
||||
{
|
||||
polytop = popentop + rowoffset;
|
||||
polybottom = polytop - midtexheight;
|
||||
polytopslope = popentopslope + rowoffset;
|
||||
polybottomslope = polytopslope - midtexheight;
|
||||
}
|
||||
|
||||
// The cut-off values of a linedef can always be constant, since every line has an absoulute front and or back sector
|
||||
if (gl_curline->polyseg)
|
||||
{
|
||||
lowcut = polybottom;
|
||||
highcut = polytop;
|
||||
lowcutslope = polybottomslope;
|
||||
highcutslope = polytopslope;
|
||||
}
|
||||
else
|
||||
{
|
||||
lowcut = popenbottom;
|
||||
highcut = popentop;
|
||||
lowcutslope = popenbottomslope;
|
||||
highcutslope = popentopslope;
|
||||
}
|
||||
|
||||
fixed_t h = min(highcut, polytop);
|
||||
fixed_t l = max(polybottom, lowcut);
|
||||
fixed_t hS = min(highcutslope, polytopslope);
|
||||
fixed_t lS = max(polybottomslope, lowcutslope);
|
||||
|
||||
// PEGGING
|
||||
fixed_t texturevpeg, texturevpegslope;
|
||||
|
||||
if (gl_linedef->flags & ML_MIDPEG)
|
||||
{
|
||||
texturevpeg = midtexheight - h + polybottom;
|
||||
texturevpegslope = midtexheight - hS + polybottomslope;
|
||||
}
|
||||
else
|
||||
{
|
||||
texturevpeg = polytop - h;
|
||||
texturevpegslope = polytopslope - hS;
|
||||
}
|
||||
|
||||
memcpy(wallVerts, inWallVerts, sizeof(wallVerts));
|
||||
|
||||
// Left side
|
||||
wallVerts[3].t = texturevpeg * yscale * grTex->scaleY;
|
||||
wallVerts[0].t = (h - l + texturevpeg) * yscale * grTex->scaleY;
|
||||
wallVerts[0].s = wallVerts[3].s = ((cliplow * xscale) + gl_sidedef->textureoffset + gl_sidedef->offsetx_mid) * grTex->scaleX;
|
||||
|
||||
// Right side
|
||||
wallVerts[2].t = texturevpegslope * yscale * grTex->scaleY;
|
||||
wallVerts[1].t = (hS - lS + texturevpegslope) * yscale * grTex->scaleY;
|
||||
wallVerts[2].s = wallVerts[1].s = ((cliphigh * xscale) + gl_sidedef->textureoffset + gl_sidedef->offsetx_mid) * grTex->scaleX;
|
||||
|
||||
// set top/bottom coords
|
||||
// Take the texture peg into account, rather than changing the offsets past
|
||||
// where the polygon might not be.
|
||||
wallVerts[3].y = FIXED_TO_FLOAT(h);
|
||||
wallVerts[0].y = FIXED_TO_FLOAT(l);
|
||||
wallVerts[2].y = FIXED_TO_FLOAT(hS);
|
||||
wallVerts[1].y = FIXED_TO_FLOAT(lS);
|
||||
|
||||
// TODO: Actually use the surface's flags so that I don't have to do this
|
||||
FUINT blendmode = Surf.PolyFlags;
|
||||
|
||||
// Render midtextures on two-sided lines with a z-buffer offset.
|
||||
// This will cause the midtexture appear on top, if a FOF overlaps with it.
|
||||
blendmode |= PF_Decal;
|
||||
|
||||
extracolormap_t *colormap = gl_frontsector->extra_colormap;
|
||||
|
||||
if (gl_frontsector->numlights)
|
||||
{
|
||||
if (!(blendmode & PF_Masked))
|
||||
HWR_SplitWall(gl_frontsector, wallVerts, gl_midtexture, &Surf, FOF_TRANSLUCENT, NULL, blendmode);
|
||||
else
|
||||
HWR_SplitWall(gl_frontsector, wallVerts, gl_midtexture, &Surf, FOF_CUTLEVEL, NULL, blendmode);
|
||||
}
|
||||
else if (!(blendmode & PF_Masked))
|
||||
HWR_AddTransparentWall(wallVerts, &Surf, gl_midtexture, blendmode, false, lightnum, colormap);
|
||||
else
|
||||
HWR_ProjectWall(wallVerts, &Surf, blendmode, lightnum, colormap);
|
||||
}
|
||||
|
||||
//
|
||||
// HWR_ProcessSeg
|
||||
// A portion or all of a wall segment will be drawn, from startfrac to endfrac,
|
||||
|
@ -1105,9 +1290,8 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
|
|||
wallVerts[2].z = wallVerts[1].z = ve.y;
|
||||
|
||||
// x offset the texture
|
||||
fixed_t texturehpeg = gl_sidedef->textureoffset + gl_curline->offset;
|
||||
float cliplow = (float)texturehpeg;
|
||||
float cliphigh = (float)(texturehpeg + (gl_curline->flength*FRACUNIT));
|
||||
float cliplow = (float)gl_curline->offset;
|
||||
float cliphigh = cliplow + (gl_curline->flength * FRACUNIT);
|
||||
|
||||
FUINT lightnum = HWR_CalcWallLight(gl_frontsector->lightlevel, vs.x, vs.y, ve.x, ve.y);
|
||||
extracolormap_t *colormap = gl_frontsector->extra_colormap;
|
||||
|
@ -1122,6 +1306,7 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
|
|||
if (gl_backsector)
|
||||
{
|
||||
INT32 gl_toptexture = 0, gl_bottomtexture = 0;
|
||||
|
||||
fixed_t texturevpeg;
|
||||
|
||||
SLOPEPARAMS(gl_backsector->c_slope, worldhigh, worldhighslope, gl_backsector->ceilingheight)
|
||||
|
@ -1151,30 +1336,46 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
|
|||
if ((worldhighslope < worldtopslope || worldhigh < worldtop) && gl_toptexture)
|
||||
{
|
||||
grTex = HWR_GetTexture(gl_toptexture);
|
||||
xscale = FixedToFloat(gl_sidedef->scalex_top);
|
||||
yscale = FixedToFloat(gl_sidedef->scaley_top);
|
||||
xscale = FixedToFloat(abs(gl_sidedef->scalex_top));
|
||||
yscale = FixedToFloat(abs(gl_sidedef->scaley_top));
|
||||
|
||||
fixed_t texheight = FixedDiv(textureheight[gl_toptexture], gl_sidedef->scaley_top);
|
||||
fixed_t offsetx_top = gl_sidedef->textureoffset + gl_sidedef->offsetx_top;
|
||||
|
||||
float left = cliplow * xscale;
|
||||
float right = cliphigh * xscale;
|
||||
if (gl_sidedef->scalex_top < 0)
|
||||
{
|
||||
left = -left;
|
||||
right = -right;
|
||||
offsetx_top = -offsetx_top;
|
||||
}
|
||||
|
||||
fixed_t texheight = textureheight[gl_toptexture];
|
||||
fixed_t texheightscaled = FixedDiv(texheight, abs(gl_sidedef->scaley_top));
|
||||
|
||||
// PEGGING
|
||||
// FIXME: This is probably not correct?
|
||||
if (gl_linedef->flags & ML_DONTPEGTOP)
|
||||
texturevpeg = 0;
|
||||
else if (gl_linedef->flags & ML_SKEWTD)
|
||||
texturevpeg = worldhigh + texheight - worldtop;
|
||||
else
|
||||
texturevpeg = gl_backsector->ceilingheight + texheight - gl_frontsector->ceilingheight;
|
||||
texturevpeg = gl_backsector->ceilingheight + texheightscaled - gl_frontsector->ceilingheight;
|
||||
|
||||
texturevpeg *= yscale;
|
||||
|
||||
texturevpeg += gl_sidedef->rowoffset + gl_sidedef->offsety_top;
|
||||
if (gl_sidedef->scaley_top < 0)
|
||||
texturevpeg -= gl_sidedef->rowoffset + gl_sidedef->offsety_top;
|
||||
else
|
||||
texturevpeg += gl_sidedef->rowoffset + gl_sidedef->offsety_top;
|
||||
|
||||
// This is so that it doesn't overflow and screw up the wall, it doesn't need to go higher than the texture's height anyway
|
||||
texturevpeg %= texheight;
|
||||
texturevpeg %= texheightscaled;
|
||||
|
||||
wallVerts[3].t = wallVerts[2].t = texturevpeg * grTex->scaleY;
|
||||
wallVerts[0].t = wallVerts[1].t = (texturevpeg + (gl_frontsector->ceilingheight - gl_backsector->ceilingheight) * yscale) * grTex->scaleY;
|
||||
wallVerts[0].s = wallVerts[3].s = ((cliplow * xscale) + gl_sidedef->offsetx_top) * grTex->scaleX;
|
||||
wallVerts[2].s = wallVerts[1].s = ((cliphigh * xscale) + gl_sidedef->offsetx_top) * grTex->scaleX;
|
||||
wallVerts[0].s = wallVerts[3].s = (left + offsetx_top) * grTex->scaleX;
|
||||
wallVerts[2].s = wallVerts[1].s = (right + offsetx_top) * grTex->scaleX;
|
||||
|
||||
// Adjust t value for sloped walls
|
||||
if (!(gl_linedef->flags & ML_SKEWTD))
|
||||
|
@ -1199,6 +1400,14 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
|
|||
wallVerts[2].t = wallVerts[1].t - (worldtopslope - worldhighslope) * yscale * grTex->scaleY;
|
||||
}
|
||||
|
||||
if (gl_sidedef->scaley_top < 0)
|
||||
{
|
||||
wallVerts[0].t = -wallVerts[0].t;
|
||||
wallVerts[1].t = -wallVerts[1].t;
|
||||
wallVerts[2].t = -wallVerts[2].t;
|
||||
wallVerts[3].t = -wallVerts[3].t;
|
||||
}
|
||||
|
||||
// set top/bottom coords
|
||||
wallVerts[3].y = FIXED_TO_FLOAT(worldtop);
|
||||
wallVerts[0].y = FIXED_TO_FLOAT(worldhigh);
|
||||
|
@ -1217,8 +1426,19 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
|
|||
if ((worldlowslope > worldbottomslope || worldlow > worldbottom) && gl_bottomtexture)
|
||||
{
|
||||
grTex = HWR_GetTexture(gl_bottomtexture);
|
||||
xscale = FixedToFloat(gl_sidedef->scalex_bottom);
|
||||
yscale = FixedToFloat(gl_sidedef->scaley_bottom);
|
||||
xscale = FixedToFloat(abs(gl_sidedef->scalex_bottom));
|
||||
yscale = FixedToFloat(abs(gl_sidedef->scaley_bottom));
|
||||
|
||||
fixed_t offsetx_bottom = gl_sidedef->textureoffset + gl_sidedef->offsetx_bottom;
|
||||
|
||||
float left = cliplow * xscale;
|
||||
float right = cliphigh * xscale;
|
||||
if (gl_sidedef->scalex_bottom < 0)
|
||||
{
|
||||
left = -left;
|
||||
right = -right;
|
||||
offsetx_bottom = -offsetx_bottom;
|
||||
}
|
||||
|
||||
// PEGGING
|
||||
if (!(gl_linedef->flags & ML_DONTPEGBOTTOM))
|
||||
|
@ -1230,15 +1450,18 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
|
|||
|
||||
texturevpeg *= yscale;
|
||||
|
||||
texturevpeg += gl_sidedef->rowoffset + gl_sidedef->offsety_bottom;
|
||||
if (gl_sidedef->scaley_bottom < 0)
|
||||
texturevpeg -= gl_sidedef->rowoffset + gl_sidedef->offsety_bottom;
|
||||
else
|
||||
texturevpeg += gl_sidedef->rowoffset + gl_sidedef->offsety_bottom;
|
||||
|
||||
// This is so that it doesn't overflow and screw up the wall, it doesn't need to go higher than the texture's height anyway
|
||||
texturevpeg %= FixedDiv(textureheight[gl_bottomtexture], gl_sidedef->scaley_bottom);
|
||||
texturevpeg %= FixedDiv(textureheight[gl_bottomtexture], abs(gl_sidedef->scaley_bottom));
|
||||
|
||||
wallVerts[3].t = wallVerts[2].t = texturevpeg * grTex->scaleY;
|
||||
wallVerts[0].t = wallVerts[1].t = (texturevpeg + (gl_backsector->floorheight - gl_frontsector->floorheight) * yscale) * grTex->scaleY;
|
||||
wallVerts[0].s = wallVerts[3].s = ((cliplow * xscale) + gl_sidedef->offsetx_bottom) * grTex->scaleX;
|
||||
wallVerts[2].s = wallVerts[1].s = ((cliphigh * xscale) + gl_sidedef->offsetx_bottom) * grTex->scaleX;
|
||||
wallVerts[0].s = wallVerts[3].s = (left + offsetx_bottom) * grTex->scaleX;
|
||||
wallVerts[2].s = wallVerts[1].s = (right + offsetx_bottom) * grTex->scaleX;
|
||||
|
||||
// Adjust t value for sloped walls
|
||||
if (!(gl_linedef->flags & ML_SKEWTD))
|
||||
|
@ -1262,6 +1485,14 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
|
|||
wallVerts[1].t = (texturevpeg + (worldlowslope - worldbottomslope) * yscale) * grTex->scaleY;
|
||||
}
|
||||
|
||||
if (gl_sidedef->scaley_bottom < 0)
|
||||
{
|
||||
wallVerts[0].t = -wallVerts[0].t;
|
||||
wallVerts[1].t = -wallVerts[1].t;
|
||||
wallVerts[2].t = -wallVerts[2].t;
|
||||
wallVerts[3].t = -wallVerts[3].t;
|
||||
}
|
||||
|
||||
// set top/bottom coords
|
||||
wallVerts[3].y = FIXED_TO_FLOAT(worldlow);
|
||||
wallVerts[0].y = FIXED_TO_FLOAT(worldbottom);
|
||||
|
@ -1276,196 +1507,14 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
|
|||
HWR_ProjectWall(wallVerts, &Surf, PF_Masked, lightnum, colormap);
|
||||
}
|
||||
|
||||
// Render midtexture if there's one. Determine if it's visible first, though
|
||||
if (gl_midtexture && HWR_BlendMidtextureSurface(&Surf))
|
||||
{
|
||||
sector_t *front, *back;
|
||||
fixed_t texheight = FixedDiv(textureheight[gl_midtexture], gl_sidedef->scaley_mid);
|
||||
INT32 repeats;
|
||||
// Render midtexture if there's one
|
||||
if (gl_midtexture)
|
||||
HWR_RenderMidtexture(gl_midtexture, cliplow, cliphigh, worldtop, worldbottom, worldhigh, worldlow, worldtopslope, worldbottomslope, worldhighslope, worldlowslope, lightnum, wallVerts);
|
||||
|
||||
if (gl_linedef->frontsector->heightsec != -1)
|
||||
front = §ors[gl_linedef->frontsector->heightsec];
|
||||
else
|
||||
front = gl_linedef->frontsector;
|
||||
|
||||
if (gl_linedef->backsector->heightsec != -1)
|
||||
back = §ors[gl_linedef->backsector->heightsec];
|
||||
else
|
||||
back = gl_linedef->backsector;
|
||||
|
||||
if (gl_sidedef->repeatcnt)
|
||||
repeats = 1 + gl_sidedef->repeatcnt;
|
||||
else if (gl_linedef->flags & ML_WRAPMIDTEX)
|
||||
{
|
||||
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) / texheight;
|
||||
if ((high - low) % texheight)
|
||||
repeats++; // tile an extra time to fill the gap -- Monster Iestyn
|
||||
}
|
||||
else
|
||||
repeats = 1;
|
||||
|
||||
grTex = HWR_GetTexture(gl_midtexture);
|
||||
xscale = FixedToFloat(gl_sidedef->scalex_mid);
|
||||
yscale = FixedToFloat(gl_sidedef->scaley_mid);
|
||||
|
||||
// SoM: a little note: popentop and popenbottom
|
||||
// record the limits the texture can be displayed in.
|
||||
// polytop and polybottom, are the ideal (i.e. unclipped)
|
||||
// heights of the polygon, and h & l, are the final (clipped)
|
||||
// poly coords.
|
||||
fixed_t popentop, popenbottom, polytop, polybottom, lowcut, highcut;
|
||||
fixed_t popentopslope, popenbottomslope, polytopslope, polybottomslope, lowcutslope, highcutslope;
|
||||
|
||||
// NOTE: With polyobjects, whenever you need to check the properties of the polyobject sector it belongs to,
|
||||
// you must use the linedef's backsector to be correct
|
||||
// From CB
|
||||
if (gl_curline->polyseg)
|
||||
{
|
||||
popentop = popentopslope = back->ceilingheight;
|
||||
popenbottom = popenbottomslope = back->floorheight;
|
||||
}
|
||||
else
|
||||
{
|
||||
popentop = min(worldtop, worldhigh);
|
||||
popenbottom = max(worldbottom, worldlow);
|
||||
popentopslope = min(worldtopslope, worldhighslope);
|
||||
popenbottomslope = max(worldbottomslope, worldlowslope);
|
||||
}
|
||||
|
||||
// Find the wall's coordinates
|
||||
fixed_t midtexheight = texheight * repeats;
|
||||
|
||||
fixed_t rowoffset = FixedDiv(gl_sidedef->rowoffset + gl_sidedef->offsety_mid, gl_sidedef->scaley_mid);
|
||||
|
||||
// Texture is not skewed
|
||||
if (gl_linedef->flags & ML_NOSKEW)
|
||||
{
|
||||
// Peg it to the floor
|
||||
if (gl_linedef->flags & ML_MIDPEG)
|
||||
{
|
||||
polybottom = max(front->floorheight, back->floorheight) + rowoffset;
|
||||
polytop = polybottom + midtexheight;
|
||||
}
|
||||
// Peg it to the ceiling
|
||||
else
|
||||
{
|
||||
polytop = min(front->ceilingheight, back->ceilingheight) + rowoffset;
|
||||
polybottom = polytop - midtexheight;
|
||||
}
|
||||
|
||||
// The right side's coordinates are the the same as the left side
|
||||
polytopslope = polytop;
|
||||
polybottomslope = polybottom;
|
||||
}
|
||||
// Skew the texture, but peg it to the floor
|
||||
else if (gl_linedef->flags & ML_MIDPEG)
|
||||
{
|
||||
polybottom = popenbottom + rowoffset;
|
||||
polytop = polybottom + midtexheight;
|
||||
polybottomslope = popenbottomslope + rowoffset;
|
||||
polytopslope = polybottomslope + midtexheight;
|
||||
}
|
||||
// Skew it according to the ceiling's slope
|
||||
else
|
||||
{
|
||||
polytop = popentop + rowoffset;
|
||||
polybottom = polytop - midtexheight;
|
||||
polytopslope = popentopslope + rowoffset;
|
||||
polybottomslope = polytopslope - midtexheight;
|
||||
}
|
||||
|
||||
// CB
|
||||
// NOTE: With polyobjects, whenever you need to check the properties of the polyobject sector it belongs to,
|
||||
// you must use the linedef's backsector to be correct
|
||||
if (gl_curline->polyseg)
|
||||
{
|
||||
lowcut = polybottom;
|
||||
highcut = polytop;
|
||||
lowcutslope = polybottomslope;
|
||||
highcutslope = polytopslope;
|
||||
}
|
||||
else
|
||||
{
|
||||
// The cut-off values of a linedef can always be constant, since every line has an absoulute front and or back sector
|
||||
lowcut = popenbottom;
|
||||
highcut = popentop;
|
||||
lowcutslope = popenbottomslope;
|
||||
highcutslope = popentopslope;
|
||||
}
|
||||
|
||||
h = min(highcut, polytop);
|
||||
l = max(polybottom, lowcut);
|
||||
hS = min(highcutslope, polytopslope);
|
||||
lS = max(polybottomslope, lowcutslope);
|
||||
|
||||
// PEGGING
|
||||
fixed_t texturevpegslope;
|
||||
|
||||
if (gl_linedef->flags & ML_MIDPEG)
|
||||
{
|
||||
texturevpeg = midtexheight - h + polybottom;
|
||||
texturevpegslope = midtexheight - hS + polybottomslope;
|
||||
}
|
||||
else
|
||||
{
|
||||
texturevpeg = polytop - h;
|
||||
texturevpegslope = polytopslope - hS;
|
||||
}
|
||||
|
||||
// Left side
|
||||
wallVerts[3].t = texturevpeg * yscale * grTex->scaleY;
|
||||
wallVerts[0].t = (h - l + texturevpeg) * yscale * grTex->scaleY;
|
||||
wallVerts[0].s = wallVerts[3].s = ((cliplow * xscale) + gl_sidedef->offsetx_mid) * grTex->scaleX;
|
||||
|
||||
// Right side
|
||||
wallVerts[2].t = texturevpegslope * yscale * grTex->scaleY;
|
||||
wallVerts[1].t = (hS - lS + texturevpegslope) * yscale * grTex->scaleY;
|
||||
wallVerts[2].s = wallVerts[1].s = ((cliphigh * xscale) + gl_sidedef->offsetx_mid) * grTex->scaleX;
|
||||
|
||||
// set top/bottom coords
|
||||
// Take the texture peg into account, rather than changing the offsets past
|
||||
// where the polygon might not be.
|
||||
wallVerts[3].y = FIXED_TO_FLOAT(h);
|
||||
wallVerts[0].y = FIXED_TO_FLOAT(l);
|
||||
wallVerts[2].y = FIXED_TO_FLOAT(hS);
|
||||
wallVerts[1].y = FIXED_TO_FLOAT(lS);
|
||||
|
||||
// TODO: Actually use the surface's flags so that I don't have to do this
|
||||
FUINT blendmode = Surf.PolyFlags;
|
||||
|
||||
// Render midtextures on two-sided lines with a z-buffer offset.
|
||||
// This will cause the midtexture appear on top, if a FOF overlaps with it.
|
||||
blendmode |= PF_Decal;
|
||||
|
||||
if (gl_frontsector->numlights)
|
||||
{
|
||||
if (!(blendmode & PF_Masked))
|
||||
HWR_SplitWall(gl_frontsector, wallVerts, gl_midtexture, &Surf, FOF_TRANSLUCENT, NULL, blendmode);
|
||||
else
|
||||
HWR_SplitWall(gl_frontsector, wallVerts, gl_midtexture, &Surf, FOF_CUTLEVEL, NULL, blendmode);
|
||||
}
|
||||
else if (!(blendmode & PF_Masked))
|
||||
HWR_AddTransparentWall(wallVerts, &Surf, gl_midtexture, blendmode, false, lightnum, colormap);
|
||||
else
|
||||
HWR_ProjectWall(wallVerts, &Surf, blendmode, lightnum, colormap);
|
||||
}
|
||||
|
||||
// Sky culling
|
||||
// No longer so much a mess as before!
|
||||
if (!gl_curline->polyseg) // Don't do it for polyobjects
|
||||
{
|
||||
// Sky culling
|
||||
// No longer so much a mess as before!
|
||||
if (gl_frontsector->ceilingpic == skyflatnum
|
||||
&& gl_backsector->ceilingpic != skyflatnum) // don't cull if back sector is also sky
|
||||
{
|
||||
|
@ -1509,8 +1558,8 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
|
|||
|
||||
wallVerts[3].t = wallVerts[2].t = texturevpeg * grTex->scaleY;
|
||||
wallVerts[0].t = wallVerts[1].t = (texturevpeg + gl_frontsector->ceilingheight - gl_frontsector->floorheight) * grTex->scaleY;
|
||||
wallVerts[0].s = wallVerts[3].s = ((cliplow * xscale) + gl_sidedef->offsetx_mid) * grTex->scaleX;
|
||||
wallVerts[2].s = wallVerts[1].s = ((cliphigh * xscale) + gl_sidedef->offsetx_mid) * grTex->scaleX;
|
||||
wallVerts[0].s = wallVerts[3].s = ((cliplow * xscale) + gl_sidedef->textureoffset + gl_sidedef->offsetx_mid) * grTex->scaleX;
|
||||
wallVerts[2].s = wallVerts[1].s = ((cliphigh * xscale) + gl_sidedef->textureoffset + gl_sidedef->offsetx_mid) * grTex->scaleX;
|
||||
|
||||
// Texture correction for slopes
|
||||
if (gl_linedef->flags & ML_NOSKEW) {
|
||||
|
@ -1573,8 +1622,9 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
|
|||
// Used for height comparisons and etc across FOFs and slopes
|
||||
fixed_t high1, highslope1, low1, lowslope1;
|
||||
|
||||
fixed_t texturehpeg = gl_sidedef->textureoffset + gl_sidedef->offsetx_mid;
|
||||
|
||||
INT32 texnum;
|
||||
line_t * newline = NULL; // Multi-Property FOF
|
||||
|
||||
lowcut = max(worldbottom, worldlow);
|
||||
highcut = min(worldtop, worldhigh);
|
||||
|
@ -1608,16 +1658,14 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
|
|||
if ((high1 < lowcut && highslope1 < lowcutslope) || (low1 > highcut && lowslope1 > highcutslope))
|
||||
continue;
|
||||
|
||||
side_t *side = &sides[rover->master->sidenum[0]];
|
||||
side_t *side = R_GetFFloorSide(gl_curline, rover);
|
||||
|
||||
boolean do_texture_skew;
|
||||
boolean dont_peg_bottom;
|
||||
|
||||
if (rover->master->flags & ML_TFERLINE)
|
||||
{
|
||||
size_t linenum = gl_curline->linedef-gl_backsector->lines[0];
|
||||
newline = rover->master->frontsector->lines[0] + linenum;
|
||||
side = &sides[newline->sidenum[0]];
|
||||
line_t *newline = R_GetFFloorLine(gl_curline, rover);
|
||||
do_texture_skew = newline->flags & ML_SKEWTD;
|
||||
dont_peg_bottom = newline->flags & ML_DONTPEGBOTTOM;
|
||||
}
|
||||
|
@ -1695,14 +1743,14 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
|
|||
}
|
||||
}
|
||||
|
||||
wallVerts[0].s = wallVerts[3].s = ((cliplow * xscale) + side->offsetx_mid) * grTex->scaleX;
|
||||
wallVerts[2].s = wallVerts[1].s = ((cliphigh * xscale) + side->offsetx_mid) * grTex->scaleX;
|
||||
wallVerts[0].s = wallVerts[3].s = ((cliplow * xscale) + texturehpeg + side->offsetx_mid) * grTex->scaleX;
|
||||
wallVerts[2].s = wallVerts[1].s = ((cliphigh * xscale) + texturehpeg + side->offsetx_mid) * grTex->scaleX;
|
||||
}
|
||||
|
||||
FBITFIELD blendmode;
|
||||
|
||||
if (rover->fofflags & FOF_FOG)
|
||||
{
|
||||
FBITFIELD blendmode;
|
||||
|
||||
blendmode = PF_Fog|PF_NoTexture;
|
||||
|
||||
lightnum = HWR_CalcWallLight(rover->master->frontsector->lightlevel, vs.x, vs.y, ve.x, ve.y);
|
||||
|
@ -1717,7 +1765,7 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
|
|||
}
|
||||
else
|
||||
{
|
||||
FBITFIELD blendmode = PF_Masked;
|
||||
blendmode = PF_Masked;
|
||||
|
||||
if ((rover->fofflags & FOF_TRANSLUCENT && !(rover->fofflags & FOF_SPLAT)) || rover->blend)
|
||||
{
|
||||
|
@ -1765,13 +1813,21 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
|
|||
if ((high1 < lowcut && highslope1 < lowcutslope) || (low1 > highcut && lowslope1 > highcutslope))
|
||||
continue;
|
||||
|
||||
side_t *side = &sides[rover->master->sidenum[0]];
|
||||
side_t *side = R_GetFFloorSide(gl_curline, rover);
|
||||
|
||||
boolean do_texture_skew;
|
||||
boolean dont_peg_bottom;
|
||||
|
||||
if (rover->master->flags & ML_TFERLINE)
|
||||
{
|
||||
size_t linenum = gl_curline->linedef-gl_backsector->lines[0];
|
||||
newline = rover->master->frontsector->lines[0] + linenum;
|
||||
side = &sides[newline->sidenum[0]];
|
||||
line_t *newline = R_GetFFloorLine(gl_curline, rover);
|
||||
do_texture_skew = newline->flags & ML_SKEWTD;
|
||||
dont_peg_bottom = newline->flags & ML_DONTPEGBOTTOM;
|
||||
}
|
||||
else
|
||||
{
|
||||
do_texture_skew = rover->master->flags & ML_SKEWTD;
|
||||
dont_peg_bottom = gl_curline->linedef->flags & ML_DONTPEGBOTTOM;
|
||||
}
|
||||
|
||||
texnum = R_GetTextureNum(side->midtexture);
|
||||
|
@ -1808,23 +1864,49 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
|
|||
}
|
||||
else
|
||||
{
|
||||
// Wow, how was this missing from OpenGL for so long?
|
||||
// ...Oh well, anyway, Lower Unpegged now changes pegging of FOFs like in software
|
||||
// -- Monster Iestyn 26/06/18
|
||||
fixed_t texturevpeg = side->rowoffset + side->offsety_mid;
|
||||
|
||||
grTex = HWR_GetTexture(texnum);
|
||||
xscale = FixedToFloat(side->scalex_mid);
|
||||
yscale = FixedToFloat(side->scaley_mid);
|
||||
|
||||
fixed_t diff = (*rover->topheight - h) * yscale;
|
||||
if (!do_texture_skew) // no skewing
|
||||
{
|
||||
if (dont_peg_bottom)
|
||||
texturevpeg -= (*rover->topheight - *rover->bottomheight) * yscale;
|
||||
|
||||
wallVerts[3].t = wallVerts[2].t = (diff + side->rowoffset + side->offsety_mid) * grTex->scaleY;
|
||||
wallVerts[0].t = wallVerts[1].t = (((h - l) * yscale) + (diff + side->rowoffset + side->offsety_mid)) * grTex->scaleY;
|
||||
wallVerts[3].t = (((*rover->topheight - h) * yscale) + texturevpeg) * grTex->scaleY;
|
||||
wallVerts[2].t = (((*rover->topheight - hS) * yscale) + texturevpeg) * grTex->scaleY;
|
||||
wallVerts[0].t = (((*rover->topheight - l) * yscale) + texturevpeg) * grTex->scaleY;
|
||||
wallVerts[1].t = (((*rover->topheight - lS) * yscale) + texturevpeg) * grTex->scaleY;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!dont_peg_bottom) // skew by top
|
||||
{
|
||||
wallVerts[3].t = wallVerts[2].t = texturevpeg * grTex->scaleY;
|
||||
wallVerts[0].t = (((h - l) * yscale) + texturevpeg) * grTex->scaleY;
|
||||
wallVerts[1].t = (((hS - lS) * yscale) + texturevpeg) * grTex->scaleY;
|
||||
}
|
||||
else // skew by bottom
|
||||
{
|
||||
wallVerts[0].t = wallVerts[1].t = texturevpeg * grTex->scaleY;
|
||||
wallVerts[3].t = wallVerts[0].t - ((h - l) * yscale) * grTex->scaleY;
|
||||
wallVerts[2].t = wallVerts[1].t - ((hS - lS) * yscale) * grTex->scaleY;
|
||||
}
|
||||
}
|
||||
|
||||
wallVerts[0].s = wallVerts[3].s = ((cliplow * xscale) + side->offsetx_mid) * grTex->scaleX;
|
||||
wallVerts[2].s = wallVerts[1].s = ((cliphigh * xscale) + side->offsetx_mid) * grTex->scaleX;
|
||||
wallVerts[0].s = wallVerts[3].s = ((cliplow * xscale) + texturehpeg + side->offsetx_mid) * grTex->scaleX;
|
||||
wallVerts[2].s = wallVerts[1].s = ((cliphigh * xscale) + texturehpeg + side->offsetx_mid) * grTex->scaleX;
|
||||
}
|
||||
|
||||
FBITFIELD blendmode;
|
||||
|
||||
if (rover->fofflags & FOF_FOG)
|
||||
{
|
||||
FBITFIELD blendmode;
|
||||
|
||||
blendmode = PF_Fog|PF_NoTexture;
|
||||
|
||||
lightnum = HWR_CalcWallLight(rover->master->frontsector->lightlevel, vs.x, vs.y, ve.x, ve.y);
|
||||
|
@ -1839,7 +1921,7 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
|
|||
}
|
||||
else
|
||||
{
|
||||
FBITFIELD blendmode = PF_Masked;
|
||||
blendmode = PF_Masked;
|
||||
|
||||
if ((rover->fofflags & FOF_TRANSLUCENT && !(rover->fofflags & FOF_SPLAT)) || rover->blend)
|
||||
{
|
||||
|
@ -2656,36 +2738,14 @@ static boolean HWR_CheckBBox(fixed_t *bspcoord)
|
|||
static inline void HWR_AddPolyObjectSegs(void)
|
||||
{
|
||||
size_t i, j;
|
||||
seg_t *gl_fakeline = Z_Calloc(sizeof(seg_t), PU_STATIC, NULL);
|
||||
polyvertex_t *pv1 = Z_Calloc(sizeof(polyvertex_t), PU_STATIC, NULL);
|
||||
polyvertex_t *pv2 = Z_Calloc(sizeof(polyvertex_t), PU_STATIC, NULL);
|
||||
|
||||
// Sort through all the polyobjects
|
||||
for (i = 0; i < numpolys; ++i)
|
||||
{
|
||||
// Render the polyobject's lines
|
||||
for (j = 0; j < po_ptrs[i]->segCount; ++j)
|
||||
{
|
||||
// Copy the info of a polyobject's seg, then convert it to OpenGL floating point
|
||||
M_Memcpy(gl_fakeline, po_ptrs[i]->segs[j], sizeof(seg_t));
|
||||
|
||||
// Now convert the line to float and add it to be rendered
|
||||
pv1->x = FIXED_TO_FLOAT(gl_fakeline->v1->x);
|
||||
pv1->y = FIXED_TO_FLOAT(gl_fakeline->v1->y);
|
||||
pv2->x = FIXED_TO_FLOAT(gl_fakeline->v2->x);
|
||||
pv2->y = FIXED_TO_FLOAT(gl_fakeline->v2->y);
|
||||
|
||||
gl_fakeline->pv1 = pv1;
|
||||
gl_fakeline->pv2 = pv2;
|
||||
|
||||
HWR_AddLine(gl_fakeline);
|
||||
}
|
||||
HWR_AddLine(po_ptrs[i]->segs[j]);
|
||||
}
|
||||
|
||||
// Free temporary data no longer needed
|
||||
Z_Free(pv2);
|
||||
Z_Free(pv1);
|
||||
Z_Free(gl_fakeline);
|
||||
}
|
||||
|
||||
static void HWR_RenderPolyObjectPlane(polyobj_t *polysector, boolean isceiling, fixed_t fixedheight,
|
||||
|
|
|
@ -3290,8 +3290,6 @@ static void P_InitializeSeg(seg_t *seg)
|
|||
seg->lightmaps = NULL; // list of static lightmap for this seg
|
||||
#endif
|
||||
|
||||
seg->numlights = 0;
|
||||
seg->rlights = NULL;
|
||||
seg->polyseg = NULL;
|
||||
seg->dontrenderme = false;
|
||||
}
|
||||
|
|
|
@ -742,9 +742,6 @@ typedef struct seg_s
|
|||
lightmap_t *lightmaps; // for static lightmap
|
||||
#endif
|
||||
|
||||
// Why slow things down by calculating lightlists for every thick side?
|
||||
size_t numlights;
|
||||
r_lightlist_t *rlights;
|
||||
polyobj_t *polyseg;
|
||||
boolean dontrenderme;
|
||||
boolean glseg;
|
||||
|
@ -828,6 +825,7 @@ typedef struct drawseg_s
|
|||
INT16 *sprtopclip;
|
||||
INT16 *sprbottomclip;
|
||||
fixed_t *maskedtexturecol;
|
||||
fixed_t *maskedtextureheight; // For handling sloped midtextures
|
||||
fixed_t *invscale;
|
||||
|
||||
struct visplane_s *ffloorplanes[MAXFFLOORS];
|
||||
|
@ -839,8 +837,6 @@ typedef struct drawseg_s
|
|||
|
||||
UINT8 portalpass; // if > 0 and <= portalrender, do not affect sprite clipping
|
||||
|
||||
fixed_t maskedtextureheight[MAXVIDWIDTH]; // For handling sloped midtextures
|
||||
|
||||
vertex_t leftpos, rightpos; // Used for rendering FOF walls with slopes
|
||||
} drawseg_t;
|
||||
|
||||
|
|
55
src/r_main.c
55
src/r_main.c
|
@ -318,7 +318,6 @@ angle_t R_PointToAngle(fixed_t x, fixed_t y)
|
|||
}
|
||||
|
||||
// This version uses 64-bit variables to avoid overflows with large values.
|
||||
// Currently used only by OpenGL rendering.
|
||||
angle_t R_PointToAngle64(INT64 x, INT64 y)
|
||||
{
|
||||
return (y -= viewy, (x -= viewx) || y) ?
|
||||
|
@ -384,56 +383,26 @@ fixed_t R_PointToDist(fixed_t x, fixed_t y)
|
|||
return R_PointToDist2(viewx, viewy, x, y);
|
||||
}
|
||||
|
||||
angle_t R_PointToAngleEx(INT32 x2, INT32 y2, INT32 x1, INT32 y1)
|
||||
line_t *R_GetFFloorLine(const seg_t *seg, const ffloor_t *pfloor)
|
||||
{
|
||||
INT64 dx = x1-x2;
|
||||
INT64 dy = y1-y2;
|
||||
if (dx < INT32_MIN || dx > INT32_MAX || dy < INT32_MIN || dy > INT32_MAX)
|
||||
if (pfloor->master->flags & ML_TFERLINE)
|
||||
{
|
||||
x1 = (int)(dx / 2 + x2);
|
||||
y1 = (int)(dy / 2 + y2);
|
||||
size_t linenum = seg->linedef - pfloor->target->lines[0];
|
||||
return pfloor->master->frontsector->lines[0] + linenum;
|
||||
}
|
||||
return (y1 -= y2, (x1 -= x2) || y1) ?
|
||||
x1 >= 0 ?
|
||||
y1 >= 0 ?
|
||||
(x1 > y1) ? tantoangle[SlopeDivEx(y1,x1)] : // octant 0
|
||||
ANGLE_90-tantoangle[SlopeDivEx(x1,y1)] : // octant 1
|
||||
x1 > (y1 = -y1) ? 0-tantoangle[SlopeDivEx(y1,x1)] : // octant 8
|
||||
ANGLE_270+tantoangle[SlopeDivEx(x1,y1)] : // octant 7
|
||||
y1 >= 0 ? (x1 = -x1) > y1 ? ANGLE_180-tantoangle[SlopeDivEx(y1,x1)] : // octant 3
|
||||
ANGLE_90 + tantoangle[SlopeDivEx(x1,y1)] : // octant 2
|
||||
(x1 = -x1) > (y1 = -y1) ? ANGLE_180+tantoangle[SlopeDivEx(y1,x1)] : // octant 4
|
||||
ANGLE_270-tantoangle[SlopeDivEx(x1,y1)] : // octant 5
|
||||
0;
|
||||
else
|
||||
return pfloor->master;
|
||||
}
|
||||
|
||||
//
|
||||
// R_ScaleFromGlobalAngle
|
||||
// Returns the texture mapping scale for the current line (horizontal span)
|
||||
// at the given angle.
|
||||
// rw_distance must be calculated first.
|
||||
//
|
||||
// killough 5/2/98: reformatted, cleaned up
|
||||
//
|
||||
// note: THIS IS USED ONLY FOR WALLS!
|
||||
fixed_t R_ScaleFromGlobalAngle(angle_t visangle)
|
||||
side_t *R_GetFFloorSide(const seg_t *seg, const ffloor_t *pfloor)
|
||||
{
|
||||
angle_t anglea = ANGLE_90 + (visangle-viewangle);
|
||||
angle_t angleb = ANGLE_90 + (visangle-rw_normalangle);
|
||||
fixed_t den = FixedMul(rw_distance, FINESINE(anglea>>ANGLETOFINESHIFT));
|
||||
// proff 11/06/98: Changed for high-res
|
||||
fixed_t num = FixedMul(projectiony, FINESINE(angleb>>ANGLETOFINESHIFT));
|
||||
|
||||
if (den > num>>16)
|
||||
if (pfloor->master->flags & ML_TFERLINE)
|
||||
{
|
||||
num = FixedDiv(num, den);
|
||||
if (num > 64*FRACUNIT)
|
||||
return 64*FRACUNIT;
|
||||
if (num < 256)
|
||||
return 256;
|
||||
return num;
|
||||
line_t *newline = R_GetFFloorLine(seg, pfloor);
|
||||
return &sides[newline->sidenum[0]];
|
||||
}
|
||||
return 64*FRACUNIT;
|
||||
else
|
||||
return &sides[pfloor->master->sidenum[0]];
|
||||
}
|
||||
|
||||
//
|
||||
|
|
|
@ -77,17 +77,18 @@ INT32 R_PointOnSegSide(fixed_t x, fixed_t y, seg_t *line);
|
|||
angle_t R_PointToAngle(fixed_t x, fixed_t y);
|
||||
angle_t R_PointToAngle64(INT64 x, INT64 y);
|
||||
angle_t R_PointToAngle2(fixed_t px2, fixed_t py2, fixed_t px1, fixed_t py1);
|
||||
angle_t R_PointToAngleEx(INT32 x2, INT32 y2, INT32 x1, INT32 y1);
|
||||
fixed_t R_PointToDist(fixed_t x, fixed_t y);
|
||||
fixed_t R_PointToDist2(fixed_t px2, fixed_t py2, fixed_t px1, fixed_t py1);
|
||||
|
||||
fixed_t R_ScaleFromGlobalAngle(angle_t visangle);
|
||||
boolean R_IsPointInSector(sector_t *sector, fixed_t x, fixed_t y);
|
||||
subsector_t *R_PointInSubsector(fixed_t x, fixed_t y);
|
||||
subsector_t *R_PointInSubsectorOrNull(fixed_t x, fixed_t y);
|
||||
|
||||
boolean R_DoCulling(line_t *cullheight, line_t *viewcullheight, fixed_t vz, fixed_t bottomh, fixed_t toph);
|
||||
|
||||
line_t *R_GetFFloorLine(const seg_t *seg, const ffloor_t *pfloor);
|
||||
side_t *R_GetFFloorSide(const seg_t *seg, const ffloor_t *pfloor);
|
||||
|
||||
// Render stats
|
||||
|
||||
extern precise_t ps_prevframetime;// time when previous frame was rendered
|
||||
|
|
308
src/r_segs.c
308
src/r_segs.c
|
@ -16,15 +16,10 @@
|
|||
#include "r_sky.h"
|
||||
|
||||
#include "r_portal.h"
|
||||
#include "r_splats.h"
|
||||
|
||||
#include "w_wad.h"
|
||||
#include "z_zone.h"
|
||||
#include "netcode/d_netcmd.h"
|
||||
#include "m_misc.h"
|
||||
#include "p_local.h" // Camera...
|
||||
#include "p_slopes.h"
|
||||
#include "console.h" // con_clipviewtop
|
||||
#include "taglist.h"
|
||||
|
||||
// OPTIMIZE: closed two sided lines as single sided
|
||||
|
@ -79,6 +74,8 @@ static fixed_t *maskedtextureheight = NULL;
|
|||
static fixed_t *thicksidecol = NULL;
|
||||
static fixed_t *invscale = NULL;
|
||||
|
||||
static boolean texcoltables;
|
||||
|
||||
//SoM: 3/23/2000: Use boom opening limit removal
|
||||
static size_t numopenings;
|
||||
static INT16 *openings, *lastopening;
|
||||
|
@ -92,10 +89,6 @@ void R_ClearSegTables(void)
|
|||
curtexturecolumntable = texturecolumntable;
|
||||
}
|
||||
|
||||
// ==========================================================================
|
||||
// R_RenderMaskedSegRange
|
||||
// ==========================================================================
|
||||
|
||||
transnum_t R_GetLinedefTransTable(fixed_t alpha)
|
||||
{
|
||||
return (20*(FRACUNIT - alpha - 1) + FRACUNIT) >> (FRACBITS+1);
|
||||
|
@ -115,8 +108,13 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
|
|||
INT32 times, repeats;
|
||||
INT64 overflow_test;
|
||||
INT32 range;
|
||||
UINT8 vertflip;
|
||||
unsigned lengthcol;
|
||||
|
||||
fixed_t wall_scaley;
|
||||
fixed_t scalestep;
|
||||
fixed_t scale1;
|
||||
|
||||
// Calculate light table.
|
||||
// Use different light tables
|
||||
// for horizontal / vertical / diagonal. Diagonal?
|
||||
|
@ -164,9 +162,17 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
|
|||
colfunc = colfuncs[COLDRAWFUNC_FUZZY];
|
||||
}
|
||||
|
||||
fixed_t wall_scaley = sidedef->scaley_mid;
|
||||
fixed_t scalestep = FixedDiv(ds->scalestep, wall_scaley);
|
||||
fixed_t scale1 = FixedDiv(ds->scale1, wall_scaley);
|
||||
vertflip = textures[texnum]->flip & 2;
|
||||
|
||||
wall_scaley = sidedef->scaley_mid;
|
||||
if (wall_scaley < 0)
|
||||
{
|
||||
wall_scaley = -wall_scaley;
|
||||
vertflip = !vertflip;
|
||||
}
|
||||
|
||||
scalestep = FixedDiv(ds->scalestep, wall_scaley);
|
||||
scale1 = FixedDiv(ds->scale1, wall_scaley);
|
||||
|
||||
range = max(ds->x2-ds->x1, 1);
|
||||
rw_scalestep = scalestep;
|
||||
|
@ -175,7 +181,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
|
|||
// Texture must be cached
|
||||
R_CheckTextureCache(texnum);
|
||||
|
||||
if (textures[texnum]->flip & 2) // vertically flipped?
|
||||
if (vertflip) // vertically flipped?
|
||||
colfunc_2s = R_DrawFlippedMaskedColumn;
|
||||
else
|
||||
colfunc_2s = R_DrawMaskedColumn; // render the usual 2sided single-patch packed texture
|
||||
|
@ -469,6 +475,11 @@ static boolean R_IsFFloorTranslucent(visffloor_t *pfloor)
|
|||
return false;
|
||||
}
|
||||
|
||||
static fixed_t R_GetSlopeTextureSlide(pslope_t *slope, angle_t lineangle)
|
||||
{
|
||||
return FixedMul(slope->zdelta, FINECOSINE((lineangle-slope->xydirection)>>ANGLETOFINESHIFT));
|
||||
}
|
||||
|
||||
//
|
||||
// R_RenderThickSideRange
|
||||
// Renders all the thick sides in the given range.
|
||||
|
@ -484,8 +495,6 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
|
|||
sector_t tempsec;
|
||||
INT32 templight;
|
||||
INT32 i, p;
|
||||
fixed_t bottombounds = viewheight << FRACBITS;
|
||||
fixed_t topbounds = (con_clipviewtop - 1) << FRACBITS;
|
||||
fixed_t offsetvalue;
|
||||
lightlist_t *light;
|
||||
r_lightlist_t *rlight;
|
||||
|
@ -495,12 +504,14 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
|
|||
INT64 top_frac, top_step, bottom_frac, bottom_step;
|
||||
// skew FOF walls with slopes?
|
||||
fixed_t ffloortextureslide = 0;
|
||||
INT32 oldx = -1;
|
||||
fixed_t oldtexturecolumn = -1;
|
||||
fixed_t left_top, left_bottom; // needed here for slope skewing
|
||||
pslope_t *skewslope = NULL;
|
||||
boolean do_texture_skew;
|
||||
boolean dont_peg_bottom;
|
||||
fixed_t wall_offsetx;
|
||||
fixed_t wall_scalex, wall_scaley;
|
||||
UINT8 vertflip;
|
||||
unsigned lengthcol;
|
||||
|
||||
void (*colfunc_2s) (column_t *, unsigned);
|
||||
|
@ -513,15 +524,13 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
|
|||
curline = ds->curline;
|
||||
backsector = pfloor->target;
|
||||
frontsector = curline->frontsector == pfloor->target ? curline->backsector : curline->frontsector;
|
||||
sidedef = &sides[pfloor->master->sidenum[0]];
|
||||
sidedef = R_GetFFloorSide(curline, pfloor);
|
||||
|
||||
colfunc = colfuncs[BASEDRAWFUNC];
|
||||
|
||||
if (pfloor->master->flags & ML_TFERLINE)
|
||||
{
|
||||
size_t linenum = curline->linedef-backsector->lines[0];
|
||||
line_t *newline = pfloor->master->frontsector->lines[0] + linenum;
|
||||
sidedef = &sides[newline->sidenum[0]];
|
||||
line_t *newline = R_GetFFloorLine(curline, pfloor);
|
||||
do_texture_skew = newline->flags & ML_SKEWTD;
|
||||
dont_peg_bottom = newline->flags & ML_DONTPEGBOTTOM;
|
||||
}
|
||||
|
@ -532,6 +541,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
|
|||
}
|
||||
|
||||
texnum = R_GetTextureNum(sidedef->midtexture);
|
||||
vertflip = textures[texnum]->flip & 2;
|
||||
|
||||
if (pfloor->fofflags & FOF_TRANSLUCENT)
|
||||
{
|
||||
|
@ -685,18 +695,25 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
|
|||
|
||||
wall_scalex = FixedDiv(FRACUNIT, sidedef->scalex_mid);
|
||||
wall_scaley = sidedef->scaley_mid;
|
||||
if (wall_scaley < 0)
|
||||
{
|
||||
wall_scaley = -wall_scaley;
|
||||
vertflip = !vertflip;
|
||||
}
|
||||
|
||||
thicksidecol = ffloortexturecolumn;
|
||||
|
||||
wall_offsetx = ds->offsetx + sidedef->offsetx_mid;
|
||||
|
||||
if (wall_scalex == FRACUNIT)
|
||||
{
|
||||
for (INT32 x = x1; x <= x2; x++)
|
||||
thicksidecol[x] = ds->thicksidecol[x] + ds->offsetx;
|
||||
thicksidecol[x] = ds->thicksidecol[x];
|
||||
}
|
||||
else
|
||||
{
|
||||
for (INT32 x = x1; x <= x2; x++)
|
||||
thicksidecol[x] = FixedDiv(ds->thicksidecol[x], wall_scalex) + ds->offsetx;
|
||||
thicksidecol[x] = FixedDiv(ds->thicksidecol[x], wall_scalex);
|
||||
}
|
||||
|
||||
mfloorclip = ds->sprbottomclip;
|
||||
|
@ -731,7 +748,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
|
|||
if (skewslope)
|
||||
{
|
||||
angle_t lineangle = R_PointToAngle2(curline->v1->x, curline->v1->y, curline->v2->x, curline->v2->y);
|
||||
ffloortextureslide = FixedMul(skewslope->zdelta, FINECOSINE((lineangle-skewslope->xydirection)>>ANGLETOFINESHIFT));
|
||||
ffloortextureslide = FixedMul(R_GetSlopeTextureSlide(skewslope, lineangle), wall_scaley);
|
||||
}
|
||||
|
||||
dc_texturemid += offsetvalue;
|
||||
|
@ -739,7 +756,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
|
|||
// Texture must be cached
|
||||
R_CheckTextureCache(texnum);
|
||||
|
||||
if (textures[texnum]->flip & 2) // vertically flipped?
|
||||
if (vertflip) // vertically flipped?
|
||||
colfunc_2s = R_DrawRepeatFlippedMaskedColumn;
|
||||
else
|
||||
colfunc_2s = R_DrawRepeatMaskedColumn; // render the usual 2sided single-patch packed texture
|
||||
|
@ -773,9 +790,9 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
|
|||
// skew FOF walls
|
||||
if (ffloortextureslide)
|
||||
{
|
||||
if (oldx != -1)
|
||||
dc_texturemid += FixedMul(ffloortextureslide, thicksidecol[oldx]-thicksidecol[dc_x]);
|
||||
oldx = dc_x;
|
||||
if (oldtexturecolumn != -1)
|
||||
dc_texturemid += FixedMul(ffloortextureslide, oldtexturecolumn-ds->thicksidecol[dc_x]);
|
||||
oldtexturecolumn = ds->thicksidecol[dc_x];
|
||||
}
|
||||
|
||||
// Calculate bounds
|
||||
|
@ -791,7 +808,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
|
|||
bottom_frac += bottom_step;
|
||||
|
||||
// SoM: If column is out of range, why bother with it??
|
||||
if (windowbottom < topbounds || windowtop > bottombounds)
|
||||
if (windowbottom < 0 || windowtop > (viewheight << FRACBITS))
|
||||
{
|
||||
if (dc_numlights)
|
||||
{
|
||||
|
@ -810,7 +827,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
|
|||
dc_iscale = FixedMul(0xffffffffu / (unsigned)spryscale, wall_scaley);
|
||||
|
||||
// Get data for the column
|
||||
col = R_GetColumn(texnum, (thicksidecol[dc_x] >> FRACBITS));
|
||||
col = R_GetColumn(texnum, ((thicksidecol[dc_x] + wall_offsetx) >> FRACBITS));
|
||||
|
||||
// SoM: New code does not rely on R_DrawColumnShadowed_8 which
|
||||
// will (hopefully) put less strain on the stack.
|
||||
|
@ -984,36 +1001,64 @@ static boolean R_FFloorCanClip(visffloor_t *pfloor)
|
|||
#define HEIGHTBITS 12
|
||||
#define HEIGHTUNIT (1<<HEIGHTBITS)
|
||||
|
||||
static void R_DrawRegularWall(UINT8 *source, INT32 height)
|
||||
{
|
||||
dc_source = source;
|
||||
dc_texheight = height;
|
||||
colfunc();
|
||||
}
|
||||
|
||||
//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_DrawFlippedWall(UINT8 *source, INT32 height)
|
||||
{
|
||||
dc_texheight = height;
|
||||
R_DrawFlippedPost(source, (unsigned)height, colfunc);
|
||||
}
|
||||
|
||||
static void R_RenderSegLoop (void)
|
||||
{
|
||||
angle_t angle;
|
||||
fixed_t textureoffset;
|
||||
size_t pindex;
|
||||
INT32 yl;
|
||||
INT32 yh;
|
||||
size_t pindex;
|
||||
INT32 yl;
|
||||
INT32 yh;
|
||||
|
||||
INT32 mid;
|
||||
INT32 mid;
|
||||
fixed_t texturecolumn = 0;
|
||||
fixed_t toptexturecolumn = 0;
|
||||
fixed_t bottomtexturecolumn = 0;
|
||||
fixed_t oldtexturecolumn = -1;
|
||||
fixed_t oldtexturecolumn_top = -1;
|
||||
fixed_t oldtexturecolumn_bottom = -1;
|
||||
INT32 top;
|
||||
INT32 bottom;
|
||||
INT32 i;
|
||||
INT32 top;
|
||||
INT32 bottom;
|
||||
INT32 i;
|
||||
|
||||
fixed_t topscaley = rw_toptexturescaley;
|
||||
fixed_t midscaley = rw_midtexturescaley;
|
||||
fixed_t bottomscaley = rw_bottomtexturescaley;
|
||||
|
||||
void (*drawtop)(UINT8 *, INT32) = R_DrawRegularWall;
|
||||
void (*drawmiddle)(UINT8 *, INT32) = R_DrawRegularWall;
|
||||
void (*drawbottom)(UINT8 *, INT32) = R_DrawRegularWall;
|
||||
|
||||
if (dc_numlights)
|
||||
colfunc = colfuncs[COLDRAWFUNC_SHADOWED];
|
||||
|
||||
if (toptexture && topscaley < 0)
|
||||
{
|
||||
topscaley = -topscaley;
|
||||
drawtop = R_DrawFlippedWall;
|
||||
}
|
||||
if (midtexture && midscaley < 0)
|
||||
{
|
||||
midscaley = -midscaley;
|
||||
drawmiddle = R_DrawFlippedWall;
|
||||
}
|
||||
if (bottomtexture && bottomscaley < 0)
|
||||
{
|
||||
bottomscaley = -bottomscaley;
|
||||
drawbottom = R_DrawFlippedWall;
|
||||
}
|
||||
|
||||
if (midtexture)
|
||||
R_CheckTextureCache(midtexture);
|
||||
|
@ -1234,8 +1279,6 @@ static void R_RenderSegLoop (void)
|
|||
dc_lightlist[i].rcolormap = dc_lightlist[i].extra_colormap->colormap + (xwalllights[pindex] - colormaps);
|
||||
else
|
||||
dc_lightlist[i].rcolormap = xwalllights[pindex];
|
||||
|
||||
colfunc = colfuncs[COLDRAWFUNC_SHADOWED];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1252,24 +1295,9 @@ static void R_RenderSegLoop (void)
|
|||
dc_yl = yl;
|
||||
dc_yh = yh;
|
||||
dc_texturemid = rw_midtexturemid;
|
||||
dc_iscale = FixedMul(0xffffffffu / (unsigned)rw_scale, rw_midtexturescaley);
|
||||
dc_source = R_GetColumn(midtexture, offset >> FRACBITS)->pixels;
|
||||
dc_texheight = textureheight[midtexture]>>FRACBITS;
|
||||
|
||||
//profile stuff ---------------------------------------------------------
|
||||
#ifdef TIMING
|
||||
ProfZeroTimer();
|
||||
#endif
|
||||
colfunc();
|
||||
#ifdef TIMING
|
||||
RDMSR(0x10,&mycount);
|
||||
mytotal += mycount; //64bit add
|
||||
|
||||
if (nombre--==0)
|
||||
I_Error("R_DrawColumn CPU Spy reports: 0x%d %d\n", *((INT32 *)&mytotal+1),
|
||||
(INT32)mytotal);
|
||||
#endif
|
||||
//profile stuff ---------------------------------------------------------
|
||||
dc_iscale = FixedMul(0xffffffffu / (unsigned)rw_scale, midscaley);
|
||||
drawmiddle(R_GetColumn(midtexture, offset >> FRACBITS)->pixels, dc_texheight);
|
||||
|
||||
// dont draw anything more for this column, since
|
||||
// a midtexture blocks the view
|
||||
|
@ -1321,10 +1349,9 @@ static void R_RenderSegLoop (void)
|
|||
dc_yl = yl;
|
||||
dc_yh = mid;
|
||||
dc_texturemid = rw_toptexturemid;
|
||||
dc_iscale = FixedMul(0xffffffffu / (unsigned)rw_scale, rw_toptexturescaley);
|
||||
dc_source = R_GetColumn(toptexture, offset >> FRACBITS)->pixels;
|
||||
dc_texheight = textureheight[toptexture]>>FRACBITS;
|
||||
colfunc();
|
||||
dc_iscale = FixedMul(0xffffffffu / (unsigned)rw_scale, topscaley);
|
||||
drawtop(R_GetColumn(toptexture, offset >> FRACBITS)->pixels, dc_texheight);
|
||||
ceilingclip[rw_x] = (INT16)mid;
|
||||
}
|
||||
else if (!rw_ceilingmarked) // entirely off top of screen
|
||||
|
@ -1334,8 +1361,8 @@ static void R_RenderSegLoop (void)
|
|||
ceilingclip[rw_x] = topclip;
|
||||
|
||||
if (oldtexturecolumn_top != -1)
|
||||
rw_toptexturemid += FixedMul(rw_toptextureslide, oldtexturecolumn_top-toptexturecolumn);
|
||||
oldtexturecolumn_top = toptexturecolumn;
|
||||
rw_toptexturemid += FixedMul(rw_toptextureslide, oldtexturecolumn_top-textureoffset);
|
||||
oldtexturecolumn_top = textureoffset;
|
||||
}
|
||||
else if (markceiling && (!rw_ceilingmarked)) // no top wall
|
||||
ceilingclip[rw_x] = topclip;
|
||||
|
@ -1369,10 +1396,9 @@ static void R_RenderSegLoop (void)
|
|||
dc_yl = mid;
|
||||
dc_yh = yh;
|
||||
dc_texturemid = rw_bottomtexturemid;
|
||||
dc_iscale = FixedMul(0xffffffffu / (unsigned)rw_scale, rw_bottomtexturescaley);
|
||||
dc_source = R_GetColumn(bottomtexture, offset >> FRACBITS)->pixels;
|
||||
dc_texheight = textureheight[bottomtexture]>>FRACBITS;
|
||||
colfunc();
|
||||
dc_iscale = FixedMul(0xffffffffu / (unsigned)rw_scale, bottomscaley);
|
||||
drawbottom(R_GetColumn(bottomtexture, offset >> FRACBITS)->pixels, dc_texheight);
|
||||
floorclip[rw_x] = (INT16)mid;
|
||||
}
|
||||
else if (!rw_floormarked) // entirely off bottom of screen
|
||||
|
@ -1382,8 +1408,8 @@ static void R_RenderSegLoop (void)
|
|||
floorclip[rw_x] = bottomclip;
|
||||
|
||||
if (oldtexturecolumn_bottom != -1)
|
||||
rw_bottomtexturemid += FixedMul(rw_bottomtextureslide, oldtexturecolumn_bottom-bottomtexturecolumn);
|
||||
oldtexturecolumn_bottom = bottomtexturecolumn;
|
||||
rw_bottomtexturemid += FixedMul(rw_bottomtextureslide, oldtexturecolumn_bottom-textureoffset);
|
||||
oldtexturecolumn_bottom = textureoffset;
|
||||
}
|
||||
else if (markfloor && (!rw_floormarked)) // no bottom wall
|
||||
floorclip[rw_x] = bottomclip;
|
||||
|
@ -1407,11 +1433,14 @@ static void R_RenderSegLoop (void)
|
|||
{
|
||||
if (oldtexturecolumn != -1)
|
||||
{
|
||||
rw_midtexturemid += FixedMul(rw_midtextureslide, oldtexturecolumn-texturecolumn);
|
||||
rw_midtextureback += FixedMul(rw_midtexturebackslide, oldtexturecolumn-texturecolumn);
|
||||
INT32 diff = oldtexturecolumn-textureoffset;
|
||||
if (rw_invmidtexturescalex < 0)
|
||||
diff = -diff;
|
||||
rw_midtexturemid += FixedMul(rw_midtextureslide, diff);
|
||||
rw_midtextureback += FixedMul(rw_midtexturebackslide, diff);
|
||||
}
|
||||
|
||||
oldtexturecolumn = texturecolumn;
|
||||
oldtexturecolumn = textureoffset;
|
||||
}
|
||||
|
||||
if (invscale)
|
||||
|
@ -1505,7 +1534,7 @@ static void R_AllocClippingTables(size_t range)
|
|||
static void R_AllocTextureColumnTables(size_t range)
|
||||
{
|
||||
size_t pos = curtexturecolumntable - texturecolumntable;
|
||||
size_t need = range * 3;
|
||||
size_t need = range * 4;
|
||||
|
||||
if (pos + need < texturecolumntablesize)
|
||||
return;
|
||||
|
@ -1526,15 +1555,48 @@ static void R_AllocTextureColumnTables(size_t range)
|
|||
for (drawseg_t *ds = drawsegs; ds < ds_p; ds++)
|
||||
{
|
||||
// Check if it's in range of the tables
|
||||
if (ds->maskedtexturecol + ds->x1 >= oldtable && ds->maskedtexturecol + ds->x1 <= oldlast)
|
||||
ds->maskedtexturecol = (ds->maskedtexturecol - oldtable) + texturecolumntable;
|
||||
if (ds->thicksidecol + ds->x1 >= oldtable && ds->thicksidecol + ds->x1 <= oldlast)
|
||||
ds->thicksidecol = (ds->thicksidecol - oldtable) + texturecolumntable;
|
||||
if (ds->invscale + ds->x1 >= oldtable && ds->invscale + ds->x1 <= oldlast)
|
||||
ds->invscale = (ds->invscale - oldtable) + texturecolumntable;
|
||||
#define CHECK(which) \
|
||||
if (which + ds->x1 >= oldtable && which + ds->x1 <= oldlast) \
|
||||
which = (which - oldtable) + texturecolumntable
|
||||
|
||||
CHECK(ds->maskedtexturecol);
|
||||
CHECK(ds->maskedtextureheight);
|
||||
CHECK(ds->thicksidecol);
|
||||
CHECK(ds->invscale);
|
||||
|
||||
#undef CHECK
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// R_ScaleFromGlobalAngle
|
||||
// Returns the texture mapping scale for the current line (horizontal span)
|
||||
// at the given angle.
|
||||
// rw_distance must be calculated first.
|
||||
//
|
||||
// killough 5/2/98: reformatted, cleaned up
|
||||
//
|
||||
// note: THIS IS USED ONLY FOR WALLS!
|
||||
static fixed_t R_ScaleFromGlobalAngle(angle_t visangle)
|
||||
{
|
||||
angle_t anglea = ANGLE_90 + (visangle-viewangle);
|
||||
angle_t angleb = ANGLE_90 + (visangle-rw_normalangle);
|
||||
fixed_t den = FixedMul(rw_distance, FINESINE(anglea>>ANGLETOFINESHIFT));
|
||||
// proff 11/06/98: Changed for high-res
|
||||
fixed_t num = FixedMul(projectiony, FINESINE(angleb>>ANGLETOFINESHIFT));
|
||||
|
||||
if (den > num>>16)
|
||||
{
|
||||
num = FixedDiv(num, den);
|
||||
if (num > 64*FRACUNIT)
|
||||
return 64*FRACUNIT;
|
||||
if (num < 256)
|
||||
return 256;
|
||||
return num;
|
||||
}
|
||||
return 64*FRACUNIT;
|
||||
}
|
||||
|
||||
//
|
||||
// R_StoreWallRange
|
||||
// A wall segment will be drawn
|
||||
|
@ -1706,11 +1768,14 @@ void R_StoreWallRange(INT32 start, INT32 stop)
|
|||
|
||||
midtexture = toptexture = bottomtexture = maskedtexture = 0;
|
||||
ds_p->maskedtexturecol = NULL;
|
||||
ds_p->maskedtextureheight = NULL;
|
||||
ds_p->numthicksides = numthicksides = 0;
|
||||
ds_p->thicksidecol = NULL;
|
||||
ds_p->invscale = NULL;
|
||||
ds_p->tsilheight = 0;
|
||||
|
||||
texcoltables = false;
|
||||
|
||||
numbackffloors = 0;
|
||||
|
||||
for (i = 0; i < MAXFFLOORS; i++)
|
||||
|
@ -1736,16 +1801,19 @@ void R_StoreWallRange(INT32 start, INT32 stop)
|
|||
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));
|
||||
floorfrontslide = R_GetSlopeTextureSlide(frontsector->f_slope, lineangle);
|
||||
|
||||
if (frontsector->c_slope)
|
||||
ceilingfrontslide = FixedMul(frontsector->c_slope->zdelta, FINECOSINE((lineangle-frontsector->c_slope->xydirection)>>ANGLETOFINESHIFT));
|
||||
ceilingfrontslide = R_GetSlopeTextureSlide(frontsector->c_slope, lineangle);
|
||||
|
||||
if (backsector && backsector->f_slope)
|
||||
floorbackslide = FixedMul(backsector->f_slope->zdelta, FINECOSINE((lineangle-backsector->f_slope->xydirection)>>ANGLETOFINESHIFT));
|
||||
if (backsector)
|
||||
{
|
||||
if (backsector->f_slope)
|
||||
floorbackslide = R_GetSlopeTextureSlide(backsector->f_slope, lineangle);
|
||||
|
||||
if (backsector && backsector->c_slope)
|
||||
ceilingbackslide = FixedMul(backsector->c_slope->zdelta, FINECOSINE((lineangle-backsector->c_slope->xydirection)>>ANGLETOFINESHIFT));
|
||||
if (backsector->c_slope)
|
||||
ceilingbackslide = R_GetSlopeTextureSlide(backsector->c_slope, lineangle);
|
||||
}
|
||||
}
|
||||
|
||||
rw_midtexturescalex = sidedef->scalex_mid;
|
||||
|
@ -1761,26 +1829,27 @@ void R_StoreWallRange(INT32 start, INT32 stop)
|
|||
|
||||
fixed_t rowoffset = sidedef->rowoffset + sidedef->offsety_mid;
|
||||
fixed_t texheight = textureheight[midtexture];
|
||||
fixed_t scaley = abs(rw_midtexturescaley);
|
||||
|
||||
if (rw_midtexturescaley > 0)
|
||||
{
|
||||
if (linedef->flags & ML_NOSKEW)
|
||||
{
|
||||
if (linedef->flags & ML_DONTPEGBOTTOM)
|
||||
rw_midtexturemid = FixedMul(frontsector->floorheight - viewz, rw_midtexturescaley) + texheight;
|
||||
rw_midtexturemid = FixedMul(frontsector->floorheight - viewz, scaley) + texheight;
|
||||
else
|
||||
rw_midtexturemid = FixedMul(frontsector->ceilingheight - viewz, rw_midtexturescaley);
|
||||
rw_midtexturemid = FixedMul(frontsector->ceilingheight - viewz, scaley);
|
||||
}
|
||||
else if (linedef->flags & ML_DONTPEGBOTTOM)
|
||||
{
|
||||
rw_midtexturemid = FixedMul(worldbottom, rw_midtexturescaley) + texheight;
|
||||
rw_midtextureslide = floorfrontslide;
|
||||
rw_midtexturemid = FixedMul(worldbottom, scaley) + texheight;
|
||||
rw_midtextureslide = FixedMul(floorfrontslide, scaley);
|
||||
}
|
||||
else
|
||||
{
|
||||
// top of texture at top
|
||||
rw_midtexturemid = FixedMul(worldtop, rw_midtexturescaley);
|
||||
rw_midtextureslide = ceilingfrontslide;
|
||||
rw_midtexturemid = FixedMul(worldtop, scaley);
|
||||
rw_midtextureslide = FixedMul(ceilingfrontslide, scaley);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -1791,20 +1860,20 @@ void R_StoreWallRange(INT32 start, INT32 stop)
|
|||
if (linedef->flags & ML_NOSKEW)
|
||||
{
|
||||
if (linedef->flags & ML_DONTPEGBOTTOM)
|
||||
rw_midtexturemid = FixedMul(frontsector->floorheight - viewz, rw_midtexturescaley);
|
||||
rw_midtexturemid = FixedMul(frontsector->floorheight - viewz, scaley);
|
||||
else
|
||||
rw_midtexturemid = FixedMul(frontsector->ceilingheight - viewz, rw_midtexturescaley) + texheight;
|
||||
rw_midtexturemid = FixedMul(frontsector->ceilingheight - viewz, scaley) + texheight;
|
||||
}
|
||||
else if (linedef->flags & ML_DONTPEGBOTTOM)
|
||||
{
|
||||
rw_midtexturemid = FixedMul(worldbottom, rw_midtexturescaley);
|
||||
rw_midtextureslide = floorfrontslide;
|
||||
rw_midtexturemid = FixedMul(worldbottom, scaley);
|
||||
rw_midtextureslide = FixedMul(floorfrontslide, scaley);
|
||||
}
|
||||
else
|
||||
{
|
||||
// top of texture at top
|
||||
rw_midtexturemid = FixedMul(worldtop, rw_midtexturescaley) + texheight;
|
||||
rw_midtextureslide = ceilingfrontslide;
|
||||
rw_midtexturemid = FixedMul(worldtop, scaley) + texheight;
|
||||
rw_midtextureslide = FixedMul(ceilingfrontslide, scaley);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2013,15 +2082,16 @@ void R_StoreWallRange(INT32 start, INT32 stop)
|
|||
{
|
||||
// top of texture at top
|
||||
rw_toptexturemid = worldtop;
|
||||
rw_toptextureslide = ceilingfrontslide;
|
||||
rw_toptextureslide = FixedMul(ceilingfrontslide, abs(rw_toptexturescaley));
|
||||
}
|
||||
else
|
||||
{
|
||||
rw_toptexturemid = worldhigh + texheight;
|
||||
rw_toptextureslide = ceilingbackslide;
|
||||
rw_toptextureslide = FixedMul(ceilingbackslide, abs(rw_toptexturescaley));
|
||||
}
|
||||
|
||||
rw_toptexturemid = FixedMul(rw_toptexturemid, rw_toptexturescaley);
|
||||
rw_toptexturemid = FixedMul(rw_toptexturemid, abs(rw_toptexturescaley));
|
||||
rw_toptexturemid += toprowoffset;
|
||||
}
|
||||
|
||||
// check BOTTOM TEXTURE
|
||||
|
@ -2052,24 +2122,24 @@ void R_StoreWallRange(INT32 start, INT32 stop)
|
|||
// bottom of texture at bottom
|
||||
// top of texture at top
|
||||
rw_bottomtexturemid = worldbottom;
|
||||
rw_bottomtextureslide = floorfrontslide;
|
||||
rw_bottomtextureslide = FixedMul(floorfrontslide, abs(rw_bottomtexturescaley));
|
||||
}
|
||||
else
|
||||
{
|
||||
// top of texture at top
|
||||
rw_bottomtexturemid = worldlow;
|
||||
rw_bottomtextureslide = floorbackslide;
|
||||
rw_bottomtextureslide = FixedMul(floorbackslide, abs(rw_bottomtexturescaley));
|
||||
}
|
||||
|
||||
rw_bottomtexturemid = FixedMul(rw_bottomtexturemid, rw_bottomtexturescaley);
|
||||
rw_bottomtexturemid = FixedMul(rw_bottomtexturemid, abs(rw_bottomtexturescaley));
|
||||
rw_bottomtexturemid += botrowoffset;
|
||||
}
|
||||
|
||||
rw_toptexturemid += toprowoffset;
|
||||
rw_bottomtexturemid += botrowoffset;
|
||||
|
||||
// allocate space for masked texture tables
|
||||
R_AllocTextureColumnTables(rw_stopx - start);
|
||||
|
||||
texcoltables = true;
|
||||
|
||||
if (frontsector && backsector && !Tag_Compare(&frontsector->tags, &backsector->tags) && (backsector->ffloors || frontsector->ffloors))
|
||||
{
|
||||
ffloor_t *rover;
|
||||
|
@ -2268,7 +2338,8 @@ void R_StoreWallRange(INT32 start, INT32 stop)
|
|||
ds_p->maskedtexturecol = maskedtexturecol = curtexturecolumntable - rw_x;
|
||||
curtexturecolumntable += rw_stopx - rw_x;
|
||||
|
||||
maskedtextureheight = ds_p->maskedtextureheight; // note to red, this == &(ds_p->maskedtextureheight[0])
|
||||
ds_p->maskedtextureheight = maskedtextureheight = curtexturecolumntable - rw_x;
|
||||
curtexturecolumntable += rw_stopx - rw_x;
|
||||
|
||||
maskedtexture = true;
|
||||
|
||||
|
@ -2310,13 +2381,14 @@ void R_StoreWallRange(INT32 start, INT32 stop)
|
|||
}
|
||||
}
|
||||
|
||||
rw_midtexturemid = FixedMul(rw_midtexturemid, rw_midtexturescaley);
|
||||
rw_midtextureback = FixedMul(rw_midtextureback, rw_midtexturescaley);
|
||||
rw_midtexturemid = FixedMul(rw_midtexturemid, abs(rw_midtexturescaley));
|
||||
rw_midtextureback = FixedMul(rw_midtextureback, abs(rw_midtexturescaley));
|
||||
|
||||
rw_midtextureslide = FixedMul(rw_midtextureslide, abs(rw_midtexturescaley));
|
||||
rw_midtexturebackslide = FixedMul(rw_midtexturebackslide, abs(rw_midtexturescaley));
|
||||
|
||||
rw_midtexturemid += sidedef->rowoffset + sidedef->offsety_mid;
|
||||
rw_midtextureback += sidedef->rowoffset + sidedef->offsety_mid;
|
||||
|
||||
maskedtexture = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2440,7 +2512,7 @@ void R_StoreWallRange(INT32 start, INT32 stop)
|
|||
if (frontsector->numlights)
|
||||
{
|
||||
dc_numlights = frontsector->numlights;
|
||||
if (dc_numlights >= dc_maxlights)
|
||||
if (dc_numlights > dc_maxlights)
|
||||
{
|
||||
dc_maxlights = dc_numlights;
|
||||
dc_lightlist = Z_Realloc(dc_lightlist, sizeof (*dc_lightlist) * dc_maxlights, PU_STATIC, NULL);
|
||||
|
|
|
@ -658,12 +658,31 @@ void R_DrawMaskedColumn(column_t *column, unsigned lengthcol)
|
|||
static UINT8 *flippedcol = NULL;
|
||||
static size_t flippedcolsize = 0;
|
||||
|
||||
void R_DrawFlippedPost(UINT8 *source, unsigned length, void (*drawcolfunc)(void))
|
||||
{
|
||||
if (!length)
|
||||
return;
|
||||
|
||||
if (!flippedcolsize || length > flippedcolsize)
|
||||
{
|
||||
flippedcolsize = length;
|
||||
flippedcol = Z_Realloc(flippedcol, length, PU_STATIC, NULL);
|
||||
}
|
||||
|
||||
dc_source = flippedcol;
|
||||
|
||||
for (UINT8 *s = (UINT8 *)source, *d = flippedcol+length-1; d >= flippedcol; s++)
|
||||
*d-- = *s;
|
||||
|
||||
drawcolfunc();
|
||||
}
|
||||
|
||||
void R_DrawFlippedMaskedColumn(column_t *column, unsigned lengthcol)
|
||||
{
|
||||
INT32 topscreen;
|
||||
INT32 bottomscreen;
|
||||
fixed_t basetexturemid = dc_texturemid;
|
||||
UINT8 *d,*s;
|
||||
INT32 topdelta;
|
||||
|
||||
for (unsigned i = 0; i < column->num_posts; i++)
|
||||
{
|
||||
|
@ -671,7 +690,7 @@ void R_DrawFlippedMaskedColumn(column_t *column, unsigned lengthcol)
|
|||
if (!post->length)
|
||||
continue;
|
||||
|
||||
INT32 topdelta = lengthcol-post->length-post->topdelta;
|
||||
topdelta = lengthcol-post->length-post->topdelta;
|
||||
topscreen = sprtopscreen + spryscale*topdelta;
|
||||
bottomscreen = sprbotscreen == INT32_MAX ? topscreen + spryscale*post->length
|
||||
: sprbotscreen + spryscale*post->length;
|
||||
|
@ -698,18 +717,9 @@ void R_DrawFlippedMaskedColumn(column_t *column, unsigned lengthcol)
|
|||
|
||||
if (dc_yl <= dc_yh && dc_yh > 0)
|
||||
{
|
||||
if (post->length > flippedcolsize)
|
||||
{
|
||||
flippedcolsize = post->length;
|
||||
flippedcol = Z_Realloc(flippedcol, flippedcolsize, PU_STATIC, NULL);
|
||||
}
|
||||
|
||||
for (s = column->pixels+post->data_offset+post->length, d = flippedcol; d < flippedcol+post->length; --s)
|
||||
*d++ = *s;
|
||||
dc_source = flippedcol;
|
||||
dc_texturemid = basetexturemid - (topdelta<<FRACBITS);
|
||||
|
||||
colfunc();
|
||||
R_DrawFlippedPost(column->pixels + post->data_offset, post->length, colfunc);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -48,6 +48,7 @@ extern fixed_t windowbottom;
|
|||
|
||||
void R_DrawMaskedColumn(column_t *column, unsigned lengthcol);
|
||||
void R_DrawFlippedMaskedColumn(column_t *column, unsigned lengthcol);
|
||||
void R_DrawFlippedPost(UINT8 *source, unsigned length, void (*drawcolfunc)(void));
|
||||
|
||||
// ----------------
|
||||
// SPRITE RENDERING
|
||||
|
|
|
@ -81,7 +81,7 @@ extern angle_t tantoangle[SLOPERANGE+1];
|
|||
|
||||
// Utility function, called by R_PointToAngle.
|
||||
FUNCMATH unsigned SlopeDiv(unsigned num, unsigned den);
|
||||
// Only called by R_PointToAngleEx
|
||||
// Only called by R_PointToAngle64
|
||||
UINT64 SlopeDivEx(unsigned int num, unsigned int den);
|
||||
|
||||
// 360 - angle_t(ANGLE_45) = ANGLE_315
|
||||
|
|
Loading…
Reference in a new issue