diff --git a/include/alignment.h b/include/alignment.h index 7a3b94ea2c..e26a1d3f33 100644 --- a/include/alignment.h +++ b/include/alignment.h @@ -13,4 +13,16 @@ #define ALIGNED8 #endif +#ifdef __sgi /* IDO compiler */ +#define ALIGNOF(x) __builtin_alignof(x) +#elif (__STDC_VERSION__ >= 201112L) /* C11 */ +#define ALIGNOF(x) _Alignof(x) +#else /* __GNUC__ */ +#define ALIGNOF(x) __alignof__(x) +#endif + +#define ALIGN_MASK(n) (~((n) - 1)) + +#define ALIGNOF_MASK(x) ALIGN_MASK(ALIGNOF(x)) + #endif diff --git a/include/functions.h b/include/functions.h index 9a42f50ff7..3502a6dc96 100644 --- a/include/functions.h +++ b/include/functions.h @@ -1460,35 +1460,6 @@ void func_800C213C(PreRender* this, Gfx** gfxp); void PreRender_RestoreFramebuffer(PreRender* this, Gfx** gfxp); void PreRender_CopyImageRegion(PreRender* this, Gfx** gfxp); void PreRender_ApplyFilters(PreRender* this); -void THGA_Ct(TwoHeadGfxArena* thga, Gfx* start, u32 size); -void THGA_Dt(TwoHeadGfxArena* thga); -u32 THGA_IsCrash(TwoHeadGfxArena* thga); -void THGA_Init(TwoHeadGfxArena* thga); -s32 THGA_GetSize(TwoHeadGfxArena* thga); -Gfx* THGA_GetHead(TwoHeadGfxArena* thga); -void THGA_SetHead(TwoHeadGfxArena* thga, Gfx* start); -Gfx* THGA_GetTail(TwoHeadGfxArena* thga); -Gfx* THGA_AllocStartArray8(TwoHeadGfxArena* thga, u32 count); -Gfx* THGA_AllocStart8(TwoHeadGfxArena* thga); -Gfx* THGA_AllocStart8Wrapper(TwoHeadGfxArena* thga); -Gfx* THGA_AllocEnd(TwoHeadGfxArena* thga, u32 size); -Gfx* THGA_AllocEndArray64(TwoHeadGfxArena* thga, u32 count); -Gfx* THGA_AllocEnd64(TwoHeadGfxArena* thga); -Gfx* THGA_AllocEndArray16(TwoHeadGfxArena* thga, u32 count); -Gfx* THGA_AllocEnd16(TwoHeadGfxArena* thga); -void* THA_GetHead(TwoHeadArena* tha); -void THA_SetHead(TwoHeadArena* tha, void* start); -void* THA_GetTail(TwoHeadArena* tha); -void* THA_AllocStart(TwoHeadArena* tha, u32 size); -void* THA_AllocStart1(TwoHeadArena* tha); -void* THA_AllocEnd(TwoHeadArena* tha, u32 size); -void* THA_AllocEndAlign16(TwoHeadArena* tha, u32 size); -void* THA_AllocEndAlign(TwoHeadArena* tha, u32 size, u32 mask); -s32 THA_GetSize(TwoHeadArena* tha); -u32 THA_IsCrash(TwoHeadArena* tha); -void THA_Init(TwoHeadArena* tha); -void THA_Ct(TwoHeadArena* tha, void* ptr, u32 size); -void THA_Dt(TwoHeadArena* tha); void AudioMgr_StopAllSfx(void); void func_800C3C80(AudioMgr* audioMgr); void AudioMgr_HandleRetrace(AudioMgr* audioMgr); diff --git a/include/tha.h b/include/tha.h new file mode 100644 index 0000000000..1f086b0016 --- /dev/null +++ b/include/tha.h @@ -0,0 +1,28 @@ +#ifndef THA_H +#define THA_H + +#include "ultra64.h" +#include "alignment.h" + +typedef struct { + /* 0x00 */ size_t size; + /* 0x04 */ void* start; + /* 0x08 */ void* head; + /* 0x0C */ void* tail; +} TwoHeadArena; // size = 0x10 + +void* THA_GetHead(TwoHeadArena* tha); +void THA_SetHead(TwoHeadArena* tha, void* newHead); +void* THA_GetTail(TwoHeadArena* tha); +void* THA_AllocHead(TwoHeadArena* tha, size_t size); +void* THA_AllocHeadByte(TwoHeadArena* tha); +void* THA_AllocTail(TwoHeadArena* tha, size_t size); +void* THA_AllocTailAlign16(TwoHeadArena* tha, size_t size); +void* THA_AllocTailAlign(TwoHeadArena* tha, size_t size, uintptr_t mask); +s32 THA_GetRemaining(TwoHeadArena* tha); +u32 THA_IsCrash(TwoHeadArena* tha); +void THA_Reset(TwoHeadArena* tha); +void THA_Init(TwoHeadArena* tha, void* start, size_t size); +void THA_Destroy(TwoHeadArena* tha); + +#endif diff --git a/include/thga.h b/include/thga.h new file mode 100644 index 0000000000..9d9e96950a --- /dev/null +++ b/include/thga.h @@ -0,0 +1,33 @@ +#ifndef THGA_H +#define THGA_H + +#include "tha.h" + +typedef union { + /* 0x00 */ TwoHeadArena tha; + struct { // Same as TwoHeadArena, with different types and field names for the head and tail pointers + /* 0x00 */ size_t size; + /* 0x04 */ void* start; + /* 0x08 */ Gfx* p; + /* 0x0C */ void* d; + }; +} TwoHeadGfxArena; // size = 0x10 + +void THGA_Init(TwoHeadGfxArena* thga, void* start, size_t size); +void THGA_Destroy(TwoHeadGfxArena* thga); +u32 THGA_IsCrash(TwoHeadGfxArena* thga); +void THGA_Reset(TwoHeadGfxArena* thga); +s32 THGA_GetRemaining(TwoHeadGfxArena* thga); +Gfx* THGA_GetHead(TwoHeadGfxArena* thga); +void THGA_SetHead(TwoHeadGfxArena* thga, Gfx* newHead); +void* THGA_GetTail(TwoHeadGfxArena* thga); +Gfx* THGA_AllocDisplayList(TwoHeadGfxArena* thga, size_t num); +Gfx* THGA_AllocGfx(TwoHeadGfxArena* thga); +Gfx* THGA_AllocGfx2(TwoHeadGfxArena* thga); +void* THGA_AllocTail(TwoHeadGfxArena* thga, size_t size); +Mtx* THGA_AllocMtxArray(TwoHeadGfxArena* thga, size_t num); +Mtx* THGA_AllocMtx(TwoHeadGfxArena* thga); +Vtx* THGA_AllocVtxArray(TwoHeadGfxArena* thga, size_t num); +Vtx* THGA_AllocVtx(TwoHeadGfxArena* thga); + +#endif diff --git a/include/z64.h b/include/z64.h index 526921d074..8cfcfd160b 100644 --- a/include/z64.h +++ b/include/z64.h @@ -38,6 +38,8 @@ #include "fault.h" #include "sched.h" #include "rumble.h" +#include "tha.h" +#include "thga.h" #define SCREEN_WIDTH 320 #define SCREEN_HEIGHT 240 @@ -106,20 +108,6 @@ typedef struct { /* 0x12408 */ u16 tailMagic; // GFXPOOL_TAIL_MAGIC } GfxPool; // size = 0x12410 -typedef struct { - /* 0x0000 */ u32 size; - /* 0x0004 */ void* bufp; - /* 0x0008 */ void* head; - /* 0x000C */ void* tail; -} TwoHeadArena; // size = 0x10 - -typedef struct { - /* 0x0000 */ u32 size; - /* 0x0004 */ Gfx* bufp; - /* 0x0008 */ Gfx* p; - /* 0x000C */ Gfx* d; -} TwoHeadGfxArena; // size = 0x10 - typedef struct GraphicsContext { /* 0x0000 */ Gfx* polyOpaBuffer; // Pointer to "Zelda 0" /* 0x0004 */ Gfx* polyXluBuffer; // Pointer to "Zelda 1" diff --git a/spec b/spec index dd2dc1036b..a8a6dbb534 100644 --- a/spec +++ b/spec @@ -385,6 +385,7 @@ beginseg include "build/src/code/z_kaleido_scope_call.o" include "build/src/code/z_play.o" include "build/src/code/PreRender.o" + include "build/src/code/TwoHeadGfxArena.o" include "build/src/code/TwoHeadArena.o" include "build/src/code/code_800C3C20.o" include "build/src/code/audioMgr.o" diff --git a/src/code/TwoHeadArena.c b/src/code/TwoHeadArena.c index 3340604607..271c2ae7ff 100644 --- a/src/code/TwoHeadArena.c +++ b/src/code/TwoHeadArena.c @@ -1,140 +1,135 @@ +/** + * @file TwoHeadArena.c + * + * This file implements a simple general purpose double-ended stack allocator. + * + * A double-ended stack allocator accepts allocations at either the "head" or "tail" of its allotted memory region. + * While in general this type of allocator could accept deallocations on the most recently allocated block at either + * end, this implementation does not support any individual deallocations; the only provided way to deallocate anything + * is to reset the entire arena, deallocating everything. This scheme is most applicable to allocating similar data + * with identical lifetime. + */ #include "global.h" -void THGA_Ct(TwoHeadGfxArena* thga, Gfx* start, u32 size) { - THA_Ct((TwoHeadArena*)thga, start, size); -} - -void THGA_Dt(TwoHeadGfxArena* thga) { - THA_Dt((TwoHeadArena*)thga); -} - -u32 THGA_IsCrash(TwoHeadGfxArena* thga) { - return THA_IsCrash((TwoHeadArena*)thga); -} - -void THGA_Init(TwoHeadGfxArena* thga) { - THA_Init((TwoHeadArena*)thga); -} - -s32 THGA_GetSize(TwoHeadGfxArena* thga) { - return THA_GetSize((TwoHeadArena*)thga); -} - -Gfx* THGA_GetHead(TwoHeadGfxArena* thga) { - return THA_GetHead((TwoHeadArena*)thga); -} - -void THGA_SetHead(TwoHeadGfxArena* thga, Gfx* start) { - THA_SetHead((TwoHeadArena*)thga, start); -} - -Gfx* THGA_GetTail(TwoHeadGfxArena* thga) { - return THA_GetTail((TwoHeadArena*)thga); -} - -Gfx* THGA_AllocStartArray8(TwoHeadGfxArena* thga, u32 count) { - return THA_AllocStart((TwoHeadArena*)thga, count * 8); -} - -Gfx* THGA_AllocStart8(TwoHeadGfxArena* thga) { - return THGA_AllocStartArray8(thga, 1); -} - -Gfx* THGA_AllocStart8Wrapper(TwoHeadGfxArena* thga) { - return THGA_AllocStart8(thga); -} - -Gfx* THGA_AllocEnd(TwoHeadGfxArena* thga, u32 size) { - return THA_AllocEnd((TwoHeadArena*)thga, size); -} - -Gfx* THGA_AllocEndArray64(TwoHeadGfxArena* thga, u32 count) { - return THGA_AllocEnd(thga, count * 0x40); -} - -Gfx* THGA_AllocEnd64(TwoHeadGfxArena* thga) { - return THGA_AllocEnd(thga, 0x40); -} - -Gfx* THGA_AllocEndArray16(TwoHeadGfxArena* thga, u32 count) { - return THGA_AllocEnd(thga, count * 0x10); -} - -Gfx* THGA_AllocEnd16(TwoHeadGfxArena* thga) { - return THGA_AllocEnd(thga, 0x10); -} - void* THA_GetHead(TwoHeadArena* tha) { return tha->head; } -void THA_SetHead(TwoHeadArena* tha, void* start) { - tha->head = start; +void THA_SetHead(TwoHeadArena* tha, void* newHead) { + tha->head = newHead; } void* THA_GetTail(TwoHeadArena* tha) { return tha->tail; } -void* THA_AllocStart(TwoHeadArena* tha, u32 size) { +/** + * Allocates to the head of the Two Head Arena. The allocation will not have any alignment guarantees. + */ +void* THA_AllocHead(TwoHeadArena* tha, size_t size) { void* start = tha->head; - tha->head = (void*)((u32)tha->head + size); + tha->head = (u8*)tha->head + size; return start; } -void* THA_AllocStart1(TwoHeadArena* tha) { - return THA_AllocStart(tha, 1); +void* THA_AllocHeadByte(TwoHeadArena* tha) { + return THA_AllocHead(tha, 1); } -void* THA_AllocEnd(TwoHeadArena* tha, u32 size) { - u32 mask; +/** + * Allocates to the tail end of the Two Head Arena. The allocation will be aligned based on the size of the allocation. + * All allocations of 16 bytes or more will be aligned to 16-bytes. Otherwise, the alignment will be the largest power + * of 2 for which the size is a multiple, in order to accommodate the alignment requirements of any data types that can + * fit within the allocation. + */ +void* THA_AllocTail(TwoHeadArena* tha, size_t size) { + uintptr_t mask; if (size == 8) { - mask = ~7; + // Align 8 for multiples of 8 + mask = ALIGN_MASK(8); } else if (size == 4 || size == 12) { - mask = ~3; + // Align 4 for multiples of 4 + mask = ALIGN_MASK(4); } else if (size == 2 || size == 6 || size == 10 || size == 12 || size == 14) { - mask = ~1; + // Align 2 for multiples of 2 + mask = ALIGN_MASK(2); + } else if (size >= 0x10) { + // Align 0x10 for allocations greater than 0x10 + mask = ALIGN_MASK(0x10); } else { - mask = (size >= 0x10) ? ~0xF : 0; + //! @bug if size is less than 16 and odd the computation below will give NULL. The mask for this case would be + //! more sensible as ~0, for no extra alignment + mask = 0; } - tha->tail = (void*)((((u32)tha->tail & mask) - size) & mask); + tha->tail = (void*)((((uintptr_t)tha->tail & mask) - size) & mask); return tha->tail; } -void* THA_AllocEndAlign16(TwoHeadArena* tha, u32 size) { - u32 mask = ~0xF; +/** + * Allocates to the tail end of the Two Head Arena with guaranteed 16-byte alignment. + */ +void* THA_AllocTailAlign16(TwoHeadArena* tha, size_t size) { + uintptr_t mask = ALIGN_MASK(0x10); - tha->tail = (void*)((((u32)tha->tail & mask) - size) & (u32)(u64)mask); + tha->tail = (void*)((((uintptr_t)tha->tail & mask) - size) & (uintptr_t)(u64)mask); return tha->tail; } -void* THA_AllocEndAlign(TwoHeadArena* tha, u32 size, u32 mask) { - tha->tail = (void*)((((u32)tha->tail & mask) - size) & mask); +/** + * Allocates to the tail end of the Two Head Arena using the provided mask to align the allocated region. + * + * @param tha Arena to allocate to + * @param size Size of the allocation + * @param mask Mask to use to align the allocated region. To align to n-bytes where n is a power of 2, use the + * ALIGN_MASK(n) macro + * + * @return Pointer to the start of the allocated block + */ +void* THA_AllocTailAlign(TwoHeadArena* tha, size_t size, uintptr_t mask) { + tha->tail = (void*)((((uintptr_t)tha->tail & mask) - size) & mask); return tha->tail; } -s32 THA_GetSize(TwoHeadArena* tha) { - return (u32)tha->tail - (u32)tha->head; +/** + * Gets the remaining size of the Two Head Arena + * + * @return Remaining size. A negative number indicates an overflow. + */ +s32 THA_GetRemaining(TwoHeadArena* tha) { + return (s32)((u8*)tha->tail - (u8*)tha->head); } +/** + * @return true if the Two Head Arena has overflowed, false otherwise + */ u32 THA_IsCrash(TwoHeadArena* tha) { - return THA_GetSize(tha) < 0; + return THA_GetRemaining(tha) < 0; } -void THA_Init(TwoHeadArena* tha) { - tha->head = tha->bufp; - tha->tail = (void*)((u32)tha->bufp + tha->size); +/** + * Resets the head and tail positions of the Two Head Arena, all prior allocations are effectively considered free + * as any new allocations will begin to overwrite them. + */ +void THA_Reset(TwoHeadArena* tha) { + tha->head = tha->start; + tha->tail = (u8*)tha->start + tha->size; } -void THA_Ct(TwoHeadArena* tha, void* ptr, u32 size) { - tha->bufp = ptr; +/** + * Creates a new Two Head Arena at `start` with available size `size` + */ +void THA_Init(TwoHeadArena* tha, void* start, size_t size) { + tha->start = start; tha->size = size; - THA_Init(tha); + THA_Reset(tha); } -void THA_Dt(TwoHeadArena* tha) { +/** + * Destroys the Two Head Arena, no further allocations are possible + */ +void THA_Destroy(TwoHeadArena* tha) { bzero(tha, sizeof(TwoHeadArena)); } diff --git a/src/code/TwoHeadGfxArena.c b/src/code/TwoHeadGfxArena.c new file mode 100644 index 0000000000..ce7b8a45fb --- /dev/null +++ b/src/code/TwoHeadGfxArena.c @@ -0,0 +1,102 @@ +/** + * @file TwoHeadGfxArena.c + * + * This file implements a particular use of the double-ended stack allocator from TwoHeadArena.c for graphics data. + * + * Display list commands are allocated from the head while other graphics data such as matrices and vertices are + * allocated from the tail end. + * + * @see TwoHeadArena.c + */ +#include "global.h" + +void THGA_Init(TwoHeadGfxArena* thga, void* start, size_t size) { + THA_Init(&thga->tha, start, size); +} + +void THGA_Destroy(TwoHeadGfxArena* thga) { + THA_Destroy(&thga->tha); +} + +u32 THGA_IsCrash(TwoHeadGfxArena* thga) { + return THA_IsCrash(&thga->tha); +} + +void THGA_Reset(TwoHeadGfxArena* thga) { + THA_Reset(&thga->tha); +} + +s32 THGA_GetRemaining(TwoHeadGfxArena* thga) { + return THA_GetRemaining(&thga->tha); +} + +Gfx* THGA_GetHead(TwoHeadGfxArena* thga) { + return THA_GetHead(&thga->tha); +} + +void THGA_SetHead(TwoHeadGfxArena* thga, Gfx* newHead) { + THA_SetHead(&thga->tha, newHead); +} + +void* THGA_GetTail(TwoHeadGfxArena* thga) { + return THA_GetTail(&thga->tha); +} + +/** + * Allocates a display list of `num` Gfx commands to the head of the Two Head Gfx Arena. + */ +Gfx* THGA_AllocDisplayList(TwoHeadGfxArena* thga, size_t num) { + return THA_AllocHead(&thga->tha, num * sizeof(Gfx)); +} + +/** + * Allocates a single Gfx command to the head of the Two Head Gfx Arena. + */ +Gfx* THGA_AllocGfx(TwoHeadGfxArena* thga) { + return THGA_AllocDisplayList(thga, 1); +} + +/** + * Identical to `THGA_AllocGfx` + * + * @see THGA_AllocGfx + */ +Gfx* THGA_AllocGfx2(TwoHeadGfxArena* thga) { + return THGA_AllocGfx(thga); +} + +/** + * Allocates to the end of the Two Head Gfx Arena. Intended for data complementary to the display lists such as + * matrices and vertices that are only needed for a single graphics task. + */ +void* THGA_AllocTail(TwoHeadGfxArena* thga, size_t size) { + return THA_AllocTail(&thga->tha, size); +} + +/** + * Allocates `num` matrices to the tail end of the Two Head Gfx Arena. + */ +Mtx* THGA_AllocMtxArray(TwoHeadGfxArena* thga, size_t num) { + return THGA_AllocTail(thga, num * sizeof(Mtx)); +} + +/** + * Allocates a matrix to the tail end of the Two Head Gfx Arena. + */ +Mtx* THGA_AllocMtx(TwoHeadGfxArena* thga) { + return THGA_AllocTail(thga, sizeof(Mtx)); +} + +/** + * Allocates `num` vertices to the tail end of the Two Head Gfx Arena. + */ +Vtx* THGA_AllocVtxArray(TwoHeadGfxArena* thga, size_t num) { + return THGA_AllocTail(thga, num * sizeof(Vtx)); +} + +/** + * Allocates a vertex to the tail end of the Two Head Gfx Arena. + */ +Vtx* THGA_AllocVtx(TwoHeadGfxArena* thga) { + return THGA_AllocTail(thga, sizeof(Vtx)); +} diff --git a/src/code/game.c b/src/code/game.c index b004dd3676..88d2f5527e 100644 --- a/src/code/game.c +++ b/src/code/game.c @@ -173,7 +173,7 @@ void GameState_Draw(GameState* gameState, GraphicsContext* gfxCtx) { DebugArena_Display(); SystemArena_Display(); // "%08x bytes left until the death of Hyrule (game_alloc)" - osSyncPrintf("ハイラル滅亡まであと %08x バイト(game_alloc)\n", THA_GetSize(&gameState->tha)); + osSyncPrintf("ハイラル滅亡まであと %08x バイト(game_alloc)\n", THA_GetRemaining(&gameState->tha)); R_ENABLE_ARENA_DBG = 0; } @@ -325,10 +325,10 @@ void GameState_InitArena(GameState* gameState, size_t size) { osSyncPrintf("ハイラル確保 サイズ=%u バイト\n"); // "Hyrule reserved size = %u bytes" arena = GameAlloc_MallocDebug(&gameState->alloc, size, "../game.c", 992); if (arena != NULL) { - THA_Ct(&gameState->tha, arena, size); + THA_Init(&gameState->tha, arena, size); osSyncPrintf("ハイラル確保成功\n"); // "Successful Hyral" } else { - THA_Ct(&gameState->tha, NULL, 0); + THA_Init(&gameState->tha, NULL, 0); osSyncPrintf("ハイラル確保失敗\n"); // "Failure to secure Hyrule" Fault_AddHungupAndCrash("../game.c", 999); } @@ -340,10 +340,10 @@ void GameState_Realloc(GameState* gameState, size_t size) { u32 systemMaxFree; u32 systemFree; u32 systemAlloc; - void* thaBufp = gameState->tha.bufp; + void* thaStart = gameState->tha.start; - THA_Dt(&gameState->tha); - GameAlloc_Free(alloc, thaBufp); + THA_Destroy(&gameState->tha); + GameAlloc_Free(alloc, thaStart); osSyncPrintf("ハイラル一時解放!!\n"); // "Hyrule temporarily released!!" SystemArena_GetSizes(&systemMaxFree, &systemFree, &systemAlloc); if ((systemMaxFree - 0x10) < size) { @@ -360,10 +360,10 @@ void GameState_Realloc(GameState* gameState, size_t size) { osSyncPrintf("ハイラル再確保 サイズ=%u バイト\n", size); // "Hyral reallocate size = %u bytes" gameArena = GameAlloc_MallocDebug(alloc, size, "../game.c", 1033); if (gameArena != NULL) { - THA_Ct(&gameState->tha, gameArena, size); + THA_Init(&gameState->tha, gameArena, size); osSyncPrintf("ハイラル再確保成功\n"); // "Successful reacquisition of Hyrule" } else { - THA_Ct(&gameState->tha, NULL, 0); + THA_Init(&gameState->tha, NULL, 0); osSyncPrintf("ハイラル再確保失敗\n"); // "Failure to secure Hyral" SystemArena_Display(); Fault_AddHungupAndCrash("../game.c", 1044); @@ -441,7 +441,7 @@ void GameState_Destroy(GameState* gameState) { if (R_VI_MODE_EDIT_STATE == VI_MODE_EDIT_STATE_INACTIVE) { ViMode_Destroy(&sViMode); } - THA_Dt(&gameState->tha); + THA_Destroy(&gameState->tha); GameAlloc_Cleanup(&gameState->alloc); SystemArena_Display(); Fault_RemoveClient(&sGameFaultClient); @@ -467,13 +467,13 @@ void* GameState_Alloc(GameState* gameState, size_t size, char* file, s32 line) { if (THA_IsCrash(&gameState->tha)) { osSyncPrintf("ハイラルは滅亡している\n"); ret = NULL; - } else if ((u32)THA_GetSize(&gameState->tha) < size) { + } else if ((u32)THA_GetRemaining(&gameState->tha) < size) { // "Hyral on the verge of extinction does not have %d bytes left (%d bytes until extinction)" osSyncPrintf("滅亡寸前のハイラルには %d バイトの余力もない(滅亡まであと %d バイト)\n", size, - THA_GetSize(&gameState->tha)); + THA_GetRemaining(&gameState->tha)); ret = NULL; } else { - ret = THA_AllocEndAlign16(&gameState->tha, size); + ret = THA_AllocTailAlign16(&gameState->tha, size); if (THA_IsCrash(&gameState->tha)) { osSyncPrintf("ハイラルは滅亡してしまった\n"); // "Hyrule has been destroyed" ret = NULL; @@ -488,9 +488,9 @@ void* GameState_Alloc(GameState* gameState, size_t size, char* file, s32 line) { } void* GameState_AllocEndAlign16(GameState* gameState, size_t size) { - return THA_AllocEndAlign16(&gameState->tha, size); + return THA_AllocTailAlign16(&gameState->tha, size); } s32 GameState_GetArenaSize(GameState* gameState) { - return THA_GetSize(&gameState->tha); + return THA_GetRemaining(&gameState->tha); } diff --git a/src/code/graph.c b/src/code/graph.c index bbd87434cc..ba683b2670 100644 --- a/src/code/graph.c +++ b/src/code/graph.c @@ -93,10 +93,10 @@ void Graph_InitTHGA(GraphicsContext* gfxCtx) { pool->headMagic = GFXPOOL_HEAD_MAGIC; pool->tailMagic = GFXPOOL_TAIL_MAGIC; - THGA_Ct(&gfxCtx->polyOpa, pool->polyOpaBuffer, sizeof(pool->polyOpaBuffer)); - THGA_Ct(&gfxCtx->polyXlu, pool->polyXluBuffer, sizeof(pool->polyXluBuffer)); - THGA_Ct(&gfxCtx->overlay, pool->overlayBuffer, sizeof(pool->overlayBuffer)); - THGA_Ct(&gfxCtx->work, pool->workBuffer, sizeof(pool->workBuffer)); + THGA_Init(&gfxCtx->polyOpa, pool->polyOpaBuffer, sizeof(pool->polyOpaBuffer)); + THGA_Init(&gfxCtx->polyXlu, pool->polyXluBuffer, sizeof(pool->polyXluBuffer)); + THGA_Init(&gfxCtx->overlay, pool->overlayBuffer, sizeof(pool->overlayBuffer)); + THGA_Init(&gfxCtx->work, pool->workBuffer, sizeof(pool->workBuffer)); gfxCtx->polyOpaBuffer = pool->polyOpaBuffer; gfxCtx->polyXluBuffer = pool->polyXluBuffer; @@ -458,20 +458,20 @@ void* Graph_Alloc(GraphicsContext* gfxCtx, size_t size) { TwoHeadGfxArena* thga = &gfxCtx->polyOpa; if (HREG(59) == 1) { - osSyncPrintf("graph_alloc siz=%d thga size=%08x bufp=%08x head=%08x tail=%08x\n", size, thga->size, thga->bufp, + osSyncPrintf("graph_alloc siz=%d thga size=%08x bufp=%08x head=%08x tail=%08x\n", size, thga->size, thga->start, thga->p, thga->d); } - return THGA_AllocEnd(&gfxCtx->polyOpa, ALIGN16(size)); + return THGA_AllocTail(&gfxCtx->polyOpa, ALIGN16(size)); } void* Graph_Alloc2(GraphicsContext* gfxCtx, size_t size) { TwoHeadGfxArena* thga = &gfxCtx->polyOpa; if (HREG(59) == 1) { - osSyncPrintf("graph_alloc siz=%d thga size=%08x bufp=%08x head=%08x tail=%08x\n", size, thga->size, thga->bufp, + osSyncPrintf("graph_alloc siz=%d thga size=%08x bufp=%08x head=%08x tail=%08x\n", size, thga->size, thga->start, thga->p, thga->d); } - return THGA_AllocEnd(&gfxCtx->polyOpa, ALIGN16(size)); + return THGA_AllocTail(&gfxCtx->polyOpa, ALIGN16(size)); } void Graph_OpenDisps(Gfx** dispRefs, GraphicsContext* gfxCtx, const char* file, s32 line) { diff --git a/src/code/speed_meter.c b/src/code/speed_meter.c index f22680b566..5d38d65bf2 100644 --- a/src/code/speed_meter.c +++ b/src/code/speed_meter.c @@ -231,25 +231,26 @@ void SpeedMeter_DrawAllocEntries(SpeedMeter* meter, GraphicsContext* gfxCtx, Gam } thga = (TwoHeadGfxArena*)&state->tha; - SpeedMeter_InitAllocEntry(&entry, thga->size, thga->size - THA_GetSize((TwoHeadArena*)thga), + //! @bug THA_GetRemaining call should be THGA_GetRemaining like the others below, harmless as-is + SpeedMeter_InitAllocEntry(&entry, thga->size, thga->size - THA_GetRemaining(&thga->tha), GPACK_RGBA5551(0, 0, 255, 1), GPACK_RGBA5551(0, 255, 0, 1), ulx, lrx, y, y); SpeedMeter_DrawAllocEntry(&entry, gfxCtx); y++; thga = &gfxCtx->polyOpa; - SpeedMeter_InitAllocEntry(&entry, thga->size, thga->size - THGA_GetSize(thga), GPACK_RGBA5551(0, 0, 255, 1), + SpeedMeter_InitAllocEntry(&entry, thga->size, thga->size - THGA_GetRemaining(thga), GPACK_RGBA5551(0, 0, 255, 1), GPACK_RGBA5551(255, 0, 255, 1), ulx, lrx, y, y); SpeedMeter_DrawAllocEntry(&entry, gfxCtx); y++; thga = &gfxCtx->polyXlu; - SpeedMeter_InitAllocEntry(&entry, thga->size, thga->size - THGA_GetSize(thga), GPACK_RGBA5551(0, 0, 255, 1), + SpeedMeter_InitAllocEntry(&entry, thga->size, thga->size - THGA_GetRemaining(thga), GPACK_RGBA5551(0, 0, 255, 1), GPACK_RGBA5551(255, 255, 0, 1), ulx, lrx, y, y); SpeedMeter_DrawAllocEntry(&entry, gfxCtx); y++; thga = &gfxCtx->overlay; - SpeedMeter_InitAllocEntry(&entry, thga->size, thga->size - THGA_GetSize(thga), GPACK_RGBA5551(0, 0, 255, 1), + SpeedMeter_InitAllocEntry(&entry, thga->size, thga->size - THGA_GetRemaining(thga), GPACK_RGBA5551(0, 0, 255, 1), GPACK_RGBA5551(255, 0, 0, 1), ulx, lrx, y, y); SpeedMeter_DrawAllocEntry(&entry, gfxCtx); y++; diff --git a/src/code/z_bgcheck.c b/src/code/z_bgcheck.c index d3223433bc..1385bbc835 100644 --- a/src/code/z_bgcheck.c +++ b/src/code/z_bgcheck.c @@ -149,7 +149,7 @@ void DynaSSNodeList_Initialize(PlayState* play, DynaSSNodeList* nodeList) { * Initialize DynaSSNodeList tbl */ void DynaSSNodeList_Alloc(PlayState* play, DynaSSNodeList* nodeList, s32 max) { - nodeList->tbl = THA_AllocEndAlign(&play->state.tha, max * sizeof(SSNode), -2); + nodeList->tbl = THA_AllocTailAlign(&play->state.tha, max * sizeof(SSNode), ALIGNOF_MASK(SSNode)); ASSERT(nodeList->tbl != NULL, "psst->tbl != NULL", "../z_bgcheck.c", 1811); @@ -1613,9 +1613,10 @@ void BgCheck_Allocate(CollisionContext* colCtx, PlayState* play, CollisionHeader colCtx->subdivAmount.z = 16; } } - colCtx->lookupTbl = THA_AllocEndAlign( - &play->state.tha, - colCtx->subdivAmount.x * sizeof(StaticLookup) * colCtx->subdivAmount.y * colCtx->subdivAmount.z, ~1); + colCtx->lookupTbl = THA_AllocTailAlign(&play->state.tha, + colCtx->subdivAmount.x * sizeof(StaticLookup) * colCtx->subdivAmount.y * + colCtx->subdivAmount.z, + ALIGNOF_MASK(StaticLookup)); if (colCtx->lookupTbl == NULL) { LogUtils_HungupThread("../z_bgcheck.c", 4176); } @@ -2501,7 +2502,7 @@ void SSNodeList_Initialize(SSNodeList* this) { void SSNodeList_Alloc(PlayState* play, SSNodeList* this, s32 tblMax, s32 numPolys) { this->max = tblMax; this->count = 0; - this->tbl = THA_AllocEndAlign(&play->state.tha, tblMax * sizeof(SSNode), -2); + this->tbl = THA_AllocTailAlign(&play->state.tha, tblMax * sizeof(SSNode), ALIGNOF_MASK(SSNode)); ASSERT(this->tbl != NULL, "this->short_slist_node_tbl != NULL", "../z_bgcheck.c", 5975); @@ -2636,7 +2637,7 @@ void DynaPoly_NullPolyList(CollisionPoly** polyList) { * Allocate dyna.polyList */ void DynaPoly_AllocPolyList(PlayState* play, CollisionPoly** polyList, s32 numPolys) { - *polyList = THA_AllocEndAlign(&play->state.tha, numPolys * sizeof(CollisionPoly), -2); + *polyList = THA_AllocTailAlign(&play->state.tha, numPolys * sizeof(CollisionPoly), ALIGNOF_MASK(CollisionPoly)); ASSERT(*polyList != NULL, "ptbl->pbuf != NULL", "../z_bgcheck.c", 6247); } @@ -2651,7 +2652,7 @@ void DynaPoly_NullVtxList(Vec3s** vtxList) { * Allocate dyna.vtxList */ void DynaPoly_AllocVtxList(PlayState* play, Vec3s** vtxList, s32 numVtx) { - *vtxList = THA_AllocEndAlign(&play->state.tha, numVtx * sizeof(Vec3s), -2); + *vtxList = THA_AllocTailAlign(&play->state.tha, numVtx * sizeof(Vec3s), ALIGNOF_MASK(Vec3s)); ASSERT(*vtxList != NULL, "ptbl->pbuf != NULL", "../z_bgcheck.c", 6277); } diff --git a/src/code/z_play.c b/src/code/z_play.c index 24311b6010..b2fd9d5aaf 100644 --- a/src/code/z_play.c +++ b/src/code/z_play.c @@ -393,8 +393,8 @@ void Play_Init(GameState* thisx) { D_801614B0.a = 0; Flags_UnsetAllEnv(this); - osSyncPrintf("ZELDA ALLOC SIZE=%x\n", THA_GetSize(&this->state.tha)); - zAllocSize = THA_GetSize(&this->state.tha); + osSyncPrintf("ZELDA ALLOC SIZE=%x\n", THA_GetRemaining(&this->state.tha)); + zAllocSize = THA_GetRemaining(&this->state.tha); zAlloc = (u32)GameState_Alloc(&this->state, zAllocSize, "../z_play.c", 2918); zAllocAligned = (zAlloc + 8) & ~0xF; ZeldaArena_Init((void*)zAllocAligned, zAllocSize - zAllocAligned + zAlloc);