diff --git a/.gitignore b/.gitignore
index aa4a3a5c41..a2acf29c31 100644
--- a/.gitignore
+++ b/.gitignore
@@ -14,6 +14,7 @@ tags
# Project-specific ignores
*.z64
+*.sra
*.bin
*.elf
archive/
diff --git a/assets/xml/objects/gameplay_dangeon_keep.xml b/assets/xml/objects/gameplay_dangeon_keep.xml
index 70f9d606b1..f3ad6195a9 100644
--- a/assets/xml/objects/gameplay_dangeon_keep.xml
+++ b/assets/xml/objects/gameplay_dangeon_keep.xml
@@ -14,20 +14,20 @@
-
-
+
+
-
-
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
@@ -59,15 +59,15 @@
-
+
-
+
-
-
-
-
-
+
+
+
+
+
diff --git a/spec b/spec
index 164776201d..f719cb5a18 100644
--- a/spec
+++ b/spec
@@ -1504,9 +1504,7 @@ beginseg
name "ovl_Obj_Switch"
compress
include "build/src/overlays/actors/ovl_Obj_Switch/z_obj_switch.o"
- include "build/data/ovl_Obj_Switch/ovl_Obj_Switch.data.o"
- include "build/data/ovl_Obj_Switch/ovl_Obj_Switch.bss.o"
- include "build/data/ovl_Obj_Switch/ovl_Obj_Switch.reloc.o"
+ include "build/src/overlays/actors/ovl_Obj_Switch/ovl_Obj_Switch_reloc.o"
endseg
beginseg
diff --git a/src/overlays/actors/ovl_Obj_Switch/z_obj_switch.c b/src/overlays/actors/ovl_Obj_Switch/z_obj_switch.c
index 4a69fc1ebc..7bea978269 100644
--- a/src/overlays/actors/ovl_Obj_Switch/z_obj_switch.c
+++ b/src/overlays/actors/ovl_Obj_Switch/z_obj_switch.c
@@ -5,17 +5,71 @@
*/
#include "z_obj_switch.h"
+#include "objects/gameplay_dangeon_keep/gameplay_dangeon_keep.h"
#define FLAGS (ACTOR_FLAG_10)
#define THIS ((ObjSwitch*)thisx)
+#define COS_OF_5_PI_DIV_8 -0.38268343f
+
void ObjSwitch_Init(Actor* thisx, GlobalContext* globalCtx);
void ObjSwitch_Destroy(Actor* thisx, GlobalContext* globalCtx);
void ObjSwitch_Update(Actor* thisx, GlobalContext* globalCtx);
void ObjSwitch_Draw(Actor* thisx, GlobalContext* globalCtx);
-#if 0
+void ObjSwitch_FloorSwitchUpInit(ObjSwitch* this);
+void ObjSwitch_FloorSwitchPushDownInit(ObjSwitch* this);
+void ObjSwitch_FloorSwitchDownInit(ObjSwitch* this);
+void ObjSwitch_FloorSwitchRiseUpInit(ObjSwitch* this);
+void ObjSwitch_EyeSwitchFrozenInit(ObjSwitch* this);
+void ObjSwitch_EyeSwitchOpenInit(ObjSwitch* this);
+void ObjSwitch_EyeSwitchClosingInit(ObjSwitch* this);
+void ObjSwitch_EyeSwitchClosedInit(ObjSwitch* this);
+void ObjSwitch_EyeSwitchOpeningInit(ObjSwitch* this);
+void ObjSwitch_CrystalSwitchOffInit(ObjSwitch* this);
+void ObjSwitch_CrystalSwitchTurnOnInit(ObjSwitch* this);
+void ObjSwitch_CrystalSwitchOnInit(ObjSwitch* this);
+void ObjSwitch_CrystalSwitchTurnOffInit(ObjSwitch* this);
+void ObjSwitch_LargeFloorSwitchUpInit(ObjSwitch* this);
+void ObjSwitch_LargeFloorSwitchPushDownInit(ObjSwitch* this);
+void ObjSwitch_LargeFloorSwitchDownInit(ObjSwitch* this);
+void ObjSwitch_LargeFloorSwitchRiseUpInit(ObjSwitch* this);
+
+void ObjSwitch_FloorSwitchSnapPlayerToSwitchEdge(ObjSwitch* this, GlobalContext* globalCtx);
+void ObjSwitch_TryPlayCutscene(ObjSwitch* this, GlobalContext* globalCtx);
+void ObjSwitch_FloorSwitchUp(ObjSwitch* this, GlobalContext* globalCtx);
+void ObjSwitch_FloorSwitchPushDown(ObjSwitch* this, GlobalContext* globalCtx);
+void ObjSwitch_FloorSwitchDown(ObjSwitch* this, GlobalContext* globalCtx);
+void ObjSwitch_FloorSwitchRiseUp(ObjSwitch* this, GlobalContext* globalCtx);
+void ObjSwitch_EyeSwitchUnfrozen(ObjSwitch* this, GlobalContext* globalCtx);
+void ObjSwitch_EyeSwitchOpen(ObjSwitch* this, GlobalContext* globalCtx);
+void ObjSwitch_EyeSwitchClosing(ObjSwitch* this, GlobalContext* globalCtx);
+void ObjSwitch_EyeSwitchClosed(ObjSwitch* this, GlobalContext* globalCtx);
+void ObjSwitch_EyeSwitchOpening(ObjSwitch* this, GlobalContext* globalCtx);
+void ObjSwitch_CrystalSwitchOff(ObjSwitch* this, GlobalContext* globalCtx);
+void ObjSwitch_CrystalSwitchTurnOn(ObjSwitch* this, GlobalContext* globalCtx);
+void ObjSwitch_CrystalSwitchOn(ObjSwitch* this, GlobalContext* globalCtx);
+void ObjSwitch_CrystalSwitchTurnOff(ObjSwitch* this, GlobalContext* globalCtx);
+void ObjSwitch_LargeFloorSwitchUp(ObjSwitch* this, GlobalContext* globalCtx);
+void ObjSwitch_LargeFloorSwitchPushDown(ObjSwitch* this, GlobalContext* globalCtx);
+void ObjSwitch_LargeFloorSwitchDown(ObjSwitch* this, GlobalContext* globalCtx);
+void ObjSwitch_LargeFloorSwitchRiseUp(ObjSwitch* this, GlobalContext* globalCtx);
+
+void ObjSwitch_DrawFloorSwitch(ObjSwitch* this, GlobalContext* globalCtx);
+void ObjSwitch_DrawRustyFloorSwitch(ObjSwitch* this, GlobalContext* globalCtx);
+void ObjSwitch_DrawVisibleEyeSwitch(ObjSwitch* this, GlobalContext* globalCtx);
+void ObjSwitch_DrawInvisibleEyeSwitch(ObjSwitch* this, GlobalContext* globalCtx);
+void ObjSwitch_DrawEyeSwitch(ObjSwitch* this, GlobalContext* globalCtx);
+void ObjSwitch_DrawCrystalSwitch(ObjSwitch* this, GlobalContext* globalCtx);
+
+static TexturePtr sEyeSwitchTextures[][4] = {
+ { gEyeSwitchGoldOpenTex, gEyeSwitchGoldOpeningTex, gEyeSwitchGoldClosingTex, gEyeSwitchGoldClosedTex },
+ { gEyeSwitchSilverOpenTex, gEyeSwitchSilverHalfTex, gEyeSwitchSilverClosedTex, gEyeSwitchSilverClosedTex },
+};
+
+static s32 sIsSegmentTableInit = false;
+
const ActorInit Obj_Switch_InitVars = {
ACTOR_OBJ_SWITCH,
ACTORCAT_SWITCH,
@@ -28,183 +82,969 @@ const ActorInit Obj_Switch_InitVars = {
(ActorFunc)ObjSwitch_Draw,
};
-// static ColliderTrisElementInit sTrisElementsInit[2] = {
-static ColliderTrisElementInit D_8093CCD4[2] = {
+static f32 sHeights[] = { 10.0f, 10.0f, 0.0f, 30.0f, 30.0f, 15.0f };
+
+static f32 sScale[] = { 0.123f, 0.123f, 0.1f, 0.118f, 0.118f, 0.248f };
+
+static ColliderTrisElementInit sRustyFloorTrisElementsInit[2] = {
{
- { ELEMTYPE_UNK0, { 0x00000000, 0x00, 0x00 }, { 0x00000400, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_NONE, },
+ {
+ ELEMTYPE_UNK0,
+ { 0x00000000, 0x00, 0x00 },
+ { 0x00000400, 0x00, 0x00 },
+ TOUCH_NONE | TOUCH_SFX_NORMAL,
+ BUMP_ON,
+ OCELEM_NONE,
+ },
{ { { -20.0f, 19.0f, -20.0f }, { -20.0f, 19.0f, 20.0f }, { 20.0f, 19.0f, 20.0f } } },
},
{
- { ELEMTYPE_UNK0, { 0x00000000, 0x00, 0x00 }, { 0x00000400, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_NONE, },
+ {
+ ELEMTYPE_UNK0,
+ { 0x00000000, 0x00, 0x00 },
+ { 0x00000400, 0x00, 0x00 },
+ TOUCH_NONE | TOUCH_SFX_NORMAL,
+ BUMP_ON,
+ OCELEM_NONE,
+ },
{ { { 20.0f, 19.0f, 20.0f }, { 20.0f, 19.0f, -20.0f }, { -20.0f, 19.0f, -20.0f } } },
},
};
-// static ColliderTrisInit sTrisInit = {
-static ColliderTrisInit D_8093CD4C = {
- { COLTYPE_NONE, AT_NONE, AC_ON | AC_TYPE_PLAYER, OC1_NONE, OC2_NONE, COLSHAPE_TRIS, },
- 2, D_8093CCD4, // sTrisElementsInit,
+static ColliderTrisInit sRustyFloorTrisInit = {
+ {
+ COLTYPE_NONE,
+ AT_NONE,
+ AC_ON | AC_TYPE_PLAYER,
+ OC1_NONE,
+ OC2_NONE,
+ COLSHAPE_TRIS,
+ },
+ ARRAY_COUNT(sRustyFloorTrisElementsInit),
+ sRustyFloorTrisElementsInit,
};
-// static ColliderTrisElementInit sTrisElementsInit[2] = {
-static ColliderTrisElementInit D_8093CD5C[2] = {
+static ColliderTrisElementInit sEyeSwitchTrisElementsInit[2] = {
{
- { ELEMTYPE_UNK4, { 0x00000000, 0x00, 0x00 }, { 0x00003820, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_NONE, },
+ {
+ ELEMTYPE_UNK4,
+ { 0x00000000, 0x00, 0x00 },
+ { 0x00003820, 0x00, 0x00 },
+ TOUCH_NONE | TOUCH_SFX_NORMAL,
+ BUMP_ON,
+ OCELEM_NONE,
+ },
{ { { 0.0f, 23.0f, 8.5f }, { -23.0f, 0.0f, 8.5f }, { 0.0f, -23.0f, 8.5f } } },
},
{
- { ELEMTYPE_UNK4, { 0x00000000, 0x00, 0x00 }, { 0x00003820, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_NONE, },
+ {
+ ELEMTYPE_UNK4,
+ { 0x00000000, 0x00, 0x00 },
+ { 0x00003820, 0x00, 0x00 },
+ TOUCH_NONE | TOUCH_SFX_NORMAL,
+ BUMP_ON,
+ OCELEM_NONE,
+ },
{ { { 0.0f, 23.0f, 8.5f }, { 0.0f, -23.0f, 8.5f }, { 23.0f, 0.0f, 8.5f } } },
},
};
-// static ColliderTrisInit sTrisInit = {
-static ColliderTrisInit D_8093CDD4 = {
- { COLTYPE_NONE, AT_NONE, AC_ON | AC_TYPE_PLAYER, OC1_NONE, OC2_NONE, COLSHAPE_TRIS, },
- 2, D_8093CD5C, // sTrisElementsInit,
+static ColliderTrisInit sEyeSwitchTrisInit = {
+ {
+ COLTYPE_NONE,
+ AT_NONE,
+ AC_ON | AC_TYPE_PLAYER,
+ OC1_NONE,
+ OC2_NONE,
+ COLSHAPE_TRIS,
+ },
+ ARRAY_COUNT(sEyeSwitchTrisElementsInit),
+ sEyeSwitchTrisElementsInit,
};
-// static ColliderJntSphElementInit sJntSphElementsInit[1] = {
-static ColliderJntSphElementInit D_8093CDE4[1] = {
+static ColliderJntSphElementInit sJntSphElementsInit[1] = {
{
- { ELEMTYPE_UNK0, { 0x00000000, 0x00, 0x00 }, { 0x01CBFFBE, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, },
+ {
+ ELEMTYPE_UNK0,
+ { 0x00000000, 0x00, 0x00 },
+ { 0x01CBFFBE, 0x00, 0x00 },
+ TOUCH_NONE | TOUCH_SFX_NORMAL,
+ BUMP_ON,
+ OCELEM_ON,
+ },
{ 0, { { 0, 300, 0 }, 20 }, 100 },
},
};
-// static ColliderJntSphInit sJntSphInit = {
-static ColliderJntSphInit D_8093CE08 = {
- { COLTYPE_METAL, AT_NONE, AC_ON | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_2, COLSHAPE_JNTSPH, },
- 1, D_8093CDE4, // sJntSphElementsInit,
+static ColliderJntSphInit sJntSphInit = {
+ {
+ COLTYPE_METAL,
+ AT_NONE,
+ AC_ON | AC_TYPE_PLAYER,
+ OC1_ON | OC1_TYPE_ALL,
+ OC2_TYPE_2,
+ COLSHAPE_JNTSPH,
+ },
+ ARRAY_COUNT(sJntSphElementsInit),
+ sJntSphElementsInit,
};
-// static InitChainEntry sInitChain[] = {
-static InitChainEntry D_8093CE18[] = {
+static InitChainEntry sInitChain[] = {
ICHAIN_F32(uncullZoneForward, 4000, ICHAIN_CONTINUE),
ICHAIN_F32(uncullZoneScale, 200, ICHAIN_CONTINUE),
ICHAIN_F32(uncullZoneDownward, 200, ICHAIN_STOP),
};
-#endif
+static Color_RGB8 sSakonHideoutColor[2] = { { 250, 90, 60 }, { 255, 255, 255 } };
-extern ColliderTrisElementInit D_8093CCD4[2];
-extern ColliderTrisInit D_8093CD4C;
-extern ColliderTrisElementInit D_8093CD5C[2];
-extern ColliderTrisInit D_8093CDD4;
-extern ColliderJntSphElementInit D_8093CDE4[1];
-extern ColliderJntSphInit D_8093CE08;
-extern InitChainEntry D_8093CE18[];
+static Gfx* sFloorSwitchDL[] = { gFloorSwitch1DL, gFloorSwitch3DL, gFloorSwitch2DL, gFloorSwitch2DL, gFloorSwitch1DL };
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/func_8093ABD0.s")
+static Gfx* sEyeSwitchDL[] = { gEyeSwitchGoldDL, gEyeSwitchSilverDL };
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/func_8093AC6C.s")
+static AnimatedMaterial* sCrystalSwitchAnimatedMat;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/func_8093ADA8.s")
+void ObjSwitch_InitJntSphCollider(ObjSwitch* this, GlobalContext* globalCtx, ColliderJntSphInit* init) {
+ s32 pad;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/func_8093AE1C.s")
+ Collider_InitJntSph(globalCtx, &this->colliderJntSph);
+ Collider_SetJntSph(globalCtx, &this->colliderJntSph, &this->dyna.actor, init, this->colliderJntSphElements);
+ Matrix_SetStateRotationAndTranslation(this->dyna.actor.world.pos.x,
+ this->dyna.actor.world.pos.y +
+ (this->dyna.actor.shape.yOffset * this->dyna.actor.scale.y),
+ this->dyna.actor.world.pos.z, &this->dyna.actor.shape.rot);
+ Matrix_Scale(this->dyna.actor.scale.x, this->dyna.actor.scale.y, this->dyna.actor.scale.z, MTXMODE_APPLY);
+ Collider_UpdateSpheres(0, &this->colliderJntSph);
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/func_8093AE74.s")
+void ObjSwitch_InitTrisCollider(ObjSwitch* this, GlobalContext* globalCtx, ColliderTrisInit* init) {
+ s32 pad;
+ s32 i;
+ s32 j;
+ Vec3f vtx[3];
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/func_8093AE88.s")
+ Collider_InitTris(globalCtx, &this->colliderTris);
+ Collider_SetTris(globalCtx, &this->colliderTris, &this->dyna.actor, init, this->colliderTrisElements);
+ Matrix_StatePush();
+ Matrix_SetStateRotationAndTranslation(this->dyna.actor.world.pos.x,
+ this->dyna.actor.world.pos.y +
+ this->dyna.actor.shape.yOffset * this->dyna.actor.scale.y,
+ this->dyna.actor.world.pos.z, &this->dyna.actor.shape.rot);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/func_8093AEC4.s")
+ for (i = 0; i < ARRAY_COUNT(this->colliderTrisElements); i++) {
+ if (this) {}
+ for (j = 0; j < ARRAY_COUNT(vtx); j++) {
+ Matrix_MultiplyVector3fByState(&init->elements[i].dim.vtx[j], &vtx[j]);
+ }
+ Collider_SetTrisVertices(&this->colliderTris, i, &vtx[0], &vtx[1], &vtx[2]);
+ }
+ Matrix_StatePop();
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/func_8093AEF0.s")
+Actor* ObjSwitch_SpawnIce(ObjSwitch* this, GlobalContext* globalCtx) {
+ Actor_SpawnAsChild(&globalCtx->actorCtx, &this->dyna.actor, globalCtx, ACTOR_OBJ_ICE_POLY,
+ this->dyna.actor.world.pos.x, this->dyna.actor.world.pos.y - 25.0f, this->dyna.actor.world.pos.z,
+ this->dyna.actor.world.rot.x, this->dyna.actor.world.rot.y, this->dyna.actor.world.rot.z,
+ 0xFF32);
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/func_8093AF1C.s")
+void ObjSwitch_SetSwitchFlagState(ObjSwitch* this, GlobalContext* globalCtx, s32 setFlag) {
+ if (setFlag) {
+ s32 flag = OBJ_SWITCH_GET_SWITCH_FLAG(&this->dyna.actor);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/func_8093AF54.s")
+ Flags_SetSwitch(globalCtx, flag);
+ } else {
+ s32 flag = OBJ_SWITCH_GET_SWITCH_FLAG(&this->dyna.actor);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/ObjSwitch_Init.s")
+ Flags_UnsetSwitch(globalCtx, flag);
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/ObjSwitch_Destroy.s")
+void ObjSwitch_CrystalUpdateTimer(ObjSwitch* this) {
+ this->crystalAnimTimer++;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/func_8093B648.s")
+void ObjSwitch_StopCutscene(ObjSwitch* this) {
+ if (this->isPlayingCutscene) {
+ ActorCutscene_Stop(this->dyna.actor.cutscene);
+ this->isPlayingCutscene = false;
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/func_8093B668.s")
+void ObjSwitch_PlayFootSwitchSfx(ObjSwitch* this) {
+ if (this->sfxTimer <= 0) {
+ Actor_PlaySfxAtPos(&this->dyna.actor, NA_SE_EV_FOOT_SWITCH);
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/func_8093B6F4.s")
+void ObjSwitch_PlayDiamondSwitchSfx(ObjSwitch* this) {
+ if (this->sfxTimer <= 0) {
+ Actor_PlaySfxAtPos(&this->dyna.actor, NA_SE_EV_DIAMOND_SWITCH);
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/func_8093B710.s")
+void ObjSwitch_SetFloorSwitchSnapPlayerState(ObjSwitch* this, s32 state) {
+ if (DynaPolyActor_IsInRidingMovingState(&this->dyna)) {
+ this->floorSwitchPlayerSnapState = state;
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/func_8093B92C.s")
+void ObjSwitch_FloorSwitchSnapPlayerToSwitchEdge(ObjSwitch* this, GlobalContext* globalCtx) {
+ s32 pad;
+ Player* player;
+ f32 centerDisplacement;
+ s16 yaw;
+ f32 cos;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/func_8093B940.s")
+ if (globalCtx->actorCtx.unk5 & 0x80) {
+ player = GET_PLAYER(globalCtx);
+ // compute yawTowardsPlayer relative to model space
+ yaw = BINANG_SUB(this->dyna.actor.yawTowardsPlayer, this->dyna.actor.shape.rot.y);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/func_8093B9C0.s")
+ // clamps yaw to the range -45 to 45 degrees, such that 0 degrees follows along the apothem
+ yaw += 0x2000;
+ yaw &= 0x3FFF;
+ yaw -= 0x2000;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/func_8093B9E4.s")
+ // set centerDisplacement to the length of the apothem for the floor switch square
+ // only OBJSWITCH_TYPE_FLOOR and OBJSWITCH_TYPE_FLOOR_LARGE are supported
+ centerDisplacement = OBJ_SWITCH_GET_TYPE(&this->dyna.actor) == OBJSWITCH_TYPE_FLOOR ? 24.0f : 48.0f;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/func_8093BB5C.s")
+ cos = Math_CosS(yaw);
+ if (fabsf(cos) > 0.01f) {
+ // compute how far to displace the player so that the player is touching an edge
+ centerDisplacement /= cos;
+ // if the player is already inside the square, don't move them
+ if (centerDisplacement < this->dyna.actor.xzDistToPlayer) {
+ player->actor.world.pos.x =
+ Math_SinS(this->dyna.actor.yawTowardsPlayer) * centerDisplacement + this->dyna.actor.world.pos.x;
+ player->actor.world.pos.z =
+ Math_CosS(this->dyna.actor.yawTowardsPlayer) * centerDisplacement + this->dyna.actor.world.pos.z;
+ }
+ player->linearVelocity = 0.0f;
+ }
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/func_8093BB70.s")
+void ObjSwitch_Init(Actor* thisx, GlobalContext* globalCtx) {
+ s32 pad;
+ s32 type;
+ u32 isSwitchFlagSet;
+ ObjSwitch* this = THIS;
+ s32 pad2;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/func_8093BBD0.s")
+ isSwitchFlagSet = Flags_GetSwitch(globalCtx, OBJ_SWITCH_GET_SWITCH_FLAG(&this->dyna.actor));
+ type = OBJ_SWITCH_GET_TYPE(&this->dyna.actor);
+ Actor_ProcessInitChain(&this->dyna.actor, sInitChain);
+ Actor_SetScale(&this->dyna.actor, sScale[type]);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/func_8093BCC8.s")
+ if (type == OBJSWITCH_TYPE_FLOOR || type == OBJSWITCH_TYPE_FLOOR_RUSTY || type == OBJSWITCH_TYPE_FLOOR_LARGE) {
+ if (type == OBJSWITCH_TYPE_FLOOR_LARGE) {
+ this->dyna.actor.world.pos.y = this->dyna.actor.home.pos.y + 1.9f;
+ } else {
+ this->dyna.actor.world.pos.y = this->dyna.actor.home.pos.y + 1.0f;
+ }
+ DynaPolyActor_Init(&this->dyna, 1);
+ DynaPolyActor_LoadMesh(globalCtx, &this->dyna, &gFloorSwitchCol);
+ }
+ if (type == OBJSWITCH_TYPE_FLOOR) {
+ if (globalCtx->sceneNum == SCENE_SECOM) {
+ this->floorSwitchUpScale = 33.0f / 200.0f / 3.0f;
+ this->floorSwitchDownScale = 33.0f / 2000.0f / 3.0f;
+ } else {
+ this->floorSwitchUpScale = 33.0f / 200.0f;
+ this->floorSwitchDownScale = 33.0f / 2000.0f;
+ }
+ }
+ if (type == OBJSWITCH_TYPE_FLOOR || type == OBJSWITCH_TYPE_FLOOR_LARGE) {
+ if (globalCtx->sceneNum == SCENE_SECOM) {
+ Color_RGB8* color = &sSakonHideoutColor[OBJ_SWITCH_GET_COLOR_ID(&this->dyna.actor)];
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/func_8093BCDC.s")
+ this->color.r = color->r;
+ this->color.g = color->g;
+ this->color.b = color->b;
+ this->dyna.actor.shape.rot.z = 0;
+ this->dyna.actor.world.rot.z = 0;
+ } else {
+ this->color.r = 255;
+ this->color.g = 255;
+ this->color.b = 255;
+ }
+ }
+ Actor_SetFocus(&this->dyna.actor, sHeights[type]);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/func_8093BD34.s")
+ if (type == OBJSWITCH_TYPE_FLOOR_RUSTY) {
+ ObjSwitch_InitTrisCollider(this, globalCtx, &sRustyFloorTrisInit);
+ } else if (type == OBJSWITCH_TYPE_EYE) {
+ ObjSwitch_InitTrisCollider(this, globalCtx, &sEyeSwitchTrisInit);
+ } else if (type == OBJSWITCH_TYPE_CRYSTAL || type == OBJSWITCH_TYPE_CRYSTAL_TARGETABLE) {
+ ObjSwitch_InitJntSphCollider(this, globalCtx, &sJntSphInit);
+ }
+ if (type == OBJSWITCH_TYPE_CRYSTAL_TARGETABLE) {
+ this->dyna.actor.targetMode = 4;
+ this->dyna.actor.flags |= 1;
+ }
+ this->dyna.actor.colChkInfo.mass = MASS_IMMOVABLE;
+ if (OBJ_SWITCH_IS_FROZEN(&this->dyna.actor)) {
+ if (ObjSwitch_SpawnIce(this, globalCtx) == NULL) {
+ OBJ_SWITCH_UNSET_FROZEN(&this->dyna.actor);
+ }
+ this->sfxTimer = 0;
+ } else {
+ this->sfxTimer = 10;
+ }
+ if (OBJ_SWITCH_IS_INVISIBLE(&this->dyna.actor)) {
+ this->dyna.actor.flags |= 0x80;
+ }
+ if (type == OBJSWITCH_TYPE_EYE) {
+ if (sIsSegmentTableInit == false) {
+ s32 i, j;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/func_8093BD4C.s")
+ sIsSegmentTableInit = true;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/func_8093BDAC.s")
+ for (i = 0; i < ARRAY_COUNT(sEyeSwitchTextures); i++) {
+ for (j = 0; j < ARRAY_COUNT(*sEyeSwitchTextures); j++) {
+ sEyeSwitchTextures[i][j] = Lib_SegmentedToVirtual(sEyeSwitchTextures[i][j]);
+ }
+ }
+ }
+ }
+ if (type == OBJSWITCH_TYPE_CRYSTAL) {
+ sCrystalSwitchAnimatedMat = Lib_SegmentedToVirtual(&gCrystalSwitchAnimatedMat);
+ }
+ if (OBJ_SWITCH_IS_FROZEN(&this->dyna.actor)) {
+ ObjSwitch_EyeSwitchFrozenInit(this);
+ } else if (type == OBJSWITCH_TYPE_FLOOR || type == OBJSWITCH_TYPE_FLOOR_RUSTY) {
+ if (OBJ_SWITCH_GET_SUBTYPE(&this->dyna.actor) == OBJSWITCH_SUBTYPE_RESET_INVERTED) {
+ if (isSwitchFlagSet) {
+ ObjSwitch_FloorSwitchUpInit(this);
+ } else {
+ ObjSwitch_FloorSwitchDownInit(this);
+ }
+ } else {
+ if (isSwitchFlagSet) {
+ ObjSwitch_FloorSwitchDownInit(this);
+ } else {
+ ObjSwitch_FloorSwitchUpInit(this);
+ }
+ }
+ } else if (type == OBJSWITCH_TYPE_EYE) {
+ if (isSwitchFlagSet) {
+ ObjSwitch_EyeSwitchClosedInit(this);
+ } else {
+ ObjSwitch_EyeSwitchOpenInit(this);
+ }
+ } else if (type == OBJSWITCH_TYPE_CRYSTAL || type == OBJSWITCH_TYPE_CRYSTAL_TARGETABLE) {
+ if (isSwitchFlagSet) {
+ ObjSwitch_CrystalSwitchOnInit(this);
+ } else {
+ ObjSwitch_CrystalSwitchOffInit(this);
+ }
+ } else if (type == OBJSWITCH_TYPE_FLOOR_LARGE) {
+ if (OBJ_SWITCH_GET_SUBTYPE(&this->dyna.actor) == OBJSWITCH_SUBTYPE_RESET_INVERTED) {
+ if (isSwitchFlagSet) {
+ ObjSwitch_LargeFloorSwitchUpInit(this);
+ } else {
+ ObjSwitch_LargeFloorSwitchDownInit(this);
+ }
+ } else {
+ if (isSwitchFlagSet) {
+ ObjSwitch_LargeFloorSwitchDownInit(this);
+ } else {
+ ObjSwitch_LargeFloorSwitchUpInit(this);
+ }
+ }
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/func_8093BDC0.s")
+void ObjSwitch_Destroy(Actor* thisx, GlobalContext* globalCtx) {
+ s32 pad;
+ ObjSwitch* this = THIS;
+ s32 type = OBJ_SWITCH_GET_TYPE(&this->dyna.actor);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/func_8093BE10.s")
+ if (type == OBJSWITCH_TYPE_FLOOR || type == OBJSWITCH_TYPE_FLOOR_RUSTY || type == OBJSWITCH_TYPE_FLOOR_LARGE) {
+ DynaPoly_DeleteBgActor(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId);
+ }
+ switch (type) {
+ case OBJSWITCH_TYPE_FLOOR_RUSTY:
+ case OBJSWITCH_TYPE_EYE:
+ Collider_DestroyTris(globalCtx, &this->colliderTris);
+ break;
+ case OBJSWITCH_TYPE_CRYSTAL:
+ case OBJSWITCH_TYPE_CRYSTAL_TARGETABLE:
+ Collider_DestroyJntSph(globalCtx, &this->colliderJntSph);
+ break;
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/func_8093BE2C.s")
+void ObjSwitch_TryPlayCutsceneInit(ObjSwitch* this, GlobalContext* globalCtx, ObjSwitchSetupActionFunc actionFunc,
+ s32 nextSwitchFlagState) {
+ this->setupFunc = actionFunc;
+ this->nextSwitchFlagState = nextSwitchFlagState;
+ this->actionFunc = ObjSwitch_TryPlayCutscene;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/func_8093BEF0.s")
+void ObjSwitch_TryPlayCutscene(ObjSwitch* this, GlobalContext* globalCtx) {
+ if (ActorCutscene_GetCanPlayNext(this->dyna.actor.cutscene)) {
+ ActorCutscene_StartAndSetUnkLinkFields(this->dyna.actor.cutscene, &this->dyna.actor);
+ ObjSwitch_SetSwitchFlagState(this, globalCtx, this->nextSwitchFlagState);
+ if (this->floorSwitchPlayerSnapState == 1) {
+ this->floorSwitchPlayerSnapState = 2;
+ }
+ this->isPlayingCutscene = true;
+ this->setupFunc(this);
+ } else {
+ ActorCutscene_SetIntentToPlay(this->dyna.actor.cutscene);
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/func_8093BF04.s")
+void ObjSwitch_FloorSwitchUpInit(ObjSwitch* this) {
+ this->actionFunc = ObjSwitch_FloorSwitchUp;
+ this->dyna.actor.scale.y = this->floorSwitchUpScale;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/func_8093BF50.s")
+void ObjSwitch_FloorSwitchUp(ObjSwitch* this, GlobalContext* globalCtx) {
+ s32 pad;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/func_8093BF70.s")
+ if (OBJ_SWITCH_GET_TYPE(&this->dyna.actor) == OBJSWITCH_TYPE_FLOOR_RUSTY) {
+ if (this->colliderTris.base.acFlags & AC_HIT) {
+ this->colliderTris.base.acFlags &= ~AT_HIT;
+ ObjSwitch_TryPlayCutsceneInit(this, globalCtx, ObjSwitch_FloorSwitchPushDownInit, true);
+ } else {
+ CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->colliderTris.base);
+ }
+ } else {
+ switch (OBJ_SWITCH_GET_SUBTYPE(&this->dyna.actor)) {
+ case OBJSWITCH_SUBTYPE_ONCE:
+ if (DynaPolyActor_IsInSwitchPressedState(&this->dyna)) {
+ ObjSwitch_SetFloorSwitchSnapPlayerState(this, 1);
+ ObjSwitch_TryPlayCutsceneInit(this, globalCtx, ObjSwitch_FloorSwitchPushDownInit, true);
+ }
+ break;
+ case OBJSWITCH_SUBTYPE_SYNC:
+ if (DynaPolyActor_IsInSwitchPressedState(&this->dyna)) {
+ ObjSwitch_SetFloorSwitchSnapPlayerState(this, 1);
+ ObjSwitch_TryPlayCutsceneInit(this, globalCtx, ObjSwitch_FloorSwitchPushDownInit, true);
+ } else if (Flags_GetSwitch(globalCtx, OBJ_SWITCH_GET_SWITCH_FLAG(&this->dyna.actor))) {
+ ObjSwitch_FloorSwitchPushDownInit(this);
+ }
+ break;
+ case OBJSWITCH_SUBTYPE_TOGGLE:
+ if (DynaPolyActor_IsInSwitchPressedState(&this->dyna)) {
+ s32 isSwitchFlagNotSet =
+ Flags_GetSwitch(globalCtx, OBJ_SWITCH_GET_SWITCH_FLAG(&this->dyna.actor)) ? false : true;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/func_8093C0A4.s")
+ ObjSwitch_SetFloorSwitchSnapPlayerState(this, 1);
+ ObjSwitch_TryPlayCutsceneInit(this, globalCtx, ObjSwitch_FloorSwitchPushDownInit,
+ isSwitchFlagNotSet);
+ }
+ break;
+ case OBJSWITCH_SUBTYPE_RESET:
+ if (DynaPolyActor_IsInSwitchPressedState(&this->dyna)) {
+ ObjSwitch_SetFloorSwitchSnapPlayerState(this, 1);
+ ObjSwitch_TryPlayCutsceneInit(this, globalCtx, ObjSwitch_FloorSwitchPushDownInit, true);
+ }
+ break;
+ case OBJSWITCH_SUBTYPE_RESET_INVERTED:
+ if (DynaPolyActor_IsInSwitchPressedState(&this->dyna)) {
+ ObjSwitch_SetFloorSwitchSnapPlayerState(this, 2);
+ ObjSwitch_SetSwitchFlagState(this, globalCtx, false);
+ ObjSwitch_FloorSwitchPushDownInit(this);
+ }
+ break;
+ }
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/func_8093C0B8.s")
+void ObjSwitch_FloorSwitchPushDownInit(ObjSwitch* this) {
+ this->actionFunc = ObjSwitch_FloorSwitchPushDown;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/func_8093C138.s")
+void ObjSwitch_FloorSwitchPushDown(ObjSwitch* this, GlobalContext* globalCtx) {
+ this->dyna.actor.scale.y -= 0.0495f;
+ if (this->dyna.actor.scale.y <= this->floorSwitchDownScale) {
+ ObjSwitch_PlayFootSwitchSfx(this);
+ func_8013ECE0(this->dyna.actor.xyzDistToPlayerSq, 120, 20, 10);
+ ObjSwitch_StopCutscene(this);
+ ObjSwitch_FloorSwitchDownInit(this);
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/func_8093C15C.s")
+void ObjSwitch_FloorSwitchDownInit(ObjSwitch* this) {
+ this->floorSwitchReleaseTimer = 6;
+ this->actionFunc = ObjSwitch_FloorSwitchDown;
+ this->dyna.actor.scale.y = this->floorSwitchDownScale;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/func_8093C23C.s")
+void ObjSwitch_FloorSwitchDown(ObjSwitch* this, GlobalContext* globalCtx) {
+ s32 pad;
+ u32 subType = OBJ_SWITCH_GET_SUBTYPE(&this->dyna.actor);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/func_8093C250.s")
+ switch (subType) {
+ case OBJSWITCH_SUBTYPE_ONCE:
+ case OBJSWITCH_SUBTYPE_SYNC:
+ if (!Flags_GetSwitch(globalCtx, OBJ_SWITCH_GET_SWITCH_FLAG(&this->dyna.actor))) {
+ if (globalCtx->sceneNum == SCENE_SECOM && DynaPolyActor_IsInSwitchPressedState(&this->dyna)) {
+ ObjSwitch_SetSwitchFlagState(this, globalCtx, true);
+ } else {
+ ObjSwitch_FloorSwitchRiseUpInit(this);
+ }
+ }
+ break;
+ case OBJSWITCH_SUBTYPE_TOGGLE:
+ case OBJSWITCH_SUBTYPE_RESET:
+ case OBJSWITCH_SUBTYPE_RESET_INVERTED:
+ if (!DynaPolyActor_IsInSwitchPressedState(&this->dyna) &&
+ (Player_InCsMode(&globalCtx->state) == 0 || globalCtx->sceneNum == SCENE_SECOM)) {
+ if (this->floorSwitchReleaseTimer <= 0) {
+ if (subType == OBJSWITCH_SUBTYPE_RESET) {
+ ObjSwitch_SetSwitchFlagState(this, globalCtx, false);
+ ObjSwitch_FloorSwitchRiseUpInit(this);
+ } else if (subType == OBJSWITCH_SUBTYPE_RESET_INVERTED) {
+ ObjSwitch_TryPlayCutsceneInit(this, globalCtx, ObjSwitch_FloorSwitchRiseUpInit, true);
+ } else {
+ ObjSwitch_FloorSwitchRiseUpInit(this);
+ }
+ }
+ } else {
+ if (globalCtx->sceneNum == SCENE_SECOM) {
+ this->floorSwitchReleaseTimer = 2;
+ } else {
+ this->floorSwitchReleaseTimer = 6;
+ }
+ }
+ break;
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/func_8093C2B4.s")
+void ObjSwitch_FloorSwitchRiseUpInit(ObjSwitch* this) {
+ this->actionFunc = ObjSwitch_FloorSwitchRiseUp;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/func_8093C2D4.s")
+void ObjSwitch_FloorSwitchRiseUp(ObjSwitch* this, GlobalContext* globalCtx) {
+ this->dyna.actor.scale.y += 0.0495f;
+ if (this->floorSwitchUpScale <= this->dyna.actor.scale.y) {
+ ObjSwitch_PlayFootSwitchSfx(this);
+ ObjSwitch_StopCutscene(this);
+ ObjSwitch_FloorSwitchUpInit(this);
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/func_8093C3C8.s")
+s32 ObjSwitch_IsEyeSwitchHit(ObjSwitch* this) {
+ Actor* acActor;
+ Actor* actor = &this->dyna.actor;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/func_8093C3DC.s")
+ if ((this->colliderTris.base.acFlags & AC_HIT) && !(this->collisionFlags & AC_HIT)) {
+ acActor = this->colliderTris.base.ac;
+ if (acActor != NULL) {
+ Vec3f sp2C;
+ Vec3f sp20;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/func_8093C460.s")
+ Matrix_StatePush();
+ Matrix_RotateY(acActor->world.rot.y, MTXMODE_NEW);
+ Matrix_InsertXRotation_s(acActor->world.rot.x, MTXMODE_APPLY);
+ Matrix_GetStateTranslationAndScaledZ(1.0f, &sp2C);
+ Matrix_RotateY(actor->shape.rot.y, MTXMODE_NEW);
+ Matrix_InsertXRotation_s(actor->shape.rot.x, MTXMODE_APPLY);
+ Matrix_InsertZRotation_s(actor->shape.rot.z, MTXMODE_APPLY);
+ Matrix_GetStateTranslationAndScaledZ(1.0f, &sp20);
+ Matrix_StatePop();
+ if ((Math3D_Parallel(&sp2C, &sp20) < COS_OF_5_PI_DIV_8)) {
+ return true;
+ }
+ }
+ }
+ return false;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/func_8093C488.s")
+void ObjSwitch_EyeSwitchFrozenInit(ObjSwitch* this) {
+ this->actionFunc = ObjSwitch_EyeSwitchUnfrozen;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/func_8093C584.s")
+void ObjSwitch_EyeSwitchUnfrozen(ObjSwitch* this, GlobalContext* globalCtx) {
+ if (Flags_GetSwitch(globalCtx, OBJ_SWITCH_GET_SWITCH_FLAG(&this->dyna.actor))) {
+ ObjSwitch_EyeSwitchClosedInit(this);
+ } else {
+ ObjSwitch_EyeSwitchOpenInit(this);
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/func_8093C598.s")
+void ObjSwitch_EyeSwitchOpenInit(ObjSwitch* this) {
+ this->actionFunc = ObjSwitch_EyeSwitchOpen;
+ this->eyeTexIndex = 0;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/ObjSwitch_Update.s")
+void ObjSwitch_EyeSwitchOpen(ObjSwitch* this, GlobalContext* globalCtx) {
+ if (ObjSwitch_IsEyeSwitchHit(this) || OBJ_SWITCH_IS_FROZEN(&this->dyna.actor)) {
+ OBJ_SWITCH_UNSET_FROZEN(&this->dyna.actor);
+ ObjSwitch_TryPlayCutsceneInit(this, globalCtx, ObjSwitch_EyeSwitchClosingInit, true);
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/func_8093C778.s")
+void ObjSwitch_EyeSwitchClosingInit(ObjSwitch* this) {
+ this->actionFunc = ObjSwitch_EyeSwitchClosing;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/func_8093C888.s")
+void ObjSwitch_EyeSwitchClosing(ObjSwitch* this, GlobalContext* globalCtx) {
+ this->eyeTexIndex++;
+ if (this->eyeTexIndex >= 3) {
+ ObjSwitch_StopCutscene(this);
+ ObjSwitch_PlayFootSwitchSfx(this);
+ ObjSwitch_EyeSwitchClosedInit(this);
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/func_8093C8B8.s")
+void ObjSwitch_EyeSwitchClosedInit(ObjSwitch* this) {
+ this->actionFunc = ObjSwitch_EyeSwitchClosed;
+ this->eyeTexIndex = 3;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/func_8093C99C.s")
+void ObjSwitch_EyeSwitchClosed(ObjSwitch* this, GlobalContext* globalCtx) {
+ switch (OBJ_SWITCH_GET_SUBTYPE(&this->dyna.actor)) {
+ case OBJSWITCH_SUBTYPE_ONCE:
+ if (!Flags_GetSwitch(globalCtx, OBJ_SWITCH_GET_SWITCH_FLAG(&this->dyna.actor))) {
+ OBJ_SWITCH_UNSET_FROZEN(&this->dyna.actor);
+ ObjSwitch_EyeSwitchOpeningInit(this);
+ }
+ break;
+ case OBJSWITCH_SUBTYPE_TOGGLE:
+ if (ObjSwitch_IsEyeSwitchHit(this) || OBJ_SWITCH_IS_FROZEN(&this->dyna.actor)) {
+ OBJ_SWITCH_UNSET_FROZEN(&this->dyna.actor);
+ ObjSwitch_TryPlayCutsceneInit(this, globalCtx, ObjSwitch_EyeSwitchOpeningInit, false);
+ }
+ break;
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/func_8093CA80.s")
+void ObjSwitch_EyeSwitchOpeningInit(ObjSwitch* this) {
+ this->actionFunc = ObjSwitch_EyeSwitchOpening;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/func_8093CAC4.s")
+void ObjSwitch_EyeSwitchOpening(ObjSwitch* this, GlobalContext* globalCtx) {
+ this->eyeTexIndex--;
+ if (this->eyeTexIndex <= 0) {
+ ObjSwitch_StopCutscene(this);
+ ObjSwitch_PlayFootSwitchSfx(this);
+ ObjSwitch_EyeSwitchOpenInit(this);
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/ObjSwitch_Draw.s")
+void ObjSwitch_CrystalSwitchOffInit(ObjSwitch* this) {
+ this->color.r = 0;
+ this->color.g = 0;
+ this->color.b = 0;
+ this->actionFunc = ObjSwitch_CrystalSwitchOff;
+}
+
+void ObjSwitch_CrystalSwitchOff(ObjSwitch* this, GlobalContext* globalCtx) {
+ s32 switchHit = (this->colliderJntSph.base.acFlags & AC_HIT) != 0;
+ s32 canActivate = switchHit && !(this->collisionFlags & AC_HIT) && (this->disableCrystalSwitchTimer <= 0);
+
+ if (switchHit) {
+ this->disableCrystalSwitchTimer = 10;
+ }
+ switch (OBJ_SWITCH_GET_SUBTYPE(&this->dyna.actor)) {
+ case OBJSWITCH_SUBTYPE_ONCE:
+ if (canActivate) {
+ ObjSwitch_TryPlayCutsceneInit(this, globalCtx, ObjSwitch_CrystalSwitchTurnOnInit, true);
+ }
+ break;
+ case OBJSWITCH_SUBTYPE_SYNC:
+ if (canActivate) {
+ ObjSwitch_TryPlayCutsceneInit(this, globalCtx, ObjSwitch_CrystalSwitchTurnOnInit, true);
+
+ } else if (Flags_GetSwitch(globalCtx, OBJ_SWITCH_GET_SWITCH_FLAG(&this->dyna.actor))) {
+ this->disableCrystalSwitchTimer = 10;
+ ObjSwitch_CrystalSwitchTurnOnInit(this);
+ }
+ break;
+ case OBJSWITCH_SUBTYPE_TOGGLE:
+ if (canActivate) {
+ ObjSwitch_TryPlayCutsceneInit(this, globalCtx, ObjSwitch_CrystalSwitchTurnOnInit, true);
+ }
+ ObjSwitch_CrystalUpdateTimer(this);
+ break;
+ }
+}
+
+void ObjSwitch_CrystalSwitchTurnOnInit(ObjSwitch* this) {
+ this->actionFunc = ObjSwitch_CrystalSwitchTurnOn;
+}
+
+void ObjSwitch_CrystalSwitchTurnOn(ObjSwitch* this, GlobalContext* globalCtx) {
+ s32 switchHit = (this->colliderJntSph.base.acFlags & AC_HIT) != 0;
+ s32 subType = OBJ_SWITCH_GET_SUBTYPE(&this->dyna.actor);
+
+ if (switchHit) {
+ this->disableCrystalSwitchTimer = 10;
+ }
+ ObjSwitch_StopCutscene(this);
+ if (subType == OBJSWITCH_SUBTYPE_TOGGLE) {
+ ObjSwitch_CrystalUpdateTimer(this);
+ }
+ ObjSwitch_PlayDiamondSwitchSfx(this);
+ ObjSwitch_CrystalSwitchOnInit(this);
+}
+
+void ObjSwitch_CrystalSwitchOnInit(ObjSwitch* this) {
+ this->color.r = 255;
+ this->color.g = 255;
+ this->color.b = 255;
+ this->actionFunc = ObjSwitch_CrystalSwitchOn;
+}
+
+void ObjSwitch_CrystalSwitchOn(ObjSwitch* this, GlobalContext* globalCtx) {
+ s32 switchHit = (this->colliderJntSph.base.acFlags & AC_HIT) != 0;
+ s32 canActivate = switchHit && !(this->collisionFlags & AC_HIT) && (this->disableCrystalSwitchTimer <= 0);
+
+ if (switchHit) {
+ this->disableCrystalSwitchTimer = 10;
+ }
+ switch (OBJ_SWITCH_GET_SUBTYPE(&this->dyna.actor)) {
+ case OBJSWITCH_SUBTYPE_ONCE:
+ case OBJSWITCH_SUBTYPE_SYNC:
+ if (!Flags_GetSwitch(globalCtx, OBJ_SWITCH_GET_SWITCH_FLAG(&this->dyna.actor))) {
+ this->disableCrystalSwitchTimer = 10;
+ ObjSwitch_CrystalSwitchTurnOffInit(this);
+ }
+ break;
+ case OBJSWITCH_SUBTYPE_TOGGLE:
+ if (canActivate) {
+ ObjSwitch_TryPlayCutsceneInit(this, globalCtx, ObjSwitch_CrystalSwitchTurnOffInit, false);
+ }
+ }
+ ObjSwitch_CrystalUpdateTimer(this);
+}
+
+void ObjSwitch_CrystalSwitchTurnOffInit(ObjSwitch* this) {
+ this->actionFunc = ObjSwitch_CrystalSwitchTurnOff;
+}
+
+void ObjSwitch_CrystalSwitchTurnOff(ObjSwitch* this, GlobalContext* globalCtx) {
+ s32 switchHit = (this->colliderJntSph.base.acFlags & AC_HIT) != 0;
+
+ if (switchHit) {
+ this->disableCrystalSwitchTimer = 10;
+ }
+ ObjSwitch_StopCutscene(this);
+ ObjSwitch_CrystalUpdateTimer(this);
+ ObjSwitch_PlayDiamondSwitchSfx(this);
+ ObjSwitch_CrystalSwitchOffInit(this);
+}
+
+void ObjSwitch_LargeFloorSwitchUpInit(ObjSwitch* this) {
+ this->dyna.actor.scale.y = 0.2475f;
+ this->actionFunc = ObjSwitch_LargeFloorSwitchUp;
+}
+
+void ObjSwitch_LargeFloorSwitchUp(ObjSwitch* this, GlobalContext* globalCtx) {
+ s32 subType = OBJ_SWITCH_GET_SUBTYPE(&this->dyna.actor);
+
+ if (subType == OBJSWITCH_SUBTYPE_ONCE) {
+ if (DynaPolyActor_IsInHeavySwitchPressedState(&this->dyna)) {
+ ObjSwitch_SetFloorSwitchSnapPlayerState(this, 1);
+ ObjSwitch_TryPlayCutsceneInit(this, globalCtx, ObjSwitch_LargeFloorSwitchPushDownInit, true);
+ }
+ } else if (subType == OBJSWITCH_SUBTYPE_RESET) {
+ if (DynaPolyActor_IsInHeavySwitchPressedState(&this->dyna)) {
+ ObjSwitch_SetFloorSwitchSnapPlayerState(this, 1);
+ ObjSwitch_TryPlayCutsceneInit(this, globalCtx, ObjSwitch_LargeFloorSwitchPushDownInit, true);
+ }
+ } else if (subType == OBJSWITCH_SUBTYPE_RESET_INVERTED && DynaPolyActor_IsInHeavySwitchPressedState(&this->dyna)) {
+ ObjSwitch_SetFloorSwitchSnapPlayerState(this, 2);
+ ObjSwitch_SetSwitchFlagState(this, globalCtx, false);
+ ObjSwitch_LargeFloorSwitchPushDownInit(this);
+ }
+}
+
+void ObjSwitch_LargeFloorSwitchPushDownInit(ObjSwitch* this) {
+ this->actionFunc = ObjSwitch_LargeFloorSwitchPushDown;
+}
+
+void ObjSwitch_LargeFloorSwitchPushDown(ObjSwitch* this, GlobalContext* globalCtx) {
+ this->dyna.actor.scale.y -= 0.074250005f;
+ if (this->dyna.actor.scale.y <= 33.0f / 2000.0f) {
+ ObjSwitch_PlayFootSwitchSfx(this);
+ func_8013ECE0(this->dyna.actor.xyzDistToPlayerSq, 120, 20, 10);
+ ObjSwitch_StopCutscene(this);
+ ObjSwitch_LargeFloorSwitchDownInit(this);
+ }
+}
+
+void ObjSwitch_LargeFloorSwitchDownInit(ObjSwitch* this) {
+ this->dyna.actor.scale.y = 33.0f / 2000.0f;
+ this->floorSwitchReleaseTimer = 6;
+ this->actionFunc = ObjSwitch_LargeFloorSwitchDown;
+}
+
+void ObjSwitch_LargeFloorSwitchDown(ObjSwitch* this, GlobalContext* globalCtx) {
+ s32 subType = OBJ_SWITCH_GET_SUBTYPE(&this->dyna.actor);
+
+ if (subType == OBJSWITCH_SUBTYPE_ONCE) {
+ if (!Flags_GetSwitch(globalCtx, OBJ_SWITCH_GET_SWITCH_FLAG(&this->dyna.actor))) {
+ ObjSwitch_LargeFloorSwitchRiseUpInit(this);
+ }
+ } else if (subType == OBJSWITCH_SUBTYPE_RESET || subType == OBJSWITCH_SUBTYPE_RESET_INVERTED) {
+ if (!DynaPolyActor_IsInHeavySwitchPressedState(&this->dyna) && !Player_InCsMode(&globalCtx->state)) {
+ if (this->floorSwitchReleaseTimer <= 0) {
+ if (OBJ_SWITCH_GET_SUBTYPE(&this->dyna.actor) == OBJSWITCH_SUBTYPE_RESET) {
+ ObjSwitch_SetSwitchFlagState(this, globalCtx, false);
+ ObjSwitch_LargeFloorSwitchRiseUpInit(this);
+ } else {
+ ObjSwitch_TryPlayCutsceneInit(this, globalCtx, ObjSwitch_LargeFloorSwitchRiseUpInit, true);
+ }
+ }
+ } else {
+ this->floorSwitchReleaseTimer = 6;
+ }
+ }
+}
+
+void ObjSwitch_LargeFloorSwitchRiseUpInit(ObjSwitch* this) {
+ this->actionFunc = ObjSwitch_LargeFloorSwitchRiseUp;
+}
+
+void ObjSwitch_LargeFloorSwitchRiseUp(ObjSwitch* this, GlobalContext* globalCtx) {
+ this->dyna.actor.scale.y += 0.074250005f;
+ if (this->dyna.actor.scale.y >= 0.2475f) {
+ ObjSwitch_PlayFootSwitchSfx(this);
+ ObjSwitch_StopCutscene(this);
+ ObjSwitch_LargeFloorSwitchUpInit(this);
+ }
+}
+
+void ObjSwitch_Update(Actor* thisx, GlobalContext* globalCtx) {
+ ObjSwitch* this = THIS;
+
+ if (this->floorSwitchReleaseTimer > 0) {
+ this->floorSwitchReleaseTimer--;
+ }
+ if (this->sfxTimer > 0) {
+ this->sfxTimer--;
+ }
+ this->actionFunc(this, globalCtx);
+ if (this->floorSwitchPlayerSnapState != 0) {
+ s32 pad;
+
+ dummy:
+ ObjSwitch_FloorSwitchSnapPlayerToSwitchEdge(this, globalCtx);
+ if (this->floorSwitchPlayerSnapState == 2) {
+ this->floorSwitchPlayerSnapState = 0;
+ }
+ }
+ switch (OBJ_SWITCH_GET_TYPE(&this->dyna.actor)) {
+ case OBJSWITCH_TYPE_FLOOR:
+ case OBJSWITCH_TYPE_FLOOR_RUSTY:
+ case OBJSWITCH_TYPE_FLOOR_LARGE:
+ this->collisionFlags = this->dyna.stateFlags;
+ break;
+ case OBJSWITCH_TYPE_EYE:
+ this->collisionFlags = this->colliderTris.base.acFlags;
+ this->colliderTris.base.acFlags &= ~AC_HIT;
+ CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->colliderTris.base);
+ break;
+ case OBJSWITCH_TYPE_CRYSTAL:
+ case OBJSWITCH_TYPE_CRYSTAL_TARGETABLE:
+ if (!Player_InCsMode(&globalCtx->state)) {
+ if (this->disableCrystalSwitchTimer > 0) {
+ this->disableCrystalSwitchTimer--;
+ }
+ }
+ if (this->disableCrystalSwitchTimer == 0) {
+ this->colliderJntSph.base.colType = sJntSphInit.base.colType;
+ } else {
+ this->colliderJntSph.base.colType = COLTYPE_NONE;
+ }
+ this->collisionFlags = this->colliderJntSph.base.acFlags;
+ CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->colliderJntSph.base);
+ CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->colliderJntSph.base);
+ }
+}
+
+void ObjSwitch_DrawFloorSwitch(ObjSwitch* this, GlobalContext* globalCtx) {
+ s32 pad[2];
+
+ if (OBJ_SWITCH_GET_SUBTYPE(&this->dyna.actor) == OBJSWITCH_SUBTYPE_ONCE) {
+ Gfx* opa;
+
+ OPEN_DISPS(globalCtx->state.gfxCtx);
+ opa = POLY_OPA_DISP;
+ gSPDisplayList(opa++, &sSetupDL[6 * 25]);
+ gSPMatrix(opa++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gDPSetPrimColor(opa++, 0, 0x80, this->color.r, this->color.g, this->color.b, 255);
+ gSPDisplayList(opa++, gFloorSwitch1DL);
+ POLY_OPA_DISP = opa;
+ CLOSE_DISPS(globalCtx->state.gfxCtx);
+ } else {
+ Gfx_DrawDListOpa(globalCtx, sFloorSwitchDL[OBJ_SWITCH_GET_SUBTYPE(&this->dyna.actor)]);
+ }
+}
+
+void ObjSwitch_DrawRustyFloorSwitch(ObjSwitch* this, GlobalContext* globalCtx) {
+ Gfx_DrawDListOpa(globalCtx, gRustyFloorSwitchDL);
+}
+
+void ObjSwitch_DrawVisibleEyeSwitch(ObjSwitch* this, GlobalContext* globalCtx) {
+ s32 pad;
+ s32 subType = OBJ_SWITCH_GET_SUBTYPE(&this->dyna.actor);
+
+ OPEN_DISPS(globalCtx->state.gfxCtx);
+
+ func_8012C28C(globalCtx->state.gfxCtx);
+ gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPSegment(POLY_OPA_DISP++, 0x08, sEyeSwitchTextures[subType][this->eyeTexIndex]);
+ gSPDisplayList(POLY_OPA_DISP++, sEyeSwitchDL[subType]);
+
+ CLOSE_DISPS(globalCtx->state.gfxCtx);
+}
+
+void ObjSwitch_DrawInvisibleEyeSwitch(ObjSwitch* this, GlobalContext* globalCtx) {
+ s32 pad;
+ s32 subType = OBJ_SWITCH_GET_SUBTYPE(&this->dyna.actor);
+
+ OPEN_DISPS(globalCtx->state.gfxCtx);
+
+ func_8012C2DC(globalCtx->state.gfxCtx);
+ gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPSegment(POLY_XLU_DISP++, 0x08, sEyeSwitchTextures[subType][this->eyeTexIndex]);
+ gSPDisplayList(POLY_XLU_DISP++, sEyeSwitchDL[subType]);
+
+ CLOSE_DISPS(globalCtx->state.gfxCtx);
+}
+
+void ObjSwitch_DrawEyeSwitch(ObjSwitch* this, GlobalContext* globalCtx) {
+ if (OBJ_SWITCH_IS_INVISIBLE(&this->dyna.actor)) {
+ ObjSwitch_DrawInvisibleEyeSwitch(this, globalCtx);
+ } else {
+ ObjSwitch_DrawVisibleEyeSwitch(this, globalCtx);
+ }
+}
+
+void ObjSwitch_DrawCrystalSwitch(ObjSwitch* this, GlobalContext* globalCtx) {
+ s32 pad[2];
+
+ OPEN_DISPS(globalCtx->state.gfxCtx);
+
+ func_800B8118(&this->dyna.actor, globalCtx, 0);
+ AnimatedMat_DrawStep(globalCtx, sCrystalSwitchAnimatedMat, this->crystalAnimTimer);
+ func_8012C28C(globalCtx->state.gfxCtx);
+ func_8012C2DC(globalCtx->state.gfxCtx);
+
+ gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_OPA_DISP++, gCrystalSwitchBaseDL);
+ gDPSetPrimColor(POLY_OPA_DISP++, 0, 0x80, this->color.r, this->color.g, this->color.b, 255);
+ gSPDisplayList(POLY_OPA_DISP++, gCrystalSwitchCoreDL);
+ gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_XLU_DISP++, gCrystalSwitchDiamondDL);
+
+ CLOSE_DISPS(globalCtx->state.gfxCtx);
+}
+
+void ObjSwitch_Draw(Actor* thisx, GlobalContext* globalCtx) {
+ static ObjSwitchDrawFunc drawFunc[] = {
+ ObjSwitch_DrawFloorSwitch, ObjSwitch_DrawRustyFloorSwitch, ObjSwitch_DrawEyeSwitch,
+ ObjSwitch_DrawCrystalSwitch, ObjSwitch_DrawCrystalSwitch, ObjSwitch_DrawFloorSwitch,
+ };
+ ObjSwitch* this = THIS;
+
+ drawFunc[OBJ_SWITCH_GET_TYPE(&this->dyna.actor)](this, globalCtx);
+}
diff --git a/src/overlays/actors/ovl_Obj_Switch/z_obj_switch.h b/src/overlays/actors/ovl_Obj_Switch/z_obj_switch.h
index 5d1134f124..42ee4207fd 100644
--- a/src/overlays/actors/ovl_Obj_Switch/z_obj_switch.h
+++ b/src/overlays/actors/ovl_Obj_Switch/z_obj_switch.h
@@ -5,7 +5,26 @@
struct ObjSwitch;
-typedef void (*ObjSwitchActionFunc)(struct ObjSwitch*, GlobalContext*);
+typedef void (*ObjSwitchActionFunc)(struct ObjSwitch* this, GlobalContext* globalCtx);
+typedef void (*ObjSwitchDrawFunc)(struct ObjSwitch* this, GlobalContext* globalCtx);
+typedef void (*ObjSwitchSetupActionFunc)(struct ObjSwitch* this);
+
+typedef enum {
+ /* 0 */ OBJSWITCH_TYPE_FLOOR,
+ /* 1 */ OBJSWITCH_TYPE_FLOOR_RUSTY, // Unused, incomplete implementation
+ /* 2 */ OBJSWITCH_TYPE_EYE,
+ /* 3 */ OBJSWITCH_TYPE_CRYSTAL,
+ /* 4 */ OBJSWITCH_TYPE_CRYSTAL_TARGETABLE,
+ /* 5 */ OBJSWITCH_TYPE_FLOOR_LARGE
+} ObjSwitchType;
+
+typedef enum {
+ /* 0 */ OBJSWITCH_SUBTYPE_ONCE, // Set Switch Flag when activated, stays activated
+ /* 1 */ OBJSWITCH_SUBTYPE_TOGGLE, // Toggle Switch Flag when activated
+ /* 2 */ OBJSWITCH_SUBTYPE_RESET, // Floor type only, set switch flag when pressed, unset when released
+ /* 3 */ OBJSWITCH_SUBTYPE_RESET_INVERTED, // Floor type only, set switch flag when not pressed, unset when pressed
+ /* 4 */ OBJSWITCH_SUBTYPE_SYNC // Crystal type only, syncronizes all crystal fl
+} ObjSwitchSubType;
#define OBJSWITCH_GET_33(thisx) ((thisx)->params & 0x33)
#define OBJSWITCH_GET_7F00(thisx) (((thisx)->params >> 8) & 0x7F)
@@ -14,12 +33,41 @@ typedef void (*ObjSwitchActionFunc)(struct ObjSwitch*, GlobalContext*);
#define OBJSWITCH_INVERSE_BLUE 0x30
typedef struct ObjSwitch {
- /* 0x0000 */ Actor actor;
- /* 0x0144 */ char unk_144[0x18];
+ /* 0x0000 */ DynaPolyActor dyna;
/* 0x015C */ ObjSwitchActionFunc actionFunc;
- /* 0x0160 */ char unk_160[0xF8];
+ /* 0x0160 */ s16 floorSwitchReleaseTimer;
+ /* 0x0162 */ s16 disableCrystalSwitchTimer;
+ /* 0x0164 */ s8 eyeTexIndex;
+ /* 0x0165 */ s8 sfxTimer;
+ /* 0x0168 */ s32 crystalAnimTimer;
+ /* 0x016C */ Color_RGB8 color;
+ /* 0x016F */ u8 collisionFlags;
+ /* 0x0170 */ s8 floorSwitchPlayerSnapState;
+ /* 0x0171 */ s8 nextSwitchFlagState;
+ /* 0x0172 */ s8 isPlayingCutscene;
+ /* 0x0174 */ ObjSwitchSetupActionFunc setupFunc;
+ union {
+ struct {
+ /* 0x0178 */ ColliderJntSph colliderJntSph;
+ /* 0x0198 */ ColliderJntSphElement colliderJntSphElements[1];
+ };
+ struct {
+ /* 0x0178 */ ColliderTris colliderTris;
+ /* 0x0198 */ ColliderTrisElement colliderTrisElements[2];
+ };
+ };
+ /* 0x0250 */ f32 floorSwitchUpScale;
+ /* 0x0254 */ f32 floorSwitchDownScale;
} ObjSwitch; // size = 0x258
extern const ActorInit Obj_Switch_InitVars;
+#define OBJ_SWITCH_GET_TYPE(thisx) ((thisx)->params&7)
+#define OBJ_SWITCH_GET_SUBTYPE(thisx) ((thisx)->params >> 4 & 7)
+#define OBJ_SWITCH_GET_SWITCH_FLAG(thisx) ((thisx)->params >> 8 & 0x7F)
+#define OBJ_SWITCH_IS_FROZEN(thisx) ((thisx)->params >> 7 & 1)
+#define OBJ_SWITCH_UNSET_FROZEN(thisx) ((thisx)->params &= ~(1 << 7))
+#define OBJ_SWITCH_IS_INVISIBLE(thisx) ((thisx)->params >> 3 & 1)
+#define OBJ_SWITCH_GET_COLOR_ID(thisx) ((thisx)->home.rot.z&1)
+
#endif // Z_OBJ_SWITCH_H
diff --git a/tools/disasm/functions.txt b/tools/disasm/functions.txt
index 0205a83387..4923739ed0 100644
--- a/tools/disasm/functions.txt
+++ b/tools/disasm/functions.txt
@@ -7361,62 +7361,62 @@
0x8093A3F4:("ObjBombiwa_Update",),
0x8093A418:("func_8093A418",),
0x8093A608:("func_8093A608",),
- 0x8093ABD0:("func_8093ABD0",),
- 0x8093AC6C:("func_8093AC6C",),
- 0x8093ADA8:("func_8093ADA8",),
- 0x8093AE1C:("func_8093AE1C",),
- 0x8093AE74:("func_8093AE74",),
- 0x8093AE88:("func_8093AE88",),
- 0x8093AEC4:("func_8093AEC4",),
- 0x8093AEF0:("func_8093AEF0",),
- 0x8093AF1C:("func_8093AF1C",),
- 0x8093AF54:("func_8093AF54",),
+ 0x8093ABD0:("ObjSwitch_InitJntSphCollider",),
+ 0x8093AC6C:("ObjSwitch_InitTrisCollider",),
+ 0x8093ADA8:("ObjSwitch_SpawnIce",),
+ 0x8093AE1C:("ObjSwitch_SetSwitchFlagState",),
+ 0x8093AE74:("ObjSwitch_CrystalUpdateTimer",),
+ 0x8093AE88:("ObjSwitch_StopCutscene",),
+ 0x8093AEC4:("ObjSwitch_PlayFootSwitchSfx",),
+ 0x8093AEF0:("ObjSwitch_PlayDiamondSwitchSfx",),
+ 0x8093AF1C:("ObjSwitch_SetFloorSwitchSnapPlayerState",),
+ 0x8093AF54:("ObjSwitch_FloorSwitchSnapPlayerToSwitchEdge",),
0x8093B084:("ObjSwitch_Init",),
0x8093B59C:("ObjSwitch_Destroy",),
- 0x8093B648:("func_8093B648",),
- 0x8093B668:("func_8093B668",),
- 0x8093B6F4:("func_8093B6F4",),
- 0x8093B710:("func_8093B710",),
- 0x8093B92C:("func_8093B92C",),
- 0x8093B940:("func_8093B940",),
- 0x8093B9C0:("func_8093B9C0",),
- 0x8093B9E4:("func_8093B9E4",),
- 0x8093BB5C:("func_8093BB5C",),
- 0x8093BB70:("func_8093BB70",),
- 0x8093BBD0:("func_8093BBD0",),
- 0x8093BCC8:("func_8093BCC8",),
- 0x8093BCDC:("func_8093BCDC",),
- 0x8093BD34:("func_8093BD34",),
- 0x8093BD4C:("func_8093BD4C",),
- 0x8093BDAC:("func_8093BDAC",),
- 0x8093BDC0:("func_8093BDC0",),
- 0x8093BE10:("func_8093BE10",),
- 0x8093BE2C:("func_8093BE2C",),
- 0x8093BEF0:("func_8093BEF0",),
- 0x8093BF04:("func_8093BF04",),
- 0x8093BF50:("func_8093BF50",),
- 0x8093BF70:("func_8093BF70",),
- 0x8093C0A4:("func_8093C0A4",),
- 0x8093C0B8:("func_8093C0B8",),
- 0x8093C138:("func_8093C138",),
- 0x8093C15C:("func_8093C15C",),
- 0x8093C23C:("func_8093C23C",),
- 0x8093C250:("func_8093C250",),
- 0x8093C2B4:("func_8093C2B4",),
- 0x8093C2D4:("func_8093C2D4",),
- 0x8093C3C8:("func_8093C3C8",),
- 0x8093C3DC:("func_8093C3DC",),
- 0x8093C460:("func_8093C460",),
- 0x8093C488:("func_8093C488",),
- 0x8093C584:("func_8093C584",),
- 0x8093C598:("func_8093C598",),
+ 0x8093B648:("ObjSwitch_TryPlayCutsceneInit",),
+ 0x8093B668:("ObjSwitch_TryPlayCutscene",),
+ 0x8093B6F4:("ObjSwitch_FloorSwitchUpInit",),
+ 0x8093B710:("ObjSwitch_FloorSwitchUp",),
+ 0x8093B92C:("ObjSwitch_FloorSwitchPushDownInit",),
+ 0x8093B940:("ObjSwitch_FloorSwitchPushDown",),
+ 0x8093B9C0:("ObjSwitch_FloorSwitchDownInit",),
+ 0x8093B9E4:("ObjSwitch_FloorSwitchDown",),
+ 0x8093BB5C:("ObjSwitch_FloorSwitchRiseUpInit",),
+ 0x8093BB70:("ObjSwitch_FloorSwitchRiseUp",),
+ 0x8093BBD0:("ObjSwitch_IsEyeSwitchHit",),
+ 0x8093BCC8:("ObjSwitch_EyeSwitchFrozenInit",),
+ 0x8093BCDC:("ObjSwitch_EyeSwitchUnfrozen",),
+ 0x8093BD34:("ObjSwitch_EyeSwitchOpenInit",),
+ 0x8093BD4C:("ObjSwitch_EyeSwitchOpen",),
+ 0x8093BDAC:("ObjSwitch_EyeSwitchClosingInit",),
+ 0x8093BDC0:("ObjSwitch_EyeSwitchClosing",),
+ 0x8093BE10:("ObjSwitch_EyeSwitchClosedInit",),
+ 0x8093BE2C:("ObjSwitch_EyeSwitchClosed",),
+ 0x8093BEF0:("ObjSwitch_EyeSwitchOpeningInit",),
+ 0x8093BF04:("ObjSwitch_EyeSwitchOpening",),
+ 0x8093BF50:("ObjSwitch_CrystalSwitchOffInit",),
+ 0x8093BF70:("ObjSwitch_CrystalSwitchOff",),
+ 0x8093C0A4:("ObjSwitch_CrystalSwitchTurnOnInit",),
+ 0x8093C0B8:("ObjSwitch_CrystalSwitchTurnOn",),
+ 0x8093C138:("ObjSwitch_CrystalSwitchOnInit",),
+ 0x8093C15C:("ObjSwitch_CrystalSwitchOn",),
+ 0x8093C23C:("ObjSwitch_CrystalSwitchTurnOffInit",),
+ 0x8093C250:("ObjSwitch_CrystalSwitchTurnOff",),
+ 0x8093C2B4:("ObjSwitch_LargeFloorSwitchUpInit",),
+ 0x8093C2D4:("ObjSwitch_LargeFloorSwitchUp",),
+ 0x8093C3C8:("ObjSwitch_LargeFloorSwitchPushDownInit",),
+ 0x8093C3DC:("ObjSwitch_LargeFloorSwitchPushDown",),
+ 0x8093C460:("ObjSwitch_LargeFloorSwitchDownInit",),
+ 0x8093C488:("ObjSwitch_LargeFloorSwitchDown",),
+ 0x8093C584:("ObjSwitch_LargeFloorSwitchRiseUpInit",),
+ 0x8093C598:("ObjSwitch_LargeFloorSwitchRiseUp",),
0x8093C5FC:("ObjSwitch_Update",),
- 0x8093C778:("func_8093C778",),
- 0x8093C888:("func_8093C888",),
- 0x8093C8B8:("func_8093C8B8",),
- 0x8093C99C:("func_8093C99C",),
- 0x8093CA80:("func_8093CA80",),
- 0x8093CAC4:("func_8093CAC4",),
+ 0x8093C778:("ObjSwitch_DrawFloorSwitch",),
+ 0x8093C888:("ObjSwitch_DrawRustyFloorSwitch",),
+ 0x8093C8B8:("ObjSwitch_DrawVisibleEyeSwitch",),
+ 0x8093C99C:("ObjSwitch_DrawInvisibleEyeSwitch",),
+ 0x8093CA80:("ObjSwitch_DrawEyeSwitch",),
+ 0x8093CAC4:("ObjSwitch_DrawCrystalSwitch",),
0x8093CC24:("ObjSwitch_Draw",),
0x8093D3C0:("func_8093D3C0",),
0x8093D628:("ObjLift_Init",),
diff --git a/undefined_syms.txt b/undefined_syms.txt
index 54eb83c1b9..da4bdabc45 100644
--- a/undefined_syms.txt
+++ b/undefined_syms.txt
@@ -510,13 +510,10 @@ D_05006760 = 0x05006760;
D_05007498 = 0x05007498;
D_050078A0 = 0x050078A0;
D_05007938 = 0x05007938;
-D_05007E00 = 0x05007E00;
-D_05008018 = 0x05008018;
D_050085F0 = 0x050085F0;
D_050089D0 = 0x050089D0;
D_050182A8 = 0x050182A8;
D_0501B370 = 0x0501B370;
-D_0501B508 = 0x0501B508;
D_0501BEE0 = 0x0501BEE0;
D_0501BFB8 = 0x0501BFB8;
D_0501C058 = 0x0501C058;