mirror of
https://github.com/ZDoom/Raze.git
synced 2025-01-18 22:51:50 +00:00
- file system update and adjustment.
This commit is contained in:
parent
ac32194079
commit
5584c726ba
98 changed files with 3406 additions and 2051 deletions
|
@ -588,7 +588,6 @@ file( GLOB HEADER_FILES
|
||||||
core/utility/*.h
|
core/utility/*.h
|
||||||
core/utility/rapidjson/*.h
|
core/utility/rapidjson/*.h
|
||||||
core/console/*.h
|
core/console/*.h
|
||||||
core/filesystem/*.h
|
|
||||||
core/music/*.h
|
core/music/*.h
|
||||||
core/sound/*.h
|
core/sound/*.h
|
||||||
core/sound/backend/*.h
|
core/sound/backend/*.h
|
||||||
|
@ -604,6 +603,7 @@ file( GLOB HEADER_FILES
|
||||||
core/rendering/hwrenderer/utility/*.h
|
core/rendering/hwrenderer/utility/*.h
|
||||||
|
|
||||||
common/utility/*.h
|
common/utility/*.h
|
||||||
|
common/filesystem/*.h
|
||||||
common/thirdparty/*.h
|
common/thirdparty/*.h
|
||||||
common/thirdparty/rapidjson/*.h
|
common/thirdparty/rapidjson/*.h
|
||||||
common/thirdparty/math./*h
|
common/thirdparty/math./*h
|
||||||
|
@ -737,6 +737,18 @@ set (PCH_SOURCES
|
||||||
common/utility/zstrformat.cpp
|
common/utility/zstrformat.cpp
|
||||||
common/thirdparty/md5.cpp
|
common/thirdparty/md5.cpp
|
||||||
common/thirdparty/superfasthash.cpp
|
common/thirdparty/superfasthash.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_directory.cpp
|
||||||
|
common/filesystem/resourcefile.cpp
|
||||||
|
|
||||||
core/utility/name.cpp
|
core/utility/name.cpp
|
||||||
core/utility/m_png.cpp
|
core/utility/m_png.cpp
|
||||||
|
@ -744,17 +756,6 @@ set (PCH_SOURCES
|
||||||
core/utility/stringtable.cpp
|
core/utility/stringtable.cpp
|
||||||
core/utility/stats.cpp
|
core/utility/stats.cpp
|
||||||
|
|
||||||
core/filesystem/filesystem.cpp
|
|
||||||
core/filesystem/ancientzip.cpp
|
|
||||||
core/filesystem/file_zip.cpp
|
|
||||||
core/filesystem/file_7z.cpp
|
|
||||||
core/filesystem/file_grp.cpp
|
|
||||||
core/filesystem/file_rff.cpp
|
|
||||||
core/filesystem/file_pak.cpp
|
|
||||||
core/filesystem/file_lump.cpp
|
|
||||||
core/filesystem/file_directory.cpp
|
|
||||||
core/filesystem/resourcefile.cpp
|
|
||||||
|
|
||||||
core/textures/bitmap.cpp
|
core/textures/bitmap.cpp
|
||||||
core/textures/buildtiles.cpp
|
core/textures/buildtiles.cpp
|
||||||
core/textures/texture.cpp
|
core/textures/texture.cpp
|
||||||
|
@ -893,7 +894,6 @@ include_directories(
|
||||||
core/utility
|
core/utility
|
||||||
core/console
|
core/console
|
||||||
core/textures
|
core/textures
|
||||||
core/filesystem
|
|
||||||
core/music
|
core/music
|
||||||
core/sound
|
core/sound
|
||||||
core/sound/backend
|
core/sound/backend
|
||||||
|
@ -910,6 +910,7 @@ include_directories(
|
||||||
core/rendering
|
core/rendering
|
||||||
platform
|
platform
|
||||||
common/thirdparty
|
common/thirdparty
|
||||||
|
common/filesystem
|
||||||
common/utility
|
common/utility
|
||||||
|
|
||||||
${CMAKE_BINARY_DIR}/libraries/gdtoa
|
${CMAKE_BINARY_DIR}/libraries/gdtoa
|
||||||
|
@ -1008,7 +1009,6 @@ source_group("Core\\Utility" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/co
|
||||||
source_group("Core\\2D" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/core/2d/.+")
|
source_group("Core\\2D" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/core/2d/.+")
|
||||||
source_group("Core\\Console" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/core/console/.+")
|
source_group("Core\\Console" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/core/console/.+")
|
||||||
source_group("Core\\Fonts" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/core/fonts/.+")
|
source_group("Core\\Fonts" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/core/fonts/.+")
|
||||||
source_group("Core\\File System" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/core/filesystem/.+")
|
|
||||||
source_group("Core\\Music" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/core/music/.+")
|
source_group("Core\\Music" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/core/music/.+")
|
||||||
source_group("Core\\Sound" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/core/sound/.+")
|
source_group("Core\\Sound" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/core/sound/.+")
|
||||||
source_group("Core\\Sound\\Backend" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/core/sound/backend/.+")
|
source_group("Core\\Sound\\Backend" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/core/sound/backend/.+")
|
||||||
|
@ -1021,6 +1021,7 @@ source_group("Platform" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/platfor
|
||||||
source_group("Platform\\Win32" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/platform/win32/.+")
|
source_group("Platform\\Win32" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/platform/win32/.+")
|
||||||
source_group("Platform\\POSIX" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/platform/posix/.+")
|
source_group("Platform\\POSIX" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/platform/posix/.+")
|
||||||
source_group("Common" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/.+")
|
source_group("Common" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/.+")
|
||||||
|
source_group("Common\\File System" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/filesystem/.+")
|
||||||
source_group("Common\\Utility" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/utility/.+")
|
source_group("Common\\Utility" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/utility/.+")
|
||||||
source_group("Common\\Third Party" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/thirdparty/.+")
|
source_group("Common\\Third Party" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/thirdparty/.+")
|
||||||
source_group("Common\\Third Party\\Math" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/thirdparty/math/.+")
|
source_group("Common\\Third Party\\Math" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/thirdparty/math/.+")
|
||||||
|
|
|
@ -29,10 +29,14 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
#include "globals.h"
|
#include "globals.h"
|
||||||
#include "sound.h"
|
#include "sound.h"
|
||||||
#include "filesystem/resourcefile.h"
|
#include "filesystem.h"
|
||||||
|
|
||||||
BEGIN_BLD_NS
|
BEGIN_BLD_NS
|
||||||
|
|
||||||
|
// I don't think we still need these.
|
||||||
|
#define DICT_LOAD 0
|
||||||
|
#define DICT_LOCK 0
|
||||||
|
|
||||||
static Resource gBarfRes;
|
static Resource gBarfRes;
|
||||||
|
|
||||||
#define kMaxCmdLineDefines 5
|
#define kMaxCmdLineDefines 5
|
||||||
|
@ -905,12 +909,12 @@ void ReadAllRFS()
|
||||||
for (int i = 0; i < numf; i++)
|
for (int i = 0; i < numf; i++)
|
||||||
{
|
{
|
||||||
auto rl = fileSystem.GetResourceType(i);
|
auto rl = fileSystem.GetResourceType(i);
|
||||||
if (rl == NAME_RFS)
|
if (!stricmp(rl, "RFS"))
|
||||||
{
|
{
|
||||||
ParseScript(i);
|
ParseScript(i);
|
||||||
found = true;
|
found = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (found) fileSystem.Rehash();
|
if (found) fileSystem.InitHashChains();
|
||||||
}
|
}
|
||||||
END_BLD_NS
|
END_BLD_NS
|
||||||
|
|
|
@ -1078,7 +1078,7 @@ int GameInterface::app_main()
|
||||||
loaddefinitions_game(defsfile, FALSE);
|
loaddefinitions_game(defsfile, FALSE);
|
||||||
powerupInit();
|
powerupInit();
|
||||||
Printf("Loading cosine table\n");
|
Printf("Loading cosine table\n");
|
||||||
trigInit(gSysRes);
|
trigInit();
|
||||||
Printf("Initializing view subsystem\n");
|
Printf("Initializing view subsystem\n");
|
||||||
viewInit();
|
viewInit();
|
||||||
Printf("Initializing dynamic fire\n");
|
Printf("Initializing dynamic fire\n");
|
||||||
|
|
|
@ -130,7 +130,7 @@ void IniFile::Load()
|
||||||
|
|
||||||
curNode = &head;
|
curNode = &head;
|
||||||
|
|
||||||
auto fp = fileSystem.OpenFileReader(fileName, 0);
|
auto fp = fileSystem.OpenFileReader(fileName);
|
||||||
if (fp.isOpen())
|
if (fp.isOpen())
|
||||||
{
|
{
|
||||||
int nSize = fp.GetLength();
|
int nSize = fp.GetLength();
|
||||||
|
|
|
@ -23,9 +23,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "filesystem/resourcefile.h"
|
#include "filesystem.h"
|
||||||
#include "filesystem/filesystem.h"
|
|
||||||
|
|
||||||
using Resource = FileSystem;
|
using Resource = FileSystem;
|
||||||
// Map NBlood's resource system to our own.
|
// Map NBlood's resource system to our own.
|
||||||
using DICTNODE = FResourceEntry;
|
using DICTNODE = FResourceLump;
|
||||||
|
|
|
@ -83,9 +83,8 @@ void seqPrecacheId(int id)
|
||||||
DICTNODE *hSeq = gSysRes.Lookup(id, "SEQ");
|
DICTNODE *hSeq = gSysRes.Lookup(id, "SEQ");
|
||||||
if (!hSeq)
|
if (!hSeq)
|
||||||
return;
|
return;
|
||||||
Seq *pSeq = (Seq*)gSysRes.Lock(hSeq);
|
Seq *pSeq = (Seq*)gSysRes.Load(hSeq);
|
||||||
pSeq->Precache();
|
pSeq->Precache();
|
||||||
gSysRes.Unlock(hSeq);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SEQINST siWall[kMaxXWalls];
|
SEQINST siWall[kMaxXWalls];
|
||||||
|
@ -375,7 +374,6 @@ void UnlockInstance(SEQINST *pInst)
|
||||||
dassert(pInst != NULL);
|
dassert(pInst != NULL);
|
||||||
dassert(pInst->hSeq != NULL);
|
dassert(pInst->hSeq != NULL);
|
||||||
dassert(pInst->pSequence != NULL);
|
dassert(pInst->pSequence != NULL);
|
||||||
gSysRes.Unlock(pInst->hSeq);
|
|
||||||
pInst->hSeq = NULL;
|
pInst->hSeq = NULL;
|
||||||
pInst->pSequence = NULL;
|
pInst->pSequence = NULL;
|
||||||
pInst->at13 = 0;
|
pInst->at13 = 0;
|
||||||
|
@ -403,7 +401,7 @@ void seqSpawn(int a1, int a2, int a3, int a4)
|
||||||
}
|
}
|
||||||
dassert(i < activeCount);
|
dassert(i < activeCount);
|
||||||
}
|
}
|
||||||
Seq *pSeq = (Seq*)gSysRes.Lock(hSeq);
|
Seq *pSeq = (Seq*)gSysRes.Load(hSeq);
|
||||||
if (memcmp(pSeq->signature, "SEQ\x1a", 4) != 0)
|
if (memcmp(pSeq->signature, "SEQ\x1a", 4) != 0)
|
||||||
ThrowError("Invalid sequence %d", a1);
|
ThrowError("Invalid sequence %d", a1);
|
||||||
if ((pSeq->version & 0xff00) != 0x300)
|
if ((pSeq->version & 0xff00) != 0x300)
|
||||||
|
@ -588,7 +586,7 @@ void SeqLoadSave::Load(void)
|
||||||
ThrowError("Missing sequence #%d", nSeq);
|
ThrowError("Missing sequence #%d", nSeq);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
Seq *pSeq = (Seq*)gSysRes.Lock(hSeq);
|
Seq *pSeq = (Seq*)gSysRes.Load(hSeq);
|
||||||
if (memcmp(pSeq->signature, "SEQ\x1a", 4) != 0)
|
if (memcmp(pSeq->signature, "SEQ\x1a", 4) != 0)
|
||||||
ThrowError("Invalid sequence %d", nSeq);
|
ThrowError("Invalid sequence %d", nSeq);
|
||||||
if ((pSeq->version & 0xff00) != 0x300)
|
if ((pSeq->version & 0xff00) != 0x300)
|
||||||
|
|
|
@ -103,14 +103,14 @@ void sndInit(void)
|
||||||
for (int i = fileSystem.GetNumEntries() - 1; i >= 0; i--)
|
for (int i = fileSystem.GetNumEntries() - 1; i >= 0; i--)
|
||||||
{
|
{
|
||||||
auto type = fileSystem.GetResourceType(i);
|
auto type = fileSystem.GetResourceType(i);
|
||||||
if (type == NAME_SFX)
|
if (!stricmp(type, "SFX"))
|
||||||
{
|
{
|
||||||
if (soundEngine->FindSoundByResID(fileSystem.GetResourceId(i)) == 0)
|
if (soundEngine->FindSoundByResID(fileSystem.GetResourceId(i)) == 0)
|
||||||
S_AddBloodSFX(i);
|
S_AddBloodSFX(i);
|
||||||
}
|
}
|
||||||
else if (type == NAME_WAV || type == NAME_OGG || type == NAME_FLAC || type == NAME_VOC)
|
else if (!stricmp(type, "WAV") || !stricmp(type, "OGG") || !stricmp(type, "FLAC") || !stricmp(type, "VOC"))
|
||||||
{
|
{
|
||||||
soundEngine->AddSoundLump(fileSystem.GetFileName(i), i, 0, fileSystem.GetResourceId(i)| 0x40000000, 6); // mark the resource ID as special.
|
soundEngine->AddSoundLump(fileSystem.GetFileFullName(i), i, 0, fileSystem.GetResourceId(i)| 0x40000000, 6); // mark the resource ID as special.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
soundEngine->HashSounds();
|
soundEngine->HashSounds();
|
||||||
|
|
|
@ -86,12 +86,12 @@ int tileInit(char a1, const char *a2)
|
||||||
for (int i = 0; i < kMaxTiles; i++)
|
for (int i = 0; i < kMaxTiles; i++)
|
||||||
voxelIndex[i] = 0;
|
voxelIndex[i] = 0;
|
||||||
|
|
||||||
auto hFile = fileSystem.OpenFileReader("SURFACE.DAT", 0);
|
auto hFile = fileSystem.OpenFileReader("SURFACE.DAT");
|
||||||
if (hFile.isOpen())
|
if (hFile.isOpen())
|
||||||
{
|
{
|
||||||
hFile.Read(surfType, sizeof(surfType));
|
hFile.Read(surfType, sizeof(surfType));
|
||||||
}
|
}
|
||||||
hFile = fileSystem.OpenFileReader("VOXEL.DAT", 0);
|
hFile = fileSystem.OpenFileReader("VOXEL.DAT");
|
||||||
if (hFile.isOpen())
|
if (hFile.isOpen())
|
||||||
{
|
{
|
||||||
hFile.Read(voxelIndex, sizeof(voxelIndex));
|
hFile.Read(voxelIndex, sizeof(voxelIndex));
|
||||||
|
@ -100,7 +100,7 @@ int tileInit(char a1, const char *a2)
|
||||||
voxelIndex[i] = B_LITTLE16(voxelIndex[i]);
|
voxelIndex[i] = B_LITTLE16(voxelIndex[i]);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
hFile = fileSystem.OpenFileReader("SHADE.DAT", 0);
|
hFile = fileSystem.OpenFileReader("SHADE.DAT");
|
||||||
if (hFile.isOpen())
|
if (hFile.isOpen())
|
||||||
{
|
{
|
||||||
hFile.Read(tileShade, sizeof(tileShade));
|
hFile.Read(tileShade, sizeof(tileShade));
|
||||||
|
|
|
@ -59,14 +59,12 @@ void RotatePoint(int *x, int *y, int nAngle, int ox, int oy)
|
||||||
*y = oy+dmulscale30r(dx, Sin(nAngle), dy, Cos(nAngle));
|
*y = oy+dmulscale30r(dx, Sin(nAngle), dy, Cos(nAngle));
|
||||||
}
|
}
|
||||||
|
|
||||||
void trigInit(Resource &Res)
|
void trigInit()
|
||||||
{
|
{
|
||||||
DICTNODE *pTable = Res.Lookup("cosine","dat");
|
auto fr = fileSystem.OpenFileReader("cosine.dat");
|
||||||
if (!pTable)
|
auto len = fr.Read(costable, 2048);
|
||||||
ThrowError("Cosine table not found");
|
if (len != 2048)
|
||||||
if (pTable->Size() != 2048)
|
|
||||||
ThrowError("Cosine table incorrect size");
|
ThrowError("Cosine table incorrect size");
|
||||||
memcpy(costable, Res.Load(pTable), pTable->Size());
|
|
||||||
#if B_BIG_ENDIAN == 1
|
#if B_BIG_ENDIAN == 1
|
||||||
for (int i = 0; i < 512; i++)
|
for (int i = 0; i < 512; i++)
|
||||||
{
|
{
|
||||||
|
|
|
@ -31,7 +31,7 @@ extern int costable[2048];
|
||||||
int GetOctant(int x, int y);
|
int GetOctant(int x, int y);
|
||||||
void RotateVector(int *dx, int *dy, int nAngle);
|
void RotateVector(int *dx, int *dy, int nAngle);
|
||||||
void RotatePoint(int *x, int *y, int nAngle, int ox, int oy);
|
void RotatePoint(int *x, int *y, int nAngle, int ox, int oy);
|
||||||
void trigInit(Resource &Res);
|
void trigInit();
|
||||||
|
|
||||||
inline int Sin(int ang)
|
inline int Sin(int ang)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1795,6 +1795,7 @@ void viewPrecacheTiles(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static TArray<uint8_t> lensdata;
|
||||||
int *lensTable;
|
int *lensTable;
|
||||||
|
|
||||||
int gZoom = 1024;
|
int gZoom = 1024;
|
||||||
|
@ -1811,11 +1812,10 @@ void viewInit(void)
|
||||||
FontSet(3, 4384, 1);
|
FontSet(3, 4384, 1);
|
||||||
FontSet(4, 4480, 0);
|
FontSet(4, 4480, 0);
|
||||||
|
|
||||||
DICTNODE *hLens = gSysRes.Lookup("LENS", "DAT");
|
lensdata = fileSystem.LoadFile("lens.dat");
|
||||||
dassert(hLens != NULL);
|
dassert(lensdata.Size() == kLensSize * kLensSize * sizeof(int));
|
||||||
dassert(hLens->Size() == kLensSize * kLensSize * sizeof(int));
|
|
||||||
|
|
||||||
lensTable = (int*)gSysRes.Lock(hLens);
|
lensTable = (int*)lensdata.Data();
|
||||||
#if B_BIG_ENDIAN == 1
|
#if B_BIG_ENDIAN == 1
|
||||||
for (int i = 0; i < kLensSize*kLensSize; i++)
|
for (int i = 0; i < kLensSize*kLensSize; i++)
|
||||||
{
|
{
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
#define palette_h_
|
#define palette_h_
|
||||||
|
|
||||||
#include "renderstyle.h"
|
#include "renderstyle.h"
|
||||||
#include "filesystem/filesystem.h"
|
#include "filesystem.h"
|
||||||
|
|
||||||
#define MAXBASEPALS 256
|
#define MAXBASEPALS 256
|
||||||
#define MAXPALOOKUPS 256
|
#define MAXPALOOKUPS 256
|
||||||
|
|
|
@ -2628,7 +2628,7 @@ static int32_t defsparser(scriptfile *script)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
FileReader fil = fileSystem.OpenFileReader(fn, 0);
|
FileReader fil = fileSystem.OpenFileReader(fn);
|
||||||
if (!fil.isOpen())
|
if (!fil.isOpen())
|
||||||
{
|
{
|
||||||
Printf("Error: basepalette: Failed opening \"%s\" on line %s:%d\n", fn,
|
Printf("Error: basepalette: Failed opening \"%s\" on line %s:%d\n", fn,
|
||||||
|
@ -2800,7 +2800,7 @@ static int32_t defsparser(scriptfile *script)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
FileReader fil = fileSystem.OpenFileReader(fn, 0);
|
FileReader fil = fileSystem.OpenFileReader(fn);
|
||||||
if (!fil.isOpen())
|
if (!fil.isOpen())
|
||||||
{
|
{
|
||||||
Printf("Error: palookup: Failed opening \"%s\" on line %s:%d\n", fn,
|
Printf("Error: palookup: Failed opening \"%s\" on line %s:%d\n", fn,
|
||||||
|
@ -3093,7 +3093,7 @@ static int32_t defsparser(scriptfile *script)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
FileReader fil = fileSystem.OpenFileReader(fn, 0);
|
FileReader fil = fileSystem.OpenFileReader(fn);
|
||||||
if (!fil.isOpen())
|
if (!fil.isOpen())
|
||||||
{
|
{
|
||||||
Printf("Error: blendtable: Failed opening \"%s\" on line %s:%d\n", fn,
|
Printf("Error: blendtable: Failed opening \"%s\" on line %s:%d\n", fn,
|
||||||
|
|
|
@ -24,7 +24,6 @@
|
||||||
#include "c_console.h"
|
#include "c_console.h"
|
||||||
#include "v_2ddrawer.h"
|
#include "v_2ddrawer.h"
|
||||||
#include "v_draw.h"
|
#include "v_draw.h"
|
||||||
#include "imgui.h"
|
|
||||||
#include "stats.h"
|
#include "stats.h"
|
||||||
#include "menu.h"
|
#include "menu.h"
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
|
@ -3405,7 +3404,7 @@ int32_t engineLoadBoard(const char *filename, char flags, vec3_t *dapos, int16_t
|
||||||
|
|
||||||
flags &= 3;
|
flags &= 3;
|
||||||
|
|
||||||
FileReader fr = fileSystem.OpenFileReader(filename, 0);
|
FileReader fr = fileSystem.OpenFileReader(filename);
|
||||||
if (!fr.isOpen())
|
if (!fr.isOpen())
|
||||||
{ mapversion = 7; return -1; }
|
{ mapversion = 7; return -1; }
|
||||||
|
|
||||||
|
@ -3593,7 +3592,7 @@ int32_t engineLoadBoardV5V6(const char *filename, char fromwhere, vec3_t *dapos,
|
||||||
struct walltypev6 v6wall;
|
struct walltypev6 v6wall;
|
||||||
struct spritetypev6 v6spr;
|
struct spritetypev6 v6spr;
|
||||||
|
|
||||||
FileReader fr = fileSystem.OpenFileReader(filename, fromwhere);
|
FileReader fr = fileSystem.OpenFileReader(filename);
|
||||||
if (!fr.isOpen())
|
if (!fr.isOpen())
|
||||||
{ mapversion = 5L; return -1; }
|
{ mapversion = 5L; return -1; }
|
||||||
|
|
||||||
|
@ -3865,7 +3864,7 @@ int32_t qloadkvx(int32_t voxindex, const char *filename)
|
||||||
if ((unsigned)voxindex >= MAXVOXELS)
|
if ((unsigned)voxindex >= MAXVOXELS)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
auto fil = fileSystem.OpenFileReader(filename, 0);
|
auto fil = fileSystem.OpenFileReader(filename);
|
||||||
if (!fil.isOpen())
|
if (!fil.isOpen())
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
|
|
@ -1850,7 +1850,7 @@ static mdmodel_t *mdload(const char *filnam)
|
||||||
vm = (mdmodel_t *)voxload(filnam);
|
vm = (mdmodel_t *)voxload(filnam);
|
||||||
if (vm) return vm;
|
if (vm) return vm;
|
||||||
|
|
||||||
auto fil = fileSystem.OpenFileReader(filnam,0);
|
auto fil = fileSystem.OpenFileReader(filnam);
|
||||||
|
|
||||||
if (!fil.isOpen())
|
if (!fil.isOpen())
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
|
@ -104,7 +104,7 @@ void paletteLoadFromDisk(void)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto fil = fileSystem.OpenFileReader("palette.dat", 0);
|
auto fil = fileSystem.OpenFileReader("palette.dat");
|
||||||
if (!fil.isOpen())
|
if (!fil.isOpen())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
#include "scriptfile.h"
|
#include "scriptfile.h"
|
||||||
#include "baselayer.h"
|
#include "baselayer.h"
|
||||||
#include "compat.h"
|
#include "compat.h"
|
||||||
#include "filesystem/filesystem.h"
|
#include "filesystem.h"
|
||||||
|
|
||||||
|
|
||||||
#define ISWS(x) ((x == ' ') || (x == '\t') || (x == '\r') || (x == '\n'))
|
#define ISWS(x) ((x == ' ') || (x == '\t') || (x == '\r') || (x == '\n'))
|
||||||
|
@ -299,7 +299,7 @@ void scriptfile_preparse(scriptfile *sf, char *tx, int32_t flen)
|
||||||
|
|
||||||
scriptfile *scriptfile_fromfile(const char *fn)
|
scriptfile *scriptfile_fromfile(const char *fn)
|
||||||
{
|
{
|
||||||
auto fr = fileSystem.OpenFileReader(fn, 0);
|
auto fr = fileSystem.OpenFileReader(fn);
|
||||||
if (!fr.isOpen()) return nullptr;
|
if (!fr.isOpen()) return nullptr;
|
||||||
|
|
||||||
uint32_t flen = fr.GetLength();
|
uint32_t flen = fr.GetLength();
|
||||||
|
|
|
@ -606,7 +606,7 @@ static void read_pal(FileReader &fil, int32_t pal[256])
|
||||||
|
|
||||||
static int32_t loadvox(const char *filnam)
|
static int32_t loadvox(const char *filnam)
|
||||||
{
|
{
|
||||||
auto fil = fileSystem.OpenFileReader(filnam, 0);
|
auto fil = fileSystem.OpenFileReader(filnam);
|
||||||
if (!fil.isOpen())
|
if (!fil.isOpen())
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
@ -682,7 +682,7 @@ static int32_t loadkvx(const char *filnam)
|
||||||
{
|
{
|
||||||
int32_t i, mip1leng;
|
int32_t i, mip1leng;
|
||||||
|
|
||||||
auto fil = fileSystem.OpenFileReader(filnam, 0);
|
auto fil = fileSystem.OpenFileReader(filnam);
|
||||||
if (!fil.isOpen())
|
if (!fil.isOpen())
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
@ -766,7 +766,7 @@ static int32_t loadkv6(const char *filnam)
|
||||||
{
|
{
|
||||||
int32_t i;
|
int32_t i;
|
||||||
|
|
||||||
auto fil = fileSystem.OpenFileReader(filnam, 0);
|
auto fil = fileSystem.OpenFileReader(filnam);
|
||||||
if (!fil.isOpen())
|
if (!fil.isOpen())
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
#include <stdexcept>
|
|
||||||
#include "files.h"
|
#include "files.h"
|
||||||
#include "engineerrors.h"
|
#include "engineerrors.h"
|
||||||
|
|
||||||
|
@ -42,7 +41,7 @@ public:
|
||||||
int Explode(unsigned char *out, unsigned int outsize, FileReader &in, unsigned int insize, int flags);
|
int Explode(unsigned char *out, unsigned int outsize, FileReader &in, unsigned int insize, int flags);
|
||||||
};
|
};
|
||||||
|
|
||||||
class CExplosionError : public CRecoverableError
|
class CExplosionError : CRecoverableError
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CExplosionError(const char *message) : CRecoverableError(message) {}
|
CExplosionError(const char *message) : CRecoverableError(message) {}
|
|
@ -40,8 +40,6 @@
|
||||||
#include "resourcefile.h"
|
#include "resourcefile.h"
|
||||||
#include "cmdlib.h"
|
#include "cmdlib.h"
|
||||||
#include "printf.h"
|
#include "printf.h"
|
||||||
//#include "v_text.h"
|
|
||||||
//#include "w_wad.h"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -171,7 +169,7 @@ struct F7ZLump : public FResourceLump
|
||||||
{
|
{
|
||||||
int Position;
|
int Position;
|
||||||
|
|
||||||
int ValidateCache() override;
|
virtual int FillCache();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -191,7 +189,7 @@ class F7ZFile : public FResourceFile
|
||||||
|
|
||||||
public:
|
public:
|
||||||
F7ZFile(const char * filename, FileReader &filer);
|
F7ZFile(const char * filename, FileReader &filer);
|
||||||
bool Open(bool quiet);
|
bool Open(bool quiet, LumpFilterInfo* filter);
|
||||||
virtual ~F7ZFile();
|
virtual ~F7ZFile();
|
||||||
virtual FResourceLump *GetLump(int no) { return ((unsigned)no < NumLumps)? &Lumps[no] : NULL; }
|
virtual FResourceLump *GetLump(int no) { return ((unsigned)no < NumLumps)? &Lumps[no] : NULL; }
|
||||||
};
|
};
|
||||||
|
@ -218,7 +216,7 @@ F7ZFile::F7ZFile(const char * filename, FileReader &filer)
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
bool F7ZFile::Open(bool quiet)
|
bool F7ZFile::Open(bool quiet, LumpFilterInfo *filter)
|
||||||
{
|
{
|
||||||
Archive = new C7zArchive(Reader);
|
Archive = new C7zArchive(Reader);
|
||||||
int skipped = 0;
|
int skipped = 0;
|
||||||
|
@ -231,7 +229,7 @@ bool F7ZFile::Open(bool quiet)
|
||||||
Archive = NULL;
|
Archive = NULL;
|
||||||
if (!quiet)
|
if (!quiet)
|
||||||
{
|
{
|
||||||
Printf("\n%s: ", FileName.GetChars());
|
Printf("\n" TEXTCOLOR_RED "%s: ", FileName.GetChars());
|
||||||
if (res == SZ_ERROR_UNSUPPORTED)
|
if (res == SZ_ERROR_UNSUPPORTED)
|
||||||
{
|
{
|
||||||
Printf("Decoder does not support this archive\n");
|
Printf("Decoder does not support this archive\n");
|
||||||
|
@ -285,16 +283,17 @@ bool F7ZFile::Open(bool quiet)
|
||||||
{
|
{
|
||||||
nameASCII[c] = static_cast<char>(nameUTF16[c]);
|
nameASCII[c] = static_cast<char>(nameUTF16[c]);
|
||||||
}
|
}
|
||||||
|
FixPathSeperator(&nameASCII[0]);
|
||||||
|
|
||||||
FString name = &nameASCII[0];
|
FString name = &nameASCII[0];
|
||||||
name.Substitute("\\", "/");
|
|
||||||
name.ToLower();
|
name.ToLower();
|
||||||
|
|
||||||
lump_p->LumpNameSetup(name);
|
lump_p->LumpNameSetup(name);
|
||||||
lump_p->LumpSize = static_cast<int>(SzArEx_GetFileSize(archPtr, i));
|
lump_p->LumpSize = static_cast<int>(SzArEx_GetFileSize(archPtr, i));
|
||||||
lump_p->Owner = this;
|
lump_p->Owner = this;
|
||||||
lump_p->Flags = LUMPF_ZIPFILE|LUMPF_COMPRESSED;
|
lump_p->Flags = LUMPF_FULLPATH|LUMPF_COMPRESSED;
|
||||||
lump_p->Position = i;
|
lump_p->Position = i;
|
||||||
|
lump_p->CheckEmbedded();
|
||||||
lump_p++;
|
lump_p++;
|
||||||
}
|
}
|
||||||
// Resize the lump record array to its actual size
|
// Resize the lump record array to its actual size
|
||||||
|
@ -314,9 +313,8 @@ bool F7ZFile::Open(bool quiet)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!quiet) Printf(", %d lumps\n", NumLumps);
|
GenerateHash();
|
||||||
|
PostProcessArchive(&Lumps[0], sizeof(F7ZLump), filter);
|
||||||
PostProcessArchive(&Lumps[0], sizeof(F7ZLump));
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -344,10 +342,11 @@ F7ZFile::~F7ZFile()
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
int F7ZLump::ValidateCache()
|
int F7ZLump::FillCache()
|
||||||
{
|
{
|
||||||
Cache.Resize(LumpSize);
|
Cache = new char[LumpSize];
|
||||||
static_cast<F7ZFile*>(Owner)->Archive->Extract(Position, (char*)Cache.Data());
|
static_cast<F7ZFile*>(Owner)->Archive->Extract(Position, Cache);
|
||||||
|
RefCount = 1;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -357,7 +356,7 @@ int F7ZLump::ValidateCache()
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
FResourceFile *Check7Z(const char *filename, FileReader &file, bool quiet)
|
FResourceFile *Check7Z(const char *filename, FileReader &file, bool quiet, LumpFilterInfo* filter)
|
||||||
{
|
{
|
||||||
char head[k7zSignatureSize];
|
char head[k7zSignatureSize];
|
||||||
|
|
||||||
|
@ -369,7 +368,7 @@ FResourceFile *Check7Z(const char *filename, FileReader &file, bool quiet)
|
||||||
if (!memcmp(head, k7zSignature, k7zSignatureSize))
|
if (!memcmp(head, k7zSignature, k7zSignatureSize))
|
||||||
{
|
{
|
||||||
FResourceFile *rf = new F7ZFile(filename, file);
|
FResourceFile *rf = new F7ZFile(filename, file);
|
||||||
if (rf->Open(quiet)) return rf;
|
if (rf->Open(quiet, filter)) return rf;
|
||||||
|
|
||||||
file = std::move(rf->Reader); // to avoid destruction of reader
|
file = std::move(rf->Reader); // to avoid destruction of reader
|
||||||
delete rf;
|
delete rf;
|
|
@ -35,11 +35,6 @@
|
||||||
|
|
||||||
|
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#ifdef _WIN32
|
|
||||||
#include <io.h>
|
|
||||||
#else
|
|
||||||
#include <fts.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "resourcefile.h"
|
#include "resourcefile.h"
|
||||||
#include "cmdlib.h"
|
#include "cmdlib.h"
|
||||||
|
@ -56,8 +51,8 @@
|
||||||
|
|
||||||
struct FDirectoryLump : public FResourceLump
|
struct FDirectoryLump : public FResourceLump
|
||||||
{
|
{
|
||||||
virtual FileReader NewReader() override;
|
FileReader NewReader() override;
|
||||||
int ValidateCache() override;
|
int FillCache() override;
|
||||||
|
|
||||||
FString mFullPath;
|
FString mFullPath;
|
||||||
};
|
};
|
||||||
|
@ -79,7 +74,7 @@ class FDirectory : public FResourceFile
|
||||||
|
|
||||||
public:
|
public:
|
||||||
FDirectory(const char * dirname, bool nosubdirflag = false);
|
FDirectory(const char * dirname, bool nosubdirflag = false);
|
||||||
bool Open(bool quiet);
|
bool Open(bool quiet, LumpFilterInfo* filter);
|
||||||
virtual FResourceLump *GetLump(int no) { return ((unsigned)no < NumLumps)? &Lumps[no] : NULL; }
|
virtual FResourceLump *GetLump(int no) { return ((unsigned)no < NumLumps)? &Lumps[no] : NULL; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -150,9 +145,7 @@ int FDirectory::AddDirectory(const char *dirpath)
|
||||||
(fi[1] == '\0' ||
|
(fi[1] == '\0' ||
|
||||||
(fi[1] == '.' && fi[2] == '\0'))))
|
(fi[1] == '.' && fi[2] == '\0'))))
|
||||||
{
|
{
|
||||||
// Movie and music subdirectories must always pass.
|
// Do not record . and .. directories.
|
||||||
if (fi.CompareNoCase("movie") && fi.CompareNoCase("music"))
|
|
||||||
// Skip if requested and do not record . and .. directories.
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
FString newdir = dirpath;
|
FString newdir = dirpath;
|
||||||
|
@ -170,7 +163,7 @@ int FDirectory::AddDirectory(const char *dirpath)
|
||||||
FString fn = FString(dirpath) + fi;
|
FString fn = FString(dirpath) + fi;
|
||||||
if (GetFileInfo(fn, &size, nullptr))
|
if (GetFileInfo(fn, &size, nullptr))
|
||||||
{
|
{
|
||||||
AddEntry(fn, size);
|
AddEntry(fn, (int)size);
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -187,11 +180,10 @@ int FDirectory::AddDirectory(const char *dirpath)
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
bool FDirectory::Open(bool quiet)
|
bool FDirectory::Open(bool quiet, LumpFilterInfo* filter)
|
||||||
{
|
{
|
||||||
NumLumps = AddDirectory(FileName);
|
NumLumps = AddDirectory(FileName);
|
||||||
if (!quiet) Printf(", %d lumps\n", NumLumps);
|
PostProcessArchive(&Lumps[0], sizeof(FDirectoryLump), filter);
|
||||||
PostProcessArchive(&Lumps[0], sizeof(FDirectoryLump));
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -217,6 +209,7 @@ void FDirectory::AddEntry(const char *fullpath, int size)
|
||||||
lump_p->LumpSize = size;
|
lump_p->LumpSize = size;
|
||||||
lump_p->Owner = this;
|
lump_p->Owner = this;
|
||||||
lump_p->Flags = 0;
|
lump_p->Flags = 0;
|
||||||
|
lump_p->CheckEmbedded();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -239,17 +232,17 @@ FileReader FDirectoryLump::NewReader()
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
int FDirectoryLump::ValidateCache()
|
int FDirectoryLump::FillCache()
|
||||||
{
|
{
|
||||||
FileReader fr;
|
FileReader fr;
|
||||||
|
Cache = new char[LumpSize];
|
||||||
if (!fr.OpenFile(mFullPath))
|
if (!fr.OpenFile(mFullPath))
|
||||||
{
|
{
|
||||||
memset(Cache.Data(), 0, LumpSize);
|
memset(Cache, 0, LumpSize);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
LumpSize = fr.GetLength(); // keep this updated
|
fr.Read(Cache, LumpSize);
|
||||||
Cache.Resize(LumpSize);
|
RefCount = 1;
|
||||||
fr.Read(Cache.Data(), LumpSize);
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -259,10 +252,10 @@ int FDirectoryLump::ValidateCache()
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
FResourceFile *CheckDir(const char *filename, bool quiet, bool nosubdirflag)
|
FResourceFile *CheckDir(const char *filename, bool quiet, bool nosubdirflag, LumpFilterInfo* filter)
|
||||||
{
|
{
|
||||||
FResourceFile *rf = new FDirectory(filename, nosubdirflag);
|
FResourceFile *rf = new FDirectory(filename, nosubdirflag);
|
||||||
if (rf->Open(quiet)) return rf;
|
if (rf->Open(quiet, filter)) return rf;
|
||||||
delete rf;
|
delete rf;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
|
@ -72,7 +72,7 @@ class FGrpFile : public FUncompressedFile
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
FGrpFile(const char * filename, FileReader &file);
|
FGrpFile(const char * filename, FileReader &file);
|
||||||
bool Open(bool quiet);
|
bool Open(bool quiet, LumpFilterInfo* filter);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -93,7 +93,7 @@ FGrpFile::FGrpFile(const char *filename, FileReader &file)
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
bool FGrpFile::Open(bool quiet)
|
bool FGrpFile::Open(bool quiet, LumpFilterInfo*)
|
||||||
{
|
{
|
||||||
GrpInfo header;
|
GrpInfo header;
|
||||||
|
|
||||||
|
@ -117,7 +117,7 @@ bool FGrpFile::Open(bool quiet)
|
||||||
fileinfo[i].NameWithZero[12] = '\0'; // Be sure filename is null-terminated
|
fileinfo[i].NameWithZero[12] = '\0'; // Be sure filename is null-terminated
|
||||||
Lumps[i].LumpNameSetup(fileinfo[i].NameWithZero);
|
Lumps[i].LumpNameSetup(fileinfo[i].NameWithZero);
|
||||||
}
|
}
|
||||||
if (!quiet) Printf(", %d lumps\n", NumLumps);
|
GenerateHash();
|
||||||
delete[] fileinfo;
|
delete[] fileinfo;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -129,7 +129,7 @@ bool FGrpFile::Open(bool quiet)
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
FResourceFile *CheckGRP(const char *filename, FileReader &file, bool quiet)
|
FResourceFile *CheckGRP(const char *filename, FileReader &file, bool quiet, LumpFilterInfo* filter)
|
||||||
{
|
{
|
||||||
char head[12];
|
char head[12];
|
||||||
|
|
||||||
|
@ -141,7 +141,7 @@ FResourceFile *CheckGRP(const char *filename, FileReader &file, bool quiet)
|
||||||
if (!memcmp(head, "KenSilverman", 12))
|
if (!memcmp(head, "KenSilverman", 12))
|
||||||
{
|
{
|
||||||
FResourceFile *rf = new FGrpFile(filename, file);
|
FResourceFile *rf = new FGrpFile(filename, file);
|
||||||
if (rf->Open(quiet)) return rf;
|
if (rf->Open(quiet, filter)) return rf;
|
||||||
|
|
||||||
file = std::move(rf->Reader); // to avoid destruction of reader
|
file = std::move(rf->Reader); // to avoid destruction of reader
|
||||||
delete rf;
|
delete rf;
|
|
@ -34,6 +34,7 @@
|
||||||
|
|
||||||
#include "resourcefile.h"
|
#include "resourcefile.h"
|
||||||
#include "cmdlib.h"
|
#include "cmdlib.h"
|
||||||
|
#include "printf.h"
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
|
@ -45,7 +46,7 @@ class FLumpFile : public FUncompressedFile
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
FLumpFile(const char * filename, FileReader &file);
|
FLumpFile(const char * filename, FileReader &file);
|
||||||
bool Open(bool quiet);
|
bool Open(bool quiet, LumpFilterInfo* filter);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -66,16 +67,21 @@ FLumpFile::FLumpFile(const char *filename, FileReader &file)
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
bool FLumpFile::Open(bool quiet)
|
bool FLumpFile::Open(bool quiet, LumpFilterInfo*)
|
||||||
{
|
{
|
||||||
|
FString name(ExtractFileBase(FileName, true));
|
||||||
|
|
||||||
Lumps.Resize(1);
|
Lumps.Resize(1);
|
||||||
|
Lumps[0].LumpNameSetup(name);
|
||||||
Lumps[0].Owner = this;
|
Lumps[0].Owner = this;
|
||||||
Lumps[0].Position = 0;
|
Lumps[0].Position = 0;
|
||||||
Lumps[0].LumpSize = (int)Reader.GetLength();
|
Lumps[0].LumpSize = (int)Reader.GetLength();
|
||||||
Lumps[0].Flags = 0;
|
Lumps[0].Flags = 0;
|
||||||
auto p = FileName.LastIndexOf('/');
|
|
||||||
Lumps[0].LumpNameSetup(FileName.GetChars() + p);
|
|
||||||
NumLumps = 1;
|
NumLumps = 1;
|
||||||
|
if (!quiet)
|
||||||
|
{
|
||||||
|
Printf("\n");
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,11 +91,11 @@ bool FLumpFile::Open(bool quiet)
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
FResourceFile *CheckLump(const char *filename, FileReader &file, bool quiet)
|
FResourceFile *CheckLump(const char *filename, FileReader &file, bool quiet, LumpFilterInfo* filter)
|
||||||
{
|
{
|
||||||
// always succeeds
|
// always succeeds
|
||||||
FResourceFile *rf = new FLumpFile(filename, file);
|
FResourceFile *rf = new FLumpFile(filename, file);
|
||||||
if (rf->Open(quiet)) return rf;
|
if (rf->Open(quiet, filter)) return rf;
|
||||||
file = std::move(rf->Reader); // to avoid destruction of reader
|
file = std::move(rf->Reader); // to avoid destruction of reader
|
||||||
delete rf;
|
delete rf;
|
||||||
return NULL;
|
return NULL;
|
|
@ -34,8 +34,6 @@
|
||||||
|
|
||||||
#include "resourcefile.h"
|
#include "resourcefile.h"
|
||||||
#include "printf.h"
|
#include "printf.h"
|
||||||
//#include "w_wad.h"
|
|
||||||
//#include "doomtype.h"
|
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
|
@ -67,7 +65,7 @@ class FPakFile : public FUncompressedFile
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
FPakFile(const char * filename, FileReader &file);
|
FPakFile(const char * filename, FileReader &file);
|
||||||
bool Open(bool quiet);
|
bool Open(bool quiet, LumpFilterInfo* filter);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -90,7 +88,7 @@ FPakFile::FPakFile(const char *filename, FileReader &file)
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
bool FPakFile::Open(bool quiet)
|
bool FPakFile::Open(bool quiet, LumpFilterInfo* filter)
|
||||||
{
|
{
|
||||||
dpackheader_t header;
|
dpackheader_t header;
|
||||||
|
|
||||||
|
@ -104,15 +102,17 @@ bool FPakFile::Open(bool quiet)
|
||||||
|
|
||||||
Lumps.Resize(NumLumps);
|
Lumps.Resize(NumLumps);
|
||||||
|
|
||||||
if (!quiet) Printf(", %d lumps\n", NumLumps);
|
|
||||||
|
|
||||||
for(uint32_t i = 0; i < NumLumps; i++)
|
for(uint32_t i = 0; i < NumLumps; i++)
|
||||||
{
|
{
|
||||||
Lumps[i].LumpNameSetup(fileinfo[i].name);
|
Lumps[i].LumpNameSetup(fileinfo[i].name);
|
||||||
|
Lumps[i].Flags = LUMPF_FULLPATH;
|
||||||
Lumps[i].Owner = this;
|
Lumps[i].Owner = this;
|
||||||
Lumps[i].Position = LittleLong(fileinfo[i].filepos);
|
Lumps[i].Position = LittleLong(fileinfo[i].filepos);
|
||||||
Lumps[i].LumpSize = LittleLong(fileinfo[i].filelen);
|
Lumps[i].LumpSize = LittleLong(fileinfo[i].filelen);
|
||||||
|
Lumps[i].CheckEmbedded();
|
||||||
}
|
}
|
||||||
|
GenerateHash();
|
||||||
|
PostProcessArchive(&Lumps[0], sizeof(Lumps[0]), filter);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -123,7 +123,7 @@ bool FPakFile::Open(bool quiet)
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
FResourceFile *CheckPak(const char *filename, FileReader &file, bool quiet)
|
FResourceFile *CheckPak(const char *filename, FileReader &file, bool quiet, LumpFilterInfo* filter)
|
||||||
{
|
{
|
||||||
char head[4];
|
char head[4];
|
||||||
|
|
||||||
|
@ -135,7 +135,7 @@ FResourceFile *CheckPak(const char *filename, FileReader &file, bool quiet)
|
||||||
if (!memcmp(head, "PACK", 4))
|
if (!memcmp(head, "PACK", 4))
|
||||||
{
|
{
|
||||||
FResourceFile *rf = new FPakFile(filename, file);
|
FResourceFile *rf = new FPakFile(filename, file);
|
||||||
if (rf->Open(quiet)) return rf;
|
if (rf->Open(quiet, filter)) return rf;
|
||||||
|
|
||||||
file = std::move(rf->Reader); // to avoid destruction of reader
|
file = std::move(rf->Reader); // to avoid destruction of reader
|
||||||
delete rf;
|
delete rf;
|
|
@ -32,8 +32,9 @@
|
||||||
**
|
**
|
||||||
**
|
**
|
||||||
*/
|
*/
|
||||||
#include <algorithm>
|
|
||||||
#include "resourcefile.h"
|
#include "resourcefile.h"
|
||||||
|
#include "templates.h"
|
||||||
#include "printf.h"
|
#include "printf.h"
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
@ -61,7 +62,7 @@ struct RFFLump
|
||||||
uint8_t Flags;
|
uint8_t Flags;
|
||||||
char Extension[3];
|
char Extension[3];
|
||||||
char Name[8];
|
char Name[8];
|
||||||
uint32_t ResourceId;
|
uint32_t IndexNum; // Used by .sfx, possibly others
|
||||||
};
|
};
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
@ -72,10 +73,12 @@ struct RFFLump
|
||||||
|
|
||||||
struct FRFFLump : public FUncompressedLump
|
struct FRFFLump : public FUncompressedLump
|
||||||
{
|
{
|
||||||
virtual FileReader *GetReader() override;
|
virtual FileReader *GetReader();
|
||||||
int ValidateCache() override;
|
virtual int FillCache();
|
||||||
|
|
||||||
uint32_t IndexNum;
|
uint32_t IndexNum;
|
||||||
|
|
||||||
|
int GetIndexNum() const { return IndexNum; }
|
||||||
};
|
};
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
@ -103,11 +106,12 @@ void BloodCrypt (void *data, int key, int len)
|
||||||
|
|
||||||
class FRFFFile : public FResourceFile
|
class FRFFFile : public FResourceFile
|
||||||
{
|
{
|
||||||
TArray<FRFFLump> Lumps;
|
FRFFLump *Lumps;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
FRFFFile(const char * filename, FileReader &file);
|
FRFFFile(const char * filename, FileReader &file);
|
||||||
virtual bool Open(bool quiet);
|
virtual ~FRFFFile();
|
||||||
|
virtual bool Open(bool quiet, LumpFilterInfo* filter);
|
||||||
virtual FResourceLump *GetLump(int no) { return ((unsigned)no < NumLumps)? &Lumps[no] : NULL; }
|
virtual FResourceLump *GetLump(int no) { return ((unsigned)no < NumLumps)? &Lumps[no] : NULL; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -121,6 +125,7 @@ public:
|
||||||
FRFFFile::FRFFFile(const char *filename, FileReader &file)
|
FRFFFile::FRFFFile(const char *filename, FileReader &file)
|
||||||
: FResourceFile(filename, file)
|
: FResourceFile(filename, file)
|
||||||
{
|
{
|
||||||
|
Lumps = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
@ -129,7 +134,7 @@ FRFFFile::FRFFFile(const char *filename, FileReader &file)
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
bool FRFFFile::Open(bool quiet)
|
bool FRFFFile::Open(bool quiet, LumpFilterInfo*)
|
||||||
{
|
{
|
||||||
RFFLump *lumps;
|
RFFLump *lumps;
|
||||||
RFFInfo header;
|
RFFInfo header;
|
||||||
|
@ -143,22 +148,18 @@ bool FRFFFile::Open(bool quiet)
|
||||||
Reader.Read (lumps, header.NumLumps * sizeof(RFFLump));
|
Reader.Read (lumps, header.NumLumps * sizeof(RFFLump));
|
||||||
BloodCrypt (lumps, header.DirOfs, header.NumLumps * sizeof(RFFLump));
|
BloodCrypt (lumps, header.DirOfs, header.NumLumps * sizeof(RFFLump));
|
||||||
|
|
||||||
Lumps.Grow(NumLumps);
|
Lumps = new FRFFLump[NumLumps];
|
||||||
|
|
||||||
if (!quiet) Printf(", %d lumps\n", NumLumps);
|
|
||||||
for (uint32_t i = 0; i < NumLumps; ++i)
|
for (uint32_t i = 0; i < NumLumps; ++i)
|
||||||
{
|
{
|
||||||
Lumps.Reserve(1);
|
Lumps[i].Position = LittleLong(lumps[i].FilePos);
|
||||||
auto& Lump = Lumps.Last();
|
Lumps[i].LumpSize = LittleLong(lumps[i].Size);
|
||||||
|
Lumps[i].Owner = this;
|
||||||
Lump.Position = LittleLong(lumps[i].FilePos);
|
|
||||||
Lump.LumpSize = LittleLong(lumps[i].Size);
|
|
||||||
Lump.Owner = this;
|
|
||||||
if (lumps[i].Flags & 0x10)
|
if (lumps[i].Flags & 0x10)
|
||||||
{
|
{
|
||||||
Lump.Flags |= LUMPF_BLOODCRYPT;
|
Lumps[i].Flags |= LUMPF_COMPRESSED; // flags the lump as not directly usable
|
||||||
}
|
}
|
||||||
Lump.ResourceId = LittleLong(lumps[i].ResourceId);
|
Lumps[i].IndexNum = LittleLong(lumps[i].IndexNum);
|
||||||
// Rearrange the name and extension to construct the fullname.
|
// Rearrange the name and extension to construct the fullname.
|
||||||
char name[13];
|
char name[13];
|
||||||
strncpy(name, lumps[i].Name, 8);
|
strncpy(name, lumps[i].Name, 8);
|
||||||
|
@ -170,12 +171,21 @@ bool FRFFFile::Open(bool quiet)
|
||||||
name[len+2] = lumps[i].Extension[1];
|
name[len+2] = lumps[i].Extension[1];
|
||||||
name[len+3] = lumps[i].Extension[2];
|
name[len+3] = lumps[i].Extension[2];
|
||||||
name[len+4] = 0;
|
name[len+4] = 0;
|
||||||
Lump.LumpNameSetup(name);
|
Lumps[i].LumpNameSetup(name);
|
||||||
}
|
}
|
||||||
delete[] lumps;
|
delete[] lumps;
|
||||||
|
GenerateHash();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FRFFFile::~FRFFFile()
|
||||||
|
{
|
||||||
|
if (Lumps != NULL)
|
||||||
|
{
|
||||||
|
delete[] Lumps;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
|
@ -187,7 +197,7 @@ FileReader *FRFFLump::GetReader()
|
||||||
{
|
{
|
||||||
// Don't return the reader if this lump is encrypted
|
// Don't return the reader if this lump is encrypted
|
||||||
// In that case always force caching of the lump
|
// In that case always force caching of the lump
|
||||||
if (!(Flags & LUMPF_BLOODCRYPT))
|
if (!(Flags & LUMPF_COMPRESSED))
|
||||||
{
|
{
|
||||||
return FUncompressedLump::GetReader();
|
return FUncompressedLump::GetReader();
|
||||||
}
|
}
|
||||||
|
@ -203,14 +213,14 @@ FileReader *FRFFLump::GetReader()
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
int FRFFLump::ValidateCache()
|
int FRFFLump::FillCache()
|
||||||
{
|
{
|
||||||
int res = FUncompressedLump::ValidateCache();
|
int res = FUncompressedLump::FillCache();
|
||||||
|
|
||||||
if (res && (Flags & LUMPF_BLOODCRYPT))
|
if (Flags & LUMPF_COMPRESSED)
|
||||||
{
|
{
|
||||||
int cryptlen = std::min<int> (LumpSize, 256);
|
int cryptlen = MIN<int> (LumpSize, 256);
|
||||||
uint8_t *data = Cache.Data();
|
uint8_t *data = (uint8_t *)Cache;
|
||||||
|
|
||||||
for (int i = 0; i < cryptlen; ++i)
|
for (int i = 0; i < cryptlen; ++i)
|
||||||
{
|
{
|
||||||
|
@ -227,7 +237,7 @@ int FRFFLump::ValidateCache()
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
FResourceFile *CheckRFF(const char *filename, FileReader &file, bool quiet)
|
FResourceFile *CheckRFF(const char *filename, FileReader &file, bool quiet, LumpFilterInfo* filter)
|
||||||
{
|
{
|
||||||
char head[4];
|
char head[4];
|
||||||
|
|
||||||
|
@ -239,7 +249,7 @@ FResourceFile *CheckRFF(const char *filename, FileReader &file, bool quiet)
|
||||||
if (!memcmp(head, "RFF\x1a", 4))
|
if (!memcmp(head, "RFF\x1a", 4))
|
||||||
{
|
{
|
||||||
FResourceFile *rf = new FRFFFile(filename, file);
|
FResourceFile *rf = new FRFFFile(filename, file);
|
||||||
if (rf->Open(quiet)) return rf;
|
if (rf->Open(quiet, filter)) return rf;
|
||||||
|
|
||||||
file = std::move(rf->Reader); // to avoid destruction of reader
|
file = std::move(rf->Reader); // to avoid destruction of reader
|
||||||
delete rf;
|
delete rf;
|
484
source/common/filesystem/file_wad.cpp
Normal file
484
source/common/filesystem/file_wad.cpp
Normal file
|
@ -0,0 +1,484 @@
|
||||||
|
/*
|
||||||
|
** file_wad.cpp
|
||||||
|
**
|
||||||
|
**---------------------------------------------------------------------------
|
||||||
|
** Copyright 1998-2009 Randy Heit
|
||||||
|
** Copyright 2005-2009 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 <ctype.h>
|
||||||
|
#include "resourcefile.h"
|
||||||
|
#include "v_text.h"
|
||||||
|
#include "filesystem.h"
|
||||||
|
#include "engineerrors.h"
|
||||||
|
|
||||||
|
|
||||||
|
struct wadinfo_t
|
||||||
|
{
|
||||||
|
// Should be "IWAD" or "PWAD".
|
||||||
|
uint32_t Magic;
|
||||||
|
uint32_t NumLumps;
|
||||||
|
uint32_t InfoTableOfs;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct wadlump_t
|
||||||
|
{
|
||||||
|
uint32_t FilePos;
|
||||||
|
uint32_t Size;
|
||||||
|
char Name[8];
|
||||||
|
};
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// Wad Lump (with console doom LZSS support)
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
class FWadFileLump : public FResourceLump
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
bool Compressed;
|
||||||
|
int Position;
|
||||||
|
int Namespace;
|
||||||
|
|
||||||
|
int GetNamespace() const override { return Namespace; }
|
||||||
|
|
||||||
|
int GetFileOffset() { return Position; }
|
||||||
|
FileReader *GetReader()
|
||||||
|
{
|
||||||
|
if(!Compressed)
|
||||||
|
{
|
||||||
|
Owner->Reader.Seek(Position, FileReader::SeekSet);
|
||||||
|
return &Owner->Reader;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
int FillCache()
|
||||||
|
{
|
||||||
|
if(!Compressed)
|
||||||
|
{
|
||||||
|
const char * buffer = Owner->Reader.GetBuffer();
|
||||||
|
|
||||||
|
if (buffer != NULL)
|
||||||
|
{
|
||||||
|
// This is an in-memory file so the cache can point directly to the file's data.
|
||||||
|
Cache = const_cast<char*>(buffer) + Position;
|
||||||
|
RefCount = -1;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Owner->Reader.Seek(Position, FileReader::SeekSet);
|
||||||
|
Cache = new char[LumpSize];
|
||||||
|
|
||||||
|
if(Compressed)
|
||||||
|
{
|
||||||
|
FileReader lzss;
|
||||||
|
if (lzss.OpenDecompressor(Owner->Reader, LumpSize, METHOD_LZSS, false, [](const char* err) { I_Error("%s", err); }))
|
||||||
|
{
|
||||||
|
lzss.Read(Cache, LumpSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Owner->Reader.Read(Cache, LumpSize);
|
||||||
|
|
||||||
|
RefCount = 1;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// Wad file
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
class FWadFile : public FResourceFile
|
||||||
|
{
|
||||||
|
TArray<FWadFileLump> Lumps;
|
||||||
|
|
||||||
|
bool IsMarker(int lump, const char *marker);
|
||||||
|
void SetNamespace(const char *startmarker, const char *endmarker, namespace_t space, bool flathack=false);
|
||||||
|
void SkinHack ();
|
||||||
|
|
||||||
|
public:
|
||||||
|
FWadFile(const char * filename, FileReader &file);
|
||||||
|
FResourceLump *GetLump(int lump) { return &Lumps[lump]; }
|
||||||
|
bool Open(bool quiet, LumpFilterInfo* filter);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// FWadFile::FWadFile
|
||||||
|
//
|
||||||
|
// Initializes a WAD file
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
FWadFile::FWadFile(const char *filename, FileReader &file)
|
||||||
|
: FResourceFile(filename, file)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// Open it
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
bool FWadFile::Open(bool quiet, LumpFilterInfo*)
|
||||||
|
{
|
||||||
|
wadinfo_t header;
|
||||||
|
uint32_t InfoTableOfs;
|
||||||
|
bool isBigEndian = false; // Little endian is assumed until proven otherwise
|
||||||
|
auto wadSize = Reader.GetLength();
|
||||||
|
|
||||||
|
Reader.Read(&header, sizeof(header));
|
||||||
|
NumLumps = LittleLong(header.NumLumps);
|
||||||
|
InfoTableOfs = LittleLong(header.InfoTableOfs);
|
||||||
|
|
||||||
|
// Check to see if the little endian interpretation is valid
|
||||||
|
// This should be sufficient to detect big endian wads.
|
||||||
|
if (InfoTableOfs + NumLumps*sizeof(wadlump_t) > (unsigned)wadSize)
|
||||||
|
{
|
||||||
|
NumLumps = BigLong(header.NumLumps);
|
||||||
|
InfoTableOfs = BigLong(header.InfoTableOfs);
|
||||||
|
isBigEndian = true;
|
||||||
|
|
||||||
|
// Check again to detect broken wads
|
||||||
|
if (InfoTableOfs + NumLumps*sizeof(wadlump_t) > (unsigned)wadSize)
|
||||||
|
{
|
||||||
|
I_Error("Cannot load broken WAD file %s\n", FileName.GetChars());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TArray<wadlump_t> fileinfo(NumLumps, true);
|
||||||
|
Reader.Seek (InfoTableOfs, FileReader::SeekSet);
|
||||||
|
Reader.Read (fileinfo.Data(), NumLumps * sizeof(wadlump_t));
|
||||||
|
|
||||||
|
Lumps.Resize(NumLumps);
|
||||||
|
|
||||||
|
for(uint32_t i = 0; i < NumLumps; i++)
|
||||||
|
{
|
||||||
|
char n[9];
|
||||||
|
uppercopy(n, fileinfo[i].Name);
|
||||||
|
n[8] = 0;
|
||||||
|
// This needs to be done differently. We cannot simply assume that all lumps where the first character's high bit is set are compressed without verification.
|
||||||
|
// This requires explicit toggling for precisely the files that need it.
|
||||||
|
#if 0
|
||||||
|
Lumps[i].Compressed = !(gameinfo.flags & GI_SHAREWARE) && (n[0] & 0x80) == 0x80;
|
||||||
|
#else
|
||||||
|
Lumps[i].Compressed = false;
|
||||||
|
#endif
|
||||||
|
n[0] &= ~0x80;
|
||||||
|
Lumps[i].LumpNameSetup(n);
|
||||||
|
|
||||||
|
Lumps[i].Owner = this;
|
||||||
|
Lumps[i].Position = isBigEndian ? BigLong(fileinfo[i].FilePos) : LittleLong(fileinfo[i].FilePos);
|
||||||
|
Lumps[i].LumpSize = isBigEndian ? BigLong(fileinfo[i].Size) : LittleLong(fileinfo[i].Size);
|
||||||
|
Lumps[i].Namespace = ns_global;
|
||||||
|
Lumps[i].Flags = Lumps[i].Compressed ? LUMPF_COMPRESSED | LUMPF_SHORTNAME : LUMPF_SHORTNAME;
|
||||||
|
|
||||||
|
// Check if the lump is within the WAD file and print a warning if not.
|
||||||
|
if (Lumps[i].Position + Lumps[i].LumpSize > wadSize || Lumps[i].Position < 0 || Lumps[i].LumpSize < 0)
|
||||||
|
{
|
||||||
|
if (Lumps[i].LumpSize != 0)
|
||||||
|
{
|
||||||
|
Printf(PRINT_HIGH, "%s: Lump %s contains invalid positioning info and will be ignored\n", FileName.GetChars(), Lumps[i].getName());
|
||||||
|
Lumps[i].LumpNameSetup("");
|
||||||
|
}
|
||||||
|
Lumps[i].LumpSize = Lumps[i].Position = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GenerateHash(); // Do this before the lump processing below.
|
||||||
|
|
||||||
|
if (!quiet) // don't bother with namespaces in quiet mode. We won't need them.
|
||||||
|
{
|
||||||
|
SetNamespace("S_START", "S_END", ns_sprites);
|
||||||
|
SetNamespace("F_START", "F_END", ns_flats, true);
|
||||||
|
SetNamespace("C_START", "C_END", ns_colormaps);
|
||||||
|
SetNamespace("A_START", "A_END", ns_acslibrary);
|
||||||
|
SetNamespace("TX_START", "TX_END", ns_newtextures);
|
||||||
|
SetNamespace("V_START", "V_END", ns_strifevoices);
|
||||||
|
SetNamespace("HI_START", "HI_END", ns_hires);
|
||||||
|
SetNamespace("VX_START", "VX_END", ns_voxels);
|
||||||
|
SkinHack();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// IsMarker
|
||||||
|
//
|
||||||
|
// (from BOOM)
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
inline bool FWadFile::IsMarker(int lump, const char *marker)
|
||||||
|
{
|
||||||
|
if (Lumps[lump].getName()[0] == marker[0])
|
||||||
|
{
|
||||||
|
return (!strcmp(Lumps[lump].getName(), marker) ||
|
||||||
|
(marker[1] == '_' && !strcmp(Lumps[lump].getName() +1, marker)));
|
||||||
|
}
|
||||||
|
else return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// SetNameSpace
|
||||||
|
//
|
||||||
|
// Sets namespace information for the lumps. It always looks for the first
|
||||||
|
// x_START and the last x_END lump, except when loading flats. In this case
|
||||||
|
// F_START may be absent and if that is the case all lumps with a size of
|
||||||
|
// 4096 will be flagged appropriately.
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
// This class was supposed to be local in the function but GCC
|
||||||
|
// does not like that.
|
||||||
|
struct Marker
|
||||||
|
{
|
||||||
|
int markertype;
|
||||||
|
unsigned int index;
|
||||||
|
};
|
||||||
|
|
||||||
|
void FWadFile::SetNamespace(const char *startmarker, const char *endmarker, namespace_t space, bool flathack)
|
||||||
|
{
|
||||||
|
bool warned = false;
|
||||||
|
int numstartmarkers = 0, numendmarkers = 0;
|
||||||
|
unsigned int i;
|
||||||
|
TArray<Marker> markers;
|
||||||
|
|
||||||
|
for(i = 0; i < NumLumps; i++)
|
||||||
|
{
|
||||||
|
if (IsMarker(i, startmarker))
|
||||||
|
{
|
||||||
|
Marker m = { 0, i };
|
||||||
|
markers.Push(m);
|
||||||
|
numstartmarkers++;
|
||||||
|
}
|
||||||
|
else if (IsMarker(i, endmarker))
|
||||||
|
{
|
||||||
|
Marker m = { 1, i };
|
||||||
|
markers.Push(m);
|
||||||
|
numendmarkers++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (numstartmarkers == 0)
|
||||||
|
{
|
||||||
|
if (numendmarkers == 0) return; // no markers found
|
||||||
|
|
||||||
|
Printf(TEXTCOLOR_YELLOW"WARNING: %s marker without corresponding %s found.\n", endmarker, startmarker);
|
||||||
|
|
||||||
|
|
||||||
|
if (flathack)
|
||||||
|
{
|
||||||
|
// We have found no F_START but one or more F_END markers.
|
||||||
|
// mark all lumps before the last F_END marker as potential flats.
|
||||||
|
unsigned int end = markers[markers.Size()-1].index;
|
||||||
|
for(unsigned int i = 0; i < end; i++)
|
||||||
|
{
|
||||||
|
if (Lumps[i].LumpSize == 4096)
|
||||||
|
{
|
||||||
|
// We can't add this to the flats namespace but
|
||||||
|
// it needs to be flagged for the texture manager.
|
||||||
|
DPrintf(DMSG_NOTIFY, "Marking %s as potential flat\n", Lumps[i].getName());
|
||||||
|
Lumps[i].Flags |= LUMPF_MAYBEFLAT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
while (i < markers.Size())
|
||||||
|
{
|
||||||
|
int start, end;
|
||||||
|
if (markers[i].markertype != 0)
|
||||||
|
{
|
||||||
|
Printf(TEXTCOLOR_YELLOW"WARNING: %s marker without corresponding %s found.\n", endmarker, startmarker);
|
||||||
|
i++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
start = i++;
|
||||||
|
|
||||||
|
// skip over subsequent x_START markers
|
||||||
|
while (i < markers.Size() && markers[i].markertype == 0)
|
||||||
|
{
|
||||||
|
Printf(TEXTCOLOR_YELLOW"WARNING: duplicate %s marker found.\n", startmarker);
|
||||||
|
i++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// same for x_END markers
|
||||||
|
while (i < markers.Size()-1 && (markers[i].markertype == 1 && markers[i+1].markertype == 1))
|
||||||
|
{
|
||||||
|
Printf(TEXTCOLOR_YELLOW"WARNING: duplicate %s marker found.\n", endmarker);
|
||||||
|
i++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// We found a starting marker but no end marker. Ignore this block.
|
||||||
|
if (i >= markers.Size())
|
||||||
|
{
|
||||||
|
Printf(TEXTCOLOR_YELLOW"WARNING: %s marker without corresponding %s found.\n", startmarker, endmarker);
|
||||||
|
end = NumLumps;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
end = markers[i++].index;
|
||||||
|
}
|
||||||
|
|
||||||
|
// we found a marked block
|
||||||
|
DPrintf(DMSG_NOTIFY, "Found %s block at (%d-%d)\n", startmarker, markers[start].index, end);
|
||||||
|
for(int j = markers[start].index + 1; j < end; j++)
|
||||||
|
{
|
||||||
|
if (Lumps[j].Namespace != ns_global)
|
||||||
|
{
|
||||||
|
if (!warned)
|
||||||
|
{
|
||||||
|
Printf(TEXTCOLOR_YELLOW"WARNING: Overlapping namespaces found (lump %d)\n", j);
|
||||||
|
}
|
||||||
|
warned = true;
|
||||||
|
}
|
||||||
|
else if (space == ns_sprites && Lumps[j].LumpSize < 8)
|
||||||
|
{
|
||||||
|
// sf 26/10/99:
|
||||||
|
// ignore sprite lumps smaller than 8 bytes (the smallest possible)
|
||||||
|
// in size -- this was used by some dmadds wads
|
||||||
|
// as an 'empty' graphics resource
|
||||||
|
DPrintf(DMSG_WARNING, " Skipped empty sprite %s (lump %d)\n", Lumps[j].getName(), j);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Lumps[j].Namespace = space;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// W_SkinHack
|
||||||
|
//
|
||||||
|
// Tests a wad file to see if it contains an S_SKIN marker. If it does,
|
||||||
|
// every lump in the wad is moved into a new namespace. Because skins are
|
||||||
|
// only supposed to replace player sprites, sounds, or faces, this should
|
||||||
|
// not be a problem. Yes, there are skins that replace more than that, but
|
||||||
|
// they are such a pain, and breaking them like this was done on purpose.
|
||||||
|
// This also renames any S_SKINxx lumps to just S_SKIN.
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
void FWadFile::SkinHack ()
|
||||||
|
{
|
||||||
|
// this being static is not a problem. The only relevant thing is that each skin gets a different number.
|
||||||
|
static int namespc = ns_firstskin;
|
||||||
|
bool skinned = false;
|
||||||
|
bool hasmap = false;
|
||||||
|
uint32_t i;
|
||||||
|
|
||||||
|
for (i = 0; i < NumLumps; i++)
|
||||||
|
{
|
||||||
|
FResourceLump *lump = &Lumps[i];
|
||||||
|
|
||||||
|
if (!strnicmp(lump->getName(), "S_SKIN", 6))
|
||||||
|
{ // Wad has at least one skin.
|
||||||
|
lump->LumpNameSetup("S_SKIN");
|
||||||
|
if (!skinned)
|
||||||
|
{
|
||||||
|
skinned = true;
|
||||||
|
uint32_t j;
|
||||||
|
|
||||||
|
for (j = 0; j < NumLumps; j++)
|
||||||
|
{
|
||||||
|
Lumps[j].Namespace = namespc;
|
||||||
|
}
|
||||||
|
namespc++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ((lump->getName()[0] == 'M' &&
|
||||||
|
lump->getName()[1] == 'A' &&
|
||||||
|
lump->getName()[2] == 'P' &&
|
||||||
|
lump->getName()[3] >= '0' && lump->getName()[3] <= '9' &&
|
||||||
|
lump->getName()[4] >= '0' && lump->getName()[4] <= '9' &&
|
||||||
|
lump->getName()[5] >= '\0')
|
||||||
|
||
|
||||||
|
(lump->getName()[0] == 'E' &&
|
||||||
|
lump->getName()[1] >= '0' && lump->getName()[1] <= '9' &&
|
||||||
|
lump->getName()[2] == 'M' &&
|
||||||
|
lump->getName()[3] >= '0' && lump->getName()[3] <= '9' &&
|
||||||
|
lump->getName()[4] >= '\0'))
|
||||||
|
{
|
||||||
|
hasmap = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (skinned && hasmap)
|
||||||
|
{
|
||||||
|
Printf (TEXTCOLOR_BLUE
|
||||||
|
"The maps in %s will not be loaded because it has a skin.\n"
|
||||||
|
TEXTCOLOR_BLUE
|
||||||
|
"You should remove the skin from the wad to play these maps.\n",
|
||||||
|
FileName.GetChars());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// File open
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
FResourceFile *CheckWad(const char *filename, FileReader &file, bool quiet, LumpFilterInfo* filter)
|
||||||
|
{
|
||||||
|
char head[4];
|
||||||
|
|
||||||
|
if (file.GetLength() >= 12)
|
||||||
|
{
|
||||||
|
file.Seek(0, FileReader::SeekSet);
|
||||||
|
file.Read(&head, 4);
|
||||||
|
file.Seek(0, FileReader::SeekSet);
|
||||||
|
if (!memcmp(head, "IWAD", 4) || !memcmp(head, "PWAD", 4))
|
||||||
|
{
|
||||||
|
FResourceFile *rf = new FWadFile(filename, file);
|
||||||
|
if (rf->Open(quiet, filter)) return rf;
|
||||||
|
|
||||||
|
file = std::move(rf->Reader); // to avoid destruction of reader
|
||||||
|
delete rf;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
158
source/common/filesystem/file_whres.cpp
Normal file
158
source/common/filesystem/file_whres.cpp
Normal file
|
@ -0,0 +1,158 @@
|
||||||
|
/*
|
||||||
|
** file_whres.cpp
|
||||||
|
**
|
||||||
|
** reads a Witchaven/TekWar sound resource file
|
||||||
|
**
|
||||||
|
**---------------------------------------------------------------------------
|
||||||
|
** Copyright 2009-2019 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 "resourcefile.h"
|
||||||
|
#include "printf.h"
|
||||||
|
#include "cmdlib.h"
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
struct whresentry
|
||||||
|
{
|
||||||
|
int filepospage, filelen, priority;
|
||||||
|
} ;
|
||||||
|
|
||||||
|
struct dpackheader_t
|
||||||
|
{
|
||||||
|
int ident; // == IDPAKHEADER
|
||||||
|
int dirofs;
|
||||||
|
int dirlen;
|
||||||
|
} ;
|
||||||
|
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// Wad file
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
class FWHResFile : public FUncompressedFile
|
||||||
|
{
|
||||||
|
FString basename;
|
||||||
|
public:
|
||||||
|
FWHResFile(const char * filename, FileReader &file);
|
||||||
|
bool Open(bool quiet, LumpFilterInfo* filter);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// FWadFile::FWadFile
|
||||||
|
//
|
||||||
|
// Initializes a WAD file
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
FWHResFile::FWHResFile(const char *filename, FileReader &file)
|
||||||
|
: FUncompressedFile(filename, file)
|
||||||
|
{
|
||||||
|
basename = ExtractFileBase(filename, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// Open it
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
bool FWHResFile::Open(bool quiet, LumpFilterInfo*)
|
||||||
|
{
|
||||||
|
int directory[1024];
|
||||||
|
|
||||||
|
Reader.Seek(-4096, FileReader::SeekEnd);
|
||||||
|
Reader.Read(directory, 4096);
|
||||||
|
|
||||||
|
int nl =1024/3;
|
||||||
|
Lumps.Resize(nl);
|
||||||
|
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
for(int k = 0; k < nl; k++)
|
||||||
|
{
|
||||||
|
int offset = LittleLong(directory[k*3]) * 4096;
|
||||||
|
int length = LittleLong(directory[k*3+1]);
|
||||||
|
if (length <= 0) break;
|
||||||
|
FStringf synthname("%s/%04d", basename.GetChars(), k);
|
||||||
|
Lumps[i].LumpNameSetup(synthname);
|
||||||
|
Lumps[i].Owner = this;
|
||||||
|
Lumps[i].Position = offset;
|
||||||
|
Lumps[i].LumpSize = length;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
NumLumps = i;
|
||||||
|
Lumps.Clamp(NumLumps);
|
||||||
|
Lumps.ShrinkToFit();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// File open
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
FResourceFile *CheckWHRes(const char *filename, FileReader &file, bool quiet, LumpFilterInfo* filter)
|
||||||
|
{
|
||||||
|
if (file.GetLength() >= 8192) // needs to be at least 8192 to contain one file and the directory.
|
||||||
|
{
|
||||||
|
int directory[1024];
|
||||||
|
int nl =1024/3;
|
||||||
|
|
||||||
|
file.Seek(-4096, FileReader::SeekEnd);
|
||||||
|
file.Read(directory, 4096);
|
||||||
|
|
||||||
|
int checkpos = 0;
|
||||||
|
for(int k = 0; k < nl; k++)
|
||||||
|
{
|
||||||
|
int offset = LittleLong(directory[k*3]);
|
||||||
|
int length = LittleLong(directory[k*3+1]);
|
||||||
|
if (length <= 0 && offset == 0) break;
|
||||||
|
if (offset != checkpos || length <= 0) return nullptr;
|
||||||
|
checkpos += (length+4095) / 4096;
|
||||||
|
}
|
||||||
|
FResourceFile *rf = new FWHResFile(filename, file);
|
||||||
|
if (rf->Open(quiet, filter)) return rf;
|
||||||
|
file = std::move(rf->Reader); // to avoid destruction of reader
|
||||||
|
delete rf;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
|
@ -34,15 +34,14 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <algorithm>
|
|
||||||
#include "printf.h"
|
|
||||||
#include "file_zip.h"
|
#include "file_zip.h"
|
||||||
#include "ancientzip.h"
|
#include "cmdlib.h"
|
||||||
#include "templates.h"
|
#include "templates.h"
|
||||||
//#include "v_text.h"
|
#include "printf.h"
|
||||||
//#include "w_wad.h"
|
|
||||||
#include "w_zip.h"
|
#include "w_zip.h"
|
||||||
|
|
||||||
|
#include "ancientzip.h"
|
||||||
|
|
||||||
#define BUFREADCOMMENT (0x400)
|
#define BUFREADCOMMENT (0x400)
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
@ -68,7 +67,7 @@ static bool UncompressZipLump(char *Cache, FileReader &Reader, int Method, int L
|
||||||
case METHOD_LZMA:
|
case METHOD_LZMA:
|
||||||
{
|
{
|
||||||
FileReader frz;
|
FileReader frz;
|
||||||
if (frz.OpenDecompressor(Reader, LumpSize, Method, false, nullptr))
|
if (frz.OpenDecompressor(Reader, LumpSize, Method, false, [](const char* err) { I_Error("%s", err); }))
|
||||||
{
|
{
|
||||||
frz.Read(Cache, LumpSize);
|
frz.Read(Cache, LumpSize);
|
||||||
}
|
}
|
||||||
|
@ -94,9 +93,9 @@ static bool UncompressZipLump(char *Cache, FileReader &Reader, int Method, int L
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (const CRecoverableError &err)
|
catch (CRecoverableError &err)
|
||||||
{
|
{
|
||||||
Printf("%s\n", err.what());
|
Printf("%s\n", err.GetMessage());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -125,7 +124,7 @@ static uint32_t Zip_FindCentralDir(FileReader &fin)
|
||||||
uint32_t uPosFound=0;
|
uint32_t uPosFound=0;
|
||||||
|
|
||||||
FileSize = (uint32_t)fin.GetLength();
|
FileSize = (uint32_t)fin.GetLength();
|
||||||
uMaxBack = std::min<uint32_t>(0xffff, FileSize);
|
uMaxBack = MIN<uint32_t>(0xffff, FileSize);
|
||||||
|
|
||||||
uBackRead = 4;
|
uBackRead = 4;
|
||||||
while (uBackRead < uMaxBack)
|
while (uBackRead < uMaxBack)
|
||||||
|
@ -138,7 +137,7 @@ static uint32_t Zip_FindCentralDir(FileReader &fin)
|
||||||
uBackRead += BUFREADCOMMENT;
|
uBackRead += BUFREADCOMMENT;
|
||||||
uReadPos = FileSize - uBackRead;
|
uReadPos = FileSize - uBackRead;
|
||||||
|
|
||||||
uReadSize = std::min<uint32_t>((BUFREADCOMMENT + 4), (FileSize - uReadPos));
|
uReadSize = MIN<uint32_t>((BUFREADCOMMENT + 4), (FileSize - uReadPos));
|
||||||
|
|
||||||
if (fin.Seek(uReadPos, FileReader::SeekSet) != 0) break;
|
if (fin.Seek(uReadPos, FileReader::SeekSet) != 0) break;
|
||||||
|
|
||||||
|
@ -171,7 +170,7 @@ FZipFile::FZipFile(const char * filename, FileReader &file)
|
||||||
Lumps = NULL;
|
Lumps = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FZipFile::Open(bool quiet)
|
bool FZipFile::Open(bool quiet, LumpFilterInfo* filter)
|
||||||
{
|
{
|
||||||
uint32_t centraldir = Zip_FindCentralDir(Reader);
|
uint32_t centraldir = Zip_FindCentralDir(Reader);
|
||||||
FZipEndOfCentralDirectory info;
|
FZipEndOfCentralDirectory info;
|
||||||
|
@ -181,7 +180,7 @@ bool FZipFile::Open(bool quiet)
|
||||||
|
|
||||||
if (centraldir == 0)
|
if (centraldir == 0)
|
||||||
{
|
{
|
||||||
if (!quiet) Printf("\n%s: ZIP file corrupt!\n", FileName.GetChars());
|
if (!quiet) Printf(TEXTCOLOR_RED "\n%s: ZIP file corrupt!\n", FileName.GetChars());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -193,7 +192,7 @@ bool FZipFile::Open(bool quiet)
|
||||||
if (info.NumEntries != info.NumEntriesOnAllDisks ||
|
if (info.NumEntries != info.NumEntriesOnAllDisks ||
|
||||||
info.FirstDisk != 0 || info.DiskNumber != 0)
|
info.FirstDisk != 0 || info.DiskNumber != 0)
|
||||||
{
|
{
|
||||||
if (!quiet) Printf("\n%s: Multipart Zip files are not supported.\n", FileName.GetChars());
|
if (!quiet) Printf(TEXTCOLOR_RED "\n%s: Multipart Zip files are not supported.\n", FileName.GetChars());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -209,6 +208,61 @@ bool FZipFile::Open(bool quiet)
|
||||||
char *dirptr = (char*)directory;
|
char *dirptr = (char*)directory;
|
||||||
FZipLump *lump_p = Lumps;
|
FZipLump *lump_p = Lumps;
|
||||||
|
|
||||||
|
FString name0;
|
||||||
|
bool foundspeciallump = false;
|
||||||
|
|
||||||
|
// Check if all files have the same prefix so that this can be stripped out.
|
||||||
|
// This will only be done if there is either a MAPINFO, ZMAPINFO or GAMEINFO lump in the subdirectory, denoting a ZDoom mod.
|
||||||
|
if (NumLumps > 1) for (uint32_t i = 0; i < NumLumps; i++)
|
||||||
|
{
|
||||||
|
FZipCentralDirectoryInfo *zip_fh = (FZipCentralDirectoryInfo *)dirptr;
|
||||||
|
|
||||||
|
int len = LittleShort(zip_fh->NameLength);
|
||||||
|
FString name(dirptr + sizeof(FZipCentralDirectoryInfo), len);
|
||||||
|
|
||||||
|
dirptr += sizeof(FZipCentralDirectoryInfo) +
|
||||||
|
LittleShort(zip_fh->NameLength) +
|
||||||
|
LittleShort(zip_fh->ExtraLength) +
|
||||||
|
LittleShort(zip_fh->CommentLength);
|
||||||
|
|
||||||
|
if (dirptr > ((char*)directory) + dirsize) // This directory entry goes beyond the end of the file.
|
||||||
|
{
|
||||||
|
free(directory);
|
||||||
|
if (!quiet) Printf(TEXTCOLOR_RED "\n%s: Central directory corrupted.", FileName.GetChars());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
name.ToLower();
|
||||||
|
if (i == 0)
|
||||||
|
{
|
||||||
|
// check for special names, if one of these gets found this must be treated as a normal zip.
|
||||||
|
bool isspecial = name.IndexOf("/") < 0 || (filter && filter->reservedFolders.Find(name) < filter->reservedFolders.Size());
|
||||||
|
if (isspecial) break;
|
||||||
|
name0 = name;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (name.IndexOf(name0) != 0)
|
||||||
|
{
|
||||||
|
name0 = "";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (!foundspeciallump && filter)
|
||||||
|
{
|
||||||
|
// at least one of the more common definition lumps must be present.
|
||||||
|
for (auto &p : filter->requiredPrefixes)
|
||||||
|
{
|
||||||
|
if (name.IndexOf(name0 + p) == 0)
|
||||||
|
{
|
||||||
|
foundspeciallump = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// If it ran through the list without finding anything it should not attempt any path remapping.
|
||||||
|
if (!foundspeciallump) name0 = "";
|
||||||
|
|
||||||
dirptr = (char*)directory;
|
dirptr = (char*)directory;
|
||||||
lump_p = Lumps;
|
lump_p = Lumps;
|
||||||
|
@ -218,6 +272,7 @@ bool FZipFile::Open(bool quiet)
|
||||||
|
|
||||||
int len = LittleShort(zip_fh->NameLength);
|
int len = LittleShort(zip_fh->NameLength);
|
||||||
FString name(dirptr + sizeof(FZipCentralDirectoryInfo), len);
|
FString name(dirptr + sizeof(FZipCentralDirectoryInfo), len);
|
||||||
|
if (name0.IsNotEmpty()) name = name.Mid(name0.Len());
|
||||||
dirptr += sizeof(FZipCentralDirectoryInfo) +
|
dirptr += sizeof(FZipCentralDirectoryInfo) +
|
||||||
LittleShort(zip_fh->NameLength) +
|
LittleShort(zip_fh->NameLength) +
|
||||||
LittleShort(zip_fh->ExtraLength) +
|
LittleShort(zip_fh->ExtraLength) +
|
||||||
|
@ -226,7 +281,7 @@ bool FZipFile::Open(bool quiet)
|
||||||
if (dirptr > ((char*)directory) + dirsize) // This directory entry goes beyond the end of the file.
|
if (dirptr > ((char*)directory) + dirsize) // This directory entry goes beyond the end of the file.
|
||||||
{
|
{
|
||||||
free(directory);
|
free(directory);
|
||||||
if (!quiet) Printf("\n%s: Central directory corrupted.", FileName.GetChars());
|
if (!quiet) Printf(TEXTCOLOR_RED "\n%s: Central directory corrupted.", FileName.GetChars());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -246,7 +301,7 @@ bool FZipFile::Open(bool quiet)
|
||||||
zip_fh->Method != METHOD_IMPLODE &&
|
zip_fh->Method != METHOD_IMPLODE &&
|
||||||
zip_fh->Method != METHOD_SHRINK)
|
zip_fh->Method != METHOD_SHRINK)
|
||||||
{
|
{
|
||||||
if (!quiet) Printf("\n%s: '%s' uses an unsupported compression algorithm (#%d).\n", FileName.GetChars(), name.GetChars(), zip_fh->Method);
|
if (!quiet) Printf(TEXTCOLOR_YELLOW "\n%s: '%s' uses an unsupported compression algorithm (#%d).\n", FileName.GetChars(), name.GetChars(), zip_fh->Method);
|
||||||
skipped++;
|
skipped++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -254,34 +309,36 @@ bool FZipFile::Open(bool quiet)
|
||||||
zip_fh->Flags = LittleShort(zip_fh->Flags);
|
zip_fh->Flags = LittleShort(zip_fh->Flags);
|
||||||
if (zip_fh->Flags & ZF_ENCRYPTED)
|
if (zip_fh->Flags & ZF_ENCRYPTED)
|
||||||
{
|
{
|
||||||
if (!quiet) Printf("\n%s: '%s' is encrypted. Encryption is not supported.\n", FileName.GetChars(), name.GetChars());
|
if (!quiet) Printf(TEXTCOLOR_YELLOW "\n%s: '%s' is encrypted. Encryption is not supported.\n", FileName.GetChars(), name.GetChars());
|
||||||
skipped++;
|
skipped++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
name.Substitute("\\", "/");
|
FixPathSeperator(name);
|
||||||
name.ToLower();
|
name.ToLower();
|
||||||
|
|
||||||
lump_p->LumpNameSetup(name);
|
lump_p->LumpNameSetup(name);
|
||||||
lump_p->LumpSize = LittleLong(zip_fh->UncompressedSize);
|
lump_p->LumpSize = LittleLong(zip_fh->UncompressedSize);
|
||||||
lump_p->Owner = this;
|
lump_p->Owner = this;
|
||||||
// The start of the Reader will be determined the first time it is accessed.
|
// The start of the Reader will be determined the first time it is accessed.
|
||||||
lump_p->Flags = LUMPF_ZIPFILE | LUMPFZIP_NEEDFILESTART;
|
lump_p->Flags = LUMPF_FULLPATH;
|
||||||
|
lump_p->NeedFileStart = true;
|
||||||
lump_p->Method = uint8_t(zip_fh->Method);
|
lump_p->Method = uint8_t(zip_fh->Method);
|
||||||
if (lump_p->Method != METHOD_STORED) lump_p->Flags |= LUMPF_COMPRESSED;
|
if (lump_p->Method != METHOD_STORED) lump_p->Flags |= LUMPF_COMPRESSED;
|
||||||
lump_p->GPFlags = zip_fh->Flags;
|
lump_p->GPFlags = zip_fh->Flags;
|
||||||
lump_p->CRC32 = zip_fh->CRC32;
|
lump_p->CRC32 = zip_fh->CRC32;
|
||||||
lump_p->CompressedSize = LittleLong(zip_fh->CompressedSize);
|
lump_p->CompressedSize = LittleLong(zip_fh->CompressedSize);
|
||||||
lump_p->Position = LittleLong(zip_fh->LocalHeaderOffset);
|
lump_p->Position = LittleLong(zip_fh->LocalHeaderOffset);
|
||||||
|
lump_p->CheckEmbedded();
|
||||||
|
|
||||||
lump_p++;
|
lump_p++;
|
||||||
}
|
}
|
||||||
// Resize the lump record array to its actual size
|
// Resize the lump record array to its actual size
|
||||||
NumLumps -= skipped;
|
NumLumps -= skipped;
|
||||||
free(directory);
|
free(directory);
|
||||||
if (!quiet) Printf(", %d lumps\n", NumLumps);
|
|
||||||
|
|
||||||
PostProcessArchive(&Lumps[0], sizeof(FZipLump));
|
GenerateHash();
|
||||||
|
PostProcessArchive(&Lumps[0], sizeof(FZipLump), filter);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -305,7 +362,7 @@ FZipFile::~FZipFile()
|
||||||
FCompressedBuffer FZipLump::GetRawData()
|
FCompressedBuffer FZipLump::GetRawData()
|
||||||
{
|
{
|
||||||
FCompressedBuffer cbuf = { (unsigned)LumpSize, (unsigned)CompressedSize, Method, GPFlags, CRC32, new char[CompressedSize] };
|
FCompressedBuffer cbuf = { (unsigned)LumpSize, (unsigned)CompressedSize, Method, GPFlags, CRC32, new char[CompressedSize] };
|
||||||
if (Flags & LUMPFZIP_NEEDFILESTART) SetLumpAddress();
|
if (NeedFileStart) SetLumpAddress();
|
||||||
Owner->Reader.Seek(Position, FileReader::SeekSet);
|
Owner->Reader.Seek(Position, FileReader::SeekSet);
|
||||||
Owner->Reader.Read(cbuf.mBuffer, CompressedSize);
|
Owner->Reader.Read(cbuf.mBuffer, CompressedSize);
|
||||||
return cbuf;
|
return cbuf;
|
||||||
|
@ -329,7 +386,7 @@ void FZipLump::SetLumpAddress()
|
||||||
Owner->Reader.Read(&localHeader, sizeof(localHeader));
|
Owner->Reader.Read(&localHeader, sizeof(localHeader));
|
||||||
skiplen = LittleShort(localHeader.NameLength) + LittleShort(localHeader.ExtraLength);
|
skiplen = LittleShort(localHeader.NameLength) + LittleShort(localHeader.ExtraLength);
|
||||||
Position += sizeof(localHeader) + skiplen;
|
Position += sizeof(localHeader) + skiplen;
|
||||||
Flags &= ~LUMPFZIP_NEEDFILESTART;
|
NeedFileStart = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
@ -344,7 +401,7 @@ FileReader *FZipLump::GetReader()
|
||||||
// In that case always force caching of the lump
|
// In that case always force caching of the lump
|
||||||
if (Method == METHOD_STORED)
|
if (Method == METHOD_STORED)
|
||||||
{
|
{
|
||||||
if (Flags & LUMPFZIP_NEEDFILESTART) SetLumpAddress();
|
if (NeedFileStart) SetLumpAddress();
|
||||||
Owner->Reader.Seek(Position, FileReader::SeekSet);
|
Owner->Reader.Seek(Position, FileReader::SeekSet);
|
||||||
return &Owner->Reader;
|
return &Owner->Reader;
|
||||||
}
|
}
|
||||||
|
@ -357,13 +414,23 @@ FileReader *FZipLump::GetReader()
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
int FZipLump::ValidateCache()
|
int FZipLump::FillCache()
|
||||||
{
|
{
|
||||||
if (Flags & LUMPFZIP_NEEDFILESTART) SetLumpAddress();
|
if (NeedFileStart) SetLumpAddress();
|
||||||
|
const char *buffer;
|
||||||
|
|
||||||
|
if (Method == METHOD_STORED && (buffer = Owner->Reader.GetBuffer()) != NULL)
|
||||||
|
{
|
||||||
|
// This is an in-memory file so the cache can point directly to the file's data.
|
||||||
|
Cache = const_cast<char*>(buffer) + Position;
|
||||||
|
RefCount = -1;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
Owner->Reader.Seek(Position, FileReader::SeekSet);
|
Owner->Reader.Seek(Position, FileReader::SeekSet);
|
||||||
Cache.Resize(LumpSize);
|
Cache = new char[LumpSize];
|
||||||
UncompressZipLump((char*)Cache.Data(), Owner->Reader, Method, LumpSize, CompressedSize, GPFlags);
|
UncompressZipLump(Cache, Owner->Reader, Method, LumpSize, CompressedSize, GPFlags);
|
||||||
|
RefCount = 1;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -376,7 +443,7 @@ int FZipLump::ValidateCache()
|
||||||
int FZipLump::GetFileOffset()
|
int FZipLump::GetFileOffset()
|
||||||
{
|
{
|
||||||
if (Method != METHOD_STORED) return -1;
|
if (Method != METHOD_STORED) return -1;
|
||||||
if (Flags & LUMPFZIP_NEEDFILESTART) SetLumpAddress();
|
if (NeedFileStart) SetLumpAddress();
|
||||||
return Position;
|
return Position;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -386,7 +453,7 @@ int FZipLump::GetFileOffset()
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
FResourceFile *CheckZip(const char *filename, FileReader &file, bool quiet)
|
FResourceFile *CheckZip(const char *filename, FileReader &file, bool quiet, LumpFilterInfo* filter)
|
||||||
{
|
{
|
||||||
char head[4];
|
char head[4];
|
||||||
|
|
||||||
|
@ -398,7 +465,7 @@ FResourceFile *CheckZip(const char *filename, FileReader &file, bool quiet)
|
||||||
if (!memcmp(head, "PK\x3\x4", 4))
|
if (!memcmp(head, "PK\x3\x4", 4))
|
||||||
{
|
{
|
||||||
FResourceFile *rf = new FZipFile(filename, file);
|
FResourceFile *rf = new FZipFile(filename, file);
|
||||||
if (rf->Open(quiet)) return rf;
|
if (rf->Open(quiet, filter)) return rf;
|
||||||
|
|
||||||
file = std::move(rf->Reader); // to avoid destruction of reader
|
file = std::move(rf->Reader); // to avoid destruction of reader
|
||||||
delete rf;
|
delete rf;
|
|
@ -3,11 +3,6 @@
|
||||||
|
|
||||||
#include "resourcefile.h"
|
#include "resourcefile.h"
|
||||||
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
LUMPFZIP_NEEDFILESTART = 128
|
|
||||||
};
|
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
// Zip Lump
|
// Zip Lump
|
||||||
|
@ -18,17 +13,18 @@ struct FZipLump : public FResourceLump
|
||||||
{
|
{
|
||||||
uint16_t GPFlags;
|
uint16_t GPFlags;
|
||||||
uint8_t Method;
|
uint8_t Method;
|
||||||
|
bool NeedFileStart;
|
||||||
int CompressedSize;
|
int CompressedSize;
|
||||||
int Position;
|
int Position;
|
||||||
unsigned CRC32;
|
unsigned CRC32;
|
||||||
|
|
||||||
virtual FileReader *GetReader() override;
|
virtual FileReader *GetReader();
|
||||||
virtual int ValidateCache() override;
|
virtual int FillCache();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void SetLumpAddress();
|
void SetLumpAddress();
|
||||||
virtual int GetFileOffset() override;
|
virtual int GetFileOffset();
|
||||||
FCompressedBuffer GetRawData() override;
|
FCompressedBuffer GetRawData();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -45,7 +41,7 @@ class FZipFile : public FResourceFile
|
||||||
public:
|
public:
|
||||||
FZipFile(const char * filename, FileReader &file);
|
FZipFile(const char * filename, FileReader &file);
|
||||||
virtual ~FZipFile();
|
virtual ~FZipFile();
|
||||||
bool Open(bool quiet);
|
bool Open(bool quiet, LumpFilterInfo* filter);
|
||||||
virtual FResourceLump *GetLump(int no) { return ((unsigned)no < NumLumps)? &Lumps[no] : NULL; }
|
virtual FResourceLump *GetLump(int no) { return ((unsigned)no < NumLumps)? &Lumps[no] : NULL; }
|
||||||
};
|
};
|
||||||
|
|
1707
source/common/filesystem/filesystem.cpp
Normal file
1707
source/common/filesystem/filesystem.cpp
Normal file
File diff suppressed because it is too large
Load diff
237
source/common/filesystem/filesystem.h
Normal file
237
source/common/filesystem/filesystem.h
Normal file
|
@ -0,0 +1,237 @@
|
||||||
|
#pragma once
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// DESCRIPTION:
|
||||||
|
// File system I/O functions.
|
||||||
|
//
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include "files.h"
|
||||||
|
#include "tarray.h"
|
||||||
|
#include "cmdlib.h"
|
||||||
|
#include "zstring.h"
|
||||||
|
#include "resourcefile.h"
|
||||||
|
|
||||||
|
class FResourceFile;
|
||||||
|
struct FResourceLump;
|
||||||
|
class FTexture;
|
||||||
|
|
||||||
|
union LumpShortName
|
||||||
|
{
|
||||||
|
char String[9];
|
||||||
|
|
||||||
|
uint32_t dword; // These are for accessing the first 4 or 8 chars of
|
||||||
|
uint64_t qword; // Name as a unit without breaking strict aliasing rules
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// A lump in memory.
|
||||||
|
class FileData
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FileData ();
|
||||||
|
|
||||||
|
FileData (const FileData ©);
|
||||||
|
FileData &operator= (const FileData ©);
|
||||||
|
~FileData ();
|
||||||
|
void *GetMem () { return Block.Len() == 0 ? NULL : (void *)Block.GetChars(); }
|
||||||
|
size_t GetSize () { return Block.Len(); }
|
||||||
|
FString GetString () { return Block; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
FileData (const FString &source);
|
||||||
|
|
||||||
|
FString Block;
|
||||||
|
|
||||||
|
friend class FileSystem;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct FolderEntry
|
||||||
|
{
|
||||||
|
const char *name;
|
||||||
|
unsigned lumpnum;
|
||||||
|
};
|
||||||
|
|
||||||
|
class FileSystem
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FileSystem ();
|
||||||
|
~FileSystem ();
|
||||||
|
|
||||||
|
// The wadnum for the IWAD
|
||||||
|
int GetIwadNum() { return IwadIndex; }
|
||||||
|
void SetIwadNum(int x) { IwadIndex = x; }
|
||||||
|
|
||||||
|
int GetMaxIwadNum() { return MaxIwadIndex; }
|
||||||
|
void SetMaxIwadNum(int x) { MaxIwadIndex = x; }
|
||||||
|
|
||||||
|
void InitSingleFile(const char *filename, bool quiet = false);
|
||||||
|
void InitMultipleFiles (TArray<FString> &filenames, bool quiet = false, LumpFilterInfo* filter = nullptr);
|
||||||
|
void AddFile (const char *filename, FileReader *wadinfo, bool quiet, LumpFilterInfo* filter);
|
||||||
|
int CheckIfResourceFileLoaded (const char *name) noexcept;
|
||||||
|
void AddAdditionalFile(const char* filename, FileReader* wadinfo = NULL) {}
|
||||||
|
|
||||||
|
const char *GetResourceFileName (int filenum) const noexcept;
|
||||||
|
const char *GetResourceFileFullName (int wadnum) const noexcept;
|
||||||
|
|
||||||
|
int GetFirstEntry(int wadnum) const noexcept;
|
||||||
|
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);
|
||||||
|
|
||||||
|
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 FString &name) { return CheckNumForName (name.GetChars()); }
|
||||||
|
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 FString &name) { return GetNumForName (name.GetChars(), 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); }
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
return CheckNumForFullName(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FileExists(const char* name)
|
||||||
|
{
|
||||||
|
return FindFile(name) >= 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FileExists(const FString& name)
|
||||||
|
{
|
||||||
|
return FindFile(name) >= 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FileExists(const std::string& name)
|
||||||
|
{
|
||||||
|
return FindFile(name.c_str()) >= 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
LumpShortName& GetShortName(int i); // may only be called before the hash chains are set up.
|
||||||
|
void RenameFile(int num, const char* fn);
|
||||||
|
bool CreatePathlessCopy(const char* name, int id, int flags);
|
||||||
|
|
||||||
|
inline int CheckNumForFullName(const FString &name, bool trynormal = false, int namespc = ns_global) { return CheckNumForFullName(name.GetChars(), trynormal, namespc); }
|
||||||
|
inline int CheckNumForFullName (const FString &name, int wadfile) { return CheckNumForFullName(name.GetChars(), wadfile); }
|
||||||
|
inline int GetNumForFullName (const FString &name) { return GetNumForFullName(name.GetChars()); }
|
||||||
|
|
||||||
|
void SetLinkedTexture(int lump, FTexture *tex);
|
||||||
|
FTexture *GetLinkedTexture(int lump);
|
||||||
|
|
||||||
|
|
||||||
|
void ReadFile (int lump, void *dest);
|
||||||
|
TArray<uint8_t> GetFileData(int lump, int pad = 0); // reads lump into a writable buffer and optionally adds some padding at the end. (FileData isn't writable!)
|
||||||
|
FileData ReadFile (int lump);
|
||||||
|
FileData ReadFile (const char *name) { return ReadFile (GetNumForName (name)); }
|
||||||
|
|
||||||
|
inline TArray<uint8_t> LoadFile(const char* name, int padding = 0)
|
||||||
|
{
|
||||||
|
auto lump = FindFile(name);
|
||||||
|
if (lump < 0) return TArray<uint8_t>();
|
||||||
|
return GetFileData(lump, padding);
|
||||||
|
}
|
||||||
|
|
||||||
|
FileReader OpenFileReader(int lump); // opens a reader that redirects to the containing file's one.
|
||||||
|
FileReader ReopenFileReader(int lump, bool alwayscache = false); // opens an independent reader.
|
||||||
|
FileReader OpenFileReader(const char* name);
|
||||||
|
|
||||||
|
int FindLump (const char *name, int *lastlump, bool anyns=false); // [RH] Find lumps with duplication
|
||||||
|
int FindLumpMulti (const char **names, int *lastlump, bool anyns = false, int *nameindex = NULL); // same with multiple possible names
|
||||||
|
int FindLumpFullName(const char* name, int* lastlump, bool noext = false);
|
||||||
|
bool CheckFileName (int lump, const char *name); // [RH] True if lump's name == name
|
||||||
|
|
||||||
|
int FindFileWithExtensions(const char* name, const char* const* exts, int count);
|
||||||
|
int FindResource(int resid, const char* type, int filenum = -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
|
||||||
|
void GetFileShortName (char *to, int lump) const; // [RH] Copies the lump name to to using uppercopy
|
||||||
|
void GetFileShortName (FString &to, int lump) const;
|
||||||
|
const char* GetFileShortName(int lump) const;
|
||||||
|
const char *GetFileFullName (int lump, bool returnshort = true) const; // [RH] Returns the lump's full name
|
||||||
|
FString GetFileFullPath (int lump) const; // [RH] Returns wad's name + lump's full name
|
||||||
|
int GetFileContainer (int lump) const; // [RH] Returns wadnum for a specified lump
|
||||||
|
int GetFileNamespace (int lump) const; // [RH] Returns the namespace a lump belongs to
|
||||||
|
void SetFileNamespace(int lump, int ns);
|
||||||
|
int GetResourceId(int lump) const; // Returns the RFF index number for this lump
|
||||||
|
const char* GetResourceType(int lump) const;
|
||||||
|
bool CheckFileName (int lump, const char *name) const; // [RH] Returns true if the names match
|
||||||
|
unsigned GetFilesInFolder(const char *path, TArray<FolderEntry> &result, bool atomic) const;
|
||||||
|
|
||||||
|
int GetNumEntries() const
|
||||||
|
{
|
||||||
|
return NumEntries;
|
||||||
|
}
|
||||||
|
|
||||||
|
int GetNumWads() const
|
||||||
|
{
|
||||||
|
return Files.Size();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AddLump(FResourceLump* lump);
|
||||||
|
int AddExternalFile(const char *filename);
|
||||||
|
int AddFromBuffer(const char* name, const char* type, char* data, int size, int id, int flags);
|
||||||
|
FileReader* GetFileReader(int wadnum); // Gets a FileReader object to the entire WAD
|
||||||
|
void InitHashChains();
|
||||||
|
|
||||||
|
// Blood stuff
|
||||||
|
FResourceLump* Lookup(const char* name, const char* type);
|
||||||
|
FResourceLump* Lookup(unsigned int id, const char* type);
|
||||||
|
|
||||||
|
FResourceLump* GetFileAt(int no);
|
||||||
|
|
||||||
|
const void* Lock(int lump);
|
||||||
|
void Unlock(int lump);
|
||||||
|
const void* Get(int lump);
|
||||||
|
static const void* Lock(FResourceLump* lump);
|
||||||
|
static void Unlock(FResourceLump* lump);
|
||||||
|
static const void* Load(FResourceLump* lump);;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
struct LumpRecord;
|
||||||
|
|
||||||
|
TArray<FResourceFile *> Files;
|
||||||
|
TArray<LumpRecord> FileInfo;
|
||||||
|
|
||||||
|
TArray<uint32_t> Hashes; // one allocation for all hash lists.
|
||||||
|
uint32_t *FirstLumpIndex; // [RH] Hashing stuff moved out of lumpinfo structure
|
||||||
|
uint32_t *NextLumpIndex;
|
||||||
|
|
||||||
|
uint32_t *FirstLumpIndex_FullName; // The same information for fully qualified paths from .zips
|
||||||
|
uint32_t *NextLumpIndex_FullName;
|
||||||
|
|
||||||
|
uint32_t *FirstLumpIndex_NoExt; // The same information for fully qualified paths from .zips
|
||||||
|
uint32_t *NextLumpIndex_NoExt;
|
||||||
|
|
||||||
|
uint32_t* FirstLumpIndex_ResId; // The same information for fully qualified paths from .zips
|
||||||
|
uint32_t* NextLumpIndex_ResId;
|
||||||
|
|
||||||
|
uint32_t NumEntries = 0; // Not necessarily the same as FileInfo.Size()
|
||||||
|
uint32_t NumWads;
|
||||||
|
|
||||||
|
int IwadIndex = -1;
|
||||||
|
int MaxIwadIndex = -1;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void DeleteAll();
|
||||||
|
void MoveLumpsInFolder(const char *);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
extern FileSystem fileSystem;
|
||||||
|
|
|
@ -36,10 +36,9 @@
|
||||||
|
|
||||||
#include <zlib.h>
|
#include <zlib.h>
|
||||||
#include "resourcefile.h"
|
#include "resourcefile.h"
|
||||||
#include "name.h"
|
|
||||||
#include "m_swap.h"
|
|
||||||
#include "gamecontrol.h"
|
|
||||||
#include "cmdlib.h"
|
#include "cmdlib.h"
|
||||||
|
#include "md5.h"
|
||||||
|
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
|
@ -55,13 +54,13 @@ public:
|
||||||
FLumpReader(FResourceLump *src)
|
FLumpReader(FResourceLump *src)
|
||||||
: MemoryReader(NULL, src->LumpSize), source(src)
|
: MemoryReader(NULL, src->LumpSize), source(src)
|
||||||
{
|
{
|
||||||
bufptr = (const char*)src->Lock();
|
src->Lock();
|
||||||
src->Cache.Data();
|
bufptr = src->Cache;
|
||||||
}
|
}
|
||||||
|
|
||||||
~FLumpReader()
|
~FLumpReader()
|
||||||
{
|
{
|
||||||
source->Unlock(true);
|
source->Unlock();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -74,34 +73,82 @@ public:
|
||||||
|
|
||||||
FResourceLump::~FResourceLump()
|
FResourceLump::~FResourceLump()
|
||||||
{
|
{
|
||||||
|
if (Cache != NULL && RefCount >= 0)
|
||||||
|
{
|
||||||
|
delete [] Cache;
|
||||||
|
Cache = NULL;
|
||||||
|
}
|
||||||
Owner = NULL;
|
Owner = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
// Sets up the file name information
|
// Sets up the lump name information for anything not coming from a WAD file.
|
||||||
// This is stored as FNames for various formats.
|
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
void FResourceLump::LumpNameSetup(FString iname)
|
void FResourceLump::LumpNameSetup(FString iname)
|
||||||
{
|
{
|
||||||
auto pathLen = iname.LastIndexOf('/') + 1;
|
// this causes interference with real Dehacked lumps.
|
||||||
LumpName[FullNameType] = iname.GetChars();
|
if (!iname.CompareNoCase("dehacked.exe"))
|
||||||
LumpName[BaseNameType] = iname.GetChars() + pathLen;
|
|
||||||
|
|
||||||
auto extStart = iname.LastIndexOf('.');
|
|
||||||
if (extStart <= pathLen) extStart = -1;
|
|
||||||
if (extStart > 0)
|
|
||||||
{
|
{
|
||||||
LumpName[ExtensionType] = iname.GetChars() + extStart + 1;
|
iname = "";
|
||||||
iname.Truncate(extStart);
|
|
||||||
}
|
}
|
||||||
LumpName[FullNameNoExtType] = iname.GetChars();
|
|
||||||
LumpName[BaseNameNoExtType] = iname.GetChars() + pathLen;
|
FullName = iname;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// Checks for embedded resource files
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
static bool IsWadInFolder(const FResourceFile* const archive, const char* const resPath)
|
||||||
|
{
|
||||||
|
// Checks a special case when <somefile.wad> was put in
|
||||||
|
// <myproject> directory inside <myproject.zip>
|
||||||
|
|
||||||
|
if (NULL == archive)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const FString dirName = ExtractFileBase(archive->FileName);
|
||||||
|
const FString fileName = ExtractFileBase(resPath, true);
|
||||||
|
const FString filePath = dirName + '/' + fileName;
|
||||||
|
|
||||||
|
return 0 == filePath.CompareNoCase(resPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FResourceLump::CheckEmbedded()
|
||||||
|
{
|
||||||
|
// Checks for embedded archives
|
||||||
|
const char *c = strstr(FullName, ".wad");
|
||||||
|
if (c && strlen(c) == 4 && (!strchr(FullName, '/') || IsWadInFolder(Owner, FullName)))
|
||||||
|
{
|
||||||
|
Flags |= LUMPF_EMBEDDED;
|
||||||
|
}
|
||||||
|
/* later
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (c==NULL) c = strstr(Name, ".zip");
|
||||||
|
if (c==NULL) c = strstr(Name, ".pk3");
|
||||||
|
if (c==NULL) c = strstr(Name, ".7z");
|
||||||
|
if (c==NULL) c = strstr(Name, ".pak");
|
||||||
|
if (c && strlen(c) <= 4)
|
||||||
|
{
|
||||||
|
// Mark all embedded archives in any directory
|
||||||
|
Flags |= LUMPF_EMBEDDED;
|
||||||
|
memset(Name, 0, 8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
// this is just for completeness. For non-Zips only an uncompressed lump can
|
// this is just for completeness. For non-Zips only an uncompressed lump can
|
||||||
|
@ -113,8 +160,8 @@ FCompressedBuffer FResourceLump::GetRawData()
|
||||||
{
|
{
|
||||||
FCompressedBuffer cbuf = { (unsigned)LumpSize, (unsigned)LumpSize, METHOD_STORED, 0, 0, new char[LumpSize] };
|
FCompressedBuffer cbuf = { (unsigned)LumpSize, (unsigned)LumpSize, METHOD_STORED, 0, 0, new char[LumpSize] };
|
||||||
memcpy(cbuf.mBuffer, Lock(), LumpSize);
|
memcpy(cbuf.mBuffer, Lock(), LumpSize);
|
||||||
|
Unlock();
|
||||||
cbuf.mCRC32 = crc32(0, (uint8_t*)cbuf.mBuffer, LumpSize);
|
cbuf.mCRC32 = crc32(0, (uint8_t*)cbuf.mBuffer, LumpSize);
|
||||||
Unlock(true);
|
|
||||||
return cbuf;
|
return cbuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -149,33 +196,15 @@ FileReader FResourceLump::NewReader()
|
||||||
|
|
||||||
void *FResourceLump::Lock()
|
void *FResourceLump::Lock()
|
||||||
{
|
{
|
||||||
if (Cache.Size())
|
if (Cache != NULL)
|
||||||
{
|
{
|
||||||
if (RefCount > 0) RefCount++;
|
if (RefCount > 0) RefCount++;
|
||||||
}
|
}
|
||||||
else if (LumpSize > 0)
|
else if (LumpSize > 0)
|
||||||
{
|
{
|
||||||
ValidateCache();
|
FillCache();
|
||||||
// NBlood has some endian conversion right in here which is extremely dangerous and needs to be handled differently.
|
|
||||||
// Fortunately Big Endian platforms are mostly irrelevant so this is something to be sorted out later (if ever)
|
|
||||||
RefCount++;
|
|
||||||
}
|
}
|
||||||
return Cache.Data();
|
return Cache;
|
||||||
}
|
|
||||||
|
|
||||||
//==========================================================================
|
|
||||||
//
|
|
||||||
// Caches a lump's content without increasing the reference counter
|
|
||||||
//
|
|
||||||
//==========================================================================
|
|
||||||
|
|
||||||
void *FResourceLump::Get()
|
|
||||||
{
|
|
||||||
if (Cache.Size() == 0)
|
|
||||||
{
|
|
||||||
ValidateCache();
|
|
||||||
}
|
|
||||||
return Cache.Data();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
@ -184,15 +213,17 @@ void *FResourceLump::Get()
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
void FResourceLump::Unlock(bool mayfree)
|
int FResourceLump::Unlock()
|
||||||
{
|
{
|
||||||
if (LumpSize > 0 && RefCount > 0)
|
if (LumpSize > 0 && RefCount > 0)
|
||||||
{
|
{
|
||||||
if (--RefCount == 0)
|
if (--RefCount == 0)
|
||||||
{
|
{
|
||||||
if (mayfree) Cache.Reset();
|
delete [] Cache;
|
||||||
|
Cache = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return RefCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
@ -201,53 +232,45 @@ void FResourceLump::Unlock(bool mayfree)
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
typedef FResourceFile * (*CheckFunc)(const char *filename, FileReader &file, bool quiet);
|
typedef FResourceFile * (*CheckFunc)(const char *filename, FileReader &file, bool quiet, LumpFilterInfo* filter);
|
||||||
|
|
||||||
FResourceFile *CheckWad(const char *filename, FileReader &file, bool quiet);
|
FResourceFile *CheckWad(const char *filename, FileReader &file, bool quiet, LumpFilterInfo* filter);
|
||||||
FResourceFile *CheckGRP(const char *filename, FileReader &file, bool quiet);
|
FResourceFile *CheckGRP(const char *filename, FileReader &file, bool quiet, LumpFilterInfo* filter);
|
||||||
FResourceFile *CheckRFF(const char *filename, FileReader &file, bool quiet);
|
FResourceFile *CheckRFF(const char *filename, FileReader &file, bool quiet, LumpFilterInfo* filter);
|
||||||
FResourceFile *CheckPak(const char *filename, FileReader &file, bool quiet);
|
FResourceFile *CheckPak(const char *filename, FileReader &file, bool quiet, LumpFilterInfo* filter);
|
||||||
FResourceFile *CheckZip(const char *filename, FileReader &file, bool quiet);
|
FResourceFile *CheckZip(const char *filename, FileReader &file, bool quiet, LumpFilterInfo* filter);
|
||||||
FResourceFile *Check7Z(const char *filename, FileReader &file, bool quiet);
|
FResourceFile *Check7Z(const char *filename, FileReader &file, bool quiet, LumpFilterInfo* filter);
|
||||||
FResourceFile *CheckLump(const char *filename,FileReader &file, bool quiet);
|
FResourceFile *CheckLump(const char *filename,FileReader &file, bool quiet, LumpFilterInfo* filter);
|
||||||
FResourceFile *CheckDir(const char *filename, bool quiet, bool nosubdirflag);
|
FResourceFile *CheckDir(const char *filename, bool quiet, bool nosub, LumpFilterInfo* filter);
|
||||||
|
|
||||||
static CheckFunc funcs[] = { CheckGRP, CheckRFF, CheckZip, Check7Z, CheckPak, CheckLump };
|
static CheckFunc funcs[] = { CheckWad, CheckZip, Check7Z, CheckPak, CheckGRP, CheckRFF, CheckLump };
|
||||||
|
|
||||||
FResourceFile *FResourceFile::DoOpenResourceFile(const char *filename, FileReader &file, bool quiet, bool containeronly)
|
FResourceFile *FResourceFile::DoOpenResourceFile(const char *filename, FileReader &file, bool quiet, bool containeronly, LumpFilterInfo* filter)
|
||||||
{
|
{
|
||||||
for(size_t i = 0; i < countof(funcs) - containeronly; i++)
|
for(size_t i = 0; i < countof(funcs) - containeronly; i++)
|
||||||
{
|
{
|
||||||
FResourceFile *resfile = funcs[i](filename, file, quiet);
|
FResourceFile *resfile = funcs[i](filename, file, quiet, filter);
|
||||||
if (resfile != NULL) return resfile;
|
if (resfile != NULL) return resfile;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
FResourceFile *FResourceFile::OpenResourceFile(const char *filename, FileReader &file, bool quiet, bool containeronly)
|
FResourceFile *FResourceFile::OpenResourceFile(const char *filename, FileReader &file, bool quiet, bool containeronly, LumpFilterInfo* filter)
|
||||||
{
|
{
|
||||||
return DoOpenResourceFile(filename, file, quiet, containeronly);
|
return DoOpenResourceFile(filename, file, quiet, containeronly, filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
FResourceFile *FResourceFile::OpenResourceFile(const char *filename, bool quiet, bool containeronly)
|
FResourceFile *FResourceFile::OpenResourceFile(const char *filename, bool quiet, bool containeronly, LumpFilterInfo* filter)
|
||||||
{
|
{
|
||||||
FileReader file;
|
FileReader file;
|
||||||
if (!file.OpenFile(filename)) return nullptr;
|
if (!file.OpenFile(filename)) return nullptr;
|
||||||
return DoOpenResourceFile(filename, file, quiet, containeronly);
|
return DoOpenResourceFile(filename, file, quiet, containeronly, filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
FResourceFile *FResourceFile::OpenDirectory(const char *filename, bool quiet, LumpFilterInfo* filter)
|
||||||
FResourceFile *FResourceFile::OpenResourceFileFromLump(int lumpnum, bool quiet, bool containeronly)
|
|
||||||
{
|
{
|
||||||
FileReader file = Wads.ReopenLumpReader(lumpnum);
|
return CheckDir(filename, quiet, false, filter);
|
||||||
return DoOpenResourceFile("internal", file, quiet, containeronly);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
FResourceFile *FResourceFile::OpenDirectory(const char *filename, bool quiet, bool nosubdirflag)
|
|
||||||
{
|
|
||||||
return CheckDir(filename, quiet, nosubdirflag);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
@ -275,7 +298,39 @@ int lumpcmp(const void * a, const void * b)
|
||||||
{
|
{
|
||||||
FResourceLump * rec1 = (FResourceLump *)a;
|
FResourceLump * rec1 = (FResourceLump *)a;
|
||||||
FResourceLump * rec2 = (FResourceLump *)b;
|
FResourceLump * rec2 = (FResourceLump *)b;
|
||||||
return stricmp(rec1->LumpName[FResourceLump::FullNameType].GetChars(), rec2->LumpName[FResourceLump::FullNameType].GetChars());
|
return stricmp(rec1->getName(), rec2->getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// FResourceFile :: GenerateHash
|
||||||
|
//
|
||||||
|
// Generates a hash identifier for use in file identification.
|
||||||
|
// Potential uses are mod-wide compatibility settings or localization add-ons.
|
||||||
|
// This only hashes the lump directory but not the actual content
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
void FResourceFile::GenerateHash()
|
||||||
|
{
|
||||||
|
// hash the lump directory after sorting
|
||||||
|
|
||||||
|
Hash.Format(("%08X-%04X-"), (unsigned)Reader.GetLength(), NumLumps);
|
||||||
|
|
||||||
|
MD5Context md5;
|
||||||
|
|
||||||
|
uint8_t digest[16];
|
||||||
|
for(uint32_t i = 0; i < NumLumps; i++)
|
||||||
|
{
|
||||||
|
auto lump = GetLump(i);
|
||||||
|
md5.Update((const uint8_t*)lump->FullName.GetChars(), (unsigned)lump->FullName.Len() + 1);
|
||||||
|
md5.Update((const uint8_t*)&lump->LumpSize, 4);
|
||||||
|
}
|
||||||
|
md5.Final(digest);
|
||||||
|
for (auto c : digest)
|
||||||
|
{
|
||||||
|
Hash.AppendFormat("%02X", c);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
@ -289,28 +344,30 @@ int lumpcmp(const void * a, const void * b)
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
void FResourceFile::PostProcessArchive(void *lumps, size_t lumpsize)
|
void FResourceFile::PostProcessArchive(void *lumps, size_t lumpsize, LumpFilterInfo *filter)
|
||||||
{
|
{
|
||||||
// Entries in archives are sorted alphabetically
|
// Entries in archives are sorted alphabetically
|
||||||
qsort(lumps, NumLumps, lumpsize, lumpcmp);
|
qsort(lumps, NumLumps, lumpsize, lumpcmp);
|
||||||
|
if (!filter) return;
|
||||||
|
|
||||||
// Filter out lumps using the same names as the Autoload.* sections
|
// Filter out lumps using the same names as the Autoload.* sections
|
||||||
// in the ini file use. We reduce the maximum lump concidered after
|
// in the ini file use. We reduce the maximum lump concidered after
|
||||||
// each one so that we don't risk refiltering already filtered lumps.
|
// each one so that we don't risk refiltering already filtered lumps.
|
||||||
uint32_t max = NumLumps;
|
uint32_t max = NumLumps;
|
||||||
|
max -= FilterLumpsByGameType(filter, lumps, lumpsize, max);
|
||||||
|
|
||||||
|
long len;
|
||||||
int lastpos = -1;
|
int lastpos = -1;
|
||||||
FString file;
|
FString file;
|
||||||
|
FString LumpFilter = filter->dotFilter;
|
||||||
auto segments = LumpFilter.Split(".");
|
if (LumpFilter.IndexOf('.') < 0)
|
||||||
FString build;
|
|
||||||
|
|
||||||
for (auto& segment : segments)
|
|
||||||
{
|
{
|
||||||
if (build.IsEmpty()) build = segment;
|
max -= FilterLumps(LumpFilter, lumps, lumpsize, max);
|
||||||
else build << "." << segment;
|
}
|
||||||
max -= FilterLumps(build, lumps, lumpsize, max);
|
else while ((len = LumpFilter.IndexOf('.', lastpos+1)) > 0)
|
||||||
|
{
|
||||||
|
max -= FilterLumps(LumpFilter.Left(len), lumps, lumpsize, max);
|
||||||
|
lastpos = len;
|
||||||
}
|
}
|
||||||
JunkLeftoverFilters(lumps, lumpsize, max);
|
JunkLeftoverFilters(lumps, lumpsize, max);
|
||||||
}
|
}
|
||||||
|
@ -338,6 +395,13 @@ int FResourceFile::FilterLumps(FString filtername, void *lumps, size_t lumpsize,
|
||||||
|
|
||||||
bool found = FindPrefixRange(filter, lumps, lumpsize, max, start, end);
|
bool found = FindPrefixRange(filter, lumps, lumpsize, max, start, end);
|
||||||
|
|
||||||
|
// Workaround for old Doom filter names.
|
||||||
|
if (!found && filtername.IndexOf("doom.id.doom") == 0)
|
||||||
|
{
|
||||||
|
filter.Substitute("doom.id.doom", "doom.doom");
|
||||||
|
found = FindPrefixRange(filter, lumps, lumpsize, max, start, end);
|
||||||
|
}
|
||||||
|
|
||||||
if (found)
|
if (found)
|
||||||
{
|
{
|
||||||
void *from = (uint8_t *)lumps + start * lumpsize;
|
void *from = (uint8_t *)lumps + start * lumpsize;
|
||||||
|
@ -347,8 +411,8 @@ int FResourceFile::FilterLumps(FString filtername, void *lumps, size_t lumpsize,
|
||||||
for (uint32_t i = start; i < end; ++i, lump_p = (uint8_t *)lump_p + lumpsize)
|
for (uint32_t i = start; i < end; ++i, lump_p = (uint8_t *)lump_p + lumpsize)
|
||||||
{
|
{
|
||||||
FResourceLump *lump = (FResourceLump *)lump_p;
|
FResourceLump *lump = (FResourceLump *)lump_p;
|
||||||
assert(filter.CompareNoCase(lump->FullName(), (int)filter.Len()) == 0);
|
assert(lump->FullName.CompareNoCase(filter, (int)filter.Len()) == 0);
|
||||||
lump->LumpNameSetup(lump->FullName() + filter.Len());
|
lump->LumpNameSetup(lump->FullName.Mid(filter.Len()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Move filtered lumps to the end of the lump list.
|
// Move filtered lumps to the end of the lump list.
|
||||||
|
@ -374,6 +438,29 @@ int FResourceFile::FilterLumps(FString filtername, void *lumps, size_t lumpsize,
|
||||||
return end - start;
|
return end - start;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// FResourceFile :: FilterLumpsByGameType
|
||||||
|
//
|
||||||
|
// Matches any lumps that match "filter/game-<gametype>/*". Includes
|
||||||
|
// inclusive gametypes like Raven.
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
int FResourceFile::FilterLumpsByGameType(LumpFilterInfo *filter, void *lumps, size_t lumpsize, uint32_t max)
|
||||||
|
{
|
||||||
|
if (filter == nullptr)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
int count = 0;
|
||||||
|
for (auto &fstring : filter->gameTypeFilter)
|
||||||
|
{
|
||||||
|
count += FilterLumps(fstring, lumps, lumpsize, max);
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
// FResourceFile :: JunkLeftoverFilters
|
// FResourceFile :: JunkLeftoverFilters
|
||||||
|
@ -394,8 +481,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)
|
for (void *p = (uint8_t *)lumps + start * lumpsize; p < stop; p = (uint8_t *)p + lumpsize)
|
||||||
{
|
{
|
||||||
FResourceLump *lump = (FResourceLump *)p;
|
FResourceLump *lump = (FResourceLump *)p;
|
||||||
for (auto &ln : lump->LumpName)
|
lump->FullName = "";
|
||||||
ln = NAME_None;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -428,11 +514,10 @@ bool FResourceFile::FindPrefixRange(FString filter, void *lumps, size_t lumpsize
|
||||||
{
|
{
|
||||||
mid = min + (max - min) / 2;
|
mid = min + (max - min) / 2;
|
||||||
lump = (FResourceLump *)((uint8_t *)lumps + mid * lumpsize);
|
lump = (FResourceLump *)((uint8_t *)lumps + mid * lumpsize);
|
||||||
cmp = filter.CompareNoCase(lump->FullName(), (int)filter.Len());
|
cmp = lump->FullName.CompareNoCase(filter, (int)filter.Len());
|
||||||
|
|
||||||
if (cmp == 0)
|
if (cmp == 0)
|
||||||
break;
|
break;
|
||||||
else if (cmp > 0)
|
else if (cmp < 0)
|
||||||
min = mid + 1;
|
min = mid + 1;
|
||||||
else
|
else
|
||||||
max = mid - 1;
|
max = mid - 1;
|
||||||
|
@ -449,7 +534,7 @@ bool FResourceFile::FindPrefixRange(FString filter, void *lumps, size_t lumpsize
|
||||||
{
|
{
|
||||||
mid = min + (max - min) / 2;
|
mid = min + (max - min) / 2;
|
||||||
lump = (FResourceLump *)((uint8_t *)lumps + mid * lumpsize);
|
lump = (FResourceLump *)((uint8_t *)lumps + mid * lumpsize);
|
||||||
cmp = filter.CompareNoCase(lump->FullName(), (int)filter.Len());
|
cmp = lump->FullName.CompareNoCase(filter, (int)filter.Len());
|
||||||
// Go left on matches and right on misses.
|
// Go left on matches and right on misses.
|
||||||
if (cmp == 0)
|
if (cmp == 0)
|
||||||
max = mid - 1;
|
max = mid - 1;
|
||||||
|
@ -464,7 +549,7 @@ bool FResourceFile::FindPrefixRange(FString filter, void *lumps, size_t lumpsize
|
||||||
{
|
{
|
||||||
mid = min + (max - min) / 2;
|
mid = min + (max - min) / 2;
|
||||||
lump = (FResourceLump *)((uint8_t *)lumps + mid * lumpsize);
|
lump = (FResourceLump *)((uint8_t *)lumps + mid * lumpsize);
|
||||||
cmp = filter.CompareNoCase(lump->FullName(), (int)filter.Len());
|
cmp = lump->FullName.CompareNoCase(filter, (int)filter.Len());
|
||||||
// Go right on matches and left on misses.
|
// Go right on matches and left on misses.
|
||||||
if (cmp == 0)
|
if (cmp == 0)
|
||||||
min = mid + 1;
|
min = mid + 1;
|
||||||
|
@ -483,12 +568,10 @@ bool FResourceFile::FindPrefixRange(FString filter, void *lumps, size_t lumpsize
|
||||||
|
|
||||||
FResourceLump *FResourceFile::FindLump(const char *name)
|
FResourceLump *FResourceFile::FindLump(const char *name)
|
||||||
{
|
{
|
||||||
FName lname(name, true);
|
|
||||||
if (lname == NAME_None) return nullptr;
|
|
||||||
for (unsigned i = 0; i < NumLumps; i++)
|
for (unsigned i = 0; i < NumLumps; i++)
|
||||||
{
|
{
|
||||||
FResourceLump *lump = GetLump(i);
|
FResourceLump *lump = GetLump(i);
|
||||||
if (lump->LumpName[FResourceLump::FullNameType] == lname)
|
if (!stricmp(name, lump->FullName))
|
||||||
{
|
{
|
||||||
return lump;
|
return lump;
|
||||||
}
|
}
|
||||||
|
@ -514,11 +597,22 @@ FileReader *FUncompressedLump::GetReader()
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
int FUncompressedLump::ValidateCache()
|
int FUncompressedLump::FillCache()
|
||||||
{
|
{
|
||||||
|
const char * buffer = Owner->Reader.GetBuffer();
|
||||||
|
|
||||||
|
if (buffer != NULL)
|
||||||
|
{
|
||||||
|
// This is an in-memory file so the cache can point directly to the file's data.
|
||||||
|
Cache = const_cast<char*>(buffer) + Position;
|
||||||
|
RefCount = -1;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
Owner->Reader.Seek(Position, FileReader::SeekSet);
|
Owner->Reader.Seek(Position, FileReader::SeekSet);
|
||||||
Cache.Resize(LumpSize);
|
Cache = new char[LumpSize];
|
||||||
Owner->Reader.Read(Cache.Data(), LumpSize);
|
Owner->Reader.Read(Cache, LumpSize);
|
||||||
|
RefCount = 1;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -573,18 +667,22 @@ FExternalLump::FExternalLump(const char *_filename, int filesize)
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
int FExternalLump::ValidateCache()
|
int FExternalLump::FillCache()
|
||||||
{
|
{
|
||||||
Cache.Resize(LumpSize);
|
Cache = new char[LumpSize];
|
||||||
FileReader f;
|
FileReader f;
|
||||||
|
|
||||||
if (f.OpenFile(Filename))
|
if (f.OpenFile(Filename))
|
||||||
{
|
{
|
||||||
f.Read(Cache.Data(), LumpSize);
|
f.Read(Cache, LumpSize);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
memset(Cache.Data(), 0, LumpSize);
|
memset(Cache, 0, LumpSize);
|
||||||
}
|
}
|
||||||
|
RefCount = 1;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -3,14 +3,24 @@
|
||||||
#ifndef __RESFILE_H
|
#ifndef __RESFILE_H
|
||||||
#define __RESFILE_H
|
#define __RESFILE_H
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include "files.h"
|
#include "files.h"
|
||||||
#include "zstring.h"
|
|
||||||
#include "name.h"
|
struct LumpFilterInfo
|
||||||
|
{
|
||||||
|
TArray<FString> gameTypeFilter; // this can contain multiple entries
|
||||||
|
FString dotFilter;
|
||||||
|
|
||||||
|
// The following are for checking if the root directory of a zip can be removed.
|
||||||
|
TArray<FString> reservedFolders;
|
||||||
|
TArray<FString> requiredPrefixes;
|
||||||
|
std::function<void()> postprocessFunc;
|
||||||
|
};
|
||||||
|
|
||||||
class FResourceFile;
|
class FResourceFile;
|
||||||
class FTexture;
|
class FTexture;
|
||||||
|
|
||||||
|
// [RH] Namespaces from BOOM.
|
||||||
|
// These are needed here in the low level part so that WAD files can be properly set up.
|
||||||
typedef enum {
|
typedef enum {
|
||||||
ns_hidden = -1,
|
ns_hidden = -1,
|
||||||
|
|
||||||
|
@ -20,9 +30,9 @@ typedef enum {
|
||||||
ns_colormaps,
|
ns_colormaps,
|
||||||
ns_acslibrary,
|
ns_acslibrary,
|
||||||
ns_newtextures,
|
ns_newtextures,
|
||||||
ns_bloodraw,
|
ns_bloodraw, // no longer used - kept for ZScript.
|
||||||
ns_bloodsfx,
|
ns_bloodsfx, // no longer used - kept for ZScript.
|
||||||
ns_bloodmisc,
|
ns_bloodmisc, // no longer used - kept for ZScript.
|
||||||
ns_strifevoices,
|
ns_strifevoices,
|
||||||
ns_hires,
|
ns_hires,
|
||||||
ns_voxels,
|
ns_voxels,
|
||||||
|
@ -43,16 +53,13 @@ typedef enum {
|
||||||
enum ELumpFlags
|
enum ELumpFlags
|
||||||
{
|
{
|
||||||
LUMPF_MAYBEFLAT = 1, // might be a flat outside F_START/END
|
LUMPF_MAYBEFLAT = 1, // might be a flat outside F_START/END
|
||||||
LUMPF_ZIPFILE=2, // contains a full path
|
LUMPF_FULLPATH = 2, // contains a full path. This will trigger extended namespace checks when looking up short names.
|
||||||
LUMPF_EMBEDDED=4, // from an embedded WAD
|
LUMPF_EMBEDDED = 4, // marks an embedded resource file for later processing.
|
||||||
LUMPF_BLOODCRYPT = 8, // encrypted
|
LUMPF_SHORTNAME = 8, // the stored name is a short extension-less name
|
||||||
LUMPF_COMPRESSED = 16, // compressed
|
LUMPF_COMPRESSED = 16, // compressed or encrypted, i.e. cannot be read with the container file's reader.
|
||||||
LUMPF_SEQUENTIAL = 32, // compressed but a sequential reader can be retrieved.
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class FResourceFile;
|
// This holds a compresed Zip entry with all needed info to decompress it.
|
||||||
|
|
||||||
// This holds a compressed Zip entry with all needed info to decompress it.
|
|
||||||
struct FCompressedBuffer
|
struct FCompressedBuffer
|
||||||
{
|
{
|
||||||
unsigned mSize;
|
unsigned mSize;
|
||||||
|
@ -74,60 +81,50 @@ struct FCompressedBuffer
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct FResourceLump
|
struct FResourceLump
|
||||||
{
|
{
|
||||||
enum ENameType
|
|
||||||
{
|
|
||||||
FullNameType,
|
|
||||||
FullNameNoExtType,
|
|
||||||
BaseNameType,
|
|
||||||
BaseNameNoExtType,
|
|
||||||
ExtensionType,
|
|
||||||
DoomLumpType,
|
|
||||||
NUMNAMETYPES
|
|
||||||
};
|
|
||||||
|
|
||||||
friend class FResourceFile;
|
friend class FResourceFile;
|
||||||
friend struct FClonedLump;
|
friend class FWadFile; // this still needs direct access.
|
||||||
|
|
||||||
unsigned LumpSize = 0;
|
int LumpSize;
|
||||||
int RefCount = 0;
|
int RefCount;
|
||||||
int Flags = 0;
|
protected:
|
||||||
int ResourceId = -1;
|
FString FullName;
|
||||||
int Namespace = ns_global;
|
public:
|
||||||
FName LumpName[NUMNAMETYPES] = {};
|
uint8_t Flags;
|
||||||
FResourceFile * Owner = nullptr;
|
char * Cache;
|
||||||
TArray<uint8_t> Cache;
|
FResourceFile * Owner;
|
||||||
|
|
||||||
FResourceLump() = default;
|
FResourceLump()
|
||||||
|
{
|
||||||
|
Cache = NULL;
|
||||||
|
Owner = NULL;
|
||||||
|
Flags = 0;
|
||||||
|
RefCount = 0;
|
||||||
|
}
|
||||||
|
|
||||||
virtual ~FResourceLump();
|
virtual ~FResourceLump();
|
||||||
virtual FileReader *GetReader();
|
virtual FileReader *GetReader();
|
||||||
virtual FileReader NewReader();
|
virtual FileReader NewReader();
|
||||||
virtual int GetFileOffset() { return -1; }
|
virtual int GetFileOffset() { return -1; }
|
||||||
|
virtual int GetIndexNum() const { return -1; }
|
||||||
|
virtual int GetNamespace() const { return 0; }
|
||||||
void LumpNameSetup(FString iname);
|
void LumpNameSetup(FString iname);
|
||||||
|
void CheckEmbedded();
|
||||||
virtual FCompressedBuffer GetRawData();
|
virtual FCompressedBuffer GetRawData();
|
||||||
|
|
||||||
virtual void *Lock(); // validates the cache and increases the refcount.
|
void *Lock(); // validates the cache and increases the refcount.
|
||||||
virtual void Unlock(bool freeunrefd = false); // recreases the refcount and optionally frees the buffer
|
int Unlock(); // decreases the refcount and frees the buffer
|
||||||
virtual void *Get(); // validates the cache and returns a pointer without locking
|
|
||||||
|
|
||||||
// Wrappers for emulating Blood's resource system
|
|
||||||
unsigned Size() const{ return LumpSize; }
|
unsigned Size() const{ return LumpSize; }
|
||||||
int LockCount() const { return RefCount; }
|
int LockCount() const { return RefCount; }
|
||||||
const char *ResName() const { return LumpName[BaseNameNoExtType].GetChars(); }
|
const char* getName() { return FullName.GetChars(); }
|
||||||
const FName ResType() { return LumpName[ExtensionType]; }
|
|
||||||
const char *FullName() const { return LumpName[FullNameType].GetChars(); }
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual int ValidateCache() { return -1; }
|
virtual int FillCache() { return -1; }
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Map NBlood's resource system to our own.
|
|
||||||
using DICTNODE = FResourceLump;
|
|
||||||
|
|
||||||
class FResourceFile
|
class FResourceFile
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -135,35 +132,38 @@ public:
|
||||||
FString FileName;
|
FString FileName;
|
||||||
protected:
|
protected:
|
||||||
uint32_t NumLumps;
|
uint32_t NumLumps;
|
||||||
|
FString Hash;
|
||||||
|
|
||||||
FResourceFile(const char *filename);
|
FResourceFile(const char *filename);
|
||||||
FResourceFile(const char *filename, FileReader &r);
|
FResourceFile(const char *filename, FileReader &r);
|
||||||
|
|
||||||
// for archives that can contain directories
|
// for archives that can contain directories
|
||||||
void PostProcessArchive(void *lumps, size_t lumpsize);
|
void GenerateHash();
|
||||||
|
void PostProcessArchive(void *lumps, size_t lumpsize, LumpFilterInfo *filter);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint32_t FirstLump;
|
uint32_t FirstLump;
|
||||||
|
|
||||||
int FilterLumps(FString filtername, void *lumps, size_t lumpsize, uint32_t max);
|
int FilterLumps(FString filtername, void *lumps, size_t lumpsize, uint32_t max);
|
||||||
|
int FilterLumpsByGameType(LumpFilterInfo *filter, void *lumps, size_t lumpsize, uint32_t max);
|
||||||
bool FindPrefixRange(FString filter, void *lumps, size_t lumpsize, uint32_t max, uint32_t &start, uint32_t &end);
|
bool FindPrefixRange(FString filter, void *lumps, size_t lumpsize, uint32_t max, uint32_t &start, uint32_t &end);
|
||||||
void JunkLeftoverFilters(void *lumps, size_t lumpsize, uint32_t max);
|
void JunkLeftoverFilters(void *lumps, size_t lumpsize, uint32_t max);
|
||||||
static FResourceFile *DoOpenResourceFile(const char *filename, FileReader &file, bool quiet, bool containeronly);
|
static FResourceFile *DoOpenResourceFile(const char *filename, FileReader &file, bool quiet, bool containeronly, LumpFilterInfo* filter);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static FResourceFile *OpenResourceFile(const char *filename, FileReader &file, bool quiet = false, bool containeronly = false);
|
static FResourceFile *OpenResourceFile(const char *filename, FileReader &file, bool quiet = false, bool containeronly = false, LumpFilterInfo* filter = nullptr);
|
||||||
static FResourceFile *OpenResourceFile(const char *filename, bool quiet = false, bool containeronly = false);
|
static FResourceFile *OpenResourceFile(const char *filename, bool quiet = false, bool containeronly = false, LumpFilterInfo* filter = nullptr);
|
||||||
static FResourceFile* OpenDirectory(const char* filename, bool quiet = false, bool nosubdirs = false);
|
static FResourceFile *OpenDirectory(const char *filename, bool quiet = false, LumpFilterInfo* filter = nullptr);
|
||||||
virtual ~FResourceFile();
|
virtual ~FResourceFile();
|
||||||
// If this FResourceFile represents a directory, the Reader object is not usable so don't return it.
|
// If this FResourceFile represents a directory, the Reader object is not usable so don't return it.
|
||||||
FileReader *GetReader() { return Reader.isOpen()? &Reader : nullptr; }
|
FileReader *GetReader() { return Reader.isOpen()? &Reader : nullptr; }
|
||||||
uint32_t LumpCount() const { return NumLumps; }
|
uint32_t LumpCount() const { return NumLumps; }
|
||||||
uint32_t GetFirstLump() const { return FirstLump; }
|
uint32_t GetFirstEntry() const { return FirstLump; }
|
||||||
void SetFirstLump(uint32_t f) { FirstLump = f; }
|
void SetFirstLump(uint32_t f) { FirstLump = f; }
|
||||||
|
const FString &GetHash() const { return Hash; }
|
||||||
|
|
||||||
|
|
||||||
|
virtual bool Open(bool quiet, LumpFilterInfo* filter) = 0;
|
||||||
virtual bool Open(bool quiet) = 0;
|
|
||||||
virtual FResourceLump *GetLump(int no) = 0;
|
virtual FResourceLump *GetLump(int no) = 0;
|
||||||
FResourceLump *FindLump(const char *name);
|
FResourceLump *FindLump(const char *name);
|
||||||
};
|
};
|
||||||
|
@ -172,14 +172,14 @@ struct FUncompressedLump : public FResourceLump
|
||||||
{
|
{
|
||||||
int Position;
|
int Position;
|
||||||
|
|
||||||
FileReader *GetReader() override;
|
virtual FileReader *GetReader();
|
||||||
int ValidateCache() override;
|
virtual int FillCache();
|
||||||
virtual int GetFileOffset() override { return Position; }
|
virtual int GetFileOffset() { return Position; }
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// Base class for uncompressed resource files (GRP, PAK and single lumps)
|
// Base class for uncompressed resource files (WAD, GRP, PAK and single lumps)
|
||||||
class FUncompressedFile : public FResourceFile
|
class FUncompressedFile : public FResourceFile
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
|
@ -196,7 +196,7 @@ struct FExternalLump : public FResourceLump
|
||||||
FString Filename;
|
FString Filename;
|
||||||
|
|
||||||
FExternalLump(const char *_filename, int filesize = -1);
|
FExternalLump(const char *_filename, int filesize = -1);
|
||||||
virtual int ValidateCache() override;
|
virtual int FillCache();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -204,29 +204,20 @@ struct FMemoryLump : public FResourceLump
|
||||||
{
|
{
|
||||||
FMemoryLump(const void* data, int length)
|
FMemoryLump(const void* data, int length)
|
||||||
{
|
{
|
||||||
|
RefCount = INT_MAX / 2;
|
||||||
LumpSize = length;
|
LumpSize = length;
|
||||||
Cache.Resize(length);
|
Cache = new char[length];
|
||||||
memcpy(Cache.Data(), data, length);
|
memcpy(Cache, data, length);
|
||||||
}
|
}
|
||||||
virtual int ValidateCache() override
|
|
||||||
|
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.
|
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;
|
return 1;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct FClonedLump : public FResourceLump
|
|
||||||
{
|
|
||||||
FResourceLump* parent;
|
|
||||||
FClonedLump(FResourceLump* lump)
|
|
||||||
{
|
|
||||||
parent = lump;
|
|
||||||
}
|
|
||||||
void* Lock() override { return parent->Lock(); }
|
|
||||||
void Unlock(bool mayfree) override { parent->Unlock(mayfree); }
|
|
||||||
void* Get() override { return parent->Get(); }
|
|
||||||
int ValidateCache() override { return parent->ValidateCache(); }
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
70
source/common/filesystem/w_zip.h
Normal file
70
source/common/filesystem/w_zip.h
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
#ifndef __W_ZIP
|
||||||
|
#define __W_ZIP
|
||||||
|
|
||||||
|
#include "basics.h"
|
||||||
|
|
||||||
|
#pragma pack(1)
|
||||||
|
// FZipCentralInfo
|
||||||
|
struct FZipEndOfCentralDirectory
|
||||||
|
{
|
||||||
|
uint32_t Magic;
|
||||||
|
uint16_t DiskNumber;
|
||||||
|
uint16_t FirstDisk;
|
||||||
|
uint16_t NumEntries;
|
||||||
|
uint16_t NumEntriesOnAllDisks;
|
||||||
|
uint32_t DirectorySize;
|
||||||
|
uint32_t DirectoryOffset;
|
||||||
|
uint16_t ZipCommentLength;
|
||||||
|
} FORCE_PACKED;
|
||||||
|
|
||||||
|
// FZipFileInfo
|
||||||
|
struct FZipCentralDirectoryInfo
|
||||||
|
{
|
||||||
|
uint32_t Magic;
|
||||||
|
uint8_t VersionMadeBy[2];
|
||||||
|
uint8_t VersionToExtract[2];
|
||||||
|
uint16_t Flags;
|
||||||
|
uint16_t Method;
|
||||||
|
uint16_t ModTime;
|
||||||
|
uint16_t ModDate;
|
||||||
|
uint32_t CRC32;
|
||||||
|
uint32_t CompressedSize;
|
||||||
|
uint32_t UncompressedSize;
|
||||||
|
uint16_t NameLength;
|
||||||
|
uint16_t ExtraLength;
|
||||||
|
uint16_t CommentLength;
|
||||||
|
uint16_t StartingDiskNumber;
|
||||||
|
uint16_t InternalAttributes;
|
||||||
|
uint32_t ExternalAttributes;
|
||||||
|
uint32_t LocalHeaderOffset;
|
||||||
|
// file name and other variable length info follows
|
||||||
|
} FORCE_PACKED;
|
||||||
|
|
||||||
|
// FZipLocalHeader
|
||||||
|
struct FZipLocalFileHeader
|
||||||
|
{
|
||||||
|
uint32_t Magic;
|
||||||
|
uint8_t VersionToExtract[2];
|
||||||
|
uint16_t Flags;
|
||||||
|
uint16_t Method;
|
||||||
|
uint16_t ModTime;
|
||||||
|
uint16_t ModDate;
|
||||||
|
uint32_t CRC32;
|
||||||
|
uint32_t CompressedSize;
|
||||||
|
uint32_t UncompressedSize;
|
||||||
|
uint16_t NameLength;
|
||||||
|
uint16_t ExtraLength;
|
||||||
|
// file name and other variable length info follows
|
||||||
|
} FORCE_PACKED;
|
||||||
|
|
||||||
|
|
||||||
|
#pragma pack()
|
||||||
|
|
||||||
|
#define ZIP_LOCALFILE MAKE_ID('P','K',3,4)
|
||||||
|
#define ZIP_CENTRALFILE MAKE_ID('P','K',1,2)
|
||||||
|
#define ZIP_ENDOFDIR MAKE_ID('P','K',5,6)
|
||||||
|
|
||||||
|
// File header flags.
|
||||||
|
#define ZF_ENCRYPTED 0x1
|
||||||
|
|
||||||
|
#endif
|
|
@ -23,6 +23,18 @@ typedef int32_t fixed_t;
|
||||||
|
|
||||||
typedef uint32_t angle_t;
|
typedef uint32_t angle_t;
|
||||||
|
|
||||||
|
#if defined(__GNUC__)
|
||||||
|
// With versions of GCC newer than 4.2, it appears it was determined that the
|
||||||
|
// cost of an unaligned pointer on PPC was high enough to add padding to the
|
||||||
|
// end of packed structs. For whatever reason __packed__ and pragma pack are
|
||||||
|
// handled differently in this regard. Note that this only needs to be applied
|
||||||
|
// to types which are used in arrays or sizeof is needed. This also prevents
|
||||||
|
// code from taking references to the struct members.
|
||||||
|
#define FORCE_PACKED __attribute__((__packed__))
|
||||||
|
#else
|
||||||
|
#define FORCE_PACKED
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
#define GCCPRINTF(stri,firstargi) __attribute__((format(printf,stri,firstargi)))
|
#define GCCPRINTF(stri,firstargi) __attribute__((format(printf,stri,firstargi)))
|
||||||
|
|
|
@ -36,6 +36,8 @@
|
||||||
|
|
||||||
#include "cmdlib.h"
|
#include "cmdlib.h"
|
||||||
#include "findfile.h"
|
#include "findfile.h"
|
||||||
|
#include "files.h"
|
||||||
|
#include "md5.h"
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
@ -1032,3 +1034,36 @@ FString M_ZLibError(int zerr)
|
||||||
return errs[-zerr - 1];
|
return errs[-zerr - 1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void md5Update(FileReader& file, MD5Context& md5, unsigned len)
|
||||||
|
{
|
||||||
|
uint8_t readbuf[8192];
|
||||||
|
unsigned t;
|
||||||
|
|
||||||
|
while (len > 0)
|
||||||
|
{
|
||||||
|
t = std::min<unsigned>(len, sizeof(readbuf));
|
||||||
|
len -= t;
|
||||||
|
t = (long)file.Read(readbuf, t);
|
||||||
|
md5.Update(readbuf, t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// uppercoppy
|
||||||
|
//
|
||||||
|
// [RH] Copy up to 8 chars, upper-casing them in the process
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
void uppercopy(char* to, const char* from)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < 8 && from[i]; i++)
|
||||||
|
to[i] = toupper(from[i]);
|
||||||
|
for (; i < 8; i++)
|
||||||
|
to[i] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -84,4 +84,10 @@ inline int32_t Scale(int32_t a, int32_t b, int32_t c)
|
||||||
return (int32_t)(((int64_t)a * b) / c);
|
return (int32_t)(((int64_t)a * b) / c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class FileReader;
|
||||||
|
struct MD5Context;
|
||||||
|
|
||||||
|
void md5Update(FileReader& file, MD5Context& md5, unsigned len);
|
||||||
|
void uppercopy(char* to, const char* from);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -293,7 +293,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
friend class FWadCollection;
|
friend class FileSystem;
|
||||||
};
|
};
|
||||||
|
|
||||||
class DecompressorBase : public FileReaderInterface
|
class DecompressorBase : public FileReaderInterface
|
||||||
|
|
|
@ -94,6 +94,10 @@ public:
|
||||||
TIterator operator-(difference_type offset) const { return TIterator(m_ptr - offset); }
|
TIterator operator-(difference_type offset) const { return TIterator(m_ptr - offset); }
|
||||||
difference_type operator-(const TIterator &other) const { return m_ptr - other.m_ptr; }
|
difference_type operator-(const TIterator &other) const { return m_ptr - other.m_ptr; }
|
||||||
|
|
||||||
|
// Random access operators
|
||||||
|
T& operator[](difference_type i) { return m_ptr[i]; }
|
||||||
|
const T& operator[](difference_type i) const { return m_ptr[i]; }
|
||||||
|
|
||||||
T &operator*() { return *m_ptr; }
|
T &operator*() { return *m_ptr; }
|
||||||
const T &operator*() const { return *m_ptr; }
|
const T &operator*() const { return *m_ptr; }
|
||||||
T* operator->() { return m_ptr; }
|
T* operator->() { return m_ptr; }
|
||||||
|
|
|
@ -36,6 +36,7 @@
|
||||||
|
|
||||||
#include "zstring.h"
|
#include "zstring.h"
|
||||||
#include "tarray.h"
|
#include "tarray.h"
|
||||||
|
#include "printf.h"
|
||||||
|
|
||||||
class FFont;
|
class FFont;
|
||||||
|
|
||||||
|
@ -48,34 +49,6 @@ struct FBrokenLines
|
||||||
#define TEXTCOLOR_ESCAPE '\034'
|
#define TEXTCOLOR_ESCAPE '\034'
|
||||||
#define TEXTCOLOR_ESCAPESTR "\034"
|
#define TEXTCOLOR_ESCAPESTR "\034"
|
||||||
|
|
||||||
#define TEXTCOLOR_BRICK "\034A"
|
|
||||||
#define TEXTCOLOR_TAN "\034B"
|
|
||||||
#define TEXTCOLOR_GRAY "\034C"
|
|
||||||
#define TEXTCOLOR_GREY "\034C"
|
|
||||||
#define TEXTCOLOR_GREEN "\034D"
|
|
||||||
#define TEXTCOLOR_BROWN "\034E"
|
|
||||||
#define TEXTCOLOR_GOLD "\034F"
|
|
||||||
#define TEXTCOLOR_RED "\034G"
|
|
||||||
#define TEXTCOLOR_BLUE "\034H"
|
|
||||||
#define TEXTCOLOR_ORANGE "\034I"
|
|
||||||
#define TEXTCOLOR_WHITE "\034J"
|
|
||||||
#define TEXTCOLOR_YELLOW "\034K"
|
|
||||||
#define TEXTCOLOR_UNTRANSLATED "\034L"
|
|
||||||
#define TEXTCOLOR_BLACK "\034M"
|
|
||||||
#define TEXTCOLOR_LIGHTBLUE "\034N"
|
|
||||||
#define TEXTCOLOR_CREAM "\034O"
|
|
||||||
#define TEXTCOLOR_OLIVE "\034P"
|
|
||||||
#define TEXTCOLOR_DARKGREEN "\034Q"
|
|
||||||
#define TEXTCOLOR_DARKRED "\034R"
|
|
||||||
#define TEXTCOLOR_DARKBROWN "\034S"
|
|
||||||
#define TEXTCOLOR_PURPLE "\034T"
|
|
||||||
#define TEXTCOLOR_DARKGRAY "\034U"
|
|
||||||
#define TEXTCOLOR_CYAN "\034V"
|
|
||||||
#define TEXTCOLOR_ICE "\034W"
|
|
||||||
#define TEXTCOLOR_FIRE "\034X"
|
|
||||||
#define TEXTCOLOR_SAPPHIRE "\034Y"
|
|
||||||
#define TEXTCOLOR_TEAL "\034Z"
|
|
||||||
|
|
||||||
#define TEXTCOLOR_NORMAL "\034-"
|
#define TEXTCOLOR_NORMAL "\034-"
|
||||||
#define TEXTCOLOR_BOLD "\034+"
|
#define TEXTCOLOR_BOLD "\034+"
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
#include "files.h"
|
#include "files.h"
|
||||||
#include "zstring.h"
|
#include "zstring.h"
|
||||||
#include "tarray.h"
|
#include "tarray.h"
|
||||||
#include "filesystem/resourcefile.h"
|
#include "resourcefile.h"
|
||||||
|
|
||||||
class CompositeSavegameWriter
|
class CompositeSavegameWriter
|
||||||
{
|
{
|
||||||
|
|
|
@ -683,17 +683,17 @@ void ReadBindings(int lump, bool override)
|
||||||
|
|
||||||
void CONFIG_SetDefaultKeys(const char* baseconfig)
|
void CONFIG_SetDefaultKeys(const char* baseconfig)
|
||||||
{
|
{
|
||||||
auto lump = fileSystem.GetFile("engine/commonbinds.txt", ELookupMode::FullName, 0);
|
auto lump = fileSystem.CheckNumForFullName("engine/commonbinds.txt");
|
||||||
if (lump >= 0) ReadBindings(lump, true);
|
if (lump >= 0) ReadBindings(lump, true);
|
||||||
int lastlump = 0;
|
int lastlump = 0;
|
||||||
|
|
||||||
while ((lump = fileSystem.Iterate(baseconfig, &lastlump)) != -1)
|
while ((lump = fileSystem.FindLumpFullName(baseconfig, &lastlump)) != -1)
|
||||||
{
|
{
|
||||||
if (fileSystem.GetFileContainer(lump) > 0) break;
|
if (fileSystem.GetFileContainer(lump) > 0) break;
|
||||||
ReadBindings(lump, true);
|
ReadBindings(lump, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
while ((lump = fileSystem.Iterate("defbinds.txt", &lastlump)) != -1)
|
while ((lump = fileSystem.FindLumpFullName("defbinds.txt", &lastlump)) != -1)
|
||||||
{
|
{
|
||||||
ReadBindings(lump, false);
|
ReadBindings(lump, false);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,129 +0,0 @@
|
||||||
|
|
||||||
|
|
||||||
struct CacheNode
|
|
||||||
{
|
|
||||||
size_t size;
|
|
||||||
CacheNode *next, *prev;
|
|
||||||
int lockCount;
|
|
||||||
int lastusetick; // This is to ensure that a node lives for the duration of the frame it is last axxessed on
|
|
||||||
|
|
||||||
virtual ~CacheNode();
|
|
||||||
virtual void Purge() = 0; // needs to be implemented by the child class to allow different types of menory to be used.
|
|
||||||
};
|
|
||||||
|
|
||||||
class Cache
|
|
||||||
{
|
|
||||||
size_t maxSize;
|
|
||||||
size_t currentSize;
|
|
||||||
CacheNode purgeHead;
|
|
||||||
int currenttick;
|
|
||||||
|
|
||||||
public:
|
|
||||||
Cache()
|
|
||||||
{
|
|
||||||
maxSize = 100'000'000;
|
|
||||||
currentSize = 0;
|
|
||||||
purgeHead = { 0, &purgeHead, &purgeHead, 0 };
|
|
||||||
}
|
|
||||||
|
|
||||||
SetSize(size_t newsize)
|
|
||||||
{
|
|
||||||
if (newsize < maxSize) Purge();
|
|
||||||
maxSize = newsize;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AddToPurgeList(CacheNode *h)
|
|
||||||
{
|
|
||||||
h->prev = purgeHead.prev;
|
|
||||||
purgeHead.prev->next = h;
|
|
||||||
h->next = &purgeHead;
|
|
||||||
purgeHead.prev = h;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RemoveFromPurgeList(CacheNode *h)
|
|
||||||
{
|
|
||||||
h->prev->next = h->next;
|
|
||||||
h->next->prev = h->prev;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Alloc(CacheNode *h)
|
|
||||||
{
|
|
||||||
currentSize += h->size;
|
|
||||||
if (currentSize > maxSize)
|
|
||||||
{
|
|
||||||
Purge();
|
|
||||||
}
|
|
||||||
AddToPurgeList(h);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Release(CacheNode *h)
|
|
||||||
{
|
|
||||||
currentSize -= h->size;
|
|
||||||
RemoveFromPurgeList(h);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Validata(CacheNode *h)
|
|
||||||
{
|
|
||||||
if (h->LockCount == 0)
|
|
||||||
{
|
|
||||||
// Move node to the top of the linked list.
|
|
||||||
RemoveFromPurgeList(h);
|
|
||||||
AddToPurgeList(h);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void *Lock(CacheNode *h)
|
|
||||||
{
|
|
||||||
// This merely locks the node. Allocation must be reported separately.
|
|
||||||
assert(h != NULL);
|
|
||||||
if (h->lockCount == 0)
|
|
||||||
{
|
|
||||||
RemoveFromPurgeList(h);
|
|
||||||
}
|
|
||||||
|
|
||||||
h->lockCount++;
|
|
||||||
return h->ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Unlock(CacheNode *h)
|
|
||||||
{
|
|
||||||
assert(h != NULL);
|
|
||||||
if (h->lockCount > 0)
|
|
||||||
{
|
|
||||||
h->lockCount--;
|
|
||||||
if (h->lockCount == 0)
|
|
||||||
{
|
|
||||||
AddToPurgeList();
|
|
||||||
if (currentSize > maxSize)
|
|
||||||
{
|
|
||||||
Release(h);
|
|
||||||
h->Purge();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void PurgeCache(bool all = false)
|
|
||||||
{
|
|
||||||
// Do not delete from the list while it's being iterated. Better store in a temporary list and delete from there.
|
|
||||||
TArray<CacheNode *> nodesToPurge(10);
|
|
||||||
int purgeSize = 0;
|
|
||||||
for (CacheNode *node = purgeHead.next; node != &purgeHead; node = node->next)
|
|
||||||
{
|
|
||||||
if (node->lastusetick < currenttick)
|
|
||||||
{
|
|
||||||
nodesToPurge.Push(npde);
|
|
||||||
purgeSize += node->size;
|
|
||||||
if (currentSize - purgeSize < maxSize && !all) break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (auto h : nodesToPurge)
|
|
||||||
{
|
|
||||||
Release(h);
|
|
||||||
h->Purge();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,208 +0,0 @@
|
||||||
#pragma once
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// DESCRIPTION:
|
|
||||||
// File system I/O functions.
|
|
||||||
//
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
|
|
||||||
#include <stdexcept>
|
|
||||||
#include "files.h"
|
|
||||||
#include "tarray.h"
|
|
||||||
#include "name.h"
|
|
||||||
#include "zstring.h"
|
|
||||||
#include "engineerrors.h"
|
|
||||||
|
|
||||||
#ifdef FindResource
|
|
||||||
#undef FindResource
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// We do not want to expose the resource file interface here.
|
|
||||||
class FResourceFile;
|
|
||||||
struct FResourceLump;
|
|
||||||
|
|
||||||
class FileSystemError : CRecoverableError
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
FileSystemError(const char* err) : CRecoverableError(err) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
// A file in memory.
|
|
||||||
class FileData
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
FileData ();
|
|
||||||
|
|
||||||
FileData (const FileData ©);
|
|
||||||
FileData &operator= (const FileData ©);
|
|
||||||
~FileData ();
|
|
||||||
void *GetMem () { return Block.Len() == 0 ? NULL : (void *)Block.GetChars(); }
|
|
||||||
size_t GetSize () { return Block.Len(); }
|
|
||||||
FString GetString () { return Block; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
FileData (const FString &source);
|
|
||||||
|
|
||||||
FString Block;
|
|
||||||
|
|
||||||
friend class FileSystem;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct FolderEntry
|
|
||||||
{
|
|
||||||
const char *name;
|
|
||||||
unsigned lumpnum;
|
|
||||||
};
|
|
||||||
|
|
||||||
enum DICTFLAGS {
|
|
||||||
DICT_LOAD = 4,
|
|
||||||
DICT_LOCK = 8,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class ELookupMode // Todo: Merge with FResourceLump::ENameType
|
|
||||||
{
|
|
||||||
FullName,
|
|
||||||
NoExtension,
|
|
||||||
BaseName,
|
|
||||||
BaseWithExtension,
|
|
||||||
IdWithType,
|
|
||||||
NumLookupModes
|
|
||||||
};
|
|
||||||
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
NumLookupModes = (int)ELookupMode::NumLookupModes + 1
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class FileSystem
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
FileSystem () = default;
|
|
||||||
~FileSystem ();
|
|
||||||
|
|
||||||
int InitMultipleFiles (TArray<FString> &filenames, const TArray<FString> &todelete, int maingamefiles);
|
|
||||||
void DeleteStuff(const TArray<FString>& deletelumps, int numgamefiles);
|
|
||||||
void Rehash();
|
|
||||||
|
|
||||||
void AddFile (const char *filename, FileReader *wadinfo = NULL, bool nosubdirflag = false);
|
|
||||||
void AddAdditionalFile(const char* filename, FileReader* wadinfo = NULL) {}
|
|
||||||
int CheckIfResourceFileLoaded (const char *name) noexcept;
|
|
||||||
|
|
||||||
const char *GetResourceFileName (int filenum) const noexcept;
|
|
||||||
const char *GetResourceFileFullName (int filenum) const noexcept;
|
|
||||||
|
|
||||||
int GetFirstEntry(int filenum) const noexcept;
|
|
||||||
int GetLastEntry(int filenum) const noexcept;
|
|
||||||
int GetEntryCount(int filenum) const noexcept;
|
|
||||||
|
|
||||||
int FindFile (const char *name, ELookupMode lookupmode = ELookupMode::FullName, int filenum = -1) const noexcept;
|
|
||||||
int FindFileWithExtensions(const char* name, const FName* exts, int count);
|
|
||||||
int GetFile (const char *name, ELookupMode lookupmode = ELookupMode::FullName, int filenum = -1) const; // Like FindFile, but throws an exception when it cannot find what it looks for.
|
|
||||||
bool FileExists(const char* name)
|
|
||||||
{
|
|
||||||
return FindFile(name) >= 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int FindFile (const FString &name, ELookupMode lookupmode = ELookupMode::FullName, int filenum = -1) const noexcept { return FindFile(name.GetChars(), lookupmode, filenum); }
|
|
||||||
int GetFile (const FString &name, ELookupMode lookupmode = ELookupMode::FullName, int filenum = -1) const { return GetFile(name.GetChars(), lookupmode, filenum); }
|
|
||||||
bool FileExists(const FString & name)
|
|
||||||
{
|
|
||||||
return FindFile(name) >= 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int FindFile (const std::string &name, ELookupMode lookupmode = ELookupMode::FullName, int filenum = -1) const noexcept { return FindFile(name.c_str(), lookupmode, filenum); }
|
|
||||||
int GetFile (const std::string &name, ELookupMode lookupmode = ELookupMode::FullName, int filenum = -1) const { return GetFile(name.c_str(), lookupmode, filenum); }
|
|
||||||
bool FileExists(const std::string& name)
|
|
||||||
{
|
|
||||||
return FindFile(name) >= 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int FindResource (int resid, const char *type, int filenum = -1) const noexcept;
|
|
||||||
int GetResource (int resid, const char *type, int filenum = -1) const; // Like FindFile, but throws an exception when it cannot find what it looks for.
|
|
||||||
|
|
||||||
int AddFromBuffer(const char* name, const char* type, char* data, int size, int id, int flags);
|
|
||||||
|
|
||||||
|
|
||||||
TArray<FString> GetAllFilesOfType(FName type, bool withsubdirs = false);
|
|
||||||
TArray<uint8_t> GetFileData(int file, int pad = 0); // reads file into a writable buffer and optionally adds some padding at the end. (FileData isn't writable!)
|
|
||||||
FileData ReadFile (int file);
|
|
||||||
FileData ReadFile (const char *name) { return ReadFile (GetFile (name)); }
|
|
||||||
|
|
||||||
inline TArray<uint8_t> LoadFile(const char* name, int padding)
|
|
||||||
{
|
|
||||||
auto lump = FindFile(name);
|
|
||||||
if (lump < 0) return TArray<uint8_t>();
|
|
||||||
return GetFileData(lump, padding);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const void *Lock(int lump);
|
|
||||||
void Unlock(int lump, bool mayfree = false);
|
|
||||||
const void *Get(int lump);
|
|
||||||
|
|
||||||
// These are designed to be stand-ins for Blood's resource class.
|
|
||||||
static const void *Lock(FResourceLump *lump);
|
|
||||||
static void Unlock(FResourceLump *lump);
|
|
||||||
static const void *Load(FResourceLump *lump);
|
|
||||||
FResourceLump *Lookup(const char *name, const char *type);
|
|
||||||
FResourceLump *Lookup(unsigned int id, const char *type);
|
|
||||||
bool CreatePathlessCopy(const char *name, int id, int flags);
|
|
||||||
|
|
||||||
FileReader OpenFileReader(int file); // opens a reader that redirects to the containing file's one.
|
|
||||||
FileReader ReopenFileReader(int file, bool alwayscache = false); // opens an independent reader.
|
|
||||||
FileReader OpenFileReader(const char* name, int where);
|
|
||||||
|
|
||||||
int Iterate (const char *name, int *lastfile, ELookupMode lookupmode = ELookupMode::FullName); // [RH] Find files with duplication
|
|
||||||
|
|
||||||
int FileLength (int file) const;
|
|
||||||
int GetFileOffset (int file); // [RH] Returns offset of file in the wadfile
|
|
||||||
int GetFileFlags (int file); // Return the flags for this file
|
|
||||||
const char *GetFileName (int file) const;
|
|
||||||
FString GetFileFullPath (int file) const; // [RH] Returns wad's name + file's full name
|
|
||||||
int GetFileContainer (int file) const; // [RH] Returns filenum for a specified file
|
|
||||||
int GetRFFIndexNum (int file) const; // Returns the RFF index number for this file
|
|
||||||
unsigned GetFilesInFolder(const char *path, TArray<FolderEntry> &result, bool atomic) const;
|
|
||||||
|
|
||||||
bool IsEncryptedFile(int file) const noexcept;
|
|
||||||
int GetResourceId(int file) const;
|
|
||||||
FName GetResourceType(int file) const;
|
|
||||||
|
|
||||||
int GetNumResourceFiles() const { return NumFiles; }
|
|
||||||
int GetNumEntries () const { return NumEntries; }
|
|
||||||
FResourceLump* GetFileAt(int lump) const
|
|
||||||
{
|
|
||||||
return FileInfo[lump].lump;
|
|
||||||
}
|
|
||||||
void PrintDirectory();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
struct FileRecord
|
|
||||||
{
|
|
||||||
int rfnum;
|
|
||||||
FResourceLump* lump;
|
|
||||||
};
|
|
||||||
|
|
||||||
TArray<FResourceFile *> Files;
|
|
||||||
TArray<FileRecord> FileInfo;
|
|
||||||
|
|
||||||
TArray<uint32_t> Hashes; // one allocation for all hash lists.
|
|
||||||
uint32_t *FirstFileIndex[NumLookupModes]; // Hash information for the base name (no path and no extension)
|
|
||||||
uint32_t *NextFileIndex[NumLookupModes];
|
|
||||||
|
|
||||||
uint32_t NumFiles = 0; // Not necessarily the same as FileInfo.Size()
|
|
||||||
uint32_t NumEntries; // Hash modulus. Can be smaller than NumFiles if things get added at run time.
|
|
||||||
|
|
||||||
void InitHashChains (); // [RH] Set up the lumpinfo hashing
|
|
||||||
void AddLump(FResourceLump* lump);
|
|
||||||
|
|
||||||
private:
|
|
||||||
void DeleteAll();
|
|
||||||
};
|
|
||||||
|
|
||||||
extern FileSystem fileSystem;
|
|
||||||
|
|
|
@ -34,7 +34,7 @@
|
||||||
**
|
**
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "filesystem/filesystem.h"
|
#include "filesystem.h"
|
||||||
#include "bitmap.h"
|
#include "bitmap.h"
|
||||||
#include "image.h"
|
#include "image.h"
|
||||||
#include "imagehelpers.h"
|
#include "imagehelpers.h"
|
||||||
|
|
|
@ -40,7 +40,7 @@
|
||||||
#include "fontchars.h"
|
#include "fontchars.h"
|
||||||
#include "printf.h"
|
#include "printf.h"
|
||||||
#include "imagehelpers.h"
|
#include "imagehelpers.h"
|
||||||
#include "filesystem/filesystem.h"
|
#include "filesystem.h"
|
||||||
|
|
||||||
#include "fontinternals.h"
|
#include "fontinternals.h"
|
||||||
|
|
||||||
|
|
|
@ -93,7 +93,7 @@ FFont *V_GetFont(const char *name, const char *fontlumpname)
|
||||||
FFont *font = FFont::FindFont (name);
|
FFont *font = FFont::FindFont (name);
|
||||||
if (font == nullptr)
|
if (font == nullptr)
|
||||||
{
|
{
|
||||||
auto lumpy = fileSystem.OpenFileReader(fontlumpname, 0);
|
auto lumpy = fileSystem.OpenFileReader(fontlumpname);
|
||||||
if (!lumpy.isOpen()) return nullptr;
|
if (!lumpy.isOpen()) return nullptr;
|
||||||
uint32_t head;
|
uint32_t head;
|
||||||
lumpy.Read (&head, 4);
|
lumpy.Read (&head, 4);
|
||||||
|
@ -404,7 +404,7 @@ void V_InitFontColors ()
|
||||||
TranslationLookup.Clear();
|
TranslationLookup.Clear();
|
||||||
TranslationColors.Clear();
|
TranslationColors.Clear();
|
||||||
|
|
||||||
while ((lump = fileSystem.Iterate("engine/textcolors.txt", &lastlump)) != -1)
|
while ((lump = fileSystem.FindLumpFullName("engine/textcolors.txt", &lastlump)) != -1)
|
||||||
{
|
{
|
||||||
FScanner sc(lump);
|
FScanner sc(lump);
|
||||||
while (sc.GetString())
|
while (sc.GetString())
|
||||||
|
|
|
@ -73,6 +73,8 @@ MapRecord *currentLevel; // level that is currently played. (The real level, not
|
||||||
MapRecord* lastLevel; // Same here, for the last level.
|
MapRecord* lastLevel; // Same here, for the last level.
|
||||||
MapRecord userMapRecord; // stand-in for the user map.
|
MapRecord userMapRecord; // stand-in for the user map.
|
||||||
|
|
||||||
|
FILE* hashfile;
|
||||||
|
|
||||||
FStartupInfo RazeStartupInfo;
|
FStartupInfo RazeStartupInfo;
|
||||||
FMemArena dump; // this is for memory blocks than cannot be deallocated without some huge effort. Put them in here so that they do not register on shutdown.
|
FMemArena dump; // this is for memory blocks than cannot be deallocated without some huge effort. Put them in here so that they do not register on shutdown.
|
||||||
|
|
||||||
|
|
|
@ -33,8 +33,7 @@
|
||||||
**
|
**
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "filesystem/filesystem.h"
|
#include "filesystem.h"
|
||||||
#include "filesystem/resourcefile.h"
|
|
||||||
#include "cmdlib.h"
|
#include "cmdlib.h"
|
||||||
#include "zstring.h"
|
#include "zstring.h"
|
||||||
#include "gamecontrol.h"
|
#include "gamecontrol.h"
|
||||||
|
@ -420,7 +419,7 @@ static FString CheckGameInfo(TArray<FString>& pwads)
|
||||||
{
|
{
|
||||||
FResourceLump* lmp = resfile->GetLump(i);
|
FResourceLump* lmp = resfile->GetLump(i);
|
||||||
|
|
||||||
if (lmp->LumpName[0] == gameinfo)
|
if (FName(lmp->getName(), true) == gameinfo)
|
||||||
{
|
{
|
||||||
// Found one!
|
// Found one!
|
||||||
FString iwad = ParseGameInfo(pwads, resfile->FileName, (const char*)lmp->Lock(), lmp->LumpSize);
|
FString iwad = ParseGameInfo(pwads, resfile->FileName, (const char*)lmp->Lock(), lmp->LumpSize);
|
||||||
|
@ -473,6 +472,38 @@ FString GetGameFronUserFiles()
|
||||||
return CheckGameInfo(Files);
|
return CheckGameInfo(Files);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// Deletes unwanted content from the main game files
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
static void DeleteStuff(FileSystem &fileSystem, const TArray<FString>& deletelumps, int numgamefiles)
|
||||||
|
{
|
||||||
|
// This must account for the game directory being inserted at index 2.
|
||||||
|
// Deletion may only occur in the main game file, the directory and the add-on, there are no secondary dependencies, i.e. more than two game files.
|
||||||
|
numgamefiles++;
|
||||||
|
for (auto str : deletelumps)
|
||||||
|
{
|
||||||
|
FString renameTo;
|
||||||
|
auto ndx = str.IndexOf("*");
|
||||||
|
if (ndx >= 0)
|
||||||
|
{
|
||||||
|
renameTo = FName(str.Mid(ndx + 1)).GetChars();
|
||||||
|
str.Truncate(ndx);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < fileSystem.GetNumEntries(); i++)
|
||||||
|
{
|
||||||
|
int cf = fileSystem.GetFileContainer(i);
|
||||||
|
auto fname = fileSystem.GetFileFullName(i, false);
|
||||||
|
if (cf >= 1 && cf <= numgamefiles && !str.CompareNoCase(fname))
|
||||||
|
{
|
||||||
|
fileSystem.RenameFile(i, renameTo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
|
@ -575,15 +606,21 @@ void InitFileSystem(TArray<GrpEntry>& groups)
|
||||||
todelete.Append(g.FileInfo.tobedeleted);
|
todelete.Append(g.FileInfo.tobedeleted);
|
||||||
}
|
}
|
||||||
todelete.Append(userConfig.toBeDeleted);
|
todelete.Append(userConfig.toBeDeleted);
|
||||||
fileSystem.InitMultipleFiles(Files, todelete, groups.Size());
|
LumpFilterInfo lfi;
|
||||||
|
|
||||||
|
lfi.dotFilter = LumpFilter;
|
||||||
|
lfi.postprocessFunc = [&]()
|
||||||
|
{
|
||||||
|
DeleteStuff(fileSystem, todelete, groups.Size());
|
||||||
|
};
|
||||||
|
fileSystem.InitMultipleFiles(Files, false, &lfi);
|
||||||
if (Args->CheckParm("-dumpfs"))
|
if (Args->CheckParm("-dumpfs"))
|
||||||
{
|
{
|
||||||
FILE* f = fopen("filesystem.dir", "wb");
|
FILE* f = fopen("filesystem.dir", "wb");
|
||||||
for (int i = 0; i < fileSystem.GetNumEntries(); i++)
|
for (int i = 0; i < fileSystem.GetNumEntries(); i++)
|
||||||
{
|
{
|
||||||
auto fd = fileSystem.GetFileAt(i);
|
auto fd = fileSystem.GetFileAt(i);
|
||||||
fprintf(f, "%.50s %60s %d\n", fd->FullName(), fileSystem.GetResourceFileFullName(fileSystem.GetFileContainer(i)), fd->Size());
|
fprintf(f, "%.50s %60s %d\n", fd->getName(), fileSystem.GetResourceFileFullName(fileSystem.GetFileContainer(i)), fd->Size());
|
||||||
}
|
}
|
||||||
fclose(f);
|
fclose(f);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1162,7 +1162,7 @@ void M_ParseMenuDefs()
|
||||||
DefaultOptionMenuSettings.Reset();
|
DefaultOptionMenuSettings.Reset();
|
||||||
|
|
||||||
M_DeinitMenus();
|
M_DeinitMenus();
|
||||||
while ((lump = fileSystem.Iterate("engine/menudef.txt", &lastlump)) != -1)
|
while ((lump = fileSystem.FindLumpFullName("engine/menudef.txt", &lastlump)) != -1)
|
||||||
{
|
{
|
||||||
FScanner sc(lump);
|
FScanner sc(lump);
|
||||||
|
|
||||||
|
|
|
@ -379,12 +379,14 @@ unsigned FSavegameManager::ExtractSaveData(int index)
|
||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
void* data = info->Get();
|
void* data = info->Lock();
|
||||||
FSerializer arc;
|
FSerializer arc;
|
||||||
if (!arc.OpenReader((const char*)data, info->LumpSize))
|
if (!arc.OpenReader((const char*)data, info->LumpSize))
|
||||||
{
|
{
|
||||||
|
info->Unlock();
|
||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
|
info->Unlock();
|
||||||
|
|
||||||
FString comment, fcomment, ncomment, mtime;
|
FString comment, fcomment, ncomment, mtime;
|
||||||
|
|
||||||
|
|
|
@ -67,40 +67,12 @@ CVAR(Bool, printmusicinfo, false, 0)
|
||||||
CVAR(Bool, mus_extendedlookup, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
CVAR(Bool, mus_extendedlookup, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
||||||
|
|
||||||
// Order is: streaming formats, module formats, emulated formats and MIDI formats - for external files the first one found wins so ambiguous names should be avoided
|
// Order is: streaming formats, module formats, emulated formats and MIDI formats - for external files the first one found wins so ambiguous names should be avoided
|
||||||
static FName knownMusicExts[] = {
|
static const char* knownMusicExts[] = {
|
||||||
NAME_OGG,
|
"OGG", "FLAC", "MP3", "MP2", "XA", "XM", "MOD",
|
||||||
NAME_FLAC,
|
"IT", "S3M", "MTM", "STM", "669", "PTM", "AMF",
|
||||||
NAME_MP3,
|
"OKT", "DSM", "AMFF", "SPC", "VGM", "VGZ", "AY",
|
||||||
NAME_MP2,
|
"GBS", "GYM", "HES", "KSS", "NSF", "NSFE", "SAP",
|
||||||
NAME_XA,
|
"MID", "HMP", "HMI", "XMI", "VOC"
|
||||||
NAME_XM,
|
|
||||||
NAME_MOD,
|
|
||||||
NAME_IT,
|
|
||||||
NAME_S3M,
|
|
||||||
NAME_MTM,
|
|
||||||
NAME_STM,
|
|
||||||
NAME_669,
|
|
||||||
NAME_PTM,
|
|
||||||
NAME_AMF,
|
|
||||||
NAME_OKT,
|
|
||||||
NAME_DSM,
|
|
||||||
NAME_AMFF,
|
|
||||||
NAME_SPC,
|
|
||||||
NAME_VGM,
|
|
||||||
NAME_VGZ,
|
|
||||||
NAME_AY,
|
|
||||||
NAME_GBS,
|
|
||||||
NAME_GYM,
|
|
||||||
NAME_HES,
|
|
||||||
NAME_KSS,
|
|
||||||
NAME_NSF,
|
|
||||||
NAME_NSFE,
|
|
||||||
NAME_SAP,
|
|
||||||
NAME_MID,
|
|
||||||
NAME_HMP,
|
|
||||||
NAME_HMI,
|
|
||||||
NAME_XMI,
|
|
||||||
NAME_VOC,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -112,7 +84,7 @@ FString G_SetupFilenameBasedMusic(const char* fn, const char* defmusic)
|
||||||
// Test if a real file with this name exists with all known extensions for music.
|
// Test if a real file with this name exists with all known extensions for music.
|
||||||
for (auto& ext : knownMusicExts)
|
for (auto& ext : knownMusicExts)
|
||||||
{
|
{
|
||||||
test.Format("%s.%s", name.GetChars(), ext.GetChars());
|
test.Format("%s.%s", name.GetChars(), ext);
|
||||||
if (FileExists(test)) return test;
|
if (FileExists(test)) return test;
|
||||||
#ifdef __unix__
|
#ifdef __unix__
|
||||||
test.Format("%s.%s", name.GetChars(), FString(ext.GetChars()).MakeLower().GetChars());
|
test.Format("%s.%s", name.GetChars(), FString(ext.GetChars()).MakeLower().GetChars());
|
||||||
|
|
|
@ -97,7 +97,7 @@ void S_ParseSndInfo ()
|
||||||
{
|
{
|
||||||
int lump, lastlump = 0;
|
int lump, lastlump = 0;
|
||||||
|
|
||||||
while ((lump = fileSystem.Iterate("engine/mussetting.txt", &lastlump)) >= 0)
|
while ((lump = fileSystem.FindLumpFullName("engine/mussetting.txt", &lastlump)) >= 0)
|
||||||
{
|
{
|
||||||
S_AddSNDINFO (lump);
|
S_AddSNDINFO (lump);
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,7 +35,7 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "zstring.h"
|
#include "zstring.h"
|
||||||
#include "tarray.h"
|
#include "tarray.h"
|
||||||
#include "filesystem/filesystem.h"
|
#include "filesystem.h"
|
||||||
#include "rts.h"
|
#include "rts.h"
|
||||||
#include "m_swap.h"
|
#include "m_swap.h"
|
||||||
#include "s_soundinternal.h"
|
#include "s_soundinternal.h"
|
||||||
|
@ -81,7 +81,7 @@ bool RTS_IsInitialized()
|
||||||
{
|
{
|
||||||
if (LumpInfo.Size() > 0) return true;
|
if (LumpInfo.Size() > 0) return true;
|
||||||
if (RTSName.IsEmpty()) return false;
|
if (RTSName.IsEmpty()) return false;
|
||||||
auto fr = fileSystem.OpenFileReader(RTSName, 0);
|
auto fr = fileSystem.OpenFileReader(RTSName);
|
||||||
RTSName = ""; // don't try ever again.
|
RTSName = ""; // don't try ever again.
|
||||||
if (!fr.isOpen()) return false;
|
if (!fr.isOpen()) return false;
|
||||||
RTSFile = fr.Read();
|
RTSFile = fr.Read();
|
||||||
|
|
|
@ -39,7 +39,7 @@
|
||||||
#include "gstrings.h"
|
#include "gstrings.h"
|
||||||
#include "i_specialpaths.h"
|
#include "i_specialpaths.h"
|
||||||
#include "cmdlib.h"
|
#include "cmdlib.h"
|
||||||
#include "filesystem/filesystem.h"
|
#include "filesystem.h"
|
||||||
#include "statistics.h"
|
#include "statistics.h"
|
||||||
#include "secrets.h"
|
#include "secrets.h"
|
||||||
#include "quotemgr.h"
|
#include "quotemgr.h"
|
||||||
|
@ -101,12 +101,14 @@ bool OpenSaveGameForRead(const char *name)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void* data = info->Lock();
|
||||||
FSerializer arc;
|
FSerializer arc;
|
||||||
void* data = info->Get();
|
|
||||||
if (!arc.OpenReader((const char*)data, info->LumpSize))
|
if (!arc.OpenReader((const char*)data, info->LumpSize))
|
||||||
{
|
{
|
||||||
|
info->Unlock();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
info->Unlock();
|
||||||
|
|
||||||
// Load system-side data from savegames.
|
// Load system-side data from savegames.
|
||||||
SerializeSession(arc);
|
SerializeSession(arc);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "filesystem/resourcefile.h"
|
#include "resourcefile.h"
|
||||||
|
|
||||||
bool OpenSaveGameForWrite(const char *fname, const char *name);
|
bool OpenSaveGameForWrite(const char *fname, const char *name);
|
||||||
bool OpenSaveGameForRead(const char *name);
|
bool OpenSaveGameForRead(const char *name);
|
||||||
|
|
|
@ -46,8 +46,7 @@
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
#include "gamecontrol.h"
|
#include "gamecontrol.h"
|
||||||
#include "m_argv.h"
|
#include "m_argv.h"
|
||||||
#include "filesystem/filesystem.h"
|
#include "filesystem.h"
|
||||||
#include "filesystem/resourcefile.h"
|
|
||||||
#include "findfile.h"
|
#include "findfile.h"
|
||||||
|
|
||||||
static const char* res_exts[] = { ".grp", ".zip", ".pk3", ".pk4", ".7z", ".pk7" };
|
static const char* res_exts[] = { ".grp", ".zip", ".pk3", ".pk4", ".7z", ".pk7" };
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#include "c_dispatch.h"
|
#include "c_dispatch.h"
|
||||||
#include "filesystem/filesystem.h"
|
#include "filesystem.h"
|
||||||
#include "printf.h"
|
#include "printf.h"
|
||||||
#include "v_text.h"
|
#include "v_text.h"
|
||||||
#include "tarray.h"
|
#include "tarray.h"
|
||||||
|
|
|
@ -4,10 +4,11 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include "tarray.h"
|
#include "tarray.h"
|
||||||
#include "filesystem/file_zip.h"
|
#include "file_zip.h"
|
||||||
#include "tflags.h"
|
#include "tflags.h"
|
||||||
#include "vectors.h"
|
#include "vectors.h"
|
||||||
#include "palentry.h"
|
#include "palentry.h"
|
||||||
|
#include "name.h"
|
||||||
|
|
||||||
extern bool save_full;
|
extern bool save_full;
|
||||||
|
|
||||||
|
|
|
@ -1758,7 +1758,7 @@ CVAR(Bool, snd_extendedlookup, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
||||||
|
|
||||||
int S_LookupSound(const char* fn)
|
int S_LookupSound(const char* fn)
|
||||||
{
|
{
|
||||||
static const FName sndformats[] = { NAME_OGG, NAME_FLAC, NAME_WAV };
|
static const char * const sndformats[] = { "OGG", "FLAC", "WAV" };
|
||||||
if (snd_extendedlookup)
|
if (snd_extendedlookup)
|
||||||
{
|
{
|
||||||
int lump = fileSystem.FindFileWithExtensions(StripExtension(fn), sndformats, countof(sndformats));
|
int lump = fileSystem.FindFileWithExtensions(StripExtension(fn), sndformats, countof(sndformats));
|
||||||
|
|
|
@ -308,7 +308,7 @@ int BuildTiles::LoadArtFile(const char *fn, bool mapart, int firsttile)
|
||||||
auto old = FindFile(fn);
|
auto old = FindFile(fn);
|
||||||
if (old >= ArtFiles.Size()) // Do not process if already loaded.
|
if (old >= ArtFiles.Size()) // Do not process if already loaded.
|
||||||
{
|
{
|
||||||
FileReader fr = fileSystem.OpenFileReader(fn, 0);
|
FileReader fr = fileSystem.OpenFileReader(fn);
|
||||||
if (fr.isOpen())
|
if (fr.isOpen())
|
||||||
{
|
{
|
||||||
auto artdata = fr.Read();
|
auto artdata = fr.Read();
|
||||||
|
@ -598,7 +598,7 @@ void artSetupMapArt(const char* filename)
|
||||||
artClearMapArt();
|
artClearMapArt();
|
||||||
|
|
||||||
FStringf firstname("%s_00.art", filename);
|
FStringf firstname("%s_00.art", filename);
|
||||||
auto fr = fileSystem.OpenFileReader(firstname, 0);
|
auto fr = fileSystem.OpenFileReader(firstname);
|
||||||
if (!fr.isOpen()) return;
|
if (!fr.isOpen()) return;
|
||||||
|
|
||||||
for (bssize_t i = 0; i < MAXARTFILES_TOTAL - MAXARTFILES_BASE; i++)
|
for (bssize_t i = 0; i < MAXARTFILES_TOTAL - MAXARTFILES_BASE; i++)
|
||||||
|
|
|
@ -118,7 +118,7 @@ FArtTexture::FArtTexture(int width, int height, int p)
|
||||||
|
|
||||||
void FArtTexture::CreatePalettedPixels(uint8_t* buffer)
|
void FArtTexture::CreatePalettedPixels(uint8_t* buffer)
|
||||||
{
|
{
|
||||||
FileReader fr = fileSystem.OpenFileReader(Name, 0);
|
FileReader fr = fileSystem.OpenFileReader(Name);
|
||||||
if (!fr.isOpen()) return;
|
if (!fr.isOpen()) return;
|
||||||
int numpixels = Width * Height;
|
int numpixels = Width * Height;
|
||||||
fr.Read(buffer, numpixels);
|
fr.Read(buffer, numpixels);
|
||||||
|
@ -139,7 +139,7 @@ int FArtTexture::CopyPixels(FBitmap *bmp, int conversion)
|
||||||
// Both Src and Dst are ordered the same with no padding.
|
// Both Src and Dst are ordered the same with no padding.
|
||||||
int numpixels = Width * Height;
|
int numpixels = Width * Height;
|
||||||
bool hasalpha = false;
|
bool hasalpha = false;
|
||||||
FileReader fr = fileSystem.OpenFileReader(Name, 0);
|
FileReader fr = fileSystem.OpenFileReader(Name);
|
||||||
if (!fr.isOpen()) return 0;
|
if (!fr.isOpen()) return 0;
|
||||||
TArray<uint8_t> source(numpixels, true);
|
TArray<uint8_t> source(numpixels, true);
|
||||||
fr.Read(source.Data(), numpixels);
|
fr.Read(source.Data(), numpixels);
|
||||||
|
|
|
@ -55,7 +55,7 @@
|
||||||
#include "imagehelpers.h"
|
#include "imagehelpers.h"
|
||||||
#include "image.h"
|
#include "image.h"
|
||||||
#include "m_png.h"
|
#include "m_png.h"
|
||||||
#include "filesystem/filesystem.h"
|
#include "filesystem.h"
|
||||||
|
|
||||||
// Since we want this to compile under Linux too, we need to define this
|
// Since we want this to compile under Linux too, we need to define this
|
||||||
// stuff ourselves instead of including a DirectX header.
|
// stuff ourselves instead of including a DirectX header.
|
||||||
|
@ -374,7 +374,7 @@ void FDDSTexture::CalcBitShift (uint32_t mask, uint8_t *lshiftp, uint8_t *rshift
|
||||||
|
|
||||||
void FDDSTexture::CreatePalettedPixels(uint8_t *buffer)
|
void FDDSTexture::CreatePalettedPixels(uint8_t *buffer)
|
||||||
{
|
{
|
||||||
auto lump = fileSystem.OpenFileReader(Name, 0);
|
auto lump = fileSystem.OpenFileReader(Name);
|
||||||
if (!lump.isOpen()) return; // Just leave the texture blank.
|
if (!lump.isOpen()) return; // Just leave the texture blank.
|
||||||
|
|
||||||
lump.Seek (sizeof(DDSURFACEDESC2) + 4, FileReader::SeekSet);
|
lump.Seek (sizeof(DDSURFACEDESC2) + 4, FileReader::SeekSet);
|
||||||
|
@ -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)
|
||||||
{
|
{
|
||||||
auto lump = fileSystem.OpenFileReader(Name, 0);
|
auto lump = fileSystem.OpenFileReader(Name);
|
||||||
if (!lump.isOpen()) return -1; // Just leave the texture blank.
|
if (!lump.isOpen()) return -1; // Just leave the texture blank.
|
||||||
|
|
||||||
uint8_t *TexBuffer = bmp->GetPixels();
|
uint8_t *TexBuffer = bmp->GetPixels();
|
||||||
|
|
|
@ -40,7 +40,7 @@
|
||||||
#include "printf.h"
|
#include "printf.h"
|
||||||
#include "bitmap.h"
|
#include "bitmap.h"
|
||||||
#include "image.h"
|
#include "image.h"
|
||||||
#include "filesystem/filesystem.h"
|
#include "filesystem.h"
|
||||||
#include "imagehelpers.h"
|
#include "imagehelpers.h"
|
||||||
#include "v_text.h"
|
#include "v_text.h"
|
||||||
|
|
||||||
|
@ -262,7 +262,7 @@ FJPEGTexture::FJPEGTexture (int width, int height)
|
||||||
|
|
||||||
void FJPEGTexture::CreatePalettedPixels(uint8_t *buffer)
|
void FJPEGTexture::CreatePalettedPixels(uint8_t *buffer)
|
||||||
{
|
{
|
||||||
auto lump = fileSystem.OpenFileReader(Name, 0);
|
auto lump = fileSystem.OpenFileReader(Name);
|
||||||
if (!lump.isOpen()) return; // Just leave the texture blank.
|
if (!lump.isOpen()) return; // Just leave the texture blank.
|
||||||
JSAMPLE *buff = NULL;
|
JSAMPLE *buff = NULL;
|
||||||
|
|
||||||
|
@ -385,7 +385,7 @@ int FJPEGTexture::CopyPixels(FBitmap *bmp, int conversion)
|
||||||
{
|
{
|
||||||
PalEntry pe[256];
|
PalEntry pe[256];
|
||||||
|
|
||||||
auto lump = fileSystem.OpenFileReader(Name, 0);
|
auto lump = fileSystem.OpenFileReader(Name);
|
||||||
if (!lump.isOpen()) return -1; // Just leave the texture blank.
|
if (!lump.isOpen()) return -1; // Just leave the texture blank.
|
||||||
|
|
||||||
jpeg_decompress_struct cinfo;
|
jpeg_decompress_struct cinfo;
|
||||||
|
|
|
@ -39,7 +39,7 @@
|
||||||
#include "bitmap.h"
|
#include "bitmap.h"
|
||||||
#include "imagehelpers.h"
|
#include "imagehelpers.h"
|
||||||
#include "image.h"
|
#include "image.h"
|
||||||
#include "filesystem/filesystem.h"
|
#include "filesystem.h"
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
|
@ -350,7 +350,7 @@ void FPCXTexture::CreatePalettedPixels(uint8_t *buffer)
|
||||||
PCXHeader header;
|
PCXHeader header;
|
||||||
int bitcount;
|
int bitcount;
|
||||||
|
|
||||||
auto lump = fileSystem.OpenFileReader(Name, 0);
|
auto lump = fileSystem.OpenFileReader(Name);
|
||||||
if (!lump.isOpen()) return; // Just leave the texture blank.
|
if (!lump.isOpen()) return; // Just leave the texture blank.
|
||||||
|
|
||||||
lump.Read(&header, sizeof(header));
|
lump.Read(&header, sizeof(header));
|
||||||
|
@ -436,7 +436,7 @@ int FPCXTexture::CopyPixels(FBitmap *bmp, int conversion)
|
||||||
int bitcount;
|
int bitcount;
|
||||||
TArray<uint8_t> Pixels;
|
TArray<uint8_t> Pixels;
|
||||||
|
|
||||||
auto lump = fileSystem.OpenFileReader(Name, 0);
|
auto lump = fileSystem.OpenFileReader(Name);
|
||||||
if (!lump.isOpen()) return -1; // Just leave the texture blank.
|
if (!lump.isOpen()) return -1; // Just leave the texture blank.
|
||||||
|
|
||||||
lump.Read(&header, sizeof(header));
|
lump.Read(&header, sizeof(header));
|
||||||
|
|
|
@ -41,7 +41,7 @@
|
||||||
#include "imagehelpers.h"
|
#include "imagehelpers.h"
|
||||||
#include "image.h"
|
#include "image.h"
|
||||||
#include "printf.h"
|
#include "printf.h"
|
||||||
#include "filesystem/filesystem.h"
|
#include "filesystem.h"
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
|
@ -291,7 +291,7 @@ void FPNGTexture::CreatePalettedPixels(uint8_t *buffer)
|
||||||
FileReader *lump;
|
FileReader *lump;
|
||||||
FileReader lfr;
|
FileReader lfr;
|
||||||
|
|
||||||
lfr = fileSystem.OpenFileReader(Name, 0);
|
lfr = fileSystem.OpenFileReader(Name);
|
||||||
if (!lfr.isOpen()) return;
|
if (!lfr.isOpen()) return;
|
||||||
lump = 𝔩
|
lump = 𝔩
|
||||||
|
|
||||||
|
@ -408,7 +408,7 @@ int FPNGTexture::CopyPixels(FBitmap *bmp, int conversion)
|
||||||
FileReader *lump;
|
FileReader *lump;
|
||||||
FileReader lfr;
|
FileReader lfr;
|
||||||
|
|
||||||
lfr = fileSystem.OpenFileReader(Name, 0);
|
lfr = fileSystem.OpenFileReader(Name);
|
||||||
if (!lfr.isOpen()) return -1; // Just leave the texture blank.
|
if (!lfr.isOpen()) return -1; // Just leave the texture blank.
|
||||||
|
|
||||||
lump = 𝔩
|
lump = 𝔩
|
||||||
|
|
|
@ -49,7 +49,7 @@
|
||||||
#include "bitmap.h"
|
#include "bitmap.h"
|
||||||
#include "imagehelpers.h"
|
#include "imagehelpers.h"
|
||||||
#include "image.h"
|
#include "image.h"
|
||||||
#include "filesystem/filesystem.h"
|
#include "filesystem.h"
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
|
@ -154,7 +154,7 @@ void FStbTexture::CreatePalettedPixels(uint8_t *buffer)
|
||||||
|
|
||||||
int FStbTexture::CopyPixels(FBitmap *bmp, int conversion)
|
int FStbTexture::CopyPixels(FBitmap *bmp, int conversion)
|
||||||
{
|
{
|
||||||
auto lump = fileSystem.OpenFileReader(Name, 0);
|
auto lump = fileSystem.OpenFileReader(Name);
|
||||||
if (!lump.isOpen()) return -1; // Just leave the texture blank.
|
if (!lump.isOpen()) return -1; // Just leave the texture blank.
|
||||||
int x, y, chan;
|
int x, y, chan;
|
||||||
auto image = stbi_load_from_callbacks(&callbacks, &lump, &x, &y, &chan, STBI_rgb_alpha);
|
auto image = stbi_load_from_callbacks(&callbacks, &lump, &x, &y, &chan, STBI_rgb_alpha);
|
||||||
|
|
|
@ -37,7 +37,7 @@
|
||||||
#include "templates.h"
|
#include "templates.h"
|
||||||
#include "bitmap.h"
|
#include "bitmap.h"
|
||||||
#include "image.h"
|
#include "image.h"
|
||||||
#include "filesystem/filesystem.h"
|
#include "filesystem.h"
|
||||||
#include "imagehelpers.h"
|
#include "imagehelpers.h"
|
||||||
|
|
||||||
|
|
||||||
|
@ -179,7 +179,7 @@ void FTGATexture::ReadCompressed(FileReader &lump, uint8_t * buffer, int bytespe
|
||||||
void FTGATexture::CreatePalettedPixels(uint8_t *buffer)
|
void FTGATexture::CreatePalettedPixels(uint8_t *buffer)
|
||||||
{
|
{
|
||||||
uint8_t PaletteMap[256];
|
uint8_t PaletteMap[256];
|
||||||
auto lump = fileSystem.OpenFileReader(Name, 0);
|
auto lump = fileSystem.OpenFileReader(Name);
|
||||||
if (!lump.isOpen()) return;
|
if (!lump.isOpen()) return;
|
||||||
TGAHeader hdr;
|
TGAHeader hdr;
|
||||||
uint16_t w;
|
uint16_t w;
|
||||||
|
@ -385,7 +385,7 @@ void FTGATexture::CreatePalettedPixels(uint8_t *buffer)
|
||||||
int FTGATexture::CopyPixels(FBitmap *bmp, int conversion)
|
int FTGATexture::CopyPixels(FBitmap *bmp, int conversion)
|
||||||
{
|
{
|
||||||
PalEntry pe[256];
|
PalEntry pe[256];
|
||||||
auto lump = fileSystem.OpenFileReader(Name, 0);
|
auto lump = fileSystem.OpenFileReader(Name);
|
||||||
if (!lump.isOpen()) return -1;
|
if (!lump.isOpen()) return -1;
|
||||||
TGAHeader hdr;
|
TGAHeader hdr;
|
||||||
uint16_t w;
|
uint16_t w;
|
||||||
|
|
|
@ -38,7 +38,7 @@
|
||||||
#include "bitmap.h"
|
#include "bitmap.h"
|
||||||
#include "image.h"
|
#include "image.h"
|
||||||
#include "files.h"
|
#include "files.h"
|
||||||
#include "filesystem/filesystem.h"
|
#include "filesystem.h"
|
||||||
#include "imagehelpers.h"
|
#include "imagehelpers.h"
|
||||||
|
|
||||||
int FImageSource::NextID;
|
int FImageSource::NextID;
|
||||||
|
@ -79,7 +79,7 @@ FImageSource * FImageSource::GetImage(const char *name)
|
||||||
{ nullptr }
|
{ nullptr }
|
||||||
};
|
};
|
||||||
|
|
||||||
auto data = fileSystem.OpenFileReader(name, 0);
|
auto data = fileSystem.OpenFileReader(name);
|
||||||
if (!data.isOpen()) return nullptr;
|
if (!data.isOpen()) return nullptr;
|
||||||
|
|
||||||
for (size_t i = 0; CreateInfo[i].TryCreate; i++)
|
for (size_t i = 0; CreateInfo[i].TryCreate; i++)
|
||||||
|
|
|
@ -9,48 +9,6 @@ xx(None)
|
||||||
xx(Null)
|
xx(Null)
|
||||||
xx(_)
|
xx(_)
|
||||||
xx(Untranslated)
|
xx(Untranslated)
|
||||||
xx(QAV)
|
|
||||||
xx(SEQ)
|
|
||||||
xx(SFX)
|
|
||||||
xx(RAW)
|
|
||||||
xx(AIF)
|
|
||||||
xx(AIFF)
|
|
||||||
xx(MAP)
|
|
||||||
xx(RFS)
|
|
||||||
xx(WAV)
|
|
||||||
xx(OGG)
|
|
||||||
xx(FLAC)
|
|
||||||
xx(VOC)
|
|
||||||
xx(MP3)
|
|
||||||
xx(XM)
|
|
||||||
xx(MOD)
|
|
||||||
xx(IT)
|
|
||||||
xx(S3M)
|
|
||||||
xx(MTM)
|
|
||||||
xx(MID)
|
|
||||||
xx(HMP)
|
|
||||||
xx(HMI)
|
|
||||||
xx(XMI)
|
|
||||||
xx(SPC)
|
|
||||||
xx(VGM)
|
|
||||||
xx(VGZ)
|
|
||||||
xx(MP2)
|
|
||||||
xx(XA)
|
|
||||||
xx(STM)
|
|
||||||
xx(669)
|
|
||||||
xx(PTM)
|
|
||||||
xx(AMF)
|
|
||||||
xx(OKT)
|
|
||||||
xx(DSM)
|
|
||||||
xx(AMFF)
|
|
||||||
xx(AY)
|
|
||||||
xx(GBS)
|
|
||||||
xx(GYM)
|
|
||||||
xx(HES)
|
|
||||||
xx(KSS)
|
|
||||||
xx(NSF)
|
|
||||||
xx(NSFE)
|
|
||||||
xx(SAP)
|
|
||||||
|
|
||||||
|
|
||||||
xx(Controlmessage)
|
xx(Controlmessage)
|
||||||
|
|
|
@ -11,6 +11,34 @@
|
||||||
extern "C" int mysnprintf(char* buffer, size_t count, const char* format, ...) ATTRIBUTE((format(printf, 3, 4)));
|
extern "C" int mysnprintf(char* buffer, size_t count, const char* format, ...) ATTRIBUTE((format(printf, 3, 4)));
|
||||||
extern "C" int myvsnprintf(char* buffer, size_t count, const char* format, va_list argptr) ATTRIBUTE((format(printf, 3, 0)));
|
extern "C" int myvsnprintf(char* buffer, size_t count, const char* format, va_list argptr) ATTRIBUTE((format(printf, 3, 0)));
|
||||||
|
|
||||||
|
#define TEXTCOLOR_BRICK "\034A"
|
||||||
|
#define TEXTCOLOR_TAN "\034B"
|
||||||
|
#define TEXTCOLOR_GRAY "\034C"
|
||||||
|
#define TEXTCOLOR_GREY "\034C"
|
||||||
|
#define TEXTCOLOR_GREEN "\034D"
|
||||||
|
#define TEXTCOLOR_BROWN "\034E"
|
||||||
|
#define TEXTCOLOR_GOLD "\034F"
|
||||||
|
#define TEXTCOLOR_RED "\034G"
|
||||||
|
#define TEXTCOLOR_BLUE "\034H"
|
||||||
|
#define TEXTCOLOR_ORANGE "\034I"
|
||||||
|
#define TEXTCOLOR_WHITE "\034J"
|
||||||
|
#define TEXTCOLOR_YELLOW "\034K"
|
||||||
|
#define TEXTCOLOR_UNTRANSLATED "\034L"
|
||||||
|
#define TEXTCOLOR_BLACK "\034M"
|
||||||
|
#define TEXTCOLOR_LIGHTBLUE "\034N"
|
||||||
|
#define TEXTCOLOR_CREAM "\034O"
|
||||||
|
#define TEXTCOLOR_OLIVE "\034P"
|
||||||
|
#define TEXTCOLOR_DARKGREEN "\034Q"
|
||||||
|
#define TEXTCOLOR_DARKRED "\034R"
|
||||||
|
#define TEXTCOLOR_DARKBROWN "\034S"
|
||||||
|
#define TEXTCOLOR_PURPLE "\034T"
|
||||||
|
#define TEXTCOLOR_DARKGRAY "\034U"
|
||||||
|
#define TEXTCOLOR_CYAN "\034V"
|
||||||
|
#define TEXTCOLOR_ICE "\034W"
|
||||||
|
#define TEXTCOLOR_FIRE "\034X"
|
||||||
|
#define TEXTCOLOR_SAPPHIRE "\034Y"
|
||||||
|
#define TEXTCOLOR_TEAL "\034Z"
|
||||||
|
|
||||||
// game print flags
|
// game print flags
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
|
@ -48,3 +76,8 @@ int VPrintf(int printlevel, const char* format, va_list parms);
|
||||||
int Printf (int printlevel, const char *format, ...) ATTRIBUTE((format(printf,2,3)));
|
int Printf (int printlevel, const char *format, ...) ATTRIBUTE((format(printf,2,3)));
|
||||||
int Printf (const char *format, ...) ATTRIBUTE((format(printf,1,2)));
|
int Printf (const char *format, ...) ATTRIBUTE((format(printf,1,2)));
|
||||||
int DPrintf (int level, const char *format, ...) ATTRIBUTE((format(printf,2,3)));
|
int DPrintf (int level, const char *format, ...) ATTRIBUTE((format(printf,2,3)));
|
||||||
|
|
||||||
|
void debugprintf(const char* f, ...); // Prints to the debugger's log.
|
||||||
|
|
||||||
|
// flag to silence non-error output
|
||||||
|
extern bool batchrun;
|
||||||
|
|
|
@ -48,7 +48,7 @@
|
||||||
#include "templates.h"
|
#include "templates.h"
|
||||||
#include "zstring.h"
|
#include "zstring.h"
|
||||||
#include "name.h"
|
#include "name.h"
|
||||||
#include "filesystem/filesystem.h"
|
#include "filesystem.h"
|
||||||
|
|
||||||
// MACROS ------------------------------------------------------------------
|
// MACROS ------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -171,7 +171,7 @@ FScanner &FScanner::operator=(const FScanner &other)
|
||||||
|
|
||||||
void FScanner::Open (const char *name)
|
void FScanner::Open (const char *name)
|
||||||
{
|
{
|
||||||
auto fr = fileSystem.OpenFileReader(name, 0);
|
auto fr = fileSystem.OpenFileReader(name);
|
||||||
if (!fr.isOpen())
|
if (!fr.isOpen())
|
||||||
{
|
{
|
||||||
I_Error("Could not find script lump '%s'\n", name);
|
I_Error("Could not find script lump '%s'\n", name);
|
||||||
|
@ -199,7 +199,7 @@ FScanner::FScanner(int lump)
|
||||||
Close();
|
Close();
|
||||||
auto data = fileSystem.GetFileData(lump, 1);
|
auto data = fileSystem.GetFileData(lump, 1);
|
||||||
ScriptBuffer = data;
|
ScriptBuffer = data;
|
||||||
ScriptName = fileSystem.GetFileName(lump);
|
ScriptName = fileSystem.GetFileFullName(lump);
|
||||||
LumpNum = lump;
|
LumpNum = lump;
|
||||||
PrepareScript();
|
PrepareScript();
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,13 +61,13 @@ void FStringTable::LoadStrings ()
|
||||||
int lastlump, lump;
|
int lastlump, lump;
|
||||||
|
|
||||||
lastlump = 0;
|
lastlump = 0;
|
||||||
while ((lump = fileSystem.Iterate("engine/lmacros", &lastlump, ELookupMode::NoExtension)) != -1)
|
while ((lump = fileSystem.FindLumpFullName("engine/lmacros", &lastlump, true)) != -1)
|
||||||
{
|
{
|
||||||
readMacros(lump);
|
readMacros(lump);
|
||||||
}
|
}
|
||||||
|
|
||||||
lastlump = 0;
|
lastlump = 0;
|
||||||
while ((lump = fileSystem.Iterate ("engine/language", &lastlump, ELookupMode::NoExtension)) != -1)
|
while ((lump = fileSystem.FindLumpFullName("engine/language", &lastlump, true)) != -1)
|
||||||
{
|
{
|
||||||
auto lumpdata = fileSystem.GetFileData(lump);
|
auto lumpdata = fileSystem.GetFileData(lump);
|
||||||
|
|
||||||
|
|
|
@ -244,7 +244,7 @@ int32_t Anim_Play(const char *fn)
|
||||||
FileReader handle;
|
FileReader handle;
|
||||||
if (!Bstrcmp(dot, ".ivf"))
|
if (!Bstrcmp(dot, ".ivf"))
|
||||||
{
|
{
|
||||||
handle = fileSystem.OpenFileReader(fn, 0);
|
handle = fileSystem.OpenFileReader(fn);
|
||||||
if (!handle.isOpen())
|
if (!handle.isOpen())
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -263,7 +263,7 @@ int32_t Anim_Play(const char *fn)
|
||||||
vpxfndot[3] = 'f';
|
vpxfndot[3] = 'f';
|
||||||
vpxfndot[4] = '\0';
|
vpxfndot[4] = '\0';
|
||||||
|
|
||||||
handle = fileSystem.OpenFileReader(vpxfn, 0);
|
handle = fileSystem.OpenFileReader(vpxfn);
|
||||||
if (!handle.isOpen())
|
if (!handle.isOpen())
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -404,7 +404,7 @@ int32_t Anim_Play(const char *fn)
|
||||||
|
|
||||||
int32_t ogltexfiltermode = hw_texfilter;
|
int32_t ogltexfiltermode = hw_texfilter;
|
||||||
TArray<uint8_t> buffer;
|
TArray<uint8_t> buffer;
|
||||||
auto fr = fileSystem.OpenFileReader(fn, 0);
|
auto fr = fileSystem.OpenFileReader(fn);
|
||||||
|
|
||||||
if (!fr.isOpen())
|
if (!fr.isOpen())
|
||||||
goto end_anim;
|
goto end_anim;
|
||||||
|
|
|
@ -106,7 +106,7 @@ void G_LoadLookups(void)
|
||||||
{
|
{
|
||||||
int32_t j;
|
int32_t j;
|
||||||
|
|
||||||
auto fr = fileSystem.OpenFileReader("lookup.dat", 0);
|
auto fr = fileSystem.OpenFileReader("lookup.dat");
|
||||||
if (!fr.isOpen())
|
if (!fr.isOpen())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
#define demo_h_
|
#define demo_h_
|
||||||
|
|
||||||
#include "compat.h"
|
#include "compat.h"
|
||||||
#include "filesystem/filesystem.h"
|
#include "filesystem.h"
|
||||||
|
|
||||||
BEGIN_DUKE_NS
|
BEGIN_DUKE_NS
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
#include "printf.h"
|
#include "printf.h"
|
||||||
#include "m_argv.h"
|
#include "m_argv.h"
|
||||||
#include "c_dispatch.h"
|
#include "c_dispatch.h"
|
||||||
#include "filesystem/filesystem.h"
|
#include "filesystem.h"
|
||||||
#include "statistics.h"
|
#include "statistics.h"
|
||||||
#include "menu/menu.h"
|
#include "menu/menu.h"
|
||||||
#include "mapinfo.h"
|
#include "mapinfo.h"
|
||||||
|
|
|
@ -1931,7 +1931,7 @@ static int C_CountCaseStatements()
|
||||||
|
|
||||||
static void C_Include(const char *confile)
|
static void C_Include(const char *confile)
|
||||||
{
|
{
|
||||||
auto fp = fileSystem.OpenFileReader(confile,0);
|
auto fp = fileSystem.OpenFileReader(confile);
|
||||||
|
|
||||||
if (!fp.isOpen())
|
if (!fp.isOpen())
|
||||||
{
|
{
|
||||||
|
@ -5936,7 +5936,7 @@ void C_Compile(const char *fileName)
|
||||||
Gv_Init();
|
Gv_Init();
|
||||||
C_InitProjectiles();
|
C_InitProjectiles();
|
||||||
|
|
||||||
auto kFile = fileSystem.OpenFileReader(fileName,0);
|
auto kFile = fileSystem.OpenFileReader(fileName);
|
||||||
|
|
||||||
if (!kFile.isOpen())
|
if (!kFile.isOpen())
|
||||||
{
|
{
|
||||||
|
|
|
@ -25,7 +25,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
#include "fix16.hpp"
|
#include "fix16.hpp"
|
||||||
#include "gamedef.h"
|
#include "gamedef.h"
|
||||||
#include "filesystem/filesystem.h"
|
#include "filesystem.h"
|
||||||
|
|
||||||
BEGIN_DUKE_NS
|
BEGIN_DUKE_NS
|
||||||
|
|
||||||
|
|
|
@ -2808,7 +2808,7 @@ void InitSpiritHead()
|
||||||
lNextStateChange = (int)totalclock;
|
lNextStateChange = (int)totalclock;
|
||||||
lHeadStartClock = (int)totalclock;
|
lHeadStartClock = (int)totalclock;
|
||||||
|
|
||||||
auto headfd = fileSystem.OpenFileReader(filename, 512); // 512??
|
auto headfd = fileSystem.OpenFileReader(filename); // 512??
|
||||||
if (!headfd.isOpen())
|
if (!headfd.isOpen())
|
||||||
{
|
{
|
||||||
memset(cPupData, 0, sizeof(cPupData));
|
memset(cPupData, 0, sizeof(cPupData));
|
||||||
|
|
|
@ -31,7 +31,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
#include "tarray.h"
|
#include "tarray.h"
|
||||||
#include "save.h"
|
#include "save.h"
|
||||||
#include "zstring.h"
|
#include "zstring.h"
|
||||||
#include "filesystem/filesystem.h"
|
#include "filesystem.h"
|
||||||
|
|
||||||
BEGIN_PS_NS
|
BEGIN_PS_NS
|
||||||
|
|
||||||
|
|
|
@ -85,7 +85,7 @@ int LoadPaletteLookups()
|
||||||
|
|
||||||
for (int i = 0; i < kMaxGrads; i++)
|
for (int i = 0; i < kMaxGrads; i++)
|
||||||
{
|
{
|
||||||
auto hFile = fileSystem.OpenFileReader(GradList[i], 1);
|
auto hFile = fileSystem.OpenFileReader(GradList[i]);
|
||||||
if (!hFile.isOpen())
|
if (!hFile.isOpen())
|
||||||
{
|
{
|
||||||
Printf("Error reading palette lookup '%s'\n", GradList[i]);
|
Printf("Error reading palette lookup '%s'\n", GradList[i]);
|
||||||
|
|
|
@ -1004,7 +1004,7 @@ int LoadCinemaPalette(int nPal)
|
||||||
|
|
||||||
// original code strcpy'd into a buffer first...
|
// original code strcpy'd into a buffer first...
|
||||||
|
|
||||||
auto hFile = fileSystem.OpenFileReader(cinpalfname[nPal], 0);
|
auto hFile = fileSystem.OpenFileReader(cinpalfname[nPal]);
|
||||||
if (!hFile.isOpen()) {
|
if (!hFile.isOpen()) {
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
|
|
|
@ -194,7 +194,7 @@ void PlayMovie(const char* fileName)
|
||||||
|
|
||||||
int bDoFade = kTrue;
|
int bDoFade = kTrue;
|
||||||
int hFx = -1;
|
int hFx = -1;
|
||||||
auto fp = fileSystem.OpenFileReader(fileName, 0);
|
auto fp = fileSystem.OpenFileReader(fileName);
|
||||||
if (!fp.isOpen())
|
if (!fp.isOpen())
|
||||||
{
|
{
|
||||||
Printf("Unable to open %s\n", fileName);
|
Printf("Unable to open %s\n", fileName);
|
||||||
|
|
|
@ -39,10 +39,10 @@
|
||||||
#include "gl_shader.h"
|
#include "gl_shader.h"
|
||||||
#include "textures.h"
|
#include "textures.h"
|
||||||
#include "palette.h"
|
#include "palette.h"
|
||||||
#include "imgui.h"
|
//#include "imgui.h"
|
||||||
#include "gamecontrol.h"
|
#include "gamecontrol.h"
|
||||||
#include "imgui_impl_sdl.h"
|
//#include "imgui_impl_sdl.h"
|
||||||
#include "imgui_impl_opengl3.h"
|
//#include "imgui_impl_opengl3.h"
|
||||||
#include "baselayer.h"
|
#include "baselayer.h"
|
||||||
#include "gl_interface.h"
|
#include "gl_interface.h"
|
||||||
#include "v_2ddrawer.h"
|
#include "v_2ddrawer.h"
|
||||||
|
@ -60,7 +60,7 @@ TArray<VSMatrix> matrixArray;
|
||||||
|
|
||||||
FileReader GetResource(const char* fn)
|
FileReader GetResource(const char* fn)
|
||||||
{
|
{
|
||||||
auto fr = fileSystem.OpenFileReader(fn, 0);
|
auto fr = fileSystem.OpenFileReader(fn);
|
||||||
if (!fr.isOpen())
|
if (!fr.isOpen())
|
||||||
{
|
{
|
||||||
I_Error("Fatal: '%s' not found", fn);
|
I_Error("Fatal: '%s' not found", fn);
|
||||||
|
@ -77,8 +77,8 @@ GLInstance::GLInstance()
|
||||||
matrixArray.Push(mat);
|
matrixArray.Push(mat);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImGui_Init_Backend();
|
//void ImGui_Init_Backend();
|
||||||
ImGuiContext* im_ctx;
|
//ImGuiContext* im_ctx;
|
||||||
TArray<uint8_t> ttf;
|
TArray<uint8_t> ttf;
|
||||||
|
|
||||||
void GLInstance::Init(int ydim)
|
void GLInstance::Init(int ydim)
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "FileStream.h"
|
#include "FileStream.h"
|
||||||
#include "filesystem/filesystem.h"
|
#include "filesystem.h"
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include "cmdlib.h"
|
#include "cmdlib.h"
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@ bool FileStream::Open(const char *fileName)
|
||||||
{
|
{
|
||||||
FString fixedname = fileName;
|
FString fixedname = fileName;
|
||||||
FixPathSeperator(fixedname);
|
FixPathSeperator(fixedname);
|
||||||
file = fileSystem.OpenFileReader(fixedname, 0);
|
file = fileSystem.OpenFileReader(fixedname);
|
||||||
if (!file.isOpen())
|
if (!file.isOpen())
|
||||||
{
|
{
|
||||||
// log error
|
// log error
|
||||||
|
|
|
@ -136,6 +136,7 @@ extern bool AppActive;
|
||||||
|
|
||||||
int SessionState = 0;
|
int SessionState = 0;
|
||||||
int BlockMouseMove;
|
int BlockMouseMove;
|
||||||
|
int refreshfreq;
|
||||||
|
|
||||||
static bool EventHandlerResultForNativeMouse;
|
static bool EventHandlerResultForNativeMouse;
|
||||||
|
|
||||||
|
|
|
@ -45,7 +45,6 @@
|
||||||
#include "version.h" // for GAMENAME
|
#include "version.h" // for GAMENAME
|
||||||
|
|
||||||
// Stuff that needs to be set up later.
|
// Stuff that needs to be set up later.
|
||||||
static bool batchrun;
|
|
||||||
|
|
||||||
// Vanilla MinGW does not have folder ids
|
// Vanilla MinGW does not have folder ids
|
||||||
#if defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR)
|
#if defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR)
|
||||||
|
|
|
@ -280,7 +280,7 @@ int32_t Anim_Play(const char *fn)
|
||||||
FileReader handle;
|
FileReader handle;
|
||||||
if (!Bstrcmp(dot, ".ivf"))
|
if (!Bstrcmp(dot, ".ivf"))
|
||||||
{
|
{
|
||||||
handle = fileSystem.OpenFileReader(fn, 0);
|
handle = fileSystem.OpenFileReader(fn);
|
||||||
if (!handle.isOpen())
|
if (!handle.isOpen())
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -299,7 +299,7 @@ int32_t Anim_Play(const char *fn)
|
||||||
vpxfndot[3] = 'f';
|
vpxfndot[3] = 'f';
|
||||||
vpxfndot[4] = '\0';
|
vpxfndot[4] = '\0';
|
||||||
|
|
||||||
handle = fileSystem.OpenFileReader(vpxfn, 0);
|
handle = fileSystem.OpenFileReader(vpxfn);
|
||||||
if (!handle.isOpen())
|
if (!handle.isOpen())
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -436,7 +436,7 @@ int32_t Anim_Play(const char *fn)
|
||||||
// ANM playback --- v v v ---
|
// ANM playback --- v v v ---
|
||||||
|
|
||||||
int32_t ogltexfiltermode = hw_texfilter;
|
int32_t ogltexfiltermode = hw_texfilter;
|
||||||
auto fr = fileSystem.OpenFileReader(fn, 0);
|
auto fr = fileSystem.OpenFileReader(fn);
|
||||||
|
|
||||||
if (!fr.isOpen())
|
if (!fr.isOpen())
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -105,7 +105,7 @@ void G_LoadLookups(void)
|
||||||
{
|
{
|
||||||
int32_t j;
|
int32_t j;
|
||||||
|
|
||||||
auto fr = fileSystem.OpenFileReader("lookup.dat", 0);
|
auto fr = fileSystem.OpenFileReader("lookup.dat");
|
||||||
if (!fr.isOpen())
|
if (!fr.isOpen())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
|
@ -43,7 +43,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
#include "gameconfigfile.h"
|
#include "gameconfigfile.h"
|
||||||
#include "printf.h"
|
#include "printf.h"
|
||||||
#include "m_argv.h"
|
#include "m_argv.h"
|
||||||
#include "filesystem/filesystem.h"
|
#include "filesystem.h"
|
||||||
#include "statistics.h"
|
#include "statistics.h"
|
||||||
#include "c_dispatch.h"
|
#include "c_dispatch.h"
|
||||||
#include "mapinfo.h"
|
#include "mapinfo.h"
|
||||||
|
|
|
@ -955,7 +955,7 @@ static int32_t C_CheckEmptyBranch(int32_t tw, intptr_t lastScriptPtr)
|
||||||
|
|
||||||
static void C_Include(const char *confile)
|
static void C_Include(const char *confile)
|
||||||
{
|
{
|
||||||
auto fp = fileSystem.OpenFileReader(confile,0);
|
auto fp = fileSystem.OpenFileReader(confile);
|
||||||
|
|
||||||
if (!fp.isOpen())
|
if (!fp.isOpen())
|
||||||
{
|
{
|
||||||
|
@ -2646,7 +2646,7 @@ void C_Compile(const char *fileName)
|
||||||
C_InitHashes();
|
C_InitHashes();
|
||||||
Gv_Init();
|
Gv_Init();
|
||||||
|
|
||||||
auto kFile = fileSystem.OpenFileReader(fileName,0);
|
auto kFile = fileSystem.OpenFileReader(fileName);
|
||||||
|
|
||||||
if (!kFile.isOpen())
|
if (!kFile.isOpen())
|
||||||
{
|
{
|
||||||
|
|
|
@ -241,7 +241,7 @@ playanm(short anim_num)
|
||||||
MONO_PRINT(ds);
|
MONO_PRINT(ds);
|
||||||
|
|
||||||
TArray<uint8_t> buffer;
|
TArray<uint8_t> buffer;
|
||||||
auto fr = fileSystem.OpenFileReader(ANIMname[ANIMnum], 0);
|
auto fr = fileSystem.OpenFileReader(ANIMname[ANIMnum]);
|
||||||
|
|
||||||
if (!fr.isOpen())
|
if (!fr.isOpen())
|
||||||
goto ENDOFANIMLOOP;
|
goto ENDOFANIMLOOP;
|
||||||
|
|
|
@ -55,7 +55,7 @@ extern int DemoRecCnt; // Can only record 1-player game
|
||||||
#if DEMO_FILE_TYPE == DEMO_FILE_GROUP
|
#if DEMO_FILE_TYPE == DEMO_FILE_GROUP
|
||||||
typedef FileReader DFILE;
|
typedef FileReader DFILE;
|
||||||
#define DREAD(ptr, size, num, handle) (handle).Read((ptr),(size)*(num))
|
#define DREAD(ptr, size, num, handle) (handle).Read((ptr),(size)*(num))
|
||||||
#define DOPEN_READ(name) fileSystem.OpenFileReader(name,0)
|
#define DOPEN_READ(name) fileSystem.OpenFileReader(name)
|
||||||
#define DCLOSE(handle) ((handle).Close())
|
#define DCLOSE(handle) ((handle).Close())
|
||||||
#define DF_ERR(f) (!(f).isOpen())
|
#define DF_ERR(f) (!(f).isOpen())
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -82,7 +82,7 @@ SWBOOL LoadScriptFile(const char *filename)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (!(fp = fileSystem.OpenFileReader(filename, 0)).isOpen())
|
if (!(fp = fileSystem.OpenFileReader(filename)).isOpen())
|
||||||
{
|
{
|
||||||
// If there's no script file, forget it.
|
// If there's no script file, forget it.
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
|
@ -51,7 +51,7 @@ Prepared for public release: 03/28/2005 - Charlie Wiederhold, 3D Realms
|
||||||
#include "menu/menu.h"
|
#include "menu/menu.h"
|
||||||
#include "z_music.h"
|
#include "z_music.h"
|
||||||
#include "sound/s_soundinternal.h"
|
#include "sound/s_soundinternal.h"
|
||||||
#include "filesystem/filesystem.h"
|
#include "filesystem.h"
|
||||||
#include "serializer.h"
|
#include "serializer.h"
|
||||||
|
|
||||||
BEGIN_SW_NS
|
BEGIN_SW_NS
|
||||||
|
|
Loading…
Reference in a new issue