diff --git a/source/build/include/build.h b/source/build/include/build.h index 71e84c6c5..39b4badde 100644 --- a/source/build/include/build.h +++ b/source/build/include/build.h @@ -428,10 +428,10 @@ void neartag(int32_t xs, int32_t ys, int32_t zs, int16_t sectnum, int16_t ange int32_t cansee(int32_t x1, int32_t y1, int32_t z1, int16_t sect1, int32_t x2, int32_t y2, int32_t z2, int16_t sect2); int32_t inside(int32_t x, int32_t y, int sectnum); -void dragpoint(int pointhighlight, int32_t dax, int32_t day, uint8_t flags = 0); -inline void dragpoint(walltype* pointhighlight, int32_t dax, int32_t day, uint8_t flags = 0) +void dragpoint(int pointhighlight, int32_t dax, int32_t day); +inline void dragpoint(walltype* pointhighlight, int32_t dax, int32_t day) { - dragpoint(int(pointhighlight - wall), dax, day, 0); + dragpoint(int(pointhighlight - wall), dax, day); } int32_t try_facespr_intersect(uspriteptr_t const spr, vec3_t const in, int32_t vx, int32_t vy, int32_t vz, diff --git a/source/build/src/engine.cpp b/source/build/src/engine.cpp index 695245476..233821b7c 100644 --- a/source/build/src/engine.cpp +++ b/source/build/src/engine.cpp @@ -62,8 +62,6 @@ int16_t pskybits_override = -1; static int32_t beforedrawrooms = 1; -static int8_t tempbuf[MAXWALLS]; - static int32_t no_radarang2 = 0; static int16_t radarang[1280]; @@ -1075,73 +1073,56 @@ void neartag(int32_t xs, int32_t ys, int32_t zs, int16_t sectnum, int16_t ange, // // dragpoint // -// flags: -// 1: don't reset walbitmap[] (the bitmap of already dragged vertices) -// 2: In the editor, do wall[].cstat |= (1<<14) also for the lastwall(). -void dragpoint(int pointhighlight, int32_t dax, int32_t day, uint8_t flags) +void dragpoint(int w, int32_t dax, int32_t day) { - int32_t i, numyaxwalls=0; - static int16_t yaxwalls[MAXWALLS]; + BFSSearch walbitmap(numwalls); + int clockwise = 0; + const int tmpstartwall = w; + int cnt = 16384; // limit the number of iterations. - uint8_t *const walbitmap = (uint8_t *)tempbuf; - - if ((flags&1)==0) - memset(walbitmap, 0, (numwalls+7)>>3); - yaxwalls[numyaxwalls++] = pointhighlight; - - for (i=0; i>3] |= (1<<(w&7)); - - if (!clockwise) //search points CCW + if (wall[w].nextwall >= 0) + w = wall[wall[w].nextwall].point2; + else { - if (wall[w].nextwall >= 0) - w = wall[wall[w].nextwall].point2; - else - { - w = tmpstartwall; - clockwise = 1; - } - } - - cnt--; - if (cnt==0) - { - Printf("dragpoint %d: infloop!\n", pointhighlight); - i = numyaxwalls; - break; - } - - if (clockwise) - { - int32_t thelastwall = lastwall(w); - if (wall[thelastwall].nextwall >= 0) - w = wall[thelastwall].nextwall; - else - break; - } - - if ((walbitmap[w>>3] & (1<<(w&7)))) - { - if (clockwise) - break; - w = tmpstartwall; clockwise = 1; - continue; } } + + cnt--; + if (cnt==0) + { + Printf("dragpoint %d: infinite loop!\n", w); + break; + } + + if (clockwise) + { + int32_t thelastwall = lastwall(w); + if (wall[thelastwall].nextwall >= 0) + w = wall[thelastwall].nextwall; + else + break; + } + + if (walbitmap.Check(w)) + { + if (clockwise) + break; + + w = tmpstartwall; + clockwise = 1; + continue; + } } } diff --git a/source/core/gamefuncs.h b/source/core/gamefuncs.h index 44a9fcd41..cb855307a 100644 --- a/source/core/gamefuncs.h +++ b/source/core/gamefuncs.h @@ -29,6 +29,16 @@ public: Set(startnode); store.Push(startnode); } + + // This allows this object to just work as a bit array + // which is useful for using its shared storage. + BFSSearch(unsigned datasize) + { + bitpos = store.Size(); + unsigned bitsize = (datasize + 31) >> 5; + store.Reserve(bitsize); + memset(&store[bitpos], 0, bitsize * 4); + } ~BFSSearch() { @@ -40,12 +50,13 @@ public: return !!(store[bitpos + (index >> 5)] & (1 << (index & 31))); } -private: void Set(unsigned index) { store[bitpos + (index >> 5)] |= (1 << (index & 31)); } + +private: public: unsigned GetNext() { diff --git a/source/games/exhumed/src/init.cpp b/source/games/exhumed/src/init.cpp index b18a66e71..241d56ddc 100644 --- a/source/games/exhumed/src/init.cpp +++ b/source/games/exhumed/src/init.cpp @@ -260,7 +260,7 @@ void SnapSectors(int nSectorA, int nSectorB, int b) nCount2++; } - dragpoint(bestwall, bestwall->x + bestx, bestwall->y + besty, 0); + dragpoint(bestwall, bestwall->x + bestx, bestwall->y + besty); nCount++; nWallA++; diff --git a/source/games/exhumed/src/move.cpp b/source/games/exhumed/src/move.cpp index 2c97cd4c1..acc393bfb 100644 --- a/source/games/exhumed/src/move.cpp +++ b/source/games/exhumed/src/move.cpp @@ -1058,7 +1058,7 @@ void MoveSector(int nSector, int nAngle, int *nXVel, int *nYVel) for (int i = 0; i < nWalls; i++) { - dragpoint(startwall, xvect + pStartWall->x, yvect + pStartWall->y, 0); + dragpoint(startwall, xvect + pStartWall->x, yvect + pStartWall->y); pStartWall++; startwall++; } diff --git a/source/games/exhumed/src/object.cpp b/source/games/exhumed/src/object.cpp index 1ac006fc9..04b197888 100644 --- a/source/games/exhumed/src/object.cpp +++ b/source/games/exhumed/src/object.cpp @@ -1129,7 +1129,7 @@ void AISlide::Tick(RunListEvent* ev) int var_2C = nSeekB; int var_24 = nSeekB; - dragpoint(SlideData[nSlide].field_4, x, y, 0); + dragpoint(SlideData[nSlide].field_4, x, y); movesprite(SlideData[nSlide].pActor, var_34 << 14, var_2C << 14, 0, 0, 0, CLIPMASK1); if (var_34 == 0) @@ -1145,7 +1145,7 @@ void AISlide::Tick(RunListEvent* ev) y = wall[nWall].y + var_24; x = wall[nWall].x + var_20; - dragpoint(SlideData[nSlide].field_0, x, y, 0); + dragpoint(SlideData[nSlide].field_0, x, y); nWall = SlideData[nSlide].field_C; @@ -1160,7 +1160,7 @@ void AISlide::Tick(RunListEvent* ev) int edi = nSeekD; var_24 = nSeekD; - dragpoint(SlideData[nSlide].field_C, x, y, 0); + dragpoint(SlideData[nSlide].field_C, x, y); if (var_30 == 0 && edi == 0) { ebp++; @@ -1171,7 +1171,7 @@ void AISlide::Tick(RunListEvent* ev) x = wall[nWall].x + var_20; y = wall[nWall].y + var_24; - dragpoint(SlideData[nSlide].field_8, x, y, 0); + dragpoint(SlideData[nSlide].field_8, x, y); } else if (cx == 0) // right branch { @@ -1187,7 +1187,7 @@ void AISlide::Tick(RunListEvent* ev) int ecx = nSeekB; int var_28 = nSeekB; - dragpoint(SlideData[nSlide].field_0, x, y, 0); + dragpoint(SlideData[nSlide].field_0, x, y); if (edi == 0 && ecx == 0) { ebp = clipmask; @@ -1198,7 +1198,7 @@ void AISlide::Tick(RunListEvent* ev) y = wall[nWall].y + var_28; x = wall[nWall].x + var_1C; - dragpoint(SlideData[nSlide].field_4, x, y, 0); + dragpoint(SlideData[nSlide].field_4, x, y); nWall = SlideData[nSlide].field_8; @@ -1213,7 +1213,7 @@ void AISlide::Tick(RunListEvent* ev) ecx = nSeekD; var_28 = nSeekD; - dragpoint(SlideData[nSlide].field_8, x, y, 0); + dragpoint(SlideData[nSlide].field_8, x, y); if (edi == 0 && ecx == 0) { ebp++; @@ -1224,7 +1224,7 @@ void AISlide::Tick(RunListEvent* ev) y = wall[nWall].y + var_28; x = wall[nWall].x + var_1C; - dragpoint(SlideData[nSlide].field_C, x, y, 0); + dragpoint(SlideData[nSlide].field_C, x, y); } // loc_21A51: diff --git a/source/games/sw/src/morph.cpp b/source/games/sw/src/morph.cpp index 2e49e5675..3175b2df2 100644 --- a/source/games/sw/src/morph.cpp +++ b/source/games/sw/src/morph.cpp @@ -349,7 +349,7 @@ MorphTornado(SECTOR_OBJECTp sop) sop->morph_ang = RANDOM_P2(2048); // move it x,y - dragpoint(sop->morph_wall_point, mx, my, 0); + dragpoint(sop->morph_wall_point, mx, my); // bound the Z ceilingz = sector[sop->op_main_sector].ceilingz; @@ -428,7 +428,7 @@ MorphFloor(SECTOR_OBJECTp sop) sop->morph_ang = RANDOM_P2(2048); // move x,y point "just like in build" - dragpoint(sop->morph_wall_point, mx, my, 0); + dragpoint(sop->morph_wall_point, mx, my); // bound the Z floorz = sector[sop->op_main_sector].floorz; diff --git a/source/games/sw/src/rotator.cpp b/source/games/sw/src/rotator.cpp index 526d0989f..37728184d 100644 --- a/source/games/sw/src/rotator.cpp +++ b/source/games/sw/src/rotator.cpp @@ -390,7 +390,7 @@ int DoRotator(DSWActor* actor) vec2_t const orig = { r->origX[ndx], r->origY[ndx] }; rotatepoint(pivot->pos.vec2, orig, r->pos, &nxy); - dragpoint(w, nxy.x, nxy.y, 0); + dragpoint(w, nxy.x, nxy.y); ndx++; } diff --git a/source/games/sw/src/sector.cpp b/source/games/sw/src/sector.cpp index 83903f649..8c809e095 100644 --- a/source/games/sw/src/sector.cpp +++ b/source/games/sw/src/sector.cpp @@ -2576,13 +2576,13 @@ void DoSineWaveWall(void) { New = sw->orig_xy + MulScale(sw->range, bsin(sw->sintable_ndx), 14); // wall[sw->wall].y = New; - dragpoint(sw->wall, wall[sw->wall].x, New, 0); + dragpoint(sw->wall, wall[sw->wall].x, New); } else { New = sw->orig_xy + MulScale(sw->range, bsin(sw->sintable_ndx), 14); // wall[sw->wall].x = New; - dragpoint(sw->wall, New, wall[sw->wall].y, 0); + dragpoint(sw->wall, New, wall[sw->wall].y); } } } diff --git a/source/games/sw/src/slidor.cpp b/source/games/sw/src/slidor.cpp index f85c79a56..c37a04aa5 100644 --- a/source/games/sw/src/slidor.cpp +++ b/source/games/sw/src/slidor.cpp @@ -380,8 +380,8 @@ int DoSlidorMoveWalls(DSWActor* actor, int amt) else { // red wall - move 2 points - dragpoint(w, wall[w].x - amt, wall[w].y, 0); - dragpoint(wall[w].point2, wall[wall[w].point2].x - amt, wall[wall[w].point2].y, 0); + dragpoint(w, wall[w].x - amt, wall[w].y); + dragpoint(wall[w].point2, wall[wall[w].point2].x - amt, wall[wall[w].point2].y); } break; @@ -404,8 +404,8 @@ int DoSlidorMoveWalls(DSWActor* actor, int amt) else { // red wall - move 2 points - dragpoint(w, wall[w].x + amt, wall[w].y, 0); - dragpoint(wall[w].point2, wall[wall[w].point2].x + amt, wall[wall[w].point2].y, 0); + dragpoint(w, wall[w].x + amt, wall[w].y); + dragpoint(wall[w].point2, wall[wall[w].point2].x + amt, wall[wall[w].point2].y); } break; @@ -426,8 +426,8 @@ int DoSlidorMoveWalls(DSWActor* actor, int amt) } else { - dragpoint(w, wall[w].x, wall[w].y - amt, 0); - dragpoint(wall[w].point2, wall[wall[w].point2].x, wall[wall[w].point2].y - amt, 0); + dragpoint(w, wall[w].x, wall[w].y - amt); + dragpoint(wall[w].point2, wall[wall[w].point2].x, wall[wall[w].point2].y - amt); } break; @@ -448,8 +448,8 @@ int DoSlidorMoveWalls(DSWActor* actor, int amt) } else { - dragpoint(w, wall[w].x, wall[w].y + amt, 0); - dragpoint(wall[w].point2, wall[wall[w].point2].x, wall[wall[w].point2].y + amt, 0); + dragpoint(w, wall[w].x, wall[w].y + amt); + dragpoint(wall[w].point2, wall[wall[w].point2].x, wall[wall[w].point2].y + amt); } diff --git a/source/games/sw/src/track.cpp b/source/games/sw/src/track.cpp index 93e962355..2f8c26cdd 100644 --- a/source/games/sw/src/track.cpp +++ b/source/games/sw/src/track.cpp @@ -1708,7 +1708,7 @@ void MovePoints(SECTOR_OBJECTp sop, short delta_ang, int nx, int ny) if (wp->extra && TEST(wp->extra, WALLFX_LOOP_OUTER)) { - dragpoint(k, wp->x += nx, wp->y += ny, 0); + dragpoint(k, wp->x += nx, wp->y += ny); } else { @@ -1731,7 +1731,7 @@ void MovePoints(SECTOR_OBJECTp sop, short delta_ang, int nx, int ny) if (wp->extra && TEST(wp->extra, WALLFX_LOOP_OUTER)) { - dragpoint(k, rxy.x, rxy.y, 0); + dragpoint(k, rxy.x, rxy.y); } else { @@ -1957,7 +1957,7 @@ void RefreshPoints(SECTOR_OBJECTp sop, int nx, int ny, bool dynamic) if (wp->extra && TEST(wp->extra, WALLFX_LOOP_OUTER)) { - dragpoint(k, dx, dy, 0); + dragpoint(k, dx, dy); } else { @@ -2119,7 +2119,7 @@ void CollapseSectorObject(SECTOR_OBJECTp sop, int nx, int ny) if (wp->extra && TEST(wp->extra, WALLFX_LOOP_OUTER)) { - dragpoint(k, nx, ny, 0); + dragpoint(k, nx, ny); } else {