- moved the file name management out of the single resource lumps.

This is now being managed by the main file system class. The single lumps should only concern themselves with the actual data they manage, not with how the file system presents them to the outside.
The IWAD detection code was also switched to use a file system wrapper instead of looking at the single files directly.
This commit is contained in:
Christoph Oelckers 2020-04-11 13:14:52 +02:00
parent 89fb479c19
commit a38633aa22
11 changed files with 210 additions and 218 deletions

View file

@ -43,7 +43,6 @@
#include "sc_man.h" #include "sc_man.h"
#include "v_video.h" #include "v_video.h"
#include "gameconfigfile.h" #include "gameconfigfile.h"
#include "resourcefiles/resourcefile.h"
#include "version.h" #include "version.h"
#include "engineerrors.h" #include "engineerrors.h"
#include "v_text.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); FWadCollection check;
if (resfile != NULL) TArray<FString> fns;
{ TArray<FString> deletes;
uint32_t cnt = resfile->LumpCount(); fns.Push(firstfn);
for(int i=cnt-1; i>=0; i--) if (optfn) fns.Push(optfn);
{
FResourceLump *lmp = resfile->GetLump(i);
if (lmp->Namespace == ns_global && !stricmp(lmp->Name, "IWADINFO")) check.InitMultipleFiles(fns, deletes, true);
{ if (check.GetNumLumps() > 0)
// Found one! {
ParseIWadInfo(resfile->FileName, (const char*)lmp->CacheLump(), lmp->LumpSize); int num = check.CheckNumForName("IWADINFO");
break; if (num >= 0)
}
}
delete resfile;
if (mIWadNames.Size() == 0 || mIWadInfos.Size() == 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) int FIWadManager::ScanIWAD (const char *iwad)
{ {
FResourceFile *iwadfile = FResourceFile::OpenResourceFile(iwad, true); FWadCollection check;
check.InitSingleFile(iwad, true);
mLumpsFound.Resize(mIWadInfos.Size()); 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])); 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); CheckLumpName(check.GetLumpName(ii));
if (lump->FullName.IsNotEmpty()) auto full = check.GetLumpFullName(ii, false);
if (full && strnicmp(full, "maps/", 5) == 0)
{ {
if (strnicmp(lump->FullName, "maps/", 5) == 0) FString mapname(&full[5], strcspn(&full[5], "."));
{ CheckLumpName(mapname);
FString mapname(&lump->FullName[5], strcspn(&lump->FullName[5], "."));
CheckLumpName(mapname);
}
} }
} }
delete iwadfile;
} }
for (unsigned i = 0; i< mIWadInfos.Size(); i++) 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); FWadCollection check;
if (resfile != NULL)
check.InitSingleFile(fn, true);
if (check.GetNumLumps() > 0)
{ {
uint32_t cnt = resfile->LumpCount(); int num = check.CheckNumForName("IWADINFO");
for (int i = cnt - 1; i >= 0; i--) if (num >= 0)
{ {
FResourceLump *lmp = resfile->GetLump(i); try
if (lmp->Namespace == ns_global && !stricmp(lmp->Name, "IWADINFO"))
{ {
// 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) }
{ catch (CRecoverableError & err)
delete resfile; {
Printf(TEXTCOLOR_RED "%s: %s\nFile has been removed from the list of IWADs\n", fn, err.GetMessage()); Printf(TEXTCOLOR_RED "%s: %s\nFile has been removed from the list of IWADs\n", fn, err.what());
return -1; return -1;
}
break;
} }
} }
delete resfile;
Printf(TEXTCOLOR_RED "%s: Unable to find IWADINFO\nFile has been removed from the list of IWADs\n", fn); Printf(TEXTCOLOR_RED "%s: Unable to find IWADINFO\nFile has been removed from the list of IWADs\n", fn);
return -1; return -1;
} }

View file

@ -2018,49 +2018,20 @@ static FString ParseGameInfo(TArray<FString> &pwads, const char *fn, const char
static FString CheckGameInfo(TArray<FString> & pwads) static FString CheckGameInfo(TArray<FString> & pwads)
{ {
// scan the list of WADs backwards to find the last one that contains a GAMEINFO lump TArray<FString> deletes;
for(int i=pwads.Size()-1; i>=0; i--) 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; int num = check.CheckNumForName("GAMEINFO");
FResourceFile *resfile; if (num >= 0)
const char *filename = pwads[i];
// Does this exist? If so, is it a directory?
if (!DirEntryExists(pwads[i], &isdir))
{ {
Printf(TEXTCOLOR_RED "Could not stat %s\n", filename); // Found one!
continue; auto data = check.ReadLumpIntoArray(num);
} auto wadname = check.GetWadName(check.GetLumpFile(num));
return ParseGameInfo(pwads, wadname, (const char*)data.Data(), data.Size());
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;
} }
} }
return ""; return "";

View file

@ -1802,11 +1802,12 @@ void G_ReadSnapshots(FResourceFile *resf)
FResourceLump * resl = resf->GetLump(j); FResourceLump * resl = resf->GetLump(j);
if (resl != nullptr) if (resl != nullptr)
{ {
auto ptr = strstr(resl->FullName, ".map.json"); auto name = resl->getName();
auto ptr = strstr(name, ".map.json");
if (ptr != nullptr) if (ptr != nullptr)
{ {
ptrdiff_t maplen = ptr - resl->FullName.GetChars(); ptrdiff_t maplen = ptr - name;
FString mapname(resl->FullName.GetChars(), (size_t)maplen); FString mapname(name, (size_t)maplen);
i = FindLevelInfo(mapname); i = FindLevelInfo(mapname);
if (i != nullptr) if (i != nullptr)
{ {
@ -1815,11 +1816,11 @@ void G_ReadSnapshots(FResourceFile *resf)
} }
else else
{ {
auto ptr = strstr(resl->FullName, ".mapd.json"); auto ptr = strstr(name, ".mapd.json");
if (ptr != nullptr) if (ptr != nullptr)
{ {
ptrdiff_t maplen = ptr - resl->FullName.GetChars(); ptrdiff_t maplen = ptr - name;
FString mapname(resl->FullName.GetChars(), (size_t)maplen); FString mapname(name, (size_t)maplen);
TheDefaultLevelInfo.Snapshot = resl->GetRawData(); TheDefaultLevelInfo.Snapshot = resl->GetRawData();
} }
} }

View file

@ -70,17 +70,15 @@ FLumpFile::FLumpFile(const char *filename, FileReader &file)
bool FLumpFile::Open(bool quiet) bool FLumpFile::Open(bool quiet)
{ {
FString name(ExtractFileBase (FileName)); FString name(ExtractFileBase(FileName, true));
Lumps.Resize(1); Lumps.Resize(1);
uppercopy(Lumps[0].Name, name); Lumps[0].LumpNameSetup(name);
Lumps[0].Name[8] = 0;
Lumps[0].Owner = this; Lumps[0].Owner = this;
Lumps[0].Position = 0; Lumps[0].Position = 0;
Lumps[0].LumpSize = (int)Reader.GetLength(); Lumps[0].LumpSize = (int)Reader.GetLength();
Lumps[0].Namespace = ns_global; Lumps[0].Namespace = ns_global;
Lumps[0].Flags = 0; Lumps[0].Flags = 0;
Lumps[0].FullName = "";
NumLumps = 1; NumLumps = 1;
if (!quiet) if (!quiet)
{ {

View file

@ -349,12 +349,6 @@ bool FZipFile::Open(bool quiet)
lump_p->Position = LittleLong(zip_fh->LocalHeaderOffset); lump_p->Position = LittleLong(zip_fh->LocalHeaderOffset);
lump_p->CheckEmbedded(); 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++; lump_p++;
} }
// Resize the lump record array to its actual size // Resize the lump record array to its actual size

View file

@ -94,6 +94,12 @@ FResourceLump::~FResourceLump()
void FResourceLump::LumpNameSetup(FString iname) void FResourceLump::LumpNameSetup(FString iname)
{ {
// this causes interference with real Dehacked lumps.
if (!iname.CompareNoCase("dehacked.exe"))
{
iname = "";
}
long slash = iname.LastIndexOf('/'); long slash = iname.LastIndexOf('/');
FString base = (slash >= 0) ? iname.Mid(slash + 1) : iname; FString base = (slash >= 0) ? iname.Mid(slash + 1) : iname;
auto dot = base.LastIndexOf('.'); auto dot = base.LastIndexOf('.');
@ -350,8 +356,7 @@ int lumpcmp(const void * a, const void * b)
{ {
FResourceLump * rec1 = (FResourceLump *)a; FResourceLump * rec1 = (FResourceLump *)a;
FResourceLump * rec2 = (FResourceLump *)b; FResourceLump * rec2 = (FResourceLump *)b;
return stricmp(rec1->getName(), rec2->getName());
return rec1->FullName.CompareNoCase(rec2->FullName);
} }
//========================================================================== //==========================================================================
@ -768,15 +773,12 @@ bool FMemoryFile::Open(bool quiet)
FString fname(ExtractFileBase(FileName, true)); FString fname(ExtractFileBase(FileName, true));
Lumps.Resize(1); Lumps.Resize(1);
uppercopy(Lumps[0].Name, name); Lumps[0].LumpNameSetup(fname);
Lumps[0].Name[8] = 0;
Lumps[0].FullName = fname;
Lumps[0].Owner = this; Lumps[0].Owner = this;
Lumps[0].Position = 0; Lumps[0].Position = 0;
Lumps[0].LumpSize = (int)Reader.GetLength(); Lumps[0].LumpSize = (int)Reader.GetLength();
Lumps[0].Namespace = ns_global; Lumps[0].Namespace = ns_global;
Lumps[0].Flags = 0; Lumps[0].Flags = 0;
Lumps[0].FullName = "";
NumLumps = 1; NumLumps = 1;
return true; return true;
} }

View file

@ -33,8 +33,10 @@ struct FCompressedBuffer
struct FResourceLump struct FResourceLump
{ {
friend class FResourceFile; friend class FResourceFile;
friend class FWadFile; // this still needs direct access.
int LumpSize; int LumpSize;
protected:
FString FullName; // only valid for files loaded from a non-wad archive FString FullName; // only valid for files loaded from a non-wad archive
union union
{ {
@ -43,6 +45,7 @@ struct FResourceLump
uint32_t dwName; // These are for accessing the first 4 or 8 chars of 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 uint64_t qwName; // Name as a unit without breaking strict aliasing rules
}; };
public:
uint8_t Flags; uint8_t Flags;
int8_t RefCount; int8_t RefCount;
char * Cache; char * Cache;
@ -71,6 +74,10 @@ struct FResourceLump
void *CacheLump(); void *CacheLump();
int ReleaseCache(); int ReleaseCache();
const char* shortName() { return Name; }
const FString &longName() { return FullName; }
const char* getName() { return FullName.IsNotEmpty() ? FullName.GetChars() : Name; }
protected: protected:
virtual int FillCache() { return -1; } virtual int FillCache() { return -1; }

View file

@ -60,11 +60,23 @@
// //
// WADFILE I/O related stuff. // 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 struct FWadCollection::LumpRecord
{ {
int wadnum; int wadnum;
FResourceLump *lump; FResourceLump *lump;
FTexture* linkedTexture; FTexture* linkedTexture;
LumpShortName shortName;
FString longName;
}; };
// EXTERNAL FUNCTION PROTOTYPES -------------------------------------------- // EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
@ -150,7 +162,15 @@ void FWadCollection::DeleteAll ()
// //
//========================================================================== //==========================================================================
void FWadCollection::InitMultipleFiles (TArray<FString> &filenames, const TArray<FString> &deletelumps) void FWadCollection::InitSingleFile(const char* filename, bool quiet)
{
TArray<FString> filenames;
TArray<FString> deletes;
filenames.Push(filename);
InitMultipleFiles(filenames, deletes, true);
}
void FWadCollection::InitMultipleFiles (TArray<FString> &filenames, const TArray<FString> &deletelumps, bool quiet)
{ {
int numfiles; int numfiles;
@ -161,7 +181,7 @@ void FWadCollection::InitMultipleFiles (TArray<FString> &filenames, const TArray
for(unsigned i=0;i<filenames.Size(); i++) for(unsigned i=0;i<filenames.Size(); i++)
{ {
int baselump = NumLumps; int baselump = NumLumps;
AddFile (filenames[i]); AddFile (filenames[i], nullptr, quiet);
if (i == (unsigned)MaxIwadIndex) MoveLumpsInFolder("after_iwad/"); if (i == (unsigned)MaxIwadIndex) MoveLumpsInFolder("after_iwad/");
FStringf path("filter/%s", Files.Last()->GetHash().GetChars()); FStringf path("filter/%s", Files.Last()->GetHash().GetChars());
@ -171,7 +191,8 @@ void FWadCollection::InitMultipleFiles (TArray<FString> &filenames, const TArray
NumLumps = LumpInfo.Size(); NumLumps = LumpInfo.Size();
if (NumLumps == 0) if (NumLumps == 0)
{ {
I_FatalError ("W_InitMultipleFiles: no files found"); if (!quiet) I_FatalError("W_InitMultipleFiles: no files found");
else return;
} }
RenameNerve(); RenameNerve();
RenameSprites(deletelumps); RenameSprites(deletelumps);
@ -206,6 +227,8 @@ int FWadCollection::AddExternalFile(const char *filename)
lumprec->lump = lump; lumprec->lump = lump;
lumprec->wadnum = -1; lumprec->wadnum = -1;
lumprec->linkedTexture = nullptr; lumprec->linkedTexture = nullptr;
memcpy(lumprec->shortName.String, lump->shortName(), 9);
lumprec->longName = lump->longName();
return LumpInfo.Size()-1; // later return LumpInfo.Size()-1; // later
} }
@ -219,7 +242,7 @@ int FWadCollection::AddExternalFile(const char *filename)
// [RH] Removed reload hack // [RH] Removed reload hack
//========================================================================== //==========================================================================
void FWadCollection::AddFile (const char *filename, FileReader *wadr) void FWadCollection::AddFile (const char *filename, FileReader *wadr, bool quiet)
{ {
int startlump; int startlump;
bool isdir = false; bool isdir = false;
@ -230,8 +253,11 @@ void FWadCollection::AddFile (const char *filename, FileReader *wadr)
// Does this exist? If so, is it a directory? // Does this exist? If so, is it a directory?
if (!DirEntryExists(filename, &isdir)) if (!DirEntryExists(filename, &isdir))
{ {
Printf(TEXTCOLOR_RED "%s: File or Directory not found\n", filename); if (!quiet)
PrintLastError(); {
Printf(TEXTCOLOR_RED "%s: File or Directory not found\n", filename);
PrintLastError();
}
return; return;
} }
@ -239,23 +265,26 @@ void FWadCollection::AddFile (const char *filename, FileReader *wadr)
{ {
if (!wadreader.OpenFile(filename)) if (!wadreader.OpenFile(filename))
{ // Didn't find file { // Didn't find file
Printf (TEXTCOLOR_RED "%s: File not found\n", filename); if (!quiet)
PrintLastError (); {
Printf(TEXTCOLOR_RED "%s: File not found\n", filename);
PrintLastError();
}
return; return;
} }
} }
} }
else wadreader = std::move(*wadr); else wadreader = std::move(*wadr);
if (!batchrun) Printf (" adding %s", filename); if (!batchrun && !quiet) Printf (" adding %s", filename);
startlump = NumLumps; startlump = NumLumps;
FResourceFile *resfile; FResourceFile *resfile;
if (!isdir) if (!isdir)
resfile = FResourceFile::OpenResourceFile(filename, wadreader); resfile = FResourceFile::OpenResourceFile(filename, wadreader, quiet);
else else
resfile = FResourceFile::OpenDirectory(filename); resfile = FResourceFile::OpenDirectory(filename, quiet);
if (resfile != NULL) if (resfile != NULL)
{ {
@ -269,6 +298,9 @@ void FWadCollection::AddFile (const char *filename, FileReader *wadr)
lump_p->lump = lump; lump_p->lump = lump;
lump_p->wadnum = Files.Size(); 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<int>(Files.Size()) == GetIwadNum() && gameinfo.gametype == GAME_Strife && gameinfo.flags & GI_SHAREWARE) if (static_cast<int>(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) if (lump->Flags & LUMPF_EMBEDDED)
{ {
FString path; FString path;
path.Format("%s:%s", filename, lump->FullName.GetChars()); path.Format("%s:%s", filename, lump->getName());
auto embedded = lump->NewReader(); auto embedded = lump->NewReader();
AddFile(path, &embedded); AddFile(path, &embedded);
} }
} }
if (hashfile) if (hashfile && !quiet)
{ {
uint8_t cksum[16]; uint8_t cksum[16];
char cksumout[33]; char cksumout[33];
@ -329,9 +361,7 @@ void FWadCollection::AddFile (const char *filename, FileReader *wadr)
sprintf(cksumout + (j * 2), "%02X", cksum[j]); sprintf(cksumout + (j * 2), "%02X", cksum[j]);
} }
fprintf(hashfile, "file: %s, lump: %s, hash: %s, size: %d\n", filename, fprintf(hashfile, "file: %s, lump: %s, hash: %s, size: %d\n", filename, lump->getName(), cksumout, lump->LumpSize);
lump->FullName.IsNotEmpty() ? lump->FullName.GetChars() : lump->Name,
cksumout, lump->LumpSize);
} }
} }
} }
@ -383,28 +413,12 @@ int FWadCollection::CheckIfWadLoaded (const char *name)
// //
//========================================================================== //==========================================================================
int FWadCollection::GetNumLumps () const
{
return NumLumps;
}
DEFINE_ACTION_FUNCTION(_Wads, GetNumLumps) DEFINE_ACTION_FUNCTION(_Wads, GetNumLumps)
{ {
PARAM_PROLOGUE; PARAM_PROLOGUE;
ACTION_RETURN_INT(Wads.GetNumLumps()); ACTION_RETURN_INT(Wads.GetNumLumps());
} }
//==========================================================================
//
// GetNumFiles
//
//==========================================================================
int FWadCollection::GetNumWads () const
{
return Files.Size();
}
//========================================================================== //==========================================================================
// //
// W_CheckNumForName // W_CheckNumForName
@ -442,10 +456,10 @@ int FWadCollection::CheckNumForName (const char *name, int space)
while (i != NULL_INDEX) 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 (lump->Namespace == space) break;
// If the lump is from one of the special namespaces exclusive to Zips // If the lump is from one of the special namespaces exclusive to Zips
// the check has to be done differently: // 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. // also those in earlier WADs.
while (i != NULL_INDEX && while (i != NULL_INDEX &&
(lump = LumpInfo[i].lump, lump->qwName != qname || (lump = LumpInfo[i].lump, LumpInfo[i].shortName.qword != qname ||
lump->Namespace != space || lump->Namespace != space ||
(exact? (LumpInfo[i].wadnum != wadnum) : (LumpInfo[i].wadnum > wadnum)) )) (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]) for (i = fli[MakeKey(name) % NumLumps]; i != NULL_INDEX; i = nli[i])
{ {
if (strnicmp(name, LumpInfo[i].lump->FullName, len)) continue; if (strnicmp(name, LumpInfo[i].longName, len)) continue;
if (LumpInfo[i].lump->FullName[len] == 0) break; // this is a full match if (LumpInfo[i].longName[len] == 0) break; // this is a full match
if (ignoreext && LumpInfo[i].lump->FullName[len] == '.') 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? // 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]; i = FirstLumpIndex_FullName[MakeKey (name) % NumLumps];
while (i != NULL_INDEX && 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]; i = NextLumpIndex_FullName[i];
} }
@ -730,7 +744,6 @@ uint32_t FWadCollection::LumpNameHash (const char *s)
void FWadCollection::InitHashChains (void) void FWadCollection::InitHashChains (void)
{ {
char name[8];
unsigned int i, j; unsigned int i, j;
// Mark all buckets as empty // Mark all buckets as empty
@ -744,19 +757,18 @@ void FWadCollection::InitHashChains (void)
// Now set up the chains // Now set up the chains
for (i = 0; i < (unsigned)NumLumps; i++) for (i = 0; i < (unsigned)NumLumps; i++)
{ {
uppercopy (name, LumpInfo[i].lump->Name); j = LumpNameHash (LumpInfo[i].shortName.String) % NumLumps;
j = LumpNameHash (name) % NumLumps;
NextLumpIndex[i] = FirstLumpIndex[j]; NextLumpIndex[i] = FirstLumpIndex[j];
FirstLumpIndex[j] = i; FirstLumpIndex[j] = i;
// Do the same for the full paths // 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]; NextLumpIndex_FullName[i] = FirstLumpIndex_FullName[j];
FirstLumpIndex_FullName[j] = i; FirstLumpIndex_FullName[j] = i;
FString nameNoExt = LumpInfo[i].lump->FullName; FString nameNoExt = LumpInfo[i].longName;
auto dot = nameNoExt.LastIndexOf('.'); auto dot = nameNoExt.LastIndexOf('.');
auto slash = nameNoExt.LastIndexOf('/'); auto slash = nameNoExt.LastIndexOf('/');
if (dot > slash) nameNoExt.Truncate(dot); if (dot > slash) nameNoExt.Truncate(dot);
@ -862,7 +874,7 @@ void FWadCollection::RenameSprites (const TArray<FString> &deletelumps)
// some frames need to be renamed. // some frames need to be renamed.
if (LumpInfo[i].lump->Namespace == ns_sprites) 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; MNTRZfound = true;
break; break;
@ -881,30 +893,30 @@ void FWadCollection::RenameSprites (const TArray<FString> &deletelumps)
{ {
for (int j = 0; j < numrenames; ++j) 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 (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].shortName.String[4] = 'D'; LumpInfo[i].shortName.String[5] = 'E';
LumpInfo[i].lump->Name[6]='F'; LumpInfo[i].lump->Name[7]='N'; LumpInfo[i].shortName.String[6] = 'F'; LumpInfo[i].shortName.String[7] = 'N';
} }
} }
} }
if (!MNTRZfound) 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}) 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<FString> &deletelumps)
// the same blood states can be used everywhere // the same blood states can be used everywhere
if (!(gameinfo.gametype & GAME_DoomChex)) 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) 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. // 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 // Only rename the maps from NERVE.WAD
assert(LumpInfo[i].wadnum == w); 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].shortName.String[6] = LumpInfo[i].shortName.String[4];
LumpInfo[i].lump->Name[5] = '0'; LumpInfo[i].shortName.String[5] = '0';
LumpInfo[i].lump->Name[4] = 'L'; LumpInfo[i].shortName.String[4] = 'L';
LumpInfo[i].lump->dwName = MAKE_ID('L', 'E', 'V', 'E'); 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) 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]; auto& li = LumpInfo[i];
if (li.wadnum >= GetIwadNum()) break; 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); 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. 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(); auto &ln = LumpInfo.Last();
ln.wadnum = wadnum; // pretend this is from the WAD this is injected into. 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; 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]); int lump = int(lump_p - &LumpInfo[0]);
*lastlump = lump + 1; *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++) 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]); int lump = int(lump_p - &LumpInfo[0]);
*lastlump = lump + 1; *lastlump = lump + 1;
@ -1228,7 +1243,7 @@ bool FWadCollection::CheckLumpName (int lump, const char *name)
if ((size_t)lump >= NumLumps) if ((size_t)lump >= NumLumps)
return false; 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) if ((size_t)lump >= NumLumps)
*to = 0; *to = 0;
else 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 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) if ((size_t)lump >= NumLumps)
to = FString(); to = FString();
else { else {
to = LumpInfo[lump].lump->Name; to = LumpInfo[lump].shortName.String;
to.ToUpper(); 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) if ((size_t)lump >= NumLumps)
return NULL; return NULL;
else if (LumpInfo[lump].lump->FullName.IsNotEmpty()) else if (LumpInfo[lump].longName.IsNotEmpty())
return LumpInfo[lump].lump->FullName; return LumpInfo[lump].longName;
else else if (returnshort)
return LumpInfo[lump].lump->Name; return LumpInfo[lump].shortName.String;
else return nullptr;
} }
DEFINE_ACTION_FUNCTION(_Wads, GetLumpFullName) DEFINE_ACTION_FUNCTION(_Wads, GetLumpFullName)
@ -1399,12 +1423,12 @@ unsigned FWadCollection::GetLumpsInFolder(const char *inpath, TArray<FolderEntry
result.Clear(); result.Clear();
for (unsigned i = 0; i < LumpInfo.Size(); i++) for (unsigned i = 0; i < LumpInfo.Size(); i++)
{ {
if (LumpInfo[i].lump->FullName.IndexOf(path) == 0) if (LumpInfo[i].longName.IndexOf(path) == 0)
{ {
// Only if it hasn't been replaced. // 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 });
} }
} }
} }

View file

@ -121,8 +121,9 @@ public:
int GetMaxIwadNum() { return MaxIwadIndex; } int GetMaxIwadNum() { return MaxIwadIndex; }
void SetMaxIwadNum(int x) { MaxIwadIndex = x; } void SetMaxIwadNum(int x) { MaxIwadIndex = x; }
void InitMultipleFiles (TArray<FString> &filenames, const TArray<FString> &deletelumps); void InitSingleFile(const char *filename, bool quiet = false);
void AddFile (const char *filename, FileReader *wadinfo = NULL); void InitMultipleFiles (TArray<FString> &filenames, const TArray<FString> &deletelumps, bool quiet = false);
void AddFile (const char *filename, FileReader *wadinfo = NULL, bool quiet = false);
int CheckIfWadLoaded (const char *name); int CheckIfWadLoaded (const char *name);
const char *GetWadName (int wadnum) const; const char *GetWadName (int wadnum) const;
@ -176,7 +177,8 @@ public:
int GetLumpFlags (int lump); // Return the flags for this lump 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 (char *to, int lump) const; // [RH] Copies the lump name to to using uppercopy
void GetLumpName (FString &to, int lump) const; 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 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 GetLumpFile (int lump) const; // [RH] Returns wadnum for a specified lump
int GetLumpNamespace (int lump) const; // [RH] Returns the namespace a lump belongs to int GetLumpNamespace (int lump) const; // [RH] Returns the namespace a lump belongs to
@ -187,8 +189,15 @@ public:
bool IsEncryptedFile(int lump) const; bool IsEncryptedFile(int lump) const;
int GetNumLumps () const; int GetNumLumps() const
int GetNumWads () const; {
return NumLumps;
}
int GetNumWads() const
{
return Files.Size();
}
int AddExternalFile(const char *filename); int AddExternalFile(const char *filename);

View file

@ -792,7 +792,7 @@ static int FindGLNodesInFile(FResourceFile * f, const char * label)
{ {
for(uint32_t i=0;i<numentries-4;i++) for(uint32_t i=0;i<numentries-4;i++)
{ {
if (!strnicmp(f->GetLump(i)->Name, glheader, 8)) if (!strnicmp(f->GetLump(i)->getName(), glheader, 8))
{ {
if (mustcheck) if (mustcheck)
{ {
@ -899,7 +899,7 @@ bool MapLoader::LoadGLNodes(MapData * map)
result=true; result=true;
for(unsigned i=0; i<4;i++) 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; result=false;
break; break;

View file

@ -284,11 +284,11 @@ MapData *P_OpenMapData(const char * mapname, bool justcheck)
int index=0; int index=0;
map->MapLumps[0].Reader = map->resource->GetLump(0)->NewReader(); 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++) 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)) 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); strncpy(map->MapLumps[ML_TEXTMAP].Name, lumpname, 8);
for(int i = 2;; i++) for(int i = 2;; i++)
{ {
lumpname = map->resource->GetLump(i)->Name; lumpname = map->resource->GetLump(i)->getName();
if (!strnicmp(lumpname, "ZNODES",8)) if (!strnicmp(lumpname, "ZNODES",8))
{ {
index = ML_GLZNODES; index = ML_GLZNODES;