]> Chaos Git - corbenik/ctrulib.git/commitdiff
Implemented more APT and GSPGPU commands. Improved return-to-menu handling, screensho...
authoryellows8 <yellowstar6@gmail.com>
Tue, 20 May 2014 19:49:03 +0000 (15:49 -0400)
committeryellows8 <yellowstar6@gmail.com>
Tue, 20 May 2014 19:49:03 +0000 (15:49 -0400)
13 files changed:
arm11u/Makefile
arm11u/source/crt0.s
arm11u/source/main.c
gpu/Makefile
gpu/source/crt0.s
gpu/source/main.c
libctru/include/ctr/APT.h
libctru/include/ctr/GSP.h
libctru/source/APT.c
libctru/source/GSP.c
sdmc/Makefile
sdmc/source/crt0.s
sdmc/source/main.c

index 8f02861235942d35b135f39472bf2f3eeca00f06..ca643f4620bc778fe0e0f95dcdd0cef94c5c7fbd 100644 (file)
@@ -1,7 +1,7 @@
 CC = arm-none-eabi-gcc
 LINK = arm-none-eabi-ld
 OBJCOPY = arm-none-eabi-objcopy
-CTRULIB = "../libctru"
+CTRULIB = ../libctru
 CFLAGS += -Wall -std=c99 -march=armv6 -O3 -I"$(CTRULIB)/include" -I$(DEVKITPRO)/libnds/include
 LDFLAGS += --script=ccd00.ld -L"$(DEVKITARM)/arm-none-eabi/lib" -L"$(CTRULIB)/lib"
 
index 6463bc268a3a98ad789940f1180fe6edef5468b7..557c32713cda33ccbfd6204df7be767da0974bd3 100644 (file)
@@ -1,4 +1,4 @@
-.section ".text"
+.section ".init"
 .arm
 .align 4
 .global _init
index 027a117e6b8eb541ef6b2a1174717e32bc75de1a..6cc7f83f543f1f15134eb6900e8aa7fe5ecd71d3 100644 (file)
@@ -139,6 +139,14 @@ int main()
                        swapBuffers();
                        copyBuffer();
                }
+               else if(status == APP_SUSPENDING)
+               {
+                       aptReturnToMenu();
+               }
+               else if(status == APP_SLEEPMODE)
+               {
+                       aptWaitStatusEvent();
+               }
                svc_sleepThread(16666666);
        }
 
index 6591a653d782e9073ff5fa5a8fdb6b95770ea91f..4840710f2dd1dc77fb045447b34f2f2b15783bfb 100644 (file)
@@ -2,8 +2,8 @@ CC = arm-none-eabi-gcc
 LINK = arm-none-eabi-gcc
 AS = arm-none-eabi-as
 OBJCOPY = arm-none-eabi-objcopy
-CTRULIB = "../libctru"
-AEMSTROPATH = "../../aemstro"
+CTRULIB = ../libctru
+AEMSTROPATH = ../../aemstro
 CFLAGS += -Wall -std=c99 -march=armv6 -O3 -I"$(CTRULIB)/include" -I$(DEVKITPRO)/libnds/include
 # LDFLAGS += --script=ccd00.ld -L"$(DEVKITARM)/arm-none-eabi/lib" -L"$(DEVKITARM)/lib/gcc/arm-none-eabi/4.7.1" -L"$(CTRULIB)/lib"
 # LDFLAGS += --script=ccd00.ld -L"$(DEVKITARM)/arm-none-eabi/lib" -L"$(CTRULIB)/lib"
index 6463bc268a3a98ad789940f1180fe6edef5468b7..557c32713cda33ccbfd6204df7be767da0974bd3 100644 (file)
@@ -1,4 +1,4 @@
-.section ".text"
+.section ".init"
 .arm
 .align 4
 .global _init
index b8bb00186882d02335f26953aefc58fd97d61534..097e09bbcde504712fada7c35870afa51490cf0c 100644 (file)
@@ -128,6 +128,14 @@ int main()
 
                        swapBuffers();
                }
+               else if(status == APP_SUSPENDING)
+               {
+                       aptReturnToMenu();
+               }
+               else if(status == APP_SLEEPMODE)
+               {
+                       aptWaitStatusEvent();
+               }
                svc_sleepThread(16666666);
        }
 
index 06a24f9e0fbaf5d1e832a26985b0e7bde2812626..a5c2e94c00929655bb8e40f72cc0063cb013b2cc 100644 (file)
@@ -9,9 +9,12 @@ typedef enum{
 }NS_APPID; // cf http://3dbrew.org/wiki/NS#AppIDs
 
 typedef enum{
+       APT_NOTINITIALIZED,
        APP_RUNNING,
        APP_SUSPENDED,
-       APP_EXITING
+       APP_EXITING,
+       APP_SUSPENDING,
+       APP_SLEEPMODE
 }APP_STATUS;
 
 extern Handle aptEvents[3];
@@ -23,6 +26,10 @@ void aptCloseSession();
 void aptSetupEventHandler();
 void aptSetStatus(APP_STATUS status);
 APP_STATUS aptGetStatus();
+u32 aptGetStatusPower();//This can be used when the status is APP_SUSPEND* to check how the return-to-menu was triggered: 0 = home-button, 1 = power-button.
+void aptSetStatusPower(u32 status);
+void aptReturnToMenu();//This should be called by the user application when aptGetStatus() returns APP_SUSPENDING, not calling this will result in return-to-menu being disabled with the status left at APP_SUSPENDING. This function will not return until the system returns to the application, or when the status was changed to APP_EXITING.
+void aptWaitStatusEvent();
 
 Result APT_GetLockHandle(Handle* handle, u16 flags, Handle* lockHandle);
 Result APT_Initialize(Handle* handle, NS_APPID appId, Handle* eventHandle1, Handle* eventHandle2);
@@ -34,7 +41,10 @@ Result APT_NotifyToWait(Handle* handle, NS_APPID appID);
 Result APT_AppletUtility(Handle* handle, u32* out, u32 a, u32 size1, u8* buf1, u32 size2, u8* buf2);
 Result APT_GlanceParameter(Handle* handle, NS_APPID appID, u32 bufferSize, u32* buffer, u32* actualSize, u8* signalType);
 Result APT_ReceiveParameter(Handle* handle, NS_APPID appID, u32 bufferSize, u32* buffer, u32* actualSize, u8* signalType);
+Result APT_SendParameter(Handle* handle, NS_APPID src_appID, NS_APPID dst_appID, u32 bufferSize, u32* buffer, Handle paramhandle, u8 signalType);
+Result APT_SendCaptureBufferInfo(Handle* handle, u32 bufferSize, u32* buffer);
 Result APT_ReplySleepQuery(Handle* handle, NS_APPID appID, u32 a);
+Result APT_ReplySleepNotificationComplete(Handle* handle, NS_APPID appID);
 Result APT_PrepareToCloseApplication(Handle* handle, u8 a);
 Result APT_CloseApplication(Handle* handle, u32 a, u32 b, u32 c);
 
index 3b16f2eff6306c4b67f805548b1fc2958f6e0392..57f3cdf6629a63854f8579d06aec7d161914c5d8 100644 (file)
@@ -14,11 +14,27 @@ typedef struct
        u32 unk;//"?"
 } GSP_FramebufferInfo;
 
+typedef struct//See this for GSP_CaptureInfoEntry and GSP_CaptureInfo: http://3dbrew.org/wiki/GSPGPU:ImportDisplayCaptureInfo
+{
+       u32 *framebuf0_vaddr;
+       u32 *framebuf1_vaddr;
+       u32 format;
+       u32 framebuf_widthbytesize;
+} GSP_CaptureInfoEntry;
+
+typedef struct
+{
+       GSP_CaptureInfoEntry screencapture[2];
+} GSP_CaptureInfo;
+
 Result gspInit();
 void gspExit();
 
 Result GSPGPU_AcquireRight(Handle *handle, u8 flags);
 Result GSPGPU_ReleaseRight(Handle *handle);
+Result GSPGPU_ImportDisplayCaptureInfo(Handle* handle, GSP_CaptureInfo *captureinfo);
+Result GSPGPU_SaveVramSysArea(Handle* handle);
+Result GSPGPU_RestoreVramSysArea(Handle* handle);
 Result GSPGPU_SetLcdForceBlack(Handle *handle, u8 flags);
 Result GSPGPU_SetBufferSwap(Handle* handle, u32 screenid, GSP_FramebufferInfo *framebufinfo);
 Result GSPGPU_FlushDataCache(Handle *handle, u8* adr, u32 size);
index 63ece7f7655e5a4935808ebf4154ff50190fb166..e9ccdfdec1f6b645b51a1844c06f38bd942e5f6d 100644 (file)
@@ -19,13 +19,117 @@ Handle aptEventHandlerThread;
 u64 aptEventHandlerStack[APT_HANDLER_STACKSIZE/8]; //u64 so that it's 8-byte aligned
 
 Handle aptStatusMutex;
-u32 aptStatus;
+Handle aptStatusEvent = 0;
+u32 aptStatus = APT_NOTINITIALIZED;
+u32 aptStatusPower = 0;
 
 u32 aptParameters[0x1000/4]; //TEMP
 
+void aptInitCaptureInfo(u32 *ns_capinfo)
+{
+       u32 tmp=0;
+       u32 main_pixsz, sub_pixsz;
+       GSP_CaptureInfo gspcapinfo;
+
+       memset(&gspcapinfo, 0, sizeof(GSP_CaptureInfo));
+
+       GSPGPU_ImportDisplayCaptureInfo(NULL, &gspcapinfo);
+
+       if(gspcapinfo.screencapture[0].framebuf0_vaddr != gspcapinfo.screencapture[1].framebuf0_vaddr)ns_capinfo[1] = 1;
+       
+       ns_capinfo[4] = gspcapinfo.screencapture[0].format & 0x7;
+       ns_capinfo[7] = gspcapinfo.screencapture[1].format & 0x7;
+
+       if(ns_capinfo[4] < 2)
+       {
+               main_pixsz = 3;
+       }
+       else
+       {
+               main_pixsz = 2;
+       }
+
+       if(ns_capinfo[7] < 2)
+       {
+               sub_pixsz = 3;
+       }
+       else
+       {
+               sub_pixsz = 2;
+       }
+
+       ns_capinfo[2] = sub_pixsz * 0x14000;
+       ns_capinfo[3] = ns_capinfo[2];
+
+       if(ns_capinfo[1])ns_capinfo[3] = main_pixsz * 0x19000 + ns_capinfo[2];
+
+       tmp = main_pixsz * 0x19000 + ns_capinfo[3];
+       ns_capinfo[0] = main_pixsz * 0x7000 + tmp;
+}
+
+void aptWaitStatusEvent()
+{
+       svc_waitSynchronization1(aptStatusEvent, U64_MAX);
+       svc_clearEvent(aptStatusEvent);
+}
+
+void aptReturnToMenu()
+{
+       u32 tmp0 = 1, tmp1 = 0;
+       u32 ns_capinfo[0x20>>2];
+       u32 tmp_params[0x20>>2];
+
+       /*aptOpenSession();
+       APT_AppletUtility(NULL, NULL, 0x6, 0x4, (u8*)&tmp0, 0x1, (u8*)&tmp1);
+       aptCloseSession();*/
+
+       aptOpenSession();
+       APT_PrepareToJumpToHomeMenu(NULL); //prepare for return to menu
+       aptCloseSession();
+
+       svc_clearEvent(aptStatusEvent);
+       aptSetStatus(APP_SUSPENDED);
+
+       GSPGPU_SaveVramSysArea(NULL);
+
+       memset(tmp_params, 0, 0x20);
+       memset(ns_capinfo, 0, 0x20);
+
+       aptInitCaptureInfo(ns_capinfo);
+
+       aptOpenSession();
+       APT_SendParameter(NULL, currentAppId, 0x101, 0x20, ns_capinfo, 0x0, 0x10);
+       aptCloseSession();
+
+       aptOpenSession();
+       APT_SendCaptureBufferInfo(NULL, 0x20, ns_capinfo);
+       aptCloseSession();
+
+       GSPGPU_ReleaseRight(NULL); //disable GSP module access
+
+       aptOpenSession();
+       APT_JumpToHomeMenu(NULL, 0x0, 0x0, 0x0); //jump !
+       aptCloseSession();
+
+       aptOpenSession();
+       APT_NotifyToWait(NULL, currentAppId);
+       aptCloseSession();
+
+       if(aptGetStatusPower()==0)//This is only executed when ret-to-menu was triggered via the home-button, not the power-button.
+       {
+               tmp0 = 0;
+               aptOpenSession();
+               APT_AppletUtility(NULL, NULL, 0x4, 0x1, (u8*)&tmp0, 0x1, (u8*)&tmp1);
+               aptCloseSession();
+       }
+
+       aptWaitStatusEvent();
+}
+
 void aptEventHandler(u32 arg)
 {
        bool runThread=true;
+
        while(runThread)
        {
                s32 syncedID=0x0;
@@ -45,17 +149,36 @@ void aptEventHandler(u32 arg)
                                        switch(signalType)
                                        {
                                                case 0x1: //home menu button got pressed
+                                               case 0x8: //power button got pressed
+                                                       if(aptGetStatus()==APP_RUNNING)
+                                                       {
+                                                               aptOpenSession();
+                                                               APT_ReplySleepQuery(NULL, currentAppId, 0x0);
+                                                               aptCloseSession();
+
+                                                               if(signalType==0x1)aptSetStatusPower(0);
+                                                               if(signalType==0x8)aptSetStatusPower(1);
+                                                               aptSetStatus(APP_SUSPENDING);//The main thread should call aptReturnToMenu() when the status gets set to this.
+                                                       }
+
+                                                       break;
+
+                                               case 0x3: //preparing to enter sleep-mode
                                                        aptOpenSession();
-                                                       APT_PrepareToJumpToHomeMenu(NULL); //prepare for return to menu
+                                                       APT_ReplySleepQuery(NULL, currentAppId, 0x1);
                                                        aptCloseSession();
+                                                       break;
 
-                                                       aptSetStatus(APP_SUSPENDED);
-                       
-                                                       GSPGPU_ReleaseRight(NULL); //disable GSP module access
-                       
+                                               case 0x5: //entering sleep-mode
                                                        aptOpenSession();
-                                                       APT_JumpToHomeMenu(NULL, 0x0, 0x0, 0x0); //jump !
+                                                       APT_ReplySleepNotificationComplete(NULL, currentAppId);
                                                        aptCloseSession();
+                                                       aptSetStatus(APP_SLEEPMODE);
+                                                       break;
+
+                                               case 0x6: //leaving sleep-mode
+                                                       GSPGPU_SetLcdForceBlack(NULL, 0);
+                                                       aptSetStatus(APP_RUNNING);
                                                        break;
                                        }
                                }
@@ -73,6 +196,7 @@ void aptEventHandler(u32 arg)
                                                        break;
                                                case 0xB: //just returned from menu
                                                        GSPGPU_AcquireRight(NULL, 0x0);
+                                                       GSPGPU_RestoreVramSysArea(NULL);
                                                        aptSetStatus(APP_RUNNING);
                                                        break;
                                                case 0xC: //exiting application
@@ -116,6 +240,8 @@ Result aptInit(NS_APPID appID)
        aptOpenSession();
        if((ret=APT_NotifyToWait(NULL, currentAppId)))return ret;
        aptCloseSession();
+
+       svc_createEvent(&aptStatusEvent, 0);
        
        return 0;
 }
@@ -153,6 +279,7 @@ void aptExit()
 
        svc_closeHandle(aptStatusMutex);
        // svc_closeHandle(aptLockHandle);
+       svc_closeHandle(aptStatusEvent);
 }
 
 void aptSetupEventHandler()
@@ -185,6 +312,8 @@ void aptSetupEventHandler()
        aptStatus=0;
        svc_releaseMutex(aptStatusMutex);
 
+       aptSetStatus(APP_RUNNING);
+
        //create thread for stuff handling APT events
        svc_createThread(&aptEventHandlerThread, aptEventHandler, 0x0, (u32*)(&aptEventHandlerStack[APT_HANDLER_STACKSIZE/8]), 0x31, 0xfffffffe);
 }
@@ -200,8 +329,35 @@ APP_STATUS aptGetStatus()
 
 void aptSetStatus(APP_STATUS status)
 {
+       u32 prevstatus;
+
        svc_waitSynchronization1(aptStatusMutex, U64_MAX);
-       aptStatus=status;
+
+       prevstatus = status;
+       aptStatus = status;
+
+       if(prevstatus!=APT_NOTINITIALIZED)
+       {
+               if(status==APP_RUNNING)svc_signalEvent(aptStatusEvent);
+               if(status==APP_EXITING)svc_signalEvent(aptStatusEvent);
+       }
+
+       svc_releaseMutex(aptStatusMutex);
+}
+
+u32 aptGetStatusPower()
+{
+       u32 ret;
+       svc_waitSynchronization1(aptStatusMutex, U64_MAX);
+       ret=aptStatusPower;
+       svc_releaseMutex(aptStatusMutex);
+       return ret;
+}
+
+void aptSetStatusPower(u32 status)
+{
+       svc_waitSynchronization1(aptStatusMutex, U64_MAX);
+       aptStatusPower = status;
        svc_releaseMutex(aptStatusMutex);
 }
 
@@ -380,6 +536,47 @@ Result APT_ReceiveParameter(Handle* handle, NS_APPID appID, u32 bufferSize, u32*
        return cmdbuf[1];
 }
 
+Result APT_SendParameter(Handle* handle, NS_APPID src_appID, NS_APPID dst_appID, u32 bufferSize, u32* buffer, Handle paramhandle, u8 signalType)
+{
+       u32* cmdbuf=getThreadCommandBuffer();
+
+       if(!handle)handle=&aptuHandle;
+
+       cmdbuf[0] = 0x000C0104; //request header code
+       cmdbuf[1] = src_appID;
+       cmdbuf[2] = dst_appID;
+       cmdbuf[3] = signalType;
+       cmdbuf[4] = bufferSize;
+
+       cmdbuf[5]=0x0;
+       cmdbuf[6] = paramhandle;
+       
+       cmdbuf[7] = (bufferSize<<14) | 2;
+       cmdbuf[8] = (u32)buffer;
+       
+       Result ret=0;
+       if((ret=svc_sendSyncRequest(*handle)))return ret;
+
+       return cmdbuf[1];
+}
+
+Result APT_SendCaptureBufferInfo(Handle* handle, u32 bufferSize, u32* buffer)
+{
+       u32* cmdbuf=getThreadCommandBuffer();
+
+       if(!handle)handle=&aptuHandle;
+
+       cmdbuf[0] = 0x00400042; //request header code
+       cmdbuf[1] = bufferSize;
+       cmdbuf[2] = (bufferSize<<14) | 2;
+       cmdbuf[3] = (u32)buffer;
+       
+       Result ret=0;
+       if((ret=svc_sendSyncRequest(*handle)))return ret;
+
+       return cmdbuf[1];
+}
+
 Result APT_ReplySleepQuery(Handle* handle, NS_APPID appID, u32 a)
 {
        if(!handle)handle=&aptuHandle;
@@ -395,6 +592,20 @@ Result APT_ReplySleepQuery(Handle* handle, NS_APPID appID, u32 a)
        return cmdbuf[1];
 }
 
+Result APT_ReplySleepNotificationComplete(Handle* handle, NS_APPID appID)
+{
+       if(!handle)handle=&aptuHandle;
+
+       u32* cmdbuf=getThreadCommandBuffer();
+       cmdbuf[0]=0x3F0040; //request header code
+       cmdbuf[1]=appID;
+       
+       Result ret=0;
+       if((ret=svc_sendSyncRequest(*handle)))return ret;
+
+       return cmdbuf[1];
+}
+
 Result APT_PrepareToCloseApplication(Handle* handle, u8 a)
 {
        if(!handle)handle=&aptuHandle;
index ea557eb198cda101830b707c1dd6c66fe4ad24dd..a47acdde55b684193d3db0b09e1f6f239a04aa6a 100644 (file)
@@ -47,6 +47,52 @@ Result GSPGPU_ReleaseRight(Handle* handle)
        return cmdbuf[1];
 }
 
+Result GSPGPU_ImportDisplayCaptureInfo(Handle* handle, GSP_CaptureInfo *captureinfo)
+{
+       if(!handle)handle=&gspGpuHandle;
+       
+       u32* cmdbuf=getThreadCommandBuffer();
+       cmdbuf[0]=0x00180000; //request header code
+
+       Result ret=0;
+       if((ret=svc_sendSyncRequest(*handle)))return ret;
+
+       ret = cmdbuf[1];
+
+       if(ret==0)
+       {
+               memcpy(captureinfo, &cmdbuf[2], 0x20);
+       }
+
+       return ret;
+}
+
+Result GSPGPU_SaveVramSysArea(Handle* handle)
+{
+       if(!handle)handle=&gspGpuHandle;
+       
+       u32* cmdbuf=getThreadCommandBuffer();
+       cmdbuf[0]=0x00190000; //request header code
+
+       Result ret=0;
+       if((ret=svc_sendSyncRequest(*handle)))return ret;
+
+       return cmdbuf[1];
+}
+
+Result GSPGPU_RestoreVramSysArea(Handle* handle)
+{
+       if(!handle)handle=&gspGpuHandle;
+       
+       u32* cmdbuf=getThreadCommandBuffer();
+       cmdbuf[0]=0x001A0000; //request header code
+
+       Result ret=0;
+       if((ret=svc_sendSyncRequest(*handle)))return ret;
+
+       return cmdbuf[1];
+}
+
 Result GSPGPU_SetLcdForceBlack(Handle* handle, u8 flags)
 {
        if(!handle)handle=&gspGpuHandle;
index 4196b20d5c27c753bb3fd612fcaa0c0f4f3df610..197fe4ea29d9010c130de2dc753929a7b05eded9 100644 (file)
@@ -2,7 +2,7 @@ CC = arm-none-eabi-gcc
 LINK = arm-none-eabi-ld
 AS = arm-none-eabi-as
 OBJCOPY = arm-none-eabi-objcopy
-CTRULIB = "../libctru"
+CTRULIB = ../libctru
 CFLAGS += -Wall -std=c99 -march=armv6 -O3 -I"$(CTRULIB)/include" -I$(DEVKITPRO)/libnds/include
 LDFLAGS += --script=ccd00.ld -L"$(DEVKITARM)/arm-none-eabi/lib" -L"$(CTRULIB)/lib"
 
@@ -28,7 +28,10 @@ endef
 
 .PHONY:=all
 
-all: $(PROJECTNAME).bin
+all: dir $(PROJECTNAME).bin
+
+dir:
+       @mkdir -p build
 
 ctrulib:
        cd $(CTRULIB) && make
index 6463bc268a3a98ad789940f1180fe6edef5468b7..557c32713cda33ccbfd6204df7be767da0974bd3 100644 (file)
@@ -1,4 +1,4 @@
-.section ".text"
+.section ".init"
 .arm
 .align 4
 .global _init
index b146328fa578aa051e3abad70a34e50bb04f5304..0fbf9b83f6b6aa9b0020466367e2ca50f4c45b70 100644 (file)
@@ -137,20 +137,32 @@ int main()
 
        aptSetupEventHandler();
        
-       while(!aptGetStatus())
+       APP_STATUS status;
+       while((status=aptGetStatus())!=APP_EXITING)
        {
-               u32 PAD=hidSharedMem[7];
-               renderEffect();
-               swapBuffers();
-               copyBuffer();
-               u32 regData=PAD|0x01000000;
-               GSPGPU_WriteHWRegs(NULL, 0x202A04, &regData, 4);
-               svc_sleepThread(1000000000);
+               if(status==APP_RUNNING)
+               {
+                       u32 PAD=hidSharedMem[7];
+                       renderEffect();
+                       swapBuffers();
+                       copyBuffer();
+                       u32 regData=PAD|0x01000000;
+                       GSPGPU_WriteHWRegs(NULL, 0x202A04, &regData, 4);
+                       svc_sleepThread(1000000000);
+               }
+               else if(status == APP_SUSPENDING)
+               {
+                       aptReturnToMenu();
+               }
+               else if(status == APP_SLEEPMODE)
+               {
+                       aptWaitStatusEvent();
+               }
        }
 
        svc_closeHandle(fsuHandle);
        hidExit();
-       gspGpuInit();
+       gspGpuExit();
        aptExit();
        svc_exitProcess();
        return 0;