From aed063840fc047f920caef1f984a8afb12d514f1 Mon Sep 17 00:00:00 2001 From: Reonu Date: Sat, 19 Apr 2025 19:09:34 +0100 Subject: [PATCH] Patch AnimationContext_SetLoadFrame to allow custom animations --- patches/memory_patches.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/patches/memory_patches.c b/patches/memory_patches.c index 9033993..4fbfe55 100644 --- a/patches/memory_patches.c +++ b/patches/memory_patches.c @@ -10,3 +10,33 @@ RECOMP_PATCH void* Lib_SegmentedToVirtual(void* ptr) { return SEGMENTED_TO_K0(ptr); } } + +AnimationEntry* AnimationContext_AddEntry(AnimationContext* animationCtx, AnimationType type); +#define LINK_ANIMETION_OFFSET(addr, offset) \ + (SEGMENT_ROM_START(link_animetion) + ((uintptr_t)addr & 0xFFFFFF) + ((u32)offset)) + +// @recomp Skip the DMA if the animation is already in RAM. Allows mods to play custom animations. +RECOMP_PATCH void AnimationContext_SetLoadFrame(PlayState* play, PlayerAnimationHeader* animation, s32 frame, s32 limbCount, + Vec3s* frameTable) { + AnimationEntry* task = AnimationContext_AddEntry(&play->animationCtx, ANIMATION_LINKANIMETION); + + if (task != NULL) { + PlayerAnimationHeader* playerAnimHeader = Lib_SegmentedToVirtual(animation); + s32 pad; + + osCreateMesgQueue(&task->data.load.msgQueue, task->data.load.msg, + ARRAY_COUNT(task->data.load.msg)); + + if (IS_KSEG0(playerAnimHeader->linkAnimSegment)) { + osSendMesg(&task->data.load.msgQueue, NULL, OS_MESG_NOBLOCK); + Lib_MemCpy(frameTable, ((u8*)playerAnimHeader->segmentVoid) + (sizeof(Vec3s) * limbCount + sizeof(s16)) * frame, + sizeof(Vec3s) * limbCount + sizeof(s16)); + } + else { + DmaMgr_SendRequestImpl( + &task->data.load.req, frameTable, + LINK_ANIMETION_OFFSET(playerAnimHeader->linkAnimSegment, (sizeof(Vec3s) * limbCount + sizeof(s16)) * frame), + sizeof(Vec3s) * limbCount + sizeof(s16), 0, &task->data.load.msgQueue, NULL); + } + } +}