diff --git a/src/am_map.cpp b/src/am_map.cpp index dcf988f10..312e4b901 100644 --- a/src/am_map.cpp +++ b/src/am_map.cpp @@ -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); diff --git a/src/g_levellocals.h b/src/g_levellocals.h index e4d87934c..a7bd53ed1 100644 --- a/src/g_levellocals.h +++ b/src/g_levellocals.h @@ -34,6 +34,8 @@ struct FLevelLocals TStaticArray lines; TStaticArray sides; TStaticArray segs; + TStaticPointableArray subsectors; + TStaticPointableArray gamesubsectors; TArray 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]; diff --git a/src/g_shared/a_dynlight.cpp b/src/g_shared/a_dynlight.cpp index e594e6a63..73ca554d1 100644 --- a/src/g_shared/a_dynlight.cpp +++ b/src/g_shared/a_dynlight.cpp @@ -829,19 +829,18 @@ CCMD(listlights) CCMD(listsublights) { - for(int i=0;ilighthead; + 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); } } diff --git a/src/gl/compatibility/gl_20.cpp b/src/gl/compatibility/gl_20.cpp index b1dbdee7d..c8b561bc6 100644 --- a/src/gl/compatibility/gl_20.cpp +++ b/src/gl/compatibility/gl_20.cpp @@ -680,7 +680,7 @@ void GLFlat::DrawLightsCompat(int pass) for (int i = 0; isubsectorcount; 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); } diff --git a/src/gl/data/gl_data.cpp b/src/gl/data/gl_data.cpp index b83ced72c..6b4edcb9d 100644 --- a/src/gl/data/gl_data.cpp +++ b/src/gl/data/gl_data.cpp @@ -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;knumlines;k++) { seg_t * seg = sub->firstline + k; diff --git a/src/gl/data/gl_portaldata.cpp b/src/gl/data/gl_portaldata.cpp index cc7368249..99ab17413 100644 --- a/src/gl/data/gl_portaldata.cpp +++ b/src/gl/data/gl_portaldata.cpp @@ -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;jrender_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++) { diff --git a/src/gl/data/gl_setup.cpp b/src/gl/data/gl_setup.cpp index 1ecd74057..26aee78b7 100644 --- a/src/gl/data/gl_setup.cpp +++ b/src/gl/data/gl_setup.cpp @@ -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 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; irender_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; irender_sector->subsectors[ss->render_sector->subsectorcount++]=ss; + sub.render_sector->subsectors[sub.render_sector->subsectorcount++] = ⊂ } // 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;jSubsector->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;iIndex(), subsectors[j].firstline->linedef->Index()); + Printf("Mapsection %d, sector %d, line %d\n", i, sub.render_sector->Index(), sub.firstline->linedef->Index()); break; } } diff --git a/src/gl/scene/gl_bsp.cpp b/src/gl/scene/gl_bsp.cpp index 32d20bedb..3112b716a 100644 --- a/src/gl/scene/gl_bsp.cpp +++ b/src/gl/scene/gl_bsp.cpp @@ -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 diff --git a/src/gl/scene/gl_drawinfo.cpp b/src/gl/scene/gl_drawinfo.cpp index 241987ddf..dbc646464 100644 --- a/src/gl/scene/gl_drawinfo.cpp +++ b/src/gl/scene/gl_drawinfo.cpp @@ -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(§orrenderflags[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; diff --git a/src/gl/scene/gl_flats.cpp b/src/gl/scene/gl_flats.cpp index 9674d4750..76c6466ab 100644 --- a/src/gl/scene/gl_flats.cpp +++ b/src/gl/scene/gl_flats.cpp @@ -224,7 +224,7 @@ void GLFlat::ProcessLights(bool istrans) for (int i=0; isubsectorcount; 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; isubsectorcount; 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); diff --git a/src/gl/scene/gl_portal.cpp b/src/gl/scene/gl_portal.cpp index f36016c3d..9968d2350 100644 --- a/src/gl/scene/gl_portal.cpp +++ b/src/gl/scene/gl_portal.cpp @@ -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;jportalcoverage[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); diff --git a/src/gl/scene/gl_renderhacks.cpp b/src/gl/scene/gl_renderhacks.cpp index 425adba5f..3e3f23dca 100644 --- a/src/gl/scene/gl_renderhacks.cpp +++ b/src/gl/scene/gl_renderhacks.cpp @@ -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;ksubsectorcount;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;jnumlines;j++) @@ -1148,7 +1148,7 @@ void FDrawInfo::ProcessSectorStacks() for(unsigned int j=0;jIndex()] &= ~SSRF_RENDERCEILING; if (sub->portalcoverage[sector_t::ceiling].subsectors == NULL) { @@ -1176,7 +1176,7 @@ void FDrawInfo::ProcessSectorStacks() if (portal != NULL) for(int k=0;ksubsectorcount;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;jnumlines;j++) @@ -1193,7 +1193,7 @@ void FDrawInfo::ProcessSectorStacks() for(unsigned int j=0;jIndex()] &= ~SSRF_RENDERFLOOR; if (sub->portalcoverage[sector_t::floor].subsectors == NULL) { diff --git a/src/nodebuild.h b/src/nodebuild.h index 09298ac19..72e301be1 100644 --- a/src/nodebuild.h +++ b/src/nodebuild.h @@ -195,7 +195,7 @@ public: void Extract(node_t *&nodes, int &nodeCount, TStaticArray &segs, - subsector_t *&ssecs, int &subCount, + TStaticPointableArray &ssecs, TStaticArray &vertexes); const int *GetOldVertexTable(); diff --git a/src/nodebuild_extract.cpp b/src/nodebuild_extract.cpp index f16b75524..6d1f13303 100644 --- a/src/nodebuild_extract.cpp +++ b/src/nodebuild_extract.cpp @@ -54,7 +54,7 @@ void FNodeBuilder::Extract (node_t *&outNodes, int &nodeCount, TStaticArray &outSegs, - subsector_t *&outSubs, int &subCount, + TStaticPointableArray &outSubs, TStaticArray &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 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]; } diff --git a/src/p_effect.cpp b/src/p_effect.cpp index 200fc367d..ba1b4552f 100644 --- a/src/p_effect.cpp +++ b/src/p_effect.cpp @@ -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; } diff --git a/src/p_glnodes.cpp b/src/p_glnodes.cpp index 153c20949..b7c03d46c 100644 --- a/src/p_glnodes.cpp +++ b/src/p_glnodes.cpp @@ -163,13 +163,10 @@ static int CheckForMissingSegs() bool P_CheckForGLNodes() { - int i; - - for(i=0;ifirstline; - 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;jnumlines;j++) + for(uint32_t j=0;jGetLength(); + 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; ilinedef==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;iIndex()); } 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; jnumlines; j++) + ss.flags |= SSECF_DEGENERATE; + for(j=2; jfixX(), 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; jnumlines; j++) + seg = ss.firstline; + for(j=0; jsidedef && (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); } } diff --git a/src/p_maputl.cpp b/src/p_maputl.cpp index 7ec64e8db..86183a8fc 100644 --- a/src/p_maputl.cpp +++ b/src/p_maputl.cpp @@ -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; diff --git a/src/p_saveg.cpp b/src/p_saveg.cpp index d749be0cc..52609ca2e 100644 --- a/src/p_saveg.cpp +++ b/src/p_saveg.cpp @@ -333,15 +333,14 @@ FSerializer &Serialize(FSerializer &arc, const char *key, sector_t &p, sector_t void RecalculateDrawnSubsectors() { - for (int i = 0; inumlines; j++) + for (unsigned int j = 0; jfirstline[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 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); diff --git a/src/p_setup.cpp b/src/p_setup.cpp index 908306a25..4485d5763 100644 --- a/src/p_setup.cpp +++ b/src/p_setup.cpp @@ -125,12 +125,6 @@ inline bool P_LoadBuildMap(uint8_t *mapdata, size_t len, FMapThing **things, int // TArray vertexdatas; -int numsegs; -seg_t* segs; - -int numsubsectors; -subsector_t* subsectors; - int numnodes; node_t* nodes; @@ -139,9 +133,6 @@ TArray Zones; node_t * gamenodes; int numgamenodes; -subsector_t * gamesubsectors; -int numgamesubsectors; - bool hasglnodes; TArray MapThingsConverted; @@ -191,7 +182,6 @@ TArray 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 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 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 = ⊂ } } 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;ibacksector == 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 (d2sidedef = 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) { diff --git a/src/po_man.cpp b/src/po_man.cpp index 5572db1fa..5a0405a43 100644 --- a/src/po_man.cpp +++ b/src/po_man.cpp @@ -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;jnumlines; j++) + for(uint32_t j=0;jfirstline[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; } } diff --git a/src/polyrenderer/scene/poly_cull.cpp b/src/polyrenderer/scene/poly_cull.cpp index de579d799..246da6187 100644 --- a/src/polyrenderer/scene/poly_cull.cpp +++ b/src/polyrenderer/scene/poly_cull.cpp @@ -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. } diff --git a/src/polyrenderer/scene/poly_scene.cpp b/src/polyrenderer/scene/poly_scene.cpp index 7edd216a9..830f68c25 100644 --- a/src/polyrenderer/scene/poly_scene.cpp +++ b/src/polyrenderer/scene/poly_scene.cpp @@ -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 }); diff --git a/src/r_defs.h b/src/r_defs.h index eeb2931a6..18ef9e1d3 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -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 // diff --git a/src/r_state.h b/src/r_state.h index 780a2767c..56b53cad5 100644 --- a/src/r_state.h +++ b/src/r_state.h @@ -46,12 +46,6 @@ extern uint32_t NumStdSprites; extern TArray 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 Zones; extern node_t * gamenodes; extern int numgamenodes; -extern subsector_t * gamesubsectors; -extern int numgamesubsectors; - // // POV data. diff --git a/src/r_utility.cpp b/src/r_utility.cpp index bcd613af6..f76b6fb89 100644 --- a/src/r_utility.cpp +++ b/src/r_utility.cpp @@ -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; diff --git a/src/swrenderer/plane/r_visibleplane.h b/src/swrenderer/plane/r_visibleplane.h index 970eee632..0c1b13f45 100644 --- a/src/swrenderer/plane/r_visibleplane.h +++ b/src/swrenderer/plane/r_visibleplane.h @@ -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; diff --git a/src/swrenderer/scene/r_opaque_pass.cpp b/src/swrenderer/scene/r_opaque_pass.cpp index 471731df6..dec5f8e17 100644 --- a/src/swrenderer/scene/r_opaque_pass.cpp +++ b/src/swrenderer/scene/r_opaque_pass.cpp @@ -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 diff --git a/src/tarray.h b/src/tarray.h index d6962816c..38e655563 100644 --- a/src/tarray.h +++ b/src/tarray.h @@ -596,6 +596,51 @@ public: } }; +template +class TStaticPointableArray : public TStaticArray +{ + bool pointed = false; +public: + + //////// + TStaticPointableArray() + { + } + // This is not supposed to be copyable. + TStaticPointableArray(const TStaticArray &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 & 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.