Merge pull request #90 from tmaul/master

Update sceRtcSetTick based on test cases
This commit is contained in:
Henrik Rydgård 2012-11-25 02:13:27 -08:00
commit ec25bfc9a4
2 changed files with 729 additions and 645 deletions

View file

@ -68,6 +68,86 @@ void __RtcTmToPspTime(ScePspDateTime &t, tm *val)
t.second = val->tm_sec;
}
//based on http://stackoverflow.com/a/11197532
void __RtcTicksToPspTime(ScePspDateTime &t, u64 ticks)
{
u64 sec;
u16 quadricentennials, centennials, quadrennials, annuals/*1-ennial?*/;
u16 year, leap;
u16 yday, hour, min;
u16 month, mday, wday;
static const u16 daysSinceJan1st[2][13]=
{
{0,31,59,90,120,151,181,212,243,273,304,334,365}, // 365 days, non-leap
{0,31,60,91,121,152,182,213,244,274,305,335,366} // 366 days, leap
};
sec = ticks / 1000000UL;
wday = (u16)((sec / 86400 + 1) % 7); // day of week
// Remove multiples of 400 years (incl. 97 leap days)
quadricentennials = (u16)(sec / 12622780800ULL); // 400*365.2425*24*3600
sec %= 12622780800ULL;
// Remove multiples of 100 years (incl. 24 leap days), can't be more than 3
// (because multiples of 4*100=400 years (incl. leap days) have been removed)
centennials = (u16)(sec / 3155673600ULL); // 100*(365+24/100)*24*3600
if (centennials > 3)
{
centennials = 3;
}
sec -= centennials * 3155673600ULL;
// Remove multiples of 4 years (incl. 1 leap day), can't be more than 24
// (because multiples of 25*4=100 years (incl. leap days) have been removed)
quadrennials = (u16)(sec / 126230400); // 4*(365+1/4)*24*3600
if (quadrennials > 24)
{
quadrennials = 24;
}
sec -= quadrennials * 126230400ULL;
// Remove multiples of years (incl. 0 leap days), can't be more than 3
// (because multiples of 4 years (incl. leap days) have been removed)
annuals = (u16)(sec / 31536000); // 365*24*3600
if (annuals > 3)
{
annuals = 3;
}
sec -= annuals * 31536000ULL;
// Calculate the year and find out if it's leap
year = 1 + quadricentennials * 400 + centennials * 100 + quadrennials * 4 + annuals;
leap = !(year % 4) && (year % 100 || !(year % 400));
// Calculate the day of the year and the time
yday = sec / 86400;
sec %= 86400;
hour = sec / 3600;
sec %= 3600;
min = sec / 60;
sec %= 60;
// Calculate the month
for (mday = month = 1; month < 13; month++)
{
if (yday < daysSinceJan1st[leap][month])
{
mday += yday - daysSinceJan1st[leap][month - 1];
break;
}
}
t.year = year;
t.month = month;
t.day = mday;
t.hour = hour;
t.minute = min;
t.second = sec;
t.microsecond = ticks % 1000000;
}
bool __RtcValidatePspTime(ScePspDateTime &t)
{
return t.year > 0;
@ -140,13 +220,13 @@ u32 sceRtcGetCurrentClockLocalTime(u32 pspTimePtr)
u32 sceRtcSetTick(u32 pspTimePtr, u32 tickPtr)
{
DEBUG_LOG(HLE, "HACK sceRtcSetTick(%08x, %08x)", pspTimePtr, tickPtr);
DEBUG_LOG(HLE, "sceRtcSetTick(%08x, %08x)", pspTimePtr, tickPtr);
if (Memory::IsValidAddress(pspTimePtr) && Memory::IsValidAddress(tickPtr))
{
time_t sec = (time_t)Memory::Read_U64(tickPtr);
tm *local = localtime(&sec);
u64 ticks = Memory::Read_U64(tickPtr);
ScePspDateTime ret;
__RtcTmToPspTime(ret, local);
__RtcTicksToPspTime(ret, ticks);
Memory::WriteStruct(pspTimePtr, &ret);
}
return 0;
@ -273,4 +353,3 @@ void Register_sceRtc()
{
RegisterModule("sceRtc", ARRAY_SIZE(sceRtc), sceRtc);
}

File diff suppressed because it is too large Load diff