Merge branch 'v2dev3' into ACS2

This commit is contained in:
NepDisk 2024-10-23 13:02:58 -04:00
commit 62f50486fe
3 changed files with 307 additions and 305 deletions

View file

@ -833,13 +833,11 @@ static void HWR_ProjectWall(FOutVector *wallVerts, FSurfaceInfo *pSurf, FBITFIEL
//
// HWR_SplitWall
// SoM: split up and light walls according to the lightlist.
// This may also include leaving out parts of the wall that can't be seen
//
static void HWR_SplitWall(sector_t *sector, FOutVector *wallVerts, INT32 texnum, FSurfaceInfo* Surf, INT32 cutflag, ffloor_t *pfloor, FBITFIELD polyflags)
{
/* SoM: split up and light walls according to the
lightlist. This may also include leaving out parts
of the wall that can't be seen */
float realtop, realbot, top, bot;
float pegt, pegb, pegmul;
float height = 0.0f, bheight = 0.0f;
@ -848,38 +846,51 @@ static void HWR_SplitWall(sector_t *sector, FOutVector *wallVerts, INT32 texnum,
float endpegt, endpegb, endpegmul;
float endheight = 0.0f, endbheight = 0.0f;
// compiler complains when P_GetSlopeZAt is used in FLOAT_TO_FIXED directly
// use this as a temp var to store P_GetSlopeZAt's return value each time
fixed_t temp;
float diff;
fixed_t v1x = FLOAT_TO_FIXED(wallVerts[0].x);
fixed_t v1y = FLOAT_TO_FIXED(wallVerts[0].z); // not a typo
fixed_t v2x = FLOAT_TO_FIXED(wallVerts[1].x);
fixed_t v2y = FLOAT_TO_FIXED(wallVerts[1].z); // not a typo
fixed_t v1x = FloatToFixed(wallVerts[0].x);
fixed_t v1y = FloatToFixed(wallVerts[0].z);
fixed_t v2x = FloatToFixed(wallVerts[1].x);
fixed_t v2y = FloatToFixed(wallVerts[1].z);
INT32 solid, i;
lightlist_t * list = sector->lightlist;
const UINT8 alpha = Surf->PolyColor.s.alpha;
FUINT lightnum = sector->lightlevel;
extracolormap_t *colormap = NULL;
realtop = top = wallVerts[3].y;
realbot = bot = wallVerts[0].y;
diff = top - bot;
pegt = wallVerts[3].t;
pegb = wallVerts[0].t;
pegmul = (pegb - pegt) / (top - bot);
// Lactozilla: If both heights of a side lay on the same position, then this wall is a triangle.
// To avoid division by zero, which would result in a NaN, we check if the vertical difference
// between the two vertices is not zero.
if (fpclassify(diff) == FP_ZERO)
pegmul = 0.0;
else
pegmul = (pegb - pegt) / diff;
endrealtop = endtop = wallVerts[2].y;
endrealbot = endbot = wallVerts[1].y;
diff = endtop - endbot;
endpegt = wallVerts[2].t;
endpegb = wallVerts[1].t;
endpegmul = (endpegb - endpegt) / (endtop - endbot);
for (i = 0; i < sector->numlights; i++)
if (fpclassify(diff) == FP_ZERO)
endpegmul = 0.0;
else
endpegmul = (endpegb - endpegt) / diff;
for (INT32 i = 0; i < sector->numlights; i++)
{
if (endtop < endrealbot && top < realbot)
return;
lightlist_t *list = sector->lightlist;
if (!(list[i].flags & FOF_NOSHADE))
{
if (pfloor && (pfloor->fofflags & FOF_FOG))
@ -894,7 +905,7 @@ static void HWR_SplitWall(sector_t *sector, FOutVector *wallVerts, INT32 texnum,
}
}
solid = false;
boolean solid = false;
if ((sector->lightlist[i].flags & FOF_CUTSOLIDS) && !(cutflag & FOF_EXTRA))
solid = true;
@ -911,16 +922,13 @@ static void HWR_SplitWall(sector_t *sector, FOutVector *wallVerts, INT32 texnum,
else
solid = false;
temp = P_GetLightZAt(&list[i], v1x, v1y);
height = FIXED_TO_FLOAT(temp);
temp = P_GetLightZAt(&list[i], v2x, v2y);
endheight = FIXED_TO_FLOAT(temp);
height = FixedToFloat(P_GetLightZAt(&list[i], v1x, v1y));
endheight = FixedToFloat(P_GetLightZAt(&list[i], v2x, v2y));
if (solid)
{
temp = P_GetFFloorBottomZAt(list[i].caster, v1x, v1y);
bheight = FIXED_TO_FLOAT(temp);
temp = P_GetFFloorBottomZAt(list[i].caster, v2x, v2y);
endbheight = FIXED_TO_FLOAT(temp);
bheight = FixedToFloat(P_GetFFloorBottomZAt(list[i].caster, v1x, v1y));
endbheight = FixedToFloat(P_GetFFloorBottomZAt(list[i].caster, v2x, v2y));
}
if (endheight >= endtop && height >= top)
@ -933,10 +941,8 @@ static void HWR_SplitWall(sector_t *sector, FOutVector *wallVerts, INT32 texnum,
if (i + 1 < sector->numlights)
{
temp = P_GetLightZAt(&list[i+1], v1x, v1y);
bheight = FIXED_TO_FLOAT(temp);
temp = P_GetLightZAt(&list[i+1], v2x, v2y);
endbheight = FIXED_TO_FLOAT(temp);
bheight = FixedToFloat(P_GetLightZAt(&list[i+1], v1x, v1y));
endbheight = FixedToFloat(P_GetLightZAt(&list[i+1], v2x, v2y));
}
else
{
@ -944,19 +950,20 @@ static void HWR_SplitWall(sector_t *sector, FOutVector *wallVerts, INT32 texnum,
endbheight = endrealbot;
}
if (endbheight >= endtop && bheight >= top)
if (endbheight > endtop)
endbot = endtop;
if (bheight >= top)
continue;
//Found a break;
// Found a break
// The heights are clamped to ensure the polygon doesn't cross itself.
bot = bheight;
if (bot < realbot)
bot = realbot;
endbot = endbheight;
if (endbot < endrealbot)
endbot = endrealbot;
endbot = min(max(endbheight, endrealbot), endtop);
Surf->PolyColor.s.alpha = alpha;
@ -1025,6 +1032,42 @@ static void HWR_DrawSkyWall(FOutVector *wallVerts, FSurfaceInfo *Surf)
// PF_Occlude is set in HWR_ProjectWall to draw into the depth buffer
}
// Returns true if the midtexture is visible, and false if... it isn't...
static boolean HWR_BlendMidtextureSurface(FSurfaceInfo *pSurf)
{
FUINT blendmode = PF_Masked;
pSurf->PolyColor.s.alpha = 0xFF;
if (!gl_curline->polyseg)
{
if (gl_linedef->blendmode && gl_linedef->blendmode != AST_FOG)
{
if (gl_linedef->alpha >= 0 && gl_linedef->alpha < FRACUNIT)
blendmode = HWR_SurfaceBlend(gl_linedef->blendmode, R_GetLinedefTransTable(gl_linedef->alpha), pSurf);
else
blendmode = HWR_GetBlendModeFlag(gl_linedef->blendmode);
}
else if (gl_linedef->alpha >= 0 && gl_linedef->alpha < FRACUNIT)
blendmode = HWR_TranstableToAlpha(R_GetLinedefTransTable(gl_linedef->alpha), pSurf);
}
else if (gl_curline->polyseg->translucency > 0)
{
// Polyobject translucency is done differently
if (gl_curline->polyseg->translucency >= NUMTRANSMAPS) // wall not drawn
return false;
else
blendmode = HWR_TranstableToAlpha(gl_curline->polyseg->translucency, pSurf);
}
if (blendmode != PF_Masked && pSurf->PolyColor.s.alpha == 0x00)
return false;
pSurf->PolyFlags = blendmode;
return true;
}
//
// HWR_ProcessSeg
// A portion or all of a wall segment will be drawn, from startfrac to endfrac,
@ -1043,16 +1086,9 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
fixed_t worldhighslope = 0, worldlowslope = 0;
fixed_t v1x, v1y, v2x, v2y;
GLMapTexture_t *grTex = NULL;
float cliplow = 0.0f, cliphigh = 0.0f;
INT32 gl_midtexture;
fixed_t h, l; // 3D sides and 2s middle textures
fixed_t hS, lS;
FUINT lightnum = 255;
extracolormap_t *colormap;
FSurfaceInfo Surf;
boolean tripwire;
gl_sidedef = gl_curline->sidedef;
@ -1104,11 +1140,15 @@ 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;
cliplow = (float)texturehpeg;
cliphigh = (float)(texturehpeg + (gl_curline->flength*FRACUNIT));
}
fixed_t texturehpeg = gl_sidedef->textureoffset + gl_curline->offset;
float cliplow = (float)texturehpeg;
float cliphigh = (float)(texturehpeg + (gl_curline->flength*FRACUNIT));
FUINT lightnum = 255;
extracolormap_t *colormap = gl_frontsector->extra_colormap;
FSurfaceInfo Surf;
Surf.PolyColor.s.alpha = 255;
tripwire = P_IsLineTripWire(gl_linedef);
@ -1117,15 +1157,16 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
lightnum = HWR_CalcWallLight(gl_frontsector->lightlevel, gl_curline);
}
colormap = gl_frontsector->extra_colormap;
if (gl_frontsector)
Surf.PolyColor.s.alpha = 255;
INT32 gl_midtexture = R_GetTextureNum(gl_sidedef->midtexture);
GLMapTexture_t *grTex = NULL;
// two sided line
if (gl_backsector)
{
INT32 gl_toptexture = 0, gl_bottomtexture = 0;
// two sided line
fixed_t texturevpeg;
boolean bothceilingssky = false; // turned on if both back and front ceilings are sky
boolean bothfloorssky = false; // likewise, but for floors
@ -1241,51 +1282,47 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
// check TOP TEXTURE
if ((worldhighslope < worldtopslope || worldhigh < worldtop) && gl_toptexture)
{
// PEGGING
if (gl_linedef->flags & ML_DONTPEGTOP)
texturevpeg = 0;
else if (gl_linedef->flags & ML_SKEWTD)
texturevpeg = worldhigh + textureheight[gl_toptexture] - worldtop;
else
texturevpeg = gl_backsector->ceilingheight + textureheight[gl_toptexture] - gl_frontsector->ceilingheight;
texturevpeg += gl_sidedef->rowoffset;
// 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 %= textureheight[gl_toptexture];
grTex = HWR_GetTexture(gl_toptexture);
wallVerts[3].t = wallVerts[2].t = texturevpeg * grTex->scaleY;
wallVerts[0].t = wallVerts[1].t = (texturevpeg + gl_frontsector->ceilingheight - gl_backsector->ceilingheight) * grTex->scaleY;
wallVerts[0].s = wallVerts[3].s = cliplow * grTex->scaleX;
wallVerts[2].s = wallVerts[1].s = cliphigh * grTex->scaleX;
// Adjust t value for sloped walls
if (!(gl_linedef->flags & ML_SKEWTD))
{
fixed_t texturevpegtop; // top
grTex = HWR_GetTexture(gl_toptexture);
// PEGGING
if (gl_linedef->flags & ML_DONTPEGTOP)
texturevpegtop = 0;
else if (gl_linedef->flags & ML_SKEWTD)
texturevpegtop = worldhigh + textureheight[gl_sidedef->toptexture] - worldtop;
else
texturevpegtop = gl_backsector->ceilingheight + textureheight[gl_sidedef->toptexture] - gl_frontsector->ceilingheight;
texturevpegtop += gl_sidedef->rowoffset;
// 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
texturevpegtop %= (textures[gl_toptexture]->height)<<FRACBITS;
wallVerts[3].t = wallVerts[2].t = texturevpegtop * grTex->scaleY;
wallVerts[0].t = wallVerts[1].t = (texturevpegtop + gl_frontsector->ceilingheight - gl_backsector->ceilingheight) * grTex->scaleY;
wallVerts[0].s = wallVerts[3].s = cliplow * grTex->scaleX;
wallVerts[2].s = wallVerts[1].s = cliphigh * grTex->scaleX;
// Adjust t value for sloped walls
if (!(gl_linedef->flags & ML_SKEWTD))
{
// Unskewed
wallVerts[3].t -= (worldtop - gl_frontsector->ceilingheight) * grTex->scaleY;
wallVerts[2].t -= (worldtopslope - gl_frontsector->ceilingheight) * grTex->scaleY;
wallVerts[0].t -= (worldhigh - gl_backsector->ceilingheight) * grTex->scaleY;
wallVerts[1].t -= (worldhighslope - gl_backsector->ceilingheight) * grTex->scaleY;
}
else if (gl_linedef->flags & ML_DONTPEGTOP)
{
// Skewed by top
wallVerts[0].t = (texturevpegtop + worldtop - worldhigh) * grTex->scaleY;
wallVerts[1].t = (texturevpegtop + worldtopslope - worldhighslope) * grTex->scaleY;
}
else
{
// Skewed by bottom
wallVerts[0].t = wallVerts[1].t = (texturevpegtop + worldtop - worldhigh) * grTex->scaleY;
wallVerts[3].t = wallVerts[0].t - (worldtop - worldhigh) * grTex->scaleY;
wallVerts[2].t = wallVerts[1].t - (worldtopslope - worldhighslope) * grTex->scaleY;
}
// Unskewed
wallVerts[3].t -= (worldtop - gl_frontsector->ceilingheight) * grTex->scaleY;
wallVerts[2].t -= (worldtopslope - gl_frontsector->ceilingheight) * grTex->scaleY;
wallVerts[0].t -= (worldhigh - gl_backsector->ceilingheight) * grTex->scaleY;
wallVerts[1].t -= (worldhighslope - gl_backsector->ceilingheight) * grTex->scaleY;
}
else if (gl_linedef->flags & ML_DONTPEGTOP)
{
// Skewed by top
wallVerts[0].t = (texturevpeg + worldtop - worldhigh) * grTex->scaleY;
wallVerts[1].t = (texturevpeg + worldtopslope - worldhighslope) * grTex->scaleY;
}
else
{
// Skewed by bottom
wallVerts[0].t = wallVerts[1].t = (texturevpeg + worldtop - worldhigh) * grTex->scaleY;
wallVerts[3].t = wallVerts[0].t - (worldtop - worldhigh) * grTex->scaleY;
wallVerts[2].t = wallVerts[1].t - (worldtopslope - worldhighslope) * grTex->scaleY;
}
// set top/bottom coords
@ -1294,71 +1331,62 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
wallVerts[2].y = FIXED_TO_FLOAT(worldtopslope);
wallVerts[1].y = FIXED_TO_FLOAT(worldhighslope);
{
FBITFIELD polyflags = PF_Masked;
FBITFIELD polyflags = PF_Masked;
if (grTex->mipmap.flags & TF_TRANSPARENT)
polyflags = PF_Environment;
if (grTex->mipmap.flags & TF_TRANSPARENT)
polyflags = PF_Environment;
if (gl_frontsector->numlights)
HWR_SplitWall(gl_frontsector, wallVerts, gl_toptexture, &Surf, FOF_CUTLEVEL, NULL, polyflags);
else if (grTex->mipmap.flags & TF_TRANSPARENT)
HWR_AddTransparentWall(wallVerts, &Surf, gl_toptexture, polyflags, false, lightnum, colormap);
else
HWR_ProjectWall(wallVerts, &Surf, polyflags, lightnum, colormap);
}
if (gl_frontsector->numlights)
HWR_SplitWall(gl_frontsector, wallVerts, gl_toptexture, &Surf, FOF_CUTLEVEL, NULL, polyflags);
else if (grTex->mipmap.flags & TF_TRANSPARENT)
HWR_AddTransparentWall(wallVerts, &Surf, gl_toptexture, polyflags, false, lightnum, colormap);
else
HWR_ProjectWall(wallVerts, &Surf, polyflags, lightnum, colormap);
}
// check BOTTOM TEXTURE
if ((
worldlowslope > worldbottomslope ||
worldlow > worldbottom) && gl_bottomtexture) //only if VISIBLE!!!
if ((worldlowslope > worldbottomslope || worldlow > worldbottom) && gl_bottomtexture)
{
// PEGGING
if (!(gl_linedef->flags & ML_DONTPEGBOTTOM))
texturevpeg = 0;
else if (gl_linedef->flags & ML_SKEWTD)
texturevpeg = worldbottom - worldlow;
else
texturevpeg = gl_frontsector->floorheight - gl_backsector->floorheight;
texturevpeg += gl_sidedef->rowoffset;
// 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 %= textureheight[gl_bottomtexture];
grTex = HWR_GetTexture(gl_bottomtexture);
wallVerts[3].t = wallVerts[2].t = texturevpeg * grTex->scaleY;
wallVerts[0].t = wallVerts[1].t = (texturevpeg + gl_backsector->floorheight - gl_frontsector->floorheight) * grTex->scaleY;
wallVerts[0].s = wallVerts[3].s = cliplow * grTex->scaleX;
wallVerts[2].s = wallVerts[1].s = cliphigh * grTex->scaleX;
// Adjust t value for sloped walls
if (!(gl_linedef->flags & ML_SKEWTD))
{
fixed_t texturevpegbottom = 0; // bottom
grTex = HWR_GetTexture(gl_bottomtexture);
// PEGGING
if (!(gl_linedef->flags & ML_DONTPEGBOTTOM))
texturevpegbottom = 0;
else if (gl_linedef->flags & ML_SKEWTD)
texturevpegbottom = worldbottom - worldlow;
else
texturevpegbottom = gl_frontsector->floorheight - gl_backsector->floorheight;
texturevpegbottom += gl_sidedef->rowoffset;
// 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
texturevpegbottom %= (textures[gl_bottomtexture]->height)<<FRACBITS;
wallVerts[3].t = wallVerts[2].t = texturevpegbottom * grTex->scaleY;
wallVerts[0].t = wallVerts[1].t = (texturevpegbottom + gl_backsector->floorheight - gl_frontsector->floorheight) * grTex->scaleY;
wallVerts[0].s = wallVerts[3].s = cliplow * grTex->scaleX;
wallVerts[2].s = wallVerts[1].s = cliphigh * grTex->scaleX;
// Adjust t value for sloped walls
if (!(gl_linedef->flags & ML_SKEWTD))
{
// Unskewed
wallVerts[0].t -= (worldbottom - gl_frontsector->floorheight) * grTex->scaleY;
wallVerts[1].t -= (worldbottomslope - gl_frontsector->floorheight) * grTex->scaleY;
wallVerts[3].t -= (worldlow - gl_backsector->floorheight) * grTex->scaleY;
wallVerts[2].t -= (worldlowslope - gl_backsector->floorheight) * grTex->scaleY;
}
else if (gl_linedef->flags & ML_DONTPEGBOTTOM)
{
// Skewed by bottom
wallVerts[0].t = wallVerts[1].t = (texturevpegbottom + worldlow - worldbottom) * grTex->scaleY;
//wallVerts[3].t = wallVerts[0].t - (worldlow - worldbottom) * grTex->scaleY; // no need, [3] is already this
wallVerts[2].t = wallVerts[1].t - (worldlowslope - worldbottomslope) * grTex->scaleY;
}
else
{
// Skewed by top
wallVerts[0].t = (texturevpegbottom + worldlow - worldbottom) * grTex->scaleY;
wallVerts[1].t = (texturevpegbottom + worldlowslope - worldbottomslope) * grTex->scaleY;
}
// Unskewed
wallVerts[0].t -= (worldbottom - gl_frontsector->floorheight) * grTex->scaleY;
wallVerts[1].t -= (worldbottomslope - gl_frontsector->floorheight) * grTex->scaleY;
wallVerts[3].t -= (worldlow - gl_backsector->floorheight) * grTex->scaleY;
wallVerts[2].t -= (worldlowslope - gl_backsector->floorheight) * grTex->scaleY;
}
else if (gl_linedef->flags & ML_DONTPEGBOTTOM)
{
// Skewed by bottom
wallVerts[0].t = wallVerts[1].t = (texturevpeg + worldlow - worldbottom) * grTex->scaleY;
wallVerts[2].t = wallVerts[1].t - (worldlowslope - worldbottomslope) * grTex->scaleY;
}
else
{
// Skewed by top
wallVerts[0].t = (texturevpeg + worldlow - worldbottom) * grTex->scaleY;
wallVerts[1].t = (texturevpeg + worldlowslope - worldbottomslope) * grTex->scaleY;
}
// set top/bottom coords
@ -1367,29 +1395,23 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
wallVerts[2].y = FIXED_TO_FLOAT(worldlowslope);
wallVerts[1].y = FIXED_TO_FLOAT(worldbottomslope);
{
FBITFIELD polyflags = PF_Masked;
FBITFIELD polyflags = PF_Masked;
if (grTex->mipmap.flags & TF_TRANSPARENT)
polyflags = PF_Environment;
if (grTex->mipmap.flags & TF_TRANSPARENT)
polyflags = PF_Environment;
if (gl_frontsector->numlights)
HWR_SplitWall(gl_frontsector, wallVerts, gl_bottomtexture, &Surf, FOF_CUTLEVEL, NULL, polyflags);
else if (grTex->mipmap.flags & TF_TRANSPARENT)
HWR_AddTransparentWall(wallVerts, &Surf, gl_bottomtexture, polyflags, false, lightnum, colormap);
else
HWR_ProjectWall(wallVerts, &Surf, polyflags, lightnum, colormap);
}
if (gl_frontsector->numlights)
HWR_SplitWall(gl_frontsector, wallVerts, gl_bottomtexture, &Surf, FOF_CUTLEVEL, NULL, polyflags);
else if (grTex->mipmap.flags & TF_TRANSPARENT)
HWR_AddTransparentWall(wallVerts, &Surf, gl_bottomtexture, polyflags, false, lightnum, colormap);
else
HWR_ProjectWall(wallVerts, &Surf, polyflags, lightnum, colormap);
}
gl_midtexture = R_GetTextureNum(gl_sidedef->midtexture);
if (gl_midtexture)
// Render midtexture if there's one. Determine if it's visible first, though
if (gl_midtexture && HWR_BlendMidtextureSurface(&Surf))
{
FBITFIELD blendmode;
sector_t *front, *back;
fixed_t popentop, popenbottom, polytop, polybottom, lowcut, highcut;
fixed_t texturevpeg = 0;
INT32 repeats;
if (gl_linedef->frontsector->heightsec != -1)
@ -1418,57 +1440,73 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
else
low = back->floorheight;
repeats = (high - low)/textureheight[gl_sidedef->midtexture];
if ((high-low)%textureheight[gl_sidedef->midtexture])
repeats = (high - low) / textureheight[gl_midtexture];
if ((high - low) % textureheight[gl_midtexture])
repeats++; // tile an extra time to fill the gap -- Monster Iestyn
}
else
repeats = 1;
// SoM: a little note: This code re-arranging will
// fix the bug in Nimrod map02. popentop and popenbottom
// 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 = back->ceilingheight;
popenbottom = back->floorheight;
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 = textureheight[gl_midtexture] * repeats;
// Texture is not skewed
if (gl_linedef->flags & ML_NOSKEW)
{
if (gl_linedef->flags & ML_MIDPEG)
if (gl_linedef->flags & ML_MIDPEG) // Peg it to the floor
{
polybottom = max(front->floorheight, back->floorheight) + gl_sidedef->rowoffset;
polytop = polybottom + textureheight[gl_midtexture]*repeats;
polytop = polybottom + midtexheight;
}
else
else // Peg it to the ceiling
{
polytop = min(front->ceilingheight, back->ceilingheight) + gl_sidedef->rowoffset;
polybottom = polytop - textureheight[gl_midtexture]*repeats;
polybottom = polytop - midtexheight;
}
// The right side's coordinates are the the same as the left side
polytopslope = polytop;
polybottomslope = polybottom;
}
else if (gl_linedef->flags & ML_MIDPEG)
else if (gl_linedef->flags & ML_MIDPEG) // Skew the texture, but peg it to the floor
{
polybottom = popenbottom + gl_sidedef->rowoffset;
polytop = polybottom + textureheight[gl_midtexture]*repeats;
polytop = polybottom + midtexheight;
polybottomslope = popenbottomslope + gl_sidedef->rowoffset;
polytopslope = polybottomslope + midtexheight;
}
else
else // Skew it according to the ceiling's slope
{
polytop = popentop + gl_sidedef->rowoffset;
polybottom = polytop - textureheight[gl_midtexture]*repeats;
polybottom = polytop - midtexheight;
polytopslope = popentopslope + gl_sidedef->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
@ -1476,40 +1514,63 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
{
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)
{
// PEGGING
if (gl_linedef->flags & ML_MIDPEG)
texturevpeg = textureheight[gl_sidedef->midtexture]*repeats - h + polybottom;
else
texturevpeg = polytop - h;
grTex = HWR_GetTexture(gl_midtexture);
wallVerts[3].t = wallVerts[2].t = texturevpeg * grTex->scaleY;
wallVerts[0].t = wallVerts[1].t = (h - l + texturevpeg) * grTex->scaleY;
wallVerts[0].s = wallVerts[3].s = cliplow * grTex->scaleX;
wallVerts[2].s = wallVerts[1].s = cliphigh * grTex->scaleX;
texturevpeg = midtexheight - h + polybottom;
texturevpegslope = midtexheight - hS + polybottomslope;
}
else
{
texturevpeg = polytop - h;
texturevpegslope = polytopslope - hS;
}
grTex = HWR_GetTexture(gl_midtexture);
// Left side
wallVerts[3].t = texturevpeg * grTex->scaleY;
wallVerts[0].t = (h - l + texturevpeg) * grTex->scaleY;
wallVerts[0].s = wallVerts[3].s = cliplow * grTex->scaleX;
// Right side
wallVerts[2].t = texturevpegslope * grTex->scaleY;
wallVerts[1].t = (hS - lS + texturevpegslope) * grTex->scaleY;
wallVerts[2].s = wallVerts[1].s = cliphigh * 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[2].y = wallVerts[3].y = FIXED_TO_FLOAT(h);
wallVerts[0].y = wallVerts[1].y = FIXED_TO_FLOAT(l);
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);
// Correct to account for slopes
// TODO: Actually use the surface's flags so that I don't have to do this
FUINT blendmode = Surf.PolyFlags;
if (udmf) // lug: idk if we should even keep this? seems like it doesent do anything since udmf maps still had issues which this did not fix
{
// Correct to account for slopes
fixed_t midtextureslant;
if (gl_linedef->flags & ML_NOSKEW)
@ -1603,26 +1664,22 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
{
if (!gl_curline->polyseg) // Don't do it for polyobjects
{
if (gl_frontsector->ceilingpic == skyflatnum)
if (gl_frontsector->ceilingpic == skyflatnum
&& gl_backsector->ceilingpic != skyflatnum) // don't cull if back sector is also sky
{
if (gl_backsector->ceilingpic != skyflatnum) // don't cull if back sector is also sky
{
wallVerts[2].y = wallVerts[3].y = FIXED_TO_FLOAT(INT32_MAX); // draw to top of map space
wallVerts[0].y = FIXED_TO_FLOAT(worldtop);
wallVerts[1].y = FIXED_TO_FLOAT(worldtopslope);
HWR_DrawSkyWall(wallVerts, &Surf);
}
wallVerts[2].y = wallVerts[3].y = FIXED_TO_FLOAT(INT32_MAX); // draw to top of map space
wallVerts[0].y = FIXED_TO_FLOAT(worldtop);
wallVerts[1].y = FIXED_TO_FLOAT(worldtopslope);
HWR_DrawSkyWall(wallVerts, &Surf);
}
if (gl_frontsector->floorpic == skyflatnum)
if (gl_frontsector->floorpic == skyflatnum
&& gl_backsector->floorpic != skyflatnum) // same thing here
{
if (gl_backsector->floorpic != skyflatnum) // don't cull if back sector is also sky
{
wallVerts[3].y = FIXED_TO_FLOAT(worldbottom);
wallVerts[2].y = FIXED_TO_FLOAT(worldbottomslope);
wallVerts[0].y = wallVerts[1].y = FIXED_TO_FLOAT(INT32_MIN); // draw to bottom of map space
HWR_DrawSkyWall(wallVerts, &Surf);
}
wallVerts[3].y = FIXED_TO_FLOAT(worldbottom);
wallVerts[2].y = FIXED_TO_FLOAT(worldbottomslope);
wallVerts[0].y = wallVerts[1].y = FIXED_TO_FLOAT(INT32_MIN); // draw to bottom of map space
HWR_DrawSkyWall(wallVerts, &Surf);
}
}
}
@ -1630,40 +1687,38 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
else
{
// Single sided line... Deal only with the middletexture (if one exists)
gl_midtexture = R_GetTextureNum(gl_sidedef->midtexture);
if (gl_midtexture && gl_linedef->special != 41) // (Ignore horizon line for OGL)
if (gl_midtexture && gl_linedef->special != HORIZONSPECIAL) // (Ignore horizon line for OGL)
{
{
fixed_t texturevpeg;
// PEGGING
if ((gl_linedef->flags & (ML_DONTPEGBOTTOM|ML_NOSKEW)) == (ML_DONTPEGBOTTOM|ML_NOSKEW))
texturevpeg = gl_frontsector->floorheight + textureheight[gl_sidedef->midtexture] - gl_frontsector->ceilingheight + gl_sidedef->rowoffset;
else if (gl_linedef->flags & ML_DONTPEGBOTTOM)
texturevpeg = worldbottom + textureheight[gl_sidedef->midtexture] - worldtop + gl_sidedef->rowoffset;
else
// top of texture at top
texturevpeg = gl_sidedef->rowoffset;
fixed_t texturevpeg;
grTex = HWR_GetTexture(gl_midtexture);
// PEGGING
if ((gl_linedef->flags & (ML_DONTPEGBOTTOM|ML_NOSKEW)) == (ML_DONTPEGBOTTOM|ML_NOSKEW))
texturevpeg = gl_frontsector->floorheight + textureheight[gl_sidedef->midtexture] - gl_frontsector->ceilingheight + gl_sidedef->rowoffset;
else if (gl_linedef->flags & ML_DONTPEGBOTTOM)
texturevpeg = worldbottom + textureheight[gl_sidedef->midtexture] - worldtop + gl_sidedef->rowoffset;
else
// top of texture at top
texturevpeg = gl_sidedef->rowoffset;
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 * grTex->scaleX;
wallVerts[2].s = wallVerts[1].s = cliphigh * grTex->scaleX;
grTex = HWR_GetTexture(gl_midtexture);
// Texture correction for slopes
if (gl_linedef->flags & ML_NOSKEW) {
wallVerts[3].t += (gl_frontsector->ceilingheight - worldtop) * grTex->scaleY;
wallVerts[2].t += (gl_frontsector->ceilingheight - worldtopslope) * grTex->scaleY;
wallVerts[0].t += (gl_frontsector->floorheight - worldbottom) * grTex->scaleY;
wallVerts[1].t += (gl_frontsector->floorheight - worldbottomslope) * grTex->scaleY;
} else if (gl_linedef->flags & ML_DONTPEGBOTTOM) {
wallVerts[3].t = wallVerts[0].t + (worldbottom-worldtop) * grTex->scaleY;
wallVerts[2].t = wallVerts[1].t + (worldbottomslope-worldtopslope) * grTex->scaleY;
} else {
wallVerts[0].t = wallVerts[3].t - (worldbottom-worldtop) * grTex->scaleY;
wallVerts[1].t = wallVerts[2].t - (worldbottomslope-worldtopslope) * grTex->scaleY;
}
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 * grTex->scaleX;
wallVerts[2].s = wallVerts[1].s = cliphigh * grTex->scaleX;
// Texture correction for slopes
if (gl_linedef->flags & ML_NOSKEW) {
wallVerts[3].t += (gl_frontsector->ceilingheight - worldtop) * grTex->scaleY;
wallVerts[2].t += (gl_frontsector->ceilingheight - worldtopslope) * grTex->scaleY;
wallVerts[0].t += (gl_frontsector->floorheight - worldbottom) * grTex->scaleY;
wallVerts[1].t += (gl_frontsector->floorheight - worldbottomslope) * grTex->scaleY;
} else if (gl_linedef->flags & ML_DONTPEGBOTTOM) {
wallVerts[3].t = wallVerts[0].t + (worldbottom-worldtop) * grTex->scaleY;
wallVerts[2].t = wallVerts[1].t + (worldbottomslope-worldtopslope) * grTex->scaleY;
} else {
wallVerts[0].t = wallVerts[3].t - (worldbottom-worldtop) * grTex->scaleY;
wallVerts[1].t = wallVerts[2].t - (worldbottomslope-worldtopslope) * grTex->scaleY;
}
//Set textures properly on single sided walls that are sloped
@ -1726,7 +1781,7 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
//Hurdler: 3d-floors test
if (gl_frontsector && gl_backsector && !Tag_Compare(&gl_frontsector->tags, &gl_backsector->tags) && (gl_backsector->ffloors || gl_frontsector->ffloors))
if (gl_backsector && !Tag_Compare(&gl_frontsector->tags, &gl_backsector->tags) && (gl_backsector->ffloors || gl_frontsector->ffloors))
{
ffloor_t * rover;
fixed_t highcut = 0, lowcut = 0;

View file

@ -261,7 +261,7 @@ INT32 R_PointOnSideUDMF(fixed_t x, fixed_t y, const node_t *node)
// Try to quickly decide by looking at sign bits.
INT32 mask = (node->dy ^ node->dx ^ dx ^ dy) >> 31;
return (mask & ((node->dy ^ dx) < 0)) | // (left is negative)
(~mask & (FixedMul(dy, node->dx>>FRACBITS) >= FixedMul(node->dy>>FRACBITS, dx)));
(~mask & (FixedMul(dy, node->dx>>FRACBITS) >= FixedMul(node->dy>>FRACBITS, dx)));
}
INT32 R_PointOnSideKart(fixed_t x, fixed_t y, const node_t *restrict node)
@ -279,7 +279,7 @@ INT32 R_PointOnSideKart(fixed_t x, fixed_t y, const node_t *restrict node)
// also use a mask to avoid branch prediction
INT32 mask = (node->dy ^ node->dx ^ x ^ y) >> 31;
return (mask & ((node->dy ^ x) < 0)) | // (left is negative)
(~mask & (FixedMul(y, node->dx>>FRACBITS) >= FixedMul(node->dy>>FRACBITS, x)));
(~mask & (FixedMul(y, node->dx>>FRACBITS) >= FixedMul(node->dy>>FRACBITS, x)));
}
// killough 5/2/98: reformatted
@ -305,24 +305,6 @@ INT32 R_PointOnSegSide(fixed_t x, fixed_t y, const seg_t *line)
return FixedMul(dy, ldx>>FRACBITS) >= FixedMul(ldy>>FRACBITS, dx);
}
//
// R_PointToAngle
// To get a global angle from cartesian coordinates,
// the coordinates are flipped until they are in
// the first octant of the coordinate system, then
// the y (<=x) is scaled and divided by x to get a
// tangent (slope) value which is looked up in the
// tantoangle[] table. The +1 size of tantoangle[]
// is to handle the case when x==y without additional
// checking.
//
// killough 5/2/98: reformatted, cleaned up
angle_t R_PointToAngle(fixed_t x, fixed_t y)
{
return R_PointToAngle2(viewx, viewy, x, y);
}
// Similar to R_PointToAngle, but requires an additional player_t argument.
// If this player is a local displayplayer, this will base off the calculations off of their camera instead, otherwise use viewx/viewy as usual.
// Yes this is kinda ghetto.
@ -385,40 +367,6 @@ angle_t R_PointToAngle2(fixed_t pviewx, fixed_t pviewy, fixed_t x, fixed_t y)
0;
}
fixed_t R_PointToDist2(fixed_t px2, fixed_t py2, fixed_t px1, fixed_t py1)
{
return FixedHypot(px1 - px2, py1 - py2);
}
// Little extra utility. Works in the same way as R_PointToAngle2
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)
{
INT64 dx = x1-x2;
INT64 dy = y1-y2;
if (dx < INT32_MIN || dx > INT32_MAX || dy < INT32_MIN || dy > INT32_MAX)
{
x1 = (int)(dx / 2 + x2);
y1 = (int)(dy / 2 + y2);
}
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;
}
//
// R_ScaleFromGlobalAngle
// Returns the texture mapping scale for the current line (horizontal span)

View file

@ -75,13 +75,12 @@ extern lighttable_t *zlight[LIGHTLEVELS][MAXLIGHTZ];
INT32 R_PointOnSideUDMF(fixed_t x, fixed_t y, const node_t *node);
INT32 R_PointOnSideKart(fixed_t x, fixed_t y, const node_t *node);
INT32 R_PointOnSegSide(fixed_t x, fixed_t y, const seg_t *line);
angle_t R_PointToAngle(fixed_t x, fixed_t y);
#define R_PointToAngle(x, y) R_PointToAngle2(viewx, viewy, x, y)
angle_t R_PointToAnglePlayer(player_t *player, 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);
#define R_PointToDist(x, y) R_PointToDist2(viewx, viewy, x, y)
#define R_PointToDist2(px2, py2, px1, py1) FixedHypot((px1) - (px2), (py1) - (py2))
fixed_t R_ScaleFromGlobalAngle(angle_t visangle);
subsector_t *R_PointInSubsector(fixed_t x, fixed_t y);