diff --git a/docs/rh-log.txt b/docs/rh-log.txt index fb1f23ac3..c6ac4845f 100644 --- a/docs/rh-log.txt +++ b/docs/rh-log.txt @@ -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! diff --git a/src/d_iwad.cpp b/src/d_iwad.cpp index 1f5529532..c3bce6034 100644 --- a/src/d_iwad.cpp +++ b/src/d_iwad.cpp @@ -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. diff --git a/src/resourcefiles/file_7z.cpp b/src/resourcefiles/file_7z.cpp index 46f55f844..290792140 100644 --- a/src/resourcefiles/file_7z.cpp +++ b/src/resourcefiles/file_7z.cpp @@ -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; } } diff --git a/src/resourcefiles/file_grp.cpp b/src/resourcefiles/file_grp.cpp index c9ce2dc1b..dc4c97812 100644 --- a/src/resourcefiles/file_grp.cpp +++ b/src/resourcefiles/file_grp.cpp @@ -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; } } diff --git a/src/resourcefiles/file_lump.cpp b/src/resourcefiles/file_lump.cpp index 09d665173..e70a5f609 100644 --- a/src/resourcefiles/file_lump.cpp +++ b/src/resourcefiles/file_lump.cpp @@ -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; } diff --git a/src/resourcefiles/file_pak.cpp b/src/resourcefiles/file_pak.cpp index 3554c1534..099e8046c 100644 --- a/src/resourcefiles/file_pak.cpp +++ b/src/resourcefiles/file_pak.cpp @@ -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; } } diff --git a/src/resourcefiles/file_rff.cpp b/src/resourcefiles/file_rff.cpp index fb5daf708..bb2616c2b 100644 --- a/src/resourcefiles/file_rff.cpp +++ b/src/resourcefiles/file_rff.cpp @@ -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; } } diff --git a/src/resourcefiles/file_wad.cpp b/src/resourcefiles/file_wad.cpp index bc9e3472c..6ee0e22cb 100644 --- a/src/resourcefiles/file_wad.cpp +++ b/src/resourcefiles/file_wad.cpp @@ -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; } } diff --git a/src/resourcefiles/file_zip.cpp b/src/resourcefiles/file_zip.cpp index 168c1fd22..3a90efe1e 100644 --- a/src/resourcefiles/file_zip.cpp +++ b/src/resourcefiles/file_zip.cpp @@ -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; } } diff --git a/src/resourcefiles/resourcefile.cpp b/src/resourcefiles/resourcefile.cpp index da3f54003..dcf6b9a29 100644 --- a/src/resourcefiles/resourcefile.cpp +++ b/src/resourcefiles/resourcefile.cpp @@ -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; +} //========================================================================== // diff --git a/src/resourcefiles/resourcefile.h b/src/resourcefiles/resourcefile.h index a74d53226..716083f54 100644 --- a/src/resourcefiles/resourcefile.h +++ b/src/resourcefiles/resourcefile.h @@ -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; }; diff --git a/src/w_wad.cpp b/src/w_wad.cpp index 1db4639cb..1ca14ffba 100644 --- a/src/w_wad.cpp +++ b/src/w_wad.cpp @@ -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; } }