2023-12-13 00:40:16 -05:00
|
|
|
#include "Game/System/HeapMemoryWatcher.hpp"
|
|
|
|
|
#include "Game/Util.hpp"
|
2022-05-10 09:08:49 -04:00
|
|
|
#include <revolution/wpad.h>
|
2023-07-31 02:29:59 -04:00
|
|
|
#include <revolution/os.h>
|
2022-05-10 09:08:49 -04:00
|
|
|
|
2022-08-14 03:51:14 -04:00
|
|
|
JKRExpHeap* HeapMemoryWatcher::sRootHeapGDDR3;
|
|
|
|
|
|
2022-05-10 09:08:49 -04:00
|
|
|
namespace {
|
|
|
|
|
JKRExpHeap* createExpHeap(u32 size, JKRHeap *pHeap, bool a3) {
|
|
|
|
|
JKRExpHeap* heap;
|
|
|
|
|
|
|
|
|
|
if (a3) {
|
|
|
|
|
void* data = new(pHeap, -4) u8[size];
|
|
|
|
|
heap = JKRExpHeap::create(data, size, pHeap, true);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
heap = JKRExpHeap::create(size, pHeap, true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (MR::isEqualCurrentHeap(heap)) {
|
|
|
|
|
JKRHeap::sRootHeap->becomeCurrentHeap();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return heap;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
JKRSolidHeap* createSolidHeap(u32 size, JKRHeap *pHeap) {
|
|
|
|
|
JKRSolidHeap* heap = JKRSolidHeap::create(size, pHeap, true);
|
|
|
|
|
|
|
|
|
|
if (MR::isEqualCurrentHeap(heap)) {
|
|
|
|
|
JKRHeap::sRootHeap->becomeCurrentHeap();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return heap;
|
|
|
|
|
}
|
|
|
|
|
|
2023-02-13 03:33:10 -05:00
|
|
|
void destroyHeapAndSetnullptr(JKRHeap **pHeap) {
|
2022-05-10 09:08:49 -04:00
|
|
|
if (*pHeap) {
|
|
|
|
|
JKRHeap::destroy(*pHeap);
|
2023-02-13 03:33:10 -05:00
|
|
|
*pHeap = nullptr;
|
2022-05-10 09:08:49 -04:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
JKRHeap* HeapMemoryWatcher::getHeapNapa(const JKRHeap *pHeap)
|
|
|
|
|
{
|
|
|
|
|
if (pHeap == mStationedHeapNapa || pHeap == mStationedHeapGDDR)
|
|
|
|
|
return mStationedHeapNapa;
|
|
|
|
|
|
|
|
|
|
if (pHeap == mSceneHeapNapa || pHeap == mSceneHeapGDDR)
|
|
|
|
|
return mSceneHeapNapa;
|
|
|
|
|
|
2023-02-13 03:33:10 -05:00
|
|
|
return nullptr;
|
2022-05-10 09:08:49 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
JKRHeap* HeapMemoryWatcher::getHeapGDDR3(const JKRHeap *pHeap)
|
|
|
|
|
{
|
|
|
|
|
if (pHeap == mStationedHeapNapa || pHeap == mStationedHeapGDDR)
|
|
|
|
|
return mStationedHeapGDDR;
|
|
|
|
|
|
|
|
|
|
if (pHeap == mSceneHeapNapa || pHeap == mSceneHeapGDDR)
|
|
|
|
|
return mSceneHeapGDDR;
|
|
|
|
|
|
2023-02-13 03:33:10 -05:00
|
|
|
return nullptr;
|
2022-05-10 09:08:49 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void HeapMemoryWatcher::createFileCacheHeapOnGameHeap(u32 size) {
|
|
|
|
|
mFileCacheHeap = createSolidHeap(size, mGameHeapGDDR);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void HeapMemoryWatcher::createSceneHeapOnGameHeap() {
|
|
|
|
|
mSceneHeapNapa = createSolidHeap(-1, mGameHeapNapa);
|
|
|
|
|
mSceneHeapGDDR = createSolidHeap(-1, mGameHeapGDDR);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void HeapMemoryWatcher::adjustStationedHeaps() {
|
|
|
|
|
MR::adjustHeapSize(mStationedHeapNapa, 0);
|
|
|
|
|
MR::adjustHeapSize(mStationedHeapGDDR, 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void HeapMemoryWatcher::setCurrentHeapToStationedHeap() {
|
|
|
|
|
MR::becomeCurrentHeap(mStationedHeapNapa);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void HeapMemoryWatcher::setCurrentHeapToGameHeap() {
|
|
|
|
|
MR::becomeCurrentHeap(JKRHeap::sSystemHeap);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void HeapMemoryWatcher::setCurrentHeapToSceneHeap() {
|
|
|
|
|
MR::becomeCurrentHeap(mSceneHeapNapa);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void HeapMemoryWatcher::destroySceneHeap() {
|
2023-02-13 03:33:10 -05:00
|
|
|
destroyHeapAndSetnullptr((JKRHeap**)&mSceneHeapNapa);
|
|
|
|
|
destroyHeapAndSetnullptr((JKRHeap**)&mSceneHeapGDDR);
|
2022-05-10 09:08:49 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void HeapMemoryWatcher::destroyGameHeap() {
|
|
|
|
|
if (mSceneHeapNapa) {
|
2023-02-13 03:33:10 -05:00
|
|
|
destroyHeapAndSetnullptr((JKRHeap**)&mSceneHeapNapa);
|
2022-05-10 09:08:49 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (mSceneHeapGDDR) {
|
2023-02-13 03:33:10 -05:00
|
|
|
destroyHeapAndSetnullptr((JKRHeap**)&mSceneHeapGDDR);
|
2022-05-10 09:08:49 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (mFileCacheHeap) {
|
2023-02-13 03:33:10 -05:00
|
|
|
destroyHeapAndSetnullptr((JKRHeap**)&mFileCacheHeap);
|
2022-05-10 09:08:49 -04:00
|
|
|
}
|
|
|
|
|
|
2023-02-13 03:33:10 -05:00
|
|
|
destroyHeapAndSetnullptr((JKRHeap**)&mGameHeapNapa);
|
|
|
|
|
destroyHeapAndSetnullptr((JKRHeap**)&mGameHeapGDDR);
|
2022-05-10 09:08:49 -04:00
|
|
|
createGameHeap();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void HeapMemoryWatcher::createRootHeap() {
|
2023-07-31 02:29:59 -04:00
|
|
|
JKRExpHeap* heap;
|
|
|
|
|
void* newHi;
|
|
|
|
|
u32 arenaHi, arenaLo;
|
|
|
|
|
|
2022-05-10 09:08:49 -04:00
|
|
|
JKRExpHeap::createRoot(1, true);
|
2023-07-31 02:29:59 -04:00
|
|
|
arenaLo = (u32)OSGetMEM2ArenaLo();
|
|
|
|
|
arenaHi = (u32)OSGetMEM2ArenaHi();
|
|
|
|
|
newHi = (void*)(arenaLo + 0xE00000);
|
2022-05-10 09:08:49 -04:00
|
|
|
OSSetMEM2ArenaHi(newHi);
|
|
|
|
|
JKRHeap::setAltAramStartAdr(arenaLo);
|
2023-07-31 02:29:59 -04:00
|
|
|
heap = JKRExpHeap::create(newHi, arenaHi - (u32)newHi, JKRHeap::sRootHeap, true);
|
2022-05-10 09:08:49 -04:00
|
|
|
|
|
|
|
|
if (MR::isEqualCurrentHeap(heap)) {
|
|
|
|
|
JKRHeap::sRootHeap->becomeCurrentHeap();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
HeapMemoryWatcher::sRootHeapGDDR3 = heap;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void HeapMemoryWatcher::createHeaps() {
|
|
|
|
|
MR::CurrentHeapRestorer chr = MR::CurrentHeapRestorer(JKRHeap::sRootHeap);
|
|
|
|
|
createExpHeap(0x40000, JKRHeap::sRootHeap, false)->becomeSystemHeap();
|
2023-09-02 01:46:08 -04:00
|
|
|
mAudSystemHeap = createSolidHeap(0x1E0000, JKRHeap::sRootHeap);
|
2022-05-10 09:08:49 -04:00
|
|
|
mStationedHeapNapa = createExpHeap(0x900000, JKRHeap::sRootHeap, false);
|
|
|
|
|
JKRHeap* gddr = HeapMemoryWatcher::sRootHeapGDDR3;
|
|
|
|
|
u32 thing = ((WPADGetWorkMemorySize() + 0x1F) & 0xFFFFFFE0) + 208;
|
|
|
|
|
mWPadHeap = createExpHeap(thing, gddr, false);
|
|
|
|
|
mHomeButtonLayoutHeap = createExpHeap(0x80000, HeapMemoryWatcher::sRootHeapGDDR3, false);
|
|
|
|
|
mStationedHeapGDDR = createExpHeap(0x1400000, HeapMemoryWatcher::sRootHeapGDDR3, false);
|
|
|
|
|
createGameHeap();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void HeapMemoryWatcher::createGameHeap() {
|
|
|
|
|
mGameHeapNapa = createExpHeap(-1, JKRHeap::sRootHeap, false);
|
|
|
|
|
mGameHeapGDDR = createExpHeap(-1, HeapMemoryWatcher::sRootHeapGDDR3, false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
HeapMemoryWatcher::HeapMemoryWatcher() {
|
2023-02-13 03:33:10 -05:00
|
|
|
mStationedHeapNapa = nullptr;
|
|
|
|
|
mStationedHeapGDDR = nullptr;
|
|
|
|
|
mGameHeapNapa = nullptr;
|
|
|
|
|
mGameHeapGDDR = nullptr;
|
|
|
|
|
mFileCacheHeap = nullptr;
|
|
|
|
|
mSceneHeapNapa = nullptr;
|
|
|
|
|
mSceneHeapGDDR = nullptr;
|
|
|
|
|
mWPadHeap = nullptr;
|
|
|
|
|
mHomeButtonLayoutHeap = nullptr;
|
2023-09-02 01:46:08 -04:00
|
|
|
mAudSystemHeap = nullptr;
|
2022-05-10 09:08:49 -04:00
|
|
|
JKRHeap::setErrorHandler(HeapMemoryWatcher::memoryErrorCallback);
|
|
|
|
|
createHeaps();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void HeapMemoryWatcher::memoryErrorCallback(void *, u32, int) {
|
|
|
|
|
OSPanic(__FILE__, 0x219, "");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void HeapMemoryWatcher::checkRestMemory() {
|
|
|
|
|
|
|
|
|
|
}
|