SMG-Decomp
A decompilation of Super Mario Galaxy 1
Loading...
Searching...
No Matches
HeapMemoryWatcher.cpp
1#include "Game/System/HeapMemoryWatcher.hpp"
2#include "Game/Util.hpp"
3#include <revolution/wpad.h>
4#include <revolution/os.h>
5
6JKRExpHeap* HeapMemoryWatcher::sRootHeapGDDR3;
7
8namespace {
9 JKRExpHeap* createExpHeap(u32 size, JKRHeap *pHeap, bool a3) {
10 JKRExpHeap* heap;
11
12 if (a3) {
13 void* data = new(pHeap, -4) u8[size];
14 heap = JKRExpHeap::create(data, size, pHeap, true);
15 }
16 else {
17 heap = JKRExpHeap::create(size, pHeap, true);
18 }
19
20 if (MR::isEqualCurrentHeap(heap)) {
21 JKRHeap::sRootHeap->becomeCurrentHeap();
22 }
23
24 return heap;
25 }
26
27 JKRSolidHeap* createSolidHeap(u32 size, JKRHeap *pHeap) {
28 JKRSolidHeap* heap = JKRSolidHeap::create(size, pHeap, true);
29
30 if (MR::isEqualCurrentHeap(heap)) {
31 JKRHeap::sRootHeap->becomeCurrentHeap();
32 }
33
34 return heap;
35 }
36
37 void destroyHeapAndSetnullptr(JKRHeap **pHeap) {
38 if (*pHeap) {
39 JKRHeap::destroy(*pHeap);
40 *pHeap = nullptr;
41 }
42 }
43};
44
45JKRHeap* HeapMemoryWatcher::getHeapNapa(const JKRHeap *pHeap)
46{
47 if (pHeap == mStationedHeapNapa || pHeap == mStationedHeapGDDR)
48 return mStationedHeapNapa;
49
50 if (pHeap == mSceneHeapNapa || pHeap == mSceneHeapGDDR)
51 return mSceneHeapNapa;
52
53 return nullptr;
54}
55
56JKRHeap* HeapMemoryWatcher::getHeapGDDR3(const JKRHeap *pHeap)
57{
58 if (pHeap == mStationedHeapNapa || pHeap == mStationedHeapGDDR)
59 return mStationedHeapGDDR;
60
61 if (pHeap == mSceneHeapNapa || pHeap == mSceneHeapGDDR)
62 return mSceneHeapGDDR;
63
64 return nullptr;
65}
66
67void HeapMemoryWatcher::createFileCacheHeapOnGameHeap(u32 size) {
68 mFileCacheHeap = createSolidHeap(size, mGameHeapGDDR);
69}
70
71void HeapMemoryWatcher::createSceneHeapOnGameHeap() {
72 mSceneHeapNapa = createSolidHeap(-1, mGameHeapNapa);
73 mSceneHeapGDDR = createSolidHeap(-1, mGameHeapGDDR);
74}
75
76void HeapMemoryWatcher::adjustStationedHeaps() {
77 MR::adjustHeapSize(mStationedHeapNapa, 0);
78 MR::adjustHeapSize(mStationedHeapGDDR, 0);
79}
80
81void HeapMemoryWatcher::setCurrentHeapToStationedHeap() {
82 MR::becomeCurrentHeap(mStationedHeapNapa);
83}
84
85void HeapMemoryWatcher::setCurrentHeapToGameHeap() {
86 MR::becomeCurrentHeap(JKRHeap::sSystemHeap);
87}
88
89void HeapMemoryWatcher::setCurrentHeapToSceneHeap() {
90 MR::becomeCurrentHeap(mSceneHeapNapa);
91}
92
93void HeapMemoryWatcher::destroySceneHeap() {
94 destroyHeapAndSetnullptr((JKRHeap**)&mSceneHeapNapa);
95 destroyHeapAndSetnullptr((JKRHeap**)&mSceneHeapGDDR);
96}
97
98void HeapMemoryWatcher::destroyGameHeap() {
99 if (mSceneHeapNapa) {
100 destroyHeapAndSetnullptr((JKRHeap**)&mSceneHeapNapa);
101 }
102
103 if (mSceneHeapGDDR) {
104 destroyHeapAndSetnullptr((JKRHeap**)&mSceneHeapGDDR);
105 }
106
107 if (mFileCacheHeap) {
108 destroyHeapAndSetnullptr((JKRHeap**)&mFileCacheHeap);
109 }
110
111 destroyHeapAndSetnullptr((JKRHeap**)&mGameHeapNapa);
112 destroyHeapAndSetnullptr((JKRHeap**)&mGameHeapGDDR);
113 createGameHeap();
114}
115
116void HeapMemoryWatcher::createRootHeap() {
117 JKRExpHeap* heap;
118 void* newHi;
119 u32 arenaHi, arenaLo;
120
121 JKRExpHeap::createRoot(1, true);
122 arenaLo = (u32)OSGetMEM2ArenaLo();
123 arenaHi = (u32)OSGetMEM2ArenaHi();
124 newHi = (void*)(arenaLo + 0xE00000);
125 OSSetMEM2ArenaHi(newHi);
126 JKRHeap::setAltAramStartAdr(arenaLo);
127 heap = JKRExpHeap::create(newHi, arenaHi - (u32)newHi, JKRHeap::sRootHeap, true);
128
129 if (MR::isEqualCurrentHeap(heap)) {
130 JKRHeap::sRootHeap->becomeCurrentHeap();
131 }
132
133 HeapMemoryWatcher::sRootHeapGDDR3 = heap;
134}
135
136void HeapMemoryWatcher::createHeaps() {
137 MR::CurrentHeapRestorer chr = MR::CurrentHeapRestorer(JKRHeap::sRootHeap);
138 createExpHeap(0x40000, JKRHeap::sRootHeap, false)->becomeSystemHeap();
139 mAudSystemHeap = createSolidHeap(0x1E0000, JKRHeap::sRootHeap);
140 mStationedHeapNapa = createExpHeap(0x900000, JKRHeap::sRootHeap, false);
141 JKRHeap* gddr = HeapMemoryWatcher::sRootHeapGDDR3;
142 u32 thing = ((WPADGetWorkMemorySize() + 0x1F) & 0xFFFFFFE0) + 208;
143 mWPadHeap = createExpHeap(thing, gddr, false);
144 mHomeButtonLayoutHeap = createExpHeap(0x80000, HeapMemoryWatcher::sRootHeapGDDR3, false);
145 mStationedHeapGDDR = createExpHeap(0x1400000, HeapMemoryWatcher::sRootHeapGDDR3, false);
146 createGameHeap();
147}
148
149void HeapMemoryWatcher::createGameHeap() {
150 mGameHeapNapa = createExpHeap(-1, JKRHeap::sRootHeap, false);
151 mGameHeapGDDR = createExpHeap(-1, HeapMemoryWatcher::sRootHeapGDDR3, false);
152}
153
154HeapMemoryWatcher::HeapMemoryWatcher() {
155 mStationedHeapNapa = nullptr;
156 mStationedHeapGDDR = nullptr;
157 mGameHeapNapa = nullptr;
158 mGameHeapGDDR = nullptr;
159 mFileCacheHeap = nullptr;
160 mSceneHeapNapa = nullptr;
161 mSceneHeapGDDR = nullptr;
162 mWPadHeap = nullptr;
163 mHomeButtonLayoutHeap = nullptr;
164 mAudSystemHeap = nullptr;
165 JKRHeap::setErrorHandler(HeapMemoryWatcher::memoryErrorCallback);
166 createHeaps();
167}
168
169void HeapMemoryWatcher::memoryErrorCallback(void *, u32, int) {
170 OSPanic(__FILE__, 0x219, "");
171}
172
173void HeapMemoryWatcher::checkRestMemory() {
174
175}