2021-06-09 01:14:31 -05:00
|
|
|
/* The comment below is needed for this file to be picked up by generate_ld */
|
|
|
|
|
/* RAM_POS: 0x80065EA0 */
|
|
|
|
|
|
2021-07-05 14:00:21 -05:00
|
|
|
#include "camera.h"
|
2021-09-13 14:23:49 -04:00
|
|
|
#include "audio.h"
|
2022-02-23 10:13:44 -05:00
|
|
|
#include "objects.h"
|
2022-02-13 11:38:43 -05:00
|
|
|
#include "game.h"
|
2021-09-14 15:50:58 -04:00
|
|
|
#include "unknown_0255E0.h"
|
2021-09-17 23:52:24 -04:00
|
|
|
#include "video.h"
|
2021-09-29 08:46:57 -04:00
|
|
|
#include "lib/src/libc/rmonPrintf.h"
|
2022-10-24 15:37:47 +01:00
|
|
|
#include "math_util.h"
|
2022-11-15 17:45:22 +00:00
|
|
|
#include "weather.h"
|
2021-06-09 01:14:31 -05:00
|
|
|
|
|
|
|
|
/************ .rodata ************/
|
|
|
|
|
|
2023-01-05 17:37:08 +00:00
|
|
|
UNUSED const char D_800E6F00[] = "Camera Error: Illegal mode!\n";
|
|
|
|
|
UNUSED const char D_800E6F20[] = "Camera Error: Illegal player no!\n";
|
|
|
|
|
UNUSED const char D_800E6F34[] = "cameraPushSprMtx: model stack overflow!!\n";
|
|
|
|
|
UNUSED const char D_800E6F70[] = "\nCam do 2D sprite called with NULL pointer!";
|
|
|
|
|
UNUSED const char D_800E6F9C[] = "CamDo2DSprite FrameNo Overflow !!!\n";
|
|
|
|
|
UNUSED const char D_800E6FC0[] = "cameraPushModelMtx: model stack overflow!!\n";
|
|
|
|
|
UNUSED const char D_800E6FEC[] = "camPushModelMtx: bsp stack overflow!!\n";
|
|
|
|
|
UNUSED const char D_800E7010[] = "camPopModelMtx: model stack negative overflow!!\n";
|
|
|
|
|
UNUSED const char D_800E7048[] = "camPopModelMtx: bsp stack negative overflow!!\n";
|
2021-06-09 01:14:31 -05:00
|
|
|
|
|
|
|
|
/*********************************/
|
|
|
|
|
|
|
|
|
|
/************ .data ************/
|
|
|
|
|
|
2022-10-24 15:37:47 +01:00
|
|
|
s8 gAntiPiracyViewport = FALSE;
|
2021-06-09 01:14:31 -05:00
|
|
|
|
2021-12-11 22:59:46 -05:00
|
|
|
// x1, y1, x2, y2
|
|
|
|
|
// posX, posY, width, height
|
|
|
|
|
// scissorX1, scissorY1, scissorX2, scissorY2
|
|
|
|
|
// flags
|
2021-07-05 14:00:21 -05:00
|
|
|
#define DEFAULT_VIEWPORT \
|
|
|
|
|
0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, \
|
|
|
|
|
SCREEN_WIDTH_HALF, SCREEN_HEIGHT_HALF, SCREEN_WIDTH, SCREEN_HEIGHT, \
|
|
|
|
|
0, 0, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1, \
|
|
|
|
|
0
|
2021-06-09 01:14:31 -05:00
|
|
|
|
2021-07-05 14:00:21 -05:00
|
|
|
ScreenViewport gScreenViewports[4] = {
|
|
|
|
|
{ DEFAULT_VIEWPORT },
|
|
|
|
|
{ DEFAULT_VIEWPORT },
|
|
|
|
|
{ DEFAULT_VIEWPORT },
|
|
|
|
|
{ DEFAULT_VIEWPORT },
|
2021-06-09 01:14:31 -05:00
|
|
|
};
|
|
|
|
|
|
2023-01-23 12:54:17 +00:00
|
|
|
u32 gViewportWithBG = FALSE;
|
2021-06-09 01:14:31 -05:00
|
|
|
|
2022-11-15 17:45:22 +00:00
|
|
|
Vertex D_800DD138 = {
|
|
|
|
|
0, 0, 0, 255, 255, 255, 255
|
2021-07-05 14:00:21 -05:00
|
|
|
};
|
|
|
|
|
|
2021-08-15 16:47:35 -05:00
|
|
|
// RSP Viewports
|
2023-01-23 12:54:17 +00:00
|
|
|
Vp gViewportStack[20] = {
|
2022-03-10 09:01:18 -05:00
|
|
|
{ { { 0, 0, 511, 0 }, { 0, 0, 511, 0 } } },
|
|
|
|
|
{ { { 0, 0, 511, 0 }, { 0, 0, 511, 0 } } },
|
|
|
|
|
{ { { 0, 0, 511, 0 }, { 0, 0, 511, 0 } } },
|
|
|
|
|
{ { { 0, 0, 511, 0 }, { 0, 0, 511, 0 } } },
|
|
|
|
|
{ { { 0, 0, 511, 0 }, { 0, 0, 511, 0 } } },
|
|
|
|
|
{ { { 0, 0, 511, 0 }, { 0, 0, 511, 0 } } },
|
|
|
|
|
{ { { 0, 0, 511, 0 }, { 0, 0, 511, 0 } } },
|
|
|
|
|
{ { { 0, 0, 511, 0 }, { 0, 0, 511, 0 } } },
|
|
|
|
|
{ { { 0, 0, 511, 0 }, { 0, 0, 511, 0 } } },
|
|
|
|
|
{ { { 0, 0, 511, 0 }, { 0, 0, 511, 0 } } },
|
|
|
|
|
{ { { 0, 0, 511, 0 }, { 0, 0, 511, 0 } } },
|
|
|
|
|
{ { { 0, 0, 511, 0 }, { 0, 0, 511, 0 } } },
|
|
|
|
|
{ { { 0, 0, 511, 0 }, { 0, 0, 511, 0 } } },
|
|
|
|
|
{ { { 0, 0, 511, 0 }, { 0, 0, 511, 0 } } },
|
|
|
|
|
{ { { 0, 0, 511, 0 }, { 0, 0, 511, 0 } } },
|
|
|
|
|
{ { { 0, 0, 511, 0 }, { 0, 0, 511, 0 } } },
|
|
|
|
|
{ { { 0, 0, 511, 0 }, { 0, 0, 511, 0 } } },
|
|
|
|
|
{ { { 0, 0, 511, 0 }, { 0, 0, 511, 0 } } },
|
|
|
|
|
{ { { 0, 0, 511, 0 }, { 0, 0, 511, 0 } } },
|
|
|
|
|
{ { { 0, 0, 511, 0 }, { 0, 0, 511, 0 } } },
|
2021-06-09 01:14:31 -05:00
|
|
|
};
|
|
|
|
|
|
2022-03-10 09:01:18 -05:00
|
|
|
ObjectTransform D_800DD288 = {
|
2021-09-17 09:34:22 -04:00
|
|
|
0, 0, 0, 0, 1.0f, 0.0f, 0.0f, -281.0f,
|
2021-06-09 01:14:31 -05:00
|
|
|
};
|
|
|
|
|
|
2022-03-10 09:01:18 -05:00
|
|
|
ObjectTransform D_800DD2A0 = {
|
2021-09-17 09:34:22 -04:00
|
|
|
0, 0, 0, 0, 1.0f, 0.0f, 0.0f, 0.0f,
|
2021-06-09 01:14:31 -05:00
|
|
|
};
|
|
|
|
|
|
2021-12-09 21:48:51 +00:00
|
|
|
Matrix gOrthoMatrix = {
|
2021-09-09 09:18:51 -04:00
|
|
|
{ 1.0f, 0.0f, 0.0f, 0.0f },
|
|
|
|
|
{ 0.0f, 1.0f, 0.0f, 0.0f },
|
|
|
|
|
{ 0.0f, 0.0f, 0.0f, 0.0f },
|
|
|
|
|
{ 0.0f, 0.0f, 0.0f, 160.0f },
|
2021-06-09 01:14:31 -05:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
u8 D_800DD2F8[8] = {
|
|
|
|
|
0, 0, 0, 0, 0, 0, 0, 0
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/*******************************/
|
|
|
|
|
|
|
|
|
|
/************ .bss ************/
|
|
|
|
|
|
2022-11-20 23:37:50 +00:00
|
|
|
ObjectSegment gActiveCameraStack[8];
|
2021-07-22 02:23:31 -05:00
|
|
|
s32 gNumberOfViewports;
|
2022-11-20 23:37:50 +00:00
|
|
|
s32 gActiveCameraID;
|
2023-01-06 19:39:37 +00:00
|
|
|
s32 gViewportCap;
|
2023-01-05 17:37:08 +00:00
|
|
|
UNUSED s32 D_80120CEC;
|
2023-01-23 12:54:17 +00:00
|
|
|
ObjectTransform gCameraTransform;
|
2021-06-09 01:14:31 -05:00
|
|
|
s32 D_80120D08;
|
|
|
|
|
s32 D_80120D0C;
|
2021-07-05 14:00:21 -05:00
|
|
|
f32 gCurCamFOV;
|
2022-10-24 15:37:47 +01:00
|
|
|
s8 gCutsceneCameraActive;
|
|
|
|
|
s8 gAdjustViewportHeight;
|
2021-06-09 01:14:31 -05:00
|
|
|
s32 D_80120D18;
|
|
|
|
|
s32 D_80120D1C;
|
2022-09-20 09:42:30 -04:00
|
|
|
s32 D_80120D20;
|
2022-10-24 15:37:47 +01:00
|
|
|
UNUSED s32 D_80120D24;
|
2022-09-20 09:42:30 -04:00
|
|
|
f32 D_80120D28[6];
|
|
|
|
|
f32 D_80120D40[6];
|
|
|
|
|
f32 D_80120D58[5];
|
|
|
|
|
u16 perspNorm;
|
2022-03-10 09:01:18 -05:00
|
|
|
Matrix *D_80120D70[6];
|
2022-12-10 22:42:50 +00:00
|
|
|
MatrixS *D_80120D88[6];
|
2022-03-10 09:01:18 -05:00
|
|
|
Matrix D_80120DA0[5];
|
2023-01-05 17:37:08 +00:00
|
|
|
Matrix gPerspectiveMatrixF;
|
2021-09-09 09:18:51 -04:00
|
|
|
Matrix D_80120F20;
|
|
|
|
|
Matrix D_80120F60;
|
2021-09-09 12:27:33 -04:00
|
|
|
Matrix D_80120FA0;
|
2023-01-05 17:37:08 +00:00
|
|
|
MatrixS gPerspectiveMatrixS;
|
2022-12-10 22:42:50 +00:00
|
|
|
MatrixS D_80121020;
|
2021-09-09 09:18:51 -04:00
|
|
|
Matrix D_80121060;
|
2021-09-09 12:27:33 -04:00
|
|
|
Matrix D_801210A0;
|
2021-06-09 01:14:31 -05:00
|
|
|
|
|
|
|
|
/******************************/
|
|
|
|
|
|
2021-12-15 14:58:05 -05:00
|
|
|
#ifdef NON_EQUIVALENT
|
2021-07-05 14:00:21 -05:00
|
|
|
extern s32 D_B0000578;
|
|
|
|
|
|
|
|
|
|
void func_80065EA0(void) {
|
|
|
|
|
s32 i, j;
|
2021-10-28 10:18:37 -04:00
|
|
|
for (i = 0; i < 5; i++) {
|
2021-07-05 14:00:21 -05:00
|
|
|
D_80120D70[i] = &D_80120DA0[i];
|
|
|
|
|
};
|
2021-10-28 10:18:37 -04:00
|
|
|
for (j = 0; j < 8; j++) {
|
2022-11-20 23:37:50 +00:00
|
|
|
gActiveCameraID = j;
|
2021-07-05 14:00:21 -05:00
|
|
|
func_800663DC(200, 200, 200, 0, 0, 180);
|
|
|
|
|
};
|
2022-10-24 15:37:47 +01:00
|
|
|
gCutsceneCameraActive = FALSE;
|
2022-11-20 23:37:50 +00:00
|
|
|
gActiveCameraID = 0;
|
2021-07-05 14:00:21 -05:00
|
|
|
D_80120D1C = 0;
|
2022-09-20 09:42:30 -04:00
|
|
|
D_80120D20 = 0;
|
2021-07-22 02:23:31 -05:00
|
|
|
gNumberOfViewports = 0;
|
2021-07-05 14:00:21 -05:00
|
|
|
D_80120D0C = 0;
|
|
|
|
|
D_80120D18 = 0;
|
2022-10-24 15:37:47 +01:00
|
|
|
gAdjustViewportHeight = 0;
|
|
|
|
|
gAntiPiracyViewport = 0;
|
2021-12-11 22:59:46 -05:00
|
|
|
while (IO_READ(PI_STATUS_REG) & PI_STATUS_ERROR) {
|
2021-07-05 14:00:21 -05:00
|
|
|
}
|
|
|
|
|
if ((D_B0000578 & 0xFFFF) != 0x8965) {
|
2022-10-24 15:37:47 +01:00
|
|
|
gAntiPiracyViewport = TRUE;
|
2021-07-05 14:00:21 -05:00
|
|
|
}
|
2023-01-05 17:37:08 +00:00
|
|
|
guPerspectiveF(gPerspectiveMatrixF, &perspNorm, CAMERA_DEFAULT_FOV, CAMERA_ASPECT, CAMERA_NEAR, CAMERA_FAR, CAMERA_SCALE);
|
|
|
|
|
f32_matrix_to_s16_matrix(gPerspectiveMatrixF, gPerspectiveMatrixS);
|
2021-07-05 14:00:21 -05:00
|
|
|
gCurCamFOV = CAMERA_DEFAULT_FOV;
|
|
|
|
|
}
|
|
|
|
|
#else
|
|
|
|
|
GLOBAL_ASM("asm/non_matchings/camera/func_80065EA0.s")
|
|
|
|
|
#endif
|
2021-06-09 01:14:31 -05:00
|
|
|
|
|
|
|
|
void func_80066060(s32 arg0, s32 arg1) {
|
|
|
|
|
if (arg0 >= 0 && arg0 < 4) {
|
|
|
|
|
D_800DD2F8[arg0] = arg1;
|
2022-12-22 13:55:08 +00:00
|
|
|
gActiveCameraStack[arg0].unk38.byte.unk3B = arg1;
|
2021-06-09 01:14:31 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-10-24 15:37:47 +01:00
|
|
|
/**
|
|
|
|
|
* Set gAdjustViewportHeight to PAL mode if necessary, if setting is 1.
|
|
|
|
|
* Otherwise, set it to 0, regardless of TV type.
|
|
|
|
|
*/
|
|
|
|
|
void set_viewport_tv_type(s8 setting) {
|
|
|
|
|
if (osTvType == TV_TYPE_PAL) {
|
|
|
|
|
gAdjustViewportHeight = setting;
|
2021-06-09 01:14:31 -05:00
|
|
|
}
|
|
|
|
|
}
|
2022-10-24 15:37:47 +01:00
|
|
|
|
2021-06-09 01:14:31 -05:00
|
|
|
void func_800660C0(void) {
|
|
|
|
|
D_80120D18 = 1;
|
|
|
|
|
}
|
2022-10-24 15:37:47 +01:00
|
|
|
|
2021-06-09 01:14:31 -05:00
|
|
|
void func_800660D0(void) {
|
|
|
|
|
D_80120D18 = 0;
|
|
|
|
|
}
|
2021-12-10 19:03:19 +00:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Unused function that will return the current camera's FoV.
|
|
|
|
|
*/
|
|
|
|
|
UNUSED f32 get_current_camera_fov(void) {
|
2021-07-05 14:00:21 -05:00
|
|
|
return gCurCamFOV;
|
2021-06-09 01:14:31 -05:00
|
|
|
}
|
|
|
|
|
|
2021-12-10 19:03:19 +00:00
|
|
|
/**
|
|
|
|
|
* Set the FoV of the viewspace, then recalculate the perspective matrix.
|
|
|
|
|
*/
|
2021-07-05 14:00:21 -05:00
|
|
|
void update_camera_fov(f32 camFieldOfView) {
|
|
|
|
|
if (CAMERA_MIN_FOV < camFieldOfView && camFieldOfView < CAMERA_MAX_FOV && camFieldOfView != gCurCamFOV) {
|
|
|
|
|
gCurCamFOV = camFieldOfView;
|
2023-01-05 17:37:08 +00:00
|
|
|
guPerspectiveF(gPerspectiveMatrixF, &perspNorm, camFieldOfView, CAMERA_ASPECT, CAMERA_NEAR, CAMERA_FAR, CAMERA_SCALE);
|
|
|
|
|
f32_matrix_to_s16_matrix(&gPerspectiveMatrixF, &gPerspectiveMatrixS);
|
2021-06-09 01:14:31 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-12-10 19:03:19 +00:00
|
|
|
/**
|
|
|
|
|
* Unused function that recalculates the perspective matrix.
|
|
|
|
|
*/
|
|
|
|
|
UNUSED void calculate_camera_perspective(void) {
|
2023-01-05 17:37:08 +00:00
|
|
|
guPerspectiveF(gPerspectiveMatrixF, &perspNorm, CAMERA_DEFAULT_FOV, CAMERA_ASPECT, CAMERA_NEAR, CAMERA_FAR, CAMERA_SCALE);
|
|
|
|
|
f32_matrix_to_s16_matrix(&gPerspectiveMatrixF, &gPerspectiveMatrixS);
|
2021-06-09 01:14:31 -05:00
|
|
|
}
|
|
|
|
|
|
2022-09-20 09:42:30 -04:00
|
|
|
UNUSED Matrix *func_80066204(void) {
|
2021-09-09 12:27:33 -04:00
|
|
|
return &D_801210A0;
|
2021-06-09 01:14:31 -05:00
|
|
|
}
|
|
|
|
|
|
2023-01-06 19:39:37 +00:00
|
|
|
/**
|
|
|
|
|
* Returns the number of active viewports.
|
|
|
|
|
*/
|
2021-07-22 02:23:31 -05:00
|
|
|
s32 get_viewport_count(void) {
|
|
|
|
|
return gNumberOfViewports;
|
2021-06-09 01:14:31 -05:00
|
|
|
}
|
|
|
|
|
|
2022-12-04 18:43:29 +00:00
|
|
|
/**
|
|
|
|
|
* Return the index of the active view.
|
|
|
|
|
* 0-3 is players 1-4, and 4-7 is the same, but with 4 added on for cutscenes.
|
|
|
|
|
*/
|
|
|
|
|
s32 get_current_viewport(void) {
|
2022-11-20 23:37:50 +00:00
|
|
|
return gActiveCameraID;
|
2021-06-09 01:14:31 -05:00
|
|
|
}
|
|
|
|
|
|
2022-12-10 22:42:50 +00:00
|
|
|
void func_80066230(Gfx **dlist, MatrixS **mats) {
|
2023-01-23 12:54:17 +00:00
|
|
|
ObjectSegment *cam;
|
|
|
|
|
s16 angleY;
|
|
|
|
|
s16 angleX;
|
|
|
|
|
s16 angleZ;
|
2021-06-09 01:14:31 -05:00
|
|
|
s16 sp24;
|
2023-01-23 12:54:17 +00:00
|
|
|
f32 posX;
|
|
|
|
|
f32 posY;
|
|
|
|
|
f32 posZ;
|
2021-06-09 01:14:31 -05:00
|
|
|
|
2023-01-06 19:39:37 +00:00
|
|
|
set_active_viewports_and_max(0);
|
|
|
|
|
set_active_camera(0);
|
2023-01-23 12:54:17 +00:00
|
|
|
cam = get_active_camera_segment();
|
|
|
|
|
angleY = cam->trans.y_rotation;
|
|
|
|
|
angleX = cam->trans.x_rotation;
|
|
|
|
|
angleZ = cam->trans.z_rotation;
|
|
|
|
|
posX = cam->trans.x_position;
|
|
|
|
|
posY = cam->trans.y_position;
|
|
|
|
|
posZ = cam->trans.z_position;
|
|
|
|
|
sp24 = cam->unk38.half.unk38;
|
|
|
|
|
cam->trans.z_rotation = 0;
|
|
|
|
|
cam->trans.x_rotation = 0;
|
|
|
|
|
cam->trans.y_rotation = -0x8000;
|
|
|
|
|
cam->unk38.half.unk38 = 0;
|
|
|
|
|
cam->trans.x_position = 0.0f;
|
|
|
|
|
cam->trans.y_position = 0.0f;
|
|
|
|
|
cam->trans.z_position = 0.0f;
|
2023-01-06 19:39:37 +00:00
|
|
|
update_envmap_position(0.0f, 0.0f, -1.0f);
|
2022-03-28 08:36:12 -04:00
|
|
|
func_80066CDC(dlist, mats);
|
2023-01-23 12:54:17 +00:00
|
|
|
cam->unk38.half.unk38 = sp24;
|
|
|
|
|
cam->trans.y_rotation = angleY;
|
|
|
|
|
cam->trans.x_rotation = angleX;
|
|
|
|
|
cam->trans.z_rotation = angleZ;
|
|
|
|
|
cam->trans.x_position = posX;
|
|
|
|
|
cam->trans.y_position = posY;
|
|
|
|
|
cam->trans.z_position = posZ;
|
2021-06-09 01:14:31 -05:00
|
|
|
}
|
|
|
|
|
|
2022-11-20 23:37:50 +00:00
|
|
|
/**
|
|
|
|
|
* Compare the coordinates passed through to the active camera and return the distance between them.
|
|
|
|
|
*/
|
|
|
|
|
f32 get_distance_to_active_camera(f32 xPos, f32 yPos, f32 zPos) {
|
2022-03-28 08:36:12 -04:00
|
|
|
s32 index;
|
|
|
|
|
f32 dx, dz, dy;
|
2021-06-09 01:14:31 -05:00
|
|
|
|
2022-11-20 23:37:50 +00:00
|
|
|
index = gActiveCameraID;
|
2021-10-28 10:18:37 -04:00
|
|
|
|
2022-10-24 15:37:47 +01:00
|
|
|
if (gCutsceneCameraActive) {
|
2022-03-28 08:36:12 -04:00
|
|
|
index += 4;
|
2021-06-09 01:14:31 -05:00
|
|
|
}
|
2021-10-28 10:18:37 -04:00
|
|
|
|
2022-11-20 23:37:50 +00:00
|
|
|
dz = zPos - gActiveCameraStack[index].trans.z_position;
|
|
|
|
|
dx = xPos - gActiveCameraStack[index].trans.x_position;
|
|
|
|
|
dy = yPos - gActiveCameraStack[index].trans.y_position;
|
2022-03-28 08:36:12 -04:00
|
|
|
return sqrtf((dz * dz) + ((dx * dx) + (dy * dy)));
|
2021-06-09 01:14:31 -05:00
|
|
|
}
|
|
|
|
|
|
2021-09-10 08:00:35 -04:00
|
|
|
void func_800663DC(s32 xPos, s32 yPos, s32 zPos, s32 arg3, s32 arg4, s32 arg5) {
|
2022-11-20 23:37:50 +00:00
|
|
|
gActiveCameraStack[gActiveCameraID].trans.z_rotation = (s16) (arg3 * 0xB6);
|
|
|
|
|
gActiveCameraStack[gActiveCameraID].trans.x_position = (f32) xPos;
|
|
|
|
|
gActiveCameraStack[gActiveCameraID].trans.y_position = (f32) yPos;
|
|
|
|
|
gActiveCameraStack[gActiveCameraID].trans.z_position = (f32) zPos;
|
|
|
|
|
gActiveCameraStack[gActiveCameraID].trans.x_rotation = (s16) (arg4 * 0xB6);
|
2022-12-22 13:55:08 +00:00
|
|
|
gActiveCameraStack[gActiveCameraID].unk38.half.unk38 = (s16) 0;
|
2022-11-20 23:37:50 +00:00
|
|
|
gActiveCameraStack[gActiveCameraID].z_velocity = 0.0f;
|
|
|
|
|
gActiveCameraStack[gActiveCameraID].unk28 = 0.0f;
|
|
|
|
|
gActiveCameraStack[gActiveCameraID].unk2C.word = 0.0f;
|
|
|
|
|
gActiveCameraStack[gActiveCameraID].unk30 = 0.0f;
|
|
|
|
|
gActiveCameraStack[gActiveCameraID].x_velocity = 160.0f;
|
|
|
|
|
gActiveCameraStack[gActiveCameraID].trans.y_rotation = (s16) (arg5 * 0xB6);
|
2022-12-22 13:55:08 +00:00
|
|
|
gActiveCameraStack[gActiveCameraID].unk38.byte.unk3B = D_800DD2F8[gActiveCameraID];
|
2021-06-09 01:14:31 -05:00
|
|
|
}
|
|
|
|
|
|
2022-10-24 15:37:47 +01:00
|
|
|
/**
|
|
|
|
|
* Write directly to the second set of object stack indeces.
|
|
|
|
|
* The first 4 are reserved for the 4 player viewports, so the misc views, used in the title screen
|
|
|
|
|
* and course previews instead use the next 4.
|
|
|
|
|
*/
|
|
|
|
|
void write_to_object_render_stack(s32 stackPos, f32 xPos, f32 yPos, f32 zPos, s16 arg4, s16 arg5, s16 arg6) {
|
|
|
|
|
stackPos += 4;
|
2022-12-22 13:55:08 +00:00
|
|
|
gActiveCameraStack[stackPos].unk38.half.unk38 = 0;
|
2022-11-20 23:37:50 +00:00
|
|
|
gActiveCameraStack[stackPos].trans.x_position = xPos;
|
|
|
|
|
gActiveCameraStack[stackPos].trans.y_position = yPos;
|
|
|
|
|
gActiveCameraStack[stackPos].trans.z_position = zPos;
|
|
|
|
|
gActiveCameraStack[stackPos].trans.y_rotation = arg4;
|
|
|
|
|
gActiveCameraStack[stackPos].trans.x_rotation = arg5;
|
|
|
|
|
gActiveCameraStack[stackPos].trans.z_rotation = arg6;
|
|
|
|
|
gActiveCameraStack[stackPos].unk34_a.levelSegmentIndex = get_level_segment_index_from_position(xPos, yPos, zPos);
|
2022-10-24 15:37:47 +01:00
|
|
|
gCutsceneCameraActive = TRUE;
|
2021-06-09 01:14:31 -05:00
|
|
|
}
|
|
|
|
|
|
2022-10-24 15:37:47 +01:00
|
|
|
/**
|
|
|
|
|
* Check if the misc camera view is active.
|
|
|
|
|
*/
|
|
|
|
|
s8 check_if_showing_cutscene_camera(void) {
|
|
|
|
|
return gCutsceneCameraActive;
|
2021-06-09 01:14:31 -05:00
|
|
|
}
|
|
|
|
|
|
2022-10-24 15:37:47 +01:00
|
|
|
/**
|
|
|
|
|
* Disable the cutscene camera, returning it to the conventional mode.
|
|
|
|
|
*/
|
|
|
|
|
void disable_cutscene_camera(void) {
|
|
|
|
|
gCutsceneCameraActive = FALSE;
|
2021-06-09 01:14:31 -05:00
|
|
|
}
|
|
|
|
|
|
2022-10-24 15:37:47 +01:00
|
|
|
/**
|
2023-01-06 19:39:37 +00:00
|
|
|
* Sets the cap for the viewports. Usually reflecting how many there are.
|
2022-10-24 15:37:47 +01:00
|
|
|
* If the number passed is within 1-4, then the stack cap is set to
|
|
|
|
|
* how many active viewports there are.
|
|
|
|
|
*/
|
2023-01-06 19:39:37 +00:00
|
|
|
s32 set_active_viewports_and_max(s32 num) {
|
2022-10-24 15:37:47 +01:00
|
|
|
if (num >= 0 && num < 4) {
|
|
|
|
|
gNumberOfViewports = num;
|
2021-06-09 01:14:31 -05:00
|
|
|
} else {
|
2021-07-22 02:23:31 -05:00
|
|
|
gNumberOfViewports = 0;
|
2021-06-09 01:14:31 -05:00
|
|
|
}
|
2021-10-28 10:18:37 -04:00
|
|
|
switch (gNumberOfViewports) {
|
2021-07-22 02:23:31 -05:00
|
|
|
case VIEWPORTS_COUNT_1_PLAYER:
|
2023-01-06 19:39:37 +00:00
|
|
|
gViewportCap = 1;
|
2021-06-09 01:14:31 -05:00
|
|
|
break;
|
2021-07-22 02:23:31 -05:00
|
|
|
case VIEWPORTS_COUNT_2_PLAYERS:
|
2023-01-06 19:39:37 +00:00
|
|
|
gViewportCap = 2;
|
2021-06-09 01:14:31 -05:00
|
|
|
break;
|
2021-07-22 02:23:31 -05:00
|
|
|
case VIEWPORTS_COUNT_3_PLAYERS:
|
2023-01-06 19:39:37 +00:00
|
|
|
gViewportCap = 3;
|
2021-06-09 01:14:31 -05:00
|
|
|
break;
|
2021-07-22 02:23:31 -05:00
|
|
|
case VIEWPORTS_COUNT_4_PLAYERS:
|
2023-01-06 19:39:37 +00:00
|
|
|
gViewportCap = 4;
|
2021-06-09 01:14:31 -05:00
|
|
|
break;
|
|
|
|
|
}
|
2023-01-06 19:39:37 +00:00
|
|
|
if (gActiveCameraID >= gViewportCap) {
|
2022-11-20 23:37:50 +00:00
|
|
|
gActiveCameraID = 0;
|
2021-06-09 01:14:31 -05:00
|
|
|
}
|
2023-01-06 19:39:37 +00:00
|
|
|
return gViewportCap;
|
2021-06-09 01:14:31 -05:00
|
|
|
}
|
|
|
|
|
|
2022-10-24 15:37:47 +01:00
|
|
|
/**
|
2023-01-06 19:39:37 +00:00
|
|
|
* Sets the active viewport ID to the passed number.
|
2022-10-24 15:37:47 +01:00
|
|
|
* If it's not within 1-4, then it's set to 0.
|
|
|
|
|
*/
|
2023-01-06 19:39:37 +00:00
|
|
|
void set_active_camera(s32 num) {
|
2022-10-24 15:37:47 +01:00
|
|
|
if (num >= 0 && num < 4) {
|
2022-11-20 23:37:50 +00:00
|
|
|
gActiveCameraID = num;
|
2021-06-09 01:14:31 -05:00
|
|
|
} else {
|
2022-11-20 23:37:50 +00:00
|
|
|
gActiveCameraID = 0;
|
2021-06-09 01:14:31 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-01-23 12:54:17 +00:00
|
|
|
/**
|
|
|
|
|
* Takes the size of each view frame and writes them to the viewport stack, using values compatable with the RSP.
|
|
|
|
|
* Only does this if extended backgrounds are enabled.
|
|
|
|
|
*/
|
|
|
|
|
void copy_viewports_to_stack(void) {
|
2021-12-10 19:03:19 +00:00
|
|
|
s32 width;
|
|
|
|
|
s32 height;
|
2023-01-23 12:54:17 +00:00
|
|
|
s32 port;
|
2021-12-10 19:03:19 +00:00
|
|
|
s32 yPos;
|
|
|
|
|
s32 xPos;
|
2021-07-05 14:00:21 -05:00
|
|
|
s32 i;
|
|
|
|
|
|
2023-01-23 12:54:17 +00:00
|
|
|
gViewportWithBG = 1 - gViewportWithBG;
|
2021-10-28 10:18:37 -04:00
|
|
|
for (i = 0; i < 4; i++) {
|
2021-12-10 19:03:19 +00:00
|
|
|
if (gScreenViewports[i].flags & VIEWPORT_UNK_04) {
|
2023-01-07 14:40:25 +00:00
|
|
|
gScreenViewports[i].flags &= ~VIEWPORT_EXTRA_BG;
|
2021-12-10 19:03:19 +00:00
|
|
|
} else if (gScreenViewports[i].flags & VIEWPORT_UNK_02) {
|
2023-01-07 14:40:25 +00:00
|
|
|
gScreenViewports[i].flags |= VIEWPORT_EXTRA_BG;
|
2021-07-05 14:00:21 -05:00
|
|
|
}
|
2023-01-23 12:54:17 +00:00
|
|
|
gScreenViewports[i].flags &= ~(VIEWPORT_UNK_02 | VIEWPORT_UNK_04);
|
|
|
|
|
if (gScreenViewports[i].flags & VIEWPORT_EXTRA_BG) {
|
2021-12-10 19:03:19 +00:00
|
|
|
if (!(gScreenViewports[i].flags & VIEWPORT_X_CUSTOM)) {
|
2023-01-23 12:54:17 +00:00
|
|
|
xPos = (((gScreenViewports[i].x2 - gScreenViewports[i].x1) + 1) << 1) + (gScreenViewports[i].x1 * 4);
|
2021-07-05 14:00:21 -05:00
|
|
|
} else {
|
2021-12-10 19:03:19 +00:00
|
|
|
xPos = gScreenViewports[i].posX;
|
|
|
|
|
xPos *= 4;
|
2021-07-05 14:00:21 -05:00
|
|
|
}
|
2021-12-10 19:03:19 +00:00
|
|
|
if (!(gScreenViewports[i].flags & VIEWPORT_Y_CUSTOM)) {
|
2023-01-23 12:54:17 +00:00
|
|
|
yPos = (((gScreenViewports[i].y2 - gScreenViewports[i].y1 + 1)) << 1) + (gScreenViewports[i].y1 * 4);
|
2021-07-05 14:00:21 -05:00
|
|
|
} else {
|
2021-12-10 19:03:19 +00:00
|
|
|
yPos = gScreenViewports[i].posY;
|
|
|
|
|
yPos *= 4;
|
2021-07-05 14:00:21 -05:00
|
|
|
}
|
2021-12-10 19:03:19 +00:00
|
|
|
if (!(gScreenViewports[i].flags & VIEWPORT_WIDTH_CUSTOM)) {
|
|
|
|
|
width = gScreenViewports[i].x2 - gScreenViewports[i].x1;
|
|
|
|
|
width += 1;
|
|
|
|
|
width *= 2;
|
2021-07-05 14:00:21 -05:00
|
|
|
} else {
|
2021-12-10 19:03:19 +00:00
|
|
|
width = gScreenViewports[i].width;
|
|
|
|
|
width *= 2;
|
2021-07-05 14:00:21 -05:00
|
|
|
}
|
2021-12-10 19:03:19 +00:00
|
|
|
if (!(gScreenViewports[i].flags & VIEWPORT_HEIGHT_CUSTOM)) {
|
2023-01-23 12:54:17 +00:00
|
|
|
height = (gScreenViewports[i].y2 - gScreenViewports[i].y1) + 1;
|
2021-12-10 19:03:19 +00:00
|
|
|
height *= 2;
|
2021-07-05 14:00:21 -05:00
|
|
|
} else {
|
2021-12-10 19:03:19 +00:00
|
|
|
height = gScreenViewports[i].height;
|
|
|
|
|
height *= 2;
|
2021-07-05 14:00:21 -05:00
|
|
|
}
|
2023-01-23 12:54:17 +00:00
|
|
|
port = i + (gViewportWithBG * 5);
|
|
|
|
|
port += 10;
|
2021-07-05 14:00:21 -05:00
|
|
|
if (get_filtered_cheats() & CHEAT_MIRRORED_TRACKS) {
|
2023-01-23 12:54:17 +00:00
|
|
|
if (0) { } // Fakematch
|
|
|
|
|
width = -width;
|
2021-07-05 14:00:21 -05:00
|
|
|
}
|
2023-01-23 12:54:17 +00:00
|
|
|
gViewportStack[port].vp.vtrans[0] = xPos;
|
|
|
|
|
gViewportStack[port].vp.vtrans[1] = yPos;
|
|
|
|
|
gViewportStack[port].vp.vscale[0] = width;
|
|
|
|
|
gViewportStack[port].vp.vscale[1] = height;
|
2021-07-05 14:00:21 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-06-09 01:14:31 -05:00
|
|
|
|
2023-01-28 20:25:21 -05:00
|
|
|
void camEnableUserView(s32 viewPortIndex, s32 arg1) {
|
2021-06-09 01:14:31 -05:00
|
|
|
if (arg1 != 0) {
|
2023-01-07 14:40:25 +00:00
|
|
|
gScreenViewports[viewPortIndex].flags |= VIEWPORT_EXTRA_BG;
|
2021-06-09 01:14:31 -05:00
|
|
|
} else {
|
2021-12-10 19:03:19 +00:00
|
|
|
gScreenViewports[viewPortIndex].flags |= VIEWPORT_UNK_02;
|
2021-06-09 01:14:31 -05:00
|
|
|
}
|
2021-12-10 19:03:19 +00:00
|
|
|
gScreenViewports[viewPortIndex].flags &= ~VIEWPORT_UNK_04;
|
2021-06-09 01:14:31 -05:00
|
|
|
}
|
|
|
|
|
|
2023-01-28 20:25:21 -05:00
|
|
|
void camDisableUserView(s32 viewPortIndex, s32 arg1) {
|
2021-06-09 01:14:31 -05:00
|
|
|
if (arg1 != 0) {
|
2023-01-07 14:40:25 +00:00
|
|
|
gScreenViewports[viewPortIndex].flags &= ~VIEWPORT_EXTRA_BG;
|
2021-06-09 01:14:31 -05:00
|
|
|
} else {
|
2021-12-10 19:03:19 +00:00
|
|
|
gScreenViewports[viewPortIndex].flags |= VIEWPORT_UNK_04;
|
2021-06-09 01:14:31 -05:00
|
|
|
}
|
2021-12-10 19:03:19 +00:00
|
|
|
gScreenViewports[viewPortIndex].flags &= ~VIEWPORT_UNK_02;
|
2021-06-09 01:14:31 -05:00
|
|
|
}
|
|
|
|
|
|
2023-01-07 14:40:25 +00:00
|
|
|
/**
|
|
|
|
|
* Return's the current viewport's flag status for extended backgrounds.
|
|
|
|
|
* Required to draw some extra things used in menus.
|
2023-01-31 12:02:37 -05:00
|
|
|
* Official name: camIsUserView
|
2023-01-07 14:40:25 +00:00
|
|
|
*/
|
|
|
|
|
s32 check_viewport_background_flag(s32 viewPortIndex) {
|
|
|
|
|
return gScreenViewports[viewPortIndex].flags & VIEWPORT_EXTRA_BG;
|
2021-06-09 01:14:31 -05:00
|
|
|
}
|
|
|
|
|
|
2023-01-23 12:54:17 +00:00
|
|
|
/**
|
|
|
|
|
* Sets the intended viewport to the size passed through by arguments.
|
|
|
|
|
*/
|
|
|
|
|
void resize_viewport(s32 viewPortIndex, s32 x1, s32 y1, s32 x2, s32 y2) {
|
2021-08-15 16:47:35 -05:00
|
|
|
s32 widthAndHeight, width, height;
|
2021-12-11 22:59:46 -05:00
|
|
|
s32 temp;
|
2021-10-28 10:18:37 -04:00
|
|
|
|
2021-08-15 16:47:35 -05:00
|
|
|
widthAndHeight = get_video_width_and_height_as_s32();
|
2021-12-11 22:59:46 -05:00
|
|
|
height = GET_VIDEO_HEIGHT(widthAndHeight) & 0xFFFF;
|
|
|
|
|
width = GET_VIDEO_WIDTH(widthAndHeight);
|
|
|
|
|
|
2021-12-10 19:03:19 +00:00
|
|
|
if (x2 < x1) {
|
2021-12-11 22:59:46 -05:00
|
|
|
temp = x1;
|
|
|
|
|
x1 = x2;
|
|
|
|
|
x2 = temp;
|
2021-08-15 16:47:35 -05:00
|
|
|
}
|
2021-12-10 19:03:19 +00:00
|
|
|
if (y2 < y1) {
|
2021-12-11 22:59:46 -05:00
|
|
|
temp = y1;
|
2021-12-10 19:03:19 +00:00
|
|
|
y1 = y2;
|
2021-12-11 22:59:46 -05:00
|
|
|
y2 = temp;
|
2021-08-15 16:47:35 -05:00
|
|
|
}
|
2021-12-11 22:59:46 -05:00
|
|
|
|
2023-01-23 12:54:17 +00:00
|
|
|
if (x1 >= width || x2 < 0 || y1 >= height || y2 < 0) {
|
2021-12-10 19:03:19 +00:00
|
|
|
gScreenViewports[viewPortIndex].scissorX1 = 0;
|
|
|
|
|
gScreenViewports[viewPortIndex].scissorY1 = 0;
|
|
|
|
|
gScreenViewports[viewPortIndex].scissorX2 = 0;
|
|
|
|
|
gScreenViewports[viewPortIndex].scissorY2 = 0;
|
2021-08-15 16:47:35 -05:00
|
|
|
} else {
|
2021-12-11 22:59:46 -05:00
|
|
|
if (x1 < 0) {
|
2021-12-10 19:03:19 +00:00
|
|
|
gScreenViewports[viewPortIndex].scissorX1 = 0;
|
2021-08-15 16:47:35 -05:00
|
|
|
} else {
|
2021-12-11 22:59:46 -05:00
|
|
|
gScreenViewports[viewPortIndex].scissorX1 = x1;
|
2021-08-15 16:47:35 -05:00
|
|
|
}
|
2021-12-10 19:03:19 +00:00
|
|
|
if (y1 < 0) {
|
|
|
|
|
gScreenViewports[viewPortIndex].scissorY1 = 0;
|
2021-08-15 16:47:35 -05:00
|
|
|
} else {
|
2021-12-10 19:03:19 +00:00
|
|
|
gScreenViewports[viewPortIndex].scissorY1 = y1;
|
2021-08-15 16:47:35 -05:00
|
|
|
}
|
2021-12-11 22:59:46 -05:00
|
|
|
if (x2 >= width) {
|
2021-12-10 19:03:19 +00:00
|
|
|
gScreenViewports[viewPortIndex].scissorX2 = width - 1;
|
2021-08-15 16:47:35 -05:00
|
|
|
} else {
|
2021-12-11 22:59:46 -05:00
|
|
|
gScreenViewports[viewPortIndex].scissorX2 = x2;
|
2021-08-15 16:47:35 -05:00
|
|
|
}
|
2021-12-11 22:59:46 -05:00
|
|
|
if (y2 >= height) {
|
2021-12-10 19:03:19 +00:00
|
|
|
gScreenViewports[viewPortIndex].scissorY2 = height - 1;
|
2021-08-15 16:47:35 -05:00
|
|
|
} else {
|
2021-12-11 22:59:46 -05:00
|
|
|
gScreenViewports[viewPortIndex].scissorY2 = y2;
|
2021-08-15 16:47:35 -05:00
|
|
|
}
|
|
|
|
|
}
|
2021-12-10 19:03:19 +00:00
|
|
|
gScreenViewports[viewPortIndex].y1 = y1;
|
2021-12-11 22:59:46 -05:00
|
|
|
gScreenViewports[viewPortIndex].x1 = x1;
|
|
|
|
|
gScreenViewports[viewPortIndex].x2 = x2;
|
|
|
|
|
gScreenViewports[viewPortIndex].y2 = y2;
|
2021-08-15 16:47:35 -05:00
|
|
|
}
|
2021-06-09 01:14:31 -05:00
|
|
|
|
2021-12-10 19:03:19 +00:00
|
|
|
/**
|
|
|
|
|
* Set the selected viewport's coordinate offsets and view size.
|
|
|
|
|
* If you pass VIEWPORT_AUTO through, then the property will be automatically set when the game creates the viewports.
|
2023-01-31 12:02:37 -05:00
|
|
|
* Official name: camSetUserViewSpecial
|
2021-12-10 19:03:19 +00:00
|
|
|
*/
|
|
|
|
|
void set_viewport_properties(s32 viewPortIndex, s32 posX, s32 posY, s32 width, s32 height) {
|
|
|
|
|
if (posX != VIEWPORT_AUTO) {
|
|
|
|
|
gScreenViewports[viewPortIndex].posX = posX;
|
|
|
|
|
gScreenViewports[viewPortIndex].flags |= VIEWPORT_X_CUSTOM;
|
2021-06-09 01:14:31 -05:00
|
|
|
} else {
|
2021-12-10 19:03:19 +00:00
|
|
|
gScreenViewports[viewPortIndex].flags &= ~VIEWPORT_X_CUSTOM;
|
2021-06-09 01:14:31 -05:00
|
|
|
}
|
2021-12-10 19:03:19 +00:00
|
|
|
if (posY != VIEWPORT_AUTO) {
|
2022-12-10 23:34:00 +00:00
|
|
|
//!@bug Viewport Y writes to the X value. Luckily, all cases this function is called use VIEWPORT_AUTO,
|
2021-12-10 19:03:19 +00:00
|
|
|
// so this bug doesn't happen in practice.
|
|
|
|
|
gScreenViewports[viewPortIndex].posX = posY;
|
|
|
|
|
gScreenViewports[viewPortIndex].flags |= VIEWPORT_Y_CUSTOM;
|
2021-06-09 01:14:31 -05:00
|
|
|
} else {
|
2021-12-10 19:03:19 +00:00
|
|
|
gScreenViewports[viewPortIndex].flags &= ~VIEWPORT_Y_CUSTOM;
|
2021-06-09 01:14:31 -05:00
|
|
|
}
|
2021-12-10 19:03:19 +00:00
|
|
|
if (width != VIEWPORT_AUTO) {
|
|
|
|
|
gScreenViewports[viewPortIndex].width = width;
|
|
|
|
|
gScreenViewports[viewPortIndex].flags |= VIEWPORT_WIDTH_CUSTOM;
|
2021-06-09 01:14:31 -05:00
|
|
|
} else {
|
2021-12-10 19:03:19 +00:00
|
|
|
gScreenViewports[viewPortIndex].flags &= ~VIEWPORT_WIDTH_CUSTOM;
|
2021-06-09 01:14:31 -05:00
|
|
|
}
|
2021-12-10 19:03:19 +00:00
|
|
|
if (height != VIEWPORT_AUTO) {
|
|
|
|
|
gScreenViewports[viewPortIndex].height = height;
|
|
|
|
|
gScreenViewports[viewPortIndex].flags |= VIEWPORT_HEIGHT_CUSTOM;
|
|
|
|
|
} else {
|
|
|
|
|
gScreenViewports[viewPortIndex].flags &= ~VIEWPORT_HEIGHT_CUSTOM;
|
2021-06-09 01:14:31 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-12-10 19:03:19 +00:00
|
|
|
/**
|
|
|
|
|
* Sets the passed values to be equal to the selected viewports scissor size, before drawing the background elements.
|
|
|
|
|
* Usually, this is the same size as the viewport's size.
|
2023-01-31 12:02:37 -05:00
|
|
|
* Official name: camGetVisibleUserView
|
2021-12-10 19:03:19 +00:00
|
|
|
*/
|
|
|
|
|
s32 copy_viewport_background_size_to_coords(s32 viewPortIndex, s32 *x1, s32 *y1, s32 *x2, s32 *y2) {
|
2021-09-17 20:50:15 -04:00
|
|
|
//gDPFillRectangle values
|
2021-12-10 19:03:19 +00:00
|
|
|
*x1 = gScreenViewports[viewPortIndex].scissorX1;
|
|
|
|
|
*x2 = gScreenViewports[viewPortIndex].scissorX2;
|
|
|
|
|
*y1 = gScreenViewports[viewPortIndex].scissorY1;
|
|
|
|
|
*y2 = gScreenViewports[viewPortIndex].scissorY2;
|
|
|
|
|
if ((*x1 | *x2 | *y1 | *y2) == 0) {
|
2021-06-09 01:14:31 -05:00
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
2021-12-10 19:03:19 +00:00
|
|
|
/**
|
|
|
|
|
* Sets the passed values to the coordinate size of the passed viewport.
|
2023-01-31 12:02:37 -05:00
|
|
|
* Official name: camGetUserView
|
2021-12-10 19:03:19 +00:00
|
|
|
*/
|
|
|
|
|
void copy_viewport_frame_size_to_coords(s32 viewPortIndex, s32 *x1, s32 *y1, s32 *x2, s32 *y2) {
|
|
|
|
|
*x1 = gScreenViewports[viewPortIndex].x1;
|
2021-12-11 22:59:46 -05:00
|
|
|
*y1 = gScreenViewports[viewPortIndex].y1;
|
|
|
|
|
*x2 = gScreenViewports[viewPortIndex].x2;
|
2021-12-10 19:03:19 +00:00
|
|
|
*y2 = gScreenViewports[viewPortIndex].y2;
|
2021-06-09 01:14:31 -05:00
|
|
|
}
|
|
|
|
|
|
2021-12-10 19:03:19 +00:00
|
|
|
/**
|
|
|
|
|
* Unused function that sets the passed values to the framebuffer's size in coordinates.
|
|
|
|
|
*/
|
|
|
|
|
UNUSED void copy_framebuffer_size_to_coords(s32 *x1, s32 *y1, s32 *x2, s32 *y2) {
|
2021-12-11 22:59:46 -05:00
|
|
|
u32 widthAndHeight = get_video_width_and_height_as_s32();
|
2021-12-10 19:03:19 +00:00
|
|
|
*x1 = 0;
|
|
|
|
|
*y1 = 0;
|
2021-12-11 22:59:46 -05:00
|
|
|
*x2 = GET_VIDEO_WIDTH(widthAndHeight);
|
|
|
|
|
*y2 = GET_VIDEO_HEIGHT(widthAndHeight);
|
2021-06-09 01:14:31 -05:00
|
|
|
}
|
|
|
|
|
|
2021-12-15 14:58:05 -05:00
|
|
|
#ifdef NON_EQUIVALENT
|
2021-07-08 10:59:11 -05:00
|
|
|
|
|
|
|
|
// Still a work-in-progress but it doesn't seem to cause any problems,
|
2021-12-15 14:58:05 -05:00
|
|
|
// which is why it is labeled under NON_EQUIVALENT
|
2021-07-08 10:59:11 -05:00
|
|
|
|
|
|
|
|
#define SCISSOR_INTERLACE G_SC_NON_INTERLACE
|
|
|
|
|
|
2022-12-10 22:42:50 +00:00
|
|
|
void func_80066CDC(Gfx **dlist, MatrixS **mats) {
|
2021-07-08 10:59:11 -05:00
|
|
|
u32 sp58;
|
|
|
|
|
u32 sp54;
|
|
|
|
|
u32 sp4C;
|
|
|
|
|
u32 temp_a2;
|
|
|
|
|
u32 temp_a3;
|
|
|
|
|
u32 temp_t0;
|
2021-12-11 22:59:46 -05:00
|
|
|
u32 width;
|
2021-07-08 10:59:11 -05:00
|
|
|
u32 widthAndHeight;
|
|
|
|
|
u32 temp_v0_6;
|
|
|
|
|
u32 phi_a1;
|
|
|
|
|
u32 phi_t3;
|
|
|
|
|
u32 phi_t5;
|
|
|
|
|
u32 phi_t4;
|
|
|
|
|
|
2021-07-22 02:23:31 -05:00
|
|
|
if (func_8000E184() && !gNumberOfViewports) {
|
2022-11-20 23:37:50 +00:00
|
|
|
gActiveCameraID = 1;
|
2021-07-08 10:59:11 -05:00
|
|
|
}
|
|
|
|
|
widthAndHeight = get_video_width_and_height_as_s32();
|
|
|
|
|
temp_t0 = widthAndHeight >> 16;
|
|
|
|
|
temp_a3 = temp_t0 >> 1;
|
2023-01-07 14:40:25 +00:00
|
|
|
if (gScreenViewports[gActiveCameraID].flags & VIEWPORT_EXTRA_BG) {
|
2021-12-07 20:03:03 +00:00
|
|
|
gDPSetScissor((*dlist)++, SCISSOR_INTERLACE,
|
2022-11-20 23:37:50 +00:00
|
|
|
gScreenViewports[gActiveCameraID].scissorX1,
|
|
|
|
|
gScreenViewports[gActiveCameraID].scissorY1,
|
|
|
|
|
gScreenViewports[gActiveCameraID].scissorX2,
|
|
|
|
|
gScreenViewports[gActiveCameraID].scissorY2
|
2021-10-27 17:17:08 -04:00
|
|
|
);
|
2021-07-08 10:59:11 -05:00
|
|
|
func_80068158(dlist, 0, 0, 0, 0);
|
2022-03-28 08:36:12 -04:00
|
|
|
if (mats != 0) {
|
|
|
|
|
func_80067D3C(dlist, mats);
|
2021-07-08 10:59:11 -05:00
|
|
|
}
|
|
|
|
|
return;
|
|
|
|
|
}
|
2021-12-11 22:59:46 -05:00
|
|
|
width = GET_VIDEO_WIDTH(widthAndHeight);
|
2021-07-22 02:23:31 -05:00
|
|
|
if (gNumberOfViewports == VIEWPORTS_COUNT_3_PLAYERS) {
|
|
|
|
|
gNumberOfViewports = VIEWPORTS_COUNT_4_PLAYERS;
|
2021-07-08 10:59:11 -05:00
|
|
|
}
|
2021-12-11 22:59:46 -05:00
|
|
|
temp_a2 = width >> 1;
|
2021-07-08 10:59:11 -05:00
|
|
|
sp54 = temp_a2;
|
|
|
|
|
sp58 = temp_a3;
|
2021-09-10 08:22:05 -04:00
|
|
|
if (osTvType == TV_TYPE_PAL) {
|
2021-07-08 10:59:11 -05:00
|
|
|
sp58 = 0x91;
|
|
|
|
|
}
|
2021-10-28 10:18:37 -04:00
|
|
|
|
|
|
|
|
switch (gNumberOfViewports) {
|
2021-07-22 02:23:31 -05:00
|
|
|
case VIEWPORTS_COUNT_1_PLAYER:
|
2021-07-08 10:59:11 -05:00
|
|
|
phi_t3 = sp58;
|
2021-09-10 08:22:05 -04:00
|
|
|
if (osTvType == TV_TYPE_PAL) {
|
2021-07-08 10:59:11 -05:00
|
|
|
phi_t3 = sp58 - 0x12;
|
|
|
|
|
}
|
2021-12-11 22:59:46 -05:00
|
|
|
gDPSetScissor((*dlist)++, SCISSOR_INTERLACE, 0, 0, width, temp_t0);
|
2021-07-08 10:59:11 -05:00
|
|
|
sp4C = temp_a2;
|
|
|
|
|
break;
|
2021-07-22 02:23:31 -05:00
|
|
|
case VIEWPORTS_COUNT_2_PLAYERS:
|
2022-11-20 23:37:50 +00:00
|
|
|
if (gActiveCameraID == 0) {
|
2021-07-08 10:59:11 -05:00
|
|
|
temp_v0_6 = temp_t0 >> 2;
|
|
|
|
|
phi_t3 = temp_v0_6;
|
2021-09-10 08:22:05 -04:00
|
|
|
if (osTvType == TV_TYPE_PAL) {
|
2021-07-08 10:59:11 -05:00
|
|
|
phi_t3 = temp_v0_6 - 0xC;
|
|
|
|
|
}
|
2021-12-11 22:59:46 -05:00
|
|
|
gDPSetScissor((*dlist)++, SCISSOR_INTERLACE, 0, 0, width, (temp_a3 - (temp_t0 >> 7)));
|
2021-07-08 10:59:11 -05:00
|
|
|
} else {
|
2021-12-11 22:59:46 -05:00
|
|
|
gDPSetScissor((*dlist)++, SCISSOR_INTERLACE, 0, (temp_a3 + (temp_t0 >> 7)), width, (temp_t0 - (temp_t0 >> 7)));
|
2021-07-08 10:59:11 -05:00
|
|
|
phi_t3 = temp_a3 + (temp_t0 >> 2);
|
|
|
|
|
}
|
|
|
|
|
sp4C = temp_a2;
|
|
|
|
|
break;
|
2021-07-22 02:23:31 -05:00
|
|
|
case VIEWPORTS_COUNT_3_PLAYERS:
|
2022-11-20 23:37:50 +00:00
|
|
|
if (gActiveCameraID == 0) {
|
2021-12-11 22:59:46 -05:00
|
|
|
gDPSetScissor((*dlist)++, SCISSOR_INTERLACE, 0, 0, temp_a2 - (width >> 8), temp_t0);
|
|
|
|
|
phi_a1 = width >> 2;
|
2021-07-08 10:59:11 -05:00
|
|
|
} else {
|
2021-12-11 22:59:46 -05:00
|
|
|
gDPSetScissor((*dlist)++, SCISSOR_INTERLACE, temp_a2 + (width >> 8), 0, width - (width >> 8), temp_t0);
|
|
|
|
|
phi_a1 = temp_a2 + (width >> 2);
|
2021-07-08 10:59:11 -05:00
|
|
|
}
|
|
|
|
|
sp4C = phi_a1;
|
|
|
|
|
phi_t3 = sp58;
|
|
|
|
|
break;
|
2021-07-22 02:23:31 -05:00
|
|
|
case VIEWPORTS_COUNT_4_PLAYERS:
|
2021-07-08 10:59:11 -05:00
|
|
|
sp58 = sp58 >> 1;
|
|
|
|
|
sp54 = temp_a2 >> 1;
|
2022-11-20 23:37:50 +00:00
|
|
|
switch (gActiveCameraID) {
|
2021-07-08 10:59:11 -05:00
|
|
|
case 0:
|
2021-12-11 22:59:46 -05:00
|
|
|
gDPSetScissor((*dlist)++, SCISSOR_INTERLACE, 0.0f, 0.0f, (temp_a2 - (width >> 8)), (temp_a3 - (temp_t0 >> 7)));
|
2021-07-08 10:59:11 -05:00
|
|
|
phi_t5 = 0;
|
|
|
|
|
phi_t4 = 0;
|
|
|
|
|
case 1:
|
2021-12-11 22:59:46 -05:00
|
|
|
gDPSetScissor((*dlist)++, SCISSOR_INTERLACE, (temp_a2 + (width >> 8)), 0, ((temp_a2 * 2) - (width >> 8)), (temp_a3 - (temp_t0 >> 7)));
|
2021-07-08 10:59:11 -05:00
|
|
|
phi_t5 = 0;
|
|
|
|
|
phi_t4 = temp_a2;
|
|
|
|
|
break;
|
|
|
|
|
case 2:
|
2021-12-11 22:59:46 -05:00
|
|
|
gDPSetScissor((*dlist)++, SCISSOR_INTERLACE, 0, temp_a3 + (temp_t0 >> 7), temp_a2 - (width >> 8), (temp_a3 * 2) - (temp_t0 >> 7));
|
2021-07-08 10:59:11 -05:00
|
|
|
phi_t5 = temp_a3;
|
|
|
|
|
phi_t4 = 0;
|
|
|
|
|
break;
|
|
|
|
|
case 3:
|
2021-12-11 22:59:46 -05:00
|
|
|
gDPSetScissor((*dlist)++, SCISSOR_INTERLACE, temp_a2 + (width >> 8), temp_a3 + (temp_t0 >> 7), (temp_a2 * 2) - (width >> 8), (temp_a3 * 2) - (temp_t0 >> 7));
|
2021-07-08 10:59:11 -05:00
|
|
|
phi_t5 = temp_a3;
|
|
|
|
|
phi_t4 = temp_a2;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
phi_t5 = 0;
|
|
|
|
|
phi_t4 = 0;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
phi_t3 = phi_t5 + sp58;
|
|
|
|
|
sp4C = phi_t4 + sp54;
|
2021-09-10 08:22:05 -04:00
|
|
|
if (osTvType == TV_TYPE_PAL) {
|
2021-07-08 10:59:11 -05:00
|
|
|
phi_t3 -= 6;
|
2022-11-20 23:37:50 +00:00
|
|
|
if (gActiveCameraID < 2) {
|
2021-07-08 10:59:11 -05:00
|
|
|
phi_t3 -= 0x14;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
//phi_t3 = sp50;
|
|
|
|
|
phi_t3 = sp54;
|
|
|
|
|
break;
|
|
|
|
|
}
|
2021-10-28 10:18:37 -04:00
|
|
|
|
2021-09-10 08:22:05 -04:00
|
|
|
if (osTvType == TV_TYPE_PAL) {
|
2021-07-08 10:59:11 -05:00
|
|
|
sp4C -= 4;
|
|
|
|
|
}
|
|
|
|
|
func_80068158(dlist, sp54, sp58, sp4C, phi_t3);
|
2022-03-28 08:36:12 -04:00
|
|
|
if (mats != 0) {
|
|
|
|
|
func_80067D3C(dlist, mats);
|
2021-07-08 10:59:11 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#else
|
2021-07-05 14:00:21 -05:00
|
|
|
GLOBAL_ASM("asm/non_matchings/camera/func_80066CDC.s")
|
2021-07-08 10:59:11 -05:00
|
|
|
#endif
|
|
|
|
|
|
2023-01-07 14:40:25 +00:00
|
|
|
/**
|
|
|
|
|
* Takes the size of the screen as depicted by an active screen viewport, then sets the RDP scissor to match it.
|
|
|
|
|
*/
|
|
|
|
|
void set_viewport_scissor(Gfx **dlist) {
|
2022-11-14 10:49:35 -05:00
|
|
|
s32 size;
|
|
|
|
|
s32 lrx;
|
|
|
|
|
s32 lry;
|
|
|
|
|
s32 ulx;
|
|
|
|
|
s32 uly;
|
|
|
|
|
s32 numViewports;
|
|
|
|
|
s32 temp;
|
|
|
|
|
s32 temp2;
|
|
|
|
|
s32 temp3;
|
|
|
|
|
s32 temp4;
|
|
|
|
|
s32 width;
|
|
|
|
|
s32 height;
|
|
|
|
|
|
|
|
|
|
size = get_video_width_and_height_as_s32();
|
|
|
|
|
height = (u16) GET_VIDEO_HEIGHT(size);
|
|
|
|
|
width = (u16) size;
|
|
|
|
|
numViewports = gNumberOfViewports;
|
|
|
|
|
|
|
|
|
|
if (numViewports != 0) {
|
2023-01-07 14:40:25 +00:00
|
|
|
if (numViewports == VIEWPORTS_COUNT_3_PLAYERS) {
|
|
|
|
|
numViewports = VIEWPORTS_COUNT_4_PLAYERS;
|
2022-11-14 10:49:35 -05:00
|
|
|
}
|
|
|
|
|
lrx = ulx = 0;
|
|
|
|
|
lry = uly = 0;
|
|
|
|
|
lrx += width;\
|
|
|
|
|
lry += height;
|
|
|
|
|
temp = lry >> 7;
|
|
|
|
|
temp2 = lrx >> 8;
|
|
|
|
|
temp4 = lrx >> 1;
|
|
|
|
|
temp3 = lry >> 1;
|
|
|
|
|
switch (numViewports) {
|
|
|
|
|
case 1:
|
2022-11-20 23:37:50 +00:00
|
|
|
switch (gActiveCameraID) {
|
2022-11-14 10:49:35 -05:00
|
|
|
case 0:
|
|
|
|
|
lry = temp3 - temp;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
uly = temp3 + temp;
|
|
|
|
|
lry -= temp;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 2:
|
2022-11-20 23:37:50 +00:00
|
|
|
switch (gActiveCameraID) {
|
2022-11-14 10:49:35 -05:00
|
|
|
case 0:
|
|
|
|
|
lrx = temp4 - temp2;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
ulx = temp4 + temp2;
|
|
|
|
|
lrx -= temp2;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 3:
|
2022-11-20 23:37:50 +00:00
|
|
|
switch (gActiveCameraID) {
|
2022-11-14 10:49:35 -05:00
|
|
|
case 0:
|
|
|
|
|
lrx = temp4 - temp2;\
|
|
|
|
|
lry = temp3 - temp;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 1:
|
|
|
|
|
ulx = temp4 + temp2;
|
|
|
|
|
lrx -= temp2;
|
|
|
|
|
lry = temp3 - temp;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 2:
|
|
|
|
|
uly = temp3 + temp;
|
|
|
|
|
lrx = temp4 - temp2;\
|
|
|
|
|
lry -= temp;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 3:
|
|
|
|
|
ulx = temp4 + temp2; \
|
|
|
|
|
uly = temp3 + temp;
|
|
|
|
|
lrx -= temp2; \
|
|
|
|
|
lry -= temp;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
gDPSetScissor((*dlist)++, 0, ulx, uly, lrx, lry);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
gDPSetScissor((*dlist)++, 0, 0, 0, width, height);
|
|
|
|
|
}
|
2022-03-28 08:36:12 -04:00
|
|
|
|
2022-12-10 22:42:50 +00:00
|
|
|
void func_80067D3C(Gfx **dlist, UNUSED MatrixS **mats) {
|
2022-03-28 08:36:12 -04:00
|
|
|
s32 temp;
|
|
|
|
|
|
2022-09-20 09:42:30 -04:00
|
|
|
gSPPerspNormalize((*dlist)++, perspNorm);
|
2022-03-28 08:36:12 -04:00
|
|
|
|
2022-11-20 23:37:50 +00:00
|
|
|
temp = gActiveCameraID;
|
2022-10-24 15:37:47 +01:00
|
|
|
if (gCutsceneCameraActive) {
|
2022-11-20 23:37:50 +00:00
|
|
|
gActiveCameraID += 4;
|
2022-03-28 08:36:12 -04:00
|
|
|
}
|
|
|
|
|
|
2023-01-23 12:54:17 +00:00
|
|
|
gCameraTransform.y_rotation = 0x8000 + gActiveCameraStack[gActiveCameraID].trans.y_rotation;
|
|
|
|
|
gCameraTransform.x_rotation = gActiveCameraStack[gActiveCameraID].trans.x_rotation + gActiveCameraStack[gActiveCameraID].unk38.half.unk38;
|
|
|
|
|
gCameraTransform.z_rotation = gActiveCameraStack[gActiveCameraID].trans.z_rotation;
|
2022-03-28 08:36:12 -04:00
|
|
|
|
2023-01-23 12:54:17 +00:00
|
|
|
gCameraTransform.x_position = -gActiveCameraStack[gActiveCameraID].trans.x_position;
|
|
|
|
|
gCameraTransform.y_position = -gActiveCameraStack[gActiveCameraID].trans.y_position;
|
2022-03-28 08:36:12 -04:00
|
|
|
if (D_80120D18 != 0) {
|
2023-01-23 12:54:17 +00:00
|
|
|
gCameraTransform.y_position -= gActiveCameraStack[gActiveCameraID].unk30;
|
2022-03-28 08:36:12 -04:00
|
|
|
}
|
2023-01-23 12:54:17 +00:00
|
|
|
gCameraTransform.z_position = -gActiveCameraStack[gActiveCameraID].trans.z_position;
|
2022-03-28 08:36:12 -04:00
|
|
|
|
2023-01-23 12:54:17 +00:00
|
|
|
object_transform_to_matrix_2(D_80120F60, &gCameraTransform);
|
2023-01-05 17:37:08 +00:00
|
|
|
f32_matrix_mult(&D_80120F60, &gPerspectiveMatrixF, &D_80120F20);
|
2022-03-28 08:36:12 -04:00
|
|
|
|
2023-01-23 12:54:17 +00:00
|
|
|
gCameraTransform.y_rotation = -0x8000 - gActiveCameraStack[gActiveCameraID].trans.y_rotation;
|
|
|
|
|
gCameraTransform.x_rotation = -(gActiveCameraStack[gActiveCameraID].trans.x_rotation + gActiveCameraStack[gActiveCameraID].unk38.half.unk38);
|
|
|
|
|
gCameraTransform.z_rotation = -gActiveCameraStack[gActiveCameraID].trans.z_rotation;
|
|
|
|
|
gCameraTransform.scale = 1.0f;
|
|
|
|
|
gCameraTransform.x_position = gActiveCameraStack[gActiveCameraID].trans.x_position;
|
|
|
|
|
gCameraTransform.y_position = gActiveCameraStack[gActiveCameraID].trans.y_position;
|
2022-03-28 08:36:12 -04:00
|
|
|
if (D_80120D18 != 0) {
|
2023-01-23 12:54:17 +00:00
|
|
|
gCameraTransform.y_position += gActiveCameraStack[gActiveCameraID].unk30;
|
2022-03-28 08:36:12 -04:00
|
|
|
}
|
2023-01-23 12:54:17 +00:00
|
|
|
gCameraTransform.z_position = gActiveCameraStack[gActiveCameraID].trans.z_position;
|
2022-03-28 08:36:12 -04:00
|
|
|
|
2023-01-23 12:54:17 +00:00
|
|
|
object_transform_to_matrix(D_80120FA0, &gCameraTransform);
|
2022-11-30 16:49:33 -05:00
|
|
|
f32_matrix_to_s16_matrix(&D_80120FA0, &D_80121020);
|
2022-03-28 08:36:12 -04:00
|
|
|
|
2022-11-20 23:37:50 +00:00
|
|
|
gActiveCameraID = temp;
|
2022-03-28 08:36:12 -04:00
|
|
|
}
|
2021-06-09 01:14:31 -05:00
|
|
|
|
2021-12-09 21:48:51 +00:00
|
|
|
/**
|
|
|
|
|
* Sets the Y value of the Y axis in the matrix to the passed value.
|
|
|
|
|
* This is used to vertically scale ortho geometry to look identical across NTSC and PAL systems.
|
|
|
|
|
*/
|
|
|
|
|
void set_ortho_matrix_height(f32 value) {
|
|
|
|
|
gOrthoMatrix[1][1] = value;
|
2021-06-09 01:14:31 -05:00
|
|
|
}
|
|
|
|
|
|
2022-12-18 12:39:40 +00:00
|
|
|
/**
|
|
|
|
|
* Sets the current matrix to represent an orthogonal view.
|
|
|
|
|
* Used for drawing triangles on screen as HUD.
|
|
|
|
|
*/
|
|
|
|
|
void set_ortho_matrix_view(Gfx **dlist, MatrixS **mtx) {
|
2021-09-17 23:52:24 -04:00
|
|
|
u32 widthAndHeight;
|
|
|
|
|
s32 width, height;
|
2021-09-09 09:18:51 -04:00
|
|
|
s32 i, j;
|
2021-10-28 10:18:37 -04:00
|
|
|
|
2021-08-15 16:47:35 -05:00
|
|
|
widthAndHeight = get_video_width_and_height_as_s32();
|
2021-12-11 22:59:46 -05:00
|
|
|
height = GET_VIDEO_HEIGHT(widthAndHeight);
|
|
|
|
|
width = GET_VIDEO_WIDTH(widthAndHeight);
|
2022-12-10 22:42:50 +00:00
|
|
|
f32_matrix_to_s16_matrix(&gOrthoMatrix, *mtx);
|
|
|
|
|
D_80120D88[0] = *mtx;
|
2023-01-23 12:54:17 +00:00
|
|
|
gViewportStack[gActiveCameraID + 5].vp.vscale[0] = width * 2;
|
|
|
|
|
gViewportStack[gActiveCameraID + 5].vp.vscale[1] = width * 2;
|
|
|
|
|
gViewportStack[gActiveCameraID + 5].vp.vtrans[0] = width * 2;
|
|
|
|
|
gViewportStack[gActiveCameraID + 5].vp.vtrans[1] = height * 2;
|
|
|
|
|
gSPViewport((*dlist)++, OS_K0_TO_PHYSICAL(&gViewportStack[gActiveCameraID + 5]));
|
2022-12-10 22:42:50 +00:00
|
|
|
gSPMatrix((*dlist)++, OS_PHYSICAL_TO_K0((*mtx)++), G_MTX_NOPUSH | G_MTX_MUL | G_MTX_MODELVIEW);
|
2021-08-15 16:47:35 -05:00
|
|
|
D_80120D1C = 0;
|
|
|
|
|
D_80120D08 = 0;
|
2021-09-09 09:18:51 -04:00
|
|
|
|
2022-08-28 07:02:05 -04:00
|
|
|
for (i = 0; i < 4; i++) {
|
|
|
|
|
//Required to be one line, but the "\" fixes that.
|
|
|
|
|
for (j = 0; j < 4; j++){ \
|
2021-12-09 21:48:51 +00:00
|
|
|
D_80120F20[i][j] = gOrthoMatrix[i][j];
|
2021-09-09 09:18:51 -04:00
|
|
|
}
|
2021-08-15 16:47:35 -05:00
|
|
|
}
|
|
|
|
|
}
|
2021-06-09 01:14:31 -05:00
|
|
|
|
2022-12-10 22:42:50 +00:00
|
|
|
void func_8006807C(Gfx **dlist, MatrixS **mtx) {
|
|
|
|
|
object_transform_to_matrix_2(D_80121060, &D_800DD288);
|
2023-01-05 17:37:08 +00:00
|
|
|
f32_matrix_mult(&D_80121060, &gPerspectiveMatrixF, &D_80120F20);
|
2022-12-10 22:42:50 +00:00
|
|
|
object_transform_to_matrix_2((float (*)[4]) D_80120D70[0], &D_800DD2A0);
|
2022-11-30 16:49:33 -05:00
|
|
|
f32_matrix_mult(D_80120D70[0], &D_80120F20, &D_80121060);
|
2022-12-10 22:42:50 +00:00
|
|
|
f32_matrix_to_s16_matrix(&D_80121060, *mtx);
|
|
|
|
|
gSPMatrix((*dlist)++, OS_PHYSICAL_TO_K0((*mtx)++), G_MTX_NOPUSH | G_MTX_MUL | G_MTX_MODELVIEW);
|
2021-06-09 01:14:31 -05:00
|
|
|
D_80120D1C = 0;
|
|
|
|
|
D_80120D08 = 0;
|
|
|
|
|
}
|
|
|
|
|
|
2021-12-10 19:03:19 +00:00
|
|
|
void func_80068158(Gfx **dlist, s32 width, s32 height, s32 posX, s32 posY) {
|
|
|
|
|
s32 tempWidth = (get_filtered_cheats() & CHEAT_MIRRORED_TRACKS) ? -width : width;
|
2022-10-24 15:37:47 +01:00
|
|
|
// Antipiracy measure. Flips the screen upside down.
|
|
|
|
|
if (gAntiPiracyViewport) {
|
2021-12-10 19:03:19 +00:00
|
|
|
height = -height;
|
|
|
|
|
tempWidth = -width;
|
2021-08-15 16:47:35 -05:00
|
|
|
}
|
2023-01-07 14:40:25 +00:00
|
|
|
if (!(gScreenViewports[gActiveCameraID].flags & VIEWPORT_EXTRA_BG)) {
|
2023-01-23 12:54:17 +00:00
|
|
|
gViewportStack[gActiveCameraID].vp.vtrans[0] = posX * 4;
|
|
|
|
|
gViewportStack[gActiveCameraID].vp.vtrans[1] = posY * 4;
|
|
|
|
|
gViewportStack[gActiveCameraID].vp.vscale[0] = tempWidth * 4;
|
|
|
|
|
gViewportStack[gActiveCameraID].vp.vscale[1] = height * 4;
|
|
|
|
|
gSPViewport((*dlist)++, OS_PHYSICAL_TO_K0(&gViewportStack[gActiveCameraID]));
|
2021-08-15 16:47:35 -05:00
|
|
|
} else {
|
2023-01-23 12:54:17 +00:00
|
|
|
gSPViewport((*dlist)++, OS_PHYSICAL_TO_K0(&gViewportStack[gActiveCameraID + 10 + (gViewportWithBG * 5)]));
|
2021-08-15 16:47:35 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void func_800682AC(Gfx **dlist) {
|
|
|
|
|
u32 widthAndHeight, width, height;
|
2022-11-20 23:37:50 +00:00
|
|
|
gActiveCameraID = 4;
|
2021-08-15 16:47:35 -05:00
|
|
|
widthAndHeight = get_video_width_and_height_as_s32();
|
2021-12-11 22:59:46 -05:00
|
|
|
height = GET_VIDEO_HEIGHT(widthAndHeight);
|
|
|
|
|
width = GET_VIDEO_WIDTH(widthAndHeight);
|
2023-01-07 14:40:25 +00:00
|
|
|
if (!(gScreenViewports[gActiveCameraID].flags & VIEWPORT_EXTRA_BG)) {
|
2021-10-27 17:17:08 -04:00
|
|
|
gDPSetScissor((*dlist)++, G_SC_NON_INTERLACE, 0, 0, width - 1, height - 1);
|
2021-08-15 16:47:35 -05:00
|
|
|
func_80068158(dlist, width >> 1, height >> 1, width >> 1, height >> 1);
|
|
|
|
|
} else {
|
2023-01-07 14:40:25 +00:00
|
|
|
set_viewport_scissor(dlist);
|
2021-08-15 16:47:35 -05:00
|
|
|
func_80068158(dlist, 0, 0, 0, 0);
|
|
|
|
|
}
|
2022-11-20 23:37:50 +00:00
|
|
|
gActiveCameraID = 0;
|
2021-08-15 16:47:35 -05:00
|
|
|
}
|
2021-06-09 01:14:31 -05:00
|
|
|
|
2022-12-10 22:42:50 +00:00
|
|
|
void func_80068408(Gfx **dlist, MatrixS **mtx) {
|
2022-11-30 16:49:33 -05:00
|
|
|
f32_matrix_from_position(D_80120D70[D_80120D1C], 0.0f, 0.0f, 0.0f);
|
|
|
|
|
f32_matrix_mult(D_80120D70[D_80120D1C], &D_80120F20, &D_80121060);
|
2022-12-10 22:42:50 +00:00
|
|
|
f32_matrix_to_s16_matrix(&D_80121060, *mtx);
|
|
|
|
|
D_80120D88[D_80120D1C] = *mtx;
|
|
|
|
|
gSPMatrix((*dlist)++, OS_PHYSICAL_TO_K0((*mtx)++), D_80120D08 << 6);
|
2021-06-09 01:14:31 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void func_80068508(s32 arg0) {
|
|
|
|
|
D_80120D0C = arg0;
|
|
|
|
|
}
|
|
|
|
|
|
2022-11-15 17:45:22 +00:00
|
|
|
/**
|
|
|
|
|
* Calculates angle from object to camera, then renders the sprite as a billboard, facing the camera.
|
|
|
|
|
*/
|
2022-12-10 22:42:50 +00:00
|
|
|
s32 render_sprite_billboard(Gfx **dlist, MatrixS **mtx, Vertex **vertexList, Object *obj, unk80068514_arg4 *arg4, s32 flags) {
|
2022-11-15 17:45:22 +00:00
|
|
|
f32 sp5C;
|
|
|
|
|
f32 sp58;
|
|
|
|
|
Vertex *v;
|
|
|
|
|
f32 sp50;
|
|
|
|
|
f32 sp4C;
|
|
|
|
|
f32 temp_f0;
|
|
|
|
|
f32 sp44;
|
|
|
|
|
f32 var_f20;
|
|
|
|
|
s32 sp3C;
|
|
|
|
|
s32 sp38;
|
|
|
|
|
s32 sp34;
|
|
|
|
|
s32 result;
|
|
|
|
|
s32 var_s2;
|
|
|
|
|
|
|
|
|
|
result = TRUE;
|
2022-12-08 16:05:29 +00:00
|
|
|
if (flags & RENDER_ANTI_ALIASING) {
|
2022-11-15 17:45:22 +00:00
|
|
|
sp5C = D_80120D28[D_80120D20] - obj->segment.trans.x_position;
|
|
|
|
|
sp58 = D_80120D40[D_80120D20] - obj->segment.trans.y_position;
|
|
|
|
|
var_f20 = D_80120D58[D_80120D20] - obj->segment.trans.z_position;
|
2022-11-30 16:49:33 -05:00
|
|
|
sp4C = sins_f(obj->segment.trans.y_rotation);
|
|
|
|
|
temp_f0 = coss_f(obj->segment.trans.y_rotation);
|
2022-11-15 17:45:22 +00:00
|
|
|
sp44 = (sp5C * temp_f0) + (var_f20 * sp4C);
|
|
|
|
|
var_f20 = (var_f20 * temp_f0) - (sp5C * sp4C);
|
|
|
|
|
sp38 = arctan2_f(sp44, sqrtf((sp58 * sp58) + (var_f20 * var_f20)));
|
2022-11-30 16:49:33 -05:00
|
|
|
sp3C = -sins(arctan2_f(sp44, var_f20)) >> 8;
|
2022-11-15 17:45:22 +00:00
|
|
|
if (var_f20 < 0.0f) {
|
|
|
|
|
var_f20 = -var_f20;
|
|
|
|
|
sp3C = 1 - sp3C;
|
|
|
|
|
sp38 = -sp38;
|
|
|
|
|
}
|
|
|
|
|
sp34 = arctan2_f(sp58, var_f20);
|
|
|
|
|
if (sp34 > 0x8000) {
|
|
|
|
|
sp34 -= 0x10000;
|
|
|
|
|
}
|
|
|
|
|
sp34 = (sp34 * sp3C) >> 8;
|
|
|
|
|
var_s2 = (sp38 >> 7) & 0xFF;
|
|
|
|
|
if (var_s2 > 127) {
|
|
|
|
|
var_s2 = 255 - var_s2;
|
|
|
|
|
sp34 += 0x8000;
|
|
|
|
|
result = FALSE;
|
|
|
|
|
}
|
|
|
|
|
var_s2 *= 2;
|
|
|
|
|
sp5C = D_80120D28[D_80120D20] - obj->segment.trans.x_position;
|
|
|
|
|
sp58 = D_80120D40[D_80120D20] - obj->segment.trans.y_position;
|
|
|
|
|
var_f20 = D_80120D58[D_80120D20] - obj->segment.trans.z_position;
|
|
|
|
|
sp50 = sqrtf((sp5C * sp5C) + (var_f20 * var_f20));
|
2023-01-23 12:54:17 +00:00
|
|
|
gCameraTransform.y_rotation = arctan2_f(sp5C, var_f20);
|
|
|
|
|
gCameraTransform.x_rotation = -arctan2_f(sp58, sp50);
|
|
|
|
|
gCameraTransform.z_rotation = sp34;
|
|
|
|
|
gCameraTransform.scale = obj->segment.trans.scale;
|
|
|
|
|
gCameraTransform.x_position = obj->segment.trans.x_position;
|
|
|
|
|
gCameraTransform.y_position = obj->segment.trans.y_position;
|
|
|
|
|
gCameraTransform.z_position = obj->segment.trans.z_position;
|
|
|
|
|
object_transform_to_matrix(D_80121060, &gCameraTransform);
|
2022-11-15 17:45:22 +00:00
|
|
|
D_80120D1C++;
|
2023-01-23 12:54:17 +00:00
|
|
|
f32_matrix_mult((Matrix *) D_80121060, (Matrix *) &D_80120D70[D_80120D1C-1][0][0], (Matrix *) &D_80120D70[D_80120D1C][0][0]);
|
|
|
|
|
f32_matrix_mult(D_80120D70[D_80120D1C], (Matrix *) D_80120F20, (Matrix *) D_80121060);
|
|
|
|
|
f32_matrix_to_s16_matrix((Matrix *) D_80121060, *mtx);
|
2022-11-15 17:45:22 +00:00
|
|
|
D_80120D88[D_80120D1C] = *mtx;
|
|
|
|
|
gSPMatrix((*dlist)++, OS_PHYSICAL_TO_K0((*mtx)++), 0x80);
|
|
|
|
|
gSPVertexDKR((*dlist)++, OS_K0_TO_PHYSICAL(&D_800DD138), 1, 0);
|
|
|
|
|
} else {
|
|
|
|
|
v = *vertexList;
|
|
|
|
|
v->x = obj->segment.trans.x_position;
|
|
|
|
|
v->y = obj->segment.trans.y_position;
|
|
|
|
|
v->z = obj->segment.trans.z_position;
|
|
|
|
|
v->r = 255;
|
|
|
|
|
v->g = 255;
|
|
|
|
|
v->b = 255;
|
|
|
|
|
v->a = 255;
|
|
|
|
|
gSPVertexDKR((*dlist)++, OS_PHYSICAL_TO_K0(*vertexList), 1, 0);
|
|
|
|
|
(*vertexList)++;
|
|
|
|
|
if (gCutsceneCameraActive == 0) {
|
2022-11-20 23:37:50 +00:00
|
|
|
sp34 = gActiveCameraStack[gActiveCameraID].trans.z_rotation + obj->segment.trans.z_rotation;
|
2022-11-15 17:45:22 +00:00
|
|
|
} else {
|
2022-11-20 23:37:50 +00:00
|
|
|
sp34 = gActiveCameraStack[gActiveCameraID + 4].trans.z_rotation + obj->segment.trans.z_rotation;
|
2022-11-15 17:45:22 +00:00
|
|
|
}
|
2022-12-15 20:19:28 +00:00
|
|
|
var_s2 = obj->segment.animFrame;
|
2022-11-15 17:45:22 +00:00
|
|
|
D_80120D1C++;
|
2022-11-30 16:49:33 -05:00
|
|
|
f32_matrix_from_rotation_and_scale((f32 (*)[4]) D_80120D70[D_80120D1C], sp34, obj->segment.trans.scale, gVideoAspectRatio);
|
|
|
|
|
f32_matrix_to_s16_matrix(D_80120D70[D_80120D1C], *mtx);
|
2022-11-15 17:45:22 +00:00
|
|
|
D_80120D88[D_80120D1C] = *mtx;
|
|
|
|
|
gSPMatrix((*dlist)++, OS_PHYSICAL_TO_K0((*mtx)++), 0x80);
|
|
|
|
|
gDkrEnableBillboard((*dlist)++);
|
|
|
|
|
}
|
|
|
|
|
if (D_80120D0C == 0) {
|
|
|
|
|
var_s2 = ((var_s2 & 0xFF) * arg4->unk0) >> 8;
|
|
|
|
|
}
|
2022-12-08 16:05:29 +00:00
|
|
|
flags &= ~RENDER_ANTI_ALIASING;
|
|
|
|
|
if (flags & RENDER_SEMI_TRANSPARENT) {
|
|
|
|
|
flags |= RENDER_ANTI_ALIASING;
|
2022-11-15 17:45:22 +00:00
|
|
|
}
|
2022-12-08 16:05:29 +00:00
|
|
|
func_8007BF34(dlist, arg4->unk6 | (flags & (RENDER_FOG_ACTIVE | RENDER_SEMI_TRANSPARENT | RENDER_Z_COMPARE | RENDER_ANTI_ALIASING)));
|
|
|
|
|
if (!(flags & RENDER_Z_UPDATE)) {
|
2022-11-15 17:45:22 +00:00
|
|
|
gDPSetPrimColor((*dlist)++, 0, 0, 255, 255, 255, 255);
|
|
|
|
|
}
|
|
|
|
|
gSPDisplayList((*dlist)++, arg4->unk8[var_s2 + 1]);
|
|
|
|
|
D_80120D1C--;
|
|
|
|
|
if (D_80120D1C == 0) {
|
|
|
|
|
var_s2 = 0;
|
|
|
|
|
} else {
|
|
|
|
|
var_s2 = 1;
|
|
|
|
|
}
|
|
|
|
|
gDkrInsertMatrix((*dlist)++, 0, var_s2 << 6);
|
|
|
|
|
gDkrDisableBillboard((*dlist)++);
|
|
|
|
|
return result;
|
|
|
|
|
}
|
2022-10-24 15:37:47 +01:00
|
|
|
|
2022-12-18 12:39:40 +00:00
|
|
|
/**
|
|
|
|
|
* Sets transform and scale matrices to set position and size, loads the texture, sets the rendermodes, then draws the result onscreen.
|
|
|
|
|
*/
|
2023-01-07 14:40:25 +00:00
|
|
|
void render_ortho_triangle_image(Gfx **dList, MatrixS **mtx, Vertex **vtx, ObjectSegment *segment, Sprite *sprite, s32 flags) {
|
2022-10-24 15:37:47 +01:00
|
|
|
UNUSED s32 pad;
|
|
|
|
|
f32 scale;
|
|
|
|
|
s32 index;
|
|
|
|
|
Vertex *temp_v1;
|
|
|
|
|
Matrix sp90;
|
|
|
|
|
Matrix sp50;
|
|
|
|
|
|
2023-01-07 14:40:25 +00:00
|
|
|
if (sprite != NULL) {
|
2022-12-10 22:42:50 +00:00
|
|
|
temp_v1 = *vtx;
|
|
|
|
|
temp_v1->x = segment->trans.x_position;
|
|
|
|
|
temp_v1->y = segment->trans.y_position;
|
|
|
|
|
temp_v1->z = segment->trans.z_position;
|
2022-10-24 15:37:47 +01:00
|
|
|
temp_v1->r = 255;
|
|
|
|
|
temp_v1->g = 255;
|
|
|
|
|
temp_v1->b = 255;
|
|
|
|
|
temp_v1->a = 255;
|
2023-01-07 14:40:25 +00:00
|
|
|
gSPVertexDKR((*dList)++, OS_PHYSICAL_TO_K0(*vtx), 1, 0);
|
2022-12-10 22:42:50 +00:00
|
|
|
(*vtx)++; // Can't be done in the macro?
|
2022-12-15 20:19:28 +00:00
|
|
|
index = segment->animFrame;
|
2022-10-24 15:37:47 +01:00
|
|
|
D_80120D1C ++;
|
2023-01-23 12:54:17 +00:00
|
|
|
gCameraTransform.y_rotation = -segment->trans.y_rotation;
|
|
|
|
|
gCameraTransform.x_rotation = -segment->trans.x_rotation;
|
|
|
|
|
gCameraTransform.z_rotation = gActiveCameraStack[gActiveCameraID].trans.z_rotation + segment->trans.z_rotation;
|
|
|
|
|
gCameraTransform.x_position = 0.0f;
|
|
|
|
|
gCameraTransform.y_position = 0.0f;
|
|
|
|
|
gCameraTransform.z_position = 0.0f;
|
2022-10-24 15:37:47 +01:00
|
|
|
if (gAdjustViewportHeight) {
|
2022-12-10 22:42:50 +00:00
|
|
|
scale = segment->trans.scale;
|
2022-11-30 16:49:33 -05:00
|
|
|
f32_matrix_from_scale(sp50, scale, scale, 1.0f);
|
|
|
|
|
f32_matrix_from_rotation_and_scale(sp90, 0, 1.0f, gVideoAspectRatio);
|
|
|
|
|
f32_matrix_mult(&sp90, &sp50, &D_80121060);
|
2022-10-24 15:37:47 +01:00
|
|
|
} else {
|
2022-12-10 22:42:50 +00:00
|
|
|
scale = segment->trans.scale;
|
2022-11-30 16:49:33 -05:00
|
|
|
f32_matrix_from_scale(D_80121060, scale, scale, 1.0f);
|
2022-10-24 15:37:47 +01:00
|
|
|
}
|
2023-01-23 12:54:17 +00:00
|
|
|
object_transform_to_matrix_2(sp90, &gCameraTransform);
|
2022-11-30 16:49:33 -05:00
|
|
|
f32_matrix_mult(&D_80121060, &sp90, D_80120D70[D_80120D1C]);
|
2022-12-10 22:42:50 +00:00
|
|
|
f32_matrix_to_s16_matrix(D_80120D70[D_80120D1C], *mtx);
|
|
|
|
|
D_80120D88[D_80120D1C] = *mtx;
|
|
|
|
|
gSPMatrix((*dList)++, OS_PHYSICAL_TO_K0((*mtx)++), G_MTX_DKR_INDEX_2);
|
|
|
|
|
gDkrEnableBillboard((*dList)++);
|
2022-10-24 15:37:47 +01:00
|
|
|
if (D_80120D0C == 0) {
|
2023-01-07 14:40:25 +00:00
|
|
|
index = (((u8) index) * sprite->baseTextureId) >> 8;
|
2022-10-24 15:37:47 +01:00
|
|
|
}
|
2023-01-07 14:40:25 +00:00
|
|
|
func_8007BF34(dList, sprite->unk6 | flags);
|
|
|
|
|
if (index >= sprite->baseTextureId) {
|
|
|
|
|
index = sprite->baseTextureId - 1;
|
2022-10-24 15:37:47 +01:00
|
|
|
}
|
2023-01-07 14:40:25 +00:00
|
|
|
gSPDisplayList((*dList)++, sprite->unkC[index]);
|
2022-10-24 15:37:47 +01:00
|
|
|
if (--D_80120D1C == 0) {
|
|
|
|
|
index = 0;
|
|
|
|
|
} else {
|
|
|
|
|
index = 1;
|
|
|
|
|
}
|
2022-12-10 22:42:50 +00:00
|
|
|
gDkrInsertMatrix((*dList)++, 0, index << 6);
|
|
|
|
|
gDkrDisableBillboard((*dList)++);
|
2022-10-24 15:37:47 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-07-05 14:00:21 -05:00
|
|
|
GLOBAL_ASM("asm/non_matchings/camera/func_80068FA8.s")
|
2022-10-24 15:37:47 +01:00
|
|
|
|
2022-12-10 22:42:50 +00:00
|
|
|
void func_80069484(Gfx **dList, MatrixS **mtx, ObjectTransform *trans, f32 scale, f32 scaleY) {
|
2022-10-24 15:37:47 +01:00
|
|
|
f32 tempX;
|
|
|
|
|
f32 tempY;
|
|
|
|
|
f32 tempZ;
|
|
|
|
|
s32 index;
|
|
|
|
|
f32 scaleFactor;
|
|
|
|
|
|
2022-12-10 22:42:50 +00:00
|
|
|
object_transform_to_matrix(D_80121060, trans);
|
|
|
|
|
if (scaleY != 0.0f) {
|
|
|
|
|
f32_matrix_y_scale(&D_80121060, scaleY);
|
2022-10-24 15:37:47 +01:00
|
|
|
}
|
2022-12-10 22:42:50 +00:00
|
|
|
if (scale != 1.0f) {
|
|
|
|
|
f32_matrix_scale(&D_80121060, scale);
|
2022-10-24 15:37:47 +01:00
|
|
|
}
|
2022-11-30 16:49:33 -05:00
|
|
|
f32_matrix_mult(&D_80121060, D_80120D70[D_80120D1C], D_80120D70[D_80120D1C + 1]);
|
|
|
|
|
f32_matrix_mult(D_80120D70[D_80120D1C + 1], &D_80120F20, &D_801210A0);
|
2022-12-10 22:42:50 +00:00
|
|
|
f32_matrix_to_s16_matrix(&D_801210A0, *mtx);
|
2022-10-24 15:37:47 +01:00
|
|
|
D_80120D1C++;
|
2022-12-10 22:42:50 +00:00
|
|
|
D_80120D88[0, D_80120D1C] = *mtx; // Should be [D_80120D1C], but only matches with [0, D_80120D1C]
|
|
|
|
|
if (1) { } if (1) { } if (1) { }; // Fakematch
|
|
|
|
|
gSPMatrix((*dList)++, OS_PHYSICAL_TO_K0((*mtx)++), G_MTX_DKR_INDEX_1);
|
2022-10-24 15:37:47 +01:00
|
|
|
guMtxXFMF(*D_80120D70[D_80120D1C], 0.0f, 0.0f, 0.0f, &tempX, &tempY, &tempZ);
|
2022-11-20 23:37:50 +00:00
|
|
|
index = gActiveCameraID;
|
2022-10-24 15:37:47 +01:00
|
|
|
if (gCutsceneCameraActive) {
|
|
|
|
|
index += 4;
|
|
|
|
|
}
|
2022-11-20 23:37:50 +00:00
|
|
|
tempX = gActiveCameraStack[index].trans.x_position - tempX;
|
|
|
|
|
tempY = gActiveCameraStack[index].trans.y_position - tempY;
|
|
|
|
|
tempZ = gActiveCameraStack[index].trans.z_position - tempZ;
|
2023-01-23 12:54:17 +00:00
|
|
|
gCameraTransform.y_rotation = -trans->y_rotation;
|
|
|
|
|
gCameraTransform.x_rotation = -trans->x_rotation;
|
|
|
|
|
gCameraTransform.z_rotation = -trans->z_rotation;
|
|
|
|
|
gCameraTransform.x_position = 0.0f;
|
|
|
|
|
gCameraTransform.y_position = 0.0f;
|
|
|
|
|
gCameraTransform.z_position = 0.0f;
|
|
|
|
|
gCameraTransform.scale = 1.0f;
|
|
|
|
|
object_transform_to_matrix_2(D_80121060, &gCameraTransform);
|
2022-10-24 15:37:47 +01:00
|
|
|
guMtxXFMF(D_80121060, tempX, tempY, tempZ, &tempX, &tempY, &tempZ);
|
2022-12-10 22:42:50 +00:00
|
|
|
scaleFactor = 1.0f / trans->scale;
|
2022-10-24 15:37:47 +01:00
|
|
|
tempX *= scaleFactor;
|
|
|
|
|
tempY *= scaleFactor;
|
|
|
|
|
tempZ *= scaleFactor;
|
|
|
|
|
D_80120D20++;
|
|
|
|
|
index = D_80120D20;
|
|
|
|
|
D_80120D28[index] = tempX;
|
|
|
|
|
D_80120D40[index] = tempY;
|
|
|
|
|
if (0) {} // Necessary to match
|
|
|
|
|
D_80120D58[index] = tempZ;
|
|
|
|
|
}
|
|
|
|
|
|
2021-07-05 14:00:21 -05:00
|
|
|
GLOBAL_ASM("asm/non_matchings/camera/func_80069790.s")
|
2022-08-28 07:02:05 -04:00
|
|
|
|
2022-09-20 09:42:30 -04:00
|
|
|
UNUSED void func_800699E4(f32 *arg0, f32 *arg1, f32 *arg2) {
|
|
|
|
|
*arg0 = D_80120D28[D_80120D20];
|
|
|
|
|
*arg1 = D_80120D40[D_80120D20];
|
|
|
|
|
*arg2 = D_80120D58[D_80120D20];
|
|
|
|
|
}
|
|
|
|
|
|
2022-08-28 07:02:05 -04:00
|
|
|
void func_80069A40(Gfx **dlist) {
|
2022-09-20 09:42:30 -04:00
|
|
|
D_80120D20--;
|
2022-08-28 07:02:05 -04:00
|
|
|
D_80120D1C--;
|
2022-09-20 09:42:30 -04:00
|
|
|
|
2023-01-02 15:42:19 +00:00
|
|
|
{ s32 temp = D_80120D20; if ((temp && temp) != 0){} } // Fakematch
|
2022-09-20 09:42:30 -04:00
|
|
|
|
2022-08-28 07:02:05 -04:00
|
|
|
if (D_80120D1C > 0) {
|
|
|
|
|
gSPMatrix((*dlist)++, OS_PHYSICAL_TO_K0(D_80120D88[D_80120D1C]), G_MTX_DKR_INDEX_1);
|
|
|
|
|
}
|
2022-09-20 09:42:30 -04:00
|
|
|
else {
|
|
|
|
|
gDkrInsertMatrix((*dlist)++, G_MWO_MATRIX_XX_XY_I, 0);
|
|
|
|
|
}
|
2022-08-28 07:02:05 -04:00
|
|
|
}
|
|
|
|
|
|
2022-10-24 15:37:47 +01:00
|
|
|
UNUSED void func_80069ACC(f32 x, f32 y, f32 z) {
|
2022-11-20 23:37:50 +00:00
|
|
|
gActiveCameraStack[gActiveCameraID].trans.x_position += x;
|
|
|
|
|
gActiveCameraStack[gActiveCameraID].trans.y_position += y;
|
|
|
|
|
gActiveCameraStack[gActiveCameraID].trans.z_position += z;
|
|
|
|
|
gActiveCameraStack[gActiveCameraID].unk34_a.levelSegmentIndex =
|
2022-08-28 07:02:05 -04:00
|
|
|
get_level_segment_index_from_position(
|
2022-11-20 23:37:50 +00:00
|
|
|
gActiveCameraStack[gActiveCameraID].trans.x_position,
|
|
|
|
|
gActiveCameraStack[gActiveCameraID].trans.y_position,
|
|
|
|
|
gActiveCameraStack[gActiveCameraID].trans.z_position);
|
2022-08-28 07:02:05 -04:00
|
|
|
}
|
|
|
|
|
|
2022-10-24 15:37:47 +01:00
|
|
|
UNUSED void func_80069B70(f32 x, UNUSED f32 y, f32 z) {
|
2022-11-30 16:49:33 -05:00
|
|
|
gActiveCameraStack[gActiveCameraID].trans.x_position -= x * coss_f(gActiveCameraStack[gActiveCameraID].trans.y_rotation);
|
|
|
|
|
gActiveCameraStack[gActiveCameraID].trans.z_position -= x * sins_f(gActiveCameraStack[gActiveCameraID].trans.y_rotation);
|
|
|
|
|
gActiveCameraStack[gActiveCameraID].trans.x_position -= z * sins_f(gActiveCameraStack[gActiveCameraID].trans.y_rotation);
|
|
|
|
|
gActiveCameraStack[gActiveCameraID].trans.z_position += z * coss_f(gActiveCameraStack[gActiveCameraID].trans.y_rotation);
|
2022-11-20 23:37:50 +00:00
|
|
|
gActiveCameraStack[gActiveCameraID].unk34_a.levelSegmentIndex =
|
2022-08-28 07:02:05 -04:00
|
|
|
get_level_segment_index_from_position(
|
2022-11-20 23:37:50 +00:00
|
|
|
gActiveCameraStack[gActiveCameraID].trans.x_position,
|
|
|
|
|
gActiveCameraStack[gActiveCameraID].trans.y_position,
|
|
|
|
|
gActiveCameraStack[gActiveCameraID].trans.z_position);
|
2022-08-28 07:02:05 -04:00
|
|
|
}
|
|
|
|
|
|
2022-10-24 15:37:47 +01:00
|
|
|
UNUSED void func_80069CB4(s32 xRotation, s32 yRotation, s32 zRotation) {
|
2022-11-20 23:37:50 +00:00
|
|
|
gActiveCameraStack[gActiveCameraID].trans.y_rotation += xRotation;
|
|
|
|
|
gActiveCameraStack[gActiveCameraID].trans.x_rotation += yRotation;
|
|
|
|
|
gActiveCameraStack[gActiveCameraID].trans.z_rotation += zRotation;
|
2022-08-28 07:02:05 -04:00
|
|
|
}
|
2021-06-09 01:14:31 -05:00
|
|
|
|
2023-01-02 15:42:19 +00:00
|
|
|
/**
|
|
|
|
|
* Returns the segment data of the active camera, but won't apply the offset for cutscenes.
|
|
|
|
|
*/
|
|
|
|
|
ObjectSegment *get_active_camera_segment_no_cutscenes(void) {
|
2022-11-20 23:37:50 +00:00
|
|
|
return &gActiveCameraStack[gActiveCameraID];
|
2021-06-09 01:14:31 -05:00
|
|
|
}
|
|
|
|
|
|
2022-12-18 12:39:40 +00:00
|
|
|
/**
|
2023-01-02 15:42:19 +00:00
|
|
|
* Returns the segment data of the active camera.
|
2022-12-18 12:39:40 +00:00
|
|
|
*/
|
|
|
|
|
ObjectSegment *get_active_camera_segment(void) {
|
2022-10-24 15:37:47 +01:00
|
|
|
if (gCutsceneCameraActive) {
|
2022-11-20 23:37:50 +00:00
|
|
|
return &gActiveCameraStack[gActiveCameraID + 4];
|
2021-06-09 01:14:31 -05:00
|
|
|
}
|
2022-11-20 23:37:50 +00:00
|
|
|
return &gActiveCameraStack[gActiveCameraID];
|
2021-06-09 01:14:31 -05:00
|
|
|
}
|
|
|
|
|
|
2022-03-10 09:01:18 -05:00
|
|
|
ObjectSegment *func_80069D7C(void) {
|
2022-10-24 15:37:47 +01:00
|
|
|
if (gCutsceneCameraActive) {
|
2022-11-20 23:37:50 +00:00
|
|
|
return &gActiveCameraStack[4];
|
2021-06-09 01:14:31 -05:00
|
|
|
}
|
2022-11-20 23:37:50 +00:00
|
|
|
return &gActiveCameraStack[0];
|
2021-06-09 01:14:31 -05:00
|
|
|
}
|
|
|
|
|
|
2021-09-09 12:27:33 -04:00
|
|
|
Matrix *func_80069DA4(void) {
|
|
|
|
|
return &D_80120FA0;
|
2021-06-09 01:14:31 -05:00
|
|
|
}
|
|
|
|
|
|
2022-12-10 22:42:50 +00:00
|
|
|
MatrixS *func_80069DB0(void) {
|
2023-01-05 17:37:08 +00:00
|
|
|
return &gPerspectiveMatrixS;
|
2021-06-09 01:14:31 -05:00
|
|
|
}
|
|
|
|
|
|
2021-09-09 12:27:33 -04:00
|
|
|
Matrix *func_80069DBC(void) {
|
|
|
|
|
return &D_80120F60;
|
2021-06-09 01:14:31 -05:00
|
|
|
}
|
|
|
|
|
|
2021-09-09 13:42:13 -04:00
|
|
|
f32 func_80069DC8(f32 x, f32 y, f32 z) {
|
|
|
|
|
f32 ox, oy, oz;
|
|
|
|
|
|
|
|
|
|
guMtxXFMF(D_80120F60, x, y, z, &ox, &oy, &oz);
|
|
|
|
|
|
|
|
|
|
return oz;
|
2021-06-09 01:14:31 -05:00
|
|
|
}
|
|
|
|
|
|
2022-12-30 14:14:53 +00:00
|
|
|
/**
|
|
|
|
|
* Apply a shake to the camera based on the distance to the source.
|
|
|
|
|
*/
|
|
|
|
|
void set_camera_shake_by_distance(f32 x, f32 y, f32 z, f32 dist, f32 magnitude) {
|
|
|
|
|
f32 diffX;
|
|
|
|
|
f32 distance;
|
|
|
|
|
f32 diffZ;
|
|
|
|
|
f32 diffY;
|
2021-06-09 01:14:31 -05:00
|
|
|
s32 i;
|
2021-10-28 10:18:37 -04:00
|
|
|
|
2021-07-22 02:23:31 -05:00
|
|
|
for (i = 0; i <= gNumberOfViewports; i++) {
|
2022-12-30 14:14:53 +00:00
|
|
|
diffX = x - gActiveCameraStack[i].trans.x_position;
|
|
|
|
|
diffY = y - gActiveCameraStack[i].trans.y_position;
|
|
|
|
|
diffZ = z - gActiveCameraStack[i].trans.z_position;
|
|
|
|
|
distance = sqrtf(((diffX * diffX) + (diffY * diffY)) + (diffZ * diffZ));
|
|
|
|
|
if (distance < dist) {
|
|
|
|
|
gActiveCameraStack[i].unk30 = ((dist - distance) * magnitude) / dist;
|
2021-06-09 01:14:31 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-12-30 14:14:53 +00:00
|
|
|
/**
|
|
|
|
|
* Apply a shake to all active cameras.
|
|
|
|
|
*/
|
|
|
|
|
void set_camera_shake(f32 magnitude) {
|
2021-08-15 16:47:35 -05:00
|
|
|
s32 i;
|
2021-10-28 10:18:37 -04:00
|
|
|
for (i = 0; i <= gNumberOfViewports; i++) {
|
2022-12-30 14:14:53 +00:00
|
|
|
gActiveCameraStack[i].unk30 = magnitude;
|
2021-08-15 16:47:35 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-12-09 21:48:51 +00:00
|
|
|
/**
|
|
|
|
|
* Unused function that prints out the passed matrix values to the debug output.
|
|
|
|
|
* This function prints in fixed point.
|
|
|
|
|
*/
|
2022-08-28 07:02:05 -04:00
|
|
|
UNUSED void debug_print_fixed_matrix_values(s16 *mtx) {
|
2021-08-15 16:47:35 -05:00
|
|
|
s32 i, j;
|
|
|
|
|
s32 val;
|
2021-10-28 10:18:37 -04:00
|
|
|
for (i = 0; i < 4; i++) {
|
|
|
|
|
for (j = 0; j < 4; j++) {
|
2021-08-15 16:47:35 -05:00
|
|
|
val = mtx[i * 4 + j];
|
2021-09-29 08:46:57 -04:00
|
|
|
rmonPrintf("%x.", val);
|
2022-08-28 07:02:05 -04:00
|
|
|
val = mtx[((i + 4) * 4 + j)];
|
|
|
|
|
rmonPrintf("%x ", (u16)val & 0xFFFF);
|
2021-08-15 16:47:35 -05:00
|
|
|
}
|
2021-09-29 08:46:57 -04:00
|
|
|
rmonPrintf("\n");
|
2023-01-02 15:42:19 +00:00
|
|
|
if (!val){} // Fakematch
|
2021-08-15 16:47:35 -05:00
|
|
|
}
|
2021-09-29 08:46:57 -04:00
|
|
|
rmonPrintf("\n");
|
2021-08-15 16:47:35 -05:00
|
|
|
}
|
|
|
|
|
|
2021-12-09 21:48:51 +00:00
|
|
|
/**
|
|
|
|
|
* Unused function that prints out the passed matrix values to the debug output.
|
|
|
|
|
* This function prints in floating point.
|
|
|
|
|
*/
|
|
|
|
|
UNUSED void debug_print_float_matrix_values(f32 *mtx) {
|
2021-08-15 16:47:35 -05:00
|
|
|
s32 i, j;
|
2021-10-28 10:18:37 -04:00
|
|
|
|
|
|
|
|
for (i = 0; i < 4; i++) {
|
|
|
|
|
for (j = 0; j < 4; j++) {
|
2021-09-29 08:46:57 -04:00
|
|
|
rmonPrintf("%f ", mtx[i * 4 + j]);
|
2021-08-15 16:47:35 -05:00
|
|
|
}
|
2021-09-29 08:46:57 -04:00
|
|
|
rmonPrintf("\n");
|
2021-08-15 16:47:35 -05:00
|
|
|
}
|
2021-09-29 08:46:57 -04:00
|
|
|
rmonPrintf("\n");
|
2021-08-15 16:47:35 -05:00
|
|
|
}
|