- moved the subsectors into FLevelLocals.

This commit is contained in:
Christoph Oelckers 2017-03-17 00:22:52 +01:00
parent 59b684bdbc
commit f201dab534
28 changed files with 280 additions and 295 deletions

View file

@ -2020,7 +2020,8 @@ void AM_drawSubsectors()
PalEntry flatcolor;
mpoint_t originpt;
for (int i = 0; i < numsubsectors; ++i)
auto &subsectors = level.subsectors;
for (unsigned i = 0; i < subsectors.Size(); ++i)
{
if (subsectors[i].flags & SSECF_POLYORG)
{
@ -2247,14 +2248,14 @@ void AM_drawPolySeg(FPolySeg *seg, const AMColor &color)
void AM_showSS()
{
if (am_showsubsector >= 0 && am_showsubsector < numsubsectors)
if (am_showsubsector >= 0 && (unsigned)am_showsubsector < level.subsectors.Size())
{
AMColor yellow;
yellow.FromRGB(255,255,0);
AMColor red;
red.FromRGB(255,0,0);
subsector_t *sub = &subsectors[am_showsubsector];
subsector_t *sub = &level.subsectors[am_showsubsector];
for (unsigned int i = 0; i < sub->numlines; i++)
{
AM_drawSeg(sub->firstline + i, yellow);

View file

@ -34,6 +34,8 @@ struct FLevelLocals
TStaticArray<line_t> lines;
TStaticArray<side_t> sides;
TStaticArray<seg_t> segs;
TStaticPointableArray<subsector_t> subsectors;
TStaticPointableArray<subsector_t> gamesubsectors;
TArray<FSectorPortal> sectorPortals;
@ -115,6 +117,11 @@ inline int seg_t::Index() const
return int(this - &level.segs[0]);
}
inline int subsector_t::Index() const
{
return int(this - &level.subsectors[0]);
}
inline FSectorPortal *line_t::GetTransferredPortal()
{
return portaltransferred >= level.sectorPortals.Size() ? (FSectorPortal*)nullptr : &level.sectorPortals[portaltransferred];

View file

@ -829,19 +829,18 @@ CCMD(listlights)
CCMD(listsublights)
{
for(int i=0;i<numsubsectors;i++)
for(auto &sub : level.subsectors)
{
subsector_t *sub = &subsectors[i];
int lights = 0;
FLightNode * node = sub->lighthead;
FLightNode * node = sub.lighthead;
while (node != NULL)
{
lights++;
node = node->nextLight;
}
Printf(PRINT_LOG, "Subsector %d - %d lights\n", i, lights);
Printf(PRINT_LOG, "Subsector %d - %d lights\n", sub.Index(), lights);
}
}

View file

@ -680,7 +680,7 @@ void GLFlat::DrawLightsCompat(int pass)
for (int i = 0; i<sector->subsectorcount; i++)
{
subsector_t * sub = sector->subsectors[i];
if (gl_drawinfo->ss_renderflags[sub - subsectors] & renderflags)
if (gl_drawinfo->ss_renderflags[sub->Index()] & renderflags)
{
DrawSubsectorLights(sub, pass);
}

View file

@ -381,7 +381,7 @@ CCMD(dumpgeometry)
{
subsector_t * sub = sector.subsectors[j];
Printf(PRINT_LOG, " Subsector %d - real sector = %d - %s\n", int(sub-subsectors), sub->sector->sectornum, sub->hacked&1? "hacked":"");
Printf(PRINT_LOG, " Subsector %d - real sector = %d - %s\n", int(sub->Index()), sub->sector->sectornum, sub->hacked&1? "hacked":"");
for(uint32_t k=0;k<sub->numlines;k++)
{
seg_t * seg = sub->firstline + k;

View file

@ -297,7 +297,7 @@ struct FCoverageBuilder
{
// we reached a subsector so we can link the node with this subsector
subsector_t *sub = (subsector_t *)((uint8_t *)node - 1);
collect.Push(int(sub-subsectors));
collect.Push(int(sub->Index()));
}
}
};
@ -493,22 +493,21 @@ CCMD(dumpportals)
Printf(PRINT_LOG, "Portal #%d, %s, displacement = (%f,%f)\n", i, glSectorPortals[i]->plane==0? "floor":"ceiling",
xdisp, ydisp);
Printf(PRINT_LOG, "Coverage:\n");
for(int j=0;j<numsubsectors;j++)
for(auto &sub : level.subsectors)
{
subsector_t *sub = &subsectors[j];
FPortal *port = sub->render_sector->GetGLPortal(glSectorPortals[i]->plane);
FPortal *port = sub.render_sector->GetGLPortal(glSectorPortals[i]->plane);
if (port == glSectorPortals[i])
{
Printf(PRINT_LOG, "\tSubsector %d (%d):\n\t\t", j, sub->render_sector->sectornum);
for(unsigned k = 0;k< sub->numlines; k++)
Printf(PRINT_LOG, "\tSubsector %d (%d):\n\t\t", sub.Index(), sub.render_sector->sectornum);
for(unsigned k = 0;k< sub.numlines; k++)
{
Printf(PRINT_LOG, "(%.3f,%.3f), ", sub->firstline[k].v1->fX() + xdisp, sub->firstline[k].v1->fY() + ydisp);
Printf(PRINT_LOG, "(%.3f,%.3f), ", sub.firstline[k].v1->fX() + xdisp, sub.firstline[k].v1->fY() + ydisp);
}
Printf(PRINT_LOG, "\n\t\tCovered by subsectors:\n");
FPortalCoverage *cov = &sub->portalcoverage[glSectorPortals[i]->plane];
FPortalCoverage *cov = &sub.portalcoverage[glSectorPortals[i]->plane];
for(int l = 0;l< cov->sscount; l++)
{
subsector_t *csub = &subsectors[cov->subsectors[l]];
subsector_t *csub = &level.subsectors[cov->subsectors[l]];
Printf(PRINT_LOG, "\t\t\t%5d (%4d): ", cov->subsectors[l], csub->render_sector->sectornum);
for(unsigned m = 0;m< csub->numlines; m++)
{

View file

@ -148,9 +148,9 @@ static int MergeMapSections(int num)
if (vsection != section)
{
// These 2 sections should be merged
for (int k = 0; k < numsubsectors; k++)
for (auto &sub : level.subsectors)
{
if (subsectors[k].mapsection == vsection) subsectors[k].mapsection = section;
if (sub.mapsection == vsection) sub.mapsection = section;
}
FSectionVertexMap::Iterator it(vmap);
while (it.NextPair(pair))
@ -165,10 +165,10 @@ static int MergeMapSections(int num)
{
if (sectvalid[i]) sectmap[i] = mergecount++;
}
for (int i = 0; i < numsubsectors; i++)
for (auto &sub : level.subsectors)
{
subsectors[i].mapsection = sectmap[subsectors[i].mapsection - 1];
assert(subsectors[i].mapsection != -1);
sub.mapsection = sectmap[sub.mapsection - 1];
assert(sub.mapsection != -1);
}
return mergecount - 1;
}
@ -186,12 +186,12 @@ static void SetMapSections()
do
{
set = false;
for(int i=0; i<numsubsectors; i++)
for (auto &sub : level.subsectors)
{
if (subsectors[i].mapsection == 0)
if (sub.mapsection == 0)
{
num++;
DoSetMapSection(&subsectors[i], num);
DoSetMapSection(&sub, num);
set = true;
break;
}
@ -244,16 +244,14 @@ static void SpreadHackedFlag(subsector_t * sub)
static void PrepareSectorData()
{
int i;
TArray<subsector_t *> undetermined;
subsector_t * ss;
// now group the subsectors by sector
subsector_t ** subsectorbuffer = new subsector_t * [numsubsectors];
subsector_t ** subsectorbuffer = new subsector_t * [level.subsectors.Size()];
for(i=0, ss=subsectors; i<numsubsectors; i++, ss++)
for (auto &sub : level.subsectors)
{
ss->render_sector->subsectorcount++;
sub.render_sector->subsectorcount++;
}
for (auto &sec : level.sectors)
@ -263,28 +261,28 @@ static void PrepareSectorData()
sec.subsectorcount = 0;
}
for(i=0, ss = subsectors; i<numsubsectors; i++, ss++)
for (auto &sub : level.subsectors)
{
ss->render_sector->subsectors[ss->render_sector->subsectorcount++]=ss;
sub.render_sector->subsectors[sub.render_sector->subsectorcount++] = &sub;
}
// marks all malformed subsectors so rendering tricks using them can be handled more easily
for (i = 0; i < numsubsectors; i++)
for (auto &sub : level.subsectors)
{
if (subsectors[i].sector == subsectors[i].render_sector)
if (sub.sector == sub.render_sector)
{
seg_t * seg = subsectors[i].firstline;
for(uint32_t j=0;j<subsectors[i].numlines;j++)
seg_t * seg = sub.firstline;
for(uint32_t j=0;j<sub.numlines;j++)
{
if (!(subsectors[i].hacked&1) && seg[j].linedef==0 &&
if (!(sub.hacked&1) && seg[j].linedef==0 &&
seg[j].PartnerSeg!=NULL &&
subsectors[i].render_sector != seg[j].PartnerSeg->Subsector->render_sector)
sub.render_sector != seg[j].PartnerSeg->Subsector->render_sector)
{
DPrintf(DMSG_NOTIFY, "Found hack: (%f,%f) (%f,%f)\n", seg[j].v1->fX(), seg[j].v1->fY(), seg[j].v2->fX(), seg[j].v2->fY());
subsectors[i].hacked|=5;
SpreadHackedFlag(&subsectors[i]);
sub.hacked|=5;
SpreadHackedFlag(&sub);
}
if (seg[j].PartnerSeg==NULL) subsectors[i].hacked|=2; // used for quick termination checks
if (seg[j].PartnerSeg==NULL) sub.hacked|=2; // used for quick termination checks
}
}
}
@ -616,14 +614,14 @@ void gl_CleanLevelData()
delete [] level.sectors[0].subsectors;
level.sectors[0].subsectors = nullptr;
}
for (int i=0;i<numsubsectors;i++)
for (auto &sub : level.subsectors)
{
for(int j=0;j<2;j++)
{
if (subsectors[i].portalcoverage[j].subsectors != NULL)
if (sub.portalcoverage[j].subsectors != NULL)
{
delete [] subsectors[i].portalcoverage[j].subsectors;
subsectors[i].portalcoverage[j].subsectors = NULL;
delete [] sub.portalcoverage[j].subsectors;
sub.portalcoverage[j].subsectors = NULL;
}
}
}
@ -643,13 +641,13 @@ void gl_CleanLevelData()
CCMD(listmapsections)
{
for(int i=0;i<100;i++)
for (int i = 0; i < 100; i++)
{
for (int j=0;j<numsubsectors;j++)
for (auto &sub : level.subsectors)
{
if (subsectors[j].mapsection == i)
if (sub.mapsection == i)
{
Printf("Mapsection %d, sector %d, line %d\n", i, subsectors[j].render_sector->Index(), subsectors[j].firstline->linedef->Index());
Printf("Mapsection %d, sector %d, line %d\n", i, sub.render_sector->Index(), sub.firstline->linedef->Index());
break;
}
}

View file

@ -426,7 +426,7 @@ void GLSceneDrawer::DoSubsector(subsector_t * sub)
if (!(currentmapsection[sub->mapsection>>3] & (1 << (sub->mapsection & 7)))) return;
if (sub->flags & SSECF_POLYORG) return; // never render polyobject origin subsectors because their vertices no longer are where one may expect.
if (gl_drawinfo->ss_renderflags[sub-subsectors] & SSRF_SEEN)
if (gl_drawinfo->ss_renderflags[sub->Index()] & SSRF_SEEN)
{
// This means that we have reached a subsector in a portal that has been marked 'seen'
// from the other side of the portal. This means we must clear the clipper for the
@ -460,7 +460,7 @@ void GLSceneDrawer::DoSubsector(subsector_t * sub)
{
SetupSprite.Clock();
for (i = ParticlesInSubsec[uint32_t(sub-subsectors)]; i != NO_PARTICLE; i = Particles[i].snext)
for (i = ParticlesInSubsec[sub->Index()]; i != NO_PARTICLE; i = Particles[i].snext)
{
GLSprite sprite(this);
sprite.ProcessParticle(&Particles[i], fakesector);
@ -516,7 +516,7 @@ void GLSceneDrawer::DoSubsector(subsector_t * sub)
SetupFlat.Unclock();
}
// mark subsector as processed - but mark for rendering only if it has an actual area.
gl_drawinfo->ss_renderflags[sub-subsectors] =
gl_drawinfo->ss_renderflags[sub->Index()] =
(sub->numlines > 2) ? SSRF_PROCESSED|SSRF_RENDERALL : SSRF_PROCESSED;
if (sub->hacked & 1) gl_drawinfo->AddHackedSubsector(sub);
@ -556,7 +556,7 @@ void GLSceneDrawer::RenderBSPNode (void *node)
{
if (numnodes == 0)
{
DoSubsector (subsectors);
DoSubsector (&level.subsectors[0]);
return;
}
while (!((size_t)node & 1)) // Keep going until found a subsector

View file

@ -1047,11 +1047,11 @@ void FDrawInfo::StartScene()
ClearBuffers();
sectorrenderflags.Resize(level.sectors.Size());
ss_renderflags.Resize(numsubsectors);
no_renderflags.Resize(numsubsectors);
ss_renderflags.Resize(level.subsectors.Size());
no_renderflags.Resize(level.subsectors.Size());
memset(&sectorrenderflags[0], 0, level.sectors.Size() * sizeof(sectorrenderflags[0]));
memset(&ss_renderflags[0], 0, numsubsectors * sizeof(ss_renderflags[0]));
memset(&ss_renderflags[0], 0, level.subsectors.Size() * sizeof(ss_renderflags[0]));
memset(&no_renderflags[0], 0, numnodes * sizeof(no_renderflags[0]));
next = gl_drawinfo;

View file

@ -224,7 +224,7 @@ void GLFlat::ProcessLights(bool istrans)
for (int i=0; i<sector->subsectorcount; i++)
{
subsector_t * sub = sector->subsectors[i];
if (gl_drawinfo->ss_renderflags[sub-subsectors]&renderflags || istrans)
if (gl_drawinfo->ss_renderflags[sub->Index()]&renderflags || istrans)
{
SetupSubsectorLights(GLPASS_LIGHTSONLY, sub);
}
@ -264,7 +264,7 @@ void GLFlat::DrawSubsectors(int pass, bool processlights, bool istrans)
{
subsector_t * sub = sector->subsectors[i];
if (gl_drawinfo->ss_renderflags[sub-subsectors]&renderflags || istrans)
if (gl_drawinfo->ss_renderflags[sub->Index()]&renderflags || istrans)
{
if (processlights) SetupSubsectorLights(GLPASS_ALL, sub, &dli);
drawcalls.Clock();
@ -283,7 +283,7 @@ void GLFlat::DrawSubsectors(int pass, bool processlights, bool istrans)
for (int i=0; i<sector->subsectorcount; i++)
{
subsector_t * sub = sector->subsectors[i];
if (gl_drawinfo->ss_renderflags[sub-subsectors]&renderflags || istrans)
if (gl_drawinfo->ss_renderflags[sub->Index()]&renderflags || istrans)
{
if (processlights) SetupSubsectorLights(GLPASS_ALL, sub, &dli);
DrawSubsector(sub);

View file

@ -706,7 +706,7 @@ static uint8_t SetCoverage(void *node)
else
{
subsector_t *sub = (subsector_t *)((uint8_t *)node - 1);
return gl_drawinfo->ss_renderflags[sub-subsectors] & SSRF_SEEN;
return gl_drawinfo->ss_renderflags[sub->Index()] & SSRF_SEEN;
}
}
@ -718,9 +718,9 @@ void GLSectorStackPortal::SetupCoverage()
int plane = origin->plane;
for(int j=0;j<sub->portalcoverage[plane].sscount; j++)
{
subsector_t *dsub = &::subsectors[sub->portalcoverage[plane].subsectors[j]];
subsector_t *dsub = &::level.subsectors[sub->portalcoverage[plane].subsectors[j]];
currentmapsection[dsub->mapsection>>3] |= 1 << (dsub->mapsection&7);
gl_drawinfo->ss_renderflags[dsub-::subsectors] |= SSRF_SEEN;
gl_drawinfo->ss_renderflags[dsub->Index()] |= SSRF_SEEN;
}
}
SetCoverage(&nodes[numnodes-1]);
@ -750,7 +750,7 @@ void GLSectorStackPortal::DrawContents()
// If the viewpoint is not within the portal, we need to invalidate the entire clip area.
// The portal will re-validate the necessary parts when its subsectors get traversed.
subsector_t *sub = R_PointInSubsector(r_viewpoint.Pos);
if (!(gl_drawinfo->ss_renderflags[sub - ::subsectors] & SSRF_SEEN))
if (!(gl_drawinfo->ss_renderflags[sub->Index()] & SSRF_SEEN))
{
drawer->clipper.SafeAddClipRange(0, ANGLE_MAX);
drawer->clipper.SetBlocked(true);

View file

@ -782,7 +782,7 @@ bool FDrawInfo::CollectSubsectorsFloor(subsector_t * sub, sector_t * anchor)
if (!(sub->flags & SSECF_DEGENERATE))
{
// Is not being rendered so don't bother.
if (!(ss_renderflags[uint32_t(sub - subsectors)] & SSRF_PROCESSED)) return true;
if (!(ss_renderflags[sub->Index()] & SSRF_PROCESSED)) return true;
if (sub->render_sector->GetTexture(sector_t::floor) != anchor->GetTexture(sector_t::floor) ||
sub->render_sector->GetPlaneTexZ(sector_t::floor) != anchor->GetPlaneTexZ(sector_t::floor) ||
@ -884,7 +884,7 @@ bool FDrawInfo::CollectSubsectorsCeiling(subsector_t * sub, sector_t * anchor)
if (!(sub->flags & SSECF_DEGENERATE))
{
// Is not being rendererd so don't bother.
if (!(ss_renderflags[uint32_t(sub-subsectors)]&SSRF_PROCESSED)) return true;
if (!(ss_renderflags[sub->Index()]&SSRF_PROCESSED)) return true;
if (sub->render_sector->GetTexture(sector_t::ceiling) != anchor->GetTexture(sector_t::ceiling) ||
sub->render_sector->GetPlaneTexZ(sector_t::ceiling) != anchor->GetPlaneTexZ(sector_t::ceiling) ||
@ -1040,7 +1040,7 @@ void FDrawInfo::CollectSectorStacksCeiling(subsector_t * sub, sector_t * anchor)
if (sub->render_sector->GetGLPortal(sector_t::ceiling) != nullptr) return;
// Don't bother processing unrendered subsectors
if (sub->numlines>2 && !(ss_renderflags[uint32_t(sub-subsectors)]&SSRF_PROCESSED)) return;
if (sub->numlines>2 && !(ss_renderflags[sub->Index()]&SSRF_PROCESSED)) return;
// Must be the exact same visplane
sector_t * me = gl_FakeFlat(sub->render_sector, &fakesec, mDrawer->in_area, false);
@ -1084,7 +1084,7 @@ void FDrawInfo::CollectSectorStacksFloor(subsector_t * sub, sector_t * anchor)
if (sub->render_sector->GetGLPortal(sector_t::floor) != nullptr) return;
// Don't bother processing unrendered subsectors
if (sub->numlines>2 && !(ss_renderflags[uint32_t(sub-subsectors)]&SSRF_PROCESSED)) return;
if (sub->numlines>2 && !(ss_renderflags[sub->Index()]&SSRF_PROCESSED)) return;
// Must be the exact same visplane
sector_t * me = gl_FakeFlat(sub->render_sector, &fakesec, mDrawer->in_area, false);
@ -1132,7 +1132,7 @@ void FDrawInfo::ProcessSectorStacks()
if (portal != NULL) for(int k=0;k<sec->subsectorcount;k++)
{
subsector_t * sub = sec->subsectors[k];
if (ss_renderflags[sub-subsectors] & SSRF_PROCESSED)
if (ss_renderflags[sub->Index()] & SSRF_PROCESSED)
{
HandledSubsectors.Clear();
for(uint32_t j=0;j<sub->numlines;j++)
@ -1148,7 +1148,7 @@ void FDrawInfo::ProcessSectorStacks()
for(unsigned int j=0;j<HandledSubsectors.Size();j++)
{
subsector_t *sub = HandledSubsectors[j];
ss_renderflags[uint32_t(sub-subsectors)] &= ~SSRF_RENDERCEILING;
ss_renderflags[sub->Index()] &= ~SSRF_RENDERCEILING;
if (sub->portalcoverage[sector_t::ceiling].subsectors == NULL)
{
@ -1176,7 +1176,7 @@ void FDrawInfo::ProcessSectorStacks()
if (portal != NULL) for(int k=0;k<sec->subsectorcount;k++)
{
subsector_t * sub = sec->subsectors[k];
if (ss_renderflags[sub-subsectors] & SSRF_PROCESSED)
if (ss_renderflags[sub->Index()] & SSRF_PROCESSED)
{
HandledSubsectors.Clear();
for(uint32_t j=0;j<sub->numlines;j++)
@ -1193,7 +1193,7 @@ void FDrawInfo::ProcessSectorStacks()
for(unsigned int j=0;j<HandledSubsectors.Size();j++)
{
subsector_t *sub = HandledSubsectors[j];
ss_renderflags[uint32_t(sub-subsectors)] &= ~SSRF_RENDERFLOOR;
ss_renderflags[sub->Index()] &= ~SSRF_RENDERFLOOR;
if (sub->portalcoverage[sector_t::floor].subsectors == NULL)
{

View file

@ -195,7 +195,7 @@ public:
void Extract(node_t *&nodes, int &nodeCount,
TStaticArray<seg_t> &segs,
subsector_t *&ssecs, int &subCount,
TStaticPointableArray<subsector_t> &ssecs,
TStaticArray<vertex_t> &vertexes);
const int *GetOldVertexTable();

View file

@ -54,7 +54,7 @@
void FNodeBuilder::Extract (node_t *&outNodes, int &nodeCount,
TStaticArray<seg_t> &outSegs,
subsector_t *&outSubs, int &subCount,
TStaticPointableArray<subsector_t> &outSubs,
TStaticArray<vertex_t> &outVerts)
{
int i;
@ -67,9 +67,9 @@ void FNodeBuilder::Extract (node_t *&outNodes, int &nodeCount,
outVerts[i].set(Vertices[i].x, Vertices[i].y);
}
subCount = Subsectors.Size();
outSubs = new subsector_t[subCount];
memset(outSubs, 0, subCount * sizeof(subsector_t));
auto subCount = Subsectors.Size();
outSubs.Alloc(subCount);
memset(&outSubs[0], 0, subCount * sizeof(subsector_t));
nodeCount = Nodes.Size ();
outNodes = new node_t[nodeCount];
@ -86,7 +86,7 @@ void FNodeBuilder::Extract (node_t *&outNodes, int &nodeCount,
if (outNodes[i].intchildren[j] & 0x80000000)
{
D(Printf(PRINT_LOG, " subsector %d\n", outNodes[i].intchildren[j] & 0x7FFFFFFF));
outNodes[i].children[j] = (uint8_t *)(outSubs + (outNodes[i].intchildren[j] & 0x7fffffff)) + 1;
outNodes[i].children[j] = (uint8_t *)(&outSubs[(outNodes[i].intchildren[j] & 0x7fffffff)]) + 1;
}
else
{
@ -107,7 +107,7 @@ void FNodeBuilder::Extract (node_t *&outNodes, int &nodeCount,
{
TArray<glseg_t> segs (Segs.Size()*5/4);
for (i = 0; i < subCount; ++i)
for (unsigned i = 0; i < subCount; ++i)
{
uint32_t numsegs = CloseSubsector (segs, i, &outVerts[0]);
outSubs[i].numlines = numsegs;
@ -134,7 +134,7 @@ void FNodeBuilder::Extract (node_t *&outNodes, int &nodeCount,
}
else
{
memcpy (outSubs, &Subsectors[0], subCount*sizeof(subsector_t));
memcpy (&outSubs[0], &Subsectors[0], subCount*sizeof(subsector_t));
auto segCount = Segs.Size ();
outSegs.Alloc(segCount);
for (unsigned i = 0; i < segCount; ++i)
@ -153,7 +153,7 @@ void FNodeBuilder::Extract (node_t *&outNodes, int &nodeCount,
out->PartnerSeg = nullptr;
}
}
for (i = 0; i < subCount; ++i)
for (unsigned i = 0; i < subCount; ++i)
{
outSubs[i].firstline = &outSegs[(size_t)outSubs[i].firstline];
}

View file

@ -194,12 +194,12 @@ void P_ClearParticles ()
void P_FindParticleSubsectors ()
{
if (ParticlesInSubsec.Size() < (size_t)numsubsectors)
if (ParticlesInSubsec.Size() < level.subsectors.Size())
{
ParticlesInSubsec.Reserve (numsubsectors - ParticlesInSubsec.Size());
ParticlesInSubsec.Reserve (level.subsectors.Size() - ParticlesInSubsec.Size());
}
fillshort (&ParticlesInSubsec[0], numsubsectors, NO_PARTICLE);
fillshort (&ParticlesInSubsec[0], level.subsectors.Size(), NO_PARTICLE);
if (!r_particles)
{
@ -209,7 +209,7 @@ void P_FindParticleSubsectors ()
{
// Try to reuse the subsector from the last portal check, if still valid.
if (Particles[i].subsector == NULL) Particles[i].subsector = R_PointInSubsector(Particles[i].Pos);
int ssnum = int(Particles[i].subsector - subsectors);
int ssnum = Particles[i].subsector->Index();
Particles[i].snext = ParticlesInSubsec[ssnum];
ParticlesInSubsec[ssnum] = i;
}

View file

@ -163,13 +163,10 @@ static int CheckForMissingSegs()
bool P_CheckForGLNodes()
{
int i;
for(i=0;i<numsubsectors;i++)
for(auto &sub : level.subsectors)
{
subsector_t * sub = &subsectors[i];
seg_t * firstseg = sub->firstline;
seg_t * lastseg = sub->firstline + sub->numlines - 1;
seg_t * firstseg = sub.firstline;
seg_t * lastseg = sub.firstline + sub.numlines - 1;
if (firstseg->v1 != lastseg->v2)
{
@ -179,7 +176,7 @@ bool P_CheckForGLNodes()
}
else
{
for(uint32_t j=0;j<sub->numlines;j++)
for(uint32_t j=0;j<sub.numlines;j++)
{
if (level.segs[j].linedef==NULL) // miniseg
{
@ -445,7 +442,7 @@ static bool LoadGLSubsectors(FileReader * lump)
char * datab;
int i;
numsubsectors = lump->GetLength();
auto numsubsectors = lump->GetLength();
datab = new char[numsubsectors];
lump->Seek(0, SEEK_SET);
lump->Read(datab, numsubsectors);
@ -460,8 +457,9 @@ static bool LoadGLSubsectors(FileReader * lump)
{
mapsubsector_t * data = (mapsubsector_t*) datab;
numsubsectors /= sizeof(mapsubsector_t);
subsectors = new subsector_t[numsubsectors];
memset(subsectors,0,numsubsectors * sizeof(subsector_t));
level.subsectors.Alloc(numsubsectors);
auto &subsectors = level.subsectors;
memset(&subsectors[0],0,numsubsectors * sizeof(subsector_t));
for (i=0; i<numsubsectors; i++)
{
@ -479,8 +477,9 @@ static bool LoadGLSubsectors(FileReader * lump)
{
gl3_mapsubsector_t * data = (gl3_mapsubsector_t*) (datab+(format5? 0:4));
numsubsectors /= sizeof(gl3_mapsubsector_t);
subsectors = new subsector_t[numsubsectors];
memset(subsectors,0,numsubsectors * sizeof(subsector_t));
level.subsectors.Alloc(numsubsectors);
auto &subsectors = level.subsectors;
memset(&subsectors[0],0,numsubsectors * sizeof(subsector_t));
for (i=0; i<numsubsectors; i++)
{
@ -495,15 +494,15 @@ static bool LoadGLSubsectors(FileReader * lump)
}
}
for (i=0; i<numsubsectors; i++)
for (auto &sub : level.subsectors)
{
for(unsigned j=0;j<subsectors[i].numlines;j++)
for(unsigned j=0;j<sub.numlines;j++)
{
seg_t * seg = subsectors[i].firstline + j;
if (seg->linedef==NULL) seg->frontsector = seg->backsector = subsectors[i].firstline->frontsector;
seg_t * seg = sub.firstline + j;
if (seg->linedef==NULL) seg->frontsector = seg->backsector = sub.firstline->frontsector;
}
seg_t *firstseg = subsectors[i].firstline;
seg_t *lastseg = subsectors[i].firstline + subsectors[i].numlines - 1;
seg_t *firstseg = sub.firstline;
seg_t *lastseg = sub.firstline + sub.numlines - 1;
// The subsector must be closed. If it isn't we can't use these nodes and have to do a rebuild.
if (lastseg->v2 != firstseg->v1)
{
@ -563,12 +562,12 @@ static bool LoadNodes (FileReader * lump)
if (child & NF_SUBSECTOR)
{
child &= ~NF_SUBSECTOR;
if (child >= numsubsectors)
if (child >= level.subsectors.Size())
{
delete [] basemn;
return false;
}
no->children[j] = (uint8_t *)&subsectors[child] + 1;
no->children[j] = (uint8_t *)&level.subsectors[child] + 1;
}
else if (child >= numnodes)
{
@ -623,12 +622,12 @@ static bool LoadNodes (FileReader * lump)
if (child & GL5_NF_SUBSECTOR)
{
child &= ~GL5_NF_SUBSECTOR;
if (child >= numsubsectors)
if ((unsigned)child >= level.subsectors.Size())
{
delete [] basemn;
return false;
}
no->children[j] = (uint8_t *)&subsectors[child] + 1;
no->children[j] = (uint8_t *)&level.subsectors[child] + 1;
}
else if (child >= numnodes)
{
@ -675,8 +674,7 @@ static bool DoLoadGLNodes(FileReader ** lumps)
}
if (!LoadGLSubsectors(lumps[2]))
{
delete [] subsectors;
subsectors = NULL;
level.subsectors.Clear();
level.segs.Clear();
return false;
}
@ -684,8 +682,7 @@ static bool DoLoadGLNodes(FileReader ** lumps)
{
delete [] nodes;
nodes = NULL;
delete [] subsectors;
subsectors = NULL;
level.subsectors.Clear();
level.segs.Clear();
return false;
}
@ -693,16 +690,15 @@ static bool DoLoadGLNodes(FileReader ** lumps)
// Quick check for the validity of the nodes
// For invalid nodes there is a high chance that this test will fail
for (int i = 0; i < numsubsectors; i++)
for (auto &sub : level.subsectors)
{
seg_t * seg = subsectors[i].firstline;
seg_t * seg = sub.firstline;
if (!seg->sidedef)
{
Printf("GL nodes contain invalid data. The BSP has to be rebuilt.\n");
delete [] nodes;
nodes = NULL;
delete [] subsectors;
subsectors = NULL;
level.subsectors.Clear();
level.segs.Clear();
return false;
}
@ -857,7 +853,7 @@ bool P_LoadGLNodes(MapData * map)
{
try
{
subsectors = NULL;
level.subsectors.Clear();
level.segs.Clear();
nodes = NULL;
P_LoadZNodes (*map->file, id);
@ -865,11 +861,7 @@ bool P_LoadGLNodes(MapData * map)
}
catch (CRecoverableError &)
{
if (subsectors != NULL)
{
delete[] subsectors;
subsectors = NULL;
}
level.subsectors.Clear();
level.segs.Clear();
if (nodes != NULL)
{
@ -965,15 +957,14 @@ bool P_CheckNodes(MapData * map, bool rebuilt, int buildtime)
if (!rebuilt && !P_CheckForGLNodes())
{
ret = true; // we are not using the level's original nodes if we get here.
for (int i = 0; i < numsubsectors; i++)
for (auto &sub : level.gamesubsectors)
{
gamesubsectors[i].sector = gamesubsectors[i].firstline->sidedef->sector;
sub.sector = sub.firstline->sidedef->sector;
}
nodes = NULL;
numnodes = 0;
subsectors = NULL;
numsubsectors = 0;
level.subsectors.Clear();
level.segs.Clear();
// Try to load GL nodes (cached or GWA)
@ -998,7 +989,7 @@ bool P_CheckNodes(MapData * map, bool rebuilt, int buildtime)
builder.Extract (nodes, numnodes,
level.segs,
subsectors, numsubsectors,
level.subsectors,
level.vertexes);
endTime = I_FPSTime ();
DPrintf (DMSG_NOTIFY, "BSP generation took %.3f sec (%u segs)\n", (endTime - startTime) * 0.001, level.segs.Size());
@ -1027,8 +1018,7 @@ bool P_CheckNodes(MapData * map, bool rebuilt, int buildtime)
{
gamenodes = nodes;
numgamenodes = numnodes;
gamesubsectors = subsectors;
numgamesubsectors = numsubsectors;
level.gamesubsectors.Point(level.subsectors);
}
return ret;
}
@ -1088,10 +1078,10 @@ static void CreateCachedNodes(MapData *map)
WriteLong(ZNodes, vert.fixY());
}
WriteLong(ZNodes, numsubsectors);
for(int i=0;i<numsubsectors;i++)
WriteLong(ZNodes, level.subsectors.Size());
for (auto &sub : level.subsectors)
{
WriteLong(ZNodes, subsectors[i].numlines);
WriteLong(ZNodes, sub.numlines);
}
WriteLong(ZNodes, level.segs.Size());
@ -1131,7 +1121,7 @@ static void CreateCachedNodes(MapData *map)
uint32_t child;
if ((size_t)nodes[i].children[j] & 1)
{
child = 0x80000000 | uint32_t((subsector_t *)((uint8_t *)nodes[i].children[j] - 1) - subsectors);
child = 0x80000000 | uint32_t(((subsector_t *)((uint8_t *)nodes[i].children[j] - 1))->Index());
}
else
{
@ -1230,11 +1220,7 @@ static bool CheckCachedNodes(MapData *map)
{
Printf ("Error loading nodes: %s\n", error.GetMessage());
if (subsectors != NULL)
{
delete[] subsectors;
subsectors = NULL;
}
level.subsectors.Clear();
level.segs.Clear();
if (nodes != NULL)
{
@ -1324,7 +1310,7 @@ subsector_t *P_PointInSubsector (double x, double y)
// single subsector is a special case
if (numgamenodes == 0)
return gamesubsectors;
return &level.gamesubsectors[0];
node = gamenodes + numgamenodes - 1;
@ -1450,39 +1436,38 @@ void P_SetRenderSector()
}
// look up sector number for each subsector
for (i = 0; i < numsubsectors; i++)
for (auto &ss : level.subsectors)
{
// For rendering pick the sector from the first seg that is a sector boundary
// this takes care of self-referencing sectors
ss = &subsectors[i];
seg_t *seg = ss->firstline;
seg_t *seg = ss.firstline;
// Check for one-dimensional subsectors. These should be ignored when
// being processed for automap drawing etc.
ss->flags |= SSECF_DEGENERATE;
for(j=2; j<ss->numlines; j++)
ss.flags |= SSECF_DEGENERATE;
for(j=2; j<ss.numlines; j++)
{
if (!PointOnLine(seg[j].v1->fixX(), seg[j].v1->fixY(), seg->v1->fixX(), seg->v1->fixY(), seg->v2->fixX() -seg->v1->fixX(), seg->v2->fixY() -seg->v1->fixY()))
{
// Not on the same line
ss->flags &= ~SSECF_DEGENERATE;
ss.flags &= ~SSECF_DEGENERATE;
break;
}
}
seg = ss->firstline;
for(j=0; j<ss->numlines; j++)
seg = ss.firstline;
for(j=0; j<ss.numlines; j++)
{
if(seg->sidedef && (seg->PartnerSeg == nullptr || (seg->PartnerSeg->sidedef != nullptr && seg->sidedef->sector!=seg->PartnerSeg->sidedef->sector)))
{
ss->render_sector = seg->sidedef->sector;
ss.render_sector = seg->sidedef->sector;
break;
}
seg++;
}
if(ss->render_sector == NULL)
if(ss.render_sector == NULL)
{
undetermined.Push(ss);
undetermined.Push(&ss);
}
}

View file

@ -2104,7 +2104,7 @@ sector_t *P_PointInSectorBuggy(double x, double y)
{
// single subsector is a special case
if (numgamenodes == 0)
return gamesubsectors->sector;
return level.gamesubsectors[0].sector;
node_t *node = gamenodes + numgamenodes - 1;

View file

@ -333,15 +333,14 @@ FSerializer &Serialize(FSerializer &arc, const char *key, sector_t &p, sector_t
void RecalculateDrawnSubsectors()
{
for (int i = 0; i<numsubsectors; i++)
for (auto &sub : level.subsectors)
{
subsector_t *sub = &subsectors[i];
for (unsigned int j = 0; j<sub->numlines; j++)
for (unsigned int j = 0; j<sub.numlines; j++)
{
if (sub->firstline[j].linedef != NULL &&
(sub->firstline[j].linedef->flags & ML_MAPPED))
if (sub.firstline[j].linedef != NULL &&
(sub.firstline[j].linedef->flags & ML_MAPPED))
{
sub->flags |= SSECF_DRAWN;
sub.flags |= SSECF_DRAWN;
}
}
}
@ -353,23 +352,24 @@ void RecalculateDrawnSubsectors()
//
//==========================================================================
FSerializer &Serialize(FSerializer &arc, const char *key, subsector_t *&ss, subsector_t **)
FSerializer &SerializeSubsectors(FSerializer &arc, const char *key)
{
uint8_t by;
const char *str;
auto numsubsectors = level.subsectors.Size();
if (arc.isWriting())
{
if (hasglnodes)
{
TArray<char> encoded(1 + (numsubsectors + 5) / 6);
int p = 0;
for (int i = 0; i < numsubsectors; i += 6)
for (unsigned i = 0; i < numsubsectors; i += 6)
{
by = 0;
for (int j = 0; j < 6; j++)
{
if (i + j < numsubsectors && (subsectors[i + j].flags & SSECF_DRAWN))
if (i + j < (int)numsubsectors && (level.subsectors[i + j].flags & SSECF_DRAWN))
{
by |= (1 << j);
}
@ -423,9 +423,9 @@ FSerializer &Serialize(FSerializer &arc, const char *key, subsector_t *&ss, subs
}
for (int s = 0; s < 6; s++)
{
if (sub + s < numsubsectors && (by & (1 << s)))
if (sub + s < (int)numsubsectors && (by & (1 << s)))
{
subsectors[sub + s].flags |= SSECF_DRAWN;
level.subsectors[sub + s].flags |= SSECF_DRAWN;
}
}
sub += 6;
@ -1003,7 +1003,7 @@ void G_SerializeLevel(FSerializer &arc, bool hubload)
E_SerializeEvents(arc);
DThinker::SerializeThinkers(arc, !hubload);
arc.Array("polyobjs", polyobjs, po_NumPolyobjs);
arc("subsectors", subsectors);
SerializeSubsectors(arc, "subsectors");
StatusBar->SerializeMessages(arc);
AM_SerializeMarkers(arc);
FRemapTable::StaticSerializeTranslations(arc);

View file

@ -125,12 +125,6 @@ inline bool P_LoadBuildMap(uint8_t *mapdata, size_t len, FMapThing **things, int
//
TArray<vertexdata_t> vertexdatas;
int numsegs;
seg_t* segs;
int numsubsectors;
subsector_t* subsectors;
int numnodes;
node_t* nodes;
@ -139,9 +133,6 @@ TArray<zone_t> Zones;
node_t * gamenodes;
int numgamenodes;
subsector_t * gamesubsectors;
int numgamesubsectors;
bool hasglnodes;
TArray<FMapThing> MapThingsConverted;
@ -191,7 +182,6 @@ TArray<FPlayerStart> AllPlayerStarts;
static void P_AllocateSideDefs (MapData *map, int count);
//===========================================================================
//
// GetMapIndex
@ -863,7 +853,7 @@ void P_LoadVertexes (MapData * map)
void P_LoadZSegs (FileReaderBase &data)
{
for (int i = 0; i < numsegs; ++i)
for (auto &seg : level.segs)
{
line_t *ldef;
uint32_t v1, v2;
@ -872,18 +862,18 @@ void P_LoadZSegs (FileReaderBase &data)
data >> v1 >> v2 >> line >> side;
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;
seg.v1 = &level.vertexes[v1];
seg.v2 = &level.vertexes[v2];
seg.linedef = ldef = &level.lines[line];
seg.sidedef = ldef->sidedef[side];
seg.frontsector = ldef->sidedef[side]->sector;
if (ldef->flags & ML_TWOSIDED && ldef->sidedef[side^1] != NULL)
{
segs[i].backsector = ldef->sidedef[side^1]->sector;
seg.backsector = ldef->sidedef[side^1]->sector;
}
else
{
segs[i].backsector = 0;
seg.backsector = 0;
ldef->flags &= ~ML_TWOSIDED;
}
}
@ -899,9 +889,10 @@ void P_LoadZSegs (FileReaderBase &data)
void P_LoadGLZSegs (FileReaderBase &data, int type)
{
for (int i = 0; i < numsubsectors; ++i)
for (unsigned i = 0; i < level.subsectors.Size(); ++i)
{
for (size_t j = 0; j < subsectors[i].numlines; ++j)
for (size_t j = 0; j < level.subsectors[i].numlines; ++j)
{
seg_t *seg;
uint32_t v1, partner;
@ -921,18 +912,18 @@ void P_LoadGLZSegs (FileReaderBase &data, int type)
}
data >> side;
seg = subsectors[i].firstline + j;
seg = level.subsectors[i].firstline + j;
seg->v1 = &level.vertexes[v1];
if (j == 0)
{
seg[subsectors[i].numlines - 1].v2 = seg->v1;
seg[level.subsectors[i].numlines - 1].v2 = seg->v1;
}
else
{
seg[-1].v2 = seg->v1;
}
seg->PartnerSeg = partner == 0xffffffffu? nullptr : &segs[partner];
seg->PartnerSeg = partner == 0xffffffffu? nullptr : &level.segs[partner];
if (line != 0xFFFFFFFF)
{
line_t *ldef;
@ -954,7 +945,7 @@ void P_LoadGLZSegs (FileReaderBase &data, int type)
{
seg->linedef = NULL;
seg->sidedef = NULL;
seg->frontsector = seg->backsector = subsectors[i].firstline->frontsector;
seg->frontsector = seg->backsector = level.subsectors[i].firstline->frontsector;
}
}
}
@ -1012,17 +1003,16 @@ void LoadZNodes(FileReaderBase &data, int glnodes)
uint32_t numSubs, currSeg;
data >> numSubs;
numsubsectors = numSubs;
subsectors = new subsector_t[numSubs];
memset (subsectors, 0, numsubsectors*sizeof(subsector_t));
level.subsectors.Alloc(numSubs);
memset (&level.subsectors[0], 0, level.subsectors.Size()*sizeof(subsector_t));
for (i = currSeg = 0; i < numSubs; ++i)
{
uint32_t numsegs;
data >> numsegs;
subsectors[i].firstline = (seg_t *)(size_t)currSeg; // Oh damn. I should have stored the seg count sooner.
subsectors[i].numlines = numsegs;
level.subsectors[i].firstline = (seg_t *)(size_t)currSeg; // Oh damn. I should have stored the seg count sooner.
level.subsectors[i].numlines = numsegs;
currSeg += numsegs;
}
@ -1038,13 +1028,12 @@ void LoadZNodes(FileReaderBase &data, int glnodes)
throw CRecoverableError("Incorrect number of segs in nodes.\n");
}
numsegs = numSegs;
segs = new seg_t[numsegs];
memset (segs, 0, numsegs*sizeof(seg_t));
level.segs.Alloc(numSegs);
memset (&level.segs[0], 0, numSegs*sizeof(seg_t));
for (i = 0; i < numSubs; ++i)
for (auto &sub : level.subsectors)
{
subsectors[i].firstline = &segs[(size_t)subsectors[i].firstline];
sub.firstline = &level.segs[(size_t)sub.firstline];
}
if (glnodes == 0)
@ -1095,7 +1084,7 @@ void LoadZNodes(FileReaderBase &data, int glnodes)
data >> child;
if (child & 0x80000000)
{
nodes[i].children[m] = (uint8_t *)&subsectors[child & 0x7FFFFFFF] + 1;
nodes[i].children[m] = (uint8_t *)&level.subsectors[child & 0x7FFFFFFF] + 1;
}
else
{
@ -1205,7 +1194,6 @@ struct badseg
template<class segtype>
void P_LoadSegs (MapData * map)
{
int i;
uint8_t *data;
int numvertexes = level.vertexes.Size();
uint8_t *vertchanged = new uint8_t[numvertexes]; // phares 10/4/98
@ -1217,27 +1205,28 @@ void P_LoadSegs (MapData * map)
memset (vertchanged,0,numvertexes); // phares 10/4/98
numsegs = lumplen / sizeof(segtype);
unsigned numsegs = lumplen / sizeof(segtype);
if (numsegs == 0)
{
Printf ("This map has no segs.\n");
delete[] subsectors;
level.subsectors.Clear();
delete[] nodes;
delete[] vertchanged;
ForceNodeBuild = true;
return;
}
segs = new seg_t[numsegs];
memset (segs, 0, numsegs*sizeof(seg_t));
level.segs.Alloc(numsegs);
auto &segs = level.segs;
memset (&segs[0], 0, numsegs*sizeof(seg_t));
data = new uint8_t[lumplen];
map->Read(ML_SEGS, data);
for (i = 0; i < numsubsectors; ++i)
for (auto &sub : level.subsectors)
{
subsectors[i].firstline = &segs[(size_t)subsectors[i].firstline];
sub.firstline = &segs[(size_t)sub.firstline];
}
// phares: 10/4/98: Vertchanged is an array that represents the vertices.
@ -1251,9 +1240,9 @@ void P_LoadSegs (MapData * map)
try
{
for (i = 0; i < numsegs; i++)
for (unsigned i = 0; i < numsegs; i++)
{
seg_t *li = segs + i;
seg_t *li = &segs[i];
segtype *ml = ((segtype *) data) + i;
int side, linedef;
@ -1366,8 +1355,8 @@ void P_LoadSegs (MapData * map)
break;
}
Printf ("The BSP will be rebuilt.\n");
delete[] segs;
delete[] subsectors;
level.segs.Clear();
level.subsectors.Clear();
delete[] nodes;
ForceNodeBuild = true;
}
@ -1386,10 +1375,9 @@ void P_LoadSegs (MapData * map)
template<class subsectortype, class segtype>
void P_LoadSubsectors (MapData * map)
{
int i;
uint32_t maxseg = map->Size(ML_SEGS) / sizeof(segtype);
numsubsectors = map->Size(ML_SSECTORS) / sizeof(subsectortype);
unsigned numsubsectors = map->Size(ML_SSECTORS) / sizeof(subsectortype);
if (numsubsectors == 0 || maxseg == 0 )
{
@ -1399,12 +1387,13 @@ void P_LoadSubsectors (MapData * map)
return;
}
subsectors = new subsector_t[numsubsectors];
auto &subsectors = level.subsectors;
subsectors.Alloc(numsubsectors);
map->Seek(ML_SSECTORS);
memset (subsectors, 0, numsubsectors*sizeof(subsector_t));
memset (&subsectors[0], 0, numsubsectors*sizeof(subsector_t));
for (i = 0; i < numsubsectors; i++)
for (unsigned i = 0; i < numsubsectors; i++)
{
subsectortype subd;
@ -1413,7 +1402,7 @@ void P_LoadSubsectors (MapData * map)
if (subd.numsegs == 0)
{
Printf ("Subsector %i is empty.\n", i);
delete[] subsectors;
level.subsectors.Clear();
delete[] nodes;
ForceNodeBuild = true;
return;
@ -1429,7 +1418,7 @@ void P_LoadSubsectors (MapData * map)
(unsigned)((size_t)subsectors[i].firstline) + subsectors[i].numlines - 1);
ForceNodeBuild = true;
delete[] nodes;
delete[] subsectors;
level.subsectors.Clear();
break;
}
else if ((size_t)subsectors[i].firstline + subsectors[i].numlines > maxseg)
@ -1439,7 +1428,7 @@ void P_LoadSubsectors (MapData * map)
(unsigned)((size_t)subsectors[i].firstline) + subsectors[i].numlines - 1);
ForceNodeBuild = true;
delete[] nodes;
delete[] subsectors;
level.subsectors.Clear();
break;
}
}
@ -1597,7 +1586,7 @@ void P_LoadNodes (MapData * map)
delete[] mnp;
return;
}
no->children[j] = (uint8_t *)&subsectors[child] + 1;
no->children[j] = (uint8_t *)&level.subsectors[child] + 1;
}
else if (child >= numnodes)
{
@ -3085,15 +3074,15 @@ static void P_GroupLines (bool buildmap)
// look up sector number for each subsector
times[0].Clock();
for (int i = 0; i < numsubsectors; i++)
for (auto &sub : level.subsectors)
{
subsectors[i].sector = subsectors[i].firstline->sidedef->sector;
sub.sector = sub.firstline->sidedef->sector;
}
for (int i = 0; i < numsubsectors; i++)
for (auto &sub : level.subsectors)
{
for (jj = 0; jj < subsectors[i].numlines; ++jj)
for (jj = 0; jj < sub.numlines; ++jj)
{
subsectors[i].firstline[jj].Subsector = &subsectors[i];
sub.firstline[jj].Subsector = &sub;
}
}
times[0].Unclock();
@ -3448,12 +3437,7 @@ void P_FreeLevelData ()
wminfo.maxfrags = 0;
FBehavior::StaticUnloadModules ();
if (segs != NULL)
{
delete[] segs;
segs = NULL;
}
numsegs = 0;
level.segs.Clear();
if (level.sectors.Size() > 0)
{
delete[] level.sectors[0].e;
@ -3467,27 +3451,12 @@ void P_FreeLevelData ()
{
delete[] gamenodes;
}
if (gamesubsectors != NULL && gamesubsectors != subsectors)
{
delete[] gamesubsectors;
}
if (subsectors != NULL)
{
for (int i = 0; i < numsubsectors; ++i)
{
if (subsectors[i].BSP != NULL)
{
delete subsectors[i].BSP;
}
}
delete[] subsectors;
}
level.subsectors.Clear();
level.gamesubsectors.Clear();
if (nodes != NULL)
{
delete[] nodes;
}
subsectors = gamesubsectors = NULL;
numsubsectors = numgamesubsectors = 0;
nodes = gamenodes = NULL;
numnodes = numgamenodes = 0;
@ -3823,16 +3792,8 @@ void P_SetupLevel (const char *lumpname, int position)
Printf ("Error loading nodes: %s\n", error.GetMessage());
ForceNodeBuild = true;
if (subsectors != NULL)
{
delete[] subsectors;
subsectors = NULL;
}
if (segs != NULL)
{
delete[] segs;
segs = NULL;
}
level.subsectors.Clear();
level.segs.Clear();
if (nodes != NULL)
{
delete[] nodes;
@ -3915,10 +3876,10 @@ void P_SetupLevel (const char *lumpname, int position)
FNodeBuilder builder (leveldata, polyspots, anchors, BuildGLNodes);
builder.Extract (nodes, numnodes,
level.segs,
subsectors, numsubsectors,
level.subsectors,
level.vertexes);
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, level.segs.Size());
oldvertextable = builder.GetOldVertexTable();
reloop = true;
}
@ -3926,38 +3887,38 @@ void P_SetupLevel (const char *lumpname, int position)
{
BuildGLNodes = false;
// Older ZDBSPs had problems with compressed sidedefs and assigned wrong sides to the segs if both sides were the same sidedef.
for(i=0;i<numsegs;i++)
for(auto &seg : level.segs)
{
seg_t * seg=&segs[i];
if (seg->backsector == seg->frontsector && seg->linedef)
if (seg.backsector == seg.frontsector && seg.linedef)
{
double d1 = (seg->v1->fPos() - seg->linedef->v1->fPos()).LengthSquared();
double d2 = (seg->v2->fPos() - seg->linedef->v1->fPos()).LengthSquared();
double d1 = (seg.v1->fPos() - seg.linedef->v1->fPos()).LengthSquared();
double d2 = (seg.v2->fPos() - seg.linedef->v1->fPos()).LengthSquared();
if (d2<d1) // backside
{
seg->sidedef = seg->linedef->sidedef[1];
seg.sidedef = seg.linedef->sidedef[1];
}
else // front side
{
seg->sidedef = seg->linedef->sidedef[0];
seg.sidedef = seg.linedef->sidedef[0];
}
}
}
}
// Copy pointers to the old nodes so that R_PointInSubsector can use them
if (nodes && subsectors)
if (nodes)
{
gamenodes = nodes;
numgamenodes = numnodes;
gamesubsectors = subsectors;
numgamesubsectors = numsubsectors;
}
else
{
gamenodes=NULL;
}
// let the game data take ownership, because that is guaranteed to remain intact after here.
level.gamesubsectors = std::move(level.subsectors);
level.subsectors.Point(level.gamesubsectors);
if (RequireGLNodes)
{

View file

@ -1751,15 +1751,14 @@ void PO_Init (void)
// mark all subsectors which have a seg belonging to a polyobj
// These ones should not be rendered on the textured automap.
for (int i = 0; i < numsubsectors; i++)
for (auto &ss : level.subsectors)
{
subsector_t *ss = &subsectors[i];
for(uint32_t j=0;j<ss->numlines; j++)
for(uint32_t j=0;j<ss.numlines; j++)
{
if (ss->firstline[j].sidedef != NULL &&
ss->firstline[j].sidedef->Flags & WALLF_POLYOBJ)
if (ss.firstline[j].sidedef != NULL &&
ss.firstline[j].sidedef->Flags & WALLF_POLYOBJ)
{
ss->flags |= SSECF_POLYORG;
ss.flags |= SSECF_POLYORG;
break;
}
}

View file

@ -38,7 +38,7 @@ void PolyCull::CullScene(const TriMatrix &worldToClip, const Vec4f &portalClipPl
MaxCeilingHeight = 0.0;
MinFloorHeight = 0.0;
if (numnodes == 0)
CullSubsector(subsectors);
CullSubsector(&level.subsectors[0]);
else
CullNode(nodes + numnodes - 1); // The head node is the last node output.
}

View file

@ -117,10 +117,10 @@ void RenderPolyScene::RenderSubsector(subsector_t *sub)
}
}
bool mainBSP = ((unsigned int)(sub - subsectors) < (unsigned int)numsubsectors);
bool mainBSP = ((unsigned int)(sub->Index()) < level.subsectors.Size());
if (mainBSP)
{
int subsectorIndex = (int)(sub - subsectors);
int subsectorIndex = sub->Index();
for (int i = ParticlesInSubsec[subsectorIndex]; i != NO_PARTICLE; i = Particles[i].snext)
{
particle_t *particle = Particles + i;
@ -136,7 +136,7 @@ void RenderPolyScene::RenderSprite(AActor *thing, double sortDistance, const DVe
{
if (numnodes == 0)
{
subsector_t *sub = subsectors;
subsector_t *sub = &level.subsectors[0];
auto it = SubsectorDepths.find(sub);
if (it != SubsectorDepths.end())
TranslucentObjects.push_back({ thing, sub, it->second, sortDistance, 0.0f, 1.0f });

View file

@ -1413,6 +1413,7 @@ struct subsector_t
int flags;
void BuildPolyBSP();
int Index() const;
// subsector related GL data
FLightNode * lighthead; // Light nodes (blended and additive)
int validcount;
@ -1462,7 +1463,6 @@ struct FMiniBSP
};
//
// OTHER TYPES
//

View file

@ -46,12 +46,6 @@ extern uint32_t NumStdSprites;
extern TArray<vertexdata_t> vertexdatas;
//extern int numsegs;
//extern seg_t* segs;
extern int numsubsectors;
extern subsector_t* subsectors;
extern int numnodes;
extern node_t* nodes;
@ -60,9 +54,6 @@ extern TArray<zone_t> Zones;
extern node_t * gamenodes;
extern int numgamenodes;
extern subsector_t * gamesubsectors;
extern int numgamesubsectors;
//
// POV data.

View file

@ -302,7 +302,7 @@ subsector_t *R_PointInSubsector (fixed_t x, fixed_t y)
// single subsector is a special case
if (numnodes == 0)
return subsectors;
return &level.subsectors[0];
node = nodes + numnodes - 1;

View file

@ -50,7 +50,7 @@ namespace swrenderer
secplane_t height;
FTextureID picnum;
int lightlevel = 0;
int left = viewwidth;
int left;// = viewwidth;
int right = 0;
int sky = 0;

View file

@ -449,8 +449,8 @@ namespace swrenderer
}
#ifdef RANGECHECK
if (outersubsector && sub - subsectors >= (ptrdiff_t)numsubsectors)
I_Error("RenderSubsector: ss %ti with numss = %i", sub - subsectors, numsubsectors);
if (outersubsector && (unsigned)sub->Index() >= level.subsectors.Size())
I_Error("RenderSubsector: ss %i with numss = %u", sub->Index(), level.subsectors.Size());
#endif
assert(sub->sector != nullptr);
@ -714,12 +714,12 @@ namespace swrenderer
AddSprites(sub->sector, frontsector->GetTexture(sector_t::ceiling) == skyflatnum ? ceilinglightlevel : floorlightlevel, FakeSide, foggy, basecolormap);
// [RH] Add particles
if ((unsigned int)(sub - subsectors) < (unsigned int)numsubsectors)
if ((unsigned int)(sub->Index()) < level.subsectors.Size())
{ // Only do it for the main BSP.
int shade = LightVisibility::LightLevelToShade((floorlightlevel + ceilinglightlevel) / 2 + LightVisibility::ActualExtraLight(foggy, Thread->Viewport.get()), foggy);
for (int i = ParticlesInSubsec[(unsigned int)(sub - subsectors)]; i != NO_PARTICLE; i = Particles[i].snext)
for (int i = ParticlesInSubsec[sub->Index()]; i != NO_PARTICLE; i = Particles[i].snext)
{
RenderParticle::Project(Thread, Particles + i, subsectors[sub - subsectors].sector, shade, FakeSide, foggy);
RenderParticle::Project(Thread, Particles + i, sub->sector, shade, FakeSide, foggy);
}
}
@ -790,7 +790,7 @@ namespace swrenderer
{
if (numnodes == 0)
{
RenderSubsector(subsectors);
RenderSubsector(&level.subsectors[0]);
return;
}
while (!((size_t)node & 1)) // Keep going until found a subsector

View file

@ -596,6 +596,51 @@ public:
}
};
template <class T>
class TStaticPointableArray : public TStaticArray<T>
{
bool pointed = false;
public:
////////
TStaticPointableArray()
{
}
// This is not supposed to be copyable.
TStaticPointableArray(const TStaticArray<T> &other) = delete;
void Clear()
{
if (!pointed && this->Array) delete[] this->Array;
this->Count = 0;
this->Array = nullptr;
}
void Alloc(unsigned int amount)
{
// intentionally first deletes and then reallocates.
if (!pointed && this->Array) delete[] this->Array;
this->Array = new T[amount];
this->Count = amount;
pointed = false;
}
void Point(TStaticArray<T> & other)
{
if (!pointed && this->Array) delete[] this->Array;
this->Array = other.Array;
this->Count = other.Count;
pointed = true;
}
TStaticPointableArray &operator=(TStaticArray &&other)
{
if (!pointed && this->Array) delete[] this->Array;
this->Array = other.Array;
this->Count = other.Count;
other.Array = nullptr;
other.Count = 0;
pointed = false;
return *this;
}
};
// TAutoGrowArray -----------------------------------------------------------
// An array with accessors that automatically grow the array as needed.