Use C++ heap for resource manager

# Conflicts:
#	source/blood/src/actor.cpp
#	source/blood/src/mapedit.cpp
This commit is contained in:
nukeykt 2019-09-16 00:25:21 +09:00 committed by Christoph Oelckers
parent 55de5230ca
commit c91a85a353
6 changed files with 120 additions and 24 deletions

View file

@ -7221,10 +7221,16 @@ int getDudeMassBySpriteSize(spritetype* pSprite) {
if (xrepeat > 64) x += ((xrepeat - 64) * 2); if (xrepeat > 64) x += ((xrepeat - 64) * 2);
else if (xrepeat < 64) x -= ((64 - xrepeat) * 2); else if (xrepeat < 64) x -= ((64 - xrepeat) * 2);
int yrepeat = pSprite->yrepeat; if (seqId >= 0) {
int y = tilesiz[picnum].y; DICTNODE* hSeq = gSysRes.Lookup(seqId, "SEQ");
if (yrepeat > 64) y += ((yrepeat - 64) * 2); if (hSeq)
else if (yrepeat < 64) y -= ((64 - yrepeat) * 2); {
pSeq = (Seq*)gSysRes.Load(hSeq);
picnum = seqGetTile(&pSeq->frames[0]);
}
else
picnum = pSprite->picnum;
}
mass = ((x + y) * clipDist) / 25; mass = ((x + y) * clipDist) / 25;
//if ((mass+=(x+y)) > 200) mass+=((mass - 200)*16); //if ((mass+=(x+y)) > 200) mass+=((mass - 200)*16);

View file

@ -84,7 +84,9 @@ int32_t gNoSetup = 0, gCommandSetup = 0;
INPUT_MODE gInputMode; INPUT_MODE gInputMode;
#ifdef USE_QHEAP
unsigned int nMaxAlloc = 0x4000000; unsigned int nMaxAlloc = 0x4000000;
#endif
bool bCustomName = false; bool bCustomName = false;
char bAddUserMap = false; char bAddUserMap = false;
@ -1010,7 +1012,9 @@ SWITCH switches[] = {
{ "art", 26, 1 }, { "art", 26, 1 },
{ "snd", 27, 1 }, { "snd", 27, 1 },
{ "rff", 28, 1 }, { "rff", 28, 1 },
#ifdef USE_QHEAP
{ "maxalloc", 29, 1 }, { "maxalloc", 29, 1 },
#endif
{ "server", 30, 1 }, { "server", 30, 1 },
{ "client", 31, 1 }, { "client", 31, 1 },
{ "noautoload", 32, 0 }, { "noautoload", 32, 0 },
@ -1111,12 +1115,14 @@ void ParseOptions(void)
ThrowError("Invalid argument: %s", OptFull); ThrowError("Invalid argument: %s", OptFull);
fallthrough__; fallthrough__;
case 29: case 29:
#ifdef USE_QHEAP
if (OptArgc < 1) if (OptArgc < 1)
ThrowError("Missing argument"); ThrowError("Missing argument");
nMaxAlloc = atoi(OptArgv[0]); nMaxAlloc = atoi(OptArgv[0]);
if (!nMaxAlloc) if (!nMaxAlloc)
nMaxAlloc = 0x2000000; nMaxAlloc = 0x2000000;
break; break;
#endif
case 0: case 0:
PrintHelp(); PrintHelp();
break; break;
@ -1500,7 +1506,9 @@ int app_main(int argc, char const * const * argv)
system_getcvars(); system_getcvars();
#ifdef USE_QHEAP
Resource::heap = new QHeap(nMaxAlloc); Resource::heap = new QHeap(nMaxAlloc);
#endif
gSysRes.Init(pUserRFF ? pUserRFF : "BLOOD.RFF"); gSysRes.Init(pUserRFF ? pUserRFF : "BLOOD.RFF");
gGuiRes.Init("GUI.RFF"); gGuiRes.Init("GUI.RFF");
gSoundRes.Init(pUserSoundRFF ? pUserSoundRFF : "SOUNDS.RFF"); gSoundRes.Init(pUserSoundRFF ? pUserSoundRFF : "SOUNDS.RFF");

View file

@ -20,6 +20,8 @@ along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/ */
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
#ifdef USE_QHEAP
#include <stdio.h> #include <stdio.h>
#include <ctype.h> #include <ctype.h>
#include <stdlib.h> #include <stdlib.h>
@ -215,3 +217,5 @@ int QHeap::Free(void *p)
} }
return node->size - 0x40; return node->size - 0x40;
} }
#endif

View file

@ -22,6 +22,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
#pragma once #pragma once
#ifdef USE_QHEAP
struct HEAPNODE struct HEAPNODE
{ {
HEAPNODE *prev; HEAPNODE *prev;
@ -47,4 +49,6 @@ public:
HEAPNODE heap; HEAPNODE heap;
HEAPNODE freeHeap; HEAPNODE freeHeap;
int size; int size;
}; };
#endif

View file

@ -44,8 +44,9 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
CACHENODE Resource::purgeHead = { NULL, &purgeHead, &purgeHead, 0 }; CACHENODE Resource::purgeHead = { NULL, &purgeHead, &purgeHead, 0 };
#ifdef USE_QHEAP
QHeap *Resource::heap; QHeap *Resource::heap;
#endif
Resource::Resource(void) Resource::Resource(void)
{ {
dict = NULL; dict = NULL;
@ -82,7 +83,9 @@ Resource::~Resource(void)
void Resource::Init(const char *filename) void Resource::Init(const char *filename)
{ {
RFFHeader header; RFFHeader header;
#ifdef USE_QHEAP
dassert(heap != NULL); dassert(heap != NULL);
#endif
if (filename) if (filename)
{ {
@ -228,11 +231,16 @@ void Resource::Flush(CACHENODE *h)
{ {
if (h->ptr) if (h->ptr)
{ {
#ifdef USE_QHEAP
heap->Free(h->ptr); heap->Free(h->ptr);
#else
delete h->ptr;
#endif
h->ptr = NULL; h->ptr = NULL;
if (h->lockCount == 0) if (h->lockCount == 0)
{ {
RemoveMRU((CACHENODE*)h); RemoveMRU(h);
return; return;
} }
h->lockCount = 0; h->lockCount = 0;
@ -358,7 +366,10 @@ void Resource::AddExternalResource(const char *name, const char *type, int id)
{ {
char name2[BMAX_PATH], type2[BMAX_PATH], filename[BMAX_PATH*2]; char name2[BMAX_PATH], type2[BMAX_PATH], filename[BMAX_PATH*2];
//if (strlen(name) > 8 || strlen(type) > 3) return; //if (strlen(name) > 8 || strlen(type) > 3) return;
sprintf(filename, "%s.%s", name, type); if (Bstrlen(type) > 0)
Bsprintf(filename, "%s.%s", name, type);
else
Bsprintf(filename, "%s", name);
int fhandle = kopen4loadfrommod(filename, 0); int fhandle = kopen4loadfrommod(filename, 0);
if (fhandle == -1) if (fhandle == -1)
return; return;
@ -384,9 +395,15 @@ void Resource::AddExternalResource(const char *name, const char *type, int id)
index = Probe(name2, type2); index = Probe(name2, type2);
*index = node; *index = node;
if (node->type) if (node->type)
{
Free(node->type); Free(node->type);
node->type = NULL;
}
if (node->name) if (node->name)
{
Free(node->name); Free(node->name);
node->name = NULL;
}
int nTypeLength = strlen(type2); int nTypeLength = strlen(type2);
int nNameLength = strlen(name2); int nNameLength = strlen(name2);
node->type = (char*)Alloc(nTypeLength+1); node->type = (char*)Alloc(nTypeLength+1);
@ -396,7 +413,7 @@ void Resource::AddExternalResource(const char *name, const char *type, int id)
} }
node->size = size; node->size = size;
node->flags |= DICT_EXTERNAL; node->flags |= DICT_EXTERNAL;
Flush((CACHENODE*)node); Flush(node);
if (id != -1) if (id != -1)
{ {
index = Probe(id, type2); index = Probe(id, type2);
@ -413,9 +430,15 @@ void Resource::AddExternalResource(const char *name, const char *type, int id)
*index = node; *index = node;
} }
if (node->type) if (node->type)
{
Free(node->type); Free(node->type);
node->type = NULL;
}
if (node->name) if (node->name)
{
Free(node->name); Free(node->name);
node->name = NULL;
}
int nTypeLength = strlen(type2); int nTypeLength = strlen(type2);
int nNameLength = strlen(name2); int nNameLength = strlen(name2);
node->type = (char*)Alloc(nTypeLength+1); node->type = (char*)Alloc(nTypeLength+1);
@ -425,12 +448,13 @@ void Resource::AddExternalResource(const char *name, const char *type, int id)
node->id = id; node->id = id;
node->size = size; node->size = size;
node->flags |= DICT_EXTERNAL; node->flags |= DICT_EXTERNAL;
Flush((CACHENODE*)node); Flush(node);
} }
} }
void *Resource::Alloc(int nSize) void *Resource::Alloc(int nSize)
{ {
#ifdef USE_QHEAP
dassert(heap != NULL); dassert(heap != NULL);
dassert(nSize != 0); dassert(nSize != 0);
void *p = heap->Alloc(nSize); void *p = heap->Alloc(nSize);
@ -454,13 +478,39 @@ void *Resource::Alloc(int nSize)
} }
ThrowError("Out of memory!"); ThrowError("Out of memory!");
return NULL; return NULL;
#else
dassert(nSize != 0);
void* p = new char[nSize];
if (p)
{
return p;
}
for (CACHENODE *node = purgeHead.next; node != &purgeHead; node = node->next)
{
dassert(node->lockCount == 0);
dassert(node->ptr != NULL);
delete node->ptr;
node->ptr = NULL;
RemoveMRU(node);
p = new char[nSize];
if (p)
return p;
}
ThrowError("Out of memory!");
return NULL;
#endif
} }
void Resource::Free(void *p) void Resource::Free(void *p)
{ {
#ifdef USE_QHEAP
dassert(heap != NULL); dassert(heap != NULL);
dassert(p != NULL); dassert(p != NULL);
heap->Free(p); heap->Free(p);
#else
dassert(p != NULL);
delete p;
#endif
} }
DICTNODE *Resource::Lookup(const char *name, const char *type) DICTNODE *Resource::Lookup(const char *name, const char *type)
@ -615,12 +665,12 @@ void *Resource::Load(DICTNODE *h)
{ {
if (!h->lockCount) if (!h->lockCount)
{ {
RemoveMRU((CACHENODE*)h); RemoveMRU(h);
h->prev = purgeHead.prev; h->prev = purgeHead.prev;
purgeHead.prev->next = (CACHENODE*)h; purgeHead.prev->next = h;
h->next = &purgeHead; h->next = &purgeHead;
purgeHead.prev = (CACHENODE*)h; purgeHead.prev = h;
} }
} }
else else
@ -629,9 +679,9 @@ void *Resource::Load(DICTNODE *h)
Read(h); Read(h);
h->prev = purgeHead.prev; h->prev = purgeHead.prev;
purgeHead.prev->next = (CACHENODE*)h; purgeHead.prev->next = h;
h->next = &purgeHead; h->next = &purgeHead;
purgeHead.prev = (CACHENODE*)h; purgeHead.prev = h;
} }
return h->ptr; return h->ptr;
} }
@ -653,7 +703,7 @@ void *Resource::Lock(DICTNODE *h)
{ {
if (h->lockCount == 0) if (h->lockCount == 0)
{ {
RemoveMRU((CACHENODE*)h); RemoveMRU(h);
} }
} }
else else
@ -676,9 +726,9 @@ void Resource::Unlock(DICTNODE *h)
if (h->lockCount == 0) if (h->lockCount == 0)
{ {
h->prev = purgeHead.prev; h->prev = purgeHead.prev;
purgeHead.prev->next = (CACHENODE*)h; purgeHead.prev->next = h;
h->next = &purgeHead; h->next = &purgeHead;
purgeHead.prev = (CACHENODE*)h; purgeHead.prev = h;
} }
} }
} }
@ -720,6 +770,16 @@ void Resource::FNAddFiles(fnlist_t * fnlist, const char *pattern)
} }
} }
void Resource::PurgeCache(void)
{
#ifndef USE_QHEAP
for (CACHENODE *node = purgeHead.next; node != &purgeHead; node = node->next)
{
DICTNODE *pDict = (DICTNODE*)node;
}
#endif
}
void Resource::PrecacheSounds(void) void Resource::PrecacheSounds(void)
{ {
for (unsigned int i = 0; i < count; i++) for (unsigned int i = 0; i < count; i++)
@ -735,6 +795,22 @@ void Resource::PrecacheSounds(void)
void Resource::RemoveNode(DICTNODE* pNode) void Resource::RemoveNode(DICTNODE* pNode)
{ {
Flush(pNode);
if (pNode->name)
{
Free(pNode->name);
pNode->name = NULL;
}
if (pNode->type)
{
Free(pNode->type);
pNode->type = NULL;
}
*pNode = dict[--count]; *pNode = dict[--count];
if (pNode->ptr)
{
pNode->prev->next = pNode;
pNode->next->prev = pNode;
}
Reindex(); Reindex();
} }

View file

@ -67,12 +67,8 @@ struct CACHENODE
int lockCount; int lockCount;
}; };
struct DICTNODE struct DICTNODE : CACHENODE
{ {
void *ptr;
CACHENODE *prev;
CACHENODE *next;
int lockCount;
unsigned int offset; unsigned int offset;
unsigned int size; unsigned int size;
char flags; char flags;
@ -112,6 +108,7 @@ public:
int Size(DICTNODE*h) { return h->size; } int Size(DICTNODE*h) { return h->size; }
void FNAddFiles(fnlist_t *fnlist, const char *pattern); void FNAddFiles(fnlist_t *fnlist, const char *pattern);
void PrecacheSounds(void); void PrecacheSounds(void);
void PurgeCache(void);
void RemoveNode(DICTNODE* pNode); void RemoveNode(DICTNODE* pNode);
DICTNODE *dict; DICTNODE *dict;
@ -119,10 +116,11 @@ public:
DICTNODE **indexId; DICTNODE **indexId;
unsigned int buffSize; unsigned int buffSize;
unsigned int count; unsigned int count;
//FILE *handle;
int handle; int handle;
bool crypt; bool crypt;
#if USE_QHEAP
static QHeap *heap; static QHeap *heap;
#endif
static CACHENODE purgeHead; static CACHENODE purgeHead;
}; };