- 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;
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;

View File

@ -27,6 +27,7 @@ struct FLevelLocals
FString NextSecretMap; // map to go to when used secret exit
EMapType maptype;
TStaticArray<vertex_t> vertexes;
TStaticArray<sector_t> sectors;
TStaticArray<line_t> lines;
TStaticArray<side_t> 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]);

View File

@ -403,7 +403,7 @@ static void InitVertexData()
int i,j,k;
vt_sectorlists = new TArray<int>[numvertexes];
vt_sectorlists = new TArray<int>[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;i<numvertexes;i++)
for(i=0;i<level.vertexes.Size();i++)
{
auto vert = level.vertexes[i];
int cnt = vt_sectorlists[i].Size();
vertexes[i].dirty = true;
vertexes[i].numheights=0;
vert.dirty = true;
vert.numheights=0;
if (cnt>1)
{
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;j<cnt;j++)
{
vertexes[i].sectors[j] = &level.sectors[vt_sectorlists[i][j]];
vert.sectors[j] = &level.sectors[vt_sectorlists[i][j]];
}
}
else
{
vertexes[i].numsectors=0;
vert.numsectors=0;
}
}
@ -493,9 +494,9 @@ static void PrepareSegs()
int realsegs = 0;
// 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
@ -586,8 +587,8 @@ void gl_PreprocessLevel()
PrepareSegs();
PrepareSectorData();
InitVertexData();
int *checkmap = new int[numvertexes];
memset(checkmap, -1, sizeof(int)*numvertexes);
int *checkmap = new int[level.vertexes.Size()];
memset(checkmap, -1, sizeof(int)*level.vertexes.Size());
for(auto &sec : level.sectors)
{
int i = sec.sectornum;
@ -598,21 +599,21 @@ void gl_PreprocessLevel()
{
if (l->sidedef[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;
}
}

View File

@ -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<vertex_t> &vertexes);
const int *GetOldVertexTable();
// These are used for building sub-BSP trees for polyobjects.

View File

@ -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<vertex_t> &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];
}
}

View File

@ -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<vertex_t> 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;i<numvertexes;i++)
WriteLong(ZNodes, level.vertexes.Size());
for(auto &vert : level.vertexes)
{
WriteLong(ZNodes, vertexes[i].fixX());
WriteLong(ZNodes, vertexes[i].fixY());
WriteLong(ZNodes, vert.fixX());
WriteLong(ZNodes, vert.fixY());
}
WriteLong(ZNodes, numsubsectors);
@ -1111,7 +1111,7 @@ static void CreateCachedNodes(MapData *map)
WriteLong(ZNodes, numsegs);
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));
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;

View File

@ -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;

View File

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

View File

@ -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<vertex_t> 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<int>(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<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.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();

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)
{
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);
}
}

View File

@ -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();

View File

@ -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;
}
}

View File

@ -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

View File

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

View File

@ -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);

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)
{
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->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.
TStaticArray(const TStaticArray<T> &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;
}
};