diff --git a/include/PreRender.h b/include/PreRender.h index c0811176..dc61b7ca 100644 --- a/include/PreRender.h +++ b/include/PreRender.h @@ -9,11 +9,11 @@ extern "C" { #endif -#define BG2D_FLAGS_1 (1 << 0) -#define BG2D_FLAGS_2 (1 << 1) -#define BG2D_FLAGS_AC_THRESHOLD (1 << 2) -#define BG2D_FLAGS_LOAD_S2DEX2 (1 << 3) -#define BG2D_FLAGS_COPY (1 << 4) +#define BG2D_FLAGS_SAVE_OTHERMODE (1 << 0) /* Keep othermode settings */ +#define BG2D_FLAGS_SAVE_COMBINER (1 << 1) /* Keep combiner settings */ +#define BG2D_FLAGS_AC_THRESHOLD (1 << 2) /* Alpha compare uses threshold */ +#define BG2D_FLAGS_LOAD_S2DEX2 (1 << 3) /* Load S2DEX2 ucode */ +#define BG2D_FLAGS_COPY (1 << 4) /* Direct copy instead of combined */ typedef struct prerender_s { /* 0x00 */ u16 width; diff --git a/src/PreRender.c b/src/PreRender.c index 83336ddc..05f879f2 100644 --- a/src/PreRender.c +++ b/src/PreRender.c @@ -48,7 +48,7 @@ extern void wallpaper_draw1(PreRenderBackground2DParams* bg2D, Gfx** gfxp) { bg->b.frameW = bg2D->width * (1 << 2); bg->b.frameH = bg2D->height * (1 << 2); - if (!(bg2D->flags & BG2D_FLAGS_1)) { + if (!(bg2D->flags & BG2D_FLAGS_SAVE_OTHERMODE)) { gDPSetOtherMode(gfx++, bg2D->tt | G_CYC_COPY, alphaCompare); } @@ -60,14 +60,14 @@ extern void wallpaper_draw1(PreRenderBackground2DParams* bg2D, Gfx** gfxp) { bg->b.tmemH = (1 << 10) / bg2D->yScale; bg->s.imageYorig = bg->b.imageY; - if (!(bg2D->flags & BG2D_FLAGS_1)) { + if (!(bg2D->flags & BG2D_FLAGS_SAVE_OTHERMODE)) { gDPSetOtherMode(gfx++, bg2D->tt | G_AD_DISABLE | G_CD_DISABLE | G_TC_FILT, AA_EN | CVG_X_ALPHA | ALPHA_CVG_SEL | GBL_c1(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_BL, G_BL_1MA) | GBL_c2(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_BL, G_BL_1MA) | alphaCompare); } - if (!(bg2D->flags & BG2D_FLAGS_2)) { + if (!(bg2D->flags & BG2D_FLAGS_SAVE_COMBINER)) { gDPSetCombineLERP(gfx++, 0, 0, 0, TEXEL0, 0, 0, 0, 1, 0, 0, 0, TEXEL0, 0, 0, 0, 1); } @@ -202,8 +202,9 @@ extern void PreRender_CopyRGBC(PreRender* render, Gfx** gfxp, int width, int hei G_AC_NONE | G_ZS_PRIM | G_RM_OPA_SURF | G_RM_OPA_SURF2); gDPSetCombineLERP(gfx++, 0, 0, 0, TEXEL0, 0, 0, 0, 1, 0, 0, 0, TEXEL0, 0, 0, 0, 1); - wallpaper_draw(&gfx, render->framebuffer_bak, 0, render->width_bak, render->height_bak, 0, 2, 0, 0, width, height, - 1.0f, 1.0f, 11); + wallpaper_draw(&gfx, render->framebuffer_bak, 0, render->width_bak, render->height_bak, G_IM_FMT_RGBA, G_IM_SIZ_16b, + 0, 0, width, height, 1.0f, 1.0f, + BG2D_FLAGS_SAVE_OTHERMODE | BG2D_FLAGS_SAVE_COMBINER | BG2D_FLAGS_LOAD_S2DEX2); gfx = gfx_SetUpCFB(gfx, render->framebuffer_bak, render->width_bak, render->height_bak); @@ -259,9 +260,9 @@ extern void PreRender_CopyRGBC(PreRender* render, Gfx** gfxp, int width, int hei h = lrt + remain; gDPLoadTextureTile(gfx++, render->framebuffer_bak, G_IM_FMT_I, G_IM_SIZ_8b, (render->width_bak << 1), - (render->height_bak << 1), (uls * 2), ult, ((lrs_max * 2) - 1), /* this has issues */ - (lrt_max - 1), 0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOLOD, - G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOLOD); + (render->height_bak << 1), (uls * 2), ult, ((lrs_max * 2) - 1), (lrt_max - 1), 0, + G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, + G_TX_NOLOD); gSPTextureRectangle(gfx++, ((u32)lrs) * 4, ((u32)lrt) << G_TEXTURE_IMAGE_FRAC, ((u32)w) << G_TEXTURE_IMAGE_FRAC, ((u32)h) << G_TEXTURE_IMAGE_FRAC, G_TX_RENDERTILE, (uls * 2) << 5, ult << 5, (1 << 1) << 10, diff --git a/src/ac_mural.c b/src/ac_mural.c index ee693894..897d7ebb 100644 --- a/src/ac_mural.c +++ b/src/ac_mural.c @@ -24,8 +24,8 @@ ACTOR_PROFILE Mural_Profile = { NULL, }; -static u8 tex[aML_MURAL_NUM][(32 * 32) / 2]; -static u16 pal[aML_MURAL_NUM][16]; +static u8 tex[aML_MURAL_NUM][(32 * 32) / 2] ATTRIBUTE_ALIGN(32); +static u16 pal[aML_MURAL_NUM][16] ATTRIBUTE_ALIGN(32); static void Mural_Actor_ct(ACTOR* actorx, GAME* game) { MURAL_ACTOR* mural = (MURAL_ACTOR*)actorx; diff --git a/src/m_camera2.c b/src/m_camera2.c index 99f8fe97..d090bcfa 100644 --- a/src/m_camera2.c +++ b/src/m_camera2.c @@ -10,2862 +10,2670 @@ #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; + 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); + xyz_t_sub(&camera->lookat.eye, &camera->lookat.center, &eye_minus_center); + dir = camera->direction; + mag = Math3d_normalizeXyz_t(&eye_minus_center); - if (F32_IS_ZERO(mag)) { - 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; - } + if (F32_IS_ZERO(mag)) { + 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; + 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; + 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; - } + 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; + 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; - } + 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; + return FALSE; } static f32 Camera2_GetUnderBorderAdjust() { - if (Camera2_InDoorCheck()) { - return 0.0f; - } - else { - return -15.0f; - } + 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; - 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; + *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); + 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* camera = &play->camera; - Camera2_SetEyePos_fromCenterPosCalc(play, &camera->lookat.center, &camera->lookat.eye); + 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; + s_xyz* dir; + s_xyz* dir_vel; + Camera2* camera = &play->camera; - dir = &camera->direction; - dir_vel = &camera->direction_velocity; + 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; + 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 = 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; - dir_vel->x = dir->x - last_dir.x; - dir_vel->y = dir->y - last_dir.y; - dir_vel->z = dir->z - last_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; + 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; + 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; + 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); + 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; - } + 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; + 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; - } + 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; + *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; + 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; + eye = &camera->lookat.eye; + view = &play->view; + center = &camera->lookat.center; - if (F32_IS_ZERO(Math3DLength(eye, center))) { - 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 (F32_IS_ZERO(Math3DLength(eye, center))) { + eye->z = center->z + 1.0f; } - } - if (F32_IS_ZERO(camera->perspective.fov_y)) { - camera->perspective.fov_y += 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); - 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); + 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 (F32_IS_ZERO(camera->perspective.fov_y)) { + 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; - } +static f32 Camera2_BorderSize() { + int type = mFI_GET_TYPE(mFI_GetFieldId()); + f32 size = 110.0f; - return size; + 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 }; + 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((GAME*)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; + PLAYER_ACTOR* player = get_player_actor_withoutCheck(play); + xyz_t entrance_pos; int block_x; int block_z; - if (count <= 0) { - PLAYER_ACTOR* player = get_player_actor_withoutCheck(play); + 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); + } - 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; + *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 (count >= max) { - play->camera.main_data.inter.now_delta = max; + if (Camera2_InDoorCheck()) { + *z_min += -mFI_UT_WORLDSIZE_Z_F; } - 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_GetLongBorderScale(GAME_PLAY* play, f32* scale) { + if (play->camera.flags & 1) { + *scale = 1.5f; + } else { + *scale = 1.0f; + } } -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); +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); } -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); +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; - } - - 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_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_Staff_Roll_Center(GAME_PLAY* play, ACTOR* speaker, ACTOR* listener, xyz_t* center, f32 distance, f32 t, int update) { - Camera2* camera = &play->camera; +static void Camera2_ChangeCameraPos_inBlock(GAME_PLAY* play, const xyz_t* pos, xyz_t* end_pos) { + f32 x0; + f32 x1; + f32 z0; + f32 z1; - xyz_t* pos0; - xyz_t* pos1; - xyz_t goal_center; - f32 y_shift; + f32 x00; + f32 x01; + f32 z00; + f32 z01; - f32 center_x; - f32 center_y; - f32 center_z; + f32 scale; - f32 h; - f32 r_rot; - f32 y_rot_x; - f32 y_rot_z; - int temp; - s16 temp2; + Camera2_GetLongBorderScale(play, &scale); + Camera2_GetBorder(play, &x0, &x1, &z1, &z0); + Camera2_GetBorderScale(play, 1.0f, &x00, &x01, &z01, &z00); - *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; + *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; + } } - y_shift = 17.0f; - if (!F32_IS_ZERO(distance)) { - y_shift -= -60.0f / distance; + 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; + } } - - 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); +extern xyz_t* Camera2_getEyePos_p() { + return &((GAME_PLAY*)gamePT)->camera.lookat.eye; } -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; +extern xyz_t* Camera2_getCenterPos_p() { + return &((GAME_PLAY*)gamePT)->camera.lookat.center; +} - if (speaker != NULL || listener != NULL) { - u8* kk_save_area = mEv_get_save_area(mEv_EVENT_KK_SLIDER, 10); +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); +} - if (speaker == NULL || listener == NULL) { - distance = 0.0f; - } - else { - distance = search_position_distance(&speaker->world.position, &listener->world.position); +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; + } } - /* 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; + 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; + } } - 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); + return FALSE; +} - 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); +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]; +} + +static void Camera2_SetMicPos(GAME_PLAY* play) { + PLAYER_ACTOR* player = get_player_actor_withoutCheck(play); + + if (player != NULL) { + xyz_t* player_pos = &player->actor_class.world.position; + Camera2* camera = &play->camera; + xyz_t* lookat = &camera->lookat.center; + xyz_t* eye = &camera->lookat.eye; + f32 x; + f32 t; + s16 s; + s16 s2; + + if (Camera2_Check_MicPosFix()) { + xyz_t* mic_pos; + 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_pos->x + x; + mic_pos->y = player_pos->y + 240.0f; + mic_pos->z = player_pos->z + z; + } else { + s_xyz* dir = &camera->direction; + s16 dirX; + f32 p; + f32 x0; + f32 cosX; + f32 sinX; + f32 abs_cosX; + s16 dirY; + f32 cosY; + f32 sinY; + xyz_t* mic_pos; + + x0 = (eye->y - player_pos->y) - 472.0f; + t = (x0 * 0.796f) + 261.0f; + dirX = dir->x; + cosX = t * cos_s(dirX); + sinX = t * sin_s(dirX); + + 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; + abs_cosX = ABS(cosX) + p; + dirY = dir->y; + cosY = abs_cosX * cos_s(dirY); + sinY = abs_cosX * sin_s(dirY); + mic_pos = Camera2_getMicPos_p(play); + + mic_pos->x = eye->x + sinY; + mic_pos->y = eye->y + sinX; + mic_pos->z = eye->z + cosY; + } + } +} + +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); - } } - 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); +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); +} - if (main_data->staff_roll.morph_counter != 0) { - main_data->staff_roll.morph_counter--; - } - else { - main_data->staff_roll.flags &= ~1; - } +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; - 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); + 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); + } - 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; - } + play->camera.request_data.talk.flags = 0; + Camera2_request_main_index(play, CAMERA2_PROCESS_TALK, priority); + return TRUE; } - main_data->staff_roll.rotation_y_delta++; - if (main_data->staff_roll.rotation_y_delta > 2600) { - main_data->staff_roll.rotation_y_delta = 0; + 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((GAME*)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; +} + +static void Camera2_Door_SetEyePos(GAME_PLAY* play, int step) { + Camera2* camera = &play->camera; + CameraLookat* lookat = &camera->lookat; + xyz_t* center = &lookat->center; + xyz_t* eye = &lookat->eye; + s_xyz* dir_vel = &camera->direction_velocity; + f32* dist_p; + f32 last_dist; + s_xyz* dir; + f32* vel_p; + s_xyz angle; + + camera->focus_distance = camera->focus_distance; // what? + + dist_p = &camera->focus_distance; + last_dist = camera->focus_distance; + dir = &camera->direction; + vel_p = &camera->focus_distance_velocity; + + angle.x = (s16)-0x7194; + angle.y = (s16)-0x8000; + angle.z = (s16)0; + + inter_float(dist_p, (float)350.0f, (int)step); + *vel_p = last_dist - *dist_p; // inverted velocity? + + if (step == 0) { + *dir = angle; + + dir_vel->x = 0; + dir_vel->y = 0; + dir_vel->z = 0; + } 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, dir->x + (u16)SHT_MIN_S, dir->y + (u16)SHT_MIN_S, center, *dist_p); +} + +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) { + u8* 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); + 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 - }; + 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; + 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 - }; + 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); - } + 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 - }; + 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); - } + 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) { } +extern void Camera2_draw(GAME_PLAY* play) { +} diff --git a/src/m_submenu_ovl.c b/src/m_submenu_ovl.c index 24db2ace..52f5203b 100644 --- a/src/m_submenu_ovl.c +++ b/src/m_submenu_ovl.c @@ -8,251 +8,283 @@ #include "sys_matrix.h" static void mSM_setup_view(Submenu* submenu, GRAPH* graph, int init_flag) { - Gfx* gfx; - Mtx* mtx; - View* view; + Gfx* gfx; + Mtx* mtx; + View* view; - if (init_flag) { - mtx = GRAPH_ALLOC_TYPE(graph, Mtx, 1); - mFont_CulcOrthoMatrix(mtx); - submenu->overlay->projection_matrix = mtx; - } - else { - mtx = submenu->overlay->projection_matrix; - } - - OPEN_DISP(graph); - gfx = NOW_POLY_OPA_DISP; - - if (init_flag == FALSE) { - if (submenu->mode != 4) { - view = &((GAME_PLAY*)gamePT)->view; - } - else { - view = &((GAME_TRADEMARK*)gamePT)->view; // I'm not sure this is the correct game subclass + if (init_flag) { + mtx = GRAPH_ALLOC_TYPE(graph, Mtx, 1); + mFont_CulcOrthoMatrix(mtx); + submenu->overlay->projection_matrix = mtx; + } else { + mtx = submenu->overlay->projection_matrix; } - gDPPipeSync(gfx++); - gDPSetScissor(gfx++, G_SC_NON_INTERLACE, view->screen.l, view->screen.top, view->screen.r, view->screen.bottom); - gSPViewport(gfx++, &view->viewport); - gDPSetScissor(gfx++, G_SC_NON_INTERLACE, 0, 0, 640, 480); - } + OPEN_DISP(graph); + gfx = NOW_POLY_OPA_DISP; - gSPMatrix(gfx++, mtx, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_PROJECTION); + if (init_flag == FALSE) { + if (submenu->mode != 4) { + view = &((GAME_PLAY*)gamePT)->view; + } else { + view = &((GAME_TRADEMARK*)gamePT)->view; // I'm not sure this is the correct game subclass + } - SET_POLY_OPA_DISP(gfx); - CLOSE_DISP(graph); + gDPPipeSync(gfx++); + gDPSetScissor(gfx++, G_SC_NON_INTERLACE, view->screen.l, view->screen.top, view->screen.r, view->screen.bottom); + gSPViewport(gfx++, &view->viewport); + gDPSetScissor(gfx++, G_SC_NON_INTERLACE, 0, 0, 640, 480); + } + + gSPMatrix(gfx++, mtx, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_PROJECTION); + + SET_POLY_OPA_DISP(gfx); + CLOSE_DISP(graph); } -static void mSM_change_view(GRAPH* graph, s16 angle, int width, int height, f32 eye_dist, f32 y_lookAt, f32 vp_x, f32 vp_y) { - static Vp viewport_data = { - { 0, 0, 511, 0 }, - { 0, 0, 511, 0 } - }; +static void mSM_change_view(GRAPH* graph, s16 angle, int width, int height, f32 eye_dist, f32 y_lookAt, f32 vp_x, + f32 vp_y) { + static Vp viewport_data = { { 0, 0, 511, 0 }, { 0, 0, 511, 0 } }; - static Lights0 light_data = { - { { 105, 90, 90 }, 0, { 105, 90, 90 }, 0 }, // Ambient - { { { 255, 255, 245 }, 0, { 255, 255, 245 }, 0, { 0, 60, 60 }, 0 } } // Light - }; + static Lights0 light_data = { + { { 105, 90, 90 }, 0, { 105, 90, 90 }, 0 }, // Ambient + { { { 255, 255, 245 }, 0, { 255, 255, 245 }, 0, { 0, 60, 60 }, 0 } } // Light + }; - Vp* viewport = GRAPH_ALLOC_TYPE(graph, Vp, 1); - Mtx* mtx = GRAPH_ALLOC_TYPE(graph, mtx, 1); - u16 persp_norm; - f32 y_eye; - f32 z_eye; + Vp* viewport = GRAPH_ALLOC_TYPE(graph, Vp, 1); + Mtx* mtx = GRAPH_ALLOC_TYPE(graph, mtx, 1); + u16 persp_norm; + f32 y_eye; + f32 z_eye; - if (viewport == NULL) { - viewport = &viewport_data; - } - else { - viewport->vp.vscale[0] = width << 1; - viewport->vp.vtrans[0] = (width << 1) + (s16)vp_x; - - viewport->vp.vscale[1] = height << 1; - viewport->vp.vtrans[1] = (height << 1) + (s16)vp_y; - - viewport->vp.vscale[2] = 511; - viewport->vp.vtrans[2] = 511; + if (viewport == NULL) { + viewport = &viewport_data; + } else { + viewport->vp.vscale[0] = width << 1; + viewport->vp.vtrans[0] = (width << 1) + (s16)vp_x; - viewport->vp.vscale[3] = 0; - viewport->vp.vtrans[3] = 0; - } + viewport->vp.vscale[1] = height << 1; + viewport->vp.vtrans[1] = (height << 1) + (s16)vp_y; - OPEN_DISP(graph); + viewport->vp.vscale[2] = 511; + viewport->vp.vtrans[2] = 511; - gSPViewport(NOW_POLY_OPA_DISP++, viewport); + viewport->vp.vscale[3] = 0; + viewport->vp.vtrans[3] = 0; + } - CLOSE_DISP(graph); + OPEN_DISP(graph); - if (width != 256) { - guPerspective( - mtx, - &persp_norm, - 35.0f, - (f32)width / (f32)height, - 1.0f, - 2000.0f, - 1.0f - ); - } - else { - guPerspective( - mtx, - &persp_norm, - 20.0f, - (f32)width / (f32)height, - 100.0f, - 800.0f, - 1.0f - ); - } + gSPViewport(NOW_POLY_OPA_DISP++, viewport); - OPEN_DISP(graph); + CLOSE_DISP(graph); - gSPPerspNormalize(NOW_POLY_OPA_DISP++, persp_norm); - gSPMatrix(NOW_POLY_OPA_DISP++, mtx, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_PROJECTION); + if (width != 256) { + guPerspective(mtx, &persp_norm, 35.0f, (f32)width / (f32)height, 1.0f, 2000.0f, 1.0f); + } else { + guPerspective(mtx, &persp_norm, 20.0f, (f32)width / (f32)height, 100.0f, 800.0f, 1.0f); + } - CLOSE_DISP(graph); + OPEN_DISP(graph); - if (angle == DEG2SHORT_ANGLE(90.0f)) { - angle = 0x4100; - } - else if (angle == DEG2SHORT_ANGLE(-90.0f)) { - angle = -0x3F00; - } + gSPPerspNormalize(NOW_POLY_OPA_DISP++, persp_norm); + gSPMatrix(NOW_POLY_OPA_DISP++, mtx, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_PROJECTION); - y_eye = y_lookAt + eye_dist * sin_s(angle); - z_eye = eye_dist * cos_s(angle); + CLOSE_DISP(graph); - if (angle < DEG2SHORT_ANGLE(-90.0f) || angle > DEG2SHORT_ANGLE(90.0f)) { - guLookAt( - mtx, - 0.0f, y_eye, z_eye, - 0.0f, y_lookAt, 0.0f, - 0.0f, -1.0f, 0.0f - ); - } - else { - guLookAt( - mtx, - 0.0f, y_eye, z_eye, - 0.0f, y_lookAt, 0.0f, - 0.0f, 1.0f, 0.0f - ); - } + if (angle == DEG2SHORT_ANGLE(90.0f)) { + angle = 0x4100; + } else if (angle == DEG2SHORT_ANGLE(-90.0f)) { + angle = -0x3F00; + } - OPEN_DISP(graph); + y_eye = y_lookAt + eye_dist * sin_s(angle); + z_eye = eye_dist * cos_s(angle); - gSPMatrix(NOW_POLY_OPA_DISP++, mtx, G_MTX_NOPUSH | G_MTX_MUL | G_MTX_PROJECTION); - gSPSetLights0(NOW_POLY_OPA_DISP++, light_data); - SET_POLY_OPA_DISP(gfx_set_fog_nosync(NOW_POLY_OPA_DISP++, 255, 255, 255, 255, 1000, 1000)); + if (angle < DEG2SHORT_ANGLE(-90.0f) || angle > DEG2SHORT_ANGLE(90.0f)) { + guLookAt(mtx, 0.0f, y_eye, z_eye, 0.0f, y_lookAt, 0.0f, 0.0f, -1.0f, 0.0f); + } else { + guLookAt(mtx, 0.0f, y_eye, z_eye, 0.0f, y_lookAt, 0.0f, 0.0f, 1.0f, 0.0f); + } - CLOSE_DISP(graph); + OPEN_DISP(graph); + + gSPMatrix(NOW_POLY_OPA_DISP++, mtx, G_MTX_NOPUSH | G_MTX_MUL | G_MTX_PROJECTION); + gSPSetLights0(NOW_POLY_OPA_DISP++, light_data); + SET_POLY_OPA_DISP(gfx_set_fog_nosync(NOW_POLY_OPA_DISP++, 255, 255, 255, 255, 1000, 1000)); + + CLOSE_DISP(graph); } static void mSM_set_char_matrix(GRAPH* graph) { - OPEN_DISP(graph); - gSPMatrix(NOW_POLY_OPA_DISP++, &Mtx_clear, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); - CLOSE_DISP(graph); + OPEN_DISP(graph); + gSPMatrix(NOW_POLY_OPA_DISP++, &Mtx_clear, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + CLOSE_DISP(graph); } static void mSM_cbuf_copy(GRAPH* graph, PreRender* prerender, int x, int y, int mode) { - if (x < (640-1)) { - int width = prerender->width_bak; + if (x < (640 - 1)) { + u32 width = prerender->width_bak; - if (x > -width) { - int height = prerender->height_bak; + if (x > -width) { + int height = prerender->height_bak; - if (y > -height && y < (480-1)) { - int x_max; - int x_min; - int y_max; - int y_min; - u8* color_img_buf; - u8* texture_img_buf; - int w; - int h; + if (y > -height && y < (480 - 1)) { + int x_max; + int x_min; + int y_max; + int y_min; + u8* color_img_buf; + u8* texture_img_buf; + u32 w; + u32 h; + u32 tmem_line; + u32 uls; + u32 ult; + u32 lrs; + u32 lrt; + u32 width2; + u32 height2; + u32 lrt2; + if (x < 0) { + x_max = width + x; + x_min = -x; + x = 0; + } else { + x_min = 0; - if (x < 0) { - x_max = width + x; - x_min = -x; - x = 0; + if (x + width >= 640) { + x_max = 640 - x; + } else { + x_max = width; + } + } + + if (y < 0) { + y_max = height + y; + y_min = -y; + y = 0; + } else { + y_min = 0; + + if (y + height >= 480) { + y_max = (480 - 1) - y; + } else { + y_max = height; + } + } + + if (mode == 0) { + color_img_buf = prerender->framebuffer_bak; + w = width; + height = height; + uls = x; + ult = y; + lrt = y_min; + lrs = x_min; + width2 = 640; + height2 = 480; + } else { + texture_img_buf = prerender->framebuffer_bak; + w = 640; + h = 480; + uls = x_min; + ult = y_min; + lrs = x; + lrt = y; + width2 = width; + height2 = height; + } + + // TODO: finish + tmem_line = (1 << 12) / (u32)((x_max + 3) << 1); + lrt2 = (x_max + uls) - 1; + if (mode) { + Gfx* gfx; + + OPEN_DISP(graph); + + gfx = NOW_POLY_OPA_DISP; + prerender->width = 640; + prerender->height = 480; + PreRender_CopyRGBC(prerender, &gfx, x - x_min, y - y_min); + SET_POLY_OPA_DISP(gfx); + + CLOSE_DISP(graph); + } else { + OPEN_DISP(graph); + + gDPPipeSync(NOW_POLY_OPA_DISP++); + gSPClearGeometryMode(NOW_POLY_OPA_DISP++, 0xFFFFFF); + gDPSetOtherMode(NOW_POLY_OPA_DISP++, + G_AD_DISABLE | G_CD_DISABLE | G_CK_NONE | G_TC_FILT | G_TF_BILERP | G_TT_NONE | + G_TL_TILE | G_TD_CLAMP | G_TP_NONE | G_CYC_COPY | G_PM_NPRIMITIVE, + G_AC_NONE | G_ZS_PRIM | G_RM_NOOP | G_RM_NOOP2); + gDPSetColorImage(NOW_POLY_OPA_DISP++, G_IM_FMT_RGBA, G_IM_SIZ_16b, width, color_img_buf); + gDPSetScissor(NOW_POLY_OPA_DISP++, G_SC_NON_INTERLACE, 0, 0, width, height); + + while (y_max > 0) { + if (tmem_line > y_max) { + tmem_line = y_max; + } + + gDPLoadTextureTile(NEXT_POLY_OPA_DISP, texture_img_buf, G_IM_FMT_RGBA, G_IM_SIZ_16b, width2, + height2, uls, ult, lrt2, (ult + tmem_line - 1), 0, G_TX_NOMIRROR | G_TX_WRAP, + G_TX_NOMASK, G_TX_NOLOD, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOLOD); + + gSPTextureRectangle(NEXT_POLY_OPA_DISP, (lrs) * 4, (lrt) << G_TEXTURE_IMAGE_FRAC, + (lrs + (x_max - 1)) << G_TEXTURE_IMAGE_FRAC, + (lrt + (tmem_line - 1)) << G_TEXTURE_IMAGE_FRAC, G_TX_RENDERTILE, uls << 5, + ult << 5, (1 << 1) << 10, 1 << 10); + + y_max -= tmem_line; + ult += tmem_line; + lrt += tmem_line; + } + + CLOSE_DISP(graph); + } + } } - else { - x_min = 0; - - if (x + width >= 640) { - x_max = 640 - x; - } - else { - x_max = width; - } - } - - if (y < 0) { - y_max = height + y; - y_min = -y; - y = 0; - } - else { - y_min = 0; - - if (y + height >= 480) { - y_max = (480 - 1) - y; - } - else { - y_max = height; - } - } - - // TODO: finish - - if (mode == 0) { - - } - else { - - } - } } - } - // gDPPipeSync(NOW_POLY_OPA_DISP++) - // gSPClearGeometryMode(NOW_POLY_OPA_DISP++, 0xFFFFFF) - // gDPSetOtherMode(NOW_POLY_OPA_DISP++, G_AD_DISABLE | G_CD_DISABLE | G_CK_NONE | G_TC_FILT | G_TF_BILERP | G_TT_NONE | G_TL_TILE | G_TD_CLAMP | G_TP_NONE | G_CYC_COPY | G_PM_NPRIMITIVE, G_AC_NONE | G_ZS_PRIM | G_RM_NOOP | G_RM_NOOP2) - // gDPSetColorImage(NOW_POLY_OPA_DISP++, G_IM_FMT_RGBA, G_IM_SIZ_16b, width, color_image_buf); - // gDPSetScissor(NOW_POLY_OPA_DISP++, G_SC_NON_INTERLACE, 0, 0, width, height); + // gDPPipeSync(NOW_POLY_OPA_DISP++) + // gSPClearGeometryMode(NOW_POLY_OPA_DISP++, 0xFFFFFF) + // gDPSetOtherMode(NOW_POLY_OPA_DISP++, G_AD_DISABLE | G_CD_DISABLE | G_CK_NONE | G_TC_FILT | G_TF_BILERP | + // G_TT_NONE | G_TL_TILE | G_TD_CLAMP | G_TP_NONE | G_CYC_COPY | G_PM_NPRIMITIVE, G_AC_NONE | G_ZS_PRIM | G_RM_NOOP + // | G_RM_NOOP2) gDPSetColorImage(NOW_POLY_OPA_DISP++, G_IM_FMT_RGBA, G_IM_SIZ_16b, width, color_image_buf); + // gDPSetScissor(NOW_POLY_OPA_DISP++, G_SC_NON_INTERLACE, 0, 0, width, height); - // LOOP - // [gDPLoadTextureTile] - // gDPSetTextureImage(NOW_POLY_OPA_DISP++, G_IM_FMT_RGBA, G_IM_SIZ_16b, some_width, texture_img_buf); - // gDPSetTile(G_IM_FMT_RGBA, G_IM_SIZ_16b, 0, 0x0000, G_TX_LOADTILE, 0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOLOD) - // gDPLoadSync() - // gDPLoadTile(G_TX_LOADTILE, ...) - // gDPPipeSync() - // gDPSetTile(G_IM_FMT_RGBA, G_IM_SIZ_16b, 0, 0x0000, G_TX_RENDERTILE, 0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOLOD) - // gDPSetTileSize(G_TX_RENDERTILE, ...) - // - // [gSPTextureRectangle] - // gTexRect(..., G_TX_RENDERTILE) - // gDPHalf1(...) - // gDPHalf2(...) + // LOOP + // [gDPLoadTextureTile] + // gDPSetTextureImage(NOW_POLY_OPA_DISP++, G_IM_FMT_RGBA, G_IM_SIZ_16b, some_width, texture_img_buf); + // gDPSetTile(G_IM_FMT_RGBA, G_IM_SIZ_16b, 0, 0x0000, G_TX_LOADTILE, 0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, + // G_TX_NOLOD, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOLOD) gDPLoadSync() gDPLoadTile(G_TX_LOADTILE, ...) + // gDPPipeSync() + // gDPSetTile(G_IM_FMT_RGBA, G_IM_SIZ_16b, 0, 0x0000, G_TX_RENDERTILE, 0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, + // G_TX_NOLOD, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOLOD) gDPSetTileSize(G_TX_RENDERTILE, ...) + // + // [gSPTextureRectangle] + // gTexRect(..., G_TX_RENDERTILE) + // gDPHalf1(...) + // gDPHalf2(...) } static void mSM_set_drawMode(GRAPH* graph, PreRender* prerender, f32 dist, f32 height, s16 angle) { - // TODO + // TODO } static int mSM_get_groupNo(mActor_name_t item) { - return ITEM_NAME_GET_INDEX(item); + return ITEM_NAME_GET_INDEX(item); } typedef struct inventory_icon_info_s { - u16* pal; - u8* tex; + u16* pal; + u8* tex; } mSM_inventory_icon_info_c; -static void mSM_set_dl_item(GRAPH* graph, f32 x, f32 y, f32 scale, mSM_inventory_icon_info_c* icon_info, u16* palette, u8 l, rgba_t* color, int draw_shadow, int draw_mark) { - // TODO +static void mSM_set_dl_item(GRAPH* graph, f32 x, f32 y, f32 scale, mSM_inventory_icon_info_c* icon_info, u16* palette, + u8 l, rgba_t* color, int draw_shadow, int draw_mark) { + // TODO }