diff options
| author | Prakxo <87568477+Prakxo@users.noreply.github.com> | 2023-12-21 16:50:42 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-12-21 08:50:42 -0700 |
| commit | 72514d5aae62cc9789b2de0d3d3ba764be2c168d (patch) | |
| tree | b3e91ff0fd9320f6ee021f8cebd046683f0cd5d4 | |
| parent | 45e93dc1b6a859a5f27f3f2b52630598a8d11ad1 (diff) | |
m_select OK (#128)
* m_select OK
* format
| -rw-r--r-- | include/6BA500.h | 2 | ||||
| -rw-r--r-- | include/libu64/gfxprint.h | 8 | ||||
| -rw-r--r-- | include/m_common_data.h | 15 | ||||
| -rw-r--r-- | include/m_private.h | 19 | ||||
| -rw-r--r-- | include/m_private_internals.h | 6 | ||||
| -rw-r--r-- | include/m_rcp.h | 2 | ||||
| -rw-r--r-- | include/m_scene_table.h | 42 | ||||
| -rw-r--r-- | include/m_view.h | 33 | ||||
| -rw-r--r-- | linker_scripts/jp/symbol_addrs_code.txt | 2 | ||||
| -rw-r--r-- | linker_scripts/jp/symbol_addrs_overlays.txt | 115 | ||||
| -rw-r--r-- | src/code/m_start_data_init.c | 2 | ||||
| -rw-r--r-- | src/overlays/gamestates/ovl_play/m_play.c | 8 | ||||
| -rw-r--r-- | src/overlays/gamestates/ovl_select/m_select.c | 969 | ||||
| -rw-r--r-- | src/overlays/gamestates/ovl_select/m_select.h | 100 | ||||
| -rw-r--r-- | src/overlays/submenu/submenu_ovl/m_submenu_ovl.c | 13 | ||||
| -rw-r--r-- | yamls/jp/overlays.yaml | 6 |
16 files changed, 1233 insertions, 109 deletions
diff --git a/include/6BA500.h b/include/6BA500.h index 5db7e1e..e80d8fb 100644 --- a/include/6BA500.h +++ b/include/6BA500.h @@ -4,7 +4,7 @@ #include "ultra64.h" // void func_80096860_jp(); -// void func_800968C0_jp(); +void func_800968C0_jp(void); // void func_80096B2C_jp(); // void func_80096B4C_jp(); void func_80096B64_jp(void); diff --git a/include/libu64/gfxprint.h b/include/libu64/gfxprint.h index 27d7cf6..a3aae97 100644 --- a/include/libu64/gfxprint.h +++ b/include/libu64/gfxprint.h @@ -39,6 +39,14 @@ typedef struct gfxprint { #define GFXPRINT_UNUSED_CHAR '\x8E' +#define GFXPRINT_CLEAR_GRADIENT "\x8A" +#define GFXPRINT_ENABLE_GRADIENT "\x8B" + +#define GFXPRINT_KATAKANA_MODE "\x8C" +#define GFXPRINT_HIRAGANA_MODE "\x8D" + +#define GFXPRINT_UNUSED "\x8E" + /* Macros for quickly checking state of gfxprint struct */ #define gfxprint_isFlagOn(this, flag) ((this->flags & flag) != 0) #define gfxprint_setFlag(this, flag) (this->flags |= flag) diff --git a/include/m_common_data.h b/include/m_common_data.h index b592f64..c98be21 100644 --- a/include/m_common_data.h +++ b/include/m_common_data.h @@ -179,7 +179,8 @@ typedef struct CommonData { /* 0x0F428 */ u64 melody; /* 0x0F430 */ UNK_TYPE1 unk_F430[0x8]; /* 0x0F438 */ u8 stationType; - /* 0x0F439 */ u8 unk_F439[0x3]; + /* 0x0F439 */ u8 saveWeather; + /* 0x0F440 */ u8 unk_F440[0x2]; /* 0x0F43C */ u16 deposit[FG_BLOCK_X_NUM * FG_BLOCK_Z_NUM][UT_Z_NUM]; // flags for which items are buried around town /* 0x0F7FC */ lbRTC_time_c lastGrowTime; /* 0x0F804 */ PrivateMotherMail motherMailInfo[PLAYER_NUM]; @@ -231,9 +232,15 @@ typedef struct CommonData { /* 0x104AD */ u8 unk_104AD; /* 0x104AE */ u8 sunlightFlag; /* 0x104AF */ UNK_TYPE1 unk_104AF[0x1]; - /* 0x104B0 */ UNK_TYPE1 unk_104B0[0xE8]; + /* 0x104B0 */ UNK_TYPE1 unk_104B0[0xBC]; + /* 0x1056C */ s16 weather; + /* 0x1056E */ s16 weatherIntensity; + /* 0x10570 */ lbRTC_time_c weatherTime; + /* 0x10578 */ s_xyz wind; + /* 0x10580 */ f32 windSpeed; + /* 0x10584 */ UNK_TYPE1 unk10584[0x14]; /* 0x10598 */ mQst_not_saved_c quest; - /* 0x105A0 */ u32 sceneFromTitleDemo; + /* 0x105A0 */ s32 sceneFromTitleDemo; /* 0x105A4 */ NpsSchedule npcSchedule[ANIMAL_NUM_MAX]; /* 0x10694 */ NpcWalking npcWalk; /* 0x10710 */ NpcEvent npcEvent[5]; @@ -245,7 +252,7 @@ typedef struct CommonData { /* 0x107A4 */ UNK_TYPE1 unk_107A4[0x12]; /* 0x107B6 */ s16 unk_107B6; // named "demo_profile" in AC GCN decomp (though it's an array of two s16s in that game) /* 0x107B8 */ UNK_TYPE1 unk_107B8[0x28]; - /* 0x107E0 */ s8 player_decoy_flag; + /* 0x107E0 */ s8 playerDecoyFlag; /* 0x107E1 */ UNK_TYPE1 unk_107E1[0x3]; /* 0x107E4 */ s16 unk_107E4; /* 0x107E6 */ UNK_TYPE1 unk107E6[0x252]; diff --git a/include/m_private.h b/include/m_private.h index 7448960..e566576 100644 --- a/include/m_private.h +++ b/include/m_private.h @@ -26,10 +26,23 @@ typedef enum mPr_ITEM_COND{ /* 3 */ mPr_ITEM_COND_NUM } mPr_ITEM_COND; +typedef enum mPr_FACE_TYPE { + /* 0 */ mPr_FACE_TYPE0, + /* 1 */ mPr_FACE_TYPE1, + /* 2 */ mPr_FACE_TYPE2, + /* 3 */ mPr_FACE_TYPE3, + /* 4 */ mPr_FACE_TYPE4, + /* 5 */ mPr_FACE_TYPE5, + /* 6 */ mPr_FACE_TYPE6, + /* 7 */ mPr_FACE_TYPE7, + /* 8 */ mPr_FACE_TYPE_NUM +} mPr_FACE_TYPE; + typedef struct PrivateInfo { /* 0x000 */ PersonalID_c playerId; /* 0x010 */ s8 gender; - /* 0x011 */ UNK_TYPE1 unk_011[0x3]; + /* 0x011 */ s8 face; + /* 0x012 */ UNK_TYPE1 unk_012[0x2]; /* 0x014 */ PrivateInventory inventory; /* 0x040 */ mQst_delivery_c deliveries[mPr_DELIVERY_QUEST_NUM]; /* delivery quests */ /* 0x25C */ QuestErrand errands[mPr_ERRAND_QUEST_NUM]; /* errand quests */ @@ -38,7 +51,9 @@ typedef struct PrivateInfo { /* 0x40A */ Mail_c unk_40A[10]; /* 0xA72 */ UNK_TYPE1 unk_A72[0x2]; /* 0xA74 */ u8 exists; - /* 0xA75 */ UNK_TYPE1 unk_A75[0x11]; + /* 0xA75 */ UNK_TYPE1 unkA75[1]; + /* 0xA76 */ PrivateCloth cloth; + /* 0xA7A */ UNK_TYPE1 unkA7A[0xC]; /* 0xA86 */ Private_Sub_A86 unk_A86; /* 0xA90 */ UNK_TYPE1 unk_A90[0x3C]; /* 0xACC */ Anmremail remail; diff --git a/include/m_private_internals.h b/include/m_private_internals.h index 914f857..2bdd1f2 100644 --- a/include/m_private_internals.h +++ b/include/m_private_internals.h @@ -48,4 +48,10 @@ typedef struct PrivateInventory { /* 0x28 */ u32 loan; } PrivateInventory; // size = 0x2C +typedef struct PrivateCloth { + /* 0x00 */ u16 id; + /* 0x02 */ u16 item; +} PrivateCloth; // size = 0x4 + + #endif diff --git a/include/m_rcp.h b/include/m_rcp.h index 6d6c641..f8e5298 100644 --- a/include/m_rcp.h +++ b/include/m_rcp.h @@ -25,7 +25,7 @@ void func_800BD5E8_jp(struct GraphicsContext *gfxCtx); // void func_800BD6D0_jp(); // void func_800BD6F8_jp(); Gfx* func_800BD720_jp(Gfx* gfx); -// void func_800BD748_jp(); +void rect_moji(struct GraphicsContext*); // void func_800BD770_jp(); // void func_800BD798_jp(); Gfx* func_800BD7C0_jp(Gfx* gfx); diff --git a/include/m_scene_table.h b/include/m_scene_table.h index 9adf609..d049a5f 100644 --- a/include/m_scene_table.h +++ b/include/m_scene_table.h @@ -4,10 +4,44 @@ #include "ultra64.h" #include "z64math.h" -#define SCENE_FG 7 -#define SCENE_START_DEMO 15 -#define SCENE_START_DEMO2 16 - +typedef enum SceneTable { + /* 00 */ SCENE_TEST1, + /* 01 */ SCENE_TEST2, + /* 02 */ SCENE_TEST3, + /* 03 */ SCENE_WATER_TEST, + /* 04 */ SCENE_FOOTPRINT_TEST, + /* 05 */ SCENE_NPC_TEST, + /* 06 */ SCENE_NPC_HOUSE, /* npc house interior */ + /* 07 */ SCENE_FG, /* outdoors/FG */ + /* 08 */ SCENE_RANDOM_NPC_TEST, + /* 09 */ SCENE_SHOP0, /* nook's cranny */ + /* 10 */ SCENE_BG_TEST_NO_RIVER, + /* 11 */ SCENE_BG_TEST_RIVER, + /* 12 */ SCENE_BROKER_SHOP, /* crazy redd's tent */ + /* 13 */ SCENE_FIELD_TOOL_INSIDE, + /* 14 */ SCENE_POST_OFFICE, /* post office */ + /* 15 */ SCENE_START_DEMO, /* after player select */ + /* 16 */ SCENE_START_DEMO2, /* */ + /* 17 */ SCENE_POLICE_BOX, + /* 18 */ SCENE_BUGGY, + /* 19 */ SCENE_PLAYERSELECT, + /* 20 */ SCENE_MY_ROOM_S, + /* 21 */ SCENE_MY_ROOM_M, + /* 22 */ SCENE_MY_ROOM_L, + /* 23 */ SCENE_CONVENI, /* nook 'n' go */ + /* 24 */ SCENE_SUPER, /* nookway */ + /* 25 */ SCENE_DEPART, /* nookington's 1st floor */ + /* 26 */ SCENE_TEST5, + /* 27 */ SCENE_PLAYERSELECT_2, + /* 28 */ SCENE_PLAYERSELECT_3, + /* 29 */ SCENE_DEPART_2, /* nookington's 2nd floor */ + /* 30 */ SCENE_EVENT_ANNOUNCEMENT, + /* 31 */ SCENE_KAMAKURA, + /* 32 */ SCENE_FIELD_TOOL, + /* 33 */ SCENE_TITLE_DEMO, /* title screen demo */ + /* 34 */ SCENE_PLAYERSELECT_SAVE, + /* 35 */ SCENE_NUM +} SceneTable; extern Struct_8010EAA0 scene_data_status[]; #endif diff --git a/include/m_view.h b/include/m_view.h index 346c2bc..72a0566 100644 --- a/include/m_view.h +++ b/include/m_view.h @@ -8,12 +8,16 @@ struct Game_Play; struct GraphicsContext; +typedef struct Viewport { + /* 0x00 */ s32 topY; // uly (upper left y) + /* 0x04 */ s32 bottomY; // lry (lower right y) + /* 0x08 */ s32 leftX; // ulx (upper left x) + /* 0x0C */ s32 rightX; // lrx (lower right x) +} Viewport; // size = 0x10 + typedef struct Game_Play1938 { /* 0x000 */ UNK_TYPE1 unk_000[0x8]; - /* 0x008 */ s32 unk_008; - /* 0x00C */ s32 unk_00C; - /* 0x010 */ s32 unk_010; - /* 0x018 */ s32 unk_014; + /* 0x008 */ Viewport viewport; /* 0x01C */ UNK_TYPE1 unk_018[0x10]; /* 0x028 */ xyz_t unk_028; /* 0x034 */ UNK_TYPE1 unk_034[0x1C]; @@ -25,12 +29,17 @@ typedef struct Game_Play1938 { /* 0x124 */ UNK_TYPE1 unk_124[0x4]; } Game_Play1938; // size = 0x128 -typedef struct ScissorViewArg1 { - /* 0x00 */ s32 unk_00; - /* 0x04 */ s32 unk_04; - /* 0x08 */ s32 unk_08; - /* 0x0C */ s32 unk_0C; -} ScissorViewArg1; // size = 0x10 + +#define SET_FULLSCREEN_VIEWPORT(view) \ + { \ + Viewport viewport; \ + viewport.bottomY = SCREEN_HEIGHT; \ + viewport.rightX = SCREEN_WIDTH; \ + viewport.topY = 0; \ + viewport.leftX = 0; \ + setScissorView(view, &viewport); \ + } \ + (void)0 // void set_viewport(); void initView(Game_Play1938* arg0, struct GraphicsContext* gfxCtx); @@ -40,14 +49,14 @@ void initView(Game_Play1938* arg0, struct GraphicsContext* gfxCtx); // void getScaleView(); // void setPerspectiveView(); // void getPerspectiveView(); -void setScissorView(Game_Play1938* arg0, ScissorViewArg1* arg1); +void setScissorView(Game_Play1938* arg0, Viewport* arg1); // void getScissorView(); // void setScissorX(); // void setScissorOvl(); // void setScissor(); // void stretchViewInit(); // void do_stretch_view(); -void showView(Game_Play1938* arg0, s32 arg1, struct Game_Play* game_play); +void showView(Game_Play1938* arg0, s32 arg1); // void showPerspectiveView(); // void showOrthoView(); // void showOverLayView(); diff --git a/linker_scripts/jp/symbol_addrs_code.txt b/linker_scripts/jp/symbol_addrs_code.txt index 3c0f573..9803eee 100644 --- a/linker_scripts/jp/symbol_addrs_code.txt +++ b/linker_scripts/jp/symbol_addrs_code.txt @@ -2891,7 +2891,7 @@ func_800BD68C_jp = 0x800BD68C; // type:func func_800BD6D0_jp = 0x800BD6D0; // type:func func_800BD6F8_jp = 0x800BD6F8; // type:func func_800BD720_jp = 0x800BD720; // type:func -func_800BD748_jp = 0x800BD748; // type:func +rect_moji = 0x800BD748; // type:func func_800BD770_jp = 0x800BD770; // type:func func_800BD798_jp = 0x800BD798; // type:func func_800BD7C0_jp = 0x800BD7C0; // type:func diff --git a/linker_scripts/jp/symbol_addrs_overlays.txt b/linker_scripts/jp/symbol_addrs_overlays.txt index d16175d..1b86cf1 100644 --- a/linker_scripts/jp/symbol_addrs_overlays.txt +++ b/linker_scripts/jp/symbol_addrs_overlays.txt @@ -1,73 +1,62 @@ // .text -func_80800000_jp = 0x80800000; // type:func -func_80800058_jp = 0x80800058; // type:func -func_8080007C_jp = 0x8080007C; // type:func -func_808000A4_jp = 0x808000A4; // type:func -func_80800138_jp = 0x80800138; // type:func -func_80800248_jp = 0x80800248; // type:func -func_808002C8_jp = 0x808002C8; // type:func -func_808002D8_jp = 0x808002D8; // type:func -func_808002E8_jp = 0x808002E8; // type:func -func_808002F8_jp = 0x808002F8; // type:func -func_8080034C_jp = 0x8080034C; // type:func -func_80800384_jp = 0x80800384; // type:func -func_808003BC_jp = 0x808003BC; // type:func -func_808003F0_jp = 0x808003F0; // type:func -func_80800424_jp = 0x80800424; // type:func -func_80800434_jp = 0x80800434; // type:func -func_80800444_jp = 0x80800444; // type:func -func_80800498_jp = 0x80800498; // type:func -func_8080053C_jp = 0x8080053C; // type:func -func_80800564_jp = 0x80800564; // type:func -func_808005EC_jp = 0x808005EC; // type:func -func_808006A8_jp = 0x808006A8; // type:func -func_80800774_jp = 0x80800774; // type:func -func_808007C8_jp = 0x808007C8; // type:func -func_80800814_jp = 0x80800814; // type:func -func_80800854_jp = 0x80800854; // type:func -func_808008E4_jp = 0x808008E4; // type:func -func_80800978_jp = 0x80800978; // type:func -func_808009C0_jp = 0x808009C0; // type:func -func_80800A08_jp = 0x80800A08; // type:func -func_80800A5C_jp = 0x80800A5C; // type:func -func_80800C3C_jp = 0x80800C3C; // type:func -func_80800DE0_jp = 0x80800DE0; // type:func -func_80800E34_jp = 0x80800E34; // type:func -func_80800EBC_jp = 0x80800EBC; // type:func -func_8080108C_jp = 0x8080108C; // type:func -func_808010CC_jp = 0x808010CC; // type:func -func_8080131C_jp = 0x8080131C; // type:func -func_80801354_jp = 0x80801354; // type:func -func_80801390_jp = 0x80801390; // type:func -func_808013B4_jp = 0x808013B4; // type:func -func_8080140C_jp = 0x8080140C; // type:func -func_80801468_jp = 0x80801468; // type:func -func_808014E4_jp = 0x808014E4; // type:func -func_8080154C_jp = 0x8080154C; // type:func -func_808015B4_jp = 0x808015B4; // type:func -func_80801610_jp = 0x80801610; // type:func -func_80801658_jp = 0x80801658; // type:func -func_80801840_jp = 0x80801840; // type:func -func_80801928_jp = 0x80801928; // type:func -func_808019E4_jp = 0x808019E4; // type:func +game_next_play = 0x80800000; // type:func +data2fcode = 0x80800058; // type:func +fcode2data = 0x8080007C; // type:func +select_pass = 0x808000A4; // type:func +select_start_proc = 0x80800138; // type:func +select_check_start = 0x80800248; // type:func +select_check_A_button_rtc = 0x808002C8; // type:func +select_check_A_button_time = 0x808002D8; // type:func +select_check_A_buttonStep = 0x808002E8; // type:func +select_check_A_button_weather = 0x808002F8; // type:func +select_check_A_button_sex = 0x8080034C; // type:func +select_check_A_button_face_type = 0x80800384; // type:func +select_check_A_button_swell = 0x808003BC; // type:func +select_check_A_button_decoy = 0x808003F0; // type:func +select_check_A_button_cloth = 0x80800424; // type:func +select_check_A_button_event = 0x80800434; // type:func +select_check_A_button = 0x80800444; // type:func +select_move_cursol = 0x80800498; // type:func +select_course_step_sub = 0x8080053C; // type:func +select_adjust_top_no = 0x80800564; // type:func +select_course_step = 0x808005EC; // type:func +select_course = 0x808006A8; // type:func +select_move_main = 0x80800774; // type:func +select_move_setup = 0x808007C8; // type:func +select_move_time_year_set = 0x80800814; // type:func +select_move_time_month_set = 0x80800854; // type:func +select_move_time_day_set = 0x808008E4; // type:func +select_move_time_hour_set = 0x80800978; // type:func +select_move_time_min_set = 0x808009C0; // type:func +select_move_time_week_set = 0x80800A08; // type:func +select_move_time_set = 0x80800A5C; // type:func +select_move_cloth_sel = 0x80800C3C; // type:func +select_move = 0x80800DE0; // type:func +select_print_wait = 0x80800E34; // type:func +select_print_course_name = 0x80800EBC; // type:func +select_print_rtc = 0x8080108C; // type:func +select_print_time_sub = 0x808010CC; // type:func +select_print_time = 0x8080131C; // type:func +select_print_step_sub2 = 0x80801354; // type:func +select_print_step = 0x80801390; // type:func +select_print_weather = 0x808013B4; // type:func +select_print_sex = 0x8080140C; // type:func +select_print_cloth = 0x80801468; // type:func +select_print_swell = 0x808014E4; // type:func +select_print_decoy = 0x8080154C; // type:func +select_print_face_type = 0x808015B4; // type:func +select_print_event = 0x80801610; // type:func +select_draw_main = 0x80801658; // type:func +select_draw_wait = 0x80801840; // type:func +select_draw = 0x80801928; // type:func +select_main = 0x808019E4; // type:func select_cleanup = 0x80801A28; // type:func select_init = 0x80801A34; // type:func // .data -D_80801B60_jp = 0x80801B60; // -D_80801D04_jp = 0x80801D04; // -D_80801D2C_jp = 0x80801D2C; // -D_80801D60_jp = 0x80801D60; // -D_80801D68_jp = 0x80801D68; // -D_80801D7C_jp = 0x80801D7C; // -D_80801D8C_jp = 0x80801D8C; // -D_80801DBC_jp = 0x80801DBC; // -D_80801DD0_jp = 0x80801DD0; // -D_80801DD8_jp = 0x80801DD8; // -D_80801DF8_jp = 0x80801DF8; // -D_80801E14_jp = 0x80801E14; // +nf_tbl = 0x80801B60; // // .rodata diff --git a/src/code/m_start_data_init.c b/src/code/m_start_data_init.c index cfedc6e..9e2e00f 100644 --- a/src/code/m_start_data_init.c +++ b/src/code/m_start_data_init.c @@ -288,7 +288,7 @@ s32 mSDI_StartInitFrom(Game* game2, s32 playerNumber, s32 mallocFlag) { mMkRm_MarkRoom(game); res = TRUE; } else { - common_data.player_decoy_flag = TRUE; + common_data.playerDecoyFlag = TRUE; privateInfo->exists = TRUE; common_data.privateInfo = privateInfo; common_data.playerNumber = playerNumber; diff --git a/src/overlays/gamestates/ovl_play/m_play.c b/src/overlays/gamestates/ovl_play/m_play.c index fe351c3..4ceba43 100644 --- a/src/overlays/gamestates/ovl_play/m_play.c +++ b/src/overlays/gamestates/ovl_play/m_play.c @@ -579,7 +579,7 @@ void setupFog(Game_Play* game_play, GraphicsContext* gfxCtx) { } void setupViewer(Game_Play* game_play) { - showView(&game_play->unk_1938, 0xF, game_play); + showView(&game_play->unk_1938, 0xF); } void setupViewMatrix(Game_Play* game_play, GraphicsContext* __gfxCtx, GraphicsContext* gfxCtx2) { @@ -614,7 +614,6 @@ s32 makeBumpTexture(Game_Play* game_play, GraphicsContext* __gfxCtx, GraphicsCon if (game_play->unk_1EE3 == 3) { Game_Play1938 sp60; - ScissorViewArg1 sp50; initView(&sp60, gfxCtx2); { @@ -622,10 +621,7 @@ s32 makeBumpTexture(Game_Play* game_play, GraphicsContext* __gfxCtx, GraphicsCon //! FAKE label2:; } - sp50.unk_04 = 0xF0, sp50.unk_0C = 0x140; - sp50.unk_00 = 0; - sp50.unk_08 = 0; - setScissorView(&sp60, &sp50); + SET_FULLSCREEN_VIEWPORT(&sp60); showView1(&sp60, 0xF, &sp194); game_play->unk_1EE8.unk_21C.unk_0C(&game_play->unk_1EE8, &sp194); } diff --git a/src/overlays/gamestates/ovl_select/m_select.c b/src/overlays/gamestates/ovl_select/m_select.c new file mode 100644 index 0000000..e0f2ba5 --- /dev/null +++ b/src/overlays/gamestates/ovl_select/m_select.c @@ -0,0 +1,969 @@ +#include "m_select.h" +#include "overlays/gamestates/ovl_play/m_play.h" +#include "m_debug.h" +#include "6B81C0.h" +#include "6BA500.h" +#include "libu64/gfxprint.h" +#include "m_scene_table.h" +#include "macros.h" +#include "libc/alloca.h" +#include "m_rcp.h" +#include "audio.h" + +#define nf_str(s0, s1) (s0 GFXPRINT_KATAKANA_MODE s1) +NameFunction 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 }, +}; + +void game_next_play(Game* game, s32 scene) { + common_data.sceneNo = scene; + STOP_GAMESTATE(game); + SET_NEXT_GAMESTATE(game, play_init, sizeof(Game_Play)); + mHm_SetNowHome(); + common_data.unk_10754 = 0; + func_800968C0_jp(); + common_data.unk_10140 = 1; +} + +char data2fcode(char data) { + char fcode = ' '; + + if (data != 0) { + fcode = data + 0x90; + } + + return fcode; +} + +char fcode2data(char fcode) { + char data = 0; + if (fcode != ' ') { + data = fcode - 0x90; + } + + return data; +} + +void select_pass(Game_Select* select) { + lbRTC_time_c* rtc = &common_data.time.rtcTime; + NameFunction* nfPtr; + s32 scene = common_data.sceneFromTitleDemo; + + common_data.time.nowSec = rtc->hour * 3600 + rtc->min * 60 + rtc->sec; + nfPtr = &nf_tbl[scene]; + if (nfPtr->nextProc != NULL) { + (*nfPtr->nextProc)((Game*)select, nfPtr->sceneNo); + } + + common_data.sceneFromTitleDemo = -1; +} + +s32 select_start_proc(Game_Select* select) { + NameFunction* nfPtr; + s32 i; + + common_data.time.nowSec = + common_data.time.rtcTime.hour * 3600 + common_data.time.rtcTime.min * 60 + common_data.time.rtcTime.sec; + nfPtr = &nf_tbl[select->selectedScene]; + if (nfPtr->nextProc != NULL) { + (*nfPtr->nextProc)((Game*)select, nfPtr->sceneNo); + } + + DORO(80) = select->selectedScene; + DORO(81) = select->topScene; + + if (common_data.time.rtcTime.min == 0) { + common_data.time.timeSignal = 1; + } + + for (i = 0; i < PLAYER_NAME_LEN; i++) { + common_data.privateInfo->playerId.playerName[i] = data2fcode(select->name[i]); + } + + return 1; +} + +s32 select_check_start(Game_Select* select) { + if (select->status == 0) { + if (chkTrigger(START_BUTTON) || chkTrigger(A_BUTTON)) { + return select_start_proc(select); + } + } else if (chkTrigger(START_BUTTON)) { + return select_start_proc(select); + } + + return 0; +} + +s32 select_check_A_button_rtc(UNUSED Game_Select* select) { + return FALSE; +} + +s32 select_check_A_button_time(UNUSED Game_Select* select) { + return FALSE; +} + +s32 select_check_A_buttonStep(UNUSED Game_Select* select) { + return FALSE; +} + +s32 select_check_A_button_weather(UNUSED Game_Select* select) { + s32 weather = common_data.weather; + weather++; + if (weather >= 5 || weather < 0) { + weather = 0; + } + + common_data.weather = weather; + common_data.weatherIntensity = 3; + + { + u8 saved; + saved = weather; + saved = weather << 4; + common_data.saveWeather = saved | 3; + } + + return 0; +} + +s32 select_check_A_button_sex(UNUSED Game_Select* select) { + s32 sex = common_data.privateInfo->gender; + sex++; + sex %= mPr_SEX_NUM; + common_data.privateInfo->gender = sex; + + return FALSE; +} + +s32 select_check_A_button_face_type(UNUSED Game_Select* select) { + s32 face_type = common_data.privateInfo->face; + face_type++; + face_type %= mPr_FACE_TYPE_NUM; + common_data.privateInfo->face = face_type; + + return FALSE; +} + +s32 select_check_A_button_swell(UNUSED Game_Select* select) { + s32 sting; + + sting = common_data.beeStingFlag; + if (sting != 0) { + sting = 0; + } else { + sting = 1; + } + + common_data.beeStingFlag = sting; + + return FALSE; +} + +s32 select_check_A_button_decoy(UNUSED Game_Select* select) { + s32 decoy; + + decoy = common_data.playerDecoyFlag; + if (decoy != 0) { + decoy = 0; + } else { + decoy = 1; + } + common_data.playerDecoyFlag = decoy; + + return FALSE; +} + +s32 select_check_A_button_cloth(UNUSED Game_Select* select) { + return FALSE; +} + +s32 select_check_A_button_event(UNUSED Game_Select* select) { + return FALSE; +} + +typedef s32 (*SelectCheckProc)(Game_Select*); + +s32 select_check_A_button(Game_Select* select) { + static SelectCheckProc process[] = { + &select_check_A_button_rtc, &select_check_A_button_time, &select_check_A_buttonStep, + &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_event, + }; + + if (chkTrigger(A_BUTTON)) { + return (*process[select->cursorY])(select); + } else { + return FALSE; + } +} + +s32 select_move_cursol(Game_Select* select) { + if (chkTrigger(L_JPAD)) { + select->status = 0; + return TRUE; + } else if (chkTrigger(U_JPAD)) { + if (select->cursorY == 0) { + select->cursorY = SELECT_CHECK_A_BUTTON_NUM - 1; + } else { + select->cursorY--; + } + } else if (chkTrigger(D_JPAD)) { + select->cursorY = (select->cursorY + 1) % SELECT_CHECK_A_BUTTON_NUM; + } + + return FALSE; +} + +s32 select_course_step_sub(s32 course) { + if (course < 0) { + course += 0x23; + } else if (course >= 0x23) { + course -= 0x23; + } + + return course; +} + +void select_adjust_top_no(Game_Select* select, s32 course, s32 adjust) { + s32 top = select->topScene; + s32 newTop = (select->topScene + 0xE) % 0x23; + + if (top < newTop) { + if (course <= top || course >= newTop) { + top = select_course_step_sub(top + adjust); + } + } else if (course <= top && course >= newTop) { + top = select_course_step_sub(top + adjust); + } + + select->topScene = top; +} + +void select_course_step(Game_Select* select, s32 addend) { + s32 step = select->step + addend; + + if (ABS(step) >= 32) { + s32 course = select->selectedScene; + sAdo_SysTrgStart(1); + + if (step > 0) { + step = 0; + course = select_course_step_sub(course + 1); + select_adjust_top_no(select, course, 1); + } else { + step = 0; + course = select_course_step_sub(course - 1); + select_adjust_top_no(select, course, -1); + } + + select->stepAdd = 6; + select->selectedScene = course; + } + + select->step = step; +} + +void select_course(Game_Select* select) { + if (chkTrigger(U_JPAD)) { + if (select->step > 0) { + select->step = 0; + } + + select_course_step(select, -32); + select->stepAdd = 1; + } else if (chkButton(U_JPAD)) { + select_course_step(select, -select->stepAdd); + } else if (chkTrigger(D_JPAD)) { + if (select->step < 0) { + select->step = 0; + } + + select_course_step(select, 32); + select->stepAdd = 1; + } else if (chkButton(D_JPAD)) { + select_course_step(select, select->stepAdd); + } +} + +void select_move_main(Game_Select* select) { + if (select_check_start(select) != TRUE) { + if (chkTrigger(R_JPAD)) { + select->status = 1; + } else { + select_course(select); + } + } +} + +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) {} + } +} + +void select_move_time_year_set(s32 adjust) { + s32 year = common_data.time.rtcTime.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_data.time.rtcTime.year = year; +} + +void select_move_time_month_set(s32 adjust) { + static s32 season_table[] = { + SPRING, WINTER, WINTER, SPRING, SPRING, SPRING, SUMMER, SUMMER, SUMMER, FALL, FALL, FALL, WINTER, + }; + + s32 month; + month = common_data.time.rtcTime.month; + month = (month + adjust); + month %= (lbRTC_MONTHS_MAX + 1); + + if (month == 0) { + month = (adjust > 0) ? 1 : 12; + } + common_data.time.rtcTime.month = month; + { + u8 save = lbRTC_GetDaysByMonth(common_data.time.rtcTime.year, common_data.time.rtcTime.month); + if (common_data.time.rtcTime.day > save) { + common_data.time.rtcTime.day = save; + } + } + + common_data.time.season = season_table[month]; +} + +void select_move_time_day_set(s32 adjust) { + u8 max_day = lbRTC_GetDaysByMonth(common_data.time.rtcTime.year, common_data.time.rtcTime.month); + s32 day = common_data.time.rtcTime.day; + day = (day + adjust) % (max_day + 1); + + if (day == 0) { + day = (adjust > 0) ? 1 : max_day; + } + + common_data.time.rtcTime.day = day; +} + +void select_move_time_hour_set(s32 adjust) { + s32 hour = common_data.time.rtcTime.hour; + if (hour == 0 && adjust < 0) { + hour = lbRTC_HOURS_PER_DAY - 1; + } else { + hour = (hour + adjust) % lbRTC_HOURS_PER_DAY; + } + + common_data.time.rtcTime.hour = hour; +} + +void select_move_time_min_set(s32 adjust) { + s32 min = common_data.time.rtcTime.min; + if (min == 0 && adjust < 0) { + min = lbRTC_MINUTES_PER_HOUR - 1; + } else { + min = (min + adjust) % lbRTC_MINUTES_PER_HOUR; + } + + common_data.time.rtcTime.min = min; +} + +void select_move_time_week_set(s32 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_data.time.rtcTime, &base); + interval = interval / (lbRTC_HOURS_PER_DAY * lbRTC_MINUTES_PER_HOUR) + (lbRTC_WEEK - 1); + common_data.time.rtcTime.weekday = interval % lbRTC_WEEK; + } +} + +typedef void (*SelectMoveTimeProc)(s32); + +void select_move_time_set(Game_Select* select) { + if (chkTrigger(A_BUTTON) || chkTrigger(START_BUTTON)) { + select->status = 1; + if (common_data.time.rtcEnabled == TRUE) { + lbRTC_SetTime(&common_data.time.rtcTime); + } + } else if (chkTrigger(L_JPAD)) { + if (select->cursorX == 0) { + select->cursorX = 4; + } else { + select->cursorX--; + } + } else if (chkTrigger(R_JPAD)) { + select->cursorX = (select->cursorX + 1) % 5; + } else { + int adjust = 0; + + if (chkButton(D_JPAD)) { + if (chkTrigger(D_JPAD)) { + + select->buttonStep = -16; + adjust = -1; + } + + select->buttonStep++; + if (select->buttonStep == 6) { + select->buttonStep = 0; + adjust = -1; + } + } + + if (chkButton(U_JPAD)) { + if (chkTrigger(U_JPAD)) { + + select->buttonStep = 16; + adjust = 1; + } + + select->buttonStep--; + if (select->buttonStep == -6) { + select->buttonStep = 0; + adjust = 1; + } + } + + if (chkButton(B_BUTTON)) { + adjust *= 10; + } + + { + static SelectMoveTimeProc 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->cursorX) { + (*process[i])(adjust); + select_move_time_week_set(adjust); + } + } + + if (adjust != 0 && common_data.time.rtcEnabled == TRUE) { + lbRTC_SetTime(&common_data.time.rtcTime); + } + } + } +} + +void select_move_cloth_sel(Game_Select* select) { + if (chkTrigger(A_BUTTON) || chkTrigger(START_BUTTON)) { + select->status = 1; + } else { + int cloth = common_data.privateInfo->cloth.item - 0x2401; // shouldn't this be CLOTH000? + int adjust = (chkButton(B_BUTTON)) ? 10 : 1; + + if (chkButton(D_JPAD)) { + if (chkTrigger(D_JPAD)) { + select->buttonStep = -16; + cloth += adjust; + } + + select->buttonStep++; + if (select->buttonStep == 6) { + select->buttonStep = 0; + cloth += adjust; + } + } + + if (chkButton(U_JPAD)) { + if (chkTrigger(U_JPAD)) { + select->buttonStep = 16; + cloth -= adjust; + } + + select->buttonStep--; + if (select->buttonStep == -6) { + select->buttonStep = 0; + cloth -= adjust; + } + } + + while (cloth < 0) { + cloth += 255; + } + + while (cloth > 255 - 1) { + cloth -= 255; + } + + common_data.privateInfo->cloth.item = 0x2401 + cloth; + } +} + +typedef void (*SelectMoveProc)(Game_Select*); + +void select_move(Game_Select* select) { + static SelectMoveProc process[] = { + &select_move_main, + &select_move_setup, + &select_move_time_set, + &select_move_cloth_sel, + }; + + if (common_data.sceneFromTitleDemo >= 0) { + select_pass(select); + } else { + (*process[select->status])(select); + } +} + +void select_print_wait(gfxprint* gfxprint) { + static const char* msgs[12] = { + GFXPRINT_HIRAGANA_MODE "シバラクオマチクダサイ", /* (しばらくお待ち下さい) "Please wait for a bit" */ + GFXPRINT_HIRAGANA_MODE "チョット マッテネ", /* (ちょっと 待ってね) "Wait a minute" */ + GFXPRINT_KATAKANA_MODE "ウェイト ア モーメント", /* "Wait a moment" */ + GFXPRINT_KATAKANA_MODE "ロード" GFXPRINT_HIRAGANA_MODE "チュウ", /* (ロード中) "Loading" */ + GFXPRINT_HIRAGANA_MODE "ナウ ワーキング", /* "Now working" */ + GFXPRINT_HIRAGANA_MODE "イマ ツクッテマス", /* (今つくってます) "Now making" */ + GFXPRINT_HIRAGANA_MODE "コショウジャナイヨ", /* (故障じゃないよ) "It's not faulty" */ + GFXPRINT_KATAKANA_MODE "コーヒー ブレイク", /* "coffee break" */ + GFXPRINT_KATAKANA_MODE "Bメンヲセットシテクダサイ", /* (Bメンヲ セットしてください) "Please set the B menu" */ + GFXPRINT_HIRAGANA_MODE "ジット" GFXPRINT_KATAKANA_MODE "ガマン" GFXPRINT_HIRAGANA_MODE "ノ" GFXPRINT_KATAKANA_MODE + "コ" GFXPRINT_HIRAGANA_MODE "デアッタ", /* (ジっと我慢のこであった) "I am patient" */ + GFXPRINT_HIRAGANA_MODE "イマシバラクオマチクダサイ", /* (今しばらくお待ちください) "Please wait a moment now" */ + GFXPRINT_HIRAGANA_MODE "アワテナイアワテナイ。ヒトヤスミヒトヤスミ。", /* (あわてないあわてない。 ひとやすみひとやすみ。) "Don't rush, + don't rush. Take a break, take a break." */ + }; + + s32 msg; + gfxprint_locate8x8(gfxprint, 10, 15); + gfxprint_color(gfxprint, 255, 255, 255, 255); + msg = RANDOM(12.0f); + gfxprint_printf(gfxprint, "%s", msgs[msg]); +} + +void select_print_course_name(Game_Select* select, gfxprint* gfxprint) { + const char* name; + s32 i; + s32 course; + + 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++) { + gfxprint_locate8x8(gfxprint, 5, i + 4); + course = (select->topScene + i + 35) % 35; + if (course == select->selectedScene) { + 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); + } +} + +void select_print_rtc(gfxprint* gfxprint, UNUSED Game_Select* select) { + gfxprint_locate8x8(gfxprint, 23, 6); + gfxprint_printf(gfxprint, "RTC Z:USE"); +} + +void select_print_time_sub(gfxprint* 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 == 2) { + gfxprint_color(gfxprint, 255, 180, 180, 255); + + switch (select->cursorX) { + 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; + } + } + } +} + +void select_print_time(gfxprint* gfxprint, Game_Select* select) { + lbRTC_time_c time; + + lbRTC_GetTime(&time); + select_print_time_sub(gfxprint, select, &time); +} + +void select_print_step_sub2(gfxprint* gfxprint) { + gfxprint_locate8x8(gfxprint, 23, 9); + gfxprint_printf(gfxprint, GFXPRINT_KATAKANA_MODE "ステップ :**m**s"); +} + +void select_print_step(gfxprint* gfxprint, UNUSED Game_Select* select) { + select_print_step_sub2(gfxprint); +} + +void select_print_weather(gfxprint* gfxprint, UNUSED Game_Select* select) { + static const char* Weather_type[] = { + GFXPRINT_HIRAGANA_MODE "ハレ", // 晴れ (clear/fine) + GFXPRINT_HIRAGANA_MODE "アメ", // 雨 (rain) + GFXPRINT_HIRAGANA_MODE "ユキ", // 雪 (snow) + GFXPRINT_HIRAGANA_MODE "サクラ", // 桜 (cherry blossoms) + GFXPRINT_HIRAGANA_MODE "ランダム" // "random" (should be leaves seen in K.K. Slider demo) + }; + + gfxprint_locate8x8(gfxprint, 23, 10); + gfxprint_printf(gfxprint, GFXPRINT_HIRAGANA_MODE "テンキ :%s", Weather_type[common_data.weather]); +} + +void select_print_sex(gfxprint* gfxprint, UNUSED Game_Select* select) { + static const char* Distinction[mPr_SEX_NUM] = { + GFXPRINT_HIRAGANA_MODE "オトコノコ", // 男の子 (boy) + GFXPRINT_HIRAGANA_MODE "オンナノコ" // 女の子 (girl) + }; + + gfxprint_locate8x8(gfxprint, 23, 11); + gfxprint_printf(gfxprint, "セイベツ :%s", Distinction[common_data.privateInfo->gender]); +} + +void select_print_cloth(gfxprint* gfxprint, Game_Select* select) { + gfxprint_locate8x8(gfxprint, 23, 15); + if (select->status == 3) { + gfxprint_color(gfxprint, 255, 180, 180, 255); + } + + gfxprint_printf(gfxprint, "フク :%03d", common_data.privateInfo->cloth.item - 0x2400); +} + +void select_print_swell(gfxprint* gfxprint, UNUSED Game_Select* select) { + s32 swell = common_data.beeStingFlag; + gfxprint_locate8x8(gfxprint, 23, 13); + + if (swell == FALSE) { + gfxprint_printf(gfxprint, "ムシササレ :イタクナイ"); // 虫刺され: 痛くない (sting: painless) + } else { + gfxprint_printf(gfxprint, "ムシササレ :イタソウ"); // 虫刺され: 痛そう (sting: painful) + } +} + +void select_print_decoy(gfxprint* gfxprint, UNUSED Game_Select* select) { + s32 decoy = common_data.playerDecoyFlag; + 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] + } +} +void select_print_face_type(gfxprint* gfxprint, UNUSED Game_Select* select) { + static const char* Distinction[] = { GFXPRINT_HIRAGANA_MODE "タイプ1", GFXPRINT_HIRAGANA_MODE "タイプ2", + GFXPRINT_HIRAGANA_MODE "タイプ3", GFXPRINT_HIRAGANA_MODE "タイプ4", + GFXPRINT_HIRAGANA_MODE "タイプ5", GFXPRINT_HIRAGANA_MODE "タイプ6", + GFXPRINT_HIRAGANA_MODE "タイプ7", GFXPRINT_HIRAGANA_MODE "タイプ8" }; + + gfxprint_locate8x8(gfxprint, 23, 12); + gfxprint_printf(gfxprint, "カオ :%s", Distinction[common_data.privateInfo->face]); +} + +void select_print_event(gfxprint* gfxprint, UNUSED Game_Select* select) { + static const char* event_kind[] = { + GFXPRINT_KATAKANA_MODE "---", + GFXPRINT_KATAKANA_MODE "ザッカヤ", // (雑貨屋) (general store/shop) + GFXPRINT_KATAKANA_MODE "デザイナ-", // designer + GFXPRINT_KATAKANA_MODE "ブロ-カ-", // broker + GFXPRINT_KATAKANA_MODE "ガハク", // (画伯) artist + GFXPRINT_KATAKANA_MODE "ジュウタン", // (絨毯) carpet + GFXPRINT_KATAKANA_MODE "クロヒョウ" // (黒豹) black panther + }; + + gfxprint_locate8x8(gfxprint, 23, 16); + gfxprint_printf(gfxprint, GFXPRINT_KATAKANA_MODE "イベント :%s", event_kind[0]); +} + +typedef void (*SelectPrintProc)(gfxprint*, Game_Select*); + +void select_draw_main(Game_Select* select) { + static SelectPrintProc print_process[] = { + &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_event, + }; + + GraphicsContext* graph = select->state.gfxCtx; + s32 i; + + OPEN_DISPS(graph); + + gSPSegment(POLY_OPA_DISP++, 0, 0); + + DisplayList_initialize(graph, 0, 0, 0, NULL); + + SET_FULLSCREEN_VIEWPORT(&select->view); + showView(&select->view, 15); + + rect_moji(graph); + + { + gfxprint* gfxprint_p; + gfxprint_p = alloca(sizeof(gfxprint)); + + gfxprint_init(gfxprint_p); + gfxprint_open(gfxprint_p, 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 "-セッテイ-"); // -settings- + + for (i = 0; i < 10; i++) { + if (select->cursorY == i) { + if (select->status == 0) { + 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); + } + + POLY_OPA_DISP = (gfxprint_close(gfxprint_p)); + + gfxprint_cleanup(gfxprint_p); + } + CLOSE_DISPS(graph); +} + +void select_draw_wait(Game_Select* select) { + GraphicsContext* graph = select->state.gfxCtx; + gfxprint* gfxprint_p; + + OPEN_DISPS(graph); + + gSPSegment(POLY_OPA_DISP++, 0, 0); + + DisplayList_initialize(graph, 0, 0, 0, NULL); + + SET_FULLSCREEN_VIEWPORT(&select->view); + showView(&select->view, 15); + + rect_moji(graph); + { + gfxprint_p = alloca(sizeof(gfxprint)); + + gfxprint_init(gfxprint_p); + gfxprint_open(gfxprint_p, POLY_OPA_DISP); + + select_print_wait(gfxprint_p); + + POLY_OPA_DISP = (gfxprint_close(gfxprint_p)); + + gfxprint_cleanup(gfxprint_p); + } + CLOSE_DISPS(graph); +} + +void select_draw(Game_Select* select) { + GraphicsContext* graph = select->state.gfxCtx; + + OPEN_DISPS(graph); + + gSPSegment(POLY_OPA_DISP++, 0, 0); + + DisplayList_initialize(graph, 0, 0, 0, NULL); + + // FAKE !! + if (1) {} + if (1) {} + if (1) {} + if (1) {} + if (1) {} + if (1) {} + CLOSE_DISPS(graph); + + SET_FULLSCREEN_VIEWPORT(&select->view); + showView(&select->view, 15); + + if (select->state.running == FALSE) { + select_draw_wait(select); + } else { + select_draw_main(select); + } +} + +void select_main(Game* game) { + Game_Select* select = (Game_Select*)game; + + select_move(select); + select_draw(select); + + { + GraphicsContext* graph = game->gfxCtx; + game_debug_draw_last(game, graph); + game_draw_last(graph); + } +} + +void select_cleanup(UNUSED Game* game) { +} + +void select_init(Game* game) { + Game_Select* select = (Game_Select*)game; + s32 i; + + game->main = &select_main; + game->destroy = &select_cleanup; + + select->status = 0; + select->cursorY = 9; + select->step = 0; + select->stepAdd = 0; + + select->topScene = 0; + select->selectedScene = 0; + + initView(&select->view, game->gfxCtx); + select->view.unk_120 = 10; + + select->unk_234 = 0; + select->unk_238 = 0; + select->unk_23C = 0; + for (i = 0; i < PLAYER_NAME_LEN; i++) { + select->name[i] = fcode2data(common_data.privateInfo->playerId.playerName[i]); + } + if ((DORO(80) >= 0) && (DORO(80) < 0x23)) { + select->selectedScene = DORO(80); + select->topScene = DORO(81); + } + + SetGameFrame(1); + + common_data.unk_10004 = common_data.sceneNo; + common_data.unk_104AD = 0; + common_data.privateInfo->inventory.loan = 1000; + + mNpc_ClearEventNpc(); +} diff --git a/src/overlays/gamestates/ovl_select/m_select.h b/src/overlays/gamestates/ovl_select/m_select.h index ccfcfb3..8dbb323 100644 --- a/src/overlays/gamestates/ovl_select/m_select.h +++ b/src/overlays/gamestates/ovl_select/m_select.h @@ -4,13 +4,105 @@ #include "ultra64.h" #include "game.h" #include "unk.h" +#include "m_view.h" +#include "m_private_internals.h" + +typedef enum SelectCheck { + /* 0 */ SELECT_CHECK_A_BUTTON_RTC, + /* 1 */ SELECT_CHECK_A_BUTTON_TIME, + /* 2 */ SELECT_CHECK_A_BUTTON_STEP, + /* 3 */ SELECT_CHECK_A_BUTTON_WEATHER, + /* 4 */ SELECT_CHECK_A_BUTTON_SEX, + /* 5 */ SELECT_CHECK_A_BUTTON_FACE_TYPE, + /* 6 */ SELECT_CHECK_A_BUTTON_SWELL, + /* 7 */ SELECT_CHECK_A_BUTTON_DECOY, + /* 8 */ SELECT_CHECK_A_BUTTON_CLOTH, + /* 9 */ SELECT_CHECK_A_BUTTON_EVENT, + /* 10 */ SELECT_CHECK_A_BUTTON_NUM +} SelectCheck; + +struct lbRTC_time_c; +struct gfxprint; typedef struct Game_Select { - /* 0x00 */ Game state; - /* 0xE0 */ UNK_TYPE1 unk_00[0x240-0xE0]; + /* 0x000 */ Game state; + /* 0x0E0 */ Game_Play1938 view; + /* 0x208 */ s32 status; + /* 0x20C */ s32 cursorX; + /* 0x210 */ s32 cursorY; + /* 0x214 */ s32 step; + /* 0x218 */ s32 stepAdd; + /* 0x21C */ s32 selectedScene; + /* 0x220 */ s32 topScene; + /* 0x224 */ s32 unk224; + /* 0x228 */ s32 buttonStep; + /* 0x22C */ char name[PLAYER_NAME_LEN]; + /* 0x234 */ UNK_TYPE unk_234; + /* 0x238 */ UNK_TYPE unk_238; + /* 0x23C */ UNK_TYPE unk_23C; } Game_Select; // size = 0x240 -void select_init(Game *thisx); -void select_cleanup(Game *thisx); +typedef void (*GameProc)(Game*, s32); + +typedef struct NameFunction { + /* 0x0 */ const char* name; + /* 0x4 */ GameProc nextProc; + /* 0x8 */ s32 sceneNo; +} NameFunction; // size = 0xC + +void game_next_play(Game* game, s32 scene); +char data2fcode(char data); +char fcode2data(char fcode); +void select_pass(Game_Select* select); +s32 select_start_proc(Game_Select* select); +s32 select_check_start(Game_Select* select); +s32 select_check_A_button_rtc(Game_Select* select); +s32 select_check_A_button_time(Game_Select* select); +s32 select_check_A_buttonStep(Game_Select* select); +s32 select_check_A_button_weather(Game_Select* select); +s32 select_check_A_button_sex(Game_Select* select); +s32 select_check_A_button_face_type(Game_Select* select); +s32 select_check_A_button_swell(Game_Select* select); +s32 select_check_A_button_decoy(Game_Select* select); +s32 select_check_A_button_cloth(Game_Select* select); +s32 select_check_A_button_event(Game_Select* select); +s32 select_check_A_button(Game_Select* select); +s32 select_move_cursol(Game_Select* select); +s32 select_course_step_sub(s32 course); +void select_adjust_top_no(Game_Select* select, s32 course, s32 adjust); +void select_course_step(Game_Select* select, s32 addend); +void select_course(Game_Select* select); +void select_move_main(Game_Select* select); +void select_move_setup(Game_Select* select); +void select_move_time_year_set(s32 adjust); +void select_move_time_month_set(s32 adjust); +void select_move_time_day_set(s32 adjust); +void select_move_time_hour_set(s32 adjust); +void select_move_time_min_set(s32 adjust); +void select_move_time_week_set(s32 adjust); +void select_move_time_set(Game_Select* select); +void select_move_cloth_sel(Game_Select* select); +void select_move(Game_Select* select); +void select_print_wait(struct gfxprint* gfxprint); +void select_print_course_name(Game_Select* select, struct gfxprint* gfxprint); +void select_print_rtc(struct gfxprint* gfxprint, Game_Select* select); +void select_print_time_sub(struct gfxprint* gfxprint, Game_Select* select, struct lbRTC_time_c* time); +void select_print_time(struct gfxprint* gfxprint, Game_Select* select); +void select_print_step_sub2(struct gfxprint* gfxprint); +void select_print_step(struct gfxprint* gfxprint, Game_Select* select); +void select_print_weather(struct gfxprint* gfxprint, Game_Select* select); +void select_print_sex(struct gfxprint* gfxprint, Game_Select* select); +void select_print_cloth(struct gfxprint* gfxprint, Game_Select* select); +void select_print_swell(struct gfxprint* gfxprint, Game_Select* select); +void select_print_decoy(struct gfxprint* gfxprint, Game_Select* select); +void select_print_face_type(struct gfxprint* gfxprint, Game_Select* select); +void select_print_event(struct gfxprint* gfxprint, Game_Select* select); +void select_draw_main(Game_Select* select); +void select_draw_wait(Game_Select* select); +void select_draw(Game_Select* select); +void select_main(Game* game); +void select_cleanup(Game* game); +void select_init(Game* game); + #endif diff --git a/src/overlays/submenu/submenu_ovl/m_submenu_ovl.c b/src/overlays/submenu/submenu_ovl/m_submenu_ovl.c index 6bed36b..0bc469a 100644 --- a/src/overlays/submenu/submenu_ovl/m_submenu_ovl.c +++ b/src/overlays/submenu/submenu_ovl/m_submenu_ovl.c @@ -606,7 +606,7 @@ void mSM_setup_view(Submenu* submenu, GraphicsContext* gfxCtx, s32 arg1) { Mtx* mtx; UNUSED s32 pad; Gfx* gfx; - + Game_Play1938* view; if (arg1 != 0) { mtx = GRAPH_ALLOC(gfxCtx, sizeof(Mtx)); guOrtho(mtx, SCREEN_WIDTH * -8, SCREEN_WIDTH * 8, SCREEN_HEIGHT * -8, SCREEN_HEIGHT * 8, 1.0f, 2000.0f, 1.0f); @@ -619,17 +619,16 @@ void mSM_setup_view(Submenu* submenu, GraphicsContext* gfxCtx, s32 arg1) { gfx = POLY_OPA_DISP; if (arg1 == 0) { - Game_Play1938* var_a0; - if (submenu->unk_00 != 4) { - var_a0 = &((Game_Play*)gamePT)->unk_1938; + view = &((Game_Play*)gamePT)->unk_1938; } else { - var_a0 = &((Game__00743CD0*)gamePT)->unk_00E0; + view = &((Game__00743CD0*)gamePT)->unk_00E0; } gDPPipeSync(gfx++); - gDPSetScissor(gfx++, G_SC_NON_INTERLACE, var_a0->unk_010, var_a0->unk_008, var_a0->unk_014, var_a0->unk_00C); - gSPViewport(gfx++, &var_a0->vp); + gDPSetScissor(gfx++, G_SC_NON_INTERLACE, view->viewport.leftX, view->viewport.topY, view->viewport.rightX, + view->viewport.bottomY); + gSPViewport(gfx++, &view->vp); gDPSetColorImage(gfx++, G_IM_FMT_RGBA, G_IM_SIZ_16b, SCREEN_WIDTH, gfxCtx->unk_2E4); gDPSetScissor(gfx++, G_SC_NON_INTERLACE, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT); } diff --git a/yamls/jp/overlays.yaml b/yamls/jp/overlays.yaml index 69297c9..900a575 100644 --- a/yamls/jp/overlays.yaml +++ b/yamls/jp/overlays.yaml @@ -5,9 +5,9 @@ compress: True bss_size: 0x0 subsegments: - - [0x73F4D0, asm, overlays/gamestates/ovl_select/m_select] - - [0x741030, data, overlays/gamestates/ovl_select/m_select] - - [0x741310, rodata, overlays/gamestates/ovl_select/m_select] + - [0x73F4D0, c, overlays/gamestates/ovl_select/m_select] + - [0x741030, .data, overlays/gamestates/ovl_select/m_select] + - [0x741310, .rodata, overlays/gamestates/ovl_select/m_select] - name: ovl_select_reloc type: code start: 0x741A40 |
