FakeRtc datetime and ResetRtcScreen day increments (#5695)

Co-authored-by: psf <77138753+pkmnsnfrn@users.noreply.github.com>
This commit is contained in:
cawtds 2025-04-12 22:17:58 +02:00 committed by GitHub
parent 540744024d
commit ee911ffbae
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 335 additions and 68 deletions

28
include/datetime.h Normal file
View File

@ -0,0 +1,28 @@
#ifndef GUARD_DATETIME_H
#define GUARD_DATETIME_H
#include "global.h"
#include "siirtc.h"
struct DateTime
{
u16 year;
enum Month month;
u8 day;
enum Weekday dayOfWeek;
u8 hour;
u8 minute;
u8 second;
};
extern const struct DateTime gGen3Epoch;
void ConvertTimeToDateTime(struct DateTime *result, struct Time *timeSinceEpoch);
void DateTime_AddDays(struct DateTime *dateTime, u32 days);
void DateTime_AddHours(struct DateTime *dateTime, u32 hours);
void DateTime_AddMinutes(struct DateTime *dateTime, u32 minutes);
void DateTime_AddSeconds(struct DateTime *dateTime, u32 seconds);
void ConvertDateTimeToRtc(struct SiiRtcInfo *result, struct DateTime *dateTime);
void ConvertRtcToDateTime(struct DateTime *result, struct SiiRtcInfo *rtc);
#endif // GUARD_DATETIME_H

View File

@ -3,10 +3,11 @@
#include "siirtc.h"
struct Time* FakeRtc_GetCurrentTime(void);
void FakeRtc_Reset(void);
struct SiiRtcInfo* FakeRtc_GetCurrentTime(void);
void FakeRtc_GetRawInfo(struct SiiRtcInfo *rtc);
void FakeRtc_AdvanceTimeBy(u32 hours, u32 minutes, u32 seconds);
void FakeRtc_ManuallySetTime(u32 hour, u32 minute, u32 second);
void FakeRtc_AdvanceTimeBy(u32 days, u32 hours, u32 minutes, u32 seconds);
void FakeRtc_ManuallySetTime(u32 day, u32 hour, u32 minute, u32 second);
void FakeRtc_TickTimeForward(void);
u32 FakeRtc_GetSecondsRatio(void);

View File

@ -5,6 +5,7 @@
#include <limits.h>
#include "config/general.h" // we need to define config before gba headers as print stuff needs the functions nulled before defines.
#include "gba/gba.h"
#include "siirtc.h"
#include "fpmath.h"
#include "metaprogram.h"
#include "constants/global.h"
@ -205,7 +206,7 @@ struct Time
struct SaveBlock3
{
#if OW_USE_FAKE_RTC
struct Time fakeRTC;
struct SiiRtcInfo fakeRTC;
#endif
#if OW_SHOW_ITEM_DESCRIPTIONS == OW_ITEM_DESCRIPTIONS_FIRST_TIME
u8 itemFlags[ITEM_FLAGS_COUNT];

View File

@ -98,6 +98,7 @@ enum TimeOfDay
STATIC_ASSERT(OW_TIME_OF_DAY_DEFAULT == 0, TimeOfDayDefaultMustBeFirstElementInTimeOfDayEnum)
extern struct Time gLocalTime;
extern const s32 sNumDaysInMonths[12];
void RtcDisableInterrupts(void);
void RtcRestoreInterrupts(void);
@ -129,6 +130,10 @@ void CalcTimeDifference(struct Time *result, struct Time *t1, struct Time *t2);
u32 RtcGetMinuteCount(void);
u32 RtcGetLocalDayCount(void);
void FormatDecimalTimeWithoutSeconds(u8 *dest, s8 hour, s8 minute, bool32 is24Hour);
u16 GetFullYear(void);
enum Month GetMonth(void);
u8 GetDay(void);
enum Weekday GetDayOfWeek(void);
enum TimeOfDay TryIncrementTimeOfDay(enum TimeOfDay timeOfDay);
enum TimeOfDay TryDecrementTimeOfDay(enum TimeOfDay timeOfDay);

View File

@ -13,7 +13,19 @@
#define MINUTES_PER_HOUR 60
#define SECONDS_PER_MINUTE 60
enum
enum Weekday
{
WEEKDAY_SUN,
WEEKDAY_MON,
WEEKDAY_TUE,
WEEKDAY_WED,
WEEKDAY_THU,
WEEKDAY_FRI,
WEEKDAY_SAT,
WEEKDAY_COUNT,
};
enum Month
{
MONTH_JAN = 1,
MONTH_FEB,

115
src/datetime.c Normal file
View File

@ -0,0 +1,115 @@
#include "global.h"
#include "datetime.h"
#include "rtc.h"
const struct DateTime gGen3Epoch =
{
.year = 2000,
.month = MONTH_JAN,
.day = 1,
.dayOfWeek = WEEKDAY_SAT,
.hour = 0,
.minute = 0,
.second = 0,
};
void DateTime_AddDays(struct DateTime *dateTime, u32 days)
{
while (days > 0)
{
u32 remainingDaysInMonth = (sNumDaysInMonths[dateTime->month - 1] + (dateTime->month == MONTH_FEB && IsLeapYear(dateTime->year)) - dateTime->day);
if (days > remainingDaysInMonth)
{
dateTime->day = 1;
dateTime->month++;
if (dateTime->month > MONTH_DEC)
{
dateTime->month = MONTH_JAN;
dateTime->year++;
}
days -= (remainingDaysInMonth + 1);
dateTime->dayOfWeek = (dateTime->dayOfWeek + remainingDaysInMonth + 1) % WEEKDAY_COUNT;
}
else
{
dateTime->day += days;
dateTime->dayOfWeek = (dateTime->dayOfWeek + days) % WEEKDAY_COUNT;
days = 0;
}
}
}
void DateTime_AddHours(struct DateTime *dateTime, u32 hours)
{
u32 days = 0;
dateTime->hour += hours;
while (dateTime->hour >= HOURS_PER_DAY)
{
days++;
dateTime->hour -= HOURS_PER_DAY;
}
DateTime_AddDays(dateTime, days);
}
void DateTime_AddMinutes(struct DateTime *dateTime, u32 minutes)
{
u32 hours = 0;
dateTime->minute += minutes;
while(dateTime->minute >= MINUTES_PER_HOUR)
{
hours++;
dateTime->minute -= MINUTES_PER_HOUR;
}
DateTime_AddHours(dateTime, hours);
}
void DateTime_AddSeconds(struct DateTime *dateTime, u32 seconds)
{
u32 minutes = 0;
dateTime->second += seconds;
while(dateTime->second >= SECONDS_PER_MINUTE)
{
minutes++;
dateTime->second -= SECONDS_PER_MINUTE;
}
DateTime_AddMinutes(dateTime, minutes);
}
void ConvertDateTimeToRtc(struct SiiRtcInfo *result, struct DateTime *dateTime)
{
result->second = dateTime->second;
result->minute = dateTime->minute;
result->hour = dateTime->hour;
result->day = dateTime->day;
result->dayOfWeek = dateTime->dayOfWeek;
result->month = dateTime->month;
result->year = dateTime->year - gGen3Epoch.year;
}
void ConvertRtcToDateTime(struct DateTime *result, struct SiiRtcInfo *rtc)
{
result->second = rtc->second;
result->minute = rtc->minute;
result->hour = rtc->hour;
result->day = rtc->day;
result->dayOfWeek = rtc->dayOfWeek;
result->month = rtc->month;
result->year = gGen3Epoch.year + rtc->year;
}
void ConvertTimeToDateTime(struct DateTime *result, struct Time *timeSinceEpoch)
{
result = memcpy(result, &gGen3Epoch, sizeof(struct DateTime));
DateTime_AddSeconds(result, timeSinceEpoch->seconds);
DateTime_AddMinutes(result, timeSinceEpoch->minutes);
DateTime_AddHours(result, timeSinceEpoch->hours);
DateTime_AddDays(result, timeSinceEpoch->days);
}

View File

@ -2,12 +2,24 @@
#include "string_util.h"
#include "strings.h"
#include "text.h"
#include "datetime.h"
#include "rtc.h"
#include "fake_rtc.h"
#include "event_data.h"
#include "script.h"
struct Time *FakeRtc_GetCurrentTime(void)
void FakeRtc_Reset(void)
{
#if OW_USE_FAKE_RTC
memset(&gSaveBlock3Ptr->fakeRTC, 0, sizeof(gSaveBlock3Ptr->fakeRTC));
gSaveBlock3Ptr->fakeRTC.year = 0; // offset by gGen3Epoch.year
gSaveBlock3Ptr->fakeRTC.month = gGen3Epoch.month;
gSaveBlock3Ptr->fakeRTC.day = gGen3Epoch.day;
gSaveBlock3Ptr->fakeRTC.dayOfWeek = gGen3Epoch.dayOfWeek;
#endif
}
struct SiiRtcInfo *FakeRtc_GetCurrentTime(void)
{
#if OW_USE_FAKE_RTC
return &gSaveBlock3Ptr->fakeRTC;
@ -18,11 +30,9 @@ struct Time *FakeRtc_GetCurrentTime(void)
void FakeRtc_GetRawInfo(struct SiiRtcInfo *rtc)
{
struct Time* time = FakeRtc_GetCurrentTime();
rtc->second = time->seconds;
rtc->minute = time->minutes;
rtc->hour = time->hours;
rtc->day = time->days;
struct SiiRtcInfo *fakeRtc = FakeRtc_GetCurrentTime();
if (fakeRtc != NULL)
memcpy(rtc, fakeRtc, sizeof(struct SiiRtcInfo));
}
void FakeRtc_TickTimeForward(void)
@ -33,51 +43,31 @@ void FakeRtc_TickTimeForward(void)
if (FlagGet(OW_FLAG_PAUSE_TIME))
return;
FakeRtc_AdvanceTimeBy(0, 0, FakeRtc_GetSecondsRatio());
FakeRtc_AdvanceTimeBy(0, 0, 0, FakeRtc_GetSecondsRatio());
}
void FakeRtc_AdvanceTimeBy(u32 hours, u32 minutes, u32 seconds)
void FakeRtc_AdvanceTimeBy(u32 days, u32 hours, u32 minutes, u32 seconds)
{
struct Time* time = FakeRtc_GetCurrentTime();
seconds += time->seconds;
minutes += time->minutes;
hours += time->hours;
struct DateTime dateTime;
struct SiiRtcInfo *rtc = FakeRtc_GetCurrentTime();
while(seconds >= SECONDS_PER_MINUTE)
{
minutes++;
seconds -= SECONDS_PER_MINUTE;
}
while(minutes >= MINUTES_PER_HOUR)
{
hours++;
minutes -= MINUTES_PER_HOUR;
}
while(hours >= HOURS_PER_DAY)
{
time->days++;
hours -= HOURS_PER_DAY;
}
time->seconds = seconds;
time->minutes = minutes;
time->hours = hours;
ConvertRtcToDateTime(&dateTime, rtc);
DateTime_AddSeconds(&dateTime, seconds);
DateTime_AddMinutes(&dateTime, minutes);
DateTime_AddHours(&dateTime, hours);
DateTime_AddDays(&dateTime, days);
ConvertDateTimeToRtc(rtc, &dateTime);
}
void FakeRtc_ManuallySetTime(u32 hour, u32 minute, u32 second)
void FakeRtc_ManuallySetTime(u32 day, u32 hour, u32 minute, u32 second)
{
struct Time diff, target;
RtcCalcLocalTime();
FakeRtc_Reset();
FakeRtc_AdvanceTimeBy(day, hour, minute, second);
}
target.hours = hour;
target.minutes = minute;
target.seconds = second;
target.days = gLocalTime.days;
CalcTimeDifference(&diff, &gLocalTime, &target);
FakeRtc_AdvanceTimeBy(diff.hours, diff.minutes, diff.seconds);
void AdvanceScript(void)
{
FakeRtc_AdvanceTimeBy(300, 0, 0, 0);
}
u32 FakeRtc_GetSecondsRatio(void)

View File

@ -1,6 +1,7 @@
#include "global.h"
#include "malloc.h"
#include "berry_powder.h"
#include "fake_rtc.h"
#include "item.h"
#include "load_save.h"
#include "main.h"
@ -63,6 +64,7 @@ void CheckForFlashMemory(void)
void ClearSav3(void)
{
CpuFill16(0, &gSaveblock3, sizeof(struct SaveBlock3));
FakeRtc_Reset();
}
void ClearSav2(void)

View File

@ -1,6 +1,7 @@
#include "global.h"
#include "reset_rtc_screen.h"
#include "event_data.h"
#include "fake_rtc.h"
#include "main.h"
#include "menu.h"
#include "palette.h"
@ -41,7 +42,10 @@ enum {
#define tWindowId data[8]
enum {
SELECTION_DAYS = 1,
SELECTION_DAYS_1000 = 1,
SELECTION_DAYS_100,
SELECTION_DAYS_10,
SELECTION_DAYS_1,
SELECTION_HOURS,
SELECTION_MINS,
SELECTION_SECS,
@ -59,6 +63,7 @@ struct ResetRtcInputMap
/*0x0*/ u8 dataIndex;
/*0x2*/ u16 minVal;
/*0x4*/ u16 maxVal;
u16 increment;
/*0x6*/ u8 left;
/*0x7*/ u8 right;
/*0x8*/ u8 unk; // never read
@ -117,43 +122,75 @@ static const struct WindowTemplate sInputTimeWindow = {
static const struct ResetRtcInputMap sInputMap[] =
{
[SELECTION_DAYS - 1] = {
[SELECTION_DAYS_1000 - 1] = {
.dataIndex = DATAIDX_DAYS,
.minVal = 1,
.maxVal = 9999,
.increment = 1000,
.left = 0,
.right = 2,
.unk = 0,
},
[SELECTION_DAYS_100 - 1] = {
.dataIndex = DATAIDX_DAYS,
.minVal = 1,
.maxVal = 9999,
.increment = 100,
.left = 1,
.right = 3,
.unk = 0,
},
[SELECTION_DAYS_10 - 1] = {
.dataIndex = DATAIDX_DAYS,
.minVal = 1,
.maxVal = 9999,
.increment = 10,
.left = 2,
.right = 4,
.unk = 0,
},
[SELECTION_DAYS_1 - 1] = {
.dataIndex = DATAIDX_DAYS,
.minVal = 1,
.maxVal = 9999,
.increment = 1,
.left = 3,
.right = 5,
.unk = 0,
},
[SELECTION_HOURS - 1] = {
.dataIndex = DATAIDX_HOURS,
.minVal = 0,
.maxVal = 23,
.left = 1,
.right = 3,
.increment = 1,
.left = 4,
.right = 6,
.unk = 0,
},
[SELECTION_MINS - 1] = {
.dataIndex = DATAIDX_MINS,
.minVal = 0,
.maxVal = 59,
.left = 2,
.right = 4,
.increment = 1,
.left = 5,
.right = 7,
.unk = 0,
},
[SELECTION_SECS - 1] = {
.dataIndex = DATAIDX_SECS,
.minVal = 0,
.maxVal = 59,
.left = 3,
.right = 5,
.increment = 1,
.left = 6,
.right = 8,
.unk = 0,
},
[SELECTION_CONFIRM - 1] = {
.dataIndex = DATAIDX_CONFIRM,
.minVal = 0,
.maxVal = 0,
.left = 4,
.increment = 1,
.left = 7,
.right = 0,
.unk = 6,
},
@ -244,7 +281,28 @@ static void SpriteCB_Cursor_UpOrRight(struct Sprite *sprite)
sprite->sState = state;
switch (state)
{
case SELECTION_DAYS:
case SELECTION_DAYS_1000:
sprite->invisible = FALSE;
sprite->animNum = ARROW_UP;
sprite->animDelayCounter = 0;
sprite->x = 35;
sprite->y = 68;
break;
case SELECTION_DAYS_100:
sprite->invisible = FALSE;
sprite->animNum = ARROW_UP;
sprite->animDelayCounter = 0;
sprite->x = 41;
sprite->y = 68;
break;
case SELECTION_DAYS_10:
sprite->invisible = FALSE;
sprite->animNum = ARROW_UP;
sprite->animDelayCounter = 0;
sprite->x = 47;
sprite->y = 68;
break;
case SELECTION_DAYS_1:
sprite->invisible = FALSE;
sprite->animNum = ARROW_UP;
sprite->animDelayCounter = 0;
@ -294,7 +352,28 @@ static void SpriteCB_Cursor_Down(struct Sprite *sprite)
sprite->sState = state;
switch (state)
{
case SELECTION_DAYS:
case SELECTION_DAYS_1000:
sprite->invisible = FALSE;
sprite->animNum = ARROW_DOWN;
sprite->animDelayCounter = 0;
sprite->x = 35;
sprite->y = 92;
break;
case SELECTION_DAYS_100:
sprite->invisible = FALSE;
sprite->animNum = ARROW_DOWN;
sprite->animDelayCounter = 0;
sprite->x = 41;
sprite->y = 92;
break;
case SELECTION_DAYS_10:
sprite->invisible = FALSE;
sprite->animNum = ARROW_DOWN;
sprite->animDelayCounter = 0;
sprite->x = 47;
sprite->y = 92;
break;
case SELECTION_DAYS_1:
sprite->invisible = FALSE;
sprite->animNum = ARROW_DOWN;
sprite->animDelayCounter = 0;
@ -397,17 +476,17 @@ static void ShowChooseTimeWindow(u8 windowId, u16 days, u8 hours, u8 minutes, u8
ScheduleBgCopyTilemapToVram(0);
}
static bool32 MoveTimeUpDown(s16 *val, int minVal, int maxVal, u16 keys)
static bool32 MoveTimeUpDown(s16 *val, int minVal, int maxVal, int increment, u16 keys)
{
if (keys & DPAD_DOWN)
{
*val -= 1;
*val -= increment;
if (*val < minVal)
*val = maxVal;
}
else if (keys & DPAD_UP)
{
*val += 1;
*val += increment;
if (*val > maxVal)
*val = minVal;
}
@ -494,7 +573,7 @@ static void Task_ResetRtc_HandleInput(u8 taskId)
tSelection = SELECTION_NONE;
}
}
else if (MoveTimeUpDown(&data[selectionInfo->dataIndex], selectionInfo->minVal, selectionInfo->maxVal, JOY_REPEAT(DPAD_UP | DPAD_DOWN)))
else if (MoveTimeUpDown(&data[selectionInfo->dataIndex], selectionInfo->minVal, selectionInfo->maxVal, selectionInfo->increment, JOY_REPEAT(DPAD_UP | DPAD_DOWN)))
{
PlaySE(SE_SELECT);
PrintTime(tWindowId, 0, 1, tDays, tHours, tMinutes, tSeconds);

View File

@ -1,6 +1,7 @@
#include "global.h"
#include "battle_pike.h"
#include "battle_pyramid.h"
#include "datetime.h"
#include "rtc.h"
#include "string_util.h"
#include "strings.h"
@ -21,7 +22,7 @@ COMMON_DATA struct Time gLocalTime = {0};
static const struct SiiRtcInfo sRtcDummy = {0, MONTH_JAN, 1}; // 2000 Jan 1
static const s32 sNumDaysInMonths[MONTH_COUNT] =
const s32 sNumDaysInMonths[MONTH_COUNT] =
{
[MONTH_JAN - 1] = 31,
[MONTH_FEB - 1] = 28,
@ -98,9 +99,6 @@ u16 RtcGetDayCount(struct SiiRtcInfo *rtc)
{
u8 year, month, day;
if (OW_USE_FAKE_RTC)
return rtc->day;
year = ConvertBcdToBinary(rtc->year);
month = ConvertBcdToBinary(rtc->month);
day = ConvertBcdToBinary(rtc->day);
@ -233,7 +231,7 @@ void RtcReset(void)
{
if (OW_USE_FAKE_RTC)
{
memset(FakeRtc_GetCurrentTime(), 0, sizeof(struct Time));
FakeRtc_Reset();
return;
}
@ -421,6 +419,42 @@ void FormatDecimalTimeWithoutSeconds(u8 *txtPtr, s8 hour, s8 minute, bool32 is24
*txtPtr = EOS;
}
u16 GetFullYear(void)
{
struct DateTime dateTime;
RtcCalcLocalTime();
ConvertTimeToDateTime(&dateTime, &gLocalTime);
return dateTime.year;
}
enum Month GetMonth(void)
{
struct DateTime dateTime;
RtcCalcLocalTime();
ConvertTimeToDateTime(&dateTime, &gLocalTime);
return dateTime.month;
}
u8 GetDay(void)
{
struct DateTime dateTime;
RtcCalcLocalTime();
ConvertTimeToDateTime(&dateTime, &gLocalTime);
return dateTime.day;
}
enum Weekday GetDayOfWeek(void)
{
struct DateTime dateTime;
RtcCalcLocalTime();
ConvertTimeToDateTime(&dateTime, &gLocalTime);
return dateTime.dayOfWeek;
}
enum TimeOfDay TryIncrementTimeOfDay(enum TimeOfDay timeOfDay)
{
return timeOfDay == TIME_NIGHT ? TIME_MORNING : timeOfDay + 1;