diff --git a/src/deh_tables.c b/src/deh_tables.c index fa86518e2..fb4f85926 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -4540,6 +4540,7 @@ const char *const ML_LIST[] = { "EFFECT6", "BOUNCY", "TFERLINE", + "CLIPMIDTEX", NULL }; diff --git a/src/doomdata.h b/src/doomdata.h index b60338cc3..45b9ec1b3 100644 --- a/src/doomdata.h +++ b/src/doomdata.h @@ -146,7 +146,9 @@ enum // Bounce off walls! ML_BOUNCY = 1<<14, - ML_TFERLINE = 1<<15 + ML_TFERLINE = 1<<15, + + ML_CLIPMIDTEX = 1<<16 }; // Sector definition, from editing. diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 706a2415a..b703c10d1 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -1159,10 +1159,20 @@ static void HWR_RenderMidtexture(INT32 gl_midtexture, float cliplow, float cliph } // The cut-off values of a linedef can always be constant, since every line has an absoulute front and or back sector - lowcut = popenbottom; - highcut = popentop; - lowcutslope = popenbottomslope; - highcutslope = popentopslope; + if (gl_curline->polyseg && !(gl_linedef->flags & ML_CLIPMIDTEX)) + { + lowcut = polybottom; + highcut = polytop; + lowcutslope = polybottomslope; + highcutslope = polytopslope; + } + else + { + lowcut = popenbottom; + highcut = popentop; + lowcutslope = popenbottomslope; + highcutslope = popentopslope; + } fixed_t h = min(highcut, polytop); fixed_t l = max(polybottom, lowcut); diff --git a/src/p_saveg.c b/src/p_saveg.c index 4a5b0e484..7c0bfa1e1 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -1571,7 +1571,7 @@ static void ArchiveLines(void) if (diff & LD_DIFF2) WRITEUINT8(save_p, diff2); if (diff & LD_FLAG) - WRITEINT16(save_p, li->flags); + WRITEUINT32(save_p, li->flags); if (diff & LD_SPECIAL) WRITEINT16(save_p, li->special); if (diff & LD_CLLCOUNT) @@ -1705,7 +1705,7 @@ static void UnArchiveLines(void) li = &lines[i]; if (diff & LD_FLAG) - li->flags = READINT16(save_p); + li->flags = READUINT32(save_p); if (diff & LD_SPECIAL) li->special = READINT16(save_p); if (diff & LD_CLLCOUNT) diff --git a/src/p_setup.c b/src/p_setup.c index 9feb4fc7c..d2a70c89b 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1963,8 +1963,7 @@ static void ParseTextmapSidedefParameter(UINT32 i, const char *param, const char P_SetSidedefSector(i, atol(val)); else if (fastcmp(param, "repeatcnt")) sides[i].repeatcnt = atol(val); - // Oh God there's a total of 28 fields to read. Uhhh - // Okay, so ParseTextmapSidedefOverlay handles all the parameters edges have. + // Parse edge fields else if (fastncmp(param, "edge_", 5) && strlen(param) > 5) { if (fastncmp(param, "edge_top_upper_", 15) && strlen(param) > 15) @@ -2058,6 +2057,8 @@ static void ParseTextmapLinedefParameter(UINT32 i, const char *param, const char lines[i].flags |= ML_MIDPEG; else if (fastcmp(param, "midsolid") && fastcmp("true", val)) lines[i].flags |= ML_MIDSOLID; + else if (fastcmp(param, "clipmidtex") && fastcmp("true", val)) + lines[i].flags |= ML_CLIPMIDTEX; else if (fastcmp(param, "wrapmidtex") && fastcmp("true", val)) lines[i].flags |= ML_WRAPMIDTEX; else if (fastcmp(param, "nonet") && fastcmp("true", val)) diff --git a/src/r_defs.h b/src/r_defs.h index f6f770de2..91abbc47c 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -579,8 +579,7 @@ typedef struct line_s fixed_t dx, dy; // Precalculated v2 - v1 for side checking. angle_t angle; // Precalculated angle between dx and dy - // Animation related. - INT16 flags; + UINT32 flags; INT16 special; taglist_t tags; INT32 args[NUMLINEARGS]; diff --git a/src/r_segs.c b/src/r_segs.c index fc244534a..e2be6aed0 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -565,6 +565,33 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) for (times = 0; times < repeats; times++) { + fixed_t left_top = 0, left_bottom = 0; + fixed_t right_top = 0, right_bottom = 0; + fixed_t top_step = 0, bottom_step = 0; + + // Get left and right ends of wall for clipping it + if (ldef->flags & ML_CLIPMIDTEX) + { + // For this to work correctly with polyobjects, it needs to use its own back sector, rather than the seg's front sector + sector_t *sec_front = curline->polyseg ? + curline->polyseg->lines[0]->backsector : + frontsector; + + // calculate both left ends + left_top = P_GetSectorCeilingZAt(sec_front, ds->leftpos.x, ds->leftpos.y) - viewz; + left_bottom = P_GetSectorFloorZAt(sec_front, ds->leftpos.x, ds->leftpos.y) - viewz; + + // calculate right ends now + right_top = P_GetSectorCeilingZAt(sec_front, ds->rightpos.x, ds->rightpos.y) - viewz; + right_bottom = P_GetSectorFloorZAt(sec_front, ds->rightpos.x, ds->rightpos.y) - viewz; + + top_step = (right_top - left_top) / range; + bottom_step = (right_bottom - left_bottom) / range; + + left_top += top_step * (x1 - ds->x1); + left_bottom += bottom_step * (x1 - ds->x1); + } + if (times > 0) { rw_scalestep = scalestep; @@ -585,7 +612,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) { dc_texturemid = ds->maskedtextureheight[dc_x]; - if (curline->linedef->flags & ML_MIDPEG) + if (ldef->flags & ML_MIDPEG) dc_texturemid += (textureheight[texnum])*times + textureheight[texnum]; else dc_texturemid -= (textureheight[texnum])*times; @@ -614,16 +641,18 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) texture_top = dc_texturemid; texture_bottom = texture_top - textureheight[texnum]; - sprtopscreen = centeryfrac - FixedMul(texture_top, spryscale); - - // Clip texture if it's a polyobject side - if (curline->polyseg) + // If the texture is meant to be clipped + if (ldef->flags & ML_CLIPMIDTEX) { - // For this to work correctly, it needs to use the polyobject's sector, rather than the seg's back sector - // Change this when polyobjects support slopes - texture_bottom = max(curline->polyseg->lines[0]->backsector->floorheight - viewz, texture_bottom); + texture_top = min(left_top, texture_top); + texture_bottom = max(left_bottom, texture_bottom); + + left_top += top_step; + left_bottom += bottom_step; } + sprtopscreen = centeryfrac - FixedMul(texture_top, spryscale); + // set wall bounds if there is a light list, or if this is a polyobject side if (dc_numlights || curline->polyseg) {