- added a level iterator for operations that need to make changes to all open levels.

Since currently there is only one level, this will obvciously only run once on that level for the time being.

This is mainly used for CCMDs and CVARs which either print some diagnostics or change some user-settable configuration.
This commit is contained in:
Christoph Oelckers 2019-01-28 02:41:29 +01:00
parent 64e9f7e43b
commit d941dea005
23 changed files with 198 additions and 126 deletions

View File

@ -1061,7 +1061,8 @@ CCMD(changesky)
FTextureID newsky = TexMan.GetTextureID(sky1name, ETextureType::Wall, FTextureManager::TEXMAN_Overridable | FTextureManager::TEXMAN_ReturnFirst);
if (newsky.Exists())
{
sky1texture = level.skytexture1 = newsky;
// This only alters the primary level's sky setting.
sky1texture = currentUILevel->skytexture1 = newsky;
}
else
{

View File

@ -746,12 +746,15 @@ void D_Display ()
//E_RenderFrame();
//
// Check for the presence of dynamic lights at the start of the frame once.
if ((gl_lights && vid_rendermode == 4) || (r_dynlights && vid_rendermode != 4))
for (auto Level : AllLevels())
{
level.HasDynamicLights = !!level.lights;
// Check for the presence of dynamic lights at the start of the frame once.
if ((gl_lights && vid_rendermode == 4) || (r_dynlights && vid_rendermode != 4))
{
Level->HasDynamicLights = !!level.lights;
}
else Level->HasDynamicLights = false; // lights are off so effectively we have none.
}
else level.HasDynamicLights = false; // lights are off so effectively we have none.
viewsec = screen->RenderView(&players[consoleplayer]);
screen->Begin2D();

View File

@ -488,6 +488,8 @@ void DObject::StaticPointerSubstitution (AActor *old, AActor *notOld)
DObject *probe;
size_t changed = 0;
int i;
if (old == nullptr) return;
// Go through all objects.
i = 0;DObject *last=0;
@ -515,8 +517,8 @@ void DObject::StaticPointerSubstitution (AActor *old, AActor *notOld)
}
}
// Go through sectors.
for (auto &sec : level.sectors)
// Go through sectors. Only the level this actor belongs to is relevant.
for (auto &sec : old->Level->sectors)
{
if (sec.SoundTarget == old) sec.SoundTarget = notOld;
}

View File

@ -306,7 +306,8 @@ static void MarkRoot()
DThinker::MarkRoots();
Mark(E_FirstEventHandler);
Mark(E_LastEventHandler);
level.Mark();
for (auto Level : AllLevels())
Level->Mark();
// Mark players.
for (i = 0; i < MAXPLAYERS; i++)

View File

@ -50,14 +50,21 @@ CVAR (Bool, alwaysapplydmflags, false, CVAR_SERVERINFO);
CUSTOM_CVAR (Float, teamdamage, 0.f, CVAR_SERVERINFO)
{
level.teamdamage = self;
for (auto Level : AllLevels())
{
Level->teamdamage = self;
}
}
CUSTOM_CVAR (String, language, "auto", CVAR_ARCHIVE)
{
SetLanguageIDs ();
GStrings.LoadStrings (false);
if (level.info != NULL) level.LevelName = level.info->LookupLevelName();
for (auto Level : AllLevels())
{
// does this even make sense on secondary levels...?
if (Level->info != nullptr) Level->LevelName = Level->info->LookupLevelName();
}
}
// [RH] Network arbitrator

View File

@ -769,7 +769,7 @@ void G_AddViewPitch (int look, bool mouse)
return;
}
look = LookAdjust(look);
if (!level.IsFreelookAllowed())
if (!currentUILevel->IsFreelookAllowed())
{
LocalViewPitch = 0;
}

View File

@ -109,17 +109,26 @@ void G_VerifySkill();
CUSTOM_CVAR(Bool, gl_brightfog, false, CVAR_ARCHIVE | CVAR_NOINITCALL)
{
if (level.info == nullptr || level.info->brightfog == -1) level.brightfog = self;
for (auto Level : AllLevels())
{
if (Level->info == nullptr || Level->info->brightfog == -1) Level->brightfog = self;
}
}
CUSTOM_CVAR(Bool, gl_lightadditivesurfaces, false, CVAR_ARCHIVE | CVAR_NOINITCALL)
{
if (level.info == nullptr || level.info->lightadditivesurfaces == -1) level.lightadditivesurfaces = self;
for (auto Level : AllLevels())
{
if (Level->info == nullptr || Level->info->lightadditivesurfaces == -1) Level->lightadditivesurfaces = self;
}
}
CUSTOM_CVAR(Bool, gl_notexturefill, false, CVAR_NOINITCALL)
{
if (level.info == nullptr || level.info->notexturefill == -1) level.notexturefill = self;
for (auto Level : AllLevels())
{
if (Level->info == nullptr || Level->info->notexturefill == -1) Level->notexturefill = self;
}
}
CUSTOM_CVAR(Int, gl_lightmode, 3, CVAR_ARCHIVE | CVAR_NOINITCALL)
@ -129,7 +138,10 @@ CUSTOM_CVAR(Int, gl_lightmode, 3, CVAR_ARCHIVE | CVAR_NOINITCALL)
else if (newself > 4) newself = 8;
else if (newself < 0) newself = 0;
if (self != newself) self = newself;
else if ((level.info == nullptr || level.info->lightmode == ELightMode::NotSet)) level.lightMode = (ELightMode)*self;
else for (auto Level : AllLevels())
{
if ((level.info == nullptr || level.info->lightmode == ELightMode::NotSet)) level.lightMode = (ELightMode)*self;
}
}
@ -202,7 +214,7 @@ CCMD (map)
if (argv.argc() > 1)
{
const char *mapname = argv[1];
if (!strcmp(mapname, "*")) mapname = level.MapName.GetChars();
if (!strcmp(mapname, "*")) mapname = currentUILevel->MapName.GetChars();
try
{
@ -252,7 +264,7 @@ UNSAFE_CCMD(recordmap)
if (argv.argc() > 2)
{
const char *mapname = argv[2];
if (!strcmp(mapname, "*")) mapname = level.MapName.GetChars();
if (!strcmp(mapname, "*")) mapname = currentUILevel->MapName.GetChars();
try
{
@ -2180,7 +2192,8 @@ CCMD(skyfog)
{
if (argv.argc()>1)
{
level.skyfog = MAX(0, (int)strtoull(argv[1], NULL, 0));
// Do this only on the primary level.
currentUILevel->skyfog = MAX(0, (int)strtoull(argv[1], NULL, 0));
}
}

View File

@ -635,3 +635,10 @@ inline AActor *P_SpawnPlayer(FPlayerStart *mthing, int playernum, int flags = 0)
{
return level.SpawnPlayer(mthing, playernum, flags);
}
// This must later be extended to return an array with all levels.
// It is meant for code that needs to iterate over all levels to make some global changes, e.g. configuation CCMDs.
inline TArrayView<FLevelLocals *> AllLevels()
{
return TArrayView<FLevelLocals *>(&currentUILevel, 1);
}

View File

@ -92,12 +92,15 @@ CUSTOM_CVAR(Int, sv_corpsequeuesize, 64, CVAR_ARCHIVE|CVAR_SERVERINFO)
{
if (self > 0)
{
auto &corpsequeue = level.CorpseQueue;
while (corpsequeue.Size() > (unsigned)self)
for (auto Level : AllLevels())
{
AActor *corpse = corpsequeue[0];
if (corpse) corpse->Destroy();
corpsequeue.Delete(0);
auto &corpsequeue = Level->CorpseQueue;
while (corpsequeue.Size() > (unsigned)self)
{
AActor *corpse = corpsequeue[0];
if (corpse) corpse->Destroy();
corpsequeue.Delete(0);
}
}
}
}

View File

@ -538,9 +538,9 @@ CUSTOM_CVAR (Int, cl_maxdecals, 1024, CVAR_ARCHIVE)
{
self = 0;
}
else
else for (auto Level : AllLevels())
{
while (level.ImpactDecalCount > self)
while (Level->ImpactDecalCount > self)
{
DThinker *thinker = DThinker::FirstThinker(STAT_AUTODECAL);
if (thinker != NULL)
@ -553,13 +553,13 @@ CUSTOM_CVAR (Int, cl_maxdecals, 1024, CVAR_ARCHIVE)
void DImpactDecal::CheckMax ()
{
if (++level.ImpactDecalCount >= cl_maxdecals)
if (++Level->ImpactDecalCount >= cl_maxdecals)
{
DThinker *thinker = DThinker::FirstThinker (STAT_AUTODECAL);
if (thinker != NULL)
{
thinker->Destroy();
level.ImpactDecalCount--;
Level->ImpactDecalCount--;
}
}
}

View File

@ -880,48 +880,52 @@ CCMD(listlights)
int allwalls=0, allsectors=0, allsubsecs = 0;
int i=0, shadowcount = 0;
FDynamicLight * dl;
for (dl = level.lights; dl; dl = dl->next)
for (auto Level : AllLevels())
{
walls=0;
sectors=0;
Printf("%s at (%f, %f, %f), color = 0x%02x%02x%02x, radius = %f %s %s",
dl->target->GetClass()->TypeName.GetChars(),
dl->X(), dl->Y(), dl->Z(), dl->GetRed(), dl->GetGreen(), dl->GetBlue(),
dl->radius, dl->IsAttenuated()? "attenuated" : "", dl->shadowmapped? "shadowmapped" : "");
i++;
shadowcount += dl->shadowmapped;
if (dl->target)
Printf("Lights for %s\n", Level->MapName.GetChars());
for (dl = Level->lights; dl; dl = dl->next)
{
FTextureID spr = sprites[dl->target->sprite].GetSpriteFrame(dl->target->frame, 0, 0., nullptr);
Printf(", frame = %s ", TexMan.GetTexture(spr)->GetName().GetChars());
walls=0;
sectors=0;
Printf("%s at (%f, %f, %f), color = 0x%02x%02x%02x, radius = %f %s %s",
dl->target->GetClass()->TypeName.GetChars(),
dl->X(), dl->Y(), dl->Z(), dl->GetRed(), dl->GetGreen(), dl->GetBlue(),
dl->radius, dl->IsAttenuated()? "attenuated" : "", dl->shadowmapped? "shadowmapped" : "");
i++;
shadowcount += dl->shadowmapped;
if (dl->target)
{
FTextureID spr = sprites[dl->target->sprite].GetSpriteFrame(dl->target->frame, 0, 0., nullptr);
Printf(", frame = %s ", TexMan.GetTexture(spr)->GetName().GetChars());
}
FLightNode * node;
node=dl->touching_sides;
while (node)
{
walls++;
allwalls++;
node = node->nextTarget;
}
node = dl->touching_sector;
while (node)
{
allsectors++;
sectors++;
node = node->nextTarget;
}
Printf("- %d walls, %d sectors\n", walls, sectors);
}
FLightNode * node;
node=dl->touching_sides;
while (node)
{
walls++;
allwalls++;
node = node->nextTarget;
}
node = dl->touching_sector;
while (node)
{
allsectors++;
sectors++;
node = node->nextTarget;
}
Printf("- %d walls, %d sectors\n", walls, sectors);
Printf("%i dynamic lights, %d shadowmapped, %d walls, %d sectors\n\n\n", i, shadowcount, allwalls, allsectors);
}
Printf("%i dynamic lights, %d shadowmapped, %d walls, %d sectors\n\n\n", i, shadowcount, allwalls, allsectors);
}

View File

@ -368,7 +368,7 @@ static void HU_DrawTimeRemaining (int y)
if (deathmatch && timelimit && gamestate == GS_LEVEL)
{
char str[80];
int timeleft = (int)(timelimit * TICRATE * 60) - level.maptime;
int timeleft = (int)(timelimit * TICRATE * 60) - currentUILevel->maptime;
int hours, minutes, seconds;
if (timeleft < 0)

View File

@ -83,9 +83,9 @@ CUSTOM_CVAR(Int, gl_shadowmap_quality, 512, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
CUSTOM_CVAR (Bool, gl_light_shadowmap, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
{
if (!self)
if (!self) for (auto Level : AllLevels())
{
auto light = level.lights;
auto light = Level->lights;
while (light)
{
light->mShadowmapIndex = 1024;

View File

@ -287,7 +287,10 @@ void cht_DoCheat (player_t *player, int cheat)
if (i == 4)
{
level.flags2 ^= LEVEL2_ALLMAP;
for (auto Level : AllLevels())
{
Level->flags2 ^= LEVEL2_ALLMAP;
}
}
else if (player->mo != NULL && player->health >= 0)
{

View File

@ -867,13 +867,15 @@ CCMD (dump3df)
{
if (argv.argc() > 1)
{
// Print 3D floor info for a single sector.
// This only checks the primary level.
int sec = (int)strtoll(argv[1], NULL, 10);
if ((unsigned)sec >= level.sectors.Size())
if ((unsigned)sec >= currentUILevel->sectors.Size())
{
Printf("Sector %d does not exist.\n", sec);
return;
}
sector_t *sector = &level.sectors[sec];
sector_t *sector = &currentUILevel->sectors[sec];
TArray<F3DFloor*> & ffloors=sector->e->XFloor.ffloors;
for (unsigned int i = 0; i < ffloors.Size(); i++)

View File

@ -147,7 +147,10 @@ FRandom pr_spawnmobj ("SpawnActor");
CUSTOM_CVAR (Float, sv_gravity, 800.f, CVAR_SERVERINFO|CVAR_NOSAVE)
{
level.gravity = self;
for (auto Level : AllLevels())
{
Level->gravity = self;
}
}
CVAR (Bool, cl_missiledecals, true, CVAR_ARCHIVE)
@ -3021,9 +3024,11 @@ int FLevelLocals::FindUniqueTID(int start_tid, int limit)
CCMD(utid)
{
Printf("%d\n",
level.FindUniqueTID(argv.argc() > 1 ? atoi(argv[1]) : 0,
(argv.argc() > 2 && atoi(argv[2]) >= 0) ? atoi(argv[2]) : 0));
for (auto Level : AllLevels())
{
Printf("%s, %d\n", Level->MapName.GetChars(), Level->FindUniqueTID(argv.argc() > 1 ? atoi(argv[1]) : 0,
(argv.argc() > 2 && atoi(argv[2]) >= 0) ? atoi(argv[2]) : 0));
}
}
//==========================================================================

View File

@ -466,7 +466,7 @@ FBlockNode *FBlockNode::Create(AActor *who, int x, int y, int group)
{
block = (FBlockNode *)secnodearena.Alloc(sizeof(FBlockNode));
}
block->BlockIndex = x + y * level.blockmap.bmapwidth;
block->BlockIndex = x + y * who->Level->blockmap.bmapwidth;
block->Me = who;
block->NextActor = nullptr;
block->PrevActor = nullptr;
@ -479,4 +479,4 @@ void FBlockNode::Release()
{
NextBlock = FreeBlocks;
FreeBlocks = this;
}
}

View File

@ -594,39 +594,43 @@ static void P_Shutdown ()
CCMD(dumpgeometry)
{
for (auto &sector : level.sectors)
for (auto Level : AllLevels())
{
Printf(PRINT_LOG, "Sector %d\n", sector.sectornum);
for (int j = 0; j<sector.subsectorcount; j++)
Printf("Geometry for %s\n", Level->MapName.GetChars());
for (auto &sector : Level->sectors)
{
subsector_t * sub = sector.subsectors[j];
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++)
Printf(PRINT_LOG, "Sector %d\n", sector.sectornum);
for (int j = 0; j<sector.subsectorcount; j++)
{
seg_t * seg = sub->firstline + k;
if (seg->linedef)
subsector_t * sub = sector.subsectors[j];
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++)
{
Printf(PRINT_LOG, " (%4.4f, %4.4f), (%4.4f, %4.4f) - seg %d, linedef %d, side %d",
seg->v1->fX(), seg->v1->fY(), seg->v2->fX(), seg->v2->fY(),
seg->Index(), seg->linedef->Index(), seg->sidedef != seg->linedef->sidedef[0]);
seg_t * seg = sub->firstline + k;
if (seg->linedef)
{
Printf(PRINT_LOG, " (%4.4f, %4.4f), (%4.4f, %4.4f) - seg %d, linedef %d, side %d",
seg->v1->fX(), seg->v1->fY(), seg->v2->fX(), seg->v2->fY(),
seg->Index(), seg->linedef->Index(), seg->sidedef != seg->linedef->sidedef[0]);
}
else
{
Printf(PRINT_LOG, " (%4.4f, %4.4f), (%4.4f, %4.4f) - seg %d, miniseg",
seg->v1->fX(), seg->v1->fY(), seg->v2->fX(), seg->v2->fY(), seg->Index());
}
if (seg->PartnerSeg)
{
subsector_t * sub2 = seg->PartnerSeg->Subsector;
Printf(PRINT_LOG, ", back sector = %d, real back sector = %d", sub2->render_sector->sectornum, seg->PartnerSeg->frontsector->sectornum);
}
else if (seg->backsector)
{
Printf(PRINT_LOG, ", back sector = %d (no partnerseg)", seg->backsector->sectornum);
}
Printf(PRINT_LOG, "\n");
}
else
{
Printf(PRINT_LOG, " (%4.4f, %4.4f), (%4.4f, %4.4f) - seg %d, miniseg",
seg->v1->fX(), seg->v1->fY(), seg->v2->fX(), seg->v2->fY(), seg->Index());
}
if (seg->PartnerSeg)
{
subsector_t * sub2 = seg->PartnerSeg->Subsector;
Printf(PRINT_LOG, ", back sector = %d, real back sector = %d", sub2->render_sector->sectornum, seg->PartnerSeg->frontsector->sectornum);
}
else if (seg->backsector)
{
Printf(PRINT_LOG, ", back sector = %d (no partnerseg)", seg->backsector->sectornum);
}
Printf(PRINT_LOG, "\n");
}
}
}
@ -640,14 +644,18 @@ CCMD(dumpgeometry)
CCMD(listmapsections)
{
for (int i = 0; i < 100; i++)
for (auto Level : AllLevels())
{
for (auto &sub : level.subsectors)
Printf("Map sections for %s:\n", Level->MapName.GetChars());
for (int i = 0; i < 100; i++)
{
if (sub.mapsection == i)
for (auto &sub : Level->subsectors)
{
Printf("Mapsection %d, sector %d, line %d\n", i, sub.render_sector->Index(), sub.firstline->linedef->Index());
break;
if (sub.mapsection == i)
{
Printf("Mapsection %d, sector %d, line %d\n", i, sub.render_sector->Index(), sub.firstline->linedef->Index());
break;
}
}
}
}
@ -661,9 +669,8 @@ CCMD(listmapsections)
CUSTOM_CVAR(Bool, forcewater, false, CVAR_ARCHIVE | CVAR_SERVERINFO)
{
if (gamestate == GS_LEVEL)
if (gamestate == GS_LEVEL) for (auto Level : AllLevels())
{
auto Level = currentUILevel;
for (auto &sec : Level->sectors)
{
sector_t *hsec = sec.GetHeightSec();

View File

@ -316,7 +316,10 @@ void FTagManager::DumpTags()
CCMD(dumptags)
{
level.tagManager.DumpTags();
for (auto Level : AllLevels())
{
Level->tagManager.DumpTags();
}
}
//-----------------------------------------------------------------------------
@ -369,7 +372,7 @@ int FSectorTagIterator::NextCompat(bool compat, int start)
for (unsigned i = start + 1; i < tagManager.Level->sectors.Size(); i++)
{
if (level.SectorHasTag(i, searchtag)) return i;
if (tagManager.Level->SectorHasTag(i, searchtag)) return i;
}
return -1;
}

View File

@ -1208,14 +1208,18 @@ bool FLevelLocals::CollectConnectedGroups(int startgroup, const DVector3 &positi
CCMD(dumplinktable)
{
for (int x = 1; x < level.Displacements.size; x++)
for (auto Level : AllLevels())
{
for (int y = 1; y < level.Displacements.size; y++)
Printf("Portal displacements for %s:\n", Level->MapName.GetChars());
for (int x = 1; x < Level->Displacements.size; x++)
{
FDisplacement &disp = level.Displacements(x, y);
Printf("%c%c(%6d, %6d)", TEXTCOLOR_ESCAPE, 'C' + disp.indirect, int(disp.pos.X), int(disp.pos.Y));
for (int y = 1; y < Level->Displacements.size; y++)
{
FDisplacement &disp = Level->Displacements(x, y);
Printf("%c%c(%6d, %6d)", TEXTCOLOR_ESCAPE, 'C' + disp.indirect, int(disp.pos.X), int(disp.pos.Y));
}
Printf("\n");
}
Printf("\n");
}
}

View File

@ -813,9 +813,10 @@ public:
//
//=============================================================================
void PrintSections(FSectionContainer &container)
void PrintSections(FLevelLocals *Level)
{
auto Level = &level;
FSectionContainer &container = Level->sections;
Printf("Sections for %s\n", Level->MapName.GetChars());
for (unsigned i = 0; i < container.allSections.Size(); i++)
{
auto &section = container.allSections[i];
@ -852,7 +853,7 @@ void PrintSections(FSectionContainer &container)
}
}
}
Printf(PRINT_LOG, "%d sectors, %d subsectors, %d sections\n", Level->sectors.Size(), Level->subsectors.Size(), container.allSections.Size());
Printf(PRINT_LOG, "%d sectors, %d subsectors, %d sections\n\n", Level->sectors.Size(), Level->subsectors.Size(), container.allSections.Size());
}
@ -876,7 +877,10 @@ void CreateSections(FLevelLocals *Level)
CCMD(printsections)
{
PrintSections(level.sections);
for (auto Level : AllLevels())
{
PrintSections(Level);
}
}

View File

@ -1029,7 +1029,7 @@ void R_SetupFrame (FRenderViewpoint &viewpoint, FViewWindow &viewwindow, AActor
// However, to set up a projection matrix this needs to be adjusted.
double radPitch = viewpoint.Angles.Pitch.Normalized180().Radians();
double angx = cos(radPitch);
double angy = sin(radPitch) * level.info->pixelstretch;
double angy = sin(radPitch) * actor->Level->info->pixelstretch;
double alen = sqrt(angx*angx + angy*angy);
viewpoint.HWAngles.Pitch = RAD2DEG((float)asin(angy / alen));

View File

@ -524,7 +524,10 @@ CCMD (testfade)
{
color = V_GetColorFromString (NULL, argv[1]);
}
level.fadeto = color;
for (auto Level : AllLevels())
{
Level->fadeto = color;
}
NormalLight.ChangeFade (color);
}
}