- made the vertexes array VM friendly.

This commit is contained in:
Christoph Oelckers 2017-01-09 00:46:16 +01:00
parent f78927500e
commit 12037fdc95
17 changed files with 190 additions and 169 deletions

View file

@ -1029,17 +1029,17 @@ static void AM_findMinMaxBoundaries ()
min_x = min_y = FLT_MAX; min_x = min_y = FLT_MAX;
max_x = max_y = FIXED_MIN; max_x = max_y = FIXED_MIN;
for (int i = 0; i < numvertexes; i++) for (auto &vert : level.vertexes)
{ {
if (vertexes[i].fX() < min_x) if (vert.fX() < min_x)
min_x = vertexes[i].fX(); min_x = vert.fX();
else if (vertexes[i].fX() > max_x) else if (vert.fX() > max_x)
max_x = vertexes[i].fX(); max_x = vert.fX();
if (vertexes[i].fY() < min_y) if (vert.fY() < min_y)
min_y = vertexes[i].fY(); min_y = vert.fY();
else if (vertexes[i].fY() > max_y) else if (vert.fY() > max_y)
max_y = vertexes[i].fY(); max_y = vert.fY();
} }
max_w = max_x - min_x; max_w = max_x - min_x;

View file

@ -27,6 +27,7 @@ struct FLevelLocals
FString NextSecretMap; // map to go to when used secret exit FString NextSecretMap; // map to go to when used secret exit
EMapType maptype; EMapType maptype;
TStaticArray<vertex_t> vertexes;
TStaticArray<sector_t> sectors; TStaticArray<sector_t> sectors;
TStaticArray<line_t> lines; TStaticArray<line_t> lines;
TStaticArray<side_t> sides; TStaticArray<side_t> sides;
@ -79,6 +80,11 @@ struct FLevelLocals
extern FLevelLocals level; extern FLevelLocals level;
inline int vertex_t::Index() const
{
return int(this - &level.vertexes[0]);
}
inline int side_t::Index() const inline int side_t::Index() const
{ {
return int(this - &level.sides[0]); return int(this - &level.sides[0]);

View file

@ -403,7 +403,7 @@ static void InitVertexData()
int i,j,k; int i,j,k;
vt_sectorlists = new TArray<int>[numvertexes]; vt_sectorlists = new TArray<int>[level.vertexes.Size()];
for(auto &line : level.lines) for(auto &line : level.lines)
@ -420,32 +420,33 @@ static void InitVertexData()
{ {
extsector_t::xfloor &x = sec->e->XFloor; extsector_t::xfloor &x = sec->e->XFloor;
AddToVertex(sec, vt_sectorlists[v-vertexes]); AddToVertex(sec, vt_sectorlists[v->Index()]);
if (sec->heightsec) AddToVertex(sec->heightsec, vt_sectorlists[v-vertexes]); if (sec->heightsec) AddToVertex(sec->heightsec, vt_sectorlists[v->Index()]);
} }
} }
} }
} }
for(i=0;i<numvertexes;i++) for(i=0;i<level.vertexes.Size();i++)
{ {
auto vert = level.vertexes[i];
int cnt = vt_sectorlists[i].Size(); int cnt = vt_sectorlists[i].Size();
vertexes[i].dirty = true; vert.dirty = true;
vertexes[i].numheights=0; vert.numheights=0;
if (cnt>1) if (cnt>1)
{ {
vertexes[i].numsectors= cnt; vert.numsectors= cnt;
vertexes[i].sectors=new sector_t*[cnt]; vert.sectors=new sector_t*[cnt];
vertexes[i].heightlist = new float[cnt*2]; vert.heightlist = new float[cnt*2];
for(int j=0;j<cnt;j++) for(int j=0;j<cnt;j++)
{ {
vertexes[i].sectors[j] = &level.sectors[vt_sectorlists[i][j]]; vert.sectors[j] = &level.sectors[vt_sectorlists[i][j]];
} }
} }
else else
{ {
vertexes[i].numsectors=0; vert.numsectors=0;
} }
} }
@ -493,9 +494,9 @@ static void PrepareSegs()
int realsegs = 0; int realsegs = 0;
// Get floatng point coordinates of vertices // Get floatng point coordinates of vertices
for(int i = 0; i < numvertexes; i++) for(auto &v : level.vertexes)
{ {
vertexes[i].dirty = true; v.dirty = true;
} }
// count the segs // count the segs
@ -586,8 +587,8 @@ void gl_PreprocessLevel()
PrepareSegs(); PrepareSegs();
PrepareSectorData(); PrepareSectorData();
InitVertexData(); InitVertexData();
int *checkmap = new int[numvertexes]; int *checkmap = new int[level.vertexes.Size()];
memset(checkmap, -1, sizeof(int)*numvertexes); memset(checkmap, -1, sizeof(int)*level.vertexes.Size());
for(auto &sec : level.sectors) for(auto &sec : level.sectors)
{ {
int i = sec.sectornum; int i = sec.sectornum;
@ -598,21 +599,21 @@ void gl_PreprocessLevel()
{ {
if (l->sidedef[0]->Flags & WALLF_POLYOBJ) continue; // don't bother with polyobjects if (l->sidedef[0]->Flags & WALLF_POLYOBJ) continue; // don't bother with polyobjects
int vtnum1 = int(l->v1 - vertexes); int vtnum1 = l->v1->Index();
int vtnum2 = int(l->v2 - vertexes); int vtnum2 = l->v2->Index();
if (checkmap[vtnum1] < i) if (checkmap[vtnum1] < i)
{ {
checkmap[vtnum1] = i; checkmap[vtnum1] = i;
sec.e->vertices.Push(&vertexes[vtnum1]); sec.e->vertices.Push(&level.vertexes[vtnum1]);
vertexes[vtnum1].dirty = true; level.vertexes[vtnum1].dirty = true;
} }
if (checkmap[vtnum2] < i) if (checkmap[vtnum2] < i)
{ {
checkmap[vtnum2] = i; checkmap[vtnum2] = i;
sec.e->vertices.Push(&vertexes[vtnum2]); sec.e->vertices.Push(&level.vertexes[vtnum2]);
vertexes[vtnum2].dirty = true; level.vertexes[vtnum2].dirty = true;
} }
} }
} }
@ -652,20 +653,17 @@ void gl_CleanLevelData()
mo=next; 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 [] v.sectors;
{ v.sectors = nullptr;
delete [] vertexes[i].sectors;
vertexes[i].sectors = NULL;
} }
if (vertexes[i].heightlist != NULL) if (v.heightlist != nullptr)
{ {
delete [] vertexes[i].heightlist; delete [] v.heightlist;
vertexes[i].heightlist = NULL; v.heightlist = nullptr;
}
} }
} }

View file

@ -209,10 +209,10 @@ public:
bool makeGLNodes); bool makeGLNodes);
~FNodeBuilder (); ~FNodeBuilder ();
void Extract (node_t *&nodes, int &nodeCount, void Extract(node_t *&nodes, int &nodeCount,
seg_t *&segs, glsegextra_t *&glsegextras, int &segCount, seg_t *&segs, glsegextra_t *&glsegextras, int &segCount,
subsector_t *&ssecs, int &subCount, subsector_t *&ssecs, int &subCount,
vertex_t *&verts, int &vertCount); TStaticArray<vertex_t> &vertexes);
const int *GetOldVertexTable(); const int *GetOldVertexTable();
// These are used for building sub-BSP trees for polyobjects. // These are used for building sub-BSP trees for polyobjects.

View file

@ -55,12 +55,12 @@
void FNodeBuilder::Extract (node_t *&outNodes, int &nodeCount, void FNodeBuilder::Extract (node_t *&outNodes, int &nodeCount,
seg_t *&outSegs, glsegextra_t *&outSegExtras, int &segCount, seg_t *&outSegs, glsegextra_t *&outSegExtras, int &segCount,
subsector_t *&outSubs, int &subCount, subsector_t *&outSubs, int &subCount,
vertex_t *&outVerts, int &vertCount) TStaticArray<vertex_t> &outVerts)
{ {
int i; int i;
vertCount = Vertices.Size (); int vertCount = Vertices.Size ();
outVerts = new vertex_t[vertCount]; outVerts.Alloc(vertCount);
for (i = 0; i < vertCount; ++i) for (i = 0; i < vertCount; ++i)
{ {
@ -109,7 +109,7 @@ void FNodeBuilder::Extract (node_t *&outNodes, int &nodeCount,
for (i = 0; i < subCount; ++i) 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].numlines = numsegs;
outSubs[i].firstline = (seg_t *)(size_t)(segs.Size() - 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)); D(Printf(PRINT_LOG, "Seg %d: v1(%d) -> v2(%d)\n", i, org->v1, org->v2));
out->v1 = outVerts + org->v1; out->v1 = &outVerts[org->v1];
out->v2 = outVerts + org->v2; out->v2 = &outVerts[org->v2];
out->backsector = org->backsector; out->backsector = org->backsector;
out->frontsector = org->frontsector; out->frontsector = org->frontsector;
out->linedef = Level.Lines + org->linedef; 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) for (i = 0; i < Level.NumLines; ++i)
{ {
Level.Lines[i].v1 = outVerts + (size_t)Level.Lines[i].v1; 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].v2 = &outVerts[(size_t)Level.Lines[i].v2];
} }
} }

View file

@ -224,7 +224,7 @@ static bool LoadGLVertexes(FileReader * lump)
BYTE *gldata; BYTE *gldata;
int i; int i;
firstglvertex = numvertexes; firstglvertex = level.vertexes.Size();
int gllen=lump->GetLength(); int gllen=lump->GetLength();
@ -249,23 +249,23 @@ static bool LoadGLVertexes(FileReader * lump)
} }
else format5=false; 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; TStaticArray<vertex_t> oldvertexes = std::move(level.vertexes);
numvertexes += (gllen - GL_VERT_OFFSET)/sizeof(mapglvertex_t); level.vertexes.Alloc(numvertexes);
vertexes = new vertex_t[numvertexes];
mgl = (mapglvertex_t *) (gldata + GL_VERT_OFFSET);
memcpy(vertexes, oldvertexes, firstglvertex * sizeof(vertex_t)); memcpy(&level.vertexes[0], &oldvertexes[0], firstglvertex * sizeof(vertex_t));
for(auto &line : level.lines) for(auto &line : level.lines)
{ {
line.v1 = vertexes + (line.v1 - oldvertexes); // Remap vertex pointers in linedefs
line.v2 = vertexes + (line.v2 - oldvertexes); 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++; mgl++;
} }
delete[] gldata; delete[] gldata;
@ -324,8 +324,8 @@ static bool LoadGLSegs(FileReader * lump)
glseg_t * ml = (glseg_t*)data; glseg_t * ml = (glseg_t*)data;
for(i = 0; i < numsegs; i++) for(i = 0; i < numsegs; i++)
{ // check for gl-vertices { // check for gl-vertices
segs[i].v1 = &vertexes[checkGLVertex(LittleShort(ml->v1))]; segs[i].v1 = &level.vertexes[checkGLVertex(LittleShort(ml->v1))];
segs[i].v2 = &vertexes[checkGLVertex(LittleShort(ml->v2))]; segs[i].v2 = &level.vertexes[checkGLVertex(LittleShort(ml->v2))];
glsegextras[i].PartnerSeg = ml->partner == 0xFFFF ? DWORD_MAX : LittleShort(ml->partner); glsegextras[i].PartnerSeg = ml->partner == 0xFFFF ? DWORD_MAX : LittleShort(ml->partner);
if(ml->linedef != 0xffff) if(ml->linedef != 0xffff)
@ -377,8 +377,8 @@ static bool LoadGLSegs(FileReader * lump)
glseg3_t * ml = (glseg3_t*)(data+ (format5? 0:4)); glseg3_t * ml = (glseg3_t*)(data+ (format5? 0:4));
for(i = 0; i < numsegs; i++) for(i = 0; i < numsegs; i++)
{ // check for gl-vertices { // check for gl-vertices
segs[i].v1 = &vertexes[checkGLVertex3(LittleLong(ml->v1))]; segs[i].v1 = &level.vertexes[checkGLVertex3(LittleLong(ml->v1))];
segs[i].v2 = &vertexes[checkGLVertex3(LittleLong(ml->v2))]; segs[i].v2 = &level.vertexes[checkGLVertex3(LittleLong(ml->v2))];
glsegextras[i].PartnerSeg = LittleLong(ml->partner); glsegextras[i].PartnerSeg = LittleLong(ml->partner);
@ -1002,18 +1002,18 @@ bool P_CheckNodes(MapData * map, bool rebuilt, int buildtime)
P_GetPolySpots (map, polyspots, anchors); P_GetPolySpots (map, polyspots, anchors);
FNodeBuilder::FLevel leveldata = FNodeBuilder::FLevel leveldata =
{ {
vertexes, numvertexes, &level.vertexes[0], (int)level.vertexes.Size(),
&level.sides[0], (int)level.sides.Size(), &level.sides[0], (int)level.sides.Size(),
&level.lines[0], (int)level.lines.Size(), &level.lines[0], (int)level.lines.Size(),
0, 0, 0, 0 0, 0, 0, 0
}; };
leveldata.FindMapBounds (); leveldata.FindMapBounds ();
FNodeBuilder builder (leveldata, polyspots, anchors, true); FNodeBuilder builder (leveldata, polyspots, anchors, true);
delete[] vertexes;
builder.Extract (nodes, numnodes, builder.Extract (nodes, numnodes,
segs, glsegextras, numsegs, segs, glsegextras, numsegs,
subsectors, numsubsectors, subsectors, numsubsectors,
vertexes, numvertexes); level.vertexes);
endTime = I_FPSTime (); endTime = I_FPSTime ();
DPrintf (DMSG_NOTIFY, "BSP generation took %.3f sec (%d segs)\n", (endTime - startTime) * 0.001, numsegs); DPrintf (DMSG_NOTIFY, "BSP generation took %.3f sec (%d segs)\n", (endTime - startTime) * 0.001, numsegs);
buildtime = endTime - startTime; buildtime = endTime - startTime;
@ -1095,11 +1095,11 @@ static void CreateCachedNodes(MapData *map)
MemFile ZNodes; MemFile ZNodes;
WriteLong(ZNodes, 0); WriteLong(ZNodes, 0);
WriteLong(ZNodes, numvertexes); WriteLong(ZNodes, level.vertexes.Size());
for(int i=0;i<numvertexes;i++) for(auto &vert : level.vertexes)
{ {
WriteLong(ZNodes, vertexes[i].fixX()); WriteLong(ZNodes, vert.fixX());
WriteLong(ZNodes, vertexes[i].fixY()); WriteLong(ZNodes, vert.fixY());
} }
WriteLong(ZNodes, numsubsectors); WriteLong(ZNodes, numsubsectors);
@ -1111,7 +1111,7 @@ static void CreateCachedNodes(MapData *map)
WriteLong(ZNodes, numsegs); WriteLong(ZNodes, numsegs);
for(int i=0;i<numsegs;i++) for(int i=0;i<numsegs;i++)
{ {
WriteLong(ZNodes, DWORD(segs[i].v1 - vertexes)); WriteLong(ZNodes, segs[i].v1->Index());
if (glsegextras != NULL) WriteLong(ZNodes, DWORD(glsegextras[i].PartnerSeg)); if (glsegextras != NULL) WriteLong(ZNodes, DWORD(glsegextras[i].PartnerSeg));
else WriteLong(ZNodes, 0); else WriteLong(ZNodes, 0);
if (segs[i].linedef) if (segs[i].linedef)
@ -1178,7 +1178,7 @@ static void CreateCachedNodes(MapData *map)
map->GetChecksum(compressed+8); map->GetChecksum(compressed+8);
for (unsigned i = 0; i < level.lines.Size(); i++) 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 + 8 + 16 + 8 * i, ndx, 8);
} }
memcpy(compressed + offset - 4, "ZGL3", 4); memcpy(compressed + offset - 4, "ZGL3", 4);
@ -1266,8 +1266,8 @@ static bool CheckCachedNodes(MapData *map)
for(auto &line : level.lines) for(auto &line : level.lines)
{ {
int i = line.Index(); int i = line.Index();
line.v1 = &vertexes[LittleLong(verts[i*2])]; line.v1 = &level.vertexes[LittleLong(verts[i*2])];
line.v2 = &vertexes[LittleLong(verts[i*2+1])]; line.v2 = &level.vertexes[LittleLong(verts[i*2+1])];
} }
delete [] verts; delete [] verts;

View file

@ -358,6 +358,7 @@ FSerializer &Serialize(FSerializer &arc, const char *key, subsector_t *&ss, subs
str = &encoded[0]; str = &encoded[0];
if (arc.BeginArray(key)) if (arc.BeginArray(key))
{ {
auto numvertexes = level.vertexes.Size();
arc(nullptr, numvertexes) arc(nullptr, numvertexes)
(nullptr, numsubsectors) (nullptr, numsubsectors)
.StringPtr(nullptr, str) .StringPtr(nullptr, str)
@ -376,7 +377,7 @@ FSerializer &Serialize(FSerializer &arc, const char *key, subsector_t *&ss, subs
.StringPtr(nullptr, str) .StringPtr(nullptr, str)
.EndArray(); .EndArray();
if (num_verts == numvertexes && num_subs == numsubsectors && hasglnodes) if (num_verts == level.vertexes.Size() && num_subs == numsubsectors && hasglnodes)
{ {
success = true; success = true;
int sub = 0; int sub = 0;

View file

@ -711,7 +711,7 @@ double sector_t::FindHighestFloorPoint (vertex_t **v) const
{ {
if (v != NULL) if (v != NULL)
{ {
if (Lines.Size() == 0) *v = &vertexes[0]; if (Lines.Size() == 0) *v = &level.vertexes[0];
else *v = Lines[0]->v1; else *v = Lines[0]->v1;
} }
return -floorplane.fD(); return -floorplane.fD();
@ -760,7 +760,7 @@ double sector_t::FindLowestCeilingPoint (vertex_t **v) const
{ {
if (v != NULL) if (v != NULL)
{ {
if (Lines.Size() == 0) *v = &vertexes[0]; if (Lines.Size() == 0) *v = &level.vertexes[0];
else *v = Lines[0]->v1; else *v = Lines[0]->v1;
} }
return ceilingplane.fD(); return ceilingplane.fD();
@ -1966,6 +1966,12 @@ DEFINE_ACTION_FUNCTION(_Sector, NextLowestFloorAt)
ACTION_RETURN_INT(self->Index()); ACTION_RETURN_INT(self->Index());
} }
DEFINE_ACTION_FUNCTION(_Vertex, Index)
{
PARAM_SELF_STRUCT_PROLOGUE(vertex_t);
ACTION_RETURN_INT(self->Index());
}
//=========================================================================== //===========================================================================
// //
// //

View file

@ -122,8 +122,6 @@ inline bool P_LoadBuildMap(BYTE *mapdata, size_t len, FMapThing **things, int *n
// MAP related Lookup tables. // MAP related Lookup tables.
// Store VERTEXES, LINEDEFS, SIDEDEFS, etc. // Store VERTEXES, LINEDEFS, SIDEDEFS, etc.
// //
int numvertexes;
vertex_t* vertexes;
int numvertexdatas; int numvertexdatas;
vertexdata_t* vertexdatas; vertexdata_t* vertexdatas;
@ -833,11 +831,9 @@ void P_FloodZones ()
void P_LoadVertexes (MapData * map) void P_LoadVertexes (MapData * map)
{ {
int i;
// Determine number of vertices: // Determine number of vertices:
// total lump length / vertex record length. // 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; numvertexdatas = 0;
if (numvertexes == 0) if (numvertexes == 0)
@ -846,18 +842,18 @@ void P_LoadVertexes (MapData * map)
} }
// Allocate memory for buffer. // Allocate memory for buffer.
vertexes = new vertex_t[numvertexes]; level.vertexes.Alloc(numvertexes);
vertexdatas = NULL; vertexdatas = NULL;
map->Seek(ML_VERTEXES); map->Seek(ML_VERTEXES);
// Copy and convert vertex coordinates, internal representation as fixed. // 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; (*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; data >> v1 >> v2 >> line >> side;
segs[i].v1 = &vertexes[v1]; segs[i].v1 = &level.vertexes[v1];
segs[i].v2 = &vertexes[v2]; segs[i].v2 = &level.vertexes[v2];
segs[i].linedef = ldef = &level.lines[line]; segs[i].linedef = ldef = &level.lines[line];
segs[i].sidedef = ldef->sidedef[side]; segs[i].sidedef = ldef->sidedef[side];
segs[i].frontsector = ldef->sidedef[side]->sector; segs[i].frontsector = ldef->sidedef[side]->sector;
@ -928,7 +924,7 @@ void P_LoadGLZSegs (FileReaderBase &data, int type)
data >> side; data >> side;
seg = subsectors[i].firstline + j; seg = subsectors[i].firstline + j;
seg->v1 = &vertexes[v1]; seg->v1 = &level.vertexes[v1];
if (j == 0) if (j == 0)
{ {
seg[subsectors[i].numlines - 1].v2 = seg->v1; 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 // Read extra vertices added during node building
DWORD orgVerts, newVerts; DWORD orgVerts, newVerts;
vertex_t *newvertarray; TStaticArray<vertex_t> newvertarray;
unsigned int i; unsigned int i;
data >> orgVerts >> newVerts; 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. { // These nodes are based on a map with more vertex data than we have.
// We can't use them. // We can't use them.
throw CRecoverableError("Incorrect number of vertexes in nodes.\n"); 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 else
{ {
newvertarray = new vertex_t[orgVerts + newVerts]; newvertarray.Alloc(orgVerts + newVerts);
memcpy (newvertarray, vertexes, orgVerts * sizeof(vertex_t)); memcpy (&newvertarray[0], &level.vertexes[0], orgVerts * sizeof(vertex_t));
fix = true;
} }
for (i = 0; i < newVerts; ++i) for (i = 0; i < newVerts; ++i)
{ {
@ -999,16 +998,14 @@ void LoadZNodes(FileReaderBase &data, int glnodes)
data >> x >> y; data >> x >> y;
newvertarray[i + orgVerts].set(x, y); newvertarray[i + orgVerts].set(x, y);
} }
if (vertexes != newvertarray) if (fix)
{ {
for (auto &line : level.lines) for (auto &line : level.lines)
{ {
line.v1 = line.v1 - vertexes + newvertarray; line.v1 = line.v1 - &level.vertexes[0] + &newvertarray[0];
line.v2 = line.v2 - vertexes + newvertarray; line.v2 = line.v2 - &level.vertexes[0] + &newvertarray[0];
} }
delete[] vertexes; level.vertexes = std::move(newvertarray);
vertexes = newvertarray;
numvertexes = orgVerts + newVerts;
} }
// Read the subsectors // Read the subsectors
@ -1212,6 +1209,7 @@ void P_LoadSegs (MapData * map)
{ {
int i; int i;
BYTE *data; BYTE *data;
int numvertexes = level.vertexes.Size();
BYTE *vertchanged = new BYTE[numvertexes]; // phares 10/4/98 BYTE *vertchanged = new BYTE[numvertexes]; // phares 10/4/98
DWORD segangle; DWORD segangle;
//int ptp_angle; // phares 10/4/98 //int ptp_angle; // phares 10/4/98
@ -1250,7 +1248,7 @@ void P_LoadSegs (MapData * map)
for (auto &line : level.lines) for (auto &line : level.lines)
{ {
vertchanged[line.v1 - vertexes] = vertchanged[line.v2 - vertexes] = 1; vertchanged[line.v1->Index()] = vertchanged[line.v2->Index()] = 1;
} }
try try
@ -1271,8 +1269,8 @@ void P_LoadSegs (MapData * map)
throw badseg(0, i, MAX(vnum1, vnum2)); throw badseg(0, i, MAX(vnum1, vnum2));
} }
li->v1 = &vertexes[vnum1]; li->v1 = &level.vertexes[vnum1];
li->v2 = &vertexes[vnum2]; li->v2 = &level.vertexes[vnum2];
segangle = (WORD)LittleShort(ml->angle); segangle = (WORD)LittleShort(ml->angle);
@ -2111,17 +2109,16 @@ void P_LoadLineDefs (MapData * map)
for (skipped = sidecount = i = 0; i < numlines; ) for (skipped = sidecount = i = 0; i < numlines; )
{ {
mld = ((maplinedef_t*)mldf) + i; mld = ((maplinedef_t*)mldf) + i;
int v1 = LittleShort(mld->v1); unsigned v1 = LittleShort(mld->v1);
int v2 = LittleShort(mld->v2); unsigned v2 = LittleShort(mld->v2);
if (v1 >= numvertexes || v2 >= numvertexes) if (v1 >= level.vertexes.Size() || v2 >= level.vertexes.Size())
{ {
delete [] mldf; 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 || else if (v1 == v2 ||
(vertexes[LittleShort(mld->v1)].fX() == vertexes[LittleShort(mld->v2)].fX() && (level.vertexes[v1].fX() == level.vertexes[v2].fX() && level.vertexes[v1].fY() == level.vertexes[v2].fY()))
vertexes[LittleShort(mld->v1)].fY() == vertexes[LittleShort(mld->v2)].fY()))
{ {
Printf ("Removing 0-length line %d\n", i+skipped); Printf ("Removing 0-length line %d\n", i+skipped);
memmove (mld, mld+1, sizeof(*mld)*(numlines-i-1)); memmove (mld, mld+1, sizeof(*mld)*(numlines-i-1));
@ -2172,8 +2169,8 @@ void P_LoadLineDefs (MapData * map)
} }
#endif #endif
ld->v1 = &vertexes[LittleShort(mld->v1)]; ld->v1 = &level.vertexes[LittleShort(mld->v1)];
ld->v2 = &vertexes[LittleShort(mld->v2)]; ld->v2 = &level.vertexes[LittleShort(mld->v2)];
P_SetSideNum (&ld->sidedef[0], LittleShort(mld->sidenum[0])); P_SetSideNum (&ld->sidedef[0], LittleShort(mld->sidenum[0]));
P_SetSideNum (&ld->sidedef[1], LittleShort(mld->sidenum[1])); P_SetSideNum (&ld->sidedef[1], LittleShort(mld->sidenum[1]));
@ -2210,8 +2207,8 @@ void P_LoadLineDefs2 (MapData * map)
mld = ((maplinedef2_t*)mldf) + i; mld = ((maplinedef2_t*)mldf) + i;
if (mld->v1 == mld->v2 || if (mld->v1 == mld->v2 ||
(vertexes[LittleShort(mld->v1)].fX() == vertexes[LittleShort(mld->v2)].fX() && (level.vertexes[LittleShort(mld->v1)].fX() == level.vertexes[LittleShort(mld->v2)].fX() &&
vertexes[LittleShort(mld->v1)].fY() == vertexes[LittleShort(mld->v2)].fY())) level.vertexes[LittleShort(mld->v1)].fY() == level.vertexes[LittleShort(mld->v2)].fY()))
{ {
Printf ("Removing 0-length line %d\n", i+skipped); Printf ("Removing 0-length line %d\n", i+skipped);
memmove (mld, mld+1, sizeof(*mld)*(numlines-i-1)); memmove (mld, mld+1, sizeof(*mld)*(numlines-i-1));
@ -2256,8 +2253,8 @@ void P_LoadLineDefs2 (MapData * map)
ld->flags = LittleShort(mld->flags); ld->flags = LittleShort(mld->flags);
ld->special = mld->special; ld->special = mld->special;
ld->v1 = &vertexes[LittleShort(mld->v1)]; ld->v1 = &level.vertexes[LittleShort(mld->v1)];
ld->v2 = &vertexes[LittleShort(mld->v2)]; ld->v2 = &level.vertexes[LittleShort(mld->v2)];
ld->alpha = 1.; // [RH] Opaque by default ld->alpha = 1.; // [RH] Opaque by default
P_SetSideNum (&ld->sidedef[0], LittleShort(mld->sidenum[0])); 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); level.sides.Alloc(count);
memset(&level.sides[0], 0, count * sizeof(side_t)); memset(&level.sides[0], 0, count * sizeof(side_t));
sidetemp = new sidei_t[MAX(count,numvertexes)]; sidetemp = new sidei_t[MAX<int>(count, level.vertexes.Size())];
for (i = 0; i < count; i++) for (i = 0; i < count; i++)
{ {
sidetemp[i].a.special = sidetemp[i].a.tag = 0; sidetemp[i].a.special = sidetemp[i].a.tag = 0;
@ -2326,9 +2323,9 @@ static void P_LoopSidedefs (bool firstloop)
delete[] sidetemp; delete[] sidetemp;
} }
int numsides = level.sides.Size(); int numsides = level.sides.Size();
sidetemp = new sidei_t[MAX(numvertexes, numsides)]; sidetemp = new sidei_t[MAX<int>(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.first = NO_SIDE;
sidetemp[i].b.next = NO_SIDE; sidetemp[i].b.next = NO_SIDE;
@ -2344,7 +2341,7 @@ static void P_LoopSidedefs (bool firstloop)
// as their left edge. // as their left edge.
line_t *line = level.sides[i].linedef; line_t *line = level.sides[i].linedef;
int lineside = (line->sidedef[0] != &level.sides[i]); 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.lineside = lineside;
sidetemp[i].b.next = sidetemp[vert].b.first; sidetemp[i].b.next = sidetemp[vert].b.first;
@ -2383,11 +2380,11 @@ static void P_LoopSidedefs (bool firstloop)
{ {
if (sidetemp[i].b.lineside) if (sidetemp[i].b.lineside)
{ {
right = int(line->v1 - vertexes); right = line->v1->Index();
} }
else else
{ {
right = int(line->v2 - vertexes); right = line->v2->Index();
} }
right = sidetemp[right].b.first; right = sidetemp[right].b.first;
@ -2764,22 +2761,21 @@ static void P_CreateBlockMap ()
int bmapwidth, bmapheight; int bmapwidth, bmapheight;
double dminx, dmaxx, dminy, dmaxy; double dminx, dmaxx, dminy, dmaxy;
int minx, maxx, miny, maxy; int minx, maxx, miny, maxy;
int i;
int line; int line;
if (numvertexes <= 0) if (level.vertexes.Size() == 0)
return; return;
// Find map extents for the blockmap // Find map extents for the blockmap
dminx = dmaxx = vertexes[0].fX(); dminx = dmaxx = level.vertexes[0].fX();
dminy = dmaxy = vertexes[0].fY(); 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(); if (vert.fX() < dminx) dminx = vert.fX();
else if (vertexes[i].fX() > dmaxx) dmaxx = vertexes[i].fX(); else if (vert.fX() > dmaxx) dmaxx = vert.fX();
if (vertexes[i].fY() < dminy) dminy = vertexes[i].fY(); if (vert.fY() < dminy) dminy = vert.fY();
else if (vertexes[i].fY() > dmaxy) dmaxy = vertexes[i].fY(); else if (vert.fY() > dmaxy) dmaxy = vert.fY();
} }
minx = int(dminx); minx = int(dminx);
@ -3435,12 +3431,6 @@ void P_FreeLevelData ()
wminfo.maxfrags = 0; wminfo.maxfrags = 0;
FBehavior::StaticUnloadModules (); FBehavior::StaticUnloadModules ();
if (vertexes != NULL)
{
delete[] vertexes;
vertexes = NULL;
}
numvertexes = 0;
if (segs != NULL) if (segs != NULL)
{ {
delete[] segs; delete[] segs;
@ -3459,6 +3449,7 @@ void P_FreeLevelData ()
level.sectors.Clear(); level.sectors.Clear();
level.lines.Clear(); level.lines.Clear();
level.sides.Clear(); level.sides.Clear();
level.vertexes.Clear();
if (gamenodes != NULL && gamenodes != nodes) if (gamenodes != NULL && gamenodes != nodes)
{ {
@ -3906,7 +3897,7 @@ void P_SetupLevel (const char *lumpname, int position)
P_GetPolySpots (map, polyspots, anchors); P_GetPolySpots (map, polyspots, anchors);
FNodeBuilder::FLevel leveldata = FNodeBuilder::FLevel leveldata =
{ {
vertexes, numvertexes, &level.vertexes[0], (int)level.vertexes.Size(),
&level.sides[0], (int)level.sides.Size(), &level.sides[0], (int)level.sides.Size(),
&level.lines[0], (int)level.lines.Size(), &level.lines[0], (int)level.lines.Size(),
0, 0, 0, 0 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 // In case a sync critical game mode is started, also build GL nodes to avoid problems
// if the different machines' am_textured setting differs. // if the different machines' am_textured setting differs.
FNodeBuilder builder (leveldata, polyspots, anchors, BuildGLNodes); FNodeBuilder builder (leveldata, polyspots, anchors, BuildGLNodes);
delete[] vertexes;
builder.Extract (nodes, numnodes, builder.Extract (nodes, numnodes,
segs, glsegextras, numsegs, segs, glsegextras, numsegs,
subsectors, numsubsectors, subsectors, numsubsectors,
vertexes, numvertexes); level.vertexes);
endTime = I_FPSTime (); endTime = I_FPSTime ();
DPrintf (DMSG_NOTIFY, "BSP generation took %.3f sec (%d segs)\n", (endTime - startTime) * 0.001, numsegs); DPrintf (DMSG_NOTIFY, "BSP generation took %.3f sec (%d segs)\n", (endTime - startTime) * 0.001, numsegs);
oldvertextable = builder.GetOldVertexTable(); oldvertextable = builder.GetOldVertexTable();

View file

@ -258,9 +258,9 @@ static void P_SetSlopesFromVertexHeights(FMapThing *firstmt, FMapThing *lastmt,
{ {
if (mt->info->Special == SMT_VertexFloorZ || mt->info->Special == SMT_VertexCeilingZ) 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) if (mt->info->Special == SMT_VertexFloorZ)
{ {
@ -310,14 +310,14 @@ static void P_SetSlopesFromVertexHeights(FMapThing *firstmt, FMapThing *lastmt,
DVector3 vec1, vec2; DVector3 vec1, vec2;
int vi1, vi2, vi3; int vi1, vi2, vi3;
vi1 = int(sec.Lines[0]->v1 - vertexes); vi1 = sec.Lines[0]->v1->Index();
vi2 = int(sec.Lines[0]->v2 - vertexes); vi2 = sec.Lines[0]->v2->Index();
vi3 = (sec.Lines[1]->v1 == sec.Lines[0]->v1 || sec.Lines[1]->v1 == sec.Lines[0]->v2)? 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); vt1 = DVector3(level.vertexes[vi1].fPos(), 0);
vt2 = DVector3(vertexes[vi2].fPos(), 0); vt2 = DVector3(level.vertexes[vi2].fPos(), 0);
vt3 = DVector3(vertexes[vi3].fPos(), 0); vt3 = DVector3(level.vertexes[vi3].fPos(), 0);
for(int j=0; j<2; j++) 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); 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); 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; vec1 = vt2 - vt3;
vec2 = vt1 - 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; 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); plane->set(cross[0], cross[1], cross[2], dist);
} }
} }

View file

@ -1790,12 +1790,12 @@ public:
intptr_t v1i = intptr_t(ParsedLines[i].v1); intptr_t v1i = intptr_t(ParsedLines[i].v1);
intptr_t v2i = intptr_t(ParsedLines[i].v2); 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 || 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); Printf ("Removing 0-length line %d\n", i+skipped);
ParsedLines.Delete(i); ParsedLines.Delete(i);
@ -1804,8 +1804,8 @@ public:
} }
else else
{ {
ParsedLines[i].v1 = &vertexes[v1i]; ParsedLines[i].v1 = &level.vertexes[v1i];
ParsedLines[i].v2 = &vertexes[v2i]; ParsedLines[i].v2 = &level.vertexes[v2i];
if (ParsedLines[i].sidedef[0] != NULL) if (ParsedLines[i].sidedef[0] != NULL)
sidecount++; sidecount++;
@ -2011,9 +2011,8 @@ public:
if (ParsedSides.Size() == 0) I_Error("Map has no sidedefs.\n"); if (ParsedSides.Size() == 0) I_Error("Map has no sidedefs.\n");
// Create the real vertices // Create the real vertices
numvertexes = ParsedVertices.Size(); level.vertexes.Alloc(ParsedVertices.Size());
vertexes = new vertex_t[numvertexes]; memcpy(&level.vertexes[0], &ParsedVertices[0], level.vertexes.Size() * sizeof(vertex_t));
memcpy(vertexes, &ParsedVertices[0], numvertexes * sizeof(*vertexes));
// Create the real vertex datas // Create the real vertex datas
numvertexdatas = ParsedVertexDatas.Size(); numvertexdatas = ParsedVertexDatas.Size();

View file

@ -1479,7 +1479,7 @@ static void IterFindPolySides (FPolyObj *po, side_t *side)
assert(sidetemp != NULL); assert(sidetemp != NULL);
vnum.Clear(); vnum.Clear();
vnum.Push(DWORD(side->V1() - vertexes)); vnum.Push(DWORD(side->V1()->Index()));
vnumat = 0; vnumat = 0;
while (vnum.Size() != vnumat) while (vnum.Size() != vnumat)
@ -1488,7 +1488,7 @@ static void IterFindPolySides (FPolyObj *po, side_t *side)
while (sidenum != NO_SIDE) while (sidenum != NO_SIDE)
{ {
po->Sidedefs.Push(&level.sides[sidenum]); 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; sidenum = sidetemp[sidenum].b.next;
} }
} }

View file

@ -131,11 +131,13 @@ struct vertex_t
return FLOAT2FIXED(p.Y); return FLOAT2FIXED(p.Y);
} }
DVector2 fPos() DVector2 fPos() const
{ {
return p; return p;
} }
int Index() const;
angle_t viewangle; // precalculated angle for clipping angle_t viewangle; // precalculated angle for clipping
int angletime; // recalculation time for view angle int angletime; // recalculation time for view angle
bool dirty; // something has changed and needs to be recalculated bool dirty; // something has changed and needs to be recalculated

View file

@ -42,8 +42,6 @@ extern "C" int viewheight;
extern TArray<spritedef_t> sprites; extern TArray<spritedef_t> sprites;
extern DWORD NumStdSprites; extern DWORD NumStdSprites;
extern int numvertexes;
extern vertex_t* vertexes;
extern int numvertexdatas; extern int numvertexdatas;
extern vertexdata_t* vertexdatas; extern vertexdata_t* vertexdatas;

View file

@ -730,6 +730,10 @@ void InitThingdef()
sidestruct->Size = sizeof(side_t); sidestruct->Size = sizeof(side_t);
sidestruct->Align = alignof(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... // 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. // 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("sectors", NewPointer(NewResizableArray(sectorstruct), false), myoffsetof(FLevelLocals, sectors), VARF_Native);
lstruct->AddNativeField("lines", NewPointer(NewResizableArray(linestruct), false), myoffsetof(FLevelLocals, lines), 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("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 // set up a variable for the DEH data
PStruct *dstruct = NewNativeStruct("DehInfo", nullptr); PStruct *dstruct = NewNativeStruct("DehInfo", nullptr);

View file

@ -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) 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]);
} }
//========================================================================== //==========================================================================

View file

@ -553,6 +553,13 @@ public:
this->Count = 0; this->Count = 0;
this->Array = NULL; this->Array = NULL;
} }
TStaticArray(TStaticArray<T> &&other)
{
this->Array = other.Array;
this->Count = other.Count;
other.Array = nullptr;
other.Count = 0;
}
// This is not supposed to be copyable. // This is not supposed to be copyable.
TStaticArray(const TStaticArray<T> &other) = delete; TStaticArray(const TStaticArray<T> &other) = delete;
@ -564,7 +571,7 @@ public:
{ {
if (this->Array) delete[] this->Array; if (this->Array) delete[] this->Array;
this->Count = 0; this->Count = 0;
this->Array = NULL; this->Array = nullptr;
} }
void Alloc(unsigned int amount) void Alloc(unsigned int amount)
{ {
@ -579,6 +586,15 @@ public:
memcpy(this->Array, other.Array, this->Count * sizeof(T)); memcpy(this->Array, other.Array, this->Count * sizeof(T));
return *this; 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;
}
}; };