Compare commits

...

5 commits

Author SHA1 Message Date
jn64
e54d213fcf
Merge 528fc53718 into ec2d7c086a 2025-01-30 12:21:13 -05:00
Exzap
ec2d7c086a coreinit: Clean up time functions
Some checks failed
Generate translation template / generate-pot (push) Failing after 34s
Build check / build (push) Failing after 40s
2025-01-30 03:49:17 +01:00
Exzap
c714e8cb6b 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.
2025-01-30 03:32:24 +01:00
jn64
528fc53718 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.
2022-12-09 15:26:54 +08:00
jn64
59fa217a7b 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
2022-12-09 15:25:59 +08:00
20 changed files with 274 additions and 58 deletions

73
dist/linux/Cemu.1 vendored Normal file
View file

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

85
dist/linux/Cemu.1.md vendored Normal file
View file

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

71
dist/linux/Cemu.1.txt vendored Normal file
View file

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

View file

@ -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) 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); hCPU->gpr[gprIndex] = (uint32)(coreTime&0xFFFFFFFF);
} }
void ATTR_MS_ABI PPCRecompiler_getTBU(PPCInterpreter_t* hCPU, uint32 gprIndex) 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); hCPU->gpr[gprIndex] = (uint32)((coreTime>>32)&0xFFFFFFFF);
} }

View file

@ -799,7 +799,7 @@ LatteCMDPtr LatteCP_itHLESampleTimer(LatteCMDPtr cmd, uint32 nWords)
{ {
cemu_assert_debug(nWords == 1); cemu_assert_debug(nWords == 1);
MPTR timerMPTR = (MPTR)LatteReadCMD(); MPTR timerMPTR = (MPTR)LatteReadCMD();
memory_writeU64(timerMPTR, coreinit::coreinit_getTimerTick()); memory_writeU64(timerMPTR, coreinit::OSGetSystemTime());
return cmd; return cmd;
} }

View file

@ -469,7 +469,7 @@ namespace iosu
entry->ukn0C = 0; entry->ukn0C = 0;
entry->sizeA = _swapEndianU64(0); // ukn entry->sizeA = _swapEndianU64(0); // ukn
entry->sizeB = _swapEndianU64(dirSize); 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)); sprintf(entry->path, "%susr/save/%08x/%08x/meta/", devicePath, (uint32)(titleId >> 32), (uint32)(titleId & 0xFFFFFFFF));
count++; count++;
} }
@ -504,7 +504,7 @@ namespace iosu
entry->ukn0C = 0; entry->ukn0C = 0;
entry->sizeA = _swapEndianU64(0); entry->sizeA = _swapEndianU64(0);
entry->sizeB = _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)); sprintf(entry->path, "%susr/save/%08x/%08x/meta/", devicePath, (uint32)(titleId >> 32), (uint32)(titleId & 0xFFFFFFFF));
count++; count++;
} }
@ -584,7 +584,7 @@ namespace iosu
uint64 _ACPGetTimestamp() uint64 _ACPGetTimestamp()
{ {
return coreinit::coreinit_getOSTime() / ESPRESSO_TIMER_CLOCK; return coreinit::OSGetTime() / ESPRESSO_TIMER_CLOCK;
} }
nnResult ACPUpdateSaveTimeStamp(uint32 persistentId, uint64 titleId, ACPDeviceType deviceType) nnResult ACPUpdateSaveTimeStamp(uint32 persistentId, uint64 titleId, ACPDeviceType deviceType)

View file

@ -186,7 +186,7 @@ namespace camera
if (g_cameraCounter == 0) if (g_cameraCounter == 0)
{ {
coreinit::OSCreateAlarm(g_alarm_camera.GetPtr()); 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++; g_cameraCounter++;

View file

@ -166,7 +166,7 @@ namespace coreinit
void alarm_update() void alarm_update()
{ {
cemu_assert_debug(!__OSHasSchedulerLock()); cemu_assert_debug(!__OSHasSchedulerLock());
uint64 currentTick = coreinit::coreinit_getOSTime(); uint64 currentTick = coreinit::OSGetTime();
if (!OSHostAlarm::quickCheckForAlarm(currentTick)) if (!OSHostAlarm::quickCheckForAlarm(currentTick))
return; return;
__OSLockScheduler(); __OSLockScheduler();
@ -233,7 +233,7 @@ namespace coreinit
if (period == 0) if (period == 0)
return; return;
uint64 currentTime = coreinit_getOSTime(); uint64 currentTime = OSGetTime();
uint64 ticksSinceStart = currentTime - startTime; uint64 ticksSinceStart = currentTime - startTime;
uint64 numPeriods = ticksSinceStart / period; uint64 numPeriods = ticksSinceStart / period;
@ -267,7 +267,7 @@ namespace coreinit
void OSSetAlarm(OSAlarm_t* alarm, uint64 delayInTicks, MPTR handlerFunc) void OSSetAlarm(OSAlarm_t* alarm, uint64 delayInTicks, MPTR handlerFunc)
{ {
__OSLockScheduler(); __OSLockScheduler();
__OSInitiateAlarm(alarm, coreinit_getOSTime() + delayInTicks, 0, handlerFunc, false); __OSInitiateAlarm(alarm, OSGetTime() + delayInTicks, 0, handlerFunc, false);
__OSUnlockScheduler(); __OSUnlockScheduler();
} }
@ -310,7 +310,7 @@ namespace coreinit
while( true ) while( true )
{ {
OSWaitEvent(g_alarmEvent.GetPtr()); OSWaitEvent(g_alarmEvent.GetPtr());
uint64 currentTick = coreinit_getOSTime(); uint64 currentTick = OSGetTime();
while (true) while (true)
{ {
// get alarm to fire // get alarm to fire

View file

@ -86,11 +86,11 @@ namespace coreinit
else else
{ {
// loop until lock acquired or timeout occurred // 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)) while (!spinlock->ownerThread.atomic_compare_exchange(nullptr, currentThread))
{ {
OSYieldThread(); OSYieldThread();
if (coreinit_getTimerTick() >= timeoutValue) if (OSGetSystemTime() >= timeoutValue)
{ {
return false; return false;
} }
@ -182,11 +182,11 @@ namespace coreinit
else else
{ {
// loop until lock acquired or timeout occurred // 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)) while (!spinlock->ownerThread.atomic_compare_exchange(nullptr, currentThread))
{ {
OSYieldThread(); OSYieldThread();
if (coreinit_getTimerTick() >= timeoutValue) if (OSGetSystemTime() >= timeoutValue)
{ {
return false; return false;
} }

View file

@ -73,8 +73,6 @@ namespace coreinit
} }
} }
uint64 coreinit_getOSTime();
bool OSWaitEventWithTimeout(OSEvent* event, uint64 timeout) bool OSWaitEventWithTimeout(OSEvent* event, uint64 timeout)
{ {
__OSLockScheduler(); __OSLockScheduler();
@ -95,14 +93,14 @@ namespace coreinit
// workaround for a bad implementation in some Unity games (like Qube Directors Cut, see FEventWiiU::Wait) // 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 // 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; WaitEventWithTimeoutData data;
data.thread = OSGetCurrentThread(); data.thread = OSGetCurrentThread();
data.threadQueue = &event->threadQueue; data.threadQueue = &event->threadQueue;
data.hasTimeout = false; data.hasTimeout = false;
auto hostAlarm = coreinit::OSHostAlarmCreate(OSGetTime() + coreinit::EspressoTime::ConvertNsToTimerTicks(timeout), 0, _OSWaitEventWithTimeoutHandler, &data);
auto hostAlarm = coreinit::OSHostAlarmCreate(coreinit::coreinit_getOSTime() + coreinit::EspressoTime::ConvertNsToTimerTicks(timeout), 0, _OSWaitEventWithTimeoutHandler, &data);
event->threadQueue.queueAndWait(OSGetCurrentThread()); event->threadQueue.queueAndWait(OSGetCurrentThread());
coreinit::OSHostAlarmDestroy(hostAlarm); coreinit::OSHostAlarmDestroy(hostAlarm);
if (data.hasTimeout) if (data.hasTimeout)

View file

@ -655,7 +655,7 @@ namespace coreinit
StackAllocator<OSThreadQueue> _threadQueue; StackAllocator<OSThreadQueue> _threadQueue;
OSInitThreadQueue(_threadQueue.GetPointer()); OSInitThreadQueue(_threadQueue.GetPointer());
__OSLockScheduler(); __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()); _threadQueue.GetPointer()->queueAndWait(OSGetCurrentThread());
OSHostAlarmDestroy(hostAlarm); OSHostAlarmDestroy(hostAlarm);
__OSUnlockScheduler(); __OSUnlockScheduler();

View file

@ -3,38 +3,32 @@
namespace coreinit namespace coreinit
{ {
uint64 coreinit_GetMFTB()
uint64 coreinit_getTimerTick()
{ {
// bus clock is 1/5th of core clock // bus clock is 1/5th of core clock
// timer clock is 1/4th of bus clock // timer clock is 1/4th of bus clock
return PPCInterpreter_getMainCoreCycleCounter() / 20ULL; return PPCInterpreter_getMainCoreCycleCounter() / 20ULL;
} }
uint64 coreinit_getOSTime() uint64 OSGetSystemTime()
{ {
return coreinit_getTimerTick() + ppcCyclesSince2000TimerClock; return coreinit_GetMFTB();
}
void export_OSGetTick(PPCInterpreter_t* hCPU)
{
uint64 osTime = coreinit_getOSTime();
osLib_returnFromFunction(hCPU, (uint32)osTime);
} }
uint64 OSGetTime() uint64 OSGetTime()
{ {
return coreinit_getOSTime(); return OSGetSystemTime() + ppcCyclesSince2000TimerClock;
} }
void export_OSGetSystemTime(PPCInterpreter_t* hCPU) uint32 OSGetSystemTick()
{ {
osLib_returnFromFunction64(hCPU, coreinit_getTimerTick()); return static_cast<uint32>(coreinit_GetMFTB());
} }
void export_OSGetSystemTick(PPCInterpreter_t* hCPU) uint32 OSGetTick()
{ {
osLib_returnFromFunction(hCPU, (uint32)coreinit_getTimerTick()); uint64 osTime = OSGetTime();
return static_cast<uint32>(osTime);
} }
uint32 getLeapDaysUntilYear(uint32 year) uint32 getLeapDaysUntilYear(uint32 year)
@ -360,14 +354,13 @@ namespace coreinit
void InitializeTimeAndCalendar() void InitializeTimeAndCalendar()
{ {
cafeExportRegister("coreinit", OSGetTime, LogType::Placeholder); cafeExportRegister("coreinit", OSGetTime, LogType::Placeholder);
osLib_addFunction("coreinit", "OSGetSystemTime", export_OSGetSystemTime); cafeExportRegister("coreinit", OSGetSystemTime, LogType::Placeholder);
osLib_addFunction("coreinit", "OSGetTick", export_OSGetTick); cafeExportRegister("coreinit", OSGetTick, LogType::Placeholder);
osLib_addFunction("coreinit", "OSGetSystemTick", export_OSGetSystemTick); cafeExportRegister("coreinit", OSGetSystemTick, LogType::Placeholder);
cafeExportRegister("coreinit", OSTicksToCalendarTime, LogType::Placeholder); cafeExportRegister("coreinit", OSTicksToCalendarTime, LogType::Placeholder);
cafeExportRegister("coreinit", OSCalendarTimeToTicks, LogType::Placeholder); cafeExportRegister("coreinit", OSCalendarTimeToTicks, LogType::Placeholder);
//timeTest(); //timeTest();
} }
}; };

View file

@ -40,25 +40,21 @@ namespace coreinit
inline TimerTicks ConvertNsToTimerTicks(uint64 ns) inline TimerTicks ConvertNsToTimerTicks(uint64 ns)
{ {
return ((GetTimerClock() / 31250LL) * ((TimerTicks)ns) / 32000LL); return static_cast<TimerTicks>((static_cast<uint64>(GetTimerClock()) / 31250ULL) * (ns) / 32000ULL);
} }
inline TimerTicks ConvertMsToTimerTicks(uint64 ms) inline TimerTicks ConvertMsToTimerTicks(uint64 ms)
{ {
return (TimerTicks)ms * GetTimerClock() / 1000LL; return static_cast<TimerTicks>(ms * static_cast<uint64>(GetTimerClock()) / 1000ULL);
} }
}; };
void OSTicksToCalendarTime(uint64 ticks, OSCalendarTime_t* calenderStruct); void OSTicksToCalendarTime(uint64 ticks, OSCalendarTime_t* calenderStruct);
uint64 OSGetSystemTime();
uint64 OSGetTime(); uint64 OSGetTime();
uint32 OSGetSystemTick();
uint64 coreinit_getOSTime(); uint32 OSGetTick();
uint64 coreinit_getTimerTick();
static uint64 OSGetSystemTime()
{
return coreinit_getTimerTick();
}
void InitializeTimeAndCalendar(); void InitializeTimeAndCalendar();
}; };

View file

@ -11,7 +11,7 @@ uint64 dmaeRetiredTimestamp = 0;
uint64 dmae_getTimestamp() uint64 dmae_getTimestamp()
{ {
return coreinit::coreinit_getTimerTick(); return coreinit::OSGetSystemTime();
} }
void dmae_setRetiredTimestamp(uint64 timestamp) void dmae_setRetiredTimestamp(uint64 timestamp)

View file

@ -322,7 +322,7 @@ uint64 _prevReturnedGPUTime = 0;
uint64 Latte_GetTime() uint64 Latte_GetTime()
{ {
uint64 gpuTime = coreinit::coreinit_getTimerTick(); uint64 gpuTime = coreinit::OSGetSystemTime();
gpuTime *= 20000ULL; gpuTime *= 20000ULL;
if (gpuTime <= _prevReturnedGPUTime) if (gpuTime <= _prevReturnedGPUTime)
gpuTime = _prevReturnedGPUTime + 1; // avoid ever returning identical timestamps gpuTime = _prevReturnedGPUTime + 1; // avoid ever returning identical timestamps

View file

@ -54,7 +54,7 @@ void gx2Export_GX2GetGPUTimeout(PPCInterpreter_t* hCPU)
void gx2Export_GX2SampleTopGPUCycle(PPCInterpreter_t* hCPU) void gx2Export_GX2SampleTopGPUCycle(PPCInterpreter_t* hCPU)
{ {
cemuLog_log(LogType::GX2, "GX2SampleTopGPUCycle(0x{:08x})", hCPU->gpr[3]); 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); osLib_returnFromFunction(hCPU, 0);
} }

View file

@ -315,7 +315,7 @@ namespace acp
ppcDefineParamU32BEPtr(timestamp64, 0); ppcDefineParamU32BEPtr(timestamp64, 0);
ppcDefineParamU32BEPtr(ukn, 1); // probably timezone or offset? Could also be a bool for success/failed 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[0] = (uint32)(t >> 32);
timestamp64[1] = (uint32)(t & 0xFFFFFFFF); timestamp64[1] = (uint32)(t & 0xFFFFFFFF);

View file

@ -760,7 +760,7 @@ namespace padscore
void start() void start()
{ {
OSCreateAlarm(&g_padscore.alarm); 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 const uint64 period_tick = coreinit::EspressoTime::GetTimerClock() / 200; // every 5ms
MPTR handler = PPCInterpreter_makeCallableExportDepr(TickFunction); MPTR handler = PPCInterpreter_makeCallableExportDepr(TickFunction);
OSSetPeriodicAlarm(&g_padscore.alarm, start_tick, period_tick, handler); OSSetPeriodicAlarm(&g_padscore.alarm, start_tick, period_tick, handler);

View file

@ -267,7 +267,7 @@ namespace vpad
{ {
if (channel <= 1 && vpadDelayEnabled) if (channel <= 1 && vpadDelayEnabled)
{ {
uint64 currentTime = coreinit::coreinit_getOSTime(); uint64 currentTime = coreinit::OSGetTime();
const auto dif = currentTime - vpad::g_vpad.controller_data[channel].drcLastCallTime; const auto dif = currentTime - vpad::g_vpad.controller_data[channel].drcLastCallTime;
if (dif <= (ESPRESSO_TIMER_CLOCK / 60ull)) if (dif <= (ESPRESSO_TIMER_CLOCK / 60ull))
{ {
@ -1149,7 +1149,7 @@ namespace vpad
void start() void start()
{ {
coreinit::OSCreateAlarm(&g_vpad.alarm); 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 uint64 period_tick = coreinit::EspressoTime::GetTimerClock() * 5 / 1000;
const MPTR handler = PPCInterpreter_makeCallableExportDepr(TickFunction); const MPTR handler = PPCInterpreter_makeCallableExportDepr(TickFunction);
coreinit::OSSetPeriodicAlarm(&g_vpad.alarm, start_tick, period_tick, handler); coreinit::OSSetPeriodicAlarm(&g_vpad.alarm, start_tick, period_tick, handler);

View file

@ -304,7 +304,7 @@ void SaveImportWindow::OnImport(wxCommandEvent& event)
auto new_node = info_node.append_child("account"); auto new_node = info_node.append_child("account");
new_node.append_attribute("persistentId").set_value(new_persistend_id_string.c_str()); new_node.append_attribute("persistentId").set_value(new_persistend_id_string.c_str());
auto timestamp = new_node.append_child("timestamp"); 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())) if(!doc.save_file(saveinfo.c_str()))
cemuLog_log(LogType::Force, "couldn't insert save entry in saveinfo.xml: {}", _pathToUtf8(saveinfo)); cemuLog_log(LogType::Force, "couldn't insert save entry in saveinfo.xml: {}", _pathToUtf8(saveinfo));