- make sure that all changes of wall coordinates invalidate associated data.

walltype::move should be the preferred function to be used for this, otherwise walltype::moved needs to be called.
This commit is contained in:
Christoph Oelckers 2021-12-17 18:22:42 +01:00
parent 737291ce5f
commit 4a5de6f56e
16 changed files with 101 additions and 120 deletions

View file

@ -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))); 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); sectortype* nextsectorneighborzptr(sectortype* sectp, int refz, int topbottom, int direction);
inline sectortype* safenextsectorneighborzptr(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. 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 inline walltype* walltype::point2Wall() const
{ {
return &::wall[point2]; // cannot be -1 in a proper map. 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 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_ #endif // build_h_

View file

@ -208,10 +208,12 @@ struct walltype
}; };
int16_t hitag; int16_t hitag;
int16_t extra; int16_t extra;
uint16_t portalnum;
float xpan_, ypan_; float xpan_, ypan_;
binangle clipangle; binangle clipangle;
uint8_t portalflags; 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 is the only game which extends the wall struct.
Blood::XWALL* _xw; Blood::XWALL* _xw;
@ -226,12 +228,15 @@ struct walltype
sectortype* nextSector() const; sectortype* nextSector() const;
sectortype* sectorp() const; sectortype* sectorp() const;
walltype* nextWall() const; walltype* nextWall() const;
walltype* lastWall() const;
walltype* point2Wall() const; walltype* point2Wall() const;
vec2_t delta() const { return point2Wall()->pos - pos; } vec2_t delta() const { return point2Wall()->pos - pos; }
vec2_t center() const { return(point2Wall()->pos + pos) / 2; } vec2_t center() const { return(point2Wall()->pos + pos) / 2; }
int deltax() const { return point2Wall()->x - x; } int deltax() const { return point2Wall()->x - x; }
int deltay() const { return point2Wall()->y - y; } int deltay() const { return point2Wall()->y - y; }
bool twoSided() const { return nextsector >= 0; } bool twoSided() const { return nextsector >= 0; }
void move(int newx, int newy);
void moved();
Blood::XWALL& xw() const { return *_xw; } Blood::XWALL& xw() const { return *_xw; }
bool hasX() const { return _xw != nullptr; } bool hasX() const { return _xw != nullptr; }

View file

@ -626,9 +626,7 @@ void dragpoint(int w, int32_t dax, int32_t day)
while (1) while (1)
{ {
auto wal = &wall[w]; auto wal = &wall[w];
sector[wal->sector].dirty = EDirty::AllDirty; wal->move(dax, day);
wal->x = dax;
wal->y = day;
walbitmap.Set(w); walbitmap.Set(w);
if (!clockwise) //search points CCW if (!clockwise) //search points CCW
@ -651,9 +649,9 @@ void dragpoint(int w, int32_t dax, int32_t day)
if (clockwise) if (clockwise)
{ {
int32_t thelastwall = lastwall(w); auto thelastwall = wall[w].lastWall();
if (wall[thelastwall].nextwall >= 0) if (thelastwall->nextwall >= 0)
w = wall[thelastwall].nextwall; w = thelastwall->nextwall;
else else
break; 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 ////////// ////////// UPDATESECTOR* FAMILY OF FUNCTIONS //////////
/* Different "is inside" predicates. /* Different "is inside" predicates.

View file

@ -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_CeilingPanX: sector[index].ceilingxpan_ = float(val); break;
case Interp_Sect_CeilingPanY: sector[index].ceilingypan_ = 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_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) 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) wall[index].moved(); break;
case Interp_Wall_PanX: wall[index].xpan_ = float(val); break; case Interp_Wall_PanX: wall[index].xpan_ = float(val); break;
case Interp_Wall_PanY: wall[index].ypan_ = float(val); break; case Interp_Wall_PanY: wall[index].ypan_ = float(val); break;
} }

View file

@ -525,7 +525,9 @@ void setWallSectors()
for (auto& wal : walls()) for (auto& wal : walls())
{ {
wal.sector = -1; wal.sector = -1;
wal.lengthflags = 3;
} }
for (int i = 0; i < numsectors - 1; i++) for (int i = 0; i < numsectors - 1; i++)
{ {
auto sect = &sector[i]; auto sect = &sector[i];

View file

@ -417,7 +417,7 @@ void HWDrawInfo::CreateScene(bool portal)
wal->x += eff.geox[i]; wal->x += eff.geox[i];
wal->y += eff.geoy[i]; wal->y += eff.geoy[i];
} }
sect->dirty = 255; sect->dirty = EDirty::AllDirty;
if (eff.geosector[i] == drawsectp) drawsectp = eff.geosectorwarp[i]; if (eff.geosector[i] == drawsectp) drawsectp = eff.geosectorwarp[i];
} }
@ -449,7 +449,7 @@ void HWDrawInfo::CreateScene(bool portal)
wal->x += eff.geox2[i]; wal->x += eff.geox2[i];
wal->y += eff.geoy2[i]; wal->y += eff.geoy2[i];
} }
sect->dirty = 255; sect->dirty = EDirty::AllDirty;
if (eff.geosector[i] == orgdrawsectp) drawsectp = eff.geosectorwarp2[i]; if (eff.geosector[i] == orgdrawsectp) drawsectp = eff.geosectorwarp2[i];
} }

View file

@ -329,7 +329,7 @@ void dbLoadMap(const char* pPath, int* pX, int* pY, int* pZ, short* pAngle, sect
pSector->floorypan_ = load.floorypanning; pSector->floorypan_ = load.floorypanning;
pSector->visibility = load.visibility; pSector->visibility = load.visibility;
pSector->slopewallofs = load.fogpal; pSector->slopewallofs = load.fogpal;
pSector->dirty = 255; pSector->dirty = EDirty::AllDirty;
pSector->exflags = 0; pSector->exflags = 0;
pSector->fogpal = 0; pSector->fogpal = 0;

View file

@ -759,10 +759,8 @@ void PathSound(sectortype* pSector, int nSound)
void DragPoint(walltype* pWall, int x, int y) void DragPoint(walltype* pWall, int x, int y)
{ {
pWall->sectorp()->dirty = 255;
viewInterpolateWall(pWall); viewInterpolateWall(pWall);
pWall->x = x; pWall->move(x, y);
pWall->y = y;
int vsi = numwalls; int vsi = numwalls;
auto prevWall = pWall; auto prevWall = pWall;
@ -771,24 +769,20 @@ void DragPoint(walltype* pWall, int x, int y)
if (prevWall->twoSided()) if (prevWall->twoSided())
{ {
prevWall = prevWall->nextWall()->point2Wall(); prevWall = prevWall->nextWall()->point2Wall();
prevWall->sectorp()->dirty = 255;
viewInterpolateWall(prevWall); viewInterpolateWall(prevWall);
prevWall->x = x; prevWall->move(x, y);
prevWall->y = y;
} }
else else
{ {
prevWall = pWall; prevWall = pWall;
do do
{ {
auto lw = lastwall(prevWall); auto lw = prevWall->lastWall();
if (lw->twoSided()) if (lw && lw->twoSided())
{ {
prevWall = lw->nextWall(); prevWall = lw->nextWall();
prevWall->sectorp()->dirty = 255;
viewInterpolateWall(prevWall); viewInterpolateWall(prevWall);
prevWall->x = x; prevWall->move(x, y);
prevWall->y = y;
} }
else else
break; break;

View file

@ -281,7 +281,6 @@ void ms(DDukeActor* const actor)
{ {
//T1,T2 and T3 are used for all the sector moving stuff!!! //T1,T2 and T3 are used for all the sector moving stuff!!!
int tx, ty;
auto s = actor->s; auto s = actor->s;
s->x += MulScale(s->xvel, bcos(s->ang), 14); s->x += MulScale(s->xvel, bcos(s->ang), 14);
@ -292,12 +291,10 @@ void ms(DDukeActor* const actor)
for(auto& wal : wallsofsector(actor->sector())) for(auto& wal : wallsofsector(actor->sector()))
{ {
rotatepoint( vec2_t t;
0, 0, rotatepoint({ 0, 0 }, { msx[j], msy[j] }, k & 2047, &t);
msx[j], msy[j],
k & 2047, &tx, &ty);
dragpoint(&wal, s->x + tx, s->y + ty); dragpoint(&wal, s->x + t.x, s->y + t.y);
j++; j++;
} }
} }
@ -2751,20 +2748,18 @@ void handle_se00(DDukeActor* actor, int LASERLINE)
ps[p].pos.z += zchange; ps[p].pos.z += zchange;
int m, x; vec2_t res;
rotatepoint(Owner->s->x, Owner->s->y, ps[p].pos.x, ps[p].pos.y, (q * l), &m, &x); rotatepoint(Owner->s->pos.vec2, ps[p].pos.vec2, (q * l), &res);
ps[p].bobposx += m - ps[p].pos.x; ps[p].bobposx += res.x - ps[p].pos.x;
ps[p].bobposy += x - ps[p].pos.y; ps[p].bobposy += res.y - ps[p].pos.y;
ps[p].pos.x = m; ps[p].pos.vec2 = res;
ps[p].pos.y = x;
auto psp = ps[p].GetActor(); auto psp = ps[p].GetActor();
if (psp->s->extra <= 0) if (psp->s->extra <= 0)
{ {
psp->s->x = m; psp->s->pos.vec2 = res;
psp->s->y = x;
} }
} }
} }
@ -2784,7 +2779,7 @@ void handle_se00(DDukeActor* actor, int LASERLINE)
sprp->ang &= 2047; sprp->ang &= 2047;
sprp->z += zchange; 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()) 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.x += m;
ps[p].pos.y += x; ps[p].pos.y += x;
@ -2961,7 +2956,7 @@ void handle_se14(DDukeActor* actor, bool checkstat, int RPG, int JIBS6)
auto sj = a2->s; auto sj = a2->s;
if (sj->statnum != 10 && sj->sector()->lotag != 2 && sj->picnum != SECTOREFFECTOR && sj->picnum != LOCATORS) 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->x += m;
sj->y += x; sj->y += x;

View file

@ -237,6 +237,6 @@ void loadcons();
void recordoldspritepos(); void recordoldspritepos();
void DrawStatusBar(); void DrawStatusBar();
int* animateptr(int i); int* animateptr(int i, bool write = true);
END_DUKE_NS END_DUKE_NS

View file

@ -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; static int scratch;
switch (type) switch (type)
@ -288,8 +288,10 @@ int* animateptr(int type, int index)
case anim_ceilingz: case anim_ceilingz:
return &sector[index].ceilingz; return &sector[index].ceilingz;
case anim_vertexx: case anim_vertexx:
if (write) wall[index].moved();
return &wall[index].x; return &wall[index].x;
case anim_vertexy: case anim_vertexy:
if (write) wall[index].moved();
return &wall[index].y; return &wall[index].y;
default: default:
assert(false); 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--) for (i = animatecnt - 1; i >= 0; i--)
{ {
a = *animateptr(i); a = *animateptr(i, false);
v = animatevel[i] * TICSPERFRAME; v = animatevel[i] * TICSPERFRAME;
auto dasectp = animatesect[i]; 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; break;
} }
auto animptr = animateptr(animtype, animtarget); auto animptr = animateptr(animtype, animtarget, false);
animatesect[j] = animsect; animatesect[j] = animsect;
animatetype[j] = animtype; animatetype[j] = animtype;
animatetarget[j] = animtarget; animatetarget[j] = animtarget;

View file

@ -96,10 +96,10 @@ static int &getvalue(so_interp::interp_data& element, bool write)
switch (type) switch (type)
{ {
case soi_wallx: case soi_wallx:
if (write) wall[index].sectorp()->dirty = 255; if (write) wall[index].moved();
return wall[index].x; return wall[index].x;
case soi_wally: case soi_wally:
if (write) wall[index].sectorp()->dirty = 255; if (write) wall[index].moved();
return wall[index].y; return wall[index].y;
case soi_ceil: case soi_ceil:
return sector[index].ceilingz; return sector[index].ceilingz;

View file

@ -297,10 +297,11 @@ int DoSlidorMoveWalls(DSWActor* actor, int amt)
if (!wal->twoSided()) if (!wal->twoSided())
{ {
// white wall - move 4 points // white wall - move 4 points
wal->x -= amt; wal->move(wal->x - amt, wal->y);
pwal->x -= amt; pwal->move(pwal->x - amt, pwal->y);
wal->point2Wall()->x -= amt; wal->point2Wall()->move(wal->point2Wall()->x - amt, wal->point2Wall()->y);
wal->point2Wall()->point2Wall()->x -= amt; auto pwal2 = wal->point2Wall()->point2Wall();
pwal2->move(pwal2->x - amt, pwal2->y);
} }
else else
{ {
@ -321,10 +322,11 @@ int DoSlidorMoveWalls(DSWActor* actor, int amt)
if (!wal->twoSided()) if (!wal->twoSided())
{ {
// white wall - move 4 points // white wall - move 4 points
wal->x += amt; wal->move(wal->x + amt, wal->y);
pwal->x += amt; pwal->move(pwal->x + amt, pwal->y);
wal->point2Wall()->x += amt; wal->point2Wall()->move(wal->point2Wall()->x + amt, wal->point2Wall()->y);
wal->point2Wall()->point2Wall()->x += amt; auto pwal2 = wal->point2Wall()->point2Wall();
pwal2->move(pwal2->x + amt, pwal2->y);
} }
else else
{ {
@ -344,10 +346,11 @@ int DoSlidorMoveWalls(DSWActor* actor, int amt)
if (!wal->twoSided()) if (!wal->twoSided())
{ {
wal->y -= amt; wal->move(wal->x, wal->y - amt);
pwal->y -= amt; pwal->move(pwal->x, pwal->y - amt);
wal->point2Wall()->y -= amt; wal->point2Wall()->move(wal->point2Wall()->x, wal->point2Wall()->y - amt);
wal->point2Wall()->point2Wall()->y -= amt; auto pwal2 = wal->point2Wall()->point2Wall();
pwal2->move(pwal2->x, pwal2->y - amt);
} }
else else
{ {
@ -366,10 +369,11 @@ int DoSlidorMoveWalls(DSWActor* actor, int amt)
if (!wal->twoSided()) if (!wal->twoSided())
{ {
wal->y += amt; wal->move(wal->x, wal->y + amt);
pwal->y += amt; pwal->move(pwal->x, pwal->y + amt);
wal->point2Wall()->y += amt; wal->point2Wall()->move(wal->point2Wall()->x, wal->point2Wall()->y + amt);
wal->point2Wall()->point2Wall()->y += amt; auto pwal2 = wal->point2Wall()->point2Wall();
pwal2->move(pwal2->x, pwal2->y + amt);
} }
else else
{ {

View file

@ -1513,8 +1513,7 @@ void PreMapCombineFloors(void)
for (auto& wal : wallsofsector(dasect)) for (auto& wal : wallsofsector(dasect))
{ {
wal.x += dx; wal.move(wal.x + dx, wal.y + dy);
wal.y += dy;
if (wal.twoSided()) if (wal.twoSided())
search.Add(wal.nextSector()); search.Add(wal.nextSector());

View file

@ -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)) 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 else
{ {
wal.x += nx; wal.move(wal.x + nx, wal.y + ny);
wal.y += ny;
} }
rot_ang = delta_ang; rot_ang = delta_ang;
@ -1714,8 +1713,7 @@ void MovePoints(SECTOR_OBJECTp sop, short delta_ang, int nx, int ny)
} }
else else
{ {
wal.x = rxy.x; wal.move(rxy.x, rxy.y);
wal.y = rxy.y;
} }
} }
@ -1938,8 +1936,7 @@ void RefreshPoints(SECTOR_OBJECTp sop, int nx, int ny, bool dynamic)
} }
else else
{ {
wal.x = dx; wal.move(dx, dy);
wal.y = dy;
} }
} }
@ -2093,8 +2090,7 @@ void CollapseSectorObject(SECTOR_OBJECTp sop, int nx, int ny)
} }
else else
{ {
wal.x = nx; wal.move(nx, ny);
wal.y = ny;
} }
} }
} }

View file

@ -119,9 +119,7 @@ int DoWallMove(DSWActor* actor)
} }
else else
{ {
wal.x = sp->x + nx; wal.move(sp->x + nx, sp->y + ny);
wal.y = sp->y + ny;
wal.sectorp()->dirty = 255;
} }
if (shade1) if (shade1)