diff --git a/src/maploader/edata.cpp b/src/maploader/edata.cpp index 30b541f73..e35094639 100644 --- a/src/maploader/edata.cpp +++ b/src/maploader/edata.cpp @@ -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; } } diff --git a/src/maploader/glnodes.cpp b/src/maploader/glnodes.cpp index ac28d87c8..defd5e7b7 100644 --- a/src/maploader/glnodes.cpp +++ b/src/maploader/glnodes.cpp @@ -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) { diff --git a/src/maploader/maploader.cpp b/src/maploader/maploader.cpp index ba8414550..42e3ff7f2 100644 --- a/src/maploader/maploader.cpp +++ b/src/maploader/maploader.cpp @@ -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 &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. diff --git a/src/maploader/maploader.h b/src/maploader/maploader.h index 02ab1bbe2..e3b0dc734 100644 --- a/src/maploader/maploader.h +++ b/src/maploader/maploader.h @@ -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(); diff --git a/src/maploader/polyobjects.cpp b/src/maploader/polyobjects.cpp index 78607d742..910cf4099 100644 --- a/src/maploader/polyobjects.cpp +++ b/src/maploader/polyobjects.cpp @@ -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 diff --git a/src/maploader/renderinfo.cpp b/src/maploader/renderinfo.cpp index 5ab76fce3..3a366b7e0 100644 --- a/src/maploader/renderinfo.cpp +++ b/src/maploader/renderinfo.cpp @@ -380,10 +380,8 @@ void MapLoader::PrepareTransparentDoors(sector_t * sector) // //========================================================================== -static void AddToVertex(const sector_t * sec, TArray & list) +static void AddToVertex(int secno, TArray & list) { - int secno = sec->Index(); - for(unsigned i=0;ie->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)); diff --git a/src/maploader/slopes.cpp b/src/maploader/slopes.cpp index 442b05881..86614cc35 100644 --- a/src/maploader/slopes.cpp +++ b/src/maploader/slopes.cpp @@ -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); diff --git a/src/p_tags.cpp b/src/p_tags.cpp index 861866b2c..d6f509f84 100644 --- a/src/p_tags.cpp +++ b/src/p_tags.cpp @@ -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; +} + + //----------------------------------------------------------------------------- // // diff --git a/src/p_tags.h b/src/p_tags.h index 3af2580ec..23b77ee8d 100644 --- a/src/p_tags.h +++ b/src/p_tags.h @@ -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; diff --git a/src/r_defs.h b/src/r_defs.h index 04a14b90b..200b07f86 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -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. diff --git a/src/scripting/vmthunks.cpp b/src/scripting/vmthunks.cpp index cd7473c4f..9ed1f3286 100644 --- a/src/scripting/vmthunks.cpp +++ b/src/scripting/vmthunks.cpp @@ -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)