mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-04-21 03:55:32 +00:00
cellRtc: tick conversion improvements
This commit is contained in:
parent
f51b100a8c
commit
a5b6b2e9b5
2 changed files with 42 additions and 82 deletions
|
@ -742,7 +742,7 @@ error_code cellRtcParseRfc3339(vm::ptr<CellRtcTick> pUtc, vm::cptr<char> pszDate
|
|||
|
||||
error_code cellRtcGetTick(vm::cptr<CellRtcDateTime> pTime, vm::ptr<CellRtcTick> pTick)
|
||||
{
|
||||
cellRtc.todo("cellRtcGetTick(pTime=*0x%x, pTick=*0x%x)", pTime, pTick);
|
||||
cellRtc.notice("cellRtcGetTick(pTime=*0x%x, pTick=*0x%x)", pTime, pTick);
|
||||
|
||||
if (!vm::check_addr(pTime.addr()))
|
||||
{
|
||||
|
@ -761,72 +761,47 @@ error_code cellRtcGetTick(vm::cptr<CellRtcDateTime> pTime, vm::ptr<CellRtcTick>
|
|||
|
||||
if (!pTick)
|
||||
{
|
||||
return CELL_RTC_ERROR_INVALID_POINTER;
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s64 days_in_years = ((((pTime->year * 365ULL) + ((pTime->year + 3) / 4)) - ((pTime->year + 99) / 100)) + ((pTime->year + 399) / 400) + -366);
|
||||
|
||||
// 1-12
|
||||
if (1 < pTime->month)
|
||||
{
|
||||
u32 month_idx = pTime->month - 1;
|
||||
u32 monthIdx_adjusted = is_leap_year(pTime->year) * 12;
|
||||
do
|
||||
{
|
||||
days_in_years += DAYS_IN_MONTH[monthIdx_adjusted];
|
||||
month_idx -= 1;
|
||||
monthIdx_adjusted += 1;
|
||||
} while (month_idx != 0);
|
||||
}
|
||||
|
||||
pTick->tick = ((((days_in_years + (pTime->day - 1)) * 0x18 + pTime->hour) * 0x3c + pTime->minute) * 0x3c + pTime->second) * cellRtcGetTickResolution() + pTime->microsecond;
|
||||
pTick->tick = date_time_to_tick(*pTime);
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
CellRtcDateTime tick_to_date_time(u64 tick)
|
||||
{
|
||||
/*
|
||||
u32 microseconds = round((pTick->tick % 1000000ULL));
|
||||
u16 seconds = round((pTick->tick / (1000000ULL)) % 60);
|
||||
u16 minutes = round((pTick->tick / (60ULL * 1000000ULL)) % 60);
|
||||
u16 hours = round((pTick->tick / (60ULL * 60ULL * 1000000ULL)) % 24);
|
||||
u64 days_tmp = round((pTick->tick / (24ULL * 60ULL * 60ULL * 1000000ULL)));*/
|
||||
|
||||
const u32 microseconds = (tick % 1000000ULL);
|
||||
const u16 seconds = (tick / (1000000ULL)) % 60;
|
||||
const u16 minutes = (tick / (60ULL * 1000000ULL)) % 60;
|
||||
const u16 hours = (tick / (60ULL * 60ULL * 1000000ULL)) % 24;
|
||||
u64 days_tmp = (tick / (24ULL * 60ULL * 60ULL * 1000000ULL));
|
||||
|
||||
u16 months = 1;
|
||||
u16 years = 1;
|
||||
const u32 year_400 = days_tmp / DAYS_IN_400_YEARS;
|
||||
days_tmp -= year_400 * DAYS_IN_400_YEARS;
|
||||
|
||||
bool exit_while = false;
|
||||
do
|
||||
const u32 year_within_400_interval = (
|
||||
days_tmp
|
||||
- days_tmp / (DAYS_IN_4_YEARS - 1)
|
||||
+ days_tmp / DAYS_IN_100_YEARS
|
||||
- days_tmp / (DAYS_IN_400_YEARS - 1)
|
||||
) / 365;
|
||||
|
||||
days_tmp -= year_within_400_interval * 365 + year_within_400_interval / 4 - year_within_400_interval / 100 + year_within_400_interval / 400;
|
||||
|
||||
const u16 years = year_400 * 400 + year_within_400_interval + 1;
|
||||
|
||||
const auto& month_offset = is_leap_year(years) ? MONTH_OFFSET_LEAP : MONTH_OFFSET;
|
||||
|
||||
u32 month_approx = days_tmp / 29;
|
||||
|
||||
if (month_offset[month_approx] > days_tmp)
|
||||
{
|
||||
const bool leap = is_leap_year(years);
|
||||
for (u32 m = 0; m < 12; m++)
|
||||
{
|
||||
const u8 daysinmonth = DAYS_IN_MONTH[m + (leap * 12)];
|
||||
if (days_tmp >= daysinmonth)
|
||||
{
|
||||
months++;
|
||||
days_tmp -= daysinmonth;
|
||||
}
|
||||
else
|
||||
{
|
||||
exit_while = true;
|
||||
break;
|
||||
}
|
||||
if (m == 11)
|
||||
{
|
||||
months = 1;
|
||||
years++;
|
||||
}
|
||||
}
|
||||
month_approx--;
|
||||
}
|
||||
|
||||
} while (!exit_while);
|
||||
const u16 months = month_approx + 1;
|
||||
days_tmp = days_tmp - month_offset[month_approx];
|
||||
|
||||
CellRtcDateTime date_time{
|
||||
.year = years,
|
||||
|
@ -842,40 +817,18 @@ CellRtcDateTime tick_to_date_time(u64 tick)
|
|||
|
||||
u64 date_time_to_tick(CellRtcDateTime date_time)
|
||||
{
|
||||
const auto get_days_in_year = [](u16 year, u16 months) -> u64
|
||||
{
|
||||
const bool leap = is_leap_year(year);
|
||||
u64 days = 0;
|
||||
for (u16 m = 0; m < months; m++)
|
||||
{
|
||||
days += DAYS_IN_MONTH[m + (leap * 12)];
|
||||
}
|
||||
return days;
|
||||
};
|
||||
const u32 days_in_previous_years =
|
||||
date_time.year * 365
|
||||
+ (date_time.year + 3) / 4
|
||||
- (date_time.year + 99) / 100
|
||||
+ (date_time.year + 399) / 400
|
||||
- 366;
|
||||
|
||||
u64 days = 0;
|
||||
ensure(date_time.month - 1u < 12u); // Not checked on LLE
|
||||
|
||||
if (date_time.day > 1)
|
||||
{
|
||||
// We only need the whole days before "this" day
|
||||
days += date_time.day - 1ULL;
|
||||
}
|
||||
const u16 days_in_previous_months = is_leap_year(date_time.year) ? MONTH_OFFSET_LEAP[date_time.month - 1] : MONTH_OFFSET[date_time.month - 1];
|
||||
|
||||
if (date_time.month > 1)
|
||||
{
|
||||
// We only need the whole months before "this" month
|
||||
days += get_days_in_year(date_time.year, date_time.month - 1ULL);
|
||||
}
|
||||
|
||||
if (date_time.year > 1)
|
||||
{
|
||||
// We only need the whole years before "this" year
|
||||
// NOTE: tick_to_date_time starts counting with year 1, so count [1,n[ instead of [0,n-1[
|
||||
for (u16 year = 1; year < date_time.year; year++)
|
||||
{
|
||||
days += get_days_in_year(year, 12);
|
||||
}
|
||||
}
|
||||
const u32 days = days_in_previous_years + days_in_previous_months + date_time.day - 1;
|
||||
|
||||
u64 tick = date_time.microsecond
|
||||
+ u64{date_time.second} * 1000000ULL
|
||||
|
@ -888,7 +841,7 @@ u64 date_time_to_tick(CellRtcDateTime date_time)
|
|||
|
||||
error_code cellRtcSetTick(vm::ptr<CellRtcDateTime> pTime, vm::cptr<CellRtcTick> pTick)
|
||||
{
|
||||
cellRtc.todo("cellRtcSetTick(pTime=*0x%x, pTick=*0x%x)", pTime, pTick);
|
||||
cellRtc.notice("cellRtcSetTick(pTime=*0x%x, pTick=*0x%x)", pTime, pTick);
|
||||
|
||||
if (!vm::check_addr(pTime.addr()))
|
||||
{
|
||||
|
|
|
@ -38,6 +38,13 @@ struct CellRtcDateTime
|
|||
be_t<u32> microsecond; // 0 to 999999
|
||||
};
|
||||
|
||||
constexpr u32 DAYS_IN_400_YEARS = 365 * 400 + 97;
|
||||
constexpr u16 DAYS_IN_100_YEARS = 365 * 100 + 24;
|
||||
constexpr u16 DAYS_IN_4_YEARS = 365 * 4 + 1;
|
||||
|
||||
constexpr std::array<u16, 13> MONTH_OFFSET = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, umax };
|
||||
constexpr std::array<u16, 13> MONTH_OFFSET_LEAP = { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, umax };
|
||||
|
||||
error_code cellRtcTickAddYears(vm::ptr<CellRtcTick> pTick0, vm::cptr<CellRtcTick> pTick1, s32 iAdd);
|
||||
error_code cellRtcTickAddMonths(vm::ptr<CellRtcTick> pTick0, vm::cptr<CellRtcTick> pTick1, s32 lAdd);
|
||||
error_code cellRtcTickAddDays(vm::ptr<CellRtcTick> pTick0, vm::cptr<CellRtcTick> pTick1, s32 lAdd);
|
||||
|
|
Loading…
Add table
Reference in a new issue