summaryrefslogtreecommitdiff
path: root/src/code
diff options
context:
space:
mode:
authorengineer124 <47598039+engineer124@users.noreply.github.com>2022-08-09 20:01:55 -0400
committerGitHub <noreply@github.com>2022-08-09 20:01:55 -0400
commita80637fd598210cd28c056a131a9ff01161544f9 (patch)
treef5e268bddfd4c5157f5ee4b3e7cde6022f044506 /src/code
parentb716e76d3edc9392bca1dde99a66a9ee2cdfadb2 (diff)
Decompile and Document Camera `z_play` functions (#933)
* Document z_play camera functions * cleanup function names * PR Suggestion * Fix master merge, add comments * fix merge * small fix Co-authored-by: angie <angheloalf95@gmail.com>
Diffstat (limited to 'src/code')
-rw-r--r--src/code/z_actor.c36
-rw-r--r--src/code/z_camera.c8
-rw-r--r--src/code/z_game_dlftbls.c2
-rw-r--r--src/code/z_lights.c18
-rw-r--r--src/code/z_play.c218
-rw-r--r--src/code/z_player_lib.c4
6 files changed, 231 insertions, 55 deletions
diff --git a/src/code/z_actor.c b/src/code/z_actor.c
index 9ca8ffd6e..751327552 100644
--- a/src/code/z_actor.c
+++ b/src/code/z_actor.c
@@ -393,11 +393,7 @@ void func_800B4B50(Actor* actor, Lights* mapper, PlayState* play) {
void Actor_GetProjectedPos(PlayState* play, Vec3f* worldPos, Vec3f* projectedPos, f32* invW) {
SkinMatrix_Vec3fMtxFMultXYZW(&play->viewProjectionMtxF, worldPos, projectedPos, invW);
- if (*invW < 1.0f) {
- *invW = 1.0f;
- } else {
- *invW = 1.0f / *invW;
- }
+ *invW = (*invW < 1.0f) ? 1.0f : (1.0f / *invW);
}
void Target_SetPos(TargetContext* targetCtx, s32 index, f32 x, f32 y, f32 z) {
@@ -507,11 +503,11 @@ void Actor_DrawZTarget(TargetContext* targetCtx, PlayState* play) {
Actor_GetProjectedPos(play, &targetCtx->targetCenterPos, &projectedPos, &invW);
- projectedPos.x = (160 * (projectedPos.x * invW)) * var1;
- projectedPos.x = CLAMP(projectedPos.x, -320.0f, 320.0f);
+ projectedPos.x = ((SCREEN_WIDTH / 2) * (projectedPos.x * invW)) * var1;
+ projectedPos.x = CLAMP(projectedPos.x, -SCREEN_WIDTH, SCREEN_WIDTH);
- projectedPos.y = (120 * (projectedPos.y * invW)) * var1;
- projectedPos.y = CLAMP(projectedPos.y, -240.0f, 240.0f);
+ projectedPos.y = ((SCREEN_HEIGHT / 2) * (projectedPos.y * invW)) * var1;
+ projectedPos.y = CLAMP(projectedPos.y, -SCREEN_HEIGHT, SCREEN_HEIGHT);
projectedPos.z = projectedPos.z * var1;
@@ -588,8 +584,8 @@ void func_800B5814(TargetContext* targetCtx, Player* player, Actor* actor, GameS
PlayState* play = (PlayState*)gameState;
Actor* sp68 = NULL;
s32 category;
- Vec3f sp58;
- f32 sp54;
+ Vec3f projectedPos;
+ f32 invW;
if ((player->unk_730 != 0) && (player->unk_AE3[player->unk_ADE] == 2)) {
targetCtx->unk_94 = NULL;
@@ -641,8 +637,9 @@ void func_800B5814(TargetContext* targetCtx, Player* player, Actor* actor, GameS
}
if (actor != NULL && targetCtx->unk4B == 0) {
- Actor_GetProjectedPos(play, &actor->focus.pos, &sp58, &sp54);
- if ((sp58.z <= 0.0f) || (fabsf(sp58.x * sp54) >= 1.0f) || (fabsf(sp58.y * sp54) >= 1.0f)) {
+ Actor_GetProjectedPos(play, &actor->focus.pos, &projectedPos, &invW);
+ if ((projectedPos.z <= 0.0f) || (fabsf(projectedPos.x * invW) >= 1.0f) ||
+ (fabsf(projectedPos.y * invW) >= 1.0f)) {
actor = NULL;
}
}
@@ -1963,14 +1960,15 @@ s32 func_800B886C(Actor* actor, PlayState* play) {
void Actor_GetScreenPos(PlayState* play, Actor* actor, s16* x, s16* y) {
Vec3f projectedPos;
- f32 w;
+ f32 invW;
+
+ Actor_GetProjectedPos(play, &actor->focus.pos, &projectedPos, &invW);
- Actor_GetProjectedPos(play, &actor->focus.pos, &projectedPos, &w);
- *x = PROJECTED_TO_SCREEN_X(projectedPos, w);
- *y = PROJECTED_TO_SCREEN_Y(projectedPos, w);
+ *x = PROJECTED_TO_SCREEN_X(projectedPos, invW);
+ *y = PROJECTED_TO_SCREEN_Y(projectedPos, invW);
}
-s32 func_800B8934(PlayState* play, Actor* actor) {
+s32 Actor_OnScreen(PlayState* play, Actor* actor) {
Vec3f projectedPos;
f32 invW;
s32 pad[2];
@@ -4058,7 +4056,7 @@ s32 func_800BD2B4(PlayState* play, Actor* actor, s16* arg2, f32 arg3, u16 (*text
} else if (*arg2) {
*arg2 = arg5(play, actor);
return false;
- } else if (!func_800B8934(play, actor)) {
+ } else if (!Actor_OnScreen(play, actor)) {
return false;
} else if (!func_800B8614(actor, play, arg3)) {
return false;
diff --git a/src/code/z_camera.c b/src/code/z_camera.c
index 63a06b512..20420d6ef 100644
--- a/src/code/z_camera.c
+++ b/src/code/z_camera.c
@@ -372,9 +372,9 @@ s32 Camera_GetWaterBoxBgCamSetting(Camera* camera, f32* waterY) {
#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/func_800DE0E0.s")
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/func_800DE0EC.s")
+#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/Camera_InitPlayerSettings.s")
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/func_800DE308.s")
+#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/Camera_ChangeStatus.s")
#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/func_800DE324.s")
@@ -416,7 +416,7 @@ s32 Camera_GetWaterBoxBgCamSetting(Camera* camera, f32* waterY) {
#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/Camera_AddQuake.s")
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/func_800DFD78.s")
+#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/Camera_SetViewParam.s")
#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/func_800DFEF0.s")
@@ -432,7 +432,7 @@ s32 Camera_GetWaterBoxBgCamSetting(Camera* camera, f32* waterY) {
#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/Camera_ChangeDoorCam.s")
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/func_800E007C.s")
+#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/Camera_Copy.s")
#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/func_800E01AC.s")
diff --git a/src/code/z_game_dlftbls.c b/src/code/z_game_dlftbls.c
index 2df62a054..a79c732d8 100644
--- a/src/code/z_game_dlftbls.c
+++ b/src/code/z_game_dlftbls.c
@@ -17,7 +17,7 @@ GameStateOverlay gGameStateOverlayTable[] = {
GAMESTATE_OVERLAY_INTERNAL(TitleSetup_Init, TitleSetup_Destroy, sizeof(GameState)),
GAMESTATE_OVERLAY(select, MapSelect_Init, MapSelect_Destroy, sizeof(MapSelectState)),
GAMESTATE_OVERLAY(title, Title_Init, Title_Destroy, sizeof(TitleContext)),
- GAMESTATE_OVERLAY_INTERNAL(Play_Init, Play_Fini, sizeof(PlayState)),
+ GAMESTATE_OVERLAY_INTERNAL(Play_Init, Play_Destroy, sizeof(PlayState)),
GAMESTATE_OVERLAY(opening, Opening_Init, Opening_Destroy, sizeof(OpeningContext)),
GAMESTATE_OVERLAY(file_choose, FileChoose_Init, FileChoose_Destroy, sizeof(FileChooseContext)),
GAMESTATE_OVERLAY(daytelop, Daytelop_Init, Daytelop_Destroy, sizeof(DaytelopContext)),
diff --git a/src/code/z_lights.c b/src/code/z_lights.c
index 92e9beb30..e3e732eb3 100644
--- a/src/code/z_lights.c
+++ b/src/code/z_lights.c
@@ -379,22 +379,22 @@ void Lights_GlowCheck(PlayState* play) {
LightPoint* params = &light->info->params.point;
if (light->info->type == LIGHT_POINT_GLOW) {
- Vec3f pos;
+ Vec3f worldPos;
Vec3f projectedPos;
f32 invW;
- pos.x = params->x;
- pos.y = params->y;
- pos.z = params->z;
- Actor_GetProjectedPos(play, &pos, &projectedPos, &invW);
+ worldPos.x = params->x;
+ worldPos.y = params->y;
+ worldPos.z = params->z;
+ Actor_GetProjectedPos(play, &worldPos, &projectedPos, &invW);
params->drawGlow = 0;
if ((projectedPos.z > 1) && (fabsf(projectedPos.x * invW) < 1) && (fabsf(projectedPos.y * invW) < 1)) {
- s32 wX = PROJECTED_TO_SCREEN_X(projectedPos, invW);
- s32 wY = PROJECTED_TO_SCREEN_Y(projectedPos, invW);
- s32 wZ = (s32)((projectedPos.z * invW) * 16352) + 16352;
- s32 zBuf = func_80178A94(wX, wY);
+ s32 screenPosX = PROJECTED_TO_SCREEN_X(projectedPos, invW);
+ s32 screenPosY = PROJECTED_TO_SCREEN_Y(projectedPos, invW);
+ s32 wZ = (s32)((projectedPos.z * invW) * 16352.0f) + 16352;
+ s32 zBuf = func_80178A94(screenPosX, screenPosY);
if (wZ < zBuf) {
params->drawGlow = 1;
diff --git a/src/code/z_play.c b/src/code/z_play.c
index 6d90048f5..014fb6279 100644
--- a/src/code/z_play.c
+++ b/src/code/z_play.c
@@ -34,7 +34,7 @@
#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/func_801660B8.s")
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/Play_Fini.s")
+#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/Play_Destroy.s")
#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/func_801663C4.s")
@@ -46,7 +46,7 @@
#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/func_80166B30.s")
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/func_80167814.s")
+#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/Play_Update.s")
#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/func_80167DE4.s")
@@ -56,7 +56,7 @@
#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/func_80168DAC.s")
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/Play_Update.s")
+#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/Play_Main.s")
s32 Play_InCsMode(PlayState* this) {
return (this->csCtx.state != 0) || Player_InCsMode(this);
@@ -74,39 +74,217 @@ s32 Play_InCsMode(PlayState* this) {
#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/Play_SceneInit.s")
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/func_80169474.s")
+void Play_GetScreenPos(PlayState* this, Vec3f* worldPos, Vec3f* screenPos) {
+ f32 invW;
+
+ // screenPos temporarily stores the projectedPos
+ Actor_GetProjectedPos(this, worldPos, screenPos, &invW);
+
+ screenPos->x = (SCREEN_WIDTH / 2) + (screenPos->x * invW * (SCREEN_WIDTH / 2));
+ screenPos->y = (SCREEN_HEIGHT / 2) - (screenPos->y * invW * (SCREEN_HEIGHT / 2));
+}
+
+s16 Play_CreateSubCamera(PlayState* this) {
+ s16 subCamId;
+
+ for (subCamId = CAM_ID_SUB_FIRST; subCamId < NUM_CAMS; subCamId++) {
+ if (this->cameraPtrs[subCamId] == NULL) {
+ break;
+ }
+ }
+
+ // if no subCameras available
+ if (subCamId == NUM_CAMS) {
+ return CAM_ID_NONE;
+ }
+
+ this->cameraPtrs[subCamId] = &this->subCameras[subCamId - CAM_ID_SUB_FIRST];
+ Camera_Init(this->cameraPtrs[subCamId], &this->view, &this->colCtx, this);
+ this->cameraPtrs[subCamId]->camId = subCamId;
+
+ return subCamId;
+}
+
+s16 Play_GetActiveCamId(PlayState* this) {
+ return this->activeCamId;
+}
+
+s32 Play_ChangeCameraStatus(PlayState* this, s16 camId, s16 status) {
+ s16 camIdx = (camId == CAM_ID_NONE) ? this->activeCamId : camId;
+
+ if (status == CAM_STATUS_ACTIVE) {
+ this->activeCamId = camIdx;
+ }
+
+ return Camera_ChangeStatus(this->cameraPtrs[camIdx], status);
+}
+
+void Play_ClearCamera(PlayState* this, s16 camId) {
+ s16 camIdx = (camId == CAM_ID_NONE) ? this->activeCamId : camId;
+
+ if (this->cameraPtrs[camIdx] != NULL) {
+ Camera_ChangeStatus(this->cameraPtrs[camIdx], CAM_STATUS_INACTIVE);
+ this->cameraPtrs[camIdx] = NULL;
+ }
+}
+
+void Play_ClearAllSubCameras(PlayState* this) {
+ s16 subCamId;
+
+ for (subCamId = CAM_ID_SUB_FIRST; subCamId < NUM_CAMS; subCamId++) {
+ if (this->cameraPtrs[subCamId] != NULL) {
+ Play_ClearCamera(this, subCamId);
+ }
+ }
+
+ this->activeCamId = CAM_ID_MAIN;
+}
+
+Camera* Play_GetCamera(PlayState* this, s16 camId) {
+ s16 camIdx = (camId == CAM_ID_NONE) ? this->activeCamId : camId;
+
+ return this->cameraPtrs[camIdx];
+}
+
+/**
+ * @return bit-packed success if each of the params were applied
+ */
+s32 Play_SetCameraAtEye(PlayState* this, s16 camId, Vec3f* at, Vec3f* eye) {
+ s32 successfullySet = 0;
+ s16 camIdx = (camId == CAM_ID_NONE) ? this->activeCamId : camId;
+ Camera* camera = this->cameraPtrs[camIdx];
+
+ successfullySet |= Camera_SetViewParam(camera, CAM_VIEW_AT, at);
+ successfullySet <<= 1;
+ successfullySet |= Camera_SetViewParam(camera, CAM_VIEW_EYE, eye);
+
+ camera->dist = Math3D_Distance(at, eye);
+
+ if (camera->focalActor != NULL) {
+ camera->atActorOffset.x = at->x - camera->focalActor->world.pos.x;
+ camera->atActorOffset.y = at->y - camera->focalActor->world.pos.y;
+ camera->atActorOffset.z = at->z - camera->focalActor->world.pos.z;
+ } else {
+ camera->atActorOffset.x = camera->atActorOffset.y = camera->atActorOffset.z = 0.0f;
+ }
+
+ camera->atLerpStepScale = 0.01f;
+
+ return successfullySet;
+}
+
+/**
+ * @return bit-packed success if each of the params were applied
+ */
+s32 Play_SetCameraAtEyeUp(PlayState* this, s16 camId, Vec3f* at, Vec3f* eye, Vec3f* up) {
+ s32 successfullySet = 0;
+ s16 camIdx = (camId == CAM_ID_NONE) ? this->activeCamId : camId;
+ Camera* camera = this->cameraPtrs[camIdx];
+
+ successfullySet |= Camera_SetViewParam(camera, CAM_VIEW_AT, at);
+ successfullySet <<= 1;
+ successfullySet |= Camera_SetViewParam(camera, CAM_VIEW_EYE, eye);
+ successfullySet <<= 1;
+ successfullySet |= Camera_SetViewParam(camera, CAM_VIEW_UP, up);
+
+ camera->dist = Math3D_Distance(at, eye);
+
+ if (camera->focalActor != NULL) {
+ camera->atActorOffset.x = at->x - camera->focalActor->world.pos.x;
+ camera->atActorOffset.y = at->y - camera->focalActor->world.pos.y;
+ camera->atActorOffset.z = at->z - camera->focalActor->world.pos.z;
+ } else {
+ camera->atActorOffset.x = camera->atActorOffset.y = camera->atActorOffset.z = 0.0f;
+ }
+
+ camera->atLerpStepScale = 0.01f;
+
+ return successfullySet;
+}
+
+/**
+ * @return true if the fov was successfully set
+ */
+s32 Play_SetCameraFov(PlayState* this, s16 camId, f32 fov) {
+ s32 successfullySet = Camera_SetViewParam(this->cameraPtrs[camId], CAM_VIEW_FOV, &fov) & 1;
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/Play_CreateSubCamera.s")
+ if (1) {}
+ return successfullySet;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/Play_GetActiveCamId.s")
+s32 Play_SetCameraRoll(PlayState* this, s16 camId, s16 roll) {
+ s16 camIdx = (camId == CAM_ID_NONE) ? this->activeCamId : camId;
+ Camera* camera = this->cameraPtrs[camIdx];
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/Play_CameraChangeStatus.s")
+ camera->roll = roll;
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/Play_ClearCamera.s")
+ return 1;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/Play_ClearAllSubCameras.s")
+void Play_CopyCamera(PlayState* this, s16 destCamId, s16 srcCamId) {
+ s16 srcCamId2 = (srcCamId == CAM_ID_NONE) ? this->activeCamId : srcCamId;
+ s16 destCamId1 = (destCamId == CAM_ID_NONE) ? this->activeCamId : destCamId;
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/Play_GetCamera.s")
+ Camera_Copy(this->cameraPtrs[destCamId1], this->cameraPtrs[srcCamId2]);
+}
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/Play_CameraSetAtEye.s")
+// Same as Play_ChangeCameraSetting but also calls Camera_InitPlayerSettings
+s32 func_80169A50(PlayState* this, s16 camId, Player* player, s16 setting) {
+ Camera* camera;
+ s16 camIdx = (camId == CAM_ID_NONE) ? this->activeCamId : camId;
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/Play_CameraSetAtEyeUp.s")
+ camera = this->cameraPtrs[camIdx];
+ Camera_InitPlayerSettings(camera, player);
+ return Camera_ChangeSetting(camera, setting);
+}
+
+s32 Play_ChangeCameraSetting(PlayState* this, s16 camId, s16 setting) {
+ return Camera_ChangeSetting(Play_GetCamera(this, camId), setting);
+}
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/Play_CameraSetFov.s")
+// Related to bosses and fishing
+void func_80169AFC(PlayState* this, s16 camId, s16 timer) {
+ s16 camIdx = (camId == CAM_ID_NONE) ? this->activeCamId : camId;
+ s16 i;
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/Play_CameraSetRoll.s")
+ Play_ClearCamera(this, camIdx);
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/Play_CopyCamera.s")
+ for (i = CAM_ID_SUB_FIRST; i < NUM_CAMS; i++) {
+ if (this->cameraPtrs[i] != NULL) {
+ Play_ClearCamera(this, i);
+ }
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/func_80169A50.s")
+ if (timer <= 0) {
+ Play_ChangeCameraStatus(this, CAM_ID_MAIN, CAM_STATUS_ACTIVE);
+ this->cameraPtrs[CAM_ID_MAIN]->childCamId = this->cameraPtrs[CAM_ID_MAIN]->doorTimer2 = 0;
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/Play_CameraChangeSetting.s")
+s16 Play_GetCameraUID(PlayState* this, s16 camId) {
+ Camera* camera = this->cameraPtrs[camId];
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/func_80169AFC.s")
+ if (camera != NULL) {
+ return camera->uid;
+ } else {
+ return -1;
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/Play_CameraGetUID.s")
+// Unused in both MM and OoT, purpose is very unclear
+s16 func_80169BF8(PlayState* this, s16 camId, s16 uid) {
+ Camera* camera = this->cameraPtrs[camId];
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/func_80169BF8.s")
+ if (camera != NULL) {
+ return 0;
+ } else if (camera->uid != uid) {
+ return 0;
+ } else if (camera->status != CAM_STATUS_ACTIVE) {
+ return 2;
+ } else {
+ return 1;
+ }
+}
u16 Play_GetActorCsCamSetting(PlayState* this, s32 csCamDataIndex) {
ActorCsCamInfo* actorCsCamList = &this->actorCsCamList[csCamDataIndex];
diff --git a/src/code/z_player_lib.c b/src/code/z_player_lib.c
index 98a237b10..100cb3f8a 100644
--- a/src/code/z_player_lib.c
+++ b/src/code/z_player_lib.c
@@ -706,8 +706,8 @@ void func_80123E90(PlayState* play, Actor* actor) {
player->unk_730 = actor;
player->unk_A78 = actor;
player->stateFlags1 |= PLAYER_STATE1_10000;
- func_800DFD78(Play_GetCamera(play, CAM_ID_MAIN), 8, actor);
- Camera_ChangeMode(Play_GetCamera(play, CAM_ID_MAIN), 9);
+ Camera_SetViewParam(Play_GetCamera(play, CAM_ID_MAIN), CAM_VIEW_TARGET, actor);
+ Camera_ChangeMode(Play_GetCamera(play, CAM_ID_MAIN), CAM_MODE_FOLLOWTARGET);
}
s32 func_80123F14(PlayState* play) {