mirror of
https://github.com/izzy2lost/WeeU.git
synced 2026-07-06 00:19:59 -07:00
Implement proc_ui.rpl + stub SYSSwitchToEManual() to avoid softlocks
- Full reimplementation of proc_ui.rpl with all 19 exports - Foreground/Background messages now go to the coreinit system message queue as they should (instead of using a hack where proc_ui receives them directly) - Add missing coreinit API needed by proc_ui: OSGetPFID(), OSGetUPID(), OSGetTitleID(), __OSCreateThreadType() - Use big-endian types in OSMessage - Flesh out the stubs for OSDriver_Register and OSDriver_Unregister a bit more since we need to call it from proc_ui. Similiar small tweaks to other coreinit API - Stub sysapp SYSSwitchToEManual() and _SYSSwitchToEManual() in such a way that they will trigger the expected background/foreground transition, avoiding softlocks in games that call these functions
This commit is contained in:
@@ -39,6 +39,7 @@ bin/sdcard/*
|
||||
bin/screenshots/*
|
||||
bin/dump/*
|
||||
bin/cafeLibs/*
|
||||
bin/portable/*
|
||||
bin/keys.txt
|
||||
|
||||
!bin/shaderCache/info.txt
|
||||
|
||||
@@ -221,5 +221,5 @@ void osLib_load()
|
||||
nsyskbd::nsyskbd_load();
|
||||
swkbd::load();
|
||||
camera::load();
|
||||
procui_load();
|
||||
proc_ui::load();
|
||||
}
|
||||
|
||||
@@ -179,27 +179,6 @@ void coreinitExport_OSGetSharedData(PPCInterpreter_t* hCPU)
|
||||
osLib_returnFromFunction(hCPU, 1);
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
MPTR getDriverName;
|
||||
MPTR ukn04;
|
||||
MPTR onAcquiredForeground;
|
||||
MPTR onReleaseForeground;
|
||||
MPTR ukn10;
|
||||
}OSDriverCallbacks_t;
|
||||
|
||||
void coreinitExport_OSDriver_Register(PPCInterpreter_t* hCPU)
|
||||
{
|
||||
#ifdef CEMU_DEBUG_ASSERT
|
||||
cemuLog_log(LogType::Force, "OSDriver_Register(0x{:08x},0x{:08x},0x{:08x},0x{:08x},0x{:08x},0x{:08x})", hCPU->gpr[3], hCPU->gpr[4], hCPU->gpr[5], hCPU->gpr[6], hCPU->gpr[7], hCPU->gpr[8]);
|
||||
#endif
|
||||
OSDriverCallbacks_t* driverCallbacks = (OSDriverCallbacks_t*)memory_getPointerFromVirtualOffset(hCPU->gpr[5]);
|
||||
|
||||
// todo
|
||||
|
||||
osLib_returnFromFunction(hCPU, 0);
|
||||
}
|
||||
|
||||
namespace coreinit
|
||||
{
|
||||
sint32 OSGetCoreId()
|
||||
@@ -379,7 +358,6 @@ void coreinit_load()
|
||||
coreinit::miscInit();
|
||||
osLib_addFunction("coreinit", "OSGetSharedData", coreinitExport_OSGetSharedData);
|
||||
osLib_addFunction("coreinit", "UCReadSysConfig", coreinitExport_UCReadSysConfig);
|
||||
osLib_addFunction("coreinit", "OSDriver_Register", coreinitExport_OSDriver_Register);
|
||||
|
||||
// async callbacks
|
||||
InitializeAsyncCallback();
|
||||
|
||||
@@ -2,6 +2,12 @@
|
||||
|
||||
namespace coreinit
|
||||
{
|
||||
enum class RplEntryReason
|
||||
{
|
||||
Loaded = 1,
|
||||
Unloaded = 2,
|
||||
};
|
||||
|
||||
uint32 OSDynLoad_SetAllocator(MPTR allocFunc, MPTR freeFunc);
|
||||
void OSDynLoad_SetTLSAllocator(MPTR allocFunc, MPTR freeFunc);
|
||||
uint32 OSDynLoad_GetAllocator(betype<MPTR>* funcAlloc, betype<MPTR>* funcFree);
|
||||
|
||||
@@ -837,7 +837,7 @@ namespace coreinit
|
||||
|
||||
FSAsyncResult* FSGetAsyncResult(OSMessage* msg)
|
||||
{
|
||||
return (FSAsyncResult*)memory_getPointerFromVirtualOffset(_swapEndianU32(msg->message));
|
||||
return (FSAsyncResult*)memory_getPointerFromVirtualOffset(msg->message);
|
||||
}
|
||||
|
||||
sint32 __FSProcessAsyncResult(FSClient_t* fsClient, FSCmdBlock_t* fsCmdBlock, sint32 fsStatus, uint32 errHandling)
|
||||
|
||||
@@ -126,7 +126,7 @@ namespace coreinit
|
||||
return physicalAddr;
|
||||
}
|
||||
|
||||
void OSMemoryBarrier(PPCInterpreter_t* hCPU)
|
||||
void OSMemoryBarrier()
|
||||
{
|
||||
// no-op
|
||||
}
|
||||
|
||||
@@ -5,4 +5,9 @@ namespace coreinit
|
||||
void InitializeMemory();
|
||||
|
||||
void OSGetMemBound(sint32 memType, MPTR* offsetOutput, uint32* sizeOutput);
|
||||
|
||||
void* OSBlockMove(MEMPTR<void> dst, MEMPTR<void> src, uint32 size, bool flushDC);
|
||||
void* OSBlockSet(MEMPTR<void> dst, uint32 value, uint32 size);
|
||||
|
||||
void OSMemoryBarrier();
|
||||
}
|
||||
@@ -3,6 +3,8 @@
|
||||
|
||||
namespace coreinit
|
||||
{
|
||||
void UpdateSystemMessageQueue();
|
||||
void HandleReceivedSystemMessage(OSMessage* msg);
|
||||
|
||||
SysAllocator<OSMessageQueue> g_systemMessageQueue;
|
||||
SysAllocator<OSMessage, 16> _systemMessageQueueArray;
|
||||
@@ -27,6 +29,9 @@ namespace coreinit
|
||||
|
||||
bool OSReceiveMessage(OSMessageQueue* msgQueue, OSMessage* msg, uint32 flags)
|
||||
{
|
||||
bool isSystemMessageQueue = (msgQueue == g_systemMessageQueue);
|
||||
if(isSystemMessageQueue)
|
||||
UpdateSystemMessageQueue();
|
||||
__OSLockScheduler(msgQueue);
|
||||
while (msgQueue->usedCount == (uint32be)0)
|
||||
{
|
||||
@@ -50,6 +55,8 @@ namespace coreinit
|
||||
if (!msgQueue->threadQueueSend.isEmpty())
|
||||
msgQueue->threadQueueSend.wakeupSingleThreadWaitQueue(true);
|
||||
__OSUnlockScheduler(msgQueue);
|
||||
if(isSystemMessageQueue)
|
||||
HandleReceivedSystemMessage(msg);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,12 +3,21 @@
|
||||
|
||||
namespace coreinit
|
||||
{
|
||||
enum class SysMessageId : uint32
|
||||
{
|
||||
MsgAcquireForeground = 0xFACEF000,
|
||||
MsgReleaseForeground = 0xFACEBACC,
|
||||
MsgExit = 0xD1E0D1E0,
|
||||
HomeButtonDenied = 0xCCC0FFEE,
|
||||
NetIoStartOrStop = 0xAAC0FFEE,
|
||||
};
|
||||
|
||||
struct OSMessage
|
||||
{
|
||||
MPTR message;
|
||||
uint32 data0;
|
||||
uint32 data1;
|
||||
uint32 data2;
|
||||
uint32be message;
|
||||
uint32be data0;
|
||||
uint32be data1;
|
||||
uint32be data2;
|
||||
};
|
||||
|
||||
struct OSMessageQueue
|
||||
@@ -36,5 +45,7 @@ namespace coreinit
|
||||
bool OSPeekMessage(OSMessageQueue* msgQueue, OSMessage* msg);
|
||||
sint32 OSSendMessage(OSMessageQueue* msgQueue, OSMessage* msg, uint32 flags);
|
||||
|
||||
OSMessageQueue* OSGetSystemMessageQueue();
|
||||
|
||||
void InitializeMessageQueue();
|
||||
};
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "Cafe/OS/common/OSCommon.h"
|
||||
#include "Cafe/OS/libs/coreinit/coreinit_Misc.h"
|
||||
#include "Cafe/OS/libs/coreinit/coreinit_MessageQueue.h"
|
||||
#include "Cafe/CafeSystem.h"
|
||||
#include "Cafe/Filesystem/fsc.h"
|
||||
#include <pugixml.hpp>
|
||||
@@ -371,6 +372,23 @@ namespace coreinit
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32 OSGetPFID()
|
||||
{
|
||||
return 15; // hardcoded as game
|
||||
}
|
||||
|
||||
uint32 OSGetUPID()
|
||||
{
|
||||
return OSGetPFID();
|
||||
}
|
||||
|
||||
uint64 s_currentTitleId;
|
||||
|
||||
uint64 OSGetTitleID()
|
||||
{
|
||||
return s_currentTitleId;
|
||||
}
|
||||
|
||||
uint32 s_sdkVersion;
|
||||
|
||||
uint32 __OSGetProcessSDKVersion()
|
||||
@@ -470,9 +488,78 @@ namespace coreinit
|
||||
return 0;
|
||||
}
|
||||
|
||||
void OSReleaseForeground()
|
||||
{
|
||||
cemuLog_logDebug(LogType::Force, "OSReleaseForeground not implemented");
|
||||
}
|
||||
|
||||
bool s_transitionToBackground = false;
|
||||
bool s_transitionToForeground = false;
|
||||
|
||||
void StartBackgroundForegroundTransition()
|
||||
{
|
||||
s_transitionToBackground = true;
|
||||
s_transitionToForeground = true;
|
||||
}
|
||||
|
||||
// called at the beginning of OSReceiveMessage if the queue is the system message queue
|
||||
void UpdateSystemMessageQueue()
|
||||
{
|
||||
if(!OSIsInterruptEnabled())
|
||||
return;
|
||||
cemu_assert_debug(!__OSHasSchedulerLock());
|
||||
// normally syscall 0x2E is used to get the next message
|
||||
// for now we just have some preliminary logic here to allow a fake transition to background & foreground
|
||||
if(s_transitionToBackground)
|
||||
{
|
||||
// add transition to background message
|
||||
OSMessage msg{};
|
||||
msg.data0 = stdx::to_underlying(SysMessageId::MsgReleaseForeground);
|
||||
msg.data1 = 0; // 1 -> System is shutting down 0 -> Begin transitioning to background
|
||||
OSMessageQueue* systemMessageQueue = coreinit::OSGetSystemMessageQueue();
|
||||
if(OSSendMessage(systemMessageQueue, &msg, 0))
|
||||
s_transitionToBackground = false;
|
||||
return;
|
||||
}
|
||||
if(s_transitionToForeground)
|
||||
{
|
||||
// add transition to foreground message
|
||||
OSMessage msg{};
|
||||
msg.data0 = stdx::to_underlying(SysMessageId::MsgAcquireForeground);
|
||||
msg.data1 = 1; // ?
|
||||
msg.data2 = 1; // ?
|
||||
OSMessageQueue* systemMessageQueue = coreinit::OSGetSystemMessageQueue();
|
||||
if(OSSendMessage(systemMessageQueue, &msg, 0))
|
||||
s_transitionToForeground = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// called when OSReceiveMessage returns a message from the system message queue
|
||||
void HandleReceivedSystemMessage(OSMessage* msg)
|
||||
{
|
||||
cemu_assert_debug(!__OSHasSchedulerLock());
|
||||
cemuLog_log(LogType::Force, "Receiving message: {:08x}", (uint32)msg->data0);
|
||||
}
|
||||
|
||||
uint32 OSDriver_Register(uint32 moduleHandle, sint32 priority, OSDriverInterface* driverCallbacks, sint32 driverId, uint32be* outUkn1, uint32be* outUkn2, uint32be* outUkn3)
|
||||
{
|
||||
cemuLog_logDebug(LogType::Force, "OSDriver_Register stubbed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32 OSDriver_Deregister(uint32 moduleHandle, sint32 driverId)
|
||||
{
|
||||
cemuLog_logDebug(LogType::Force, "OSDriver_Deregister stubbed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
void miscInit()
|
||||
{
|
||||
s_currentTitleId = CafeSystem::GetForegroundTitleId();
|
||||
s_sdkVersion = CafeSystem::GetForegroundTitleSDKVersion();
|
||||
s_transitionToBackground = false;
|
||||
s_transitionToForeground = false;
|
||||
|
||||
cafeExportRegister("coreinit", __os_snprintf, LogType::Placeholder);
|
||||
cafeExportRegister("coreinit", OSReport, LogType::Placeholder);
|
||||
@@ -480,6 +567,10 @@ namespace coreinit
|
||||
cafeExportRegister("coreinit", COSWarn, LogType::Placeholder);
|
||||
cafeExportRegister("coreinit", OSLogPrintf, LogType::Placeholder);
|
||||
cafeExportRegister("coreinit", OSConsoleWrite, LogType::Placeholder);
|
||||
|
||||
cafeExportRegister("coreinit", OSGetPFID, LogType::Placeholder);
|
||||
cafeExportRegister("coreinit", OSGetUPID, LogType::Placeholder);
|
||||
cafeExportRegister("coreinit", OSGetTitleID, LogType::Placeholder);
|
||||
cafeExportRegister("coreinit", __OSGetProcessSDKVersion, LogType::Placeholder);
|
||||
|
||||
g_homeButtonMenuEnabled = true; // enabled by default
|
||||
@@ -489,6 +580,11 @@ namespace coreinit
|
||||
|
||||
cafeExportRegister("coreinit", OSLaunchTitleByPathl, LogType::Placeholder);
|
||||
cafeExportRegister("coreinit", OSRestartGame, LogType::Placeholder);
|
||||
|
||||
cafeExportRegister("coreinit", OSReleaseForeground, LogType::Placeholder);
|
||||
|
||||
cafeExportRegister("coreinit", OSDriver_Register, LogType::Placeholder);
|
||||
cafeExportRegister("coreinit", OSDriver_Deregister, LogType::Placeholder);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
@@ -2,9 +2,29 @@
|
||||
|
||||
namespace coreinit
|
||||
{
|
||||
uint32 OSGetUPID();
|
||||
uint32 OSGetPFID();
|
||||
uint64 OSGetTitleID();
|
||||
uint32 __OSGetProcessSDKVersion();
|
||||
uint32 OSLaunchTitleByPathl(const char* path, uint32 pathLength, uint32 argc);
|
||||
uint32 OSRestartGame(uint32 argc, MEMPTR<char>* argv);
|
||||
|
||||
void OSReleaseForeground();
|
||||
|
||||
void StartBackgroundForegroundTransition();
|
||||
|
||||
struct OSDriverInterface
|
||||
{
|
||||
MEMPTR<void> getDriverName;
|
||||
MEMPTR<void> init;
|
||||
MEMPTR<void> onAcquireForeground;
|
||||
MEMPTR<void> onReleaseForeground;
|
||||
MEMPTR<void> done;
|
||||
};
|
||||
static_assert(sizeof(OSDriverInterface) == 0x14);
|
||||
|
||||
uint32 OSDriver_Register(uint32 moduleHandle, sint32 priority, OSDriverInterface* driverCallbacks, sint32 driverId, uint32be* outUkn1, uint32be* outUkn2, uint32be* outUkn3);
|
||||
uint32 OSDriver_Deregister(uint32 moduleHandle, sint32 driverId);
|
||||
|
||||
void miscInit();
|
||||
};
|
||||
@@ -294,9 +294,9 @@ namespace coreinit
|
||||
__OSUnlockScheduler();
|
||||
}
|
||||
|
||||
bool OSCreateThreadType(OSThread_t* thread, MPTR entryPoint, sint32 numParam, void* ptrParam, void* stackTop2, sint32 stackSize, sint32 priority, uint32 attr, OSThread_t::THREAD_TYPE threadType)
|
||||
bool OSCreateThreadType(OSThread_t* thread, MPTR entryPoint, sint32 numParam, void* ptrParam, void* stackTop, sint32 stackSize, sint32 priority, uint32 attr, OSThread_t::THREAD_TYPE threadType)
|
||||
{
|
||||
OSCreateThreadInternal(thread, entryPoint, memory_getVirtualOffsetFromPointer(stackTop2) - stackSize, stackSize, attr, threadType);
|
||||
OSCreateThreadInternal(thread, entryPoint, memory_getVirtualOffsetFromPointer(stackTop) - stackSize, stackSize, attr, threadType);
|
||||
thread->context.gpr[3] = _swapEndianU32(numParam); // num arguments
|
||||
thread->context.gpr[4] = _swapEndianU32(memory_getVirtualOffsetFromPointer(ptrParam)); // arguments pointer
|
||||
__OSSetThreadBasePriority(thread, priority);
|
||||
@@ -317,9 +317,15 @@ namespace coreinit
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OSCreateThread(OSThread_t* thread, MPTR entryPoint, sint32 numParam, void* ptrParam, void* stackTop2, sint32 stackSize, sint32 priority, uint32 attr)
|
||||
bool OSCreateThread(OSThread_t* thread, MPTR entryPoint, sint32 numParam, void* ptrParam, void* stackTop, sint32 stackSize, sint32 priority, uint32 attr)
|
||||
{
|
||||
return OSCreateThreadType(thread, entryPoint, numParam, ptrParam, stackTop2, stackSize, priority, attr, OSThread_t::THREAD_TYPE::TYPE_APP);
|
||||
return OSCreateThreadType(thread, entryPoint, numParam, ptrParam, stackTop, stackSize, priority, attr, OSThread_t::THREAD_TYPE::TYPE_APP);
|
||||
}
|
||||
|
||||
// alias to OSCreateThreadType, similar to OSCreateThread, but with an additional parameter for the thread type
|
||||
bool __OSCreateThreadType(OSThread_t* thread, MPTR entryPoint, sint32 numParam, void* ptrParam, void* stackTop, sint32 stackSize, sint32 priority, uint32 attr, OSThread_t::THREAD_TYPE threadType)
|
||||
{
|
||||
return OSCreateThreadType(thread, entryPoint, numParam, ptrParam, stackTop, stackSize, priority, attr, threadType);
|
||||
}
|
||||
|
||||
bool OSRunThread(OSThread_t* thread, MPTR funcAddress, sint32 numParam, void* ptrParam)
|
||||
@@ -445,12 +451,12 @@ namespace coreinit
|
||||
return currentThread->specificArray[index].GetPtr();
|
||||
}
|
||||
|
||||
void OSSetThreadName(OSThread_t* thread, char* name)
|
||||
void OSSetThreadName(OSThread_t* thread, const char* name)
|
||||
{
|
||||
thread->threadName = name;
|
||||
}
|
||||
|
||||
char* OSGetThreadName(OSThread_t* thread)
|
||||
const char* OSGetThreadName(OSThread_t* thread)
|
||||
{
|
||||
return thread->threadName.GetPtr();
|
||||
}
|
||||
@@ -1371,6 +1377,7 @@ namespace coreinit
|
||||
{
|
||||
cafeExportRegister("coreinit", OSCreateThreadType, LogType::CoreinitThread);
|
||||
cafeExportRegister("coreinit", OSCreateThread, LogType::CoreinitThread);
|
||||
cafeExportRegister("coreinit", __OSCreateThreadType, LogType::CoreinitThread);
|
||||
cafeExportRegister("coreinit", OSExitThread, LogType::CoreinitThread);
|
||||
|
||||
cafeExportRegister("coreinit", OSGetCurrentThread, LogType::CoreinitThread);
|
||||
|
||||
@@ -449,7 +449,7 @@ struct OSThread_t
|
||||
/* +0x578 */ sint32 alarmRelatedUkn;
|
||||
/* +0x57C */ std::array<MEMPTR<void>, 16> specificArray;
|
||||
/* +0x5BC */ betype<THREAD_TYPE> type;
|
||||
/* +0x5C0 */ MEMPTR<char> threadName;
|
||||
/* +0x5C0 */ MEMPTR<const char> threadName;
|
||||
/* +0x5C4 */ MPTR waitAlarm; // used only by OSWaitEventWithTimeout/OSSignalEvent ?
|
||||
|
||||
/* +0x5C8 */ uint32 userStackPointer;
|
||||
@@ -505,6 +505,7 @@ namespace coreinit
|
||||
void* OSGetDefaultThreadStack(sint32 coreIndex, uint32& size);
|
||||
|
||||
bool OSCreateThreadType(OSThread_t* thread, MPTR entryPoint, sint32 numParam, void* ptrParam, void* stackTop2, sint32 stackSize, sint32 priority, uint32 attr, OSThread_t::THREAD_TYPE threadType);
|
||||
bool __OSCreateThreadType(OSThread_t* thread, MPTR entryPoint, sint32 numParam, void* ptrParam, void* stackTop, sint32 stackSize, sint32 priority, uint32 attr, OSThread_t::THREAD_TYPE threadType);
|
||||
void OSCreateThreadInternal(OSThread_t* thread, uint32 entryPoint, MPTR stackLowerBaseAddr, uint32 stackSize, uint8 affinityMask, OSThread_t::THREAD_TYPE threadType);
|
||||
bool OSRunThread(OSThread_t* thread, MPTR funcAddress, sint32 numParam, void* ptrParam);
|
||||
void OSExitThread(sint32 exitValue);
|
||||
@@ -519,8 +520,8 @@ namespace coreinit
|
||||
bool OSSetThreadPriority(OSThread_t* thread, sint32 newPriority);
|
||||
uint32 OSGetThreadAffinity(OSThread_t* thread);
|
||||
|
||||
void OSSetThreadName(OSThread_t* thread, char* name);
|
||||
char* OSGetThreadName(OSThread_t* thread);
|
||||
void OSSetThreadName(OSThread_t* thread, const char* name);
|
||||
const char* OSGetThreadName(OSThread_t* thread);
|
||||
|
||||
sint32 __OSResumeThreadInternal(OSThread_t* thread, sint32 resumeCount);
|
||||
sint32 OSResumeThread(OSThread_t* thread);
|
||||
@@ -530,6 +531,7 @@ namespace coreinit
|
||||
void OSSuspendThread(OSThread_t* thread);
|
||||
void OSSleepThread(OSThreadQueue* threadQueue);
|
||||
void OSWakeupThread(OSThreadQueue* threadQueue);
|
||||
bool OSJoinThread(OSThread_t* thread, uint32be* exitValue);
|
||||
|
||||
void OSTestThreadCancelInternal();
|
||||
|
||||
|
||||
@@ -22,10 +22,9 @@ namespace coreinit
|
||||
osLib_returnFromFunction(hCPU, (uint32)osTime);
|
||||
}
|
||||
|
||||
void export_OSGetTime(PPCInterpreter_t* hCPU)
|
||||
uint64 OSGetTime()
|
||||
{
|
||||
uint64 osTime = coreinit_getOSTime();
|
||||
osLib_returnFromFunction64(hCPU, osTime);
|
||||
return coreinit_getOSTime();
|
||||
}
|
||||
|
||||
void export_OSGetSystemTime(PPCInterpreter_t* hCPU)
|
||||
@@ -360,7 +359,7 @@ namespace coreinit
|
||||
|
||||
void InitializeTimeAndCalendar()
|
||||
{
|
||||
osLib_addFunction("coreinit", "OSGetTime", export_OSGetTime);
|
||||
cafeExportRegister("coreinit", OSGetTime, LogType::Placeholder);
|
||||
osLib_addFunction("coreinit", "OSGetSystemTime", export_OSGetSystemTime);
|
||||
osLib_addFunction("coreinit", "OSGetTick", export_OSGetTick);
|
||||
osLib_addFunction("coreinit", "OSGetSystemTick", export_OSGetSystemTick);
|
||||
|
||||
@@ -45,7 +45,8 @@ namespace coreinit
|
||||
};
|
||||
|
||||
void OSTicksToCalendarTime(uint64 ticks, OSCalendarTime_t* calenderStruct);
|
||||
|
||||
uint64 OSGetTime();
|
||||
|
||||
uint64 coreinit_getOSTime();
|
||||
uint64 coreinit_getTimerTick();
|
||||
|
||||
|
||||
@@ -19,5 +19,7 @@ namespace GX2
|
||||
void GX2SetTVBuffer(void* imageBuffePtr, uint32 imageBufferSize, E_TVRES tvResolutionMode, uint32 surfaceFormat, E_TVBUFFERMODE bufferMode);
|
||||
void GX2SetTVGamma(float gamma);
|
||||
|
||||
void GX2Invalidate(uint32 invalidationFlags, MPTR invalidationAddr, uint32 invalidationSize);
|
||||
|
||||
void GX2MiscInit();
|
||||
};
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
#include "Cafe/OS/libs/proc_ui/proc_ui.h"
|
||||
#include "Cafe/OS/libs/coreinit/coreinit_Time.h"
|
||||
#include "Cafe/OS/libs/coreinit/coreinit_Misc.h"
|
||||
|
||||
namespace nn
|
||||
{
|
||||
@@ -37,7 +38,7 @@ namespace nn
|
||||
void StubPostAppReleaseBackground(PPCInterpreter_t* hCPU)
|
||||
{
|
||||
coreinit::OSSleepTicks(ESPRESSO_TIMER_CLOCK * 2); // Sleep 2s
|
||||
ProcUI_SendForegroundMessage();
|
||||
coreinit::StartBackgroundForegroundTransition();
|
||||
}
|
||||
|
||||
sint32 StubPostApp(void* pAnyPostParam)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,44 @@
|
||||
|
||||
void procui_load();
|
||||
namespace proc_ui
|
||||
{
|
||||
enum class ProcUIStatus
|
||||
{
|
||||
Foreground = 0,
|
||||
Background = 1,
|
||||
Releasing = 2,
|
||||
Exit = 3
|
||||
};
|
||||
|
||||
void ProcUI_SendForegroundMessage();
|
||||
void ProcUI_SendBackgroundMessage();
|
||||
enum class ProcUICallbackId
|
||||
{
|
||||
AcquireForeground = 0,
|
||||
ReleaseForeground = 1,
|
||||
Exit = 2,
|
||||
NetIoStart = 3,
|
||||
NetIoStop = 4,
|
||||
HomeButtonDenied = 5,
|
||||
COUNT = 6
|
||||
};
|
||||
|
||||
void ProcUIInit(MEMPTR<void> callbackReadyToRelease);
|
||||
void ProcUIInitEx(MEMPTR<void> callbackReadyToReleaseEx, MEMPTR<void> userParam);
|
||||
void ProcUIShutdown();
|
||||
bool ProcUIIsRunning();
|
||||
bool ProcUIInForeground();
|
||||
bool ProcUIInShutdown();
|
||||
void ProcUIRegisterCallback(ProcUICallbackId callbackType, void* funcPtr, void* userParam, sint32 priority);
|
||||
void ProcUIRegisterCallbackCore(ProcUICallbackId callbackType, void* funcPtr, void* userParam, sint32 priority, uint32 coreIndex);
|
||||
void ProcUIRegisterBackgroundCallback(void* funcPtr, void* userParam, uint64 tickDelay);
|
||||
void ProcUIClearCallbacks();
|
||||
void ProcUISetSaveCallback(void* funcPtr, void* userParam);
|
||||
void ProcUISetCallbackStackSize(uint32 newStackSize);
|
||||
uint32 ProcUICalcMemorySize(uint32 numCallbacks);
|
||||
sint32 ProcUISetMemoryPool(void* memBase, uint32 size);
|
||||
void ProcUISetBucketStorage(void* memBase, uint32 size);
|
||||
void ProcUISetMEM1Storage(void* memBase, uint32 size);
|
||||
void ProcUIDrawDoneRelease();
|
||||
ProcUIStatus ProcUIProcessMessages(bool isBlockingInBackground);
|
||||
ProcUIStatus ProcUISubProcessMessages(bool isBlockingInBackground);
|
||||
|
||||
void load();
|
||||
}
|
||||
@@ -639,11 +639,34 @@ namespace sysapp
|
||||
return coreinit::OSRestartGame(argc, argv);
|
||||
}
|
||||
|
||||
struct EManualArgs
|
||||
{
|
||||
sysStandardArguments_t stdArgs;
|
||||
uint64be titleId;
|
||||
};
|
||||
static_assert(sizeof(EManualArgs) == 0x10);
|
||||
|
||||
void _SYSSwitchToEManual(EManualArgs* args)
|
||||
{
|
||||
// the struct has the titleId at offset 8 and standard args at 0 (total size is most likely 0x10)
|
||||
cemuLog_log(LogType::Force, "SYSSwitchToEManual called. Opening the manual is not supported");
|
||||
coreinit::StartBackgroundForegroundTransition();
|
||||
}
|
||||
|
||||
void SYSSwitchToEManual()
|
||||
{
|
||||
EManualArgs args{};
|
||||
args.titleId = coreinit::OSGetTitleID();
|
||||
_SYSSwitchToEManual(&args);
|
||||
}
|
||||
|
||||
void load()
|
||||
{
|
||||
cafeExportRegisterFunc(SYSClearSysArgs, "sysapp", "SYSClearSysArgs", LogType::Placeholder);
|
||||
cafeExportRegisterFunc(_SYSLaunchTitleByPathFromLauncher, "sysapp", "_SYSLaunchTitleByPathFromLauncher", LogType::Placeholder);
|
||||
cafeExportRegisterFunc(SYSRelaunchTitle, "sysapp", "SYSRelaunchTitle", LogType::Placeholder);
|
||||
cafeExportRegister("sysapp", _SYSSwitchToEManual, LogType::Placeholder);
|
||||
cafeExportRegister("sysapp", SYSSwitchToEManual, LogType::Placeholder);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user