From 3cf38c7ce2baa52ed55deb401df6c47c838dc9b7 Mon Sep 17 00:00:00 2001 From: Cuyler36 Date: Mon, 7 Apr 2025 16:29:39 -0400 Subject: [PATCH] Implement & link m_calendar_ovl --- configure.py | 2 +- include/audio_defs.h | 3 + include/libforest/gbi_extensions.h | 12 + include/m_calendar_ovl.h | 76 +++ include/m_calendar_ovl_h.h | 2 + include/m_submenu_ovl.h | 3 +- src/game/m_calendar_ovl.c | 862 +++++++++++++++++++++++++++++ src/game/m_calendar_ovl_draw.c_inc | 478 ++++++++++++++++ 8 files changed, 1436 insertions(+), 2 deletions(-) create mode 100644 src/game/m_calendar_ovl.c create mode 100644 src/game/m_calendar_ovl_draw.c_inc diff --git a/configure.py b/configure.py index 0b6e2f26..e5f2a415 100644 --- a/configure.py +++ b/configure.py @@ -1377,7 +1377,7 @@ config.libs = [ Object(Matching, "game/m_birthday_ovl.c"), Object(Matching, "game/m_board_ovl.c"), Object(Matching, "game/m_calendar.c"), - Object(NonMatching, "game/m_calendar_ovl.c"), + Object(Matching, "game/m_calendar_ovl.c"), Object(Matching, "game/m_camera2.c"), Object(NonMatching, "game/m_card.c"), Object(Matching, "game/m_catalog_ovl.c"), diff --git a/include/audio_defs.h b/include/audio_defs.h index f050167d..132ecb0f 100644 --- a/include/audio_defs.h +++ b/include/audio_defs.h @@ -196,6 +196,9 @@ typedef enum audio_sound_effects { NA_SE_UCHIWA = 0x167, NA_SE_LAWNMOWER = 0x177, + NA_SE_17C = 0x17C, + NA_SE_17D = 0x17D, + NA_SE_207 = 0x207, NA_SE_SCOOP_SHIGEMI = 0x401, diff --git a/include/libforest/gbi_extensions.h b/include/libforest/gbi_extensions.h index 5f7ba482..248f969c 100644 --- a/include/libforest/gbi_extensions.h +++ b/include/libforest/gbi_extensions.h @@ -723,6 +723,18 @@ do { \ gsDPSetTextureImage_Dolphin(fmt, G_IM_SIZ_4b, w, h, timg), \ gsDPSetTile_Dolphin(G_DOLPHIN_TLUT_DEFAULT_MODE, 0, pal, ws, wt, ss, st) +#define gDPLoadTextureBlock_4b_Dolphin(pkt, timg, fmt, w, h, pal, ws, wt, ss, st) \ +do { \ + gDPSetTextureImage_Dolphin(pkt, fmt, G_IM_SIZ_4b, w, h, timg); \ + gDPSetTile_Dolphin(pkt, G_DOLPHIN_TLUT_DEFAULT_MODE, 0, pal, ws, wt, ss, st); \ +} while (0) + +#define gDPLoadTextureBlock_8b_Dolphin(pkt, timg, fmt, w, h, pal, ws, wt, ss, st) \ +do { \ + gDPSetTextureImage_Dolphin(pkt, fmt, G_IM_SIZ_8b, w, h, timg); \ + gDPSetTile_Dolphin(pkt, G_DOLPHIN_TLUT_DEFAULT_MODE, 0, pal, ws, wt, ss, st); \ +} while (0) + #define gDPLoadTextureTile_4b_Dolphin(pkt, timg, fmt, w, h) \ do { \ gDPSetTextureImage_Dolphin(pkt, fmt, G_IM_SIZ_4b, h, w, timg); \ diff --git a/include/m_calendar_ovl.h b/include/m_calendar_ovl.h index 66471c23..60d1e5c9 100644 --- a/include/m_calendar_ovl.h +++ b/include/m_calendar_ovl.h @@ -2,11 +2,87 @@ #define M_CALENDAR_OVL_H #include "types.h" +#include "m_calendar_ovl_h.h" +#include "m_submenu_ovl.h" +#include "m_calendar.h" +#include "m_string.h" +#include "m_font.h" #ifdef __cplusplus extern "C" { #endif +#define mCD_YEARS_SHOWN 3 +#define mCD_EVENT_NAME_STR_LEN 16 + +enum { + mCD_STICK_AREA_LEFT, + mCD_STICK_AREA_TOP_LEFT, + mCD_STICK_AREA_TOP, + mCD_STICK_AREA_TOP_RIGHT, + mCD_STICK_AREA_RIGHT, + mCD_STICK_AREA_BOTTOM_RIGHT, + mCD_STICK_AREA_BOTTOM, + mCD_STICK_AREA_BOTTOM_LEFT, + mCD_STICK_AREA_CENTER, + + mCD_STICK_AREA_NUM +}; + +enum { + mCD_MVPL_SELECT, + mCD_MVPL_MV0, + mCD_MVPL_MV1, + mCD_MVPL_CHG0, + mCD_MVPL_CHG1, + mCD_MVPL_DAY, + mCD_MVPL_ESCAPE, + mCD_MVPL_ENTRANCE, + + mCD_MVPL_NUM +}; + +#define mCD_DAY_NONE (0) // day panel not enabled, part of previous or next month +#define mCD_DAY_NORMAL (1) // regular day +#define mCD_DAY_FIRST_OF_WEEK (2) // first day of the week (Sunday) +#define mCD_DAY_EVENT (3) // event present on this day +#define mCD_DAY_CURRENT (4) // current day +#define mCD_DAY_UNDEFINED (5) // invalid/unset + +// TODO: fill out the rest of these struct fields with proper names + +typedef struct calendar_month_entry_s { + u8 day_data[37]; + u8 _25[37]; + u8 _4A[lbRTC_MONTHS_MAX][2]; + u8 _62[16]; + u8 _72; +} mCD_month_entry_c; + +struct calendar_ovl_s { + mCD_month_entry_c month_entries[mCD_YEARS_SHOWN * lbRTC_MONTHS_MAX]; + f32 _102C; + f32 _1030; + f32 _1034; + f32 _1038; + u8 _103C[6]; + u8 _1042; + u8 _1043; + u8 event_name_str[mCD_EVENT_NAME_STR_LEN]; + u8 _1054; + u8 move_proc_idx; + u8 _1056; + u8 _1057; + u8 day_type; + u8 _1059; + u8 _105A; + u8 stick_area; + u8 _105C; + u8 _105D; + u8 _105E; + u8 _105F; +}; + extern void mCD_calendar_ovl_construct(Submenu* submenu); extern void mCD_calendar_ovl_destruct(Submenu* submenu); extern void mCD_calendar_ovl_set_proc(Submenu* submenu); diff --git a/include/m_calendar_ovl_h.h b/include/m_calendar_ovl_h.h index 2fca2ef1..5bdff4ef 100644 --- a/include/m_calendar_ovl_h.h +++ b/include/m_calendar_ovl_h.h @@ -7,6 +7,8 @@ extern "C" { #endif +typedef struct calendar_ovl_s mCD_Ovl_c; + #ifdef __cplusplus } #endif diff --git a/include/m_submenu_ovl.h b/include/m_submenu_ovl.h index 4571d02b..c4c997c8 100644 --- a/include/m_submenu_ovl.h +++ b/include/m_submenu_ovl.h @@ -38,6 +38,7 @@ #include "m_cpedit_ovl_h.h" #include "m_cpwarning_ovl_h.h" #include "m_mscore_ovl_h.h" +#include "m_calendar_ovl_h.h" #ifdef __cplusplus extern "C" { @@ -203,7 +204,7 @@ struct submenu_overlay_s { /* 0x9E0 */ void* _9E0; /* 0x9E4 */ mGB_Ovl_c* gba_ovl; /* 0x9E8 */ mDI_Ovl_c* diary_ovl; - /* 0x9EC */ void* _9EC; + /* 0x9EC */ mCD_Ovl_c* calendar_ovl; /* 0x9F0 */ mPM_Ovl_c* passwordMake_ovl; /* 0x9F4 */ mPC_Ovl_c* passwordChk_ovl; /* 0x9F8 */ u8 hboard_exists; diff --git a/src/game/m_calendar_ovl.c b/src/game/m_calendar_ovl.c new file mode 100644 index 00000000..a9a984d1 --- /dev/null +++ b/src/game/m_calendar_ovl.c @@ -0,0 +1,862 @@ +#include "m_calendar_ovl.h" + +#include "m_common_data.h" +#include "lb_reki.h" +#include "m_soncho.h" +#include "m_warning_ovl.h" +#include "sys_matrix.h" +#include "m_malloc.h" + +static u32 mCD_visiter_chk(int player_no, int month, int day) { + u32 ret = FALSE; + + if (player_no == -1) { + player_no = Common_Get(player_no); + } + + if (Common_Get(player_no) != mPr_FOREIGNER) { + mCD_player_calendar_c* calendar_p = &Save_Get(private_data[player_no]).calendar; + int mask = 1 << (day - 1); + + ret = mask & calendar_p->played_days[month - 1]; + } + + return ret; +} + +static u32 mCD_sp_soncho_chk(lbRTC_year_t year, lbRTC_month_t month, lbRTC_day_t day, mCD_player_calendar_c* calendar) { + lbRTC_ymd_c harvest_moon_day; + lbRTC_weekday_t wday; + u16 chk = (0 << 0); + u32 ret = FALSE; + + switch (month) { + case lbRTC_JUNE: + wday = lbRTC_Week(year, month, day + 1); + if (wday == lbRTC_SUNDAY && 1 + ((day - wday) / lbRTC_WEEK) == 3) { + chk = (1 << 0); + } + break; + case lbRTC_JULY: + if (day == Save_Get(town_day)) { + chk = (1 << 1); + } + break; + case lbRTC_AUGUST: + if (day == 12) { + chk = (1 << 2); + } + + if (day == 21) { + chk = (1 << 3); + } + break; + case lbRTC_NOVEMBER: + if (day == 11) { + chk = (1 << 6); + } + break; + default: + lbRk_HarvestMoonDay(&harvest_moon_day, year); + if (month == harvest_moon_day.month && day == harvest_moon_day.day) { + chk = (1 << 5) | (1 << 4); + } + break; + } + + if (calendar->event_flags & chk) { + ret = TRUE; + } + + return ret; +} + +static u32 mCD_soncho_chk(lbRTC_year_t year, lbRTC_month_t month, lbRTC_day_t day, int player_no) { + u32 ret = FALSE; + + if (player_no == -1) { + player_no = Common_Get(player_no); + } + + if (Common_Get(player_no) != mPr_FOREIGNER) { + mCD_player_calendar_c* calendar = &Save_Get(private_data[player_no]).calendar; + + ret = mCD_sp_soncho_chk(year, month, day, calendar); + if (!ret) { + ret = calendar->event_days[month - 1] & (1 << (day - 1)); + } + } + + return ret; +} + +static int mCD_make_icon(lbRTC_year_t year, lbRTC_month_t month, lbRTC_day_t day, int player_no) { + lbRTC_time_c* rtc_time = Common_GetPointer(time.rtc_time); + int delta_months = (rtc_time->year - year) * lbRTC_MONTHS_MAX + (rtc_time->month - month); + int ret = 0; + + if (delta_months >= 0 && delta_months < lbRTC_MONTHS_MAX) { + if (mCD_soncho_chk(year, month, day, player_no)) { + ret = 2; + } else if (mCD_visiter_chk(player_no, month, day)) { + ret = 1; + } + } + + return ret; +} + +static void mDC_set_string(mCD_Ovl_c* calendar) { + if (calendar->_1043) { + int event_idx = calendar->_103C[calendar->_1042] & 0x7F; + int len = 0; + u8 string[mCD_EVENT_NAME_STR_LEN]; + + mem_clear(string, sizeof(string), CHAR_SPACE); + if (event_idx == 4) { + mLd_CopyLandName(string, Save_Get(land_info).name); + len = mMl_strlen(string, LAND_NAME_SIZE, CHAR_SPACE); + } + + mSC_get_event_name_str(string + len, sizeof(string) - len, event_idx); + mem_copy(calendar->event_name_str, string, mCD_EVENT_NAME_STR_LEN); + calendar->_1034 = 98.0f; + calendar->_1038 = 0.0f; + calendar->_1054 = 0; + } +} + +static void mDC_set_disp_table(mCD_Ovl_c* calendar) { + int entry = calendar->_1056; + mCD_month_entry_c* entry_p = &calendar->month_entries[entry]; + int i; + + calendar->_1042 = 0; + calendar->_1043 = 0; + + for (i = 0; i < 6; i++) { + calendar->_103C[i] = 0; + } + + for (i = 0; i < entry_p->_72; i++) { + if (entry_p->_4A[i][0] == calendar->_1057) { + if (calendar->_1043 >= 6) { + return; + } + + calendar->_103C[calendar->_1043] = entry_p->_4A[i][1]; + calendar->_1043++; + } + } + + mDC_set_string(calendar); + calendar->day_type = (entry_p->day_data[calendar->_1057] >> 5) & 7; // probably a struct bitfield +} + +static int mDC_weekly_to_day_data(mCD_month_entry_c* entry, int week, u32 days_after) { + u8* data_p = &entry->day_data[days_after]; + int ret = 0; + int i; + + for (i = days_after; i < 37; i += lbRTC_WEEK) { + if ((*data_p & 0x1F) > 0) { + week--; + } + + if (week <= 0) { + ret = *data_p & 0x1F; + break; + } + + data_p += lbRTC_WEEK; + } + + return ret; +} + +static lbRTC_day_t mDC_day_to_day_data(mCD_month_entry_c* entry, lbRTC_day_t day) { + u8* day_p = entry->day_data; + lbRTC_day_t i; + + for (i = 0; (*day_p & 0x1F) != day && i < 37; i++) { + day_p++; + } + + return i; +} + +static void mDC_set_disp_event_day(mCD_month_entry_c* entry, lbRTC_day_t day, u8 event) { + entry->_4A[entry->_72][0] = day; + entry->_4A[entry->_72][1] = event; + entry->_72++; +} + +static u8 mDC_get_calendar_day_position(mCD_Ovl_c* calendar, lbRTC_day_t day) { + mCD_month_entry_c* entry = &calendar->month_entries[calendar->_1056]; + lbRTC_day_t i = 0; + + while (TRUE) { + if (i > 37 || day == (entry->day_data[i] & 0x1F)) { + break; + } + + i++; + } + + return i; +} + +static void mCD_make_calendar_event_sanka_check(lbRTC_year_t year, lbRTC_month_t month, mCD_month_entry_c* entry, int player_no) { + lbRTC_day_t day; + int event; + int i; + + for (i = 0; i < entry->_72; i++) { + day = entry->day_data[entry->_4A[i][0]] & 0x1F; + event = entry->_4A[i][1] & 0x7F; + + if (event == 0x1C) { + if (mCD_visiter_chk(player_no, month, day)) { + entry->_4A[i][1] |= 0x80; + } + } else if (mCD_calendar_event_check(year, month, day, player_no, event) == TRUE) { + entry->_4A[i][1] |= 0x80; + } + } +} + +static void mDC_set_event_day_data(mCD_month_entry_c* entry, lbRTC_month_t month, lbRTC_day_t day, u8 event, u8 day_type, u8 p6) { + mCD_month_entry_c* month_entry = &entry[month - 1]; + int chg_day = mDC_day_to_day_data(month_entry, day); + u8* data_p = &month_entry->day_data[chg_day]; + + if (p6 == TRUE && ((*data_p >> 5) & 7) == 2) { + data_p[1] = (data_p[1] & 0x1F) | (2 << 5); + } + + if (day_type != mCD_DAY_UNDEFINED) { + data_p[0] = (data_p[0] & 0x1F) | (day_type << 5); + } + + if (event != 0xFF) { + mDC_set_disp_event_day(month_entry, chg_day, event); + } +} + +static void mCD_make_calendar_data_init(mCD_month_entry_c* entry) { + int i; + + for (i = 0; i < 37; i++) { + entry->day_data[i] = 0; + entry->_25[i] = 0; + } +} + +static void mCD_make_calendar_data_holiday_and_icon(mCD_month_entry_c* entry, lbRTC_year_t year, lbRTC_month_t month, int player_no) { + int first_weekday = lbRTC_Week(year, month, 1); + int days = lbRTC_GetDaysByMonth(year, month); + int end_day = first_weekday + days; + int i; + int day = 1; + + for (i = first_weekday; i < end_day; i++) { + u8* data_p = &entry->day_data[i]; + + *data_p = day; + entry->_25[i] = mCD_make_icon(year, month, day, player_no); + if ((i % lbRTC_WEEK) == lbRTC_SUNDAY) { + *data_p = (*data_p & 0x1F) | (mCD_DAY_FIRST_OF_WEEK << 5); + } else { + *data_p = (*data_p & 0x1F) | (1 << 5); + } + + day++; + } +} + +static void mCD_make_calendar_data_month(mCD_month_entry_c* entry, lbRTC_year_t year, int player_no) { + lbRTC_month_t month; + + for (month = 0; month < lbRTC_MONTHS_MAX; month++) { + mCD_make_calendar_data_init(entry); + mCD_make_calendar_data_holiday_and_icon(entry, year, month + 1, player_no); + entry++; + } +} + +typedef struct { + lbRTC_month_t month; + lbRTC_day_t day; + u8 event; +} mCD_fixed_event_c; + +static void mCD_make_calendar_data_fixed_day_event(mCD_month_entry_c* entry) { + static mCD_fixed_event_c event_table[] = { + // clang-format off + { lbRTC_JANUARY, 1, mSC_EVENT_NEW_YEARS_DAY}, + {lbRTC_FEBRUARY, 2, mSC_EVENT_GROUNDHOG_DAY}, + { lbRTC_APRIL, 1, mSC_EVENT_APRILFOOLS_DAY}, + { lbRTC_APRIL, 5, mSC_EVENT_CHERRY_BLOSSOM_FESTIVAL}, + { lbRTC_APRIL, 6, mSC_EVENT_CHERRY_BLOSSOM_FESTIVAL}, + { lbRTC_APRIL, 7, mSC_EVENT_CHERRY_BLOSSOM_FESTIVAL}, + { lbRTC_APRIL, 22, mSC_EVENT_NATURE_DAY}, + { lbRTC_MAY, 1, mSC_EVENT_SPRING_CLEANING}, + { lbRTC_JULY, 4, mSC_EVENT_FIREWORKS_SHOW}, + { lbRTC_AUGUST, 12, mSC_EVENT_METEOR_SHOWER}, + { lbRTC_AUGUST, 21, mSC_EVENT_FOUNDERS_DAY}, + { lbRTC_OCTOBER, 31, mSC_EVENT_HALLOWEEN}, + {lbRTC_NOVEMBER, 11, mSC_EVENT_OFFICERS_DAY}, + {lbRTC_DECEMBER, 1, mSC_EVENT_SNOW_DAY}, + {lbRTC_DECEMBER, 23, mSC_EVENT_TOY_DAY}, + {lbRTC_DECEMBER, 31, mSC_EVENT_NEW_YEARS_EVE_COUNTDOWN}, + // clang-format on + }; + + int i; + + for (i = 0; i < ARRAY_COUNT(event_table); i++) { + mDC_set_event_day_data(entry, event_table[i].month, event_table[i].day, event_table[i].event, mCD_DAY_EVENT, 0); + } +} + +typedef struct { + u8 month; + u8 week; + u8 weekday; + u8 days_after; + u8 event; +} mCD_fixed_data_c; + +static void mCD_make_calendar_data_unfixed_day_event(mCD_month_entry_c* entry, lbRTC_year_t year) { + static mCD_fixed_data_c event_table[] = { + { lbRTC_MAY, 2, lbRTC_SUNDAY, 0, mSC_EVENT_MOTHERS_DAY}, + { lbRTC_JUNE, 2, lbRTC_FRIDAY, 0, mSC_EVENT_GRADUATION_DAY}, + { lbRTC_JUNE, 3, lbRTC_SUNDAY, 0, mSC_EVENT_FATHERS_DAY}, + {lbRTC_SEPTEMBER, 1, lbRTC_MONDAY, 0, mSC_EVENT_LABOR_DAY}, + { lbRTC_OCTOBER, 2, lbRTC_MONDAY, 0, mSC_EVENT_EXPLORERS_DAY}, + { lbRTC_NOVEMBER, 1, lbRTC_MONDAY, 1, mSC_EVENT_MAYORS_DAY}, + { lbRTC_NOVEMBER, 4, lbRTC_THURSDAY, 0, mSC_EVENT_HARVEST_FESTIVAL}, + { lbRTC_NOVEMBER, 4, lbRTC_THURSDAY, 1, mSC_EVENT_SALE_DAY}, + }; + + lbRTC_ymd_c harvest_moon_day; + int day; + mCD_month_entry_c* month_entry; + int i; + int j; + int k; + + for (i = 0; i < ARRAY_COUNT(event_table); i++) { + lbRTC_day_t day = mDC_weekly_to_day_data(&entry[event_table[i].month - 1], event_table[i].week, event_table[i].weekday); + + day += event_table[i].days_after; + mDC_set_event_day_data(entry, event_table[i].month, day, event_table[i].event, mCD_DAY_EVENT, 0); + } + + month_entry = &entry[lbRTC_JUNE - 1]; + for (j = 0; j < 37; j += lbRTC_WEEK) { + int day = month_entry->day_data[j] & 0x1F; + + if (day > 0) { + mDC_set_event_day_data(entry, lbRTC_JUNE, day, mSC_EVENT_FISHING_TOURNEY_1, mCD_DAY_EVENT, 0); + } + } + + month_entry = &entry[lbRTC_NOVEMBER - 1]; + for (k = 0; k < 37; k += lbRTC_WEEK) { + int day = month_entry->day_data[k] & 0x1F; + + if (day > 0) { + mDC_set_event_day_data(entry, lbRTC_NOVEMBER, day, mSC_EVENT_FISHING_TOURNEY_2, mCD_DAY_EVENT, 0); + } + } + + day = lbRk_VernalEquinoxDay(year); + mDC_set_event_day_data(entry, lbRTC_MARCH, day, mSC_EVENT_SPRING_SPORTS_FAIR, mCD_DAY_EVENT, 0); + + day = lbRk_AutumnalEquinoxDay(year); + mDC_set_event_day_data(entry, lbRTC_SEPTEMBER, day, mSC_EVENT_FALL_SPORTS_FAIR, mCD_DAY_EVENT, 0); + + mDC_set_event_day_data(entry, lbRTC_JULY, (lbRTC_day_t)Save_Get(town_day), mSC_EVENT_TOWN_DAY, mCD_DAY_EVENT, 0); + + lbRk_HarvestMoonDay(&harvest_moon_day, year); + mDC_set_event_day_data(entry, harvest_moon_day.month, harvest_moon_day.day, mSC_EVENT_HARVEST_MOON_FESTIVAL, mCD_DAY_EVENT, 0); +} + +static void mCD_make_calendar_data_year(lbRTC_year_t year, mCD_month_entry_c* entry, int player_no) { + mPr_birthday_c* birthday; + int i; + + mCD_make_calendar_data_month(entry, year, player_no); + mCD_make_calendar_data_fixed_day_event(entry); + mCD_make_calendar_data_unfixed_day_event(entry, year); + + birthday = &Save_Get(private_data[player_no]).birthday; + if (birthday->month != 0xFF) { + mDC_set_event_day_data(entry, birthday->month, birthday->day, mSC_EVENT_PLAYER_BIRTHDAY, 5, 0); + } + + for (i = lbRTC_JANUARY; i <= lbRTC_DECEMBER; i++) { + mCD_make_calendar_event_sanka_check(year, i, &entry[i - 1], player_no); + } +} + +static void mCD_make_calendar_data(mCD_Ovl_c* calendar, int player_no) { + int i; + lbRTC_time_c* rtc_time = Common_GetPointer(time.rtc_time); + mCD_month_entry_c* entry; + int day_pos; + + for (i = 0; i < mCD_YEARS_SHOWN; i++) { + mCD_make_calendar_data_year(rtc_time->year + i - 1, &calendar->month_entries[i * lbRTC_MONTHS_MAX], player_no); + } + + calendar->_1056 = rtc_time->month + lbRTC_MONTHS_MAX - 1; + calendar->_1059 = calendar->_1056; + day_pos = mDC_get_calendar_day_position(calendar, rtc_time->day); + entry = calendar->month_entries + calendar->_1056; + entry->day_data[day_pos] = (entry->day_data[day_pos] & 0x1F) | (mCD_DAY_CURRENT << 5); +} + +static void mCD_stick_area_check(Submenu* submenu) { + mCD_Ovl_c* calendar = submenu->overlay->calendar_ovl; + + if (gamePT->mcon.adjusted_pR < 0.2f) { + calendar->stick_area = mCD_STICK_AREA_CENTER; + } else { + s16 angle = gamePT->mcon.move_angle; + + if (angle < DEG2SHORT_ANGLE2(-157.5f)) { + calendar->stick_area = mCD_STICK_AREA_LEFT; + } else if (angle < DEG2SHORT_ANGLE2(-112.5f)) { + calendar->stick_area = mCD_STICK_AREA_CENTER; + } else if (angle < DEG2SHORT_ANGLE2(-67.5f)) { + calendar->stick_area = mCD_STICK_AREA_BOTTOM; + } else if (angle < DEG2SHORT_ANGLE2(-22.5f)) { + calendar->stick_area = mCD_STICK_AREA_CENTER; + } else if (angle < DEG2SHORT_ANGLE2(22.5f)) { + calendar->stick_area = mCD_STICK_AREA_RIGHT; + } else if (angle < DEG2SHORT_ANGLE2(67.5f)) { + calendar->stick_area = mCD_STICK_AREA_CENTER; + } else if (angle < DEG2SHORT_ANGLE2(112.5f)) { + calendar->stick_area = mCD_STICK_AREA_TOP; + } else if (angle < DEG2SHORT_ANGLE2(157.5f)) { + calendar->stick_area = mCD_STICK_AREA_CENTER; + } else { + calendar->stick_area = mCD_STICK_AREA_LEFT; + } + } + + switch (calendar->stick_area) { + case mCD_STICK_AREA_TOP_LEFT: + case mCD_STICK_AREA_LEFT: + case mCD_STICK_AREA_BOTTOM_LEFT: + submenu->overlay->calendar_ovl->_105C = mCD_STICK_AREA_LEFT; + break; + case mCD_STICK_AREA_TOP_RIGHT: + case mCD_STICK_AREA_RIGHT: + case mCD_STICK_AREA_BOTTOM_RIGHT: + submenu->overlay->calendar_ovl->_105C = mCD_STICK_AREA_RIGHT; + break; + default: + submenu->overlay->calendar_ovl->_105C = mCD_STICK_AREA_CENTER; + break; + } +} + +static void mCD_move_Move(Submenu* submenu, mSM_MenuInfo_c* menu_info) { + (*submenu->overlay->move_Move_proc)(submenu, menu_info); +} + +static void mCD_MVPL_select(Submenu* submenu, mSM_MenuInfo_c* menu_info) { + mCD_Ovl_c* calendar = submenu->overlay->calendar_ovl; + u32 trigger = submenu->overlay->menu_control.trigger; + + if ((trigger & BUTTON_B) || (trigger & BUTTON_START)) { + (*submenu->overlay->move_chg_base_proc)(menu_info, mSM_MOVE_OUT_TOP); + sAdo_SysTrgStart(NA_SE_17D); + } else { + if (calendar->_105C == mCD_STICK_AREA_LEFT) { + if (calendar->_1056 > calendar->_1059 - 11) { + calendar->_105A = 1; + menu_info->position[0] = -320.0f; + calendar->move_proc_idx = mCD_MVPL_MV1; + calendar->_1056--; + sAdo_SysTrgStart(NA_SE_5F); + } + } else if (calendar->_105C == mCD_STICK_AREA_RIGHT) { + if (calendar->_1056 < calendar->_1059 + 11) { + calendar->_105A = 1; + menu_info->position[0] = 320.0f; + calendar->move_proc_idx = mCD_MVPL_MV0; + calendar->_1056++; + sAdo_SysTrgStart(NA_SE_5F); + } + } else if ((trigger & BUTTON_CUP) && calendar->_105C == mCD_STICK_AREA_CENTER) { + if (calendar->_1059 > calendar->_1056) { + calendar->_105A = calendar->_1059 - calendar->_1056; + menu_info->position[0] = 320.0f; + calendar->move_proc_idx = mCD_MVPL_MV0; + calendar->_1056++; + sAdo_SysTrgStart(NA_SE_5F); + } else if (calendar->_1059 < calendar->_1056) { + calendar->_105A = calendar->_1056 - calendar->_1059; + menu_info->position[0] = -320.0f; + calendar->move_proc_idx = mCD_MVPL_MV1; + calendar->_1056--; + sAdo_SysTrgStart(NA_SE_5F); + } + } else if ((trigger & BUTTON_A)) { + calendar->move_proc_idx = mCD_MVPL_CHG0; + sAdo_SysTrgStart(NA_SE_5F); + calendar->_102C = 0.0f; + calendar->_1030 = -100.0f; + } + } +} + +static void mCD_MVPL_mv(Submenu* submenu, mSM_MenuInfo_c* menu_info) { + mCD_Ovl_c* calendar = submenu->overlay->calendar_ovl; + int flag; + + if (calendar->_105A == 1) { + f32 val = add_calc(&menu_info->position[0], 0.0f, 0.4f, 37.0f, 1.25f); + + if (fabsf(val) < 0.1f) { + flag = TRUE; + } else { + flag = FALSE; + } + } else if (menu_info->position[0] > 0.0f) { + menu_info->position[0] -= 37.0f; + if (menu_info->position[0] <= 0.0f) { + flag = TRUE; + } else { + flag = FALSE; + } + } else { + menu_info->position[0] += 37.0f; + if (menu_info->position[0] >= 0.0f) { + flag = TRUE; + } else { + flag = FALSE; + } + } + + if (flag) { + calendar->_105A--; + if (calendar->_105A == 0) { + menu_info->position[0] = 0.0f; + calendar->move_proc_idx = mCD_MVPL_SELECT; + } else { + sAdo_SysTrgStart(NA_SE_5F); + if (calendar->move_proc_idx == mCD_MVPL_MV1) { + menu_info->position[0] -= 320.0f; + calendar->_1056--; + } else { + menu_info->position[0] += 320.0f; + calendar->_1056++; + } + } + } +} + +static void mCD_MVPL_chg(Submenu* submenu, mSM_MenuInfo_c* menu_info) { + f32* target1; + f32* target0; + mCD_Ovl_c* calendar = submenu->overlay->calendar_ovl; + int done1; + int done0; + f32 adj0; + f32 adj1; + + if (calendar->move_proc_idx == mCD_MVPL_CHG0) { + target0 = &calendar->_102C; + target1 = &calendar->_1030; + } else { + target0 = &calendar->_1030; + target1 = &calendar->_102C; + } + + adj1 = fabsf(add_calc(target1, 0.0f, 0.4f, 37.0f, 1.25f)); + if (adj1 < 0.1f) { + *target1 = 0.0f; + done1 = TRUE; + } else { + done1 = FALSE; + } + + adj0 = fabsf(add_calc(target0, -100.0f, 0.4f, 37.0f, 1.25f)); + if (adj0 < 0.1f) { + *target0 = -100.0f; + done0 = TRUE; + } else { + done0 = FALSE; + } + + if (done1 && done0) { + if (calendar->move_proc_idx == mCD_MVPL_CHG0) { + calendar->move_proc_idx = mCD_MVPL_DAY; + + if (calendar->_1056 == calendar->_1059) { + calendar->_1057 = mDC_get_calendar_day_position(calendar, Common_Get(time.rtc_time.day)); + } else { + calendar->_1057 = mDC_get_calendar_day_position(calendar, 1); + } + + mDC_set_disp_table(calendar); + } else { + calendar->move_proc_idx = mCD_MVPL_SELECT; + } + } +} + +static void mCD_MVPL_day(Submenu* submenu, mSM_MenuInfo_c* menu_info) { + mCD_Ovl_c* calendar = submenu->overlay->calendar_ovl; + u32 trigger = submenu->overlay->menu_control.trigger; + mCD_month_entry_c* entry = &calendar->month_entries[calendar->_1056]; + int days = entry->day_data[calendar->_1057] & 0x1F; + + if ((trigger & BUTTON_B)) { + calendar->move_proc_idx = mCD_MVPL_CHG1; + sAdo_SysTrgStart(MONO(NA_SE_3)); + calendar->_1030 = 0.0f; + calendar->_102C = -100.0f; + } else if ((trigger & BUTTON_A)) { + int arg0 = -1; + + if (menu_info->data1 == Common_Get(player_no)) { + arg0 = 0; + calendar->move_proc_idx = mCD_MVPL_ESCAPE; + } else if (Save_Get(private_data[menu_info->data1]).calendar.edit) { + mWR_SHOW_WARNING(submenu, mWR_WARNING_LOCK_DIARY); + menu_info->proc_status = mSM_OVL_PROC_WAIT; + } else { + arg0 = 1; + calendar->move_proc_idx = mCD_MVPL_ESCAPE; + } + + if (arg0 != -1) { + mSM_open_submenu_new2(submenu, mSM_OVL_DIARY, arg0, menu_info->data1, NULL, calendar->_1056 % lbRTC_MONTHS_MAX); + } + } else if ((trigger & BUTTON_CLEFT) && days > 1) { + calendar->_1057--; + mDC_set_disp_table(calendar); + sAdo_SysTrgStart(NA_SE_CURSOL); + } else if ((trigger & BUTTON_CRIGHT)) { + if (calendar->_1057 < 36 && (entry->day_data[calendar->_1057 + 1] & 0x1F) > 0) { + calendar->_1057++; + mDC_set_disp_table(calendar); + sAdo_SysTrgStart(NA_SE_CURSOL); + } + } else if ((trigger & BUTTON_CUP)) { + if (calendar->_1043 > 1 && calendar->_1042 != 0) { + calendar->_1042--; + mDC_set_string(calendar); + sAdo_SysTrgStart(NA_SE_CURSOL); + } else if (days > lbRTC_WEEK) { + calendar->_1057 -= lbRTC_WEEK; + mDC_set_disp_table(calendar); + sAdo_SysTrgStart(NA_SE_CURSOL); + } + } else if ((trigger & BUTTON_CDOWN)) { + if (calendar->_1043 > 1 && calendar->_1042 + 1 < calendar->_1043) { + calendar->_1042++; + mDC_set_string(calendar); + sAdo_SysTrgStart(NA_SE_CURSOL); + } else if (calendar->_1057 < 30 && (entry->day_data[calendar->_1057 + lbRTC_WEEK] & 0x1F) > 0) { + calendar->_1057 += lbRTC_WEEK; + mDC_set_disp_table(calendar); + sAdo_SysTrgStart(NA_SE_CURSOL); + } + } + + calendar->_1038 += 1.0f; + if (calendar->_1038 >= 60.0f) { + calendar->_1038 = 0.0f; + } + + { + f32 t0 = (calendar->_1038 - 30.0f) / 30.0f; + f32 t1; + f32 t2; + + if (t0 <= 0.0f) { + t1 = 1.0f + t0; + } else { + t1 = 1.0f - t0; + } + + if (t1 < 0.0f) { + t1 = 0.0f; + } else if (t1 > 1.0f) { + t1 = 1.0f; + } + + calendar->_1054 = (u8)(int)(255 * t1); + } +} + +static void mCD_MVPL_escape(Submenu* submenu, mSM_MenuInfo_c* menu_info) { + mCD_Ovl_c* calendar = submenu->overlay->calendar_ovl; + + if (fabsf(add_calc(&menu_info->position[1], 300.0f, 0.4f, 37.0f, 1.25f)) < 0.1f) { + menu_info->position[1] = 300.0f; + menu_info->proc_status = mSM_OVL_PROC_OBEY; + calendar->move_proc_idx = mCD_MVPL_DAY; + } +} + +static void mCD_MVPL_entrance(Submenu* submenu, mSM_MenuInfo_c* menu_info) { + mCD_Ovl_c* calendar = submenu->overlay->calendar_ovl; + + if (fabsf(add_calc(&menu_info->position[1], 0.0f, 0.4f, 37.0f, 1.25f)) < 0.1f) { + menu_info->position[1] = 0.0f; + calendar->move_proc_idx = mCD_MVPL_DAY; + } +} + +typedef void (*mCD_MVPL_PROC)(Submenu* submenu, mSM_MenuInfo_c* menu_info); + +static void mCD_move_Play(Submenu* submenu, mSM_MenuInfo_c* menu_info) { + static mCD_MVPL_PROC mCD_play_proc[] = { + // clang-format off + mCD_MVPL_select, + mCD_MVPL_mv, + mCD_MVPL_mv, + mCD_MVPL_chg, + mCD_MVPL_chg, + mCD_MVPL_day, + mCD_MVPL_escape, + mCD_MVPL_entrance, + // clang-format on + }; + + mCD_Ovl_c* calendar = submenu->overlay->calendar_ovl; + + (*mCD_play_proc[calendar->move_proc_idx])(submenu, menu_info); +} + +static void mCD_move_Obey(Submenu* submenu, mSM_MenuInfo_c* menu_info) { + mCD_Ovl_c* calendar = submenu->overlay->calendar_ovl; + mSM_MenuInfo_c* obey_info = &submenu->overlay->menu_info[menu_info->next_menu_type]; + + if (obey_info->proc_status == mSM_OVL_PROC_MOVE && obey_info->next_proc_status == mSM_OVL_PROC_END) { + menu_info->proc_status = mSM_OVL_PROC_PLAY; + menu_info->position[1] = 300.0f; + calendar->move_proc_idx = mCD_MVPL_ENTRANCE; + } +} + +static void mCD_move_Wait(Submenu* submenu, mSM_MenuInfo_c* menu_info) { + mSM_MenuInfo_c* obey_info = &submenu->overlay->menu_info[menu_info->next_menu_type]; + + if (obey_info->proc_status == mSM_OVL_PROC_MOVE && obey_info->next_proc_status == mSM_OVL_PROC_END) { + menu_info->proc_status = mSM_OVL_PROC_PLAY; + } +} + +static void mCD_move_End(Submenu* submenu, mSM_MenuInfo_c* menu_info) { + (*submenu->overlay->move_End_proc)(submenu, menu_info); +} + +static void mCD_calendar_ovl_move(Submenu* submenu) { + static mSM_MOVE_PROC ovl_move_proc[] = { + // clang-format off + mCD_move_Move, + mCD_move_Play, + mCD_move_Wait, + mCD_move_Obey, + mCD_move_End, + // clang-format on + }; + + mSM_MenuInfo_c* menu_info = &submenu->overlay->menu_info[mSM_OVL_CALENDAR]; + + mCD_stick_area_check(submenu); + (*menu_info->pre_move_func)(submenu); + (*ovl_move_proc[menu_info->proc_status])(submenu, menu_info); +} + +#include "../src/game/m_calendar_ovl_draw.c_inc" + +static void mCD_calendar_ovl_draw(Submenu* submenu, GAME* game) { + mSM_MenuInfo_c* menu_info = &submenu->overlay->menu_info[mSM_OVL_CALENDAR]; + mCD_Ovl_c* calendar = submenu->overlay->calendar_ovl; + + (*menu_info->pre_draw_func)(submenu, game); + + if (menu_info->proc_status != mSM_OVL_PROC_OBEY) { + if (calendar->move_proc_idx == mCD_MVPL_MV0) { + mCD_set_base_dl(submenu, game, menu_info->position[0] - 320.0f, menu_info->position[1], calendar->_1056 - 1); + } + + if (calendar->move_proc_idx == mCD_MVPL_MV1) { + mCD_set_base_dl(submenu, game, menu_info->position[0] + 320.0f, menu_info->position[1], calendar->_1056 + 1); + } + + mCD_set_base_dl(submenu, game, menu_info->position[0], menu_info->position[1], calendar->_1056); + + if (calendar->move_proc_idx <= mCD_MVPL_CHG1) { + mCD_set_hyoji_dl(submenu, game, 0.0f, calendar->_102C - menu_info->position[1]); + } + + if (calendar->move_proc_idx >= mCD_MVPL_CHG0) { + mCD_set_hyoji2_dl(submenu, game, 0.0f, calendar->_1030 - menu_info->position[1]); + } + + if (calendar->move_proc_idx == mCD_MVPL_DAY) { + mCD_disp_event_dl(submenu, game); + } + } +} + +extern void mCD_calendar_ovl_set_proc(Submenu* submenu) { + mSM_Control_c* ctrl = &submenu->overlay->menu_control; + + ctrl->menu_move_func = mCD_calendar_ovl_move; + ctrl->menu_draw_func = mCD_calendar_ovl_draw; +} + +static void mCD_calendar_ovl_init(Submenu* submenu) { + mSM_MenuInfo_c* menu_info = &submenu->overlay->menu_info[mSM_OVL_CALENDAR]; + mCD_Ovl_c* calendar = submenu->overlay->calendar_ovl; + lbRTC_time_c* rtc_time; + int player_no; + + sAdo_SysTrgStart(NA_SE_17C); + submenu->overlay->menu_control.animation_flag = FALSE; + menu_info->proc_status = mSM_OVL_PROC_MOVE; + menu_info->next_proc_status = mSM_OVL_PROC_PLAY; + menu_info->move_drt = mSM_MOVE_IN_TOP; + + player_no = submenu->param1; + mem_clear((u8*)calendar, sizeof(mCD_Ovl_c), 0); + rtc_time = Common_GetPointer(time.rtc_time); + mCD_calendar_check_delete(player_no, rtc_time->year, rtc_time->month, rtc_time->day); + mCD_calendar_wellcome_on(); + mCD_make_calendar_data(calendar, player_no); + calendar->move_proc_idx = mCD_MVPL_SELECT; + calendar->_102C = 0.0f; + calendar->_1030 = -100.0f; +} + +extern void mCD_calendar_ovl_construct(Submenu* submenu) { + Submenu_Overlay_c* ovl = submenu->overlay; + + if (ovl->calendar_ovl == NULL) { + ovl->calendar_ovl = (mCD_Ovl_c*)zelda_malloc(sizeof(mCD_Ovl_c)); + mem_clear((u8*)ovl->calendar_ovl, sizeof(mCD_Ovl_c), 0); + } + + mCD_calendar_ovl_init(submenu); + mCD_calendar_ovl_set_proc(submenu); +} + +extern void mCD_calendar_ovl_destruct(Submenu* submenu) { + if (submenu->overlay->calendar_ovl != NULL) { + zelda_free(submenu->overlay->calendar_ovl); + } + + submenu->overlay->calendar_ovl = NULL; +} diff --git a/src/game/m_calendar_ovl_draw.c_inc b/src/game/m_calendar_ovl_draw.c_inc new file mode 100644 index 00000000..474439cf --- /dev/null +++ b/src/game/m_calendar_ovl_draw.c_inc @@ -0,0 +1,478 @@ +extern u16 cal_win_tuki10_pal[]; +extern u16 cal_win_tuki11_pal[]; +extern u16 cal_win_tuki12_pal[]; +extern u16 cal_win_tuki1_pal[]; +extern u16 cal_win_tuki2_pal[]; +extern u16 cal_win_tuki3_pal[]; +extern u16 cal_win_tuki4_pal[]; +extern u16 cal_win_tuki5_pal[]; +extern u16 cal_win_tuki6_pal[]; +extern u16 cal_win_tuki7_pal[]; +extern u16 cal_win_tuki8_pal[]; +extern u16 cal_win_tuki9_pal[]; + +static u16* back_pal_table[lbRTC_MONTHS_MAX] = { + cal_win_tuki1_pal, cal_win_tuki2_pal, cal_win_tuki3_pal, cal_win_tuki4_pal, cal_win_tuki5_pal, cal_win_tuki6_pal, cal_win_tuki7_pal, cal_win_tuki8_pal, + cal_win_tuki9_pal, cal_win_tuki10_pal, cal_win_tuki11_pal, cal_win_tuki12_pal, +}; + +extern u8 cal_win_tuki1_tex[]; +extern u8 cal_win_tuki2_tex[]; + +static u8* back_tex_table[lbRTC_MONTHS_MAX] = { + cal_win_tuki1_tex, cal_win_tuki2_tex, cal_win_tuki2_tex, cal_win_tuki2_tex, cal_win_tuki2_tex, cal_win_tuki2_tex, cal_win_tuki2_tex, cal_win_tuki2_tex, + cal_win_tuki2_tex, cal_win_tuki2_tex, cal_win_tuki2_tex, cal_win_tuki2_tex, +}; + +extern u8 cal_win_april_tex_rgb_ia8[]; +extern u8 cal_win_august_tex_rgb_ia8[]; +extern u8 cal_win_december_tex_rgb_ia8[]; +extern u8 cal_win_february_tex_rgb_ia8[]; +extern u8 cal_win_january_tex_rgb_ia8[]; +extern u8 cal_win_july_tex_rgb_ia8[]; +extern u8 cal_win_june_tex_rgb_ia8[]; +extern u8 cal_win_march_tex_rgb_ia8[]; +extern u8 cal_win_may_tex_rgb_ia8[]; +extern u8 cal_win_november_tex_rgb_ia8[]; +extern u8 cal_win_october_tex_rgb_ia8[]; +extern u8 cal_win_september_tex_rgb_ia8[]; + +static u8* month_tex_table[lbRTC_MONTHS_MAX] = { + cal_win_january_tex_rgb_ia8, cal_win_february_tex_rgb_ia8, cal_win_march_tex_rgb_ia8, cal_win_april_tex_rgb_ia8, cal_win_may_tex_rgb_ia8, cal_win_june_tex_rgb_ia8, cal_win_july_tex_rgb_ia8, cal_win_august_tex_rgb_ia8, + cal_win_september_tex_rgb_ia8, cal_win_october_tex_rgb_ia8, cal_win_november_tex_rgb_ia8, cal_win_december_tex_rgb_ia8, +}; + +extern u8 cal_win_event_tex[]; + +static u8* event_tex_table[] = { + cal_win_event_tex, cal_win_event_tex +}; + +static u8 box_prim_table[5][3] = { + {120, 120, 95}, {225, 195, 100}, {245, 205, 165}, {255, 245, 185}, {185, 215, 185}, +}; + +static u8 box_env_table[5][3] = { + {0x46, 0x46, 0x28}, {0x69, 0x3C, 0x32}, {0x69, 0x41, 0x41}, {0x7D, 0x55, 0x55}, {0x4B, 0x32, 0x3C}, +}; + +static u8 number_prim_table[5][3] = { + {0x82, 0x64, 0x3C}, {0x82, 0x64, 0x3C}, {0x7D, 0x5F, 0x55}, {0x82, 0x64, 0x3C}, {0x6E, 0x6E, 0x7D}, +}; + +static u8 number2_prim_table[5][3] = { + {0x82, 0x64, 0x3C}, {0x4B, 0x32, 0x32}, {0x55, 0x28, 0x28}, {0x4B, 0x32, 0x32}, {0x3C, 0x3C, 0x4B}, +}; + +extern u8 cal_win_suuji10_tex_rgb_i4[]; +extern u8 cal_win_suuji11_tex_rgb_i4[]; +extern u8 cal_win_suuji12_tex_rgb_i4[]; +extern u8 cal_win_suuji13_tex_rgb_i4[]; +extern u8 cal_win_suuji14_tex_rgb_i4[]; +extern u8 cal_win_suuji15_tex_rgb_i4[]; +extern u8 cal_win_suuji16_tex_rgb_i4[]; +extern u8 cal_win_suuji17_tex_rgb_i4[]; +extern u8 cal_win_suuji18_tex_rgb_i4[]; +extern u8 cal_win_suuji19_tex_rgb_i4[]; +extern u8 cal_win_suuji1_tex_rgb_i4[]; +extern u8 cal_win_suuji20_tex_rgb_i4[]; +extern u8 cal_win_suuji21_tex_rgb_i4[]; +extern u8 cal_win_suuji22_tex_rgb_i4[]; +extern u8 cal_win_suuji23_tex_rgb_i4[]; +extern u8 cal_win_suuji24_tex_rgb_i4[]; +extern u8 cal_win_suuji25_tex_rgb_i4[]; +extern u8 cal_win_suuji26_tex_rgb_i4[]; +extern u8 cal_win_suuji27_tex_rgb_i4[]; +extern u8 cal_win_suuji28_tex_rgb_i4[]; +extern u8 cal_win_suuji29_tex_rgb_i4[]; +extern u8 cal_win_suuji2_tex_rgb_i4[]; +extern u8 cal_win_suuji30_tex_rgb_i4[]; +extern u8 cal_win_suuji31_tex_rgb_i4[]; +extern u8 cal_win_suuji3_tex_rgb_i4[]; +extern u8 cal_win_suuji4_tex_rgb_i4[]; +extern u8 cal_win_suuji5_tex_rgb_i4[]; +extern u8 cal_win_suuji6_tex_rgb_i4[]; +extern u8 cal_win_suuji7_tex_rgb_i4[]; +extern u8 cal_win_suuji8_tex_rgb_i4[]; +extern u8 cal_win_suuji9_tex_rgb_i4[]; + +static u8* suuji_tex_table[31] = { + cal_win_suuji1_tex_rgb_i4, cal_win_suuji2_tex_rgb_i4, cal_win_suuji3_tex_rgb_i4, cal_win_suuji4_tex_rgb_i4, cal_win_suuji5_tex_rgb_i4, cal_win_suuji6_tex_rgb_i4, cal_win_suuji7_tex_rgb_i4, cal_win_suuji8_tex_rgb_i4, + cal_win_suuji9_tex_rgb_i4, cal_win_suuji10_tex_rgb_i4, cal_win_suuji11_tex_rgb_i4, cal_win_suuji12_tex_rgb_i4, cal_win_suuji13_tex_rgb_i4, cal_win_suuji14_tex_rgb_i4, cal_win_suuji15_tex_rgb_i4, cal_win_suuji16_tex_rgb_i4, + cal_win_suuji17_tex_rgb_i4, cal_win_suuji18_tex_rgb_i4, cal_win_suuji19_tex_rgb_i4, cal_win_suuji20_tex_rgb_i4, cal_win_suuji21_tex_rgb_i4, cal_win_suuji22_tex_rgb_i4, cal_win_suuji23_tex_rgb_i4, cal_win_suuji24_tex_rgb_i4, + cal_win_suuji25_tex_rgb_i4, cal_win_suuji26_tex_rgb_i4, cal_win_suuji27_tex_rgb_i4, cal_win_suuji28_tex_rgb_i4, cal_win_suuji29_tex_rgb_i4, cal_win_suuji30_tex_rgb_i4, cal_win_suuji31_tex_rgb_i4, +}; + +extern u8 cal_hyouji_st1_tex_rgb_ia8[]; +extern u8 cal_hyouji_st5_tex_rgb_ia8[]; + +static u8* cal_hyoji_txt_table[2] = { + cal_hyouji_st1_tex_rgb_ia8, cal_hyouji_st5_tex_rgb_ia8, +}; + +extern Gfx cal_win_nen1_model[]; +extern Gfx cal_win_nen2_model[]; +extern Gfx cal_win_nen3_model[]; +extern Gfx cal_win_nen4_model[]; + +static Gfx* cal_win_nen_table[4] = { + cal_win_nen4_model, cal_win_nen3_model, cal_win_nen2_model, cal_win_nen1_model, +}; + +extern u8 cal_win_nen0_tex_rgb_i4[]; +extern u8 cal_win_nen1_tex_rgb_i4[]; +extern u8 cal_win_nen2_tex_rgb_i4[]; +extern u8 cal_win_nen3_tex_rgb_i4[]; +extern u8 cal_win_nen4_tex_rgb_i4[]; +extern u8 cal_win_nen5_tex_rgb_i4[]; +extern u8 cal_win_nen6_tex_rgb_i4[]; +extern u8 cal_win_nen7_tex_rgb_i4[]; +extern u8 cal_win_nen8_tex_rgb_i4[]; +extern u8 cal_win_nen9_tex_rgb_i4[]; + +static u8* cal_win_nen_txt_table[10] = { + cal_win_nen0_tex_rgb_i4, cal_win_nen1_tex_rgb_i4, cal_win_nen2_tex_rgb_i4, cal_win_nen3_tex_rgb_i4, cal_win_nen4_tex_rgb_i4, cal_win_nen5_tex_rgb_i4, cal_win_nen6_tex_rgb_i4, cal_win_nen7_tex_rgb_i4, + cal_win_nen8_tex_rgb_i4, cal_win_nen9_tex_rgb_i4, +}; + +static u8 icon_mark_prim_table[][3] = { + {0x5F, 0x3C, 0x3C}, {0x5F, 0x3C, 0x3C}, {0xB9, 0x32, 0x32}, +}; + +extern Gfx needlework_before_model[]; +extern Gfx cal_win_tuki_model[]; +extern Gfx cal_win_shita_model[]; +extern Gfx cal_win_futi_model[]; +extern Gfx cal_win_nitiyouT_model[]; +extern Gfx cal_win_doyouT_model[]; +extern Gfx cal_win_hijituT_model[]; +extern Gfx cal_win_eventT_model[]; +extern Gfx cal_win_nen_before[]; +extern Gfx cal_win_monthT_model[]; +extern u8 cal_win_box_tex_rgb_ia8[]; +extern Gfx cal_win_boxT_model[]; +extern Gfx cal_win_suuji_model[]; +extern Gfx cal_icon_mark_model[]; +extern u8 cal_win_box2_tex_rgb_ia8[]; +extern Gfx cal_icon_cursor_model[]; +extern Gfx cal_icon_sakana_model[]; +extern Gfx cal_icon_yajirushi_model[]; +extern Gfx cal_icon_yajirushi_gfx[]; +extern Gfx cal_icon_yajirushi_gfx2[]; + +static void mCD_set_base_dl(Submenu* submenu, GAME* game, f32 pos_x, f32 pos_y, int sel) { + GRAPH* graph; + mCD_Ovl_c* calendar; + int idx; + int month; + int year_ofs; + int t0; + int flag; + int k; + int j; + int i; + int type; + int day; + int day_type; + u8* prim_p; + u8* env_p; + int tex_idx; + lbRTC_time_c* rtc_time; + + calendar = submenu->overlay->calendar_ovl; + graph = game->graph; + rtc_time = Common_GetPointer(time.rtc_time); + idx = 37; + if (calendar->move_proc_idx >= mCD_MVPL_DAY) { + idx = calendar->_1057; + } + + if (sel < 0 || sel >= 36) { + return; + } + + year_ofs = sel / lbRTC_MONTHS_MAX; + month = sel % lbRTC_MONTHS_MAX; + 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++, needlework_before_model); + gDPLoadTLUT_Dolphin(POLY_OPA_DISP++, 15, 16, 1, back_pal_table[month]); + gDPLoadTextureBlock_4b_Dolphin(POLY_OPA_DISP++, back_tex_table[month], G_IM_FMT_CI, 32, 32, 15, GX_REPEAT, GX_REPEAT, 0, 0); + gSPDisplayList(POLY_OPA_DISP++, cal_win_tuki_model); + gSPDisplayList(POLY_OPA_DISP++, cal_win_shita_model); + gSPDisplayList(POLY_OPA_DISP++, cal_win_futi_model); + gSPDisplayList(POLY_OPA_DISP++, cal_win_nitiyouT_model); + gSPDisplayList(POLY_OPA_DISP++, cal_win_doyouT_model); + gSPDisplayList(POLY_OPA_DISP++, cal_win_hijituT_model); + + if (calendar->move_proc_idx == mCD_MVPL_DAY && calendar->_1043 != 0) { + flag = TRUE; + } else { + flag = FALSE; + } + + if (!flag) { + gDPLoadTextureBlock_8b_Dolphin(POLY_OPA_DISP++, event_tex_table[0], G_IM_FMT_IA, 32, 64, 0, GX_MIRROR, GX_MIRROR, 0, 0); + gDPSetPrimColor(POLY_OPA_DISP++, 0, 255, 120, 120, 95, 255); + gDPSetEnvColor(POLY_OPA_DISP++, 70, 70, 40, 255); + gSPDisplayList(POLY_OPA_DISP++, cal_win_eventT_model); + } + + gSPDisplayList(POLY_OPA_DISP++, cal_win_nen_before); + + t0 = (rtc_time->year + year_ofs); + t0--; + for (j = 0; j < 4; j++) { + tex_idx = t0 % 10; + + gDPLoadTextureBlock_4b_Dolphin(POLY_OPA_DISP++, cal_win_nen_txt_table[tex_idx], G_IM_FMT_I, 16, 16, 15, GX_MIRROR, GX_MIRROR, 0, 0); + gSPDisplayList(POLY_OPA_DISP++, cal_win_nen_table[j]); + + t0 /= 10; + } + + gSPMatrix(POLY_OPA_DISP++, _Matrix_to_Mtx_new(graph), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gDPLoadTextureBlock_8b_Dolphin(POLY_OPA_DISP++, month_tex_table[month], G_IM_FMT_IA, 32, 128, 0, GX_MIRROR, GX_MIRROR, 0, 0); + gSPDisplayList(POLY_OPA_DISP++, cal_win_monthT_model); + gDPLoadTextureBlock_8b_Dolphin(POLY_OPA_DISP++, cal_win_box_tex_rgb_ia8, G_IM_FMT_IA, 32, 32, 0, GX_MIRROR, GX_MIRROR, 0, 0); + + k = 0; + for (i = 0; i < 37; k++) { + for (j = 0; j < lbRTC_WEEK && i < 37; i++) { + Matrix_push(); + Matrix_translate(j * 32, -k * 20, 0.0f, 1); + + gSPMatrix(POLY_OPA_DISP++, _Matrix_to_Mtx_new(graph), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + + if (idx != i) { + type = (calendar->month_entries[sel].day_data[i] >> 5) & 0b111; + + prim_p = box_prim_table[type]; + gDPSetPrimColor(POLY_OPA_DISP++, 0, 255, prim_p[0], prim_p[1], prim_p[2], 255); + + env_p = box_env_table[type]; + gDPSetEnvColor(POLY_OPA_DISP++, env_p[0], env_p[1], env_p[2], 255); + gSPDisplayList(POLY_OPA_DISP++, cal_win_boxT_model); + } + + Matrix_pull(); + j++; + } + } + + j = 0; + for (k = 0; k < 37; j++) { + for (i = 0; i < lbRTC_WEEK && k < 37; k++) { + Matrix_push(); + Matrix_translate(i * 32, -j * 20, 0.0f, 1); + + gSPMatrix(POLY_OPA_DISP++, _Matrix_to_Mtx_new(graph), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + + if (idx != k) { + type = (calendar->month_entries[sel].day_data[k] >> 5) & 0b111; + day = (calendar->month_entries[sel].day_data[k] & 0x1F); + + if (day > 0) { + prim_p = number_prim_table[type]; + gDPSetPrimColor(POLY_OPA_DISP++, 0, 255, prim_p[0], prim_p[1], prim_p[2], 255); + gDPLoadTextureBlock_4b_Dolphin(POLY_OPA_DISP++, suuji_tex_table[day - 1], G_IM_FMT_I, 16, 16, 15, GX_MIRROR, GX_MIRROR, 0, 0); + gSPDisplayList(POLY_OPA_DISP++, cal_win_suuji_model); + } + + if (calendar->month_entries[sel]._25[k] != 0) { + prim_p = icon_mark_prim_table[calendar->month_entries[sel]._25[k]]; + gDPSetPrimColor(POLY_OPA_DISP++, 0, 255, prim_p[0], prim_p[1], prim_p[2], 255); + gSPDisplayList(POLY_OPA_DISP++, cal_icon_mark_model); + } + } + + Matrix_pull(); + i++; + } + } + + if (calendar->move_proc_idx >= mCD_MVPL_DAY) { + day = calendar->month_entries[sel].day_data[idx] & 0x1F; + day_type = calendar->day_type; + Matrix_push(); + Matrix_translate((idx % lbRTC_WEEK) * 32, -(idx / lbRTC_WEEK) * 20, 0.0f, 1); + + gSPMatrix(POLY_OPA_DISP++, _Matrix_to_Mtx_new(graph), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gDPLoadTextureBlock_8b_Dolphin(POLY_OPA_DISP++, cal_win_box2_tex_rgb_ia8, G_IM_FMT_IA, 32, 32, 0, GX_MIRROR, GX_MIRROR, 0, 0); + + prim_p = box_prim_table[day_type]; + gDPSetPrimColor(POLY_OPA_DISP++, 0, 255, prim_p[0], prim_p[1], prim_p[2], 255); + env_p = box_env_table[day_type]; + gDPSetEnvColor(POLY_OPA_DISP++, env_p[0], env_p[1], env_p[2], 255); + gSPDisplayList(POLY_OPA_DISP++, cal_win_boxT_model); + + Matrix_translate(0.0f, 4.0f, 0.0f, 1); + gSPMatrix(POLY_OPA_DISP++, _Matrix_to_Mtx_new(graph), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + if (day > 0) { + prim_p = number2_prim_table[day_type]; + gDPSetPrimColor(POLY_OPA_DISP++, 0, 255, prim_p[0], prim_p[1], prim_p[2], 255); + gDPLoadTextureBlock_4b_Dolphin(POLY_OPA_DISP++, suuji_tex_table[day - 1], G_IM_FMT_I, 16, 16, 15, GX_MIRROR, GX_MIRROR, 0, 0); + gSPDisplayList(POLY_OPA_DISP++, cal_win_suuji_model); + } + + if (calendar->month_entries[sel]._25[idx] != 0) { + prim_p = icon_mark_prim_table[calendar->month_entries[sel]._25[idx]]; + gDPSetPrimColor(POLY_OPA_DISP++, 0, 255, prim_p[0], prim_p[1], prim_p[2], 255); + gSPDisplayList(POLY_OPA_DISP++, cal_icon_mark_model); + } + + gSPDisplayList(POLY_OPA_DISP++, cal_icon_cursor_model); + + Matrix_pull(); + gSPMatrix(POLY_OPA_DISP++, _Matrix_to_Mtx_new(graph), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + } + + if (flag == TRUE) { + + gDPLoadTextureBlock_8b_Dolphin(POLY_OPA_DISP++, event_tex_table[0], G_IM_FMT_IA, 32, 64, 0, GX_MIRROR, GX_MIRROR, 0, 0); + + day_type = calendar->day_type; + prim_p = box_prim_table[day_type]; + gDPSetPrimColor(POLY_OPA_DISP++, 0, 255, prim_p[0], prim_p[1], prim_p[2], 255); + env_p = box_env_table[day_type]; + gDPSetEnvColor(POLY_OPA_DISP++, env_p[0], env_p[1], env_p[2], 255); + + gSPDisplayList(POLY_OPA_DISP++, cal_win_eventT_model); + + if (calendar->_103C[calendar->_1042] & 0x80) { + Matrix_push(); + Matrix_translate(0.0f, 0.0f, 0.0f, 1); + gSPMatrix(POLY_OPA_DISP++, _Matrix_to_Mtx_new(graph), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, cal_icon_sakana_model); + Matrix_pull(); + gSPMatrix(POLY_OPA_DISP++, _Matrix_to_Mtx_new(graph), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + } + } + + if (flag == TRUE && calendar->_1043 > 1) { + Matrix_push(); + Matrix_translate(calendar->_1034, -1.5f, 0.0f, 1); + gSPMatrix(POLY_OPA_DISP++, _Matrix_to_Mtx_new(graph), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gDPSetPrimColor(POLY_OPA_DISP++, 0, 255, 0, 0, 255, calendar->_1054); + gSPDisplayList(POLY_OPA_DISP++, cal_icon_yajirushi_model); + + if (calendar->_1043 - 1 == calendar->_1042) { + gSPDisplayList(POLY_OPA_DISP++, cal_icon_yajirushi_gfx2); + } else { + gSPDisplayList(POLY_OPA_DISP++, cal_icon_yajirushi_gfx); + } + + Matrix_pull(); + gSPMatrix(POLY_OPA_DISP++, _Matrix_to_Mtx_new(graph), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + } + + CLOSE_POLY_OPA_DISP(graph); +} + +extern Gfx cal_hyouji_3DT_model[]; +extern Gfx cal_hyouji_shitaT_model[]; +extern Gfx cal_hyouji_b2_model[]; +extern Gfx cal_hyouji_amojiT_model[]; +extern Gfx cal_hyoji_yaji1T_model[]; +extern Gfx cal_hyoji_yajiA_gfx[]; +extern Gfx cal_hyoji_yajiB_gfx[]; +extern Gfx cal_hyouji_stT_model[]; + +static void mCD_set_hyoji_dl(Submenu* submenu, GAME* game, f32 pos_x, f32 pos_y) { + GRAPH* graph = game->graph; + mCD_Ovl_c* calendar = submenu->overlay->calendar_ovl; + + 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++, cal_hyouji_3DT_model); + gSPDisplayList(POLY_OPA_DISP++, cal_hyouji_shitaT_model); + gSPDisplayList(POLY_OPA_DISP++, cal_hyouji_b2_model); + gSPDisplayList(POLY_OPA_DISP++, cal_hyouji_amojiT_model); + + if (calendar->move_proc_idx == mCD_MVPL_SELECT) { + gSPDisplayList(POLY_OPA_DISP++, cal_hyoji_yaji1T_model); + + if (calendar->_1056 > calendar->_1059 - 11) { + gSPDisplayList(POLY_OPA_DISP++, cal_hyoji_yajiA_gfx); + } + + if (calendar->_1056 < calendar->_1059 + 11) { + gSPDisplayList(POLY_OPA_DISP++, cal_hyoji_yajiB_gfx); + } + } + + gDPSetTextureAdjustMode(POLY_OPA_DISP++, G_TA_DOLPHIN); + gDPLoadTextureBlock_8b_Dolphin(POLY_OPA_DISP++, cal_hyoji_txt_table[calendar->_105C != mCD_STICK_AREA_CENTER], G_IM_FMT_IA, 64, 64, 0, GX_MIRROR, GX_MIRROR, 0, 0); + + if (calendar->_105C == mCD_STICK_AREA_RIGHT) { + Matrix_push(); + Matrix_RotateY(DEG2SHORT_ANGLE2(180.0f), 1); + gSPMatrix(POLY_OPA_DISP++, _Matrix_to_Mtx_new(graph), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + } + gSPDisplayList(POLY_OPA_DISP++, cal_hyouji_stT_model); + gDPSetTextureAdjustMode(POLY_OPA_DISP++, G_TA_N64); + if (calendar->_105C == mCD_STICK_AREA_RIGHT) { + Matrix_pull(); + gSPMatrix(POLY_OPA_DISP++, _Matrix_to_Mtx_new(graph), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + } + + CLOSE_POLY_OPA_DISP(graph); +} + +extern Gfx cal_hyouji2_shitaT_model[]; +extern Gfx cal_hyouji2_bt_model[]; +extern Gfx cal_hyouji2_b2_model[]; +extern Gfx cal_hyouji2_amojiT_model[]; +extern Gfx cal_hyouji2_bmojiT_model[]; + +static void mCD_set_hyoji2_dl(Submenu* submenu, GAME* game, f32 pos_x, f32 pos_y) { + GRAPH* graph = game->graph; + + 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++, cal_hyouji2_shitaT_model); + gSPDisplayList(POLY_OPA_DISP++, cal_hyouji2_bt_model); + gSPDisplayList(POLY_OPA_DISP++, cal_hyouji2_b2_model); + gSPDisplayList(POLY_OPA_DISP++, cal_hyouji2_bmojiT_model); + gSPDisplayList(POLY_OPA_DISP++, cal_hyouji2_amojiT_model); + + CLOSE_POLY_OPA_DISP(graph); +} + +static void mCD_disp_event_dl(Submenu* submenu, GAME* game) { + GRAPH* graph = game->graph; + mCD_Ovl_c* calendar = submenu->overlay->calendar_ovl; + + if (calendar->_1043) { + int day_type; + u8* prim_p; + + (*submenu->overlay->set_char_matrix_proc)(graph); + day_type = calendar->day_type; + prim_p = number2_prim_table[day_type]; + + // clang-format off + mFont_SetLineStrings( + game, + calendar->event_name_str, mCD_EVENT_NAME_STR_LEN, + 128.0f, 161.0f, + prim_p[0], prim_p[1], prim_p[2], 255, + FALSE, TRUE, + 0.875f, 0.875f, + mFont_MODE_POLY + ); + // clang-format on + } +}