diff --git a/source/build/include/build.h b/source/build/include/build.h index 47a6a90db..6e469c60f 100644 --- a/source/build/include/build.h +++ b/source/build/include/build.h @@ -606,7 +606,6 @@ static FORCE_INLINE int32_t E_SpriteIsValid(const int32_t i) void alignceilslope(int16_t dasect, int32_t x, int32_t y, int32_t z); void alignflorslope(int16_t dasect, int32_t x, int32_t y, int32_t z); -int32_t sectorofwall(int16_t wallNum); void setslope(int32_t sectnum, int32_t cf, int16_t slope); int32_t lintersect(int32_t originX, int32_t originY, int32_t originZ, diff --git a/source/build/include/buildtypes.h b/source/build/include/buildtypes.h index 757627400..ac0cf6f3e 100644 --- a/source/build/include/buildtypes.h +++ b/source/build/include/buildtypes.h @@ -51,6 +51,7 @@ struct sectortype int16_t hitag; int16_t extra; + uint8_t dirty; float ceilingxpan_, ceilingypan_, floorxpan_, floorypan_; int ceilingxpan() const { return int(ceilingxpan_); } @@ -91,7 +92,7 @@ struct walltype }; vec2_t pos; }; - int16_t point2, nextwall, nextsector; + int16_t point2, nextwall, sector, nextsector; uint16_t cstat; int16_t picnum, overpicnum; int8_t shade; diff --git a/source/build/src/engine.cpp b/source/build/src/engine.cpp index 6c8a52cba..c873e3124 100644 --- a/source/build/src/engine.cpp +++ b/source/build/src/engine.cpp @@ -2323,6 +2323,7 @@ void dragpoint(int16_t pointhighlight, int32_t dax, int32_t day, uint8_t flags) while (1) { + sector[wall[w].sector].dirty = 255; wall[w].x = dax; wall[w].y = day; walbitmap[w>>3] |= pow2char[w&7]; @@ -2839,36 +2840,6 @@ void renderCompleteMirror(void) } -// -// sectorofwall -// -static int32_t sectorofwall_internal(int16_t wallNum) -{ - native_t gap = numsectors>>1, sectNum = gap; - - while (gap > 1) - { - gap >>= 1; - native_t const n = !!(sector[sectNum].wallptr < wallNum); - sectNum += (n ^ (n - 1)) * gap; - } - while (sector[sectNum].wallptr > wallNum) sectNum--; - while (sector[sectNum].wallptr + sector[sectNum].wallnum <= wallNum) sectNum++; - - return sectNum; -} - -int32_t sectorofwall(int16_t wallNum) -{ - if ((unsigned)wallNum < (unsigned)numwalls) - { - native_t const w = wall[wallNum].nextwall; - return ((unsigned)w < MAXWALLS) ? wall[w].nextsector : sectorofwall_internal(wallNum); - } - return -1; -} - - int32_t getceilzofslopeptr(usectorptr_t sec, int32_t dax, int32_t day) { if (!(sec->ceilingstat&2)) diff --git a/source/core/gamefuncs.cpp b/source/core/gamefuncs.cpp index 92b8f534e..fbc6a8bcd 100644 --- a/source/core/gamefuncs.cpp +++ b/source/core/gamefuncs.cpp @@ -175,7 +175,7 @@ bool spriteIsModelOrVoxel(const spritetype * tspr) // //========================================================================== -void PlanesAtPoint(usectorptr_t sec, float dax, float day, float* pceilz, float* pflorz) +void PlanesAtPoint(const sectortype* sec, float dax, float day, float* pceilz, float* pflorz) { float ceilz = float(sec->ceilingz); float florz = float(sec->floorz); @@ -200,25 +200,3 @@ void PlanesAtPoint(usectorptr_t sec, float dax, float day, float* pceilz, float* if (pceilz) *pceilz = ceilz * -(1.f / 256.f); if (pflorz) *pflorz = florz * -(1.f / 256.f); } - -// variant that allows to pass precalculated info for the first line in. For cases where multiple points in a sector need to be checked. -void PlanesAtPoint(usectorptr_t sec, PlaneParam *pp, float dax, float day, float* pceilz, float* pflorz) -{ - float ceilz = float(sec->ceilingz); - float florz = float(sec->floorz); - - if (((sec->ceilingstat | sec->floorstat) & CSTAT_SECTOR_SLOPE) == CSTAT_SECTOR_SLOPE) - { - if (pp->length != 0) - { - auto wal = &wall[sec->wallptr]; - float const j = (pp->dx * (day - wal->y) - pp->dy * (dax - wal->x)) * (1.f / 8.f); - if (sec->ceilingstat & CSTAT_SECTOR_SLOPE) ceilz += (sec->ceilingheinum * j) / pp->length; - if (sec->floorstat & CSTAT_SECTOR_SLOPE) florz += (sec->floorheinum * j) / pp->length; - } - } - // Scale to render coordinates. - if (pceilz) *pceilz = ceilz * -(1.f / 256.f); - if (pflorz) *pflorz = florz * -(1.f / 256.f); -} - diff --git a/source/core/gamefuncs.h b/source/core/gamefuncs.h index f7ca8e8de..67955e795 100644 --- a/source/core/gamefuncs.h +++ b/source/core/gamefuncs.h @@ -8,15 +8,8 @@ extern int cameradist, cameraclock; bool calcChaseCamPos(int* px, int* py, int* pz, spritetype* pspr, short *psectnum, binangle ang, fixedhoriz horiz, double const smoothratio); bool spriteIsModelOrVoxel(const spritetype* tspr); -void PlanesAtPoint(usectorptr_t sec, float dax, float day, float* ceilz, float* florz); - -struct PlaneParam -{ - float dx, dy; - int length; -}; - -void PlanesAtPoint(usectorptr_t sec, PlaneParam* pp, float dax, float day, float* ceilz, float* florz); +void PlanesAtPoint(const sectortype* sec, float dax, float day, float* ceilz, float* florz); +void setWallSectors(); // y is negated so that the orientation is the same as in GZDoom, in order to use its utilities. // The render code should NOT use Build coordinates for anything! @@ -76,3 +69,10 @@ inline double PointOnLineSide(double x, double y, double linex, double liney, do return (x - linex) * deltay - (y - liney) * deltax; } +inline int sectorofwall(int wallNum) +{ + if ((unsigned)wallNum < (unsigned)numwalls) return wall[wallNum].sector; + return -1; +} + + diff --git a/source/core/interpolate.cpp b/source/core/interpolate.cpp index 8ccab4f41..8601b25b7 100644 --- a/source/core/interpolate.cpp +++ b/source/core/interpolate.cpp @@ -72,8 +72,8 @@ void Set(int index, int type, double val) case Interp_Sect_CeilingPanX: sector[index].ceilingxpan_ = float(val); break; case Interp_Sect_CeilingPanY: sector[index].ceilingypan_ = float(val); break; - case Interp_Wall_X: wall[index].x = xs_CRoundToInt(val); break; - case Interp_Wall_Y: wall[index].y = xs_CRoundToInt(val); break; + case Interp_Wall_X: wall[index].x = xs_CRoundToInt(val); sector[wall[index].sector].dirty = 255; break; + case Interp_Wall_Y: wall[index].y = xs_CRoundToInt(val); sector[wall[index].sector].dirty = 255; break; case Interp_Wall_PanX: wall[index].xpan_ = float(val); break; case Interp_Wall_PanY: wall[index].ypan_ = float(val); break; diff --git a/source/core/maploader.cpp b/source/core/maploader.cpp index b2c887ac6..e38ff0584 100644 --- a/source/core/maploader.cpp +++ b/source/core/maploader.cpp @@ -41,6 +41,7 @@ #include "inputstate.h" #include "md4.h" #include "gamecontrol.h" +#include "gamefuncs.h" static void ReadSectorV7(FileReader& fr, sectortype& sect) @@ -444,6 +445,7 @@ void engineLoadBoard(const char* filename, int flags, vec3_t* pos, int16_t* ang, unsigned char md4[16]; md4once(buffer.Data(), buffer.Size(), md4); G_LoadMapHack(filename, md4); + setWallSectors(); memcpy(wallbackup, wall, sizeof(wallbackup)); memcpy(sectorbackup, sector, sizeof(sectorbackup)); @@ -468,4 +470,17 @@ void loadMapBackup(const char* filename) engineLoadBoard(filename, 0, &pos, &scratch, &scratch); initspritelists(); } +} + +// Sets the sector reference for each wall. We need this for the triangulation cache. +void setWallSectors() +{ + for (int i = 0; i < numsectors; i++) + { + sector[i].dirty = 255; + for (int w = 0; w < sector[i].wallnum; w++) + { + wall[sector[i].wallptr + w].sector = i; + } + } } \ No newline at end of file diff --git a/source/core/savegamehelp.cpp b/source/core/savegamehelp.cpp index 32440c6dc..3e9faf194 100644 --- a/source/core/savegamehelp.cpp +++ b/source/core/savegamehelp.cpp @@ -56,6 +56,7 @@ #include "gamestate.h" #include "razemenu.h" #include "interpolate.h" +#include "gamefuncs.h" sectortype sectorbackup[MAXSECTORS]; @@ -670,6 +671,10 @@ void SerializeMap(FSerializer& arc) if (prevspritestat[i] == -2) prevspritestat[i] = i - 1; if (prevspritesect[i] == -2) prevspritesect[i] = i - 1; } + if (arc.isReading()) + { + setWallSectors(); + } } //============================================================================= diff --git a/source/games/blood/src/db.cpp b/source/games/blood/src/db.cpp index 1baf4f7ff..5df48a6fc 100644 --- a/source/games/blood/src/db.cpp +++ b/source/games/blood/src/db.cpp @@ -31,6 +31,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "md4.h" #include "automap.h" #include "raze_sound.h" +#include "gamefuncs.h" #include "blood.h" @@ -1058,6 +1059,7 @@ void dbLoadMap(const char *pPath, int *pX, int *pY, int *pZ, short *pAngle, shor } } + setWallSectors(); memcpy(wallbackup, wall, sizeof(wallbackup)); memcpy(sectorbackup, sector, sizeof(sectorbackup)); } diff --git a/source/games/blood/src/triggers.cpp b/source/games/blood/src/triggers.cpp index 4bbaf9c7f..5320726f6 100644 --- a/source/games/blood/src/triggers.cpp +++ b/source/games/blood/src/triggers.cpp @@ -794,6 +794,7 @@ void PathSound(int nSector, int nSound) void DragPoint(int nWall, int x, int y) { + sector[wall[nWall].sector].dirty = 255; viewInterpolateWall(nWall, &wall[nWall]); wall[nWall].x = x; wall[nWall].y = y; @@ -805,6 +806,7 @@ void DragPoint(int nWall, int x, int y) if (wall[vb].nextwall >= 0) { vb = wall[wall[vb].nextwall].point2; + sector[wall[vb].sector].dirty = 255; viewInterpolateWall(vb, &wall[vb]); wall[vb].x = x; wall[vb].y = y; @@ -817,6 +819,7 @@ void DragPoint(int nWall, int x, int y) if (wall[lastwall(vb)].nextwall >= 0) { vb = wall[lastwall(vb)].nextwall; + sector[wall[vb].sector].dirty = 255; viewInterpolateWall(vb, &wall[vb]); wall[vb].x = x; wall[vb].y = y;