- hooked up the file system with Blood's resource access.

This commit is contained in:
Christoph Oelckers 2019-10-31 20:17:49 +01:00
parent d7e183d46d
commit ba00fe4e66
17 changed files with 64 additions and 199 deletions

View File

@ -55,7 +55,7 @@ char scriptBuffer[256];
struct define_t
{
char *_text;
FString _text;
int _value;
};
@ -132,9 +132,7 @@ void AddCmdDefine(char *text, int value)
{
dassert(nCmdDefines < kMaxCmdLineDefines);
gCmdDefines[nCmdDefines]._text = (char*)Resource::Alloc(strlen(text) + 1);
strcpy(gCmdDefines[nCmdDefines]._text, text);
gCmdDefines[nCmdDefines]._text = text;
gCmdDefines[nCmdDefines]._value = value;
nCmdDefines++;
@ -144,6 +142,7 @@ void AddCmdDefine(char *text, int value)
struct RFS
{
private:
TArray<char> buffer;
char *_ptr; // [0]
char _curChar; // [4]
char *_pUnknown2; // [5] - some sort of pointer into _ptr?
@ -177,7 +176,8 @@ int RFS::Open(const char *fileName)
}
int fileSize = hFile.GetLength();
_ptr = (char*)Resource::Alloc(fileSize);
buffer.Resize(fileSize);
_ptr = buffer.Data();
if (_ptr == NULL) {
initprintf("BARF: Not enough memory to read %s", _fileName);
return 1;
@ -195,12 +195,6 @@ int RFS::Open(const char *fileName)
void RFS::Close()
{
if (_ptr) {
/* BUG - the original code called nfree but this should be a Resource::Free()
_nfree(_ptr);
*/
Resource::Free(_ptr);
}
}
void RFS::Increment()
@ -586,7 +580,6 @@ void ParseScript(const char *scriptFileName)
}
ID = scriptValue;
nFlags |= DICT_ID;
tag = rfs.GetNextTag();
}
@ -767,7 +760,6 @@ void ParseScript(const char *scriptFileName)
// AddDefine(fileName, scriptValue);
//}
nFlags |= DICT_ID;
ID = scriptValue;
tag = rfs.GetNextTag();
}

View File

@ -194,11 +194,13 @@ void ShutDown(void)
// PORT_TODO: Check argument
if (syncstate)
printf("A packet was lost! (syncstate)\n");
#if 0 // never used anywhere.
for (int i = 0; i < 10; i++)
{
if (gSaveGamePic[i])
Resource::Free(gSaveGamePic[i]);
}
#endif
DO_FREE_AND_NULL(pUserTiles);
DO_FREE_AND_NULL(pUserSoundRFF);
DO_FREE_AND_NULL(pUserRFF);
@ -387,16 +389,25 @@ void PreloadTiles(void)
gameHandleEvents();
}
static void PrecacheSounds(void)
{
for (unsigned int i = 0; i < fileSystem.GetNumEntries(); i++)
{
DICTNODE* pNode = fileSystem.GetFileAt(i);
if (pNode->ResType() == NAME_RAW || pNode->ResType() == NAME_SFX)
{
pNode->Get();
if ((i&15) == 15) gameHandleEvents(); // don't do this too often. That made sense in 1996 but not in 2019
}
}
}
void PreloadCache(void)
{
char tempbuf[128];
if (gDemo.at1)
return;
gSysRes.PurgeCache();
gSoundRes.PurgeCache();
gSysRes.PrecacheSounds();
gSoundRes.PrecacheSounds();
PrecacheSounds();
if (mus_restartonload)
sndTryPlaySpecialMusic(MUS_LOADING);
PreloadTiles();
@ -1301,9 +1312,9 @@ int app_main(int argc, char const * const * argv)
#ifdef USE_QHEAP
Resource::heap = new QHeap(nMaxAlloc);
#endif
gSysRes.Init(pUserRFF ? pUserRFF : "BLOOD.RFF");
//gSysRes.Init(pUserRFF ? pUserRFF : "BLOOD.RFF");
//gGuiRes.Init("GUI.RFF");
gSoundRes.Init(pUserSoundRFF ? pUserSoundRFF : "SOUNDS.RFF");
//gSoundRes.Init(pUserSoundRFF ? pUserSoundRFF : "SOUNDS.RFF");
HookReplaceFunctions();
@ -1896,10 +1907,7 @@ static int parsedefinitions_game(scriptfile *pScript, int firstPass)
if (!firstPass)
{
if (!Bstrcasecmp(rffName, "SYSTEM"))
gSysRes.AddExternalResource(resName, resType, resID);
else if (!Bstrcasecmp(rffName, "SOUND"))
gSoundRes.AddExternalResource(resName, resType, resID);
gSysRes.AddExternalResource(resName, resType, resID);
}
}
break;

View File

@ -2241,7 +2241,7 @@ bool CGameMenuItemQAV::Event(CGameMenuEvent &event)
if (at20 && at28)
{
gSysRes.Unlock(at24);
if (at24->lockCount == 0)
if (at24->LockCount() == 0)
at28 = NULL;
}
return false;

View File

@ -44,7 +44,7 @@ int gGamma;
char *gVersionString;
char gVersionStringBuf[16];
Resource gSysRes;
Resource& gSysRes = fileSystem;
static const char *_module;
static int _line;

View File

@ -35,7 +35,7 @@ extern int gFrameRate;
extern int gGamma;
extern bool bVanilla;
extern Resource gSysRes;
extern Resource &gSysRes;
const char *GetVersionString(void);
END_BLD_NS

View File

@ -65,8 +65,10 @@ short word_27AA54 = 0;
void sub_76FD4(void)
{
#if 0
if (!dword_27AA44)
dword_27AA44 = Resource::Alloc(0x186a0);
#endif
}
void LoadSave::Save(void)

View File

@ -45,9 +45,9 @@ BEGIN_BLD_NS
// Code left here for documentation.
// It's unlikely to be needed by today's systems so unless needed I rather leave such hacks out of the file system.
#if B_BIG_ENDIAN == 1
// Todo: Hook these up with the resource loader
void ByteSwapQAV(void *p)
{
QAV *qav = (QAV*)p;

View File

@ -23,115 +23,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#pragma once
#include "common.h"
#include "qheap.h"
#include "filesystem/resourcefile.h"
#include "filesystem/filesystem.h"
BEGIN_BLD_NS
#pragma pack(push, 1)
enum DICTFLAGS {
DICT_ID = 1,
DICT_EXTERNAL = 2,
DICT_LOAD = 4,
DICT_LOCK = 8,
DICT_CRYPT = 16,
DICT_BUFFER = 32,
};
struct RFFHeader
{
char sign[4];
short version;
short pad1;
unsigned int offset;
unsigned int filenum;
int pad2[4];
};
struct DICTNODE_FILE
{
char unused1[16];
unsigned int offset;
unsigned int size;
char unused2[8];
char flags;
char type[3];
char name[8];
int id;
};
#pragma pack(pop)
struct CACHENODE
{
void *ptr;
CACHENODE *prev;
CACHENODE *next;
int lockCount;
};
struct DICTNODE : CACHENODE
{
unsigned int offset;
unsigned int size;
char flags;
//char type[3];
//char name[8];
char *type;
char *name;
char *path;
char *buffer;
unsigned int id;
unsigned int Size() const { return size; }
int LockCount() const { return lockCount; }
};
class Resource
{
public:
Resource(void);
~Resource(void);
void Init(const char *filename);
static void Flush(CACHENODE *h);
void Purge(void);
DICTNODE **Probe(const char *fname, const char *type);
DICTNODE **Probe(unsigned int id, const char *type);
void Reindex(void);
void Grow(void);
void AddExternalResource(const char *name, const char *type, int id = 0, int flags = 0, const char* pzDirectory = NULL);
void AddFromBuffer(const char* name, const char* type, char *data, int size, int id = 0, int flags = 0);
static void *Alloc(int nSize);
static void Free(void *p);
DICTNODE *Lookup(const char *name, const char *type);
DICTNODE *Lookup(unsigned int id, const char *type);
void Read(DICTNODE *n);
void Read(DICTNODE *n, void *p);
void *Load(DICTNODE *h);
void *Load(DICTNODE *h, void *p);
void *Lock(DICTNODE *h);
void Unlock(DICTNODE *h);
void Crypt(void *p, int length, unsigned short key);
static void RemoveMRU(CACHENODE *h);
int Size(DICTNODE*h) { return h->size; }
void FNAddFiles(fnlist_t *fnlist, const char *pattern);
void PrecacheSounds(void);
void PurgeCache(void);
void RemoveNode(DICTNODE* pNode);
DICTNODE *dict;
DICTNODE **indexName;
DICTNODE **indexId;
unsigned int buffSize;
unsigned int count;
int handle;
bool crypt;
#if USE_QHEAP
static QHeap *heap;
#endif
static CACHENODE purgeHead;
};
END_BLD_NS
using Resource = FileSystem;

View File

@ -36,7 +36,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
BEGIN_BLD_NS
Resource gSoundRes;
Resource& gSoundRes = fileSystem;
int soundRates[13] = {
11025,
@ -97,7 +97,8 @@ int sndPlaySong(const char *songName, bool bLoop)
}
int nNewSongSize = hSong->Size();
char *pNewSongPtr = (char *)Xaligned_alloc(16, nNewSongSize);
gSoundRes.Load(hSong, pNewSongPtr);
memcpy(pNewSongPtr, hSong->Lock(), nNewSongSize);
hSong->Unlock(true);
MUSIC_SetVolume(mus_volume);
int32_t retval = MUSIC_PlaySong(pNewSongPtr, nNewSongSize, bLoop);
@ -352,7 +353,8 @@ void sndStartWavDisk(const char *pzFile, int nVolume, int nChannel)
if (!hFile.isOpen())
return;
int nLength = hFile.GetLength();
char *pData = (char*)gSoundRes.Alloc(nLength);
char* pData = nullptr;
cacheAllocateBlock((intptr_t*)pData, nLength, nullptr); // use this obsolete call to indicate that some work is needed here!
if (!pData)
{
return;
@ -374,14 +376,9 @@ void sndKillAllSounds(void)
{
if (pChannel->at4 & 2)
{
#if 0
free(pChannel->at5);
#else
gSoundRes.Free(pChannel->at5);
#endif
pChannel->at4 &= ~2;
}
else
else // This 'else' needs to be removed once the file system is up (when cacheAllocateBlock gets replaced.)
{
gSoundRes.Unlock(pChannel->at5);
}
@ -398,10 +395,9 @@ void sndProcess(void)
{
if (Channel[i].at4 & 2)
{
gSoundRes.Free(Channel[i].at5);
Channel[i].at4 &= ~2;
}
else
else // This 'else' needs to be removed once the file system is up (when cacheAllocateBlock gets replaced.)
{
gSoundRes.Unlock(Channel[i].at5);
}

View File

@ -59,6 +59,6 @@ void sndProcess(void);
void sndTerm(void);
void sndInit(void);
extern Resource gSoundRes;
extern Resource &gSoundRes;
END_BLD_NS

View File

@ -1758,7 +1758,7 @@ void viewInit(void)
DICTNODE *hLens = gSysRes.Lookup("LENS", "DAT");
dassert(hLens != NULL);
dassert(gSysRes.Size(hLens) == kLensSize * kLensSize * sizeof(int));
dassert(hLens->Size() == kLensSize * kLensSize * sizeof(int));
lensTable = (int*)gSysRes.Lock(hLens);
#if B_BIG_ENDIAN == 1

View File

@ -123,16 +123,3 @@ void Resource::RemoveMRU(CACHENODE *h)
h->next->prev = h->prev;
}
void Resource::PrecacheSounds(void)
{
for (unsigned int i = 0; i < count; i++)
{
DICTNODE *pNode = &dict[i];
if ((!strcmp(pNode->type, "RAW") || !strcmp(pNode->type, "SFX")) && !pNode->ptr)
{
Load(pNode);
gameHandleEvents();
}
}
}

View File

@ -55,19 +55,13 @@
#define NULL_INDEX (0xffffffff)
struct FileSystem::FileRecord
{
int rfnum;
FResourceLump *lump;
};
// PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
static void PrintLastError ();
// PUBLIC DATA DEFINITIONS -------------------------------------------------
FileSystem Files;
FileSystem fileSystem;
// CODE --------------------------------------------------------------------
@ -866,21 +860,6 @@ void FileSystem::AddFromBuffer(const char* name, const char* type, char* data, i
AddLump(newlump);
}
//==========================================================================
//
// Read
//
// Reads lump into buffer (simulate Blood interface)
//
//==========================================================================
void FileSystem::Read(FResourceLump *n, void *p)
{
if (!n || !p) return;
auto r = n->Get();
memcpy(p, r, n->Size());
}
//==========================================================================
//
// Blood style lookup functions
@ -986,7 +965,7 @@ FileData::~FileData ()
FString::FString (ELumpNum lumpnum)
{
auto lumpr = Files.OpenFileReader ((int)lumpnum);
auto lumpr = fileSystem.OpenFileReader ((int)lumpnum);
auto size = lumpr.GetLength ();
AllocBuffer (1 + size);
auto numread = lumpr.Read (&Chars[0], size);
@ -995,7 +974,7 @@ FString::FString (ELumpNum lumpnum)
if (numread != size)
{
FStringf err("ConstructStringFromLump: Only read %ld of %ld bytes on lump %i (%s)\n",
numread, size, lumpnum, Files.GetFileName((int)lumpnum));
numread, size, lumpnum, fileSystem.GetFileName((int)lumpnum));
}
}

View File

@ -118,23 +118,18 @@ public:
static const void *Lock(FResourceLump *lump);
static void Unlock(FResourceLump *lump);
static const void *Load(FResourceLump *lump);
static void Read(FResourceLump *lump) { Load(lump); }
static void Read(FResourceLump *n, void *p);
FResourceLump *Lookup(const char *name, const char *type);
FResourceLump *Lookup(unsigned int id, const char *type);
void AddExternalResource(const char *name, const char *type, int id, int flags, const char *pzDirectory);
void AddExternalResource(const char *name, const char *type, int id, int flags = 0, const char *pzDirectory = nullptr);
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.
int Iterate (const char *name, int *lastfile, ELookupMode lookupmode = ELookupMode::FullName); // [RH] Find files with duplication
static uint32_t FileNameHash (const char *name); // [RH] Create hash key from a given name
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
void GetFileName (char *to, int file) const; // [RH] Copies the file name to to using uppercopy
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
@ -146,10 +141,18 @@ public:
int GetNumResourceFiles() const { return NumFiles; }
int GetNumEntries () const { return NumEntries; }
FResourceLump* GetFileAt(int lump) const
{
return FileInfo[lump].lump;
}
protected:
struct FileRecord;
struct FileRecord
{
int rfnum;
FResourceLump* lump;
};
TArray<FResourceFile *> Files;
TArray<FileRecord> FileInfo;
@ -168,5 +171,5 @@ private:
void DeleteAll();
};
extern FileSystem Files;
extern FileSystem fileSystem;

View File

@ -37,6 +37,7 @@
#include <zlib.h>
#include "resourcefile.h"
#include "name.h"
#include "m_swap.h"
extern FString LumpFilter;
@ -155,6 +156,8 @@ void *FResourceLump::Lock()
else if (LumpSize > 0)
{
ValidateCache();
// 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();

View File

@ -84,7 +84,7 @@ struct FResourceLump
unsigned Size() const{ return LumpSize; }
int LockCount() const { return RefCount; }
const char *ResName() const { return LumpName[BaseNameNoExtType]; }
const char *ResType() { return LumpName[ExtensionType]; }
const FName ResType() { return LumpName[ExtensionType]; }
const char *FullName() const { return LumpName[FullNameType]; }
protected:

View File

@ -3,4 +3,7 @@ xx(None)
xx(Null)
xx(_)
xx(Untranslated)
xx(QAV)
xx(SEQ)
xx(SFX)
xx(RAW)