diff --git a/src/d_iwad.cpp b/src/d_iwad.cpp index d9e50d89e4..21bc7eed6a 100644 --- a/src/d_iwad.cpp +++ b/src/d_iwad.cpp @@ -43,7 +43,6 @@ #include "sc_man.h" #include "v_video.h" #include "gameconfigfile.h" -#include "resourcefiles/resourcefile.h" #include "version.h" #include "engineerrors.h" #include "v_text.h" @@ -267,29 +266,28 @@ void FIWadManager::ParseIWadInfo(const char *fn, const char *data, int datasize, // //========================================================================== -FIWadManager::FIWadManager(const char *fn, const char *optfn) +FIWadManager::FIWadManager(const char *firstfn, const char *optfn) { - FResourceFile *resfile = FResourceFile::OpenResourceFile(optfn, true); - if (resfile != NULL) - { - uint32_t cnt = resfile->LumpCount(); - for(int i=cnt-1; i>=0; i--) - { - FResourceLump *lmp = resfile->GetLump(i); + FWadCollection check; + TArray fns; + TArray deletes; + fns.Push(firstfn); + if (optfn) fns.Push(optfn); - 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 || mIWadInfos.Size() == 0) + check.InitMultipleFiles(fns, deletes, true); + if (check.GetNumLumps() > 0) + { + int num = check.CheckNumForName("IWADINFO"); + if (num >= 0) { - I_FatalError("No IWAD definitions found"); + auto data = check.ReadLumpIntoArray(num); + ParseIWadInfo("IWADINFO", (const char*)data.Data(), data.Size()); } } + if (mIWadNames.Size() == 0 || mIWadInfos.Size() == 0) + { + I_FatalError("No IWAD definitions found"); + } } @@ -302,7 +300,8 @@ FIWadManager::FIWadManager(const char *fn, const char *optfn) int FIWadManager::ScanIWAD (const char *iwad) { - FResourceFile *iwadfile = FResourceFile::OpenResourceFile(iwad, true); + FWadCollection check; + check.InitSingleFile(iwad, true); mLumpsFound.Resize(mIWadInfos.Size()); @@ -320,24 +319,20 @@ int FIWadManager::ScanIWAD (const char *iwad) } }; - if (iwadfile != NULL) + if (check.GetNumLumps() > 0) { memset(&mLumpsFound[0], 0, mLumpsFound.Size() * sizeof(mLumpsFound[0])); - for(uint32_t ii = 0; ii < iwadfile->LumpCount(); ii++) + for(int ii = 0; ii < check.GetNumLumps(); ii++) { - FResourceLump *lump = iwadfile->GetLump(ii); - CheckLumpName(lump->Name); - if (lump->FullName.IsNotEmpty()) + CheckLumpName(check.GetLumpName(ii)); + auto full = check.GetLumpFullName(ii, false); + if (full && strnicmp(full, "maps/", 5) == 0) { - if (strnicmp(lump->FullName, "maps/", 5) == 0) - { - FString mapname(&lump->FullName[5], strcspn(&lump->FullName[5], ".")); - CheckLumpName(mapname); - } + FString mapname(&full[5], strcspn(&full[5], ".")); + CheckLumpName(mapname); } } - delete iwadfile; } for (unsigned i = 0; i< mIWadInfos.Size(); i++) { @@ -356,46 +351,37 @@ int FIWadManager::ScanIWAD (const char *iwad) // //========================================================================== -int FIWadManager::CheckIWADInfo(const char *fn) +int FIWadManager::CheckIWADInfo(const char* fn) { - FResourceFile *resfile = FResourceFile::OpenResourceFile(fn, true); - if (resfile != NULL) + FWadCollection check; + + check.InitSingleFile(fn, true); + if (check.GetNumLumps() > 0) { - uint32_t cnt = resfile->LumpCount(); - for (int i = cnt - 1; i >= 0; i--) + int num = check.CheckNumForName("IWADINFO"); + if (num >= 0) { - FResourceLump *lmp = resfile->GetLump(i); - - if (lmp->Namespace == ns_global && !stricmp(lmp->Name, "IWADINFO")) + try { - // Found one! - try - { - FIWADInfo result; - ParseIWadInfo(resfile->FileName, (const char*)lmp->CacheLump(), lmp->LumpSize, &result); - delete resfile; - for (unsigned i = 0, count = mIWadInfos.Size(); i < count; ++i) + FIWADInfo result; + auto data = check.ReadLumpIntoArray(num); + ParseIWadInfo(fn, (const char*)data.Data(), data.Size(), &result); + + for (unsigned i = 0, count = mIWadInfos.Size(); i < count; ++i) + { + if (mIWadInfos[i].Name == result.Name) { - if (mIWadInfos[i].Name == result.Name) - { - return i; - } + return i; } - - mOrderNames.Push(result.Name); - return mIWadInfos.Push(result); } - catch (CRecoverableError &err) - { - delete resfile; - Printf(TEXTCOLOR_RED "%s: %s\nFile has been removed from the list of IWADs\n", fn, err.GetMessage()); - return -1; - } - break; + } + catch (CRecoverableError & err) + { + Printf(TEXTCOLOR_RED "%s: %s\nFile has been removed from the list of IWADs\n", fn, err.what()); + return -1; } } - delete resfile; Printf(TEXTCOLOR_RED "%s: Unable to find IWADINFO\nFile has been removed from the list of IWADs\n", fn); return -1; } diff --git a/src/d_main.cpp b/src/d_main.cpp index 5198b4d078..07bc0b8f89 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -2018,49 +2018,20 @@ static FString ParseGameInfo(TArray &pwads, const char *fn, const char static FString CheckGameInfo(TArray & pwads) { - // scan the list of WADs backwards to find the last one that contains a GAMEINFO lump - for(int i=pwads.Size()-1; i>=0; i--) + TArray deletes; + FWadCollection check; + + // Open the entire list as a temporary file system and look for a GAMEINFO lump. The last one will automatically win. + check.InitMultipleFiles(pwads, deletes, true); + if (check.GetNumLumps() > 0) { - bool isdir = false; - FResourceFile *resfile; - const char *filename = pwads[i]; - - // Does this exist? If so, is it a directory? - if (!DirEntryExists(pwads[i], &isdir)) + int num = check.CheckNumForName("GAMEINFO"); + if (num >= 0) { - Printf(TEXTCOLOR_RED "Could not stat %s\n", filename); - continue; - } - - if (!isdir) - { - FileReader fr; - if (!fr.OpenFile(filename)) - { - // Didn't find file - continue; - } - resfile = FResourceFile::OpenResourceFile(filename, fr, true); - } - else - resfile = FResourceFile::OpenDirectory(filename, true); - - if (resfile != NULL) - { - uint32_t cnt = resfile->LumpCount(); - for(int i=cnt-1; i>=0; i--) - { - FResourceLump *lmp = resfile->GetLump(i); - - if (lmp->Namespace == ns_global && !stricmp(lmp->Name, "GAMEINFO")) - { - // Found one! - FString iwad = ParseGameInfo(pwads, resfile->FileName, (const char*)lmp->CacheLump(), lmp->LumpSize); - delete resfile; - return iwad; - } - } - delete resfile; + // Found one! + auto data = check.ReadLumpIntoArray(num); + auto wadname = check.GetWadName(check.GetLumpFile(num)); + return ParseGameInfo(pwads, wadname, (const char*)data.Data(), data.Size()); } } return ""; diff --git a/src/g_level.cpp b/src/g_level.cpp index 04a9fae94e..047b723cc9 100644 --- a/src/g_level.cpp +++ b/src/g_level.cpp @@ -1802,11 +1802,12 @@ void G_ReadSnapshots(FResourceFile *resf) FResourceLump * resl = resf->GetLump(j); if (resl != nullptr) { - auto ptr = strstr(resl->FullName, ".map.json"); + auto name = resl->getName(); + auto ptr = strstr(name, ".map.json"); if (ptr != nullptr) { - ptrdiff_t maplen = ptr - resl->FullName.GetChars(); - FString mapname(resl->FullName.GetChars(), (size_t)maplen); + ptrdiff_t maplen = ptr - name; + FString mapname(name, (size_t)maplen); i = FindLevelInfo(mapname); if (i != nullptr) { @@ -1815,11 +1816,11 @@ void G_ReadSnapshots(FResourceFile *resf) } else { - auto ptr = strstr(resl->FullName, ".mapd.json"); + auto ptr = strstr(name, ".mapd.json"); if (ptr != nullptr) { - ptrdiff_t maplen = ptr - resl->FullName.GetChars(); - FString mapname(resl->FullName.GetChars(), (size_t)maplen); + ptrdiff_t maplen = ptr - name; + FString mapname(name, (size_t)maplen); TheDefaultLevelInfo.Snapshot = resl->GetRawData(); } } diff --git a/src/gamedata/resourcefiles/file_lump.cpp b/src/gamedata/resourcefiles/file_lump.cpp index bd0cc1f1b5..53ee982e5f 100644 --- a/src/gamedata/resourcefiles/file_lump.cpp +++ b/src/gamedata/resourcefiles/file_lump.cpp @@ -70,17 +70,15 @@ FLumpFile::FLumpFile(const char *filename, FileReader &file) bool FLumpFile::Open(bool quiet) { - FString name(ExtractFileBase (FileName)); + FString name(ExtractFileBase(FileName, true)); Lumps.Resize(1); - uppercopy(Lumps[0].Name, name); - Lumps[0].Name[8] = 0; + Lumps[0].LumpNameSetup(name); Lumps[0].Owner = this; Lumps[0].Position = 0; Lumps[0].LumpSize = (int)Reader.GetLength(); Lumps[0].Namespace = ns_global; Lumps[0].Flags = 0; - Lumps[0].FullName = ""; NumLumps = 1; if (!quiet) { diff --git a/src/gamedata/resourcefiles/file_zip.cpp b/src/gamedata/resourcefiles/file_zip.cpp index d661a8158f..93bf746b79 100644 --- a/src/gamedata/resourcefiles/file_zip.cpp +++ b/src/gamedata/resourcefiles/file_zip.cpp @@ -349,12 +349,6 @@ bool FZipFile::Open(bool quiet) lump_p->Position = LittleLong(zip_fh->LocalHeaderOffset); lump_p->CheckEmbedded(); - // Ignore some very specific names - if (0 == stricmp("dehacked.exe", name)) - { - memset(lump_p->Name, 0, sizeof(lump_p->Name)); - } - lump_p++; } // Resize the lump record array to its actual size diff --git a/src/gamedata/resourcefiles/resourcefile.cpp b/src/gamedata/resourcefiles/resourcefile.cpp index db56d4e553..7c158f48be 100644 --- a/src/gamedata/resourcefiles/resourcefile.cpp +++ b/src/gamedata/resourcefiles/resourcefile.cpp @@ -94,6 +94,12 @@ FResourceLump::~FResourceLump() void FResourceLump::LumpNameSetup(FString iname) { + // this causes interference with real Dehacked lumps. + if (!iname.CompareNoCase("dehacked.exe")) + { + iname = ""; + } + long slash = iname.LastIndexOf('/'); FString base = (slash >= 0) ? iname.Mid(slash + 1) : iname; auto dot = base.LastIndexOf('.'); @@ -350,8 +356,7 @@ int lumpcmp(const void * a, const void * b) { FResourceLump * rec1 = (FResourceLump *)a; FResourceLump * rec2 = (FResourceLump *)b; - - return rec1->FullName.CompareNoCase(rec2->FullName); + return stricmp(rec1->getName(), rec2->getName()); } //========================================================================== @@ -768,15 +773,12 @@ bool FMemoryFile::Open(bool quiet) FString fname(ExtractFileBase(FileName, true)); Lumps.Resize(1); - uppercopy(Lumps[0].Name, name); - Lumps[0].Name[8] = 0; - Lumps[0].FullName = fname; + Lumps[0].LumpNameSetup(fname); Lumps[0].Owner = this; Lumps[0].Position = 0; Lumps[0].LumpSize = (int)Reader.GetLength(); Lumps[0].Namespace = ns_global; Lumps[0].Flags = 0; - Lumps[0].FullName = ""; NumLumps = 1; return true; } diff --git a/src/gamedata/resourcefiles/resourcefile.h b/src/gamedata/resourcefiles/resourcefile.h index d21d52badf..643a81ede2 100644 --- a/src/gamedata/resourcefiles/resourcefile.h +++ b/src/gamedata/resourcefiles/resourcefile.h @@ -33,8 +33,10 @@ struct FCompressedBuffer struct FResourceLump { friend class FResourceFile; + friend class FWadFile; // this still needs direct access. int LumpSize; +protected: FString FullName; // only valid for files loaded from a non-wad archive union { @@ -43,6 +45,7 @@ struct FResourceLump uint32_t dwName; // These are for accessing the first 4 or 8 chars of uint64_t qwName; // Name as a unit without breaking strict aliasing rules }; +public: uint8_t Flags; int8_t RefCount; char * Cache; @@ -71,6 +74,10 @@ struct FResourceLump void *CacheLump(); int ReleaseCache(); + const char* shortName() { return Name; } + const FString &longName() { return FullName; } + const char* getName() { return FullName.IsNotEmpty() ? FullName.GetChars() : Name; } + protected: virtual int FillCache() { return -1; } diff --git a/src/gamedata/w_wad.cpp b/src/gamedata/w_wad.cpp index e506827fff..dfd14858a9 100644 --- a/src/gamedata/w_wad.cpp +++ b/src/gamedata/w_wad.cpp @@ -60,11 +60,23 @@ // // WADFILE I/O related stuff. // + +union LumpShortName +{ + char String[9]; + + uint32_t dword; // These are for accessing the first 4 or 8 chars of + uint64_t qword; // Name as a unit without breaking strict aliasing rules +}; + + struct FWadCollection::LumpRecord { int wadnum; FResourceLump *lump; FTexture* linkedTexture; + LumpShortName shortName; + FString longName; }; // EXTERNAL FUNCTION PROTOTYPES -------------------------------------------- @@ -150,7 +162,15 @@ void FWadCollection::DeleteAll () // //========================================================================== -void FWadCollection::InitMultipleFiles (TArray &filenames, const TArray &deletelumps) +void FWadCollection::InitSingleFile(const char* filename, bool quiet) +{ + TArray filenames; + TArray deletes; + filenames.Push(filename); + InitMultipleFiles(filenames, deletes, true); +} + +void FWadCollection::InitMultipleFiles (TArray &filenames, const TArray &deletelumps, bool quiet) { int numfiles; @@ -161,7 +181,7 @@ void FWadCollection::InitMultipleFiles (TArray &filenames, const TArray for(unsigned i=0;iGetHash().GetChars()); @@ -171,7 +191,8 @@ void FWadCollection::InitMultipleFiles (TArray &filenames, const TArray NumLumps = LumpInfo.Size(); if (NumLumps == 0) { - I_FatalError ("W_InitMultipleFiles: no files found"); + if (!quiet) I_FatalError("W_InitMultipleFiles: no files found"); + else return; } RenameNerve(); RenameSprites(deletelumps); @@ -206,6 +227,8 @@ int FWadCollection::AddExternalFile(const char *filename) lumprec->lump = lump; lumprec->wadnum = -1; lumprec->linkedTexture = nullptr; + memcpy(lumprec->shortName.String, lump->shortName(), 9); + lumprec->longName = lump->longName(); return LumpInfo.Size()-1; // later } @@ -219,7 +242,7 @@ int FWadCollection::AddExternalFile(const char *filename) // [RH] Removed reload hack //========================================================================== -void FWadCollection::AddFile (const char *filename, FileReader *wadr) +void FWadCollection::AddFile (const char *filename, FileReader *wadr, bool quiet) { int startlump; bool isdir = false; @@ -230,8 +253,11 @@ void FWadCollection::AddFile (const char *filename, FileReader *wadr) // 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(); + if (!quiet) + { + Printf(TEXTCOLOR_RED "%s: File or Directory not found\n", filename); + PrintLastError(); + } return; } @@ -239,23 +265,26 @@ void FWadCollection::AddFile (const char *filename, FileReader *wadr) { if (!wadreader.OpenFile(filename)) { // Didn't find file - Printf (TEXTCOLOR_RED "%s: File not found\n", filename); - PrintLastError (); + if (!quiet) + { + Printf(TEXTCOLOR_RED "%s: File not found\n", filename); + PrintLastError(); + } return; } } } else wadreader = std::move(*wadr); - if (!batchrun) Printf (" adding %s", filename); + if (!batchrun && !quiet) Printf (" adding %s", filename); startlump = NumLumps; FResourceFile *resfile; if (!isdir) - resfile = FResourceFile::OpenResourceFile(filename, wadreader); + resfile = FResourceFile::OpenResourceFile(filename, wadreader, quiet); else - resfile = FResourceFile::OpenDirectory(filename); + resfile = FResourceFile::OpenDirectory(filename, quiet); if (resfile != NULL) { @@ -269,6 +298,9 @@ void FWadCollection::AddFile (const char *filename, FileReader *wadr) lump_p->lump = lump; lump_p->wadnum = Files.Size(); + lump_p->linkedTexture = nullptr; + memcpy(lump_p->shortName.String, lump->shortName(), 9); + lump_p->longName = lump->longName(); } if (static_cast(Files.Size()) == GetIwadNum() && gameinfo.gametype == GAME_Strife && gameinfo.flags & GI_SHAREWARE) @@ -283,13 +315,13 @@ void FWadCollection::AddFile (const char *filename, FileReader *wadr) if (lump->Flags & LUMPF_EMBEDDED) { FString path; - path.Format("%s:%s", filename, lump->FullName.GetChars()); + path.Format("%s:%s", filename, lump->getName()); auto embedded = lump->NewReader(); AddFile(path, &embedded); } } - if (hashfile) + if (hashfile && !quiet) { uint8_t cksum[16]; char cksumout[33]; @@ -329,9 +361,7 @@ void FWadCollection::AddFile (const char *filename, FileReader *wadr) 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); + fprintf(hashfile, "file: %s, lump: %s, hash: %s, size: %d\n", filename, lump->getName(), cksumout, lump->LumpSize); } } } @@ -383,28 +413,12 @@ int FWadCollection::CheckIfWadLoaded (const char *name) // //========================================================================== -int FWadCollection::GetNumLumps () const -{ - return NumLumps; -} - DEFINE_ACTION_FUNCTION(_Wads, GetNumLumps) { PARAM_PROLOGUE; ACTION_RETURN_INT(Wads.GetNumLumps()); } -//========================================================================== -// -// GetNumFiles -// -//========================================================================== - -int FWadCollection::GetNumWads () const -{ - return Files.Size(); -} - //========================================================================== // // W_CheckNumForName @@ -442,10 +456,10 @@ int FWadCollection::CheckNumForName (const char *name, int space) while (i != NULL_INDEX) { - FResourceLump *lump = LumpInfo[i].lump; - if (lump->qwName == qname) + if (LumpInfo[i].shortName.qword == qname) { + FResourceLump* lump = LumpInfo[i].lump; if (lump->Namespace == space) break; // If the lump is from one of the special namespaces exclusive to Zips // the check has to be done differently: @@ -483,7 +497,7 @@ int FWadCollection::CheckNumForName (const char *name, int space, int wadnum, bo // also those in earlier WADs. while (i != NULL_INDEX && - (lump = LumpInfo[i].lump, lump->qwName != qname || + (lump = LumpInfo[i].lump, LumpInfo[i].shortName.qword != qname || lump->Namespace != space || (exact? (LumpInfo[i].wadnum != wadnum) : (LumpInfo[i].wadnum > wadnum)) )) { @@ -547,12 +561,12 @@ int FWadCollection::CheckNumForFullName (const char *name, bool trynormal, int n for (i = fli[MakeKey(name) % NumLumps]; i != NULL_INDEX; i = nli[i]) { - if (strnicmp(name, LumpInfo[i].lump->FullName, len)) continue; - if (LumpInfo[i].lump->FullName[len] == 0) break; // this is a full match - if (ignoreext && LumpInfo[i].lump->FullName[len] == '.') + if (strnicmp(name, LumpInfo[i].longName, len)) continue; + if (LumpInfo[i].longName[len] == 0) break; // this is a full match + if (ignoreext && LumpInfo[i].longName[len] == '.') { // is this the last '.' in the last path element, indicating that the remaining part of the name is only an extension? - if (strpbrk(LumpInfo[i].lump->FullName.GetChars() + len + 1, "./") == nullptr) break; + if (strpbrk(LumpInfo[i].longName.GetChars() + len + 1, "./") == nullptr) break; } } @@ -584,7 +598,7 @@ int FWadCollection::CheckNumForFullName (const char *name, int wadnum) i = FirstLumpIndex_FullName[MakeKey (name) % NumLumps]; while (i != NULL_INDEX && - (stricmp(name, LumpInfo[i].lump->FullName) || LumpInfo[i].wadnum != wadnum)) + (stricmp(name, LumpInfo[i].longName) || LumpInfo[i].wadnum != wadnum)) { i = NextLumpIndex_FullName[i]; } @@ -730,7 +744,6 @@ uint32_t FWadCollection::LumpNameHash (const char *s) void FWadCollection::InitHashChains (void) { - char name[8]; unsigned int i, j; // Mark all buckets as empty @@ -744,19 +757,18 @@ void FWadCollection::InitHashChains (void) // Now set up the chains for (i = 0; i < (unsigned)NumLumps; i++) { - uppercopy (name, LumpInfo[i].lump->Name); - j = LumpNameHash (name) % NumLumps; + j = LumpNameHash (LumpInfo[i].shortName.String) % NumLumps; NextLumpIndex[i] = FirstLumpIndex[j]; FirstLumpIndex[j] = i; // Do the same for the full paths - if (LumpInfo[i].lump->FullName.IsNotEmpty()) + if (LumpInfo[i].longName.IsNotEmpty()) { - j = MakeKey(LumpInfo[i].lump->FullName) % NumLumps; + j = MakeKey(LumpInfo[i].longName) % NumLumps; NextLumpIndex_FullName[i] = FirstLumpIndex_FullName[j]; FirstLumpIndex_FullName[j] = i; - FString nameNoExt = LumpInfo[i].lump->FullName; + FString nameNoExt = LumpInfo[i].longName; auto dot = nameNoExt.LastIndexOf('.'); auto slash = nameNoExt.LastIndexOf('/'); if (dot > slash) nameNoExt.Truncate(dot); @@ -862,7 +874,7 @@ void FWadCollection::RenameSprites (const TArray &deletelumps) // some frames need to be renamed. if (LumpInfo[i].lump->Namespace == ns_sprites) { - if (LumpInfo[i].lump->dwName == MAKE_ID('M', 'N', 'T', 'R') && LumpInfo[i].lump->Name[4] == 'Z' ) + if (LumpInfo[i].shortName.dword == MAKE_ID('M', 'N', 'T', 'R') && LumpInfo[i].shortName.String[4] == 'Z' ) { MNTRZfound = true; break; @@ -881,30 +893,30 @@ void FWadCollection::RenameSprites (const TArray &deletelumps) { for (int j = 0; j < numrenames; ++j) { - if (LumpInfo[i].lump->dwName == renames[j*2]) + if (LumpInfo[i].shortName.dword == renames[j*2]) { - LumpInfo[i].lump->dwName = renames[j*2+1]; + LumpInfo[i].shortName.dword = renames[j*2+1]; } } if (gameinfo.gametype == GAME_Hexen) { - if (CheckLumpName (i, "ARTIINVU")) + if (CheckLumpName(i, "ARTIINVU")) { - LumpInfo[i].lump->Name[4]='D'; LumpInfo[i].lump->Name[5]='E'; - LumpInfo[i].lump->Name[6]='F'; LumpInfo[i].lump->Name[7]='N'; + LumpInfo[i].shortName.String[4] = 'D'; LumpInfo[i].shortName.String[5] = 'E'; + LumpInfo[i].shortName.String[6] = 'F'; LumpInfo[i].shortName.String[7] = 'N'; } } } if (!MNTRZfound) { - if (LumpInfo[i].lump->dwName == MAKE_ID('M', 'N', 'T', 'R')) + if (LumpInfo[i].shortName.dword == MAKE_ID('M', 'N', 'T', 'R')) { for (size_t fi : {4, 6}) { - if (LumpInfo[i].lump->Name[fi] >= 'F' && LumpInfo[i].lump->Name[fi] <= 'K') + if (LumpInfo[i].shortName.String[fi] >= 'F' && LumpInfo[i].shortName.String[fi] <= 'K') { - LumpInfo[i].lump->Name[fi] += 'U' - 'F'; + LumpInfo[i].shortName.String[fi] += 'U' - 'F'; } } } @@ -914,22 +926,22 @@ void FWadCollection::RenameSprites (const TArray &deletelumps) // the same blood states can be used everywhere if (!(gameinfo.gametype & GAME_DoomChex)) { - if (LumpInfo[i].lump->dwName == MAKE_ID('B', 'L', 'O', 'D')) + if (LumpInfo[i].shortName.dword == MAKE_ID('B', 'L', 'O', 'D')) { - LumpInfo[i].lump->dwName = MAKE_ID('B', 'L', 'U', 'D'); + LumpInfo[i].shortName.dword = MAKE_ID('B', 'L', 'U', 'D'); } } } else if (LumpInfo[i].lump->Namespace == ns_global) { - if (LumpInfo[i].wadnum >= GetIwadNum() && LumpInfo[i].wadnum <= GetMaxIwadNum() && deletelumps.Find(LumpInfo[i].lump->Name) < deletelumps.Size()) + if (LumpInfo[i].wadnum >= GetIwadNum() && LumpInfo[i].wadnum <= GetMaxIwadNum() && deletelumps.Find(LumpInfo[i].shortName.String) < deletelumps.Size()) { - LumpInfo[i].lump->Name[0] = 0; // Lump must be deleted from directory. + LumpInfo[i].shortName.String[0] = 0; // Lump must be deleted from directory. } // Rename the game specific big font lumps so that the font manager does not have to do problematic special checks for them. - else if (!strcmp(LumpInfo[i].lump->Name, altbigfont)) + else if (!strcmp(LumpInfo[i].shortName.String, altbigfont)) { - strcpy(LumpInfo[i].lump->Name, "BIGFONT"); + strcpy(LumpInfo[i].shortName.String, "BIGFONT"); } } } @@ -997,16 +1009,16 @@ void FWadCollection::RenameNerve () { // Only rename the maps from NERVE.WAD assert(LumpInfo[i].wadnum == w); - if (LumpInfo[i].lump->dwName == MAKE_ID('C', 'W', 'I', 'L')) + if (LumpInfo[i].shortName.dword == MAKE_ID('C', 'W', 'I', 'L')) { - LumpInfo[i].lump->Name[0] = 'N'; + LumpInfo[i].shortName.String[0] = 'N'; } - else if (LumpInfo[i].lump->dwName == MAKE_ID('M', 'A', 'P', '0')) + else if (LumpInfo[i].shortName.dword == MAKE_ID('M', 'A', 'P', '0')) { - LumpInfo[i].lump->Name[6] = LumpInfo[i].lump->Name[4]; - LumpInfo[i].lump->Name[5] = '0'; - LumpInfo[i].lump->Name[4] = 'L'; - LumpInfo[i].lump->dwName = MAKE_ID('L', 'E', 'V', 'E'); + LumpInfo[i].shortName.String[6] = LumpInfo[i].shortName.String[4]; + LumpInfo[i].shortName.String[5] = '0'; + LumpInfo[i].shortName.String[4] = 'L'; + LumpInfo[i].shortName.dword = MAKE_ID('L', 'E', 'V', 'E'); } } } @@ -1088,7 +1100,7 @@ void FWadCollection::FixMacHexen() for (int i = lastLump - EXTRA_LUMPS + 1; i <= lastLump; ++i) { - LumpInfo[i].lump->Name[0] = '\0'; + LumpInfo[i].shortName.String[0] = '\0'; } } @@ -1117,13 +1129,16 @@ void FWadCollection::MoveLumpsInFolder(const char *path) { auto& li = LumpInfo[i]; if (li.wadnum >= GetIwadNum()) break; - if (li.lump->FullName.Left(len).CompareNoCase(path) == 0) + if (li.longName.Left(len).CompareNoCase(path) == 0) { LumpInfo.Push(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 &ln = LumpInfo.Last(); ln.wadnum = wadnum; // pretend this is from the WAD this is injected into. - ln.lump->LumpNameSetup(ln.lump->FullName.Mid(len)); + ln.lump->LumpNameSetup(ln.longName.Mid(len)); + ln.linkedTexture = nullptr; + strcpy(ln.shortName.String, ln.lump->shortName()); + ln.longName = ln.lump->longName(); } } } @@ -1154,7 +1169,7 @@ int FWadCollection::FindLump (const char *name, int *lastlump, bool anyns) { FResourceLump *lump = lump_p->lump; - if ((anyns || lump->Namespace == ns_global) && lump->qwName == qname) + if ((anyns || lump->Namespace == ns_global) && lump_p->shortName.qword == qname) { int lump = int(lump_p - &LumpInfo[0]); *lastlump = lump + 1; @@ -1201,7 +1216,7 @@ int FWadCollection::FindLumpMulti (const char **names, int *lastlump, bool anyns for(const char **name = names; *name != NULL; name++) { - if (!strnicmp(*name, lump->Name, 8)) + if (!strnicmp(*name, lump_p->shortName.String, 8)) { int lump = int(lump_p - &LumpInfo[0]); *lastlump = lump + 1; @@ -1228,7 +1243,7 @@ bool FWadCollection::CheckLumpName (int lump, const char *name) if ((size_t)lump >= NumLumps) return false; - return !strnicmp (LumpInfo[lump].lump->Name, name, 8); + return !strnicmp (LumpInfo[lump].shortName.String, name, 8); } //========================================================================== @@ -1242,7 +1257,15 @@ void FWadCollection::GetLumpName (char *to, int lump) const if ((size_t)lump >= NumLumps) *to = 0; else - uppercopy (to, LumpInfo[lump].lump->Name); + uppercopy (to, LumpInfo[lump].shortName.String); +} + +const char* FWadCollection::GetLumpName(int lump) const +{ + if ((size_t)lump >= NumLumps) + return nullptr; + else + return LumpInfo[lump].shortName.String; } void FWadCollection::GetLumpName(FString &to, int lump) const @@ -1250,7 +1273,7 @@ void FWadCollection::GetLumpName(FString &to, int lump) const if ((size_t)lump >= NumLumps) to = FString(); else { - to = LumpInfo[lump].lump->Name; + to = LumpInfo[lump].shortName.String; to.ToUpper(); } } @@ -1272,14 +1295,15 @@ DEFINE_ACTION_FUNCTION(_Wads, GetLumpName) // //========================================================================== -const char *FWadCollection::GetLumpFullName (int lump) const +const char *FWadCollection::GetLumpFullName (int lump, bool returnshort) const { if ((size_t)lump >= NumLumps) return NULL; - else if (LumpInfo[lump].lump->FullName.IsNotEmpty()) - return LumpInfo[lump].lump->FullName; - else - return LumpInfo[lump].lump->Name; + else if (LumpInfo[lump].longName.IsNotEmpty()) + return LumpInfo[lump].longName; + else if (returnshort) + return LumpInfo[lump].shortName.String; + else return nullptr; } DEFINE_ACTION_FUNCTION(_Wads, GetLumpFullName) @@ -1399,12 +1423,12 @@ unsigned FWadCollection::GetLumpsInFolder(const char *inpath, TArrayFullName.IndexOf(path) == 0) + if (LumpInfo[i].longName.IndexOf(path) == 0) { // Only if it hasn't been replaced. - if ((unsigned)Wads.CheckNumForFullName(LumpInfo[i].lump->FullName) == i) + if ((unsigned)Wads.CheckNumForFullName(LumpInfo[i].longName) == i) { - result.Push({ LumpInfo[i].lump->FullName.GetChars(), i }); + result.Push({ LumpInfo[i].longName.GetChars(), i }); } } } diff --git a/src/gamedata/w_wad.h b/src/gamedata/w_wad.h index 610e67e9a5..368f74a6dc 100644 --- a/src/gamedata/w_wad.h +++ b/src/gamedata/w_wad.h @@ -121,8 +121,9 @@ public: int GetMaxIwadNum() { return MaxIwadIndex; } void SetMaxIwadNum(int x) { MaxIwadIndex = x; } - void InitMultipleFiles (TArray &filenames, const TArray &deletelumps); - void AddFile (const char *filename, FileReader *wadinfo = NULL); + void InitSingleFile(const char *filename, bool quiet = false); + void InitMultipleFiles (TArray &filenames, const TArray &deletelumps, bool quiet = false); + void AddFile (const char *filename, FileReader *wadinfo = NULL, bool quiet = false); int CheckIfWadLoaded (const char *name); const char *GetWadName (int wadnum) const; @@ -176,7 +177,8 @@ public: int GetLumpFlags (int lump); // Return the flags for this lump void GetLumpName (char *to, int lump) const; // [RH] Copies the lump name to to using uppercopy void GetLumpName (FString &to, int lump) const; - const char *GetLumpFullName (int lump) const; // [RH] Returns the lump's full name + const char* GetLumpName(int lump) const; + const char *GetLumpFullName (int lump, bool returnshort = true) const; // [RH] Returns the lump's full name FString GetLumpFullPath (int lump) const; // [RH] Returns wad's name + lump's full name int GetLumpFile (int lump) const; // [RH] Returns wadnum for a specified lump int GetLumpNamespace (int lump) const; // [RH] Returns the namespace a lump belongs to @@ -187,8 +189,15 @@ public: bool IsEncryptedFile(int lump) const; - int GetNumLumps () const; - int GetNumWads () const; + int GetNumLumps() const + { + return NumLumps; + } + + int GetNumWads() const + { + return Files.Size(); + } int AddExternalFile(const char *filename); diff --git a/src/maploader/glnodes.cpp b/src/maploader/glnodes.cpp index d72c3f220c..b0757fa31b 100644 --- a/src/maploader/glnodes.cpp +++ b/src/maploader/glnodes.cpp @@ -792,7 +792,7 @@ static int FindGLNodesInFile(FResourceFile * f, const char * label) { for(uint32_t i=0;iGetLump(i)->Name, glheader, 8)) + if (!strnicmp(f->GetLump(i)->getName(), glheader, 8)) { if (mustcheck) { @@ -899,7 +899,7 @@ bool MapLoader::LoadGLNodes(MapData * map) result=true; for(unsigned i=0; i<4;i++) { - if (strnicmp(f_gwa->GetLump(li+i+1)->Name, check[i], 8)) + if (strnicmp(f_gwa->GetLump(li+i+1)->getName(), check[i], 8)) { result=false; break; diff --git a/src/p_openmap.cpp b/src/p_openmap.cpp index efb8571e50..7ab4ec1042 100644 --- a/src/p_openmap.cpp +++ b/src/p_openmap.cpp @@ -284,11 +284,11 @@ MapData *P_OpenMapData(const char * mapname, bool justcheck) int index=0; map->MapLumps[0].Reader = map->resource->GetLump(0)->NewReader(); - strncpy(map->MapLumps[0].Name, map->resource->GetLump(0)->Name, 8); + uppercopy(map->MapLumps[0].Name, map->resource->GetLump(0)->getName()); for(uint32_t i = 1; i < map->resource->LumpCount(); i++) { - const char* lumpname = map->resource->GetLump(i)->Name; + const char* lumpname = map->resource->GetLump(i)->getName(); if (i == 1 && !strnicmp(lumpname, "TEXTMAP", 8)) { @@ -297,7 +297,7 @@ MapData *P_OpenMapData(const char * mapname, bool justcheck) strncpy(map->MapLumps[ML_TEXTMAP].Name, lumpname, 8); for(int i = 2;; i++) { - lumpname = map->resource->GetLump(i)->Name; + lumpname = map->resource->GetLump(i)->getName(); if (!strnicmp(lumpname, "ZNODES",8)) { index = ML_GLZNODES;