Added RUNFLAG_APTREINIT for supporting environments that require APT reinitialization
This commit is contained in:
parent
004dfff8bd
commit
350cb955b2
@ -2,6 +2,7 @@
|
||||
|
||||
// TODO : find a better place to put this
|
||||
#define RUNFLAG_APTWORKAROUND (BIT(0))
|
||||
#define RUNFLAG_APTREINIT (BIT(1))
|
||||
|
||||
typedef enum{
|
||||
APPID_HOMEMENU = 0x101, // Home Menu
|
||||
@ -55,11 +56,14 @@ bool aptMainLoop(); // Use like this in your main(): while (aptMainLoop()) { you
|
||||
|
||||
Result APT_GetLockHandle(Handle* handle, u16 flags, Handle* lockHandle);
|
||||
Result APT_Initialize(Handle* handle, NS_APPID appId, Handle* eventHandle1, Handle* eventHandle2);
|
||||
Result APT_Finalize(Handle* handle, NS_APPID appId);
|
||||
Result APT_HardwareResetAsync(Handle* handle);
|
||||
Result APT_Enable(Handle* handle, u32 a);
|
||||
Result APT_GetAppletManInfo(Handle* handle, u8 inval, u8 *outval8, u32 *outval32, NS_APPID *menu_appid, NS_APPID *active_appid);
|
||||
Result APT_PrepareToJumpToHomeMenu(Handle* handle);
|
||||
Result APT_JumpToHomeMenu(Handle* handle, u32 a, u32 b, u32 c);
|
||||
Result APT_PrepareToJumpToApplication(Handle* handle, u32 a);
|
||||
Result APT_JumpToApplication(Handle* handle, u32 a, u32 b, u32 c);
|
||||
Result APT_IsRegistered(Handle* handle, NS_APPID appID, u8* out);
|
||||
Result APT_InquireNotification(Handle* handle, u32 appID, u8* signalType);
|
||||
Result APT_NotifyToWait(Handle* handle, NS_APPID appID);
|
||||
|
@ -48,8 +48,23 @@ static Handle __apt_launchapplet_inhandle;
|
||||
static u32 *__apt_launchapplet_parambuf;
|
||||
static u32 __apt_launchapplet_parambufsize;
|
||||
|
||||
// The following function can be overriden in order to log APT signals and notifications for debugging purposes
|
||||
__attribute__((weak)) void _aptDebug(int a, int b)
|
||||
{
|
||||
}
|
||||
|
||||
static void aptAppStarted(void);
|
||||
|
||||
static bool aptIsCrippled(void)
|
||||
{
|
||||
return (__system_runflags & RUNFLAG_APTWORKAROUND) != 0;
|
||||
}
|
||||
|
||||
static bool aptIsReinit(void)
|
||||
{
|
||||
return (__system_runflags & RUNFLAG_APTREINIT) != 0;
|
||||
}
|
||||
|
||||
static Result __apt_initservicehandle()
|
||||
{
|
||||
Result ret=0;
|
||||
@ -162,7 +177,7 @@ void aptReturnToMenu()
|
||||
NS_APPID menu_appid;
|
||||
u32 tmp0 = 1, tmp1 = 0;
|
||||
|
||||
if(__system_runflags&RUNFLAG_APTWORKAROUND)
|
||||
if(aptIsCrippled())
|
||||
{
|
||||
svcClearEvent(aptStatusEvent);
|
||||
aptSetStatus(APP_EXITING);
|
||||
@ -177,15 +192,15 @@ void aptReturnToMenu()
|
||||
aptCloseSession();
|
||||
}
|
||||
|
||||
// Set status to SUSPENDED.
|
||||
svcClearEvent(aptStatusEvent);
|
||||
aptSetStatus(APP_SUSPENDED);
|
||||
|
||||
// Prepare for return to menu
|
||||
aptOpenSession();
|
||||
APT_PrepareToJumpToHomeMenu(NULL);
|
||||
aptCloseSession();
|
||||
|
||||
// Set status to SUSPENDED.
|
||||
svcClearEvent(aptStatusEvent);
|
||||
aptSetStatus(APP_SUSPENDED);
|
||||
|
||||
// Save Vram
|
||||
GSPGPU_SaveVramSysArea(NULL);
|
||||
|
||||
@ -286,9 +301,10 @@ static void __handle_notification() {
|
||||
aptOpenSession();
|
||||
ret = APT_InquireNotification(NULL, currentAppId, &type);
|
||||
aptCloseSession();
|
||||
|
||||
if(ret!=0) return;
|
||||
|
||||
_aptDebug(1, type);
|
||||
|
||||
switch(type)
|
||||
{
|
||||
case APTSIGNAL_HOMEBUTTON:
|
||||
@ -350,6 +366,8 @@ static bool __handle_incoming_parameter() {
|
||||
APT_ReceiveParameter(NULL, currentAppId, 0x1000, aptParameters, NULL, &type);
|
||||
aptCloseSession();
|
||||
|
||||
_aptDebug(2, type);
|
||||
|
||||
switch(type)
|
||||
{
|
||||
case 0x1: // Application just started.
|
||||
@ -366,10 +384,14 @@ static bool __handle_incoming_parameter() {
|
||||
aptSetStatus(APP_APPLETCLOSED);
|
||||
return true;
|
||||
case 0xB: // Just returned from menu.
|
||||
if (aptStatusMutex)
|
||||
{
|
||||
GSPGPU_AcquireRight(NULL, 0x0);
|
||||
GSPGPU_RestoreVramSysArea(NULL);
|
||||
aptAppletUtility_Exit_RetToApp(0);
|
||||
aptSetStatus(APP_RUNNING);
|
||||
} else
|
||||
aptAppStarted();
|
||||
return true;
|
||||
|
||||
case 0xC: // Exiting application.
|
||||
@ -387,9 +409,8 @@ void aptEventHandler(void *arg)
|
||||
while(runThread)
|
||||
{
|
||||
s32 syncedID = 0;
|
||||
svcWaitSynchronizationN(&syncedID, aptEvents, 2, 0, U64_MAX);
|
||||
svcWaitSynchronizationN(&syncedID, aptEvents, 3, 0, U64_MAX);
|
||||
svcClearEvent(aptEvents[syncedID]);
|
||||
|
||||
switch(syncedID)
|
||||
{
|
||||
// Event 0 means we got a signal from NS (home button, power button etc).
|
||||
@ -400,7 +421,7 @@ void aptEventHandler(void *arg)
|
||||
case 0x1:
|
||||
runThread = __handle_incoming_parameter();
|
||||
break;
|
||||
// Event 2 means we should exit the thread (event will be added later).
|
||||
// Event 2 means we should exit the thread.
|
||||
case 0x2:
|
||||
runThread = false;
|
||||
break;
|
||||
@ -418,6 +439,8 @@ Result aptInit(void)
|
||||
|
||||
if (aptInitialised) return ret;
|
||||
|
||||
aptStatusMutex = 0;
|
||||
|
||||
// Initialize APT stuff, escape load screen.
|
||||
ret = __apt_initservicehandle();
|
||||
if(ret!=0)return ret;
|
||||
@ -429,7 +452,7 @@ Result aptInit(void)
|
||||
svcCreateEvent(&aptStatusEvent, 0);
|
||||
svcCreateEvent(&aptSleepSync, 0);
|
||||
|
||||
if(!(__system_runflags&RUNFLAG_APTWORKAROUND))
|
||||
if(!aptIsCrippled())
|
||||
{
|
||||
aptOpenSession();
|
||||
if((ret=APT_Initialize(NULL, currentAppId, &aptEvents[0], &aptEvents[1])))return ret;
|
||||
@ -439,6 +462,22 @@ Result aptInit(void)
|
||||
if((ret=APT_Enable(NULL, 0x0)))return ret;
|
||||
aptCloseSession();
|
||||
|
||||
// create APT close event
|
||||
svcCreateEvent(&aptEvents[2], 0);
|
||||
|
||||
// After a cycle of APT_Finalize+APT_Initialize APT thinks the
|
||||
// application is suspended, so we need to tell it to unsuspend us.
|
||||
if (aptIsReinit())
|
||||
{
|
||||
aptOpenSession();
|
||||
APT_PrepareToJumpToApplication(NULL, 0x0);
|
||||
aptCloseSession();
|
||||
|
||||
aptOpenSession();
|
||||
APT_JumpToApplication(NULL, 0x0, 0x0, 0x0);
|
||||
aptCloseSession();
|
||||
}
|
||||
|
||||
aptOpenSession();
|
||||
if((ret=APT_NotifyToWait(NULL, currentAppId)))return ret;
|
||||
aptCloseSession();
|
||||
@ -458,7 +497,7 @@ void aptExit()
|
||||
{
|
||||
if (!aptInitialised) return;
|
||||
|
||||
if(!(__system_runflags&RUNFLAG_APTWORKAROUND))aptAppletUtility_Exit_RetToApp(0);
|
||||
if(!aptIsCrippled())aptAppletUtility_Exit_RetToApp(0);
|
||||
|
||||
// This is only executed when application-termination was triggered via the home-menu power-off screen.
|
||||
if(aptGetStatusPower() == 1)
|
||||
@ -468,7 +507,10 @@ void aptExit()
|
||||
aptCloseSession();
|
||||
}
|
||||
|
||||
if(!(__system_runflags&RUNFLAG_APTWORKAROUND))
|
||||
if(!aptIsCrippled())
|
||||
{
|
||||
bool isReinit = aptIsReinit();
|
||||
if (aptGetStatus() == APP_EXITING)
|
||||
{
|
||||
aptOpenSession();
|
||||
APT_PrepareToCloseApplication(NULL, 0x1);
|
||||
@ -477,7 +519,24 @@ void aptExit()
|
||||
aptOpenSession();
|
||||
APT_CloseApplication(NULL, 0x0, 0x0, 0x0);
|
||||
aptCloseSession();
|
||||
|
||||
if (isReinit)
|
||||
{
|
||||
extern void (*__system_retAddr)(void);
|
||||
__system_retAddr = NULL;
|
||||
}
|
||||
} else if (isReinit)
|
||||
{
|
||||
aptOpenSession();
|
||||
APT_Finalize(NULL, currentAppId);
|
||||
aptCloseSession();
|
||||
}
|
||||
}
|
||||
|
||||
svcSignalEvent(aptEvents[2]);
|
||||
svcWaitSynchronization(aptEventHandlerThread, U64_MAX);
|
||||
svcCloseHandle(aptEventHandlerThread);
|
||||
svcCloseHandle(aptEvents[2]);
|
||||
|
||||
svcCloseHandle(aptSleepSync);
|
||||
|
||||
@ -492,7 +551,7 @@ bool aptMainLoop()
|
||||
{
|
||||
while(1)
|
||||
{
|
||||
//if(__system_runflags&RUNFLAG_APTWORKAROUND)__handle_notification();
|
||||
//if(aptIsCrippled())__handle_notification();
|
||||
|
||||
switch(aptGetStatus())
|
||||
{
|
||||
@ -531,7 +590,7 @@ void aptAppStarted()
|
||||
|
||||
aptSetStatus(APP_RUNNING);
|
||||
|
||||
if(!(__system_runflags&RUNFLAG_APTWORKAROUND))
|
||||
if(!aptIsCrippled())
|
||||
{
|
||||
memset(buf1, 0, 4);
|
||||
|
||||
@ -642,6 +701,18 @@ Result APT_Initialize(Handle* handle, NS_APPID appId, Handle* eventHandle1, Hand
|
||||
return cmdbuf[1];
|
||||
}
|
||||
|
||||
Result APT_Finalize(Handle* handle, NS_APPID appId)
|
||||
{
|
||||
if(!handle)handle=&aptuHandle;
|
||||
u32* cmdbuf=getThreadCommandBuffer();
|
||||
cmdbuf[0]=0x40040; //request header code
|
||||
cmdbuf[1]=appId;
|
||||
|
||||
Result ret=0;
|
||||
if((ret=svcSendSyncRequest(*handle)))return ret;
|
||||
return cmdbuf[1];
|
||||
}
|
||||
|
||||
Result APT_HardwareResetAsync(Handle* handle)
|
||||
{
|
||||
if(!handle)handle=&aptuHandle;
|
||||
@ -743,6 +814,35 @@ Result APT_JumpToHomeMenu(Handle* handle, u32 a, u32 b, u32 c)
|
||||
return cmdbuf[1];
|
||||
}
|
||||
|
||||
Result APT_PrepareToJumpToApplication(Handle* handle, u32 a)
|
||||
{
|
||||
if(!handle)handle=&aptuHandle;
|
||||
u32* cmdbuf=getThreadCommandBuffer();
|
||||
cmdbuf[0]=0x230040; //request header code
|
||||
cmdbuf[1]=a;
|
||||
|
||||
Result ret=0;
|
||||
if((ret=svcSendSyncRequest(*handle)))return ret;
|
||||
|
||||
return cmdbuf[1];
|
||||
}
|
||||
|
||||
Result APT_JumpToApplication(Handle* handle, u32 a, u32 b, u32 c)
|
||||
{
|
||||
if(!handle)handle=&aptuHandle;
|
||||
u32* cmdbuf=getThreadCommandBuffer();
|
||||
cmdbuf[0]=0x240044; //request header code
|
||||
cmdbuf[1]=a;
|
||||
cmdbuf[2]=b;
|
||||
cmdbuf[3]=c;
|
||||
cmdbuf[4]=(b<<14)|2;
|
||||
|
||||
Result ret=0;
|
||||
if((ret=svcSendSyncRequest(*handle)))return ret;
|
||||
|
||||
return cmdbuf[1];
|
||||
}
|
||||
|
||||
Result APT_NotifyToWait(Handle* handle, NS_APPID appID)
|
||||
{
|
||||
if(!handle)handle=&aptuHandle;
|
||||
|
Loading…
Reference in New Issue
Block a user