diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index b703c10d1..5598e0a4c 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -1198,12 +1198,12 @@ static void HWR_RenderMidtexture(INT32 gl_midtexture, float cliplow, float cliph // 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; + 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->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 // 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; #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; \ 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) \ { \ lowcut = worldbottom; \ @@ -1762,12 +1774,12 @@ static void HWR_RenderExtraTexture(unsigned which, side_t *side, sector_t *sec_f // Left side wallVerts[3].t = 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 wallVerts[2].t = 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 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 wallVerts[3].t = 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 wallVerts[2].t = 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(); @@ -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) { - side_t *pside = &sides[pfloor->master->sidenum[0]]; + side_t *pside = R_GetFFloorSide(gl_curline, pfloor); sector_t *psector = pfloor->master->frontsector; 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; // 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); UINT32 lightnum = HWR_CalcWallLight(gl_frontsector->lightlevel, vs.x, vs.y, ve.x, ve.y); 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)); 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 right = cliphigh * xscale; @@ -2024,15 +2035,17 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom 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 + // 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; @@ -2042,7 +2055,7 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom 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; @@ -2103,7 +2116,7 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom xscale = FixedToFloat(abs(gl_sidedef->scalex_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 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[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) { @@ -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 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); @@ -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)) 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; } @@ -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[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; @@ -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)) 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); @@ -2557,17 +2577,43 @@ 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; diff --git a/src/lua_maplib.c b/src/lua_maplib.c index ea714ba7a..d2a856960 100644 --- a/src/lua_maplib.c +++ b/src/lua_maplib.c @@ -1462,6 +1462,7 @@ enum sideoverlay_e { sideoverlay_scalex, sideoverlay_scaley, sideoverlay_noskew, + sideoverlay_noclip, sideoverlay_wrap }; @@ -1473,6 +1474,7 @@ static const char *const sideoverlay_opt[] = { "scalex", "scaley", "noskew", + "noclip", "wrap", NULL}; @@ -1515,6 +1517,9 @@ static int sideoverlay_get(lua_State *L) case sideoverlay_noskew: lua_pushboolean(L, overlay->flags & SIDEOVERLAYFLAG_NOSKEW); return 1; + case sideoverlay_noclip: + lua_pushboolean(L, overlay->flags & SIDEOVERLAYFLAG_NOCLIP); + return 1; case sideoverlay_wrap: lua_pushboolean(L, overlay->flags & SIDEOVERLAYFLAG_WRAP); 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)); case sideoverlay_texture: overlay->texture = luaL_checkinteger(L, 3); + if (overlay->texture) + overlay->side->flags |= SIDEFLAG_HASEDGETEXTURES; break; case sideoverlay_offsetx: overlay->offsetx = luaL_checkfixed(L, 3); @@ -1563,6 +1570,12 @@ static int sideoverlay_set(lua_State *L) else overlay->flags &= ~SIDEOVERLAYFLAG_NOSKEW; break; + case sideoverlay_noclip: + if (luaL_checkboolean(L, 3)) + overlay->flags |= SIDEOVERLAYFLAG_NOCLIP; + else + overlay->flags &= ~SIDEOVERLAYFLAG_NOCLIP; + break; case sideoverlay_wrap: if (luaL_checkboolean(L, 3)) overlay->flags |= SIDEOVERLAYFLAG_WRAP; diff --git a/src/p_saveg.c b/src/p_saveg.c index 7c0bfa1e1..5eb3cdca9 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -1428,6 +1428,8 @@ static UINT32 GetSideDiff(const side_t *si, const side_t *spawnsi, UINT8 edgedif diff |= LD_SDBOTSCALEY; if (si->repeatcnt != spawnsi->repeatcnt) diff |= LD_SDREPEATCNT; + if (si->flags != spawnsi->flags) + diff |= LD_SDFLAGS; if (edgediff[0] != 0) diff |= LD_SDOVERLAY1; 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); if (diff & LD_SDREPEATCNT) WRITEINT16(save_p, si->repeatcnt); + if (diff & LD_SDFLAGS) + WRITEUINT16(save_p, si->flags); if (diff & LD_SDOVERLAY1) ArchiveSideEdge(&si->overlays[0], edgediff[0]); if (diff & LD_SDOVERLAY2) @@ -1672,6 +1676,8 @@ static void UnArchiveSide(side_t *si) si->scaley_bottom = READFIXED(save_p); if (diff & LD_SDREPEATCNT) si->repeatcnt = READINT16(save_p); + if (diff & LD_SDFLAGS) + si->flags = READUINT16(save_p); if (diff & LD_SDOVERLAY1) UnArchiveSideEdge(&si->overlays[0]); if (diff & LD_SDOVERLAY2) diff --git a/src/p_setup.c b/src/p_setup.c index d2a70c89b..c0ee12524 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1331,6 +1331,18 @@ static void P_WriteTics(INT32 tics, char **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) { 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->scaley_top = sd->scaley_mid = sd->scaley_bottom = FRACUNIT; - 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; - } + P_InitSideEdges(sd); 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]; if (fastcmp(param, "texture")) + { overlay->texture = R_TextureNumForName(val); + if (overlay->texture) + sides[i].flags |= SIDEFLAG_HASEDGETEXTURES; + } else if (fastcmp(param, "offsetx")) overlay->offsetx = FLOAT_TO_FIXED(atof(val)); 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)); else if (fastcmp(param, "noskew") && fastcmp("true", val)) overlay->flags |= SIDEOVERLAYFLAG_NOSKEW; + else if (fastcmp(param, "noclip") && fastcmp("true", val)) + overlay->flags |= SIDEOVERLAYFLAG_NOCLIP; else if (fastcmp(param, "wrap") && fastcmp("true", val)) 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)); if (side->overlays[i].flags & SIDEOVERLAYFLAG_NOSKEW) 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) fprintf(f, "%s""wrap = true;\n", prefix); } @@ -3105,16 +3119,11 @@ static void P_LoadTextmap(void) sd->toptexture = R_TextureNumForName("-"); sd->midtexture = 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->repeatcnt = 0; + P_InitSideEdges(sd); + TextmapParse(sidesPos[i], i, ParseTextmapSidedefParameter); if (!sd->sector) @@ -3407,8 +3416,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; } diff --git a/src/r_defs.h b/src/r_defs.h index 91abbc47c..2d5a05b37 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -610,10 +610,16 @@ typedef struct line_s } line_t; // Don't make available to Lua or I will find where you live +typedef enum +{ + SIDEFLAG_HASEDGETEXTURES = 1 +} sideflags_t; + enum { SIDEOVERLAYFLAG_NOSKEW = 1<<0, - SIDEOVERLAYFLAG_WRAP = 1<<1 + SIDEOVERLAYFLAG_NOCLIP = 1<<1, + SIDEOVERLAYFLAG_WRAP = 1<<2 }; typedef struct @@ -622,9 +628,10 @@ typedef struct fixed_t offsetx, offsety; fixed_t scalex, scaley; UINT8 flags; + struct side_s *side; } side_overlay_t; -typedef struct +typedef struct side_s { // add this to the calculated texture column fixed_t textureoffset; @@ -632,13 +639,16 @@ typedef struct // add this to the calculated texture top fixed_t rowoffset; - // per-texture offsets for UDMF + // per-texture offsets fixed_t offsetx_top, offsetx_mid, offsetx_bottom; fixed_t offsety_top, offsety_mid, offsety_bottom; + // per-texture scale fixed_t scalex_top, scalex_mid, scalex_bottom; fixed_t scaley_top, scaley_mid, scaley_bottom; + UINT16 flags; + // Texture indices. // We do not maintain names here. INT32 toptexture, bottomtexture, midtexture; @@ -766,9 +776,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; diff --git a/src/r_main.c b/src/r_main.c index aaab234ad..eb4101bc2 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -407,33 +407,26 @@ angle_t R_PointToAngleEx(INT32 x2, INT32 y2, INT32 x1, INT32 y1) 0; } -// -// 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) +line_t *R_GetFFloorLine(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; + size_t linenum = seg->linedef - pfloor->target->lines[0]; + return pfloor->master->frontsector->lines[0] + linenum; } - 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]]; } // diff --git a/src/r_main.h b/src/r_main.h index c7dc06c90..77248babc 100644 --- a/src/r_main.h +++ b/src/r_main.h @@ -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_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 diff --git a/src/r_segs.c b/src/r_segs.c index e2be6aed0..23a34f27b 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -64,7 +64,7 @@ static struct fixed_t mid, slide; fixed_t back, backslide; fixed_t scalex, scaley; - fixed_t invscalex, invscaley; + fixed_t invscalex; fixed_t offsetx, offsety; } rw_overlay[NUM_WALL_OVERLAYS]; @@ -617,9 +617,6 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) else dc_texturemid -= (textureheight[texnum])*times; - if (hasoverlaytexture && times == 0) - R_DoMaskedOverlayColumn(dc_x, maskedtexturecol[dc_x], INT32_MAX, INT32_MAX); - // Check for overflows first overflow_test = (INT64)centeryfrac - (((INT64)dc_texturemid*spryscale)>>FRACBITS); 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); + 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 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. R_PrepareMaskedSegLightlist(ds, range); - mfloorclip = overlayopening[1]; - mceilingclip = overlayopening[0]; - for (times = 0; times < repeats; times++) { if (times > 0) @@ -1025,6 +1022,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. @@ -1050,11 +1052,12 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) // skew FOF walls with slopes? fixed_t ffloortextureslide = 0, topslopeslide = 0, bottomslopeslide = 0; angle_t lineangle; - 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; INT32 blendlevel = 0; UINT8 vertflip; @@ -1069,15 +1072,13 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) curline = ds->curline; backsector = NULL; 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-pfloor->target->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; } @@ -1248,15 +1249,17 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) 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; @@ -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); if (skewslope) - ffloortextureslide = FixedMul(skewslope->zdelta, FINECOSINE((lineangle-skewslope->xydirection)>>ANGLETOFINESHIFT)); + ffloortextureslide = FixedMul(R_GetSlopeTextureSlide(skewslope, lineangle), wall_scaley); dc_texturemid += offsetvalue; @@ -1348,9 +1351,9 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) if (hasoverlaytexture) { 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) - 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); @@ -1364,9 +1367,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 @@ -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); // 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 // will (hopefully) put less strain on the stack. @@ -1939,8 +1942,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; @@ -1985,8 +1988,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; @@ -2010,14 +2013,14 @@ static void R_RenderSegLoop (void) { if (oldtexturecolumn != -1) { - INT32 diff = 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 (hasoverlaytexture) @@ -2167,6 +2170,9 @@ static void R_AllocTextureColumnTables(size_t range) static boolean R_CheckExtraTextures(boolean onesided) { + if (!(sidedef->flags & SIDEFLAG_HASEDGETEXTURES)) + return false; + INT32 texnums[4] = { R_GetTextureNum(sidedef->overlays[0].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].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) { @@ -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].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].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) offset = -offset; - overlaycolumn[i] = FixedDiv(textureoffset, rw_overlay[i].invscaley); + overlaycolumn[i] = textureoffset; overlaytexturecol[i][x] = FixedDiv(textureoffset, rw_overlay[i].invscalex) + offset; if (oldoverlaycolumn[i] != -1) { INT32 diff = oldoverlaycolumn[i]-overlaycolumn[i]; - if (rw_overlay[i].scalex < 0) + if (rw_overlay[i].invscalex < 0) diff = -diff; rw_overlay[i].mid += FixedMul(rw_overlay[i].slide, 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) { - 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]) - { - repeats = R_GetOverlayTextureRepeats(EDGE_TEXTURE_TOP_UPPER, sidedef, overlaytexture[EDGE_TEXTURE_TOP_UPPER], - sec_front, sec_back, - ds->leftpos.x, ds->leftpos.y, ds->rightpos.x, ds->rightpos.y); - R_RenderExtraTexture(EDGE_TEXTURE_TOP_UPPER, x1, x2, repeats, blendmode, blendlevel, ds); - } +// +// 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 (overlaytexture[EDGE_TEXTURE_BOTTOM_LOWER]) + if (den > num>>16) { - repeats = R_GetOverlayTextureRepeats(EDGE_TEXTURE_BOTTOM_LOWER, sidedef, overlaytexture[EDGE_TEXTURE_BOTTOM_LOWER], - sec_front, sec_back, - ds->leftpos.x, ds->leftpos.y, ds->rightpos.x, ds->rightpos.y); - R_RenderExtraTexture(EDGE_TEXTURE_BOTTOM_LOWER, x1, x2, repeats, blendmode, blendlevel, ds); + num = FixedDiv(num, den); + if (num > 64*FRACUNIT) + return 64*FRACUNIT; + 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); 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; @@ -2594,13 +2642,13 @@ void R_StoreWallRange(INT32 start, INT32 stop) else if (linedef->flags & ML_DONTPEGBOTTOM) { rw_midtexturemid = FixedMul(worldbottom, scaley) + texheight; - rw_midtextureslide = floorfrontslide; + rw_midtextureslide = FixedMul(floorfrontslide, scaley); } else { // top of texture at top rw_midtexturemid = FixedMul(worldtop, scaley); - rw_midtextureslide = ceilingfrontslide; + rw_midtextureslide = FixedMul(ceilingfrontslide, scaley); } } else @@ -2618,13 +2666,13 @@ void R_StoreWallRange(INT32 start, INT32 stop) else if (linedef->flags & ML_DONTPEGBOTTOM) { rw_midtexturemid = FixedMul(worldbottom, scaley); - rw_midtextureslide = floorfrontslide; + rw_midtextureslide = FixedMul(floorfrontslide, scaley); } else { // top of texture at top 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 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, abs(rw_toptexturescaley)); + rw_toptexturemid += toprowoffset; } // check BOTTOM TEXTURE @@ -2872,21 +2921,19 @@ 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, abs(rw_bottomtexturescaley)); + rw_bottomtexturemid += botrowoffset; } - rw_toptexturemid += toprowoffset; - rw_bottomtexturemid += botrowoffset; - // allocate space for masked texture tables 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_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; } @@ -3686,6 +3736,9 @@ void R_StoreWallRange(INT32 start, INT32 stop) // Render up to four extra textures when everything is done if (hasoverlaytexture) { + mfloorclip = overlayopening[1]; + mceilingclip = overlayopening[0]; + for (i = 0; i < NUM_WALL_OVERLAYS; i++) { if (overlaytexture[i]) diff --git a/src/r_things.c b/src/r_things.c index 5bccea032..e7d162d61 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -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 // 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) continue; - topplaneobjectz = P_GetFFloorTopZAt (r2->ffloor, rover->gx, rover->gy); - topplanecameraz = P_GetFFloorTopZAt (r2->ffloor, viewx, viewy); - botplaneobjectz = P_GetFFloorBottomZAt(r2->ffloor, rover->gx, rover->gy); - botplanecameraz = P_GetFFloorBottomZAt(r2->ffloor, viewx, viewy); + topplaneobjectz = R_GetFFloorTopZAt (r2->thickseg, r2->ffloor, rover->gx, rover->gy); + topplanecameraz = R_GetFFloorTopZAt (r2->thickseg, r2->ffloor, viewx, viewy); + botplaneobjectz = R_GetFFloorBottomZAt(r2->thickseg, r2->ffloor, rover->gx, rover->gy); + botplanecameraz = R_GetFFloorBottomZAt(r2->thickseg, r2->ffloor, viewx, viewy); if ((topplanecameraz > viewz && botplanecameraz < viewz) || (topplanecameraz < viewz && rover->gzt < topplaneobjectz) ||