diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt index ed5b6d3d6..0ff64c7e1 100644 --- a/source/CMakeLists.txt +++ b/source/CMakeLists.txt @@ -576,7 +576,8 @@ file( GLOB HEADER_FILES common/statusbar/*.h common/fonts/*.h common/objects/*.h - common/filesystem/*.h + common/filesystem/include/*.h + common/filesystem/source/*.h common/platform/posix/cocoa/*.h common/platform/posix/sdl/*.h common/platform/win32/*.h @@ -1232,18 +1233,7 @@ else() set( NOT_COMPILED_SOURCE_FILES ${NOT_COMPILED_SOURCE_FILES} ${VM_JIT_SOURCES} ) endif() -macro( use_precompiled_header ) - if( MSVC ) - enable_precompiled_headers( "${ARGV0}/g_pch.h" PCH_SOURCES ) - else() - # Temporary solution for compilers other than MSVC - set_source_files_properties( ${PCH_SOURCES} PROPERTIES COMPILE_FLAGS "-include g_pch.h" ) - endif() -endmacro() - -use_precompiled_header(".") - -add_executable( ${PROJECT_NAME} WIN32 MACOSX_BUNDLE +set( GAME_SOURCES ${HEADER_FILES} ${NOT_COMPILED_SOURCE_FILES} ${SYSTEM_SOURCES} @@ -1273,29 +1263,37 @@ add_executable( ${PROJECT_NAME} WIN32 MACOSX_BUNDLE common/thirdparty/math/tanh.c common/thirdparty/math/fastsin.cpp - common/filesystem/filesystem.cpp - common/filesystem/ancientzip.cpp - common/filesystem/file_7z.cpp - common/filesystem/file_grp.cpp - common/filesystem/file_lump.cpp - common/filesystem/file_rff.cpp - common/filesystem/file_wad.cpp - common/filesystem/file_zip.cpp - common/filesystem/file_pak.cpp - common/filesystem/file_whres.cpp - common/filesystem/file_ssi.cpp - common/filesystem/file_directory.cpp - common/filesystem/resourcefile.cpp - common/filesystem/files.cpp - common/filesystem/files_decompress.cpp - common/filesystem/fs_findfile.cpp + common/filesystem/source/filesystem.cpp + common/filesystem/source/ancientzip.cpp + common/filesystem/source/file_7z.cpp + common/filesystem/source/file_grp.cpp + common/filesystem/source/file_lump.cpp + common/filesystem/source/file_rff.cpp + common/filesystem/source/file_wad.cpp + common/filesystem/source/file_zip.cpp + common/filesystem/source/file_pak.cpp + common/filesystem/source/file_whres.cpp + common/filesystem/source/file_ssi.cpp + common/filesystem/source/file_directory.cpp + common/filesystem/source/resourcefile.cpp + common/filesystem/source/files.cpp + common/filesystem/source/files_decompress.cpp + common/filesystem/source/fs_findfile.cpp + common/filesystem/source/fs_stringpool.cpp ) +set( GAME_NONPCH_SOURCES ${GAME_SOURCES} ) +list( REMOVE_ITEM GAME_NONPCH_SOURCES ${PCH_SOURCES} ) + +add_executable( ${PROJECT_NAME} WIN32 MACOSX_BUNDLE ${GAME_SOURCES} ) + +target_precompile_headers( ${PROJECT_NAME} PRIVATE g_pch.h ) + #set_source_files_properties( ${FASTMATH_SOURCES} PROPERTIES COMPILE_FLAGS ${DEM_FASTMATH_FLAG} ) -set_source_files_properties( xlat/parse_xlat.cpp PROPERTIES OBJECT_DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/xlat_parser.c" ) set_source_files_properties( common/engine/sc_man.cpp PROPERTIES OBJECT_DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/sc_man_scanner.h" ) set_source_files_properties( ${NOT_COMPILED_SOURCE_FILES} PROPERTIES HEADER_FILE_ONLY TRUE ) +set_source_files_properties( ${GAME_NONPCH_SOURCES} common/textures/hires/hqresize.cpp PROPERTIES SKIP_PRECOMPILE_HEADERS TRUE ) if(${CMAKE_SYSTEM_NAME} STREQUAL "SunOS") @@ -1345,7 +1343,7 @@ include_directories( common/textures/hires common/textures common/models - common/filesystem + common/filesystem/include common/utility common/console common/engine @@ -1510,6 +1508,8 @@ source_group("Common\\Objects" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/ source_group("Common\\Menu" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/menu/.+") source_group("Common\\Fonts" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/fonts/.+") source_group("Common\\File System" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/filesystem/.+") +source_group("Common\\File System\\Include" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/filesystem/include/.+") +source_group("Common\\File System\\Source" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/filesystem/source/.+") source_group("Common\\Scripting" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/scripting/.+") source_group("Common\\Scripting\\Interface" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/scripting/interface/.+") source_group("Common\\Scripting\\Frontend" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/scripting/frontend/.+" FILES ${CMAKE_CURRENT_BINARY_DIR}/zcc-parse.c ${CMAKE_CURRENT_BINARY_DIR}/zcc-parse.h) diff --git a/source/common/audio/music/i_music.cpp b/source/common/audio/music/i_music.cpp index a0f793e17..2e0f83319 100644 --- a/source/common/audio/music/i_music.cpp +++ b/source/common/audio/music/i_music.cpp @@ -53,6 +53,7 @@ #include "s_music.h" #include "filereadermusicinterface.h" +using namespace FileSys; void I_InitSoundFonts(); @@ -182,7 +183,7 @@ static void SetupGenMidi() auto genmidi = fileSystem.ReadFile(lump); if (genmidi.GetSize() < 8 + 175 * 36 || memcmp(genmidi.GetMem(), "#OPL_II#", 8)) return; - ZMusic_SetGenMidi(genmidi.GetBytes()+8); + ZMusic_SetGenMidi(genmidi.GetBytes() + 8); } static void SetupWgOpn() @@ -192,7 +193,7 @@ static void SetupWgOpn() { return; } - FileData data = fileSystem.ReadFile(lump); + auto data = fileSystem.ReadFile(lump); ZMusic_SetWgOpn(data.GetMem(), (uint32_t)data.GetSize()); } @@ -204,7 +205,7 @@ static void SetupDMXGUS() { return; } - FileData data = fileSystem.ReadFile(lump); + auto data = fileSystem.ReadFile(lump); ZMusic_SetDmxGus(data.GetMem(), (uint32_t)data.GetSize()); } diff --git a/source/common/audio/music/i_soundfont.cpp b/source/common/audio/music/i_soundfont.cpp index da6424829..bac39d3a1 100644 --- a/source/common/audio/music/i_soundfont.cpp +++ b/source/common/audio/music/i_soundfont.cpp @@ -40,10 +40,9 @@ #include "i_system.h" #include "filereadermusicinterface.h" #include -#include "resourcefile.h" +#include "fs_filesystem.h" #include "version.h" #include "fs_findfile.h" -#include "resourcefile.h" #include "i_interface.h" #include "configfile.h" #include "printf.h" @@ -332,7 +331,7 @@ FileReader FLumpPatchSetReader::OpenFile(const char *name) // //========================================================================== -void FSoundFontManager::ProcessOneFile(const FString &fn) +void FSoundFontManager::ProcessOneFile(const char* fn) { auto fb = ExtractFileBase(fn, false); auto fbe = ExtractFileBase(fn, true); @@ -402,7 +401,7 @@ void FSoundFontManager::CollectSoundfonts() { if (stricmp (key, "Path") == 0) { - FileList list; + FileSys::FileList list; FString dir; @@ -410,7 +409,7 @@ void FSoundFontManager::CollectSoundfonts() FixPathSeperator(dir); if (dir.IsNotEmpty()) { - if (ScanDirectory(list, dir.GetChars(), "*", true)) + if (FileSys::ScanDirectory(list, dir.GetChars(), "*", true)) { for(auto& entry : list) { diff --git a/source/common/audio/music/i_soundfont.h b/source/common/audio/music/i_soundfont.h index ef0295071..45e5b0ffa 100644 --- a/source/common/audio/music/i_soundfont.h +++ b/source/common/audio/music/i_soundfont.h @@ -148,7 +148,7 @@ class FSoundFontManager { TArray soundfonts; - void ProcessOneFile(const FString & fn); + void ProcessOneFile(const char* fn); public: void CollectSoundfonts(); diff --git a/source/common/audio/music/music.cpp b/source/common/audio/music/music.cpp index d9b99fc2b..adffe332f 100644 --- a/source/common/audio/music/music.cpp +++ b/source/common/audio/music/music.cpp @@ -55,6 +55,7 @@ #include "i_specialpaths.h" #include "configfile.h" #include "c_cvars.h" +#include "md5.h" // EXTERNAL FUNCTION PROTOTYPES -------------------------------------------- diff --git a/source/common/audio/music/s_music.h b/source/common/audio/music/s_music.h index 1970a57da..6ae4017c9 100644 --- a/source/common/audio/music/s_music.h +++ b/source/common/audio/music/s_music.h @@ -5,9 +5,9 @@ #include "zstring.h" #include "tarray.h" #include "name.h" +#include "files.h" #include -class FileReader; class SoundStream; diff --git a/source/common/audio/sound/i_sound.h b/source/common/audio/sound/i_sound.h index 080515494..e8e5a1a0e 100644 --- a/source/common/audio/sound/i_sound.h +++ b/source/common/audio/sound/i_sound.h @@ -40,8 +40,8 @@ #include "i_soundinternal.h" #include "zstring.h" #include +#include "files.h" -class FileReader; struct FSoundChan; enum EStartSoundFlags diff --git a/source/common/console/c_enginecmds.cpp b/source/common/console/c_enginecmds.cpp index 7a959f311..f6b8732de 100644 --- a/source/common/console/c_enginecmds.cpp +++ b/source/common/console/c_enginecmds.cpp @@ -177,81 +177,47 @@ UNSAFE_CCMD (crashout) #endif -// commented out because it's very poorly implemented (it should not abuse I_ChDir like this!) -#if 0 UNSAFE_CCMD (dir) { - FString dir, path; - const char *match; - findstate_t c_file; - void *file; - - FString curdir = I_GetCWD(); - if (curdir.IsEmpty()) - { - Printf ("Current path too long\n"); - return; - } + FString path; if (argv.argc() > 1) { path = NicePath(argv[1]); - if (!I_ChDir(path)) - { - match = path; - dir = ExtractFilePath(path); - if (dir[0] != '\0') - { - match += dir.Len(); - } - else - { - dir = "./"; - } - if (match[0] == '\0') - { - match = "*"; - } - if (!I_ChDir(dir)) - { - Printf ("%s not found\n", dir.GetChars()); - return; - } - } - else - { - match = "*"; - dir = path; - } } else { - match = "*"; - dir = curdir; + path = I_GetCWD();; } - if (dir[dir.Len()-1] != '/') + auto base = ExtractFileBase(path, true); + FString bpath; + if (base.IndexOfAny("*?") >= 0) { - dir += '/'; + bpath = ExtractFilePath(path); } - - if ( (file = I_FindFirst (match, &c_file)) == ((void *)(-1))) - Printf ("Nothing matching %s%s\n", dir.GetChars(), match); else { - Printf ("Listing of %s%s:\n", dir.GetChars(), match); - do - { - if (I_FindAttr (&c_file) & FA_DIREC) - Printf (PRINT_BOLD, "%s \n", I_FindName (&c_file)); - else - Printf ("%s\n", I_FindName (&c_file)); - } while (I_FindNext (file, &c_file) == 0); - I_FindClose (file); + base = "*"; + bpath = path; } - I_ChDir(curdir); + FileSys::FileList list; + if (!FileSys::ScanDirectory(list, bpath, base, true)) + { + Printf ("Nothing matching %s\n", path.GetChars()); + } + else + { + Printf ("Listing of %s:\n", path.GetChars()); + for(auto& entry : list) + { + if (entry.isDirectory) + Printf (PRINT_BOLD, "%s \n", entry.FileName.c_str()); + else + Printf ("%s\n", entry.FileName.c_str()); + } + } } -#endif //========================================================================== // diff --git a/source/common/engine/files.h b/source/common/engine/files.h new file mode 100644 index 000000000..af6694cf0 --- /dev/null +++ b/source/common/engine/files.h @@ -0,0 +1,6 @@ +#pragma once +#include "fs_files.h" + +using FileSys::FileReader; +using FileSys::FileWriter; +using FileSys::BufferWriter; \ No newline at end of file diff --git a/source/common/engine/filesystem.h b/source/common/engine/filesystem.h new file mode 100644 index 000000000..53f491677 --- /dev/null +++ b/source/common/engine/filesystem.h @@ -0,0 +1,7 @@ +#pragma once +#include "fs_filesystem.h" + +using FileSys::FileSystem; +using FileSys::FResourceFile; + +inline FileSys::FileSystem fileSystem; diff --git a/source/common/engine/palettecontainer.h b/source/common/engine/palettecontainer.h index a220873a6..a761ae33c 100644 --- a/source/common/engine/palettecontainer.h +++ b/source/common/engine/palettecontainer.h @@ -3,8 +3,7 @@ #include #include "memarena.h" #include "palentry.h" - -class FileReader; +#include "files.h" enum { diff --git a/source/common/engine/serializer.cpp b/source/common/engine/serializer.cpp index 571a314d0..d0e6ac7c1 100644 --- a/source/common/engine/serializer.cpp +++ b/source/common/engine/serializer.cpp @@ -57,6 +57,8 @@ #include "base64.h" #include "vm.h" +using namespace FileSys; + extern DObject *WP_NOCHANGE; bool save_full = false; // for testing. Should be removed afterward. diff --git a/source/common/engine/serializer.h b/source/common/engine/serializer.h index c9cc26320..a6f74c037 100644 --- a/source/common/engine/serializer.h +++ b/source/common/engine/serializer.h @@ -4,7 +4,6 @@ #include #include #include "tarray.h" -#include "file_zip.h" #include "tflags.h" #include "vectors.h" #include "palentry.h" @@ -80,7 +79,7 @@ public: void SetUniqueSoundNames() { soundNamesAreUnique = true; } bool OpenWriter(bool pretty = true); bool OpenReader(const char *buffer, size_t length); - bool OpenReader(FCompressedBuffer *input); + bool OpenReader(FileSys::FCompressedBuffer *input); void Close(); void ReadObjects(bool hubtravel); bool BeginObject(const char *name); @@ -91,7 +90,7 @@ public: unsigned GetSize(const char *group); const char *GetKey(); const char *GetOutput(unsigned *len = nullptr); - FCompressedBuffer GetCompressedOutput(); + FileSys::FCompressedBuffer GetCompressedOutput(); // The sprite serializer is a special case because it is needed by the VM to handle its 'spriteid' type. virtual FSerializer &Sprite(const char *key, int32_t &spritenum, int32_t *def); // This is only needed by the type system. diff --git a/source/common/filesystem/files.h b/source/common/filesystem/include/fs_files.h similarity index 84% rename from source/common/filesystem/files.h rename to source/common/filesystem/include/fs_files.h index 99a3b133f..878122e82 100644 --- a/source/common/filesystem/files.h +++ b/source/common/filesystem/include/fs_files.h @@ -41,10 +41,13 @@ #include #include #include +#include #include "fs_swap.h" #include "tarray.h" +namespace FileSys { + class FileSystemException : public std::exception { protected: @@ -99,31 +102,6 @@ public: long GetLength () const { return Length; } }; -class MemoryReader : public FileReaderInterface -{ -protected: - const char * bufptr = nullptr; - long FilePos = 0; - - MemoryReader() - {} - -public: - MemoryReader(const char *buffer, long length) - { - bufptr = buffer; - Length = length; - FilePos = 0; - } - - long Tell() const override; - long Seek(long offset, int origin) override; - long Read(void *buffer, long len) override; - char *Gets(char *strbuf, int len) override; - virtual const char *GetBuffer() const override { return bufptr; } -}; - - struct FResourceLump; class FileReader @@ -217,8 +195,11 @@ public: std::vector Read(size_t len) { std::vector buffer(len); - Size length = mReader->Read(&buffer[0], (long)len); - buffer.resize((size_t)length); + if (len > 0) + { + Size length = mReader->Read(&buffer[0], (long)len); + buffer.resize((size_t)length); + } return buffer; } @@ -231,9 +212,13 @@ public: { auto len = GetLength(); std::vector buffer(len + padding); - Size length = mReader->Read(&buffer[0], (long)len); - if (length < len) buffer.clear(); - else memset(buffer.data() + len, 0, padding); + if (len > 0) + { + Size length = mReader->Read(&buffer[0], (long)len); + if (length < len) buffer.clear(); + else memset(buffer.data() + len, 0, padding); + } + else buffer[0] = 0; return buffer; } @@ -271,7 +256,7 @@ public: { uint16_t v = 0; Read(&v, 2); - return fs_private::LittleShort(v); + return byteswap::LittleShort(v); } int16_t ReadInt16() @@ -283,7 +268,7 @@ public: { uint16_t v = 0; Read(&v, 2); - return fs_private::BigShort(v); + return byteswap::BigShort(v); } int16_t ReadInt16BE() @@ -295,7 +280,7 @@ public: { uint32_t v = 0; Read(&v, 4); - return fs_private::LittleLong(v); + return byteswap::LittleLong(v); } int32_t ReadInt32() @@ -307,7 +292,7 @@ public: { uint32_t v = 0; Read(&v, 4); - return fs_private::BigLong(v); + return byteswap::BigLong(v); } int32_t ReadInt32BE() @@ -327,24 +312,6 @@ public: friend class FileSystem; }; -class DecompressorBase : public FileReaderInterface -{ - bool exceptions = false; -public: - // These do not work but need to be defined to satisfy the FileReaderInterface. - // They will just error out when called. - long Tell() const override; - long Seek(long offset, int origin) override; - char* Gets(char* strbuf, int len) override; - void DecompressionError(const char* error, ...) const; - void SetOwnsReader(); - void EnableExceptions(bool on) { exceptions = on; } - -protected: - FileReader* File = nullptr; - FileReader OwnedFile; -}; - class FileWriter { @@ -394,5 +361,6 @@ public: TArray&& TakeBuffer() { return std::move(mBuffer); } }; +} #endif diff --git a/source/common/filesystem/filesystem.h b/source/common/filesystem/include/fs_filesystem.h similarity index 81% rename from source/common/filesystem/filesystem.h rename to source/common/filesystem/include/fs_filesystem.h index 55b877268..b55949408 100644 --- a/source/common/filesystem/filesystem.h +++ b/source/common/filesystem/include/fs_filesystem.h @@ -8,12 +8,11 @@ -#include "files.h" +#include "fs_files.h" #include "resourcefile.h" -class FResourceFile; -struct FResourceLump; - +namespace FileSys { + union LumpShortName { char String[9]; @@ -91,31 +90,31 @@ public: int GetLastEntry(int wadnum) const noexcept; int GetEntryCount(int wadnum) const noexcept; - int CheckNumForName (const char *name, int namespc); - int CheckNumForName (const char *name, int namespc, int wadfile, bool exact = true); - int GetNumForName (const char *name, int namespc); + int CheckNumForName (const char *name, int namespc) const; + int CheckNumForName (const char *name, int namespc, int wadfile, bool exact = true) const; + int GetNumForName (const char *name, int namespc) const; - inline int CheckNumForName (const uint8_t *name) { return CheckNumForName ((const char *)name, ns_global); } - inline int CheckNumForName (const char *name) { return CheckNumForName (name, ns_global); } - inline int CheckNumForName (const uint8_t *name, int ns) { return CheckNumForName ((const char *)name, ns); } - inline int GetNumForName (const char *name) { return GetNumForName (name, ns_global); } - inline int GetNumForName (const uint8_t *name) { return GetNumForName ((const char *)name); } - inline int GetNumForName (const uint8_t *name, int ns) { return GetNumForName ((const char *)name, ns); } + inline int CheckNumForName (const uint8_t *name) const { return CheckNumForName ((const char *)name, ns_global); } + inline int CheckNumForName (const char *name) const { return CheckNumForName (name, ns_global); } + inline int CheckNumForName (const uint8_t *name, int ns) const { return CheckNumForName ((const char *)name, ns); } + inline int GetNumForName (const char *name) const { return GetNumForName (name, ns_global); } + inline int GetNumForName (const uint8_t *name) const { return GetNumForName ((const char *)name); } + inline int GetNumForName (const uint8_t *name, int ns) const { return GetNumForName ((const char *)name, ns); } - int CheckNumForFullName (const char *name, bool trynormal = false, int namespc = ns_global, bool ignoreext = false); - int CheckNumForFullName (const char *name, int wadfile); - int GetNumForFullName (const char *name); - int FindFile(const char* name) + int CheckNumForFullName (const char *cname, bool trynormal = false, int namespc = ns_global, bool ignoreext = false) const; + int CheckNumForFullName (const char *name, int wadfile) const; + int GetNumForFullName (const char *name) const; + int FindFile(const char* name) const { return CheckNumForFullName(name); } - bool FileExists(const char* name) + bool FileExists(const char* name) const { return FindFile(name) >= 0; } - bool FileExists(const std::string& name) + bool FileExists(const std::string& name) const { return FindFile(name.c_str()) >= 0; } @@ -139,10 +138,13 @@ public: 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 FindFileWithExtensions(const char* name, const char* const* exts, int count) 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 + int FileLength (int lump) const; int GetFileOffset (int lump); // [RH] Returns offset of lump in the wadfile int GetFileFlags (int lump); // Return the flags for this lump @@ -200,11 +202,12 @@ protected: int IwadIndex = -1; int MaxIwadIndex = -1; + StringPool* stringpool; + private: void DeleteAll(); void MoveLumpsInFolder(const char *); }; -extern FileSystem fileSystem; - +} \ No newline at end of file diff --git a/source/common/filesystem/fs_findfile.h b/source/common/filesystem/include/fs_findfile.h similarity index 97% rename from source/common/filesystem/fs_findfile.h rename to source/common/filesystem/include/fs_findfile.h index 7b6d3e3d2..d845b7d14 100644 --- a/source/common/filesystem/fs_findfile.h +++ b/source/common/filesystem/include/fs_findfile.h @@ -5,6 +5,8 @@ #include #include +namespace FileSys { + struct FileListEntry { std::string FileName; // file name only @@ -34,3 +36,4 @@ inline void FixPathSeparator(char* path) } } +} diff --git a/source/common/filesystem/fs_swap.h b/source/common/filesystem/include/fs_swap.h similarity index 97% rename from source/common/filesystem/fs_swap.h rename to source/common/filesystem/include/fs_swap.h index 1e8bbef83..12b988585 100644 --- a/source/common/filesystem/fs_swap.h +++ b/source/common/filesystem/include/fs_swap.h @@ -17,9 +17,9 @@ #include #endif -namespace fs_private -{ - +namespace FileSys { +namespace byteswap { + #ifdef __APPLE__ inline unsigned short LittleShort(unsigned short x) @@ -117,5 +117,6 @@ inline unsigned int BigLong (unsigned int x) #endif // __BIG_ENDIAN__ } +} #endif // __M_SWAP_H__ diff --git a/source/common/filesystem/resourcefile.h b/source/common/filesystem/include/resourcefile.h similarity index 78% rename from source/common/filesystem/resourcefile.h rename to source/common/filesystem/include/resourcefile.h index c40e1c598..f714c7995 100644 --- a/source/common/filesystem/resourcefile.h +++ b/source/common/filesystem/include/resourcefile.h @@ -6,8 +6,11 @@ #include #include #include -#include "files.h" +#include "fs_files.h" +namespace FileSys { + +class StringPool; std::string ExtractBaseName(const char* path, bool include_extension = false); void strReplace(std::string& str, const char* from, const char* to); @@ -113,7 +116,7 @@ struct FResourceLump int LumpSize; int RefCount; protected: - std::string FullName; + const char* FullName; public: uint8_t Flags; char * Cache; @@ -125,6 +128,7 @@ public: Owner = NULL; Flags = 0; RefCount = 0; + FullName = ""; } virtual ~FResourceLump(); @@ -133,7 +137,7 @@ public: virtual int GetFileOffset() { return -1; } virtual int GetIndexNum() const { return -1; } virtual int GetNamespace() const { return 0; } - void LumpNameSetup(const char* iname); + void LumpNameSetup(const char* iname, StringPool* allocator); void CheckEmbedded(LumpFilterInfo* lfi); virtual FCompressedBuffer GetRawData(); @@ -142,7 +146,8 @@ public: unsigned Size() const{ return LumpSize; } int LockCount() const { return RefCount; } - const char* getName() { return FullName.c_str(); } + const char* getName() { return FullName; } + void clearName() { FullName = ""; } protected: virtual int FillCache() { return -1; } @@ -153,13 +158,14 @@ class FResourceFile { public: FileReader Reader; - std::string FileName; + const char* FileName; protected: uint32_t NumLumps; char Hash[48]; + StringPool* stringpool; - FResourceFile(const char *filename); - FResourceFile(const char *filename, FileReader &r); + FResourceFile(const char *filename, StringPool* sp); + FResourceFile(const char *filename, FileReader &r, StringPool* sp); // for archives that can contain directories void GenerateHash(); @@ -172,12 +178,12 @@ private: int FilterLumpsByGameType(LumpFilterInfo *filter, void *lumps, size_t lumpsize, uint32_t max); bool FindPrefixRange(const char* 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 containeronly, LumpFilterInfo* filter, FileSystemMessageFunc Printf); + static FResourceFile *DoOpenResourceFile(const char *filename, FileReader &file, bool containeronly, LumpFilterInfo* filter, FileSystemMessageFunc Printf, StringPool* sp); public: - 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); + static FResourceFile *OpenResourceFile(const char *filename, FileReader &file, bool containeronly = false, LumpFilterInfo* filter = nullptr, FileSystemMessageFunc Printf = nullptr, StringPool* sp = nullptr); + static FResourceFile *OpenResourceFile(const char *filename, bool containeronly = false, LumpFilterInfo* filter = nullptr, FileSystemMessageFunc Printf = nullptr, StringPool* sp = nullptr); + static FResourceFile *OpenDirectory(const char *filename, LumpFilterInfo* filter = nullptr, FileSystemMessageFunc Printf = nullptr, StringPool* sp = 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; } @@ -191,57 +197,7 @@ public: FResourceLump *FindLump(const char *name); }; -struct FUncompressedLump : public FResourceLump -{ - int Position; - - virtual FileReader *GetReader(); - virtual int FillCache() override; - virtual int GetFileOffset() { return Position; } - -}; - - -// Base class for uncompressed resource files (WAD, GRP, PAK and single lumps) -class FUncompressedFile : public FResourceFile -{ -protected: - TArray Lumps; - - FUncompressedFile(const char *filename); - FUncompressedFile(const char *filename, FileReader &r); - virtual FResourceLump *GetLump(int no) { return ((unsigned)no < NumLumps)? &Lumps[no] : NULL; } -}; - - -struct FExternalLump : public FResourceLump -{ - std::string Filename; - - FExternalLump(const char *_filename, int filesize = -1); - virtual int FillCache() override; - -}; - -struct FMemoryLump : public FResourceLump -{ - FMemoryLump(const void* data, int length) - { - RefCount = INT_MAX / 2; - LumpSize = length; - Cache = new char[length]; - memcpy(Cache, data, length); - } - - virtual int FillCache() override - { - RefCount = INT_MAX / 2; // Make sure it never counts down to 0 by resetting it to something high each time it is used. - return 1; - } -}; - - - +} #endif diff --git a/source/common/filesystem/ancientzip.cpp b/source/common/filesystem/source/ancientzip.cpp similarity index 99% rename from source/common/filesystem/ancientzip.cpp rename to source/common/filesystem/source/ancientzip.cpp index 80f0c6093..4d1e6b990 100644 --- a/source/common/filesystem/ancientzip.cpp +++ b/source/common/filesystem/source/ancientzip.cpp @@ -46,6 +46,8 @@ #include #include "ancientzip.h" +namespace FileSys { + /**************************************************************** Bit-I/O variables and routines/macros @@ -433,3 +435,5 @@ int ShrinkLoop(unsigned char *out, unsigned int outsize, FileReader &_In, unsign } return 0; } + +} diff --git a/source/common/filesystem/ancientzip.h b/source/common/filesystem/source/ancientzip.h similarity index 94% rename from source/common/filesystem/ancientzip.h rename to source/common/filesystem/source/ancientzip.h index 57b0f3584..e25a75d3b 100644 --- a/source/common/filesystem/ancientzip.h +++ b/source/common/filesystem/source/ancientzip.h @@ -1,6 +1,8 @@ #pragma once -#include "files.h" +#include "fs_files.h" +namespace FileSys { + class FZipExploder { unsigned int Hold, Bits; @@ -41,4 +43,5 @@ public: int Explode(unsigned char *out, unsigned int outsize, FileReader &in, unsigned int insize, int flags); }; -int ShrinkLoop(unsigned char *out, unsigned int outsize, FileReader &in, unsigned int insize); \ No newline at end of file +int ShrinkLoop(unsigned char *out, unsigned int outsize, FileReader &in, unsigned int insize); +} diff --git a/source/common/filesystem/file_7z.cpp b/source/common/filesystem/source/file_7z.cpp similarity index 95% rename from source/common/filesystem/file_7z.cpp rename to source/common/filesystem/source/file_7z.cpp index 5539d5448..c51a566b9 100644 --- a/source/common/filesystem/file_7z.cpp +++ b/source/common/filesystem/source/file_7z.cpp @@ -40,7 +40,8 @@ #include "fs_findfile.h" - +namespace FileSys { + //----------------------------------------------------------------------- // // Interface classes to 7z library @@ -186,7 +187,7 @@ class F7ZFile : public FResourceFile C7zArchive *Archive; public: - F7ZFile(const char * filename, FileReader &filer); + F7ZFile(const char * filename, FileReader &filer, StringPool* sp); bool Open(LumpFilterInfo* filter, FileSystemMessageFunc Printf); virtual ~F7ZFile(); virtual FResourceLump *GetLump(int no) { return ((unsigned)no < NumLumps)? &Lumps[no] : NULL; } @@ -200,8 +201,8 @@ public: // //========================================================================== -F7ZFile::F7ZFile(const char * filename, FileReader &filer) - : FResourceFile(filename, filer) +F7ZFile::F7ZFile(const char * filename, FileReader &filer, StringPool* sp) + : FResourceFile(filename, filer, sp) { Lumps = NULL; Archive = NULL; @@ -227,7 +228,7 @@ bool F7ZFile::Open(LumpFilterInfo *filter, FileSystemMessageFunc Printf) Archive = NULL; if (res == SZ_ERROR_UNSUPPORTED) { - Printf(FSMessageLevel::Error, "%s: Decoder does not support this archive\n", FileName.c_str()); + Printf(FSMessageLevel::Error, "%s: Decoder does not support this archive\n", FileName); } else if (res == SZ_ERROR_MEM) { @@ -280,7 +281,7 @@ bool F7ZFile::Open(LumpFilterInfo *filter, FileSystemMessageFunc Printf) } FixPathSeparator(&nameASCII.front()); - lump_p->LumpNameSetup(nameASCII.c_str()); + lump_p->LumpNameSetup(nameASCII.c_str(), stringpool); lump_p->LumpSize = static_cast(SzArEx_GetFileSize(archPtr, i)); lump_p->Owner = this; lump_p->Flags = LUMPF_FULLPATH|LUMPF_COMPRESSED; @@ -300,7 +301,7 @@ bool F7ZFile::Open(LumpFilterInfo *filter, FileSystemMessageFunc Printf) if (SZ_OK != Archive->Extract(Lumps[0].Position, &temp[0])) { - Printf(FSMessageLevel::Error, "%s: unsupported 7z/LZMA file!\n", FileName.c_str()); + Printf(FSMessageLevel::Error, "%s: unsupported 7z/LZMA file!\n", FileName); return false; } } @@ -352,7 +353,7 @@ int F7ZLump::FillCache() // //========================================================================== -FResourceFile *Check7Z(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf) +FResourceFile *Check7Z(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf, StringPool* sp) { char head[k7zSignatureSize]; @@ -363,7 +364,7 @@ FResourceFile *Check7Z(const char *filename, FileReader &file, LumpFilterInfo* f file.Seek(0, FileReader::SeekSet); if (!memcmp(head, k7zSignature, k7zSignatureSize)) { - auto rf = new F7ZFile(filename, file); + auto rf = new F7ZFile(filename, file, sp); if (rf->Open(filter, Printf)) return rf; file = std::move(rf->Reader); // to avoid destruction of reader @@ -374,4 +375,4 @@ FResourceFile *Check7Z(const char *filename, FileReader &file, LumpFilterInfo* f } - +} diff --git a/source/common/filesystem/file_directory.cpp b/source/common/filesystem/source/file_directory.cpp similarity index 90% rename from source/common/filesystem/file_directory.cpp rename to source/common/filesystem/source/file_directory.cpp index 882b615cf..8208e6634 100644 --- a/source/common/filesystem/file_directory.cpp +++ b/source/common/filesystem/source/file_directory.cpp @@ -38,7 +38,10 @@ #include "resourcefile.h" #include "fs_findfile.h" +#include "fs_stringpool.h" +namespace FileSys { + std::string FS_FullPath(const char* directory); #ifdef _WIN32 @@ -75,7 +78,7 @@ class FDirectory : public FResourceFile void AddEntry(const char *fullpath, int size); public: - FDirectory(const char * dirname, bool nosubdirflag = false); + FDirectory(const char * dirname, StringPool* sp, bool nosubdirflag = false); bool Open(LumpFilterInfo* filter, FileSystemMessageFunc Printf); virtual FResourceLump *GetLump(int no) { return ((unsigned)no < NumLumps)? &Lumps[no] : NULL; } }; @@ -88,11 +91,12 @@ public: // //========================================================================== -FDirectory::FDirectory(const char * directory, bool nosubdirflag) -: FResourceFile(NULL), nosubdir(nosubdirflag) +FDirectory::FDirectory(const char * directory, StringPool* sp, bool nosubdirflag) + : FResourceFile("", sp), nosubdir(nosubdirflag) { - FileName = FS_FullPath(directory); - if (FileName[FileName.length()-1] != '/') FileName += '/'; + auto fn = FS_FullPath(directory); + if (fn.back() != '/') fn += '/'; + FileName = sp->Strdup(fn.c_str()); } //========================================================================== @@ -129,6 +133,7 @@ int FDirectory::AddDirectory(const char *dirpath, LumpFilterInfo* filter, FileSy if (entry.Length > 0x7fffffff) { Printf(FSMessageLevel::Warning, "%s is larger than 2GB and will be ignored\n", entry.FilePath.c_str()); + continue; } AddEntry(entry.FilePathRel.c_str(), (int)entry.Length); count++; @@ -147,7 +152,7 @@ int FDirectory::AddDirectory(const char *dirpath, LumpFilterInfo* filter, FileSy bool FDirectory::Open(LumpFilterInfo* filter, FileSystemMessageFunc Printf) { - NumLumps = AddDirectory(FileName.c_str(), filter, Printf); + NumLumps = AddDirectory(FileName, filter, Printf); PostProcessArchive(&Lumps[0], sizeof(FDirectoryLump), filter); return true; } @@ -166,11 +171,11 @@ void FDirectory::AddEntry(const char *fullpath, int size) lump_p->mFullPath = fullpath; // [mxd] Convert name to lowercase - std::string name = fullpath + FileName; + std::string name = fullpath + strlen(FileName); for (auto& c : name) c = tolower(c); // The lump's name is only the part relative to the main directory - lump_p->LumpNameSetup(name.c_str()); + lump_p->LumpNameSetup(name.c_str(), stringpool); lump_p->LumpSize = size; lump_p->Owner = this; lump_p->Flags = 0; @@ -220,11 +225,12 @@ int FDirectoryLump::FillCache() // //========================================================================== -FResourceFile *CheckDir(const char *filename, bool nosubdirflag, LumpFilterInfo* filter, FileSystemMessageFunc Printf) +FResourceFile *CheckDir(const char *filename, bool nosubdirflag, LumpFilterInfo* filter, FileSystemMessageFunc Printf, StringPool* sp) { - auto rf = new FDirectory(filename, nosubdirflag); + auto rf = new FDirectory(filename, sp, nosubdirflag); if (rf->Open(filter, Printf)) return rf; delete rf; return nullptr; } +} diff --git a/source/common/filesystem/file_grp.cpp b/source/common/filesystem/source/file_grp.cpp similarity index 89% rename from source/common/filesystem/file_grp.cpp rename to source/common/filesystem/source/file_grp.cpp index 4765bcde0..b289b121d 100644 --- a/source/common/filesystem/file_grp.cpp +++ b/source/common/filesystem/source/file_grp.cpp @@ -33,10 +33,11 @@ ** */ -#include "resourcefile.h" +#include "resourcefile_internal.h" #include "fs_swap.h" -using namespace fs_private; +namespace FileSys { + using namespace byteswap; //========================================================================== // @@ -73,7 +74,7 @@ struct GrpLump class FGrpFile : public FUncompressedFile { public: - FGrpFile(const char * filename, FileReader &file); + FGrpFile(const char * filename, FileReader &file, StringPool* sp); bool Open(LumpFilterInfo* filter); }; @@ -84,8 +85,8 @@ public: // //========================================================================== -FGrpFile::FGrpFile(const char *filename, FileReader &file) -: FUncompressedFile(filename, file) +FGrpFile::FGrpFile(const char *filename, FileReader &file, StringPool* sp) +: FUncompressedFile(filename, file, sp) { } @@ -117,7 +118,7 @@ bool FGrpFile::Open(LumpFilterInfo* filter) Position += fileinfo[i].Size; Lumps[i].Flags = 0; fileinfo[i].NameWithZero[12] = '\0'; // Be sure filename is null-terminated - Lumps[i].LumpNameSetup(fileinfo[i].NameWithZero); + Lumps[i].LumpNameSetup(fileinfo[i].NameWithZero, stringpool); } GenerateHash(); delete[] fileinfo; @@ -131,7 +132,7 @@ bool FGrpFile::Open(LumpFilterInfo* filter) // //========================================================================== -FResourceFile *CheckGRP(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf) +FResourceFile *CheckGRP(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf, StringPool* sp) { char head[12]; @@ -142,7 +143,7 @@ FResourceFile *CheckGRP(const char *filename, FileReader &file, LumpFilterInfo* file.Seek(0, FileReader::SeekSet); if (!memcmp(head, "KenSilverman", 12)) { - auto rf = new FGrpFile(filename, file); + auto rf = new FGrpFile(filename, file, sp); if (rf->Open(filter)) return rf; file = std::move(rf->Reader); // to avoid destruction of reader @@ -152,3 +153,4 @@ FResourceFile *CheckGRP(const char *filename, FileReader &file, LumpFilterInfo* return NULL; } +} diff --git a/source/common/filesystem/file_lump.cpp b/source/common/filesystem/source/file_lump.cpp similarity index 86% rename from source/common/filesystem/file_lump.cpp rename to source/common/filesystem/source/file_lump.cpp index 60c957081..ad4406a0f 100644 --- a/source/common/filesystem/file_lump.cpp +++ b/source/common/filesystem/source/file_lump.cpp @@ -32,8 +32,9 @@ ** */ -#include "resourcefile.h" +#include "resourcefile_internal.h" +namespace FileSys { //========================================================================== // // Single lump @@ -43,7 +44,7 @@ class FLumpFile : public FUncompressedFile { public: - FLumpFile(const char * filename, FileReader &file); + FLumpFile(const char * filename, FileReader &file, StringPool* sp); bool Open(LumpFilterInfo* filter); }; @@ -54,8 +55,8 @@ public: // //========================================================================== -FLumpFile::FLumpFile(const char *filename, FileReader &file) - : FUncompressedFile(filename, file) +FLumpFile::FLumpFile(const char *filename, FileReader &file, StringPool* sp) + : FUncompressedFile(filename, file, sp) { } @@ -68,7 +69,7 @@ FLumpFile::FLumpFile(const char *filename, FileReader &file) bool FLumpFile::Open(LumpFilterInfo*) { Lumps.Resize(1); - Lumps[0].LumpNameSetup(ExtractBaseName(FileName.c_str(), true).c_str()); + Lumps[0].LumpNameSetup(ExtractBaseName(FileName, true).c_str(), stringpool); Lumps[0].Owner = this; Lumps[0].Position = 0; Lumps[0].LumpSize = (int)Reader.GetLength(); @@ -83,13 +84,14 @@ bool FLumpFile::Open(LumpFilterInfo*) // //========================================================================== -FResourceFile *CheckLump(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf) +FResourceFile *CheckLump(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf, StringPool* sp) { // always succeeds - auto rf = new FLumpFile(filename, file); + auto rf = new FLumpFile(filename, file, sp); if (rf->Open(filter)) return rf; file = std::move(rf->Reader); // to avoid destruction of reader delete rf; return NULL; } +} diff --git a/source/common/filesystem/file_pak.cpp b/source/common/filesystem/source/file_pak.cpp similarity index 89% rename from source/common/filesystem/file_pak.cpp rename to source/common/filesystem/source/file_pak.cpp index 4003ce396..4e3b3ef93 100644 --- a/source/common/filesystem/file_pak.cpp +++ b/source/common/filesystem/source/file_pak.cpp @@ -32,10 +32,11 @@ ** */ -#include "resourcefile.h" +#include "resourcefile_internal.h" -using namespace fs_private; +namespace FileSys { + using namespace byteswap; //========================================================================== // // @@ -65,7 +66,7 @@ struct dpackheader_t class FPakFile : public FUncompressedFile { public: - FPakFile(const char * filename, FileReader &file); + FPakFile(const char * filename, FileReader &file, StringPool* sp); bool Open(LumpFilterInfo* filter); }; @@ -78,8 +79,8 @@ public: // //========================================================================== -FPakFile::FPakFile(const char *filename, FileReader &file) - : FUncompressedFile(filename, file) +FPakFile::FPakFile(const char *filename, FileReader &file, StringPool* sp) + : FUncompressedFile(filename, file, sp) { } @@ -105,7 +106,7 @@ bool FPakFile::Open(LumpFilterInfo* filter) for(uint32_t i = 0; i < NumLumps; i++) { - Lumps[i].LumpNameSetup(fileinfo[i].name); + Lumps[i].LumpNameSetup(fileinfo[i].name, stringpool); Lumps[i].Flags = LUMPF_FULLPATH; Lumps[i].Owner = this; Lumps[i].Position = LittleLong(fileinfo[i].filepos); @@ -124,7 +125,7 @@ bool FPakFile::Open(LumpFilterInfo* filter) // //========================================================================== -FResourceFile *CheckPak(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf) +FResourceFile *CheckPak(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf, StringPool* sp) { char head[4]; @@ -135,7 +136,7 @@ FResourceFile *CheckPak(const char *filename, FileReader &file, LumpFilterInfo* file.Seek(0, FileReader::SeekSet); if (!memcmp(head, "PACK", 4)) { - auto rf = new FPakFile(filename, file); + auto rf = new FPakFile(filename, file, sp); if (rf->Open(filter)) return rf; file = std::move(rf->Reader); // to avoid destruction of reader @@ -145,3 +146,4 @@ FResourceFile *CheckPak(const char *filename, FileReader &file, LumpFilterInfo* return NULL; } +} diff --git a/source/common/filesystem/file_rff.cpp b/source/common/filesystem/source/file_rff.cpp similarity index 93% rename from source/common/filesystem/file_rff.cpp rename to source/common/filesystem/source/file_rff.cpp index 723d184e6..1d3cf15bf 100644 --- a/source/common/filesystem/file_rff.cpp +++ b/source/common/filesystem/source/file_rff.cpp @@ -33,10 +33,11 @@ ** */ -#include "resourcefile.h" +#include "resourcefile_internal.h" #include "fs_swap.h" -using namespace fs_private; +namespace FileSys { + using namespace byteswap; //========================================================================== // @@ -110,7 +111,7 @@ class FRFFFile : public FResourceFile FRFFLump *Lumps; public: - FRFFFile(const char * filename, FileReader &file); + FRFFFile(const char * filename, FileReader &file, StringPool* sp); virtual ~FRFFFile(); virtual bool Open(LumpFilterInfo* filter); virtual FResourceLump *GetLump(int no) { return ((unsigned)no < NumLumps)? &Lumps[no] : NULL; } @@ -123,8 +124,8 @@ public: // //========================================================================== -FRFFFile::FRFFFile(const char *filename, FileReader &file) -: FResourceFile(filename, file) +FRFFFile::FRFFFile(const char *filename, FileReader &file, StringPool* sp) +: FResourceFile(filename, file, sp) { Lumps = NULL; } @@ -172,7 +173,7 @@ bool FRFFFile::Open(LumpFilterInfo*) name[len+2] = lumps[i].Extension[1]; name[len+3] = lumps[i].Extension[2]; name[len+4] = 0; - Lumps[i].LumpNameSetup(name); + Lumps[i].LumpNameSetup(name, stringpool); } delete[] lumps; GenerateHash(); @@ -238,7 +239,7 @@ int FRFFLump::FillCache() // //========================================================================== -FResourceFile *CheckRFF(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf) +FResourceFile *CheckRFF(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf, StringPool* sp) { char head[4]; @@ -249,7 +250,7 @@ FResourceFile *CheckRFF(const char *filename, FileReader &file, LumpFilterInfo* file.Seek(0, FileReader::SeekSet); if (!memcmp(head, "RFF\x1a", 4)) { - auto rf = new FRFFFile(filename, file); + auto rf = new FRFFFile(filename, file, sp); if (rf->Open(filter)) return rf; file = std::move(rf->Reader); // to avoid destruction of reader @@ -260,4 +261,4 @@ FResourceFile *CheckRFF(const char *filename, FileReader &file, LumpFilterInfo* } - +} diff --git a/source/common/filesystem/file_ssi.cpp b/source/common/filesystem/source/file_ssi.cpp similarity index 91% rename from source/common/filesystem/file_ssi.cpp rename to source/common/filesystem/source/file_ssi.cpp index 6bf60cc1e..4b68997f0 100644 --- a/source/common/filesystem/file_ssi.cpp +++ b/source/common/filesystem/source/file_ssi.cpp @@ -33,8 +33,9 @@ ** */ -#include "resourcefile.h" +#include "resourcefile_internal.h" +namespace FileSys { //========================================================================== // // Build GRP file @@ -44,7 +45,7 @@ class FSSIFile : public FUncompressedFile { public: - FSSIFile(const char * filename, FileReader &file); + FSSIFile(const char * filename, FileReader &file, StringPool* sp); bool Open(int version, int lumpcount, LumpFilterInfo* filter); }; @@ -55,8 +56,8 @@ public: // //========================================================================== -FSSIFile::FSSIFile(const char *filename, FileReader &file) -: FUncompressedFile(filename, file) +FSSIFile::FSSIFile(const char *filename, FileReader &file, StringPool* sp) +: FUncompressedFile(filename, file, sp) { } @@ -85,7 +86,7 @@ bool FSSIFile::Open(int version, int lumpcount, LumpFilterInfo*) int flength = Reader.ReadInt32(); - Lumps[i].LumpNameSetup(fn); + Lumps[i].LumpNameSetup(fn, stringpool); Lumps[i].Position = j; Lumps[i].LumpSize = flength; Lumps[i].Owner = this; @@ -94,7 +95,7 @@ bool FSSIFile::Open(int version, int lumpcount, LumpFilterInfo*) // SSI files can swap the order of the extension's characters - but there's no reliable detection for this and it can be mixed inside the same container, // so we have no choice but to create another file record for the altered name. std::swap(fn[strlength - 1], fn[strlength - 3]); - Lumps[i+1].LumpNameSetup(fn); + Lumps[i+1].LumpNameSetup(fn, stringpool); Lumps[i+1].Position = j; Lumps[i+1].LumpSize = flength; Lumps[i+1].Owner = this; @@ -114,7 +115,7 @@ bool FSSIFile::Open(int version, int lumpcount, LumpFilterInfo*) // //========================================================================== -FResourceFile* CheckSSI(const char* filename, FileReader& file, LumpFilterInfo* filter, FileSystemMessageFunc Printf) +FResourceFile* CheckSSI(const char* filename, FileReader& file, LumpFilterInfo* filter, FileSystemMessageFunc Printf, StringPool* sp) { char zerobuf[72]; char buf[72]; @@ -144,7 +145,7 @@ FResourceFile* CheckSSI(const char* filename, FileReader& file, LumpFilterInfo* { if (!skipstring(70)) return nullptr; } - auto ssi = new FSSIFile(filename, file); + auto ssi = new FSSIFile(filename, file, sp); if (ssi->Open(version, numfiles, filter)) return ssi; file = std::move(ssi->Reader); // to avoid destruction of reader delete ssi; @@ -152,3 +153,5 @@ FResourceFile* CheckSSI(const char* filename, FileReader& file, LumpFilterInfo* } return nullptr; } + +} diff --git a/source/common/filesystem/file_wad.cpp b/source/common/filesystem/source/file_wad.cpp similarity index 92% rename from source/common/filesystem/file_wad.cpp rename to source/common/filesystem/source/file_wad.cpp index fb77a8781..13eb0b098 100644 --- a/source/common/filesystem/file_wad.cpp +++ b/source/common/filesystem/source/file_wad.cpp @@ -35,11 +35,11 @@ #include #include "resourcefile.h" -#include "filesystem.h" +#include "fs_filesystem.h" #include "fs_swap.h" -using namespace fs_private; - +namespace FileSys { + using namespace byteswap; struct wadinfo_t { @@ -136,7 +136,7 @@ class FWadFile : public FResourceFile void SkinHack (FileSystemMessageFunc Printf); public: - FWadFile(const char * filename, FileReader &file); + FWadFile(const char * filename, FileReader &file, StringPool* sp); FResourceLump *GetLump(int lump) { return &Lumps[lump]; } bool Open(LumpFilterInfo* filter, FileSystemMessageFunc Printf); }; @@ -150,8 +150,8 @@ public: // //========================================================================== -FWadFile::FWadFile(const char *filename, FileReader &file) - : FResourceFile(filename, file) +FWadFile::FWadFile(const char *filename, FileReader &file, StringPool* sp) + : FResourceFile(filename, file, sp) { } @@ -183,7 +183,7 @@ bool FWadFile::Open(LumpFilterInfo*, FileSystemMessageFunc Printf) // Check again to detect broken wads if (InfoTableOfs + NumLumps*sizeof(wadlump_t) > (unsigned)wadSize) { - Printf(FSMessageLevel::Error, "%s: Bad directory offset.\n", FileName.c_str()); + Printf(FSMessageLevel::Error, "%s: Bad directory offset.\n", FileName); return false; } } @@ -207,7 +207,7 @@ bool FWadFile::Open(LumpFilterInfo*, FileSystemMessageFunc Printf) #else Lumps[i].Compressed = false; #endif - Lumps[i].LumpNameSetup(n); + Lumps[i].LumpNameSetup(n, stringpool); Lumps[i].Owner = this; Lumps[i].Position = isBigEndian ? BigLong(fileinfo[i].FilePos) : LittleLong(fileinfo[i].FilePos); @@ -220,8 +220,8 @@ bool FWadFile::Open(LumpFilterInfo*, FileSystemMessageFunc Printf) { if (Lumps[i].LumpSize != 0) { - Printf(FSMessageLevel::Warning, "%s: Lump %s contains invalid positioning info and will be ignored\n", FileName.c_str(), Lumps[i].getName()); - Lumps[i].LumpNameSetup(""); + Printf(FSMessageLevel::Warning, "%s: Lump %s contains invalid positioning info and will be ignored\n", FileName, Lumps[i].getName()); + Lumps[i].clearName(); } Lumps[i].LumpSize = Lumps[i].Position = 0; } @@ -305,7 +305,7 @@ void FWadFile::SetNamespace(const char *startmarker, const char *endmarker, name { if (numendmarkers == 0) return; // no markers found - Printf(FSMessageLevel::Warning, "%s: %s marker without corresponding %s found.\n", FileName.c_str(), endmarker, startmarker); + Printf(FSMessageLevel::Warning, "%s: %s marker without corresponding %s found.\n", FileName, endmarker, startmarker); if (flathack) @@ -319,7 +319,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. - Printf(FSMessageLevel::DebugNotify, "%s: Marking %s as potential flat\n", FileName.c_str(), Lumps[ii].getName()); + Printf(FSMessageLevel::DebugNotify, "%s: Marking %s as potential flat\n", FileName, Lumps[ii].getName()); Lumps[ii].Flags |= LUMPF_MAYBEFLAT; } } @@ -333,7 +333,7 @@ void FWadFile::SetNamespace(const char *startmarker, const char *endmarker, name int start, end; if (markers[i].markertype != 0) { - Printf(FSMessageLevel::Warning, "%s: %s marker without corresponding %s found.\n", FileName.c_str(), endmarker, startmarker); + Printf(FSMessageLevel::Warning, "%s: %s marker without corresponding %s found.\n", FileName, endmarker, startmarker); i++; continue; } @@ -342,21 +342,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(FSMessageLevel::Warning, "%s: duplicate %s marker found.\n", FileName.c_str(), startmarker); + Printf(FSMessageLevel::Warning, "%s: duplicate %s marker found.\n", FileName, startmarker); i++; continue; } // same for x_END markers while (i < markers.Size()-1 && (markers[i].markertype == 1 && markers[i+1].markertype == 1)) { - Printf(FSMessageLevel::Warning, "%s: duplicate %s marker found.\n", FileName.c_str(), endmarker); + Printf(FSMessageLevel::Warning, "%s: duplicate %s marker found.\n", FileName, endmarker); i++; continue; } // We found a starting marker but no end marker. Ignore this block. if (i >= markers.Size()) { - Printf(FSMessageLevel::Warning, "%s: %s marker without corresponding %s found.\n", FileName.c_str(), startmarker, endmarker); + Printf(FSMessageLevel::Warning, "%s: %s marker without corresponding %s found.\n", FileName, startmarker, endmarker); end = NumLumps; } else @@ -365,14 +365,14 @@ void FWadFile::SetNamespace(const char *startmarker, const char *endmarker, name } // we found a marked block - Printf(FSMessageLevel::DebugNotify, "%s: Found %s block at (%d-%d)\n", FileName.c_str(), startmarker, markers[start].index, end); + Printf(FSMessageLevel::DebugNotify, "%s: Found %s block at (%d-%d)\n", FileName, startmarker, markers[start].index, end); for(int j = markers[start].index + 1; j < end; j++) { if (Lumps[j].Namespace != ns_global) { if (!warned) { - Printf(FSMessageLevel::Warning, "%s: Overlapping namespaces found (lump %d)\n", FileName.c_str(), j); + Printf(FSMessageLevel::Warning, "%s: Overlapping namespaces found (lump %d)\n", FileName, j); } warned = true; } @@ -382,7 +382,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 - Printf(FSMessageLevel::DebugWarn, "%s: Skipped empty sprite %s (lump %d)\n", FileName.c_str(), Lumps[j].getName(), j); + Printf(FSMessageLevel::DebugWarn, "%s: Skipped empty sprite %s (lump %d)\n", FileName, Lumps[j].getName(), j); } else { @@ -420,7 +420,7 @@ void FWadFile::SkinHack (FileSystemMessageFunc Printf) if (!strnicmp(lump->getName(), "S_SKIN", 6)) { // Wad has at least one skin. - lump->LumpNameSetup("S_SKIN"); + lump->LumpNameSetup("S_SKIN", nullptr); if (!skinned) { skinned = true; @@ -452,7 +452,7 @@ void FWadFile::SkinHack (FileSystemMessageFunc Printf) } if (skinned && hasmap) { - Printf(FSMessageLevel::Attention, "%s: The maps will not be loaded because it has a skin.\n", FileName.c_str()); + Printf(FSMessageLevel::Attention, "%s: The maps will not be loaded because it has a skin.\n", FileName); Printf(FSMessageLevel::Attention, "You should remove the skin from the wad to play these maps.\n"); } } @@ -464,7 +464,7 @@ void FWadFile::SkinHack (FileSystemMessageFunc Printf) // //========================================================================== -FResourceFile *CheckWad(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf) +FResourceFile *CheckWad(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf, StringPool* sp) { char head[4]; @@ -475,7 +475,7 @@ FResourceFile *CheckWad(const char *filename, FileReader &file, LumpFilterInfo* file.Seek(0, FileReader::SeekSet); if (!memcmp(head, "IWAD", 4) || !memcmp(head, "PWAD", 4)) { - auto rf = new FWadFile(filename, file); + auto rf = new FWadFile(filename, file, sp); if (rf->Open(filter, Printf)) return rf; file = std::move(rf->Reader); // to avoid destruction of reader @@ -485,3 +485,4 @@ FResourceFile *CheckWad(const char *filename, FileReader &file, LumpFilterInfo* return NULL; } +} diff --git a/source/common/filesystem/file_whres.cpp b/source/common/filesystem/source/file_whres.cpp similarity index 86% rename from source/common/filesystem/file_whres.cpp rename to source/common/filesystem/source/file_whres.cpp index d7149f116..efdfd5d39 100644 --- a/source/common/filesystem/file_whres.cpp +++ b/source/common/filesystem/source/file_whres.cpp @@ -34,10 +34,12 @@ ** */ -#include "resourcefile.h" +#include "resourcefile_internal.h" +#include "fs_stringpool.h" #include "fs_swap.h" -using namespace fs_private; +namespace FileSys { + using namespace byteswap; //========================================================================== // @@ -47,9 +49,9 @@ using namespace fs_private; class FWHResFile : public FUncompressedFile { - std::string basename; + const char* BaseName; public: - FWHResFile(const char * filename, FileReader &file); + FWHResFile(const char * filename, FileReader &file, StringPool* sp); bool Open(LumpFilterInfo* filter); }; @@ -60,10 +62,10 @@ public: // //========================================================================== -FWHResFile::FWHResFile(const char *filename, FileReader &file) - : FUncompressedFile(filename, file) +FWHResFile::FWHResFile(const char *filename, FileReader &file, StringPool* sp) + : FUncompressedFile(filename, file, sp) { - basename = ExtractBaseName(filename, false); + BaseName = stringpool->Strdup(ExtractBaseName(filename, false).c_str()); } //========================================================================== @@ -91,8 +93,9 @@ bool FWHResFile::Open(LumpFilterInfo*) if (length == 0) break; char num[5]; snprintf(num, 5, "/%04d", k); - std::string synthname = basename + num; - Lumps[i].LumpNameSetup(synthname.c_str()); + std::string synthname = BaseName; + synthname += num; + Lumps[i].LumpNameSetup(synthname.c_str(), stringpool); Lumps[i].Owner = this; Lumps[i].Position = offset; Lumps[i].LumpSize = length; @@ -111,7 +114,7 @@ bool FWHResFile::Open(LumpFilterInfo*) // //========================================================================== -FResourceFile *CheckWHRes(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf) +FResourceFile *CheckWHRes(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf, StringPool* sp) { if (file.GetLength() >= 8192) // needs to be at least 8192 to contain one file and the directory. { @@ -131,11 +134,12 @@ FResourceFile *CheckWHRes(const char *filename, FileReader &file, LumpFilterInfo if (offset != checkpos || length == 0 || offset + length >= (size_t)size - 4096 ) return nullptr; checkpos += (length+4095) / 4096; } - auto rf = new FWHResFile(filename, file); + auto rf = new FWHResFile(filename, file, sp); if (rf->Open(filter)) return rf; file = std::move(rf->Reader); // to avoid destruction of reader delete rf; } return NULL; } - \ No newline at end of file + +} \ No newline at end of file diff --git a/source/common/filesystem/file_zip.cpp b/source/common/filesystem/source/file_zip.cpp similarity index 94% rename from source/common/filesystem/file_zip.cpp rename to source/common/filesystem/source/file_zip.cpp index 4237e0f8a..c85788fe5 100644 --- a/source/common/filesystem/file_zip.cpp +++ b/source/common/filesystem/source/file_zip.cpp @@ -41,7 +41,8 @@ #include "fs_findfile.h" #include "fs_swap.h" -using namespace fs_private; +namespace FileSys { + using namespace byteswap; #define BUFREADCOMMENT (0x400) @@ -164,8 +165,8 @@ static uint32_t Zip_FindCentralDir(FileReader &fin, bool* zip64) // //========================================================================== -FZipFile::FZipFile(const char * filename, FileReader &file) -: FResourceFile(filename, file) +FZipFile::FZipFile(const char * filename, FileReader &file, StringPool* sp) +: FResourceFile(filename, file, sp) { Lumps = NULL; } @@ -180,7 +181,7 @@ bool FZipFile::Open(LumpFilterInfo* filter, FileSystemMessageFunc Printf) if (centraldir == 0) { - Printf(FSMessageLevel::Error, "%s: ZIP file corrupt!\n", FileName.c_str()); + Printf(FSMessageLevel::Error, "%s: ZIP file corrupt!\n", FileName); return false; } @@ -196,7 +197,7 @@ bool FZipFile::Open(LumpFilterInfo* filter, FileSystemMessageFunc Printf) if (info.NumEntries != info.NumEntriesOnAllDisks || info.FirstDisk != 0 || info.DiskNumber != 0) { - Printf(FSMessageLevel::Error, "%s: Multipart Zip files are not supported.\n", FileName.c_str()); + Printf(FSMessageLevel::Error, "%s: Multipart Zip files are not supported.\n", FileName); return false; } @@ -215,7 +216,7 @@ bool FZipFile::Open(LumpFilterInfo* filter, FileSystemMessageFunc Printf) if (info.NumEntries != info.NumEntriesOnAllDisks || info.FirstDisk != 0 || info.DiskNumber != 0) { - Printf(FSMessageLevel::Error, "%s: Multipart Zip files are not supported.\n", FileName.c_str()); + Printf(FSMessageLevel::Error, "%s: Multipart Zip files are not supported.\n", FileName); return false; } @@ -254,35 +255,36 @@ bool FZipFile::Open(LumpFilterInfo* filter, FileSystemMessageFunc Printf) if (dirptr > ((char*)directory) + dirsize) // This directory entry goes beyond the end of the file. { free(directory); - Printf(FSMessageLevel::Error, "%s: Central directory corrupted.", FileName.c_str()); + Printf(FSMessageLevel::Error, "%s: Central directory corrupted.", FileName); return false; } for (auto& c : name) c = tolower(c); - if (name.find_first_of("filter/") == 0) + auto vv = name.find("__macosx"); + if (name.find("filter/") == 0) continue; // 'filter' is a reserved name of the file system. - if (name.find_first_of("__macosx") == 0) + if (name.find("__macosx") == 0) continue; // skip Apple garbage. At this stage only the root folder matters. - if (name.find_first_of(".bat") != std::string::npos || name.find_first_of(".exe") != std::string::npos) + if (name.find(".bat") != std::string::npos || name.find(".exe") != std::string::npos) continue; // also ignore executables for this. if (!foundprefix) { // check for special names, if one of these gets found this must be treated as a normal zip. - bool isspecial = name.find_first_of("/") == std::string::npos || + bool isspecial = name.find("/") == std::string::npos || (filter && std::find(filter->reservedFolders.begin(), filter->reservedFolders.end(), name) != filter->reservedFolders.end()); if (isspecial) break; - name0 = std::string(name, 0, name.find_last_of("/")+1); - name1 = std::string(name, 0, name.find_first_of("/") + 1); + name0 = std::string(name, 0, name.rfind("/")+1); + name1 = std::string(name, 0, name.find("/") + 1); foundprefix = true; } - if (name.find_first_of(name0) != 0) + if (name.find(name0) != 0) { if (!name1.empty()) { name0 = name1; - if (name.find_first_of(name0) != 0) + if (name.find(name0) != 0) { name0 = ""; } @@ -295,7 +297,7 @@ bool FZipFile::Open(LumpFilterInfo* filter, FileSystemMessageFunc Printf) // at least one of the more common definition lumps must be present. for (auto &p : filter->requiredPrefixes) { - if (name.find_first_of(name0 + p) == 0 || name.find_last_of(p) == ptrdiff_t(name.length() - p.length())) + if (name.find(name0 + p) == 0 || name.rfind(p) == ptrdiff_t(name.length() - p.length())) { foundspeciallump = true; break; @@ -322,11 +324,11 @@ bool FZipFile::Open(LumpFilterInfo* filter, FileSystemMessageFunc Printf) if (dirptr > ((char*)directory) + dirsize) // This directory entry goes beyond the end of the file. { free(directory); - Printf(FSMessageLevel::Error, "%s: Central directory corrupted.", FileName.c_str()); + Printf(FSMessageLevel::Error, "%s: Central directory corrupted.", FileName); return false; } - if (name.find_first_of("__macosx") == 0 || name.find_first_of("__MACOSX") == 0) + if (name.find("__macosx") == 0 || name.find("__MACOSX") == 0) { skipped++; continue; // Weed out Apple's resource fork garbage right here because it interferes with safe operation. @@ -349,7 +351,7 @@ bool FZipFile::Open(LumpFilterInfo* filter, FileSystemMessageFunc Printf) zip_fh->Method != METHOD_IMPLODE && zip_fh->Method != METHOD_SHRINK) { - Printf(FSMessageLevel::Error, "%s: '%s' uses an unsupported compression algorithm (#%d).\n", FileName.c_str(), name.c_str(), zip_fh->Method); + Printf(FSMessageLevel::Error, "%s: '%s' uses an unsupported compression algorithm (#%d).\n", FileName, name.c_str(), zip_fh->Method); skipped++; continue; } @@ -357,7 +359,7 @@ bool FZipFile::Open(LumpFilterInfo* filter, FileSystemMessageFunc Printf) zip_fh->Flags = LittleShort(zip_fh->Flags); if (zip_fh->Flags & ZF_ENCRYPTED) { - Printf(FSMessageLevel::Error, "%s: '%s' is encrypted. Encryption is not supported.\n", FileName.c_str(), name.c_str()); + Printf(FSMessageLevel::Error, "%s: '%s' is encrypted. Encryption is not supported.\n", FileName, name.c_str()); skipped++; continue; } @@ -384,7 +386,7 @@ bool FZipFile::Open(LumpFilterInfo* filter, FileSystemMessageFunc Printf) if (zip_64->CompressedSize > 0x7fffffff || zip_64->UncompressedSize > 0x7fffffff) { // The file system is limited to 32 bit file sizes; - Printf(FSMessageLevel::Warning, "%s: '%s' is too large.\n", FileName.c_str(), name.c_str()); + Printf(FSMessageLevel::Warning, "%s: '%s' is too large.\n", FileName, name.c_str()); skipped++; continue; } @@ -395,7 +397,7 @@ bool FZipFile::Open(LumpFilterInfo* filter, FileSystemMessageFunc Printf) } } - lump_p->LumpNameSetup(name.c_str()); + lump_p->LumpNameSetup(name.c_str(), stringpool); lump_p->LumpSize = UncompressedSize; lump_p->Owner = this; // The start of the Reader will be determined the first time it is accessed. @@ -531,7 +533,7 @@ int FZipLump::GetFileOffset() // //========================================================================== -FResourceFile *CheckZip(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf) +FResourceFile *CheckZip(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf, StringPool* sp) { char head[4]; @@ -542,7 +544,7 @@ FResourceFile *CheckZip(const char *filename, FileReader &file, LumpFilterInfo* file.Seek(0, FileReader::SeekSet); if (!memcmp(head, "PK\x3\x4", 4)) { - auto rf = new FZipFile(filename, file); + auto rf = new FZipFile(filename, file, sp); if (rf->Open(filter, Printf)) return rf; file = std::move(rf->Reader); // to avoid destruction of reader @@ -719,3 +721,5 @@ bool WriteZip(const char* filename, const FCompressedBuffer* content, size_t con } return false; } + +} diff --git a/source/common/filesystem/file_zip.h b/source/common/filesystem/source/file_zip.h similarity index 91% rename from source/common/filesystem/file_zip.h rename to source/common/filesystem/source/file_zip.h index 028731f28..8313c9eb2 100644 --- a/source/common/filesystem/file_zip.h +++ b/source/common/filesystem/source/file_zip.h @@ -3,6 +3,7 @@ #include "resourcefile.h" +namespace FileSys { //========================================================================== // // Zip Lump @@ -39,11 +40,12 @@ class FZipFile : public FResourceFile FZipLump *Lumps; public: - FZipFile(const char * filename, FileReader &file); + FZipFile(const char * filename, FileReader &file, StringPool* sp); virtual ~FZipFile(); bool Open(LumpFilterInfo* filter, FileSystemMessageFunc Printf); virtual FResourceLump *GetLump(int no) { return ((unsigned)no < NumLumps)? &Lumps[no] : NULL; } }; +} #endif \ No newline at end of file diff --git a/source/common/filesystem/files.cpp b/source/common/filesystem/source/files.cpp similarity index 97% rename from source/common/filesystem/files.cpp rename to source/common/filesystem/source/files.cpp index 8865b7111..5cb1bd343 100644 --- a/source/common/filesystem/files.cpp +++ b/source/common/filesystem/source/files.cpp @@ -34,10 +34,10 @@ */ #include -#include "files.h" - -using namespace fs_private; +#include "files_internal.h" +namespace FileSys { + #ifdef _WIN32 std::wstring toWide(const char* str); #endif @@ -345,7 +345,7 @@ public: void UpdateBuffer() { - bufptr = (const char*)&buf[0]; + bufptr = (const char*)buf.data(); FilePos = 0; Length = (long)buf.size(); } @@ -476,12 +476,14 @@ long FileWriter::Seek(long offset, int mode) size_t FileWriter::Printf(const char *fmt, ...) { + char c[300]; va_list arglist; va_start(arglist, fmt); - auto n = snprintf(nullptr, 0, fmt, arglist); + auto n = vsnprintf(c, 300, fmt, arglist); std::string buf; buf.resize(n); - snprintf(&buf.front(), n, fmt, arglist); + va_start(arglist, fmt); + vsnprintf(&buf.front(), n, fmt, arglist); va_end(arglist); return Write(buf.c_str(), n); } @@ -492,3 +494,5 @@ size_t BufferWriter::Write(const void *buffer, size_t len) memcpy(&mBuffer[ofs], buffer, len); return len; } + +} diff --git a/source/common/filesystem/files_decompress.cpp b/source/common/filesystem/source/files_decompress.cpp similarity index 96% rename from source/common/filesystem/files_decompress.cpp rename to source/common/filesystem/source/files_decompress.cpp index 8b8f4958a..86529716a 100644 --- a/source/common/filesystem/files_decompress.cpp +++ b/source/common/filesystem/source/files_decompress.cpp @@ -41,7 +41,30 @@ #include #include -#include "files.h" +#include "fs_files.h" + +namespace FileSys { + using namespace byteswap; + + +class DecompressorBase : public FileReaderInterface +{ + bool exceptions = false; +public: + // These do not work but need to be defined to satisfy the FileReaderInterface. + // They will just error out when called. + long Tell() const override; + long Seek(long offset, int origin) override; + char* Gets(char* strbuf, int len) override; + void DecompressionError(const char* error, ...) const; + void SetOwnsReader(); + void EnableExceptions(bool on) { exceptions = on; } + +protected: + FileReader* File = nullptr; + FileReader OwnedFile; +}; + //========================================================================== // @@ -538,7 +561,7 @@ class DecompressorLZSS : public DecompressorBase return false; Stream.AvailIn -= 2; - uint16_t pos = fs_private::BigShort(*(uint16_t*)Stream.In); + uint16_t pos = BigShort(*(uint16_t*)Stream.In); uint8_t len = (pos & 0xF)+1; pos >>= 4; Stream.In += 2; @@ -752,3 +775,4 @@ bool FileReader::OpenDecompressor(FileReader &parent, Size length, int method, b } } +} diff --git a/source/common/filesystem/source/files_internal.h b/source/common/filesystem/source/files_internal.h new file mode 100644 index 000000000..34e73a070 --- /dev/null +++ b/source/common/filesystem/source/files_internal.h @@ -0,0 +1,31 @@ +#pragma once + +#include "fs_files.h" + +namespace FileSys { + +class MemoryReader : public FileReaderInterface +{ +protected: + const char * bufptr = nullptr; + long FilePos = 0; + + MemoryReader() + {} + +public: + MemoryReader(const char *buffer, long length) + { + bufptr = buffer; + Length = length; + FilePos = 0; + } + + long Tell() const override; + long Seek(long offset, int origin) override; + long Read(void *buffer, long len) override; + char *Gets(char *strbuf, int len) override; + virtual const char *GetBuffer() const override { return bufptr; } +}; + +} diff --git a/source/common/filesystem/filesystem.cpp b/source/common/filesystem/source/filesystem.cpp similarity index 87% rename from source/common/filesystem/filesystem.cpp rename to source/common/filesystem/source/filesystem.cpp index e63049984..2344f09cc 100644 --- a/source/common/filesystem/filesystem.cpp +++ b/source/common/filesystem/source/filesystem.cpp @@ -41,10 +41,14 @@ #include #include -#include "filesystem.h" +#include "resourcefile_internal.h" +#include "fs_filesystem.h" #include "fs_findfile.h" #include "md5.hpp" +#include "fs_stringpool.h" +namespace FileSys { + // MACROS ------------------------------------------------------------------ #define NULL_INDEX (0xffffffff) @@ -59,15 +63,19 @@ static void UpperCopy(char* to, const char* from) to[i] = 0; } -static int MakeHash(const void* data, unsigned length = -1) + +//djb2 +static uint32_t MakeHash(const char* str, size_t length = SIZE_MAX) { - if (length == -1) length = (unsigned)strlen((const char*)data); - return crc32(0, (const Bytef*)data, length); + uint32_t hash = 5381; + uint32_t c; + while (length-- > 0 && (c = *str++)) hash = hash * 33 + (c | 32); + return hash; } static void md5Hash(FileReader& reader, uint8_t* digest) { - using namespace fs_private::md5; + using namespace md5; md5_state_t state; md5_init(&state); @@ -84,13 +92,13 @@ struct FileSystem::LumpRecord { FResourceLump *lump; LumpShortName shortName; - std::string longName; + const char* LongName; int rfnum; int Namespace; int resourceId; int flags; - void SetFromLump(int filenum, FResourceLump* lmp) + void SetFromLump(int filenum, FResourceLump* lmp, StringPool* sp) { lump = lmp; rfnum = filenum; @@ -100,73 +108,74 @@ struct FileSystem::LumpRecord { UpperCopy(shortName.String, lump->getName()); shortName.String[8] = 0; - longName = ""; + LongName = ""; Namespace = lump->GetNamespace(); resourceId = -1; } else if ((lump->Flags & LUMPF_EMBEDDED) || !lump->getName() || !*lump->getName()) { shortName.qword = 0; - longName = ""; + LongName = ""; Namespace = ns_hidden; resourceId = -1; } else { - longName = lump->getName(); + LongName = lump->getName(); resourceId = lump->GetIndexNum(); // Map some directories to WAD namespaces. // Note that some of these namespaces don't exist in WADS. // CheckNumForName will handle any request for these namespaces accordingly. - Namespace = !strncmp(longName.c_str(), "flats/", 6) ? ns_flats : - !strncmp(longName.c_str(), "textures/", 9) ? ns_newtextures : - !strncmp(longName.c_str(), "hires/", 6) ? ns_hires : - !strncmp(longName.c_str(), "sprites/", 8) ? ns_sprites : - !strncmp(longName.c_str(), "voxels/", 7) ? ns_voxels : - !strncmp(longName.c_str(), "colormaps/", 10) ? ns_colormaps : - !strncmp(longName.c_str(), "acs/", 4) ? ns_acslibrary : - !strncmp(longName.c_str(), "voices/", 7) ? ns_strifevoices : - !strncmp(longName.c_str(), "patches/", 8) ? ns_patches : - !strncmp(longName.c_str(), "graphics/", 9) ? ns_graphics : - !strncmp(longName.c_str(), "sounds/", 7) ? ns_sounds : - !strncmp(longName.c_str(), "music/", 6) ? ns_music : - !strchr(longName.c_str(), '/') ? ns_global : + Namespace = !strncmp(LongName, "flats/", 6) ? ns_flats : + !strncmp(LongName, "textures/", 9) ? ns_newtextures : + !strncmp(LongName, "hires/", 6) ? ns_hires : + !strncmp(LongName, "sprites/", 8) ? ns_sprites : + !strncmp(LongName, "voxels/", 7) ? ns_voxels : + !strncmp(LongName, "colormaps/", 10) ? ns_colormaps : + !strncmp(LongName, "acs/", 4) ? ns_acslibrary : + !strncmp(LongName, "voices/", 7) ? ns_strifevoices : + !strncmp(LongName, "patches/", 8) ? ns_patches : + !strncmp(LongName, "graphics/", 9) ? ns_graphics : + !strncmp(LongName, "sounds/", 7) ? ns_sounds : + !strncmp(LongName, "music/", 6) ? ns_music : + !strchr(LongName, '/') ? ns_global : ns_hidden; if (Namespace == ns_hidden) shortName.qword = 0; - else + else if (strstr(LongName, ".{")) { + std::string longName = LongName; ptrdiff_t encodedResID = longName.find_last_of(".{"); if (resourceId == -1 && encodedResID != std::string::npos) { - const char* p = longName.c_str() + encodedResID; + const char* p = LongName + encodedResID; char* q; - int id = (int)strtoull(p+2, &q, 10); // only decimal numbers allowed here. + int id = (int)strtoull(p + 2, &q, 10); // only decimal numbers allowed here. if (q[0] == '}' && (q[1] == '.' || q[1] == 0)) { longName.erase(longName.begin() + encodedResID, longName.begin() + (q - p) + 1); resourceId = id; } + LongName = sp->Strdup(longName.c_str()); } - ptrdiff_t slash = longName.find_last_of('/'); - std::string base = (slash != std::string::npos) ? longName.c_str() + (slash + 1) : longName.c_str(); - auto dot = base.find_last_of('.'); - if (dot != std::string::npos) base.resize(dot); - UpperCopy(shortName.String, base.c_str()); - shortName.String[8] = 0; + } + auto slash = strrchr(LongName, '/'); + std::string base = slash ? (slash + 1) : LongName; + auto dot = base.find_last_of('.'); + if (dot != std::string::npos) base.resize(dot); + UpperCopy(shortName.String, base.c_str()); - // Since '\' can't be used as a file name's part inside a ZIP - // we have to work around this for sprites because it is a valid - // frame character. - if (Namespace == ns_sprites || Namespace == ns_voxels || Namespace == ns_hires) + // Since '\' can't be used as a file name's part inside a ZIP + // we have to work around this for sprites because it is a valid + // frame character. + if (Namespace == ns_sprites || Namespace == ns_voxels || Namespace == ns_hires) + { + char* c; + + while ((c = (char*)memchr(shortName.String, '^', 8))) { - char* c; - - while ((c = (char*)memchr(shortName.String, '^', 8))) - { - *c = '\\'; - } + *c = '\\'; } } } @@ -181,13 +190,12 @@ static void PrintLastError (FileSystemMessageFunc Printf); // PUBLIC DATA DEFINITIONS ------------------------------------------------- -FileSystem fileSystem; - // CODE -------------------------------------------------------------------- FileSystem::FileSystem() { - // Cannot be defaulted! This is needed to initialize the LumpRecord array, which depends on data only available here. + stringpool = new StringPool; + stringpool->shared = true; // will be used by all owned resource files. } FileSystem::~FileSystem () @@ -287,7 +295,7 @@ bool FileSystem::InitMultipleFiles (std::vector& filenames, LumpFil void FileSystem::AddLump(FResourceLump *lump) { FileInfo.resize(FileInfo.size() + 1); - FileInfo.back().SetFromLump(-1, lump); + FileInfo.back().SetFromLump(-1, lump, stringpool); } //----------------------------------------------------------------------- @@ -300,7 +308,7 @@ void FileSystem::AddLump(FResourceLump *lump) int FileSystem::AddExternalFile(const char *filename) { - FResourceLump *lump = new FExternalLump(filename); + FResourceLump *lump = new FExternalLump(filename, -1, stringpool); AddLump(lump); return (int)FileInfo.size() - 1; // later } @@ -313,13 +321,24 @@ int FileSystem::AddExternalFile(const char *filename) // //========================================================================== +struct FMemoryLump : public FResourceLump +{ + FMemoryLump(const void* data, int length) + { + RefCount = -1; + LumpSize = length; + Cache = new char[length]; + memcpy(Cache, data, length); + } +}; + int FileSystem::AddFromBuffer(const char* name, const char* type, char* data, int size, int id, int flags) { std::string fullname = name; - fullname += ':'; + fullname += '.'; fullname += type; auto newlump = new FMemoryLump(data, size); - newlump->LumpNameSetup(fullname.c_str()); + newlump->LumpNameSetup(fullname.c_str(), stringpool); AddLump(newlump); FileInfo.back().resourceId = id; return (int)FileInfo.size()-1; @@ -375,9 +394,9 @@ void FileSystem::AddFile (const char *filename, FileReader *filer, LumpFilterInf if (!isdir) - resfile = FResourceFile::OpenResourceFile(filename, filereader, false, filter, Printf); + resfile = FResourceFile::OpenResourceFile(filename, filereader, false, filter, Printf, stringpool); else - resfile = FResourceFile::OpenDirectory(filename, filter, Printf); + resfile = FResourceFile::OpenDirectory(filename, filter, Printf, stringpool); if (resfile != NULL) { @@ -391,8 +410,8 @@ void FileSystem::AddFile (const char *filename, FileReader *filer, LumpFilterInf { FResourceLump *lump = resfile->GetLump(i); FileInfo.resize(FileInfo.size() + 1); - FileSystem::LumpRecord *lump_p = &FileInfo.back(); - lump_p->SetFromLump((int)Files.size(), lump); + FileSystem::LumpRecord* lump_p = &FileInfo.back(); + lump_p->SetFromLump((int)Files.size(), lump, stringpool); } Files.push_back(resfile); @@ -504,7 +523,7 @@ int FileSystem::CheckIfResourceFileLoaded (const char *name) noexcept // and namespace parameter //========================================================================== -int FileSystem::CheckNumForName (const char *name, int space) +int FileSystem::CheckNumForName (const char *name, int space) const { union { @@ -549,7 +568,7 @@ int FileSystem::CheckNumForName (const char *name, int space) return i != NULL_INDEX ? i : -1; } -int FileSystem::CheckNumForName (const char *name, int space, int rfnum, bool exact) +int FileSystem::CheckNumForName (const char *name, int space, int rfnum, bool exact) const { union { @@ -587,7 +606,7 @@ int FileSystem::CheckNumForName (const char *name, int space, int rfnum, bool ex // //========================================================================== -int FileSystem::GetNumForName (const char *name, int space) +int FileSystem::GetNumForName (const char *name, int space) const { int i; @@ -610,7 +629,7 @@ int FileSystem::GetNumForName (const char *name, int space) // //========================================================================== -int FileSystem::CheckNumForFullName (const char *name, bool trynormal, int namespc, bool ignoreext) +int FileSystem::CheckNumForFullName (const char *name, bool trynormal, int namespc, bool ignoreext) const { uint32_t i; @@ -625,12 +644,12 @@ int FileSystem::CheckNumForFullName (const char *name, bool trynormal, int names for (i = fli[MakeHash(name) % NumEntries]; i != NULL_INDEX; i = nli[i]) { - if (strnicmp(name, FileInfo[i].longName.c_str(), len)) continue; - if (FileInfo[i].longName[len] == 0) break; // this is a full match - if (ignoreext && FileInfo[i].longName[len] == '.') + if (strnicmp(name, FileInfo[i].LongName, len)) continue; + if (FileInfo[i].LongName[len] == 0) break; // this is a full match + if (ignoreext && FileInfo[i].LongName[len] == '.') { // is this the last '.' in the last path element, indicating that the remaining part of the name is only an extension? - if (strpbrk(FileInfo[i].longName.c_str() + len + 1, "./") == nullptr) break; + if (strpbrk(FileInfo[i].LongName + len + 1, "./") == nullptr) break; } } @@ -643,7 +662,7 @@ int FileSystem::CheckNumForFullName (const char *name, bool trynormal, int names return -1; } -int FileSystem::CheckNumForFullName (const char *name, int rfnum) +int FileSystem::CheckNumForFullName (const char *name, int rfnum) const { uint32_t i; @@ -655,7 +674,7 @@ int FileSystem::CheckNumForFullName (const char *name, int rfnum) i = FirstLumpIndex_FullName[MakeHash (name) % NumEntries]; while (i != NULL_INDEX && - (stricmp(name, FileInfo[i].longName.c_str()) || FileInfo[i].rfnum != rfnum)) + (stricmp(name, FileInfo[i].LongName) || FileInfo[i].rfnum != rfnum)) { i = NextLumpIndex_FullName[i]; } @@ -671,7 +690,7 @@ int FileSystem::CheckNumForFullName (const char *name, int rfnum) // //========================================================================== -int FileSystem::GetNumForFullName (const char *name) +int FileSystem::GetNumForFullName (const char *name) const { int i; @@ -691,7 +710,7 @@ int FileSystem::GetNumForFullName (const char *name) // //========================================================================== -int FileSystem::FindFileWithExtensions(const char* name, const char *const *exts, int count) +int FileSystem::FindFileWithExtensions(const char* name, const char *const *exts, int count) const { uint32_t i; @@ -706,10 +725,10 @@ int FileSystem::FindFileWithExtensions(const char* name, const char *const *exts for (i = fli[MakeHash(name) % NumEntries]; i != NULL_INDEX; i = nli[i]) { - if (strnicmp(name, FileInfo[i].longName.c_str(), len)) continue; - if (FileInfo[i].longName[len] != '.') continue; // we are looking for extensions but this file doesn't have one. + if (strnicmp(name, FileInfo[i].LongName, len)) continue; + if (FileInfo[i].LongName[len] != '.') continue; // we are looking for extensions but this file doesn't have one. - auto cp = FileInfo[i].longName.c_str() + len + 1; + auto cp = FileInfo[i].LongName + len + 1; // is this the last '.' in the last path element, indicating that the remaining part of the name is only an extension? if (strpbrk(cp, "./") != nullptr) continue; // No, so it cannot be a valid entry. @@ -745,7 +764,7 @@ int FileSystem::FindResource (int resid, const char *type, int filenum) const no { if (filenum > 0 && FileInfo[i].rfnum != filenum) continue; if (FileInfo[i].resourceId != resid) continue; - auto extp = strrchr(FileInfo[i].longName.c_str(), '.'); + auto extp = strrchr(FileInfo[i].LongName, '.'); if (!extp) continue; if (!stricmp(extp + 1, type)) return i; } @@ -859,13 +878,13 @@ void FileSystem::InitHashChains (void) FirstLumpIndex[j] = i; // Do the same for the full paths - if (!FileInfo[i].longName.empty()) + if (FileInfo[i].LongName[0] != 0) { - j = MakeHash(FileInfo[i].longName.c_str()) % NumEntries; + j = MakeHash(FileInfo[i].LongName) % NumEntries; NextLumpIndex_FullName[i] = FirstLumpIndex_FullName[j]; FirstLumpIndex_FullName[j] = i; - auto nameNoExt = FileInfo[i].longName; + std::string nameNoExt = FileInfo[i].LongName; auto dot = nameNoExt.find_last_of('.'); auto slash = nameNoExt.find_last_of('/'); if ((dot > slash || slash == std::string::npos) && dot != std::string::npos) nameNoExt.resize(dot); @@ -900,7 +919,7 @@ LumpShortName& FileSystem::GetShortName(int i) void FileSystem::RenameFile(int num, const char* newfn) { if ((unsigned)num >= NumEntries) throw FileSystemException("RenameFile: Invalid index"); - FileInfo[num].longName = newfn; + FileInfo[num].LongName = stringpool->Strdup(newfn); // This does not alter the short name - call GetShortname to do that! } @@ -934,13 +953,13 @@ void FileSystem::MoveLumpsInFolder(const char *path) { auto& li = FileInfo[i]; if (li.rfnum >= GetIwadNum()) break; - if (strnicmp(li.longName.c_str(), path, len) == 0) + if (strnicmp(li.LongName, path, len) == 0) { FileInfo.push_back(li); li.lump = &placeholderLump; // Make the old entry point to something empty. We cannot delete the lump record here because it'd require adjustment of all indices in the list. auto &ln = FileInfo.back(); - ln.lump->LumpNameSetup(ln.longName.c_str() + len); - ln.SetFromLump(rfnum, ln.lump); + ln.lump->LumpNameSetup(ln.LongName + len, stringpool); // may be able to avoid the string allocation! + ln.SetFromLump(rfnum, ln.lump, stringpool); } } } @@ -956,6 +975,7 @@ void FileSystem::MoveLumpsInFolder(const char *path) int FileSystem::FindLump (const char *name, int *lastlump, bool anyns) { + if (*lastlump >= FileInfo.size()) return -1; union { char name8[8]; @@ -967,11 +987,11 @@ int FileSystem::FindLump (const char *name, int *lastlump, bool anyns) assert(lastlump != NULL && *lastlump >= 0); lump_p = &FileInfo[*lastlump]; - while (lump_p < &FileInfo[NumEntries]) + while (lump_p <= &FileInfo.back()) { if ((anyns || lump_p->Namespace == ns_global) && lump_p->shortName.qword == qname) { - int lump = int(lump_p - &FileInfo[0]); + int lump = int(lump_p - FileInfo.data()); *lastlump = lump + 1; return lump; } @@ -997,7 +1017,7 @@ int FileSystem::FindLumpMulti (const char **names, int *lastlump, bool anyns, in assert(lastlump != NULL && *lastlump >= 0); lump_p = &FileInfo[*lastlump]; - while (lump_p < &FileInfo[NumEntries]) + while (lump_p <= &FileInfo.back()) { if (anyns || lump_p->Namespace == ns_global) { @@ -1006,7 +1026,7 @@ int FileSystem::FindLumpMulti (const char **names, int *lastlump, bool anyns, in { if (!strnicmp(*name, lump_p->shortName.String, 8)) { - int lump = int(lump_p - &FileInfo[0]); + int lump = int(lump_p - FileInfo.data()); *lastlump = lump + 1; if (nameindex != NULL) *nameindex = int(name - names); return lump; @@ -1036,11 +1056,11 @@ int FileSystem::FindLumpFullName(const char* name, int* lastlump, bool noext) if (!noext) { - while (lump_p < &FileInfo[NumEntries]) + while (lump_p <= &FileInfo.back()) { - if (!stricmp(name, lump_p->longName.c_str())) + if (!stricmp(name, lump_p->LongName)) { - int lump = int(lump_p - &FileInfo[0]); + int lump = int(lump_p - FileInfo.data()); *lastlump = lump + 1; return lump; } @@ -1050,15 +1070,15 @@ int FileSystem::FindLumpFullName(const char* name, int* lastlump, bool noext) else { auto len = strlen(name); - while (lump_p < &FileInfo[NumEntries]) + while (lump_p <= &FileInfo.back()) { - auto res = strnicmp(name, lump_p->longName.c_str(), len); + auto res = strnicmp(name, lump_p->LongName, len); if (res == 0) { - auto p = lump_p->longName.c_str() + len; + auto p = lump_p->LongName + len; if (*p == 0 || (*p == '.' && strpbrk(p + 1, "./") == 0)) { - int lump = int(lump_p - &FileInfo[0]); + int lump = int(lump_p - FileInfo.data()); *lastlump = lump + 1; return lump; } @@ -1112,8 +1132,8 @@ const char *FileSystem::GetFileFullName (int lump, bool returnshort) const { if ((size_t)lump >= NumEntries) return NULL; - else if (!FileInfo[lump].longName.empty()) - return FileInfo[lump].longName.c_str(); + else if (FileInfo[lump].LongName[0] != 0) + return FileInfo[lump].LongName; else if (returnshort) return FileInfo[lump].shortName.String; else return nullptr; @@ -1191,7 +1211,7 @@ const char *FileSystem::GetResourceType(int lump) const return nullptr; else { - auto p = strrchr(FileInfo[lump].longName.c_str(), '.'); + auto p = strrchr(FileInfo[lump].LongName, '.'); if (!p) return ""; // has no extension if (strchr(p, '/')) return ""; // the '.' is part of a directory. return p + 1; @@ -1243,12 +1263,12 @@ unsigned FileSystem::GetFilesInFolder(const char *inpath, std::vector maxfile) maxfile = thisfile; } // Delete everything from older files. for (int i = (int)result.size() - 1; i >= 0; i--) { - if (fileSystem.GetFileContainer(result[i].lumpnum) != maxfile) result.erase(result.begin() + i); + if (GetFileContainer(result[i].lumpnum) != maxfile) result.erase(result.begin() + i); } } qsort(result.data(), result.size(), sizeof(FolderEntry), folderentrycmp); @@ -1292,7 +1312,7 @@ void FileSystem::ReadFile (int lump, void *dest) if (numread != size) { throw FileSystemException("W_ReadFile: only read %ld of %ld on '%s'\n", - numread, size, FileInfo[lump].longName.c_str()); + numread, size, FileInfo[lump].LongName); } } @@ -1356,8 +1376,8 @@ FileReader FileSystem::ReopenFileReader(int lump, bool alwayscache) if (rl->RefCount == 0 && rd != nullptr && !rd->GetBuffer() && !alwayscache && !(rl->Flags & LUMPF_COMPRESSED)) { - int fileno = fileSystem.GetFileContainer(lump); - const char *filename = fileSystem.GetResourceFileFullName(fileno); + int fileno = GetFileContainer(lump); + const char *filename = GetResourceFileFullName(fileno); FileReader fr; if (fr.OpenFile(filename, rl->GetFileOffset(), rl->LumpSize)) { @@ -1410,7 +1430,7 @@ const char *FileSystem::GetResourceFileName (int rfnum) const noexcept return NULL; } - name = Files[rfnum]->FileName.c_str(); + name = Files[rfnum]->FileName; slash = strrchr (name, '/'); return (slash != nullptr && slash[1] != 0) ? slash+1 : name; } @@ -1476,7 +1496,7 @@ const char *FileSystem::GetResourceFileFullName (int rfnum) const noexcept return nullptr; } - return Files[rfnum]->FileName.c_str(); + return Files[rfnum]->FileName; } @@ -1496,9 +1516,9 @@ bool FileSystem::CreatePathlessCopy(const char *name, int id, int /*flags*/) if (lump < 0) return false; // Does not exist. auto oldlump = FileInfo[lump]; - ptrdiff_t slash = oldlump.longName.find_last_of('/'); + auto slash = strrchr(oldlump.LongName, '/'); - if (slash == std::string::npos) + if (slash == nullptr) { FileInfo[lump].flags = LUMPF_FULLPATH; return true; // already is pathless. @@ -1506,7 +1526,7 @@ bool FileSystem::CreatePathlessCopy(const char *name, int id, int /*flags*/) // just create a new reference to the original data with a different name. - oldlump.longName.erase(oldlump.longName.begin(), oldlump.longName.begin() + (slash + 1)); + oldlump.LongName = slash + 1; oldlump.resourceId = id; oldlump.flags = LUMPF_FULLPATH; FileInfo.push_back(oldlump); @@ -1571,3 +1591,5 @@ FResourceLump* FileSystem::GetFileAt(int no) { return FileInfo[no].lump; } + +} diff --git a/source/common/filesystem/fs_findfile.cpp b/source/common/filesystem/source/fs_findfile.cpp similarity index 92% rename from source/common/filesystem/fs_findfile.cpp rename to source/common/filesystem/source/fs_findfile.cpp index d570c2432..689a5d644 100644 --- a/source/common/filesystem/fs_findfile.cpp +++ b/source/common/filesystem/source/fs_findfile.cpp @@ -33,9 +33,11 @@ */ #include "fs_findfile.h" +#include #include - +namespace FileSys { + enum { ZPATH_MAX = 260 @@ -61,6 +63,8 @@ enum #ifndef _WIN32 +#include +#include #include #include #include @@ -163,7 +167,7 @@ static int FS_FindAttr(findstate_t *const fileinfo) const std::string path = fileinfo->path + ent->d_name; bool isdir; - if (DirEntryExists(path.c_str(), &isdir)) + if (FS_DirEntryExists(path.c_str(), &isdir)) { return isdir ? FA_DIREC : 0; } @@ -173,8 +177,12 @@ static int FS_FindAttr(findstate_t *const fileinfo) std::string FS_FullPath(const char* directory) { - // todo - return directory + char fullpath[PATH_MAX]; + + if (realpath(directory, fullpath) != nullptr) + return fullpath; + + return directory; } static size_t FS_GetFileSize(findstate_t* handle, const char* pathname) @@ -303,7 +311,7 @@ std::string FS_FullPath(const char* directory) static size_t FS_GetFileSize(findstate_t* handle, const char* pathname) { - return handle->FindData.Size[0] + ((uint64_t)handle->FindData.Size[1] << 32); + return handle->FindData.Size[1] + ((uint64_t)handle->FindData.Size[0] << 32); } #endif @@ -315,7 +323,7 @@ static size_t FS_GetFileSize(findstate_t* handle, const char* pathname) // //========================================================================== -static bool ScanDirectory(FileList& list, const char* dirpath, const char* match, const char* relpath, bool nosubdir, bool readhidden) +static bool DoScanDirectory(FileList& list, const char* dirpath, const char* match, const char* relpath, bool nosubdir, bool readhidden) { findstate_t find; @@ -323,7 +331,7 @@ static bool ScanDirectory(FileList& list, const char* dirpath, const char* match FixPathSeparator(&dirpathn.front()); if (dirpathn[dirpathn.length() - 1] != '/') dirpathn += '/'; - std::string dirmatch = dirpath; + std::string dirmatch = dirpathn; dirmatch += match; auto handle = FS_FindFirst(dirmatch.c_str(), &find); @@ -353,7 +361,7 @@ static bool ScanDirectory(FileList& list, const char* dirpath, const char* match fl.FileName = fn; fl.FilePath = dirpathn + fn; fl.FilePathRel = relpath; - fl.FilePathRel += '/'; + if (fl.FilePathRel.length() > 0) fl.FilePathRel += '/'; fl.FilePathRel += fn; fl.isDirectory = !!(attr & FA_DIREC); fl.isReadonly = !!(attr & FA_RDONLY); @@ -363,8 +371,7 @@ static bool ScanDirectory(FileList& list, const char* dirpath, const char* match list.push_back(fl); if (!nosubdir && (attr & FA_DIREC)) { - std::string rel = relpath + '/' + fl.FileName; - ScanDirectory(list, fl.FilePath.c_str(), match); + DoScanDirectory(list, fl.FilePath.c_str(), match, fl.FilePathRel.c_str(), false, readhidden); fl.Length = 0; } } while (FS_FindNext(handle, &find) == 0); @@ -375,7 +382,7 @@ static bool ScanDirectory(FileList& list, const char* dirpath, const char* match bool ScanDirectory(std::vector& list, const char* dirpath, const char* match, bool nosubdir, bool readhidden) { - return ScanDirectory(list, dirpath, match, "", nosubdir, readhidden); + return DoScanDirectory(list, dirpath, match, "", nosubdir, readhidden); } //========================================================================== @@ -405,3 +412,4 @@ bool FS_DirEntryExists(const char* pathname, bool* isdir) return res; } +} diff --git a/source/common/filesystem/source/fs_stringpool.cpp b/source/common/filesystem/source/fs_stringpool.cpp new file mode 100644 index 000000000..1e4231139 --- /dev/null +++ b/source/common/filesystem/source/fs_stringpool.cpp @@ -0,0 +1,130 @@ +/* +** stringpool.cpp +** allocate static strings from larger blocks +** +**--------------------------------------------------------------------------- +** Copyright 2010 Randy Heit +** Copyright 2023 Christoph Oelckers +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**--------------------------------------------------------------------------- +** +*/ + +#include +#include +#include +#include "fs_stringpool.h" + +namespace FileSys { + +struct StringPool::Block +{ + Block *NextBlock; + void *Limit; // End of this block + void *Avail; // Start of free space in this block + void *alignme; // align to 16 bytes. + + void *Alloc(size_t size); +}; + +//========================================================================== +// +// StringPool Destructor +// +//========================================================================== + +StringPool::~StringPool() +{ + for (Block *next, *block = TopBlock; block != nullptr; block = next) + { + next = block->NextBlock; + free(block); + } + TopBlock = nullptr; +} + +//========================================================================== +// +// StringPool :: Alloc +// +//========================================================================== + +void *StringPool::Block::Alloc(size_t size) +{ + if ((char *)Avail + size > Limit) + { + return nullptr; + } + void *res = Avail; + Avail = ((char *)Avail + size); + return res; +} + +StringPool::Block *StringPool::AddBlock(size_t size) +{ + size += sizeof(Block); // Account for header size + + // Allocate a new block + if (size < BlockSize) + { + size = BlockSize; + } + auto mem = (Block *)malloc(size); + if (mem == nullptr) + { + + } + mem->Limit = (uint8_t *)mem + size; + mem->Avail = &mem[1]; + mem->NextBlock = TopBlock; + TopBlock = mem; + return mem; +} + +void *StringPool::iAlloc(size_t size) +{ + Block *block; + + for (block = TopBlock; block != nullptr; block = block->NextBlock) + { + void *res = block->Alloc(size); + if (res != nullptr) + { + return res; + } + } + block = AddBlock(size); + return block->Alloc(size); +} + +const char* StringPool::Strdup(const char* str) +{ + char* p = (char*)iAlloc((strlen(str) + 8) & ~7 ); + strcpy(p, str); + return p; +} + +} diff --git a/source/common/filesystem/source/fs_stringpool.h b/source/common/filesystem/source/fs_stringpool.h new file mode 100644 index 000000000..f72a180df --- /dev/null +++ b/source/common/filesystem/source/fs_stringpool.h @@ -0,0 +1,29 @@ +#pragma once + +namespace FileSys { +// Storage for all the static strings the file system must hold. +class StringPool +{ + // do not allow externally defining this. + friend class FileSystem; + friend class FResourceFile; +private: + StringPool(size_t blocksize = 10*1024) : TopBlock(nullptr), FreeBlocks(nullptr), BlockSize(blocksize) {} +public: + ~StringPool(); + const char* Strdup(const char*); + +protected: + struct Block; + + Block *AddBlock(size_t size); + void *iAlloc(size_t size); + + Block *TopBlock; + Block *FreeBlocks; + size_t BlockSize; +public: + bool shared; +}; + +} diff --git a/source/common/filesystem/md5.hpp b/source/common/filesystem/source/md5.hpp similarity index 99% rename from source/common/filesystem/md5.hpp rename to source/common/filesystem/source/md5.hpp index 2027023ca..1ecde05d4 100644 --- a/source/common/filesystem/md5.hpp +++ b/source/common/filesystem/source/md5.hpp @@ -69,7 +69,7 @@ #include #include -namespace fs_private { +namespace FileSys { /// Provides MD5 hashing functionality namespace md5 { diff --git a/source/common/filesystem/resourcefile.cpp b/source/common/filesystem/source/resourcefile.cpp similarity index 87% rename from source/common/filesystem/resourcefile.cpp rename to source/common/filesystem/source/resourcefile.cpp index e987efee9..079998df9 100644 --- a/source/common/filesystem/resourcefile.cpp +++ b/source/common/filesystem/source/resourcefile.cpp @@ -35,9 +35,13 @@ */ #include -#include "resourcefile.h" +#include "resourcefile_internal.h" #include "md5.hpp" +#include "fs_stringpool.h" +#include "files_internal.h" +namespace FileSys { + std::string ExtractBaseName(const char* path, bool include_extension) { const char* src, * dot; @@ -122,13 +126,17 @@ FResourceLump::~FResourceLump() // //========================================================================== -void FResourceLump::LumpNameSetup(const char *iname) +void FResourceLump::LumpNameSetup(const char *iname, StringPool* allocator) { // this causes interference with real Dehacked lumps. if (!stricmp(iname, "dehacked.exe")) { iname = ""; } + else if (allocator) + { + iname = allocator->Strdup(iname); + } FullName = iname; } @@ -149,7 +157,7 @@ static bool IsWadInFolder(const FResourceFile* const archive, const char* const return false; } - const auto dirName = ExtractBaseName(archive->FileName.c_str()); + const auto dirName = ExtractBaseName(archive->FileName); const auto fileName = ExtractBaseName(resPath, true); const std::string filePath = dirName + '/' + fileName; @@ -159,14 +167,14 @@ static bool IsWadInFolder(const FResourceFile* const archive, const char* const void FResourceLump::CheckEmbedded(LumpFilterInfo* lfi) { // Checks for embedded archives - const char *c = strstr(FullName.c_str(), ".wad"); - if (c && strlen(c) == 4 && (!strchr(FullName.c_str(), '/') || IsWadInFolder(Owner, FullName.c_str()))) + const char *c = strstr(FullName, ".wad"); + if (c && strlen(c) == 4 && (!strchr(FullName, '/') || IsWadInFolder(Owner, FullName))) { Flags |= LUMPF_EMBEDDED; } else if (lfi) for (auto& fstr : lfi->embeddings) { - if (!stricmp(FullName.c_str(), fstr.c_str())) + if (!stricmp(FullName, fstr.c_str())) { Flags |= LUMPF_EMBEDDED; } @@ -234,7 +242,7 @@ void *FResourceLump::Lock() catch (const FileSystemException& err) { // enrich the message with info about this lump. - throw FileSystemException("%s, file '%s': %s", getName(), Owner->FileName.c_str(), err.what()); + throw FileSystemException("%s, file '%s': %s", getName(), Owner->FileName, err.what()); } } return Cache; @@ -265,18 +273,18 @@ int FResourceLump::Unlock() // //========================================================================== -typedef FResourceFile * (*CheckFunc)(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf); +typedef FResourceFile * (*CheckFunc)(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf, StringPool* sp); -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); +FResourceFile *CheckWad(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf, StringPool* sp); +FResourceFile *CheckGRP(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf, StringPool* sp); +FResourceFile *CheckRFF(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf, StringPool* sp); +FResourceFile *CheckPak(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf, StringPool* sp); +FResourceFile *CheckZip(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf, StringPool* sp); +FResourceFile *Check7Z(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf, StringPool* sp); +FResourceFile* CheckSSI(const char* filename, FileReader& file, LumpFilterInfo* filter, FileSystemMessageFunc Printf, StringPool* sp); +FResourceFile* CheckWHRes(const char* filename, FileReader& file, LumpFilterInfo* filter, FileSystemMessageFunc Printf, StringPool* sp); +FResourceFile *CheckLump(const char *filename,FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf, StringPool* sp); +FResourceFile *CheckDir(const char *filename, bool nosub, LumpFilterInfo* filter, FileSystemMessageFunc Printf, StringPool* sp); static CheckFunc funcs[] = { CheckWad, CheckZip, Check7Z, CheckPak, CheckGRP, CheckRFF, CheckSSI, CheckWHRes, CheckLump }; @@ -285,35 +293,35 @@ static int nulPrintf(FSMessageLevel msg, const char* fmt, ...) return 0; } -FResourceFile *FResourceFile::DoOpenResourceFile(const char *filename, FileReader &file, bool containeronly, LumpFilterInfo* filter, FileSystemMessageFunc Printf) +FResourceFile *FResourceFile::DoOpenResourceFile(const char *filename, FileReader &file, bool containeronly, LumpFilterInfo* filter, FileSystemMessageFunc Printf, StringPool* sp) { if (Printf == nullptr) Printf = nulPrintf; for(auto func : funcs) { if (containeronly && func == CheckLump) break; - FResourceFile *resfile = func(filename, file, filter, Printf); + FResourceFile *resfile = func(filename, file, filter, Printf, sp); if (resfile != NULL) return resfile; } return NULL; } -FResourceFile *FResourceFile::OpenResourceFile(const char *filename, FileReader &file, bool containeronly, LumpFilterInfo* filter, FileSystemMessageFunc Printf) +FResourceFile *FResourceFile::OpenResourceFile(const char *filename, FileReader &file, bool containeronly, LumpFilterInfo* filter, FileSystemMessageFunc Printf, StringPool* sp) { - return DoOpenResourceFile(filename, file, containeronly, filter, Printf); + return DoOpenResourceFile(filename, file, containeronly, filter, Printf, sp); } -FResourceFile *FResourceFile::OpenResourceFile(const char *filename, bool containeronly, LumpFilterInfo* filter, FileSystemMessageFunc Printf) +FResourceFile *FResourceFile::OpenResourceFile(const char *filename, bool containeronly, LumpFilterInfo* filter, FileSystemMessageFunc Printf, StringPool* sp) { FileReader file; if (!file.OpenFile(filename)) return nullptr; - return DoOpenResourceFile(filename, file, containeronly, filter, Printf); + return DoOpenResourceFile(filename, file, containeronly, filter, Printf, sp); } -FResourceFile *FResourceFile::OpenDirectory(const char *filename, LumpFilterInfo* filter, FileSystemMessageFunc Printf) +FResourceFile *FResourceFile::OpenDirectory(const char *filename, LumpFilterInfo* filter, FileSystemMessageFunc Printf, StringPool* sp) { if (Printf == nullptr) Printf = nulPrintf; - return CheckDir(filename, false, filter, Printf); + return CheckDir(filename, false, filter, Printf, sp); } //========================================================================== @@ -322,19 +330,21 @@ FResourceFile *FResourceFile::OpenDirectory(const char *filename, LumpFilterInfo // //========================================================================== -FResourceFile::FResourceFile(const char *filename) - : FileName(filename) +FResourceFile::FResourceFile(const char *filename, StringPool* sp) { + stringpool = sp ? sp : new StringPool; + FileName = stringpool->Strdup(filename); } -FResourceFile::FResourceFile(const char *filename, FileReader &r) - : FResourceFile(filename) +FResourceFile::FResourceFile(const char *filename, FileReader &r, StringPool* sp) + : FResourceFile(filename,sp) { Reader = std::move(r); } FResourceFile::~FResourceFile() { + if (!stringpool->shared) delete stringpool; } int lumpcmp(const void * a, const void * b) @@ -357,7 +367,7 @@ int lumpcmp(const void * a, const void * b) void FResourceFile::GenerateHash() { // hash the lump directory after sorting - using namespace fs_private::md5; + using namespace FileSys::md5; auto n = snprintf(Hash, 48, "%08X-%04X-", (unsigned)Reader.GetLength(), NumLumps); @@ -368,7 +378,7 @@ void FResourceFile::GenerateHash() for(uint32_t i = 0; i < NumLumps; i++) { auto lump = GetLump(i); - md5_append(&state, (const uint8_t*)lump->FullName.c_str(), (unsigned)lump->FullName.length() + 1); + md5_append(&state, (const uint8_t*)lump->FullName, (unsigned)strlen(lump->FullName) + 1); md5_append(&state, (const uint8_t*)&lump->LumpSize, 4); } md5_finish(&state, digest); @@ -438,7 +448,7 @@ int FResourceFile::FilterLumps(const std::string& filtername, void *lumps, size_ bool found = FindPrefixRange(filter.c_str(), lumps, lumpsize, max, start, end); // Workaround for old Doom filter names (todo: move out of here.) - if (!found && filtername.find_first_of("doom.id.doom") == 0) + if (!found && filtername.find("doom.id.doom") == 0) { strReplace(filter, "doom.id.doom", "doom.doom"); found = FindPrefixRange(filter.c_str(), lumps, lumpsize, max, start, end); @@ -453,8 +463,8 @@ int FResourceFile::FilterLumps(const std::string& filtername, void *lumps, size_ for (uint32_t i = start; i < end; ++i, lump_p = (uint8_t *)lump_p + lumpsize) { FResourceLump *lump = (FResourceLump *)lump_p; - assert(strnicmp(lump->FullName.c_str(), filter.c_str(), filter.length()) == 0); - lump->LumpNameSetup(lump->FullName.c_str() + filter.length()); + assert(strnicmp(lump->FullName, filter.c_str(), filter.length()) == 0); + lump->LumpNameSetup(lump->FullName + filter.length(), nullptr); } // Move filtered lumps to the end of the lump list. @@ -523,7 +533,7 @@ void FResourceFile::JunkLeftoverFilters(void *lumps, size_t lumpsize, uint32_t m for (void *p = (uint8_t *)lumps + start * lumpsize; p < stop; p = (uint8_t *)p + lumpsize) { FResourceLump *lump = (FResourceLump *)p; - lump->FullName = ""; + lump->clearName(); } } } @@ -556,7 +566,7 @@ bool FResourceFile::FindPrefixRange(const char* filter, void *lumps, size_t lump { mid = min + (max - min) / 2; lump = (FResourceLump *)((uint8_t *)lumps + mid * lumpsize); - cmp = strnicmp(lump->FullName.c_str(), filter, (int)strlen(filter)); + cmp = strnicmp(lump->FullName, filter, (int)strlen(filter)); if (cmp == 0) break; else if (cmp < 0) @@ -576,7 +586,7 @@ bool FResourceFile::FindPrefixRange(const char* filter, void *lumps, size_t lump { mid = min + (max - min) / 2; lump = (FResourceLump *)((uint8_t *)lumps + mid * lumpsize); - cmp = strnicmp(lump->FullName.c_str(), filter, (int)strlen(filter)); + cmp = strnicmp(lump->FullName, filter, (int)strlen(filter)); // Go left on matches and right on misses. if (cmp == 0) max = mid - 1; @@ -591,7 +601,7 @@ bool FResourceFile::FindPrefixRange(const char* filter, void *lumps, size_t lump { mid = min + (max - min) / 2; lump = (FResourceLump *)((uint8_t *)lumps + mid * lumpsize); - cmp = strnicmp(lump->FullName.c_str(), filter, (int)strlen(filter)); + cmp = strnicmp(lump->FullName, filter, (int)strlen(filter)); // Go right on matches and left on misses. if (cmp == 0) min = mid + 1; @@ -613,7 +623,7 @@ FResourceLump *FResourceFile::FindLump(const char *name) for (unsigned i = 0; i < NumLumps; i++) { FResourceLump *lump = GetLump(i); - if (!stricmp(name, lump->FullName.c_str())) + if (!stricmp(name, lump->FullName)) { return lump; } @@ -670,12 +680,12 @@ int FUncompressedLump::FillCache() // //========================================================================== -FUncompressedFile::FUncompressedFile(const char *filename) -: FResourceFile(filename) +FUncompressedFile::FUncompressedFile(const char *filename, StringPool* sp) +: FResourceFile(filename, sp) {} -FUncompressedFile::FUncompressedFile(const char *filename, FileReader &r) - : FResourceFile(filename, r) +FUncompressedFile::FUncompressedFile(const char *filename, FileReader &r, StringPool* sp) + : FResourceFile(filename, r, sp) {} @@ -685,9 +695,10 @@ FUncompressedFile::FUncompressedFile(const char *filename, FileReader &r) // //========================================================================== -FExternalLump::FExternalLump(const char *_filename, int filesize) - : Filename(_filename) +FExternalLump::FExternalLump(const char *_filename, int filesize, StringPool* stringpool) { + FileName = stringpool->Strdup(_filename); + if (filesize == -1) { FileReader f; @@ -720,7 +731,7 @@ int FExternalLump::FillCache() Cache = new char[LumpSize]; FileReader f; - if (f.OpenFile(Filename.c_str())) + if (f.OpenFile(FileName)) { auto read = f.Read(Cache, LumpSize); if (read != LumpSize) @@ -737,4 +748,4 @@ int FExternalLump::FillCache() } - +} diff --git a/source/common/filesystem/source/resourcefile_internal.h b/source/common/filesystem/source/resourcefile_internal.h new file mode 100644 index 000000000..4371a7460 --- /dev/null +++ b/source/common/filesystem/source/resourcefile_internal.h @@ -0,0 +1,38 @@ +#pragma once + +#include "resourcefile.h" + +namespace FileSys { +struct FUncompressedLump : public FResourceLump +{ + int Position; + + virtual FileReader *GetReader(); + virtual int FillCache() override; + virtual int GetFileOffset() { return Position; } + +}; + +// Base class for uncompressed resource files (WAD, GRP, PAK and single lumps) +class FUncompressedFile : public FResourceFile +{ +protected: + TArray Lumps; + + FUncompressedFile(const char *filename, StringPool* sp); + FUncompressedFile(const char *filename, FileReader &r, StringPool* sp); + virtual FResourceLump *GetLump(int no) { return ((unsigned)no < NumLumps)? &Lumps[no] : NULL; } +}; + + +// should only be used internally. +struct FExternalLump : public FResourceLump +{ + const char* FileName; + + FExternalLump(const char *_filename, int filesize, StringPool* sp); + virtual int FillCache() override; + +}; + +} \ No newline at end of file diff --git a/source/common/filesystem/w_zip.h b/source/common/filesystem/source/w_zip.h similarity index 98% rename from source/common/filesystem/w_zip.h rename to source/common/filesystem/source/w_zip.h index c0905cd20..d26d7f003 100644 --- a/source/common/filesystem/w_zip.h +++ b/source/common/filesystem/source/w_zip.h @@ -7,6 +7,8 @@ #define FORCE_PACKED #endif +namespace FileSys { + #pragma pack(1) // FZipCentralInfo struct FZipEndOfCentralDirectory @@ -105,4 +107,5 @@ struct FZipLocalFileHeader // File header flags. #define ZF_ENCRYPTED 0x1 +} #endif diff --git a/source/common/fonts/font.cpp b/source/common/fonts/font.cpp index be02a8b59..1714d78b4 100644 --- a/source/common/fonts/font.cpp +++ b/source/common/fonts/font.cpp @@ -91,7 +91,7 @@ FFont::FFont (const char *name, const char *nametemplate, const char *filetempla // Read the font's configuration. // This will not be done for the default fonts, because they are not atomic and the default content does not need it. - std::vector folderdata; + std::vector folderdata; if (filetemplate != nullptr) { FStringf path("fonts/%s/", filetemplate); @@ -398,7 +398,7 @@ public: } }; -void FFont::ReadSheetFont(std::vector &folderdata, int width, int height, const DVector2 &Scale) +void FFont::ReadSheetFont(std::vector &folderdata, int width, int height, const DVector2 &Scale) { TMap charMap; int minchar = INT_MAX; diff --git a/source/common/fonts/hexfont.cpp b/source/common/fonts/hexfont.cpp index 643b44d4d..3fb02004b 100644 --- a/source/common/fonts/hexfont.cpp +++ b/source/common/fonts/hexfont.cpp @@ -58,7 +58,7 @@ struct HexDataSource // //========================================================================== - void ParseDefinition(FResourceLump* font) + void ParseDefinition(FileSys::FResourceLump* font) { FScanner sc; @@ -109,8 +109,8 @@ class FHexFontChar : public FImageSource public: FHexFontChar(uint8_t *sourcedata, int swidth, int width, int height); - PalettedPixels CreatePalettedPixels(int conversion) override; - int CopyPixels(FBitmap* bmp, int conversion); + PalettedPixels CreatePalettedPixels(int conversion, int frame = 0) override; + int CopyPixels(FBitmap* bmp, int conversion, int frame = 0); protected: int SourceWidth; @@ -144,7 +144,7 @@ FHexFontChar::FHexFontChar (uint8_t *sourcedata, int swidth, int width, int heig // //========================================================================== -PalettedPixels FHexFontChar::CreatePalettedPixels(int) +PalettedPixels FHexFontChar::CreatePalettedPixels(int, int) { int destSize = Width * Height; PalettedPixels Pixels(destSize); @@ -175,7 +175,7 @@ PalettedPixels FHexFontChar::CreatePalettedPixels(int) return Pixels; } -int FHexFontChar::CopyPixels(FBitmap* bmp, int conversion) +int FHexFontChar::CopyPixels(FBitmap* bmp, int conversion, int frame) { if (conversion == luminance) conversion = normal; // luminance images have no use as an RGB source. PalEntry* palette = hexdata.ConsolePal; @@ -190,8 +190,8 @@ class FHexFontChar2 : public FHexFontChar public: FHexFontChar2(uint8_t *sourcedata, int swidth, int width, int height); - PalettedPixels CreatePalettedPixels(int conversion) override; - int CopyPixels(FBitmap* bmp, int conversion); + PalettedPixels CreatePalettedPixels(int conversion, int frame = 0) override; + int CopyPixels(FBitmap* bmp, int conversion, int frame = 0); }; @@ -216,7 +216,7 @@ FHexFontChar2::FHexFontChar2(uint8_t *sourcedata, int swidth, int width, int hei // //========================================================================== -PalettedPixels FHexFontChar2::CreatePalettedPixels(int) +PalettedPixels FHexFontChar2::CreatePalettedPixels(int, int) { int destSize = Width * Height; PalettedPixels Pixels(destSize); @@ -255,7 +255,7 @@ PalettedPixels FHexFontChar2::CreatePalettedPixels(int) return Pixels; } -int FHexFontChar2::CopyPixels(FBitmap* bmp, int conversion) +int FHexFontChar2::CopyPixels(FBitmap* bmp, int conversion, int frame) { if (conversion == luminance) conversion = normal; // luminance images have no use as an RGB source. PalEntry* palette = hexdata.SmallPal; diff --git a/source/common/fonts/singlelumpfont.cpp b/source/common/fonts/singlelumpfont.cpp index 72a3b1805..b40a86bff 100644 --- a/source/common/fonts/singlelumpfont.cpp +++ b/source/common/fonts/singlelumpfont.cpp @@ -124,7 +124,7 @@ FSingleLumpFont::FSingleLumpFont (const char *name, int lump) : FFont(lump) FontName = name; - FileData data1 = fileSystem.ReadFile (lump); + auto data1 = fileSystem.ReadFile (lump); auto data = data1.GetBytes(); if (data[0] == 0xE1 && data[1] == 0xE6 && data[2] == 0xD5 && data[3] == 0x1A) @@ -474,7 +474,7 @@ void FSingleLumpFont::LoadBMF(int lump, const uint8_t *data) void FSingleLumpFont::CheckFON1Chars() { - FileData memLump = fileSystem.ReadFile(Lump); + auto memLump = fileSystem.ReadFile(Lump); auto data = memLump.GetBytes(); const uint8_t* data_p; diff --git a/source/common/fonts/v_font.cpp b/source/common/fonts/v_font.cpp index f6e4ef0de..591edb208 100644 --- a/source/common/fonts/v_font.cpp +++ b/source/common/fonts/v_font.cpp @@ -109,7 +109,7 @@ FFont *V_GetFont(const char *name, const char *fontlumpname) int lump = -1; int folderfile = -1; - std::vector folderdata; + std::vector folderdata; FStringf path("fonts/%s/", name); // Use a folder-based font only if it comes from a later file than the single lump version. diff --git a/source/common/fonts/v_font.h b/source/common/fonts/v_font.h index 9fdab0228..0b5ce1338 100644 --- a/source/common/fonts/v_font.h +++ b/source/common/fonts/v_font.h @@ -175,7 +175,7 @@ protected: void FixXMoves(); - void ReadSheetFont(std::vector &folderdata, int width, int height, const DVector2 &Scale); + void ReadSheetFont(std::vector &folderdata, int width, int height, const DVector2 &Scale); EFontType Type = EFontType::Unknown; FName AltFontName = NAME_None; diff --git a/source/common/menu/menudef.cpp b/source/common/menu/menudef.cpp index e81bda2d2..34ef1fc9d 100644 --- a/source/common/menu/menudef.cpp +++ b/source/common/menu/menudef.cpp @@ -1519,7 +1519,7 @@ void M_ParseMenuDefs() DefaultOptionMenuSettings->Reset(); OptionSettings.mLinespacing = 17; - int IWADMenu = fileSystem.CheckNumForName("MENUDEF", ns_global, fileSystem.GetIwadNum()); + int IWADMenu = fileSystem.CheckNumForName("MENUDEF", FileSys::ns_global, fileSystem.GetIwadNum()); while ((lump = fileSystem.FindLump ("MENUDEF", &lastlump)) != -1) { diff --git a/source/common/menu/savegamemanager.cpp b/source/common/menu/savegamemanager.cpp index 7e948267d..29b0f447b 100644 --- a/source/common/menu/savegamemanager.cpp +++ b/source/common/menu/savegamemanager.cpp @@ -297,7 +297,7 @@ unsigned FSavegameManagerBase::ExtractSaveData(int index) !node->bOldVersion && (resf = FResourceFile::OpenResourceFile(node->Filename.GetChars(), true)) != nullptr) { - FResourceLump *info = resf->FindLump("info.json"); + auto info = resf->FindLump("info.json"); if (info == nullptr) { // this should not happen because the file has already been verified. @@ -315,7 +315,7 @@ unsigned FSavegameManagerBase::ExtractSaveData(int index) SaveCommentString = ExtractSaveComment(arc); - FResourceLump *pic = resf->FindLump("savepic.png"); + auto pic = resf->FindLump("savepic.png"); if (pic != nullptr) { FileReader picreader; diff --git a/source/common/models/model.cpp b/source/common/models/model.cpp index ceb77bcff..a7dccfc09 100644 --- a/source/common/models/model.cpp +++ b/source/common/models/model.cpp @@ -172,7 +172,7 @@ unsigned FindModel(const char * path, const char * modelfile, bool silent) } int len = fileSystem.FileLength(lump); - FileData lumpd = fileSystem.ReadFile(lump); + auto lumpd = fileSystem.ReadFile(lump); const char * buffer = lumpd.GetString(); if ( (size_t)fullname.LastIndexOf("_d.3d") == fullname.Len()-5 ) diff --git a/source/common/models/models_iqm.cpp b/source/common/models/models_iqm.cpp index 143c4334a..a2bc656a1 100644 --- a/source/common/models/models_iqm.cpp +++ b/source/common/models/models_iqm.cpp @@ -270,7 +270,7 @@ void IQMModel::LoadGeometry() { try { - FileData lumpdata = fileSystem.ReadFile(mLumpNum); + auto lumpdata = fileSystem.ReadFile(mLumpNum); IQMFileReader reader(lumpdata.GetMem(), (int)lumpdata.GetSize()); Vertices.Resize(NumVertices); diff --git a/source/common/models/models_md2.cpp b/source/common/models/models_md2.cpp index 0dd402cf9..d56d1e7c5 100644 --- a/source/common/models/models_md2.cpp +++ b/source/common/models/models_md2.cpp @@ -177,7 +177,7 @@ bool FDMDModel::Load(const char * path, int lumpnum, const char * buffer, int le void FDMDModel::LoadGeometry() { static int axis[3] = { VX, VY, VZ }; - FileData lumpdata = fileSystem.ReadFile(mLumpNum); + auto lumpdata = fileSystem.ReadFile(mLumpNum); auto buffer = lumpdata.GetString(); texCoords = new FTexCoord[info.numTexCoords]; memcpy(texCoords, buffer + info.offsetTexCoords, info.numTexCoords * sizeof(FTexCoord)); @@ -501,7 +501,7 @@ void FMD2Model::LoadGeometry() { static int axis[3] = { VX, VY, VZ }; uint8_t *md2_frames; - FileData lumpdata = fileSystem.ReadFile(mLumpNum); + auto lumpdata = fileSystem.ReadFile(mLumpNum); auto buffer = lumpdata.GetString(); texCoords = new FTexCoord[info.numTexCoords]; diff --git a/source/common/models/models_md3.cpp b/source/common/models/models_md3.cpp index ea2083a8b..65948d809 100644 --- a/source/common/models/models_md3.cpp +++ b/source/common/models/models_md3.cpp @@ -189,7 +189,7 @@ bool FMD3Model::Load(const char * path, int lumpnum, const char * buffer, int le void FMD3Model::LoadGeometry() { - FileData lumpdata = fileSystem.ReadFile(mLumpNum); + auto lumpdata = fileSystem.ReadFile(mLumpNum); auto buffer = lumpdata.GetString(); md3_header_t * hdr = (md3_header_t *)buffer; md3_surface_t * surf = (md3_surface_t*)(buffer + LittleLong(hdr->Ofs_Surfaces)); diff --git a/source/common/models/models_ue1.cpp b/source/common/models/models_ue1.cpp index aa8567850..742ef4aaf 100644 --- a/source/common/models/models_ue1.cpp +++ b/source/common/models/models_ue1.cpp @@ -70,9 +70,9 @@ bool FUE1Model::Load( const char *filename, int lumpnum, const char *buffer, int void FUE1Model::LoadGeometry() { const char *buffer, *buffer2; - FileData lump = fileSystem.ReadFile(mDataLump); + auto lump = fileSystem.ReadFile(mDataLump); buffer = lump.GetString(); - FileData lump2 = fileSystem.ReadFile(mAnivLump); + auto lump2 = fileSystem.ReadFile(mAnivLump); buffer2 = lump2.GetString(); // map structures dhead = (const d3dhead*)(buffer); diff --git a/source/common/models/models_voxel.cpp b/source/common/models/models_voxel.cpp index f723d1fe4..5fb749b5e 100644 --- a/source/common/models/models_voxel.cpp +++ b/source/common/models/models_voxel.cpp @@ -57,8 +57,8 @@ class FVoxelTexture : public FImageSource public: FVoxelTexture(FVoxel *voxel); - int CopyPixels(FBitmap *bmp, int conversion) override; - PalettedPixels CreatePalettedPixels(int conversion) override; + int CopyPixels(FBitmap *bmp, int conversion, int frame = 0) override; + PalettedPixels CreatePalettedPixels(int conversion, int frame = 0) override; protected: FVoxel *SourceVox; @@ -84,7 +84,7 @@ FVoxelTexture::FVoxelTexture(FVoxel *vox) // //=========================================================================== -PalettedPixels FVoxelTexture::CreatePalettedPixels(int conversion) +PalettedPixels FVoxelTexture::CreatePalettedPixels(int conversion, int frame) { // GetPixels gets called when a translated palette is used so we still need to implement it here. PalettedPixels Pixels(256); @@ -123,7 +123,7 @@ PalettedPixels FVoxelTexture::CreatePalettedPixels(int conversion) // //=========================================================================== -int FVoxelTexture::CopyPixels(FBitmap *bmp, int conversion) +int FVoxelTexture::CopyPixels(FBitmap *bmp, int conversion, int frame) { PalEntry pe[256]; uint8_t bitmap[256]; diff --git a/source/common/models/voxels.cpp b/source/common/models/voxels.cpp index 6c7867ccf..9d2f1fdd6 100644 --- a/source/common/models/voxels.cpp +++ b/source/common/models/voxels.cpp @@ -161,7 +161,7 @@ FVoxel *R_LoadKVX(int lumpnum) int mip, maxmipsize; int i, j, n; - FileData lump = fileSystem.ReadFile(lumpnum); // FileData adds an extra 0 byte to the end. + auto lump = fileSystem.ReadFile(lumpnum); // FileData adds an extra 0 byte to the end. auto rawvoxel = lump.GetBytes(); int voxelsize = (int)(lump.GetSize()-1); diff --git a/source/common/platform/posix/cocoa/i_main.mm b/source/common/platform/posix/cocoa/i_main.mm index 8a9d96b07..8c58ca419 100644 --- a/source/common/platform/posix/cocoa/i_main.mm +++ b/source/common/platform/posix/cocoa/i_main.mm @@ -282,7 +282,8 @@ extern bool AppActive; { ZD_UNUSED(aNotification); - S_SetSoundPaused(1); + if (GSnd) + S_SetSoundPaused(1); AppActive = true; } @@ -291,7 +292,8 @@ extern bool AppActive; { ZD_UNUSED(aNotification); - S_SetSoundPaused(0); + if (GSnd) + S_SetSoundPaused(0); AppActive = false; } diff --git a/source/common/platform/posix/cocoa/i_system.mm b/source/common/platform/posix/cocoa/i_system.mm index c2002ab7d..3338f54db 100644 --- a/source/common/platform/posix/cocoa/i_system.mm +++ b/source/common/platform/posix/cocoa/i_system.mm @@ -171,6 +171,17 @@ unsigned int I_MakeRNGSeed() return static_cast(arc4random()); } +FString I_GetCWD() +{ + NSString *currentpath = [[NSFileManager defaultManager] currentDirectoryPath]; + return currentpath.UTF8String; +} + +bool I_ChDir(const char* path) +{ + return [[NSFileManager defaultManager] changeCurrentDirectoryPath:[NSString stringWithUTF8String:path]]; +} + void I_OpenShellFolder(const char* folder) { NSFileManager *filemgr = [NSFileManager defaultManager]; diff --git a/source/common/platform/posix/sdl/i_system.cpp b/source/common/platform/posix/sdl/i_system.cpp index b2bd33fc2..96b707749 100644 --- a/source/common/platform/posix/sdl/i_system.cpp +++ b/source/common/platform/posix/sdl/i_system.cpp @@ -406,6 +406,23 @@ FString I_GetFromClipboard (bool use_primary_selection) return ""; } +FString I_GetCWD() +{ + char* curdir = getcwd(NULL,0); + if (!curdir) + { + return ""; + } + FString ret(curdir); + free(curdir); + return ret; +} + +bool I_ChDir(const char* path) +{ + return chdir(path) == 0; +} + // Return a random seed, preferably one with lots of entropy. unsigned int I_MakeRNGSeed() { diff --git a/source/common/platform/win32/i_system.cpp b/source/common/platform/win32/i_system.cpp index 42909ed87..8b39061a6 100644 --- a/source/common/platform/win32/i_system.cpp +++ b/source/common/platform/win32/i_system.cpp @@ -958,6 +958,25 @@ void I_SetThreadNumaNode(std::thread &thread, int numaNode) } } +FString I_GetCWD() +{ + auto len = GetCurrentDirectoryW(0, nullptr); + TArray curdir(len + 1, true); + if (!GetCurrentDirectoryW(len + 1, curdir.Data())) + { + return ""; + } + FString returnv(curdir.Data()); + FixPathSeperator(returnv); + return returnv; +} + +bool I_ChDir(const char* path) +{ + return SetCurrentDirectoryW(WideString(path).c_str()); +} + + void I_OpenShellFolder(const char* infolder) { auto len = GetCurrentDirectoryW(0, nullptr); diff --git a/source/common/platform/win32/i_system.h b/source/common/platform/win32/i_system.h index 163db04be..9d360b55a 100644 --- a/source/common/platform/win32/i_system.h +++ b/source/common/platform/win32/i_system.h @@ -80,5 +80,7 @@ int I_GetNumaNodeThreadCount(int numaNode); void I_SetThreadNumaNode(std::thread &thread, int numaNode); void I_OpenShellFolder(const char*); +FString I_GetCWD(); +bool I_ChDir(const char* path); #endif diff --git a/source/common/rendering/gl/gl_shader.cpp b/source/common/rendering/gl/gl_shader.cpp index 36287da8f..afa05b863 100644 --- a/source/common/rendering/gl/gl_shader.cpp +++ b/source/common/rendering/gl/gl_shader.cpp @@ -431,17 +431,13 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char * { int pl_lump = fileSystem.CheckNumForFullName("shaders/glsl/func_defaultmat2.fp", 0); if (pl_lump == -1) I_Error("Unable to load '%s'", "shaders/glsl/func_defaultmat2.fp"); - FileData pl_data = fileSystem.ReadFile(pl_lump); - fp_comb << "\n"; - fp_comb.AppendCStrPart(pl_data.GetString(), pl_data.GetSize()); + fp_comb << "\n" << GetStringFromLump(pl_lump); } else { int pl_lump = fileSystem.CheckNumForFullName("shaders/glsl/func_defaultmat.fp", 0); if (pl_lump == -1) I_Error("Unable to load '%s'", "shaders/glsl/func_defaultmat.fp"); - FileData pl_data = fileSystem.ReadFile(pl_lump); - fp_comb << "\n"; - fp_comb.AppendCStrPart(pl_data.GetString(), pl_data.GetSize()); + fp_comb << "\n" << GetStringFromLump(pl_lump); if (pp_data.IndexOf("ProcessTexel") < 0) { @@ -467,9 +463,7 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char * { int pl_lump = fileSystem.CheckNumForFullName("shaders/glsl/func_defaultlight.fp", 0); if (pl_lump == -1) I_Error("Unable to load '%s'", "shaders/glsl/func_defaultlight.fp"); - FileData pl_data = fileSystem.ReadFile(pl_lump); - fp_comb << "\n"; - fp_comb.AppendCStrPart(pl_data.GetString(), pl_data.GetSize()); + fp_comb << "\n" << GetStringFromLump(pl_lump); } // ProcessMaterial must be considered broken because it requires the user to fill in data they possibly cannot know all about. @@ -491,8 +485,7 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char * { int pp_lump = fileSystem.CheckNumForFullName(light_fragprog, 0); if (pp_lump == -1) I_Error("Unable to load '%s'", light_fragprog); - FileData pp_data = fileSystem.ReadFile(pp_lump); - fp_comb.AppendCStrPart(pp_data.GetString(), pp_data.GetSize()) << "\n"; + fp_comb << GetStringFromLump(pp_lump) << "\n"; } if (gl.flags & RFL_NO_CLIP_PLANES) diff --git a/source/common/rendering/gles/gles_shader.cpp b/source/common/rendering/gles/gles_shader.cpp index 7d4ac8db0..4fffa8b90 100644 --- a/source/common/rendering/gles/gles_shader.cpp +++ b/source/common/rendering/gles/gles_shader.cpp @@ -383,11 +383,11 @@ bool FShader::Load(const char * name, const char * vert_prog_lump_, const char * int vp_lump = fileSystem.CheckNumForFullName(vert_prog_lump, 0); if (vp_lump == -1) I_Error("Unable to load '%s'", vert_prog_lump.GetChars()); - FileData vp_data = fileSystem.ReadFile(vp_lump); + auto vp_data = fileSystem.ReadFile(vp_lump); int fp_lump = fileSystem.CheckNumForFullName(frag_prog_lump, 0); if (fp_lump == -1) I_Error("Unable to load '%s'", frag_prog_lump.GetChars()); - FileData fp_data = fileSystem.ReadFile(fp_lump); + auto fp_data = fileSystem.ReadFile(fp_lump); @@ -433,17 +433,13 @@ bool FShader::Load(const char * name, const char * vert_prog_lump_, const char * { int pl_lump = fileSystem.CheckNumForFullName("shaders_gles/glsl/func_defaultmat2.fp", 0); if (pl_lump == -1) I_Error("Unable to load '%s'", "shaders_gles/glsl/func_defaultmat2.fp"); - FileData pl_data = fileSystem.ReadFile(pl_lump); - fp_comb << "\n"; - fp_comb.AppendCStrPart(pl_data.GetString(), pl_data.GetSize()); + fp_comb << "\n" << GetStringFromLump(pl_lump); } else { int pl_lump = fileSystem.CheckNumForFullName("shaders_gles/glsl/func_defaultmat.fp", 0); if (pl_lump == -1) I_Error("Unable to load '%s'", "shaders_gles/glsl/func_defaultmat.fp"); - FileData pl_data = fileSystem.ReadFile(pl_lump); - fp_comb << "\n"; - fp_comb.AppendCStrPart(pl_data.GetString(), pl_data.GetSize()); + fp_comb << "\n" << GetStringFromLump(pl_lump); if (pp_data.IndexOf("ProcessTexel") < 0) { @@ -469,9 +465,7 @@ bool FShader::Load(const char * name, const char * vert_prog_lump_, const char * { int pl_lump = fileSystem.CheckNumForFullName("shaders_gles/glsl/func_defaultlight.fp", 0); if (pl_lump == -1) I_Error("Unable to load '%s'", "shaders_gles/glsl/func_defaultlight.fp"); - FileData pl_data = fileSystem.ReadFile(pl_lump); - fp_comb << "\n"; - fp_comb.AppendCStrPart(pl_data.GetString(), pl_data.GetSize()); + fp_comb << "\n" << GetStringFromLump(pl_lump); } // ProcessMaterial must be considered broken because it requires the user to fill in data they possibly cannot know all about. @@ -493,8 +487,7 @@ bool FShader::Load(const char * name, const char * vert_prog_lump_, const char * { int pp_lump = fileSystem.CheckNumForFullName(light_fragprog, 0); if (pp_lump == -1) I_Error("Unable to load '%s'", light_fragprog.GetChars()); - FileData pp_data = fileSystem.ReadFile(pp_lump); - fp_comb.AppendCStrPart(pp_data.GetString(), pp_data.GetSize()) << "\n"; + fp_comb << GetStringFromLump(pp_lump) << "\n"; } if (gles.flags & RFL_NO_CLIP_PLANES) diff --git a/source/common/rendering/v_video.h b/source/common/rendering/v_video.h index bb3c8bb4d..ed428ee67 100644 --- a/source/common/rendering/v_video.h +++ b/source/common/rendering/v_video.h @@ -45,6 +45,7 @@ #include "hw_shadowmap.h" #include "hw_levelmesh.h" #include "buffers.h" +#include "files.h" struct FPortalSceneState; @@ -90,7 +91,6 @@ EXTERN_CVAR(Int, win_h) EXTERN_CVAR(Bool, win_maximized) struct FColormap; -class FileWriter; enum FTextureFormat : uint32_t; class FModelRenderer; struct SamplerUniform; diff --git a/source/common/rendering/vulkan/shaders/vk_shader.cpp b/source/common/rendering/vulkan/shaders/vk_shader.cpp index 3784543b3..4ccfbd302 100644 --- a/source/common/rendering/vulkan/shaders/vk_shader.cpp +++ b/source/common/rendering/vulkan/shaders/vk_shader.cpp @@ -473,7 +473,7 @@ FString VkShaderManager::LoadPrivateShaderLump(const char *lumpname) { int lump = fileSystem.CheckNumForFullName(lumpname, 0); if (lump == -1) I_Error("Unable to load '%s'", lumpname); - FileData data = fileSystem.ReadFile(lump); + auto data = fileSystem.ReadFile(lump); return GetStringFromLump(lump); } diff --git a/source/common/startscreen/startscreen_generic.cpp b/source/common/startscreen/startscreen_generic.cpp index c2af0bd50..3484e2200 100644 --- a/source/common/startscreen/startscreen_generic.cpp +++ b/source/common/startscreen/startscreen_generic.cpp @@ -72,7 +72,7 @@ FGenericStartScreen::FGenericStartScreen(int max_progress) : FStartScreen(max_progress) { // at this point we do not have a working texture manager yet, so we have to do the lookup via the file system - int startup_lump = fileSystem.CheckNumForName("GZDOOM", ns_graphics); + int startup_lump = fileSystem.CheckNumForName("GZDOOM", FileSys::ns_graphics); StartupBitmap.Create(640, 480); ClearBlock(StartupBitmap, { 0, 0, 0, 255 }, 0, 0, 640, 480); diff --git a/source/common/startscreen/startscreen_hexen.cpp b/source/common/startscreen/startscreen_hexen.cpp index 6eef73599..a82e21b35 100644 --- a/source/common/startscreen/startscreen_hexen.cpp +++ b/source/common/startscreen/startscreen_hexen.cpp @@ -81,9 +81,9 @@ FHexenStartScreen::FHexenStartScreen(int max_progress) : FStartScreen(max_progress) { // at this point we do not have a working texture manager yet, so we have to do the lookup via the file system - int startup_lump = fileSystem.CheckNumForName("STARTUP", ns_graphics); - int netnotch_lump = fileSystem.CheckNumForName("NETNOTCH", ns_graphics); - int notch_lump = fileSystem.CheckNumForName("NOTCH", ns_graphics); + int startup_lump = fileSystem.CheckNumForName("STARTUP", FileSys::ns_graphics); + int netnotch_lump = fileSystem.CheckNumForName("NETNOTCH", FileSys::ns_graphics); + int notch_lump = fileSystem.CheckNumForName("NOTCH", FileSys::ns_graphics); // For backwards compatibility we also need to look in the default namespace, because these were previously not handled as graphics. if (startup_lump == -1) startup_lump = fileSystem.CheckNumForName("STARTUP"); diff --git a/source/common/startscreen/startscreen_strife.cpp b/source/common/startscreen/startscreen_strife.cpp index b4490a921..5b1d48bf4 100644 --- a/source/common/startscreen/startscreen_strife.cpp +++ b/source/common/startscreen/startscreen_strife.cpp @@ -119,7 +119,7 @@ FStrifeStartScreen::FStrifeStartScreen(int max_progress) // Load the animated overlays. for (size_t i = 0; i < countof(StrifeStartupPicNames); ++i) { - int lumpnum = fileSystem.CheckNumForName(StrifeStartupPicNames[i], ns_graphics); + int lumpnum = fileSystem.CheckNumForName(StrifeStartupPicNames[i], FileSys::ns_graphics); if (lumpnum < 0) lumpnum = fileSystem.CheckNumForName(StrifeStartupPicNames[i]); if (lumpnum >= 0) diff --git a/source/common/textures/formats/anmtexture.cpp b/source/common/textures/formats/anmtexture.cpp index f57b0e31e..ad02db728 100644 --- a/source/common/textures/formats/anmtexture.cpp +++ b/source/common/textures/formats/anmtexture.cpp @@ -51,8 +51,8 @@ class FAnmTexture : public FImageSource public: FAnmTexture (int lumpnum, int w, int h); void ReadFrame(uint8_t *buffer, uint8_t *palette); - PalettedPixels CreatePalettedPixels(int conversion) override; - int CopyPixels(FBitmap *bmp, int conversion) override; + PalettedPixels CreatePalettedPixels(int conversion, int frame = 0) override; + int CopyPixels(FBitmap *bmp, int conversion, int frame = 0) override; }; @@ -103,7 +103,7 @@ FAnmTexture::FAnmTexture (int lumpnum, int w, int h) void FAnmTexture::ReadFrame(uint8_t *pixels, uint8_t *palette) { - FileData lump = fileSystem.ReadFile (SourceLump); + auto lump = fileSystem.ReadFile (SourceLump); auto source = lump.GetBytes(); anim_t anim; @@ -127,7 +127,7 @@ void FAnmTexture::ReadFrame(uint8_t *pixels, uint8_t *palette) // //========================================================================== -PalettedPixels FAnmTexture::CreatePalettedPixels(int conversion) +PalettedPixels FAnmTexture::CreatePalettedPixels(int conversion, int frame) { PalettedPixels pixels(Width*Height); uint8_t buffer[64000]; @@ -149,7 +149,7 @@ PalettedPixels FAnmTexture::CreatePalettedPixels(int conversion) // //========================================================================== -int FAnmTexture::CopyPixels(FBitmap *bmp, int conversion) +int FAnmTexture::CopyPixels(FBitmap *bmp, int conversion, int frame) { uint8_t buffer[64000]; uint8_t palette[768]; diff --git a/source/common/textures/formats/automaptexture.cpp b/source/common/textures/formats/automaptexture.cpp index 6b660b1ba..a3b16c720 100644 --- a/source/common/textures/formats/automaptexture.cpp +++ b/source/common/textures/formats/automaptexture.cpp @@ -50,7 +50,7 @@ class FAutomapTexture : public FImageSource { public: FAutomapTexture(int lumpnum); - PalettedPixels CreatePalettedPixels(int conversion) override; + PalettedPixels CreatePalettedPixels(int conversion, int frame = 0) override; }; @@ -89,10 +89,10 @@ FAutomapTexture::FAutomapTexture (int lumpnum) // //========================================================================== -PalettedPixels FAutomapTexture::CreatePalettedPixels(int conversion) +PalettedPixels FAutomapTexture::CreatePalettedPixels(int conversion, int frame) { int x, y; - FileData data = fileSystem.ReadFile (SourceLump); + auto data = fileSystem.ReadFile (SourceLump); auto indata = data.GetBytes(); PalettedPixels Pixels(Width * Height); diff --git a/source/common/textures/formats/brightmaptexture.cpp b/source/common/textures/formats/brightmaptexture.cpp index f7e36d628..43499f17e 100644 --- a/source/common/textures/formats/brightmaptexture.cpp +++ b/source/common/textures/formats/brightmaptexture.cpp @@ -43,7 +43,7 @@ class FBrightmapTexture : public FImageSource public: FBrightmapTexture (FImageSource *source); - int CopyPixels(FBitmap *bmp, int conversion) override; + int CopyPixels(FBitmap *bmp, int conversion, int frame = 0) override; protected: FImageSource *SourcePic; @@ -65,7 +65,7 @@ FBrightmapTexture::FBrightmapTexture (FImageSource *source) bMasked = false; } -int FBrightmapTexture::CopyPixels(FBitmap *bmp, int conversion) +int FBrightmapTexture::CopyPixels(FBitmap *bmp, int conversion, int frame) { SourcePic->CopyTranslatedPixels(bmp, GPalette.GlobalBrightmap.Palette); return 0; diff --git a/source/common/textures/formats/buildtexture.cpp b/source/common/textures/formats/buildtexture.cpp index f8d8a7b6a..fec41227b 100644 --- a/source/common/textures/formats/buildtexture.cpp +++ b/source/common/textures/formats/buildtexture.cpp @@ -55,7 +55,7 @@ FBuildTexture::FBuildTexture(const FString &pathprefix, int tilenum, const uint8 TopOffset = top; } -PalettedPixels FBuildTexture::CreatePalettedPixels(int conversion) +PalettedPixels FBuildTexture::CreatePalettedPixels(int conversion, int frame) { PalettedPixels Pixels(Width * Height); FRemapTable *Remap = Translation; @@ -67,7 +67,7 @@ PalettedPixels FBuildTexture::CreatePalettedPixels(int conversion) return Pixels; } -int FBuildTexture::CopyPixels(FBitmap *bmp, int conversion) +int FBuildTexture::CopyPixels(FBitmap *bmp, int conversion, int frame) { PalEntry *Remap = Translation->Palette; bmp->CopyPixelData(0, 0, RawPixels, Width, Height, Height, 1, 0, Remap); diff --git a/source/common/textures/formats/ddstexture.cpp b/source/common/textures/formats/ddstexture.cpp index 5ccf309b9..3949c3d88 100644 --- a/source/common/textures/formats/ddstexture.cpp +++ b/source/common/textures/formats/ddstexture.cpp @@ -164,7 +164,7 @@ class FDDSTexture : public FImageSource public: FDDSTexture (FileReader &lump, int lumpnum, void *surfdesc); - PalettedPixels CreatePalettedPixels(int conversion) override; + PalettedPixels CreatePalettedPixels(int conversion, int frame = 0) override; protected: uint32_t Format; @@ -183,7 +183,7 @@ protected: void DecompressDXT3 (FileReader &lump, bool premultiplied, uint8_t *buffer, int pixelmode); void DecompressDXT5 (FileReader &lump, bool premultiplied, uint8_t *buffer, int pixelmode); - int CopyPixels(FBitmap *bmp, int conversion) override; + int CopyPixels(FBitmap *bmp, int conversion, int frame = 0) override; friend class FTexture; }; @@ -372,7 +372,7 @@ void FDDSTexture::CalcBitShift (uint32_t mask, uint8_t *lshiftp, uint8_t *rshift // //========================================================================== -PalettedPixels FDDSTexture::CreatePalettedPixels(int conversion) +PalettedPixels FDDSTexture::CreatePalettedPixels(int conversion, int frame) { auto lump = fileSystem.OpenFileReader (SourceLump); @@ -781,7 +781,7 @@ void FDDSTexture::DecompressDXT5 (FileReader &lump, bool premultiplied, uint8_t // //=========================================================================== -int FDDSTexture::CopyPixels(FBitmap *bmp, int conversion) +int FDDSTexture::CopyPixels(FBitmap *bmp, int conversion, int frame) { auto lump = fileSystem.OpenFileReader (SourceLump); diff --git a/source/common/textures/formats/emptytexture.cpp b/source/common/textures/formats/emptytexture.cpp index 74e8fe1cb..cd53b996a 100644 --- a/source/common/textures/formats/emptytexture.cpp +++ b/source/common/textures/formats/emptytexture.cpp @@ -49,7 +49,7 @@ class FEmptyTexture : public FImageSource { public: FEmptyTexture (int lumpnum); - PalettedPixels CreatePalettedPixels(int conversion) override; + PalettedPixels CreatePalettedPixels(int conversion, int frame = 0) override; }; //========================================================================== @@ -94,7 +94,7 @@ FEmptyTexture::FEmptyTexture (int lumpnum) // //========================================================================== -PalettedPixels FEmptyTexture::CreatePalettedPixels(int conversion) +PalettedPixels FEmptyTexture::CreatePalettedPixels(int conversion, int frame) { static uint8_t p; PalettedPixels Pixel(&p, 1); diff --git a/source/common/textures/formats/flattexture.cpp b/source/common/textures/formats/flattexture.cpp index a01016a36..5f26df931 100644 --- a/source/common/textures/formats/flattexture.cpp +++ b/source/common/textures/formats/flattexture.cpp @@ -48,7 +48,7 @@ class FFlatTexture : public FImageSource { public: FFlatTexture (int lumpnum); - PalettedPixels CreatePalettedPixels(int conversion) override; + PalettedPixels CreatePalettedPixels(int conversion, int frame = 0) override; }; @@ -102,7 +102,7 @@ FFlatTexture::FFlatTexture (int lumpnum) // //========================================================================== -PalettedPixels FFlatTexture::CreatePalettedPixels(int conversion) +PalettedPixels FFlatTexture::CreatePalettedPixels(int conversion, int frame) { auto lump = fileSystem.OpenFileReader (SourceLump); PalettedPixels Pixels(Width*Height); diff --git a/source/common/textures/formats/fontchars.cpp b/source/common/textures/formats/fontchars.cpp index 09fbd718e..2d09cf58d 100644 --- a/source/common/textures/formats/fontchars.cpp +++ b/source/common/textures/formats/fontchars.cpp @@ -66,7 +66,7 @@ FFontChar2::FFontChar2(int sourcelump, int sourcepos, int width, int height, int // //========================================================================== -PalettedPixels FFontChar2::CreatePalettedPixels(int) +PalettedPixels FFontChar2::CreatePalettedPixels(int, int) { auto lump = fileSystem.OpenFileReader(SourceLump); int destSize = Width * Height; @@ -170,7 +170,7 @@ PalettedPixels FFontChar2::CreatePalettedPixels(int) return Pixels; } -int FFontChar2::CopyPixels(FBitmap* bmp, int conversion) +int FFontChar2::CopyPixels(FBitmap* bmp, int conversion, int frame) { if (conversion == luminance) conversion = normal; // luminance images have no use as an RGB source. auto ppix = CreatePalettedPixels(conversion); diff --git a/source/common/textures/formats/fontchars.h b/source/common/textures/formats/fontchars.h index 45c678566..089043969 100644 --- a/source/common/textures/formats/fontchars.h +++ b/source/common/textures/formats/fontchars.h @@ -6,8 +6,8 @@ class FFontChar2 : public FImageSource public: FFontChar2 (int sourcelump, int sourcepos, int width, int height, int leftofs=0, int topofs=0); - PalettedPixels CreatePalettedPixels(int conversion) override; - int CopyPixels(FBitmap* bmp, int conversion); + PalettedPixels CreatePalettedPixels(int conversion, int frame = 0) override; + int CopyPixels(FBitmap* bmp, int conversion, int frame = 0); void SetSourceRemap(const PalEntry* sourceremap) { diff --git a/source/common/textures/formats/imgztexture.cpp b/source/common/textures/formats/imgztexture.cpp index fb020c9a1..b5deaccac 100644 --- a/source/common/textures/formats/imgztexture.cpp +++ b/source/common/textures/formats/imgztexture.cpp @@ -66,8 +66,8 @@ class FIMGZTexture : public FImageSource public: FIMGZTexture (int lumpnum, uint16_t w, uint16_t h, int16_t l, int16_t t, bool isalpha); - PalettedPixels CreatePalettedPixels(int conversion) override; - int CopyPixels(FBitmap *bmp, int conversion) override; + PalettedPixels CreatePalettedPixels(int conversion, int frame = 0) override; + int CopyPixels(FBitmap *bmp, int conversion, int frame = 0) override; }; @@ -118,9 +118,9 @@ FIMGZTexture::FIMGZTexture (int lumpnum, uint16_t w, uint16_t h, int16_t l, int1 // //========================================================================== -PalettedPixels FIMGZTexture::CreatePalettedPixels(int conversion) +PalettedPixels FIMGZTexture::CreatePalettedPixels(int conversion, int frame) { - FileData lump = fileSystem.ReadFile (SourceLump); + auto lump = fileSystem.ReadFile (SourceLump); auto imgz = (const ImageHeader *)lump.GetMem(); const uint8_t *data = (const uint8_t *)&imgz[1]; @@ -198,7 +198,7 @@ PalettedPixels FIMGZTexture::CreatePalettedPixels(int conversion) // //========================================================================== -int FIMGZTexture::CopyPixels(FBitmap *bmp, int conversion) +int FIMGZTexture::CopyPixels(FBitmap *bmp, int conversion, int frame) { if (!isalpha) return FImageSource::CopyPixels(bmp, conversion); else return CopyTranslatedPixels(bmp, GPalette.GrayscaleMap.Palette); diff --git a/source/common/textures/formats/jpegtexture.cpp b/source/common/textures/formats/jpegtexture.cpp index 834dc44e3..964985421 100644 --- a/source/common/textures/formats/jpegtexture.cpp +++ b/source/common/textures/formats/jpegtexture.cpp @@ -185,8 +185,8 @@ class FJPEGTexture : public FImageSource public: FJPEGTexture (int lumpnum, int width, int height); - int CopyPixels(FBitmap *bmp, int conversion) override; - PalettedPixels CreatePalettedPixels(int conversion) override; + int CopyPixels(FBitmap *bmp, int conversion, int frame = 0) override; + PalettedPixels CreatePalettedPixels(int conversion, int frame = 0) override; }; //========================================================================== @@ -260,7 +260,7 @@ FJPEGTexture::FJPEGTexture (int lumpnum, int width, int height) // //========================================================================== -PalettedPixels FJPEGTexture::CreatePalettedPixels(int conversion) +PalettedPixels FJPEGTexture::CreatePalettedPixels(int conversion, int frame) { auto lump = fileSystem.OpenFileReader (SourceLump); JSAMPLE *buff = NULL; @@ -401,7 +401,7 @@ PalettedPixels FJPEGTexture::CreatePalettedPixels(int conversion) // //=========================================================================== -int FJPEGTexture::CopyPixels(FBitmap *bmp, int conversion) +int FJPEGTexture::CopyPixels(FBitmap *bmp, int conversion, int frame) { PalEntry pe[256]; diff --git a/source/common/textures/formats/multipatchtexture.cpp b/source/common/textures/formats/multipatchtexture.cpp index 17c0a7b28..3a8e8ae7b 100644 --- a/source/common/textures/formats/multipatchtexture.cpp +++ b/source/common/textures/formats/multipatchtexture.cpp @@ -201,7 +201,7 @@ void FMultiPatchTexture::CopyToBlock(uint8_t *dest, int dwidth, int dheight, FIm // //========================================================================== -PalettedPixels FMultiPatchTexture::CreatePalettedPixels(int conversion) +PalettedPixels FMultiPatchTexture::CreatePalettedPixels(int conversion, int frame) { int numpix = Width * Height; uint8_t blendwork[256]; @@ -278,7 +278,7 @@ PalettedPixels FMultiPatchTexture::CreatePalettedPixels(int conversion) // //=========================================================================== -int FMultiPatchTexture::CopyPixels(FBitmap *bmp, int conversion) +int FMultiPatchTexture::CopyPixels(FBitmap *bmp, int conversion, int frame) { int retv = -1; diff --git a/source/common/textures/formats/multipatchtexture.h b/source/common/textures/formats/multipatchtexture.h index 4b92aad4f..ce1f5d932 100644 --- a/source/common/textures/formats/multipatchtexture.h +++ b/source/common/textures/formats/multipatchtexture.h @@ -74,8 +74,8 @@ protected: TexPart *Parts; // The getters must optionally redirect if it's a simple one-patch texture. - int CopyPixels(FBitmap *bmp, int conversion) override; - PalettedPixels CreatePalettedPixels(int conversion) override; + int CopyPixels(FBitmap *bmp, int conversion, int frame = 0) override; + PalettedPixels CreatePalettedPixels(int conversion, int frame = 0) override; void CopyToBlock(uint8_t *dest, int dwidth, int dheight, FImageSource *source, int xpos, int ypos, int rotate, const uint8_t *translation, int style); void CollectForPrecache(PrecacheInfo &info, bool requiretruecolor) override; diff --git a/source/common/textures/formats/patchtexture.cpp b/source/common/textures/formats/patchtexture.cpp index d64e003e2..a6f70222f 100644 --- a/source/common/textures/formats/patchtexture.cpp +++ b/source/common/textures/formats/patchtexture.cpp @@ -62,8 +62,8 @@ class FPatchTexture : public FImageSource bool isalpha = false; public: FPatchTexture (int lumpnum, int w, int h, int lo, int to, bool isalphatex); - PalettedPixels CreatePalettedPixels(int conversion) override; - int CopyPixels(FBitmap *bmp, int conversion) override; + PalettedPixels CreatePalettedPixels(int conversion, int frame = 0) override; + int CopyPixels(FBitmap *bmp, int conversion, int frame = 0) override; bool SupportRemap0() override { return !badflag; } void DetectBadPatches(); }; @@ -167,14 +167,14 @@ FPatchTexture::FPatchTexture (int lumpnum, int w, int h, int lo, int to, bool is // //========================================================================== -PalettedPixels FPatchTexture::CreatePalettedPixels(int conversion) +PalettedPixels FPatchTexture::CreatePalettedPixels(int conversion, int frame) { uint8_t *remap, remaptable[256]; int numspans; const column_t *maxcol; int x; - FileData lump = fileSystem.ReadFile (SourceLump); + auto lump = fileSystem.ReadFile (SourceLump); const patch_t *patch = (const patch_t *)lump.GetMem(); maxcol = (const column_t *)((const uint8_t *)patch + fileSystem.FileLength (SourceLump) - 3); @@ -264,7 +264,7 @@ PalettedPixels FPatchTexture::CreatePalettedPixels(int conversion) // //========================================================================== -int FPatchTexture::CopyPixels(FBitmap *bmp, int conversion) +int FPatchTexture::CopyPixels(FBitmap *bmp, int conversion, int frame) { if (!isalpha) return FImageSource::CopyPixels(bmp, conversion); else return CopyTranslatedPixels(bmp, GPalette.GrayscaleMap.Palette); @@ -284,7 +284,7 @@ void FPatchTexture::DetectBadPatches () // Check if this patch is likely to be a problem. // It must be 256 pixels tall, and all its columns must have exactly // one post, where each post has a supposed length of 0. - FileData lump = fileSystem.ReadFile (SourceLump); + auto lump = fileSystem.ReadFile (SourceLump); const patch_t *realpatch = (patch_t *)lump.GetMem(); const uint32_t *cofs = realpatch->columnofs; int x, x2 = LittleShort(realpatch->width); diff --git a/source/common/textures/formats/pcxtexture.cpp b/source/common/textures/formats/pcxtexture.cpp index bc014659f..494adeb1f 100644 --- a/source/common/textures/formats/pcxtexture.cpp +++ b/source/common/textures/formats/pcxtexture.cpp @@ -84,7 +84,7 @@ class FPCXTexture : public FImageSource public: FPCXTexture (int lumpnum, PCXHeader &); - int CopyPixels(FBitmap *bmp, int conversion) override; + int CopyPixels(FBitmap *bmp, int conversion, int frame = 0) override; protected: void ReadPCX1bit (uint8_t *dst, FileReader & lump, PCXHeader *hdr); @@ -92,7 +92,7 @@ protected: void ReadPCX8bits (uint8_t *dst, FileReader & lump, PCXHeader *hdr); void ReadPCX24bits (uint8_t *dst, FileReader & lump, PCXHeader *hdr, int planes); - PalettedPixels CreatePalettedPixels(int conversion) override; + PalettedPixels CreatePalettedPixels(int conversion, int frame = 0) override; }; @@ -345,7 +345,7 @@ void FPCXTexture::ReadPCX24bits (uint8_t *dst, FileReader & lump, PCXHeader *hdr // //========================================================================== -PalettedPixels FPCXTexture::CreatePalettedPixels(int conversion) +PalettedPixels FPCXTexture::CreatePalettedPixels(int conversion, int frame) { uint8_t PaletteMap[256]; PCXHeader header; @@ -433,7 +433,7 @@ PalettedPixels FPCXTexture::CreatePalettedPixels(int conversion) // //=========================================================================== -int FPCXTexture::CopyPixels(FBitmap *bmp, int conversion) +int FPCXTexture::CopyPixels(FBitmap *bmp, int conversion, int frame) { PalEntry pe[256]; PCXHeader header; diff --git a/source/common/textures/formats/pngtexture.cpp b/source/common/textures/formats/pngtexture.cpp index cdf14c15c..01f210a1c 100644 --- a/source/common/textures/formats/pngtexture.cpp +++ b/source/common/textures/formats/pngtexture.cpp @@ -56,8 +56,8 @@ class FPNGTexture : public FImageSource public: FPNGTexture (FileReader &lump, int lumpnum, int width, int height, uint8_t bitdepth, uint8_t colortype, uint8_t interlace); - int CopyPixels(FBitmap *bmp, int conversion) override; - PalettedPixels CreatePalettedPixels(int conversion) override; + int CopyPixels(FBitmap *bmp, int conversion, int frame = 0) override; + PalettedPixels CreatePalettedPixels(int conversion, int frame = 0) override; protected: void ReadAlphaRemap(FileReader *lump, uint8_t *alpharemap); @@ -412,7 +412,7 @@ void FPNGTexture::ReadAlphaRemap(FileReader *lump, uint8_t *alpharemap) // //========================================================================== -PalettedPixels FPNGTexture::CreatePalettedPixels(int conversion) +PalettedPixels FPNGTexture::CreatePalettedPixels(int conversion, int frame) { FileReader *lump; FileReader lfr; @@ -553,7 +553,7 @@ PalettedPixels FPNGTexture::CreatePalettedPixels(int conversion) // //=========================================================================== -int FPNGTexture::CopyPixels(FBitmap *bmp, int conversion) +int FPNGTexture::CopyPixels(FBitmap *bmp, int conversion, int frame) { // Parse pre-IDAT chunks. I skip the CRCs. Is that bad? PalEntry pe[256]; diff --git a/source/common/textures/formats/qoitexture.cpp b/source/common/textures/formats/qoitexture.cpp index c84ac38ce..663472f20 100644 --- a/source/common/textures/formats/qoitexture.cpp +++ b/source/common/textures/formats/qoitexture.cpp @@ -51,8 +51,8 @@ class FQOITexture : public FImageSource { public: FQOITexture(int lumpnum, QOIHeader& header); - PalettedPixels CreatePalettedPixels(int conversion) override; - int CopyPixels(FBitmap *bmp, int conversion) override; + PalettedPixels CreatePalettedPixels(int conversion, int frame = 0) override; + int CopyPixels(FBitmap *bmp, int conversion, int frame = 0) override; }; FImageSource *QOIImage_TryCreate(FileReader &file, int lumpnum) @@ -89,7 +89,7 @@ FQOITexture::FQOITexture(int lumpnum, QOIHeader& header) if (header.channels == 3) bMasked = bTranslucent = false; } -PalettedPixels FQOITexture::CreatePalettedPixels(int conversion) +PalettedPixels FQOITexture::CreatePalettedPixels(int conversion, int frame) { FBitmap bitmap; bitmap.Create(Width, Height); @@ -124,7 +124,7 @@ PalettedPixels FQOITexture::CreatePalettedPixels(int conversion) return Pixels; } -int FQOITexture::CopyPixels(FBitmap *bmp, int conversion) +int FQOITexture::CopyPixels(FBitmap *bmp, int conversion, int frame) { enum { diff --git a/source/common/textures/formats/rawpagetexture.cpp b/source/common/textures/formats/rawpagetexture.cpp index e2b6c1146..b185f5ffc 100644 --- a/source/common/textures/formats/rawpagetexture.cpp +++ b/source/common/textures/formats/rawpagetexture.cpp @@ -52,8 +52,8 @@ class FRawPageTexture : public FImageSource int mPaletteLump = -1; public: FRawPageTexture (int lumpnum); - PalettedPixels CreatePalettedPixels(int conversion) override; - int CopyPixels(FBitmap *bmp, int conversion) override; + PalettedPixels CreatePalettedPixels(int conversion, int frame = 0) override; + int CopyPixels(FBitmap *bmp, int conversion, int frame = 0) override; }; //========================================================================== @@ -170,9 +170,9 @@ FRawPageTexture::FRawPageTexture (int lumpnum) // //========================================================================== -PalettedPixels FRawPageTexture::CreatePalettedPixels(int conversion) +PalettedPixels FRawPageTexture::CreatePalettedPixels(int conversion, int frame) { - FileData lump = fileSystem.ReadFile (SourceLump); + auto lump = fileSystem.ReadFile (SourceLump); auto source = lump.GetBytes(); const uint8_t *source_p = source; uint8_t *dest_p; @@ -199,13 +199,13 @@ PalettedPixels FRawPageTexture::CreatePalettedPixels(int conversion) return Pixels; } -int FRawPageTexture::CopyPixels(FBitmap *bmp, int conversion) +int FRawPageTexture::CopyPixels(FBitmap *bmp, int conversion, int frame) { if (mPaletteLump < 0) return FImageSource::CopyPixels(bmp, conversion); else { - FileData lump = fileSystem.ReadFile(SourceLump); - FileData plump = fileSystem.ReadFile(mPaletteLump); + auto lump = fileSystem.ReadFile(SourceLump); + auto plump = fileSystem.ReadFile(mPaletteLump); auto source = lump.GetBytes(); auto psource = plump.GetBytes(); PalEntry paldata[256]; diff --git a/source/common/textures/formats/shadertexture.cpp b/source/common/textures/formats/shadertexture.cpp index ce5952fc2..0b69e8acb 100644 --- a/source/common/textures/formats/shadertexture.cpp +++ b/source/common/textures/formats/shadertexture.cpp @@ -98,7 +98,7 @@ public: } } - PalettedPixels CreatePalettedPixels(int conversion) override + PalettedPixels CreatePalettedPixels(int conversion, int frame = 0) override { PalettedPixels Pix(512); if (conversion == luminance) @@ -118,7 +118,7 @@ public: return Pix; } - int CopyPixels(FBitmap *bmp, int conversion) override + int CopyPixels(FBitmap *bmp, int conversion, int frame = 0) override { bmp->CopyPixelData(0, 0, Pixels, Width, Height, Height, 1, 0, GPalette.GrayRamp.Palette); return 0; diff --git a/source/common/textures/formats/startscreentexture.cpp b/source/common/textures/formats/startscreentexture.cpp index 85710d42f..f19a654f9 100644 --- a/source/common/textures/formats/startscreentexture.cpp +++ b/source/common/textures/formats/startscreentexture.cpp @@ -60,7 +60,7 @@ public: Height = srcdata.GetHeight(); bUseGamePalette = false; } - int CopyPixels(FBitmap* bmp, int conversion) + int CopyPixels(FBitmap* bmp, int conversion, int frame = 0) { bmp->Blit(0, 0, info); return 0; diff --git a/source/common/textures/formats/startuptexture.cpp b/source/common/textures/formats/startuptexture.cpp index 718b7182a..510061f7c 100644 --- a/source/common/textures/formats/startuptexture.cpp +++ b/source/common/textures/formats/startuptexture.cpp @@ -77,30 +77,30 @@ class FStartupTexture : public FImageSource { public: FStartupTexture (int lumpnum); - PalettedPixels CreatePalettedPixels(int conversion) override; - int CopyPixels(FBitmap *bmp, int conversion) override; + PalettedPixels CreatePalettedPixels(int conversion, int frame = 0) override; + int CopyPixels(FBitmap *bmp, int conversion, int frame) override; }; class FNotchTexture : public FImageSource { public: FNotchTexture (int lumpnum, int width, int height); - PalettedPixels CreatePalettedPixels(int conversion) override; - int CopyPixels(FBitmap *bmp, int conversion) override; + PalettedPixels CreatePalettedPixels(int conversion, int frame = 0) override; + int CopyPixels(FBitmap *bmp, int conversion, int frame) override; }; class FStrifeStartupTexture : public FImageSource { public: FStrifeStartupTexture (int lumpnum, int w, int h); - PalettedPixels CreatePalettedPixels(int conversion) override; + PalettedPixels CreatePalettedPixels(int conversion, int frame = 0) override; }; class FStrifeStartupBackground : public FImageSource { public: FStrifeStartupBackground (int lumpnum); - PalettedPixels CreatePalettedPixels(int conversion) override; + PalettedPixels CreatePalettedPixels(int conversion, int frame = 0) override; }; //========================================================================== @@ -164,7 +164,7 @@ FStartupTexture::FStartupTexture (int lumpnum) Height = 480; bUseGamePalette = false; - FileData lump = fileSystem.ReadFile (SourceLump); + auto lump = fileSystem.ReadFile (SourceLump); auto source = lump.GetBytes(); // Initialize the bitmap palette. @@ -231,9 +231,9 @@ void PlanarToChunky(T* dest, const uint8_t* src, const T* remap, int width, int // //========================================================================== -PalettedPixels FStartupTexture::CreatePalettedPixels(int conversion) +PalettedPixels FStartupTexture::CreatePalettedPixels(int conversion, int frame) { - FileData lump = fileSystem.ReadFile (SourceLump); + auto lump = fileSystem.ReadFile (SourceLump); auto source = lump.GetBytes(); const uint8_t *remap = ImageHelpers::GetRemap(conversion == luminance); @@ -251,9 +251,9 @@ PalettedPixels FStartupTexture::CreatePalettedPixels(int conversion) // //========================================================================== -int FStartupTexture::CopyPixels(FBitmap *bmp, int conversion) +int FStartupTexture::CopyPixels(FBitmap *bmp, int conversion, int frame) { - FileData lump = fileSystem.ReadFile (SourceLump); + auto lump = fileSystem.ReadFile (SourceLump); auto source = lump.GetBytes(); PlanarToChunky((uint32_t*)bmp->GetPixels(), source + 48, startuppalette32, Width, Height); return 0; @@ -279,9 +279,9 @@ FNotchTexture::FNotchTexture (int lumpnum, int width, int height) // //========================================================================== -PalettedPixels FNotchTexture::CreatePalettedPixels(int conversion) +PalettedPixels FNotchTexture::CreatePalettedPixels(int conversion, int frame) { - FileData lump = fileSystem.ReadFile (SourceLump); + auto lump = fileSystem.ReadFile (SourceLump); auto source = lump.GetBytes(); const uint8_t *remap = ImageHelpers::GetRemap(conversion == luminance); @@ -302,9 +302,9 @@ PalettedPixels FNotchTexture::CreatePalettedPixels(int conversion) // //========================================================================== -int FNotchTexture::CopyPixels(FBitmap *bmp, int conversion) +int FNotchTexture::CopyPixels(FBitmap *bmp, int conversion, int frame) { - FileData lump = fileSystem.ReadFile (SourceLump); + auto lump = fileSystem.ReadFile (SourceLump); auto source = lump.GetBytes(); auto Work = (uint32_t*)bmp->GetPixels(); @@ -336,9 +336,9 @@ FStrifeStartupTexture::FStrifeStartupTexture (int lumpnum, int w, int h) // //========================================================================== -PalettedPixels FStrifeStartupTexture::CreatePalettedPixels(int conversion) +PalettedPixels FStrifeStartupTexture::CreatePalettedPixels(int conversion, int frame) { - FileData lump = fileSystem.ReadFile (SourceLump); + auto lump = fileSystem.ReadFile (SourceLump); auto source = lump.GetBytes(); PalettedPixels Pixels(Width*Height); const uint8_t *remap = ImageHelpers::GetRemap(conversion == luminance); @@ -366,7 +366,7 @@ FStrifeStartupBackground::FStrifeStartupBackground (int lumpnum) // //========================================================================== -PalettedPixels FStrifeStartupBackground::CreatePalettedPixels(int conversion) +PalettedPixels FStrifeStartupBackground::CreatePalettedPixels(int conversion, int frame) { TArray source(64000, true); memset(source.Data(), 0xF0, 64000); diff --git a/source/common/textures/formats/stbtexture.cpp b/source/common/textures/formats/stbtexture.cpp index e8d9fe2a0..2507cb5b2 100644 --- a/source/common/textures/formats/stbtexture.cpp +++ b/source/common/textures/formats/stbtexture.cpp @@ -67,8 +67,8 @@ class FStbTexture : public FImageSource public: FStbTexture (int lumpnum, int w, int h); - PalettedPixels CreatePalettedPixels(int conversion) override; - int CopyPixels(FBitmap *bmp, int conversion) override; + PalettedPixels CreatePalettedPixels(int conversion, int frame = 0) override; + int CopyPixels(FBitmap *bmp, int conversion, int frame = 0) override; }; @@ -117,7 +117,7 @@ FStbTexture::FStbTexture (int lumpnum, int w, int h) // //========================================================================== -PalettedPixels FStbTexture::CreatePalettedPixels(int conversion) +PalettedPixels FStbTexture::CreatePalettedPixels(int conversion, int frame) { FBitmap bitmap; bitmap.Create(Width, Height); @@ -156,7 +156,7 @@ PalettedPixels FStbTexture::CreatePalettedPixels(int conversion) // //========================================================================== -int FStbTexture::CopyPixels(FBitmap *bmp, int conversion) +int FStbTexture::CopyPixels(FBitmap *bmp, int conversion, int frame) { auto lump = fileSystem.OpenFileReader (SourceLump); int x, y, chan; diff --git a/source/common/textures/formats/tgatexture.cpp b/source/common/textures/formats/tgatexture.cpp index daa70cfa4..2318e4199 100644 --- a/source/common/textures/formats/tgatexture.cpp +++ b/source/common/textures/formats/tgatexture.cpp @@ -80,11 +80,11 @@ class FTGATexture : public FImageSource public: FTGATexture (int lumpnum, TGAHeader *); - int CopyPixels(FBitmap *bmp, int conversion) override; + int CopyPixels(FBitmap *bmp, int conversion, int frame = 0) override; protected: void ReadCompressed(FileReader &lump, uint8_t * buffer, int bytesperpixel); - PalettedPixels CreatePalettedPixels(int conversion) override; + PalettedPixels CreatePalettedPixels(int conversion, int frame = 0) override; }; //========================================================================== @@ -178,7 +178,7 @@ void FTGATexture::ReadCompressed(FileReader &lump, uint8_t * buffer, int bytespe // //========================================================================== -PalettedPixels FTGATexture::CreatePalettedPixels(int conversion) +PalettedPixels FTGATexture::CreatePalettedPixels(int conversion, int frame) { uint8_t PaletteMap[256]; auto lump = fileSystem.OpenFileReader (SourceLump); @@ -385,7 +385,7 @@ PalettedPixels FTGATexture::CreatePalettedPixels(int conversion) // //=========================================================================== -int FTGATexture::CopyPixels(FBitmap *bmp, int conversion) +int FTGATexture::CopyPixels(FBitmap *bmp, int conversion, int frame) { PalEntry pe[256]; auto lump = fileSystem.OpenFileReader (SourceLump); diff --git a/source/common/textures/formats/webptexture.cpp b/source/common/textures/formats/webptexture.cpp new file mode 100644 index 000000000..4a3233c9e --- /dev/null +++ b/source/common/textures/formats/webptexture.cpp @@ -0,0 +1,148 @@ +/* +** webptexture.cpp +** Texture class for WebP images. +** +**--------------------------------------------------------------------------- +** Copyright 2023 Cacodemon345 +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**--------------------------------------------------------------------------- +** +** +*/ +#include "webp/decode.h" +#include "webp/mux.h" + +#include "files.h" +#include "filesystem.h" +#include "bitmap.h" +#include "imagehelpers.h" +#include "image.h" +#include "printf.h" + +class FWebPTexture : public FImageSource +{ + +public: + FWebPTexture(int lumpnum, int w, int h, int xoff, int yoff); + PalettedPixels CreatePalettedPixels(int conversion, int frame = 0) override; + int CopyPixels(FBitmap *bmp, int conversion, int frame = 0) override; +}; + + +FImageSource *WebPImage_TryCreate(FileReader &file, int lumpnum) +{ + int width = 0, height = 0; + int xoff = 0, yoff = 0; + file.Seek(0, FileReader::SeekSet); + + uint8_t header[12]; + if (file.Read(header, 12) != 12) return nullptr; + if (memcmp(header, "RIFF", 4) || memcmp(header + 8, "WEBP", 4)) return nullptr; + + file.Seek(0, FileReader::SeekSet); + auto bytes = file.Read(); + + if (WebPGetInfo(bytes.data(), bytes.size(), &width, &height)) + { + WebPData data{ bytes.data(), bytes.size() }; + WebPData chunk_data; + auto mux = WebPMuxCreate(&data, 0); + if (mux) + { + const char fourcc[4] = { 'g', 'r', 'A', 'b' }; + if (WebPMuxGetChunk(mux, fourcc, &chunk_data) == WEBP_MUX_OK && chunk_data.size >= 4) + { + xoff = chunk_data.bytes[0] | (chunk_data.bytes[1] << 8); + yoff = chunk_data.bytes[2] | (chunk_data.bytes[3] << 8); + } + WebPMuxDelete(mux); + } + return new FWebPTexture(lumpnum, width, height, xoff, yoff); + } + return nullptr; +} + +FWebPTexture::FWebPTexture(int lumpnum, int w, int h, int xoff, int yoff) + : FImageSource(lumpnum) +{ + Width = w; + Height = h; + LeftOffset = xoff; + TopOffset = yoff; +} + +PalettedPixels FWebPTexture::CreatePalettedPixels(int conversion, int frame) +{ + FBitmap bitmap; + bitmap.Create(Width, Height); + CopyPixels(&bitmap, conversion); + const uint8_t *data = bitmap.GetPixels(); + + uint8_t *dest_p; + int dest_adv = Height; + int dest_rew = Width * Height - 1; + + PalettedPixels Pixels(Width*Height); + dest_p = Pixels.Data(); + + bool doalpha = conversion == luminance; + // Convert the source image from row-major to column-major format and remap it + for (int y = Height; y != 0; --y) + { + for (int x = Width; x != 0; --x) + { + int b = *data++; + int g = *data++; + int r = *data++; + int a = *data++; + if (a < 128) *dest_p = 0; + else *dest_p = ImageHelpers::RGBToPalette(doalpha, r, g, b); + dest_p += dest_adv; + } + dest_p -= dest_rew; + } + return Pixels; +} + +int FWebPTexture::CopyPixels(FBitmap *bmp, int conversion, int frame) +{ + WebPDecoderConfig config; + auto bytes = fileSystem.ReadFile(SourceLump); + + if (WebPInitDecoderConfig(&config) == false) + return 0; + + config.options.no_fancy_upsampling = 0; + config.output.colorspace = MODE_BGRA; + config.output.u.RGBA.rgba = (uint8_t*)bmp->GetPixels(); + config.output.u.RGBA.size = bmp->GetBufferSize(); + config.output.u.RGBA.stride = bmp->GetPitch(); + config.output.is_external_memory = 1; + + (void)WebPDecode(bytes.GetBytes(), bytes.GetSize(), &config); + + return 0; +} diff --git a/source/common/textures/gametexture.cpp b/source/common/textures/gametexture.cpp index 20b22939d..2c873d15f 100644 --- a/source/common/textures/gametexture.cpp +++ b/source/common/textures/gametexture.cpp @@ -182,7 +182,7 @@ void FGameTexture::AddAutoMaterials() if (this->*(layer.pointer) == nullptr) // only if no explicit assignment had been done. { FStringf lookup("%s%s%s", layer.path, fullname ? "" : "auto/", searchname.GetChars()); - auto lump = fileSystem.CheckNumForFullName(lookup, false, ns_global, true); + auto lump = fileSystem.CheckNumForFullName(lookup, false, FileSys::ns_global, true); if (lump != -1) { auto bmtex = TexMan.FindGameTexture(fileSystem.GetFileFullName(lump), ETextureType::Any, FTextureManager::TEXMAN_TryAny); @@ -199,7 +199,7 @@ void FGameTexture::AddAutoMaterials() if (!this->Layers || this->Layers.get()->*(layer.pointer) == nullptr) // only if no explicit assignment had been done. { FStringf lookup("%s%s%s", layer.path, fullname ? "" : "auto/", searchname.GetChars()); - auto lump = fileSystem.CheckNumForFullName(lookup, false, ns_global, true); + auto lump = fileSystem.CheckNumForFullName(lookup, false, FileSys::ns_global, true); if (lump != -1) { auto bmtex = TexMan.FindGameTexture(fileSystem.GetFileFullName(lump), ETextureType::Any, FTextureManager::TEXMAN_TryAny); diff --git a/source/common/textures/image.cpp b/source/common/textures/image.cpp index e1939dfe1..b7812091d 100644 --- a/source/common/textures/image.cpp +++ b/source/common/textures/image.cpp @@ -51,6 +51,7 @@ struct PrecacheDataPaletted PalettedPixels Pixels; int RefCount; int ImageID; + int Frame; }; struct PrecacheDataRgba @@ -59,6 +60,7 @@ struct PrecacheDataRgba int TransInfo; int RefCount; int ImageID; + int Frame; }; // TMap doesn't handle this kind of data well. std::map neither. The linear search is still faster, even for a few 100 entries because it doesn't have to access the heap as often.. @@ -71,21 +73,21 @@ TArray precacheDataRgba; // //=========================================================================== -PalettedPixels FImageSource::CreatePalettedPixels(int conversion) +PalettedPixels FImageSource::CreatePalettedPixels(int conversion, int frame) { PalettedPixels Pixels(Width * Height); memset(Pixels.Data(), 0, Width * Height); return Pixels; } -PalettedPixels FImageSource::GetCachedPalettedPixels(int conversion) +PalettedPixels FImageSource::GetCachedPalettedPixels(int conversion, int frame) { PalettedPixels ret; auto imageID = ImageID; // Do we have this image in the cache? - unsigned index = conversion != normal? UINT_MAX : precacheDataPaletted.FindEx([=](PrecacheDataPaletted &entry) { return entry.ImageID == imageID; }); + unsigned index = conversion != normal? UINT_MAX : precacheDataPaletted.FindEx([=](PrecacheDataPaletted &entry) { return entry.ImageID == imageID && entry.Frame == frame; }); if (index < precacheDataPaletted.Size()) { auto cache = &precacheDataPaletted[index]; @@ -115,7 +117,7 @@ PalettedPixels FImageSource::GetCachedPalettedPixels(int conversion) { // This is either the only copy needed or some access outside the caching block. In these cases create a new one and directly return it. //Printf("returning fresh copy of %s\n", name.GetChars()); - return CreatePalettedPixels(conversion); + return CreatePalettedPixels(conversion, frame); } else { @@ -126,16 +128,16 @@ PalettedPixels FImageSource::GetCachedPalettedPixels(int conversion) pdp->ImageID = imageID; pdp->RefCount = info->second - 1; info->second = 0; - pdp->Pixels = CreatePalettedPixels(normal); + pdp->Pixels = CreatePalettedPixels(normal, frame); ret.Pixels.Set(pdp->Pixels.Data(), pdp->Pixels.Size()); } } return ret; } -TArray FImageSource::GetPalettedPixels(int conversion) +TArray FImageSource::GetPalettedPixels(int conversion, int frame) { - auto pix = GetCachedPalettedPixels(conversion); + auto pix = GetCachedPalettedPixels(conversion, frame); if (pix.ownsPixels()) { // return the pixel store of the returned data directly if this was the last reference. @@ -165,19 +167,19 @@ TArray FImageSource::GetPalettedPixels(int conversion) // //=========================================================================== -int FImageSource::CopyPixels(FBitmap *bmp, int conversion) +int FImageSource::CopyPixels(FBitmap *bmp, int conversion, int frame) { if (conversion == luminance) conversion = normal; // luminance images have no use as an RGB source. PalEntry *palette = GPalette.BaseColors; - auto ppix = CreatePalettedPixels(conversion); + auto ppix = CreatePalettedPixels(conversion, frame); bmp->CopyPixelData(0, 0, ppix.Data(), Width, Height, Height, 1, 0, palette, nullptr); return 0; } -int FImageSource::CopyTranslatedPixels(FBitmap *bmp, const PalEntry *remap) +int FImageSource::CopyTranslatedPixels(FBitmap *bmp, const PalEntry *remap, int frame) { - auto ppix = CreatePalettedPixels(normal); + auto ppix = CreatePalettedPixels(normal, frame); bmp->CopyPixelData(0, 0, ppix.Data(), Width, Height, Height, 1, 0, remap, nullptr); return 0; } @@ -188,26 +190,31 @@ int FImageSource::CopyTranslatedPixels(FBitmap *bmp, const PalEntry *remap) // //========================================================================== -FBitmap FImageSource::GetCachedBitmap(const PalEntry *remap, int conversion, int *ptrans) +FBitmap FImageSource::GetCachedBitmap(const PalEntry *remap, int conversion, int *ptrans, int frame) { FBitmap ret; int trans = -1; auto imageID = ImageID; + if (NumOfFrames == 1 && frame == 1) + { + frame = 0; + } + if (remap != nullptr) { // Remapped images are never run through the cache because they would complicate matters too much for very little gain. // Translated images are normally sprites which normally just consist of a single image and use no composition. // Additionally, since translation requires the base palette, the really time consuming stuff will never be subjected to it. ret.Create(Width, Height); - trans = CopyTranslatedPixels(&ret, remap); + trans = CopyTranslatedPixels(&ret, remap, frame); } else { if (conversion == luminance) conversion = normal; // luminance has no meaning for true color. // Do we have this image in the cache? - unsigned index = conversion != normal? UINT_MAX : precacheDataRgba.FindEx([=](PrecacheDataRgba &entry) { return entry.ImageID == imageID; }); + unsigned index = conversion != normal? UINT_MAX : precacheDataRgba.FindEx([=](PrecacheDataRgba &entry) { return entry.ImageID == imageID && entry.Frame == frame; }); if (index < precacheDataRgba.Size()) { auto cache = &precacheDataRgba[index]; @@ -230,7 +237,7 @@ FBitmap FImageSource::GetCachedBitmap(const PalEntry *remap, int conversion, int // This should never happen if the function is implemented correctly //Printf("something bad happened for %s, refcount = %d\n", name.GetChars(), cache->RefCount); ret.Create(Width, Height); - trans = CopyPixels(&ret, normal); + trans = CopyPixels(&ret, normal, frame); } } else @@ -242,7 +249,7 @@ FBitmap FImageSource::GetCachedBitmap(const PalEntry *remap, int conversion, int // This is either the only copy needed or some access outside the caching block. In these cases create a new one and directly return it. //Printf("returning fresh copy of %s\n", name.GetChars()); ret.Create(Width, Height); - trans = CopyPixels(&ret, conversion); + trans = CopyPixels(&ret, conversion, frame); } else { @@ -251,10 +258,11 @@ FBitmap FImageSource::GetCachedBitmap(const PalEntry *remap, int conversion, int PrecacheDataRgba *pdr = &precacheDataRgba[precacheDataRgba.Reserve(1)]; pdr->ImageID = imageID; + pdr->Frame = frame; pdr->RefCount = info->first - 1; info->first = 0; pdr->Pixels.Create(Width, Height); - trans = pdr->TransInfo = CopyPixels(&pdr->Pixels, normal); + trans = pdr->TransInfo = CopyPixels(&pdr->Pixels, normal, frame); ret.Copy(pdr->Pixels, false); } } diff --git a/source/common/textures/image.h b/source/common/textures/image.h index 5be852549..f9e761a20 100644 --- a/source/common/textures/image.h +++ b/source/common/textures/image.h @@ -67,12 +67,13 @@ protected: int LeftOffset = 0, TopOffset = 0; // Offsets stored in the image. bool bUseGamePalette = false; // true if this is an image without its own color set. int ImageID = -1; + int NumOfFrames = 1; // Internal image creation functions. All external access should go through the cache interface, // so that all code can benefit from future improvements to that. - virtual PalettedPixels CreatePalettedPixels(int conversion); - int CopyTranslatedPixels(FBitmap *bmp, const PalEntry *remap); + virtual PalettedPixels CreatePalettedPixels(int conversion, int frame = 0); + int CopyTranslatedPixels(FBitmap *bmp, const PalEntry *remap, int frame = 0); public: @@ -101,19 +102,25 @@ public: // 'noremap0' will only be looked at by FPatchTexture and forwarded by FMultipatchTexture. // Either returns a reference to the cache, or a newly created item. The return of this has to be considered transient. If you need to store the result, use GetPalettedPixels - PalettedPixels GetCachedPalettedPixels(int conversion); + PalettedPixels GetCachedPalettedPixels(int conversion, int frame = 0); // tries to get a buffer from the cache. If not available, create a new one. If further references are pending, create a copy. - TArray GetPalettedPixels(int conversion); + TArray GetPalettedPixels(int conversion, int frame = 0); - virtual int CopyPixels(FBitmap* bmp, int conversion); + virtual int CopyPixels(FBitmap* bmp, int conversion, int frame = 0); - FBitmap GetCachedBitmap(const PalEntry *remap, int conversion, int *trans = nullptr); + FBitmap GetCachedBitmap(const PalEntry *remap, int conversion, int *trans = nullptr, int frame = 0); static void ClearImages() { ImageArena.FreeAll(); ImageForLump.Clear(); NextID = 0; } static FImageSource * GetImage(int lumpnum, bool checkflat); + // Frame functions + // Gets number of frames. + int GetNumOfFrames() { return NumOfFrames; } + + // Gets duration of frame in miliseconds. + virtual int GetDurationOfFrame(int frame) { return 1000; } // Conversion option enum EType @@ -180,8 +187,8 @@ class FBuildTexture : public FImageSource { public: FBuildTexture(const FString& pathprefix, int tilenum, const uint8_t* pixels, FRemapTable* translation, int width, int height, int left, int top); - PalettedPixels CreatePalettedPixels(int conversion) override; - int CopyPixels(FBitmap* bmp, int conversion) override; + PalettedPixels CreatePalettedPixels(int conversion, int frame = 0) override; + int CopyPixels(FBitmap* bmp, int conversion, int frame = 0) override; protected: const uint8_t* RawPixels; @@ -191,4 +198,4 @@ protected: class FTexture; -FTexture* CreateImageTexture(FImageSource* img) noexcept; +FTexture* CreateImageTexture(FImageSource* img, int frame = 0) noexcept; diff --git a/source/common/textures/imagetexture.cpp b/source/common/textures/imagetexture.cpp index d94ff8002..233cf4b09 100644 --- a/source/common/textures/imagetexture.cpp +++ b/source/common/textures/imagetexture.cpp @@ -47,10 +47,11 @@ // //========================================================================== -FImageTexture::FImageTexture(FImageSource *img) noexcept +FImageTexture::FImageTexture(FImageSource *img, int frame) noexcept : FTexture(img? img->LumpNum() : 0) { mImage = img; + TexFrame = frame; if (img != nullptr) { SetFromImage(); @@ -79,7 +80,7 @@ void FImageTexture::SetFromImage() FBitmap FImageTexture::GetBgraBitmap(const PalEntry *p, int *trans) { - return mImage->GetCachedBitmap(p, bNoRemap0? FImageSource::noremap0 : FImageSource::normal, trans); + return mImage->GetCachedBitmap(p, bNoRemap0? FImageSource::noremap0 : FImageSource::normal, trans, TexFrame); } //=========================================================================== @@ -90,7 +91,7 @@ FBitmap FImageTexture::GetBgraBitmap(const PalEntry *p, int *trans) TArray FImageTexture::Get8BitPixels(bool alpha) { - return mImage->GetPalettedPixels(alpha? FImageSource::luminance : bNoRemap0 ? FImageSource::noremap0 : FImageSource::normal); + return mImage->GetPalettedPixels(alpha? FImageSource::luminance : bNoRemap0 ? FImageSource::noremap0 : FImageSource::normal, TexFrame); } //=========================================================================== @@ -113,8 +114,8 @@ bool FImageTexture::DetermineTranslucency() } -FTexture* CreateImageTexture(FImageSource* img) noexcept +FTexture* CreateImageTexture(FImageSource* img, int frame) noexcept { - return new FImageTexture(img); + return new FImageTexture(img, frame); } diff --git a/source/common/textures/m_png.h b/source/common/textures/m_png.h index 2f52a1fcf..f65de4c0d 100644 --- a/source/common/textures/m_png.h +++ b/source/common/textures/m_png.h @@ -47,7 +47,6 @@ enum ESSType SS_BGRA }; -class FileWriter; // PNG Writing -------------------------------------------------------------- // Start writing an 8-bit palettized PNG file. @@ -82,13 +81,13 @@ struct PNGHandle uint32_t Size; }; - FileReader File; + FileSys::FileReader File; bool bDeleteFilePtr; TArray Chunks; TArray TextChunks; unsigned int ChunkPt; - PNGHandle(FileReader &file); + PNGHandle(FileSys::FileReader &file); ~PNGHandle(); }; @@ -96,7 +95,7 @@ struct PNGHandle // the signature, but also checking for the IEND chunk. CRC checking of // each chunk is not done. If it is valid, you get a PNGHandle to pass to // the following functions. -PNGHandle *M_VerifyPNG (FileReader &file); +PNGHandle *M_VerifyPNG (FileSys::FileReader &file); // Finds a chunk in a PNG file. The file pointer will be positioned at the // beginning of the chunk data, and its length will be returned. A return @@ -115,7 +114,7 @@ bool M_GetPNGText (PNGHandle *png, const char *keyword, char *buffer, size_t buf // The file must be positioned at the start of the first IDAT. It reads // image data into the provided buffer. Returns true on success. -bool M_ReadIDAT (FileReader &file, uint8_t *buffer, int width, int height, int pitch, +bool M_ReadIDAT (FileSys::FileReader &file, uint8_t *buffer, int width, int height, int pitch, uint8_t bitdepth, uint8_t colortype, uint8_t interlace, unsigned int idatlen); diff --git a/source/common/textures/multipatchtexturebuilder.cpp b/source/common/textures/multipatchtexturebuilder.cpp index 201398ee8..c032372c3 100644 --- a/source/common/textures/multipatchtexturebuilder.cpp +++ b/source/common/textures/multipatchtexturebuilder.cpp @@ -397,12 +397,12 @@ void FMultipatchTextureBuilder::AddTexturesLumps(int lump1, int lump2, int patch if (lump1 >= 0) { - FileData texdir = fileSystem.ReadFile(lump1); + auto texdir = fileSystem.ReadFile(lump1); AddTexturesLump(texdir.GetMem(), fileSystem.FileLength(lump1), lump1, patcheslump, firstdup, true); } if (lump2 >= 0) { - FileData texdir = fileSystem.ReadFile(lump2); + auto texdir = fileSystem.ReadFile(lump2); AddTexturesLump(texdir.GetMem(), fileSystem.FileLength(lump2), lump2, patcheslump, firstdup, false); } } diff --git a/source/common/textures/texturemanager.cpp b/source/common/textures/texturemanager.cpp index 5bf3e173d..c2ebe6249 100644 --- a/source/common/textures/texturemanager.cpp +++ b/source/common/textures/texturemanager.cpp @@ -50,6 +50,7 @@ #include "basics.h" #include "cmdlib.h" +using namespace FileSys; FTextureManager TexMan; @@ -681,15 +682,15 @@ void FTextureManager::AddHiresTextures (int wadnum) void FTextureManager::LoadTextureDefs(int wadnum, const char *lumpname, FMultipatchTextureBuilder &build) { - int remapLump, lastLump; + int texLump, lastLump; lastLump = 0; - while ((remapLump = fileSystem.FindLump(lumpname, &lastLump)) != -1) + while ((texLump = fileSystem.FindLump(lumpname, &lastLump)) != -1) { - if (fileSystem.GetFileContainer(remapLump) == wadnum) + if (fileSystem.GetFileContainer(texLump) == wadnum) { - ParseTextureDef(remapLump, build); + ParseTextureDef(texLump, build); } } } diff --git a/source/common/textures/textures.h b/source/common/textures/textures.h index 0d88f3843..164aa79b8 100644 --- a/source/common/textures/textures.h +++ b/source/common/textures/textures.h @@ -379,10 +379,11 @@ class FImageTexture : public FTexture { FImageSource* mImage; bool bNoRemap0 = false; + int TexFrame = 0; protected: void SetFromImage(); public: - FImageTexture(FImageSource* image) noexcept; + FImageTexture(FImageSource* image, int frame = 0) noexcept; ~FImageTexture(); TArray Get8BitPixels(bool alphatex) override; diff --git a/source/common/utility/cmdlib.cpp b/source/common/utility/cmdlib.cpp index b93c24d7b..8dbce2b7a 100644 --- a/source/common/utility/cmdlib.cpp +++ b/source/common/utility/cmdlib.cpp @@ -1018,11 +1018,8 @@ void uppercopy(char* to, const char* from) FString GetStringFromLump(int lump) { - FString ScriptBuffer; - auto mem = fileSystem.OpenFileReader(lump); - auto buff = ScriptBuffer.LockNewBuffer(mem.GetLength()); - mem.Read(buff, mem.GetLength()); - buff[mem.GetLength()] = 0; - ScriptBuffer.UnlockBuffer(); + auto fd = fileSystem.ReadFile(lump); + FString ScriptBuffer(fd.GetString(), fd.GetSize()); + ScriptBuffer.Truncate(strlen(ScriptBuffer.GetChars())); // this is necessary to properly truncate the generated string to not contain 0 bytes. return ScriptBuffer; } diff --git a/source/common/utility/cmdlib.h b/source/common/utility/cmdlib.h index 9d94d0d3f..06b5a5e0f 100644 --- a/source/common/utility/cmdlib.h +++ b/source/common/utility/cmdlib.h @@ -12,6 +12,7 @@ #include #include #include "zstring.h" +#include "files.h" #if !defined(GUID_DEFINED) #define GUID_DEFINED @@ -82,7 +83,6 @@ inline constexpr double Scale(double a, double b, double c) return (a * b) / c; } -class FileReader; struct MD5Context; void md5Update(FileReader& file, MD5Context& md5, unsigned len); diff --git a/source/common/utility/filereadermusicinterface.h b/source/common/utility/filereadermusicinterface.h index f261f9dd0..633599b63 100644 --- a/source/common/utility/filereadermusicinterface.h +++ b/source/common/utility/filereadermusicinterface.h @@ -6,6 +6,7 @@ inline ZMusicCustomReader *GetMusicReader(FileReader& fr) { + using FileSys::FileReaderInterface; auto zcr = new ZMusicCustomReader; zcr->handle = fr.GetInterface(); diff --git a/source/common/utility/findfile.cpp b/source/common/utility/findfile.cpp index cb82b89a1..e2c2ee707 100644 --- a/source/common/utility/findfile.cpp +++ b/source/common/utility/findfile.cpp @@ -40,6 +40,9 @@ #include "i_system.h" #include "fs_findfile.h" +#ifdef __unix__ +#include +#endif // __unix__ //========================================================================== // @@ -139,8 +142,11 @@ void D_AddWildFile(std::vector& wadfiles, const char* value, const else { // Try pattern matching - FileList list; - if (ScanDirectory(list, value, "*", true)) + FileSys::FileList list; + auto path = ExtractFilePath(value); + auto name = ExtractFileBase(value, true); + if (path.IsEmpty()) path = "."; + if (FileSys::ScanDirectory(list, path, name, true)) { for(auto& entry : list) { @@ -190,8 +196,8 @@ void D_AddConfigFiles(std::vector& wadfiles, const char* section, c void D_AddDirectory(std::vector& wadfiles, const char* dir, const char *filespec, FConfigFile* config) { - FileList list; - if (ScanDirectory(list, dir, "*.wad", true)) + FileSys::FileList list; + if (FileSys::ScanDirectory(list, dir, "*.wad", true)) { for (auto& entry : list) { diff --git a/source/common/utility/palette.cpp b/source/common/utility/palette.cpp index 178db734b..0b5cca67b 100644 --- a/source/common/utility/palette.cpp +++ b/source/common/utility/palette.cpp @@ -929,7 +929,7 @@ int ReadPalette(int lumpnum, uint8_t* buffer) { return 0; } - FileData lump = fileSystem.ReadFile(lumpnum); + auto lump = fileSystem.ReadFile(lumpnum); auto lumpmem = lump.GetBytes(); memset(buffer, 0, 768); diff --git a/source/common/utility/s_playlist.h b/source/common/utility/s_playlist.h index 5bd5fd55e..84d2040b0 100644 --- a/source/common/utility/s_playlist.h +++ b/source/common/utility/s_playlist.h @@ -34,7 +34,7 @@ #ifndef __S_PLAYLIST_H__ #define __S_PLAYLIST_H__ -class FileReader; +#include "files.h" class FPlayList { diff --git a/source/common/utility/zstring.h b/source/common/utility/zstring.h index b12f11fa5..7777bbf61 100644 --- a/source/common/utility/zstring.h +++ b/source/common/utility/zstring.h @@ -40,6 +40,7 @@ #include #include "tarray.h" #include "utf8.h" +#include "filesystem.h" #ifdef __GNUC__ #define PRINTFISH(x) __attribute__((format(printf, 2, x))) diff --git a/source/core/g_mapinfo.h b/source/core/g_mapinfo.h index 7527f3be5..d3b7294b7 100644 --- a/source/core/g_mapinfo.h +++ b/source/core/g_mapinfo.h @@ -37,7 +37,6 @@ #include "autosegs.h" #include "vectors.h" #include "sc_man.h" -#include "file_zip.h" #include "actorinfo.h" struct SpawnRec diff --git a/source/core/initfs.cpp b/source/core/initfs.cpp index 29372fcfe..88b61a4fa 100644 --- a/source/core/initfs.cpp +++ b/source/core/initfs.cpp @@ -48,6 +48,8 @@ #include "palutil.h" #include "startupinfo.h" +using namespace FileSys; + #ifndef PATH_MAX #define PATH_MAX 260 #endif @@ -189,7 +191,7 @@ static std::vector CheckGameInfo(std::vector& pwads) if (FName(lmp->getName(), true) == gameinfo) { // Found one! - auto bases = ParseGameInfo(pwads, resfile->FileName.c_str(), (const char*)lmp->Lock(), lmp->LumpSize); + auto bases = ParseGameInfo(pwads, resfile->FileName, (const char*)lmp->Lock(), lmp->LumpSize); delete resfile; return bases; } diff --git a/source/core/maphack.cpp b/source/core/maphack.cpp index 103ea1aa3..a0fd212ea 100644 --- a/source/core/maphack.cpp +++ b/source/core/maphack.cpp @@ -320,7 +320,7 @@ CCMD(md4sum) { auto data = fr.Read(); uint8_t digest[16]; - md4once(data.data(), data.size(), digest); + md4once(data.data(), (uint32_t)data.size(), digest); for (int j = 0; j < 16; ++j) { Printf("%02x", digest[j]); diff --git a/source/core/menu/loadsavemenu.cpp b/source/core/menu/loadsavemenu.cpp index fd332351d..24d966d9c 100644 --- a/source/core/menu/loadsavemenu.cpp +++ b/source/core/menu/loadsavemenu.cpp @@ -48,6 +48,7 @@ #include "fs_findfile.h" #include "savegamehelp.h" +using namespace FileSys; //============================================================================= // // M_ReadSaveStrings diff --git a/source/core/music/s_advsound.cpp b/source/core/music/s_advsound.cpp index 96fbbca23..af240d3ea 100644 --- a/source/core/music/s_advsound.cpp +++ b/source/core/music/s_advsound.cpp @@ -158,7 +158,7 @@ static FSoundID S_AddSound(const char* logicalname, int lumpnum, FScanner* sc) FSoundID S_AddSound(const char* logicalname, const char* lumpname, FScanner* sc) { - int lump = fileSystem.CheckNumForFullName(lumpname, true, ns_sounds); + int lump = fileSystem.CheckNumForFullName(lumpname, true, FileSys::ns_sounds); if (lump == -1 && sc && fileSystem.GetFileContainer(sc->LumpNum) > fileSystem.GetMaxIwadNum()) sc->ScriptMessage("%s: sound file not found", sc->String); return S_AddSound(logicalname, lump, sc); diff --git a/source/core/palette.h b/source/core/palette.h index bf395aee8..c6919128e 100644 --- a/source/core/palette.h +++ b/source/core/palette.h @@ -97,7 +97,7 @@ struct LookupTableInfo void makeTable(int palnum, const uint8_t* remapbuf, int r, int g, int b, bool noFloorPal); int setTable(int palnum, const uint8_t* remap); void postLoadTables(); - int loadTable(FileReader& fp); + int loadTable(FileSys::FileReader& fp); void postLoadLookups(); void setupDefaultFog(); diff --git a/source/core/raze_music.cpp b/source/core/raze_music.cpp index 7a1f16e2a..c3499d843 100644 --- a/source/core/raze_music.cpp +++ b/source/core/raze_music.cpp @@ -104,7 +104,7 @@ int LookupMusic(const char* fn, bool onlyextended) int l = fileSystem.FindFileWithExtensions(name, knownMusicExts, countof(knownMusicExts)); if (l >= 0 || onlyextended) return l; } - return fileSystem.CheckNumForFullName(fn, true, ns_music); + return fileSystem.CheckNumForFullName(fn, true, FileSys::ns_music); } //========================================================================== diff --git a/source/core/savegamehelp.cpp b/source/core/savegamehelp.cpp index f29f1b47a..db77d0bd6 100644 --- a/source/core/savegamehelp.cpp +++ b/source/core/savegamehelp.cpp @@ -132,7 +132,7 @@ bool ReadSavegame(const char* name) } file.Close(); - FResourceLump* info = savereader->FindLump("session.json"); + auto info = savereader->FindLump("session.json"); if (info == nullptr) { delete savereader; @@ -223,9 +223,9 @@ bool WriteSavegame(const char* filename, const char *name) M_FinishPNG(&savepic); auto picdata = savepic.GetBuffer(); - FCompressedBuffer bufpng = { picdata->Size(), picdata->Size(), METHOD_STORED, 0, static_cast(crc32(0, &(*picdata)[0], picdata->Size())), (char*)&(*picdata)[0] }; + FileSys::FCompressedBuffer bufpng = { picdata->Size(), picdata->Size(), FileSys::METHOD_STORED, 0, static_cast(crc32(0, &(*picdata)[0], picdata->Size())), (char*)&(*picdata)[0] }; - TArray savegame_content; + TArray savegame_content; TArray savegame_filenames; savegame_content.Push(bufpng); diff --git a/source/core/searchpaths.cpp b/source/core/searchpaths.cpp index 0cfbd0772..cc5d906a0 100644 --- a/source/core/searchpaths.cpp +++ b/source/core/searchpaths.cpp @@ -190,8 +190,8 @@ void CollectSubdirectories(TArray &searchpath, const char *dirmatch) FString AbsPath = M_GetNormalizedPath(dirpath); if (DirExists(AbsPath)) { - FileList list; - if (ScanDirectory(list, AbsPath, "*", true)) + FileSys::FileList list; + if (FileSys::ScanDirectory(list, AbsPath, "*", true)) { for (auto& entry : list) { @@ -304,8 +304,8 @@ TArray CollectAllFilesInSearchPath() { if (DirExists(path)) { - FileList list; - if (ScanDirectory(list, path, "*", true)) + FileSys::FileList list; + if (FileSys::ScanDirectory(list, path, "*", true)) { for (auto& entry : list) { diff --git a/source/games/blood/src/sound.cpp b/source/games/blood/src/sound.cpp index e6a214870..c7def7036 100644 --- a/source/games/blood/src/sound.cpp +++ b/source/games/blood/src/sound.cpp @@ -144,7 +144,7 @@ void sndInit(void) } else if (!stricmp(type, "WAV") || !stricmp(type, "OGG") || !stricmp(type, "FLAC") || !stricmp(type, "VOC")) { - if (fileSystem.GetFileNamespace(i) != ns_music) + if (fileSystem.GetFileNamespace(i) != FileSys::ns_music) soundEngine->AddSoundLump(fileSystem.GetFileFullName(i), i, 0, fileSystem.GetResourceId(i) | 0x40000000, 6); // mark the resource ID as special. } }