Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Decompile some camera functions #1484

Merged
merged 12 commits into from
Oct 22, 2024
216 changes: 206 additions & 10 deletions src/melee/cm/camera.c
Original file line number Diff line number Diff line change
@@ -1,17 +1,23 @@
#include <placeholder.h>

#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"

#include <math.h>
#include <math_ppc.h>
#include <trigf.h>
#include <baselib/gobjplink.h>

static HSD_CObj* cm_804D6464;

/// #Camera_80028B9C

Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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

Expand All @@ -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

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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)
{
Expand All @@ -779,15 +975,15 @@ 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;
}

bool Camera_8003118C(Vec3* arg0, float arg1)
{
if (Camera_80029124(arg0, arg1) == NULL) {
if (Camera_80029124(arg0, arg1) == 0) {
return true;
}
return false;
Expand Down
4 changes: 2 additions & 2 deletions src/melee/cm/camera.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
28 changes: 19 additions & 9 deletions src/melee/cm/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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;
Expand All @@ -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]? */
Expand Down
Loading