1
0
mirror of https://github.com/zeldaret/oot.git synced 2024-09-21 12:54:51 +00:00

Document Bunny Hood 🐰 (#1373)

* Change BunnyEarKinematics struct and some docs

* More complete docs

* Format, quick note in the InitModes array

* remove comment and move struct down

Co-authored-by: fig02 <fig02srl@gmail.com>
This commit is contained in:
EllipticEllipsis 2023-01-12 21:57:19 +00:00 committed by GitHub
parent 1149530c92
commit 5f7e376112
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 88 additions and 66 deletions

View File

@ -526,9 +526,10 @@ void EnMm_Draw(Actor* thisx, PlayState* play) {
if (GET_ITEMGETINF(ITEMGETINF_3B)) { if (GET_ITEMGETINF(ITEMGETINF_3B)) {
s32 linkChildObjBankIndex = Object_GetIndex(&play->objectCtx, OBJECT_LINK_CHILD); s32 linkChildObjBankIndex = Object_GetIndex(&play->objectCtx, OBJECT_LINK_CHILD);
// Draw Bunny Hood
if (linkChildObjBankIndex >= 0) { if (linkChildObjBankIndex >= 0) {
Mtx* mtx; Mtx* mtx;
Vec3s sp50; Vec3s earRot;
Mtx* mtx2; Mtx* mtx2;
mtx = Graph_Alloc(play->state.gfxCtx, sizeof(Mtx) * 2); mtx = Graph_Alloc(play->state.gfxCtx, sizeof(Mtx) * 2);
@ -540,18 +541,20 @@ void EnMm_Draw(Actor* thisx, PlayState* play) {
gSPSegment(POLY_OPA_DISP++, 0x0B, mtx); gSPSegment(POLY_OPA_DISP++, 0x0B, mtx);
gSPSegment(POLY_OPA_DISP++, 0x0D, mtx2 - 7); gSPSegment(POLY_OPA_DISP++, 0x0D, mtx2 - 7);
sp50.x = 994; // Draw the ears in the neutral position (unlike Player, no flopping physics)
sp50.y = 3518;
sp50.z = -13450;
Matrix_SetTranslateRotateYXZ(97.0f, -1203.0f, -240.0f, &sp50); // Right ear
earRot.x = 0x3E2;
earRot.y = 0xDBE;
earRot.z = -0x348A;
Matrix_SetTranslateRotateYXZ(97.0f, -1203.0f, -240.0f, &earRot);
Matrix_ToMtx(mtx++, "../z_en_mm.c", 1124); Matrix_ToMtx(mtx++, "../z_en_mm.c", 1124);
sp50.x = -994; // Left ear
sp50.y = -3518; earRot.x = -0x3E2;
sp50.z = -13450; earRot.y = -0xDBE;
earRot.z = -0x348A;
Matrix_SetTranslateRotateYXZ(97.0f, -1203.0f, 240.0f, &sp50); Matrix_SetTranslateRotateYXZ(97.0f, -1203.0f, 240.0f, &earRot);
Matrix_ToMtx(mtx, "../z_en_mm.c", 1131); Matrix_ToMtx(mtx, "../z_en_mm.c", 1131);
gSPDisplayList(POLY_OPA_DISP++, gLinkChildBunnyHoodDL); gSPDisplayList(POLY_OPA_DISP++, gLinkChildBunnyHoodDL);

View File

@ -114,14 +114,6 @@ typedef struct {
}; };
} struct_80854B18; // size = 0x08 } struct_80854B18; // size = 0x08
typedef struct {
/* 0x00 */ s16 unk_00;
/* 0x02 */ s16 unk_02;
/* 0x04 */ s16 unk_04;
/* 0x06 */ s16 unk_06;
/* 0x08 */ s16 unk_08;
} struct_80858AC8; // size = 0x0A
void func_80833770(PlayState* play, Player* this); void func_80833770(PlayState* play, Player* this);
void func_80833790(PlayState* play, Player* this); void func_80833790(PlayState* play, Player* this);
void func_8083379C(PlayState* play, Player* this); void func_8083379C(PlayState* play, Player* this);
@ -255,7 +247,7 @@ void func_8084FB10(Player* this, PlayState* play);
void func_8084FBF4(Player* this, PlayState* play); void func_8084FBF4(Player* this, PlayState* play);
s32 func_8084FCAC(Player* this, PlayState* play); s32 func_8084FCAC(Player* this, PlayState* play);
void func_8084FF7C(Player* this); void func_8084FF7C(Player* this);
void func_8085002C(Player* this); void Player_UpdateBunnyEars(Player* this);
s32 func_80850224(Player* this, PlayState* play); s32 func_80850224(Player* this, PlayState* play);
void func_808502D0(Player* this, PlayState* play); void func_808502D0(Player* this, PlayState* play);
void func_808505DC(Player* this, PlayState* play); void func_808505DC(Player* this, PlayState* play);
@ -9613,9 +9605,22 @@ void Player_InitCommon(Player* this, PlayState* play, FlexSkeletonHeader* skelHe
} }
static void (*D_80854738[])(PlayState* play, Player* this) = { static void (*D_80854738[])(PlayState* play, Player* this) = {
func_80846648, func_808467D4, func_80846660, func_808468A8, func_808468E8, func_808469BC, /* 0x0 */ func_80846648,
func_80846A68, func_80846978, func_8083CA54, func_8083CA54, func_8083CA54, func_8083CA54, /* 0x1 */ func_808467D4, // From time travel
func_8083CA54, func_8083CA20, func_8083CA54, func_8083CA9C, /* 0x2 */ func_80846660,
/* 0x3 */ func_808468A8,
/* 0x4 */ func_808468E8,
/* 0x5 */ func_808469BC,
/* 0x6 */ func_80846A68,
/* 0x7 */ func_80846978,
/* 0x8 */ func_8083CA54,
/* 0x9 */ func_8083CA54,
/* 0xA */ func_8083CA54,
/* 0xB */ func_8083CA54,
/* 0xC */ func_8083CA54,
/* 0xD */ func_8083CA20,
/* 0xE */ func_8083CA54,
/* 0xF */ func_8083CA9C,
}; };
static Vec3f D_80854778 = { 0.0f, 50.0f, 0.0f }; static Vec3f D_80854778 = { 0.0f, 50.0f, 0.0f };
@ -10589,7 +10594,7 @@ void Player_UpdateCommon(Player* this, PlayState* play, Input* input) {
this->actor.shape.face = this->unk_3A8[0] + ((play->gameplayFrames & 32) ? 0 : 3); this->actor.shape.face = this->unk_3A8[0] + ((play->gameplayFrames & 32) ? 0 : 3);
if (this->currentMask == PLAYER_MASK_BUNNY) { if (this->currentMask == PLAYER_MASK_BUNNY) {
func_8085002C(this); Player_UpdateBunnyEars(this);
} }
if (func_8002DD6C(this) != 0) { if (func_8002DD6C(this) != 0) {
@ -10929,7 +10934,13 @@ void Player_Update(Actor* thisx, PlayState* play) {
MREG(55) = this->actor.world.rot.y; MREG(55) = this->actor.world.rot.y;
} }
static struct_80858AC8 D_80858AC8; typedef struct {
/* 0x0 */ Vec3s rot;
/* 0x6 */ Vec3s angVel;
} BunnyEarKinematics; // size = 0xC
static BunnyEarKinematics sBunnyEarKinematics;
static Vec3s D_80858AD8[25]; static Vec3s D_80858AD8[25];
static Gfx* sMaskDlists[PLAYER_MASK_MAX - 1] = { static Gfx* sMaskDlists[PLAYER_MASK_MAX - 1] = {
@ -10952,24 +10963,26 @@ void Player_DrawGameplay(PlayState* play, Player* this, s32 lod, Gfx* cullDList,
Player_PostLimbDrawGameplay, this); Player_PostLimbDrawGameplay, this);
if ((overrideLimbDraw == Player_OverrideLimbDrawGameplayDefault) && (this->currentMask != PLAYER_MASK_NONE)) { if ((overrideLimbDraw == Player_OverrideLimbDrawGameplayDefault) && (this->currentMask != PLAYER_MASK_NONE)) {
Mtx* sp70 = Graph_Alloc(play->state.gfxCtx, 2 * sizeof(Mtx)); Mtx* bunnyEarMtx = Graph_Alloc(play->state.gfxCtx, 2 * sizeof(Mtx));
if (this->currentMask == PLAYER_MASK_BUNNY) { if (this->currentMask == PLAYER_MASK_BUNNY) {
Vec3s sp68; Vec3s earRot;
gSPSegment(POLY_OPA_DISP++, 0x0B, sp70); gSPSegment(POLY_OPA_DISP++, 0x0B, bunnyEarMtx);
sp68.x = D_80858AC8.unk_02 + 0x3E2; // Right ear
sp68.y = D_80858AC8.unk_04 + 0xDBE; earRot.x = sBunnyEarKinematics.rot.y + 0x3E2;
sp68.z = D_80858AC8.unk_00 - 0x348A; earRot.y = sBunnyEarKinematics.rot.z + 0xDBE;
Matrix_SetTranslateRotateYXZ(97.0f, -1203.0f, -240.0f, &sp68); earRot.z = sBunnyEarKinematics.rot.x - 0x348A;
Matrix_ToMtx(sp70++, "../z_player.c", 19273); Matrix_SetTranslateRotateYXZ(97.0f, -1203.0f, -240.0f, &earRot);
Matrix_ToMtx(bunnyEarMtx++, "../z_player.c", 19273);
sp68.x = D_80858AC8.unk_02 - 0x3E2; // Left ear
sp68.y = -0xDBE - D_80858AC8.unk_04; earRot.x = sBunnyEarKinematics.rot.y - 0x3E2;
sp68.z = D_80858AC8.unk_00 - 0x348A; earRot.y = -sBunnyEarKinematics.rot.z - 0xDBE;
Matrix_SetTranslateRotateYXZ(97.0f, -1203.0f, 240.0f, &sp68); earRot.z = sBunnyEarKinematics.rot.x - 0x348A;
Matrix_ToMtx(sp70, "../z_player.c", 19279); Matrix_SetTranslateRotateYXZ(97.0f, -1203.0f, 240.0f, &earRot);
Matrix_ToMtx(bunnyEarMtx, "../z_player.c", 19279);
} }
gSPDisplayList(POLY_OPA_DISP++, sMaskDlists[this->currentMask - 1]); gSPDisplayList(POLY_OPA_DISP++, sMaskDlists[this->currentMask - 1]);
@ -13255,44 +13268,50 @@ void func_8084FF7C(Player* this) {
} }
} }
void func_8085002C(Player* this) { /**
s32 pad; * Updates the Bunny Hood's floppy ears' rotation and velocity.
s16 sp2A; */
s16 sp28; void Player_UpdateBunnyEars(Player* this) {
s16 sp26; Vec3s force;
s16 angle;
D_80858AC8.unk_06 -= D_80858AC8.unk_06 >> 3; // Damping: decay by 1/8 the previous value each frame
D_80858AC8.unk_08 -= D_80858AC8.unk_08 >> 3; sBunnyEarKinematics.angVel.x -= sBunnyEarKinematics.angVel.x >> 3;
D_80858AC8.unk_06 += -D_80858AC8.unk_00 >> 2; sBunnyEarKinematics.angVel.y -= sBunnyEarKinematics.angVel.y >> 3;
D_80858AC8.unk_08 += -D_80858AC8.unk_02 >> 2;
sp26 = this->actor.world.rot.y - this->actor.shape.rot.y; // Elastic restorative force
sBunnyEarKinematics.angVel.x += -sBunnyEarKinematics.rot.x >> 2;
sBunnyEarKinematics.angVel.y += -sBunnyEarKinematics.rot.y >> 2;
sp28 = (s32)(this->actor.speed * -200.0f * Math_CosS(sp26) * (Rand_CenteredFloat(2.0f) + 10.0f)) & 0xFFFF; // Forcing from motion relative to shape frame
sp2A = (s32)(this->actor.speed * 100.0f * Math_SinS(sp26) * (Rand_CenteredFloat(2.0f) + 10.0f)) & 0xFFFF; angle = this->actor.world.rot.y - this->actor.shape.rot.y;
force.x = (s32)(this->actor.speed * -200.0f * Math_CosS(angle) * (Rand_CenteredFloat(2.0f) + 10.0f)) & 0xFFFF;
force.y = (s32)(this->actor.speed * 100.0f * Math_SinS(angle) * (Rand_CenteredFloat(2.0f) + 10.0f)) & 0xFFFF;
D_80858AC8.unk_06 += sp28 >> 2; sBunnyEarKinematics.angVel.x += force.x >> 2;
D_80858AC8.unk_08 += sp2A >> 2; sBunnyEarKinematics.angVel.y += force.y >> 2;
if (D_80858AC8.unk_06 > 6000) { // Clamp both angular velocities to [-6000, 6000]
D_80858AC8.unk_06 = 6000; if (sBunnyEarKinematics.angVel.x > 6000) {
} else if (D_80858AC8.unk_06 < -6000) { sBunnyEarKinematics.angVel.x = 6000;
D_80858AC8.unk_06 = -6000; } else if (sBunnyEarKinematics.angVel.x < -6000) {
sBunnyEarKinematics.angVel.x = -6000;
}
if (sBunnyEarKinematics.angVel.y > 6000) {
sBunnyEarKinematics.angVel.y = 6000;
} else if (sBunnyEarKinematics.angVel.y < -6000) {
sBunnyEarKinematics.angVel.y = -6000;
} }
if (D_80858AC8.unk_08 > 6000) { // Add angular velocity to rotations
D_80858AC8.unk_08 = 6000; sBunnyEarKinematics.rot.x += sBunnyEarKinematics.angVel.x;
} else if (D_80858AC8.unk_08 < -6000) { sBunnyEarKinematics.rot.y += sBunnyEarKinematics.angVel.y;
D_80858AC8.unk_08 = -6000;
}
D_80858AC8.unk_00 += D_80858AC8.unk_06; // swivel ears outwards if bending backwards
D_80858AC8.unk_02 += D_80858AC8.unk_08; if (sBunnyEarKinematics.rot.x < 0) {
sBunnyEarKinematics.rot.z = sBunnyEarKinematics.rot.x >> 1;
if (D_80858AC8.unk_00 < 0) {
D_80858AC8.unk_04 = D_80858AC8.unk_00 >> 1;
} else { } else {
D_80858AC8.unk_04 = 0; sBunnyEarKinematics.rot.z = 0;
} }
} }