- Backend update from GZDoom-

This compiles but doesn't run.
This commit is contained in:
Christoph Oelckers 2023-08-23 20:36:19 +02:00
parent f2740e434a
commit 82057bcd5a
117 changed files with 1218 additions and 763 deletions

View file

@ -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)

View file

@ -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());
}

View file

@ -40,10 +40,9 @@
#include "i_system.h"
#include "filereadermusicinterface.h"
#include <zmusic.h>
#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)
{

View file

@ -148,7 +148,7 @@ class FSoundFontManager
{
TArray<FSoundFontInfo> soundfonts;
void ProcessOneFile(const FString & fn);
void ProcessOneFile(const char* fn);
public:
void CollectSoundfonts();

View file

@ -55,6 +55,7 @@
#include "i_specialpaths.h"
#include "configfile.h"
#include "c_cvars.h"
#include "md5.h"
// EXTERNAL FUNCTION PROTOTYPES --------------------------------------------

View file

@ -5,9 +5,9 @@
#include "zstring.h"
#include "tarray.h"
#include "name.h"
#include "files.h"
#include <zmusic.h>
class FileReader;
class SoundStream;

View file

@ -40,8 +40,8 @@
#include "i_soundinternal.h"
#include "zstring.h"
#include <zmusic.h>
#include "files.h"
class FileReader;
struct FSoundChan;
enum EStartSoundFlags

View file

@ -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 <dir>\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 <dir>\n", entry.FileName.c_str());
else
Printf ("%s\n", entry.FileName.c_str());
}
}
}
#endif
//==========================================================================
//

View file

@ -0,0 +1,6 @@
#pragma once
#include "fs_files.h"
using FileSys::FileReader;
using FileSys::FileWriter;
using FileSys::BufferWriter;

View file

@ -0,0 +1,7 @@
#pragma once
#include "fs_filesystem.h"
using FileSys::FileSystem;
using FileSys::FResourceFile;
inline FileSys::FileSystem fileSystem;

View file

@ -3,8 +3,7 @@
#include <stdint.h>
#include "memarena.h"
#include "palentry.h"
class FileReader;
#include "files.h"
enum
{

View file

@ -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.

View file

@ -4,7 +4,6 @@
#include <stdint.h>
#include <type_traits>
#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.

View file

@ -41,10 +41,13 @@
#include <stdint.h>
#include <stdarg.h>
#include <functional>
#include <vector>
#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<uint8_t> Read(size_t len)
{
std::vector<uint8_t> 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<uint8_t> 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<unsigned char>&& TakeBuffer() { return std::move(mBuffer); }
};
}
#endif

View file

@ -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;
}

View file

@ -5,6 +5,8 @@
#include <vector>
#include <string>
namespace FileSys {
struct FileListEntry
{
std::string FileName; // file name only
@ -34,3 +36,4 @@ inline void FixPathSeparator(char* path)
}
}
}

View file

@ -17,9 +17,9 @@
#include <libkern/OSByteOrder.h>
#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__

View file

@ -6,8 +6,11 @@
#include <limits.h>
#include <vector>
#include <string>
#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<FUncompressedLump> 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

View file

@ -46,6 +46,8 @@
#include <stdlib.h>
#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;
}
}

View file

@ -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);
int ShrinkLoop(unsigned char *out, unsigned int outsize, FileReader &in, unsigned int insize);
}

View file

@ -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<int>(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
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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*
}
}

View file

@ -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;
}
}

View file

@ -35,11 +35,11 @@
#include <ctype.h>
#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;
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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

View file

@ -34,10 +34,10 @@
*/
#include <string>
#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;
}
}

View file

@ -41,7 +41,30 @@
#include <algorithm>
#include <stdexcept>
#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
}
}
}

View file

@ -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; }
};
}

View file

@ -41,10 +41,14 @@
#include <ctype.h>
#include <string.h>
#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<std::string>& 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<FolderEntr
result.clear();
for (size_t i = 0; i < FileInfo.size(); i++)
{
if (FileInfo[i].longName.find_first_of(path) == 0)
if (strncmp(FileInfo[i].LongName, path.c_str(), path.length()) == 0)
{
// Only if it hasn't been replaced.
if ((unsigned)fileSystem.CheckNumForFullName(FileInfo[i].longName.c_str()) == i)
if ((unsigned)CheckNumForFullName(FileInfo[i].LongName) == i)
{
FolderEntry fe{ FileInfo[i].longName.c_str(), (uint32_t)i };
FolderEntry fe{ FileInfo[i].LongName, (uint32_t)i };
result.push_back(fe);
}
}
@ -1261,13 +1281,13 @@ unsigned FileSystem::GetFilesInFolder(const char *inpath, std::vector<FolderEntr
// Find the highest resource file having content in the given folder.
for (auto & entry : result)
{
int thisfile = fileSystem.GetFileContainer(entry.lumpnum);
int thisfile = GetFileContainer(entry.lumpnum);
if (thisfile > 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;
}
}

View file

@ -33,9 +33,11 @@
*/
#include "fs_findfile.h"
#include <string.h>
#include <vector>
namespace FileSys {
enum
{
ZPATH_MAX = 260
@ -61,6 +63,8 @@ enum
#ifndef _WIN32
#include <limits.h>
#include <stdlib.h>
#include <unistd.h>
#include <fnmatch.h>
#include <sys/stat.h>
@ -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<FileListEntry>& 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;
}
}

View file

@ -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 <stdlib.h>
#include <stdint.h>
#include <string.h>
#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;
}
}

View file

@ -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;
};
}

View file

@ -69,7 +69,7 @@
#include <stddef.h>
#include <cstring>
namespace fs_private {
namespace FileSys {
/// Provides MD5 hashing functionality
namespace md5 {

View file

@ -35,9 +35,13 @@
*/
#include <zlib.h>
#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()
}
}

View file

@ -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<FUncompressedLump> 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;
};
}

View file

@ -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

View file

@ -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<FolderEntry> folderdata;
std::vector<FileSys::FolderEntry> folderdata;
if (filetemplate != nullptr)
{
FStringf path("fonts/%s/", filetemplate);
@ -398,7 +398,7 @@ public:
}
};
void FFont::ReadSheetFont(std::vector<FolderEntry> &folderdata, int width, int height, const DVector2 &Scale)
void FFont::ReadSheetFont(std::vector<FileSys::FolderEntry> &folderdata, int width, int height, const DVector2 &Scale)
{
TMap<int, FGameTexture*> charMap;
int minchar = INT_MAX;

View file

@ -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;

View file

@ -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;

View file

@ -109,7 +109,7 @@ FFont *V_GetFont(const char *name, const char *fontlumpname)
int lump = -1;
int folderfile = -1;
std::vector<FolderEntry> folderdata;
std::vector<FileSys::FolderEntry> folderdata;
FStringf path("fonts/%s/", name);
// Use a folder-based font only if it comes from a later file than the single lump version.

View file

@ -175,7 +175,7 @@ protected:
void FixXMoves();
void ReadSheetFont(std::vector<FolderEntry> &folderdata, int width, int height, const DVector2 &Scale);
void ReadSheetFont(std::vector<FileSys::FolderEntry> &folderdata, int width, int height, const DVector2 &Scale);
EFontType Type = EFontType::Unknown;
FName AltFontName = NAME_None;

View file

@ -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)
{

View file

@ -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;

View file

@ -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 )

View file

@ -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);

View file

@ -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];

View file

@ -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));

View file

@ -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);

View file

@ -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];

View file

@ -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);

View file

@ -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;
}

View file

@ -171,6 +171,17 @@ unsigned int I_MakeRNGSeed()
return static_cast<unsigned int>(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];

View file

@ -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()
{

View file

@ -958,6 +958,25 @@ void I_SetThreadNumaNode(std::thread &thread, int numaNode)
}
}
FString I_GetCWD()
{
auto len = GetCurrentDirectoryW(0, nullptr);
TArray<wchar_t> 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);

View file

@ -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

View file

@ -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)

View file

@ -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)

View file

@ -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;

View file

@ -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);
}

View file

@ -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);

View file

@ -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");

View file

@ -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)

View file

@ -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];

View file

@ -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);

View file

@ -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;

View file

@ -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);

View file

@ -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);

View file

@ -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);

View file

@ -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);

View file

@ -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);

View file

@ -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)
{

View file

@ -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);

View file

@ -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];

View file

@ -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;

View file

@ -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;

View file

@ -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);

View file

@ -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;

View file

@ -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];

View file

@ -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
{

View file

@ -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];

View file

@ -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;

View file

@ -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;

View file

@ -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<uint8_t> source(64000, true);
memset(source.Data(), 0xF0, 64000);

View file

@ -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;

View file

@ -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);

View file

@ -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;
}

View file

@ -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);

View file

@ -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> 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<uint8_t> FImageSource::GetPalettedPixels(int conversion)
TArray<uint8_t> 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<uint8_t> 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);
}
}

View file

@ -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<uint8_t> GetPalettedPixels(int conversion);
TArray<uint8_t> 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;

View file

@ -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<uint8_t> 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);
}

View file

@ -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<Chunk> Chunks;
TArray<char *> 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);

View file

@ -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);
}
}

View file

@ -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);
}
}
}

View file

@ -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<uint8_t> Get8BitPixels(bool alphatex) override;

Some files were not shown because too many files have changed in this diff Show more