1
0
Fork 0
mirror of https://github.com/zeldaret/oot.git synced 2025-07-03 06:24:30 +00:00

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
This commit is contained in:
Aly Cerruti 2021-07-28 09:51:12 -07:00 committed by GitHub
parent 5c147e5e03
commit 6f7312a348
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
17 changed files with 164 additions and 495 deletions

View file

@ -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")
static CollisionCheckInfoInit2 sColChkInfoInit = { 0, 0, 0, 0, MASS_IMMOVABLE };
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Tg/EnTg_Init.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_Destroy.s")
u16 EnTg_GetTextId(GlobalContext* globalCtx, Actor* thisx) {
EnTg* this = THIS;
u16 temp;
u32 phi;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Tg/func_80B185C0.s")
// 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;
}
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Tg/EnTg_Update.s")
s16 EnTg_OnTextComplete(GlobalContext* globalCtx, Actor* thisx) {
EnTg* this = THIS;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Tg/func_80B18704.s")
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;
}
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Tg/func_80B1871C.s")
void EnTg_Init(Actor* thisx, GlobalContext* globalCtx) {
EnTg* this = THIS;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Tg/func_80B18778.s")
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;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Tg/EnTg_Draw.s")
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);
}

View file

@ -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;