mirror of
https://github.com/ACreTeam/ac-decomp
synced 2026-05-25 23:15:08 -04:00
2872 lines
85 KiB
C
2872 lines
85 KiB
C
#include "m_camera2.h"
|
|
|
|
#include "m_play.h"
|
|
#include "sys_math3d.h"
|
|
#include "MSL_C/math.h"
|
|
#include "c_keyframe.h"
|
|
#include "m_player_lib.h"
|
|
#include "m_room_type.h"
|
|
#include "m_collision_bg.h"
|
|
#include "m_scene_table.h"
|
|
#include "m_common_data.h"
|
|
|
|
#ifdef MUST_MATCH
|
|
#include "ppcdis.h"
|
|
#endif
|
|
|
|
static void Camera2_main_Normal_AdjustDistanceAndDirection(GAME_PLAY* play, f32* dist, s_xyz* dir);
|
|
static void Camera2_change_main_index(GAME_PLAY* play);
|
|
|
|
static void Camera2_DirectionCalc(GAME_PLAY* play) {
|
|
Camera2* camera = &play->camera;
|
|
xyz_t eye_minus_center;
|
|
s_xyz dir;
|
|
f32 mag;
|
|
|
|
xyz_t_sub(&camera->lookat.eye, &camera->lookat.center, &eye_minus_center);
|
|
dir = camera->direction;
|
|
mag = Math3d_normalizeXyz_t(&eye_minus_center);
|
|
|
|
if (fabsf(mag) < 0.008f) {
|
|
camera->direction.x = 0;
|
|
camera->direction.y = 0;
|
|
camera->direction.z = 0;
|
|
}
|
|
else {
|
|
camera->direction.x = RAD2SHORTANGLE(facos(eye_minus_center.y)) + (u16)SHT_MIN_S;
|
|
camera->direction.y = atans_table(eye_minus_center.z, eye_minus_center.x) + (u16)SHT_MIN_S;
|
|
camera->direction.z = 0;
|
|
}
|
|
|
|
camera->direction_velocity.x = camera->direction.x - dir.x;
|
|
camera->direction_velocity.y = camera->direction.y - dir.y;
|
|
camera->direction_velocity.z = camera->direction.z - dir.z;
|
|
}
|
|
|
|
static int Camera2_InDoorCheck() {
|
|
mActor_name_t field_id = mFI_GetFieldId();
|
|
int res = FALSE;
|
|
|
|
if (mFI_GET_TYPE(field_id) == mFI_FIELD_NPCROOM0 || mFI_GET_TYPE(field_id) == mFI_FIELD_ROOM0 || mFI_GET_TYPE(field_id) == mFI_FIELD_PLAYER0_ROOM) {
|
|
res = TRUE;
|
|
}
|
|
|
|
return res;
|
|
}
|
|
|
|
static int Camera2_CheckInDoorNearFar(GAME_PLAY* play) {
|
|
if (play->camera.indoor_distance_addition_idx == 0 || (Save_Get(scene_no) == SCENE_BROKER_SHOP && play->camera.now_main_index == CAMERA2_PROCESS_TALK)) {
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
static f32 Camera2_GetUnderBorderAdjust() {
|
|
if (Camera2_InDoorCheck()) {
|
|
return 0.0f;
|
|
}
|
|
else {
|
|
return -15.0f;
|
|
}
|
|
}
|
|
|
|
static void Camera2_PolaPosCalc(xyz_t* eye, s16 inv_dir_x, s16 inv_dir_y, xyz_t* center, f32 dist) {
|
|
//f32 dir_x = inv_dir_x;
|
|
//f32 dir_y = inv_dir_y;
|
|
|
|
f32 dist_x;
|
|
f32 inv_dir_x_f;
|
|
f32 inv_dir_y_f;
|
|
f32 x;
|
|
f32 y;
|
|
f32 z;
|
|
|
|
*eye = *center;
|
|
inv_dir_x_f = inv_dir_x * SHORTANGLE2RAD(1);
|
|
inv_dir_y_f = inv_dir_y * SHORTANGLE2RAD(1);
|
|
y = sin(inv_dir_x_f);
|
|
eye->y += dist * y;
|
|
x = cos(inv_dir_x_f);
|
|
dist_x = dist * x;
|
|
x = sin(inv_dir_y_f);
|
|
eye->x += dist_x * x;
|
|
z = cos(inv_dir_y_f);
|
|
eye->z += dist_x * z;
|
|
}
|
|
|
|
static void Camera2_SetEyePos_fromCenterPosCalc(GAME_PLAY* play, xyz_t* center, xyz_t* eye) {
|
|
Camera2_PolaPosCalc(eye, play->camera.direction.x + (u16)SHT_MIN_S, play->camera.direction.y + (u16)SHT_MIN_S, center, play->camera.focus_distance);
|
|
}
|
|
|
|
static void Camera2_SetEyePos_fromCenterPos(GAME_PLAY* play) {
|
|
Camera2* camera = &play->camera;
|
|
|
|
Camera2_SetEyePos_fromCenterPosCalc(play, &camera->lookat.center, &camera->lookat.eye);
|
|
}
|
|
|
|
static void Camera2_MoveDirectionAngleXYZ_morph(GAME_PLAY* play, const s_xyz* goal_dir, int delta) {
|
|
s_xyz* dir;
|
|
s_xyz* dir_vel;
|
|
Camera2* camera = &play->camera;
|
|
|
|
dir = &camera->direction;
|
|
dir_vel = &camera->direction_velocity;
|
|
|
|
if (delta == 0) {
|
|
dir->x = goal_dir->x;
|
|
dir->y = goal_dir->y;
|
|
dir->z = goal_dir->z;
|
|
|
|
dir_vel->x = 0;
|
|
dir_vel->y = 0;
|
|
dir_vel->z = 0;
|
|
}
|
|
else {
|
|
f32 t = 1.0f / (f32)delta;
|
|
s_xyz last_dir;
|
|
last_dir.x = dir->x;
|
|
last_dir.y = dir->y;
|
|
last_dir.z = dir->z;
|
|
|
|
cKF_SkeletonInfo_subRotInterpolation(t, &dir->x, last_dir.x, goal_dir->x); // order is wrong here
|
|
cKF_SkeletonInfo_subRotInterpolation(t, &dir->y, last_dir.y, goal_dir->y);
|
|
cKF_SkeletonInfo_subRotInterpolation(t, &dir->z, last_dir.z, goal_dir->z);
|
|
|
|
dir_vel->x = dir->x - last_dir.x;
|
|
dir_vel->y = dir->y - last_dir.y;
|
|
dir_vel->z = dir->z - last_dir.z;
|
|
}
|
|
}
|
|
|
|
static void Camera2_MoveDirectionAngleXYZ(GAME_PLAY* play, const s_xyz* goal_dir, int delta) {
|
|
Camera2* camera = &play->camera;
|
|
s_xyz* dir = &camera->direction;
|
|
s_xyz* dir_vel = &camera->direction_velocity;
|
|
|
|
if (delta != 0) {
|
|
dir->x = goal_dir->x;
|
|
dir->y = goal_dir->y;
|
|
dir->z = goal_dir->z;
|
|
|
|
dir_vel->x = 0;
|
|
dir_vel->y = 0;
|
|
dir_vel->z = 0;
|
|
}
|
|
else {
|
|
s_xyz last_dir;
|
|
s16 x = dir->x;
|
|
s16 y = dir->y;
|
|
s16 z = dir->z;
|
|
|
|
add_calc_short_angle2(&dir->x, goal_dir->x, 0.051316679f, 11000, 100);
|
|
add_calc_short_angle2(&dir->y, goal_dir->y, 0.051316679f, 11000, 75);
|
|
add_calc_short_angle2(&dir->z, goal_dir->z, 0.051316679f, 11000, 150);
|
|
|
|
dir_vel->x = dir->x - x;
|
|
dir_vel->y = dir->y - y;
|
|
dir_vel->z = dir->z - z;
|
|
}
|
|
}
|
|
|
|
static void Camera2_SetDirectionAngleXYZ(GAME_PLAY* play, s_xyz* goal_dir, int delta) {
|
|
Camera2* camera = &play->camera;
|
|
s_xyz* dir = &camera->direction;
|
|
s_xyz* dir_vel = &camera->direction_velocity;
|
|
|
|
if (delta != 0) {
|
|
*dir_vel = ZeroSVec;
|
|
}
|
|
else {
|
|
dir_vel->x = goal_dir->x - dir->x;
|
|
dir_vel->y = goal_dir->y - dir->y;
|
|
dir_vel->z = goal_dir->z - dir->z;
|
|
}
|
|
|
|
*dir = *goal_dir;
|
|
}
|
|
|
|
static void Camera2_SetView(GAME_PLAY* play) {
|
|
Camera2* camera = &play->camera;
|
|
xyz_t* eye;
|
|
View* view;
|
|
xyz_t* center;
|
|
xyz_t final_center;
|
|
xyz_t final_eye;
|
|
|
|
eye = &camera->lookat.eye;
|
|
view = &play->view;
|
|
center = &camera->lookat.center;
|
|
|
|
if (fabsf(Math3DLength(eye, center)) < 0.008f) {
|
|
eye->z = center->z + 1.0f;
|
|
}
|
|
|
|
if (Camera2_CheckInDoorNearFar(play)) {
|
|
camera->perspective.near = 20.0f;
|
|
camera->perspective.far = 1600.0f;
|
|
}
|
|
else {
|
|
if (camera->now_main_index != CAMERA2_PROCESS_LOCK) {
|
|
f32 dist_from_player = Math3DLength(eye, &get_player_actor_withoutCheck(play)->actor_class.world.position);
|
|
|
|
if (dist_from_player < 540.0f) {
|
|
chase_f(&camera->perspective.near, 145.0f, 4.0f);
|
|
}
|
|
else {
|
|
chase_f(&camera->perspective.near, 200.0f, 4.0f);
|
|
}
|
|
|
|
camera->perspective.far = 1600.0f;
|
|
}
|
|
}
|
|
|
|
if (fabsf(camera->perspective.fov_y) < 0.008f) {
|
|
camera->perspective.fov_y += 1.0f;
|
|
}
|
|
|
|
setScaleView(view, camera->perspective.scale);
|
|
setPerspectiveView(view, camera->perspective.fov_y, camera->perspective.near, camera->perspective.far);
|
|
xyz_t_add(center, &camera->offset_center, &final_center);
|
|
xyz_t_add(eye, &camera->offset_eye, &final_eye);
|
|
setLookAtView(view, &final_eye, &final_center, &camera->lookat.up);
|
|
}
|
|
|
|
static f32 Camera2_BorderSize() {
|
|
int type = mFI_GET_TYPE(mFI_GetFieldId());
|
|
f32 size = 110.0f;
|
|
|
|
switch (type) {
|
|
case mFI_FIELD_NPCROOM0:
|
|
size = 110.0f;
|
|
break;
|
|
case mFI_FIELD_ROOM0:
|
|
size = 110.0f;
|
|
break;
|
|
case mFI_FIELD_PLAYER0_ROOM:
|
|
size = 110.0f;
|
|
break;
|
|
}
|
|
|
|
return size;
|
|
}
|
|
|
|
static void Camera2_GetBorderScale(GAME_PLAY* play, f32 scale, f32* x_min, f32* x_max, f32* z_min, f32* z_max) {
|
|
static xyz_t local_border_base_pos = { 0.0f, 0.0f, 0.0f };
|
|
|
|
PLAYER_ACTOR* player = get_player_actor_withoutCheck(play);
|
|
xyz_t entrance_pos;
|
|
int block_x;
|
|
int block_z;
|
|
|
|
if (mRmTp_GetEntranceBasePosition(&entrance_pos) == FALSE) {
|
|
mFI_Wpos2BlockNum(&block_x, &block_z, player->actor_class.world.position);
|
|
mFI_LposInBKtoWpos(&entrance_pos, local_border_base_pos, block_x, block_z);
|
|
}
|
|
|
|
*x_min = entrance_pos.x + mFI_GetBlockWidth() - (scale * Camera2_BorderSize(play));
|
|
*x_max = entrance_pos.x + (scale * Camera2_BorderSize(play));
|
|
*z_max = mFI_GetBlockHeight() + (entrance_pos.z - (scale * (Camera2_BorderSize(play) + Camera2_GetUnderBorderAdjust())));
|
|
*z_min = entrance_pos.z + (scale * (Camera2_BorderSize(play) + mFI_UT_WORLDSIZE_Z_F));
|
|
|
|
if (Camera2_InDoorCheck()) {
|
|
*z_min += -mFI_UT_WORLDSIZE_Z_F;
|
|
}
|
|
}
|
|
|
|
static void Camera2_GetLongBorderScale(GAME_PLAY* play, f32* scale) {
|
|
if (play->camera.flags & 1) {
|
|
*scale = 1.5f;
|
|
}
|
|
else {
|
|
*scale = 1.0f;
|
|
}
|
|
}
|
|
|
|
static void Camera2_GetBorder(GAME_PLAY* play, f32* x0, f32* x1, f32* z0, f32* z1) {
|
|
f32 scale;
|
|
|
|
Camera2_GetLongBorderScale(play, &scale);
|
|
Camera2_GetBorderScale(play, scale, x0, x1, z0, z1);
|
|
}
|
|
|
|
static void Camera2_MoveCenterPosAndSpeed_fromEndCenterPos(GAME_PLAY* play, const xyz_t* end_center_pos, int force) {
|
|
Camera2* camera = &play->camera;
|
|
xyz_t* move_vel = &camera->movement_velocity;
|
|
xyz_t* center = &camera->lookat.center;
|
|
|
|
if (force) {
|
|
xyz_t_move(move_vel, &ZeroVec);
|
|
xyz_t_move(center, end_center_pos);
|
|
}
|
|
else {
|
|
xyz_t now_center = *center;
|
|
|
|
add_calc(¢er->x, end_center_pos->x, 0.13397461f, 8.75f, 0.25f);
|
|
add_calc(¢er->y, end_center_pos->y, 0.13397461f, 8.75f, 0.25f);
|
|
add_calc(¢er->z, end_center_pos->z, 0.13397461f, 8.75f, 0.25f);
|
|
|
|
xyz_t_sub(center, &now_center, move_vel); // set velocity
|
|
}
|
|
}
|
|
|
|
static void Camera2_SetCenterPosAndSpeed(GAME_PLAY* play, xyz_t* end_center_pos, int force) {
|
|
Camera2* camera = &play->camera;
|
|
xyz_t* move_vel = &camera->movement_velocity;
|
|
xyz_t* center = &camera->lookat.center;
|
|
|
|
if (force) {
|
|
xyz_t_move(move_vel, &ZeroVec);
|
|
}
|
|
else {
|
|
xyz_t_sub(end_center_pos, center, move_vel);
|
|
}
|
|
|
|
xyz_t_move(center, end_center_pos);
|
|
}
|
|
|
|
static void Camera2_SetDistancePosAndSpeed(GAME_PLAY* play, f32 end_distance, int force) {
|
|
Camera2* camera = &play->camera;
|
|
f32* distance = &camera->focus_distance;
|
|
f32* distance_vel = &camera->focus_distance_velocity;
|
|
|
|
if (force) {
|
|
*distance_vel = 0.0f;
|
|
}
|
|
else {
|
|
*distance_vel = end_distance - *distance;
|
|
}
|
|
|
|
*distance = end_distance;
|
|
}
|
|
|
|
static f32 Camera2_MoveDistancePosAndSpeed(GAME_PLAY* play, f32 end_distance, int force) {
|
|
Camera2* camera = &play->camera;
|
|
f32* distance = &camera->focus_distance;
|
|
f32* distance_vel = &camera->focus_distance_velocity;
|
|
f32 ret = 0.0f;
|
|
|
|
if (force) {
|
|
*distance = end_distance;
|
|
*distance_vel = 0.0f;
|
|
}
|
|
else {
|
|
f32 pre_dist = *distance;
|
|
|
|
ret = add_calc(distance, end_distance, 0.13397461f, 8.75f, 0.25f);
|
|
*distance_vel = *distance - pre_dist;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
static void Camera2_Get_PosBlockRatio(GAME_PLAY* play, xyz_t* pos, f32* x_ratio, f32* z_ratio) {
|
|
f32 x0;
|
|
f32 x1;
|
|
f32 z1;
|
|
f32 z0;
|
|
|
|
f32 x_center;
|
|
f32 z_center;
|
|
|
|
f32 x_r;
|
|
f32 z_l;
|
|
|
|
*z_ratio = 0.0f;
|
|
*x_ratio = 0.0f;
|
|
|
|
Camera2_GetBorder(play, &x0, &x1, &z0, &z1);
|
|
|
|
x_center = (x0 + x1) * 0.5f;
|
|
x_r = x_center - x1;
|
|
|
|
z_center = (z0 + z1) * 0.5f;
|
|
z_l = z_center - z0;
|
|
|
|
if (!F32_IS_ZERO(x_r)) {
|
|
*x_ratio = (pos->x - x_center) / x_r;
|
|
}
|
|
else {
|
|
*x_ratio = 0.0f;
|
|
}
|
|
|
|
if (*x_ratio > 1.0f) {
|
|
*x_ratio = 1.0f;
|
|
}
|
|
|
|
if (*x_ratio < -1.0f) {
|
|
*x_ratio = -1.0f;
|
|
}
|
|
|
|
if (!F32_IS_ZERO(z_l)) {
|
|
*z_ratio = (pos->z - z_center) / z_l;
|
|
}
|
|
else {
|
|
*z_ratio = 0.0f;
|
|
}
|
|
|
|
if (*z_ratio > 1.0f) {
|
|
*z_ratio = 1.0f;
|
|
}
|
|
|
|
if (*z_ratio < -1.0f) {
|
|
*z_ratio = -1.0f;
|
|
}
|
|
}
|
|
|
|
static void Camera2_Normal_Swing(GAME_PLAY* play, f32* distance, s_xyz* dir) {
|
|
xyz_t* pos = &get_player_actor_withoutCheck(play)->actor_class.eye.position;
|
|
f32 x_ratio;
|
|
f32 z_ratio;
|
|
int block_x;
|
|
int block_z;
|
|
|
|
Camera2_Get_PosBlockRatio(play, pos, &x_ratio, &z_ratio);
|
|
mFI_Wpos2BlockNum(&block_x, &block_z, *pos);
|
|
|
|
if (block_z == 1 && z_ratio < 0.0f) {
|
|
dir->x += (s16)(z_ratio * 250.0f);
|
|
}
|
|
}
|
|
|
|
static const f32 add_distance_array[3] = {
|
|
-280.0f,
|
|
0.0f,
|
|
300.0f
|
|
};
|
|
|
|
static const s16 add_directionY_array[3] = {
|
|
DEG2SHORT_ANGLE(-16.1f), // -2930
|
|
DEG2SHORT_ANGLE(0.0f), // 0
|
|
DEG2SHORT_ANGLE(16.1f), // 2930
|
|
};
|
|
|
|
static const s16 add_directionX_array[3] = {
|
|
DEG2SHORT_ANGLE(-23.24f), // -4230
|
|
DEG2SHORT_ANGLE(0.0f), // 0
|
|
DEG2SHORT_ANGLE(19.12f) // 3480
|
|
};
|
|
|
|
static void Camera2_Get_GoalDistanceAndDirection(GAME_PLAY* play, f32* dist, s_xyz* dir) {
|
|
static const f32 distance_array[CAMERA2_PROCESS_NUM] = {
|
|
620.0f, /* CAMERA2_PROCESS_STOP */
|
|
620.0f, /* CAMERA2_PROCESS_NORMAL */
|
|
620.0f, /* CAMERA2_PROCESS_WADE */
|
|
290.0f, /* CAMERA2_PROCESS_TALK */
|
|
620.0f, /* CAMERA2_PROCESS_DEMO */
|
|
620.0f, /* CAMERA2_PROCESS_ITEM */
|
|
620.0f, /* CAMERA2_PROCESS_LOCK */
|
|
620.0f, /* CAMERA2_PROCESS_DOOR */
|
|
620.0f, /* CAMERA2_PROCESS_SIMPLE */
|
|
290.0f, /* CAMERA2_PROCESS_CUST_TALK */
|
|
620.0f, /* CAMERA2_PROCESS_INTER */
|
|
620.0f, /* CAMERA2_PROCESS_STAFF_ROLL */
|
|
620.0f /* CAMERA2_PROCESS_INTER2 */
|
|
};
|
|
|
|
static const s_xyz direction_array[CAMERA2_PROCESS_NUM] = {
|
|
{ DEG2SHORT_ANGLE(-135.0f), DEG2SHORT_ANGLE(-180.0f), DEG2SHORT_ANGLE(0.0f) },
|
|
{ DEG2SHORT_ANGLE(-135.0f), DEG2SHORT_ANGLE(-180.0f), DEG2SHORT_ANGLE(0.0f) },
|
|
{ DEG2SHORT_ANGLE(-135.0f), DEG2SHORT_ANGLE(-180.0f), DEG2SHORT_ANGLE(0.0f) },
|
|
{ DEG2SHORT_ANGLE(-164.114f), DEG2SHORT_ANGLE(-180.0f), DEG2SHORT_ANGLE(0.0f) },
|
|
{ DEG2SHORT_ANGLE(-135.0f), DEG2SHORT_ANGLE(-180.0f), DEG2SHORT_ANGLE(0.0f) },
|
|
{ DEG2SHORT_ANGLE(-135.0f), DEG2SHORT_ANGLE(-180.0f), DEG2SHORT_ANGLE(0.0f) },
|
|
{ DEG2SHORT_ANGLE(-135.0f), DEG2SHORT_ANGLE(-180.0f), DEG2SHORT_ANGLE(0.0f) },
|
|
{ DEG2SHORT_ANGLE(-135.0f), DEG2SHORT_ANGLE(-180.0f), DEG2SHORT_ANGLE(0.0f) },
|
|
{ DEG2SHORT_ANGLE(-135.0f), DEG2SHORT_ANGLE(-180.0f), DEG2SHORT_ANGLE(0.0f) },
|
|
{ DEG2SHORT_ANGLE(-165.2125f), DEG2SHORT_ANGLE(-180.0f), DEG2SHORT_ANGLE(0.0f) },
|
|
{ DEG2SHORT_ANGLE(-135.0f), DEG2SHORT_ANGLE(-180.0f), DEG2SHORT_ANGLE(0.0f) },
|
|
{ DEG2SHORT_ANGLE(-135.0f), DEG2SHORT_ANGLE(-180.0f), DEG2SHORT_ANGLE(0.0f) },
|
|
{ DEG2SHORT_ANGLE(-135.0f), DEG2SHORT_ANGLE(-180.0f), DEG2SHORT_ANGLE(0.0f) },
|
|
};
|
|
|
|
Camera2* camera = &play->camera;
|
|
int main_index = camera->now_main_index;
|
|
int add_dist_idx = camera->indoor_distance_addition_idx;
|
|
int add_dir_idx = camera->indoor_direction_addition_idx;
|
|
|
|
if (main_index < 0 || main_index >= CAMERA2_PROCESS_NUM) {
|
|
main_index = 0;
|
|
}
|
|
|
|
*dist = distance_array[main_index];
|
|
*dir = direction_array[main_index];
|
|
|
|
if (main_index == CAMERA2_PROCESS_NORMAL && Camera2_InDoorCheck()) {
|
|
if (add_dist_idx < 0 || add_dist_idx >= 3) {
|
|
add_dist_idx = 1;
|
|
}
|
|
|
|
if (add_dir_idx < 0 || add_dir_idx >= 3) {
|
|
add_dir_idx = 1;
|
|
}
|
|
|
|
*dist += add_distance_array[add_dist_idx];
|
|
dir->y += add_directionY_array[add_dir_idx];
|
|
dir->x += add_directionX_array[add_dist_idx]; // adjust by add_dist_idx since rotation on X axis should be defined by distance of camera
|
|
}
|
|
|
|
if (main_index == CAMERA2_PROCESS_NORMAL || main_index == CAMERA2_PROCESS_WADE) {
|
|
if (Camera2_InDoorCheck() == FALSE && (camera->flags & 1) == 0) {
|
|
Camera2_Normal_Swing(play, dist, dir);
|
|
}
|
|
}
|
|
|
|
Camera2_main_Normal_AdjustDistanceAndDirection(play, dist, dir);
|
|
}
|
|
|
|
static void Camera2_SetPos_fromStartEnd(GAME_PLAY* play, const xyz_t* start, const xyz_t* end, f32 now_time, f32 end_time) {
|
|
Camera2* camera = &play->camera;
|
|
f32 percent = get_percent_forAccelBrake(now_time, 0.0f, end_time, 1.1999999f, 34.8f);
|
|
xyz_t center = camera->lookat.center;
|
|
xyz_t* center_p = &camera->lookat.center;
|
|
xyz_t* move_vel_p = &camera->movement_velocity;
|
|
xyz_t goal;
|
|
f32 dist;
|
|
s_xyz dir;
|
|
|
|
if (percent >= 1.0f) {
|
|
goal = *end;
|
|
}
|
|
else {
|
|
f32 x = start->x;
|
|
f32 y = start->y;
|
|
f32 z = start->z;
|
|
|
|
x = start->x + percent * (end->x - x);
|
|
y = start->y + percent * (end->y - y);
|
|
z = start->z + percent * (end->z - z);
|
|
|
|
goal.x = x;
|
|
goal.y = y;
|
|
goal.z = z;
|
|
}
|
|
|
|
*center_p = goal;
|
|
xyz_t_sub(&goal, ¢er, move_vel_p);
|
|
Camera2_Get_GoalDistanceAndDirection(play, &dist, &dir);
|
|
Camera2_MoveDistancePosAndSpeed(play, dist, FALSE);
|
|
Camera2_MoveDirectionAngleXYZ_morph(play, &dir, end_time - now_time);
|
|
Camera2_SetEyePos_fromCenterPos(play);
|
|
Camera2_SetView(play);
|
|
}
|
|
|
|
static void Camera2_setup_main_Base(GAME_PLAY* play) {
|
|
play->camera.last_main_index = play->camera.now_main_index;
|
|
play->camera.now_main_index = play->camera.requested_main_index;
|
|
play->camera.requested_main_index_flag = FALSE;
|
|
}
|
|
|
|
extern s16 getCamera2AngleY(GAME_PLAY* play) {
|
|
return play->camera.direction.y;
|
|
}
|
|
|
|
static int Camera2_check_request_main_priority(GAME_PLAY* play, int priority) {
|
|
return priority - play->camera.requested_main_index_priority;
|
|
}
|
|
|
|
extern int Camera2_change_priority(GAME_PLAY* play, int priority) {
|
|
play->camera.requested_main_index_priority = priority;
|
|
return TRUE;
|
|
}
|
|
|
|
static void Camera2_request_main_index(GAME_PLAY* play, int main_index, int priority) {
|
|
play->camera.requested_main_index = main_index;
|
|
play->camera.requested_main_index_priority = priority;
|
|
play->camera.requested_main_index_flag = TRUE;
|
|
}
|
|
|
|
static void Camera2_ChangeCameraPos_inBlock(GAME_PLAY* play, const xyz_t* pos, xyz_t* end_pos) {
|
|
f32 x0;
|
|
f32 x1;
|
|
f32 z0;
|
|
f32 z1;
|
|
|
|
f32 x00;
|
|
f32 x01;
|
|
f32 z00;
|
|
f32 z01;
|
|
|
|
f32 scale;
|
|
|
|
Camera2_GetLongBorderScale(play, &scale);
|
|
Camera2_GetBorder(play, &x0, &x1, &z1, &z0);
|
|
Camera2_GetBorderScale(play, 1.0f, &x00, &x01, &z01, &z00);
|
|
|
|
*end_pos = *pos;
|
|
|
|
if (pos->x < x1) {
|
|
if (pos->x < x1 - scale * Camera2_BorderSize(play)) {
|
|
end_pos->x = x1 - (scale + 1.0f) * Camera2_BorderSize(play);
|
|
}
|
|
else if (end_pos->x < x01) {
|
|
end_pos->x = x01;
|
|
}
|
|
}
|
|
else if (pos->x > x0) {
|
|
if (pos->x > x0 + scale * Camera2_BorderSize(play)) {
|
|
end_pos->x = x0 + (scale + 1.0f) * Camera2_BorderSize(play);
|
|
}
|
|
else if (end_pos->x > x00) {
|
|
end_pos->x = x00;
|
|
}
|
|
}
|
|
|
|
if (pos->z < z1) {
|
|
if (pos->z < z1 - scale * (Camera2_BorderSize(play) + mFI_UT_WORLDSIZE_Z_F)) {
|
|
end_pos->z = (z1 - ((scale + 1.0f) * Camera2_BorderSize(play)) - (scale * mFI_UT_WORLDSIZE_Z_F)) - Camera2_GetUnderBorderAdjust();
|
|
}
|
|
else if (end_pos->z < z01) {
|
|
end_pos->z = z01;
|
|
}
|
|
}
|
|
else if (pos->z > z0) {
|
|
if (pos->z > scale * (Camera2_BorderSize(play) + Camera2_GetUnderBorderAdjust() + z0)) {
|
|
end_pos->z = (z0 + (scale + 1.0f) * Camera2_BorderSize(play) + mFI_UT_WORLDSIZE_Z_F) + scale * Camera2_GetUnderBorderAdjust();
|
|
}
|
|
else if (end_pos->z > z00) {
|
|
end_pos->z = z00;
|
|
}
|
|
}
|
|
}
|
|
|
|
extern xyz_t* Camera2_getEyePos_p() {
|
|
return &((GAME_PLAY*)gamePT)->camera.lookat.eye;
|
|
}
|
|
|
|
extern xyz_t* Camera2_getCenterPos_p() {
|
|
return &((GAME_PLAY*)gamePT)->camera.lookat.center;
|
|
}
|
|
|
|
static void Camera2_SetCameraParameter(GAME_PLAY* play, xyz_t* center_pos, s_xyz* dir, int force, f32 dist) {
|
|
Camera2_SetCenterPosAndSpeed(play, center_pos, force);
|
|
Camera2_SetDistancePosAndSpeed(play, dist, force);
|
|
Camera2_SetDirectionAngleXYZ(play, dir, force);
|
|
Camera2_SetEyePos_fromCenterPos(play);
|
|
}
|
|
|
|
extern int Camera2_CheckCullingMode() {
|
|
GAME_PLAY* play = (GAME_PLAY*)gamePT;
|
|
Camera2* camera = &play->camera;
|
|
int main_index = camera->now_main_index;
|
|
|
|
if (main_index == CAMERA2_PROCESS_TALK) {
|
|
if (camera->main_data.talk.cull_timer >= 15.0f) {
|
|
return TRUE;
|
|
}
|
|
}
|
|
else if (main_index == CAMERA2_PROCESS_ITEM) {
|
|
if (camera->main_data.item.cull_timer >= 6.0f) {
|
|
return TRUE;
|
|
}
|
|
}
|
|
else if (main_index == CAMERA2_PROCESS_DOOR) {
|
|
if (camera->main_data.door.morph_counter < 70) {
|
|
return TRUE;
|
|
}
|
|
}
|
|
else if (main_index == CAMERA2_PROCESS_CUST_TALK) {
|
|
if (camera->main_data.cust_talk.cull_timer >= 15.0f) {
|
|
return TRUE;
|
|
}
|
|
}
|
|
else if (main_index == CAMERA2_PROCESS_SIMPLE) {
|
|
CameraSimple* simple = &camera->main_data.simple;
|
|
|
|
if (simple->mode == 1 && simple->cull_timer >= 6.0f) {
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
static int pos_cull_check(const xyz_t *pos, const f32 pos_x, const f32 pos_z, f32 width, const f32 size_x, const f32 size_z) {
|
|
GAME_PLAY *play = (GAME_PLAY *) gamePT;
|
|
f32 pos_left;
|
|
f32 x;
|
|
f32 eye_left;
|
|
f32 eye_right;
|
|
f32 pos_right;
|
|
|
|
width += size_x;
|
|
|
|
if ((play->camera.lookat.center.z + size_z) <= pos_z) {
|
|
eye_left = play->camera.lookat.eye.x - width;
|
|
eye_right = play->camera.lookat.eye.x + width;
|
|
|
|
x = pos->x;
|
|
pos_left = x - width;
|
|
pos_right = x + width;
|
|
|
|
if (pos_left > eye_left) {
|
|
pos_left = eye_left;
|
|
}
|
|
|
|
if (pos_right < eye_right) {
|
|
pos_right = eye_right;
|
|
}
|
|
|
|
if ((pos_left <= pos_x) && (pos_x <= pos_right)) {
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
extern int Camera2_CheckEnterCullingArea(f32 pos_x, f32 pos_z, f32 width) {
|
|
GAME_PLAY* play = (GAME_PLAY*)gamePT;
|
|
Camera2* camera = &play->camera;
|
|
int main_index = camera->now_main_index;
|
|
f32 center_z = camera->lookat.center.z;
|
|
|
|
if (main_index == CAMERA2_PROCESS_SIMPLE) {
|
|
return pos_cull_check(&camera->main_data.simple.center_pos, pos_x, pos_z, width, 50.0f, -50.0f);
|
|
}
|
|
else {
|
|
ACTOR* actor0;
|
|
ACTOR* actor1;
|
|
|
|
if (main_index == CAMERA2_PROCESS_TALK) {
|
|
actor0 = camera->main_data.talk.speaker_actor;
|
|
actor1 = camera->main_data.talk.listener_actor;
|
|
}
|
|
else {
|
|
actor1 = &get_player_actor_withoutCheck(play)->actor_class;
|
|
actor0 = actor1;
|
|
}
|
|
|
|
if (center_z <= pos_z && (actor0 != NULL || actor1 != NULL)) {
|
|
f32 x0;
|
|
f32 x1;
|
|
f32 fx;
|
|
f32 eye_left = camera->lookat.eye.x - width;
|
|
f32 eye_right = camera->lookat.eye.x + width;
|
|
|
|
f32 t0;
|
|
f32 t1;
|
|
|
|
if (actor0 == NULL) {
|
|
x0 = actor1->world.position.x;
|
|
x1 = x0;
|
|
}
|
|
else if (actor1 == NULL) {
|
|
x1 = actor0->world.position.x;
|
|
x0 = x1;
|
|
}
|
|
else {
|
|
x0 = actor0->world.position.x;
|
|
x1 = actor1->world.position.x;
|
|
}
|
|
|
|
if (main_index == CAMERA2_PROCESS_TALK) {
|
|
CameraTalk* talk = &camera->main_data.talk;
|
|
|
|
if (talk->flags & 2) {
|
|
x1 = talk->listener_pos.x;
|
|
}
|
|
}
|
|
|
|
if (x0 > x1) {
|
|
fx = x1;
|
|
}
|
|
else {
|
|
fx = x0;
|
|
x0 = x1;
|
|
}
|
|
|
|
fx -= width;
|
|
x0 += width;
|
|
|
|
if (fx > eye_left) {
|
|
fx = eye_left;
|
|
}
|
|
|
|
if (x0 < eye_right) {
|
|
x0 = eye_right;
|
|
}
|
|
|
|
if (fx <= pos_x && pos_x <= x0) {
|
|
return TRUE;
|
|
}
|
|
}
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
extern void Camera2_ClearActorTalking_Cull(GAME_PLAY* play) {
|
|
Actor_list* actor_list;
|
|
ACTOR* actor;
|
|
int i;
|
|
|
|
actor_list = play->actor_info.list;
|
|
for (i = 0; i < ACTOR_PART_NUM; i++) {
|
|
for (actor = actor_list->actor; actor != NULL; actor = actor->next_actor) {
|
|
actor->cull_while_talking = FALSE;
|
|
}
|
|
|
|
actor_list++;
|
|
}
|
|
}
|
|
|
|
static void Camera2_AddCullTimer(f32* cull_timer, f32 max) {
|
|
*cull_timer += 1.0f;
|
|
|
|
if (*cull_timer > max) {
|
|
*cull_timer = max;
|
|
}
|
|
}
|
|
|
|
extern int Camera2_Check_main_index(GAME_PLAY* play, int main_index) {
|
|
return play->camera.now_main_index == main_index;
|
|
}
|
|
|
|
extern xyz_t* Camera2_getMicPos_p(GAME_PLAY* play) {
|
|
return &play->camera.mic_pos;
|
|
}
|
|
|
|
static int Camera2_Check_MicPosFix() {
|
|
static const s8 data[SCENE_NUM] = {
|
|
TRUE, TRUE, TRUE, TRUE,
|
|
TRUE, TRUE, FALSE, TRUE,
|
|
TRUE, FALSE, TRUE, TRUE,
|
|
FALSE, FALSE, FALSE, TRUE,
|
|
TRUE, FALSE, FALSE, TRUE,
|
|
FALSE, FALSE, FALSE, FALSE,
|
|
FALSE, FALSE, TRUE, TRUE,
|
|
TRUE, FALSE, TRUE, FALSE,
|
|
TRUE, TRUE, TRUE, FALSE,
|
|
FALSE, FALSE, FALSE, FALSE,
|
|
FALSE, FALSE, FALSE, FALSE,
|
|
FALSE, FALSE, FALSE, FALSE,
|
|
FALSE, TRUE, FALSE, FALSE
|
|
};
|
|
|
|
int scene = Save_Get(scene_no);
|
|
if (scene < 0 || scene >= SCENE_NUM) {
|
|
return TRUE;
|
|
}
|
|
|
|
return data[scene];
|
|
}
|
|
|
|
#ifndef MUST_MATCH
|
|
/* @nonmatching - regswaps */
|
|
static void Camera2_SetMicPos(GAME_PLAY* play) {
|
|
PLAYER_ACTOR* player = get_player_actor_withoutCheck(play);
|
|
Camera2* camera = &play->camera;
|
|
xyz_t* mic_pos;
|
|
|
|
if (player != NULL) {
|
|
if (Camera2_Check_MicPosFix()) {
|
|
f32 z;
|
|
f32 x;
|
|
|
|
z = cos_s(0) * 77.0f;
|
|
x = sin_s(0) * 77.0f;
|
|
mic_pos = Camera2_getMicPos_p(play);
|
|
|
|
mic_pos->x = player->actor_class.world.position.x + x;
|
|
mic_pos->y = player->actor_class.world.position.y + 240.0f;
|
|
mic_pos->z = player->actor_class.world.position.z + z;
|
|
}
|
|
else {
|
|
s_xyz* dir = &camera->direction;
|
|
f32 x0;
|
|
f32 x;
|
|
f32 t;
|
|
f32 p;
|
|
f32 y;
|
|
f32 z;
|
|
s16 s;
|
|
s16 s2;
|
|
|
|
x0 = (camera->lookat.eye.y - player->actor_class.world.position.y) - 472.0f;
|
|
t = (x0 * 0.796f) + 261.0f;
|
|
s = dir->x;
|
|
x = t * cos_s(s);
|
|
y = t * sin_s(s);
|
|
|
|
switch (Save_Get(scene_no)) {
|
|
case SCENE_MY_ROOM_S:
|
|
p = 100.0f;
|
|
break;
|
|
|
|
case SCENE_POLICE_BOX:
|
|
case SCENE_MY_ROOM_L:
|
|
case SCENE_CONVENI:
|
|
case SCENE_SUPER:
|
|
case SCENE_DEPART:
|
|
case SCENE_DEPART_2:
|
|
p = 190.0f;
|
|
break;
|
|
|
|
default:
|
|
p = 150.0f;
|
|
break;
|
|
}
|
|
|
|
p += x0 * -0.186f;
|
|
t = ABS(x) + p;
|
|
s2 = dir->y;
|
|
z = t * cos_s(s2);
|
|
x = t * sin_s(s2);
|
|
mic_pos = Camera2_getMicPos_p(play);
|
|
|
|
mic_pos->x = camera->lookat.eye.x + x;
|
|
mic_pos->y = camera->lookat.eye.y + y;
|
|
mic_pos->z = camera->lookat.eye.z + z;
|
|
}
|
|
}
|
|
}
|
|
#else
|
|
#pragma force_active on
|
|
|
|
extern f32 lbl_80641440;
|
|
REL_SYMBOL_AT(lbl_80641440, 0x80641440);
|
|
|
|
/*
|
|
extern f32 lbl_8064158c;
|
|
REL_SYMBOL_AT(lbl_8064158c, 0x8064158c);
|
|
|
|
extern f32 lbl_80641590;
|
|
REL_SYMBOL_AT(lbl_80641590, 0x80641590);
|
|
|
|
extern f32 lbl_80641594;
|
|
REL_SYMBOL_AT(lbl_80641594, 0x80641594);
|
|
|
|
extern f32 lbl_80641598;
|
|
REL_SYMBOL_AT(lbl_80641598, 0x80641598);
|
|
|
|
extern f32 lbl_8064159c;
|
|
REL_SYMBOL_AT(lbl_8064159c, 0x8064159c);
|
|
|
|
extern f32 lbl_806415a0;
|
|
REL_SYMBOL_AT(lbl_806415a0, 0x806415a0);
|
|
|
|
extern f32 lbl_806415a4;
|
|
REL_SYMBOL_AT(lbl_806415a4, 0x806415a4);
|
|
|
|
extern f32 lbl_806415a8;
|
|
REL_SYMBOL_AT(lbl_806415a8, 0x806415a8);
|
|
|
|
extern f32 lbl_806415ac;
|
|
REL_SYMBOL_AT(lbl_806415ac, 0x806415ac);
|
|
*/
|
|
|
|
#pragma force_active reset
|
|
|
|
#include "jumptable/8064f824.inc"
|
|
#include "orderfloats/8064158c_806415b0.inc"
|
|
|
|
static asm void Camera2_SetMicPos(GAME_PLAY* play) {
|
|
#include "asm/8037f2e8.s"
|
|
}
|
|
|
|
#endif
|
|
|
|
extern int Camera2NormalState_get(GAME_PLAY* play) {
|
|
Camera2* camera = &play->camera;
|
|
const s16 inv_dir_y = camera->direction.y + 0x8000;
|
|
const s16 dir_vel_y = camera->direction_velocity.y;
|
|
const int scene = Save_Get(scene_no);
|
|
int state = 0;
|
|
|
|
if (scene == SCENE_MUSEUM_ROOM_INSECT || scene == SCENE_MUSEUM_ROOM_FISH) {
|
|
if (camera->now_main_index == CAMERA2_PROCESS_NORMAL) {
|
|
if (dir_vel_y == 0) {
|
|
if (inv_dir_y == 0) {
|
|
state = 2;
|
|
}
|
|
else if (inv_dir_y > 0) {
|
|
state = 1;
|
|
}
|
|
else {
|
|
state = 3;
|
|
}
|
|
}
|
|
else if (dir_vel_y < 0) {
|
|
if (inv_dir_y <= 0) {
|
|
state = 7;
|
|
}
|
|
else {
|
|
state = 4;
|
|
}
|
|
}
|
|
else if (inv_dir_y < 0) {
|
|
state = 6;
|
|
}
|
|
else {
|
|
state = 5;
|
|
}
|
|
}
|
|
}
|
|
|
|
return state;
|
|
}
|
|
|
|
static void Camera2_sound_Set_Ground(GAME_PLAY* play) { }
|
|
|
|
static void Camera2_process_other_func2(GAME_PLAY* play) { }
|
|
|
|
static void Camera2_setup_main_Stop(GAME_PLAY* play) { }
|
|
|
|
static void Camera2_main_Stop(GAME_PLAY* play) { }
|
|
|
|
extern int Camera2_request_main_wade(GAME_PLAY* play, xyz_t* pos, int priority, f32 goal_time) {
|
|
Camera2* camera = &play->camera;
|
|
xyz_t goal_pos;
|
|
int res = FALSE;
|
|
|
|
if (Camera2_check_request_main_priority(play, priority) > 0) {
|
|
Camera2_ChangeCameraPos_inBlock(play, pos, &goal_pos);
|
|
camera->request_data.wade.goal_pos = goal_pos;
|
|
camera->request_data.wade.goal_time = goal_time;
|
|
Camera2_request_main_index(play, CAMERA2_PROCESS_WADE, priority);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
static void Camera2_setup_main_Wade(GAME_PLAY* play) {
|
|
play->camera.main_data.wade.timer = 0.0f;
|
|
play->camera.main_data.wade.start_pos = play->camera.lookat.center;
|
|
play->camera.main_data.wade.goal_pos = play->camera.request_data.wade.goal_pos;
|
|
play->camera.main_data.wade.goal_time = play->camera.request_data.wade.goal_time;
|
|
|
|
Camera2_setup_main_Base(play);
|
|
play->camera.requested_main_index_priority = 9;
|
|
}
|
|
|
|
static void Camera2_SetPos_Wade(GAME_PLAY* play) {
|
|
Camera2_SetPos_fromStartEnd(
|
|
play,
|
|
&play->camera.main_data.wade.start_pos, &play->camera.main_data.wade.goal_pos,
|
|
play->camera.main_data.wade.timer, play->camera.main_data.wade.goal_time
|
|
);
|
|
}
|
|
|
|
static void Camera2_request_proc_index_fromWade(GAME_PLAY* play) {
|
|
play->camera.main_data.wade.timer += 1.0f;
|
|
|
|
if (play->camera.main_data.wade.timer > play->camera.main_data.wade.goal_time) {
|
|
play->camera.requested_main_index_priority = 0;
|
|
Camera2_request_main_normal(play, 0, 5);
|
|
}
|
|
}
|
|
|
|
static void Camera2_main_Wade(GAME_PLAY* play) {
|
|
Camera2_SetPos_Wade(play);
|
|
Camera2_sound_Set_Ground(play);
|
|
Camera2_SetMicPos(play);
|
|
Camera2_request_proc_index_fromWade(play);
|
|
Camera2_change_main_index(play);
|
|
}
|
|
|
|
extern int Camera2_request_main_talk(GAME_PLAY* play, ACTOR* speaker, ACTOR* listener, int priority) {
|
|
if (Camera2_check_request_main_priority(play, priority) > 0) {
|
|
play->camera.request_data.talk.speaker_actor = speaker;
|
|
play->camera.request_data.talk.listener_actor = listener;
|
|
|
|
if (listener != NULL) {
|
|
xyz_t_move(&play->camera.request_data.talk.listener_pos, &listener->eye.position);
|
|
}
|
|
else {
|
|
xyz_t_move(&play->camera.request_data.talk.listener_pos, &ZeroVec);
|
|
}
|
|
|
|
play->camera.request_data.talk.flags = 0;
|
|
Camera2_request_main_index(play, CAMERA2_PROCESS_TALK, priority);
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
extern int Camera2_request_main_talk_pos(GAME_PLAY* play, ACTOR* speaker, xyz_t* listener_pos, int priority) {
|
|
if (
|
|
(play->camera.now_main_index == CAMERA2_PROCESS_TALK || play->camera.requested_main_index == CAMERA2_PROCESS_TALK) &&
|
|
(Math3DLength(&play->camera.request_data.talk.listener_pos, listener_pos) < 1.0f)
|
|
) {
|
|
return FALSE;
|
|
}
|
|
else {
|
|
if (Camera2_check_request_main_priority(play, priority) > 0) {
|
|
play->camera.request_data.talk.speaker_actor = speaker;
|
|
play->camera.request_data.talk.listener_actor = NULL;
|
|
play->camera.request_data.talk.listener_pos = *listener_pos;
|
|
play->camera.request_data.talk.flags = 1;
|
|
Camera2_request_main_index(play, CAMERA2_PROCESS_TALK, priority);
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
static void Camera2_setup_main_Talk(GAME_PLAY* play) {
|
|
play->camera.main_data.talk.speaker_actor = play->camera.request_data.talk.speaker_actor;
|
|
play->camera.main_data.talk.listener_actor = play->camera.request_data.talk.listener_actor;
|
|
play->camera.main_data.talk.listener_pos = play->camera.request_data.talk.listener_pos;
|
|
play->camera.main_data.talk.cull_timer = 0.0f;
|
|
play->camera.main_data.talk.flags = (play->camera.request_data.talk.flags & 1) ? 2 : 0;
|
|
Camera2_setup_main_Base(play);
|
|
play->camera.requested_main_index_priority = 0;
|
|
}
|
|
|
|
static void Camera2_Talk_ChangeCameraCenterPos_BetweenSpeakerToListener(GAME_PLAY* play, ACTOR* speaker, ACTOR* listener, f32 dist) {
|
|
xyz_t* pos0;
|
|
xyz_t* pos1;
|
|
xyz_t end_center_pos;
|
|
f32 y_adjust;
|
|
|
|
if (speaker != NULL || listener != NULL) {
|
|
if (speaker == NULL) {
|
|
pos0 = &listener->eye.position;
|
|
pos1 = pos0;
|
|
}
|
|
else if (listener == NULL) {
|
|
pos1 = &speaker->eye.position;
|
|
pos0 = pos1;
|
|
}
|
|
else {
|
|
pos1 = &listener->eye.position;
|
|
pos0 = &speaker->eye.position;
|
|
}
|
|
|
|
if (play->camera.main_data.talk.flags & 2) {
|
|
pos1 = &play->camera.main_data.talk.listener_pos;
|
|
}
|
|
|
|
y_adjust = 17.0f;
|
|
if (!F32_IS_ZERO(dist)) {
|
|
y_adjust -= -60.0f / dist;
|
|
}
|
|
|
|
end_center_pos.x = (pos0->x + pos1->x) * 0.5f;
|
|
end_center_pos.y = (pos0->y + pos1->y) * 0.5f - y_adjust;
|
|
end_center_pos.z = (pos0->z + pos1->z) * 0.5f;
|
|
|
|
play->camera.main_data.talk.goal_center_pos = end_center_pos;
|
|
Camera2_MoveCenterPosAndSpeed_fromEndCenterPos(play, &end_center_pos, FALSE);
|
|
}
|
|
}
|
|
|
|
static int Camera2_TalkCheckCliffLRRange(GAME_PLAY* play, int left_ut_x, int right_ut_x, int ut_z, f32 height) {
|
|
int i;
|
|
|
|
for (i = left_ut_x; i < right_ut_x + 1; i++) {
|
|
u32 attribute = mCoBG_UtNum2BgAttr(i, ut_z);
|
|
f32 center_y = mCoBG_UtNum2UtCenterY(i, ut_z);
|
|
|
|
if ((mCoBG_CheckCliffAttr(attribute) && center_y > height + 30.0f) || center_y > height + 230.0f) {
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
static int Camera2_Talk_CheckCliffLR(GAME_PLAY* play, const xyz_t* pos) {
|
|
int ut_x;
|
|
int ut_z;
|
|
|
|
int l_ut_x;
|
|
int r_ut_x;
|
|
|
|
mFI_Wpos2UtNum(&ut_x, &ut_z, *pos); // weirdness going on here with the struct copy
|
|
l_ut_x = ut_x - 4;
|
|
if (l_ut_x < 0) {
|
|
l_ut_x = 0;
|
|
}
|
|
|
|
r_ut_x = ut_x + 4;
|
|
|
|
if (
|
|
Camera2_TalkCheckCliffLRRange(play, l_ut_x, r_ut_x, ut_z, pos->y) ||
|
|
Camera2_TalkCheckCliffLRRange(play, l_ut_x, r_ut_x, ut_z + 3, pos->y) ||
|
|
Camera2_TalkCheckCliffLRRange(play, l_ut_x, r_ut_x, ut_z + 6, pos->y)
|
|
) {
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
static int Camera2_Talk_NoLowAngleCheck(GAME_PLAY* play, const xyz_t* pos) {
|
|
int block_x;
|
|
int block_z;
|
|
int ut_x;
|
|
int ut_z;
|
|
|
|
if (Camera2_InDoorCheck()) {
|
|
return FALSE;
|
|
}
|
|
|
|
mFI_Wpos2BkandUtNuminBlock(&block_x, &block_z, &ut_x, &ut_z, *pos); /* ??? why is this here */
|
|
return Camera2_Talk_CheckCliffLR(play, pos) != FALSE;
|
|
}
|
|
|
|
static void Camera2_Talk_GetAngleY(GAME_PLAY* play, ACTOR* speaker, ACTOR* listener, s_xyz* goal_dir, f32 dist_between) {
|
|
int angle;
|
|
s16 angle_y;
|
|
|
|
if (play->camera.main_data.talk.flags & 2) {
|
|
angle_y = (s16)search_position_angleY(&speaker->world.position, &play->camera.main_data.talk.listener_pos);
|
|
}
|
|
else {
|
|
angle_y = (s16)search_position_angleY(&speaker->world.position, &listener->world.position);
|
|
}
|
|
|
|
if (
|
|
(angle_y < DEG2SHORT_ANGLE( 135.0f) && angle_y > DEG2SHORT_ANGLE( 45.0f)) ||
|
|
(angle_y > DEG2SHORT_ANGLE(-135.0f) && angle_y < DEG2SHORT_ANGLE(-45.0f))
|
|
) {
|
|
angle = 0;
|
|
}
|
|
else {
|
|
f32 add_angle = cos_s(2 * angle_y) * 2730.0f; // cos_s(2 * y) * 15.0f (deg)
|
|
f32 sin = sin_s(angle_y);
|
|
f32 cos = cos_s(angle_y);
|
|
|
|
if (cos * sin >= 0.0f) {
|
|
angle = -add_angle; // angle = [-15 deg, 0 deg]
|
|
}
|
|
else {
|
|
angle = add_angle; // angle = [0 deg, 15 deg]
|
|
}
|
|
}
|
|
|
|
goal_dir->y += angle;
|
|
}
|
|
|
|
static void Camera2_Talk_GetGoalDirectionAngleXYZAndSetDistance_BetweenSpeakerToListener(GAME_PLAY* play, ACTOR* speaker, ACTOR* listener, f32 dist_between, s_xyz* dir) {
|
|
xyz_t pos = play->camera.main_data.talk.goal_center_pos;
|
|
f32 dist;
|
|
f32 x_ratio = 0.0f;
|
|
f32 z_ratio = 0.0f;
|
|
|
|
Camera2_Get_GoalDistanceAndDirection(play, &dist, dir);
|
|
dir->x += 1440; // just shy of 8 degrees (~7.915)
|
|
Camera2_Get_PosBlockRatio(play, &pos, &x_ratio, &z_ratio);
|
|
|
|
if (Camera2_Talk_NoLowAngleCheck(play, &pos)) {
|
|
Camera2_main_Simple_AngleDistStd(play, dir, &dist);
|
|
dist *= 0.75f;
|
|
dir->x -= DEG2SHORT_ANGLE(2.75f);
|
|
play->camera.main_data.talk.flags |= 1;
|
|
}
|
|
else {
|
|
Camera2_Talk_GetAngleY(play, speaker, listener, dir, dist_between);
|
|
dist += dist_between * 1.46f;
|
|
play->camera.main_data.talk.flags &= ~1;
|
|
}
|
|
|
|
Camera2_MoveDistancePosAndSpeed(play, dist, FALSE);
|
|
}
|
|
|
|
static void Camera2_SetPos_Talk(GAME_PLAY* play) {
|
|
Camera2* camera = &play->camera;
|
|
ACTOR* speaker = camera->main_data.talk.speaker_actor;
|
|
ACTOR* listener = camera->main_data.talk.listener_actor;
|
|
CameraMainData* main_data = &camera->main_data;
|
|
f32 dist;
|
|
s_xyz dir;
|
|
|
|
if (speaker != NULL || listener != NULL) {
|
|
if (speaker == NULL || listener == NULL) {
|
|
dist = 0.0f;
|
|
}
|
|
else {
|
|
dist = search_position_distance(&speaker->world.position, &listener->world.position);
|
|
}
|
|
|
|
if (main_data->talk.flags & 2) {
|
|
dist = search_position_distance(&speaker->world.position, &main_data->talk.listener_pos);
|
|
}
|
|
|
|
Camera2_Talk_ChangeCameraCenterPos_BetweenSpeakerToListener(play, speaker, listener, dist);
|
|
Camera2_Talk_GetGoalDirectionAngleXYZAndSetDistance_BetweenSpeakerToListener(play, speaker, listener, dist, &dir);
|
|
Camera2_MoveDirectionAngleXYZ(play, &dir, 0);
|
|
Camera2_SetEyePos_fromCenterPos(play);
|
|
Camera2_SetView(play);
|
|
}
|
|
}
|
|
|
|
static void Camera2_Talk_AddCullTimer(GAME_PLAY* play) {
|
|
Camera2_AddCullTimer(&play->camera.main_data.talk.cull_timer, 15.0f);
|
|
}
|
|
|
|
static void Camera2_Talk_SetTalking_Cull(GAME_PLAY* play) {
|
|
ACTOR* actor;
|
|
f32 width;
|
|
f32 x;
|
|
f32 z;
|
|
|
|
if (Camera2_CheckCullingMode()) {
|
|
for (actor = play->actor_info.list[ACTOR_PART_ITEM].actor; actor != NULL; actor = actor->next_actor) {
|
|
s16 id = actor->id;
|
|
|
|
if (
|
|
(s16)id == mAc_PROFILE_BGITEM ||
|
|
(s16)id == mAc_PROFILE_FALLS || (s16)id == mAc_PROFILE_FALLSESW ||
|
|
(s16)id == mAc_PROFILE_TRAIN0 || (s16)id == mAc_PROFILE_TRAIN1 ||
|
|
(s16)id == mAc_PROFILE_STATION ||
|
|
(s16)id == mAc_PROFILE_DUMP ||
|
|
(s16)id == mAc_PROFILE_GOZA || (s16)id == mAc_PROFILE_RADIO ||
|
|
(s16)id == mAc_PROFILE_MIKUJI ||
|
|
(s16)id == mAc_PROFILE_TUKIMI ||
|
|
(s16)id == mAc_PROFILE_LOTUS ||
|
|
(s16)id == mAc_PROFILE_BOAT ||
|
|
(s16)id == mAc_PROFILE_BRIDGE_A ||
|
|
(s16)id == mAc_PROFILE_ROOM_SUNSHINE_MINSECT ||
|
|
(s16)id == mAc_PROFILE_S_CAR
|
|
) {
|
|
continue;
|
|
}
|
|
|
|
x = actor->world.position.x;
|
|
z = actor->world.position.z;
|
|
|
|
if ((s16)id == mAc_PROFILE_MUSEUM) {
|
|
width = 142.0f;
|
|
}
|
|
else if ((s16)id == mAc_PROFILE_DEPART || (s16)id == mAc_PROFILE_SUPER) {
|
|
width = 130.0f;
|
|
}
|
|
else if ((s16)id == mAc_PROFILE_CONVENI) {
|
|
width = 110.0f;
|
|
}
|
|
else if ((s16)id == mAc_PROFILE_POST_OFFICE || (s16)id == mAc_PROFILE_SHOP || (s16)id == mAc_PROFILE_NEEDLEWORK_SHOP) {
|
|
width = 90.0f;
|
|
}
|
|
else {
|
|
width = 65.0f;
|
|
}
|
|
|
|
if (Camera2_CheckEnterCullingArea(x, z, width)) {
|
|
actor->cull_while_talking = TRUE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static void Camera2_main_Talk(GAME_PLAY* play) {
|
|
Camera2_SetPos_Talk(play);
|
|
Camera2_sound_Set_Ground(play);
|
|
Camera2_SetMicPos(play);
|
|
Camera2_Talk_AddCullTimer(play);
|
|
Camera2_Talk_SetTalking_Cull(play);
|
|
Camera2_change_main_index(play);
|
|
}
|
|
|
|
static void Camera2_main_Normal_SetEndCenterPos_fromPlayer(GAME_PLAY* play, xyz_t* end_center_pos) {
|
|
PLAYER_ACTOR* player = get_player_actor_withoutCheck(play);
|
|
f32 border_x0;
|
|
f32 border_x1;
|
|
f32 border_z1;
|
|
f32 border_z0;
|
|
f32 scale;
|
|
int block_x;
|
|
int block_z;
|
|
|
|
Camera2_GetLongBorderScale(play, &scale);
|
|
|
|
if (Camera2_InDoorCheck()) {
|
|
int add_dir_idx;
|
|
int add_dist_idx;
|
|
|
|
add_dist_idx = play->camera.indoor_distance_addition_idx;
|
|
add_dir_idx = play->camera.indoor_direction_addition_idx;
|
|
|
|
scale *= (add_distance_array[add_dist_idx] + 620.0f) / 620.0f;
|
|
|
|
if (add_dir_idx == 0 || add_dir_idx == 2) {
|
|
scale *= 0.8f;
|
|
}
|
|
|
|
if (add_dist_idx == 2) {
|
|
scale *= 0.88f;
|
|
}
|
|
}
|
|
|
|
Camera2_GetBorderScale(play, scale, &border_x0, &border_x1, &border_z0, &border_z1);
|
|
*end_center_pos = player->actor_class.eye.position;
|
|
|
|
if (mPlib_get_player_actor_main_index(play) == 114) {
|
|
if (mFI_Wpos2BlockNum(&block_x, &block_z, player->actor_class.world.position)) {
|
|
if (block_x == 5) {
|
|
if (block_z == 7) {
|
|
end_center_pos->z += 55.0f; // extra Z distance when travelling in Kapp'n's boat in the acre below the dock?
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (play->camera.flags & 1) {
|
|
f32 z_midpoint = (border_z0 + border_z1) * 0.5f;
|
|
f32 z_left = z_midpoint - border_z0;
|
|
f32 z_scale;
|
|
|
|
if (F32_IS_ZERO(z_left)) {
|
|
z_scale = 0.0f;
|
|
}
|
|
else {
|
|
z_scale = (end_center_pos->z - z_midpoint) / z_left;
|
|
}
|
|
|
|
end_center_pos->z = z_midpoint + (z_scale * z_left) * 0.25f;
|
|
}
|
|
|
|
if (mFI_GetBlockWidth() < scale * 330.0f || border_x0 < border_x1) {
|
|
end_center_pos->x = (border_x0 + border_x1) * 0.5f;
|
|
}
|
|
else if (end_center_pos->x > border_x0) {
|
|
end_center_pos->x = border_x0;
|
|
}
|
|
else if (end_center_pos->x < border_x1) {
|
|
end_center_pos->x = border_x1;
|
|
}
|
|
|
|
if (mFI_GetBlockHeight() < scale * 250.0f || border_z1 < border_z0) {
|
|
end_center_pos->z = (border_z0 + border_z1) * 0.5f;
|
|
}
|
|
else if (end_center_pos->z < border_z0) {
|
|
end_center_pos->z = border_z0;
|
|
}
|
|
else if (end_center_pos->z > border_z1) {
|
|
end_center_pos->z = border_z1;
|
|
}
|
|
|
|
if (Camera2_InDoorCheck()) {
|
|
end_center_pos->y = 73.0f;
|
|
}
|
|
}
|
|
|
|
static int Camera2_MoveVparamCenter(GAME_PLAY* play, xyz_t* pos) {
|
|
xyz_t new_center;
|
|
Camera2* camera = &play->camera;
|
|
xyz_t* center_p = &camera->lookat.center;
|
|
xyz_t last_center = *center_p;
|
|
xyz_t* center_vel_p = &camera->movement_velocity;
|
|
|
|
Math3DInDivPos2(center_p, pos, &new_center, 0.2f); // weirdness with the float loading
|
|
*center_p = new_center;
|
|
|
|
xyz_t_sub(center_p, &last_center, center_vel_p);
|
|
return TRUE;
|
|
}
|
|
|
|
static int Camera2_MoveDistancePosAndSpeedVParam(GAME_PLAY* play, f32 goal_dist) {
|
|
f32 dist = play->camera.focus_distance;
|
|
|
|
play->camera.focus_distance = dist + (goal_dist - dist) * 0.2f;
|
|
play->camera.focus_distance_velocity = play->camera.focus_distance - dist;
|
|
return FALSE;
|
|
}
|
|
|
|
static void Camera2_MoveDirectionAngleXYZVParam(GAME_PLAY* play, const s_xyz* goal_dir) {
|
|
s_xyz last_dir;
|
|
|
|
Camera2* camera = &play->camera;
|
|
s_xyz* dir_vel = &camera->direction_velocity;
|
|
s16 x;
|
|
s16 y;
|
|
s16 z;
|
|
s_xyz* dir = &camera->direction;
|
|
|
|
x = dir->x;
|
|
y = dir->y;
|
|
z = dir->z;
|
|
|
|
add_calc_short_angle2(&dir->x, goal_dir->x, 0.10557282f, SHT_MAX_S, 2);
|
|
add_calc_short_angle2(&dir->y, goal_dir->y, 0.10557282f, SHT_MAX_S, 2);
|
|
add_calc_short_angle2(&dir->z, goal_dir->z, 0.10557282f, SHT_MAX_S, 2);
|
|
|
|
#ifndef BUGFIXES
|
|
dir_vel->z = dir->x - x; // @BUG
|
|
#else
|
|
dir_vel->x = dir->x - x;
|
|
#endif
|
|
dir_vel->y = dir->y - y;
|
|
dir_vel->z = dir->z - z;
|
|
}
|
|
|
|
static void Camera2_main_Normal_SetPos_fromPlayer(GAME_PLAY* play, int force) {
|
|
Camera2* camera = &play->camera;
|
|
CameraMainData* main_data = &camera->main_data;
|
|
f32 goal_dist;
|
|
s_xyz goal_dir;
|
|
|
|
if (
|
|
main_data->normal.last_indoor_distance_addition_idx != camera->indoor_distance_addition_idx ||
|
|
main_data->normal.last_indoor_direction_addition_idx != camera->indoor_direction_addition_idx
|
|
) {
|
|
main_data->normal.morph_counter = 80;
|
|
main_data->normal.last_indoor_distance_addition_idx = camera->indoor_distance_addition_idx;
|
|
main_data->normal.last_indoor_direction_addition_idx = camera->indoor_direction_addition_idx;
|
|
}
|
|
|
|
Camera2_Get_GoalDistanceAndDirection(play, &goal_dist, &goal_dir);
|
|
|
|
if (main_data->normal.morph_counter <= 0) {
|
|
Camera2_MoveDistancePosAndSpeed(play, goal_dist, FALSE);
|
|
Camera2_MoveDirectionAngleXYZ(play, &goal_dir, force);
|
|
}
|
|
else {
|
|
Camera2_MoveDistancePosAndSpeedVParam(play, goal_dist);
|
|
Camera2_MoveDirectionAngleXYZVParam(play, &goal_dir);
|
|
}
|
|
|
|
if (main_data->normal.morph_counter <= 0) {
|
|
xyz_t end_center_pos;
|
|
|
|
Camera2_main_Normal_SetEndCenterPos_fromPlayer(play, &end_center_pos);
|
|
Camera2_MoveCenterPosAndSpeed_fromEndCenterPos(play, &end_center_pos, force);
|
|
Camera2_SetEyePos_fromCenterPos(play);
|
|
}
|
|
else {
|
|
xyz_t end_center_pos;
|
|
|
|
Camera2_main_Normal_SetEndCenterPos_fromPlayer(play, &end_center_pos);
|
|
Camera2_MoveVparamCenter(play, &end_center_pos);
|
|
Camera2_SetEyePos_fromCenterPos(play);
|
|
main_data->normal.morph_counter--;
|
|
}
|
|
|
|
Camera2_SetView(play);
|
|
}
|
|
|
|
static void Camera2_main_Normal_AdjustDistanceAndDirection(GAME_PLAY* play, f32* dist, s_xyz* dir) {
|
|
Camera2* camera = &play->camera;
|
|
CameraMainData* main_data = &camera->main_data;
|
|
|
|
if ((main_data->normal.flags & 1) == 0 && (camera->flags & 1) == 0) {
|
|
return;
|
|
}
|
|
|
|
*dist *= 1.5f;
|
|
}
|
|
|
|
extern int Camera2_request_main_normal(GAME_PLAY* play, int flags, int priority) {
|
|
if (Camera2_check_request_main_priority(play, priority) > 0) {
|
|
play->camera.request_data.normal.flags = flags;
|
|
Camera2_request_main_index(play, CAMERA2_PROCESS_NORMAL, priority);
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
static void Camera2_setup_main_Normal(GAME_PLAY* play) {
|
|
Camera2* camera = &play->camera;
|
|
CameraMainData* main_data = &camera->main_data;
|
|
|
|
Camera2_setup_main_Base(play);
|
|
main_data->normal.flags = 0;
|
|
main_data->normal.last_indoor_distance_addition_idx = camera->indoor_distance_addition_idx;
|
|
main_data->normal.last_indoor_direction_addition_idx = camera->indoor_direction_addition_idx;
|
|
main_data->normal.morph_counter = 0;
|
|
|
|
if (play->camera.request_data.normal.flags & 1) {
|
|
Camera2_main_Normal_SetPos_fromPlayer(play, TRUE);
|
|
}
|
|
else {
|
|
Camera2_main_Normal_SetPos_fromPlayer(play, FALSE);
|
|
}
|
|
|
|
play->camera.requested_main_index_priority = 0;
|
|
}
|
|
|
|
static void Camera2_main_Normal(GAME_PLAY* play) {
|
|
Camera2_main_Normal_SetPos_fromPlayer(play, FALSE);
|
|
Camera2_sound_Set_Ground(play);
|
|
Camera2_SetMicPos(play);
|
|
Camera2_change_main_index(play);
|
|
}
|
|
|
|
extern int Camera2_request_main_demo(
|
|
GAME_PLAY* play,
|
|
const xyz_t* start_center, const f32 start_dist, const s_xyz* start_dir,
|
|
const xyz_t* goal_center, const f32 goal_dist, const s_xyz* goal_dir,
|
|
const f32 goal_delta, const f32 accel_delta, const f32 braking_delta,
|
|
const int priority
|
|
) {
|
|
if (Camera2_check_request_main_priority(play, priority) > 0) {
|
|
play->camera.request_data.demo.starting_center_pos = *start_center;
|
|
play->camera.request_data.demo.starting_distance = start_dist;
|
|
play->camera.request_data.demo.starting_direction = *start_dir;
|
|
|
|
play->camera.request_data.demo.goal_center_pos = *goal_center;
|
|
play->camera.request_data.demo.goal_distance = goal_dist;
|
|
play->camera.request_data.demo.goal_direction = *goal_dir;
|
|
|
|
play->camera.request_data.demo.goal_delta = goal_delta;
|
|
play->camera.request_data.demo.acceleration_delta = accel_delta;
|
|
play->camera.request_data.demo.braking_delta = braking_delta;
|
|
|
|
Camera2_request_main_index(play, CAMERA2_PROCESS_DEMO, priority);
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
extern int Camera2_request_main_demo_fromNowPos(GAME_PLAY* play,
|
|
const xyz_t* goal_center, const s_xyz* goal_dir, const f32 goal_dist,
|
|
const f32 goal_delta, const f32 accel_delta, const f32 braking_delta,
|
|
const int priority
|
|
) {
|
|
return Camera2_request_main_demo(
|
|
play,
|
|
&play->camera.lookat.center, play->camera.focus_distance, &play->camera.direction,
|
|
goal_center, goal_dist, goal_dir,
|
|
goal_delta, accel_delta, braking_delta,
|
|
priority
|
|
);
|
|
}
|
|
|
|
extern int Camera2_request_main_demo_fromNowPos2(GAME_PLAY* play,
|
|
const xyz_t* goal_center,
|
|
const f32 goal_delta, const f32 accel_delta, const f32 braking_delta,
|
|
const int priority
|
|
) {
|
|
static const s_xyz goal_direction = { DEG2SHORT_ANGLE(-135.0f), DEG2SHORT_ANGLE(-180.0f), DEG2SHORT_ANGLE(0) };
|
|
|
|
Camera2* camera = &play->camera;
|
|
|
|
return Camera2_request_main_demo(
|
|
play,
|
|
&play->camera.lookat.center, play->camera.focus_distance, &play->camera.direction,
|
|
goal_center, 620.0f, &goal_direction,
|
|
goal_delta, accel_delta, braking_delta,
|
|
priority
|
|
);
|
|
}
|
|
|
|
static void Camera2_CalcPos_Demo(GAME_PLAY* play, xyz_t* pos, f32* dist, s_xyz* dir) {
|
|
f32 now_delta = play->camera.main_data.demo.now_delta;
|
|
f32 goal_delta = play->camera.main_data.demo.goal_delta;
|
|
f32 accel_delta = play->camera.main_data.demo.acceleration_delta;
|
|
f32 brake_delta = play->camera.main_data.demo.braking_delta;
|
|
f32 percent;
|
|
|
|
int sx;
|
|
int dx;
|
|
int sy;
|
|
int dy;
|
|
|
|
if (now_delta != goal_delta) {
|
|
now_delta += 1.0f;
|
|
|
|
if (now_delta > goal_delta) {
|
|
now_delta = goal_delta;
|
|
}
|
|
|
|
play->camera.main_data.demo.now_delta = now_delta;
|
|
}
|
|
|
|
percent = get_percent_forAccelBrake(now_delta, 0.0f, goal_delta, accel_delta, brake_delta);
|
|
pos->x = play->camera.main_data.demo.starting_center_pos.x + percent * (play->camera.main_data.demo.goal_center_pos.x - play->camera.main_data.demo.starting_center_pos.x);
|
|
pos->y = play->camera.main_data.demo.starting_center_pos.y + percent * (play->camera.main_data.demo.goal_center_pos.y - play->camera.main_data.demo.starting_center_pos.y);
|
|
pos->z = play->camera.main_data.demo.starting_center_pos.z + percent * (play->camera.main_data.demo.goal_center_pos.z - play->camera.main_data.demo.starting_center_pos.z);
|
|
|
|
*dist = play->camera.main_data.demo.starting_distance + percent * (play->camera.main_data.demo.goal_distance - play->camera.main_data.demo.starting_distance);
|
|
|
|
sx = play->camera.main_data.demo.starting_direction.x;
|
|
dx = play->camera.main_data.demo.goal_direction.x - sx;
|
|
|
|
if (ABS(dx) > (u16)SHT_MIN_S) {
|
|
if (dx > 0) {
|
|
dx -= 2 * (u16)SHT_MIN_S;
|
|
}
|
|
else {
|
|
dx += 2 * (u16)SHT_MIN_S;
|
|
}
|
|
}
|
|
|
|
dir->x = sx + (s16)(percent * dx);
|
|
|
|
sy = play->camera.main_data.demo.starting_direction.y;
|
|
dy = play->camera.main_data.demo.goal_direction.y - sy;
|
|
|
|
if (ABS(dy) > (u16)SHT_MIN_S) {
|
|
if (dy > 0) {
|
|
dy -= 2 * (u16)SHT_MIN_S;
|
|
}
|
|
else {
|
|
dy += 2 * (u16)SHT_MIN_S;
|
|
}
|
|
}
|
|
|
|
dir->y = sy + (s16)(percent * dy);
|
|
dir->z = 0;
|
|
}
|
|
|
|
static void Camera2_SetPos_Demo(GAME_PLAY* play) {
|
|
xyz_t pos;
|
|
f32 dist;
|
|
s_xyz dir;
|
|
|
|
Camera2_CalcPos_Demo(play, &pos, &dist, &dir);
|
|
Camera2_SetCameraParameter(play, &pos, &dir, FALSE, dist);
|
|
Camera2_SetView(play);
|
|
}
|
|
|
|
static void Camera2_main_Demo(GAME_PLAY* play) {
|
|
Camera2_SetPos_Demo(play);
|
|
Camera2_change_main_index(play);
|
|
}
|
|
|
|
static void Camera2_setup_main_Demo(GAME_PLAY* play) {
|
|
Camera2* camera = &play->camera;
|
|
CameraMainData* main_data = &camera->main_data;
|
|
|
|
main_data->demo.now_delta = 0.0f;
|
|
|
|
main_data->demo.starting_center_pos = play->camera.request_data.demo.starting_center_pos;
|
|
main_data->demo.starting_distance = play->camera.request_data.demo.starting_distance;
|
|
main_data->demo.starting_direction = play->camera.request_data.demo.starting_direction;
|
|
|
|
main_data->demo.goal_center_pos = play->camera.request_data.demo.goal_center_pos;
|
|
main_data->demo.goal_distance = play->camera.request_data.demo.goal_distance;
|
|
main_data->demo.goal_direction = play->camera.request_data.demo.goal_direction;
|
|
|
|
main_data->demo.goal_delta = play->camera.request_data.demo.goal_delta;
|
|
main_data->demo.acceleration_delta = play->camera.request_data.demo.acceleration_delta;
|
|
main_data->demo.braking_delta = play->camera.request_data.demo.braking_delta;
|
|
|
|
Camera2_SetCameraParameter(play, &main_data->demo.starting_center_pos, &main_data->demo.starting_direction, TRUE, main_data->demo.starting_distance);
|
|
Camera2_SetView(play);
|
|
Camera2_setup_main_Base(play);
|
|
play->camera.requested_main_index_priority = 0;
|
|
}
|
|
|
|
extern int Camera2_request_main_item(GAME_PLAY* play, int type, int priority) {
|
|
if (Camera2_check_request_main_priority(play, priority) > 0) {
|
|
play->camera.request_data.item.type = type;
|
|
Camera2_request_main_index(play, CAMERA2_PROCESS_ITEM, priority);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
static void Camera2_SetPos_Item(GAME_PLAY* play) {
|
|
static const xyz_t offset = { 3.167068f, 28.884293f, 17.341202f };
|
|
|
|
Camera2* camera = &play->camera;
|
|
CameraMainData* main_data = &camera->main_data;
|
|
PLAYER_ACTOR* player = get_player_actor_withoutCheck(play);
|
|
int type = main_data->item.type;
|
|
xyz_t pos = player->actor_class.world.position;
|
|
s_xyz dir;
|
|
f32 dist;
|
|
|
|
if (type == 0) {
|
|
pos.x += offset.x;
|
|
pos.y += offset.y;
|
|
pos.z += offset.z;
|
|
|
|
pos.y += -15.0f;
|
|
}
|
|
|
|
Camera2_MoveCenterPosAndSpeed_fromEndCenterPos(play, &pos, FALSE);
|
|
Camera2_Get_GoalDistanceAndDirection(play, &dist, &dir);
|
|
|
|
dist += -250.0f;
|
|
dir.x += -1400; // approx. -7.7 deg
|
|
|
|
Camera2_MoveDistancePosAndSpeed(play, dist, FALSE);
|
|
Camera2_MoveDirectionAngleXYZ(play, &dir, FALSE);
|
|
Camera2_SetEyePos_fromCenterPos(play);
|
|
Camera2_SetView(play);
|
|
}
|
|
|
|
static void Camera2_Item_AddCullTimer(GAME_PLAY* play) {
|
|
Camera2_AddCullTimer(&play->camera.main_data.item.cull_timer, 6.0f);
|
|
}
|
|
|
|
static void Camera2_Item_SetTalking_Cull(GAME_PLAY* play) {
|
|
Camera2_Talk_SetTalking_Cull(play);
|
|
}
|
|
|
|
static void Camera2_main_Item(GAME_PLAY* play) {
|
|
Camera2_SetPos_Item(play);
|
|
Camera2_sound_Set_Ground(play);
|
|
Camera2_SetMicPos(play);
|
|
Camera2_Item_AddCullTimer(play);
|
|
Camera2_Item_SetTalking_Cull(play);
|
|
Camera2_change_main_index(play);
|
|
}
|
|
|
|
static void Camera2_setup_main_Item(GAME_PLAY* play) {
|
|
play->camera.main_data.item.type = play->camera.request_data.item.type;
|
|
play->camera.main_data.item.cull_timer = 0.0f;
|
|
Camera2_setup_main_Base(play);
|
|
play->camera.requested_main_index_priority = 0;
|
|
}
|
|
|
|
extern int Camera2_request_main_lock(GAME_PLAY* play, xyz_t* center_pos, xyz_t* eye_pos, f32 fov_y, int morph_counter, f32 near, f32 far, int priority) {
|
|
if (Camera2_check_request_main_priority(play, priority) > 0) {
|
|
play->camera.request_data.lock.center_pos = *center_pos;
|
|
play->camera.request_data.lock.eye_pos = *eye_pos;
|
|
play->camera.request_data.lock.fov_y = fov_y;
|
|
play->camera.request_data.lock.morph_counter = morph_counter;
|
|
play->camera.request_data.lock.near = near;
|
|
play->camera.request_data.lock.far = far;
|
|
|
|
Camera2_request_main_index(play, CAMERA2_PROCESS_LOCK, priority);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
static void Camera2_setup_main_Lock(GAME_PLAY* play) {
|
|
play->camera.main_data.lock.center_pos = play->camera.request_data.lock.center_pos;
|
|
play->camera.main_data.lock.eye_pos = play->camera.request_data.lock.eye_pos;
|
|
play->camera.main_data.lock.fov_y = play->camera.request_data.lock.fov_y;
|
|
play->camera.main_data.lock.morph_counter = play->camera.request_data.lock.morph_counter;
|
|
play->camera.main_data.lock.near = play->camera.request_data.lock.near;
|
|
play->camera.main_data.lock.far = play->camera.request_data.lock.far;
|
|
|
|
Camera2_setup_main_Base(play);
|
|
}
|
|
|
|
static void Camera2_Lock_SetCenterPos(GAME_PLAY* play, xyz_t* center_pos, int step) {
|
|
Camera2* camera = &play->camera;
|
|
|
|
xyz_t* center_vel_p = &camera->movement_velocity;
|
|
xyz_t* center_p = &camera->lookat.center;
|
|
xyz_t pre_center = *center_p;
|
|
|
|
inter_float(¢er_p->x, center_pos->x, step);
|
|
inter_float(¢er_p->y, center_pos->y, step);
|
|
inter_float(¢er_p->z, center_pos->z, step);
|
|
|
|
center_vel_p->x = center_p->x - pre_center.x;
|
|
center_vel_p->y = center_p->y - pre_center.y;
|
|
center_vel_p->z = center_p->z - pre_center.z;
|
|
}
|
|
|
|
static void Camera2_Lock_SetEyePos(GAME_PLAY* play, xyz_t* eye, int step) {
|
|
xyz_t* eye_p = &play->camera.lookat.eye;
|
|
|
|
inter_float(&eye_p->x, eye->x, step);
|
|
inter_float(&eye_p->y, eye->y, step);
|
|
inter_float(&eye_p->z, eye->z, step);
|
|
}
|
|
|
|
static void Camera2_Lock_SetFovy(GAME_PLAY* play, f32 fov_y, int step) {
|
|
inter_float(&play->camera.perspective.fov_y, fov_y, step);
|
|
}
|
|
|
|
static void Camera2_Lock_SetNearFar(GAME_PLAY* play, f32 near, f32 far, int step) {
|
|
inter_float(&play->camera.perspective.near, near, step);
|
|
inter_float(&play->camera.perspective.far, far, step);
|
|
}
|
|
|
|
static void Camera2_Lock_MorphCounterProc(GAME_PLAY* play) {
|
|
int morph_counter = play->camera.main_data.lock.morph_counter;
|
|
|
|
if (morph_counter <= 0) {
|
|
play->camera.main_data.lock.morph_counter = 0;
|
|
}
|
|
else {
|
|
play->camera.main_data.lock.morph_counter = morph_counter - 1;
|
|
}
|
|
}
|
|
|
|
static void Camera2_SetPos_Lock(GAME_PLAY* play) {
|
|
int morph_counter = play->camera.main_data.lock.morph_counter;
|
|
f32 fov_y = play->camera.main_data.lock.fov_y;
|
|
f32 near = play->camera.main_data.lock.near;
|
|
f32 far = play->camera.main_data.lock.far;
|
|
|
|
Camera2_Lock_SetCenterPos(play, &play->camera.main_data.lock.center_pos, morph_counter);
|
|
Camera2_Lock_SetEyePos(play, &play->camera.main_data.lock.eye_pos, morph_counter);
|
|
Camera2_Lock_SetFovy(play, fov_y, morph_counter);
|
|
Camera2_Lock_SetNearFar(play, near, far, morph_counter);
|
|
Camera2_Lock_MorphCounterProc(play);
|
|
Camera2_DirectionCalc(play);
|
|
Camera2_SetView(play);
|
|
}
|
|
|
|
static void Camera2_main_Lock(GAME_PLAY* play) {
|
|
Camera2_SetPos_Lock(play);
|
|
Camera2_sound_Set_Ground(play);
|
|
Camera2_SetMicPos(play);
|
|
Camera2_change_main_index(play);
|
|
}
|
|
|
|
extern int Camera2_request_main_door(GAME_PLAY* play, ACTOR* door_actor, u32 flags, int priority) {
|
|
if (door_actor == NULL) {
|
|
return FALSE;
|
|
}
|
|
else if (Camera2_check_request_main_priority(play, priority) > 0) {
|
|
play->camera.request_data.door.door_actor = door_actor;
|
|
play->camera.request_data.door.flags = flags;
|
|
|
|
Camera2_request_main_index(play, CAMERA2_PROCESS_DOOR, priority);
|
|
|
|
return TRUE;
|
|
}
|
|
else {
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
static void Camera2_setup_main_Door(GAME_PLAY* play) {
|
|
Camera2* camera = &play->camera;
|
|
CameraMainData* main_data = &camera->main_data;
|
|
|
|
main_data->door.flags = camera->request_data.door.flags;
|
|
main_data->door.center_position = camera->request_data.door.door_actor->eye.position;
|
|
|
|
if (main_data->door.flags & 1) {
|
|
main_data->door.morph_counter = 140;
|
|
}
|
|
else {
|
|
main_data->door.morph_counter = 0;
|
|
camera->requested_main_index_priority = 0;
|
|
}
|
|
|
|
Camera2_setup_main_Base(play);
|
|
}
|
|
|
|
static void Camera2_Door_SetCenterPos(GAME_PLAY* play, int step) {
|
|
xyz_t goal_center;
|
|
xyz_t start_center;
|
|
Camera2* camera = &play->camera;
|
|
xyz_t* center_vel_p = &camera->movement_velocity;
|
|
xyz_t* center_p = &camera->lookat.center;
|
|
|
|
start_center = *center_p;
|
|
goal_center = camera->main_data.door.center_position;
|
|
|
|
inter_float(¢er_p->x, goal_center.x, step);
|
|
inter_float(¢er_p->y, goal_center.y, step);
|
|
inter_float(¢er_p->z, goal_center.z, step);
|
|
|
|
center_vel_p->x = center_p->x - start_center.x;
|
|
center_vel_p->y = center_p->y - start_center.y;
|
|
center_vel_p->z = center_p->z - start_center.z;
|
|
}
|
|
|
|
#ifndef MUST_MATCH
|
|
/* @nonmatching - minor control flow order issue at beginning */
|
|
static void Camera2_Door_SetEyePos(GAME_PLAY* play, int step) {
|
|
Camera2* camera = &play->camera;
|
|
xyz_t* center_p;
|
|
xyz_t* eye_p;
|
|
s_xyz* dir;
|
|
s_xyz* dir_vel;
|
|
f32* dist_p;
|
|
f32 last_dist;
|
|
s_xyz angle;
|
|
|
|
dist_p = &camera->focus_distance;
|
|
last_dist = camera->focus_distance;
|
|
|
|
angle.x = DEG2SHORT_ANGLE(-159.72f);
|
|
angle.y = DEG2SHORT_ANGLE(-180.00f);
|
|
angle.z = 0;
|
|
|
|
center_p = &camera->lookat.center;
|
|
eye_p = &camera->lookat.eye;
|
|
|
|
dir = &camera->direction;
|
|
dir_vel = &camera->direction_velocity;
|
|
|
|
inter_float(dist_p, 350.0f, step);
|
|
camera->focus_distance_velocity = last_dist - *dist_p; // inverted velocity?
|
|
|
|
if (step == 0) {
|
|
*dir = angle;
|
|
|
|
dir_vel->x = 0.0f;
|
|
dir_vel->y = 0.0f;
|
|
dir_vel->z = 0.0f;
|
|
}
|
|
else {
|
|
f32 t = 1.5f / (f32)step;
|
|
|
|
cKF_SkeletonInfo_subRotInterpolation(t, &dir->x, dir->x, angle.x);
|
|
cKF_SkeletonInfo_subRotInterpolation(t, &dir->y, dir->y, angle.y);
|
|
}
|
|
|
|
Camera2_PolaPosCalc(eye_p, dir->x + (u16)SHT_MIN_S, dir->y + (u16)SHT_MIN_S, center_p, *dist_p);
|
|
}
|
|
#else
|
|
|
|
#pragma push
|
|
#pragma force_active on
|
|
|
|
//extern const f32 lbl_80641614;
|
|
//REL_SYMBOL_AT(lbl_80641614, 0x80641614);
|
|
|
|
extern const f64 lbl_80641450;
|
|
REL_SYMBOL_AT(lbl_80641450, 0x80641450);
|
|
|
|
extern const f32 lbl_80641484;
|
|
REL_SYMBOL_AT(lbl_80641484, 0x80641484);
|
|
|
|
#pragma pop
|
|
|
|
#include "orderfloats/80641614_80641618.inc"
|
|
|
|
static asm void Camera2_Door_SetEyePos(GAME_PLAY* play, int step) {
|
|
#include "asm/803815c4.s"
|
|
}
|
|
#endif
|
|
|
|
static void Camera2_Door_MorphCounterProc(GAME_PLAY* play) {
|
|
int morph_counter = play->camera.main_data.door.morph_counter;
|
|
|
|
if (morph_counter <= 0) {
|
|
play->camera.main_data.door.morph_counter = 0;
|
|
}
|
|
else {
|
|
play->camera.main_data.door.morph_counter = morph_counter - 1;
|
|
}
|
|
}
|
|
|
|
static void Camera2_SetPos_Door(GAME_PLAY* play) {
|
|
int morph_counter = play->camera.main_data.door.morph_counter;
|
|
|
|
Camera2_Door_SetCenterPos(play, morph_counter);
|
|
Camera2_Door_SetEyePos(play, morph_counter);
|
|
Camera2_Door_MorphCounterProc(play);
|
|
Camera2_SetView(play);
|
|
}
|
|
|
|
static void Camera2_Door_SetTalking_Cull(GAME_PLAY* play) {
|
|
Camera2_Talk_SetTalking_Cull(play);
|
|
}
|
|
|
|
static void Camera2_main_Door(GAME_PLAY* play) {
|
|
Camera2_SetPos_Door(play);
|
|
Camera2_sound_Set_Ground(play);
|
|
Camera2_SetMicPos(play);
|
|
Camera2_Door_SetTalking_Cull(play);
|
|
Camera2_change_main_index(play);
|
|
}
|
|
|
|
extern int Camera2_request_main_simple2(GAME_PLAY* play, xyz_t* center, s_xyz* dir, f32 dist, int morph_counter, int mode, int priority) {
|
|
if (Camera2_check_request_main_priority(play, priority) > 0) {
|
|
play->camera.request_data.simple.center_pos = *center;
|
|
play->camera.request_data.simple.angle = *dir;
|
|
play->camera.request_data.simple.distance = dist;
|
|
play->camera.request_data.simple.morph_counter = morph_counter;
|
|
play->camera.request_data.simple.mode = mode;
|
|
|
|
Camera2_request_main_index(play, CAMERA2_PROCESS_SIMPLE, priority);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
extern int Camera2_request_main_simple_kirin(GAME_PLAY* play, const xyz_t* center, int priority) {
|
|
xyz_t pos;
|
|
s_xyz dir;
|
|
f32 dist;
|
|
|
|
Camera2_main_Simple_AngleDistStd(play, &dir, &dist);
|
|
dir.x += -1000;
|
|
dir.y += 2000;
|
|
|
|
pos.x = center->x + -45.0f;
|
|
pos.y = center->y;
|
|
pos.z = center->z + -105.0f;
|
|
|
|
return Camera2_request_main_simple2(play, &pos, &dir, dist * 0.8f, 20, 1, priority);
|
|
}
|
|
|
|
extern int Camera2_request_main_simple_fishing(GAME_PLAY* play, const xyz_t* player_pos, const xyz_t* bobber_pos, int priority) {
|
|
f32 dist_mult = 1.0f;
|
|
|
|
xyz_t center;
|
|
s_xyz dir;
|
|
f32 dist;
|
|
f32 x0;
|
|
f32 y0;
|
|
f32 z0;
|
|
f32 x1;
|
|
f32 y1;
|
|
f32 z1;
|
|
|
|
Camera2_main_Simple_AngleDistStd(play, &dir, &dist);
|
|
|
|
if (player_pos->y - bobber_pos->y > 70.0f) {
|
|
dist_mult = 1.15f;
|
|
center.x = player_pos->x * 0.55f + bobber_pos->x * 0.45f;
|
|
center.y = player_pos->y * 0.55f + bobber_pos->y * 0.45f;
|
|
center.z = player_pos->z * 0.55f + bobber_pos->z * 0.45f;
|
|
}
|
|
else {
|
|
center.x = player_pos->x * 0.65f + bobber_pos->x * 0.35f;
|
|
center.y = player_pos->y * 0.65f + bobber_pos->y * 0.35f;
|
|
center.z = player_pos->z * 0.65f + bobber_pos->z * 0.35f;
|
|
}
|
|
|
|
return Camera2_request_main_simple(play, ¢er, &dir, dist * dist_mult, 40, priority);
|
|
}
|
|
extern int Camera2_request_main_simple_fishing_return(GAME_PLAY* play, xyz_t* player_pos, int priority) {
|
|
xyz_t center_pos;
|
|
s_xyz dir;
|
|
f32 dist;
|
|
|
|
Camera2_main_Normal_SetEndCenterPos_fromPlayer(play, ¢er_pos);
|
|
Camera2_main_Simple_AngleDistStd(play, &dir, &dist);
|
|
return Camera2_request_main_simple(play, ¢er_pos, &dir, dist, 30, priority);
|
|
}
|
|
|
|
extern int Camera2_request_main_simple(GAME_PLAY* play, xyz_t* pos, s_xyz* dir, f32 dist, int morph_counter, int priority) {
|
|
if (Camera2_check_request_main_priority(play, priority) > 0) {
|
|
play->camera.request_data.simple.center_pos = *pos;
|
|
play->camera.request_data.simple.angle = *dir;
|
|
play->camera.request_data.simple.distance = dist;
|
|
play->camera.request_data.simple.morph_counter = morph_counter;
|
|
play->camera.request_data.simple.mode = 0;
|
|
Camera2_request_main_index(play, CAMERA2_PROCESS_SIMPLE, priority);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
static void Camera2_setup_main_Simple(GAME_PLAY* play) {
|
|
play->camera.main_data.simple.center_pos = play->camera.request_data.simple.center_pos;
|
|
play->camera.main_data.simple.angle = play->camera.request_data.simple.angle;
|
|
play->camera.main_data.simple.distance = play->camera.request_data.simple.distance;
|
|
play->camera.main_data.simple.morph_counter = play->camera.request_data.simple.morph_counter;
|
|
play->camera.main_data.simple.mode = play->camera.request_data.simple.mode;
|
|
play->camera.main_data.simple.cull_timer = 0.0f;
|
|
Camera2_setup_main_Base(play);
|
|
}
|
|
|
|
extern void Camera2_main_Simple_AngleDistStd(GAME_PLAY* play, s_xyz* angle, f32* dist) {
|
|
static const s_xyz std_angle = { DEG2SHORT_ANGLE(-135.0f), DEG2SHORT_ANGLE(-180.0f), DEG2SHORT_ANGLE(0.0f) };
|
|
|
|
*angle = std_angle;
|
|
*dist = 620.0f;
|
|
|
|
if (Camera2_InDoorCheck() == FALSE && (play->camera.flags & 1) == 0) {
|
|
Camera2_Normal_Swing(play, dist, angle);
|
|
}
|
|
}
|
|
|
|
static void Camera2_Simple_MorphDistance(GAME_PLAY* play, f32 goal_dist, int step) {
|
|
Camera2* camera = &play->camera;
|
|
f32* dist_p = &camera->focus_distance;
|
|
f32* dist_vel_p = &camera->focus_distance_velocity;
|
|
f32 last_dist = *dist_p;
|
|
|
|
inter_float(dist_p, goal_dist, step);
|
|
if (step == 0) {
|
|
*dist_vel_p = 0;
|
|
}
|
|
else {
|
|
*dist_vel_p = *dist_p - last_dist;
|
|
}
|
|
}
|
|
|
|
static void Camera2_Simple_AngleCalc(GAME_PLAY* play, const s_xyz* goal_angle, int morph_counter) {
|
|
Camera2* camera = &play->camera;
|
|
s_xyz* angle_p = &camera->direction;
|
|
s_xyz* angle_vel_p = &camera->direction_velocity;
|
|
s_xyz last_angle;
|
|
f32 t;
|
|
|
|
if (morph_counter == 0) {
|
|
angle_p->x = goal_angle->x;
|
|
angle_p->y = goal_angle->y;
|
|
angle_p->z = goal_angle->z;
|
|
|
|
angle_vel_p->x = 0;
|
|
angle_vel_p->y = 0;
|
|
angle_vel_p->z = 0;
|
|
}
|
|
else {
|
|
last_angle = *angle_p;
|
|
t = 1.0f / (f32)morph_counter;
|
|
|
|
cKF_SkeletonInfo_subRotInterpolation(t, &angle_p->x, last_angle.x, goal_angle->x);
|
|
cKF_SkeletonInfo_subRotInterpolation(t, &angle_p->y, last_angle.y, goal_angle->y);
|
|
cKF_SkeletonInfo_subRotInterpolation(t, &angle_p->z, last_angle.z, goal_angle->z);
|
|
|
|
#ifndef BUGFIXES
|
|
angle_vel_p->z = angle_p->x - last_angle.x; // BUG, it should be angle_vel_p->x
|
|
#else
|
|
angle_vel_p->x = angle_p->x - last_angle.x;
|
|
#endif
|
|
angle_vel_p->y = angle_p->y - last_angle.y;
|
|
angle_vel_p->z = angle_p->z - last_angle.z;
|
|
}
|
|
}
|
|
|
|
static void Camera2_SetPos_Simple(GAME_PLAY* play) {
|
|
int morph_counter = play->camera.main_data.simple.morph_counter;
|
|
f32 goal_dist = play->camera.main_data.simple.distance;
|
|
|
|
Camera2_Lock_SetCenterPos(play, &play->camera.main_data.simple.center_pos, morph_counter);
|
|
Camera2_Simple_MorphDistance(play, goal_dist, morph_counter);
|
|
Camera2_Simple_AngleCalc(play, &play->camera.main_data.simple.angle, morph_counter);
|
|
Camera2_SetEyePos_fromCenterPos(play);
|
|
Camera2_SetView(play);
|
|
}
|
|
|
|
static void Camera2_Simple_AddCullTimer(GAME_PLAY* play) {
|
|
Camera2_AddCullTimer(&play->camera.main_data.simple.cull_timer, 6.0f);
|
|
}
|
|
|
|
static void Camera2_main_Simple(GAME_PLAY* play) {
|
|
Camera2_SetPos_Simple(play);
|
|
Camera2_sound_Set_Ground(play);
|
|
Camera2_SetMicPos(play);
|
|
|
|
if (play->camera.main_data.simple.mode == 1) {
|
|
Camera2_Simple_AddCullTimer(play);
|
|
Camera2_Talk_SetTalking_Cull(play);
|
|
}
|
|
|
|
Camera2_change_main_index(play);
|
|
}
|
|
|
|
extern int Camera2_request_main_listen_front_low_talk(GAME_PLAY* play, ACTOR* speaker, ACTOR* listener, int priority) {
|
|
const s16 y = listener->world.angle.y;
|
|
s16 angle_y;
|
|
|
|
if (!(sin_s(y) < 0.0f)) {
|
|
angle_y = DEG2SHORT_ANGLE(-169.06f);
|
|
}
|
|
else {
|
|
angle_y = DEG2SHORT_ANGLE(169.06f);
|
|
}
|
|
|
|
return Camera2_request_main_cust_talk(play, speaker, listener, 1.0f, priority, DEG2SHORT_ANGLE(5.495f), angle_y, 0.0f);
|
|
}
|
|
|
|
extern int Camera2_request_main_needlework_talk(GAME_PLAY* play, ACTOR* speaker, ACTOR* listener, int priority) {
|
|
s16 angle_x;
|
|
s16 angle_y;
|
|
f32 diff_x = listener->eye.position.x - speaker->eye.position.x;
|
|
|
|
angle_y = (s16)(diff_x * (20.0f/3.0f) + -32768.0f);
|
|
|
|
if (angle_y > 0) {
|
|
angle_y = DEG2SHORT_ANGLE(-180.0f);
|
|
}
|
|
|
|
angle_x = DEG2SHORT_ANGLE(5.495f);
|
|
if (fabsf(diff_x) < mFI_UT_WORLDSIZE_X_F) {
|
|
angle_x = DEG2SHORT_ANGLE(13.735f);
|
|
}
|
|
|
|
return Camera2_request_main_cust_talk(play, speaker, listener, 0.5f, priority, angle_x, angle_y, 50.0f);
|
|
}
|
|
|
|
extern int Camera2_request_main_cust_talk(GAME_PLAY* play, ACTOR* speaker, ACTOR* listener, f32 center_ratio, int priority, s16 angle_x, s16 angle_y, f32 distance) {
|
|
if (Camera2_check_request_main_priority(play, priority) > 0) {
|
|
play->camera.request_data.cust_talk.speaker_actor = speaker;
|
|
play->camera.request_data.cust_talk.listener_actor = listener;
|
|
play->camera.request_data.cust_talk.center_ratio = center_ratio;
|
|
play->camera.request_data.cust_talk.angle_x = angle_x;
|
|
play->camera.request_data.cust_talk.angle_y = angle_y;
|
|
play->camera.request_data.cust_talk.distance = distance;
|
|
|
|
Camera2_request_main_index(play, CAMERA2_PROCESS_CUST_TALK, priority);
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
static void Camera2_setup_main_Cust_talk(GAME_PLAY* play) {
|
|
play->camera.main_data.cust_talk.speaker_actor = play->camera.request_data.cust_talk.speaker_actor;
|
|
play->camera.main_data.cust_talk.listener_actor = play->camera.request_data.cust_talk.listener_actor;
|
|
play->camera.main_data.cust_talk.center_ratio = play->camera.request_data.cust_talk.center_ratio;
|
|
play->camera.main_data.cust_talk.angle_x = play->camera.request_data.cust_talk.angle_x;
|
|
play->camera.main_data.cust_talk.angle_y = play->camera.request_data.cust_talk.angle_y;
|
|
play->camera.main_data.cust_talk.distance = play->camera.request_data.cust_talk.distance;
|
|
play->camera.main_data.cust_talk.cull_timer = 0.0f;
|
|
|
|
Camera2_setup_main_Base(play);
|
|
play->camera.requested_main_index_priority = 0;
|
|
}
|
|
|
|
static void Camera2_Cust_Talk_ChangeCameraCenterPos_BetweenSpeakerToListener(GAME_PLAY* play, ACTOR* speaker, ACTOR* listener, f32 dist, f32 center_ratio) {
|
|
if (speaker != NULL || listener != NULL) {
|
|
xyz_t* pos0;
|
|
xyz_t* pos1;
|
|
xyz_t center;
|
|
|
|
if (speaker == NULL) {
|
|
pos0 = &listener->eye.position;
|
|
pos1 = pos0;
|
|
}
|
|
else if (listener == NULL) {
|
|
pos1 = &speaker->eye.position;
|
|
pos0 = pos1;
|
|
}
|
|
else {
|
|
pos1 = &listener->eye.position;
|
|
pos0 = &speaker->eye.position;
|
|
}
|
|
|
|
center.x = pos0->x + center_ratio * (pos1->x - pos0->x);
|
|
center.y = pos0->y + center_ratio * (pos1->y - pos0->y);
|
|
center.z = pos0->z + center_ratio * (pos1->z - pos0->z);
|
|
|
|
Camera2_MoveCenterPosAndSpeed_fromEndCenterPos(play, ¢er, FALSE);
|
|
}
|
|
}
|
|
|
|
static void Camera2_Cust_Talk_SetAngleDist(GAME_PLAY* play, ACTOR* speaker, ACTOR* listener, s_xyz* angle, f32 dist) {
|
|
f32 goal_dist;
|
|
|
|
Camera2_Get_GoalDistanceAndDirection(play, &goal_dist, angle);
|
|
angle->x += play->camera.main_data.cust_talk.angle_x;
|
|
angle->y = play->camera.main_data.cust_talk.angle_y;
|
|
goal_dist += dist * 1.46f + play->camera.main_data.cust_talk.distance;
|
|
Camera2_MoveDistancePosAndSpeed(play, goal_dist, FALSE);
|
|
}
|
|
|
|
static void Camera2_SetPos_Cust_Talk(GAME_PLAY* play) {
|
|
ACTOR* speaker = play->camera.main_data.cust_talk.speaker_actor;
|
|
ACTOR* listener = play->camera.main_data.cust_talk.listener_actor;
|
|
|
|
if (speaker != NULL || listener != NULL) {
|
|
f32 dist;
|
|
f32 center_ratio = play->camera.main_data.cust_talk.center_ratio;
|
|
s_xyz angle;
|
|
|
|
if (speaker == NULL || listener == NULL) {
|
|
dist = 0.0f;
|
|
}
|
|
else {
|
|
dist = search_position_distance(&speaker->world.position, &listener->world.position);
|
|
}
|
|
|
|
Camera2_Cust_Talk_ChangeCameraCenterPos_BetweenSpeakerToListener(play, speaker, listener, dist, center_ratio);
|
|
Camera2_Cust_Talk_SetAngleDist(play, speaker, listener, &angle, dist);
|
|
Camera2_MoveDirectionAngleXYZ(play, &angle, 0);
|
|
Camera2_SetEyePos_fromCenterPos(play);
|
|
Camera2_SetView(play);
|
|
}
|
|
}
|
|
|
|
static void Camera2_Cust_Talk_AddCullTimer(GAME_PLAY* play) {
|
|
Camera2_AddCullTimer(&play->camera.main_data.cust_talk.cull_timer, 15.0f);
|
|
}
|
|
|
|
static void Camera2_main_Cust_talk(GAME_PLAY* play) {
|
|
Camera2_SetPos_Cust_Talk(play);
|
|
Camera2_sound_Set_Ground(play);
|
|
Camera2_SetMicPos(play);
|
|
Camera2_Cust_Talk_AddCullTimer(play);
|
|
Camera2_Talk_SetTalking_Cull(play);
|
|
Camera2_change_main_index(play);
|
|
}
|
|
|
|
extern int Camera2_request_BuySikimono_WallPaper(GAME_PLAY* play, xyz_t* center, xyz_t* eye) {
|
|
return Camera2_request_main_inter(play, center, eye, center, eye, 0.6f, 0.3f, 1, 28, 5);
|
|
}
|
|
|
|
extern int Camera2_Inter_set_reverse_mode(GAME_PLAY* play) {
|
|
switch (play->camera.now_main_index) {
|
|
case CAMERA2_PROCESS_INTER:
|
|
{
|
|
play->camera.main_data.inter.flags |= 2;
|
|
break;
|
|
}
|
|
|
|
case CAMERA2_PROCESS_INTER2:
|
|
{
|
|
play->camera.main_data.inter.flags |= 4;
|
|
break;
|
|
}
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
extern int Camera2_request_main_inter(GAME_PLAY* play, xyz_t* start_center, xyz_t* start_eye, xyz_t* goal_center, xyz_t* goal_eye, f32 s0, f32 s1, u32 flags, int morph_counter, int priority) {
|
|
if (Camera2_check_request_main_priority(play, priority) > 0) {
|
|
play->camera.request_data.inter.starting_center_pos = *start_center;
|
|
play->camera.request_data.inter.starting_eye_pos = *start_eye;
|
|
play->camera.request_data.inter.goal_center_pos = *goal_center;
|
|
play->camera.request_data.inter.goal_eye_pos = *goal_eye;
|
|
play->camera.request_data.inter.slope0 = s0;
|
|
play->camera.request_data.inter.slope1 = s1;
|
|
play->camera.request_data.inter.flags = flags;
|
|
play->camera.request_data.inter.morph_counter = morph_counter;
|
|
|
|
Camera2_request_main_index(play, CAMERA2_PROCESS_INTER, priority);
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
static void Camera2_setup_main_Inter(GAME_PLAY* play) {
|
|
Camera2* camera = &play->camera;
|
|
CameraRequestData* request_data = &camera->request_data;
|
|
CameraMainData* main_data = &camera->main_data;
|
|
|
|
main_data->inter.flags = request_data->inter.flags;
|
|
|
|
if (main_data->inter.flags & 1) {
|
|
main_data->inter.starting_center_pos = camera->lookat.center;
|
|
main_data->inter.starting_eye_pos = camera->lookat.eye;
|
|
}
|
|
else {
|
|
main_data->inter.starting_center_pos = request_data->inter.starting_center_pos;
|
|
main_data->inter.starting_eye_pos = request_data->inter.starting_eye_pos;
|
|
}
|
|
|
|
main_data->inter.goal_center_pos = request_data->inter.goal_center_pos;
|
|
main_data->inter.goal_eye_pos = request_data->inter.goal_eye_pos;
|
|
main_data->inter.slope0 = request_data->inter.slope0;
|
|
main_data->inter.slope1 = request_data->inter.slope1;
|
|
main_data->inter.now_delta = 0;
|
|
main_data->inter.max_delta = request_data->inter.morph_counter;
|
|
|
|
Camera2_setup_main_Base(play);
|
|
play->camera.requested_main_index_priority = 0;
|
|
}
|
|
|
|
static void Camera2_Inter_SetPosCenter(GAME_PLAY* play, f32 center_ratio) {
|
|
Camera2* camera = &play->camera;
|
|
xyz_t* center_p = &camera->lookat.center;
|
|
const xyz_t last_center = *center_p;
|
|
|
|
Math3DInDivPos2(&camera->main_data.inter.starting_center_pos, &camera->main_data.inter.goal_center_pos, center_p, center_ratio);
|
|
xyz_t_sub(center_p, &last_center, &camera->movement_velocity);
|
|
}
|
|
|
|
static void Camera2_Inter_SetPosEye(GAME_PLAY* play, f32 eye_ratio) {
|
|
Camera2* camera = &play->camera;
|
|
|
|
Math3DInDivPos2(&camera->main_data.inter.starting_eye_pos, &camera->main_data.inter.goal_eye_pos, &camera->lookat.eye, eye_ratio);
|
|
}
|
|
|
|
static void Camera2_Inter_CounterProc(GAME_PLAY* play) {
|
|
if (play->camera.main_data.inter.flags & 2) {
|
|
int count = play->camera.main_data.inter.now_delta;
|
|
|
|
if (count <= 0) {
|
|
play->camera.main_data.inter.now_delta = 0;
|
|
Camera2_request_main_normal(play, 0, 5);
|
|
}
|
|
else {
|
|
play->camera.main_data.inter.now_delta = count - 1;
|
|
}
|
|
}
|
|
else if (play->camera.main_data.inter.flags & 4) {
|
|
int count = play->camera.main_data.inter.now_delta;
|
|
xyz_t pos;
|
|
s_xyz angle;
|
|
f32 dist;
|
|
int block_x;
|
|
int block_z;
|
|
|
|
if (count <= 0) {
|
|
PLAYER_ACTOR* player = get_player_actor_withoutCheck(play);
|
|
|
|
play->camera.main_data.inter.now_delta = 0;
|
|
Camera2_main_Simple_AngleDistStd(play, &angle, &dist);
|
|
mFI_BlockKind2BkNum(&block_x, &block_z, mRF_BLOCKKIND_SHRINE);
|
|
mFI_BkNum2WposXZ(&pos.x, &pos.z, block_x, block_z);
|
|
pos.x += (UT_X_NUM / 2) * mFI_UT_WORLDSIZE_X_F;
|
|
pos.y = player->actor_class.world.position.y;
|
|
pos.z += (UT_Z_NUM / 2 + 2) * mFI_UT_WORLDSIZE_Z_F;
|
|
Camera2_request_main_simple(play, &pos, &angle, dist, 0, 6);
|
|
}
|
|
else {
|
|
play->camera.main_data.inter.now_delta = count - 1;
|
|
}
|
|
}
|
|
else {
|
|
int count = play->camera.main_data.inter.now_delta;
|
|
int max = play->camera.main_data.inter.max_delta;
|
|
|
|
if (count >= max) {
|
|
play->camera.main_data.inter.now_delta = max;
|
|
}
|
|
else {
|
|
play->camera.main_data.inter.now_delta = count + 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
static void Camera2_SetPos_Inter(GAME_PLAY* play) {
|
|
Camera2* camera = &play->camera;
|
|
f32 ratio;
|
|
int now = camera->main_data.inter.now_delta;
|
|
int max = camera->main_data.inter.max_delta;
|
|
f32 slope0 = camera->main_data.inter.slope0;
|
|
f32 slope1 = camera->main_data.inter.slope1;
|
|
|
|
if (max != 0) {
|
|
ratio = cKF_HermitCalc(
|
|
(f32)now / (f32)max,
|
|
1.0f,
|
|
0.0f, 1.0f,
|
|
slope0, slope1
|
|
);
|
|
}
|
|
else {
|
|
ratio = 0.0f;
|
|
}
|
|
|
|
Camera2_Inter_SetPosCenter(play, ratio);
|
|
Camera2_Inter_SetPosEye(play, ratio);
|
|
Camera2_Inter_CounterProc(play);
|
|
Camera2_DirectionCalc(play);
|
|
Camera2_SetView(play);
|
|
}
|
|
|
|
static void Camera2_main_Inter(GAME_PLAY* play) {
|
|
Camera2_SetPos_Inter(play);
|
|
Camera2_sound_Set_Ground(play);
|
|
Camera2_SetMicPos(play);
|
|
Camera2_change_main_index(play);
|
|
}
|
|
|
|
extern int Camera2_request_main_staff_roll(GAME_PLAY* play, ACTOR* speaker, ACTOR* listener, int priority) {
|
|
if (Camera2_check_request_main_priority(play, priority) > 0) {
|
|
play->camera.request_data.staff_roll.speaker_actor = speaker;
|
|
play->camera.request_data.staff_roll.listener_actor = listener;
|
|
Camera2_request_main_index(play, CAMERA2_PROCESS_STAFF_ROLL, priority);
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
static void Camera2_setup_main_Staff_roll(GAME_PLAY* play) {
|
|
play->camera.main_data.staff_roll.last_center_pos = play->camera.lookat.center;
|
|
play->camera.main_data.staff_roll.last_eye_pos = play->camera.lookat.eye;
|
|
play->camera.main_data.staff_roll.last_distance = play->camera.focus_distance;
|
|
play->camera.main_data.staff_roll.last_direction = play->camera.direction;
|
|
play->camera.main_data.staff_roll.speaker_actor = play->camera.request_data.staff_roll.speaker_actor;
|
|
play->camera.main_data.staff_roll.listener_actor = play->camera.request_data.staff_roll.listener_actor;
|
|
play->camera.main_data.staff_roll.rotation_y_delta = 0;
|
|
play->camera.main_data.staff_roll.r_delta = 20;
|
|
play->camera.main_data.staff_roll.rotation_x_delta = 40;
|
|
play->camera.main_data.staff_roll.flags = 1;
|
|
play->camera.main_data.staff_roll.dist_counter = 0;
|
|
play->camera.main_data.staff_roll.morph_counter = 320;
|
|
|
|
Camera2_setup_main_Base(play);
|
|
play->camera.requested_main_index_priority = 0;
|
|
}
|
|
|
|
static void Camera2_Staff_Roll_Center(GAME_PLAY* play, ACTOR* speaker, ACTOR* listener, xyz_t* center, f32 distance, f32 t, int update) {
|
|
Camera2* camera = &play->camera;
|
|
|
|
xyz_t* pos0;
|
|
xyz_t* pos1;
|
|
xyz_t goal_center;
|
|
f32 y_shift;
|
|
|
|
f32 center_x;
|
|
f32 center_y;
|
|
f32 center_z;
|
|
|
|
f32 h;
|
|
f32 r_rot;
|
|
f32 y_rot_x;
|
|
f32 y_rot_z;
|
|
int temp;
|
|
s16 temp2;
|
|
|
|
*center = ZeroVec;
|
|
if (speaker != NULL || listener != NULL) {
|
|
if (speaker == NULL) {
|
|
pos0 = &listener->eye.position;
|
|
pos1 = pos0;
|
|
}
|
|
else if (listener == NULL) {
|
|
pos1 = &speaker->eye.position;
|
|
pos0 = pos1;
|
|
}
|
|
else {
|
|
pos1 = &listener->eye.position;
|
|
pos0 = &speaker->eye.position;
|
|
}
|
|
|
|
y_shift = 17.0f;
|
|
if (!F32_IS_ZERO(distance)) {
|
|
y_shift -= -60.0f / distance;
|
|
}
|
|
|
|
center_x = (pos0->x + pos1->x) / 2.0f;
|
|
center_y = (pos0->y + pos1->y) / 2.0f - y_shift;
|
|
center_z = (pos0->z + pos1->z) / 2.0f;
|
|
|
|
h = cKF_HermitCalc(t, 1.0f, 0.0f, 1.0f, 0.49f, 0.0f);
|
|
temp2 = ((f32)camera->main_data.staff_roll.r_delta / 4600.0f) * 65535.0f;
|
|
h *= ((1.0f + sin_s(temp2) * 0.2f) - 0.2f) * 45.0f;
|
|
|
|
// likely fakematch
|
|
temp = (int)((-(f32)camera->main_data.staff_roll.rotation_y_delta / 2600.0f) * 65535.0f) + 0x10000;
|
|
temp += camera->main_data.staff_roll.last_direction.y;
|
|
y_rot_x = sin_s(temp + -0x4000);
|
|
|
|
goal_center.y = center_y;
|
|
goal_center.x = center_x + h * y_rot_x;
|
|
|
|
// likely fakematch
|
|
temp = (int)((-(f32)camera->main_data.staff_roll.rotation_y_delta / 2600.0f) * 65535.0f) + 0x10000;
|
|
temp += camera->main_data.staff_roll.last_direction.y;
|
|
y_rot_z = cos_s(temp + -0x4000);
|
|
|
|
goal_center.z = center_z + h * y_rot_z;
|
|
|
|
*center = goal_center;
|
|
|
|
if (update) {
|
|
Camera2_MoveCenterPosAndSpeed_fromEndCenterPos(play, &goal_center, FALSE);
|
|
}
|
|
}
|
|
}
|
|
|
|
static void Camera2_Staff_Roll_DistAngle(GAME_PLAY* play, ACTOR* speaker, ACTOR* listener, s_xyz* angle, f32 distance) {
|
|
Camera2* camera = &play->camera;
|
|
s16 temp;
|
|
f32 dist;
|
|
|
|
temp = ((f32)camera->main_data.staff_roll.r_delta / 4600.0f) * 65535.0f;
|
|
dist = ((sin_s(temp) * 0.2f + 1.0f) - 0.2f) * 575.0f;
|
|
temp = ((f32)camera->main_data.staff_roll.rotation_x_delta / 4000.0f) * 65536.0f;
|
|
|
|
angle->x = (s16)(sin_s(temp) * 5000.0f);
|
|
angle->y = (s16)((-(f32)camera->main_data.staff_roll.rotation_y_delta / 2600.0f) * 65535.0f) + camera->main_data.staff_roll.last_direction.y + (u16)SHT_MIN_S;
|
|
angle->z = 0;
|
|
|
|
Camera2_MoveDistancePosAndSpeed(play, dist, FALSE);
|
|
}
|
|
|
|
static void Camera2_main_Staff_Roll_SetPos(GAME_PLAY* play) {
|
|
Camera2* camera = &play->camera;
|
|
ACTOR* speaker = camera->main_data.staff_roll.speaker_actor;
|
|
ACTOR* listener = camera->main_data.staff_roll.listener_actor;
|
|
CameraMainData* main_data = &camera->main_data;
|
|
f32 distance;
|
|
xyz_t center;
|
|
xyz_t eye;
|
|
xyz_t last_center;
|
|
s_xyz angle;
|
|
|
|
if (speaker != NULL || listener != NULL) {
|
|
s8* kk_save_area = mEv_get_save_area(mEv_EVENT_KK_SLIDER, 10);
|
|
|
|
if (speaker == NULL || listener == NULL) {
|
|
distance = 0.0f;
|
|
}
|
|
else {
|
|
distance = search_position_distance(&speaker->world.position, &listener->world.position);
|
|
}
|
|
|
|
/* TODO: cast kk_save_area to correct struct type */
|
|
if (((*(u16*)(kk_save_area + 2)) & 0x8000) && (main_data->staff_roll.flags & 2) == 0) {
|
|
/* Start camera sequence? */
|
|
main_data->staff_roll.flags &= ~1;
|
|
main_data->staff_roll.flags |= 2;
|
|
main_data->staff_roll.morph_counter = 240;
|
|
}
|
|
|
|
if (main_data->staff_roll.flags & 2) {
|
|
Camera2_Lock_SetCenterPos(play, &main_data->staff_roll.last_center_pos, main_data->staff_roll.morph_counter);
|
|
Camera2_Lock_SetEyePos(play, &main_data->staff_roll.last_eye_pos, main_data->staff_roll.morph_counter);
|
|
Camera2_DirectionCalc(play);
|
|
|
|
if (main_data->staff_roll.morph_counter != 0) {
|
|
main_data->staff_roll.morph_counter--;
|
|
}
|
|
else {
|
|
camera->focus_distance = main_data->staff_roll.last_distance;
|
|
camera->direction = main_data->staff_roll.last_direction;
|
|
Camera2_change_priority(play, 0);
|
|
Camera2_request_main_normal(play, 0, 5);
|
|
}
|
|
}
|
|
else if (main_data->staff_roll.flags & 1) {
|
|
xyz_t* center_vel_p = &camera->movement_velocity;
|
|
xyz_t* center_p = &camera->lookat.center;
|
|
u32 morph_counter = main_data->staff_roll.morph_counter;
|
|
f32 t = (320.0f - (f32)morph_counter) / 320.0f;
|
|
|
|
last_center = *center_p;
|
|
|
|
|
|
|
|
Camera2_Staff_Roll_Center(play, speaker, listener, ¢er, distance, t, FALSE);
|
|
Camera2_Lock_SetCenterPos(play, ¢er, main_data->staff_roll.morph_counter);
|
|
center_vel_p->x = center_p->x - last_center.x;
|
|
center_vel_p->y = center_p->y - last_center.y;
|
|
center_vel_p->z = center_p->z - last_center.z;
|
|
Camera2_Staff_Roll_DistAngle(play, speaker, listener, &angle, distance);
|
|
Camera2_PolaPosCalc(&eye, angle.x + (u16)SHT_MIN_S, angle.y + (u16)SHT_MIN_S, ¢er, camera->focus_distance);
|
|
Camera2_Lock_SetEyePos(play, &eye, main_data->staff_roll.morph_counter);
|
|
|
|
if (main_data->staff_roll.morph_counter != 0) {
|
|
main_data->staff_roll.morph_counter--;
|
|
}
|
|
else {
|
|
main_data->staff_roll.flags &= ~1;
|
|
}
|
|
|
|
Camera2_DirectionCalc(play);
|
|
}
|
|
else {
|
|
Camera2_Staff_Roll_Center(play, speaker, listener, ¢er, distance, 1.0f, TRUE);
|
|
Camera2_Staff_Roll_DistAngle(play, speaker, listener, &angle, distance);
|
|
Camera2_MoveDirectionAngleXYZ_morph(play, &angle, 0);
|
|
Camera2_SetEyePos_fromCenterPos(play);
|
|
|
|
main_data->staff_roll.r_delta++;
|
|
if (main_data->staff_roll.r_delta > 4600) {
|
|
main_data->staff_roll.r_delta = 0;
|
|
}
|
|
|
|
main_data->staff_roll.rotation_x_delta++;
|
|
if (main_data->staff_roll.rotation_x_delta > 4000) {
|
|
main_data->staff_roll.rotation_x_delta = 0;
|
|
}
|
|
}
|
|
|
|
main_data->staff_roll.rotation_y_delta++;
|
|
if (main_data->staff_roll.rotation_y_delta > 2600) {
|
|
main_data->staff_roll.rotation_y_delta = 0;
|
|
}
|
|
|
|
Camera2_SetView(play);
|
|
}
|
|
}
|
|
|
|
static void Camera2_main_Staff_roll(GAME_PLAY* play) {
|
|
Camera2_main_Staff_Roll_SetPos(play);
|
|
Camera2_sound_Set_Ground(play);
|
|
Camera2_SetMicPos(play);
|
|
Camera2_change_main_index(play);
|
|
}
|
|
|
|
extern void Init_Camera2(GAME_PLAY* play) {
|
|
static const Camera2 init_camera_data = {
|
|
// lookat
|
|
{
|
|
{ 0.0f, 876.81238f, 876.81238f }, // eye
|
|
{ 0.0f, 0.0f, 0.0f }, // center
|
|
{ 0.0f, 1.0f, 0.0f } // up
|
|
},
|
|
// perspective
|
|
{
|
|
20.0f, // fov_y
|
|
4.0f/3.0f, // aspect_ratio
|
|
200.0f, // near
|
|
1600.0f, // far
|
|
1.0f // scale
|
|
},
|
|
{ DEG2SHORT_ANGLE(-135.0f), DEG2SHORT_ANGLE(-180.0f), DEG2SHORT_ANGLE(0.0f) }, // direction
|
|
{ 0, 0, 0 }, // direction_velocity
|
|
{ 0.0f, 0.0f, 0.0f }, // movement_velocity
|
|
620.0f, // focus_distance
|
|
0.0f, // focus_distance_velocity
|
|
1, // indoor_distance_addition_idx
|
|
1, // indoor_direction_addition_idx
|
|
CAMERA2_PROCESS_NORMAL, // now_main_index
|
|
CAMERA2_PROCESS_NORMAL, // last_main_index
|
|
CAMERA2_PROCESS_NORMAL, // requested_main_index
|
|
-1, // requested_main_index_priority
|
|
FALSE, // requested_main_index_flag
|
|
{ 0 }, // main_data
|
|
{ 0 }, // request_data
|
|
{ 0.0f, 876.81238f, 876.81238f }, // mic_pos
|
|
0, // flags
|
|
{ 0.0f, 0.0f, 0.0f }, // offset_eye
|
|
{ 0.0f, 0.0f, 0.0f } // offset_center
|
|
};
|
|
|
|
play->camera = init_camera_data;
|
|
}
|
|
|
|
typedef void (*CAMERA2_MAIN_INDEX_SETUP_PROC)(GAME_PLAY*);
|
|
|
|
static void Camera2_change_main_index(GAME_PLAY* play) {
|
|
static const CAMERA2_MAIN_INDEX_SETUP_PROC proc[CAMERA2_PROCESS_NUM] = {
|
|
&Camera2_setup_main_Stop,
|
|
&Camera2_setup_main_Normal,
|
|
&Camera2_setup_main_Wade,
|
|
&Camera2_setup_main_Talk,
|
|
&Camera2_setup_main_Demo,
|
|
&Camera2_setup_main_Item,
|
|
&Camera2_setup_main_Lock,
|
|
&Camera2_setup_main_Door,
|
|
&Camera2_setup_main_Simple,
|
|
&Camera2_setup_main_Cust_talk,
|
|
&Camera2_setup_main_Inter,
|
|
&Camera2_setup_main_Staff_roll,
|
|
&Camera2_setup_main_Inter
|
|
};
|
|
|
|
if (play->camera.requested_main_index_flag != TRUE ||
|
|
play->camera.requested_main_index < CAMERA2_PROCESS_STOP ||
|
|
play->camera.requested_main_index >= CAMERA2_PROCESS_NUM ||
|
|
proc[play->camera.requested_main_index] == NULL
|
|
) {
|
|
return;
|
|
}
|
|
else {
|
|
CAMERA2_MAIN_INDEX_SETUP_PROC setup_proc = proc[play->camera.requested_main_index];
|
|
(*setup_proc)(play);
|
|
}
|
|
}
|
|
|
|
typedef void (*CAMERA2_MAIN_INDEX_PROC)(GAME_PLAY*);
|
|
extern void Camera2_process(GAME_PLAY* play) {
|
|
static const CAMERA2_MAIN_INDEX_PROC proc[CAMERA2_PROCESS_NUM] = {
|
|
&Camera2_main_Stop,
|
|
&Camera2_main_Normal,
|
|
&Camera2_main_Wade,
|
|
&Camera2_main_Talk,
|
|
&Camera2_main_Demo,
|
|
&Camera2_main_Item,
|
|
&Camera2_main_Lock,
|
|
&Camera2_main_Door,
|
|
&Camera2_main_Simple,
|
|
&Camera2_main_Cust_talk,
|
|
&Camera2_main_Inter,
|
|
&Camera2_main_Staff_roll,
|
|
&Camera2_main_Inter
|
|
};
|
|
|
|
if (
|
|
play->camera.now_main_index < CAMERA2_PROCESS_STOP ||
|
|
play->camera.now_main_index >= CAMERA2_PROCESS_NUM ||
|
|
proc[play->camera.now_main_index] == NULL
|
|
) {
|
|
return;
|
|
}
|
|
else {
|
|
CAMERA2_MAIN_INDEX_PROC main_proc = proc[play->camera.now_main_index];
|
|
|
|
(*main_proc)(play);
|
|
Camera2_process_other_func2(play);
|
|
}
|
|
}
|
|
|
|
extern void Camera2_draw(GAME_PLAY* play) { }
|