From bfae5ce1bcb237c7392604df53b9378e937f78df Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 15 Nov 2022 14:53:39 +0100 Subject: [PATCH] - use a TArrayView to store the wall references in a sector. This is a lot more scripting friendly than hacking around the indices. --- source/core/maploader.cpp | 35 ++--- source/core/maptypes.h | 180 ++++++++++++-------------- source/core/postprocessor.cpp | 3 +- source/core/rendering/hw_sections.cpp | 2 +- source/core/savegamehelp.cpp | 2 - source/core/vmexports.cpp | 3 +- source/games/blood/src/db.cpp | 3 +- source/games/duke/src/gameexec.cpp | 2 +- source/games/exhumed/src/player.cpp | 4 +- wadsrc/static/zscript/maptypes.zs | 3 +- 10 files changed, 113 insertions(+), 124 deletions(-) diff --git a/source/core/maploader.cpp b/source/core/maploader.cpp index 147d35622..15995dcc6 100644 --- a/source/core/maploader.cpp +++ b/source/core/maploader.cpp @@ -95,8 +95,9 @@ void sectortype::allocX() static void ReadSectorV7(FileReader& fr, sectortype& sect) { - sect.wallptr = fr.ReadInt16(); - sect.wallnum = fr.ReadInt16(); + int wallptr = fr.ReadInt16(); + int wallnum = fr.ReadInt16(); + sect.walls.Set(&wall[wallptr], wallnum); int c = fr.ReadInt32(); int f = fr.ReadInt32(); sect.setzfrommap(c, f); @@ -123,8 +124,9 @@ static void ReadSectorV7(FileReader& fr, sectortype& sect) static void ReadSectorV6(FileReader& fr, sectortype& sect) { - sect.wallptr = fr.ReadUInt16(); - sect.wallnum = fr.ReadUInt16(); + int wallptr = fr.ReadInt16(); + int wallnum = fr.ReadInt16(); + sect.walls.Set(&wall[wallptr], wallnum); sect.ceilingpicnum = fr.ReadUInt16(); sect.floorpicnum = fr.ReadUInt16(); sect.ceilingheinum = clamp(fr.ReadInt16() << 5, -32768, 32767); @@ -151,8 +153,9 @@ static void ReadSectorV6(FileReader& fr, sectortype& sect) static void ReadSectorV5(FileReader& fr, sectortype& sect) { - sect.wallptr = fr.ReadInt16(); - sect.wallnum = fr.ReadInt16(); + int wallptr = fr.ReadInt16(); + int wallnum = fr.ReadInt16(); + sect.walls.Set(&wall[wallptr], wallnum); sect.ceilingpicnum = fr.ReadUInt16(); sect.floorpicnum = fr.ReadUInt16(); sect.ceilingheinum = clamp(fr.ReadInt16() << 5, -32768, 32767); @@ -426,8 +429,7 @@ void fixSectors() // Note: we do not have the 'sector' index initialized here, it would not be helpful anyway for this fix. while (wp != wall.Data() && wp[-1].twoSided() && wp[-1].nextWall()->nextWall() == &wp[-1] && wp[-1].nextWall()->nextSector() == §) { - sect.wallptr--; - sect.wallnum++; + sect.walls.Set(sect.walls.Data() - 1, sect.walls.Size() + 1); wp--; } } @@ -755,8 +757,8 @@ void setWallSectors() auto sect = §or[i]; auto nextsect = §or[i + 1]; - int sectstart = sect->wall_index(); - int nextsectstart = nextsect->wall_index(); + int sectstart = wallindex(sect->firstWall()); + int nextsectstart = wallindex(sect->firstWall()); if (sectstart < nextsectstart && sectstart + sect->wall_count() > nextsectstart) { @@ -765,8 +767,8 @@ void setWallSectors() int checkend = sectstart + sect->wall_count(); // for now assign the walls to the first sector. Final decisions are made below. - nextsect->wallnum -= checkend - checkstart; - nextsect->wallptr = checkend; + nextsectstart = checkend; + nextsect->walls.Set(&wall[nextsectstart], nextsect->walls.Size() - (checkend - checkstart)); auto belongs = [](int wal, int first, int last, int firstwal) { @@ -782,19 +784,20 @@ void setWallSectors() while (checkstart < checkend && belongs(checkstart, sectstart, checkstart, checkstart)) checkstart++; - sect->wallnum = checkstart - sectstart; + sect->walls.Set(sect->firstWall(), checkstart - sectstart); while (checkstart < checkend && belongs(checkend - 1, checkend, nextsectstart + nextsect->wall_count(), checkstart)) checkend--; - nextsect->wallnum += nextsectstart - checkend; - nextsect->wallptr = nextsectstart = checkend; + int cnt = nextsect->walls.Size() - (nextsectstart - checkend); + nextsectstart = checkend; + nextsect->walls.Set(&wall[nextsectstart], cnt); if (nextsectstart > sectstart + sect->wall_count()) { // If there's a gap, assign to the first sector. In this case we may only guess. Printf("Wall range %d - %d referenced by sectors %d and %d\n", sectstart + sect->wall_count(), nextsectstart - 1, i, i + 1); - sect->wallnum = nextsectstart - sectstart; + sect->walls.Set(sect->firstWall(), nextsectstart - sectstart); } } } diff --git a/source/core/maptypes.h b/source/core/maptypes.h index 186c2d551..c7c0b636c 100644 --- a/source/core/maptypes.h +++ b/source/core/maptypes.h @@ -210,7 +210,86 @@ BEGIN_BLD_NS END_BLD_NS class DCoreActor; -struct walltype; +struct sectortype; + + +//============================================================================= +// +// internal wall struct - no longer identical with on-disk format +// +//============================================================================= + +struct walltype +{ + DVector2 pos; + + vec2_t wall_int_pos() const { return vec2_t(int(pos.X * worldtoint), int(pos.Y * worldtoint)); }; + vec2_t int_delta() const { return point2Wall()->wall_int_pos() - wall_int_pos(); } + + void setPosFromMap(int x, int y) { pos = { x * maptoworld, y * maptoworld }; } + + int32_t point2; + int32_t nextwall; + int32_t sector; // Build never had this... + int32_t nextsector; + + // Again, panning fields extended for interpolation. + float xpan_; + float ypan_; + + EWallFlags cstat; + int16_t picnum; + int16_t overpicnum; + union { int16_t lotag, type; }; // type is for Blood + int16_t hitag; + int16_t extra; + + int8_t shade; + uint8_t pal; + uint8_t xrepeat; + uint8_t yrepeat; + + // extensions not from the binary map format. + angle_t clipangle; + double length; // cached value to avoid calling sqrt repeatedly. + + uint16_t portalnum; + uint8_t portalflags; + uint8_t lengthflags; + + // Blood is the only game which extends the wall struct. + Blood::XWALL* _xw; + DVector2 baseWall; + + int xpan() const { return int(xpan_); } + int ypan() const { return int(ypan_); } + void setxpan(float add) { xpan_ = fmodf(add + 512, 256); } // +512 is for handling negative offsets + void setypan(float add) { ypan_ = fmodf(add + 512, 256); } // +512 is for handling negative offsets + void addxpan(float add) { xpan_ = fmodf(xpan_ + add + 512, 256); } // +512 is for handling negative offsets + void addypan(float add) { ypan_ = fmodf(ypan_ + add + 512, 256); } // +512 is for handling negative offsets + sectortype* nextSector() const; + sectortype* sectorp() const; + walltype* nextWall() const; + walltype* lastWall(bool fast = true) const; + walltype* point2Wall() const; + DVector2 delta() const { return point2Wall()->pos - pos; } + DVector2 center() const { return(point2Wall()->pos + pos) / 2; } + DAngle normalAngle() const { return delta().Angle() + DAngle90; } + bool twoSided() const { return nextsector >= 0; } + double Length(); + void calcLength(); // this is deliberately not inlined and stored in a file where it can't be found at compile time. + void move(const DVector2& vec) + { + pos = vec; + moved(); + } + + void moved(); + + Blood::XWALL& xw() const { return *_xw; } + bool hasX() const { return _xw != nullptr; } + void allocX(); +}; // enable for running a compile-check to ensure that renderer-critical variables are not being written to directly. //#define SECTOR_HACKJOB @@ -227,7 +306,8 @@ struct sectortype // Fields were reordered by size, some also enlarged. DCoreActor* firstEntry, * lastEntry; - int32_t wallptr; + TArrayView walls; + #ifdef SECTOR_HACKJOB // Debug hack job for finding all places where ceilingz and floorz get written to. // If the engine does not compile with this block on, we got a problem. @@ -259,7 +339,6 @@ struct sectortype float floorxpan_; float floorypan_; - int16_t wallnum; ESectorFlags ceilingstat; ESectorFlags floorstat; int16_t ceilingpicnum; @@ -348,10 +427,9 @@ struct sectortype void setfloorslope(int heinum) { floorheinum = heinum; if (heinum) floorstat |= CSTAT_SECTOR_SLOPE; else floorstat &= ~CSTAT_SECTOR_SLOPE; } int getfloorslope() const { return floorstat & CSTAT_SECTOR_SLOPE ? floorheinum : 0; } int getceilingslope() const { return ceilingstat & CSTAT_SECTOR_SLOPE ? ceilingheinum : 0; } - walltype* firstWall() const; - walltype* lastWall() const; - int wall_index() const { return wallptr; } - int wall_count() const { return wallnum; } + walltype* firstWall() const { return walls.Data(); } + walltype* lastWall() const { return &walls.Last(); } + int wall_count() const { return walls.Size(); } Blood::XSECTOR& xs() const { return *_xs; } @@ -362,84 +440,6 @@ struct sectortype bool hasU() const { return u_defined; } }; -//============================================================================= -// -// internal wall struct - no longer identical with on-disk format -// -//============================================================================= - -struct walltype -{ - DVector2 pos; - - vec2_t wall_int_pos() const { return vec2_t(int(pos.X * worldtoint), int(pos.Y * worldtoint)); }; - vec2_t int_delta() const { return point2Wall()->wall_int_pos() - wall_int_pos(); } - - void setPosFromMap(int x, int y) { pos = { x * maptoworld, y * maptoworld }; } - - int32_t point2; - int32_t nextwall; - int32_t sector; // Build never had this... - int32_t nextsector; - - // Again, panning fields extended for interpolation. - float xpan_; - float ypan_; - - EWallFlags cstat; - int16_t picnum; - int16_t overpicnum; - union { int16_t lotag, type; }; // type is for Blood - int16_t hitag; - int16_t extra; - - int8_t shade; - uint8_t pal; - uint8_t xrepeat; - uint8_t yrepeat; - - // extensions not from the binary map format. - angle_t clipangle; - double length; // cached value to avoid calling sqrt repeatedly. - - uint16_t portalnum; - uint8_t portalflags; - uint8_t lengthflags; - - // Blood is the only game which extends the wall struct. - Blood::XWALL* _xw; - DVector2 baseWall; - - int xpan() const { return int(xpan_); } - int ypan() const { return int(ypan_); } - void setxpan(float add) { xpan_ = fmodf(add + 512, 256); } // +512 is for handling negative offsets - void setypan(float add) { ypan_ = fmodf(add + 512, 256); } // +512 is for handling negative offsets - void addxpan(float add) { xpan_ = fmodf(xpan_ + add + 512, 256); } // +512 is for handling negative offsets - void addypan(float add) { ypan_ = fmodf(ypan_ + add + 512, 256); } // +512 is for handling negative offsets - sectortype* nextSector() const; - sectortype* sectorp() const; - walltype* nextWall() const; - walltype* lastWall(bool fast = true) const; - walltype* point2Wall() const; - DVector2 delta() const { return point2Wall()->pos - pos; } - DVector2 center() const { return(point2Wall()->pos + pos) / 2; } - DAngle normalAngle() const { return delta().Angle() + DAngle90; } - bool twoSided() const { return nextsector >= 0; } - double Length(); - void calcLength(); // this is deliberately not inlined and stored in a file where it can't be found at compile time. - void move(const DVector2& vec) - { - pos = vec; - moved(); - } - - void moved(); - - Blood::XWALL& xw() const { return *_xw; } - bool hasX() const { return _xw != nullptr; } - void allocX(); -}; - //============================================================================= // // internal sprite struct - no longer identical with on-disk format @@ -597,16 +597,6 @@ inline walltype* walltype::point2Wall() const return &::wall[point2]; // cannot be -1 in a proper map. } -inline walltype* sectortype::firstWall() const -{ - return &wall[wallptr]; // cannot be -1 in a proper map -} - -inline walltype* sectortype::lastWall() const -{ - return &wall[wallptr + wallnum - 1]; // cannot be -1 in a proper map -} - inline void walltype::moved() { lengthflags = 3; diff --git a/source/core/postprocessor.cpp b/source/core/postprocessor.cpp index 73e6fa255..396367b65 100644 --- a/source/core/postprocessor.cpp +++ b/source/core/postprocessor.cpp @@ -40,6 +40,7 @@ #include "maptypes.h" #include "hw_sections.h" #include "mapinfo.h" +#include "gamefuncs.h" //========================================================================== // @@ -124,7 +125,7 @@ DEFINE_ACTION_FUNCTION(DLevelPostProcessor, SplitSector) if (sectornum < sector.Size()) { - int sectstart = sector[sectornum].wall_index(); + int sectstart = wallindex(sector[sectornum].firstWall()); if (firstwall >= sectstart && firstwall < sectstart + sector[sectornum].wall_count() && secondwall >= sectstart && secondwall < sectstart + sector[sectornum].wall_count()) diff --git a/source/core/rendering/hw_sections.cpp b/source/core/rendering/hw_sections.cpp index 41e017fed..fadf8167d 100644 --- a/source/core/rendering/hw_sections.cpp +++ b/source/core/rendering/hw_sections.cpp @@ -223,7 +223,7 @@ static void CollectLoops(TArray& sectors) int count = 0; for (unsigned i = 0; i < sector.Size(); i++) { - int first = sector[i].wall_index(); + int first = wallindex(sector[i].firstWall()); int last = first + sector[i].wall_count(); sectors.Reserve(1); sectors.Last().bugged = 0; diff --git a/source/core/savegamehelp.cpp b/source/core/savegamehelp.cpp index 5f16b3d4f..7bbc48761 100644 --- a/source/core/savegamehelp.cpp +++ b/source/core/savegamehelp.cpp @@ -458,8 +458,6 @@ FSerializer &Serialize(FSerializer &arc, const char *key, sectortype &c, sectort { arc("firstentry", c.firstEntry) ("lastentry", c.lastEntry) - ("wallptr", c.wallptr, def->wallptr) - ("wallnum", c.wallnum, def->wallnum) #ifndef SECTOR_HACKJOB // can't save these in test mode... ("ceilingz", c.ceilingz, def->ceilingz) ("floorz", c.floorz, def->floorz) diff --git a/source/core/vmexports.cpp b/source/core/vmexports.cpp index 2cc9b5133..1ce69ff7f 100644 --- a/source/core/vmexports.cpp +++ b/source/core/vmexports.cpp @@ -47,8 +47,7 @@ DEFINE_FIELD_NAMED_X(sectortype, sectortype, ceilingxpan_, ceilingxpan) DEFINE_FIELD_NAMED_X(sectortype, sectortype, ceilingypan_, ceilingypan) DEFINE_FIELD_NAMED_X(sectortype, sectortype, floorxpan_, floorxpan) DEFINE_FIELD_NAMED_X(sectortype, sectortype, floorypan_, floorypan) -DEFINE_FIELD_X(sectortype, sectortype, wallptr) -DEFINE_FIELD_X(sectortype, sectortype, wallnum) +DEFINE_FIELD_UNSIZED(sectortype, sectortype, walls) DEFINE_FIELD_X(sectortype, sectortype, ceilingstat) DEFINE_FIELD_X(sectortype, sectortype, floorstat) DEFINE_FIELD_X(sectortype, sectortype, lotag) diff --git a/source/games/blood/src/db.cpp b/source/games/blood/src/db.cpp index 68e921aa8..cebc28f38 100644 --- a/source/games/blood/src/db.cpp +++ b/source/games/blood/src/db.cpp @@ -253,8 +253,7 @@ void dbLoadMap(const char* pPath, DVector3& pos, short* pAngle, sectortype** cur { dbCrypt((char*)&load, sizeof(sectortypedisk), gMapRev * sizeof(sectortypedisk)); } - pSector->wallptr = LittleShort(load.wallptr); - pSector->wallnum = LittleShort(load.wallnum); + pSector->walls.Set(&wall[LittleShort(load.wallptr)], LittleShort(load.wallnum)); pSector->setzfrommap(LittleLong(load.ceilingz), LittleLong(load.floorz)); pSector->ceilingstat = ESectorFlags::FromInt(LittleShort(load.ceilingstat)); pSector->floorstat = ESectorFlags::FromInt(LittleShort(load.floorstat)); diff --git a/source/games/duke/src/gameexec.cpp b/source/games/duke/src/gameexec.cpp index 4a74de48d..644aa0170 100644 --- a/source/games/duke/src/gameexec.cpp +++ b/source/games/duke/src/gameexec.cpp @@ -1052,7 +1052,7 @@ void DoSector(bool bSet, int lVar1, int lLabelID, int lVar2, DDukeActor* sActor, switch (lLabelID) { case SECTOR_WALLPTR: - if (!bSet) SetGameVarID(lVar2, sectp->wall_index(), sActor, sPlayer); + if (!bSet) SetGameVarID(lVar2, wallindex(sectp->firstWall()), sActor, sPlayer); break; case SECTOR_WALLNUM: if (!bSet) SetGameVarID(lVar2, sectp->wall_count(), sActor, sPlayer); diff --git a/source/games/exhumed/src/player.cpp b/source/games/exhumed/src/player.cpp index 56521d646..3a57e17b1 100644 --- a/source/games/exhumed/src/player.cpp +++ b/source/games/exhumed/src/player.cpp @@ -128,7 +128,7 @@ void feebtag(const DVector3& pos, sectortype* pSector, DExhumedActor **nSprite, { *nSprite = nullptr; - int startwall = pSector->wall_index(); + auto startwall = pSector->firstWall(); int nWalls = pSector->wall_count(); @@ -166,7 +166,7 @@ void feebtag(const DVector3& pos, sectortype* pSector, DExhumedActor **nSprite, if (nWalls < -1) return; - pSector = wall[startwall].nextSector(); + pSector = startwall->nextSector(); startwall++; } } diff --git a/wadsrc/static/zscript/maptypes.zs b/wadsrc/static/zscript/maptypes.zs index 76e8f4999..fe3c27722 100644 --- a/wadsrc/static/zscript/maptypes.zs +++ b/wadsrc/static/zscript/maptypes.zs @@ -123,8 +123,7 @@ struct sectortype native native readonly float floorypan; native readonly double ceilingz, floorz; - native readonly int wallptr; - native readonly int16 wallnum; + native Array<@walltype> walls; native int16 ceilingstat; native int16 floorstat; //int16 ceilingpicnum;