Make libSceRtc fully HLE (#3330)

* Add stubbed libkernel time functions

* Implement remaining stubbed Rtc functions

* Move Rtc from the optionally HLE loading part to the always loaded part

* Remove Rtc from the README list of LLE modules

* Mfw last second hotfix I noticed while double checking that everything's good before opening the PR
This commit is contained in:
kalaposfos13
2025-08-06 19:08:26 +02:00
committed by GitHub
parent 841aa9e43d
commit 5b46216bae
7 changed files with 97 additions and 16 deletions

View File

@@ -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 | | | |
</div>

View File

@@ -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<Common::NativeClock>();
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);

View File

@@ -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);

View File

@@ -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

View File

@@ -4,6 +4,7 @@
#include <chrono>
#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);

View File

@@ -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

View File

@@ -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},