From 9187913c4285276e94439f901d6b0ca7c38a4712 Mon Sep 17 00:00:00 2001 From: CrazyBloo Date: Mon, 2 Sep 2024 07:37:20 -0400 Subject: [PATCH 1/2] various formatting improvements and fixes --- src/core/libraries/rtc/rtc.cpp | 122 ++++++++++++++++++++------------- src/core/libraries/rtc/rtc.h | 43 +++++++----- 2 files changed, 100 insertions(+), 65 deletions(-) diff --git a/src/core/libraries/rtc/rtc.cpp b/src/core/libraries/rtc/rtc.cpp index a567a787a..51e66a466 100644 --- a/src/core/libraries/rtc/rtc.cpp +++ b/src/core/libraries/rtc/rtc.cpp @@ -49,7 +49,7 @@ int PS4_SYSV_ABI sceRtcCheckValid(OrbisRtcDateTime* pTime) { if (pTime->microsecond >= 1000000) return ORBIS_RTC_ERROR_INVALID_MICROSECOND; - return 0; + return SCE_OK; } int PS4_SYSV_ABI sceRtcCompareTick(OrbisRtcTick* pTick1, OrbisRtcTick* pTick2) { @@ -121,7 +121,7 @@ int PS4_SYSV_ABI sceRtcConvertUtcToLocalTime(OrbisRtcTick* pTickUtc, OrbisRtcTic } int PS4_SYSV_ABI sceRtcEnd() { - return 0; + return SCE_OK; } int PS4_SYSV_ABI sceRtcFormatRFC2822(char* pszDateTime, const OrbisRtcTick* pTickUtc, int minutes) { @@ -163,7 +163,7 @@ int PS4_SYSV_ABI sceRtcGetCurrentAdNetworkTick(OrbisRtcTick* pTick) { return ORBIS_RTC_ERROR_INVALID_POINTER; Kernel::OrbisKernelTimespec clocktime; - int returnValue = Kernel::sceKernelClockGettime(Kernel::ORBIS_CLOCK_EXT_NETWORK, &clocktime); + int returnValue = Kernel::sceKernelClockGettime(Kernel::ORBIS_CLOCK_REALTIME, &clocktime); if (returnValue == 0) { pTick->tick = clocktime.tv_nsec / 1000 + clocktime.tv_sec * 1000000 + 0xdcbffeff2bc000; @@ -171,7 +171,7 @@ int PS4_SYSV_ABI sceRtcGetCurrentAdNetworkTick(OrbisRtcTick* pTick) { return ORBIS_RTC_ERROR_NOT_INITIALIZED; } - return 0; + return SCE_OK; } int PS4_SYSV_ABI sceRtcGetCurrentClock(OrbisRtcDateTime* pTime, int timeZone) { @@ -230,7 +230,7 @@ int PS4_SYSV_ABI sceRtcGetCurrentDebugNetworkTick(OrbisRtcTick* pTick) { return ORBIS_RTC_ERROR_INVALID_POINTER; Kernel::OrbisKernelTimespec clocktime; - int returnValue = Kernel::sceKernelClockGettime(Kernel::ORBIS_CLOCK_EXT_NETWORK, &clocktime); + int returnValue = Kernel::sceKernelClockGettime(Kernel::ORBIS_CLOCK_REALTIME, &clocktime); if (returnValue == 0) { pTick->tick = clocktime.tv_nsec / 1000 + clocktime.tv_sec * 1000000 + 0xdcbffeff2bc000; @@ -238,7 +238,7 @@ int PS4_SYSV_ABI sceRtcGetCurrentDebugNetworkTick(OrbisRtcTick* pTick) { return ORBIS_RTC_ERROR_NOT_INITIALIZED; } - return 0; + return SCE_OK; } int PS4_SYSV_ABI sceRtcGetCurrentNetworkTick(OrbisRtcTick* pTick) { @@ -248,7 +248,7 @@ int PS4_SYSV_ABI sceRtcGetCurrentNetworkTick(OrbisRtcTick* pTick) { return ORBIS_RTC_ERROR_INVALID_POINTER; Kernel::OrbisKernelTimespec clocktime; - int returnValue = Kernel::sceKernelClockGettime(Kernel::ORBIS_CLOCK_EXT_NETWORK, &clocktime); + int returnValue = Kernel::sceKernelClockGettime(Kernel::ORBIS_CLOCK_REALTIME, &clocktime); if (returnValue == 0) { pTick->tick = clocktime.tv_nsec / 1000 + clocktime.tv_sec * 1000000 + 0xdcbffeff2bc000; @@ -256,7 +256,7 @@ int PS4_SYSV_ABI sceRtcGetCurrentNetworkTick(OrbisRtcTick* pTick) { return ORBIS_RTC_ERROR_NOT_INITIALIZED; } - return 0; + return SCE_OK; } int PS4_SYSV_ABI sceRtcGetCurrentRawNetworkTick(OrbisRtcTick* pTick) { @@ -266,8 +266,7 @@ int PS4_SYSV_ABI sceRtcGetCurrentRawNetworkTick(OrbisRtcTick* pTick) { return ORBIS_RTC_ERROR_INVALID_POINTER; Kernel::OrbisKernelTimespec clocktime; - int returnValue = - Kernel::sceKernelClockGettime(Kernel::ORBIS_CLOCK_EXT_RAW_NETWORK, &clocktime); + int returnValue = Kernel::sceKernelClockGettime(Kernel::ORBIS_CLOCK_REALTIME, &clocktime); if (returnValue == 0) { pTick->tick = clocktime.tv_nsec / 1000 + clocktime.tv_sec * 1000000 + 0xdcbffeff2bc000; @@ -275,7 +274,7 @@ int PS4_SYSV_ABI sceRtcGetCurrentRawNetworkTick(OrbisRtcTick* pTick) { return ORBIS_RTC_ERROR_NOT_INITIALIZED; } - return 0; + return SCE_OK; } int PS4_SYSV_ABI sceRtcGetCurrentTick(OrbisRtcTick* pTick) { @@ -291,29 +290,55 @@ int PS4_SYSV_ABI sceRtcGetCurrentTick(OrbisRtcTick* pTick) { pTick->tick = clocktime.tv_nsec / 1000 + clocktime.tv_sec * 1000000 + 0xdcbffeff2bc000; } - return returnValue; + return SCE_OK; } int PS4_SYSV_ABI sceRtcGetDayOfWeek(int year, int month, int day) { - LOG_ERROR(Lib_Rtc, "(STUBBED) called"); + LOG_TRACE(Lib_Rtc, "called"); + + int sdk_version = 0; + int sdkResult = Kernel::sceKernelGetCompiledSdkVersion(&sdk_version); + if (sdkResult != ORBIS_OK) { + sdk_version = 0; + } + + if (sdk_version < 0x3000000) { + if (year < 1) { + return ORBIS_RTC_ERROR_INVALID_YEAR; + } + if (month > 12 || month <= 0) { + return ORBIS_RTC_ERROR_INVALID_MONTH; + } + } else { + if (year > 9999 || year < 1) { + return ORBIS_RTC_ERROR_INVALID_YEAR; + } + if (month > 12 || month <= 0) { + return ORBIS_RTC_ERROR_INVALID_MONTH; + } + } + + int daysInMonth = sceRtcGetDaysInMonth(year, month); + + if (day <= 0 || day > daysInMonth) + return ORBIS_RTC_ERROR_INVALID_DAY; + return ORBIS_OK; } -int PS4_SYSV_ABI sceRtcGetDaysInMonth(int iYear, int iMonth) { +int PS4_SYSV_ABI sceRtcGetDaysInMonth(int year, int month) { LOG_TRACE(Lib_Rtc, "called"); - if (iYear <= 0) + if (year <= 0) return ORBIS_RTC_ERROR_INVALID_YEAR; - if (iMonth <= 0 || iMonth > 12) + if (month <= 0 || month > 12) return ORBIS_RTC_ERROR_INVALID_MONTH; - using namespace std::chrono; - - year chronoYear = year(iYear); - month chronoMonth = month(iMonth); - int lastDay = - static_cast(unsigned(year_month_day_last{chronoYear / chronoMonth / last}.day())); + std::chrono::year chronoYear = std::chrono::year(year); + std::chrono::month chronoMonth = std::chrono::month(month); + int lastDay = static_cast(unsigned( + std::chrono::year_month_day_last{chronoYear / chronoMonth / std::chrono::last}.day())); return lastDay; } @@ -355,7 +380,7 @@ int PS4_SYSV_ABI sceRtcGetTick(OrbisRtcDateTime* pTime, OrbisRtcTick* pTick) { pTick->tick = days + msec; - return 0; + return SCE_OK; } unsigned int PS4_SYSV_ABI sceRtcGetTickResolution() { @@ -375,7 +400,7 @@ int PS4_SYSV_ABI sceRtcGetWin32FileTime(OrbisRtcDateTime* pTime, uint64_t* ulWin } int PS4_SYSV_ABI sceRtcInit() { - return 0; + return SCE_OK; } int PS4_SYSV_ABI sceRtcIsLeapYear(int yearInt) { @@ -442,7 +467,7 @@ int PS4_SYSV_ABI sceRtcSetDosTime(OrbisRtcDateTime* pTime, u32 dosTime) { pTime->month = (days >> 5) & 0xf; pTime->year = (days >> 9) + 0x7bc; - return 0; + return SCE_OK; } int PS4_SYSV_ABI sceRtcSetTick(OrbisRtcDateTime* pTime, OrbisRtcTick* pTick) { @@ -491,7 +516,7 @@ int PS4_SYSV_ABI sceRtcSetTick(OrbisRtcDateTime* pTime, OrbisRtcTick* pTick) { msec %= 1000000; pTime->microsecond = msec; - return 0; + return SCE_OK; } int PS4_SYSV_ABI sceRtcSetTime_t(OrbisRtcDateTime* pTime, time_t llTime) { @@ -519,7 +544,7 @@ int PS4_SYSV_ABI sceRtcSetTime_t(OrbisRtcDateTime* pTime, time_t llTime) { newTick.tick += 0xdcbffeff2bc000; sceRtcSetTick(pTime, &newTick); - return ORBIS_OK; + return SCE_OK; } int PS4_SYSV_ABI sceRtcSetWin32FileTime(OrbisRtcDateTime* pTime, uint64_t ulWin32Time) { @@ -535,10 +560,10 @@ int PS4_SYSV_ABI sceRtcSetWin32FileTime(OrbisRtcDateTime* pTime, uint64_t ulWin3 sceRtcSetTick(pTime, &convertedTick); - return 0; + return SCE_OK; } -int PS4_SYSV_ABI sceRtcTickAddDays(OrbisRtcTick* pTick1, OrbisRtcTick* pTick2, s32 lAdd) { +int PS4_SYSV_ABI sceRtcTickAddDays(OrbisRtcTick* pTick1, OrbisRtcTick* pTick2, int32_t lAdd) { LOG_TRACE(Lib_Rtc, "called"); if (pTick1 == nullptr || pTick2 == nullptr) @@ -546,10 +571,10 @@ int PS4_SYSV_ABI sceRtcTickAddDays(OrbisRtcTick* pTick1, OrbisRtcTick* pTick2, s pTick1->tick = (lAdd * 86400000000) + pTick2->tick; - return 0; + return SCE_OK; } -int PS4_SYSV_ABI sceRtcTickAddHours(OrbisRtcTick* pTick1, OrbisRtcTick* pTick2, s32 lAdd) { +int PS4_SYSV_ABI sceRtcTickAddHours(OrbisRtcTick* pTick1, OrbisRtcTick* pTick2, int32_t lAdd) { LOG_TRACE(Lib_Rtc, "called"); if (pTick1 == nullptr || pTick2 == nullptr) @@ -557,10 +582,11 @@ int PS4_SYSV_ABI sceRtcTickAddHours(OrbisRtcTick* pTick1, OrbisRtcTick* pTick2, pTick1->tick = (lAdd * 3600000000) + pTick2->tick; - return 0; + return SCE_OK; } -int PS4_SYSV_ABI sceRtcTickAddMicroseconds(OrbisRtcTick* pTick1, OrbisRtcTick* pTick2, s64 lAdd) { +int PS4_SYSV_ABI sceRtcTickAddMicroseconds(OrbisRtcTick* pTick1, OrbisRtcTick* pTick2, + int64_t lAdd) { LOG_TRACE(Lib_Rtc, "called"); if (pTick1 == nullptr || pTick2 == nullptr) @@ -568,10 +594,10 @@ int PS4_SYSV_ABI sceRtcTickAddMicroseconds(OrbisRtcTick* pTick1, OrbisRtcTick* p pTick1->tick = lAdd + pTick2->tick; - return 0; + return SCE_OK; } -int PS4_SYSV_ABI sceRtcTickAddMinutes(OrbisRtcTick* pTick1, OrbisRtcTick* pTick2, s64 lAdd) { +int PS4_SYSV_ABI sceRtcTickAddMinutes(OrbisRtcTick* pTick1, OrbisRtcTick* pTick2, int64_t lAdd) { LOG_TRACE(Lib_Rtc, "called"); if (pTick1 == nullptr || pTick2 == nullptr) @@ -579,10 +605,10 @@ int PS4_SYSV_ABI sceRtcTickAddMinutes(OrbisRtcTick* pTick1, OrbisRtcTick* pTick2 pTick1->tick = (lAdd * 60000000) + pTick2->tick; - return 0; + return SCE_OK; } -int PS4_SYSV_ABI sceRtcTickAddMonths(OrbisRtcTick* pTick1, OrbisRtcTick* pTick2, s32 lAdd) { +int PS4_SYSV_ABI sceRtcTickAddMonths(OrbisRtcTick* pTick1, OrbisRtcTick* pTick2, int32_t lAdd) { LOG_TRACE(Lib_Rtc, "called"); if (pTick1 == nullptr || pTick2 == nullptr) @@ -590,7 +616,7 @@ int PS4_SYSV_ABI sceRtcTickAddMonths(OrbisRtcTick* pTick1, OrbisRtcTick* pTick2, if (lAdd == 0) { pTick1->tick = pTick2->tick; - return 0; + return SCE_OK; } OrbisRtcDateTime time; @@ -632,10 +658,10 @@ int PS4_SYSV_ABI sceRtcTickAddMonths(OrbisRtcTick* pTick1, OrbisRtcTick* pTick2, return timeIsValid; } - return 0; + return SCE_OK; } -int PS4_SYSV_ABI sceRtcTickAddSeconds(OrbisRtcTick* pTick1, OrbisRtcTick* pTick2, s64 lAdd) { +int PS4_SYSV_ABI sceRtcTickAddSeconds(OrbisRtcTick* pTick1, OrbisRtcTick* pTick2, int64_t lAdd) { LOG_TRACE(Lib_Rtc, "called"); if (pTick1 == nullptr || pTick2 == nullptr) @@ -643,10 +669,10 @@ int PS4_SYSV_ABI sceRtcTickAddSeconds(OrbisRtcTick* pTick1, OrbisRtcTick* pTick2 pTick1->tick = (lAdd * 1000000) + pTick2->tick; - return 0; + return SCE_OK; } -int PS4_SYSV_ABI sceRtcTickAddTicks(OrbisRtcTick* pTick1, OrbisRtcTick* pTick2, s64 lAdd) { +int PS4_SYSV_ABI sceRtcTickAddTicks(OrbisRtcTick* pTick1, OrbisRtcTick* pTick2, int64_t lAdd) { LOG_TRACE(Lib_Rtc, "called"); if (pTick1 == nullptr || pTick2 == nullptr) @@ -654,10 +680,10 @@ int PS4_SYSV_ABI sceRtcTickAddTicks(OrbisRtcTick* pTick1, OrbisRtcTick* pTick2, pTick1->tick = lAdd + pTick2->tick; - return 0; + return SCE_OK; } -int PS4_SYSV_ABI sceRtcTickAddWeeks(OrbisRtcTick* pTick1, OrbisRtcTick* pTick2, s32 lAdd) { +int PS4_SYSV_ABI sceRtcTickAddWeeks(OrbisRtcTick* pTick1, OrbisRtcTick* pTick2, int32_t lAdd) { LOG_TRACE(Lib_Rtc, "called"); if (pTick1 == nullptr || pTick2 == nullptr) @@ -665,10 +691,10 @@ int PS4_SYSV_ABI sceRtcTickAddWeeks(OrbisRtcTick* pTick1, OrbisRtcTick* pTick2, pTick1->tick = (lAdd * 0x8cd0e3a000) + pTick2->tick; - return 0; + return SCE_OK; } -int PS4_SYSV_ABI sceRtcTickAddYears(OrbisRtcTick* pTick1, OrbisRtcTick* pTick2, s16 lAdd) { +int PS4_SYSV_ABI sceRtcTickAddYears(OrbisRtcTick* pTick1, OrbisRtcTick* pTick2, int32_t lAdd) { LOG_TRACE(Lib_Rtc, "called"); if (pTick1 == nullptr || pTick2 == nullptr) @@ -678,7 +704,7 @@ int PS4_SYSV_ABI sceRtcTickAddYears(OrbisRtcTick* pTick1, OrbisRtcTick* pTick2, if (lAdd == 0) { pTick1->tick = pTick2->tick; - return 0; + return SCE_OK; } sceRtcSetTick(&time, pTick1); @@ -692,7 +718,7 @@ int PS4_SYSV_ABI sceRtcTickAddYears(OrbisRtcTick* pTick1, OrbisRtcTick* pTick2, return timeIsValid; } - return 0; + return SCE_OK; } void RegisterlibSceRtc(Core::Loader::SymbolsResolver* sym) { diff --git a/src/core/libraries/rtc/rtc.h b/src/core/libraries/rtc/rtc.h index aa910ae23..e9dc3171d 100644 --- a/src/core/libraries/rtc/rtc.h +++ b/src/core/libraries/rtc/rtc.h @@ -11,18 +11,26 @@ class SymbolsResolver; namespace Libraries::Rtc { +constexpr int ORBIS_RTC_DAYOFWEEK_SUNDAY = 0; +constexpr int ORBIS_RTC_DAYOFWEEK_MONDAY = 1; +constexpr int ORBIS_RTC_DAYOFWEEK_TUESDAY = 2; +constexpr int ORBIS_RTC_DAYOFWEEK_WEDNESDAY = 3; +constexpr int ORBIS_RTC_DAYOFWEEK_THURSDAY = 4; +constexpr int ORBIS_RTC_DAYOFWEEK_FRIDAY = 5; +constexpr int ORBIS_RTC_DAYOFWEEK_SATURDAY = 6; + struct OrbisRtcTick { - u64 tick; + uint64_t tick; }; struct OrbisRtcDateTime { - int16_t year; - int16_t month; - int16_t day; - int16_t hour; - int16_t minute; - int16_t second; - int32_t microsecond; + uint16_t year; + uint16_t month; + uint16_t day; + uint16_t hour; + uint16_t minute; + uint16_t second; + uint32_t microsecond; }; int PS4_SYSV_ABI sceRtcCheckValid(OrbisRtcDateTime* pTime); @@ -65,15 +73,16 @@ int PS4_SYSV_ABI sceRtcSetDosTime(OrbisRtcDateTime* pTime, u32 dosTime); int PS4_SYSV_ABI sceRtcSetTick(OrbisRtcDateTime* pTime, OrbisRtcTick* pTick); int PS4_SYSV_ABI sceRtcSetTime_t(OrbisRtcDateTime* pTime, time_t llTime); int PS4_SYSV_ABI sceRtcSetWin32FileTime(OrbisRtcDateTime* pTime, uint64_t ulWin32Time); -int PS4_SYSV_ABI sceRtcTickAddDays(OrbisRtcTick* pTick1, OrbisRtcTick* pTick2, s32 lAdd); -int PS4_SYSV_ABI sceRtcTickAddHours(OrbisRtcTick* pTick1, OrbisRtcTick* pTick2, s32 lAdd); -int PS4_SYSV_ABI sceRtcTickAddMicroseconds(OrbisRtcTick* pTick1, OrbisRtcTick* pTick2, s64 lAdd); -int PS4_SYSV_ABI sceRtcTickAddMinutes(OrbisRtcTick* pTick1, OrbisRtcTick* pTick2, s64 lAdd); -int PS4_SYSV_ABI sceRtcTickAddMonths(OrbisRtcTick* pTick1, OrbisRtcTick* pTick2, s32 lAdd); -int PS4_SYSV_ABI sceRtcTickAddSeconds(OrbisRtcTick* pTick1, OrbisRtcTick* pTick2, s64 lAdd); -int PS4_SYSV_ABI sceRtcTickAddTicks(OrbisRtcTick* pTick1, OrbisRtcTick* pTick2, s64 lAdd); -int PS4_SYSV_ABI sceRtcTickAddWeeks(OrbisRtcTick* pTick1, OrbisRtcTick* pTick2, s32 lAdd); -int PS4_SYSV_ABI sceRtcTickAddYears(OrbisRtcTick* pTick1, OrbisRtcTick* pTick2, s16 lAdd); +int PS4_SYSV_ABI sceRtcTickAddDays(OrbisRtcTick* pTick1, OrbisRtcTick* pTick2, int32_t lAdd); +int PS4_SYSV_ABI sceRtcTickAddHours(OrbisRtcTick* pTick1, OrbisRtcTick* pTick2, int32_t lAdd); +int PS4_SYSV_ABI sceRtcTickAddMicroseconds(OrbisRtcTick* pTick1, OrbisRtcTick* pTick2, + int64_t lAdd); +int PS4_SYSV_ABI sceRtcTickAddMinutes(OrbisRtcTick* pTick1, OrbisRtcTick* pTick2, int64_t lAdd); +int PS4_SYSV_ABI sceRtcTickAddMonths(OrbisRtcTick* pTick1, OrbisRtcTick* pTick2, int32_t lAdd); +int PS4_SYSV_ABI sceRtcTickAddSeconds(OrbisRtcTick* pTick1, OrbisRtcTick* pTick2, int64_t lAdd); +int PS4_SYSV_ABI sceRtcTickAddTicks(OrbisRtcTick* pTick1, OrbisRtcTick* pTick2, int64_t lAdd); +int PS4_SYSV_ABI sceRtcTickAddWeeks(OrbisRtcTick* pTick1, OrbisRtcTick* pTick2, int32_t lAdd); +int PS4_SYSV_ABI sceRtcTickAddYears(OrbisRtcTick* pTick1, OrbisRtcTick* pTick2, int32_t lAdd); void RegisterlibSceRtc(Core::Loader::SymbolsResolver* sym); } // namespace Libraries::Rtc \ No newline at end of file From 7a6f22dfa0b62fb51cc576ef14f94cdeea9cee9b Mon Sep 17 00:00:00 2001 From: CrazyBloo Date: Tue, 3 Sep 2024 16:17:00 +0900 Subject: [PATCH 2/2] fix sceRtcGetCurrentClockLocalTime, fixes sceRtcGetCurrentClockLocalTime using lizardy's suggestions. also implements various formatting improvements and logging changes --- src/core/libraries/kernel/time_management.h | 1 + src/core/libraries/rtc/rtc.cpp | 60 ++++++++++++++------- src/core/libraries/rtc/rtc_error.h | 1 + 3 files changed, 43 insertions(+), 19 deletions(-) diff --git a/src/core/libraries/kernel/time_management.h b/src/core/libraries/kernel/time_management.h index 4f8032c17..a28e6e558 100644 --- a/src/core/libraries/kernel/time_management.h +++ b/src/core/libraries/kernel/time_management.h @@ -53,6 +53,7 @@ u64 PS4_SYSV_ABI sceKernelGetProcessTimeCounter(); u64 PS4_SYSV_ABI sceKernelGetProcessTimeCounterFrequency(); u64 PS4_SYSV_ABI sceKernelReadTsc(); int PS4_SYSV_ABI sceKernelClockGettime(s32 clock_id, OrbisKernelTimespec* tp); +s32 PS4_SYSV_ABI sceKernelGettimezone(OrbisKernelTimezone* tz); int PS4_SYSV_ABI sceKernelConvertLocaltimeToUtc(time_t param_1, int64_t param_2, time_t* seconds, OrbisKernelTimezone* timezone, int* dst_seconds); void timeSymbolsRegister(Core::Loader::SymbolsResolver* sym); diff --git a/src/core/libraries/rtc/rtc.cpp b/src/core/libraries/rtc/rtc.cpp index 51e66a466..649d21333 100644 --- a/src/core/libraries/rtc/rtc.cpp +++ b/src/core/libraries/rtc/rtc.cpp @@ -80,7 +80,7 @@ int PS4_SYSV_ABI sceRtcConvertLocalTimeToUtc(OrbisRtcTick* pTickLocal, OrbisRtcT if (convertValue >= 0) { convertValue = sceRtcTickAddMinutes( - pTickUtc, pTickLocal, -((timezone.tz_dsttime + timezone.tz_minuteswest) / 0x3c)); + pTickUtc, pTickLocal, -((timezone.tz_dsttime + timezone.tz_minuteswest) / 60)); } return convertValue; @@ -99,7 +99,7 @@ int PS4_SYSV_ABI sceRtcConvertUtcToLocalTime(OrbisRtcTick* pTickUtc, OrbisRtcTic (pTickUtc->tick + 0xff23400100d44000U) / 1000000, &seconds, &timezone, 0); if (convertValue >= 0) { - auto newTime = ((timezone.dst_sec + timezone.west_sec) / 0x3c) * 60000000; + auto newTime = ((timezone.dst_sec + timezone.west_sec) / 60) * 60000000; if (pTickLocal == nullptr) return ORBIS_RTC_ERROR_INVALID_POINTER; @@ -124,7 +124,8 @@ int PS4_SYSV_ABI sceRtcEnd() { return SCE_OK; } -int PS4_SYSV_ABI sceRtcFormatRFC2822(char* pszDateTime, const OrbisRtcTick* pTickUtc, int minutes) { +int PS4_SYSV_ABI sceRtcFormatRFC2822(char* pszDateTime, const OrbisRtcTick* pTickUtc, + int iTimeZoneMinutes) { LOG_ERROR(Lib_Rtc, "(STUBBED) called"); return ORBIS_OK; } @@ -134,7 +135,8 @@ int PS4_SYSV_ABI sceRtcFormatRFC2822LocalTime(char* pszDateTime, const OrbisRtcT return ORBIS_OK; } -int PS4_SYSV_ABI sceRtcFormatRFC3339(char* pszDateTime, const OrbisRtcTick* pTickUtc, int minutes) { +int PS4_SYSV_ABI sceRtcFormatRFC3339(char* pszDateTime, const OrbisRtcTick* pTickUtc, + int iTimeZoneMinutes) { LOG_ERROR(Lib_Rtc, "(STUBBED) called"); return ORBIS_OK; } @@ -145,7 +147,7 @@ int PS4_SYSV_ABI sceRtcFormatRFC3339LocalTime(char* pszDateTime, const OrbisRtcT } int PS4_SYSV_ABI sceRtcFormatRFC3339Precise(char* pszDateTime, const OrbisRtcTick* pTickUtc, - int minutes) { + int iTimeZoneMinutes) { LOG_ERROR(Lib_Rtc, "(STUBBED) called"); return ORBIS_OK; } @@ -178,7 +180,7 @@ int PS4_SYSV_ABI sceRtcGetCurrentClock(OrbisRtcDateTime* pTime, int timeZone) { LOG_TRACE(Lib_Rtc, "called"); if (pTime == nullptr) - return ORBIS_RTC_ERROR_INVALID_POINTER; + return ORBIS_RTC_ERROR_DATETIME_UNINITIALIZED; Kernel::OrbisKernelTimespec clocktime; int returnValue = Kernel::sceKernelClockGettime(Kernel::ORBIS_CLOCK_REALTIME, &clocktime); @@ -191,6 +193,9 @@ int PS4_SYSV_ABI sceRtcGetCurrentClock(OrbisRtcDateTime* pTime, int timeZone) { sceRtcSetTick(pTime, &clockTick); } + LOG_INFO(Lib_Rtc, "Got Current Clock {}/{}/{} @ {}:{}", pTime->year, pTime->month, pTime->day, + pTime->hour, pTime->minute); + return returnValue; } @@ -198,28 +203,37 @@ int PS4_SYSV_ABI sceRtcGetCurrentClockLocalTime(OrbisRtcDateTime* pTime) { LOG_TRACE(Lib_Rtc, "called"); if (pTime == nullptr) - return ORBIS_RTC_ERROR_INVALID_POINTER; + return ORBIS_RTC_ERROR_DATETIME_UNINITIALIZED; - Kernel::OrbisKernelTimespec clocktime; - int returnValue = Kernel::sceKernelClockGettime(Kernel::ORBIS_CLOCK_REALTIME, &clocktime); + Kernel::OrbisKernelTimezone timeZone; + int returnValue = Kernel::sceKernelGettimezone(&timeZone); if (returnValue >= 0) { - u64 clockTick = clocktime.tv_nsec / 1000 + clocktime.tv_sec * 1000000 + 0xdcbffeff2bc000; + Kernel::OrbisKernelTimespec clocktime; - time_t seconds; - Kernel::OrbisTimesec timezone; - - returnValue = - Kernel::sceKernelConvertUtcToLocaltime(clockTick / 1000000, &seconds, &timezone, 0); + // calculate total timezone offset for converting UTC to local time + uint64_t tzOffset = -(timeZone.tz_minuteswest - (timeZone.tz_dsttime * 60)); + returnValue = sceKernelClockGettime(0, &clocktime); if (returnValue >= 0) { OrbisRtcTick newTick; - newTick.tick = clockTick; - sceRtcTickAddMinutes(&newTick, &newTick, (timezone.dst_sec + timezone.west_sec) / 0x3c); + newTick.tick = + ((unsigned __int64)((unsigned __int128)(clocktime.tv_nsec * + (signed __int128)2361183241434822607LL) >> + 64) >> + 63) + + ((signed __int64)((unsigned __int128)(clocktime.tv_nsec * + (signed __int128)2361183241434822607LL) >> + 64) >> + 7) + + 1000000 * clocktime.tv_sec + 62135596800000000LL; + sceRtcTickAddMinutes(&newTick, &newTick, tzOffset); sceRtcSetTick(pTime, &newTick); } } + LOG_INFO(Lib_Rtc, "Got Local Time {}/{}/{} @ {}:{}", pTime->year, pTime->month, pTime->day, + pTime->hour, pTime->minute); return returnValue; } @@ -281,7 +295,7 @@ int PS4_SYSV_ABI sceRtcGetCurrentTick(OrbisRtcTick* pTick) { LOG_TRACE(Lib_Rtc, "called"); if (pTick == nullptr) - return ORBIS_RTC_ERROR_INVALID_POINTER; + return ORBIS_RTC_ERROR_DATETIME_UNINITIALIZED; Kernel::OrbisKernelTimespec clocktime; int returnValue = Kernel::sceKernelClockGettime(Kernel::ORBIS_CLOCK_REALTIME, &clocktime); @@ -323,7 +337,13 @@ int PS4_SYSV_ABI sceRtcGetDayOfWeek(int year, int month, int day) { if (day <= 0 || day > daysInMonth) return ORBIS_RTC_ERROR_INVALID_DAY; - return ORBIS_OK; + std::chrono::sys_days chrono_time{std::chrono::year(year) / std::chrono::month(month) / + std::chrono::day(day)}; + std::chrono::weekday chrono_weekday{chrono_time}; + + LOG_INFO(Lib_Rtc, "Got Day Of Week : {}", chrono_weekday.c_encoding()); + + return chrono_weekday.c_encoding(); } int PS4_SYSV_ABI sceRtcGetDaysInMonth(int year, int month) { @@ -340,6 +360,8 @@ int PS4_SYSV_ABI sceRtcGetDaysInMonth(int year, int month) { int lastDay = static_cast(unsigned( std::chrono::year_month_day_last{chronoYear / chronoMonth / std::chrono::last}.day())); + LOG_INFO(Lib_Rtc, "Got Days In Month : {}", lastDay); + return lastDay; } diff --git a/src/core/libraries/rtc/rtc_error.h b/src/core/libraries/rtc/rtc_error.h index cbcde6f41..3af5a68fd 100644 --- a/src/core/libraries/rtc/rtc_error.h +++ b/src/core/libraries/rtc/rtc_error.h @@ -3,6 +3,7 @@ #pragma once +constexpr int ORBIS_RTC_ERROR_DATETIME_UNINITIALIZED = 0x7FFEF9FE; constexpr int ORBIS_RTC_ERROR_INVALID_PARAMETER = 0x80010602; constexpr int ORBIS_RTC_ERROR_INVALID_TICK_PARAMETER = 0x80010603; constexpr int ORBIS_RTC_ERROR_INVALID_DATE_PARAMETER = 0x80010604;