#include "stdafx.h" #include "Emu/SysCalls/SysCalls.h" #include "Emu/SysCalls/SC_FUNC.h" void cellRtc_init(); Module cellRtc(0x0009, cellRtc_init); // Return Codes enum { CELL_RTC_ERROR_NOT_INITIALIZED = 0x80010601, CELL_RTC_ERROR_INVALID_POINTER = 0x80010602, CELL_RTC_ERROR_INVALID_VALUE = 0x80010603, CELL_RTC_ERROR_INVALID_ARG = 0x80010604, CELL_RTC_ERROR_NOT_SUPPORTED = 0x80010605, CELL_RTC_ERROR_NO_CLOCK = 0x80010606, CELL_RTC_ERROR_BAD_PARSE = 0x80010607, CELL_RTC_ERROR_INVALID_YEAR = 0x80010621, CELL_RTC_ERROR_INVALID_MONTH = 0x80010622, CELL_RTC_ERROR_INVALID_DAY = 0x80010623, CELL_RTC_ERROR_INVALID_HOUR = 0x80010624, CELL_RTC_ERROR_INVALID_MINUTE = 0x80010625, CELL_RTC_ERROR_INVALID_SECOND = 0x80010626, CELL_RTC_ERROR_INVALID_MICROSECOND = 0x80010627, }; struct CellRtcTick { u64 tick; }; struct CellRtcDateTime { u16 year; u16 month; u16 day; u16 hour; u16 minute; u16 second; u32 microsecond; }; long convertToUNIXTime(u16 seconds, u16 minutes, u16 hours, u16 days, int years) { return (seconds + minutes*60 + hours*3600 + days*86400 + (years-70)*31536000 + ((years-69)/4)*86400 - ((years-1)/100)*86400 + ((years+299)/400)*86400); } u64 convertToWin32FILETIME(u16 seconds, u16 minutes, u16 hours, u16 days, int years) { long unixtime = convertToUNIXTime(seconds, minutes, hours, days, years); LONGLONG win32time = Int32x32To64(unixtime, 10000000) + 116444736000000000; u64 win32filetime = (u64) win32time | win32time >> 32; return win32filetime; } int cellRtcGetCurrentTick(mem64_t tick) { cellRtc.Log("cellRtcGetCurrentTick(tick_addr=0x%x)", tick.GetAddr()); CellRtcTick *current_tick = new CellRtcTick; wxDateTime unow = wxDateTime::UNow(); current_tick->tick = unow.GetTicks(); tick = current_tick->tick; return CELL_OK; } int cellRtcGetCurrentClock(u32 clock_addr, int time_zone) { cellRtc.Log("cellRtcGetCurrentClock(clock_addr=0x%x, time_zone=%d)", clock_addr, time_zone); CellRtcDateTime *current_clock = new CellRtcDateTime; wxDateTime unow = wxDateTime::UNow(); // Add time_zone as offset in minutes. wxTimeSpan tz = wxTimeSpan::wxTimeSpan(0, (long) time_zone, 0, 0); unow.Add(tz); current_clock->year = unow.GetYear(wxDateTime::TZ::UTC); current_clock->month = unow.GetMonth(wxDateTime::TZ::UTC); current_clock->day = unow.GetDay(wxDateTime::TZ::UTC); current_clock->hour = unow.GetHour(wxDateTime::TZ::UTC); current_clock->minute = unow.GetMinute(wxDateTime::TZ::UTC); current_clock->second = unow.GetSecond(wxDateTime::TZ::UTC); current_clock->microsecond = unow.GetMillisecond(wxDateTime::TZ::UTC) * 1000; Memory.Write16(clock_addr, current_clock->year); Memory.Write16(clock_addr + 2, current_clock->month); Memory.Write16(clock_addr + 4, current_clock->day); Memory.Write16(clock_addr + 6, current_clock->hour); Memory.Write16(clock_addr + 8, current_clock->minute); Memory.Write16(clock_addr + 10, current_clock->second); Memory.Write32(clock_addr + 12, current_clock->microsecond); return CELL_OK; } int cellRtcGetCurrentClockLocalTime(u32 clock_addr) { cellRtc.Log("cellRtcGetCurrentClockLocalTime(clock_addr=0x%x)", clock_addr); CellRtcDateTime *current_clock = new CellRtcDateTime; wxDateTime unow = wxDateTime::UNow(); current_clock->year = unow.GetYear(wxDateTime::TZ::Local); current_clock->month = unow.GetMonth(wxDateTime::TZ::Local); current_clock->day = unow.GetDay(wxDateTime::TZ::Local); current_clock->hour = unow.GetHour(wxDateTime::TZ::Local); current_clock->minute = unow.GetMinute(wxDateTime::TZ::Local); current_clock->second = unow.GetSecond(wxDateTime::TZ::Local); current_clock->microsecond = unow.GetMillisecond(wxDateTime::TZ::Local) * 1000; Memory.Write16(clock_addr, current_clock->year); Memory.Write16(clock_addr + 2, current_clock->month); Memory.Write16(clock_addr + 4, current_clock->day); Memory.Write16(clock_addr + 6, current_clock->hour); Memory.Write16(clock_addr + 8, current_clock->minute); Memory.Write16(clock_addr + 10, current_clock->second); Memory.Write32(clock_addr + 12, current_clock->microsecond); return CELL_OK; } int cellRtcFormatRfc2822(u32 rfc_addr, u32 tick_addr, int time_zone) { cellRtc.Log("cellRtcFormatRfc2822(rfc_addr=0x%x, tick_addr=0x%x, time_zone=%d)", rfc_addr, tick_addr, time_zone); CellRtcTick *current_tick = new CellRtcTick; current_tick->tick = Memory.Read64(tick_addr); // Add time_zone as offset in minutes. wxTimeSpan tz = wxTimeSpan::wxTimeSpan(0, (long) time_zone, 0, 0); // Get date from ticks + tz. wxDateTime date = wxDateTime::wxDateTime((time_t)current_tick->tick); date.Add(tz); // Format date string in RFC2822 format (e.g.: Mon, 01 Jan 1990 12:00:00 +0000). const wxString& str = date.Format("%a, %d %b %Y %T %z", wxDateTime::TZ::UTC); Memory.WriteString(rfc_addr, str); return CELL_OK; } int cellRtcFormatRfc2822LocalTime(u32 rfc_addr, u32 tick_addr) { cellRtc.Log("cellRtcFormatRfc2822LocalTime(rfc_addr=0x%x, tick_addr=0x%x)", rfc_addr, tick_addr); CellRtcTick *current_tick = new CellRtcTick; current_tick->tick = Memory.Read64(tick_addr); // Get date from ticks. wxDateTime date = wxDateTime::wxDateTime((time_t)current_tick->tick); // Format date string in RFC2822 format (e.g.: Mon, 01 Jan 1990 12:00:00 +0000). const wxString& str = date.Format("%a, %d %b %Y %T %z", wxDateTime::TZ::Local); Memory.WriteString(rfc_addr, str); return CELL_OK; } int cellRtcFormatRfc3339(u32 rfc_addr, u32 tick_addr, int time_zone) { cellRtc.Log("cellRtcFormatRfc3339(rfc_addr=0x%x, tick_addr=0x%x, time_zone=%d)", rfc_addr, tick_addr, time_zone); CellRtcTick *current_tick = new CellRtcTick; current_tick->tick = Memory.Read64(tick_addr); // Add time_zone as offset in minutes. wxTimeSpan tz = wxTimeSpan::wxTimeSpan(0, (long) time_zone, 0, 0); // Get date from ticks + tz. wxDateTime date = wxDateTime::wxDateTime((time_t)current_tick->tick); date.Add(tz); // Format date string in RFC3339 format (e.g.: 1990-01-01T12:00:00.00Z). const wxString& str = date.Format("%FT%T.%zZ", wxDateTime::TZ::UTC); Memory.WriteString(rfc_addr, str); return CELL_OK; } int cellRtcFormatRfc3339LocalTime(u32 rfc_addr, u32 tick_addr) { cellRtc.Log("cellRtcFormatRfc3339LocalTime(rfc_addr=0x%x, tick_addr=0x%x)", rfc_addr, tick_addr); CellRtcTick *current_tick = new CellRtcTick; current_tick->tick = Memory.Read64(tick_addr); // Get date from ticks. wxDateTime date = wxDateTime::wxDateTime((time_t)current_tick->tick); // Format date string in RFC3339 format (e.g.: 1990-01-01T12:00:00.00Z). const wxString& str = date.Format("%FT%T.%zZ", wxDateTime::TZ::Local); Memory.WriteString(rfc_addr, str); return CELL_OK; } int cellRtcParseDateTime(mem64_t tick, u32 datetime_addr) { cellRtc.Log("cellRtcParseDateTime(tick_addr=0x%x, datetime_addr=0x%x)", tick.GetAddr(), datetime_addr); const wxString& format = Memory.ReadString(datetime_addr); // Get date from formatted string. wxDateTime date; date.ParseDateTime(format); tick = date.GetTicks(); return CELL_OK; } int cellRtcParseRfc3339(mem64_t tick, u32 datetime_addr) { cellRtc.Log("cellRtcParseRfc3339(tick_addr=0x%x, datetime_addr=0x%x)", tick.GetAddr(), datetime_addr); const wxString& format = Memory.ReadString(datetime_addr); // Get date from RFC3339 formatted string. wxDateTime date; date.ParseDateTime(format); tick = date.GetTicks(); return CELL_OK; } int cellRtcGetTick(u32 clock_addr, mem64_t tick) { cellRtc.Log("cellRtcGetTick(clock_addr=0x%x, tick_addr=0x%x)", clock_addr, tick.GetAddr()); CellRtcDateTime *clock = new CellRtcDateTime; clock->year = Memory.Read16(clock_addr); clock->month = Memory.Read16(clock_addr + 2); clock->day = Memory.Read16(clock_addr + 4); clock->hour = Memory.Read16(clock_addr + 6); clock->minute = Memory.Read16(clock_addr + 8); clock->second = Memory.Read16(clock_addr + 10); clock->microsecond = Memory.Read32(clock_addr + 12); wxDateTime datetime = wxDateTime::wxDateTime(clock->day, (wxDateTime::Month)clock->month, clock->year, clock->hour, clock->minute, clock->second, (clock->microsecond / 1000)); tick = datetime.GetTicks(); return CELL_OK; } int cellRtcSetTick(u32 clock_addr, u32 tick_addr) { cellRtc.Log("cellRtcSetTick(clock_addr=0x%x, tick_addr=0x%x)", clock_addr, tick_addr); CellRtcTick *current_tick = new CellRtcTick; current_tick->tick = Memory.Read64(tick_addr); wxDateTime date = wxDateTime::wxDateTime((time_t)current_tick->tick); CellRtcDateTime *clock = new CellRtcDateTime; clock->year = date.GetYear(wxDateTime::TZ::UTC); clock->month = date.GetMonth(wxDateTime::TZ::UTC); clock->day = date.GetDay(wxDateTime::TZ::UTC); clock->hour = date.GetHour(wxDateTime::TZ::UTC); clock->minute = date.GetMinute(wxDateTime::TZ::UTC); clock->second = date.GetSecond(wxDateTime::TZ::UTC); clock->microsecond = date.GetMillisecond(wxDateTime::TZ::UTC) * 1000; Memory.Write16(clock_addr, clock->year); Memory.Write16(clock_addr + 2, clock->month); Memory.Write16(clock_addr + 4, clock->day); Memory.Write16(clock_addr + 6, clock->hour); Memory.Write16(clock_addr + 8, clock->minute); Memory.Write16(clock_addr + 10, clock->second); Memory.Write32(clock_addr + 12, clock->microsecond); return CELL_OK; } int cellRtcTickAddTicks(mem64_t tick, u32 tick_add_addr, long add) { cellRtc.Log("cellRtcTickAddTicks(tick_addr=0x%x, tick_add_addr=0x%x, add=%l)", tick.GetAddr(), tick_add_addr, add); tick = Memory.Read64(tick_add_addr) + add; return CELL_OK; } int cellRtcTickAddMicroseconds(mem64_t tick, u32 tick_add_addr, long add) { cellRtc.Log("cellRtcTickAddMicroseconds(tick_addr=0x%x, tick_add_addr=0x%x, add=%l)", tick.GetAddr(), tick_add_addr, add); wxDateTime date = wxDateTime::wxDateTime((time_t)Memory.Read64(tick_add_addr)); wxTimeSpan microseconds = wxTimeSpan::wxTimeSpan(0, 0, 0, add / 1000); date.Add(microseconds); tick = date.GetTicks(); return CELL_OK; } int cellRtcTickAddSeconds(mem64_t tick, u32 tick_add_addr, long add) { cellRtc.Log("cellRtcTickAddSeconds(tick_addr=0x%x, tick_add_addr=0x%x, add=%l)", tick.GetAddr(), tick_add_addr, add); wxDateTime date = wxDateTime::wxDateTime((time_t)Memory.Read64(tick_add_addr)); wxTimeSpan seconds = wxTimeSpan::wxTimeSpan(0, 0, add, 0); date.Add(seconds); tick = date.GetTicks(); return CELL_OK; } int cellRtcTickAddMinutes(mem64_t tick, u32 tick_add_addr, long add) { cellRtc.Log("cellRtcTickAddMinutes(tick_addr=0x%x, tick_add_addr=0x%x, add=%l)", tick.GetAddr(), tick_add_addr, add); wxDateTime date = wxDateTime::wxDateTime((time_t)Memory.Read64(tick_add_addr)); wxTimeSpan minutes = wxTimeSpan::wxTimeSpan(0, add, 0, 0); date.Add(minutes); tick = date.GetTicks(); return CELL_OK; } int cellRtcTickAddHours(mem64_t tick, u32 tick_add_addr, int add) { cellRtc.Log("cellRtcTickAddHours(tick_addr=0x%x, tick_add_addr=0x%x, add=%l)", tick.GetAddr(), tick_add_addr, add); wxDateTime date = wxDateTime::wxDateTime((time_t)Memory.Read64(tick_add_addr)); wxTimeSpan hours = wxTimeSpan::wxTimeSpan(add, 0, 0, 0); date.Add(hours); tick = date.GetTicks(); return CELL_OK; } int cellRtcTickAddDays(mem64_t tick, u32 tick_add_addr, int add) { cellRtc.Log("cellRtcTickAddDays(tick_addr=0x%x, tick_add_addr=0x%x, add=%l)", tick.GetAddr(), tick_add_addr, add); wxDateTime date = wxDateTime::wxDateTime((time_t)Memory.Read64(tick_add_addr)); wxDateSpan days = wxDateSpan::wxDateSpan(0, 0, 0, add); date.Add(days); tick = date.GetTicks(); return CELL_OK; } int cellRtcTickAddWeeks(mem64_t tick, u32 tick_add_addr, int add) { cellRtc.Log("cellRtcTickAddWeeks(tick_addr=0x%x, tick_add_addr=0x%x, add=%l)", tick.GetAddr(), tick_add_addr, add); wxDateTime date = wxDateTime::wxDateTime((time_t)Memory.Read64(tick_add_addr)); wxDateSpan weeks = wxDateSpan::wxDateSpan(0, 0, add, 0); date.Add(weeks); tick = date.GetTicks(); return CELL_OK; } int cellRtcTickAddMonths(mem64_t tick, u32 tick_add_addr, int add) { cellRtc.Log("cellRtcTickAddMonths(tick_addr=0x%x, tick_add_addr=0x%x, add=%l)", tick.GetAddr(), tick_add_addr, add); wxDateTime date = wxDateTime::wxDateTime((time_t)Memory.Read64(tick_add_addr)); wxDateSpan months = wxDateSpan::wxDateSpan(0, add, 0, 0); date.Add(months); tick = date.GetTicks(); return CELL_OK; } int cellRtcTickAddYears(mem64_t tick, u32 tick_add_addr, int add) { cellRtc.Log("cellRtcTickAddYears(tick_addr=0x%x, tick_add_addr=0x%x, add=%l)", tick.GetAddr(), tick_add_addr, add); wxDateTime date = wxDateTime::wxDateTime((time_t)Memory.Read64(tick_add_addr)); wxDateSpan years = wxDateSpan::wxDateSpan(add, 0, 0, 0); date.Add(years); tick = date.GetTicks(); return CELL_OK; } int cellRtcConvertUtcToLocalTime(u32 tick_utc_addr, mem64_t tick_local) { cellRtc.Log("cellRtcConvertUtcToLocalTime(tick_utc_addr=0x%x, tick_local_addr=0x%x)", tick_utc_addr, tick_local.GetAddr()); wxDateTime time = wxDateTime::wxDateTime((time_t)Memory.Read64(tick_utc_addr)); wxDateTime local_time = time.FromUTC(false); tick_local = local_time.GetTicks(); return CELL_OK; } int cellRtcConvertLocalTimeToUtc(u32 tick_local_addr, mem64_t tick_utc) { cellRtc.Log("cellRtcConvertLocalTimeToUtc(tick_local_addr=0x%x, tick_utc_addr=0x%x)", tick_local_addr, tick_utc.GetAddr()); wxDateTime time = wxDateTime::wxDateTime((time_t)Memory.Read64(tick_local_addr)); wxDateTime utc_time = time.ToUTC(false); tick_utc = utc_time.GetTicks(); return CELL_OK; } int cellRtcGetDosTime(u32 datetime_addr, mem64_t dos_time) { cellRtc.Log("cellRtcGetDosTime(datetime_addr=0x%x, dos_time_addr=0x%x)", datetime_addr, dos_time.GetAddr()); CellRtcDateTime *datetime = new CellRtcDateTime; datetime->year = Memory.Read16(datetime_addr); datetime->month = Memory.Read16(datetime_addr + 2); datetime->day = Memory.Read16(datetime_addr + 4); datetime->hour = Memory.Read16(datetime_addr + 6); datetime->minute = Memory.Read16(datetime_addr + 8); datetime->second = Memory.Read16(datetime_addr + 10); datetime->microsecond = Memory.Read32(datetime_addr + 12); // Convert to DOS time. wxDateTime date_time = wxDateTime::wxDateTime(datetime->day, (wxDateTime::Month)datetime->month, datetime->year, datetime->hour, datetime->minute, datetime->second, (datetime->microsecond / 1000)); dos_time = date_time.GetAsDOS(); return CELL_OK; } int cellRtcGetTime_t(u32 datetime_addr, mem64_t posix_time) { cellRtc.Log("cellRtcGetTime_t(datetime_addr=0x%x, posix_time_addr=0x%x)", datetime_addr, posix_time.GetAddr()); CellRtcDateTime *datetime = new CellRtcDateTime; datetime->year = Memory.Read16(datetime_addr); datetime->month = Memory.Read16(datetime_addr + 2); datetime->day = Memory.Read16(datetime_addr + 4); datetime->hour = Memory.Read16(datetime_addr + 6); datetime->minute = Memory.Read16(datetime_addr + 8); datetime->second = Memory.Read16(datetime_addr + 10); datetime->microsecond = Memory.Read32(datetime_addr + 12); // Convert to POSIX time_t. wxDateTime date_time = wxDateTime::wxDateTime(datetime->day, (wxDateTime::Month)datetime->month, datetime->year, datetime->hour, datetime->minute, datetime->second, (datetime->microsecond / 1000)); posix_time = convertToUNIXTime(date_time.GetSecond(wxDateTime::TZ::UTC), date_time.GetMinute(wxDateTime::TZ::UTC), date_time.GetHour(wxDateTime::TZ::UTC), date_time.GetDay(wxDateTime::TZ::UTC), date_time.GetYear(wxDateTime::TZ::UTC)); return CELL_OK; } int cellRtcGetWin32FileTime(u32 datetime_addr, mem64_t win32_time) { cellRtc.Log("cellRtcGetWin32FileTime(datetime_addr=0x%x, win32_time_addr=0x%x)", datetime_addr, win32_time.GetAddr()); CellRtcDateTime *datetime = new CellRtcDateTime; datetime->year = Memory.Read16(datetime_addr); datetime->month = Memory.Read16(datetime_addr + 2); datetime->day = Memory.Read16(datetime_addr + 4); datetime->hour = Memory.Read16(datetime_addr + 6); datetime->minute = Memory.Read16(datetime_addr + 8); datetime->second = Memory.Read16(datetime_addr + 10); datetime->microsecond = Memory.Read32(datetime_addr + 12); // Convert to WIN32 FILETIME. wxDateTime date_time = wxDateTime::wxDateTime(datetime->day, (wxDateTime::Month)datetime->month, datetime->year, datetime->hour, datetime->minute, datetime->second, (datetime->microsecond / 1000)); win32_time = convertToWin32FILETIME(date_time.GetSecond(wxDateTime::TZ::UTC), date_time.GetMinute(wxDateTime::TZ::UTC), date_time.GetHour(wxDateTime::TZ::UTC), date_time.GetDay(wxDateTime::TZ::UTC), date_time.GetYear(wxDateTime::TZ::UTC)); return CELL_OK; } int cellRtcSetDosTime(u32 datetime_addr, u32 dos_time_addr) { cellRtc.Log("cellRtcSetDosTime(datetime_addr=0x%x, dos_time_addr=0x%x)", datetime_addr, dos_time_addr); wxDateTime date_time; wxDateTime dos_time = date_time.SetFromDOS(Memory.Read32(dos_time_addr)); CellRtcDateTime *datetime = new CellRtcDateTime; datetime->year = dos_time.GetYear(wxDateTime::TZ::UTC); datetime->month = dos_time.GetMonth(wxDateTime::TZ::UTC); datetime->day = dos_time.GetDay(wxDateTime::TZ::UTC); datetime->hour = dos_time.GetHour(wxDateTime::TZ::UTC); datetime->minute = dos_time.GetMinute(wxDateTime::TZ::UTC); datetime->second = dos_time.GetSecond(wxDateTime::TZ::UTC); datetime->microsecond = dos_time.GetMillisecond(wxDateTime::TZ::UTC) * 1000; Memory.Write16(datetime_addr, datetime->year); Memory.Write16(datetime_addr + 2, datetime->month); Memory.Write16(datetime_addr + 4, datetime->day); Memory.Write16(datetime_addr + 6, datetime->hour); Memory.Write16(datetime_addr + 8, datetime->minute); Memory.Write16(datetime_addr + 10, datetime->second); Memory.Write32(datetime_addr + 12, datetime->microsecond); return CELL_OK; } int cellRtcSetTime_t(u32 datetime_addr, u32 posix_time_addr) { cellRtc.Log("cellRtcSetTime_t(datetime_addr=0x%x, posix_time_addr=0x%x)", datetime_addr, posix_time_addr); wxDateTime date_time = wxDateTime::wxDateTime((time_t)Memory.Read64(posix_time_addr)); CellRtcDateTime *datetime = new CellRtcDateTime; datetime->year = date_time.GetYear(wxDateTime::TZ::UTC); datetime->month = date_time.GetMonth(wxDateTime::TZ::UTC); datetime->day = date_time.GetDay(wxDateTime::TZ::UTC); datetime->hour = date_time.GetHour(wxDateTime::TZ::UTC); datetime->minute = date_time.GetMinute(wxDateTime::TZ::UTC); datetime->second = date_time.GetSecond(wxDateTime::TZ::UTC); datetime->microsecond = date_time.GetMillisecond(wxDateTime::TZ::UTC) * 1000; Memory.Write16(datetime_addr, datetime->year); Memory.Write16(datetime_addr + 2, datetime->month); Memory.Write16(datetime_addr + 4, datetime->day); Memory.Write16(datetime_addr + 6, datetime->hour); Memory.Write16(datetime_addr + 8, datetime->minute); Memory.Write16(datetime_addr + 10, datetime->second); Memory.Write32(datetime_addr + 12, datetime->microsecond); return CELL_OK; } int cellRtcSetWin32FileTime(u32 datetime_addr, u32 win32_time_addr) { cellRtc.Log("cellRtcSetWin32FileTime(datetime_addr=0x%x, win32_time_addr=0x%x)", datetime_addr, win32_time_addr); wxDateTime date_time = wxDateTime::wxDateTime((time_t)Memory.Read64(win32_time_addr)); CellRtcDateTime *datetime = new CellRtcDateTime; datetime->year = date_time.GetYear(wxDateTime::TZ::UTC); datetime->month = date_time.GetMonth(wxDateTime::TZ::UTC); datetime->day = date_time.GetDay(wxDateTime::TZ::UTC); datetime->hour = date_time.GetHour(wxDateTime::TZ::UTC); datetime->minute = date_time.GetMinute(wxDateTime::TZ::UTC); datetime->second = date_time.GetSecond(wxDateTime::TZ::UTC); datetime->microsecond = date_time.GetMillisecond(wxDateTime::TZ::UTC) * 1000; Memory.Write16(datetime_addr, datetime->year); Memory.Write16(datetime_addr + 2, datetime->month); Memory.Write16(datetime_addr + 4, datetime->day); Memory.Write16(datetime_addr + 6, datetime->hour); Memory.Write16(datetime_addr + 8, datetime->minute); Memory.Write16(datetime_addr + 10, datetime->second); Memory.Write32(datetime_addr + 12, datetime->microsecond); return CELL_OK; } int cellRtcIsLeapYear(int year) { cellRtc.Log("cellRtcIsLeapYear(year=%d)", year); wxDateTime datetime; return datetime.IsLeapYear(year, wxDateTime::Gregorian); } int cellRtcGetDaysInMonth(int year, int month) { cellRtc.Log("cellRtcGetDaysInMonth(year=%d, month=%d)", year, month); wxDateTime datetime; return datetime.GetNumberOfDays((wxDateTime::Month) month, year, wxDateTime::Gregorian); } int cellRtcGetDayOfWeek(int year, int month, int day) { cellRtc.Log("cellRtcGetDayOfWeek(year=%d, month=%d, day=%d)", year, month, day); wxDateTime datetime; datetime.SetToWeekDay((wxDateTime::WeekDay) day, 1, (wxDateTime::Month) month, year); return datetime.GetWeekDay(); } int cellRtcCheckValid(u32 datetime_addr) { cellRtc.Log("cellRtcCheckValid(datetime_addr=0x%x)", datetime_addr); CellRtcDateTime *datetime = new CellRtcDateTime; datetime->year = Memory.Read16(datetime_addr); datetime->month = Memory.Read16(datetime_addr + 2); datetime->day = Memory.Read16(datetime_addr + 4); datetime->hour = Memory.Read16(datetime_addr + 6); datetime->minute = Memory.Read16(datetime_addr + 8); datetime->second = Memory.Read16(datetime_addr + 10); datetime->microsecond = Memory.Read32(datetime_addr + 12); if((datetime->year < 1) || (datetime->year > 9999)) return CELL_RTC_ERROR_INVALID_YEAR; else if((datetime->month < 1) || (datetime->month > 12)) return CELL_RTC_ERROR_INVALID_MONTH; else if((datetime->day < 1) || (datetime->day > 31)) return CELL_RTC_ERROR_INVALID_DAY; else if((datetime->hour < 0) || (datetime->hour > 23)) return CELL_RTC_ERROR_INVALID_HOUR; else if((datetime->minute < 0) || (datetime->minute > 59)) return CELL_RTC_ERROR_INVALID_MINUTE; else if((datetime->second < 0) || (datetime->second > 59)) return CELL_RTC_ERROR_INVALID_SECOND; else if((datetime->microsecond < 0) || (datetime->microsecond > 999999)) return CELL_RTC_ERROR_INVALID_MICROSECOND; else return CELL_OK; } int cellRtcCompareTick(u32 tick_addr_1, u32 tick_addr_2) { cellRtc.Log("cellRtcCompareTick(tick_addr_1=0x%x, tick_addr_2=0x%x)", tick_addr_1, tick_addr_2); long tick1 = Memory.Read64(tick_addr_1); long tick2 = Memory.Read64(tick_addr_2); if(tick1 < tick2) return -1; else if(tick1 > tick2) return 1; else return CELL_OK; } void cellRtc_init() { cellRtc.AddFunc(0x9dafc0d9, cellRtcGetCurrentTick); cellRtc.AddFunc(0x32c941cf, cellRtcGetCurrentClock); cellRtc.AddFunc(0x2cce9cf5, cellRtcGetCurrentClockLocalTime); cellRtc.AddFunc(0x5491b9d5, cellRtcFormatRfc2822); cellRtc.AddFunc(0xa07c3d2f, cellRtcFormatRfc2822LocalTime); cellRtc.AddFunc(0xd9c0b463, cellRtcFormatRfc3339); cellRtc.AddFunc(0x1324948a, cellRtcFormatRfc3339LocalTime); cellRtc.AddFunc(0xc5bc0fac, cellRtcParseDateTime); cellRtc.AddFunc(0xcf11c3d6, cellRtcParseRfc3339); cellRtc.AddFunc(0xc7bdb7eb, cellRtcGetTick); cellRtc.AddFunc(0x99b13034, cellRtcSetTick); cellRtc.AddFunc(0x269a1882, cellRtcTickAddTicks); cellRtc.AddFunc(0xf8509925, cellRtcTickAddMicroseconds); cellRtc.AddFunc(0xccce71bd, cellRtcTickAddSeconds); cellRtc.AddFunc(0x2f010bfa, cellRtcTickAddMinutes); cellRtc.AddFunc(0xd41d3bd2, cellRtcTickAddHours); cellRtc.AddFunc(0x75744e2a, cellRtcTickAddDays); cellRtc.AddFunc(0x64c63fd5, cellRtcTickAddWeeks); cellRtc.AddFunc(0xe0ecbb45, cellRtcTickAddMonths); cellRtc.AddFunc(0x332a74dd, cellRtcTickAddYears); cellRtc.AddFunc(0xc48d5002, cellRtcConvertUtcToLocalTime); cellRtc.AddFunc(0x46ca7fe0, cellRtcConvertLocalTimeToUtc); // (TODO: Time Information Manipulation Functions missing) cellRtc.AddFunc(0xdfff32cf, cellRtcGetDosTime); cellRtc.AddFunc(0xcb90c761, cellRtcGetTime_t); cellRtc.AddFunc(0xe7086f05, cellRtcGetWin32FileTime); cellRtc.AddFunc(0x9598d4b3, cellRtcSetDosTime); cellRtc.AddFunc(0xbb543189, cellRtcSetTime_t); cellRtc.AddFunc(0x5f68c268, cellRtcSetWin32FileTime); cellRtc.AddFunc(0x5316b4a8, cellRtcIsLeapYear); cellRtc.AddFunc(0x5b6a0a1d, cellRtcGetDaysInMonth); cellRtc.AddFunc(0xc2d8cf95, cellRtcGetDayOfWeek); cellRtc.AddFunc(0x7f1086e6, cellRtcCheckValid); cellRtc.AddFunc(0xfb51fc61, cellRtcCompareTick); }