- store the index of each map item in the struct itself and return that for the Index function.

If we ever want to refactor the global level data these must not reference the 'level' variable.
The main parts of the map loader cannot use this information, because it can only be created after running the node builder, so it got its own set of index functions instead.
This commit is contained in:
Christoph Oelckers 2019-01-06 00:41:46 +01:00
parent c05968146e
commit 8b18ed4759
11 changed files with 150 additions and 76 deletions

View file

@ -583,7 +583,7 @@ void MapLoader::ProcessEDLinedef(line_t *ld, int recordnum)
ld->flags = (ld->flags&~fmask) | eld->flags;
ld->setAlpha(eld->alpha);
memcpy(ld->args, eld->args, sizeof(ld->args));
tagManager.AddLineID(ld->Index(), eld->tag);
tagManager.AddLineID(Index(ld), eld->tag);
}
void MapLoader::ProcessEDSector(sector_t *sec, int recordnum)
@ -642,7 +642,7 @@ void MapLoader::ProcessEDSectors()
{
if (line.special == Static_Init && line.args[1] == Init_EDSector)
{
sectorrecord[line.frontsector->Index()] = line.args[0];
sectorrecord[Index(line.frontsector)] = line.args[0];
line.special = 0;
}
}

View file

@ -126,7 +126,7 @@ int MapLoader::CheckForMissingSegs()
{
// check all the segs and calculate the length they occupy on their sidedef
DVector2 vec1(seg.v2->fX() - seg.v1->fX(), seg.v2->fY() - seg.v1->fY());
added_seglen[seg.sidedef->Index()] += vec1.Length();
added_seglen[Index(seg.sidedef)] += vec1.Length();
}
}
@ -1002,11 +1002,11 @@ void MapLoader::CreateCachedNodes(MapData *map)
WriteLong(ZNodes, Level->segs.Size());
for(auto &seg : Level->segs)
{
WriteLong(ZNodes, seg.v1->Index());
WriteLong(ZNodes, seg.PartnerSeg == nullptr? 0xffffffffu : uint32_t(seg.PartnerSeg->Index()));
WriteLong(ZNodes, Index(seg.v1));
WriteLong(ZNodes, seg.PartnerSeg == nullptr? 0xffffffffu : uint32_t(Index(seg.PartnerSeg)));
if (seg.linedef)
{
WriteLong(ZNodes, uint32_t(seg.linedef->Index()));
WriteLong(ZNodes, uint32_t(Index(seg.linedef)));
WriteByte(ZNodes, seg.sidedef == seg.linedef->sidedef[0]? 0:1);
}
else
@ -1036,11 +1036,11 @@ void MapLoader::CreateCachedNodes(MapData *map)
uint32_t child;
if ((size_t)node.children[j] & 1)
{
child = 0x80000000 | uint32_t(((subsector_t *)((uint8_t *)node.children[j] - 1))->Index());
child = 0x80000000 | uint32_t(Index(((subsector_t *)((uint8_t *)node.children[j] - 1))));
}
else
{
child = ((node_t *)node.children[j])->Index();
child = Index(((node_t *)node.children[j]));
}
WriteLong(ZNodes, child);
}
@ -1067,7 +1067,7 @@ void MapLoader::CreateCachedNodes(MapData *map)
map->GetChecksum(&compressed[8]);
for (unsigned i = 0; i < Level->lines.Size(); i++)
{
uint32_t ndx[2] = { LittleLong(uint32_t(Level->lines[i].v1->Index())), LittleLong(uint32_t(Level->lines[i].v2->Index())) };
uint32_t ndx[2] = { LittleLong(uint32_t(Index(Level->lines[i].v1))), LittleLong(uint32_t(Index(Level->lines[i].v2))) };
memcpy(&compressed[8 + 16 + 8 * i], ndx, 8);
}
memcpy(&compressed[offset - 4], "ZGL3", 4);
@ -1138,7 +1138,7 @@ bool MapLoader::CheckCachedNodes(MapData *map)
for(auto &line : Level->lines)
{
int i = line.Index();
int i = Index(&line);
line.v1 = &Level->vertexes[LittleLong(verts[i*2])];
line.v2 = &Level->vertexes[LittleLong(verts[i*2+1])];
}
@ -1253,7 +1253,7 @@ void MapLoader::SetRenderSector()
auto p = seg.PartnerSeg;
if (p != nullptr)
{
int partner = p->Index();
int partner = Index(p);
if (partner < 0 || partner >= (int)Level->segs.Size() || &Level->segs[partner] != p)
{

View file

@ -790,7 +790,7 @@ void MapLoader::LoadSegs (MapData * map)
for (auto &line : Level->lines)
{
vertchanged[line.v1->Index()] = vertchanged[line.v2->Index()] = 1;
vertchanged[Index(line.v1)] = vertchanged[Index(line.v2)] = 1;
}
try
@ -878,9 +878,9 @@ void MapLoader::LoadSegs (MapData * map)
{
throw badseg(3, i, side);
}
if ((unsigned)(ldef->sidedef[side]->Index()) >= Level->sides.Size())
if ((unsigned)(Index(ldef->sidedef[side])) >= Level->sides.Size())
{
throw badseg(2, i, ldef->sidedef[side]->Index());
throw badseg(2, i, Index(ldef->sidedef[side]));
}
li->sidedef = ldef->sidedef[side];
li->frontsector = ldef->sidedef[side]->sector;
@ -1155,7 +1155,7 @@ void MapLoader::LoadNodes (MapData * map)
else if ((unsigned)child >= numnodes)
{
Printf ("BSP node %d references invalid node %d.\n"
"The BSP will be rebuilt.\n", i, ((node_t *)no->children[j])->Index());
"The BSP will be rebuilt.\n", i, Index(((node_t *)no->children[j])));
ForceNodeBuild = true;
Level->nodes.Clear();
return;
@ -1478,7 +1478,7 @@ void MapLoader::SaveLineSpecial (line_t *ld)
if (ld->sidedef[0] == nullptr)
return;
uint32_t sidenum = ld->sidedef[0]->Index();
uint32_t sidenum = Index(ld->sidedef[0]);
// killough 4/4/98: support special sidedef interpretation below
// [RH] Save Static_Init only if it's interested in the textures
if (ld->special != Static_Init || ld->args[1] == Init_Color)
@ -1506,7 +1506,7 @@ void MapLoader::FinishLoadingLineDef(line_t *ld, int alpha)
ld->backsector = ld->sidedef[1] != nullptr ? ld->sidedef[1]->sector : nullptr;
double dx = (ld->v2->fX() - ld->v1->fX());
double dy = (ld->v2->fY() - ld->v1->fY());
int linenum = ld->Index();
int linenum = Index(ld);
if (ld->frontsector == nullptr)
{
@ -1581,7 +1581,7 @@ void MapLoader::FinishLoadingLineDefs ()
{
for (auto &line : Level->lines)
{
FinishLoadingLineDef(&line, sidetemp[line.sidedef[0]->Index()].a.alpha);
FinishLoadingLineDef(&line, sidetemp[Index(line.sidedef[0])].a.alpha);
}
}
@ -1869,7 +1869,7 @@ void MapLoader::LoopSidedefs (bool firstloop)
// as their left edge.
line_t *line = Level->sides[i].linedef;
int lineside = (line->sidedef[0] != &Level->sides[i]);
int vert = lineside ? line->v2->Index() : line->v1->Index();
int vert = lineside ? Index(line->v2) : Index(line->v1);
sidetemp[i].b.lineside = lineside;
sidetemp[i].b.next = sidetemp[vert].b.first;
@ -1893,26 +1893,26 @@ void MapLoader::LoopSidedefs (bool firstloop)
// instead of as part of another loop
if (line->frontsector == line->backsector)
{
const side_t* const rightside = line->sidedef[!sidetemp[i].b.lineside];
side_t* rightside = line->sidedef[!sidetemp[i].b.lineside];
if (nullptr == rightside)
{
// There is no right side!
if (firstloop) Printf ("Line %d's right edge is unconnected\n", linemap[line->Index()]);
if (firstloop) Printf ("Line %d's right edge is unconnected\n", linemap[Index(line)]);
continue;
}
right = rightside->Index();
right = Index(rightside);
}
else
{
if (sidetemp[i].b.lineside)
{
right = line->v1->Index();
right = Index(line->v1);
}
else
{
right = line->v2->Index();
right = Index(line->v2);
}
right = sidetemp[right].b.first;
@ -1920,7 +1920,7 @@ void MapLoader::LoopSidedefs (bool firstloop)
if (right == NO_SIDE)
{
// There is no right side!
if (firstloop) Printf ("Line %d's right edge is unconnected\n", linemap[line->Index()]);
if (firstloop) Printf ("Line %d's right edge is unconnected\n", linemap[Index(line)]);
continue;
}
@ -2686,7 +2686,7 @@ void MapLoader::GroupLines (bool buildmap)
{
if (sector->Lines.Count == 0)
{
Printf ("Sector %i (tag %i) has no lines\n", i, tagManager.GetFirstSectorTag(sector));
Printf ("Sector %i (tag %i) has no lines\n", i, tagManager.GetFirstSectorTag(Index(sector)));
// 0 the sector's tag so that no specials can use it
tagManager.RemoveSectorTags(i);
}
@ -2702,11 +2702,11 @@ void MapLoader::GroupLines (bool buildmap)
auto li = &Level->lines[i];
if (li->frontsector != nullptr)
{
li->frontsector->Lines[linesDoneInEachSector[li->frontsector->Index()]++] = li;
li->frontsector->Lines[linesDoneInEachSector[Index(li->frontsector)]++] = li;
}
if (li->backsector != nullptr && li->backsector != li->frontsector)
{
li->backsector->Lines[linesDoneInEachSector[li->backsector->Index()]++] = li;
li->backsector->Lines[linesDoneInEachSector[Index(li->backsector)]++] = li;
}
}
@ -2866,6 +2866,40 @@ void MapLoader::GetPolySpots (MapData * map, TArray<FNodeBuilder::FPolyStart> &s
}
}
//==========================================================================
//
//
//
//==========================================================================
void MapLoader::CalcIndices()
{
// sectornums were already initialized because some init code needs them.
for (unsigned int i = 0; i < Level->vertexes.Size(); ++i)
{
Level->vertexes[i].vertexnum = i;
}
for (unsigned int i = 0; i < Level->lines.Size(); ++i)
{
Level->lines[i].linenum = i;
}
for (unsigned int i = 0; i < Level->sides.Size(); ++i)
{
Level->sides[i].sidenum = i;
}
for (unsigned int i = 0; i < Level->segs.Size(); ++i)
{
Level->segs[i].segnum = i;
}
for (unsigned int i = 0; i < Level->subsectors.Size(); ++i)
{
Level->subsectors[i].subsectornum = i;
}
for (unsigned int i = 0; i < Level->nodes.Size(); ++i)
{
Level->nodes[i].nodenum = i;
}
}
//==========================================================================
//
@ -3061,6 +3095,13 @@ void MapLoader::LoadLevel(MapData *map, const char *lumpname, int position)
uint64_t startTime = 0, endTime = 0;
bool BuildGLNodes;
// The node builder needs these indices.
for (unsigned int i = 0; i < Level->sides.Size(); ++i)
{
Level->sides[i].sidenum = i;
}
if (ForceNodeBuild)
{
BuildGLNodes = true;
@ -3127,6 +3168,9 @@ void MapLoader::LoadLevel(MapData *map, const char *lumpname, int position)
FixMinisegReferences();
FixHoles();
// Create the item indices, after the last function which may change the data has run.
CalcIndices();
Level->bodyqueslot = 0;
// phares 8/10/98: Clear body queue so the corpses from previous games are
// not assumed to be from this one.

View file

@ -167,6 +167,7 @@ private:
void FixMinisegReferences();
void FixHoles();
void ReportUnpairedMinisegs();
void CalcIndices();
void SetTexture(side_t *side, int position, const char *name, FMissingTextureTracker &track);
void SetTexture(sector_t *sector, int index, int position, const char *name, FMissingTextureTracker &track, bool truncate);
@ -189,6 +190,42 @@ private:
void CreateBlockMap();
void PO_Init(void);
// During map init the items' own Index functions should not be used.
inline int Index(vertex_t *v) const
{
return int(v - &Level->vertexes[0]);
}
inline int Index(side_t *v) const
{
return int(v - &Level->sides[0]);
}
inline int Index(line_t *v) const
{
return int(v - &Level->lines[0]);
}
inline int Index(seg_t *v) const
{
return int(v - &Level->segs[0]);
}
inline int Index(subsector_t *v) const
{
return int(v - &Level->subsectors[0]);
}
inline int Index(node_t *v) const
{
return int(v - &Level->nodes[0]);
}
inline int Index(sector_t *v) const
{
return int(v - &Level->sectors[0]);
}
public:
void LoadMapinfoACSLump();
void ProcessEDSectors();

View file

@ -120,7 +120,7 @@ void MapLoader::IterFindPolySides (FPolyObj *po, side_t *side)
assert(sidetemp.Size() > 0);
vnum.Clear();
vnum.Push(uint32_t(side->V1()->Index()));
vnum.Push(uint32_t(Index(side->V1())));
vnumat = 0;
while (vnum.Size() != vnumat)
@ -129,7 +129,7 @@ void MapLoader::IterFindPolySides (FPolyObj *po, side_t *side)
while (sidenum != NO_SIDE)
{
po->Sidedefs.Push(&Level->sides[sidenum]);
AddPolyVert(vnum, uint32_t(Level->sides[sidenum].V2()->Index()));
AddPolyVert(vnum, uint32_t(Index(Level->sides[sidenum].V2())));
sidenum = sidetemp[sidenum].b.next;
}
}
@ -208,7 +208,7 @@ void MapLoader::SpawnPolyobj (int index, int tag, int type)
{
if (!Level->sides[i].linedef->args[1])
{
Printf(TEXTCOLOR_RED "SpawnPolyobj: Explicit line missing order number in poly %d, linedef %d.\n", tag, Level->sides[i].linedef->Index());
Printf(TEXTCOLOR_RED "SpawnPolyobj: Explicit line missing order number in poly %d, linedef %d.\n", tag, Index(Level->sides[i].linedef));
return;
}
else

View file

@ -380,10 +380,8 @@ void MapLoader::PrepareTransparentDoors(sector_t * sector)
//
//==========================================================================
static void AddToVertex(const sector_t * sec, TArray<int> & list)
static void AddToVertex(int secno, TArray<int> & list)
{
int secno = sec->Index();
for(unsigned i=0;i<list.Size();i++)
{
if (list[i]==secno) return;
@ -415,8 +413,8 @@ void MapLoader::InitVertexData()
{
extsector_t::xfloor &x = sec->e->XFloor;
AddToVertex(sec, vt_sectorlists[v->Index()]);
if (sec->heightsec) AddToVertex(sec->heightsec, vt_sectorlists[v->Index()]);
AddToVertex(Index(sec), vt_sectorlists[Index(v)]);
if (sec->heightsec) AddToVertex(Index(sec->heightsec), vt_sectorlists[Index(v)]);
}
}
}
@ -492,7 +490,7 @@ void MapLoader::PrepareSegs()
for(auto &seg : Level->segs)
{
if (seg.sidedef == nullptr) continue; // miniseg
int sidenum = seg.sidedef->Index();
int sidenum = Index(seg.sidedef);
realsegs++;
segcount[sidenum]++;
@ -544,7 +542,7 @@ void MapLoader::InitRenderInfo()
memset(checkmap.Data(), -1, sizeof(int)*Level->vertexes.Size());
for(auto &sec : Level->sectors)
{
int i = sec.sectornum;
int i = Index(&sec);
PrepareTransparentDoors(&sec);
// This ignores vertices only used for seg splitting because those aren't needed here
@ -552,8 +550,8 @@ void MapLoader::InitRenderInfo()
{
if (l->sidedef[0]->Flags & WALLF_POLYOBJ) continue; // don't bother with polyobjects
int vtnum1 = l->v1->Index();
int vtnum2 = l->v2->Index();
int vtnum1 = Index(l->v1);
int vtnum2 = Index(l->v2);
if (checkmap[vtnum1] < i)
{
@ -613,7 +611,7 @@ void MapLoader::FixMinisegReferences()
}
if (pick)
{
DPrintf(DMSG_NOTIFY, "Linking miniseg pair from (%2.3f, %2.3f) -> (%2.3f, %2.3f) in sector %d\n", pick->v2->fX(), pick->v2->fY(), pick->v1->fX(), pick->v1->fY(), pick->frontsector->Index());
DPrintf(DMSG_NOTIFY, "Linking miniseg pair from (%2.3f, %2.3f) -> (%2.3f, %2.3f) in sector %d\n", pick->v2->fX(), pick->v2->fY(), pick->v1->fX(), pick->v1->fY(), Index(pick->frontsector));
pick->PartnerSeg = seg1;
seg1->PartnerSeg = pick;
assert(seg1->v1 == pick->v2 && pick->v1 == seg1->v2);
@ -720,7 +718,7 @@ void MapLoader::FixHoles()
subsector_t *newssstartptr = &Level->subsectors[0];
// Now fix all references to these in the level data.
// Note that the Index() method does not work here due to the reallocation.
// Note that the Index method does not work here due to the reallocation.
for (auto &seg : Level->segs)
{
if (seg.PartnerSeg) seg.PartnerSeg = newsegstartptr + (seg.PartnerSeg - oldsegstartptr);
@ -758,7 +756,7 @@ void MapLoader::FixHoles()
// Add the new data. This doesn't care about convexity. It is never directly used to generate a primitive.
for (auto &segloop : segloops)
{
DPrintf(DMSG_NOTIFY, "Adding dummy subsector for sector %d\n", segloop[0]->Subsector->render_sector->Index());
DPrintf(DMSG_NOTIFY, "Adding dummy subsector for sector %d\n", Index(segloop[0]->Subsector->render_sector));
subsector_t &sub = Level->subsectors[newssstart++];
memset(&sub, 0, sizeof(sub));

View file

@ -312,10 +312,10 @@ void MapLoader::SetSlopesFromVertexHeights(FMapThing *firstmt, FMapThing *lastmt
DVector3 vec1, vec2;
int vi1, vi2, vi3;
vi1 = sec.Lines[0]->v1->Index();
vi2 = sec.Lines[0]->v2->Index();
vi1 = Index(sec.Lines[0]->v1);
vi2 = Index(sec.Lines[0]->v2);
vi3 = (sec.Lines[1]->v1 == sec.Lines[0]->v1 || sec.Lines[1]->v1 == sec.Lines[0]->v2)?
sec.Lines[1]->v2->Index() : sec.Lines[1]->v1->Index();
Index(sec.Lines[1]->v2) : Index(sec.Lines[1]->v1);
vt1 = DVector3(Level->vertexes[vi1].fPos(), 0);
vt2 = DVector3(Level->vertexes[vi2].fPos(), 0);

View file

@ -196,6 +196,12 @@ int FTagManager::GetFirstSectorTag(const sector_t *sect) const
return SectorHasTags(i) ? allTags[startForSector[i]].tag : 0;
}
int FTagManager::GetFirstSectorTag(int i) const
{
return SectorHasTags(i) ? allTags[startForSector[i]].tag : 0;
}
//-----------------------------------------------------------------------------
//
//

View file

@ -54,6 +54,7 @@ public:
bool SectorHasTags(const sector_t *sector) const;
int GetFirstSectorTag(const sector_t *sect) const;
int GetFirstSectorTag(int sect) const;
bool SectorHasTag(int sector, int tag) const;
bool SectorHasTag(const sector_t *sector, int tag) const;

View file

@ -97,6 +97,15 @@ struct vertex_t
{
DVector2 p;
int vertexnum;
angle_t viewangle; // precalculated angle for clipping
int angletime; // recalculation time for view angle
bool dirty; // something has changed and needs to be recalculated
int numheights;
int numsectors;
sector_t ** sectors;
float * heightlist;
void set(fixed_t x, fixed_t y)
{
p.X = x / 65536.;
@ -143,15 +152,6 @@ struct vertex_t
void RecalcVertexHeights();
angle_t viewangle; // precalculated angle for clipping
int angletime; // recalculation time for view angle
bool dirty; // something has changed and needs to be recalculated
int numheights;
int numsectors;
sector_t ** sectors;
float * heightlist;
int vertexnum;
vertex_t()
{
p = { 0,0 };
@ -1187,6 +1187,7 @@ struct side_t
FLightNode * lighthead; // all dynamic lights that may affect this wall
seg_t **segs; // all segs belonging to this sidedef in ascending order. Used for precise rendering
int numsegs;
int sidenum;
int GetLightLevel (bool foggy, int baselight, bool is3dlight=false, int *pfakecontrast_usedbygzdoom=NULL) const;
@ -1387,6 +1388,7 @@ struct line_t
AutomapLineStyle automapstyle;
int health; // [ZZ] for destructible geometry (0 = no special behavior)
int healthgroup; // [ZZ] this is the "destructible object" id
int linenum;
DVector2 Delta() const
{
@ -1487,6 +1489,7 @@ struct seg_t
subsector_t* Subsector;
float sidefrac; // relative position of seg's ending vertex on owning sidedef
int segnum;
int Index() const;
};
@ -1525,6 +1528,7 @@ struct subsector_t
seg_t *firstline;
sector_t *render_sector;
FSection *section;
int subsectornum;
uint32_t numlines;
uint16_t flags;
short mapsection;
@ -1558,6 +1562,7 @@ struct node_t
fixed_t nb_bbox[2][4]; // Used by nodebuilder.
};
float len;
int nodenum;
union
{
void *children[2]; // If bit 0 is set, it's a subsector.

View file

@ -1154,9 +1154,7 @@ DEFINE_ACTION_FUNCTION_NATIVE(_Sector, RemoveForceField, RemoveForceField)
static int SectorIndex(sector_t *self)
{
unsigned ndx = self->Index();
if (ndx >= level.sectors.Size()) return -1; // This must not throw because it is the only means to check that the given pointer is valid.
return ndx;
return self->Index();
}
DEFINE_ACTION_FUNCTION_NATIVE(_Sector, Index, SectorIndex)
@ -1295,12 +1293,7 @@ DEFINE_ACTION_FUNCTION_NATIVE(_Sector, RemoveForceField, RemoveForceField)
static int LineIndex(line_t *self)
{
unsigned ndx = self->Index();
if (ndx >= level.lines.Size())
{
return -1;
}
return ndx;
return self->Index();
}
DEFINE_ACTION_FUNCTION_NATIVE(_Line, Index, LineIndex)
@ -1594,12 +1587,7 @@ DEFINE_ACTION_FUNCTION_NATIVE(_Sector, RemoveForceField, RemoveForceField)
static int SideIndex(side_t *self)
{
unsigned ndx = self->Index();
if (ndx >= level.sides.Size())
{
return -1;
}
return ndx;
return self->Index();
}
DEFINE_ACTION_FUNCTION_NATIVE(_Side, Index, SideIndex)
@ -1616,12 +1604,7 @@ DEFINE_ACTION_FUNCTION_NATIVE(_Sector, RemoveForceField, RemoveForceField)
static int VertexIndex(vertex_t *self)
{
unsigned ndx = self->Index();
if (ndx >= level.vertexes.Size())
{
return -1;
}
return ndx;
return self->Index();
}
DEFINE_ACTION_FUNCTION_NATIVE(_Vertex, Index, VertexIndex)