void FBlurShader::ComputeBlurSamples(int sampleCount, float blurAmount, TArray<float> &sampleWeights, TArray<int> &sampleOffsets) { sampleWeights.Resize(sampleCount); sampleOffsets.Resize(sampleCount); sampleWeights[0] = ComputeGaussian(0, blurAmount); sampleOffsets[0] = 0; float totalWeights = sampleWeights[0]; for (int i = 0; i < sampleCount / 2; i++) { float weight = ComputeGaussian(i + 1.0f, blurAmount); sampleWeights[i * 2 + 1] = weight; sampleWeights[i * 2 + 2] = weight; sampleOffsets[i * 2 + 1] = i + 1; sampleOffsets[i * 2 + 2] = -i - 1; totalWeights += weight * 2; } for (int i = 0; i < sampleCount; i++) { sampleWeights[i] /= totalWeights; } }
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 P_ReadDemoWeaponsChunk(BYTE **demo) { int count, i; PClassWeapon *type; const char *s; count = ReadWord(demo); Weapons_ntoh.Resize(count); Weapons_hton.Clear(count); Weapons_ntoh[0] = type = NULL; Weapons_hton[type] = 0; for (i = 1; i < count; ++i) { s = ReadStringConst(demo); type = dyn_cast<PClassWeapon>(PClass::FindClass(s)); // If a demo was recorded with a weapon that is no longer present, // should we report it? Weapons_ntoh[i] = type; if (type != NULL) { Weapons_hton[type] = i; } } }
void InitSWColorMaps() { DeinitSWColorMaps(); atterm(DeinitSWColorMaps); InitBoomColormaps(); NormalLight.Color = PalEntry (255, 255, 255); NormalLight.Fade = 0; NormalLight.Maps = realcolormaps.Maps; NormalLightHasFixedLights = R_CheckForFixedLights(realcolormaps.Maps); // [SP] Create a copy of the colormap if (!realfbcolormaps.Maps) { realfbcolormaps.Maps = new uint8_t[256*NUMCOLORMAPS*fakecmaps.Size()]; memcpy(realfbcolormaps.Maps, realcolormaps.Maps, 256*NUMCOLORMAPS*fakecmaps.Size()); } FullNormalLight.Color = PalEntry(255, 255, 255); FullNormalLight.Fade = 0; FullNormalLight.Maps = realfbcolormaps.Maps; SpecialSWColormaps.Resize(SpecialColormaps.Size()); for(unsigned i = 0; i < SpecialColormaps.Size(); i++) { SpecialSWColormaps[i].Maps = SpecialColormaps[i].Colormap; } }
void STAT_Serialize(FSerializer &arc) { FString startlevel; int i = LevelData.Size(); if (arc.BeginObject("statistics")) { if (arc.isReading()) { arc("startlevel", 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", startlevel); } arc("levels", LevelData); arc.EndObject(); } }
// TODO: exploit a better algorithm, use vertex hash table/map. // void mxRenderMesh::WeldVertices() { TArray< mxVertex > newVerts; newVerts.Resize( GetVertexCount() ); for ( u32 triIdx = 0; triIdx < GetTriangleCount(); triIdx++ ) { IndexTriple & rTri = Triangles[ triIdx ]; for ( TIndex i = 0; i < 3; i++ ) { const mxVertex & rCurrVertex = Vertices[ rTri[i] ]; s32 iExistingVertex = -1; for ( TIndex iVtx = 0; iVtx < newVerts.Num(); iVtx++ ) { if ( VectorsEqual( newVerts[ iVtx ].Pos, rCurrVertex.Pos ) ) { iExistingVertex = iVtx; break; } } if ( iExistingVertex != -1 ) { rTri[ i ] = iExistingVertex; } else { rTri[ i ] = newVerts.Append( mxVertex( rCurrVertex ) ); } } } Vertices = newVerts; }
void gl_InitializeActorLights() { for(unsigned int i=0;i<LightAssociations.Size();i++) { const PClass * ti = PClass::FindClass(LightAssociations[i].ActorName()); if (ti) { ti = GetRealType(ti); AActor * defaults = GetDefaultByType(ti); if (defaults) { FInternalLightAssociation * iasso = new FInternalLightAssociation(&LightAssociations[i]); if (!defaults->lightassociations) { TDeletingArray<FInternalLightAssociation*> *p =new TDeletingArray<FInternalLightAssociation*>; defaults->lightassociations = p; AssoDeleter.Push(p); } TDeletingArray<FInternalLightAssociation *> * lights = gl_GetActorLights(defaults); if (iasso->Light()==NULL) { // The definition was not valid. delete iasso; } else { lights->Push(iasso); } } } } // we don't need the parser data for the light associations anymore LightAssociations.Clear(); LightAssociations.ShrinkToFit(); StateLights.Resize(ParsedStateLights.Size()+1); for(unsigned i=0; i<ParsedStateLights.Size();i++) { if (ParsedStateLights[i] != NAME_None) { StateLights[i] = (FLightDefaults*)-1; // something invalid that's not NULL. for(unsigned int j=0;j<LightDefaults.Size();j++) { if (LightDefaults[j]->GetName() == ParsedStateLights[i]) { StateLights[i] = LightDefaults[j]; break; } } } else StateLights[i] = NULL; } StateLights[StateLights.Size()-1] = NULL; // terminator ParsedStateLights.Clear(); ParsedStateLights.ShrinkToFit(); }
MemoryArrayReader(const char *buffer, long length) { if (length > 0) { buf.Resize(length); memcpy(&buf[0], buffer, length); } UpdateBuffer(); }
void gl_CreateSections() { SectionLines.Clear(); SectionLoops.Clear(); Sections.Clear(); SectionForSubsector.Resize(numsubsectors); memset(&SectionForSubsector[0], -1, numsubsectors * sizeof(SectionForSubsector[0])); FSectionCreator creat; creat.CreateSections(); if (dumpsections) DumpSections(); }
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(); }
void FTextureManager::SortTexturesByType(int start, int end) { TArray<FTexture *> newtextures; // First unlink all newly added textures from the hash chain for (int i = 0; i < HASH_SIZE; i++) { while (HashFirst[i] >= start && HashFirst[i] != HASH_END) { HashFirst[i] = Textures[HashFirst[i]].HashNext; } } newtextures.Resize(end-start); for(int i=start; i<end; i++) { newtextures[i-start] = Textures[i].Texture; } Textures.Resize(start); Translation.Resize(start); static int texturetypes[] = { FTexture::TEX_Sprite, FTexture::TEX_Null, FTexture::TEX_FirstDefined, FTexture::TEX_WallPatch, FTexture::TEX_Wall, FTexture::TEX_Flat, FTexture::TEX_Override, FTexture::TEX_MiscPatch }; for(unsigned int i=0;i<countof(texturetypes);i++) { for(unsigned j = 0; j<newtextures.Size(); j++) { if (newtextures[j] != NULL && newtextures[j]->UseType == texturetypes[i]) { AddTexture(newtextures[j]); newtextures[j] = NULL; } } } // This should never happen. All other UseTypes are only used outside for(unsigned j = 0; j<newtextures.Size(); j++) { if (newtextures[j] != NULL) { Printf("Texture %s has unknown type!\n", newtextures[j]->Name); AddTexture(newtextures[j]); } } }
void FFlatVertexGenerator::CreateIndexedFlatVertices() { TArray<FIndexGenerationInfo> gen; gen.Resize(level.sectors.Size()); // This must be generated up front so that the following code knows how many vertices a sector contains. for (unsigned i = 0; i < level.sectors.Size(); i++) { for (int j = 0; j < level.sectors[i].subsectorcount; j++) { auto sub = level.sectors[i].subsectors[j]; for (unsigned k = 0; k < sub->numlines; k++) { auto vert = sub->firstline[k].v1; gen[i].AddVertex(vert); } } } for (int h = sector_t::floor; h <= sector_t::ceiling; h++) { for (auto &sec : level.sectors) { CreateIndexedVertices(h, &sec, sec.GetSecPlane(h), h == sector_t::floor, gen); } } // We need to do a final check for Vavoom water and FF_FIX sectors. // No new vertices are needed here. The planes come from the actual sector for (auto &sec : level.sectors) { for (auto ff : sec.e->XFloor.ffloors) { if (ff->top.model == &sec) { ff->top.vindex = sec.iboindex[ff->top.isceiling]; } if (ff->bottom.model == &sec) { ff->bottom.vindex = sec.iboindex[ff->top.isceiling]; } } } }
int FFont::SimpleTranslation (uint32_t *colorsused, uint8_t *translation, uint8_t *reverse, TArray<double> &Luminosity) { double min, max, diver; int i, j; memset (translation, 0, 256); reverse[0] = 0; for (i = 1, j = 1; i < 256; i++) { if (colorsused[i]) { reverse[j++] = i; } } qsort (reverse+1, j-1, 1, compare); Luminosity.Resize(j); Luminosity[0] = 0.0; // [BL] Prevent uninitalized memory max = 0.0; min = 100000000.0; for (i = 1; i < j; i++) { translation[reverse[i]] = i; Luminosity[i] = RPART(GPalette.BaseColors[reverse[i]]) * 0.299 + GPART(GPalette.BaseColors[reverse[i]]) * 0.587 + BPART(GPalette.BaseColors[reverse[i]]) * 0.114; if (Luminosity[i] > max) max = Luminosity[i]; if (Luminosity[i] < min) min = Luminosity[i]; } diver = 1.0 / (max - min); for (i = 1; i < j; i++) { Luminosity[i] = (Luminosity[i] - min) * diver; } return j; }
void gl_BuildPortalCoverage(FPortalCoverage *coverage, subsector_t *subsector, FPortal *portal) { TArray<FCoverageVertex> shape; double centerx=0, centery=0; shape.Resize(subsector->numlines); for(unsigned i=0; i<subsector->numlines; i++) { centerx += (shape[i].x = subsector->firstline[i].v1->x + portal->xDisplacement); centery += (shape[i].y = subsector->firstline[i].v1->y + portal->yDisplacement); } FCoverageBuilder build(subsector, portal); build.center.x = xs_CRoundToInt(centerx / subsector->numlines); build.center.y = xs_CRoundToInt(centery / subsector->numlines); build.CollectNode(nodes + numnodes - 1, shape); coverage->subsectors = new DWORD[build.collect.Size()]; coverage->sscount = build.collect.Size(); memcpy(coverage->subsectors, &build.collect[0], build.collect.Size() * sizeof(DWORD)); }
void gl_BuildPortalCoverage(FPortalCoverage *coverage, subsector_t *subsector, const DVector2 &displacement) { TArray<FCoverageVertex> shape; double centerx=0, centery=0; shape.Resize(subsector->numlines); for(unsigned i=0; i<subsector->numlines; i++) { centerx += (shape[i].x = FLOAT2FIXED(subsector->firstline[i].v1->fX() + displacement.X)); centery += (shape[i].y = FLOAT2FIXED(subsector->firstline[i].v1->fY() + displacement.Y)); } FCoverageBuilder build(subsector); build.center.x = xs_CRoundToInt(centerx / subsector->numlines); build.center.y = xs_CRoundToInt(centery / subsector->numlines); build.CollectNode(level.HeadNode(), shape); coverage->subsectors = new uint32_t[build.collect.Size()]; coverage->sscount = build.collect.Size(); memcpy(coverage->subsectors, &build.collect[0], build.collect.Size() * sizeof(uint32_t)); }
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()); } }
unsigned int FModelVertexBuffer::SetupFrame(unsigned int frame1, unsigned int frame2, unsigned int size) { glBindBuffer(GL_ARRAY_BUFFER, vbo_id); if (vbo_id > 0) { if (!gl.legacyMode) { glVertexAttribPointer(VATTR_VERTEX, 3, GL_FLOAT, false, sizeof(FModelVertex), &VMO[frame1].x); glVertexAttribPointer(VATTR_TEXCOORD, 2, GL_FLOAT, false, sizeof(FModelVertex), &VMO[frame1].u); glVertexAttribPointer(VATTR_VERTEX2, 3, GL_FLOAT, false, sizeof(FModelVertex), &VMO[frame2].x); glVertexAttribPointer(VATTR_NORMAL, 4, GL_UNSIGNED_INT_2_10_10_10_REV, false, sizeof(FModelVertex), &VMO[frame2].packedNormal); } else { // only used for single frame models so there is no vertex2 here, which has no use without a shader. glVertexPointer(3, GL_FLOAT, sizeof(FModelVertex), &VMO[frame1].x); glTexCoordPointer(2, GL_FLOAT, sizeof(FModelVertex), &VMO[frame1].u); } } else if (frame1 == frame2 || size == 0 || gl_RenderState.GetInterpolationFactor() == 0.f) { glVertexPointer(3, GL_FLOAT, sizeof(FModelVertex), &vbo_ptr[frame1].x); glTexCoordPointer(2, GL_FLOAT, sizeof(FModelVertex), &vbo_ptr[frame1].u); } else { // must interpolate iBuffer.Resize(size); glVertexPointer(3, GL_FLOAT, sizeof(FModelVertex), &iBuffer[0].x); glTexCoordPointer(2, GL_FLOAT, sizeof(FModelVertex), &vbo_ptr[frame1].u); float frac = gl_RenderState.GetInterpolationFactor(); for (unsigned i = 0; i < size; i++) { iBuffer[i].x = vbo_ptr[frame1 + i].x * (1.f - frac) + vbo_ptr[frame2 + i].x * frac; iBuffer[i].y = vbo_ptr[frame1 + i].y * (1.f - frac) + vbo_ptr[frame2 + i].y * frac; iBuffer[i].z = vbo_ptr[frame1 + i].z * (1.f - frac) + vbo_ptr[frame2 + i].z * frac; } } return frame1; }
bool F7ZFile::Open(bool quiet) { Archive = new C7zArchive(Reader); int skipped = 0; SRes res; res = Archive->Open(); if (res != SZ_OK) { delete Archive; Archive = NULL; if (!quiet) { Printf("\n" TEXTCOLOR_RED "%s: ", Filename); if (res == SZ_ERROR_UNSUPPORTED) { Printf("Decoder does not support this archive\n"); } else if (res == SZ_ERROR_MEM) { Printf("Cannot allocate memory\n"); } else if (res == SZ_ERROR_CRC) { Printf("CRC error\n"); } else { Printf("error #%d\n", res); } } return false; } NumLumps = Archive->DB.db.NumFiles; Lumps = new F7ZLump[NumLumps]; F7ZLump *lump_p = Lumps; TArray<UInt16> nameUTF16; TArray<char> nameASCII; for (DWORD i = 0; i < NumLumps; ++i) { CSzFileItem *file = &Archive->DB.db.Files[i]; // skip Directories if (file->IsDir) { skipped++; continue; } const size_t nameLength = SzArEx_GetFileNameUtf16(&Archive->DB, i, NULL); if (0 == nameLength) { ++skipped; continue; } nameUTF16.Resize(nameLength); nameASCII.Resize(nameLength); SzArEx_GetFileNameUtf16(&Archive->DB, i, &nameUTF16[0]); for (size_t c = 0; c < nameLength; ++c) { nameASCII[c] = static_cast<char>(nameUTF16[c]); } FixPathSeperator(&nameASCII[0]); FString name = &nameASCII[0]; name.ToLower(); lump_p->LumpNameSetup(name); lump_p->LumpSize = int(file->Size); lump_p->Owner = this; lump_p->Flags = LUMPF_ZIPFILE; lump_p->Position = i; lump_p->CheckEmbedded(); lump_p++; } // Resize the lump record array to its actual size NumLumps -= skipped; if (NumLumps > 0) { // Quick check for unsupported compression method TArray<char> temp; temp.Resize(Lumps[0].LumpSize); if (SZ_OK != Archive->Extract(Lumps[0].Position, &temp[0])) { if (!quiet) Printf("\n%s: unsupported 7z/LZMA file!\n", Filename); return false; } } if (!quiet) Printf(", %d lumps\n", NumLumps); // Entries in archives are sorted alphabetically qsort(&Lumps[0], NumLumps, sizeof(F7ZLump), lumpcmp); return true; }
//***************************************************************************** // void SERVER_AUTH_ParsePacket( BYTESTREAM_s *pByteStream ) { while ( 1 ) { const int commandNum = NETWORK_ReadLong( pByteStream ); if ( commandNum == -1 ) break; switch ( commandNum ) { case AUTH_SERVER_NEGOTIATE: { const int protovolVersion = NETWORK_ReadByte( pByteStream ); const unsigned int clientSessionID = NETWORK_ReadLong( pByteStream ); const int sessionID = NETWORK_ReadLong( pByteStream ); const int lenSalt = NETWORK_ReadByte( pByteStream ); TArray<unsigned char> bytesSalt; if ( lenSalt > 0 ) { bytesSalt.Resize( lenSalt ); for ( int i = 0; i < lenSalt; ++i ) bytesSalt[i] = NETWORK_ReadByte( pByteStream ); } else Printf ( "AUTH_SERVER_NEGOTIATE: Invalid length\n" ); const FString username = NETWORK_ReadString( pByteStream ); const int clientID = SERVER_FindClientWithClientSessionID ( clientSessionID ); if ( clientID < MAXPLAYERS ) { // [BB] We need to use the username the auth server sent us. SERVER_GetClient(clientID)->username = username; SERVER_GetClient(clientID)->SRPsessionID = sessionID; SERVER_GetClient(clientID)->salt = bytesSalt; // [BB] Tell the client the true username to start the authentication. SERVERCOMMANDS_SRPUserStartAuthentication ( clientID ); } else Printf ( "AUTH_SERVER_NEGOTIATE: Can't find client with client session id %d (username '%s').\n", clientSessionID, username.GetChars() ); } break; case AUTH_SERVER_SRP_STEP_TWO: { const int sessionID = NETWORK_ReadLong( pByteStream ); const int lenB = NETWORK_ReadShort( pByteStream ); TArray<unsigned char> bytesB; if ( lenB > 0 ) { bytesB.Resize( lenB ); for ( int i = 0; i < lenB; ++i ) bytesB[i] = NETWORK_ReadByte( pByteStream ); } else Printf ( "AUTH_SERVER_SRP_STEP_TWO: Invalid length\n" ); const int clientID = SERVER_FindClientWithSessionID ( sessionID ); if ( clientID < MAXPLAYERS ) { SERVER_GetClient(clientID)->bytesB = bytesB; SERVERCOMMANDS_SRPUserProcessChallenge ( clientID ); } else Printf ( "AUTH_SERVER_SRP_STEP_TWO: Can't find client with session ID '%d'.\n", sessionID ); } break; case AUTH_SERVER_SRP_STEP_FOUR: { const int sessionID = NETWORK_ReadLong( pByteStream ); const int lenHAMK = NETWORK_ReadShort( pByteStream ); TArray<unsigned char> bytesHAMK; if ( lenHAMK > 0 ) { bytesHAMK.Resize( lenHAMK ); for ( int i = 0; i < lenHAMK; ++i ) bytesHAMK[i] = NETWORK_ReadByte( pByteStream ); } else Printf ( "AUTH_SERVER_SRP_STEP_FOUR: Invalid length\n" ); const int clientID = SERVER_FindClientWithSessionID ( sessionID ); if ( clientID < MAXPLAYERS ) { // [BB] The user has logged in in successfully. Printf ( "Client %d has logged in successfully as '%s'.\n", clientID, SERVER_GetClient(clientID)->username.GetChars() ); SERVER_GetClient(clientID)->loggedIn = true; // [BB] Thus the session is invalid. SERVER_GetClient(clientID)->SRPsessionID = -1; // [BB] Send H(A,M,K) back to the client. This allows the client to // check that the communication with the auth server was legit. SERVER_GetClient(clientID)->bytesHAMK = bytesHAMK; SERVERCOMMANDS_SRPUserVerifySession ( clientID ); } else Printf ( "AUTH_SERVER_SRP_STEP_FOUR: Can't find client with session ID '%d'.\n", sessionID ); } break; case AUTH_SERVER_USER_ERROR: { const int errorCode = NETWORK_ReadByte( pByteStream ); const unsigned int clientSessionID = NETWORK_ReadLong( pByteStream ); Printf ( "Error: Error authenticating user with session id %u.\n", clientSessionID ); FString errorMessage = ""; switch ( errorCode ) { case USER_TRY_LATER: errorMessage = "The auth server is having issues. Try again later.\n"; break; case USER_NO_EXIST: errorMessage = "User does not exist.\n"; break; case USER_OUTDATED_PROTOCOL: errorMessage = "User requires a newer version of the protocol to authenticate.\n"; break; case USER_WILL_NOT_AUTH: errorMessage = "User exists, but will not be authenticated.\n"; break; default: errorMessage.AppendFormat ( "Unknown error code '%d'.\n", errorCode ); break; } Printf ( "%s", errorMessage.GetChars() ); const int clientID = SERVER_FindClientWithClientSessionID ( clientSessionID ); if ( clientID < MAXPLAYERS ) { // [BB] Since the authentication failed, clear all authentication related data of this client. SERVER_InitClientSRPData ( clientID ); SERVER_PrintfPlayer( PRINT_HIGH, clientID, "User authentication failed! %s", errorMessage.GetChars() ); } else Printf ( "AUTH_SERVER_NEGOTIATE: Can't find client with client session id %u.\n", clientSessionID ); } break; case AUTH_SERVER_SESSION_ERROR: { const int errorCode = NETWORK_ReadByte( pByteStream ); const int sessionID = NETWORK_ReadLong( pByteStream ); Printf ( "Session error: " ); FString errorMessage = ""; switch ( errorCode ) { case SESSION_TRY_LATER: errorMessage = "The auth server is having issues. Try again later.\n"; break; case SESSION_NO_EXIST: errorMessage = "Session ID does not exist or timed out.\n"; break; case SESSION_VERIFIER_UNSAFE: errorMessage = "Verifier safety check has been violated.\n"; break; case SESSION_AUTH_FAILED: errorMessage = "User could not be authenticated.\n"; break; default: errorMessage.AppendFormat ( "Unknown error code '%d'.\n", errorCode ); break; } Printf ( "%s", errorMessage.GetChars() ); const int clientID = SERVER_FindClientWithSessionID ( sessionID ); if ( clientID < MAXPLAYERS ) { // [BB] Since the authentication failed, clear all authentication related data of this client. SERVER_InitClientSRPData ( clientID ); SERVER_PrintfPlayer( PRINT_HIGH, clientID, "Session error: %s", errorMessage.GetChars() ); } } break; default: Printf ( "Error: Received unknown command '%d' from authentication server.\n", commandNum ); break; } } }
int FIWadManager::IdentifyVersion (TArray<FString> &wadfiles, const char *iwad, const char *zdoom_wad) { TArray<WadStuff> wads; TArray<size_t> foundwads; const char *iwadparm = Args->CheckValue ("-iwad"); size_t numwads; int pickwad; size_t i; bool iwadparmfound = false; FString custwad; ParseIWadInfos(zdoom_wad); wads.Resize(mIWadNames.Size()); foundwads.Resize(mIWads.Size()); memset(&foundwads[0], 0, foundwads.Size() * sizeof(foundwads[0])); if (iwadparm == NULL && iwad != NULL && *iwad != 0) { iwadparm = iwad; } if (iwadparm) { custwad = iwadparm; FixPathSeperator (custwad); if (CheckIWAD (custwad, &wads[0])) { // -iwad parameter was a directory iwadparm = NULL; } else { DefaultExtension (custwad, ".wad"); iwadparm = custwad; mIWadNames[0] = custwad; CheckIWAD ("", &wads[0]); } } if (iwadparm == NULL || wads[0].Path.IsEmpty() || mIWads[wads[0].Type].Required.IsNotEmpty()) { if (GameConfig->SetSection ("IWADSearch.Directories")) { const char *key; const char *value; while (GameConfig->NextInSection (key, value)) { if (stricmp (key, "Path") == 0) { FString nice = NicePath(value); FixPathSeperator(nice); CheckIWAD(nice, &wads[0]); } } } #ifdef _WIN32 FString steam_path = I_GetSteamPath(); if (steam_path.IsNotEmpty()) { static const char *const steam_dirs[] = { "doom 2/base", "final doom/base", "heretic shadow of the serpent riders/base", "hexen/base", "hexen deathkings of the dark citadel/base", "ultimate doom/base", "DOOM 3 BFG Edition/base/wads" }; steam_path += "/SteamApps/common/"; for (i = 0; i < countof(steam_dirs); ++i) { CheckIWAD (steam_path + steam_dirs[i], &wads[0]); } } #endif } if (iwadparm != NULL && !wads[0].Path.IsEmpty()) { iwadparmfound = true; } for (i = numwads = 0; i < mIWadNames.Size(); i++) { if (!wads[i].Path.IsEmpty()) { if (i != numwads) { wads[numwads] = wads[i]; } foundwads[wads[numwads].Type] = numwads + 1; numwads++; } } for (unsigned i=0; i<mIWads.Size(); i++) { if (mIWads[i].Required.IsNotEmpty() && foundwads[i]) { bool found = false; // needs to be loaded with another IWAD (HexenDK) for (unsigned j=0; j<mIWads.Size(); j++) { if (!mIWads[i].Required.Compare(mIWads[j].Name)) { if (foundwads[j]) { found = true; mIWads[i].preload = j; } break; } } // The required WAD is not there so this one can't be used and must be deleted from the list if (!found) { size_t kill = foundwads[i]; for (size_t j = kill; j < numwads; ++j) { wads[j - 1] = wads[j]; } numwads--; foundwads[i] = 0; for (unsigned j = 0; j < foundwads.Size(); ++j) { if (foundwads[j] > kill) { foundwads[j]--; } } } } } if (numwads == 0) { I_FatalError ("Cannot find a game IWAD (doom.wad, doom2.wad, heretic.wad, etc.).\n" "Did you install ZDoom properly? You can do either of the following:\n" "\n" "1. Place one or more of these wads in the same directory as ZDoom.\n" "2. Edit your zdoom-username.ini and add the directories of your iwads\n" "to the list beneath [IWADSearch.Directories]"); } pickwad = 0; if ((!iwadparmfound && numwads > 1) || I_ForcePickIWAD()) { int defiwad = 0; // Locate the user's prefered IWAD, if it was found. if (defaultiwad[0] != '\0') { for (i = 0; i < numwads; ++i) { FString basename = ExtractFileBase (wads[i].Path); if (stricmp (basename, defaultiwad) == 0) { defiwad = (int)i; break; } } } pickwad = I_PickIWad (&wads[0], (int)numwads, queryiwad, defiwad); if (pickwad >= 0) { // The newly selected IWAD becomes the new default FString basename = ExtractFileBase (wads[pickwad].Path); defaultiwad = basename; } } if (pickwad < 0) exit (0); // zdoom.pk3 must always be the first file loaded and the IWAD second. wadfiles.Clear(); D_AddFile (wadfiles, zdoom_wad); if (mIWads[wads[pickwad].Type].preload >= 0) { D_AddFile (wadfiles, wads[foundwads[mIWads[wads[pickwad].Type].preload]-1].Path); } D_AddFile (wadfiles, wads[pickwad].Path); for (unsigned i=0; i < mIWads[wads[pickwad].Type].Load.Size(); i++) { long lastslash = wads[pickwad].Path.LastIndexOf ('/'); FString path; if (lastslash == -1) { path = "";// wads[pickwad].Path; } else { path = FString (wads[pickwad].Path.GetChars(), lastslash + 1); } path += mIWads[wads[pickwad].Type].Load[i]; D_AddFile (wadfiles, path); } return wads[pickwad].Type; }
static int MergeMapSections(int num) { FSectionVertexMap vmap; FSectionVertexMap::Pair *pair; TArray<int> sectmap; TArray<bool> sectvalid; sectmap.Resize(num); sectvalid.Resize(num); for(int i=0; i<num; i++) { sectmap[i] = -1; sectvalid[i] = true; } int mergecount = 1; cvertex_t vt; // first step: Set mapsection for all vertex positions. for(DWORD i=0; i<(DWORD)numsegs; i++) { seg_t * seg = &segs[i]; int section = seg->Subsector->mapsection; for(int j=0; j<2; j++) { vt = j==0? seg->v1:seg->v2; vmap[vt] = section; } } // second step: Check if any seg references more than one mapsection, either by subsector or by vertex for(DWORD i=0; i<(DWORD)numsegs; i++) { seg_t * seg = &segs[i]; int section = seg->Subsector->mapsection; for(int j=0; j<2; j++) { vt = j==0? seg->v1:seg->v2; int vsection = vmap[vt]; if (vsection != section) { // These 2 sections should be merged for(int k=0; k<numsubsectors; k++) { if (subsectors[k].mapsection == vsection) subsectors[k].mapsection = section; } FSectionVertexMap::Iterator it(vmap); while (it.NextPair(pair)) { if (pair->Value == vsection) pair->Value = section; } sectvalid[vsection-1] = false; } } } for(int i=0; i<num; i++) { if (sectvalid[i]) sectmap[i] = mergecount++; } for(int i=0; i<numsubsectors; i++) { subsectors[i].mapsection = sectmap[subsectors[i].mapsection-1]; assert(subsectors[i].mapsection!=-1); } return mergecount-1; }
void gl_InitPortals() { FPortalMap collection; if (level.nodes.Size() == 0) return; CollectPortalSectors(collection); glSectorPortals.Clear(); FPortalMap::Iterator it(collection); FPortalMap::Pair *pair; int c = 0; int planeflags = 0; while (it.NextPair(pair)) { for(unsigned i=0;i<pair->Value.Size(); i++) { if (pair->Value[i].mPlane == sector_t::floor) planeflags |= 1; else if (pair->Value[i].mPlane == sector_t::ceiling) planeflags |= 2; } for (int i=1;i<=2;i<<=1) { // add separate glSectorPortals for floor and ceiling. if (planeflags & i) { FPortal *portal = new FPortal; portal->mDisplacement = pair->Key.mDisplacement; portal->plane = (i==1? sector_t::floor : sector_t::ceiling); /**/ portal->glportal = NULL; glSectorPortals.Push(portal); for(unsigned j=0;j<pair->Value.Size(); j++) { sector_t *sec = pair->Value[j].mSub; int plane = pair->Value[j].mPlane; if (portal->plane == plane) { for(int k=0;k<sec->subsectorcount; k++) { subsector_t *sub = sec->subsectors[k]; gl_BuildPortalCoverage(&sub->portalcoverage[plane], sub, pair->Key.mDisplacement); } sec->portals[plane] = portal; } } } } } // Now group the line glSectorPortals (each group must be a continuous set of colinear linedefs with no gaps) glLinePortals.Clear(); linePortalToGL.Clear(); TArray<int> tempindex; tempindex.Reserve(linePortals.Size()); memset(&tempindex[0], -1, linePortals.Size() * sizeof(int)); for (unsigned i = 0; i < linePortals.Size(); i++) { auto port = linePortals[i]; bool gotsome; if (tempindex[i] == -1) { tempindex[i] = glLinePortals.Size(); line_t *pSrcLine = linePortals[i].mOrigin; line_t *pLine = linePortals[i].mDestination; FGLLinePortal &glport = glLinePortals[glLinePortals.Reserve(1)]; glport.lines.Push(&linePortals[i]); // We cannot do this grouping for non-linked glSectorPortals because they can be changed at run time. if (linePortals[i].mType == PORTT_LINKED && pLine != nullptr) { glport.v1 = pLine->v1; glport.v2 = pLine->v2; do { // now collect all other colinear lines connected to this one. We run this loop as long as it still finds a match gotsome = false; for (unsigned j = 0; j < linePortals.Size(); j++) { if (tempindex[j] == -1) { line_t *pSrcLine2 = linePortals[j].mOrigin; line_t *pLine2 = linePortals[j].mDestination; // angular precision is intentionally reduced to 32 bit BAM to account for precision problems (otherwise many not perfectly horizontal or vertical glSectorPortals aren't found here.) unsigned srcang = pSrcLine->Delta().Angle().BAMs(); unsigned dstang = pLine->Delta().Angle().BAMs(); if ((pSrcLine->v2 == pSrcLine2->v1 && pLine->v1 == pLine2->v2) || (pSrcLine->v1 == pSrcLine2->v2 && pLine->v2 == pLine2->v1)) { // The line connects, now check the translation unsigned srcang2 = pSrcLine2->Delta().Angle().BAMs(); unsigned dstang2 = pLine2->Delta().Angle().BAMs(); if (srcang == srcang2 && dstang == dstang2) { // The lines connect and both source and destination are colinear, so this is a match gotsome = true; tempindex[j] = tempindex[i]; if (pLine->v1 == pLine2->v2) glport.v1 = pLine2->v1; else glport.v2 = pLine2->v2; glport.lines.Push(&linePortals[j]); } } } } } while (gotsome); } } } linePortalToGL.Resize(linePortals.Size()); for (unsigned i = 0; i < linePortals.Size(); i++) { linePortalToGL[i] = &glLinePortals[tempindex[i]]; /* Printf("portal at line %d translates to GL portal %d, range = %f,%f to %f,%f\n", int(linePortals[i].mOrigin - lines), tempindex[i], linePortalToGL[i]->v1->fixX() / 65536., linePortalToGL[i]->v1->fixY() / 65536., linePortalToGL[i]->v2->fixX() / 65536., linePortalToGL[i]->v2->fixY() / 65536.); */ } }
static HCURSOR CreateAlphaCursor(FTexture *cursorpic) { HDC dc; BITMAPV5HEADER bi; HBITMAP color, mono; void *bits; // Find closest integer scale factor for the monitor DPI HDC screenDC = GetDC(0); int dpi = GetDeviceCaps(screenDC, LOGPIXELSX); int scale = MAX((dpi + 96 / 2 - 1) / 96, 1); ReleaseDC(0, screenDC); memset(&bi, 0, sizeof(bi)); bi.bV5Size = sizeof(bi); bi.bV5Width = 32 * scale; bi.bV5Height = 32 * scale; bi.bV5Planes = 1; bi.bV5BitCount = 32; bi.bV5Compression = BI_BITFIELDS; bi.bV5RedMask = 0x00FF0000; bi.bV5GreenMask = 0x0000FF00; bi.bV5BlueMask = 0x000000FF; bi.bV5AlphaMask = 0xFF000000; dc = GetDC(NULL); if (dc == NULL) { return NULL; } // Create the DIB section with an alpha channel. color = CreateDIBSection(dc, (BITMAPINFO *)&bi, DIB_RGB_COLORS, &bits, NULL, 0); ReleaseDC(NULL, dc); if (color == NULL) { return NULL; } // Create an empty mask bitmap, since CreateIconIndirect requires this. mono = CreateBitmap(32 * scale, 32 * scale, 1, 1, NULL); if (mono == NULL) { DeleteObject(color); return NULL; } // Copy cursor to the color bitmap. Note that GDI bitmaps are upside down compared // to normal conventions, so we create the FBitmap pointing at the last row and use // a negative pitch so that CopyTrueColorPixels will use GDI's orientation. if (scale == 1) { FBitmap bmp((uint8_t *)bits + 31 * 32 * 4, -32 * 4, 32, 32); cursorpic->CopyTrueColorPixels(&bmp, 0, 0); } else { TArray<uint32_t> unscaled; unscaled.Resize(32 * 32); for (int i = 0; i < 32 * 32; i++) unscaled[i] = 0; FBitmap bmp((uint8_t *)&unscaled[0] + 31 * 32 * 4, -32 * 4, 32, 32); cursorpic->CopyTrueColorPixels(&bmp, 0, 0); uint32_t *scaled = (uint32_t*)bits; for (int y = 0; y < 32 * scale; y++) { for (int x = 0; x < 32 * scale; x++) { scaled[x + y * 32 * scale] = unscaled[x / scale + y / scale * 32]; } } } return CreateBitmapCursor(cursorpic->LeftOffset * scale, cursorpic->TopOffset * scale, mono, color); }