diff options
| author | EllipticEllipsis <73679967+EllipticEllipsis@users.noreply.github.com> | 2022-03-05 14:57:28 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-03-05 11:57:28 -0300 |
| commit | 7fcefd8d3fa60a13c1229bf4a1bdc5f2c59f0d75 (patch) | |
| tree | e6d62de9f42d5f8c6eb2606c009a95de2af40cc3 /src/code | |
| parent | 6017869b1e2f369fa2c27a17a5e1b8f29b4aaf41 (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.c | 6 | ||||
| -rw-r--r-- | src/code/z_collision_check.c | 14 | ||||
| -rw-r--r-- | src/code/z_effect.c | 2 | ||||
| -rw-r--r-- | src/code/z_effect_soft_sprite.c | 2 | ||||
| -rw-r--r-- | src/code/z_game_over.c | 2 | ||||
| -rw-r--r-- | src/code/z_play.c | 278 |
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") |
