From f09950ddd5eb7657c446e19e812358b99d7697ae Mon Sep 17 00:00:00 2001 From: Ashnal Date: Mon, 20 Oct 2025 23:33:28 +0000 Subject: [PATCH] Tripwire texture swap --- src/doomtype.h | 1 + src/hardware/hw_main.c | 43 ++++++++++++++++++++++++++++++++++++------ src/p_map.c | 1 + src/p_setup.cpp | 13 +++++++++++++ src/r_bsp.cpp | 7 +++++++ src/r_bsp.h | 1 + src/r_segs.cpp | 14 +++++++++++--- 7 files changed, 71 insertions(+), 9 deletions(-) diff --git a/src/doomtype.h b/src/doomtype.h index 670d4b9b3..4c661a662 100644 --- a/src/doomtype.h +++ b/src/doomtype.h @@ -239,6 +239,7 @@ enum {false = 0, true = 1}; #endif #define ATTRUNUSED __attribute__((unused)) + #define ATTRUNOPTIMIZE __attribute__((optimize("O0"))) #elif defined (_MSC_VER) #define ATTRNORETURN __declspec(noreturn) #define ATTRINLINE __forceinline diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 232082bbc..b5e8fca5a 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -1386,8 +1386,18 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom grTex = HWR_GetTexture(gl_midtexture, gl_sidedef->midtexture); - wallVerts[3].t = wallVerts[2].t = texturevpeg * grTex->scaleY; - wallVerts[0].t = wallVerts[1].t = (h - l + texturevpeg) * grTex->scaleY; + // Check if we should flip tripwire texture vertically for unpegged tripwires + if (R_ShouldFlipTripWire(gl_linedef)) + { + // Flip texture coordinates vertically + wallVerts[0].t = wallVerts[1].t = texturevpeg * grTex->scaleY; + wallVerts[3].t = wallVerts[2].t = (h - l + texturevpeg) * grTex->scaleY; + } + else + { + wallVerts[3].t = wallVerts[2].t = texturevpeg * grTex->scaleY; + wallVerts[0].t = wallVerts[1].t = (h - l + texturevpeg) * grTex->scaleY; + } wallVerts[0].s = wallVerts[3].s = cliplow * grTex->scaleX; wallVerts[2].s = wallVerts[1].s = cliphigh * grTex->scaleX; } @@ -1433,8 +1443,19 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom texturevpeg = textureheight[gl_sidedef->midtexture]*repeats - h + polybottom; else texturevpeg = polytop - h; - wallVerts[2].t = texturevpeg * grTex->scaleY; - wallVerts[1].t = (h - l + texturevpeg) * grTex->scaleY; + + // Apply tripwire flipping for slope correction as well + if (R_ShouldFlipTripWire(gl_linedef)) + { + // Flip texture coordinates vertically + wallVerts[1].t = texturevpeg * grTex->scaleY; + wallVerts[2].t = (h - l + texturevpeg) * grTex->scaleY; + } + else + { + wallVerts[2].t = texturevpeg * grTex->scaleY; + wallVerts[1].t = (h - l + texturevpeg) * grTex->scaleY; + } } wallVerts[2].y = FIXED_TO_FLOAT(h); @@ -1531,8 +1552,18 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom grTex = HWR_GetTexture(gl_midtexture, gl_sidedef->midtexture); - wallVerts[3].t = wallVerts[2].t = texturevpeg * grTex->scaleY; - wallVerts[0].t = wallVerts[1].t = (texturevpeg + gl_frontsector->ceilingheight - gl_frontsector->floorheight) * grTex->scaleY; + // Check if we should flip tripwire texture vertically for single-sided lines too + if (R_ShouldFlipTripWire(gl_linedef)) + { + // Flip texture coordinates vertically + wallVerts[0].t = wallVerts[1].t = texturevpeg * grTex->scaleY; + wallVerts[3].t = wallVerts[2].t = (texturevpeg + gl_frontsector->ceilingheight - gl_frontsector->floorheight) * grTex->scaleY; + } + else + { + wallVerts[3].t = wallVerts[2].t = texturevpeg * grTex->scaleY; + wallVerts[0].t = wallVerts[1].t = (texturevpeg + gl_frontsector->ceilingheight - gl_frontsector->floorheight) * grTex->scaleY; + } wallVerts[0].s = wallVerts[3].s = cliplow * grTex->scaleX; wallVerts[2].s = wallVerts[1].s = cliphigh * grTex->scaleX; diff --git a/src/p_map.c b/src/p_map.c index 00336754a..9b1d835d3 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -1856,6 +1856,7 @@ boolean P_IsLineTripWire(const line_t *ld) return ld->tripwire; } + static boolean P_UsingStepUp(mobj_t *thing) { if (thing->flags & MF_NOCLIP) diff --git a/src/p_setup.cpp b/src/p_setup.cpp index e3f6824c5..5003ac354 100644 --- a/src/p_setup.cpp +++ b/src/p_setup.cpp @@ -3375,6 +3375,19 @@ static boolean P_CheckLineSideTripWire(line_t *ld, int p) terrain = K_GetTerrainForTextureNum(sda->midtexture); tripwire = terrain && (terrain->flags & TRF_TRIPWIRE); + // If we are texture TRIPWIRE and have the ML_MIDTEXINVISWALL, the replace texture with TRIPWLOW + if (tripwire && (ld->flags & ML_MIDTEXINVISWALL)) // if we do backwards compat, update this to also swap for older custom maps without the flag + { + if (sda->midtexture == R_TextureNumForName("TRIPWIRE")) + { + sda->midtexture = R_TextureNumForName("TRIPWLOW"); + } + else if (sda->midtexture == R_TextureNumForName("4RIPWIRE")) + { + sda->midtexture = R_TextureNumForName("4RIPWLOW"); + } + } + if (tripwire) { // copy midtexture to other side diff --git a/src/r_bsp.cpp b/src/r_bsp.cpp index 73474d1f8..5952d94fc 100644 --- a/src/r_bsp.cpp +++ b/src/r_bsp.cpp @@ -429,6 +429,13 @@ boolean R_IsDebugLine(seg_t *line) return false; } +boolean R_ShouldFlipTripWire(const line_t *ld) +{ + // Flip tripwire textures when they are unpegged + // so the energy flows downward instead of upward, matching collision behavior + return (ld->tripwire && !(ld->flags & ML_MIDPEG)); +} + // // R_AddLine // Clips the given segment and adds any visible pieces to the line list. diff --git a/src/r_bsp.h b/src/r_bsp.h index 6c2848ef0..e784d7d30 100644 --- a/src/r_bsp.h +++ b/src/r_bsp.h @@ -61,6 +61,7 @@ sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec, INT32 *floorlightlevel, INT32 *ceilinglightlevel, boolean back); boolean R_IsEmptyLine(seg_t *line, sector_t *front, sector_t *back); boolean R_IsDebugLine(seg_t *line); +boolean R_ShouldFlipTripWire(const line_t *ld); INT32 R_GetPlaneLight(sector_t *sector, fixed_t planeheight, boolean underside); void R_Prep3DFloors(sector_t *sector); diff --git a/src/r_segs.cpp b/src/r_segs.cpp index f863b43b4..6dd45359a 100644 --- a/src/r_segs.cpp +++ b/src/r_segs.cpp @@ -696,7 +696,7 @@ void R_RenderMaskedSegRange(drawseg_t *drawseg, INT32 x1, INT32 x2) // are not stored per-column with post info in SRB2 if (textures[texnum]->holes) { - if (textures[texnum]->flip & 2) // vertically flipped? + if ((textures[texnum]->flip & 2) || R_ShouldFlipTripWire(ldef)) // vertically flipped? { colfunc_2s = R_DrawFlippedMaskedColumn; lengthcol = textures[texnum]->height; @@ -706,8 +706,16 @@ void R_RenderMaskedSegRange(drawseg_t *drawseg, INT32 x1, INT32 x2) } else { - colfunc_2s = R_Render2sidedMultiPatchColumn; // render multipatch with no holes (no post_t info) - lengthcol = textures[texnum]->height; + if (R_ShouldFlipTripWire(ldef)) // Check for tripwire flip even for non-holey textures + { + colfunc_2s = R_DrawFlippedMaskedColumn; + lengthcol = textures[texnum]->height; + } + else + { + colfunc_2s = R_Render2sidedMultiPatchColumn; // render multipatch with no holes (no post_t info) + lengthcol = textures[texnum]->height; + } } maskedtexturecol = drawseg->maskedtexturecol;