diff --git a/README.md b/README.md index 06da2d471..88e674368 100644 --- a/README.md +++ b/README.md @@ -133,7 +133,7 @@ The following firmware modules are supported and must be placed in shadPS4's `sy |-------------------------|-------------------------|-------------------------|-------------------------| | libSceCesCs.sprx | libSceFont.sprx | libSceFontFt.sprx | libSceFreeTypeOt.sprx | | libSceJson.sprx | libSceJson2.sprx | libSceLibcInternal.sprx | libSceNgs2.sprx | -| libSceRtc.sprx | libSceUlt.sprx | | | +| libSceUlt.sprx | | | | diff --git a/src/core/libraries/kernel/time.cpp b/src/core/libraries/kernel/time.cpp index 2fe74d0a3..ecdcbac3e 100644 --- a/src/core/libraries/kernel/time.cpp +++ b/src/core/libraries/kernel/time.cpp @@ -508,6 +508,24 @@ s32 PS4_SYSV_ABI sceKernelConvertUtcToLocaltime(time_t time, time_t* local_time, return ORBIS_OK; } +s32 PS4_SYSV_ABI posix_clock_settime(s32 clock_id, OrbisKernelTimespec* tp) { + LOG_ERROR(Lib_Kernel, "(STUBBED) called, clock_id: {}", clock_id); + return ORBIS_OK; +} + +s32 PS4_SYSV_ABI posix_settimeofday(OrbisKernelTimeval* _tv, OrbisKernelTimezone* _tz) { + LOG_ERROR(Lib_Kernel, "(STUBBED) called"); + return ORBIS_OK; +} + +s32 PS4_SYSV_ABI sceKernelSettimeofday(OrbisKernelTimeval* _tv, OrbisKernelTimezone* _tz) { + s32 ret = posix_settimeofday(_tv, _tz); + if (ret < 0) { + return ErrnoToSceKernelError(ret); + } + return ret; +} + void RegisterTime(Core::Loader::SymbolsResolver* sym) { clock = std::make_unique(); initial_ptc = clock->GetUptime(); @@ -525,6 +543,9 @@ void RegisterTime(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("smIj7eqzZE8", "libScePosix", 1, "libkernel", 1, 1, posix_clock_getres); LIB_FUNCTION("n88vx3C5nW8", "libkernel", 1, "libkernel", 1, 1, posix_gettimeofday); LIB_FUNCTION("n88vx3C5nW8", "libScePosix", 1, "libkernel", 1, 1, posix_gettimeofday); + LIB_FUNCTION("ChCOChPU-YM", "libkernel", 1, "libkernel", 1, 1, sceKernelSettimeofday); + LIB_FUNCTION("VdXIDAbJ3tQ", "libScePosix", 1, "libkernel", 1, 1, posix_settimeofday); + LIB_FUNCTION("d7nUj1LOdDU", "libScePosix", 1, "libkernel", 1, 1, posix_clock_settime); // Orbis LIB_FUNCTION("4J2sUJmuHZQ", "libkernel", 1, "libkernel", 1, 1, sceKernelGetProcessTime); diff --git a/src/core/libraries/kernel/time.h b/src/core/libraries/kernel/time.h index c80de7bc4..583d138b8 100644 --- a/src/core/libraries/kernel/time.h +++ b/src/core/libraries/kernel/time.h @@ -83,6 +83,9 @@ s32 PS4_SYSV_ABI sceKernelConvertLocaltimeToUtc(time_t param_1, int64_t param_2, s32 PS4_SYSV_ABI sceKernelConvertUtcToLocaltime(time_t time, time_t* local_time, OrbisTimesec* st, u64* dst_sec); s32 PS4_SYSV_ABI sceKernelUsleep(u32 microseconds); +s32 PS4_SYSV_ABI posix_clock_settime(s32 clock_id, OrbisKernelTimespec* tp); +s32 PS4_SYSV_ABI posix_settimeofday(OrbisKernelTimeval* _tv, OrbisKernelTimezone* _tz); +s32 PS4_SYSV_ABI sceKernelSettimeofday(OrbisKernelTimeval* _tv, OrbisKernelTimezone* _tz); void RegisterTime(Core::Loader::SymbolsResolver* sym); diff --git a/src/core/libraries/libs.cpp b/src/core/libraries/libs.cpp index af9328a57..b2987cd97 100644 --- a/src/core/libraries/libs.cpp +++ b/src/core/libraries/libs.cpp @@ -130,6 +130,7 @@ void InitHLELibs(Core::Loader::SymbolsResolver* sym) { Libraries::CompanionHttpd::RegisterLib(sym); Libraries::CompanionUtil::RegisterLib(sym); Libraries::Voice::RegisterLib(sym); + Libraries::Rtc::RegisterLib(sym); } } // namespace Libraries diff --git a/src/core/libraries/rtc/rtc.cpp b/src/core/libraries/rtc/rtc.cpp index f94c00134..89be435c9 100644 --- a/src/core/libraries/rtc/rtc.cpp +++ b/src/core/libraries/rtc/rtc.cpp @@ -4,6 +4,7 @@ #include #include "common/logging/log.h" +#include "core/libraries/kernel/kernel.h" #include "core/libraries/kernel/process.h" #include "core/libraries/kernel/time.h" #include "core/libraries/libs.h" @@ -827,29 +828,81 @@ int PS4_SYSV_ABI sceRtcParseRFC3339(OrbisRtcTick* pTickUtc, const char* pszDateT return ORBIS_OK; } -int PS4_SYSV_ABI sceRtcSetConf() { - LOG_ERROR(Lib_Rtc, "(STUBBED) called"); - return ORBIS_OK; +void PS4_SYSV_ABI sceRtcSetConf(void* p1, void* p2, s32 minuteswest, s32 dsttime) { + LOG_INFO(Lib_Rtc, "called"); + Kernel::OrbisKernelTimezone tz{minuteswest, dsttime}; + Kernel::sceKernelSettimeofday(0, &tz); + return; } int PS4_SYSV_ABI sceRtcSetCurrentAdNetworkTick(OrbisRtcTick* pTick) { - LOG_ERROR(Lib_Rtc, "(STUBBED) called"); - return ORBIS_OK; + LOG_INFO(Lib_Rtc, "called"); + if (UNIX_EPOCH_TICKS >= pTick->tick) { + return ORBIS_RTC_ERROR_INVALID_VALUE; + } + s32 ret = 0; + if (pTick != nullptr) { + u64 temp = pTick->tick - UNIX_EPOCH_TICKS; + Kernel::OrbisKernelTimespec ts(temp / 1000000, temp % 1000000); + ret = Kernel::posix_clock_settime(ORBIS_RTC_CLOCK_ID_AD_NETWORK, &ts); + } else { + ret = Kernel::posix_clock_settime(ORBIS_RTC_CLOCK_ID_AD_NETWORK, nullptr); + } + if (ret < 0) { + return Kernel::ErrnoToSceKernelError(*Kernel::__Error()); + } + return ret; } int PS4_SYSV_ABI sceRtcSetCurrentDebugNetworkTick(OrbisRtcTick* pTick) { - LOG_ERROR(Lib_Rtc, "(STUBBED) called"); - return ORBIS_OK; + LOG_INFO(Lib_Rtc, "called"); + if (UNIX_EPOCH_TICKS >= pTick->tick) { + return ORBIS_RTC_ERROR_INVALID_VALUE; + } + s32 ret = 0; + if (pTick != nullptr) { + u64 temp = pTick->tick - UNIX_EPOCH_TICKS; + Kernel::OrbisKernelTimespec ts(temp / 1000000, temp % 1000000); + ret = Kernel::posix_clock_settime(ORBIS_RTC_CLOCK_ID_DEBUG_NETWORK, &ts); + } else { + ret = Kernel::posix_clock_settime(ORBIS_RTC_CLOCK_ID_DEBUG_NETWORK, nullptr); + } + if (ret < 0) { + return Kernel::ErrnoToSceKernelError(*Kernel::__Error()); + } + return ret; } int PS4_SYSV_ABI sceRtcSetCurrentNetworkTick(OrbisRtcTick* pTick) { - LOG_ERROR(Lib_Rtc, "(STUBBED) called"); - return ORBIS_OK; + LOG_INFO(Lib_Rtc, "called"); + if (UNIX_EPOCH_TICKS >= pTick->tick) { + return ORBIS_RTC_ERROR_INVALID_VALUE; + } + s32 ret = 0; + if (pTick != nullptr) { + u64 temp = pTick->tick - UNIX_EPOCH_TICKS; + Kernel::OrbisKernelTimespec ts(temp / 1000000, temp % 1000000); + ret = Kernel::posix_clock_settime(ORBIS_RTC_CLOCK_ID_NETWORK, &ts); + } else { + ret = Kernel::posix_clock_settime(ORBIS_RTC_CLOCK_ID_NETWORK, nullptr); + } + if (ret < 0) { + return Kernel::ErrnoToSceKernelError(*Kernel::__Error()); + } + return ret; } int PS4_SYSV_ABI sceRtcSetCurrentTick(OrbisRtcTick* pTick) { - LOG_ERROR(Lib_Rtc, "(STUBBED) called"); - return ORBIS_OK; + LOG_INFO(Lib_Rtc, "called"); + if (pTick == nullptr) { + return ORBIS_RTC_ERROR_INVALID_POINTER; + } + if (UNIX_EPOCH_TICKS >= pTick->tick) { + return ORBIS_RTC_ERROR_INVALID_VALUE; + } + s64 temp = pTick->tick - UNIX_EPOCH_TICKS; + Kernel::OrbisKernelTimeval tv(temp / 1000000, temp % 1000000); + return Kernel::sceKernelSettimeofday(&tv, nullptr); } int PS4_SYSV_ABI sceRtcSetDosTime(OrbisRtcDateTime* pTime, u32 dosTime) { @@ -1122,7 +1175,7 @@ int PS4_SYSV_ABI sceRtcTickAddYears(OrbisRtcTick* pTick1, OrbisRtcTick* pTick2, return ORBIS_OK; } -void RegisterlibSceRtc(Core::Loader::SymbolsResolver* sym) { +void RegisterLib(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("lPEBYdVX0XQ", "libSceRtc", 1, "libSceRtc", 1, 1, sceRtcCheckValid); LIB_FUNCTION("fNaZ4DbzHAE", "libSceRtc", 1, "libSceRtc", 1, 1, sceRtcCompareTick); LIB_FUNCTION("8Yr143yEnRo", "libSceRtc", 1, "libSceRtc", 1, 1, sceRtcConvertLocalTimeToUtc); diff --git a/src/core/libraries/rtc/rtc.h b/src/core/libraries/rtc/rtc.h index eb7afa00c..8ca55a03a 100644 --- a/src/core/libraries/rtc/rtc.h +++ b/src/core/libraries/rtc/rtc.h @@ -20,6 +20,10 @@ constexpr int ORBIS_RTC_DAYOFWEEK_THURSDAY = 4; constexpr int ORBIS_RTC_DAYOFWEEK_FRIDAY = 5; constexpr int ORBIS_RTC_DAYOFWEEK_SATURDAY = 6; +constexpr int ORBIS_RTC_CLOCK_ID_NETWORK = 0x10; +constexpr int ORBIS_RTC_CLOCK_ID_DEBUG_NETWORK = 0x11; +constexpr int ORBIS_RTC_CLOCK_ID_AD_NETWORK = 0x12; + constexpr s64 UNIX_EPOCH_TICKS = 0xdcbffeff2bc000; constexpr s64 WIN32_FILETIME_EPOCH_TICKS = 0xb36168b6a58000; @@ -68,7 +72,7 @@ int PS4_SYSV_ABI sceRtcInit(); int PS4_SYSV_ABI sceRtcIsLeapYear(int yearInt); int PS4_SYSV_ABI sceRtcParseDateTime(OrbisRtcTick* pTickUtc, const char* pszDateTime); int PS4_SYSV_ABI sceRtcParseRFC3339(OrbisRtcTick* pTickUtc, const char* pszDateTime); -int PS4_SYSV_ABI sceRtcSetConf(); +void PS4_SYSV_ABI sceRtcSetConf(void* p1, void* p2, s32 minuteswest, s32 dsttime); int PS4_SYSV_ABI sceRtcSetCurrentAdNetworkTick(OrbisRtcTick* pTick); int PS4_SYSV_ABI sceRtcSetCurrentDebugNetworkTick(OrbisRtcTick* pTick); int PS4_SYSV_ABI sceRtcSetCurrentNetworkTick(OrbisRtcTick* pTick); @@ -88,5 +92,5 @@ int PS4_SYSV_ABI sceRtcTickAddTicks(OrbisRtcTick* pTick1, OrbisRtcTick* pTick2, 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); +void RegisterLib(Core::Loader::SymbolsResolver* sym); } // namespace Libraries::Rtc diff --git a/src/emulator.cpp b/src/emulator.cpp index 7d162ab16..e100214b0 100644 --- a/src/emulator.cpp +++ b/src/emulator.cpp @@ -330,7 +330,6 @@ void Emulator::LoadSystemModules(const std::string& game_serial) { {"libSceJson.sprx", nullptr}, {"libSceJson2.sprx", nullptr}, {"libSceLibcInternal.sprx", &Libraries::LibcInternal::RegisterlibSceLibcInternal}, - {"libSceRtc.sprx", &Libraries::Rtc::RegisterlibSceRtc}, {"libSceCesCs.sprx", nullptr}, {"libSceFont.sprx", nullptr}, {"libSceFontFt.sprx", nullptr},