From 7fee89d1f545cc4989185f5645560a5c8d1cd649 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 17 Aug 2023 21:28:35 +0200 Subject: [PATCH] - uncouple the file system from the engine's Printf function. This is needed to use it in non GZDoom based projects. --- src/common/audio/music/i_soundfont.cpp | 2 +- src/common/filesystem/file_7z.cpp | 43 ++++----- src/common/filesystem/file_directory.cpp | 19 ++-- src/common/filesystem/file_grp.cpp | 9 +- src/common/filesystem/file_lump.cpp | 13 +-- src/common/filesystem/file_pak.cpp | 9 +- src/common/filesystem/file_rff.cpp | 10 +-- src/common/filesystem/file_ssi.cpp | 9 +- src/common/filesystem/file_wad.cpp | 68 +++++++------- src/common/filesystem/file_whres.cpp | 9 +- src/common/filesystem/file_zip.cpp | 108 +++++++++++------------ src/common/filesystem/file_zip.h | 2 +- src/common/filesystem/filesystem.cpp | 69 ++++++--------- src/common/filesystem/filesystem.h | 8 +- src/common/filesystem/resourcefile.cpp | 46 ++++++---- src/common/filesystem/resourcefile.h | 23 ++++- src/common/utility/files_decompress.cpp | 1 - src/d_iwad.cpp | 8 +- src/d_main.cpp | 53 ++++++++++- src/g_game.cpp | 2 +- src/maploader/glnodes.cpp | 2 +- src/menu/loadsavemenu.cpp | 2 +- src/p_openmap.cpp | 2 +- 23 files changed, 272 insertions(+), 245 deletions(-) diff --git a/src/common/audio/music/i_soundfont.cpp b/src/common/audio/music/i_soundfont.cpp index af1c5634c8..dd487954c5 100644 --- a/src/common/audio/music/i_soundfont.cpp +++ b/src/common/audio/music/i_soundfont.cpp @@ -197,7 +197,7 @@ FileReader FSF2Reader::OpenFile(const char *name) FZipPatReader::FZipPatReader(const char *filename) { mAllowAbsolutePaths = true; - resf = FResourceFile::OpenResourceFile(filename, true); + resf = FResourceFile::OpenResourceFile(filename); } FZipPatReader::~FZipPatReader() diff --git a/src/common/filesystem/file_7z.cpp b/src/common/filesystem/file_7z.cpp index f207702d05..2bdd2e38f2 100644 --- a/src/common/filesystem/file_7z.cpp +++ b/src/common/filesystem/file_7z.cpp @@ -39,7 +39,6 @@ #include "resourcefile.h" #include "cmdlib.h" -#include "printf.h" @@ -189,7 +188,7 @@ class F7ZFile : public FResourceFile public: F7ZFile(const char * filename, FileReader &filer); - bool Open(bool quiet, LumpFilterInfo* filter); + bool Open(LumpFilterInfo* filter, FileSystemMessageFunc Printf); virtual ~F7ZFile(); virtual FResourceLump *GetLump(int no) { return ((unsigned)no < NumLumps)? &Lumps[no] : NULL; } }; @@ -216,7 +215,7 @@ F7ZFile::F7ZFile(const char * filename, FileReader &filer) // //========================================================================== -bool F7ZFile::Open(bool quiet, LumpFilterInfo *filter) +bool F7ZFile::Open(LumpFilterInfo *filter, FileSystemMessageFunc Printf) { Archive = new C7zArchive(Reader); int skipped = 0; @@ -227,25 +226,21 @@ bool F7ZFile::Open(bool quiet, LumpFilterInfo *filter) { delete Archive; Archive = NULL; - if (!quiet) + if (res == SZ_ERROR_UNSUPPORTED) { - Printf("\n" TEXTCOLOR_RED "%s: ", FileName.GetChars()); - 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); - } + Printf(FSMessageLevel::Error, "%s: Decoder does not support this archive\n", FileName.GetChars()); + } + else if (res == SZ_ERROR_MEM) + { + Printf(FSMessageLevel::Error, "Cannot allocate memory\n"); + } + else if (res == SZ_ERROR_CRC) + { + Printf(FSMessageLevel::Error, "CRC error\n"); + } + else + { + Printf(FSMessageLevel::Error, "error #%d\n", res); } return false; } @@ -308,7 +303,7 @@ bool F7ZFile::Open(bool quiet, LumpFilterInfo *filter) if (SZ_OK != Archive->Extract(Lumps[0].Position, &temp[0])) { - if (!quiet) Printf("\n%s: unsupported 7z/LZMA file!\n", FileName.GetChars()); + Printf(FSMessageLevel::Error, "%s: unsupported 7z/LZMA file!\n", FileName.GetChars()); return false; } } @@ -356,7 +351,7 @@ int F7ZLump::FillCache() // //========================================================================== -FResourceFile *Check7Z(const char *filename, FileReader &file, bool quiet, LumpFilterInfo* filter) +FResourceFile *Check7Z(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf) { char head[k7zSignatureSize]; @@ -368,7 +363,7 @@ FResourceFile *Check7Z(const char *filename, FileReader &file, bool quiet, LumpF if (!memcmp(head, k7zSignature, k7zSignatureSize)) { auto rf = new F7ZFile(filename, file); - if (rf->Open(quiet, filter)) return rf; + if (rf->Open(filter, Printf)) return rf; file = std::move(rf->Reader); // to avoid destruction of reader delete rf; diff --git a/src/common/filesystem/file_directory.cpp b/src/common/filesystem/file_directory.cpp index 80b9f6e578..f0ba89bfc7 100644 --- a/src/common/filesystem/file_directory.cpp +++ b/src/common/filesystem/file_directory.cpp @@ -38,7 +38,6 @@ #include "resourcefile.h" #include "cmdlib.h" -#include "printf.h" #include "findfile.h" //========================================================================== @@ -67,12 +66,12 @@ class FDirectory : public FResourceFile TArray Lumps; const bool nosubdir; - int AddDirectory(const char *dirpath); + int AddDirectory(const char* dirpath, FileSystemMessageFunc Printf); void AddEntry(const char *fullpath, int size); public: FDirectory(const char * dirname, bool nosubdirflag = false); - bool Open(bool quiet, LumpFilterInfo* filter); + bool Open(LumpFilterInfo* filter, FileSystemMessageFunc Printf); virtual FResourceLump *GetLump(int no) { return ((unsigned)no < NumLumps)? &Lumps[no] : NULL; } }; @@ -110,7 +109,7 @@ FDirectory::FDirectory(const char * directory, bool nosubdirflag) // //========================================================================== -int FDirectory::AddDirectory(const char *dirpath) +int FDirectory::AddDirectory(const char *dirpath, FileSystemMessageFunc Printf) { void * handle; int count = 0; @@ -122,7 +121,7 @@ int FDirectory::AddDirectory(const char *dirpath) handle = I_FindFirst(dirmatch.GetChars(), &find); if (handle == ((void *)(-1))) { - Printf("Could not scan '%s': %s\n", dirpath, strerror(errno)); + Printf(FSMessageLevel::Error, "Could not scan '%s': %s\n", dirpath, strerror(errno)); } else { @@ -148,7 +147,7 @@ int FDirectory::AddDirectory(const char *dirpath) } FString newdir = dirpath; newdir << fi << '/'; - count += AddDirectory(newdir); + count += AddDirectory(newdir, Printf); } else { @@ -193,9 +192,9 @@ int FDirectory::AddDirectory(const char *dirpath) // //========================================================================== -bool FDirectory::Open(bool quiet, LumpFilterInfo* filter) +bool FDirectory::Open(LumpFilterInfo* filter, FileSystemMessageFunc Printf) { - NumLumps = AddDirectory(FileName); + NumLumps = AddDirectory(FileName, Printf); PostProcessArchive(&Lumps[0], sizeof(FDirectoryLump), filter); return true; } @@ -265,10 +264,10 @@ int FDirectoryLump::FillCache() // //========================================================================== -FResourceFile *CheckDir(const char *filename, bool quiet, bool nosubdirflag, LumpFilterInfo* filter) +FResourceFile *CheckDir(const char *filename, bool nosubdirflag, LumpFilterInfo* filter, FileSystemMessageFunc Printf) { auto rf = new FDirectory(filename, nosubdirflag); - if (rf->Open(quiet, filter)) return rf; + if (rf->Open(filter, Printf)) return rf; delete rf; return nullptr; } diff --git a/src/common/filesystem/file_grp.cpp b/src/common/filesystem/file_grp.cpp index 7128c1307c..7ed9222632 100644 --- a/src/common/filesystem/file_grp.cpp +++ b/src/common/filesystem/file_grp.cpp @@ -34,7 +34,6 @@ */ #include "resourcefile.h" -#include "printf.h" //========================================================================== // @@ -72,7 +71,7 @@ class FGrpFile : public FUncompressedFile { public: FGrpFile(const char * filename, FileReader &file); - bool Open(bool quiet, LumpFilterInfo* filter); + bool Open(LumpFilterInfo* filter); }; @@ -93,7 +92,7 @@ FGrpFile::FGrpFile(const char *filename, FileReader &file) // //========================================================================== -bool FGrpFile::Open(bool quiet, LumpFilterInfo*) +bool FGrpFile::Open(LumpFilterInfo* filter) { GrpHeader header; @@ -129,7 +128,7 @@ bool FGrpFile::Open(bool quiet, LumpFilterInfo*) // //========================================================================== -FResourceFile *CheckGRP(const char *filename, FileReader &file, bool quiet, LumpFilterInfo* filter) +FResourceFile *CheckGRP(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf) { char head[12]; @@ -141,7 +140,7 @@ FResourceFile *CheckGRP(const char *filename, FileReader &file, bool quiet, Lump if (!memcmp(head, "KenSilverman", 12)) { auto rf = new FGrpFile(filename, file); - if (rf->Open(quiet, filter)) return rf; + if (rf->Open(filter)) return rf; file = std::move(rf->Reader); // to avoid destruction of reader delete rf; diff --git a/src/common/filesystem/file_lump.cpp b/src/common/filesystem/file_lump.cpp index abeb9cf71d..0101aecf40 100644 --- a/src/common/filesystem/file_lump.cpp +++ b/src/common/filesystem/file_lump.cpp @@ -34,7 +34,6 @@ #include "resourcefile.h" #include "cmdlib.h" -#include "printf.h" //========================================================================== // @@ -46,7 +45,7 @@ class FLumpFile : public FUncompressedFile { public: FLumpFile(const char * filename, FileReader &file); - bool Open(bool quiet, LumpFilterInfo* filter); + bool Open(LumpFilterInfo* filter); }; @@ -67,7 +66,7 @@ FLumpFile::FLumpFile(const char *filename, FileReader &file) // //========================================================================== -bool FLumpFile::Open(bool quiet, LumpFilterInfo*) +bool FLumpFile::Open(LumpFilterInfo*) { FString name(ExtractFileBase(FileName, true)); @@ -78,10 +77,6 @@ bool FLumpFile::Open(bool quiet, LumpFilterInfo*) Lumps[0].LumpSize = (int)Reader.GetLength(); Lumps[0].Flags = 0; NumLumps = 1; - if (!quiet) - { - Printf("\n"); - } return true; } @@ -91,11 +86,11 @@ bool FLumpFile::Open(bool quiet, LumpFilterInfo*) // //========================================================================== -FResourceFile *CheckLump(const char *filename, FileReader &file, bool quiet, LumpFilterInfo* filter) +FResourceFile *CheckLump(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf) { // always succeeds auto rf = new FLumpFile(filename, file); - if (rf->Open(quiet, filter)) return rf; + if (rf->Open(filter)) return rf; file = std::move(rf->Reader); // to avoid destruction of reader delete rf; return NULL; diff --git a/src/common/filesystem/file_pak.cpp b/src/common/filesystem/file_pak.cpp index 3a868766ce..f9e96eed69 100644 --- a/src/common/filesystem/file_pak.cpp +++ b/src/common/filesystem/file_pak.cpp @@ -33,7 +33,6 @@ */ #include "resourcefile.h" -#include "printf.h" //========================================================================== // @@ -65,7 +64,7 @@ class FPakFile : public FUncompressedFile { public: FPakFile(const char * filename, FileReader &file); - bool Open(bool quiet, LumpFilterInfo* filter); + bool Open(LumpFilterInfo* filter); }; @@ -88,7 +87,7 @@ FPakFile::FPakFile(const char *filename, FileReader &file) // //========================================================================== -bool FPakFile::Open(bool quiet, LumpFilterInfo* filter) +bool FPakFile::Open(LumpFilterInfo* filter) { dpackheader_t header; @@ -123,7 +122,7 @@ bool FPakFile::Open(bool quiet, LumpFilterInfo* filter) // //========================================================================== -FResourceFile *CheckPak(const char *filename, FileReader &file, bool quiet, LumpFilterInfo* filter) +FResourceFile *CheckPak(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf) { char head[4]; @@ -135,7 +134,7 @@ FResourceFile *CheckPak(const char *filename, FileReader &file, bool quiet, Lump if (!memcmp(head, "PACK", 4)) { auto rf = new FPakFile(filename, file); - if (rf->Open(quiet, filter)) return rf; + if (rf->Open(filter)) return rf; file = std::move(rf->Reader); // to avoid destruction of reader delete rf; diff --git a/src/common/filesystem/file_rff.cpp b/src/common/filesystem/file_rff.cpp index 3e512b62da..8d59749a5e 100644 --- a/src/common/filesystem/file_rff.cpp +++ b/src/common/filesystem/file_rff.cpp @@ -35,8 +35,6 @@ #include "resourcefile.h" -#include "printf.h" - //========================================================================== // // @@ -111,7 +109,7 @@ class FRFFFile : public FResourceFile public: FRFFFile(const char * filename, FileReader &file); virtual ~FRFFFile(); - virtual bool Open(bool quiet, LumpFilterInfo* filter); + virtual bool Open(LumpFilterInfo* filter); virtual FResourceLump *GetLump(int no) { return ((unsigned)no < NumLumps)? &Lumps[no] : NULL; } }; @@ -134,7 +132,7 @@ FRFFFile::FRFFFile(const char *filename, FileReader &file) // //========================================================================== -bool FRFFFile::Open(bool quiet, LumpFilterInfo*) +bool FRFFFile::Open(LumpFilterInfo*) { RFFLump *lumps; RFFInfo header; @@ -237,7 +235,7 @@ int FRFFLump::FillCache() // //========================================================================== -FResourceFile *CheckRFF(const char *filename, FileReader &file, bool quiet, LumpFilterInfo* filter) +FResourceFile *CheckRFF(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf) { char head[4]; @@ -249,7 +247,7 @@ FResourceFile *CheckRFF(const char *filename, FileReader &file, bool quiet, Lump if (!memcmp(head, "RFF\x1a", 4)) { auto rf = new FRFFFile(filename, file); - if (rf->Open(quiet, filter)) return rf; + if (rf->Open(filter)) return rf; file = std::move(rf->Reader); // to avoid destruction of reader delete rf; diff --git a/src/common/filesystem/file_ssi.cpp b/src/common/filesystem/file_ssi.cpp index 64623e805e..6bf60cc1e2 100644 --- a/src/common/filesystem/file_ssi.cpp +++ b/src/common/filesystem/file_ssi.cpp @@ -34,7 +34,6 @@ */ #include "resourcefile.h" -#include "printf.h" //========================================================================== // @@ -46,7 +45,7 @@ class FSSIFile : public FUncompressedFile { public: FSSIFile(const char * filename, FileReader &file); - bool Open(bool quiet, int version, int lumpcount, LumpFilterInfo* filter); + bool Open(int version, int lumpcount, LumpFilterInfo* filter); }; @@ -68,7 +67,7 @@ FSSIFile::FSSIFile(const char *filename, FileReader &file) // //========================================================================== -bool FSSIFile::Open(bool quiet, int version, int lumpcount, LumpFilterInfo*) +bool FSSIFile::Open(int version, int lumpcount, LumpFilterInfo*) { NumLumps = lumpcount*2; Lumps.Resize(lumpcount*2); @@ -115,7 +114,7 @@ bool FSSIFile::Open(bool quiet, int version, int lumpcount, LumpFilterInfo*) // //========================================================================== -FResourceFile* CheckSSI(const char* filename, FileReader& file, bool quiet, LumpFilterInfo* filter) +FResourceFile* CheckSSI(const char* filename, FileReader& file, LumpFilterInfo* filter, FileSystemMessageFunc Printf) { char zerobuf[72]; char buf[72]; @@ -146,7 +145,7 @@ FResourceFile* CheckSSI(const char* filename, FileReader& file, bool quiet, Lump if (!skipstring(70)) return nullptr; } auto ssi = new FSSIFile(filename, file); - if (ssi->Open(filename, version, numfiles, filter)) return ssi; + if (ssi->Open(version, numfiles, filter)) return ssi; file = std::move(ssi->Reader); // to avoid destruction of reader delete ssi; } diff --git a/src/common/filesystem/file_wad.cpp b/src/common/filesystem/file_wad.cpp index 8af39b5f82..45e2ec39cd 100644 --- a/src/common/filesystem/file_wad.cpp +++ b/src/common/filesystem/file_wad.cpp @@ -35,7 +35,6 @@ #include #include "resourcefile.h" -#include "v_text.h" #include "filesystem.h" #include "engineerrors.h" @@ -125,13 +124,13 @@ class FWadFile : public FResourceFile TArray Lumps; bool IsMarker(int lump, const char *marker); - void SetNamespace(const char *startmarker, const char *endmarker, namespace_t space, bool flathack=false); - void SkinHack (); + void SetNamespace(const char *startmarker, const char *endmarker, namespace_t space, FileSystemMessageFunc Printf, bool flathack=false); + void SkinHack (FileSystemMessageFunc Printf); public: FWadFile(const char * filename, FileReader &file); FResourceLump *GetLump(int lump) { return &Lumps[lump]; } - bool Open(bool quiet, LumpFilterInfo* filter); + bool Open(LumpFilterInfo* filter, FileSystemMessageFunc Printf); }; @@ -154,7 +153,7 @@ FWadFile::FWadFile(const char *filename, FileReader &file) // //========================================================================== -bool FWadFile::Open(bool quiet, LumpFilterInfo*) +bool FWadFile::Open(LumpFilterInfo*, FileSystemMessageFunc Printf) { wadinfo_t header; uint32_t InfoTableOfs; @@ -176,7 +175,8 @@ bool FWadFile::Open(bool quiet, LumpFilterInfo*) // Check again to detect broken wads if (InfoTableOfs + NumLumps*sizeof(wadlump_t) > (unsigned)wadSize) { - I_Error("Cannot load broken WAD file %s\n", FileName.GetChars()); + Printf(FSMessageLevel::Error, "%s: Bad directory offset.\n", FileName.GetChars()); + return false; } } @@ -212,7 +212,7 @@ bool FWadFile::Open(bool quiet, LumpFilterInfo*) { if (Lumps[i].LumpSize != 0) { - Printf(PRINT_HIGH, "%s: Lump %s contains invalid positioning info and will be ignored\n", FileName.GetChars(), Lumps[i].getName()); + Printf(FSMessageLevel::Warning, "%s: Lump %s contains invalid positioning info and will be ignored\n", FileName.GetChars(), Lumps[i].getName()); Lumps[i].LumpNameSetup(""); } Lumps[i].LumpSize = Lumps[i].Position = 0; @@ -221,18 +221,15 @@ bool FWadFile::Open(bool quiet, LumpFilterInfo*) GenerateHash(); // Do this before the lump processing below. - if (!quiet) // don't bother with namespaces in quiet mode. 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); - SetNamespace("VX_START", "VX_END", ns_voxels); - SkinHack(); - } + SetNamespace("S_START", "S_END", ns_sprites, Printf); + SetNamespace("F_START", "F_END", ns_flats, Printf, true); + SetNamespace("C_START", "C_END", ns_colormaps, Printf); + SetNamespace("A_START", "A_END", ns_acslibrary, Printf); + SetNamespace("TX_START", "TX_END", ns_newtextures, Printf); + SetNamespace("V_START", "V_END", ns_strifevoices, Printf); + SetNamespace("HI_START", "HI_END", ns_hires, Printf); + SetNamespace("VX_START", "VX_END", ns_voxels, Printf); + SkinHack(Printf); return true; } @@ -273,7 +270,7 @@ struct Marker unsigned int index; }; -void FWadFile::SetNamespace(const char *startmarker, const char *endmarker, namespace_t space, bool flathack) +void FWadFile::SetNamespace(const char *startmarker, const char *endmarker, namespace_t space, FileSystemMessageFunc Printf, bool flathack) { bool warned = false; int numstartmarkers = 0, numendmarkers = 0; @@ -300,7 +297,7 @@ void FWadFile::SetNamespace(const char *startmarker, const char *endmarker, name { if (numendmarkers == 0) return; // no markers found - Printf(TEXTCOLOR_YELLOW"WARNING: %s marker without corresponding %s found.\n", endmarker, startmarker); + Printf(FSMessageLevel::Warning, "%s: %s marker without corresponding %s found.\n", FileName.GetChars(), endmarker, startmarker); if (flathack) @@ -314,7 +311,7 @@ void FWadFile::SetNamespace(const char *startmarker, const char *endmarker, name { // We can't add this to the flats namespace but // it needs to be flagged for the texture manager. - DPrintf(DMSG_NOTIFY, "Marking %s as potential flat\n", Lumps[ii].getName()); + Printf(FSMessageLevel::DebugNotify, "%s: Marking %s as potential flat\n", FileName.GetChars(), Lumps[ii].getName()); Lumps[ii].Flags |= LUMPF_MAYBEFLAT; } } @@ -328,7 +325,7 @@ void FWadFile::SetNamespace(const char *startmarker, const char *endmarker, name int start, end; if (markers[i].markertype != 0) { - Printf(TEXTCOLOR_YELLOW"WARNING: %s marker without corresponding %s found.\n", endmarker, startmarker); + Printf(FSMessageLevel::Warning, "%s: %s marker without corresponding %s found.\n", FileName.GetChars(), endmarker, startmarker); i++; continue; } @@ -337,21 +334,21 @@ void FWadFile::SetNamespace(const char *startmarker, const char *endmarker, name // skip over subsequent x_START markers while (i < markers.Size() && markers[i].markertype == 0) { - Printf(TEXTCOLOR_YELLOW"WARNING: duplicate %s marker found.\n", startmarker); + Printf(FSMessageLevel::Warning, "%s: duplicate %s marker found.\n", FileName.GetChars(), startmarker); i++; continue; } // same for x_END markers while (i < markers.Size()-1 && (markers[i].markertype == 1 && markers[i+1].markertype == 1)) { - Printf(TEXTCOLOR_YELLOW"WARNING: duplicate %s marker found.\n", endmarker); + Printf(FSMessageLevel::Warning, "%s: duplicate %s marker found.\n", FileName.GetChars(), endmarker); i++; continue; } // We found a starting marker but no end marker. Ignore this block. if (i >= markers.Size()) { - Printf(TEXTCOLOR_YELLOW"WARNING: %s marker without corresponding %s found.\n", startmarker, endmarker); + Printf(FSMessageLevel::Warning, "%s: %s marker without corresponding %s found.\n", FileName.GetChars(), startmarker, endmarker); end = NumLumps; } else @@ -360,14 +357,14 @@ void FWadFile::SetNamespace(const char *startmarker, const char *endmarker, name } // we found a marked block - DPrintf(DMSG_NOTIFY, "Found %s block at (%d-%d)\n", startmarker, markers[start].index, end); + Printf(FSMessageLevel::DebugNotify, "%s: Found %s block at (%d-%d)\n", FileName.GetChars(), startmarker, markers[start].index, end); for(int j = markers[start].index + 1; j < end; j++) { if (Lumps[j].Namespace != ns_global) { if (!warned) { - Printf(TEXTCOLOR_YELLOW"WARNING: Overlapping namespaces found (lump %d)\n", j); + Printf(FSMessageLevel::Warning, "%s: Overlapping namespaces found (lump %d)\n", FileName.GetChars(), j); } warned = true; } @@ -377,7 +374,7 @@ void FWadFile::SetNamespace(const char *startmarker, const char *endmarker, name // ignore sprite lumps smaller than 8 bytes (the smallest possible) // in size -- this was used by some dmadds wads // as an 'empty' graphics resource - DPrintf(DMSG_WARNING, " Skipped empty sprite %s (lump %d)\n", Lumps[j].getName(), j); + Printf(FSMessageLevel::DebugWarn, "%s: Skipped empty sprite %s (lump %d)\n", FileName.GetChars(), Lumps[j].getName(), j); } else { @@ -401,7 +398,7 @@ void FWadFile::SetNamespace(const char *startmarker, const char *endmarker, name // //========================================================================== -void FWadFile::SkinHack () +void FWadFile::SkinHack (FileSystemMessageFunc Printf) { // this being static is not a problem. The only relevant thing is that each skin gets a different number. static int namespc = ns_firstskin; @@ -447,11 +444,8 @@ void FWadFile::SkinHack () } if (skinned && hasmap) { - Printf (TEXTCOLOR_BLUE - "The maps in %s will not be loaded because it has a skin.\n" - TEXTCOLOR_BLUE - "You should remove the skin from the wad to play these maps.\n", - FileName.GetChars()); + Printf(FSMessageLevel::Attention, "%s: The maps will not be loaded because it has a skin.\n", FileName.GetChars()); + Printf(FSMessageLevel::Attention, "You should remove the skin from the wad to play these maps.\n"); } } @@ -462,7 +456,7 @@ void FWadFile::SkinHack () // //========================================================================== -FResourceFile *CheckWad(const char *filename, FileReader &file, bool quiet, LumpFilterInfo* filter) +FResourceFile *CheckWad(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf) { char head[4]; @@ -474,7 +468,7 @@ FResourceFile *CheckWad(const char *filename, FileReader &file, bool quiet, Lump if (!memcmp(head, "IWAD", 4) || !memcmp(head, "PWAD", 4)) { auto rf = new FWadFile(filename, file); - if (rf->Open(quiet, filter)) return rf; + if (rf->Open(filter, Printf)) return rf; file = std::move(rf->Reader); // to avoid destruction of reader delete rf; diff --git a/src/common/filesystem/file_whres.cpp b/src/common/filesystem/file_whres.cpp index 969aaafabe..cc37ec26c2 100644 --- a/src/common/filesystem/file_whres.cpp +++ b/src/common/filesystem/file_whres.cpp @@ -35,7 +35,6 @@ */ #include "resourcefile.h" -#include "printf.h" #include "cmdlib.h" //========================================================================== @@ -68,7 +67,7 @@ class FWHResFile : public FUncompressedFile FString basename; public: FWHResFile(const char * filename, FileReader &file); - bool Open(bool quiet, LumpFilterInfo* filter); + bool Open(LumpFilterInfo* filter); }; @@ -92,7 +91,7 @@ FWHResFile::FWHResFile(const char *filename, FileReader &file) // //========================================================================== -bool FWHResFile::Open(bool quiet, LumpFilterInfo*) +bool FWHResFile::Open(LumpFilterInfo*) { int directory[1024]; @@ -129,7 +128,7 @@ bool FWHResFile::Open(bool quiet, LumpFilterInfo*) // //========================================================================== -FResourceFile *CheckWHRes(const char *filename, FileReader &file, bool quiet, LumpFilterInfo* filter) +FResourceFile *CheckWHRes(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf) { if (file.GetLength() >= 8192) // needs to be at least 8192 to contain one file and the directory. { @@ -149,7 +148,7 @@ FResourceFile *CheckWHRes(const char *filename, FileReader &file, bool quiet, Lu checkpos += (length+4095) / 4096; } auto rf = new FWHResFile(filename, file); - if (rf->Open(quiet, filter)) return rf; + if (rf->Open(filter)) return rf; file = std::move(rf->Reader); // to avoid destruction of reader delete rf; } diff --git a/src/common/filesystem/file_zip.cpp b/src/common/filesystem/file_zip.cpp index e14305b529..75ca09da1b 100644 --- a/src/common/filesystem/file_zip.cpp +++ b/src/common/filesystem/file_zip.cpp @@ -37,7 +37,6 @@ #include "file_zip.h" #include "cmdlib.h" -#include "printf.h" #include "w_zip.h" #include "ancientzip.h" @@ -52,50 +51,42 @@ static bool UncompressZipLump(char *Cache, FileReader &Reader, int Method, int LumpSize, int CompressedSize, int GPFlags) { - try + switch (Method) { - switch (Method) - { - case METHOD_STORED: - { - Reader.Read(Cache, LumpSize); - break; - } - - case METHOD_DEFLATE: - case METHOD_BZIP2: - case METHOD_LZMA: - { - FileReader frz; - if (frz.OpenDecompressor(Reader, LumpSize, Method, false, [](const char* err) { I_Error("%s", err); })) - { - frz.Read(Cache, LumpSize); - } - break; - } - - // Fixme: These should also use a stream - case METHOD_IMPLODE: - { - FZipExploder exploder; - exploder.Explode((unsigned char *)Cache, LumpSize, Reader, CompressedSize, GPFlags); - break; - } - - case METHOD_SHRINK: - { - ShrinkLoop((unsigned char *)Cache, LumpSize, Reader, CompressedSize); - break; - } - - default: - assert(0); - return false; - } + case METHOD_STORED: + { + Reader.Read(Cache, LumpSize); + break; } - catch (CRecoverableError &err) + + case METHOD_DEFLATE: + case METHOD_BZIP2: + case METHOD_LZMA: { - Printf("%s\n", err.GetMessage()); + FileReader frz; + if (frz.OpenDecompressor(Reader, LumpSize, Method, false, [](const char* err) { I_Error("%s", err); })) + { + frz.Read(Cache, LumpSize); + } + break; + } + + // Fixme: These should also use a stream + case METHOD_IMPLODE: + { + FZipExploder exploder; + exploder.Explode((unsigned char *)Cache, LumpSize, Reader, CompressedSize, GPFlags); + break; + } + + case METHOD_SHRINK: + { + ShrinkLoop((unsigned char *)Cache, LumpSize, Reader, CompressedSize); + break; + } + + default: + assert(0); return false; } return true; @@ -173,7 +164,7 @@ FZipFile::FZipFile(const char * filename, FileReader &file) Lumps = NULL; } -bool FZipFile::Open(bool quiet, LumpFilterInfo* filter) +bool FZipFile::Open(LumpFilterInfo* filter, FileSystemMessageFunc Printf) { bool zip64 = false; uint32_t centraldir = Zip_FindCentralDir(Reader, &zip64); @@ -183,7 +174,7 @@ bool FZipFile::Open(bool quiet, LumpFilterInfo* filter) if (centraldir == 0) { - if (!quiet) Printf(TEXTCOLOR_RED "\n%s: ZIP file corrupt!\n", FileName.GetChars()); + Printf(FSMessageLevel::Error, "%s: ZIP file corrupt!\n", FileName.GetChars()); return false; } @@ -199,7 +190,7 @@ bool FZipFile::Open(bool quiet, LumpFilterInfo* filter) if (info.NumEntries != info.NumEntriesOnAllDisks || info.FirstDisk != 0 || info.DiskNumber != 0) { - if (!quiet) Printf(TEXTCOLOR_RED "\n%s: Multipart Zip files are not supported.\n", FileName.GetChars()); + Printf(FSMessageLevel::Error, "%s: Multipart Zip files are not supported.\n", FileName.GetChars()); return false; } @@ -218,7 +209,7 @@ bool FZipFile::Open(bool quiet, LumpFilterInfo* filter) if (info.NumEntries != info.NumEntriesOnAllDisks || info.FirstDisk != 0 || info.DiskNumber != 0) { - if (!quiet) Printf(TEXTCOLOR_RED "\n%s: Multipart Zip files are not supported.\n", FileName.GetChars()); + Printf(FSMessageLevel::Error, "%s: Multipart Zip files are not supported.\n", FileName.GetChars()); return false; } @@ -257,7 +248,7 @@ bool FZipFile::Open(bool quiet, LumpFilterInfo* filter) if (dirptr > ((char*)directory) + dirsize) // This directory entry goes beyond the end of the file. { free(directory); - if (!quiet) Printf(TEXTCOLOR_RED "\n%s: Central directory corrupted.", FileName.GetChars()); + Printf(FSMessageLevel::Error, "%s: Central directory corrupted.", FileName.GetChars()); return false; } @@ -323,7 +314,7 @@ bool FZipFile::Open(bool quiet, LumpFilterInfo* filter) if (dirptr > ((char*)directory) + dirsize) // This directory entry goes beyond the end of the file. { free(directory); - if (!quiet) Printf(TEXTCOLOR_RED "\n%s: Central directory corrupted.", FileName.GetChars()); + Printf(FSMessageLevel::Error, "%s: Central directory corrupted.", FileName.GetChars()); return false; } @@ -350,7 +341,7 @@ bool FZipFile::Open(bool quiet, LumpFilterInfo* filter) zip_fh->Method != METHOD_IMPLODE && zip_fh->Method != METHOD_SHRINK) { - if (!quiet) Printf(TEXTCOLOR_YELLOW "\n%s: '%s' uses an unsupported compression algorithm (#%d).\n", FileName.GetChars(), name.GetChars(), zip_fh->Method); + Printf(FSMessageLevel::Error, "%s: '%s' uses an unsupported compression algorithm (#%d).\n", FileName.GetChars(), name.GetChars(), zip_fh->Method); skipped++; continue; } @@ -358,7 +349,7 @@ bool FZipFile::Open(bool quiet, LumpFilterInfo* filter) zip_fh->Flags = LittleShort(zip_fh->Flags); if (zip_fh->Flags & ZF_ENCRYPTED) { - if (!quiet) Printf(TEXTCOLOR_YELLOW "\n%s: '%s' is encrypted. Encryption is not supported.\n", FileName.GetChars(), name.GetChars()); + Printf(FSMessageLevel::Error, "%s: '%s' is encrypted. Encryption is not supported.\n", FileName.GetChars(), name.GetChars()); skipped++; continue; } @@ -385,7 +376,7 @@ bool FZipFile::Open(bool quiet, LumpFilterInfo* filter) if (zip_64->CompressedSize > 0x7fffffff || zip_64->UncompressedSize > 0x7fffffff) { // The file system is limited to 32 bit file sizes; - if (!quiet) Printf(TEXTCOLOR_YELLOW "\n%s: '%s' is too large.\n", FileName.GetChars(), name.GetChars()); + Printf(FSMessageLevel::Warning, "%s: '%s' is too large.\n", FileName.GetChars(), name.GetChars()); skipped++; continue; } @@ -508,7 +499,16 @@ int FZipLump::FillCache() Owner->Reader.Seek(Position, FileReader::SeekSet); Cache = new char[LumpSize]; - UncompressZipLump(Cache, Owner->Reader, Method, LumpSize, CompressedSize, GPFlags); + try + { + UncompressZipLump(Cache, Owner->Reader, Method, LumpSize, CompressedSize, GPFlags); + } + catch (const CRecoverableError& ) + { + // this cannot propagate the exception but also has no means to handle the error message. Damn... + // At least don't return uninitialized memory here. + memset(Cache, 0, LumpSize); + } RefCount = 1; return 1; } @@ -532,7 +532,7 @@ int FZipLump::GetFileOffset() // //========================================================================== -FResourceFile *CheckZip(const char *filename, FileReader &file, bool quiet, LumpFilterInfo* filter) +FResourceFile *CheckZip(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf) { char head[4]; @@ -544,7 +544,7 @@ FResourceFile *CheckZip(const char *filename, FileReader &file, bool quiet, Lump if (!memcmp(head, "PK\x3\x4", 4)) { auto rf = new FZipFile(filename, file); - if (rf->Open(quiet, filter)) return rf; + if (rf->Open(filter, Printf)) return rf; file = std::move(rf->Reader); // to avoid destruction of reader delete rf; diff --git a/src/common/filesystem/file_zip.h b/src/common/filesystem/file_zip.h index c6a42d9a45..fc1d9acab3 100644 --- a/src/common/filesystem/file_zip.h +++ b/src/common/filesystem/file_zip.h @@ -41,7 +41,7 @@ class FZipFile : public FResourceFile public: FZipFile(const char * filename, FileReader &file); virtual ~FZipFile(); - bool Open(bool quiet, LumpFilterInfo* filter); + bool Open(LumpFilterInfo* filter, FileSystemMessageFunc Printf); virtual FResourceLump *GetLump(int no) { return ((unsigned)no < NumLumps)? &Lumps[no] : NULL; } }; diff --git a/src/common/filesystem/filesystem.cpp b/src/common/filesystem/filesystem.cpp index 6b60e8e68d..c4bcb64cda 100644 --- a/src/common/filesystem/filesystem.cpp +++ b/src/common/filesystem/filesystem.cpp @@ -152,7 +152,7 @@ struct FileSystem::LumpRecord // PRIVATE FUNCTION PROTOTYPES --------------------------------------------- -static void PrintLastError (); +static void PrintLastError (FileSystemMessageFunc Printf); // PUBLIC DATA DEFINITIONS ------------------------------------------------- @@ -162,7 +162,7 @@ FileSystem fileSystem; FileSystem::FileSystem() { - // This is needed to initialize the LumpRecord array, which depends on data only available here. + // Cannot be defaulted! This is needed to initialize the LumpRecord array, which depends on data only available here. } FileSystem::~FileSystem () @@ -199,14 +199,14 @@ void FileSystem::DeleteAll () // //========================================================================== -void FileSystem::InitSingleFile(const char* filename, bool quiet) +bool FileSystem::InitSingleFile(const char* filename, FileSystemMessageFunc Printf) { TArray filenames; filenames.Push(filename); - InitMultipleFiles(filenames, true); + return InitMultipleFiles(filenames, nullptr, Printf); } -void FileSystem::InitMultipleFiles (TArray &filenames, bool quiet, LumpFilterInfo* filter, bool allowduplicates, FILE* hashfile) +bool FileSystem::InitMultipleFiles (TArray &filenames, LumpFilterInfo* filter, FileSystemMessageFunc Printf, bool allowduplicates, FILE* hashfile) { int numfiles; @@ -232,7 +232,7 @@ void FileSystem::InitMultipleFiles (TArray &filenames, bool quiet, Lump for(unsigned i=0;iGetHash().GetChars()); @@ -242,13 +242,13 @@ void FileSystem::InitMultipleFiles (TArray &filenames, bool quiet, Lump NumEntries = FileInfo.Size(); if (NumEntries == 0) { - if (!quiet) I_FatalError("W_InitMultipleFiles: no files found"); - else return; + return false; } if (filter && filter->postprocessFunc) filter->postprocessFunc(); // [RH] Set up hash table InitHashChains (); + return true; } //========================================================================== @@ -308,7 +308,7 @@ int FileSystem::AddFromBuffer(const char* name, const char* type, char* data, in // [RH] Removed reload hack //========================================================================== -void FileSystem::AddFile (const char *filename, FileReader *filer, bool quiet, LumpFilterInfo* filter, FILE* hashfile) +void FileSystem::AddFile (const char *filename, FileReader *filer, LumpFilterInfo* filter, FileSystemMessageFunc Printf, FILE* hashfile) { int startlump; bool isdir = false; @@ -319,10 +319,10 @@ void FileSystem::AddFile (const char *filename, FileReader *filer, bool quiet, L // Does this exist? If so, is it a directory? if (!DirEntryExists(filename, &isdir)) { - if (!quiet) + if (Printf) { - Printf(TEXTCOLOR_RED "%s: File or Directory not found\n", filename); - PrintLastError(); + Printf(FSMessageLevel::Error, "%s: File or Directory not found\n", filename); + PrintLastError(Printf); } return; } @@ -331,10 +331,10 @@ void FileSystem::AddFile (const char *filename, FileReader *filer, bool quiet, L { if (!filereader.OpenFile(filename)) { // Didn't find file - if (!quiet) + if (Printf) { - Printf(TEXTCOLOR_RED "%s: File not found\n", filename); - PrintLastError(); + Printf(FSMessageLevel::Error, "%s: File not found\n", filename); + PrintLastError(Printf); } return; } @@ -342,19 +342,20 @@ void FileSystem::AddFile (const char *filename, FileReader *filer, bool quiet, L } else filereader = std::move(*filer); - if (!batchrun && !quiet) Printf (" adding %s", filename); startlump = NumEntries; FResourceFile *resfile; + if (!isdir) - resfile = FResourceFile::OpenResourceFile(filename, filereader, quiet, false, filter); + resfile = FResourceFile::OpenResourceFile(filename, filereader, false, filter, Printf); else - resfile = FResourceFile::OpenDirectory(filename, quiet, filter); + resfile = FResourceFile::OpenDirectory(filename, filter, Printf); if (resfile != NULL) { - if (!quiet && !batchrun) Printf(", %d lumps\n", resfile->LumpCount()); + if (!batchrun && Printf) + Printf(FSMessageLevel::Message, "adding %s, %d lumps\n", filename, resfile->LumpCount()); uint32_t lumpstart = FileInfo.Size(); @@ -376,11 +377,11 @@ void FileSystem::AddFile (const char *filename, FileReader *filer, bool quiet, L FString path; path.Format("%s:%s", filename, lump->getName()); auto embedded = lump->NewReader(); - AddFile(path, &embedded, quiet, filter, hashfile); + AddFile(path, &embedded, filter, Printf, hashfile); } } - if (hashfile && !quiet) + if (hashfile) { uint8_t cksum[16]; char cksumout[33]; @@ -1647,7 +1648,7 @@ __declspec(dllimport) void * __stdcall LocalFree (void *); __declspec(dllimport) unsigned long __stdcall GetLastError (); } -static void PrintLastError () +static void PrintLastError (FileSystemMessageFunc Printf) { char *lpMsgBuf; FormatMessageA(0x1300 /*FORMAT_MESSAGE_ALLOCATE_BUFFER | @@ -1660,14 +1661,14 @@ static void PrintLastError () 0, NULL ); - Printf (TEXTCOLOR_RED " %s\n", lpMsgBuf); + Printf (FSMessageLevel::Error, " %s\n", lpMsgBuf); // Free the buffer. LocalFree( lpMsgBuf ); } #else -static void PrintLastError () +static void PrintLastError (FileSystemMessageFunc Printf) { - Printf (TEXTCOLOR_RED " %s\n", strerror(errno)); + Printf(FSMessageLevel::Error, " %s\n", strerror(errno)); } #endif @@ -1681,21 +1682,3 @@ FResourceLump* FileSystem::GetFileAt(int no) { return FileInfo[no].lump; } - -#include "c_dispatch.h" - -CCMD(fs_dir) -{ - int numfiles = fileSystem.GetNumEntries(); - - for (int i = 0; i < numfiles; i++) - { - auto container = fileSystem.GetResourceFileFullName(fileSystem.GetFileContainer(i)); - auto fn1 = fileSystem.GetFileFullName(i); - auto fns = fileSystem.GetFileShortName(i); - auto fnid = fileSystem.GetResourceId(i); - auto length = fileSystem.FileLength(i); - bool hidden = fileSystem.FindFile(fn1) != i; - Printf(PRINT_HIGH | PRINT_NONOTIFY, "%s%-64s %-15s (%5d) %10d %s %s\n", hidden ? TEXTCOLOR_RED : TEXTCOLOR_UNTRANSLATED, fn1, fns, fnid, length, container, hidden ? "(h)" : ""); - } -} diff --git a/src/common/filesystem/filesystem.h b/src/common/filesystem/filesystem.h index 2dc80f7ffc..fb72d77de7 100644 --- a/src/common/filesystem/filesystem.h +++ b/src/common/filesystem/filesystem.h @@ -57,7 +57,7 @@ struct FolderEntry class FileSystem { public: - FileSystem (); + FileSystem(); ~FileSystem (); // The wadnum for the IWAD @@ -67,9 +67,9 @@ public: int GetMaxIwadNum() { return MaxIwadIndex; } void SetMaxIwadNum(int x) { MaxIwadIndex = x; } - void InitSingleFile(const char *filename, bool quiet = false); - void InitMultipleFiles (TArray &filenames, bool quiet = false, LumpFilterInfo* filter = nullptr, bool allowduplicates = false, FILE* hashfile = nullptr); - void AddFile (const char *filename, FileReader *wadinfo, bool quiet, LumpFilterInfo* filter, FILE* hashfile); + bool InitSingleFile(const char *filename, FileSystemMessageFunc Printf = nullptr); + bool InitMultipleFiles (TArray &filenames, LumpFilterInfo* filter = nullptr, FileSystemMessageFunc Printf = nullptr, bool allowduplicates = false, FILE* hashfile = nullptr); + void AddFile (const char *filename, FileReader *wadinfo, LumpFilterInfo* filter, FileSystemMessageFunc Printf, FILE* hashfile); int CheckIfResourceFileLoaded (const char *name) noexcept; void AddAdditionalFile(const char* filename, FileReader* wadinfo = NULL) {} diff --git a/src/common/filesystem/resourcefile.cpp b/src/common/filesystem/resourcefile.cpp index 3b8e39915d..f8ae9b09c8 100644 --- a/src/common/filesystem/resourcefile.cpp +++ b/src/common/filesystem/resourcefile.cpp @@ -223,46 +223,54 @@ int FResourceLump::Unlock() // //========================================================================== -typedef FResourceFile * (*CheckFunc)(const char *filename, FileReader &file, bool quiet, LumpFilterInfo* filter); +typedef FResourceFile * (*CheckFunc)(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf); -FResourceFile *CheckWad(const char *filename, FileReader &file, bool quiet, LumpFilterInfo* filter); -FResourceFile *CheckGRP(const char *filename, FileReader &file, bool quiet, LumpFilterInfo* filter); -FResourceFile *CheckRFF(const char *filename, FileReader &file, bool quiet, LumpFilterInfo* filter); -FResourceFile *CheckPak(const char *filename, FileReader &file, bool quiet, LumpFilterInfo* filter); -FResourceFile *CheckZip(const char *filename, FileReader &file, bool quiet, LumpFilterInfo* filter); -FResourceFile *Check7Z(const char *filename, FileReader &file, bool quiet, LumpFilterInfo* filter); -FResourceFile* CheckSSI(const char* filename, FileReader& file, bool quiet, LumpFilterInfo* filter); -FResourceFile *CheckLump(const char *filename,FileReader &file, bool quiet, LumpFilterInfo* filter); -FResourceFile *CheckDir(const char *filename, bool quiet, bool nosub, LumpFilterInfo* filter); +FResourceFile *CheckWad(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf); +FResourceFile *CheckGRP(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf); +FResourceFile *CheckRFF(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf); +FResourceFile *CheckPak(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf); +FResourceFile *CheckZip(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf); +FResourceFile *Check7Z(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf); +FResourceFile* CheckSSI(const char* filename, FileReader& file, LumpFilterInfo* filter, FileSystemMessageFunc Printf); +FResourceFile* CheckWHRes(const char* filename, FileReader& file, LumpFilterInfo* filter, FileSystemMessageFunc Printf); +FResourceFile *CheckLump(const char *filename,FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf); +FResourceFile *CheckDir(const char *filename, bool nosub, LumpFilterInfo* filter, FileSystemMessageFunc Printf); -static CheckFunc funcs[] = { CheckWad, CheckZip, Check7Z, CheckPak, CheckGRP, CheckRFF, CheckSSI, CheckLump }; +static CheckFunc funcs[] = { CheckWad, CheckZip, Check7Z, CheckPak, CheckGRP, CheckRFF, CheckSSI, CheckWHRes, CheckLump }; -FResourceFile *FResourceFile::DoOpenResourceFile(const char *filename, FileReader &file, bool quiet, bool containeronly, LumpFilterInfo* filter) +static int nulPrintf(FSMessageLevel msg, const char* fmt, ...) { + return 0; +} + +FResourceFile *FResourceFile::DoOpenResourceFile(const char *filename, FileReader &file, bool containeronly, LumpFilterInfo* filter, FileSystemMessageFunc Printf) +{ + if (Printf == nullptr) Printf = nulPrintf; for(size_t i = 0; i < countof(funcs) - containeronly; i++) { - FResourceFile *resfile = funcs[i](filename, file, quiet, filter); + FResourceFile *resfile = funcs[i](filename, file, filter, Printf); if (resfile != NULL) return resfile; } return NULL; } -FResourceFile *FResourceFile::OpenResourceFile(const char *filename, FileReader &file, bool quiet, bool containeronly, LumpFilterInfo* filter) +FResourceFile *FResourceFile::OpenResourceFile(const char *filename, FileReader &file, bool containeronly, LumpFilterInfo* filter, FileSystemMessageFunc Printf) { - return DoOpenResourceFile(filename, file, quiet, containeronly, filter); + return DoOpenResourceFile(filename, file, containeronly, filter, Printf); } -FResourceFile *FResourceFile::OpenResourceFile(const char *filename, bool quiet, bool containeronly, LumpFilterInfo* filter) +FResourceFile *FResourceFile::OpenResourceFile(const char *filename, bool containeronly, LumpFilterInfo* filter, FileSystemMessageFunc Printf) { FileReader file; if (!file.OpenFile(filename)) return nullptr; - return DoOpenResourceFile(filename, file, quiet, containeronly, filter); + return DoOpenResourceFile(filename, file, containeronly, filter, Printf); } -FResourceFile *FResourceFile::OpenDirectory(const char *filename, bool quiet, LumpFilterInfo* filter) +FResourceFile *FResourceFile::OpenDirectory(const char *filename, LumpFilterInfo* filter, FileSystemMessageFunc Printf) { - return CheckDir(filename, quiet, false, filter); + if (Printf == nullptr) Printf = nulPrintf; + return CheckDir(filename, false, filter, Printf); } //========================================================================== diff --git a/src/common/filesystem/resourcefile.h b/src/common/filesystem/resourcefile.h index d64c278e8e..65a6a4636e 100644 --- a/src/common/filesystem/resourcefile.h +++ b/src/common/filesystem/resourcefile.h @@ -8,6 +8,7 @@ #include "files.h" #include "zstring.h" +// user context in which the file system gets opened. This also contains a few callbacks to avoid direct dependencies on the engine. struct LumpFilterInfo { TArray gameTypeFilter; // this can contain multiple entries @@ -20,6 +21,20 @@ struct LumpFilterInfo std::function postprocessFunc; }; +enum class FSMessageLevel +{ + Error = 1, + Warning = 2, + Attention = 3, + Message = 4, + DebugWarn = 5, + DebugNotify = 6, +}; + +// pass the text output function as parameter to avoid a hard dependency on higher level code. +using FileSystemMessageFunc = int(*)(FSMessageLevel msglevel, const char* format, ...); + + class FResourceFile; // [RH] Namespaces from BOOM. @@ -151,12 +166,12 @@ private: int FilterLumpsByGameType(LumpFilterInfo *filter, void *lumps, size_t lumpsize, uint32_t max); bool FindPrefixRange(FString filter, void *lumps, size_t lumpsize, uint32_t max, uint32_t &start, uint32_t &end); void JunkLeftoverFilters(void *lumps, size_t lumpsize, uint32_t max); - static FResourceFile *DoOpenResourceFile(const char *filename, FileReader &file, bool quiet, bool containeronly, LumpFilterInfo* filter); + static FResourceFile *DoOpenResourceFile(const char *filename, FileReader &file, bool containeronly, LumpFilterInfo* filter, FileSystemMessageFunc Printf); public: - static FResourceFile *OpenResourceFile(const char *filename, FileReader &file, bool quiet = false, bool containeronly = false, LumpFilterInfo* filter = nullptr); - static FResourceFile *OpenResourceFile(const char *filename, bool quiet = false, bool containeronly = false, LumpFilterInfo* filter = nullptr); - static FResourceFile *OpenDirectory(const char *filename, bool quiet = false, LumpFilterInfo* filter = nullptr); + static FResourceFile *OpenResourceFile(const char *filename, FileReader &file, bool containeronly = false, LumpFilterInfo* filter = nullptr, FileSystemMessageFunc Printf = nullptr); + static FResourceFile *OpenResourceFile(const char *filename, bool containeronly = false, LumpFilterInfo* filter = nullptr, FileSystemMessageFunc Printf = nullptr); + static FResourceFile *OpenDirectory(const char *filename, LumpFilterInfo* filter = nullptr, FileSystemMessageFunc Printf = nullptr); virtual ~FResourceFile(); // If this FResourceFile represents a directory, the Reader object is not usable so don't return it. FileReader *GetReader() { return Reader.isOpen()? &Reader : nullptr; } diff --git a/src/common/utility/files_decompress.cpp b/src/common/utility/files_decompress.cpp index cd2e36ed7c..7954b51014 100644 --- a/src/common/utility/files_decompress.cpp +++ b/src/common/utility/files_decompress.cpp @@ -43,7 +43,6 @@ #include "files.h" -#include "zstring.h" #include "cmdlib.h" //========================================================================== diff --git a/src/d_iwad.cpp b/src/d_iwad.cpp index 4266b75a7a..27bcb7276e 100644 --- a/src/d_iwad.cpp +++ b/src/d_iwad.cpp @@ -308,8 +308,7 @@ FIWadManager::FIWadManager(const char *firstfn, const char *optfn) fns.Push(firstfn); if (optfn) fns.Push(optfn); - check.InitMultipleFiles(fns, true); - if (check.GetNumEntries() > 0) + if (check.InitMultipleFiles(fns, nullptr, nullptr)) { int num = check.CheckNumForName("IWADINFO"); if (num >= 0) @@ -331,7 +330,7 @@ FIWadManager::FIWadManager(const char *firstfn, const char *optfn) int FIWadManager::ScanIWAD (const char *iwad) { FileSystem check; - check.InitSingleFile(iwad, true); + check.InitSingleFile(iwad, nullptr); mLumpsFound.Resize(mIWadInfos.Size()); @@ -390,8 +389,7 @@ int FIWadManager::CheckIWADInfo(const char* fn) TArray filenames; filenames.Push(fn); - check.InitMultipleFiles(filenames, true, &lfi); - if (check.GetNumEntries() > 0) + if (check.InitMultipleFiles(filenames, &lfi, nullptr)) { int num = check.CheckNumForName("IWADINFO"); if (num >= 0) diff --git a/src/d_main.cpp b/src/d_main.cpp index 6e88286c85..7709c046c1 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -1924,8 +1924,7 @@ static FString CheckGameInfo(TArray & pwads) GetReserved(lfi); // Open the entire list as a temporary file system and look for a GAMEINFO lump. The last one will automatically win. - check.InitMultipleFiles(pwads, true, &lfi); - if (check.GetNumEntries() > 0) + if (check.InitMultipleFiles(pwads, &lfi, nullptr)) { int num = check.CheckNumForName("GAMEINFO"); if (num >= 0) @@ -3031,6 +3030,35 @@ static FILE* D_GetHashFile() return hashfile; } +static int FileSystemPrintf(FSMessageLevel level, const char* fmt, ...) +{ + va_list arg; + va_start(arg, fmt); + FString text; + text.VFormat(fmt, arg); + switch (level) + { + case FSMessageLevel::Error: + return Printf(TEXTCOLOR_RED "%s", text.GetChars()); + break; + case FSMessageLevel::Warning: + Printf(TEXTCOLOR_YELLOW "%s", text.GetChars()); + break; + case FSMessageLevel::Attention: + Printf(TEXTCOLOR_BLUE "%s", text.GetChars()); + break; + case FSMessageLevel::Message: + Printf("%s", text.GetChars()); + break; + case FSMessageLevel::DebugWarn: + DPrintf(DMSG_WARNING, "%s", text.GetChars()); + break; + case FSMessageLevel::DebugNotify: + DPrintf(DMSG_NOTIFY, "%s", text.GetChars()); + break; + } + return text.Len(); +} //========================================================================== // // D_InitGame @@ -3119,7 +3147,10 @@ static int D_InitGame(const FIWADInfo* iwad_info, TArray& allwads, TArr bool allowduplicates = Args->CheckParm("-allowduplicates"); auto hashfile = D_GetHashFile(); - fileSystem.InitMultipleFiles (allwads, false, &lfi, allowduplicates, hashfile); + if (!fileSystem.InitMultipleFiles(allwads, &lfi, FileSystemPrintf, allowduplicates, hashfile)) + { + I_FatalError("FileSystem: no files found"); + } allwads.Clear(); allwads.ShrinkToFit(); SetMapxxFlag(); @@ -3914,3 +3945,19 @@ void I_UpdateWindowTitle() I_UpdateDiscordPresence(false, nullptr, nullptr, nullptr); I_SetWindowTitle(copy.Data()); } + +CCMD(fs_dir) +{ + int numfiles = fileSystem.GetNumEntries(); + + for (int i = 0; i < numfiles; i++) + { + auto container = fileSystem.GetResourceFileFullName(fileSystem.GetFileContainer(i)); + auto fn1 = fileSystem.GetFileFullName(i); + auto fns = fileSystem.GetFileShortName(i); + auto fnid = fileSystem.GetResourceId(i); + auto length = fileSystem.FileLength(i); + bool hidden = fileSystem.FindFile(fn1) != i; + Printf(PRINT_HIGH | PRINT_NONOTIFY, "%s%-64s %-15s (%5d) %10d %s %s\n", hidden ? TEXTCOLOR_RED : TEXTCOLOR_UNTRANSLATED, fn1, fns, fnid, length, container, hidden ? "(h)" : ""); + } +} diff --git a/src/g_game.cpp b/src/g_game.cpp index 42feceee09..e4b47082ef 100644 --- a/src/g_game.cpp +++ b/src/g_game.cpp @@ -1975,7 +1975,7 @@ void G_DoLoadGame () hidecon = gameaction == ga_loadgamehidecon; gameaction = ga_nothing; - std::unique_ptr resfile(FResourceFile::OpenResourceFile(savename.GetChars(), true, true)); + std::unique_ptr resfile(FResourceFile::OpenResourceFile(savename.GetChars(), true)); if (resfile == nullptr) { LoadGameError("TXT_COULDNOTREAD"); diff --git a/src/maploader/glnodes.cpp b/src/maploader/glnodes.cpp index 21da9462a3..b7d773f03d 100644 --- a/src/maploader/glnodes.cpp +++ b/src/maploader/glnodes.cpp @@ -883,7 +883,7 @@ bool MapLoader::LoadGLNodes(MapData * map) strcpy(ext, ".gwa"); // Todo: Compare file dates - f_gwa = FResourceFile::OpenResourceFile(path, true); + f_gwa = FResourceFile::OpenResourceFile(path); if (f_gwa==nullptr) return false; strncpy(map->MapLumps[0].Name, fileSystem.GetFileFullName(map->lumpnum), 8); diff --git a/src/menu/loadsavemenu.cpp b/src/menu/loadsavemenu.cpp index 3eba261143..aaeb5ccbf0 100644 --- a/src/menu/loadsavemenu.cpp +++ b/src/menu/loadsavemenu.cpp @@ -77,7 +77,7 @@ void FSavegameManager::ReadSaveStrings() // I_FindName only returns the file's name and not its full path FString filepath = G_BuildSaveName(I_FindName(&c_file)); - std::unique_ptr savegame(FResourceFile::OpenResourceFile(filepath, true, true)); + std::unique_ptr savegame(FResourceFile::OpenResourceFile(filepath, true)); if (savegame != nullptr) { bool oldVer = false; diff --git a/src/p_openmap.cpp b/src/p_openmap.cpp index 771ae1d877..759c540221 100644 --- a/src/p_openmap.cpp +++ b/src/p_openmap.cpp @@ -125,7 +125,7 @@ MapData *P_OpenMapData(const char * mapname, bool justcheck) delete map; return NULL; } - map->resource = FResourceFile::OpenResourceFile(mapname, true); + map->resource = FResourceFile::OpenResourceFile(mapname); wadReader = map->resource->GetReader(); } else