- Added 'noclip' property to extra textures
- Fixed multiple issues with texture scaling
This commit is contained in:
Lactozilla 2024-02-01 02:23:13 -03:00
parent 2325b1bd20
commit e0885a4ad1
9 changed files with 333 additions and 146 deletions

View file

@ -1198,12 +1198,12 @@ static void HWR_RenderMidtexture(INT32 gl_midtexture, float cliplow, float cliph
// Left side // Left side
wallVerts[3].t = texturevpeg * yscale * grTex->scaleY; wallVerts[3].t = texturevpeg * yscale * grTex->scaleY;
wallVerts[0].t = (h - l + 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; wallVerts[0].s = wallVerts[3].s = ((cliplow * xscale) + gl_sidedef->textureoffset + gl_sidedef->offsetx_mid) * grTex->scaleX;
// Right side // Right side
wallVerts[2].t = texturevpegslope * yscale * grTex->scaleY; wallVerts[2].t = texturevpegslope * yscale * grTex->scaleY;
wallVerts[1].t = (hS - lS + 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; wallVerts[2].s = wallVerts[1].s = ((cliphigh * xscale) + gl_sidedef->textureoffset + gl_sidedef->offsetx_mid) * grTex->scaleX;
// set top/bottom coords // set top/bottom coords
// Take the texture peg into account, rather than changing the offsets past // Take the texture peg into account, rather than changing the offsets past
@ -1429,12 +1429,24 @@ static void HWR_RenderExtraTexture(unsigned which, side_t *side, sector_t *sec_f
fixed_t lowcutslope, highcutslope; fixed_t lowcutslope, highcutslope;
#define GET_CLIP_HEIGHTS() \ #define GET_CLIP_HEIGHTS() \
if (polyobj) \ if ((pfloor || polyobj) && (overlay->flags & SIDEOVERLAYFLAG_NOCLIP)) \
{ \ { \
/* Overlay textures on poly objects aren't clipped */ \
lowcut = lowcutslope = INT32_MIN; \ lowcut = lowcutslope = INT32_MIN; \
highcut = highcutslope = INT32_MAX; \ highcut = highcutslope = INT32_MAX; \
} \ } \
else if (polyobj) \
{ \
if (R_GetTextureNum(gl_sidedef->midtexture)) \
{ \
lowcut = lowcutslope = sec_back->floorheight; \
highcut = highcutslope = sec_back->ceilingheight; \
} \
else \
{ \
lowcut = lowcutslope = INT32_MIN; \
highcut = highcutslope = INT32_MAX; \
} \
} \
else if (!sec_back) \ else if (!sec_back) \
{ \ { \
lowcut = worldbottom; \ lowcut = worldbottom; \
@ -1762,12 +1774,12 @@ static void HWR_RenderExtraTexture(unsigned which, side_t *side, sector_t *sec_f
// Left side // Left side
wallVerts[3].t = texturevpeg * yscale * grTex->scaleY; wallVerts[3].t = texturevpeg * yscale * grTex->scaleY;
wallVerts[0].t = (h - l + texturevpeg) * yscale * grTex->scaleY; wallVerts[0].t = (h - l + texturevpeg) * yscale * grTex->scaleY;
wallVerts[0].s = wallVerts[3].s = ((xcliplow * xscale) + overlay->offsetx) * grTex->scaleX; wallVerts[0].s = wallVerts[3].s = ((xcliplow * xscale) + gl_sidedef->textureoffset + overlay->offsetx) * grTex->scaleX;
// Right side // Right side
wallVerts[2].t = texturevpegslope * yscale * grTex->scaleY; wallVerts[2].t = texturevpegslope * yscale * grTex->scaleY;
wallVerts[1].t = (hS - lS + texturevpegslope) * yscale * grTex->scaleY; wallVerts[1].t = (hS - lS + texturevpegslope) * yscale * grTex->scaleY;
wallVerts[2].s = wallVerts[1].s = ((xcliphigh * xscale) + overlay->offsetx) * grTex->scaleX; wallVerts[2].s = wallVerts[1].s = ((xcliphigh * xscale) + gl_sidedef->textureoffset + overlay->offsetx) * grTex->scaleX;
// set top/bottom coords // set top/bottom coords
wallVerts[3].y = FIXED_TO_FLOAT(h); wallVerts[3].y = FIXED_TO_FLOAT(h);
@ -1869,12 +1881,12 @@ static void HWR_RenderExtraTexture(unsigned which, side_t *side, sector_t *sec_f
// Left side // Left side
wallVerts[3].t = texturevpeg * yscale * grTex->scaleY; wallVerts[3].t = texturevpeg * yscale * grTex->scaleY;
wallVerts[0].t = (h - l + texturevpeg) * yscale * grTex->scaleY; wallVerts[0].t = (h - l + texturevpeg) * yscale * grTex->scaleY;
wallVerts[0].s = wallVerts[3].s = ((xcliplow * xscale) + overlay->offsetx) * grTex->scaleX; wallVerts[0].s = wallVerts[3].s = ((xcliplow * xscale) + gl_sidedef->textureoffset + overlay->offsetx) * grTex->scaleX;
// Right side // Right side
wallVerts[2].t = texturevpegslope * yscale * grTex->scaleY; wallVerts[2].t = texturevpegslope * yscale * grTex->scaleY;
wallVerts[1].t = (hS - lS + texturevpegslope) * yscale * grTex->scaleY; wallVerts[1].t = (hS - lS + texturevpegslope) * yscale * grTex->scaleY;
wallVerts[2].s = wallVerts[1].s = ((xcliphigh * xscale) + overlay->offsetx) * grTex->scaleX; wallVerts[2].s = wallVerts[1].s = ((xcliphigh * xscale) + gl_sidedef->textureoffset + overlay->offsetx) * grTex->scaleX;
RENDER_WALL_POLYGON(); RENDER_WALL_POLYGON();
@ -1883,7 +1895,7 @@ static void HWR_RenderExtraTexture(unsigned which, side_t *side, sector_t *sec_f
static void HWR_RenderFFloorExtraTextures(ffloor_t *pfloor, v2d_t vs, v2d_t ve, float xcliplow, float xcliphigh, FSurfaceInfo Surf, FBITFIELD blendmode) static void HWR_RenderFFloorExtraTextures(ffloor_t *pfloor, v2d_t vs, v2d_t ve, float xcliplow, float xcliphigh, FSurfaceInfo Surf, FBITFIELD blendmode)
{ {
side_t *pside = &sides[pfloor->master->sidenum[0]]; side_t *pside = R_GetFFloorSide(gl_curline, pfloor);
sector_t *psector = pfloor->master->frontsector; sector_t *psector = pfloor->master->frontsector;
HWR_RenderExtraTexture(EDGE_TEXTURE_TOP_UPPER, pside, psector, NULL, pfloor, NULL, vs, ve, xcliplow, xcliphigh, Surf, blendmode); HWR_RenderExtraTexture(EDGE_TEXTURE_TOP_UPPER, pside, psector, NULL, pfloor, NULL, vs, ve, xcliplow, xcliphigh, Surf, blendmode);
@ -1961,9 +1973,8 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
wallVerts[2].z = wallVerts[1].z = ve.y; wallVerts[2].z = wallVerts[1].z = ve.y;
// x offset the texture // x offset the texture
fixed_t texturehpeg = gl_sidedef->textureoffset + gl_curline->offset; float cliplow = (float)gl_curline->offset;
float cliplow = (float)texturehpeg; float cliphigh = cliplow + (gl_curline->flength * FRACUNIT);
float cliphigh = (float)(texturehpeg + (gl_curline->flength*FRACUNIT));
UINT32 lightnum = HWR_CalcWallLight(gl_frontsector->lightlevel, vs.x, vs.y, ve.x, ve.y); UINT32 lightnum = HWR_CalcWallLight(gl_frontsector->lightlevel, vs.x, vs.y, ve.x, ve.y);
extracolormap_t *colormap = gl_frontsector->extra_colormap; extracolormap_t *colormap = gl_frontsector->extra_colormap;
@ -2013,7 +2024,7 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
xscale = FixedToFloat(abs(gl_sidedef->scalex_top)); xscale = FixedToFloat(abs(gl_sidedef->scalex_top));
yscale = FixedToFloat(abs(gl_sidedef->scaley_top)); yscale = FixedToFloat(abs(gl_sidedef->scaley_top));
fixed_t offsetx_top = gl_sidedef->offsetx_top; fixed_t offsetx_top = gl_sidedef->textureoffset + gl_sidedef->offsetx_top;
float left = cliplow * xscale; float left = cliplow * xscale;
float right = cliphigh * xscale; float right = cliphigh * xscale;
@ -2024,15 +2035,17 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
offsetx_top = -offsetx_top; offsetx_top = -offsetx_top;
} }
fixed_t texheight = FixedDiv(textureheight[gl_toptexture], abs(gl_sidedef->scaley_top)); fixed_t texheight = textureheight[gl_toptexture];
fixed_t texheightscaled = FixedDiv(texheight, abs(gl_sidedef->scaley_top));
// PEGGING // PEGGING
// FIXME: This is probably not correct?
if (gl_linedef->flags & ML_DONTPEGTOP) if (gl_linedef->flags & ML_DONTPEGTOP)
texturevpeg = 0; texturevpeg = 0;
else if (gl_linedef->flags & ML_SKEWTD) else if (gl_linedef->flags & ML_SKEWTD)
texturevpeg = worldhigh + texheight - worldtop; texturevpeg = worldhigh + texheight - worldtop;
else else
texturevpeg = gl_backsector->ceilingheight + texheight - gl_frontsector->ceilingheight; texturevpeg = gl_backsector->ceilingheight + texheightscaled - gl_frontsector->ceilingheight;
texturevpeg *= yscale; texturevpeg *= yscale;
@ -2042,7 +2055,7 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
texturevpeg += gl_sidedef->rowoffset + gl_sidedef->offsety_top; 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 // 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[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].t = wallVerts[1].t = (texturevpeg + (gl_frontsector->ceilingheight - gl_backsector->ceilingheight) * yscale) * grTex->scaleY;
@ -2103,7 +2116,7 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
xscale = FixedToFloat(abs(gl_sidedef->scalex_bottom)); xscale = FixedToFloat(abs(gl_sidedef->scalex_bottom));
yscale = FixedToFloat(abs(gl_sidedef->scaley_bottom)); yscale = FixedToFloat(abs(gl_sidedef->scaley_bottom));
fixed_t offsetx_bottom = gl_sidedef->offsetx_bottom; fixed_t offsetx_bottom = gl_sidedef->textureoffset + gl_sidedef->offsetx_bottom;
float left = cliplow * xscale; float left = cliplow * xscale;
float right = cliphigh * xscale; float right = cliphigh * xscale;
@ -2252,8 +2265,8 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
wallVerts[3].t = wallVerts[2].t = texturevpeg * 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].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[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->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 // Texture correction for slopes
if (gl_linedef->flags & ML_NOSKEW) { if (gl_linedef->flags & ML_NOSKEW) {
@ -2320,8 +2333,9 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
// Used for height comparisons and etc across FOFs and slopes // Used for height comparisons and etc across FOFs and slopes
fixed_t high1, highslope1, low1, lowslope1; fixed_t high1, highslope1, low1, lowslope1;
fixed_t texturehpeg = gl_sidedef->textureoffset + gl_sidedef->offsetx_mid;
INT32 texnum; INT32 texnum;
line_t * newline = NULL; // Multi-Property FOF
lowcut = max(worldbottom, worldlow); lowcut = max(worldbottom, worldlow);
highcut = min(worldtop, worldhigh); highcut = min(worldtop, worldhigh);
@ -2355,16 +2369,14 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
if ((high1 < lowcut && highslope1 < lowcutslope) || (low1 > highcut && lowslope1 > highcutslope)) if ((high1 < lowcut && highslope1 < lowcutslope) || (low1 > highcut && lowslope1 > highcutslope))
continue; continue;
side_t *side = &sides[rover->master->sidenum[0]]; side_t *side = R_GetFFloorSide(gl_curline, rover);
boolean do_texture_skew; boolean do_texture_skew;
boolean dont_peg_bottom; boolean dont_peg_bottom;
if (rover->master->flags & ML_TFERLINE) if (rover->master->flags & ML_TFERLINE)
{ {
size_t linenum = gl_curline->linedef-gl_backsector->lines[0]; line_t *newline = R_GetFFloorLine(gl_curline, rover);
newline = rover->master->frontsector->lines[0] + linenum;
side = &sides[newline->sidenum[0]];
do_texture_skew = newline->flags & ML_SKEWTD; do_texture_skew = newline->flags & ML_SKEWTD;
dont_peg_bottom = newline->flags & ML_DONTPEGBOTTOM; dont_peg_bottom = newline->flags & ML_DONTPEGBOTTOM;
} }
@ -2442,8 +2454,8 @@ 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[0].s = wallVerts[3].s = ((cliplow * xscale) + texturehpeg + side->offsetx_mid) * grTex->scaleX;
wallVerts[2].s = wallVerts[1].s = ((cliphigh * xscale) + side->offsetx_mid) * grTex->scaleX; wallVerts[2].s = wallVerts[1].s = ((cliphigh * xscale) + texturehpeg + side->offsetx_mid) * grTex->scaleX;
} }
FBITFIELD blendmode; FBITFIELD blendmode;
@ -2514,13 +2526,21 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
if ((high1 < lowcut && highslope1 < lowcutslope) || (low1 > highcut && lowslope1 > highcutslope)) if ((high1 < lowcut && highslope1 < lowcutslope) || (low1 > highcut && lowslope1 > highcutslope))
continue; 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) if (rover->master->flags & ML_TFERLINE)
{ {
size_t linenum = gl_curline->linedef-gl_backsector->lines[0]; line_t *newline = R_GetFFloorLine(gl_curline, rover);
newline = rover->master->frontsector->lines[0] + linenum; do_texture_skew = newline->flags & ML_SKEWTD;
side = &sides[newline->sidenum[0]]; 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); texnum = R_GetTextureNum(side->midtexture);
@ -2557,17 +2577,43 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
} }
else 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); grTex = HWR_GetTexture(texnum);
xscale = FixedToFloat(side->scalex_mid); xscale = FixedToFloat(side->scalex_mid);
yscale = FixedToFloat(side->scaley_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[3].t = (((*rover->topheight - h) * yscale) + texturevpeg) * grTex->scaleY;
wallVerts[0].t = wallVerts[1].t = (((h - l) * yscale) + (diff + side->rowoffset + side->offsety_mid)) * 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[0].s = wallVerts[3].s = ((cliplow * xscale) + texturehpeg + side->offsetx_mid) * grTex->scaleX;
wallVerts[2].s = wallVerts[1].s = ((cliphigh * xscale) + side->offsetx_mid) * grTex->scaleX; wallVerts[2].s = wallVerts[1].s = ((cliphigh * xscale) + texturehpeg + side->offsetx_mid) * grTex->scaleX;
} }
FBITFIELD blendmode; FBITFIELD blendmode;

View file

@ -1462,6 +1462,7 @@ enum sideoverlay_e {
sideoverlay_scalex, sideoverlay_scalex,
sideoverlay_scaley, sideoverlay_scaley,
sideoverlay_noskew, sideoverlay_noskew,
sideoverlay_noclip,
sideoverlay_wrap sideoverlay_wrap
}; };
@ -1473,6 +1474,7 @@ static const char *const sideoverlay_opt[] = {
"scalex", "scalex",
"scaley", "scaley",
"noskew", "noskew",
"noclip",
"wrap", "wrap",
NULL}; NULL};
@ -1515,6 +1517,9 @@ static int sideoverlay_get(lua_State *L)
case sideoverlay_noskew: case sideoverlay_noskew:
lua_pushboolean(L, overlay->flags & SIDEOVERLAYFLAG_NOSKEW); lua_pushboolean(L, overlay->flags & SIDEOVERLAYFLAG_NOSKEW);
return 1; return 1;
case sideoverlay_noclip:
lua_pushboolean(L, overlay->flags & SIDEOVERLAYFLAG_NOCLIP);
return 1;
case sideoverlay_wrap: case sideoverlay_wrap:
lua_pushboolean(L, overlay->flags & SIDEOVERLAYFLAG_WRAP); lua_pushboolean(L, overlay->flags & SIDEOVERLAYFLAG_WRAP);
return 1; return 1;
@ -1544,6 +1549,8 @@ static int sideoverlay_set(lua_State *L)
return luaL_error(L, "side_t.overlay has no field named " LUA_QS ".", lua_tostring(L, 2)); return luaL_error(L, "side_t.overlay has no field named " LUA_QS ".", lua_tostring(L, 2));
case sideoverlay_texture: case sideoverlay_texture:
overlay->texture = luaL_checkinteger(L, 3); overlay->texture = luaL_checkinteger(L, 3);
if (overlay->texture)
overlay->side->flags |= SIDEFLAG_HASEDGETEXTURES;
break; break;
case sideoverlay_offsetx: case sideoverlay_offsetx:
overlay->offsetx = luaL_checkfixed(L, 3); overlay->offsetx = luaL_checkfixed(L, 3);
@ -1563,6 +1570,12 @@ static int sideoverlay_set(lua_State *L)
else else
overlay->flags &= ~SIDEOVERLAYFLAG_NOSKEW; overlay->flags &= ~SIDEOVERLAYFLAG_NOSKEW;
break; break;
case sideoverlay_noclip:
if (luaL_checkboolean(L, 3))
overlay->flags |= SIDEOVERLAYFLAG_NOCLIP;
else
overlay->flags &= ~SIDEOVERLAYFLAG_NOCLIP;
break;
case sideoverlay_wrap: case sideoverlay_wrap:
if (luaL_checkboolean(L, 3)) if (luaL_checkboolean(L, 3))
overlay->flags |= SIDEOVERLAYFLAG_WRAP; overlay->flags |= SIDEOVERLAYFLAG_WRAP;

View file

@ -1428,6 +1428,8 @@ static UINT32 GetSideDiff(const side_t *si, const side_t *spawnsi, UINT8 edgedif
diff |= LD_SDBOTSCALEY; diff |= LD_SDBOTSCALEY;
if (si->repeatcnt != spawnsi->repeatcnt) if (si->repeatcnt != spawnsi->repeatcnt)
diff |= LD_SDREPEATCNT; diff |= LD_SDREPEATCNT;
if (si->flags != spawnsi->flags)
diff |= LD_SDFLAGS;
if (edgediff[0] != 0) if (edgediff[0] != 0)
diff |= LD_SDOVERLAY1; diff |= LD_SDOVERLAY1;
if (edgediff[1] != 0) if (edgediff[1] != 0)
@ -1497,6 +1499,8 @@ static void ArchiveSide(const side_t *si, UINT32 diff, UINT8 edgediff[4])
WRITEFIXED(save_p, si->scaley_bottom); WRITEFIXED(save_p, si->scaley_bottom);
if (diff & LD_SDREPEATCNT) if (diff & LD_SDREPEATCNT)
WRITEINT16(save_p, si->repeatcnt); WRITEINT16(save_p, si->repeatcnt);
if (diff & LD_SDFLAGS)
WRITEUINT16(save_p, si->flags);
if (diff & LD_SDOVERLAY1) if (diff & LD_SDOVERLAY1)
ArchiveSideEdge(&si->overlays[0], edgediff[0]); ArchiveSideEdge(&si->overlays[0], edgediff[0]);
if (diff & LD_SDOVERLAY2) if (diff & LD_SDOVERLAY2)
@ -1672,6 +1676,8 @@ static void UnArchiveSide(side_t *si)
si->scaley_bottom = READFIXED(save_p); si->scaley_bottom = READFIXED(save_p);
if (diff & LD_SDREPEATCNT) if (diff & LD_SDREPEATCNT)
si->repeatcnt = READINT16(save_p); si->repeatcnt = READINT16(save_p);
if (diff & LD_SDFLAGS)
si->flags = READUINT16(save_p);
if (diff & LD_SDOVERLAY1) if (diff & LD_SDOVERLAY1)
UnArchiveSideEdge(&si->overlays[0]); UnArchiveSideEdge(&si->overlays[0]);
if (diff & LD_SDOVERLAY2) if (diff & LD_SDOVERLAY2)

View file

@ -1331,6 +1331,18 @@ static void P_WriteTics(INT32 tics, char **target)
P_WriteDuplicateText(text, target); P_WriteDuplicateText(text, target);
} }
static void P_InitSideEdges(side_t *sd)
{
for (unsigned j = 0; j < NUM_WALL_OVERLAYS; j++)
{
sd->overlays[j].texture = R_TextureNumForName("-");
sd->overlays[j].offsetx = sd->overlays[j].offsety = 0;
sd->overlays[j].scalex = sd->overlays[j].scaley = FRACUNIT;
sd->overlays[j].flags = 0;
sd->overlays[j].side = sd;
}
}
static void P_LoadSidedefs(UINT8 *data) static void P_LoadSidedefs(UINT8 *data)
{ {
mapsidedef_t *msd = (mapsidedef_t*)data; mapsidedef_t *msd = (mapsidedef_t*)data;
@ -1366,13 +1378,7 @@ static void P_LoadSidedefs(UINT8 *data)
sd->scalex_top = sd->scalex_mid = sd->scalex_bottom = FRACUNIT; sd->scalex_top = sd->scalex_mid = sd->scalex_bottom = FRACUNIT;
sd->scaley_top = sd->scaley_mid = sd->scaley_bottom = FRACUNIT; sd->scaley_top = sd->scaley_mid = sd->scaley_bottom = FRACUNIT;
for (unsigned j = 0; j < NUM_WALL_OVERLAYS; j++) P_InitSideEdges(sd);
{
sd->overlays[j].texture = R_TextureNumForName("-");
sd->overlays[j].offsetx = sd->overlays[j].offsety = 0;
sd->overlays[j].scalex = sd->overlays[j].scaley = FRACUNIT;
sd->overlays[j].flags = 0;
}
P_SetSidedefSector(i, (UINT16)SHORT(msd->sector)); P_SetSidedefSector(i, (UINT16)SHORT(msd->sector));
@ -1908,7 +1914,11 @@ static void ParseTextmapSidedefOverlay(unsigned which, UINT32 i, const char *par
{ {
side_overlay_t *overlay = &sides[i].overlays[which]; side_overlay_t *overlay = &sides[i].overlays[which];
if (fastcmp(param, "texture")) if (fastcmp(param, "texture"))
{
overlay->texture = R_TextureNumForName(val); overlay->texture = R_TextureNumForName(val);
if (overlay->texture)
sides[i].flags |= SIDEFLAG_HASEDGETEXTURES;
}
else if (fastcmp(param, "offsetx")) else if (fastcmp(param, "offsetx"))
overlay->offsetx = FLOAT_TO_FIXED(atof(val)); overlay->offsetx = FLOAT_TO_FIXED(atof(val));
else if (fastcmp(param, "offsety")) else if (fastcmp(param, "offsety"))
@ -1919,6 +1929,8 @@ static void ParseTextmapSidedefOverlay(unsigned which, UINT32 i, const char *par
overlay->scaley = FLOAT_TO_FIXED(atof(val)); overlay->scaley = FLOAT_TO_FIXED(atof(val));
else if (fastcmp(param, "noskew") && fastcmp("true", val)) else if (fastcmp(param, "noskew") && fastcmp("true", val))
overlay->flags |= SIDEOVERLAYFLAG_NOSKEW; overlay->flags |= SIDEOVERLAYFLAG_NOSKEW;
else if (fastcmp(param, "noclip") && fastcmp("true", val))
overlay->flags |= SIDEOVERLAYFLAG_NOCLIP;
else if (fastcmp(param, "wrap") && fastcmp("true", val)) else if (fastcmp(param, "wrap") && fastcmp("true", val))
overlay->flags |= SIDEOVERLAYFLAG_WRAP; overlay->flags |= SIDEOVERLAYFLAG_WRAP;
} }
@ -2243,6 +2255,8 @@ static void WriteTextmapEdgeTexture(const char *prefix, unsigned i, side_t *side
fprintf(f, "%s""scaley = %f;\n", prefix, FIXED_TO_FLOAT(side->overlays[i].scaley)); fprintf(f, "%s""scaley = %f;\n", prefix, FIXED_TO_FLOAT(side->overlays[i].scaley));
if (side->overlays[i].flags & SIDEOVERLAYFLAG_NOSKEW) if (side->overlays[i].flags & SIDEOVERLAYFLAG_NOSKEW)
fprintf(f, "%s""noskew = true;\n", prefix); fprintf(f, "%s""noskew = true;\n", prefix);
if (side->overlays[i].flags & SIDEOVERLAYFLAG_NOCLIP)
fprintf(f, "%s""noclip = true;\n", prefix);
if (side->overlays[i].flags & SIDEOVERLAYFLAG_WRAP) if (side->overlays[i].flags & SIDEOVERLAYFLAG_WRAP)
fprintf(f, "%s""wrap = true;\n", prefix); fprintf(f, "%s""wrap = true;\n", prefix);
} }
@ -3105,16 +3119,11 @@ static void P_LoadTextmap(void)
sd->toptexture = R_TextureNumForName("-"); sd->toptexture = R_TextureNumForName("-");
sd->midtexture = R_TextureNumForName("-"); sd->midtexture = R_TextureNumForName("-");
sd->bottomtexture = R_TextureNumForName("-"); sd->bottomtexture = R_TextureNumForName("-");
for (unsigned j = 0; j < NUM_WALL_OVERLAYS; j++)
{
sd->overlays[j].texture = R_TextureNumForName("-");
sd->overlays[j].offsetx = sd->overlays[j].offsety = 0;
sd->overlays[j].scalex = sd->overlays[j].scaley = FRACUNIT;
sd->overlays[j].flags = 0;
}
sd->sector = NULL; sd->sector = NULL;
sd->repeatcnt = 0; sd->repeatcnt = 0;
P_InitSideEdges(sd);
TextmapParse(sidesPos[i], i, ParseTextmapSidedefParameter); TextmapParse(sidesPos[i], i, ParseTextmapSidedefParameter);
if (!sd->sector) if (!sd->sector)
@ -3407,8 +3416,6 @@ static void P_InitializeSeg(seg_t *seg)
seg->lightmaps = NULL; // list of static lightmap for this seg seg->lightmaps = NULL; // list of static lightmap for this seg
#endif #endif
seg->numlights = 0;
seg->rlights = NULL;
seg->polyseg = NULL; seg->polyseg = NULL;
seg->dontrenderme = false; seg->dontrenderme = false;
} }

View file

@ -610,10 +610,16 @@ typedef struct line_s
} line_t; } line_t;
// Don't make available to Lua or I will find where you live // Don't make available to Lua or I will find where you live
typedef enum
{
SIDEFLAG_HASEDGETEXTURES = 1
} sideflags_t;
enum enum
{ {
SIDEOVERLAYFLAG_NOSKEW = 1<<0, SIDEOVERLAYFLAG_NOSKEW = 1<<0,
SIDEOVERLAYFLAG_WRAP = 1<<1 SIDEOVERLAYFLAG_NOCLIP = 1<<1,
SIDEOVERLAYFLAG_WRAP = 1<<2
}; };
typedef struct typedef struct
@ -622,9 +628,10 @@ typedef struct
fixed_t offsetx, offsety; fixed_t offsetx, offsety;
fixed_t scalex, scaley; fixed_t scalex, scaley;
UINT8 flags; UINT8 flags;
struct side_s *side;
} side_overlay_t; } side_overlay_t;
typedef struct typedef struct side_s
{ {
// add this to the calculated texture column // add this to the calculated texture column
fixed_t textureoffset; fixed_t textureoffset;
@ -632,13 +639,16 @@ typedef struct
// add this to the calculated texture top // add this to the calculated texture top
fixed_t rowoffset; fixed_t rowoffset;
// per-texture offsets for UDMF // per-texture offsets
fixed_t offsetx_top, offsetx_mid, offsetx_bottom; fixed_t offsetx_top, offsetx_mid, offsetx_bottom;
fixed_t offsety_top, offsety_mid, offsety_bottom; fixed_t offsety_top, offsety_mid, offsety_bottom;
// per-texture scale
fixed_t scalex_top, scalex_mid, scalex_bottom; fixed_t scalex_top, scalex_mid, scalex_bottom;
fixed_t scaley_top, scaley_mid, scaley_bottom; fixed_t scaley_top, scaley_mid, scaley_bottom;
UINT16 flags;
// Texture indices. // Texture indices.
// We do not maintain names here. // We do not maintain names here.
INT32 toptexture, bottomtexture, midtexture; INT32 toptexture, bottomtexture, midtexture;
@ -766,9 +776,6 @@ typedef struct seg_s
lightmap_t *lightmaps; // for static lightmap lightmap_t *lightmaps; // for static lightmap
#endif #endif
// Why slow things down by calculating lightlists for every thick side?
size_t numlights;
r_lightlist_t *rlights;
polyobj_t *polyseg; polyobj_t *polyseg;
boolean dontrenderme; boolean dontrenderme;
boolean glseg; boolean glseg;

View file

@ -407,33 +407,26 @@ angle_t R_PointToAngleEx(INT32 x2, INT32 y2, INT32 x1, INT32 y1)
0; 0;
} }
// line_t *R_GetFFloorLine(const seg_t *seg, const ffloor_t *pfloor)
// 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)
{ {
angle_t anglea = ANGLE_90 + (visangle-viewangle); if (pfloor->master->flags & ML_TFERLINE)
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); size_t linenum = seg->linedef - pfloor->target->lines[0];
if (num > 64*FRACUNIT) return pfloor->master->frontsector->lines[0] + linenum;
return 64*FRACUNIT;
if (num < 256)
return 256;
return num;
} }
return 64*FRACUNIT; else
return pfloor->master;
}
side_t *R_GetFFloorSide(const seg_t *seg, const ffloor_t *pfloor)
{
if (pfloor->master->flags & ML_TFERLINE)
{
line_t *newline = R_GetFFloorLine(seg, pfloor);
return &sides[newline->sidenum[0]];
}
else
return &sides[pfloor->master->sidenum[0]];
} }
// //

View file

@ -81,13 +81,15 @@ 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_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_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); 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_PointInSubsector(fixed_t x, fixed_t y);
subsector_t *R_PointInSubsectorOrNull(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); 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 // Render stats
extern precise_t ps_prevframetime;// time when previous frame was rendered extern precise_t ps_prevframetime;// time when previous frame was rendered

View file

@ -64,7 +64,7 @@ static struct
fixed_t mid, slide; fixed_t mid, slide;
fixed_t back, backslide; fixed_t back, backslide;
fixed_t scalex, scaley; fixed_t scalex, scaley;
fixed_t invscalex, invscaley; fixed_t invscalex;
fixed_t offsetx, offsety; fixed_t offsetx, offsety;
} rw_overlay[NUM_WALL_OVERLAYS]; } rw_overlay[NUM_WALL_OVERLAYS];
@ -617,9 +617,6 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
else else
dc_texturemid -= (textureheight[texnum])*times; dc_texturemid -= (textureheight[texnum])*times;
if (hasoverlaytexture && times == 0)
R_DoMaskedOverlayColumn(dc_x, maskedtexturecol[dc_x], INT32_MAX, INT32_MAX);
// Check for overflows first // Check for overflows first
overflow_test = (INT64)centeryfrac - (((INT64)dc_texturemid*spryscale)>>FRACBITS); overflow_test = (INT64)centeryfrac - (((INT64)dc_texturemid*spryscale)>>FRACBITS);
if (overflow_test < 0) overflow_test = -overflow_test; if (overflow_test < 0) overflow_test = -overflow_test;
@ -653,6 +650,9 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
sprtopscreen = centeryfrac - FixedMul(texture_top, spryscale); sprtopscreen = centeryfrac - FixedMul(texture_top, spryscale);
if (hasoverlaytexture && times == 0)
R_DoMaskedOverlayColumn(dc_x, maskedtexturecol[dc_x], sprtopscreen, centeryfrac - FixedMul(texture_bottom, spryscale));
// set wall bounds if there is a light list, or if this is a polyobject side // set wall bounds if there is a light list, or if this is a polyobject side
if (dc_numlights || curline->polyseg) if (dc_numlights || curline->polyseg)
{ {
@ -845,9 +845,6 @@ static void R_RenderExtraTexture(unsigned which, INT32 x1, INT32 x2, INT32 repea
// Setup lighting based on the presence/lack-of 3D floors. // Setup lighting based on the presence/lack-of 3D floors.
R_PrepareMaskedSegLightlist(ds, range); R_PrepareMaskedSegLightlist(ds, range);
mfloorclip = overlayopening[1];
mceilingclip = overlayopening[0];
for (times = 0; times < repeats; times++) for (times = 0; times < repeats; times++)
{ {
if (times > 0) if (times > 0)
@ -1025,6 +1022,11 @@ static boolean R_IsFFloorTranslucent(visffloor_t *pfloor)
return false; return false;
} }
static fixed_t R_GetSlopeTextureSlide(pslope_t *slope, angle_t lineangle)
{
return FixedMul(slope->zdelta, FINECOSINE((lineangle-slope->xydirection)>>ANGLETOFINESHIFT));
}
// //
// R_RenderThickSideRange // R_RenderThickSideRange
// Renders all the thick sides in the given range. // Renders all the thick sides in the given range.
@ -1050,11 +1052,12 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
// skew FOF walls with slopes? // skew FOF walls with slopes?
fixed_t ffloortextureslide = 0, topslopeslide = 0, bottomslopeslide = 0; fixed_t ffloortextureslide = 0, topslopeslide = 0, bottomslopeslide = 0;
angle_t lineangle; angle_t lineangle;
INT32 oldx = -1; fixed_t oldtexturecolumn = -1;
fixed_t left_top, left_bottom; // needed here for slope skewing fixed_t left_top, left_bottom; // needed here for slope skewing
pslope_t *skewslope = NULL; pslope_t *skewslope = NULL;
boolean do_texture_skew; boolean do_texture_skew;
boolean dont_peg_bottom; boolean dont_peg_bottom;
fixed_t wall_offsetx;
fixed_t wall_scalex, wall_scaley; fixed_t wall_scalex, wall_scaley;
INT32 blendlevel = 0; INT32 blendlevel = 0;
UINT8 vertflip; UINT8 vertflip;
@ -1069,15 +1072,13 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
curline = ds->curline; curline = ds->curline;
backsector = NULL; backsector = NULL;
frontsector = curline->frontsector == pfloor->target ? curline->backsector : curline->frontsector; frontsector = curline->frontsector == pfloor->target ? curline->backsector : curline->frontsector;
sidedef = &sides[pfloor->master->sidenum[0]]; sidedef = R_GetFFloorSide(curline, pfloor);
colfunc = colfuncs[BASEDRAWFUNC]; colfunc = colfuncs[BASEDRAWFUNC];
if (pfloor->master->flags & ML_TFERLINE) if (pfloor->master->flags & ML_TFERLINE)
{ {
size_t linenum = curline->linedef-pfloor->target->lines[0]; line_t *newline = R_GetFFloorLine(curline, pfloor);
line_t *newline = pfloor->master->frontsector->lines[0] + linenum;
sidedef = &sides[newline->sidenum[0]];
do_texture_skew = newline->flags & ML_SKEWTD; do_texture_skew = newline->flags & ML_SKEWTD;
dont_peg_bottom = newline->flags & ML_DONTPEGBOTTOM; dont_peg_bottom = newline->flags & ML_DONTPEGBOTTOM;
} }
@ -1248,15 +1249,17 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
thicksidecol = ffloortexturecolumn; thicksidecol = ffloortexturecolumn;
wall_offsetx = ds->offsetx + sidedef->offsetx_mid;
if (wall_scalex == FRACUNIT) if (wall_scalex == FRACUNIT)
{ {
for (INT32 x = x1; x <= x2; x++) for (INT32 x = x1; x <= x2; x++)
thicksidecol[x] = ds->thicksidecol[x] + ds->offsetx; thicksidecol[x] = ds->thicksidecol[x];
} }
else else
{ {
for (INT32 x = x1; x <= x2; x++) 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; mfloorclip = ds->sprbottomclip;
@ -1291,7 +1294,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
lineangle = R_PointToAngle2(curline->v1->x, curline->v1->y, curline->v2->x, curline->v2->y); lineangle = R_PointToAngle2(curline->v1->x, curline->v1->y, curline->v2->x, curline->v2->y);
if (skewslope) if (skewslope)
ffloortextureslide = FixedMul(skewslope->zdelta, FINECOSINE((lineangle-skewslope->xydirection)>>ANGLETOFINESHIFT)); ffloortextureslide = FixedMul(R_GetSlopeTextureSlide(skewslope, lineangle), wall_scaley);
dc_texturemid += offsetvalue; dc_texturemid += offsetvalue;
@ -1348,9 +1351,9 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
if (hasoverlaytexture) if (hasoverlaytexture)
{ {
if (*pfloor->t_slope) if (*pfloor->t_slope)
topslopeslide = FixedMul((*pfloor->t_slope)->zdelta, FINECOSINE((lineangle-(*pfloor->t_slope)->xydirection)>>ANGLETOFINESHIFT)); topslopeslide = R_GetSlopeTextureSlide(*pfloor->t_slope, lineangle);
if (*pfloor->b_slope) if (*pfloor->b_slope)
bottomslopeslide = FixedMul((*pfloor->b_slope)->zdelta, FINECOSINE((lineangle-(*pfloor->b_slope)->xydirection)>>ANGLETOFINESHIFT)); bottomslopeslide = R_GetSlopeTextureSlide(*pfloor->b_slope, lineangle);
R_AddOverlayTextures(pfloor->master->frontsector, NULL, left_top, left_bottom, 0, 0, topslopeslide, bottomslopeslide, 0, 0); R_AddOverlayTextures(pfloor->master->frontsector, NULL, left_top, left_bottom, 0, 0, topslopeslide, bottomslopeslide, 0, 0);
@ -1364,9 +1367,9 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
// skew FOF walls // skew FOF walls
if (ffloortextureslide) if (ffloortextureslide)
{ {
if (oldx != -1) if (oldtexturecolumn != -1)
dc_texturemid += FixedMul(ffloortextureslide, thicksidecol[oldx]-thicksidecol[dc_x]); dc_texturemid += FixedMul(ffloortextureslide, oldtexturecolumn-ds->thicksidecol[dc_x]);
oldx = dc_x; oldtexturecolumn = ds->thicksidecol[dc_x];
} }
// Calculate bounds // Calculate bounds
@ -1404,7 +1407,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
dc_iscale = FixedMul(0xffffffffu / (unsigned)spryscale, wall_scaley); dc_iscale = FixedMul(0xffffffffu / (unsigned)spryscale, wall_scaley);
// Get data for the column // Get data for the column
col = (column_t *)((UINT8 *)R_GetColumn(texnum, (thicksidecol[dc_x] >> FRACBITS)) - 3); col = (column_t *)((UINT8 *)R_GetColumn(texnum, ((thicksidecol[dc_x] + wall_offsetx) >> FRACBITS)) - 3);
// SoM: New code does not rely on R_DrawColumnShadowed_8 which // SoM: New code does not rely on R_DrawColumnShadowed_8 which
// will (hopefully) put less strain on the stack. // will (hopefully) put less strain on the stack.
@ -1939,8 +1942,8 @@ static void R_RenderSegLoop (void)
ceilingclip[rw_x] = topclip; ceilingclip[rw_x] = topclip;
if (oldtexturecolumn_top != -1) if (oldtexturecolumn_top != -1)
rw_toptexturemid += FixedMul(rw_toptextureslide, oldtexturecolumn_top-toptexturecolumn); rw_toptexturemid += FixedMul(rw_toptextureslide, oldtexturecolumn_top-textureoffset);
oldtexturecolumn_top = toptexturecolumn; oldtexturecolumn_top = textureoffset;
} }
else if (markceiling && (!rw_ceilingmarked)) // no top wall else if (markceiling && (!rw_ceilingmarked)) // no top wall
ceilingclip[rw_x] = topclip; ceilingclip[rw_x] = topclip;
@ -1985,8 +1988,8 @@ static void R_RenderSegLoop (void)
floorclip[rw_x] = bottomclip; floorclip[rw_x] = bottomclip;
if (oldtexturecolumn_bottom != -1) if (oldtexturecolumn_bottom != -1)
rw_bottomtexturemid += FixedMul(rw_bottomtextureslide, oldtexturecolumn_bottom-bottomtexturecolumn); rw_bottomtexturemid += FixedMul(rw_bottomtextureslide, oldtexturecolumn_bottom-textureoffset);
oldtexturecolumn_bottom = bottomtexturecolumn; oldtexturecolumn_bottom = textureoffset;
} }
else if (markfloor && (!rw_floormarked)) // no bottom wall else if (markfloor && (!rw_floormarked)) // no bottom wall
floorclip[rw_x] = bottomclip; floorclip[rw_x] = bottomclip;
@ -2010,14 +2013,14 @@ static void R_RenderSegLoop (void)
{ {
if (oldtexturecolumn != -1) if (oldtexturecolumn != -1)
{ {
INT32 diff = oldtexturecolumn-texturecolumn; INT32 diff = oldtexturecolumn-textureoffset;
if (rw_invmidtexturescalex < 0) if (rw_invmidtexturescalex < 0)
diff = -diff; diff = -diff;
rw_midtexturemid += FixedMul(rw_midtextureslide, diff); rw_midtexturemid += FixedMul(rw_midtextureslide, diff);
rw_midtextureback += FixedMul(rw_midtexturebackslide, diff); rw_midtextureback += FixedMul(rw_midtexturebackslide, diff);
} }
oldtexturecolumn = texturecolumn; oldtexturecolumn = textureoffset;
} }
if (hasoverlaytexture) if (hasoverlaytexture)
@ -2167,6 +2170,9 @@ static void R_AllocTextureColumnTables(size_t range)
static boolean R_CheckExtraTextures(boolean onesided) static boolean R_CheckExtraTextures(boolean onesided)
{ {
if (!(sidedef->flags & SIDEFLAG_HASEDGETEXTURES))
return false;
INT32 texnums[4] = { INT32 texnums[4] = {
R_GetTextureNum(sidedef->overlays[0].texture), R_GetTextureNum(sidedef->overlays[0].texture),
R_GetTextureNum(sidedef->overlays[1].texture), R_GetTextureNum(sidedef->overlays[1].texture),
@ -2214,7 +2220,6 @@ static void R_AddOverlayTextures(sector_t *sec_front, sector_t *sec_back, fixed_
rw_overlay[i].offsety = sidedef->overlays[i].offsety; rw_overlay[i].offsety = sidedef->overlays[i].offsety;
rw_overlay[i].invscalex = FixedDiv(FRACUNIT, rw_overlay[i].scalex); rw_overlay[i].invscalex = FixedDiv(FRACUNIT, rw_overlay[i].scalex);
rw_overlay[i].invscaley = FixedDiv(FRACUNIT, abs(rw_overlay[i].scaley));
if (sidedef->overlays[i].flags & SIDEOVERLAYFLAG_NOSKEW) if (sidedef->overlays[i].flags & SIDEOVERLAYFLAG_NOSKEW)
{ {
@ -2267,6 +2272,9 @@ static void R_AddOverlayTextures(sector_t *sec_front, sector_t *sec_back, fixed_
rw_overlay[i].mid = FixedMul(rw_overlay[i].mid, abs(rw_overlay[i].scaley)); rw_overlay[i].mid = FixedMul(rw_overlay[i].mid, abs(rw_overlay[i].scaley));
rw_overlay[i].back = FixedMul(rw_overlay[i].back, abs(rw_overlay[i].scaley)); rw_overlay[i].back = FixedMul(rw_overlay[i].back, abs(rw_overlay[i].scaley));
rw_overlay[i].slide = FixedMul(rw_overlay[i].slide, abs(rw_overlay[i].scaley));
rw_overlay[i].backslide = FixedMul(rw_overlay[i].backslide, abs(rw_overlay[i].scaley));
rw_overlay[i].mid += sidedef->rowoffset + rw_overlay[i].offsety; rw_overlay[i].mid += sidedef->rowoffset + rw_overlay[i].offsety;
rw_overlay[i].back += sidedef->rowoffset + rw_overlay[i].offsety; rw_overlay[i].back += sidedef->rowoffset + rw_overlay[i].offsety;
} }
@ -2304,13 +2312,13 @@ static void R_StoreOverlayColumn(INT32 x, fixed_t textureoffset)
if (rw_overlay[i].scalex < 0) if (rw_overlay[i].scalex < 0)
offset = -offset; offset = -offset;
overlaycolumn[i] = FixedDiv(textureoffset, rw_overlay[i].invscaley); overlaycolumn[i] = textureoffset;
overlaytexturecol[i][x] = FixedDiv(textureoffset, rw_overlay[i].invscalex) + offset; overlaytexturecol[i][x] = FixedDiv(textureoffset, rw_overlay[i].invscalex) + offset;
if (oldoverlaycolumn[i] != -1) if (oldoverlaycolumn[i] != -1)
{ {
INT32 diff = oldoverlaycolumn[i]-overlaycolumn[i]; INT32 diff = oldoverlaycolumn[i]-overlaycolumn[i];
if (rw_overlay[i].scalex < 0) if (rw_overlay[i].invscalex < 0)
diff = -diff; diff = -diff;
rw_overlay[i].mid += FixedMul(rw_overlay[i].slide, diff); rw_overlay[i].mid += FixedMul(rw_overlay[i].slide, diff);
rw_overlay[i].back += FixedMul(rw_overlay[i].backslide, diff); rw_overlay[i].back += FixedMul(rw_overlay[i].backslide, diff);
@ -2320,25 +2328,62 @@ static void R_StoreOverlayColumn(INT32 x, fixed_t textureoffset)
} }
} }
static void R_RenderSingleOverlayTexture(unsigned which, drawseg_t *ds, INT32 x1, INT32 x2, sector_t *sec_front, sector_t *sec_back, UINT32 blendmode, UINT8 blendlevel)
{
if (!overlaytexture[which])
return;
INT32 repeats = R_GetOverlayTextureRepeats(which, sidedef, overlaytexture[which],
sec_front, sec_back,
ds->leftpos.x, ds->leftpos.y, ds->rightpos.x, ds->rightpos.y);
if (sidedef->overlays[which].flags & SIDEOVERLAYFLAG_NOCLIP)
{
mfloorclip = ds->sprbottomclip;
mceilingclip = ds->sprtopclip;
}
else
{
mfloorclip = overlayopening[1];
mceilingclip = overlayopening[0];
}
R_RenderExtraTexture(which, x1, x2, repeats, blendmode, blendlevel, ds);
}
static void R_RenderMaskedOverlayTextures(drawseg_t *ds, INT32 x1, INT32 x2, sector_t *sec_front, sector_t *sec_back, UINT32 blendmode, UINT8 blendlevel) static void R_RenderMaskedOverlayTextures(drawseg_t *ds, INT32 x1, INT32 x2, sector_t *sec_front, sector_t *sec_back, UINT32 blendmode, UINT8 blendlevel)
{ {
INT32 repeats; R_RenderSingleOverlayTexture(EDGE_TEXTURE_TOP_UPPER, ds, x1, x2, sec_front, sec_back, blendmode, blendlevel);
R_RenderSingleOverlayTexture(EDGE_TEXTURE_BOTTOM_LOWER, ds, x1, x2, sec_front, sec_back, blendmode, blendlevel);
}
if (overlaytexture[EDGE_TEXTURE_TOP_UPPER]) //
{ // R_ScaleFromGlobalAngle
repeats = R_GetOverlayTextureRepeats(EDGE_TEXTURE_TOP_UPPER, sidedef, overlaytexture[EDGE_TEXTURE_TOP_UPPER], // Returns the texture mapping scale for the current line (horizontal span)
sec_front, sec_back, // at the given angle.
ds->leftpos.x, ds->leftpos.y, ds->rightpos.x, ds->rightpos.y); // rw_distance must be calculated first.
R_RenderExtraTexture(EDGE_TEXTURE_TOP_UPPER, x1, x2, repeats, blendmode, blendlevel, ds); //
} // 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 (overlaytexture[EDGE_TEXTURE_BOTTOM_LOWER]) if (den > num>>16)
{ {
repeats = R_GetOverlayTextureRepeats(EDGE_TEXTURE_BOTTOM_LOWER, sidedef, overlaytexture[EDGE_TEXTURE_BOTTOM_LOWER], num = FixedDiv(num, den);
sec_front, sec_back, if (num > 64*FRACUNIT)
ds->leftpos.x, ds->leftpos.y, ds->rightpos.x, ds->rightpos.y); return 64*FRACUNIT;
R_RenderExtraTexture(EDGE_TEXTURE_BOTTOM_LOWER, x1, x2, repeats, blendmode, blendlevel, ds); if (num < 256)
return 256;
return num;
} }
return 64*FRACUNIT;
} }
// //
@ -2555,16 +2600,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); angle_t lineangle = R_PointToAngle2(curline->v1->x, curline->v1->y, curline->v2->x, curline->v2->y);
if (frontsector->f_slope) 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) 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) if (backsector)
floorbackslide = FixedMul(backsector->f_slope->zdelta, FINECOSINE((lineangle-backsector->f_slope->xydirection)>>ANGLETOFINESHIFT)); {
if (backsector->f_slope)
floorbackslide = R_GetSlopeTextureSlide(backsector->f_slope, lineangle);
if (backsector && backsector->c_slope) if (backsector->c_slope)
ceilingbackslide = FixedMul(backsector->c_slope->zdelta, FINECOSINE((lineangle-backsector->c_slope->xydirection)>>ANGLETOFINESHIFT)); ceilingbackslide = R_GetSlopeTextureSlide(backsector->c_slope, lineangle);
}
} }
rw_midtexturescalex = sidedef->scalex_mid; rw_midtexturescalex = sidedef->scalex_mid;
@ -2594,13 +2642,13 @@ void R_StoreWallRange(INT32 start, INT32 stop)
else if (linedef->flags & ML_DONTPEGBOTTOM) else if (linedef->flags & ML_DONTPEGBOTTOM)
{ {
rw_midtexturemid = FixedMul(worldbottom, scaley) + texheight; rw_midtexturemid = FixedMul(worldbottom, scaley) + texheight;
rw_midtextureslide = floorfrontslide; rw_midtextureslide = FixedMul(floorfrontslide, scaley);
} }
else else
{ {
// top of texture at top // top of texture at top
rw_midtexturemid = FixedMul(worldtop, scaley); rw_midtexturemid = FixedMul(worldtop, scaley);
rw_midtextureslide = ceilingfrontslide; rw_midtextureslide = FixedMul(ceilingfrontslide, scaley);
} }
} }
else else
@ -2618,13 +2666,13 @@ void R_StoreWallRange(INT32 start, INT32 stop)
else if (linedef->flags & ML_DONTPEGBOTTOM) else if (linedef->flags & ML_DONTPEGBOTTOM)
{ {
rw_midtexturemid = FixedMul(worldbottom, scaley); rw_midtexturemid = FixedMul(worldbottom, scaley);
rw_midtextureslide = floorfrontslide; rw_midtextureslide = FixedMul(floorfrontslide, scaley);
} }
else else
{ {
// top of texture at top // top of texture at top
rw_midtexturemid = FixedMul(worldtop, scaley) + texheight; rw_midtexturemid = FixedMul(worldtop, scaley) + texheight;
rw_midtextureslide = ceilingfrontslide; rw_midtextureslide = FixedMul(ceilingfrontslide, scaley);
} }
} }
@ -2833,15 +2881,16 @@ void R_StoreWallRange(INT32 start, INT32 stop)
{ {
// top of texture at top // top of texture at top
rw_toptexturemid = worldtop; rw_toptexturemid = worldtop;
rw_toptextureslide = ceilingfrontslide; rw_toptextureslide = FixedMul(ceilingfrontslide, abs(rw_toptexturescaley));
} }
else else
{ {
rw_toptexturemid = worldhigh + texheight; rw_toptexturemid = worldhigh + texheight;
rw_toptextureslide = ceilingbackslide; rw_toptextureslide = FixedMul(ceilingbackslide, abs(rw_toptexturescaley));
} }
rw_toptexturemid = FixedMul(rw_toptexturemid, abs(rw_toptexturescaley)); rw_toptexturemid = FixedMul(rw_toptexturemid, abs(rw_toptexturescaley));
rw_toptexturemid += toprowoffset;
} }
// check BOTTOM TEXTURE // check BOTTOM TEXTURE
@ -2872,20 +2921,18 @@ void R_StoreWallRange(INT32 start, INT32 stop)
// bottom of texture at bottom // bottom of texture at bottom
// top of texture at top // top of texture at top
rw_bottomtexturemid = worldbottom; rw_bottomtexturemid = worldbottom;
rw_bottomtextureslide = floorfrontslide; rw_bottomtextureslide = FixedMul(floorfrontslide, abs(rw_bottomtexturescaley));
} }
else else
{ {
// top of texture at top // top of texture at top
rw_bottomtexturemid = worldlow; rw_bottomtexturemid = worldlow;
rw_bottomtextureslide = floorbackslide; rw_bottomtextureslide = FixedMul(floorbackslide, abs(rw_bottomtexturescaley));
} }
rw_bottomtexturemid = FixedMul(rw_bottomtexturemid, abs(rw_bottomtexturescaley)); rw_bottomtexturemid = FixedMul(rw_bottomtexturemid, abs(rw_bottomtexturescaley));
}
rw_toptexturemid += toprowoffset;
rw_bottomtexturemid += botrowoffset; rw_bottomtexturemid += botrowoffset;
}
// allocate space for masked texture tables // allocate space for masked texture tables
R_AllocTextureColumnTables(rw_stopx - start); R_AllocTextureColumnTables(rw_stopx - start);
@ -3136,6 +3183,9 @@ void R_StoreWallRange(INT32 start, INT32 stop)
rw_midtexturemid = FixedMul(rw_midtexturemid, abs(rw_midtexturescaley)); rw_midtexturemid = FixedMul(rw_midtexturemid, abs(rw_midtexturescaley));
rw_midtextureback = FixedMul(rw_midtextureback, 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_midtexturemid += sidedef->rowoffset + sidedef->offsety_mid;
rw_midtextureback += sidedef->rowoffset + sidedef->offsety_mid; rw_midtextureback += sidedef->rowoffset + sidedef->offsety_mid;
} }
@ -3686,6 +3736,9 @@ void R_StoreWallRange(INT32 start, INT32 stop)
// Render up to four extra textures when everything is done // Render up to four extra textures when everything is done
if (hasoverlaytexture) if (hasoverlaytexture)
{ {
mfloorclip = overlayopening[1];
mceilingclip = overlayopening[0];
for (i = 0; i < NUM_WALL_OVERLAYS; i++) for (i = 0; i < NUM_WALL_OVERLAYS; i++)
{ {
if (overlaytexture[i]) if (overlaytexture[i])

View file

@ -2752,6 +2752,66 @@ static void R_SortVisSprites(vissprite_t* vsprsortedhead, UINT32 start, UINT32 e
} }
} }
static fixed_t R_GetHighestSidedefTexture(side_t *side)
{
fixed_t highest = INT32_MIN;
for (unsigned i = 0; i < NUM_WALL_OVERLAYS; i++)
{
INT32 texnum = R_GetTextureNum(side->overlays[i].texture);
if (texnum <= 0 || texnum >= numtextures)
continue;
fixed_t high = side->rowoffset + side->overlays[i].offsety;
if (high > highest)
highest = high;
}
if (highest <= 0)
return 0;
return highest;
}
static fixed_t R_GetLowestSidedefTexture(side_t *side)
{
fixed_t lowest = INT32_MIN;
for (unsigned i = 0; i < NUM_WALL_OVERLAYS; i++)
{
INT32 texnum = R_GetTextureNum(side->overlays[i].texture);
if (texnum <= 0 || texnum >= numtextures)
continue;
fixed_t low = side->rowoffset + side->overlays[i].offsety + FixedMul(textureheight[texnum], FixedDiv(FRACUNIT, abs(side->overlays[i].scaley)));
if (low > lowest)
lowest = low;
}
if (lowest <= 0)
return 0;
return lowest;
}
static fixed_t R_GetFFloorTopZAt(const drawseg_t *ds, const ffloor_t *pfloor, fixed_t x, fixed_t y)
{
side_t *side = R_GetFFloorSide(ds->curline, pfloor);
if (side->flags & SIDEFLAG_HASEDGETEXTURES)
return P_GetFFloorTopZAt(pfloor, x, y) + R_GetHighestSidedefTexture(side);
return P_GetFFloorTopZAt(pfloor, x, y);
}
static fixed_t R_GetFFloorBottomZAt(const drawseg_t *ds, const ffloor_t *pfloor, fixed_t x, fixed_t y)
{
side_t *side = R_GetFFloorSide(ds->curline, pfloor);
if (side->flags & SIDEFLAG_HASEDGETEXTURES)
return P_GetFFloorBottomZAt(pfloor, x, y) - R_GetLowestSidedefTexture(side);
return P_GetFFloorBottomZAt(pfloor, x, y);
}
// //
// R_CreateDrawNodes // R_CreateDrawNodes
// Creates and sorts a list of drawnodes for the scene being rendered. // Creates and sorts a list of drawnodes for the scene being rendered.
@ -2950,10 +3010,10 @@ static void R_CreateDrawNodes(maskcount_t* mask, drawnode_t* head, boolean temps
if (scale <= rover->sortscale) if (scale <= rover->sortscale)
continue; continue;
topplaneobjectz = P_GetFFloorTopZAt (r2->ffloor, rover->gx, rover->gy); topplaneobjectz = R_GetFFloorTopZAt (r2->thickseg, r2->ffloor, rover->gx, rover->gy);
topplanecameraz = P_GetFFloorTopZAt (r2->ffloor, viewx, viewy); topplanecameraz = R_GetFFloorTopZAt (r2->thickseg, r2->ffloor, viewx, viewy);
botplaneobjectz = P_GetFFloorBottomZAt(r2->ffloor, rover->gx, rover->gy); botplaneobjectz = R_GetFFloorBottomZAt(r2->thickseg, r2->ffloor, rover->gx, rover->gy);
botplanecameraz = P_GetFFloorBottomZAt(r2->ffloor, viewx, viewy); botplanecameraz = R_GetFFloorBottomZAt(r2->thickseg, r2->ffloor, viewx, viewy);
if ((topplanecameraz > viewz && botplanecameraz < viewz) || if ((topplanecameraz > viewz && botplanecameraz < viewz) ||
(topplanecameraz < viewz && rover->gzt < topplaneobjectz) || (topplanecameraz < viewz && rover->gzt < topplaneobjectz) ||