diff --git a/config/rel_slices.yml b/config/rel_slices.yml index b10355f1..f9a71fe0 100644 --- a/config/rel_slices.yml +++ b/config/rel_slices.yml @@ -733,6 +733,10 @@ ac_train1.c: .text: [0x805C0614, 0x805C0CC8] .rodata: [0x8064AD80, 0x8064ADB0] .data: [0x806C7300, 0x806C7388] +ac_yatai.c: + .text: [0x805C1D34, 0x805C217C] + .rodata: [0x8064ADC0, 0x8064ADC8] + .data: [0x806C76B8, 0x806C77E0] m_bank_ovl.c: .text: [0x805C38E4, 0x805C4714] .rodata: [0x8064AE58, 0x8064AE90] diff --git a/include/ac_yatai.h b/include/ac_yatai.h index 1f07388c..a072850c 100644 --- a/include/ac_yatai.h +++ b/include/ac_yatai.h @@ -2,7 +2,7 @@ #define AC_YATAI_H #include "types.h" -#include "m_actor.h" +#include "ac_structure.h" #ifdef __cplusplus extern "C" { @@ -10,6 +10,11 @@ extern "C" { extern ACTOR_PROFILE Yatai_Profile; +/* sizeof(YATAI_ACTOR) == 0x2DC */ +typedef struct actor_yatai_s { + STRUCTURE_ACTOR structure_class; +} YATAI_ACTOR; + #ifdef __cplusplus } #endif diff --git a/include/m_name_table.h b/include/m_name_table.h index 89a7743e..d601e435 100644 --- a/include/m_name_table.h +++ b/include/m_name_table.h @@ -2697,6 +2697,7 @@ extern int mNT_check_unknown(mActor_name_t item_no); #define DUMMY_RESERVE 0xF102 #define DUMMY_SHRINE 0xF103 #define DUMMY_RADIO 0xF109 +#define DUMMY_YATAI 0xF10A #define DUMMY_MIKUJI 0xF10D #define DUMMY_TAMA 0xF110 #define DUMMY_KOINOBORI 0xF114 diff --git a/src/ac_yatai.c b/src/ac_yatai.c new file mode 100644 index 00000000..0af54cf4 --- /dev/null +++ b/src/ac_yatai.c @@ -0,0 +1,63 @@ +#include "ac_yatai.h" + +#include "m_name_table.h" +#include "sys_matrix.h" +#include "m_lib.h" +#include "m_rcp.h" +#include "m_common_data.h" +#include "m_player_lib.h" + +static void aYAT_actor_ct(ACTOR* actor, GAME* game); +static void aYAT_actor_init(ACTOR* actor, GAME* game); +static void aYAT_actor_draw(ACTOR* actor, GAME* game); + +ACTOR_PROFILE Yatai_Profile = { + mAc_PROFILE_YATAI, + ACTOR_PART_ITEM, + ACTOR_STATE_TA_SET, + FIREWORKS_STALL0, + ACTOR_OBJ_BANK_KEEP, + sizeof(YATAI_ACTOR), + &aYAT_actor_ct, + NONE_ACTOR_PROC, + &aYAT_actor_init, + &aYAT_actor_draw, + NULL +}; + +static u8 aYAT_shadow_vtx_fix_flg_table[] = { + TRUE, FALSE, TRUE, FALSE, + FALSE, FALSE, TRUE, FALSE +}; + +extern Vtx obj_e_yatai_shadow_l_v[]; +extern Gfx obj_e_yatai_shadow_l_modelT[]; +static bIT_ShadowData_c aYAT_shadow_data_l = { + 7, aYAT_shadow_vtx_fix_flg_table, + 60.0f, + obj_e_yatai_shadow_l_v, + obj_e_yatai_shadow_l_modelT +}; + +extern Vtx obj_e_yatai_shadow_r_v[]; +extern Gfx obj_e_yatai_shadow_r_modelT[]; +static bIT_ShadowData_c aYAT_shadow_data_r = { + 10, aYAT_shadow_vtx_fix_flg_table, + 60.0f, + obj_e_yatai_shadow_r_v, + obj_e_yatai_shadow_r_modelT +}; + +static void aYAT_set_bgOffset(STRUCTURE_ACTOR* yatai, int idx); + +static void aYAT_actor_ct(ACTOR* actor, GAME* game) +{ + STRUCTURE_ACTOR* yatai = (STRUCTURE_ACTOR*)actor; + + yatai->arg0 = actor->npc_id - FIREWORKS_STALL0; + aYAT_set_bgOffset(yatai, yatai->arg0 + 2); +} + + #include "../src/ac_yatai_move.c_inc" + + #include "../src/ac_yatai_draw.c_inc" diff --git a/src/ac_yatai_draw.c_inc b/src/ac_yatai_draw.c_inc new file mode 100644 index 00000000..cc75b6e6 --- /dev/null +++ b/src/ac_yatai_draw.c_inc @@ -0,0 +1,37 @@ +extern Gfx obj_e_yatai_l_modelT[]; +extern Gfx obj_e_yatai_r_modelT[]; +extern Gfx obj_e_yatai_l_model[]; +extern Gfx obj_e_yatai_r_model[]; + +static void aYAT_actor_draw(ACTOR* actor, GAME* game) { + static bIT_ShadowData_c* shadow_data[2] = { &aYAT_shadow_data_l, &aYAT_shadow_data_r }; + static Gfx* mdl[2] = { obj_e_yatai_l_modelT, obj_e_yatai_r_modelT }; + static Gfx* mdl2[2] = { obj_e_yatai_l_model, obj_e_yatai_r_model }; + + STRUCTURE_ACTOR* yatai; + u16* pal; + Mtx* mtx; + Gfx* gfx; + GRAPH* graph; + + yatai = (STRUCTURE_ACTOR*)actor; + graph = game->graph; + pal = Common_Get(clip).structure_clip->get_pal_segment_proc(aSTR_PAL_YATAI); + mtx = _Matrix_to_Mtx_new(graph); + if (mtx != NULL) { + _texture_z_light_fog_prim_npc(graph); + + OPEN_DISP(graph); + gfx = NOW_POLY_OPA_DISP; + + gSPSegment(gfx++, G_MWO_SEGMENT_8, pal); + gSPMatrix(gfx++, mtx, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(gfx++, mdl[yatai->arg0]); + gSPDisplayList(gfx++, mdl2[yatai->arg0]); + + SET_POLY_OPA_DISP(gfx); + CLOSE_DISP(graph); + + (*Common_Get(clip).bg_item_clip->draw_shadow_proc)(game, shadow_data[yatai->arg0], FALSE); + } +} diff --git a/src/ac_yatai_move.c_inc b/src/ac_yatai_move.c_inc new file mode 100644 index 00000000..4f5d6b54 --- /dev/null +++ b/src/ac_yatai_move.c_inc @@ -0,0 +1,89 @@ +static void aYAT_set_bgOffset(STRUCTURE_ACTOR* yatai, int idx){ + static mCoBG_OffsetTable_c height_table_ct_l[9] = { + { 0x64, 0, 0, 0, 0, 0, 0 }, + { 0x64, 8, 0, 8, 8, 8, 1 }, + { 0x64, 8, 8, 8, 8, 0, 1 }, + { 0x64, 8, 0, 8, 8, 8, 1 }, + { 0x64, 8, 8, 8, 8, 8, 0 }, + { 0x64, 8, 8, 8, 0, 8, 1 }, + { 0x64, 8, 8, 0, 8, 8, 1 }, + { 0x64, 8, 8, 8, 0, 8, 1 }, + { 0x64, 0, 0, 0, 0, 0, 0 } + }; + + static mCoBG_OffsetTable_c height_table_ct_r[9] = { + { 0x64, 8, 0, 8, 8, 8, 1 }, + { 0x64, 8, 8, 8, 8, 0, 1 }, + { 0x64, 0, 0, 0, 0, 0, 0 }, + { 0x64, 8, 8, 0, 8, 8, 1 }, + { 0x64, 8, 8, 8, 8, 8, 0 }, + { 0x64, 8, 8, 8, 8, 0, 1 }, + { 0x64, 0, 0, 0, 0, 0, 0 }, + { 0x64, 8, 8, 0, 8, 8, 1 }, + { 0x64, 8, 8, 8, 0, 8, 1 } + }; + + static mCoBG_OffsetTable_c* height_table[4] = { + height_table_ct_l, height_table_ct_r, + height_table_ct_l, height_table_ct_r + }; + + static f32 addX[3] = { -40.0f, 0.0f, 40.0f }; + static f32 addZ[3] = { -40.0f, 0.0f, 40.0f }; + + mCoBG_OffsetTable_c* offset; + int type; + int i; + int j; + xyz_t pos; + + offset = height_table[idx]; + type = idx & 1; + for (i = 0; i < 3; i++) { + pos.z = 40.0f + (yatai->actor_class.home.position.z + addZ[i]); + for (j = 0; j < 3; j++) { + if (type == 0) { + if (j + i * 3 != 0 && j + i * 3 != 8) { + pos.x = (yatai->actor_class.home.position.x + addX[j]); + mCoBG_SetPluss5PointOffset_file(pos, *offset, __FILE__, 123); + } + } + else { + if (j + i * 3 != 2 && j + i * 3 != 6) { + pos.x = (yatai->actor_class.home.position.x + addX[j]); + mCoBG_SetPluss5PointOffset_file(pos, *offset, __FILE__, 129); + } + } + + offset++; + } + } +} + +static void aYAT_actor_move(ACTOR* actor, GAME* game) { + PLAYER_ACTOR* player_actor; + int yatai_bx; + int yatai_bz; + int player_bx; + int player_bz; + + player_actor = get_player_actor_withoutCheck((GAME_PLAY*)game); + + mFI_Wpos2BlockNum(&yatai_bx, &yatai_bz, actor->world.position); + mFI_Wpos2BlockNum(&player_bx, &player_bz, player_actor->actor_class.world.position); + + if (mDemo_Check(mDemo_TYPE_SCROLL, &player_actor->actor_class) == FALSE + && mDemo_Check(mDemo_TYPE_SCROLL2, &player_actor->actor_class) == FALSE + && mDemo_Check(mDemo_TYPE_SCROLL3, &player_actor->actor_class) == FALSE + && (yatai_bx != player_bx || yatai_bz != player_bz)) + { + Actor_delete(actor); + } +} + +static void aYAT_actor_init(ACTOR* actor, GAME* game){ + STRUCTURE_ACTOR* yatai = (STRUCTURE_ACTOR*)actor; + mFI_SetFG_common(DUMMY_YATAI, actor->home.position, FALSE); + aYAT_actor_move(actor, game); + actor->mv_proc = aYAT_actor_move; +}