diff --git a/source/build/include/build.h b/source/build/include/build.h index 51e3228ff..844e85f29 100644 --- a/source/build/include/build.h +++ b/source/build/include/build.h @@ -352,21 +352,6 @@ inline constexpr uint32_t uhypsq(int32_t const dx, int32_t const dy) } void rotatepoint(vec2_t const pivot, vec2_t p, int16_t const daang, vec2_t * const p2) ATTRIBUTE((nonnull(4))); -inline void rotatepoint(int px, int py, int ptx, int pty, int daang, int* resx, int* resy) -{ - vec2_t pivot = { px, py }; - vec2_t point = { ptx, pty }; - vec2_t result; - rotatepoint(pivot, point, daang, &result); - *resx = result.x; - *resy = result.y; -} - -int32_t lastwall(int16_t point); -inline walltype* lastwall(walltype* point) -{ - return &wall[lastwall(wall.IndexOf(point))]; -} sectortype* nextsectorneighborzptr(sectortype* sectp, int refz, int topbottom, int direction); inline sectortype* safenextsectorneighborzptr(sectortype* sectp, int refz, int topbottom, int direction) @@ -590,6 +575,21 @@ inline sectortype* walltype::sectorp() const return &::sector[sector]; // cannot be -1 in a proper map. } +inline walltype* walltype::lastWall() const +{ + int index = wall.IndexOf(this); + if (index > 0 && wall[index - 1].point2 == index) return &wall[index - 1]; + + int check = index; + for (int i = 0; i < numwalls; i++) + { + int next = wall[check].point2; + if (next == index) return &wall[check]; + check = next; + } + return nullptr; +} + inline walltype* walltype::point2Wall() const { return &::wall[point2]; // cannot be -1 in a proper map. @@ -605,5 +605,19 @@ inline walltype* sectortype::lastWall() const return &wall[wallptr + wallnum - 1]; // cannot be -1 in a proper map } +inline void walltype::moved() +{ + lengthflags = 3; + sectorp()->dirty = EDirty::AllDirty; +} + +inline void walltype::move(int newx, int newy) +{ + pos.x = newx; + pos.y = newy; + lengthflags = 3; + sectorp()->dirty = EDirty::AllDirty; +} + #endif // build_h_ diff --git a/source/build/include/buildtypes.h b/source/build/include/buildtypes.h index 141a37ea1..b6b893e7e 100644 --- a/source/build/include/buildtypes.h +++ b/source/build/include/buildtypes.h @@ -208,10 +208,12 @@ struct walltype }; int16_t hitag; int16_t extra; + uint16_t portalnum; float xpan_, ypan_; binangle clipangle; uint8_t portalflags; - uint16_t portalnum; + uint8_t lengthflags; + int length; // cached value to avoid calling sqrt repeatedly. // Blood is the only game which extends the wall struct. Blood::XWALL* _xw; @@ -226,12 +228,15 @@ struct walltype sectortype* nextSector() const; sectortype* sectorp() const; walltype* nextWall() const; + walltype* lastWall() const; walltype* point2Wall() const; vec2_t delta() const { return point2Wall()->pos - pos; } vec2_t center() const { return(point2Wall()->pos + pos) / 2; } int deltax() const { return point2Wall()->x - x; } int deltay() const { return point2Wall()->y - y; } bool twoSided() const { return nextsector >= 0; } + void move(int newx, int newy); + void moved(); Blood::XWALL& xw() const { return *_xw; } bool hasX() const { return _xw != nullptr; } diff --git a/source/build/src/engine.cpp b/source/build/src/engine.cpp index 553313c6c..e6f0da772 100644 --- a/source/build/src/engine.cpp +++ b/source/build/src/engine.cpp @@ -626,9 +626,7 @@ void dragpoint(int w, int32_t dax, int32_t day) while (1) { auto wal = &wall[w]; - sector[wal->sector].dirty = EDirty::AllDirty; - wal->x = dax; - wal->y = day; + wal->move(dax, day); walbitmap.Set(w); if (!clockwise) //search points CCW @@ -651,9 +649,9 @@ void dragpoint(int w, int32_t dax, int32_t day) if (clockwise) { - int32_t thelastwall = lastwall(w); - if (wall[thelastwall].nextwall >= 0) - w = wall[thelastwall].nextwall; + auto thelastwall = wall[w].lastWall(); + if (thelastwall->nextwall >= 0) + w = thelastwall->nextwall; else break; } @@ -670,32 +668,6 @@ void dragpoint(int w, int32_t dax, int32_t day) } } -// -// lastwall -// -int32_t lastwall(int16_t point) -{ - if (point > 0 && wall[point-1].point2 == point) - return point-1; - - int i = point, cnt = numwalls; - do - { - int const j = wall[i].point2; - - if (j == point) - { - point = i; - break; - } - - i = j; - } - while (--cnt); - - return point; -} - ////////// UPDATESECTOR* FAMILY OF FUNCTIONS ////////// /* Different "is inside" predicates. diff --git a/source/core/interpolate.cpp b/source/core/interpolate.cpp index 2c40e277b..aeb1394a9 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: old = wall[index].x; wall[index].x = xs_CRoundToInt(val); if (wall[index].x != old) sector[wall[index].sector].dirty = EDirty::AllDirty; break; - case Interp_Wall_Y: old = wall[index].y; wall[index].y = xs_CRoundToInt(val); if (wall[index].y != old) sector[wall[index].sector].dirty = EDirty::AllDirty; break; + case Interp_Wall_X: old = wall[index].x; wall[index].x = xs_CRoundToInt(val); if (wall[index].x != old) wall[index].moved(); break; + case Interp_Wall_Y: old = wall[index].y; wall[index].y = xs_CRoundToInt(val); if (wall[index].y != old) wall[index].moved(); 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 0df78de8a..02211acd4 100644 --- a/source/core/maploader.cpp +++ b/source/core/maploader.cpp @@ -525,7 +525,9 @@ void setWallSectors() for (auto& wal : walls()) { wal.sector = -1; + wal.lengthflags = 3; } + for (int i = 0; i < numsectors - 1; i++) { auto sect = §or[i]; diff --git a/source/core/rendering/scene/hw_drawinfo.cpp b/source/core/rendering/scene/hw_drawinfo.cpp index 84f152062..972d5f266 100644 --- a/source/core/rendering/scene/hw_drawinfo.cpp +++ b/source/core/rendering/scene/hw_drawinfo.cpp @@ -417,7 +417,7 @@ void HWDrawInfo::CreateScene(bool portal) wal->x += eff.geox[i]; wal->y += eff.geoy[i]; } - sect->dirty = 255; + sect->dirty = EDirty::AllDirty; if (eff.geosector[i] == drawsectp) drawsectp = eff.geosectorwarp[i]; } @@ -449,7 +449,7 @@ void HWDrawInfo::CreateScene(bool portal) wal->x += eff.geox2[i]; wal->y += eff.geoy2[i]; } - sect->dirty = 255; + sect->dirty = EDirty::AllDirty; if (eff.geosector[i] == orgdrawsectp) drawsectp = eff.geosectorwarp2[i]; } diff --git a/source/games/blood/src/db.cpp b/source/games/blood/src/db.cpp index 2ef4eb9a8..94ed11070 100644 --- a/source/games/blood/src/db.cpp +++ b/source/games/blood/src/db.cpp @@ -329,7 +329,7 @@ void dbLoadMap(const char* pPath, int* pX, int* pY, int* pZ, short* pAngle, sect pSector->floorypan_ = load.floorypanning; pSector->visibility = load.visibility; pSector->slopewallofs = load.fogpal; - pSector->dirty = 255; + pSector->dirty = EDirty::AllDirty; pSector->exflags = 0; pSector->fogpal = 0; diff --git a/source/games/blood/src/triggers.cpp b/source/games/blood/src/triggers.cpp index 0919b2602..11c109ae8 100644 --- a/source/games/blood/src/triggers.cpp +++ b/source/games/blood/src/triggers.cpp @@ -759,10 +759,8 @@ void PathSound(sectortype* pSector, int nSound) void DragPoint(walltype* pWall, int x, int y) { - pWall->sectorp()->dirty = 255; viewInterpolateWall(pWall); - pWall->x = x; - pWall->y = y; + pWall->move(x, y); int vsi = numwalls; auto prevWall = pWall; @@ -771,24 +769,20 @@ void DragPoint(walltype* pWall, int x, int y) if (prevWall->twoSided()) { prevWall = prevWall->nextWall()->point2Wall(); - prevWall->sectorp()->dirty = 255; viewInterpolateWall(prevWall); - prevWall->x = x; - prevWall->y = y; + prevWall->move(x, y); } else { prevWall = pWall; do { - auto lw = lastwall(prevWall); - if (lw->twoSided()) + auto lw = prevWall->lastWall(); + if (lw && lw->twoSided()) { prevWall = lw->nextWall(); - prevWall->sectorp()->dirty = 255; viewInterpolateWall(prevWall); - prevWall->x = x; - prevWall->y = y; + prevWall->move(x, y); } else break; diff --git a/source/games/duke/src/actors.cpp b/source/games/duke/src/actors.cpp index 437f67537..513fc5453 100644 --- a/source/games/duke/src/actors.cpp +++ b/source/games/duke/src/actors.cpp @@ -281,7 +281,6 @@ void ms(DDukeActor* const actor) { //T1,T2 and T3 are used for all the sector moving stuff!!! - int tx, ty; auto s = actor->s; s->x += MulScale(s->xvel, bcos(s->ang), 14); @@ -292,12 +291,10 @@ void ms(DDukeActor* const actor) for(auto& wal : wallsofsector(actor->sector())) { - rotatepoint( - 0, 0, - msx[j], msy[j], - k & 2047, &tx, &ty); + vec2_t t; + rotatepoint({ 0, 0 }, { msx[j], msy[j] }, k & 2047, &t); - dragpoint(&wal, s->x + tx, s->y + ty); + dragpoint(&wal, s->x + t.x, s->y + t.y); j++; } } @@ -2751,20 +2748,18 @@ void handle_se00(DDukeActor* actor, int LASERLINE) ps[p].pos.z += zchange; - int m, x; - rotatepoint(Owner->s->x, Owner->s->y, ps[p].pos.x, ps[p].pos.y, (q * l), &m, &x); + vec2_t res; + rotatepoint(Owner->s->pos.vec2, ps[p].pos.vec2, (q * l), &res); - ps[p].bobposx += m - ps[p].pos.x; - ps[p].bobposy += x - ps[p].pos.y; + ps[p].bobposx += res.x - ps[p].pos.x; + ps[p].bobposy += res.y - ps[p].pos.y; - ps[p].pos.x = m; - ps[p].pos.y = x; + ps[p].pos.vec2 = res; auto psp = ps[p].GetActor(); if (psp->s->extra <= 0) { - psp->s->x = m; - psp->s->y = x; + psp->s->pos.vec2 = res; } } } @@ -2784,7 +2779,7 @@ void handle_se00(DDukeActor* actor, int LASERLINE) sprp->ang &= 2047; sprp->z += zchange; - rotatepoint(Owner->s->x, Owner->s->y, ap->s->x, ap->s->y, (q* l), &ap->s->x, &ap->s->y); + rotatepoint(Owner->s->pos.vec2, ap->s->pos.vec2, (q* l), &ap->s->pos.vec2); } } @@ -2932,7 +2927,7 @@ void handle_se14(DDukeActor* actor, bool checkstat, int RPG, int JIBS6) if (s->sector() == psp->s->sector()) { - rotatepoint(s->x, s->y, ps[p].pos.x, ps[p].pos.y, q, &ps[p].pos.x, &ps[p].pos.y); + rotatepoint(s->pos.vec2, ps[p].pos.vec2, q, &ps[p].pos.vec2); ps[p].pos.x += m; ps[p].pos.y += x; @@ -2961,7 +2956,7 @@ void handle_se14(DDukeActor* actor, bool checkstat, int RPG, int JIBS6) auto sj = a2->s; if (sj->statnum != 10 && sj->sector()->lotag != 2 && sj->picnum != SECTOREFFECTOR && sj->picnum != LOCATORS) { - rotatepoint(s->x, s->y, sj->x, sj->y, q, &sj->x, &sj->y); + rotatepoint(s->pos.vec2, sj->pos.vec2, q, &sj->pos.vec2); sj->x += m; sj->y += x; diff --git a/source/games/duke/src/funct.h b/source/games/duke/src/funct.h index c7424dfa4..610711b14 100644 --- a/source/games/duke/src/funct.h +++ b/source/games/duke/src/funct.h @@ -237,6 +237,6 @@ void loadcons(); void recordoldspritepos(); void DrawStatusBar(); -int* animateptr(int i); +int* animateptr(int i, bool write = true); END_DUKE_NS diff --git a/source/games/duke/src/sectors.cpp b/source/games/duke/src/sectors.cpp index 2a2822b74..63aa2ff46 100644 --- a/source/games/duke/src/sectors.cpp +++ b/source/games/duke/src/sectors.cpp @@ -278,7 +278,7 @@ int findotherplayer(int p, int* d) // //--------------------------------------------------------------------------- -int* animateptr(int type, int index) +int* animateptr(int type, int index, bool write) { static int scratch; switch (type) @@ -288,8 +288,10 @@ int* animateptr(int type, int index) case anim_ceilingz: return §or[index].ceilingz; case anim_vertexx: + if (write) wall[index].moved(); return &wall[index].x; case anim_vertexy: + if (write) wall[index].moved(); return &wall[index].y; default: assert(false); @@ -297,9 +299,9 @@ int* animateptr(int type, int index) } } -int* animateptr(int i) +int* animateptr(int i, bool write) { - return animateptr(animatetype[i], animatetarget[i]); + return animateptr(animatetype[i], animatetarget[i], write); } //--------------------------------------------------------------------------- @@ -314,7 +316,7 @@ void doanimations(void) for (i = animatecnt - 1; i >= 0; i--) { - a = *animateptr(i); + a = *animateptr(i, false); v = animatevel[i] * TICSPERFRAME; auto dasectp = animatesect[i]; @@ -365,7 +367,7 @@ void doanimations(void) } } - *animateptr(i) = a; + *animateptr(i, true) = a; } } @@ -411,7 +413,7 @@ static int dosetanimation(sectortype* animsect, int animtype, int animtarget, in break; } - auto animptr = animateptr(animtype, animtarget); + auto animptr = animateptr(animtype, animtarget, false); animatesect[j] = animsect; animatetype[j] = animtype; animatetarget[j] = animtarget; diff --git a/source/games/sw/src/interpso.cpp b/source/games/sw/src/interpso.cpp index b145ffaf2..d1b26d275 100644 --- a/source/games/sw/src/interpso.cpp +++ b/source/games/sw/src/interpso.cpp @@ -96,10 +96,10 @@ static int &getvalue(so_interp::interp_data& element, bool write) switch (type) { case soi_wallx: - if (write) wall[index].sectorp()->dirty = 255; + if (write) wall[index].moved(); return wall[index].x; case soi_wally: - if (write) wall[index].sectorp()->dirty = 255; + if (write) wall[index].moved(); return wall[index].y; case soi_ceil: return sector[index].ceilingz; diff --git a/source/games/sw/src/slidor.cpp b/source/games/sw/src/slidor.cpp index 226aa0048..f56886af2 100644 --- a/source/games/sw/src/slidor.cpp +++ b/source/games/sw/src/slidor.cpp @@ -297,10 +297,11 @@ int DoSlidorMoveWalls(DSWActor* actor, int amt) if (!wal->twoSided()) { // white wall - move 4 points - wal->x -= amt; - pwal->x -= amt; - wal->point2Wall()->x -= amt; - wal->point2Wall()->point2Wall()->x -= amt; + wal->move(wal->x - amt, wal->y); + pwal->move(pwal->x - amt, pwal->y); + wal->point2Wall()->move(wal->point2Wall()->x - amt, wal->point2Wall()->y); + auto pwal2 = wal->point2Wall()->point2Wall(); + pwal2->move(pwal2->x - amt, pwal2->y); } else { @@ -321,10 +322,11 @@ int DoSlidorMoveWalls(DSWActor* actor, int amt) if (!wal->twoSided()) { // white wall - move 4 points - wal->x += amt; - pwal->x += amt; - wal->point2Wall()->x += amt; - wal->point2Wall()->point2Wall()->x += amt; + wal->move(wal->x + amt, wal->y); + pwal->move(pwal->x + amt, pwal->y); + wal->point2Wall()->move(wal->point2Wall()->x + amt, wal->point2Wall()->y); + auto pwal2 = wal->point2Wall()->point2Wall(); + pwal2->move(pwal2->x + amt, pwal2->y); } else { @@ -344,10 +346,11 @@ int DoSlidorMoveWalls(DSWActor* actor, int amt) if (!wal->twoSided()) { - wal->y -= amt; - pwal->y -= amt; - wal->point2Wall()->y -= amt; - wal->point2Wall()->point2Wall()->y -= amt; + wal->move(wal->x, wal->y - amt); + pwal->move(pwal->x, pwal->y - amt); + wal->point2Wall()->move(wal->point2Wall()->x, wal->point2Wall()->y - amt); + auto pwal2 = wal->point2Wall()->point2Wall(); + pwal2->move(pwal2->x, pwal2->y - amt); } else { @@ -366,10 +369,11 @@ int DoSlidorMoveWalls(DSWActor* actor, int amt) if (!wal->twoSided()) { - wal->y += amt; - pwal->y += amt; - wal->point2Wall()->y += amt; - wal->point2Wall()->point2Wall()->y += amt; + wal->move(wal->x, wal->y + amt); + pwal->move(pwal->x, pwal->y + amt); + wal->point2Wall()->move(wal->point2Wall()->x, wal->point2Wall()->y + amt); + auto pwal2 = wal->point2Wall()->point2Wall(); + pwal2->move(pwal2->x, pwal2->y + amt); } else { diff --git a/source/games/sw/src/sprite.cpp b/source/games/sw/src/sprite.cpp index d17d91ad7..ec1b10291 100644 --- a/source/games/sw/src/sprite.cpp +++ b/source/games/sw/src/sprite.cpp @@ -1513,8 +1513,7 @@ void PreMapCombineFloors(void) for (auto& wal : wallsofsector(dasect)) { - wal.x += dx; - wal.y += dy; + wal.move(wal.x + dx, wal.y + dy); if (wal.twoSided()) search.Add(wal.nextSector()); diff --git a/source/games/sw/src/track.cpp b/source/games/sw/src/track.cpp index 11b77d7c9..9ab0a1aa0 100644 --- a/source/games/sw/src/track.cpp +++ b/source/games/sw/src/track.cpp @@ -1687,12 +1687,11 @@ void MovePoints(SECTOR_OBJECTp sop, short delta_ang, int nx, int ny) if (wal.extra && TEST(wal.extra, WALLFX_LOOP_OUTER)) { - dragpoint(&wal, wal.x += nx, wal.y += ny); + dragpoint(&wal, wal.x + nx, wal.y + ny); } else { - wal.x += nx; - wal.y += ny; + wal.move(wal.x + nx, wal.y + ny); } rot_ang = delta_ang; @@ -1714,8 +1713,7 @@ void MovePoints(SECTOR_OBJECTp sop, short delta_ang, int nx, int ny) } else { - wal.x = rxy.x; - wal.y = rxy.y; + wal.move(rxy.x, rxy.y); } } @@ -1938,8 +1936,7 @@ void RefreshPoints(SECTOR_OBJECTp sop, int nx, int ny, bool dynamic) } else { - wal.x = dx; - wal.y = dy; + wal.move(dx, dy); } } @@ -2093,8 +2090,7 @@ void CollapseSectorObject(SECTOR_OBJECTp sop, int nx, int ny) } else { - wal.x = nx; - wal.y = ny; + wal.move(nx, ny); } } } diff --git a/source/games/sw/src/wallmove.cpp b/source/games/sw/src/wallmove.cpp index ef18fd942..0435f7f67 100644 --- a/source/games/sw/src/wallmove.cpp +++ b/source/games/sw/src/wallmove.cpp @@ -119,9 +119,7 @@ int DoWallMove(DSWActor* actor) } else { - wal.x = sp->x + nx; - wal.y = sp->y + ny; - wal.sectorp()->dirty = 255; + wal.move(sp->x + nx, sp->y + ny); } if (shade1)