mirror of
https://github.com/ACreTeam/ac-decomp
synced 2026-06-08 11:47:05 -04:00
Merge pull request #267 from Cuyler36/ac_misin
Implement & link ac_misin
This commit is contained in:
@@ -430,6 +430,10 @@ ac_mbg.c:
|
||||
.text: [0x8042DCA0, 0x8042DEC8]
|
||||
.rodata: [0x80644218, 0x80644238]
|
||||
.data: [0x80684BB0, 0x80684CB8]
|
||||
ac_misin.c:
|
||||
.text: [0x8042DEC8, 0x8042EAE0]
|
||||
.rodata: [0x80644238, 0x80644288]
|
||||
.data: [0x80684CB8, 0x80684D20]
|
||||
ac_museum_fossil.c:
|
||||
.text: [0x8042EDC0, 0x8042F170]
|
||||
.rodata: [0x806442A0, 0x806442D0]
|
||||
|
||||
+52
-1
@@ -3,11 +3,63 @@
|
||||
|
||||
#include "types.h"
|
||||
#include "m_actor.h"
|
||||
#include "m_needlework.h"
|
||||
#include "c_keyframe.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct misin_actor_s MISIN_ACTOR;
|
||||
|
||||
typedef void (*aMSN_REQUEST_MISIN_STOP_PROC)(void);
|
||||
typedef void (*aMSN_REQUEST_MISIN_MOVE_PROC)(void);
|
||||
|
||||
typedef void (*aMSN_REQUEST_DUSTCLOTH_STOP_PROC)(void);
|
||||
typedef void (*aMSN_REQUEST_DUSTCLOTH_MOVE_PROC)(void);
|
||||
|
||||
typedef struct misin_clip_s {
|
||||
MISIN_ACTOR* misin_actor_p;
|
||||
aMSN_REQUEST_MISIN_STOP_PROC request_misin_stop_proc;
|
||||
aMSN_REQUEST_MISIN_MOVE_PROC request_misin_move_proc;
|
||||
aMSN_REQUEST_DUSTCLOTH_STOP_PROC request_dustcloth_stop_proc;
|
||||
aMSN_REQUEST_DUSTCLOTH_MOVE_PROC request_dustcloth_move_proc;
|
||||
} aMSN_Clip_c;
|
||||
|
||||
#define aMSN_GetClip() ((aMSN_Clip_c*)Common_Get(clip).misin_clip)
|
||||
|
||||
typedef struct misin_dustcloth_s {
|
||||
s16 switch_flag;
|
||||
s16 frame;
|
||||
xyz_t pos;
|
||||
xyz_t target_pos;
|
||||
int target_idx;
|
||||
s16 target_angle_y;
|
||||
int moving_flag;
|
||||
mNW_original_design_c* original_p;
|
||||
u16* palette_p;
|
||||
} aMSN_DustCloth_c;
|
||||
|
||||
typedef struct misin_misin_s {
|
||||
s16 status;
|
||||
f32 speed;
|
||||
xyz_t pos;
|
||||
f32 needle_y_counter;
|
||||
xyz_t needle_offset;
|
||||
s16 y_scroll;
|
||||
cKF_SkeletonInfo_R_c keyframe;
|
||||
s_xyz work[17];
|
||||
s_xyz morph[17];
|
||||
Mtx mtx[2][16] ATTRIBUTE_ALIGN(8);
|
||||
} aMSN_Misin_c;
|
||||
|
||||
struct misin_actor_s {
|
||||
ACTOR actor_class;
|
||||
aMSN_DustCloth_c dustcloth;
|
||||
aMSN_Misin_c misin;
|
||||
aMSN_Clip_c clip;
|
||||
};
|
||||
|
||||
extern ACTOR_PROFILE Misin_Profile;
|
||||
|
||||
#ifdef __cplusplus
|
||||
@@ -15,4 +67,3 @@ extern ACTOR_PROFILE Misin_Profile;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
+52
-46
@@ -32,52 +32,58 @@ typedef void (*CLIP_NONE_PROC)();
|
||||
|
||||
/* sizeof(Clip_c) == 0x104 */
|
||||
typedef struct clip_s {
|
||||
/* 0x000 */ void* _000[(0x020 - 0x000) / sizeof(void*)];
|
||||
/* 0x020 */ int arrange_ftr_num;
|
||||
/* 0x024 */ void* _024[(0x040 - 0x024) / sizeof(void*)];
|
||||
/* 0x040 */ aNPC_Clip_c* npc_clip;
|
||||
/* 0x044 */ void* _044[(0x060 - 0x044) / sizeof(void*)];
|
||||
/* 0x060 */ aSM_Clip_c* shop_manekin_clip;
|
||||
/* 0x064 */ void* _064;
|
||||
/* 0x068 */ CLIP_NONE_PROC _068;
|
||||
/* 0x06C */ aQMgr_Clip_c* quest_manager_clip;
|
||||
/* 0x070 */ aSI_Clip_c* shop_indoor_clip;
|
||||
/* 0x074 */ bIT_Clip_c* bg_item_clip;
|
||||
/* 0x078 */ aWeather_Clip_c* weather_clip;
|
||||
/* 0x07C */ aINS_Clip_c* insect_clip;
|
||||
/* 0x080 */ aMR_Clip_c* my_room_clip;
|
||||
/* 0x084 */ void* _084;
|
||||
/* 0x088 */ aHOI_Clip_c* handOverItem_clip;
|
||||
/* 0x08C */ aSTR_Clip_c* structure_clip;
|
||||
/* 0x090 */ eEC_EffectControl_Clip_c* effect_clip;
|
||||
/* 0x094 */ aTOL_Clip_c* tools_clip;
|
||||
/* 0x098 */ void* _098;
|
||||
/* 0x09C */ aMI_Clip_c* my_indoor_clip;
|
||||
/* 0x0A0 */ mDemo_Clip_c* demo_clip; /* can be multiple clip classes */
|
||||
/* 0x0A4 */ mDemo_Clip_c* demo_clip2; /* can be multiple clip classes */
|
||||
/* 0x0A8 */ void* _0A8;
|
||||
/* 0x0AC */ aGYO_Clip_c* gyo_clip;
|
||||
/* 0x0B0 */ void* _0B0;
|
||||
/* 0x0B4 */ void* _0B4;
|
||||
/* 0x0B8 */ aShopUmbrella_Clip_c* shop_umbrella_clip;
|
||||
/* 0x0BC */ aAR_Clip_c* arrange_room_clip;
|
||||
/* 0x0C0 */ void* _0C0;
|
||||
/* 0x0C4 */ void* _0C4;
|
||||
/* 0x0C8 */ void* shrine_clip;
|
||||
/* 0x0CC */ void* _0CC;
|
||||
/* 0x0D0 */ void* _0D0;
|
||||
/* 0x0D4 */ CLIP_NONE_PROC ball_redma_proc; /* removed in DnM+ */
|
||||
/* 0x0D8 */ void* _0D8;
|
||||
/* 0x0DC */ aAL_Clip_c* animal_logo_clip;
|
||||
/* 0x0E0 */ void* _0E0;
|
||||
/* 0x0E4 */ void* _0E4;
|
||||
/* 0x0E8 */ void* _0E8;
|
||||
/* 0x0EC */ aAPC_Clip_c* aprilfool_control_clip;
|
||||
/* 0x0F0 */ aEvMgr_Clip_c* event_manager_clip;
|
||||
/* 0x0F4 */ aGHC_Clip_c* groundhog_control_clip;
|
||||
/* 0x0F8 */ void* _0F8;
|
||||
/* 0x0FC */ void* _0FC;
|
||||
/* 0x100 */ void* _100;
|
||||
/* 0x000 */ void* _000[(0x020 - 0x000) / sizeof(void*)];
|
||||
/* 0x020 */ int arrange_ftr_num;
|
||||
/* 0x024 */ void* _024;
|
||||
/* 0x028 */ void* misin_clip;
|
||||
/* 0x02C */ void* _02C;
|
||||
/* 0x030 */ void* _030;
|
||||
/* 0x034 */ void* _034;
|
||||
/* 0x038 */ void* _038;
|
||||
/* 0x03C */ void* _03C;
|
||||
/* 0x040 */ aNPC_Clip_c* npc_clip;
|
||||
/* 0x044 */ void* _044[(0x060 - 0x044) / sizeof(void*)];
|
||||
/* 0x060 */ aSM_Clip_c* shop_manekin_clip;
|
||||
/* 0x064 */ void* _064;
|
||||
/* 0x068 */ CLIP_NONE_PROC _068;
|
||||
/* 0x06C */ aQMgr_Clip_c* quest_manager_clip;
|
||||
/* 0x070 */ aSI_Clip_c* shop_indoor_clip;
|
||||
/* 0x074 */ bIT_Clip_c* bg_item_clip;
|
||||
/* 0x078 */ aWeather_Clip_c* weather_clip;
|
||||
/* 0x07C */ aINS_Clip_c* insect_clip;
|
||||
/* 0x080 */ aMR_Clip_c* my_room_clip;
|
||||
/* 0x084 */ void* _084;
|
||||
/* 0x088 */ aHOI_Clip_c* handOverItem_clip;
|
||||
/* 0x08C */ aSTR_Clip_c* structure_clip;
|
||||
/* 0x090 */ eEC_EffectControl_Clip_c* effect_clip;
|
||||
/* 0x094 */ aTOL_Clip_c* tools_clip;
|
||||
/* 0x098 */ void* _098;
|
||||
/* 0x09C */ aMI_Clip_c* my_indoor_clip;
|
||||
/* 0x0A0 */ mDemo_Clip_c* demo_clip; /* can be multiple clip classes */
|
||||
/* 0x0A4 */ mDemo_Clip_c* demo_clip2; /* can be multiple clip classes */
|
||||
/* 0x0A8 */ void* _0A8;
|
||||
/* 0x0AC */ aGYO_Clip_c* gyo_clip;
|
||||
/* 0x0B0 */ void* _0B0;
|
||||
/* 0x0B4 */ void* _0B4;
|
||||
/* 0x0B8 */ aShopUmbrella_Clip_c* shop_umbrella_clip;
|
||||
/* 0x0BC */ aAR_Clip_c* arrange_room_clip;
|
||||
/* 0x0C0 */ void* _0C0;
|
||||
/* 0x0C4 */ void* _0C4;
|
||||
/* 0x0C8 */ void* shrine_clip;
|
||||
/* 0x0CC */ void* _0CC;
|
||||
/* 0x0D0 */ void* _0D0;
|
||||
/* 0x0D4 */ CLIP_NONE_PROC ball_redma_proc; /* removed in DnM+ */
|
||||
/* 0x0D8 */ void* _0D8;
|
||||
/* 0x0DC */ aAL_Clip_c* animal_logo_clip;
|
||||
/* 0x0E0 */ void* _0E0;
|
||||
/* 0x0E4 */ void* _0E4;
|
||||
/* 0x0E8 */ void* _0E8;
|
||||
/* 0x0EC */ aAPC_Clip_c* aprilfool_control_clip;
|
||||
/* 0x0F0 */ aEvMgr_Clip_c* event_manager_clip;
|
||||
/* 0x0F4 */ aGHC_Clip_c* groundhog_control_clip;
|
||||
/* 0x0F8 */ void* _0F8;
|
||||
/* 0x0FC */ void* _0FC;
|
||||
/* 0x100 */ void* _100;
|
||||
} Clip_c;
|
||||
|
||||
extern void clip_clear();
|
||||
|
||||
+370
@@ -0,0 +1,370 @@
|
||||
#include "ac_misin.h"
|
||||
|
||||
#include "m_common_data.h"
|
||||
#include "m_malloc.h"
|
||||
#include "m_player_lib.h"
|
||||
#include "m_rcp.h"
|
||||
#include "sys_matrix.h"
|
||||
|
||||
static void Misin_Actor_ct(ACTOR* actorx, GAME* game);
|
||||
static void Misin_Actor_dt(ACTOR* actorx, GAME* game);
|
||||
static void Misin_Actor_draw(ACTOR* actorx, GAME* game);
|
||||
static void Misin_Actor_move(ACTOR* actorx, GAME* game);
|
||||
|
||||
ACTOR_PROFILE Misin_Profile = {
|
||||
mAc_PROFILE_MISIN,
|
||||
ACTOR_PART_BG,
|
||||
ACTOR_STATE_CAN_MOVE_IN_DEMO_SCENES | ACTOR_STATE_NO_DRAW_WHILE_CULLED | ACTOR_STATE_NO_MOVE_WHILE_CULLED,
|
||||
EMPTY_NO,
|
||||
ACTOR_OBJ_BANK_KEEP,
|
||||
sizeof(MISIN_ACTOR),
|
||||
&Misin_Actor_ct,
|
||||
&Misin_Actor_dt,
|
||||
&Misin_Actor_move,
|
||||
&Misin_Actor_draw,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static void aMSN_SetDustclothSwitch(s16 switch_flag) {
|
||||
if (aMSN_GetClip() != NULL) {
|
||||
aMSN_GetClip()->misin_actor_p->dustcloth.switch_flag = switch_flag;
|
||||
}
|
||||
}
|
||||
|
||||
static void aMSN_RequestDustclothMove(void) {
|
||||
aMSN_SetDustclothSwitch(TRUE);
|
||||
}
|
||||
|
||||
static void aMSN_RequestDustclothStop(void) {
|
||||
aMSN_SetDustclothSwitch(FALSE);
|
||||
}
|
||||
|
||||
static xyz_t aMSN_dustcloth_target_table[4] = {
|
||||
{ -4.0f, 0.0f, 4.0f },
|
||||
{ -4.0f, 0.0f, -4.0f },
|
||||
{ 4.0f, 0.0f, -4.0f },
|
||||
{ 4.0f, 0.0f, 4.0f },
|
||||
};
|
||||
|
||||
static void aMSN_DustclothCT(aMSN_DustCloth_c* dustcloth, GAME* game) {
|
||||
dustcloth->switch_flag = TRUE;
|
||||
dustcloth->frame = 0;
|
||||
dustcloth->original_p = (mNW_original_design_c*)zelda_malloc_align(sizeof(mNW_original_design_c), 32);
|
||||
|
||||
if (dustcloth->original_p != NULL) {
|
||||
if (RANDOM(3) == 1) {
|
||||
mNW_CopyOriginalTextureClass(dustcloth->original_p,
|
||||
&Save_Get(needlework).original_design[RANDOM(1000) & 7]);
|
||||
} else {
|
||||
dustcloth->palette_p = (u16*)zelda_malloc_align(sizeof(u16) * 16, 32);
|
||||
if (dustcloth->palette_p != NULL) {
|
||||
mActor_name_t cloth;
|
||||
|
||||
mSP_SelectRandomItem_New(NULL, &cloth, 1, NULL, 0, mSP_KIND_CLOTH, mSP_LISTTYPE_ABC, FALSE);
|
||||
mPlib_Load_PlayerTexAndPallet(dustcloth->original_p->design.data, dustcloth->palette_p,
|
||||
ITEM_NAME_GET_INDEX(cloth));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dustcloth->target_idx = 1;
|
||||
dustcloth->pos.x = 91.0f;
|
||||
dustcloth->pos.y = 0.0f;
|
||||
dustcloth->pos.z = 136.0f;
|
||||
dustcloth->target_pos = aMSN_dustcloth_target_table[(dustcloth->target_idx - 1) & 3];
|
||||
}
|
||||
|
||||
static void aMSN_SetMisinStatus(s16 status) {
|
||||
if (aMSN_GetClip() != NULL) {
|
||||
aMSN_GetClip()->misin_actor_p->misin.status = status;
|
||||
}
|
||||
}
|
||||
|
||||
static void aMSN_RequestMisinStop(void) {
|
||||
aMSN_SetMisinStatus(FALSE);
|
||||
}
|
||||
|
||||
static void aMSN_ReqeustMisinMove(void) {
|
||||
aMSN_SetMisinStatus(TRUE);
|
||||
}
|
||||
|
||||
extern cKF_Skeleton_R_c cKF_bs_r_obj_misin;
|
||||
extern cKF_Animation_R_c cKF_ba_r_obj_misin;
|
||||
|
||||
static void aMSN_MisinCT(aMSN_Misin_c* misin, GAME* game) {
|
||||
cKF_SkeletonInfo_R_c* keyframe = &misin->keyframe;
|
||||
|
||||
misin->status = TRUE;
|
||||
cKF_SkeletonInfo_R_ct(keyframe, &cKF_bs_r_obj_misin, &cKF_ba_r_obj_misin, misin->work, misin->morph);
|
||||
cKF_SkeletonInfo_R_init_standard_repeat(keyframe, &cKF_ba_r_obj_misin, NULL);
|
||||
cKF_SkeletonInfo_R_play(keyframe);
|
||||
|
||||
misin->speed = 1.0f;
|
||||
keyframe->frame_control.speed = 1.0f;
|
||||
misin->pos.x = 0.0f;
|
||||
misin->pos.y = 0.0f;
|
||||
misin->pos.z = 0.0f;
|
||||
misin->needle_y_counter = 0.0f;
|
||||
}
|
||||
|
||||
static void aMSN_SetClipInfo(ACTOR* actorx, GAME* game) {
|
||||
MISIN_ACTOR* misin_actor = (MISIN_ACTOR*)actorx;
|
||||
aMSN_Clip_c* clip = &misin_actor->clip;
|
||||
|
||||
clip->misin_actor_p = misin_actor;
|
||||
clip->request_misin_stop_proc = &aMSN_RequestMisinStop;
|
||||
clip->request_misin_move_proc = &aMSN_ReqeustMisinMove;
|
||||
clip->request_dustcloth_stop_proc = &aMSN_RequestDustclothStop;
|
||||
clip->request_dustcloth_move_proc = &aMSN_RequestDustclothMove;
|
||||
Common_Get(clip).misin_clip = clip;
|
||||
}
|
||||
|
||||
static void Misin_Actor_ct(ACTOR* actorx, GAME* game) {
|
||||
MISIN_ACTOR* misin_actor = (MISIN_ACTOR*)actorx;
|
||||
aMSN_DustCloth_c* dustcloth = &misin_actor->dustcloth;
|
||||
aMSN_Misin_c* misin = &misin_actor->misin;
|
||||
|
||||
aMSN_DustclothCT(dustcloth, game);
|
||||
aMSN_MisinCT(misin, game);
|
||||
aMSN_SetClipInfo(actorx, game);
|
||||
}
|
||||
|
||||
static void Misin_Actor_dt(ACTOR* actorx, GAME* game) {
|
||||
MISIN_ACTOR* misin = (MISIN_ACTOR*)actorx;
|
||||
|
||||
if (misin->dustcloth.original_p != NULL) {
|
||||
zelda_free(misin->dustcloth.original_p);
|
||||
}
|
||||
|
||||
if (misin->dustcloth.palette_p != NULL) {
|
||||
zelda_free(misin->dustcloth.palette_p);
|
||||
}
|
||||
|
||||
Common_Get(clip).misin_clip = NULL;
|
||||
}
|
||||
|
||||
extern Gfx obj_misin_cloth_model[];
|
||||
|
||||
static void aMSN_DrawDustcloth(aMSN_DustCloth_c* dustcloth, GAME* game) {
|
||||
s16 target_angle_y = dustcloth->target_angle_y;
|
||||
|
||||
if (dustcloth->original_p != NULL) {
|
||||
_texture_z_light_fog_prim(game->graph);
|
||||
|
||||
OPEN_DISP(game->graph);
|
||||
|
||||
/* Segment 8 holds the custom design or shirt texture */
|
||||
gSPSegment(NEXT_POLY_OPA_DISP, G_MWO_SEGMENT_8, dustcloth->original_p->design.data);
|
||||
|
||||
if (dustcloth->palette_p != NULL) {
|
||||
/* Segment 9 holds the palette for the shirt */
|
||||
gSPSegment(NEXT_POLY_OPA_DISP, G_MWO_SEGMENT_9, dustcloth->palette_p);
|
||||
} else {
|
||||
/* Segment 9 holds the palette for the custom design */
|
||||
gSPSegment(NEXT_POLY_OPA_DISP, G_MWO_SEGMENT_9, mNW_PaletteIdx2Palette(dustcloth->original_p->palette));
|
||||
}
|
||||
|
||||
Matrix_translate(dustcloth->pos.x, dustcloth->pos.y, dustcloth->pos.z, 0);
|
||||
Matrix_RotateY(target_angle_y, 1);
|
||||
Matrix_translate(-dustcloth->target_pos.x, -dustcloth->target_pos.y, -dustcloth->target_pos.z, 1);
|
||||
Matrix_scale(0.01f, 0.01f, 0.01f, 1);
|
||||
|
||||
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, obj_misin_cloth_model);
|
||||
|
||||
CLOSE_DISP(game->graph);
|
||||
}
|
||||
}
|
||||
|
||||
static int aMSN_DrawMisinBefore(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) {
|
||||
/* Skip drawing the needle model */
|
||||
if (joint_idx == 3) {
|
||||
*joint_shape = NULL;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
extern Gfx obj_misin_hari_model[];
|
||||
|
||||
static int aMSN_DrawMisinAfter(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) {
|
||||
aMSN_Misin_c* misin = (aMSN_Misin_c*)arg;
|
||||
|
||||
/* Now draw the needle model */
|
||||
if (joint_idx == 3) {
|
||||
OPEN_DISP(game->graph);
|
||||
|
||||
Matrix_translate(87.0f, 62.0f + misin->needle_offset.y, 141.0f, 0);
|
||||
Matrix_RotateY(DEG2SHORT_ANGLE(0.0f), 1);
|
||||
Matrix_RotateZ(DEG2SHORT_ANGLE(-90.0f), 1);
|
||||
Matrix_scale(0.01f, 0.01f, 0.01f, 1);
|
||||
|
||||
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, obj_misin_hari_model);
|
||||
|
||||
CLOSE_DISP(game->graph);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static Gfx* aMSN_MakeBeltGFX(aMSN_Misin_c* misin, GAME* game) {
|
||||
return two_tex_scroll_dolphin(game->graph, 0, 0, misin->y_scroll, 8, 32, 1, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
static void aMSN_DrawMisin(aMSN_Misin_c* misin, GAME* game) {
|
||||
cKF_SkeletonInfo_R_c* keyframe = &misin->keyframe;
|
||||
Mtx* mtx_p = misin->mtx[game->frame_counter & 1];
|
||||
Gfx* belt_gfx = aMSN_MakeBeltGFX(misin, game);
|
||||
|
||||
_texture_z_light_fog_prim(game->graph);
|
||||
if (belt_gfx != NULL) {
|
||||
OPEN_DISP(game->graph);
|
||||
|
||||
Matrix_translate(misin->pos.x, misin->pos.y, misin->pos.z, 0);
|
||||
Matrix_RotateY(DEG2SHORT_ANGLE(0.0f), 1);
|
||||
Matrix_scale(0.01f, 0.01f, 0.01f, 1);
|
||||
|
||||
gSPMatrix(NEXT_POLY_OPA_DISP, _Matrix_to_Mtx_new(game->graph), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
|
||||
|
||||
/* Segment 9 has the scrolled belt gfx */
|
||||
gSPSegment(NEXT_POLY_OPA_DISP, G_MWO_SEGMENT_9, belt_gfx);
|
||||
|
||||
/* Draw animated model */
|
||||
cKF_Si3_draw_R_SV(game, keyframe, mtx_p, &aMSN_DrawMisinBefore, &aMSN_DrawMisinAfter, misin);
|
||||
|
||||
CLOSE_DISP(game->graph);
|
||||
}
|
||||
}
|
||||
|
||||
static void Misin_Actor_draw(ACTOR* actorx, GAME* game) {
|
||||
MISIN_ACTOR* misin = (MISIN_ACTOR*)actorx;
|
||||
|
||||
aMSN_DrawDustcloth(&misin->dustcloth, game);
|
||||
aMSN_DrawMisin(&misin->misin, game);
|
||||
}
|
||||
|
||||
static void aMSN_MoveDustcloth(aMSN_DustCloth_c* dustcloth, GAME* game) {
|
||||
static s16 target_angle_table[4] = {
|
||||
DEG2SHORT_ANGLE(0.0f),
|
||||
DEG2SHORT_ANGLE(90.0f),
|
||||
DEG2SHORT_ANGLE(-180.0f),
|
||||
DEG2SHORT_ANGLE(-90.0f),
|
||||
};
|
||||
dustcloth->moving_flag = FALSE;
|
||||
|
||||
if (dustcloth->switch_flag != FALSE) {
|
||||
if (dustcloth->frame == 137) {
|
||||
int target_idx = dustcloth->target_idx;
|
||||
|
||||
dustcloth->target_pos = aMSN_dustcloth_target_table[target_idx];
|
||||
dustcloth->target_angle_y = target_angle_table[target_idx];
|
||||
|
||||
if (dustcloth->target_angle_y == DEG2SHORT_ANGLE(0.0f)) {
|
||||
dustcloth->target_angle_y = -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (dustcloth->frame < 98) {
|
||||
f32 percent = get_percent(97, 0, dustcloth->frame);
|
||||
int now_idx = dustcloth->target_idx;
|
||||
int prev_idx = (dustcloth->target_idx - 1) & 3;
|
||||
|
||||
/* Interpolate position between last target pos & now target pos */
|
||||
dustcloth->target_pos.x =
|
||||
aMSN_dustcloth_target_table[prev_idx].x +
|
||||
percent * (aMSN_dustcloth_target_table[now_idx].x - aMSN_dustcloth_target_table[prev_idx].x);
|
||||
dustcloth->target_pos.z =
|
||||
aMSN_dustcloth_target_table[prev_idx].z +
|
||||
percent * (aMSN_dustcloth_target_table[now_idx].z - aMSN_dustcloth_target_table[prev_idx].z);
|
||||
|
||||
/* Set rotation */
|
||||
dustcloth->target_angle_y = target_angle_table[prev_idx];
|
||||
|
||||
if (dustcloth->frame > 21) {
|
||||
/* Play sewing SFX */
|
||||
xyz_t pos = { 91.0f, 40.0f, 136.0f };
|
||||
|
||||
sAdo_OngenPos((u32)&aMSN_MoveDustcloth, 0x48, &pos);
|
||||
}
|
||||
} else if (dustcloth->frame >= 120) {
|
||||
f32 percent = get_percent(138, 120, dustcloth->frame);
|
||||
int now_idx = dustcloth->target_idx;
|
||||
int prev_idx = (dustcloth->target_idx - 1) & 3;
|
||||
|
||||
/* Interpolate rotation */
|
||||
dustcloth->target_angle_y = target_angle_table[prev_idx] + (s16)(percent * (f32)DEG2SHORT_ANGLE(90.0f));
|
||||
}
|
||||
|
||||
if (!(dustcloth->frame > 4 && dustcloth->frame < 118)) {
|
||||
dustcloth->moving_flag = TRUE;
|
||||
}
|
||||
|
||||
dustcloth->frame++;
|
||||
if (dustcloth->frame >= 138) {
|
||||
dustcloth->target_idx = (dustcloth->target_idx + 1) & 3;
|
||||
dustcloth->frame = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void aMSN_SetNeedleOffsetPosition(aMSN_Misin_c* misin, aMSN_DustCloth_c* dustcloth) {
|
||||
static xyz_t zero_offset = { 0.0f, 0.0f, 0.0f };
|
||||
int counter = misin->needle_y_counter;
|
||||
|
||||
if (counter < 10) {
|
||||
misin->needle_offset.y = (misin->needle_y_counter / 10.0f) * -3.0f;
|
||||
} else if (counter < 17) {
|
||||
misin->needle_offset.y = ((misin->needle_y_counter - 10.0f) / 7.0f) * 3.0f + -3.0f;
|
||||
} else {
|
||||
misin->needle_offset = zero_offset;
|
||||
}
|
||||
|
||||
if (dustcloth->moving_flag == FALSE) {
|
||||
misin->needle_y_counter += misin->speed;
|
||||
}
|
||||
|
||||
if (misin->needle_y_counter > 19.0f) {
|
||||
misin->needle_y_counter -= 19.0f;
|
||||
}
|
||||
}
|
||||
|
||||
static void aMSN_MoveMisin(aMSN_Misin_c* misin, aMSN_DustCloth_c* dustcloth, GAME* game) {
|
||||
f32 target_speed;
|
||||
cKF_SkeletonInfo_R_c* keyframe;
|
||||
|
||||
if (misin->status == TRUE) {
|
||||
target_speed = 1.0f;
|
||||
} else {
|
||||
target_speed = 0.0f;
|
||||
}
|
||||
|
||||
keyframe = &misin->keyframe;
|
||||
aMSN_SetNeedleOffsetPosition(misin, dustcloth);
|
||||
misin->y_scroll += (s16)(misin->speed * -6.0f);
|
||||
cKF_SkeletonInfo_R_play(keyframe);
|
||||
|
||||
if (misin->speed < target_speed) {
|
||||
misin->speed += 0.01f;
|
||||
} else {
|
||||
misin->speed -= 0.01f;
|
||||
}
|
||||
|
||||
if (misin->speed < 0.0f) {
|
||||
misin->speed = 0.0f;
|
||||
} else if (misin->speed > 1.0f) {
|
||||
misin->speed = 1.0f;
|
||||
}
|
||||
|
||||
keyframe->frame_control.speed = misin->speed;
|
||||
}
|
||||
|
||||
static void Misin_Actor_move(ACTOR* actorx, GAME* game) {
|
||||
MISIN_ACTOR* misin = (MISIN_ACTOR*)actorx;
|
||||
aMSN_DustCloth_c* dustcloth = &misin->dustcloth;
|
||||
|
||||
aMSN_MoveDustcloth(dustcloth, game);
|
||||
aMSN_MoveMisin(&misin->misin, dustcloth, game);
|
||||
}
|
||||
Reference in New Issue
Block a user