diff --git a/include/functions.h b/include/functions.h index 90f1526774..d65e818e1e 100644 --- a/include/functions.h +++ b/include/functions.h @@ -23,7 +23,8 @@ f32 signF(f32 val); void* heap_malloc(s32 size); void* _heap_malloc(HeapNode* head, u32 size); -HeapNode* _heap_create(s32* addr, u32 size); +u32 _heap_free(HeapNode* heapNodeList, void* addrToFree); +HeapNode* _heap_create(HeapNode* addr, u32 size); s32 dma_copy(Addr romStart, Addr romEnd, void* vramDest); void copy_matrix(Matrix4f src, Matrix4f dest); diff --git a/include/variables.h b/include/variables.h index 548c97aa23..a1a3bb8691 100644 --- a/include/variables.h +++ b/include/variables.h @@ -384,14 +384,14 @@ extern s32 D_802C05CC; extern s16 gCurrentCamID; -extern s32 gSpriteHeapPtr; +extern HeapNode gSpriteHeapPtr; extern s32 D_8029C890[12][5]; // Heap? extern s32 D_8038F800; extern s32 D_803B5000; -extern s32 D_803DA800; +extern HeapNode heap_battleHead; extern s32 D_80108A64; extern s32 bMarioIdleAnims[]; diff --git a/src/316d90.c b/src/316d90.c index dcb8677c3c..8f818de954 100644 --- a/src/316d90.c +++ b/src/316d90.c @@ -43,6 +43,6 @@ void func_802AE000(void) { if (((u32)battle_heap_create >> 0x1C) == 8) { (battle_heap_create)(); } else { - _heap_create(&D_803DA800, 0x10000); + _heap_create(&heap_battleHead, 0x10000); } } diff --git a/src/43F0.c b/src/43F0.c index 6c39dce252..7300b84362 100644 --- a/src/43F0.c +++ b/src/43F0.c @@ -59,7 +59,7 @@ f32 length2D(f32 x, f32 y) { return sqrtf(SQ(x) + SQ(y)); } -HeapNode* _heap_create(s32* addr, u32 size) { +HeapNode* _heap_create(HeapNode* addr, u32 size) { if (size < 32) { return (HeapNode*)-1; } else { @@ -187,7 +187,9 @@ void* _heap_malloc_tail(HeapNode* head, u32 size) { // we found a block to use, see if we can split it and return a portion // or if we just need to return the whole block if (foundNodeLength >= newNodeSize) { - // room to split and add another free block after this one, do so + // add a free block before this one + // this is where this function differs from heap_malloc, it returns + // the end of the block instead of the beginning when splitting it up curNode->next = (HeapNode*)((u8*)curNode + foundNodeLength - size); curNode->length = foundNodeLength - newNodeSize; curNode->allocated = FALSE; @@ -211,7 +213,70 @@ void* _heap_malloc_tail(HeapNode* head, u32 size) { return NULL; } -INCLUDE_ASM(s32, "43F0", _heap_free); +u32 _heap_free(HeapNode* heapNodeList, void* addrToFree) { + u32 curNodeLength; + HeapNode* nextNode; + HeapNode* nodeToFreeHeader; + HeapNode* tempNode; + HeapNode* outNode; + + // if no address to free then return + if (addrToFree == NULL) { + return TRUE; + } + + // if we are not allocated then ignore this request + nodeToFreeHeader = (HeapNode*)((u8*)addrToFree - sizeof(HeapNode)); + if (!nodeToFreeHeader->allocated) { + return TRUE; + } + + nextNode = nodeToFreeHeader->next; + curNodeLength = nodeToFreeHeader->length; + outNode = nextNode; + + // see if the next node after us is allocated, if not then adjust our size + // to include it and point nextNode to be the node after as it must be allocated + if (nextNode && !nextNode->allocated) { + curNodeLength += nextNode->length + sizeof(HeapNode); + nextNode = nextNode->next; + } + + // walk the full heap node list looking for the block before our current entry + tempNode = heapNodeList; + while (1) { + // get the pointer to the next block, if it matches the block being freed then + // exit the search + heapNodeList = tempNode->next; + if (heapNodeList == nodeToFreeHeader) { + + // we found the node prior to us, if it is not allocated then adjust our total + // size to include it and change the header node pointer to point that block + if (!tempNode->allocated) { + curNodeLength += sizeof(HeapNode) + tempNode->length; + nodeToFreeHeader = tempNode; + } + break; + } + + // if the node being freed is before the current node being looked at then we + // moved past our current node, bail out. Also bail if we hit the end of the list + if (nodeToFreeHeader < tempNode || !heapNodeList) { + break; + } + + // move to the next node + tempNode = tempNode->next; + } + + // update the node being free'd with a proper size and pointer to the next node that is + // allocated + outNode = nodeToFreeHeader; + outNode->next = nextNode; + outNode->length = curNodeLength; + outNode->allocated = FALSE; + return FALSE; +} INCLUDE_ASM(s32, "43F0", _heap_realloc); diff --git a/src/heap.c b/src/heap.c index c63d194f09..e60927c39f 100644 --- a/src/heap.c +++ b/src/heap.c @@ -1,26 +1,27 @@ #include "common.h" -extern s32 D_80268000; -extern s32 D_802FB800; +extern HeapNode heap_collisionHead; +extern HeapNode heap_generalHead; +extern HeapNode heap_battleHead; HeapNode* general_heap_create(void) { - return _heap_create(&D_802FB800, 0x54000); + return _heap_create(&heap_generalHead, 0x54000); } void* general_heap_malloc(s32 size) { - return _heap_malloc(&D_802FB800, size); + return _heap_malloc(&heap_generalHead, size); } s32 general_heap_malloc_tail(s32 size) { - return _heap_malloc_tail(&D_802FB800, size); + return _heap_malloc_tail(&heap_generalHead, size); } s32 general_heap_free(s32* data) { - return _heap_free(&D_802FB800, data); + return _heap_free(&heap_generalHead, data); } s32 battle_heap_create(void) { - if ((s32)_heap_create(&D_803DA800, 0x25800) == -1) { + if ((s32)_heap_create(&heap_battleHead, 0x25800) == -1) { return -1; } else { return 0; @@ -35,20 +36,20 @@ void* heap_malloc(s32 size) { if (!gGameStatusPtr->isBattle) { return general_heap_malloc(size); } else { - return _heap_malloc(&D_803DA800, size); + return _heap_malloc(&heap_battleHead, size); } } s32 heap_free(void* data) { if (gGameStatusPtr->isBattle) { - return _heap_free(&D_803DA800, data); + return _heap_free(&heap_battleHead, data); } else { return general_heap_free(data); } } s32 collision_heap_create(void) { - if ((s32)_heap_create(&D_80268000, 0x18000) == -1) { + if ((s32)_heap_create(&heap_collisionHead, 0x18000) == -1) { return -1; } return 0; @@ -56,16 +57,16 @@ s32 collision_heap_create(void) { void* collision_heap_malloc(s32 size) { if (!gGameStatusPtr->isBattle) { - return _heap_malloc(&D_80268000, size); + return _heap_malloc(&heap_collisionHead, size); } else { - return _heap_malloc(&D_803DA800, size); + return _heap_malloc(&heap_battleHead, size); } } s32 collision_heap_free(void* data) { if (gGameStatusPtr->isBattle) { - return _heap_free(&D_803DA800, data); + return _heap_free(&heap_battleHead, data); } else { - return _heap_free(&D_80268000, data); + return _heap_free(&heap_collisionHead, data); } } diff --git a/src/state_battle.c b/src/state_battle.c index b92f37333e..4566ef9a29 100644 --- a/src/state_battle.c +++ b/src/state_battle.c @@ -5,7 +5,7 @@ #include "sprite.h" s32 D_800778A0[] = { - &D_8038F800, &D_803B5000, &D_803DA800, + &D_8038F800, &D_803B5000, &heap_battleHead, }; s32 D_800778AC[] = { diff --git a/src/state_file_select.c b/src/state_file_select.c index 6f975caa1a..f2dd853fa9 100644 --- a/src/state_file_select.c +++ b/src/state_file_select.c @@ -5,7 +5,7 @@ #include "hud_element.h" #include "sprite.h" -s32 D_80077980[] = { &D_8038F800, &D_803B5000, &D_803DA800, }; +s32 D_80077980[] = { &D_8038F800, &D_803B5000, &heap_battleHead, }; NUPiOverlaySegment D_8007798C = { .romStart = _163400_ROM_START, diff --git a/src/state_pause.c b/src/state_pause.c index 1a61fa5e65..e9c51bd8f3 100644 --- a/src/state_pause.c +++ b/src/state_pause.c @@ -5,7 +5,7 @@ #include "hud_element.h" #include "sprite.h" -s32 D_80077950[] = { 0x8038F800, 0x803B5000, &D_803DA800 }; +s32 D_80077950[] = { 0x8038F800, 0x803B5000, &heap_battleHead }; NUPiOverlaySegment D_8007795C = { .romStart = pause_ROM_START, diff --git a/ver/us/asm/data/6EAC0.data.s b/ver/us/asm/data/6EAC0.data.s index 7c1da977a1..69163ecd69 100644 --- a/ver/us/asm/data/6EAC0.data.s +++ b/ver/us/asm/data/6EAC0.data.s @@ -21,7 +21,7 @@ glabel nugfx_ucode .word 0x80096030, 0x80097660 glabel FrameBuf -.word D_8038F800, D_803B5000, D_803DA800, 0x00000000 +.word D_8038F800, D_803B5000, heap_battleHead, 0x00000000 glabel rdpstateinit_dl .word 0xFB000000, 0x00000000, 0xFA000000, 0x00000000, 0xF9000000, 0x00000000, 0xF8000000, 0x00000000, 0xF7000000, 0x00000000, 0xEE000000, 0x00000000, 0xEC000000, 0x00000000, 0xEB000000, 0x00000000, 0xEA000000, 0x00000000, 0xFCFFFFFF, 0xFFFE793C, 0xED000000, 0x005003C0, 0xF5100000, 0x00000000, 0xF5100000, 0x01000000, 0xF5100000, 0x02000000, 0xF5100000, 0x03000000, 0xF5100000, 0x04000000, 0xF5100000, 0x05000000, 0xF5100000, 0x06000000, 0xF5100000, 0x07000000, 0xF2000000, 0x00000000, 0xF2000000, 0x01000000, 0xF2000000, 0x02000000, 0xF2000000, 0x03000000, 0xF2000000, 0x04000000, 0xF2000000, 0x05000000, 0xF2000000, 0x06000000, 0xF2000000, 0x07000000, 0xE7000000, 0x00000000, 0xDF000000, 0x00000000 diff --git a/ver/us/asm/nonmatchings/101b90_len_8f0/spr_allocate_components.s b/ver/us/asm/nonmatchings/101b90_len_8f0/spr_allocate_components.s index ef2ba78590..62cd7cdae1 100644 --- a/ver/us/asm/nonmatchings/101b90_len_8f0/spr_allocate_components.s +++ b/ver/us/asm/nonmatchings/101b90_len_8f0/spr_allocate_components.s @@ -18,8 +18,8 @@ glabel spr_allocate_components /* 1023FC 802DF30C 2484F800 */ addiu $a0, $a0, %lo(gSpriteHeapPtr) /* 102400 802DF310 10600003 */ beqz $v1, .L802DF320 /* 102404 802DF314 AFBF0018 */ sw $ra, 0x18($sp) -/* 102408 802DF318 3C048030 */ lui $a0, %hi(D_802FB800) -/* 10240C 802DF31C 2484B800 */ addiu $a0, $a0, %lo(D_802FB800) +/* 102408 802DF318 3C048030 */ lui $a0, %hi(heap_generalHead) +/* 10240C 802DF31C 2484B800 */ addiu $a0, $a0, %lo(heap_generalHead) .L802DF320: /* 102410 802DF320 0C00A41B */ jal _heap_malloc /* 102414 802DF324 00000000 */ nop diff --git a/ver/us/asm/nonmatchings/43F0/_heap_free.s b/ver/us/asm/nonmatchings/43F0/_heap_free.s deleted file mode 100644 index 01f8e2c5ff..0000000000 --- a/ver/us/asm/nonmatchings/43F0/_heap_free.s +++ /dev/null @@ -1,52 +0,0 @@ -.set noat # allow manual use of $at -.set noreorder # don't insert nops after branches - -glabel _heap_free -/* 461C 8002921C 14A00003 */ bnez $a1, .L8002922C -/* 4620 80029220 00000000 */ nop -.L80029224: -/* 4624 80029224 03E00008 */ jr $ra -/* 4628 80029228 24020001 */ addiu $v0, $zero, 1 -.L8002922C: -/* 462C 8002922C 94A2FFF8 */ lhu $v0, -8($a1) -/* 4630 80029230 1040FFFC */ beqz $v0, .L80029224 -/* 4634 80029234 24A6FFF0 */ addiu $a2, $a1, -0x10 -/* 4638 80029238 8CA7FFF0 */ lw $a3, -0x10($a1) -/* 463C 8002923C 8CA5FFF4 */ lw $a1, -0xc($a1) -/* 4640 80029240 00E0182D */ daddu $v1, $a3, $zero -/* 4644 80029244 50600009 */ beql $v1, $zero, .L8002926C -/* 4648 80029248 0080182D */ daddu $v1, $a0, $zero -/* 464C 8002924C 94620008 */ lhu $v0, 8($v1) -/* 4650 80029250 54400006 */ bnel $v0, $zero, .L8002926C -/* 4654 80029254 0080182D */ daddu $v1, $a0, $zero -/* 4658 80029258 8C670000 */ lw $a3, ($v1) -/* 465C 8002925C 8C630004 */ lw $v1, 4($v1) -/* 4660 80029260 24A20010 */ addiu $v0, $a1, 0x10 -/* 4664 80029264 00432821 */ addu $a1, $v0, $v1 -/* 4668 80029268 0080182D */ daddu $v1, $a0, $zero -.L8002926C: -/* 466C 8002926C 8C640000 */ lw $a0, ($v1) -/* 4670 80029270 10860007 */ beq $a0, $a2, .L80029290 -/* 4674 80029274 00C3102B */ sltu $v0, $a2, $v1 -/* 4678 80029278 1440000D */ bnez $v0, .L800292B0 -/* 467C 8002927C 00C0182D */ daddu $v1, $a2, $zero -/* 4680 80029280 1080000A */ beqz $a0, .L800292AC -/* 4684 80029284 0080182D */ daddu $v1, $a0, $zero -/* 4688 80029288 0800A49B */ j .L8002926C -/* 468C 8002928C 00000000 */ nop -.L80029290: -/* 4690 80029290 94620008 */ lhu $v0, 8($v1) -/* 4694 80029294 54400006 */ bnel $v0, $zero, .L800292B0 -/* 4698 80029298 00C0182D */ daddu $v1, $a2, $zero -/* 469C 8002929C 0060302D */ daddu $a2, $v1, $zero -/* 46A0 800292A0 8CC30004 */ lw $v1, 4($a2) -/* 46A4 800292A4 24A20010 */ addiu $v0, $a1, 0x10 -/* 46A8 800292A8 00432821 */ addu $a1, $v0, $v1 -.L800292AC: -/* 46AC 800292AC 00C0182D */ daddu $v1, $a2, $zero -.L800292B0: -/* 46B0 800292B0 0000102D */ daddu $v0, $zero, $zero -/* 46B4 800292B4 AC670000 */ sw $a3, ($v1) -/* 46B8 800292B8 AC650004 */ sw $a1, 4($v1) -/* 46BC 800292BC 03E00008 */ jr $ra -/* 46C0 800292C0 A4600008 */ sh $zero, 8($v1) diff --git a/ver/us/asm/nonmatchings/sprite/spr_free_sprite.s b/ver/us/asm/nonmatchings/sprite/spr_free_sprite.s index 83fd3a958b..9bfda47093 100644 --- a/ver/us/asm/nonmatchings/sprite/spr_free_sprite.s +++ b/ver/us/asm/nonmatchings/sprite/spr_free_sprite.s @@ -71,8 +71,8 @@ glabel spr_free_sprite /* 1017CC 802DE6DC 2484F800 */ addiu $a0, $a0, %lo(gSpriteHeapPtr) /* 1017D0 802DE6E0 10400003 */ beqz $v0, .L802DE6F0 /* 1017D4 802DE6E4 00000000 */ nop -/* 1017D8 802DE6E8 3C048030 */ lui $a0, %hi(D_802FB800) -/* 1017DC 802DE6EC 2484B800 */ addiu $a0, $a0, %lo(D_802FB800) +/* 1017D8 802DE6E8 3C048030 */ lui $a0, %hi(heap_generalHead) +/* 1017DC 802DE6EC 2484B800 */ addiu $a0, $a0, %lo(heap_generalHead) .L802DE6F0: /* 1017E0 802DE6F0 0C00A487 */ jal _heap_free /* 1017E4 802DE6F4 0200282D */ daddu $a1, $s0, $zero diff --git a/ver/us/symbol_addrs.txt b/ver/us/symbol_addrs.txt index c9c7fd8e5f..ff23905bc5 100644 --- a/ver/us/symbol_addrs.txt +++ b/ver/us/symbol_addrs.txt @@ -19813,7 +19813,7 @@ D_80262C34 = 0x80262C34; // type:data D_80262C38 = 0x80262C38; // type:data D_80262F68 = 0x80262F68; // type:data StartRumbleWithParams = 0x80267D9C; // -D_80268000 = 0x80268000; // type:data +heap_collisionHead = 0x80268000; // type:data D_8026A2B0 = 0x8026A2B0; // type:data D_8026F118 = 0x8026F118; // type:data D_8026F1B8 = 0x8026F1B8; // type:data @@ -20617,11 +20617,11 @@ D_802EE8D0 = 0x802EE8D0; // type:data D_802EF0D0 = 0x802EF0D0; // type:data D_802F39D0 = 0x802F39D0; // type:data D_802F4560 = 0x802F4560; // type:data -D_802FB800 = 0x802FB800; // type:data +heap_generalHead = 0x802FB800; // type:data gSpriteHeapPtr = 0x8034F800; // type:data D_8038F800 = 0x8038F800; // type:data D_803B5000 = 0x803B5000; // type:data -D_803DA800 = 0x803DA800; // type:data +heap_battleHead = 0x803DA800; // type:data D_8887FFFB = 0x8887FFFB; // type:data D_A0000000 = 0xA0000000; // type:data D_A4000000 = 0xA4000000; // type:data diff --git a/ver/us/undefined_syms.txt b/ver/us/undefined_syms.txt index cdb00c9f6d..52547ea5a3 100644 --- a/ver/us/undefined_syms.txt +++ b/ver/us/undefined_syms.txt @@ -729,7 +729,7 @@ D_80262A70 = 0x80262A70; D_80262C34 = 0x80262C34; D_80262C38 = 0x80262C38; D_80262F68 = 0x80262F68; -D_80268000 = 0x80268000; +heap_collisionHead = 0x80268000; gPauseMenuCommonIconIDs = 0x802700E8; D_80270108 = 0x80270108; D_8027010C = 0x8027010C; @@ -1255,9 +1255,9 @@ D_802ED970 = 0x802ED970; D_802EE8D0 = 0x802EE8D0; D_802F39D0 = 0x802F39D0; D_802F4560 = 0x802F4560; -D_802FB800 = 0x802FB800; +heap_generalHead = 0x802FB800; gSpriteHeapPtr = 0x8034F800; -D_803DA800 = 0x803DA800; +heap_battleHead = 0x803DA800; D_802510B0 = 0x802510B0; D_8026A2B0 = 0x8026A2B0;