From b6cb7edd194bdc4debf861cff6a929cdb4fc71bf Mon Sep 17 00:00:00 2001 From: Cuyler36 Date: Thu, 3 Apr 2025 11:02:58 -0400 Subject: [PATCH] Implement & link m_address_ovl --- configure.py | 2 +- include/audio_defs.h | 2 + include/m_address_ovl.h | 47 ++- include/m_mail.h | 5 +- src/game/m_address_ovl.c | 753 +++++++++++++++++++++++++++++++++++++++ src/game/m_editor_ovl.c | 4 +- src/game/m_mail.c | 6 +- 7 files changed, 800 insertions(+), 19 deletions(-) create mode 100644 src/game/m_address_ovl.c diff --git a/configure.py b/configure.py index a121033e..0cc2644b 100644 --- a/configure.py +++ b/configure.py @@ -1366,7 +1366,7 @@ config.libs = [ Object(Matching, "game/m_actor.c"), Object(Matching, "game/m_actor_dlftbls.c"), Object(Matching, "game/m_actor_shadow.c"), - Object(NonMatching, "game/m_address_ovl.c"), + Object(Matching, "game/m_address_ovl.c"), Object(Matching, "game/m_all_grow.c"), Object(Matching, "game/m_all_grow_ovl.c"), Object(Matching, "game/m_bank_ovl.c"), diff --git a/include/audio_defs.h b/include/audio_defs.h index 770df727..f050167d 100644 --- a/include/audio_defs.h +++ b/include/audio_defs.h @@ -64,6 +64,8 @@ typedef enum audio_sound_effects { NA_SE_31 = 0x31, NA_SE_32 = 0x32, NA_SE_33 = 0x33, + NA_SE_34 = 0x34, + NA_SE_35 = 0x35, NA_SE_DRAWER_SHUT = 0x3A, diff --git a/include/m_address_ovl.h b/include/m_address_ovl.h index 0c6ea56d..bba8943a 100644 --- a/include/m_address_ovl.h +++ b/include/m_address_ovl.h @@ -10,22 +10,47 @@ extern "C" { #endif -#define mAD_PAGE_NUM 3 +enum { + mAD_PAGE_PLAYER, + mAD_PAGE_NPC0, + mAD_PAGE_NPC1, + + mAD_PAGE_NUM +}; + +enum { + mAD_PROC_REFUSE, + mAD_PROC_START, + mAD_PROC_SELECT, + mAD_PROC_TURN_PAGE, + mAD_PROC_TURN_PAGE2, + + mAD_PROC_NUM +}; + +enum { + mAD_OPEN_ADDRESS, + mAD_OPEN_WAIT, + + mAD_OPEN_NUM +}; + +#define mAD_PAGE_MAX_ENTRIES 8 struct address_ovl_s { - u8 _00; - u8 _01; - u8 command; - u8 _03; - u8 _04; + u8 page_bitfield; + u8 page_count; + u8 proc_idx; + u8 curIdx; + u8 nextIdx; u8 selected_entry; u8 show_museum_address; - u8 _07; + u8 editor_move_down; u8 page_entry_count[mAD_PAGE_NUM]; - f32 _0C; - f32 _10; - f32 _14[mAD_PAGE_NUM]; - f32 _20[mAD_PAGE_NUM]; + f32 pos_x; + f32 speed_x; + f32 pile[mAD_PAGE_NUM]; + f32 goal_pile[mAD_PAGE_NUM]; Mail_nm_c player_mail_name[PLAYER_NUM + 1]; // last entry is the museum name Mail_nm_c animal_mail_name[ANIMAL_NUM_MAX]; Gfx* display_list; // set to the beginning of the address display list data for drawing over editor etc diff --git a/include/m_mail.h b/include/m_mail.h index 088e3f5f..136e6c4c 100644 --- a/include/m_mail.h +++ b/include/m_mail.h @@ -10,7 +10,8 @@ extern "C" { #endif -#define MAIL_HEADER_LEN (32 - PLAYER_NAME_LEN) +#define MAIL_HEADER_BASE_LEN 32 +#define MAIL_HEADER_LEN (MAIL_HEADER_BASE_LEN - PLAYER_NAME_LEN) #define MAIL_FOOTER_LEN 32 #define MAIL_BODY_LEN 192 @@ -108,7 +109,7 @@ extern void mMl_clear_mail_header(Mail_hdr_c* header); extern void mMl_clear_mail(Mail_c* mail); extern void mMl_clear_mail_box(Mail_c* mail, int num); extern int mMl_check_not_used_mail(Mail_c* mail); -extern void mMl_copy_header_name(Mail_c* dst, Mail_c* src); +extern void mMl_copy_header_name(Mail_nm_c* dst, Mail_nm_c* src); extern void mMl_set_to_plname(Mail_c* mail, PersonalID_c* pid); extern void mMl_set_playername(Mail_c* mail, PersonalID_c* pid); extern void mMl_init_mail(Mail_c* mail, PersonalID_c* pid); diff --git a/src/game/m_address_ovl.c b/src/game/m_address_ovl.c new file mode 100644 index 00000000..a0592c70 --- /dev/null +++ b/src/game/m_address_ovl.c @@ -0,0 +1,753 @@ +#include "m_address_ovl.h" + +#include "m_common_data.h" +#include "m_board_ovl.h" +#include "m_editor_ovl.h" +#include "m_font.h" +#include "sys_matrix.h" + +static mAD_Ovl_c adrs_ovl_data; + +static Vtx lat_atena_v[48] = { + // Page 0 + { {{0xFFE1, 0xFFF3, 0x0000}, 0x0001, {0x0000, 0x0200}, {0xCA, 0xCA, 0xCA, 0xCA}} }, + { {{0xFFE1, 0xFFE2, 0x0000}, 0x0001, {0x0000, 0x0400}, {0xCA, 0xCA, 0xCA, 0xCA}} }, + { {{0x002D, 0xFFF3, 0x0000}, 0x0001, {0x0800, 0x0200}, {0xFF, 0xFF, 0xFF, 0xFF}} }, + { {{0x002D, 0xFFE2, 0x0000}, 0x0001, {0x0800, 0x0400}, {0xFF, 0xFF, 0xFF, 0xFF}} }, + { {{0xFFE1, 0xFFFD, 0x0000}, 0x0001, {0x0000, 0x0200}, {0x98, 0x98, 0x98, 0x98}} }, + { {{0x002D, 0xFFFD, 0x0000}, 0x0001, {0x0800, 0x0200}, {0x98, 0x98, 0x98, 0x98}} }, + { {{0x002D, 0x000E, 0x0000}, 0x0001, {0x0800, 0x0000}, {0x98, 0x98, 0x98, 0x98}} }, + { {{0xFFE1, 0x000E, 0x0000}, 0x0001, {0x0000, 0x0000}, {0x98, 0x98, 0x98, 0x98}} }, + { {{0xFFDE, 0x0011, 0x0000}, 0x0001, {0x0000, 0x0000}, {0x00, 0x00, 0x00, 0x00}} }, + { {{0xFFDE, 0x0000, 0x0000}, 0x0001, {0x0000, 0x0200}, {0x00, 0x00, 0x00, 0x00}} }, + { {{0x002A, 0x0011, 0x0000}, 0x0001, {0x0800, 0x0000}, {0x00, 0x00, 0x00, 0x00}} }, + { {{0x002A, 0x0000, 0x0000}, 0x0001, {0x0800, 0x0200}, {0x00, 0x00, 0x00, 0x00}} }, + { {{0xFFDE, 0xFFF6, 0x0000}, 0x0001, {0x0000, 0x0200}, {0x32, 0x32, 0x32, 0x32}} }, + { {{0x002A, 0xFFF6, 0x0000}, 0x0001, {0x0800, 0x0200}, {0x64, 0x64, 0x64, 0x64}} }, + { {{0xFFDE, 0xFFE5, 0x0000}, 0x0001, {0x0000, 0x0400}, {0x32, 0x32, 0x32, 0x32}} }, + { {{0x002A, 0xFFE5, 0x0000}, 0x0001, {0x0800, 0x0400}, {0x64, 0x64, 0x64, 0x64}} }, + // Page 1 + { {{0xFFE1, 0xFFF3, 0x0000}, 0x0001, {0x0000, 0x0200}, {0xCA, 0xCA, 0xCA, 0xCA}} }, + { {{0xFFE1, 0xFFE2, 0x0000}, 0x0001, {0x0000, 0x0400}, {0xCA, 0xCA, 0xCA, 0xCA}} }, + { {{0x002D, 0xFFF3, 0x0000}, 0x0001, {0x0800, 0x0200}, {0xFF, 0xFF, 0xFF, 0xFF}} }, + { {{0x002D, 0xFFE2, 0x0000}, 0x0001, {0x0800, 0x0400}, {0xFF, 0xFF, 0xFF, 0xFF}} }, + { {{0xFFE1, 0xFFFD, 0x0000}, 0x0001, {0x0000, 0x0200}, {0x98, 0x98, 0x98, 0x98}} }, + { {{0x002D, 0xFFFD, 0x0000}, 0x0001, {0x0800, 0x0200}, {0x98, 0x98, 0x98, 0x98}} }, + { {{0x002D, 0x000E, 0x0000}, 0x0001, {0x0800, 0x0000}, {0x98, 0x98, 0x98, 0x98}} }, + { {{0xFFE1, 0x000E, 0x0000}, 0x0001, {0x0000, 0x0000}, {0x98, 0x98, 0x98, 0x98}} }, + { {{0xFFDE, 0x0011, 0x0000}, 0x0001, {0x0000, 0x0000}, {0x00, 0x00, 0x00, 0x00}} }, + { {{0xFFDE, 0x0000, 0x0000}, 0x0001, {0x0000, 0x0200}, {0x00, 0x00, 0x00, 0x00}} }, + { {{0x002A, 0x0011, 0x0000}, 0x0001, {0x0800, 0x0000}, {0x00, 0x00, 0x00, 0x00}} }, + { {{0x002A, 0x0000, 0x0000}, 0x0001, {0x0800, 0x0200}, {0x00, 0x00, 0x00, 0x00}} }, + { {{0xFFDE, 0xFFF6, 0x0000}, 0x0001, {0x0000, 0x0200}, {0x32, 0x32, 0x32, 0x32}} }, + { {{0x002A, 0xFFF6, 0x0000}, 0x0001, {0x0800, 0x0200}, {0x64, 0x64, 0x64, 0x64}} }, + { {{0xFFDE, 0xFFE5, 0x0000}, 0x0001, {0x0000, 0x0400}, {0x32, 0x32, 0x32, 0x32}} }, + { {{0x002A, 0xFFE5, 0x0000}, 0x0001, {0x0800, 0x0400}, {0x64, 0x64, 0x64, 0x64}} }, + // Page 2 + { {{0xFFE1, 0xFFF3, 0x0000}, 0x0001, {0x0000, 0x0200}, {0xCA, 0xCA, 0xCA, 0xCA}} }, + { {{0xFFE1, 0xFFE2, 0x0000}, 0x0001, {0x0000, 0x0400}, {0xCA, 0xCA, 0xCA, 0xCA}} }, + { {{0x002D, 0xFFF3, 0x0000}, 0x0001, {0x0800, 0x0200}, {0xFF, 0xFF, 0xFF, 0xFF}} }, + { {{0x002D, 0xFFE2, 0x0000}, 0x0001, {0x0800, 0x0400}, {0xFF, 0xFF, 0xFF, 0xFF}} }, + { {{0xFFE1, 0xFFFD, 0x0000}, 0x0001, {0x0000, 0x0200}, {0x98, 0x98, 0x98, 0x98}} }, + { {{0x002D, 0xFFFD, 0x0000}, 0x0001, {0x0800, 0x0200}, {0x98, 0x98, 0x98, 0x98}} }, + { {{0x002D, 0x000E, 0x0000}, 0x0001, {0x0800, 0x0000}, {0x98, 0x98, 0x98, 0x98}} }, + { {{0xFFE1, 0x000E, 0x0000}, 0x0001, {0x0000, 0x0000}, {0x98, 0x98, 0x98, 0x98}} }, + { {{0xFFDE, 0x0011, 0x0000}, 0x0001, {0x0000, 0x0000}, {0x00, 0x00, 0x00, 0x00}} }, + { {{0xFFDE, 0x0000, 0x0000}, 0x0001, {0x0000, 0x0200}, {0x00, 0x00, 0x00, 0x00}} }, + { {{0x002A, 0x0011, 0x0000}, 0x0001, {0x0800, 0x0000}, {0x00, 0x00, 0x00, 0x00}} }, + { {{0x002A, 0x0000, 0x0000}, 0x0001, {0x0800, 0x0200}, {0x00, 0x00, 0x00, 0x00}} }, + { {{0xFFDE, 0xFFF6, 0x0000}, 0x0001, {0x0000, 0x0200}, {0x32, 0x32, 0x32, 0x32}} }, + { {{0x002A, 0xFFF6, 0x0000}, 0x0001, {0x0800, 0x0200}, {0x64, 0x64, 0x64, 0x64}} }, + { {{0xFFDE, 0xFFE5, 0x0000}, 0x0001, {0x0000, 0x0400}, {0x32, 0x32, 0x32, 0x32}} }, + { {{0x002A, 0xFFE5, 0x0000}, 0x0001, {0x0800, 0x0400}, {0x64, 0x64, 0x64, 0x64}} }, +}; + +static u8 l_shop_name_str[ANIMAL_NAME_LEN] = "\x0F\x16\x06\x10 \0\0"; // たぬきち \0\0 (Tanukichi, Tom Nook) +static u8 mAD_title_str[20] = "Choose an addressee."; +static u8 mAD_title_str2[27] = "Your address book is empty!"; + +static void mAD_cancel_edit(Submenu* submenu, mSM_MenuInfo_c* menu_info) { + mSM_MenuInfo_c* prev_menu = &submenu->overlay->menu_info[menu_info->pre_menu_type]; + + if (prev_menu->proc_status == mSM_OVL_PROC_PLAY) { + submenu->overlay->return_func_proc(submenu, menu_info); + submenu->overlay->move_chg_base_proc(prev_menu, mSM_MOVE_OUT_TOP); + sAdo_SysTrgStart(MONO(NA_SE_3)); + } +} + +static int mAD_get_nextIdx(mAD_Ovl_c* adrs_ovl, int idx, int add) { + int next_idx = idx; + + if (adrs_ovl->page_count <= 1) { + next_idx = -1; + } else { + int flags = adrs_ovl->page_bitfield; + int i; + + for (i = 0; i < 2; i++) { + next_idx += add; + if (next_idx == 3) { + next_idx = 0; + } else if (next_idx < 0) { + next_idx = 2; + } + + if ((flags >> next_idx) & 1) { + break; + } + } + } + + return next_idx; +} + +static void mAD_pile_init(mAD_Ovl_c* adrs_ovl, f32* pile, int idx) { + if (adrs_ovl->page_count == 2) { + if (idx == 0) { + pile[0] = 0.0f; + pile[1] = 5.0f; + pile[2] = 0.0f; + } else { + pile[0] = 5.0f; + pile[1] = 0.0f; + pile[2] = 5.0f; + } + } else if (adrs_ovl->page_count == 3) { + pile[idx] = 0.0f; + pile[(idx + 1) % mAD_PAGE_NUM] = 5.0f; + pile[(idx + 2) % mAD_PAGE_NUM] = 10.0f; + } else { + pile[0] = 0.0f; + pile[1] = 0.0f; + pile[2] = 0.0f; + } +} + +static void mAD_move_between(Submenu* submenu, int add) { + int idx; + mAD_Ovl_c* adrs_ovl = submenu->overlay->address_ovl; + + idx = mAD_get_nextIdx(adrs_ovl, adrs_ovl->curIdx, add); + if (idx != -1) { + adrs_ovl->proc_idx = mAD_PROC_TURN_PAGE; + if (add == -1) { + adrs_ovl->speed_x = 0.5f; + } else { + adrs_ovl->speed_x = -0.5f; + } + + adrs_ovl->nextIdx = idx; + mAD_pile_init(adrs_ovl, adrs_ovl->goal_pile, idx); + sAdo_SysTrgStart(NA_SE_41C); + } +} + +static void mAD_move_cursol(Submenu* submenu) { + mAD_Ovl_c* adrs_ovl = submenu->overlay->address_ovl; + u32 trigger = submenu->overlay->menu_control.trigger; + + if ((trigger & BUTTON_CLEFT)) { + mAD_move_between(submenu, -1); + } else if ((trigger & BUTTON_CDOWN)) { + if (adrs_ovl->selected_entry < adrs_ovl->page_entry_count[adrs_ovl->curIdx] - 1) { + adrs_ovl->selected_entry++; + sAdo_SysTrgStart(NA_SE_CURSOL); + } else { + mAD_move_between(submenu, 1); + } + } else if ((trigger & BUTTON_CUP)) { + if (adrs_ovl->selected_entry != 0) { + adrs_ovl->selected_entry--; + sAdo_SysTrgStart(NA_SE_CURSOL); + } else { + mAD_move_between(submenu, -1); + } + } else if ((trigger & BUTTON_CRIGHT)) { + mAD_move_between(submenu, 1); + } +} + +static void mAD_make_player_address(mAD_Ovl_c* adrs_ovl) { + int player_no = Common_Get(player_no); + Mail_nm_c* name_p = adrs_ovl->player_mail_name; + u8* count_p = &adrs_ovl->page_entry_count[mAD_PAGE_PLAYER]; + PersonalID_c* pid; + int i; + + *count_p = 0; + for (i = 0; i < PLAYER_NUM; i++) { + if (i != player_no) { + pid = &Save_Get(private_data[i]).player_ID; + + if (mPr_NullCheckPersonalID(pid) == FALSE) { + mPr_CopyPersonalID(&name_p->personalID, pid); + name_p->type = mMl_NAME_TYPE_PLAYER; + name_p++; + (*count_p)++; + } + } + } + + if (mPr_CheckMuseumAddress(Now_Private)) { + mMsm_GetMuseumMailName(name_p); + (*count_p)++; + adrs_ovl->show_museum_address = TRUE; + } else { + adrs_ovl->show_museum_address = FALSE; + } +} + +static void mAD_make_npc_address(mAD_Ovl_c* adrs_ovl) { + Animal_c* animal_p = Save_Get(animals); + Mail_nm_c* name_p = adrs_ovl->animal_mail_name; + PersonalID_c* pid = &Now_Private->player_ID; + int i; + int count; + + count = 0; + for (i = 0; i < ANIMAL_NUM_MAX; i++) { + if (mNpc_CheckFreeAnimalPersonalID(&animal_p->id) == FALSE && + mNpc_GetAnimalMemoryIdx(pid, animal_p->memories, ANIMAL_MEMORY_NUM) != -1) { + mMl_set_mail_name_npcinfo(name_p, &animal_p->id); + name_p++; + count++; + } + + animal_p++; + } + + if (count < mAD_PAGE_MAX_ENTRIES) { + adrs_ovl->page_entry_count[mAD_PAGE_NPC0] = count; + adrs_ovl->page_entry_count[mAD_PAGE_NPC1] = 0; + } else { + adrs_ovl->page_entry_count[mAD_PAGE_NPC0] = mAD_PAGE_MAX_ENTRIES; + adrs_ovl->page_entry_count[mAD_PAGE_NPC1] = count - mAD_PAGE_MAX_ENTRIES; + } +} + +static void mAD_refuse_proc(Submenu* submenu, mSM_MenuInfo_c* menu_info) { + if (submenu->overlay->menu_control.trigger & (BUTTON_A | BUTTON_B | BUTTON_START)) { + mAD_cancel_edit(submenu, menu_info); + } +} + +static void mAD_start_proc(Submenu* submenu, mSM_MenuInfo_c* menu_info) { + mAD_Ovl_c* adrs_ovl = submenu->overlay->address_ovl; + u32 trigger = submenu->overlay->menu_control.trigger; + + if (trigger & BUTTON_B) { + mAD_cancel_edit(submenu, menu_info); + } else if (trigger & (BUTTON_A | BUTTON_START)) { + adrs_ovl->proc_idx = mAD_PROC_SELECT; + sAdo_SysTrgStart(NA_SE_MENU_EXIT); + mAD_pile_init(adrs_ovl, adrs_ovl->pile, adrs_ovl->curIdx); + adrs_ovl->selected_entry = 0; + } +} + +static void mAD_select_proc(Submenu* submenu, mSM_MenuInfo_c* menu_info) { + mBD_Ovl_c* board_ovl; + mAD_Ovl_c* adrs_ovl; + u32 trigger; + Mail_nm_c* name_p; + + adrs_ovl = submenu->overlay->address_ovl; + board_ovl = submenu->overlay->board_ovl; + trigger = submenu->overlay->menu_control.trigger; + if (trigger & BUTTON_B) { + if (board_ovl->first == TRUE) { + mAD_cancel_edit(submenu, menu_info); + } else { + board_ovl->header_pos = 0; + menu_info->proc_status = mSM_OVL_PROC_WAIT; + sAdo_SysTrgStart(MONO(NA_SE_3)); + } + } else if (trigger & (BUTTON_A | BUTTON_START)) { + if (adrs_ovl->curIdx == 0) { + name_p = &adrs_ovl->player_mail_name[adrs_ovl->selected_entry]; + } else if (adrs_ovl->curIdx == 2) { + name_p = &adrs_ovl->animal_mail_name[mAD_PAGE_MAX_ENTRIES + adrs_ovl->selected_entry]; + } else { + name_p = &adrs_ovl->animal_mail_name[adrs_ovl->selected_entry]; + } + + mMl_copy_header_name(&board_ovl->mail.header.recipient, name_p); + board_ovl->header_name_len = mMl_strlen(name_p->personalID.player_name, PLAYER_NAME_LEN, CHAR_SPACE); + board_ovl->header_pos = 2; + menu_info->proc_status = mSM_OVL_PROC_WAIT; + + if (submenu->overlay->board_ovl->first == TRUE) { + mSM_open_submenu_new2(submenu, mSM_OVL_EDITOR, mED_TYPE_BOARD, MAIL_HEADER_BASE_LEN, menu_info->data2, menu_info->data3); + submenu->overlay->board_ovl->first = FALSE; + } + + sAdo_SysTrgStart(NA_SE_MENU_EXIT); + } else { + mAD_move_cursol(submenu); + + if (submenu->overlay->board_ovl->first == FALSE) { + if (trigger & BUTTON_DLEFT) { + sAdo_SysTrgStart(NA_SE_35); + board_ovl->header_pos = 0; + menu_info->proc_status = mSM_OVL_PROC_WAIT; + } else if (trigger & BUTTON_DRIGHT) { + sAdo_SysTrgStart(NA_SE_35); + board_ovl->header_pos = 2; + menu_info->proc_status = mSM_OVL_PROC_WAIT; + } else if (trigger & BUTTON_DDOWN) { + adrs_ovl->editor_move_down = TRUE; + sAdo_SysTrgStart(NA_SE_35); + board_ovl->header_pos = 0; + menu_info->proc_status = mSM_OVL_PROC_WAIT; + } + } + } +} + +static void mAD_turn_page_proc(Submenu* submenu, mSM_MenuInfo_c* menu_info) { + mAD_Ovl_c* adrs_ovl = submenu->overlay->address_ovl; + u8 idx; + int i; + f32 pos; + + pos = adrs_ovl->pos_x; + if (fabsf(pos) < 14.0f) { + adrs_ovl->speed_x *= sqrtf(2.0f); + } else if (fabsf(pos) > 30.0f) { + adrs_ovl->speed_x *= sqrtf(0.5f); + + if (fabsf(adrs_ovl->speed_x) < 0.25f) { + idx = adrs_ovl->curIdx; + adrs_ovl->curIdx = adrs_ovl->nextIdx; + adrs_ovl->nextIdx = idx; + adrs_ovl->proc_idx = mAD_PROC_TURN_PAGE2; + + if (adrs_ovl->speed_x < 0.0f) { + adrs_ovl->selected_entry = 0; + } else { + adrs_ovl->selected_entry = adrs_ovl->page_entry_count[adrs_ovl->curIdx] - 1; + } + + mAD_pile_init(adrs_ovl, adrs_ovl->pile, adrs_ovl->curIdx); + adrs_ovl->pos_x *= -1.0f; + return; + } + } + + adrs_ovl->pos_x += adrs_ovl->speed_x; + for (i = 0; i < mAD_PAGE_NUM; i++) { + chase_f(&adrs_ovl->pile[i], adrs_ovl->goal_pile[i], 0.6f); + } +} + +static void mAD_turn_page2_proc(Submenu* submenu, mSM_MenuInfo_c* menu_info) { + mAD_Ovl_c* adrs_ovl = submenu->overlay->address_ovl; + f32 pos; + + pos = adrs_ovl->pos_x; + + if (fabsf(pos) > 30.0f) { + adrs_ovl->speed_x *= sqrtf(2.0f); + } else if (fabsf(pos) < 14.0f) { + adrs_ovl->speed_x *= sqrtf(0.5f); + } + + adrs_ovl->pos_x += adrs_ovl->speed_x; + if (adrs_ovl->pos_x * adrs_ovl->speed_x > 0.0f) { + adrs_ovl->pos_x = 0.0f; + adrs_ovl->speed_x = 0.0f; + adrs_ovl->proc_idx = mAD_PROC_SELECT; + } +} + +typedef void (*mAD_PLAY_PROC)(Submenu* submenu, mSM_MenuInfo_c* menu_info); + +static void mAD_move_Play(Submenu* submenu, mSM_MenuInfo_c* menu_info) { + static mAD_PLAY_PROC play_process[] = { + // clang-format off + mAD_refuse_proc, + mAD_start_proc, + mAD_select_proc, + mAD_turn_page_proc, + mAD_turn_page2_proc, + // clang-format on + }; + + (*play_process[submenu->overlay->address_ovl->proc_idx])(submenu, menu_info); +} + +static void mAD_move_Wait(Submenu* submenu, mSM_MenuInfo_c* menu_info) { + mAD_Ovl_c* adrs_ovl = submenu->overlay->address_ovl; + mBD_Ovl_c* board_ovl = submenu->overlay->board_ovl; + + menu_info->next_proc_status = mSM_OVL_PROC_PLAY; + if (board_ovl->header_pos == 1) { + menu_info->proc_status = mSM_OVL_PROC_PLAY; + menu_info->next_proc_status = mSM_OVL_PROC_WAIT; + adrs_ovl->proc_idx = mAD_PROC_SELECT; + adrs_ovl->selected_entry = 0; + + if (adrs_ovl->page_entry_count[mAD_PAGE_PLAYER] != 0) { + adrs_ovl->curIdx = mAD_PAGE_PLAYER; + } else if (adrs_ovl->page_entry_count[mAD_PAGE_NPC0] != 0) { + adrs_ovl->curIdx = mAD_PAGE_NPC0; + } + + mAD_pile_init(adrs_ovl, adrs_ovl->pile, adrs_ovl->curIdx); + } +} + +static void mAD_move_End(Submenu* submenu, mSM_MenuInfo_c* menu_info) { + (*submenu->overlay->move_End_proc)(submenu, menu_info); +} + +static void mAD_address_ovl_move(Submenu* submenu) { + static mSM_MOVE_PROC ovl_move_proc[] = { + // clang-format off + (mSM_MOVE_PROC)none_proc1, + mAD_move_Play, + mAD_move_Wait, + (mSM_MOVE_PROC)none_proc1, + mAD_move_End, + // clang-format on + }; + + mSM_MenuInfo_c* menu_info = &submenu->overlay->menu_info[mSM_OVL_ADDRESS]; + + (*menu_info->pre_move_func)(submenu); + (*ovl_move_proc[menu_info->proc_status])(submenu, menu_info); +} + +static void mAD_address_draw_init(Submenu* submenu) { + Vtx* vtx_p; + int i; + int count; + int ofs; + + for (i = 0; i < mAD_PAGE_NUM; i++) { + count = submenu->overlay->address_ovl->page_entry_count[i] - 1; + + if (count >= 0) { + vtx_p = &lat_atena_v[i * 16]; + + if (i == mAD_PAGE_PLAYER && submenu->overlay->address_ovl->show_museum_address && count > 0) { + count++; + } + + // ofs = (int)(count * 12.857142f); + ofs = (int)(count * (90.0f / (mAD_PAGE_MAX_ENTRIES - 1))); + vtx_p[12].v.ob[1] = vtx_p[9].v.ob[1] - ofs; + vtx_p[13].v.ob[1] = vtx_p[11].v.ob[1] - ofs; + vtx_p[14].v.ob[1] = vtx_p[12].v.ob[1] - 17; + vtx_p[15].v.ob[1] = vtx_p[13].v.ob[1] - 17; + + vtx_p[0].v.ob[1] = vtx_p[4].v.ob[1] - ofs; + vtx_p[2].v.ob[1] = vtx_p[5].v.ob[1] - ofs; + vtx_p[1].v.ob[1] = vtx_p[0].v.ob[1] - 17; + vtx_p[3].v.ob[1] = vtx_p[2].v.ob[1] - 17; + } + } +} + +extern Gfx lat_mes_winT_model[]; + +static void mAD_set_first_tag(Submenu* submenu, GAME* game, GRAPH* graph, f32 pos_x, f32 pos_y) { + static u8* title_table[] = { mAD_title_str, mAD_title_str2 }; + static int title_length[] = { sizeof(mAD_title_str), sizeof(mAD_title_str2) }; + static f32 offset[][2] = { { -66.0f, 8.0f }, { -90.0f, 8.0f } }; + u8* title_p; + int len; + f32* ofs_p; + int idx; + + idx = 0; + Matrix_scale(16.0f, 16.0f, 1.0f, 0); + Matrix_translate(pos_x, pos_y, 140.0f, 1); + + OPEN_POLY_OPA_DISP(graph); + + gSPMatrix(POLY_OPA_DISP++, _Matrix_to_Mtx_new(graph), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, lat_mes_winT_model); + + CLOSE_POLY_OPA_DISP(graph); + + + (*submenu->overlay->set_char_matrix_proc)(graph); + if (submenu->overlay->address_ovl->proc_idx == mAD_PROC_REFUSE) { + idx = 1; + } + + title_p = title_table[idx]; + len = title_length[idx]; + mFont_SetLineStrings(game, title_p, len, 160.0f + (pos_x + offset[idx][0]), 120.0f - (pos_y + offset[idx][1]), 80, 80, 230, 255, FALSE, TRUE, 1.0f, 1.0f, mFont_MODE_POLY); +} + +extern Gfx lat_atena_model[]; +extern Gfx lat_atena_winT_model[]; + +static void mAD_set_addressSel_tag_field(GRAPH* graph, f32 pos_x, f32 pos_y, int idx, int col_idx) { + static rgba_t prim_color[2][3] = { + // clang-format off + { { 215, 225, 70, 255 }, { 205, 205, 80, 255 }, { 150, 150, 40, 255 } }, + { { 145, 255, 100, 255 }, { 115, 225, 80, 255 }, { 100, 190, 60, 255 } }, + // clang-format on + }; + + rgba_t* color_p = &prim_color[idx != 0][col_idx]; + + Matrix_scale(16.0f, 16.0f, 1.0f, 0); + Matrix_translate(pos_x, pos_y, 140.0f, 1); + + OPEN_POLY_OPA_DISP(graph); + + gSPSegment(POLY_OPA_DISP++, ANIME_1_TXT_SEG, &lat_atena_v[idx * 16] + 8); + gSPSegment(POLY_OPA_DISP++, ANIME_2_TXT_SEG, &lat_atena_v[idx * 16] + 0); + gSPMatrix(POLY_OPA_DISP++, _Matrix_to_Mtx_new(graph), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, lat_atena_model); + gDPSetPrimColor(POLY_OPA_DISP++, 0, 255, color_p->r, color_p->g, color_p->b, 255); + gSPDisplayList(POLY_OPA_DISP++, lat_atena_winT_model); + + CLOSE_POLY_OPA_DISP(graph); +} + +static void mAD_set_addressSel_tag_character(Submenu* submenu, GAME* game, f32 pos_x, f32 pos_y, int idx) { + static rgba_t address_color[5] = { + // clang-format off + { 110, 115, 50, 255 }, + { 0, 135, 20, 255 }, + { 150, 120, 20, 255 }, + { 55, 30, 50, 255 }, + { 75, 60, 0, 255 }, + // clang-format on + }; + + mAD_Ovl_c* adrs_ovl = submenu->overlay->address_ovl; + int flag = idx == adrs_ovl->curIdx && adrs_ovl->proc_idx == mAD_PROC_SELECT; + int count; + Mail_nm_c* name_p; + int i; + f32 ofs_y; + rgba_t* color_p; + + count = adrs_ovl->page_entry_count[idx]; + ofs_y = (11.0f + (count - 1) * (3.0f / (mAD_PAGE_MAX_ENTRIES - 1))); + pos_x = 160.0f + ((pos_x + 7.0f) + -34.0f); + pos_y = 120.0f - ((pos_y - ofs_y) + 17.0f); + if (idx == mAD_PAGE_PLAYER) { + name_p = adrs_ovl->player_mail_name; + } else if (idx == mAD_PAGE_NPC0) { + name_p = &adrs_ovl->animal_mail_name[0]; + } else { + name_p = &adrs_ovl->animal_mail_name[mAD_PAGE_MAX_ENTRIES]; + } + + for (i = 0; i < count; i++, name_p++) { + if (flag == TRUE && i == adrs_ovl->selected_entry) { + if (idx == mAD_PAGE_PLAYER && adrs_ovl->show_museum_address && i == count - 1) { + color_p = &address_color[4]; + } else { + color_p = &address_color[3]; + } + } else if (idx == mAD_PAGE_PLAYER) { + if (adrs_ovl->show_museum_address && i == count - 1) { + color_p = &address_color[2]; + } else { + color_p = &address_color[0]; + } + } else { + color_p = &address_color[1]; + } + + mFont_SetLineStrings( + // clang-format off + game, + name_p->personalID.player_name, PLAYER_NAME_LEN, + pos_x, pos_y, + color_p->r, color_p->g, color_p->b, 255, + FALSE, TRUE, + 0.75f, 0.75f, + mFont_MODE_POLY + // clang--format on + ); + + if (adrs_ovl->show_museum_address && i == count - 2 && idx == mAD_PAGE_PLAYER) { + pos_y += 24.0f; + } else { + pos_y += 12.0f; + } + } +} + +static void mAD_set_addressSel_tag(Submenu* submenu, GRAPH* graph, GAME* game) { + mAD_Ovl_c* adrs_ovl = submenu->overlay->address_ovl; + mBD_Ovl_c* board_ovl = submenu->overlay->board_ovl; + int page_bitfield = adrs_ovl->page_bitfield; + int idx = adrs_ovl->curIdx; + f32 pos_x; + f32 pos_y; + f32 x; + f32 y; + int i; + int col = 2; + + if (board_ovl != NULL) { + pos_x = board_ovl->ofs_x + 4.0f; + pos_y = board_ovl->ofs_y - 20.0f; + } else { + pos_x = 0.0f; + pos_y = 0.0f; + } + + for (i = 0; i < 3; i++) { + if (idx == mAD_PAGE_PLAYER) { + idx = mAD_PAGE_NPC1; + } else { + idx--; + } + + if ((page_bitfield >> idx) & 1) { + if (idx == adrs_ovl->curIdx) { + x = pos_x + adrs_ovl->pos_x; + } else if (idx == adrs_ovl->nextIdx) { + x = pos_x - adrs_ovl->pos_x; + } else if ((adrs_ovl->proc_idx == mAD_PROC_TURN_PAGE && adrs_ovl->speed_x < 0.0f) || + (adrs_ovl->proc_idx == mAD_PROC_TURN_PAGE2 && adrs_ovl->speed_x > 0.0f)) { + x = pos_x - adrs_ovl->pos_x; + } else { + x = pos_x + adrs_ovl->pos_x; + } + + x += adrs_ovl->pile[idx]; + y = pos_y - adrs_ovl->pile[idx]; + mAD_set_addressSel_tag_field(graph, x, y, idx, col); + + (*submenu->overlay->set_char_matrix_proc)(graph); + mAD_set_addressSel_tag_character(submenu, game, x, y, idx); + } + + col--; + } +} + +static void mAD_set_dl(Submenu* submenu, GAME* game, mSM_MenuInfo_c* menu_info) { + mAD_Ovl_c* adrs_ovl = submenu->overlay->address_ovl; + GRAPH* graph = game->graph; + f32 pos_x = menu_info->position[0]; + f32 pos_y = menu_info->position[1]; + + if (adrs_ovl->proc_idx == mAD_PROC_REFUSE || adrs_ovl->proc_idx == mAD_PROC_START) { + mAD_set_first_tag(submenu, game, graph, pos_x, pos_y); + } else { + mAD_set_addressSel_tag(submenu, graph, game); + } +} + +static void mAD_address_ovl_draw(Submenu* submenu, GAME* game) { + mSM_MenuInfo_c* menu_info = &submenu->overlay->menu_info[mSM_OVL_ADDRESS]; + + (*menu_info->pre_draw_func)(submenu, game); + if (menu_info->proc_status == mSM_OVL_PROC_PLAY) { + Gfx* gfx = NULL; + + if (menu_info->next_menu_type == mSM_OVL_EDITOR) { + OPEN_DISP(game->graph); + + gfx = NOW_POLY_OPA_DISP; + NEXT_POLY_OPA_DISP; + submenu->overlay->address_ovl->display_list = NOW_POLY_OPA_DISP; + + CLOSE_DISP(game->graph); + + } + + mAD_set_dl(submenu, game, menu_info); + + if (gfx != NULL) { + OPEN_DISP(game->graph); + + gSPEndDisplayList(NEXT_POLY_OPA_DISP); + gSPBranchList(gfx, NOW_POLY_OPA_DISP); + + CLOSE_DISP(game->graph); + } + } else { + submenu->overlay->address_ovl->display_list = NULL; + } +} + +extern void mAD_address_ovl_set_proc(Submenu* submenu) { + mSM_Control_c* ctrl_p = &submenu->overlay->menu_control; + + ctrl_p->menu_move_func = mAD_address_ovl_move; + ctrl_p->menu_draw_func = mAD_address_ovl_draw; +} + +static void mAD_address_ovl_init(Submenu* submenu) { + mAD_Ovl_c* adrs_ovl = submenu->overlay->address_ovl; + mSM_MenuInfo_c* menu_info = &submenu->overlay->menu_info[mSM_OVL_ADDRESS]; + int page_bitfield = 0; + int i; + u8 count = 0; + + submenu->overlay->menu_control.animation_flag = FALSE; + switch (menu_info->data0) { + case mAD_OPEN_ADDRESS: + menu_info->proc_status = mSM_OVL_PROC_PLAY; + break; + case mAD_OPEN_WAIT: + mSM_open_submenu_new2(submenu, mSM_OVL_EDITOR, mED_TYPE_BOARD, MAIL_HEADER_BASE_LEN, menu_info->data2, menu_info->data3); + menu_info->proc_status = mSM_OVL_PROC_WAIT; + break; + default: + menu_info->proc_status = mSM_OVL_PROC_WAIT; + break; + } + + mAD_make_player_address(adrs_ovl); + mAD_make_npc_address(adrs_ovl); + if (adrs_ovl->page_entry_count[mAD_PAGE_PLAYER] != 0) { + adrs_ovl->curIdx = mAD_PAGE_PLAYER; + } else if (adrs_ovl->page_entry_count[mAD_PAGE_NPC0] != 0) { + adrs_ovl->curIdx = mAD_PAGE_NPC0; + } + + for (i = mAD_PAGE_NUM - 1; i >= 0; i--) { + page_bitfield <<= 1; + if (adrs_ovl->page_entry_count[i] != 0) { + page_bitfield |= 1; + count++; + } + } + + adrs_ovl->page_bitfield = page_bitfield; + adrs_ovl->page_count = count; + + if (adrs_ovl->page_count == 0) { + adrs_ovl->proc_idx = mAD_PROC_REFUSE; + } else { + adrs_ovl->proc_idx = mAD_PROC_START; + } +} + +extern void mAD_address_ovl_construct(Submenu* submenu) { + Submenu_Overlay_c* ovl = submenu->overlay; + int flag = FALSE; + + if (ovl->address_ovl == NULL) { + mem_clear((u8*)&adrs_ovl_data, sizeof(adrs_ovl_data), 0); + ovl->address_ovl = &adrs_ovl_data; + flag = TRUE; + } + + mAD_address_ovl_init(submenu); + mAD_address_ovl_set_proc(submenu); + + if (flag) { + mAD_address_draw_init(submenu); + } +} + +extern void mAD_address_ovl_destruct(Submenu* submenu) { + submenu->overlay->address_ovl = NULL; +} diff --git a/src/game/m_editor_ovl.c b/src/game/m_editor_ovl.c index aa5b82fb..b1fdc0fa 100644 --- a/src/game/m_editor_ovl.c +++ b/src/game/m_editor_ovl.c @@ -1843,11 +1843,11 @@ static void mED_move_Play(Submenu* submenu, mSM_MenuInfo_c* menu_info) { editor_ovl->_0F = 26; editor_ovl->_0E = 0; - if (submenu->overlay->address_ovl->_07 != 0) { + if (submenu->overlay->address_ovl->editor_move_down) { board_ovl = submenu->overlay->board_ovl; if (board_ovl != NULL) { - submenu->overlay->address_ovl->_07 = FALSE; + submenu->overlay->address_ovl->editor_move_down = FALSE; editor_ovl->command = mED_COMMAND_CURSOL_LOWER; mED_move_letter_table(editor_ovl, board_ovl, submenu); editor_ovl->exchange_code = mED_get_exchange_code(editor_ovl); diff --git a/src/game/m_mail.c b/src/game/m_mail.c index 502b2e7a..daaa2361 100644 --- a/src/game/m_mail.c +++ b/src/game/m_mail.c @@ -86,9 +86,9 @@ extern int mMl_check_not_used_mail(Mail_c* mail) { return res; } -extern void mMl_copy_header_name(Mail_c* dst, Mail_c* src) { - dst->header.recipient.type = src->header.recipient.type; - mPr_CopyPersonalID(&dst->header.recipient.personalID, &src->header.recipient.personalID); +extern void mMl_copy_header_name(Mail_nm_c* dst, Mail_nm_c* src) { + dst->type = src->type; + mPr_CopyPersonalID(&dst->personalID, &src->personalID); } extern void mMl_set_to_plname(Mail_c* mail, PersonalID_c* pid) {