From d05fed7173143ec7119839d802db417c2323153a Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Mon, 29 Aug 2016 22:42:06 +0100 Subject: [PATCH 1/4] Upper Unpegged on an FOF's control linedef now enables skewing of walls with respect to slopes Skewing direction is decided per in-level wall by the Lower Unpegged flag on in-level linedefs themselves, since they already decide the stuff for FOF wall pegging as it is. That is unless Transfer Line is involved which moves everything to the control sector linedefs instead... --- src/r_segs.c | 73 +++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 64 insertions(+), 9 deletions(-) diff --git a/src/r_segs.c b/src/r_segs.c index 502ff3304..fff98dbf2 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -743,6 +743,12 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) // Render FOF sides kinda like normal sides, with the frac and step and everything // NOTE: INT64 instead of fixed_t because overflow concerns INT64 top_frac, top_step, bottom_frac, bottom_step; + // skew FOF walls with slopes? + boolean slopeskew = false; + fixed_t ffloortextureslide = 0; + INT32 oldx = -1; + fixed_t left_top, left_bottom; // needed here for slope skewing + pslope_t *skewslope = NULL; #endif void (*colfunc_2s) (column_t *); @@ -966,21 +972,68 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) mceilingclip = ds->sprtopclip; dc_texheight = textureheight[texnum]>>FRACBITS; +#ifdef ESLOPE + // calculate both left ends + if (*pfloor->t_slope) + left_top = P_GetZAt(*pfloor->t_slope, ds->leftpos.x, ds->leftpos.y) - viewz; + else + left_top = *pfloor->topheight - viewz; + + if (*pfloor->b_slope) + left_bottom = P_GetZAt(*pfloor->b_slope, ds->leftpos.x, ds->leftpos.y) - viewz; + else + left_bottom = *pfloor->bottomheight - viewz; + dc_texturemid = left_top; + skewslope = *pfloor->t_slope; // skew using top slope by default +#else dc_texturemid = *pfloor->topheight - viewz; +#endif if (newline) { offsetvalue = sides[newline->sidenum[0]].rowoffset; if (newline->flags & ML_DONTPEGBOTTOM) +#ifdef ESLOPE + { + dc_texturemid = left_bottom; + skewslope = *pfloor->b_slope; // skew using bottom slope + } +#else offsetvalue -= *pfloor->topheight - *pfloor->bottomheight; +#endif +#ifdef ESLOPE + if (newline->flags & ML_DONTPEGTOP) + slopeskew = true; +#endif } else { offsetvalue = sides[pfloor->master->sidenum[0]].rowoffset; if (curline->linedef->flags & ML_DONTPEGBOTTOM) +#ifdef ESLOPE + { + dc_texturemid = left_bottom; + skewslope = *pfloor->b_slope; // skew using bottom slope + } +#else offsetvalue -= *pfloor->topheight - *pfloor->bottomheight; +#endif +#ifdef ESLOPE + if (pfloor->master->flags & ML_DONTPEGTOP) // use control linedef's flags + slopeskew = true; +#endif } +#ifdef ESLOPE + if (slopeskew) + { + angle_t 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)); + } +#endif + dc_texturemid += offsetvalue; // Texture must be cached before setting colfunc_2s, @@ -999,23 +1052,18 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) #ifdef ESLOPE // Set heights according to plane, or slope, whichever { - fixed_t left_top, right_top, left_bottom, right_bottom; + fixed_t right_top, right_bottom; + // calculate right ends now if (*pfloor->t_slope) - { - left_top = P_GetZAt(*pfloor->t_slope, ds->leftpos.x, ds->leftpos.y) - viewz; right_top = P_GetZAt(*pfloor->t_slope, ds->rightpos.x, ds->rightpos.y) - viewz; - } else - left_top = right_top = *pfloor->topheight - viewz; + right_top = *pfloor->topheight - viewz; if (*pfloor->b_slope) - { - left_bottom = P_GetZAt(*pfloor->b_slope, ds->leftpos.x, ds->leftpos.y) - viewz; right_bottom = P_GetZAt(*pfloor->b_slope, ds->rightpos.x, ds->rightpos.y) - viewz; - } else - left_bottom = right_bottom = *pfloor->bottomheight - viewz; + right_bottom = *pfloor->bottomheight - viewz; // using INT64 to avoid 32bit overflow top_frac = (INT64)centeryfrac - (((INT64)left_top * ds->scale1) >> FRACBITS); @@ -1039,6 +1087,13 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) { if (maskedtexturecol[dc_x] != INT16_MAX) { +#ifdef ESLOPE + if (ffloortextureslide) { // skew FOF walls + if (oldx != -1) + dc_texturemid += FixedMul(ffloortextureslide, (maskedtexturecol[oldx]-maskedtexturecol[dc_x])< Date: Mon, 29 Aug 2016 23:21:57 +0100 Subject: [PATCH 2/4] If NOT skewing FOF walls, make sure dc_texturemid reverts to using unsloped FOF topheight/bottomheight rather than actual left side top/bottom heights --- src/r_segs.c | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/src/r_segs.c b/src/r_segs.c index fff98dbf2..0d3a6430e 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -983,45 +983,45 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) left_bottom = P_GetZAt(*pfloor->b_slope, ds->leftpos.x, ds->leftpos.y) - viewz; else left_bottom = *pfloor->bottomheight - viewz; - dc_texturemid = left_top; skewslope = *pfloor->t_slope; // skew using top slope by default -#else - dc_texturemid = *pfloor->topheight - viewz; + if (newline && newline->flags & ML_DONTPEGTOP) + slopeskew = true; + else if (pfloor->master->flags & ML_DONTPEGTOP) + slopeskew = true; + + if (slopeskew) + dc_texturemid = left_top; + else #endif + dc_texturemid = *pfloor->topheight - viewz; if (newline) { offsetvalue = sides[newline->sidenum[0]].rowoffset; if (newline->flags & ML_DONTPEGBOTTOM) -#ifdef ESLOPE { - dc_texturemid = left_bottom; - skewslope = *pfloor->b_slope; // skew using bottom slope - } -#else - offsetvalue -= *pfloor->topheight - *pfloor->bottomheight; -#endif #ifdef ESLOPE - if (newline->flags & ML_DONTPEGTOP) - slopeskew = true; + skewslope = *pfloor->b_slope; // skew using bottom slope + if (slopeskew) + dc_texturemid = left_bottom; + else #endif + offsetvalue -= *pfloor->topheight - *pfloor->bottomheight; + } } else { offsetvalue = sides[pfloor->master->sidenum[0]].rowoffset; if (curline->linedef->flags & ML_DONTPEGBOTTOM) -#ifdef ESLOPE { - dc_texturemid = left_bottom; - skewslope = *pfloor->b_slope; // skew using bottom slope - } -#else - offsetvalue -= *pfloor->topheight - *pfloor->bottomheight; -#endif #ifdef ESLOPE - if (pfloor->master->flags & ML_DONTPEGTOP) // use control linedef's flags - slopeskew = true; + skewslope = *pfloor->b_slope; // skew using bottom slope + if (slopeskew) + dc_texturemid = left_bottom; + else #endif + offsetvalue -= *pfloor->topheight - *pfloor->bottomheight; + } } #ifdef ESLOPE From 31e27eae0e9390e6a8884bc55e0575f10cad1afc Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Mon, 29 Aug 2016 23:24:59 +0100 Subject: [PATCH 3/4] probably best if we did this instead actually --- src/r_segs.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/r_segs.c b/src/r_segs.c index 0d3a6430e..b997c2a88 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -984,8 +984,11 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) else left_bottom = *pfloor->bottomheight - viewz; skewslope = *pfloor->t_slope; // skew using top slope by default - if (newline && newline->flags & ML_DONTPEGTOP) - slopeskew = true; + if (newline) + { + if (newline->flags & ML_DONTPEGTOP) + slopeskew = true; + } else if (pfloor->master->flags & ML_DONTPEGTOP) slopeskew = true; From 57f76051bd18d4c5dbd8a25df5b613299f9e20c0 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Fri, 28 Sep 2018 17:02:02 +0100 Subject: [PATCH 4/4] Redo OpenGL skewing support, so that it now itself supports the lower unpegged effect for FOFs in OpenGL! --- src/hardware/hw_main.c | 46 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 38 insertions(+), 8 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index d7c73415a..92925c9bf 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -2183,6 +2183,10 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) else if (drawtextured) { fixed_t texturevpeg; + boolean attachtobottom = false; +#ifdef ESLOPE + boolean slopeskew = false; // skew FOF walls with slopes? +#endif // Wow, how was this missing from OpenGL for so long? // ...Oh well, anyway, Lower Unpegged now changes pegging of FOFs like in software @@ -2190,24 +2194,50 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) if (newline) { texturevpeg = sides[newline->sidenum[0]].rowoffset; - if (newline->flags & ML_DONTPEGBOTTOM) - texturevpeg -= *rover->topheight - *rover->bottomheight; + attachtobottom = !!(newline->flags & ML_DONTPEGBOTTOM); +#ifdef ESLOPE + slopeskew = !!(newline->flags & ML_DONTPEGTOP); +#endif } else { texturevpeg = sides[rover->master->sidenum[0]].rowoffset; - if (gr_linedef->flags & ML_DONTPEGBOTTOM) - texturevpeg -= *rover->topheight - *rover->bottomheight; + attachtobottom = !!(gr_linedef->flags & ML_DONTPEGBOTTOM); +#ifdef ESLOPE + slopeskew = !!(rover->master->flags & ML_DONTPEGTOP); +#endif } grTex = HWR_GetTexture(texnum); #ifdef ESLOPE - wallVerts[3].t = (*rover->topheight - h + texturevpeg) * grTex->scaleY; - wallVerts[2].t = (*rover->topheight - hS + texturevpeg) * grTex->scaleY; - wallVerts[0].t = (*rover->topheight - l + texturevpeg) * grTex->scaleY; - wallVerts[1].t = (*rover->topheight - lS + texturevpeg) * grTex->scaleY; + if (!slopeskew) // no skewing + { + if (attachtobottom) + texturevpeg -= *rover->topheight - *rover->bottomheight; + wallVerts[3].t = (*rover->topheight - h + texturevpeg) * grTex->scaleY; + wallVerts[2].t = (*rover->topheight - hS + texturevpeg) * grTex->scaleY; + wallVerts[0].t = (*rover->topheight - l + texturevpeg) * grTex->scaleY; + wallVerts[1].t = (*rover->topheight - lS + texturevpeg) * grTex->scaleY; + } + else + { + if (!attachtobottom) // skew by top + { + wallVerts[3].t = wallVerts[2].t = texturevpeg * grTex->scaleY; + wallVerts[0].t = (h - l + texturevpeg) * grTex->scaleY; + wallVerts[1].t = (hS - lS + texturevpeg) * grTex->scaleY; + } + else // skew by bottom + { + wallVerts[0].t = wallVerts[1].t = texturevpeg * grTex->scaleY; + wallVerts[3].t = wallVerts[0].t - (h - l) * grTex->scaleY; + wallVerts[2].t = wallVerts[1].t - (hS - lS) * grTex->scaleY; + } + } #else + if (attachtobottom) + texturevpeg -= *rover->topheight - *rover->bottomheight; wallVerts[3].t = wallVerts[2].t = (*rover->topheight - h + texturevpeg) * grTex->scaleY; wallVerts[0].t = wallVerts[1].t = (*rover->topheight - l + texturevpeg) * grTex->scaleY; #endif