summaryrefslogtreecommitdiff
path: root/src/code
diff options
context:
space:
mode:
authorEllipticEllipsis <73679967+EllipticEllipsis@users.noreply.github.com>2022-03-05 14:57:28 +0000
committerGitHub <noreply@github.com>2022-03-05 11:57:28 -0300
commit7fcefd8d3fa60a13c1229bf4a1bdc5f2c59f0d75 (patch)
treee6d62de9f42d5f8c6eb2606c009a95de2af40cc3 /src/code
parent6017869b1e2f369fa2c27a17a5e1b8f29b4aaf41 (diff)
Decompile and partially document some functions in z_play (#582)
* Decomp 10 functions in z_play, start documentation * Add numbers to enums in z_en_torch2.h * Decompile a 5 more functions (56 unattempted) * Add more details, name some more variables * Bit more Doxygen * Format * Fix arguments * Add symbols to actorfixer.py * Merge branch 'master' into play * Fix z_actor * Review * Deduplicate CycleSceneFlags * Fix warning * Fix unk4 * Review
Diffstat (limited to 'src/code')
-rw-r--r--src/code/z_actor.c6
-rw-r--r--src/code/z_collision_check.c14
-rw-r--r--src/code/z_effect.c2
-rw-r--r--src/code/z_effect_soft_sprite.c2
-rw-r--r--src/code/z_game_over.c2
-rw-r--r--src/code/z_play.c278
6 files changed, 262 insertions, 42 deletions
diff --git a/src/code/z_actor.c b/src/code/z_actor.c
index 064ee0a88..08a230e16 100644
--- a/src/code/z_actor.c
+++ b/src/code/z_actor.c
@@ -2016,7 +2016,7 @@ s32 Actor_PickUp(Actor* actor, GlobalContext* globalCtx, s32 getItemId, f32 xzRa
player->getItemDirection = absYawDiff;
if ((getItemId > GI_NONE) && (getItemId < GI_MAX)) {
- ActorCutscene_SetIntentToPlay(globalCtx->unk_1879C[1]);
+ ActorCutscene_SetIntentToPlay(globalCtx->playerActorCsIds[1]);
}
return true;
@@ -2237,7 +2237,7 @@ void Actor_InitContext(GlobalContext* globalCtx, ActorContext* actorCtx, ActorEn
s32 i;
gSaveContext.weekEventReg[92] |= 0x80;
- cycleFlags = &gSaveContext.cycleSceneFlags[convert_scene_number_among_shared_scenes(globalCtx->sceneNum)];
+ cycleFlags = &gSaveContext.cycleSceneFlags[Play_GetOriginalSceneNumber(globalCtx->sceneNum)];
bzero(actorCtx, sizeof(ActorContext));
ActorOverlayTable_Init();
@@ -3037,7 +3037,7 @@ void Actor_CleanupContext(ActorContext* actorCtx, GlobalContext* globalCtx) {
actorCtx->absoluteSpace = NULL;
}
- func_80169D40(globalCtx);
+ Play_SaveCycleSceneFlags(&globalCtx->state);
ActorOverlayTable_Cleanup();
}
diff --git a/src/code/z_collision_check.c b/src/code/z_collision_check.c
index ddf21fe17..a08e3f822 100644
--- a/src/code/z_collision_check.c
+++ b/src/code/z_collision_check.c
@@ -1145,7 +1145,7 @@ ColChkResetFunc sATResetFuncs[] = {
s32 CollisionCheck_SetAT(GlobalContext* globalCtx, CollisionCheckContext* colCtxt, Collider* collider) {
s32 index;
- if (FrameAdvance_IsEnabled(globalCtx)) {
+ if (FrameAdvance_IsEnabled(&globalCtx->state)) {
return -1;
}
sATResetFuncs[collider->shape](globalCtx, collider);
@@ -1171,7 +1171,7 @@ s32 CollisionCheck_SetAT(GlobalContext* globalCtx, CollisionCheckContext* colCtx
* will be inserted into the next slot.
*/
s32 CollisionCheck_SetAT_SAC(GlobalContext* globalCtx, CollisionCheckContext* colCtxt, Collider* collider, s32 index) {
- if (FrameAdvance_IsEnabled(globalCtx)) {
+ if (FrameAdvance_IsEnabled(&globalCtx->state)) {
return -1;
}
sATResetFuncs[collider->shape](globalCtx, collider);
@@ -1205,7 +1205,7 @@ ColChkResetFunc sACResetFuncs[] = {
s32 CollisionCheck_SetAC(GlobalContext* globalCtx, CollisionCheckContext* colCtxt, Collider* collider) {
s32 index;
- if (FrameAdvance_IsEnabled(globalCtx)) {
+ if (FrameAdvance_IsEnabled(&globalCtx->state)) {
return -1;
}
sACResetFuncs[collider->shape](globalCtx, collider);
@@ -1231,7 +1231,7 @@ s32 CollisionCheck_SetAC(GlobalContext* globalCtx, CollisionCheckContext* colCtx
* will be inserted into the next slot
*/
s32 CollisionCheck_SetAC_SAC(GlobalContext* globalCtx, CollisionCheckContext* colCtxt, Collider* collider, s32 index) {
- if (FrameAdvance_IsEnabled(globalCtx)) {
+ if (FrameAdvance_IsEnabled(&globalCtx->state)) {
return -1;
}
sACResetFuncs[collider->shape](globalCtx, collider);
@@ -1265,7 +1265,7 @@ ColChkResetFunc sOCResetFuncs[] = {
s32 CollisionCheck_SetOC(GlobalContext* globalCtx, CollisionCheckContext* colCtxt, Collider* collider) {
s32 index;
- if (FrameAdvance_IsEnabled(globalCtx)) {
+ if (FrameAdvance_IsEnabled(&globalCtx->state)) {
return -1;
}
sOCResetFuncs[collider->shape](globalCtx, collider);
@@ -1291,7 +1291,7 @@ s32 CollisionCheck_SetOC(GlobalContext* globalCtx, CollisionCheckContext* colCtx
* will be inserted into the next slot.
*/
s32 CollisionCheck_SetOC_SAC(GlobalContext* globalCtx, CollisionCheckContext* colCtxt, Collider* collider, s32 index) {
- if (FrameAdvance_IsEnabled(globalCtx)) {
+ if (FrameAdvance_IsEnabled(&globalCtx->state)) {
return -1;
}
sOCResetFuncs[collider->shape](globalCtx, collider);
@@ -1323,7 +1323,7 @@ s32 CollisionCheck_SetOC_SAC(GlobalContext* globalCtx, CollisionCheckContext* co
s32 CollisionCheck_SetOCLine(GlobalContext* globalCtx, CollisionCheckContext* colCtxt, OcLine* line) {
s32 index;
- if (FrameAdvance_IsEnabled(globalCtx)) {
+ if (FrameAdvance_IsEnabled(&globalCtx->state)) {
return -1;
}
diff --git a/src/code/z_effect.c b/src/code/z_effect.c
index dd696393f..4c446b650 100644
--- a/src/code/z_effect.c
+++ b/src/code/z_effect.c
@@ -124,7 +124,7 @@ void Effect_Add(GlobalContext* globalCtx, s32* pIndex, s32 type, u8 arg3, u8 arg
*pIndex = TOTAL_EFFECT_COUNT;
- if (FrameAdvance_IsEnabled(globalCtx) != true) {
+ if (FrameAdvance_IsEnabled(&globalCtx->state) != true) {
slotFound = false;
switch (type) {
case EFFECT_SPARK:
diff --git a/src/code/z_effect_soft_sprite.c b/src/code/z_effect_soft_sprite.c
index 43307bbc8..fd1d0212c 100644
--- a/src/code/z_effect_soft_sprite.c
+++ b/src/code/z_effect_soft_sprite.c
@@ -152,7 +152,7 @@ s32 EffectSS_FindFreeSpace(s32 priority, s32* tableEntry) {
void EffectSS_Copy(GlobalContext* globalCtx, EffectSs* effectsSs) {
s32 index;
- if (FrameAdvance_IsEnabled(globalCtx) != true) {
+ if (FrameAdvance_IsEnabled(&globalCtx->state) != true) {
if (EffectSS_FindFreeSpace(effectsSs->priority, &index) == 0) {
sEffectSsInfo.searchIndex = index + 1;
sEffectSsInfo.data_table[index] = *effectsSs;
diff --git a/src/code/z_game_over.c b/src/code/z_game_over.c
index 15f3a6693..6b375ecf8 100644
--- a/src/code/z_game_over.c
+++ b/src/code/z_game_over.c
@@ -67,7 +67,7 @@ void GameOver_Update(GlobalContext* globalCtx) {
break;
case GAMEOVER_DEATH_FADE_OUT:
if (func_801A8A50(1) != NA_BGM_GAME_OVER) {
- func_80169F78(globalCtx);
+ func_80169F78(&globalCtx->state);
if (gSaveContext.respawnFlag != -7) {
gSaveContext.respawnFlag = -6;
}
diff --git a/src/code/z_play.c b/src/code/z_play.c
index a14359be7..b5c2b15c8 100644
--- a/src/code/z_play.c
+++ b/src/code/z_play.c
@@ -110,34 +110,254 @@
#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/Play_GetCsCamDataVec3s.s")
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/convert_scene_number_among_shared_scenes.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/func_80169D40.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/func_80169DCC.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/func_80169E6C.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/func_80169ECC.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/func_80169EFC.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/func_80169F78.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/func_80169FDC.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/func_80169FFC.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/FrameAdvance_IsEnabled.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/func_8016A02C.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/func_8016A0AC.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/func_8016A168.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/func_8016A178.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/func_8016A268.s")
+/**
+ * Converts the number of a scene to its "original" equivalent, the default version of the area which the player first
+ * enters.
+ */
+s16 Play_GetOriginalSceneNumber(s16 sceneNum) {
+ // Inverted Stone Tower Temple -> Stone Tower Temple
+ if (sceneNum == SCENE_INISIE_R) {
+ return SCENE_INISIE_N;
+ }
+
+ // Purified Southern Swamp -> Poisoned Sothern Swamp
+ if (sceneNum == SCENE_20SICHITAI2) {
+ return SCENE_20SICHITAI;
+ }
+
+ // Spring Mountain Village -> Winter Mountain Village
+ if (sceneNum == SCENE_10YUKIYAMANOMURA2) {
+ return SCENE_10YUKIYAMANOMURA;
+ }
+
+ // Spring Goron Village -> Winter Goron Village
+ if (sceneNum == SCENE_11GORONNOSATO2) {
+ return SCENE_11GORONNOSATO;
+ }
+
+ // Spring Path to Goron Village -> Winter Path to Goron Village
+ if (sceneNum == SCENE_17SETUGEN2) {
+ return SCENE_17SETUGEN;
+ }
+
+ // Inverted Stone Tower -> Stone Tower
+ if (sceneNum == SCENE_F41) {
+ return SCENE_F40;
+ }
+
+ return sceneNum;
+}
+
+/**
+ * Copies the flags set in ActorContext over to the current scene's CycleSceneFlags, usually using the original scene
+ * number. Exception for Inverted Stone Tower Temple, which uses its own.
+ */
+void Play_SaveCycleSceneFlags(GameState* gameState) {
+ GlobalContext* globalCtx = (GlobalContext*)gameState;
+ CycleSceneFlags* cycleSceneFlags;
+
+ cycleSceneFlags = &gSaveContext.cycleSceneFlags[Play_GetOriginalSceneNumber(globalCtx->sceneNum)];
+ cycleSceneFlags->chest = globalCtx->actorCtx.flags.chest;
+ cycleSceneFlags->swch0 = globalCtx->actorCtx.flags.switches[0];
+ cycleSceneFlags->swch1 = globalCtx->actorCtx.flags.switches[1];
+
+ if (globalCtx->sceneNum == SCENE_INISIE_R) { // Inverted Stone Tower Temple
+ cycleSceneFlags = &gSaveContext.cycleSceneFlags[globalCtx->sceneNum];
+ }
+
+ cycleSceneFlags->collectible = globalCtx->actorCtx.flags.collectible[0];
+ cycleSceneFlags->clearedRoom = globalCtx->actorCtx.flags.clearedRoom;
+}
+
+void Play_SetRespawnData(GameState* gameState, s32 respawnMode, u16 entranceIndex, s32 roomIndex, s32 playerParams,
+ Vec3f* pos, s16 yaw) {
+ GlobalContext* globalCtx = (GlobalContext*)gameState;
+
+ gSaveContext.respawn[respawnMode].entranceIndex = Entrance_CreateIndex(entranceIndex >> 9, 0, entranceIndex & 0xF);
+ gSaveContext.respawn[respawnMode].roomIndex = roomIndex;
+ gSaveContext.respawn[respawnMode].pos = *pos;
+ gSaveContext.respawn[respawnMode].yaw = yaw;
+ gSaveContext.respawn[respawnMode].playerParams = playerParams;
+ gSaveContext.respawn[respawnMode].tempSwchFlags = globalCtx->actorCtx.flags.switches[2];
+ gSaveContext.respawn[respawnMode].unk_18 = globalCtx->actorCtx.flags.collectible[1];
+ gSaveContext.respawn[respawnMode].tempCollectFlags = globalCtx->actorCtx.flags.collectible[2];
+}
+
+void Play_SetupRespawnPoint(GameState* gameState, s32 respawnMode, s32 playerParams) {
+ GlobalContext* globalCtx = (GlobalContext*)gameState;
+ Player* player = GET_PLAYER(globalCtx);
+
+ if (globalCtx->sceneNum != SCENE_KAKUSIANA) { // Grottos
+ Play_SetRespawnData(&globalCtx->state, respawnMode, (u16)((void)0, gSaveContext.entranceIndex),
+ globalCtx->roomCtx.currRoom.num, playerParams, &player->actor.world.pos,
+ player->actor.shape.rot.y);
+ }
+}
+
+// Override respawn data in Sakon's Hideout
+void func_80169ECC(GlobalContext* globalCtx) {
+ if (globalCtx->sceneNum == SCENE_SECOM) {
+ globalCtx->nextEntranceIndex = 0x2060;
+ gSaveContext.respawnFlag = -7;
+ }
+}
+
+// Gameplay_TriggerVoidOut ?
+// Used by Player, Ikana_Rotaryroom, Bji01, Kakasi, LiftNuts, Test4, Warptag, WarpUzu, Roomtimer
+void func_80169EFC(GameState* gameState) {
+ GlobalContext* globalCtx = (GlobalContext*)gameState;
+
+ gSaveContext.respawn[0].tempSwchFlags = globalCtx->actorCtx.flags.switches[2];
+ gSaveContext.respawn[0].unk_18 = globalCtx->actorCtx.flags.collectible[1];
+ gSaveContext.respawn[0].tempCollectFlags = globalCtx->actorCtx.flags.collectible[2];
+ globalCtx->nextEntranceIndex = gSaveContext.respawn[0].entranceIndex;
+ gSaveContext.respawnFlag = 1;
+ func_80169ECC(globalCtx);
+ globalCtx->sceneLoadFlag = 0x14;
+ globalCtx->unk_1887F = 2;
+}
+
+// Gameplay_LoadToLastEntrance ?
+// Used by game_over and Test7
+void func_80169F78(GameState* gameState) {
+ GlobalContext* globalCtx = (GlobalContext*)gameState;
+
+ globalCtx->nextEntranceIndex = gSaveContext.respawn[2].entranceIndex;
+ gSaveContext.respawnFlag = -1;
+ func_80169ECC(globalCtx);
+ globalCtx->sceneLoadFlag = 0x14;
+ globalCtx->unk_1887F = 2;
+}
+
+// Gameplay_TriggerRespawn ?
+// Used for void by Wallmaster, Deku Shrine doors. Also used by Player, Kaleido, DoorWarp1
+void func_80169FDC(GameState* gameState) {
+ func_80169F78(gameState);
+}
+
+// Used by Kankyo to determine how to change the lighting, e.g. for game over.
+s32 func_80169FFC(GameState* gameState) {
+ GlobalContext* globalCtx = (GlobalContext*)gameState;
+
+ return globalCtx->roomCtx.currRoom.mesh->type0.type != 1;
+}
+
+s32 FrameAdvance_IsEnabled(GameState* gameState) {
+ GlobalContext* globalCtx = (GlobalContext*)gameState;
+
+ return globalCtx->frameAdvCtx.enabled != 0;
+}
+
+// Unused, unchanged from OoT, which uses it only in one Camera function.
+/**
+ * @brief Tests if \p actor is a door and the sides are different rooms.
+ *
+ * @param[in] gameState GameState, promoted to globalCtx inside.
+ * @param[in] actor Actor to test.
+ * @param[out] yaw Facing angle of the actor, or reverse if in the back room.
+ * @return true if \p actor is a door and the sides are in different rooms, false otherwise
+ */
+s32 func_8016A02C(GameState* gameState, Actor* actor, s16* yaw) {
+ GlobalContext* globalCtx = (GlobalContext*)gameState;
+ TransitionActorEntry* transitionActor;
+ s8 frontRoom;
+
+ if (actor->category != ACTORCAT_DOOR) {
+ return false;
+ }
+
+ transitionActor = &globalCtx->doorCtx.transitionActorList[(u16)actor->params >> 10];
+ frontRoom = transitionActor->sides[0].room;
+ if (frontRoom == transitionActor->sides[1].room) {
+ return false;
+ }
+
+ if (frontRoom == actor->room) {
+ *yaw = actor->shape.rot.y;
+ } else {
+ *yaw = actor->shape.rot.y + 0x8000;
+ }
+
+ return true;
+}
+
+// Unused
+/**
+ * @brief Tests if \p pos is underwater.
+ *
+ * @param[in] globalCtx GlobalContext
+ * @param[in] pos position to test
+ * @return true if inside a waterbox and not above a void.
+ */
+s32 Play_IsUnderwater(GlobalContext* globalCtx, Vec3f* pos) {
+ WaterBox* waterBox;
+ CollisionPoly* poly;
+ Vec3f waterSurfacePos;
+ s32 bgId;
+
+ waterSurfacePos = *pos;
+
+ if ((WaterBox_GetSurface1(globalCtx, &globalCtx->colCtx, waterSurfacePos.x, waterSurfacePos.z, &waterSurfacePos.y,
+ &waterBox) == true) &&
+ (pos->y < waterSurfacePos.y) &&
+ (BgCheck_EntityRaycastFloor3(&globalCtx->colCtx, &poly, &bgId, &waterSurfacePos) != BGCHECK_Y_MIN)) {
+ return true;
+ } else {
+ return false;
+ }
+}
+
+// z_demo and EnTest4
+// This data appears to be a boolean. It is only set by Play_Init.
+s32 func_8016A168(void) {
+ return D_801D0D50;
+}
+
+// A mapping from playerActorCsIds to sGlobalCamDataSettings indices.
+extern s16 D_801D0D64[];
+// s16 D_801D0D64[] = { -3, -2, -4, -5, -7, -11, -8, -9, -6, -16 };
+
+// Used by Player
+/**
+ * Extract the common actor cutscene ids used by Player from the scene and set the actor cutscene ids in
+ * globalCtx->playerActorCsIds. If a playerActorCsId is not present in the scene, then that particular id is set
+ * to -1. Otherwise, if there is an ActorCutscene where csCamSceneDataId matches the appropriate element of D_801D0D64,
+ * set the corresponding playerActorCsId (and possibly change its priority for the zeroth one)
+ */
+void Play_AssignPlayerActorCsIdsFromScene(GameState* gameState, s32 startActorCsId) {
+ GlobalContext* globalCtx = (GlobalContext*)gameState;
+ s32 i;
+ s16* curPlayerActorCsId = globalCtx->playerActorCsIds;
+ s16* phi_s1 = D_801D0D64;
+
+ for (i = 0; i < ARRAY_COUNT(globalCtx->playerActorCsIds); i++, curPlayerActorCsId++, phi_s1++) {
+ ActorCutscene* actorCutscene;
+ s32 curActorCsId;
+
+ *curPlayerActorCsId = -1;
+
+ for (curActorCsId = startActorCsId; curActorCsId != -1; curActorCsId = actorCutscene->additionalCutscene) {
+ actorCutscene = ActorCutscene_GetCutscene(curActorCsId);
+
+ if (actorCutscene->csCamSceneDataId == *phi_s1) {
+ if ((actorCutscene->csCamSceneDataId == -3) &&
+ (actorCutscene->priority == 700)) { // override ocarina cs priority
+ actorCutscene->priority = 550;
+ }
+ *curPlayerActorCsId = curActorCsId;
+ break;
+ }
+ }
+ }
+}
+
+// These regs are used by Gameplay_Draw, and several actors, purpose as yet unclear.
+void func_8016A268(GameState* gameState, s16 arg1, u8 arg2, u8 arg3, u8 arg4, u8 arg5) {
+ MREG(64) = arg1;
+ MREG(65) = arg2;
+ MREG(66) = arg3;
+ MREG(67) = arg4;
+ MREG(68) = arg5;
+}
#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/Play_Init.s")