diff --git a/config/rel_slices.yml b/config/rel_slices.yml index f5ddddb0..d2903542 100644 --- a/config/rel_slices.yml +++ b/config/rel_slices.yml @@ -40,6 +40,11 @@ m_bg_item.c: .text: [0x80378858, 0x803789F8] .rodata: [0x806413E0, 0x806413F0] .bss: [0x81263080, 0x81263088] +m_bgm.c: + .text: [0x803789F8, 0x8037D190] + .rodata: [0x806413F0, 0x80641438] + .data: [0x8064F658, 0x8064F818] + .bss: [0x81263088, 0x812633A0] m_calendar.c: .text: [0x8037D190, 0x8037DA54] m_camera2.c: diff --git a/include/audio.h b/include/audio.h index 5fe96d79..fd0514f5 100644 --- a/include/audio.h +++ b/include/audio.h @@ -19,8 +19,8 @@ extern void sAdo_Calc_MicPosition_forTrig(f32* fcalc, u16* scalc, xyz_t* pos); extern void sAdo_Calc_MicPosition_forLevel(f32* fcalc, u16* scalc, xyz_t* pos); extern void sAdo_GameFrame(); -extern void sAdo_BgmStart(s8 id); -extern void sAdo_BgmStop(s16 id); +extern void sAdo_BgmStart(u8 id); +extern void sAdo_BgmStop(u16 id); extern void sAdo_SysTrgStart(u16 id); extern void sAdo_PlyWalkSe(int walk, xyz_t* pos); diff --git a/include/jaudio_NES/game64.h b/include/jaudio_NES/game64.h index 624fbcf2..8a337092 100644 --- a/include/jaudio_NES/game64.h +++ b/include/jaudio_NES/game64.h @@ -9,9 +9,9 @@ extern "C" { extern void Na_InitAudio(void (*fatal_callback)(), u8* load_addr, size_t load_size, u8* bootsound, size_t bootsound_size, BOOL cut_flag); extern void Na_GameFrame(); -extern void Na_BgmStart(s8); +extern void Na_BgmStart(u8); extern void Na_BgmCrossfadeStart(u8); -extern void Na_BgmStop(s16); +extern void Na_BgmStop(u16); extern void Na_SysTrgStart(u16); extern void Na_PlyWalkSe(int, u16,f32); extern void Na_PlyWalkSeRoom(int, u16, f32); diff --git a/include/m_bgm.h b/include/m_bgm.h index 331f2cad..32c22a43 100644 --- a/include/m_bgm.h +++ b/include/m_bgm.h @@ -2,26 +2,55 @@ #define M_BGM_H #include "types.h" +#include "game_h.h" +#include "m_lib.h" #ifdef __cplusplus extern "C" { #endif -extern void mBGM_ct(); -extern void mBGM_reset(); -extern void mBGMPsComp_make_ps_lost_fanfare(u8 bgm_no, u16 unk); -extern void mBGMPsComp_scene_mode(int scene_mode); -extern void mBGMPsComp_make_ps_wipe(u16 ps_wipe); -extern void mBGMPsComp_delete_ps_demo(u8 bgm_num, u16 stop_type); -extern void mBGMPsComp_make_ps_demo(u8 bgm_no, u16 stop_type); -extern void mBGMPsComp_museum_status(int museum_status); +extern void mBGMPsComp_make_ps_fanfare(u8 bgm_num, u16 stop_type); +extern void mBGMPsComp_make_ps_lost_fanfare(u8 bgm_num, u16 stop_type); +extern void mBGMPsComp_make_ps_wipe(u16 stop_type); +extern void mBGMPsComp_make_ps_quiet(u16 stop_type); +extern void mBGMPsComp_make_ps_co_quiet(u16 stop_type, s16 counter); +extern void mBGMPsComp_make_ps_fc_quiet(u16 stop_type); +extern void mBGMPsComp_make_ps_demo(u8 bgm_num, u16 stop_type); +extern void mBGMPsComp_make_ps_happening(u8 bgm_num, u16 stop_type); +extern void mBGMPsComp_make_ps_room(u8 bgm_num, u16 stop_type); extern void mBGMPsComp_make_ps_quietField(u16 stop_type); +extern void mBGMPsComp_make_ps_fc_quietField(u16 stop_type); +extern void mBGMPsComp_make_ps_fieldSuddenEv(u8 bgm_num, u16 stop_type, u8 priority); +extern void mBGMPsComp_delete_ps_fanfare(u8 bgm_num, u16 stop_type); +extern void mBGMPsComp_delete_ps_wipe(); +extern void mBGMPsComp_delete_ps_demo(u8 bgm_num, u16 stop_type); +extern void mBGMPsComp_delete_ps_happening(u8 bgm_num, u16 stop_type); +extern void mBGMPsComp_delete_ps_room(u8 bgm_num, u16 stop_type); extern void mBGMPsComp_delete_ps_quietField(); -extern void mBGMPsComp_make_ps_co_quiet(u16 stop_type, s16 frames); +extern void mBGMPsComp_delete_ps_fieldSuddenEv(u8 bgm_num, u16 stop_type); +extern void mBGMPsComp_volume_fishing_start(); +extern void mBGMPsComp_volume_fishing_end(); +extern void mBGMPsComp_volume_collect_insects_start(); +extern void mBGMPsComp_volume_collect_insects_end(); extern void mBGMPsComp_volume_talk_start(); extern void mBGMPsComp_volume_talk_end(); +extern void mBGMPsComp_volume_boat_start(); +extern void mBGMPsComp_volume_boat_end(); +extern void mBGMPsComp_pause(int state); +extern void mBGMPsComp_MDPlayerPos_make(); +extern void mBGMPsComp_MDPlayerPos_delete(); +extern void mBGMPsComp_MDPlayerPos_param_set(const xyz_t* pos, u16 angle, u16 md_type, u32 ongen_no); +extern void mBGMPsComp_scene_mode(u8 mode); +extern void mBGMPsComp_museum_status(u8 status); +extern int mBGMPsComp_execute_bgm_num_get(); +extern void mBGMForce_inform_start(); extern void mBGMForce_inform_end(); -extern void mBGMPsComp_pause(int pause_mode); +extern void mBGMForce_room_nonstop_start(); +extern void mBGM_main(GAME* game); +extern void mBGM_ct(); +extern void mBGM_init(); +extern void mBGM_cleanup(); +extern void mBGM_reset(); #ifdef __cplusplus } diff --git a/include/m_event.h b/include/m_event.h index 4b08e778..93677d88 100644 --- a/include/m_event.h +++ b/include/m_event.h @@ -487,6 +487,7 @@ extern int mEv_CheckFirstIntro(); extern int mEv_CheckArbeit(); extern int mEv_CheckTitleDemo(); extern int mEv_check_status(int event, s16 status); +extern int mEv_check_status_edge(s16 status); extern s8* mEv_get_common_area(int type, s8 id); extern s8* mEv_reserve_common_area(int type, s8 id); extern s8* mEv_get_save_area(int type, s8 id); diff --git a/include/m_player_lib.h b/include/m_player_lib.h index 0adb78ac..bf52d7e4 100644 --- a/include/m_player_lib.h +++ b/include/m_player_lib.h @@ -25,7 +25,7 @@ extern void mPlib_Set_goal_player_demo_walk(f32 goal_x, f32 goal_z, f32 speed); extern void mPlib_Set_able_hand_all_item_in_demo(s8 enable); extern void mPlib_change_player_cloth_info_lv2(Private_c* priv, mActor_name_t cloth_name); extern int mPlib_Get_address_able_display(); -extern int mPlib_get_player_actor_main_index(GAME_PLAY* play); +extern int mPlib_get_player_actor_main_index(GAME* game); extern int mPlib_check_player_actor_main_index_AllWade(GAME_PLAY* play); extern int mPlib_request_main_demo_wait_type1(GAME_PLAY* play, int param_2, void* param_3); extern int mPlib_request_main_talk_type1(GAME_PLAY* play, ACTOR* other_actor, int turn, int flag); diff --git a/src/audio.c b/src/audio.c index 33707972..36a9e1f3 100644 --- a/src/audio.c +++ b/src/audio.c @@ -49,11 +49,11 @@ extern void sAdo_GameFrame(){ Na_GameFrame(); } -extern void sAdo_BgmStart(s8 id){ +extern void sAdo_BgmStart(u8 id){ Na_BgmStart(id); } -extern void sAdo_BgmStop(s16 id){ +extern void sAdo_BgmStop(u16 id){ Na_BgmStop(id); } extern void sAdo_SysTrgStart(u16 id){ @@ -261,9 +261,9 @@ extern void sAdo_MDPlayerPos(xyz_t* pos, u16 s1, u16 s2, int p){ Na_MDPlayerPos(scalc,s1,s2,p,fcalc); } -extern void sAdo_BGMVolume(f32 f, u16 volume){ +extern void sAdo_BGMVolume(f32 volume, u16 vol_move_ctr){ - Na_BGMVolume(f,volume); + Na_BGMVolume(volume, vol_move_ctr); } extern void sAdo_BgmCrossfadeStart(u8 b){ diff --git a/src/m_bgm.c b/src/m_bgm.c new file mode 100644 index 00000000..e696f64d --- /dev/null +++ b/src/m_bgm.c @@ -0,0 +1,2969 @@ +#include "m_bgm.h" + +#include "game.h" +#include "libultra/libultra.h" +#include "m_common_data.h" +#include "m_event.h" +#include "m_lib.h" +#include "m_melody.h" +#include "m_player_lib.h" + +#define mBGMPs_FLAG_REMOVE (1 << 0) +#define mBGMPs_FLAG_UPDATE_VOLUME (1 << 1) +#define mBGMPs_FLAG_EXECUTE (1 << 2) +#define mBGMPs_FLAG_CROSSFADE (1 << 3) +#define mBGMPs_FLAG_UPDATE_VOLUME_MOVE_CTR (1 << 4) +#define mBGMPs_FLAG_UPDATE_VOLUME_LEVEL (1 << 5) +#define mBGMPs_FLAG_SILENT (1 << 6) +#define mBGMPs_FLAG_FADEOUT (1 << 7) +#define mBGMPs_FLAG_LOST (1 << 8) + +enum { + mBGM_KATEGORIE_FANFARE, + mBGM_KATEGORIE_WIPE, + mBGM_KATEGORIE_QUIET, + mBGM_KATEGORIE_DEMO, + mBGM_KATEGORIE_HAPPENING, + mBGM_KATEGORIE_QUIETROOM, + mBGM_KATEGORIE_ROOM, + mBGM_KATEGORIE_TIME, + mBGM_KATEGORIE_QUIETFIELD, + mBGM_KATEGORIE_FIELDSUDDENEV, + mBGM_KATEGORIE_FIELDSCHEDEV, + mBGM_KATEGORIE_FIELDNORM, + + mBGM_KATEGORIE_NUM +}; + +enum { + mBGMForce_INFORM_0, + mBGMForce_INFORM_1, + mBGMForce_INFORM_2, + mBGMForce_INFORM_3, + mBGMForce_INFORM_4, + mBGMForce_INFORM_5, + mBGMForce_INFORM_6, + mBGMForce_INFORM_7, + + mBGMForce_INFORM_NUM +}; + +typedef struct bgm_elem_s { + u8 bgm_num; + u8 _pad0; + u16 _pad1; + u16 stop_type0; + u16 stop_type1; +} mBGMElem; + +typedef struct bgm_clock_s { + u32 now; + u32 before; +} mBGMClock; + +typedef struct bgm_demo_s { + mBGMElem elem; + u8 make_flag; + u8 delete_flag; + u16 _pad; +} mBGMDemo; + +typedef struct bgm_room_s { + mBGMElem elem; + u8 make_flag; + u8 delete_flag; + u8 shop_fadeout_flag; + u8 _pad; + u32 shop_close_time0; + u32 shop_close_time1; +} mBGMRoom; + +typedef struct bgm_time_s mBGMTime; + +typedef void (*mBGMTime_MOVE_PROC)(mBGMTime*, GAME*); + +struct bgm_time_s { + mBGMTime_MOVE_PROC move_proc; + u8 new_year_ev_flag; + u8 _pad; +}; + +typedef struct bgm_field_sudden_ev_s { + u32 flag; + u32 old_flag; +} mBGMFieldSuddenEv; + +typedef struct bgm_field_schedule_ev_info_s { + u32 flag; + int attr; + int old_attr; +} mBGMFieldSchedEv_Info; + +typedef struct bgm_field_schedule_ev_s { + mBGMFieldSchedEv_Info info[24]; // every hour has its own info +} mBGMFieldSchedEv; + +typedef struct bgm_field_normal_s { + mBGMElem elem; + u8 make_flag; + u8 delete_flag; + u16 _pad; +} mBGMFieldNorm; + +typedef struct bgm_ps_s { + mBGMElem elem; + int kategorie; + s16 counter; + u16 cf_flags; + u8 priority; + u8 _pad; +} mBGMPs; + +typedef struct bgm_ps_comp_stop_s { + u8 req_flag; + u16 type; + u8 _pad; +} mBGMPsComp_Stop; + +typedef struct bgm_ps_comp_start_s { + u8 req_flag; + u8 bgm_num; + u8 flags; + u8 _pad; +} mBGMPsComp_Start; + +typedef struct bgm_ps_comp_volume_s { + f32 main_volume; + u16 main_volume_move_ctr; + u8 main_req_flag; + u8 _pad0; + + f32 ps_volume; + u16 ps_volume_move_ctr; + u8 ps_req_flag; + u8 _pad1; + + f32 fishing_volume; + u16 fishing_volume_move_ctr; + u8 fishing_req_flag; + u8 _pad2; + + f32 collect_insects_volume; + u16 collect_insects_volume_move_ctr; + u8 collect_insects_req_flag; + u8 _pad3; + + f32 talk_volume; + u8 talk_req_flag; + u8 _pad4; + + f32 boat_volume; + u8 boat_req_flag; + u8 _pad5; + + f32 pause_volume; + u16 pause_volume_move_ctr; + u8 pause_req_flag; + u8 _pad6; +} mBGMPsComp_Volume; + +typedef struct bgm_ps_comp_pause_s { + u8 req_flag; + u8 mode; + u16 _pad; +} mBGMPsComp_Pause; + +typedef struct bgm_ps_comp_md_player_pos_s { + u8 req_flag; + u8 make_flag; + u8 delete_flag; + u8 move_flag; + xyz_t pos; + u16 angle; + u16 md_type_no; + u32 ongen_no; +} mBGMPsComp_MDPlayerPos; + +#define mBGM_BGMPs_NUM 14 + +typedef struct bgm_ps_comp_arm_s { + u8 req_flag; + u8 arm_state; + u16 _pad; +} mBGMPsComp_Arm; + +typedef struct bgm_ps_comp_museum_s { + u8 req_flag; + u8 type; + u16 _pad; +} mBGMPsComp_Museum; + +typedef struct bgm_ps_comp_s { + mBGMPs ps[mBGM_BGMPs_NUM]; + int ps_num; + int fishing_state; + int collect_insects_state; + int talk_state; + int boat_state; + int pause_state; + mBGMPsComp_Stop stop; + mBGMPsComp_Start start; + mBGMPsComp_Volume volume; + mBGMPsComp_Pause pause; + mBGMPsComp_MDPlayerPos md; + mBGMPsComp_Arm arm; + mBGMPsComp_Museum museum; +} mBGMPsComp; + +typedef struct bgm_force_s { + int inform; + u8 flag; + int room_nonstop; +} mBGMForce; + +typedef struct bgm_s { + mBGMClock clock; + mBGMDemo demo; + mBGMRoom room; + mBGMTime time; + mBGMFieldSuddenEv field_sudden_ev; + mBGMFieldSchedEv field_sched_ev; + mBGMFieldNorm field_norm; + mBGMPsComp ps_comp; + mBGMForce force; +} mBGM; + +static mBGM M_bgm; + +static int mBGM_check_MD(u8 bgm_num) { + int res = FALSE; + + if ((bgm_num >= 0x80 && bgm_num <= 0xB3) || (bgm_num >= 0xB4 && bgm_num <= 0xB6)) { + res = TRUE; + } + + return res; +} + +static int mBGM_check_ignore_talk_volume(u8 bgm_num) { + /* TODO: defines/enums for these ids */ + static const u8 bgm_data[44] = { + 40, + 73, + 68, + 74, + 76, + 75, + 49, + 50, + 71, + 64, + 66, + 78, + 122, + 125, + 92, + 93, + 94, + 95, + 96, + 97, + 98, + 99, + 100, + 101, + 102, + 103, + 104, + 105, + 106, + 107, + 108, + 109, + 110, + 111, + 112, + 113, + 114, + 115, + 116, + 117, + 118, + 119, + 120, + 121 + }; + + const u8* bgm_data_p = bgm_data; + int i; + + for (i = 0; i < ARRAY_COUNT(bgm_data); i++) { + if (bgm_num == *bgm_data_p) { + return TRUE; + } + + bgm_data_p++; + } + + return FALSE; +} + +static int mBGM_check_ignore_collect_insects_volume(u8 bgm_num) { + if (bgm_num == 40) { + return TRUE; + } + + return FALSE; +} + +static mBGMElem_default_set(mBGMElem* elem) { + static mBGMElem default_data = { 127, 0, 0, 0x168, 0x168 }; + + bcopy(&default_data, elem, sizeof(mBGMElem)); +} + +/* mBGMClock */ + +#define mBGMClock_CHK_ss (((1 << 6) - 1) << 0) +#define mBGMClock_CHK_mm (((1 << 6) - 1) << 6) +#define mBGMClock_CHK_hh (((1 << 5) - 1) << 12) +#define mBGMClock_CHK_DD (((1 << 5) - 1) << 17) +#define mBGMClock_CHK_MM (((1 << 4) - 1) << 22) + +static int mBGMClock_after_time_check(mBGMClock* clock, u32 check_time, u32 check_mask) { + u32 t_now = clock->now & check_mask; + u32 t_check = check_time & check_mask; + + if (t_now >= t_check) { + return TRUE; + } + + return FALSE; +} + +static int mBGMClock_over_time_check(mBGMClock* clock, u32 check_time, u32 check_mask) { + u32 t_now = clock->now & check_mask; + u32 t_before = clock->before & check_mask; + u32 t_check = check_time & check_mask; + + if (t_now >= t_before) { + int res = FALSE; + if (t_check > t_before && t_check <= t_now) { + res = TRUE; + } + + return res; + } + else { + int res = FALSE; + if (t_check > t_before || t_check <= t_now) { + res = TRUE; + } + + return res; + } +} + +static int mBGMClock_range_time_check(mBGMClock* clock, u32 check_time0, u32 check_time1, u32 check_mask) { + u32 t_now = clock->now & check_mask; + u32 t_check0 = check_time0 & check_mask; + u32 t_check1 = check_time1 & check_mask; + int res; + + if (t_check1 >= t_check0) { + res = FALSE; + if (t_now >= t_check0 && t_now < t_check1) { + res = TRUE; + } + + return res; + } + else { + res = FALSE; + if (t_now >= t_check0 || t_now < t_check1) { + res = TRUE; + } + + return res; + } +} + +static void mBGMClock_now_set(mBGMClock* clock) { + clock->before = clock->now; + clock->now = + ((Common_Get(time.rtc_time).month & 0x0F) << 22) | + ((Common_Get(time.rtc_time).day & 0x1F) << 17) | + ((Common_Get(time.rtc_time).hour & 0x1F) << 12) | + ((Common_Get(time.rtc_time).min & 0x3F) << 6) | + ((Common_Get(time.rtc_time).sec & 0x3F) << 0); +} + +static void mBGMClock_move(mBGMClock* clock, GAME* game) { + mBGMClock_now_set(clock); +} + +static void mBGMClock_ct(mBGMClock* clock) { + bzero(clock, sizeof(mBGMClock)); + mBGMClock_now_set(clock); + clock->before = clock->now; +} + +/* mBGMDemo */ + +static void mBGMDemo_make_scene_bgm(mBGMDemo* demo) { + if (demo->elem.bgm_num == 127 && mFI_CheckFieldData()) { + mActor_name_t field_id = mFI_GetFieldId(); + u8 bgm_num; + + switch (field_id) { + case mFI_FIELD_DEMO_STARTDEMO: + case mFI_FIELD_DEMO_STARTDEMO2: + bgm_num = 42; + break; + + case mFI_FIELD_DEMO_STARTDEMO3: + bgm_num = 123; + break; + + case mFI_FIELD_DEMO_PLAYERSELECT: + if (Save_Get(scene_no) == SCENE_PLAYERSELECT_SAVE) { + bgm_num = 46; + } + else { + bgm_num = 43; + } + break; + + default: + bgm_num = 127; + break; + } + + if (bgm_num != 127) { + mBGMElem_default_set(&demo->elem); + demo->elem.bgm_num = bgm_num; + mBGMPsComp_make_ps_demo(bgm_num, 0x168); + } + } +} + +static void mBGMDemo_delete_scene_bgm(mBGMDemo* demo) { + if (demo->elem.bgm_num != 127) { + mBGMPsComp_delete_ps_demo(demo->elem.bgm_num, 0x168); + demo->elem.bgm_num = 127; + } +} + +static void mBGMDemo_move(mBGMDemo* demo, GAME* game) { + if (demo->delete_flag) { + mBGMDemo_delete_scene_bgm(demo); + } + + if (demo->make_flag) { + mBGMDemo_make_scene_bgm(demo); + } + + demo->make_flag = FALSE; + demo->delete_flag = FALSE; +} + +static void mBGMDemo_scene_bgm_make_req() { + M_bgm.demo.make_flag = TRUE; +} + +static void mBGMDemo_scene_bgm_delete_req() { + M_bgm.demo.delete_flag = TRUE; +} + +static void mBGMDemo_ct(mBGMDemo* demo) { + bzero(demo, sizeof(mBGMDemo)); + mBGMElem_default_set(&demo->elem); +} + +/* mBGMRoom */ + +static void mBGMRoom_shop_close_time_set(mBGMRoom* room) { + if (mFI_CheckFieldData()) { + mActor_name_t field_id = mFI_GetFieldId(); + + if ( + field_id == mFI_FIELD_ROOM_SHOP0 || + field_id == mFI_FIELD_ROOM_SHOP1 || + field_id == mFI_FIELD_ROOM_SHOP2 || + field_id == mFI_FIELD_ROOM_SHOP3_1 || + field_id == mFI_FIELD_ROOM_SHOP3_2 + ) { + lbRTC_time_c time; + + bzero(&time, sizeof(lbRTC_time_c)); + time.hour = mSP_GetShopCloseTime_Bgm(); + + lbRTC_Sub_mm(&time, 5); + room->shop_close_time1 = ((time.hour & 0x1F) << 12) | ((time.min & 0x3F) << 6) | ((time.sec & 0x3F) << 0); + + lbRTC_Sub_ss(&time, 5); + room->shop_close_time0 = ((time.hour & 0x1F) << 12) | ((time.min & 0x3F) << 6) | ((time.sec & 0x3F) << 0); + } + } +} + +static u8 mBGMRoom_make_scene_bgm_shop_get(mBGMRoom* room, mActor_name_t field_id) { + u8 bgm_num; + + if ( + mEv_CheckRealArbeit() == FALSE && + mBGMClock_after_time_check(&M_bgm.clock, room->shop_close_time1, mBGMClock_CHK_hh | mBGMClock_CHK_mm | mBGMClock_CHK_ss) + ) { + /* Play 'almost closing' music */ + if (field_id == mFI_FIELD_ROOM_SHOP0) { + bgm_num = 79; + } + else if (field_id == mFI_FIELD_ROOM_SHOP1) { + bgm_num = 80; + } + else if (field_id == mFI_FIELD_ROOM_SHOP2) { + bgm_num = 81; + } + else { + bgm_num = 82; + } + } + else { + /* Play normal music */ + if (field_id == mFI_FIELD_ROOM_SHOP0) { + bgm_num = 44; + } + else if (field_id == mFI_FIELD_ROOM_SHOP1) { + bgm_num = 37; + } + else if (field_id == mFI_FIELD_ROOM_SHOP2) { + bgm_num = 38; + } + else { + bgm_num = 39; + } + } + + return bgm_num; +} + +static void mBGMRoom_make_scene_bgm(mBGMRoom* room) { + if (room->elem.bgm_num == 127 && mFI_CheckFieldData()) { + mActor_name_t field_id = mFI_GetFieldId(); + u8 bgm_num; + + switch (field_id) { + case mFI_FIELD_ROOM_SHOP0: + case mFI_FIELD_ROOM_SHOP1: + case mFI_FIELD_ROOM_SHOP2: + case mFI_FIELD_ROOM_SHOP3_1: + case mFI_FIELD_ROOM_SHOP3_2: + bgm_num = mBGMRoom_make_scene_bgm_shop_get(room, field_id); + break; + + case mFI_FIELD_ROOM_BROKER_SHOP: + bgm_num = 25; + break; + + case mFI_FIELD_ROOM_POST_OFFICE: + if (Common_Get(post_girl_npc_type) != 0) { + bgm_num = 62; + } + else { + bgm_num = 41; + } + break; + + case mFI_FIELD_ROOM_POLICE_BOX: + bgm_num = 45; + break; + + case mFI_FIELD_ROOM_BUGGY: + bgm_num = 26; + break; + + case mFI_FIELD_ROOM_KAMAKURA: + bgm_num = 77; + break; + + case mFI_FIELD_ROOM_TENT: + bgm_num = 254; + break; + + case mFI_FIELD_ROOM_MUSEUM_ENTRANCE: + case mFI_FIELD_ROOM_MUSEUM_PAINTING: + case mFI_FIELD_ROOM_MUSEUM_FOSSIL: + case mFI_FIELD_ROOM_MUSEUM_INSECT: + case mFI_FIELD_ROOM_MUSEUM_FISH: + bgm_num = 88; + break; + + case mFI_FIELD_ROOM_NEEDLEWORK: + bgm_num = 89; + break; + + case mFI_FIELD_ROOM_LIGHTHOUSE: + bgm_num = 90; + break; + + default: + bgm_num = 127; + break; + } + + if (bgm_num != 127) { + mBGMElem_default_set(&room->elem); + room->elem.bgm_num = bgm_num; + mBGMPsComp_make_ps_room(bgm_num, 0x168); + } + } +} + +static void mBGMRoom_delete_scene_bgm(mBGMRoom* room) { + if (room->elem.bgm_num != 127) { + mBGMPsComp_delete_ps_room(room->elem.bgm_num, 0x168); + room->elem.bgm_num = 127; + } +} + +static void mBGMPsComp_make_ps_quietRoom(u16 stop_type); +static void mBGMPsComp_delete_ps_quietRoom(); + +static int mBGMRoom_shop_close_check(mBGMRoom* room) { + int res = FALSE; + int time1_flag = FALSE; + int fadeout_flag = FALSE; + int temp_flag2; + + if (mFI_CheckFieldData()) { + mActor_name_t field_id = mFI_GetFieldId(); + + if ( + field_id == mFI_FIELD_ROOM_SHOP0 || + field_id == mFI_FIELD_ROOM_SHOP1 || + field_id == mFI_FIELD_ROOM_SHOP2 || + field_id == mFI_FIELD_ROOM_SHOP3_1 || + field_id == mFI_FIELD_ROOM_SHOP3_2 + ) { + int real_arbeit = mEv_CheckRealArbeit(); + + temp_flag2 = FALSE; + if (real_arbeit == FALSE && mBGMClock_range_time_check(&M_bgm.clock, room->shop_close_time0, room->shop_close_time1, mBGMClock_CHK_hh | mBGMClock_CHK_mm | mBGMClock_CHK_ss)) { + temp_flag2 = TRUE; + } + fadeout_flag = temp_flag2; + + time1_flag = FALSE; + if (real_arbeit == FALSE && mBGMClock_over_time_check(&M_bgm.clock, room->shop_close_time1, mBGMClock_CHK_hh | mBGMClock_CHK_mm | mBGMClock_CHK_ss)) { + time1_flag = TRUE; + } + + res = time1_flag; + } + } + + if (fadeout_flag && room->shop_fadeout_flag == FALSE) { + mBGMPsComp_make_ps_quietRoom(0x13DE); + room->shop_fadeout_flag = TRUE; + } + else if (!fadeout_flag && room->shop_fadeout_flag) { + mBGMPsComp_delete_ps_quietRoom(); + room->shop_fadeout_flag = FALSE; + } + + return res; +} + +static void mBGMRoom_move(mBGMRoom* room, GAME* game) { + if (mBGMRoom_shop_close_check(room)) { + room->delete_flag = TRUE; + room->make_flag = TRUE; + } + + if (room->delete_flag) { + mBGMRoom_delete_scene_bgm(room); + } + + if (room->make_flag) { + mBGMRoom_make_scene_bgm(room); + } + + room->make_flag = FALSE; + room->delete_flag = FALSE; +} + +static void mBGMRoom_scene_bgm_make_req() { + M_bgm.room.make_flag = TRUE; +} + +static void mBGMRoom_scene_bgm_delete_req() { + M_bgm.room.delete_flag = TRUE; +} + +static void mBGMRoom_ct(mBGMRoom* room) { + bzero(room, sizeof(mBGMRoom)); + mBGMElem_default_set(&room->elem); +} + +/* mBGMTime */ + +static void mBGMTime_signal_melody(mBGMTime* time, GAME* game) { + static u8 signal_melody_buf[mMld_MELODY_LEN]; + + if ( + mEv_CheckFirstIntro() == FALSE && + mEv_CheckTitleDemo() != -9 && + mFI_CheckFieldData() && + mFI_GET_TYPE(mFI_GetFieldId()) != mFI_FIELD_DEMO_STARTDEMO && + time->new_year_ev_flag == FALSE && + mPlib_get_player_actor_main_index(game) != mPlayer_INDEX_DEMO_GETON_BOAT && + mPlib_get_player_actor_main_index(game) != mPlayer_INDEX_DEMO_GETON_BOAT_SITDOWN && + mPlib_get_player_actor_main_index(game) != mPlayer_INDEX_DEMO_GETON_BOAT_WAIT && + mPlib_get_player_actor_main_index(game) != mPlayer_INDEX_DEMO_GETON_BOAT_WADE && + mPlib_get_player_actor_main_index(game) != mPlayer_INDEX_DEMO_GETOFF_BOAT_STANDUP && + mPlib_get_player_actor_main_index(game) != mPlayer_INDEX_DEMO_GETOFF_BOAT + ) { + mMld_GetMelody(signal_melody_buf); + + if (mFI_CheckInIsland()) { + sAdo_Inst(0xFE, signal_melody_buf); + } + else { + sAdo_Inst(0xFF, signal_melody_buf); + } + } +} + +static int mBGMTime_silent_check(mBGMTime* time) { + if (time->new_year_ev_flag) { + return FALSE; + } + + /* Silent between XX:59:52 and XX:00:16 */ + return mBGMClock_range_time_check(&M_bgm.clock, (59 << 6) | (52 << 0), (0 << 6) | (16 << 0), mBGMClock_CHK_mm | mBGMClock_CHK_ss); +} + +static void mBGMTime_new_year_ev_flag_set() { + M_bgm.time.new_year_ev_flag = TRUE; +} + +static void mBGMTime_new_year_ev_flag_clr() { + M_bgm.time.new_year_ev_flag = FALSE; +} + +static void mBGMTime_move_wait(mBGMTime* time, GAME* game); +static void mBGMTime_move_change(mBGMTime* time, GAME* game); +static void mBGMPsComp_make_ps_time(); + +static void mBGMTime_move_wait(mBGMTime* time, GAME* game) { + if (mBGMTime_silent_check(time)) { + mBGMPsComp_make_ps_time(); + time->move_proc = &mBGMTime_move_change; + } +} + +static void mBGMPsComp_delete_ps_time(); + +static void mBGMTime_move_change(mBGMTime* time, GAME* game) { + /* Wait until XX:00:00 and then play the town tune melody */ + if (mBGMClock_over_time_check(&M_bgm.clock, 0, mBGMClock_CHK_mm | mBGMClock_CHK_ss)) { + mBGMTime_signal_melody(time, game); + } + + if (mBGMTime_silent_check(time) == FALSE) { + mBGMPsComp_delete_ps_time(); + time->move_proc = &mBGMTime_move_wait; + } +} + +static void mBGMTime_move(mBGMTime* time, GAME* game) { + (*time->move_proc)(time, game); +} + +static void mBGMTime_ct(mBGMTime* time) { + bzero(time, sizeof(mBGMTime)); + time->move_proc = &mBGMTime_move_wait; +} + +/* mBGMFieldSuddenEv */ + +static int mBGMFieldSuddenEv_flag_check_island(mBGMFieldSuddenEv* field_sudden_ev, GAME* game) { + return mFI_CheckInJustIslandOutdoor(); +} + +static int mBGMFieldSuddenEv_flag_check_arbeit(mBGMFieldSuddenEv* field_sudden_ev, GAME* game) { + return mEv_CheckFirstJob(); +} + +typedef int (*mBGMFieldSuddenEv_EV_CHK_PROC)(mBGMFieldSuddenEv*, GAME*); + +static void mBGMFieldSuddenEv_flag_set(mBGMFieldSuddenEv* field_sudden_ev, GAME* game) { + static mBGMFieldSuddenEv_EV_CHK_PROC ev_chk[] = { + &mBGMFieldSuddenEv_flag_check_island, + NULL, + &mBGMFieldSuddenEv_flag_check_arbeit + }; + + field_sudden_ev->old_flag = field_sudden_ev->flag; + field_sudden_ev->flag = 0; + + if (mFI_CheckFieldData() && mFI_GET_TYPE(mFI_GetFieldId()) == mFI_FIELD_FG) { + int i = 0; + u32 mask = 1; + + for (i; i < 3; i++) { + if (ev_chk[i] != NULL && (*ev_chk[i])(field_sudden_ev, game) != FALSE) { + field_sudden_ev->flag |= mask; + } + + mask <<= 1; + } + } +} + +static void mBGMFieldSuddenEv_ps_compose(mBGMFieldSuddenEv* field_sudden_ev, GAME* game) { + static u8 bgm_num_data[3] = { 91, 127, 52 }; + int now; + int old; + int i = 0; + int mask = 1; + + for (i; i < 3; i++) { + now = (field_sudden_ev->flag & mask) != 0; + old = (field_sudden_ev->old_flag & mask) != 0; + + if (!now && old) { + mBGMPsComp_delete_ps_fieldSuddenEv(bgm_num_data[i], 0x168); + } + + if (now && !old) { + mBGMPsComp_make_ps_fieldSuddenEv(bgm_num_data[i], 0x168, i); + } + + mask <<= 1; + } +} + +static void mBGMFieldSuddenEv_move(mBGMFieldSuddenEv* field_sudden_ev, GAME* game) { + mBGMFieldSuddenEv_flag_set(field_sudden_ev, game); + mBGMFieldSuddenEv_ps_compose(field_sudden_ev, game); +} + +static void mBGMFieldSuddenEv_ct(mBGMFieldSuddenEv* field_sudden_ev) { + bzero(field_sudden_ev, sizeof(mBGMFieldSuddenEv)); +} + +/* mBGMFieldSchedEv */ + +static int mbgm_pattern_data[3][3] = { + { 2, 2, 2 }, + { 0, 1, 2 }, + { 0, 0, 2 } +}; + +#define mBGMEventArea_ALL 0 /* Happens everywhere */ +#define mBGMEventArea_BLOCK 1 /* Happens at a specific block */ + +enum { + mBGMFieldSchedEv_EVENT_SILENCE_0, + mBGMFieldSchedEv_EVENT_FIREWORKS, + mBGMFieldSchedEv_EVENT_HALLOWEEN, + mBGMFieldSchedEv_EVENT_TOY_DAY, + mBGMFieldSchedEv_EVENT_CHERRY_BLOSSOM_FESTIVAL, + mBGMFieldSchedEv_EVENT_MORNING_AEROBICS, + mBGMFieldSchedEv_EVENT_HARVEST_MOON_13, + mBGMFieldSchedEv_EVENT_HARVEST_FESTIVAL, + mBGMFieldSchedEv_EVENT_SPORTS_FAIR_AEROBICS, + mBGMFieldSchedEv_EVENT_SPORTS_FAIR_FOOT_RACE, + mBGMFieldSchedEv_EVENT_SPORTS_FAIR_BALL_TOSS, + mBGMFieldSchedEv_EVENT_SPORTS_FAIR_TUG_OF_WAR, + mBGMFieldSchedEv_EVENT_COUNTDOWN_1, + mBGMFieldSchedEv_EVENT_COUNTDOWN_2, + mBGMFieldSchedEv_EVENT_COUNTDOWN_3, + mBGMFieldSchedEv_EVENT_COUNTDOWN_4, + mBGMFieldSchedEv_EVENT_COUNTDOWN_5, + mBGMFieldSchedEv_EVENT_COUNTDOWN_6, + mBGMFieldSchedEv_EVENT_NEW_YEARS, + mBGMFieldSchedEv_EVENT_HOTARU, + mBGMFieldSchedEv_EVENT_NEWYEAR01, + mBGMFieldSchedEv_EVENT_NEWYEAR02, + mBGMFieldSchedEv_EVENT_GROUNDHOG_DAY, + mBGMFieldSchedEv_EVENT_METEOR_SHOWER, + + mBGMFieldSchedEv_EVENT_NUM +}; + +typedef struct bgm_event_data_s { + s16 event_type; + u8 bgm_num; + u8 event_area; + u32 block_type; +} mBGMEventData; + +static mBGMEventData mbgm_event_data[mBGMFieldSchedEv_EVENT_NUM] = { + { + -1, + 127, + mBGMEventArea_BLOCK, + mRF_BLOCKKIND_POOL + }, + { + mEv_EVENT_FIREWORKS_SHOW, + 55, + mBGMEventArea_BLOCK, + mRF_BLOCKKIND_POOL + }, + { + mEv_EVENT_HALLOWEEN, + 53, + mBGMEventArea_ALL, + mRF_BLOCKKIND_NONE + }, + { + mEv_EVENT_TALK_TOY_DAY, + 54, + mBGMEventArea_ALL, + mRF_BLOCKKIND_NONE + }, + { + mEv_EVENT_CHERRY_BLOSSOM_FESTIVAL, + 56, + mBGMEventArea_BLOCK, + mRF_BLOCKKIND_SHRINE + }, + { + mEv_EVENT_MORNING_AEROBICS, + 27, + mBGMEventArea_BLOCK, + mRF_BLOCKKIND_SHRINE + }, + { + mEv_EVENT_HARVEST_MOON_FESTIVAL, + 30, + mBGMEventArea_BLOCK, + mRF_BLOCKKIND_POOL + }, + { + mEv_EVENT_HARVEST_FESTIVAL, + 253, + mBGMEventArea_BLOCK, + mRF_BLOCKKIND_SHRINE + }, + { + mEv_EVENT_SPORTS_FAIR_AEROBICS, + 27, + mBGMEventArea_BLOCK, + mRF_BLOCKKIND_SHRINE + }, + { + mEv_EVENT_SPORTS_FAIR_FOOT_RACE, + 28, + mBGMEventArea_BLOCK, + mRF_BLOCKKIND_SHRINE + }, + { + mEv_EVENT_SPORTS_FAIR_BALL_TOSS, + 29, + mBGMEventArea_BLOCK, + mRF_BLOCKKIND_SHRINE + }, + { + mEv_EVENT_SPORTS_FAIR_TUG_OF_WAR, + 60, + mBGMEventArea_BLOCK, + mRF_BLOCKKIND_SHRINE + }, + { + mEv_EVENT_NEW_YEARS_EVE_COUNTDOWN, + 31, + mBGMEventArea_BLOCK, + mRF_BLOCKKIND_POOL + }, + { + -1, + 32, + mBGMEventArea_BLOCK, + mRF_BLOCKKIND_POOL + }, + { + -1, + 33, + mBGMEventArea_BLOCK, + mRF_BLOCKKIND_POOL + }, + { + -1, + 34, + mBGMEventArea_BLOCK, + mRF_BLOCKKIND_POOL + }, + { + -1, + 35, + mBGMEventArea_BLOCK, + mRF_BLOCKKIND_POOL + }, + { + -1, + 57, + mBGMEventArea_BLOCK, + mRF_BLOCKKIND_POOL + }, + { + mEv_EVENT_NEW_YEARS_DAY, + 59, + mBGMEventArea_BLOCK, + mRF_BLOCKKIND_SHRINE + }, + { + -1, + 255, + mBGMEventArea_ALL, + mRF_BLOCKKIND_NONE + }, + { + -1, + 36, + mBGMEventArea_ALL, + mRF_BLOCKKIND_NONE + }, + { + -1, + 61, + mBGMEventArea_ALL, + mRF_BLOCKKIND_NONE + }, + { + mEv_EVENT_GROUNDHOG_DAY, + 251, + mBGMEventArea_BLOCK, + mRF_BLOCKKIND_SHRINE + }, + { + mEv_EVENT_METEOR_SHOWER, + 250, + mBGMEventArea_BLOCK, + mRF_BLOCKKIND_POOL + } +}; + +enum { + mBGM_BL_ATTR_INACTIVE, + mBGM_BL_ATTR_NEARBY, + mBGM_BL_ATTR_ACTIVE, + + mBGM_BL_ATTR_NUM +}; + +static int mBGMFieldSchedEv_bl_attr_get(int bx, int bz, int area, u32 block_type) { + int attr = mBGM_BL_ATTR_INACTIVE; + + if (area == mBGMEventArea_ALL) { + attr = mBGM_BL_ATTR_ACTIVE; + } + else if (block_type != mRF_BLOCKKIND_NONE) { + int ev_bx; + int ev_bz; + + if (mFI_BlockKind2BkNum(&ev_bx, &ev_bz, block_type)) { + int d_bx = ev_bx - bx; + int d_bz = ev_bz - bz; + + if (d_bx == 0 && d_bz == 0) { + attr = mBGM_BL_ATTR_ACTIVE; + } + else if (area == mBGMEventArea_BLOCK) { + d_bx = ABS(d_bx); + d_bz = ABS(d_bz); + + if ((d_bx == 0 && d_bz == 1) || (d_bx == 1 && d_bz == 0)) { + attr = mBGM_BL_ATTR_NEARBY; + } + } + } + } + + return attr; +} + +static int mBGMFieldSchedEv_bl_attr_evdata_get(mBGMEventData* data, GAME* game) { + PLAYER_ACTOR* player = GET_PLAYER_ACTOR((GAME_PLAY*)game); + int attr = mBGM_BL_ATTR_NUM; + + if (player != NULL) { + int not_wading = mFI_CheckPlayerWade(mFI_WADE_NONE) || mFI_CheckPlayerWade(mFI_WADE_END); + int pos_valid; + int bx; + int bz; + + if (not_wading) { + int inform = M_bgm.force.inform; + + if ( + inform == mBGMForce_INFORM_3 || + inform == mBGMForce_INFORM_4 || + inform == mBGMForce_INFORM_5 || + inform == mBGMForce_INFORM_6 + ) { + xyz_t original_pos; + + xyz_t_move_s_xyz(&original_pos, &Common_Get(event_door_data).exit_position); + pos_valid = mFI_Wpos2BlockNum(&bx, &bz, original_pos); + } + else { + pos_valid = mFI_Wpos2BlockNum(&bx, &bz, player->actor_class.world.position); + } + } + else { + pos_valid = mFI_GetNextBlockNum(&bx, &bz); + } + + if (pos_valid) { + attr = mBGMFieldSchedEv_bl_attr_get(bx, bz, data->event_area, data->block_type); + } + } + + return attr; +} + +static void mBGMFieldSchedEv_Info_old_copy(mBGMFieldSchedEv_Info* sched_ev_info) { + if ((sched_ev_info->flag & 1)) { + sched_ev_info->flag |= 2; + } + else { + sched_ev_info->flag &= ~2; + } + + if ((sched_ev_info->flag & 4)) { + sched_ev_info->flag |= 8; + } + else { + sched_ev_info->flag &= ~8; + } + + sched_ev_info->old_attr = sched_ev_info->attr; +} + +static void mBGMFieldSchedEv_Info_ev_now_set_standard(mBGMFieldSchedEv_Info* sched_ev_info, mBGMEventData* data, GAME* game, int ev_start_flag) { + if (ev_start_flag || (sched_ev_info->flag & 1)) { + if (mEv_check_status(data->event_type, mEv_STATUS_ACTIVE)) { + sched_ev_info->flag |= 1; + } + else { + sched_ev_info->flag &= ~1; + } + } +} + +static void mBGMFieldSchedEv_Info_ev_now_set_Silence_0(mBGMFieldSchedEv_Info* sched_ev_info, mBGMEventData* data, GAME* game, int ev_start_flag) { + int event_now = FALSE; + + if ( + (sched_ev_info->flag & 4) && + mBGMClock_over_time_check(&M_bgm.clock, (12 << 22) | (31 << 17) | (23 << 12) | (59 << 6) | (0 << 0), mBGMClock_CHK_MM | mBGMClock_CHK_DD | mBGMClock_CHK_hh | mBGMClock_CHK_mm | mBGMClock_CHK_ss) && + mBGMFieldSchedEv_bl_attr_evdata_get(&mbgm_event_data[mBGMFieldSchedEv_EVENT_SILENCE_0], game) == mBGM_BL_ATTR_ACTIVE + ) { + sched_ev_info->flag |= 0x10; + } + + if ( + mBGMClock_range_time_check( + &M_bgm.clock, + (12 << 22) | (31 << 17) | (23 << 12) | (59 << 6) | (0 << 0), + ( 1 << 22) | ( 1 << 17) | ( 0 << 12) | ( 0 << 6) | (0 << 0), + mBGMClock_CHK_MM | mBGMClock_CHK_DD | mBGMClock_CHK_hh | mBGMClock_CHK_mm | mBGMClock_CHK_ss + ) + ) { + if ((sched_ev_info->flag & 0x10)) { + if (mEv_check_status(mEv_EVENT_NEW_YEARS_EVE_COUNTDOWN, mEv_STATUS_PLAYSOUND)) { + event_now = TRUE; + } + } + else { + event_now = TRUE; + } + } + else { + sched_ev_info->flag &= ~0x10; + } + + if (event_now) { + sched_ev_info->flag |= 1; + } + else { + sched_ev_info->flag &= ~1; + } +} + +static void mBGMFieldSchedEv_Info_ev_now_set_CountDown_1(mBGMFieldSchedEv_Info* sched_ev_info, mBGMEventData* data, GAME* game, int ev_start_flag) { + if ( + mEv_check_status(mEv_EVENT_NEW_YEARS_EVE_COUNTDOWN, mEv_STATUS_ACTIVE) && + mBGMClock_range_time_check( + &M_bgm.clock, + (12 << 22) | (31 << 17) | (23 << 12) | ( 0 << 6) | (0 << 0), + (12 << 22) | (31 << 17) | (23 << 12) | (30 << 6) | (0 << 0), + mBGMClock_CHK_MM | mBGMClock_CHK_DD | mBGMClock_CHK_hh | mBGMClock_CHK_mm | mBGMClock_CHK_ss + ) + ) { + sched_ev_info->flag |= 1; + } + else { + sched_ev_info->flag &= ~1; + } +} + +static void mBGMFieldSchedEv_Info_ev_now_set_CountDown_2(mBGMFieldSchedEv_Info* sched_ev_info, mBGMEventData* data, GAME* game, int ev_start_flag) { + if ( + mEv_check_status(mEv_EVENT_NEW_YEARS_EVE_COUNTDOWN, mEv_STATUS_ACTIVE) && + mBGMClock_range_time_check( + &M_bgm.clock, + (12 << 22) | (31 << 17) | (23 << 12) | (30 << 6) | (0 << 0), + (12 << 22) | (31 << 17) | (23 << 12) | (50 << 6) | (0 << 0), + mBGMClock_CHK_MM | mBGMClock_CHK_DD | mBGMClock_CHK_hh | mBGMClock_CHK_mm | mBGMClock_CHK_ss + ) + ) { + sched_ev_info->flag |= 1; + } + else { + sched_ev_info->flag &= ~1; + } +} + +static void mBGMFieldSchedEv_Info_ev_now_set_CountDown_3(mBGMFieldSchedEv_Info* sched_ev_info, mBGMEventData* data, GAME* game, int ev_start_flag) { + if ( + mEv_check_status(mEv_EVENT_NEW_YEARS_EVE_COUNTDOWN, mEv_STATUS_ACTIVE) && + mBGMClock_range_time_check( + &M_bgm.clock, + (12 << 22) | (31 << 17) | (23 << 12) | (50 << 6) | (0 << 0), + (12 << 22) | (31 << 17) | (23 << 12) | (55 << 6) | (0 << 0), + mBGMClock_CHK_MM | mBGMClock_CHK_DD | mBGMClock_CHK_hh | mBGMClock_CHK_mm | mBGMClock_CHK_ss + ) + ) { + sched_ev_info->flag |= 1; + } + else { + sched_ev_info->flag &= ~1; + } +} + +static void mBGMFieldSchedEv_Info_ev_now_set_CountDown_4(mBGMFieldSchedEv_Info* sched_ev_info, mBGMEventData* data, GAME* game, int ev_start_flag) { + if ( + mEv_check_status(mEv_EVENT_NEW_YEARS_EVE_COUNTDOWN, mEv_STATUS_ACTIVE) && + mBGMClock_range_time_check( + &M_bgm.clock, + (12 << 22) | (31 << 17) | (23 << 12) | (55 << 6) | (0 << 0), + ( 1 << 22) | ( 1 << 17) | ( 0 << 12) | ( 0 << 6) | (0 << 0), + mBGMClock_CHK_MM | mBGMClock_CHK_DD | mBGMClock_CHK_hh | mBGMClock_CHK_mm | mBGMClock_CHK_ss + ) + ) { + sched_ev_info->flag |= 1; + } + else { + sched_ev_info->flag &= ~1; + } +} + +static void mBGMFieldSchedEv_Info_ev_now_set_CountDown_5(mBGMFieldSchedEv_Info* sched_ev_info, mBGMEventData* data, GAME* game, int ev_start_flag) { + int event_now = FALSE; + + if ( + mBGMClock_range_time_check( + &M_bgm.clock, + (1 << 22) | (1 << 17) | (0 << 12) | (0 << 6) | (0 << 0), + (1 << 22) | (1 << 17) | (1 << 12) | (0 << 6) | (0 << 0), + mBGMClock_CHK_MM | mBGMClock_CHK_DD | mBGMClock_CHK_hh | mBGMClock_CHK_mm | mBGMClock_CHK_ss + ) + ) { + if ( + (sched_ev_info->flag & 4) && + mBGMClock_over_time_check( + &M_bgm.clock, + (1 << 22) | (1 << 17) | (0 << 12) | (0 << 6) | (0 << 0), + mBGMClock_CHK_MM | mBGMClock_CHK_DD | mBGMClock_CHK_hh | mBGMClock_CHK_mm | mBGMClock_CHK_ss + ) && + mBGMFieldSchedEv_bl_attr_evdata_get(&mbgm_event_data[mBGMFieldSchedEv_EVENT_COUNTDOWN_5], game) != mBGM_BL_ATTR_INACTIVE + ) { + sched_ev_info->flag |= 0x20; + } + + if ( + (sched_ev_info->flag & 0x20) && + mBGMFieldSchedEv_bl_attr_evdata_get(&mbgm_event_data[mBGMFieldSchedEv_EVENT_COUNTDOWN_5], game) == mBGM_BL_ATTR_INACTIVE + ) { + sched_ev_info->flag &= ~0x20; + } + + if ((sched_ev_info->flag & 0x20) && mEv_check_status(mEv_EVENT_NEW_YEARS_EVE_COUNTDOWN, mEv_STATUS_ACTIVE)) { + event_now = TRUE; + } + } + else { + sched_ev_info->flag &= ~0x20; + } + + if (event_now) { + sched_ev_info->flag |= 1; + } + else { + sched_ev_info->flag &= ~1; + } +} + +static void mBGMFieldSchedEv_Info_ev_now_set_CountDown_6(mBGMFieldSchedEv_Info* sched_ev_info, mBGMEventData* data, GAME* game, int ev_start_flag) { + int event_now = FALSE; + + if ( + mBGMClock_range_time_check( + &M_bgm.clock, + (1 << 22) | (1 << 17) | (0 << 12) | (0 << 6) | (0 << 0), + (1 << 22) | (1 << 17) | (1 << 12) | (0 << 6) | (0 << 0), + mBGMClock_CHK_MM | mBGMClock_CHK_DD | mBGMClock_CHK_hh | mBGMClock_CHK_mm | mBGMClock_CHK_ss + ) + ) { + if ( + (sched_ev_info->flag & 4) && + mBGMClock_over_time_check( + &M_bgm.clock, + (1 << 22) | (1 << 17) | (0 << 12) | (0 << 6) | (0 << 0), + mBGMClock_CHK_MM | mBGMClock_CHK_DD | mBGMClock_CHK_hh | mBGMClock_CHK_mm | mBGMClock_CHK_ss + ) && + mBGMFieldSchedEv_bl_attr_evdata_get(&mbgm_event_data[mBGMFieldSchedEv_EVENT_COUNTDOWN_6], game) != mBGM_BL_ATTR_INACTIVE + ) { + sched_ev_info->flag |= 0x20; + } + + if ( + (sched_ev_info->flag & 0x20) && + mBGMFieldSchedEv_bl_attr_evdata_get(&mbgm_event_data[mBGMFieldSchedEv_EVENT_COUNTDOWN_6], game) == mBGM_BL_ATTR_INACTIVE + ) { + sched_ev_info->flag &= ~0x20; + } + + if ((sched_ev_info->flag & 0x20) == 0 && mEv_check_status(mEv_EVENT_NEW_YEARS_EVE_COUNTDOWN, mEv_STATUS_ACTIVE)) { + event_now = TRUE; + } + } + else { + sched_ev_info->flag &= ~0x20; + } + + if (event_now) { + sched_ev_info->flag |= 1; + } + else { + sched_ev_info->flag &= ~1; + } +} + +static void mBGMFieldSchedEv_Info_ev_now_set_Hotaru(mBGMFieldSchedEv_Info* sched_ev_info, mBGMEventData* data, GAME* game, int ev_start_flag) { + if ( + mBGMClock_range_time_check( + &M_bgm.clock, + (1 << 22) | (1 << 17) | (0 << 12) | (0 << 6) | (0 << 0), + (1 << 22) | (1 << 17) | (1 << 12) | (0 << 6) | (0 << 0), + mBGMClock_CHK_MM | mBGMClock_CHK_DD | mBGMClock_CHK_hh | mBGMClock_CHK_mm | mBGMClock_CHK_ss + ) + ) { + sched_ev_info->flag |= 1; + } + else { + sched_ev_info->flag &= ~1; + } +} + +static void mBGMFieldSchedEv_Info_ev_now_set_NewYear01(mBGMFieldSchedEv_Info* sched_ev_info, mBGMEventData* data, GAME* game, int ev_start_flag) { + if ( + mBGMClock_range_time_check( + &M_bgm.clock, + (1 << 22) | (1 << 17) | ( 1 << 12) | (0 << 6) | (0 << 0), + (1 << 22) | (1 << 17) | (18 << 12) | (0 << 6) | (0 << 0), + mBGMClock_CHK_MM | mBGMClock_CHK_DD | mBGMClock_CHK_hh | mBGMClock_CHK_mm | mBGMClock_CHK_ss + ) + ) { + sched_ev_info->flag |= 1; + } + else { + sched_ev_info->flag &= ~1; + } +} + +static void mBGMFieldSchedEv_Info_ev_now_set_NewYear02(mBGMFieldSchedEv_Info* sched_ev_info, mBGMEventData* data, GAME* game, int ev_start_flag) { + if ( + mBGMClock_range_time_check( + &M_bgm.clock, + (1 << 22) | (1 << 17) | (18 << 12) | (0 << 6) | (0 << 0), + (1 << 22) | (2 << 17) | ( 0 << 12) | (0 << 6) | (0 << 0), + mBGMClock_CHK_MM | mBGMClock_CHK_DD | mBGMClock_CHK_hh | mBGMClock_CHK_mm | mBGMClock_CHK_ss + ) + ) { + sched_ev_info->flag |= 1; + } + else { + sched_ev_info->flag &= ~1; + } +} + +static void mBGMFieldSchedEv_Info_attr_now_set(mBGMFieldSchedEv_Info* sched_ev_info, GAME* game, mBGMEventData* data) { + sched_ev_info->attr = mBGM_BL_ATTR_INACTIVE; + + if ((sched_ev_info->flag & (4 | 1)) == (4 | 1)) { + int attr = mBGMFieldSchedEv_bl_attr_evdata_get(data, game); + + if (attr < mBGM_BL_ATTR_NUM) { + sched_ev_info->attr = attr; + } + } +} + +typedef void (*mBGMFieldSchedEv_INFO_CHK_PROC)(mBGMFieldSchedEv_Info*, mBGMEventData*, GAME*, int); + +static void mBGMFieldSchedEv_info_set(mBGMFieldSchedEv* sched_ev, GAME* game) { + static mBGMFieldSchedEv_INFO_CHK_PROC ev_chk[mBGMFieldSchedEv_EVENT_NUM] = { + &mBGMFieldSchedEv_Info_ev_now_set_Silence_0, + &mBGMFieldSchedEv_Info_ev_now_set_standard, + &mBGMFieldSchedEv_Info_ev_now_set_standard, + &mBGMFieldSchedEv_Info_ev_now_set_standard, + &mBGMFieldSchedEv_Info_ev_now_set_standard, + &mBGMFieldSchedEv_Info_ev_now_set_standard, + &mBGMFieldSchedEv_Info_ev_now_set_standard, + &mBGMFieldSchedEv_Info_ev_now_set_standard, + &mBGMFieldSchedEv_Info_ev_now_set_standard, + &mBGMFieldSchedEv_Info_ev_now_set_standard, + &mBGMFieldSchedEv_Info_ev_now_set_standard, + &mBGMFieldSchedEv_Info_ev_now_set_standard, + &mBGMFieldSchedEv_Info_ev_now_set_CountDown_1, + &mBGMFieldSchedEv_Info_ev_now_set_CountDown_2, + &mBGMFieldSchedEv_Info_ev_now_set_CountDown_3, + &mBGMFieldSchedEv_Info_ev_now_set_CountDown_4, + &mBGMFieldSchedEv_Info_ev_now_set_CountDown_5, + &mBGMFieldSchedEv_Info_ev_now_set_CountDown_6, + &mBGMFieldSchedEv_Info_ev_now_set_standard, + &mBGMFieldSchedEv_Info_ev_now_set_Hotaru, + &mBGMFieldSchedEv_Info_ev_now_set_NewYear01, + &mBGMFieldSchedEv_Info_ev_now_set_NewYear02, + &mBGMFieldSchedEv_Info_ev_now_set_standard, + &mBGMFieldSchedEv_Info_ev_now_set_standard + }; + + mBGMFieldSchedEv_Info* info; + mBGMEventData* data; + int i; + const int event_active_on_edge = mEv_check_status_edge(mEv_STATUS_ACTIVE); + const int valid_field = mFI_CheckFieldData() && mFI_GET_TYPE(mFI_GetFieldId()) == mFI_FIELD_FG; + + info = sched_ev->info; + data = mbgm_event_data; + + for (i = 0; i < ARRAY_COUNT(mbgm_event_data); i++, info++, data++) { + mBGMFieldSchedEv_Info_old_copy(info); + info->flag &= ~4; + + if (valid_field) { + info->flag |= 4; + } + + (*ev_chk[i])(info, data, game, event_active_on_edge); + mBGMFieldSchedEv_Info_attr_now_set(info, game, data); + } +} + +static void mBGMPsComp_delete_ps_fieldSchedEv(u8 bgm_num, u16 stop_type); +static void mBGMPsComp_search_cf_set_field(u8 bgm_num, int kategorie); + +static void mBGMFieldSchedEv_Info_ps_delete(mBGMFieldSchedEv_Info* sched_ev_info, mBGMEventData* data, int flag) { + mBGMPsComp_delete_ps_fieldSchedEv(data->bgm_num, 0x168); + + if (flag && data->bgm_num == mBGMPsComp_execute_bgm_num_get()) { + mBGMPsComp_search_cf_set_field(data->bgm_num, 10); + } +} + +static void mBGMPsComp_make_ps_fieldSchedEv(u8 bgm_num, int update_volume_move_ctr, int update_volume_level, int cf_flag, u16 stop_type, u8 priority); + +static void mBGMFieldSchedEv_Info_ps_make(mBGMFieldSchedEv_Info* sched_ev_info, mBGMEventData* data, int priority) { + int update_volume_move_ctr = sched_ev_info->attr != mBGM_BL_ATTR_INACTIVE && sched_ev_info->old_attr == mBGM_BL_ATTR_INACTIVE; + int update_volume_level = mbgm_pattern_data[data->event_area][sched_ev_info->attr] == 1; + int crossfade = mBGMPsComp_execute_bgm_num_get() < 0 ? FALSE : TRUE; + u16 stop_type = priority == 0 ? (u16)0xA8C : (u16)0x168; + + mBGMPsComp_make_ps_fieldSchedEv(data->bgm_num, update_volume_move_ctr, update_volume_level, crossfade, stop_type, priority); +} + +static void mBGMPsComp_volume_change_fieldSchedEv(u8 bgm_num, int update_volume_move_ctr, int update_volume_level); + +static void mBGMFieldSchedEv_Info_ps_volume_change(mBGMFieldSchedEv_Info* sched_ev_info, mBGMEventData* data) { + int flag = mbgm_pattern_data[data->event_area][sched_ev_info->attr] == 1; + + mBGMPsComp_volume_change_fieldSchedEv(data->bgm_num, TRUE, flag); +} + +static void mBGMFieldSchedEv_ps_compose(mBGMFieldSchedEv* sched_ev, GAME* game) { + mBGMFieldSchedEv_Info* info = sched_ev->info; + mBGMEventData* data = mbgm_event_data; + int i; + int flag = TRUE; + int now_flag; + int old_flag; + + for (i = 0; i < ARRAY_COUNT(mbgm_event_data); i++) { + now_flag = (info->flag & (4 | 1)) == (4 | 1) && info->attr != mBGM_BL_ATTR_INACTIVE; + old_flag = (info->flag & (8 | 2)) == (8 | 2) && info->old_attr != mBGM_BL_ATTR_INACTIVE; + + if (!now_flag && old_flag) { + mBGMFieldSchedEv_Info_ps_delete(info, data, flag); + } + + if (now_flag && !old_flag) { + mBGMFieldSchedEv_Info_ps_make(info, data, i); + } + + if (now_flag && old_flag) { + int now_vol = mbgm_pattern_data[data->event_area][info->attr]; + int old_vol = mbgm_pattern_data[data->event_area][info->old_attr]; + + if (now_vol != old_vol && now_vol != 0 && old_vol != 0 && data->bgm_num != 127) { + mBGMFieldSchedEv_Info_ps_volume_change(info, data); + } + } + + if (flag && old_flag) { + flag = FALSE; + } + + info++; + data++; + } +} + +static void mBGMFieldSchedEv_sp_flag(mBGMFieldSchedEv* sched_ev) { + mBGMFieldSchedEv_Info* info0 = &sched_ev->info[mBGMFieldSchedEv_EVENT_COUNTDOWN_5]; + mBGMFieldSchedEv_Info* info1 = &sched_ev->info[mBGMFieldSchedEv_EVENT_COUNTDOWN_6]; + + if ( + ( + ((info0->flag & (4 | 1)) == (4 | 1) && info0->attr != mBGM_BL_ATTR_INACTIVE) || + ((info1->flag & (4 | 1)) == (4 | 1) && info1->attr != mBGM_BL_ATTR_INACTIVE) + ) && + mBGMClock_range_time_check( + &M_bgm.clock, + (1 << 22) | (1 << 17) | (0 << 12) | (0 << 6) | (0 << 0), + (1 << 22) | (1 << 17) | (0 << 12) | (1 << 6) | (0 << 0), + mBGMClock_CHK_MM | mBGMClock_CHK_DD | mBGMClock_CHK_hh | mBGMClock_CHK_mm | mBGMClock_CHK_ss + ) + ) { + mBGMTime_new_year_ev_flag_set(); + } + else { + mBGMTime_new_year_ev_flag_clr(); + } +} + +static void mBGMFieldSchedEv_move(mBGMFieldSchedEv* sched_ev, GAME* game) { + mBGMFieldSchedEv_info_set(sched_ev, game); + mBGMFieldSchedEv_ps_compose(sched_ev, game); + mBGMFieldSchedEv_sp_flag(sched_ev); +} + +static void mBGMFieldSchedEv_ct(mBGMFieldSchedEv* sched_ev) { + int i; + + bzero(sched_ev, sizeof(mBGMFieldSchedEv)); + for (i = 0; i < ARRAY_COUNT(sched_ev->info); i++) { + sched_ev->info[i].old_attr = mBGM_BL_ATTR_INACTIVE; + sched_ev->info[i].attr = mBGM_BL_ATTR_INACTIVE; + } +} + +/* mBGMFieldNorm */ + +static u8 mBGMFieldNorm_bgm_num_get(int hour) { + static u8 bgm_table[24] = { + 1, 2, 3, 4, + 5, 6, 7, 8, + 9, 10, 11, 12, + 13, 14, 15, 16, + 17, 18, 19, 20, + 21, 22, 23, 24 + }; + + return bgm_table[hour]; +} + +static void mBGMFieldNorm_elem_set(mBGMFieldNorm* norm) { + int hour = Common_Get(time.rtc_time.hour) % 24; + + mBGMElem_default_set(&norm->elem); + norm->elem.bgm_num = mBGMFieldNorm_bgm_num_get(hour); +} + +static void mBGMPsComp_make_ps_fieldNorm(u8 bgm_num, u16 stop_type); + +static void mBGMFieldNorm_make_bgm(mBGMFieldNorm* norm, GAME* game) { + if (norm->elem.bgm_num == 127) { + mBGMFieldNorm_elem_set(norm); + mBGMPsComp_make_ps_fieldNorm(norm->elem.bgm_num, 0x168); + } +} + +static void mBGMPsComp_delete_ps_fieldNorm(u8 bgm_num, u16 stop_type); + +static void mBGMFieldNorm_delete_bgm(mBGMFieldNorm* norm) { + if (norm->elem.bgm_num != 127) { + mBGMPsComp_delete_ps_fieldNorm(norm->elem.bgm_num, norm->elem.stop_type0); + norm->elem.bgm_num = 127; + } +} + +static void mBGMFieldNorm_move(mBGMFieldNorm* norm, GAME* game) { + if ( + mBGMClock_over_time_check(&M_bgm.clock, 0, mBGMClock_CHK_mm | mBGMClock_CHK_ss) && + mFI_CheckFieldData() && + mFI_GET_TYPE(mFI_GetFieldId()) == mFI_FIELD_FG + ) { + norm->delete_flag = TRUE; + norm->make_flag = TRUE; + } + + if (norm->delete_flag) { + mBGMFieldNorm_delete_bgm(norm); + } + + if (norm->make_flag) { + mBGMFieldNorm_make_bgm(norm, game); + } + + norm->make_flag = FALSE; + norm->delete_flag = FALSE; +} + +static void mBGMFieldNorm_make_req() { + M_bgm.field_norm.make_flag = TRUE; +} + +static void mBGMFieldNorm_delete_req() { + M_bgm.field_norm.delete_flag = TRUE; +} + +static void mBGMFieldNorm_ct(mBGMFieldNorm* norm) { + bzero(norm, sizeof(mBGMFieldNorm)); + mBGMElem_default_set(&norm->elem); +} + +/* mBGMPs[Comp] */ + +static void mBGMPs_counter_dec(mBGMPs* ps) { + if (ps->counter > 0) { + ps->counter--; + + if (ps->counter == 0) { + ps->cf_flags |= mBGMPs_FLAG_REMOVE; + } + } +} + +static void mBGMPsComp_ps_remove(mBGMPsComp* ps_comp, int remove_pos) { + if (remove_pos >= 0 && remove_pos < mBGM_BGMPs_NUM) { + + if (remove_pos < ps_comp->ps_num && ps_comp->ps_num > 0) { + int max = ps_comp->ps_num - 1; + int i; + + for (i = remove_pos; i < max; i++) { + ps_comp->ps[i] = ps_comp->ps[i + 1]; + } + + bzero(&ps_comp->ps[max], sizeof(mBGMPs)); + ps_comp->ps_num = max; + } + } +} + +static int mBGMPsComp_search_insert_pos_kategorie(mBGMPsComp* ps_comp, int kategorie, u8 priority) { + mBGMPs* ps = ps_comp->ps; + int max = ps_comp->ps_num; + int i; + int res; + + if (max < mBGM_BGMPs_NUM) { + res = max; + for (i = 0; i < max; i++, ps++) { + if ((kategorie == ps->kategorie && priority < ps->priority) || kategorie < ps->kategorie) { + res = i; + break; + } + } + } + else { + res = -1; + } + + return res; +} + +static int mBGMPsComp_search_pos_kategorie_bgm_num(mBGMPsComp* ps_comp, int kategorie, u8 bgm_num, int counter_flag, int del_pass) { + int kategorie_valid = kategorie < mBGM_KATEGORIE_NUM; + int bgm_is_reset = bgm_num != 127; + int res = -1; + u8 delete_mask = del_pass == 0; + + if (kategorie_valid || bgm_is_reset) { + mBGMPs* ps = ps_comp->ps; + int i = 0; + int max = ps_comp->ps_num; + + for (i; i < max; i++, ps++) { + if ( + (!kategorie_valid || ps->kategorie == kategorie) && + (!bgm_is_reset || ps->elem.bgm_num == bgm_num) && + (counter_flag == FALSE || (ps->counter < 0 && (ps->cf_flags & mBGMPs_FLAG_FADEOUT) == 0)) && + ((ps->cf_flags & delete_mask) == 0) + ) { + res = i; + break; + } + } + } + + return res; +} + +static void mBGMPsComp_shift_behind(mBGMPsComp* ps_comp, int shift_idx) { + if (ps_comp->ps_num != 0) { + int i; + + for (i = ps_comp->ps_num - 1; i >= shift_idx; i--) { + bcopy(&ps_comp->ps[i], &ps_comp->ps[i + 1], sizeof(mBGMPs)); + } + } + + bzero(&ps_comp->ps[shift_idx], sizeof(mBGMPs)); + ps_comp->ps_num++; +} + +static void mBGMPsComp_all_ps_bitclr(mBGMPsComp* ps_comp, u8 bits) { + mBGMPs* ps = ps_comp->ps; + int max = ps_comp->ps_num; + int i; + + for (i = 0; i < max; i++, ps++) { + ps->cf_flags &= ~bits; + } +} + +static int mBGMPsComp_execute_ps_pos_get(mBGMPsComp* ps_comp) { + mBGMPs* ps = ps_comp->ps; + int max = ps_comp->ps_num; + int i; + int idx = -1; + + for (i = 0; i < max; i++, ps++) { + if ((ps->cf_flags & mBGMPs_FLAG_EXECUTE)) { + idx = i; + break; + } + } + + return idx; +} + +static mBGMPs* mBGMPsComp_high_ps_not_delete(mBGMPsComp* ps_comp, int max_pos) { + mBGMPs* ps = ps_comp->ps; + mBGMPs* high_ps = NULL; + int i; + + for (i = 0; i < max_pos; i++, ps++) { + if ((ps->cf_flags & mBGMPs_FLAG_REMOVE) == 0) { + high_ps = ps; + break; + } + } + + return high_ps; +} + +static void mBGMPsComp_main_req_stop(mBGMPsComp* ps_comp) { + mBGMPs* ps = ps_comp->ps; + int execute_pos = mBGMPsComp_execute_ps_pos_get(ps_comp); + + if (execute_pos >= 0) { + ps += execute_pos; + + if ((ps->cf_flags & mBGMPs_FLAG_SILENT) == 0) { + if (execute_pos > 0) { + mBGMPs* high_ps = mBGMPsComp_high_ps_not_delete(ps_comp, execute_pos); + + if (high_ps != NULL) { + ps_comp->stop.req_flag = TRUE; + ps_comp->stop.type = high_ps->elem.stop_type1; + return; + } + } + + if ((ps->cf_flags & mBGMPs_FLAG_REMOVE) && (ps->cf_flags & mBGMPs_FLAG_LOST) == 0) { + ps_comp->stop.req_flag = TRUE; + ps_comp->stop.type = ps->elem.stop_type0; + } + } + } +} + +static void mBGMPsComp_main_remove(mBGMPsComp* ps_comp) { + mBGMPs* ps; + int i; + + for (i = ps_comp->ps_num - 1, ps = &ps_comp->ps[i]; i >= 0; i--, ps--) { + if ((ps->cf_flags & mBGMPs_FLAG_REMOVE)) { + ps->cf_flags &= ~mBGMPs_FLAG_REMOVE; + mBGMPsComp_ps_remove(ps_comp, i); + } + } +} + +static void mBGMPsComp_main_req_start(mBGMPsComp* ps_comp) { + if (ps_comp->ps_num > 0) { + if ((ps_comp->ps[0].cf_flags & mBGMPs_FLAG_EXECUTE) == 0) { + if ((ps_comp->ps[0].cf_flags & mBGMPs_FLAG_SILENT) == 0) { + ps_comp->start.req_flag = TRUE; + ps_comp->start.flags = (ps_comp->ps[0].cf_flags >> 3) & 1; // crossfade (mBGMPs_FLAG_CROSSFADE) + ps_comp->start.bgm_num = ps_comp->ps[0].elem.bgm_num; + + if (mBGM_check_MD(ps_comp->ps[0].elem.bgm_num) == FALSE) { + ps_comp->ps[0].cf_flags |= mBGMPs_FLAG_UPDATE_VOLUME; + } + } + + mBGMPsComp_all_ps_bitclr(ps_comp, mBGMPs_FLAG_EXECUTE); + ps_comp->ps[0].cf_flags |= mBGMPs_FLAG_EXECUTE; + } + + mBGMPsComp_all_ps_bitclr(ps_comp, mBGMPs_FLAG_CROSSFADE); + } +} + +static void mBGMPsComp_main_req_pause(mBGMPsComp* ps_comp) { + if (ps_comp->pause_state == 1 || ps_comp->pause_state == 3) { + ps_comp->pause.mode = 1; + ps_comp->pause.req_flag = TRUE; + } + else if (ps_comp->pause_state == 2) { + ps_comp->pause.mode = 2; + ps_comp->pause.req_flag = TRUE; + } + else if (ps_comp->pause_state == 5) { + ps_comp->pause.mode = 0; + ps_comp->pause.req_flag = TRUE; + } +} + +static void mBGMPsComp_main_req_md(mBGMPsComp* ps_comp) { + if (ps_comp->md.move_flag) { + ps_comp->md.req_flag = TRUE; + } +} + +static void mBGMPsComp_main_md_move(mBGMPsComp* ps_comp) { + if (ps_comp->md.delete_flag) { + ps_comp->md.move_flag = FALSE; + ps_comp->md.delete_flag = FALSE; + } + + if (ps_comp->md.make_flag) { + ps_comp->md.move_flag = TRUE; + ps_comp->md.make_flag = FALSE; + } +} + +static void mBGMPsComp_main_req_volume_ps(mBGMPsComp* ps_comp) { + if (ps_comp->ps_num > 0) { + if ((ps_comp->ps[0].cf_flags & mBGMPs_FLAG_UPDATE_VOLUME)) { + if ((ps_comp->ps[0].cf_flags & mBGMPs_FLAG_UPDATE_VOLUME_MOVE_CTR)) { + ps_comp->volume.ps_volume_move_ctr = 90; + } + else { + ps_comp->volume.ps_volume_move_ctr = 0; + } + + if ((ps_comp->ps[0].cf_flags & mBGMPs_FLAG_UPDATE_VOLUME_LEVEL)) { + ps_comp->volume.ps_volume = 0.5f; + } + else { + ps_comp->volume.ps_volume = 1.0f; + } + + ps_comp->volume.ps_req_flag = TRUE; + } + + mBGMPsComp_all_ps_bitclr(ps_comp, mBGMPs_FLAG_UPDATE_VOLUME_MOVE_CTR | mBGMPs_FLAG_UPDATE_VOLUME); + } + + if (mBGMPsComp_execute_bgm_num_get() < 0) { + ps_comp->volume.ps_volume = -1.0f; + } +} + +static void mBGMPsComp_main_req_volume_fishing(mBGMPsComp* ps_comp) { + if (ps_comp->fishing_state == 1) { + ps_comp->fishing_state = 2; + ps_comp->volume.fishing_volume = 0.6f; + ps_comp->volume.fishing_volume_move_ctr = 300; + ps_comp->volume.fishing_req_flag = TRUE; + } + else if (ps_comp->fishing_state == 3) { + ps_comp->fishing_state = 0; + ps_comp->volume.fishing_volume = -1.0f; + ps_comp->volume.fishing_volume_move_ctr = 35; + + if (ps_comp->ps_num <= 0 || mBGM_check_MD(ps_comp->ps[0].elem.bgm_num) == FALSE) { + ps_comp->volume.fishing_req_flag = TRUE; + } + } +} + +static void mBGMPsComp_main_req_volume_collect_insects(mBGMPsComp* ps_comp) { + if (ps_comp->collect_insects_state == 1) { + ps_comp->collect_insects_state = 2; + ps_comp->volume.collect_insects_volume = 0.65f; + ps_comp->volume.collect_insects_volume_move_ctr = 100; + ps_comp->volume.collect_insects_req_flag = TRUE; + } + else if (ps_comp->collect_insects_state == 3) { + ps_comp->collect_insects_state = 0; + ps_comp->volume.collect_insects_volume = -1.0f; + ps_comp->volume.collect_insects_volume_move_ctr = 17; + + if (ps_comp->ps_num <= 0 || mBGM_check_MD(ps_comp->ps[0].elem.bgm_num) == FALSE) { + ps_comp->volume.collect_insects_req_flag = TRUE; + } + } +} + +static void mBGMPsComp_main_req_volume_talk(mBGMPsComp* ps_comp) { + if (ps_comp->talk_state == 1) { + ps_comp->talk_state = 2; + ps_comp->volume.talk_volume = 0.7f; + ps_comp->volume.talk_req_flag = TRUE; + } + else if (ps_comp->talk_state == 3) { + ps_comp->talk_state = 0; + ps_comp->volume.talk_volume = -1.0f; + + if (ps_comp->ps_num <= 0 || mBGM_check_MD(ps_comp->ps[0].elem.bgm_num) == FALSE) { + ps_comp->volume.talk_req_flag = TRUE; + } + } +} + +static void mBGMPsComp_main_req_volume_boat(mBGMPsComp* ps_comp) { + if (ps_comp->boat_state == 1) { + ps_comp->boat_state = 2; + ps_comp->volume.boat_volume = 0.7f; + ps_comp->volume.boat_req_flag = TRUE; + } + else if (ps_comp->boat_state == 3) { + ps_comp->boat_state = 0; + ps_comp->volume.boat_volume = -1.0f; + + if (ps_comp->ps_num <= 0 || mBGM_check_MD(ps_comp->ps[0].elem.bgm_num) == FALSE) { + ps_comp->volume.boat_req_flag = TRUE; + } + } +} + +static void mBGMPsComp_main_req_volume_pause(mBGMPsComp* ps_comp) { + if (ps_comp->pause_state == 1) { + ps_comp->pause_state = 4; + ps_comp->volume.pause_volume = 0.5f; + ps_comp->volume.pause_volume_move_ctr = 2; + ps_comp->volume.pause_req_flag = TRUE; + } + else if (ps_comp->pause_state == 2) { + ps_comp->pause_state = 4; + ps_comp->volume.pause_volume = 0.0f; + ps_comp->volume.pause_volume_move_ctr = 2; + ps_comp->volume.pause_req_flag = TRUE; + } + else if (ps_comp->pause_state == 3) { + ps_comp->pause_state = 4; + ps_comp->volume.pause_volume = 0.5f; + ps_comp->volume.pause_volume_move_ctr = 2; + ps_comp->volume.pause_req_flag = TRUE; + } + else if (ps_comp->pause_state == 5) { + ps_comp->pause_state = 0; + ps_comp->volume.pause_volume = -1.0f; + ps_comp->volume.pause_volume_move_ctr = 2; + + if (ps_comp->ps_num <= 0 || mBGM_check_MD(ps_comp->ps[0].elem.bgm_num) == FALSE) { + ps_comp->volume.pause_req_flag = TRUE; + } + } +} + +static void mBGMPsComp_main_req_volume(mBGMPsComp* ps_comp) { + f32 t_ps_vol; + f32 t_talk_vol; + f32 t_pause_vol; + f32 t_collect_insects_vol; + f32 t_fishing_vol; + f32 t_boat_vol; + f32 final_vol; + u16 final_vol_move_ctr; + mBGMPs* ps = &ps_comp->ps[0]; + int ignore_talk = ps_comp->ps_num > 0 ? mBGM_check_ignore_talk_volume(ps->elem.bgm_num) : FALSE; + int ignore_collect_insects = ps_comp->ps_num > 0 ? mBGM_check_ignore_collect_insects_volume(ps->elem.bgm_num) : FALSE; + + mBGMPsComp_main_req_volume_ps(ps_comp); + mBGMPsComp_main_req_volume_fishing(ps_comp); + mBGMPsComp_main_req_volume_collect_insects(ps_comp); + mBGMPsComp_main_req_volume_talk(ps_comp); + mBGMPsComp_main_req_volume_boat(ps_comp); + mBGMPsComp_main_req_volume_pause(ps_comp); + + t_ps_vol = ps_comp->volume.ps_volume; + if (t_ps_vol < 0.0f) { + t_fishing_vol = -1.0f; + t_collect_insects_vol = -1.0f; + t_talk_vol = -1.0f; + t_boat_vol = -1.0f; + t_pause_vol = -1.0f; + } + else { + t_fishing_vol = (ps_comp->volume.fishing_volume < 0.0f || ps_comp->volume.fishing_volume > t_ps_vol || ignore_collect_insects) ? t_ps_vol : ps_comp->volume.fishing_volume; + t_collect_insects_vol = (ps_comp->volume.collect_insects_volume < 0.0f || ps_comp->volume.collect_insects_volume > t_fishing_vol || ignore_collect_insects) ? t_fishing_vol : ps_comp->volume.collect_insects_volume; + t_talk_vol = (ps_comp->volume.talk_volume < 0.0f || ps_comp->volume.talk_volume > t_collect_insects_vol || ignore_talk) ? t_collect_insects_vol : ps_comp->volume.talk_volume; + t_boat_vol = (ps_comp->volume.boat_volume < 0.0f || ps_comp->volume.boat_volume > t_talk_vol) ? t_talk_vol : ps_comp->volume.boat_volume; + t_pause_vol = (ps_comp->volume.pause_volume < 0.0f || ps_comp->volume.pause_volume > t_boat_vol) ? t_boat_vol : ps_comp->volume.pause_volume; + } + + final_vol = -1.0f; + final_vol_move_ctr = 0; + + if (ps_comp->volume.ps_req_flag) { + final_vol = t_ps_vol; + final_vol_move_ctr = ps_comp->volume.ps_volume_move_ctr; + } + + if (ps_comp->volume.fishing_req_flag && !ignore_collect_insects) { + final_vol = t_fishing_vol; + final_vol_move_ctr = ps_comp->volume.fishing_volume_move_ctr; + } + + if (ps_comp->volume.collect_insects_req_flag && !ignore_collect_insects) { + final_vol = t_collect_insects_vol; + final_vol_move_ctr = ps_comp->volume.collect_insects_volume_move_ctr; + } + + if (ps_comp->volume.talk_req_flag && !ignore_talk) { + final_vol = t_talk_vol; + final_vol_move_ctr = 30; + } + + if (ps_comp->volume.boat_req_flag) { + final_vol = t_boat_vol; + final_vol_move_ctr = 30; + } + + if (ps_comp->volume.pause_req_flag) { + final_vol = t_pause_vol; + final_vol_move_ctr = ps_comp->volume.pause_volume_move_ctr; + } + + if (ps_comp->pause_state == 4) { + if ((final_vol < 0.0f) == FALSE) { + final_vol = t_pause_vol; + } + } + else if (ps_comp->boat_state == 2) { + if ((final_vol < 0.0f) == FALSE) { + final_vol = t_boat_vol; + } + } + else if (ps_comp->talk_state == 2) { + if ((final_vol < 0.0f) == FALSE) { + final_vol = t_talk_vol; + } + } + else if (ps_comp->collect_insects_state == 2) { + if ((final_vol < 0.0f) == FALSE) { + final_vol = t_collect_insects_vol; + } + } + else if (ps_comp->fishing_state == 2) { + if ((final_vol < 0.0f) == FALSE) { + final_vol = t_fishing_vol; + } + } + + if ((final_vol < 0.0f) == FALSE) { + ps_comp->volume.main_volume = final_vol; + ps_comp->volume.main_volume_move_ctr = final_vol_move_ctr; + ps_comp->volume.main_req_flag = TRUE; + } + + ps_comp->volume.ps_req_flag = FALSE; + ps_comp->volume.fishing_req_flag = FALSE; + ps_comp->volume.collect_insects_req_flag = FALSE; + ps_comp->volume.talk_req_flag = FALSE; + ps_comp->volume.boat_req_flag = FALSE; + ps_comp->volume.pause_req_flag = FALSE; +} + +static void mBGMPsComp_MDPlayerPos_main_inform_sound(mBGMPsComp_MDPlayerPos* md) { + if (md->req_flag) { + sAdo_MDPlayerPos(&md->pos, md->angle, md->md_type_no, md->ongen_no); + md->req_flag = FALSE; + } +} + +static void mBGMPsComp_arm_delete(); + +static void mBGMPsComp_Arm_main_inform_sound(mBGMPsComp_Arm* arm) { + if (arm->req_flag) { + if (mBGMPsComp_execute_bgm_num_get() == 43) { + sAdos_TTKK_ARM(arm->arm_state); + + if (arm->arm_state == 0) { + mBGMPsComp_arm_delete(); + } + } + else { + mBGMPsComp_arm_delete(); + } + } +} + +static void mBGMPsComp_Stop_main_inform_sound(mBGMPsComp_Stop* stop) { + if (stop->req_flag) { + sAdo_BgmStop(stop->type); + stop->req_flag = FALSE; + } +} + +static void mBGMPsComp_arm_make(u8 state); + +static void mBGMPsComp_Start_main_inform_sound(mBGMPsComp_Start* start) { + if (start->req_flag) { + if (start->flags != 0) { + sAdo_BgmCrossfadeStart(start->bgm_num); + } + else { + sAdo_BgmStart(start->bgm_num); + + if (start->bgm_num == 43) { + if (Save_Get(scene_no) == SCENE_PLAYERSELECT_2) { + mBGMPsComp_arm_make(1); + } + else { + mBGMPsComp_arm_make(0); + } + } + } + + start->req_flag = FALSE; + } +} + +static void mBGMPsComp_Volume_main_inform_sound(mBGMPsComp_Volume* volume) { + if (volume->main_req_flag) { + sAdo_BGMVolume(volume->main_volume, volume->main_volume_move_ctr); + volume->main_req_flag = FALSE; + } +} + +static void mBGMPsComp_Pause_main_inform_sound(mBGMPsComp_Pause* pause) { + if (pause->req_flag) { + sAdo_Pause(pause->mode); + pause->req_flag = FALSE; + } +} + +static void mBGMPsComp_Museum_main_inform_sound(mBGMPsComp_Museum* museum) { + if (museum->req_flag) { + museum->req_flag--; + + if (museum->req_flag == 0) { + sAdo_Museum(museum->type); + } + } +} + +static void mBGMPsComp_main_inform_sound(mBGMPsComp* ps_comp) { + mBGMPsComp_MDPlayerPos_main_inform_sound(&ps_comp->md); + mBGMPsComp_Arm_main_inform_sound(&ps_comp->arm); + mBGMPsComp_Stop_main_inform_sound(&ps_comp->stop); + mBGMPsComp_Start_main_inform_sound(&ps_comp->start); + mBGMPsComp_Pause_main_inform_sound(&ps_comp->pause); + mBGMPsComp_Volume_main_inform_sound(&ps_comp->volume); + mBGMPsComp_Museum_main_inform_sound(&ps_comp->museum); +} + +static void mBGMPsComp_main_counter_dec(mBGMPsComp* ps_comp) { + mBGMPs* ps = ps_comp->ps; + int i; + int max = ps_comp->ps_num; + + for (i = 0; i < max; i++, ps++) { + mBGMPs_counter_dec(ps); + } +} + +static void mBGMPsComp_main_fo_check(mBGMPsComp* ps_comp) { + mBGMPs* ps = ps_comp->ps; + int i; + int max = ps_comp->ps_num; + + for (i = 0; i < max; i++, ps++) { + if (ps->cf_flags & mBGMPs_FLAG_FADEOUT) { + int execute_pos = mBGMPsComp_execute_ps_pos_get(ps_comp); + + if ( + (execute_pos >= i || execute_pos < 0) || + (ps_comp->ps[execute_pos].elem.bgm_num == 127) || + (ps_comp->ps[execute_pos].cf_flags & mBGMPs_FLAG_SILENT) + ) { + if (sAdo_BgmFadeoutCheck() == FALSE) { + continue; /* don't clear the fadeout flag */ + } + } + + ps->cf_flags &= ~mBGMPs_FLAG_FADEOUT; + ps->cf_flags |= mBGMPs_FLAG_REMOVE; + } + } +} + +static void mBGMPsComp_main_lost(mBGMPsComp* ps_comp) { + mBGMPs* ps = ps_comp->ps; + int i; + int max = ps_comp->ps_num; + + for (i = 0; i < max; i++, ps++) { + if ((ps->cf_flags & mBGMPs_FLAG_LOST)) { + ps->cf_flags |= mBGMPs_FLAG_REMOVE; + } + } +} + +static int mBGMPsComp_make_ps(mBGMPsComp* ps_comp, mBGMElem* elem, int kategorie, s16 counter, u16 cf_flags, u8 priority) { + int pos = mBGMPsComp_search_insert_pos_kategorie(ps_comp, kategorie, priority); + + if (pos >= 0) { + mBGMPs* dst_ps = &ps_comp->ps[pos]; + + mBGMPsComp_shift_behind(ps_comp, pos); + bcopy(elem, &dst_ps->elem, sizeof(mBGMElem)); + dst_ps->kategorie = kategorie; + dst_ps->counter = counter; + dst_ps->cf_flags = cf_flags; + dst_ps->priority = priority; + } + + return pos; +} + +static void _mBGMPsComp_make_ps_fanfare(u8 bgm_num, u16 stop_type) { + mBGMElem elem; + + mBGMElem_default_set(&elem); + elem.bgm_num = bgm_num; + elem.stop_type1 = stop_type; + mBGMPsComp_make_ps(&M_bgm.ps_comp, &elem, mBGM_KATEGORIE_FANFARE, -1, 0, 0xFF); +} + +extern void mBGMPsComp_make_ps_fanfare(u8 bgm_num, u16 stop_type) { + _mBGMPsComp_make_ps_fanfare(bgm_num, stop_type); +} + +static void _mBGMPsComp_make_ps_lost_fanfare(u8 bgm_num, u16 stop_type) { + mBGMElem elem; + + mBGMElem_default_set(&elem); + elem.bgm_num = bgm_num; + elem.stop_type1 = stop_type; + mBGMPsComp_make_ps(&M_bgm.ps_comp, &elem, mBGM_KATEGORIE_FANFARE, -1, mBGMPs_FLAG_LOST, 0xFF); +} + +extern void mBGMPsComp_make_ps_lost_fanfare(u8 bgm_num, u16 stop_type) { + _mBGMPsComp_make_ps_lost_fanfare(bgm_num, stop_type); +} + +static void _mBGMPsComp_make_ps_wipe(u16 stop_type) { + mBGMForce* force = &M_bgm.force; + mBGMPsComp* ps_comp = &M_bgm.ps_comp; + mBGMElem elem; + + if (mBGMForce_wipe_ps_make_permit(force) && mBGMPsComp_search_pos_kategorie_bgm_num(ps_comp, mBGM_KATEGORIE_WIPE, 127, FALSE, FALSE) < 0) { + mBGMElem_default_set(&elem); + elem.stop_type1 = stop_type; + mBGMPsComp_make_ps(&M_bgm.ps_comp, &elem, mBGM_KATEGORIE_WIPE, -1, mBGMPs_FLAG_SILENT, 0xFF); + } +} + +extern void mBGMPsComp_make_ps_wipe(u16 stop_type) { + _mBGMPsComp_make_ps_wipe(stop_type); +} + +static void _mBGMPsComp_make_ps_quiet(u16 stop_type) { + mBGMElem elem; + + mBGMElem_default_set(&elem); + elem.stop_type1 = stop_type; + mBGMPsComp_make_ps(&M_bgm.ps_comp, &elem, mBGM_KATEGORIE_QUIET, -1, mBGMPs_FLAG_SILENT, 0xFF); +} + +extern void mBGMPsComp_make_ps_quiet(u16 stop_type) { + _mBGMPsComp_make_ps_quiet(stop_type); +} + +static void _mBGMPsComp_make_ps_co_quiet(u16 stop_type, s16 counter) { + mBGMElem elem; + + mBGMElem_default_set(&elem); + elem.stop_type1 = stop_type; + mBGMPsComp_make_ps(&M_bgm.ps_comp, &elem, mBGM_KATEGORIE_QUIET, counter, mBGMPs_FLAG_SILENT, 0xFF); +} + +extern void mBGMPsComp_make_ps_co_quiet(u16 stop_type, s16 counter) { + _mBGMPsComp_make_ps_co_quiet(stop_type, counter); +} + +static void _mBGMPsComp_make_ps_fc_quiet(u16 stop_type) { + mBGMElem elem; + + mBGMElem_default_set(&elem); + elem.stop_type1 = stop_type; + mBGMPsComp_make_ps(&M_bgm.ps_comp, &elem, mBGM_KATEGORIE_QUIET, -1, mBGMPs_FLAG_SILENT | mBGMPs_FLAG_FADEOUT, 0xFF); +} + +extern void mBGMPsComp_make_ps_fc_quiet(u16 stop_type) { + _mBGMPsComp_make_ps_fc_quiet(stop_type); +} + +static void _mBGMPsComp_make_ps_demo(u8 bgm_num, u16 stop_type) { + mBGMElem elem; + + mBGMElem_default_set(&elem); + elem.bgm_num = bgm_num; + elem.stop_type1 = stop_type; + mBGMPsComp_make_ps(&M_bgm.ps_comp, &elem, mBGM_KATEGORIE_DEMO, -1, 0, 0xFF); +} + +extern void mBGMPsComp_make_ps_demo(u8 bgm_num, u16 stop_type) { + _mBGMPsComp_make_ps_demo(bgm_num, stop_type); +} + +static void _mBGMPsComp_make_ps_happening(u8 bgm_num, u16 stop_type) { + mBGMElem elem; + + mBGMElem_default_set(&elem); + elem.bgm_num = bgm_num; + elem.stop_type1 = stop_type; + mBGMPsComp_make_ps(&M_bgm.ps_comp, &elem, mBGM_KATEGORIE_HAPPENING, -1, 0, 0xFF); +} + +extern void mBGMPsComp_make_ps_happening(u8 bgm_num, u16 stop_type) { + _mBGMPsComp_make_ps_happening(bgm_num, stop_type); +} + +static void mBGMPsComp_make_ps_quietRoom(u16 stop_type) { + mBGMElem elem; + + mBGMElem_default_set(&elem); + elem.stop_type1 = stop_type; + mBGMPsComp_make_ps(&M_bgm.ps_comp, &elem, mBGM_KATEGORIE_QUIETROOM, -1, mBGMPs_FLAG_SILENT, 0xFF); +} + +static void _mBGMPsComp_make_ps_room(u8 bgm_num, u16 stop_type) { + mBGMElem elem; + + mBGMElem_default_set(&elem); + elem.bgm_num = bgm_num; + elem.stop_type1 = stop_type; + mBGMPsComp_make_ps(&M_bgm.ps_comp, &elem, mBGM_KATEGORIE_ROOM, -1, 0, 0xFF); +} + +extern void mBGMPsComp_make_ps_room(u8 bgm_num, u16 stop_type) { + _mBGMPsComp_make_ps_room(bgm_num, stop_type); +} + +static void mBGMPsComp_make_ps_time() { + mBGMElem elem; + + mBGMElem_default_set(&elem); + elem.stop_type1 = 0x870; + mBGMPsComp_make_ps(&M_bgm.ps_comp, &elem, mBGM_KATEGORIE_TIME, -1, mBGMPs_FLAG_SILENT, 0xFF); +} + +static void _mBGMPsComp_make_ps_quietField(u16 stop_type) { + mBGMElem elem; + + mBGMElem_default_set(&elem); + elem.stop_type1 = stop_type; + mBGMPsComp_make_ps(&M_bgm.ps_comp, &elem, mBGM_KATEGORIE_QUIETFIELD, -1, mBGMPs_FLAG_SILENT, 0xFF); +} + +extern void mBGMPsComp_make_ps_quietField(u16 stop_type) { + _mBGMPsComp_make_ps_quietField(stop_type); +} + +static void _mBGMPsComp_make_ps_fc_quietField(u16 stop_type) { + mBGMElem elem; + + mBGMElem_default_set(&elem); + elem.stop_type1 = stop_type; + mBGMPsComp_make_ps(&M_bgm.ps_comp, &elem, mBGM_KATEGORIE_QUIETFIELD, -1, mBGMPs_FLAG_SILENT | mBGMPs_FLAG_FADEOUT, 0xFF); +} + +extern void mBGMPsComp_make_ps_fc_quietField(u16 stop_type) { + _mBGMPsComp_make_ps_fc_quietField(stop_type); +} + +static void _mBGMPsComp_make_ps_fieldSuddenEv(u8 bgm_num, u16 stop_type, u8 priority) { + mBGMElem elem; + + mBGMElem_default_set(&elem); + elem.bgm_num = bgm_num; + elem.stop_type1 = stop_type; + mBGMPsComp_make_ps(&M_bgm.ps_comp, &elem, mBGM_KATEGORIE_FIELDSUDDENEV, -1, 0, priority); +} + +extern void mBGMPsComp_make_ps_fieldSuddenEv(u8 bgm_num, u16 stop_type, u8 priority) { + _mBGMPsComp_make_ps_fieldSuddenEv(bgm_num, stop_type, priority); +} + +static void mBGMPsComp_make_ps_fieldSchedEv(u8 bgm_num, int update_volume_move_ctr, int update_volume_level, int cf_flag, u16 stop_type, u8 priority) { + mBGMPsComp* ps_comp = &M_bgm.ps_comp; + mBGMElem elem; + u16 flags; + + mBGMElem_default_set(&elem); + elem.bgm_num = bgm_num; + elem.stop_type1 = stop_type; + flags = 0; + + if (update_volume_move_ctr) { + flags |= mBGMPs_FLAG_UPDATE_VOLUME_MOVE_CTR; + } + + if (update_volume_level) { + flags |= mBGMPs_FLAG_UPDATE_VOLUME_LEVEL; + } + + if (cf_flag) { + flags |= mBGMPs_FLAG_CROSSFADE; + } + + if (bgm_num == 127) { + flags |= mBGMPs_FLAG_SILENT; + } + + mBGMPsComp_make_ps(ps_comp, &elem, mBGM_KATEGORIE_FIELDSCHEDEV, -1, flags, priority); +} + +static void mBGMPsComp_make_ps_fieldNorm(u8 bgm_num, u16 stop_type) { + mBGMElem elem; + + mBGMElem_default_set(&elem); + elem.bgm_num = bgm_num; + elem.stop_type1 = stop_type; + mBGMPsComp_make_ps(&M_bgm.ps_comp, &elem, mBGM_KATEGORIE_FIELDNORM, -1, 0, 255); +} + +static void mBGMPsComp_delete_ps(mBGMPsComp* ps_comp, int kategorie, u8 bgm_num, u16 stop_type, int counter_flag) { + int num = mBGMPsComp_search_pos_kategorie_bgm_num(ps_comp, kategorie, bgm_num, counter_flag, FALSE); + + if (num >= 0 && num < ps_comp->ps_num) { + ps_comp->ps[num].cf_flags |= mBGMPs_FLAG_REMOVE; + ps_comp->ps[num].elem.stop_type0 = stop_type; + } +} + +static void _mBGMPsComp_delete_ps_fanfare(u8 bgm_num, u16 stop_type) { + mBGMPsComp_delete_ps(&M_bgm.ps_comp, mBGM_KATEGORIE_FANFARE, bgm_num, stop_type, FALSE); +} + +extern void mBGMPsComp_delete_ps_fanfare(u8 bgm_num, u16 stop_type) { + _mBGMPsComp_delete_ps_fanfare(bgm_num, stop_type); +} + +static void mBGMPsComp_delete_ps_wipe() { + mBGMPsComp_delete_ps(&M_bgm.ps_comp, mBGM_KATEGORIE_WIPE, 127, 0x168, FALSE); +} + +static void _mBGMPsComp_delete_ps_quiet() { + mBGMPsComp_delete_ps(&M_bgm.ps_comp, mBGM_KATEGORIE_QUIET, 127, 0x168, TRUE); +} + +extern void mBGMPsComp_delete_ps_quiet() { + _mBGMPsComp_delete_ps_quiet(); +} + +static void _mBGMPsComp_delete_ps_demo(u8 bgm_num, u16 stop_type) { + mBGMPsComp_delete_ps(&M_bgm.ps_comp, mBGM_KATEGORIE_DEMO, bgm_num, stop_type, FALSE); +} + +extern void mBGMPsComp_delete_ps_demo(u8 bgm_num, u16 stop_type) { + _mBGMPsComp_delete_ps_demo(bgm_num, stop_type); +} + +static void _mBGMPsComp_delete_ps_happening(u8 bgm_num, u16 stop_type) { + mBGMPsComp_delete_ps(&M_bgm.ps_comp, mBGM_KATEGORIE_HAPPENING, bgm_num, stop_type, FALSE); +} + +extern void mBGMPsComp_delete_ps_happening(u8 bgm_num, u16 stop_type) { + _mBGMPsComp_delete_ps_happening(bgm_num, stop_type); +} + +static void mBGMPsComp_delete_ps_quietRoom() { + mBGMPsComp_delete_ps(&M_bgm.ps_comp, mBGM_KATEGORIE_QUIETROOM, 127, 0x168, TRUE); +} + +static void _mBGMPsComp_delete_ps_room(u8 bgm_num, u16 stop_type) { + mBGMPsComp_delete_ps(&M_bgm.ps_comp, mBGM_KATEGORIE_ROOM, bgm_num, stop_type, FALSE); +} + +extern void mBGMPsComp_delete_ps_room(u8 bgm_num, u16 stop_type) { + _mBGMPsComp_delete_ps_room(bgm_num, stop_type); +} + +static void mBGMPsComp_delete_ps_time() { + mBGMPsComp_delete_ps(&M_bgm.ps_comp, mBGM_KATEGORIE_TIME, 127, 0x168, FALSE); +} + +static void _mBGMPsComp_delete_ps_quietField() { + mBGMPsComp_delete_ps(&M_bgm.ps_comp, mBGM_KATEGORIE_QUIETFIELD, 127, 0x168, TRUE); +} + +extern void mBGMPsComp_delete_ps_quietField() { + _mBGMPsComp_delete_ps_quietField(); +} + +static void _mBGMPsComp_delete_ps_fieldSuddenEv(u8 bgm_num, u16 stop_type) { + mBGMPsComp_delete_ps(&M_bgm.ps_comp, mBGM_KATEGORIE_FIELDSUDDENEV, bgm_num, stop_type, FALSE); +} + +extern void mBGMPsComp_delete_ps_fieldSuddenEv(u8 bgm_num, u16 stop_type) { + _mBGMPsComp_delete_ps_fieldSuddenEv(bgm_num, stop_type); +} + +static void mBGMPsComp_delete_ps_fieldSchedEv(u8 bgm_num, u16 stop_type) { + mBGMPsComp_delete_ps(&M_bgm.ps_comp, mBGM_KATEGORIE_FIELDSCHEDEV, bgm_num, stop_type, FALSE); +} + +static void mBGMPsComp_delete_ps_fieldNorm(u8 bgm_num, u16 stop_type) { + mBGMPsComp_delete_ps(&M_bgm.ps_comp, mBGM_KATEGORIE_FIELDNORM, bgm_num, stop_type, FALSE); +} + +static void mBGMPsComp_volume_change_fieldSchedEv(u8 bgm_num, int update_volume_move_ctr, int update_volume_level) { + mBGMPsComp* ps_comp = &M_bgm.ps_comp; + int idx = mBGMPsComp_search_pos_kategorie_bgm_num(ps_comp, mBGM_KATEGORIE_FIELDSCHEDEV, bgm_num, FALSE, FALSE); + + if (idx >= 0) { + mBGMPs* ps = &ps_comp->ps[idx]; + + if (update_volume_move_ctr) { + ps->cf_flags |= mBGMPs_FLAG_UPDATE_VOLUME_MOVE_CTR; + } + + if (update_volume_level) { + ps->cf_flags |= mBGMPs_FLAG_UPDATE_VOLUME_LEVEL; + } + else { + ps->cf_flags &= ~mBGMPs_FLAG_UPDATE_VOLUME_LEVEL; + } + + ps->cf_flags |= mBGMPs_FLAG_UPDATE_VOLUME; + } +} + +static void mBGMPsComp_search_cf_set_field(u8 bgm_num, int kategorie) { + mBGMPsComp* ps_comp = &M_bgm.ps_comp; + int pos = mBGMPsComp_search_pos_kategorie_bgm_num(ps_comp, kategorie, bgm_num, FALSE, TRUE); + + if (pos >= 0) { + int i; + + for (i = pos + 1; i < ps_comp->ps_num; i++) { + if ( + ps_comp->ps[i].kategorie == mBGM_KATEGORIE_FIELDSUDDENEV || + ps_comp->ps[i].kategorie == mBGM_KATEGORIE_FIELDSCHEDEV || + ps_comp->ps[i].kategorie == mBGM_KATEGORIE_FIELDNORM + ) { + ps_comp->ps[i].cf_flags |= (mBGMPs_FLAG_UPDATE_VOLUME_MOVE_CTR | mBGMPs_FLAG_CROSSFADE); + } + } + } +} + +extern void mBGMPsComp_volume_fishing_start() { + M_bgm.ps_comp.fishing_state = 1; +} + +extern void mBGMPsComp_volume_fishing_end() { + M_bgm.ps_comp.fishing_state = 3; +} + +extern void mBGMPsComp_volume_collect_insects_start() { + M_bgm.ps_comp.collect_insects_state = 1; +} + +extern void mBGMPsComp_volume_collect_insects_end() { + M_bgm.ps_comp.collect_insects_state = 3; +} + +extern void mBGMPsComp_volume_talk_start() { + M_bgm.ps_comp.talk_state = 1; +} + +extern void mBGMPsComp_volume_talk_end() { + if (M_bgm.ps_comp.talk_state != 0) { + M_bgm.ps_comp.talk_state = 3; + } +} + +/* @unused */ +extern void mBGMPsComp_volume_boat_start() { + M_bgm.ps_comp.boat_state = 1; +} + +extern void mBGMPsComp_volume_boat_end() { + mBGMPsComp* ps_comp = &M_bgm.ps_comp; + + if (ps_comp->boat_state != 0) { + ps_comp->boat_state = 3; + } +} + +extern void mBGMPsComp_pause(int state) { + M_bgm.ps_comp.pause_state = state; +} + +extern void mBGMPsComp_MDPlayerPos_make() { + M_bgm.ps_comp.md.make_flag = TRUE; +} + +extern void mBGMPsComp_MDPlayerPos_delete() { + M_bgm.ps_comp.md.delete_flag = TRUE; +} + +extern void mBGMPsComp_MDPlayerPos_param_set(const xyz_t* pos, u16 angle, u16 md_type, u32 ongen_no) { + mBGMPsComp* ps_comp = &M_bgm.ps_comp; + + xyz_t_move(&ps_comp->md.pos, pos); + ps_comp->md.angle = angle; + ps_comp->md.md_type_no = md_type; + ps_comp->md.ongen_no = ongen_no; +} + +extern void mBGMPsComp_scene_mode(u8 mode) { + sAdo_SceneMode(mode); +} + +static void mBGMPsComp_arm_make(u8 state) { + mBGMPsComp* ps_comp = &M_bgm.ps_comp; + + ps_comp->arm.req_flag = TRUE; + ps_comp->arm.arm_state = state; +} + +static void mBGMPsComp_arm_delete() { + mBGMPsComp* ps_comp = &M_bgm.ps_comp; + + ps_comp->arm.req_flag = FALSE; + ps_comp->arm.arm_state = 0; +} + +extern void mBGMPsComp_museum_status(u8 status) { + mBGMPsComp* ps_comp = &M_bgm.ps_comp; + + if (status == 0) { + ps_comp->museum.req_flag = 1; + } + else { + ps_comp->museum.req_flag = 2; + } + + ps_comp->museum.type = status; +} + +extern int mBGMPsComp_execute_bgm_num_get() { + mBGMPsComp* ps_comp = &M_bgm.ps_comp; + int pos = mBGMPsComp_execute_ps_pos_get(ps_comp); + + if (pos >= 0 && ps_comp->ps[pos].elem.bgm_num != 127 && (ps_comp->ps[pos].cf_flags & mBGMPs_FLAG_SILENT) == 0) { + return ps_comp->ps[pos].elem.bgm_num; + } + + return -1; +} + +static void mBGMPsComp_ct(mBGMPsComp* ps_comp) { + bzero(ps_comp, sizeof(mBGMPsComp)); + + ps_comp->volume.main_volume = -1.0f; + ps_comp->volume.main_volume_move_ctr = 0; + ps_comp->volume.ps_volume = -1.0f; + ps_comp->volume.ps_volume_move_ctr = 0; + ps_comp->volume.fishing_volume = -1.0f; + ps_comp->volume.fishing_volume_move_ctr = 100; + ps_comp->volume.collect_insects_volume = -1.0f; + ps_comp->volume.collect_insects_volume_move_ctr = 100; + ps_comp->volume.talk_volume = -1.0f; + ps_comp->volume.boat_volume = -1.0f; + ps_comp->volume.pause_volume = -1.0f; + ps_comp->volume.pause_volume_move_ctr = 2; +} + +/* mBGMForce */ + +static int mBGMForce_wipe_ps_make_permit(mBGMForce* force) { + if (force->room_nonstop != 0) { + return FALSE; + } + else { + return TRUE; + } +} + +static void mBGMForce_move_inform(mBGMForce* force) { + if (force->inform == mBGMForce_INFORM_1) { + int field_ok = mFI_CheckFieldData(); + + if (field_ok == FALSE || (field_ok != FALSE && mFI_GET_TYPE(mFI_GetFieldId()) != mFI_FIELD_FG)) { + force->flag = TRUE; + mBGMPsComp_make_ps_wipe(0x195); + } + + force->inform = mBGMForce_INFORM_2; + } + else if (force->inform == mBGMForce_INFORM_3) { + force->inform = mBGMForce_INFORM_4; + } + else if (force->inform == mBGMForce_INFORM_5) { + if (force->flag) { + mBGMPsComp_make_ps_wipe(0x249); + } + + force->inform = mBGMForce_INFORM_6; + } + else if (force->inform == mBGMForce_INFORM_7) { + force->inform = mBGMForce_INFORM_0; + force->flag = FALSE; + } +} + +static void mBGMForce_move_room_nonstop(mBGMForce* force) { + if (force->room_nonstop == 1) { + force->room_nonstop = 2; + } + else if (force->room_nonstop == 3) { + force->room_nonstop = 0; + } +} + +static void mBGMForce_move(mBGMForce* force) { + mBGMForce_move_inform(force); + mBGMForce_move_room_nonstop(force); +} + +static void mBGMForce_ct(mBGMForce* force) { + bzero(force, sizeof(mBGMForce)); +} + +static void mBGMForce_inform_cleanup(mBGMForce* force) { + if (force->inform == mBGMForce_INFORM_2) { + force->inform = mBGMForce_INFORM_3; + } + else if (force->inform == mBGMForce_INFORM_6) { + force->inform = mBGMForce_INFORM_7; + } +} + +static void mBGMForce_room_nonstop_cleanup(mBGMForce* force) { + if (force->room_nonstop == 2) { + force->room_nonstop = 3; + } +} + +static void mBGMForce_cleanup(mBGMForce* force) { + mBGMForce_inform_cleanup(force); + mBGMForce_room_nonstop_cleanup(force); +} + +extern void mBGMForce_inform_start() { + M_bgm.force.inform = mBGMForce_INFORM_1; +} + +extern void mBGMForce_inform_end() { + M_bgm.force.inform = mBGMForce_INFORM_5; +} + +static void _mBGMForce_room_nonstop_start() { + M_bgm.force.room_nonstop = 1; +} + +extern void mBGMForce_room_nonstop_start() { + _mBGMForce_room_nonstop_start(); +} + +static void mBGM_main_control(mBGM* bgm) { + mBGMPsComp* ps_comp = &bgm->ps_comp; + + mBGMPsComp_main_req_md(ps_comp); + mBGMPsComp_main_req_stop(ps_comp); + mBGMPsComp_main_remove(ps_comp); + mBGMPsComp_main_req_start(ps_comp); + mBGMPsComp_main_req_pause(ps_comp); + mBGMPsComp_main_req_volume(ps_comp); + mBGMPsComp_main_inform_sound(ps_comp); + mBGMPsComp_main_md_move(ps_comp); + mBGMPsComp_main_counter_dec(ps_comp); + mBGMPsComp_main_fo_check(ps_comp); + mBGMPsComp_main_lost(ps_comp); +} + +static void mBGM_weather_set() { + s16 weather = Common_Get(weather); + + if (weather >= mEnv_WEATHER_LEAVES) { + weather = mEnv_WEATHER_SAKURA; + } + else if (weather < 0) { + weather = mEnv_WEATHER_CLEAR; + } + + sAdo_Tenki(weather); +} + +extern void mBGM_main(GAME* game) { + mBGMClock_move(&M_bgm.clock, game); + mBGMDemo_move(&M_bgm.demo, game); + mBGMRoom_move(&M_bgm.room, game); + mBGMFieldSuddenEv_move(&M_bgm.field_sudden_ev, game); + mBGMFieldSchedEv_move(&M_bgm.field_sched_ev, game); + mBGMFieldNorm_move(&M_bgm.field_norm, game); + mBGMTime_move(&M_bgm.time, game); + mBGM_main_control(&M_bgm); + mBGMForce_move(&M_bgm.force); + mBGM_weather_set(); +} + +extern void mBGM_ct() { + mBGMClock_ct(&M_bgm.clock); + mBGMDemo_ct(&M_bgm.demo); + mBGMRoom_ct(&M_bgm.room); + mBGMTime_ct(&M_bgm.time); + mBGMFieldSuddenEv_ct(&M_bgm.field_sudden_ev); + mBGMFieldSchedEv_ct(&M_bgm.field_sched_ev); + mBGMFieldNorm_ct(&M_bgm.field_norm); + mBGMPsComp_ct(&M_bgm.ps_comp); + mBGMForce_ct(&M_bgm.force); +} + +extern void mBGM_init() { + mBGMPsComp_delete_ps_wipe(); + + if (mFI_CheckFieldData()) { + mActor_name_t field_id = mFI_GetFieldId(); + mActor_name_t field_type = mFI_GET_TYPE(field_id); + mBGMForce* force = &M_bgm.force; + + if (field_type == mFI_FIELD_FG) { + if (mEv_CheckTitleDemo() > 0) { + mBGMPsComp_make_ps_demo(70, 0x168); // Play title music + } + else { + if ((force->inform != mBGMForce_INFORM_3 && force->inform != mBGMForce_INFORM_7) || force->flag) { + mBGMFieldNorm_make_req(); + } + + if (force->inform == mBGMForce_INFORM_3 && force->flag) { + mBGMPsComp_make_ps_quiet(0x168); + } + } + } + else if (field_type == mFI_FIELD_ROOM0 || field_type == mFI_FIELD_NPCROOM0 || field_type == mFI_FIELD_PLAYER0_ROOM) { + if (force->room_nonstop != 3) { + mBGMRoom_shop_close_time_set(&M_bgm.room); + mBGMRoom_scene_bgm_make_req(); + } + } + else { + mBGMDemo_scene_bgm_make_req(); + } + } +} + +extern void mBGM_cleanup() { + mBGMForce* force = &M_bgm.force; + + mBGMForce_cleanup(force); + if (mFI_CheckFieldData()) { + mActor_name_t field_id = mFI_GetFieldId(); + mActor_name_t field_type = mFI_GET_TYPE(field_id); + + if (field_type == mFI_FIELD_FG) { + if (mEv_CheckTitleDemo() > 0) { + mBGMPsComp_delete_ps_demo(70, 0x168); // Stop title music + } + else { + if ((force->inform != mBGMForce_INFORM_3 && force->inform != mBGMForce_INFORM_7) || force->flag) { + mBGMFieldNorm_delete_req(); + } + + if (force->inform == mBGMForce_INFORM_7 && force->flag) { + mBGMPsComp_delete_ps_quiet(); + } + } + } + else if (field_type == mFI_FIELD_ROOM0 || field_type == mFI_FIELD_NPCROOM0 || field_type == mFI_FIELD_PLAYER0_ROOM) { + if (force->room_nonstop != 3) { + mBGMRoom_scene_bgm_delete_req(); + } + } + else { + mBGMDemo_scene_bgm_delete_req(); + } + } +} + +extern void mBGM_reset() { + mBGM* bgm = &M_bgm; + mBGMPsComp* ps_comp = &bgm->ps_comp; + mBGMPs* ps = ps_comp->ps; + int i; + int max = ps_comp->ps_num; + + for (i = 0; i < max; i++, ps++) { + ps->cf_flags |= mBGMPs_FLAG_REMOVE; + ps->elem.stop_type0 = 0x168; + } + + if (ps_comp->fishing_state != 0) { + mBGMPsComp_volume_fishing_end(); + } + + if (ps_comp->collect_insects_state != 0) { + mBGMPsComp_volume_collect_insects_end(); + } + + if (ps_comp->talk_state != 0) { + mBGMPsComp_volume_talk_end(); + } + + if (ps_comp->boat_state != 0) { + mBGMPsComp_volume_boat_end(); + } + + if (ps_comp->pause_state != 0) { + mBGMPsComp_pause(5); + } + + mBGMDemo_ct(&bgm->demo); + mBGMRoom_ct(&bgm->room); + mBGMTime_ct(&bgm->time); + mBGMFieldSuddenEv_ct(&bgm->field_sudden_ev); + mBGMFieldSchedEv_ct(&bgm->field_sched_ev); + mBGMFieldNorm_ct(&bgm->field_norm); + mBGMForce_ct(&bgm->force); +} diff --git a/src/m_camera2.c b/src/m_camera2.c index c48ac135..8c351253 100644 --- a/src/m_camera2.c +++ b/src/m_camera2.c @@ -1397,7 +1397,7 @@ static void Camera2_main_Normal_SetEndCenterPos_fromPlayer(GAME_PLAY* play, xyz_ Camera2_GetBorderScale(play, scale, &border_x0, &border_x1, &border_z0, &border_z1); *end_center_pos = player->actor_class.eye.position; - if (mPlib_get_player_actor_main_index(play) == 114) { + if (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) { diff --git a/src/m_demo.c b/src/m_demo.c index 4bbd2776..7e43c6b3 100644 --- a/src/m_demo.c +++ b/src/m_demo.c @@ -439,7 +439,7 @@ static int wait_talk_start() { if (demo->data.talk.change_player) { if ( - mPlib_get_player_actor_main_index((GAME_PLAY*)gamePT) != 65 && + mPlib_get_player_actor_main_index(gamePT) != 65 && mPlib_request_main_talk_type1((GAME_PLAY*)gamePT, demo->current.actor, demo->data.talk.turn, FALSE) == FALSE ) { return FALSE; diff --git a/src/m_soncho.c b/src/m_soncho.c index b7de7f3e..ae96492a 100644 --- a/src/m_soncho.c +++ b/src/m_soncho.c @@ -1169,7 +1169,7 @@ extern int mSC_LightHouse_travel_check() { } extern void mSC_change_player_freeze(GAME_PLAY* play) { - if (mPlib_get_player_actor_main_index(play) != 74) { + if (mPlib_get_player_actor_main_index((GAME*)play) != 74) { mPlib_request_main_demo_wait_type1(play, 0, NULL); } }