From e88fcc1b140dbd04ca4341376139300d0cb698fa Mon Sep 17 00:00:00 2001 From: eperdew Date: Mon, 21 Oct 2024 22:00:53 -0400 Subject: [PATCH] Decompile some camera functions (#1484) * Match Camera_80029124 * Match Camera_800293E0 * Remove Camera_800293E0 comment * Partial match on Camera_80029C88 * Partially match Camera_8002A28C * Remove duplicate decompilation * Decent progress on Camera_8002A28C * Couple of small functions * More progress in camera.c Couple of other small functions Decent progress on Camera_8002A28C Remove duplicate decompilation --- src/melee/cm/camera.c | 216 ++++++++++++++++++++++++++++++++++++++++-- src/melee/cm/camera.h | 4 +- src/melee/cm/types.h | 28 ++++-- 3 files changed, 227 insertions(+), 21 deletions(-) diff --git a/src/melee/cm/camera.c b/src/melee/cm/camera.c index 41f3d164a4..c46c8af783 100644 --- a/src/melee/cm/camera.c +++ b/src/melee/cm/camera.c @@ -1,10 +1,13 @@ #include +#include "cm/forward.h" #include "ft/forward.h" #include "camera.static.h" +#include "cm/types.h" #include "ft/ftlib.h" +#include "gr/ground.h" #include "gr/stage.h" #include "lb/lbvector.h" #include "pl/player.h" @@ -12,6 +15,9 @@ #include #include #include +#include + +static HSD_CObj* cm_804D6464; /// #Camera_80028B9C @@ -99,11 +105,126 @@ void Camera_800290D4(CameraBox* subject) cm_804D6458 = subject; } -/// #Camera_80029124 +u32 Camera_80029124(Vec3* arg0, s32 distance) +{ + f32 _unused; + f32 slope; + f32 intercept; + f32 bounds_left; + f32 bounds_right; + f32 bounds_top; + f32 bounds_bottom; + u32 result; + + result = 0; + Ground_801C4368(&slope, &intercept); + slope += 1.0; + + bounds_left = Stage_GetCamBoundsLeftOffset(); + bounds_right = Stage_GetCamBoundsRightOffset(); + bounds_top = Stage_GetCamBoundsTopOffset(); + + if (Stage_GetCamBoundsBottomOffset() > slope) { + bounds_bottom = Stage_GetCamBoundsBottomOffset(); + } else { + bounds_bottom = slope; + } + + if (arg0->x < (bounds_left - distance)) { + result |= 4; + } + if (arg0->x > (bounds_right + distance)) { + result |= 8; + } + + if (arg0->y > (bounds_top + distance)) { + result |= 1; + } + if (arg0->y < (bounds_bottom - distance)) { + result |= 2; + } + + return result; +} /// #Camera_8002928C -/// #Camera_800293E0 +void Camera_800293E0(void) +{ + CameraBox* curr; + f32 temp_f0; + f32 temp_f1; + f32 distance; + + for (curr = cm_804D6468; curr != NULL; curr = curr->prev) { + if (Camera_8002928C(curr) != 0) { + temp_f1 = curr->x40.x; + temp_f0 = curr->x2C.x; + distance = temp_f1 - temp_f0; + if (distance != 0.0f) { + if (distance > 0.5f) { + curr->x2C.x += 0.5f; + } else if (distance < -0.5f) { + curr->x2C.x -= 0.5f; + } else { + curr->x2C.x = temp_f1; + } + } + + temp_f1 = curr->x40.y; + temp_f0 = curr->x2C.y; + distance = temp_f1 - temp_f0; + if (distance != 0.0f) { + if (distance > 0.5f) { + curr->x2C.y += 0.5f; + } else if (distance < -0.5f) { + curr->x2C.y -= 0.5f; + } else { + curr->x2C.y = temp_f1; + } + } + + temp_f1 = curr->x48.x; + temp_f0 = curr->x34.x; + distance = temp_f1 - temp_f0; + if (distance != 0.0f) { + if (distance > 0.5f) { + curr->x34.x += 0.5f; + } else if (distance < -0.5f) { + curr->x34.x -= 0.5f; + } else { + curr->x34.x = temp_f1; + } + } + + temp_f1 = curr->x48.y; + temp_f0 = curr->x34.y; + distance = temp_f1 - temp_f0; + if (distance != 0.0f) { + if (distance > 0.5f) { + curr->x34.y += 0.5f; + } else if (distance < -0.5f) { + curr->x34.y -= 0.5f; + } else { + curr->x34.y = temp_f1; + } + } + + temp_f1 = curr->x48.z; + temp_f0 = curr->x34.z; + distance = temp_f1 - temp_f0; + if (distance != 0.0f) { + if (distance > 0.5f) { + curr->x34.z += 0.5f; + } else if (distance < -0.5f) { + curr->x34.z = temp_f0 - 0.5f; + } else { + curr->x34.z = temp_f1; + } + } + } + } +} /// #Camera_8002958C @@ -177,7 +298,33 @@ void Camera_80029BC4(CameraBounds* bounds, CameraMovement* movement) bounds->z_pos = cam_dist; } -/// #Camera_80029C88 +void Camera_80029C88(CameraMovement* movement, f32 arg_scale) +{ + /// @todo r3 and r4 need to be swapped in this function to get a match + /// + /// It sure feels like this function should be... + /// + /// lbVector_Lerp(&movement->position, &movement->target_position, + /// &movement->position, scale); + /// + /// But that produces code pretty far from the target. + Vec3 dist; + f32 scale; + f32 camera_speed; + + dist.x = movement->target_position.x - movement->position.x; + dist.y = movement->target_position.y - movement->position.y; + dist.z = movement->target_position.z - movement->position.z; + + scale = cm_803BCCA0.x3C * arg_scale; + if (scale > 1.0f) { + scale = 1.0f; + } + + movement->position.x += dist.x * scale; + movement->position.y += dist.y * scale; + movement->position.z += dist.z * scale; +} /// #Camera_80029CF8 @@ -189,7 +336,40 @@ void Camera_8002A278(f32 x, f32 y) cm_80452C68.unk_A8 = y; } -/// #Camera_8002A28C +void Camera_8002A28C(void) +{ + /// @todo Mostly register allocation preventing a match here. + Camera* camera = &cm_80452C68; + struct UnkInternalCameraStruct* src; + struct UnkInternalCameraStruct* dst; + + s32 test; + s32 i; + s32 j; + + test = -1; + + for (i = 0; i < 2; ++i) { + src = camera->unk_B0[i]; + dst = camera->unk_1B0[i]; + for (j = 0; j < 8; ++j) { + dst[j] = src[j]; + src[j].xC = 0; + } + } + + for (i = 0; i < 5; ++i) { + if (camera->unk_8C[i] != 0) { + camera->unk_8C[i] -= 1; + test = i; + } + } + + if ((test != -1) && (camera->unk_A0 != NULL) && (camera->unk_8C[1] == 0)) { + HSD_GObjPLink_80390228(camera->unk_A0); + camera->unk_A0 = 0; + } +} /// #Camera_8002A4AC @@ -513,7 +693,7 @@ void Camera_8002B1F8(CameraMovement* movement) (temp_r3_2 = Player_GetEntity(1), ((temp_r3_2 == NULL) == 0)) && (var_r29 = ftLib_80086B74(temp_r3_2), ((var_r29 == NULL) == 0)) && (Camera_8002928C(var_r29) != 0) && - (Camera_80029124(&var_r29->x1C, 0) == NULL)))) + (Camera_80029124(&var_r29->x1C, 0) == 0)))) { lbVector_Diff(&movement->target_interest, &var_r29->x1C, &vec); temp_f1 = *temp_r31; @@ -766,11 +946,27 @@ enum_t Camera_8003108C(void) return cm_80452C68.unk_399_b0_b1; } -/// #Camera_800310A0 +void Camera_800310A0(u8 arg0) +{ + cm_80452C68.unk_399_b0_b1 = arg0; +} -/// #Camera_800310B8 +HSD_CObj* Camera_800310B8(void) +{ + HSD_CObjSetMtxDirty(cm_804D6464); + HSD_CObjSetupViewingMtx(cm_804D6464); + return cm_804D6464; +} -/// #Camera_800310E8 +void Camera_800310E8(void) +{ + cm_80452C68.unk_398_b0 = 0; + cm_80452C68.unk_398_b1 = 0; + cm_80452C68.unk_398_b2 = 0; + cm_80452C68.unk_398_b3 = 0; + cm_80452C68.unk_398_b4 = 0; + cm_80452C68.unk_398_b5 = 0; +} f32 Camera_80031144(void) { @@ -779,7 +975,7 @@ f32 Camera_80031144(void) bool Camera_80031154(Vec3* arg0) { - if (Camera_80029124(arg0, 0) == NULL) { + if (Camera_80029124(arg0, 0) == 0) { return true; } return false; @@ -787,7 +983,7 @@ bool Camera_80031154(Vec3* arg0) bool Camera_8003118C(Vec3* arg0, float arg1) { - if (Camera_80029124(arg0, arg1) == NULL) { + if (Camera_80029124(arg0, arg1) == 0) { return true; } return false; diff --git a/src/melee/cm/camera.h b/src/melee/cm/camera.h index 5d3ee79154..91898d48ec 100644 --- a/src/melee/cm/camera.h +++ b/src/melee/cm/camera.h @@ -18,14 +18,14 @@ /* 029020 */ CameraBox* Camera_80029020(void); /* 029044 */ CameraBox* Camera_80029044(int); /* 0290D4 */ void Camera_800290D4(CameraBox*); -/* 029124 */ UNK_T Camera_80029124(Vec3*, int); +/* 029124 */ u32 Camera_80029124(Vec3*, s32); /* 02928C */ s32 Camera_8002928C(CameraBox*); /* 0293E0 */ UNK_RET Camera_800293E0(UNK_PARAMS); /* 02958C */ UNK_RET Camera_8002958C(UNK_PARAMS); /* 029AAC */ void Camera_80028F5C(CameraBox*, s32); /* 029BC4 */ void Camera_80029BC4(CameraBounds* bounds, CameraMovement* movement); -/* 029C88 */ UNK_RET Camera_80029C88(UNK_PARAMS); +/* 029C88 */ void Camera_80029C88(CameraMovement* movement, f32); /* 029CF8 */ UNK_RET Camera_80029CF8(UNK_PARAMS); /* 02A0C0 */ UNK_RET Camera_8002A0C0(UNK_PARAMS); /* 02A278 */ void Camera_8002A278(float x, float y); diff --git a/src/melee/cm/types.h b/src/melee/cm/types.h index 6eb6d2ea03..b2af33de9c 100644 --- a/src/melee/cm/types.h +++ b/src/melee/cm/types.h @@ -26,12 +26,12 @@ struct CameraBox { }; struct CameraMovement { - Vec3 interest; - Vec3 target_interest; - Vec3 position; - Vec3 target_position; - float fov; - float target_fov; + /* +0 */ Vec3 interest; + /* +C */ Vec3 target_interest; + /* +18 */ Vec3 position; + /* +24 */ Vec3 target_position; + /* +30 */ float fov; + /* +34 */ float target_fov; }; struct CameraBounds { @@ -43,6 +43,13 @@ struct CameraBounds { float z_pos; }; +struct UnkInternalCameraStruct { + /* 0x0 */ s32 x0; + /* 0x4 */ s32 x4; + /* 0x8 */ s32 x8; + /* 0xC */ s32 xC; +}; + typedef struct Camera { /* 0x000 */ HSD_GObj* gobj; /* 0x004 */ u32 mode; @@ -55,11 +62,14 @@ typedef struct Camera { /* 0x014 */ CameraMovement movement; /* 0x04C */ CameraMovement movement_lerp; /* 0x084 */ Vec2 translation; - /* 0x08C */ char pad_8C[0x18]; /* maybe part of translation[4]? */ + /* 0x08C */ s32 unk_8C[5]; /* maybe part of translation[4]? */ + /* 0x0A0 */ HSD_GObj* unk_A0; /* 0x0A4 */ f32 unk_A4; /* 0x0A8 */ f32 unk_A8; - /* 0x0AC */ f32 unk_AC; /* inferred */ - /* 0x0B0 */ char pad_B0[0x20C]; /* maybe part of unk_AC[0x84]? */ + /* 0x0AC */ f32 unk_AC; /* inferred */ + /* 0x0B0 */ struct UnkInternalCameraStruct unk_B0[2][8]; + /* 0x1B0 */ struct UnkInternalCameraStruct unk_1B0[2][8]; + /* 0x2B0 */ u8 pad_2B0[0x2BC - 0x2B0]; /* 0x2BC */ f32 unk_2bc; /* 0x2C0 */ f32 unk_2c0; /* 0x2C4 */ char pad_2C4[0x7D]; /* maybe part of unk_2c0[0x20]? */