From d166a1509dec22bc934ccbfda92d98b78273318c Mon Sep 17 00:00:00 2001 From: Arthur Date: Tue, 20 Feb 2024 18:57:37 -0500 Subject: [PATCH 1/4] Starting over, beginning with cleaning up floorz/ceilingz functions --- src/p_local.h | 26 +++---- src/p_mobj.c | 208 +++++++------------------------------------------- 2 files changed, 38 insertions(+), 196 deletions(-) diff --git a/src/p_local.h b/src/p_local.h index 9644e7a24..062289f93 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -308,21 +308,19 @@ void P_PushableThinker(mobj_t *mobj); void P_SceneryThinker(mobj_t *mobj); -fixed_t P_MobjFloorZ(mobj_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t x, fixed_t y, line_t *line, boolean lowest, boolean perfect); -fixed_t P_MobjCeilingZ(mobj_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t x, fixed_t y, line_t *line, boolean lowest, boolean perfect); -#define P_GetFloorZ(mobj, sector, x, y, line) P_MobjFloorZ(mobj, sector, NULL, x, y, line, false, false) -#define P_GetCeilingZ(mobj, sector, x, y, line) P_MobjCeilingZ(mobj, sector, NULL, x, y, line, true, false) -#define P_GetFOFTopZ(mobj, sector, fof, x, y, line) P_MobjCeilingZ(mobj, sectors + fof->secnum, sector, x, y, line, false, false) -#define P_GetFOFBottomZ(mobj, sector, fof, x, y, line) P_MobjFloorZ(mobj, sectors + fof->secnum, sector, x, y, line, true, false) -#define P_GetSpecialBottomZ(mobj, src, bound) P_MobjFloorZ(mobj, src, bound, mobj->x, mobj->y, NULL, src != bound, true) -#define P_GetSpecialTopZ(mobj, src, bound) P_MobjCeilingZ(mobj, src, bound, mobj->x, mobj->y, NULL, src == bound, true) +fixed_t P_MobjFloorZ(sector_t *sector, sector_t *boundsec, fixed_t x, fixed_t y, fixed_t radius, line_t *line, boolean lowest, boolean perfect); +fixed_t P_MobjCeilingZ(sector_t *sector, sector_t *boundsec, fixed_t x, fixed_t y, fixed_t radius, line_t *line, boolean lowest, boolean perfect); +#define P_GetFloorZ(mobj, sector, x, y, line) P_MobjFloorZ(sector, NULL, x, y, mobj->radius, line, false, false) +#define P_GetCeilingZ(mobj, sector, x, y, line) P_MobjCeilingZ(sector, NULL, x, y, mobj->radius, line, true, false) +#define P_GetFOFTopZ(mobj, sector, fof, x, y, line) P_MobjCeilingZ(sectors + fof->secnum, sector, x, y, mobj->radius, line, false, false) +#define P_GetFOFBottomZ(mobj, sector, fof, x, y, line) P_MobjFloorZ(sectors + fof->secnum, sector, x, y, mobj->radius, line, true, false) +#define P_GetSpecialBottomZ(mobj, src, bound) P_MobjFloorZ(src, bound, mobj->x, mobj->y, mobj->radius, NULL, src != bound, true) +#define P_GetSpecialTopZ(mobj, src, bound) P_MobjCeilingZ(src, bound, mobj->x, mobj->y, mobj->radius, NULL, src == bound, true) -fixed_t P_CameraFloorZ(camera_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t x, fixed_t y, line_t *line, boolean lowest, boolean perfect); -fixed_t P_CameraCeilingZ(camera_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t x, fixed_t y, line_t *line, boolean lowest, boolean perfect); -#define P_CameraGetFloorZ(mobj, sector, x, y, line) P_CameraFloorZ(mobj, sector, NULL, x, y, line, false, false) -#define P_CameraGetCeilingZ(mobj, sector, x, y, line) P_CameraCeilingZ(mobj, sector, NULL, x, y, line, true, false) -#define P_CameraGetFOFTopZ(mobj, sector, fof, x, y, line) P_CameraCeilingZ(mobj, sectors + fof->secnum, sector, x, y, line, false, false) -#define P_CameraGetFOFBottomZ(mobj, sector, fof, x, y, line) P_CameraFloorZ(mobj, sectors + fof->secnum, sector, x, y, line, true, false) +#define P_CameraGetFloorZ(mobj, sector, x, y, line) P_MobjFloorZ(sector, NULL, x, y, mobj->radius, line, false, false) +#define P_CameraGetCeilingZ(mobj, sector, x, y, line) P_MobjCeilingZ(sector, NULL, x, y, mobj->radius, line, true, false) +#define P_CameraGetFOFTopZ(mobj, sector, fof, x, y, line) P_MobjCeilingZ(sectors + fof->secnum, sector, x, y, mobj->radius, line, false, false) +#define P_CameraGetFOFBottomZ(mobj, sector, fof, x, y, line) P_MobjFloorZ(sectors + fof->secnum, sector, x, y, mobj->radius, line, true, false) boolean P_InsideANonSolidFFloor(mobj_t *mobj, ffloor_t *rover); boolean P_CheckDeathPitCollide(mobj_t *mo); diff --git a/src/p_mobj.c b/src/p_mobj.c index 16ca0c634..d4a1fa981 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -1092,9 +1092,8 @@ static fixed_t HighestOnLine(fixed_t radius, fixed_t x, fixed_t y, line_t *line, ); } -fixed_t P_MobjFloorZ(mobj_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t x, fixed_t y, line_t *line, boolean lowest, boolean perfect) +fixed_t P_MobjFloorZ(sector_t *sector, sector_t *boundsec, fixed_t x, fixed_t y, fixed_t radius, line_t *line, boolean lowest, boolean perfect) { - I_Assert(mobj != NULL); I_Assert(sector != NULL); if (sector->f_slope) { @@ -1103,14 +1102,14 @@ fixed_t P_MobjFloorZ(mobj_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t // Get the corner of the object that should be the highest on the slope if (slope->d.x < 0) - testx = mobj->radius; + testx = radius; else - testx = -mobj->radius; + testx = -radius; if (slope->d.y < 0) - testy = mobj->radius; + testy = radius; else - testy = -mobj->radius; + testy = -radius; if ((slope->zdelta > 0) ^ !!(lowest)) { testx = -testx; @@ -1136,10 +1135,10 @@ fixed_t P_MobjFloorZ(mobj_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t else finalheight = INT32_MIN; - bbox[BOXLEFT] = x-mobj->radius; - bbox[BOXRIGHT] = x+mobj->radius; - bbox[BOXTOP] = y+mobj->radius; - bbox[BOXBOTTOM] = y-mobj->radius; + bbox[BOXLEFT] = x-radius; + bbox[BOXRIGHT] = x+radius; + bbox[BOXTOP] = y+radius; + bbox[BOXBOTTOM] = y-radius; for (i = 0; i < boundsec->linecount; i++) { ld = boundsec->lines[i]; @@ -1151,9 +1150,9 @@ fixed_t P_MobjFloorZ(mobj_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t continue; if (lowest) - finalheight = min(finalheight, HighestOnLine(mobj->radius, x, y, ld, slope, true)); + finalheight = min(finalheight, HighestOnLine(radius, x, y, ld, slope, true)); else - finalheight = max(finalheight, HighestOnLine(mobj->radius, x, y, ld, slope, false)); + finalheight = max(finalheight, HighestOnLine(radius, x, y, ld, slope, false)); } return finalheight; @@ -1164,14 +1163,13 @@ fixed_t P_MobjFloorZ(mobj_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t if (line == NULL) return P_GetSlopeZAt(slope, x, y); - return HighestOnLine(mobj->radius, x, y, line, slope, lowest); + return HighestOnLine(radius, x, y, line, slope, lowest); } else // Well, that makes it easy. Just get the floor height return sector->floorheight; } -fixed_t P_MobjCeilingZ(mobj_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t x, fixed_t y, line_t *line, boolean lowest, boolean perfect) +fixed_t P_MobjCeilingZ(sector_t *sector, sector_t *boundsec, fixed_t x, fixed_t y, fixed_t radius, line_t *line, boolean lowest, boolean perfect) { - I_Assert(mobj != NULL); I_Assert(sector != NULL); if (sector->c_slope) { @@ -1180,14 +1178,14 @@ fixed_t P_MobjCeilingZ(mobj_t *mobj, sector_t *sector, sector_t *boundsec, fixed // Get the corner of the object that should be the highest on the slope if (slope->d.x < 0) - testx = mobj->radius; + testx = radius; else - testx = -mobj->radius; + testx = -radius; if (slope->d.y < 0) - testy = mobj->radius; + testy = radius; else - testy = -mobj->radius; + testy = -radius; if ((slope->zdelta > 0) ^ !!(lowest)) { testx = -testx; @@ -1213,10 +1211,10 @@ fixed_t P_MobjCeilingZ(mobj_t *mobj, sector_t *sector, sector_t *boundsec, fixed else finalheight = INT32_MIN; - bbox[BOXLEFT] = x-mobj->radius; - bbox[BOXRIGHT] = x+mobj->radius; - bbox[BOXTOP] = y+mobj->radius; - bbox[BOXBOTTOM] = y-mobj->radius; + bbox[BOXLEFT] = x-radius; + bbox[BOXRIGHT] = x+radius; + bbox[BOXTOP] = y+radius; + bbox[BOXBOTTOM] = y-radius; for (i = 0; i < boundsec->linecount; i++) { ld = boundsec->lines[i]; @@ -1228,9 +1226,9 @@ fixed_t P_MobjCeilingZ(mobj_t *mobj, sector_t *sector, sector_t *boundsec, fixed continue; if (lowest) - finalheight = min(finalheight, HighestOnLine(mobj->radius, x, y, ld, slope, true)); + finalheight = min(finalheight, HighestOnLine(radius, x, y, ld, slope, true)); else - finalheight = max(finalheight, HighestOnLine(mobj->radius, x, y, ld, slope, false)); + finalheight = max(finalheight, HighestOnLine(radius, x, y, ld, slope, false)); } return finalheight; @@ -1241,165 +1239,11 @@ fixed_t P_MobjCeilingZ(mobj_t *mobj, sector_t *sector, sector_t *boundsec, fixed if (line == NULL) return P_GetSlopeZAt(slope, x, y); - return HighestOnLine(mobj->radius, x, y, line, slope, lowest); + return HighestOnLine(radius, x, y, line, slope, lowest); } else // Well, that makes it easy. Just get the ceiling height return sector->ceilingheight; } -// Now do the same as all above, but for cameras because apparently cameras are special? -fixed_t P_CameraFloorZ(camera_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t x, fixed_t y, line_t *line, boolean lowest, boolean perfect) -{ - I_Assert(mobj != NULL); - I_Assert(sector != NULL); - - if (sector->f_slope) { - fixed_t testx, testy; - pslope_t *slope = sector->f_slope; - - // Get the corner of the object that should be the highest on the slope - if (slope->d.x < 0) - testx = mobj->radius; - else - testx = -mobj->radius; - - if (slope->d.y < 0) - testy = mobj->radius; - else - testy = -mobj->radius; - - if ((slope->zdelta > 0) ^ !!(lowest)) { - testx = -testx; - testy = -testy; - } - - testx += x; - testy += y; - - // If the highest point is in the sector, then we have it easy! Just get the Z at that point - if (R_IsPointInSector(boundsec ? boundsec : sector, testx, testy)) - return P_GetSlopeZAt(slope, testx, testy); - - // If boundsec is set, we're looking for specials. In that case, iterate over every line in this sector to find the TRUE highest/lowest point - if (perfect) { - size_t i; - line_t *ld; - fixed_t bbox[4]; - fixed_t finalheight; - - if (lowest) - finalheight = INT32_MAX; - else - finalheight = INT32_MIN; - - bbox[BOXLEFT] = x-mobj->radius; - bbox[BOXRIGHT] = x+mobj->radius; - bbox[BOXTOP] = y+mobj->radius; - bbox[BOXBOTTOM] = y-mobj->radius; - for (i = 0; i < boundsec->linecount; i++) { - ld = boundsec->lines[i]; - - if (bbox[BOXRIGHT] <= ld->bbox[BOXLEFT] || bbox[BOXLEFT] >= ld->bbox[BOXRIGHT] - || bbox[BOXTOP] <= ld->bbox[BOXBOTTOM] || bbox[BOXBOTTOM] >= ld->bbox[BOXTOP]) - continue; - - if (P_BoxOnLineSide(bbox, ld) != -1) - continue; - - if (lowest) - finalheight = min(finalheight, HighestOnLine(mobj->radius, x, y, ld, slope, true)); - else - finalheight = max(finalheight, HighestOnLine(mobj->radius, x, y, ld, slope, false)); - } - - return finalheight; - } - - // If we're just testing for base sector location (no collision line), just go for the center's spot... - // It'll get fixed when we test for collision anyway, and the final result can't be lower than this - if (line == NULL) - return P_GetSlopeZAt(slope, x, y); - - return HighestOnLine(mobj->radius, x, y, line, slope, lowest); - } else // Well, that makes it easy. Just get the floor height - return sector->floorheight; -} - -fixed_t P_CameraCeilingZ(camera_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t x, fixed_t y, line_t *line, boolean lowest, boolean perfect) -{ - I_Assert(mobj != NULL); - I_Assert(sector != NULL); - - if (sector->c_slope) { - fixed_t testx, testy; - pslope_t *slope = sector->c_slope; - - // Get the corner of the object that should be the highest on the slope - if (slope->d.x < 0) - testx = mobj->radius; - else - testx = -mobj->radius; - - if (slope->d.y < 0) - testy = mobj->radius; - else - testy = -mobj->radius; - - if ((slope->zdelta > 0) ^ !!(lowest)) { - testx = -testx; - testy = -testy; - } - - testx += x; - testy += y; - - // If the highest point is in the sector, then we have it easy! Just get the Z at that point - if (R_IsPointInSector(boundsec ? boundsec : sector, testx, testy)) - return P_GetSlopeZAt(slope, testx, testy); - - // If boundsec is set, we're looking for specials. In that case, iterate over every line in this sector to find the TRUE highest/lowest point - if (perfect) { - size_t i; - line_t *ld; - fixed_t bbox[4]; - fixed_t finalheight; - - if (lowest) - finalheight = INT32_MAX; - else - finalheight = INT32_MIN; - - bbox[BOXLEFT] = x-mobj->radius; - bbox[BOXRIGHT] = x+mobj->radius; - bbox[BOXTOP] = y+mobj->radius; - bbox[BOXBOTTOM] = y-mobj->radius; - for (i = 0; i < boundsec->linecount; i++) { - ld = boundsec->lines[i]; - - if (bbox[BOXRIGHT] <= ld->bbox[BOXLEFT] || bbox[BOXLEFT] >= ld->bbox[BOXRIGHT] - || bbox[BOXTOP] <= ld->bbox[BOXBOTTOM] || bbox[BOXBOTTOM] >= ld->bbox[BOXTOP]) - continue; - - if (P_BoxOnLineSide(bbox, ld) != -1) - continue; - - if (lowest) - finalheight = min(finalheight, HighestOnLine(mobj->radius, x, y, ld, slope, true)); - else - finalheight = max(finalheight, HighestOnLine(mobj->radius, x, y, ld, slope, false)); - } - - return finalheight; - } - - // If we're just testing for base sector location (no collision line), just go for the center's spot... - // It'll get fixed when we test for collision anyway, and the final result can't be lower than this - if (line == NULL) - return P_GetSlopeZAt(slope, x, y); - - return HighestOnLine(mobj->radius, x, y, line, slope, lowest); - } else // Well, that makes it easy. Just get the ceiling height - return sector->ceilingheight; -} static void P_PlayerFlip(mobj_t *mo) { if (!mo->player) @@ -2329,8 +2173,8 @@ boolean P_CheckDeathPitCollide(mobj_t *mo) if (mo->player && mo->player->pflags & PF_GODMODE) return false; - fixed_t sectorFloor = P_GetSectorFloorZAt(mo->subsector->sector, mo->x, mo->y); - fixed_t sectorCeiling = P_GetSectorCeilingZAt(mo->subsector->sector, mo->x, mo->y); + fixed_t sectorFloor = P_MobjFloorZ(mo->subsector->sector, mo->subsector->sector, mo->x, mo->y, mo->radius, NULL, false, true); + fixed_t sectorCeiling = P_MobjCeilingZ(mo->subsector->sector, mo->subsector->sector, mo->x, mo->y, mo->radius, NULL, true, true); if (((mo->z <= sectorFloor && ((mo->subsector->sector->flags & MSF_TRIGGERSPECIAL_HEADBUMP) || !(mo->eflags & MFE_VERTICALFLIP)) && (mo->subsector->sector->flags & MSF_FLIPSPECIAL_FLOOR)) From 9e50f08fc37d8cf5ae8c9e348e6bdaaaaec57017 Mon Sep 17 00:00:00 2001 From: Arthur Date: Tue, 20 Feb 2024 19:14:11 -0500 Subject: [PATCH 2/4] So far so good... --- src/p_mobj.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index d4a1fa981..64024b034 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -1120,11 +1120,14 @@ fixed_t P_MobjFloorZ(sector_t *sector, sector_t *boundsec, fixed_t x, fixed_t y, testy += y; // If the highest point is in the sector, then we have it easy! Just get the Z at that point - if (R_IsPointInSector(boundsec ? boundsec : sector, testx, testy)) +// if (R_IsPointInSector(boundsec ? boundsec : sector, testx, testy)) +// return P_GetSlopeZAt(slope, testx, testy); + + if (R_PointInSubsector(testx, testy)->sector == (boundsec ? boundsec : sector)) // Faster return P_GetSlopeZAt(slope, testx, testy); // If boundsec is set, we're looking for specials. In that case, iterate over every line in this sector to find the TRUE highest/lowest point - if (perfect) { + if (perfect && boundsec) { size_t i; line_t *ld; fixed_t bbox[4]; @@ -1196,11 +1199,14 @@ fixed_t P_MobjCeilingZ(sector_t *sector, sector_t *boundsec, fixed_t x, fixed_t testy += y; // If the highest point is in the sector, then we have it easy! Just get the Z at that point - if (R_IsPointInSector(boundsec ? boundsec : sector, testx, testy)) +// if (R_IsPointInSector(boundsec ? boundsec : sector, testx, testy)) +// return P_GetSlopeZAt(slope, testx, testy); + + if (R_PointInSubsector(testx, testy)->sector == (boundsec ? boundsec : sector)) // Faster return P_GetSlopeZAt(slope, testx, testy); // If boundsec is set, we're looking for specials. In that case, iterate over every line in this sector to find the TRUE highest/lowest point - if (perfect) { + if (perfect && boundsec) { size_t i; line_t *ld; fixed_t bbox[4]; From 9296d6b496471cc17f0b3b0afde8bacd57550e32 Mon Sep 17 00:00:00 2001 From: Arthur Date: Tue, 20 Feb 2024 19:20:09 -0500 Subject: [PATCH 3/4] This should do it. --- 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 64024b034..5e0e3cfe9 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -2179,8 +2179,8 @@ boolean P_CheckDeathPitCollide(mobj_t *mo) if (mo->player && mo->player->pflags & PF_GODMODE) return false; - fixed_t sectorFloor = P_MobjFloorZ(mo->subsector->sector, mo->subsector->sector, mo->x, mo->y, mo->radius, NULL, false, true); - fixed_t sectorCeiling = P_MobjCeilingZ(mo->subsector->sector, mo->subsector->sector, mo->x, mo->y, mo->radius, NULL, true, true); + fixed_t sectorFloor = P_GetSpecialBottomZ(mo, mo->subsector->sector, mo->subsector->sector); + fixed_t sectorCeiling = P_GetSpecialTopZ(mo, mo->subsector->sector, mo->subsector->sector); if (((mo->z <= sectorFloor && ((mo->subsector->sector->flags & MSF_TRIGGERSPECIAL_HEADBUMP) || !(mo->eflags & MFE_VERTICALFLIP)) && (mo->subsector->sector->flags & MSF_FLIPSPECIAL_FLOOR)) From de13b600bf3cbfef49e6ff556e2842bd2d0fd787 Mon Sep 17 00:00:00 2001 From: Arthur Date: Tue, 20 Feb 2024 21:42:23 -0500 Subject: [PATCH 4/4] R_IsPointInSector is fine, it was the clang issue screwing up --- src/p_mobj.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 5e0e3cfe9..c15ac6678 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -1120,10 +1120,7 @@ fixed_t P_MobjFloorZ(sector_t *sector, sector_t *boundsec, fixed_t x, fixed_t y, testy += y; // If the highest point is in the sector, then we have it easy! Just get the Z at that point -// if (R_IsPointInSector(boundsec ? boundsec : sector, testx, testy)) -// return P_GetSlopeZAt(slope, testx, testy); - - if (R_PointInSubsector(testx, testy)->sector == (boundsec ? boundsec : sector)) // Faster + if (R_IsPointInSector(boundsec ? boundsec : sector, testx, testy)) return P_GetSlopeZAt(slope, testx, testy); // If boundsec is set, we're looking for specials. In that case, iterate over every line in this sector to find the TRUE highest/lowest point @@ -1199,10 +1196,7 @@ fixed_t P_MobjCeilingZ(sector_t *sector, sector_t *boundsec, fixed_t x, fixed_t testy += y; // If the highest point is in the sector, then we have it easy! Just get the Z at that point -// if (R_IsPointInSector(boundsec ? boundsec : sector, testx, testy)) -// return P_GetSlopeZAt(slope, testx, testy); - - if (R_PointInSubsector(testx, testy)->sector == (boundsec ? boundsec : sector)) // Faster + if (R_IsPointInSector(boundsec ? boundsec : sector, testx, testy)) return P_GetSlopeZAt(slope, testx, testy); // If boundsec is set, we're looking for specials. In that case, iterate over every line in this sector to find the TRUE highest/lowest point