diff --git a/assets/xml/objects/object_kamejima.xml b/assets/xml/objects/object_kamejima.xml
index e8368051dc..cce285475e 100644
--- a/assets/xml/objects/object_kamejima.xml
+++ b/assets/xml/objects/object_kamejima.xml
@@ -1,81 +1,99 @@
+
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/xml/overlays/ovl_Dm_Char08.xml b/assets/xml/overlays/ovl_Dm_Char08.xml
new file mode 100644
index 0000000000..4d96a8eb4b
--- /dev/null
+++ b/assets/xml/overlays/ovl_Dm_Char08.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/include/functions.h b/include/functions.h
index 88a149d1f0..f238824d55 100644
--- a/include/functions.h
+++ b/include/functions.h
@@ -882,6 +882,7 @@ void func_800C636C(PlayState* play, DynaCollisionContext* dyna, s32 bgId);
void func_800C63C4(PlayState* play, DynaCollisionContext* dyna, s32 bgId);
void func_800C641C(PlayState* play, DynaCollisionContext* dyna, s32 bgId);
void func_800C6474(PlayState* play, DynaCollisionContext* dyna, s32 bgId);
+void func_800C6554(PlayState* play, DynaCollisionContext* dyna);
void DynaPoly_DeleteBgActor(PlayState* play, DynaCollisionContext* dyna, s32 bgId);
void BgCheck_CalcWaterboxDimensions(Vec3f* minPos, Vec3f* maxXPos, Vec3f* maxZPos, Vec3s* minPosOut, s16* xLength, s16* zLength);
void DynaPoly_ExpandSRT(PlayState* play, DynaCollisionContext* dyna, s32 bgId, s32* vtxStartIndex, s32* polyStartIndex, s32* waterBoxStartIndex);
diff --git a/spec b/spec
index c99e6ce3f1..ddd1c86e82 100644
--- a/spec
+++ b/spec
@@ -3108,8 +3108,7 @@ beginseg
name "ovl_Dm_Char08"
compress
include "build/src/overlays/actors/ovl_Dm_Char08/z_dm_char08.o"
- include "build/data/ovl_Dm_Char08/ovl_Dm_Char08.data.o"
- include "build/data/ovl_Dm_Char08/ovl_Dm_Char08.reloc.o"
+ include "build/src/overlays/actors/ovl_Dm_Char08/ovl_Dm_Char08_reloc.o"
endseg
beginseg
diff --git a/src/overlays/actors/ovl_Dm_Char08/z_dm_char08.c b/src/overlays/actors/ovl_Dm_Char08/z_dm_char08.c
index ed86257953..94d15be601 100644
--- a/src/overlays/actors/ovl_Dm_Char08/z_dm_char08.c
+++ b/src/overlays/actors/ovl_Dm_Char08/z_dm_char08.c
@@ -5,17 +5,52 @@
*/
#include "z_dm_char08.h"
+#include "objects/object_kamejima/object_kamejima.h"
#define FLAGS (ACTOR_FLAG_2000000)
#define THIS ((DmChar08*)thisx)
-void DmChar08_Init(Actor* thisx, PlayState* play);
+void DmChar08_Init(Actor* thisx, PlayState* play2);
void DmChar08_Destroy(Actor* thisx, PlayState* play);
void DmChar08_Update(Actor* thisx, PlayState* play);
void DmChar08_Draw(Actor* thisx, PlayState* play);
-#if 0
+void func_80AAFAC4(DmChar08* this, PlayState* play);
+void DmChar08_WaitForSong(DmChar08* this, PlayState* play);
+void func_80AAF8F4(DmChar08* this, PlayState* play);
+void func_80AAFAE4(DmChar08* this, PlayState* play);
+void DmChar08_DoNothing(DmChar08* this, PlayState* play);
+void func_80AAFA18(DmChar08* this, PlayState* play);
+void DmChar08_SetupAppearCs(DmChar08* this, PlayState* play);
+void func_80AAF884(DmChar08* this, PlayState* play);
+void func_80AAFB04(DmChar08* this, PlayState* play);
+void func_80AAFB94(DmChar08* this, PlayState* play);
+void func_80AAFE88(DmChar08* this, PlayState* play);
+void func_80AB023C(DmChar08* this, PlayState* play);
+void func_80AB01E8(DmChar08* this, PlayState* play);
+void DmChar08_SpawnBubbles(DmChar08* this, PlayState* play);
+void func_80AAFCCC(DmChar08* this, PlayState* play);
+
+typedef enum {
+ /* 0 */ TURTLE_EYEMODE_BLINK_LEFT,
+ /* 1 */ TURTLE_EYEMODE_BLINK_STRAIGHT,
+ /* 2 */ TURTLE_EYEMODE_CLOSED,
+ /* 3 */ TURTLE_EYEMODE_LOOK_STRAIGHT,
+ /* 4 */ TURTLE_EYEMODE_UNUSED,
+ /* 5 */ TURTLE_EYEMODE_LOOK_RIGHT,
+} EyeMode;
+
+typedef enum {
+ /* 0 */ TURTLE_ANIM_IDLE,
+ /* 1 */ TURTLE_ANIM_SWIM,
+ /* 2 */ TURTLE_ANIM_FLOAT,
+ /* 3 */ TURTLE_ANIM_SPEAK1,
+ /* 4 */ TURTLE_ANIM_COUGH,
+ /* 5 */ TURTLE_ANIM_SPEAK2,
+ /* 6 */ TURTLE_ANIM_YAWN,
+} TurtleAnimation;
+
const ActorInit Dm_Char08_InitVars = {
ACTOR_DM_CHAR08,
ACTORCAT_BG,
@@ -28,71 +63,1061 @@ const ActorInit Dm_Char08_InitVars = {
(ActorFunc)DmChar08_Draw,
};
-// static InitChainEntry sInitChain[] = {
-static InitChainEntry D_80AB1764[] = {
+#include "overlays/ovl_Dm_Char08/ovl_Dm_Char08.c"
+
+static AnimationInfo sAnimationInfo[] = {
+ { &gTurtleIdleAnim, 1.0f, 0.0f, -1.0f, ANIMMODE_LOOP, -24.0f },
+ { &gTurtleSwimAnim, 1.0f, 0.0f, -1.0f, ANIMMODE_LOOP, -24.0f },
+ { &gTurtleFloatAnim, 1.0f, 0.0f, -1.0f, ANIMMODE_LOOP, -24.0f },
+ { &gTurtleSpeak1Anim, 1.0f, 0.0f, -1.0f, ANIMMODE_LOOP, -24.0f },
+ { &gTurtleCoughAnim, 1.0f, 0.0f, -1.0f, ANIMMODE_LOOP, -24.0f },
+ { &gTurtleSpeak2Anim, 1.0f, 0.0f, -1.0f, ANIMMODE_LOOP, -24.0f },
+ { &gTurtleYawnAnim, 1.0f, 0.0f, -1.0f, ANIMMODE_LOOP, -24.0f },
+};
+
+static InitChainEntry sInitChain[] = {
ICHAIN_F32(uncullZoneForward, 4000, ICHAIN_CONTINUE),
ICHAIN_F32(uncullZoneScale, 4000, ICHAIN_CONTINUE),
ICHAIN_F32(uncullZoneDownward, 4000, ICHAIN_STOP),
};
-#endif
+void DmChar08_UpdateEyes(DmChar08* this) {
+ switch (this->eyeMode) {
+ case TURTLE_EYEMODE_BLINK_LEFT:
+ this->eyeIndex = 0;
+ if (this->blinkTimer > 0) {
+ this->blinkTimer--;
+ } else {
+ this->blinkTimer = 0;
+ }
+ if (this->blinkTimer < 4) {
+ this->eyeIndex = this->blinkTimer;
+ }
+ if (this->blinkTimer == 0) {
+ this->blinkTimer = Rand_S16Offset(30, 30);
+ }
+ break;
-extern InitChainEntry D_80AB1764[];
+ case TURTLE_EYEMODE_BLINK_STRAIGHT:
+ this->eyeIndex = 4;
+ if (this->blinkTimer > 0) {
+ this->blinkTimer--;
+ } else {
+ this->blinkTimer = 0;
+ }
+ if (this->blinkTimer < 4) {
+ this->eyeIndex = this->blinkTimer + 4;
+ }
+ if (this->blinkTimer == 0) {
+ this->blinkTimer = Rand_S16Offset(30, 30);
+ }
+ break;
-extern UNK_TYPE D_06002470;
-extern UNK_TYPE D_06004E70;
-extern UNK_TYPE D_0600E748;
+ case TURTLE_EYEMODE_CLOSED:
+ this->eyeIndex = 2;
+ break;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char08/func_80AAF050.s")
+ case TURTLE_EYEMODE_LOOK_STRAIGHT:
+ this->eyeIndex = 4;
+ break;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char08/func_80AAF15C.s")
+ case TURTLE_EYEMODE_LOOK_RIGHT:
+ this->eyeIndex = 8;
+ break;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char08/DmChar08_Init.s")
+ default:
+ break;
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char08/DmChar08_Destroy.s")
+void DmChar08_ChangeAnim(SkelAnime* skelAnime, AnimationInfo* animationInfo, u16 animIndex) {
+ f32 endFrame;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char08/func_80AAF610.s")
+ animationInfo += animIndex;
+ if (animationInfo->frameCount < 0.0f) {
+ endFrame = Animation_GetLastFrame(animationInfo->animation);
+ } else {
+ endFrame = animationInfo->frameCount;
+ }
+ Animation_Change(skelAnime, animationInfo->animation, animationInfo->playSpeed, animationInfo->startFrame, endFrame,
+ animationInfo->mode, animationInfo->morphFrames);
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char08/func_80AAF79C.s")
+void DmChar08_Init(Actor* thisx, PlayState* play2) {
+ PlayState* play = play2;
+ DmChar08* this = THIS;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char08/func_80AAF884.s")
+ thisx->targetMode = 5;
+ this->eyeMode = TURTLE_EYEMODE_CLOSED;
+ thisx->targetArrowOffset = 120.0f;
+ ActorShape_Init(&thisx->shape, 0.0f, ActorShadow_DrawCircle, 24.0f);
+ SkelAnime_InitFlex(play, &this->skelAnime, &gTurtleSkel, NULL, NULL, NULL, 0);
+ Actor_ProcessInitChain(thisx, sInitChain);
+ Actor_SetScale(thisx, 0.1f);
+ this->unk_1F4 = 0;
+ this->bubbleCount = 0;
+ this->unk_1FF = 0;
+ this->alpha = 0;
+ this->animIndex = TURTLE_ANIM_IDLE;
+ this->unk_1FC = 0xFFFF;
+ this->dynapolyInitialized = false;
+ this->targetYPos = thisx->world.pos.y;
+ this->unk_1F0 = 0.0f;
+ if (play->sceneId == SCENE_31MISAKI) {
+ if (gSaveContext.save.weekEventReg[53] & 0x20) {
+ DynaPolyActor_Init(&this->dyna, 3);
+ DynaPolyActor_LoadMesh(play, &this->dyna, &gTurtleZoraCapeAwakeCol);
+ } else {
+ DynaPolyActor_Init(&this->dyna, 3);
+ DynaPolyActor_LoadMesh(play, &this->dyna, &gTurtleZoraCapeAsleepCol);
+ }
+ this->dynapolyInitialized = true;
+ } else if (play->sceneId == SCENE_SEA) {
+ DynaPolyActor_Init(&this->dyna, 3);
+ DynaPolyActor_LoadMesh(play, &this->dyna, &sTurtleGreatBayTempleCol);
+ this->dynapolyInitialized = true;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char08/func_80AAF8F4.s")
+ this->palmTree1 = Actor_Spawn(&play->actorCtx, play, ACTOR_OBJ_YASI, thisx->world.pos.x + -80.0f,
+ thisx->world.pos.y + 390.0f, thisx->world.pos.z, 0, 0, 0, 1);
+ this->palmTree2 = Actor_Spawn(&play->actorCtx, play, ACTOR_OBJ_YASI, thisx->world.pos.x + 68.0f,
+ thisx->world.pos.y + 368.0f, thisx->world.pos.z - 174.0f, 0, 0x7530, 0, 1);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char08/func_80AAFA18.s")
+ switch (play->sceneId) {
+ case SCENE_31MISAKI:
+ if (gSaveContext.save.weekEventReg[53] & 0x20) {
+ thisx->world.pos.x = -6480.0f;
+ this->targetYPos = -120.0f;
+ thisx->world.pos.z = 1750.0f;
+ thisx->world.rot.x = 0;
+ thisx->world.rot.y = -0x7234;
+ thisx->world.rot.z = 0;
+ thisx->shape.rot.x = 0;
+ thisx->shape.rot.y = -0x7234;
+ thisx->shape.rot.z = 0;
+ this->unk_1F0 = 1.0f;
+ this->unk_1FF = 2;
+ this->animIndex = TURTLE_ANIM_FLOAT;
+ this->unk_203 = 0x63;
+ this->eyeMode = TURTLE_EYEMODE_BLINK_STRAIGHT;
+ this->unk_207 = 0;
+ this->unk_208 = 0;
+ thisx->flags |= ACTOR_FLAG_1;
+ if (gSaveContext.save.entrance == ENTRANCE(ZORA_CAPE, 8)) {
+ this->eyeMode = TURTLE_EYEMODE_BLINK_LEFT;
+ this->actionFunc = func_80AAFAC4;
+ } else {
+ this->actionFunc = func_80AAF8F4;
+ }
+ } else {
+ this->actionFunc = DmChar08_WaitForSong;
+ }
+ break;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char08/func_80AAFAC4.s")
+ case SCENE_SEA:
+ this->unk_1FF = 2;
+ this->animIndex = TURTLE_ANIM_FLOAT;
+ this->unk_203 = 0x63;
+ this->eyeMode = TURTLE_EYEMODE_BLINK_LEFT;
+ this->unk_207 = 0;
+ this->unk_208 = 0;
+ thisx->flags |= ACTOR_FLAG_1;
+ this->actionFunc = func_80AAFAE4;
+ this->unk_1F0 = 1.0f;
+ break;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char08/func_80AAFAE4.s")
+ case SCENE_KONPEKI_ENT:
+ this->unk_1FF = 2;
+ this->animIndex = TURTLE_ANIM_FLOAT;
+ this->unk_203 = 0x63;
+ this->eyeMode = TURTLE_EYEMODE_BLINK_LEFT;
+ this->unk_207 = 0;
+ this->unk_208 = 0;
+ this->actionFunc = DmChar08_DoNothing;
+ this->unk_1F0 = 1.0f;
+ break;
+ }
+ DmChar08_ChangeAnim(&this->skelAnime, &sAnimationInfo[this->animIndex], 0);
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char08/func_80AAFB04.s")
+void DmChar08_Destroy(Actor* thisx, PlayState* play) {
+ DmChar08* this = THIS;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char08/func_80AAFB94.s")
+ if (this->dynapolyInitialized) {
+ DynaPoly_DeleteBgActor(play, &play->colCtx.dyna, this->dyna.bgId);
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char08/func_80AAFBA4.s")
+static s16 sSuccessSoundAlreadyPlayed = false;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char08/func_80AAFCCC.s")
+void DmChar08_WaitForSong(DmChar08* this, PlayState* play) {
+ Player* player = GET_PLAYER(play);
+ Player* player2 = GET_PLAYER(play);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char08/func_80AAFE78.s")
+ if ((player2->stateFlags2 & PLAYER_STATE2_8000000) &&
+ ((player2->actor.world.pos.x > -5780.0f) && (player2->actor.world.pos.x < -5385.0f) &&
+ (player2->actor.world.pos.z > 1120.0f) && (player2->actor.world.pos.z < 2100.0f))) {
+ if (!sSuccessSoundAlreadyPlayed) {
+ play_sound(NA_SE_SY_TRE_BOX_APPEAR);
+ sSuccessSoundAlreadyPlayed = true;
+ }
+ } else {
+ sSuccessSoundAlreadyPlayed = false;
+ }
+ if ((player->transformation == PLAYER_FORM_ZORA) && (play->msgCtx.ocarinaMode == 3) &&
+ (play->msgCtx.lastPlayedSong == OCARINA_SONG_NEW_WAVE)) {
+ if ((player2->actor.world.pos.x > -5780.0f) && (player2->actor.world.pos.x < -5385.0f)) {
+ if ((player2->actor.world.pos.z > 1120.0f) && (player2->actor.world.pos.z < 2100.0f)) {
+ this->actionFunc = DmChar08_SetupAppearCs;
+ }
+ }
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char08/func_80AAFE88.s")
+void DmChar08_SetupAppearCs(DmChar08* this, PlayState* play) {
+ s16 cs1 = this->dyna.actor.cutscene;
+ s16 cs = ActorCutscene_GetAdditionalCutscene(
+ ActorCutscene_GetAdditionalCutscene(ActorCutscene_GetAdditionalCutscene(cs1)));
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char08/func_80AB01E8.s")
+ if (gSaveContext.save.weekEventReg[93] & 8) {
+ cs1 = cs;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char08/func_80AB023C.s")
+ if (ActorCutscene_GetCanPlayNext(cs1)) {
+ ActorCutscene_Start(cs1, &this->dyna.actor);
+ gSaveContext.save.weekEventReg[53] |= 0x20;
+ gSaveContext.save.weekEventReg[93] |= 8;
+ DynaPoly_DeleteBgActor(play, &play->colCtx.dyna, this->dyna.bgId);
+ this->actionFunc = func_80AAF884;
+ } else {
+ ActorCutscene_SetIntentToPlay(cs1);
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char08/func_80AB032C.s")
+void func_80AAF884(DmChar08* this, PlayState* play) {
+ if (play->csCtx.state == CS_STATE_0) {
+ DynaPolyActor_Init(&this->dyna, 3);
+ DynaPolyActor_LoadMesh(play, &this->dyna, &gTurtleZoraCapeAwakeCol);
+ this->dyna.actor.flags |= ACTOR_FLAG_1;
+ this->actionFunc = func_80AAF8F4;
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char08/func_80AB096C.s")
+void func_80AAF8F4(DmChar08* this, PlayState* play) {
+ s32 pad;
+ f32 yOffset;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char08/func_80AB0A10.s")
+ if (fabsf(this->dyna.actor.xzDistToPlayer) < 200.0f) {
+ this->actionFunc = func_80AAFA18;
+ }
+ this->unk_1FA += 200;
+ yOffset = 50.0f;
+ yOffset *= Math_SinS(this->unk_1FA);
+ Math_SmoothStepToF(&this->dyna.actor.world.pos.x, -6400.0f, 0.2f, 2.0f, 0.1f);
+ Math_SmoothStepToF(&this->targetYPos, -180.0f + yOffset, 0.5f, 5.0f, 0.1f);
+ Math_SmoothStepToF(&this->dyna.actor.world.pos.z, 1750.0f, 0.5f, 20.0f, 0.1f);
+ Math_SmoothStepToS(&this->dyna.actor.world.rot.y, -0x7234, 0xA, 0xDC, 1);
+ Math_SmoothStepToS(&this->dyna.actor.shape.rot.y, -0x7234, 0xA, 0xDC, 1);
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char08/DmChar08_Update.s")
+void func_80AAFA18(DmChar08* this, PlayState* play) {
+ s16 nextCs;
+ s16 nextCs2;
+ s16 nextCs1;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char08/func_80AB0E3C.s")
+ nextCs1 = ActorCutscene_GetAdditionalCutscene(this->dyna.actor.cutscene);
+ nextCs2 = nextCs1;
+ nextCs1 = ActorCutscene_GetAdditionalCutscene(nextCs1);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char08/func_80AB0E7C.s")
+ nextCs = ((void)0, gSaveContext.save.weekEventReg[53] & 0x40) ? nextCs1 : nextCs2;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char08/func_80AB0F90.s")
+ if (ActorCutscene_GetCanPlayNext(nextCs) != 0) {
+ gSaveContext.save.weekEventReg[53] |= 0x40;
+ ActorCutscene_Start(nextCs, &this->dyna.actor);
+ this->actionFunc = DmChar08_DoNothing;
+ } else {
+ ActorCutscene_SetIntentToPlay(nextCs);
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char08/DmChar08_Draw.s")
+void func_80AAFAC4(DmChar08* this, PlayState* play) {
+ if (play->csCtx.state == 0) {
+ this->actionFunc = func_80AAF8F4;
+ }
+}
+
+void func_80AAFAE4(DmChar08* this, PlayState* play) {
+ if (play->csCtx.state == 0) {
+ this->actionFunc = func_80AAFB04;
+ }
+}
+
+void func_80AAFB04(DmChar08* this, PlayState* play) {
+ Player* player = GET_PLAYER(play);
+
+ if ((fabsf(this->dyna.actor.xzDistToPlayer) < 200.0f) && (player->actor.world.pos.y > 0.0f)) {
+ play->nextEntrance = ENTRANCE(ZORA_CAPE, 7);
+ play->transitionTrigger = TRANS_TRIGGER_START;
+ Scene_SetExitFade(play);
+ this->actionFunc = func_80AAFB94;
+ }
+}
+
+void func_80AAFB94(DmChar08* this, PlayState* play) {
+}
+
+Color_RGBA8 sLargeTurtleBubblePrimColor = { 250, 200, 250, 100 };
+Color_RGBA8 sLargeTurtleBubbleEnvColor = { 80, 80, 80, 0 };
+Vec3f sLargeTurtleBubbleAccel = { 0.0f, -0.8f, 0.0f };
+
+void DmChar08_SpawnBubbles(DmChar08* this, PlayState* play) {
+ s32 i;
+ Vec3f velocity;
+
+ velocity.x = (Rand_ZeroOne() - 0.5f) * 24.0f;
+ velocity.y = -5.2f;
+ velocity.z = 4.0f;
+ sLargeTurtleBubbleAccel.x = 0.0f;
+ sLargeTurtleBubbleAccel.y = 1.18f;
+ sLargeTurtleBubbleAccel.z = 0.0f;
+ for (i = 0; i < this->bubbleCount; i++) {
+ EffectSsDtBubble_SpawnCustomColor(play, &this->bubblePos, &velocity, &sLargeTurtleBubbleAccel,
+ &sLargeTurtleBubblePrimColor, &sLargeTurtleBubbleEnvColor,
+ Rand_S16Offset(80, 130), 30, 0);
+ }
+}
+
+void func_80AAFCCC(DmChar08* this, PlayState* play) {
+ switch (play->sceneId) {
+ case SCENE_31MISAKI:
+ if (!(gSaveContext.save.weekEventReg[55] & 0x80)) {
+ switch (this->unk_206) {
+ case 0:
+ break;
+
+ case 1:
+ // Fire hookshot
+ Message_StartTextbox(play, 0x102A, &this->dyna.actor);
+ this->unk_206++;
+ break;
+
+ case 2:
+ // I know your name
+ if (Message_GetState(&play->msgCtx) == TEXT_STATE_CLOSING) {
+ Message_StartTextbox(play, 0x102B, &this->dyna.actor);
+ this->unk_206 = 0;
+ }
+ break;
+ }
+ } else {
+ switch (this->unk_206) {
+ case 0:
+ break;
+
+ case 1:
+ // Going to the temple again
+ Message_StartTextbox(play, 0x103B, &this->dyna.actor);
+ this->unk_206++;
+ break;
+
+ case 2:
+ if (Message_GetState(&play->msgCtx) == TEXT_STATE_CLOSING) {
+ func_801477B4(play);
+ this->unk_206 = 0;
+ }
+ break;
+ }
+ }
+ return;
+
+ case SCENE_SEA:
+ switch (this->unk_206) {
+ case 0:
+ break;
+
+ case 1:
+ Message_StartTextbox(play, 0x102E, &this->dyna.actor);
+ this->unk_206++;
+ break;
+
+ case 2:
+ if (Message_GetState(&play->msgCtx) == TEXT_STATE_CLOSING) {
+ Message_StartTextbox(play, 0x102F, &this->dyna.actor);
+ this->unk_206 = 0;
+ }
+ break;
+ }
+ break;
+ }
+}
+
+void DmChar08_DoNothing(DmChar08* this, PlayState* play) {
+}
+
+void func_80AAFE88(DmChar08* this, PlayState* play) {
+ s32 actorActionIndex;
+ CsCmdActorAction* csAction;
+ f32 phi_f12;
+
+ if (Cutscene_CheckActorAction(play, 474)) {
+ actorActionIndex = Cutscene_GetActorActionIndex(play, 474);
+ if (this->unk_1F6 != play->csCtx.actorActions[actorActionIndex]->action) {
+ this->unk_1F6 = play->csCtx.actorActions[actorActionIndex]->action;
+ switch (play->csCtx.actorActions[actorActionIndex]->action) {
+ case 1:
+ this->animIndex = TURTLE_ANIM_IDLE;
+ break;
+
+ case 3:
+ this->bubbleCount = 2;
+ break;
+
+ case 4:
+ this->animIndex = TURTLE_ANIM_FLOAT;
+ break;
+
+ case 5:
+ this->animIndex = TURTLE_ANIM_SWIM;
+ break;
+
+ case 6:
+ this->eyeMode = TURTLE_EYEMODE_BLINK_LEFT;
+ break;
+
+ case 7:
+ this->eyeMode = TURTLE_EYEMODE_CLOSED;
+ break;
+
+ case 8:
+ this->animIndex = TURTLE_ANIM_YAWN;
+ break;
+
+ case 9:
+ this->animIndex = TURTLE_ANIM_FLOAT;
+ break;
+
+ case 10:
+ this->animIndex = TURTLE_ANIM_COUGH;
+ break;
+
+ case 12:
+ this->animIndex = TURTLE_ANIM_SPEAK2;
+ break;
+
+ case 13:
+ this->bubbleCount = 0;
+ break;
+
+ case 14:
+ Actor_PlaySfxAtPos(&this->dyna.actor, NA_SE_EV_BIG_TORTOISE_ROLL);
+ this->animIndex = TURTLE_ANIM_FLOAT;
+ break;
+ }
+ }
+ switch (play->csCtx.actorActions[actorActionIndex]->action) {
+ case 2:
+ this->unk_1FF = 1;
+ phi_f12 = 2.0f * Environment_LerpWeight(play->csCtx.actorActions[actorActionIndex]->endFrame,
+ play->csCtx.actorActions[actorActionIndex]->startFrame,
+ play->csCtx.frames);
+ if (phi_f12 > 1.0f) {
+ phi_f12 = 1.0f;
+ }
+
+ this->alpha = (1.0f - phi_f12) * 255.0f;
+ if (this->alpha < 6) {
+ this->unk_1FF = 2;
+ }
+
+ Cutscene_ActorTranslateAndYaw(&this->dyna.actor, play, actorActionIndex);
+ break;
+
+ case 5:
+ Cutscene_ActorTranslateAndYawSmooth(&this->dyna.actor, play, actorActionIndex);
+ break;
+
+ case 14:
+ Cutscene_ActorTranslate(&this->dyna.actor, play, actorActionIndex);
+ Math_SmoothStepToS(&this->dyna.actor.world.rot.y, play->csCtx.actorActions[actorActionIndex]->rot.y,
+ 0xA, 0xDC, 1);
+ this->dyna.actor.shape.rot.y = this->dyna.actor.world.rot.y;
+ break;
+
+ default:
+ Cutscene_ActorTranslateAndYaw(&this->dyna.actor, play, actorActionIndex);
+ break;
+ }
+ this->targetYPos = this->dyna.actor.world.pos.y;
+ if ((this->unk_1FF >= 2) || (play->csCtx.actorActions[actorActionIndex]->action == 2)) {
+ Math_SmoothStepToF(&this->unk_1F0, 1.0f, 0.02f, 0.1f, 0.00001f);
+ }
+ } else {
+ this->unk_1F6 = 99;
+ }
+}
+
+void func_80AB01E8(DmChar08* this, PlayState* play) {
+ if (this->animIndex != this->unk_203) {
+ this->unk_203 = this->animIndex;
+ DmChar08_ChangeAnim(&this->skelAnime, &sAnimationInfo[this->animIndex], 0);
+ }
+}
+
+void func_80AB023C(DmChar08* this, PlayState* play) {
+ if ((play->msgCtx.currentTextId != this->unk_1FC) && (play->msgCtx.currentTextId != 0)) {
+ this->unk_1FC = play->msgCtx.currentTextId;
+ this->unk_208 = 0;
+ switch (play->msgCtx.currentTextId) {
+ case 0x1025: // Slept well
+ this->unk_207 = 1;
+ break;
+
+ case 0x1026: // Time Flies
+ this->unk_207 = 2;
+ break;
+
+ case 0x1027: // See Everything
+ this->unk_207 = 3;
+ break;
+
+ case 0x1028: // No time
+ this->unk_207 = 4;
+ break;
+
+ case 0x1029: // Quick lets go
+ this->unk_207 = 10;
+ break;
+
+ case 0x102C: // Having trouble
+ this->unk_207 = 5;
+ break;
+
+ case 0x102D: // Ready, climb
+ this->unk_207 = 8;
+ break;
+
+ case 0x102A: // Fire hookshot
+ this->unk_207 = 6;
+ break;
+
+ case 0x102B: // I know your name
+ this->unk_207 = 2;
+ break;
+
+ case 0x102E: // Returning to shore
+ this->unk_207 = 9;
+ break;
+
+ case 0x102F: // It is okay to retreat
+ this->unk_207 = 7;
+ break;
+
+ case 0x103B: // Going to the temple again
+ this->unk_207 = 6;
+
+ break;
+ case 0x1030: // Return to sleep
+ this->unk_207 = 4;
+ break;
+ }
+ }
+}
+
+void func_80AB032C(DmChar08* this, PlayState* play) {
+ switch (this->unk_207) {
+ case 1:
+ switch (this->unk_208) {
+ case 0:
+ this->animIndex = TURTLE_ANIM_YAWN;
+ this->eyeMode = TURTLE_EYEMODE_CLOSED;
+ this->unk_208++;
+ break;
+
+ case 1:
+ if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) {
+ this->animIndex = TURTLE_ANIM_FLOAT;
+ this->eyeMode = TURTLE_EYEMODE_BLINK_LEFT;
+ this->unk_207 = 0;
+ this->unk_208 = 0;
+ }
+ break;
+ }
+ break;
+
+ case 2:
+ switch (this->unk_208) {
+ case 0:
+ this->animIndex = TURTLE_ANIM_COUGH;
+ this->eyeMode = TURTLE_EYEMODE_CLOSED;
+ this->unk_208++;
+ break;
+
+ case 1:
+ if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) {
+ this->animIndex = TURTLE_ANIM_SPEAK1;
+ this->eyeMode = TURTLE_EYEMODE_BLINK_LEFT;
+ this->unk_208++;
+ }
+ break;
+
+ case 2:
+ if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) {
+ this->animIndex = TURTLE_ANIM_FLOAT;
+ this->eyeMode = TURTLE_EYEMODE_BLINK_LEFT;
+ this->unk_207 = 0;
+ this->unk_208 = 0;
+ }
+ break;
+ }
+ break;
+
+ case 3:
+ case 4:
+ case 8:
+ switch (this->unk_208) {
+ case 0:
+ this->animIndex = TURTLE_ANIM_SPEAK1;
+ if (this->unk_207 >= 5) {
+ this->eyeMode = TURTLE_EYEMODE_CLOSED;
+ } else {
+ this->eyeMode = TURTLE_EYEMODE_BLINK_LEFT;
+ }
+ this->unk_208 = 2;
+ break;
+
+ case 2:
+ if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) {
+ this->animIndex = TURTLE_ANIM_SPEAK2;
+ this->eyeMode = TURTLE_EYEMODE_CLOSED;
+ this->unk_208++;
+ }
+ break;
+
+ case 3:
+ if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) {
+ if (this->unk_207 != 4) {
+ this->animIndex = TURTLE_ANIM_FLOAT;
+ this->eyeMode = TURTLE_EYEMODE_BLINK_LEFT;
+ this->unk_207 = 0;
+ this->unk_208 = 0;
+ } else {
+ this->animIndex = TURTLE_ANIM_SPEAK1;
+ this->eyeMode = TURTLE_EYEMODE_BLINK_LEFT;
+ this->unk_208++;
+ }
+ }
+ break;
+
+ case 4:
+ case 5:
+ if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) {
+ this->unk_208++;
+ }
+ break;
+
+ case 6:
+ if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) {
+ this->animIndex = TURTLE_ANIM_FLOAT;
+ this->eyeMode = TURTLE_EYEMODE_BLINK_LEFT;
+ this->unk_207 = 0;
+ this->unk_208 = 0;
+ }
+ break;
+ }
+ break;
+
+ case 5:
+ switch (this->unk_208) {
+ case 0:
+ this->animIndex = TURTLE_ANIM_SPEAK1;
+ this->eyeMode = TURTLE_EYEMODE_BLINK_LEFT;
+ this->unk_208++;
+ break;
+
+ case 2:
+ case 3:
+ if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) {
+ this->unk_208++;
+ }
+ break;
+
+ case 4:
+ if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) {
+ this->animIndex = TURTLE_ANIM_SPEAK2;
+ this->eyeMode = TURTLE_EYEMODE_CLOSED;
+ this->unk_208++;
+ }
+ break;
+
+ case 5:
+ if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) {
+ this->animIndex = TURTLE_ANIM_FLOAT;
+ this->eyeMode = TURTLE_EYEMODE_BLINK_LEFT;
+ this->unk_207 = 0;
+ this->unk_208 = 0;
+ }
+ break;
+ }
+ break;
+
+ case 6:
+ switch (this->unk_208) {
+ case 0:
+ this->animIndex = TURTLE_ANIM_SPEAK1;
+ this->eyeMode = TURTLE_EYEMODE_LOOK_RIGHT;
+ this->unk_208++;
+ break;
+
+ case 1:
+ if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) {
+ this->unk_208++;
+ }
+ break;
+
+ case 2:
+ if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) {
+ this->animIndex = TURTLE_ANIM_FLOAT;
+ this->eyeMode = TURTLE_EYEMODE_BLINK_LEFT;
+ this->unk_207 = 0;
+ this->unk_208 = 0;
+ }
+ break;
+ }
+ break;
+
+ case 7:
+ switch (this->unk_208) {
+ case 0:
+ this->animIndex = TURTLE_ANIM_SPEAK2;
+ this->eyeMode = TURTLE_EYEMODE_CLOSED;
+ this->unk_208++;
+ break;
+
+ case 1:
+ if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) {
+ this->animIndex = TURTLE_ANIM_SPEAK1;
+ this->eyeMode = TURTLE_EYEMODE_CLOSED;
+ this->unk_208++;
+ }
+ break;
+
+ case 2:
+ if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) {
+ this->animIndex = TURTLE_ANIM_FLOAT;
+ this->eyeMode = TURTLE_EYEMODE_BLINK_LEFT;
+ this->unk_207 = 0;
+ this->unk_208 = 0;
+ }
+ break;
+ }
+ break;
+
+ case 9:
+ switch (this->unk_208) {
+ case 0:
+ this->animIndex = TURTLE_ANIM_SPEAK1;
+ this->eyeMode = TURTLE_EYEMODE_BLINK_LEFT;
+ this->unk_208++;
+ break;
+
+ case 1:
+ if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) {
+ this->unk_208++;
+ }
+ if ((Message_GetState(&play->msgCtx) == TEXT_STATE_DONE) && Message_ShouldAdvance(play)) {
+ this->unk_208 = 3;
+ }
+ break;
+
+ case 2:
+ if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) {
+ this->animIndex = TURTLE_ANIM_FLOAT;
+ this->eyeMode = TURTLE_EYEMODE_BLINK_LEFT;
+ this->unk_208++;
+ }
+ if ((Message_GetState(&play->msgCtx) == TEXT_STATE_DONE) && Message_ShouldAdvance(play)) {
+ this->unk_208 = 3;
+ }
+ break;
+
+ case 3:
+ if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) {
+ this->animIndex = TURTLE_ANIM_COUGH;
+ this->eyeMode = TURTLE_EYEMODE_CLOSED;
+ this->unk_208++;
+ }
+ break;
+
+ case 4:
+ if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) {
+ this->animIndex = TURTLE_ANIM_FLOAT;
+ this->eyeMode = TURTLE_EYEMODE_BLINK_LEFT;
+ this->unk_207 = 0;
+ this->unk_208 = 0;
+ }
+ break;
+ }
+ break;
+ case 10:
+ switch (this->unk_208) {
+ case 0:
+ this->animIndex = TURTLE_ANIM_SPEAK1;
+ this->eyeMode = TURTLE_EYEMODE_BLINK_LEFT;
+ this->unk_208++;
+ break;
+ case 1:
+ if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) {
+ this->animIndex = TURTLE_ANIM_SPEAK2;
+ this->eyeMode = TURTLE_EYEMODE_CLOSED;
+ this->unk_208++;
+ }
+ break;
+ case 2:
+ if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) {
+ this->animIndex = TURTLE_ANIM_SPEAK1;
+ this->eyeMode = TURTLE_EYEMODE_BLINK_LEFT;
+ this->unk_208++;
+ }
+ break;
+ case 3:
+ if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) {
+ this->animIndex = TURTLE_ANIM_FLOAT;
+ this->eyeMode = TURTLE_EYEMODE_BLINK_LEFT;
+ this->unk_207 = 0;
+ this->unk_208 = 0;
+ }
+ break;
+ }
+ break;
+ }
+}
+
+void func_80AB096C(DmChar08* this, PlayState* play) {
+ if ((play->csCtx.state != 0) && (play->sceneId == SCENE_31MISAKI) && (gSaveContext.sceneLayer == 0) &&
+ (play->csCtx.currentCsIndex == 0)) {
+ if ((play->csCtx.frames >= 890) && (play->csCtx.frames < 922)) {
+ Actor_PlaySfxAtPos(&this->dyna.actor, NA_SE_EV_EARTHQUAKE_LAST2 - SFX_FLAG);
+ }
+ }
+ if ((this->animIndex == TURTLE_ANIM_SWIM) && Animation_OnFrame(&this->skelAnime, 16.0f)) {
+ Actor_PlaySfxAtPos(&this->dyna.actor, NA_SE_EV_BIG_TORTOISE_SWIM);
+ }
+}
+
+void DmChar08_UpdateCollision(DmChar08* this, PlayState* play) {
+ Player* player = GET_PLAYER(play);
+ f32 curFrame;
+ f32 phi_f2;
+ f32 phi_f0;
+ f32 phi_f12;
+ s32 i;
+
+ if (player->actor.world.pos.x > 0.0f) {
+ curFrame = this->skelAnime.curFrame;
+ if (curFrame <= 19.0f) {
+ phi_f12 = 19.0f;
+ phi_f2 = curFrame / 19.0f;
+ } else {
+ phi_f2 = (29.0f - curFrame) / 9.0f;
+ phi_f12 = 29.0f;
+ }
+
+ sTurtleGreatBayTempleCol.polyList = sTurtleGreatBayTempleColPolygons;
+
+ for (i = 0; i < ARRAY_COUNT(sTurtleGreatBayTempleColVertices); i++) {
+ sTurtleGreatBayTempleColVertices[i].x = sTurtleGreatBayTempleColVertices2[i].x;
+ }
+
+ sTurtleGreatBayTempleColVertices[0].y = (100.0f * phi_f2) + 900.0f;
+ sTurtleGreatBayTempleColVertices[1].y = (100.0f * phi_f2) + 900.0f;
+ sTurtleGreatBayTempleColVertices[2].y = (500.0f * phi_f2) + -200.0f;
+ sTurtleGreatBayTempleColVertices[3].y = (900.0f * phi_f2) + -800.0f;
+ sTurtleGreatBayTempleColVertices[5].y = 0x4B0;
+ sTurtleGreatBayTempleColVertices[9].y = 0x6A4;
+ } else {
+ phi_f0 = this->skelAnime.curFrame + 26.0f;
+ if (phi_f0 > 29.0f) {
+ phi_f12 = 29.0f;
+ phi_f0 -= 29.0f;
+ }
+
+ if (phi_f0 <= 18.0f) {
+ phi_f2 = phi_f0 / 18.0f;
+ } else {
+ phi_f2 = (29.0f - phi_f0) / 10.0f;
+ }
+
+ sTurtleGreatBayTempleCol.polyList = sTurtleGreatBayTempleColPolygons2;
+
+ for (i = 0; i < ARRAY_COUNT(sTurtleGreatBayTempleColVertices); i++) {
+ sTurtleGreatBayTempleColVertices[i].x = -sTurtleGreatBayTempleColVertices2[i].x;
+ }
+
+ sTurtleGreatBayTempleColVertices[0].y = (500.0f * phi_f2) + 720.0f;
+ sTurtleGreatBayTempleColVertices[1].y = (660.0f * phi_f2) + 420.0f;
+ sTurtleGreatBayTempleColVertices[2].y = (1130.0f * phi_f2) + -430.0f;
+ sTurtleGreatBayTempleColVertices[3].y = (1430.0f * phi_f2) + -1060.0f;
+ sTurtleGreatBayTempleColVertices[5].y = 0x4B0;
+ sTurtleGreatBayTempleColVertices[9].y = 0x6A4;
+ }
+ func_800C6554(play, &play->colCtx.dyna);
+}
+
+void DmChar08_Update(Actor* thisx, PlayState* play) {
+ DmChar08* this = THIS;
+
+ this->dyna.actor.focus.pos.x = this->focusPos.x;
+ this->dyna.actor.focus.pos.y = this->focusPos.y + this->dyna.actor.targetArrowOffset;
+ this->dyna.actor.focus.pos.z = this->focusPos.z;
+ this->dyna.actor.focus.rot.x = this->dyna.actor.world.rot.x;
+ this->dyna.actor.focus.rot.y = this->dyna.actor.world.rot.y;
+ this->dyna.actor.focus.rot.z = this->dyna.actor.world.rot.z;
+
+ if (Actor_ProcessTalkRequest(&this->dyna.actor, &play->state)) {
+ this->unk_206 = 1;
+ }
+
+ DmChar08_UpdateEyes(this);
+ this->actionFunc(this, play);
+ func_80AAFE88(this, play);
+ func_80AB023C(this, play);
+ func_80AB032C(this, play);
+ func_80AB01E8(this, play);
+ SkelAnime_Update(&this->skelAnime);
+ DmChar08_SpawnBubbles(this, play);
+ this->dyna.actor.world.pos.y = this->targetYPos;
+ if (play->sceneId == SCENE_31MISAKI) {
+ if (this->dyna.actor.xzDistToPlayer > 1300.0f) {
+ func_800C62BC(play, &play->colCtx.dyna, this->dyna.bgId);
+ } else {
+ func_800C6314(play, &play->colCtx.dyna, this->dyna.bgId);
+ }
+ }
+ if (this->unk_1FF != 0) {
+ func_80AAFCCC(this, play);
+ func_800B8614(&this->dyna.actor, play, 400.0f);
+ }
+ func_80AB096C(this, play);
+ DmChar08_UpdateCollision(this, play);
+}
+
+s32 DmChar08_OverrideLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx) {
+ if ((play->csCtx.state == 0) && (play->sceneId == SCENE_31MISAKI) &&
+ (limbIndex == TURTLE_LIMB_FRONT_RIGHT_UPPER_FLIPPER)) {
+ rot->z = -0x5E24;
+ }
+ return false;
+}
+
+void DmChar08_PostLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) {
+ DmChar08* this = THIS;
+ Vec3f src;
+
+ if (limbIndex == TURTLE_LIMB_SHELL) {
+ src.x = 800.0f;
+ src.y = 2600.0f;
+ src.z = -800.0f;
+ Matrix_MultVec3f(&src, &this->tree1Pos);
+ src.x = 2600.0f;
+ src.y = 2500.0f;
+ src.z = 700.0f;
+ Matrix_MultVec3f(&src, &this->tree2Pos);
+ } else if (limbIndex == TURTLE_LIMB_LOWER_MOUTH) {
+ src.x = 1600.0f;
+ src.y = -200.0f;
+ src.z = 0.0f;
+ Matrix_MultVec3f(&src, &this->bubblePos);
+ } else if (limbIndex == TURTLE_LIMB_UPPER_MOUTH) {
+ src.x = 600.0f;
+ src.y = 700.0f;
+ src.z = 0.0f;
+ Matrix_MultVec3f(&src, &this->focusPos);
+ }
+}
+
+void DmChar08_TransformLimbDraw(PlayState* play, s32 limbIndex, Actor* thisx) {
+ DmChar08* this = THIS;
+ f32 one;
+
+ switch (limbIndex) {
+ case TURTLE_LIMB_SHELL:
+ break;
+
+ case TURTLE_LIMB_NECK:
+ Matrix_Pop();
+ one = 1.0f;
+ Matrix_Scale(((one - 0.7f) * this->unk_1F0) + 0.7f, ((one - 0.7f) * this->unk_1F0) + 0.7f, 1.0f,
+ MTXMODE_APPLY);
+ Matrix_Push();
+ break;
+
+ case TURTLE_LIMB_FRONT_LEFT_UPPER_FLIPPER:
+ case TURTLE_LIMB_FRONT_LEFT_LOWER_FLIPPER:
+ case TURTLE_LIMB_FRONT_RIGHT_UPPER_FLIPPER:
+ case TURTLE_LIMB_FRONT_RIGHT_LOWER_FLIPPER:
+ Matrix_Pop();
+ Matrix_Scale((this->unk_1F0 * 0.4f) + 0.6f, (this->unk_1F0 * 0.4f) + 0.6f, (this->unk_1F0 * 0.4f) + 0.6f,
+ MTXMODE_APPLY);
+ Matrix_Push();
+ break;
+
+ case TURTLE_LIMB_FRONT_LEFT_END_FLIPPER:
+ case TURTLE_LIMB_FRONT_RIGHT_END_FLIPPER:
+ Matrix_Scale((this->unk_1F0 * 0.4f) + 0.6f, (this->unk_1F0 * 0.4f) + 0.6f, (this->unk_1F0 * 0.4f) + 0.6f,
+ MTXMODE_APPLY);
+ break;
+
+ case TURTLE_TAIL_LIMB:
+ Matrix_Pop();
+ Matrix_Scale((this->unk_1F0 * 0.52f) + 0.48f, (this->unk_1F0 * 0.52f) + 0.48f,
+ (this->unk_1F0 * 0.52f) + 0.48f, MTXMODE_APPLY);
+ Matrix_Push();
+ break;
+
+ case TURTLE_LIMB_BACK_LEFT_FLIPPER:
+ case TURTLE_LIMB_BACK_RIGHT_FLIPPER:
+ Matrix_Scale((this->unk_1F0 * 0.55f) + 0.45f, (this->unk_1F0 * 0.2f) + 0.8f,
+ (this->unk_1F0 * 0.55f) + 0.45f, MTXMODE_APPLY);
+ break;
+ }
+}
+
+TexturePtr sBigTurtleEyeTextures[] = {
+ gTurtleEyeOpenLeftTex, gTurtleEyeHalfLeftTex, gTurtleEyeClosedTex,
+ gTurtleEyeHalfLeftTex, gTurtleEyeOpenStraightTex, gTurtleEyeHalfStraightTex,
+ gTurtleEyeClosedTex, gTurtleEyeHalfStraightTex, gTurtleEyeOpenRightTex,
+};
+
+void DmChar08_Draw(Actor* thisx, PlayState* play) {
+ s32 pad;
+ DmChar08* this = THIS;
+
+ OPEN_DISPS(play->state.gfxCtx);
+ func_8012C28C(play->state.gfxCtx);
+
+ gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(sBigTurtleEyeTextures[this->eyeIndex]));
+ gSPSegment(POLY_OPA_DISP++, 0x09, Lib_SegmentedToVirtual(sBigTurtleEyeTextures[this->eyeIndex]));
+ if ((this->unk_1FF > 0) || (play->csCtx.state != CS_STATE_0)) {
+ SkelAnime_DrawTransformFlexOpa(play, this->skelAnime.skeleton, this->skelAnime.jointTable,
+ this->skelAnime.dListCount, DmChar08_OverrideLimbDraw, DmChar08_PostLimbDraw,
+ DmChar08_TransformLimbDraw, &this->dyna.actor);
+ this->palmTree1->world.pos.x = this->tree1Pos.x;
+ this->palmTree1->world.pos.y = this->tree1Pos.y;
+ this->palmTree1->world.pos.z = this->tree1Pos.z;
+ this->palmTree2->world.pos.x = this->tree2Pos.x;
+ this->palmTree2->world.pos.y = this->tree2Pos.y;
+ this->palmTree2->world.pos.z = this->tree2Pos.z;
+ }
+ if (this->unk_1FF == 0) {
+ Scene_SetRenderModeXlu(play, 0, 1);
+ gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_OPA_DISP++, gTurtleAsleepDL);
+ } else if (this->unk_1FF == 1) {
+ func_8012C2DC(play->state.gfxCtx);
+ Scene_SetRenderModeXlu(play, 2, 2);
+ gDPSetEnvColor(POLY_XLU_DISP++, 0, 0, 0, this->alpha);
+ gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_XLU_DISP++, gTurtleAsleepDL);
+ }
+ CLOSE_DISPS(play->state.gfxCtx);
+}
diff --git a/src/overlays/actors/ovl_Dm_Char08/z_dm_char08.h b/src/overlays/actors/ovl_Dm_Char08/z_dm_char08.h
index 1718a9fb02..2cdbb52c7d 100644
--- a/src/overlays/actors/ovl_Dm_Char08/z_dm_char08.h
+++ b/src/overlays/actors/ovl_Dm_Char08/z_dm_char08.h
@@ -8,10 +8,36 @@ struct DmChar08;
typedef void (*DmChar08ActionFunc)(struct DmChar08*, PlayState*);
typedef struct DmChar08 {
- /* 0x000 */ Actor actor;
- /* 0x144 */ char unk_144[0x5C];
+ /* 0x000 */ DynaPolyActor dyna;
+ /* 0x15C */ SkelAnime skelAnime;
/* 0x1A0 */ DmChar08ActionFunc actionFunc;
- /* 0x1A4 */ char unk_1A4[0x68];
+ /* 0x1A4 */ Actor* palmTree1;
+ /* 0x1A8 */ Actor* palmTree2;
+ /* 0x1AC */ Vec3f tree1Pos;
+ /* 0x1B8 */ Vec3f tree2Pos;
+ /* 0x1C4 */ Vec3f bubblePos;
+ /* 0x1D0 */ Vec3f focusPos;
+ /* 0x1DC */ UNK_TYPE1 unk_1DC[8];
+ /* 0x1E4 */ f32 targetYPos;
+ /* 0x1E8 */ UNK_TYPE1 unk_1E8[8];
+ /* 0x1F0 */ f32 unk_1F0;
+ /* 0x1F4 */ s16 unk_1F4;
+ /* 0x1F6 */ s16 unk_1F6;
+ /* 0x1F6 */ s16 blinkTimer;
+ /* 0x1FA */ s16 unk_1FA;
+ /* 0x1FC */ u16 unk_1FC;
+ /* 0x1FE */ u8 bubbleCount;
+ /* 0x1FF */ u8 unk_1FF;
+ /* 0x200 */ u8 eyeMode;
+ /* 0x201 */ u8 eyeIndex;
+ /* 0x202 */ u8 animIndex;
+ /* 0x203 */ u8 unk_203;
+ /* 0x204 */ UNK_TYPE1 unk_204;
+ /* 0x205 */ u8 alpha;
+ /* 0x206 */ u8 unk_206;
+ /* 0x207 */ u8 unk_207;
+ /* 0x208 */ u8 unk_208;
+ /* 0x209 */ u8 dynapolyInitialized;
} DmChar08; // size = 0x20C
extern const ActorInit Dm_Char08_InitVars;
diff --git a/src/overlays/actors/ovl_Eff_Kamejima_Wave/z_eff_kamejima_wave.c b/src/overlays/actors/ovl_Eff_Kamejima_Wave/z_eff_kamejima_wave.c
index 83842569fe..2de3d86041 100644
--- a/src/overlays/actors/ovl_Eff_Kamejima_Wave/z_eff_kamejima_wave.c
+++ b/src/overlays/actors/ovl_Eff_Kamejima_Wave/z_eff_kamejima_wave.c
@@ -56,7 +56,7 @@ void EffKamejimaWave_Init(Actor* thisx, PlayState* play) {
this->actionFunc = func_80BCEC6C;
sVtxAlpha = 255;
}
- D_80BCF1C4 = Lib_SegmentedToVirtual(object_kamejima_Matanimheader_001AF0);
+ D_80BCF1C4 = Lib_SegmentedToVirtual(gTurtleWaveTexAnim);
}
void EffKamejimaWave_Destroy(Actor* thisx, PlayState* play) {
@@ -137,7 +137,7 @@ void EffKamejimaWave_Update(Actor* thisx, PlayState* play) {
}
void EffKamejimaWave_SetVtxAlpha(u8 alpha) {
- Vtx* vtx = Lib_SegmentedToVirtual(&object_kamejima_Vtx_000000);
+ Vtx* vtx = Lib_SegmentedToVirtual(&gTurtleWaveVtx);
vtx[2].v.cn[3] = alpha;
vtx[6].v.cn[3] = alpha;
@@ -165,7 +165,7 @@ void EffKamejimaWave_Draw(Actor* thisx, PlayState* play) {
AnimatedMat_Draw(play, D_80BCF1C4);
gDPSetPrimColor(POLY_XLU_DISP++, 0, 0x80, primColor.r, primColor.g, primColor.b, 255);
gDPSetEnvColor(POLY_XLU_DISP++, envColor.r, envColor.g, envColor.b, 255);
- gSPDisplayList(POLY_XLU_DISP++, object_kamejima_DL_000140);
+ gSPDisplayList(POLY_XLU_DISP++, gTurtleWaveDL);
CLOSE_DISPS(play->state.gfxCtx);
}
diff --git a/tools/disasm/functions.txt b/tools/disasm/functions.txt
index 5b05adefb4..1e0438cac8 100644
--- a/tools/disasm/functions.txt
+++ b/tools/disasm/functions.txt
@@ -11629,12 +11629,12 @@
0x80AAEABC:("DmChar07_DoNothing",),
0x80AAEACC:("DmChar07_Update",),
0x80AAEAF0:("DmChar07_Draw",),
- 0x80AAF050:("func_80AAF050",),
- 0x80AAF15C:("func_80AAF15C",),
+ 0x80AAF050:("DmChar08_UpdateEyes",),
+ 0x80AAF15C:("DmChar08_ChangeAnimation",),
0x80AAF1F8:("DmChar08_Init",),
0x80AAF5D8:("DmChar08_Destroy",),
- 0x80AAF610:("func_80AAF610",),
- 0x80AAF79C:("func_80AAF79C",),
+ 0x80AAF610:("DmChar08_WaitForSong",),
+ 0x80AAF79C:("DmChar08_SetupAppearCs",),
0x80AAF884:("func_80AAF884",),
0x80AAF8F4:("func_80AAF8F4",),
0x80AAFA18:("func_80AAFA18",),
@@ -11642,19 +11642,19 @@
0x80AAFAE4:("func_80AAFAE4",),
0x80AAFB04:("func_80AAFB04",),
0x80AAFB94:("func_80AAFB94",),
- 0x80AAFBA4:("func_80AAFBA4",),
+ 0x80AAFBA4:("DmChar08_SpawnBubbles",),
0x80AAFCCC:("func_80AAFCCC",),
- 0x80AAFE78:("func_80AAFE78",),
+ 0x80AAFE78:("DmChar08_DoNothing",),
0x80AAFE88:("func_80AAFE88",),
0x80AB01E8:("func_80AB01E8",),
0x80AB023C:("func_80AB023C",),
0x80AB032C:("func_80AB032C",),
0x80AB096C:("func_80AB096C",),
- 0x80AB0A10:("func_80AB0A10",),
+ 0x80AB0A10:("DmChar08_UpdateCollision",),
0x80AB0CC8:("DmChar08_Update",),
- 0x80AB0E3C:("func_80AB0E3C",),
- 0x80AB0E7C:("func_80AB0E7C",),
- 0x80AB0F90:("func_80AB0F90",),
+ 0x80AB0E3C:("DmChar08_OverrideLimbDraw",),
+ 0x80AB0E7C:("DmChar08_PostLimbDraw",),
+ 0x80AB0F90:("DmChar08_TransformLimbDraw",),
0x80AB1124:("DmChar08_Draw",),
0x80AB1E10:("DmChar09_ChangeAnim",),
0x80AB1EAC:("DmChar09_Init",),
diff --git a/tools/disasm/variables.txt b/tools/disasm/variables.txt
index 8b487de8a5..f8023eb2c1 100644
--- a/tools/disasm/variables.txt
+++ b/tools/disasm/variables.txt
@@ -12659,21 +12659,21 @@
0x80AAE960:("Dm_Char06_InitVars","UNK_TYPE1","",0x1),
0x80AAEFF0:("Dm_Char07_InitVars","UNK_TYPE1","",0x1),
0x80AB1370:("Dm_Char08_InitVars","UNK_TYPE1","",0x1),
- 0x80AB1390:("D_80AB1390","UNK_TYPE1","",0x1),
- 0x80AB1398:("D_80AB1398","UNK_TYPE1","",0x1),
- 0x80AB13A0:("D_80AB13A0","UNK_TYPE1","",0x1),
- 0x80AB14D0:("D_80AB14D0","UNK_TYPE1","",0x1),
- 0x80AB1600:("D_80AB1600","UNK_TYPE2","",0x2),
- 0x80AB1648:("D_80AB1648","UNK_TYPE2","",0x2),
- 0x80AB1690:("D_80AB1690","UNK_TYPE1","",0x1),
+ 0x80AB1390:("D_80AB1390","CamData","",0x8),
+ 0x80AB1398:("D_80AB1398","SurfaceType","",0x8),
+ 0x80AB13A0:("D_80AB13A0","CollisionPoly","19",0xCC),
+ 0x80AB14D0:("sTurtleGreatBayTempleColPolygons2","CollisionPoly[]","19",0xCC),
+ 0x80AB1600:("D_80AB1600","Vec3s[]","12",0x48),
+ 0x80AB1648:("D_80AB1648","Vec3s[]","12",0x48),
+ 0x80AB1690:("sTurtleGreatBayTempleCol","CollisionHeader","",0x2C),
0x80AB16A8:("D_80AB16A8","UNK_PTR","",0x4),
- 0x80AB16BC:("D_80AB16BC","UNK_TYPE1","",0x1),
- 0x80AB1764:("D_80AB1764","UNK_TYPE1","",0x1),
- 0x80AB1770:("D_80AB1770","UNK_TYPE2","",0x2),
- 0x80AB1774:("D_80AB1774","UNK_TYPE1","",0x1),
- 0x80AB1778:("D_80AB1778","UNK_TYPE1","",0x1),
- 0x80AB177C:("D_80AB177C","UNK_TYPE4","",0x4),
- 0x80AB1788:("D_80AB1788","UNK_TYPE1","",0x1),
+ 0x80AB16BC:("sLargeTurtleAnimationInfo","AnimationInfo[]","0x7",0xE0),
+ 0x80AB1764:("sInitChain","InitChainEntry","",0x1),
+ 0x80AB1770:("D_80AB1770","s16","",0x2),
+ 0x80AB1774:("sLargeTurtleBubblePrimColor","Color_RGBA8","",0x4),
+ 0x80AB1778:("sLargeTurtleBubbleEnvColor","Color_RGBA8","",0x4),
+ 0x80AB177C:("sLargeTurtleBubbelAccel","Vec3f","",0xC),
+ 0x80AB1788:("sLargeTurtleEyeTextures","TexturePtr","9",0x1),
0x80AB17B0:("jtbl_80AB17B0","UNK_PTR","",0x4),
0x80AB17C8:("D_80AB17C8","f32","",0x4),
0x80AB17CC:("D_80AB17CC","f32","",0x4),
@@ -14305,7 +14305,7 @@
0x80B3FE50:("D_80B3FE50","f32","",0x4),
0x80B3FE54:("D_80B3FE54","f32","",0x4),
0x80B3FE58:("D_80B3FE58","UNK_TYPE1","",0x1),
- 0x80B3FE70:("D_80B3FE70","UNK_TYPE1","",0x1),
+ 0x80B3FE70:("sEyeTextures","TexturePtr[]","0x9",0x4),
0x80B3FE90:("D_80B3FE90","f32","",0x4),
0x80B3FE94:("D_80B3FE94","f32","",0x4),
0x80B40760:("Bg_Goron_Oyu_InitVars","UNK_TYPE1","",0x1),