static void RetargetStatePointers (intptr_t count, const char *target, TArray<FStateDefine> & statelist) { for(unsigned i = 0;i<statelist.Size(); i++) { if (statelist[i].State == (FState*)count) { statelist[i].State = target == NULL ? NULL : (FState *)copystring (target); } if (statelist[i].Children.Size() > 0) { RetargetStatePointers(count, target, statelist[i].Children); } } }
static void AddAmmoToList(AWeapon * weapdef) { for(int i=0; i<2;i++) { const PClass * ti = i==0? weapdef->AmmoType1 : weapdef->AmmoType2; if (ti) { AAmmo * ammodef=(AAmmo*)GetDefaultByType(ti); if (ammodef && !(ammodef->ItemFlags&IF_INVBAR)) { unsigned int j; for(j=0;j<orderedammos.Size();j++) { if (ti == orderedammos[j]) break; } if (j==orderedammos.Size()) orderedammos.Push(ti); } } } }
TArray<uint8_t> SndFileDecoder::readAll() { if(SndInfo.frames <= 0) return SoundDecoder::readAll(); int framesize = 2 * SndInfo.channels; TArray<uint8_t> output; output.Resize((unsigned)(SndInfo.frames * framesize)); size_t got = read((char*)&output[0], output.Size()); output.Resize((unsigned)got); return output; }
//============================================================================= // // // //============================================================================= void MergeLines(FGLSectionLoop *loop) { int i; int deleted = 0; FGLSectionLine *ln1; FGLSectionLine *ln2; // Merge identical lines in the list for(i = loop->numlines - 1; i > 0; i--) { ln1 = loop->GetLine(i); ln2 = loop->GetLine(i-1); if (ln1->sidedef == ln2->sidedef && ln1->otherside == ln2->otherside) { // identical references. These 2 lines can be merged. ln2->end = ln1->end; SectionLines.Delete(loop->startline + i); loop->numlines--; deleted++; } } // If we started in the middle of a sidedef the first and last lines // may reference the same sidedef. check that, too. int loopstart = 0; ln1 = loop->GetLine(0); for(i = loop->numlines - 1; i > 0; i--) { ln2 = loop->GetLine(i); if (ln1->sidedef != ln2->sidedef || ln1->otherside != ln2->otherside) break; } if (i < loop->numlines-1) { i++; ln2 = loop->GetLine(i); ln1->start = ln2->start; SectionLines.Delete(loop->startline + i, loop->numlines - i); deleted += loop->numlines - i; loop->numlines = i; } // Adjust all following loops for(unsigned ii = unsigned(loop - &SectionLoops[0]) + 1; ii < SectionLoops.Size(); ii++) { SectionLoops[ii].startline -= deleted; } }
void gl_PrintStartupLog() { int v = 0; if (!gl.legacyMode) glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &v); Printf ("GL_VENDOR: %s\n", glGetString(GL_VENDOR)); Printf ("GL_RENDERER: %s\n", glGetString(GL_RENDERER)); Printf ("GL_VERSION: %s (%s profile)\n", glGetString(GL_VERSION), (v & GL_CONTEXT_CORE_PROFILE_BIT)? "Core" : "Compatibility"); Printf ("GL_SHADING_LANGUAGE_VERSION: %s\n", glGetString(GL_SHADING_LANGUAGE_VERSION)); Printf (PRINT_LOG, "GL_EXTENSIONS:"); for (unsigned i = 0; i < m_Extensions.Size(); i++) { Printf(PRINT_LOG, " %s", m_Extensions[i].GetChars()); } glGetIntegerv(GL_MAX_TEXTURE_SIZE, &v); Printf("\nMax. texture size: %d\n", v); glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &v); Printf ("Max. texture units: %d\n", v); glGetIntegerv(GL_MAX_VARYING_FLOATS, &v); Printf ("Max. varying: %d\n", v); if (!gl.legacyMode && !(gl.flags & RFL_SHADER_STORAGE_BUFFER)) { glGetIntegerv(GL_MAX_UNIFORM_BLOCK_SIZE, &v); Printf ("Max. uniform block size: %d\n", v); glGetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, &v); Printf ("Uniform block alignment: %d\n", v); } if (gl.flags & RFL_SHADER_STORAGE_BUFFER) { glGetIntegerv(GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS, &v); Printf("Max. combined shader storage blocks: %d\n", v); glGetIntegerv(GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS, &v); Printf("Max. vertex shader storage blocks: %d\n", v); } // For shader-less, the special alphatexture translation must be changed to actually set the alpha, because it won't get translated by a shader. if (gl.legacyMode) { FRemapTable *remap = translationtables[TRANSLATION_Standard][8]; for (int i = 0; i < 256; i++) { remap->Remap[i] = i; remap->Palette[i] = PalEntry(i, 255, 255, 255); } } }
int P_FindTerrain (FName name) { unsigned int i; if (name == NAME_Null) return -1; for (i = 0; i < Terrains.Size (); i++) { if (Terrains[i].Name == name) { return (int)i; } } return -1; }
static void StoreLevelStats() { unsigned int i; if (gamestate != GS_LEVEL) return; if (!(level.flags2&LEVEL2_NOSTATISTICS)) // don't consider maps that were excluded from statistics { for(i=0;i<LevelData.Size();i++) { if (!stricmp(LevelData[i].levelname, level.MapName)) break; } if (i==LevelData.Size()) { LevelData.Reserve(1); strncpy(LevelData[i].levelname, level.MapName, 8); LevelData[i].levelname[8] = 0; } LevelData[i].totalkills = level.total_monsters; LevelData[i].killcount = level.killed_monsters; LevelData[i].totalsecrets = level.total_secrets; LevelData[i].secretcount = level.found_secrets; LevelData[i].leveltime = AdjustTics(level.maptime); // Check for living monsters. On some maps it can happen // that the counter misses some. TThinkerIterator<AActor> it; AActor *ac; int mc = 0; while ((ac = it.Next())) { if ((ac->flags & MF_COUNTKILL) && ac->health > 0) mc++; } if (mc == 0) LevelData[i].killcount = LevelData[i].totalkills; } }
int ParseUMapInfo(int lumpnum) { FScanner scanner(lumpnum); unsigned int i; while (scanner.GetToken()) { scanner.TokenMustBe(TK_Map); UMapEntry parsed; ParseMapEntry(scanner, &parsed); // Endpic overrides level exits. if (parsed.endpic[0]) { parsed.nextmap[0] = parsed.nextsecret[0] = 0; if (parsed.endpic[0] == '!') parsed.endpic[0] = 0; } /* else if (!parsed.nextmap[0] && !parsed.endpic[0]) { if (!parsed.MapName.CompareNoCase("MAP30")) uppercopy(parsed.endpic, "$CAST"); else if (!parsed.MapName.CompareNoCase("E1M8")) uppercopy(parsed.endpic, gameinfo.creditPages.Last()); else if (!parsed.MapName.CompareNoCase("E2M8")) uppercopy(parsed.endpic, "VICTORY"); else if (!parsed.MapName.CompareNoCase("E3M8")) uppercopy(parsed.endpic, "$BUNNY"); else if (!parsed.MapName.CompareNoCase("E4M8")) uppercopy(parsed.endpic, "ENDPIC"); else if (gameinfo.gametype == GAME_Chex && !parsed.MapName.CompareNoCase("E1M5")) uppercopy(parsed.endpic, "CREDIT"); else { parsed.nextmap[0] = 0; // keep previous setting } } */ // Does this property already exist? If yes, replace it. for(i = 0; i < Maps.Size(); i++) { if (!parsed.MapName.Compare(Maps[i].MapName)) { Maps[i] = parsed; return 1; } } // Not found so create a new one. Maps.Push(parsed); } return 1; }
void gl_InitPortals() { TThinkerIterator<AStackPoint> it; AStackPoint *pt; while ((pt = it.Next())) { FPortal *portal = NULL; int plane; for(int i=0;i<numsectors;i++) { if (sectors[i].linecount == 0) { continue; } else if (sectors[i].FloorSkyBox == pt) { plane = 1; } else if (sectors[i].CeilingSkyBox == pt) { plane = 2; } else continue; // we only process portals that actually are in use. if (portal == NULL) { pt->special1 = portals.Size(); // Link portal thing to render data portal = &portals[portals.Reserve(1)]; portal->origin = pt; portal->plane = 0; portal->xDisplacement = pt->x - pt->Mate->x; portal->yDisplacement = pt->y - pt->Mate->y; } portal->AddSectorToPortal(§ors[i]); portal->plane|=plane; } if (portal != NULL) { // if the first vertex is duplicated at the end it'll save time in a time critical function // because that code does not need to check for wraparounds anymire. portal->Shape.Resize(portal->Shape.Size()+1); portal->Shape[portal->Shape.Size()-1] = portal->Shape[0]; portal->Shape.ShrinkToFit(); portal->ClipAngles.Resize(portal->Shape.Size()); } } }
static void G_SerializeHub(FArchive & arc) { int i=hubdata.Size(); arc << i; if (i>0) { if (arc.IsStoring()) arc.Write(&hubdata[0], i * sizeof(wbstartstruct_t)); else { hubdata.Resize(i); arc.Read(&hubdata[0], i * sizeof(wbstartstruct_t)); } } else hubdata.Clear(); }
PClassWeapon *Net_ReadWeapon(BYTE **stream) { int index; index = ReadByte(stream); if (index & 0x80) { index = (index & 0x7F) | (ReadByte(stream) << 7); } if ((unsigned)index >= Weapons_ntoh.Size()) { return NULL; } return Weapons_ntoh[index]; }
static FStateDefine * FindStateAddress(const char * name) { static TArray<FName> namelist(3); FStateDefine * statedef=NULL; MakeStateNameList(name, &namelist); TArray<FStateDefine> * statelist = &StateLabels; for(unsigned i=0;i<namelist.Size();i++) { statedef = FindStateLabelInList(*statelist, namelist[i], true); statelist = &statedef->Children; } return statedef; }
static void MakeStateList(const FStateLabels *list, TArray<FStateDefine> &dest) { dest.Clear(); if (list != NULL) for(int i=0;i<list->NumLabels;i++) { FStateDefine def; def.Label = list->Labels[i].Label; def.State = list->Labels[i].State; dest.Push(def); if (list->Labels[i].Children != NULL) { MakeStateList(list->Labels[i].Children, dest[dest.Size()-1].Children); } } }
FState * FindState(AActor * actor, const PClass * type, const char * name) { static TArray<FName> namelist(3); FStateDefine * statedef=NULL; MakeStateNameList(name, &namelist); TArray<FStateDefine> * statelist = &StateLabels; for(unsigned i=0;i<namelist.Size();i++) { statedef = FindStateLabelInList(*statelist, namelist[i], false); if (statedef == NULL) return NULL; statelist = &statedef->Children; } return statedef? statedef->State : NULL; }
static void ResampleBoxPrecalc(TArray<BoxPrecalc>& boxes, int oldDim) { int newDim = boxes.Size(); const double scale_factor_1 = double(oldDim) / newDim; const int scale_factor_2 = (int)(scale_factor_1 / 2); for (int dst = 0; dst < newDim; ++dst) { // Source pixel in the Y direction const int src_p = int(dst * scale_factor_1); BoxPrecalc& precalc = boxes[dst]; precalc.boxStart = clamp<int>(int(src_p - scale_factor_1 / 2.0 + 1), 0, oldDim - 1); precalc.boxEnd = clamp<int>(MAX<int>(precalc.boxStart + 1, int(src_p + scale_factor_2)), 0, oldDim - 1); } }
void FStateDefinitions::FixStatePointers (PClassActor *actor, TArray<FStateDefine> & list) { for (unsigned i = 0; i < list.Size(); i++) { if (list[i].DefineFlags == SDF_INDEX) { size_t v = (size_t)list[i].State; list[i].State = actor->OwnedStates + v - 1; list[i].DefineFlags = SDF_STATE; } if (list[i].Children.Size() > 0) { FixStatePointers(actor, list[i].Children); } } }
void gl_SetActorLights(AActor *actor) { TArray<FInternalLightAssociation *> * l = gl_GetActorLights(actor); unsigned int count = 0; All.Clock(); if (actor->state == NULL) return; if (l) { TArray<FInternalLightAssociation *> & LightAssociations=*l; ADynamicLight *lights, *tmpLight; unsigned int i; int sprite = actor->sprite; int frame = actor->frame; lights = tmpLight = NULL; for (i = 0; i < LightAssociations.Size(); i++) { if (LightAssociations[i]->Sprite() == sprite && (LightAssociations[i]->Frame()==frame || LightAssociations[i]->Frame()==-1)) { gl_AttachLight(actor, count++, LightAssociations[i]->Light()); } } } if (count == 0 && actor->state->Light > 0) { for(int i= actor->state->Light; StateLights[i] != NULL; i++) { if (StateLights[i] != (FLightDefaults*)-1) { gl_AttachLight(actor, count++, StateLights[i]); } } } for(;count<actor->dynamiclights.Size();count++) { actor->dynamiclights[count]->flags2|=MF2_DORMANT; memset(actor->dynamiclights[count]->args, 0, sizeof(actor->args)); } All.Unclock(); }
void C_BackupCVars (void) { assert(CVarBackups.Size() == 0); CVarBackups.Clear(); FCVarBackup backup; for (FBaseCVar *cvar = CVars; cvar != NULL; cvar = cvar->m_Next) { if ((cvar->Flags & (CVAR_SERVERINFO|CVAR_DEMOSAVE)) && !(cvar->Flags & CVAR_LATCH)) { backup.Name = cvar->GetName(); backup.String = cvar->GetGenericRep(CVAR_String).String; CVarBackups.Push(backup); } } }
uint32_t R_ColormapNumForName (const char *name) { if (strnicmp (name, "COLORMAP", 8)) { // COLORMAP always returns 0 for(int i=fakecmaps.Size()-1; i > 0; i--) { if (!strnicmp(name, fakecmaps[i].name, 8)) { return i; } } if (!strnicmp (name, "WATERMAP", 8)) return MAKEARGB (128,0,0x4f,0xa5); } return 0; }
//============================================================================= // // // //============================================================================= void tesselateSections() { // init tesselator GLUtesselator *tess = gluNewTess(); if (!tess) { return; } // set callbacks gluTessCallback(tess, GLU_TESS_BEGIN_DATA, (tessFunc)cbTessBegin); gluTessCallback(tess, GLU_TESS_VERTEX_DATA, (tessFunc)cbTessVertex); gluTessCallback(tess, GLU_TESS_ERROR_DATA, (tessFunc)cbTessError); gluTessCallback(tess, GLU_TESS_COMBINE, (tessFunc)cbTessCombine); gluTessCallback(tess, GLU_TESS_END_DATA, (tessFunc)cbTessEnd); for(unsigned int i=0;i<Sections.Size(); i++) { FGLSection *sect = &Sections[i]; gluTessBeginPolygon(tess, sect); for(int j=0; j< sect->numloops; j++) { gluTessBeginContour(tess); FGLSectionLoop *loop = sect->GetLoop(j); for(int k=0; k<loop->numlines; k++) { FGLSectionLine *line = loop->GetLine(k); vertex_t *vert = line->start; GLdouble v[3] = { -(double)vert->x/(double)FRACUNIT, // negate to get proper winding 0.0, (double)vert->y/(double)FRACUNIT }; gluTessVertex(tess, v, (void*)(vert - vertexes)); } gluTessEndContour(tess); } gluTessEndPolygon(tess); sect->vertices.Push(-1337); sect->vertices.ShrinkToFit(); } gluDeleteTess(tess); }
void gl_AddLightDefaults(FLightDefaults *defaults) { FLightDefaults *temp; unsigned int i; // remove duplicates for (i = 0; i < LightDefaults.Size(); i++) { temp = LightDefaults[i]; if (temp->GetName() == defaults->GetName()) { delete temp; LightDefaults.Delete(i); break; } } LightDefaults.Push(defaults); }
void DBaseDecal::SpreadLeft (fixed_t r, vertex_t *v1, side_t *feelwall, F3DFloor *ffloor) { fixed_t ldx, ldy; SpreadStack.Push (feelwall); while (r < 0 && feelwall->LeftSide != NO_SIDE) { fixed_t startr = r; fixed_t x = v1->x; fixed_t y = v1->y; feelwall = &sides[feelwall->LeftSide]; GetWallStuff (feelwall, v1, ldx, ldy); fixed_t wallsize = Length (ldx, ldy); r += DecalLeft; x += Scale (r, ldx, wallsize); y += Scale (r, ldy, wallsize); r = wallsize + startr; SpreadSource->CloneSelf (SpreadTemplate, x, y, SpreadZ, feelwall, ffloor); SpreadStack.Push (feelwall); side_t *nextwall = NextWall (feelwall); if (nextwall != NULL && nextwall->LeftSide != NO_SIDE) { int i; for (i = SpreadStack.Size(); i-- > 0; ) { if (SpreadStack[i] == nextwall) break; } if (i == -1) { vertex_t *v2; GetWallStuff (nextwall, v2, ldx, ldy); SpreadLeft (startr, v2, nextwall, ffloor); } } } }
void DBaseDecal::SpreadLeft (double r, vertex_t *v1, side_t *feelwall, F3DFloor *ffloor) { double ldx, ldy; SpreadStack.Push (feelwall); while (r < 0 && feelwall->LeftSide != NO_SIDE) { double startr = r; double x = v1->fX(); double y = v1->fY(); feelwall = &level.sides[feelwall->LeftSide]; GetWallStuff (feelwall, v1, ldx, ldy); double wallsize = Length (ldx, ldy); r += DecalLeft; x += r*ldx / wallsize; y += r*ldy / wallsize; r = wallsize + startr; SpreadSource->CloneSelf (SpreadTemplate, x, y, SpreadZ, feelwall, ffloor); SpreadStack.Push (feelwall); side_t *nextwall = NextWall (feelwall); if (nextwall != NULL && nextwall->LeftSide != NO_SIDE) { int i; for (i = SpreadStack.Size(); i-- > 0; ) { if (SpreadStack[i] == nextwall) break; } if (i == -1) { vertex_t *v2; GetWallStuff (nextwall, v2, ldx, ldy); SpreadLeft (startr, v2, nextwall, ffloor); } } } }
void FShaderManager::CompileShaders() { mActiveShader = NULL; mTextureEffects.Clear(); mTextureEffectsNAT.Clear(); for (int i = 0; i < MAX_EFFECTS; i++) { mEffectShaders[i] = NULL; } for(int i=0;defaultshaders[i].ShaderName != NULL;i++) { FShader *shc = Compile(defaultshaders[i].ShaderName, defaultshaders[i].gettexelfunc, true); mTextureEffects.Push(shc); if (i <= 3) { FShader *shc = Compile(defaultshaders[i].ShaderName, defaultshaders[i].gettexelfunc, false); mTextureEffectsNAT.Push(shc); } } for(unsigned i = 0; i < usershaders.Size(); i++) { FString name = ExtractFileBase(usershaders[i]); FName sfn = name; FShader *shc = Compile(sfn, usershaders[i], true); mTextureEffects.Push(shc); } for(int i=0;i<MAX_EFFECTS;i++) { FShader *eff = new FShader(effectshaders[i].ShaderName); if (!eff->Load(effectshaders[i].ShaderName, effectshaders[i].vp, effectshaders[i].fp1, effectshaders[i].fp2, effectshaders[i].defines)) { delete eff; } else mEffectShaders[i] = eff; } }
void gl_AddLightAssociation(const char *actor, const char *frame, const char *light) { FLightAssociation *temp; unsigned int i; FLightAssociation assoc(actor, frame, light); for (i = 0; i < LightAssociations.Size(); i++) { temp = &LightAssociations[i]; if (temp->ActorName() == assoc.ActorName()) { if (strcmp(temp->FrameName(), assoc.FrameName()) == 0) { temp->ReplaceLightName(assoc.Light()); return; } } } LightAssociations.Push(assoc); }
static void SerializeStatistics(FArchive &arc) { FString startlevel; int i = LevelData.Size(); arc << i; if (arc.IsLoading()) { arc << startlevel; StartEpisode = NULL; for(unsigned int j=0;j<AllEpisodes.Size();j++) { if (!AllEpisodes[j].mEpisodeMap.CompareNoCase(startlevel)) { StartEpisode = &AllEpisodes[j]; break; } } LevelData.Resize(i); } else { if (StartEpisode != NULL) startlevel = StartEpisode->mEpisodeMap; arc << startlevel; } for(int j = 0; j < i; j++) { OneLevel &l = LevelData[j]; arc << l.totalkills << l.killcount << l.totalsecrets << l.secretcount << l.leveltime; if (arc.IsStoring()) arc.WriteName(l.levelname); else strcpy(l.levelname, arc.ReadName()); } }
void InitThingdef() { // Sort the flag lists for (size_t i = 0; i < NUM_FLAG_LISTS; ++i) { qsort (FlagLists[i].Defs, FlagLists[i].NumDefs, sizeof(FFlagDef), flagcmp); } // Create a sorted list of properties if (properties.Size() == 0) { FAutoSegIterator probe(GRegHead, GRegTail); while (*++probe != NULL) { properties.Push((FPropertyInfo *)*probe); } properties.ShrinkToFit(); qsort(&properties[0], properties.Size(), sizeof(properties[0]), propcmp); } // Create a sorted list of native action functions if (AFTable.Size() == 0) { FAutoSegIterator probe(ARegHead, ARegTail); while (*++probe != NULL) { AFTable.Push(*(AFuncDesc *)*probe); } AFTable.ShrinkToFit(); qsort(&AFTable[0], AFTable.Size(), sizeof(AFTable[0]), funccmp); } // Create a sorted list of native variables if (variables.Size() == 0) { FAutoSegIterator probe(MRegHead, MRegTail); while (*++probe != NULL) { variables.Push((FVariableInfo *)*probe); } variables.ShrinkToFit(); qsort(&variables[0], variables.Size(), sizeof(variables[0]), varcmp); } }
void DBaseDecal::SpreadRight (fixed_t r, side_t *feelwall, fixed_t wallsize, F3DFloor *ffloor) { vertex_t *v1; fixed_t x, y, ldx, ldy; SpreadStack.Push (feelwall); while (r > wallsize && feelwall->RightSide != NO_SIDE) { feelwall = &sides[feelwall->RightSide]; side_t *nextwall = NextWall (feelwall); if (nextwall != NULL && nextwall->LeftSide != NO_SIDE) { int i; for (i = SpreadStack.Size(); i-- > 0; ) { if (SpreadStack[i] == nextwall) break; } if (i == -1) { SpreadRight (r, nextwall, wallsize, ffloor); } } r = DecalWidth - r + wallsize - DecalLeft; GetWallStuff (feelwall, v1, ldx, ldy); x = v1->x; y = v1->y; wallsize = Length (ldx, ldy); x -= Scale (r, ldx, wallsize); y -= Scale (r, ldy, wallsize); r = DecalRight - r; SpreadSource->CloneSelf (SpreadTemplate, x, y, SpreadZ, feelwall, ffloor); SpreadStack.Push (feelwall); } }
void FShaderManager::CompileShaders() { mActiveShader = mEffectShaders[0] = mEffectShaders[1] = NULL; if (gl.shadermodel > 0) { for(int i=0;defaultshaders[i].ShaderName != NULL;i++) { FShaderContainer * shc = new FShaderContainer(defaultshaders[i].ShaderName, defaultshaders[i].gettexelfunc); mTextureEffects.Push(shc); if (gl.shadermodel <= 2) return; // SM2 will only initialize the default shader } for(unsigned i = 0; i < usershaders.Size(); i++) { FString name = ExtractFileBase(usershaders[i]); FName sfn = name; if (gl.shadermodel > 2) { FShaderContainer * shc = new FShaderContainer(sfn, usershaders[i]); mTextureEffects.Push(shc); } } if (gl.shadermodel > 2) { for(int i=0;i<NUM_EFFECTS;i++) { FShader *eff = new FShader(); if (!eff->Load(effectshaders[i].ShaderName, effectshaders[i].vp, effectshaders[i].fp1, effectshaders[i].fp2, effectshaders[i].defines)) { delete eff; } else mEffectShaders[i] = eff; } } } }
void MapLoader::IterFindPolySides (FPolyObj *po, side_t *side) { static TArray<uint32_t> vnum; unsigned int vnumat; assert(sidetemp.Size() > 0); vnum.Clear(); vnum.Push(uint32_t(Index(side->V1()))); vnumat = 0; while (vnum.Size() != vnumat) { uint32_t sidenum = sidetemp[vnum[vnumat++]].b.first; while (sidenum != NO_SIDE) { po->Sidedefs.Push(&Level->sides[sidenum]); AddPolyVert(vnum, uint32_t(Index(Level->sides[sidenum].V2()))); sidenum = sidetemp[sidenum].b.next; } } }