summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPrakxo <87568477+Prakxo@users.noreply.github.com>2023-12-21 16:50:42 +0100
committerGitHub <noreply@github.com>2023-12-21 08:50:42 -0700
commit72514d5aae62cc9789b2de0d3d3ba764be2c168d (patch)
treeb3e91ff0fd9320f6ee021f8cebd046683f0cd5d4
parent45e93dc1b6a859a5f27f3f2b52630598a8d11ad1 (diff)
m_select OK (#128)
* m_select OK * format
-rw-r--r--include/6BA500.h2
-rw-r--r--include/libu64/gfxprint.h8
-rw-r--r--include/m_common_data.h15
-rw-r--r--include/m_private.h19
-rw-r--r--include/m_private_internals.h6
-rw-r--r--include/m_rcp.h2
-rw-r--r--include/m_scene_table.h42
-rw-r--r--include/m_view.h33
-rw-r--r--linker_scripts/jp/symbol_addrs_code.txt2
-rw-r--r--linker_scripts/jp/symbol_addrs_overlays.txt115
-rw-r--r--src/code/m_start_data_init.c2
-rw-r--r--src/overlays/gamestates/ovl_play/m_play.c8
-rw-r--r--src/overlays/gamestates/ovl_select/m_select.c969
-rw-r--r--src/overlays/gamestates/ovl_select/m_select.h100
-rw-r--r--src/overlays/submenu/submenu_ovl/m_submenu_ovl.c13
-rw-r--r--yamls/jp/overlays.yaml6
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