- rewrote Blood's map loader to use FileReader directly instead of implementing its own wrapper around the lump cache.

Also deleting a few other unused files.
This commit is contained in:
Christoph Oelckers 2020-07-25 18:48:26 +02:00
parent aea6467d00
commit dfda0c9cb2
9 changed files with 33 additions and 664 deletions

View file

@ -45,11 +45,9 @@ set( PCH_SOURCES
src/gib.cpp
src/globals.cpp
src/inifile.cpp
src/iob.cpp
src/levels.cpp
src/loadsave.cpp
src/map2d.cpp
src/menu.cpp
src/messages.cpp
src/mirrors.cpp
src/misc.cpp
@ -58,7 +56,6 @@ set( PCH_SOURCES
src/osdcmd.cpp
src/player.cpp
src/qav.cpp
src/qheap.cpp
src/replace.cpp
src/resource.cpp
src/screen.cpp

View file

@ -54,7 +54,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "osdcmds.h"
#include "replace.h"
#include "resource.h"
#include "qheap.h"
#include "screen.h"
#include "sectorfx.h"
#include "seq.h"

View file

@ -26,13 +26,13 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "build.h"
#include "compat.h"
#include "common_game.h"
#include "zstring.h"
#include "m_crc32.h"
#include "md4.h"
//#include "actor.h"
#include "globals.h"
#include "db.h"
#include "iob.h"
#include "eventq.h"
#include "nnexts.h"
@ -586,47 +586,36 @@ unsigned int dbReadMapCRC(const char *pPath)
byte_1A76C7 = 0;
byte_1A76C8 = 0;
DICTNODE* pNode;
pNode = gSysRes.Lookup(pPath, "MAP");
if (!pNode)
{
char name2[BMAX_PATH];
Bstrncpy(name2, pPath, BMAX_PATH);
ChangeExtension(name2, "");
pNode = gSysRes.Lookup(name2, "MAP");
}
FString mapname = pPath;
DefaultExtension(mapname, ".map");
auto fr = fileSystem.OpenFileReader(mapname);
if (!pNode)
if (!fr.isOpen())
{
Printf("Error opening map file %s", pPath);
return -1;
}
char *pData = (char*)gSysRes.Lock(pNode);
int nSize = pNode->Size();
MAPSIGNATURE header;
IOBuffer(nSize, pData).Read(&header, 6);
#if B_BIG_ENDIAN == 1
header.version = B_LITTLE16(header.version);
#endif
fr.Read(&header, 6);
if (memcmp(header.signature, "BLM\x1a", 4))
{
ThrowError("Map file corrupted");
I_Error("%d: Map file corrupted.");
}
if ((header.version & 0xff00) == 0x600)
int ver = LittleShort(header.version);
if ((ver & 0xff00) == 0x600)
{
}
else if ((header.version & 0xff00) == 0x700)
else if ((ver & 0xff00) == 0x700)
{
byte_1A76C8 = 1;
}
else
{
ThrowError("Map file is wrong version");
I_Error("%s: Map file is wrong version.");
}
unsigned int nCRC = *(unsigned int*)(pData+nSize-4);
gSysRes.Unlock(pNode);
return nCRC;
fr.Seek(-4, FileReader::SeekEnd);
return fr.ReadInt32();
}
int gMapRev, gSongId, gSkyCount;
@ -648,38 +637,24 @@ int dbLoadMap(const char *pPath, int *pX, int *pY, int *pZ, short *pAngle, short
Polymost_prepare_loadboard();
#endif
DICTNODE* pNode;
FString mapname = pPath;
DefaultExtension(mapname, ".map");
auto fr = fileSystem.OpenFileReader(mapname);
pNode = gSysRes.Lookup(pPath, "MAP");
if (!pNode)
{
char name2[BMAX_PATH];
Bstrncpy(name2, pPath, BMAX_PATH);
ChangeExtension(name2, "");
pNode = gSysRes.Lookup(name2, "MAP");
}
if (!pNode)
if (!fr.isOpen())
{
Printf("Error opening map file %s", pPath);
return -1;
}
char *pData = (char*)gSysRes.Lock(pNode);
int nSize = pNode->Size();
MAPSIGNATURE header;
IOBuffer IOBuffer1 = IOBuffer(nSize, pData);
IOBuffer1.Read(&header, 6);
#if B_BIG_ENDIAN == 1
header.version = B_LITTLE16(header.version);
#endif
fr.Read(&header, 6);
if (memcmp(header.signature, "BLM\x1a", 4))
{
Printf("Map file corrupted");
gSysRes.Unlock(pNode);
return -1;
}
byte_1A76C8 = 0;
if ((header.version & 0xff00) == 0x700) {
if ((LittleShort(header.version) & 0xff00) == 0x700) {
byte_1A76C8 = 1;
#ifdef NOONE_EXTENSIONS
@ -691,12 +666,11 @@ int dbLoadMap(const char *pPath, int *pX, int *pY, int *pZ, short *pAngle, short
} else {
Printf("Map file is wrong version");
gSysRes.Unlock(pNode);
return -1;
}
MAPHEADER mapHeader;
IOBuffer1.Read(&mapHeader,37/* sizeof(mapHeader)*/);
fr.Read(&mapHeader,37/* sizeof(mapHeader)*/);
if (mapHeader.at16 != 0 && mapHeader.at16 != 0x7474614d && mapHeader.at16 != 0x4d617474) {
dbCrypt((char*)&mapHeader, sizeof(mapHeader), 0x7474614d);
byte_1A76C7 = 1;
@ -737,14 +711,12 @@ int dbLoadMap(const char *pPath, int *pX, int *pY, int *pZ, short *pAngle, short
else
{
Printf("Corrupted Map file");
gSysRes.Unlock(pNode);
return -1;
}
}
else if (mapHeader.at16)
{
Printf("Corrupted Map file");
gSysRes.Unlock(pNode);
return -1;
}
parallaxtype = mapHeader.at1a;
@ -754,7 +726,7 @@ int dbLoadMap(const char *pPath, int *pX, int *pY, int *pZ, short *pAngle, short
dbInit();
if (byte_1A76C8)
{
IOBuffer1.Read(&byte_19AE44, 128);
fr.Read(&byte_19AE44, 128);
dbCrypt((char*)&byte_19AE44, 128, numwalls);
#if B_BIG_ENDIAN == 1
byte_19AE44.at40 = B_LITTLE32(byte_19AE44.at40);
@ -767,7 +739,7 @@ int dbLoadMap(const char *pPath, int *pX, int *pY, int *pZ, short *pAngle, short
memset(&byte_19AE44, 0, 128);
}
gSkyCount = 1<< mapHeader.at10;
IOBuffer1.Read(tpskyoff, gSkyCount*sizeof(tpskyoff[0]));
fr.Read(tpskyoff, gSkyCount*sizeof(tpskyoff[0]));
if (byte_1A76C8)
{
dbCrypt((char*)tpskyoff, gSkyCount*sizeof(tpskyoff[0]), gSkyCount*2);
@ -784,7 +756,7 @@ int dbLoadMap(const char *pPath, int *pX, int *pY, int *pZ, short *pAngle, short
for (int i = 0; i < numsectors; i++)
{
sectortype *pSector = &sector[i];
IOBuffer1.Read(pSector, sizeof(sectortype));
fr.Read(pSector, sizeof(sectortype));
if (byte_1A76C8)
{
dbCrypt((char*)pSector, sizeof(sectortype), gMapRev*sizeof(sectortype));
@ -822,7 +794,7 @@ int dbLoadMap(const char *pPath, int *pX, int *pY, int *pZ, short *pAngle, short
nCount = byte_19AE44.at48;
}
dassert(nCount <= nXSectorSize);
IOBuffer1.Read(pBuffer, nCount);
fr.Read(pBuffer, nCount);
BitReader bitReader(pBuffer, nCount);
pXSector->reference = bitReader.readSigned(14);
pXSector->state = bitReader.readUnsigned(1);
@ -909,7 +881,7 @@ int dbLoadMap(const char *pPath, int *pX, int *pY, int *pZ, short *pAngle, short
for (int i = 0; i < numwalls; i++)
{
walltype *pWall = &wall[i];
IOBuffer1.Read(pWall, sizeof(walltype));
fr.Read(pWall, sizeof(walltype));
if (byte_1A76C8)
{
dbCrypt((char*)pWall, sizeof(walltype), (gMapRev*sizeof(sectortype)) | 0x7474614d);
@ -943,7 +915,7 @@ int dbLoadMap(const char *pPath, int *pX, int *pY, int *pZ, short *pAngle, short
nCount = byte_19AE44.at44;
}
dassert(nCount <= nXWallSize);
IOBuffer1.Read(pBuffer, nCount);
fr.Read(pBuffer, nCount);
BitReader bitReader(pBuffer, nCount);
pXWall->reference = bitReader.readSigned(14);
pXWall->state = bitReader.readUnsigned(1);
@ -986,7 +958,7 @@ int dbLoadMap(const char *pPath, int *pX, int *pY, int *pZ, short *pAngle, short
{
RemoveSpriteStat(i);
spritetype *pSprite = &sprite[i];
IOBuffer1.Read(pSprite, sizeof(spritetype));
fr.Read(pSprite, sizeof(spritetype));
if (byte_1A76C8)
{
dbCrypt((char*)pSprite, sizeof(spritetype), (gMapRev*sizeof(spritetype)) | 0x7474614d);
@ -1030,7 +1002,7 @@ int dbLoadMap(const char *pPath, int *pX, int *pY, int *pZ, short *pAngle, short
nCount = byte_19AE44.at40;
}
dassert(nCount <= nXSpriteSize);
IOBuffer1.Read(pBuffer, nCount);
fr.Read(pBuffer, nCount);
BitReader bitReader(pBuffer, nCount);
pXSprite->reference = bitReader.readSigned(14);
pXSprite->state = bitReader.readUnsigned(1);
@ -1112,20 +1084,20 @@ int dbLoadMap(const char *pPath, int *pX, int *pY, int *pZ, short *pAngle, short
}
}
unsigned int nCRC;
IOBuffer1.Read(&nCRC, 4);
fr.Read(&nCRC, 4);
#if B_BIG_ENDIAN == 1
nCRC = B_LITTLE32(nCRC);
#endif
md4once((unsigned char*)pData, nSize, g_loadedMapHack.md4);
if (Bcrc32(pData, nSize-4, 0) != nCRC)
fr.Seek(0, FileReader::SeekSet);
auto buffer = fr.Read();
md4once(buffer.Data(), buffer.Size(), g_loadedMapHack.md4);
if (CalcCRC32(buffer.Data(), buffer.Size() -4) != nCRC)
{
Printf("Map File does not match CRC");
gSysRes.Unlock(pNode);
return -1;
}
if (pCRC)
*pCRC = nCRC;
gSysRes.Unlock(pNode);
PropagateMarkerReferences();
if (byte_1A76C8)
{
@ -1140,14 +1112,12 @@ int dbLoadMap(const char *pPath, int *pX, int *pY, int *pZ, short *pAngle, short
else
{
Printf("Corrupted Map file");
gSysRes.Unlock(pNode);
return -1;
}
}
else if (gSongId != 0)
{
Printf("Corrupted Map file");
gSysRes.Unlock(pNode);
return -1;
}

View file

@ -1,80 +0,0 @@
//-------------------------------------------------------------------------
/*
Copyright (C) 2010-2019 EDuke32 developers and contributors
Copyright (C) 2019 Nuke.YKT
This file is part of NBlood.
NBlood is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License version 2
as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
//-------------------------------------------------------------------------
#include "ns.h" // Must come before everything else!
#include <stdlib.h>
#include <string.h>
#include "compat.h"
#include "common_game.h"
#include "iob.h"
BEGIN_BLD_NS
IOBuffer::IOBuffer(int _nRemain, char *_pBuffer)
{
nRemain = _nRemain;
pBuffer =_pBuffer;
}
void IOBuffer::Read(void *pData, int nSize)
{
if (nSize <= nRemain)
{
memcpy(pData, pBuffer, nSize);
nRemain -= nSize;
pBuffer += nSize;
}
else
{
ThrowError("Read buffer overflow");
}
}
void IOBuffer::Write(void *pData, int nSize)
{
if (nSize <= nRemain)
{
memcpy(pBuffer, pData, nSize);
nRemain -= nSize;
pBuffer += nSize;
}
else
{
ThrowError("Write buffer overflow");
}
}
void IOBuffer::Skip(int nSize)
{
if (nSize <= nRemain)
{
nRemain -= nSize;
pBuffer += nSize;
}
else
{
ThrowError("Skip overflow");
}
}
END_BLD_NS

View file

@ -1,38 +0,0 @@
//-------------------------------------------------------------------------
/*
Copyright (C) 2010-2019 EDuke32 developers and contributors
Copyright (C) 2019 Nuke.YKT
This file is part of NBlood.
NBlood is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License version 2
as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
//-------------------------------------------------------------------------
#pragma once
BEGIN_BLD_NS
class IOBuffer
{
public:
IOBuffer(int _nRemain, char *pBuffer);
int nRemain;
char *pBuffer;
void Read(void *, int);
void Write(void *, int);
void Skip(int);
};
END_BLD_NS

View file

@ -1,201 +0,0 @@
//-------------------------------------------------------------------------
/*
Copyright (C) 2010-2019 EDuke32 developers and contributors
Copyright (C) 2019 Nuke.YKT
This file is part of NBlood.
NBlood is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License version 2
as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
//-------------------------------------------------------------------------
#if 0
// Not yet implemented content kept for reference. Mostly multiplayer related.
const char *zMonsterStrings[] =
{
"None",
"Bring 'em on",
"Respawn",
};
const char *zWeaponStrings[] =
{
"Do not Respawn",
"Are Permanent",
"Respawn",
"Respawn with Markers",
};
const char *zItemStrings[] =
{
"Do not Respawn",
"Respawn",
"Respawn with Markers",
};
const char *zRespawnStrings[] =
{
"At Random Locations",
"Close to Weapons",
"Away from Enemies",
};
const char *pzShowWeaponStrings[] = {
"OFF",
"SPRITE",
"VOXEL"
};
CGameMenuItemTitle itemMessagesTitle("MESSAGES", 1, 160, 20, 2038);
CGameMenuItemZBool boolMessages("MESSAGES:", 3, 66, 70, 180, 0, SetMessages, NULL, NULL);
CGameMenuItemSlider sliderMsgCount("MESSAGE COUNT:", 3, 66, 80, 180, gMessageCount, 1, 16, 1, NULL, -1, -1);
CGameMenuItemSlider sliderMsgTime("MESSAGE TIME:", 3, 66, 90, 180, gMessageTime, 1, 8, 1, NULL, -1, -1);
CGameMenuItemTitle itemOptionsGameTitle("GAME SETUP", 1, 160, 20, 2038);
CGameMenuItemZCycle itemOptionsGameShowWeapons("SHOW WEAPONS:", 3, 66, 70, 180, 0, SetShowWeapons, pzShowWeaponStrings, ARRAY_SSIZE(pzShowWeaponStrings), 0);
CGameMenuItemZBool itemOptionsGameBoolSlopeTilting("SLOPE TILTING:", 3, 66, 80, 180, cl_slopetilting, SetSlopeTilting, NULL, NULL);
CGameMenuItemZBool itemOptionsGameBoolViewBobbing("VIEW BOBBING:", 3, 66, 90, 180, cl_viewvbob, SetViewBobbing, NULL, NULL);
CGameMenuItemZBool itemOptionsGameBoolViewSwaying("VIEW SWAYING:", 3, 66, 100, 180, cl_viewhbob, SetViewSwaying, NULL, NULL);
CGameMenuItemZBool itemOptionsDisplayBoolCenterHoriz("CENTER HORIZON LINE:", 3, 66, 90, 180, r_horizcenter, SetCenterHoriz, NULL, NULL);
CGameMenuItemZBool itemOptionsDisplayBoolPowerupDuration("POWERUP DURATION:", 3, 66, 110, 180, hud_powerupduration, SetPowerupDuration, NULL, NULL);
CGameMenuItemZBool itemOptionsDisplayBoolShowMapTitle("MAP TITLE:", 3, 66, 120, 180, hud_showmapname, SetShowMapTitle, NULL, NULL);
CGameMenuItemTitle itemNetworkHostTitle("HOST A GAME", 1, 160, 20, 2038);
CGameMenuItemSlider itemNetworkHostPlayerNum("PLAYER NUMBER:", 3, 66, 70, 180, 1, 2, kMaxPlayers, 1, NULL, -1, -1, kMenuSliderValue);
CGameMenuItemZEdit itemNetworkHostPort("NETWORK PORT:", 3, 66, 80, 180, zNetPortBuffer, 6, 0, NULL, 0);
CGameMenuItemChain itemNetworkHostHost("HOST A GAME", 3, 66, 100, 180, 1, NULL, -1, NetworkHostGame, 0);
CGameMenuItemTitle itemNetworkJoinTitle("JOIN A GAME", 1, 160, 20, 2038);
CGameMenuItemZEdit itemNetworkJoinAddress("NETWORK ADDRESS:", 3, 66, 70, 180, zNetAddressBuffer, 16, 0, NULL, 0);
CGameMenuItemZEdit itemNetworkJoinPort("NETWORK PORT:", 3, 66, 80, 180, zNetPortBuffer, 6, 0, NULL, 0);
CGameMenuItemChain itemNetworkJoinJoin("JOIN A GAME", 3, 66, 100, 180, 1, NULL, -1, NetworkJoinGame, 0);
////
void SetWeaponsV10X(CGameMenuItemZBool* pItem)
{
if (gGameOptions.nGameType == 0) {
gWeaponsV10x = pItem->at20;
gGameOptions.weaponsV10x = pItem->at20;
}
}
////
void SetTurnSpeed(CGameMenuItemSlider *pItem)
{
gTurnSpeed = pItem->nValue;
}
void SetAutoAim(CGameMenuItemZCycle *pItem)
{
cl_autoaim = pItem->m_nFocus;
if (!gDemo.at0 && !gDemo.at1)
{
gProfile[myconnectindex].nAutoAim = cl_autoaim;
netBroadcastPlayerInfo(myconnectindex);
}
}
void SetupNetworkMenu(void)
{
sprintf(zNetPortBuffer, "%d", gNetPort);
if (strlen(gNetAddress) > 0)
strncpy(zNetAddressBuffer, gNetAddress, sizeof(zNetAddressBuffer)-1);
menuNetwork.Add(&itemNetworkTitle, false);
menuNetwork.Add(&itemNetworkHost, true);
menuNetwork.Add(&itemNetworkJoin, false);
menuNetwork.Add(&itemBloodQAV, false);
menuNetworkHost.Add(&itemNetworkHostTitle, false);
menuNetworkHost.Add(&itemNetworkHostPlayerNum, true);
menuNetworkHost.Add(&itemNetworkHostPort, false);
menuNetworkHost.Add(&itemNetworkHostHost, false);
menuNetworkHost.Add(&itemBloodQAV, false);
menuNetworkJoin.Add(&itemNetworkJoinTitle, false);
menuNetworkJoin.Add(&itemNetworkJoinAddress, true);
menuNetworkJoin.Add(&itemNetworkJoinPort, false);
menuNetworkJoin.Add(&itemNetworkJoinJoin, false);
menuNetworkJoin.Add(&itemBloodQAV, false);
}
void SetupNetworkHostMenu(CGameMenuItemChain *pItem)
{
UNREFERENCED_PARAMETER(pItem);
}
void SetupNetworkJoinMenu(CGameMenuItemChain *pItem)
{
UNREFERENCED_PARAMETER(pItem);
}
void NetworkHostGame(CGameMenuItemChain *pItem)
{
UNREFERENCED_PARAMETER(pItem);
Mus_Stop();
FX_StopAllSounds_();
UpdateDacs(0, true);
gNetPlayers = itemNetworkHostPlayerNum.nValue;
gNetPort = strtoul(zNetPortBuffer, NULL, 10);
if (!gNetPort)
gNetPort = kNetDefaultPort;
gNetMode = NETWORK_SERVER;
netInitialize(false);
gGameMenuMgr.Deactivate();
gQuitGame = gRestartGame = true;
}
void NetworkJoinGame(CGameMenuItemChain *pItem)
{
UNREFERENCED_PARAMETER(pItem);
Mus_Stop();
FX_StopAllSounds_();
UpdateDacs(0, true);
strcpy(gNetAddress, zNetAddressBuffer);
gNetPort = strtoul(zNetPortBuffer, NULL, 10);
if (!gNetPort)
gNetPort = kNetDefaultPort;
gNetMode = NETWORK_CLIENT;
netInitialize(false);
gGameMenuMgr.Deactivate();
gQuitGame = gRestartGame = true;
}
void Restart(CGameMenuItemChain *pItem)
{
UNREFERENCED_PARAMETER(pItem);
if (gGameOptions.nGameType == 0 || numplayers == 1)
{
gQuitGame = true;
gRestartGame = true;
}
else
gQuitRequest = 2;
gGameMenuMgr.Deactivate();
}
#endif

View file

@ -1,223 +0,0 @@
//-------------------------------------------------------------------------
/*
Copyright (C) 2010-2019 EDuke32 developers and contributors
Copyright (C) 2019 Nuke.YKT
This file is part of NBlood.
NBlood is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License version 2
as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
//-------------------------------------------------------------------------
#include "ns.h" // Must come before everything else!
#ifdef USE_QHEAP
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include "common_game.h"
#include "qheap.h"
void InstallFenceposts(HEAPNODE *n)
{
char *address = (char*)n;
memset(address + 0x20, 0xcc, 0x10);
memset(address + n->size - 0x10, 0xcc, 0x10);
}
void CheckFenceposts(HEAPNODE *n)
{
char *data = (char*)n + 0x20;
for (int i = 0; i < 0x10; i++)
{
if (data[i] != 0xcc)
{
ThrowError("Block underwritten");
}
}
data = (char*)n + n->size - 0x10;
for (int i = 0; i < 0x10; i++)
{
if (data[i] != 0xcc)
{
ThrowError("Block overwritten");
}
}
}
QHeap::QHeap(int heapSize)
{
dassert(heapSize > 0);
size = heapSize;
while (size > 0 && (heapPtr = malloc(size)) == NULL)
{
size -= 0x1000;
}
if (!heapPtr)
{
ThrowError("Allocation failure\n");
}
heap.isFree = false;
freeHeap.isFree = false;
HEAPNODE *node = (HEAPNODE*)(((intptr_t)heapPtr + 0xf) & ~0xf);
heap.next = heap.prev = node;
node->next = node->prev = &heap;
freeHeap.freeNext = freeHeap.freePrev = node;
node->freeNext = node->freePrev = &freeHeap;
node->isFree = true;
node->size = size & ~0xf;
}
QHeap::~QHeap(void)
{
Check();
free(heapPtr);
heapPtr = NULL;
}
void QHeap::Check(void)
{
HEAPNODE *node = heap.next;
while (node != &heap)
{
if (!node->isFree)
{
CheckFenceposts(node);
}
node = node->next;
}
}
void QHeap::Debug(void)
{
#if 0
char s[4];
FILE *f = fopen("MEMFRAG.TXT", "wt");
if (!f)
{
return;
}
HEAPNODE *node = heap.next;
while (node != &heap)
{
if (node->isFree)
{
fprintf(f, "%P %10d FREE", node, node->size);
}
else
{
char *data = (char*)node + 0x20;
for (int i = 0; i < 4; i++)
{
if (isalpha(data[i]))
{
s[i] = data[i];
}
else
{
s[i] = '_';
}
}
fprintf(f, "%P %10d %4s", node, node->size, s);
}
}
fclose(f);
#endif
}
void *QHeap::Alloc(int blockSize)
{
dassert(blockSize > 0);
dassert(heapPtr != NULL);
if (blockSize > 0)
{
blockSize = ((blockSize + 0xf) & ~0xf) + 0x40;
HEAPNODE *freeNode = freeHeap.freeNext;
while (freeNode != &freeHeap)
{
dassert(freeNode->isFree);
if (blockSize <= freeNode->size)
{
if (blockSize + 0x30 <= freeNode->size)
{
freeNode->size -= blockSize;
HEAPNODE *nextNode = (HEAPNODE *)((char*)freeNode + freeNode->size);
nextNode->size = blockSize;
nextNode->prev = freeNode;
nextNode->next = freeNode->next;
nextNode->prev->next = nextNode;
nextNode->next->prev = nextNode;
nextNode->isFree = false;
InstallFenceposts(nextNode);
return (void*)((char*)nextNode + 0x30);
}
else
{
freeNode->freePrev->freeNext = freeNode->freeNext;
freeNode->freeNext->freePrev = freeNode->freePrev;
freeNode->isFree = false;
InstallFenceposts(freeNode);
return (void*)((char*)freeNode + 0x30);
}
}
freeNode = freeNode->freeNext;
}
}
return NULL;
}
int QHeap::Free(void *p)
{
if (!p)
{
return 0;
}
dassert(heapPtr != NULL);
HEAPNODE *node = (HEAPNODE*)((char*)p - 0x30);
if (node->isFree)
{
ThrowError("Free on bad or freed block");
}
CheckFenceposts(node);
if (node->prev->isFree)
{
node->prev->size += node->size;
node->prev->next = node->next;
node->next->prev = node->prev;
node = node->prev;
}
else
{
node->freeNext = freeHeap.freeNext;
node->freePrev = &freeHeap;
node->freePrev->freeNext = node;
node->freeNext->freePrev = node;
node->isFree = true;
}
HEAPNODE *nextNode = node->next;
if (nextNode->isFree)
{
node->size += nextNode->size;
nextNode->freePrev->freeNext = nextNode->freeNext;
nextNode->freeNext->freePrev = nextNode->freePrev;
nextNode->prev->next = nextNode->next;
nextNode->next->prev = nextNode->prev;
}
return node->size - 0x40;
}
#endif

View file

@ -1,54 +0,0 @@
//-------------------------------------------------------------------------
/*
Copyright (C) 2010-2019 EDuke32 developers and contributors
Copyright (C) 2019 Nuke.YKT
This file is part of NBlood.
NBlood is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License version 2
as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
//-------------------------------------------------------------------------
#pragma once
#ifdef USE_QHEAP
struct HEAPNODE
{
HEAPNODE *prev;
HEAPNODE *next;
int size;
bool isFree;
HEAPNODE *freePrev;
HEAPNODE *freeNext;
};
class QHeap
{
public:
QHeap(int heapSize);
~QHeap(void);
void Check(void);
void Debug(void);
void *Alloc(int);
int Free(void *p);
void *heapPtr;
HEAPNODE heap;
HEAPNODE freeHeap;
int size;
};
#endif

View file

@ -31,7 +31,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "common_game.h"
#include "misc.h"
#include "qheap.h"
#include "resource.h"
#if B_BIG_ENDIAN == 1