diff --git a/src/am_map.cpp b/src/am_map.cpp index 90d84360bf..a6ccb92cfa 100644 --- a/src/am_map.cpp +++ b/src/am_map.cpp @@ -1029,17 +1029,17 @@ static void AM_findMinMaxBoundaries () min_x = min_y = FLT_MAX; max_x = max_y = FIXED_MIN; - for (int i = 0; i < numvertexes; i++) + for (auto &vert : level.vertexes) { - if (vertexes[i].fX() < min_x) - min_x = vertexes[i].fX(); - else if (vertexes[i].fX() > max_x) - max_x = vertexes[i].fX(); + if (vert.fX() < min_x) + min_x = vert.fX(); + else if (vert.fX() > max_x) + max_x = vert.fX(); - if (vertexes[i].fY() < min_y) - min_y = vertexes[i].fY(); - else if (vertexes[i].fY() > max_y) - max_y = vertexes[i].fY(); + if (vert.fY() < min_y) + min_y = vert.fY(); + else if (vert.fY() > max_y) + max_y = vert.fY(); } max_w = max_x - min_x; diff --git a/src/g_levellocals.h b/src/g_levellocals.h index c49be313bc..08b18145d9 100644 --- a/src/g_levellocals.h +++ b/src/g_levellocals.h @@ -27,6 +27,7 @@ struct FLevelLocals FString NextSecretMap; // map to go to when used secret exit EMapType maptype; + TStaticArray vertexes; TStaticArray sectors; TStaticArray lines; TStaticArray sides; @@ -79,6 +80,11 @@ struct FLevelLocals extern FLevelLocals level; +inline int vertex_t::Index() const +{ + return int(this - &level.vertexes[0]); +} + inline int side_t::Index() const { return int(this - &level.sides[0]); diff --git a/src/gl/data/gl_setup.cpp b/src/gl/data/gl_setup.cpp index e411812287..5b0affea58 100644 --- a/src/gl/data/gl_setup.cpp +++ b/src/gl/data/gl_setup.cpp @@ -403,7 +403,7 @@ static void InitVertexData() int i,j,k; - vt_sectorlists = new TArray[numvertexes]; + vt_sectorlists = new TArray[level.vertexes.Size()]; for(auto &line : level.lines) @@ -420,32 +420,33 @@ static void InitVertexData() { extsector_t::xfloor &x = sec->e->XFloor; - AddToVertex(sec, vt_sectorlists[v-vertexes]); - if (sec->heightsec) AddToVertex(sec->heightsec, vt_sectorlists[v-vertexes]); + AddToVertex(sec, vt_sectorlists[v->Index()]); + if (sec->heightsec) AddToVertex(sec->heightsec, vt_sectorlists[v->Index()]); } } } } - for(i=0;i1) { - vertexes[i].numsectors= cnt; - vertexes[i].sectors=new sector_t*[cnt]; - vertexes[i].heightlist = new float[cnt*2]; + vert.numsectors= cnt; + vert.sectors=new sector_t*[cnt]; + vert.heightlist = new float[cnt*2]; for(int j=0;jsidedef[0]->Flags & WALLF_POLYOBJ) continue; // don't bother with polyobjects - int vtnum1 = int(l->v1 - vertexes); - int vtnum2 = int(l->v2 - vertexes); + int vtnum1 = l->v1->Index(); + int vtnum2 = l->v2->Index(); if (checkmap[vtnum1] < i) { checkmap[vtnum1] = i; - sec.e->vertices.Push(&vertexes[vtnum1]); - vertexes[vtnum1].dirty = true; + sec.e->vertices.Push(&level.vertexes[vtnum1]); + level.vertexes[vtnum1].dirty = true; } if (checkmap[vtnum2] < i) { checkmap[vtnum2] = i; - sec.e->vertices.Push(&vertexes[vtnum2]); - vertexes[vtnum2].dirty = true; + sec.e->vertices.Push(&level.vertexes[vtnum2]); + level.vertexes[vtnum2].dirty = true; } } } @@ -652,20 +653,17 @@ void gl_CleanLevelData() mo=next; } - if (vertexes != NULL) + for(auto &v : level.vertexes) if (v.numsectors > 0) { - for(int i = 0; i < numvertexes; i++) if (vertexes[i].numsectors > 0) + if (v.sectors != nullptr) { - if (vertexes[i].sectors != NULL) - { - delete [] vertexes[i].sectors; - vertexes[i].sectors = NULL; - } - if (vertexes[i].heightlist != NULL) - { - delete [] vertexes[i].heightlist; - vertexes[i].heightlist = NULL; - } + delete [] v.sectors; + v.sectors = nullptr; + } + if (v.heightlist != nullptr) + { + delete [] v.heightlist; + v.heightlist = nullptr; } } diff --git a/src/nodebuild.h b/src/nodebuild.h index 7e2a61aaac..54d07ad5fb 100644 --- a/src/nodebuild.h +++ b/src/nodebuild.h @@ -209,10 +209,10 @@ public: bool makeGLNodes); ~FNodeBuilder (); - void Extract (node_t *&nodes, int &nodeCount, + void Extract(node_t *&nodes, int &nodeCount, seg_t *&segs, glsegextra_t *&glsegextras, int &segCount, subsector_t *&ssecs, int &subCount, - vertex_t *&verts, int &vertCount); + TStaticArray &vertexes); const int *GetOldVertexTable(); // These are used for building sub-BSP trees for polyobjects. diff --git a/src/nodebuild_extract.cpp b/src/nodebuild_extract.cpp index c3f63c8202..bec0fbc5d9 100644 --- a/src/nodebuild_extract.cpp +++ b/src/nodebuild_extract.cpp @@ -55,12 +55,12 @@ void FNodeBuilder::Extract (node_t *&outNodes, int &nodeCount, seg_t *&outSegs, glsegextra_t *&outSegExtras, int &segCount, subsector_t *&outSubs, int &subCount, - vertex_t *&outVerts, int &vertCount) + TStaticArray &outVerts) { int i; - vertCount = Vertices.Size (); - outVerts = new vertex_t[vertCount]; + int vertCount = Vertices.Size (); + outVerts.Alloc(vertCount); for (i = 0; i < vertCount; ++i) { @@ -109,7 +109,7 @@ void FNodeBuilder::Extract (node_t *&outNodes, int &nodeCount, for (i = 0; i < subCount; ++i) { - DWORD numsegs = CloseSubsector (segs, i, outVerts); + DWORD numsegs = CloseSubsector (segs, i, &outVerts[0]); outSubs[i].numlines = numsegs; outSubs[i].firstline = (seg_t *)(size_t)(segs.Size() - numsegs); } @@ -145,8 +145,8 @@ void FNodeBuilder::Extract (node_t *&outNodes, int &nodeCount, D(Printf(PRINT_LOG, "Seg %d: v1(%d) -> v2(%d)\n", i, org->v1, org->v2)); - out->v1 = outVerts + org->v1; - out->v2 = outVerts + org->v2; + out->v1 = &outVerts[org->v1]; + out->v2 = &outVerts[org->v2]; out->backsector = org->backsector; out->frontsector = org->frontsector; out->linedef = Level.Lines + org->linedef; @@ -162,8 +162,8 @@ void FNodeBuilder::Extract (node_t *&outNodes, int &nodeCount, for (i = 0; i < Level.NumLines; ++i) { - Level.Lines[i].v1 = outVerts + (size_t)Level.Lines[i].v1; - Level.Lines[i].v2 = outVerts + (size_t)Level.Lines[i].v2; + Level.Lines[i].v1 = &outVerts[(size_t)Level.Lines[i].v1]; + Level.Lines[i].v2 = &outVerts[(size_t)Level.Lines[i].v2]; } } diff --git a/src/p_glnodes.cpp b/src/p_glnodes.cpp index c68b0d5b02..4310c670eb 100644 --- a/src/p_glnodes.cpp +++ b/src/p_glnodes.cpp @@ -224,7 +224,7 @@ static bool LoadGLVertexes(FileReader * lump) BYTE *gldata; int i; - firstglvertex = numvertexes; + firstglvertex = level.vertexes.Size(); int gllen=lump->GetLength(); @@ -249,23 +249,23 @@ static bool LoadGLVertexes(FileReader * lump) } else format5=false; - mapglvertex_t* mgl; + mapglvertex_t* mgl = (mapglvertex_t *)(gldata + GL_VERT_OFFSET); + unsigned numvertexes = firstglvertex + (gllen - GL_VERT_OFFSET)/sizeof(mapglvertex_t); - vertex_t * oldvertexes = vertexes; - numvertexes += (gllen - GL_VERT_OFFSET)/sizeof(mapglvertex_t); - vertexes = new vertex_t[numvertexes]; - mgl = (mapglvertex_t *) (gldata + GL_VERT_OFFSET); + TStaticArray oldvertexes = std::move(level.vertexes); + level.vertexes.Alloc(numvertexes); - memcpy(vertexes, oldvertexes, firstglvertex * sizeof(vertex_t)); + memcpy(&level.vertexes[0], &oldvertexes[0], firstglvertex * sizeof(vertex_t)); for(auto &line : level.lines) { - line.v1 = vertexes + (line.v1 - oldvertexes); - line.v2 = vertexes + (line.v2 - oldvertexes); + // Remap vertex pointers in linedefs + line.v1 = &level.vertexes[line.v1 - &oldvertexes[0]]; + line.v2 = &level.vertexes[line.v2 - &oldvertexes[0]]; } - for (i = firstglvertex; i < numvertexes; i++) + for (i = firstglvertex; i < (int)numvertexes; i++) { - vertexes[i].set(LittleLong(mgl->x)/65536., LittleLong(mgl->y)/65536.); + level.vertexes[i].set(LittleLong(mgl->x)/65536., LittleLong(mgl->y)/65536.); mgl++; } delete[] gldata; @@ -324,8 +324,8 @@ static bool LoadGLSegs(FileReader * lump) glseg_t * ml = (glseg_t*)data; for(i = 0; i < numsegs; i++) { // check for gl-vertices - segs[i].v1 = &vertexes[checkGLVertex(LittleShort(ml->v1))]; - segs[i].v2 = &vertexes[checkGLVertex(LittleShort(ml->v2))]; + segs[i].v1 = &level.vertexes[checkGLVertex(LittleShort(ml->v1))]; + segs[i].v2 = &level.vertexes[checkGLVertex(LittleShort(ml->v2))]; glsegextras[i].PartnerSeg = ml->partner == 0xFFFF ? DWORD_MAX : LittleShort(ml->partner); if(ml->linedef != 0xffff) @@ -377,8 +377,8 @@ static bool LoadGLSegs(FileReader * lump) glseg3_t * ml = (glseg3_t*)(data+ (format5? 0:4)); for(i = 0; i < numsegs; i++) { // check for gl-vertices - segs[i].v1 = &vertexes[checkGLVertex3(LittleLong(ml->v1))]; - segs[i].v2 = &vertexes[checkGLVertex3(LittleLong(ml->v2))]; + segs[i].v1 = &level.vertexes[checkGLVertex3(LittleLong(ml->v1))]; + segs[i].v2 = &level.vertexes[checkGLVertex3(LittleLong(ml->v2))]; glsegextras[i].PartnerSeg = LittleLong(ml->partner); @@ -1002,18 +1002,18 @@ bool P_CheckNodes(MapData * map, bool rebuilt, int buildtime) P_GetPolySpots (map, polyspots, anchors); FNodeBuilder::FLevel leveldata = { - vertexes, numvertexes, + &level.vertexes[0], (int)level.vertexes.Size(), &level.sides[0], (int)level.sides.Size(), &level.lines[0], (int)level.lines.Size(), 0, 0, 0, 0 }; leveldata.FindMapBounds (); FNodeBuilder builder (leveldata, polyspots, anchors, true); - delete[] vertexes; + builder.Extract (nodes, numnodes, segs, glsegextras, numsegs, subsectors, numsubsectors, - vertexes, numvertexes); + level.vertexes); endTime = I_FPSTime (); DPrintf (DMSG_NOTIFY, "BSP generation took %.3f sec (%d segs)\n", (endTime - startTime) * 0.001, numsegs); buildtime = endTime - startTime; @@ -1095,11 +1095,11 @@ static void CreateCachedNodes(MapData *map) MemFile ZNodes; WriteLong(ZNodes, 0); - WriteLong(ZNodes, numvertexes); - for(int i=0;iIndex()); if (glsegextras != NULL) WriteLong(ZNodes, DWORD(glsegextras[i].PartnerSeg)); else WriteLong(ZNodes, 0); if (segs[i].linedef) @@ -1178,7 +1178,7 @@ static void CreateCachedNodes(MapData *map) map->GetChecksum(compressed+8); for (unsigned i = 0; i < level.lines.Size(); i++) { - DWORD ndx[2] = { LittleLong(DWORD(level.lines[i].v1 - vertexes)), LittleLong(DWORD(level.lines[i].v2 - vertexes)) }; + DWORD ndx[2] = { LittleLong(DWORD(level.lines[i].v1->Index())), LittleLong(DWORD(level.lines[i].v2->Index())) }; memcpy(compressed + 8 + 16 + 8 * i, ndx, 8); } memcpy(compressed + offset - 4, "ZGL3", 4); @@ -1266,8 +1266,8 @@ static bool CheckCachedNodes(MapData *map) for(auto &line : level.lines) { int i = line.Index(); - line.v1 = &vertexes[LittleLong(verts[i*2])]; - line.v2 = &vertexes[LittleLong(verts[i*2+1])]; + line.v1 = &level.vertexes[LittleLong(verts[i*2])]; + line.v2 = &level.vertexes[LittleLong(verts[i*2+1])]; } delete [] verts; diff --git a/src/p_saveg.cpp b/src/p_saveg.cpp index 33f65bfa74..227fc91fdc 100644 --- a/src/p_saveg.cpp +++ b/src/p_saveg.cpp @@ -358,6 +358,7 @@ FSerializer &Serialize(FSerializer &arc, const char *key, subsector_t *&ss, subs str = &encoded[0]; if (arc.BeginArray(key)) { + auto numvertexes = level.vertexes.Size(); arc(nullptr, numvertexes) (nullptr, numsubsectors) .StringPtr(nullptr, str) @@ -376,7 +377,7 @@ FSerializer &Serialize(FSerializer &arc, const char *key, subsector_t *&ss, subs .StringPtr(nullptr, str) .EndArray(); - if (num_verts == numvertexes && num_subs == numsubsectors && hasglnodes) + if (num_verts == level.vertexes.Size() && num_subs == numsubsectors && hasglnodes) { success = true; int sub = 0; diff --git a/src/p_sectors.cpp b/src/p_sectors.cpp index 20489057c4..c95f48d150 100644 --- a/src/p_sectors.cpp +++ b/src/p_sectors.cpp @@ -711,7 +711,7 @@ double sector_t::FindHighestFloorPoint (vertex_t **v) const { if (v != NULL) { - if (Lines.Size() == 0) *v = &vertexes[0]; + if (Lines.Size() == 0) *v = &level.vertexes[0]; else *v = Lines[0]->v1; } return -floorplane.fD(); @@ -760,7 +760,7 @@ double sector_t::FindLowestCeilingPoint (vertex_t **v) const { if (v != NULL) { - if (Lines.Size() == 0) *v = &vertexes[0]; + if (Lines.Size() == 0) *v = &level.vertexes[0]; else *v = Lines[0]->v1; } return ceilingplane.fD(); @@ -1966,6 +1966,12 @@ DEFINE_ACTION_FUNCTION(_Sector, NextLowestFloorAt) ACTION_RETURN_INT(self->Index()); } + DEFINE_ACTION_FUNCTION(_Vertex, Index) + { + PARAM_SELF_STRUCT_PROLOGUE(vertex_t); + ACTION_RETURN_INT(self->Index()); + } + //=========================================================================== // // diff --git a/src/p_setup.cpp b/src/p_setup.cpp index 58b9344389..cf86a452d2 100644 --- a/src/p_setup.cpp +++ b/src/p_setup.cpp @@ -122,8 +122,6 @@ inline bool P_LoadBuildMap(BYTE *mapdata, size_t len, FMapThing **things, int *n // MAP related Lookup tables. // Store VERTEXES, LINEDEFS, SIDEDEFS, etc. // -int numvertexes; -vertex_t* vertexes; int numvertexdatas; vertexdata_t* vertexdatas; @@ -833,11 +831,9 @@ void P_FloodZones () void P_LoadVertexes (MapData * map) { - int i; - // Determine number of vertices: // total lump length / vertex record length. - numvertexes = map->Size(ML_VERTEXES) / sizeof(mapvertex_t); + unsigned numvertexes = map->Size(ML_VERTEXES) / sizeof(mapvertex_t); numvertexdatas = 0; if (numvertexes == 0) @@ -846,18 +842,18 @@ void P_LoadVertexes (MapData * map) } // Allocate memory for buffer. - vertexes = new vertex_t[numvertexes]; + level.vertexes.Alloc(numvertexes); vertexdatas = NULL; map->Seek(ML_VERTEXES); // Copy and convert vertex coordinates, internal representation as fixed. - for (i = 0; i < numvertexes; i++) + for (auto &v : level.vertexes) { - SWORD x, y; + int16_t x, y; (*map->file) >> x >> y; - vertexes[i].set(double(x), double(y)); + v.set(double(x), double(y)); } } @@ -878,8 +874,8 @@ void P_LoadZSegs (FileReaderBase &data) data >> v1 >> v2 >> line >> side; - segs[i].v1 = &vertexes[v1]; - segs[i].v2 = &vertexes[v2]; + segs[i].v1 = &level.vertexes[v1]; + segs[i].v2 = &level.vertexes[v2]; segs[i].linedef = ldef = &level.lines[line]; segs[i].sidedef = ldef->sidedef[side]; segs[i].frontsector = ldef->sidedef[side]->sector; @@ -928,7 +924,7 @@ void P_LoadGLZSegs (FileReaderBase &data, int type) data >> side; seg = subsectors[i].firstline + j; - seg->v1 = &vertexes[v1]; + seg->v1 = &level.vertexes[v1]; if (j == 0) { seg[subsectors[i].numlines - 1].v2 = seg->v1; @@ -975,23 +971,26 @@ void LoadZNodes(FileReaderBase &data, int glnodes) { // Read extra vertices added during node building DWORD orgVerts, newVerts; - vertex_t *newvertarray; + TStaticArray newvertarray; unsigned int i; data >> orgVerts >> newVerts; - if (orgVerts > (DWORD)numvertexes) + if (orgVerts > level.vertexes.Size()) { // These nodes are based on a map with more vertex data than we have. // We can't use them. throw CRecoverableError("Incorrect number of vertexes in nodes.\n"); } - if (orgVerts + newVerts == (DWORD)numvertexes) + bool fix; + if (orgVerts + newVerts == level.vertexes.Size()) { - newvertarray = vertexes; + newvertarray = std::move(level.vertexes); + fix = false; } else { - newvertarray = new vertex_t[orgVerts + newVerts]; - memcpy (newvertarray, vertexes, orgVerts * sizeof(vertex_t)); + newvertarray.Alloc(orgVerts + newVerts); + memcpy (&newvertarray[0], &level.vertexes[0], orgVerts * sizeof(vertex_t)); + fix = true; } for (i = 0; i < newVerts; ++i) { @@ -999,16 +998,14 @@ void LoadZNodes(FileReaderBase &data, int glnodes) data >> x >> y; newvertarray[i + orgVerts].set(x, y); } - if (vertexes != newvertarray) + if (fix) { for (auto &line : level.lines) { - line.v1 = line.v1 - vertexes + newvertarray; - line.v2 = line.v2 - vertexes + newvertarray; + line.v1 = line.v1 - &level.vertexes[0] + &newvertarray[0]; + line.v2 = line.v2 - &level.vertexes[0] + &newvertarray[0]; } - delete[] vertexes; - vertexes = newvertarray; - numvertexes = orgVerts + newVerts; + level.vertexes = std::move(newvertarray); } // Read the subsectors @@ -1212,6 +1209,7 @@ void P_LoadSegs (MapData * map) { int i; BYTE *data; + int numvertexes = level.vertexes.Size(); BYTE *vertchanged = new BYTE[numvertexes]; // phares 10/4/98 DWORD segangle; //int ptp_angle; // phares 10/4/98 @@ -1250,7 +1248,7 @@ void P_LoadSegs (MapData * map) for (auto &line : level.lines) { - vertchanged[line.v1 - vertexes] = vertchanged[line.v2 - vertexes] = 1; + vertchanged[line.v1->Index()] = vertchanged[line.v2->Index()] = 1; } try @@ -1271,8 +1269,8 @@ void P_LoadSegs (MapData * map) throw badseg(0, i, MAX(vnum1, vnum2)); } - li->v1 = &vertexes[vnum1]; - li->v2 = &vertexes[vnum2]; + li->v1 = &level.vertexes[vnum1]; + li->v2 = &level.vertexes[vnum2]; segangle = (WORD)LittleShort(ml->angle); @@ -2111,17 +2109,16 @@ void P_LoadLineDefs (MapData * map) for (skipped = sidecount = i = 0; i < numlines; ) { mld = ((maplinedef_t*)mldf) + i; - int v1 = LittleShort(mld->v1); - int v2 = LittleShort(mld->v2); + unsigned v1 = LittleShort(mld->v1); + unsigned v2 = LittleShort(mld->v2); - if (v1 >= numvertexes || v2 >= numvertexes) + if (v1 >= level.vertexes.Size() || v2 >= level.vertexes.Size()) { delete [] mldf; - I_Error ("Line %d has invalid vertices: %d and/or %d.\nThe map only contains %d vertices.", i+skipped, v1, v2, numvertexes); + I_Error ("Line %d has invalid vertices: %d and/or %d.\nThe map only contains %u vertices.", i+skipped, v1, v2, level.vertexes.Size()); } else if (v1 == v2 || - (vertexes[LittleShort(mld->v1)].fX() == vertexes[LittleShort(mld->v2)].fX() && - vertexes[LittleShort(mld->v1)].fY() == vertexes[LittleShort(mld->v2)].fY())) + (level.vertexes[v1].fX() == level.vertexes[v2].fX() && level.vertexes[v1].fY() == level.vertexes[v2].fY())) { Printf ("Removing 0-length line %d\n", i+skipped); memmove (mld, mld+1, sizeof(*mld)*(numlines-i-1)); @@ -2172,8 +2169,8 @@ void P_LoadLineDefs (MapData * map) } #endif - ld->v1 = &vertexes[LittleShort(mld->v1)]; - ld->v2 = &vertexes[LittleShort(mld->v2)]; + ld->v1 = &level.vertexes[LittleShort(mld->v1)]; + ld->v2 = &level.vertexes[LittleShort(mld->v2)]; P_SetSideNum (&ld->sidedef[0], LittleShort(mld->sidenum[0])); P_SetSideNum (&ld->sidedef[1], LittleShort(mld->sidenum[1])); @@ -2210,8 +2207,8 @@ void P_LoadLineDefs2 (MapData * map) mld = ((maplinedef2_t*)mldf) + i; if (mld->v1 == mld->v2 || - (vertexes[LittleShort(mld->v1)].fX() == vertexes[LittleShort(mld->v2)].fX() && - vertexes[LittleShort(mld->v1)].fY() == vertexes[LittleShort(mld->v2)].fY())) + (level.vertexes[LittleShort(mld->v1)].fX() == level.vertexes[LittleShort(mld->v2)].fX() && + level.vertexes[LittleShort(mld->v1)].fY() == level.vertexes[LittleShort(mld->v2)].fY())) { Printf ("Removing 0-length line %d\n", i+skipped); memmove (mld, mld+1, sizeof(*mld)*(numlines-i-1)); @@ -2256,8 +2253,8 @@ void P_LoadLineDefs2 (MapData * map) ld->flags = LittleShort(mld->flags); ld->special = mld->special; - ld->v1 = &vertexes[LittleShort(mld->v1)]; - ld->v2 = &vertexes[LittleShort(mld->v2)]; + ld->v1 = &level.vertexes[LittleShort(mld->v1)]; + ld->v2 = &level.vertexes[LittleShort(mld->v2)]; ld->alpha = 1.; // [RH] Opaque by default P_SetSideNum (&ld->sidedef[0], LittleShort(mld->sidenum[0])); @@ -2297,7 +2294,7 @@ static void P_AllocateSideDefs (MapData *map, int count) level.sides.Alloc(count); memset(&level.sides[0], 0, count * sizeof(side_t)); - sidetemp = new sidei_t[MAX(count,numvertexes)]; + sidetemp = new sidei_t[MAX(count, level.vertexes.Size())]; for (i = 0; i < count; i++) { sidetemp[i].a.special = sidetemp[i].a.tag = 0; @@ -2326,9 +2323,9 @@ static void P_LoopSidedefs (bool firstloop) delete[] sidetemp; } int numsides = level.sides.Size(); - sidetemp = new sidei_t[MAX(numvertexes, numsides)]; + sidetemp = new sidei_t[MAX(level.vertexes.Size(), numsides)]; - for (i = 0; i < numvertexes; ++i) + for (i = 0; i < (int)level.vertexes.Size(); ++i) { sidetemp[i].b.first = NO_SIDE; sidetemp[i].b.next = NO_SIDE; @@ -2344,7 +2341,7 @@ static void P_LoopSidedefs (bool firstloop) // as their left edge. line_t *line = level.sides[i].linedef; int lineside = (line->sidedef[0] != &level.sides[i]); - int vert = int((lineside ? line->v2 : line->v1) - vertexes); + int vert = lineside ? line->v2->Index() : line->v1->Index(); sidetemp[i].b.lineside = lineside; sidetemp[i].b.next = sidetemp[vert].b.first; @@ -2383,11 +2380,11 @@ static void P_LoopSidedefs (bool firstloop) { if (sidetemp[i].b.lineside) { - right = int(line->v1 - vertexes); + right = line->v1->Index(); } else { - right = int(line->v2 - vertexes); + right = line->v2->Index(); } right = sidetemp[right].b.first; @@ -2764,22 +2761,21 @@ static void P_CreateBlockMap () int bmapwidth, bmapheight; double dminx, dmaxx, dminy, dmaxy; int minx, maxx, miny, maxy; - int i; int line; - if (numvertexes <= 0) + if (level.vertexes.Size() == 0) return; // Find map extents for the blockmap - dminx = dmaxx = vertexes[0].fX(); - dminy = dmaxy = vertexes[0].fY(); + dminx = dmaxx = level.vertexes[0].fX(); + dminy = dmaxy = level.vertexes[0].fY(); - for (i = 1; i < numvertexes; ++i) + for (auto &vert : level.vertexes) { - if (vertexes[i].fX() < dminx) dminx = vertexes[i].fX(); - else if (vertexes[i].fX() > dmaxx) dmaxx = vertexes[i].fX(); - if (vertexes[i].fY() < dminy) dminy = vertexes[i].fY(); - else if (vertexes[i].fY() > dmaxy) dmaxy = vertexes[i].fY(); + if (vert.fX() < dminx) dminx = vert.fX(); + else if (vert.fX() > dmaxx) dmaxx = vert.fX(); + if (vert.fY() < dminy) dminy = vert.fY(); + else if (vert.fY() > dmaxy) dmaxy = vert.fY(); } minx = int(dminx); @@ -3435,12 +3431,6 @@ void P_FreeLevelData () wminfo.maxfrags = 0; FBehavior::StaticUnloadModules (); - if (vertexes != NULL) - { - delete[] vertexes; - vertexes = NULL; - } - numvertexes = 0; if (segs != NULL) { delete[] segs; @@ -3459,6 +3449,7 @@ void P_FreeLevelData () level.sectors.Clear(); level.lines.Clear(); level.sides.Clear(); + level.vertexes.Clear(); if (gamenodes != NULL && gamenodes != nodes) { @@ -3906,7 +3897,7 @@ void P_SetupLevel (const char *lumpname, int position) P_GetPolySpots (map, polyspots, anchors); FNodeBuilder::FLevel leveldata = { - vertexes, numvertexes, + &level.vertexes[0], (int)level.vertexes.Size(), &level.sides[0], (int)level.sides.Size(), &level.lines[0], (int)level.lines.Size(), 0, 0, 0, 0 @@ -3916,11 +3907,10 @@ void P_SetupLevel (const char *lumpname, int position) // In case a sync critical game mode is started, also build GL nodes to avoid problems // if the different machines' am_textured setting differs. FNodeBuilder builder (leveldata, polyspots, anchors, BuildGLNodes); - delete[] vertexes; builder.Extract (nodes, numnodes, segs, glsegextras, numsegs, subsectors, numsubsectors, - vertexes, numvertexes); + level.vertexes); endTime = I_FPSTime (); DPrintf (DMSG_NOTIFY, "BSP generation took %.3f sec (%d segs)\n", (endTime - startTime) * 0.001, numsegs); oldvertextable = builder.GetOldVertexTable(); diff --git a/src/p_slopes.cpp b/src/p_slopes.cpp index 672c9e77b3..c16e03b3c6 100644 --- a/src/p_slopes.cpp +++ b/src/p_slopes.cpp @@ -258,9 +258,9 @@ static void P_SetSlopesFromVertexHeights(FMapThing *firstmt, FMapThing *lastmt, { if (mt->info->Special == SMT_VertexFloorZ || mt->info->Special == SMT_VertexCeilingZ) { - for (int i = 0; i < numvertexes; i++) + for (unsigned i = 0; i < level.vertexes.Size(); i++) { - if (vertexes[i].fX() == mt->pos.X && vertexes[i].fY() == mt->pos.Y) + if (level.vertexes[i].fX() == mt->pos.X && level.vertexes[i].fY() == mt->pos.Y) { if (mt->info->Special == SMT_VertexFloorZ) { @@ -310,14 +310,14 @@ static void P_SetSlopesFromVertexHeights(FMapThing *firstmt, FMapThing *lastmt, DVector3 vec1, vec2; int vi1, vi2, vi3; - vi1 = int(sec.Lines[0]->v1 - vertexes); - vi2 = int(sec.Lines[0]->v2 - vertexes); + vi1 = sec.Lines[0]->v1->Index(); + vi2 = sec.Lines[0]->v2->Index(); vi3 = (sec.Lines[1]->v1 == sec.Lines[0]->v1 || sec.Lines[1]->v1 == sec.Lines[0]->v2)? - int(sec.Lines[1]->v2 - vertexes) : int(sec.Lines[1]->v1 - vertexes); + sec.Lines[1]->v2->Index() : sec.Lines[1]->v1->Index(); - vt1 = DVector3(vertexes[vi1].fPos(), 0); - vt2 = DVector3(vertexes[vi2].fPos(), 0); - vt3 = DVector3(vertexes[vi3].fPos(), 0); + vt1 = DVector3(level.vertexes[vi1].fPos(), 0); + vt2 = DVector3(level.vertexes[vi2].fPos(), 0); + vt3 = DVector3(level.vertexes[vi3].fPos(), 0); for(int j=0; j<2; j++) { @@ -330,7 +330,7 @@ static void P_SetSlopesFromVertexHeights(FMapThing *firstmt, FMapThing *lastmt, vt2.Z = h2? *h2 : j==0? sec.GetPlaneTexZ(sector_t::floor) : sec.GetPlaneTexZ(sector_t::ceiling); vt3.Z = h3? *h3 : j==0? sec.GetPlaneTexZ(sector_t::floor) : sec.GetPlaneTexZ(sector_t::ceiling); - if (P_PointOnLineSidePrecise(vertexes[vi3].fX(), vertexes[vi3].fY(), sec.Lines[0]) == 0) + if (P_PointOnLineSidePrecise(level.vertexes[vi3].fX(), level.vertexes[vi3].fY(), sec.Lines[0]) == 0) { vec1 = vt2 - vt3; vec2 = vt1 - vt3; @@ -360,7 +360,7 @@ static void P_SetSlopesFromVertexHeights(FMapThing *firstmt, FMapThing *lastmt, secplane_t *plane = j==0? &sec.floorplane : &sec.ceilingplane; - double dist = -cross[0] * vertexes[vi3].fX() - cross[1] * vertexes[vi3].fY() - cross[2] * vt3.Z; + double dist = -cross[0] * level.vertexes[vi3].fX() - cross[1] * level.vertexes[vi3].fY() - cross[2] * vt3.Z; plane->set(cross[0], cross[1], cross[2], dist); } } diff --git a/src/p_udmf.cpp b/src/p_udmf.cpp index d86e83a39a..0284c0c233 100644 --- a/src/p_udmf.cpp +++ b/src/p_udmf.cpp @@ -1790,12 +1790,12 @@ public: intptr_t v1i = intptr_t(ParsedLines[i].v1); intptr_t v2i = intptr_t(ParsedLines[i].v2); - if (v1i >= numvertexes || v2i >= numvertexes || v1i < 0 || v2i < 0) + if (v1i >= level.vertexes.Size() || v2i >= level.vertexes.Size() || v1i < 0 || v2i < 0) { - I_Error ("Line %d has invalid vertices: %zd and/or %zd.\nThe map only contains %d vertices.", i+skipped, v1i, v2i, numvertexes); + I_Error ("Line %d has invalid vertices: %zd and/or %zd.\nThe map only contains %u vertices.", i+skipped, v1i, v2i, level.vertexes.Size()); } else if (v1i == v2i || - (vertexes[v1i].fX() == vertexes[v2i].fX() && vertexes[v1i].fY() == vertexes[v2i].fY())) + (level.vertexes[v1i].fX() == level.vertexes[v2i].fX() && level.vertexes[v1i].fY() == level.vertexes[v2i].fY())) { Printf ("Removing 0-length line %d\n", i+skipped); ParsedLines.Delete(i); @@ -1804,8 +1804,8 @@ public: } else { - ParsedLines[i].v1 = &vertexes[v1i]; - ParsedLines[i].v2 = &vertexes[v2i]; + ParsedLines[i].v1 = &level.vertexes[v1i]; + ParsedLines[i].v2 = &level.vertexes[v2i]; if (ParsedLines[i].sidedef[0] != NULL) sidecount++; @@ -2011,9 +2011,8 @@ public: if (ParsedSides.Size() == 0) I_Error("Map has no sidedefs.\n"); // Create the real vertices - numvertexes = ParsedVertices.Size(); - vertexes = new vertex_t[numvertexes]; - memcpy(vertexes, &ParsedVertices[0], numvertexes * sizeof(*vertexes)); + level.vertexes.Alloc(ParsedVertices.Size()); + memcpy(&level.vertexes[0], &ParsedVertices[0], level.vertexes.Size() * sizeof(vertex_t)); // Create the real vertex datas numvertexdatas = ParsedVertexDatas.Size(); diff --git a/src/po_man.cpp b/src/po_man.cpp index 45b4592814..e8c1cbbb87 100644 --- a/src/po_man.cpp +++ b/src/po_man.cpp @@ -1479,7 +1479,7 @@ static void IterFindPolySides (FPolyObj *po, side_t *side) assert(sidetemp != NULL); vnum.Clear(); - vnum.Push(DWORD(side->V1() - vertexes)); + vnum.Push(DWORD(side->V1()->Index())); vnumat = 0; while (vnum.Size() != vnumat) @@ -1488,7 +1488,7 @@ static void IterFindPolySides (FPolyObj *po, side_t *side) while (sidenum != NO_SIDE) { po->Sidedefs.Push(&level.sides[sidenum]); - AddPolyVert(vnum, DWORD(level.sides[sidenum].V2() - vertexes)); + AddPolyVert(vnum, DWORD(level.sides[sidenum].V2()->Index())); sidenum = sidetemp[sidenum].b.next; } } diff --git a/src/r_defs.h b/src/r_defs.h index ce6890311d..6972eab65f 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -131,11 +131,13 @@ struct vertex_t return FLOAT2FIXED(p.Y); } - DVector2 fPos() + DVector2 fPos() const { return p; } + int Index() const; + angle_t viewangle; // precalculated angle for clipping int angletime; // recalculation time for view angle bool dirty; // something has changed and needs to be recalculated diff --git a/src/r_state.h b/src/r_state.h index 743bc11a00..aa5b46342b 100644 --- a/src/r_state.h +++ b/src/r_state.h @@ -42,8 +42,6 @@ extern "C" int viewheight; extern TArray sprites; extern DWORD NumStdSprites; -extern int numvertexes; -extern vertex_t* vertexes; extern int numvertexdatas; extern vertexdata_t* vertexdatas; diff --git a/src/scripting/thingdef_data.cpp b/src/scripting/thingdef_data.cpp index 0effa0c202..46485b2268 100644 --- a/src/scripting/thingdef_data.cpp +++ b/src/scripting/thingdef_data.cpp @@ -730,6 +730,10 @@ void InitThingdef() sidestruct->Size = sizeof(side_t); sidestruct->Align = alignof(side_t); + auto vertstruct = NewNativeStruct("Vertex", nullptr); + vertstruct->Size = sizeof(vertex_t); + vertstruct->Align = alignof(vertex_t); + // set up the lines array in the sector struct. This is a bit messy because the type system is not prepared to handle a pointer to an array of pointers to a native struct even remotely well... // As a result, the size has to be set to something large and arbritrary because it can change between maps. This will need some serious improvement when things get cleaned up. @@ -759,6 +763,7 @@ void InitThingdef() lstruct->AddNativeField("sectors", NewPointer(NewResizableArray(sectorstruct), false), myoffsetof(FLevelLocals, sectors), VARF_Native); lstruct->AddNativeField("lines", NewPointer(NewResizableArray(linestruct), false), myoffsetof(FLevelLocals, lines), VARF_Native); lstruct->AddNativeField("sides", NewPointer(NewResizableArray(sidestruct), false), myoffsetof(FLevelLocals, sides), VARF_Native); + lstruct->AddNativeField("vertexes", NewPointer(NewResizableArray(vertstruct), false), myoffsetof(FLevelLocals, vertexes), VARF_Native|VARF_ReadOnly); // set up a variable for the DEH data PStruct *dstruct = NewNativeStruct("DehInfo", nullptr); diff --git a/src/serializer.cpp b/src/serializer.cpp index 181d4b741e..5154b0700c 100644 --- a/src/serializer.cpp +++ b/src/serializer.cpp @@ -1484,7 +1484,7 @@ template<> FSerializer &Serialize(FSerializer &arc, const char *key, line_t *&va template<> FSerializer &Serialize(FSerializer &arc, const char *key, vertex_t *&value, vertex_t **defval) { - return SerializePointer(arc, key, value, defval, vertexes); + return SerializePointer(arc, key, value, defval, &level.vertexes[0]); } //========================================================================== diff --git a/src/tarray.h b/src/tarray.h index 5ae24965de..3ee1c5cb99 100644 --- a/src/tarray.h +++ b/src/tarray.h @@ -553,6 +553,13 @@ public: this->Count = 0; this->Array = NULL; } + TStaticArray(TStaticArray &&other) + { + this->Array = other.Array; + this->Count = other.Count; + other.Array = nullptr; + other.Count = 0; + } // This is not supposed to be copyable. TStaticArray(const TStaticArray &other) = delete; @@ -564,7 +571,7 @@ public: { if (this->Array) delete[] this->Array; this->Count = 0; - this->Array = NULL; + this->Array = nullptr; } void Alloc(unsigned int amount) { @@ -579,6 +586,15 @@ public: memcpy(this->Array, other.Array, this->Count * sizeof(T)); return *this; } + TStaticArray &operator=(TStaticArray &&other) + { + if (this->Array) delete[] this->Array; + this->Array = other.Array; + this->Count = other.Count; + other.Array = nullptr; + other.Count = 0; + return *this; + } };