diff options
| author | Aly Cerruti <aprime2003@gmail.com> | 2021-07-28 09:51:12 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-07-28 12:51:12 -0400 |
| commit | 6f7312a3480f722425f31fcacbd031c1155bc4d6 (patch) | |
| tree | 5d457a50935afbeec2a9b6dc99360ea7b60db1f2 /src | |
| parent | 5c147e5e03e9d693213537101f56d3a6eb53f16a (diff) | |
Dancing Couple (ovl_En_Tg) (#866)
* Match EnTg_Destroy
* Match EnTg_Init
* Matching EnTg_Update
* Match func_80B18360
Moving both 'return phi;'s into a single return at the end of the function causes the assembly to not match.
* Probably equivalent, non-matching func_80B183F8
* Matching EnTg_Draw
* Matching update function
* Matching func_80B18778
* All functions decompiled
* Move data to C code
* All functions matched excepted weird switch/case
* Last matching function
* Remove unused ASM
* Name obvious symbols
* Clang format
* Name text-related functions and variables
* Describe actor as Dancing Couple
See https://github.com/zeldaret/oot/pull/866#discussion_r664726581
* Use named constants
* Name drawing constants
* Use THIS macro for void*
* Name the function that sets environment color
* Add comments to parts of code that aren't clear
* Rename timesSpokenTo to nextDialogue, treat isTalking as boolean
Diffstat (limited to 'src')
| -rw-r--r-- | src/overlays/actors/ovl_En_Tg/z_en_tg.c | 193 | ||||
| -rw-r--r-- | src/overlays/actors/ovl_En_Tg/z_en_tg.h | 9 |
2 files changed, 167 insertions, 35 deletions
diff --git a/src/overlays/actors/ovl_En_Tg/z_en_tg.c b/src/overlays/actors/ovl_En_Tg/z_en_tg.c index 7188b70fe..b4f6578a9 100644 --- a/src/overlays/actors/ovl_En_Tg/z_en_tg.c +++ b/src/overlays/actors/ovl_En_Tg/z_en_tg.c @@ -1,10 +1,11 @@ /* * File: z_en_tg.c * Overlay: ovl_En_Tg - * Description: Honey & Darling + * Description: Dancing Couple */ #include "z_en_tg.h" +#include "objects/object_mu/object_mu.h" #define FLAGS 0x00000009 @@ -15,23 +16,9 @@ void EnTg_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnTg_Update(Actor* thisx, GlobalContext* globalCtx); void EnTg_Draw(Actor* thisx, GlobalContext* globalCtx); -extern UNK_TYPE D_06005040; -extern UNK_TYPE D_0600AE40; +void EnTg_SpinIfNotTalking(EnTg* this, GlobalContext* globalCtx); -/* -const ActorInit En_Tg_InitVars = { - ACTOR_EN_TG, - ACTORCAT_NPC, - FLAGS, - OBJECT_MU, - sizeof(EnTg), - (ActorFunc)EnTg_Init, - (ActorFunc)EnTg_Destroy, - (ActorFunc)EnTg_Update, - (ActorFunc)EnTg_Draw, -}; - -static ColliderCylinderInit D_80B18910 = { +static ColliderCylinderInit sCylinderInit = { { COLTYPE_NONE, AT_NONE, @@ -50,23 +37,161 @@ static ColliderCylinderInit D_80B18910 = { }, { 20, 64, 0, { 0, 0, 0 } }, }; -*/ -#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Tg/func_80B18360.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Tg/func_80B183F8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Tg/EnTg_Init.s") -#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Tg/EnTg_Destroy.s") +static CollisionCheckInfoInit2 sColChkInfoInit = { 0, 0, 0, 0, MASS_IMMOVABLE }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Tg/func_80B185C0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Tg/EnTg_Update.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Tg/func_80B18704.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Tg/func_80B1871C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Tg/func_80B18778.s") +const ActorInit En_Tg_InitVars = { + ACTOR_EN_TG, + ACTORCAT_NPC, + FLAGS, + OBJECT_MU, + sizeof(EnTg), + (ActorFunc)EnTg_Init, + (ActorFunc)EnTg_Destroy, + (ActorFunc)EnTg_Update, + (ActorFunc)EnTg_Draw, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Tg/EnTg_Draw.s") +u16 EnTg_GetTextId(GlobalContext* globalCtx, Actor* thisx) { + EnTg* this = THIS; + u16 temp; + u32 phi; + + // If the player is wearing a mask, return a special reaction text + temp = Text_GetFaceReaction(globalCtx, 0x24); + if (temp != 0) { + return temp; + } + // Use a different set of dialogue in Kakariko Village (Adult) + if (globalCtx->sceneNum == SCENE_SPOT01) { + if (this->nextDialogue % 2 != 0) { + phi = 0x5089; + } else { + phi = 0x508A; + } + return phi; + } else { + if (this->nextDialogue % 2 != 0) { + phi = 0x7025; + } else { + phi = 0x7026; + } + return phi; + } +} + +s16 EnTg_OnTextComplete(GlobalContext* globalCtx, Actor* thisx) { + EnTg* this = THIS; + + switch (func_8010BDBC(&globalCtx->msgCtx)) { + case 0: + case 1: + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + case 9: + return 1; + case 2: + switch (this->actor.textId) { + case 0x5089: + case 0x508A: + this->nextDialogue++; + break; + case 0x7025: + case 0x7026: + this->actor.params ^= 1; + this->nextDialogue++; + break; + } + return 0; + default: + return 1; + } +} + +void EnTg_Init(Actor* thisx, GlobalContext* globalCtx) { + EnTg* this = THIS; + + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 28.0f); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &gDancingCoupleSkel, &gDancingCoupleAnim, NULL, NULL, 0); + Collider_InitCylinder(globalCtx, &this->collider); + Collider_SetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); + CollisionCheck_SetInfo2(&this->actor.colChkInfo, NULL, &sColChkInfoInit); + this->actor.targetMode = 6; + Actor_SetScale(&this->actor, 0.01f); + this->nextDialogue = globalCtx->state.frames % 2; + this->actionFunc = EnTg_SpinIfNotTalking; +} + +void EnTg_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnTg* this = THIS; + + SkelAnime_Free(&this->skelAnime, globalCtx); + Collider_DestroyCylinder(globalCtx, &this->collider); +} + +void EnTg_SpinIfNotTalking(EnTg* this, GlobalContext* globalCtx) { + if (!this->isTalking) { + this->actor.shape.rot.y += 0x800; + } +} + +void EnTg_Update(Actor* thisx, GlobalContext* globalCtx) { + EnTg* this = THIS; + s32 pad; + f32 temp; + Vec3s sp2C; + + sp2C.x = this->actor.world.pos.x; + sp2C.y = this->actor.world.pos.y; + sp2C.z = (s16)this->actor.world.pos.z + 3; + this->collider.dim.pos = sp2C; + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + SkelAnime_Update(&this->skelAnime); + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 0.0f, 0.0f, 0.0f, 4); + this->actionFunc(this, globalCtx); + temp = this->collider.dim.radius + 30.0f; + func_800343CC(globalCtx, &this->actor, &this->isTalking, temp, EnTg_GetTextId, EnTg_OnTextComplete); +} + +s32 EnTg_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, void* thisx) { + return false; +} + +void EnTg_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, void* thisx) { + EnTg* this = THIS; + Vec3f targetOffset = { 0.0f, 800.0f, 0.0f }; + + if (limbIndex == 9) { + // Place the target point at the guy's head instead of the center of the actor + Matrix_MultVec3f(&targetOffset, &this->actor.focus.pos); + } +} + +Gfx* EnTg_SetColor(GraphicsContext* gfxCtx, u8 r, u8 g, u8 b, u8 a) { + Gfx* displayList = Graph_Alloc(gfxCtx, 2 * sizeof(Gfx)); + + gDPSetEnvColor(displayList, r, g, b, a); + gSPEndDisplayList(displayList + 1); + return displayList; +} + +void EnTg_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnTg* this = THIS; + + OPEN_DISPS(globalCtx->state.gfxCtx, "../z_en_tg.c", 462); + Matrix_Translate(0.0f, 0.0f, -560.0f, MTXMODE_APPLY); + + // Set the guy's shoes and shirt to royal blue + gSPSegment(POLY_OPA_DISP++, 0x08, EnTg_SetColor(globalCtx->state.gfxCtx, 0, 50, 160, 0)); + + // Set the girl's shirt to white + gSPSegment(POLY_OPA_DISP++, 0x09, EnTg_SetColor(globalCtx->state.gfxCtx, 255, 255, 255, 0)); + + SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, + EnTg_OverrideLimbDraw, EnTg_PostLimbDraw, this); + CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_en_tg.c", 480); +} diff --git a/src/overlays/actors/ovl_En_Tg/z_en_tg.h b/src/overlays/actors/ovl_En_Tg/z_en_tg.h index 55e8b5442..b22708504 100644 --- a/src/overlays/actors/ovl_En_Tg/z_en_tg.h +++ b/src/overlays/actors/ovl_En_Tg/z_en_tg.h @@ -6,9 +6,16 @@ struct EnTg; +typedef void (*EnTgActionFunc)(struct EnTg*, GlobalContext*); + typedef struct EnTg { /* 0x0000 */ Actor actor; - /* 0x014C */ char unk_14C[0xC0]; + /* 0x014C */ SkelAnime skelAnime; + /* 0x0190 */ EnTgActionFunc actionFunc; + /* 0x0194 */ ColliderCylinder collider; + /* 0x01E0 */ s16 isTalking; + /* 0x01E2 */ char unk_1E2[0x26]; + /* 0x0208 */ u8 nextDialogue; } EnTg; // size = 0x020C extern const ActorInit En_Tg_InitVars; |
