Tutorial on decompiling objects (and also object_dns documented) (#647)

* Fix existing documentation

* Fill out object_decomp.md

* First part of object decomp example

* Document animations

* Tutorial for identifying blob

* Naming everything else referenced in the actor

* Name all limb display lists

* Finish example

* Some tips and tricks

* Remove TODO

* Make merging.md consistent with everything else

* Name limbs properly

* Rename "bouncing idle" to "walk", since they use that animation to walk towards you if they catch you

* Run formatter again

* Purge hylian toolbox

* Be a bit more precise about vertex naming

* Also -> Further

* Correct description of how extract_assets works

* Format types of data

* Add note about palette

* Update text about object's C file

* Fix typo

* one more time -> in more detail

* Format render error as code

* explain what texture animations are

* Standardize on bullet points

* Use anon's sugestion for the "How we work with objects" section

* Trailing commas for better formatting

* Delete undefined_syms reference in object decomp

* Add note about root limbs

* Remove undefined_syms reference in object_decomp_example

* Remove "since"

* Explain *how* I changed the texture

* Explain what to do if the limb doesn't render anything

* Fix some extremely tiny incorrect enum name thing

* Explain the object symbol stuff bettter

* Add link to ZAPD documentation

* Also update documentation

* Update actor flags for Dns
This commit is contained in:
Tom Overton
2022-02-19 13:30:31 -08:00
committed by GitHub
parent 8e3d28b536
commit fed9dc991d
22 changed files with 599 additions and 188 deletions
+72 -45
View File
@@ -5,9 +5,8 @@
*/
#include "z_en_dns.h"
#include "objects/object_dns/object_dns.h"
#define FLAGS 0x00000019
#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8 | ACTOR_FLAG_10)
#define THIS ((EnDns*)thisx)
@@ -20,6 +19,20 @@ void func_8092D330(EnDns* this, GlobalContext* globalCtx);
void EnDns_DoNothing(EnDns* this, GlobalContext* globalCtx);
void func_8092D4D8(EnDns* this, GlobalContext* globalCtx);
typedef enum {
/* 0 */ EN_DNS_ANIMATION_IDLE_1,
/* 1 */ EN_DNS_ANIMATION_IDLE_2,
/* 2 */ EN_DNS_ANIMATION_WALK_1,
/* 3 */ EN_DNS_ANIMATION_WALK_2,
/* 4 */ EN_DNS_ANIMATION_SURPRISE_START,
/* 5 */ EN_DNS_ANIMATION_SURPRISE_LOOP,
/* 6 */ EN_DNS_ANIMATION_RUN_START,
/* 7 */ EN_DNS_ANIMATION_RUN_LOOP,
/* 8 */ EN_DNS_ANIMATION_DANCE,
/* 9 */ EN_DNS_ANIMATION_FLIP,
/* 10 */ EN_DNS_ANIMATION_MAX,
} EnDnsAnimationIndex;
static s32 D_8092DCB0[] = {
0x00172000, 0x050E082F, 0x0C100E08, 0x200C1000, 0x00172000, 0x050E0830, 0x0C100E08, 0x210C1000,
0x00172000, 0x050E0831, 0x0C100E08, 0x220C1000, 0x00172000, 0x050E0832, 0x0C100E08, 0x230C1000,
@@ -61,22 +74,23 @@ static ColliderCylinderInit sCylinderInit = {
static CollisionCheckInfoInit2 sColChkInfoInit = { 1, 0, 0, 0, MASS_IMMOVABLE };
static AnimationInfoS sAnimations[] = {
{ &object_dns_Anim_003310, 1.0f, 0, -1, ANIMMODE_LOOP, 0 },
{ &object_dns_Anim_003310, 1.0f, 0, -1, ANIMMODE_LOOP, -4 },
{ &object_dns_Anim_0034EC, 1.0f, 0, -1, ANIMMODE_LOOP, 0 },
{ &object_dns_Anim_0034EC, 1.0f, 0, -1, ANIMMODE_LOOP, -4 },
{ &object_dns_Anim_0008F4, 1.0f, 0, -1, ANIMMODE_ONCE, 0 },
{ &object_dns_Anim_000BD8, 1.0f, 0, -1, ANIMMODE_LOOP, 0 },
{ &object_dns_Anim_000D58, 1.0f, 0, -1, ANIMMODE_ONCE, 0 },
{ &object_dns_Anim_000FEC, 1.0f, 0, -1, ANIMMODE_LOOP, 0 },
{ &object_dns_Anim_0002A8, 1.0f, 0, -1, ANIMMODE_ONCE, 0 },
{ &object_dns_Anim_000734, 1.0f, 0, -1, ANIMMODE_ONCE, 0 },
{ &gKingsChamberDekuGuardIdleAnim, 1.0f, 0, -1, ANIMMODE_LOOP, 0 },
{ &gKingsChamberDekuGuardIdleAnim, 1.0f, 0, -1, ANIMMODE_LOOP, -4 },
{ &gKingsChamberDekuGuardWalkAnim, 1.0f, 0, -1, ANIMMODE_LOOP, 0 },
{ &gKingsChamberDekuGuardWalkAnim, 1.0f, 0, -1, ANIMMODE_LOOP, -4 },
{ &gKingsChamberDekuGuardSurpriseStartAnim, 1.0f, 0, -1, ANIMMODE_ONCE, 0 },
{ &gKingsChamberDekuGuardSurpriseLoopAnim, 1.0f, 0, -1, ANIMMODE_LOOP, 0 },
{ &gKingsChamberDekuGuardRunStartAnim, 1.0f, 0, -1, ANIMMODE_ONCE, 0 },
{ &gKingsChamberDekuGuardRunLoopAnim, 1.0f, 0, -1, ANIMMODE_LOOP, 0 },
{ &gKingsChamberDekuGuardDanceAnim, 1.0f, 0, -1, ANIMMODE_ONCE, 0 },
{ &gKingsChamberDekuGuardFlipAnim, 1.0f, 0, -1, ANIMMODE_ONCE, 0 },
};
void func_8092C5C0(EnDns* this) {
s32 pad;
if (((this->unk_2F8 == 2) || (this->unk_2F8 == 3) || (this->unk_2F8 == 6) || (this->unk_2F8 == 7)) &&
if (((this->animationIndex == EN_DNS_ANIMATION_WALK_1) || (this->animationIndex == EN_DNS_ANIMATION_WALK_2) ||
(this->animationIndex == EN_DNS_ANIMATION_RUN_START) || (this->animationIndex == EN_DNS_ANIMATION_RUN_LOOP)) &&
(Animation_OnFrame(&this->skelAnime, 0.0f) || Animation_OnFrame(&this->skelAnime, 3.0f))) {
Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_NUTS_WALK);
}
@@ -87,28 +101,30 @@ s32 func_8092C63C(EnDns* this, s32 arg1) {
s32 ret = false;
switch (arg1) {
case 0:
case 1:
if ((this->unk_2F8 != 0) && (this->unk_2F8 != 1)) {
case EN_DNS_ANIMATION_IDLE_1:
case EN_DNS_ANIMATION_IDLE_2:
if ((this->animationIndex != EN_DNS_ANIMATION_IDLE_1) &&
(this->animationIndex != EN_DNS_ANIMATION_IDLE_2)) {
phi_v1 = true;
}
break;
case 2:
case 3:
if ((this->unk_2F8 != 2) && (this->unk_2F8 != 3)) {
case EN_DNS_ANIMATION_WALK_1:
case EN_DNS_ANIMATION_WALK_2:
if ((this->animationIndex != EN_DNS_ANIMATION_WALK_1) &&
(this->animationIndex != EN_DNS_ANIMATION_WALK_2)) {
phi_v1 = true;
}
break;
default:
if (this->unk_2F8 != arg1) {
if (this->animationIndex != arg1) {
phi_v1 = true;
}
}
if (phi_v1) {
this->unk_2F8 = arg1;
this->animationIndex = arg1;
ret = SubS_ChangeAnimationByInfoS(&this->skelAnime, sAnimations, arg1);
}
@@ -154,11 +170,11 @@ void func_8092C86C(EnDns* this, GlobalContext* globalCtx) {
}
void func_8092C934(EnDns* this) {
if ((this->unk_2C6 & 0x40) && (DECR(this->unk_2DE) == 0)) {
this->unk_2E0++;
if (this->unk_2E0 >= 4) {
this->unk_2DE = Rand_S16Offset(30, 30);
this->unk_2E0 = 0;
if ((this->unk_2C6 & 0x40) && (DECR(this->blinkTimer) == 0)) {
this->eyeIndex++;
if (this->eyeIndex >= 4) {
this->blinkTimer = Rand_S16Offset(30, 30);
this->eyeIndex = 0;
}
}
}
@@ -220,7 +236,7 @@ s32 func_8092CAD0(EnDns* this, GlobalContext* globalCtx) {
this->unk_2F0 = 0.0f;
if (this->unk_2D2 != 0) {
this->unk_2F0 = this->skelAnime.curFrame;
func_8092C63C(this, 2);
func_8092C63C(this, EN_DNS_ANIMATION_WALK_1);
}
this->unk_2DA = this->actor.world.rot.y;
}
@@ -238,14 +254,14 @@ s32 func_8092CB98(EnDns* this, GlobalContext* globalCtx) {
if (globalCtx->csCtx.state != 0) {
if (!(this->unk_2C6 & 0x80)) {
this->unk_2C8 = func_8092CA74(this);
this->actor.flags &= ~0x1;
this->actor.flags &= ~ACTOR_FLAG_1;
func_8013AED4(&this->unk_2C6, 0, 7);
this->unk_2C6 |= 0x80;
this->unk_1D8 = 0xFF;
}
phi_v1 = 1;
} else if (this->unk_2C6 & 0x80) {
this->actor.flags |= 1;
this->actor.flags |= ACTOR_FLAG_1;
func_8013AED4(&this->unk_2C6, 3, 7);
this->unk_2C6 &= ~0x80;
}
@@ -290,7 +306,7 @@ s32 func_8092CCEC(EnDns* this, GlobalContext* globalCtx) {
}
s32 func_8092CE38(EnDns* this) {
static s32 D_8092DE00[] = { 8, 8, 9 };
static s32 D_8092DE00[] = { EN_DNS_ANIMATION_DANCE, EN_DNS_ANIMATION_DANCE, EN_DNS_ANIMATION_FLIP };
s16 frame;
s32 pad;
Vec3f sp2C;
@@ -369,7 +385,7 @@ void func_8092D108(EnDns* this, GlobalContext* globalCtx) {
Matrix_Scale(this->actor.scale.x, this->actor.scale.y, this->actor.scale.z, MTXMODE_APPLY);
gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_OPA_DISP++, object_dns_DL_002C48);
gSPDisplayList(POLY_OPA_DISP++, gKingsChamberDekuGuardDekuFlower);
CLOSE_DISPS(globalCtx->state.gfxCtx);
}
@@ -390,11 +406,11 @@ void func_8092D1B8(EnDns* this, GlobalContext* globalCtx) {
play_sound(NA_SE_SY_FOUND);
gSaveContext.eventInf[1] |= 0x20;
this->unk_2F4 = func_8092CCEC;
func_8092C63C(this, 2);
func_8092C63C(this, EN_DNS_ANIMATION_WALK_1);
this->actionFunc = EnDns_DoNothing;
} else if (gSaveContext.eventInf[1] & 0x40) {
func_8092CCEC(this, globalCtx);
func_8092C63C(this, 2);
func_8092C63C(this, EN_DNS_ANIMATION_WALK_1);
this->actionFunc = func_8092D330;
}
Math_ApproachS(&this->actor.shape.rot.y, sp22, 3, 0x2AA8);
@@ -436,7 +452,7 @@ void func_8092D4D8(EnDns* this, GlobalContext* globalCtx) {
if (ENDNS_GET_4000(&this->actor) && (this->unk_2D2 == 0)) {
if (func_8092CE38(this)) {
func_8092C63C(this, 2);
func_8092C63C(this, EN_DNS_ANIMATION_WALK_1);
}
} else if (func_8010BF58(&this->actor, globalCtx, this->unk_1E0, this->unk_2F4, &this->unk_1DC)) {
func_8013AED4(&this->unk_2C6, 3, 7);
@@ -445,7 +461,7 @@ void func_8092D4D8(EnDns* this, GlobalContext* globalCtx) {
if (!(gSaveContext.eventInf[1] & 0x20)) {
this->skelAnime.curFrame = this->unk_2F0;
this->actor.world.rot.y = this->unk_2DA;
func_8092C63C(this, 8);
func_8092C63C(this, EN_DNS_ANIMATION_DANCE);
}
this->unk_2CC = 0;
this->unk_2CE = 0;
@@ -458,7 +474,12 @@ void func_8092D4D8(EnDns* this, GlobalContext* globalCtx) {
}
void func_8092D5E8(EnDns* this, GlobalContext* globalCtx) {
static s32 D_8092DE0C[] = { 0, 0, 4, 6 };
static s32 D_8092DE0C[] = {
EN_DNS_ANIMATION_IDLE_1,
EN_DNS_ANIMATION_IDLE_1,
EN_DNS_ANIMATION_SURPRISE_START,
EN_DNS_ANIMATION_RUN_START,
};
u32 temp_v0;
u32 temp_v1;
@@ -470,9 +491,10 @@ void func_8092D5E8(EnDns* this, GlobalContext* globalCtx) {
this->unk_1D8 = temp_v1;
}
if (((this->unk_2F8 == 4) || (this->unk_2F8 == 6)) &&
if (((this->animationIndex == EN_DNS_ANIMATION_SURPRISE_START) ||
(this->animationIndex == EN_DNS_ANIMATION_RUN_START)) &&
Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) {
func_8092C63C(this, this->unk_2F8 + 1);
func_8092C63C(this, this->animationIndex + 1);
}
func_800EDF24(&this->actor, globalCtx, temp_v0);
@@ -488,9 +510,10 @@ void EnDns_Init(Actor* thisx, GlobalContext* globalCtx) {
}
ActorShape_Init(&this->actor.shape, 0.0f, NULL, 18.0f);
SkelAnime_Init(globalCtx, &this->skelAnime, &object_dns_Skel_002DD8, NULL, this->jointTable, this->morphTable, 13);
this->unk_2F8 = -1;
func_8092C63C(this, 2);
SkelAnime_Init(globalCtx, &this->skelAnime, &gKingsChamberDekuGuardSkel, NULL, this->jointTable, this->morphTable,
KINGS_CHAMBER_DEKU_GUARD_LIMB_MAX);
this->animationIndex = -1;
func_8092C63C(this, EN_DNS_ANIMATION_WALK_1);
Collider_InitAndSetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit);
CollisionCheck_SetInfo2(&this->actor.colChkInfo, DamageTable_Get(0x16), &sColChkInfoInit);
Actor_SetScale(&this->actor, 0.01f);
@@ -590,7 +613,7 @@ void EnDns_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Ve
}
}
if (limbIndex == 2) {
if (limbIndex == KINGS_CHAMBER_DEKU_GUARD_LIMB_HEAD) {
func_8092D954(this->unk_2CC, this->unk_2CE + this->actor.shape.rot.y, &this->unk_218, &this->unk_224, phi_v1,
phi_v0);
Matrix_InsertTranslation(this->unk_218.x, this->unk_218.y, this->unk_218.z, MTXMODE_NEW);
@@ -609,15 +632,19 @@ void EnDns_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Ve
}
void EnDns_Draw(Actor* thisx, GlobalContext* globalCtx) {
static TexturePtr D_8092DE1C[] = { object_dns_Tex_0028E8, object_dns_Tex_002968, object_dns_Tex_0029E8,
object_dns_Tex_002968 };
static TexturePtr sEyeTextures[] = {
gKingsChamberDekuGuardEyeOpenTex,
gKingsChamberDekuGuardEyeHalfTex,
gKingsChamberDekuGuardEyeClosedTex,
gKingsChamberDekuGuardEyeHalfTex,
};
EnDns* this = THIS;
OPEN_DISPS(globalCtx->state.gfxCtx);
func_8012C28C(globalCtx->state.gfxCtx);
gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(D_8092DE1C[this->unk_2E0]));
gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(sEyeTextures[this->eyeIndex]));
gDPPipeSync(POLY_OPA_DISP++);
SkelAnime_DrawOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, EnDns_OverrideLimbDraw,
+6 -5
View File
@@ -2,6 +2,7 @@
#define Z_EN_DNS_H
#include "global.h"
#include "objects/object_dns/object_dns.h"
struct EnDns;
@@ -31,8 +32,8 @@ typedef struct EnDns {
/* 0x1E4 */ Gfx* unk_1E4[13];
/* 0x218 */ Vec3f unk_218;
/* 0x224 */ Vec3s unk_224;
/* 0x22A */ Vec3s jointTable[13];
/* 0x278 */ Vec3s morphTable[13];
/* 0x22A */ Vec3s jointTable[KINGS_CHAMBER_DEKU_GUARD_LIMB_MAX];
/* 0x278 */ Vec3s morphTable[KINGS_CHAMBER_DEKU_GUARD_LIMB_MAX];
/* 0x2C6 */ u16 unk_2C6;
/* 0x2C8 */ u16 unk_2C8;
/* 0x2CA */ UNK_TYPE1 unk_2CA[0x2];
@@ -45,14 +46,14 @@ typedef struct EnDns {
/* 0x2D8 */ s16 unk_2D8;
/* 0x2DA */ s16 unk_2DA;
/* 0x2DC */ s16 unk_2DC;
/* 0x2DE */ s16 unk_2DE;
/* 0x2E0 */ s16 unk_2E0;
/* 0x2DE */ s16 blinkTimer;
/* 0x2E0 */ s16 eyeIndex;
/* 0x2E4 */ f32 unk_2E4;
/* 0x2E8 */ UNK_TYPE1 unk_2E8[0x4];
/* 0x2EC */ f32 unk_2EC;
/* 0x2F0 */ f32 unk_2F0;
/* 0x2F4 */ EnDnsFunc unk_2F4;
/* 0x2F8 */ s32 unk_2F8;
/* 0x2F8 */ s32 animationIndex;
/* 0x2FC */ s32 unk_2FC;
} EnDns; // size = 0x300