diff --git a/src/common/filesystem/source/filesystem.cpp b/src/common/filesystem/source/filesystem.cpp index b4d7ebab31..ab7d96a58a 100644 --- a/src/common/filesystem/source/filesystem.cpp +++ b/src/common/filesystem/source/filesystem.cpp @@ -90,29 +90,33 @@ static void md5Hash(FileReader& reader, uint8_t* digest) struct FileSystem::LumpRecord { - FResourceLump *lump; + FResourceFile *resfile; LumpShortName shortName; const char* LongName; - int rfnum; - int Namespace; + int resindex; + int16_t rfnum; // this is not necessarily the same as resfile's index! + int16_t Namespace; int resourceId; int flags; - void SetFromLump(int filenum, FResourceLump* lmp, StringPool* sp) + void SetFromLump(FResourceFile* file, int fileindex, int filenum, StringPool* sp, const char* name = nullptr) { - lump = lmp; + resfile = file; + resindex = fileindex; rfnum = filenum; flags = 0; - if (lump->Flags & LUMPF_SHORTNAME) + auto lflags = file->GetEntryFlags(fileindex); + if (!name) name = file->getName(fileindex); + if (lflags & LUMPF_SHORTNAME) { - UpperCopy(shortName.String, lump->getName()); + UpperCopy(shortName.String, name); shortName.String[8] = 0; LongName = ""; - Namespace = lump->GetNamespace(); + Namespace = file->GetEntryNamespace(fileindex); resourceId = -1; } - else if ((lump->Flags & LUMPF_EMBEDDED) || !lump->getName() || !*lump->getName()) + else if ((lflags & LUMPF_EMBEDDED) || !name || !*name) { shortName.qword = 0; LongName = ""; @@ -121,8 +125,8 @@ struct FileSystem::LumpRecord } else { - LongName = lump->getName(); - resourceId = lump->GetIndexNum(); + LongName = name; + resourceId = file->GetEntryResourceID(fileindex); // Map some directories to WAD namespaces. // Note that some of these namespaces don't exist in WADS. @@ -305,7 +309,7 @@ int FileSystem::AddFromBuffer(const char* name, char* data, int size, int id, in FResourceLump* lump = rf->GetLump(0); FileInfo.resize(FileInfo.size() + 1); FileSystem::LumpRecord* lump_p = &FileInfo.back(); - lump_p->SetFromLump((int)Files.size(), lump, stringpool); + lump_p->SetFromLump(rf, 0, (int)Files.size() - 1, stringpool); } return (int)FileInfo.size() - 1; } @@ -372,16 +376,15 @@ void FileSystem::AddFile (const char *filename, FileReader *filer, LumpFilterInf uint32_t lumpstart = (uint32_t)FileInfo.size(); resfile->SetFirstLump(lumpstart); + Files.push_back(resfile); for (int i = 0; i < resfile->EntryCount(); i++) { FResourceLump* lump = resfile->GetLump(i); FileInfo.resize(FileInfo.size() + 1); FileSystem::LumpRecord* lump_p = &FileInfo.back(); - lump_p->SetFromLump((int)Files.size(), lump, stringpool); + lump_p->SetFromLump(resfile, i, (int)Files.size() - 1, stringpool); } - Files.push_back(resfile); - for (int i = 0; i < resfile->EntryCount(); i++) { int flags = resfile->GetEntryFlags(i); @@ -524,8 +527,9 @@ int FileSystem::CheckNumForName (const char *name, int space) const // If we find a lump with this name in the global namespace that does not come // from a Zip return that. WADs don't know these namespaces and single lumps must // work as well. + auto lflags = lump.resfile->GetEntryFlags(lump.resindex); if (space > ns_specialzipdirectory && lump.Namespace == ns_global && - !((lump.lump->Flags ^lump.flags) & LUMPF_FULLPATH)) break; + !((lflags ^lump.flags) & LUMPF_FULLPATH)) break; } i = NextLumpIndex[i]; } @@ -771,7 +775,8 @@ int FileSystem::FileLength (int lump) const { return -1; } - return FileInfo[lump].lump->LumpSize; + const auto &lump_p = FileInfo[lump]; + return lump_p.resfile->Length(lump_p.resindex); } //========================================================================== @@ -789,7 +794,8 @@ int FileSystem::GetFileOffset (int lump) { return -1; } - return FileInfo[lump].lump->GetFileOffset(); + const auto &lump_p = FileInfo[lump]; + return lump_p.resfile->Offset(lump_p.resindex); } //========================================================================== @@ -805,7 +811,8 @@ int FileSystem::GetFileFlags (int lump) return 0; } - return FileInfo[lump].lump->Flags ^ FileInfo[lump].flags; + const auto& lump_p = FileInfo[lump]; + return lump_p.resfile->GetEntryFlags(lump_p.resindex) ^ lump_p.flags; } //========================================================================== @@ -920,11 +927,12 @@ void FileSystem::MoveLumpsInFolder(const char *path) if (li.rfnum >= GetIwadNum()) break; if (strnicmp(li.LongName, path, len) == 0) { - FileInfo.push_back(li); - li.lump = &placeholderLump; // Make the old entry point to something empty. We cannot delete the lump record here because it'd require adjustment of all indices in the list. + auto lic = li; // make a copy before pushing. + FileInfo.push_back(lic); + li.LongName = ""; //nuke the name of the old record. + li.shortName.qword = 0; auto &ln = FileInfo.back(); - ln.lump->LumpNameSetup(ln.LongName + len, stringpool); // may be able to avoid the string allocation! - ln.SetFromLump(rfnum, ln.lump, stringpool); + ln.SetFromLump(li.resfile, li.resindex, rfnum, stringpool, ln.LongName + len); } } } @@ -1304,8 +1312,9 @@ FileData FileSystem::ReadFile (int lump) { throw FileSystemException("ReadFile: %u >= NumEntries", lump); } - auto lumpp = FileInfo[lump].lump; + auto file = FileInfo[lump].resfile; + auto lumpp = file->GetLump(FileInfo[lump].resindex); return FileData(lumpp); } @@ -1325,16 +1334,8 @@ FileReader FileSystem::OpenFileReader(int lump) throw FileSystemException("OpenFileReader: %u >= NumEntries", lump); } - auto rl = FileInfo[lump].lump; - auto rd = rl->GetReader(); - - if (rl->RefCount == 0 && rd != nullptr && !rd->GetBuffer() && !(rl->Flags & LUMPF_COMPRESSED)) - { - FileReader rdr; - rdr.OpenFilePart(*rd, rl->GetFileOffset(), rl->LumpSize); - return rdr; - } - return rl->NewReader(); // This always gets a reader to the cache + auto file = FileInfo[lump].resfile; + return file->GetEntryReader(FileInfo[lump].resindex, false); } FileReader FileSystem::ReopenFileReader(int lump, bool alwayscache) @@ -1344,20 +1345,8 @@ FileReader FileSystem::ReopenFileReader(int lump, bool alwayscache) throw FileSystemException("ReopenFileReader: %u >= NumEntries", lump); } - auto rl = FileInfo[lump].lump; - auto rd = rl->GetReader(); - - if (rl->RefCount == 0 && rd != nullptr && !rd->GetBuffer() && !alwayscache && !(rl->Flags & LUMPF_COMPRESSED)) - { - int fileno = GetFileContainer(lump); - const char *filename = GetResourceFileFullName(fileno); - FileReader fr; - if (fr.OpenFile(filename, rl->GetFileOffset(), rl->LumpSize)) - { - return fr; - } - } - return rl->NewReader(); // This always gets a reader to the cache + auto file = FileInfo[lump].resfile; + return file->GetEntryReader(FileInfo[lump].resindex, true); } FileReader FileSystem::OpenFileReader(const char* name)