From db54bffe14b71fc82da95dd5df6ed3e77e3067d3 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 5 May 2013 10:12:29 -0700 Subject: [PATCH] Use a base time throughout rtc and kernel time. This way, time doesn't move abnormally as far as the game can tell, even when savestates and fast forward and pause are used. --- Core/HLE/sceKernel.cpp | 3 +++ Core/HLE/sceKernelTime.cpp | 37 ++++++++++--------------------------- Core/HLE/sceRtc.cpp | 33 ++++++++++++++++++++++++++++++--- Core/HLE/sceRtc.h | 7 +++++-- 4 files changed, 48 insertions(+), 32 deletions(-) diff --git a/Core/HLE/sceKernel.cpp b/Core/HLE/sceKernel.cpp index b37fce7859..176b136108 100644 --- a/Core/HLE/sceKernel.cpp +++ b/Core/HLE/sceKernel.cpp @@ -57,6 +57,7 @@ #include "scePower.h" #include "sceUtility.h" #include "sceUmd.h" +#include "sceRtc.h" #include "sceSsl.h" #include "sceSas.h" #include "scePsmf.h" @@ -108,6 +109,7 @@ void __KernelInit() __MpegInit(PSP_CoreParameter().useMediaEngine); __PsmfInit(); __CtrlInit(); + __RtcInit(); __SslInit(); __ImposeInit(); __UsbInit(); @@ -201,6 +203,7 @@ void __KernelDoState(PointerWrap &p) __PowerDoState(p); __PsmfDoState(p); __PsmfPlayerDoState(p); + __RtcDoState(p); __SasDoState(p); __SslDoState(p); __UmdDoState(p); diff --git a/Core/HLE/sceKernelTime.cpp b/Core/HLE/sceKernelTime.cpp index 4eb23f8475..97590acb1d 100644 --- a/Core/HLE/sceKernelTime.cpp +++ b/Core/HLE/sceKernelTime.cpp @@ -24,14 +24,12 @@ #include -#include "HLE.h" -#include "../MIPS/MIPS.h" - -#include "sceKernel.h" -#include "sceKernelTime.h" - -#include "../CoreTiming.h" -#include "ChunkFile.h" +#include "Common/ChunkFile.h" +#include "Core/CoreTiming.h" +#include "Core/HLE/HLE.h" +#include "Core/HLE/sceKernel.h" +#include "Core/HLE/sceKernelTime.h" +#include "Core/HLE/sceRtc.h" ////////////////////////////////////////////////////////////////////////// // State @@ -160,27 +158,12 @@ u32 sceKernelLibcTime(u32 outPtr) u32 sceKernelLibcGettimeofday(u32 timeAddr, u32 tzAddr) { // TODO: tzAddr? -#ifdef _WIN32 - union { - s64 ns100; /*time since 1 Jan 1601 in 100ns units */ - FILETIME ft; - } now; - - struct timeval + if (Memory::IsValidAddress(timeAddr)) { - u32 tv_sec; - u32 tv_usec; - }; + timeval *tv = (timeval *)Memory::GetPointer(timeAddr); + __RtcTimeOfDay(tv); + } - timeval *tv = (timeval*)Memory::GetPointer(timeAddr); - - GetSystemTimeAsFileTime (&now.ft); - tv->tv_usec = (long) ((now.ns100 / 10LL) % 1000000LL); - tv->tv_sec = (long) ((now.ns100 - 116444736000000000LL) / 10000000LL); -#else - timeval *tv = (timeval*)Memory::GetPointer(timeAddr); - gettimeofday(tv, NULL); -#endif DEBUG_LOG(HLE,"sceKernelLibcGettimeofday(%08x, %08x)", timeAddr, tzAddr); hleEatCycles(1885); return 0; diff --git a/Core/HLE/sceRtc.cpp b/Core/HLE/sceRtc.cpp index 7a9286186e..1295f7e0ba 100644 --- a/Core/HLE/sceRtc.cpp +++ b/Core/HLE/sceRtc.cpp @@ -31,6 +31,10 @@ #include "sceRtc.h" #include "../CoreTiming.h" +// This is a base time that everything is relative to. +// This way, time doesn't move strangely with savestates, turbo speed, etc. +static timeval rtcBaseTime; + // Grabbed from JPSCP // This is # of microseconds between January 1, 0001 and January 1, 1970. const u64 rtcMagicOffset = 62135596800000000L; @@ -72,7 +76,6 @@ time_t rtc_timegm(struct tm *tm) return _mkgmtime(&modified); } -// TODO: Who has timegm? #elif defined(__GLIBC__) && !defined(ANDROID) #define rtc_timegm timegm #else @@ -100,6 +103,30 @@ time_t rtc_timegm(struct tm *tm) #endif +void __RtcInit() +{ + // This is the base time, the only case we use gettimeofday() for. + // Everything else is relative to that, "virtual time." + gettimeofday(&rtcBaseTime, NULL); +} + +void __RtcDoState(PointerWrap &p) +{ + p.Do(rtcBaseTime); + + p.DoMarker("sceRtc"); +} + +void __RtcTimeOfDay(timeval *tv) +{ + s64 additionalUs = cyclesToUs(CoreTiming::GetTicks()); + *tv = rtcBaseTime; + + s64 adjustedUs = additionalUs + tv->tv_usec; + tv->tv_sec += long(adjustedUs / 1000000UL); + tv->tv_usec = adjustedUs % 1000000UL; +} + void __RtcTmToPspTime(ScePspDateTime &t, tm *val) { t.year = val->tm_year + 1900; @@ -207,7 +234,7 @@ u32 sceRtcGetCurrentClock(u32 pspTimePtr, int tz) { DEBUG_LOG(HLE, "sceRtcGetCurrentClock(%08x, %d)", pspTimePtr, tz); timeval tv; - gettimeofday(&tv, NULL); + __RtcTimeOfDay(&tv); time_t sec = (time_t) tv.tv_sec; tm *utc = gmtime(&sec); @@ -236,7 +263,7 @@ u32 sceRtcGetCurrentClockLocalTime(u32 pspTimePtr) { DEBUG_LOG(HLE, "sceRtcGetCurrentClockLocalTime(%08x)", pspTimePtr); timeval tv; - gettimeofday(&tv, NULL); + __RtcTimeOfDay(&tv); time_t sec = (time_t) tv.tv_sec; tm *local = localtime(&sec); diff --git a/Core/HLE/sceRtc.h b/Core/HLE/sceRtc.h index cfba0c4ece..95288cdd9e 100644 --- a/Core/HLE/sceRtc.h +++ b/Core/HLE/sceRtc.h @@ -17,9 +17,12 @@ #pragma once -void sceRtcGetCurrentTick(); -int sceRtcGetLastAdjustedTime(u32 tickPtr); +struct timeval; +void __RtcTimeOfDay(timeval *tv); + void Register_sceRtc(); +void __RtcInit(); +void __RtcDoState(PointerWrap &p); struct ScePspDateTime { unsigned short year;