From 5ac88ebce274e1e7b247fde512d23d9c49ba5d6d Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 11 Apr 2020 13:37:39 +0200 Subject: [PATCH] - added some Raze-specific file system utilities so that both can work with the same code. --- src/common/filesystem/filesystem.cpp | 147 ++++++++++++++++++++++++++- src/common/filesystem/filesystem.h | 49 +++++++-- src/common/filesystem/resourcefile.h | 2 +- src/utility/printf.h | 50 ++++----- 4 files changed, 213 insertions(+), 35 deletions(-) diff --git a/src/common/filesystem/filesystem.cpp b/src/common/filesystem/filesystem.cpp index c7620e28d..2bced8429 100644 --- a/src/common/filesystem/filesystem.cpp +++ b/src/common/filesystem/filesystem.cpp @@ -679,7 +679,7 @@ int FileSystem::FindResource (int resid, const char *type, int filenum) const no { uint32_t i; - if (type == NULL) + if (type == NULL || resid < 0) { return -1; } @@ -885,17 +885,24 @@ void FileSystem::InitHashChains (void) //========================================================================== // -// may only be called before the hash chains are set up. +// should only be called before the hash chains are set up. +// If done later this needs rehashing. // //========================================================================== LumpShortName& FileSystem::GetShortName(int i) { - if (Hashes.Size()) I_FatalError("Attempt to modify file system"); // This may ONLY be called in the RenameSprites callback. if ((unsigned)i >= NumEntries) I_Error("GetShortName: Invalid index"); return FileInfo[i].shortName; } +void FileSystem::RenameFile(int num, const char* newfn) +{ + if ((unsigned)num >= NumEntries) I_Error("RenameFile: Invalid index"); + FileInfo[num].longName = newfn; + // This does not alter the short name - call GetShortname to do that! +} + //========================================================================== // // MoveLumpsInFolder @@ -1007,6 +1014,58 @@ int FileSystem::FindLumpMulti (const char **names, int *lastlump, bool anyns, in return -1; } +//========================================================================== +// +// W_FindLump +// +// Find a named lump. Specifically allows duplicates for merging of e.g. +// SNDINFO lumps. +// +//========================================================================== + +int FileSystem::FindLumpFullName(const char* name, int* lastlump, bool noext) +{ + assert(lastlump != NULL && *lastlump >= 0); + auto lump_p = &FileInfo[*lastlump]; + + if (!noext) + { + while (lump_p < &FileInfo[NumEntries]) + { + if (!stricmp(name, lump_p->longName)) + { + int lump = int(lump_p - &FileInfo[0]); + *lastlump = lump + 1; + return lump; + } + lump_p++; + } + } + else + { + auto len = strlen(name); + while (lump_p < &FileInfo[NumEntries]) + { + auto res = strnicmp(name, lump_p->longName, len); + if (res == 0) + { + auto p = lump_p->longName.GetChars() + len; + if (*p == 0 || (*p == '.' && strpbrk(p + 1, "./") == 0)) + { + int lump = int(lump_p - &FileInfo[0]); + *lastlump = lump + 1; + return lump; + } + } + lump_p++; + } + } + + + *lastlump = NumEntries; + return -1; +} + //========================================================================== // // W_CheckLumpName @@ -1564,3 +1623,85 @@ static void PrintLastError () } #endif +//========================================================================== +// +// NBlood style lookup functions +// +//========================================================================== + +FResourceLump *FileSystem::Lookup(const char *name, const char *type) +{ + FStringf fname("%s.%s", name, type); + auto lump = FindFile(fname); + if (lump >= 0) return FileInfo[lump].lump; + else return nullptr; +} + +FResourceLump *FileSystem::Lookup(unsigned int id, const char *type) +{ + auto lump = FindResource(id, type); + if (lump >= 0) return FileInfo[lump].lump; + else return nullptr; +} +FResourceLump* FileSystem::GetFileAt(int no) +{ + return FileInfo[no].lump; +} + +//========================================================================== +// +// Stand-ins for Blood's resource class +// +//========================================================================== + +const void *FileSystem::Lock(int lump) +{ + if ((size_t)lump >= FileInfo.Size()) return nullptr; + auto lumpp = FileInfo[lump].lump; + return lumpp->Lock(); +} + +void FileSystem::Unlock(int lump) +{ + if ((size_t)lump >= FileInfo.Size()) return; + auto lumpp = FileInfo[lump].lump; + lumpp->Unlock(); +} + +const void *FileSystem::Get(int lump) +{ + if ((size_t)lump >= FileInfo.Size()) return nullptr; + auto lumpp = FileInfo[lump].lump; + auto p = lumpp->Lock(); + lumpp->RefCount = INT_MAX/2; // lock forever. + return p; +} + +//========================================================================== +// +// Stand-ins for Blood's resource class +// +//========================================================================== + +const void *FileSystem::Lock(FResourceLump *lump) +{ + if (lump) return lump->Lock(); + else return nullptr; +} + +void FileSystem::Unlock(FResourceLump *lump) +{ + if (lump) lump->Unlock(); +} + +const void *FileSystem::Load(FResourceLump *lump) +{ + if (lump) + { + auto p = lump->Lock(); + lump->RefCount = INT_MAX/2; // lock forever. + return p; + } + else return nullptr; +} + diff --git a/src/common/filesystem/filesystem.h b/src/common/filesystem/filesystem.h index be22ab028..f71aefb85 100644 --- a/src/common/filesystem/filesystem.h +++ b/src/common/filesystem/filesystem.h @@ -1,13 +1,12 @@ +#pragma once //----------------------------------------------------------------------------- // // DESCRIPTION: -// WAD I/O functions. +// File system I/O functions. // //----------------------------------------------------------------------------- -#ifndef __W_WAD__ -#define __W_WAD__ #include "files.h" #include "tarray.h" @@ -72,6 +71,7 @@ public: void InitMultipleFiles (TArray &filenames, bool quiet = false, LumpFilterInfo* filter = nullptr); void AddFile (const char *filename, FileReader *wadinfo, bool quiet, LumpFilterInfo* filter); int CheckIfResourceFileLoaded (const char *name) noexcept; + void AddAdditionalFile(const char* filename, FileReader* wadinfo = NULL) {} const char *GetResourceFileName (int filenum) const noexcept; const char *GetResourceFileFullName (int wadnum) const noexcept; @@ -100,7 +100,24 @@ public: { return CheckNumForFullName(name); } + + bool FileExists(const char* name) + { + return FindFile(name) >= 0; + } + + bool FileExists(const FString& name) + { + return FindFile(name) >= 0; + } + + bool FileExists(const std::string& name) + { + return FindFile(name.c_str()) >= 0; + } + LumpShortName& GetShortName(int i); // may only be called before the hash chains are set up. + void RenameFile(int num, const char* fn); bool CreatePathlessCopy(const char* name, int id, int flags); inline int CheckNumForFullName(const FString &name, bool trynormal = false, int namespc = ns_global) { return CheckNumForFullName(name.GetChars(), trynormal, namespc); } @@ -116,17 +133,25 @@ public: FileData ReadFile (int lump); FileData ReadFile (const char *name) { return ReadFile (GetNumForName (name)); } + inline TArray LoadFile(const char* name, int padding = 0) + { + auto lump = FindFile(name); + if (lump < 0) return TArray(); + return GetFileData(lump, padding); + } + FileReader OpenFileReader(int lump); // opens a reader that redirects to the containing file's one. FileReader ReopenFileReader(int lump, bool alwayscache = false); // opens an independent reader. FileReader OpenFileReader(const char* name); int FindLump (const char *name, int *lastlump, bool anyns=false); // [RH] Find lumps with duplication int FindLumpMulti (const char **names, int *lastlump, bool anyns = false, int *nameindex = NULL); // same with multiple possible names + int FindLumpFullName(const char* name, int* lastlump, bool noext = false); bool CheckFileName (int lump, const char *name); // [RH] True if lump's name == name int FindFileWithExtensions(const char* name, const char* const* exts, int count); - int FindResource(int resid, const char* type, int filenum) const noexcept; - int GetResource(int resid, const char* type, int filenum) const; + int FindResource(int resid, const char* type, int filenum = -1) const noexcept; + int GetResource(int resid, const char* type, int filenum = -1) const; static uint32_t LumpNameHash (const char *name); // [RH] Create hash key from an 8-char name @@ -163,6 +188,19 @@ public: FileReader* GetFileReader(int wadnum); // Gets a FileReader object to the entire WAD void InitHashChains(); + // Blood stuff + FResourceLump* Lookup(const char* name, const char* type); + FResourceLump* Lookup(unsigned int id, const char* type); + + FResourceLump* GetFileAt(int no); + + const void* Lock(int lump); + void Unlock(int lump); + const void* Get(int lump); + static const void* Lock(FResourceLump* lump); + static void Unlock(FResourceLump* lump); + static const void* Load(FResourceLump* lump);; + protected: struct LumpRecord; @@ -197,4 +235,3 @@ private: extern FileSystem fileSystem; -#endif diff --git a/src/common/filesystem/resourcefile.h b/src/common/filesystem/resourcefile.h index b76dd8dec..82ba8c7a5 100644 --- a/src/common/filesystem/resourcefile.h +++ b/src/common/filesystem/resourcefile.h @@ -107,7 +107,7 @@ public: virtual FileReader *GetReader(); virtual FileReader NewReader(); virtual int GetFileOffset() { return -1; } - virtual int GetIndexNum() const { return 0; } + virtual int GetIndexNum() const { return -1; } virtual int GetNamespace() const { return 0; } void LumpNameSetup(FString iname); void CheckEmbedded(); diff --git a/src/utility/printf.h b/src/utility/printf.h index abe5db8f3..900eb4f74 100644 --- a/src/utility/printf.h +++ b/src/utility/printf.h @@ -11,31 +11,6 @@ extern "C" int mysnprintf(char* buffer, size_t count, const char* format, ...) ATTRIBUTE((format(printf, 3, 4))); extern "C" int myvsnprintf(char* buffer, size_t count, const char* format, va_list argptr) ATTRIBUTE((format(printf, 3, 0))); -// game print flags -enum -{ - PRINT_LOW, // pickup messages - PRINT_MEDIUM, // death messages - PRINT_HIGH, // critical messages - PRINT_CHAT, // chat messages - PRINT_TEAMCHAT, // chat messages from a teammate - PRINT_LOG, // only to logfile - PRINT_BOLD = 200, // What Printf_Bold used - PRINT_TYPES = 1023, // Bitmask. - PRINT_NONOTIFY = 1024, // Flag - do not add to notify buffer - PRINT_NOLOG = 2048, // Flag - do not print to log file - PRINT_NOTIFY = 4096, // Flag - add to notify buffer -}; - -enum -{ - DMSG_OFF, // no developer messages. - DMSG_ERROR, // general notification messages - DMSG_WARNING, // warnings - DMSG_NOTIFY, // general notification messages - DMSG_SPAMMY, // for those who want to see everything, regardless of its usefulness. -}; - #define TEXTCOLOR_BRICK "\034A" #define TEXTCOLOR_TAN "\034B" #define TEXTCOLOR_GRAY "\034C" @@ -64,6 +39,31 @@ enum #define TEXTCOLOR_SAPPHIRE "\034Y" #define TEXTCOLOR_TEAL "\034Z" +// game print flags +enum +{ + PRINT_LOW, // pickup messages + PRINT_MEDIUM, // death messages + PRINT_HIGH, // critical messages + PRINT_CHAT, // chat messages + PRINT_TEAMCHAT, // chat messages from a teammate + PRINT_LOG, // only to logfile + PRINT_BOLD = 200, // What Printf_Bold used + PRINT_TYPES = 1023, // Bitmask. + PRINT_NONOTIFY = 1024, // Flag - do not add to notify buffer + PRINT_NOLOG = 2048, // Flag - do not print to log file + PRINT_NOTIFY = 4096, // Flag - add to notify buffer +}; + +enum +{ + DMSG_OFF, // no developer messages. + DMSG_ERROR, // general notification messages + DMSG_WARNING, // warnings + DMSG_NOTIFY, // general notification messages + DMSG_SPAMMY, // for those who want to see everything, regardless of its usefulness. +}; + void I_Error(const char *fmt, ...) ATTRIBUTE((format(printf,1,2))); void I_FatalError(const char* fmt, ...) ATTRIBUTE((format(printf, 1, 2)));