diff --git a/include/m_lib.h b/include/m_lib.h index 150388ab..c17007fe 100644 --- a/include/m_lib.h +++ b/include/m_lib.h @@ -13,26 +13,33 @@ extern "C" { #endif #define SHT_MIN_S -32768 /* 0x8000 */ -#define SHT_MAX_S 32767 /* 0x7FFF */ +#define SHT_MAX_S 32767 /* 0x7FFF */ #define SHT_MIN ((f32)SHT_MIN_S) #define SHT_MAX ((f32)SHT_MAX_S) +#define USHT_MIN_S 0 +#define USHT_MAX_S 65535 + +#define USHT_MIN ((f32)USHT_MIN_S) +#define USHT_MAX ((f32)USHT_MAX_S) + #define SHT_MINV (1.0f / SHT_MAX) #define ABS(x) (((x) >= 0) ? (x) : -(x)) -#define SQ(x) ((x)*(x)) -#define CLAMP_MAX(x, min) ((min) < (x) ? (min) : (x)) +#define SQ(x) ((x) * (x)) +#define CLAMP_MAX(x, min) ((min) < (x) ? (min) : (x)) /* Float modulo operator */ #define MOD_F(a, m) (a - (int)((a) * (1.0f / (m))) * (m)) /* radians -> short angle */ #define RAD2SHORT_ANGLE(rad) ((s16)(int)((rad) * (65536.0f / (2.0f * F_PI)))) -#define RAD2SHORTANGLE(rad) ((s16)((32768.0f / F_PI) * ((f32)(rad)))) +#define RAD2SHORTANGLE(rad) ((s16)((32768.0f / F_PI) * ((f32)(rad)))) +#define RAD2SHORT_ANGLE2(rad) ((s16)((rad) * (65536.0f / (2.0f * F_PI)))) /* short angle -> radians */ #define SHORT2RAD_ANGLE(s) ((((f32)(s)) / (65536.0f / (2.0f * F_PI)))) -#define SHORTANGLE2RAD(sangle) ((F_PI / 32768.0f) * ((f32)(sangle))) +#define SHORTANGLE2RAD(sangle) ((F_PI / 32768.0f) * ((f32)(sangle))) /* degrees -> short angle */ #define DEG2SHORT_ANGLE(deg) ((s16)((deg) * (65536.0f / 360.0f))) @@ -48,12 +55,12 @@ extern "C" { /* degrees -> radians */ #define DEG2RAD(deg) ((F_PI / 180.0f) * (deg)) -typedef struct rgba_t { //can be put in other place +typedef struct rgba_t { // can be put in other place u8 r, g, b, a; } rgba_t; typedef struct rgb_t { - uint r, g, b; + uint r, g, b; } rgb_t; typedef struct { @@ -102,7 +109,8 @@ extern void none_proc2(ACTOR* actor, GAME* game); extern int _Game_play_isPause(GAME_PLAY* play); extern f32 check_percent_abs(f32 x, f32 min, f32 max, f32 scale, int shift_by_min); -extern f32 get_percent_forAccelBrake(const f32 now, const f32 start, const f32 end, const f32 accelerateDist, const f32 brakeDist); +extern f32 get_percent_forAccelBrake(const f32 now, const f32 start, const f32 end, const f32 accelerateDist, + const f32 brakeDist); extern void Game_play_Projection_Trans(GAME_PLAY* const play, xyz_t* world_pos, xyz_t* screen_pos); extern f32 get_percent(const int max, const int min, const int x); diff --git a/include/m_name_table.h b/include/m_name_table.h index 67b1609e..785c8eea 100644 --- a/include/m_name_table.h +++ b/include/m_name_table.h @@ -1122,6 +1122,9 @@ extern int mNT_check_unknown(mActor_name_t item_no); #define FTR_UMBRELLA31_WEST 0x1D87 #define FTR_UMBRELLA_END FTR_UMBRELLA31_WEST +#define FTR_MYUMBRELLA_START 0x1D88 +#define FTR_MYUMBRELLA_END 0x1DA7 + #define FTR_FAMICOM_START 0x1DA8 #define FTR_FAMICOM_CLU_CLU_LAND FTR_FAMICOM_START #define FTR_FAMICOM_BALLOON_FIGHT 0x1DAC diff --git a/src/f_furniture.c b/src/f_furniture.c index c1dc6649..c359e179 100644 --- a/src/f_furniture.c +++ b/src/f_furniture.c @@ -10,6 +10,7 @@ #include "sys_matrix.h" #include "m_malloc.h" #include "m_debug.h" +#include "m_house.h" static u16 fFTR_myhome_off_pal_table[][16] = { // clang-format off @@ -200,7 +201,7 @@ static Gfx* fFTR_GetTwoTileGfx(int width0, int height0, int scroll_x0, int scrol #include "../src/ftr/ac_ike_jny_truth01.c" #include "../src/ftr/ac_ike_jpn_tansu01.c" #include "../src/ftr/ac_ike_kama_danro01.c" -// #include "../src/ftr/ac_ike_k_count01.c" +#include "../src/ftr/ac_ike_k_count01.c" #include "../src/ftr/ac_ike_k_iveboy01.c" #include "../src/ftr/ac_ike_k_kid01.c" #include "../src/ftr/ac_ike_k_kid02.c" @@ -264,8 +265,8 @@ static Gfx* fFTR_GetTwoTileGfx(int width0, int height0, int scroll_x0, int scrol #include "../src/ftr/ac_kon_tukue.c" #include "../src/ftr/ac_kon_waclock.c" #include "../src/ftr/ac_kon_xtree02.c" -// #include "../src/ftr/ac_myfmanekin.c" -// #include "../src/ftr/ac_myfumbrella.c" +#include "../src/ftr/ac_myfmanekin.c" +#include "../src/ftr/ac_myfumbrella.c" #include "../src/ftr/ac_nog_amenbo.c" #include "../src/ftr/ac_nog_ari.c" // #include "../src/ftr/ac_nog_balloon_common.c" @@ -664,7 +665,7 @@ static Gfx* fFTR_GetTwoTileGfx(int width0, int height0, int scroll_x0, int scrol // #include "../src/ftr/ac_sum_x_chest01.c" // #include "../src/ftr/ac_sum_x_chest02.c" #include "../src/ftr/ac_sum_x_chest03.c" -// #include "../src/ftr/ac_sum_x_clk.c" +#include "../src/ftr/ac_sum_x_clk.c" #include "../src/ftr/ac_sum_x_lanp.c" // #include "../src/ftr/ac_sum_x_piano.c" #include "../src/ftr/ac_sum_x_sofa01.c" @@ -681,13 +682,13 @@ static Gfx* fFTR_GetTwoTileGfx(int width0, int height0, int scroll_x0, int scrol #include "../src/ftr/ac_tak_drum02.c" #include "../src/ftr/ac_tak_eisei.c" #include "../src/ftr/ac_tak_hole01.c" -// #include "../src/ftr/ac_tak_ice.c" +#include "../src/ftr/ac_tak_ice.c" #include "../src/ftr/ac_tak_isu03.c" -// #include "../src/ftr/ac_tak_lion.c" -// #include "../src/ftr/ac_tak_megami.c" -// #include "../src/ftr/ac_tak_metro.c" -// #include "../src/ftr/ac_tak_money.c" -// #include "../src/ftr/ac_tak_moon.c" +#include "../src/ftr/ac_tak_lion.c" +#include "../src/ftr/ac_tak_megami.c" +#include "../src/ftr/ac_tak_metro.c" +#include "../src/ftr/ac_tak_money.c" +#include "../src/ftr/ac_tak_moon.c" #include "../src/ftr/ac_tak_mooncar.c" #include "../src/ftr/ac_tak_moti.c" #include "../src/ftr/ac_tak_neko.c" diff --git a/src/ftr/ac_ike_k_count01.c b/src/ftr/ac_ike_k_count01.c index e5f8ece6..c4e59c88 100644 --- a/src/ftr/ac_ike_k_count01.c +++ b/src/ftr/ac_ike_k_count01.c @@ -1,12 +1,29 @@ extern Gfx int_ike_k_count01_body_model[]; -static void fIKC_mv(FTR_ACTOR* ftr_actor, ACTOR* my_room_actor, GAME* game, u8* data); +#define fIKC_MIN_TIME (f32)(20 + GETREG(TAKREG, 72)) +#define fIKC_MAX_TIME (f32)(40 + GETREG(TAKREG, 73)) + +static void fIKC_mv(FTR_ACTOR* ftr_actor, ACTOR* my_room_actor, GAME* game, u8* data) { + if (aFTR_CAN_PLAY_SE(ftr_actor)) { + if (ftr_actor->dynamic_work_s[0] < 0) { + xyz_t pos = ftr_actor->position; + + pos.y += 13.0f; + (*Common_Get(clip).effect_clip->effect_make_proc)(eEC_EFFECT_SOBA_YUGE, pos, 1, 0, game, RSV_NO, 6, 0); + + ftr_actor->dynamic_work_s[0] = (int)(fIKC_MIN_TIME + RANDOM_F(fIKC_MAX_TIME - fIKC_MIN_TIME)); + } else { + ftr_actor->dynamic_work_s[0]--; + } + } +} static aFTR_vtable_c fIKC_func = { NULL, &fIKC_mv, NULL, NULL, NULL, }; aFTR_PROFILE iam_ike_k_count01 = { + // clang-format off int_ike_k_count01_body_model, NULL, NULL, @@ -24,4 +41,5 @@ aFTR_PROFILE iam_ike_k_count01 = { 0, 0, &fIKC_func, + // clang-format on }; diff --git a/src/ftr/ac_myfmanekin.c b/src/ftr/ac_myfmanekin.c index 57f3921c..2f461c97 100644 --- a/src/ftr/ac_myfmanekin.c +++ b/src/ftr/ac_myfmanekin.c @@ -1,18 +1,42 @@ -static void aMyfmanekin_ct(FTR_ACTOR* ftr_actor, u8* data); -static void aMyfmanekin_mv(FTR_ACTOR* ftr_actor, ACTOR* my_room_actor, GAME* game, u8* data); -static void aMyfmanekin_dw(FTR_ACTOR* ftr_actor, ACTOR* my_room_actor, GAME* game, u8* data); -static void aMyfmanekin_dt(FTR_ACTOR* ftr_actor, u8* data); -static void aMyfmanekin_dma(mActor_name_t ftr_name, u8* data); +static void aMyfmanekin_ct(FTR_ACTOR* ftr_actor, u8* data) { + // nothing +} + +extern Gfx obj_shop_manekin_model[]; + +static void aMyfmanekin_dw(FTR_ACTOR* ftr_actor, ACTOR* my_room_actor, GAME* game, u8* data) { + OPEN_DISP(game->graph); + + gSPSegment(NEXT_POLY_OPA_DISP, G_MWO_SEGMENT_8, data); + gSPSegment(NEXT_POLY_OPA_DISP, G_MWO_SEGMENT_9, data + mNW_DESIGN_TEX_SIZE); + gSPDisplayList(NEXT_POLY_OPA_DISP, obj_shop_manekin_model); + + CLOSE_DISP(game->graph); +} + +static void aMyfmanekin_mv(FTR_ACTOR* ftr_actor, ACTOR* my_room_actor, GAME* game, u8* data) { + // nothing +} + +static void aMyfmanekin_dt(FTR_ACTOR* ftr_actor, u8* data) { + // nothing +} + +static void aMyfmanekin_dma(mActor_name_t ftr_name, u8* data) { + int house_no = (mFI_GetFieldId() - mFI_FIELD_PLAYER0_ROOM) & 3; + int player_no = mHS_get_pl_no(house_no); + u32 manekin_no = ((ftr_name - FTR_CLOTH_MANNIQUIN_MY_ORIGINAL0) >> 2); + + mNW_CopyOriginalTexture(data, &Save_Get(private[player_no]).my_org[manekin_no & 7]); + mNW_CopyOriginalPalette(data + mNW_DESIGN_TEX_SIZE, &Save_Get(private[player_no]).my_org[manekin_no & 7]); +} static aFTR_vtable_c aMyfmanekin_func = { - &aMyfmanekin_ct, - &aMyfmanekin_mv, - &aMyfmanekin_dw, - &aMyfmanekin_dt, - &aMyfmanekin_dma, + &aMyfmanekin_ct, &aMyfmanekin_mv, &aMyfmanekin_dw, &aMyfmanekin_dt, &aMyfmanekin_dma, }; aFTR_PROFILE iam_myfmanekin = { + // clang-format off NULL, NULL, NULL, @@ -30,4 +54,5 @@ aFTR_PROFILE iam_myfmanekin = { 0, aFTR_INTERACTION_MANNEKIN, &aMyfmanekin_func, + // clang-format on }; diff --git a/src/ftr/ac_myfumbrella.c b/src/ftr/ac_myfumbrella.c index 0da72ce6..acd72ed6 100644 --- a/src/ftr/ac_myfumbrella.c +++ b/src/ftr/ac_myfumbrella.c @@ -1,33 +1,58 @@ -static void aMFU_ct(FTR_ACTOR* ftr_actor, u8* data); -static void aMFU_mv(FTR_ACTOR* ftr_actor, ACTOR* my_room_actor, GAME* game, u8* data); -static void aMFU_dw(FTR_ACTOR* ftr_actor, ACTOR* my_room_actor, GAME* game, u8* data); -static void aMFU_dt(FTR_ACTOR* ftr_actor, u8* data); -static void aMFU_dma(mActor_name_t ftr_name, u8* data); +static void aMFU_ct(FTR_ACTOR* ftr_actor, u8* data) { + // nothing +} + +extern Gfx obj_shop_umbmy_model[]; + +static void aMFU_dw(FTR_ACTOR* ftr_actor, ACTOR* my_room_actor, GAME* game, u8* data) { + OPEN_DISP(game->graph); + + gSPSegment(NEXT_POLY_OPA_DISP, G_MWO_SEGMENT_9, data); // seg 9 has tex + gSPSegment(NEXT_POLY_OPA_DISP, G_MWO_SEGMENT_8, data + mNW_DESIGN_TEX_SIZE); // seg 8 has pal + gSPDisplayList(NEXT_POLY_OPA_DISP, obj_shop_umbmy_model); + + CLOSE_DISP(game->graph); +} + +static void aMFU_mv(FTR_ACTOR* ftr_actor, ACTOR* my_room_actor, GAME* game, u8* data) { + // nothing +} + +static void aMFU_dt(FTR_ACTOR* ftr_actor, u8* data) { + // nothing +} + +static void aMFU_dma(mActor_name_t ftr_name, u8* data) { + int house_no = (mFI_GetFieldId() - mFI_FIELD_PLAYER0_ROOM) & 3; + int player_no = mHS_get_pl_no(house_no); + u32 manekin_no = ((ftr_name - FTR_MYUMBRELLA_START) >> 2); + + mNW_CopyOriginalTexture(data, &Save_Get(private[player_no]).my_org[manekin_no & 7]); + mNW_CopyOriginalPalette(data + mNW_DESIGN_TEX_SIZE, &Save_Get(private[player_no]).my_org[manekin_no & 7]); +} static aFTR_vtable_c aMFU_func = { - &aMFU_ct, - &aMFU_mv, - &aMFU_dw, - &aMFU_dt, - &aMFU_dma, + &aMFU_ct, &aMFU_mv, &aMFU_dw, &aMFU_dt, &aMFU_dma, }; aFTR_PROFILE iam_myfumbrella = { - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - 30.0f, - 0.01f, - aFTR_SHAPE_TYPEA, - mCoBG_FTR_TYPEA, - 0, - 0, - 0, - aFTR_INTERACTION_UMBRELLA, - &aMFU_func, + // clang-format off + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + 30.0f, + 0.01f, + aFTR_SHAPE_TYPEA, + mCoBG_FTR_TYPEA, + 0, + 0, + 0, + aFTR_INTERACTION_UMBRELLA, + &aMFU_func, + // clang-format on }; diff --git a/src/ftr/ac_sum_x_clk.c b/src/ftr/ac_sum_x_clk.c index 2642fc3b..74937302 100644 --- a/src/ftr/ac_sum_x_clk.c +++ b/src/ftr/ac_sum_x_clk.c @@ -1,17 +1,133 @@ -static void aSumXClk_ct(FTR_ACTOR* ftr_actor, u8* data); -static void aSumXClk_mv(FTR_ACTOR* ftr_actor, ACTOR* my_room_actor, GAME* game, u8* data); -static void aSumXClk_dw(FTR_ACTOR* ftr_actor, ACTOR* my_room_actor, GAME* game, u8* data); -static void aSumXClk_dt(FTR_ACTOR* ftr_actor, u8* data); +extern Gfx int_sum_x_clk_evw_model[]; +extern Gfx int_sum_x_clk_short_model[]; +extern Gfx int_sum_x_clk_long_model[]; + +static int aSumXClk_DwAfter(GAME* game, cKF_SkeletonInfo_R_c* keyframe, int joint_idx, Gfx** joint_shape, + u8* joint_flags, void* arg, s_xyz* joint_rot, xyz_t* joint_pos) { + FTR_ACTOR* ftr_actor = (FTR_ACTOR*)arg; + GAME_PLAY* play = (GAME_PLAY*)game; + xyz_t pos; + xyz_t save_pos = { 0.0f, 0.0f, 0.0f }; + s16 base_angle_y = RAD2SHORT_ANGLE2(DEG2RAD(ftr_actor->angle_y)); + f32 scale_x = ftr_actor->scale.x * 0.01f; + f32 scale_y = ftr_actor->scale.y * 0.01f; + f32 scale_z = ftr_actor->scale.z * 0.01f; + GRAPH* graph = game->graph; + + if (joint_idx == 6) { + _texture_z_light_fog_prim_xlu(graph); + Setpos_HiliteReflect_xlu_init(&ftr_actor->position, play); + Matrix_Position(&save_pos, &pos); + Matrix_push(); + Matrix_translate(pos.x, pos.y, pos.z, 0); + Matrix_RotateY(base_angle_y, 1); + Matrix_RotateZ(DEG2SHORT_ANGLE(90.0f), 1); + Matrix_scale(scale_x, scale_y, scale_z, 1); + + OPEN_DISP(graph); + + gSPMatrix(NEXT_POLY_XLU_DISP, _Matrix_to_Mtx_new(game->graph), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + Matrix_pull(); + gSPDisplayList(NEXT_POLY_XLU_DISP, int_sum_x_clk_evw_model); + + CLOSE_DISP(graph); + } else if (joint_idx == 3) { + Matrix_Position(&save_pos, &pos); + Matrix_push(); + Matrix_translate(pos.x, pos.y, pos.z, 0); + Matrix_RotateY(base_angle_y, 1); + Matrix_RotateZ(DEG2SHORT_ANGLE(90.0f) - Common_Get(time.rad_hour), 1); + Matrix_translate(0.0f, 0.0f, 1.0f, 1); + Matrix_scale(scale_x, scale_y, scale_z, 1); + + OPEN_DISP(graph); + + gSPMatrix(NEXT_POLY_OPA_DISP, _Matrix_to_Mtx_new(game->graph), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + Matrix_pull(); + gSPDisplayList(NEXT_POLY_OPA_DISP, int_sum_x_clk_short_model); + + CLOSE_DISP(graph); + } else if (joint_idx == 7) { + Matrix_Position(&save_pos, &pos); + Matrix_push(); + Matrix_translate(pos.x, pos.y, pos.z, 0); + Matrix_RotateY(base_angle_y, 1); + Matrix_RotateZ(DEG2SHORT_ANGLE(90.0f) - Common_Get(time.rad_min), 1); + Matrix_translate(0.0f, 0.0f, 1.0f, 1); + Matrix_scale(scale_x, scale_y, scale_z, 1); + + OPEN_DISP(graph); + + gSPMatrix(NEXT_POLY_OPA_DISP, _Matrix_to_Mtx_new(game->graph), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + Matrix_pull(); + gSPDisplayList(NEXT_POLY_OPA_DISP, int_sum_x_clk_long_model); + + CLOSE_DISP(graph); + } + + return TRUE; +} + +static int aSumXClk_DwBefore(GAME* game, cKF_SkeletonInfo_R_c* keyframe, int joint_idx, Gfx** joint_shape, + u8* joint_flags, void* arg, s_xyz* joint_rot, xyz_t* joint_pos) { + if (joint_idx == 3 || joint_idx == 7 || joint_idx == 6) { + *joint_shape = NULL; + } + + return TRUE; +} + +static void aSumXClk_dw(FTR_ACTOR* ftr_actor, ACTOR* my_room_actor, GAME* game, u8* data) { + cKF_SkeletonInfo_R_c* keyframe = &ftr_actor->keyframe; + Mtx* mtx = ftr_actor->skeleton_mtx[game->frame_counter & 1]; + + cKF_Si3_draw_R_SV(game, keyframe, mtx, &aSumXClk_DwBefore, &aSumXClk_DwAfter, ftr_actor); +} + +extern cKF_Skeleton_R_c cKF_bs_r_int_sum_x_clk; +extern cKF_Animation_R_c cKF_ba_r_int_sum_x_clk; + +static void aSumXClk_ct(FTR_ACTOR* ftr_actor, u8* data) { + cKF_SkeletonInfo_R_c* keyframe = &ftr_actor->keyframe; + + cKF_SkeletonInfo_R_ct(keyframe, &cKF_bs_r_int_sum_x_clk, &cKF_ba_r_int_sum_x_clk, ftr_actor->joint, + ftr_actor->morph); + cKF_SkeletonInfo_R_init_standard_repeat(keyframe, &cKF_ba_r_int_sum_x_clk, NULL); + cKF_SkeletonInfo_R_play(keyframe); + keyframe->frame_control.speed = 0.5f; +} + +static void aSumXClk_mv(FTR_ACTOR* ftr_actor, ACTOR* my_room_actor, GAME* game, u8* data) { + if (Common_Get(clip).my_room_clip != NULL) { + cKF_SkeletonInfo_R_c* keyframe = &ftr_actor->keyframe; + aMR_clock_info_c* clock_info = Common_Get(clip).my_room_clip->clock_info_p; + + if (clock_info->tick_stop) { + cKF_SkeletonInfo_R_init_standard_repeat(keyframe, &cKF_ba_r_int_sum_x_clk, NULL); + cKF_SkeletonInfo_R_play(keyframe); + keyframe->frame_control.speed = 0.5f; + } else if (clock_info->tick0 == TRUE || clock_info->tick1 == TRUE) { + if (aFTR_CAN_PLAY_SE(ftr_actor)) { + sAdo_OngenTrgStart(0x12D, &ftr_actor->position); + } + + cKF_SkeletonInfo_R_play(keyframe); + } else { + cKF_SkeletonInfo_R_play(keyframe); + } + } +} + +static void aSumXClk_dt(FTR_ACTOR* ftr_actor, u8* data) { + // nothing +} static aFTR_vtable_c aSumXClk_func = { - &aSumXClk_ct, - &aSumXClk_mv, - &aSumXClk_dw, - &aSumXClk_dt, - NULL, + &aSumXClk_ct, &aSumXClk_mv, &aSumXClk_dw, &aSumXClk_dt, NULL, }; aFTR_PROFILE iam_sum_x_clk = { + // clang-format off NULL, NULL, NULL, @@ -29,4 +145,5 @@ aFTR_PROFILE iam_sum_x_clk = { 0, 0, &aSumXClk_func, + // clang-format on }; diff --git a/src/ftr/ac_tak_ice.c b/src/ftr/ac_tak_ice.c index 242731ee..e67d10ea 100644 --- a/src/ftr/ac_tak_ice.c +++ b/src/ftr/ac_tak_ice.c @@ -1,31 +1,150 @@ -static void fTIC_ct(FTR_ACTOR* ftr_actor, u8* data); -static void fTIC_mv(FTR_ACTOR* ftr_actor, ACTOR* my_room_actor, GAME* game, u8* data); -static void fTIC_dw(FTR_ACTOR* ftr_actor, ACTOR* my_room_actor, GAME* game, u8* data); +extern cKF_Skeleton_R_c cKF_bs_r_int_tak_ice; +extern cKF_Animation_R_c cKF_ba_r_int_tak_ice; + +static void fTIC_ct(FTR_ACTOR* ftr_actor, u8* data) { + cKF_SkeletonInfo_R_c* keyframe = &ftr_actor->keyframe; + + cKF_SkeletonInfo_R_ct(keyframe, &cKF_bs_r_int_tak_ice, &cKF_ba_r_int_tak_ice, ftr_actor->joint, ftr_actor->morph); + cKF_SkeletonInfo_R_init_standard_repeat(keyframe, &cKF_ba_r_int_tak_ice, NULL); + cKF_SkeletonInfo_R_play(keyframe); + + if (ftr_actor->switch_bit == TRUE) { + keyframe->frame_control.speed = 0.5f; + ftr_actor->dynamic_work_f[0] = 1.0f; + } else { + keyframe->frame_control.speed = 0.0f; + ftr_actor->dynamic_work_f[0] = 0.0f; + } +} + +static void fTIC_mv(FTR_ACTOR* ftr_actor, ACTOR* my_room_actor, GAME* game, u8* data) { + f32 target = ftr_actor->switch_bit ? 1.0f : 0.0f; + cKF_SkeletonInfo_R_c* keyframe = &ftr_actor->keyframe; + + if (ftr_actor->dynamic_work_f[0] < target) { + ftr_actor->dynamic_work_f[0] += 0.01f; + + if (ftr_actor->dynamic_work_f[0] > target) { + ftr_actor->dynamic_work_f[0] = target; + } + } else if (ftr_actor->dynamic_work_f[0] > target) { + ftr_actor->dynamic_work_f[0] -= 0.01f; + + if (ftr_actor->dynamic_work_f[0] < target) { + ftr_actor->dynamic_work_f[0] = target; + } + } + + keyframe->frame_control.speed = ftr_actor->dynamic_work_f[0] * 0.5f; + cKF_SkeletonInfo_R_play(keyframe); + + if (aFTR_CAN_PLAY_SE(ftr_actor)) { + if (ftr_actor->switch_changed_flag) { + if (ftr_actor->switch_bit == TRUE) { + sAdo_OngenTrgStart(0x16, &ftr_actor->position); + } else { + sAdo_OngenTrgStart(0x17, &ftr_actor->position); + } + } + + if (ftr_actor->dynamic_work_f[0] >= 0.01f && ftr_actor->switch_bit == TRUE) { + sAdo_OngenPos((u32)ftr_actor, 0x51, &ftr_actor->position); + } + } +} + +static int fTIC_DrawBefore(GAME* game, cKF_SkeletonInfo_R_c* keyframe, int joint_idx, Gfx** joint_shape, + u8* joint_flags, void* arg, s_xyz* joint_rot, xyz_t* joint_pos) { + FTR_ACTOR* ftr_actor = (FTR_ACTOR*)arg; + GAME_PLAY* play = (GAME_PLAY*)game; + + if (joint_idx == 3 || joint_idx == 4) { + *joint_shape = NULL; + } + + return TRUE; +} + +static Gfx* fTIC_GetTwoTileGfx(int x0, int y0, int x1, int y1, GAME* game) { + return two_tex_scroll_dolphin(game->graph, 0, x0, y0, 8, 32, 1, x1, y1, 8, 32); +} + +extern Gfx int_tak_ice_block_model[]; +extern Gfx int_tak_ice_yuki_model[]; + +static int fTIC_DrawAfter(GAME* game, cKF_SkeletonInfo_R_c* keyframe, int joint_idx, Gfx** joint_shape, u8* joint_flags, + void* arg, s_xyz* joint_rot, xyz_t* joint_pos) { + FTR_ACTOR* ftr_actor = (FTR_ACTOR*)arg; + cKF_SkeletonInfo_R_c* ftr_keyframe = &ftr_actor->keyframe; + GAME_PLAY* play = (GAME_PLAY*)game; + u32 ctr_ofs; + + if (ftr_actor->ctr_type == aFTR_CTR_TYPE_GAME_PLAY) { + ctr_ofs = play->game_frame; + } else { + ctr_ofs = game->frame_counter; + } + + if (joint_idx == 3) { + OPEN_DISP(game->graph); + + gSPMatrix(NEXT_POLY_XLU_DISP, _Matrix_to_Mtx_new(game->graph), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(NEXT_POLY_XLU_DISP, int_tak_ice_block_model); + + CLOSE_DISP(game->graph); + } else if (joint_idx == 4) { + Gfx* scroll_gfx = fTIC_GetTwoTileGfx(0, ctr_ofs * 8, 0, 0, game); + u8 a = (int)((ftr_keyframe->frame_control.speed / 0.5f) * 255.0f); + + if (scroll_gfx != NULL) { + OPEN_DISP(game->graph); + + gSPMatrix(NEXT_POLY_XLU_DISP, _Matrix_to_Mtx_new(game->graph), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gDPSetPrimColor(NEXT_POLY_XLU_DISP, 0, 255, 255, 255, 255, a); + gSPSegment(NEXT_POLY_XLU_DISP, G_MWO_SEGMENT_9, scroll_gfx); + gSPDisplayList(NEXT_POLY_XLU_DISP, int_tak_ice_yuki_model); + + CLOSE_DISP(game->graph); + } + } + + return TRUE; +} + +static void fTIC_dw(FTR_ACTOR* ftr_actor, ACTOR* my_room_actor, GAME* game, u8* data) { + GAME_PLAY* play = (GAME_PLAY*)game; + cKF_SkeletonInfo_R_c* keyframe = &ftr_actor->keyframe; + Mtx* mtx = ftr_actor->skeleton_mtx[game->frame_counter & 1]; + + OPEN_DISP(game->graph); + + gSPMatrix(NEXT_POLY_OPA_DISP, _Matrix_to_Mtx_new(game->graph), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + + CLOSE_DISP(game->graph); + + cKF_Si3_draw_R_SV(game, keyframe, mtx, &fTIC_DrawBefore, &fTIC_DrawAfter, ftr_actor); +} static aFTR_vtable_c fTIC_func = { - &fTIC_ct, - &fTIC_mv, - &fTIC_dw, - NULL, - NULL, + &fTIC_ct, &fTIC_mv, &fTIC_dw, NULL, NULL, }; aFTR_PROFILE iam_tak_ice = { - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - 40.0f, - 0.01f, - aFTR_SHAPE_TYPEA, - mCoBG_FTR_TYPEA, - 0, - 2, - 0, - aFTR_INTERACTION_START_DISABLED, - &fTIC_func, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + 40.0f, + 0.01f, + aFTR_SHAPE_TYPEA, + mCoBG_FTR_TYPEA, + 0, + 2, + 0, + aFTR_INTERACTION_START_DISABLED, + &fTIC_func, }; diff --git a/src/ftr/ac_tak_lion.c b/src/ftr/ac_tak_lion.c index 05f8071b..41cb6e73 100644 --- a/src/ftr/ac_tak_lion.c +++ b/src/ftr/ac_tak_lion.c @@ -1,17 +1,108 @@ -static void fTL_ct(FTR_ACTOR* ftr_actor, u8* data); -static void fTL_mv(FTR_ACTOR* ftr_actor, ACTOR* my_room_actor, GAME* game, u8* data); +static void fTL_ct(FTR_ACTOR* ftr_actor, u8* data) { + f32 l; + + if (ftr_actor->switch_bit == TRUE) { + ftr_actor->dynamic_work_s[0] = TRUE; + } else { + ftr_actor->dynamic_work_s[0] = FALSE; + } + + if (ftr_actor->dynamic_work_s[0] == TRUE) { + l = 126.0f; + } else { + l = 0.0f; + } + + ftr_actor->dynamic_work_f[0] = l; +} + +static void fTL_mv(FTR_ACTOR* ftr_actor, ACTOR* my_room_actor, GAME* game, u8* data) { + f32 l; + + if (ftr_actor->dynamic_work_s[0] == 1) { + l = 126.0f; + } else { + l = 0.0f; + } + + if (ftr_actor->dynamic_work_s[0] == 1) { + if (aFTR_CAN_PLAY_SE(ftr_actor)) { + sAdo_OngenPos((u32)ftr_actor, 0x4A, &ftr_actor->position); + } + } + + if (ftr_actor->dynamic_work_f[0] > l) { + ftr_actor->dynamic_work_f[0] -= 4.0f; + if (ftr_actor->dynamic_work_f[0] < l) { + ftr_actor->dynamic_work_f[0] = l; + } + } else if (ftr_actor->dynamic_work_f[0] < l) { + ftr_actor->dynamic_work_f[0] += 4.0f; + if (ftr_actor->dynamic_work_f[0] > l) { + ftr_actor->dynamic_work_f[0] = l; + } + } else { + if (ftr_actor->switch_changed_flag) { + ftr_actor->dynamic_work_s[0] = (ftr_actor->dynamic_work_s[0] + 1) & 1; + } + } +} + +static Gfx* fTL_GetTwoTileGfx(int x0, int y0, int x1, int y1, GAME* game) { + return two_tex_scroll_dolphin(game->graph, 0, x0, y0, 8, 8, 1, x1, y1, 8, 8); +} + +extern Gfx int_tak_lion_on_model[]; +extern Gfx int_tak_lion_onT_model[]; +extern Gfx int_tak_lion_alphaT_model[]; + +static void fSKP_dw(FTR_ACTOR* ftr_actor, ACTOR* my_room_actor, GAME* game, u8* data) { + GAME_PLAY* play = (GAME_PLAY*)game; + u32 ctr_ofs; + Gfx* scroll_gfx; + u8 l; + + if (ftr_actor->ctr_type == aFTR_CTR_TYPE_GAME_PLAY) { + ctr_ofs = play->game_frame; + } else { + ctr_ofs = game->frame_counter; + } + + scroll_gfx = fTL_GetTwoTileGfx(-ctr_ofs, ctr_ofs * 4, ctr_ofs, ctr_ofs * 4, game); + + if (ftr_actor->ctr_type == aFTR_CTR_TYPE_GAME_PLAY) { + l = (int)ftr_actor->dynamic_work_f[0]; + } else { + l = 156; + } + + if (scroll_gfx != NULL) { + OPEN_DISP(game->graph); + + gSPMatrix(NEXT_POLY_OPA_DISP, _Matrix_to_Mtx_new(game->graph), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPMatrix(NEXT_POLY_XLU_DISP, _Matrix_to_Mtx_new(game->graph), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(NEXT_POLY_OPA_DISP, int_tak_lion_on_model); + gSPDisplayList(NEXT_POLY_OPA_DISP, int_tak_lion_onT_model); + gDPSetPrimColor(NEXT_POLY_XLU_DISP, 0, l, 255, 255, 255, 127); + gSPSegment(NEXT_POLY_XLU_DISP, G_MWO_SEGMENT_8, scroll_gfx); + gSPDisplayList(NEXT_POLY_XLU_DISP, int_tak_lion_alphaT_model); + + CLOSE_DISP(game->graph); + } +} + static void fTL_dw(FTR_ACTOR* ftr_actor, ACTOR* my_room_actor, GAME* game, u8* data); -static void fTL_dt(FTR_ACTOR* ftr_actor, u8* data); + +static void fTL_dt(FTR_ACTOR* ftr_actor, u8* data) { + ftr_actor->switch_bit = ftr_actor->dynamic_work_s[0]; +} static aFTR_vtable_c fTL_func = { - &fTL_ct, - &fTL_mv, - &fTL_dw, - &fTL_dt, - NULL, + &fTL_ct, &fTL_mv, &fTL_dw, &fTL_dt, NULL, }; aFTR_PROFILE iam_tak_lion = { + // clang-format off NULL, NULL, NULL, @@ -29,4 +120,5 @@ aFTR_PROFILE iam_tak_lion = { 0, 0, &fTL_func, + // clang-format on }; diff --git a/src/ftr/ac_tak_megami.c b/src/ftr/ac_tak_megami.c index d6225609..3381e5d6 100644 --- a/src/ftr/ac_tak_megami.c +++ b/src/ftr/ac_tak_megami.c @@ -1,14 +1,26 @@ -static void fTM_dw(FTR_ACTOR* ftr_actor, ACTOR* my_room_actor, GAME* game, u8* data); +extern Gfx int_tak_megami_on_model[]; +extern Gfx int_tak_megami_onT_model[]; +extern Gfx int_tak_megami_offT_model[]; + +static void fTM_dw(FTR_ACTOR* ftr_actor, ACTOR* my_room_actor, GAME* game, u8* data) { + GAME_PLAY* play = (GAME_PLAY*)game; + + OPEN_DISP(game->graph); + + gSPMatrix(NEXT_POLY_OPA_DISP, _Matrix_to_Mtx_new(game->graph), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(NEXT_POLY_OPA_DISP, int_tak_megami_on_model); + gSPDisplayList(NEXT_POLY_OPA_DISP, int_tak_megami_onT_model); + gSPDisplayList(NEXT_POLY_OPA_DISP, int_tak_megami_offT_model); + + CLOSE_DISP(game->graph); +} static aFTR_vtable_c fTM_func = { - NULL, - NULL, - &fTM_dw, - NULL, - NULL, + NULL, NULL, &fTM_dw, NULL, NULL, }; aFTR_PROFILE iam_tak_megami = { + // clang-format off NULL, NULL, NULL, @@ -26,4 +38,5 @@ aFTR_PROFILE iam_tak_megami = { 0, 0, &fTM_func, + // clang-format on }; diff --git a/src/ftr/ac_tak_metro.c b/src/ftr/ac_tak_metro.c index c81af47f..a8dfc0bd 100644 --- a/src/ftr/ac_tak_metro.c +++ b/src/ftr/ac_tak_metro.c @@ -1,17 +1,97 @@ -static void aTakMetro_ct(FTR_ACTOR* ftr_actor, u8* data); -static void aTakMetro_mv(FTR_ACTOR* ftr_actor, ACTOR* my_room_actor, GAME* game, u8* data); -static void aTakMetro_dw(FTR_ACTOR* ftr_actor, ACTOR* my_room_actor, GAME* game, u8* data); -static void aTakMetro_dt(FTR_ACTOR* ftr_actor, u8* data); +extern cKF_Skeleton_R_c cKF_bs_r_int_tak_metro; +extern cKF_Animation_R_c cKF_ba_r_int_tak_metro; + +#define aTakMetro_DISABLED(ftr_actor) (ftr_actor->dynamic_work_s[1]) + +static void aTakMetro_ct(FTR_ACTOR* ftr_actor, u8* data) { + cKF_SkeletonInfo_R_c* keyframe = &ftr_actor->keyframe; + + cKF_SkeletonInfo_R_ct(keyframe, &cKF_bs_r_int_tak_metro, &cKF_ba_r_int_tak_metro, ftr_actor->joint, + ftr_actor->morph); + cKF_SkeletonInfo_R_init_standard_repeat(keyframe, &cKF_ba_r_int_tak_metro, NULL); + keyframe->frame_control.current_frame = 16.0f; + cKF_SkeletonInfo_R_play(keyframe); + keyframe->frame_control.speed = 0.5f; + + ftr_actor->dynamic_work_s[0] = 0; + + if (ftr_actor->switch_bit) { + aTakMetro_DISABLED(ftr_actor) = FALSE; + } else { + aTakMetro_DISABLED(ftr_actor) = TRUE; + } +} + +static void aTakMetro_mv(FTR_ACTOR* ftr_actor, ACTOR* my_room_actor, GAME* game, u8* data) { + GAME_PLAY* play = (GAME_PLAY*)game; + cKF_SkeletonInfo_R_c* keyframe = &ftr_actor->keyframe; + f32 frame = keyframe->frame_control.current_frame; + + if (ftr_actor->switch_changed_flag) { + switch (aTakMetro_DISABLED(ftr_actor)) { + case FALSE: + if (ftr_actor->dynamic_work_s[0] == 0) { + ftr_actor->dynamic_work_s[0] = 1; + sAdo_OngenTrgStart(0x17, &ftr_actor->position); + } + break; + case TRUE: + ftr_actor->dynamic_work_s[0] = 0; + aTakMetro_DISABLED(ftr_actor) = FALSE; + ftr_actor->switch_bit = TRUE; + sAdo_OngenTrgStart(0x16, &ftr_actor->position); + break; + } + } + + if (ftr_actor->dynamic_work_s[0] == 1 && (frame == 17.0f || frame == 47.0f)) { + ftr_actor->dynamic_work_s[0] = 0; + aTakMetro_DISABLED(ftr_actor) = TRUE; + ftr_actor->switch_bit = FALSE; + } + + if (aTakMetro_DISABLED(ftr_actor) == FALSE) { + cKF_SkeletonInfo_R_play(keyframe); + keyframe->frame_control.speed = 0.5f; + } + + if (ftr_actor->dynamic_work_s[0] == 0 && aTakMetro_DISABLED(ftr_actor) == FALSE) { + if (frame == 60.0f) { + if (aFTR_CAN_PLAY_SE(ftr_actor)) { + sAdo_OngenTrgStart(0x19, &ftr_actor->position); + } + } else if (frame == 30.0f) { + if (aFTR_CAN_PLAY_SE(ftr_actor)) { + sAdo_OngenTrgStart(0x19, &ftr_actor->position); + } + } + } +} + +static void aTakMetro_dw(FTR_ACTOR* ftr_actor, ACTOR* my_room_actor, GAME* game, u8* data) { + GAME_PLAY* play = (GAME_PLAY*)game; + cKF_SkeletonInfo_R_c* keyframe = &ftr_actor->keyframe; + Mtx* mtx = ftr_actor->skeleton_mtx[game->frame_counter & 1]; + + OPEN_DISP(game->graph); + + gSPMatrix(NEXT_POLY_OPA_DISP, _Matrix_to_Mtx_new(game->graph), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + + CLOSE_DISP(game->graph); + + cKF_Si3_draw_R_SV(game, keyframe, mtx, NULL, NULL, NULL); +} + +static void aTakMetro_dt(FTR_ACTOR* ftr_actor, u8* data) { + // nothing +} static aFTR_vtable_c aTakMetro_func = { - &aTakMetro_ct, - &aTakMetro_mv, - &aTakMetro_dw, - &aTakMetro_dt, - NULL, + &aTakMetro_ct, &aTakMetro_mv, &aTakMetro_dw, &aTakMetro_dt, NULL, }; aFTR_PROFILE iam_tak_metro = { + // clang-format off NULL, NULL, NULL, @@ -29,4 +109,7 @@ aFTR_PROFILE iam_tak_metro = { 0, 0, &aTakMetro_func, + // clang-format on }; + +#undef aTakMetro_DISABLED diff --git a/src/ftr/ac_tak_money.c b/src/ftr/ac_tak_money.c index 963976dc..32e7fdae 100644 --- a/src/ftr/ac_tak_money.c +++ b/src/ftr/ac_tak_money.c @@ -1,16 +1,102 @@ -static void fTMny_ct(FTR_ACTOR* ftr_actor, u8* data); -static void fTMny_mv(FTR_ACTOR* ftr_actor, ACTOR* my_room_actor, GAME* game, u8* data); -static void fTMny_dw(FTR_ACTOR* ftr_actor, ACTOR* my_room_actor, GAME* game, u8* data); +extern cKF_Skeleton_R_c cKF_bs_r_int_tak_money; +extern cKF_Animation_R_c cKF_ba_r_int_tak_money; + +static void fTMny_ct(FTR_ACTOR* ftr_actor, u8* data) { + cKF_SkeletonInfo_R_c* keyframe = &ftr_actor->keyframe; + + cKF_SkeletonInfo_R_ct(keyframe, &cKF_bs_r_int_tak_money, &cKF_ba_r_int_tak_money, ftr_actor->joint, + ftr_actor->morph); + cKF_SkeletonInfo_R_init_standard_repeat(keyframe, &cKF_ba_r_int_tak_money, NULL); + cKF_SkeletonInfo_R_play(keyframe); + keyframe->frame_control.speed = 0.0f; +} + +static f32 fTMny_GetSpeed(FTR_ACTOR* ftr_actor) { + f32 spd_x = ABS(ftr_actor->position.x - ftr_actor->last_position.x); + f32 spd_z = ABS(ftr_actor->position.z - ftr_actor->last_position.z); + f32 speed_sq = spd_x * spd_x + spd_z * spd_z; + + return sqrtf(speed_sq); +} + +static void fTMny_mv(FTR_ACTOR* ftr_actor, ACTOR* my_room_actor, GAME* game, u8* data) { + cKF_SkeletonInfo_R_c* keyframe = &ftr_actor->keyframe; + aMR_contact_info_c* contact_info = aMR_GetContactInfoLayer1(); + f32 speed = fTMny_GetSpeed(ftr_actor); + + if (contact_info != NULL) { + speed = (0.1f + speed / 1.55f) * 0.5f; + + if (ftr_actor->state == aFTR_STATE_WAIT_PUSH || ftr_actor->state == aFTR_STATE_WAIT_PUSH2 || + ftr_actor->state == aFTR_STATE_WAIT_PUSH3 || ftr_actor->state == aFTR_STATE_PUSH) { + switch (contact_info->contact_direction) { + case aMR_CONTACT_DIR_LEFT: + // play animation normally + keyframe->frame_control.speed = speed; + keyframe->frame_control.start_frame = 1.0f; + keyframe->frame_control.end_frame = cKF_ba_r_int_tak_money.frames; + break; + case aMR_CONTACT_DIR_RIGHT: + // play animation but in reverse + keyframe->frame_control.speed = speed; + keyframe->frame_control.start_frame = cKF_ba_r_int_tak_money.frames; + keyframe->frame_control.end_frame = 1.0f; + break; + default: + // no animation from other directions + keyframe->frame_control.speed = 0.0f; + break; + } + } else if (ftr_actor->state == aFTR_STATE_WAIT_PULL || ftr_actor->state == aFTR_STATE_WAIT_PULL2 || + ftr_actor->state == aFTR_STATE_PULL) { + switch (contact_info->contact_direction) { + case aMR_CONTACT_DIR_RIGHT: + // play animation normally + keyframe->frame_control.speed = speed; + keyframe->frame_control.start_frame = 1.0f; + keyframe->frame_control.end_frame = cKF_ba_r_int_tak_money.frames; + break; + case aMR_CONTACT_DIR_LEFT: + // play animation but in reverse + keyframe->frame_control.speed = speed; + keyframe->frame_control.start_frame = cKF_ba_r_int_tak_money.frames; + keyframe->frame_control.end_frame = 1.0f; + break; + default: + // no animation from other directions + keyframe->frame_control.speed = 0.0f; + break; + } + } else { + keyframe->frame_control.speed = 0.0f; + } + } else { + keyframe->frame_control.speed = 0.0f; + } + + cKF_SkeletonInfo_R_play(keyframe); +} + +static void fTMny_dw(FTR_ACTOR* ftr_actor, ACTOR* my_room_actor, GAME* game, u8* data) { + GAME_PLAY* play = (GAME_PLAY*)game; + cKF_SkeletonInfo_R_c* keyframe = &ftr_actor->keyframe; + Mtx* mtx = ftr_actor->skeleton_mtx[game->frame_counter & 1]; + + OPEN_DISP(game->graph); + + gSPMatrix(NEXT_POLY_OPA_DISP, _Matrix_to_Mtx_new(game->graph), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + + CLOSE_DISP(game->graph); + + cKF_Si3_draw_R_SV(game, keyframe, mtx, NULL, NULL, NULL); +} static aFTR_vtable_c fTMny_func = { - &fTMny_ct, - &fTMny_mv, - &fTMny_dw, - NULL, - NULL, + &fTMny_ct, &fTMny_mv, &fTMny_dw, NULL, NULL, }; aFTR_PROFILE iam_tak_money = { + // clang-format off NULL, NULL, NULL, @@ -28,4 +114,5 @@ aFTR_PROFILE iam_tak_money = { 0, 0, &fTMny_func, + // clang-format on }; diff --git a/src/ftr/ac_tak_moon.c b/src/ftr/ac_tak_moon.c index 879966c6..810d4b56 100644 --- a/src/ftr/ac_tak_moon.c +++ b/src/ftr/ac_tak_moon.c @@ -1,16 +1,86 @@ -static void fTMN_ct(FTR_ACTOR* ftr_actor, u8* data); -static void fTMN_mv(FTR_ACTOR* ftr_actor, ACTOR* my_room_actor, GAME* game, u8* data); -static void fTMN_dw(FTR_ACTOR* ftr_actor, ACTOR* my_room_actor, GAME* game, u8* data); +extern cKF_Skeleton_R_c cKF_bs_r_int_tak_moon; +extern cKF_Animation_R_c cKF_ba_r_int_tak_moon; + +static void fTMN_ct(FTR_ACTOR* ftr_actor, u8* data) { + cKF_SkeletonInfo_R_c* keyframe = &ftr_actor->keyframe; + int min = Common_Get(time.rtc_time.min); + int sec = Common_Get(time.rtc_time.sec); + + cKF_SkeletonInfo_R_ct(keyframe, &cKF_bs_r_int_tak_moon, &cKF_ba_r_int_tak_moon, ftr_actor->joint, ftr_actor->morph); + cKF_SkeletonInfo_R_init_standard_repeat(keyframe, &cKF_ba_r_int_tak_moon, NULL); + cKF_SkeletonInfo_R_play(keyframe); + + if (ftr_actor->switch_bit == TRUE) { + keyframe->frame_control.speed = 1.0f; + ftr_actor->dynamic_work_f[0] = 1.0f; + } else { + keyframe->frame_control.speed = 0.0f; + ftr_actor->dynamic_work_f[0] = 0.0f; + } + + ftr_actor->dynamic_work_f[1] = (f32)(min * mTM_SECONDS_IN_MINUTE + sec) / 600.0f; +} + +static void fTMN_mv(FTR_ACTOR* ftr_actor, ACTOR* my_room_actor, GAME* game, u8* data) { + cKF_SkeletonInfo_R_c* keyframe = &ftr_actor->keyframe; + f32 target; + + if (ftr_actor->switch_bit == TRUE) { + target = 1.0f; + } else { + target = 0.0f; + } + + add_calc(&ftr_actor->dynamic_work_f[0], target, 0.3f, 0.3f, 0.0001f); + keyframe->frame_control.speed = ftr_actor->dynamic_work_f[0] * 0.5f * 2.0f; + cKF_SkeletonInfo_R_play(keyframe); + + ftr_actor->dynamic_work_f[1] += 1.820444f; + if (ftr_actor->dynamic_work_f[1] >= USHT_MAX) { + ftr_actor->dynamic_work_f[1] = 0.0f; + } +} + +static int fTMN_DrawBefore(GAME* game, cKF_SkeletonInfo_R_c* keyframe, int joint_idx, Gfx** joint_shape, + u8* joint_flags, void* arg, s_xyz* joint_rot, xyz_t* joint_pos) { + FTR_ACTOR* ftr_actor = (FTR_ACTOR*)arg; + GAME_PLAY* play = (GAME_PLAY*)game; + + if (joint_idx == 1) { + joint_rot->z += (int)ftr_actor->dynamic_work_f[1]; + } + + return TRUE; +} + +static int fTMN_DrawAfter(GAME* game, cKF_SkeletonInfo_R_c* keyframe, int joint_idx, Gfx** joint_shape, u8* joint_flags, + void* arg, s_xyz* joint_rot, xyz_t* joint_pos) { + FTR_ACTOR* ftr_actor = (FTR_ACTOR*)arg; + GAME_PLAY* play = (GAME_PLAY*)game; + + return TRUE; +} + +static void fTMN_dw(FTR_ACTOR* ftr_actor, ACTOR* my_room_actor, GAME* game, u8* data) { + GAME_PLAY* play = (GAME_PLAY*)game; + cKF_SkeletonInfo_R_c* keyframe = &ftr_actor->keyframe; + Mtx* mtx = ftr_actor->skeleton_mtx[game->frame_counter & 1]; + + OPEN_DISP(game->graph); + + gSPMatrix(NEXT_POLY_OPA_DISP, _Matrix_to_Mtx_new(game->graph), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + + CLOSE_DISP(game->graph); + + cKF_Si3_draw_R_SV(game, keyframe, mtx, &fTMN_DrawBefore, &fTMN_DrawAfter, ftr_actor); +} static aFTR_vtable_c fTMN_func = { - &fTMN_ct, - &fTMN_mv, - &fTMN_dw, - NULL, - NULL, + &fTMN_ct, &fTMN_mv, &fTMN_dw, NULL, NULL, }; aFTR_PROFILE iam_tak_moon = { + // clang-format off NULL, NULL, NULL, @@ -28,4 +98,5 @@ aFTR_PROFILE iam_tak_moon = { 0, 0, &fTMN_func, + // clang-format on };