From c243e9cdda8de2abf5ee3fceb0b0fca46ae2e820 Mon Sep 17 00:00:00 2001 From: Cuyler36 Date: Tue, 20 Jun 2023 15:35:59 -0400 Subject: [PATCH] Implement & link m_select.c --- config/rel_slices.yml | 4 + include/libu64/gfxprint.h | 8 + include/m_common_data.h | 17 +- include/m_kankyo.h | 9 + include/m_name_table.h | 2 + include/m_npc.h | 2 + include/m_private.h | 39 +- include/m_rcp.h | 1 + include/m_scene_table.h | 66 +- include/m_select.h | 36 +- include/m_time.h | 2 + rel/m_select.c | 1340 +++++++++++++++++++++++++++++++++++++ 12 files changed, 1499 insertions(+), 27 deletions(-) create mode 100644 rel/m_select.c diff --git a/config/rel_slices.yml b/config/rel_slices.yml index 3ef70122..c93259de 100644 --- a/config/rel_slices.yml +++ b/config/rel_slices.yml @@ -160,6 +160,10 @@ m_random_field/mRF_MakePerfectBit.c: .text: [0x8050B1AC, 0x8050B1D4] m_random_field/mRF_GetRandomStepMode.c: .text: [0x8050B284, 0x8050B2C0] +m_select.c: + .text: [0x80627F88, 0x80629CA8] + .rodata: [0x8064D1B0, 0x8064D1B8] + .data: [0x806D3D08, 0x806D46D0] first_game.c: .text: [0x80629CA8, 0x80629D4C] sys_romcheck.c: diff --git a/include/libu64/gfxprint.h b/include/libu64/gfxprint.h index 60a620e5..27c588b3 100644 --- a/include/libu64/gfxprint.h +++ b/include/libu64/gfxprint.h @@ -25,6 +25,14 @@ extern "C"{ #define GFXPRINT_KANA_MODE_KATAKANA 0 #define GFXPRINT_KANA_MODE_HIRAGANA 1 +#define GFXPRINT_CLEAR_GRADIENT_CHAR "\x8A" +#define GFXPRINT_ENABLE_GRADIENT_CHAR "\x8B" + +#define GFXPRINT_KATAKANA_MODE_CHAR "\x8C" +#define GFXPRINT_HIRAGANA_MODE_CHAR "\x8D" + +#define GFXPRINT_UNUSED_CHAR "\x8E" + /* NOTE: this should be a void return type but we're going to use a void* for readibility */ typedef void* (*PrintCallback)(void*, const char*, int); typedef struct gfxprint_obj { diff --git a/include/m_common_data.h b/include/m_common_data.h index 6ba449c7..40d99266 100644 --- a/include/m_common_data.h +++ b/include/m_common_data.h @@ -150,7 +150,8 @@ typedef struct common_data_s { /* 0x026110 */ Time_c time; /* 0x02613C */ Private_c* now_private; /* 0x026140 */ mHm_hs_c* now_home; - /* 0x026144 */ u8 tmp0[0x2614D - 0x26144]; + /* 0x026144 */ u8 map_flag; + /* 0x026145 */ u8 tmp0[0x2614D - 0x26145]; /* 0x02614D */ u8 transFadeDuration; /* 0x02614E */ u8 transWipeSpeed; /* 0x02614F */ u8 wipeType; /* maybe unused? */ @@ -175,7 +176,15 @@ typedef struct common_data_s { /* 0x02852E */ s16 goods_power; /* 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[0x02883E - 0x28558]; + /* 0x028558 */ u8 tmp1[0x0285C0 - 0x028558]; + /* 0x0285C0 */ s8 player_decoy_flag; + /* 0x0285C1 */ u8 _285C1[0x028838 - 0x0285C1]; + /* 0x028838 */ s8 player_bee_swell_flag; + /* 0x028839 */ s8 player_bee_chase_flag; + /* 0x02883A */ u8 goki_shocked_flag; + /* 0x02883B */ u8 time_changed_flag; + /* 0x02883C */ u8 unable_to_wade_flag; + /* 0x02883D */ u8 _02883D; /* 0x02883E */ u8 train_coming_flag; /* state tracker for when train is going to spawn/has spawned */ /* 0x02883F */ u8 train_exists_flag; /* state tracker for when train exists */ /* 0x028840 */ u8 train_control_state; /* current train state */ @@ -209,7 +218,9 @@ typedef struct common_data_s { /* 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]; + /* 0x02DB42 */ u16 select_last_select_no; + /* 0x02DB44 */ u16 select_last_top_no; + /* 0x02DB46 */ u8 tmp3[0x2DBB0 - 0x2DB46]; /* 0x02DBB0 */ s16 can_look_goki_count; /* 0x02DBB4 */ f32 rainbow_opacity; /* current opacity of rainbow (0.0f - 1.0f) */ /* 0x02DBB8 */ u32 event_flags[7]; /* TODO: make array size a definition/enum */ diff --git a/include/m_kankyo.h b/include/m_kankyo.h index 6050919e..a1856fcb 100644 --- a/include/m_kankyo.h +++ b/include/m_kankyo.h @@ -17,6 +17,15 @@ enum weather { mEnv_WEATHER_NUM }; +enum weather_intensity { + mEnv_WEATHER_INTENSITY_NONE, + mEnv_WEATHER_INTENSITY_LIGHT, + mEnv_WEATHER_INTENSITY_NORMAL, + mEnv_WEATHER_INTENSITY_HEAVY, + + mEnv_WEATHER_INTENSITY_NUM, +}; + extern int mEnv_NowWeather(); #ifdef __cplusplus diff --git a/include/m_name_table.h b/include/m_name_table.h index fa21cd0e..8ba766c9 100644 --- a/include/m_name_table.h +++ b/include/m_name_table.h @@ -420,6 +420,8 @@ extern int mNT_check_unknown(mActor_name_t item_no); #define ITM_TOOL_END (ITM_LEAF_FAN + 1) #define ITM_CLOTH_START 0x2400 +#define ITM_CLOTH000 ITM_CLOTH_START +#define ITM_CLOTH001 (ITM_CLOTH_START + 1) #define ITM_CLOTH_END 0x24FF #define ITM_DUST0_EMPTY_CAN 0x250E diff --git a/include/m_npc.h b/include/m_npc.h index 4d670ddf..a4c5cabf 100644 --- a/include/m_npc.h +++ b/include/m_npc.h @@ -191,6 +191,8 @@ extern void mNpc_FirstClearGoodbyMail(); extern void mNpc_ClearIslandNpcRoomData(); extern void mNpc_CopyAnimalPersonalID(AnmPersonalID_c* dst, AnmPersonalID_c* src); extern AnmPersonalID_c* mNpc_GetOtherAnimalPersonalID(AnmPersonalID_c* ids, int num_ids); +extern void mNpc_ClearEventNpc(); +extern void mNpc_ClearMaskNpc(); extern void mNpc_PrintRemoveInfo(gfxprint_t* gfxprint); extern void mNpc_PrintFriendship_fdebug(gfxprint_t* gfxprint); diff --git a/include/m_private.h b/include/m_private.h index 0e66f697..83c1a9ee 100644 --- a/include/m_private.h +++ b/include/m_private.h @@ -36,6 +36,26 @@ enum { mPr_ITEM_COND_NUM }; +enum { + mPr_SEX_MALE, + mPr_SEX_FEMALE, + + mPr_SEX_NUM +}; + +enum { + mPr_FACE_TYPE0, + mPr_FACE_TYPE1, + mPr_FACE_TYPE2, + mPr_FACE_TYPE3, + mPr_FACE_TYPE4, + mPr_FACE_TYPE5, + mPr_FACE_TYPE6, + mPr_FACE_TYPE7, + + mPr_FACE_TYPE_NUM +}; + #define mPr_ECARD_NUM 367 #define mPr_ECARD_LETTER_NUM ((mPr_ECARD_NUM + 7) / 8) // 46 @@ -47,8 +67,23 @@ enum { #define mPr_FOREIGN_MAP_COUNT 8 #define mPr_ORIGINAL_DESIGN_COUNT 8 -#define mPr_SUNBURN_MIN_RANK 0 -#define mPr_SUNBURN_MAX_RANK 8 +enum { + mPr_SUNBURN_RANK_MIN, + + mPr_SUNBURN_RANK0 = mPr_SUNBURN_RANK_MIN, + mPr_SUNBURN_RANK1, + mPr_SUNBURN_RANK2, + mPr_SUNBURN_RANK3, + mPr_SUNBURN_RANK4, + mPr_SUNBURN_RANK5, + mPr_SUNBURN_RANK6, + mPr_SUNBURN_RANK7, + mPr_SUNBURN_RANK8, + + mPr_SUNBURN_RANK_MAX = mPr_SUNBURN_RANK8, + + mPr_SUNBURN_RANK_NUM +}; enum { mPr_DESTINY_NORMAL, /* standard fortune state */ diff --git a/include/m_rcp.h b/include/m_rcp.h index 8a24d73a..bca60e14 100644 --- a/include/m_rcp.h +++ b/include/m_rcp.h @@ -15,6 +15,7 @@ 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); +extern void rect_moji(GRAPH* graph); #ifdef __cplusplus } diff --git a/include/m_scene_table.h b/include/m_scene_table.h index 0133fd53..599a978e 100644 --- a/include/m_scene_table.h +++ b/include/m_scene_table.h @@ -21,6 +21,8 @@ enum field_draw_type { there may be a better place for this */ +#define SCENE_INVALID -1 + enum scene_table { SCENE_TEST1, SCENE_TEST2, @@ -31,25 +33,51 @@ enum scene_table { SCENE_NPC_HOUSE, /* npc house interior */ SCENE_FG, /* outdoors/FG */ SCENE_RANDOM_NPC_TEST, - SCENE_SHOP0 = 0x09, /* nook's cranny */ - SCENE_BROKER_SHOP = 0x0C, /* crazy redd's tent */ - SCENE_POST_OFFICE = 0x0E, /* post office */ - SCENE_START_DEMO = 0x0F, /* after player select */ - SCENE_START_DEMO2 = 0x10, /* */ - SCENE_BUGGY = 0x12, - SCENE_PLAYERSELECT = 0x13, - SCENE_CONVENI = 0x17, /* nook 'n' go */ - SCENE_SUPER = 0x18, /* nookway */ - SCENE_DEPART = 0x19, /* nookington's 1st floor */ - SCENE_DEPART_2 = 0x1D, /* nookington's 2nd floor */ - SCENE_TITLE_DEMO = 0x21, /* title screen demo */ - SCENE_PLAYERSELECT_SAVE = 0x22, - SCENE_MUSEUM_ENTRANCE = 0x23, - SCENE_MUSEUM_ROOM = 0x24, - SCENE_NEEDLEWORK = 0x2E, /* able sister's */ - SCENE_COTTAGE_MY = 0x2F, - SCENE_COTTAGE_NPC = 0x30, - /* TODO: finish */ + SCENE_SHOP0, /* nook's cranny */ + SCENE_BG_TEST_NO_RIVER, + SCENE_BG_TEST_RIVER, + SCENE_BROKER_SHOP, /* crazy redd's tent */ + SCENE_FIELD_TOOL_INSIDE, + SCENE_POST_OFFICE, /* post office */ + SCENE_START_DEMO, /* after player select */ + SCENE_START_DEMO2, /* */ + SCENE_POLICE_BOX, + SCENE_BUGGY, + SCENE_PLAYERSELECT, + SCENE_MY_ROOM_S, + SCENE_MY_ROOM_M, + SCENE_MY_ROOM_L, + SCENE_CONVENI, /* nook 'n' go */ + SCENE_SUPER, /* nookway */ + SCENE_DEPART, /* nookington's 1st floor */ + SCENE_TEST5, + SCENE_PLAYERSELECT_2, + SCENE_PLAYERSELECT_3, + SCENE_DEPART_2, /* nookington's 2nd floor */ + SCENE_EVENT_ANNOUNCEMENT, + SCENE_KAMAKURA, + SCENE_FIELD_TOOL, + SCENE_TITLE_DEMO, /* title screen demo */ + SCENE_PLAYERSELECT_SAVE, + SCENE_MUSEUM_ENTRANCE, + SCENE_MUSEUM_ROOM_PAINTING, + SCENE_MUSEUM_ROOM_FOSSIL, + SCENE_MUSEUM_ROOM_INSECT, + SCENE_MUSEUM_ROOM_FISH, + SCENE_MY_ROOM_LL1, + SCENE_MY_ROOM_LL2, + SCENE_MY_ROOM_BASEMENT_S, + SCENE_MY_ROOM_BASEMENT_M, + SCENE_MY_ROOM_BASEMENT_L, + SCENE_MY_ROOM_BASEMENT_LL1, + SCENE_NEEDLEWORK, /* able sister's */ + SCENE_COTTAGE_MY, + SCENE_COTTAGE_NPC, + SCENE_START_DEMO3, + SCENE_LIGHTHOUSE, + SCENE_TENT, + + SCENE_NUM }; #ifdef __cplusplus diff --git a/include/m_select.h b/include/m_select.h index e9d9d3e2..64eea26c 100644 --- a/include/m_select.h +++ b/include/m_select.h @@ -4,11 +4,41 @@ #include "types.h" #include "game.h" #include "m_view.h" +#include "m_private.h" #ifdef __cplusplus extern "C" { #endif +#define SELECT_COURSE_NUM_VISIBLE 14 + +typedef void (*GAME_PROC)(GAME*, int); + +enum { + SELECT_CHECK_A_BUTTON_RTC, + SELECT_CHECK_A_BUTTON_TIME, + SELECT_CHECK_A_BUTTON_STEP, + SELECT_CHECK_A_BUTTON_WEATHER, + SELECT_CHECK_A_BUTTON_SEX, + SELECT_CHECK_A_BUTTON_FACE_TYPE, + SELECT_CHECK_A_BUTTON_SWELL, + SELECT_CHECK_A_BUTTON_DECOY, + SELECT_CHECK_A_BUTTON_CLOTH, + SELECT_CHECK_A_BUTTON_SUNBURN, + SELECT_CHECK_A_BUTTON_EVENT, + + SELECT_CHECK_A_BUTTON_NUM +}; + +enum { + SELECT_STATUS_MAIN, + SELECT_STATUS_SETUP, + SELECT_STATUS_TIME_SET, + SELECT_STATUS_CLOTH_SEL, + + SELECT_STATUS_NUM +}; + /* sizeof(struct game_select_s) == 0x0238 */ typedef struct game_select_s { /* 0x0000 */ GAME game; @@ -22,12 +52,12 @@ typedef struct game_select_s { /* 0x0218 */ int top_course; /* course at top of screen it seems */ /* 0x021C */ u32 unk_21C; /* 0x0220 */ int button_step; - /* 0x0224 */ u8 name[8]; + /* 0x0224 */ u8 name[PLAYER_NAME_LEN]; /* 0x0228 */ int unk_228[3]; } GAME_SELECT; -extern void select_init(GAME_SELECT* select); -extern void select_cleanup(GAME_SELECT* select); +extern void select_init(GAME* game); +extern void select_cleanup(GAME* game); #ifdef __cplusplus } diff --git a/include/m_time.h b/include/m_time.h index 4dbe640b..47f08660 100644 --- a/include/m_time.h +++ b/include/m_time.h @@ -71,6 +71,8 @@ typedef struct time_calendar_term_s { s16 bgitem_bank; } mTM_calendar_term_t; +extern void mTM_set_renew_time(lbRTC_ymd_t* renew_time, lbRTC_time_c* rtc_time); + extern const lbRTC_time_c mTM_rtcTime_clear_code; extern const lbRTC_ymd_t mTM_rtcTime_ymd_clear_code; extern const lbRTC_time_c mTM_rtcTime_default_code; diff --git a/rel/m_select.c b/rel/m_select.c new file mode 100644 index 00000000..2076db24 --- /dev/null +++ b/rel/m_select.c @@ -0,0 +1,1340 @@ +#include "m_select.h" + +#include "m_play.h" +#include "m_private.h" +#include "m_home.h" +#include "m_kabu_manager.h" +#include "m_font.h" +#include "m_time.h" +#include "m_scene.h" +#include "m_controller.h" +#include "m_kankyo.h" +#include "audio.h" +#include "libu64/gfxprint.h" +#include "m_name_table.h" +#include "libc64/qrand.h" +#include "m_rcp.h" +#include "main.h" +#include "m_npc.h" +#include "m_field_info.h" +#include "m_common_data.h" + +static void game_next_play(GAME* game, int scene_no) { + Save_Set(scene_no, scene_no); + + GAME_GOTO_NEXT(game, play, PLAY); + mHm_SetNowHome(); + Common_Set(door_data.next_scene_id, 0); + Kabu_decide_price_schedule(); + Common_Set(map_flag, TRUE); +} + +typedef struct namefunc_s { + const char* name; + GAME_PROC next_play_proc; + int scene_no; +} namefunc_t; + +#define nf_str(s0, s1) (s0 GFXPRINT_KATAKANA_MODE_CHAR s1) +static namefunc_t nf_tbl[SCENE_NUM] = { + { + nf_str(" 1:", "フィールド コース1"), + &game_next_play, + SCENE_TEST1 + }, + { + nf_str(" 2:", "フィールド コース2"), + &game_next_play, + SCENE_TEST2 + }, + { + nf_str(" 3:", "フィールデ コース3"), + &game_next_play, + SCENE_TEST3 + }, + { + nf_str(" 4:", "オミズテスト コース"), + &game_next_play, + SCENE_WATER_TEST + }, + { + nf_str(" 5:", "アシアトテストコース"), + &game_next_play, + SCENE_FOOTPRINT_TEST + }, + { + nf_str(" 6:", "npc テストコース"), + &game_next_play, + SCENE_NPC_TEST + }, + { + nf_str(" 7:", "NPCアレンジルーム"), + &game_next_play, + SCENE_NPC_HOUSE + }, + { + nf_str(" 8:", "NPCランダムコース"), + &game_next_play, + SCENE_FG + }, + { + nf_str(" 9:", "FGツール フィールドヨウ"), + &game_next_play, + SCENE_RANDOM_NPC_TEST + }, + { + nf_str("10:", "オミセ"), + &game_next_play, + SCENE_SHOP0 + }, + { + nf_str("11:", "BGプレビュー カワナシ"), + &game_next_play, + SCENE_BG_TEST_NO_RIVER + }, + { + nf_str("12:", "BGプレビュー カワアリ"), + &game_next_play, + SCENE_BG_TEST_RIVER + }, + { + nf_str("13:", "ヤミブローカーノ オミセ"), + &game_next_play, + SCENE_BROKER_SHOP + }, + { + nf_str("14:", "FGツール ヘヤノナカヨウ"), + &game_next_play, + SCENE_FIELD_TOOL_INSIDE + }, + { + nf_str("15:", "ユウビンキョク"), + &game_next_play, + SCENE_POST_OFFICE + }, + { + nf_str("16:", "start demo 1"), + &game_next_play, + SCENE_START_DEMO + }, + { + nf_str("17:", "start demo 2"), + &game_next_play, + SCENE_START_DEMO2 + }, + { + nf_str("18:", "コウバン"), + &game_next_play, + SCENE_POLICE_BOX + }, + { + nf_str("19:", "ホロバシャ"), + &game_next_play, + SCENE_BUGGY + }, + { + nf_str("20:", "プレーヤー セレクト"), + &game_next_play, + SCENE_PLAYERSELECT + }, + { + nf_str("21:", "マイルーム size S"), + &game_next_play, + SCENE_MY_ROOM_S + }, + { + nf_str("22:", "マイルーム size M"), + &game_next_play, + SCENE_MY_ROOM_M + }, + { + nf_str("23:", "マイルーム size L"), + &game_next_play, + SCENE_MY_ROOM_L + }, + { + nf_str("24:", "コンビニ"), + &game_next_play, + SCENE_CONVENI + }, + { + nf_str("25:", "スーパー"), + &game_next_play, + SCENE_SUPER + }, + { + nf_str("26:", "デパート1F"), + &game_next_play, + SCENE_DEPART + }, + { + nf_str("27:", "テストコース 5"), + &game_next_play, + SCENE_TEST5 + }, + { + nf_str("28:", "プレーヤー セレクト 2"), + &game_next_play, + SCENE_PLAYERSELECT_2 + }, + { + nf_str("29:", "プレーヤー セレクト 3"), + &game_next_play, + SCENE_PLAYERSELECT_3 + }, + { + nf_str("30:", "デパート2F"), + &game_next_play, + SCENE_DEPART_2 + }, + { + nf_str("31:", "イベント コクチ"), + &game_next_play, + SCENE_EVENT_ANNOUNCEMENT + }, + { + nf_str("32:", "カマクラ"), + &game_next_play, + SCENE_KAMAKURA + }, + { + nf_str("33:", "for field tool"), + &game_next_play, + SCENE_FIELD_TOOL + }, + { + nf_str("34:", "キャクマチ デモ"), + &game_next_play, + SCENE_TITLE_DEMO + }, + { + nf_str("35:", "プレーヤー セレクト 4"), + &game_next_play, + SCENE_PLAYERSELECT_SAVE + }, + { + nf_str("36:", "museum-エントランス"), + &game_next_play, + SCENE_MUSEUM_ENTRANCE + }, + { + nf_str("37:", "museum-カイガ"), + &game_next_play, + SCENE_MUSEUM_ROOM_PAINTING + }, + { + nf_str("38:", "museum-カセキ"), + &game_next_play, + SCENE_MUSEUM_ROOM_FOSSIL + }, + { + nf_str("39:", "museum-インセクト"), + &game_next_play, + SCENE_MUSEUM_ROOM_INSECT + }, + { + nf_str("40:", "museum-フィッシュ"), + &game_next_play, + SCENE_MUSEUM_ROOM_FISH + }, + { + nf_str("41:", "マイルーム size LL1"), + &game_next_play, + SCENE_MY_ROOM_LL1 + }, + { + nf_str("42:", "マイルーム size LL2"), + &game_next_play, + SCENE_MY_ROOM_LL2 + }, + { + nf_str("43:", "マイルーム チカ -> S"), + &game_next_play, + SCENE_MY_ROOM_BASEMENT_S + }, + { + nf_str("44:", "マイルーム チカ -> M"), + &game_next_play, + SCENE_MY_ROOM_BASEMENT_M + }, + { + nf_str("45:", "マイルーム チカ -> L"), + &game_next_play, + SCENE_MY_ROOM_BASEMENT_L + }, + { + nf_str("46:", "マイルーム チカ -> LL1"), + &game_next_play, + SCENE_MY_ROOM_BASEMENT_LL1 + }, + { + nf_str("47:", "シタテヤ"), + &game_next_play, + SCENE_NEEDLEWORK + }, + { + nf_str("48:", "シマノプレイヤノイエ"), + &game_next_play, + SCENE_COTTAGE_MY + }, + { + nf_str("49:", "シマノNPCノイエ"), + &game_next_play, + SCENE_COTTAGE_NPC + }, + { + nf_str("50:", "start demo 3"), + &game_next_play, + SCENE_START_DEMO3 + }, + { + nf_str("51:", "LIGHTHOUSE"), + &game_next_play, + SCENE_LIGHTHOUSE + }, + { + nf_str("52:", "In Tent"), + &game_next_play, + SCENE_TENT + } +}; + +static u8 data2fcode(u8 data) { + u8 fcode = CHAR_SPACE; + + if (data != 0) { + fcode = data + 0x90; + } + + return fcode; +} + +static u8 fcode2data(u8 fcode) { + u8 data = 0; + if (fcode != CHAR_SPACE) { + data = fcode - 0x90; + } + + return data; +} + +static void select_pass(GAME_SELECT* select) { + lbRTC_time_c* rtc_time = Common_GetPointer(time.rtc_time); + namefunc_t* nf_p; + int field_scene = Common_Get(scene_from_title_demo); + int sec = rtc_time->sec; + int min_sec = rtc_time->min * mTM_SECONDS_IN_MINUTE; + int hour_sec = rtc_time->hour * mTM_SECONDS_IN_HOUR; + + Common_Set(time.now_sec, hour_sec + min_sec + sec); + nf_p = nf_tbl + field_scene; + if (nf_p->next_play_proc != NULL) { + (*nf_p->next_play_proc)((GAME*)select, nf_p->scene_no); + } + + Common_Set(scene_from_title_demo, SCENE_INVALID); +} + +static int select_start_proc(GAME_SELECT* select) { + lbRTC_time_c* rtc_time = Common_GetPointer(time.rtc_time); + int sec = rtc_time->sec; + int min_sec = rtc_time->min * mTM_SECONDS_IN_MINUTE; + int hour_sec = rtc_time->hour * mTM_SECONDS_IN_HOUR; + + Common_Set(time.now_sec, hour_sec + min_sec + sec); + + { + namefunc_t* nf_p = nf_tbl + select->selected_course; + if (nf_p->next_play_proc != NULL) { + (*nf_p->next_play_proc)((GAME*)select, nf_p->scene_no); + } + } + + Common_Set(select_last_select_no, select->selected_course); + Common_Set(select_last_top_no, select->top_course); + + if (rtc_time->min == 0) { + Common_Set(time.time_signal, TRUE); + } + + { + int i; + + for (i = 0; i < PLAYER_NAME_LEN; i++) { + Common_Get(now_private)->player_ID.player_name[i] = data2fcode(select->name[i]); + } + } + + return TRUE; +} + +static int select_check_start(GAME_SELECT* select) { + if (select->status == 0) { + if (chkTrigger(BUTTON_START) || chkTrigger(BUTTON_A)) { + return select_start_proc(select); + } + } + else if (chkTrigger(BUTTON_START)) { + return select_start_proc(select); + } + + return FALSE; +} + +typedef int (*SELECT_CHECK_A_BUTTON_PROC)(GAME_SELECT*); + +static int select_check_A_button_rtc(GAME_SELECT* select) { + return FALSE; +} + +static int select_check_A_button_time(GAME_SELECT* select) { + return FALSE; +} + +static int select_check_A_button_step(GAME_SELECT* select) { + return FALSE; +} + +static int select_check_A_button_weather(GAME_SELECT* select) { + u8 save_weather; + int weather = Common_Get(weather); + weather++; + if (weather > mEnv_WEATHER_LEAVES || weather < mEnv_WEATHER_CLEAR) { + weather = mEnv_WEATHER_CLEAR; + } + + Common_Set(weather, weather); + Common_Set(weather_intensity, mEnv_WEATHER_INTENSITY_HEAVY); + + save_weather = mEnv_WEATHER_INTENSITY_HEAVY; + save_weather |= (u8)weather << 4; + Save_Set(weather, save_weather); + + return FALSE; +} + +static int select_check_A_button_sex(GAME_SELECT* select) { + int sex = Common_Get(now_private)->gender; + sex++; + Common_Get(now_private)->gender = sex % mPr_SEX_NUM; + + return FALSE; +} + +static int select_check_A_button_face_type(GAME_SELECT* select) { + int face_type = Common_Get(now_private)->face; + face_type++; + Common_Get(now_private)->face = face_type % mPr_FACE_TYPE_NUM; + + return FALSE; +} + +static int select_check_A_button_swell(GAME_SELECT* select) { + int swell = Common_Get(player_bee_swell_flag); + Common_Set(player_bee_swell_flag, !swell); + + return FALSE; +} + +static int select_check_A_button_sunburn(GAME_SELECT* select) { + lbRTC_ymd_t renew_time; + mPr_sunburn_c sunburn = Common_Get(now_private)->sunburn; + + mTM_set_renew_time(&renew_time, Common_GetPointer(time.rtc_time)); + sunburn.last_changed_date = renew_time; + + sunburn.rank++; + if (sunburn.rank >= mPr_SUNBURN_RANK_NUM) { + sunburn.rank = mPr_SUNBURN_RANK0; + } + + sunburn.rankdown_days = 2; + Common_Get(now_private)->sunburn = sunburn; + + return FALSE; +} + +static int select_check_A_button_decoy(GAME_SELECT* select) { + Common_Set(player_decoy_flag, !Common_Get(player_decoy_flag)); + + return FALSE; +} + +static int select_check_A_button_cloth(GAME_SELECT* select) { + return FALSE; +} + +static int select_check_A_button_event(GAME_SELECT* select) { + return FALSE; +} + +static int select_check_A_button(GAME_SELECT* select) { + static SELECT_CHECK_A_BUTTON_PROC process[SELECT_CHECK_A_BUTTON_NUM] = { + &select_check_A_button_rtc, + &select_check_A_button_time, + &select_check_A_button_step, + &select_check_A_button_weather, + &select_check_A_button_sex, + &select_check_A_button_face_type, + &select_check_A_button_swell, + &select_check_A_button_decoy, + &select_check_A_button_cloth, + &select_check_A_button_sunburn, + &select_check_A_button_event + }; + + if (chkTrigger(BUTTON_A)) { + return (*process[select->cursor_y])(select); + } + else { + return FALSE; + } +} + +static int select_move_cursol(GAME_SELECT* select) { + if (chkTrigger(BUTTON_DLEFT)) { + select->status = 0; + return TRUE; + } + else if (chkTrigger(BUTTON_DUP)) { + if (select->cursor_y == 0) { + select->cursor_y = SELECT_CHECK_A_BUTTON_NUM - 1; + } + else { + select->cursor_y--; + } + } + else if (chkTrigger(BUTTON_DDOWN)) { + select->cursor_y = (select->cursor_y + 1) % SELECT_CHECK_A_BUTTON_NUM; + } + + return FALSE; +} + +static int select_course_step_sub(int course) { + if (course < 0) { + return course + SCENE_NUM; + } + else if (course >= SCENE_NUM) { + return course - SCENE_NUM; + } + + return course; +} + +static int select_adjust_top_no(GAME_SELECT* select, int course, int adjust) { + int top = select->top_course; + int new_top = (top + SELECT_COURSE_NUM_VISIBLE) % SCENE_NUM; + + if (top < new_top) { + if (course <= top || course >= new_top) { + top = select_course_step_sub(top + adjust); + } + } + else if (course <= top && course >= new_top) { + top = select_course_step_sub(top + adjust); + } + + select->top_course = top; + return top; +} + +static void select_course_step(GAME_SELECT* select, int step_add) { + int new_step = select->step + step_add; + + if (ABS(new_step) >= 32) { + int course = select->selected_course; + sAdo_SysTrgStart(1); + + if (new_step > 0) { + new_step = 0; + course = select_course_step_sub(course + 1); + select_adjust_top_no(select, course, 1); + } + else { + new_step = 0; + course = select_course_step_sub(course - 1); + select_adjust_top_no(select, course, -1); + } + + select->step_add = 6; + select->selected_course = course; + } + + select->step = new_step; +} + +static void select_course(GAME_SELECT* select) { + int step_add; + int joystick_y; + if (chkTrigger(BUTTON_DUP)) { + if (select->step > 0) { + select->step = 0; + } + + select_course_step(select, -32); + select->step_add = 1; + } + else if (chkButton(BUTTON_DUP)) { + select_course_step(select, -select->step_add); + } + else if (chkTrigger(BUTTON_DDOWN)) { + if (select->step < 0) { + select->step = 0; + } + + select_course_step(select, 32); + select->step_add = 1; + } + else if (chkButton(BUTTON_DDOWN)) { + select_course_step(select, select->step_add); + } + else { + joystick_y = -getJoystick_Y(); + step_add = select->step_add; + + if (step_add == 0) { + if (joystick_y < 0) { + if (select->step > 0) { + select->step = 0; + } + + select_course_step(select, -32); + select->step_add = 1; + } + else if (joystick_y > 0) { + if (select->step < 0) { + select->step = 0; + } + + select_course_step(select, 32); + select->step_add = 1; + } + } + else { + if (joystick_y == 0) { + select->step_add = 0; + } + else if (joystick_y < 0) { + select_course_step(select, -step_add * 2); + } + else if (joystick_y > 0) { + select_course_step(select, step_add * 2); + } + } + } +} + +typedef void (*SELECT_MOVE_PROC)(GAME_SELECT*); + +static void select_move_main(GAME_SELECT* select) { + if (select_check_start(select) != TRUE) { + if (chkTrigger(BUTTON_DRIGHT)) { + select->status = 1; + } + else { + select_course(select); + } + } +} + +static void select_move_setup(GAME_SELECT* select) { + if (select_check_start(select) != TRUE && select_move_cursol(select) != TRUE) { + if (select_check_A_button(select) == TRUE) { + return; /* stubbed code */ + } + } +} + +typedef void (*SELECT_MOVE_TIME_PROC)(int); + +static void select_move_time_year_set(int adjust) { + int year = Common_Get(time.rtc_time.year); + year += adjust; + + if (year > lbRTC_YEAR_MAX) { + year -= ((lbRTC_YEAR_MAX - lbRTC_YEAR_MIN) + 1); + } + else if (year < lbRTC_YEAR_MIN) { + year = lbRTC_YEAR_MAX - ((lbRTC_YEAR_MIN - 1) - year); + } + + Common_Set(time.rtc_time.year, year); +} + +static void select_move_time_month_set(int adjust) { + static int season_table[lbRTC_MONTHS_MAX] = { + mTM_SEASON_WINTER, mTM_SEASON_WINTER, mTM_SEASON_SPRING, mTM_SEASON_SPRING, + mTM_SEASON_SPRING, mTM_SEASON_SUMMER, mTM_SEASON_SUMMER, mTM_SEASON_SUMMER, + mTM_SEASON_AUTUMN, mTM_SEASON_AUTUMN, mTM_SEASON_AUTUMN, mTM_SEASON_WINTER + }; + + int month = Common_Get(time.rtc_time.month) - 1; + u8 day; + month = (month + adjust) % lbRTC_MONTHS_MAX; + Common_Set(time.rtc_time.month, month + 1); + + day = lbRTC_GetDaysByMonth(Common_Get(time.rtc_time.year), month + 1); + if (Common_Get(time.rtc_time.day) > day) { + Common_Set(time.rtc_time.day, day); + } + + Common_Set(time.season, season_table[month]); +} + +static void select_move_time_day_set(int adjust) { + int max_day = lbRTC_GetDaysByMonth(Common_Get(time.rtc_time.year), Common_Get(time.rtc_time.month)); + int day = (Common_Get(time.rtc_time.day) + adjust) % (max_day + 1); + + if (day == 0) { + if (adjust > 0) { + day = 1; + } + else { + day = max_day; + } + } + + Common_Set(time.rtc_time.day, day); +} + +static void select_move_time_hour_set(int adjust) { + int hour = Common_Get(time.rtc_time.hour); + if (hour == 0 && adjust < 0) { + hour = lbRTC_HOURS_PER_DAY - 1; + } + else { + hour = (hour + adjust) % lbRTC_HOURS_PER_DAY; + } + + Common_Set(time.rtc_time.hour, hour); +} + +static void select_move_time_min_set(int adjust) { + int min = Common_Get(time.rtc_time.min); + + if (min == 0 && adjust < 0) { + min = lbRTC_MINUTES_PER_HOUR - 1; + } + else { + min = (min + adjust) % lbRTC_MINUTES_PER_HOUR; + } + + Common_Set(time.rtc_time.min, min); +} + +static void select_move_time_week_set(int adjust) { + static lbRTC_time_c base = { + 0, 0, 0, // 00:00:00 + 1, lbRTC_SATURDAY, lbRTC_JANUARY, // Sunday Jan 1st + 2000 + }; + + if (adjust != 0) { + u32 interval = lbRTC_IntervalTime(Common_GetPointer(time.rtc_time), &base); + /* minutes -> days */ + interval = interval / (lbRTC_HOURS_PER_DAY * lbRTC_MINUTES_PER_HOUR) + (lbRTC_WEEK - 1); + Common_Set(time.rtc_time.weekday, interval % lbRTC_WEEK); + } +} + +static void select_move_time_set(GAME_SELECT* select) { + if (chkTrigger(BUTTON_A) || chkTrigger(BUTTON_START)) { + select->status = 1; + if (Common_Get(time.rtc_enabled) == TRUE) { + lbRTC_SetTime(Common_GetPointer(time.rtc_time)); + } + } + else if (chkTrigger(BUTTON_DLEFT)) { + if (select->cursor_x == 0) { + select->cursor_x = 4; + } + else { + select->cursor_x--; + } + } + else if (chkTrigger(BUTTON_DRIGHT)) { + select->cursor_x = (select->cursor_x + 1) % 5; + } + else { + int adjust = 0; + + if (chkButton(BUTTON_DDOWN)) { + if (chkTrigger(BUTTON_DDOWN)) { + adjust = -1; + select->button_step = -16; + } + + select->button_step++; + if (select->button_step == 6) { + adjust = -1; + select->button_step = 0; + } + } + + if (chkButton(BUTTON_DUP)) { + if (chkTrigger(BUTTON_DUP)) { + adjust = 1; + select->button_step = 16; + } + + select->button_step--; + if (select->button_step == -6) { + adjust = 1; + select->button_step = 0; + } + } + + if (chkButton(BUTTON_B)) { + adjust *= 10; + } + + { + static SELECT_MOVE_TIME_PROC process[5] = { + &select_move_time_year_set, + &select_move_time_month_set, + &select_move_time_day_set, + &select_move_time_hour_set, + &select_move_time_min_set + }; + + int i; + + for (i = 0; i < 5; i++) { + if (i == select->cursor_x) { + (*process[i])(adjust); + select_move_time_week_set(adjust); + } + } + + if (adjust != 0 && Common_Get(time.rtc_enabled) == TRUE) { + lbRTC_SetTime(Common_GetPointer(time.rtc_time)); + } + } + } +} + +static void select_move_cloth_sel(GAME_SELECT* select) { + if (chkTrigger(BUTTON_A) || chkTrigger(BUTTON_START)) { + select->status = 1; + } + else { + int cloth = Common_Get(now_private)->cloth - ITM_CLOTH001; // shouldn't this be CLOTH000? + int adjust = (chkButton(BUTTON_B)) ? 10 : 1; + + if (chkButton(BUTTON_DDOWN)) { + if (chkTrigger(BUTTON_DDOWN)) { + cloth += adjust; + select->button_step = -16; + } + + select->button_step++; + if (select->button_step == 6) { + cloth += adjust; + select->button_step = 0; + } + } + + if (chkButton(BUTTON_DUP)) { + if (chkTrigger(BUTTON_DUP)) { + cloth -= adjust; + select->button_step = 16; + } + + select->button_step--; + if (select->button_step == -6) { + cloth -= adjust; + select->button_step = 0; + } + } + + while (cloth < 0) { + cloth += CLOTH_NUM; + } + + while (cloth > CLOTH_NUM - 1) { + cloth -= CLOTH_NUM; + } + + Common_Get(now_private)->cloth = ITM_CLOTH001 + cloth; + } +} + +static void select_move(GAME_SELECT* select) { + static SELECT_MOVE_PROC process[SELECT_STATUS_NUM] = { + &select_move_main, + &select_move_setup, + &select_move_time_set, + &select_move_cloth_sel + }; + + if (Common_Get(scene_from_title_demo) >= 0) { + select_pass(select); + } + else { + (*process[select->status])(select); + } +} + +typedef void (*SELECT_PRINT_PROC)(gfxprint_t*, GAME_SELECT*); + +static void select_print_wait(gfxprint_t* gfxprint) { + static const char* msgs[12] = { + GFXPRINT_HIRAGANA_MODE_CHAR "シバラクオマチクダサイ", /* (しばらくお待ち下さい) "Please wait for a bit" */ + GFXPRINT_HIRAGANA_MODE_CHAR "チョット マッテネ", /* (ちょっと 待ってね) "Wait a minute" */ + GFXPRINT_KATAKANA_MODE_CHAR "ウェイト ア モーメント", /* "Wait a moment" */ + GFXPRINT_KATAKANA_MODE_CHAR "ロード" GFXPRINT_HIRAGANA_MODE_CHAR "チュウ", /* (ロード中) "Loading" */ + GFXPRINT_HIRAGANA_MODE_CHAR "ナウ ワーキング", /* "Now working" */ + GFXPRINT_HIRAGANA_MODE_CHAR "イマ ツクッテマス", /* (今つくってます) "Now making" */ + GFXPRINT_HIRAGANA_MODE_CHAR "コショウジャナイヨ", /* (故障じゃないよ) "It's not faulty" */ + GFXPRINT_KATAKANA_MODE_CHAR "コーヒー ブレイク", /* "coffee break" */ + GFXPRINT_KATAKANA_MODE_CHAR "Bメンヲセットシテクダサイ", /* (Bメンヲ セットしてください) "Please set the B menu" */ + GFXPRINT_HIRAGANA_MODE_CHAR "ジット" GFXPRINT_KATAKANA_MODE_CHAR "ガマン" GFXPRINT_HIRAGANA_MODE_CHAR "ノ" GFXPRINT_KATAKANA_MODE_CHAR "コ" GFXPRINT_HIRAGANA_MODE_CHAR "デアッタ", /* (ジっと我慢のこであった) "I am patient" */ + GFXPRINT_HIRAGANA_MODE_CHAR "イマシバラクオマチクダサイ", /* (今しばらくお待ちください) "Please wait a moment now" */ + GFXPRINT_HIRAGANA_MODE_CHAR "アワテナイアワテナイ。ヒトヤスミヒトヤスミ。" /* (あわてないあわてない。 ひとやすみひとやすみ。) "Don't rush, don't rush. Take a break, take a break." */ + }; + + int msg_no; + + gfxprint_locate8x8(gfxprint, 10, 15); + gfxprint_color(gfxprint, 255, 255, 255, 255); + + msg_no = fqrand() * 12.0f; + gfxprint_printf(gfxprint, "%s", msgs[msg_no]); +} + +#pragma pool_data on +static void select_print_course_name(GAME_SELECT* select, gfxprint_t* gfxprint) { + const char* name; + int i; + + gfxprint_color(gfxprint, 255, 155, 150, 255); + gfxprint_locate8x8(gfxprint, 12, 2); + gfxprint_printf(gfxprint, "FOREST MAP SELECT"); + + + gfxprint_color(gfxprint, 255, 255, 255, 255); + for (i = 0; i < 15; i++) { + int course; + + gfxprint_locate8x8(gfxprint, 5, i + 4); + course = (select->top_course + i + SCENE_NUM) % SCENE_NUM; + if (course == select->selected_course) { + if (select->status != 0) { + gfxprint_color(gfxprint, 255, 120, 120, 255); + + } + else { + gfxprint_color(gfxprint, 255, 20, 20, 255); + } + } + else { + gfxprint_color(gfxprint, 200, 200, 55, 255); + } + + name = nf_tbl[course].name; + if (name == NULL) { + name = "**Null**"; + } + + gfxprint_printf(gfxprint, "%s", name); + } +} +#pragma pool_data reset + +static void select_print_rtc(gfxprint_t* gfxprint, GAME_SELECT* select) { + gfxprint_locate8x8(gfxprint, 23, 6); + gfxprint_printf(gfxprint, "RTC Z:USE"); +} + +#pragma pool_data on +static void select_print_time_sub(gfxprint_t* gfxprint, GAME_SELECT* select, lbRTC_time_c* time) { + const char* weekday_name; + + gfxprint_locate8x8(gfxprint, 23, 7); + gfxprint_printf(gfxprint, "%04d/%02d/%02d", time->year, time->month, time->day); + + gfxprint_locate8x8(gfxprint, 33, 7); + switch(time->weekday) { + case lbRTC_SUNDAY: + weekday_name = "SUN"; + break; + + case lbRTC_MONDAY: + weekday_name = "MON"; + break; + + case lbRTC_TUESDAY: + weekday_name = "TUE"; + break; + + case lbRTC_WEDNESDAY: + weekday_name = "WED"; + break; + + case lbRTC_THURSDAY: + weekday_name = "THU"; + break; + + case lbRTC_FRIDAY: + weekday_name = "FRI"; + break; + + case lbRTC_SATURDAY: + weekday_name = "SAT"; + break; + + default: + weekday_name = "---"; + break; + } + + gfxprint_printf(gfxprint, "<%s>", weekday_name); + + gfxprint_locate8x8(gfxprint, 28, 8); + gfxprint_printf(gfxprint, "%02d:%02d", time->hour, time->min); + + if (select->status == SELECT_STATUS_TIME_SET) { + gfxprint_color(gfxprint, 255, 180, 180, 255); + + switch (select->cursor_x) { + case 0: + { + gfxprint_locate8x8(gfxprint, 23, 7); + gfxprint_printf(gfxprint, "%04d", time->year); + break; + } + + case 1: + { + gfxprint_locate8x8(gfxprint, 28, 7); + gfxprint_printf(gfxprint, "%02d", time->month); + break; + } + + case 2: + { + gfxprint_locate8x8(gfxprint, 31, 7); + gfxprint_printf(gfxprint, "%02d", time->day); + break; + } + + case 3: + { + gfxprint_locate8x8(gfxprint, 28, 8); + gfxprint_printf(gfxprint, "%02d", time->hour); + break; + } + + case 4: + { + gfxprint_locate8x8(gfxprint, 31, 8); + gfxprint_printf(gfxprint, "%02d", time->min); + break; + } + } + } +} +#pragma pool_data reset + +static void select_print_time(gfxprint_t* gfxprint, GAME_SELECT* select) { + lbRTC_time_c time; + + lbRTC_GetTime(&time); + select_print_time_sub(gfxprint, select, &time); +} + +static void select_print_step_sub2(gfxprint_t* gfxprint) { + gfxprint_locate8x8(gfxprint, 23, 9); + gfxprint_printf(gfxprint, GFXPRINT_KATAKANA_MODE_CHAR "ステップ :**m**s"); +} + +static void select_print_step(gfxprint_t* gfxprint, GAME_SELECT* select) { + select_print_step_sub2(gfxprint); +} + +static void select_print_weather(gfxprint_t* gfxprint, GAME_SELECT* select) { + static const char* Weather_type[mEnv_WEATHER_NUM] = { + GFXPRINT_HIRAGANA_MODE_CHAR "ハレ", // 晴れ (clear/fine) + GFXPRINT_HIRAGANA_MODE_CHAR "アメ", // 雨 (rain) + GFXPRINT_HIRAGANA_MODE_CHAR "ユキ", // 雪 (snow) + GFXPRINT_HIRAGANA_MODE_CHAR "サクラ", // 桜 (cherry blossoms) + GFXPRINT_HIRAGANA_MODE_CHAR "ランダム" // "random" (should be leaves seen in K.K. Slider demo) + }; + + gfxprint_locate8x8(gfxprint, 23, 10); + gfxprint_printf(gfxprint, GFXPRINT_HIRAGANA_MODE_CHAR "テンキ :%s", Weather_type[Common_Get(weather)]); +} + +static void select_print_sex(gfxprint_t* gfxprint, GAME_SELECT* select) { + static const char* Distinction[mPr_SEX_NUM] = { + GFXPRINT_HIRAGANA_MODE_CHAR "オトコノコ", // 男の子 (boy) + GFXPRINT_HIRAGANA_MODE_CHAR "オンナノコ" // 女の子 (girl) + }; + + gfxprint_locate8x8(gfxprint, 23, 11); + gfxprint_printf(gfxprint, "セイベツ :%s", Distinction[Common_Get(now_private)->gender]); +} + +static void select_print_cloth(gfxprint_t* gfxprint, GAME_SELECT* select) { + gfxprint_locate8x8(gfxprint, 23, 15); + if (select->status == SELECT_STATUS_CLOTH_SEL) { + gfxprint_color(gfxprint, 255, 180, 180, 255); + } + + gfxprint_printf(gfxprint, "フク :%03d", Common_Get(now_private)->cloth - ITM_CLOTH_START); +} + +static void select_print_swell(gfxprint_t* gfxprint, GAME_SELECT* select) { + int swell = Common_Get(player_bee_swell_flag); + gfxprint_locate8x8(gfxprint, 23, 13); + + if (swell == FALSE) { + gfxprint_printf(gfxprint, "ムシササレ :イタクナイ"); // 虫刺され: 痛くない (sting: painless) + } + else { + gfxprint_printf(gfxprint, "ムシササレ :イタソウ"); // 虫刺され: 痛そう (sting: painful) + } +} + +static void select_print_decoy(gfxprint_t* gfxprint, GAME_SELECT* select) { + int decoy = Common_Get(player_decoy_flag); + gfxprint_locate8x8(gfxprint, 23, 14); + + if (decoy == FALSE) { + gfxprint_printf(gfxprint, "データ :モノホン"); // (data: genuine) + } + else { + gfxprint_printf(gfxprint, "データ :カゲムシャ"); // (data: double) [double meaning body double/puppet master] + } +} + +static void select_print_face_type(gfxprint_t* gfxprint, GAME_SELECT* select) { + static const char* Distinction[mPr_FACE_TYPE_NUM] = { + GFXPRINT_HIRAGANA_MODE_CHAR "タイプ1", + GFXPRINT_HIRAGANA_MODE_CHAR "タイプ2", + GFXPRINT_HIRAGANA_MODE_CHAR "タイプ3", + GFXPRINT_HIRAGANA_MODE_CHAR "タイプ4", + GFXPRINT_HIRAGANA_MODE_CHAR "タイプ5", + GFXPRINT_HIRAGANA_MODE_CHAR "タイプ6", + GFXPRINT_HIRAGANA_MODE_CHAR "タイプ7", + GFXPRINT_HIRAGANA_MODE_CHAR "タイプ8" + }; + + gfxprint_locate8x8(gfxprint, 23, 12); + gfxprint_printf(gfxprint, "カオ :%s", Distinction[Common_Get(now_private)->face]); +} + +static void select_print_sunburn(gfxprint_t* gfxprint, GAME_SELECT* select) { + mPr_sunburn_c* sunburn = &Common_Get(now_private)->sunburn; + int rank = sunburn->rank; + + gfxprint_locate8x8(gfxprint, 23, 16); + gfxprint_printf(gfxprint, "ヒヤケ :%d %d/%d", rank, sunburn->last_changed_date.month, sunburn->last_changed_date.day); +} + +static void select_print_event(gfxprint_t* gfxprint, GAME_SELECT* select) { + static const char* event_kind[] = { + GFXPRINT_KATAKANA_MODE_CHAR "---", + GFXPRINT_KATAKANA_MODE_CHAR "ザッカヤ", // (雑貨屋) (general store/shop) + GFXPRINT_KATAKANA_MODE_CHAR "デザイナ-", // designer + GFXPRINT_KATAKANA_MODE_CHAR "ブロ-カ-", // broker + GFXPRINT_KATAKANA_MODE_CHAR "ガハク", // (画伯) artist + GFXPRINT_KATAKANA_MODE_CHAR "ジュウタン", // (絨毯) carpet + GFXPRINT_KATAKANA_MODE_CHAR "クロヒョウ" // (黒豹) black panther + }; + + gfxprint_locate8x8(gfxprint, 23, 17); + gfxprint_printf(gfxprint, GFXPRINT_KATAKANA_MODE_CHAR "イベント :%s", event_kind[0]); +} + +static void select_draw_main(GAME_SELECT* select) { + static SELECT_PRINT_PROC print_process[11] = { + &select_print_rtc, + &select_print_time, + &select_print_step, + &select_print_weather, + &select_print_sex, + &select_print_face_type, + &select_print_swell, + &select_print_decoy, + &select_print_cloth, + &select_print_sunburn, + &select_print_event + }; + + rect screen; + GRAPH* g = select->game.graph; + + OPEN_DISP(g); + + gSPSegment(NOW_BG_OPA_DISP++, G_MWO_SEGMENT_0, 0); + gSPSegment(NOW_POLY_OPA_DISP++, G_MWO_SEGMENT_0, 0); + + DisplayList_initialize(g, 0, 0, 0, NULL); + + { + screen.top = 0; + screen.bottom = SCREEN_HEIGHT; + screen.l = 0; + screen.r = SCREEN_WIDTH; + + setScissorView(&select->view, &screen); + showView(&select->view, VIEW_UPDATE_ALL); + } + + rect_moji(g); + + { + gfxprint_t* gfxprint_p = __alloca(sizeof(gfxprint_t)); + int i; + gfxprint_init(gfxprint_p); + gfxprint_open(gfxprint_p, NOW_POLY_OPA_DISP); + + select_print_course_name(select, gfxprint_p); + + gfxprint_color(gfxprint_p, 200, 200, 55, 255); + gfxprint_locate8x8(gfxprint_p, 26, 4); + gfxprint_printf(gfxprint_p, GFXPRINT_HIRAGANA_MODE_CHAR "-セッテイ-"); // -settings- + + for (i = 0; i < 11; i++) { + if (select->cursor_y == i) { + if (select->status == SELECT_STATUS_MAIN) { + gfxprint_color(gfxprint_p, 180, 180, 255, 255); + } + else { + gfxprint_color(gfxprint_p, 120, 120, 255, 255); + } + } + else { + gfxprint_color(gfxprint_p, 255, 255, 55, 255); + } + + (*print_process[i])(gfxprint_p, select); + } + + SET_POLY_OPA_DISP(gfxprint_close(gfxprint_p)); + + + gfxprint_cleanup(gfxprint_p); + } + CLOSE_DISP(g); +} + +static void select_draw_wait(GAME_SELECT* select) { + GRAPH* g = select->game.graph; + + OPEN_DISP(g); + + gSPSegment(NOW_BG_OPA_DISP++, G_MWO_SEGMENT_0, 0); + gSPSegment(NOW_POLY_OPA_DISP++, G_MWO_SEGMENT_0, 0); + + DisplayList_initialize(g, 0, 0, 0, NULL); + + { + rect screen; + + screen.top = 0; + screen.bottom = SCREEN_HEIGHT; + screen.l = 0; + screen.r = SCREEN_WIDTH; + + setScissorView(&select->view, &screen); + showView(&select->view, VIEW_UPDATE_ALL); + } + + rect_moji(g); + { + gfxprint_t* gfxprint_p = __alloca(sizeof(gfxprint_t)); + + gfxprint_init(gfxprint_p); + gfxprint_open(gfxprint_p, NOW_POLY_OPA_DISP); + + select_print_wait(gfxprint_p); + + SET_POLY_OPA_DISP(gfxprint_close(gfxprint_p)); + + + gfxprint_cleanup(gfxprint_p); + } + CLOSE_DISP(g); +} + +static void select_draw(GAME_SELECT* select) { + GRAPH* g = select->game.graph; + rect screen; + + OPEN_DISP(g); + + gSPSegment(NOW_BG_OPA_DISP++, G_MWO_SEGMENT_0, 0); + gSPSegment(NOW_POLY_OPA_DISP++, G_MWO_SEGMENT_0, 0); + + DisplayList_initialize(g, 0, 0, 0, NULL); + + screen.top = 0; + screen.bottom = SCREEN_HEIGHT; + screen.l = 0; + screen.r = SCREEN_WIDTH; + + setScissorView(&select->view, &screen); + showView(&select->view, VIEW_UPDATE_ALL); + + if (select->game.doing == FALSE) { + select_draw_wait(select); + } + else { + select_draw_main(select); + } + + CLOSE_DISP(g); +} + +static void select_main(GAME* game) { + GAME_SELECT* select = (GAME_SELECT*)game; + + select_move(select); + select_draw(select); + + { + GRAPH* g = game->graph; + game_debug_draw_last(game, g); + game_draw_last(g); + } +} + +extern void select_cleanup(GAME* game) { } + +extern void select_init(GAME* game) { + GAME_SELECT* select = (GAME_SELECT*)game; + int i; + + game->exec = &select_main; + game->cleanup = &select_cleanup; + + select->status = SELECT_STATUS_MAIN; + select->cursor_y = 10; + select->step = 0; + select->step_add = 0; + + initView(&select->view, game->graph); + select->view.flag = VIEW_UPDATE_SCISSOR | VIEW_UPDATE_ORTHOGRAPHIC; + + select->unk_228[0] = 0; + select->unk_228[1] = 0; + select->unk_228[2] = 0; + for (i = 0; i < PLAYER_NAME_LEN; i++) { + select->name[i] = fcode2data(Common_Get(now_private)->player_ID.player_name[i]); + } + + select->selected_course = Common_Get(select_last_select_no); + select->top_course = Common_Get(select_last_top_no); + + SetGameFrame(1); + Common_Set(last_scene_no, Save_Get(scene_no)); + Common_Set(submenu_disabled, 0); + Common_Set(now_private->inventory.loan, 1000); + mNpc_ClearEventNpc(); + mNpc_ClearMaskNpc(); + mFI_SetClimate(mFI_CLIMATE_0); + Common_Set(last_scene_no, 0); +}