From c75716e58c7485239005f9fcf0572e9c80f26c5b Mon Sep 17 00:00:00 2001 From: Cuyler36 Date: Tue, 29 Aug 2023 16:03:25 -0400 Subject: [PATCH] Implement & link m_calendar.c --- config/rel_slices.yml | 2 + include/m_calendar.h | 14 ++ rel/m_calendar.c | 390 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 406 insertions(+) create mode 100644 rel/m_calendar.c diff --git a/config/rel_slices.yml b/config/rel_slices.yml index 0a536ed0..b781a046 100644 --- a/config/rel_slices.yml +++ b/config/rel_slices.yml @@ -30,6 +30,8 @@ m_banti.c: .rodata: [0x80641388, 0x806413E0] .data: [0x8064F548, 0x8064F658] .bss: [0x8125A830, 0x8125AC80] +m_calendar.c: + .text: [0x8037D190, 0x8037DA54] m_cockroach.c: .text: [0x80385430, 0x80385A80] m_common_data.c: diff --git a/include/m_calendar.h b/include/m_calendar.h index 2fb28399..bff5bf93 100644 --- a/include/m_calendar.h +++ b/include/m_calendar.h @@ -8,6 +8,14 @@ extern "C" { #endif +#define mCD_FLAG_MOTHERS_DAY (1 << 0) +#define mCD_FLAG_TOWN_DAY (1 << 1) +#define mCD_FLAG_METEOR_SHOWER (1 << 2) +#define mCD_FLAG_FOUNDERS_DAY (1 << 3) +#define mCD_FLAG_HARVEST_MOON_9 (1 << 4) +#define mCD_FLAG_HARVEST_MOON_10 (1 << 5) +#define mCD_FLAG_OFFICERS_DAY (1 << 6) + /* sizeof(mCD_player_calendar_c) == 0x68 */ typedef struct calendar_player_info_s { /* 0x00 */ u32 played_days[lbRTC_MONTHS_MAX]; /* bitfield of days where 1 bit represents a day played */ @@ -18,6 +26,12 @@ typedef struct calendar_player_info_s { /* 0x66 */ lbRTC_month_t month; /* month calendar was last updated */ } mCD_player_calendar_c; +extern void mCD_calendar_clear(int player_no); +extern void mCD_calendar_check_delete(int player_no, lbRTC_year_t year, lbRTC_month_t month, lbRTC_day_t day); +extern void mCD_calendar_wellcome_on(); +extern void mCD_calendar_event_on(lbRTC_year_t year, lbRTC_month_t month, lbRTC_day_t day, u8 event); +extern int mCD_calendar_event_check(lbRTC_year_t year, lbRTC_month_t month, lbRTC_day_t day, int player_no, u8 event); + #ifdef __cplusplus } #endif diff --git a/rel/m_calendar.c b/rel/m_calendar.c new file mode 100644 index 00000000..640a3546 --- /dev/null +++ b/rel/m_calendar.c @@ -0,0 +1,390 @@ +#include "m_calendar.h" + +#include "lb_reki.h" +#include "m_common_data.h" + +static void mCD_calendar_clear_interval(mCD_player_calendar_c* calendar, int interval) { + u8 months[lbRTC_MONTHS_MAX]; + int i; + + for (i = 0; i < lbRTC_MONTHS_MAX; i++) { + months[i] = 0; + } + + for (i = 0; i < interval; i++) { + months[(calendar->month + i) % lbRTC_MONTHS_MAX] = 1; + } + + for (i = 0; i > interval; i--) { + months[(calendar->month + (lbRTC_MONTHS_MAX - 1) + i) % lbRTC_MONTHS_MAX] = 1; + } + + for (i = 0; i < lbRTC_MONTHS_MAX; i++) { + if (months[i] == 1) { + calendar->played_days[i] = 0; + calendar->event_days[i] = 0; + } + } + + if (months[lbRTC_JUNE - 1] == 1) { + calendar->event_flags &= ~mCD_FLAG_MOTHERS_DAY; // 1 + } + + if (months[lbRTC_JULY - 1] == 1) { + calendar->event_flags &= ~mCD_FLAG_TOWN_DAY; // 2 + } + + if (months[lbRTC_AUGUST - 1] == 1) { + calendar->event_flags &= ~(mCD_FLAG_METEOR_SHOWER | mCD_FLAG_FOUNDERS_DAY); // 12 (4 | 8) + } + + if (months[lbRTC_SEPTEMBER - 1] == 1) { + calendar->event_flags &= ~mCD_FLAG_HARVEST_MOON_9; // 16 + } + + if (months[lbRTC_OCTOBER - 1] == 1) { + calendar->event_flags &= ~mCD_FLAG_HARVEST_MOON_10; // 32 + } + + if (months[lbRTC_NOVEMBER - 1] == 1) { + calendar->event_flags &= ~mCD_FLAG_OFFICERS_DAY; // 64 + } +} + +static void mCD_calendar_clear_day(mCD_player_calendar_c* calendar, lbRTC_year_t year, lbRTC_month_t month, lbRTC_day_t day) { + lbRTC_day_t days = lbRTC_GetDaysByMonth(year, month); + int i; + + if (days != day) { + u32 days_bitfield = 0; + for (i = day; i < 31; i++) { + days_bitfield |= (1 << i); + } + + calendar->played_days[month - 1] &= ~days_bitfield; + calendar->event_days[month - 1] &= ~days_bitfield; + + switch (month) { + case lbRTC_JUNE: + { + lbRTC_weekday_t weekday = lbRTC_Week(year, month, day + 1); + + /* Calculate the current week and verify it's not the last week */ + if ((day - weekday) / lbRTC_WEEK + 1 < 3) { + calendar->event_flags &= ~mCD_FLAG_MOTHERS_DAY; + } + + break; + } + + case lbRTC_JULY: + { + if (day < Save_Get(town_day)) { + calendar->event_flags &= ~mCD_FLAG_TOWN_DAY; + } + + break; + } + + case lbRTC_AUGUST: + { + if (day < 12) { + calendar->event_flags &= ~mCD_FLAG_METEOR_SHOWER; + } + + if (day < 21) { + calendar->event_flags &= ~mCD_FLAG_FOUNDERS_DAY; + } + + break; + } + + case lbRTC_SEPTEMBER: + { + lbRTC_ymd_t harvest_moon_day; + + lbRk_HarvestMoonDay(&harvest_moon_day, year); + + if (month == harvest_moon_day.month && day < harvest_moon_day.day) { + calendar->event_flags &= ~mCD_FLAG_HARVEST_MOON_9; + } + + break; + } + + case lbRTC_OCTOBER: + { + lbRTC_ymd_t harvest_moon_day; + + lbRk_HarvestMoonDay(&harvest_moon_day, year); + + if (month == harvest_moon_day.month && day < harvest_moon_day.day) { + calendar->event_flags &= ~mCD_FLAG_HARVEST_MOON_10; + } + + break; + } + + case lbRTC_NOVEMBER: + { + if (day < 11) { + calendar->event_flags &= ~mCD_FLAG_OFFICERS_DAY; + } + + break; + } + } + } +} + +static int mCD_GetIntervalMonths(lbRTC_year_t y0, lbRTC_month_t m0, lbRTC_year_t y1, lbRTC_month_t m1) { + return (m1 - m0) + (y1 - y0) * lbRTC_MONTHS_MAX; +} + +extern void mCD_calendar_clear(int player_no) { + Private_c* priv = Save_Get(private); + + if (player_no == -1) { + player_no = Common_Get(player_no); + } + + if (player_no != mPr_FOREIGNER) { + mem_clear((u8*)&priv[player_no].calendar, sizeof(mCD_player_calendar_c), 0); + } +} + +static int mCD_calendar_check_harvest_moon_viewing(mCD_player_calendar_c* calendar, lbRTC_month_t month) { + int res = FALSE; + + switch (month) { + case lbRTC_SEPTEMBER: + { + if ((calendar->event_flags & mCD_FLAG_HARVEST_MOON_9) != 0) { + res = TRUE; + } + + break; + } + + case lbRTC_OCTOBER: + { + if ((calendar->event_flags & mCD_FLAG_HARVEST_MOON_10) != 0) { + res = TRUE; + } + + break; + } + } + + return res; +} + +extern void mCD_calendar_check_delete(int player_no, lbRTC_year_t year, lbRTC_month_t month, lbRTC_day_t day) { + if (player_no == -1) { + player_no = Common_Get(player_no); + } + + if (player_no != mPr_FOREIGNER) { + mCD_player_calendar_c* calendar = &Save_Get(private[player_no]).calendar; + + if (calendar->year == 0) { + mCD_calendar_clear(-1); + } + else { + int interval = mCD_GetIntervalMonths(calendar->year, calendar->month, year, month); + + if (interval >= lbRTC_MONTHS_MAX || interval <= -lbRTC_MONTHS_MAX) { + mCD_calendar_clear(-1); // clear entire calendar since interval is >= 1 year + } + else { + if (interval != 0) { + mCD_calendar_clear_interval(calendar, interval); // clear only interval months + } + + mCD_calendar_clear_day(calendar, year, month, day); // clear days + } + } + } +} + +extern void mCD_calendar_wellcome_on() { + mCD_player_calendar_c* calendar = &Common_Get(now_private)->calendar; + + if (Common_Get(player_no) != mPr_FOREIGNER) { + lbRTC_time_c* rtc_time = Common_GetPointer(time.rtc_time); + + mCD_calendar_check_delete(-1, rtc_time->year, rtc_time->month, rtc_time->day); + calendar->played_days[rtc_time->month - 1] |= (1 << (rtc_time->day - 1)); + calendar->year = rtc_time->year; + calendar->month = rtc_time->month; + } +} + +extern void mCD_calendar_event_on(lbRTC_year_t year, lbRTC_month_t month, lbRTC_day_t day, u8 event) { + if (Common_Get(player_no) != mPr_FOREIGNER) { + mCD_player_calendar_c* calendar; + + mCD_calendar_check_delete(-1, year, month, day); + calendar = &Save_Get(private[Common_Get(player_no)]).calendar; + + switch (event) { + case 11: + { + calendar->event_flags |= mCD_FLAG_MOTHERS_DAY; + + break; + } + + case 4: + { + calendar->event_flags |= mCD_FLAG_TOWN_DAY; + + break; + } + + case 16: + { + calendar->event_flags |= mCD_FLAG_METEOR_SHOWER; + + break; + } + + case 1: + { + calendar->event_flags |= mCD_FLAG_FOUNDERS_DAY; + + break; + } + + case 17: + { + switch (month) { + case lbRTC_SEPTEMBER: + { + calendar->event_flags |= mCD_FLAG_HARVEST_MOON_9; + + break; + } + + case lbRTC_OCTOBER: + { + calendar->event_flags |= mCD_FLAG_HARVEST_MOON_10; + + break; + } + } + + break; + } + + case 19: + { + calendar->event_flags |= mCD_FLAG_OFFICERS_DAY; + + break; + } + + case 255: + { + break; + } + + default: + { + calendar->event_days[month - 1] |= (1 << (day - 1)); + + break; + } + } + } +} + +extern int mCD_calendar_event_check(lbRTC_year_t year, lbRTC_month_t month, lbRTC_day_t day, int player_no, u8 event) { + int res = FALSE; + + if (player_no == -1) { + player_no = Common_Get(player_no); + } + + if (player_no != mPr_FOREIGNER) { + lbRTC_time_c* rtc_time = Common_GetPointer(time.rtc_time); + + int interval = (rtc_time->month - month) + (rtc_time->year - year) * lbRTC_MONTHS_MAX; + + if (interval >= 0 && interval < lbRTC_MONTHS_MAX) { + mCD_player_calendar_c* calendar = &Save_Get(private[player_no]).calendar; + + switch (event) { + case 11: + { + if (calendar->event_flags & mCD_FLAG_MOTHERS_DAY) { + res = TRUE; + } + + break; + } + + case 4: + { + if (calendar->event_flags & mCD_FLAG_TOWN_DAY) { + res = TRUE; + } + + break; + } + + case 16: + { + if (calendar->event_flags & mCD_FLAG_METEOR_SHOWER) { + res = TRUE; + } + + break; + } + + case 1: + { + if (calendar->event_flags & mCD_FLAG_FOUNDERS_DAY) { + res = TRUE; + } + + break; + } + + case 17: + { + if (mCD_calendar_check_harvest_moon_viewing(calendar, month) == TRUE) { + res = TRUE; + } + + break; + } + + case 19: + { + if (calendar->event_flags & mCD_FLAG_OFFICERS_DAY) { + res = TRUE; + } + + break; + } + + case 255: + { + break; + } + + default: + { + if (calendar->event_days[month - 1] & (1 << (day - 1))) { + res = TRUE; + } + + break; + } + } + } + } + + return res; +}