diff --git a/config/rel_slices.yml b/config/rel_slices.yml index e747e333..1a38324e 100644 --- a/config/rel_slices.yml +++ b/config/rel_slices.yml @@ -124,6 +124,10 @@ m_random_field/mRF_MakePerfectBit.c: .text: [0x8050B1AC, 0x8050B1D4] m_random_field/mRF_GetRandomStepMode.c: .text: [0x8050B284, 0x8050B2C0] +m_trademark.c: + .text: [0x8062B848, 0x8062C048] + .rodata: [0x8064D1C0, 0x8064D1C8] + .data: [0x806D4958, 0x806D4B18] sys_dynamic.c: .bss: [0x813413F8, 0x81361820] # ac_aprilfool_control/aPC_actor_dt.c: common_data is pure bs, diff --git a/include/game.h b/include/game.h index 98ab71ee..960c5e7e 100644 --- a/include/game.h +++ b/include/game.h @@ -53,7 +53,11 @@ do { \ GAME_NEXT_GAME(t_game, init_name, class_name); \ } while (0) +extern void SetGameFrame(int frame); + extern void game_get_controller(GAME* game); +extern void game_debug_draw_last(GAME* game, GRAPH* graph); +extern void game_draw_last(GRAPH* graph); extern GAME* gamePT; diff --git a/include/libc/math.h b/include/libc/math.h index 1ab5b46a..ef3eff40 100644 --- a/include/libc/math.h +++ b/include/libc/math.h @@ -1,5 +1,5 @@ -#ifndef MATH_H -#define MATH_H +#ifndef LIB_C_MATH_H +#define LIB_C_MATH_H #include "types.h" diff --git a/include/m_bg_item.h b/include/m_bg_item.h new file mode 100644 index 00000000..9f2ff11f --- /dev/null +++ b/include/m_bg_item.h @@ -0,0 +1,16 @@ +#ifndef M_BG_ITEM_H +#define M_BG_ITEM_H + +#include "types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +extern void mBI_ct(); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/m_bgm.h b/include/m_bgm.h index 3e7c98c5..8433b003 100644 --- a/include/m_bgm.h +++ b/include/m_bgm.h @@ -8,6 +8,8 @@ extern "C" { #endif extern void mBGM_reset(); +extern void mBGMPsComp_make_ps_lost_fanfare(u8 bgm_no, u16 unk); +extern void mBGMPsComp_scene_mode(int scene_mode); #ifdef __cplusplus } diff --git a/include/m_card.h b/include/m_card.h index 973f3979..44c393cf 100644 --- a/include/m_card.h +++ b/include/m_card.h @@ -9,6 +9,7 @@ extern "C" { #endif extern void mCD_PrintErrInfo(gfxprint_t* gfxprint); +extern void mCD_InitAll(); #ifdef __cplusplus } diff --git a/include/m_common_data.h b/include/m_common_data.h index c310b265..0d4a5803 100644 --- a/include/m_common_data.h +++ b/include/m_common_data.h @@ -24,6 +24,7 @@ #include "m_field_assessment.h" #include "m_mushroom.h" #include "m_clip.h" +#include "m_scene.h" #ifdef __cplusplus extern "C" { @@ -152,20 +153,35 @@ typedef struct common_data_s { /* 0x026144 */ u8 tmp0[0x2614D - 0x26144]; /* 0x02614D */ u8 transFadeDuration; /* 0x02614E */ u8 transWipeSpeed; - /* 0x02614F */ u8 tmp34[0x2666C - 0x2614F]; + /* 0x02614F */ u8 wipeType; /* maybe unused? */ + /* 0x02614F */ u8 _26150[0x26164 - 0x26150]; + /* 0x026164 */ mNpc_NpcList_c npclist[ANIMAL_NUM_MAX]; + /* 0x0264AC */ mNpc_NpcList_c unk_264AC; // fits exact size of npc list struct, seems unused + /* 0x0264E4 */ mNpc_NpcList_c island_npclist[1]; // TODO: define for island npc count + /* 0x02651C */ mActor_name_t house_owner_name; + /* 0x02651E */ mActor_name_t last_field_id; + /* 0x026520 */ u8 in_initial_block; /* when TRUE, the player is in the acre which they exited a building. FALSE otherwise. */ + /* 0x026521 */ u8 submenu_disabled; /* when set, submenus cannot be accessed from start button */ + /* 0x026522 */ u8 _26522[0x2666C - 0x26522]; /* 0x02666C */ s16 weather; /* 0x02666E */ s16 weather_intensity; /* 0x026670 */ lbRTC_time_c weather_time; - /* 0x026678 */ u8 _26678[0x2852C - 0x26678]; + /* 0x026678 */ u8 _26678[0x266A4 - 0x26678]; + /* 0x0266A4 */ int scene_from_title_demo; /* next scene to be loaded when title demo finishes */ + /* 0x0266A8 */ u8 _266A8[0x2852C - 0x266A8]; /* 0x02852C */ s16 money_power; /* 0x02852E */ s16 goods_power; - /* 0x028530 */ u8 tmp1[0x28879 - 0x28530]; + /* 0x028530 */ Door_data_c door_data; /* misc door data */ + /* 0x028544 */ Door_data_c structure_exit_door_data; /* door data for when exiting a building */ + /* 0x028558 */ u8 tmp1[0x28879 - 0x28558]; /* 0x028879 */ u8 auto_nwrite_count; /* 0x02887A */ lbRTC_year_t auto_nwrite_year; /* 0x02887C */ u8 save_error_type; /* set to one of the mFRm_ERROR_* states when save is invalid */ /* 0x02887D */ u8 train_coming_flag; /* set when the train is coming */ /* 0x02887E */ u8 buried_treasure_flag; /* when set, treasure cannot be buried */ - /* 0x02887F */ u8 tmp2[0x2DB40 - 0x2887F]; + /* 0x02887F */ u8 tmp2[0x288A0 - 0x2887F]; + /* 0x0288A0 */ u8 pad_connected; /* is gamepad 0 connected? */ + /* 0x0288A1 */ u8 _288a1[0x02DB40 - 0x0288A1]; /* 0x02DB40 */ u8 auto_nwrite_set; /* when true, saved nwrite time will be utilized. Seems to be used to keep same date for fishing tourney stuff. */ /* 0x02DB41 */ u8 tmp3[0x2DBB0 - 0x2DB41]; /* 0x02DBB0 */ s16 can_look_goki_count; @@ -192,6 +208,8 @@ extern common_data_t common_data; #define Save_GetPointer(name) (Common_GetPointer(save.save.name)) #define Save_Set(name, value) (Common_Set(save.save.name, value)) +extern void common_data_reinit(); + #ifdef __cplusplus } #endif diff --git a/include/m_cpak.h b/include/m_cpak.h new file mode 100644 index 00000000..3c54b764 --- /dev/null +++ b/include/m_cpak.h @@ -0,0 +1,16 @@ +#ifndef M_CPAK_H +#define M_CPAK_H + +#include "types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +extern int mCPk_InitPak(int pak_idx); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/m_event.h b/include/m_event.h index c84c1580..f76b4a5b 100644 --- a/include/m_event.h +++ b/include/m_event.h @@ -143,6 +143,10 @@ extern int mEv_check_status(int event, s16 status); extern s8* mEv_get_common_area(int type, s8 id); extern int mEv_weekday2day(lbRTC_month_t month, int week_type, lbRTC_weekday_t weekday); +extern void mEv_ClearEventInfo(); + +extern int mEv_CheckTitleDemo(); +extern void mEv_SetTitleDemo(int titledemo_no); extern void mEv_debug_print4f(gfxprint_t* gfxprint); extern void mEv_sp_debug_print4f(gfxprint_t* gfxprint); diff --git a/include/m_field_info.h b/include/m_field_info.h index 1e291c3f..8bec7ea0 100644 --- a/include/m_field_info.h +++ b/include/m_field_info.h @@ -84,6 +84,7 @@ typedef struct location_info_s { extern int mFI_CheckFieldData(); extern mActor_name_t mFI_GetFieldId(); extern int mFI_GetClimate(); +extern void mFI_SetClimate(int climate); extern mActor_name_t* mFI_BkNumtoUtFGTop(int block_x, int block_z); extern void mFI_ClearDeposit(int block_x, int block_z); extern int mFI_GetLineDeposit(u16* deposit, int ut_x); diff --git a/include/m_island.h b/include/m_island.h index fab30676..5b7e83c7 100644 --- a/include/m_island.h +++ b/include/m_island.h @@ -43,6 +43,8 @@ typedef struct island_s { /* 0x18E3 */ u8 unused_18E3[29]; /* unused */ } Island_c; +extern void mISL_ClearKeepIsland(); + #ifdef __cplusplus } #endif diff --git a/include/m_lib.h b/include/m_lib.h index f73403e1..f0446da5 100644 --- a/include/m_lib.h +++ b/include/m_lib.h @@ -4,6 +4,7 @@ #include "types.h" #include "m_play.h" #include "m_actor_type.h" +#include "MSL_C/math.h" #ifdef __cplusplus extern "C" { @@ -14,6 +15,18 @@ extern "C" { #define ABS(x) (((x) >= 0) ? (x) : -(x)) #define SQ(x) ((x)*(x)) +/* radians -> short angle */ +#define RAD2SHORT_ANGLE(rad) ((s16)(int)((rad) * (65536.0f / (2.0f * F_PI)))) + +/* short angle -> radians */ +#define SHORT2RAD_ANGLE(s) ((((f32)(s)) / (65536.0f / (2.0f * F_PI)))) + +/* degrees -> short angle */ +#define DEG2SHORT_ANGLE(deg) ((s16)((deg) * (65536.0f / 360.0f))) + +/* short angle -> degrees */ +#define SHORT2DEG_ANGLE(s) ((((f32)(s)) / (65536.0f / 360.0f))) + typedef struct xy_s { f32 x, y; } xy_t; diff --git a/include/m_msg.h b/include/m_msg.h index 7c99cb28..f14359f7 100644 --- a/include/m_msg.h +++ b/include/m_msg.h @@ -19,6 +19,8 @@ extern void mMsg_Set_free_str(M_MSG_WINDOW* msg, int free_str_no, u8* str, size_ extern void mMsg_debug_draw(gfxprint_t* gfxprint); +extern void mMsg_aram_init(); + #ifdef __cplusplus } #endif diff --git a/include/m_name_table.h b/include/m_name_table.h index eea1d071..4698a9f2 100644 --- a/include/m_name_table.h +++ b/include/m_name_table.h @@ -369,6 +369,23 @@ extern int mNT_check_unknown(mActor_name_t item_no); #define EXIT_DOOR 0x4080 +#define NPC_START 0xE000 +#define NPC_BOB NPC_START +// TODO: Finish +#define NPC_JOEY 0xE048 +#define NPC_PAOLO 0xE04C +#define NPC_JANE 0xE061 +#define NPC_CARRIE 0xE06F +#define NPC_SAMSON 0xE07D +#define NPC_BUZZ 0xE08C +#define NPC_CUBE 0xE093 +#define NPC_RASHER 0xE09B +#define NPC_TANK 0xE0AA +#define NPC_VESTA 0xE0AD +#define NPC_TYBALT 0xE0B6 +#define NPC_LOBO 0xE0B9 +#define NPC_BIFF 0xE0C2 + #define RSV_DOOR 0xFE1B #define RSV_WALL_NO 0xFFFE /* interior wall item, no collision */ #define RSV_NO 0xFFFF /* reserved space, can't interact but no collision */ diff --git a/include/m_npc.h b/include/m_npc.h index cd9c28d9..e2e3ed04 100644 --- a/include/m_npc.h +++ b/include/m_npc.h @@ -10,6 +10,7 @@ #include "lb_rtc.h" #include "m_personal_id.h" #include "m_quest.h" +#include "m_lib.h" #ifdef __cplusplus extern "C" { @@ -145,9 +146,47 @@ typedef struct animal_return_s { /* 0x04 */ lbRTC_time_c renew_time; /* time that this struct was updated */ } Anmret_c; +typedef struct demo_npc_s { + mActor_name_t npc_name; /* villager id, E0XX */ + u32 block_x, block_z; /* spawn acre */ + u32 ut_x, ut_z; /* spawn unit in acre */ +} mNpc_demo_npc_c; + +typedef struct { + u8 type; + u8 palette; + u8 wall_id; + u8 floor_id; + mActor_name_t main_layer_id; + mActor_name_t secondary_layer_id; +} mNpc_NpcHouseData_c; + +typedef struct npc_conversation_s { + u8 beesting:1; // talk to player about their beesting + u8 unk:7; +} mNpc_NpcConversation_c; + +typedef struct npc_list_s { + mActor_name_t name; + mActor_name_t field_name; + xyz_t house_position; + xyz_t position; + u8 appear_flag; + mNpc_NpcConversation_c conversation_flags; + mQst_base_c quest_info; + mNpc_NpcHouseData_c house_data; + mActor_name_t reward_furniture; +} mNpc_NpcList_c; + /* anm_id could also just be a Animal_c pointer */ extern void mNpc_GetNpcWorldNameAnm(u8* name, AnmPersonalID_c* anm_id); extern int mNpc_CheckFreeAnimalPersonalID(AnmPersonalID_c* anm_id); +extern void mNpc_SetAnimalTitleDemo(mNpc_demo_npc_c* demo_npc, Animal_c* animal, GAME* game); +extern void mNpc_SetNpcList(mNpc_NpcList_c* npc_list, Animal_c* animal, int max, int unused); +extern void mNpc_ClearCacheName(); +extern void mNpc_ClearInAnimal(); +extern void mNpc_FirstClearGoodbyMail(); +extern void mNpc_ClearIslandNpcRoomData(); extern void mNpc_PrintRemoveInfo(gfxprint_t* gfxprint); extern void mNpc_PrintFriendship_fdebug(gfxprint_t* gfxprint); diff --git a/include/m_play.h b/include/m_play.h index fae5580c..45534c61 100644 --- a/include/m_play.h +++ b/include/m_play.h @@ -14,9 +14,10 @@ typedef struct game_play_s { /* 0x0000 */ GAME game; // TODO: finish /* 0x00E0 */ u8 d[0x1CC0]; - /* 0x1DA0*/ int isPause; - /* 0x1DA4*/ u8 _temp[0x268]; - /* 0x200C*/ MtxF matrix; + /* 0x1DA0 */ int isPause; + /* 0x1DA4 */ u8 _temp[0x268]; + /* 0x200C */ MtxF matrix; + /* 0x204C */ u8 _204C[0x2600-0x204C]; } GAME_PLAY; extern void play_init(GAME_PLAY* play); diff --git a/include/m_private.h b/include/m_private.h index e32c35cf..90ce0670 100644 --- a/include/m_private.h +++ b/include/m_private.h @@ -176,6 +176,8 @@ extern int mPr_NullCheckPersonalID(PersonalID_c* pid); extern int mPr_CheckCmpPersonalID(PersonalID_c* pid_a, PersonalID_c* pid_b); extern void mPr_ClearPersonalID(PersonalID_c* pid); extern void mPr_CopyPersonalID(PersonalID_c* dst, PersonalID_c* src); +extern void mPr_ClearPrivateInfo(Private_c* private); +extern void mPr_RandomSetPlayerData_title_demo(); #ifdef __cplusplus } diff --git a/include/m_quest.h b/include/m_quest.h index 9cafcf36..551ce6af 100644 --- a/include/m_quest.h +++ b/include/m_quest.h @@ -114,6 +114,7 @@ typedef struct quest_errand_s { } mQst_errand_c; extern void mQst_PrintQuestInfo(gfxprint_t* gfxprint); +extern void mQst_ClearGrabItemInfo(); #ifdef __cplusplus } diff --git a/include/m_rcp.h b/include/m_rcp.h index df98dcfa..8a24d73a 100644 --- a/include/m_rcp.h +++ b/include/m_rcp.h @@ -3,6 +3,7 @@ #include "types.h" #include "PR/mbi.h" +#include "game.h" #ifdef __cplusplus extern "C" { @@ -12,6 +13,8 @@ extern Gfx* gfx_gSPTextureRectangle1(Gfx* gfx, u32 ulx, u32 uly, u32 lrx, u32 lr extern Gfx* gfx_gDPFillRectangle1(Gfx* gfx, u32 ulx, u32 uly, u32 lrx, u32 lry); extern Gfx* gfx_gDPFillRectangleF(Gfx* gfx, u32 ulx, u32 uly, u32 lrx, u32 lry); extern Gfx* gfx_tex_scroll2(Gfx** gfxpp, u32 x, u32 y, int width, int height); +extern void DisplayList_initialize(GRAPH* graph, u32 clear_r, u32 clear_g, u32 clear_b, GAME* game); +extern void fade_black_draw(Gfx** gfxpp, u32 alpha); #ifdef __cplusplus } diff --git a/include/m_room_type.h b/include/m_room_type.h index 32c05159..e4e1bf11 100644 --- a/include/m_room_type.h +++ b/include/m_room_type.h @@ -32,7 +32,6 @@ typedef struct room_type_place_info_s { // TEMPORARY. Should be generated with .decl files #define ITEM0_NO_START 0x0000 -#define NULL_NO ITEM0_NO_START #define ITEM0_1_NO_START ITEM0_NO_START + 0x800 #define FTR0_NO_START 0x1000 diff --git a/include/m_scene.h b/include/m_scene.h new file mode 100644 index 00000000..721ba752 --- /dev/null +++ b/include/m_scene.h @@ -0,0 +1,27 @@ +#ifndef M_SCENE_H +#define M_SCENE_H + +#include "types.h" +#include "m_scene_table.h" +#include "m_lib.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct door_data_s { + int next_scene_id; + u8 exit_orientation; + u8 exit_type; // 0 = normal, 1 = restart game? + u16 extra_data; + s_xyz exit_position; + mActor_name_t door_actor_name; + u8 wipe_type; + u8 pad[3]; // possibly necessary due to struct copy +} Door_data_c; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/m_scene_table.h b/include/m_scene_table.h index 0f00edda..a31cea59 100644 --- a/include/m_scene_table.h +++ b/include/m_scene_table.h @@ -15,6 +15,7 @@ extern "C" { enum scene_table { /* TODO: finish */ SCENE_FG = 0x07, /* outdoors/FG */ + SCENE_TITLE_DEMO = 0x21, /* title screen demo */ SCENE_ISLAND_COTTAGE = 0x2F, /* TODO: finish */ }; diff --git a/include/m_time.h b/include/m_time.h index e21a6596..79e7112e 100644 --- a/include/m_time.h +++ b/include/m_time.h @@ -76,6 +76,8 @@ extern const lbRTC_time_c mTM_rtcTime_default_code; #define mTM_IsTimeCleared(time) (lbRTC_IsEqualTime((time), &mTM_rtcTime_clear_code, lbRTC_CHECK_ALL) == TRUE) #define mTM_AreTimesEqual(t0, t1) (lbRTC_IsEqualTime(t0, t1, lbRTC_CHECK_ALL)) +extern void mTM_set_season(); + #ifdef __cplusplus } #endif diff --git a/include/m_titledemo.h b/include/m_titledemo.h new file mode 100644 index 00000000..ee7783a2 --- /dev/null +++ b/include/m_titledemo.h @@ -0,0 +1,19 @@ +#ifndef M_TITLEDEMO_H +#define M_TITLEDEMO_H + +#include "types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define mTD_TITLE_DEMO_NUM 5 + +extern int mTD_get_titledemo_no(); +extern int mTD_demono_get(); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/m_trademark.h b/include/m_trademark.h index 5bb03beb..dc7e8428 100644 --- a/include/m_trademark.h +++ b/include/m_trademark.h @@ -3,6 +3,7 @@ #include "types.h" #include "game.h" +#include "m_view.h" #ifdef __cplusplus extern "C" { @@ -11,12 +12,29 @@ extern "C" { /* sizeof(struct game_trademark_s) == 0x25A70 */ typedef struct game_trademark_s { /* 0x000000 */ GAME game; - // TODO: finish - /* 0x0000E0 */ u8 _temp[0x25990]; + /* 0x0000E0 */ View view; + /* 0x000200 */ xyz_t unused_200; // n64 + /* 0x00020C */ f32 unused_20c; // n64 + /* 0x000210 */ u32 unused_210; // n64 + /* 0x000214 */ int unused_214; // n64 + /* 0x000218 */ int unused_218[15]; // n64 + /* 0x000254 */ int unused_254; // n64 + /* 0x000258 */ int unused_258[38400]; // n64 texture + /* 0x025A58 */ u32 alpha; + /* 0x025A5C */ s16 logo_timer; + /* 0x025A5E */ u16 alpha2; + /* 0x025A60 */ s16 move_timer; + /* 0x025A62 */ s16 unused_25a62; // n64 + /* 0x025A64 */ s16 unused_25a64; // n64 + /* 0x025A66 */ u8 stage; + /* 0x025A67 */ u8 unused_25a67; // n64 + /* 0x025A68 */ u8 cancel; + /* 0x025A69 */ u8 check; + /* 0x025A6C */ int unused_25a6c; // n64 } GAME_TRADEMARK; -extern void trademark_init(GAME_TRADEMARK* trademark); -extern void trademark_cleanup(GAME_TRADEMARK* trademark); +extern void trademark_init(GAME* game); +extern void trademark_cleanup(GAME* game); #ifdef __cplusplus } diff --git a/include/m_vibctl.h b/include/m_vibctl.h index 3f1b4325..73625700 100644 --- a/include/m_vibctl.h +++ b/include/m_vibctl.h @@ -8,6 +8,7 @@ extern "C" { #endif extern void mVibctl_reset(); +extern void mVibctl_init0(); #ifdef __cplusplus } diff --git a/include/m_view.h b/include/m_view.h index 03472ad0..b4ddd2c5 100644 --- a/include/m_view.h +++ b/include/m_view.h @@ -43,6 +43,8 @@ typedef struct view_s { int _unused_pad0; } View; +extern void initView(View* view, GRAPH* graph); + #ifdef __cplusplus } #endif diff --git a/include/sys_matrix.h b/include/sys_matrix.h index bd878d86..2001d75d 100644 --- a/include/sys_matrix.h +++ b/include/sys_matrix.h @@ -16,6 +16,7 @@ extern void Matrix_push(); extern void Matrix_pull(); extern void Matrix_get(MtxF* m); extern void Matrix_put(MtxF* m); +extern void new_Matrix(GAME* game); #ifdef __cplusplus } diff --git a/rel/m_room_type/mRmTp_FtrItemNo2FtrIdx.c b/rel/m_room_type/mRmTp_FtrItemNo2FtrIdx.c index ac4241a7..46bd60fe 100644 --- a/rel/m_room_type/mRmTp_FtrItemNo2FtrIdx.c +++ b/rel/m_room_type/mRmTp_FtrItemNo2FtrIdx.c @@ -12,5 +12,5 @@ extern int mRmTp_FtrItemNo2FtrIdx(u16 ftr_no) { return FTR_NO_2_FTR_IDX(ftr_no - FTR1_NO_START) + NUM_FTR_IN_TYPE; } - return NULL_NO; + return EMPTY_NO; } diff --git a/rel/m_trademark.c b/rel/m_trademark.c new file mode 100644 index 00000000..af1d1923 --- /dev/null +++ b/rel/m_trademark.c @@ -0,0 +1,414 @@ +#include "m_trademark.h" + +#include "m_scene.h" +#include "m_name_table.h" +#include "m_npc.h" +#include "m_kankyo.h" +#include "m_cpak.h" +#include "m_flashrom.h" +#include "m_private.h" +#include "m_event.h" +#include "m_private.h" +#include "m_time.h" +#include "libultra/libultra.h" +#include "initial_menu.h" +#include "m_titledemo.h" +#include "m_bgm.h" +#include "m_rcp.h" +#include "m_home.h" +#include "m_mail.h" +#include "m_msg.h" +#include "m_field_info.h" +#include "m_font.h" +#include "m_quest.h" +#include "m_bg_item.h" +#include "m_card.h" +#include "m_island.h" +#include "m_vibctl.h" +#include "sys_matrix.h" +#include "sys_vimgr.h" +#include "libjsys/jsyswrapper.h" +#include "libc64/qrand.h" +#include "m_common_data.h" + +static int mTR_first_flag = TRUE; + +static Door_data_c demo_1_door_data = { + SCENE_TITLE_DEMO, + 4, + FALSE, + 0, + { 2180, 200, 824 }, + EMPTY_NO, + 3, + {0,0,0} +}; + +static Door_data_c demo_2_door_data = { + SCENE_TITLE_DEMO, + 4, + FALSE, + 0, + { 3218, 40, 3074 }, + EMPTY_NO, + 3, + {0,0,0} +}; + +static Door_data_c demo_3_door_data = { + SCENE_TITLE_DEMO, + 4, + FALSE, + 0, + { 2117, 160, 1488 }, + EMPTY_NO, + 3, + {0,0,0} +}; + +static Door_data_c demo_4_door_data = { + SCENE_TITLE_DEMO, + 4, + FALSE, + 0, + { 2899, 160, 1101 }, + EMPTY_NO, + 3, + {0,0,0} +}; + +static Door_data_c demo_5_door_data = { + SCENE_TITLE_DEMO, + 4, + FALSE, + 0, + { 1578, 40, 2472 }, + EMPTY_NO, + 3, + {0,0,0} +}; + +static Door_data_c* l_demo_door_data_table[mTD_TITLE_DEMO_NUM] = { + &demo_1_door_data, + &demo_2_door_data, + &demo_3_door_data, + &demo_4_door_data, + &demo_5_door_data +}; + +#define DEMO_NPC(name, bx, bz, utx, utz) { NPC_##name, (bx), (bz), (utx), (utz) } +static mNpc_demo_npc_c demo_npc_list[] = { + DEMO_NPC(BOB, 1, 2, 3, 7), + DEMO_NPC(PAOLO, 1, 2, 8, 11), + DEMO_NPC(VESTA, 1, 4, 12, 11), + DEMO_NPC(JOEY, 2, 3, 5, 6), + DEMO_NPC(LOBO, 2, 3, 4, 12), + DEMO_NPC(CARRIE, 3, 5, 11, 5), + DEMO_NPC(TANK, 4, 3, 3, 12), + DEMO_NPC(BUZZ, 4, 4, 3, 4), + DEMO_NPC(RASHER, 4, 4, 12, 13), + DEMO_NPC(BIFF, 4, 6, 5, 6), + DEMO_NPC(SAMSON, 5, 2, 12, 4), + DEMO_NPC(JANE, 5, 2, 9, 11), + DEMO_NPC(TYBALT, 5, 4, 11, 4), + DEMO_NPC(CUBE, 5, 5, 5, 11) +}; + +static int demo_npc_num = sizeof(demo_npc_list) / sizeof(mNpc_demo_npc_c); + +static int set_npc_4_title_demo(GAME_TRADEMARK* trademark) { + Animal_c* animals = Save_Get(animals); + + mNpc_SetAnimalTitleDemo(demo_npc_list, animals, (GAME*)trademark); + mNpc_SetNpcList(Common_Get(npclist), animals, demo_npc_num, 0); + + return demo_npc_num; +} + +typedef struct tradeday_s { + lbRTC_month_t month; + lbRTC_day_t day; + lbRTC_hour_t hour; + s16 weather; +} mTM_tradeday_c; + +static void mTM_demotime_set(int title_no) { + static mTM_tradeday_c tradeday_table[] = { + { lbRTC_APRIL, 6, 13, mEnv_WEATHER_SAKURA }, /* April 6th @ 1pm, Cherry Blossoms */ + { lbRTC_JUNE, 16, 13, mEnv_WEATHER_RAIN }, /* June 16th @ 1pm, Raining */ + { lbRTC_AUGUST, 1, 6, mEnv_WEATHER_CLEAR }, /* August 1st @ 6am, Clear */ + { lbRTC_NOVEMBER, 1, 16, mEnv_WEATHER_CLEAR }, /* November 1st @ 4pm, Clear */ + { lbRTC_FEBRUARY, 1, 2, mEnv_WEATHER_SNOW } /* February 1st @ 2am, Snowing */ + }; + + Common_Set(time.rtc_enabled, FALSE); + Common_Set(time.rtc_time.year, GAME_YEAR_MIN + 1); + Common_Set(time.rtc_time.min, 0); + + if (title_no != 0) { + Common_Set(time.rtc_time.month, tradeday_table[(title_no - 1)].month); + Common_Set(time.rtc_time.day, tradeday_table[(title_no - 1)].day); + Common_Set(time.rtc_time.hour, tradeday_table[(title_no - 1)].hour); + Common_Set(weather, tradeday_table[(title_no - 1)].weather); + } +} + +static void trademark_goto_demo_scene(GAME_TRADEMARK* trademark) { + int demo_no; + int i; + Private_c* n_private; + Save_t* save; + Private_c* private; + + save = Common_GetPointer(save.save); + mCPk_InitPak(0); + n_private = Save_Get(private); + Common_Set(now_private, n_private); + + if (mFRm_CheckSaveData() == FALSE) { + bzero(save, sizeof(Save_t)); + mFRm_ClearSaveCheckData(Save_GetPointer(save_check)); + + private = n_private; + for (i = 0; i < PLAYER_NUM; i++) { + mPr_ClearPrivateInfo(private); + private++; + } + + Save_Set(land_info.exists, TRUE); + Common_Set(house_owner_name, RSV_NO); + Common_Set(last_field_id, -1); + } + + mEv_ClearEventInfo(); + + demo_no = mEv_CheckTitleDemo(); + if (demo_no > 0) { + Door_data_c* demo_door_data = l_demo_door_data_table[demo_no - 1]; + + Common_Set(door_data, *demo_door_data); + Common_Set(door_data.next_scene_id, demo_door_data->next_scene_id + 1); // go to next demo scene + mTM_demotime_set(demo_no); // set demo date, time, and weather + mPr_RandomSetPlayerData_title_demo(); // randomize player data + set_npc_4_title_demo(trademark); // set animals in the demo + Common_Set(wipeType, 3); + } + + Save_Set(scene_no, SCENE_TITLE_DEMO); + mTM_set_season(); + Common_Set(submenu_disabled, TRUE); + GAME_GOTO_NEXT((GAME*)trademark, play, PLAY); +} + +static void nintendo_logo_move(GAME_TRADEMARK* trademark) { + int timer; + int alpha2; + if (trademark->stage == 2) { + alpha2 = trademark->alpha2; + alpha2 += 0x880; + if (alpha2 >= 0xFF00) { + trademark->stage = 4; + alpha2 = 0xFF00; + } + + trademark->alpha2 = alpha2; + } + else if (trademark->stage == 4) { + if (trademark->logo_timer == 0) { + timer = 0; + } + else { + timer = --trademark->logo_timer; + } + + if (timer == 0) { + trademark->stage = 3; + } + } +} + +static void nintendo_logo_draw(GAME_TRADEMARK* trademark) { + Gfx* gfx; + GRAPH* g = trademark->game.graph; + u8 a; + + OPEN_DISP(g); + nintendo_logo_move(trademark); + gfx = NOW_POLY_OPA_DISP; + a = trademark->alpha2 >> 8; + make_dl_nintendo_logo(&gfx, a); + SET_POLY_OPA_DISP(gfx); + CLOSE_DISP(g); +} + +static void trademark_cancel(GAME_TRADEMARK* trademark) { + if (trademark->cancel != FALSE) { + return; + } + + if (trademark->stage != 4) { + return; + } + + if (Common_Get(pad_connected) == FALSE) { + return; + } + + if ((gamePT->pads[0].on.button & BUTTON_START) != BUTTON_START) { + return; + } + + trademark->cancel = TRUE; +} + +static void trademark_move(GAME_TRADEMARK* trademark) { + static u8 s_titlebgm[mTD_TITLE_DEMO_NUM] = { 83, 84, 85, 86, 87 }; // TODO: convert to enum/definitions + + if (trademark->stage == 0) { + int titledemo_no = mTD_get_titledemo_no(); + mBGMPsComp_make_ps_lost_fanfare(s_titlebgm[titledemo_no], 360); + trademark->alpha = 0; + trademark->stage = 1; + } + + if (trademark->stage == 1) { + int move_timer; + if (trademark->move_timer == 0) { + move_timer = 0; + } + else { + move_timer = --trademark->move_timer; + } + + if (move_timer == 0) { + trademark->stage = 2; + } + } + + if (trademark->stage == 3 || trademark->cancel) { + if (trademark->alpha < 0xFF00) { + trademark->alpha += 0x880; + } + + if (trademark->check != TRUE) { + trademark->check = TRUE; + } + + if (trademark->alpha >= 0xFF00 && trademark->check == TRUE) { + trademark->alpha = 0xFF00; + trademark->stage = 5; + } + } +} + +static void trademark_draw(GAME_TRADEMARK* trademark) { + GRAPH* g = trademark->game.graph; + Gfx* gfx; + + OPEN_DISP(g); + + gSPSegment(NOW_POLY_OPA_DISP++, 0, 0); + DisplayList_initialize(g, 0, 0, 0, NULL); + if (mTR_first_flag == FALSE) { + if (trademark->stage >= 2) { + nintendo_logo_draw(trademark); + } + + gfx = NOW_POLY_XLU_DISP; + fade_black_draw(&gfx, trademark->alpha >> 8); + SET_POLY_XLU_DISP(gfx); + } + + CLOSE_DISP(g); +} + +static void trademark_main(GAME* game) { + GAME_TRADEMARK* trademark = (GAME_TRADEMARK*)game; + GRAPH* g; + + fqrand(); /* increment qrand seed every frame */ + trademark_cancel(trademark); + trademark_move(trademark); + trademark_draw(trademark); + + g = game->graph; + game_debug_draw_last(game, g); + game_draw_last(g); + + if (trademark->stage == 5) { + trademark->stage = 0; + trademark_goto_demo_scene(trademark); + mTR_first_flag = FALSE; + } +} + +extern void trademark_cleanup(GAME* game) { + GAME_TRADEMARK* trademark = (GAME_TRADEMARK*)game; + mHm_hs_c* home = Save_Get(homes); + int i; + + for (i = 0; i < PLAYER_NUM; i++) { + home->outlook_pal = i; + home->next_outlook_pal = i; + + mMl_clear_mail_box(home->mailbox, HOME_MAILBOX_SIZE); + home++; + } + + JW_SetLogoMode(0); + SoftResetEnable = TRUE; +} + +extern void trademark_init(GAME* game) { + GAME_TRADEMARK* trademark = (GAME_TRADEMARK*)game; + GRAPH* g = game->graph; + + common_data_reinit(); + mFI_SetClimate(mFI_CLIMATE_0); + game->exec = &trademark_main; + game->cleanup = &trademark_cleanup; + initView(&trademark->view, g); + new_Matrix(game); + trademark->alpha = 0xFF00; + trademark->alpha2 = 0; + trademark->logo_timer = 60; + trademark->move_timer = 16; + trademark->unused_254 = 0; + trademark->unused_210 = 0; + trademark->stage = 0; + trademark->unused_200.x = 0.0f; + trademark->unused_200.y = 0.0f; + trademark->unused_200.z = 0.0f; + trademark->unused_20c = 0.5f; + trademark->unused_25a62 = 0; + trademark->unused_25a64 = 5072; + trademark->unused_25a67 = 0; + trademark->cancel = FALSE; + trademark->check = FALSE; + + if (mTR_first_flag) { + trademark->stage = 5; + } + + SetGameFrame(1); + viBlack(FALSE); + JW_SetLogoMode(1); + mMsg_aram_init(); + + Common_Set(player_no, 0); + Common_Set(player_data_mode, 0); + Common_Set(scene_from_title_demo, -1); + mNpc_ClearCacheName(); + mNpc_ClearInAnimal(); + mNpc_FirstClearGoodbyMail(); + mQst_ClearGrabItemInfo(); + mNpc_ClearIslandNpcRoomData(); + mCD_InitAll(); + mISL_ClearKeepIsland(); + mBI_ct(); + mFont_ct(); + mBGMPsComp_scene_mode(0); + mVibctl_init0(); + mFRm_clear_err_info(); + mEv_SetTitleDemo(mTD_demono_get()); +}