summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAly Cerruti <aprime2003@gmail.com>2021-07-28 09:51:12 -0700
committerGitHub <noreply@github.com>2021-07-28 12:51:12 -0400
commit6f7312a3480f722425f31fcacbd031c1155bc4d6 (patch)
tree5d457a50935afbeec2a9b6dc99360ea7b60db1f2 /src
parent5c147e5e03e9d693213537101f56d3a6eb53f16a (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.c193
-rw-r--r--src/overlays/actors/ovl_En_Tg/z_en_tg.h9
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;