From 9f87841936a957c4c7552089654cfdd2bd22cc15 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Thu, 8 Sep 2016 22:55:11 +0100 Subject: [PATCH 01/35] Fix bottom of FOF with a pusher special not accounting for slopes --- src/p_spec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_spec.c b/src/p_spec.c index 30b08ebb..92f62af4 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -7428,7 +7428,7 @@ void T_Pusher(pusher_t *p) } else { - if (top < thing->z || referrer->floorheight > (thing->z + (thing->height >> 1))) + if (top < thing->z || bottom > (thing->z + (thing->height >> 1))) continue; if (thing->z + thing->height > top) touching = true; From b8345aaf27ab32dd7cee8960143fc63bd666f5c2 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Thu, 22 Sep 2016 00:13:34 +0100 Subject: [PATCH 02/35] Solid objects are now no longer selectively intangible on slopes. HOWEVER, since these changes to PIT_CheckThing do raise questions about whether there may be unintended side effects here. As a result, I may remake this for internal only if necessary. --- src/p_map.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/p_map.c b/src/p_map.c index c4616db4..13496bef 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -985,7 +985,7 @@ static boolean PIT_CheckThing(mobj_t *thing) return true; } - topz = thing->z - FixedMul(FRACUNIT, thing->scale); + topz = thing->z - thing->scale; // block only when jumping not high enough, // (dont climb max. 24units while already in air) @@ -996,7 +996,7 @@ static boolean PIT_CheckThing(mobj_t *thing) if (thing->flags & MF_SPRING) ; - else if (topz < tmceilingz && tmthing->z+tmthing->height <= thing->z+thing->height) + else if (topz < tmceilingz && tmthing->z <= thing->z+thing->height) { tmceilingz = topz; #ifdef ESLOPE @@ -1022,7 +1022,7 @@ static boolean PIT_CheckThing(mobj_t *thing) return true; } - topz = thing->z + thing->height + FixedMul(FRACUNIT, thing->scale); + topz = thing->z + thing->height + thing->scale; // block only when jumping not high enough, // (dont climb max. 24units while already in air) @@ -1032,7 +1032,7 @@ static boolean PIT_CheckThing(mobj_t *thing) if (thing->flags & MF_SPRING) ; - else if (topz > tmfloorz && tmthing->z >= thing->z) + else if (topz > tmfloorz && tmthing->z+tmthing->height >= thing->z) { tmfloorz = topz; #ifdef ESLOPE From fa16abf7ae8cf0468bb3237047687eefca997e6e Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Thu, 22 Sep 2016 11:15:08 +0100 Subject: [PATCH 03/35] Fixed the thing where if you thok into a solid object you spin really fast in the air without moving OR losing your momentum. --- src/p_map.c | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/src/p_map.c b/src/p_map.c index 13496bef..a3f34aa8 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -989,12 +989,18 @@ static boolean PIT_CheckThing(mobj_t *thing) // block only when jumping not high enough, // (dont climb max. 24units while already in air) - // if not in air, let P_TryMove() decide if it's not too high + // since return false doesn't handle momentum properly, + // we lie to P_TryMove() so it's always too high if (tmthing->player && tmthing->z + tmthing->height > topz && tmthing->z + tmthing->height < tmthing->ceilingz) - return false; // block while in air - - if (thing->flags & MF_SPRING) + { + tmceilingz = INT32_MIN; // block while in air +#ifdef ESLOPE + tmceilingslope = NULL; +#endif + tmfloorthing = thing; // needed for side collision + } + else if (thing->flags & MF_SPRING) ; else if (topz < tmceilingz && tmthing->z <= thing->z+thing->height) { @@ -1026,11 +1032,18 @@ static boolean PIT_CheckThing(mobj_t *thing) // block only when jumping not high enough, // (dont climb max. 24units while already in air) - // if not in air, let P_TryMove() decide if it's not too high - if (tmthing->player && tmthing->z < topz && tmthing->z > tmthing->floorz) - return false; // block while in air - - if (thing->flags & MF_SPRING) + // since return false doesn't handle momentum properly, + // we lie to P_TryMove() so it's always too high + if (tmthing->player && tmthing->z < topz + && tmthing->z > tmthing->floorz) + { + tmfloorz = INT32_MAX; // block while in air +#ifdef ESLOPE + tmfloorslope = NULL; +#endif + tmfloorthing = thing; // needed for side collision + } + else if (thing->flags & MF_SPRING) ; else if (topz > tmfloorz && tmthing->z+tmthing->height >= thing->z) { From 0568712a5e3bee3335e5e0f9256c1ad07f78d25a Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Thu, 22 Sep 2016 12:01:13 +0100 Subject: [PATCH 04/35] Prevent overflow when attempting to calculate the space between floor and ceiling. (I didn't notice any bugs as a result of the previous behvaiour, but you never know.) --- src/p_map.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/p_map.c b/src/p_map.c index a3f34aa8..8b8c6c07 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -994,7 +994,7 @@ static boolean PIT_CheckThing(mobj_t *thing) if (tmthing->player && tmthing->z + tmthing->height > topz && tmthing->z + tmthing->height < tmthing->ceilingz) { - tmceilingz = INT32_MIN; // block while in air + tmfloorz = tmceilingz = INT32_MIN; // block while in air #ifdef ESLOPE tmceilingslope = NULL; #endif @@ -1037,7 +1037,7 @@ static boolean PIT_CheckThing(mobj_t *thing) if (tmthing->player && tmthing->z < topz && tmthing->z > tmthing->floorz) { - tmfloorz = INT32_MAX; // block while in air + tmfloorz = tmceilingz = INT32_MAX; // block while in air #ifdef ESLOPE tmfloorslope = NULL; #endif From 394ed30f4436dd3d9a2a8bd118a60175f350527b Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Thu, 22 Sep 2016 21:08:36 +0100 Subject: [PATCH 05/35] Fixed the problem with the reverseplatform_clipping branch that caused springs to fall through platforms, as tested by Wolfs in TD. --- src/p_mobj.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 5e5961d4..82326f04 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -2017,13 +2017,13 @@ static void P_AdjustMobjFloorZ_FFloors(mobj_t *mo, sector_t *sector, UINT8 motyp delta2 = thingtop - (bottomheight + ((topheight - bottomheight)/2)); if (topheight > mo->floorz && abs(delta1) < abs(delta2) && !(rover->flags & FF_REVERSEPLATFORM) - && ((P_MobjFlip(mo)*mo->momz > 0) || (!(rover->flags & FF_PLATFORM)))) // In reverse gravity, only clip for FOFs that are intangible from their bottom (the "top" you're falling through) if you're coming from above ("below" in your frame of reference) + && ((P_MobjFlip(mo)*mo->momz >= 0) || (!(rover->flags & FF_PLATFORM)))) // In reverse gravity, only clip for FOFs that are intangible from their bottom (the "top" you're falling through) if you're coming from above ("below" in your frame of reference) { mo->floorz = topheight; } if (bottomheight < mo->ceilingz && abs(delta1) >= abs(delta2) && !(rover->flags & FF_PLATFORM) - && ((P_MobjFlip(mo)*mo->momz > 0) || (!(rover->flags & FF_REVERSEPLATFORM)))) // In normal gravity, only clip for FOFs that are intangible from the top if you're coming from below + && ((P_MobjFlip(mo)*mo->momz >= 0) || (!(rover->flags & FF_REVERSEPLATFORM)))) // In normal gravity, only clip for FOFs that are intangible from the top if you're coming from below { mo->ceilingz = bottomheight; } From 8ad72232bea1b1b093fe9a36ca189e1c90db5127 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Thu, 22 Sep 2016 21:15:12 +0100 Subject: [PATCH 06/35] Helpful explanatory comments to assauge MI's fears. --- src/p_map.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/p_map.c b/src/p_map.c index 8b8c6c07..6a555953 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -985,7 +985,7 @@ static boolean PIT_CheckThing(mobj_t *thing) return true; } - topz = thing->z - thing->scale; + topz = thing->z - thing->scale; // FixedMul(FRACUNIT, thing->scale), but thing->scale == FRACUNIT in base scale anyways // block only when jumping not high enough, // (dont climb max. 24units while already in air) @@ -1028,7 +1028,7 @@ static boolean PIT_CheckThing(mobj_t *thing) return true; } - topz = thing->z + thing->height + thing->scale; + topz = thing->z + thing->height + thing->scale; // FixedMul(FRACUNIT, thing->scale), but thing->scale == FRACUNIT in base scale anyways // block only when jumping not high enough, // (dont climb max. 24units while already in air) From 5f4f6fdac89e01a330bf821a9ec95dd3c74cc480 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Mon, 26 Sep 2016 18:35:13 +0100 Subject: [PATCH 07/35] Public remake of a merge request I shouldn't have put in Internal in the first place. --- src/m_misc.c | 2 ++ src/p_spec.c | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/m_misc.c b/src/m_misc.c index 457214e3..cfe73d88 100644 --- a/src/m_misc.c +++ b/src/m_misc.c @@ -1675,6 +1675,7 @@ char *M_GetToken(const char *inputString) || stringToUse[startPos] == '\r' || stringToUse[startPos] == '\n' || stringToUse[startPos] == '\0' + || stringToUse[startPos] == '"' // we're treating this as whitespace because SLADE likes adding it for no good reason || inComment != 0) && startPos < stringLength) { @@ -1742,6 +1743,7 @@ char *M_GetToken(const char *inputString) && stringToUse[endPos] != ',' && stringToUse[endPos] != '{' && stringToUse[endPos] != '}' + && stringToUse[endPos] != '"' // see above && inComment == 0) && endPos < stringLength) { diff --git a/src/p_spec.c b/src/p_spec.c index 30b08ebb..5dac8d34 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -509,7 +509,7 @@ void P_ParseAnimationDefintion(SINT8 istexture, INT32 *i) animdefsToken = M_GetToken(NULL); if (animdefsToken == NULL) { - I_Error("Error parsing TEXTURES lump: Unexpected end of file where \"%s\"'s animation speed should be", animdefs[*i].startname); + I_Error("Error parsing ANIMDEFS lump: Unexpected end of file where \"%s\"'s animation speed should be", animdefs[*i].startname); } endPos = NULL; #ifndef AVOID_ERRNO @@ -523,7 +523,7 @@ void P_ParseAnimationDefintion(SINT8 istexture, INT32 *i) #endif || animSpeed < 0) // Number is not positive { - I_Error("Error parsing TEXTURES lump: Expected a positive integer for \"%s\"'s animation speed, got \"%s\"", animdefs[*i].startname, animdefsToken); + I_Error("Error parsing ANIMDEFS lump: Expected a positive integer for \"%s\"'s animation speed, got \"%s\"", animdefs[*i].startname, animdefsToken); } animdefs[*i].speed = animSpeed; Z_Free(animdefsToken); From 8881a413f3c3a652675e4f451ebb849f17a8ac10 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Tue, 27 Sep 2016 17:17:23 +0100 Subject: [PATCH 08/35] Fixed that really annoying bug where you disappear when spindashing on top of a FOF whilst wearing a multi-layer shield. (the problem was that MT_OVERLAY's default radius and height were never getting changed from 1*FRACUNIT, and that meant that when you spindashed, the game considered it completely below the surface of the flat you were standing on. Since you're not usually clipped on flats that don't belong to FOFs, we didn't notice this issue sooner.) --- src/p_mobj.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/p_mobj.c b/src/p_mobj.c index 5e5961d4..b35b7286 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -5930,6 +5930,8 @@ static boolean P_ShieldLook(mobj_t *thing, shieldtype_t shield) P_UnsetThingPosition(thing); thing->x = thing->target->x; thing->y = thing->target->y; + thing->radius = thing->target->radius; + thing->height = thing->target->height; if (thing->eflags & MFE_VERTICALFLIP) thing->z = thing->target->z + thing->target->height - thing->height + FixedDiv(P_GetPlayerHeight(thing->target->player) - thing->target->height, 3*FRACUNIT) - FixedMul(2*FRACUNIT, thing->target->scale); else @@ -6048,6 +6050,8 @@ void P_RunOverlays(void) P_UnsetThingPosition(mo); mo->x = destx; mo->y = desty; + mo->radius = mo->target->radius; + mo->height = mo->target->height; if (mo->eflags & MFE_VERTICALFLIP) mo->z = (mo->target->z + mo->target->height - mo->height) - zoffs; else From 1c23a84aa531b02a1f62b6ea65f1896e249d904a Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sun, 9 Oct 2016 20:55:04 +0100 Subject: [PATCH 09/35] set floorcenterz/ceilingcenterz for all of R_Subsector to use, not just FOF planes --- src/r_bsp.c | 47 ++++++++++++++++++++--------------------------- 1 file changed, 20 insertions(+), 27 deletions(-) diff --git a/src/r_bsp.c b/src/r_bsp.c index 69aa7be2..11159db3 100644 --- a/src/r_bsp.c +++ b/src/r_bsp.c @@ -859,6 +859,7 @@ static void R_Subsector(size_t num) static sector_t tempsec; // Deep water hack extracolormap_t *floorcolormap; extracolormap_t *ceilingcolormap; + fixed_t floorcenterz, ceilingcenterz; #ifdef RANGECHECK if (num >= numsubsectors) @@ -879,6 +880,18 @@ static void R_Subsector(size_t num) floorcolormap = ceilingcolormap = frontsector->extra_colormap; + floorcenterz = +#ifdef ESLOPE + frontsector->f_slope ? P_GetZAt(frontsector->f_slope, frontsector->soundorg.x, frontsector->soundorg.y) : +#endif + frontsector->floorheight; + + ceilingcenterz = +#ifdef ESLOPE + frontsector->c_slope ? P_GetZAt(frontsector->c_slope, frontsector->soundorg.x, frontsector->soundorg.y) : +#endif + frontsector->ceilingheight; + // Check and prep all 3D floors. Set the sector floor/ceiling light levels and colormaps. if (frontsector->ffloors) { @@ -891,19 +904,11 @@ static void R_Subsector(size_t num) sub->sector->moved = frontsector->moved = false; } - light = R_GetPlaneLight(frontsector, -#ifdef ESLOPE - frontsector->f_slope ? P_GetZAt(frontsector->f_slope, frontsector->soundorg.x, frontsector->soundorg.y) : -#endif - frontsector->floorheight, false); + light = R_GetPlaneLight(frontsector, floorcenterz, false); if (frontsector->floorlightsec == -1) floorlightlevel = *frontsector->lightlist[light].lightlevel; floorcolormap = frontsector->lightlist[light].extra_colormap; - light = R_GetPlaneLight(frontsector, -#ifdef ESLOPE - frontsector->c_slope ? P_GetZAt(frontsector->c_slope, frontsector->soundorg.x, frontsector->soundorg.y) : -#endif - frontsector->ceilingheight, false); + light = R_GetPlaneLight(frontsector, ceilingcenterz, false); if (frontsector->ceilinglightsec == -1) ceilinglightlevel = *frontsector->lightlist[light].lightlevel; ceilingcolormap = frontsector->lightlist[light].extra_colormap; @@ -956,7 +961,7 @@ static void R_Subsector(size_t num) if (frontsector->ffloors) { ffloor_t *rover; - fixed_t heightcheck, planecenterz, floorcenterz, ceilingcenterz; + fixed_t heightcheck, planecenterz; for (rover = frontsector->ffloors; rover && numffloors < MAXFFLOORS; rover = rover->next) { @@ -975,18 +980,6 @@ static void R_Subsector(size_t num) ffloor[numffloors].plane = NULL; ffloor[numffloors].polyobj = NULL; - floorcenterz = -#ifdef ESLOPE - frontsector->f_slope ? P_GetZAt(frontsector->f_slope, frontsector->soundorg.x, frontsector->soundorg.y) : -#endif - frontsector->floorheight; - - ceilingcenterz = -#ifdef ESLOPE - frontsector->c_slope ? P_GetZAt(frontsector->c_slope, frontsector->soundorg.x, frontsector->soundorg.y) : -#endif - frontsector->ceilingheight; - heightcheck = #ifdef ESLOPE *rover->b_slope ? P_GetZAt(*rover->b_slope, viewx, viewy) : @@ -1093,8 +1086,8 @@ static void R_Subsector(size_t num) polysec = po->lines[0]->backsector; ffloor[numffloors].plane = NULL; - if (polysec->floorheight <= frontsector->ceilingheight - && polysec->floorheight >= frontsector->floorheight + if (polysec->floorheight <= ceilingcenterz + && polysec->floorheight >= floorcenterz && (viewz < polysec->floorheight)) { fixed_t xoff, yoff; @@ -1139,8 +1132,8 @@ static void R_Subsector(size_t num) ffloor[numffloors].plane = NULL; - if (polysec->ceilingheight >= frontsector->floorheight - && polysec->ceilingheight <= frontsector->ceilingheight + if (polysec->ceilingheight >= floorcenterz + && polysec->ceilingheight <= ceilingcenterz && (viewz > polysec->ceilingheight)) { fixed_t xoff, yoff; From b66925e467ca6cebbaa78fd21eb3e96898d2c8d2 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sun, 9 Oct 2016 21:48:25 +0100 Subject: [PATCH 10/35] R_FindPlane now has a polyobj argument, R_DrawPlanes now skips polyobj planes, like it does with FOF planes --- src/r_bsp.c | 20 ++++++++++++++++++-- src/r_plane.c | 13 +++++++++++-- src/r_plane.h | 3 +++ 3 files changed, 32 insertions(+), 4 deletions(-) diff --git a/src/r_bsp.c b/src/r_bsp.c index 11159db3..2562cff6 100644 --- a/src/r_bsp.c +++ b/src/r_bsp.c @@ -925,6 +925,9 @@ static void R_Subsector(size_t num) { floorplane = R_FindPlane(frontsector->floorheight, frontsector->floorpic, floorlightlevel, frontsector->floor_xoffs, frontsector->floor_yoffs, frontsector->floorpic_angle, floorcolormap, NULL +#ifdef POLYOBJECTS_PLANES + , NULL +#endif #ifdef ESLOPE , frontsector->f_slope #endif @@ -944,6 +947,9 @@ static void R_Subsector(size_t num) ceilingplane = R_FindPlane(frontsector->ceilingheight, frontsector->ceilingpic, ceilinglightlevel, frontsector->ceiling_xoffs, frontsector->ceiling_yoffs, frontsector->ceilingpic_angle, ceilingcolormap, NULL +#ifdef POLYOBJECTS_PLANES + , NULL +#endif #ifdef ESLOPE , frontsector->c_slope #endif @@ -1002,6 +1008,9 @@ static void R_Subsector(size_t num) ffloor[numffloors].plane = R_FindPlane(*rover->bottomheight, *rover->bottompic, *frontsector->lightlist[light].lightlevel, *rover->bottomxoffs, *rover->bottomyoffs, *rover->bottomangle, frontsector->lightlist[light].extra_colormap, rover +#ifdef POLYOBJECTS_PLANES + , NULL +#endif #ifdef ESLOPE , *rover->b_slope #endif @@ -1045,6 +1054,9 @@ static void R_Subsector(size_t num) ffloor[numffloors].plane = R_FindPlane(*rover->topheight, *rover->toppic, *frontsector->lightlist[light].lightlevel, *rover->topxoffs, *rover->topyoffs, *rover->topangle, frontsector->lightlist[light].extra_colormap, rover +#ifdef POLYOBJECTS_PLANES + , NULL +#endif #ifdef ESLOPE , *rover->t_slope #endif @@ -1111,11 +1123,13 @@ static void R_Subsector(size_t num) polysec->floorpic_angle-po->angle, NULL, NULL +#ifdef POLYOBJECTS_PLANES + , po +#endif #ifdef ESLOPE , NULL // will ffloors be slopable eventually? #endif ); - //ffloor[numffloors].plane->polyobj = po; ffloor[numffloors].height = polysec->floorheight; ffloor[numffloors].polyobj = po; @@ -1155,11 +1169,13 @@ static void R_Subsector(size_t num) ffloor[numffloors].plane = R_FindPlane(polysec->ceilingheight, polysec->ceilingpic, polysec->lightlevel, xoff, yoff, polysec->ceilingpic_angle-po->angle, NULL, NULL +#ifdef POLYOBJECTS_PLANES + , po +#endif #ifdef ESLOPE , NULL // will ffloors be slopable eventually? #endif ); - //ffloor[numffloors].plane->polyobj = po; ffloor[numffloors].polyobj = po; ffloor[numffloors].height = polysec->ceilingheight; diff --git a/src/r_plane.c b/src/r_plane.c index 19007d88..b7b9eaff 100644 --- a/src/r_plane.c +++ b/src/r_plane.c @@ -431,6 +431,9 @@ static visplane_t *new_visplane(unsigned hash) visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel, fixed_t xoff, fixed_t yoff, angle_t plangle, extracolormap_t *planecolormap, ffloor_t *pfloor +#ifdef POLYOBJECTS_PLANES + , polyobj_t *polyobj +#endif #ifdef ESLOPE , pslope_t *slope #endif @@ -470,6 +473,8 @@ visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel, #ifdef POLYOBJECTS_PLANES if (check->polyobj && pfloor) continue; + if (polyobj != check->polyobj) + continue; #endif if (height == check->height && picnum == check->picnum && lightlevel == check->lightlevel @@ -504,7 +509,7 @@ visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel, check->viewangle = viewangle; check->plangle = plangle; #ifdef POLYOBJECTS_PLANES - check->polyobj = NULL; + check->polyobj = polyobj; #endif #ifdef ESLOPE check->slope = slope; @@ -719,7 +724,11 @@ void R_DrawPlanes(void) continue; } - if (pl->ffloor != NULL) + if (pl->ffloor != NULL +#ifdef POLYOBJECTS_PLANES + || pl->polyobj != NULL +#endif + ) continue; R_DrawSinglePlane(pl); diff --git a/src/r_plane.h b/src/r_plane.h index ec194071..16c8c12a 100644 --- a/src/r_plane.h +++ b/src/r_plane.h @@ -97,6 +97,9 @@ void R_MakeSpans(INT32 x, INT32 t1, INT32 b1, INT32 t2, INT32 b2); void R_DrawPlanes(void); visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel, fixed_t xoff, fixed_t yoff, angle_t plangle, extracolormap_t *planecolormap, ffloor_t *ffloor +#ifdef POLYOBJECTS_PLANES + , polyobj_t *polyobj +#endif #ifdef ESLOPE , pslope_t *slope #endif From ff0b1d1dface10ab11357eee5a0a1fe66ad23403 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Tue, 11 Oct 2016 22:35:46 +0100 Subject: [PATCH 11/35] Split polyobj plane drawnode-creating code from ds->maskedtexturecol code, and add plane bounds checking --- src/r_things.c | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/src/r_things.c b/src/r_things.c index 22551a02..ed1ddeab 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -1699,21 +1699,25 @@ static void R_CreateDrawNodes(void) entry->ffloor = ds->thicksides[i]; } } +#ifdef POLYOBJECTS_PLANES + // Check for a polyobject plane, but only if this is a front line + if (ds->curline->polyseg && ds->curline->polyseg->visplane && !ds->curline->side) { + plane = ds->curline->polyseg->visplane; + R_PlaneBounds(plane); + + if (plane->low < con_clipviewtop || plane->high > vid.height || plane->high > plane->low) + ; + else { + // Put it in! + entry = R_CreateDrawNode(&nodehead); + entry->plane = plane; + entry->seg = ds; + } + ds->curline->polyseg->visplane = NULL; + } +#endif if (ds->maskedtexturecol) { -#ifdef POLYOBJECTS_PLANES - // Check for a polyobject plane, but only if this is a front line - if (ds->curline->polyseg && ds->curline->polyseg->visplane && !ds->curline->side) { - // Put it in! - - entry = R_CreateDrawNode(&nodehead); - entry->plane = ds->curline->polyseg->visplane; - entry->seg = ds; - ds->curline->polyseg->visplane->polyobj = ds->curline->polyseg; - ds->curline->polyseg->visplane = NULL; - } -#endif - entry = R_CreateDrawNode(&nodehead); entry->seg = ds; } From e1baf02b7a3f2dd27ccf8bcf6089c5d765dfe756 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Tue, 18 Oct 2016 22:07:20 +0100 Subject: [PATCH 12/35] Lua now errors if negative scales are used with v.drawScaled --- src/lua_hudlib.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/lua_hudlib.c b/src/lua_hudlib.c index 7aadd9c0..60cbbe50 100644 --- a/src/lua_hudlib.c +++ b/src/lua_hudlib.c @@ -369,6 +369,8 @@ static int libd_drawScaled(lua_State *L) x = luaL_checkinteger(L, 1); y = luaL_checkinteger(L, 2); scale = luaL_checkinteger(L, 3); + if (scale < 0) + return luaL_error(L, "negative scale"); patch = *((patch_t **)luaL_checkudata(L, 4, META_PATCH)); flags = luaL_optinteger(L, 5, 0); if (!lua_isnoneornil(L, 6)) From aa3e52f05e5b044e4f9a6f710027fae020b625c7 Mon Sep 17 00:00:00 2001 From: Yukita Mayako Date: Wed, 19 Oct 2016 03:17:36 -0400 Subject: [PATCH 13/35] Fix ANIMDEFS parsing to allow overwrite. ANIMATED and ANIMDEFS are now processed in reverse order, and duplicate definitions in ANIMDEFS are dropped. --- src/p_spec.c | 111 ++++++++++++++++++++++++++++++--------------------- 1 file changed, 66 insertions(+), 45 deletions(-) diff --git a/src/p_spec.c b/src/p_spec.c index cb928eee..b04c5588 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -221,8 +221,8 @@ static animdef_t harddefs[] = static animdef_t *animdefs = NULL; // A prototype; here instead of p_spec.h, so they're "private" -void P_ParseANIMDEFSLump(INT32 wadNum, UINT16 lumpnum, INT32 *i); -void P_ParseAnimationDefintion(SINT8 istexture, INT32 *i); +void P_ParseANIMDEFSLump(INT32 wadNum, UINT16 lumpnum); +void P_ParseAnimationDefintion(SINT8 istexture); /** Sets up texture and flat animations. * @@ -232,24 +232,21 @@ void P_ParseAnimationDefintion(SINT8 istexture, INT32 *i); * Issues an error if any animation cycles are invalid. * * \sa P_FindAnimatedFlat, P_SetupLevelFlatAnims - * \author Steven McGranahan (original), Shadow Hog (had to rewrite it to handle multiple WADs) + * \author Steven McGranahan (original), Shadow Hog (had to rewrite it to handle multiple WADs), JTE (had to rewrite it to handle multiple WADs _correctly_) */ void P_InitPicAnims(void) { // Init animation - INT32 i; // Position in the animdefs array INT32 w; // WAD - UINT8 *wadAnimdefs; // not to be confused with animdefs, the combined total of every ANIMATED lump in every WAD, or ANIMDEFS, the ZDoom lump I intend to implement later + UINT8 *animatedLump; UINT8 *currentPos; + size_t i; + + I_Assert(animdefs == NULL); if (W_CheckNumForName("ANIMATED") != LUMPERROR || W_CheckNumForName("ANIMDEFS") != LUMPERROR) { - if (animdefs) - { - Z_Free(animdefs); - animdefs = NULL; - } - for (w = 0, i = 0, maxanims = 0; w < numwadfiles; w++) + for (w = numwadfiles-1, maxanims = 0; w >= 0; w--) { UINT16 animatedLumpNum; UINT16 animdefsLumpNum; @@ -258,20 +255,20 @@ void P_InitPicAnims(void) animatedLumpNum = W_CheckNumForNamePwad("ANIMATED", w, 0); if (animatedLumpNum != INT16_MAX) { - wadAnimdefs = (UINT8 *)W_CacheLumpNumPwad(w, animatedLumpNum, PU_STATIC); + animatedLump = (UINT8 *)W_CacheLumpNumPwad(w, animatedLumpNum, PU_STATIC); // Get the number of animations in the file - for (currentPos = wadAnimdefs; *currentPos != UINT8_MAX; maxanims++, currentPos+=23); + i = maxanims; + for (currentPos = animatedLump; *currentPos != UINT8_MAX; maxanims++, currentPos+=23); // Resize animdefs (or if it hasn't been created, create it) animdefs = (animdef_t *)Z_Realloc(animdefs, sizeof(animdef_t)*(maxanims + 1), PU_STATIC, NULL); // Sanity check it - if (!animdefs) { + if (!animdefs) I_Error("Not enough free memory for ANIMATED data"); - } // Populate the new array - for (currentPos = wadAnimdefs; *currentPos != UINT8_MAX; i++, currentPos+=23) + for (currentPos = animatedLump; *currentPos != UINT8_MAX; i++, currentPos+=23) { M_Memcpy(&(animdefs[i].istexture), currentPos, 1); // istexture, 1 byte M_Memcpy(animdefs[i].endname, (currentPos + 1), 9); // endname, 9 bytes @@ -279,15 +276,13 @@ void P_InitPicAnims(void) M_Memcpy(&(animdefs[i].speed), (currentPos + 19), 4); // speed, 4 bytes } - Z_Free(wadAnimdefs); + Z_Free(animatedLump); } // Now find ANIMDEFS animdefsLumpNum = W_CheckNumForNamePwad("ANIMDEFS", w, 0); if (animdefsLumpNum != INT16_MAX) - { - P_ParseANIMDEFSLump(w, animdefsLumpNum, &i); - } + P_ParseANIMDEFSLump(w, animdefsLumpNum); } // Define the last one animdefs[maxanims].istexture = -1; @@ -347,16 +342,20 @@ void P_InitPicAnims(void) lastanim->istexture = -1; R_ClearTextureNumCache(false); + // Clear animdefs now that we're done with it. + // We'll only be using anims from now on. if (animdefs != harddefs) - Z_ChangeTag(animdefs, PU_CACHE); + Z_Free(animdefs); + animdefs = NULL; } -void P_ParseANIMDEFSLump(INT32 wadNum, UINT16 lumpnum, INT32 *i) +void P_ParseANIMDEFSLump(INT32 wadNum, UINT16 lumpnum) { char *animdefsLump; size_t animdefsLumpLength; char *animdefsText; char *animdefsToken; + char *p; // Since lumps AREN'T \0-terminated like I'd assumed they should be, I'll // need to make a space of memory where I can ensure that it will terminate @@ -376,18 +375,19 @@ void P_ParseANIMDEFSLump(INT32 wadNum, UINT16 lumpnum, INT32 *i) Z_Free(animdefsLump); // Now, let's start parsing this thing - animdefsToken = M_GetToken(animdefsText); + p = animdefsText; + animdefsToken = M_GetToken(p); while (animdefsToken != NULL) { if (stricmp(animdefsToken, "TEXTURE") == 0) { Z_Free(animdefsToken); - P_ParseAnimationDefintion(1, i); + P_ParseAnimationDefintion(1); } else if (stricmp(animdefsToken, "FLAT") == 0) { Z_Free(animdefsToken); - P_ParseAnimationDefintion(0, i); + P_ParseAnimationDefintion(0); } else if (stricmp(animdefsToken, "OSCILLATE") == 0) { @@ -398,23 +398,22 @@ void P_ParseANIMDEFSLump(INT32 wadNum, UINT16 lumpnum, INT32 *i) { I_Error("Error parsing ANIMDEFS lump: Expected \"TEXTURE\" or \"FLAT\", got \"%s\"",animdefsToken); } - animdefsToken = M_GetToken(NULL); + // parse next line + while (*p != '\0' && *p != '\n') ++p; + if (*p == '\n') ++p; + animdefsToken = M_GetToken(p); } Z_Free(animdefsToken); Z_Free((void *)animdefsText); } -void P_ParseAnimationDefintion(SINT8 istexture, INT32 *i) +void P_ParseAnimationDefintion(SINT8 istexture) { char *animdefsToken; size_t animdefsTokenLength; char *endPos; INT32 animSpeed; - - // Increase the size to make room for the new animation definition - maxanims++; - animdefs = (animdef_t *)Z_Realloc(animdefs, sizeof(animdef_t)*(maxanims + 1), PU_STATIC, NULL); - animdefs[*i].istexture = istexture; + size_t i; // Startname animdefsToken = M_GetToken(NULL); @@ -448,14 +447,39 @@ void P_ParseAnimationDefintion(SINT8 istexture, INT32 *i) { I_Error("Error parsing ANIMDEFS lump: lump name \"%s\" exceeds 8 characters", animdefsToken); } - strncpy(animdefs[*i].startname, animdefsToken, 9); + + // Search for existing animdef + for (i = 0; i < maxanims; i++) + if (stricmp(animdefsToken, animdefs[i].startname) == 0) + { + //CONS_Alert(CONS_NOTICE, "Duplicate animation: %s\n", animdefsToken); + + // If we weren't parsing in reverse order, we would `break` here and parse the new data into the existing slot we found. + // Instead, we're just going to skip parsing the rest of this line entirely. + Z_Free(animdefsToken); + return; + } + + // Not found + if (i == maxanims) + { + // Increase the size to make room for the new animation definition + maxanims++; + animdefs = (animdef_t *)Z_Realloc(animdefs, sizeof(animdef_t)*(maxanims + 1), PU_STATIC, NULL); + strncpy(animdefs[i].startname, animdefsToken, 9); + } + + // animdefs[i].startname is now set to animdefsToken either way. Z_Free(animdefsToken); + // set texture type + animdefs[i].istexture = istexture; + // "RANGE" animdefsToken = M_GetToken(NULL); if (animdefsToken == NULL) { - I_Error("Error parsing ANIMDEFS lump: Unexpected end of file where \"RANGE\" after \"%s\"'s startname should be", animdefs[*i].startname); + I_Error("Error parsing ANIMDEFS lump: Unexpected end of file where \"RANGE\" after \"%s\"'s startname should be", animdefs[i].startname); } if (stricmp(animdefsToken, "ALLOWDECALS") == 0) { @@ -470,7 +494,7 @@ void P_ParseAnimationDefintion(SINT8 istexture, INT32 *i) } if (stricmp(animdefsToken, "RANGE") != 0) { - I_Error("Error parsing ANIMDEFS lump: Expected \"RANGE\" after \"%s\"'s startname, got \"%s\"", animdefs[*i].startname, animdefsToken); + I_Error("Error parsing ANIMDEFS lump: Expected \"RANGE\" after \"%s\"'s startname, got \"%s\"", animdefs[i].startname, animdefsToken); } Z_Free(animdefsToken); @@ -478,21 +502,21 @@ void P_ParseAnimationDefintion(SINT8 istexture, INT32 *i) animdefsToken = M_GetToken(NULL); if (animdefsToken == NULL) { - I_Error("Error parsing ANIMDEFS lump: Unexpected end of file where \"%s\"'s end texture/flat name should be", animdefs[*i].startname); + I_Error("Error parsing ANIMDEFS lump: Unexpected end of file where \"%s\"'s end texture/flat name should be", animdefs[i].startname); } animdefsTokenLength = strlen(animdefsToken); if (animdefsTokenLength>8) { I_Error("Error parsing ANIMDEFS lump: lump name \"%s\" exceeds 8 characters", animdefsToken); } - strncpy(animdefs[*i].endname, animdefsToken, 9); + strncpy(animdefs[i].endname, animdefsToken, 9); Z_Free(animdefsToken); // "TICS" animdefsToken = M_GetToken(NULL); if (animdefsToken == NULL) { - I_Error("Error parsing ANIMDEFS lump: Unexpected end of file where \"%s\"'s \"TICS\" should be", animdefs[*i].startname); + I_Error("Error parsing ANIMDEFS lump: Unexpected end of file where \"%s\"'s \"TICS\" should be", animdefs[i].startname); } if (stricmp(animdefsToken, "RAND") == 0) { @@ -501,7 +525,7 @@ void P_ParseAnimationDefintion(SINT8 istexture, INT32 *i) } if (stricmp(animdefsToken, "TICS") != 0) { - I_Error("Error parsing ANIMDEFS lump: Expected \"TICS\" in animation definition for \"%s\", got \"%s\"", animdefs[*i].startname, animdefsToken); + I_Error("Error parsing ANIMDEFS lump: Expected \"TICS\" in animation definition for \"%s\", got \"%s\"", animdefs[i].startname, animdefsToken); } Z_Free(animdefsToken); @@ -509,7 +533,7 @@ void P_ParseAnimationDefintion(SINT8 istexture, INT32 *i) animdefsToken = M_GetToken(NULL); if (animdefsToken == NULL) { - I_Error("Error parsing ANIMDEFS lump: Unexpected end of file where \"%s\"'s animation speed should be", animdefs[*i].startname); + I_Error("Error parsing ANIMDEFS lump: Unexpected end of file where \"%s\"'s animation speed should be", animdefs[i].startname); } endPos = NULL; #ifndef AVOID_ERRNO @@ -523,13 +547,10 @@ void P_ParseAnimationDefintion(SINT8 istexture, INT32 *i) #endif || animSpeed < 0) // Number is not positive { - I_Error("Error parsing ANIMDEFS lump: Expected a positive integer for \"%s\"'s animation speed, got \"%s\"", animdefs[*i].startname, animdefsToken); + I_Error("Error parsing ANIMDEFS lump: Expected a positive integer for \"%s\"'s animation speed, got \"%s\"", animdefs[i].startname, animdefsToken); } - animdefs[*i].speed = animSpeed; + animdefs[i].speed = animSpeed; Z_Free(animdefsToken); - - // Increment i before we go, so this doesn't cause issues later - (*i)++; } From cdb841ef544f479cc4f9548e067f98d548987456 Mon Sep 17 00:00:00 2001 From: Yukita Mayako Date: Wed, 19 Oct 2016 03:22:11 -0400 Subject: [PATCH 14/35] Only P_InitPicAnims when wads are loaded. Not in P_SetupLevel. That's just dumb. --- src/p_setup.c | 7 +++---- src/r_data.c | 3 +++ 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index e56c44c7..f1d3a68c 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2587,10 +2587,6 @@ boolean P_SetupLevel(boolean skipprecip) R_ReInitColormaps(mapheaderinfo[gamemap-1]->palette); CON_ReSetupBackColormap(mapheaderinfo[gamemap-1]->palette); - // now part of level loading since in future each level may have - // its own anim texture sequences, switches etc. - P_InitPicAnims(); - // SRB2 determines the sky texture to be used depending on the map header. P_SetupLevelSky(mapheaderinfo[gamemap-1]->skynum, true); @@ -3001,6 +2997,9 @@ boolean P_AddWadFile(const char *wadfilename, char **firstmapname) else R_FlushTextureCache(); // just reload it from file + // Reload ANIMATED / ANIMDEFS + P_InitPicAnims(); + // Flush and reload HUD graphics ST_UnloadGraphics(); HU_LoadGraphics(); diff --git a/src/r_data.c b/src/r_data.c index cb5cf359..87b6b119 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -1499,6 +1499,9 @@ void R_InitData(void) CONS_Printf("R_LoadTextures()...\n"); R_LoadTextures(); + CONS_Printf("P_InitPicAnims()...\n"); + P_InitPicAnims(); + CONS_Printf("R_InitSprites()...\n"); R_InitSpriteLumps(); R_InitSprites(); From 8025ef2f79ec32e71053e7d9eaeb4e7f8c89972a Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sat, 29 Oct 2016 16:08:06 +0100 Subject: [PATCH 15/35] At MI's suggestion (shields don't NEED to be tweaked, just overlays) --- src/p_mobj.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index b35b7286..b3842da1 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -5930,8 +5930,6 @@ static boolean P_ShieldLook(mobj_t *thing, shieldtype_t shield) P_UnsetThingPosition(thing); thing->x = thing->target->x; thing->y = thing->target->y; - thing->radius = thing->target->radius; - thing->height = thing->target->height; if (thing->eflags & MFE_VERTICALFLIP) thing->z = thing->target->z + thing->target->height - thing->height + FixedDiv(P_GetPlayerHeight(thing->target->player) - thing->target->height, 3*FRACUNIT) - FixedMul(2*FRACUNIT, thing->target->scale); else From ff443251b18e666c8618e61a6fa052ba5ac0abed Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Thu, 27 Oct 2016 23:14:22 +0100 Subject: [PATCH 16/35] P_IsPointInSubsector now works in both Software and GL, which means it can be used as the main driver behind support for Knuckles climbing on one-sided walls. Also, the "teleport" devmode command can now gracefully handle coordinates specified outside maps with no/few thok barriers, which previously prevented teleport via the thok barrier bleed's sector floor and ceiling being equal. --- src/m_cheat.c | 2 +- src/p_user.c | 7 +++---- src/r_main.c | 5 +++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/m_cheat.c b/src/m_cheat.c index 89334596..3bbaadc5 100644 --- a/src/m_cheat.c +++ b/src/m_cheat.c @@ -452,7 +452,7 @@ void Command_RTeleport_f(void) else inty = 0; - ss = R_PointInSubsector(p->mo->x + intx*FRACUNIT, p->mo->y + inty*FRACUNIT); + ss = R_IsPointInSubsector(p->mo->x + intx*FRACUNIT, p->mo->y + inty*FRACUNIT); if (!ss || ss->sector->ceilingheight - ss->sector->floorheight < p->mo->height) { CONS_Alert(CONS_NOTICE, M_GetText("Not a valid location.\n")); diff --git a/src/p_user.c b/src/p_user.c index 3867137a..f8dc942c 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -2280,14 +2280,13 @@ static void P_DoClimbing(player_t *player) fixed_t platy; subsector_t *glidesector; boolean climb = true; - boolean onesided = ((player->lastsidehit != -1 && player->lastlinehit != -1) && !(lines[player->lastlinehit].backsector)); platx = P_ReturnThrustX(player->mo, player->mo->angle, player->mo->radius + FixedMul(8*FRACUNIT, player->mo->scale)); platy = P_ReturnThrustY(player->mo, player->mo->angle, player->mo->radius + FixedMul(8*FRACUNIT, player->mo->scale)); - glidesector = R_PointInSubsector(player->mo->x + platx, player->mo->y + platy); + glidesector = R_IsPointInSubsector(player->mo->x + platx, player->mo->y + platy); - if (onesided || glidesector->sector != player->mo->subsector->sector) + if (!glidesector || glidesector->sector != player->mo->subsector->sector) { boolean floorclimb = false; boolean thrust = false; @@ -2295,7 +2294,7 @@ static void P_DoClimbing(player_t *player) boolean skyclimber = false; fixed_t floorheight, ceilingheight; // ESLOPE - if (onesided) + if (!glidesector) floorclimb = true; else { diff --git a/src/r_main.c b/src/r_main.c index 498f4dab..1b4322b4 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -771,7 +771,7 @@ subsector_t *R_PointInSubsector(fixed_t x, fixed_t y) } // -// R_IsPointInSubsector, same as above but returns 0 if not in subsector - this does not work in opengl because of polyvertex_t +// R_IsPointInSubsector, same as above but returns 0 if not in subsector // subsector_t *R_IsPointInSubsector(fixed_t x, fixed_t y) { @@ -795,7 +795,8 @@ subsector_t *R_IsPointInSubsector(fixed_t x, fixed_t y) ret = &subsectors[nodenum & ~NF_SUBSECTOR]; for (i = 0; i < ret->numlines; i++) - if (R_PointOnSegSide(x, y, &segs[ret->firstline + i])) + //if (R_PointOnSegSide(x, y, &segs[ret->firstline + i])) -- breaks in ogl because polyvertex_t cast over vertex pointers + if (P_PointOnLineSide(x, y, segs[ret->firstline + i].linedef) != segs[ret->firstline + i].side) return 0; return ret; From ab6fd676b5d42b1446ba4a6961abce6093a8422a Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Thu, 27 Oct 2016 23:41:24 +0100 Subject: [PATCH 17/35] YUP, I just fixed OGL Precipitation with this branch too. What the fuck? Squashing ancient bugs, woo. --- src/hardware/hw_main.c | 48 ++++++++++++++++++++++++++++++------------ 1 file changed, 35 insertions(+), 13 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 5251e0b3..a107ecd3 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -45,7 +45,7 @@ #include "hw_md2.h" #define R_FAKEFLOORS -//#define HWPRECIP +#define HWPRECIP #define SORTING //#define POLYSKY @@ -4401,7 +4401,6 @@ static inline void HWR_DrawPrecipitationSprite(gr_vissprite_t *spr) FOutVector *wv; GLPatch_t *gpatch; // sprite patch converted to hardware FSurfaceInfo Surf; - sector_t *sector; if (!spr->mobj) return; @@ -4455,19 +4454,38 @@ static inline void HWR_DrawPrecipitationSprite(gr_vissprite_t *spr) //Hurdler: 25/04/2000: now support colormap in hardware mode HWR_GetMappedPatch(gpatch, spr->colormap); - sector = spr->mobj->subsector->sector; - - if (sector->ffloors) + // colormap test { - ffloor_t *caster = sector->lightlist[R_GetPlaneLight(sector, spr->mobj->z, false)].caster; - sector = caster ? §ors[caster->secnum] : sector; - } + sector_t *sector = spr->mobj->subsector->sector; + UINT8 lightlevel = 255; + extracolormap_t *colormap = sector->extra_colormap; - // sprite lighting by modulating the RGB components - if (sector->extra_colormap) - Surf.FlatColor.rgba = HWR_Lighting(spr->sectorlight,sector->extra_colormap->rgba,sector->extra_colormap->fadergba, false, false); + if (sector->numlights) + { + INT32 light; + + light = R_GetPlaneLight(sector, spr->mobj->z + spr->mobj->height, false); // Always use the light at the top instead of whatever I was doing before + + if (!(spr->mobj->frame & FF_FULLBRIGHT)) + lightlevel = *sector->lightlist[light].lightlevel; + + if (sector->lightlist[light].extra_colormap) + colormap = sector->lightlist[light].extra_colormap; + } else - Surf.FlatColor.rgba = HWR_Lighting(spr->sectorlight,NORMALFOG,FADEFOG, false, false); + { + if (!(spr->mobj->frame & FF_FULLBRIGHT)) + lightlevel = sector->lightlevel; + + if (sector->extra_colormap) + colormap = sector->extra_colormap; + } + + if (colormap) + Surf.FlatColor.rgba = HWR_Lighting(lightlevel, colormap->rgba, colormap->fadergba, false, false); + else + Surf.FlatColor.rgba = HWR_Lighting(lightlevel, NORMALFOG, FADEFOG, false, false); + } if (spr->mobj->flags2 & MF2_SHADOW) { @@ -5289,6 +5307,11 @@ static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing) // vis = HWR_NewVisSprite(); vis->x1 = x1; +#if 0 + vis->x2 = x2; +#else + (void)x2; +#endif vis->x2 = tx; vis->tz = tz; vis->dispoffset = 0; // Monster Iestyn: 23/11/15: HARDWARE SUPPORT AT LAST @@ -5301,7 +5324,6 @@ static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing) // set top/bottom coords vis->ty = FIXED_TO_FLOAT(thing->z + spritecachedinfo[lumpoff].topoffset) - gr_viewz; - vis->sectorlight = 0xff; vis->precip = true; } #endif From 31d569a15b002d2555ac16940bae118e3096f0af Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sat, 29 Oct 2016 18:12:41 +0100 Subject: [PATCH 18/35] No more changing skins when you're in singleplayer and manage to enter a hole in the gamestate defenses! --- src/d_netcmd.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 4f73a256..7fd10d08 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -4062,8 +4062,7 @@ static void Skin_OnChange(void) if (!Playing()) return; // do whatever you want - if (!(cv_debug || devparm) && !(multiplayer || netgame) // In single player. - && (gamestate == GS_LEVEL || gamestate == GS_INTERMISSION || gamestate == GS_CONTINUING)) + if (!(cv_debug || devparm) && !(multiplayer || netgame)) // In single player. { CV_StealthSet(&cv_skin, skins[players[consoleplayer].skin].name); return; From f5f25428499698d70adaa2f31ff8a471216e1e3f Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Wed, 16 Nov 2016 17:50:44 +0000 Subject: [PATCH 19/35] Go through all the polyobjects to find leftover polyobj planes to add to the draw nodes list I'm convinced there's going to be some stupid side effects from doing this, but it's the quickest way I can fix the polyobj planes not all appearing anyway --- src/r_things.c | 36 +++++++++++++++++++++++++++++++----- 1 file changed, 31 insertions(+), 5 deletions(-) diff --git a/src/r_things.c b/src/r_things.c index ed1ddeab..927217c5 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -1760,6 +1760,29 @@ static void R_CreateDrawNodes(void) } } +#ifdef POLYOBJECTS_PLANES + // find all the remaining polyobject planes and add them on the end of the list + // probably this is a terrible idea if we wanted them to be sorted properly + // but it works getting them in for now + for (i = 0; i < numPolyObjects; i++) + { + if (!PolyObjects[i].visplane) + continue; + plane = PolyObjects[i].visplane; + R_PlaneBounds(plane); + + if (plane->low < con_clipviewtop || plane->high > vid.height || plane->high > plane->low) + { + PolyObjects[i].visplane = NULL; + continue; + } + entry = R_CreateDrawNode(&nodehead); + entry->plane = plane; + // note: no seg is set, for what should be obvious reasons + PolyObjects[i].visplane = NULL; + } +#endif + if (visspritecount == 0) return; @@ -1816,13 +1839,16 @@ static void R_CreateDrawNodes(void) if (x1 < r2->plane->minx) x1 = r2->plane->minx; if (x2 > r2->plane->maxx) x2 = r2->plane->maxx; - for (i = x1; i <= x2; i++) + if (r2->seg) // if no seg set, assume the whole thing is in front or something stupid { - if (r2->seg->frontscale[i] > rover->scale) - break; + for (i = x1; i <= x2; i++) + { + if (r2->seg->frontscale[i] > rover->scale) + break; + } + if (i > x2) + continue; } - if (i > x2) - continue; entry = R_CreateDrawNode(NULL); (entry->prev = r2->prev)->next = entry; From 02d78b355bf9dacd3e740d3535921541d9c6b70d Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Thu, 1 Dec 2016 14:33:44 +0000 Subject: [PATCH 20/35] Smoother ropes and zoom tubes ported from internal. --- src/p_user.c | 82 ++++++++++++++++++++-------------------------------- 1 file changed, 31 insertions(+), 51 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index f8dc942c..cb523585 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -7057,7 +7057,6 @@ static void P_DoZoomTube(player_t *player) mobj_t *waypoint = NULL; fixed_t dist; boolean reverse; - fixed_t speedx,speedy,speedz; player->mo->height = P_GetPlayerSpinHeight(player); @@ -7078,17 +7077,17 @@ static void P_DoZoomTube(player_t *player) if (dist < 1) dist = 1; - speedx = FixedMul(FixedDiv(player->mo->tracer->x - player->mo->x, dist), (speed)); - speedy = FixedMul(FixedDiv(player->mo->tracer->y - player->mo->y, dist), (speed)); - speedz = FixedMul(FixedDiv(player->mo->tracer->z - player->mo->z, dist), (speed)); + player->mo->momx = FixedMul(FixedDiv(player->mo->tracer->x - player->mo->x, dist), (speed)); + player->mo->momy = FixedMul(FixedDiv(player->mo->tracer->y - player->mo->y, dist), (speed)); + player->mo->momz = FixedMul(FixedDiv(player->mo->tracer->z - player->mo->z, dist), (speed)); // Calculate the distance between the player and the waypoint // 'dist' already equals this. - // Will the player be FURTHER away if the momx/momy/momz is added to - // his current coordinates, or closer? (shift down to fracunits to avoid approximation errors) - if (dist>>FRACBITS <= P_AproxDistance(P_AproxDistance(player->mo->tracer->x - player->mo->x - speedx, player->mo->tracer->y - player->mo->y - speedy), player->mo->tracer->z - player->mo->z - speedz)>>FRACBITS) + // Will the player go past the waypoint? + if (speed > dist) { + speed -= dist; // If further away, set XYZ of player to waypoint location P_UnsetThingPosition(player->mo); player->mo->x = player->mo->tracer->x; @@ -7128,14 +7127,9 @@ static void P_DoZoomTube(player_t *player) { CONS_Debug(DBG_GAMELOGIC, "Found waypoint (sequence %d, number %d).\n", waypoint->threshold, waypoint->health); - // calculate MOMX/MOMY/MOMZ for next waypoint - // change angle - player->mo->angle = R_PointToAngle2(player->mo->x, player->mo->y, player->mo->tracer->x, player->mo->tracer->y); + P_SetTarget(&player->mo->tracer, waypoint); - if (player == &players[consoleplayer]) - localangle = player->mo->angle; - else if (player == &players[secondarydisplayplayer]) - localangle2 = player->mo->angle; + // calculate MOMX/MOMY/MOMZ for next waypoint // change slope dist = P_AproxDistance(P_AproxDistance(player->mo->tracer->x - player->mo->x, player->mo->tracer->y - player->mo->y), player->mo->tracer->z - player->mo->z); @@ -7146,22 +7140,14 @@ static void P_DoZoomTube(player_t *player) player->mo->momx = FixedMul(FixedDiv(player->mo->tracer->x - player->mo->x, dist), (speed)); player->mo->momy = FixedMul(FixedDiv(player->mo->tracer->y - player->mo->y, dist), (speed)); player->mo->momz = FixedMul(FixedDiv(player->mo->tracer->z - player->mo->z, dist), (speed)); - - P_SetTarget(&player->mo->tracer, waypoint); } else { - P_SetTarget(&player->mo->tracer, NULL); // Else, we just let him fly. + P_SetTarget(&player->mo->tracer, NULL); // Else, we just let them fly. CONS_Debug(DBG_GAMELOGIC, "Next waypoint not found, releasing from track...\n"); } } - else - { - player->mo->momx = speedx; - player->mo->momy = speedy; - player->mo->momz = speedz; - } // change angle if (player->mo->tracer) @@ -7189,24 +7175,10 @@ static void P_DoRopeHang(player_t *player) mobj_t *mo2; mobj_t *waypoint = NULL; fixed_t dist; - fixed_t speedx,speedy,speedz; fixed_t playerz; player->mo->height = P_GetPlayerHeight(player); - if (player->cmd.buttons & BT_USE && !(player->pflags & PF_STASIS)) // Drop off of the rope - { - P_SetTarget(&player->mo->tracer, NULL); - - player->pflags |= PF_JUMPED; - player->pflags &= ~PF_ROPEHANG; - - if (!(player->pflags & PF_SLIDING) && (player->pflags & PF_JUMPED) - && !(player->panim == PA_ROLL) && player->charability2 == CA2_SPINDASH) - P_SetPlayerMobjState(player->mo, S_PLAY_ATK1); - return; - } - // Play the 'clink' sound only if the player is moving. if (!(leveltime & 7) && player->speed) S_StartSound(player->mo, sfx_s3k55); @@ -7223,9 +7195,22 @@ static void P_DoRopeHang(player_t *player) if (dist < 1) dist = 1; - speedx = FixedMul(FixedDiv(player->mo->tracer->x - player->mo->x, dist), (speed)); - speedy = FixedMul(FixedDiv(player->mo->tracer->y - player->mo->y, dist), (speed)); - speedz = FixedMul(FixedDiv(player->mo->tracer->z - playerz, dist), (speed)); + player->mo->momx = FixedMul(FixedDiv(player->mo->tracer->x - player->mo->x, dist), (speed)); + player->mo->momy = FixedMul(FixedDiv(player->mo->tracer->y - player->mo->y, dist), (speed)); + player->mo->momz = FixedMul(FixedDiv(player->mo->tracer->z - playerz, dist), (speed)); + + if (player->cmd.buttons & BT_USE && !(player->pflags & PF_STASIS)) // Drop off of the rope + { + P_SetTarget(&player->mo->tracer, NULL); + + player->pflags |= PF_JUMPED; + player->pflags &= ~PF_ROPEHANG; + + if (!(player->pflags & PF_SLIDING) && (player->pflags & PF_JUMPED) + && !(player->panim == PA_ROLL) && player->charability2 == CA2_SPINDASH) + P_SetPlayerMobjState(player->mo, S_PLAY_ATK1); + return; + } // If not allowed to move, we're done here. if (!speed) @@ -7234,15 +7219,16 @@ static void P_DoRopeHang(player_t *player) // Calculate the distance between the player and the waypoint // 'dist' already equals this. - // Will the player be FURTHER away if the momx/momy/momz is added to - // his current coordinates, or closer? (shift down to fracunits to avoid approximation errors) - if (dist>>FRACBITS <= P_AproxDistance(P_AproxDistance(player->mo->tracer->x - player->mo->x - speedx, player->mo->tracer->y - player->mo->y - speedy), player->mo->tracer->z - playerz - speedz)>>FRACBITS) + // Will the player go past the waypoint? + if (speed > dist) { + speed -= dist; // If further away, set XYZ of player to waypoint location P_UnsetThingPosition(player->mo); player->mo->x = player->mo->tracer->x; player->mo->y = player->mo->tracer->y; player->mo->z = player->mo->tracer->z - player->mo->height; + playerz = player->mo->tracer->z; P_SetThingPosition(player->mo); CONS_Debug(DBG_GAMELOGIC, "Looking for next waypoint...\n"); @@ -7298,6 +7284,8 @@ static void P_DoRopeHang(player_t *player) { CONS_Debug(DBG_GAMELOGIC, "Found waypoint (sequence %d, number %d).\n", waypoint->threshold, waypoint->health); + P_SetTarget(&player->mo->tracer, waypoint); + // calculate MOMX/MOMY/MOMZ for next waypoint // change slope dist = P_AproxDistance(P_AproxDistance(player->mo->tracer->x - player->mo->x, player->mo->tracer->y - player->mo->y), player->mo->tracer->z - playerz); @@ -7308,8 +7296,6 @@ static void P_DoRopeHang(player_t *player) player->mo->momx = FixedMul(FixedDiv(player->mo->tracer->x - player->mo->x, dist), (speed)); player->mo->momy = FixedMul(FixedDiv(player->mo->tracer->y - player->mo->y, dist), (speed)); player->mo->momz = FixedMul(FixedDiv(player->mo->tracer->z - playerz, dist), (speed)); - - P_SetTarget(&player->mo->tracer, waypoint); } else { @@ -7328,12 +7314,6 @@ static void P_DoRopeHang(player_t *player) CONS_Debug(DBG_GAMELOGIC, "Next waypoint not found!\n"); } } - else - { - player->mo->momx = speedx; - player->mo->momy = speedy; - player->mo->momz = speedz; - } } #if 0 From 7c07f39019723c0784a6bea2f8df61f5e7432c47 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Mon, 5 Dec 2016 22:07:16 +0000 Subject: [PATCH 21/35] Make sure flipped things placed directly on ceiling get MFE_ONGROUND This fixes ceiling springs apparently flying down with you in various scenarios --- src/p_mobj.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/p_mobj.c b/src/p_mobj.c index e7ec2f8b..6a3ac9ee 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -7685,6 +7685,10 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) if (mobj->type == MT_UNIDUS) mobj->z -= FixedMul(mobj->info->mass, mobj->scale); + + // defaults onground + if (mobj->z + mobj->height == mobj->ceilingz) + mobj->eflags |= MFE_ONGROUND; } else mobj->z = z; From d294c9d15c3d91354edb9ea7db27b52fc6d3ede0 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Thu, 8 Dec 2016 21:45:25 +0000 Subject: [PATCH 22/35] P_NetUnArchiveWorld now uses P_AddLevelFlatRuntime instead of P_AddLevelFlat. Also created P_CheckLevelFlat to just return the flat # from a name, since that's all P_NetArchiveWorld really needed from P_AddLevelFlat anyway --- src/lua_maplib.c | 40 ------------------------------ src/p_saveg.c | 9 +++---- src/p_setup.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++ src/p_setup.h | 2 ++ 4 files changed, 69 insertions(+), 45 deletions(-) diff --git a/src/lua_maplib.c b/src/lua_maplib.c index c512bf3c..54614c4e 100644 --- a/src/lua_maplib.c +++ b/src/lua_maplib.c @@ -400,46 +400,6 @@ static int sector_get(lua_State *L) return 0; } -// help function for P_LoadSectors, find a flat in the active wad files, -// allocate an id for it, and set the levelflat (to speedup search) -// -static INT32 P_AddLevelFlatRuntime(const char *flatname) -{ - size_t i; - levelflat_t *levelflat = levelflats; - - // - // first scan through the already found flats - // - for (i = 0; i < numlevelflats; i++, levelflat++) - if (strnicmp(levelflat->name,flatname,8)==0) - break; - - // that flat was already found in the level, return the id - if (i == numlevelflats) - { - // allocate new flat memory - levelflats = Z_Realloc(levelflats, (numlevelflats + 1) * sizeof(*levelflats), PU_LEVEL, NULL); - levelflat = levelflats+i; - - // store the name - strlcpy(levelflat->name, flatname, sizeof (levelflat->name)); - strupr(levelflat->name); - - // store the flat lump number - levelflat->lumpnum = R_GetFlatNumForName(flatname); - -#ifndef ZDEBUG - CONS_Debug(DBG_SETUP, "flat #%03d: %s\n", atoi(sizeu1(numlevelflats)), levelflat->name); -#endif - - numlevelflats++; - } - - // level flat id - return (INT32)i; -} - static int sector_set(lua_State *L) { sector_t *sector = *((sector_t **)luaL_checkudata(L, 1, META_SECTOR)); diff --git a/src/p_saveg.c b/src/p_saveg.c index 5e457ca3..2144a3f9 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -509,10 +509,9 @@ static void P_NetArchiveWorld(void) // // flats // - // P_AddLevelFlat should not add but just return the number - if (ss->floorpic != P_AddLevelFlat(ms->floorpic, levelflats)) + if (ss->floorpic != P_CheckLevelFlat(ms->floorpic)) diff |= SD_FLOORPIC; - if (ss->ceilingpic != P_AddLevelFlat(ms->ceilingpic, levelflats)) + if (ss->ceilingpic != P_CheckLevelFlat(ms->ceilingpic)) diff |= SD_CEILPIC; if (ss->lightlevel != SHORT(ms->lightlevel)) @@ -752,12 +751,12 @@ static void P_NetUnArchiveWorld(void) sectors[i].ceilingheight = READFIXED(get); if (diff & SD_FLOORPIC) { - sectors[i].floorpic = P_AddLevelFlat((char *)get, levelflats); + sectors[i].floorpic = P_AddLevelFlatRuntime((char *)get); get += 8; } if (diff & SD_CEILPIC) { - sectors[i].ceilingpic = P_AddLevelFlat((char *)get, levelflats); + sectors[i].ceilingpic = P_AddLevelFlatRuntime((char *)get); get += 8; } if (diff & SD_LIGHT) diff --git a/src/p_setup.c b/src/p_setup.c index d6563735..ae6aa153 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -574,6 +574,69 @@ INT32 P_AddLevelFlat(const char *flatname, levelflat_t *levelflat) return (INT32)i; } +// help function for Lua and $$$.sav reading +// same as P_AddLevelFlat, except this is not setup so we must realloc levelflats to fit in the new flat +// no longer a static func in lua_maplib.c because p_saveg.c also needs it +// +INT32 P_AddLevelFlatRuntime(const char *flatname) +{ + size_t i; + levelflat_t *levelflat = levelflats; + + // + // first scan through the already found flats + // + for (i = 0; i < numlevelflats; i++, levelflat++) + if (strnicmp(levelflat->name,flatname,8)==0) + break; + + // that flat was already found in the level, return the id + if (i == numlevelflats) + { + // allocate new flat memory + levelflats = Z_Realloc(levelflats, (numlevelflats + 1) * sizeof(*levelflats), PU_LEVEL, NULL); + levelflat = levelflats+i; + + // store the name + strlcpy(levelflat->name, flatname, sizeof (levelflat->name)); + strupr(levelflat->name); + + // store the flat lump number + levelflat->lumpnum = R_GetFlatNumForName(flatname); + +#ifndef ZDEBUG + CONS_Debug(DBG_SETUP, "flat #%03d: %s\n", atoi(sizeu1(numlevelflats)), levelflat->name); +#endif + + numlevelflats++; + } + + // level flat id + return (INT32)i; +} + +// help function for $$$.sav checking +// this simply returns the flat # for the name given +// +INT32 P_CheckLevelFlat(const char *flatname) +{ + size_t i; + levelflat_t *levelflat = levelflats; + + // + // scan through the already found flats + // + for (i = 0; i < numlevelflats; i++, levelflat++) + if (strnicmp(levelflat->name,flatname,8)==0) + break; + + if (i == numlevelflats) + return 0; // ??? flat was not found, this should not happen! + + // level flat id + return (INT32)i; +} + static void P_LoadSectors(lumpnum_t lumpnum) { UINT8 *data; diff --git a/src/p_setup.h b/src/p_setup.h index 0d735fd7..3bca1104 100644 --- a/src/p_setup.h +++ b/src/p_setup.h @@ -47,6 +47,8 @@ typedef struct extern size_t numlevelflats; extern levelflat_t *levelflats; INT32 P_AddLevelFlat(const char *flatname, levelflat_t *levelflat); +INT32 P_AddLevelFlatRuntime(const char *flatname); +INT32 P_CheckLevelFlat(const char *flatname); extern size_t nummapthings; extern mapthing_t *mapthings; From ab423f99c6abf7cddb88e4e2dbf5475d7545d114 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Fri, 9 Dec 2016 21:18:06 +0000 Subject: [PATCH 23/35] Optimising retrieval of sector_floorpic/ceilingpic As LJSonic has pointed out, there's no need for a for loop in either case; just use sector->floorpic/ceilingpic as a levelflats index directly (Besides, if that was to stop any out-of-bounds indexes being used, that's hardly the way to do it anyway) --- src/lua_maplib.c | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/src/lua_maplib.c b/src/lua_maplib.c index 54614c4e..208aebe3 100644 --- a/src/lua_maplib.c +++ b/src/lua_maplib.c @@ -348,22 +348,12 @@ static int sector_get(lua_State *L) case sector_ceilingheight: lua_pushfixed(L, sector->ceilingheight); return 1; - case sector_floorpic: { // floorpic - levelflat_t *levelflat; - INT16 i; - for (i = 0, levelflat = levelflats; i != sector->floorpic; i++, levelflat++) - ; - lua_pushlstring(L, levelflat->name, 8); + case sector_floorpic: // floorpic + lua_pushlstring(L, levelflats[sector->floorpic].name, 8); return 1; - } - case sector_ceilingpic: { // ceilingpic - levelflat_t *levelflat; - INT16 i; - for (i = 0, levelflat = levelflats; i != sector->ceilingpic; i++, levelflat++) - ; - lua_pushlstring(L, levelflat->name, 8); + case sector_ceilingpic: // ceilingpic + lua_pushlstring(L, levelflats[sector->ceilingpic].name, 8); return 1; - } case sector_lightlevel: lua_pushinteger(L, sector->lightlevel); return 1; From 93901847d3e6d35577e97d2d7026e8ae586cefb5 Mon Sep 17 00:00:00 2001 From: Sryder Date: Mon, 12 Dec 2016 00:06:48 +0000 Subject: [PATCH 24/35] Fix the Fixed Rounding functions --- src/m_fixed.h | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/src/m_fixed.h b/src/m_fixed.h index 70402f27..d7db9bf2 100644 --- a/src/m_fixed.h +++ b/src/m_fixed.h @@ -283,9 +283,16 @@ FUNCMATH FUNCINLINE static ATTRINLINE fixed_t FixedFloor(fixed_t x) { const fixed_t a = abs(x); //absolute of x const fixed_t i = (a>>FRACBITS)< 0) + return x-f; + else + return x-(FRACUNIT-f); + } return INT32_MIN; } @@ -301,7 +308,7 @@ FUNCMATH FUNCINLINE static ATTRINLINE fixed_t FixedTrunc(fixed_t x) { const fixed_t a = abs(x); //absolute of x const fixed_t i = (a>>FRACBITS)< 0) @@ -324,11 +331,18 @@ FUNCMATH FUNCINLINE static ATTRINLINE fixed_t FixedCeil(fixed_t x) { const fixed_t a = abs(x); //absolute of x const fixed_t i = (a>>FRACBITS)< 0) + return x+(FRACUNIT-f); + else + return x+f; + } return INT32_MAX; } @@ -344,7 +358,9 @@ FUNCMATH FUNCINLINE static ATTRINLINE fixed_t FixedRound(fixed_t x) { const fixed_t a = abs(x); //absolute of x const fixed_t i = (a>>FRACBITS)< Date: Fri, 16 Dec 2016 21:38:53 +0000 Subject: [PATCH 25/35] Created R_GetTextureNum to make sure top/bottom/midtexture texture ids are always valid in rendering code for both software and OpenGL (and also for the Solid Midtexture effect physics code) --- src/hardware/hw_main.c | 36 ++++++++------ src/p_maputl.c | 77 +++++++++++++++-------------- src/r_data.c | 14 ++++++ src/r_data.h | 2 + src/r_segs.c | 108 ++++++++++++++++------------------------- 5 files changed, 118 insertions(+), 119 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 5251e0b3..948965db 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -1558,6 +1558,7 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) if (gr_backsector) { + INT32 gr_toptexture, gr_bottomtexture; // two sided line if (gr_backsector->heightsec != -1) { @@ -1608,19 +1609,22 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) #endif } + gr_toptexture = R_GetTextureNum(gr_sidedef->toptexture); + gr_bottomtexture = R_GetTextureNum(gr_sidedef->bottomtexture); + // check TOP TEXTURE if (( #ifdef ESLOPE worldhighslope < worldtopslope || #endif worldhigh < worldtop - ) && texturetranslation[gr_sidedef->toptexture]) + ) && gr_toptexture) { if (drawtextured) { fixed_t texturevpegtop; // top - grTex = HWR_GetTexture(texturetranslation[gr_sidedef->toptexture]); + grTex = HWR_GetTexture(gr_toptexture); // PEGGING if (gr_linedef->flags & ML_DONTPEGTOP) @@ -1638,7 +1642,7 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) texturevpegtop += gr_sidedef->rowoffset; // 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 - texturevpegtop %= SHORT(textures[texturetranslation[gr_sidedef->toptexture]]->height)<height)<scaleY; wallVerts[0].t = wallVerts[1].t = (texturevpegtop + gr_frontsector->ceilingheight - gr_backsector->ceilingheight) * grTex->scaleY; @@ -1683,9 +1687,9 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) #endif if (gr_frontsector->numlights) - HWR_SplitWall(gr_frontsector, wallVerts, texturetranslation[gr_sidedef->toptexture], &Surf, FF_CUTSOLIDS); + HWR_SplitWall(gr_frontsector, wallVerts, gr_toptexture, &Surf, FF_CUTSOLIDS); else if (grTex->mipmap.flags & TF_TRANSPARENT) - HWR_AddTransparentWall(wallVerts, &Surf, texturetranslation[gr_sidedef->toptexture], PF_Environment, false, lightnum, colormap); + HWR_AddTransparentWall(wallVerts, &Surf, gr_toptexture, PF_Environment, false, lightnum, colormap); else HWR_ProjectWall(wallVerts, &Surf, PF_Masked, lightnum, colormap); } @@ -1695,13 +1699,13 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) #ifdef ESLOPE worldlowslope > worldbottomslope || #endif - worldlow > worldbottom) && texturetranslation[gr_sidedef->bottomtexture]) //only if VISIBLE!!! + worldlow > worldbottom) && gr_bottomtexture) //only if VISIBLE!!! { if (drawtextured) { fixed_t texturevpegbottom = 0; // bottom - grTex = HWR_GetTexture(texturetranslation[gr_sidedef->bottomtexture]); + grTex = HWR_GetTexture(gr_bottomtexture); // PEGGING #ifdef ESLOPE @@ -1721,7 +1725,7 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) texturevpegbottom += gr_sidedef->rowoffset; // 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 - texturevpegbottom %= SHORT(textures[texturetranslation[gr_sidedef->bottomtexture]]->height)<height)<scaleY; wallVerts[0].t = wallVerts[1].t = (texturevpegbottom + gr_backsector->floorheight - gr_frontsector->floorheight) * grTex->scaleY; @@ -1766,13 +1770,13 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) #endif if (gr_frontsector->numlights) - HWR_SplitWall(gr_frontsector, wallVerts, texturetranslation[gr_sidedef->bottomtexture], &Surf, FF_CUTSOLIDS); + HWR_SplitWall(gr_frontsector, wallVerts, gr_bottomtexture, &Surf, FF_CUTSOLIDS); else if (grTex->mipmap.flags & TF_TRANSPARENT) - HWR_AddTransparentWall(wallVerts, &Surf, texturetranslation[gr_sidedef->bottomtexture], PF_Environment, false, lightnum, colormap); + HWR_AddTransparentWall(wallVerts, &Surf, gr_bottomtexture, PF_Environment, false, lightnum, colormap); else HWR_ProjectWall(wallVerts, &Surf, PF_Masked, lightnum, colormap); } - gr_midtexture = texturetranslation[gr_sidedef->midtexture]; + gr_midtexture = R_GetTextureNum(gr_sidedef->midtexture); if (gr_midtexture) { FBITFIELD blendmode; @@ -2134,7 +2138,7 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) else { // Single sided line... Deal only with the middletexture (if one exists) - gr_midtexture = texturetranslation[gr_sidedef->midtexture]; + gr_midtexture = R_GetTextureNum(gr_sidedef->midtexture); if (gr_midtexture) { if (drawtextured) @@ -2232,13 +2236,13 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) if (*rover->topheight < lowcut || *rover->bottomheight > highcut) continue; - texnum = texturetranslation[sides[rover->master->sidenum[0]].midtexture]; + texnum = R_GetTextureNum(sides[rover->master->sidenum[0]].midtexture); if (rover->master->flags & ML_TFERLINE) { size_t linenum = gr_curline->linedef-gr_backsector->lines[0]; newline = rover->master->frontsector->lines[0] + linenum; - texnum = texturetranslation[sides[newline->sidenum[0]].midtexture]; + texnum = R_GetTextureNum(sides[newline->sidenum[0]].midtexture); } #ifdef ESLOPE @@ -2366,13 +2370,13 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) if (*rover->topheight < lowcut || *rover->bottomheight > highcut) continue; - texnum = texturetranslation[sides[rover->master->sidenum[0]].midtexture]; + texnum = R_GetTextureNum(sides[rover->master->sidenum[0]].midtexture); if (rover->master->flags & ML_TFERLINE) { size_t linenum = gr_curline->linedef-gr_backsector->lines[0]; newline = rover->master->frontsector->lines[0] + linenum; - texnum = texturetranslation[sides[newline->sidenum[0]].midtexture]; + texnum = R_GetTextureNum(sides[newline->sidenum[0]].midtexture); } #ifdef ESLOPE //backsides h = *rover->t_slope ? P_GetZAt(*rover->t_slope, v1x, v1y) : *rover->topheight; diff --git a/src/p_maputl.c b/src/p_maputl.c index fea8530a..46b03338 100644 --- a/src/p_maputl.c +++ b/src/p_maputl.c @@ -572,51 +572,54 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj) side_t *side = &sides[linedef->sidenum[0]]; fixed_t textop, texbottom, texheight; fixed_t texmid, delta1, delta2; + INT32 texnum = R_GetTextureNum(side->midtexture); // make sure the texture is actually valid - // Get the midtexture's height - texheight = textures[texturetranslation[side->midtexture]]->height << FRACBITS; + if (texnum) { + // Get the midtexture's height + texheight = textures[texnum]->height << FRACBITS; - // Set texbottom and textop to the Z coordinates of the texture's boundaries + // Set texbottom and textop to the Z coordinates of the texture's boundaries #if 0 // #ifdef POLYOBJECTS - // don't remove this code unless solid midtextures - // on non-solid polyobjects should NEVER happen in the future - if (linedef->polyobj && (linedef->polyobj->flags & POF_TESTHEIGHT)) { - if (linedef->flags & ML_EFFECT5 && !side->repeatcnt) { // "infinite" repeat - texbottom = back->floorheight + side->rowoffset; - textop = back->ceilingheight + side->rowoffset; - } else if (!!(linedef->flags & ML_DONTPEGBOTTOM) ^ !!(linedef->flags & ML_EFFECT3)) { - texbottom = back->floorheight + side->rowoffset; - textop = texbottom + texheight*(side->repeatcnt+1); - } else { - textop = back->ceilingheight + side->rowoffset; - texbottom = textop - texheight*(side->repeatcnt+1); - } - } else + // don't remove this code unless solid midtextures + // on non-solid polyobjects should NEVER happen in the future + if (linedef->polyobj && (linedef->polyobj->flags & POF_TESTHEIGHT)) { + if (linedef->flags & ML_EFFECT5 && !side->repeatcnt) { // "infinite" repeat + texbottom = back->floorheight + side->rowoffset; + textop = back->ceilingheight + side->rowoffset; + } else if (!!(linedef->flags & ML_DONTPEGBOTTOM) ^ !!(linedef->flags & ML_EFFECT3)) { + texbottom = back->floorheight + side->rowoffset; + textop = texbottom + texheight*(side->repeatcnt+1); + } else { + textop = back->ceilingheight + side->rowoffset; + texbottom = textop - texheight*(side->repeatcnt+1); + } + } else #endif - { - if (linedef->flags & ML_EFFECT5 && !side->repeatcnt) { // "infinite" repeat - texbottom = openbottom + side->rowoffset; - textop = opentop + side->rowoffset; - } else if (!!(linedef->flags & ML_DONTPEGBOTTOM) ^ !!(linedef->flags & ML_EFFECT3)) { - texbottom = openbottom + side->rowoffset; - textop = texbottom + texheight*(side->repeatcnt+1); - } else { - textop = opentop + side->rowoffset; - texbottom = textop - texheight*(side->repeatcnt+1); + { + if (linedef->flags & ML_EFFECT5 && !side->repeatcnt) { // "infinite" repeat + texbottom = openbottom + side->rowoffset; + textop = opentop + side->rowoffset; + } else if (!!(linedef->flags & ML_DONTPEGBOTTOM) ^ !!(linedef->flags & ML_EFFECT3)) { + texbottom = openbottom + side->rowoffset; + textop = texbottom + texheight*(side->repeatcnt+1); + } else { + textop = opentop + side->rowoffset; + texbottom = textop - texheight*(side->repeatcnt+1); + } } - } - texmid = texbottom+(textop-texbottom)/2; + texmid = texbottom+(textop-texbottom)/2; - delta1 = abs(mobj->z - texmid); - delta2 = abs(thingtop - texmid); + delta1 = abs(mobj->z - texmid); + delta2 = abs(thingtop - texmid); - if (delta1 > delta2) { // Below - if (opentop > texbottom) - opentop = texbottom; - } else { // Above - if (openbottom < textop) - openbottom = textop; + if (delta1 > delta2) { // Below + if (opentop > texbottom) + opentop = texbottom; + } else { // Above + if (openbottom < textop) + openbottom = textop; + } } } diff --git a/src/r_data.c b/src/r_data.c index cb5cf359..c24cca91 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -303,6 +303,20 @@ done: return blocktex; } +// +// R_GetTextureNum +// +// Returns the actual texture id that we should use. +// This can either be texnum, the current frame for texnum's anim (if animated), +// or 0 if not valid. +// +INT32 R_GetTextureNum(INT32 texnum) +{ + if (texnum < 0 || texnum >= numtextures) + return 0; + return texturetranslation[texnum]; +} + // // R_GetColumn // diff --git a/src/r_data.h b/src/r_data.h index 69a2882a..68af0325 100644 --- a/src/r_data.h +++ b/src/r_data.h @@ -65,6 +65,8 @@ extern CV_PossibleValue_t Color_cons_t[]; void R_LoadTextures(void); void R_FlushTextureCache(void); +INT32 R_GetTextureNum(INT32 texnum); + // Retrieve column data for span blitting. UINT8 *R_GetColumn(fixed_t tex, INT32 col); diff --git a/src/r_segs.c b/src/r_segs.c index cb78743b..e0a08137 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -300,7 +300,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) curline = ds->curline; frontsector = curline->frontsector; backsector = curline->backsector; - texnum = texturetranslation[curline->sidedef->midtexture]; + texnum = R_GetTextureNum(curline->sidedef->midtexture); windowbottom = windowtop = sprbotscreen = INT32_MAX; // hack translucent linedef types (900-909 for transtables 1-9) @@ -740,7 +740,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) curline = ds->curline; backsector = pfloor->target; frontsector = curline->frontsector == pfloor->target ? curline->backsector : curline->frontsector; - texnum = texturetranslation[sides[pfloor->master->sidenum[0]].midtexture]; + texnum = R_GetTextureNum(sides[pfloor->master->sidenum[0]].midtexture); colfunc = wallcolfunc; @@ -748,7 +748,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) { size_t linenum = curline->linedef-backsector->lines[0]; newline = pfloor->master->frontsector->lines[0] + linenum; - texnum = texturetranslation[sides[newline->sidenum[0]].midtexture]; + texnum = R_GetTextureNum(sides[newline->sidenum[0]].midtexture); } if (pfloor->flags & FF_TRANSLUCENT) @@ -1878,14 +1878,16 @@ void R_StoreWallRange(INT32 start, INT32 stop) if (!backsector) { + fixed_t texheight; // single sided line - midtexture = texturetranslation[sidedef->midtexture]; + midtexture = R_GetTextureNum(sidedef->midtexture); + texheight = textureheight[midtexture]; // a single sided line is terminal, so it must mark ends markfloor = markceiling = true; #ifdef ESLOPE if (linedef->flags & ML_EFFECT2) { if (linedef->flags & ML_DONTPEGBOTTOM) - rw_midtexturemid = frontsector->floorheight + textureheight[sidedef->midtexture] - viewz; + rw_midtexturemid = frontsector->floorheight + texheight - viewz; else rw_midtexturemid = frontsector->ceilingheight - viewz; } @@ -1894,10 +1896,10 @@ void R_StoreWallRange(INT32 start, INT32 stop) if (linedef->flags & ML_DONTPEGBOTTOM) { #ifdef ESLOPE - rw_midtexturemid = worldbottom + textureheight[sidedef->midtexture]; + rw_midtexturemid = worldbottom + texheight; rw_midtextureslide = floorfrontslide; #else - vtop = frontsector->floorheight + textureheight[sidedef->midtexture]; + vtop = frontsector->floorheight + texheight; // bottom of texture at bottom rw_midtexturemid = vtop - viewz; #endif @@ -2129,76 +2131,50 @@ void R_StoreWallRange(INT32 start, INT32 stop) #endif ) { + fixed_t texheight; // top texture if ((linedef->flags & (ML_DONTPEGTOP) && (linedef->flags & ML_DONTPEGBOTTOM)) && linedef->sidenum[1] != 0xffff) { // Special case... use offsets from 2nd side but only if it has a texture. side_t *def = &sides[linedef->sidenum[1]]; - toptexture = texturetranslation[def->toptexture]; + toptexture = R_GetTextureNum(def->toptexture); if (!toptexture) //Second side has no texture, use the first side's instead. - toptexture = texturetranslation[sidedef->toptexture]; - -#ifdef ESLOPE - if (!(linedef->flags & ML_EFFECT1)) { // Ignore slopes for lower/upper textures unless flag is checked - if (linedef->flags & ML_DONTPEGTOP) - rw_toptexturemid = frontsector->ceilingheight - viewz; - else - rw_toptexturemid = backsector->ceilingheight - viewz; - } else -#endif - if (linedef->flags & ML_DONTPEGTOP) - { - // top of texture at top - rw_toptexturemid = worldtop; -#ifdef ESLOPE - rw_toptextureslide = ceilingfrontslide; -#endif - } - else - { -#ifdef ESLOPE - rw_toptexturemid = worldhigh + textureheight[def->toptexture]; - rw_toptextureslide = ceilingbackslide; -#else - vtop = backsector->ceilingheight + textureheight[def->toptexture]; - // bottom of texture - rw_toptexturemid = vtop - viewz; -#endif - } + toptexture = R_GetTextureNum(sidedef->toptexture); + texheight = textureheight[toptexture]; } else { - toptexture = texturetranslation[sidedef->toptexture]; - + toptexture = R_GetTextureNum(sidedef->toptexture); + texheight = textureheight[toptexture]; + } #ifdef ESLOPE - if (!(linedef->flags & ML_EFFECT1)) { // Ignore slopes for lower/upper textures unless flag is checked - if (linedef->flags & ML_DONTPEGTOP) - rw_toptexturemid = frontsector->ceilingheight - viewz; - else - rw_toptexturemid = backsector->ceilingheight - viewz; - } else -#endif + if (!(linedef->flags & ML_EFFECT1)) { // Ignore slopes for lower/upper textures unless flag is checked if (linedef->flags & ML_DONTPEGTOP) - { - // top of texture at top - rw_toptexturemid = worldtop; -#ifdef ESLOPE - rw_toptextureslide = ceilingfrontslide; -#endif - } + rw_toptexturemid = frontsector->ceilingheight - viewz; else - { -#ifdef ESLOPE - rw_toptexturemid = worldhigh + textureheight[sidedef->toptexture]; - rw_toptextureslide = ceilingbackslide; -#else - vtop = backsector->ceilingheight + textureheight[sidedef->toptexture]; - // bottom of texture - rw_toptexturemid = vtop - viewz; + rw_toptexturemid = backsector->ceilingheight - viewz; + } else +#endif + if (linedef->flags & ML_DONTPEGTOP) + { + // top of texture at top + rw_toptexturemid = worldtop; +#ifdef ESLOPE + rw_toptextureslide = ceilingfrontslide; +#endif + } + else + { +#ifdef ESLOPE + rw_toptexturemid = worldhigh + texheight; + rw_toptextureslide = ceilingbackslide; +#else + vtop = backsector->ceilingheight + texheight; + // bottom of texture + rw_toptexturemid = vtop - viewz; #endif - } } } // check BOTTOM TEXTURE @@ -2209,7 +2185,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) ) //seulement si VISIBLE!!! { // bottom texture - bottomtexture = texturetranslation[sidedef->bottomtexture]; + bottomtexture = R_GetTextureNum(sidedef->bottomtexture); #ifdef ESLOPE if (!(linedef->flags & ML_EFFECT1)) { // Ignore slopes for lower/upper textures unless flag is checked @@ -2494,7 +2470,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) ds_p->numthicksides = numthicksides = i; } - if (sidedef->midtexture) + if (sidedef->midtexture > 0 && sidedef->midtexture < numtextures) { // masked midtexture if (!ds_p->thicksidecol) @@ -3101,12 +3077,12 @@ void R_StoreWallRange(INT32 start, INT32 stop) if (maskedtexture && !(ds_p->silhouette & SIL_TOP)) { ds_p->silhouette |= SIL_TOP; - ds_p->tsilheight = sidedef->midtexture ? INT32_MIN: INT32_MAX; + ds_p->tsilheight = (sidedef->midtexture > 0 && sidedef->midtexture < numtextures) ? INT32_MIN: INT32_MAX; } if (maskedtexture && !(ds_p->silhouette & SIL_BOTTOM)) { ds_p->silhouette |= SIL_BOTTOM; - ds_p->bsilheight = sidedef->midtexture ? INT32_MAX: INT32_MIN; + ds_p->bsilheight = (sidedef->midtexture > 0 && sidedef->midtexture < numtextures) ? INT32_MAX: INT32_MIN; } ds_p++; } From 8e56582728e02176b32890c89fc105df2a0bd0f3 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sat, 17 Dec 2016 19:59:54 +0000 Subject: [PATCH 26/35] Created R_CheckTextureCache to make sure midtexture/FOF walls cache their textures before choosing colfunc_2s, for software mode --- src/r_data.c | 12 ++++++++++++ src/r_data.h | 1 + src/r_segs.c | 6 ++++++ 3 files changed, 19 insertions(+) diff --git a/src/r_data.c b/src/r_data.c index c24cca91..bb12f916 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -317,6 +317,18 @@ INT32 R_GetTextureNum(INT32 texnum) return texturetranslation[texnum]; } +// +// R_CheckTextureCache +// +// Use this if you need to make sure the texture is cached before R_GetColumn calls +// e.g.: midtextures and FOF walls +// +void R_CheckTextureCache(INT32 tex) +{ + if (!texturecache[tex]) + R_GenerateTexture(tex); +} + // // R_GetColumn // diff --git a/src/r_data.h b/src/r_data.h index 68af0325..1e9e0eb5 100644 --- a/src/r_data.h +++ b/src/r_data.h @@ -66,6 +66,7 @@ void R_LoadTextures(void); void R_FlushTextureCache(void); INT32 R_GetTextureNum(INT32 texnum); +void R_CheckTextureCache(INT32 tex); // Retrieve column data for span blitting. UINT8 *R_GetColumn(fixed_t tex, INT32 col); diff --git a/src/r_segs.c b/src/r_segs.c index e0a08137..ab501082 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -344,6 +344,9 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) rw_scalestep = ds->scalestep; spryscale = ds->scale1 + (x1 - ds->x1)*rw_scalestep; + // Texture must be cached before setting colfunc_2s, + // otherwise texture[texnum]->holes may be false when it shouldn't be + R_CheckTextureCache(texnum); // handle case where multipatch texture is drawn on a 2sided wall, multi-patch textures // are not stored per-column with post info in SRB2 if (textures[texnum]->holes) @@ -968,6 +971,9 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) dc_texturemid += offsetvalue; + // Texture must be cached before setting colfunc_2s, + // otherwise texture[texnum]->holes may be false when it shouldn't be + R_CheckTextureCache(texnum); //faB: handle case where multipatch texture is drawn on a 2sided wall, multi-patch textures // are not stored per-column with post info anymore in Doom Legacy if (textures[texnum]->holes) From 6ca806a8c0395e4283a7be477e9d1a06782317a5 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sat, 31 Dec 2016 20:44:16 +0000 Subject: [PATCH 27/35] Fix FOF lighting being stupid with repeating midtextures. --- src/r_defs.h | 1 + src/r_segs.c | 9 +++++++++ 2 files changed, 10 insertions(+) diff --git a/src/r_defs.h b/src/r_defs.h index 2c5860ee..e1ffca7e 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -203,6 +203,7 @@ typedef struct r_lightlist_s fixed_t heightstep; fixed_t botheight; fixed_t botheightstep; + fixed_t startheight; // for repeating midtextures INT16 lightlevel; extracolormap_t *extra_colormap; lighttable_t *rcolormap; diff --git a/src/r_segs.c b/src/r_segs.c index ab501082..8f271bfe 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -394,6 +394,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) rlight->height = (centeryfrac) - FixedMul((light->height - viewz), spryscale); rlight->heightstep = -FixedMul(rw_scalestep, (light->height - viewz)); #endif + rlight->startheight = rlight->height; // keep starting value here to reset for each repeat rlight->lightlevel = *light->lightlevel; rlight->extra_colormap = light->extra_colormap; rlight->flags = light->flags; @@ -487,6 +488,14 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) { rw_scalestep = ds->scalestep; spryscale = ds->scale1 + (x1 - ds->x1)*rw_scalestep; + if (dc_numlights) + { // reset all lights to their starting heights + for (i = 0; i < dc_numlights; i++) + { + rlight = &dc_lightlist[i]; + rlight->height = rlight->startheight; + } + } } #ifndef ESLOPE From 0e6e52eabe99c8d031ea736d4b5d26b24ab00efb Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sun, 1 Jan 2017 17:03:13 +0000 Subject: [PATCH 28/35] Start mobjnums at 1 instead of 0, so that the first found mobj can be relinked as a target etc to other mobjs properly This fixes Brak's electric barrier disappearing for joiners to ERZC. There seems to be some issues with the lava falls there too I've found, but the electric barrier actually stays around now at least --- src/d_netcmd.c | 2 +- src/p_saveg.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 7fd10d08..66c90f91 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -3960,7 +3960,7 @@ static void Command_Archivetest_f(void) } // assign mobjnum - i = 0; + i = 1; for (th = thinkercap.next; th != &thinkercap; th = th->next) if (th->function.acp1 == (actionf_p1)P_MobjThinker) ((mobj_t *)th)->mobjnum = i++; diff --git a/src/p_saveg.c b/src/p_saveg.c index 5e457ca3..14386ff1 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -3285,7 +3285,7 @@ void P_SaveNetGame(void) { thinker_t *th; mobj_t *mobj; - INT32 i = 0; + INT32 i = 1; // don't start from 0, it'd be confused with a blank pointer otherwise CV_SaveNetVars(&save_p); P_NetArchiveMisc(); From eb22f347f35c6a1417a15e61a2550e4181a0b69c Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Mon, 2 Jan 2017 19:04:33 +0000 Subject: [PATCH 29/35] Made Eggscalibur use mobj->watertop instead of mobj->spawnpoint->z because that's not netgame-safe. CEZ3 STILL has some ridiculous inconsistencies, but this is one less to worry about. --- src/p_mobj.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 5e5961d4..a9dedf51 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -4436,7 +4436,7 @@ static void P_Boss4MoveSpikeballs(mobj_t *mobj, angle_t angle, fixed_t fz) { INT32 s; mobj_t *base = mobj, *seg; - fixed_t dist, bz = (mobj->spawnpoint->z+16)<watertop+(16<tracer)) { for (seg = base, dist = 172*FRACUNIT, s = 9; seg; seg = seg->hnext, dist += 124*FRACUNIT, --s) @@ -4450,7 +4450,7 @@ static void P_Boss4PinchSpikeballs(mobj_t *mobj, angle_t angle, fixed_t fz) { INT32 s; mobj_t *base = mobj, *seg; - fixed_t dist, bz = (mobj->spawnpoint->z+16)<watertop+(16<tracer)) { for (seg = base, dist = 112*FRACUNIT, s = 9; seg; seg = seg->hnext, dist += 132*FRACUNIT, --s) @@ -4566,7 +4566,7 @@ static void P_Boss4Thinker(mobj_t *mobj) INT32 i, arm; mobj_t *seg, *base = mobj; // First frame init, spawn all the things. - mobj->spawnpoint->z = mobj->z>>FRACBITS; + mobj->watertop = mobj->z; z = mobj->z + mobj->height/2 - mobjinfo[MT_EGGMOBILE4_MACE].height/2; for (arm = 0; arm <3 ; arm++) { @@ -4622,7 +4622,7 @@ static void P_Boss4Thinker(mobj_t *mobj) case 3: { fixed_t z; - if (mobj->z < (mobj->spawnpoint->z+512)<z < mobj->watertop+(512<momz = 8*FRACUNIT; else { @@ -4631,7 +4631,7 @@ static void P_Boss4Thinker(mobj_t *mobj) } mobj->movecount += 400<<(FRACBITS>>1); mobj->movecount %= 360*FRACUNIT; - z = mobj->z - (mobj->spawnpoint->z<height/2; + z = mobj->z - mobj->watertop - mobjinfo[MT_EGGMOBILE4_MACE].height - mobj->height/2; if (z < 0) // We haven't risen high enough to pull the spikeballs along yet P_Boss4MoveSpikeballs(mobj, FixedAngle(mobj->movecount), 0); // So don't pull the spikeballs along yet. else @@ -4641,13 +4641,13 @@ static void P_Boss4Thinker(mobj_t *mobj) // Pinch phase! case 4: { - if (mobj->z < (mobj->spawnpoint->z+512+128*(mobj->info->damage-mobj->health))<z < mobj->watertop+(512+128*(mobj->info->damage-mobj->health))<momz = 8*FRACUNIT; else mobj->momz = 0; mobj->movecount += (800+800*(mobj->info->damage-mobj->health))<<(FRACBITS>>1); mobj->movecount %= 360*FRACUNIT; - P_Boss4PinchSpikeballs(mobj, FixedAngle(mobj->movecount), mobj->z - (mobj->spawnpoint->z<height/2); + P_Boss4PinchSpikeballs(mobj, FixedAngle(mobj->movecount), mobj->z - mobj->watertop - mobjinfo[MT_EGGMOBILE4_MACE].height - mobj->height/2); if (!mobj->target || !mobj->target->health) P_SupermanLook4Players(mobj); From a4fe3580e2795e1852e818a66e5a92b8c81ef70a Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Mon, 2 Jan 2017 19:07:20 +0000 Subject: [PATCH 30/35] Forgot to commit this compiling fix. --- src/p_mobj.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index a9dedf51..c150b691 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -4641,7 +4641,7 @@ static void P_Boss4Thinker(mobj_t *mobj) // Pinch phase! case 4: { - if (mobj->z < mobj->watertop+(512+128*(mobj->info->damage-mobj->health))<z < (mobj->watertop + ((512+128*(mobj->info->damage-mobj->health))<momz = 8*FRACUNIT; else mobj->momz = 0; From a0d095e70735f8237ccfd4b6a7fce35408c08bf1 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Tue, 3 Jan 2017 18:47:46 +0000 Subject: [PATCH 31/35] Fix sector floordata/ceilingdata/lightingdata pointers not being NULL when they should be This fixes ERCZ's lava falls not moving after joining a netgame at that stage. Possibly explains other various floor/ceiling related netgame quirks that haven't been noticed until now, maybe even in multiplayer levels. --- src/p_saveg.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/p_saveg.c b/src/p_saveg.c index 14386ff1..66fc118a 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -2607,6 +2607,7 @@ static void P_NetUnArchiveThinkers(void) thinker_t *next; UINT8 tclass; UINT8 restoreNum = false; + UINT32 i; if (READUINT32(save_p) != ARCHIVEBLOCK_THINKERS) I_Error("Bad $$$.sav at archive block Thinkers"); @@ -2627,6 +2628,12 @@ static void P_NetUnArchiveThinkers(void) iquetail = iquehead = 0; P_InitThinkers(); + // clear sector thinker pointers so they don't point to non-existant thinkers for all of eternity + for (i = 0; i < numsectors; i++) + { + sectors[i].floordata = sectors[i].ceilingdata = sectors[i].lightingdata = NULL; + } + // read in saved thinkers for (;;) { From b768c4b9611e916d2190f09420b48738af7a5ec8 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Tue, 3 Jan 2017 20:48:39 +0000 Subject: [PATCH 32/35] Sync sector tags and tag list variables properly Dunno who thought it was a good idea to lump tag, nexttag and firsttag together in $$$.sav, but that meant changing sector tags caused SRB2 to stop responding since it lead to the tag lists being broken --- src/p_saveg.c | 19 +++++++++++-------- src/p_setup.c | 1 + src/p_spec.c | 2 ++ src/r_defs.h | 1 + 4 files changed, 15 insertions(+), 8 deletions(-) diff --git a/src/p_saveg.c b/src/p_saveg.c index 66fc118a..d2062820 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -460,6 +460,7 @@ static void P_NetUnArchivePlayers(void) #define SD_TAG 0x10 #define SD_FLOORANG 0x20 #define SD_CEILANG 0x40 +#define SD_TAGLIST 0x80 #define LD_FLAG 0x01 #define LD_SPECIAL 0x02 @@ -535,6 +536,8 @@ static void P_NetArchiveWorld(void) if (ss->tag != SHORT(ms->tag)) diff2 |= SD_TAG; + if (ss->nexttag != ss->spawn_nexttag || ss->firsttag != ss->spawn_firsttag) + diff2 |= SD_TAGLIST; // Check if any of the sector's FOFs differ from how they spawned if (ss->ffloors) @@ -582,16 +585,17 @@ static void P_NetArchiveWorld(void) WRITEFIXED(put, ss->ceiling_xoffs); if (diff2 & SD_CYOFFS) WRITEFIXED(put, ss->ceiling_yoffs); - if (diff2 & SD_TAG) - { + if (diff2 & SD_TAG) // save only the tag WRITEINT16(put, ss->tag); - WRITEINT32(put, ss->firsttag); - WRITEINT32(put, ss->nexttag); - } if (diff2 & SD_FLOORANG) WRITEANGLE(put, ss->floorpic_angle); if (diff2 & SD_CEILANG) WRITEANGLE(put, ss->ceilingpic_angle); + if (diff2 & SD_TAGLIST) // save both firsttag and nexttag + { // either of these could be changed even if tag isn't + WRITEINT32(put, ss->firsttag); + WRITEINT32(put, ss->nexttag); + } // Special case: save the stats of all modified ffloors along with their ffloor "number"s // we don't bother with ffloors that haven't changed, that would just add to savegame even more than is really needed @@ -774,12 +778,11 @@ static void P_NetUnArchiveWorld(void) if (diff2 & SD_CYOFFS) sectors[i].ceiling_yoffs = READFIXED(get); if (diff2 & SD_TAG) + sectors[i].tag = READINT16(get); // DON'T use P_ChangeSectorTag + if (diff2 & SD_TAGLIST) { - INT16 tag; - tag = READINT16(get); sectors[i].firsttag = READINT32(get); sectors[i].nexttag = READINT32(get); - P_ChangeSectorTag(i, tag); } if (diff2 & SD_FLOORANG) sectors[i].floorpic_angle = READANGLE(get); diff --git a/src/p_setup.c b/src/p_setup.c index d6563735..224a31bb 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -614,6 +614,7 @@ static void P_LoadSectors(lumpnum_t lumpnum) ss->special = SHORT(ms->special); ss->tag = SHORT(ms->tag); ss->nexttag = ss->firsttag = -1; + ss->spawn_nexttag = ss->spawn_firsttag = -1; memset(&ss->soundorg, 0, sizeof(ss->soundorg)); ss->validcount = 0; diff --git a/src/p_spec.c b/src/p_spec.c index b04c5588..325dcd5d 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -1519,6 +1519,8 @@ static inline void P_InitTagLists(void) size_t j = (unsigned)sectors[i].tag % numsectors; sectors[i].nexttag = sectors[j].firsttag; sectors[j].firsttag = (INT32)i; + sectors[i].spawn_nexttag = sectors[i].nexttag; + sectors[j].spawn_firsttag = sectors[j].firsttag; } for (i = numlines - 1; i != (size_t)-1; i--) diff --git a/src/r_defs.h b/src/r_defs.h index 3669ec8f..082bb8ca 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -383,6 +383,7 @@ typedef struct sector_s #endif // these are saved for netgames, so do not let Lua touch these! + INT32 spawn_nexttag, spawn_firsttag; // the actual nexttag/firsttag values may differ if the sector's tag was changed // offsets sector spawned with (via linedef type 7) fixed_t spawn_flr_xoffs, spawn_flr_yoffs; From 4d8ca41e653d78a329d3f112d08f55019f237963 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Tue, 3 Jan 2017 22:43:46 +0000 Subject: [PATCH 33/35] Fix player colors mysteriously turning red if a resynch occurs outside of CTF/Team Match. Not technically a $$$.sav fix, but still netplay related of course At least, I assume this is how it's happening for some, I haven't been able to get the full info since WHERE IS EVERYBODY? --- src/d_clisrv.c | 21 +++++---------------- src/d_clisrv.h | 2 +- 2 files changed, 6 insertions(+), 17 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 7e9dcf8e..2a2d5fea 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -868,12 +868,13 @@ static inline void resynch_write_others(resynchend_pak *rst) { UINT8 i; - rst->ingame = rst->ctfteam = 0; + rst->ingame = 0; for (i = 0; i < MAXPLAYERS; ++i) { if (!playeringame[i]) { + rst->ctfteam[i] = 0; rst->score[i] = 0; rst->numboxes[i] = 0; rst->totalring[i] = 0; @@ -883,11 +884,8 @@ static inline void resynch_write_others(resynchend_pak *rst) } if (!players[i].spectator) - { rst->ingame |= (1< 1) - rst->ctfteam |= (1<ctfteam[i] = (INT32)LONG(players[i].ctfteam); rst->score[i] = (UINT32)LONG(players[i].score); rst->numboxes[i] = SHORT(players[i].numboxes); rst->totalring[i] = SHORT(players[i].totalring); @@ -904,21 +902,12 @@ static inline void resynch_read_others(resynchend_pak *p) { UINT8 i; UINT32 loc_ingame = (UINT32)LONG(p->ingame); - UINT32 loc_ctfteam = (UINT32)LONG(p->ctfteam); for (i = 0; i < MAXPLAYERS; ++i) { // We don't care if they're in the game or not, just write all the data. - if (loc_ingame & (1<ctfteam[i]); // no, 0 does not mean spectator, at least not in Match players[i].score = (UINT32)LONG(p->score[i]); players[i].numboxes = SHORT(p->numboxes[i]); players[i].totalring = SHORT(p->totalring[i]); diff --git a/src/d_clisrv.h b/src/d_clisrv.h index fe80be1b..02a03738 100644 --- a/src/d_clisrv.h +++ b/src/d_clisrv.h @@ -133,7 +133,7 @@ typedef struct fixed_t flagz[2]; UINT32 ingame; // Spectator bit for each player - UINT32 ctfteam; // If not spectator, then which team? + INT32 ctfteam[MAXPLAYERS]; // Which team? (can't be 1 bit, since in regular Match there are no teams) // Resynch game scores and the like all at once UINT32 score[MAXPLAYERS]; // Everyone's score From f2a58a74ef0deb2ce13a3efd871d00e68cc111b4 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Tue, 3 Jan 2017 22:48:06 +0000 Subject: [PATCH 34/35] Stupid me --- src/d_clisrv.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 2a2d5fea..12484556 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -895,7 +895,6 @@ static inline void resynch_write_others(resynchend_pak *rst) // endian safeness rst->ingame = (UINT32)LONG(rst->ingame); - rst->ctfteam = (UINT32)LONG(rst->ctfteam); } static inline void resynch_read_others(resynchend_pak *p) From ad30c4117923b02e0cac54192d2ca40a555106df Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sat, 7 Jan 2017 18:02:55 +0000 Subject: [PATCH 35/35] Fix egg guard shields being endlessly killed by lasers. Simply make sure they have health first before killing them! --- src/p_spec.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/p_spec.c b/src/p_spec.c index b04c5588..6fcef330 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -5342,6 +5342,10 @@ void T_LaserFlash(laserthink_t *flash) && thing->flags & MF_BOSS) continue; // Don't hurt bosses + // Don't endlessly kill egg guard shields (or anything else for that matter) + if (thing->health <= 0) + continue; + top = P_GetSpecialTopZ(thing, sourcesec, sector); bottom = P_GetSpecialBottomZ(thing, sourcesec, sector);