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
This commit is contained in:
EllipticEllipsis
2022-03-05 14:57:28 +00:00
committed by GitHub
parent 6017869b1e
commit 7fcefd8d3f
27 changed files with 326 additions and 101 deletions
+3 -3
View File
@@ -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();
}
+7 -7
View File
@@ -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;
}
+1 -1
View File
@@ -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:
+1 -1
View File
@@ -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;
+1 -1
View File
@@ -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;
}
+235 -15
View File
@@ -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")
/**
* 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;
}
#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/func_80169D40.s")
// Purified Southern Swamp -> Poisoned Sothern Swamp
if (sceneNum == SCENE_20SICHITAI2) {
return SCENE_20SICHITAI;
}
#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/func_80169DCC.s")
// Spring Mountain Village -> Winter Mountain Village
if (sceneNum == SCENE_10YUKIYAMANOMURA2) {
return SCENE_10YUKIYAMANOMURA;
}
#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/func_80169E6C.s")
// Spring Goron Village -> Winter Goron Village
if (sceneNum == SCENE_11GORONNOSATO2) {
return SCENE_11GORONNOSATO;
}
#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/func_80169ECC.s")
// Spring Path to Goron Village -> Winter Path to Goron Village
if (sceneNum == SCENE_17SETUGEN2) {
return SCENE_17SETUGEN;
}
#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/func_80169EFC.s")
// Inverted Stone Tower -> Stone Tower
if (sceneNum == SCENE_F41) {
return SCENE_F40;
}
#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/func_80169F78.s")
return sceneNum;
}
#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/func_80169FDC.s")
/**
* 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;
#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/func_80169FFC.s")
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];
#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/FrameAdvance_IsEnabled.s")
if (globalCtx->sceneNum == SCENE_INISIE_R) { // Inverted Stone Tower Temple
cycleSceneFlags = &gSaveContext.cycleSceneFlags[globalCtx->sceneNum];
}
#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/func_8016A02C.s")
cycleSceneFlags->collectible = globalCtx->actorCtx.flags.collectible[0];
cycleSceneFlags->clearedRoom = globalCtx->actorCtx.flags.clearedRoom;
}
#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/func_8016A0AC.s")
void Play_SetRespawnData(GameState* gameState, s32 respawnMode, u16 entranceIndex, s32 roomIndex, s32 playerParams,
Vec3f* pos, s16 yaw) {
GlobalContext* globalCtx = (GlobalContext*)gameState;
#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/func_8016A168.s")
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];
}
#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/func_8016A178.s")
void Play_SetupRespawnPoint(GameState* gameState, s32 respawnMode, s32 playerParams) {
GlobalContext* globalCtx = (GlobalContext*)gameState;
Player* player = GET_PLAYER(globalCtx);
#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/func_8016A268.s")
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")