From eee73de42aebc57b07dd283e25e6be1a3542934f Mon Sep 17 00:00:00 2001 From: "H.M. Burger" <92937601+Onenutmcgee@users.noreply.github.com> Date: Wed, 20 Nov 2024 13:28:11 -0600 Subject: [PATCH] Decompile tt_003 func_us_801744CC and func_us_80176564 (#1920) Very similar to a combination of the Faerie and the Bat. --- config/splat.us.tt_003.yaml | 3 +- config/symbols.us.tt_003.txt | 9 +++ src/servant/tt_003/demon.c | 145 +++++++++++++++++++++++++++++++++-- 3 files changed, 150 insertions(+), 7 deletions(-) diff --git a/config/splat.us.tt_003.yaml b/config/splat.us.tt_003.yaml index 826cdc1ff..646b7f57f 100644 --- a/config/splat.us.tt_003.yaml +++ b/config/splat.us.tt_003.yaml @@ -38,7 +38,8 @@ segments: align: 4 subalign: 4 subsegments: - - [0x0, data] + - [0x0, .data, demon] + - [0x40, data] - [0x29DC, .rodata, demon] - [0x2A68, c, demon] - [0x83C4, sbss] diff --git a/config/symbols.us.tt_003.txt b/config/symbols.us.tt_003.txt index 5f0f31276..7da9dce51 100644 --- a/config/symbols.us.tt_003.txt +++ b/config/symbols.us.tt_003.txt @@ -1,4 +1,8 @@ +g_DemonSpriteParts = 0x80170040; +g_ServantClut = 0x80171990; g_DemonAbilityStats = 0x80171A68; +g_DemonClut = 0x80171C24; +s_PassthroughFunctions = 0x80171CC4; g_DemonAnimationFrames = 0x80172010; g_Events = 0x80172090; g_PlaySfxStep = 0x801729C0; @@ -10,8 +14,12 @@ g_CurrentRoomY = 0x801729D8; SetAnimationFrame = 0x80172A68; FindValidTarget = 0x80172A9C; CheckEntityValid = 0x80172D50; +unused_2DBC = 0x80172DBC; DestroyEntityPassthrough = 0x80172ED8; +ServantInit = 0x801744CC; +UpdateServantDefault = 0x8017472C; UpdateServantSfxPassthrough = 0x80176544; +FunctionPointerPassthrough = 0x80176564; ServantUpdateAnim = 0x80177750; DestroyEntity = 0x801778F8; AccumulateTowardZero = 0x80177964; @@ -26,5 +34,6 @@ IsMovementAllowed = 0x8017818C; CheckAllEntitiesValid = 0x801782A4; ServantUnk0 = 0x80178350; s_TargetMatch = 0x801783C4; +s_ServantId = 0x80178690; s_DemonStats = 0x80178694; s_LastTargetedEntityIndex = 0x801786E0; diff --git a/src/servant/tt_003/demon.c b/src/servant/tt_003/demon.c index aebc79f95..12b804e8b 100644 --- a/src/servant/tt_003/demon.c +++ b/src/servant/tt_003/demon.c @@ -8,6 +8,49 @@ extern s32 g_DemonAbilityStats[10][4]; extern FamiliarStats s_DemonStats; extern s32 s_LastTargetedEntityIndex; extern AnimationFrame* g_DemonAnimationFrames[]; +extern s32 s_ServantId; +extern u16 g_DemonClut[64]; +extern SpriteParts* g_DemonSpriteParts[]; +extern s32 D_us_801786D0; +extern s32 D_us_801786D4; + +extern void (*s_PassthroughFunctions[])(Entity*); + +void ServantInit(InitializeMode); +void UpdateServantDefault(Entity*); +void func_us_80174FD0(Entity*); +void func_us_8017540C(Entity*); +void unused_5800(Entity*); +void unused_5808(Entity*); +void func_us_80175810(Entity*); +void func_us_80175C08(Entity*); +void func_us_80175D20(Entity*); +void UpdateServantSfxPassthrough(Entity*); +void FunctionPointerPassthrough(Entity*); +void func_us_801765A0(Entity*); +void func_us_80176814(Entity*); +void func_us_80176C1C(Entity*); +void func_us_801771B0(Entity*); +void func_us_80177690(Entity*); + +ServantDesc demon_ServantDesc = { + ServantInit, + UpdateServantDefault, + func_us_80174FD0, + func_us_8017540C, + unused_5800, + unused_5808, + func_us_80175810, + func_us_80175C08, + func_us_80175D20, + UpdateServantSfxPassthrough, + FunctionPointerPassthrough, + func_us_801765A0, + func_us_80176814, + func_us_80176C1C, + func_us_801771B0, + func_us_80177690, +}; static void SetAnimationFrame(Entity* self, s32 animationIndex) { if (self->anim != g_DemonAnimationFrames[animationIndex]) { @@ -101,7 +144,7 @@ static Entity* FindValidTarget(Entity* self) { #include "../check_entity_valid.h" -void func_us_80172DBC(void) {} +void unused_2DBC(void) {} INCLUDE_ASM("servant/tt_003/nonmatchings/demon", func_us_80172DC4); @@ -115,17 +158,105 @@ INCLUDE_ASM("servant/tt_003/nonmatchings/demon", func_us_801737F0); INCLUDE_ASM("servant/tt_003/nonmatchings/demon", func_us_80173D14); -INCLUDE_ASM("servant/tt_003/nonmatchings/demon", func_us_801744CC); +void ServantInit(InitializeMode mode) { + u16* src; + u16* dst; + RECT rect; + s32 i; + SpriteParts** spriteBanks; + Entity* entity; -INCLUDE_ASM("servant/tt_003/nonmatchings/demon", func_us_8017472C); +#ifdef VERSION_PC + const int lenServant = LEN(g_ServantClut); + const int lenDemon = LEN(g_DemonClut); +#else + const int lenServant = 256; + const int lenDemon = 80; +#endif + + s_ServantId = g_Servant; + + if ((mode == MENU_SWITCH_SERVANT) || (mode == MENU_SAME_SERVANT)) { + ProcessEvent(NULL, true); + if (mode == MENU_SAME_SERVANT) { + return; + } + } + + dst = &g_Clut[CLUT_INDEX_SERVANT]; + src = g_ServantClut; + for (i = 0; i < lenServant; i++) { + *dst++ = *src++; + } + + dst = &g_Clut[CLUT_INDEX_SERVANT_OVERWRITE]; + src = g_DemonClut; + + for (i = 0; i < lenDemon; i++) { + *dst++ = *src++; + } + + rect.x = 0; + rect.w = 0x100; + rect.h = 1; + rect.y = 0xF4; + + dst = &g_Clut[CLUT_INDEX_SERVANT]; + LoadImage(&rect, (u_long*)dst); + + spriteBanks = g_api.o.spriteBanks; + spriteBanks += 20; + *spriteBanks = (SpriteParts*)g_DemonSpriteParts; + + entity = &g_Entities[SERVANT_ENTITY_INDEX]; + + DestroyEntity(entity); + entity->unk5A = 0x6C; + entity->palette = 0x140; + entity->animSet = ANIMSET_OVL(20); + entity->zPriority = PLAYER.zPriority - 2; + entity->facingLeft = PLAYER.facingLeft; + entity->params = 0; + + if (mode == MENU_SWITCH_SERVANT) { + if (LOW(D_8003C708.flags) & + (LAYOUT_RECT_PARAMS_UNKNOWN_20 | LAYOUT_RECT_PARAMS_UNKNOWN_40)) { + entity->entityId = 0xD1; + } else { + entity->entityId = 0xD8; + } + entity->posX.val = FIX(128); + entity->posY.val = FIX(-32); + } else { + entity->entityId = 0xD1; + if (D_8003C708.flags & LAYOUT_RECT_PARAMS_UNKNOWN_20) { + if (ServantUnk0()) { + entity->posX.val = FIX(192); + } else { + entity->posX.val = FIX(64); + } + entity->posY.val = FIX(160); + } else { + entity->posX.val = + PLAYER.posX.val + (PLAYER.facingLeft ? FIX(24) : FIX(-24)); + entity->posY.val = PLAYER.posY.val + FIX(-32); + } + } + + D_us_801786D0 = 0; + D_us_801786D4 = 0; + g_api.GetServantStats(entity, 0, 0, &s_DemonStats); +} + +INCLUDE_ASM("servant/tt_003/nonmatchings/demon", UpdateServantDefault); INCLUDE_ASM("servant/tt_003/nonmatchings/demon", func_us_80174FD0); INCLUDE_ASM("servant/tt_003/nonmatchings/demon", func_us_8017540C); -void func_us_80175800(void) {} +void unused_5800(Entity* self) {} -void func_us_80175808(void) {} +void unused_5808(Entity* self) {} INCLUDE_ASM("servant/tt_003/nonmatchings/demon", func_us_80175810); @@ -135,7 +266,9 @@ INCLUDE_ASM("servant/tt_003/nonmatchings/demon", func_us_80175D20); void UpdateServantSfxPassthrough(Entity* self) { ProcessSfxState(self); } -INCLUDE_ASM("servant/tt_003/nonmatchings/demon", func_us_80176564); +void FunctionPointerPassthrough(Entity* arg0) { + s_PassthroughFunctions[arg0->params](arg0); +} INCLUDE_ASM("servant/tt_003/nonmatchings/demon", func_us_801765A0);