mirror of
https://github.com/zeldaret/ss
synced 2026-06-11 05:08:16 -04:00
136 lines
3.2 KiB
C++
136 lines
3.2 KiB
C++
#include "egg/core/eggExpHeap.h"
|
|
|
|
namespace EGG {
|
|
|
|
ExpHeap::ExpHeap(MEMiHeapHead *heapHandle) : Heap(heapHandle) {}
|
|
|
|
ExpHeap::~ExpHeap() {
|
|
dispose();
|
|
MEMDestroyExpHeap(mHeapHandle);
|
|
}
|
|
|
|
ExpHeap *ExpHeap::create(void *heapStart, size_t size, u16 attr) {
|
|
ExpHeap *heap = nullptr;
|
|
void *startAddr = heapStart;
|
|
void *heapEnd = ROUND_DOWN_PTR((u8 *)heapStart + size, 0x04);
|
|
heapStart = ROUND_UP_PTR(heapStart, 0x04);
|
|
|
|
if (heapStart > heapEnd || ((u8 *)heapEnd - (u8 *)heapStart) < 0x38u) {
|
|
return nullptr;
|
|
}
|
|
|
|
MEMiHeapHead *head = MEMCreateExpHeapEx(((ExpHeap *)heapStart) + 1, ((u8 *)heapEnd - (u8 *)heapStart) - 0x34, attr);
|
|
if (head != nullptr) {
|
|
heap = new (heapStart) ExpHeap(head);
|
|
heap->mParentBlock = startAddr;
|
|
if (sCreateCallback != nullptr) {
|
|
(sCreateCallback)(heap);
|
|
}
|
|
}
|
|
|
|
return heap;
|
|
}
|
|
|
|
ExpHeap *ExpHeap::create(size_t size, Heap *heap, u16 attr) {
|
|
ExpHeap *newHeap = nullptr;
|
|
if (heap == nullptr) {
|
|
heap = sCurrentHeap;
|
|
}
|
|
|
|
if (size == -1) {
|
|
size = heap->getAllocatableSize(0x04);
|
|
}
|
|
|
|
void *block = heap->alloc(size, 0x04);
|
|
if (block != nullptr) {
|
|
newHeap = ExpHeap::create(block, size, attr);
|
|
if (newHeap == nullptr) {
|
|
heap->free(block);
|
|
}
|
|
}
|
|
|
|
return newHeap;
|
|
}
|
|
|
|
void ExpHeap::destroy() {
|
|
if (sDestroyCallback != nullptr) {
|
|
sDestroyCallback(this);
|
|
}
|
|
|
|
Heap *parentHeap = findParentHeap();
|
|
this->~ExpHeap();
|
|
if (parentHeap != nullptr) {
|
|
parentHeap->free(this);
|
|
}
|
|
}
|
|
|
|
void *ExpHeap::alloc(u32 size, s32 align) {
|
|
if (mFlag.onBit(0)) {
|
|
#line 182
|
|
OSError("DAME DAME\n");
|
|
}
|
|
|
|
void *ptr = MEMAllocFromExpHeapEx(mHeapHandle, size, align);
|
|
if (sAllocCallback != nullptr) {
|
|
HeapAllocArg arg;
|
|
arg.userArg = sAllocCallbackArg;
|
|
arg.ptr = ptr;
|
|
arg.size = size;
|
|
arg.align = align;
|
|
arg.heap = this;
|
|
(sAllocCallback)(&arg);
|
|
}
|
|
|
|
return ptr;
|
|
}
|
|
|
|
void ExpHeap::free(void *ptr) {
|
|
if (sFreeCallback != nullptr) {
|
|
HeapFreeArg arg;
|
|
arg.userArg = sFreeCallbackArg;
|
|
arg.ptr = ptr;
|
|
arg.heap = this;
|
|
(sFreeCallback)(&arg);
|
|
}
|
|
MEMFreeToExpHeap(mHeapHandle, ptr);
|
|
}
|
|
|
|
u32 ExpHeap::resizeForMBlock(void *block, u32 size) {
|
|
return MEMResizeForMBlockExpHeap(mHeapHandle, block, size);
|
|
}
|
|
|
|
u32 ExpHeap::getTotalFreeSize() {
|
|
return MEMGetTotalFreeSizeForExpHeap(mHeapHandle);
|
|
}
|
|
|
|
u32 ExpHeap::getAllocatableSize(s32 align) {
|
|
return MEMGetAllocatableSizeForExpHeapEx(mHeapHandle, align);
|
|
}
|
|
|
|
void ExpHeap::setAllocMode(u16 allocMode) {
|
|
MEMSetAllocModeForExpHeap(mHeapHandle, allocMode);
|
|
}
|
|
|
|
u32 ExpHeap::adjust() {
|
|
u32 adjustedSize = MEMAdjustExpHeap(mHeapHandle);
|
|
u32 totalSize = adjustedSize + sizeof(ExpHeap);
|
|
if (totalSize > sizeof(ExpHeap)) {
|
|
Heap *parent = findParentHeap();
|
|
if (parent != nullptr) {
|
|
parent->resizeForMBlock(mParentBlock, totalSize);
|
|
return totalSize;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
u32 ExpHeap::getSizeForMBlock(const void *block) {
|
|
return MEMGetSizeForMBlockExpHeap(block);
|
|
}
|
|
|
|
Heap::eHeapKind ExpHeap::getHeapKind() const {
|
|
return HEAP_KIND_EXPANDED;
|
|
}
|
|
|
|
} // namespace EGG
|