diff --git a/frontend/drivers/platform_wiiu.c b/frontend/drivers/platform_wiiu.c index a7382bbfed..2ad2a41ae2 100644 --- a/frontend/drivers/platform_wiiu.c +++ b/frontend/drivers/platform_wiiu.c @@ -507,11 +507,6 @@ int main(int argc, char **argv) return 0; } -unsigned long _times_r(struct _reent *r, struct tms *tmsbuf) -{ - return 0; -} - void __eabi(void) { diff --git a/wiiu/system/imports.h b/wiiu/system/imports.h index 35c6c555a4..27670203e3 100644 --- a/wiiu/system/imports.h +++ b/wiiu/system/imports.h @@ -34,6 +34,7 @@ IMPORT(OSGetCoreId); IMPORT(OSIsMainCore); IMPORT(OSGetSystemTime); IMPORT(OSGetSystemTick); +IMPORT(OSGetTime); IMPORT(OSGetSymbolName); IMPORT(OSGetSharedData); IMPORT(OSEffectiveToPhysical); diff --git a/wiiu/system/missing_libc_functions.c b/wiiu/system/missing_libc_functions.c index 2ebd6f9fda..577a66d3ff 100644 --- a/wiiu/system/missing_libc_functions.c +++ b/wiiu/system/missing_libc_functions.c @@ -7,6 +7,9 @@ #include #include #include +#include +#include +#include /* This is usually in libogc; we can't use that on wiiu */ int usleep(useconds_t microseconds) { @@ -51,11 +54,62 @@ struct passwd* getpwuid(uid_t uid) { return &out; } -/* Try to vaugely spoof the POISX clock. Epoch is off by about 30 */ -/* years, so this could be better... */ -/* Only has second accuracy since I'm lazy. */ +/* Basic Cafe OS clock thingy. */ +int _gettimeofday_r(struct _reent *ptr, + struct timeval* ptimeval, + void* ptimezone) { + + OSTime cosTime; + uint64_t cosSecs; + uint32_t cosUSecs; + time_t unixSecs; + +/* We need somewhere to put our output */ + if (ptimeval == NULL) { + errno = EFAULT; + return -1; + } + +/* Get Cafe OS clock in seconds; epoch 2000-01-01 00:00 */ + cosTime = OSGetTime(); + cosSecs = ticks_to_sec(cosTime); + +/* Get extra milliseconds */ + cosUSecs = ticks_to_us(cosTime) - (cosSecs * 1000000); + +/* Convert to Unix time, epoch 1970-01-01 00:00. + Constant value is seconds between 1970 and 2000. + time_t is 32bit here, so the Wii U is vulnerable to the 2038 problem. */ + unixSecs = cosSecs + 946684800; + + ptimeval->tv_sec = unixSecs; + ptimeval->tv_usec = cosUSecs; + return 0; +} + +/* POSIX clock in all its glory */ int clock_gettime(clockid_t clk_id, struct timespec* tp) { - int64_t time_usec = cpu_features_get_time_usec(); - tp->tv_sec = time_usec / 1000000; + struct timeval ptimeval = { 0 }; + int ret = 0; + OSTime cosTime; + + if (tp == NULL) { + errno = EFAULT; + return -1; + } + + switch (clk_id) { + case CLOCK_REALTIME: + /* Just wrap gettimeofday. Cheating, I know. */ + ret = _gettimeofday_r(NULL, &ptimeval, NULL); + if (ret) return -1; + + tp->tv_sec = ptimeval.tv_sec; + tp->tv_nsec = ptimeval.tv_usec * 1000; + break; + default: + errno = EINVAL; + return -1; + } return 0; }