From 59fa217a7b7ec41aadd10e3128bbdabf54904b94 Mon Sep 17 00:00:00 2001 From: jn64 <23169302+jn64@users.noreply.github.com> Date: Fri, 9 Dec 2022 14:30:09 +0800 Subject: [PATCH 1/4] Draft manpage (pandoc Markdown) While Markdown isn't the best fit for writing manpages, it's the easiest for future contributions/maintenance. However, pandoc is a heavy dependency for producing a single manpage. Other tools [1] could be evaluated. The only pandoc-isms are the title block [2] (first 3 lines) which will rarely change, and the definition lists ':' for options which is self-explanatory. The Markdown source is intentionally not hard wrapped. pandoc automatically hard wraps the roff man output (which may be further re-wrapped by manpage viewers). To produce the manpage (outputs a file Cemu.1): pandoc -s -f markdown-smart -t man Cemu.1.md -o Cemu.1 Preview from Markdown without writing to file: pandoc -s -f markdown-smart -t man Cemu.1.md | man -l - markdown-smart *disables* the smart typography extension to avoid mangling '--'. [3] [1]: https://drewdevault.com/2018/05/13/scdoc.html [2]: https://pandoc.org/MANUAL.html#extension-pandoc_title_block [3]: https://pandoc.org/MANUAL.html#extensions --- dist/linux/Cemu.1.md | 85 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 dist/linux/Cemu.1.md diff --git a/dist/linux/Cemu.1.md b/dist/linux/Cemu.1.md new file mode 100644 index 00000000..08bf69fc --- /dev/null +++ b/dist/linux/Cemu.1.md @@ -0,0 +1,85 @@ +% CEMU(1) Cemu | Wii U emulator +% Exzap; Petergov +% 2022-12-09 + +# NAME + +Cemu - Wii U emulator + +# SYNOPSIS + +**Cemu** [_OPTIONS_...] + +# DESCRIPTION + +**Cemu** is a Wii U emulator that is able to run most Wii U games and homebrew in a playable state. It's written in C/C++ and is being actively developed with new features and fixes to increase compatibility, convenience and usability. + +# OPTIONS + +If an option has argument _n_, a value of 1 (or no argument) enables the option. A value of 0 disables the option. + +## Launch options + +**-g** _path_, **--game** _path_ + +: Path of game to launch + +**-m** _path_, **--mlc** _path_ + +: Custom mlc folder location + +**-f** [_n_], **--fullscreen** [_n_] + +: Launch games in fullscreen mode + +**-u** [_n_], **--ud** [_n_] + +: Render output upside-down + +**-a** _id_, **--account** _id_ + +: Persistent id of account + +**--force-interpreter** [_n_] + +: Force interpreter CPU emulation and disable recompiler + +**--act-url** _url_ + +: URL prefix for account server + +**--ecs-url** _url_ + +: URL for ECS service + +**-h**, **--help** + +: Display a usage message and exit + +**-v**, **--version** + +: Display Cemu version and exit + +## Extractor tool + +**-e** _path_, **--extract** _path_ + +: Path to WUD or WUX file for extraction + +**-p** _path_, **--path** _path_ + +: Path of file to extract (for example meta/meta.xml) + +**-o** _path_, **--output** _path_ + +: Output path for extracted file + +# BUGS + +To report a bug, visit _https://github.com/cemu-project/Cemu/issues_ + +# SEE ALSO + +Project homepage: + +_https://github.com/cemu-project/Cemu_ From 528fc53718d28a50db3377fcd246cb5fdd52c253 Mon Sep 17 00:00:00 2001 From: jn64 <23169302+jn64@users.noreply.github.com> Date: Fri, 9 Dec 2022 14:49:58 +0800 Subject: [PATCH 2/4] manpage sample output The roff manpage produced by pandoc is included in this commit, as well as a plaintext preview of what it would look like when viewed with 'man' in a terminal of 80 width. --- dist/linux/Cemu.1 | 73 +++++++++++++++++++++++++++++++++++++++++++ dist/linux/Cemu.1.txt | 71 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 144 insertions(+) create mode 100644 dist/linux/Cemu.1 create mode 100644 dist/linux/Cemu.1.txt diff --git a/dist/linux/Cemu.1 b/dist/linux/Cemu.1 new file mode 100644 index 00000000..110ead22 --- /dev/null +++ b/dist/linux/Cemu.1 @@ -0,0 +1,73 @@ +.\" Automatically generated by Pandoc 2.14.0.3 +.\" +.TH "CEMU" "1" "2022-12-09" "Cemu" "Wii U emulator" +.hy +.SH NAME +.PP +Cemu - Wii U emulator +.SH SYNOPSIS +.PP +\f[B]Cemu\f[R] [\f[I]OPTIONS\f[R]...] +.SH DESCRIPTION +.PP +\f[B]Cemu\f[R] is a Wii U emulator that is able to run most Wii U games +and homebrew in a playable state. +It\[aq]s written in C/C++ and is being actively developed with new +features and fixes to increase compatibility, convenience and usability. +.SH OPTIONS +.PP +If an option has argument \f[I]n\f[R], a value of 1 (or no argument) +enables the option. +A value of 0 disables the option. +.SS Launch options +.TP +\f[B]-g\f[R] \f[I]path\f[R], \f[B]--game\f[R] \f[I]path\f[R] +Path of game to launch +.TP +\f[B]-m\f[R] \f[I]path\f[R], \f[B]--mlc\f[R] \f[I]path\f[R] +Custom mlc folder location +.TP +\f[B]-f\f[R] [\f[I]n\f[R]], \f[B]--fullscreen\f[R] [\f[I]n\f[R]] +Launch games in fullscreen mode +.TP +\f[B]-u\f[R] [\f[I]n\f[R]], \f[B]--ud\f[R] [\f[I]n\f[R]] +Render output upside-down +.TP +\f[B]-a\f[R] \f[I]id\f[R], \f[B]--account\f[R] \f[I]id\f[R] +Persistent id of account +.TP +\f[B]--force-interpreter\f[R] [\f[I]n\f[R]] +Force interpreter CPU emulation and disable recompiler +.TP +\f[B]--act-url\f[R] \f[I]url\f[R] +URL prefix for account server +.TP +\f[B]--ecs-url\f[R] \f[I]url\f[R] +URL for ECS service +.TP +\f[B]-h\f[R], \f[B]--help\f[R] +Display a usage message and exit +.TP +\f[B]-v\f[R], \f[B]--version\f[R] +Display Cemu version and exit +.SS Extractor tool +.TP +\f[B]-e\f[R] \f[I]path\f[R], \f[B]--extract\f[R] \f[I]path\f[R] +Path to WUD or WUX file for extraction +.TP +\f[B]-p\f[R] \f[I]path\f[R], \f[B]--path\f[R] \f[I]path\f[R] +Path of file to extract (for example meta/meta.xml) +.TP +\f[B]-o\f[R] \f[I]path\f[R], \f[B]--output\f[R] \f[I]path\f[R] +Output path for extracted file +.SH BUGS +.PP +To report a bug, visit +\f[I]https://github.com/cemu-project/Cemu/issues\f[R] +.SH SEE ALSO +.PP +Project homepage: +.PP +\f[I]https://github.com/cemu-project/Cemu\f[R] +.SH AUTHORS +Exzap; Petergov. diff --git a/dist/linux/Cemu.1.txt b/dist/linux/Cemu.1.txt new file mode 100644 index 00000000..129b3138 --- /dev/null +++ b/dist/linux/Cemu.1.txt @@ -0,0 +1,71 @@ +CEMU(1) Wii U emulator CEMU(1) + +NAME + Cemu - Wii U emulator + +SYNOPSIS + Cemu [OPTIONS...] + +DESCRIPTION + Cemu is a Wii U emulator that is able to run most Wii U games and home‐ + brew in a playable state. It's written in C/C++ and is being actively + developed with new features and fixes to increase compatibility, conve‐ + nience and usability. + +OPTIONS + If an option has argument n, a value of 1 (or no argument) enables the + option. A value of 0 disables the option. + + Launch options + -g path, --game path + Path of game to launch + + -m path, --mlc path + Custom mlc folder location + + -f [n], --fullscreen [n] + Launch games in fullscreen mode + + -u [n], --ud [n] + Render output upside-down + + -a id, --account id + Persistent id of account + + --force-interpreter [n] + Force interpreter CPU emulation and disable recompiler + + --act-url url + URL prefix for account server + + --ecs-url url + URL for ECS service + + -h, --help + Display a usage message and exit + + -v, --version + Display Cemu version and exit + + Extractor tool + -e path, --extract path + Path to WUD or WUX file for extraction + + -p path, --path path + Path of file to extract (for example meta/meta.xml) + + -o path, --output path + Output path for extracted file + +BUGS + To report a bug, visit https://github.com/cemu-project/Cemu/issues + +SEE ALSO + Project homepage: + + https://github.com/cemu-project/Cemu + +AUTHORS + Exzap; Petergov. + +Cemu 2022-12-09 CEMU(1) From c714e8cb6bbf86b3430cb94159374cf83ed52df4 Mon Sep 17 00:00:00 2001 From: Exzap <13877693+Exzap@users.noreply.github.com> Date: Thu, 30 Jan 2025 03:32:24 +0100 Subject: [PATCH 3/4] coreinit: Time to tick conversion is unsigned The result is treated as signed in most cases, but the calculation uses unsigned arithmetic. As a concrete example where this matters, DS VC passes -1 (2^64-1) to OSWaitEventWithTimeout which internally causes an overflow. But only with unsigned arithmetic this will result in a large positive number that behaves like the intended infinite timeout. With signed arithmetic the result is negative and the events will timeout immediately. --- src/Cafe/OS/libs/coreinit/coreinit_Synchronization.cpp | 8 +++----- src/Cafe/OS/libs/coreinit/coreinit_Time.h | 4 ++-- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/Cafe/OS/libs/coreinit/coreinit_Synchronization.cpp b/src/Cafe/OS/libs/coreinit/coreinit_Synchronization.cpp index c144c384..e81cc577 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit_Synchronization.cpp +++ b/src/Cafe/OS/libs/coreinit/coreinit_Synchronization.cpp @@ -73,8 +73,6 @@ namespace coreinit } } - uint64 coreinit_getOSTime(); - bool OSWaitEventWithTimeout(OSEvent* event, uint64 timeout) { __OSLockScheduler(); @@ -95,14 +93,14 @@ namespace coreinit // workaround for a bad implementation in some Unity games (like Qube Directors Cut, see FEventWiiU::Wait) // where the the return value of OSWaitEventWithTimeout is ignored and instead the game measures the elapsed time to determine if a timeout occurred - timeout = timeout * 98ULL / 100ULL; // 98% (we want the function to return slightly before the actual timeout) + if (timeout < 0x00FFFFFFFFFFFFFFULL) + timeout = timeout * 98ULL / 100ULL; // 98% (we want the function to return slightly before the actual timeout) WaitEventWithTimeoutData data; data.thread = OSGetCurrentThread(); data.threadQueue = &event->threadQueue; data.hasTimeout = false; - - auto hostAlarm = coreinit::OSHostAlarmCreate(coreinit::coreinit_getOSTime() + coreinit::EspressoTime::ConvertNsToTimerTicks(timeout), 0, _OSWaitEventWithTimeoutHandler, &data); + auto hostAlarm = coreinit::OSHostAlarmCreate(OSGetTime() + coreinit::EspressoTime::ConvertNsToTimerTicks(timeout), 0, _OSWaitEventWithTimeoutHandler, &data); event->threadQueue.queueAndWait(OSGetCurrentThread()); coreinit::OSHostAlarmDestroy(hostAlarm); if (data.hasTimeout) diff --git a/src/Cafe/OS/libs/coreinit/coreinit_Time.h b/src/Cafe/OS/libs/coreinit/coreinit_Time.h index 3aa92b99..37bd5f88 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit_Time.h +++ b/src/Cafe/OS/libs/coreinit/coreinit_Time.h @@ -40,12 +40,12 @@ namespace coreinit inline TimerTicks ConvertNsToTimerTicks(uint64 ns) { - return ((GetTimerClock() / 31250LL) * ((TimerTicks)ns) / 32000LL); + return static_cast((static_cast(GetTimerClock()) / 31250ULL) * (ns) / 32000ULL); } inline TimerTicks ConvertMsToTimerTicks(uint64 ms) { - return (TimerTicks)ms * GetTimerClock() / 1000LL; + return static_cast(ms * static_cast(GetTimerClock()) / 1000ULL); } }; From ec2d7c086a3b2cc4f40897ae9978d4699e273b02 Mon Sep 17 00:00:00 2001 From: Exzap <13877693+Exzap@users.noreply.github.com> Date: Thu, 30 Jan 2025 03:49:17 +0100 Subject: [PATCH 4/4] coreinit: Clean up time functions --- .../Espresso/Recompiler/PPCRecompilerX64.cpp | 4 +-- .../HW/Latte/Core/LatteCommandProcessor.cpp | 2 +- src/Cafe/IOSU/legacy/iosu_acp.cpp | 6 ++-- src/Cafe/OS/libs/camera/camera.cpp | 2 +- src/Cafe/OS/libs/coreinit/coreinit_Alarm.cpp | 8 ++--- .../OS/libs/coreinit/coreinit_Spinlock.cpp | 8 ++--- src/Cafe/OS/libs/coreinit/coreinit_Thread.cpp | 2 +- src/Cafe/OS/libs/coreinit/coreinit_Time.cpp | 31 +++++++------------ src/Cafe/OS/libs/coreinit/coreinit_Time.h | 12 +++---- src/Cafe/OS/libs/dmae/dmae.cpp | 2 +- src/Cafe/OS/libs/gx2/GX2.cpp | 2 +- src/Cafe/OS/libs/gx2/GX2_Misc.cpp | 2 +- src/Cafe/OS/libs/nn_acp/nn_acp.cpp | 2 +- src/Cafe/OS/libs/padscore/padscore.cpp | 2 +- src/Cafe/OS/libs/vpad/vpad.cpp | 4 +-- .../dialogs/SaveImport/SaveImportWindow.cpp | 2 +- 16 files changed, 40 insertions(+), 51 deletions(-) diff --git a/src/Cafe/HW/Espresso/Recompiler/PPCRecompilerX64.cpp b/src/Cafe/HW/Espresso/Recompiler/PPCRecompilerX64.cpp index a30295b5..97b2c14c 100644 --- a/src/Cafe/HW/Espresso/Recompiler/PPCRecompilerX64.cpp +++ b/src/Cafe/HW/Espresso/Recompiler/PPCRecompilerX64.cpp @@ -114,13 +114,13 @@ void* ATTR_MS_ABI PPCRecompiler_virtualHLE(PPCInterpreter_t* hCPU, uint32 hleFun void ATTR_MS_ABI PPCRecompiler_getTBL(PPCInterpreter_t* hCPU, uint32 gprIndex) { - uint64 coreTime = coreinit::coreinit_getTimerTick(); + uint64 coreTime = coreinit::OSGetSystemTime(); hCPU->gpr[gprIndex] = (uint32)(coreTime&0xFFFFFFFF); } void ATTR_MS_ABI PPCRecompiler_getTBU(PPCInterpreter_t* hCPU, uint32 gprIndex) { - uint64 coreTime = coreinit::coreinit_getTimerTick(); + uint64 coreTime = coreinit::OSGetSystemTime(); hCPU->gpr[gprIndex] = (uint32)((coreTime>>32)&0xFFFFFFFF); } diff --git a/src/Cafe/HW/Latte/Core/LatteCommandProcessor.cpp b/src/Cafe/HW/Latte/Core/LatteCommandProcessor.cpp index a8f81901..f592cc9e 100644 --- a/src/Cafe/HW/Latte/Core/LatteCommandProcessor.cpp +++ b/src/Cafe/HW/Latte/Core/LatteCommandProcessor.cpp @@ -799,7 +799,7 @@ LatteCMDPtr LatteCP_itHLESampleTimer(LatteCMDPtr cmd, uint32 nWords) { cemu_assert_debug(nWords == 1); MPTR timerMPTR = (MPTR)LatteReadCMD(); - memory_writeU64(timerMPTR, coreinit::coreinit_getTimerTick()); + memory_writeU64(timerMPTR, coreinit::OSGetSystemTime()); return cmd; } diff --git a/src/Cafe/IOSU/legacy/iosu_acp.cpp b/src/Cafe/IOSU/legacy/iosu_acp.cpp index f5144ee6..6a9e6b89 100644 --- a/src/Cafe/IOSU/legacy/iosu_acp.cpp +++ b/src/Cafe/IOSU/legacy/iosu_acp.cpp @@ -469,7 +469,7 @@ namespace iosu entry->ukn0C = 0; entry->sizeA = _swapEndianU64(0); // ukn entry->sizeB = _swapEndianU64(dirSize); - entry->time = _swapEndianU64((coreinit::coreinit_getOSTime() / ESPRESSO_TIMER_CLOCK)); + entry->time = _swapEndianU64((coreinit::OSGetTime() / ESPRESSO_TIMER_CLOCK)); sprintf(entry->path, "%susr/save/%08x/%08x/meta/", devicePath, (uint32)(titleId >> 32), (uint32)(titleId & 0xFFFFFFFF)); count++; } @@ -504,7 +504,7 @@ namespace iosu entry->ukn0C = 0; entry->sizeA = _swapEndianU64(0); entry->sizeB = _swapEndianU64(0); - entry->time = _swapEndianU64((coreinit::coreinit_getOSTime() / ESPRESSO_TIMER_CLOCK)); + entry->time = _swapEndianU64((coreinit::OSGetTime() / ESPRESSO_TIMER_CLOCK)); sprintf(entry->path, "%susr/save/%08x/%08x/meta/", devicePath, (uint32)(titleId >> 32), (uint32)(titleId & 0xFFFFFFFF)); count++; } @@ -584,7 +584,7 @@ namespace iosu uint64 _ACPGetTimestamp() { - return coreinit::coreinit_getOSTime() / ESPRESSO_TIMER_CLOCK; + return coreinit::OSGetTime() / ESPRESSO_TIMER_CLOCK; } nnResult ACPUpdateSaveTimeStamp(uint32 persistentId, uint64 titleId, ACPDeviceType deviceType) diff --git a/src/Cafe/OS/libs/camera/camera.cpp b/src/Cafe/OS/libs/camera/camera.cpp index 03e01bfc..efb8013d 100644 --- a/src/Cafe/OS/libs/camera/camera.cpp +++ b/src/Cafe/OS/libs/camera/camera.cpp @@ -186,7 +186,7 @@ namespace camera if (g_cameraCounter == 0) { coreinit::OSCreateAlarm(g_alarm_camera.GetPtr()); - coreinit::OSSetPeriodicAlarm(g_alarm_camera.GetPtr(), coreinit::coreinit_getOSTime(), (uint64)ESPRESSO_TIMER_CLOCK / 60ull, RPLLoader_MakePPCCallable(ppcCAMUpdate60)); + coreinit::OSSetPeriodicAlarm(g_alarm_camera.GetPtr(), coreinit::OSGetTime(), (uint64)ESPRESSO_TIMER_CLOCK / 60ull, RPLLoader_MakePPCCallable(ppcCAMUpdate60)); } g_cameraCounter++; diff --git a/src/Cafe/OS/libs/coreinit/coreinit_Alarm.cpp b/src/Cafe/OS/libs/coreinit/coreinit_Alarm.cpp index f7e58115..ae2d1e63 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit_Alarm.cpp +++ b/src/Cafe/OS/libs/coreinit/coreinit_Alarm.cpp @@ -166,7 +166,7 @@ namespace coreinit void alarm_update() { cemu_assert_debug(!__OSHasSchedulerLock()); - uint64 currentTick = coreinit::coreinit_getOSTime(); + uint64 currentTick = coreinit::OSGetTime(); if (!OSHostAlarm::quickCheckForAlarm(currentTick)) return; __OSLockScheduler(); @@ -233,7 +233,7 @@ namespace coreinit if (period == 0) return; - uint64 currentTime = coreinit_getOSTime(); + uint64 currentTime = OSGetTime(); uint64 ticksSinceStart = currentTime - startTime; uint64 numPeriods = ticksSinceStart / period; @@ -267,7 +267,7 @@ namespace coreinit void OSSetAlarm(OSAlarm_t* alarm, uint64 delayInTicks, MPTR handlerFunc) { __OSLockScheduler(); - __OSInitiateAlarm(alarm, coreinit_getOSTime() + delayInTicks, 0, handlerFunc, false); + __OSInitiateAlarm(alarm, OSGetTime() + delayInTicks, 0, handlerFunc, false); __OSUnlockScheduler(); } @@ -310,7 +310,7 @@ namespace coreinit while( true ) { OSWaitEvent(g_alarmEvent.GetPtr()); - uint64 currentTick = coreinit_getOSTime(); + uint64 currentTick = OSGetTime(); while (true) { // get alarm to fire diff --git a/src/Cafe/OS/libs/coreinit/coreinit_Spinlock.cpp b/src/Cafe/OS/libs/coreinit/coreinit_Spinlock.cpp index 5201d441..3d235107 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit_Spinlock.cpp +++ b/src/Cafe/OS/libs/coreinit/coreinit_Spinlock.cpp @@ -86,11 +86,11 @@ namespace coreinit else { // loop until lock acquired or timeout occurred - uint64 timeoutValue = coreinit_getTimerTick() + coreinit::EspressoTime::ConvertNsToTimerTicks(timeout); + uint64 timeoutValue = OSGetSystemTime() + coreinit::EspressoTime::ConvertNsToTimerTicks(timeout); while (!spinlock->ownerThread.atomic_compare_exchange(nullptr, currentThread)) { OSYieldThread(); - if (coreinit_getTimerTick() >= timeoutValue) + if (OSGetSystemTime() >= timeoutValue) { return false; } @@ -182,11 +182,11 @@ namespace coreinit else { // loop until lock acquired or timeout occurred - uint64 timeoutValue = coreinit_getTimerTick() + coreinit::EspressoTime::ConvertNsToTimerTicks(timeout); + uint64 timeoutValue = OSGetSystemTime() + coreinit::EspressoTime::ConvertNsToTimerTicks(timeout); while (!spinlock->ownerThread.atomic_compare_exchange(nullptr, currentThread)) { OSYieldThread(); - if (coreinit_getTimerTick() >= timeoutValue) + if (OSGetSystemTime() >= timeoutValue) { return false; } diff --git a/src/Cafe/OS/libs/coreinit/coreinit_Thread.cpp b/src/Cafe/OS/libs/coreinit/coreinit_Thread.cpp index db457047..870d1850 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit_Thread.cpp +++ b/src/Cafe/OS/libs/coreinit/coreinit_Thread.cpp @@ -655,7 +655,7 @@ namespace coreinit StackAllocator _threadQueue; OSInitThreadQueue(_threadQueue.GetPointer()); __OSLockScheduler(); - OSHostAlarm* hostAlarm = OSHostAlarmCreate(coreinit_getOSTime() + ticks, 0, _OSSleepTicks_alarmHandler, _threadQueue.GetPointer()); + OSHostAlarm* hostAlarm = OSHostAlarmCreate(OSGetTime() + ticks, 0, _OSSleepTicks_alarmHandler, _threadQueue.GetPointer()); _threadQueue.GetPointer()->queueAndWait(OSGetCurrentThread()); OSHostAlarmDestroy(hostAlarm); __OSUnlockScheduler(); diff --git a/src/Cafe/OS/libs/coreinit/coreinit_Time.cpp b/src/Cafe/OS/libs/coreinit/coreinit_Time.cpp index d6fc27b2..50a404f4 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit_Time.cpp +++ b/src/Cafe/OS/libs/coreinit/coreinit_Time.cpp @@ -3,38 +3,32 @@ namespace coreinit { - - uint64 coreinit_getTimerTick() + uint64 coreinit_GetMFTB() { // bus clock is 1/5th of core clock // timer clock is 1/4th of bus clock return PPCInterpreter_getMainCoreCycleCounter() / 20ULL; } - uint64 coreinit_getOSTime() + uint64 OSGetSystemTime() { - return coreinit_getTimerTick() + ppcCyclesSince2000TimerClock; - } - - void export_OSGetTick(PPCInterpreter_t* hCPU) - { - uint64 osTime = coreinit_getOSTime(); - osLib_returnFromFunction(hCPU, (uint32)osTime); + return coreinit_GetMFTB(); } uint64 OSGetTime() { - return coreinit_getOSTime(); + return OSGetSystemTime() + ppcCyclesSince2000TimerClock; } - void export_OSGetSystemTime(PPCInterpreter_t* hCPU) + uint32 OSGetSystemTick() { - osLib_returnFromFunction64(hCPU, coreinit_getTimerTick()); + return static_cast(coreinit_GetMFTB()); } - void export_OSGetSystemTick(PPCInterpreter_t* hCPU) + uint32 OSGetTick() { - osLib_returnFromFunction(hCPU, (uint32)coreinit_getTimerTick()); + uint64 osTime = OSGetTime(); + return static_cast(osTime); } uint32 getLeapDaysUntilYear(uint32 year) @@ -360,14 +354,13 @@ namespace coreinit void InitializeTimeAndCalendar() { cafeExportRegister("coreinit", OSGetTime, LogType::Placeholder); - osLib_addFunction("coreinit", "OSGetSystemTime", export_OSGetSystemTime); - osLib_addFunction("coreinit", "OSGetTick", export_OSGetTick); - osLib_addFunction("coreinit", "OSGetSystemTick", export_OSGetSystemTick); + cafeExportRegister("coreinit", OSGetSystemTime, LogType::Placeholder); + cafeExportRegister("coreinit", OSGetTick, LogType::Placeholder); + cafeExportRegister("coreinit", OSGetSystemTick, LogType::Placeholder); cafeExportRegister("coreinit", OSTicksToCalendarTime, LogType::Placeholder); cafeExportRegister("coreinit", OSCalendarTimeToTicks, LogType::Placeholder); - //timeTest(); } }; \ No newline at end of file diff --git a/src/Cafe/OS/libs/coreinit/coreinit_Time.h b/src/Cafe/OS/libs/coreinit/coreinit_Time.h index 37bd5f88..380ccf1d 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit_Time.h +++ b/src/Cafe/OS/libs/coreinit/coreinit_Time.h @@ -50,15 +50,11 @@ namespace coreinit }; void OSTicksToCalendarTime(uint64 ticks, OSCalendarTime_t* calenderStruct); + + uint64 OSGetSystemTime(); uint64 OSGetTime(); - - uint64 coreinit_getOSTime(); - uint64 coreinit_getTimerTick(); - - static uint64 OSGetSystemTime() - { - return coreinit_getTimerTick(); - } + uint32 OSGetSystemTick(); + uint32 OSGetTick(); void InitializeTimeAndCalendar(); }; diff --git a/src/Cafe/OS/libs/dmae/dmae.cpp b/src/Cafe/OS/libs/dmae/dmae.cpp index 6b3e8d0d..7c513784 100644 --- a/src/Cafe/OS/libs/dmae/dmae.cpp +++ b/src/Cafe/OS/libs/dmae/dmae.cpp @@ -11,7 +11,7 @@ uint64 dmaeRetiredTimestamp = 0; uint64 dmae_getTimestamp() { - return coreinit::coreinit_getTimerTick(); + return coreinit::OSGetSystemTime(); } void dmae_setRetiredTimestamp(uint64 timestamp) diff --git a/src/Cafe/OS/libs/gx2/GX2.cpp b/src/Cafe/OS/libs/gx2/GX2.cpp index c2ea34a4..593d31fb 100644 --- a/src/Cafe/OS/libs/gx2/GX2.cpp +++ b/src/Cafe/OS/libs/gx2/GX2.cpp @@ -322,7 +322,7 @@ uint64 _prevReturnedGPUTime = 0; uint64 Latte_GetTime() { - uint64 gpuTime = coreinit::coreinit_getTimerTick(); + uint64 gpuTime = coreinit::OSGetSystemTime(); gpuTime *= 20000ULL; if (gpuTime <= _prevReturnedGPUTime) gpuTime = _prevReturnedGPUTime + 1; // avoid ever returning identical timestamps diff --git a/src/Cafe/OS/libs/gx2/GX2_Misc.cpp b/src/Cafe/OS/libs/gx2/GX2_Misc.cpp index 2111238a..3c7ea3f9 100644 --- a/src/Cafe/OS/libs/gx2/GX2_Misc.cpp +++ b/src/Cafe/OS/libs/gx2/GX2_Misc.cpp @@ -54,7 +54,7 @@ void gx2Export_GX2GetGPUTimeout(PPCInterpreter_t* hCPU) void gx2Export_GX2SampleTopGPUCycle(PPCInterpreter_t* hCPU) { cemuLog_log(LogType::GX2, "GX2SampleTopGPUCycle(0x{:08x})", hCPU->gpr[3]); - memory_writeU64(hCPU->gpr[3], coreinit::coreinit_getTimerTick()); + memory_writeU64(hCPU->gpr[3], coreinit::OSGetSystemTime()); osLib_returnFromFunction(hCPU, 0); } diff --git a/src/Cafe/OS/libs/nn_acp/nn_acp.cpp b/src/Cafe/OS/libs/nn_acp/nn_acp.cpp index 37ea471f..9cde0213 100644 --- a/src/Cafe/OS/libs/nn_acp/nn_acp.cpp +++ b/src/Cafe/OS/libs/nn_acp/nn_acp.cpp @@ -315,7 +315,7 @@ namespace acp ppcDefineParamU32BEPtr(timestamp64, 0); ppcDefineParamU32BEPtr(ukn, 1); // probably timezone or offset? Could also be a bool for success/failed - uint64 t = coreinit::coreinit_getOSTime() + (uint64)((sint64)(ppcCyclesSince2000_UTC - ppcCyclesSince2000) / 20LL); + uint64 t = coreinit::OSGetTime() + (uint64)((sint64)(ppcCyclesSince2000_UTC - ppcCyclesSince2000) / 20LL); timestamp64[0] = (uint32)(t >> 32); timestamp64[1] = (uint32)(t & 0xFFFFFFFF); diff --git a/src/Cafe/OS/libs/padscore/padscore.cpp b/src/Cafe/OS/libs/padscore/padscore.cpp index 0a577b97..2f359748 100644 --- a/src/Cafe/OS/libs/padscore/padscore.cpp +++ b/src/Cafe/OS/libs/padscore/padscore.cpp @@ -760,7 +760,7 @@ namespace padscore void start() { OSCreateAlarm(&g_padscore.alarm); - const uint64 start_tick = coreinit::coreinit_getOSTime(); + const uint64 start_tick = coreinit::OSGetTime(); const uint64 period_tick = coreinit::EspressoTime::GetTimerClock() / 200; // every 5ms MPTR handler = PPCInterpreter_makeCallableExportDepr(TickFunction); OSSetPeriodicAlarm(&g_padscore.alarm, start_tick, period_tick, handler); diff --git a/src/Cafe/OS/libs/vpad/vpad.cpp b/src/Cafe/OS/libs/vpad/vpad.cpp index ded4304d..21c1c9e5 100644 --- a/src/Cafe/OS/libs/vpad/vpad.cpp +++ b/src/Cafe/OS/libs/vpad/vpad.cpp @@ -267,7 +267,7 @@ namespace vpad { if (channel <= 1 && vpadDelayEnabled) { - uint64 currentTime = coreinit::coreinit_getOSTime(); + uint64 currentTime = coreinit::OSGetTime(); const auto dif = currentTime - vpad::g_vpad.controller_data[channel].drcLastCallTime; if (dif <= (ESPRESSO_TIMER_CLOCK / 60ull)) { @@ -1149,7 +1149,7 @@ namespace vpad void start() { coreinit::OSCreateAlarm(&g_vpad.alarm); - const uint64 start_tick = coreinit::coreinit_getOSTime(); + const uint64 start_tick = coreinit::OSGetTime(); const uint64 period_tick = coreinit::EspressoTime::GetTimerClock() * 5 / 1000; const MPTR handler = PPCInterpreter_makeCallableExportDepr(TickFunction); coreinit::OSSetPeriodicAlarm(&g_vpad.alarm, start_tick, period_tick, handler); diff --git a/src/gui/dialogs/SaveImport/SaveImportWindow.cpp b/src/gui/dialogs/SaveImport/SaveImportWindow.cpp index b31f24b2..1b1fecbf 100644 --- a/src/gui/dialogs/SaveImport/SaveImportWindow.cpp +++ b/src/gui/dialogs/SaveImport/SaveImportWindow.cpp @@ -304,7 +304,7 @@ void SaveImportWindow::OnImport(wxCommandEvent& event) auto new_node = info_node.append_child("account"); new_node.append_attribute("persistentId").set_value(new_persistend_id_string.c_str()); auto timestamp = new_node.append_child("timestamp"); - timestamp.text().set(fmt::format("{:016x}", coreinit::coreinit_getOSTime() / ESPRESSO_TIMER_CLOCK).c_str()); // TODO time not initialized yet? + timestamp.text().set(fmt::format("{:016x}", coreinit::OSGetTime() / ESPRESSO_TIMER_CLOCK).c_str()); // TODO time not initialized yet? if(!doc.save_file(saveinfo.c_str())) cemuLog_log(LogType::Force, "couldn't insert save entry in saveinfo.xml: {}", _pathToUtf8(saveinfo));