mirror of
https://github.com/zeldaret/mm.git
synced 2026-05-31 09:21:28 -04:00
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:
+3
-3
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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
@@ -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:
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
@@ -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")
|
||||
|
||||
Reference in New Issue
Block a user