start using CMemoryHeap

This commit is contained in:
aap
2020-11-26 16:47:19 +01:00
parent 4ddc356341
commit d857758c16
22 changed files with 652 additions and 238 deletions

View File

@ -44,7 +44,7 @@ CMemoryHeap::Init(uint32 total)
m_end = (HeapBlockDesc*)(mem + total - sizeof(HeapBlockDesc));
m_start->m_memId = MEMID_FREE;
m_start->m_size = total - 2*sizeof(HeapBlockDesc);
m_end->m_memId = MEMID_ID1;
m_end->m_memId = MEMID_GAME;
m_end->m_size = 0;
m_freeList.m_last.m_size = INT_MAX;
@ -65,7 +65,7 @@ CMemoryHeap::Init(uint32 total)
RegisterMalloc(GetDescFromHeapPointer(m_memUsed));
RegisterMalloc(GetDescFromHeapPointer(m_blocksUsed));
m_currentMemID = MEMID_ID1;
m_currentMemID = MEMID_GAME;
for(int i = 0; i < NUM_MEMIDS; i++){
m_memUsed[i] = 0;
m_blocksUsed[i] = 0;
@ -90,8 +90,8 @@ CMemoryHeap::RegisterFree(HeapBlockDesc *block)
if(block->m_memId == MEMID_FREE)
return;
m_totalMemUsed -= block->m_size + sizeof(HeapBlockDesc);
m_memUsed[m_currentMemID] -= block->m_size + sizeof(HeapBlockDesc);
m_blocksUsed[m_currentMemID]--;
m_memUsed[block->m_memId] -= block->m_size + sizeof(HeapBlockDesc);
m_blocksUsed[block->m_memId]--;
m_totalBlocksUsed--;
}
@ -433,13 +433,16 @@ CMemoryHeap::GetBlocksUsed(int32 id)
void
CMemoryHeap::PopMemId(void)
{
assert(m_idStack.sp > 0);
m_currentMemID = m_idStack.pop();
assert(m_currentMemID != MEMID_FREE);
}
void
CMemoryHeap::PushMemId(int32 id)
{
MEMORYHEAP_ASSERT(id != MEMID_FREE);
assert(m_idStack.sp < 16);
m_idStack.push(m_currentMemID);
m_currentMemID = id;
}
@ -457,7 +460,7 @@ CMemoryHeap::ParseHeap(void)
for(HeapBlockDesc *block = m_start; block < m_end; block = block->GetNextConsecutive()){
char chr = '*'; // free
if(block->m_memId != MEMID_FREE)
chr = block->m_memId-MEMID_ID1 + 'A';
chr = block->m_memId-1 + 'A';
int numQW = block->m_size>>4;
if((addrQW & 0x3F) == 0){
@ -506,10 +509,31 @@ InitMemoryMgr(void)
#endif
}
RwMemoryFunctions memFuncs = {
MemoryMgrMalloc,
MemoryMgrFree,
MemoryMgrRealloc,
MemoryMgrCalloc
};
#ifdef USE_CUSTOM_ALLOCATOR
// game seems to be using heap directly here, but this is nicer
void *operator new(size_t sz) { return MemoryMgrMalloc(sz); }
void *operator new[](size_t sz) { return MemoryMgrMalloc(sz); }
void operator delete(void *ptr) noexcept { MemoryMgrFree(ptr); }
void operator delete[](void *ptr) noexcept { MemoryMgrFree(ptr); }
#endif
#endif
void*
MemoryMgrMalloc(uint32 size)
{
#ifdef USE_CUSTOM_ALLOCATOR
void *mem = gMainHeap.Malloc(size);
#else
void *mem = malloc(size);
#endif
if(mem > pMemoryTop)
pMemoryTop = mem;
return mem;
@ -518,7 +542,11 @@ MemoryMgrMalloc(uint32 size)
void*
MemoryMgrRealloc(void *ptr, uint32 size)
{
#ifdef USE_CUSTOM_ALLOCATOR
void *mem = gMainHeap.Realloc(ptr, size);
#else
void *mem = realloc(ptr, size);
#endif
if(mem > pMemoryTop)
pMemoryTop = mem;
return mem;
@ -527,7 +555,11 @@ MemoryMgrRealloc(void *ptr, uint32 size)
void*
MemoryMgrCalloc(uint32 num, uint32 size)
{
#ifdef USE_CUSTOM_ALLOCATOR
void *mem = gMainHeap.Malloc(num*size);
#else
void *mem = calloc(num, size);
#endif
if(mem > pMemoryTop)
pMemoryTop = mem;
#ifdef FIX_BUGS
@ -539,18 +571,52 @@ MemoryMgrCalloc(uint32 num, uint32 size)
void
MemoryMgrFree(void *ptr)
{
#ifdef USE_CUSTOM_ALLOCATOR
#ifdef FIX_BUGS
// i don't suppose this is handled by RW?
if(ptr == nil) return;
#endif
gMainHeap.Free(ptr);
#else
free(ptr);
#endif
}
RwMemoryFunctions memFuncs = {
MemoryMgrMalloc,
MemoryMgrFree,
MemoryMgrRealloc,
MemoryMgrCalloc
};
void *
RwMallocAlign(RwUInt32 size, RwUInt32 align)
{
#ifdef FIX_BUGS
uintptr ptralign = align-1;
void *mem = (void *)MemoryMgrMalloc(size + sizeof(uintptr) + ptralign);
ASSERT(mem != nil);
void *addr = (void *)((((uintptr)mem) + sizeof(uintptr) + ptralign) & ~ptralign);
ASSERT(addr != nil);
#else
void *mem = (void *)MemoryMgrMalloc(size + align);
ASSERT(mem != nil);
void *addr = (void *)((((uintptr)mem) + align) & ~(align - 1));
ASSERT(addr != nil);
#endif
*(((void **)addr) - 1) = mem;
return addr;
}
void
RwFreeAlign(void *mem)
{
ASSERT(mem != nil);
void *addr = *(((void **)mem) - 1);
ASSERT(addr != nil);
MemoryMgrFree(addr);
}

View File

@ -5,9 +5,75 @@
#undef MoveMemory
#endif
#ifdef USE_CUSTOM_ALLOCATOR
#define PUSH_MEMID(id) gMainHeap.PushMemId(id)
#define POP_MEMID() gMainHeap.PopMemId()
#define REGISTER_MEMPTR(ptr) gMainHeap.RegisterMemPointer(ptr)
#else
#define PUSH_MEMID(id)
#define POP_MEMID()
#define REGISTER_MEMPTR(ptr)
#endif
enum {
MEMID_FREE,
// IDs from LCS:
/*
MEMID_GAME = 1, // "Game"
MEMID_WORLD = 2, // "World"
MEMID_ANIMATION = 3, // "Animation"
MEMID_POOLS = 4, // "Pools"
MEMID_DEF_MODELS = 5, // "Default Models"
MEMID_STREAM = 6, // "Streaming"
MEMID_STREAM_MODELS = 7, // "Streamed Models"
MEMID_STREAM_LODS = 8, // "Streamed LODs"
MEMID_STREAM_TEXUTRES = 9, // "Streamed Textures"
MEMID_STREAM_COLLISION = 10, // "Streamed Collision"
MEMID_STREAM_ANIMATION = 11, // "Streamed Animation"
MEMID_TEXTURES = 12, // "Textures"
MEMID_COLLISION = 13, // "Collision"
MEMID_PRE_ALLOC = 14, // "PreAlloc"
MEMID_GAME_PROCESS = 15, // "Game Process"
MEMID_SCRIPT = 16, // "Script"
MEMID_CARS = 17, // "Cars"
MEMID_RENDER = 18, // "Render"
MEMID_PED_ATTR = 19, // "Ped Attr"
*/
// III:
MEMID_GAME = 1, // "Game"
MEMID_WORLD = 2, // "World"
MEMID_ANIMATION = 3, // "Animation"
MEMID_POOLS = 4, // "Pools"
MEMID_DEF_MODELS = 5, // "Default Models"
MEMID_STREAM = 6, // "Streaming"
MEMID_STREAM_MODELS = 7, // "Streamed Models" (instance)
MEMID_STREAM_TEXUTRES = 8, // "Streamed Textures"
MEMID_TEXTURES = 9, // "Textures"
MEMID_COLLISION = 10, // "Collision"
MEMID_RENDERLIST = 11, // ?
MEMID_GAME_PROCESS = 12, // "Game Process"
MEMID_SCRIPT = 13, // "Script"
MEMID_CARS = 14, // "Cars"
MEMID_RENDER = 15, // "Render"
MEMID_FRONTEND = 17, // ?
NUM_MEMIDS,
NUM_FIXED_MEMBLOCKS = 6
};
extern RwMemoryFunctions memFuncs;
void InitMemoryMgr(void);
void *MemoryMgrMalloc(uint32 size);
void *MemoryMgrRealloc(void *ptr, uint32 size);
void *MemoryMgrCalloc(uint32 num, uint32 size);
void MemoryMgrFree(void *ptr);
void *RwMallocAlign(RwUInt32 size, RwUInt32 align);
void RwFreeAlign(void *mem);
template<typename T, uint32 N>
class CStack
{
@ -17,7 +83,7 @@ public:
CStack() : sp(0) {}
void push(const T& val) { values[sp++] = val; }
T& pop() { return values[sp--]; }
T& pop() { return values[--sp]; }
};
@ -111,34 +177,6 @@ struct CommonSize
}
};
enum {
MEMID_FREE,
// IDs from LCS:
MEMID_ID1, // "Game"
MEMID_ID2, // "World"
MEMID_ID3, // "Animation"
MEMID_ID4, // "Pools"
MEMID_ID5, // "Default Models"
MEMID_ID6, // "Streaming"
MEMID_ID7, // "Streamed Models"
MEMID_ID8, // "Streamed LODs"
MEMID_ID9, // "Streamed Textures"
MEMID_ID10, // "Streamed Collision"
MEMID_ID11, // "Streamed Animation"
MEMID_ID12, // "Textures"
MEMID_ID13, // "Collision"
MEMID_ID14, // "PreAlloc"
MEMID_ID15, // "Game Process"
MEMID_ID16, // "Script"
MEMID_ID17, // "Cars"
MEMID_ID18, // "Render"
MEMID_ID19, // "Ped Attr"
NUM_MEMIDS,
NUM_FIXED_MEMBLOCKS = 6
};
class CMemoryHeap
{
public:
@ -194,3 +232,5 @@ public:
block->InsertHeapFreeBlock(b->m_prev);
}
};
extern CMemoryHeap gMainHeap;

View File

@ -64,45 +64,6 @@ void FlushObrsPrintfs()
#endif
}
void *
RwMallocAlign(RwUInt32 size, RwUInt32 align)
{
#ifdef FIX_BUGS
uintptr ptralign = align-1;
void *mem = (void *)malloc(size + sizeof(uintptr) + ptralign);
ASSERT(mem != nil);
void *addr = (void *)((((uintptr)mem) + sizeof(uintptr) + ptralign) & ~ptralign);
ASSERT(addr != nil);
#else
void *mem = (void *)malloc(size + align);
ASSERT(mem != nil);
void *addr = (void *)((((uintptr)mem) + align) & ~(align - 1));
ASSERT(addr != nil);
#endif
*(((void **)addr) - 1) = mem;
return addr;
}
void
RwFreeAlign(void *mem)
{
ASSERT(mem != nil);
void *addr = *(((void **)mem) - 1);
ASSERT(addr != nil);
free(addr);
}
void
DefinedState(void)
{

View File

@ -2,9 +2,6 @@
extern bool gPS2alphaTest;
void *RwMallocAlign(RwUInt32 size, RwUInt32 align);
void RwFreeAlign(void *mem);
void OpenCharsetSafe();
void CreateDebugFont();
void DestroyDebugFont();

View File

@ -10,6 +10,7 @@
#include "VisibilityPlugins.h"
#include "World.h"
#include "custompipes.h"
#include "MemoryHeap.h"
CLinkList<CVisibilityPlugins::AlphaObjectInfo> CVisibilityPlugins::m_alphaList;
CLinkList<CVisibilityPlugins::AlphaObjectInfo> CVisibilityPlugins::m_alphaEntityList;
@ -30,6 +31,41 @@ float CVisibilityPlugins::ms_pedLod0Dist;
float CVisibilityPlugins::ms_pedLod1Dist;
float CVisibilityPlugins::ms_pedFadeDist;
#ifdef GTA_PS2
void
rpDefaultGeometryInstance(RpGeometry *geo, void *atomic, int unk)
{
// TODO
// this function seems to delete the original geometry data
// and only keep the instanced data
AtomicDefaultRenderCallBack((RpAtomic*)atomic);
}
RpAtomic*
PreInstanceRenderCB(RpAtomic *atomic)
{
RpGeometry *geo = RpAtomicGetGeometry(atomic);
if(RpGeometryGetTriangles(geo)){
PUSH_MEMID(MEMID_STREAM_MODELS);
rpDefaultGeometryInstance(geo, atomic, 1);
POP_MEMID();
}else
AtomicDefaultRenderCallBack(atomic);
return atomic;
}
#define RENDERCALLBACK PreInstanceRenderCB
#else
RpAtomic*
DefaultRenderCB_pushid(RpAtomic *atomic)
{
PUSH_MEMID(MEMID_STREAM_MODELS);
AtomicDefaultRenderCallBack(atomic);
POP_MEMID();
return atomic;
}
#define RENDERCALLBACK DefaultRenderCB_pushid
#endif
void
CVisibilityPlugins::Initialise(void)
{
@ -132,7 +168,7 @@ CVisibilityPlugins::RenderAlphaAtomics(void)
for(node = m_alphaList.tail.prev;
node != &m_alphaList.head;
node = node->prev)
AtomicDefaultRenderCallBack(node->item.atomic);
RENDERCALLBACK(node->item.atomic);
}
void
@ -201,7 +237,7 @@ CVisibilityPlugins::RenderWheelAtomicCB(RpAtomic *atomic)
if(lodatm){
if(RpAtomicGetGeometry(lodatm) != RpAtomicGetGeometry(atomic))
RpAtomicSetGeometry(atomic, RpAtomicGetGeometry(lodatm), rpATOMICSAMEBOUNDINGSPHERE);
AtomicDefaultRenderCallBack(atomic);
RENDERCALLBACK(atomic);
}
return atomic;
}
@ -218,7 +254,7 @@ CVisibilityPlugins::RenderObjNormalAtomic(RpAtomic *atomic)
len = RwV3dLength(&view);
if(RwV3dDotProduct(&view, RwMatrixGetUp(m)) < -0.3f*len && len > 8.0f)
return atomic;
AtomicDefaultRenderCallBack(atomic);
RENDERCALLBACK(atomic);
return atomic;
}
@ -232,7 +268,7 @@ CVisibilityPlugins::RenderAlphaAtomic(RpAtomic *atomic, int alpha)
flags = RpGeometryGetFlags(geo);
RpGeometrySetFlags(geo, flags | rpGEOMETRYMODULATEMATERIALCOLOR);
RpGeometryForAllMaterials(geo, SetAlphaCB, (void*)alpha);
AtomicDefaultRenderCallBack(atomic);
RENDERCALLBACK(atomic);
RpGeometryForAllMaterials(geo, SetAlphaCB, (void*)255);
RpGeometrySetFlags(geo, flags);
return atomic;
@ -250,7 +286,7 @@ CVisibilityPlugins::RenderFadingAtomic(RpAtomic *atomic, float camdist)
lodatm = mi->GetAtomicFromDistance(camdist - FADE_DISTANCE);
if(mi->m_additive){
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDONE);
AtomicDefaultRenderCallBack(atomic);
RENDERCALLBACK(atomic);
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
}else{
fadefactor = (mi->GetLargestLodDistance() - (camdist - FADE_DISTANCE))/FADE_DISTANCE;
@ -258,7 +294,7 @@ CVisibilityPlugins::RenderFadingAtomic(RpAtomic *atomic, float camdist)
fadefactor = 1.0f;
alpha = mi->m_alpha * fadefactor;
if(alpha == 255)
AtomicDefaultRenderCallBack(atomic);
RENDERCALLBACK(atomic);
else{
RpGeometry *geo = RpAtomicGetGeometry(lodatm);
uint32 flags = RpGeometryGetFlags(geo);
@ -266,7 +302,7 @@ CVisibilityPlugins::RenderFadingAtomic(RpAtomic *atomic, float camdist)
RpGeometryForAllMaterials(geo, SetAlphaCB, (void*)alpha);
if(geo != RpAtomicGetGeometry(atomic))
RpAtomicSetGeometry(atomic, geo, rpATOMICSAMEBOUNDINGSPHERE); // originally 5 (mistake?)
AtomicDefaultRenderCallBack(atomic);
RENDERCALLBACK(atomic);
RpGeometryForAllMaterials(geo, SetAlphaCB, (void*)255);
RpGeometrySetFlags(geo, flags);
}
@ -293,7 +329,7 @@ CVisibilityPlugins::RenderVehicleHiDetailCB(RpAtomic *atomic)
if(dot > 0.0f && ((flags & ATOMIC_FLAG_ANGLECULL) || 0.1f*distsq < dot*dot))
return atomic;
}
AtomicDefaultRenderCallBack(atomic);
RENDERCALLBACK(atomic);
}
return atomic;
}
@ -318,10 +354,10 @@ CVisibilityPlugins::RenderVehicleHiDetailAlphaCB(RpAtomic *atomic)
if(flags & ATOMIC_FLAG_DRAWLAST){
// sort before clump
if(!InsertAtomicIntoSortedList(atomic, distsq - 0.0001f))
AtomicDefaultRenderCallBack(atomic);
RENDERCALLBACK(atomic);
}else{
if(!InsertAtomicIntoSortedList(atomic, distsq + dot))
AtomicDefaultRenderCallBack(atomic);
RENDERCALLBACK(atomic);
}
}
return atomic;
@ -344,7 +380,7 @@ CVisibilityPlugins::RenderVehicleHiDetailCB_BigVehicle(RpAtomic *atomic)
if(dot > 0.0f)
return atomic;
}
AtomicDefaultRenderCallBack(atomic);
RENDERCALLBACK(atomic);
}
return atomic;
}
@ -367,7 +403,7 @@ CVisibilityPlugins::RenderVehicleHiDetailAlphaCB_BigVehicle(RpAtomic *atomic)
return atomic;
if(!InsertAtomicIntoSortedList(atomic, distsq + dot))
AtomicDefaultRenderCallBack(atomic);
RENDERCALLBACK(atomic);
}
return atomic;
}
@ -381,7 +417,7 @@ CVisibilityPlugins::RenderVehicleHiDetailCB_Boat(RpAtomic *atomic)
clumpframe = RpClumpGetFrame(RpAtomicGetClump(atomic));
distsq = GetDistanceSquaredFromCamera(clumpframe);
if(distsq < ms_bigVehicleLod1Dist)
AtomicDefaultRenderCallBack(atomic);
RENDERCALLBACK(atomic);
return atomic;
}
@ -403,7 +439,7 @@ CVisibilityPlugins::RenderVehicleLowDetailCB_BigVehicle(RpAtomic *atomic)
if(dot > 0.0f)
return atomic;
}
AtomicDefaultRenderCallBack(atomic);
RENDERCALLBACK(atomic);
}
return atomic;
}
@ -427,7 +463,7 @@ CVisibilityPlugins::RenderVehicleLowDetailAlphaCB_BigVehicle(RpAtomic *atomic)
return atomic;
if(!InsertAtomicIntoSortedList(atomic, distsq + dot))
AtomicDefaultRenderCallBack(atomic);
RENDERCALLBACK(atomic);
}
return atomic;
}
@ -444,7 +480,7 @@ CVisibilityPlugins::RenderVehicleReallyLowDetailCB(RpAtomic *atomic)
if(dist >= ms_vehicleLod0Dist){
alpha = GetClumpAlpha(clump);
if(alpha == 255)
AtomicDefaultRenderCallBack(atomic);
RENDERCALLBACK(atomic);
else
RenderAlphaAtomic(atomic, alpha);
}
@ -461,7 +497,7 @@ CVisibilityPlugins::RenderVehicleReallyLowDetailCB_BigVehicle(RpAtomic *atomic)
clumpframe = RpClumpGetFrame(RpAtomicGetClump(atomic));
distsq = GetDistanceSquaredFromCamera(clumpframe);
if(distsq >= ms_bigVehicleLod1Dist)
AtomicDefaultRenderCallBack(atomic);
RENDERCALLBACK(atomic);
return atomic;
}
@ -482,7 +518,7 @@ CVisibilityPlugins::RenderTrainHiDetailCB(RpAtomic *atomic)
if(dot > 0.0f && ((flags & ATOMIC_FLAG_ANGLECULL) || 0.1f*distsq < dot*dot))
return atomic;
}
AtomicDefaultRenderCallBack(atomic);
RENDERCALLBACK(atomic);
}
return atomic;
}
@ -507,10 +543,10 @@ CVisibilityPlugins::RenderTrainHiDetailAlphaCB(RpAtomic *atomic)
if(flags & ATOMIC_FLAG_DRAWLAST){
// sort before clump
if(!InsertAtomicIntoSortedList(atomic, distsq - 0.0001f))
AtomicDefaultRenderCallBack(atomic);
RENDERCALLBACK(atomic);
}else{
if(!InsertAtomicIntoSortedList(atomic, distsq + dot))
AtomicDefaultRenderCallBack(atomic);
RENDERCALLBACK(atomic);
}
}
return atomic;
@ -521,7 +557,7 @@ CVisibilityPlugins::RenderPlayerCB(RpAtomic *atomic)
{
if(CWorld::Players[0].m_pSkinTexture)
RpGeometryForAllMaterials(RpAtomicGetGeometry(atomic), SetTextureCB, CWorld::Players[0].m_pSkinTexture);
AtomicDefaultRenderCallBack(atomic);
RENDERCALLBACK(atomic);
return atomic;
}
@ -537,7 +573,7 @@ CVisibilityPlugins::RenderPedLowDetailCB(RpAtomic *atomic)
if(dist >= ms_pedLod0Dist){
alpha = GetClumpAlpha(clump);
if(alpha == 255)
AtomicDefaultRenderCallBack(atomic);
RENDERCALLBACK(atomic);
else
RenderAlphaAtomic(atomic, alpha);
}
@ -556,7 +592,7 @@ CVisibilityPlugins::RenderPedHiDetailCB(RpAtomic *atomic)
if(dist < ms_pedLod0Dist){
alpha = GetClumpAlpha(clump);
if(alpha == 255)
AtomicDefaultRenderCallBack(atomic);
RENDERCALLBACK(atomic);
else
RenderAlphaAtomic(atomic, alpha);
}
@ -575,7 +611,7 @@ CVisibilityPlugins::RenderPedCB(RpAtomic *atomic)
if(RwV3dDotProduct(&cam2atm, &cam2atm) < ms_pedLod1Dist){
alpha = GetClumpAlpha(RpAtomicGetClump(atomic));
if(alpha == 255)
AtomicDefaultRenderCallBack(atomic);
RENDERCALLBACK(atomic);
else
RenderAlphaAtomic(atomic, alpha);
}
@ -775,12 +811,11 @@ CVisibilityPlugins::GetAtomicId(RpAtomic *atomic)
return ATOMICEXT(atomic)->flags;
}
// This is rather useless, but whatever
void
CVisibilityPlugins::SetAtomicRenderCallback(RpAtomic *atomic, RpAtomicCallBackRender cb)
{
if(cb == nil)
cb = AtomicDefaultRenderCallBack; // not necessary
cb = RENDERCALLBACK;
RpAtomicSetRenderCallBack(atomic, cb);
}