- Rewrote IWAD detection code to use the ResourceFile classes instead of

reading the WAD directory directly. As a side effect it should now be
  possible to use Zip and 7z for IWADs, too.


SVN r1621 (trunk)
This commit is contained in:
Christoph Oelckers 2009-05-30 09:53:38 +00:00
parent 9c4cbedc26
commit 2effc9b803
12 changed files with 155 additions and 134 deletions

View file

@ -1,4 +1,7 @@
May 30, 2009 (Changes by Graf Zahl)
- Rewrote IWAD detection code to use the ResourceFile classes instead of
reading the WAD directory directly. As a side effect it should now be
possible to use Zip and 7z for IWADs, too.
- Added 'EndTitle' nextmap option which goes to the regular title loop after
the game has finished.
- Added NOBOSSRIP flag. Note: we are now at flags6!

View file

@ -44,6 +44,7 @@
#include "m_misc.h"
#include "c_cvars.h"
#include "gameconfigfile.h"
#include "resourcefiles/resourcefile.h"
CVAR (Bool, queryiwad, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG);
@ -188,34 +189,21 @@ static EIWADType ScanIWAD (const char *iwad)
Check_e2m1
};
int lumpsfound[NUM_CHECKLUMPS];
size_t i;
wadinfo_t header;
FILE *f;
memset (lumpsfound, 0, sizeof(lumpsfound));
if ( (f = fopen (iwad, "rb")) )
FResourceFile *iwadfile = FResourceFile::OpenResourceFile(iwad, NULL, true);
if (iwadfile != NULL)
{
fread (&header, sizeof(header), 1, f);
if (header.Magic == IWAD_ID || header.Magic == PWAD_ID)
for(DWORD i = 0; i < iwadfile->LumpCount(); i++)
{
header.NumLumps = LittleLong(header.NumLumps);
if (0 == fseek (f, LittleLong(header.InfoTableOfs), SEEK_SET))
{
for (i = 0; i < (size_t)header.NumLumps; i++)
{
wadlump_t lump;
size_t j;
FResourceLump *lump = iwadfile->GetLump(i);
if (0 == fread (&lump, sizeof(lump), 1, f))
break;
for (j = 0; j < NUM_CHECKLUMPS; j++)
if (strnicmp (lump.Name, checklumps[j], 8) == 0)
lumpsfound[j]++;
}
}
for (DWORD j = 0; j < NUM_CHECKLUMPS; j++)
if (strnicmp (lump->Name, checklumps[j], 8) == 0)
lumpsfound[j]++;
}
fclose (f);
delete iwadfile;
}
// Always check for custom iwads first.

View file

@ -194,7 +194,7 @@ class F7ZFile : public FResourceFile
public:
F7ZFile(const char * filename, FileReader *filer);
bool Open();
bool Open(bool quiet);
virtual ~F7ZFile();
virtual FResourceLump *GetLump(int no) { return ((unsigned)no < NumLumps)? &Lumps[no] : NULL; }
};
@ -230,7 +230,7 @@ F7ZFile::F7ZFile(const char * filename, FileReader *filer)
//
//==========================================================================
bool F7ZFile::Open()
bool F7ZFile::Open(bool quiet)
{
Archive = new C7zArchive(Reader);
int skipped = 0;
@ -241,22 +241,25 @@ bool F7ZFile::Open()
{
delete Archive;
Archive = NULL;
Printf("\n"TEXTCOLOR_RED"%s: ", Filename);
if (res == SZ_ERROR_UNSUPPORTED)
if (!quiet)
{
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);
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;
}
@ -292,7 +295,7 @@ bool F7ZFile::Open()
}
// Resize the lump record array to its actual size
NumLumps -= skipped;
Printf(", %d lumps\n", NumLumps);
if (!quiet) Printf(", %d lumps\n", NumLumps);
// Entries in archives are sorted alphabetically
qsort(&Lumps[0], NumLumps, sizeof(F7ZLump), lumpcmp);
@ -330,7 +333,7 @@ int F7ZLump::FillCache()
//
//==========================================================================
FResourceFile *Check7Z(const char *filename, FileReader *file)
FResourceFile *Check7Z(const char *filename, FileReader *file, bool quiet)
{
char head[k7zSignatureSize];
@ -342,7 +345,7 @@ FResourceFile *Check7Z(const char *filename, FileReader *file)
if (!memcmp(head, k7zSignature, k7zSignatureSize))
{
FResourceFile *rf = new F7ZFile(filename, file);
if (rf->Open()) return rf;
if (rf->Open(quiet)) return rf;
delete rf;
}
}

View file

@ -74,7 +74,7 @@ class FGrpFile : public FUncompressedFile
{
public:
FGrpFile(const char * filename, FileReader *file);
bool Open();
bool Open(bool quiet);
};
@ -96,7 +96,7 @@ FGrpFile::FGrpFile(const char *filename, FileReader *file)
//
//==========================================================================
bool FGrpFile::Open()
bool FGrpFile::Open(bool quiet)
{
GrpInfo header;
@ -121,7 +121,7 @@ bool FGrpFile::Open()
fileinfo[i].NameWithZero[12] = '\0'; // Be sure filename is null-terminated
Lumps[i].LumpNameSetup(fileinfo[i].NameWithZero);
}
Printf(", %d lumps\n", NumLumps);
if (!quiet) Printf(", %d lumps\n", NumLumps);
delete[] fileinfo;
return true;
@ -134,7 +134,7 @@ bool FGrpFile::Open()
//
//==========================================================================
FResourceFile *CheckGRP(const char *filename, FileReader *file)
FResourceFile *CheckGRP(const char *filename, FileReader *file, bool quiet)
{
char head[12];
@ -146,7 +146,7 @@ FResourceFile *CheckGRP(const char *filename, FileReader *file)
if (!memcmp(head, "KenSilverman", 12))
{
FResourceFile *rf = new FGrpFile(filename, file);
if (rf->Open()) return rf;
if (rf->Open(quiet)) return rf;
delete rf;
}
}

View file

@ -47,7 +47,7 @@ class FLumpFile : public FUncompressedFile
{
public:
FLumpFile(const char * filename, FileReader *file);
bool Open();
bool Open(bool quiet);
};
@ -67,7 +67,7 @@ FLumpFile::FLumpFile(const char *filename, FileReader *file) : FUncompressedFile
//
//==========================================================================
bool FLumpFile::Open()
bool FLumpFile::Open(bool)
{
FString name(ExtractFileBase (Filename));
@ -90,11 +90,11 @@ bool FLumpFile::Open()
//
//==========================================================================
FResourceFile *CheckLump(const char *filename, FileReader *file)
FResourceFile *CheckLump(const char *filename, FileReader *file, bool quiet)
{
// always succeeds
FResourceFile *rf = new FLumpFile(filename, file);
if (rf->Open()) return rf;
if (rf->Open(quiet)) return rf;
delete rf;
return NULL;
}

View file

@ -67,7 +67,7 @@ class FPakFile : public FUncompressedFile
{
public:
FPakFile(const char * filename, FileReader *file);
bool Open();
bool Open(bool quiet);
};
@ -90,7 +90,7 @@ FPakFile::FPakFile(const char *filename, FileReader *file) : FUncompressedFile(f
//
//==========================================================================
bool FPakFile::Open()
bool FPakFile::Open(bool quiet)
{
dpackheader_t header;
@ -104,7 +104,7 @@ bool FPakFile::Open()
Lumps = new FUncompressedLump[NumLumps];
Printf(", %d lumps\n", NumLumps);
if (!quiet) Printf(", %d lumps\n", NumLumps);
for(DWORD i = 0; i < NumLumps; i++)
{
@ -126,7 +126,7 @@ bool FPakFile::Open()
//
//==========================================================================
FResourceFile *CheckPak(const char *filename, FileReader *file)
FResourceFile *CheckPak(const char *filename, FileReader *file, bool quiet)
{
char head[4];
@ -138,7 +138,7 @@ FResourceFile *CheckPak(const char *filename, FileReader *file)
if (!memcmp(head, "PACK", 4))
{
FResourceFile *rf = new FPakFile(filename, file);
if (rf->Open()) return rf;
if (rf->Open(quiet)) return rf;
delete rf;
}
}

View file

@ -107,7 +107,7 @@ class FRFFFile : public FResourceFile
public:
FRFFFile(const char * filename, FileReader *file);
virtual ~FRFFFile();
virtual bool Open();
virtual bool Open(bool quiet);
virtual FResourceLump *GetLump(int no) { return ((unsigned)no < NumLumps)? &Lumps[no] : NULL; }
};
@ -130,7 +130,7 @@ FRFFFile::FRFFFile(const char *filename, FileReader *file)
//
//==========================================================================
bool FRFFFile::Open()
bool FRFFFile::Open(bool quiet)
{
RFFLump *lumps;
RFFInfo header;
@ -146,7 +146,7 @@ bool FRFFFile::Open()
Lumps = new FRFFLump[NumLumps];
Printf(", %d lumps\n", NumLumps);
if (!quiet) Printf(", %d lumps\n", NumLumps);
for (DWORD i = 0; i < NumLumps; ++i)
{
if (lumps[i].Extension[0] == 'S' && lumps[i].Extension[1] == 'F' &&
@ -231,7 +231,7 @@ int FRFFLump::FillCache()
//
//==========================================================================
FResourceFile *CheckRFF(const char *filename, FileReader *file)
FResourceFile *CheckRFF(const char *filename, FileReader *file, bool quiet)
{
char head[4];
@ -243,7 +243,7 @@ FResourceFile *CheckRFF(const char *filename, FileReader *file)
if (!memcmp(head, "RFF\x1a", 4))
{
FResourceFile *rf = new FRFFFile(filename, file);
if (rf->Open()) return rf;
if (rf->Open(quiet)) return rf;
delete rf;
}
}

View file

@ -53,7 +53,7 @@ class FWadFile : public FUncompressedFile
public:
FWadFile(const char * filename, FileReader *file);
void FindStrifeTeaserVoices ();
bool Open();
bool Open(bool quiet);
};
@ -76,7 +76,7 @@ FWadFile::FWadFile(const char *filename, FileReader *file) : FUncompressedFile(f
//
//==========================================================================
bool FWadFile::Open()
bool FWadFile::Open(bool quiet)
{
wadinfo_t header;
@ -90,7 +90,7 @@ bool FWadFile::Open()
Lumps = new FUncompressedLump[NumLumps];
Printf(", %d lumps\n", NumLumps);
if (!quiet) Printf(", %d lumps\n", NumLumps);
for(DWORD i = 0; i < NumLumps; i++)
{
@ -104,14 +104,17 @@ bool FWadFile::Open()
Lumps[i].FullName = NULL;
}
SetNamespace("S_START", "S_END", ns_sprites);
SetNamespace("F_START", "F_END", ns_flats, true);
SetNamespace("C_START", "C_END", ns_colormaps);
SetNamespace("A_START", "A_END", ns_acslibrary);
SetNamespace("TX_START", "TX_END", ns_newtextures);
SetNamespace("V_START", "V_END", ns_strifevoices);
SetNamespace("HI_START", "HI_END", ns_hires);
SkinHack();
if (!quiet) // don't bother with namespaces here. We won't need them.
{
SetNamespace("S_START", "S_END", ns_sprites);
SetNamespace("F_START", "F_END", ns_flats, true);
SetNamespace("C_START", "C_END", ns_colormaps);
SetNamespace("A_START", "A_END", ns_acslibrary);
SetNamespace("TX_START", "TX_END", ns_newtextures);
SetNamespace("V_START", "V_END", ns_strifevoices);
SetNamespace("HI_START", "HI_END", ns_hires);
SkinHack();
}
delete [] fileinfo;
return true;
}
@ -358,7 +361,7 @@ void FWadFile::FindStrifeTeaserVoices ()
//
//==========================================================================
FResourceFile *CheckWad(const char *filename, FileReader *file)
FResourceFile *CheckWad(const char *filename, FileReader *file, bool quiet)
{
char head[4];
@ -370,7 +373,7 @@ FResourceFile *CheckWad(const char *filename, FileReader *file)
if (!memcmp(head, "IWAD", 4) || !memcmp(head, "PWAD", 4))
{
FResourceFile *rf = new FWadFile(filename, file);
if (rf->Open()) return rf;
if (rf->Open(quiet)) return rf;
delete rf;
}
}

View file

@ -143,7 +143,7 @@ class FZipFile : public FResourceFile
public:
FZipFile(const char * filename, FileReader *file);
virtual ~FZipFile();
bool Open();
bool Open(bool quiet);
virtual FResourceLump *GetLump(int no) { return ((unsigned)no < NumLumps)? &Lumps[no] : NULL; }
};
@ -170,7 +170,7 @@ FZipFile::FZipFile(const char * filename, FileReader *file)
Lumps = NULL;
}
bool FZipFile::Open()
bool FZipFile::Open(bool quiet)
{
DWORD centraldir = Zip_FindCentralDir(Reader);
FZipEndOfCentralDirectory info;
@ -180,7 +180,7 @@ bool FZipFile::Open()
if (centraldir == 0)
{
Printf("\n%s: ZIP file corrupt!\n", Filename);
if (!quiet) Printf("\n%s: ZIP file corrupt!\n", Filename);
return false;
}
@ -192,7 +192,7 @@ bool FZipFile::Open()
if (info.NumEntries != info.NumEntriesOnAllDisks ||
info.FirstDisk != 0 || info.DiskNumber != 0)
{
Printf("\n%s: Multipart Zip files are not supported.\n", Filename);
if (!quiet) Printf("\n%s: Multipart Zip files are not supported.\n", Filename);
return false;
}
@ -236,7 +236,7 @@ bool FZipFile::Open()
zip_fh->Method != METHOD_IMPLODE &&
zip_fh->Method != METHOD_SHRINK)
{
Printf("\n%s: '%s' uses an unsupported compression algorithm (#%d).\n", Filename, name, zip_fh->Method);
if (!quiet) Printf("\n%s: '%s' uses an unsupported compression algorithm (#%d).\n", Filename, name, zip_fh->Method);
skipped++;
continue;
}
@ -244,7 +244,7 @@ bool FZipFile::Open()
zip_fh->Flags = LittleShort(zip_fh->Flags);
if (zip_fh->Flags & ZF_ENCRYPTED)
{
Printf("\n%s: '%s' is encrypted. Encryption is not supported.\n", Filename, name);
if (!quiet) Printf("\n%s: '%s' is encrypted. Encryption is not supported.\n", Filename, name);
skipped++;
continue;
}
@ -268,7 +268,7 @@ bool FZipFile::Open()
NumLumps -= skipped;
free(directory);
//LumpInfo.Resize(NumLumps);
Printf(", %d lumps\n", NumLumps);
if (!quiet) Printf(", %d lumps\n", NumLumps);
// Entries in Zips are sorted alphabetically.
qsort(Lumps, NumLumps, sizeof(FZipLump), lumpcmp);
@ -406,7 +406,7 @@ int FZipLump::FillCache()
//
//==========================================================================
FResourceFile *CheckZip(const char *filename, FileReader *file)
FResourceFile *CheckZip(const char *filename, FileReader *file, bool quiet)
{
char head[4];
@ -418,7 +418,7 @@ FResourceFile *CheckZip(const char *filename, FileReader *file)
if (!memcmp(head, "PK\x3\x4", 4))
{
FResourceFile *rf = new FZipFile(filename, file);
if (rf->Open()) return rf;
if (rf->Open(quiet)) return rf;
delete rf;
}
}

View file

@ -37,6 +37,7 @@
#include "resourcefile.h"
#include "cmdlib.h"
#include "w_wad.h"
#include "doomerrors.h"
@ -242,7 +243,44 @@ int FResourceLump::ReleaseCache()
return RefCount;
}
//==========================================================================
//
// Opens a resource file
//
//==========================================================================
typedef FResourceFile * (*CheckFunc)(const char *filename, FileReader *file, bool quiet);
FResourceFile *CheckWad(const char *filename, FileReader *file, bool quiet);
FResourceFile *CheckGRP(const char *filename, FileReader *file, bool quiet);
FResourceFile *CheckRFF(const char *filename, FileReader *file, bool quiet);
FResourceFile *CheckPak(const char *filename, FileReader *file, bool quiet);
FResourceFile *CheckZip(const char *filename, FileReader *file, bool quiet);
FResourceFile *Check7Z(const char *filename, FileReader *file, bool quiet);
FResourceFile *CheckLump(const char *filename, FileReader *file, bool quiet);
static CheckFunc funcs[] = { CheckWad, CheckZip, Check7Z, CheckPak, CheckGRP, CheckRFF, CheckLump };
FResourceFile *FResourceFile::OpenResourceFile(const char *filename, FileReader *file, bool quiet)
{
if (file == NULL)
{
try
{
file = new FileReader(filename);
}
catch (CRecoverableError &)
{
return NULL;
}
}
for(size_t i = 0; i < countof(funcs); i++)
{
FResourceFile *resfile = funcs[i](filename, file, quiet);
if (resfile != NULL) return resfile;
}
return NULL;
}
//==========================================================================
//

View file

@ -60,6 +60,7 @@ private:
DWORD FirstLump;
public:
static FResourceFile *OpenResourceFile(const char *filename, FileReader *file, bool quiet = false);
virtual ~FResourceFile();
FileReader *GetReader() const { return Reader; }
DWORD LumpCount() const { return NumLumps; }
@ -67,7 +68,7 @@ public:
void SetFirstLump(DWORD f) { FirstLump = f; }
virtual void FindStrifeTeaserVoices ();
virtual bool Open() = 0;
virtual bool Open(bool quiet) = 0;
virtual FResourceLump *GetLump(int no) = 0;
};

View file

@ -228,18 +228,6 @@ int FWadCollection::AddExternalFile(const char *filename)
//
// [RH] Removed reload hack
//==========================================================================
typedef FResourceFile * (*CheckFunc)(const char *filename, FileReader *file);
FResourceFile *CheckWad(const char *filename, FileReader *file);
FResourceFile *CheckGRP(const char *filename, FileReader *file);
FResourceFile *CheckRFF(const char *filename, FileReader *file);
FResourceFile *CheckPak(const char *filename, FileReader *file);
FResourceFile *CheckZip(const char *filename, FileReader *file);
FResourceFile *Check7Z(const char *filename, FileReader *file);
FResourceFile *CheckLump(const char *filename, FileReader *file);
static CheckFunc funcs[] = { CheckWad, CheckZip, Check7Z, CheckPak, CheckGRP, CheckRFF, CheckLump };
void FWadCollection::AddFile (const char *filename, FileReader *wadinfo)
{
@ -262,48 +250,45 @@ void FWadCollection::AddFile (const char *filename, FileReader *wadinfo)
Printf (" adding %s", filename);
startlump = NumLumps;
for(size_t i = 0; i < countof(funcs); i++)
FResourceFile *resfile = FResourceFile::OpenResourceFile(filename, wadinfo);
if (resfile != NULL)
{
FResourceFile * resfile = funcs[i](filename, wadinfo);
if (resfile != NULL)
DWORD lumpstart = LumpInfo.Size();
resfile->SetFirstLump(lumpstart);
for (DWORD i=0; i < resfile->LumpCount(); i++)
{
DWORD lumpstart = LumpInfo.Size();
FResourceLump *lump = resfile->GetLump(i);
FWadCollection::LumpRecord *lump_p = &LumpInfo[LumpInfo.Reserve(1)];
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(wadstr, embedded);
}
}
return;
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(wadstr, embedded);
}
}
return;
}
}