From c44e26a14356be233402fc98a44681c37ae45761 Mon Sep 17 00:00:00 2001 From: Anghelo Carvajal Date: Tue, 11 Jan 2022 20:25:14 -0300 Subject: [PATCH 01/13] `__osMalloc.c` OK (#395) * __osRealloc * match __osCheckArena * cleanup * Import bss, unreferenced strings and cleanup * format * Reviews * Move convert.h to ultra64/ * Make the os_malloc.h header * potato * renames and fixes * format * small doc pass } * format * minor changes * Introduce system_malloc.h * Docs pass * fix * format * stuff * Apply suggestions from code review Co-authored-by: EllipticEllipsis <73679967+EllipticEllipsis@users.noreply.github.com> * review * format * remove repeated sentence * Apply suggestions from code review Co-authored-by: Tharo <17233964+Thar0@users.noreply.github.com> * include headers * review * Rename __osMallocAddHeap * remove @brief * Update src/boot_O2/__osMalloc.c Co-authored-by: Derek Hensley Co-authored-by: EllipticEllipsis <73679967+EllipticEllipsis@users.noreply.github.com> Co-authored-by: Tharo <17233964+Thar0@users.noreply.github.com> Co-authored-by: Derek Hensley --- include/functions.h | 28 +- include/macros.h | 2 +- include/os_malloc.h | 35 ++ include/system_malloc.h | 20 + include/{ => ultra64}/convert.h | 4 +- include/variables.h | 2 - include/z64.h | 17 - spec | 2 - src/boot_O2/__osMalloc.c | 356 ++++++++++++++---- src/boot_O2/boot_800862E0.c | 1 + src/boot_O2/loadfragment.c | 1 + src/boot_O2/loadfragment2.c | 1 + src/boot_O2/system_malloc.c | 5 +- src/code/game.c | 3 +- src/code/gamealloc.c | 1 + src/code/graph.c | 1 + src/code/listalloc.c | 1 + src/code/speed_meter.c | 1 + src/code/sys_cmpdma.c | 1 + src/code/sys_flashrom.c | 1 + src/code/z_DLF.c | 1 + src/code/z_debug.c | 3 +- src/code/z_fbdemo.c | 1 + src/code/z_malloc.c | 9 +- src/code/z_vismono.c | 1 + src/overlays/actors/ovl_Eff_Dust/z_eff_dust.c | 1 + tools/disasm/functions.txt | 6 +- tools/sizes/boot_functions.csv | 6 +- 28 files changed, 376 insertions(+), 135 deletions(-) create mode 100644 include/os_malloc.h create mode 100644 include/system_malloc.h rename include/{ => ultra64}/convert.h (94%) diff --git a/include/functions.h b/include/functions.h index cfa7f4fad..3c20bca11 100644 --- a/include/functions.h +++ b/include/functions.h @@ -194,16 +194,7 @@ s32 func_80086D40(f64 param_1); f64 func_80086D6C(f64 param_1); s32 func_80086D8C(f32 param_1); s32 func_80086DAC(f64 param_1); -void* SystemArena_Malloc(size_t size); -void* SystemArena_MallocR(size_t size); -void* SystemArena_Realloc(void* oldPtr, size_t newSize); -void SystemArena_Free(void* ptr); -void* SystemArena_Calloc(u32 elements, size_t size); -void SystemArena_AnalyzeArena(size_t* maxFreeBlock, size_t* bytesFree, size_t* bytesAllocated); -u32 SystemArena_CheckArena(void); -void SystemArena_InitArena(void* start, size_t size); -void SystemArena_Cleanup(void); -u8 SystemArena_IsInitialized(void); + s32 Rand_Next(void); void Rand_Seed(u32 seed); f32 Rand_ZeroOne(void); @@ -212,20 +203,7 @@ void Rand_Seed_Variable(u32* rndNum, u32 seed); u32 Rand_Next_Variable(u32* param_1); f32 Rand_ZeroOne_Variable(u32* param_1); f32 Rand_Centered_Variable(u32* param_1); -void ArenaImpl_LockInit(Arena* heap); -void ArenaImpl_Lock(Arena* heap); -void ArenaImpl_Unlock(Arena* heap); -ArenaNode* ArenaImpl_GetLastBlock(Arena* param_1); -void __osMallocInit(Arena* heap, void* heapBase, size_t heapSize); -void __osMallocAddBlock(Arena* heap, void* start, s32 size); -void __osMallocCleanup(Arena* heap); -u8 __osMallocIsInitalized(Arena* heap); -void* __osMalloc(Arena* heap, size_t size); -void* __osMallocR(Arena* heap, size_t size); -void __osFree(Arena* heap, void* ptr); -void* __osRealloc(Arena* heap, void* oldPtr, size_t newSize); -void __osAnalyzeArena(Arena* heap, size_t* maxFreeBlock, size_t* bytesFree, size_t* bytesAllocated); -u32 __osCheckArena(Arena* heap); + void* proutSprintf(void* s, const char* buf, size_t n); s32 vsprintf(char* dst, char* fmt, va_list args); s32 sprintf(char* s, char* fmt, ...); @@ -1769,7 +1747,7 @@ void* ZeldaArena_Realloc(void* oldPtr, size_t newSize); void ZeldaArena_Free(void* param_1); void* ZeldaArena_Calloc(u32 num, size_t size); void ZeldaArena_GetSizes(size_t* maxFreeBlock, size_t* bytesFree, size_t* bytesAllocated); -void ZeldaArena_Check(); +s32 ZeldaArena_Check(); void ZeldaArena_Init(void* start, size_t size); void ZeldaArena_Cleanup(); u8 ZeldaArena_IsInitialized(); diff --git a/include/macros.h b/include/macros.h index 7e6104317..21593c13b 100644 --- a/include/macros.h +++ b/include/macros.h @@ -2,7 +2,7 @@ #define _MACROS_H_ #include "libc/stdint.h" -#include "convert.h" +#include "ultra64/convert.h" #include "z64.h" #define SCREEN_WIDTH 320 diff --git a/include/os_malloc.h b/include/os_malloc.h new file mode 100644 index 000000000..6b1cceab5 --- /dev/null +++ b/include/os_malloc.h @@ -0,0 +1,35 @@ +#ifndef OS_MALLOC +#define OS_MALLOC + +#include "PR/ultratypes.h" +#include "ultra64/message.h" +#include "libc/stddef.h" + +typedef struct ArenaNode { + /* 0x0 */ s16 magic; // Should always be 0x7373 + /* 0x2 */ s16 isFree; + /* 0x4 */ size_t size; + /* 0x8 */ struct ArenaNode* next; + /* 0xC */ struct ArenaNode* prev; +} ArenaNode; // size = 0x10 + +typedef struct { + /* 0x00 */ ArenaNode* head; + /* 0x04 */ void* start; + /* 0x08 */ OSMesgQueue lock; + /* 0x20 */ u8 unk20; + /* 0x21 */ u8 isInit; + /* 0x22 */ u8 flag; +} Arena; // size = 0x24 + +void __osMallocInit(Arena* arena, void* heap, size_t size); +void __osMallocCleanup(Arena* arena); +u8 __osMallocIsInitalized(Arena* arena); +void* __osMalloc(Arena* arena, size_t size); +void* __osMallocR(Arena* arena, size_t size); +void __osFree(Arena* arena, void* ptr); +void* __osRealloc(Arena* arena, void* ptr, size_t newSize); +void __osGetSizes(Arena* arena, size_t* maxFreeBlock, size_t* bytesFree, size_t* bytesAllocated); +s32 __osCheckArena(Arena* arena); + +#endif diff --git a/include/system_malloc.h b/include/system_malloc.h new file mode 100644 index 000000000..e92eaf89f --- /dev/null +++ b/include/system_malloc.h @@ -0,0 +1,20 @@ +#ifndef SYSTEM_MALLOC +#define SYSTEM_MALLOC + +#include "PR/ultratypes.h" +#include "os_malloc.h" + +void* SystemArena_Malloc(size_t size); +void* SystemArena_MallocR(size_t size); +void* SystemArena_Realloc(void* oldPtr, size_t newSize); +void SystemArena_Free(void* ptr); +void* SystemArena_Calloc(u32 elements, size_t size); +void SystemArena_GetSizes(size_t* maxFreeBlock, size_t* bytesFree, size_t* bytesAllocated); +u32 SystemArena_CheckArena(void); +void SystemArena_InitArena(void* start, size_t size); +void SystemArena_Cleanup(void); +u8 SystemArena_IsInitialized(void); + +extern Arena gSystemArena; + +#endif diff --git a/include/convert.h b/include/ultra64/convert.h similarity index 94% rename from include/convert.h rename to include/ultra64/convert.h index c453e18e3..59d8b801c 100644 --- a/include/convert.h +++ b/include/ultra64/convert.h @@ -1,5 +1,5 @@ -#ifndef _ULTRA64_CONVERT_H_ -#define _ULTRA64_CONVERT_H_ +#ifndef ULTRA64_CONVERT_H +#define ULTRA64_CONVERT_H #include "libc/stdint.h" diff --git a/include/variables.h b/include/variables.h index 6d1fc3ef9..cabe5d09e 100644 --- a/include/variables.h +++ b/include/variables.h @@ -322,7 +322,6 @@ extern StackEntry sFaultThreadInfo; extern FaultThreadStruct gFaultStruct; extern FaultDrawer sFaultDrawerStruct; // extern UNK_TYPE4 D_8009CD10; -// extern Arena gSystemArena; extern u32 sRandFloat; // extern UNK_TYPE4 sArenaLockMsg; extern OSTask tmp_task; @@ -3271,7 +3270,6 @@ extern s16 D_801F4E7A; // extern UNK_TYPE1 D_801F4F68; // extern UNK_TYPE1 D_801F4F6A; extern LightsBuffer sLightsBuffer; -extern Arena sZeldaArena; // extern UNK_TYPE1 D_801F5130; // extern UNK_TYPE1 D_801F5270; // extern UNK_TYPE1 D_801F528E; diff --git a/include/z64.h b/include/z64.h index 31eec335b..1aba77e7a 100644 --- a/include/z64.h +++ b/include/z64.h @@ -884,23 +884,6 @@ typedef struct { /* 0x120D8 */ UNK_TYPE1 pad120D8[0x8]; } MessageContext; // size = 0x120E0 -typedef struct ArenaNode { - /* 0x0 */ s16 magic; // Should always be 0x7373 - /* 0x2 */ s16 isFree; - /* 0x4 */ size_t size; - /* 0x8 */ struct ArenaNode* next; - /* 0xC */ struct ArenaNode* prev; -} ArenaNode; // size = 0x10 - -typedef struct { - /* 0x00 */ ArenaNode* head; - /* 0x04 */ void* start; - /* 0x08 */ OSMesgQueue lock; - /* 0x20 */ u8 unk20; - /* 0x21 */ u8 isInit; - /* 0x22 */ u8 flag; -} Arena; // size = 0x24 - typedef struct FaultAddrConvClient { /* 0x0 */ struct FaultAddrConvClient* next; /* 0x4 */ void* (*callback)(void*, void*); diff --git a/spec b/spec index aa2eacaea..10b3e560e 100644 --- a/spec +++ b/spec @@ -46,7 +46,6 @@ beginseg include "build/src/boot_O2/system_malloc.o" include "build/src/boot_O2/rand.o" include "build/src/boot_O2/__osMalloc.o" - include "build/data/boot/__osMalloc.bss.o" include "build/src/libultra/rmon/sprintf.o" include "build/src/boot_O2/printutils.o" include "build/src/boot_O2/sleep.o" @@ -491,7 +490,6 @@ beginseg include "build/src/code/z_lights.o" include "build/data/code/z_lights.bss.o" include "build/src/code/z_malloc.o" - include "build/data/code/z_malloc.bss.o" include "build/src/code/z_map_disp.o" include "build/data/code/z_map_disp.data.o" include "build/data/code/z_map_disp.bss.o" diff --git a/src/boot_O2/__osMalloc.c b/src/boot_O2/__osMalloc.c index c74c34866..24fa6d39e 100644 --- a/src/boot_O2/__osMalloc.c +++ b/src/boot_O2/__osMalloc.c @@ -1,4 +1,8 @@ -#include "global.h" +#include "os_malloc.h" +#include "libc/stdbool.h" +#include "libc/stdint.h" +#include "macros.h" +#include "functions.h" #define FILL_ALLOCBLOCK (1 << 0) #define FILL_FREEBLOCK (1 << 1) @@ -13,9 +17,9 @@ #define BLOCK_FREE_MAGIC (0xEF) #define BLOCK_FREE_MAGIC_32 (0xEFEFEFEF) -extern OSMesg sArenaLockMsg[1]; +OSMesg sArenaLockMsg[1]; -#pragma GLOBAL_ASM("asm/non_matchings/boot/__osMalloc/D_80099110.s") +void __osMallocAddHeap(Arena* arena, void* heap, size_t size); void ArenaImpl_LockInit(Arena* arena) { osCreateMesgQueue(&arena->lock, sArenaLockMsg, ARRAY_COUNT(sArenaLockMsg)); @@ -45,111 +49,184 @@ ArenaNode* ArenaImpl_GetLastBlock(Arena* arena) { return last; } -void __osMallocInit(Arena* arena, void* start, size_t size) { - bzero(arena, sizeof(*arena)); +/** + * Initializes \p arena to manage the memory region \p heap. + * + * @param arena The Arena to initialize. + * @param heap The memory region to use as heap space. + * @param size The size of the heap. + */ +void __osMallocInit(Arena* arena, void* heap, size_t size) { + bzero(arena, sizeof(Arena)); + ArenaImpl_LockInit(arena); - __osMallocAddBlock(arena, start, size); - arena->isInit = 1; + + __osMallocAddHeap(arena, heap, size); + arena->isInit = true; } -void __osMallocAddBlock(Arena* arena, void* start, s32 size) { - s32 diff; - s32 size2; +// Original name: __osMallocAddBlock +void __osMallocAddHeap(Arena* arena, void* heap, size_t size) { + ptrdiff_t diff; + s32 alignedSize; ArenaNode* firstNode; ArenaNode* lastNode; - if (start != NULL) { - firstNode = (ArenaNode*)ALIGN16((u32)start); - diff = (s32)firstNode - (s32)start; - size2 = (size - diff) & ~0xF; + if (heap == NULL) { + return; + } - if (size2 > (s32)sizeof(ArenaNode)) { - firstNode->next = NULL; - firstNode->prev = NULL; - firstNode->size = size2 - sizeof(ArenaNode); - firstNode->isFree = 1; - firstNode->magic = NODE_MAGIC; - ArenaImpl_Lock(arena); - lastNode = ArenaImpl_GetLastBlock(arena); - if (lastNode == NULL) { - arena->head = firstNode; - arena->start = start; - } else { - firstNode->prev = lastNode; - lastNode->next = firstNode; - } - ArenaImpl_Unlock(arena); + firstNode = (ArenaNode*)ALIGN16((uintptr_t)heap); + diff = (uintptr_t)firstNode - (uintptr_t)heap; + alignedSize = ((s32)size - diff) & ~0xF; + + // If the size of the heap is smaller than sizeof(ArenaNode), then the initialization will silently fail + if (alignedSize > (s32)sizeof(ArenaNode)) { + firstNode->next = NULL; + firstNode->prev = NULL; + firstNode->size = alignedSize - sizeof(ArenaNode); + firstNode->isFree = true; + firstNode->magic = NODE_MAGIC; + + ArenaImpl_Lock(arena); + + lastNode = ArenaImpl_GetLastBlock(arena); + + // Checks if there's already a block + if (lastNode == NULL) { + arena->head = firstNode; + arena->start = heap; + } else { + // Chain the existing block with the new one + firstNode->prev = lastNode; + lastNode->next = firstNode; } + + ArenaImpl_Unlock(arena); } } +/** + * Clears the whole \p arena, invalidating every allocated pointer to it. + * + * @param arena The Arena to clear. + */ void __osMallocCleanup(Arena* arena) { - bzero(arena, sizeof(*arena)); + bzero(arena, sizeof(Arena)); } +/** + * Returns whether or not the \p arena has been initialized. + * + * @param arena The Arena to check. + * @return u8 `true` if the \p arena has been initialized. `false` otherwise. + */ u8 __osMallocIsInitalized(Arena* arena) { return arena->isInit; } +/** + * Allocates at least \p size bytes of memory using the given \p arena. + * The block of memory will be allocated at the start of the first sufficiently large free block. + * + * - If there's not enough space in the given \p arena, this function will fail, returning `NULL`. + * - If \p size is zero, then an empty region of memory is returned. + * + * To avoid memory leaks, the returned pointer should be eventually deallocated using either `__osFree` or + * `__osRealloc`. + * + * @param[in, out] arena The specific Arena to be used for the allocation. + * @param[in] size The size in bytes that will be allocated. + * @return void* On success, the allocated area of the \p arena memory. Otherwise, `NULL`. + */ void* __osMalloc(Arena* arena, size_t size) { ArenaNode* iter; ArenaNode* newNode; - void* alloc; - u32 blockSize; - alloc = NULL; + void* alloc = NULL; size = ALIGN16(size); + ArenaImpl_Lock(arena); + + // Start iterating from the head of the arena. iter = arena->head; + // Iterate over the arena looking for a big enough space of memory. while (iter != NULL) { if (iter->isFree && iter->size >= size) { - ArenaNode* next; - blockSize = ALIGN16(size) + sizeof(ArenaNode); + size_t blockSize = ALIGN16(size) + sizeof(ArenaNode); + + // If the block is larger than the requested size, then split it and just use the required size of the + // current block. if (blockSize < iter->size) { - newNode = (ArenaNode*)((u32)iter + blockSize); + ArenaNode* next; + + newNode = (ArenaNode*)((uintptr_t)iter + blockSize); newNode->next = iter->next; newNode->prev = iter; newNode->size = iter->size - blockSize; - newNode->isFree = 1; + newNode->isFree = true; newNode->magic = NODE_MAGIC; iter->next = newNode; iter->size = size; + next = newNode->next; - if (next) { + if (next != NULL) { next->prev = newNode; } } - iter->isFree = 0; - alloc = (void*)((u32)iter + sizeof(ArenaNode)); + iter->isFree = false; + alloc = (void*)((uintptr_t)iter + sizeof(ArenaNode)); break; } iter = iter->next; } + ArenaImpl_Unlock(arena); return alloc; } +/** + * Allocates at least \p size bytes of memory using the given \p arena. + * Unlike __osMalloc, the block of memory will be allocated from the end of the \p arena. + * + * - If there's not enough space in the given \p arena, this function will fail, returning `NULL`. + * - If \p size is zero, then an empty region of memory is returned. + * + * To avoid memory leaks, the returned pointer should be eventually deallocated using `__osFree` or `__osRealloc`. + * + * @param[in, out] arena The specific Arena to be used for the allocation. + * @param[in] size The size in bytes that will be allocated. + * @return void* On success, the allocated area of the \p arena memory. Otherwise, `NULL`. + */ void* __osMallocR(Arena* arena, size_t size) { ArenaNode* iter; ArenaNode* newNode; - u32 blockSize; + size_t blockSize; void* alloc = NULL; size = ALIGN16(size); + ArenaImpl_Lock(arena); + + // Start iterating from the last block of the arena. iter = ArenaImpl_GetLastBlock(arena); + // Iterate in reverse the arena looking for a big enough space of memory. while (iter != NULL) { if (iter->isFree && iter->size >= size) { - ArenaNode* next; blockSize = ALIGN16(size) + sizeof(ArenaNode); + + // If the block is larger than the requested size, then split it and just use the required size of the + // current block. if (blockSize < iter->size) { - newNode = (ArenaNode*)((u32)iter + (iter->size - size)); + ArenaNode* next; + + newNode = (ArenaNode*)((uintptr_t)iter + (iter->size - size)); newNode->next = iter->next; newNode->prev = iter; newNode->size = size; @@ -157,69 +234,171 @@ void* __osMallocR(Arena* arena, size_t size) { iter->next = newNode; iter->size -= blockSize; + next = newNode->next; - if (next) { + if (next != NULL) { next->prev = newNode; } iter = newNode; } - iter->isFree = 0; - alloc = (void*)((u32)iter + sizeof(ArenaNode)); + iter->isFree = false; + alloc = (void*)((uintptr_t)iter + sizeof(ArenaNode)); break; } iter = iter->prev; } + ArenaImpl_Unlock(arena); return alloc; } +/** + * Deallocates the pointer \p ptr previously allocated by `__osMalloc`, `__osMallocR` or `__osRealloc`. + * If \p ptr is `NULL` or it has been already been freed, then this function does nothing. + * + * - The behaviour is undefined if \p ptr is not a memory region returned by one of the cited allocating + * functions. + * - The behaviour is undefined if \p ptr doesn't correspond to the given \p arena. + * - Any access to the freed pointer is undefined behaviour. + * + * @param[in, out] arena The specific Arena to be used for the allocation. + * @param[in, out] ptr The allocated memory block to deallocate. + */ void __osFree(Arena* arena, void* ptr) { ArenaNode* node; ArenaNode* next; ArenaNode* prev; - ArenaNode* newNext; ArenaImpl_Lock(arena); + node = (ArenaNode*)((uintptr_t)ptr - sizeof(ArenaNode)); - if (ptr == NULL || (node->magic != NODE_MAGIC) || node->isFree) { - goto end; - } + if (ptr != NULL && node->magic == NODE_MAGIC && !node->isFree) { + next = node->next; + prev = node->prev; + node->isFree = true; - next = node->next; - prev = node->prev; - node->isFree = true; + // Checks if the next node is contiguous to the current node and if it isn't currently allocated. Then merge the + // two nodes into one. + if ((uintptr_t)next == (uintptr_t)node + sizeof(ArenaNode) + node->size && next->isFree) { + ArenaNode* newNext = next->next; - newNext = next; - if ((uintptr_t)next == (uintptr_t)node + sizeof(ArenaNode) + node->size && next->isFree) { - newNext = next->next; - if (newNext != NULL) { - newNext->prev = node; + if (newNext != NULL) { + newNext->prev = node; + } + + node->size += next->size + sizeof(ArenaNode); + + node->next = newNext; + next = newNext; } - node->size += next->size + sizeof(ArenaNode); + // Checks if the previous node is contiguous to the current node and if it isn't currently allocated. Then merge + // the two nodes into one. + if (prev != NULL && prev->isFree && (uintptr_t)node == (uintptr_t)prev + sizeof(ArenaNode) + prev->size) { + if (next != NULL) { + next->prev = prev; + } - node->next = newNext; - next = newNext; - } - - if (prev != NULL && prev->isFree && (uintptr_t)node == (uintptr_t)prev + sizeof(ArenaNode) + prev->size) { - if (next) { - next->prev = prev; + prev->next = next; + prev->size += node->size + sizeof(ArenaNode); } - prev->next = next; - prev->size += node->size + sizeof(ArenaNode); } -end: ArenaImpl_Unlock(arena); } -#pragma GLOBAL_ASM("asm/non_matchings/boot/__osMalloc/__osRealloc.s") +/** + * Reallocates the pointer \p ptr. + * \p ptr must be either a pointer previously allocated by `__osMalloc`, `__osMallocR` or `__osRealloc` and + * not freed yet, or a `NULL` pointer. + * + * - If \p ptr is `NULL` a new pointer is allocated. See `__osMalloc` for more details. + * - If \p newSize is 0, then the given pointer is freed and `NULL` is returned. See `__osFree` for more details. + * - If \p newSize is bigger than the currently allocated allocated pointer, then the area of memory is expanded to a + * size big enough to fit the requested size. + * + * - The behaviour is undefined if \p ptr is not a memory region returned by one of the cited allocating + * functions. + * - The behaviour is undefined if \p ptr doesn't correspond to the given \p arena. + * - If the pointer is freed, then any access to the original freed pointer is undefined behaviour. + * + * @param[in, out] arena The specific Arena to be used for the allocation. + * @param[in, out] ptr The allocated memory block to deallocate. + * @param[in] newSize The new requested size. + * @return void* On success, the pointer to the reallocated area of memory. On failure, `NULL` is returned, + * and the original parameter \p ptr remains valid. + */ +void* __osRealloc(Arena* arena, void* ptr, size_t newSize) { + ArenaImpl_Lock(arena); -void __osAnalyzeArena(Arena* arena, size_t* outMaxFree, size_t* outFree, size_t* outAlloc) { + (void)"__osRealloc(%08x, %d)\n"; + + if (ptr == NULL) { + // if the `ptr` is NULL, then allocate a new pointer with the specified size + // if newSize is 0, then __osMalloc would return a NULL pointer + ptr = __osMalloc(arena, newSize); + } else if (newSize == 0) { + // if the requested size is zero, then free the pointer + __osFree(arena, ptr); + ptr = NULL; + } else { + size_t diff; + void* newPtr; + // Gets the start of the ArenaNode pointer embedded + ArenaNode* node = (void*)((uintptr_t)ptr - sizeof(ArenaNode)); + + newSize = ALIGN16(newSize); + + // Only reallocate the memory if the new size isn't smaller than the actual node size + if ((newSize != node->size) && (node->size < newSize)) { + ArenaNode* next = node->next; + + diff = newSize - node->size; + // Checks if the next node is contiguous to the current allocated node and it has enough space to fit the + // new requested size + if (((uintptr_t)next == (uintptr_t)node + node->size + sizeof(ArenaNode)) && (next->isFree) && + (next->size >= diff)) { + ArenaNode* next2 = next->next; + + next->size = (next->size - diff); + if (next2 != NULL) { + // Update the previous element of the linked list + next2->prev = (void*)((uintptr_t)next + diff); + } + + next2 = (void*)((uintptr_t)next + diff); + node->next = next2; + node->size = newSize; + __osMemcpy(next2, next, sizeof(ArenaNode)); + } else { + // Create a new pointer and manually copy the data from the old pointer to the new one + newPtr = __osMalloc(arena, newSize); + if (newPtr != NULL) { + bcopy(newPtr, ptr, node->size); + __osFree(arena, ptr); + } + ptr = newPtr; + } + } + } + + ArenaImpl_Unlock(arena); + + return ptr; +} + +/** + * Gets the size of the largest free block, the total free space and the total allocated space. + * + * @param[in, out] arena The Arena which will be used to get the values from. + * @param[out] outMaxFree The size of the largest free block. + * @param[out] outFree The total free space. + * @param[out] outAlloc The total allocated space. + */ +void __osGetSizes(Arena* arena, size_t* outMaxFree, size_t* outFree, size_t* outAlloc) { ArenaNode* iter; ArenaImpl_Lock(arena); @@ -245,4 +424,35 @@ void __osAnalyzeArena(Arena* arena, size_t* outMaxFree, size_t* outFree, size_t* ArenaImpl_Unlock(arena); } -#pragma GLOBAL_ASM("asm/non_matchings/boot/__osMalloc/__osCheckArena.s") +/** + * Checks the validity of every node of the \p arena. + * + * @param arena The Arena to check. + * @return s32 0 if every pointer is valid. 1 otherwise. + */ +s32 __osCheckArena(Arena* arena) { + ArenaNode* iter; + s32 err = 0; + + ArenaImpl_Lock(arena); + + // "Checking the contents of the arena..." + (void)"アリーナの内容をチェックしています... (%08x)\n"; + + for (iter = arena->head; iter != NULL; iter = iter->next) { + if (iter->magic != NODE_MAGIC) { + // "Oops!!" + (void)"おおっと!! (%08x %08x)\n"; + + err = 1; + break; + } + } + + // "The arena still looks good" + (void)"アリーナはまだ、いけそうです\n"; + + ArenaImpl_Unlock(arena); + + return err; +} diff --git a/src/boot_O2/boot_800862E0.c b/src/boot_O2/boot_800862E0.c index ecba8c5f5..1055dfe1b 100644 --- a/src/boot_O2/boot_800862E0.c +++ b/src/boot_O2/boot_800862E0.c @@ -1,4 +1,5 @@ #include "global.h" +#include "os_malloc.h" #pragma GLOBAL_ASM("asm/non_matchings/boot/boot_800862E0/SystemArena_MallocMin1.s") diff --git a/src/boot_O2/loadfragment.c b/src/boot_O2/loadfragment.c index 4589cd359..968fb464a 100644 --- a/src/boot_O2/loadfragment.c +++ b/src/boot_O2/loadfragment.c @@ -1,4 +1,5 @@ #include "global.h" +#include "system_malloc.h" #pragma GLOBAL_ASM("asm/non_matchings/boot/loadfragment/Load_Relocate.s") diff --git a/src/boot_O2/loadfragment2.c b/src/boot_O2/loadfragment2.c index 5c884be96..c324b80d5 100644 --- a/src/boot_O2/loadfragment2.c +++ b/src/boot_O2/loadfragment2.c @@ -1,4 +1,5 @@ #include "global.h" +#include "system_malloc.h" UNK_TYPE4 D_80096C30 = 2; diff --git a/src/boot_O2/system_malloc.c b/src/boot_O2/system_malloc.c index ad2bb6345..56608166c 100644 --- a/src/boot_O2/system_malloc.c +++ b/src/boot_O2/system_malloc.c @@ -1,4 +1,5 @@ #include "global.h" +#include "os_malloc.h" Arena gSystemArena; @@ -29,8 +30,8 @@ void* SystemArena_Calloc(u32 elements, size_t size) { return ptr; } -void SystemArena_AnalyzeArena(size_t* maxFreeBlock, size_t* bytesFree, size_t* bytesAllocated) { - __osAnalyzeArena(&gSystemArena, maxFreeBlock, bytesFree, bytesAllocated); +void SystemArena_GetSizes(size_t* maxFreeBlock, size_t* bytesFree, size_t* bytesAllocated) { + __osGetSizes(&gSystemArena, maxFreeBlock, bytesFree, bytesAllocated); } u32 SystemArena_CheckArena(void) { diff --git a/src/code/game.c b/src/code/game.c index e431fafda..2713be299 100644 --- a/src/code/game.c +++ b/src/code/game.c @@ -1,4 +1,5 @@ #include "global.h" +#include "system_malloc.h" s32 gFramerateDivisor = 1; f32 gFramerateDivisorF = 1.0f; @@ -174,7 +175,7 @@ void GameState_Realloc(GameState* gameState, size_t size) { alloc = &gameState->alloc; THA_Dt(&gameState->heap); GameAlloc_Free(alloc, heapStart); - SystemArena_AnalyzeArena(&systemMaxFree, &bytesFree, &bytesAllocated); + SystemArena_GetSizes(&systemMaxFree, &bytesFree, &bytesAllocated); size = ((systemMaxFree - (sizeof(ArenaNode))) < size) ? (0) : (size); if (size == 0) { size = systemMaxFree - (sizeof(ArenaNode)); diff --git a/src/code/gamealloc.c b/src/code/gamealloc.c index 541f9125b..6067ad91c 100644 --- a/src/code/gamealloc.c +++ b/src/code/gamealloc.c @@ -1,4 +1,5 @@ #include "global.h" +#include "system_malloc.h" void GameAlloc_Log(GameAlloc* this) { GameAllocEntry* iter; diff --git a/src/code/graph.c b/src/code/graph.c index e09cfedc4..8059d1f63 100644 --- a/src/code/graph.c +++ b/src/code/graph.c @@ -1,5 +1,6 @@ #include "prevent_bss_reordering.h" #include "global.h" +#include "system_malloc.h" #include "overlays/gamestates/ovl_daytelop/z_daytelop.h" #include "overlays/gamestates/ovl_file_choose/z_file_choose.h" #include "overlays/gamestates/ovl_opening/z_opening.h" diff --git a/src/code/listalloc.c b/src/code/listalloc.c index da294a109..33f9989ba 100644 --- a/src/code/listalloc.c +++ b/src/code/listalloc.c @@ -1,4 +1,5 @@ #include "global.h" +#include "system_malloc.h" ListAlloc* ListAlloc_Init(ListAlloc* this) { this->prev = NULL; diff --git a/src/code/speed_meter.c b/src/code/speed_meter.c index b8b0299eb..9f04de110 100644 --- a/src/code/speed_meter.c +++ b/src/code/speed_meter.c @@ -1,4 +1,5 @@ #include "global.h" +#include "system_malloc.h" #pragma GLOBAL_ASM("asm/non_matchings/code/speed_meter/func_80177390.s") diff --git a/src/code/sys_cmpdma.c b/src/code/sys_cmpdma.c index c670645fc..2533c44f5 100644 --- a/src/code/sys_cmpdma.c +++ b/src/code/sys_cmpdma.c @@ -1,4 +1,5 @@ #include "global.h" +#include "system_malloc.h" #pragma GLOBAL_ASM("asm/non_matchings/code/sys_cmpdma/func_80178750.s") diff --git a/src/code/sys_flashrom.c b/src/code/sys_flashrom.c index 1431e7a66..8b6c2fa5c 100644 --- a/src/code/sys_flashrom.c +++ b/src/code/sys_flashrom.c @@ -1,4 +1,5 @@ #include "global.h" +#include "system_malloc.h" #pragma GLOBAL_ASM("asm/non_matchings/code/sys_flashrom/func_801857C0.s") diff --git a/src/code/z_DLF.c b/src/code/z_DLF.c index 688a5af15..4c57aca01 100644 --- a/src/code/z_DLF.c +++ b/src/code/z_DLF.c @@ -1,4 +1,5 @@ #include "global.h" +#include "system_malloc.h" #pragma GLOBAL_ASM("asm/non_matchings/code/z_DLF/Overlay_LoadGameState.s") diff --git a/src/code/z_debug.c b/src/code/z_debug.c index 924a2ad30..46649a4ce 100644 --- a/src/code/z_debug.c +++ b/src/code/z_debug.c @@ -1,11 +1,12 @@ #include "global.h" +#include "system_malloc.h" GameInfo* gGameInfo; void GameInfo_Init(void) { s32 i; - gGameInfo = (GameInfo*)SystemArena_Malloc(sizeof(GameInfo)); + gGameInfo = SystemArena_Malloc(sizeof(GameInfo)); if (1) {} gGameInfo->unk_00 = 0; gGameInfo->unk_01 = 0; diff --git a/src/code/z_fbdemo.c b/src/code/z_fbdemo.c index c2da6f9ce..3d33399e5 100644 --- a/src/code/z_fbdemo.c +++ b/src/code/z_fbdemo.c @@ -1,4 +1,5 @@ #include "global.h" +#include "system_malloc.h" #pragma GLOBAL_ASM("asm/non_matchings/code/z_fbdemo/func_80163DC0.s") diff --git a/src/code/z_malloc.c b/src/code/z_malloc.c index 8d0bba44a..781f4310e 100644 --- a/src/code/z_malloc.c +++ b/src/code/z_malloc.c @@ -1,4 +1,7 @@ #include "global.h" +#include "os_malloc.h" + +Arena sZeldaArena; void* ZeldaArena_Malloc(size_t size) { void* ptr = __osMalloc(&sZeldaArena, size); @@ -34,11 +37,11 @@ void* ZeldaArena_Calloc(u32 num, size_t size) { } void ZeldaArena_GetSizes(size_t* outMaxFree, size_t* outFree, size_t* outAlloc) { - __osAnalyzeArena(&sZeldaArena, outMaxFree, outFree, outAlloc); + __osGetSizes(&sZeldaArena, outMaxFree, outFree, outAlloc); } -void ZeldaArena_Check() { - __osCheckArena(&sZeldaArena); +s32 ZeldaArena_Check() { + return __osCheckArena(&sZeldaArena); } void ZeldaArena_Init(void* start, size_t size) { diff --git a/src/code/z_vismono.c b/src/code/z_vismono.c index 4e02a0af2..6c0d1ef22 100644 --- a/src/code/z_vismono.c +++ b/src/code/z_vismono.c @@ -1,4 +1,5 @@ #include "global.h" +#include "system_malloc.h" #pragma GLOBAL_ASM("asm/non_matchings/code/z_vismono/func_801418B0.s") diff --git a/src/overlays/actors/ovl_Eff_Dust/z_eff_dust.c b/src/overlays/actors/ovl_Eff_Dust/z_eff_dust.c index 296d6e429..697ea58e8 100644 --- a/src/overlays/actors/ovl_Eff_Dust/z_eff_dust.c +++ b/src/overlays/actors/ovl_Eff_Dust/z_eff_dust.c @@ -5,6 +5,7 @@ */ #include "z_eff_dust.h" +#include "system_malloc.h" #define FLAGS 0x00000030 diff --git a/tools/disasm/functions.txt b/tools/disasm/functions.txt index 7466934fb..69ca079a9 100644 --- a/tools/disasm/functions.txt +++ b/tools/disasm/functions.txt @@ -204,7 +204,7 @@ 0x80086E20:("SystemArena_Realloc",), 0x80086E50:("SystemArena_Free",), 0x80086E78:("SystemArena_Calloc",), - 0x80086ECC:("SystemArena_AnalyzeArena",), + 0x80086ECC:("SystemArena_GetSizes",), 0x80086F04:("SystemArena_CheckArena",), 0x80086F28:("SystemArena_InitArena",), 0x80086F58:("SystemArena_Cleanup",), @@ -222,14 +222,14 @@ 0x800871B4:("ArenaImpl_Unlock",), 0x800871DC:("ArenaImpl_GetLastBlock",), 0x8008720C:("__osMallocInit",), - 0x8008725C:("__osMallocAddBlock",), + 0x8008725C:("__osMallocAddHeap",), 0x800872FC:("__osMallocCleanup",), 0x8008731C:("__osMallocIsInitalized",), 0x80087324:("__osMalloc",), 0x80087408:("__osMallocR",), 0x800874EC:("__osFree",), 0x800875E4:("__osRealloc",), - 0x80087714:("__osAnalyzeArena",), + 0x80087714:("__osGetSizes",), 0x800877C4:("__osCheckArena",), 0x80087830:("proutSprintf",), 0x80087854:("vsprintf",), diff --git a/tools/sizes/boot_functions.csv b/tools/sizes/boot_functions.csv index 46e57b75c..3685e3fa9 100644 --- a/tools/sizes/boot_functions.csv +++ b/tools/sizes/boot_functions.csv @@ -201,7 +201,7 @@ asm/non_matchings/boot/system_malloc/SystemArena_MallocR.s,SystemArena_MallocR,0 asm/non_matchings/boot/system_malloc/SystemArena_Realloc.s,SystemArena_Realloc,0x80086E20,0xC asm/non_matchings/boot/system_malloc/SystemArena_Free.s,SystemArena_Free,0x80086E50,0xA asm/non_matchings/boot/system_malloc/SystemArena_Calloc.s,SystemArena_Calloc,0x80086E78,0x15 -asm/non_matchings/boot/system_malloc/SystemArena_AnalyzeArena.s,SystemArena_AnalyzeArena,0x80086ECC,0xE +asm/non_matchings/boot/system_malloc/SystemArena_GetSizes.s,SystemArena_GetSizes,0x80086ECC,0xE asm/non_matchings/boot/system_malloc/SystemArena_CheckArena.s,SystemArena_CheckArena,0x80086F04,0x9 asm/non_matchings/boot/system_malloc/SystemArena_InitArena.s,SystemArena_InitArena,0x80086F28,0xC asm/non_matchings/boot/system_malloc/SystemArena_Cleanup.s,SystemArena_Cleanup,0x80086F58,0x9 @@ -219,14 +219,14 @@ asm/non_matchings/boot/__osMalloc/ArenaImpl_Lock.s,ArenaImpl_Lock,0x8008718C,0xA asm/non_matchings/boot/__osMalloc/ArenaImpl_Unlock.s,ArenaImpl_Unlock,0x800871B4,0xA asm/non_matchings/boot/__osMalloc/ArenaImpl_GetLastBlock.s,ArenaImpl_GetLastBlock,0x800871DC,0xC asm/non_matchings/boot/__osMalloc/__osMallocInit.s,__osMallocInit,0x8008720C,0x14 -asm/non_matchings/boot/__osMalloc/__osMallocAddBlock.s,__osMallocAddBlock,0x8008725C,0x28 +asm/non_matchings/boot/__osMalloc/__osMallocAddHeap.s,__osMallocAddHeap,0x8008725C,0x28 asm/non_matchings/boot/__osMalloc/__osMallocCleanup.s,__osMallocCleanup,0x800872FC,0x8 asm/non_matchings/boot/__osMalloc/__osMallocIsInitalized.s,__osMallocIsInitalized,0x8008731C,0x2 asm/non_matchings/boot/__osMalloc/__osMalloc.s,__osMalloc,0x80087324,0x39 asm/non_matchings/boot/__osMalloc/__osMallocR.s,__osMallocR,0x80087408,0x39 asm/non_matchings/boot/__osMalloc/__osFree.s,__osFree,0x800874EC,0x3E asm/non_matchings/boot/__osMalloc/__osRealloc.s,__osRealloc,0x800875E4,0x4C -asm/non_matchings/boot/__osMalloc/__osAnalyzeArena.s,__osAnalyzeArena,0x80087714,0x2C +asm/non_matchings/boot/__osMalloc/__osGetSizes.s,__osGetSizes,0x80087714,0x2C asm/non_matchings/boot/__osMalloc/__osCheckArena.s,__osCheckArena,0x800877C4,0x1B asm/non_matchings/boot/sprintf/proutSprintf.s,proutSprintf,0x80087830,0x9 asm/non_matchings/boot/sprintf/vsprintf.s,vsprintf,0x80087854,0x14 From 816971d98cc6d1fcdffce3db6e16a1ef805567f6 Mon Sep 17 00:00:00 2001 From: Maide <34639600+Kelebek1@users.noreply.github.com> Date: Wed, 12 Jan 2022 15:37:26 +0000 Subject: [PATCH 02/13] En_Kanban (1 non-matching) (#419) * En_Kanban * PR * PR * Object * undef * PR * Merge * Merge * Merge --- assets/xml/overlays/ovl_En_Kanban.xml | 9 + include/macros.h | 2 +- spec | 5 +- .../actors/ovl_En_Kanban/z_en_kanban.c | 1016 ++++++++++++++++- .../actors/ovl_En_Kanban/z_en_kanban.h | 95 +- .../actors/ovl_En_Kanban/z_en_kanban_gfx.c | 68 ++ tools/disasm/variables.txt | 10 +- 7 files changed, 1184 insertions(+), 21 deletions(-) create mode 100644 assets/xml/overlays/ovl_En_Kanban.xml create mode 100644 src/overlays/actors/ovl_En_Kanban/z_en_kanban_gfx.c diff --git a/assets/xml/overlays/ovl_En_Kanban.xml b/assets/xml/overlays/ovl_En_Kanban.xml new file mode 100644 index 000000000..386cfc663 --- /dev/null +++ b/assets/xml/overlays/ovl_En_Kanban.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/include/macros.h b/include/macros.h index 21593c13b..c5fc2c4ae 100644 --- a/include/macros.h +++ b/include/macros.h @@ -45,7 +45,7 @@ // linkAge still exists in MM, but is always set to 0 (always adult) // There are remnants of these macros from OOT, but they are essentially useless -//#define LINK_IS_CHILD (gSaveContext.linkAge != 0) +#define LINK_IS_CHILD (gSaveContext.linkAge == 1) #define LINK_IS_ADULT (gSaveContext.linkAge == 0) #define CURRENT_DAY (((void)0, gSaveContext.day) % 5) diff --git a/spec b/spec index 10b3e560e..f86a1d585 100644 --- a/spec +++ b/spec @@ -1640,8 +1640,11 @@ beginseg name "ovl_En_Kanban" compress include "build/src/overlays/actors/ovl_En_Kanban/z_en_kanban.o" - include "build/data/ovl_En_Kanban/ovl_En_Kanban.data.o" +#ifdef NON_MATCHING + include "build/src/overlays/actors/ovl_En_Kanban/ovl_En_Kanban_reloc.o" +#else include "build/data/ovl_En_Kanban/ovl_En_Kanban.reloc.o" +#endif endseg beginseg diff --git a/src/overlays/actors/ovl_En_Kanban/z_en_kanban.c b/src/overlays/actors/ovl_En_Kanban/z_en_kanban.c index 63c5854ea..fdf1c3e48 100644 --- a/src/overlays/actors/ovl_En_Kanban/z_en_kanban.c +++ b/src/overlays/actors/ovl_En_Kanban/z_en_kanban.c @@ -5,6 +5,8 @@ */ #include "z_en_kanban.h" +#include "objects/object_kanban/object_kanban.h" +#include "objects/gameplay_keep/gameplay_keep.h" #define FLAGS 0x00000019 @@ -15,7 +17,6 @@ void EnKanban_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnKanban_Update(Actor* thisx, GlobalContext* globalCtx); void EnKanban_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 const ActorInit En_Kanban_InitVars = { ACTOR_EN_KANBAN, ACTORCAT_PROP, @@ -28,27 +29,1016 @@ const ActorInit En_Kanban_InitVars = { (ActorFunc)EnKanban_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80957300 = { - { COLTYPE_NONE, AT_ON | AT_TYPE_ENEMY, AC_ON | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_1, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK0, { 0xF7CFFFFF, 0x00, 0x00 }, { 0xF3CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, }, +static ColliderCylinderInit sCylinderInit = { + { + COLTYPE_NONE, + AT_ON | AT_TYPE_ENEMY, + AC_ON | AC_TYPE_PLAYER, + OC1_ON | OC1_TYPE_ALL, + OC2_TYPE_1, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK0, + { 0xF7CFFFFF, 0x00, 0x00 }, + { 0xF3CFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, { 20, 50, 5, { 0, 0, 0 } }, }; +static u16 sPartFlags[] = { + PART_UPPER_LEFT, PART_LEFT_UPPER, PART_LEFT_LOWER, PART_RIGHT_UPPER, PART_RIGHT_LOWER, PART_LOWER_LEFT, + PART_UPPER_RIGHT, PART_LOWER_RIGHT, PART_POST_UPPER, PART_POST_LOWER, PART_POST_STAND, +}; + +static Vec3f sPieceOffsets[] = { + /* WHOLE_SIGN */ { 0.0f, 44.0f, 0.0f }, + /* UPPER_HALF */ { 0.0f, 50.0f, 0.0f }, + /* LOWER_HALF */ { 0.0f, 38.0f, 0.0f }, + /* RIGHT_HALF */ { 10.0f, 44.0f, 0.0f }, + /* LEFT_HALF */ { -10.0f, 44.0f, 0.0f }, + /* 2ND_QUAD */ { -10.0f, 50.0f, 0.0f }, + /* 1ST_QUAD */ { 10.0f, 50.0f, 0.0f }, + /* 3RD_QUAD */ { -10.0f, 38.0f, 0.0f }, + /* 4TH_QUAD */ { 10.0f, 38.0f, 0.0f }, + /* UPPER_LEFT */ { -7.5f, 51.0f, 0.0f }, + /* LEFT_UPPER */ { -12.5f, 48.0f, 0.0f }, + /* LEFT_LOWER */ { -12.5f, 40.0f, 0.0f }, + /* LOWER_LEFT */ { -7.5f, 37.0f, 0.0f }, + /* UPPER_RIGHT */ { 7.5f, 51.0f, 0.0f }, + /* RIGHT_UPPER */ { 12.5f, 48.0f, 0.0f }, + /* RIGHT_LOWER */ { 12.5f, 40.0f, 0.0f }, + /* LOWER_RIGHT */ { 7.5f, 37.0f, 0.0f }, + /* POST_UPPER */ { 0.0f, 50.0f, 0.0f }, + /* POST_LOWER */ { 0.0f, 38.0f, 0.0f }, +}; + +static Vec3f sPieceSizes[] = { + /* WHOLE_SIGN */ { 1500.0f, 1000.0f, 0.0f }, + /* UPPER_HALF */ { 1500.0f, 500.0f, 0.0f }, + /* LOWER_HALF */ { 1500.0f, 500.0f, 0.0f }, + /* RIGHT_HALF */ { 700.0f, 1000.0f, 0.0f }, + /* LEFT_HALF */ { 700.0f, 1000.0f, 0.0f }, + /* 2ND_QUAD */ { 700.0f, 500.0f, 0.0f }, + /* 1ST_QUAD */ { 700.0f, 500.0f, 0.0f }, + /* 3RD_QUAD */ { 700.0f, 500.0f, 0.0f }, + /* 4TH_QUAD */ { 700.0f, 500.0f, 0.0f }, + /* UPPER_LEFT */ { 700.0f, 500.0f, 0.0f }, + /* LEFT_UPPER */ { 700.0f, 500.0f, 0.0f }, + /* LEFT_LOWER */ { 700.0f, 500.0f, 0.0f }, + /* LOWER_LEFT */ { 700.0f, 500.0f, 0.0f }, + /* UPPER_RIGHT */ { 700.0f, 500.0f, 0.0f }, + /* RIGHT_UPPER */ { 700.0f, 500.0f, 0.0f }, + /* RIGHT_LOWER */ { 700.0f, 500.0f, 0.0f }, + /* LOWER_RIGHT */ { 700.0f, 500.0f, 0.0f }, + /* POST_UPPER */ { 200.0f, 500.0f, 0.0f }, + /* POST_LOWER */ { 200.0f, 500.0f, 0.0f }, +}; + +static u8 sCutTypes[] = { + /* 1H_OVER */ CUT_VERT_L, /* 2H_OVER */ CUT_VERT_L, + /* 1H_COMBO */ CUT_DIAG_R, /* 2H_COMBO */ CUT_DIAG_R, + /* 1H_LEFT */ CUT_HORIZ, /* 2H_LEFT */ CUT_HORIZ, + /* 1H_COMBO */ CUT_HORIZ, /* 2H_COMBO */ CUT_HORIZ, + /* 1H_RIGHT */ CUT_HORIZ, /* 2H_RIGHT */ CUT_HORIZ, + /* 1H_COMBO */ CUT_HORIZ, /* 2H_COMBO */ CUT_HORIZ, + /* 1H_STAB */ CUT_POST, /* 2H_STAB */ CUT_POST, + /* 1H_COMBO */ CUT_POST, /* 2H_COMBO */ CUT_POST, + /* FLIP_START */ CUT_VERT_L, /* JUMP_START */ CUT_VERT_L, + /* FLIP_END */ CUT_VERT_L, /* JUMP_END */ CUT_VERT_L, + /* */ CUT_VERT_L, /* */ CUT_VERT_L, + /* */ CUT_HORIZ, /* */ CUT_HORIZ, + /* */ CUT_HORIZ, /* */ CUT_HORIZ, + /* */ CUT_HORIZ, /* */ CUT_HORIZ, + /* BACK_LEFT */ CUT_HORIZ, /* BACK_RIGHT */ CUT_HORIZ, + /* OVER_HAMMER */ CUT_POST, /* SIDE_HAMMER */ CUT_POST, + /* 1H_SPIN_ATK */ CUT_POST, /* 2H_SPIN_ATK */ CUT_POST, + /* 1H_BIG_SPIN */ CUT_POST, /* 2H_BIG_SPIN */ CUT_POST, +}; + +static u16 sCutFlags[] = { + /* CUT_POST */ ALL_PARTS, /* CUT_VERT_L */ LEFT_HALF, + /* CUT_HORIZ */ UPPER_HALF, /* CUT_DIAG_L */ UPPERLEFT_HALF, + /* CUT_DIAG_R */ UPPERRIGHT_HALF, /* CUT_VERT_R */ RIGHT_HALF, +}; + +void func_80954960(EnKanban* this) { + f32 nx; + f32 ny; + f32 nz; + + if (this->actor.floorPoly != NULL) { + nx = COLPOLY_GET_NORMAL(this->actor.floorPoly->normal.x); + ny = COLPOLY_GET_NORMAL(this->actor.floorPoly->normal.y); + nz = COLPOLY_GET_NORMAL(this->actor.floorPoly->normal.z); + + this->floorRot.x = -func_80086B30(-nz * ny, 1.0f); + this->floorRot.z = func_80086B30(-nx * ny, 1.0f); + } +} + +void EnKanban_Init(Actor* thisx, GlobalContext* globalCtx) { + EnKanban* this = THIS; + + Actor_SetScale(&this->actor, 0.01f); + if (this->actor.params != ENKANBAN_PIECE) { + this->actor.targetMode = 0; + this->actor.flags |= 1; + this->unk_19A = Rand_ZeroFloat(1.9f); + Collider_InitCylinder(globalCtx, &this->collider); + Collider_SetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); + + if (this->actor.params == ENKANBAN_FISHING) { + if (LINK_IS_CHILD) { + this->actor.textId = 0x409D; + } else { + this->actor.textId = 0x4090; + } + } else { + this->actor.textId = this->actor.params | ENKANBAN_FISHING; + } + + this->bounceX = 1; + this->partFlags = 0xFFFF; + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 10.0f, 10.0f, 50.0f, 4); + func_80954960(this); + } +} + +void EnKanban_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnKanban* this = THIS; + + if (this->actionState == ENKANBAN_SIGN) { + Collider_DestroyCylinder(globalCtx, &this->collider); + } +} + +void func_80954BE8(EnKanban* this, GlobalContext* globalCtx) { + s16 yaw; + + if (!this->msgFlag) { + if (this->msgTimer == 0) { + yaw = this->actor.yawTowardsPlayer - this->actor.shape.rot.y; + if (ABS_ALT(yaw) < 0x2800) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + this->msgFlag = true; + } else { + func_800B8614(&this->actor, globalCtx, 68.0f); + } + } + } else { + this->msgTimer--; + } + } else if (Actor_TextboxIsClosing(&this->actor, globalCtx)) { + this->msgFlag = false; + this->msgTimer = 20; + } +} + +#ifdef NON_MATCHING +// Lots of branch likely stuff +void EnKanban_Update(Actor* thisx, GlobalContext* globalCtx) { + // GlobalContext* globalCtx = globalCtx2; + u8 bounced = false; + s32 pad; + EnKanban* this = THIS; + Player* player = GET_PLAYER(globalCtx); + Vec3f offset; + EnKanban* piece; + EnKanban* signpost; + s32 temp_v0_18; + f32 phi_f0; + s32 pad2; + + this->frameCount++; + + switch (this->actionState) { + case ENKANBAN_SIGN: + if (this->invincibilityTimer != 0) { + this->invincibilityTimer--; + } + + if (this->zTargetTimer != 0) { + this->zTargetTimer--; + } + + if (DECR(this->unk_1A0) == 0) { + this->unk_19C = NULL; + } + + if (this->zTargetTimer == 1) { + this->actor.flags &= ~1; + } + + if (this->partFlags == 0xFFFF) { + func_80954BE8(this, globalCtx); + } + + if ((this->invincibilityTimer == 0) && (this->collider.base.acFlags & AC_HIT)) { + this->collider.base.acFlags &= ~AC_HIT; + if (this->unk_19C != this->collider.base.ac) { + this->unk_19C = this->collider.base.ac; + this->unk_1A0 = 3; + this->invincibilityTimer = 6; + + piece = (EnKanban*)Actor_SpawnAsChild( + &globalCtx->actorCtx, &this->actor, globalCtx, ACTOR_EN_KANBAN, this->actor.world.pos.x, + this->actor.world.pos.y, this->actor.world.pos.z, this->actor.shape.rot.x, + this->actor.shape.rot.y, this->actor.shape.rot.z, ENKANBAN_PIECE); + if (piece != NULL) { + ColliderInfo* hitItem = this->collider.info.acHitInfo; + s16 yawDiff = this->actor.yawTowardsPlayer - this->actor.shape.rot.y; + u8 i; + + if (hitItem->toucher.dmgFlags & 0x200) { + this->cutType = sCutTypes[player->swordAnimation]; + } else if (hitItem->toucher.dmgFlags & 0x10) { + this->invincibilityTimer = 0; + this->cutType = this->unk_19A + 3; + this->unk_19A = 1 - this->unk_19A; + if (this->unk_199 == 0) { + this->unk_199++; + Item_DropCollectibleRandom(globalCtx, NULL, &this->actor.focus.pos, 0x60); + } + } else { + this->cutType = 0; + } + + if ((ABS_ALT(yawDiff) > 0x4000) && !(hitItem->toucher.dmgFlags & 0x10)) { + if (this->cutType == 4) { + this->cutType = 3; + } else if (this->cutType == 1) { + this->cutType = 5; + } + } + + piece->partFlags = sCutFlags[this->cutType] & this->partFlags; + if (piece->partFlags == 0) { + Actor_MarkForDeath(&piece->actor); + return; + } + + piece->partCount = 0; + for (i = 0; i < 11; i++) { + if (sPartFlags[i] & piece->partFlags) { + piece->partCount++; + } + } + + this->partFlags &= ~sCutFlags[this->cutType]; + if ((this->partFlags & 0x3FF) == 0) { + this->zTargetTimer = 10; + } + + if ((piece->partFlags & PART_UPPER_LEFT) && (piece->partFlags & PART_LOWER_RIGHT)) { + piece->pieceType = PIECE_WHOLE_SIGN; + } else if ((piece->partFlags & PART_LEFT_UPPER) && (piece->partFlags & PART_RIGHT_UPPER)) { + piece->pieceType = PIECE_UPPER_HALF; + } else if ((piece->partFlags & PART_LEFT_LOWER) && (piece->partFlags & PART_RIGHT_LOWER)) { + piece->pieceType = PIECE_LOWER_HALF; + } else if ((piece->partFlags & PART_UPPER_RIGHT) && (piece->partFlags & PART_LOWER_RIGHT)) { + piece->pieceType = PIECE_RIGHT_HALF; + } else if ((piece->partFlags & PART_UPPER_LEFT) && (piece->partFlags & PART_LOWER_LEFT)) { + piece->pieceType = PIECE_LEFT_HALF; + } else if ((piece->partFlags & PART_UPPER_LEFT) && (piece->partFlags & PART_LEFT_UPPER)) { + piece->pieceType = PIECE_2ND_QUAD; + } else if ((piece->partFlags & PART_UPPER_RIGHT) && (piece->partFlags & PART_RIGHT_UPPER)) { + piece->pieceType = PIECE_1ST_QUAD; + } else if ((piece->partFlags & PART_LEFT_LOWER) && (piece->partFlags & PART_LOWER_LEFT)) { + piece->pieceType = PIECE_3RD_QUAD; + } else if ((piece->partFlags & PART_RIGHT_LOWER) && (piece->partFlags & PART_LOWER_RIGHT)) { + piece->pieceType = PIECE_4TH_QUAD; + } else if (piece->partFlags & PART_UPPER_LEFT) { + piece->pieceType = PIECE_UPPER_LEFT; + } else if (piece->partFlags & PART_LEFT_UPPER) { + piece->pieceType = PIECE_LEFT_UPPER; + } else if (piece->partFlags & PART_LEFT_LOWER) { + piece->pieceType = PIECE_LEFT_LOWER; + } else if (piece->partFlags & PART_LOWER_LEFT) { + piece->pieceType = PIECE_LOWER_LEFT; + } else if (piece->partFlags & PART_UPPER_RIGHT) { + piece->pieceType = PIECE_UPPER_RIGHT; + } else if (piece->partFlags & PART_RIGHT_UPPER) { + piece->pieceType = PIECE_RIGHT_UPPER; + } else if (piece->partFlags & PART_RIGHT_LOWER) { + piece->pieceType = PIECE_RIGHT_LOWER; + } else if (piece->partFlags & PART_LOWER_RIGHT) { + piece->pieceType = PIECE_LOWER_RIGHT; + } else if (piece->partFlags & PART_POST_UPPER) { + piece->pieceType = PIECE_POST_UPPER; + } else if (piece->partFlags & PART_POST_LOWER) { + piece->pieceType = PIECE_POST_LOWER; + } else { + piece->pieceType = PIECE_OTHER; + } + + if (piece->pieceType == PIECE_OTHER) { + piece->pieceType = PIECE_WHOLE_SIGN; + } + + Matrix_RotateY(this->actor.shape.rot.y, MTXMODE_NEW); + Matrix_MultiplyVector3fByState(&sPieceOffsets[piece->pieceType], &offset); + piece->actor.world.pos.x += offset.x; + piece->actor.world.pos.y += offset.y; + piece->actor.world.pos.z += offset.z; + + piece->offset.x = -sPieceOffsets[piece->pieceType].x / this->actor.scale.x; + piece->offset.y = -sPieceOffsets[piece->pieceType].y / this->actor.scale.x; + piece->offset.z = -sPieceOffsets[piece->pieceType].z / this->actor.scale.x; + + piece->pieceWidth = sPieceSizes[piece->pieceType].x; + piece->pieceHeight = sPieceSizes[piece->pieceType].y; + piece->actionState = ENKANBAN_AIR; + piece->actor.gravity = -1.0f; + piece->actor.world.rot.y = + BINANG_ROT180((s32)randPlusMinusPoint5Scaled(0x4000) + this->actor.yawTowardsPlayer); + + if ((hitItem->toucher.dmgFlags & 0x10) || (hitItem->toucher.dmgFlags & 8) || + (hitItem->toucher.dmgFlags & 0x80000000)) { + piece->actor.velocity.y = Rand_ZeroFloat(3.0f) + 6.0f; + piece->actor.speedXZ = Rand_ZeroFloat(4.0f) + 6.0f; + } else { + piece->actor.velocity.y = Rand_ZeroFloat(2.0f) + 3.0f; + piece->actor.speedXZ = Rand_ZeroFloat(2.0f) + 3.0f; + } + + if (piece->partCount >= 4) { + piece->bounceX = Rand_ZeroFloat(10.0f) + 6.0f; + piece->bounceZ = Rand_ZeroFloat(10.0f) + 6.0f; + } else { + piece->bounceX = Rand_ZeroFloat(7.0f) + 3.0f; + piece->bounceZ = Rand_ZeroFloat(7.0f) + 3.0f; + } + + piece->spinVel.y = randPlusMinusPoint5Scaled(0x1800); + + if (Rand_ZeroOne() < 0.5f) { + piece->direction = 1; + } else { + piece->direction = -1; + } + piece->airTimer = 100; + piece->actor.flags &= ~1; + piece->actor.flags |= 0x2000000; + this->cutMarkTimer = 5; + Actor_PlaySfxAtPos(&this->actor, NA_SE_IT_SWORD_STRIKE); + } + } + } + + this->actor.focus.pos = this->actor.world.pos; + this->actor.focus.pos.y += 44.0f; + + Collider_UpdateCylinder(&this->actor, &this->collider); + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + + if (this->actor.xzDistToPlayer > 500.0f) { + this->actor.flags |= 1; + this->partFlags = 0xFFFF; + } + + if (this->cutMarkTimer != 0) { + if (this->cutMarkTimer >= 5) { + this->cutMarkAlpha += 255; + if (this->cutMarkAlpha > 255) { + this->cutMarkAlpha = 255; + } + } else { + this->cutMarkAlpha -= 65; + if (this->cutMarkAlpha < 0) { + this->cutMarkAlpha = 0; + } + } + this->cutMarkTimer--; + } + break; + + case ENKANBAN_AIR: + case ENKANBAN_UNUSED: { + f32 tempX; + f32 tempY; + f32 tempZ; + f32 tempWaterDepth; + u16 tempBgFlags; + u8 onGround; + + if (this->unk_198 != 0) { + this->actor.velocity.y = -2.0f; + Actor_UpdatePos(&this->actor); + } else { + Actor_MoveWithGravity(&this->actor); + } + + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 30.0f, 10.0f, 50.0f, 5); + + tempX = this->actor.world.pos.x; + tempY = this->actor.world.pos.y; + tempZ = this->actor.world.pos.z; + tempBgFlags = this->actor.bgCheckFlags; + tempWaterDepth = this->actor.depthInWater; + this->actor.world.pos.z += ((this->actor.world.pos.y - this->actor.floorHeight) * -50.0f) / 100.0f; + + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 10.0f, 10.0f, 50.0f, 4); + func_80954960(this); + + this->actor.world.pos.x = tempX; + this->actor.world.pos.y = tempY; + this->actor.world.pos.z = tempZ; + this->actor.bgCheckFlags = tempBgFlags; + this->actor.depthInWater = tempWaterDepth; + + if (1) {} + + onGround = (this->actor.bgCheckFlags & 1); + + if (this->spinXFlag != 0) { + this->spinRot.x += this->spinVel.x; + this->spinVel.x -= 0x800; + if ((this->spinRot.x <= 0) && onGround) { + this->spinRot.x = 0; + this->spinVel.x = 0; + } + } else { + this->spinRot.x -= this->spinVel.x; + this->spinVel.x -= 0x800; + if ((this->spinRot.x >= 0) && onGround) { + this->spinRot.x = 0; + this->spinVel.x = 0; + } + } + + if (this->spinVel.x < -0xC00) { + this->spinVel.x = -0xC00; + } + + if (this->spinZFlag != 0) { + this->spinRot.z += this->spinVel.z; + this->spinVel.z -= 0x800; + if ((this->spinRot.z <= 0) && onGround) { + this->spinRot.z = 0; + this->spinVel.z = 0; + } + } else { + this->spinRot.z -= this->spinVel.z; + this->spinVel.z -= 0x800; + if ((this->spinRot.z >= 0) && onGround) { + this->spinRot.z = 0; + this->spinVel.z = 0; + } + } + + if (this->spinVel.z < -0xC00) { + this->spinVel.z = -0xC00; + } + + if (this->actor.bgCheckFlags & 8) { + if (!(this->actor.bgCheckFlags & 1)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_WOODPLATE_BOUND); + } + this->actor.speedXZ *= -0.5f; + } + + if (this->actor.bgCheckFlags & 0x40) { + this->actionState = ENKANBAN_WATER; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_BOMB_DROP_WATER); + this->bounceX = this->bounceZ = 0; + this->actor.world.pos.y += this->actor.depthInWater; + EffectSsGSplash_Spawn(globalCtx, &this->actor.world.pos, NULL, NULL, 0, (this->partCount * 20) + 300); + EffectSsGRipple_Spawn(globalCtx, &this->actor.world.pos, 150, 650, 0); + EffectSsGRipple_Spawn(globalCtx, &this->actor.world.pos, 300, 800, 5); + this->actor.velocity.y = 0.0f; + this->actor.gravity = 0.0f; + break; + } + + if (onGround) { + temp_v0_18 = func_800C99D4(&globalCtx->colCtx, this->actor.floorPoly, this->actor.floorBgId); + + if ((temp_v0_18 == 15) || (temp_v0_18 == 14)) { + this->unk_197 = 1; + } else if (temp_v0_18 == 5) { + this->unk_197 = -1; + } + + if (this->bounceCount <= 0) { + this->bounceCount++; + if (this->unk_197 != 0) { + this->actor.velocity.y = 0.0f; + } else { + this->actor.velocity.y *= -0.3f; + this->actor.world.rot.y += (s16)randPlusMinusPoint5Scaled(0x4000); + } + bounced = true; + } else { + this->actor.velocity.y = 0.0f; + } + + if (this->unk_197 != 0) { + if (this->unk_197 > 0) { + this->actor.speedXZ = 0.0f; + } else if ((this->floorRot.x > 0.1f) || (this->floorRot.z > 0.1f)) { + this->airTimer = 10; + if (this->actor.bgCheckFlags & 8) { + this->actionState = ENKANBAN_GROUND; + this->actor.speedXZ = 0.0f; + goto nextCase; + } else { + Vec3f spC8; + + Matrix_SetStateXRotation(this->floorRot.x); + Matrix_InsertZRotation_f(this->floorRot.z, MTXMODE_APPLY); + Matrix_GetStateTranslationAndScaledY(KREG(20) + 10.0f, &spC8); + Math_ApproachF(&this->actor.velocity.x, spC8.x, 0.5f, (KREG(21) * 0.01f) + 0.1f); + Math_ApproachF(&this->actor.velocity.z, spC8.z, 0.5f, (KREG(21) * 0.01f) + 0.3f); + this->actor.world.rot.y = Math_Atan2S(spC8.x, spC8.z); + this->unk_198 = 1; + this->actor.speedXZ = sqrtf(SQXZ(this->actor.velocity)); + } + } else { + this->unk_198 = 0; + Math_ApproachZeroF(&this->actor.speedXZ, 1, 0.1f); + } + } else { + this->actor.speedXZ *= 0.7f; + } + + if (this->spinRot.x == 0) { + if (this->bounceX != 0) { + bounced = true; + if (this->unk_197 != 0) { + this->spinRot.x = 0; + this->bounceX = 0; + } else { + this->spinVel.x = this->bounceX << 9; + if (this->bounceX != 0) { + this->bounceX -= 5; + if (this->bounceX <= 0) { + this->bounceX = 0; + } + } + + if (Rand_ZeroOne() < 0.5f) { + this->spinXFlag = 1; + } else { + this->spinXFlag = 0; + } + } + } + } + + if (this->spinRot.z == 0) { + if (this->bounceZ != 0) { + bounced = 1; + if (this->unk_197 != 0) { + this->spinRot.z = 0; + this->bounceZ = 0; + } else { + this->spinVel.z = this->bounceZ << 9; + if (this->bounceZ != 0) { + this->bounceZ -= 5; + if (this->bounceZ <= 0) { + this->bounceZ = 0; + } + } + + if (Rand_ZeroOne() < 0.5f) { + this->spinZFlag = 1; + } else { + this->spinZFlag = 0; + } + } + } + } + + Math_ApproachS(&this->actor.shape.rot.x, this->direction << 0xE, 1, 0x2000); + } else { + this->actor.shape.rot.y += this->spinVel.y; + this->actor.shape.rot.x += this->direction * 0x7D0; + } + + if (bounced) { + if (this->unk_197 > 0) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_PL_WALK_SNOW); + } else { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_WOODPLATE_BOUND); + } + } + + if (bounced && (this->unk_197 >= 0)) { + s16 dustCount; + s16 j; + Vec3f velocity = { 0.0f, 0.0f, 0.0f }; + static Color_RGBA8 D_80957548 = { 185, 140, 70, 255 }; + static Color_RGBA8 D_8095754C = { 255, 255, 255, 255 }; + Vec3f accel; + Vec3f pos; + Color_RGBA8 primColor; + Color_RGBA8 envColor; + + if (this->unk_197 != 0) { + primColor = D_8095754C; + envColor = D_8095754C; + } else { + primColor = D_80957548; + envColor = D_80957548; + } + + accel.x = 0.0f; + accel.y = 0.1f; + accel.z = 0.0f; + + pos.y = this->actor.floorHeight + 3.0f; + dustCount = this->partCount * 0.5f; + + for (j = 0; j < dustCount + 3; j++) { + pos.x = randPlusMinusPoint5Scaled((this->partCount * 0.5f) + 20.0f) + this->actor.world.pos.x; + pos.z = randPlusMinusPoint5Scaled((this->partCount * 0.5f) + 20.0f) + this->actor.world.pos.z; + func_800B0F18(globalCtx, &pos, &velocity, &accel, &primColor, &envColor, 100, 5, + Rand_ZeroFloat(5.0f) + 14.0f); + } + } + + if (DECR(this->airTimer) == 0) { + this->actionState = ENKANBAN_GROUND; + } + } + + case ENKANBAN_GROUND: + case ENKANBAN_WATER: + nextCase: + signpost = (EnKanban*)this->actor.parent; + + if (signpost->partFlags == 0xFFFF) { + Actor_MarkForDeath(&this->actor); + } + + phi_f0 = 0.0f; + if (this->unk_197 > 0) { + phi_f0 = -150.0f; + } + + Math_ApproachF(&this->actor.shape.yOffset, 100.0f + phi_f0, 1.0f, 5.0f); + + if (this->actionState == ENKANBAN_WATER) { + s16 rippleDelay; + s32 rippleScale; + + if ((player->actor.speedXZ > 0.0f) && (player->actor.world.pos.y < this->actor.world.pos.y) && + (this->actor.xyzDistToPlayerSq < SQ(50.0f))) { + Math_ApproachF(&this->actor.speedXZ, player->actor.speedXZ, 1.0f, 0.2f); + if (this->actor.speedXZ > 1.0f) { + this->actor.speedXZ = 1.0f; + } + + if (Math_SmoothStepToS(&this->actor.world.rot.y, BINANG_ROT180(this->actor.yawTowardsPlayer), 1, + 0x1000, 0) > 0) { + this->spinVel.y = this->actor.speedXZ * 1000.0f; + } else { + this->spinVel.y = this->actor.speedXZ * -1000.0f; + } + } + + if (this->actor.bgCheckFlags & 1) { + this->actor.speedXZ = 0.0f; + } + + Actor_MoveWithGravity(&this->actor); + + if (this->actor.speedXZ != 0.0f) { + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 10.0f, 10.0f, 50.0f, 5); + if (this->actor.bgCheckFlags & 8) { + this->actor.speedXZ *= -0.5f; + if (this->spinVel.y > 0) { + this->spinVel.y = -2000; + } else { + this->spinVel.y = 2000; + } + } + Math_ApproachZeroF(&this->actor.speedXZ, 1.0f, 0.15f); + } + this->actor.shape.rot.y += this->spinVel.y; + Math_ApproachS(&this->spinVel.y, 0, 1, 0x3A); + Math_ApproachS(&this->actor.shape.rot.x, this->direction * 0x4000, 2, 0x1000); + Math_ApproachS(&this->spinRot.x, Math_SinS(this->frameCount * 2500) * 500.0f, 2, 0x1000); + Math_ApproachS(&this->spinRot.z, Math_CosS(this->frameCount * 3000) * 500.0f, 2, 0x1000); + Math_ApproachZeroF(&this->floorRot.x, 0.5f, 0.2f); + Math_ApproachZeroF(&this->floorRot.z, 0.5f, 0.2f); + + if (fabsf(this->actor.speedXZ) > 1.0f) { + rippleDelay = 0; + } else if (fabsf(this->actor.speedXZ) > 0.5f) { + rippleDelay = 3; + } else { + rippleDelay = 7; + } + + if (!(this->frameCount & rippleDelay)) { + if (this->partCount < 3) { + rippleScale = 0; + } else if (this->partCount < 6) { + rippleScale = 100; + } else { + rippleScale = 200; + } + EffectSsGRipple_Spawn(globalCtx, &this->actor.world.pos, rippleScale, rippleScale + 500, 0); + } + } else if ((globalCtx->actorCtx.unk2 != 0) && (this->actor.xyzDistToPlayerSq < SQ(100.0f))) { + f32 hammerStrength = (100.0f - sqrtf(this->actor.xyzDistToPlayerSq)) * 0.05f; + + this->actionState = ENKANBAN_AIR; + this->actor.gravity = -1.0f; + this->actor.world.rot.y = randPlusMinusPoint5Scaled(0x10000); + if (this->partCount >= 4) { + this->bounceX = Rand_ZeroFloat(10.0f) + 6.0f; + this->bounceZ = Rand_ZeroFloat(10.0f) + 6.0f; + this->actor.velocity.y = 2.0f + hammerStrength; + this->actor.speedXZ = Rand_ZeroFloat(1.0f); + } else { + this->bounceX = Rand_ZeroFloat(7.0f) + 3.0f; + this->bounceZ = Rand_ZeroFloat(7.0f) + 3.0f; + this->actor.velocity.y = 3.0f + hammerStrength; + this->actor.speedXZ = Rand_ZeroFloat(1.5f); + } + + this->spinVel.y = randPlusMinusPoint5Scaled(0x1800); + + if (Rand_ZeroOne() < 0.5f) { + this->direction = 1; + } else { + this->direction = -1; + } + this->airTimer = 70; + } + + if (this->bounceX == 0) { + Actor* explosive = globalCtx->actorCtx.actorLists[ACTORCAT_EXPLOSIVES].first; + f32 dx; + f32 dy; + f32 dz; + + while (explosive != NULL) { + if (explosive->params != 1) { + explosive = explosive->next; + continue; + } + + dx = this->actor.world.pos.x - explosive->world.pos.x; + dy = this->actor.world.pos.y - explosive->world.pos.y; + dz = this->actor.world.pos.z - explosive->world.pos.z; + + if (sqrtf(SQ(dx) + SQ(dy) + SQ(dz)) < 100.0f) { + f32 bombStrength = (100.0f - sqrtf(SQ(dx) + SQ(dy) + SQ(dz))) * 0.05f; + + this->actionState = ENKANBAN_AIR; + this->actor.gravity = -1.0f; + this->actor.world.rot.y = Math_Atan2S(dx, dz); + + if (this->partCount >= 4) { + this->bounceX = Rand_ZeroFloat(10.0f) + 6.0f; + this->bounceZ = Rand_ZeroFloat(10.0f) + 6.0f; + this->actor.velocity.y = 2.5f + bombStrength; + this->actor.speedXZ = 3.0f + bombStrength; + } else { + this->bounceX = Rand_ZeroFloat(7.0f) + 3.0f; + this->bounceZ = Rand_ZeroFloat(7.0f) + 3.0f; + this->actor.velocity.y = 5.0f + bombStrength; + this->actor.speedXZ = 4.0f + bombStrength; + } + + this->spinVel.y = randPlusMinusPoint5Scaled(0x1800); + + if (Rand_ZeroOne() < 0.5f) { + this->direction = 1; + } else { + this->direction = -1; + } + this->airTimer = 70; + } + + explosive = explosive->next; + } + } + + switch (this->ocarinaFlag) { + case 0: + if (globalCtx->msgCtx.unk1202A == 1) { + this->ocarinaFlag = 1; + } + break; + + case 1: + if ((globalCtx->msgCtx.unk1202A == 4) && (globalCtx->msgCtx.unk1202E == 7)) { + this->actionState = ENKANBAN_REPAIR; + this->bounceX = 1; + play_sound(NA_SE_SY_TRE_BOX_APPEAR); + } + break; + } + break; + + case ENKANBAN_REPAIR: { + f32 distX; + f32 distY; + f32 distZ; + s16 pDiff; + s16 yDiff; + s16 rDiff; + + signpost = (EnKanban*)this->actor.parent; + signpost->invincibilityTimer = 5; + + if (signpost->partFlags == 0xFFFF) { + Actor_MarkForDeath(&this->actor); + } + + Matrix_RotateY(signpost->actor.shape.rot.y, MTXMODE_NEW); + Matrix_MultiplyVector3fByState(&sPieceOffsets[this->pieceType], &offset); + distX = + Math_SmoothStepToF(&this->actor.world.pos.x, signpost->actor.world.pos.x + offset.x, 1.0f, 3.0f, 0.0f); + distY = + Math_SmoothStepToF(&this->actor.world.pos.y, signpost->actor.world.pos.y + offset.y, 1.0f, 3.0f, 0.0f); + distZ = + Math_SmoothStepToF(&this->actor.world.pos.z, signpost->actor.world.pos.z + offset.z, 1.0f, 3.0f, 0.0f); + pDiff = Math_SmoothStepToS(&this->actor.shape.rot.x, signpost->actor.shape.rot.x, 1, 0x200, 0); + yDiff = Math_SmoothStepToS(&this->actor.shape.rot.y, signpost->actor.shape.rot.y, 1, 0x200, 0); + rDiff = Math_SmoothStepToS(&this->actor.shape.rot.z, signpost->actor.shape.rot.z, 1, 0x200, 0); + Math_ApproachS(&this->spinRot.x, 0, 1, 0x200); + Math_ApproachS(&this->spinRot.z, 0, 1, 0x200); + Math_ApproachZeroF(&this->floorRot.x, 1.0f, 0.05f); + Math_ApproachZeroF(&this->floorRot.z, 1.0f, 0.05f); + Math_ApproachZeroF(&this->actor.shape.yOffset, 1.0f, 2.0f); + if (((distX + distY + distZ) == 0.0f) && + ((pDiff + yDiff + rDiff + this->spinRot.x + this->spinRot.z) == 0) && (this->floorRot.x == 0.0f) && + (this->floorRot.z == 0.0f)) { + signpost->partFlags |= this->partFlags; + signpost->actor.flags |= 1; + Actor_MarkForDeath(&this->actor); + return; + } + break; + } + } +} +#else +static Vec3f D_8095753C = { 0.0f, 0.0f, 0.0f }; +static Color_RGBA8 D_80957548 = { 185, 140, 70, 255 }; +static Color_RGBA8 D_8095754C = { 255, 255, 255, 255 }; +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kanban/EnKanban_Update.s") #endif -extern ColliderCylinderInit D_80957300; +static Gfx* sDisplayLists[] = { + object_kanban_DL_000CB0, object_kanban_DL_000DB8, object_kanban_DL_000E78, object_kanban_DL_000F38, + object_kanban_DL_000FF8, object_kanban_DL_0010B8, object_kanban_DL_0011C0, object_kanban_DL_0012C8, + object_kanban_DL_0013D0, object_kanban_DL_001488, object_kanban_DL_001540, +}; -extern UNK_TYPE D_06000C30; +#include "z_en_kanban_gfx.c" -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kanban/func_80954960.s") +static f32 sCutAngles[] = { + /* CUT_POST */ 0.50f * M_PI, + /* CUT_VERT_L */ 0.00f * M_PI, + /* CUT_HORIZ */ 0.50f * M_PI, + /* CUT_DIAG_L */ 0.66f * M_PI, + /* CUT_DIAG_R */ 0.34f * M_PI, + /* CUT_VERT_R */ 0.00f * M_PI, + /* */ 0.00f * M_PI, + /* */ 0.00f * M_PI, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kanban/EnKanban_Init.s") +#include "overlays/ovl_En_Kanban/ovl_En_Kanban.c" -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kanban/EnKanban_Destroy.s") +void EnKanban_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnKanban* this = THIS; + f32 zShift; + f32 zShift2; + s32 i; + Player* player = GET_PLAYER(globalCtx); + u8* shadowTex = GRAPH_ALLOC(globalCtx->state.gfxCtx, ARRAY_COUNT(sShadowTexFlags)); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kanban/func_80954BE8.s") + OPEN_DISPS(globalCtx->state.gfxCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kanban/EnKanban_Update.s") + func_8012C28C(globalCtx->state.gfxCtx); + func_8012C2DC(globalCtx->state.gfxCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kanban/EnKanban_Draw.s") + gSPDisplayList(POLY_OPA_DISP++, object_kanban_DL_000C30); + + if (this->actionState != ENKANBAN_SIGN) { + Matrix_InsertTranslation(this->actor.world.pos.x, this->actor.world.pos.y, this->actor.world.pos.z, + MTXMODE_NEW); + Matrix_Scale(this->actor.scale.x, this->actor.scale.y, this->actor.scale.z, MTXMODE_APPLY); + Matrix_RotateStateAroundXAxis(this->floorRot.x); + Matrix_InsertZRotation_f(this->floorRot.z, MTXMODE_APPLY); + Matrix_InsertTranslation(0.0f, this->actor.shape.yOffset, 0.0f, MTXMODE_APPLY); + Matrix_RotateY(this->actor.shape.rot.y, MTXMODE_APPLY); + Matrix_InsertXRotation_s(this->actor.shape.rot.x, MTXMODE_APPLY); + + zShift = fabsf(Math_SinS(this->spinRot.x) * this->pieceHeight); + zShift2 = fabsf(Math_SinS(this->spinRot.z) * this->pieceWidth); + zShift = CLAMP_MIN(zShift, zShift2); + zShift *= -(f32)this->direction; + + Matrix_InsertTranslation(0.0f, 0.0f, zShift, MTXMODE_APPLY); + Matrix_InsertXRotation_s(this->spinRot.x, MTXMODE_APPLY); + Matrix_RotateY(this->spinRot.z, MTXMODE_APPLY); + Matrix_InsertTranslation(this->offset.x, this->offset.y, this->offset.z - 100.0f, MTXMODE_APPLY); + + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + + for (i = 0; i < ARRAY_COUNT(sPartFlags); i++) { + if (sPartFlags[i] & this->partFlags) { + gSPDisplayList(POLY_OPA_DISP++, sDisplayLists[i]); + } + } + } else { + f32 phi_f0 = 0.0f; + + if ((player->transformation == PLAYER_FORM_HUMAN) || (player->transformation == PLAYER_FORM_DEKU)) { + phi_f0 = -15.0f; + } + this->actor.world.pos.y = this->actor.home.pos.y + phi_f0; + Matrix_InsertTranslation(0.0f, 0.0f, -100.0f, MTXMODE_APPLY); + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + + if (this->partFlags == 0xFFFF) { + gSPDisplayList(POLY_OPA_DISP++, gameplay_keep_DL_05AED0); + } else { + for (i = 0; i < ARRAY_COUNT(sPartFlags); i++) { + if (sPartFlags[i] & this->partFlags) { + gSPDisplayList(POLY_OPA_DISP++, sDisplayLists[i]); + } + } + } + + if (this->cutMarkAlpha != 0) { + f32 cutOffset = (this->cutType == CUT_POST) ? -1200.0f : 0.0f; + + Matrix_InsertTranslation(0.0f, 4400.0f + cutOffset, 200.0f, MTXMODE_APPLY); + Matrix_InsertZRotation_f(sCutAngles[this->cutType], MTXMODE_APPLY); + Matrix_Scale(0.0f, 10.0f, 2.0f, MTXMODE_APPLY); + + gDPPipeSync(POLY_XLU_DISP++); + gDPSetPrimColor(POLY_XLU_DISP++, 0x00, 0x00, 255, 255, 255, this->cutMarkAlpha); + gDPSetEnvColor(POLY_XLU_DISP++, 255, 255, 150, 0); + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, object_kanban_DL_001630); + } + } + + if ((this->actor.projectedPos.z <= 400.0f) && (this->actor.projectedPos.z > 0.0f) && + (this->actor.floorHeight > -3000.0f) && ((this->bounceX != 0) || (this->bounceZ != 0))) { + u16 dayTime = gSaveContext.time; + f32 shadowAlpha; + + if (dayTime >= CLOCK_TIME(12, 0)) { + dayTime = (0xFFFF - dayTime) & 0xFFFF; + } + + shadowAlpha = (dayTime * 0.00275f) + 10.0f; + if (this->actor.projectedPos.z > 300.0f) { + shadowAlpha *= (400.0f - this->actor.projectedPos.z) * 0.01f; + } + + gDPSetPrimColor(POLY_XLU_DISP++, 0x00, 0x00, 0, 0, 0, (s8)shadowAlpha); + + if ((player->transformation == PLAYER_FORM_HUMAN) || (player->transformation == PLAYER_FORM_DEKU)) { + zShift = 0.0f; + } else { + zShift = ((this->actor.world.pos.y - this->actor.floorHeight) * -50.0f) / 100.0f; + } + + Matrix_InsertTranslation(this->actor.world.pos.x, this->actor.floorHeight, this->actor.world.pos.z + zShift, + MTXMODE_NEW); + Matrix_RotateStateAroundXAxis(this->floorRot.x); + Matrix_InsertZRotation_f(this->floorRot.z, MTXMODE_APPLY); + Matrix_Scale(this->actor.scale.x, 0.0f, this->actor.scale.z, MTXMODE_APPLY); + + if (this->actionState == ENKANBAN_SIGN) { + Matrix_RotateStateAroundXAxis(-M_PI / 5); + } + + Matrix_RotateY(this->actor.shape.rot.y, MTXMODE_APPLY); + Matrix_InsertXRotation_s(this->actor.shape.rot.x, MTXMODE_APPLY); + Matrix_InsertXRotation_s(this->spinRot.x, MTXMODE_APPLY); + Matrix_RotateY(this->spinRot.z, MTXMODE_APPLY); + Matrix_InsertTranslation(this->offset.x, this->offset.y, this->offset.z, MTXMODE_APPLY); + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + + for (i = 0; i < ARRAY_COUNT(sShadowTexFlags); i++) { + if (sShadowTexFlags[i] & this->partFlags) { + shadowTex[i] = 0xFF; + } else { + shadowTex[i] = 0; + } + } + + gSPSegment(POLY_XLU_DISP++, 0x08, Lib_SegmentedToVirtual(shadowTex)); + gSPDisplayList(POLY_XLU_DISP++, gEnKanban_D_80957DE0); + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_En_Kanban/z_en_kanban.h b/src/overlays/actors/ovl_En_Kanban/z_en_kanban.h index 40eeb1060..b667bd9e8 100644 --- a/src/overlays/actors/ovl_En_Kanban/z_en_kanban.h +++ b/src/overlays/actors/ovl_En_Kanban/z_en_kanban.h @@ -5,11 +5,104 @@ struct EnKanban; +#define PART_UPPER_LEFT (1 << 0) +#define PART_LEFT_UPPER (1 << 1) +#define PART_LEFT_LOWER (1 << 2) +#define PART_RIGHT_UPPER (1 << 3) +#define PART_RIGHT_LOWER (1 << 4) +#define PART_LOWER_LEFT (1 << 5) +#define PART_UPPER_RIGHT (1 << 6) +#define PART_LOWER_RIGHT (1 << 7) +#define PART_POST_UPPER (1 << 8) +#define PART_POST_LOWER (1 << 9) +#define PART_POST_STAND (1 << 10) +#define LEFT_HALF (PART_UPPER_LEFT | PART_LEFT_UPPER | PART_LEFT_LOWER | PART_LOWER_LEFT) +#define RIGHT_HALF (PART_UPPER_RIGHT | PART_RIGHT_UPPER | PART_RIGHT_LOWER | PART_LOWER_RIGHT) +#define UPPER_HALF (PART_POST_UPPER | PART_UPPER_RIGHT | PART_RIGHT_UPPER | PART_UPPER_LEFT | PART_LEFT_UPPER) +#define UPPERLEFT_HALF (PART_POST_UPPER | PART_UPPER_RIGHT | PART_LEFT_LOWER | PART_UPPER_LEFT | PART_LEFT_UPPER) +#define UPPERRIGHT_HALF (PART_POST_UPPER | PART_UPPER_RIGHT | PART_RIGHT_UPPER | PART_UPPER_LEFT | PART_RIGHT_LOWER) +#define ALL_PARTS (LEFT_HALF | RIGHT_HALF | PART_POST_UPPER | PART_POST_LOWER) + +typedef enum { + /* 0 */ ENKANBAN_SIGN, + /* 1 */ ENKANBAN_AIR, + /* 2 */ ENKANBAN_UNUSED, + /* 3 */ ENKANBAN_GROUND, + /* 4 */ ENKANBAN_WATER, + /* 5 */ ENKANBAN_REPAIR +} EnKanbanActionState; + +typedef enum { + /* 0 */ PIECE_WHOLE_SIGN, + /* 1 */ PIECE_UPPER_HALF, + /* 2 */ PIECE_LOWER_HALF, + /* 3 */ PIECE_RIGHT_HALF, + /* 4 */ PIECE_LEFT_HALF, + /* 5 */ PIECE_2ND_QUAD, + /* 6 */ PIECE_1ST_QUAD, + /* 7 */ PIECE_3RD_QUAD, + /* 8 */ PIECE_4TH_QUAD, + /* 9 */ PIECE_UPPER_LEFT, + /* 10 */ PIECE_LEFT_UPPER, + /* 11 */ PIECE_LEFT_LOWER, + /* 12 */ PIECE_LOWER_LEFT, + /* 13 */ PIECE_UPPER_RIGHT, + /* 14 */ PIECE_RIGHT_UPPER, + /* 15 */ PIECE_RIGHT_LOWER, + /* 16 */ PIECE_LOWER_RIGHT, + /* 17 */ PIECE_POST_UPPER, + /* 18 */ PIECE_POST_LOWER, + /* 100 */ PIECE_OTHER = 100 +} EnKanbanPiece; + +typedef enum { + /* 0 */ CUT_POST, + /* 1 */ CUT_VERT_L, + /* 2 */ CUT_HORIZ, + /* 3 */ CUT_DIAG_L, // lower left to upper right + /* 4 */ CUT_DIAG_R, // upper left to lower right + /* 5 */ CUT_VERT_R +} EnKanbanCutType; + typedef struct EnKanban { /* 0x000 */ Actor actor; - /* 0x144 */ char unk_144[0xAC]; + /* 0x144 */ UNK_TYPE1 unk144[4]; // actionFunc? + /* 0x148 */ u8 frameCount; + /* 0x14A */ s16 airTimer; + /* 0x14C */ u8 actionState; + /* 0x14E */ u16 partFlags; + /* 0x150 */ u8 partCount; + /* 0x152 */ s16 invincibilityTimer; + /* 0x154 */ Vec3f offset; + /* 0x160 */ Vec3s spinRot; + /* 0x166 */ Vec3s spinVel; + /* 0x16C */ s8 spinXFlag; + /* 0x16D */ s8 spinZFlag; + /* 0x16E */ s16 bounceX; + /* 0x170 */ s16 bounceZ; + /* 0x172 */ u8 bounceCount; + /* 0x174 */ f32 pieceWidth; + /* 0x178 */ f32 pieceHeight; + /* 0x17C */ s16 direction; + /* 0x180 */ Vec3f floorRot; + /* 0x18C */ u8 cutType; + /* 0x18D */ u8 pieceType; + /* 0x18E */ s16 cutMarkTimer; + /* 0x190 */ s16 cutMarkAlpha; + /* 0x192 */ s16 zTargetTimer; + /* 0x194 */ u8 msgFlag; + /* 0x195 */ u8 msgTimer; + /* 0x196 */ u8 ocarinaFlag; + /* 0x197 */ s8 unk_197; + /* 0x198 */ s8 unk_198; + /* 0x199 */ u8 unk_199; + /* 0x19A */ u8 unk_19A; + /* 0x19C */ Actor* unk_19C; + /* 0x1A0 */ s16 unk_1A0; + /* 0x1A4 */ ColliderCylinder collider; } EnKanban; // size = 0x1F0 +#define ENKANBAN_PIECE ((s16)0xFFDD) #define ENKANBAN_FISHING 0x300 extern const ActorInit En_Kanban_InitVars; diff --git a/src/overlays/actors/ovl_En_Kanban/z_en_kanban_gfx.c b/src/overlays/actors/ovl_En_Kanban/z_en_kanban_gfx.c new file mode 100644 index 000000000..c38e9df94 --- /dev/null +++ b/src/overlays/actors/ovl_En_Kanban/z_en_kanban_gfx.c @@ -0,0 +1,68 @@ +#include "z_en_kanban.h" + +static u16 sShadowTexFlags[] = { + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x100, + 0x100, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x100, 0x100, + 0x100, 0x100, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x100, 0x100, + 0x100, 0x100, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x100, 0x100, + 0x100, 0x100, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x001, 0x001, 0x001, 0x001, 0x001, 0x001, 0x001, 0x001, 0x001, 0x001, 0x001, 0x001, 0x001, 0x001, 0x101, 0x101, + 0x140, 0x140, 0x040, 0x040, 0x040, 0x040, 0x040, 0x040, 0x040, 0x040, 0x040, 0x040, 0x040, 0x040, 0x040, 0x040, + 0x002, 0x002, 0x002, 0x001, 0x001, 0x001, 0x001, 0x001, 0x001, 0x001, 0x001, 0x001, 0x001, 0x001, 0x101, 0x101, + 0x140, 0x140, 0x040, 0x040, 0x040, 0x040, 0x040, 0x040, 0x040, 0x040, 0x040, 0x040, 0x040, 0x008, 0x008, 0x008, + 0x002, 0x002, 0x002, 0x002, 0x002, 0x002, 0x001, 0x001, 0x001, 0x001, 0x001, 0x001, 0x001, 0x001, 0x101, 0x101, + 0x140, 0x140, 0x040, 0x040, 0x040, 0x040, 0x040, 0x040, 0x040, 0x040, 0x008, 0x008, 0x008, 0x008, 0x008, 0x008, + 0x002, 0x002, 0x002, 0x002, 0x002, 0x002, 0x002, 0x002, 0x002, 0x001, 0x001, 0x001, 0x001, 0x001, 0x101, 0x101, + 0x140, 0x140, 0x040, 0x040, 0x040, 0x040, 0x040, 0x008, 0x008, 0x008, 0x008, 0x008, 0x008, 0x008, 0x008, 0x008, + 0x002, 0x002, 0x002, 0x002, 0x002, 0x002, 0x002, 0x002, 0x002, 0x002, 0x002, 0x002, 0x001, 0x001, 0x101, 0x101, + 0x140, 0x140, 0x040, 0x040, 0x008, 0x008, 0x008, 0x008, 0x008, 0x008, 0x008, 0x008, 0x008, 0x008, 0x008, 0x008, + 0x002, 0x002, 0x002, 0x002, 0x002, 0x002, 0x002, 0x002, 0x002, 0x002, 0x002, 0x002, 0x002, 0x002, 0x102, 0x301, + 0x340, 0x108, 0x008, 0x008, 0x008, 0x008, 0x008, 0x008, 0x008, 0x008, 0x008, 0x008, 0x008, 0x008, 0x008, 0x008, + 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x204, 0x220, + 0x280, 0x210, 0x010, 0x010, 0x010, 0x010, 0x010, 0x010, 0x010, 0x010, 0x010, 0x010, 0x010, 0x010, 0x010, 0x010, + 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x020, 0x020, 0x220, 0x220, + 0x280, 0x280, 0x080, 0x080, 0x010, 0x010, 0x010, 0x010, 0x010, 0x010, 0x010, 0x010, 0x010, 0x010, 0x010, 0x010, + 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x020, 0x020, 0x020, 0x020, 0x020, 0x220, 0x220, + 0x280, 0x280, 0x080, 0x080, 0x080, 0x080, 0x080, 0x010, 0x010, 0x010, 0x010, 0x010, 0x010, 0x010, 0x010, 0x010, + 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x020, 0x020, 0x020, 0x020, 0x020, 0x020, 0x020, 0x020, 0x220, 0x220, + 0x280, 0x280, 0x080, 0x080, 0x080, 0x080, 0x080, 0x080, 0x080, 0x080, 0x010, 0x010, 0x010, 0x010, 0x010, 0x010, + 0x004, 0x004, 0x004, 0x020, 0x020, 0x020, 0x020, 0x020, 0x020, 0x020, 0x020, 0x020, 0x020, 0x020, 0x220, 0x220, + 0x280, 0x280, 0x080, 0x080, 0x080, 0x080, 0x080, 0x080, 0x080, 0x080, 0x080, 0x080, 0x080, 0x010, 0x010, 0x010, + 0x020, 0x020, 0x020, 0x020, 0x020, 0x020, 0x020, 0x020, 0x020, 0x020, 0x020, 0x020, 0x020, 0x020, 0x220, 0x620, + 0x680, 0x280, 0x080, 0x080, 0x080, 0x080, 0x080, 0x080, 0x080, 0x080, 0x080, 0x080, 0x080, 0x080, 0x080, 0x080, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x400, 0x400, + 0x400, 0x400, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x400, 0x400, + 0x400, 0x400, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x400, 0x400, + 0x400, 0x400, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x400, 0x400, + 0x400, 0x400, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x400, 0x400, + 0x400, 0x400, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x400, 0x400, + 0x400, 0x400, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x400, 0x400, + 0x400, 0x400, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x400, 0x400, + 0x400, 0x400, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x400, 0x400, + 0x400, 0x400, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x400, 0x400, + 0x400, 0x400, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x400, 0x400, + 0x400, 0x400, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x400, 0x400, + 0x400, 0x400, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x400, 0x400, + 0x400, 0x400, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x400, 0x400, + 0x400, 0x400, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x400, 0x400, + 0x400, 0x400, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x400, 0x400, + 0x400, 0x400, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, +}; diff --git a/tools/disasm/variables.txt b/tools/disasm/variables.txt index 60e39862c..73afcda75 100644 --- a/tools/disasm/variables.txt +++ b/tools/disasm/variables.txt @@ -8782,14 +8782,14 @@ 0x809548A0:("Bg_Ingate_InitVars","UNK_TYPE1","",0x1), 0x809572E0:("En_Kanban_InitVars","UNK_TYPE1","",0x1), 0x80957300:("D_80957300","UNK_TYPE1","",0x1), - 0x8095732C:("D_8095732C","UNK_TYPE2","",0x2), + 0x8095732C:("sPartFlags","UNK_TYPE2","",0x2), 0x8095732E:("D_8095732E","UNK_TYPE2","",0x2), 0x80957330:("D_80957330","UNK_TYPE2","",0x2), 0x80957332:("D_80957332","UNK_TYPE2","",0x2), - 0x80957344:("D_80957344","UNK_TYPE4","",0x4), - 0x80957428:("D_80957428","UNK_TYPE4","",0x4), - 0x8095750C:("D_8095750C","UNK_TYPE1","",0x1), - 0x80957530:("D_80957530","UNK_TYPE1","",0x1), + 0x80957344:("sPieceOffsets","UNK_TYPE4","",0x4), + 0x80957428:("sPieceSizes","UNK_TYPE4","",0x4), + 0x8095750C:("sCutTypes","UNK_TYPE1","",0x1), + 0x80957530:("sCutFlags","UNK_TYPE1","",0x1), 0x8095753C:("D_8095753C","UNK_TYPE4","",0x4), 0x80957548:("D_80957548","UNK_TYPE4","",0x4), 0x8095754C:("D_8095754C","UNK_TYPE4","",0x4), From 7aa3766d6728823c16e9b3771fd3d29bca1cc712 Mon Sep 17 00:00:00 2001 From: Parker Burnett Date: Sun, 16 Jan 2022 08:37:21 -0600 Subject: [PATCH 03/13] En_hgOK (#394) * en_hgo OK * Formatting changed somehow?...hopefully this fixes * who would win, Cammoguy or one letter? * format * addressing review comments * fixing PR comments * fixing and merging master * forgot to format * fixes warnings? * minor documentation...don't have tools to do more * Fixing things, hopefully OK * formatting... * clean-up undefined syms --- spec | 3 +- src/overlays/actors/ovl_En_Hgo/z_en_hgo.c | 358 ++++++++++++++++++++-- src/overlays/actors/ovl_En_Hgo/z_en_hgo.h | 44 ++- tools/disasm/functions.txt | 8 +- undefined_syms.txt | 7 - 5 files changed, 374 insertions(+), 46 deletions(-) diff --git a/spec b/spec index f86a1d585..dcf40880e 100644 --- a/spec +++ b/spec @@ -4748,8 +4748,7 @@ beginseg name "ovl_En_Hgo" compress include "build/src/overlays/actors/ovl_En_Hgo/z_en_hgo.o" - include "build/data/ovl_En_Hgo/ovl_En_Hgo.data.o" - include "build/data/ovl_En_Hgo/ovl_En_Hgo.reloc.o" + include "build/src/overlays/actors/ovl_En_Hgo/ovl_En_Hgo_reloc.o" endseg beginseg diff --git a/src/overlays/actors/ovl_En_Hgo/z_en_hgo.c b/src/overlays/actors/ovl_En_Hgo/z_en_hgo.c index 179338401..2e2b6a84b 100644 --- a/src/overlays/actors/ovl_En_Hgo/z_en_hgo.c +++ b/src/overlays/actors/ovl_En_Hgo/z_en_hgo.c @@ -5,6 +5,7 @@ */ #include "z_en_hgo.h" +#include "objects/object_harfgibud/object_harfgibud.h" #define FLAGS 0x02000019 @@ -15,7 +16,18 @@ void EnHgo_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnHgo_Update(Actor* thisx, GlobalContext* globalCtx); void EnHgo_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 +void func_80BD03EC(EnHgo* this); +void func_80BD0410(EnHgo* this, GlobalContext* globalCtx); +void func_80BD0434(EnHgo* this, GlobalContext* globalCtx); +void func_80BD049C(EnHgo* this); +void func_80BD04E0(EnHgo* this, GlobalContext* globalCtx); +void EnHgo_SetupDialogueHandler(EnHgo* this); +void EnHgo_DefaultDialogueHandler(EnHgo* this, GlobalContext* globalCtx); +void func_80BD06FC(EnHgo* this, GlobalContext* globalCtx); +s32 func_80BD0898(EnHgo* this, GlobalContext* globalCtx); +s32 EnHgo_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx); +void EnHgo_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* pos, Actor* thisx); + const ActorInit En_Hgo_InitVars = { ACTOR_EN_HGO, ACTORCAT_NPC, @@ -28,54 +40,342 @@ const ActorInit En_Hgo_InitVars = { (ActorFunc)EnHgo_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80BD0F48 = { - { COLTYPE_NONE, AT_NONE, AC_NONE, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_2, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK0, { 0x00000000, 0x00, 0x00 }, { 0x00000000, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_NONE, OCELEM_ON, }, +static ActorAnimationEntry sAnimations[] = { + { &object_harfgibud_Anim_00B644, 1.0f, 0.0f, 0.0f, 0, -4.0f }, + { &object_harfgibud_Anim_013684, 1.0f, 0.0f, 0.0f, 0, 0.0f }, + { &object_harfgibud_Anim_0152EC, 1.0f, 0.0f, 0.0f, 2, 0.0f }, + { &object_harfgibud_Anim_015C70, 1.0f, 0.0f, 0.0f, 0, 0.0f }, + { &object_harfgibud_Anim_0165F0, 1.0f, 0.0f, 0.0f, 0, 0.0f }, + { &object_harfgibud_Anim_014220, 1.0f, 0.0f, 0.0f, 2, 0.0f }, + { &object_harfgibud_Anim_014A9C, 1.0f, 0.0f, 0.0f, 0, 0.0f }, +}; + +static ColliderCylinderInit sCylinderInit = { + { + COLTYPE_NONE, + AT_NONE, + AC_NONE, + OC1_ON | OC1_TYPE_ALL, + OC2_TYPE_2, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK0, + { 0x00000000, 0x00, 0x00 }, + { 0x00000000, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_NONE, + OCELEM_ON, + }, { 18, 46, 0, { 0, 0, 0 } }, }; -// sColChkInfoInit -static CollisionCheckInfoInit2 D_80BD0F74 = { 0, 0, 0, 0, MASS_IMMOVABLE }; +static CollisionCheckInfoInit2 sColChkInfoInit = { 0, 0, 0, 0, MASS_IMMOVABLE }; -#endif +static TexturePtr sEyeTextures[] = { + object_harfgibud_Tex_011138, + object_harfgibud_Tex_011938, + object_harfgibud_Tex_012138, +}; -extern ColliderCylinderInit D_80BD0F48; -extern CollisionCheckInfoInit2 D_80BD0F74; +void EnHgo_Init(Actor* thisx, GlobalContext* globalCtx) { + EnHgo* this = THIS; + s32 pad; -extern UNK_TYPE D_0600B644; -extern UNK_TYPE D_0600F248; + ActorShape_Init(&thisx->shape, 0.0f, ActorShadow_DrawCircle, 36.0f); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_harfgibud_Skel_012A58, &object_harfgibud_Anim_00B644, + this->jointTable, this->morphTable, HGO_LIMB_MAX); + Collider_InitCylinder(globalCtx, &this->collider); + Collider_SetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); + CollisionCheck_SetInfo2(&thisx->colChkInfo, NULL, &sColChkInfoInit); + thisx->targetMode = 6; + this->unk_30C = 0; + this->unk_30E = 0; + this->unk_314 = 0; + this->unk_310 = 0; + this->unk_312 = 0; + if ((gSaveContext.weekEventReg[75] & 0x20) || (gSaveContext.weekEventReg[52] & 0x20)) { + func_80BD049C(this); + } else { + thisx->draw = NULL; + func_80BD03EC(this); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hgo/EnHgo_Init.s") +void EnHgo_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnHgo* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hgo/EnHgo_Destroy.s") + Collider_DestroyCylinder(globalCtx, &this->collider); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hgo/func_80BD03EC.s") +void func_80BD03EC(EnHgo* this) { + this->actor.flags &= ~1; + this->actionFunc = func_80BD0410; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hgo/func_80BD0410.s") +void func_80BD0410(EnHgo* this, GlobalContext* globalCtx) { +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hgo/func_80BD0420.s") +void func_80BD0420(EnHgo* this) { + this->actionFunc = func_80BD0434; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hgo/func_80BD0434.s") +void func_80BD0434(EnHgo* this, GlobalContext* globalCtx) { + this->collider.dim.pos.x = this->actor.focus.pos.x; + this->collider.dim.pos.y = this->actor.world.pos.y; + this->collider.dim.pos.z = this->actor.focus.pos.z; + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hgo/func_80BD049C.s") +void func_80BD049C(EnHgo* this) { + Actor_ChangeAnimation(&this->skelAnime, sAnimations, 0); + this->actionFunc = func_80BD04E0; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hgo/func_80BD04E0.s") +void func_80BD04E0(EnHgo* this, GlobalContext* globalCtx) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + if (Player_GetMask(globalCtx) == PLAYER_MASK_GIBDO) { + if (!(this->unk_310 & 4)) { + this->unk_310 |= 4; + func_801518B0(globalCtx, 0x15A5, &this->actor); + this->unk_314 = 0x15A5; // That mask is a gibdo -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hgo/func_80BD064C.s") + } else { + func_801518B0(globalCtx, 0x15A7, &this->actor); + this->unk_314 = 0x15A7; // can I research that mask + } + } else if (gSaveContext.playerForm == PLAYER_FORM_HUMAN) { + if (!(this->unk_310 & 1)) { + this->unk_310 |= 1; + func_801518B0(globalCtx, 0x158F, &this->actor); + this->unk_314 = 0x158F; // Isn't this a fairy + } else { + func_801518B0(globalCtx, 0x1593, &this->actor); + this->unk_314 = 0x1593; // Never seen a fairy this lively + } + } else { + if (!(this->unk_310 & 2)) { + this->unk_310 |= 2; + func_801518B0(globalCtx, 0x1595, &this->actor); + this->unk_314 = 0x1595; // ghost radar is reacting + } else { + func_801518B0(globalCtx, 0x1598, &this->actor); + this->unk_314 = 0x1598; // you seem to be similar to a ghost + } + } + EnHgo_SetupDialogueHandler(this); + } else { + func_800B8614(&this->actor, globalCtx, 100.0f); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hgo/func_80BD0660.s") +void EnHgo_SetupDialogueHandler(EnHgo* this) { + this->actionFunc = EnHgo_DefaultDialogueHandler; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hgo/func_80BD06FC.s") +void EnHgo_DefaultDialogueHandler(EnHgo* this, GlobalContext* globalCtx) { + switch (Message_GetState(&globalCtx->msgCtx)) { + case 0: + case 1: + case 2: + case 3: + case 4: + break; + case 5: + func_80BD06FC(this, globalCtx); + break; + case 6: + if (func_80147624(globalCtx)) { + func_80BD049C(this); + } + } + Math_SmoothStepToS(&this->actor.world.rot.y, this->actor.yawTowardsPlayer, 0xA, 0x71C, 0xB6); + this->actor.shape.rot.y = this->actor.world.rot.y; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hgo/func_80BD0898.s") +void func_80BD06FC(EnHgo* this, GlobalContext* globalCtx) { + if (func_80147624(globalCtx)) { + switch (this->unk_314) { + case 0x158F: + func_801518B0(globalCtx, 0x1590, &this->actor); + this->unk_314 = 0x1590; + break; + case 0x1590: + if (gSaveContext.weekEventReg[14] & 4) { + func_801518B0(globalCtx, 0x1591, &this->actor); + this->unk_314 = 0x1591; + break; + } + func_801518B0(globalCtx, 0x1592, &this->actor); + this->unk_314 = 0x1592; + break; + case 0x1591: + func_801518B0(globalCtx, 0x1592, &this->actor); + this->unk_314 = 0x1592; + break; + case 0x1593: + func_801518B0(globalCtx, 0x1594, &this->actor); + this->unk_314 = 0x1594; + break; + case 0x1595: + func_801518B0(globalCtx, 0x1596, &this->actor); + this->unk_314 = 0x1596; + break; + case 0x1596: + func_801518B0(globalCtx, 0x1597, &this->actor); + this->unk_314 = 0x1597; + break; + case 0x1598: + func_801518B0(globalCtx, 0x1599, &this->actor); + this->unk_314 = 0x1599; + break; + case 0x15A5: + func_801518B0(globalCtx, 0x15A6, &this->actor); + this->unk_314 = 0x15A6; + break; + case 0x15A6: + func_801518B0(globalCtx, 0x15A7, &this->actor); + this->unk_314 = 0x15A7; + break; + case 0x15A7: + func_801477B4(globalCtx); + func_80BD049C(this); + break; + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hgo/func_80BD0B8C.s") +s32 func_80BD0898(EnHgo* this, GlobalContext* globalCtx) { + u32 actionIndex; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hgo/EnHgo_Update.s") + if (func_800EE29C(globalCtx, 0x1E6)) { + actionIndex = func_800EE200(globalCtx, 0x1E6); + if (this->unk_316 != globalCtx->csCtx.npcActions[actionIndex]->unk0) { + this->unk_316 = globalCtx->csCtx.npcActions[actionIndex]->unk0; + switch (globalCtx->csCtx.npcActions[actionIndex]->unk0) { + case 1: + this->unk_218 = 0; + Actor_ChangeAnimation(&this->skelAnime, sAnimations, 0); + break; + case 2: + this->actor.draw = EnHgo_Draw; + this->unk_218 = 1; + Actor_ChangeAnimation(&this->skelAnime, sAnimations, 1); + break; + case 3: + this->unk_218 = 2; + Actor_ChangeAnimation(&this->skelAnime, sAnimations, 2); + break; + case 4: + this->unk_218 = 3; + Actor_ChangeAnimation(&this->skelAnime, sAnimations, 3); + break; + case 5: + this->unk_218 = 4; + Actor_ChangeAnimation(&this->skelAnime, sAnimations, 4); + break; + case 6: + this->unk_218 = 5; + Actor_ChangeAnimation(&this->skelAnime, sAnimations, 5); + break; + } + } else if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { + switch (this->unk_218) { + case 1: + if ((Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) && (this->unk_312 == 0)) { + this->unk_312 = 1; + if ((gSaveContext.sceneSetupIndex == 0) && + ((globalCtx->csCtx.unk_12 == 2) || (globalCtx->csCtx.unk_12 == 4))) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_VO_GBVO02); + } + } + break; + case 2: + this->unk_218 = 3; + Actor_ChangeAnimation(&this->skelAnime, sAnimations, 3); + break; + case 5: + this->unk_218 = 6; + Actor_ChangeAnimation(&this->skelAnime, sAnimations, 6); + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hgo/func_80BD0CF0.s") + func_800EDF24(&this->actor, globalCtx, actionIndex); + return true; + } + if ((globalCtx->csCtx.state == 0) && (((gSaveContext.weekEventReg[75]) & 0x20)) && + (this->actionFunc == func_80BD0410)) { + this->actor.shape.rot.y = this->actor.world.rot.y; + Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_ELF_MSG2, this->actor.focus.pos.x, this->actor.focus.pos.y, + this->actor.focus.pos.z, 7, 0, 0, 0x7F5A); + func_80BD0420(this); + } + this->unk_316 = 0x63; + return false; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hgo/func_80BD0D38.s") +void func_80BD0B8C(EnHgo* this, GlobalContext* globalCtx) { + func_800E9250(globalCtx, &this->actor, &this->unk_300, &this->unk_306, this->actor.focus.pos); + if (this->unk_30E > 2) { + this->unk_30E--; + } else if (this->unk_30E == 2) { + this->unk_30C = 1; + this->unk_30E = 1; + } else if (this->unk_30E == 1) { + this->unk_30C = 2; + this->unk_30E = 0; + } else { + this->unk_30C = 0; + this->unk_30E = 60; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hgo/EnHgo_Draw.s") +void EnHgo_Update(Actor* thisx, GlobalContext* globalCtx) { + EnHgo* this = THIS; + s32 pad; + + this->actionFunc(this, globalCtx); + SkelAnime_Update(&this->skelAnime); + if (func_80BD0898(this, globalCtx)) { + func_800E8F08(&this->unk_300, &this->unk_306); + } else if (this->actionFunc != func_80BD0410) { + if (this->actionFunc != func_80BD0434) { + Collider_UpdateCylinder(&this->actor, &this->collider); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + func_80BD0B8C(this, globalCtx); + } + } +} + +s32 EnHgo_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx) { + EnHgo* this = THIS; + + if (limbIndex == HGO_LIMB_PELVIS) { + rot->x += this->unk_300.y; + rot->z += this->unk_300.x; + } + return false; +} + +void EnHgo_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* pos, Actor* thisx) { + EnHgo* this = THIS; + + if (limbIndex == HGO_LIMB_PELVIS) { + Matrix_CopyCurrentState(&this->unk_1D8); + Matrix_GetStateTranslation(&this->actor.focus.pos); + } +} + +void EnHgo_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnHgo* this = THIS; + + OPEN_DISPS(globalCtx->state.gfxCtx); + func_8012C28C(globalCtx->state.gfxCtx); + gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(sEyeTextures[this->unk_30C])); + SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, + EnHgo_OverrideLimbDraw, &EnHgo_PostLimbDraw, &this->actor); + Matrix_SetCurrentState(&this->unk_1D8); + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, object_harfgibud_DL_00F248); + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_En_Hgo/z_en_hgo.h b/src/overlays/actors/ovl_En_Hgo/z_en_hgo.h index 3d7ff6e55..f39aab0fd 100644 --- a/src/overlays/actors/ovl_En_Hgo/z_en_hgo.h +++ b/src/overlays/actors/ovl_En_Hgo/z_en_hgo.h @@ -7,11 +7,47 @@ struct EnHgo; typedef void (*EnHgoActionFunc)(struct EnHgo*, GlobalContext*); +// Shares the same setup as en_hg +typedef enum { + /* 00 */ HGO_LIMB_NONE, + /* 01 */ HGO_LIMB_ABDOMEN, + /* 02 */ HGO_LIMB_CHEST, + /* 03 */ HGO_LIMB_SHOULDER_LEFT, + /* 04 */ HGO_LIMB_ARM_LEFT, + /* 05 */ HGO_LIMB_HAND_LEFT, + /* 06 */ HGO_LIMB_SHOULDER_RIGHT, + /* 07 */ HGO_LIMB_ARM_RIGHT, + /* 08 */ HGO_LIMB_HAND_RIGHT, + /* 09 */ HGO_LIMB_EYEBROW, + /* 10 */ HGO_LIMB_HEAD, + /* 11 */ HGO_LIMB_PELVIS, + /* 12 */ HGO_LIMB_THIGH_LEFT, + /* 13 */ HGO_LIMB_LEG_LEFT, + /* 14 */ HGO_LIMB_FOOT_LEFT, + /* 15 */ HGO_LIMB_THIGH_RIGHT, + /* 16 */ HGO_LIMB_LEG_RIGHT, + /* 17 */ HGO_LIMB_FOOT_RIGHT, + /* 18 */ HGO_LIMB_UNK, + /* 19 */ HGO_LIMB_MAX, +} ObjectHgoLimbs; + typedef struct EnHgo { - /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x90]; - /* 0x01D4 */ EnHgoActionFunc actionFunc; - /* 0x01D8 */ char unk_1D8[0x140]; + /* 0x000 */ Actor actor; + /* 0x144 */ ColliderCylinder collider; + /* 0x190 */ SkelAnime skelAnime; + /* 0x1D4 */ EnHgoActionFunc actionFunc; + /* 0x1D8 */ MtxF unk_1D8; + /* 0x218 */ s32 unk_218; + /* 0x21C */ Vec3s jointTable[HGO_LIMB_MAX]; + /* 0x28E */ Vec3s morphTable[HGO_LIMB_MAX]; + /* 0x300 */ Vec3s unk_300; + /* 0x306 */ Vec3s unk_306; + /* 0x30C */ s16 unk_30C; + /* 0x30E */ s16 unk_30E; + /* 0x310 */ s16 unk_310; + /* 0x312 */ s16 unk_312; + /* 0x314 */ u16 unk_314; + /* 0x316 */ u16 unk_316; } EnHgo; // size = 0x318 extern const ActorInit En_Hgo_InitVars; diff --git a/tools/disasm/functions.txt b/tools/disasm/functions.txt index 69ca079a9..fe6a3dfdb 100644 --- a/tools/disasm/functions.txt +++ b/tools/disasm/functions.txt @@ -15700,14 +15700,14 @@ 0x80BD0434:("func_80BD0434",), 0x80BD049C:("func_80BD049C",), 0x80BD04E0:("func_80BD04E0",), - 0x80BD064C:("func_80BD064C",), - 0x80BD0660:("func_80BD0660",), + 0x80BD064C:("EnHgo_SetupDialogueHandler",), + 0x80BD0660:("EnHgo_DefaultDialogueHandler",), 0x80BD06FC:("func_80BD06FC",), 0x80BD0898:("func_80BD0898",), 0x80BD0B8C:("func_80BD0B8C",), 0x80BD0C30:("EnHgo_Update",), - 0x80BD0CF0:("func_80BD0CF0",), - 0x80BD0D38:("func_80BD0D38",), + 0x80BD0CF0:("EnHgo_OverrideLimbDraw",), + 0x80BD0D38:("EnHgo_PostLimbDraw",), 0x80BD0D7C:("EnHgo_Draw",), 0x80BD11E0:("EnZov_Init",), 0x80BD13B0:("EnZov_Destroy",), diff --git a/undefined_syms.txt b/undefined_syms.txt index 9cca916c0..1168dbcab 100644 --- a/undefined_syms.txt +++ b/undefined_syms.txt @@ -2412,13 +2412,6 @@ D_06009D44 = 0x06009D44; D_0600A164 = 0x0600A164; D_0600AE1C = 0x0600AE1C; - -// ovl_En_Hgo - -D_0600B644 = 0x0600B644; -D_0600F248 = 0x0600F248; -D_06012A58 = 0x06012A58; - // ovl_En_Hidden_Nuts D_060023B8 = 0x060023B8; From b47941968d9e718fe54d6a0c35f987c5788500ed Mon Sep 17 00:00:00 2001 From: Maide <34639600+Kelebek1@users.noreply.github.com> Date: Sun, 16 Jan 2022 17:46:08 +0000 Subject: [PATCH 04/13] En_Ig (#533) * En_Ig * UNK_TYPE1 * Remove syms * PR * PR * Merge * Merge --- include/z64.h | 2 +- spec | 3 +- src/overlays/actors/ovl_En_Ig/z_en_ig.c | 997 ++++++++++++++++++++++-- src/overlays/actors/ovl_En_Ig/z_en_ig.h | 50 +- tools/disasm/functions.txt | 6 +- undefined_syms.txt | 9 - 6 files changed, 994 insertions(+), 73 deletions(-) diff --git a/include/z64.h b/include/z64.h index 1aba77e7a..f468d32aa 100644 --- a/include/z64.h +++ b/include/z64.h @@ -1395,7 +1395,7 @@ typedef struct EnHy { typedef struct { /* 0x0 */ u8 unk0; /* 0x4 */ s32 unk4; - /* 0x8 */ s32 unk8; + /* 0x8 */ s32 unk8; // game script pointer? } struct_80133038_arg2; // size = 0xC typedef s32 (*func_8013E748_arg6)(struct GlobalContext*, Actor*, Vec3s*); diff --git a/spec b/spec index dcf40880e..98cd58af9 100644 --- a/spec +++ b/spec @@ -5027,8 +5027,7 @@ beginseg name "ovl_En_Ig" compress include "build/src/overlays/actors/ovl_En_Ig/z_en_ig.o" - include "build/data/ovl_En_Ig/ovl_En_Ig.data.o" - include "build/data/ovl_En_Ig/ovl_En_Ig.reloc.o" + include "build/src/overlays/actors/ovl_En_Ig/ovl_En_Ig_reloc.o" endseg beginseg diff --git a/src/overlays/actors/ovl_En_Ig/z_en_ig.c b/src/overlays/actors/ovl_En_Ig/z_en_ig.c index c059d2e08..d2b4e3612 100644 --- a/src/overlays/actors/ovl_En_Ig/z_en_ig.c +++ b/src/overlays/actors/ovl_En_Ig/z_en_ig.c @@ -5,6 +5,8 @@ */ #include "z_en_ig.h" +#include "overlays/actors/ovl_En_Door/z_en_door.h" +#include "objects/object_dai/object_dai.h" #define FLAGS 0x00000019 @@ -18,7 +20,44 @@ void EnIg_Draw(Actor* thisx, GlobalContext* globalCtx); void func_80BF2AF8(EnIg* this, GlobalContext* globalCtx); void func_80BF2BD4(EnIg* this, GlobalContext* globalCtx); -#if 0 +static s32 D_80BF3260[] = { + 0x0D000100, 0xB10A006C, 0x4E020F19, 0x0F2D4202, 0x0F2D0F32, 0x36004B10, 0x1050210, 0x32103725, + 0x02103711, 0x0F190211, 0x0F12000D, 0x02120006, 0x0001050E, 0x12000600, 0x040E110F, 0x0600020E, + 0x1037110F, 0x0B0E1032, 0x1037060E, 0x0F2D0F32, 0x050E0F19, 0x0F2D0A0A, 0x00615A02, 0x0F2D0F32, + 0x4E020F32, 0x100A4202, 0x100A101E, 0x36004B10, 0x1902101E, 0x10320D02, 0x10321037, 0x01050E10, + 0x32103708, 0x0E101E10, 0x320D0210, 0x1E10320D, 0x02103210, 0x3701050E, 0x10321037, 0x090E101E, + 0x10320E0E, 0x100A101E, 0x030E0F32, 0x100A0C0E, 0x0F2D0F32, 0x07050500, +}; + +static s32 D_80BF3318[] = { -1, -1, 3, 1, 3, 1, 2, 0, 3, 5, 0, 3, 1, 2, 4 }; + +static s32 D_80BF3354[] = { + 0x0E28B00C, + 0x10000000, +}; + +static s32 D_80BF335C[] = { + 0x09000000, 0x4B10001F, 0x170E28B1, 0x0C090000, 0x180E28B2, 0x0C090000, 0x170E28B3, 0x2D000111, 0x37020C09, + 0x00001000, 0x5610002F, 0x170E28B1, 0x0C090000, 0x180E28B5, 0x0C090000, 0x170E28B6, 0x0C090000, 0x180E28B7, + 0x0C090000, 0x170E28B8, 0x2D00010C, 0x09000011, 0x56101009, 0x0000180E, 0x29560C09, 0x0000170E, 0x29570C09, + 0x0000180E, 0x29580C09, 0x0000170E, 0x29592D00, 0x010C0900, 0x00121000, +}; + +static s32 D_80BF33E0[] = { + 0x0E28B90C, + 0x10000000, +}; + +static s32 D_80BF33E8[] = { + 0x0E28B40C, + 0x10000000, +}; + +static s32 D_80BF33F0[] = { + 0x0E295B0C, + 0x10000000, +}; + const ActorInit En_Ig_InitVars = { ACTOR_EN_IG, ACTORCAT_NPC, @@ -31,105 +70,951 @@ const ActorInit En_Ig_InitVars = { (ActorFunc)EnIg_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80BF3418 = { - { COLTYPE_HIT1, AT_NONE, AC_NONE, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_1, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK1, { 0x00000000, 0x00, 0x00 }, { 0x00000000, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_NONE, OCELEM_ON, }, +static ColliderCylinderInit sCylinderInit = { + { + COLTYPE_HIT1, + AT_NONE, + AC_NONE, + OC1_ON | OC1_TYPE_ALL, + OC2_TYPE_1, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK1, + { 0x00000000, 0x00, 0x00 }, + { 0x00000000, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_NONE, + OCELEM_ON, + }, { 28, 62, 0, { 0, 0, 0 } }, }; -// static ColliderSphereInit sSphereInit = { -static ColliderSphereInit D_80BF3444 = { - { COLTYPE_NONE, AT_NONE, AC_NONE, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_1, COLSHAPE_SPHERE, }, - { ELEMTYPE_UNK0, { 0x00000000, 0x00, 0x00 }, { 0x00000000, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_NONE, OCELEM_ON, }, +static ColliderSphereInit sSphereInit = { + { + COLTYPE_NONE, + AT_NONE, + AC_NONE, + OC1_ON | OC1_TYPE_ALL, + OC2_TYPE_1, + COLSHAPE_SPHERE, + }, + { + ELEMTYPE_UNK0, + { 0x00000000, 0x00, 0x00 }, + { 0x00000000, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_NONE, + OCELEM_ON, + }, { 0, { { 0, 0, 0 }, 20 }, 100 }, }; -// sColChkInfoInit -static CollisionCheckInfoInit2 D_80BF3470 = { 0, 0, 0, 0, MASS_IMMOVABLE }; +static CollisionCheckInfoInit2 sColChkInfoInit = { 0, 0, 0, 0, MASS_IMMOVABLE }; -#endif +static ActorAnimationEntryS sAnimations[] = { + { &object_dai_Anim_0048B4, 1.0f, 0, -1, 0, 0 }, { &object_dai_Anim_0048B4, 1.0f, 0, -1, 0, -4 }, + { &object_dai_Anim_005100, 1.0f, 0, -1, 0, 0 }, { &object_dai_Anim_005100, 1.0f, 0, -1, 0, -4 }, + { &object_dai_Anim_0010F8, 1.0f, 0, -1, 2, 0 }, { &object_dai_Anim_001E44, 1.0f, 0, -1, 0, -4 }, + { &object_dai_Anim_0014BC, 1.0f, 0, -1, 2, 0 }, { &object_dai_Anim_003CAC, 1.0f, 0, -1, 2, -4 }, + { &object_dai_Anim_0040E0, 1.0f, 0, -1, 0, 0 }, { &object_dai_Anim_0040E0, 1.0f, 0, -1, 0, -4 }, +}; -extern ColliderCylinderInit D_80BF3418; -extern ColliderSphereInit D_80BF3444; -extern CollisionCheckInfoInit2 D_80BF3470; +Actor* func_80BF1150(EnIg* this, GlobalContext* globalCtx, u8 actorCat, s16 actorId) { + Actor* foundActor = NULL; + Actor* temp_v0; -extern UNK_TYPE D_06008710; -extern UNK_TYPE D_0600C538; -extern UNK_TYPE D_060130D0; + while (true) { + foundActor = SubS_FindActor(globalCtx, foundActor, actorCat, actorId); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ig/func_80BF1150.s") + if (foundActor == NULL) { + break; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ig/func_80BF1200.s") + if ((this != (EnIg*)foundActor) && (foundActor->update != NULL)) { + break; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ig/func_80BF1258.s") + temp_v0 = foundActor->next; + if (temp_v0 == NULL) { + foundActor = NULL; + break; + } + foundActor = temp_v0; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ig/func_80BF1284.s") + return foundActor; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ig/func_80BF1354.s") +EnDoor* func_80BF1200(GlobalContext* globalCtx, s32 arg1) { + s32 phi_a1; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ig/func_80BF13E4.s") + switch (arg1) { + case 5: + case 6: + case 7: + case 9: + phi_a1 = 11; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ig/func_80BF146C.s") + case 8: + phi_a1 = 15; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ig/func_80BF14B0.s") + default: + phi_a1 = -1; + break; + } + return (EnDoor*)SubS_FindDoor(globalCtx, phi_a1); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ig/func_80BF15EC.s") +void func_80BF1258(EnIg* this) { + this->skelAnime.playSpeed = this->unk_3D4; + SkelAnime_Update(&this->skelAnime); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ig/func_80BF16C8.s") +s32 func_80BF1284(EnIg* this, s32 arg1) { + s32 phi_v1 = false; + s32 ret = false; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ig/func_80BF1744.s") + switch (arg1) { + case 0: + case 1: + if ((this->unk_3FC != 0) && (this->unk_3FC != 1)) { + phi_v1 = true; + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ig/func_80BF17BC.s") + case 2: + case 3: + if ((this->unk_3FC != 2) && (this->unk_3FC != 3)) { + phi_v1 = true; + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ig/func_80BF1920.s") + default: + if (arg1 != this->unk_3FC) { + phi_v1 = true; + } + break; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ig/func_80BF19A0.s") + if (phi_v1) { + this->unk_3FC = arg1; + ret = func_8013BC6C(&this->skelAnime, sAnimations, arg1); + this->unk_3D4 = this->skelAnime.playSpeed; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ig/func_80BF1A60.s") + return ret; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ig/func_80BF1AE0.s") +void func_80BF1354(EnIg* this, GlobalContext* globalCtx) { + Collider_UpdateCylinder(&this->actor, &this->collider1); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider1.base); + this->collider2.dim.worldSphere.radius = this->collider2.dim.modelSphere.radius * this->collider2.dim.scale; + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider2.base); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ig/func_80BF1B40.s") +void func_80BF13E4(EnIg* this) { + if ((this->unk_3D0 & 0x100) && (DECR(this->unk_3F0) == 0)) { + this->unk_3F2++; + if (this->unk_3F2 >= 4) { + this->unk_3F0 = Rand_S16Offset(30, 30); + this->unk_3F2 = 0; + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ig/func_80BF1C44.s") +Actor* func_80BF146C(EnIg* this, GlobalContext* globalCtx) { + Actor* retActor; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ig/func_80BF1D78.s") + if (this->unk_298.unk0 == 3) { + retActor = func_80BF1150(this, globalCtx, ACTORCAT_NPC, ACTOR_EN_AN); + } else { + retActor = &GET_PLAYER(globalCtx)->actor; + } + return retActor; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ig/func_80BF1DF4.s") +void func_80BF14B0(EnIg* this) { + s32 pad; + Vec3f sp40; + Vec3f sp34; + s32 pad2; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ig/func_80BF1FA8.s") + Math_Vec3f_Copy(&sp40, &this->unk_2A8->world.pos); + Math_Vec3f_Copy(&sp34, &this->actor.world.pos); + Math_ApproachS(&this->unk_3EA, Math_Vec3f_Yaw(&sp34, &sp40) - this->actor.shape.rot.y, 4, 0x2AA8); + this->unk_3EA = CLAMP(this->unk_3EA, -0x1C70, 0x1C70); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ig/func_80BF219C.s") + Math_Vec3f_Copy(&sp34, &this->actor.focus.pos); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ig/func_80BF2368.s") + if (this->unk_2A8->id == ACTOR_PLAYER) { + sp40.y = ((Player*)this->unk_2A8)->bodyPartsPos[7].y + 3.0f; + } else { + Math_Vec3f_Copy(&sp40, &this->unk_2A8->focus.pos); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ig/func_80BF2400.s") + Math_ApproachS(&this->unk_3E8, Math_Vec3f_Pitch(&sp34, &sp40), 4, 0x2AA8); + this->unk_3E8 = CLAMP(this->unk_3E8, -0xE38, 0xE38); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ig/func_80BF2470.s") +void func_80BF15EC(EnIg* this) { + if ((this->unk_3D0 & 0x20) && (this->unk_2A8 != 0)) { + if (DECR(this->unk_3EE) == 0) { + func_80BF14B0(this); + this->unk_3D0 &= ~0x200; + this->unk_3D0 |= 0x80; + return; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ig/func_80BF25E8.s") + if (this->unk_3D0 & 0x80) { + this->unk_3D0 &= ~0x80; + this->unk_3E4 = 0; + this->unk_3E6 = 0; + this->unk_3E8 = 0; + this->unk_3EA = 0; + this->unk_3EE = 20; + return; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ig/func_80BF2890.s") + if (DECR(this->unk_3EE) == 0) { + this->unk_3D0 |= 0x200; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ig/func_80BF293C.s") +s32 func_80BF16C8(EnIg* this, s16 arg1) { + s32 ret = false; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ig/func_80BF2A50.s") + if (ActorCutscene_GetCurrentIndex() == 0x7C) { + ActorCutscene_Stop(0x7C); + ActorCutscene_SetIntentToPlay(arg1); + } else if (ActorCutscene_GetCanPlayNext(arg1)) { + ActorCutscene_StartAndSetUnkLinkFields(arg1, &this->actor); + ret = true; + } else { + ActorCutscene_SetIntentToPlay(arg1); + } + return ret; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ig/func_80BF2AF8.s") +s16 func_80BF1744(EnIg* this, s32 arg1) { + s16 cs = -1; + s32 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ig/func_80BF2BD4.s") + if ((this->actor.child != NULL) && (this->actor.child->update != NULL)) { + cs = this->actor.child->cutscene; + for (i = 0; i < arg1; i++) { + cs = ActorCutscene_GetAdditionalCutscene(cs); + } + } + return cs; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ig/EnIg_Init.s") +s32 func_80BF17BC(EnIg* this, GlobalContext* globalCtx) { + s32 pad; + s16 sp2A; + s32 ret; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ig/EnIg_Destroy.s") + sp2A = func_80BF1744(this, 0); + ret = false; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ig/EnIg_Update.s") + switch (this->unk_3F6) { + case 0: + if (func_80BF16C8(this, sp2A)) { + case 2: + case 4: + if ((this->actor.child != NULL) && (this->actor.child->update != NULL)) { + func_800E0308(Play_GetCamera(globalCtx, ActorCutscene_GetCurrentCamera(sp2A)), + this->actor.child); + } + this->unk_3F6++; + ret = true; + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ig/func_80BF2EDC.s") + case 1: + case 3: + if (!(gSaveContext.weekEventReg[75] & 0x10) && (this->unk_3F6 == 3)) { + ActorCutscene_Stop(sp2A); + this->unk_3F6 = 5; + } else { + func_800E0308(Play_GetCamera(globalCtx, ActorCutscene_GetCurrentCamera(sp2A)), &this->actor); + } + this->unk_3F6++; + ret = true; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ig/func_80BF2EFC.s") + case 5: + ActorCutscene_Stop(sp2A); + this->unk_3F6++; + ret = true; + break; + } + return ret; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ig/func_80BF302C.s") +s32* func_80BF1920(EnIg* this, GlobalContext* globalCtx) { + switch (this->unk_298.unk0) { + case 3: + this->unk_3F8 = func_80BF17BC; + return D_80BF335C; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ig/EnIg_Draw.s") + case 4: + return D_80BF33F0; + + case 2: + case 11: + case 14: + return D_80BF33E0; + + case 10: + case 12: + return D_80BF3354; + + case 13: + return D_80BF33E8; + + default: + return NULL; + } +} + +s32 func_80BF19A0(EnIg* this, GlobalContext* globalCtx) { + s32 ret = false; + + if (this->unk_3D0 & 7) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + func_8013AED4(&this->unk_3D0, 0, 7); + this->unk_3F6 = 0; + this->unk_3F8 = NULL; + this->actor.child = this->unk_2A8; + this->unk_298.unk4 = func_80BF1920(this, globalCtx); + if ((this->unk_298.unk0 != 2) && (this->unk_298.unk0 != 3) && (this->unk_298.unk0 != 4)) { + this->unk_3D0 |= 0x20; + } + this->actionFunc = func_80BF2BD4; + ret = true; + } + } + return ret; +} + +void func_80BF1A60(EnIg* this, GlobalContext* globalCtx) { + if (this->unk_3F4 == 0) { + func_80BF1284(this, 4); + this->unk_3F4++; + } else if ((this->unk_3F4 == 1) && Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { + func_80BF1284(this, 5); + this->unk_3F4++; + } +} + +s32 func_80BF1AE0(EnIg* this, GlobalContext* globalCtx) { + switch (this->unk_298.unk0) { + case 3: + func_80BF1284(this, 0); + break; + + case 10: + case 11: + case 12: + case 13: + case 14: + func_80BF1284(this, 2); + break; + } + return true; +} + +s32 func_80BF1B40(EnIg* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + u16 temp = globalCtx->msgCtx.unk11F04; + s32 pad; + + if (player->stateFlags1 & 0xC40) { + this->unk_3D0 |= 0x400; + if (this->unk_3D2 != temp) { + if ((this->unk_3FC == 2) || (this->unk_3FC == 3)) { + func_80BF1284(this, 0); + } + + if ((temp == 0x28B0) || (temp == 0x28B7)) { + this->unk_18C = func_80BF1A60; + this->unk_3F4 = 0; + } + } + this->unk_3D2 = temp; + } else if (this->unk_3D0 & 0x400) { + this->unk_3D2 = 0; + this->unk_3D0 &= ~0x400; + if (1) {} + func_80BF1AE0(this, globalCtx); + } + + if (this->unk_18C != NULL) { + this->unk_18C(this, globalCtx); + } + + return false; +} + +s32 func_80BF1C44(EnIg* this, GlobalContext* globalCtx, struct_80133038_arg2* arg2, s32 arg3, s32 arg4) { + u8 sp4F = ENIG_GET_FF(&this->actor); + Vec3s* sp48; + Vec3f sp3C; + Vec3f sp30; + Actor* sp2C; + s32 pad; + s32 sp24 = false; + + sp2C = func_80BF1150(this, globalCtx, arg3, arg4); + this->unk_274 = NULL; + + if (D_80BF3318[arg2->unk0] >= 0) { + this->unk_274 = func_8013BB34(globalCtx, sp4F, D_80BF3318[arg2->unk0]); + } + + if ((sp2C != NULL) && (sp2C->update != NULL)) { + if (this->unk_274 != NULL) { + sp48 = Lib_SegmentedToVirtual(this->unk_274->points); + Math_Vec3s_ToVec3f(&sp3C, &sp48[this->unk_274->count - 2]); + Math_Vec3s_ToVec3f(&sp30, &sp48[this->unk_274->count - 1]); + this->actor.shape.shadowDraw = NULL; + this->actor.world.rot.y = Math_Vec3f_Yaw(&sp3C, &sp30); + Math_Vec3f_Copy(&this->actor.world.pos, &sp30); + sp24 = true; + } + } + return sp24; +} + +s32 func_80BF1D78(EnIg* this, GlobalContext* globalCtx, struct_80133038_arg2* arg2) { + s32 sp2C = 0; + + if (func_80BF1C44(this, globalCtx, arg2, ACTORCAT_NPC, ACTOR_EN_AN)) { + func_80BF1284(this, 0); + func_8013AED4(&this->unk_3D0, 3, 7); + this->unk_3D0 |= 0x20; + this->unk_3D0 |= 0x100; + sp2C = true; + } + return sp2C; +} + +s32 func_80BF1DF4(EnIg* this, GlobalContext* globalCtx, struct_80133038_arg2* arg2) { + u16 sp56 = gSaveContext.time - 0x3FFC; + u8 sp55 = ENIG_GET_FF(&this->actor); + EnDoor* sp50; + Vec3s* sp4C; + Vec3f sp40; + Vec3f sp34; + s32 pad; + s32 ret = false; + + this->unk_274 = NULL; + sp50 = func_80BF1200(globalCtx, arg2->unk0); + + if (D_80BF3318[arg2->unk0] >= 0) { + this->unk_274 = func_8013BB34(globalCtx, sp55, D_80BF3318[arg2->unk0]); + } + + if ((sp50 != NULL) && (sp50->actor.update != NULL)) { + if (this->unk_274 != NULL) { + sp4C = Lib_SegmentedToVirtual(this->unk_274->points); + Math_Vec3s_ToVec3f(&sp40, &sp4C[0]); + Math_Vec3s_ToVec3f(&sp34, &sp4C[1]); + Math_Vec3f_Copy(&this->unk_2B0, &sp40); + Math_Vec3f_Copy(&this->unk_2BC, &sp34); + this->actor.world.rot.y = Math_Vec3f_Yaw(&sp40, &sp34); + Math_Vec3f_Copy(&this->actor.world.pos, &sp40); + + if (ABS_ALT(BINANG_SUB(this->actor.world.rot.y, sp50->actor.shape.rot.y)) <= 0x4000) { + this->unk_2A4 = -75; + } else { + this->unk_2A4 = 75; + } + + this->unk_3E0 = arg2->unk8 - arg2->unk4; + this->unk_3E2 = sp56 - arg2->unk4; + this->actor.flags &= ~1; + this->unk_3D0 |= 0x100; + func_80BF1284(this, 3); + this->actor.gravity = 0.0f; + ret = true; + } + } + return ret; +} + +s32 func_80BF1FA8(EnIg* this, GlobalContext* globalCtx, struct_80133038_arg2* arg2) { + u16 sp2E = gSaveContext.time - 0x3FFC; + u16 phi_v1; + u8 sp2B = ENIG_GET_FF(&this->actor); + s32 temp_t8; + s32 ret = false; + + this->unk_274 = NULL; + + if (D_80BF3318[arg2->unk0] >= 0) { + this->unk_274 = func_8013BB34(globalCtx, sp2B, D_80BF3318[arg2->unk0]); + } + + if ((this->unk_274 != NULL) && (this->unk_274->count < 3)) { + this->unk_274 = NULL; + } + + if (this->unk_274 != NULL) { + temp_t8 = this->unk_298.unk0; + if ((temp_t8 < 10) && (temp_t8 != 0) && (this->unk_3EC >= 0)) { + phi_v1 = sp2E; + } else { + phi_v1 = arg2->unk4; + } + + if (arg2->unk8 < phi_v1) { + this->unk_288 = (phi_v1 - arg2->unk8) + 0xFFFF; + } else { + this->unk_288 = arg2->unk8 - phi_v1; + } + + this->unk_294 = sp2E - phi_v1; + + phi_v1 = (this->unk_274->count - 2) & 0xFFFF; + + this->unk_28C = this->unk_288 / phi_v1; + this->unk_290 = (this->unk_294 / this->unk_28C) + 2; + + this->unk_3D0 &= ~0x8; + this->unk_3D0 &= ~0x10; + func_8013AED4(&this->unk_3D0, 3, 7); + this->unk_3D0 |= 0x100; + func_80BF1284(this, 2); + this->actor.gravity = -1.0f; + ret = true; + } + return ret; +} + +s32 func_80BF219C(EnIg* this, GlobalContext* globalCtx, struct_80133038_arg2* arg2) { + u8 sp4F = ENIG_GET_FF(&this->actor); + Vec3f sp40; + Vec3f sp34; + Vec3s* sp30; + s32 pad; + s32 ret = false; + + this->unk_274 = NULL; + + if (D_80BF3318[arg2->unk0] >= 0) { + this->unk_274 = func_8013BB34(globalCtx, sp4F, D_80BF3318[arg2->unk0]); + } + + if ((this->unk_274 != 0) && (this->unk_274->count >= 2)) { + sp30 = Lib_SegmentedToVirtual(this->unk_274->points); + Math_Vec3s_ToVec3f(&sp40, &sp30[this->unk_274->count - 1]); + Math_Vec3s_ToVec3f(&sp34, &sp30[this->unk_274->count - 2]); + this->actor.world.rot.y = Math_Vec3f_Yaw(&sp34, &sp40); + Math_Vec3s_Copy(&this->actor.shape.rot, &this->actor.world.rot); + Math_Vec3f_Copy(&this->actor.world.pos, &sp40); + Math_Vec3f_Copy(&this->actor.prevPos, &sp40); + + switch (arg2->unk0) { + case 2: + this->actor.home.rot.y = this->actor.world.rot.y; + this->actor.home.rot.y += 0x8000; + func_8013AED4(&this->unk_3D0, 3, 7); + this->unk_3D0 |= 0x100; + func_80BF1284(this, 1); + break; + + case 4: + this->actor.world.rot.y += 0x8000; + this->actor.shape.rot.y = this->actor.world.rot.y; + func_8013AED4(&this->unk_3D0, 3, 7); + this->unk_3D0 |= 0x100; + func_80BF1284(this, 8); + break; + } + ret = true; + } + return ret; +} + +s32 func_80BF2368(EnIg* this, GlobalContext* globalCtx, struct_80133038_arg2* arg2) { + s32 ret = false; + + this->actor.targetMode = 0; + this->unk_3D0 = 0; + this->actor.flags |= 1; + + switch (arg2->unk0) { + case 5: + case 6: + case 7: + case 8: + case 9: + ret = func_80BF1DF4(this, globalCtx, arg2); + break; + + case 10: + case 11: + case 12: + case 13: + case 14: + ret = func_80BF1FA8(this, globalCtx, arg2); + break; + + case 2: + case 4: + ret = func_80BF219C(this, globalCtx, arg2); + break; + + case 3: + ret = func_80BF1D78(this, globalCtx, arg2); + break; + } + return ret; +} + +s32 func_80BF2400(EnIg* this, GlobalContext* globalCtx) { + Vec3f sp2C; + Vec3f sp20; + + if ((this->unk_2A8 != NULL) && (this->unk_2A8->update != NULL)) { + Math_Vec3f_Copy(&sp2C, &this->unk_2A8->world.pos); + Math_Vec3f_Copy(&sp20, &this->actor.world.pos); + this->actor.world.rot.y = Math_Vec3f_Yaw(&sp20, &sp2C); + } + + return true; +} + +s32 func_80BF2470(EnIg* this, GlobalContext* globalCtx) { + EnDoor* sp44 = func_80BF1200(globalCtx, this->unk_298.unk0); + Vec3f sp38; + f32 temp; + s32 pad; + + if (!func_8013AD6C(globalCtx) && (this->unk_3EC != 0)) { + if ((sp44 != NULL) && (sp44->actor.update != NULL)) { + if (((f32)this->unk_3E2 / this->unk_3E0) <= 0.9f) { + sp44->unk_1A7 = this->unk_2A4; + } else { + sp44->unk_1A7 = 0; + } + } + this->unk_3E2 = CLAMP(this->unk_3E2, 0, this->unk_3E0); + temp = Math_Vec3f_DistXZ(&this->unk_2B0, &this->unk_2BC) / this->unk_3E0; + sp38.x = 0.0f; + sp38.y = 0.0f; + sp38.z = this->unk_3E2 * temp; + Lib_Vec3f_TranslateAndRotateY(&this->unk_2B0, this->actor.world.rot.y, &sp38, &this->actor.world.pos); + this->unk_3E2 += this->unk_3EC; + if (Animation_OnFrame(&this->skelAnime, 0.0f) || Animation_OnFrame(&this->skelAnime, 13.0f)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_PIRATE_WALK); + } + } + return false; +} + +s32 func_80BF25E8(EnIg* this, GlobalContext* globalCtx) { + f32 sp7C[265]; + Vec3f sp70; + Vec3f sp64; + Vec3f sp58; + s32 sp54 = 0; + s32 sp50 = 0; + s32 pad; + + func_8013AF00(sp7C, 3, this->unk_274->count + 3); + if (!(this->unk_3D0 & 8)) { + sp58 = gZeroVec3f; + func_8013B6B0(this->unk_274, &this->unk_284, &this->unk_294, this->unk_28C, this->unk_288, &this->unk_290, sp7C, + &sp58, this->unk_3EC); + func_8013B878(globalCtx, this->unk_274, this->unk_290, &sp58); + this->actor.world.pos.y = sp58.y; + this->unk_3D0 |= 8; + } else { + sp58 = this->unk_278; + } + + this->actor.world.pos.x = sp58.x; + this->actor.world.pos.z = sp58.z; + + if (func_8013AD6C(globalCtx)) { + sp54 = this->unk_294; + sp50 = this->unk_290; + sp58 = this->actor.world.pos; + } + + this->unk_278 = gZeroVec3f; + + if (func_8013B6B0(this->unk_274, &this->unk_284, &this->unk_294, this->unk_28C, this->unk_288, &this->unk_290, sp7C, + &this->unk_278, this->unk_3EC)) { + this->unk_3D0 |= 0x10; + } else { + sp70 = this->actor.world.pos; + sp64 = this->unk_278; + this->actor.world.rot.y = Math_Vec3f_Yaw(&sp70, &sp64); + } + + if (func_8013AD6C(globalCtx)) { + this->unk_294 = sp54; + this->unk_290 = sp50; + this->unk_278 = sp58; + } else if (Animation_OnFrame(&this->skelAnime, 0.0f) || Animation_OnFrame(&this->skelAnime, 13.0f)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_PIRATE_WALK); + } + return false; +} + +s32 func_80BF2890(EnIg* this, GlobalContext* globalCtx) { + if ((this->unk_3D0 & 0x100) && (this->unk_3F2 == 2)) { + this->unk_3D0 &= ~0x100; + } + + if (!(this->unk_3D0 & 0x100) && Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { + if (this->unk_408 != 0) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_GOLON_SNORE1); + } else { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_GOLON_SNORE2); + } + this->unk_408 ^= 1; + } + return true; +} + +s32 func_80BF293C(EnIg* this, GlobalContext* globalCtx) { + if (this->actor.world.rot.y != this->actor.home.rot.y) { + if ((this->actor.world.rot.y / 182) != (this->actor.home.rot.y / 182)) { + Math_ApproachS(&this->actor.world.rot.y, this->actor.home.rot.y, 3, 0x2AA8); + } else { + this->actor.world.rot.y = this->actor.home.rot.y; + func_80BF1284(this, 7); + } + } else if ((this->unk_3FC == 7) && Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { + func_8013AED4(&this->unk_3D0, 3, 7); + func_80BF1284(this, 9); + } + return true; +} + +void func_80BF2A50(EnIg* this, GlobalContext* globalCtx) { + switch (this->unk_298.unk0) { + case 10: + case 11: + case 12: + case 13: + case 14: + func_80BF25E8(this, globalCtx); + break; + + case 5: + case 6: + case 7: + case 8: + case 9: + func_80BF2470(this, globalCtx); + break; + + case 2: + func_80BF293C(this, globalCtx); + break; + + case 3: + func_80BF2400(this, globalCtx); + break; + + case 4: + func_80BF2890(this, globalCtx); + break; + } + Math_ApproachS(&this->actor.shape.rot.y, this->actor.world.rot.y, 3, 0x2AA8); +} + +void func_80BF2AF8(EnIg* this, GlobalContext* globalCtx) { + u32* unk_14 = &gSaveContext.unk_14; + struct_80133038_arg2 sp20; + + this->unk_3EC = REG(15) + *unk_14; + + if (!func_80133038(globalCtx, D_80BF3260, &sp20) || + ((this->unk_298.unk0 != sp20.unk0) && !func_80BF2368(this, globalCtx, &sp20))) { + this->actor.shape.shadowDraw = NULL; + this->actor.flags &= ~1; + sp20.unk0 = 0; + } else { + this->actor.shape.shadowDraw = ActorShadow_DrawCircle; + this->actor.flags |= 1; + } + this->unk_2A8 = func_80BF146C(this, globalCtx); + this->unk_298.unk0 = sp20.unk0; + func_80BF2A50(this, globalCtx); +} + +void func_80BF2BD4(EnIg* this, GlobalContext* globalCtx) { + s16 yaw; + Vec3f sp38; + Vec3f sp2C; + + if (func_8010BF58(&this->actor, globalCtx, this->unk_298.unk4, this->unk_3F8, &this->unk_298.unk8)) { + func_8013AED4(&this->unk_3D0, 3, 7); + this->unk_3D0 &= ~0x20; + this->unk_3D0 |= 0x200; + this->unk_3EE = 20; + this->unk_298.unk8 = 0; + this->actionFunc = func_80BF2AF8; + } else if (((this->unk_298.unk0 != 2) && (this->unk_298.unk0 != 4)) && + ((this->unk_2A8 != NULL) && (this->unk_2A8->update != NULL))) { + Math_Vec3f_Copy(&sp38, &this->unk_2A8->world.pos); + Math_Vec3f_Copy(&sp2C, &this->actor.world.pos); + yaw = Math_Vec3f_Yaw(&sp2C, &sp38); + Math_ApproachS(&this->actor.shape.rot.y, yaw, 4, 0x2AA8); + } +} + +void EnIg_Init(Actor* thisx, GlobalContext* globalCtx) { + EnIg* this = THIS; + + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 28.0f); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_dai_Skel_0130D0, NULL, this->jointTable, this->morphTable, + 19); + this->unk_3FC = -1; + func_80BF1284(this, 0); + Collider_InitAndSetCylinder(globalCtx, &this->collider1, &this->actor, &sCylinderInit); + Collider_InitAndSetSphere(globalCtx, &this->collider2, &this->actor, &sSphereInit); + CollisionCheck_SetInfo2(&this->actor.colChkInfo, DamageTable_Get(0x16), &sColChkInfoInit); + Actor_SetScale(&this->actor, 0.01f); + this->unk_298.unk0 = 0; + this->actor.gravity = 0.0f; + this->actionFunc = func_80BF2AF8; + this->actionFunc(this, globalCtx); +} + +void EnIg_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnIg* this = THIS; + + Collider_DestroyCylinder(globalCtx, &this->collider1); + Collider_DestroySphere(globalCtx, &this->collider2); +} + +void EnIg_Update(Actor* thisx, GlobalContext* globalCtx) { + EnIg* this = THIS; + + func_80BF19A0(this, globalCtx); + + this->actionFunc(this, globalCtx); + + func_80BF1B40(this, globalCtx); + + if (this->unk_298.unk0 != 0) { + func_80BF1258(this); + func_80BF13E4(this); + func_80BF15EC(this); + func_8013C964(&this->actor, globalCtx, 60.0f, 30.0f, 0, this->unk_3D0 & 7); + Actor_MoveWithGravity(&this->actor); + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 30.0f, 12.0f, 0.0f, 4); + func_80BF1354(this, globalCtx); + } +} + +s32 EnIg_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx, + Gfx** gfx) { + EnIg* this = THIS; + + if (limbIndex == 10) { + *dList = NULL; + } + return false; +} + +void EnIg_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx, Gfx** gfx) { + static Vec3f D_80BF351C = { 1800.0f, -2000.0f, 0.0f }; + static Vec3f D_80BF3528 = { 0.0f, 0.0f, 0.0f }; + s32 pad; + EnIg* this = THIS; + Vec3f sp2C; + + if (limbIndex == 11) { + Matrix_MultiplyVector3fByState(&D_80BF3528, &this->actor.focus.pos); + Math_Vec3s_Copy(&this->actor.focus.rot, &this->actor.world.rot); + + gSPDisplayList((*gfx)++, object_dai_DL_008710); + gSPDisplayList((*gfx)++, object_dai_DL_0087B8); + } + + if (limbIndex == 12) { + gSPDisplayList((*gfx)++, object_dai_DL_0089D8); + } + + if (limbIndex == 9) { + gSPDisplayList((*gfx)++, object_dai_DL_008B00); + Matrix_MultiplyVector3fByState(&D_80BF351C, &sp2C); + Math_Vec3f_ToVec3s(&this->collider2.dim.worldSphere.center, &sp2C); + } + + if (limbIndex == 10) { + Matrix_CopyCurrentState(&this->unk_190); + } +} + +void EnIg_UnkDraw(GlobalContext* globalCtx, s32 limbIndex, Actor* thisx, Gfx** gfx) { + EnIg* this = THIS; + s32 phi_v0; + s32 phi_v1; + + if (!(this->unk_3D0 & 0x200)) { + if (this->unk_3D0 & 0x80) { + phi_v1 = 1; + } else { + phi_v1 = 0; + } + phi_v0 = 1; + } else { + phi_v1 = 0; + phi_v0 = 0; + } + + if (limbIndex == 9) { + func_8013AD9C(this->unk_3E8 + 0x4000, this->unk_3EA + this->actor.shape.rot.y + 0x4000, &this->unk_2D4, + &this->unk_2E6, phi_v0, phi_v1); + Matrix_StatePop(); + Matrix_InsertTranslation(this->unk_2D4.x, this->unk_2D4.y, this->unk_2D4.z, MTXMODE_NEW); + Matrix_Scale(this->actor.scale.x, this->actor.scale.y, this->actor.scale.z, MTXMODE_APPLY); + Matrix_RotateY(this->unk_2E6.y, MTXMODE_APPLY); + Matrix_InsertXRotation_s(this->unk_2E6.x, MTXMODE_APPLY); + Matrix_InsertZRotation_s(this->unk_2E6.z, MTXMODE_APPLY); + Matrix_StatePush(); + } +} + +void EnIg_Draw(Actor* thisx, GlobalContext* globalCtx) { + static TexturePtr D_80BF3534[] = { + &object_dai_Tex_0107B0, &object_dai_Tex_010FB0, &object_dai_Tex_0117B0, + &object_dai_Tex_011FB0, &object_dai_Tex_0127B0, + }; + s32 pad; + EnIg* this = THIS; + + if (this->unk_298.unk0 != 0) { + func_8012C28C(globalCtx->state.gfxCtx); + + OPEN_DISPS(globalCtx->state.gfxCtx); + + Scene_SetRenderModeXlu(globalCtx, 0, 1); + + gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(D_80BF3534[this->unk_3F2])); + + POLY_OPA_DISP = + func_8013AB00(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, + EnIg_OverrideLimbDraw, EnIg_PostLimbDraw, EnIg_UnkDraw, &this->actor, POLY_OPA_DISP); + Matrix_SetCurrentState(&this->unk_190); + + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, object_dai_DL_00C538); + + CLOSE_DISPS(globalCtx->state.gfxCtx); + } +} diff --git a/src/overlays/actors/ovl_En_Ig/z_en_ig.h b/src/overlays/actors/ovl_En_Ig/z_en_ig.h index 19050087e..200c751b1 100644 --- a/src/overlays/actors/ovl_En_Ig/z_en_ig.h +++ b/src/overlays/actors/ovl_En_Ig/z_en_ig.h @@ -6,12 +6,58 @@ struct EnIg; typedef void (*EnIgActionFunc)(struct EnIg*, GlobalContext*); +typedef s32 (*EnIgUnkFunc)(struct EnIg*, GlobalContext*); +typedef void (*EnIgUnkFunc2)(struct EnIg*, GlobalContext*); + +#define ENIG_GET_FF(thisx) ((thisx)->params & 0xFF) typedef struct EnIg { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x44]; + /* 0x0144 */ SkelAnime skelAnime; /* 0x0188 */ EnIgActionFunc actionFunc; - /* 0x018C */ char unk_18C[0x280]; + /* 0x018C */ EnIgUnkFunc2 unk_18C; + /* 0x0190 */ MtxF unk_190; + /* 0x01D0 */ ColliderCylinder collider1; + /* 0x021C */ ColliderSphere collider2; + /* 0x0274 */ Path* unk_274; + /* 0x0278 */ Vec3f unk_278; + /* 0x0284 */ f32 unk_284; + /* 0x0288 */ s32 unk_288; + /* 0x028C */ s32 unk_28C; + /* 0x0290 */ s32 unk_290; + /* 0x0294 */ s32 unk_294; + /* 0x0298 */ struct_80133038_arg2 unk_298; + /* 0x02A4 */ s8 unk_2A4; + /* 0x02A8 */ Actor* unk_2A8; + /* 0x02AC */ UNK_TYPE1 unk2AC[0x4]; + /* 0x02B0 */ Vec3f unk_2B0; + /* 0x02BC */ Vec3f unk_2BC; + /* 0x02C8 */ UNK_TYPE1 unk2C8[0xC]; + /* 0x02D4 */ Vec3f unk_2D4; + /* 0x02E0 */ UNK_TYPE1 unk2E0[0x6]; + /* 0x02E6 */ Vec3s unk_2E6; + /* 0x02EC */ Vec3s jointTable[19]; + /* 0x035E */ Vec3s morphTable[19]; + /* 0x03D0 */ u16 unk_3D0; + /* 0x03D2 */ u16 unk_3D2; + /* 0x03D4 */ f32 unk_3D4; + /* 0x03D8 */ UNK_TYPE1 unk3D8[0x8]; + /* 0x03E0 */ s16 unk_3E0; + /* 0x03E2 */ s16 unk_3E2; + /* 0x03E4 */ s16 unk_3E4; + /* 0x03E6 */ s16 unk_3E6; + /* 0x03E8 */ s16 unk_3E8; + /* 0x03EA */ s16 unk_3EA; + /* 0x03EC */ s16 unk_3EC; + /* 0x03EE */ s16 unk_3EE; + /* 0x03F0 */ s16 unk_3F0; + /* 0x03F2 */ s16 unk_3F2; + /* 0x03F4 */ s16 unk_3F4; + /* 0x03F6 */ s16 unk_3F6; + /* 0x03F8 */ EnIgUnkFunc unk_3F8; + /* 0x03FC */ s32 unk_3FC; + /* 0x0400 */ UNK_TYPE1 unk400[0x8]; + /* 0x0408 */ s32 unk_408; } EnIg; // size = 0x40C extern const ActorInit En_Ig_InitVars; diff --git a/tools/disasm/functions.txt b/tools/disasm/functions.txt index fe6a3dfdb..25784be00 100644 --- a/tools/disasm/functions.txt +++ b/tools/disasm/functions.txt @@ -16315,9 +16315,9 @@ 0x80BF2CC0:("EnIg_Init",), 0x80BF2DC4:("EnIg_Destroy",), 0x80BF2E04:("EnIg_Update",), - 0x80BF2EDC:("func_80BF2EDC",), - 0x80BF2EFC:("func_80BF2EFC",), - 0x80BF302C:("func_80BF302C",), + 0x80BF2EDC:("EnIg_OverrideLimbDraw",), + 0x80BF2EFC:("EnIg_PostLimbDraw",), + 0x80BF302C:("EnIg_UnkDraw",), 0x80BF312C:("EnIg_Draw",), 0x80BF3920:("func_80BF3920",), 0x80BF3C64:("func_80BF3C64",), diff --git a/undefined_syms.txt b/undefined_syms.txt index 1168dbcab..2d897a3ec 100644 --- a/undefined_syms.txt +++ b/undefined_syms.txt @@ -2454,15 +2454,6 @@ D_0600A480 = 0x0600A480; D_060005C0 = 0x060005C0; D_06006260 = 0x06006260; -// ovl_En_Ig - -D_06008710 = 0x06008710; -D_060087B8 = 0x060087B8; -D_060089D8 = 0x060089D8; -D_06008B00 = 0x06008B00; -D_0600C538 = 0x0600C538; -D_060130D0 = 0x060130D0; - // ovl_En_Ik D_06000CE8 = 0x06000CE8; From 924fa9aadf99f9efdc3cd19411bb1c834f3ad74c Mon Sep 17 00:00:00 2001 From: EllipticEllipsis <73679967+EllipticEllipsis@users.noreply.github.com> Date: Sun, 16 Jan 2022 17:55:03 +0000 Subject: [PATCH 05/13] EnMag OK and documented (#547) * Name textures in object_mag * Corrections * tabs -> spaces * OK, data imported * Remove obsolete comment * Start documentation * Defines for most texture sizes * Name most static variables, add state enum * Macros, name all the statics * Couple of minor tweaks to other files * Name some more effect stuff * Fix kanfont data * Name everything else, move macros * Format * Review --- assets/xml/objects/object_mag.xml | 26 +- include/functions.h | 2 +- include/macros.h | 15 + include/z64.h | 4 +- spec | 3 +- src/code/sys_math.c | 2 +- src/code/z_kanfont.c | 14 +- src/overlays/actors/ovl_En_Mag/z_en_mag.c | 947 +++++++++++++++++++- src/overlays/actors/ovl_En_Mag/z_en_mag.h | 40 +- src/overlays/gamestates/ovl_title/z_title.c | 3 +- tools/disasm/functions.txt | 14 +- tools/disasm/variables.txt | 42 +- 12 files changed, 1045 insertions(+), 67 deletions(-) diff --git a/assets/xml/objects/object_mag.xml b/assets/xml/objects/object_mag.xml index 1feae8057..6ec4426d8 100644 --- a/assets/xml/objects/object_mag.xml +++ b/assets/xml/objects/object_mag.xml @@ -5,18 +5,20 @@ - - - - - - - - - - - - + + + + + + + + + + + + + + diff --git a/include/functions.h b/include/functions.h index 3c20bca11..14744a9de 100644 --- a/include/functions.h +++ b/include/functions.h @@ -3768,7 +3768,7 @@ void func_801A3CD8(s8 param_1); // void func_801A3D98(void); // void func_801A3E38(void); // void func_801A3EC0(void); -void func_801A3F54(s32 arg0); +void func_801A3F54(u8 flag); // void func_801A3F6C(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5, UNK_TYPE4 param_6); // void func_801A3FB4(void); // void func_801A3FFC(UNK_TYPE1 param_1); diff --git a/include/macros.h b/include/macros.h index c5fc2c4ae..4253eb6cd 100644 --- a/include/macros.h +++ b/include/macros.h @@ -127,6 +127,21 @@ extern GraphicsContext* __gfxCtx; #define GRAPH_ALLOC(gfxCtx, size) ((void*)((gfxCtx)->polyOpa.d = (Gfx*)((u8*)(gfxCtx)->polyOpa.d - (size)))) +// Custom gbi macro +#define gDPSetTileCustom(pkt, fmt, siz, width, height, pal, cms, cmt, masks, maskt, shifts, shiftt) \ + { \ + gDPPipeSync(pkt); \ + gDPTileSync(pkt); \ + gDPSetTile(pkt, fmt, siz, (((width)*siz##_TILE_BYTES) + 7) >> 3, 0, G_TX_LOADTILE, 0, cmt, maskt, shiftt, cms, \ + masks, shifts); \ + gDPTileSync(pkt); \ + gDPSetTile(pkt, fmt, siz, (((width)*siz##_TILE_BYTES) + 7) >> 3, 0, G_TX_RENDERTILE, pal, cmt, maskt, shiftt, \ + cms, masks, shifts); \ + gDPSetTileSize(pkt, G_TX_RENDERTILE, 0, 0, ((width)-1) << G_TEXTURE_IMAGE_FRAC, \ + ((height)-1) << G_TEXTURE_IMAGE_FRAC); \ + } \ + (void)0 + #define ALIGN8(val) (((val) + 7) & ~7) #define ALIGN16(val) (((val) + 0xF) & ~0xF) #define ALIGN64(val) (((val) + 0x3F) & ~0x3F) diff --git a/include/z64.h b/include/z64.h index f468d32aa..cb41a8249 100644 --- a/include/z64.h +++ b/include/z64.h @@ -167,8 +167,10 @@ typedef struct { /* 0x5 */ Color_RGB8 envColor; } FireObjLightParams; // size = 0x8 +#define FONT_CHAR_TEX_WIDTH 16 +#define FONT_CHAR_TEX_HEIGHT 16 //! @TODO: Make this use `sizeof(AnyFontTextureSymbol)` -#define FONT_CHAR_TEX_SIZE ((16 * 16) / 2) +#define FONT_CHAR_TEX_SIZE ((16 * 16) / 2) // 16x16 I4 texture // Font textures are loaded into here typedef struct { diff --git a/spec b/spec index 98cd58af9..de71a0e4f 100644 --- a/spec +++ b/spec @@ -1754,8 +1754,7 @@ beginseg name "ovl_En_Mag" compress include "build/src/overlays/actors/ovl_En_Mag/z_en_mag.o" - include "build/data/ovl_En_Mag/ovl_En_Mag.data.o" - include "build/data/ovl_En_Mag/ovl_En_Mag.reloc.o" + include "build/src/overlays/actors/ovl_En_Mag/ovl_En_Mag_reloc.o" endseg beginseg diff --git a/src/code/sys_math.c b/src/code/sys_math.c index 9b274c7e2..da4ccc9d2 100644 --- a/src/code/sys_math.c +++ b/src/code/sys_math.c @@ -34,7 +34,7 @@ f32 func_80179400(s32 n) { //! @bug No check for negative argument. Will read the array out-of-bounds if the argument is negative. //! (The OoT version does an unsigned check instead, which will return sFactorialTbl[12] for a negative argument.) - if (n > 12) { + if (n >= ARRAY_COUNT(sFactorialTbl)) { ret = sFactorialTbl[12]; for (i = 13; i <= n; i++) { ret *= i; diff --git a/src/code/z_kanfont.c b/src/code/z_kanfont.c index b678642b1..2a4849ccb 100644 --- a/src/code/z_kanfont.c +++ b/src/code/z_kanfont.c @@ -19,11 +19,13 @@ void Font_LoadMessageBoxEndIcon(Font* font, u16 icon) { FONT_CHAR_TEX_SIZE); } -static u8 sFontOrdering[] = "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19" - "!\"#$%&\'()*+,-./0123456789:ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "\x00\x0D\x0E\x1A" - "afjmosvwxyz{|}~" - "\x7F\x80\x81\x84\x86\x87\x88\x89\x8A\x8B\x8C"; +static u8 sFontOrdering[] = { + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, + 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x41, 0x42, + 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, + 0x56, 0x57, 0x58, 0x59, 0x5A, 0x00, 0x0D, 0x0E, 0x1A, 0x61, 0x66, 0x6A, 0x6D, 0x6F, 0x73, 0x76, 0x77, 0x78, 0x79, + 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, 0x80, 0x81, 0x84, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, +}; void Font_LoadOrderedFont(Font* font) { u32 loadOffset; @@ -36,7 +38,7 @@ void Font_LoadOrderedFont(Font* font) { if (sFontOrdering[codePointIndex] == 0) { loadOffset = 0; } - // UB to convert pointer to u32 + DmaMgr_SendRequest0(writeLocation, (uintptr_t)SEGMENT_ROM_START(nes_font_static) + loadOffset, FONT_CHAR_TEX_SIZE); if (sFontOrdering[codePointIndex] == 0x8C) { diff --git a/src/overlays/actors/ovl_En_Mag/z_en_mag.c b/src/overlays/actors/ovl_En_Mag/z_en_mag.c index 6b18d43fd..6f2591952 100644 --- a/src/overlays/actors/ovl_En_Mag/z_en_mag.c +++ b/src/overlays/actors/ovl_En_Mag/z_en_mag.c @@ -5,6 +5,7 @@ */ #include "z_en_mag.h" +#include "objects/object_mag/object_mag.h" #define FLAGS 0x00000030 @@ -15,7 +16,75 @@ void EnMag_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnMag_Update(Actor* thisx, GlobalContext* globalCtx); void EnMag_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 +/** + * Steps `var` towards `target` linearly, so that it will arrive in `timeRemaining` seconds. Can be used from either + * direction. `timeRemaining` must be decremented separately for this to work properly, and obviously timeRemaining = 0 + * must be handled separately. + * + * @param var Variable to step. + * @param target Target to step towards. + * @param timeRemaining Number of times this function should be run for `var` to reach `target` + * @param stepVar Variable to use for the step (required to match). + * + * The progression is not quite linear because of truncation in the division, but the variable will always reach + * `target` at the appropriate time since the last step is always the full difference. + */ +#define TIMED_STEP_TO(var, target, timeRemaining, stepVar) \ + { \ + stepVar = ABS_ALT(var - target) / timeRemaining; \ + if (var >= target) { \ + var -= stepVar; \ + } else { \ + var += stepVar; \ + } \ + } \ + (void)0 + +/** + * Similar to `TIMED_STEP_TO`, but will always increase `var`. If var > target, this will eventually increase `var` by + * an amount that is at most ( timeRemaining + 1 ) * | var - target |, but which depends on the amount lost to + * truncation from the divisions. + */ +#define TIMED_STEP_UP_TO(var, target, timeRemaining, stepVar) \ + { \ + stepVar = ABS_ALT(var - target) / timeRemaining; \ + var += stepVar; \ + } \ + (void)0 + +/** + * Similar to `TIMED_STEP_TO`, but will always increase `var`. If var < target, this will eventually dncrease `var` by + * an amount that is at most ( timeRemaining + 1 ) * | var - target |, but which depends on the amount lost to + * truncation from the divisions. + */ +#define TIMED_STEP_DOWN_TO(var, target, timeRemaining, stepVar) \ + { \ + stepVar = ABS_ALT(var - target) / timeRemaining; \ + var -= stepVar; \ + } \ + (void)0 + +typedef enum { + /* 0 */ MAG_STATE_INITIAL, + /* 1 */ MAG_STATE_FADE_IN_MASK_EFFECTS, + /* 2 */ MAG_STATE_FADE_IN_MASK, + /* 3 */ MAG_STATE_FADE_IN_MAIN_TITLE, + /* 5 */ MAG_STATE_FADE_IN_SUBTITLE = 5, + /* 6 */ MAG_STATE_FADE_IN_COPYRIGHT, // And PRESS START + /* 10 */ MAG_STATE_CALLED = 10, // by a button press + /* 13 */ MAG_STATE_DISPLAY = 13, // Buttons will trigger File Select state + /* 20 */ MAG_STATE_FADE_OUT = 20, + /* 21 */ MAG_STATE_POST_DISPLAY // Go to next scene +} EnMagState; + +static s16 sInputDelayTimer = 0; + +static s16 sZeldaEffectColorTimer = 30; +static s16 sZeldaEffectColorTargetIndex = 0; + +static s16 sTextAlphaTargetIndex = 0; +static s16 sTextAlphaTimer = 20; + const ActorInit En_Mag_InitVars = { ACTOR_EN_MAG, ACTORCAT_PROP, @@ -28,28 +97,878 @@ const ActorInit En_Mag_InitVars = { (ActorFunc)EnMag_Draw, }; -#endif +void EnMag_Init(Actor* thisx, GlobalContext* globalCtx) { + EnMag* this = THIS; + u16 i; -extern UNK_TYPE D_06011E48; + this->unk11F54 = 6; + this->unk11F56 = 10; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mag/EnMag_Init.s") + for (i = 0; i < 6; i++) { + this->effectScrollSs[i] = 0; + this->effectScrollTs[i] = 0; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mag/EnMag_Destroy.s") + this->appearEffectPrimColor[0] = 255; + this->appearEffectPrimColor[1] = 155; + this->appearEffectPrimColor[2] = 255; + this->appearEffectEnvColor[0] = 0; + this->appearEffectEnvColor[1] = 255; + this->appearEffectEnvColor[2] = 155; + this->appearEffectPrimLodFrac = 20; + this->appearEffectAlpha = 0; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mag/func_8096B604.s") + this->displayEffectPrimColor[0] = 255; + this->displayEffectPrimColor[1] = 155; + this->displayEffectPrimColor[2] = 255; + this->displayEffectEnvColor[0] = 0; + this->displayEffectEnvColor[1] = 255; + this->displayEffectEnvColor[2] = 155; + this->displayEffectPrimLodFrac = 55; + this->displayEffectAlpha = 0; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mag/EnMag_Update.s") + this->majorasMaskAlpha = 0; + this->majorasMaskEnvColor[0] = this->majorasMaskEnvColor[1] = this->majorasMaskEnvColor[2] = 255; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mag/func_8096C998.s") + this->mainTitleAlpha = this->subtitleAlpha = this->unk11F32 = this->copyrightAlpha = 0; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mag/func_8096CBB0.s") + this->unk11F02 = 30; + this->unk11F00 = this->state = MAG_STATE_INITIAL; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mag/func_8096CDC8.s") + if (gSaveContext.unk_3F1E != 0) { + this->mainTitleAlpha = 210; + this->unk11F32 = 255; + this->copyrightAlpha = 255; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mag/func_8096D230.s") + this->appearEffectPrimLodFrac = 100; + this->appearEffectAlpha = 255; + this->appearEffectPrimColor[0] = 255; + this->appearEffectPrimColor[1] = 255; + this->appearEffectPrimColor[2] = 255; + this->appearEffectEnvColor[0] = 0; + this->appearEffectEnvColor[1] = 255; + this->appearEffectEnvColor[2] = 155; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mag/func_8096D60C.s") + this->displayEffectPrimLodFrac = 100; + this->displayEffectAlpha = 255; + this->displayEffectPrimColor[0] = 255; + this->displayEffectPrimColor[1] = 255; + this->displayEffectPrimColor[2] = 255; + this->displayEffectEnvColor[0] = 0; + this->displayEffectEnvColor[1] = 255; + this->displayEffectEnvColor[2] = 155; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mag/func_8096D74C.s") + gSaveContext.unk_3F1E = 0; + this->state = MAG_STATE_FADE_IN_MASK; + sInputDelayTimer = 20; + gSaveContext.fadeDuration = 1; + gSaveContext.unk_3F51 = 255; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mag/EnMag_Draw.s") + Font_LoadOrderedFont(&this->font); + + this->unk11F58 = 0; + this->unk11F5A = 0; + this->unk11F5C = 0; + this->unk11F60 = 0; + + this->majorasMaskEffectsFadeInTimer = 25; + this->majorasMaskFadeInTimer = 25; + this->mainTitleAlphaFadeInTimer = 20; + this->effectAlphaFadeInTimer = 40; + this->subtitleFadeInTimer = 10; + this->copyrightFadeInTimer = 10; + this->fadeOutTimer = 15; + + sZeldaEffectColorTimer = 30; + sZeldaEffectColorTargetIndex = 0; +} + +void EnMag_Destroy(Actor* thisx, GlobalContext* globalCtx) { +} + +void EnMag_UpdateDisplayEffectColors(Actor* thisx) { + static s16 sDisplayEffectPrimRedTargets[] = { 155, 255 }; + static s16 sDisplayEffectPrimGreenTargets[] = { 255, 155 }; + static s16 sDisplayEffectPrimBlueTargets[] = { 55, 255 }; + static s16 sDisplayEffectEnvRedTargets[] = { 255, 0 }; + static s16 sDisplayEffectEnvBlueTargets[] = { 255, 155 }; + EnMag* this = THIS; + s16 colorStep; + + TIMED_STEP_TO(this->displayEffectPrimColor[0], sDisplayEffectPrimRedTargets[sZeldaEffectColorTargetIndex], + sZeldaEffectColorTimer, colorStep); + TIMED_STEP_TO(this->displayEffectPrimColor[1], sDisplayEffectPrimGreenTargets[sZeldaEffectColorTargetIndex], + sZeldaEffectColorTimer, colorStep); + TIMED_STEP_TO(this->displayEffectPrimColor[2], sDisplayEffectPrimBlueTargets[sZeldaEffectColorTargetIndex], + sZeldaEffectColorTimer, colorStep); + TIMED_STEP_TO(this->displayEffectEnvColor[0], sDisplayEffectEnvRedTargets[sZeldaEffectColorTargetIndex], + sZeldaEffectColorTimer, colorStep); + // Skips 1, i.e. green. + TIMED_STEP_TO(this->displayEffectEnvColor[2], sDisplayEffectEnvBlueTargets[sZeldaEffectColorTargetIndex], + sZeldaEffectColorTimer, colorStep); + + sZeldaEffectColorTimer--; + if (sZeldaEffectColorTimer == 0) { + this->displayEffectPrimColor[0] = sDisplayEffectPrimRedTargets[sZeldaEffectColorTargetIndex]; + this->displayEffectPrimColor[1] = sDisplayEffectPrimGreenTargets[sZeldaEffectColorTargetIndex]; + this->displayEffectPrimColor[2] = sDisplayEffectPrimBlueTargets[sZeldaEffectColorTargetIndex]; + this->displayEffectEnvColor[0] = sDisplayEffectEnvRedTargets[sZeldaEffectColorTargetIndex]; + // Skips 1, i.e. green. + this->displayEffectEnvColor[2] = sDisplayEffectEnvBlueTargets[sZeldaEffectColorTargetIndex]; + sZeldaEffectColorTimer = 30; + sZeldaEffectColorTargetIndex ^= 1; + } +} + +/** + * Controls the actions performed using a switch and the `state` struct variable rather than action functions. Most of + * these are to do with fading various parts in and out. + */ +void EnMag_Update(Actor* thisx, GlobalContext* globalCtx) { + static s16 sAppearEffectPrimGreenTargets[] = { 255, 155 }; + static s16 sAppearEffectEnvRedTargets[] = { 255, 0 }; + static s16 sAppearEffectEnvBlueTargets[] = { 0, 155 }; + s16 step; + s32 pad[2]; + EnMag* this = THIS; + + if (gSaveContext.fileNum != 0xFEDC) { + if (this->state == MAG_STATE_INITIAL) { + if (CHECK_BTN_ALL(CONTROLLER1(globalCtx)->press.button, BTN_START) || + CHECK_BTN_ALL(CONTROLLER1(globalCtx)->press.button, BTN_A) || + CHECK_BTN_ALL(CONTROLLER1(globalCtx)->press.button, BTN_B)) { + + if (!EnvFlags_Get(globalCtx, 4)) { + play_sound(NA_SE_SY_PIECE_OF_HEART); + this->state = MAG_STATE_CALLED; + this->unk11F00 = 0; + this->unk11F02 = 30; + sInputDelayTimer = 20; + gSaveContext.fadeDuration = 1; + gSaveContext.unk_3F51 = 255; + } + } + } else { + switch (this->state) { + case MAG_STATE_FADE_IN_MASK_EFFECTS: + TIMED_STEP_TO(this->appearEffectPrimColor[1], sAppearEffectPrimGreenTargets[0], + this->majorasMaskEffectsFadeInTimer, step); + TIMED_STEP_TO(this->appearEffectEnvColor[0], sAppearEffectEnvRedTargets[0], + this->majorasMaskEffectsFadeInTimer, step); + TIMED_STEP_TO(this->appearEffectEnvColor[2], sAppearEffectEnvBlueTargets[0], + this->majorasMaskEffectsFadeInTimer, step); + TIMED_STEP_UP_TO(this->appearEffectAlpha, 255, this->majorasMaskEffectsFadeInTimer, step); + TIMED_STEP_UP_TO(this->appearEffectPrimLodFrac, 32, this->majorasMaskEffectsFadeInTimer, step); + + this->majorasMaskEffectsFadeInTimer--; + if (this->majorasMaskEffectsFadeInTimer == 0) { + this->appearEffectPrimColor[1] = sAppearEffectPrimGreenTargets[0]; + this->appearEffectEnvColor[0] = sAppearEffectEnvRedTargets[0]; + this->appearEffectEnvColor[2] = sAppearEffectEnvBlueTargets[0]; + this->appearEffectAlpha = 255; + this->state = MAG_STATE_FADE_IN_MASK; + this->delayTimer = 5; + } + break; + + case MAG_STATE_FADE_IN_MASK: + if (this->delayTimer == 0) { + TIMED_STEP_TO(this->appearEffectPrimColor[1], sAppearEffectPrimGreenTargets[1], + this->majorasMaskFadeInTimer, step); + TIMED_STEP_TO(this->appearEffectEnvColor[0], sAppearEffectEnvRedTargets[1], + this->majorasMaskFadeInTimer, step); + TIMED_STEP_TO(this->appearEffectEnvColor[2], sAppearEffectEnvBlueTargets[1], + this->majorasMaskFadeInTimer, step); + TIMED_STEP_UP_TO(this->appearEffectPrimLodFrac, 128, this->majorasMaskFadeInTimer, step); + TIMED_STEP_UP_TO(this->majorasMaskAlpha, 255, this->majorasMaskFadeInTimer, step); + + this->majorasMaskFadeInTimer--; + if (this->majorasMaskFadeInTimer == 0) { + this->appearEffectPrimColor[1] = sAppearEffectPrimGreenTargets[1]; + this->appearEffectEnvColor[0] = sAppearEffectEnvRedTargets[1]; + this->appearEffectEnvColor[2] = sAppearEffectEnvBlueTargets[1]; + this->appearEffectPrimLodFrac = 128; + this->majorasMaskAlpha = 255; + this->state = MAG_STATE_FADE_IN_MAIN_TITLE; + this->delayTimer = 5; + } + } else { + this->delayTimer--; + } + break; + + case MAG_STATE_FADE_IN_MAIN_TITLE: + if (this->delayTimer == 0) { + TIMED_STEP_UP_TO(this->mainTitleAlpha, 255, this->mainTitleAlphaFadeInTimer, step); + + this->mainTitleAlphaFadeInTimer--; + if (this->mainTitleAlphaFadeInTimer == 0) { + this->mainTitleAlphaFadeInTimer = 1; + this->mainTitleAlpha = 255; + } + + TIMED_STEP_DOWN_TO(this->appearEffectAlpha, 60, this->effectAlphaFadeInTimer, step); + TIMED_STEP_UP_TO(this->displayEffectAlpha, 255, this->effectAlphaFadeInTimer, step); + TIMED_STEP_UP_TO(this->displayEffectPrimLodFrac, 128, this->effectAlphaFadeInTimer, step); + + this->effectAlphaFadeInTimer--; + + if (this->effectAlphaFadeInTimer == 0) { + this->appearEffectAlpha = 60; + this->displayEffectAlpha = 255; + this->displayEffectPrimLodFrac = 128; + this->state = MAG_STATE_FADE_IN_SUBTITLE; + this->delayTimer = 20; + } + } else { + this->delayTimer--; + } + break; + + case MAG_STATE_FADE_IN_SUBTITLE: + EnMag_UpdateDisplayEffectColors(&this->actor); + + if (this->delayTimer == 0) { + TIMED_STEP_UP_TO(this->subtitleAlpha, 255, this->subtitleFadeInTimer, step); + + this->subtitleFadeInTimer--; + if (this->subtitleFadeInTimer == 0) { + this->displayEffectAlpha = 255; + this->state = MAG_STATE_FADE_IN_COPYRIGHT; + this->delayTimer = 20; + } + } else { + this->delayTimer--; + } + break; + + case MAG_STATE_FADE_IN_COPYRIGHT: + EnMag_UpdateDisplayEffectColors(&this->actor); + + if (this->delayTimer == 0) { + TIMED_STEP_UP_TO(this->copyrightAlpha, 255, this->copyrightFadeInTimer, step); + + this->copyrightFadeInTimer--; + if (this->copyrightFadeInTimer == 0) { + this->copyrightAlpha = 255; + this->state = MAG_STATE_DISPLAY; + } + } else { + this->delayTimer--; + } + break; + + case MAG_STATE_CALLED: + this->appearEffectPrimColor[1] = sAppearEffectPrimGreenTargets[0]; + this->appearEffectEnvColor[0] = sAppearEffectEnvRedTargets[0]; + this->appearEffectEnvColor[2] = sAppearEffectEnvBlueTargets[0]; + this->appearEffectAlpha = 60; + this->appearEffectPrimLodFrac = 128; + this->majorasMaskAlpha = 255; + this->mainTitleAlpha = 255; + this->displayEffectAlpha = 255; + this->displayEffectPrimLodFrac = 128; + this->subtitleAlpha = 255; + this->copyrightAlpha = 255; + this->state = MAG_STATE_DISPLAY; + break; + + case MAG_STATE_DISPLAY: + EnMag_UpdateDisplayEffectColors(&this->actor); + + if (sInputDelayTimer == 0) { + if (CHECK_BTN_ALL(CONTROLLER1(globalCtx)->press.button, BTN_START) || + CHECK_BTN_ALL(CONTROLLER1(globalCtx)->press.button, BTN_A) || + CHECK_BTN_ALL(CONTROLLER1(globalCtx)->press.button, BTN_B)) { + if (globalCtx->sceneLoadFlag != 0x14) { + func_801A3F54(false); + D_801BB12C++; + if (D_801BB12C >= 2) { + D_801BB12C = 0; + } + play_sound(NA_SE_SY_PIECE_OF_HEART); + gSaveContext.gameMode = 2; // Go to FileChoose + globalCtx->sceneLoadFlag = 0x14; + globalCtx->unk_1887F = 2; + globalCtx->nextEntranceIndex = 0x1C00; + gSaveContext.cutscene = 0; + gSaveContext.sceneSetupIndex = 0; + } + this->unk11F54 = 15; + this->unk11F56 = 25; + this->state = MAG_STATE_FADE_OUT; + } + } else { + sInputDelayTimer--; + } + break; + + case MAG_STATE_FADE_OUT: + TIMED_STEP_DOWN_TO(this->appearEffectAlpha, 0, this->fadeOutTimer, step); + TIMED_STEP_DOWN_TO(this->majorasMaskAlpha, 0, this->fadeOutTimer, step); + TIMED_STEP_DOWN_TO(this->displayEffectAlpha, 0, this->fadeOutTimer, step); + TIMED_STEP_DOWN_TO(this->mainTitleAlpha, 0, this->fadeOutTimer, step); + TIMED_STEP_DOWN_TO(this->subtitleAlpha, 0, this->fadeOutTimer, step); + TIMED_STEP_DOWN_TO(this->copyrightAlpha, 0, this->fadeOutTimer, step); + + this->fadeOutTimer--; + if (this->fadeOutTimer == 0) { + this->appearEffectAlpha = 0; + this->majorasMaskAlpha = 0; + this->mainTitleAlpha = 0; + this->subtitleAlpha = 0; + this->displayEffectAlpha = 0; + this->copyrightAlpha = 0; + this->state = MAG_STATE_POST_DISPLAY; + } + break; + } + + // Appear fully immediately if called during fade-in states. + if ((this->state > MAG_STATE_INITIAL) && (this->state < MAG_STATE_CALLED)) { + if (CHECK_BTN_ALL(CONTROLLER1(globalCtx)->press.button, BTN_START) || + CHECK_BTN_ALL(CONTROLLER1(globalCtx)->press.button, BTN_A) || + CHECK_BTN_ALL(CONTROLLER1(globalCtx)->press.button, BTN_B)) { + play_sound(NA_SE_SY_PIECE_OF_HEART); + this->state = MAG_STATE_CALLED; + } + } + } + } + + if (this->state == MAG_STATE_INITIAL) { + if (EnvFlags_Get(globalCtx, 3)) { + this->unk11F02 = 40; + this->state = MAG_STATE_FADE_IN_MASK_EFFECTS; + } + } else if (this->state < MAG_STATE_FADE_OUT) { + if (EnvFlags_Get(globalCtx, 4)) { + this->state = MAG_STATE_FADE_OUT; + } + } +} + +/** + * Draws an i8 texture. + * + * @param[in,out] gfxp Pointer to current displaylist. + * @param[in] texture Texture to draw. + * @param[in] texWidth Width of the texture. + * @param[in] texHeight Height of the texture. + * @param[in] rectLeft X coordinate of the top-left of the draw position. + * @param[in] rectTop Y coordinate of the top-left of the draw position. + */ +void EnMag_DrawTextureI8(Gfx** gfxp, TexturePtr texture, s16 texWidth, s16 texHeight, s16 rectLeft, s16 rectTop) { + Gfx* gfx = *gfxp; + + gDPLoadTextureBlock(gfx++, texture, G_IM_FMT_I, G_IM_SIZ_8b, texWidth, texHeight, 0, G_TX_NOMIRROR | G_TX_WRAP, + G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD); + + gSPTextureRectangle(gfx++, rectLeft << 2, rectTop << 2, (rectLeft + texWidth) << 2, (rectTop + texHeight) << 2, + G_TX_RENDERTILE, 0, 0, 1 << 10, 1 << 10); + + *gfxp = gfx; +} + +/** + * Draws an ia8 texture. + * + * @param[in,out] gfxp Pointer to current displaylist. + * @param[in] texture Texture to draw. + * @param[in] texWidth Width of the texture. + * @param[in] texHeight Height of the texture. + * @param[in] rectLeft X coordinate of the top-left of the draw position. + * @param[in] rectTop Y coordinate of the top-left of the draw position. + */ +void EnMag_DrawTextureIA8(Gfx** gfxp, TexturePtr texture, s16 texWidth, s16 texHeight, s16 rectLeft, s16 rectTop) { + Gfx* gfx = *gfxp; + + gDPLoadTextureBlock(gfx++, texture, G_IM_FMT_IA, G_IM_SIZ_8b, texWidth, texHeight, 0, G_TX_NOMIRROR | G_TX_WRAP, + G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD); + + gSPTextureRectangle(gfx++, rectLeft << 2, rectTop << 2, (rectLeft + texWidth) << 2, (rectTop + texHeight) << 2, + G_TX_RENDERTILE, 0, 0, 1 << 10, 1 << 10); + + *gfxp = gfx; +} + +/** + * Draws an i8 effect texture, masking it with an i4 mask, with shifting + * + * @param[in,out] gfxp Pointer to current displaylist. + * @param[in] maskTex Texture with which to mask, i4. + * @param[in] effectTex Effect texture to draw, i8. + * @param[in] maskWidth Width of masking texture. + * @param[in] maskHeight Height of masking texture. + * @param[in] effectWidth Width of effect texture. + * @param[in] effectHeight Height of effect texture. + * @param[in] rectLeft X coordinate of the top-left of the draw position. + * @param[in] rectTop Y coordinate of the top-left of the draw position. + * @param[in] shifts Shift to apply to effect texture's S coordinate to control LOD. + * @param[in] shiftt Shift to apply to effect texture's T coordinate to control LOD. + * @param[in] index Index into the scrolling arrays to use for gDPSetTileSize. + * @param[in] this Pointer to EnMag instance. + */ +void EnMag_DrawEffectTextures(Gfx** gfxp, TexturePtr maskTex, TexturePtr effectTex, s16 maskWidth, s16 maskHeight, + s16 effectWidth, s16 effectHeight, s16 rectLeft, s16 rectTop, u16 shifts, u16 shiftt, + u16 index, EnMag* this) { + Gfx* gfx = *gfxp; + + gDPLoadMultiBlock_4b(gfx++, maskTex, 0x0000, G_TX_RENDERTILE, G_IM_FMT_I, maskWidth, maskHeight, 0, + G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, + G_TX_NOLOD); + + gDPLoadMultiBlock(gfx++, effectTex, 0x0100, 1, G_IM_FMT_I, G_IM_SIZ_8b, effectWidth, effectHeight, 0, + G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, 5, 5, shifts, shiftt); + + gDPSetTileSize(gfx++, 1, this->effectScrollSs[index] & 0x7F, this->effectScrollTs[index] & 0x7F, + (this->effectScrollSs[index] & 0x7F) + 15, (this->effectScrollTs[index] & 0x7F) + 15); + + gSPTextureRectangle(gfx++, rectLeft << 2, rectTop << 2, (rectLeft + maskWidth) << 2, (rectTop + maskHeight) << 2, + G_TX_RENDERTILE, 0, 0, 1 << 10, 1 << 10); + + *gfxp = gfx; +} + +/** + * Draws an rgba32 texture. Because these are so large, this will draw the texture in horizontal stripes, each narrow + * enough that that part of the texture will fit into TMEM's 4kB. + * + * @param[in,out] gfxp Pointer to current displaylist. + * @param[in] centerX X coordinate of the center of the draw position. + * @param[in] centerY Y coordinate of the center of the draw position. + * @param[in] source Texture to draw. + * @param[in] width Width of the texture. + * @param[in] height Height of the texture. + */ +void EnMag_DrawImageRGBA32(Gfx** gfxp, s16 centerX, s16 centerY, TexturePtr source, u32 width, u32 height) { + Gfx* gfx = *gfxp; + uintptr_t curTexture; + s32 textureCount; + u32 rectLeft; + u32 rectTop; + u32 textureHeight; + s32 remainingSize; + s32 textureSize; + s32 pad; + s32 i; + + func_8012CA0C(&gfx); + + curTexture = source; + rectLeft = centerX - (width / 2); + rectTop = centerY - (height / 2); + textureHeight = TMEM_SIZE / (width << 2); + remainingSize = (width * height) << 2; + textureSize = (width * textureHeight) << 2; + textureCount = remainingSize / textureSize; + if ((remainingSize % textureSize) != 0) { + textureCount++; + } + + gDPSetTileCustom(gfx++, G_IM_FMT_RGBA, G_IM_SIZ_32b, width, textureHeight, 0, G_TX_NOMIRROR | G_TX_CLAMP, + G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD); + + remainingSize -= textureSize; + + for (i = 0; i < textureCount; i++) { + gDPSetTextureImage(gfx++, G_IM_FMT_RGBA, G_IM_SIZ_32b, width, curTexture); + + gDPLoadSync(gfx++); + gDPLoadTile(gfx++, G_TX_LOADTILE, 0, 0, (width - 1) << 2, (textureHeight - 1) << 2); + + gSPTextureRectangle(gfx++, rectLeft << 2, rectTop << 2, (rectLeft + (s32)width) << 2, + (rectTop + textureHeight) << 2, G_TX_RENDERTILE, 0, 0, 1 << 10, 1 << 10); + + curTexture += textureSize; + rectTop += textureHeight; + + if ((remainingSize - textureSize) < 0) { + if (remainingSize > 0) { + textureHeight = remainingSize / (s32)(width << 2); + remainingSize -= textureSize; + + gDPSetTileCustom(gfx++, G_IM_FMT_RGBA, G_IM_SIZ_32b, width, textureHeight, 0, + G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, + G_TX_NOLOD, G_TX_NOLOD); + } + } else { + remainingSize -= textureSize; + } + } + + *gfxp = gfx; +} + +/** + * Draws one character, expected to be a 16 by 16 i4 texture. It will draw shrunk to 10 by 10. + * + * @param[in,out] gfxp Pointer to current displaylist. + * @param[in] texture Texture to draw. + * @param[in] rectLeft X coordinate of the top-left of the draw position. + * @param[in] rectTop Y coordinate of the top-left of the draw position. + */ +void EnMag_DrawCharTexture(Gfx** gfxp, TexturePtr texture, s32 rectLeft, s32 rectTop) { + Gfx* gfx = *gfxp; + + gDPLoadTextureBlock_4b(gfx++, texture, G_IM_FMT_I, 16, 16, 0, G_TX_NOMIRROR | G_TX_CLAMP, + G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD); + + // The dsdx and dtdy are roughly 1.587 * 0x400, to fit the texture into 10 by 10 pixels. It is not the more + // obvious 1.6 * 0x400 = 1656. + gSPTextureRectangle(gfx++, rectLeft << 2, rectTop << 2, (rectLeft + 10) << 2, (rectTop + 10) << 2, G_TX_RENDERTILE, + 0, 0, 1625, 1625); + + *gfxp = gfx; +} + +#define EFFECT_MASK_TEX_WIDTH 64 +#define EFFECT_MASK_TEX_HEIGHT 64 +#define EFFECT_TEX_WIDTH 32 +#define EFFECT_TEX_HEIGHT 32 +#define EFFECT_TEX_LEFT 38 +#define EFFECT_TEX_TOP 57 + +#define MAJORAS_MASK_TEX_WIDTH 128 +#define MAJORAS_MASK_TEX_HEIGHT 112 +#define MAJORAS_MASK_TEX_CENTER_X 124 +#define MAJORAS_MASK_TEX_CENTER_Y 103 + +#define ZELDA_TEX_WIDTH 144 +#define ZELDA_TEX_HEIGHT 64 +#define ZELDA_TEX_CENTER_X 177 +#define ZELDA_TEX_CENTER_Y 105 + +#define SUBTITLE_TEX_WIDTH 104 +#define SUBTITLE_TEX_HEIGHT 16 +#define SUBTITLE_TEX_LEFT 151 +#define SUBTITLE_TEX_TOP 124 + +#define THE_LEGEND_OF_TEX_WIDTH 72 +#define THE_LEGEND_OF_TEX_HEIGHT 8 +#define THE_LEGEND_OF_TEX_LEFT 158 +#define THE_LEGEND_OF_TEX_TOP 71 + +#define COPYRIGHT_TEX_WIDTH 128 +#define COPYRIGHT_TEX_HEIGHT 16 +#define COPYRIGHT_TEX_LEFT 94 +#define COPYRIGHT_TEX_TOP 198 + +#define NO_CONTROLLER_FIRST_TEX_WIDTH 256 +#define NO_CONTROLLER_FIRST_TEX_HEIGHT 9 +#define NO_CONTROLLER_FIRST_TEX_LEFT 35 +#define NO_CONTROLLER_FIRST_TEX_TOP 175 + +#define NO_CONTROLLER_SECOND_TEX_WIDTH 144 +#define NO_CONTROLLER_SECOND_TEX_HEIGHT 9 +#define NO_CONTROLLER_SECOND_TEX_LEFT 91 +#define NO_CONTROLLER_SECOND_TEX_TOP 188 + +// Top-left of the text itself, not the shadow +#define PRESS_START_LEFT 119 +#define PRESS_START_TOP 174 +#define PRESS_START_CHAR_SPACING 7 // Amount of rightward shift before printing next char +#define PRESS_START_SPACE 5 // Extra space between the words + +/** + * Loads title, PRESS START text, etc. graphics to gfxp, which is made to live on + * POLY_OPA_DISP, but is used by OVERLAY_DISP. + */ +void EnMag_DrawInner(Actor* thisx, GlobalContext* globalCtx, Gfx** gfxp) { + static u8 pressStartFontIndices[] = { + 0x19, 0x1B, 0x0E, 0x1C, 0x1C, 0x1C, 0x1D, 0x0A, 0x1B, 0x1D, + }; // Indices into this->font.fontBuf + static TexturePtr sAppearEffectMaskTextures[] = { + gTitleScreenAppearEffectMask00Tex, gTitleScreenAppearEffectMask01Tex, gTitleScreenAppearEffectMask02Tex, + gTitleScreenAppearEffectMask10Tex, gTitleScreenAppearEffectMask11Tex, gTitleScreenAppearEffectMask12Tex, + }; // Visible when mask appearing + static TexturePtr sDisplayEffectMaskTextures[] = { + gTitleScreenDisplayEffectMask00Tex, gTitleScreenDisplayEffectMask01Tex, gTitleScreenDisplayEffectMask02Tex, + gTitleScreenDisplayEffectMask10Tex, gTitleScreenDisplayEffectMask11Tex, gTitleScreenDisplayEffectMask12Tex, + }; // Visible when full game logo displayed + static TexturePtr sEffectTextures[] = { + gTitleScreenFlame0Tex, gTitleScreenFlame1Tex, gTitleScreenFlame1Tex, + gTitleScreenFlame2Tex, gTitleScreenFlame3Tex, gTitleScreenFlame3Tex, + }; + static s16 sEffectScrollVelocitySs[] = { -1, 1, 1, -1, 1, 1 }; + static s16 sEffectScrollVelocityTs[] = { -2, -2, -2, 2, 2, 2 }; + static s16 sTextAlpha = 0; // For drawing both the No Controller message and "PRESS START" + static s16 sTextAlphaTargets[] = { 255, 0 }; + s32 pad; + EnMag* this = THIS; + Font* font = &this->font; + Gfx* gfx = *gfxp; + u16 i; + u16 j; + u16 k; + s32 rectLeft; + s32 rectTop; + s16 step; + + // Set segment 6 to the object, since this will be read by OVERLAY_DISP where it is not set by default. + gSPSegment(gfx++, 0x06, globalCtx->objectCtx.status[this->actor.objBankIndex].segment); + + func_8012C680(&gfx); + + // Mask appearing effects + gDPPipeSync(gfx++); + gDPSetCycleType(gfx++, G_CYC_2CYCLE); + gDPSetAlphaCompare(gfx++, G_AC_THRESHOLD); + gDPSetRenderMode(gfx++, G_RM_PASS, G_RM_CLD_SURF2); + gDPSetCombineLERP(gfx++, TEXEL1, PRIMITIVE, PRIM_LOD_FRAC, TEXEL0, TEXEL1, 1, PRIM_LOD_FRAC, TEXEL0, PRIMITIVE, + ENVIRONMENT, COMBINED, ENVIRONMENT, COMBINED, 0, PRIMITIVE, 0); + + gDPSetPrimColor(gfx++, 0, this->appearEffectPrimLodFrac, this->appearEffectPrimColor[0], + this->appearEffectPrimColor[1], this->appearEffectPrimColor[2], this->appearEffectAlpha); + gDPSetEnvColor(gfx++, this->appearEffectEnvColor[0], this->appearEffectEnvColor[1], this->appearEffectEnvColor[2], + 255); + + if (this->appearEffectPrimLodFrac != 0) { + for (k = 0, i = 0, rectTop = EFFECT_TEX_LEFT; i < 2; i++, rectTop += EFFECT_MASK_TEX_HEIGHT) { + for (j = 0, rectLeft = EFFECT_TEX_TOP; j < 3; j++, k++, rectLeft += EFFECT_MASK_TEX_WIDTH) { + this->effectScrollSs[k] += sEffectScrollVelocitySs[k]; + this->effectScrollTs[k] += sEffectScrollVelocityTs[k]; + EnMag_DrawEffectTextures(&gfx, sAppearEffectMaskTextures[k], sEffectTextures[k], EFFECT_MASK_TEX_WIDTH, + EFFECT_MASK_TEX_HEIGHT, EFFECT_TEX_WIDTH, EFFECT_TEX_HEIGHT, rectLeft, rectTop, + 1, 1, k, this); + } + } + } + + func_8012C680(&gfx); + + if (this->majorasMaskAlpha != 0) { + gDPSetCombineLERP(gfx++, PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT, TEXEL0, 0, PRIMITIVE, 0, PRIMITIVE, + ENVIRONMENT, TEXEL0, ENVIRONMENT, TEXEL0, 0, PRIMITIVE, 0); + + gDPSetPrimColor(gfx++, 0, 0, 255, 255, 255, this->majorasMaskAlpha); + gDPSetEnvColor(gfx++, this->majorasMaskEnvColor[0], this->majorasMaskEnvColor[1], this->majorasMaskEnvColor[2], + 255); + + EnMag_DrawImageRGBA32(&gfx, MAJORAS_MASK_TEX_CENTER_X, MAJORAS_MASK_TEX_CENTER_Y, gTitleScreenMajorasMaskTex, + MAJORAS_MASK_TEX_WIDTH, MAJORAS_MASK_TEX_HEIGHT); + } + + // Flame glow effects on full game logo when displayed + gDPPipeSync(gfx++); + gDPSetCycleType(gfx++, G_CYC_2CYCLE); + gDPSetAlphaCompare(gfx++, G_AC_THRESHOLD); + gDPSetRenderMode(gfx++, G_RM_PASS, G_RM_CLD_SURF2); + gDPSetCombineLERP(gfx++, TEXEL1, PRIMITIVE, PRIM_LOD_FRAC, TEXEL0, TEXEL1, 1, PRIM_LOD_FRAC, TEXEL0, PRIMITIVE, + ENVIRONMENT, COMBINED, ENVIRONMENT, COMBINED, 0, PRIMITIVE, 0); + + gDPSetPrimColor(gfx++, 0, this->displayEffectPrimLodFrac, this->displayEffectPrimColor[0], + this->displayEffectPrimColor[1], this->displayEffectPrimColor[2], this->displayEffectAlpha); + gDPSetEnvColor(gfx++, this->displayEffectEnvColor[0], this->displayEffectEnvColor[1], + this->displayEffectEnvColor[2], 255); + + if (this->displayEffectPrimLodFrac != 0) { + for (k = 0, i = 0, rectTop = EFFECT_TEX_LEFT; i < 2; i++, rectTop += EFFECT_MASK_TEX_HEIGHT) { + for (j = 0, rectLeft = EFFECT_TEX_TOP; j < 3; j++, k++, rectLeft += EFFECT_MASK_TEX_WIDTH) { + EnMag_DrawEffectTextures(&gfx, sDisplayEffectMaskTextures[k], sEffectTextures[k], EFFECT_MASK_TEX_WIDTH, + EFFECT_MASK_TEX_HEIGHT, EFFECT_TEX_WIDTH, EFFECT_TEX_HEIGHT, rectLeft, rectTop, + 1, 1, k, this); + } + } + } + + if (this->subtitleAlpha != 0) { + func_8012C680(&gfx); + + gDPSetAlphaCompare(gfx++, G_AC_NONE); + gDPSetCombineMode(gfx++, G_CC_MODULATEIA_PRIM, G_CC_MODULATEIA_PRIM); + + if (this->mainTitleAlpha < 100) { + gDPSetRenderMode(gfx++, G_RM_CLD_SURF, G_RM_CLD_SURF2); + } else { + gDPSetRenderMode(gfx++, G_RM_XLU_SURF, G_RM_XLU_SURF2); + } + + gDPSetPrimColor(gfx++, 0, 0, 0, 0, 0, this->subtitleAlpha); + gDPSetEnvColor(gfx++, 100, 0, 100, 255); + + EnMag_DrawTextureI8(&gfx, gTitleScreenMajorasMaskSubtitleMaskTex, SUBTITLE_TEX_WIDTH, SUBTITLE_TEX_HEIGHT, + SUBTITLE_TEX_LEFT, SUBTITLE_TEX_TOP); + } + + func_8012C680(&gfx); + + gDPSetAlphaCompare(gfx++, G_AC_NONE); + gDPSetCombineMode(gfx++, G_CC_MODULATEIA_PRIM, G_CC_MODULATEIA_PRIM); + + if (this->mainTitleAlpha < 100) { + gDPSetRenderMode(gfx++, G_RM_CLD_SURF, G_RM_CLD_SURF2); + } else { + gDPSetRenderMode(gfx++, G_RM_XLU_SURF, G_RM_XLU_SURF2); + } + + gDPSetPrimColor(gfx++, 0, 120, 208, 102, 222, this->subtitleAlpha); + + EnMag_DrawTextureI8(&gfx, gTitleScreenMajorasMaskSubtitleTex, SUBTITLE_TEX_WIDTH, SUBTITLE_TEX_HEIGHT, + SUBTITLE_TEX_LEFT, SUBTITLE_TEX_TOP); + + func_8012C680(&gfx); + + gDPSetAlphaCompare(gfx++, G_AC_NONE); + gDPSetCombineMode(gfx++, G_CC_MODULATEIA_PRIM, G_CC_MODULATEIA_PRIM); + + if (this->mainTitleAlpha != 0) { + gDPSetPrimColor(gfx++, 0, 0, 255, 255, 255, this->mainTitleAlpha); + + EnMag_DrawImageRGBA32(&gfx, ZELDA_TEX_CENTER_X, ZELDA_TEX_CENTER_Y, gTitleScreenZeldaLogoTex, ZELDA_TEX_WIDTH, + ZELDA_TEX_HEIGHT); + + gDPPipeSync(gfx++); + + if (this->mainTitleAlpha < 100) { + gDPSetRenderMode(gfx++, G_RM_CLD_SURF, G_RM_CLD_SURF2); + } else { + gDPSetRenderMode(gfx++, G_RM_XLU_SURF, G_RM_XLU_SURF2); + } + + gDPSetPrimColor(gfx++, 0, 0, 208, 102, 222, this->mainTitleAlpha); + + EnMag_DrawTextureI8(&gfx, gTitleScreenTheLegendOfTextTex, THE_LEGEND_OF_TEX_WIDTH, THE_LEGEND_OF_TEX_HEIGHT, + THE_LEGEND_OF_TEX_LEFT, THE_LEGEND_OF_TEX_TOP); + } + + func_8012C680(&gfx); + + if (this->copyrightAlpha != 0) { + gDPSetAlphaCompare(gfx++, G_AC_NONE); + gDPSetCombineMode(gfx++, G_CC_MODULATEIA_PRIM, G_CC_MODULATEIA_PRIM); + gDPSetPrimColor(gfx++, 0, 0, this->copyrightAlpha, this->copyrightAlpha, this->copyrightAlpha, + this->copyrightAlpha); + + EnMag_DrawTextureIA8(&gfx, gTitleScreenCopyright2000NintendoTex, COPYRIGHT_TEX_WIDTH, COPYRIGHT_TEX_HEIGHT, + COPYRIGHT_TEX_LEFT, COPYRIGHT_TEX_TOP); + } + + if (gSaveContext.fileNum == 0xFEDC) { + // Draw No controller message + + TIMED_STEP_TO(sTextAlpha, sTextAlphaTargets[sTextAlphaTargetIndex], sTextAlphaTimer, step); + + gDPPipeSync(gfx++); + gDPSetAlphaCompare(gfx++, G_AC_THRESHOLD); + + gDPSetCombineLERP(gfx++, 0, 0, 0, PRIMITIVE, TEXEL0, 0, PRIMITIVE, 0, 0, 0, 0, PRIMITIVE, TEXEL0, 0, PRIMITIVE, + 0); + gDPSetPrimColor(gfx++, 0, 0, 0, 0, 0, sTextAlpha); + gDPLoadTextureBlock_4b(gfx++, gTitleScreenControllerNotConnectedTextTex, G_IM_FMT_I, + NO_CONTROLLER_FIRST_TEX_WIDTH, NO_CONTROLLER_FIRST_TEX_HEIGHT, 0, + G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, + G_TX_NOLOD, G_TX_NOLOD); + // Texture shadow + gSPTextureRectangle(gfx++, (NO_CONTROLLER_FIRST_TEX_LEFT + 1) << 2, (NO_CONTROLLER_FIRST_TEX_TOP + 1) << 2, + (NO_CONTROLLER_FIRST_TEX_LEFT + 1 + NO_CONTROLLER_FIRST_TEX_WIDTH) << 2, + (NO_CONTROLLER_FIRST_TEX_TOP + 1 + NO_CONTROLLER_FIRST_TEX_HEIGHT) << 2, G_TX_RENDERTILE, 0, + 0, 1 << 10, 1 << 10); + // Actual texture + gDPSetPrimColor(gfx++, 0, 0, 205, 255, 255, sTextAlpha); + gSPTextureRectangle(gfx++, NO_CONTROLLER_FIRST_TEX_LEFT << 2, NO_CONTROLLER_FIRST_TEX_TOP << 2, + (NO_CONTROLLER_FIRST_TEX_LEFT + NO_CONTROLLER_FIRST_TEX_WIDTH) << 2, + (NO_CONTROLLER_FIRST_TEX_TOP + NO_CONTROLLER_FIRST_TEX_HEIGHT) << 2, G_TX_RENDERTILE, 0, 0, + 1 << 10, 1 << 10); + + gDPSetPrimColor(gfx++, 0, 0, 0, 0, 0, sTextAlpha); + gDPLoadTextureBlock_4b(gfx++, gTitleScreenInsertControllerTextTex, G_IM_FMT_I, NO_CONTROLLER_SECOND_TEX_WIDTH, + NO_CONTROLLER_SECOND_TEX_HEIGHT, 0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, + G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD); + // Texture shadow + gSPTextureRectangle(gfx++, (NO_CONTROLLER_SECOND_TEX_LEFT + 1) << 2, (NO_CONTROLLER_SECOND_TEX_TOP + 1) << 2, + (NO_CONTROLLER_SECOND_TEX_LEFT + 1 + NO_CONTROLLER_SECOND_TEX_WIDTH) << 2, + (NO_CONTROLLER_SECOND_TEX_TOP + 1 + NO_CONTROLLER_SECOND_TEX_HEIGHT) << 2, G_TX_RENDERTILE, + 0, 0, 1 << 10, 1 << 10); + // Actual texture + gDPSetPrimColor(gfx++, 0, 0, 205, 255, 255, sTextAlpha); + gSPTextureRectangle(gfx++, NO_CONTROLLER_SECOND_TEX_LEFT << 2, NO_CONTROLLER_SECOND_TEX_TOP << 2, + (NO_CONTROLLER_SECOND_TEX_LEFT + NO_CONTROLLER_SECOND_TEX_WIDTH) << 2, + (NO_CONTROLLER_SECOND_TEX_TOP + NO_CONTROLLER_SECOND_TEX_HEIGHT) << 2, G_TX_RENDERTILE, 0, + 0, 1 << 10, 1 << 10); + + sTextAlphaTimer--; + if (sTextAlphaTimer == 0) { + sTextAlpha = sTextAlphaTargets[sTextAlphaTargetIndex]; + if (gSaveContext.fileNum == 0xFEDC) { + sTextAlphaTimer = 40; + } else { + sTextAlphaTimer = 20; + } + sTextAlphaTargetIndex ^= 1; + } + } else if (this->copyrightAlpha != 0) { + // Draw "PRESS START" characters + + TIMED_STEP_TO(sTextAlpha, sTextAlphaTargets[sTextAlphaTargetIndex], sTextAlphaTimer, step); + + // Text shadow + gDPPipeSync(gfx++); + gDPSetCombineLERP(gfx++, 0, 0, 0, PRIMITIVE, TEXEL0, 0, PRIMITIVE, 0, 0, 0, 0, PRIMITIVE, TEXEL0, 0, PRIMITIVE, + 0); + gDPSetPrimColor(gfx++, 0, 0, 0, 0, 0, sTextAlpha); + + rectLeft = PRESS_START_LEFT + 1; + for (i = 0; i < ARRAY_COUNT(pressStartFontIndices); i++) { + EnMag_DrawCharTexture(&gfx, font->fontBuf + pressStartFontIndices[i] * FONT_CHAR_TEX_SIZE, rectLeft, + PRESS_START_TOP + 1); + + rectLeft += PRESS_START_CHAR_SPACING; + if (i == 4) { + rectLeft += PRESS_START_SPACE; + } + } + + // Actual text + gDPPipeSync(gfx++); + gDPSetPrimColor(gfx++, 0, 0, 255, 30, 30, sTextAlpha); + + rectLeft = PRESS_START_LEFT; + for (i = 0; i < ARRAY_COUNT(pressStartFontIndices); i++) { + EnMag_DrawCharTexture(&gfx, font->fontBuf + pressStartFontIndices[i] * FONT_CHAR_TEX_SIZE, rectLeft, + PRESS_START_TOP); + rectLeft += PRESS_START_CHAR_SPACING; + if (i == 4) { + rectLeft += PRESS_START_SPACE; + } + } + + sTextAlphaTimer--; + if (sTextAlphaTimer == 0) { + sTextAlpha = sTextAlphaTargets[sTextAlphaTargetIndex]; + if (gSaveContext.fileNum == 0xFEDC) { + sTextAlphaTimer = 40; + } else { + sTextAlphaTimer = 20; + } + sTextAlphaTargetIndex ^= 1; + } + } + + *gfxp = gfx; +} + +/** + * Jumps drawing to POLY_OPA_DISP to take advantage of the extra space available, but jmups back and actually draws + * using OVERLAY_DISP. + */ +void EnMag_Draw(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + Gfx* gfx; + Gfx* gfxRef; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + gfxRef = POLY_OPA_DISP; + gfx = Graph_GfxPlusOne(gfxRef); + gSPDisplayList(OVERLAY_DISP++, gfx); + + EnMag_DrawInner(thisx, globalCtx, &gfx); + + gSPEndDisplayList(gfx++); + Graph_BranchDlist(gfxRef, gfx); + POLY_OPA_DISP = gfx; + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_En_Mag/z_en_mag.h b/src/overlays/actors/ovl_En_Mag/z_en_mag.h index 3543b5cea..c116ae98d 100644 --- a/src/overlays/actors/ovl_En_Mag/z_en_mag.h +++ b/src/overlays/actors/ovl_En_Mag/z_en_mag.h @@ -7,7 +7,45 @@ struct EnMag; typedef struct EnMag { /* 0x00000 */ Actor actor; - /* 0x00144 */ char unk_00144[0x11E34]; + /* 0x00144 */ UNK_TYPE1 unk144[0x2C]; + /* 0x00170 */ Font font; + /* 0x11EFC */ UNK_TYPE1 unk11EFC[4]; + /* 0x11F00 */ s16 unk11F00; // Set and not used. + /* 0x11F02 */ s16 unk11F02; // Set and not used. + /* 0x11F04 */ s16 state; // State of whole actor, uses EnMagState enum + /* 0x11F06 */ s16 appearEffectPrimLodFrac; + /* 0x11F08 */ s16 appearEffectPrimColor[3]; + /* 0x11F08 */ s16 appearEffectEnvColor[3]; + /* 0x11F14 */ s16 appearEffectAlpha; + /* 0x11F16 */ s16 displayEffectPrimLodFrac; + /* 0x11F18 */ s16 displayEffectPrimColor[3]; + /* 0x11F18 */ s16 displayEffectEnvColor[3]; + /* 0x11F24 */ s16 displayEffectAlpha; + /* 0x11F26 */ s16 majorasMaskAlpha; + /* 0x11F28 */ s16 majorasMaskEnvColor[3]; + /* 0x11F2E */ s16 mainTitleAlpha; + /* 0x11F30 */ s16 subtitleAlpha; + /* 0x11F32 */ s16 unk11F32; // Set but not used, likely a spare alpha. + /* 0x11F34 */ s16 copyrightAlpha; + /* 0x11F36 */ s16 effectScrollSs[6]; + /* 0x11F42 */ UNK_TYPE1 unk11F42[2]; + /* 0x11F44 */ s16 effectScrollTs[6]; + /* 0x11F50 */ UNK_TYPE1 unk11F50[4]; + /* 0x11F54 */ s16 unk11F54; // Set but not used. + /* 0x11F56 */ s16 unk11F56; // Set but not used. + /* 0x11F58 */ s16 unk11F58; // Set but not used. + /* 0x11F5A */ s16 unk11F5A; // Set but not used. + /* 0x11F5C */ s32 unk11F5C; // Set but not used. + /* 0x11F60 */ s32 unk11F60; // Set but not used. + /* 0x11F64 */ s16 majorasMaskEffectsFadeInTimer; + /* 0x11F66 */ s16 majorasMaskFadeInTimer; + /* 0x11F68 */ s16 mainTitleAlphaFadeInTimer; + /* 0x11F6A */ s16 effectAlphaFadeInTimer; + /* 0x11F6C */ s16 subtitleFadeInTimer; + /* 0x11F6E */ s16 copyrightFadeInTimer; + /* 0x11F70 */ s16 fadeOutTimer; + /* 0x11F72 */ s16 delayTimer; // Delays start of next action in Update. + /* 0x11F74 */ UNK_TYPE1 unk11F74[4]; } EnMag; // size = 0x11F78 extern const ActorInit En_Mag_InitVars; diff --git a/src/overlays/gamestates/ovl_title/z_title.c b/src/overlays/gamestates/ovl_title/z_title.c index 9b36a7e14..827c27387 100644 --- a/src/overlays/gamestates/ovl_title/z_title.c +++ b/src/overlays/gamestates/ovl_title/z_title.c @@ -105,7 +105,8 @@ void Title_Draw(GameState* thisx) { G_TX_NOLOD, G_TX_NOLOD); gDPSetTileSize(POLY_OPA_DISP++, 1, this->uls, (this->ult & 0x7F) - idx * 4, 0, 0); - gSPTextureRectangle(POLY_OPA_DISP++, 388, y << 2, 1156, (y + 2) << 2, G_TX_RENDERTILE, 0, 0, 1 << 10, 1 << 10); + gSPTextureRectangle(POLY_OPA_DISP++, 97 << 2, y << 2, (97 + 192) << 2, (y + 2) << 2, G_TX_RENDERTILE, 0, 0, + 1 << 10, 1 << 10); } func_800FC444(this->gameState.gfxCtx, 0, 0, 0, this->coverAlpha, 2); diff --git a/tools/disasm/functions.txt b/tools/disasm/functions.txt index 25784be00..a251e7798 100644 --- a/tools/disasm/functions.txt +++ b/tools/disasm/functions.txt @@ -7992,14 +7992,14 @@ 0x8096B260:("EnOkarinaEffect_Update",), 0x8096B310:("EnMag_Init",), 0x8096B5F4:("EnMag_Destroy",), - 0x8096B604:("func_8096B604",), + 0x8096B604:("EnMag_UpdateDisplayEffectColors",), 0x8096B94C:("EnMag_Update",), - 0x8096C998:("func_8096C998",), - 0x8096CBB0:("func_8096CBB0",), - 0x8096CDC8:("func_8096CDC8",), - 0x8096D230:("func_8096D230",), - 0x8096D60C:("func_8096D60C",), - 0x8096D74C:("func_8096D74C",), + 0x8096C998:("EnMag_DrawTextureI8",), + 0x8096CBB0:("EnMag_DrawTextureIA8",), + 0x8096CDC8:("EnMag_DrawEffectTextures",), + 0x8096D230:("EnMag_DrawImageRGBA32",), + 0x8096D60C:("EnMag_DrawCharTexture",), + 0x8096D74C:("EnMag_DrawInner",), 0x8096E868:("EnMag_Draw",), 0x8096EC40:("ElfMsg2_SetupAction",), 0x8096EC4C:("func_8096EC4C",), diff --git a/tools/disasm/variables.txt b/tools/disasm/variables.txt index 73afcda75..f1bbbb8d1 100644 --- a/tools/disasm/variables.txt +++ b/tools/disasm/variables.txt @@ -8997,28 +8997,28 @@ 0x8096AD3C:("jtbl_8096AD3C","UNK_PTR","",0x4), 0x8096B290:("En_Okarina_Effect_InitVars","UNK_TYPE1","",0x1), 0x8096B2B0:("D_8096B2B0","f32","",0x4), - 0x8096E910:("D_8096E910","UNK_TYPE2","",0x2), - 0x8096E914:("D_8096E914","UNK_TYPE2","",0x2), - 0x8096E918:("D_8096E918","UNK_TYPE2","",0x2), - 0x8096E91C:("D_8096E91C","UNK_TYPE2","",0x2), - 0x8096E920:("D_8096E920","UNK_TYPE2","",0x2), + 0x8096E910:("sInputDelayTimer","s16","",0x2), + 0x8096E914:("sZeldaEffectColorTimer","s16","",0x2), + 0x8096E918:("sZeldaEffectColorTargetIndex","s16","",0x2), + 0x8096E91C:("sTextAlphaTargetIndex","s16","",0x2), + 0x8096E920:("sTextAlphaTimer","s16","",0x2), 0x8096E924:("En_Mag_InitVars","UNK_TYPE1","",0x1), - 0x8096E944:("D_8096E944","UNK_TYPE1","",0x1), - 0x8096E948:("D_8096E948","UNK_TYPE1","",0x1), - 0x8096E94C:("D_8096E94C","UNK_TYPE1","",0x1), - 0x8096E950:("D_8096E950","UNK_TYPE1","",0x1), - 0x8096E954:("D_8096E954","UNK_TYPE1","",0x1), - 0x8096E958:("D_8096E958","UNK_TYPE2","",0x2), - 0x8096E95C:("D_8096E95C","UNK_TYPE2","",0x2), - 0x8096E960:("D_8096E960","UNK_TYPE2","",0x2), - 0x8096E964:("D_8096E964","UNK_TYPE1","",0x1), - 0x8096E970:("D_8096E970","UNK_TYPE4","",0x4), - 0x8096E988:("D_8096E988","UNK_TYPE4","",0x4), - 0x8096E9A0:("D_8096E9A0","UNK_TYPE4","",0x4), - 0x8096E9B8:("D_8096E9B8","UNK_TYPE2","",0x2), - 0x8096E9C4:("D_8096E9C4","UNK_TYPE2","",0x2), - 0x8096E9D0:("D_8096E9D0","UNK_TYPE2","",0x2), - 0x8096E9D4:("D_8096E9D4","UNK_TYPE1","",0x1), + 0x8096E944:("sDisplayEffectPrimRedTargets","s16","[2]",0x4), + 0x8096E948:("sDisplayEffectPrimGreenTargets","s16","[2]",0x4), + 0x8096E94C:("sDisplayEffectPrimBlueTargets","s16","[2]",0x4), + 0x8096E950:("sDisplayEffectEnvRedTargets","s16","[2]",0x4), + 0x8096E954:("sDisplayEffectEnvBlueTargets","s16","[2]",0x4), + 0x8096E958:("sAppearEffectPrimGreenTargets","s16","[2]",0x4), + 0x8096E95C:("sAppearEffectEnvRedTargets","s16","[2]",0x4), + 0x8096E960:("sAppearEffectEnvBlueTargets","s16","[2]",0x4), + 0x8096E964:("pressStartFontIndices","u8","[10]",0x1), + 0x8096E970:("sAppearEffectMaskTextures","TexturePtr","[6]",0x18), + 0x8096E988:("sDisplayEffectMaskTextures","TexturePtr","[6]",0x18), + 0x8096E9A0:("sEffectTextures","TexturePtr","[6]",0x18), + 0x8096E9B8:("sEffectScrollVelocitySs","s16","[6]",0xC), + 0x8096E9C4:("sEffectScrollVelocityTs","s16","[6]",0xC), + 0x8096E9D0:("sTextAlpha","s16","",0x2), + 0x8096E9D4:("sTextAlphaTargets","s16","[2]",0x4), 0x8096E9E0:("jtbl_8096E9E0","UNK_PTR","",0x4), 0x8096F090:("Elf_Msg2_InitVars","UNK_TYPE1","",0x1), 0x8096F0B0:("D_8096F0B0","UNK_TYPE1","",0x1), From b2a42dcf8bbb29f4527b97a3607aef592d1b2bed Mon Sep 17 00:00:00 2001 From: EllipticEllipsis <73679967+EllipticEllipsis@users.noreply.github.com> Date: Sun, 16 Jan 2022 18:07:19 +0000 Subject: [PATCH 06/13] Two small xmls for parameter-related asset files (#548) --- assets/xml/interface/week_static.xml | 7 +++++++ assets/xml/misc/story_static.xml | 8 ++++++++ 2 files changed, 15 insertions(+) create mode 100644 assets/xml/interface/week_static.xml create mode 100644 assets/xml/misc/story_static.xml diff --git a/assets/xml/interface/week_static.xml b/assets/xml/interface/week_static.xml new file mode 100644 index 000000000..6b21b80c0 --- /dev/null +++ b/assets/xml/interface/week_static.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/assets/xml/misc/story_static.xml b/assets/xml/misc/story_static.xml new file mode 100644 index 000000000..d53f3f857 --- /dev/null +++ b/assets/xml/misc/story_static.xml @@ -0,0 +1,8 @@ + + + + + + + + From 94a2e5a3d72de0c610b65a2c205bf96baa08e596 Mon Sep 17 00:00:00 2001 From: ZoeyZolotova Date: Mon, 17 Jan 2022 05:14:09 +1100 Subject: [PATCH 07/13] Update and fix a few comments for the banker. (#598) * Update and fix a few comments for the banker. * Change 'Link' to 'the player' and remove some actual message quotes. --- src/overlays/actors/ovl_En_Ginko_Man/z_en_ginko_man.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/overlays/actors/ovl_En_Ginko_Man/z_en_ginko_man.c b/src/overlays/actors/ovl_En_Ginko_Man/z_en_ginko_man.c index a58710030..e830ae1bf 100644 --- a/src/overlays/actors/ovl_En_Ginko_Man/z_en_ginko_man.c +++ b/src/overlays/actors/ovl_En_Ginko_Man/z_en_ginko_man.c @@ -512,7 +512,7 @@ void EnGinkoMan_SetupBankAward(EnGinkoMan* this) { void EnGinkoMan_BankAward(EnGinkoMan* this, GlobalContext* globalCtx) { if (Actor_HasParent(&this->actor, globalCtx)) { - // ? when would bank have a parent? + // Parent is the player when starting to receive the award this->actor.parent = NULL; EnGinkoMan_SetupBankAward2(this); } else if (this->curTextId == 0x45B) { // "Whats this, you already saved up 200?" @@ -535,7 +535,7 @@ void EnGinkoMan_SetupBankAward2(EnGinkoMan* this) { this->actionFunc = EnGinkoMan_BankAward2; } -// separate function to handle bank rewards... if the bank has a parent actor? might be unused +// separate function to handle bank rewards... called while the player is receiving the award void EnGinkoMan_BankAward2(EnGinkoMan* this, GlobalContext* globalCtx) { if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { if (!(gSaveContext.weekEventReg[10] & 8) && (this->curTextId == 0x45B)) { @@ -543,11 +543,11 @@ void EnGinkoMan_BankAward2(EnGinkoMan* this, GlobalContext* globalCtx) { // it!" gSaveContext.weekEventReg[10] |= 8; func_801518B0(globalCtx, 0x47A, &this->actor); - this->curTextId = 0x47A; // "See! Doesn't it hold more than your old one? + this->curTextId = 0x47A; // Message after receiving reward for depositing 200 rupees. } else { Actor_ChangeAnimation(&this->skelAnime, animations, GINKO_SITTING); func_801518B0(globalCtx, 0x47B, &this->actor); - this->curTextId = 0x47B; // "Is that so? Think it over, little guy! So what are you gonna do?" + this->curTextId = 0x47B; // Message after receiving reward for depositing 1000 rupees. } EnGinkoMan_SetupDialogue(this); From 332c71c9b1e6a518fdea6be6dff1df673899bae6 Mon Sep 17 00:00:00 2001 From: Maide <34639600+Kelebek1@users.noreply.github.com> Date: Sun, 16 Jan 2022 18:20:03 +0000 Subject: [PATCH 08/13] Update (#608) --- tools/m2ctx.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/m2ctx.py b/tools/m2ctx.py index c2e50d59f..0824899f1 100755 --- a/tools/m2ctx.py +++ b/tools/m2ctx.py @@ -40,7 +40,7 @@ def custom_replacements(output): for x in range(12): actorList.append(actorListText.replace("first;", f"{actorCats[x]};") + "\n") if x == 2: - actorList[x] = actorList[x].replace("Actor*", "Player*") + actorList[x] = actorList[x].replace("Actor*", "struct Player*") elif "ActorListEntry actorLists[ACTORCAT_MAX];" in line: output[i] = "struct {\n" + "".join(actorList) + "};" ######################################################## From 9e6a6eee4cd53bd241ddcb349d94ad23b3e18c9f Mon Sep 17 00:00:00 2001 From: engineer124 <47598039+engineer124@users.noreply.github.com> Date: Mon, 17 Jan 2022 05:24:58 +1100 Subject: [PATCH 09/13] Audio_Effects OK and Documented (#549) * Audio_Effects OK * Remove duplicate * PR Suggestion * Small cleanup * Small Touchup --- include/functions.h | 18 +- include/variables.h | 130 +----------- include/z64audio.h | 27 +-- spec | 1 - src/code/audio/audio_effects.c | 340 ++++++++++++++++++++++++++++++- src/code/audio/audio_seqplayer.c | 2 +- tools/disasm/functions.txt | 22 +- tools/disasm/variables.txt | 130 +----------- tools/sizes/code_functions.csv | 22 +- 9 files changed, 375 insertions(+), 317 deletions(-) diff --git a/include/functions.h b/include/functions.h index 14744a9de..2d94268ba 100644 --- a/include/functions.h +++ b/include/functions.h @@ -3562,16 +3562,12 @@ void Audio_WritebackDCache(void* buf, size_t size); // void func_801964F8(void); // void func_801965F0(void); // void func_801968C4(void); -// void func_80196A00(void); -// void func_80196BC8(void); -// void func_80196D20(void); -// void func_80196D7C(void); -// void func_80196DB4(void); -// void func_80196FEC(void); -// void func_80197048(void); -// void func_80197138(void); -// void func_80197164(void); -// void func_80197188(void); +void AudioEffects_SequencePlayerProcessSound(SequencePlayer* seqPlayer); +void AudioEffects_NoteVibratoUpdate(Note* note); +void AudioEffects_NoteVibratoInit(Note* note); +void AudioEffects_NotePortamentoInit(Note* note); +void AudioEffects_AdsrInit(AdsrState* adsr, AdsrEnvelope* envelope, s16* volOut); +f32 AudioEffects_AdsrUpdate(AdsrState* adsr); // void func_801974D0(void); // void func_80197538(void); // void func_80197714(void); @@ -3583,7 +3579,7 @@ void Audio_WritebackDCache(void* buf, size_t size); // void func_80197C0C(void); // void func_80197C8C(void); // void func_80197D24(void); -// void func_80197D4C(void); +void AudioSeq_SequencePlayerDisable(SequencePlayer* seqPlayer); // void func_80197E08(void); // void func_80197E48(void); // void func_80197E88(void); diff --git a/include/variables.h b/include/variables.h index cabe5d09e..32983d58c 100644 --- a/include/variables.h +++ b/include/variables.h @@ -1642,10 +1642,10 @@ extern MtxF gIdentityMtxF; // extern UNK_TYPE1 D_801D4790; // extern UNK_TYPE1 D_801D4990; // extern UNK_TYPE1 D_801D4B90; -extern UNK_PTR D_801D4D90; +extern s16* gWaveSamples[9]; extern UNK_PTR D_801D4D98; extern UNK_PTR D_801D4DB0; -// extern UNK_TYPE1 D_801D4DB4; +extern f32 gBendPitchOneOctaveFrequencies[256]; // extern UNK_TYPE1 D_801D4FB4; // extern UNK_TYPE4 D_801D51B4; // extern UNK_TYPE4 D_801D53B4; @@ -3623,131 +3623,7 @@ extern SoundRequest D_801FE7C0[1]; // extern UNK_TYPE1 D_80200BCC; // extern UNK_TYPE1 D_80200BCE; // extern UNK_TYPE1 D_80200BD0; -// extern UNK_TYPE1 D_80200C70; -// extern UNK_TYPE1 D_80200C71; -// extern UNK_TYPE1 D_80200C76; -// extern UNK_TYPE1 D_80200C78; -// extern UNK_TYPE1 D_80200C7C; -// extern UNK_TYPE1 D_80200C80; -// extern UNK_TYPE1 D_80200C92; -// extern UNK_TYPE1 D_80200C94; -// extern UNK_TYPE1 D_80200C98; -// extern UNK_TYPE1 D_80200C9A; -// extern UNK_TYPE1 D_80200C9E; -// extern UNK_TYPE1 D_80200CA0; -// extern UNK_TYPE1 D_80200CF0; -// extern UNK_TYPE1 D_80200D38; -// extern UNK_TYPE1 D_80200D70; -// extern UNK_TYPE1 D_802011F0; -// extern UNK_TYPE1 D_8020178C; -// extern UNK_TYPE1 D_802017B0; -// extern UNK_TYPE1 D_80201D68; -// extern UNK_TYPE1 D_80201D6C; -// extern UNK_TYPE1 D_802023FC; -// extern UNK_TYPE1 D_80202878; -// extern UNK_TYPE1 D_80202880; -// extern UNK_TYPE1 D_802028BC; -extern OSMesgQueue D_80202980; -// extern UNK_TYPE1 D_802029D8; -extern OSMesgQueue D_80202AB0; -extern OSMesg D_80202AC8[0x10]; -extern OSMesgQueue D_80202B08; -extern OSMesg D_80202B20[0x10]; -extern OSMesgQueue D_80202B60; -extern OSMesg D_80202B78[0x40]; -extern OSMesgQueue D_80203278; -extern OSMesg D_80203290[1]; -// extern UNK_TYPE1 D_80203294; -// extern UNK_TYPE1 D_802034C0; -// extern UNK_TYPE1 D_802034C4; -// extern UNK_TYPE1 D_802034C8; -// extern UNK_TYPE4 D_802034D0; -// extern UNK_TYPE1 D_802034D4; -// extern UNK_TYPE1 D_802034D8; -// extern UNK_TYPE1 D_802034DC; -// extern UNK_TYPE1 D_802034E8; -// extern UNK_TYPE2 D_802034F0; -// extern UNK_TYPE1 D_802034F8; -// extern UNK_TYPE1 D_802034FC; -// extern UNK_TYPE1 D_80203500; -// extern UNK_TYPE4 D_80203528; -// extern UNK_TYPE1 D_8020352C; -// extern UNK_TYPE1 D_8020352E; -// extern UNK_TYPE1 D_80203530; -// extern UNK_TYPE4 D_8020360C; -// extern UNK_TYPE1 D_80203618; -// extern UNK_TYPE1 D_8020361C; -// extern UNK_TYPE1 D_80203620; -// extern UNK_TYPE1 D_80203624; -// extern UNK_TYPE1 D_80203628; -// extern UNK_TYPE1 D_80203630; -// extern UNK_TYPE1 D_80203640; -// extern UNK_TYPE1 D_80203650; -// extern UNK_TYPE1 D_80203660; -// extern UNK_TYPE1 D_80203690; -// extern UNK_TYPE1 D_802036A0; -// extern UNK_TYPE1 D_802036B0; -// extern UNK_TYPE1 D_802036C0; -// extern UNK_TYPE1 D_802036C4; -// extern UNK_TYPE1 D_80203794; -// extern UNK_TYPE1 D_80203798; -// extern UNK_TYPE1 D_802037D0; -// extern UNK_TYPE1 D_802037D4; -// extern UNK_TYPE1 D_802038A4; -// extern UNK_TYPE1 D_802038A8; -// extern UNK_TYPE1 D_802038C2; -// extern UNK_TYPE1 D_802038CE; -// extern UNK_TYPE1 D_802038E0; -// extern UNK_TYPE1 D_802038E4; -// extern UNK_TYPE1 D_80203970; -// extern UNK_TYPE1 D_802039B4; -// extern UNK_TYPE1 D_802039B8; -// extern UNK_TYPE1 D_802039D2; -// extern UNK_TYPE1 D_802039DE; -// extern UNK_TYPE1 D_802039F0; -// extern UNK_TYPE1 D_802039FC; -// extern UNK_TYPE1 D_80203B80; -// extern UNK_TYPE1 D_80203B88; -// extern UNK_TYPE1 D_80203B90; -// extern UNK_TYPE1 D_80204590; -// extern UNK_TYPE1 D_80204594; -// extern UNK_TYPE1 D_80204598; -// extern UNK_TYPE1 D_802045A4; -// extern UNK_TYPE1 D_80204FA4; -// extern UNK_TYPE1 D_80204FA8; -// extern UNK_TYPE1 D_80204FB4; -// extern UNK_TYPE1 D_80204FB8; -// extern UNK_TYPE1 D_80204FC0; -// extern UNK_TYPE1 D_80204FCC; -// extern UNK_TYPE1 D_80204FD8; -// extern UNK_TYPE1 D_80205008; -// extern UNK_TYPE1 D_80205038; -// extern UNK_TYPE1 D_802050B9; -// extern UNK_TYPE1 D_802050C0; -// extern UNK_TYPE1 D_802050C4; -// extern UNK_TYPE4 D_802050CC; -// extern UNK_TYPE4 D_802050D0; -// extern UNK_TYPE1 D_80205228; -// extern UNK_TYPE1 D_8020522B; -// extern UNK_TYPE1 D_80205390; -// extern UNK_TYPE1 D_802053C8; -// extern UNK_TYPE1 D_802057B0; -// extern UNK_TYPE1 D_80205830; -// extern UNK_TYPE1 D_802084B0; -// extern UNK_TYPE1 D_80208530; -// extern UNK_TYPE1 D_80208598; -// extern UNK_TYPE1 D_802085A8; -// extern UNK_TYPE1 D_802085B8; -// extern UNK_TYPE1 D_802085C8; -// extern UNK_TYPE1 D_802085D8; -// extern UNK_TYPE1 D_802085F8; -// extern UNK_TYPE1 D_802085FC; -// extern UNK_TYPE1 D_80208604; -// extern UNK_TYPE1 D_8020861C; -// extern UNK_TYPE1 D_80208634; -// extern UNK_TYPE1 D_8020864C; -// extern UNK_TYPE1 D_80208650; -// extern UNK_TYPE1 D_80208654; +extern AudioContext gAudioContext; // at 0x80200C70 // extern UNK_TYPE4 D_80208E68; // extern UNK_TYPE4 D_80208E6C; // extern UNK_TYPE4 D_80208E70; diff --git a/include/z64audio.h b/include/z64audio.h index bc6d81a71..06f70b81b 100644 --- a/include/z64audio.h +++ b/include/z64audio.h @@ -11,6 +11,8 @@ #define MAX_CHANNELS_PER_BANK 3 +#define AUDIO_LERPIMP(v0, v1, t) (v0 + ((v1 - v0) * t)) + #define ADSR_DISABLE 0 #define ADSR_HANG -1 #define ADSR_GOTO -2 @@ -154,10 +156,10 @@ typedef struct NotePool { // extrapolates exponentially in the wrong direction in that case, but that // doesn't prevent seqplayer from doing it, AFAICT. typedef struct { - /* 0x00 */ u8 mode; // bit 0x80 denotes something; the rest are an index 0-5 - /* 0x02 */ u16 cur; - /* 0x04 */ u16 speed; - /* 0x08 */ f32 extent; + /* 0x0 */ u8 mode; // bit 0x80 denotes something; the rest are an index 0-5 + /* 0x2 */ u16 cur; + /* 0x4 */ u16 speed; + /* 0x8 */ f32 extent; } Portamento; // size = 0xC typedef struct { @@ -298,7 +300,7 @@ typedef struct { /* 0x000 */ u8 fontDmaInProgress : 1; /* 0x000 */ u8 recalculateVolume : 1; /* 0x000 */ u8 stopScript : 1; - /* 0x000 */ u8 unk_0b1 : 1; + /* 0x000 */ u8 applyBend : 1; /* 0x001 */ u8 state; /* 0x002 */ u8 noteAllocPolicy; /* 0x003 */ u8 muteBehavior; @@ -324,7 +326,7 @@ typedef struct { /* 0x028 */ f32 muteVolumeScale; /* 0x02C */ f32 fadeVolumeScale; /* 0x030 */ f32 appliedFadeVolume; - /* 0x034 */ f32 unk_34; + /* 0x034 */ f32 bend; /* 0x038 */ struct SequenceChannel* channels[16]; /* 0x078 */ SeqScriptState scriptState; /* 0x094 */ u8* shortNoteVelocityTable; @@ -402,17 +404,6 @@ typedef struct VibratoSubStruct { /* 0xC */ u16 vibratoDelay; } VibratoSubStruct; // size = 0xE -typedef struct SequenceChannelSubStruct { - /* 0x0 */ u8 enabled : 1; - /* 0x0 */ u8 finished : 1; - /* 0x0 */ u8 stopScript : 1; - /* 0x0 */ u8 stopSomething2 : 1; // sets SequenceLayer.stopSomething - /* 0x0 */ u8 hasInstrument : 1; - /* 0x0 */ u8 stereoHeadsetEffects : 1; - /* 0x0 */ u8 largeNotes : 1; // notes specify duration and velocity - /* 0x0 */ u8 unused : 1; -} SequenceChannelSubStruct; // size = 0x1 - // Also known as a SubTrack, according to sm64 debug strings. typedef struct SequenceChannel { /* 0x00 */ u8 enabled : 1; @@ -530,7 +521,7 @@ typedef struct SequenceLayer { /* 0x30 */ Portamento portamento; /* 0x3C */ struct Note* note; /* 0x40 */ f32 freqScale; - /* 0x44 */ f32 unk_34; + /* 0x44 */ f32 bend; /* 0x48 */ f32 velocitySquare2; /* 0x4C */ f32 velocitySquare; // not sure which one of those corresponds to the sm64 original /* 0x50 */ f32 noteVelocity; diff --git a/spec b/spec index de71a0e4f..2215b88ab 100644 --- a/spec +++ b/spec @@ -635,7 +635,6 @@ beginseg include "build/data/code/code_80194790.data.o" include "build/src/code/audio/audio_playback.o" include "build/src/code/audio/audio_effects.o" - include "build/data/code/audio_effects.data.o" include "build/src/code/audio/audio_seqplayer.o" include "build/data/code/audio_seqplayer.data.o" include "build/data/code/audio_dramStack.data.o" diff --git a/src/code/audio/audio_effects.c b/src/code/audio/audio_effects.c index e795d5e9f..2dcef2237 100644 --- a/src/code/audio/audio_effects.c +++ b/src/code/audio/audio_effects.c @@ -1,21 +1,341 @@ #include "global.h" -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_effects/func_80196A00.s") +void AudioEffects_SequenceChannelProcessSound(SequenceChannel* channel, s32 recalculateVolume, s32 applyBend) { + f32 channelVolume; + f32 chanFreqScale; + s32 i; -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_effects/func_80196BC8.s") + if (channel->changes.s.volume || recalculateVolume) { + channelVolume = channel->volume * channel->volumeScale * channel->seqPlayer->appliedFadeVolume; + if (channel->seqPlayer->muted && (channel->muteBehavior & 0x20)) { + channelVolume = channel->seqPlayer->muteVolumeScale * channelVolume; + } + channel->appliedVolume = channelVolume * channelVolume; + } -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_effects/func_80196D20.s") + if (channel->changes.s.pan) { + channel->pan = channel->newPan * channel->panChannelWeight; + } -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_effects/func_80196D7C.s") + chanFreqScale = channel->freqScale; + if (applyBend) { + chanFreqScale *= channel->seqPlayer->bend; + channel->changes.s.freqScale = true; + } -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_effects/func_80196DB4.s") + for (i = 0; i < ARRAY_COUNT(channel->layers); i++) { + SequenceLayer* layer = channel->layers[i]; -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_effects/func_80196FEC.s") + if (layer != NULL && layer->enabled && layer->note != NULL) { + if (layer->notePropertiesNeedInit) { + layer->noteFreqScale = layer->freqScale * chanFreqScale; + layer->noteVelocity = layer->velocitySquare2 * channel->appliedVolume; + layer->notePan = (channel->pan + layer->pan * (0x80 - channel->panChannelWeight)) >> 7; + layer->notePropertiesNeedInit = false; + } else { + if (channel->changes.s.freqScale) { + layer->noteFreqScale = layer->freqScale * chanFreqScale; + } + if (channel->changes.s.volume || recalculateVolume) { + layer->noteVelocity = layer->velocitySquare2 * channel->appliedVolume; + } + if (channel->changes.s.pan) { + layer->notePan = (channel->pan + layer->pan * (0x80 - channel->panChannelWeight)) >> 7; + } + } + } + } + channel->changes.asByte = 0; +} -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_effects/func_80197048.s") +void AudioEffects_SequencePlayerProcessSound(SequencePlayer* seqPlayer) { + s32 i; -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_effects/func_80197138.s") + if ((seqPlayer->fadeTimer != 0) && (seqPlayer->skipTicks == 0)) { + seqPlayer->fadeVolume += seqPlayer->fadeVelocity; + seqPlayer->recalculateVolume = true; -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_effects/func_80197164.s") + if (seqPlayer->fadeVolume > 1.0f) { + seqPlayer->fadeVolume = 1.0f; + } + if (seqPlayer->fadeVolume < 0.0f) { + seqPlayer->fadeVolume = 0.0f; + } -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_effects/func_80197188.s") + seqPlayer->fadeTimer--; + if (seqPlayer->fadeTimer == 0 && seqPlayer->state == 2) { + AudioSeq_SequencePlayerDisable(seqPlayer); + return; + } + } + + if (seqPlayer->recalculateVolume) { + seqPlayer->appliedFadeVolume = seqPlayer->fadeVolume * seqPlayer->fadeVolumeScale; + } + + for (i = 0; i < ARRAY_COUNT(seqPlayer->channels); i++) { + if (seqPlayer->channels[i]->enabled == true) { + AudioEffects_SequenceChannelProcessSound(seqPlayer->channels[i], seqPlayer->recalculateVolume, + seqPlayer->applyBend); + } + } + + seqPlayer->recalculateVolume = false; +} + +f32 AudioEffects_GetPortamentoFreqScale(Portamento* portamento) { + u32 loResCur; + f32 portamentoFreq; + + portamento->cur += portamento->speed; + loResCur = (portamento->cur >> 8) & 0xFF; + + if (loResCur >= 127) { + loResCur = 127; + portamento->mode = 0; + } + + portamentoFreq = AUDIO_LERPIMP(1.0f, gBendPitchOneOctaveFrequencies[loResCur + 128], portamento->extent); + + return portamentoFreq; +} + +s16 AudioEffects_GetVibratoPitchChange(VibratoState* vib) { + s32 index; + + vib->time += (s32)vib->rate; + index = (vib->time >> 10) & 0x3F; + return vib->curve[index]; +} + +f32 AudioEffects_GetVibratoFreqScale(VibratoState* vib) { + static f32 activeVibratoFreqScaleSum = 0.0f; + static s32 activeVibratoCount = 0; + f32 pitchChange; + f32 extent; + f32 invExtent; + f32 result; + f32 scaledExtent; + VibratoSubStruct* subVib = vib->vibSubStruct; + + if (vib->delay != 0) { + vib->delay--; + return 1.0f; + } + + if (subVib != NULL) { + if (vib->extentChangeTimer) { + if (vib->extentChangeTimer == 1) { + vib->extent = (s32)subVib->vibratoExtentTarget; + } else { + vib->extent += ((s32)subVib->vibratoExtentTarget - vib->extent) / (s32)vib->extentChangeTimer; + } + + vib->extentChangeTimer--; + } else if (subVib->vibratoExtentTarget != (s32)vib->extent) { + if ((vib->extentChangeTimer = subVib->vibratoExtentChangeDelay) == 0) { + vib->extent = (s32)subVib->vibratoExtentTarget; + } + } + + if (vib->rateChangeTimer) { + if (vib->rateChangeTimer == 1) { + vib->rate = (s32)subVib->vibratoRateTarget; + } else { + vib->rate += ((s32)subVib->vibratoRateTarget - vib->rate) / (s32)vib->rateChangeTimer; + } + + vib->rateChangeTimer--; + } else if (subVib->vibratoRateTarget != (s32)vib->rate) { + if ((vib->rateChangeTimer = subVib->vibratoRateChangeDelay) == 0) { + vib->rate = (s32)subVib->vibratoRateTarget; + } + } + } + + if (vib->extent == 0.0f) { + return 1.0f; + } + + pitchChange = AudioEffects_GetVibratoPitchChange(vib) + 32768.0f; + scaledExtent = vib->extent / 4096.0f; + extent = scaledExtent + 1.0f; + invExtent = 1.0f / extent; + + // inverse linear interpolation + result = 1.0f / ((extent - invExtent) * pitchChange / 65536.0f + invExtent); + + activeVibratoFreqScaleSum += result; + activeVibratoCount++; + + return result; +} + +void AudioEffects_NoteVibratoUpdate(Note* note) { + if (note->playbackState.portamento.mode != 0) { + note->playbackState.portamentoFreqScale = AudioEffects_GetPortamentoFreqScale(¬e->playbackState.portamento); + } + if (note->playbackState.vibratoState.active) { + note->playbackState.vibratoFreqScale = AudioEffects_GetVibratoFreqScale(¬e->playbackState.vibratoState); + } +} + +void AudioEffects_NoteVibratoInit(Note* note) { + NotePlaybackState* playbackState = ¬e->playbackState; + VibratoState* vib = &playbackState->vibratoState; + VibratoSubStruct* subVib; + + vib->active = true; + vib->curve = gWaveSamples[2]; + + if (playbackState->parentLayer->unk_0A.s.bit_3 == 1) { + vib->vibSubStruct = &playbackState->parentLayer->channel->vibrato; + } else { + vib->vibSubStruct = &playbackState->parentLayer->vibrato; + } + + subVib = vib->vibSubStruct; + + if ((vib->extentChangeTimer = subVib->vibratoExtentChangeDelay) == 0) { + vib->extent = (s32)subVib->vibratoExtentTarget; + } else { + vib->extent = (s32)subVib->vibratoExtentStart; + } + + if ((vib->rateChangeTimer = subVib->vibratoRateChangeDelay) == 0) { + vib->rate = (s32)subVib->vibratoRateTarget; + } else { + vib->rate = (s32)subVib->vibratoRateStart; + } + + playbackState->vibratoFreqScale = 1.0f; + vib->time = 0; + vib->delay = subVib->vibratoDelay; +} + +void AudioEffects_NotePortamentoInit(Note* note) { + note->playbackState.portamentoFreqScale = 1.0f; + note->playbackState.portamento = note->playbackState.parentLayer->portamento; +} + +void AudioEffects_AdsrInit(AdsrState* adsr, AdsrEnvelope* envelope, s16* volOut) { + adsr->action.asByte = 0; + adsr->delay = 0; + adsr->envelope = envelope; + adsr->sustain = 0.0f; + adsr->current = 0.0f; + adsr->velocity = 0.0f; + // (An older versions of the audio engine used in Super Mario 64 did + // adsr->volOut = volOut. That line and associated struct member were + // removed, but the function parameter was forgotten and remains.) +} + +f32 AudioEffects_AdsrUpdate(AdsrState* adsr) { + u8 state = adsr->action.s.state; + + switch (state) { + case ADSR_STATE_DISABLED: + return 0.0f; + + case ADSR_STATE_INITIAL: + if (adsr->action.s.hang) { + adsr->action.s.state = ADSR_STATE_HANG; + break; + } + // fallthrough + + case ADSR_STATE_START_LOOP: + adsr->envIndex = 0; + adsr->action.s.state = ADSR_STATE_LOOP; + // fallthrough + + retry: + case ADSR_STATE_LOOP: + adsr->delay = adsr->envelope[adsr->envIndex].delay; + switch (adsr->delay) { + case ADSR_DISABLE: + adsr->action.s.state = ADSR_STATE_DISABLED; + break; + case ADSR_HANG: + adsr->action.s.state = ADSR_STATE_HANG; + break; + case ADSR_GOTO: + adsr->envIndex = adsr->envelope[adsr->envIndex].arg; + goto retry; + case ADSR_RESTART: + adsr->action.s.state = ADSR_STATE_INITIAL; + break; + + default: + adsr->delay *= gAudioContext.audioBufferParameters.unk_24; + if (adsr->delay == 0) { + adsr->delay = 1; + } + adsr->target = adsr->envelope[adsr->envIndex].arg / 32767.0f; + adsr->target = adsr->target * adsr->target; + adsr->velocity = (adsr->target - adsr->current) / adsr->delay; + adsr->action.s.state = ADSR_STATE_FADE; + adsr->envIndex++; + break; + } + if (adsr->action.s.state != ADSR_STATE_FADE) { + break; + } + // fallthrough + + case ADSR_STATE_FADE: + adsr->current += adsr->velocity; + if (--adsr->delay <= 0) { + adsr->action.s.state = ADSR_STATE_LOOP; + } + // fallthrough + + case ADSR_STATE_HANG: + break; + + case ADSR_STATE_DECAY: + case ADSR_STATE_RELEASE: + adsr->current -= adsr->fadeOutVel; + if (adsr->sustain != 0.0f && state == ADSR_STATE_DECAY) { + if (adsr->current < adsr->sustain) { + adsr->current = adsr->sustain; + adsr->delay = 128; + adsr->action.s.state = ADSR_STATE_SUSTAIN; + } + break; + } + + if (adsr->current < 0.00001f) { + adsr->current = 0.0f; + adsr->action.s.state = ADSR_STATE_DISABLED; + } + break; + + case ADSR_STATE_SUSTAIN: + adsr->delay--; + if (adsr->delay == 0) { + adsr->action.s.state = ADSR_STATE_RELEASE; + } + break; + } + + if (adsr->action.s.decay) { + adsr->action.s.state = ADSR_STATE_DECAY; + adsr->action.s.decay = false; + } + + if (adsr->action.s.release) { + adsr->action.s.state = ADSR_STATE_RELEASE; + adsr->action.s.release = false; + } + + if (adsr->current < 0.0f) { + return 0.0f; + } + + if (adsr->current > 1.0f) { + return 1.0f; + } + + return adsr->current; +} diff --git a/src/code/audio/audio_seqplayer.c b/src/code/audio/audio_seqplayer.c index e3841a50a..ec4375796 100644 --- a/src/code/audio/audio_seqplayer.c +++ b/src/code/audio/audio_seqplayer.c @@ -22,7 +22,7 @@ #pragma GLOBAL_ASM("asm/non_matchings/code/audio_seqplayer/func_80197D24.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_seqplayer/func_80197D4C.s") +#pragma GLOBAL_ASM("asm/non_matchings/code/audio_seqplayer/AudioSeq_SequencePlayerDisable.s") #pragma GLOBAL_ASM("asm/non_matchings/code/audio_seqplayer/func_80197E08.s") diff --git a/tools/disasm/functions.txt b/tools/disasm/functions.txt index a251e7798..f0caa1238 100644 --- a/tools/disasm/functions.txt +++ b/tools/disasm/functions.txt @@ -3757,16 +3757,16 @@ 0x801964F8:("func_801964F8",), 0x801965F0:("func_801965F0",), 0x801968C4:("func_801968C4",), - 0x80196A00:("func_80196A00",), - 0x80196BC8:("func_80196BC8",), - 0x80196D20:("func_80196D20",), - 0x80196D7C:("func_80196D7C",), - 0x80196DB4:("func_80196DB4",), - 0x80196FEC:("func_80196FEC",), - 0x80197048:("func_80197048",), - 0x80197138:("func_80197138",), - 0x80197164:("func_80197164",), - 0x80197188:("func_80197188",), + 0x80196A00:("AudioEffects_SequenceChannelProcessSound",), + 0x80196BC8:("AudioEffects_SequencePlayerProcessSound",), + 0x80196D20:("AudioEffects_GetPortamentoFreqScale",), + 0x80196D7C:("AudioEffects_GetVibratoPitchChange",), + 0x80196DB4:("AudioEffects_GetVibratoFreqScale",), + 0x80196FEC:("AudioEffects_NoteVibratoUpdate",), + 0x80197048:("AudioEffects_NoteVibratoInit",), + 0x80197138:("AudioEffects_NotePortamentoInit",), + 0x80197164:("AudioEffects_AdsrInit",), + 0x80197188:("AudioEffects_AdsrUpdate",), 0x801974D0:("func_801974D0",), 0x80197538:("func_80197538",), 0x80197714:("func_80197714",), @@ -3778,7 +3778,7 @@ 0x80197C0C:("func_80197C0C",), 0x80197C8C:("func_80197C8C",), 0x80197D24:("func_80197D24",), - 0x80197D4C:("func_80197D4C",), + 0x80197D4C:("AudioSeq_SequencePlayerDisable",), 0x80197E08:("func_80197E08",), 0x80197E48:("func_80197E48",), 0x80197E88:("func_80197E88",), diff --git a/tools/disasm/variables.txt b/tools/disasm/variables.txt index f1bbbb8d1..6c8568e84 100644 --- a/tools/disasm/variables.txt +++ b/tools/disasm/variables.txt @@ -2261,10 +2261,10 @@ 0x801D4790:("D_801D4790","UNK_TYPE1","",0x1), 0x801D4990:("D_801D4990","UNK_TYPE1","",0x1), 0x801D4B90:("D_801D4B90","UNK_TYPE1","",0x1), - 0x801D4D90:("D_801D4D90","UNK_PTR","",0x4), + 0x801D4D90:("gWaveSamples","UNK_PTR","",0x4), 0x801D4D98:("D_801D4D98","UNK_PTR","",0x4), 0x801D4DB0:("D_801D4DB0","UNK_PTR","",0x4), - 0x801D4DB4:("D_801D4DB4","f32","[256]",0x400), + 0x801D4DB4:("gBendPitchOneOctaveFrequencies","f32","[256]",0x400), 0x801D51B4:("D_801D51B4","f32","[256]",0x400), 0x801D55B4:("D_801D55B4","f32","[128]",0x200), 0x801D57B4:("D_801D57B4","UNK_TYPE1","",0x1), @@ -4420,131 +4420,7 @@ 0x80200BCC:("D_80200BCC","UNK_TYPE1","",0x1), 0x80200BCE:("D_80200BCE","UNK_TYPE1","",0x1), 0x80200BD0:("D_80200BD0","UNK_TYPE1","",0x1), - 0x80200C70:("D_80200C70","UNK_TYPE1","",0x1), - 0x80200C71:("D_80200C71","UNK_TYPE1","",0x1), - 0x80200C76:("D_80200C76","UNK_TYPE1","",0x1), - 0x80200C78:("D_80200C78","UNK_TYPE1","",0x1), - 0x80200C7C:("D_80200C7C","UNK_TYPE1","",0x1), - 0x80200C80:("D_80200C80","UNK_TYPE1","",0x1), - 0x80200C92:("D_80200C92","UNK_TYPE1","",0x1), - 0x80200C94:("D_80200C94","UNK_TYPE1","",0x1), - 0x80200C98:("D_80200C98","UNK_TYPE1","",0x1), - 0x80200C9A:("D_80200C9A","UNK_TYPE1","",0x1), - 0x80200C9E:("D_80200C9E","UNK_TYPE1","",0x1), - 0x80200CA0:("D_80200CA0","UNK_TYPE1","",0x1), - 0x80200CF0:("D_80200CF0","UNK_TYPE1","",0x1), - 0x80200D38:("D_80200D38","UNK_TYPE1","",0x1), - 0x80200D70:("D_80200D70","UNK_TYPE1","",0x1), - 0x802011F0:("D_802011F0","UNK_TYPE1","",0x1), - 0x8020178C:("D_8020178C","UNK_TYPE1","",0x1), - 0x802017B0:("D_802017B0","UNK_TYPE1","",0x1), - 0x80201D68:("D_80201D68","UNK_TYPE1","",0x1), - 0x80201D6C:("D_80201D6C","UNK_TYPE1","",0x1), - 0x802023FC:("D_802023FC","UNK_TYPE1","",0x1), - 0x80202878:("D_80202878","UNK_TYPE1","",0x1), - 0x80202880:("D_80202880","UNK_TYPE1","",0x1), - 0x802028BC:("D_802028BC","UNK_TYPE1","",0x1), - 0x80202980:("D_80202980","OSMesgQueue","",0x18), - 0x802029D8:("D_802029D8","UNK_TYPE1","",0x1), - 0x80202AB0:("D_80202AB0","OSMesgQueue","",0x18), - 0x80202AC8:("D_80202AC8","OSMesg","[16]",0x40), - 0x80202B08:("D_80202B08","OSMesgQueue","",0x18), - 0x80202B20:("D_80202B20","OSMesg","[16]",0x40), - 0x80202B60:("D_80202B60","OSMesgQueue","",0x18), - 0x80202B78:("D_80202B78","OSMesg","[64]",0x100), - 0x80203278:("D_80203278","OSMesgQueue","",0x18), - 0x80203290:("D_80203290","OSMesg","[1]",0x4), - 0x80203294:("D_80203294","UNK_TYPE1","",0x1), - 0x802034C0:("D_802034C0","UNK_TYPE1","",0x1), - 0x802034C4:("D_802034C4","UNK_TYPE1","",0x1), - 0x802034C8:("D_802034C8","UNK_TYPE1","",0x1), - 0x802034D0:("D_802034D0","UNK_TYPE4","",0x4), - 0x802034D4:("D_802034D4","UNK_TYPE1","",0x1), - 0x802034D8:("D_802034D8","UNK_TYPE1","",0x1), - 0x802034DC:("D_802034DC","UNK_TYPE1","",0x1), - 0x802034E8:("D_802034E8","UNK_TYPE1","",0x1), - 0x802034F0:("D_802034F0","UNK_TYPE2","",0x2), - 0x802034F8:("D_802034F8","UNK_TYPE1","",0x1), - 0x802034FC:("D_802034FC","UNK_TYPE1","",0x1), - 0x80203500:("D_80203500","UNK_TYPE1","",0x1), - 0x80203528:("D_80203528","UNK_TYPE4","",0x4), - 0x8020352C:("D_8020352C","UNK_TYPE1","",0x1), - 0x8020352E:("D_8020352E","UNK_TYPE1","",0x1), - 0x80203530:("D_80203530","UNK_TYPE1","",0x1), - 0x8020360C:("D_8020360C","UNK_TYPE4","",0x4), - 0x80203618:("D_80203618","UNK_TYPE1","",0x1), - 0x8020361C:("D_8020361C","UNK_TYPE1","",0x1), - 0x80203620:("D_80203620","UNK_TYPE1","",0x1), - 0x80203624:("D_80203624","UNK_TYPE1","",0x1), - 0x80203628:("D_80203628","UNK_TYPE1","",0x1), - 0x80203630:("D_80203630","UNK_TYPE1","",0x1), - 0x80203640:("D_80203640","UNK_TYPE1","",0x1), - 0x80203650:("D_80203650","UNK_TYPE1","",0x1), - 0x80203660:("D_80203660","UNK_TYPE1","",0x1), - 0x80203690:("D_80203690","UNK_TYPE1","",0x1), - 0x802036A0:("D_802036A0","UNK_TYPE1","",0x1), - 0x802036B0:("D_802036B0","UNK_TYPE1","",0x1), - 0x802036C0:("D_802036C0","UNK_TYPE1","",0x1), - 0x802036C4:("D_802036C4","UNK_TYPE1","",0x1), - 0x80203794:("D_80203794","UNK_TYPE1","",0x1), - 0x80203798:("D_80203798","UNK_TYPE1","",0x1), - 0x802037D0:("D_802037D0","UNK_TYPE1","",0x1), - 0x802037D4:("D_802037D4","UNK_TYPE1","",0x1), - 0x802038A4:("D_802038A4","UNK_TYPE1","",0x1), - 0x802038A8:("D_802038A8","UNK_TYPE1","",0x1), - 0x802038C2:("D_802038C2","UNK_TYPE1","",0x1), - 0x802038CE:("D_802038CE","UNK_TYPE1","",0x1), - 0x802038E0:("D_802038E0","UNK_TYPE1","",0x1), - 0x802038E4:("D_802038E4","UNK_TYPE1","",0x1), - 0x80203970:("D_80203970","UNK_TYPE1","",0x1), - 0x802039B4:("D_802039B4","UNK_TYPE1","",0x1), - 0x802039B8:("D_802039B8","UNK_TYPE1","",0x1), - 0x802039D2:("D_802039D2","UNK_TYPE1","",0x1), - 0x802039DE:("D_802039DE","UNK_TYPE1","",0x1), - 0x802039F0:("D_802039F0","UNK_TYPE1","",0x1), - 0x802039FC:("D_802039FC","UNK_TYPE1","",0x1), - 0x80203B80:("D_80203B80","UNK_TYPE1","",0x1), - 0x80203B88:("D_80203B88","UNK_TYPE1","",0x1), - 0x80203B90:("D_80203B90","UNK_TYPE1","",0x1), - 0x80204590:("D_80204590","UNK_TYPE1","",0x1), - 0x80204594:("D_80204594","UNK_TYPE1","",0x1), - 0x80204598:("D_80204598","UNK_TYPE1","",0x1), - 0x802045A4:("D_802045A4","UNK_TYPE1","",0x1), - 0x80204FA4:("D_80204FA4","UNK_TYPE1","",0x1), - 0x80204FA8:("D_80204FA8","UNK_TYPE1","",0x1), - 0x80204FB4:("D_80204FB4","UNK_TYPE1","",0x1), - 0x80204FB8:("D_80204FB8","UNK_TYPE1","",0x1), - 0x80204FC0:("D_80204FC0","UNK_TYPE1","",0x1), - 0x80204FCC:("D_80204FCC","UNK_TYPE1","",0x1), - 0x80204FD8:("D_80204FD8","UNK_TYPE1","",0x1), - 0x80205008:("D_80205008","UNK_TYPE1","",0x1), - 0x80205038:("D_80205038","UNK_TYPE1","",0x1), - 0x802050B9:("D_802050B9","UNK_TYPE1","",0x1), - 0x802050C0:("D_802050C0","UNK_TYPE1","",0x1), - 0x802050C4:("D_802050C4","UNK_TYPE1","",0x1), - 0x802050CC:("D_802050CC","UNK_TYPE4","",0x4), - 0x802050D0:("D_802050D0","UNK_TYPE4","",0x4), - 0x80205228:("D_80205228","UNK_TYPE1","",0x1), - 0x8020522B:("D_8020522B","UNK_TYPE1","",0x1), - 0x80205390:("D_80205390","UNK_TYPE1","",0x1), - 0x802053C8:("D_802053C8","UNK_TYPE1","",0x1), - 0x802057B0:("D_802057B0","UNK_TYPE1","",0x1), - 0x80205830:("D_80205830","UNK_TYPE1","",0x1), - 0x802084B0:("D_802084B0","UNK_TYPE1","",0x1), - 0x80208530:("D_80208530","UNK_TYPE1","",0x1), - 0x80208598:("D_80208598","UNK_TYPE1","",0x1), - 0x802085A8:("D_802085A8","UNK_TYPE1","",0x1), - 0x802085B8:("D_802085B8","UNK_TYPE1","",0x1), - 0x802085C8:("D_802085C8","UNK_TYPE1","",0x1), - 0x802085D8:("D_802085D8","UNK_TYPE1","",0x1), - 0x802085F8:("D_802085F8","UNK_TYPE1","",0x1), - 0x802085FC:("D_802085FC","UNK_TYPE1","",0x1), - 0x80208604:("D_80208604","UNK_TYPE1","",0x1), - 0x8020861C:("D_8020861C","UNK_TYPE1","",0x1), - 0x80208634:("D_80208634","UNK_TYPE1","",0x1), - 0x8020864C:("D_8020864C","UNK_TYPE1","",0x1), - 0x80208650:("D_80208650","UNK_TYPE1","",0x1), - 0x80208654:("D_80208654","UNK_TYPE1","",0x1), + 0x80200C70:("gAudioContext","AudioContext","",0x81F8), 0x80208E68:("D_80208E68","UNK_TYPE4","",0x4), 0x80208E6C:("D_80208E6C","UNK_TYPE4","",0x4), 0x80208E70:("D_80208E70","UNK_TYPE4","",0x4), diff --git a/tools/sizes/code_functions.csv b/tools/sizes/code_functions.csv index ea6a1c6b8..31ad65d9f 100644 --- a/tools/sizes/code_functions.csv +++ b/tools/sizes/code_functions.csv @@ -3275,16 +3275,16 @@ asm/non_matchings/code/audio_playback/func_80196494.s,func_80196494,0x80196494,0 asm/non_matchings/code/audio_playback/func_801964F8.s,func_801964F8,0x801964F8,0x3E asm/non_matchings/code/audio_playback/func_801965F0.s,func_801965F0,0x801965F0,0xB5 asm/non_matchings/code/audio_playback/func_801968C4.s,func_801968C4,0x801968C4,0x4F -asm/non_matchings/code/audio_effects/func_80196A00.s,func_80196A00,0x80196A00,0x72 -asm/non_matchings/code/audio_effects/func_80196BC8.s,func_80196BC8,0x80196BC8,0x56 -asm/non_matchings/code/audio_effects/func_80196D20.s,func_80196D20,0x80196D20,0x17 -asm/non_matchings/code/audio_effects/func_80196D7C.s,func_80196D7C,0x80196D7C,0xE -asm/non_matchings/code/audio_effects/func_80196DB4.s,func_80196DB4,0x80196DB4,0x8E -asm/non_matchings/code/audio_effects/func_80196FEC.s,func_80196FEC,0x80196FEC,0x17 -asm/non_matchings/code/audio_effects/func_80197048.s,func_80197048,0x80197048,0x3C -asm/non_matchings/code/audio_effects/func_80197138.s,func_80197138,0x80197138,0xB -asm/non_matchings/code/audio_effects/func_80197164.s,func_80197164,0x80197164,0x9 -asm/non_matchings/code/audio_effects/func_80197188.s,func_80197188,0x80197188,0xD2 +asm/non_matchings/code/audio_effects/AudioEffects_SequenceChannelProcessSound.s,AudioEffects_SequenceChannelProcessSound,0x80196A00,0x72 +asm/non_matchings/code/audio_effects/AudioEffects_SequencePlayerProcessSound.s,AudioEffects_SequencePlayerProcessSound,0x80196BC8,0x56 +asm/non_matchings/code/audio_effects/AudioEffects_GetPortamentoFreqScale.s,AudioEffects_GetPortamentoFreqScale,0x80196D20,0x17 +asm/non_matchings/code/audio_effects/AudioEffects_GetVibratoPitchChange.s,AudioEffects_GetVibratoPitchChange,0x80196D7C,0xE +asm/non_matchings/code/audio_effects/AudioEffects_GetVibratoFreqScale.s,AudioEffects_GetVibratoFreqScale,0x80196DB4,0x8E +asm/non_matchings/code/audio_effects/AudioEffects_NoteVibratoUpdate.s,AudioEffects_NoteVibratoUpdate,0x80196FEC,0x17 +asm/non_matchings/code/audio_effects/AudioEffects_NoteVibratoInit.s,AudioEffects_NoteVibratoInit,0x80197048,0x3C +asm/non_matchings/code/audio_effects/AudioEffects_NotePortamentoInit.s,AudioEffects_NotePortamentoInit,0x80197138,0xB +asm/non_matchings/code/audio_effects/AudioEffects_AdsrInit.s,AudioEffects_AdsrInit,0x80197164,0x9 +asm/non_matchings/code/audio_effects/AudioEffects_AdsrUpdate.s,AudioEffects_AdsrUpdate,0x80197188,0xD2 asm/non_matchings/code/audio_seqplayer/func_801974D0.s,func_801974D0,0x801974D0,0x1A asm/non_matchings/code/audio_seqplayer/func_80197538.s,func_80197538,0x80197538,0x77 asm/non_matchings/code/audio_seqplayer/func_80197714.s,func_80197714,0x80197714,0x5B @@ -3296,7 +3296,7 @@ asm/non_matchings/code/audio_seqplayer/func_80197B14.s,func_80197B14,0x80197B14, asm/non_matchings/code/audio_seqplayer/func_80197C0C.s,func_80197C0C,0x80197C0C,0x20 asm/non_matchings/code/audio_seqplayer/func_80197C8C.s,func_80197C8C,0x80197C8C,0x26 asm/non_matchings/code/audio_seqplayer/func_80197D24.s,func_80197D24,0x80197D24,0xA -asm/non_matchings/code/audio_seqplayer/func_80197D4C.s,func_80197D4C,0x80197D4C,0x2F +asm/non_matchings/code/audio_seqplayer/AudioSeq_SequencePlayerDisable.s,AudioSeq_SequencePlayerDisable,0x80197D4C,0x2F asm/non_matchings/code/audio_seqplayer/func_80197E08.s,func_80197E08,0x80197E08,0x10 asm/non_matchings/code/audio_seqplayer/func_80197E48.s,func_80197E48,0x80197E48,0x10 asm/non_matchings/code/audio_seqplayer/func_80197E88.s,func_80197E88,0x80197E88,0x28 From 194c99d80b07cdc4b4e2ae92fe0cee18a22615ec Mon Sep 17 00:00:00 2001 From: Anghelo Carvajal Date: Sun, 16 Jan 2022 15:30:31 -0300 Subject: [PATCH 10/13] Subrepos update (#613) * a * git subrepo pull tools/asm-differ --force subrepo: subdir: "tools/asm-differ" merged: "6f8f80b71" upstream: origin: "https://github.com/simonlindholm/asm-differ" branch: "main" commit: "6f8f80b71" git-subrepo: version: "0.4.3" origin: "https://github.com/ingydotnet/git-subrepo.git" commit: "2f68596" * git subrepo pull tools/z64compress --force subrepo: subdir: "tools/z64compress" merged: "9e7a6dbfa" upstream: origin: "https://github.com/z64me/z64compress.git" branch: "main" commit: "9e7a6dbfa" git-subrepo: version: "0.4.3" origin: "https://github.com/ingydotnet/git-subrepo.git" commit: "2f68596" * git subrepo pull tools/ZAPD --force subrepo: subdir: "tools/ZAPD" merged: "bf16ff7c4" upstream: origin: "https://github.com/zeldaret/ZAPD.git" branch: "master" commit: "bf16ff7c4" git-subrepo: version: "0.4.3" origin: "https://github.com/ingydotnet/git-subrepo.git" commit: "2f68596" * Revert "git subrepo pull tools/z64compress --force" This reverts commit a7cc87394ed4afb5ebe1f2318526545b6bbe205d. --- tools/ZAPD/.gitrepo | 4 +- tools/ZAPD/Jenkinsfile | 2 +- tools/ZAPD/ZAPD/Declaration.cpp | 2 +- tools/ZAPD/ZAPD/Main.cpp | 4 + tools/ZAPD/ZAPD/ZArray.cpp | 13 ++- tools/ZAPD/ZAPD/ZCollision.cpp | 89 ++++++++++++------- tools/ZAPD/ZAPD/ZCollision.h | 3 +- tools/ZAPD/ZAPD/ZPointer.cpp | 57 ++++++++++++ tools/ZAPD/ZAPD/ZPointer.h | 22 +++++ tools/ZAPD/ZAPD/ZResource.h | 1 + tools/ZAPD/ZAPD/ZTexture.cpp | 53 +++++++---- tools/ZAPD/ZAPD/ZTexture.h | 1 + .../docs/zapd_extraction_xml_reference.md | 25 +++++- tools/asm-differ/.gitrepo | 6 +- tools/asm-differ/diff.py | 48 +++++----- 15 files changed, 240 insertions(+), 90 deletions(-) create mode 100644 tools/ZAPD/ZAPD/ZPointer.cpp create mode 100644 tools/ZAPD/ZAPD/ZPointer.h diff --git a/tools/ZAPD/.gitrepo b/tools/ZAPD/.gitrepo index ccd6c7d64..7576be8e0 100644 --- a/tools/ZAPD/.gitrepo +++ b/tools/ZAPD/.gitrepo @@ -6,7 +6,7 @@ [subrepo] remote = https://github.com/zeldaret/ZAPD.git branch = master - commit = fd5a7f434171a33b1b3eb2a3e112fdcee6d9262d - parent = 844c24e39c96b7a3f3a40035058bda6c91ed4bbf + commit = bf16ff7c4c409358a53793b72260b1d8e474cf0c + parent = a7cc87394ed4afb5ebe1f2318526545b6bbe205d method = merge cmdver = 0.4.3 diff --git a/tools/ZAPD/Jenkinsfile b/tools/ZAPD/Jenkinsfile index ec9b56ac5..9c4dde712 100644 --- a/tools/ZAPD/Jenkinsfile +++ b/tools/ZAPD/Jenkinsfile @@ -61,7 +61,7 @@ pipeline { sh 'cp ../ZAPD.out tools/ZAPD/' sh 'python3 tools/fixbaserom.py' sh 'python3 tools/extract_baserom.py' - sh 'python3 extract_assets.py -t$(nproc)' + sh 'python3 extract_assets.py -j $(nproc)' } } } diff --git a/tools/ZAPD/ZAPD/Declaration.cpp b/tools/ZAPD/ZAPD/Declaration.cpp index be06b0bea..34ab95351 100644 --- a/tools/ZAPD/ZAPD/Declaration.cpp +++ b/tools/ZAPD/ZAPD/Declaration.cpp @@ -171,7 +171,7 @@ std::string Declaration::GetExternalDeclarationStr() const std::string Declaration::GetExternStr() const { - if (IsStatic() || varType == "") + if (IsStatic() || varType == "" || isUnaccounted) { return ""; } diff --git a/tools/ZAPD/ZAPD/Main.cpp b/tools/ZAPD/ZAPD/Main.cpp index 048338fb7..531edc094 100644 --- a/tools/ZAPD/ZAPD/Main.cpp +++ b/tools/ZAPD/ZAPD/Main.cpp @@ -434,6 +434,10 @@ void BuildAssetTexture(const fs::path& pngFilePath, TextureType texType, const f std::string name = outPath.stem().string(); ZTexture tex(nullptr); + + if (name.find("u32") != std::string::npos) + tex.dWordAligned = false; + tex.FromPNG(pngFilePath.string(), texType); std::string cfgPath = StringHelper::Split(pngFilePath.string(), ".")[0] + ".cfg"; diff --git a/tools/ZAPD/ZAPD/ZArray.cpp b/tools/ZAPD/ZAPD/ZArray.cpp index ebfb13ee7..b6d9e50e5 100644 --- a/tools/ZAPD/ZAPD/ZArray.cpp +++ b/tools/ZAPD/ZAPD/ZArray.cpp @@ -101,11 +101,18 @@ std::string ZArray::GetBodySourceCode() const const auto& res = resList[i]; output += "\t"; - if (res->GetResourceType() == ZResourceType::Scalar || - res->GetResourceType() == ZResourceType::Vertex) + switch (res->GetResourceType()) + { + case ZResourceType::Pointer: + case ZResourceType::Scalar: + case ZResourceType::Vertex: output += resList.at(i)->GetBodySourceCode(); - else + break; + + default: output += StringHelper::Sprintf("{ %s }", resList.at(i)->GetBodySourceCode().c_str()); + break; + } if (i < arrayCnt - 1 || res->IsExternalResource()) output += ",\n"; diff --git a/tools/ZAPD/ZAPD/ZCollision.cpp b/tools/ZAPD/ZAPD/ZCollision.cpp index 1dfa46b1d..6554005ec 100644 --- a/tools/ZAPD/ZAPD/ZCollision.cpp +++ b/tools/ZAPD/ZAPD/ZCollision.cpp @@ -1,5 +1,6 @@ #include "ZCollision.h" +#include #include #include @@ -76,9 +77,42 @@ void ZCollisionHeader::ParseRawData() polygonTypes.push_back( BitConverter::ToUInt64BE(rawData, polyTypeDefSegmentOffset + (i * 8))); - if (camDataAddress != 0) - camData = new CameraDataList(parent, name, rawData, camDataSegmentOffset, - polyTypeDefSegmentOffset, polygonTypes.size()); + if (camDataAddress != SEGMENTED_NULL) + { + // Try to guess how many elements the CamDataList array has. + // The "guessing algorithm" is basically a "best effort" one and it + // is error-prone. + // This is based mostly on observation of how CollisionHeader data is + // usually ordered. If for some reason the data was in some other funny + // order, this would probably break. + // The most common ordering is: + // - *CamData* + // - SurfaceType + // - CollisionPoly + // - Vertices + // - WaterBoxes + // - CollisionHeader + offset_t upperCameraBoundary = polyTypeDefSegmentOffset; + if (upperCameraBoundary == 0) + { + upperCameraBoundary = polySegmentOffset; + } + if (upperCameraBoundary == 0) + { + upperCameraBoundary = vtxSegmentOffset; + } + if (upperCameraBoundary == 0) + { + upperCameraBoundary = waterBoxSegmentOffset; + } + if (upperCameraBoundary == 0) + { + upperCameraBoundary = rawDataIndex; + } + + camData = + new CameraDataList(parent, name, rawData, camDataSegmentOffset, upperCameraBoundary); + } for (uint16_t i = 0; i < numWaterBoxes; i++) waterBoxes.push_back(WaterBoxHeader( @@ -106,8 +140,7 @@ void ZCollisionHeader::DeclareReferences(const std::string& prefix) parent->AddDeclarationArray( waterBoxSegmentOffset, DeclarationAlignment::Align4, 16 * waterBoxes.size(), "WaterBox", - StringHelper::Sprintf("%s_waterBoxes_%06X", auxName.c_str(), waterBoxSegmentOffset), - waterBoxes.size(), declaration); + StringHelper::Sprintf("%sWaterBoxes", auxName.c_str()), waterBoxes.size(), declaration); } if (polygons.size() > 0) @@ -126,8 +159,7 @@ void ZCollisionHeader::DeclareReferences(const std::string& prefix) parent->AddDeclarationArray( polySegmentOffset, DeclarationAlignment::Align4, polygons.size() * 16, "CollisionPoly", - StringHelper::Sprintf("%s_polygons_%08X", auxName.c_str(), polySegmentOffset), - polygons.size(), declaration); + StringHelper::Sprintf("%sPolygons", auxName.c_str()), polygons.size(), declaration); } declaration.clear(); @@ -141,11 +173,10 @@ void ZCollisionHeader::DeclareReferences(const std::string& prefix) } if (polyTypeDefAddress != 0) - parent->AddDeclarationArray( - polyTypeDefSegmentOffset, DeclarationAlignment::Align4, polygonTypes.size() * 8, - "SurfaceType", - StringHelper::Sprintf("%s_surfaceType_%08X", auxName.c_str(), polyTypeDefSegmentOffset), - polygonTypes.size(), declaration); + parent->AddDeclarationArray(polyTypeDefSegmentOffset, DeclarationAlignment::Align4, + polygonTypes.size() * 8, "SurfaceType", + StringHelper::Sprintf("%sSurfaceType", auxName.c_str()), + polygonTypes.size(), declaration); declaration.clear(); @@ -167,8 +198,7 @@ void ZCollisionHeader::DeclareReferences(const std::string& prefix) parent->AddDeclarationArray( vtxSegmentOffset, first.GetDeclarationAlignment(), vertices.size() * first.GetRawDataSize(), first.GetSourceTypeName(), - StringHelper::Sprintf("%s_vtx_%08X", auxName.c_str(), vtxSegmentOffset), - vertices.size(), declaration); + StringHelper::Sprintf("%sVertices", auxName.c_str()), vertices.size(), declaration); } } @@ -183,11 +213,11 @@ std::string ZCollisionHeader::GetBodySourceCode() const std::string vtxName; Globals::Instance->GetSegmentedPtrName(vtxAddress, parent, "Vec3s", vtxName); - declaration += StringHelper::Sprintf("\t%i,\n\t%s,\n", numVerts, vtxName.c_str()); + declaration += StringHelper::Sprintf("\t%i, %s,\n", numVerts, vtxName.c_str()); std::string polyName; Globals::Instance->GetSegmentedPtrName(polyAddress, parent, "CollisionPoly", polyName); - declaration += StringHelper::Sprintf("\t%i,\n\t%s,\n", numPolygons, polyName.c_str()); + declaration += StringHelper::Sprintf("\t%i, %s,\n", numPolygons, polyName.c_str()); std::string surfaceName; Globals::Instance->GetSegmentedPtrName(polyTypeDefAddress, parent, "SurfaceType", surfaceName); @@ -199,7 +229,7 @@ std::string ZCollisionHeader::GetBodySourceCode() const std::string waterBoxName; Globals::Instance->GetSegmentedPtrName(waterBoxAddress, parent, "WaterBox", waterBoxName); - declaration += StringHelper::Sprintf("\t%i,\n\t%s\n", numWaterBoxes, waterBoxName.c_str()); + declaration += StringHelper::Sprintf("\t%i, %s\n", numWaterBoxes, waterBoxName.c_str()); return declaration; } @@ -261,16 +291,17 @@ std::string WaterBoxHeader::GetBodySourceCode() const } CameraDataList::CameraDataList(ZFile* parent, const std::string& prefix, - const std::vector& rawData, uint32_t rawDataIndex, - uint32_t polyTypeDefSegmentOffset, - [[maybe_unused]] uint32_t polygonTypesCnt) + const std::vector& rawData, offset_t rawDataIndex, + offset_t upperCameraBoundary) { std::string declaration; // Parse CameraDataEntries - int32_t numElements = (polyTypeDefSegmentOffset - rawDataIndex) / 8; - uint32_t cameraPosDataSeg = rawDataIndex; - for (int32_t i = 0; i < numElements; i++) + size_t numElements = (upperCameraBoundary - rawDataIndex) / 8; + assert(numElements < 10000); + + offset_t cameraPosDataSeg = rawDataIndex; + for (size_t i = 0; i < numElements; i++) { CameraDataEntry* entry = new CameraDataEntry(); @@ -302,8 +333,7 @@ CameraDataList::CameraDataList(ZFile* parent, const std::string& prefix, { int32_t index = ((entries[i]->cameraPosDataSeg & 0x00FFFFFF) - cameraPosDataOffset) / 0x6; - sprintf(camSegLine, "&%s_camPosData_%08X[%i]", prefix.c_str(), cameraPosDataOffset, - index); + sprintf(camSegLine, "&%sCamPosData[%i]", prefix.c_str(), index); } else sprintf(camSegLine, "NULL"); @@ -318,7 +348,7 @@ CameraDataList::CameraDataList(ZFile* parent, const std::string& prefix, parent->AddDeclarationArray( rawDataIndex, DeclarationAlignment::Align4, entries.size() * 8, "CamData", - StringHelper::Sprintf("%s_camDataList_%08X", prefix.c_str(), rawDataIndex), entries.size(), + StringHelper::Sprintf("%sCamDataList", prefix.c_str(), rawDataIndex), entries.size(), declaration); uint32_t numDataTotal = (rawDataIndex - cameraPosDataOffset) / 0x6; @@ -339,10 +369,9 @@ CameraDataList::CameraDataList(ZFile* parent, const std::string& prefix, int32_t cameraPosDataIndex = GETSEGOFFSET(cameraPosDataSeg); uint32_t entrySize = numDataTotal * 0x6; - parent->AddDeclarationArray( - cameraPosDataIndex, DeclarationAlignment::Align4, entrySize, "Vec3s", - StringHelper::Sprintf("%s_camPosData_%08X", prefix.c_str(), cameraPosDataIndex), - numDataTotal, declaration); + parent->AddDeclarationArray(cameraPosDataIndex, DeclarationAlignment::Align4, entrySize, + "Vec3s", StringHelper::Sprintf("%sCamPosData", prefix.c_str()), + numDataTotal, declaration); } } diff --git a/tools/ZAPD/ZAPD/ZCollision.h b/tools/ZAPD/ZAPD/ZCollision.h index d0325bfb9..222fd25f9 100644 --- a/tools/ZAPD/ZAPD/ZCollision.h +++ b/tools/ZAPD/ZAPD/ZCollision.h @@ -55,8 +55,7 @@ public: std::vector cameraPositionData; CameraDataList(ZFile* parent, const std::string& prefix, const std::vector& rawData, - uint32_t rawDataIndex, uint32_t polyTypeDefSegmentOffset, - uint32_t polygonTypesCnt); + offset_t rawDataIndex, offset_t upperCameraBoundary); ~CameraDataList(); }; diff --git a/tools/ZAPD/ZAPD/ZPointer.cpp b/tools/ZAPD/ZAPD/ZPointer.cpp new file mode 100644 index 000000000..6e6945cad --- /dev/null +++ b/tools/ZAPD/ZAPD/ZPointer.cpp @@ -0,0 +1,57 @@ +#include "ZPointer.h" + +#include "Globals.h" +#include "Utils/BitConverter.h" +#include "Utils/StringHelper.h" +#include "WarningHandler.h" +#include "ZFile.h" + +REGISTER_ZFILENODE(Pointer, ZPointer); + +ZPointer::ZPointer(ZFile* nParent) : ZResource(nParent) +{ + RegisterRequiredAttribute("Type"); +} + +void ZPointer::ParseXML(tinyxml2::XMLElement* reader) +{ + ZResource::ParseXML(reader); + + type = registeredAttributes.at("Type").value; +} + +void ZPointer::ParseRawData() +{ + auto& rawData = parent->GetRawData(); + + ptr = BitConverter::ToUInt32BE(rawData, rawDataIndex); +} + +std::string ZPointer::GetBodySourceCode() const +{ + std::string ptrName; + + Globals::Instance->GetSegmentedPtrName(ptr, parent, "", ptrName); + + return ptrName; +} + +bool ZPointer::DoesSupportArray() const +{ + return true; +} + +std::string ZPointer::GetSourceTypeName() const +{ + return type + "*"; +} + +ZResourceType ZPointer::GetResourceType() const +{ + return ZResourceType::Pointer; +} + +size_t ZPointer::GetRawDataSize() const +{ + return 0x04; +} diff --git a/tools/ZAPD/ZAPD/ZPointer.h b/tools/ZAPD/ZAPD/ZPointer.h new file mode 100644 index 000000000..8fb588933 --- /dev/null +++ b/tools/ZAPD/ZAPD/ZPointer.h @@ -0,0 +1,22 @@ +#pragma once + +#include "ZResource.h" + +class ZPointer : public ZResource +{ +public: + segptr_t ptr = SEGMENTED_NULL; + std::string type; + + ZPointer(ZFile* nParent); + + void ParseXML(tinyxml2::XMLElement* reader) override; + void ParseRawData() override; + std::string GetBodySourceCode() const override; + + bool DoesSupportArray() const override; + std::string GetSourceTypeName() const override; + ZResourceType GetResourceType() const override; + + size_t GetRawDataSize() const override; +}; diff --git a/tools/ZAPD/ZAPD/ZResource.h b/tools/ZAPD/ZAPD/ZResource.h index 4dad39895..c65c3c31b 100644 --- a/tools/ZAPD/ZAPD/ZResource.h +++ b/tools/ZAPD/ZAPD/ZResource.h @@ -38,6 +38,7 @@ enum class ZResourceType Mtx, Path, PlayerAnimationData, + Pointer, Room, RoomCommand, Scalar, diff --git a/tools/ZAPD/ZAPD/ZTexture.cpp b/tools/ZAPD/ZAPD/ZTexture.cpp index 7bd31438b..0d72d9c5a 100644 --- a/tools/ZAPD/ZAPD/ZTexture.cpp +++ b/tools/ZAPD/ZAPD/ZTexture.cpp @@ -16,6 +16,7 @@ ZTexture::ZTexture(ZFile* nParent) : ZResource(nParent) { width = 0; height = 0; + dWordAligned = true; RegisterRequiredAttribute("Width"); RegisterRequiredAttribute("Height"); @@ -105,10 +106,7 @@ void ZTexture::ParseXML(tinyxml2::XMLElement* reader) void ZTexture::ParseRawData() { if (rawDataIndex % 8 != 0) - { - HANDLE_WARNING_RESOURCE(WarningType::NotImplemented, parent, this, rawDataIndex, - "this texture is not 64-bit aligned", ""); - } + dWordAligned = false; switch (format) { @@ -724,7 +722,12 @@ void ZTexture::Save(const fs::path& outFolder) if (!Directory::Exists(outPath.string())) Directory::CreateDirectory(outPath.string()); - auto outFileName = outPath / (outName + "." + GetExternalExtension() + ".png"); + std::filesystem::__cxx11::path outFileName; + + if (!dWordAligned) + outFileName = outPath / (outName + ".u32" + "." + GetExternalExtension() + ".png"); + else + outFileName = outPath / (outName + +"." + GetExternalExtension() + ".png"); #ifdef TEXTURE_DEBUG printf("Saving PNG: %s\n", outFileName.c_str()); @@ -745,7 +748,7 @@ Declaration* ZTexture::DeclareVar(const std::string& prefix, { std::string auxName = name; std::string auxOutName = outName; - + std::string incStr; if (auxName == "") auxName = GetDefaultName(prefix); @@ -754,8 +757,12 @@ Declaration* ZTexture::DeclareVar(const std::string& prefix, auto filepath = Globals::Instance->outputPath / fs::path(auxOutName).stem(); - std::string incStr = - StringHelper::Sprintf("%s.%s.inc.c", filepath.c_str(), GetExternalExtension().c_str()); + if (dWordAligned) + incStr = + StringHelper::Sprintf("%s.%s.inc.c", filepath.c_str(), GetExternalExtension().c_str()); + else + incStr = StringHelper::Sprintf("%s.u32.%s.inc.c", filepath.c_str(), + GetExternalExtension().c_str()); if (!Globals::Instance->cfg.texturePool.empty()) { @@ -765,13 +772,19 @@ Declaration* ZTexture::DeclareVar(const std::string& prefix, const auto& poolEntry = Globals::Instance->cfg.texturePool.find(hash); if (poolEntry != Globals::Instance->cfg.texturePool.end()) { - incStr = StringHelper::Sprintf("%s.%s.inc.c", poolEntry->second.path.c_str(), - GetExternalExtension().c_str()); + if (dWordAligned) + incStr = StringHelper::Sprintf("%s.%s.inc.c", poolEntry->second.path.c_str(), + GetExternalExtension().c_str()); + else + incStr = StringHelper::Sprintf("%s.u32.%s.inc.c", poolEntry->second.path.c_str(), + GetExternalExtension().c_str()); } } + size_t texSizeDivisor = (dWordAligned) ? 8 : 4; - Declaration* decl = parent->AddDeclarationIncludeArray( - rawDataIndex, incStr, GetRawDataSize(), GetSourceTypeName(), auxName, GetRawDataSize() / 8); + Declaration* decl = parent->AddDeclarationIncludeArray(rawDataIndex, incStr, GetRawDataSize(), + GetSourceTypeName(), auxName, + GetRawDataSize() / texSizeDivisor); decl->staticConf = staticConf; return decl; } @@ -779,15 +792,17 @@ Declaration* ZTexture::DeclareVar(const std::string& prefix, std::string ZTexture::GetBodySourceCode() const { std::string sourceOutput; - - for (size_t i = 0; i < textureDataRaw.size(); i += 8) + size_t texSizeInc = (dWordAligned) ? 8 : 4; + for (size_t i = 0; i < textureDataRaw.size(); i += texSizeInc) { if (i % 32 == 0) sourceOutput += " "; - - sourceOutput += - StringHelper::Sprintf("0x%016llX, ", BitConverter::ToUInt64BE(textureDataRaw, i)); - + if (dWordAligned) + sourceOutput += + StringHelper::Sprintf("0x%016llX, ", BitConverter::ToUInt64BE(textureDataRaw, i)); + else + sourceOutput += + StringHelper::Sprintf("0x%08llX, ", BitConverter::ToUInt32BE(textureDataRaw, i)); if (i % 32 == 24) sourceOutput += StringHelper::Sprintf(" // 0x%06X \n", rawDataIndex + ((i / 32) * 32)); } @@ -812,7 +827,7 @@ ZResourceType ZTexture::GetResourceType() const std::string ZTexture::GetSourceTypeName() const { - return "u64"; + return dWordAligned ? "u64" : "u32"; } void ZTexture::CalcHash() diff --git a/tools/ZAPD/ZAPD/ZTexture.h b/tools/ZAPD/ZAPD/ZTexture.h index ef67c3f6e..29c3fbc0a 100644 --- a/tools/ZAPD/ZAPD/ZTexture.h +++ b/tools/ZAPD/ZAPD/ZTexture.h @@ -54,6 +54,7 @@ public: ZTexture(ZFile* nParent); bool isPalette = false; + bool dWordAligned = true; void ExtractFromBinary(uint32_t nRawDataIndex, int32_t nWidth, int32_t nHeight, TextureType nType, bool nIsPalette); diff --git a/tools/ZAPD/docs/zapd_extraction_xml_reference.md b/tools/ZAPD/docs/zapd_extraction_xml_reference.md index 06b95bb57..b3f5575c1 100644 --- a/tools/ZAPD/docs/zapd_extraction_xml_reference.md +++ b/tools/ZAPD/docs/zapd_extraction_xml_reference.md @@ -9,6 +9,7 @@ This document aims to be a small reference of how to create a compatible xml fil - [Basic XML](#basic-xml) - [Resources types](#resources-types) - [File](#file) + - [ExternalFile](#externalfile) - [Texture](#texture) - [Background](#background) - [Blob](#blob) @@ -33,6 +34,7 @@ This document aims to be a small reference of how to create a compatible xml fil - [Array](#array) - [Path](#path) - [PlayerAnimationData](#playeranimationdata) + - [Pointer](#pointer) ## Basic XML @@ -589,7 +591,7 @@ Vec3s D_04002040[24] = { The `Array` element is special, because it needs an inner element to work. It will declare an array of its inner element. -Currently, only [`Scalar`](#scalar), [`Vector`](#vector) and [`Vtx`](#vtx) support being wrapped in an array. +Currently, only [`Pointer`](#pointer), [`Scalar`](#scalar), [`Vector`](#vector) and [`Vtx`](#vtx) support being wrapped in an array. - Example: @@ -637,3 +639,24 @@ Allows the extraction of the specific data of the player animations which are fo - `FrameCount`: Required. The length of the animation in frames. It must be a positive integer. ------------------------- + +### Pointer + +Allows the extraction of a variable that contains a pointer + +- Example: + +```xml + + + +``` + +- Attributes: + + - `Name`: Required. + - `Type`: Required. The type of the extracted pointer. + +※ Can be wrapped in an [`Array`](#array) tag. + +------------------------- diff --git a/tools/asm-differ/.gitrepo b/tools/asm-differ/.gitrepo index 241c0ad6b..48e215c08 100644 --- a/tools/asm-differ/.gitrepo +++ b/tools/asm-differ/.gitrepo @@ -4,9 +4,9 @@ ; git-subrepo command. See https://github.com/git-commands/git-subrepo#readme ; [subrepo] - remote = https://github.com/simonlindholm/asm-differ.git + remote = https://github.com/simonlindholm/asm-differ branch = main - commit = 70c33cc125666495f84f8c7bee60d3158b4b1164 - parent = 62341d8db0c29d1d4f0c360196e428309ac373b6 + commit = 6f8f80b719359d018a2b734288c977aae6538870 + parent = 91a6e9f647d2035eba281d286c78f089f70f269f method = merge cmdver = 0.4.3 diff --git a/tools/asm-differ/diff.py b/tools/asm-differ/diff.py index 2ec117a12..9781420bb 100755 --- a/tools/asm-differ/diff.py +++ b/tools/asm-differ/diff.py @@ -1198,6 +1198,9 @@ def parse_elf_data_references(data: bytes) -> List[Tuple[int, int, str]]: # Skip .text -> .text references continue sec_name = sec_names[s.sh_info].decode("latin1") + if sec_name == ".mwcats.text": + # Skip Metrowerks CATS Utility section + continue sec_base = sections[s.sh_info].sh_offset for i in range(0, s.sh_size, s.sh_entsize): if s.sh_type == SHT_REL: @@ -1330,11 +1333,6 @@ def dump_binary( (objdump_flags + flags2, project.myimg, None), ) -DATA_POOL_PLACEHOLDER = "DATA_POOL_PLACEHOLDER-OFFSET_{}" -DATA_POOL_PLACEHOLDER_PATTERN = re.compile( - r"DATA_POOL_PLACEHOLDER-OFFSET_([a-zA-z0-9]+)" -) - # Example: "ldr r4, [pc, #56] ; (4c )" ARM32_LOAD_POOL_PATTERN = r"(ldr\s+r([0-9]|1[0-3]),\s+\[pc,.*;\s*)(\([a-fA-F0-9]+.*\))" @@ -1357,7 +1355,7 @@ class AsmProcessor: def _normalize_arch_specific(self, mnemonic: str, row: str) -> str: return row - + def post_process(self, lines: List["Line"]) -> None: return @@ -1460,37 +1458,21 @@ class AsmProcessorARM32(AsmProcessor): def _normalize_data_pool(self, row: str) -> str: pool_match = re.search(ARM32_LOAD_POOL_PATTERN, row) - if pool_match: - offset = pool_match.group(3).split(" ")[0][1:] - repl = DATA_POOL_PLACEHOLDER.format(offset) - return pool_match.group(1) + repl - return row + return pool_match.group(1) if pool_match else row def post_process(self, lines: List["Line"]) -> None: lines_by_line_number = {} for line in lines: lines_by_line_number[line.line_num] = line for line in lines: - reloc_match = re.search( - DATA_POOL_PLACEHOLDER_PATTERN, line.normalized_original - ) - if reloc_match is None: + if line.data_pool_addr is None: continue - # Get value at relocation - reloc = reloc_match.group(0) - line_number = re.search( - DATA_POOL_PLACEHOLDER_PATTERN, reloc).group(1) - line_original = lines_by_line_number[int(line_number, 16)].original + # Add data symbol and its address to the line. + line_original = lines_by_line_number[line.data_pool_addr].original value = line_original.split()[1] - - # Replace relocation placeholder with value - replaced = re.sub( - DATA_POOL_PLACEHOLDER_PATTERN, - f"={value} ({line_number})", - line.normalized_original, - ) - line.original = replaced + addr = "{:x}".format(line.data_pool_addr) + line.original = line.normalized_original + f"={value} ({addr})" class AsmProcessorAArch64(AsmProcessor): @@ -1795,6 +1777,7 @@ class Line: scorable_line: str line_num: Optional[int] = None branch_target: Optional[int] = None + data_pool_addr: Optional[int] = None source_filename: Optional[str] = None source_line_num: Optional[int] = None source_lines: List[str] = field(default_factory=list) @@ -1856,6 +1839,14 @@ def process(dump: str, config: Config) -> List[Line]: source_lines.append(row) continue + # If the instructions loads a data pool symbol, extract the address of + # the symbol. + data_pool_addr = None + pool_match = re.search(ARM32_LOAD_POOL_PATTERN, row) + if pool_match: + offset = pool_match.group(3).split(" ")[0][1:] + data_pool_addr = int(offset, 16) + m_comment = re.search(arch.re_comment, row) comment = m_comment[0] if m_comment else None row = re.sub(arch.re_comment, "", row) @@ -1946,6 +1937,7 @@ def process(dump: str, config: Config) -> List[Line]: scorable_line=scorable_line, line_num=line_num, branch_target=branch_target, + data_pool_addr=data_pool_addr, source_filename=source_filename, source_line_num=source_line_num, source_lines=source_lines, From a9c2449c11ef3f0c4089c0741923790f83927c8f Mon Sep 17 00:00:00 2001 From: Tom Overton Date: Sun, 16 Jan 2022 10:36:19 -0800 Subject: [PATCH 11/13] Bring merged assets up to current standards (#570) * Bring merged assets up to current standards * Clarify bigslime --- assets/xml/objects/object_bigpo.xml | 1 + assets/xml/objects/object_bigslime.xml | 1 + assets/xml/objects/object_gmo.xml | 3 ++- assets/xml/objects/object_mag.xml | 1 + assets/xml/objects/object_tokei_step.xml | 1 + 5 files changed, 6 insertions(+), 1 deletion(-) diff --git a/assets/xml/objects/object_bigpo.xml b/assets/xml/objects/object_bigpo.xml index c41d5ff79..531a151c6 100644 --- a/assets/xml/objects/object_bigpo.xml +++ b/assets/xml/objects/object_bigpo.xml @@ -1,4 +1,5 @@  + diff --git a/assets/xml/objects/object_bigslime.xml b/assets/xml/objects/object_bigslime.xml index 18b702506..5b7530add 100644 --- a/assets/xml/objects/object_bigslime.xml +++ b/assets/xml/objects/object_bigslime.xml @@ -1,4 +1,5 @@  + diff --git a/assets/xml/objects/object_gmo.xml b/assets/xml/objects/object_gmo.xml index 4884d7919..266c70383 100644 --- a/assets/xml/objects/object_gmo.xml +++ b/assets/xml/objects/object_gmo.xml @@ -1,9 +1,10 @@  + - + diff --git a/assets/xml/objects/object_mag.xml b/assets/xml/objects/object_mag.xml index 6ec4426d8..29d30daad 100644 --- a/assets/xml/objects/object_mag.xml +++ b/assets/xml/objects/object_mag.xml @@ -1,4 +1,5 @@  + diff --git a/assets/xml/objects/object_tokei_step.xml b/assets/xml/objects/object_tokei_step.xml index ecdf14ac3..aac4b5ea9 100644 --- a/assets/xml/objects/object_tokei_step.xml +++ b/assets/xml/objects/object_tokei_step.xml @@ -1,4 +1,5 @@  + From aa90d1ee2be577fb8a18c1c3c6dcafda2e732190 Mon Sep 17 00:00:00 2001 From: Derek Hensley Date: Sun, 16 Jan 2022 12:14:34 -0800 Subject: [PATCH 12/13] SubS Skelanime functions (#572) * Bring code over * Change ActorDraw typedefs from actor to thisx * Rename functions * Format * Rename and clean up limb draws * Some more limb draw cleanup * Some more cleanup * Function comments * Last bit of cleanup * update tutorial * More tutorial and format * Remove extra newlines form actorfixer * Missed one * Remove some unnecessary casts * Fix SkelAnime transform functions in functions.h * Remove bug comments, and add note * Remove some more unneeded casts and rename one variable * format * Fix merge * Format --- docs/tutorial/documenting.md | 4 +- docs/tutorial/draw_functions.md | 24 ++-- include/functions.h | 8 +- include/z64actor.h | 1 - include/z64animation.h | 16 +-- src/code/z_skelanime.c | 70 ++++++----- src/code/z_sub_s.c | 114 +++++++++++++++++- src/overlays/actors/ovl_Dm_Nb/z_dm_nb.c | 6 +- src/overlays/actors/ovl_Dm_Sa/z_dm_sa.c | 13 +- .../ovl_En_Akindonuts/z_en_akindonuts.c | 9 +- .../actors/ovl_En_Aob_01/z_en_aob_01.c | 9 +- src/overlays/actors/ovl_En_Bigpo/z_en_bigpo.c | 10 +- .../actors/ovl_En_Bji_01/z_en_bji_01.c | 7 +- src/overlays/actors/ovl_En_Dai/z_en_dai.c | 30 ++--- src/overlays/actors/ovl_En_Daiku/z_en_daiku.c | 9 +- .../actors/ovl_En_Dekunuts/z_en_dekunuts.c | 11 +- src/overlays/actors/ovl_En_Dg/z_en_dg.c | 8 +- src/overlays/actors/ovl_En_Dnp/z_en_dnp.c | 9 +- .../ovl_En_Ending_Hero/z_en_ending_hero.c | 2 +- .../ovl_En_Ending_Hero2/z_en_ending_hero2.c | 2 +- .../ovl_En_Ending_Hero3/z_en_ending_hero3.c | 2 +- .../ovl_En_Ending_Hero4/z_en_ending_hero4.c | 2 +- .../ovl_En_Ending_Hero5/z_en_ending_hero5.c | 4 +- src/overlays/actors/ovl_En_Fg/z_en_fg.c | 10 +- .../actors/ovl_En_Fishing/z_en_fishing.c | 2 +- src/overlays/actors/ovl_En_Fsn/z_en_fsn.c | 4 +- src/overlays/actors/ovl_En_Geg/z_en_geg.c | 7 +- .../actors/ovl_En_Ginko_Man/z_en_ginko_man.c | 8 +- src/overlays/actors/ovl_En_Gm/z_en_gm.c | 11 +- src/overlays/actors/ovl_En_Go/z_en_go.c | 9 +- src/overlays/actors/ovl_En_Hg/z_en_hg.c | 6 +- src/overlays/actors/ovl_En_Ig/z_en_ig.c | 10 +- src/overlays/actors/ovl_En_In/z_en_in.c | 10 +- .../actors/ovl_En_Kakasi/z_en_kakasi.c | 9 +- .../actors/ovl_En_Ma_Yts/z_en_ma_yts.c | 11 +- .../actors/ovl_En_Minifrog/z_en_minifrog.c | 8 +- src/overlays/actors/ovl_En_Niw/z_en_niw.c | 6 +- .../actors/ovl_En_Pamera/z_en_pamera.c | 2 +- .../actors/ovl_En_Pametfrog/z_en_pametfrog.c | 4 +- src/overlays/actors/ovl_En_Pm/z_en_pm.c | 14 +-- .../actors/ovl_En_Po_Fusen/z_en_po_fusen.c | 17 +-- .../actors/ovl_En_Recepgirl/z_en_recepgirl.c | 7 +- src/overlays/actors/ovl_En_Rsn/z_en_rsn.c | 10 +- .../actors/ovl_En_Sellnuts/z_en_sellnuts.c | 7 +- .../actors/ovl_En_Suttari/z_en_suttari.c | 7 +- src/overlays/actors/ovl_En_Tk/z_en_tk.c | 6 +- src/overlays/actors/ovl_En_Trt/z_en_trt.c | 9 +- src/overlays/actors/ovl_En_Tru/z_en_tru.c | 7 +- src/overlays/actors/ovl_En_Wf/z_en_wf.c | 6 +- src/overlays/actors/ovl_En_Zog/z_en_zog.c | 4 +- tools/actorfixer.py | 11 +- tools/disasm/functions.txt | 82 ++++++------- tools/sizes/code_functions.csv | 8 +- 53 files changed, 411 insertions(+), 271 deletions(-) diff --git a/docs/tutorial/documenting.md b/docs/tutorial/documenting.md index de82b54f9..bdfe49dc2 100644 --- a/docs/tutorial/documenting.md +++ b/docs/tutorial/documenting.md @@ -262,7 +262,7 @@ void EnRecepgirl_Draw(Actor *thisx, GlobalContext *globalCtx) { gSPSegment(POLY_OPA_DISP++, 0x08, D_80C106B0[this->unk_2AC]); - func_801343C0(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, func_80C10558, NULL, func_80C10590, &this->actor); + SkelAnime_DrawTransformFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, func_80C10558, NULL, func_80C10590, &this->actor); CLOSE_DISPS(globalCtx->state.gfxCtx); } @@ -273,7 +273,7 @@ void EnRecepgirl_Draw(Actor *thisx, GlobalContext *globalCtx) { (We can delete the `GLOBAL_ASM` lines now.) -The worst part of documentation is finding somewhere to start. We have a decent place to start here, though, in that we already know the function (or rather, the use) of a couple of the functions, namely the LimbDraws. So we can rename `func_80C10558` to `EnRecepgirl_OverrideLimbDraw` and `func_80C10590` to `EnRecepgirl_UnkLimbDraw`. Remember to do a global rename so that the functions in the assembly are renamed, use `rename_global_asm`, +The worst part of documentation is finding somewhere to start. We have a decent place to start here, though, in that we already know the function (or rather, the use) of a couple of the functions, namely the LimbDraws. So we can rename `func_80C10558` to `EnRecepgirl_OverrideLimbDraw` and `func_80C10590` to `EnRecepgirl_TransformLimbDraw`. Remember to do a global rename so that the functions in the assembly are renamed, use `rename_global_asm`, ``` $ ./tools/rename_global_asm.py asm/non_matchings/overlays/ovl_En_Recepgirl/func_80C10558.s --> asm/non_matchings/overlays/ovl_En_Recepgirl/EnRecepgirl_OverrideLimbDraw.s diff --git a/docs/tutorial/draw_functions.md b/docs/tutorial/draw_functions.md index 319d5efbb..5f9aa551d 100644 --- a/docs/tutorial/draw_functions.md +++ b/docs/tutorial/draw_functions.md @@ -34,7 +34,7 @@ void EnRecepgirl_Draw(Actor *thisx, GlobalContext *globalCtx) { sp30->polyOpa.p = temp_v1 + 8; temp_v1->words.w0 = 0xDB060020; temp_v1->words.w1 = (u32) D_80C106B0[this->unk_2AC]; - func_801343C0(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, (s32) this->skelAnime.dListCount, func_80C10558, NULL, func_80C10590, (Actor *) this); + SkelAnime_DrawTransformFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, (s32) this->skelAnime.dListCount, func_80C10558, NULL, func_80C10590, (Actor *) this); } ``` @@ -107,7 +107,7 @@ void EnRecepgirl_Draw(Actor *thisx, GlobalContext *globalCtx) { gSPSegment(POLY_OPA_DISP++, 0x08, D_80C106B0[this->unk_2AC]); - func_801343C0(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, func_80C10558, NULL, func_80C10590, &this->actor); + SkelAnime_DrawTransformFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, func_80C10558, NULL, func_80C10590, &this->actor); CLOSE_DISPS(globalCtx->state.gfxCtx); } @@ -115,28 +115,28 @@ void EnRecepgirl_Draw(Actor *thisx, GlobalContext *globalCtx) { And this matches. -The last two functions in the actor are used as arguments in `func_801343C0`. This is a `SkelAnime` function, except unlike the OoT ones, it has three function callback arguments instead of two: in `functions.h` or `z_skelanime.c`, we find +The last two functions in the actor are used as arguments in `SkelAnime_DrawTransformFlexOpa`. This is a `SkelAnime` function, except unlike the OoT ones, it has three function callback arguments instead of two: in `functions.h` or `z_skelanime.c`, we find ```C -void func_801343C0(GlobalContext* globalCtx, void** skeleton, Vec3s* jointTable, s32 dListCount, - OverrideLimbDraw overrideLimbDraw, PostLimbDraw postLimbDraw, UnkActorDraw unkDraw, Actor* actor) +void SkelAnime_DrawTransformFlexOpa(GlobalContext* globalCtx, void** skeleton, Vec3s* jointTable, s32 dListCount, + OverrideLimbDrawOpa overrideLimbDraw, PostLimbDrawOpa postLimbDraw, TransformLimbDrawOpa transformLimbDraw, Actor* actor) ``` The typedefs of the callbacks it uses are in `z64animation.h`: ```C -typedef s32 (*OverrideLimbDraw)(struct GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, - struct Actor* actor); +typedef s32 (*OverrideLimbDrawOpa)(struct GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, + struct Actor* thisx); -typedef void (*PostLimbDraw)(struct GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, - struct Actor* actor); +typedef void (*PostLimbDrawOpa)(struct GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, + struct Actor* thisx); [...] -typedef void (*UnkActorDraw)(struct GlobalContext* globalCtx, s32 limbIndex, struct Actor* actor); +typedef void (*TransformLimbDrawOpa)(struct GlobalContext* globalCtx, s32 limbIndex, struct Actor* thisx); ``` which is where mips2c got them from. In this case, only two of them are used, and it is these that are the last functions standing between us and a decompiled actor. -## OverrideLimbDraw, PostLimbDraw, UnkActorDraw +## OverrideLimbDraw, PostLimbDraw, TransformLimbDraw Well, we don't have a PostLimbDraw here, but as we see from the prototype, it's much the same as the OverrideLimbDraw but without the `pos` argument and no return value. ```C @@ -159,7 +159,7 @@ s32 func_80C10558(GlobalContext *globalCtx, s32 limbIndex, Gfx **dList, Vec3f *p } ``` -As for the UnkActorDraw, it has a much simpler prototype. mips2c gives +As for the TransformLimbDraw, it has a much simpler prototype. mips2c gives ```C void func_80C10590(GlobalContext *globalCtx, s32 limbIndex, Actor *actor) { if (limbIndex == 5) { diff --git a/include/functions.h b/include/functions.h index 2d94268ba..ec85d2d56 100644 --- a/include/functions.h +++ b/include/functions.h @@ -2375,8 +2375,8 @@ void SkelAnime_DrawLimbOpa(GlobalContext* globalCtx, s32 limbIndex, void** skele void SkelAnime_DrawOpa(GlobalContext* globalCtx, void** skeleton, Vec3s* jointTable, OverrideLimbDrawOpa overrideLimbDraw, PostLimbDrawOpa postLimbDraw, Actor* actor); void SkelAnime_DrawFlexLimbOpa(GlobalContext* globalCtx, s32 limbIndex, void** skeleton, Vec3s* jointTable, OverrideLimbDrawOpa overrideLimbDraw, PostLimbDrawOpa postLimbDraw, Actor* actor, Mtx** limbMatricies); void SkelAnime_DrawFlexOpa(GlobalContext* globalCtx, void** skeleton, Vec3s* jointTable, s32 dListCount, OverrideLimbDrawOpa overrideLimbDraw, PostLimbDrawOpa postLimbDraw, Actor* actor); -void func_80134148(GlobalContext* globalCtx, s32 limbIndex, void** skeleton, Vec3s* jointTable, OverrideLimbDrawOpa overrideLimbDraw, PostLimbDrawOpa postLimbDraw, UnkActorDrawOpa unkDraw, Actor* actor, Mtx** mtx); -void func_801343C0(GlobalContext* globalCtx, void** skeleton, Vec3s* jointTable, s32 dListCount, OverrideLimbDrawOpa overrideLimbDraw, PostLimbDrawOpa postLimbDraw, UnkActorDrawOpa unkDraw, Actor* actor); +void SkelAnime_DrawTransformFlexLimbOpa(GlobalContext* globalCtx, s32 limbIndex, void** skeleton, Vec3s* jointTable, OverrideLimbDrawOpa overrideLimbDraw, PostLimbDrawOpa postLimbDraw, TransformLimbDrawOpa transformLimbDraw, Actor* actor, Mtx** mtx); +void SkelAnime_DrawTransformFlexOpa(GlobalContext* globalCtx, void** skeleton, Vec3s* jointTable, s32 dListCount, OverrideLimbDrawOpa overrideLimbDraw, PostLimbDrawOpa postLimbDraw, TransformLimbDrawOpa transformLimbDraw, Actor* actor); void SkelAnime_GetFrameData(AnimationHeader* animationSeg, s32 currentFrame, s32 limbCount, Vec3s* dst); s16 Animation_GetLength(void* animation); s16 Animation_GetLastFrame(void* animation); @@ -2504,8 +2504,8 @@ u32 func_8013A4C4(s32 flag); s16 func_8013A504(s16 val); s32 func_8013A530(GlobalContext* globalCtx, Actor* actor, s32 flag, Vec3f* pos, Vec3s* rot, f32 distanceMin, f32 distanceMax, s16 angleError); struct EnDoor* SubS_FindDoor(GlobalContext* globalCtx, s32 unk_1A5); -Gfx* func_8013A860(GlobalContext* globalCtx, s32 idx, void** skeleton, Vec3s* jointTable, OverrideLimbDraw overrideLimbDraw, PostLimbDraw postLimbDraw, UnkActorDraw unkActorDraw, Actor* actor, Mtx** mtx, Gfx* gfx); -Gfx* func_8013AB00(GlobalContext* globalCtx, void** skeleton, Vec3s* jointTable, s32 dListCount, OverrideLimbDraw overrideLimbDraw, PostLimbDraw postLimbDraw, UnkActorDraw unkActorDraw, Actor* actor, Gfx* gfx); +Gfx* SubS_DrawTransformFlexLimb(GlobalContext* globalCtx, s32 idx, void** skeleton, Vec3s* jointTable, OverrideLimbDraw overrideLimbDraw, PostLimbDraw postLimbDraw, TransformLimbDraw transformLimbDraw, Actor* actor, Mtx** mtx, Gfx* gfx); +Gfx* SubS_DrawTransformFlex(GlobalContext* globalCtx, void** skeleton, Vec3s* jointTable, s32 dListCount, OverrideLimbDraw overrideLimbDraw, PostLimbDraw postLimbDraw, TransformLimbDraw transformLimbDraw, Actor* actor, Gfx* gfx); s32 func_8013AD6C(GlobalContext* globalCtx); s32 func_8013AD9C(s16 arg0, s16 arg1, Vec3f* arg2, Vec3s* arg3, s32 arg4, s32 arg5); void func_8013AED4(u16* arg0, u16 arg1, u16 arg2); diff --git a/include/z64actor.h b/include/z64actor.h index 3ed9e2a33..5fa771e49 100644 --- a/include/z64actor.h +++ b/include/z64actor.h @@ -18,7 +18,6 @@ struct Lights; struct CollisionPoly; struct EnBox; -struct EnDoor; typedef void(*ActorFunc)(struct Actor* this, struct GlobalContext* globalCtx); diff --git a/include/z64animation.h b/include/z64animation.h index 8d6df14c8..2aa97e2ec 100644 --- a/include/z64animation.h +++ b/include/z64animation.h @@ -204,26 +204,26 @@ typedef struct SkelAnime { } SkelAnime; // size = 0x44 typedef s32 (*OverrideLimbDrawOpa)(struct GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, - struct Actor* actor); + struct Actor* thisx); typedef void (*PostLimbDrawOpa)(struct GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, - struct Actor* actor); + struct Actor* thisx); typedef s32 (*OverrideLimbDraw)(struct GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, - struct Actor* actor, Gfx** gfx); + struct Actor* thisx, Gfx** gfx); typedef void (*PostLimbDraw)(struct GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, - struct Actor* actor, Gfx** gfx); + struct Actor* thisx, Gfx** gfx); typedef s32 (*OverrideLimbDrawFlex)(struct GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, - struct Actor* actor); + struct Actor* thisx); typedef void (*PostLimbDrawFlex)(struct GlobalContext* globalCtx, s32 limbIndex, Gfx** dList1, Gfx** dList2, Vec3s* rot, - struct Actor* actor); + struct Actor* thisx); -typedef void (*UnkActorDrawOpa)(struct GlobalContext* globalCtx, s32 limbIndex, struct Actor* actor); +typedef void (*TransformLimbDrawOpa)(struct GlobalContext* globalCtx, s32 limbIndex, struct Actor* thisx); -typedef void (*UnkActorDraw)(struct GlobalContext* globalCtx, s32 limbIndex, struct Actor* actor, Gfx** gfx); +typedef void (*TransformLimbDraw)(struct GlobalContext* globalCtx, s32 limbIndex, struct Actor* thisx, Gfx** gfx); typedef void (*AnimationEntryCallback)(struct GlobalContext*, AnimationEntryData*); diff --git a/src/code/z_skelanime.c b/src/code/z_skelanime.c index 7f79bb51c..8ebb2ca67 100644 --- a/src/code/z_skelanime.c +++ b/src/code/z_skelanime.c @@ -35,7 +35,7 @@ void SkelAnime_DrawLimbLod(GlobalContext* globalCtx, s32 limbIndex, void** skele OPEN_DISPS(globalCtx->state.gfxCtx); Matrix_StatePush(); - limb = (LodLimb*)Lib_SegmentedToVirtual(skeleton[limbIndex]); + limb = Lib_SegmentedToVirtual(skeleton[limbIndex]); limbIndex++; rot = jointTable[limbIndex]; @@ -94,7 +94,7 @@ void SkelAnime_DrawLod(GlobalContext* globalCtx, void** skeleton, Vec3s* jointTa Matrix_StatePush(); - rootLimb = (LodLimb*)Lib_SegmentedToVirtual(skeleton[0]); + rootLimb = Lib_SegmentedToVirtual(skeleton[0]); pos.x = jointTable[0].x; pos.y = jointTable[0].y; pos.z = jointTable[0].z; @@ -146,7 +146,7 @@ void SkelAnime_DrawFlexLimbLod(GlobalContext* globalCtx, s32 limbIndex, void** s Matrix_StatePush(); - limb = (LodLimb*)Lib_SegmentedToVirtual(skeleton[limbIndex]); + limb = Lib_SegmentedToVirtual(skeleton[limbIndex]); limbIndex++; rot = jointTable[limbIndex]; @@ -203,7 +203,7 @@ void SkelAnime_DrawFlexLod(GlobalContext* globalCtx, void** skeleton, Vec3s* joi Gfx* limbDList; Vec3f pos; Vec3s rot; - Mtx* mtx = (Mtx*)GRAPH_ALLOC(globalCtx->state.gfxCtx, ALIGN16(sizeof(Mtx) * dListCount)); + Mtx* mtx = GRAPH_ALLOC(globalCtx->state.gfxCtx, ALIGN16(sizeof(Mtx) * dListCount)); if (skeleton == NULL) { return; @@ -214,7 +214,7 @@ void SkelAnime_DrawFlexLod(GlobalContext* globalCtx, void** skeleton, Vec3s* joi gSPSegment(POLY_OPA_DISP++, 0x0D, mtx); Matrix_StatePush(); - rootLimb = (LodLimb*)Lib_SegmentedToVirtual(skeleton[0]); + rootLimb = Lib_SegmentedToVirtual(skeleton[0]); pos.x = jointTable[0].x; pos.y = jointTable[0].y; pos.z = jointTable[0].z; @@ -266,7 +266,7 @@ void SkelAnime_DrawLimbOpa(GlobalContext* globalCtx, s32 limbIndex, void** skele Matrix_StatePush(); - limb = (StandardLimb*)Lib_SegmentedToVirtual(skeleton[limbIndex]); + limb = Lib_SegmentedToVirtual(skeleton[limbIndex]); limbIndex++; rot = jointTable[limbIndex]; pos.x = limb->jointPos.x; @@ -421,7 +421,7 @@ void SkelAnime_DrawFlexOpa(GlobalContext* globalCtx, void** skeleton, Vec3s* joi Gfx* limbDList; Vec3f pos; Vec3s rot; - Mtx* mtx = (Mtx*)GRAPH_ALLOC(globalCtx->state.gfxCtx, ALIGN16(sizeof(Mtx) * dListCount)); + Mtx* mtx = GRAPH_ALLOC(globalCtx->state.gfxCtx, ALIGN16(sizeof(Mtx) * dListCount)); if (skeleton == NULL) { return; @@ -473,9 +473,9 @@ void SkelAnime_DrawFlexOpa(GlobalContext* globalCtx, void** skeleton, Vec3s* joi CLOSE_DISPS(globalCtx->state.gfxCtx); } -void func_80134148(GlobalContext* globalCtx, s32 limbIndex, void** skeleton, Vec3s* jointTable, - OverrideLimbDrawOpa overrideLimbDraw, PostLimbDrawOpa postLimbDraw, UnkActorDrawOpa unkDraw, - Actor* actor, Mtx** mtx) { +void SkelAnime_DrawTransformFlexLimbOpa(GlobalContext* globalCtx, s32 limbIndex, void** skeleton, Vec3s* jointTable, + OverrideLimbDrawOpa overrideLimbDraw, PostLimbDrawOpa postLimbDraw, + TransformLimbDrawOpa transformLimbDraw, Actor* actor, Mtx** mtx) { StandardLimb* limb; Gfx* newDList; Gfx* limbDList; @@ -486,7 +486,7 @@ void func_80134148(GlobalContext* globalCtx, s32 limbIndex, void** skeleton, Vec Matrix_StatePush(); - limb = (StandardLimb*)Lib_SegmentedToVirtual(skeleton[limbIndex]); + limb = Lib_SegmentedToVirtual(skeleton[limbIndex]); limbIndex++; rot = jointTable[limbIndex]; @@ -500,8 +500,8 @@ void func_80134148(GlobalContext* globalCtx, s32 limbIndex, void** skeleton, Vec Matrix_JointPosition(&pos, &rot); Matrix_StatePush(); - //! @bug Does not check unkDraw is not NULL before calling it. - unkDraw(globalCtx, limbIndex, actor); + transformLimbDraw(globalCtx, limbIndex, actor); + if (newDList != NULL) { Gfx* polyTemp = POLY_OPA_DISP; @@ -523,23 +523,32 @@ void func_80134148(GlobalContext* globalCtx, s32 limbIndex, void** skeleton, Vec } if (limb->child != LIMB_DONE) { - func_80134148(globalCtx, limb->child, skeleton, jointTable, overrideLimbDraw, postLimbDraw, unkDraw, actor, - mtx); + SkelAnime_DrawTransformFlexLimbOpa(globalCtx, limb->child, skeleton, jointTable, overrideLimbDraw, postLimbDraw, + transformLimbDraw, actor, mtx); } Matrix_StatePop(); if (limb->sibling != LIMB_DONE) { - func_80134148(globalCtx, limb->sibling, skeleton, jointTable, overrideLimbDraw, postLimbDraw, unkDraw, actor, - mtx); + SkelAnime_DrawTransformFlexLimbOpa(globalCtx, limb->sibling, skeleton, jointTable, overrideLimbDraw, + postLimbDraw, transformLimbDraw, actor, mtx); } CLOSE_DISPS(globalCtx->state.gfxCtx); } -void func_801343C0(GlobalContext* globalCtx, void** skeleton, Vec3s* jointTable, s32 dListCount, - OverrideLimbDrawOpa overrideLimbDraw, PostLimbDrawOpa postLimbDraw, UnkActorDrawOpa unkDraw, - Actor* actor) { +/** + * Draw all limbs of type `StandardLimb` in a given flexible skeleton to the polyOpa buffer + * Limbs in a flexible skeleton have meshes that can stretch to line up with other limbs. + * An array of matrices is dynamically allocated so each limb can access any transform to ensure its meshes line up. + * + * Also makes use of a `TransformLimbDraw`, which transforms limbs based on world coordinates, as opposed to local limb + * coordinates. + * Note that the `TransformLimbDraw` does not have a NULL check, so must be provided even if empty. + */ +void SkelAnime_DrawTransformFlexOpa(GlobalContext* globalCtx, void** skeleton, Vec3s* jointTable, s32 dListCount, + OverrideLimbDrawOpa overrideLimbDraw, PostLimbDrawOpa postLimbDraw, + TransformLimbDrawOpa transformLimbDraw, Actor* actor) { StandardLimb* rootLimb; s32 pad; Gfx* newDList; @@ -554,13 +563,13 @@ void func_801343C0(GlobalContext* globalCtx, void** skeleton, Vec3s* jointTable, OPEN_DISPS(globalCtx->state.gfxCtx); - mtx = (Mtx*)GRAPH_ALLOC(globalCtx->state.gfxCtx, ALIGN16(sizeof(Mtx) * dListCount)); + mtx = GRAPH_ALLOC(globalCtx->state.gfxCtx, ALIGN16(sizeof(Mtx) * dListCount)); gSPSegment(POLY_OPA_DISP++, 0x0D, mtx); Matrix_StatePush(); - rootLimb = (StandardLimb*)Lib_SegmentedToVirtual(skeleton[0]); + rootLimb = Lib_SegmentedToVirtual(skeleton[0]); pos.x = jointTable[0].x; pos.y = jointTable[0].y; @@ -573,8 +582,7 @@ void func_801343C0(GlobalContext* globalCtx, void** skeleton, Vec3s* jointTable, Matrix_JointPosition(&pos, &rot); Matrix_StatePush(); - //! @bug Does not check unkDraw is not NULL before calling it. - unkDraw(globalCtx, 1, actor); + transformLimbDraw(globalCtx, 1, actor); if (newDList != NULL) { Gfx* polyTemp = POLY_OPA_DISP; @@ -596,8 +604,8 @@ void func_801343C0(GlobalContext* globalCtx, void** skeleton, Vec3s* jointTable, } if (rootLimb->child != LIMB_DONE) { - func_80134148(globalCtx, rootLimb->child, skeleton, jointTable, overrideLimbDraw, postLimbDraw, unkDraw, actor, - &mtx); + SkelAnime_DrawTransformFlexLimbOpa(globalCtx, rootLimb->child, skeleton, jointTable, overrideLimbDraw, + postLimbDraw, transformLimbDraw, actor, &mtx); } Matrix_StatePop(); @@ -655,7 +663,7 @@ Gfx* SkelAnime_DrawLimb(GlobalContext* globalCtx, s32 limbIndex, void** skeleton Matrix_StatePush(); - limb = (StandardLimb*)Lib_SegmentedToVirtual(skeleton[limbIndex]); + limb = Lib_SegmentedToVirtual(skeleton[limbIndex]); limbIndex++; rot = jointTable[limbIndex]; @@ -711,7 +719,7 @@ Gfx* SkelAnime_Draw(GlobalContext* globalCtx, void** skeleton, Vec3s* jointTable Matrix_StatePush(); - rootLimb = (StandardLimb*)Lib_SegmentedToVirtual(skeleton[0]); + rootLimb = Lib_SegmentedToVirtual(skeleton[0]); pos.x = jointTable[0].x; pos.y = jointTable[0].y; @@ -758,7 +766,7 @@ Gfx* SkelAnime_DrawFlexLimb(GlobalContext* globalCtx, s32 limbIndex, void** skel Matrix_StatePush(); - limb = (StandardLimb*)Lib_SegmentedToVirtual(skeleton[limbIndex]); + limb = Lib_SegmentedToVirtual(skeleton[limbIndex]); limbIndex++; rot = jointTable[limbIndex]; @@ -821,7 +829,7 @@ Gfx* SkelAnime_DrawFlex(GlobalContext* globalCtx, void** skeleton, Vec3s* jointT return NULL; } - mtx = (Mtx*)GRAPH_ALLOC(globalCtx->state.gfxCtx, ALIGN16(sizeof(Mtx) * dListCount)); + mtx = GRAPH_ALLOC(globalCtx->state.gfxCtx, ALIGN16(sizeof(Mtx) * dListCount)); gSPSegment(gfx++, 0x0D, mtx); @@ -994,7 +1002,7 @@ void AnimationContext_SetLoadFrame(GlobalContext* globalCtx, LinkAnimationHeader AnimationEntry* entry = AnimationContext_AddEntry(&globalCtx->animationCtx, ANIMATION_LINKANIMETION); if (entry != NULL) { - LinkAnimationHeader* linkAnimHeader = (LinkAnimationHeader*)Lib_SegmentedToVirtual(animation); + LinkAnimationHeader* linkAnimHeader = Lib_SegmentedToVirtual(animation); u32 ram = frameTable; osCreateMesgQueue(&entry->data.load.msgQueue, &entry->data.load.msg, 1); diff --git a/src/code/z_sub_s.c b/src/code/z_sub_s.c index 8f0599b55..764b3525f 100644 --- a/src/code/z_sub_s.c +++ b/src/code/z_sub_s.c @@ -36,9 +36,119 @@ EnDoor* SubS_FindDoor(GlobalContext* globalCtx, s32 unk_1A5) { return door; } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_sub_s/func_8013A860.s") +Gfx* SubS_DrawTransformFlexLimb(GlobalContext* globalCtx, s32 limbIndex, void** skeleton, Vec3s* jointTable, + OverrideLimbDraw overrideLimbDraw, PostLimbDraw postLimbDraw, + TransformLimbDraw transformLimbDraw, Actor* actor, Mtx** mtx, Gfx* gfx) { + StandardLimb* limb; + Gfx* newDList; + Gfx* limbDList; + Vec3f pos; + Vec3s rot; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_sub_s/func_8013AB00.s") + Matrix_StatePush(); + limb = Lib_SegmentedToVirtual(skeleton[limbIndex]); + limbIndex++; + rot = jointTable[limbIndex]; + pos.x = limb->jointPos.x; + pos.y = limb->jointPos.y; + pos.z = limb->jointPos.z; + newDList = limbDList = limb->dList; + + if ((overrideLimbDraw == NULL) || !overrideLimbDraw(globalCtx, limbIndex, &newDList, &pos, &rot, actor, &gfx)) { + Matrix_JointPosition(&pos, &rot); + Matrix_StatePush(); + + transformLimbDraw(globalCtx, limbIndex, actor, &gfx); + + if (newDList != NULL) { + Matrix_ToMtx(*mtx); + gSPMatrix(gfx++, *mtx, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(gfx++, newDList); + (*mtx)++; + } else if (limbDList != NULL) { + Matrix_ToMtx(*mtx); + (*mtx)++; + } + Matrix_StatePop(); + } + if (postLimbDraw != NULL) { + postLimbDraw(globalCtx, limbIndex, &limbDList, &rot, actor, &gfx); + } + if (limb->child != LIMB_DONE) { + gfx = SubS_DrawTransformFlexLimb(globalCtx, limb->child, skeleton, jointTable, overrideLimbDraw, postLimbDraw, + transformLimbDraw, actor, mtx, gfx); + } + Matrix_StatePop(); + if (limb->sibling != LIMB_DONE) { + gfx = SubS_DrawTransformFlexLimb(globalCtx, limb->sibling, skeleton, jointTable, overrideLimbDraw, postLimbDraw, + transformLimbDraw, actor, mtx, gfx); + } + return gfx; +} + +/** + * Draw all limbs of type `StandardLimb` in a given flexible skeleton + * Limbs in a flexible skeleton have meshes that can stretch to line up with other limbs. + * An array of matrices is dynamically allocated so each limb can access any transform to ensure its meshes line up. + * + * Also makes use of a `TransformLimbDraw`, which transforms limbs based on world coordinates, as opposed to local limb + * coordinates. + * Note that the `TransformLimbDraw` does not have a NULL check, so must be provided even if empty. + */ +Gfx* SubS_DrawTransformFlex(GlobalContext* globalCtx, void** skeleton, Vec3s* jointTable, s32 dListCount, + OverrideLimbDraw overrideLimbDraw, PostLimbDraw postLimbDraw, + TransformLimbDraw transformLimbDraw, Actor* actor, Gfx* gfx) { + StandardLimb* rootLimb; + s32 pad; + Gfx* newDlist; + Gfx* limbDList; + Vec3f pos; + Vec3s rot; + Mtx* mtx = GRAPH_ALLOC(globalCtx->state.gfxCtx, ALIGN16(dListCount * sizeof(Mtx))); + + if (skeleton == NULL) { + return NULL; + } + + gSPSegment(gfx++, 0x0D, mtx); + Matrix_StatePush(); + rootLimb = Lib_SegmentedToVirtual(skeleton[0]); + pos.x = jointTable->x; + pos.y = jointTable->y; + pos.z = jointTable->z; + rot = jointTable[1]; + newDlist = rootLimb->dList; + limbDList = rootLimb->dList; + + if (overrideLimbDraw == NULL || !overrideLimbDraw(globalCtx, 1, &newDlist, &pos, &rot, actor, &gfx)) { + Matrix_JointPosition(&pos, &rot); + Matrix_StatePush(); + + transformLimbDraw(globalCtx, 1, actor, &gfx); + + if (newDlist != NULL) { + Matrix_ToMtx(mtx); + gSPMatrix(gfx++, mtx, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(gfx++, newDlist); + mtx++; + } else if (limbDList != NULL) { + Matrix_ToMtx(mtx); + mtx++; + } + Matrix_StatePop(); + } + + if (postLimbDraw != NULL) { + postLimbDraw(globalCtx, 1, &limbDList, &rot, actor, &gfx); + } + + if (rootLimb->child != LIMB_DONE) { + gfx = SubS_DrawTransformFlexLimb(globalCtx, rootLimb->child, skeleton, jointTable, overrideLimbDraw, + postLimbDraw, transformLimbDraw, actor, &mtx, gfx); + } + Matrix_StatePop(); + return gfx; +} #pragma GLOBAL_ASM("asm/non_matchings/code/z_sub_s/func_8013AD6C.s") diff --git a/src/overlays/actors/ovl_Dm_Nb/z_dm_nb.c b/src/overlays/actors/ovl_Dm_Nb/z_dm_nb.c index 1e36f9e29..0e9b87191 100644 --- a/src/overlays/actors/ovl_Dm_Nb/z_dm_nb.c +++ b/src/overlays/actors/ovl_Dm_Nb/z_dm_nb.c @@ -91,13 +91,13 @@ void DmNb_Update(Actor* thisx, GlobalContext* globalCtx) { Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 30.0f, 12.0f, 0.0f, 4); } -void DmNb_UnkActorDraw(GlobalContext* globalCtx, s32 limbIndex, Actor* thisx) { +void DmNb_TransformLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Actor* thisx) { } void DmNb_Draw(Actor* thisx, GlobalContext* globalCtx) { DmNb* this = THIS; func_8012C5B0(globalCtx->state.gfxCtx); - func_801343C0(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, NULL, - NULL, DmNb_UnkActorDraw, &this->actor); + SkelAnime_DrawTransformFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, + this->skelAnime.dListCount, NULL, NULL, DmNb_TransformLimbDraw, &this->actor); } diff --git a/src/overlays/actors/ovl_Dm_Sa/z_dm_sa.c b/src/overlays/actors/ovl_Dm_Sa/z_dm_sa.c index 586b231ae..16c559983 100644 --- a/src/overlays/actors/ovl_Dm_Sa/z_dm_sa.c +++ b/src/overlays/actors/ovl_Dm_Sa/z_dm_sa.c @@ -74,14 +74,14 @@ void DmSa_Update(Actor* thisx, GlobalContext* globalCtx) { this->actionFunc(this, globalCtx); } -s32 func_80A2EB10(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* actor) { - return 0; +s32 DmSa_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx) { + return false; } -void func_80A2EB2C(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* actor) { +void DmSa_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { } -void func_80A2EB44(GlobalContext* globalCtx, s32 limbIndex, Actor* actor) { +void DmSa_TransformLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Actor* thisx) { } Gfx* func_80A2EB58(GraphicsContext* gfxCtx, u32 alpha) { @@ -120,8 +120,9 @@ void DmSa_Draw(Actor* thisx, GlobalContext* globalCtx) { gSPSegment(POLY_OPA_DISP++, 0x0C, func_80A2EBB0(globalCtx->state.gfxCtx, this->alpha)); } - func_801343C0(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, - func_80A2EB10, func_80A2EB2C, func_80A2EB44, &this->actor); + SkelAnime_DrawTransformFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, + this->skelAnime.dListCount, DmSa_OverrideLimbDraw, DmSa_PostLimbDraw, + DmSa_TransformLimbDraw, &this->actor); CLOSE_DISPS(globalCtx->state.gfxCtx); } diff --git a/src/overlays/actors/ovl_En_Akindonuts/z_en_akindonuts.c b/src/overlays/actors/ovl_En_Akindonuts/z_en_akindonuts.c index a638422bf..430eeaa5d 100644 --- a/src/overlays/actors/ovl_En_Akindonuts/z_en_akindonuts.c +++ b/src/overlays/actors/ovl_En_Akindonuts/z_en_akindonuts.c @@ -1670,13 +1670,13 @@ s32 EnAkindonuts_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** *dList = object_dnt_DL_008290; } } - return 0; + return false; } void EnAkindonuts_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { } -void EnAkindonuts_UnkActorDraw(GlobalContext* globalCtx, s32 limbIndex, Actor* thisx) { +void EnAkindonuts_TransformLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Actor* thisx) { EnAkindonuts* this = THIS; if (((this->unk_33E == 1) || (this->unk_33E == 2)) && ((limbIndex == 23) || (limbIndex == 24))) { @@ -1696,6 +1696,7 @@ void EnAkindonuts_Draw(Actor* thisx, GlobalContext* globalCtx) { EnAkindonuts* this = THIS; func_8012C28C(globalCtx->state.gfxCtx); - func_801343C0(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, - EnAkindonuts_OverrideLimbDraw, EnAkindonuts_PostLimbDraw, EnAkindonuts_UnkActorDraw, &this->actor); + SkelAnime_DrawTransformFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, + this->skelAnime.dListCount, EnAkindonuts_OverrideLimbDraw, EnAkindonuts_PostLimbDraw, + EnAkindonuts_TransformLimbDraw, &this->actor); } diff --git a/src/overlays/actors/ovl_En_Aob_01/z_en_aob_01.c b/src/overlays/actors/ovl_En_Aob_01/z_en_aob_01.c index 4c7b1d6cb..2a67ff703 100644 --- a/src/overlays/actors/ovl_En_Aob_01/z_en_aob_01.c +++ b/src/overlays/actors/ovl_En_Aob_01/z_en_aob_01.c @@ -979,7 +979,7 @@ void EnAob01_Update(Actor* thisx, GlobalContext* globalCtx) { s32 EnAob01_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx) { EnAob01* this = THIS; - UNK_TYPE sp38[] = { + TexturePtr sp38[] = { &object_aob_Tex_000658, &object_aob_Tex_000E58, &object_aob_Tex_001658, @@ -1023,7 +1023,7 @@ void EnAob01_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, } } -void EnAob01_UnkDraw(GlobalContext* globalCtx, s32 limbIndex, Actor* thisx) { +void EnAob01_TransformLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Actor* thisx) { } void EnAob01_Draw(Actor* thisx, GlobalContext* globalCtx) { @@ -1040,8 +1040,9 @@ void EnAob01_Draw(Actor* thisx, GlobalContext* globalCtx) { gSPSegment(POLY_OPA_DISP++, 0x09, Gfx_EnvColor(globalCtx->state.gfxCtx, 50, 80, 0, 0)); gDPPipeSync(POLY_OPA_DISP++); - func_801343C0(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, - EnAob01_OverrideLimbDraw, EnAob01_PostLimbDraw, EnAob01_UnkDraw, &this->actor); + SkelAnime_DrawTransformFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, + this->skelAnime.dListCount, EnAob01_OverrideLimbDraw, EnAob01_PostLimbDraw, + EnAob01_TransformLimbDraw, &this->actor); if (this->actor.draw != NULL) { func_8012C2DC(globalCtx->state.gfxCtx); diff --git a/src/overlays/actors/ovl_En_Bigpo/z_en_bigpo.c b/src/overlays/actors/ovl_En_Bigpo/z_en_bigpo.c index 5b31f7601..db6258a73 100644 --- a/src/overlays/actors/ovl_En_Bigpo/z_en_bigpo.c +++ b/src/overlays/actors/ovl_En_Bigpo/z_en_bigpo.c @@ -1223,19 +1223,19 @@ void EnBigpo_UpdateFire(Actor* thisx, GlobalContext* globalCtx) { this->actionFunc(this, globalCtx); } -s32 EnBigpo_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* actor, +s32 EnBigpo_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx, Gfx** gfx) { - EnBigpo* this = (EnBigpo*)actor; + EnBigpo* this = THIS; // not fully invisible if (!(this->mainColor.a != 0 && limbIndex != 7) || (this->actionFunc == EnBigpo_BurnAwayDeath && this->idleTimer >= 2)) { *dList = NULL; } - return 0; + return false; } -void EnBigpo_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* actor, Gfx** gfx) { - EnBigpo* this = (EnBigpo*)actor; +void EnBigpo_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx, Gfx** gfx) { + EnBigpo* this = THIS; s8 limbByte; Vec3f* v1ptr; // todo: figure out better names Vec3f* v2ptr; diff --git a/src/overlays/actors/ovl_En_Bji_01/z_en_bji_01.c b/src/overlays/actors/ovl_En_Bji_01/z_en_bji_01.c index d1c876b6c..a337f9df0 100644 --- a/src/overlays/actors/ovl_En_Bji_01/z_en_bji_01.c +++ b/src/overlays/actors/ovl_En_Bji_01/z_en_bji_01.c @@ -26,8 +26,9 @@ void func_809CD6C0(EnBji01* this, GlobalContext* globalCtx); void func_809CD70C(EnBji01* this, GlobalContext* globalCtx); void func_809CD77C(EnBji01* this, GlobalContext* globalCtx); -s32 EnBji01_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* arg); -void EnBji01_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* arg); +s32 EnBji01_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, + Actor* thisx); +void EnBji01_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx); extern AnimationHeader D_06000FDC; extern AnimationHeader D_06005B58; @@ -441,7 +442,7 @@ void EnBji01_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, } void EnBji01_Draw(Actor* thisx, GlobalContext* globalCtx) { - static void* sEyeTextures[] = { D_060049F0, D_06004E70, D_06005270 }; + static TexturePtr sEyeTextures[] = { D_060049F0, D_06004E70, D_06005270 }; EnBji01* this = THIS; OPEN_DISPS(globalCtx->state.gfxCtx); diff --git a/src/overlays/actors/ovl_En_Dai/z_en_dai.c b/src/overlays/actors/ovl_En_Dai/z_en_dai.c index 0e83d1091..12266ab41 100644 --- a/src/overlays/actors/ovl_En_Dai/z_en_dai.c +++ b/src/overlays/actors/ovl_En_Dai/z_en_dai.c @@ -582,8 +582,8 @@ void EnDai_Update(Actor* thisx, GlobalContext* globalCtx) { } } -s32 func_80B3F598(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx, - Gfx** gfx) { +s32 EnDai_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx, + Gfx** gfx) { EnDai* this = THIS; if (!(this->unk_1CE & 0x40)) { @@ -598,10 +598,10 @@ s32 func_80B3F598(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* p *dList = NULL; } - return 0; + return false; } -void func_80B3F614(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx, Gfx** gfx) { +void EnDai_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx, Gfx** gfx) { static Vec3f D_80B3FE4C = { 0.0f, 0.0f, 0.0f }; EnDai* this = THIS; @@ -626,10 +626,10 @@ void func_80B3F614(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* } } -void func_80B3F6EC(GlobalContext* globalCtx, s32 arg1, Actor* thisx, Gfx** gfx) { +void EnDai_TransformLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Actor* thisx, Gfx** gfx) { EnDai* this = THIS; - switch (arg1) { + switch (limbIndex) { case 9: if (this->unk_1CE & 0x100) { func_80B3EC84(this); @@ -669,9 +669,9 @@ void func_80B3F78C(EnDai* this, GlobalContext* globalCtx) { gDPSetEnvColor(POLY_XLU_DISP++, 0, 0, 0, 255); gSPSegment(POLY_XLU_DISP++, 0x08, Lib_SegmentedToVirtual(D_80B3FE58[this->unk_1D6])); - POLY_XLU_DISP = - func_8013AB00(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, - func_80B3F598, func_80B3F614, func_80B3F6EC, &this->actor, POLY_XLU_DISP); + POLY_XLU_DISP = SubS_DrawTransformFlex(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, + this->skelAnime.dListCount, EnDai_OverrideLimbDraw, EnDai_PostLimbDraw, + EnDai_TransformLimbDraw, &this->actor, POLY_XLU_DISP); if (this->unk_1CE & 0x40) { Matrix_SetCurrentState(&this->unk_18C); @@ -701,9 +701,9 @@ void func_80B3F920(EnDai* this, GlobalContext* globalCtx) { gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(D_80B3FE70[this->unk_1D6])); - POLY_OPA_DISP = - func_8013AB00(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, - func_80B3F598, func_80B3F614, func_80B3F6EC, &this->actor, POLY_OPA_DISP); + POLY_OPA_DISP = SubS_DrawTransformFlex(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, + this->skelAnime.dListCount, EnDai_OverrideLimbDraw, EnDai_PostLimbDraw, + EnDai_TransformLimbDraw, &this->actor, POLY_OPA_DISP); Matrix_SetCurrentState(&this->unk_18C); gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); @@ -720,9 +720,9 @@ void func_80B3F920(EnDai* this, GlobalContext* globalCtx) { gDPSetEnvColor(POLY_XLU_DISP++, 0, 0, 0, this->unk_1CD); gSPSegment(POLY_XLU_DISP++, 0x08, Lib_SegmentedToVirtual(D_80B3FE70[this->unk_1D6])); - POLY_XLU_DISP = - func_8013AB00(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, - func_80B3F598, func_80B3F614, func_80B3F6EC, &this->actor, POLY_XLU_DISP); + POLY_XLU_DISP = SubS_DrawTransformFlex(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, + this->skelAnime.dListCount, EnDai_OverrideLimbDraw, EnDai_PostLimbDraw, + EnDai_TransformLimbDraw, &this->actor, POLY_XLU_DISP); Matrix_SetCurrentState(&this->unk_18C); gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); diff --git a/src/overlays/actors/ovl_En_Daiku/z_en_daiku.c b/src/overlays/actors/ovl_En_Daiku/z_en_daiku.c index 4971193a3..52777aee0 100644 --- a/src/overlays/actors/ovl_En_Daiku/z_en_daiku.c +++ b/src/overlays/actors/ovl_En_Daiku/z_en_daiku.c @@ -296,7 +296,8 @@ void EnDaiku_Update(Actor* thisx, GlobalContext* globalCtx) { CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); } -s32 func_80943E18(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx) { +s32 EnDaiku_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, + Actor* thisx) { EnDaiku* this = THIS; if (limbIndex == 15) { @@ -304,10 +305,10 @@ s32 func_80943E18(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* p rot->z += this->unk_25E; } - return 0; + return false; } -void func_80943E60(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { +void EnDaiku_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { static Gfx* D_809440D4[] = { D_060070C0, D_06006FB0, D_06006E80, D_06006D70 }; EnDaiku* this = THIS; @@ -354,7 +355,7 @@ void EnDaiku_Draw(Actor* thisx, GlobalContext* globalCtx) { } SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, - func_80943E18, func_80943E60, &this->actor); + EnDaiku_OverrideLimbDraw, EnDaiku_PostLimbDraw, &this->actor); CLOSE_DISPS(globalCtx->state.gfxCtx); } diff --git a/src/overlays/actors/ovl_En_Dekunuts/z_en_dekunuts.c b/src/overlays/actors/ovl_En_Dekunuts/z_en_dekunuts.c index e75bbade9..d6308cb1a 100644 --- a/src/overlays/actors/ovl_En_Dekunuts/z_en_dekunuts.c +++ b/src/overlays/actors/ovl_En_Dekunuts/z_en_dekunuts.c @@ -671,7 +671,8 @@ void EnDekunuts_Update(Actor* thisx, GlobalContext* globalCtx) { } } -s32 func_808BEBD0(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx) { +s32 EnDekunuts_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, + Actor* thisx) { EnDekunuts* this = THIS; f32 arg1, arg2, arg3; f32 currentFrame; @@ -700,10 +701,10 @@ s32 func_808BEBD0(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* p rot->z = this->actor.world.rot.x; } } - return 0; + return false; } -void func_808BED30(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { +void EnDekunuts_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { static s8 D_808BEF98[] = { -1, -1, -1, 3, -1, 0, -1, 1, -1, 2, 0, 0, }; @@ -739,8 +740,8 @@ void func_808BED30(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* void EnDekunuts_Draw(Actor* thisx, GlobalContext* globalCtx) { EnDekunuts* this = THIS; - SkelAnime_DrawOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, func_808BEBD0, func_808BED30, - &this->actor); + SkelAnime_DrawOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, EnDekunuts_OverrideLimbDraw, + EnDekunuts_PostLimbDraw, &this->actor); Matrix_SetStateRotationAndTranslation(this->actor.home.pos.x, this->actor.home.pos.y, this->actor.home.pos.z, &this->actor.home.rot); Matrix_Scale(this->actor.scale.x, this->actor.scale.y, this->actor.scale.z, MTXMODE_APPLY); diff --git a/src/overlays/actors/ovl_En_Dg/z_en_dg.c b/src/overlays/actors/ovl_En_Dg/z_en_dg.c index 907344cf5..2b3426843 100644 --- a/src/overlays/actors/ovl_En_Dg/z_en_dg.c +++ b/src/overlays/actors/ovl_En_Dg/z_en_dg.c @@ -1174,11 +1174,11 @@ void EnDg_Update(Actor* thisx, GlobalContext* globalCtx) { } } -s32 func_8098BFB8(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx) { - return 0; +s32 EnDg_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx) { + return false; } -void func_8098BFD4(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { +void EnDg_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { EnDg* this = THIS; Vec3f sp20 = { 0.0f, 20.0f, 0.0f }; @@ -1231,7 +1231,7 @@ void EnDg_Draw(Actor* thisx, GlobalContext* globalCtx) { Matrix_RotateY(this->actor.shape.rot.y, MTXMODE_APPLY); Matrix_Scale(this->actor.scale.x, this->actor.scale.y, this->actor.scale.z, MTXMODE_APPLY); SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, - func_8098BFB8, func_8098BFD4, &this->actor); + EnDg_OverrideLimbDraw, EnDg_PostLimbDraw, &this->actor); CLOSE_DISPS(globalCtx->state.gfxCtx); } diff --git a/src/overlays/actors/ovl_En_Dnp/z_en_dnp.c b/src/overlays/actors/ovl_En_Dnp/z_en_dnp.c index 98884c114..f578b6445 100644 --- a/src/overlays/actors/ovl_En_Dnp/z_en_dnp.c +++ b/src/overlays/actors/ovl_En_Dnp/z_en_dnp.c @@ -456,10 +456,10 @@ s32 func_80B3D974(s16 arg0, s16 arg1, Vec3f* arg2, Vec3s* arg3, s32 arg4, s32 ar return 1; } -void func_80B3DA88(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { +void EnDnp_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { } -void func_80B3DAA0(GlobalContext* globalCtx, s32 limbIndex, Actor* thisx) { +void EnDnp_TransformLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Actor* thisx) { EnDnp* this = THIS; s32 phi_v1 = 1; s32 phi_v0; @@ -504,8 +504,9 @@ void EnDnp_Draw(Actor* thisx, GlobalContext* globalCtx) { gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(D_80B3DEAC[this->unk_336])); - func_801343C0(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, NULL, - func_80B3DA88, func_80B3DAA0, &this->actor); + SkelAnime_DrawTransformFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, + this->skelAnime.dListCount, NULL, EnDnp_PostLimbDraw, EnDnp_TransformLimbDraw, + &this->actor); CLOSE_DISPS(globalCtx->state.gfxCtx); } diff --git a/src/overlays/actors/ovl_En_Ending_Hero/z_en_ending_hero.c b/src/overlays/actors/ovl_En_Ending_Hero/z_en_ending_hero.c index f483b3289..93d4ce1bd 100644 --- a/src/overlays/actors/ovl_En_Ending_Hero/z_en_ending_hero.c +++ b/src/overlays/actors/ovl_En_Ending_Hero/z_en_ending_hero.c @@ -99,7 +99,7 @@ void EnEndingHero_Draw(Actor* thisx, GlobalContext* globalCtx) { gSPSegment(POLY_OPA_DISP++, 0x09, Lib_SegmentedToVirtual(D_80C1E984[index])); SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, - 0, 0, &this->actor); + NULL, NULL, &this->actor); CLOSE_DISPS(globalCtx->state.gfxCtx); } diff --git a/src/overlays/actors/ovl_En_Ending_Hero2/z_en_ending_hero2.c b/src/overlays/actors/ovl_En_Ending_Hero2/z_en_ending_hero2.c index 8df6a328d..09c1a950f 100644 --- a/src/overlays/actors/ovl_En_Ending_Hero2/z_en_ending_hero2.c +++ b/src/overlays/actors/ovl_En_Ending_Hero2/z_en_ending_hero2.c @@ -71,5 +71,5 @@ void EnEndingHero2_Draw(Actor* thisx, GlobalContext* globalCtx) { func_8012C28C(globalCtx->state.gfxCtx); func_8012C2DC(globalCtx->state.gfxCtx); SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, - 0, 0, &this->actor); + NULL, NULL, &this->actor); } diff --git a/src/overlays/actors/ovl_En_Ending_Hero3/z_en_ending_hero3.c b/src/overlays/actors/ovl_En_Ending_Hero3/z_en_ending_hero3.c index b89196d58..c314b7b62 100644 --- a/src/overlays/actors/ovl_En_Ending_Hero3/z_en_ending_hero3.c +++ b/src/overlays/actors/ovl_En_Ending_Hero3/z_en_ending_hero3.c @@ -71,5 +71,5 @@ void EnEndingHero3_Draw(Actor* thisx, GlobalContext* globalCtx) { func_8012C28C(globalCtx->state.gfxCtx); func_8012C2DC(globalCtx->state.gfxCtx); SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, - 0, 0, &this->actor); + NULL, NULL, &this->actor); } diff --git a/src/overlays/actors/ovl_En_Ending_Hero4/z_en_ending_hero4.c b/src/overlays/actors/ovl_En_Ending_Hero4/z_en_ending_hero4.c index 5f2ad6222..1b8e7e7a1 100644 --- a/src/overlays/actors/ovl_En_Ending_Hero4/z_en_ending_hero4.c +++ b/src/overlays/actors/ovl_En_Ending_Hero4/z_en_ending_hero4.c @@ -71,5 +71,5 @@ void EnEndingHero4_Draw(Actor* thisx, GlobalContext* globalCtx) { func_8012C28C(globalCtx->state.gfxCtx); func_8012C2DC(globalCtx->state.gfxCtx); SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, - 0, 0, &this->actor); + NULL, NULL, &this->actor); } diff --git a/src/overlays/actors/ovl_En_Ending_Hero5/z_en_ending_hero5.c b/src/overlays/actors/ovl_En_Ending_Hero5/z_en_ending_hero5.c index 3a8f317f5..8daf7616e 100644 --- a/src/overlays/actors/ovl_En_Ending_Hero5/z_en_ending_hero5.c +++ b/src/overlays/actors/ovl_En_Ending_Hero5/z_en_ending_hero5.c @@ -74,7 +74,7 @@ void EnEndingHero5_Update(Actor* thisx, GlobalContext* globalCtx) { Gfx* D_80C23BF0[] = { D_060070C0, D_06006FB0, D_06006E80, D_06006D70, D_0600A390 }; -void func_80C23A30(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { +void EnEndingHero5_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { EnEndingHero5* this = THIS; OPEN_DISPS(globalCtx->state.gfxCtx); @@ -112,7 +112,7 @@ void EnEndingHero5_Draw(Actor* thisx, GlobalContext* globalCtx) { } SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, - NULL, func_80C23A30, &this->actor); + NULL, EnEndingHero5_PostLimbDraw, &this->actor); CLOSE_DISPS(globalCtx->state.gfxCtx); } diff --git a/src/overlays/actors/ovl_En_Fg/z_en_fg.c b/src/overlays/actors/ovl_En_Fg/z_en_fg.c index 612331054..189f0e2e0 100644 --- a/src/overlays/actors/ovl_En_Fg/z_en_fg.c +++ b/src/overlays/actors/ovl_En_Fg/z_en_fg.c @@ -360,8 +360,8 @@ void EnFg_Update(Actor* thisx, GlobalContext* globalCtx) { func_80A2D348(this, globalCtx); } -s32 EnFg_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* arg) { - EnFg* this = (EnFg*)arg; +s32 EnFg_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx) { + EnFg* this = THIS; if ((limbIndex == 7) || (limbIndex == 8)) { *dList = NULL; @@ -372,11 +372,11 @@ s32 EnFg_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, *dList = NULL; } } - return 0; + return false; } -void EnFg_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* arg) { - EnFg* this = (EnFg*)arg; +void EnFg_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { + EnFg* this = THIS; s16 pad; Vec3f vec1 = { 0.0f, 0.0f, 0.0f }; diff --git a/src/overlays/actors/ovl_En_Fishing/z_en_fishing.c b/src/overlays/actors/ovl_En_Fishing/z_en_fishing.c index 4de4d0955..fcd659e8f 100644 --- a/src/overlays/actors/ovl_En_Fishing/z_en_fishing.c +++ b/src/overlays/actors/ovl_En_Fishing/z_en_fishing.c @@ -4228,7 +4228,7 @@ s32 EnFishing_LoachOverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx rot->y += this->unk_1C4[2]; } - return 0; + return false; } void EnFishing_LoachPostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { diff --git a/src/overlays/actors/ovl_En_Fsn/z_en_fsn.c b/src/overlays/actors/ovl_En_Fsn/z_en_fsn.c index 7e43657c0..2085da828 100644 --- a/src/overlays/actors/ovl_En_Fsn/z_en_fsn.c +++ b/src/overlays/actors/ovl_En_Fsn/z_en_fsn.c @@ -1585,7 +1585,7 @@ s32 EnFsn_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, if (limbIndex == 17) { *dList = NULL; } - return 0; + return false; } void EnFsn_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { @@ -1604,7 +1604,7 @@ void EnFsn_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Ve } void EnFsn_Draw(Actor* thisx, GlobalContext* globalCtx) { - static void* sEyeTextures[] = { &D_06005BC0, &D_06006D40, &D_06007140 }; + static TexturePtr sEyeTextures[] = { &D_06005BC0, &D_06006D40, &D_06007140 }; EnFsn* this = THIS; s32 pad; s16 i; diff --git a/src/overlays/actors/ovl_En_Geg/z_en_geg.c b/src/overlays/actors/ovl_En_Geg/z_en_geg.c index 4209efe3f..72346ca76 100644 --- a/src/overlays/actors/ovl_En_Geg/z_en_geg.c +++ b/src/overlays/actors/ovl_En_Geg/z_en_geg.c @@ -966,7 +966,7 @@ void EnGeg_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Ve } } -void EnGeg_UnkDraw(GlobalContext* globalCtx, s32 limbIndex, Actor* thisx) { +void EnGeg_TransformLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Actor* thisx) { EnGeg* this = THIS; s32 phi_v0; s32 phi_v1; @@ -1039,8 +1039,9 @@ void func_80BB3BE0(EnGeg* this, GlobalContext* globalCtx) { gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(D_80BB4088[this->unk_23E])); gDPPipeSync(POLY_OPA_DISP++); - func_801343C0(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, - EnGeg_OverrideLimbDraw, EnGeg_PostLimbDraw, EnGeg_UnkDraw, &this->actor); + SkelAnime_DrawTransformFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, + this->skelAnime.dListCount, EnGeg_OverrideLimbDraw, EnGeg_PostLimbDraw, + EnGeg_TransformLimbDraw, &this->actor); CLOSE_DISPS(globalCtx->state.gfxCtx); } diff --git a/src/overlays/actors/ovl_En_Ginko_Man/z_en_ginko_man.c b/src/overlays/actors/ovl_En_Ginko_Man/z_en_ginko_man.c index e830ae1bf..b5ce045e6 100644 --- a/src/overlays/actors/ovl_En_Ginko_Man/z_en_ginko_man.c +++ b/src/overlays/actors/ovl_En_Ginko_Man/z_en_ginko_man.c @@ -633,8 +633,8 @@ void EnGinkoMan_Update(Actor* thisx, GlobalContext* globalCtx) { } s32 EnGinkoMan_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, - Actor* arg) { - EnGinkoMan* this = (EnGinkoMan*)arg; + Actor* thisx) { + EnGinkoMan* this = THIS; if (limbIndex == 15) { *dList = D_0600B1D8; @@ -650,10 +650,10 @@ s32 EnGinkoMan_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** d Matrix_InsertZRotation_s(-this->limb8Rot.x, MTXMODE_APPLY); } - return 0; + return false; } -void EnGinkoMan_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* arg) { +void EnGinkoMan_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { } void EnGinkoMan_Draw(Actor* thisx, GlobalContext* globalCtx) { diff --git a/src/overlays/actors/ovl_En_Gm/z_en_gm.c b/src/overlays/actors/ovl_En_Gm/z_en_gm.c index aee390e8d..026d9f51c 100644 --- a/src/overlays/actors/ovl_En_Gm/z_en_gm.c +++ b/src/overlays/actors/ovl_En_Gm/z_en_gm.c @@ -1649,7 +1649,7 @@ void EnGm_Update(Actor* thisx, GlobalContext* globalCtx) { } } -s32 func_809513AC(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx) { +s32 EnGm_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx) { s32 pad; EnGm* this = THIS; s32 phi_v0; @@ -1684,7 +1684,7 @@ s32 func_809513AC(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* p return false; } -void func_809514BC(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { +void EnGm_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { static Vec3f D_80951E24 = { 1400.0f, 0.0f, 0.0f }; EnGm* this = THIS; s32 pad[4]; @@ -1710,7 +1710,7 @@ void func_809514BC(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* } } -void func_80951594(GlobalContext* globalCtx, s32 limbIndex, Actor* thisx) { +void EnGm_TransformLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Actor* thisx) { EnGm* this = THIS; s32 phi_v0 = 1; s32 phi_v1 = 0; @@ -1762,8 +1762,9 @@ void EnGm_Draw(Actor* thisx, GlobalContext* globalCtx) { gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(D_80951E30[this->unk_3CE])); - func_801343C0(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, - func_809513AC, func_809514BC, func_80951594, &this->actor); + SkelAnime_DrawTransformFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, + this->skelAnime.dListCount, EnGm_OverrideLimbDraw, EnGm_PostLimbDraw, + EnGm_TransformLimbDraw, &this->actor); CLOSE_DISPS(globalCtx->state.gfxCtx); } diff --git a/src/overlays/actors/ovl_En_Go/z_en_go.c b/src/overlays/actors/ovl_En_Go/z_en_go.c index 15e0b7622..3a260a986 100644 --- a/src/overlays/actors/ovl_En_Go/z_en_go.c +++ b/src/overlays/actors/ovl_En_Go/z_en_go.c @@ -1993,7 +1993,7 @@ s32 EnGo_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, return false; } -void EnGo_UnkDraw(GlobalContext* globalCtx, s32 limbIndex, Actor* thisx) { +void EnGo_TransfromLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Actor* thisx) { EnGo* this = THIS; u16 temp_v0; s32 phi_v1; @@ -2044,7 +2044,7 @@ void EnGo_UnkDraw(GlobalContext* globalCtx, s32 limbIndex, Actor* thisx) { } void func_80A15FEC(Actor* thisx, GlobalContext* globalCtx) { - static UNK_TYPE D_80A1670C[] = { + static TexturePtr D_80A1670C[] = { &object_oF1d_map_Tex_010438, &object_oF1d_map_Tex_010C38, &object_oF1d_map_Tex_011038, &object_oF1d_map_Tex_010C38, &object_oF1d_map_Tex_010838, }; @@ -2060,8 +2060,9 @@ void func_80A15FEC(Actor* thisx, GlobalContext* globalCtx) { if (this->unk_3DC == 14) { Matrix_InsertTranslation(0.0f, 0.0f, -4000.0f, MTXMODE_APPLY); } - func_801343C0(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, - EnGo_OverrideLimbDraw, NULL, EnGo_UnkDraw, &this->actor); + SkelAnime_DrawTransformFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, + this->skelAnime.dListCount, EnGo_OverrideLimbDraw, NULL, EnGo_TransfromLimbDraw, + &this->actor); CLOSE_DISPS(globalCtx->state.gfxCtx); } else { diff --git a/src/overlays/actors/ovl_En_Hg/z_en_hg.c b/src/overlays/actors/ovl_En_Hg/z_en_hg.c index c02ab0eaf..1bf3652f0 100644 --- a/src/overlays/actors/ovl_En_Hg/z_en_hg.c +++ b/src/overlays/actors/ovl_En_Hg/z_en_hg.c @@ -27,8 +27,8 @@ void func_80BCF6D0(EnHg* this, GlobalContext* globalCtx); void func_80BCF8A0(EnHg* this, GlobalContext* globalCtx); void func_80BCF93C(EnHg* this); void func_80BCF95C(EnHg* this, GlobalContext* globalCtx); -s32 EnHg_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* arg); -void EnHg_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* arg); +s32 EnHg_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx); +void EnHg_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx); extern AnimationHeader D_06000370; extern AnimationHeader D_06001138; @@ -401,7 +401,7 @@ void EnHg_Update(Actor* thisx, GlobalContext* globalCtx) { } s32 EnHg_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx) { - return 0; + return false; } void EnHg_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { diff --git a/src/overlays/actors/ovl_En_Ig/z_en_ig.c b/src/overlays/actors/ovl_En_Ig/z_en_ig.c index d2b4e3612..811c9cc82 100644 --- a/src/overlays/actors/ovl_En_Ig/z_en_ig.c +++ b/src/overlays/actors/ovl_En_Ig/z_en_ig.c @@ -165,7 +165,7 @@ EnDoor* func_80BF1200(GlobalContext* globalCtx, s32 arg1) { phi_a1 = -1; break; } - return (EnDoor*)SubS_FindDoor(globalCtx, phi_a1); + return SubS_FindDoor(globalCtx, phi_a1); } void func_80BF1258(EnIg* this) { @@ -960,7 +960,7 @@ void EnIg_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec } } -void EnIg_UnkDraw(GlobalContext* globalCtx, s32 limbIndex, Actor* thisx, Gfx** gfx) { +void EnIg_TransformLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Actor* thisx, Gfx** gfx) { EnIg* this = THIS; s32 phi_v0; s32 phi_v1; @@ -1007,9 +1007,9 @@ void EnIg_Draw(Actor* thisx, GlobalContext* globalCtx) { gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(D_80BF3534[this->unk_3F2])); - POLY_OPA_DISP = - func_8013AB00(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, - EnIg_OverrideLimbDraw, EnIg_PostLimbDraw, EnIg_UnkDraw, &this->actor, POLY_OPA_DISP); + POLY_OPA_DISP = SubS_DrawTransformFlex(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, + this->skelAnime.dListCount, EnIg_OverrideLimbDraw, EnIg_PostLimbDraw, + EnIg_TransformLimbDraw, &this->actor, POLY_OPA_DISP); Matrix_SetCurrentState(&this->unk_190); gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); diff --git a/src/overlays/actors/ovl_En_In/z_en_in.c b/src/overlays/actors/ovl_En_In/z_en_in.c index 66300dda5..6c51b2c1a 100644 --- a/src/overlays/actors/ovl_En_In/z_en_in.c +++ b/src/overlays/actors/ovl_En_In/z_en_in.c @@ -1525,7 +1525,7 @@ void func_808F6334(EnIn* this, GlobalContext* globalCtx) { this->unk4C4 = CLAMP(this->unk4C4, 0.0f, 80.0f); Matrix_InsertTranslation(this->unk4C4, 0.0f, 0.0f, MTXMODE_APPLY); - if (this == (EnIn*)player->targetActor && + if (&this->actor == player->targetActor && !(globalCtx->msgCtx.unk11F04 >= 0xFF && globalCtx->msgCtx.unk11F04 <= 0x200) && newUnk4C8 == 3 && this->unk4C8 == 3) { if (!(globalCtx->state.frames & 1)) { @@ -1537,8 +1537,8 @@ void func_808F6334(EnIn* this, GlobalContext* globalCtx) { this->unk4C8 = newUnk4C8; } -s32 EnIn_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* arg) { - EnIn* this = (EnIn*)arg; +s32 EnIn_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx) { + EnIn* this = THIS; s32 pad; Gfx* sp50[] = { NULL, NULL, D_060149A8, D_06014AE0, D_06014C30, D_060145D8, D_06014710, @@ -1598,8 +1598,8 @@ s32 EnIn_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, return 0; } -void EnIn_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* arg) { - EnIn* this = (EnIn*)arg; +void EnIn_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { + EnIn* this = THIS; Vec3f sp50 = { 1600.0f, 0.0f, 0.0f }; Vec3f sp44 = { 0.0f, 0.0f, 0.0f }; diff --git a/src/overlays/actors/ovl_En_Kakasi/z_en_kakasi.c b/src/overlays/actors/ovl_En_Kakasi/z_en_kakasi.c index 0ccec5015..10bb3fff4 100644 --- a/src/overlays/actors/ovl_En_Kakasi/z_en_kakasi.c +++ b/src/overlays/actors/ovl_En_Kakasi/z_en_kakasi.c @@ -45,7 +45,8 @@ void EnKakasi_SetupSongTeach(EnKakasi* this, GlobalContext* globalCtx); void EnKakasi_SetupDialogue(EnKakasi* this); -void EnKakasi_LimbDraw(struct GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, struct Actor* actor); +void EnKakasi_PostLimbDraw(struct GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, + struct Actor* thisx); static ColliderCylinderInit D_80971D80 = { { @@ -1153,8 +1154,8 @@ void EnKakasi_Update(Actor* thisx, GlobalContext* globalCtx) { } } -void EnKakasi_LimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* actor) { - EnKakasi* this = (EnKakasi*)actor; +void EnKakasi_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { + EnKakasi* this = THIS; if (limbIndex == 4) { Matrix_MultiplyVector3fByState(&gZeroVec3f, &this->unk1BC); @@ -1165,5 +1166,5 @@ void EnKakasi_Draw(Actor* thisx, GlobalContext* globalCtx) { EnKakasi* this = THIS; func_8012C28C(globalCtx->state.gfxCtx); SkelAnime_DrawFlexOpa(globalCtx, this->skelanime.skeleton, this->skelanime.jointTable, this->skelanime.dListCount, - NULL, EnKakasi_LimbDraw, &this->actor); + NULL, EnKakasi_PostLimbDraw, &this->actor); } diff --git a/src/overlays/actors/ovl_En_Ma_Yts/z_en_ma_yts.c b/src/overlays/actors/ovl_En_Ma_Yts/z_en_ma_yts.c index 1ed32213a..7b9a0b879 100644 --- a/src/overlays/actors/ovl_En_Ma_Yts/z_en_ma_yts.c +++ b/src/overlays/actors/ovl_En_Ma_Yts/z_en_ma_yts.c @@ -523,8 +523,9 @@ void EnMaYts_Update(Actor* thisx, GlobalContext* globalCtx) { func_80B8D12C(this, globalCtx); } -s32 EnMaYts_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* arg) { - EnMaYts* this = (EnMaYts*)arg; +s32 EnMaYts_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, + Actor* thisx) { + EnMaYts* this = THIS; Vec3s sp4; if (limbIndex == MA1_LIMB_HEAD) { @@ -539,11 +540,11 @@ s32 EnMaYts_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dLis rot->z += sp4.x; } - return 0; + return false; } -void EnMaYts_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* arg) { - EnMaYts* this = (EnMaYts*)arg; +void EnMaYts_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { + EnMaYts* this = THIS; if (limbIndex == MA1_LIMB_HEAD) { Matrix_GetStateTranslation(&this->actor.focus.pos); diff --git a/src/overlays/actors/ovl_En_Minifrog/z_en_minifrog.c b/src/overlays/actors/ovl_En_Minifrog/z_en_minifrog.c index eecc28790..2f0834514 100644 --- a/src/overlays/actors/ovl_En_Minifrog/z_en_minifrog.c +++ b/src/overlays/actors/ovl_En_Minifrog/z_en_minifrog.c @@ -604,7 +604,7 @@ void EnMinifrog_UpdateMissingFrog(Actor* thisx, GlobalContext* globalCtx) { } s32 EnMinifrog_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, - Actor* arg) { + Actor* thisx) { if (limbIndex == 1) { pos->z -= 500.0f; } @@ -613,11 +613,11 @@ s32 EnMinifrog_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** d *dList = NULL; } - return 0; + return false; } -void EnMinifrog_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* arg) { - EnMinifrog* this = (EnMinifrog*)arg; +void EnMinifrog_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { + EnMinifrog* this = THIS; if ((limbIndex == 7) || (limbIndex == 8)) { OPEN_DISPS(globalCtx->state.gfxCtx); diff --git a/src/overlays/actors/ovl_En_Niw/z_en_niw.c b/src/overlays/actors/ovl_En_Niw/z_en_niw.c index 41730f4d4..8cf3c2fce 100644 --- a/src/overlays/actors/ovl_En_Niw/z_en_niw.c +++ b/src/overlays/actors/ovl_En_Niw/z_en_niw.c @@ -906,7 +906,7 @@ void EnNiw_Update(Actor* thisx, GlobalContext* globalCtx) { } } -s32 EnNiw_LimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx) { +s32 EnNiw_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx) { EnNiw* this = THIS; if (limbIndex == 13) { @@ -925,7 +925,7 @@ s32 EnNiw_LimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* rot->y += (s16)this->limb7Roty; rot->z += (s16)this->limb7Rotz; } - return 0; + return false; } void EnNiw_Draw(Actor* thisx, GlobalContext* globalCtx) { @@ -933,7 +933,7 @@ void EnNiw_Draw(Actor* thisx, GlobalContext* globalCtx) { func_8012C28C(globalCtx->state.gfxCtx); SkelAnime_DrawFlexOpa(globalCtx, this->skelanime.skeleton, this->skelanime.jointTable, this->skelanime.dListCount, - EnNiw_LimbDraw, NULL, &this->actor); + EnNiw_OverrideLimbDraw, NULL, &this->actor); EnNiw_DrawFeathers(this, globalCtx); } diff --git a/src/overlays/actors/ovl_En_Pamera/z_en_pamera.c b/src/overlays/actors/ovl_En_Pamera/z_en_pamera.c index 525606bc3..baf840980 100644 --- a/src/overlays/actors/ovl_En_Pamera/z_en_pamera.c +++ b/src/overlays/actors/ovl_En_Pamera/z_en_pamera.c @@ -553,7 +553,7 @@ s32 EnPamera_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dLi rot->x += this->limb9Rot.y; rot->z += this->limb9Rot.x; } - return 0; + return false; } void EnPamera_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { diff --git a/src/overlays/actors/ovl_En_Pametfrog/z_en_pametfrog.c b/src/overlays/actors/ovl_En_Pametfrog/z_en_pametfrog.c index 22f969379..e4456636b 100644 --- a/src/overlays/actors/ovl_En_Pametfrog/z_en_pametfrog.c +++ b/src/overlays/actors/ovl_En_Pametfrog/z_en_pametfrog.c @@ -1387,8 +1387,8 @@ static s8 limbPosIndex[] = { -1, -1, 0, -1, 1, -1, 2, -1, 3, -1, 4, -1, 5, 6, -1, 7, 8, 9, -1, 10, -1, 11, -1, -1, }; -void EnPametfrog_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* arg) { - EnPametfrog* this = (EnPametfrog*)arg; +void EnPametfrog_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { + EnPametfrog* this = THIS; Vec3f vec; Vec3s* center; s8 index; diff --git a/src/overlays/actors/ovl_En_Pm/z_en_pm.c b/src/overlays/actors/ovl_En_Pm/z_en_pm.c index df73227a2..04cc359b8 100644 --- a/src/overlays/actors/ovl_En_Pm/z_en_pm.c +++ b/src/overlays/actors/ovl_En_Pm/z_en_pm.c @@ -1809,8 +1809,8 @@ void EnPm_Update(Actor* thisx, GlobalContext* globalCtx) { } } -s32 func_80AFAA04(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx, - Gfx** gfx) { +s32 EnPm_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx, + Gfx** gfx) { EnPm* this = THIS; if (limbIndex == 15) { @@ -1819,7 +1819,7 @@ s32 func_80AFAA04(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* p return false; } -void func_80AFAA44(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx, Gfx** gfx) { +void EnPm_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx, Gfx** gfx) { EnPm* this = THIS; s32 pad; Vec3f sp2C; @@ -1854,7 +1854,7 @@ void func_80AFAA44(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* } } -void func_80AFABAC(GlobalContext* globalCtx, s32 arg1, Actor* thisx, Gfx** gfx) { +void EnPm_TransformLimbDraw(GlobalContext* globalCtx, s32 arg1, Actor* thisx, Gfx** gfx) { EnPm* this = THIS; s32 phi_v0; s32 phi_v1; @@ -1901,9 +1901,9 @@ void EnPm_Draw(Actor* thisx, GlobalContext* globalCtx) { gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(D_80AFB914[0])); - POLY_OPA_DISP = - func_8013AB00(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, - func_80AFAA04, func_80AFAA44, func_80AFABAC, &this->actor, POLY_OPA_DISP); + POLY_OPA_DISP = SubS_DrawTransformFlex(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, + this->skelAnime.dListCount, EnPm_OverrideLimbDraw, EnPm_PostLimbDraw, + EnPm_TransformLimbDraw, &this->actor, POLY_OPA_DISP); CLOSE_DISPS(globalCtx->state.gfxCtx); } diff --git a/src/overlays/actors/ovl_En_Po_Fusen/z_en_po_fusen.c b/src/overlays/actors/ovl_En_Po_Fusen/z_en_po_fusen.c index fe96f5a37..dae1f4e07 100644 --- a/src/overlays/actors/ovl_En_Po_Fusen/z_en_po_fusen.c +++ b/src/overlays/actors/ovl_En_Po_Fusen/z_en_po_fusen.c @@ -26,7 +26,7 @@ void EnPoFusen_Pop(EnPoFusen* this, GlobalContext* globalCtx); void EnPoFusen_Idle(EnPoFusen* this, GlobalContext* globalCtx); void EnPoFusen_IdleFuse(EnPoFusen* this, GlobalContext* globalCtx); s32 EnPoFusen_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, - Actor* arg); + Actor* thisx); extern AnimationHeader D_06000040; extern FlexSkeletonHeader D_060024F0; @@ -271,8 +271,8 @@ void EnPoFusen_Update(Actor* thisx, GlobalContext* globalCtx) { } s32 EnPoFusen_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, - Actor* arg) { - EnPoFusen* this = (EnPoFusen*)arg; + Actor* thisx) { + EnPoFusen* this = THIS; f32 zScale; f32 yScale; f32 xScale; @@ -307,18 +307,19 @@ s32 EnPoFusen_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dL rot->y += (s16)(this->limb9Rot * Math_SinS(this->randBaseRotChange)); rot->z += (s16)(this->limb9Rot * Math_CosS(this->randBaseRotChange)); } - return 0; + return false; } -void EnPoFusen_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* arg) { +void EnPoFusen_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { } -void EnPoFusen_UnkActorDraw(GlobalContext* globalCtx, s32 limbIndex, Actor* thisx) { +void EnPoFusen_TransformLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Actor* thisx) { } void EnPoFusen_Draw(Actor* thisx, GlobalContext* globalCtx) { EnPoFusen* this = THIS; func_8012C28C(globalCtx->state.gfxCtx); - func_801343C0(globalCtx, this->anime.skeleton, this->anime.jointTable, this->anime.dListCount, - EnPoFusen_OverrideLimbDraw, EnPoFusen_PostLimbDraw, EnPoFusen_UnkActorDraw, &this->actor); + SkelAnime_DrawTransformFlexOpa(globalCtx, this->anime.skeleton, this->anime.jointTable, this->anime.dListCount, + EnPoFusen_OverrideLimbDraw, EnPoFusen_PostLimbDraw, EnPoFusen_TransformLimbDraw, + &this->actor); } diff --git a/src/overlays/actors/ovl_En_Recepgirl/z_en_recepgirl.c b/src/overlays/actors/ovl_En_Recepgirl/z_en_recepgirl.c index baa7aadad..022e50dc2 100644 --- a/src/overlays/actors/ovl_En_Recepgirl/z_en_recepgirl.c +++ b/src/overlays/actors/ovl_En_Recepgirl/z_en_recepgirl.c @@ -200,7 +200,7 @@ s32 EnRecepgirl_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** return false; } -void EnRecepgirl_UnkLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Actor* thisx) { +void EnRecepgirl_TransformLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Actor* thisx) { EnRecepgirl* this = THIS; if (limbIndex == 5) { @@ -217,8 +217,9 @@ void EnRecepgirl_Draw(Actor* thisx, GlobalContext* globalCtx) { func_8012C28C(globalCtx->state.gfxCtx); gSPSegment(POLY_OPA_DISP++, 0x08, sEyeTextures[this->eyeTexIndex]); - func_801343C0(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, - EnRecepgirl_OverrideLimbDraw, NULL, EnRecepgirl_UnkLimbDraw, &this->actor); + SkelAnime_DrawTransformFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, + this->skelAnime.dListCount, EnRecepgirl_OverrideLimbDraw, NULL, + EnRecepgirl_TransformLimbDraw, &this->actor); CLOSE_DISPS(globalCtx->state.gfxCtx); } diff --git a/src/overlays/actors/ovl_En_Rsn/z_en_rsn.c b/src/overlays/actors/ovl_En_Rsn/z_en_rsn.c index 78af19c64..32b199da1 100644 --- a/src/overlays/actors/ovl_En_Rsn/z_en_rsn.c +++ b/src/overlays/actors/ovl_En_Rsn/z_en_rsn.c @@ -68,19 +68,19 @@ void EnRsn_Update(Actor* thisx, GlobalContext* globalCtx) { func_800E9250(globalCtx, &this->actor, &this->unk1D8, &this->unk1DE, this->actor.focus.pos); } -s32 EnRsn_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* arg) { - EnRsn* this = (EnRsn*)arg; +s32 EnRsn_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx) { + EnRsn* this = THIS; if (limbIndex == 14) { Matrix_InsertXRotation_s(this->unk1D8.y, MTXMODE_APPLY); } - return 0; + return false; } static Vec3f D_80C26028 = { 0.0f, 0.0f, 0.0f }; -void EnRsn_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* arg) { - EnRsn* this = (EnRsn*)arg; +void EnRsn_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { + EnRsn* this = THIS; Vec3f sp18 = D_80C26028; if (limbIndex == 14) { diff --git a/src/overlays/actors/ovl_En_Sellnuts/z_en_sellnuts.c b/src/overlays/actors/ovl_En_Sellnuts/z_en_sellnuts.c index e07b6895c..2a33601b8 100644 --- a/src/overlays/actors/ovl_En_Sellnuts/z_en_sellnuts.c +++ b/src/overlays/actors/ovl_En_Sellnuts/z_en_sellnuts.c @@ -1127,7 +1127,7 @@ s32 EnSellnuts_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** d void EnSellnuts_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { } -void func_80ADD7CC(GlobalContext* globalCtx, s32 limbIndex, Actor* thisx) { +void EnSellnuts_TransformLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Actor* thisx) { EnSellnuts* this = THIS; if (((this->unk_350 == 1) || (this->unk_350 == 3)) && ((limbIndex == 23) || (limbIndex == 24))) { @@ -1148,6 +1148,7 @@ void EnSellnuts_Draw(Actor* thisx, GlobalContext* globalCtx) { EnSellnuts* this = THIS; func_8012C28C(globalCtx->state.gfxCtx); - func_801343C0(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, - EnSellnuts_OverrideLimbDraw, EnSellnuts_PostLimbDraw, func_80ADD7CC, &this->actor); + SkelAnime_DrawTransformFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, + this->skelAnime.dListCount, EnSellnuts_OverrideLimbDraw, EnSellnuts_PostLimbDraw, + EnSellnuts_TransformLimbDraw, &this->actor); } diff --git a/src/overlays/actors/ovl_En_Suttari/z_en_suttari.c b/src/overlays/actors/ovl_En_Suttari/z_en_suttari.c index dc1064040..6777bd2d5 100644 --- a/src/overlays/actors/ovl_En_Suttari/z_en_suttari.c +++ b/src/overlays/actors/ovl_En_Suttari/z_en_suttari.c @@ -1525,7 +1525,7 @@ void EnSuttari_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList } } -void EnSuttari_UnkDraw(GlobalContext* globalCtx, s32 limbIndex, Actor* thisx) { +void EnSuttari_TransformLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Actor* thisx) { } void EnSuttari_Draw(Actor* thisx, GlobalContext* globalCtx) { @@ -1540,8 +1540,9 @@ void EnSuttari_Draw(Actor* thisx, GlobalContext* globalCtx) { gSPSegment(POLY_OPA_DISP++, 0x08, Gfx_EnvColor(globalCtx->state.gfxCtx, 255, 255, 255, 0)); gSPSegment(POLY_OPA_DISP++, 0x09, Gfx_EnvColor(globalCtx->state.gfxCtx, 55, 55, 255, 0)); gDPPipeSync(POLY_OPA_DISP++); - func_801343C0(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, - EnSuttari_OverrideLimbDraw, EnSuttari_PostLimbDraw, EnSuttari_UnkDraw, &this->actor); + SkelAnime_DrawTransformFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, + this->skelAnime.dListCount, EnSuttari_OverrideLimbDraw, EnSuttari_PostLimbDraw, + EnSuttari_TransformLimbDraw, &this->actor); if (this->flags1 & 0x80) { func_8012C2DC(globalCtx->state.gfxCtx); sp5C = this->actor.world.pos; diff --git a/src/overlays/actors/ovl_En_Tk/z_en_tk.c b/src/overlays/actors/ovl_En_Tk/z_en_tk.c index 102286a25..4ba5a32b7 100644 --- a/src/overlays/actors/ovl_En_Tk/z_en_tk.c +++ b/src/overlays/actors/ovl_En_Tk/z_en_tk.c @@ -1344,7 +1344,7 @@ void func_80AEF5F4(Actor* thisx, GlobalContext* globalCtx) { this->actionFunc(this, globalCtx); } -s32 func_80AEF65C(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx) { +s32 EnTk_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx) { EnTk* this = THIS; if (limbIndex == 16) { @@ -1354,7 +1354,7 @@ s32 func_80AEF65C(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* p return false; } -void func_80AEF6A4(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { +void EnTk_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { static Vec3f D_80AEFA84 = { 0.0f, 0.0f, 4600.0f }; EnTk* this = THIS; @@ -1394,7 +1394,7 @@ void EnTk_Draw(Actor* thisx, GlobalContext* globalCtx) { Matrix_RotateY(this->unk_318, MTXMODE_APPLY); SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, - func_80AEF65C, func_80AEF6A4, &this->actor); + EnTk_OverrideLimbDraw, EnTk_PostLimbDraw, &this->actor); CLOSE_DISPS(globalCtx->state.gfxCtx); } diff --git a/src/overlays/actors/ovl_En_Trt/z_en_trt.c b/src/overlays/actors/ovl_En_Trt/z_en_trt.c index 98bcf100b..17c85cb0e 100644 --- a/src/overlays/actors/ovl_En_Trt/z_en_trt.c +++ b/src/overlays/actors/ovl_En_Trt/z_en_trt.c @@ -1746,7 +1746,7 @@ s32 EnTrt_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, if (limbIndex == 14) { *dList = NULL; } - return 0; + return false; } void EnTrt_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { @@ -1767,7 +1767,7 @@ void EnTrt_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Ve } } -void EnTrt_UnkActorDraw(GlobalContext* globalCtx, s32 limbIndex, Actor* thisx) { +void EnTrt_TransformLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Actor* thisx) { EnTrt* this = THIS; if (limbIndex == 21) { @@ -1789,8 +1789,9 @@ void EnTrt_Draw(Actor* thisx, GlobalContext* globalCtx) { func_8012C28C(globalCtx->state.gfxCtx); gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(sEyeTextures[this->eyeTextureIdx])); gSPSegment(POLY_OPA_DISP++, 0x09, Lib_SegmentedToVirtual(sEyeTextures[this->eyeTextureIdx])); - func_801343C0(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, - EnTrt_OverrideLimbDraw, EnTrt_PostLimbDraw, EnTrt_UnkActorDraw, &this->actor); + SkelAnime_DrawTransformFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, + this->skelAnime.dListCount, EnTrt_OverrideLimbDraw, EnTrt_PostLimbDraw, + EnTrt_TransformLimbDraw, &this->actor); EnTrt_DrawCursor(globalCtx, this, this->cursorPos.x, this->cursorPos.y, this->cursorPos.z, this->drawCursor); EnTrt_DrawStickDirectionPrompt(globalCtx, this); diff --git a/src/overlays/actors/ovl_En_Tru/z_en_tru.c b/src/overlays/actors/ovl_En_Tru/z_en_tru.c index 74037ce2f..46ef78306 100644 --- a/src/overlays/actors/ovl_En_Tru/z_en_tru.c +++ b/src/overlays/actors/ovl_En_Tru/z_en_tru.c @@ -1192,7 +1192,7 @@ void EnTru_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Ve } } -void func_80A886D4(GlobalContext* globalCtx, s32 limbIndex, Actor* thisx) { +void EnTru_TransformLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Actor* thisx) { EnTru* this = THIS; s32 pad[3]; s32 sp2C; @@ -1250,8 +1250,9 @@ void EnTru_Draw(Actor* thisx, GlobalContext* globalCtx) { gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(D_80A8B408[this->unk_36E])); gSPSegment(POLY_OPA_DISP++, 0x09, Lib_SegmentedToVirtual(D_80A8B408[this->unk_36E])); - func_801343C0(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, - EnTru_OverrideLimbDraw, EnTru_PostLimbDraw, func_80A886D4, &this->actor); + SkelAnime_DrawTransformFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, + this->skelAnime.dListCount, EnTru_OverrideLimbDraw, EnTru_PostLimbDraw, + EnTru_TransformLimbDraw, &this->actor); func_80A85788(this->unk_394, globalCtx); func_80A85BCC(this->unk_394, globalCtx); func_80A85F84(this->unk_394, globalCtx); diff --git a/src/overlays/actors/ovl_En_Wf/z_en_wf.c b/src/overlays/actors/ovl_En_Wf/z_en_wf.c index a453e23e7..080aeeba5 100644 --- a/src/overlays/actors/ovl_En_Wf/z_en_wf.c +++ b/src/overlays/actors/ovl_En_Wf/z_en_wf.c @@ -1546,7 +1546,7 @@ void EnWf_Update(Actor* thisx, GlobalContext* globalCtx) { } } -s32 func_80993E50(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx) { +s32 EnWf_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx) { EnWf* this = THIS; if ((limbIndex == 17) || (limbIndex == 18)) { @@ -1555,7 +1555,7 @@ s32 func_80993E50(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* p return false; } -void func_80993E94(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { +void EnWf_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { static s8 D_809942FC[] = { -1, -1, -1, -1, -1, 0, 1, -1, -1, -1, -1, 2, -1, 3, 4, 5, 6, -1, -1, 7, 8, 9, }; @@ -1593,7 +1593,7 @@ void EnWf_Draw(Actor* thisx, GlobalContext* globalCtx) { CLOSE_DISPS(globalCtx->state.gfxCtx); SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, - this->skelAnime.dListCount, func_80993E50, func_80993E94, &this->actor); + this->skelAnime.dListCount, EnWf_OverrideLimbDraw, EnWf_PostLimbDraw, &this->actor); func_800BE680(globalCtx, &this->actor, this->unk_2B8, 10, this->unk_2B0, this->unk_2B4, this->unk_2AC, this->unk_296); } diff --git a/src/overlays/actors/ovl_En_Zog/z_en_zog.c b/src/overlays/actors/ovl_En_Zog/z_en_zog.c index 3306fc786..8effa1d67 100644 --- a/src/overlays/actors/ovl_En_Zog/z_en_zog.c +++ b/src/overlays/actors/ovl_En_Zog/z_en_zog.c @@ -997,7 +997,7 @@ void EnZog_Update(Actor* thisx, GlobalContext* globalCtx) { } } -void func_80B954C4(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { +void EnZog_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { static Vec3f D_80B959B8 = { 0.0f, 0.0f, 0.0f }; EnZog* this = THIS; @@ -1078,7 +1078,7 @@ void EnZog_Draw(Actor* thisx, GlobalContext* globalCtx) { POLY_OPA_DISP = &gfx[3]; SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, - this->skelAnime.dListCount, NULL, func_80B954C4, &this->actor); + this->skelAnime.dListCount, NULL, EnZog_PostLimbDraw, &this->actor); } CLOSE_DISPS(globalCtx->state.gfxCtx); diff --git a/tools/actorfixer.py b/tools/actorfixer.py index fc26e60e0..384821a55 100755 --- a/tools/actorfixer.py +++ b/tools/actorfixer.py @@ -385,6 +385,11 @@ animdict = { "func_800A81F0": "EffectBlure_AddVertex", "func_800A8514": "EffectBlure_AddSpace", "Effect_GetParams": "Effect_GetByIndex", + "func_801343C0": "SkelAnime_DrawTransformFlexOpa", + "func_80134148": "SkelAnime_DrawTransformFlexLimbOpa", + "func_8013AB00": "SubS_DrawTransformFlex", + "func_8013A860": "SubS_DrawTransformFlexLimb", + # Structs members "skelAnime.unk03": "skelAnime.taper", @@ -404,10 +409,10 @@ animdict = { "skelAnime.prevFramePos": "skelAnime.prevTransl", "skelAnime.unk3E": "skelAnime.baseTransl", "actor.minVelocityY": "actor.terminalVelocity", - "actor.yDistToWater" : "actor.depthInWater", + "actor.yDistToWater": "actor.depthInWater", "actor.yDistToPlayer": "actor.playerHeightRel", - "globalCtx->mf_187FC" : "globalCtx->billboardMtxF", - "globalCtx->projectionMatrix" : "globalCtx->viewProjectionMtxF", + "globalCtx->mf_187FC": "globalCtx->billboardMtxF", + "globalCtx->projectionMatrix": "globalCtx->viewProjectionMtxF", "player->unk_A87": "player->exchangeItemId", "player->leftHandActor": "player->heldActor", "player->unk_384": "player->getItemId", diff --git a/tools/disasm/functions.txt b/tools/disasm/functions.txt index f0caa1238..15147d8ef 100644 --- a/tools/disasm/functions.txt +++ b/tools/disasm/functions.txt @@ -2527,8 +2527,8 @@ 0x80133B3C:("SkelAnime_DrawOpa",), 0x80133CDC:("SkelAnime_DrawFlexLimbOpa",), 0x80133F28:("SkelAnime_DrawFlexOpa",), - 0x80134148:("func_80134148",), - 0x801343C0:("func_801343C0",), + 0x80134148:("SkelAnime_DrawTransformFlexLimbOpa",), + 0x801343C0:("SkelAnime_DrawTransformFlexOpa",), 0x80134600:("SkelAnime_GetFrameData",), 0x80134724:("Animation_GetLength",), 0x80134748:("Animation_GetLastFrame",), @@ -2656,8 +2656,8 @@ 0x8013A504:("func_8013A504",), 0x8013A530:("func_8013A530",), 0x8013A7C0:("SubS_FindDoor",), - 0x8013A860:("func_8013A860",), - 0x8013AB00:("func_8013AB00",), + 0x8013A860:("SubS_DrawTransformFlexLimb",), + 0x8013AB00:("SubS_DrawTransformFlex",), 0x8013AD6C:("func_8013AD6C",), 0x8013AD9C:("func_8013AD9C",), 0x8013AED4:("func_8013AED4",), @@ -5441,7 +5441,7 @@ 0x808925F8:("EnNiw_LandBeforeIdle",), 0x8089262C:("EnNiw_CheckRage",), 0x808927CC:("EnNiw_Update",), - 0x80892E70:("EnNiw_LimbDraw",), + 0x80892E70:("EnNiw_OverrideLimbDraw",), 0x80892FA0:("EnNiw_Draw",), 0x80893008:("EnNiw_SpawnFeather",), 0x808930FC:("EnNiw_UpdateFeather",), @@ -6066,8 +6066,8 @@ 0x808BE6C4:("func_808BE6C4",), 0x808BE73C:("func_808BE73C",), 0x808BEA48:("EnDekunuts_Update",), - 0x808BEBD0:("func_808BEBD0",), - 0x808BED30:("func_808BED30",), + 0x808BEBD0:("EnDekunuts_OverrideLimbDraw",), + 0x808BED30:("EnDekunuts_PostLimbDraw",), 0x808BEE38:("EnDekunuts_Draw",), 0x808BF220:("EnBbfall_Init",), 0x808BF318:("EnBbfall_Destroy",), @@ -7509,8 +7509,8 @@ 0x80943BC0:("func_80943BC0",), 0x80943BDC:("func_80943BDC",), 0x80943CA4:("EnDaiku_Update",), - 0x80943E18:("func_80943E18",), - 0x80943E60:("func_80943E60",), + 0x80943E18:("EnDaiku_OverrideLimbDraw",), + 0x80943E60:("EnDaiku_PostLimbDraw",), 0x80943EE4:("EnDaiku_Draw",), 0x809441E0:("EnNwc_Init",), 0x80944310:("EnNwc_Destroy",), @@ -7625,9 +7625,9 @@ 0x809510E4:("EnGm_Init",), 0x80951224:("EnGm_Destroy",), 0x80951264:("EnGm_Update",), - 0x809513AC:("func_809513AC",), - 0x809514BC:("func_809514BC",), - 0x80951594:("func_80951594",), + 0x809513AC:("EnGm_OverrideLimbDraw",), + 0x809514BC:("EnGm_PostLimbDraw",), + 0x80951594:("EnGm_TransformLimbDraw",), 0x80951748:("EnGm_Draw",), 0x80952620:("EnMs_Init",), 0x80952708:("EnMs_Destroy",), @@ -8351,8 +8351,8 @@ 0x8098BCA8:("EnDg_Init",), 0x8098BE18:("EnDg_Destroy",), 0x8098BE44:("EnDg_Update",), - 0x8098BFB8:("func_8098BFB8",), - 0x8098BFD4:("func_8098BFD4",), + 0x8098BFB8:("EnDg_OverrideLimbDraw",), + 0x8098BFD4:("EnDg_PostLimbDraw",), 0x8098C06C:("EnDg_Draw",), 0x8098CA20:("func_8098CA20",), 0x8098CAD0:("func_8098CAD0",), @@ -8478,8 +8478,8 @@ 0x80993738:("func_80993738",), 0x8099386C:("func_8099386C",), 0x80993BC0:("EnWf_Update",), - 0x80993E50:("func_80993E50",), - 0x80993E94:("func_80993E94",), + 0x80993E50:("EnWf_OverrideLimbDraw",), + 0x80993E94:("EnWf_PostLimbDraw",), 0x80993F68:("EnWf_Draw",), 0x8099408C:("func_8099408C",), 0x809947B0:("func_809947B0",), @@ -9033,7 +9033,7 @@ 0x809C339C:("EnAob01_Update",), 0x809C33D8:("EnAob01_OverrideLimbDraw",), 0x809C35B4:("EnAob01_PostLimbDraw",), - 0x809C35F4:("EnAob01_UnkDraw",), + 0x809C35F4:("EnAob01_TransformLimbDraw",), 0x809C3608:("EnAob01_Draw",), 0x809C3D80:("EnBoj01_Init",), 0x809C3D90:("EnBoj01_Destroy",), @@ -9743,7 +9743,7 @@ 0x80A159B0:("EnGo_Update",), 0x80A15B80:("func_80A15B80",), 0x80A15D04:("EnGo_OverrideLimbDraw",), - 0x80A15E38:("EnGo_UnkDraw",), + 0x80A15E38:("EnGo_TransfromLimbDraw",), 0x80A15FEC:("func_80A15FEC",), 0x80A16D40:("func_80A16D40",), 0x80A16D6C:("func_80A16D6C",), @@ -10118,9 +10118,9 @@ 0x80A2EAAC:("DmSa_Destroy",), 0x80A2EABC:("DmSa_DoNothing",), 0x80A2EACC:("DmSa_Update",), - 0x80A2EB10:("func_80A2EB10",), - 0x80A2EB2C:("func_80A2EB2C",), - 0x80A2EB44:("func_80A2EB44",), + 0x80A2EB10:("DmSa_OverrideLimbDraw",), + 0x80A2EB2C:("DmSa_PostLimbDraw",), + 0x80A2EB44:("DmSa_TransformLimbDraw",), 0x80A2EB58:("func_80A2EB58",), 0x80A2EBB0:("func_80A2EBB0",), 0x80A2EBE8:("DmSa_Draw",), @@ -11249,7 +11249,7 @@ 0x80A884E8:("EnTru_Update",), 0x80A885B8:("EnTru_OverrideLimbDraw",), 0x80A88698:("EnTru_PostLimbDraw",), - 0x80A886D4:("func_80A886D4",), + 0x80A886D4:("EnTru_TransformLimbDraw",), 0x80A887E4:("EnTru_Draw",), 0x80A8B770:("EnTrt_ChangeAnim",), 0x80A8B80C:("EnTrt_TestItemSelected",), @@ -11331,7 +11331,7 @@ 0x80A8FA00:("EnTrt_UpdateHeadPosAndRot",), 0x80A8FB34:("EnTrt_OverrideLimbDraw",), 0x80A8FBB4:("EnTrt_PostLimbDraw",), - 0x80A8FC64:("EnTrt_UnkActorDraw",), + 0x80A8FC64:("EnTrt_TransformLimbDraw",), 0x80A8FCE0:("EnTrt_Draw",), 0x80A903B0:("EnTest5_SetupAction",), 0x80A903BC:("EnTest5_Init",), @@ -12328,7 +12328,7 @@ 0x80ADD400:("EnSellnuts_Update",), 0x80ADD4E0:("func_80ADD4E0",), 0x80ADD7B4:("func_80ADD7B4",), - 0x80ADD7CC:("func_80ADD7CC",), + 0x80ADD7CC:("EnSellnuts_TransformLimbDraw",), 0x80ADD8A4:("EnSellnuts_Draw",), 0x80ADE230:("func_80ADE230",), 0x80ADE5A4:("BgDkjailIvy_Init",), @@ -12604,8 +12604,8 @@ 0x80AEF2D8:("func_80AEF2D8",), 0x80AEF3E8:("EnTk_Update",), 0x80AEF5F4:("func_80AEF5F4",), - 0x80AEF65C:("func_80AEF65C",), - 0x80AEF6A4:("func_80AEF6A4",), + 0x80AEF65C:("EnTk_OverrideLimbDraw",), + 0x80AEF6A4:("EnTk_PostLimbDraw",), 0x80AEF734:("EnTk_Draw",), 0x80AF0060:("BgMarketStep_Init",), 0x80AF0088:("BgMarketStep_Draw",), @@ -12772,9 +12772,9 @@ 0x80AFA7A8:("EnPm_Init",), 0x80AFA8B0:("EnPm_Destroy",), 0x80AFA8F0:("EnPm_Update",), - 0x80AFAA04:("func_80AFAA04",), - 0x80AFAA44:("func_80AFAA44",), - 0x80AFABAC:("func_80AFABAC",), + 0x80AFAA04:("EnPm_OverrideLimbDraw",), + 0x80AFAA44:("EnPm_PostLimbDraw",), + 0x80AFABAC:("EnPm_TransformLimbDraw",), 0x80AFACAC:("EnPm_Draw",), 0x80AFC960:("func_80AFC960",), 0x80AFCA94:("EnGakufu_Init",), @@ -13633,8 +13633,8 @@ 0x80B3D7B8:("EnDnp_Destroy",), 0x80B3D7E4:("EnDnp_Update",), 0x80B3D974:("func_80B3D974",), - 0x80B3DA88:("func_80B3DA88",), - 0x80B3DAA0:("func_80B3DAA0",), + 0x80B3DA88:("EnDnp_PostLimbDraw",), + 0x80B3DAA0:("EnDnp_TransformLimbDraw",), 0x80B3DB98:("EnDnp_Draw",), 0x80B3DFF0:("func_80B3DFF0",), 0x80B3E168:("func_80B3E168",), @@ -13657,9 +13657,9 @@ 0x80B3F318:("EnDai_Init",), 0x80B3F494:("EnDai_Destroy",), 0x80B3F4A4:("EnDai_Update",), - 0x80B3F598:("func_80B3F598",), - 0x80B3F614:("func_80B3F614",), - 0x80B3F6EC:("func_80B3F6EC",), + 0x80B3F598:("EnDai_OverrideLimbDraw",), + 0x80B3F614:("EnDai_PostLimbDraw",), + 0x80B3F6EC:("EnDai_TransformLimbDraw",), 0x80B3F78C:("func_80B3F78C",), 0x80B3F920:("func_80B3F920",), 0x80B3FB84:("EnDai_Draw",), @@ -14870,7 +14870,7 @@ 0x80B95128:("func_80B95128",), 0x80B95240:("func_80B95240",), 0x80B95260:("EnZog_Update",), - 0x80B954C4:("func_80B954C4",), + 0x80B954C4:("EnZog_PostLimbDraw",), 0x80B95598:("func_80B95598",), 0x80B95668:("EnZog_Draw",), 0x80B95E20:("func_80B95E20",), @@ -15247,7 +15247,7 @@ 0x80BAE108:("EnSuttari_Update",), 0x80BAE250:("EnSuttari_OverrideLimbDraw",), 0x80BAE3C4:("EnSuttari_PostLimbDraw",), - 0x80BAE524:("EnSuttari_UnkDraw",), + 0x80BAE524:("EnSuttari_TransformLimbDraw",), 0x80BAE538:("EnSuttari_Draw",), 0x80BAEF70:("EnZod_Init",), 0x80BAF1C0:("EnZod_Destroy",), @@ -15326,7 +15326,7 @@ 0x80BB3728:("func_80BB3728",), 0x80BB3860:("EnGeg_OverrideLimbDraw",), 0x80BB387C:("EnGeg_PostLimbDraw",), - 0x80BB39F8:("EnGeg_UnkDraw",), + 0x80BB39F8:("EnGeg_TransformLimbDraw",), 0x80BB3BE0:("func_80BB3BE0",), 0x80BB3CB4:("func_80BB3CB4",), 0x80BB3E0C:("EnGeg_Draw",), @@ -16274,7 +16274,7 @@ 0x80BEFF34:("EnAkindonuts_Update",), 0x80BEFFB4:("EnAkindonuts_OverrideLimbDraw",), 0x80BF0178:("EnAkindonuts_PostLimbDraw",), - 0x80BF0190:("EnAkindonuts_UnkActorDraw",), + 0x80BF0190:("EnAkindonuts_TransformLimbDraw",), 0x80BF0258:("EnAkindonuts_Draw",), 0x80BF0D90:("EffStk_Init",), 0x80BF0DD0:("EffStk_Destroy",), @@ -16745,7 +16745,7 @@ 0x80C102D4:("EnRecepgirl_Talk",), 0x80C104E8:("EnRecepgirl_Update",), 0x80C10558:("EnRecepgirl_OverrideLimbDraw",), - 0x80C10590:("EnRecepgirl_UnkLimbDraw",), + 0x80C10590:("EnRecepgirl_TransformLimbDraw",), 0x80C105EC:("EnRecepgirl_Draw",), 0x80C10770:("EnThiefbird_Init",), 0x80C10958:("EnThiefbird_Destroy",), @@ -16972,7 +16972,7 @@ 0x80C1E048:("DmNb_Init",), 0x80C1E0F8:("DmNb_Destroy",), 0x80C1E108:("DmNb_Update",), - 0x80C1E168:("DmNb_UnkActorDraw",), + 0x80C1E168:("DmNb_TransformLimbDraw",), 0x80C1E17C:("DmNb_Draw",), 0x80C1E290:("func_80C1E290",), 0x80C1E2D4:("func_80C1E2D4",), @@ -17090,7 +17090,7 @@ 0x80C23980:("func_80C23980",), 0x80C2399C:("func_80C2399C",), 0x80C239C8:("EnEndingHero5_Update",), - 0x80C23A30:("func_80C23A30",), + 0x80C23A30:("EnEndingHero5_PostLimbDraw",), 0x80C23A7C:("EnEndingHero5_Draw",), 0x80C23C90:("EnEndingHero6_Init",), 0x80C23D50:("EnEndingHero6_Destroy",), diff --git a/tools/sizes/code_functions.csv b/tools/sizes/code_functions.csv index 31ad65d9f..22244cad7 100644 --- a/tools/sizes/code_functions.csv +++ b/tools/sizes/code_functions.csv @@ -2041,8 +2041,8 @@ asm/non_matchings/code/z_skelanime/SkelAnime_DrawLimb.s,SkelAnime_DrawLimb,0x801 asm/non_matchings/code/z_skelanime/SkelAnime_Draw.s,SkelAnime_Draw,0x80133B3C,0x68 asm/non_matchings/code/z_skelanime/SkelAnime_DrawLimbSV.s,SkelAnime_DrawLimbSV,0x80133CDC,0x93 asm/non_matchings/code/z_skelanime/SkelAnime_DrawFlexOpa.s,SkelAnime_DrawFlexOpa,0x80133F28,0x88 -asm/non_matchings/code/z_skelanime/func_80134148.s,func_80134148,0x80134148,0x9E -asm/non_matchings/code/z_skelanime/func_801343C0.s,func_801343C0,0x801343C0,0x90 +asm/non_matchings/code/z_skelanime/SkelAnime_DrawTransformFlexLimbOpa.s,SkelAnime_DrawTransformFlexLimbOpa,0x80134148,0x9E +asm/non_matchings/code/z_skelanime/SkelAnime_DrawTransformFlexOpa.s,SkelAnime_DrawTransformFlexOpa,0x801343C0,0x90 asm/non_matchings/code/z_skelanime/SkelAnime_AnimateFrame.s,SkelAnime_AnimateFrame,0x80134600,0x49 asm/non_matchings/code/z_skelanime/SkelAnime_GetTotalFrames.s,SkelAnime_GetTotalFrames,0x80134724,0x9 asm/non_matchings/code/z_skelanime/Animation_GetLastFrame.s,Animation_GetLastFrame,0x80134748,0xB @@ -2170,8 +2170,8 @@ asm/non_matchings/code/z_snap/func_8013A4C4.s,func_8013A4C4,0x8013A4C4,0x10 asm/non_matchings/code/z_snap/func_8013A504.s,func_8013A504,0x8013A504,0xB asm/non_matchings/code/z_snap/func_8013A530.s,func_8013A530,0x8013A530,0xA4 asm/non_matchings/code/z_sub_s/SubS_FindDoor.s,SubS_FindDoor,0x8013A7C0,0x28 -asm/non_matchings/code/z_sub_s/func_8013A860.s,func_8013A860,0x8013A860,0xA8 -asm/non_matchings/code/z_sub_s/func_8013AB00.s,func_8013AB00,0x8013AB00,0x9B +asm/non_matchings/code/z_sub_s/SubS_DrawTransformFlexLimb.s,SubS_DrawTransformFlexLimb,0x8013A860,0xA8 +asm/non_matchings/code/z_sub_s/SubS_DrawTransformFlex.s,SubS_DrawTransformFlex,0x8013AB00,0x9B asm/non_matchings/code/z_sub_s/func_8013AD6C.s,func_8013AD6C,0x8013AD6C,0xC asm/non_matchings/code/z_sub_s/func_8013AD9C.s,func_8013AD9C,0x8013AD9C,0x4E asm/non_matchings/code/z_sub_s/func_8013AED4.s,func_8013AED4,0x8013AED4,0xB From 0da2ed135b004aa75b0fc9863688e2de9a45fdbd Mon Sep 17 00:00:00 2001 From: EllipticEllipsis <73679967+EllipticEllipsis@users.noreply.github.com> Date: Mon, 17 Jan 2022 01:05:00 +0000 Subject: [PATCH 13/13] git subrepo pull (merge) --force tools/ZAPD (#618) subrepo: subdir: "tools/ZAPD" merged: "0ba781304" upstream: origin: "https://github.com/zeldaret/ZAPD.git" branch: "master" commit: "0ba781304" git-subrepo: version: "0.4.3" origin: "https://github.com/ingydotnet/git-subrepo.git" commit: "2f68596" --- tools/ZAPD/.gitrepo | 4 ++-- tools/ZAPD/ZAPD/ZTexture.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/ZAPD/.gitrepo b/tools/ZAPD/.gitrepo index 7576be8e0..a57e9e52c 100644 --- a/tools/ZAPD/.gitrepo +++ b/tools/ZAPD/.gitrepo @@ -6,7 +6,7 @@ [subrepo] remote = https://github.com/zeldaret/ZAPD.git branch = master - commit = bf16ff7c4c409358a53793b72260b1d8e474cf0c - parent = a7cc87394ed4afb5ebe1f2318526545b6bbe205d + commit = 0ba78130478ee1272bc0e2f2fec2d162e7f7f995 + parent = aa90d1ee2be577fb8a18c1c3c6dcafda2e732190 method = merge cmdver = 0.4.3 diff --git a/tools/ZAPD/ZAPD/ZTexture.cpp b/tools/ZAPD/ZAPD/ZTexture.cpp index 0d72d9c5a..255d30886 100644 --- a/tools/ZAPD/ZAPD/ZTexture.cpp +++ b/tools/ZAPD/ZAPD/ZTexture.cpp @@ -722,7 +722,7 @@ void ZTexture::Save(const fs::path& outFolder) if (!Directory::Exists(outPath.string())) Directory::CreateDirectory(outPath.string()); - std::filesystem::__cxx11::path outFileName; + fs::path outFileName; if (!dWordAligned) outFileName = outPath / (outName + ".u32" + "." + GetExternalExtension() + ".png");