diff options
| author | robojumper <robojumper@gmail.com> | 2024-04-27 15:43:31 +0200 |
|---|---|---|
| committer | robojumper <robojumper@gmail.com> | 2024-04-27 16:46:05 +0200 |
| commit | 63a858728931d42551f7d3a13a31f8fa7a5d5429 (patch) | |
| tree | 37a1b1ca2b6df209121c620c3aa283c2050e60f6 /src/m/m_heap.cpp | |
| parent | 1ee2fdd8845d7ec2502b33ef2f45b4ab17e9d88e (diff) | |
Some m_heap work
Diffstat (limited to 'src/m/m_heap.cpp')
| -rw-r--r-- | src/m/m_heap.cpp | 180 |
1 files changed, 166 insertions, 14 deletions
diff --git a/src/m/m_heap.cpp b/src/m/m_heap.cpp index 5595136b..e2e31385 100644 --- a/src/m/m_heap.cpp +++ b/src/m/m_heap.cpp @@ -1,6 +1,7 @@ #include <egg/core/eggAssertHeap.h> #include <egg/core/eggExpHeap.h> #include <egg/core/eggFrmHeap.h> +#include <m/m_heap.h> namespace mHeap { @@ -12,6 +13,8 @@ static const char *s_GameHeapNames[4] = { 0, }; +#define MIN_ALIGN 0x20 + EGG::ExpHeap *g_gameHeaps[4]; EGG::ExpHeap *s_SavedCurrentHeap; EGG::ExpHeap *g_archiveHeap; @@ -19,23 +22,162 @@ EGG::ExpHeap *g_commandHeap; EGG::ExpHeap *g_dylinkHeap; EGG::AssertHeap *g_assertHeap; -u32 getHeapAttribute(u32) {} +u16 copyAttribute(u32 arg) { + u16 result = 0; + + if ((arg & 1) != 0) { + result = 1; + } + if ((arg & 2) != 0) { + result |= 2; + } + if ((arg & 4) != 0) { + result |= 4; + } + return result; +} EGG::Heap *setCurrentHeap(EGG::Heap *heap) { return heap->becomeCurrentHeap(); } -EGG::ExpHeap *createExpHeap(size_t, EGG::Heap *parent, const char *name, unsigned long, unsigned long) {} -void adjustExpHeap(EGG::ExpHeap *) {} -size_t expHeapCost(unsigned long, unsigned long) {} +EGG::ExpHeap *createExpHeap(size_t size, EGG::Heap *parent, const char *name, unsigned long align, unsigned long attrs) { + if (parent == nullptr) { + parent = EGG::Heap::sCurrentHeap; + } + + if (align < MIN_ALIGN) { + align = MIN_ALIGN; + } + + if (size != 0xFFFFFFFF) { + size = expHeapCost(size, align); + } else { + size = parent->getAllocatableSize(align); + } + + void *mem = parent->alloc(size, align); + EGG::ExpHeap *heap = nullptr; + if (mem != nullptr) { + heap = EGG::ExpHeap::create(mem, size, copyAttribute(attrs)); + if (heap == nullptr) { + parent->free(mem); + } else if (name != nullptr) { + heap->mName = name; + } + } + return heap; +} + +size_t adjustExpHeap(EGG::ExpHeap *heap) { + int ret = 0; + if (heap != nullptr) { + size_t ad = heap->adjust(); + size_t cost = mHeap::frmHeapCost(0, 4); + if (ad >= cost) { + ret = ad - cost; + } + } + return ret; +} +size_t expHeapCost(size_t size, size_t align) { + // TODO this generates an andc where it should be a nor + and + size_t r5 = align - 1; + return size + (~r5 & (r5 + 0x84)); +} + +EGG::FrmHeap *createFrmHeap(size_t size, EGG::Heap *parent, const char *name, unsigned long align, unsigned long attrs) { + if (parent == nullptr) { + parent = EGG::Heap::sCurrentHeap; + } -EGG::FrmHeap *createFrmHeap(unsigned long, EGG::Heap *, const char *, unsigned long, unsigned long) {} -void destroyFrmHeap(EGG::FrmHeap *) {} -size_t adjustFrmHeap(EGG::FrmHeap *) {} -size_t frmHeapCost(unsigned long, unsigned long) {} + if (align < MIN_ALIGN) { + align = MIN_ALIGN; + } -EGG::ExpHeap *createHeap(unsigned long, EGG::Heap *, const char *) {} -void saveCurrentHeap() {} -void restoreCurrentHeap() {} + if (size != 0xFFFFFFFF) { + size = expHeapCost(size, align); + } else { + size = parent->getAllocatableSize(align); + } + + void *mem = parent->alloc(size, align); + EGG::FrmHeap *heap = nullptr; + if (mem != nullptr) { + heap = EGG::FrmHeap::create(mem, size, copyAttribute(attrs)); + if (heap == nullptr) { + parent->free(mem); + } else if (name != nullptr) { + heap->mName = name; + } + } + return heap; +} +void destroyFrmHeap(EGG::FrmHeap *heap) { + if (heap != nullptr) { + heap->destroy(); + } +} + +size_t adjustFrmHeap(EGG::FrmHeap *heap) { + int ret = 0; + if (heap != nullptr) { + size_t ad = heap->adjust(); + size_t cost = mHeap::frmHeapCost(0, 4); + if (ad >= cost) { + ret = ad - cost; + } + } + return ret; +} + +size_t frmHeapCost(size_t size, size_t align) { + size_t r5 = align - 1; + return size + (~r5 & (r5 + 0x7d)); +} + +EGG::Heap **setTempHeap(EGG::Heap **prevHeap, EGG::Heap *tempNewHeap) { + *prevHeap = tempNewHeap->becomeCurrentHeap(); + return prevHeap; +} +EGG::Heap **restoreTempHeap(EGG::Heap **prevHeap, s32 size) { + if (prevHeap != nullptr) { + (*prevHeap)->becomeCurrentHeap(); + if (size > 0) { + delete prevHeap; + } + } + return prevHeap; +} + +EGG::ExpHeap *createHeap(size_t size, EGG::Heap *block, const char *name) { + EGG::ExpHeap *heap = EGG::ExpHeap::create(size, block, 4); + if (heap != nullptr) { + heap->setGroupID(0); + if (name != nullptr) { + heap->mName = name; + } + } else { + block->dump(); + } + + return heap; +} +void saveCurrentHeap() { + s_SavedCurrentHeap = (EGG::ExpHeap*) EGG::Heap::sCurrentHeap; +} +void restoreCurrentHeap() { + s_SavedCurrentHeap->becomeCurrentHeap(); + EGG::Heap::sCurrentHeap = nullptr; +} + +EGG::FrmHeap *makeFrmHeapAndUpdate(size_t size, EGG::Heap *parentHeap, const char *name, s32 align, u32 unk) { + EGG::FrmHeap *heap = createFrmHeap(size, parentHeap, name, align, unk); + if (heap != nullptr) { + EGG::Heap *heap2 = setCurrentHeap(heap); + s_SavedCurrentHeap = (EGG::ExpHeap*)heap2; + } + return heap; +} int getDefaultGameHeapId() { return g_DefaultGameHeapId; @@ -60,16 +202,26 @@ EGG::ExpHeap *createGameHeap1(size_t size, EGG::Heap *parent) { return createGameHeap(getDefaultGameHeapId(), size, parent); } EGG::ExpHeap *createArchiveHeap(size_t size, EGG::Heap *parent) { - g_archiveHeap = createHeap(size, parent, ""); + g_archiveHeap = createHeap(size, parent, "汎用ファイル読み込み用ヒープ(mHeap::archiveHeap)"); + return g_archiveHeap; } EGG::ExpHeap *createCommandHeap(size_t size, EGG::Heap *parent) { g_commandHeap = createHeap(size, parent, "DVD読み込みコマンド用ヒープ(mHeap::commandHeap)"); + return g_commandHeap; } EGG::ExpHeap *createDylinkHeap(size_t size, EGG::Heap *parent) { g_dylinkHeap = createHeap(size, parent, "ダイナミックリンク用ヒープ(mHeap::dylinkHeap)"); + return g_dylinkHeap; } -EGG::ExpHeap *createAssertHeap(EGG::Heap *parent) { +EGG::AssertHeap *createAssertHeap(EGG::Heap *parent) { + const char *name = "アサートヒープ(mHeap::assertHeap)"; g_assertHeap = EGG::AssertHeap::create(EGG::AssertHeap::getSize(), parent); - g_assertHeap->mName = "アサートヒープ(mHeap::assertHeap)"; + g_assertHeap->mName = name; + return g_assertHeap; } + +EGG::Heap *makeHeapOnCurrentGameHeap(size_t size, char *name, s32 align, u32 flags) { + return makeFrmHeapAndUpdate(size, g_gameHeaps[0], name, align, flags); +} + } // namespace mHeap |
