forked from Phobos-developers/YRpp
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Memory.h
161 lines (134 loc) · 3.21 KB
/
Memory.h
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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
#ifndef MEMORY_H
#define MEMORY_H
#include <ASMMacros.h>
//include <Unsorted.h>
/*
* The memory (de)allocators have to match!
* Do not allocate memory in the DLL and hand it to the game to deallocate, or vice versa.
* Kapiche?
* A simple |auto foo = new IngameClass();| allocates memory from the DLL's pool.
* But |delete foo;| deallocates memory from the game's own pool. (assuming the class you're freeing has a virtual SDDTOR)
* So use the macros to make sure game classes go to the game's pool.
* The custom classes like ExtMap do not need this treatment so you can use the plain old new/delete on them.
* For the ObjectClass derivates, if you use the game's built-in allocators like | Type->CreateObject() | ,
* you can use plain | delete |;
*/
/*
* OK, new plan - the game's operator new/delete has been hooked to redirect to the DLL's
* so GAME_(DE)ALLOC is now just a wrapper. Don't remove it though, just in case this fails
* and I need to run those allocations differently.
*/
/*
* Newer plan - previous hook screwed performance, so going back
*/
// allocate scalars
template<typename T>
static void * __cdecl Allocate(bool inDLL) {
size_t sz = sizeof(T);
if(inDLL) {
return operator new(sz);
}
PUSH_VAR32(sz);
CALL(0x7C8E17);
ADD_ESP(4);
};
#define DO_ALLOC(inDLL, TT, var, ...) \
{ \
void *p = Allocate<TT>(inDLL); \
if(p) { \
var = new (p) TT(__VA_ARGS__); \
} else { \
ExitProcess(1); \
} \
} \
// allocate in the game's pool
#define GAME_ALLOC(TT, var, ...) \
{ \
DO_ALLOC(0, TT, var, __VA_ARGS__); \
}
// var = new TT(__VA_ARGS__);
// allocate in the DLL's pool
// not sure if this is ever going to be needed
#define DLL_ALLOC(TT, var, ...) \
{ \
DO_ALLOC(1, TT, var, __VA_ARGS__);\
} \
// allocate vectors
template<typename T>
static void * __cdecl Allocate_Array(bool inDLL, size_t Capacity) {
size_t sz = sizeof(T) * Capacity;
if(inDLL) {
return operator new(sz);
}
PUSH_VAR32(sz);
CALL(0x7C8E17);
ADD_ESP(4);
};
// allocate arrays
#define DO_ALLOC_ARR(inDLL, TT, Capacity, var) \
{ \
void *p = Allocate_Array<TT>(inDLL, Capacity); \
if(p) { \
var = new (p) TT[Capacity]; \
} else { \
ExitProcess(1); \
} \
} \
// allocate array in the game's pool
#define GAME_ALLOC_ARR(TT, Capacity, var) \
{ \
DO_ALLOC_ARR(0, TT, Capacity, var); \
}
// deallocate scalars
template<typename T>
static void __cdecl Deallocate(T* Tptr, bool inDLL) {
if(Tptr) {
Tptr->~T();
}
if(inDLL) {
operator delete(Tptr);
return;
}
PUSH_VAR32(Tptr);
CALL(0x7C8B3D);
ADD_ESP(4);
};
// deallocate from the game's pool
#define GAME_DEALLOC(var) \
{ \
Deallocate(var, 0); \
} \
// delete var;
// deallocate from the DLL's pool
#define DLL_DEALLOC(var) \
{ \
Deallocate(var, 1); \
} \
// deallocate vectors
template<typename T>
static void __cdecl Deallocate_Array(T* Tptr, bool inDLL) {
if(Tptr) {
T *iter = Tptr;
// ye olde black magick
size_t *p = reinterpret_cast<size_t *>(iter) - 1;
size_t amount = *p;
while(amount > 0 && iter) {
iter->~T();
++iter;
--amount;
}
}
if(inDLL) {
operator delete[](Tptr);
return;
}
PUSH_VAR32(Tptr);
CALL(0x7C8B3D);
ADD_ESP(4);
};
// deallocate from the game's pool
#define GAME_DEALLOC_ARR(var) \
{ \
Deallocate_Array(var, 0); \
} \
#endif