mirror of
https://github.com/cemu-project/Cemu.git
synced 2025-07-03 13:31:18 +12:00
Compare commits
5 commits
6f021352d3
...
e54d213fcf
Author | SHA1 | Date | |
---|---|---|---|
|
e54d213fcf | ||
|
ec2d7c086a | ||
|
c714e8cb6b | ||
|
528fc53718 | ||
|
59fa217a7b |
20 changed files with 274 additions and 58 deletions
73
dist/linux/Cemu.1
vendored
Normal file
73
dist/linux/Cemu.1
vendored
Normal 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
85
dist/linux/Cemu.1.md
vendored
Normal 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
71
dist/linux/Cemu.1.txt
vendored
Normal 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)
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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++;
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
};
|
};
|
|
@ -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();
|
||||||
};
|
};
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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));
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue