bool FWadCollection::IsUncompressedFile(int lump) const { if ((unsigned)lump >= (unsigned)NumLumps) { I_Error ("IsUncompressedFile: %u >= NumLumps",lump); } FResourceLump *l = LumpInfo[lump].lump; FileReader *f = l->GetReader(); // We can access the file only if we get the FILE pointer from the FileReader here. // Any other case means it won't work. return (f != NULL && f->GetFile() != NULL); }
void FIWadManager::ParseIWadInfos(const char *fn) { FResourceFile *resfile = FResourceFile::OpenResourceFile(fn, NULL, true); if (resfile != NULL) { DWORD cnt = resfile->LumpCount(); for(int i=cnt-1; i>=0; i--) { FResourceLump *lmp = resfile->GetLump(i); if (lmp->Namespace == ns_global && !stricmp(lmp->Name, "IWADINFO")) { // Found one! ParseIWadInfo(resfile->Filename, (const char*)lmp->CacheLump(), lmp->LumpSize); break; } } delete resfile; } if (mIWadNames.Size() == 0 || mIWads.Size() == 0) { I_FatalError("No IWAD definitions found"); } }
void G_ReadSnapshots(FResourceFile *resf) { FString MapName; level_info_t *i; G_ClearSnapshots(); for (unsigned j = 0; j < resf->LumpCount(); j++) { FResourceLump * resl = resf->GetLump(j); if (resl != nullptr) { auto ptr = strstr(resl->FullName, ".map.json"); if (ptr != nullptr) { ptrdiff_t maplen = ptr - resl->FullName.GetChars(); FString mapname(resl->FullName.GetChars(), (size_t)maplen); i = FindLevelInfo(mapname); if (i != nullptr) { i->Snapshot = resl->GetRawData(); } } else { auto ptr = strstr(resl->FullName, ".mapd.json"); if (ptr != nullptr) { ptrdiff_t maplen = ptr - resl->FullName.GetChars(); FString mapname(resl->FullName.GetChars(), (size_t)maplen); TheDefaultLevelInfo.Snapshot = resl->GetRawData(); } } } } }
void FWadCollection::AddFile (const char *filename, FileReader *wadinfo) { int startlump; bool isdir = false; if (wadinfo == NULL) { // Does this exist? If so, is it a directory? if (!DirEntryExists(filename, &isdir)) { Printf(TEXTCOLOR_RED "%s: File or Directory not found\n", filename); PrintLastError(); return; } if (!isdir) { try { wadinfo = new FileReader(filename); } catch (CRecoverableError &err) { // Didn't find file Printf (TEXTCOLOR_RED "%s\n", err.GetMessage()); PrintLastError (); return; } } } if (!batchrun) Printf (" adding %s", filename); startlump = NumLumps; FResourceFile *resfile; if (!isdir) resfile = FResourceFile::OpenResourceFile(filename, wadinfo); else resfile = FResourceFile::OpenDirectory(filename); if (resfile != NULL) { uint32_t lumpstart = LumpInfo.Size(); resfile->SetFirstLump(lumpstart); for (uint32_t i=0; i < resfile->LumpCount(); i++) { FResourceLump *lump = resfile->GetLump(i); FWadCollection::LumpRecord *lump_p = &LumpInfo[LumpInfo.Reserve(1)]; lump_p->lump = lump; lump_p->wadnum = Files.Size(); } if (static_cast<int>(Files.Size()) == GetIwadNum() && gameinfo.gametype == GAME_Strife && gameinfo.flags & GI_SHAREWARE) { resfile->FindStrifeTeaserVoices(); } Files.Push(resfile); for (uint32_t i=0; i < resfile->LumpCount(); i++) { FResourceLump *lump = resfile->GetLump(i); if (lump->Flags & LUMPF_EMBEDDED) { FString path; path.Format("%s:%s", filename, lump->FullName.GetChars()); FileReader *embedded = lump->NewReader(); AddFile(path, embedded); } } if (hashfile) { uint8_t cksum[16]; char cksumout[33]; memset(cksumout, 0, sizeof(cksumout)); FileReader *reader = wadinfo; if (reader != NULL) { MD5Context md5; reader->Seek(0, SEEK_SET); md5.Update(reader, reader->GetLength()); md5.Final(cksum); for (size_t j = 0; j < sizeof(cksum); ++j) { sprintf(cksumout + (j * 2), "%02X", cksum[j]); } fprintf(hashfile, "file: %s, hash: %s, size: %ld\n", filename, cksumout, reader->GetLength()); } else fprintf(hashfile, "file: %s, Directory structure\n", filename); for (uint32_t i = 0; i < resfile->LumpCount(); i++) { FResourceLump *lump = resfile->GetLump(i); if (!(lump->Flags & LUMPF_EMBEDDED)) { reader = lump->NewReader(); MD5Context md5; md5.Update(reader, lump->LumpSize); md5.Final(cksum); for (size_t j = 0; j < sizeof(cksum); ++j) { sprintf(cksumout + (j * 2), "%02X", cksum[j]); } fprintf(hashfile, "file: %s, lump: %s, hash: %s, size: %d\n", filename, lump->FullName.IsNotEmpty() ? lump->FullName.GetChars() : lump->Name, cksumout, lump->LumpSize); delete reader; } } } return; } }
void FWadCollection::AddFile (const char *filename, FileReader *wadinfo) { int startlump; bool isdir = false; if (wadinfo == NULL) { // Does this exist? If so, is it a directory? struct stat info; if (stat(filename, &info) != 0) { Printf(TEXTCOLOR_RED "Could not stat %s\n", filename); PrintLastError(); return; } isdir = (info.st_mode & S_IFDIR) != 0; if (!isdir) { try { wadinfo = new FileReader(filename); } catch (CRecoverableError &err) { // Didn't find file Printf (TEXTCOLOR_RED "%s\n", err.GetMessage()); PrintLastError (); return; } } } Printf (" adding %s", filename); startlump = NumLumps; FResourceFile *resfile; if (!isdir) resfile = FResourceFile::OpenResourceFile(filename, wadinfo); else resfile = FResourceFile::OpenDirectory(filename); if (resfile != NULL) { DWORD lumpstart = LumpInfo.Size(); resfile->SetFirstLump(lumpstart); for (DWORD i=0; i < resfile->LumpCount(); i++) { FResourceLump *lump = resfile->GetLump(i); FWadCollection::LumpRecord *lump_p = &LumpInfo[LumpInfo.Reserve(1)]; lump_p->lump = lump; lump_p->wadnum = Files.Size(); } if (Files.Size() == IWAD_FILENUM && gameinfo.gametype == GAME_Strife && gameinfo.flags & GI_SHAREWARE) { resfile->FindStrifeTeaserVoices(); } Files.Push(resfile); for (DWORD i=0; i < resfile->LumpCount(); i++) { FResourceLump *lump = resfile->GetLump(i); if (lump->Flags & LUMPF_EMBEDDED) { char path[256]; mysnprintf(path, countof(path), "%s:", filename); char *wadstr = path + strlen(path); FileReader *embedded = lump->NewReader(); strcpy(wadstr, lump->FullName); AddFile(path, embedded); } } return; } }
unsigned FSavegameManager::ExtractSaveData(int index) { FResourceFile *resf; FSaveGameNode *node; if (index == -1) { if (SaveGames.Size() > 0 && SaveGames[0]->bNoDelete) { index = LastSaved + 1; } else { index = LastAccessed < 0? 0 : LastAccessed; } } UnloadSaveData(); if ((unsigned)index < SaveGames.Size() && (node = SaveGames[index]) && !node->Filename.IsEmpty() && !node->bOldVersion && (resf = FResourceFile::OpenResourceFile(node->Filename.GetChars(), true)) != nullptr) { FResourceLump *info = resf->FindLump("info.json"); if (info == nullptr) { // this should not happen because the file has already been verified. return index; } void *data = info->CacheLump(); FSerializer arc(nullptr); if (arc.OpenReader((const char *)data, info->LumpSize)) { FString comment; FString time = arc.GetString("Creation Time"); FString pcomment = arc.GetString("Comment"); comment = time; if (time.Len() > 0) comment += "\n"; comment += pcomment; SaveCommentString = comment; // Extract pic FResourceLump *pic = resf->FindLump("savepic.png"); if (pic != nullptr) { FileReader picreader; picreader.OpenMemoryArray([=](TArray<uint8_t> &array) { auto cache = pic->CacheLump(); array.Resize(pic->LumpSize); memcpy(&array[0], cache, pic->LumpSize); pic->ReleaseCache(); return true; }); PNGHandle *png = M_VerifyPNG(picreader); if (png != nullptr) { SavePic = PNGTexture_CreateFromFile(png, node->Filename); delete png; if (SavePic && SavePic->GetDisplayWidth() == 1 && SavePic->GetDisplayHeight() == 1) { delete SavePic; SavePic = nullptr; SavePicData.Clear(); } } } } delete resf; } return index; }
void FSavegameManager::ReadSaveStrings() { if (SaveGames.Size() == 0) { void *filefirst; findstate_t c_file; FString filter; LastSaved = LastAccessed = -1; quickSaveSlot = nullptr; filter = G_BuildSaveName("*." SAVEGAME_EXT, -1); filefirst = I_FindFirst(filter.GetChars(), &c_file); if (filefirst != ((void *)(-1))) { do { // I_FindName only returns the file's name and not its full path FString filepath = G_BuildSaveName(I_FindName(&c_file), -1); FResourceFile *savegame = FResourceFile::OpenResourceFile(filepath, true, true); if (savegame != nullptr) { bool oldVer = false; bool missing = false; FResourceLump *info = savegame->FindLump("info.json"); if (info == nullptr) { // savegame info not found. This is not a savegame so leave it alone. delete savegame; continue; } void *data = info->CacheLump(); FSerializer arc(nullptr); if (arc.OpenReader((const char *)data, info->LumpSize)) { int savever = 0; arc("Save Version", savever); FString engine = arc.GetString("Engine"); FString iwad = arc.GetString("Game WAD"); FString title = arc.GetString("Title"); if (engine.Compare(GAMESIG) != 0 || savever > SAVEVER) { // different engine or newer version: // not our business. Leave it alone. delete savegame; continue; } if (savever < MINSAVEVER) { // old, incompatible savegame. List as not usable. oldVer = true; } else if (iwad.CompareNoCase(Wads.GetWadName(Wads.GetIwadNum())) == 0) { missing = !G_CheckSaveGameWads(arc, false); } else { // different game. Skip this. delete savegame; continue; } FSaveGameNode *node = new FSaveGameNode; node->Filename = filepath; node->bOldVersion = oldVer; node->bMissingWads = missing; node->SaveTitle = title; InsertSaveNode(node); delete savegame; } } else // check for old formats. { FileReader file; if (file.OpenFile(filepath)) { PNGHandle *png; char sig[16]; char title[OLDSAVESTRINGSIZE + 1]; bool oldVer = true; bool addIt = false; bool missing = false; // ZDoom 1.23 betas 21-33 have the savesig first. // Earlier versions have the savesig second. // Later versions have the savegame encapsulated inside a PNG. // // Old savegame versions are always added to the menu so // the user can easily delete them if desired. title[OLDSAVESTRINGSIZE] = 0; if (nullptr != (png = M_VerifyPNG(file))) { char *ver = M_GetPNGText(png, "ZDoom Save Version"); if (ver != nullptr) { // An old version if (!M_GetPNGText(png, "Title", title, OLDSAVESTRINGSIZE)) { strncpy(title, I_FindName(&c_file), OLDSAVESTRINGSIZE); } addIt = true; delete[] ver; } delete png; } else { file.Seek(0, FileReader::SeekSet); if (file.Read(sig, 16) == 16) { if (strncmp(sig, "ZDOOMSAVE", 9) == 0) { if (file.Read(title, OLDSAVESTRINGSIZE) == OLDSAVESTRINGSIZE) { addIt = true; } } else { memcpy(title, sig, 16); if (file.Read(title + 16, OLDSAVESTRINGSIZE - 16) == OLDSAVESTRINGSIZE - 16 && file.Read(sig, 16) == 16 && strncmp(sig, "ZDOOMSAVE", 9) == 0) { addIt = true; } } } } if (addIt) { FSaveGameNode *node = new FSaveGameNode; node->Filename = filepath; node->bOldVersion = true; node->bMissingWads = false; node->SaveTitle = title; InsertSaveNode(node); } } } } while (I_FindNext(filefirst, &c_file) == 0); I_FindClose(filefirst); } } }
~FLumpReader() { source->ReleaseCache(); }
void LumpRemapper::DoRemap() { if(!LoadMap()) return; for(unsigned int i = 0;i < files.Size();i++) { RemapFile &file = files[i]; // Register sample rate sampleRateMap[Wads.GetLumpFile(files[i].file->GetFirstLump())] = digiTimerValue; int temp = 0; // Use to count something int temp2 = 0; for(unsigned int i = 0;i < file.file->LumpCount();i++) { FResourceLump *lump = file.file->GetLump(i); int oldNamespace = lump->Namespace; switch(file.type) { case AUDIOT: if(lump->Namespace == ns_sounds) { if(i < sounds.Size() && lump->LumpSize > 0) lump->LumpNameSetup(sounds[i]); temp++; } else if(lump->Namespace == ns_music && i-temp < music.Size() && lump->LumpSize > 0) { lump->LumpNameSetup(music[i-temp]); } break; case VGAGRAPH: if(i < graphics.Size()) { lump->LumpNameSetup(graphics[i]); } break; case VSWAP: if(lump->Namespace == ns_flats) { if(i < textures.Size() && lump->LumpSize > 0) lump->LumpNameSetup(textures[i]); temp++; temp2++; } else if(lump->Namespace == ns_sprites) { if(i-temp < sprites.Size() && lump->LumpSize > 0) lump->LumpNameSetup(sprites[i-temp]); temp2++; } else if(lump->Namespace == ns_sounds && i-temp2 < digitalsounds.Size()) { if(lump->LumpSize > 0) lump->LumpNameSetup(digitalsounds[i-temp2]); } break; default: break; } lump->Namespace = oldNamespace; lump->DoFinishRemap(); } } Wads.InitHashChains(); }