summaryrefslogtreecommitdiffstats
path: root/src/rw/MemoryMgr.cpp
blob: ef0ecbdf0b81204137a391be94d71070291195c3 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#include "common.h"
#include "MemoryHeap.h"
#include "MemoryMgr.h"


void *pMemoryTop;

void
InitMemoryMgr(void)
{
#ifdef USE_CUSTOM_ALLOCATOR
#ifdef GTA_PS2
#error "finish this"
#else
	// randomly allocate 128mb
	gMainHeap.Init(128*1024*1024);
#endif
#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

void*
MemoryMgrMalloc(size_t size)
{
#ifdef USE_CUSTOM_ALLOCATOR
	void *mem = gMainHeap.Malloc(size);
#else
	void *mem = malloc(size);
#endif
	if(mem > pMemoryTop)
		pMemoryTop = mem;
	return mem;
}

void*
MemoryMgrRealloc(void *ptr, size_t 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;
}

void*
MemoryMgrCalloc(size_t num, size_t 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
	memset(mem, 0, num*size);
#endif
	return mem;
}

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
}

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);
}