feat(rtc): implement sceRtcGetDosTime and sceRtcSetDosTime
Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
f71bf7fd40
commit
c94949aedb
|
|
@ -369,6 +369,35 @@ int APS5_VABI sceRtcSetWin32FileTime(RtcDateTime* time, uint64_t win32_time) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int APS5_VABI sceRtcGetDosTime(const RtcDateTime* time, uint32_t* dos_time) {
|
||||
if (!dos_time) return SCE_RTC_ERROR_INVALID_POINTER;
|
||||
if (const int result = validate(time); result != 0) return result;
|
||||
if (time->year < 1980 || time->year > 2107) {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
return SCE_RTC_ERROR_INVALID_YEAR;
|
||||
}
|
||||
*dos_time = static_cast<uint32_t>(time->year - 1980) << 25 | static_cast<uint32_t>(time->month) << 21
|
||||
| static_cast<uint32_t>(time->day) << 16 | static_cast<uint32_t>(time->hour) << 11
|
||||
| static_cast<uint32_t>(time->minute) << 5 | static_cast<uint32_t>(time->second / 2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int APS5_VABI sceRtcSetDosTime(RtcDateTime* time, uint32_t dos_time) {
|
||||
if (!time) return SCE_RTC_ERROR_INVALID_POINTER;
|
||||
if (dos_time >> 31 != 0) {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
return SCE_RTC_ERROR_INVALID_VALUE;
|
||||
}
|
||||
time->year = static_cast<std::uint16_t>(1980 + (dos_time >> 25));
|
||||
time->month = static_cast<std::uint16_t>(dos_time >> 21 & 0x0f);
|
||||
time->day = static_cast<std::uint16_t>(dos_time >> 16 & 0x1f);
|
||||
time->hour = static_cast<std::uint16_t>(dos_time >> 11 & 0x1f);
|
||||
time->minute = static_cast<std::uint16_t>(dos_time >> 5 & 0x3f);
|
||||
time->second = static_cast<std::uint16_t>((dos_time & 0x1f) * 2);
|
||||
time->microsecond = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int APS5_VABI sceRtcFormatRFC3339(char* date_time, const RtcTick* utc, int time_zone_minutes) {
|
||||
if (!date_time || !utc) return SCE_RTC_ERROR_INVALID_POINTER;
|
||||
if (time_zone_minutes < -1439 || time_zone_minutes > 1439) return SCE_RTC_ERROR_INVALID_VALUE;
|
||||
|
|
|
|||
|
|
@ -23,6 +23,8 @@ int APS5_VABI sceRtcGetTime_t(const RtcDateTime*, std::int64_t*);
|
|||
int APS5_VABI sceRtcSetTime_t(RtcDateTime*, std::int64_t);
|
||||
int APS5_VABI sceRtcGetWin32FileTime(const RtcDateTime*, std::uint64_t*);
|
||||
int APS5_VABI sceRtcSetWin32FileTime(RtcDateTime*, std::uint64_t);
|
||||
int APS5_VABI sceRtcGetDosTime(const RtcDateTime*, std::uint32_t*);
|
||||
int APS5_VABI sceRtcSetDosTime(RtcDateTime*, std::uint32_t);
|
||||
int APS5_VABI sceRtcFormatRFC3339(char*, const RtcTick*, int);
|
||||
int APS5_VABI sceRtcParseRFC3339(RtcTick*, const char*);
|
||||
int APS5_VABI sceRtcParseDateTime(RtcTick*, const char*);
|
||||
|
|
@ -106,6 +108,29 @@ int main() {
|
|||
std::uint64_t fileTime = 0;
|
||||
Require(sceRtcGetWin32FileTime(&epoch, &fileTime) == 0 && fileTime == 116444736000000000ull);
|
||||
Require(sceRtcSetWin32FileTime(&converted, 116444736000000000ull) == 0 && Equal(converted, epoch));
|
||||
std::uint32_t dosTime = 0xffffffffu;
|
||||
const RtcDateTime dosDate{2024, 2, 29, 12, 34, 57, 789000};
|
||||
Require(sceRtcGetDosTime(&dosDate, &dosTime) == 0 && dosTime == 0x585d645cu);
|
||||
const RtcDateTime dosFirst{1980, 1, 1, 0, 0, 0, 0};
|
||||
Require(sceRtcGetDosTime(&dosFirst, &dosTime) == 0 && dosTime == 0x00210000u);
|
||||
const RtcDateTime dosLast{2107, 12, 31, 23, 59, 59, 0};
|
||||
Require(sceRtcGetDosTime(&dosLast, &dosTime) == 0 && dosTime == 0xff9fbf7du);
|
||||
Require(sceRtcGetDosTime(&dosDate, nullptr) == invalidPointer);
|
||||
Require(sceRtcGetDosTime(nullptr, &dosTime) == invalidPointer);
|
||||
const RtcDateTime dosBadMonth{2024, 13, 1, 0, 0, 0, 0};
|
||||
Require(sceRtcGetDosTime(&dosBadMonth, &dosTime) == invalidMonth);
|
||||
const RtcDateTime dosEarly{1979, 12, 31, 0, 0, 0, 0};
|
||||
bool dosEarlyThrew = false;
|
||||
try { sceRtcGetDosTime(&dosEarly, &dosTime); } catch (const std::exception&) { dosEarlyThrew = true; }
|
||||
Require(dosEarlyThrew);
|
||||
converted = RtcDateTime{1, 1, 1, 1, 1, 1, 1};
|
||||
Require(sceRtcSetDosTime(&converted, 0x585d645cu) == 0 && Equal(converted, RtcDateTime{2024, 2, 29, 12, 34, 56, 0}));
|
||||
Require(sceRtcSetDosTime(&converted, 0x7f9fbf7du) == 0 && Equal(converted, RtcDateTime{2043, 12, 31, 23, 59, 58, 0}));
|
||||
Require(sceRtcSetDosTime(&converted, 0) == 0 && Equal(converted, RtcDateTime{1980, 0, 0, 0, 0, 0, 0}));
|
||||
Require(sceRtcSetDosTime(nullptr, 0) == invalidPointer);
|
||||
bool dosHighThrew = false;
|
||||
try { sceRtcSetDosTime(&converted, 0x80210000u); } catch (const std::exception&) { dosHighThrew = true; }
|
||||
Require(dosHighThrew);
|
||||
|
||||
char text[32];
|
||||
tick.tick = leapDayTick;
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ Throughout the project, every function at every stage either **does exactly what
|
|||
- [libSceSystemService](../../core/libs/prx/libSceSystemService/Export.cpp) - `sceSystemServicePowerTick`, `sceSystemServiceReportAbnormalTermination`, `sceSystemServiceDisableMusicPlayer` and `sceSystemServiceReenableMusicPlayer` return success and do nothing: the host has no auto power-off timer to reset, no system crash reporter to notify and no system music player to pause or resume
|
||||
- [sceVideoOutOpen](../../core/libs/prx/libSceVideoOut/src/Output.cpp) validates the priority and CPU affinity that the open param requests for the VideoOut service thread but does not apply them: the port's present and vblank threads are host threads, and guest priorities and affinities do not reach host scheduling
|
||||
- Without `VK_KHR_fragment_shader_barycentric` the shader recompiler [does not load the barycentric VGPRs](../../core/shader/recompiler/Translation/src/InstructionTranslator.cpp): [`v_interp_p1_f32` is dropped and `v_interp_p2_f32` reads the attribute Vulkan interpolated](../../core/shader/recompiler/Translation/src/AttributeInstructions.cpp), so pixel shaders that use the barycentrics for anything other than `v_interp` get wrong values.
|
||||
- [sceRtcGetDosTime, sceRtcSetDosTime](../../core/libs/prx/libSceRtc/Export.cpp) (libSceRtc) - bit layout from shadPS4 (PS4, the standard FAT date/time). Years outside 1980-2107 (`GetDosTime`) and year fields above 63 (`SetDosTime`, where shadPS4 sign-extends the 16-bit date to years before 1980) throw, since no reference says what the library returns for them. `SetDosTime` does not validate the fields, as in shadPS4
|
||||
- [libSceAudio3d](../../core/libs/prx/libSceAudio3d/Export.cpp) - the port produces no sound: the library has no bed or object exports to give it audio, so `sceAudio3dPortPush` only paces the queue at `granularity` samples per frame at 48 kHz. `sceAudio3dPortSetAttribute` accepts the late reverb level and the downmix spread attributes and ignores them
|
||||
- [libSceAvPlayer](../../core/libs/prx/libSceAvPlayer/Export.cpp): `sceAvPlayerSetLogCallback` accepts a callback that is never called, as the player produces no log messages, and `sceAvPlayerSetAvailableBandwidth` has no effect, as it governs HLS sources, which `sceAvPlayerAddSource` does not implement.
|
||||
- [libSceNpTrophy2](../../core/libs/prx/libSceNpTrophy2/src/GameInfo.cpp): `sceNpTrophy2RegisterUnlockCallback` accepts a callback that is never called, as no trophy is ever unlocked, and `sceNpTrophy2UnregisterUnlockCallback` only returns success.
|
||||
|
|
|
|||
Loading…
Reference in New Issue