mirror of
https://github.com/zeldaret/mm.git
synced 2026-08-17 21:03:30 -04:00
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:
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user