From 7281abfcd723a16386f8cd6e64816714ae85329c Mon Sep 17 00:00:00 2001 From: yellows8 Date: Fri, 21 Nov 2014 00:33:14 -0500 Subject: [PATCH 01/57] Added code for APT_IsRegistered. Added code for launching library applets, which isn't usable from the homebrew launcher atm. --- libctru/include/3ds/services/apt.h | 8 +- libctru/source/services/apt.c | 198 +++++++++++++++++++++++++++-- 2 files changed, 197 insertions(+), 9 deletions(-) diff --git a/libctru/include/3ds/services/apt.h b/libctru/include/3ds/services/apt.h index af8fd5b..71419ca 100644 --- a/libctru/include/3ds/services/apt.h +++ b/libctru/include/3ds/services/apt.h @@ -17,7 +17,9 @@ typedef enum{ APP_EXITING, APP_SUSPENDING, APP_SLEEPMODE, - APP_PREPARE_SLEEPMODE + APP_PREPARE_SLEEPMODE, + APP_APPLETSTARTED, + APP_APPLETCLOSED }APP_STATUS; enum { @@ -58,6 +60,7 @@ 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_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); Result APT_AppletUtility(Handle* handle, u32* out, u32 a, u32 size1, u8* buf1, u32 size2, u8* buf2); @@ -76,4 +79,7 @@ Result APT_CheckNew3DS_System(Handle* handle, u8 *out); Result APT_CheckNew3DS(Handle* handle, u8 *out); Result APT_PrepareToDoAppJump(Handle* handle, u8 flags, u64 programID, u8 mediatype); Result APT_DoAppJump(Handle* handle, u32 NSbuf0Size, u32 NSbuf1Size, u8 *NSbuf0Ptr, u8 *NSbuf1Ptr); +Result APT_PrepareToStartLibraryApplet(Handle* handle, NS_APPID appID); +Result APT_StartLibraryApplet(Handle* handle, NS_APPID appID, Handle inhandle, u32 *parambuf, u32 parambufsize); +Result APT_LaunchLibraryApplet(NS_APPID appID, Handle inhandle, u32 *parambuf, u32 parambufsize);//This should be used for launching library applets, this uses the above APT_StartLibraryApplet/APT_PrepareToStartLibraryApplet funcs + apt*Session(). parambuf is used for APT params input, when the applet closes the output param block is copied here. This is not usable from the homebrew launcher. diff --git a/libctru/source/services/apt.c b/libctru/source/services/apt.c index ba8e131..aba8f30 100644 --- a/libctru/source/services/apt.c +++ b/libctru/source/services/apt.c @@ -36,6 +36,13 @@ Handle aptSleepSync = 0; u32 aptParameters[0x1000/4]; //TEMP +static u32 __ns_capinfo[0x20>>2]; + +static NS_APPID __apt_launchapplet_appID; +static Handle __apt_launchapplet_inhandle; +static u32 *__apt_launchapplet_parambuf; +static u32 __apt_launchapplet_parambufsize; + static void aptAppStarted(void); static Result __apt_initservicehandle() @@ -142,8 +149,6 @@ void aptReturnToMenu() { NS_APPID menu_appid; u32 tmp0 = 1, tmp1 = 0; - u32 ns_capinfo[0x20>>2]; - u32 tmp_params[0x20>>2]; if(__system_runflags&RUNFLAG_APTWORKAROUND) { @@ -173,20 +178,19 @@ void aptReturnToMenu() GSPGPU_SaveVramSysArea(NULL); // Capture screen. - memset(tmp_params, 0, 0x20); - memset(ns_capinfo, 0, 0x20); + memset(__ns_capinfo, 0, 0x20); - aptInitCaptureInfo(ns_capinfo); + aptInitCaptureInfo(__ns_capinfo); menu_appid = aptGetMenuAppID(); // Send capture-screen info to menu. aptOpenSession(); - APT_SendParameter(NULL, currentAppId, menu_appid, 0x20, ns_capinfo, 0x0, 0x10); + APT_SendParameter(NULL, currentAppId, menu_appid, 0x20, __ns_capinfo, 0x0, 0x10); aptCloseSession(); aptOpenSession(); - APT_SendCaptureBufferInfo(NULL, 0x20, ns_capinfo); + APT_SendCaptureBufferInfo(NULL, 0x20, __ns_capinfo); aptCloseSession(); // Release GSP module. @@ -214,6 +218,54 @@ void aptReturnToMenu() aptWaitStatusEvent(); } +void aptAppletStarted() +{ + u8 buf1[4], buf2[4]; + + memset(buf1, 0, 4); + + // Set status to SUSPENDED. + svcClearEvent(aptStatusEvent); + aptSetStatus(APP_SUSPENDED); + + aptOpenSession(); + APT_SendCaptureBufferInfo(NULL, 0x20, __ns_capinfo); + aptCloseSession(); + + aptOpenSession(); + APT_ReplySleepQuery(NULL, currentAppId, 0x0); + aptCloseSession(); + + aptOpenSession(); + APT_StartLibraryApplet(NULL, __apt_launchapplet_appID, __apt_launchapplet_inhandle, __apt_launchapplet_parambuf, __apt_launchapplet_parambufsize); + aptCloseSession(); + + buf1[0]=0x00; + aptOpenSession(); + APT_AppletUtility(NULL, NULL, 0x4, 0x1, buf1, 0x1, buf2); + aptCloseSession(); + + aptOpenSession(); + APT_NotifyToWait(NULL, currentAppId); + aptCloseSession(); + + buf1[0]=0x00; + aptOpenSession(); + APT_AppletUtility(NULL, NULL, 0x4, 0x1, buf1, 0x1, buf2); + aptCloseSession(); +} + +void aptAppletClosed() +{ + aptAppletUtility_Exit_RetToApp(); + + GSPGPU_AcquireRight(NULL, 0x0); + GSPGPU_RestoreVramSysArea(NULL); + + svcClearEvent(aptStatusEvent); + aptSetStatus(APP_RUNNING); +} + static void __handle_notification() { u8 type; Result ret=0; @@ -292,6 +344,13 @@ static bool __handle_incoming_parameter() { aptAppStarted(); return true; + case 0x3: // "Launched library applet finished loading" + aptSetStatus(APP_APPLETSTARTED); + return true; + case 0xA: // "Launched library applet closed" + if(__apt_launchapplet_parambuf && __apt_launchapplet_parambufsize)memcpy(__apt_launchapplet_parambuf, aptParameters, __apt_launchapplet_parambufsize); + aptSetStatus(APP_APPLETCLOSED); + return true; case 0xB: // Just returned from menu. GSPGPU_AcquireRight(NULL, 0x0); GSPGPU_RestoreVramSysArea(NULL); @@ -423,6 +482,12 @@ bool aptMainLoop() case APP_PREPARE_SLEEPMODE: aptSignalReadyForSleep(); // Fall through + case APP_APPLETSTARTED: + aptAppletStarted(); + break; + case APP_APPLETCLOSED: + aptAppletClosed(); + break; default: //case APP_NOTINITIALIZED: //case APP_SLEEPMODE: @@ -479,7 +544,7 @@ void aptSetStatus(APP_STATUS status) //if(prevstatus != APP_NOTINITIALIZED) //{ - if(status == APP_RUNNING || status == APP_EXITING || status == APP_SLEEPMODE) + if(status == APP_RUNNING || status == APP_EXITING || status == APP_SLEEPMODE || status == APP_APPLETSTARTED || status == APP_APPLETCLOSED) svcSignalEvent(aptStatusEvent); //} @@ -596,6 +661,21 @@ Result APT_GetAppletManInfo(Handle* handle, u8 inval, u8 *outval8, u32 *outval32 return cmdbuf[1]; } +Result APT_IsRegistered(Handle* handle, NS_APPID appID, u8* out) +{ + if(!handle)handle=&aptuHandle; + u32* cmdbuf=getThreadCommandBuffer(); + cmdbuf[0]=0x90040; //request header code + cmdbuf[1]=appID; + + Result ret=0; + if((ret=svcSendSyncRequest(*handle)))return ret; + + if(out)*out=cmdbuf[2]; + + return cmdbuf[1]; +} + Result APT_InquireNotification(Handle* handle, u32 appID, u8* signalType) { if(!handle)handle=&aptuHandle; @@ -949,3 +1029,105 @@ Result APT_DoAppJump(Handle* handle, u32 NSbuf0Size, u32 NSbuf1Size, u8 *NSbuf0P return cmdbuf[1]; } +Result APT_PrepareToStartLibraryApplet(Handle* handle, NS_APPID appID) +{ + if(!handle)handle=&aptuHandle; + + u32* cmdbuf=getThreadCommandBuffer(); + cmdbuf[0]=0x180040; //request header code + cmdbuf[1]=appID; + + Result ret=0; + if((ret=svcSendSyncRequest(*handle)))return ret; + + return cmdbuf[1]; +} + +Result APT_StartLibraryApplet(Handle* handle, NS_APPID appID, Handle inhandle, u32 *parambuf, u32 parambufsize) +{ + if(!handle)handle=&aptuHandle; + + u32* cmdbuf=getThreadCommandBuffer(); + cmdbuf[0]=0x1E0084; //request header code + cmdbuf[1]=appID; + cmdbuf[2]=parambufsize; + cmdbuf[3]=0; + cmdbuf[4]=inhandle; + cmdbuf[5]=(parambufsize<<14)|2; + cmdbuf[6]=(u32)parambuf; + + Result ret=0; + if((ret=svcSendSyncRequest(*handle)))return ret; + + return cmdbuf[1]; +} + +Result APT_LaunchLibraryApplet(NS_APPID appID, Handle inhandle, u32 *parambuf, u32 parambufsize) +{ + Result ret=0; + u8 tmp=0; + + u8 buf1[4]; + u8 buf2[4]; + + aptOpenSession(); + APT_ReplySleepQuery(NULL, currentAppId, 0); + aptCloseSession(); + + memset(buf1, 0, 4); + aptOpenSession(); + APT_AppletUtility(NULL, NULL, 0x4, 0x1, buf1, 0x1, buf2); + aptCloseSession(); + + aptOpenSession(); + APT_ReplySleepQuery(NULL, currentAppId, 0); + aptCloseSession(); + + aptOpenSession(); + ret=APT_PrepareToStartLibraryApplet(NULL, appID); + aptCloseSession(); + if(ret!=0)return ret; + + memset(buf1, 0, 4); + aptOpenSession(); + APT_AppletUtility(NULL, NULL, 0x4, 0x1, buf1, 0x1, buf2); + aptCloseSession(); + + while(1) + { + aptOpenSession(); + ret=APT_IsRegistered(NULL, appID, &tmp); + aptCloseSession(); + if(ret!=0)return ret; + + if(tmp!=0)break; + } + + // Set status to SUSPENDED. + svcClearEvent(aptStatusEvent); + aptSetStatus(APP_SUSPENDED); + + // Save Vram + GSPGPU_SaveVramSysArea(NULL); + + // Capture screen. + memset(__ns_capinfo, 0, 0x20); + + aptInitCaptureInfo(__ns_capinfo); + + // Send capture-screen info to the library applet. + aptOpenSession(); + APT_SendParameter(NULL, currentAppId, appID, 0x20, __ns_capinfo, 0x0, 0x2); + aptCloseSession(); + + // Release GSP module. + GSPGPU_ReleaseRight(NULL); + + __apt_launchapplet_appID = appID; + __apt_launchapplet_inhandle = inhandle; + __apt_launchapplet_parambuf = parambuf; + __apt_launchapplet_parambufsize = parambufsize; + + return 0; +} + From 57c5473f8ecdb0e8a6c490b257b73676cc5525d6 Mon Sep 17 00:00:00 2001 From: Dave Murphy Date: Fri, 21 Nov 2014 09:26:12 +0000 Subject: [PATCH 02/57] remove temp check for CTRULIB --- template/Makefile | 5 ----- 1 file changed, 5 deletions(-) diff --git a/template/Makefile b/template/Makefile index 568eda2..c4c758e 100644 --- a/template/Makefile +++ b/template/Makefile @@ -6,11 +6,6 @@ ifeq ($(strip $(DEVKITARM)),) $(error "Please set DEVKITARM in your environment. export DEVKITARM=devkitARM") endif -ifeq ($(strip $(CTRULIB)),) -# THIS IS TEMPORARY - in the future it should be at $(DEVKITPRO)/libctru -$(error "Please set CTRULIB in your environment. export CTRULIB=libctru") -endif - TOPDIR ?= $(CURDIR) include $(DEVKITARM)/3ds_rules From 0a0276dd203bd46567800c22d4bfad0c7cb262b6 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Fri, 21 Nov 2014 07:47:24 -0500 Subject: [PATCH 03/57] soc_ioctl: Add missing va_end call --- libctru/source/services/soc/soc_ioctl.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libctru/source/services/soc/soc_ioctl.c b/libctru/source/services/soc/soc_ioctl.c index 6fce0d7..416a443 100644 --- a/libctru/source/services/soc/soc_ioctl.c +++ b/libctru/source/services/soc/soc_ioctl.c @@ -33,5 +33,7 @@ int ioctl(int fd, int request, ...) break; } + va_end(ap); + return ret; } From 0db0a117518f394cd3fc59d0aaa746cace3c9c66 Mon Sep 17 00:00:00 2001 From: fincs Date: Fri, 21 Nov 2014 16:53:28 +0100 Subject: [PATCH 04/57] Update Makefile in examples --- examples/app_launch/Makefile | 5 ----- examples/gpu/Makefile | 5 ----- examples/mic/Makefile | 5 ----- examples/mvd/Makefile | 5 ----- examples/sdmc/Makefile | 5 ----- 5 files changed, 25 deletions(-) diff --git a/examples/app_launch/Makefile b/examples/app_launch/Makefile index 568eda2..c4c758e 100644 --- a/examples/app_launch/Makefile +++ b/examples/app_launch/Makefile @@ -6,11 +6,6 @@ ifeq ($(strip $(DEVKITARM)),) $(error "Please set DEVKITARM in your environment. export DEVKITARM=devkitARM") endif -ifeq ($(strip $(CTRULIB)),) -# THIS IS TEMPORARY - in the future it should be at $(DEVKITPRO)/libctru -$(error "Please set CTRULIB in your environment. export CTRULIB=libctru") -endif - TOPDIR ?= $(CURDIR) include $(DEVKITARM)/3ds_rules diff --git a/examples/gpu/Makefile b/examples/gpu/Makefile index 568eda2..c4c758e 100644 --- a/examples/gpu/Makefile +++ b/examples/gpu/Makefile @@ -6,11 +6,6 @@ ifeq ($(strip $(DEVKITARM)),) $(error "Please set DEVKITARM in your environment. export DEVKITARM=devkitARM") endif -ifeq ($(strip $(CTRULIB)),) -# THIS IS TEMPORARY - in the future it should be at $(DEVKITPRO)/libctru -$(error "Please set CTRULIB in your environment. export CTRULIB=libctru") -endif - TOPDIR ?= $(CURDIR) include $(DEVKITARM)/3ds_rules diff --git a/examples/mic/Makefile b/examples/mic/Makefile index 568eda2..c4c758e 100644 --- a/examples/mic/Makefile +++ b/examples/mic/Makefile @@ -6,11 +6,6 @@ ifeq ($(strip $(DEVKITARM)),) $(error "Please set DEVKITARM in your environment. export DEVKITARM=devkitARM") endif -ifeq ($(strip $(CTRULIB)),) -# THIS IS TEMPORARY - in the future it should be at $(DEVKITPRO)/libctru -$(error "Please set CTRULIB in your environment. export CTRULIB=libctru") -endif - TOPDIR ?= $(CURDIR) include $(DEVKITARM)/3ds_rules diff --git a/examples/mvd/Makefile b/examples/mvd/Makefile index 568eda2..c4c758e 100644 --- a/examples/mvd/Makefile +++ b/examples/mvd/Makefile @@ -6,11 +6,6 @@ ifeq ($(strip $(DEVKITARM)),) $(error "Please set DEVKITARM in your environment. export DEVKITARM=devkitARM") endif -ifeq ($(strip $(CTRULIB)),) -# THIS IS TEMPORARY - in the future it should be at $(DEVKITPRO)/libctru -$(error "Please set CTRULIB in your environment. export CTRULIB=libctru") -endif - TOPDIR ?= $(CURDIR) include $(DEVKITARM)/3ds_rules diff --git a/examples/sdmc/Makefile b/examples/sdmc/Makefile index 568eda2..c4c758e 100644 --- a/examples/sdmc/Makefile +++ b/examples/sdmc/Makefile @@ -6,11 +6,6 @@ ifeq ($(strip $(DEVKITARM)),) $(error "Please set DEVKITARM in your environment. export DEVKITARM=devkitARM") endif -ifeq ($(strip $(CTRULIB)),) -# THIS IS TEMPORARY - in the future it should be at $(DEVKITPRO)/libctru -$(error "Please set CTRULIB in your environment. export CTRULIB=libctru") -endif - TOPDIR ?= $(CURDIR) include $(DEVKITARM)/3ds_rules From 550f690c8dff76bbd3ded4808ceedfd30c6d59a9 Mon Sep 17 00:00:00 2001 From: mtheall Date: Fri, 21 Nov 2014 11:06:32 -0600 Subject: [PATCH 05/57] Add errno to error cases for FIONBIO. --- libctru/source/services/soc/soc_ioctl.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/libctru/source/services/soc/soc_ioctl.c b/libctru/source/services/soc/soc_ioctl.c index 416a443..a79d58d 100644 --- a/libctru/source/services/soc/soc_ioctl.c +++ b/libctru/source/services/soc/soc_ioctl.c @@ -16,15 +16,23 @@ int ioctl(int fd, int request, ...) switch(request) { case FIONBIO: value = va_arg(ap, int*); - if(value == NULL) ret = -1; - else if(*value) { - flags = fcntl(fd, F_GETFL, 0); - ret = fcntl(fd, F_SETFL, flags | O_NONBLOCK); + if(value == NULL) { + errno = EFAULT; + ret = -1; } - else { - flags = fcntl(fd, F_GETFL, 0); - ret = fcntl(fd, F_SETFL, flags & ~O_NONBLOCK); + + flags = fcntl(fd, F_GETFL, 0); + if(flags == -1) { + errno = SOCU_GetError(); + return -1; } + + if(*value) ret = fcntl(fd, F_SETFL, flags | O_NONBLOCK); + else ret = fcntl(fd, F_SETFL, flags & ~O_NONBLOCK); + + if(ret != 0) + errno = SOCU_GetError(); + break; default: From e7c3b7c8a15109668c1a17eb6e74302a162c506e Mon Sep 17 00:00:00 2001 From: Xeatheran Minexew Date: Fri, 21 Nov 2014 22:42:25 +0100 Subject: [PATCH 06/57] Make SHDR_GetUniformRegister name argument const --- libctru/include/3ds/gpu/shdr.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libctru/include/3ds/gpu/shdr.h b/libctru/include/3ds/gpu/shdr.h index 459aa0b..02b5128 100644 --- a/libctru/include/3ds/gpu/shdr.h +++ b/libctru/include/3ds/gpu/shdr.h @@ -59,7 +59,7 @@ typedef struct{ DVLB_s* SHDR_ParseSHBIN(u32* shbinData, u32 shbinSize); void SHDR_UseProgram(DVLB_s* dvlb, u8 id); void SHDR_FreeDVLB(DVLB_s* dvlb); -s8 SHDR_GetUniformRegister(DVLB_s* dvlb, char* name, u8 programID); +s8 SHDR_GetUniformRegister(DVLB_s* dvlb, const char* name, u8 programID); void DVLP_SendCode(DVLP_s* dvlp); void DVLP_SendOpDesc(DVLP_s* dvlp); From 4219a23ebd39849ee606b867e2ec33ba34678fc7 Mon Sep 17 00:00:00 2001 From: fincs Date: Fri, 21 Nov 2014 23:44:57 +0100 Subject: [PATCH 07/57] linear heap allocator: use rbtree to store allocation size information --- libctru/source/allocator/linear.cpp | 76 ++++++++++++++++++++++++----- 1 file changed, 64 insertions(+), 12 deletions(-) diff --git a/libctru/source/allocator/linear.cpp b/libctru/source/allocator/linear.cpp index 0a47275..e5e6b85 100644 --- a/libctru/source/allocator/linear.cpp +++ b/libctru/source/allocator/linear.cpp @@ -1,9 +1,56 @@ #include <3ds.h> +#include <3ds/util/rbtree.h> #include "mem_pool.h" extern u32 __linear_heap, __linear_heap_size; static MemPool sLinearPool; +static rbtree_t sAddrMap; + +struct addrMapNode +{ + rbtree_node node; + MemChunk chunk; +}; + +#define getAddrMapNode(x) rbtree_item((x), addrMapNode, node) + +static int addrMapNodeComparator(const rbtree_node_t* _lhs, const rbtree_node_t* _rhs) +{ + auto lhs = getAddrMapNode(_lhs)->chunk.addr; + auto rhs = getAddrMapNode(_rhs)->chunk.addr; + if (lhs < rhs) + return -1; + if (lhs > rhs) + return 1; + return 0; +} + +static void addrMapNodeDestructor(rbtree_node_t* a) +{ + free(getAddrMapNode(a)); +} + +static addrMapNode* getNode(void* addr) +{ + addrMapNode n; + n.chunk.addr = (u8*)addr; + auto p = rbtree_find(&sAddrMap, &n.node); + return p ? getAddrMapNode(p) : nullptr; +} + +static addrMapNode* newNode(const MemChunk& chunk) +{ + auto p = (addrMapNode*)malloc(sizeof(addrMapNode)); + if (!p) return nullptr; + p->chunk = chunk; + return p; +} + +static void delNode(addrMapNode* node) +{ + rbtree_remove(&sAddrMap, &node->node, addrMapNodeDestructor); +} static bool linearInit() { @@ -11,6 +58,7 @@ static bool linearInit() if (blk) { sLinearPool.AddBlock(blk); + rbtree_init(&sAddrMap, addrMapNodeComparator); return true; } return false; @@ -36,19 +84,19 @@ void* linearMemAlign(size_t size, size_t alignment) if (!sLinearPool.Ready() && !linearInit()) return nullptr; - // Reserve memory for MemChunk structure - size += alignment; - // Allocate the chunk MemChunk chunk; if (!sLinearPool.Allocate(chunk, size, shift)) return nullptr; - // Copy the MemChunk structure and return memory - auto addr = chunk.addr; - *(MemChunk*)addr = chunk; - *(u32*)(addr + alignment - sizeof(u32)) = alignment; - return addr + alignment; + auto node = newNode(chunk); + if (!node) + { + sLinearPool.Deallocate(chunk); + return nullptr; + } + if (rbtree_insert(&sAddrMap, &node->node)); + return chunk.addr; } void* linearAlloc(size_t size) @@ -64,10 +112,14 @@ void* linearRealloc(void* mem, size_t size) void linearFree(void* mem) { - // Find MemChunk structure and free the chunk - u32 alignment = *((u32*)mem - 1); - auto pChunk = (MemChunk*)((u8*)mem - alignment); - sLinearPool.Deallocate(*pChunk); + auto node = getNode(mem); + if (!node) return; + + // Free the chunk + sLinearPool.Deallocate(node->chunk); + + // Free the node + delNode(node); } u32 linearSpaceFree() From b0c29ba6586e7b09d840f8b9089b550da03aaee7 Mon Sep 17 00:00:00 2001 From: fincs Date: Fri, 21 Nov 2014 23:51:06 +0100 Subject: [PATCH 08/57] Fix typo in soc_ioctl.c --- libctru/include/3ds/linear.h | 2 +- libctru/source/services/soc/soc_ioctl.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/libctru/include/3ds/linear.h b/libctru/include/3ds/linear.h index 8fe2c7d..8722f81 100644 --- a/libctru/include/3ds/linear.h +++ b/libctru/include/3ds/linear.h @@ -2,7 +2,7 @@ // Functions for allocating/deallocating memory from linear heap void* linearAlloc(size_t size); // returns a 16-byte aligned address -void* linearMemAlign(size_t size, size_t alignment); // WARNING: wastes 'alignment' bytes +void* linearMemAlign(size_t size, size_t alignment); void* linearRealloc(void* mem, size_t size); // not implemented yet void linearFree(void* mem); u32 linearSpaceFree(); // get free linear space in bytes diff --git a/libctru/source/services/soc/soc_ioctl.c b/libctru/source/services/soc/soc_ioctl.c index a79d58d..b9dea04 100644 --- a/libctru/source/services/soc/soc_ioctl.c +++ b/libctru/source/services/soc/soc_ioctl.c @@ -23,7 +23,7 @@ int ioctl(int fd, int request, ...) flags = fcntl(fd, F_GETFL, 0); if(flags == -1) { - errno = SOCU_GetError(); + errno = SOC_GetErrno(); return -1; } @@ -31,7 +31,7 @@ int ioctl(int fd, int request, ...) else ret = fcntl(fd, F_SETFL, flags & ~O_NONBLOCK); if(ret != 0) - errno = SOCU_GetError(); + errno = SOC_GetErrno(); break; From e8c551b11496e3121466532f376b0cf671352715 Mon Sep 17 00:00:00 2001 From: Subv Date: Fri, 21 Nov 2014 22:08:05 -0500 Subject: [PATCH 09/57] Added a file for the cfg:u service. Implemented the CFGU_GetSystemModel function --- libctru/include/3ds.h | 1 + libctru/include/3ds/services/cfgu.h | 6 ++++++ libctru/source/services/cfgu.c | 31 +++++++++++++++++++++++++++++ 3 files changed, 38 insertions(+) create mode 100644 libctru/include/3ds/services/cfgu.h create mode 100644 libctru/source/services/cfgu.c diff --git a/libctru/include/3ds.h b/libctru/include/3ds.h index 65bf5a7..beec914 100644 --- a/libctru/include/3ds.h +++ b/libctru/include/3ds.h @@ -15,6 +15,7 @@ extern "C" { #include <3ds/services/ac.h> #include <3ds/services/apt.h> #include <3ds/services/cfgnor.h> +#include <3ds/services/cfgu.h> #include <3ds/services/csnd.h> #include <3ds/services/fs.h> #include <3ds/services/gsp.h> diff --git a/libctru/include/3ds/services/cfgu.h b/libctru/include/3ds/services/cfgu.h new file mode 100644 index 0000000..7e6f634 --- /dev/null +++ b/libctru/include/3ds/services/cfgu.h @@ -0,0 +1,6 @@ +#pragma once + +Result CFGU_Initialize(void); +Result CFGU_Shutdown(void); + +Result CFGU_GetSystemModel(u8* model); \ No newline at end of file diff --git a/libctru/source/services/cfgu.c b/libctru/source/services/cfgu.c new file mode 100644 index 0000000..5d49970 --- /dev/null +++ b/libctru/source/services/cfgu.c @@ -0,0 +1,31 @@ +#include +#include <3ds.h> + +Handle CFGU_handle = 0; + +Result CFGU_Initialize() +{ + return srvGetServiceHandle(&CFGU_handle, "cfg:u"); +} + +Result CFGU_Shutdown() +{ + Result ret = svcCloseHandle(CFGU_handle); + CFGU_handle = 0; + + return ret; +} + +Result CFGU_GetSystemModel(u8* model) +{ + Result ret = 0; + u32 *cmdbuf = getThreadCommandBuffer(); + + cmdbuf[0] = 0x00050000; + + if((ret = svcSendSyncRequest(CFGU_handle))!=0)return ret; + + *model = (u8)cmdbuf[2]; + + return (Result)cmdbuf[1]; +} \ No newline at end of file From 8e8685b6e77bd8c8826ec1055b3f562b76a5ea5f Mon Sep 17 00:00:00 2001 From: Subv Date: Fri, 21 Nov 2014 22:12:34 -0500 Subject: [PATCH 10/57] Addressed some style issues --- libctru/include/3ds/services/cfgu.h | 6 +++--- libctru/source/services/cfgu.c | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/libctru/include/3ds/services/cfgu.h b/libctru/include/3ds/services/cfgu.h index 7e6f634..9a9eefd 100644 --- a/libctru/include/3ds/services/cfgu.h +++ b/libctru/include/3ds/services/cfgu.h @@ -1,6 +1,6 @@ #pragma once -Result CFGU_Initialize(void); -Result CFGU_Shutdown(void); +Result initCfgu(void); +Result exitCfgu(void); -Result CFGU_GetSystemModel(u8* model); \ No newline at end of file +Result CFGU_GetSystemModel(u8* model); diff --git a/libctru/source/services/cfgu.c b/libctru/source/services/cfgu.c index 5d49970..5b43607 100644 --- a/libctru/source/services/cfgu.c +++ b/libctru/source/services/cfgu.c @@ -1,14 +1,14 @@ #include #include <3ds.h> -Handle CFGU_handle = 0; +static Handle CFGU_handle = 0; -Result CFGU_Initialize() +Result initCfgu() { return srvGetServiceHandle(&CFGU_handle, "cfg:u"); } -Result CFGU_Shutdown() +Result exitCfgu() { Result ret = svcCloseHandle(CFGU_handle); CFGU_handle = 0; @@ -28,4 +28,4 @@ Result CFGU_GetSystemModel(u8* model) *model = (u8)cmdbuf[2]; return (Result)cmdbuf[1]; -} \ No newline at end of file +} From 0cc31baaeafb39f04a8a6141cf493f07ab63144e Mon Sep 17 00:00:00 2001 From: Subv Date: Fri, 21 Nov 2014 22:40:23 -0500 Subject: [PATCH 11/57] Added more cfg:u functions GetRegionCanadaUSA GetModelNintendo2DS GetCountryCodeString --- libctru/include/3ds/services/cfgu.h | 4 ++ libctru/source/services/cfgu.c | 58 +++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+) diff --git a/libctru/include/3ds/services/cfgu.h b/libctru/include/3ds/services/cfgu.h index 9a9eefd..036e7d2 100644 --- a/libctru/include/3ds/services/cfgu.h +++ b/libctru/include/3ds/services/cfgu.h @@ -3,4 +3,8 @@ Result initCfgu(void); Result exitCfgu(void); +Result CFGU_GetRegionCanadaUSA(u8* value); Result CFGU_GetSystemModel(u8* model); +Result CFGU_GetModelNintendo2DS(u8* value); +Result CFGU_GetCountryCodeString(u16 code, u16* string); +Result CFGU_GetCountryCodeID(u16 string, u16* code); diff --git a/libctru/source/services/cfgu.c b/libctru/source/services/cfgu.c index 5b43607..14ac5c4 100644 --- a/libctru/source/services/cfgu.c +++ b/libctru/source/services/cfgu.c @@ -16,6 +16,20 @@ Result exitCfgu() return ret; } +Result CFGU_GetRegionCanadaUSA(u8* value) +{ + Result ret = 0; + u32 *cmdbuf = getThreadCommandBuffer(); + + cmdbuf[0] = 0x00040000; + + if((ret = svcSendSyncRequest(CFGU_handle))!=0)return ret; + + *value = (u8)cmdbuf[2]; + + return (Result)cmdbuf[1]; +} + Result CFGU_GetSystemModel(u8* model) { Result ret = 0; @@ -29,3 +43,47 @@ Result CFGU_GetSystemModel(u8* model) return (Result)cmdbuf[1]; } + +Result CFGU_GetModelNintendo2DS(u8* value) +{ + Result ret = 0; + u32 *cmdbuf = getThreadCommandBuffer(); + + cmdbuf[0] = 0x00060000; + + if((ret = svcSendSyncRequest(CFGU_handle))!=0)return ret; + + *value = (u8)cmdbuf[2]; + + return (Result)cmdbuf[1]; +} + +Result CFGU_GetCountryCodeString(u16 code, u16* string) +{ + Result ret = 0; + u32 *cmdbuf = getThreadCommandBuffer(); + + cmdbuf[0] = 0x00090040; + cmdbuf[1] = (u32)code; + + if((ret = svcSendSyncRequest(CFGU_handle))!=0)return ret; + + *string = (u16)cmdbuf[2]; + + return (Result)cmdbuf[1]; +} + +Result CFGU_GetCountryCodeID(u16 string, u16* code) +{ + Result ret = 0; + u32 *cmdbuf = getThreadCommandBuffer(); + + cmdbuf[0] = 0x000A0040; + cmdbuf[1] = (u32)string; + + if((ret = svcSendSyncRequest(CFGU_handle))!=0)return ret; + + *code = (u16)cmdbuf[2]; + + return (Result)cmdbuf[1]; +} From 25d445818f241ef7dc81c0fabcfb62e62aab9855 Mon Sep 17 00:00:00 2001 From: Subv Date: Fri, 21 Nov 2014 23:36:48 -0500 Subject: [PATCH 12/57] Added the PTMU_GetTotalStepCount function --- libctru/include/3ds/services/ptm.h | 1 + libctru/source/services/ptm.c | 15 +++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/libctru/include/3ds/services/ptm.h b/libctru/include/3ds/services/ptm.h index 7c595b9..825d503 100644 --- a/libctru/include/3ds/services/ptm.h +++ b/libctru/include/3ds/services/ptm.h @@ -5,3 +5,4 @@ Result ptmExit(); Result PTMU_GetBatteryLevel(Handle* servhandle, u8 *out); Result PTMU_GetBatteryChargeState(Handle* servhandle, u8 *out); +Result PTMU_GetTotalStepCount(Handle* servhandle, u32 *steps); diff --git a/libctru/source/services/ptm.c b/libctru/source/services/ptm.c index 8fa21fc..ddd298c 100644 --- a/libctru/source/services/ptm.c +++ b/libctru/source/services/ptm.c @@ -42,3 +42,18 @@ Result PTMU_GetBatteryChargeState(Handle* servhandle, u8 *out) return (Result)cmdbuf[1]; } + +Result PTMU_GetTotalStepCount(Handle* servhandle, u32 *steps) +{ + if(!servhandle)servhandle=&ptmHandle; + Result ret=0; + u32 *cmdbuf = getThreadCommandBuffer(); + + cmdbuf[0] = 0x000C0000; + + if((ret = svcSendSyncRequest(*servhandle))!=0)return ret; + + *steps = cmdbuf[2]; + + return (Result)cmdbuf[1]; +} From 240ab44f9cb070373cbfb6b0925e215e22a0b04c Mon Sep 17 00:00:00 2001 From: yellows8 Date: Sat, 22 Nov 2014 00:43:39 -0500 Subject: [PATCH 13/57] Updated httpc code and added an example. --- examples/http/Makefile | 170 ++++++++++++++++++++++++++ examples/http/README.md | 4 + examples/http/source/main.c | 128 ++++++++++++++++++++ libctru/include/3ds/services/httpc.h | 31 +++++ libctru/source/services/httpc.c | 175 ++++++++++++++++++++++++++- 5 files changed, 506 insertions(+), 2 deletions(-) create mode 100644 examples/http/Makefile create mode 100644 examples/http/README.md create mode 100644 examples/http/source/main.c diff --git a/examples/http/Makefile b/examples/http/Makefile new file mode 100644 index 0000000..c4c758e --- /dev/null +++ b/examples/http/Makefile @@ -0,0 +1,170 @@ +#--------------------------------------------------------------------------------- +.SUFFIXES: +#--------------------------------------------------------------------------------- + +ifeq ($(strip $(DEVKITARM)),) +$(error "Please set DEVKITARM in your environment. export DEVKITARM=devkitARM") +endif + +TOPDIR ?= $(CURDIR) +include $(DEVKITARM)/3ds_rules + +#--------------------------------------------------------------------------------- +# TARGET is the name of the output +# BUILD is the directory where object files & intermediate files will be placed +# SOURCES is a list of directories containing source code +# DATA is a list of directories containing data files +# INCLUDES is a list of directories containing header files +# +# NO_SMDH: if set to anything, no SMDH file is generated. +# APP_TITLE is the name of the app stored in the SMDH file (Optional) +# APP_DESCRIPTION is the description of the app stored in the SMDH file (Optional) +# APP_AUTHOR is the author of the app stored in the SMDH file (Optional) +# ICON is the filename of the icon (.png), relative to the project folder. +# If not set, it attempts to use one of the following (in this order): +# - .png +# - icon.png +# - /default_icon.png +#--------------------------------------------------------------------------------- +TARGET := $(notdir $(CURDIR)) +BUILD := build +SOURCES := source +DATA := data +INCLUDES := include + +#--------------------------------------------------------------------------------- +# options for code generation +#--------------------------------------------------------------------------------- +ARCH := -march=armv6k -mtune=mpcore -mfloat-abi=softfp + +CFLAGS := -g -Wall -O2 -mword-relocations \ + -fomit-frame-pointer -ffast-math \ + $(ARCH) + +CFLAGS += $(INCLUDE) -DARM11 -D_3DS + +CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++11 + +ASFLAGS := -g $(ARCH) +LDFLAGS = -specs=3dsx.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map) + +LIBS := -lctru -lm + +#--------------------------------------------------------------------------------- +# list of directories containing libraries, this must be the top level containing +# include and lib +#--------------------------------------------------------------------------------- +LIBDIRS := $(CTRULIB) + + +#--------------------------------------------------------------------------------- +# no real need to edit anything past this point unless you need to add additional +# rules for different file extensions +#--------------------------------------------------------------------------------- +ifneq ($(BUILD),$(notdir $(CURDIR))) +#--------------------------------------------------------------------------------- + +export OUTPUT := $(CURDIR)/$(TARGET) +export TOPDIR := $(CURDIR) + +export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \ + $(foreach dir,$(DATA),$(CURDIR)/$(dir)) + +export DEPSDIR := $(CURDIR)/$(BUILD) + +CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c))) +CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp))) +SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s))) +BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) + +#--------------------------------------------------------------------------------- +# use CXX for linking C++ projects, CC for standard C +#--------------------------------------------------------------------------------- +ifeq ($(strip $(CPPFILES)),) +#--------------------------------------------------------------------------------- + export LD := $(CC) +#--------------------------------------------------------------------------------- +else +#--------------------------------------------------------------------------------- + export LD := $(CXX) +#--------------------------------------------------------------------------------- +endif +#--------------------------------------------------------------------------------- + +export OFILES := $(addsuffix .o,$(BINFILES)) \ + $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o) + +export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \ + $(foreach dir,$(LIBDIRS),-I$(dir)/include) \ + -I$(CURDIR)/$(BUILD) + +export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) + +ifeq ($(strip $(ICON)),) + icons := $(wildcard *.png) + ifneq (,$(findstring $(TARGET).png,$(icons))) + export APP_ICON := $(TOPDIR)/$(TARGET).png + else + ifneq (,$(findstring icon.png,$(icons))) + export APP_ICON := $(TOPDIR)/icon.png + endif + endif +else + export APP_ICON := $(TOPDIR)/$(ICON) +endif + +.PHONY: $(BUILD) clean all + +#--------------------------------------------------------------------------------- +all: $(BUILD) + +$(BUILD): + @[ -d $@ ] || mkdir -p $@ + @make --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile + +#--------------------------------------------------------------------------------- +clean: + @echo clean ... + @rm -fr $(BUILD) $(TARGET).3dsx $(OUTPUT).smdh $(TARGET).elf + + +#--------------------------------------------------------------------------------- +else + +DEPENDS := $(OFILES:.o=.d) + +#--------------------------------------------------------------------------------- +# main targets +#--------------------------------------------------------------------------------- +ifeq ($(strip $(NO_SMDH)),) +.PHONY: all +all : $(OUTPUT).3dsx $(OUTPUT).smdh +endif +$(OUTPUT).3dsx : $(OUTPUT).elf +$(OUTPUT).elf : $(OFILES) + +#--------------------------------------------------------------------------------- +# you need a rule like this for each extension you use as binary data +#--------------------------------------------------------------------------------- +%.bin.o : %.bin +#--------------------------------------------------------------------------------- + @echo $(notdir $<) + @$(bin2o) + +# WARNING: This is not the right way to do this! TODO: Do it right! +#--------------------------------------------------------------------------------- +%.vsh.o : %.vsh +#--------------------------------------------------------------------------------- + @echo $(notdir $<) + @python $(AEMSTRO)/aemstro_as.py $< ../$(notdir $<).shbin + @bin2s ../$(notdir $<).shbin | $(PREFIX)as -o $@ + @echo "extern const u8" `(echo $(notdir $<).shbin | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`"_end[];" > `(echo $(notdir $<).shbin | tr . _)`.h + @echo "extern const u8" `(echo $(notdir $<).shbin | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`"[];" >> `(echo $(notdir $<).shbin | tr . _)`.h + @echo "extern const u32" `(echo $(notdir $<).shbin | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`_size";" >> `(echo $(notdir $<).shbin | tr . _)`.h + @rm ../$(notdir $<).shbin + +-include $(DEPENDS) + +#--------------------------------------------------------------------------------------- +endif +#--------------------------------------------------------------------------------------- diff --git a/examples/http/README.md b/examples/http/README.md new file mode 100644 index 0000000..8472ee2 --- /dev/null +++ b/examples/http/README.md @@ -0,0 +1,4 @@ +# http + +This is an example for using HTTPC. This downloads a raw image for displaying on the top-screen. The URL used here is a LAN-only one, hence this URL must be changed before building+running this example. + diff --git a/examples/http/source/main.c b/examples/http/source/main.c new file mode 100644 index 0000000..3d8e16d --- /dev/null +++ b/examples/http/source/main.c @@ -0,0 +1,128 @@ +#include <3ds.h> + +Result http_download(httpcContext *context)//This error handling needs updated with proper text printing once ctrulib itself supports that. +{ + Result ret=0; + u8* framebuf_top, *framebuf_bottom; + u32 statuscode=0; + u32 size=0, contentsize=0; + u8 *buf; + + framebuf_bottom = gfxGetFramebuffer(GFX_BOTTOM, GFX_LEFT, NULL, NULL); + memset(framebuf_bottom, 0x40, 240*320*3); + gfxFlushBuffers(); + gfxSwapBuffers(); + + framebuf_bottom = gfxGetFramebuffer(GFX_BOTTOM, GFX_LEFT, NULL, NULL); + memset(framebuf_bottom, 0x40, 240*320*3); + gfxFlushBuffers(); + gfxSwapBuffers(); + gspWaitForVBlank(); + + ret = httpcBeginRequest(context); + if(ret!=0)return ret; + + ret = httpcGetResponseStatusCode(context, &statuscode, 0); + if(ret!=0)return ret; + + if(statuscode!=200)return -2; + + ret=httpcGetDownloadSizeState(context, NULL, &contentsize); + if(ret!=0)return ret; + + buf = (u8*)malloc(contentsize); + if(buf==NULL)return -1; + memset(buf, 0, contentsize); + + framebuf_bottom = gfxGetFramebuffer(GFX_BOTTOM, GFX_LEFT, NULL, NULL); + memset(framebuf_bottom, 0xc0, 240*320*3); + gfxFlushBuffers(); + gfxSwapBuffers(); + + framebuf_bottom = gfxGetFramebuffer(GFX_BOTTOM, GFX_LEFT, NULL, NULL); + memset(framebuf_bottom, 0xc0, 240*320*3); + gfxFlushBuffers(); + gfxSwapBuffers(); + gspWaitForVBlank(); + + framebuf_top = gfxGetFramebuffer(GFX_TOP, GFX_LEFT, NULL, NULL); + framebuf_bottom = gfxGetFramebuffer(GFX_BOTTOM, GFX_LEFT, NULL, NULL); + + ret = httpcDownloadData(context, buf, contentsize, NULL); + if(ret!=0) + { + free(buf); + return ret; + } + + size = contentsize; + if(size>(240*400*3))size = 240*400*3; + + memset(framebuf_bottom, 0xff, 240*320*3); + memcpy(framebuf_top, buf, size); + + gfxFlushBuffers(); + gfxSwapBuffers(); + + framebuf_top = gfxGetFramebuffer(GFX_TOP, GFX_LEFT, NULL, NULL); + framebuf_bottom = gfxGetFramebuffer(GFX_BOTTOM, GFX_LEFT, NULL, NULL); + + memset(framebuf_bottom, 0xff, 240*320*3); + memcpy(framebuf_top, buf, size); + + gfxFlushBuffers(); + gfxSwapBuffers(); + gspWaitForVBlank(); + + free(buf); + + return 0; +} + +int main() +{ + Result ret=0; + httpcContext context; + + // Initialize services + srvInit(); + aptInit(); + hidInit(NULL); + gfxInit(); + //gfxSet3D(true); // uncomment if using stereoscopic 3D + httpcInit(); + + ret = httpcOpenContext(&context, "http://10.0.0.3/httpexample_rawimg.bin", 0);//Change this to your own URL. + + if(ret==0) + { + ret=http_download(&context); + httpcCloseContext(&context); + } + + // Main loop + while (aptMainLoop()) + { + gspWaitForVBlank(); + hidScanInput(); + + // Your code goes here + + u32 kDown = hidKeysDown(); + if (kDown & KEY_START) + break; // break in order to return to hbmenu + + // Flush and swap framebuffers + gfxFlushBuffers(); + gfxSwapBuffers(); + } + + // Exit services + httpcExit(); + gfxExit(); + hidExit(); + aptExit(); + srvExit(); + return 0; +} + diff --git a/libctru/include/3ds/services/httpc.h b/libctru/include/3ds/services/httpc.h index 5e53e6f..06bc877 100644 --- a/libctru/include/3ds/services/httpc.h +++ b/libctru/include/3ds/services/httpc.h @@ -1,5 +1,32 @@ #pragma once +typedef struct { + Handle servhandle; + u32 httphandle; +} httpcContext; + +typedef enum{ + HTTPCREQSTAT_INPROGRESS_REQSENT = 0x5, + HTTPCREQSTAT_DLREADY = 0x7 +} httpcReqStatus; + +#define HTTPC_RESULTCODE_DOWNLOADPENDING 0xd840a02b + +Result httpcInit(); +void httpcExit(); + +Result httpcOpenContext(httpcContext *context, char* url, u32 use_defaultproxy);//use_defaultproxy should be zero normally, unless you don't want HTTPC_SetProxyDefault() to be used automatically. +Result httpcCloseContext(httpcContext *context); +Result httpcBeginRequest(httpcContext *context); +Result httpcReceiveData(httpcContext *context, u8* buffer, u32 size); +Result httpcGetRequestState(httpcContext *context, httpcReqStatus* out); +Result httpcGetDownloadSizeState(httpcContext *context, u32* downloadedsize, u32* contentsize); +Result httpcGetResponseStatusCode(httpcContext *context, u32* out, u64 delay);//delay isn't used yet. This writes the HTTP status code from the server to out. + +Result httpcDownloadData(httpcContext *context, u8* buffer, u32 size, u32 *downloadedsize);//The *entire* content must be downloaded before using httpcCloseContext(), otherwise httpcCloseContext() will hang. + +//Using the below functions directly is not recommended, use the above functions. See also the http example. + Result HTTPC_Initialize(Handle handle); Result HTTPC_InitializeConnectionSession(Handle handle, Handle contextHandle); Result HTTPC_CreateContext(Handle handle, char* url, Handle* contextHandle); @@ -8,3 +35,7 @@ Result HTTPC_SetProxyDefault(Handle handle, Handle contextHandle); Result HTTPC_AddRequestHeaderField(Handle handle, Handle contextHandle, char* name, char* value); Result HTTPC_BeginRequest(Handle handle, Handle contextHandle); Result HTTPC_ReceiveData(Handle handle, Handle contextHandle, u8* buffer, u32 size); +Result HTTPC_GetRequestState(Handle handle, Handle contextHandle, httpcReqStatus* out); +Result HTTPC_GetDownloadSizeState(Handle handle, Handle contextHandle, u32* downloadedsize, u32* contentsize); +Result HTTPC_GetResponseStatusCode(Handle handle, Handle contextHandle, u32* out); + diff --git a/libctru/source/services/httpc.c b/libctru/source/services/httpc.c index d9e7ec7..b7a30f9 100644 --- a/libctru/source/services/httpc.c +++ b/libctru/source/services/httpc.c @@ -1,13 +1,137 @@ -#include #include <3ds.h> +Handle __httpc_servhandle = 0; + +Result httpcInit() +{ + Result ret=0; + + if(__httpc_servhandle)return 0; + if((ret=srvGetServiceHandle(&__httpc_servhandle, "http:C")))*((u32*)0x500) = ret;//return ret; + + //*((u32*)0x600) = __httpc_servhandle; + + ret = HTTPC_Initialize(__httpc_servhandle); + if(ret!=0)*((u32*)0x400) = ret;//return ret; + + return 0; +} + +void httpcExit() +{ + if(__httpc_servhandle==0)return; + + svcCloseHandle(__httpc_servhandle); +} + +Result httpcOpenContext(httpcContext *context, char* url, u32 use_defaultproxy) +{ + Result ret=0; + + ret = HTTPC_CreateContext(__httpc_servhandle, url, &context->httphandle); + if(ret!=0)*((u32*)0x100) = ret;//return ret; + + ret = srvGetServiceHandle(&context->servhandle, "http:C"); + if(ret!=0)*((u32*)0x104) = ret;//return ret; + + ret = HTTPC_InitializeConnectionSession(context->servhandle, context->httphandle); + if(ret!=0)*((u32*)0x108) = ret;//return ret; + + if(use_defaultproxy==0)return 0; + + ret = HTTPC_SetProxyDefault(context->servhandle, context->httphandle); + if(ret!=0)*((u32*)0x10c) = ret;//return ret; + + return 0; +} + +Result httpcCloseContext(httpcContext *context) +{ + Result ret=0; + + ret = HTTPC_CloseContext(context->servhandle, context->httphandle); + + svcCloseHandle(context->servhandle); + + return ret; +} + +Result httpcAddRequestHeaderField(httpcContext *context, char* name, char* value) +{ + return HTTPC_AddRequestHeaderField(context->servhandle, context->httphandle, name, value); +} + +Result httpcBeginRequest(httpcContext *context) +{ + return HTTPC_BeginRequest(context->servhandle, context->httphandle); +} + +Result httpcReceiveData(httpcContext *context, u8* buffer, u32 size) +{ + return HTTPC_ReceiveData(context->servhandle, context->httphandle, buffer, size); +} + +Result httpcGetRequestState(httpcContext *context, httpcReqStatus* out) +{ + return HTTPC_GetRequestState(context->servhandle, context->httphandle, out); +} + +Result httpcGetDownloadSizeState(httpcContext *context, u32* downloadedsize, u32* contentsize) +{ + return HTTPC_GetDownloadSizeState(context->servhandle, context->httphandle, downloadedsize, contentsize); +} + +Result httpcGetResponseStatusCode(httpcContext *context, u32* out, u64 delay) +{ + return HTTPC_GetResponseStatusCode(context->servhandle, context->httphandle, out); +} + +Result httpcDownloadData(httpcContext *context, u8* buffer, u32 size, u32 *downloadedsize) +{ + Result ret=0; + u32 contentsize=0; + u32 pos=0, sz=0; + + if(downloadedsize)*downloadedsize = 0; + + ret=httpcGetDownloadSizeState(context, NULL, &contentsize); + if(ret!=0)return ret; + + while(pos < size) + { + sz = size - pos; + + ret=httpcReceiveData(context, &buffer[pos], sz); + + if(ret==HTTPC_RESULTCODE_DOWNLOADPENDING) + { + ret=httpcGetDownloadSizeState(context, &pos, NULL); + if(ret!=0)return ret; + } + else if(ret!=0) + { + return ret; + } + else + { + pos+= sz; + } + + if(downloadedsize)*downloadedsize = pos; + } + + return 0; +} + Result HTTPC_Initialize(Handle handle) { u32* cmdbuf=getThreadCommandBuffer(); cmdbuf[0]=0x10044; //request header code cmdbuf[1]=0x1000; //unk - cmdbuf[2]=0x20; //unk + cmdbuf[2]=0x20;//processID header, following word is set to processID by the arm11kernel. + cmdbuf[4]=0; + cmdbuf[5]=0;//Some sort of handle. Result ret=0; if((ret=svcSendSyncRequest(handle)))return ret; @@ -124,3 +248,50 @@ Result HTTPC_ReceiveData(Handle handle, Handle contextHandle, u8* buffer, u32 si return cmdbuf[1]; } + +Result HTTPC_GetRequestState(Handle handle, Handle contextHandle, httpcReqStatus* out) +{ + u32* cmdbuf=getThreadCommandBuffer(); + + cmdbuf[0]=0x50040; //request header code + cmdbuf[1]=contextHandle; + + Result ret=0; + if((ret=svcSendSyncRequest(handle)))return ret; + + *out = cmdbuf[2]; + + return cmdbuf[1]; +} + +Result HTTPC_GetDownloadSizeState(Handle handle, Handle contextHandle, u32* downloadedsize, u32* contentsize) +{ + u32* cmdbuf=getThreadCommandBuffer(); + + cmdbuf[0]=0x60040; //request header code + cmdbuf[1]=contextHandle; + + Result ret=0; + if((ret=svcSendSyncRequest(handle)))return ret; + + if(downloadedsize)*downloadedsize = cmdbuf[2]; + if(contentsize)*contentsize = cmdbuf[3]; + + return cmdbuf[1]; +} + +Result HTTPC_GetResponseStatusCode(Handle handle, Handle contextHandle, u32* out) +{ + u32* cmdbuf=getThreadCommandBuffer(); + + cmdbuf[0]=0x220040; //request header code + cmdbuf[1]=contextHandle; + + Result ret=0; + if((ret=svcSendSyncRequest(handle)))return ret; + + *out = cmdbuf[2]; + + return cmdbuf[1]; +} + From 3ee89602fa359814e880de2cd257a08217bc1be0 Mon Sep 17 00:00:00 2001 From: Xeatheran Minexew Date: Sat, 22 Nov 2014 15:26:56 +0100 Subject: [PATCH 14/57] Fix previous half-baked commit --- libctru/source/gpu/shdr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libctru/source/gpu/shdr.c b/libctru/source/gpu/shdr.c index bab4166..013f17d 100644 --- a/libctru/source/gpu/shdr.c +++ b/libctru/source/gpu/shdr.c @@ -56,7 +56,7 @@ DVLB_s* SHDR_ParseSHBIN(u32* shbinData, u32 shbinSize) return ret; } -s8 SHDR_GetUniformRegister(DVLB_s* dvlb, char* name, u8 programID) +s8 SHDR_GetUniformRegister(DVLB_s* dvlb, const char* name, u8 programID) { if(!dvlb || !name)return -1; From 3fa354313ea46862d0cd53eb7665b7ffbedaf35a Mon Sep 17 00:00:00 2001 From: Xeatheran Minexew Date: Sat, 22 Nov 2014 15:27:12 +0100 Subject: [PATCH 15/57] Fix incorrect uniform setting in examples/gpu --- examples/gpu/source/main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/gpu/source/main.c b/examples/gpu/source/main.c index 17a4bee..3c177ce 100644 --- a/examples/gpu/source/main.c +++ b/examples/gpu/source/main.c @@ -167,8 +167,8 @@ void renderFrame() //setup lighting (this is specific to our shader) vect3Df_s lightDir=vnormf(vect3Df(cos(lightAngle), -1.0f, sin(lightAngle))); - GPU_SetUniform(SHDR_GetUniformRegister(shader, "lightDirection", 0), (u32*)(float[]){0.0f, -lightDir.z, -lightDir.y, -lightDir.x}, 4); - GPU_SetUniform(SHDR_GetUniformRegister(shader, "lightAmbient", 0), (u32*)(float[]){0.7f, 0.4f, 0.4f, 0.4f}, 4); + GPU_SetUniform(SHDR_GetUniformRegister(shader, "lightDirection", 0), (u32*)(float[]){0.0f, -lightDir.z, -lightDir.y, -lightDir.x}, 1); + GPU_SetUniform(SHDR_GetUniformRegister(shader, "lightAmbient", 0), (u32*)(float[]){0.7f, 0.4f, 0.4f, 0.4f}, 1); //initialize projection matrix to standard perspective stuff gsMatrixMode(GS_PROJECTION); From 30638307c6e3bad62dea696cfdf8f44e81a4fe8f Mon Sep 17 00:00:00 2001 From: Dave Murphy Date: Sat, 22 Nov 2014 20:17:41 +0000 Subject: [PATCH 16/57] remove instructions for manually patching devkitARM --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 834dcd0..59d8261 100644 --- a/README.md +++ b/README.md @@ -13,9 +13,9 @@ setup ctrulib is just a library and needs a toolchain to function. we built ctrulib to be used in conjunction with devkitARM. you may find instructions on how to install devkitARM here : http://devkitpro.org/wiki/Getting_Started -once devkitARM is installed, you will need to manually patch it with the following : http://mtheall.com/~fincs/3dsdkA/ +The most recent devkitARM (r43) includes 3DS support and a prebuilt libctru. -that done, just checkout ctrulib, build it, set your CTRULIB path and you should be good to go ! +To keep up to date with the most recent changes you'll want to checkout ctrulib, build it and install it. license ======= From 251c4d458f33e6a92bdd7a98767a6024e85758a7 Mon Sep 17 00:00:00 2001 From: Thibaut Girka Date: Sat, 22 Nov 2014 20:56:55 +0100 Subject: [PATCH 17/57] Implement PTMU_GetShellState and PTMU_GetPedometerState --- libctru/include/3ds/services/ptm.h | 2 ++ libctru/source/services/ptm.c | 30 ++++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/libctru/include/3ds/services/ptm.h b/libctru/include/3ds/services/ptm.h index 825d503..586b456 100644 --- a/libctru/include/3ds/services/ptm.h +++ b/libctru/include/3ds/services/ptm.h @@ -3,6 +3,8 @@ Result ptmInit(); Result ptmExit(); +Result PTMU_GetShellState(Handle* servhandle, u8 *out); Result PTMU_GetBatteryLevel(Handle* servhandle, u8 *out); Result PTMU_GetBatteryChargeState(Handle* servhandle, u8 *out); +Result PTMU_GetPedometerState(Handle* servhandle, u8 *out); Result PTMU_GetTotalStepCount(Handle* servhandle, u32 *steps); diff --git a/libctru/source/services/ptm.c b/libctru/source/services/ptm.c index ddd298c..e9abfb6 100644 --- a/libctru/source/services/ptm.c +++ b/libctru/source/services/ptm.c @@ -13,6 +13,21 @@ Result ptmExit() return svcCloseHandle(ptmHandle); } +Result PTMU_GetShellState(Handle* servhandle, u8 *out) +{ + if(!servhandle)servhandle=&ptmHandle; + Result ret=0; + u32 *cmdbuf = getThreadCommandBuffer(); + + cmdbuf[0] = 0x00060000; + + if((ret = svcSendSyncRequest(*servhandle))!=0)return ret; + + *out = (u8)cmdbuf[2]; + + return (Result)cmdbuf[1]; +} + Result PTMU_GetBatteryLevel(Handle* servhandle, u8 *out) { if(!servhandle)servhandle=&ptmHandle; @@ -43,6 +58,21 @@ Result PTMU_GetBatteryChargeState(Handle* servhandle, u8 *out) return (Result)cmdbuf[1]; } +Result PTMU_GetPedometerState(Handle* servhandle, u8 *out) +{ + if(!servhandle)servhandle=&ptmHandle; + Result ret=0; + u32 *cmdbuf = getThreadCommandBuffer(); + + cmdbuf[0] = 0x00090000; + + if((ret = svcSendSyncRequest(*servhandle))!=0)return ret; + + *out = (u8)cmdbuf[2]; + + return (Result)cmdbuf[1]; +} + Result PTMU_GetTotalStepCount(Handle* servhandle, u32 *steps) { if(!servhandle)servhandle=&ptmHandle; From 2815cd84c40aba741cf02498d4faa84c8ce1c82b Mon Sep 17 00:00:00 2001 From: Yuri Kunde Schlesner Date: Sat, 22 Nov 2014 20:10:00 -0200 Subject: [PATCH 18/57] Add FSUSER_RenameFile and FSUSER_RenameDirectory --- libctru/include/3ds/services/fs.h | 2 + libctru/source/services/fs.c | 142 ++++++++++++++++++++++++++++-- 2 files changed, 138 insertions(+), 6 deletions(-) diff --git a/libctru/include/3ds/services/fs.h b/libctru/include/3ds/services/fs.h index 36526f9..073f3b6 100644 --- a/libctru/include/3ds/services/fs.h +++ b/libctru/include/3ds/services/fs.h @@ -156,6 +156,8 @@ Result FSUSER_CloseArchive(Handle* handle, FS_archive* archive); Result FSUSER_CreateDirectory(Handle* handle, FS_archive archive, FS_path dirLowPath); Result FSUSER_DeleteFile(Handle *handle, FS_archive archive, FS_path fileLowPath); Result FSUSER_DeleteDirectory(Handle *handle, FS_archive archive, FS_path dirLowPath); +Result FSUSER_RenameFile(Handle *handle, FS_archive srcArchive, FS_path srcFileLowPath, FS_archive destArchive, FS_path destFileLowPath); +Result FSUSER_RenameDirectory(Handle *handle, FS_archive srcArchive, FS_path srcDirLowPath, FS_archive destArchive, FS_path destDirLowPath); Result FSUSER_GetSdmcArchiveResource(Handle *handle, u32 *sectorSize, u32 *clusterSize, u32 *numClusters, u32 *freeClusters); Result FSUSER_IsSdmcDetected(Handle *handle, u32 *detected); Result FSUSER_IsSdmcWritable(Handle *handle, u32 *writable); diff --git a/libctru/source/services/fs.c b/libctru/source/services/fs.c index 47946f8..7d80569 100644 --- a/libctru/source/services/fs.c +++ b/libctru/source/services/fs.c @@ -298,11 +298,76 @@ FSUSER_DeleteFile(Handle *handle, return cmdbuf[1]; } -/* stub */ +/*! Renames or moves a file. + * + * @param[in] handle fs:USER handle + * @param[in] srcArchive Open archive of source + * @param[in] srcFileLowPath File path to source + * @param[in] destArchive Open archive of destination + * @param[in] destFileLowPath File path to destination + * + * @returns error + * + * @internal + * + * #### Request + * + * Index Word | Description + * -----------|------------------------- + * 0 | Header code [0x08050244] + * 1 | 0 + * 2 | srcArchive.handleLow + * 3 | srcArchive.handleHigh + * 4 | srcFileLowPath.type + * 5 | srcFileLowPath.size + * 6 | destArchive.handleLow + * 7 | destArchive.handleHigh + * 8 | destFileLowPath.type + * 9 | destFileLowPath.size + * 10 | (srcFileLowPath.size << 14) \| 0x2 + * 11 | srcFileLowPath.data + * 12 | (destFileLowPath.size << 14) \| 0x2 + * 13 | destFileLowPath.data + * + * #### Response + * + * Index Word | Description + * -----------|------------------------- + * 0 | Header code + * 1 | Result code + */ Result -FSUSER_RenameFile(void) +FSUSER_RenameFile(Handle *handle, + FS_archive srcArchive, + FS_path srcFileLowPath, + FS_archive destArchive, + FS_path destFileLowPath) { - return -1; + if(!handle) + handle = &fsuHandle; + + u32 *cmdbuf = getThreadCommandBuffer(); + + cmdbuf[0] = 0x08050244; + cmdbuf[1] = 0; + cmdbuf[2] = srcArchive.handleLow; + cmdbuf[3] = srcArchive.handleHigh; + cmdbuf[4] = srcFileLowPath.type; + cmdbuf[5] = srcFileLowPath.size; + cmdbuf[6] = destArchive.handleLow; + cmdbuf[7] = destArchive.handleHigh; + cmdbuf[8] = destFileLowPath.type; + cmdbuf[9] = destFileLowPath.size; + cmdbuf[10] = (srcFileLowPath.size << 14) | 0x402; + cmdbuf[11] = (u32)srcFileLowPath.data; + cmdbuf[12] = (destFileLowPath.size << 14) | 0x802; + cmdbuf[13] = (u32)destFileLowPath.data; + + Result ret = 0; + if((ret = svcSendSyncRequest(*handle))) + return ret; + + return cmdbuf[1]; } /*! Delete a directory @@ -433,11 +498,76 @@ FSUSER_CreateDirectory(Handle *handle, return cmdbuf[1]; } -/* stub */ +/*! Renames or moves a directory. + * + * @param[in] handle fs:USER handle + * @param[in] srcArchive Open archive of source + * @param[in] srcDirLowPath Dir path to source + * @param[in] destArchive Open archive of destination + * @param[in] destDirLowPath Dir path to destination + * + * @returns error + * + * @internal + * + * #### Request + * + * Index Word | Description + * -----------|------------------------- + * 0 | Header code [0x08050244] + * 1 | 0 + * 2 | srcArchive.handleLow + * 3 | srcArchive.handleHigh + * 4 | srcDirLowPath.type + * 5 | srcDirLowPath.size + * 6 | destArchive.handleLow + * 7 | destArchive.handleHigh + * 8 | destDirLowPath.type + * 9 | destDirLowPath.size + * 10 | (srcDirLowPath.size << 14) \| 0x2 + * 11 | srcDirLowPath.data + * 12 | (destDirLowPath.size << 14) \| 0x2 + * 13 | destDirLowPath.data + * + * #### Response + * + * Index Word | Description + * -----------|------------------------- + * 0 | Header code + * 1 | Result code + */ Result -FSUSER_RenameDirectory(void) +FSUSER_RenameDirectory(Handle *handle, + FS_archive srcArchive, + FS_path srcDirLowPath, + FS_archive destArchive, + FS_path destDirLowPath) { - return -1; + if(!handle) + handle = &fsuHandle; + + u32 *cmdbuf = getThreadCommandBuffer(); + + cmdbuf[0] = 0x080A0244; + cmdbuf[1] = 0; + cmdbuf[2] = srcArchive.handleLow; + cmdbuf[3] = srcArchive.handleHigh; + cmdbuf[4] = srcDirLowPath.type; + cmdbuf[5] = srcDirLowPath.size; + cmdbuf[6] = destArchive.handleLow; + cmdbuf[7] = destArchive.handleHigh; + cmdbuf[8] = destDirLowPath.type; + cmdbuf[9] = destDirLowPath.size; + cmdbuf[10] = (srcDirLowPath.size << 14) | 0x402; + cmdbuf[11] = (u32)srcDirLowPath.data; + cmdbuf[12] = (destDirLowPath.size << 14) | 0x802; + cmdbuf[13] = (u32)destDirLowPath.data; + + Result ret = 0; + if((ret = svcSendSyncRequest(*handle))) + return ret; + + return cmdbuf[1]; } /*! Open a directory From 78f381095cc2bb8610cf2ea21abef47b18d6368f Mon Sep 17 00:00:00 2001 From: Yuri Kunde Schlesner Date: Sun, 23 Nov 2014 00:18:36 -0200 Subject: [PATCH 19/57] Fix documentation mistakes --- libctru/source/services/fs.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/libctru/source/services/fs.c b/libctru/source/services/fs.c index 7d80569..27f3e06 100644 --- a/libctru/source/services/fs.c +++ b/libctru/source/services/fs.c @@ -324,9 +324,9 @@ FSUSER_DeleteFile(Handle *handle, * 7 | destArchive.handleHigh * 8 | destFileLowPath.type * 9 | destFileLowPath.size - * 10 | (srcFileLowPath.size << 14) \| 0x2 + * 10 | (srcFileLowPath.size << 14) \| 0x402 * 11 | srcFileLowPath.data - * 12 | (destFileLowPath.size << 14) \| 0x2 + * 12 | (destFileLowPath.size << 14) \| 0x802 * 13 | destFileLowPath.data * * #### Response @@ -514,7 +514,7 @@ FSUSER_CreateDirectory(Handle *handle, * * Index Word | Description * -----------|------------------------- - * 0 | Header code [0x08050244] + * 0 | Header code [0x080A0244] * 1 | 0 * 2 | srcArchive.handleLow * 3 | srcArchive.handleHigh @@ -524,9 +524,9 @@ FSUSER_CreateDirectory(Handle *handle, * 7 | destArchive.handleHigh * 8 | destDirLowPath.type * 9 | destDirLowPath.size - * 10 | (srcDirLowPath.size << 14) \| 0x2 + * 10 | (srcDirLowPath.size << 14) \| 0x402 * 11 | srcDirLowPath.data - * 12 | (destDirLowPath.size << 14) \| 0x2 + * 12 | (destDirLowPath.size << 14) \| 0x802 * 13 | destDirLowPath.data * * #### Response From 87de7de14acf36aadc6bcff28ed2a444957d72a1 Mon Sep 17 00:00:00 2001 From: Lectem Date: Sun, 23 Nov 2014 20:57:57 +0100 Subject: [PATCH 20/57] added fsExit --- examples/sdmc/source/main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/sdmc/source/main.c b/examples/sdmc/source/main.c index 6b5a29b..e3c6142 100644 --- a/examples/sdmc/source/main.c +++ b/examples/sdmc/source/main.c @@ -100,6 +100,7 @@ int main(int argc, char** argv) //closing all handles is super important svcCloseHandle(fileHandle); //closing all services even more so + fsExit(); gfxExit(); hidExit(); aptExit(); From 3a47113dab3f6754140a58f022d2448a53c48593 Mon Sep 17 00:00:00 2001 From: Lectem Date: Sun, 23 Nov 2014 22:58:11 +0100 Subject: [PATCH 21/57] added svcCloseHandle to FSDIR_Close() FSDIR_Close() and FSFILE_Close() should have the same behavior --- libctru/source/services/fs.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/libctru/source/services/fs.c b/libctru/source/services/fs.c index 27f3e06..51af7b5 100644 --- a/libctru/source/services/fs.c +++ b/libctru/source/services/fs.c @@ -1331,6 +1331,7 @@ FSDIR_Close(Handle handle) Result ret = 0; if((ret = svcSendSyncRequest(handle))) return ret; - - return cmdbuf[1]; + ret = cmdbuf[1]; + if(!ret)ret = svcCloseHandle(handle); + return ret; } From 165e50091c805c61cafd3c8370d24e8a94f3f2a8 Mon Sep 17 00:00:00 2001 From: yellows8 Date: Sun, 23 Nov 2014 22:10:16 -0500 Subject: [PATCH 22/57] Removed debug code(exception triggers on failure) in httpc.c. --- libctru/source/services/httpc.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/libctru/source/services/httpc.c b/libctru/source/services/httpc.c index b7a30f9..5b4b949 100644 --- a/libctru/source/services/httpc.c +++ b/libctru/source/services/httpc.c @@ -7,12 +7,12 @@ Result httpcInit() Result ret=0; if(__httpc_servhandle)return 0; - if((ret=srvGetServiceHandle(&__httpc_servhandle, "http:C")))*((u32*)0x500) = ret;//return ret; + if((ret=srvGetServiceHandle(&__httpc_servhandle, "http:C")))return ret; //*((u32*)0x600) = __httpc_servhandle; ret = HTTPC_Initialize(__httpc_servhandle); - if(ret!=0)*((u32*)0x400) = ret;//return ret; + if(ret!=0)return ret; return 0; } @@ -29,18 +29,18 @@ Result httpcOpenContext(httpcContext *context, char* url, u32 use_defaultproxy) Result ret=0; ret = HTTPC_CreateContext(__httpc_servhandle, url, &context->httphandle); - if(ret!=0)*((u32*)0x100) = ret;//return ret; + if(ret!=0)return ret; ret = srvGetServiceHandle(&context->servhandle, "http:C"); - if(ret!=0)*((u32*)0x104) = ret;//return ret; + if(ret!=0)return ret; ret = HTTPC_InitializeConnectionSession(context->servhandle, context->httphandle); - if(ret!=0)*((u32*)0x108) = ret;//return ret; + if(ret!=0)return ret; if(use_defaultproxy==0)return 0; ret = HTTPC_SetProxyDefault(context->servhandle, context->httphandle); - if(ret!=0)*((u32*)0x10c) = ret;//return ret; + if(ret!=0)return ret; return 0; } From 15cd3bd2c32dc36f1fc46ce79fa5522844d9daf6 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Mon, 24 Nov 2014 08:31:41 -0500 Subject: [PATCH 23/57] soc_ioctl: Add a missing va_end call --- libctru/source/services/soc/soc_ioctl.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libctru/source/services/soc/soc_ioctl.c b/libctru/source/services/soc/soc_ioctl.c index b9dea04..4125646 100644 --- a/libctru/source/services/soc/soc_ioctl.c +++ b/libctru/source/services/soc/soc_ioctl.c @@ -24,6 +24,7 @@ int ioctl(int fd, int request, ...) flags = fcntl(fd, F_GETFL, 0); if(flags == -1) { errno = SOC_GetErrno(); + va_end(ap); return -1; } From c91921616e4a8f4aa79178e717ae65ed03459d6e Mon Sep 17 00:00:00 2001 From: yellows8 Date: Mon, 24 Nov 2014 22:58:07 -0500 Subject: [PATCH 24/57] Fixed svcWaitSynchronizationN, previously this didn't save/restore r4 on the stack. --- libctru/source/svc.s | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/libctru/source/svc.s b/libctru/source/svc.s index f918369..43457aa 100644 --- a/libctru/source/svc.s +++ b/libctru/source/svc.s @@ -187,11 +187,13 @@ svcWaitSynchronization: .type svcWaitSynchronizationN, %function svcWaitSynchronizationN: str r5, [sp, #-4]! + str r4, [sp, #-4]! mov r5, r0 - ldr r0, [sp, #0x4] - ldr r4, [sp, #0x4+0x4] + ldr r0, [sp, #0x8] + ldr r4, [sp, #0x8+0x4] svc 0x25 str r1, [r5] + ldr r4, [sp], #4 ldr r5, [sp], #4 bx lr From ffef3fd06b0ceba44ad41f6d3941b615422136ae Mon Sep 17 00:00:00 2001 From: yellows8 Date: Mon, 24 Nov 2014 23:05:58 -0500 Subject: [PATCH 25/57] Added warning in the mic example README regarding broken MIC. --- examples/mic/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/examples/mic/README.md b/examples/mic/README.md index f3e6d72..3f0c74c 100644 --- a/examples/mic/README.md +++ b/examples/mic/README.md @@ -3,3 +3,5 @@ mic Example for using the microphone with ctrulib. Hold down the A button to record, the app will then play the recorded audio once the A button is released. Roughly 32 seconds of audio can be recorded with the default audiobuf size in this app. +Do not use this example(and/or ctrulib MIC?), since MIC is broken currently. + From 300a0ed1256335ecb76f4930b81a6d06189c11d3 Mon Sep 17 00:00:00 2001 From: yellows8 Date: Mon, 24 Nov 2014 23:22:24 -0500 Subject: [PATCH 26/57] Fixed word-index that the handle is loaded from in the cmdreply, for MIC_GetEventHandle(). --- libctru/source/services/mic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libctru/source/services/mic.c b/libctru/source/services/mic.c index 395792b..817b9aa 100644 --- a/libctru/source/services/mic.c +++ b/libctru/source/services/mic.c @@ -207,7 +207,7 @@ Result MIC_GetEventHandle(Handle *handle) if((ret = svcSendSyncRequest(MIC_handle))!=0)return ret; - if(handle)*handle = cmdbuf[2]; + if(handle)*handle = cmdbuf[3]; return (Result)cmdbuf[1]; } From 6adaa95c18762d51935a94efec46d907c1507981 Mon Sep 17 00:00:00 2001 From: yellows8 Date: Mon, 24 Nov 2014 23:42:47 -0500 Subject: [PATCH 27/57] Updated mic example. Returning from the example then launching it again via hbmenu is broken. --- examples/mic/source/main.c | 82 ++++++++++++++++++++++---------------- 1 file changed, 47 insertions(+), 35 deletions(-) diff --git a/examples/mic/source/main.c b/examples/mic/source/main.c index 8e6fc11..89ece51 100644 --- a/examples/mic/source/main.c +++ b/examples/mic/source/main.c @@ -11,13 +11,14 @@ int main() u8 *audiobuf; u32 audiobuf_size = 0x100000, audiobuf_pos = 0; u8 control=0x40; + u32 audio_initialized = 0; srvInit(); aptInit(); gfxInit(); hidInit(NULL); - CSND_initialize(NULL); + if(CSND_initialize(NULL)==0)audio_initialized = 1; sharedmem = (u32*)memalign(0x1000, sharedmem_size); audiobuf = linearAlloc(audiobuf_size); @@ -26,52 +27,63 @@ int main() while(aptMainLoop()) { - framebuf = gfxGetFramebuffer(GFX_TOP, GFX_LEFT, NULL, NULL); hidScanInput(); + gspWaitForVBlank(); - if(hidKeysDown() & KEY_A) + u32 kDown = hidKeysDown(); + if (kDown & KEY_START) + break; // break in order to return to hbmenu + + if(audio_initialized) { - audiobuf_pos = 0; - - CSND_setchannel_playbackstate(0x8, 0);//Stop audio playback. - CSND_sharedmemtype0_cmdupdatestate(0); - - MIC_SetRecording(1); - - memset(framebuf, 0x20, 0x46500); - } - - if((hidKeysHeld() & KEY_A) && audiobuf_pos < audiobuf_size) - { - audiobuf_pos+= MIC_ReadAudioData(&audiobuf[audiobuf_pos], audiobuf_size-audiobuf_pos, 1); - if(audiobuf_pos > audiobuf_size)audiobuf_pos = audiobuf_size; - - memset(framebuf, 0x60, 0x46500); - } - - if(hidKeysUp() & KEY_A) - { - MIC_SetRecording(0); - GSPGPU_FlushDataCache(NULL, audiobuf, audiobuf_pos); - CSND_playsound(0x8, CSND_LOOP_DISABLE, CSND_ENCODING_PCM16, 16000, (u32*)audiobuf, NULL, audiobuf_pos, 2, 0); - - memset(framebuf, 0xe0, 0x46500); - - gfxFlushBuffers(); - gfxSwapBuffers(); - framebuf = gfxGetFramebuffer(GFX_TOP, GFX_LEFT, NULL, NULL); - memset(framebuf, 0xe0, 0x46500); + + if(kDown & KEY_A) + { + audiobuf_pos = 0; + + CSND_setchannel_playbackstate(0x8, 0);//Stop audio playback. + CSND_sharedmemtype0_cmdupdatestate(0); + + MIC_SetRecording(1); + + memset(framebuf, 0x20, 0x46500); + } + + if((hidKeysHeld() & KEY_A) && audiobuf_pos < audiobuf_size) + { + audiobuf_pos+= MIC_ReadAudioData(&audiobuf[audiobuf_pos], audiobuf_size-audiobuf_pos, 1); + if(audiobuf_pos > audiobuf_size)audiobuf_pos = audiobuf_size; + + memset(framebuf, 0x60, 0x46500); + } + + if(hidKeysUp() & KEY_A) + { + MIC_SetRecording(0); + GSPGPU_FlushDataCache(NULL, audiobuf, audiobuf_pos); + CSND_playsound(0x8, CSND_LOOP_DISABLE, CSND_ENCODING_PCM16, 16000, (u32*)audiobuf, NULL, audiobuf_pos, 2, 0); + + memset(framebuf, 0xe0, 0x46500); + + gfxFlushBuffers(); + gfxSwapBuffers(); + + framebuf = gfxGetFramebuffer(GFX_TOP, GFX_LEFT, NULL, NULL); + memset(framebuf, 0xe0, 0x46500); + } } gfxFlushBuffers(); gfxSwapBuffers(); - gspWaitForVBlank(); } MIC_Shutdown(); - CSND_shutdown(); + if(audio_initialized)CSND_shutdown(); + + free(sharedmem); + linearFree(audiobuf); hidExit(); gfxExit(); From c5aa5ebbbc316be5cc17ab41103f5cc6fad732c8 Mon Sep 17 00:00:00 2001 From: plutoo Date: Wed, 26 Nov 2014 01:32:47 +0100 Subject: [PATCH 28/57] added gfxSetScreenFormat --- libctru/include/3ds/gfx.h | 2 ++ libctru/source/gfx.c | 33 +++++++++++++++++++++++++++++---- 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/libctru/include/3ds/gfx.h b/libctru/include/3ds/gfx.h index 7953ca6..2965210 100644 --- a/libctru/include/3ds/gfx.h +++ b/libctru/include/3ds/gfx.h @@ -1,5 +1,6 @@ #pragma once #include <3ds/types.h> +#include <3ds/services/gsp.h> typedef enum { @@ -20,6 +21,7 @@ void gfxExit(); //control stuff void gfxSet3D(bool enable); +void gfxSetScreenFormat(gfxScreen_t screen, GSP_FramebufferFormats format); void gfxFlushBuffers(); void gfxSwapBuffers(); void gfxSwapBuffersGpu(); diff --git a/libctru/source/gfx.c b/libctru/source/gfx.c index d32dcc6..702051b 100644 --- a/libctru/source/gfx.c +++ b/libctru/source/gfx.c @@ -17,11 +17,36 @@ bool enable3d; Handle gspEvent, gspSharedMemHandle; +GSP_FramebufferFormats topFormat = GSP_BGR8_OES; +GSP_FramebufferFormats botFormat = GSP_BGR8_OES; + void gfxSet3D(bool enable) { enable3d=enable; } +void gfxSetScreenFormat(gfxScreen_t screen, GSP_FramebufferFormats format) { + if(screen==GFX_TOP) + topFormat = format; + else + botFormat = format; +} + +static u32 __get_bytes_per_pixel(GSP_FramebufferFormats format) { + switch(format) { + case GSP_RGBA8_OES: + return 4; + case GSP_BGR8_OES: + return 3; + case GSP_RGB565_OES: + case GSP_RGB5_A1_OES: + case GSP_RGBA4_OES: + return 2; + } + + return 3; +} + void gfxSetFramebufferInfo(gfxScreen_t screen, u8 id) { if(screen==GFX_TOP) @@ -30,17 +55,17 @@ void gfxSetFramebufferInfo(gfxScreen_t screen, u8 id) topFramebufferInfo.framebuf0_vaddr=(u32*)gfxTopLeftFramebuffers[id]; if(enable3d)topFramebufferInfo.framebuf1_vaddr=(u32*)gfxTopRightFramebuffers[id]; else topFramebufferInfo.framebuf1_vaddr=topFramebufferInfo.framebuf0_vaddr; - topFramebufferInfo.framebuf_widthbytesize=240*3; + topFramebufferInfo.framebuf_widthbytesize=240*__get_bytes_per_pixel(topFormat); u8 bit5=(enable3d!=0); - topFramebufferInfo.format=((1)<<8)|((1^bit5)<<6)|((bit5)<<5)|GSP_BGR8_OES; + topFramebufferInfo.format=((1)<<8)|((1^bit5)<<6)|((bit5)<<5)|topFormat; topFramebufferInfo.framebuf_dispselect=id; topFramebufferInfo.unk=0x00000000; }else{ bottomFramebufferInfo.active_framebuf=id; bottomFramebufferInfo.framebuf0_vaddr=(u32*)gfxBottomFramebuffers[id]; bottomFramebufferInfo.framebuf1_vaddr=0x00000000; - bottomFramebufferInfo.framebuf_widthbytesize=240*3; - bottomFramebufferInfo.format=GSP_BGR8_OES; + bottomFramebufferInfo.framebuf_widthbytesize=240*__get_bytes_per_pixel(botFormat); + bottomFramebufferInfo.format=botFormat; bottomFramebufferInfo.framebuf_dispselect=id; bottomFramebufferInfo.unk=0x00000000; } From 866cb1ff56d67fc565b177f2f8f05cc95dbca073 Mon Sep 17 00:00:00 2001 From: yellows8 Date: Wed, 26 Nov 2014 22:12:20 -0500 Subject: [PATCH 29/57] Added library applet launching example, this isn't usable from the homebrew launcher. --- examples/libapplet_launch/Makefile | 170 ++++++++++++++++++++++++ examples/libapplet_launch/README.md | 7 + examples/libapplet_launch/source/main.c | 50 +++++++ 3 files changed, 227 insertions(+) create mode 100644 examples/libapplet_launch/Makefile create mode 100644 examples/libapplet_launch/README.md create mode 100644 examples/libapplet_launch/source/main.c diff --git a/examples/libapplet_launch/Makefile b/examples/libapplet_launch/Makefile new file mode 100644 index 0000000..c4c758e --- /dev/null +++ b/examples/libapplet_launch/Makefile @@ -0,0 +1,170 @@ +#--------------------------------------------------------------------------------- +.SUFFIXES: +#--------------------------------------------------------------------------------- + +ifeq ($(strip $(DEVKITARM)),) +$(error "Please set DEVKITARM in your environment. export DEVKITARM=devkitARM") +endif + +TOPDIR ?= $(CURDIR) +include $(DEVKITARM)/3ds_rules + +#--------------------------------------------------------------------------------- +# TARGET is the name of the output +# BUILD is the directory where object files & intermediate files will be placed +# SOURCES is a list of directories containing source code +# DATA is a list of directories containing data files +# INCLUDES is a list of directories containing header files +# +# NO_SMDH: if set to anything, no SMDH file is generated. +# APP_TITLE is the name of the app stored in the SMDH file (Optional) +# APP_DESCRIPTION is the description of the app stored in the SMDH file (Optional) +# APP_AUTHOR is the author of the app stored in the SMDH file (Optional) +# ICON is the filename of the icon (.png), relative to the project folder. +# If not set, it attempts to use one of the following (in this order): +# - .png +# - icon.png +# - /default_icon.png +#--------------------------------------------------------------------------------- +TARGET := $(notdir $(CURDIR)) +BUILD := build +SOURCES := source +DATA := data +INCLUDES := include + +#--------------------------------------------------------------------------------- +# options for code generation +#--------------------------------------------------------------------------------- +ARCH := -march=armv6k -mtune=mpcore -mfloat-abi=softfp + +CFLAGS := -g -Wall -O2 -mword-relocations \ + -fomit-frame-pointer -ffast-math \ + $(ARCH) + +CFLAGS += $(INCLUDE) -DARM11 -D_3DS + +CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++11 + +ASFLAGS := -g $(ARCH) +LDFLAGS = -specs=3dsx.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map) + +LIBS := -lctru -lm + +#--------------------------------------------------------------------------------- +# list of directories containing libraries, this must be the top level containing +# include and lib +#--------------------------------------------------------------------------------- +LIBDIRS := $(CTRULIB) + + +#--------------------------------------------------------------------------------- +# no real need to edit anything past this point unless you need to add additional +# rules for different file extensions +#--------------------------------------------------------------------------------- +ifneq ($(BUILD),$(notdir $(CURDIR))) +#--------------------------------------------------------------------------------- + +export OUTPUT := $(CURDIR)/$(TARGET) +export TOPDIR := $(CURDIR) + +export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \ + $(foreach dir,$(DATA),$(CURDIR)/$(dir)) + +export DEPSDIR := $(CURDIR)/$(BUILD) + +CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c))) +CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp))) +SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s))) +BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) + +#--------------------------------------------------------------------------------- +# use CXX for linking C++ projects, CC for standard C +#--------------------------------------------------------------------------------- +ifeq ($(strip $(CPPFILES)),) +#--------------------------------------------------------------------------------- + export LD := $(CC) +#--------------------------------------------------------------------------------- +else +#--------------------------------------------------------------------------------- + export LD := $(CXX) +#--------------------------------------------------------------------------------- +endif +#--------------------------------------------------------------------------------- + +export OFILES := $(addsuffix .o,$(BINFILES)) \ + $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o) + +export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \ + $(foreach dir,$(LIBDIRS),-I$(dir)/include) \ + -I$(CURDIR)/$(BUILD) + +export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) + +ifeq ($(strip $(ICON)),) + icons := $(wildcard *.png) + ifneq (,$(findstring $(TARGET).png,$(icons))) + export APP_ICON := $(TOPDIR)/$(TARGET).png + else + ifneq (,$(findstring icon.png,$(icons))) + export APP_ICON := $(TOPDIR)/icon.png + endif + endif +else + export APP_ICON := $(TOPDIR)/$(ICON) +endif + +.PHONY: $(BUILD) clean all + +#--------------------------------------------------------------------------------- +all: $(BUILD) + +$(BUILD): + @[ -d $@ ] || mkdir -p $@ + @make --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile + +#--------------------------------------------------------------------------------- +clean: + @echo clean ... + @rm -fr $(BUILD) $(TARGET).3dsx $(OUTPUT).smdh $(TARGET).elf + + +#--------------------------------------------------------------------------------- +else + +DEPENDS := $(OFILES:.o=.d) + +#--------------------------------------------------------------------------------- +# main targets +#--------------------------------------------------------------------------------- +ifeq ($(strip $(NO_SMDH)),) +.PHONY: all +all : $(OUTPUT).3dsx $(OUTPUT).smdh +endif +$(OUTPUT).3dsx : $(OUTPUT).elf +$(OUTPUT).elf : $(OFILES) + +#--------------------------------------------------------------------------------- +# you need a rule like this for each extension you use as binary data +#--------------------------------------------------------------------------------- +%.bin.o : %.bin +#--------------------------------------------------------------------------------- + @echo $(notdir $<) + @$(bin2o) + +# WARNING: This is not the right way to do this! TODO: Do it right! +#--------------------------------------------------------------------------------- +%.vsh.o : %.vsh +#--------------------------------------------------------------------------------- + @echo $(notdir $<) + @python $(AEMSTRO)/aemstro_as.py $< ../$(notdir $<).shbin + @bin2s ../$(notdir $<).shbin | $(PREFIX)as -o $@ + @echo "extern const u8" `(echo $(notdir $<).shbin | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`"_end[];" > `(echo $(notdir $<).shbin | tr . _)`.h + @echo "extern const u8" `(echo $(notdir $<).shbin | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`"[];" >> `(echo $(notdir $<).shbin | tr . _)`.h + @echo "extern const u32" `(echo $(notdir $<).shbin | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`_size";" >> `(echo $(notdir $<).shbin | tr . _)`.h + @rm ../$(notdir $<).shbin + +-include $(DEPENDS) + +#--------------------------------------------------------------------------------------- +endif +#--------------------------------------------------------------------------------------- diff --git a/examples/libapplet_launch/README.md b/examples/libapplet_launch/README.md new file mode 100644 index 0000000..3b1478b --- /dev/null +++ b/examples/libapplet_launch/README.md @@ -0,0 +1,7 @@ +libapplet_launch +======= + +Example for launching library applets. This launches the extrapad library applet(Circle Pad Pro calibration applet) when the B button is pressed. + +This is not usable from the homebrew launcher. + diff --git a/examples/libapplet_launch/source/main.c b/examples/libapplet_launch/source/main.c new file mode 100644 index 0000000..d4244a3 --- /dev/null +++ b/examples/libapplet_launch/source/main.c @@ -0,0 +1,50 @@ +#include <3ds.h> + +int main() +{ + u32 val, i; + + // Initialize services + srvInit(); + aptInit(); + hidInit(NULL); + gfxInit(); + //gfxSet3D(true); // uncomment if using stereoscopic 3D + + val = 0x22447899; + + // Main loop + while (aptMainLoop()) + { + gspWaitForVBlank(); + hidScanInput(); + + // Your code goes here + + u32 kDown = hidKeysDown(); + if (kDown & KEY_START) + break; // break in order to return to hbmenu + + if (kDown & KEY_B)APT_LaunchLibraryApplet(0x408, 0, NULL, 0);//Launch the extrapad library applet when button B is pressed. + + // Example rendering code that displays a white pixel + // Please note that the 3DS screens are sideways (thus 240x400 and 240x320) + u32* fb = (u32*)gfxGetFramebuffer(GFX_TOP, GFX_LEFT, NULL, NULL); + + for(i=0; i<(0x46500>>2); i++)fb[i] = val; + + val+= 0x44; + + // Flush and swap framebuffers + gfxFlushBuffers(); + gfxSwapBuffers(); + } + + // Exit services + gfxExit(); + hidExit(); + aptExit(); + srvExit(); + return 0; +} + From 58b988ab9729678a34f7ebf42ff6a43a0a1fdf7c Mon Sep 17 00:00:00 2001 From: yellows8 Date: Thu, 27 Nov 2014 11:27:21 -0500 Subject: [PATCH 30/57] Added comments to GSP_FramebufferFormats for the pixel byte-sizes. --- libctru/include/3ds/services/gsp.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/libctru/include/3ds/services/gsp.h b/libctru/include/3ds/services/gsp.h index d324b9a..e65245d 100644 --- a/libctru/include/3ds/services/gsp.h +++ b/libctru/include/3ds/services/gsp.h @@ -15,11 +15,11 @@ typedef struct typedef enum { - GSP_RGBA8_OES=0, - GSP_BGR8_OES=1, - GSP_RGB565_OES=2, - GSP_RGB5_A1_OES=3, - GSP_RGBA4_OES=4 + GSP_RGBA8_OES=0, //pixel_size = 4-bytes + GSP_BGR8_OES=1, //pixel_size = 3-bytes + GSP_RGB565_OES=2, //pixel_size = 2-bytes + GSP_RGB5_A1_OES=3, //pixel_size = 2-bytes + GSP_RGBA4_OES=4 //pixel_size = 2-bytes }GSP_FramebufferFormats; typedef struct//See this for GSP_CaptureInfoEntry and GSP_CaptureInfo: http://3dbrew.org/wiki/GSPGPU:ImportDisplayCaptureInfo From 56b1c2755c3f0433e49912c57a5ef16681837d8f Mon Sep 17 00:00:00 2001 From: yellows8 Date: Fri, 28 Nov 2014 01:26:20 -0500 Subject: [PATCH 31/57] Added note about broken applet process termination with APT_LaunchLibraryApplet(). --- libctru/include/3ds/services/apt.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libctru/include/3ds/services/apt.h b/libctru/include/3ds/services/apt.h index 71419ca..15db7b7 100644 --- a/libctru/include/3ds/services/apt.h +++ b/libctru/include/3ds/services/apt.h @@ -81,5 +81,5 @@ Result APT_PrepareToDoAppJump(Handle* handle, u8 flags, u64 programID, u8 mediat Result APT_DoAppJump(Handle* handle, u32 NSbuf0Size, u32 NSbuf1Size, u8 *NSbuf0Ptr, u8 *NSbuf1Ptr); Result APT_PrepareToStartLibraryApplet(Handle* handle, NS_APPID appID); Result APT_StartLibraryApplet(Handle* handle, NS_APPID appID, Handle inhandle, u32 *parambuf, u32 parambufsize); -Result APT_LaunchLibraryApplet(NS_APPID appID, Handle inhandle, u32 *parambuf, u32 parambufsize);//This should be used for launching library applets, this uses the above APT_StartLibraryApplet/APT_PrepareToStartLibraryApplet funcs + apt*Session(). parambuf is used for APT params input, when the applet closes the output param block is copied here. This is not usable from the homebrew launcher. +Result APT_LaunchLibraryApplet(NS_APPID appID, Handle inhandle, u32 *parambuf, u32 parambufsize);//This should be used for launching library applets, this uses the above APT_StartLibraryApplet/APT_PrepareToStartLibraryApplet funcs + apt*Session(). parambuf is used for APT params input, when the applet closes the output param block is copied here. This is not usable from the homebrew launcher. This is broken: when the applet does get launched at all, the applet process doesn't actually get terminated when the applet gets closed. From 8dbe9d9128dc72b8d053ba28a9abde27387741a0 Mon Sep 17 00:00:00 2001 From: yellows8 Date: Fri, 28 Nov 2014 02:12:49 -0500 Subject: [PATCH 32/57] Added more code to aptAppletUtility_Exit_RetToApp() for when a library applet is closing, but this still doesn't fix the broken applet process termination. --- libctru/source/services/apt.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/libctru/source/services/apt.c b/libctru/source/services/apt.c index aba8f30..d1cc18a 100644 --- a/libctru/source/services/apt.c +++ b/libctru/source/services/apt.c @@ -103,7 +103,7 @@ void aptWaitStatusEvent() svcClearEvent(aptStatusEvent); } -void aptAppletUtility_Exit_RetToApp() +void aptAppletUtility_Exit_RetToApp(u32 type) { u8 buf1[4], buf2[4]; @@ -132,6 +132,13 @@ void aptAppletUtility_Exit_RetToApp() aptOpenSession(); APT_AppletUtility(NULL, NULL, 0x4, 0x1, buf1, 0x1, buf2); aptCloseSession(); + + if(type) + { + aptOpenSession(); + APT_AppletUtility(NULL, NULL, 0x4, 0x1, buf1, 0x1, buf2); + aptCloseSession(); + } } NS_APPID aptGetMenuAppID() @@ -257,7 +264,7 @@ void aptAppletStarted() void aptAppletClosed() { - aptAppletUtility_Exit_RetToApp(); + aptAppletUtility_Exit_RetToApp(1); GSPGPU_AcquireRight(NULL, 0x0); GSPGPU_RestoreVramSysArea(NULL); @@ -354,7 +361,7 @@ static bool __handle_incoming_parameter() { case 0xB: // Just returned from menu. GSPGPU_AcquireRight(NULL, 0x0); GSPGPU_RestoreVramSysArea(NULL); - aptAppletUtility_Exit_RetToApp(); + aptAppletUtility_Exit_RetToApp(0); aptSetStatus(APP_RUNNING); return true; @@ -436,7 +443,7 @@ Result aptInit(void) void aptExit() { - if(!(__system_runflags&RUNFLAG_APTWORKAROUND))aptAppletUtility_Exit_RetToApp(); + if(!(__system_runflags&RUNFLAG_APTWORKAROUND))aptAppletUtility_Exit_RetToApp(0); // This is only executed when application-termination was triggered via the home-menu power-off screen. if(aptGetStatusPower() == 1) From ea97e7a5292319bd9b49ab42716add72812509eb Mon Sep 17 00:00:00 2001 From: Dave Murphy Date: Fri, 28 Nov 2014 13:13:34 +0000 Subject: [PATCH 33/57] stop polluting 3ds headers with extra system headers --- libctru/include/3ds/services/fs.h | 19 ++----------------- libctru/include/3ds/types.h | 1 - libctru/source/allocator/linear.cpp | 1 + libctru/source/allocator/mem_pool.h | 1 + libctru/source/sdmc_dev.c | 1 + libctru/source/services/fs.c | 16 ++++++++++++++++ libctru/source/services/httpc.c | 1 + libctru/source/services/pm.c | 1 + libctru/source/services/soc/soc_common.h | 1 + 9 files changed, 24 insertions(+), 18 deletions(-) diff --git a/libctru/include/3ds/services/fs.h b/libctru/include/3ds/services/fs.h index 073f3b6..e5f573d 100644 --- a/libctru/include/3ds/services/fs.h +++ b/libctru/include/3ds/services/fs.h @@ -1,5 +1,4 @@ #pragma once -#include #include <3ds/types.h> /*! @file FS.h @@ -128,25 +127,11 @@ typedef struct u64 fileSize; //!< file size } FS_dirent; -/*! Create an FS_path from a type and data pointer. - * - * @param[in] type Path type. - * @param[in] path Pointer to path data. - * - * @returns FS_path - * - * @sa FS_pathType - */ -static inline FS_path -FS_makePath(FS_pathType type, - const char *path) -{ - return (FS_path){type, strlen(path)+1, (const u8*)path}; -} - Result fsInit(void); Result fsExit(void); +FS_path FS_makePath(FS_pathType type, const char *path); + Result FSUSER_Initialize(Handle* handle); Result FSUSER_OpenArchive(Handle* handle, FS_archive* archive); Result FSUSER_OpenDirectory(Handle* handle, Handle* out, FS_archive archive, FS_path dirLowPath); diff --git a/libctru/include/3ds/types.h b/libctru/include/3ds/types.h index b844bcb..2f7d01a 100644 --- a/libctru/include/3ds/types.h +++ b/libctru/include/3ds/types.h @@ -4,7 +4,6 @@ #pragma once -#include #include #include #include diff --git a/libctru/source/allocator/linear.cpp b/libctru/source/allocator/linear.cpp index e5e6b85..b0a4b27 100644 --- a/libctru/source/allocator/linear.cpp +++ b/libctru/source/allocator/linear.cpp @@ -1,5 +1,6 @@ #include <3ds.h> #include <3ds/util/rbtree.h> + #include "mem_pool.h" extern u32 __linear_heap, __linear_heap_size; diff --git a/libctru/source/allocator/mem_pool.h b/libctru/source/allocator/mem_pool.h index b75d195..97ca60b 100644 --- a/libctru/source/allocator/mem_pool.h +++ b/libctru/source/allocator/mem_pool.h @@ -1,5 +1,6 @@ #pragma once #include <3ds.h> +#include struct MemChunk { diff --git a/libctru/source/sdmc_dev.c b/libctru/source/sdmc_dev.c index 11b498c..3d9e269 100644 --- a/libctru/source/sdmc_dev.c +++ b/libctru/source/sdmc_dev.c @@ -2,6 +2,7 @@ #include #include #include +#include #include <3ds.h> /*! @internal diff --git a/libctru/source/services/fs.c b/libctru/source/services/fs.c index 51af7b5..2ff991d 100644 --- a/libctru/source/services/fs.c +++ b/libctru/source/services/fs.c @@ -14,6 +14,22 @@ static Handle fsuHandle; // used to determine whether or not we should do FSUSER_Initialize on fsuHandle Handle __get_handle_from_list(char* name); +/*! Create an FS_path from a type and data pointer. + * + * @param[in] type Path type. + * @param[in] path Pointer to path data. + * + * @returns FS_path + * + * @sa FS_pathType + */ +FS_path +FS_makePath(FS_pathType type, + const char *path) +{ + return (FS_path){type, strlen(path)+1, (const u8*)path}; +} + /*! Initialize FS service * * @returns error diff --git a/libctru/source/services/httpc.c b/libctru/source/services/httpc.c index 5b4b949..00cb8a7 100644 --- a/libctru/source/services/httpc.c +++ b/libctru/source/services/httpc.c @@ -1,3 +1,4 @@ +#include #include <3ds.h> Handle __httpc_servhandle = 0; diff --git a/libctru/source/services/pm.c b/libctru/source/services/pm.c index 185b37d..6c74ed2 100644 --- a/libctru/source/services/pm.c +++ b/libctru/source/services/pm.c @@ -1,4 +1,5 @@ #include +#include #include <3ds.h> static Handle pmHandle; diff --git a/libctru/source/services/soc/soc_common.h b/libctru/source/services/soc/soc_common.h index 004235d..f5cfe96 100644 --- a/libctru/source/services/soc/soc_common.h +++ b/libctru/source/services/soc/soc_common.h @@ -1,5 +1,6 @@ #pragma once +#include #include <3ds.h> extern Handle SOCU_handle; From ac4c1838687cc274966619d0160ee4c6894cb340 Mon Sep 17 00:00:00 2001 From: Dave Murphy Date: Fri, 28 Nov 2014 21:34:46 +0000 Subject: [PATCH 34/57] fix examples for unpolluted libctru headers --- examples/gpu/source/main.c | 1 + examples/http/source/main.c | 3 +++ examples/mvd/source/main.c | 2 ++ examples/sdmc/source/main.c | 1 + template/source/main.c | 2 ++ 5 files changed, 9 insertions(+) diff --git a/examples/gpu/source/main.c b/examples/gpu/source/main.c index 3c177ce..5747637 100644 --- a/examples/gpu/source/main.c +++ b/examples/gpu/source/main.c @@ -9,6 +9,7 @@ #include #include +#include #include #include <3ds.h> diff --git a/examples/http/source/main.c b/examples/http/source/main.c index 3d8e16d..bb93652 100644 --- a/examples/http/source/main.c +++ b/examples/http/source/main.c @@ -1,3 +1,6 @@ +#include +#include + #include <3ds.h> Result http_download(httpcContext *context)//This error handling needs updated with proper text printing once ctrulib itself supports that. diff --git a/examples/mvd/source/main.c b/examples/mvd/source/main.c index b573f88..3908a18 100644 --- a/examples/mvd/source/main.c +++ b/examples/mvd/source/main.c @@ -1,4 +1,6 @@ #include +#include + #include <3ds.h> #include "costable.h" diff --git a/examples/sdmc/source/main.c b/examples/sdmc/source/main.c index e3c6142..c65292f 100644 --- a/examples/sdmc/source/main.c +++ b/examples/sdmc/source/main.c @@ -5,6 +5,7 @@ //this example shows you how to load a binary image file from the SD card and display it on the lower screen //for this to work you should copy test.bin to the root of your SD card //this file was generated with GIMP by saving a 240x320 image to raw RGB +#include #include <3ds.h> #include "costable.h" diff --git a/template/source/main.c b/template/source/main.c index c377493..df717a6 100644 --- a/template/source/main.c +++ b/template/source/main.c @@ -1,3 +1,5 @@ +#include + #include <3ds.h> int main() From a8e08d4138c09f43d4998e58fcf61e251015e012 Mon Sep 17 00:00:00 2001 From: fincs Date: Fri, 28 Nov 2014 23:54:32 +0100 Subject: [PATCH 35/57] osGetTime(): avoid using u64<->double conversions (not supported by VFP) --- libctru/source/os.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libctru/source/os.c b/libctru/source/os.c index fb2bd97..e2677ed 100644 --- a/libctru/source/os.c +++ b/libctru/source/os.c @@ -49,7 +49,7 @@ u64 osGetTime() { break; } - u64 offset = (svcGetSystemTick() - dt->update_tick) / TICKS_PER_MSEC; + u64 offset = (u32)((u32)(svcGetSystemTick() - dt->update_tick) / TICKS_PER_MSEC); return dt->date_time + offset; } From 58192c868318e2d7cb44dc6e185710a84ba57952 Mon Sep 17 00:00:00 2001 From: yellows8 Date: Fri, 28 Nov 2014 19:28:59 -0500 Subject: [PATCH 36/57] Fixed broken MIC shutdown code. Use a tmp field for svcControlMemory when not allocating linearmem, in initSystem.c. --- examples/mic/README.md | 2 -- libctru/source/initSystem.c | 10 +++++++--- libctru/source/services/mic.c | 3 --- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/examples/mic/README.md b/examples/mic/README.md index 3f0c74c..f3e6d72 100644 --- a/examples/mic/README.md +++ b/examples/mic/README.md @@ -3,5 +3,3 @@ mic Example for using the microphone with ctrulib. Hold down the A button to record, the app will then play the recorded audio once the A button is released. Roughly 32 seconds of audio can be recorded with the default audiobuf size in this app. -Do not use this example(and/or ctrulib MIC?), since MIC is broken currently. - diff --git a/libctru/source/initSystem.c b/libctru/source/initSystem.c index efd1376..039f862 100644 --- a/libctru/source/initSystem.c +++ b/libctru/source/initSystem.c @@ -26,16 +26,18 @@ void __destroy_handle_list(void); void __attribute__((noreturn)) __ctru_exit(int rc) { + u32 tmp=0; + // Run the global destructors __libc_fini_array(); // TODO: APT exit goes here // Unmap the linear heap - svcControlMemory(&__linear_heap, __linear_heap, 0x0, __linear_heap_size, MEMOP_FREE, 0x0); + svcControlMemory(&tmp, __linear_heap, 0x0, __linear_heap_size, MEMOP_FREE, 0x0); // Unmap the application heap - svcControlMemory(&heapBase, heapBase, 0x0, __heap_size, MEMOP_FREE, 0x0); + svcControlMemory(&tmp, heapBase, 0x0, __heap_size, MEMOP_FREE, 0x0); // Close some handles __destroy_handle_list(); @@ -50,13 +52,15 @@ void __attribute__((noreturn)) __ctru_exit(int rc) void initSystem(void (*retAddr)(void)) { + u32 tmp=0; + // Register newlib exit() syscall __syscalls.exit = __ctru_exit; __system_retAddr = __service_ptr ? retAddr : NULL; // Allocate the application heap heapBase = 0x08000000; - svcControlMemory(&heapBase, heapBase, 0x0, __heap_size, MEMOP_ALLOC, 0x3); + svcControlMemory(&tmp, heapBase, 0x0, __heap_size, MEMOP_ALLOC, 0x3); // Allocate the linear heap svcControlMemory(&__linear_heap, 0x0, 0x0, __linear_heap_size, MEMOP_ALLOC_LINEAR, 0x3); diff --git a/libctru/source/services/mic.c b/libctru/source/services/mic.c index 817b9aa..463f94d 100644 --- a/libctru/source/services/mic.c +++ b/libctru/source/services/mic.c @@ -63,9 +63,6 @@ Result MIC_Shutdown() MIC_cmd5(); - ret = svcUnmapMemoryBlock(MIC_sharedmem_handle, (u32)MIC_sharedmem); - if(ret!=0)return ret; - ret = svcCloseHandle(MIC_sharedmem_handle); if(ret!=0)return ret; From 32f8e69b96d073b41b90f8d3a6e1dde30e266419 Mon Sep 17 00:00:00 2001 From: StapleButter Date: Sat, 29 Nov 2014 19:39:00 +0100 Subject: [PATCH 37/57] Sleep mode fixes. --- libctru/source/services/apt.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libctru/source/services/apt.c b/libctru/source/services/apt.c index d1cc18a..e1f99ac 100644 --- a/libctru/source/services/apt.c +++ b/libctru/source/services/apt.c @@ -486,15 +486,15 @@ bool aptMainLoop() case APP_SUSPENDING: aptReturnToMenu(); break; - case APP_PREPARE_SLEEPMODE: - aptSignalReadyForSleep(); - // Fall through case APP_APPLETSTARTED: aptAppletStarted(); break; case APP_APPLETCLOSED: aptAppletClosed(); break; + case APP_PREPARE_SLEEPMODE: + aptSignalReadyForSleep(); + // Fall through default: //case APP_NOTINITIALIZED: //case APP_SLEEPMODE: @@ -551,7 +551,7 @@ void aptSetStatus(APP_STATUS status) //if(prevstatus != APP_NOTINITIALIZED) //{ - if(status == APP_RUNNING || status == APP_EXITING || status == APP_SLEEPMODE || status == APP_APPLETSTARTED || status == APP_APPLETCLOSED) + if(status == APP_RUNNING || status == APP_EXITING || status == APP_APPLETSTARTED || status == APP_APPLETCLOSED) svcSignalEvent(aptStatusEvent); //} From c75ed65d8b8bd047bec54fefa92feb8b68afaa96 Mon Sep 17 00:00:00 2001 From: StapleButter Date: Sat, 29 Nov 2014 21:04:03 +0100 Subject: [PATCH 38/57] Fix HOME button shiz. (apparently APP_APPLETSTARTED happens when pressing the HOME button and causes aptWaitStatusEvent() to end prematurely) --- libctru/source/services/apt.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libctru/source/services/apt.c b/libctru/source/services/apt.c index e1f99ac..242abc1 100644 --- a/libctru/source/services/apt.c +++ b/libctru/source/services/apt.c @@ -352,9 +352,11 @@ static bool __handle_incoming_parameter() { return true; case 0x3: // "Launched library applet finished loading" + if (aptGetStatus() == APP_SUSPENDED) return true; aptSetStatus(APP_APPLETSTARTED); return true; case 0xA: // "Launched library applet closed" + if (aptGetStatus() == APP_SUSPENDED) return true; if(__apt_launchapplet_parambuf && __apt_launchapplet_parambufsize)memcpy(__apt_launchapplet_parambuf, aptParameters, __apt_launchapplet_parambufsize); aptSetStatus(APP_APPLETCLOSED); return true; From ac0e9ef9caa4ae9c0f9da228adf939378a04abfa Mon Sep 17 00:00:00 2001 From: fincs Date: Sat, 29 Nov 2014 21:40:59 +0100 Subject: [PATCH 39/57] Add svcSetThreadPriority --- libctru/include/3ds/svc.h | 1 + libctru/source/svc.s | 17 +++++++++++------ 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/libctru/include/3ds/svc.h b/libctru/include/3ds/svc.h index 0a023e2..8a82e4e 100644 --- a/libctru/include/3ds/svc.h +++ b/libctru/include/3ds/svc.h @@ -76,5 +76,6 @@ s32 svcConnectToPort(volatile Handle* out, const char* portName); s32 svcSendSyncRequest(Handle session); s32 svcGetProcessId(u32 *out, Handle handle); s32 svcOutputDebugString(const char* str, int length); +s32 svcSetThreadPriority(Handle thread, s32 prio); #endif diff --git a/libctru/source/svc.s b/libctru/source/svc.s index 43457aa..b16f479 100644 --- a/libctru/source/svc.s +++ b/libctru/source/svc.s @@ -259,12 +259,17 @@ svcGetProcessId: str r1, [r3] bx lr +.global svcSetThreadPriority +.type svcSetThreadPriority, %function +svcSetThreadPriority: + svc 0x0C + bx lr + .global svcOutputDebugString .type svcOutputDebugString, %function svcOutputDebugString: - str r0, [sp,#-0x4]! - svc 0x3D - ldr r2, [sp], #4 - str r1, [r2] - bx lr - + str r0, [sp,#-0x4]! + svc 0x3D + ldr r2, [sp], #4 + str r1, [r2] + bx lr From 7c13463969ca34e430806a357b74004a66b3ee25 Mon Sep 17 00:00:00 2001 From: yellows8 Date: Wed, 3 Dec 2014 11:06:01 -0500 Subject: [PATCH 40/57] Fixed FSUSER_IsSdmcDetected and FSUSER_IsSdmcWritable: the output is an u8 not u32. --- libctru/include/3ds/services/fs.h | 4 ++-- libctru/source/services/fs.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/libctru/include/3ds/services/fs.h b/libctru/include/3ds/services/fs.h index e5f573d..b062f8d 100644 --- a/libctru/include/3ds/services/fs.h +++ b/libctru/include/3ds/services/fs.h @@ -144,8 +144,8 @@ Result FSUSER_DeleteDirectory(Handle *handle, FS_archive archive, FS_path dirLow Result FSUSER_RenameFile(Handle *handle, FS_archive srcArchive, FS_path srcFileLowPath, FS_archive destArchive, FS_path destFileLowPath); Result FSUSER_RenameDirectory(Handle *handle, FS_archive srcArchive, FS_path srcDirLowPath, FS_archive destArchive, FS_path destDirLowPath); Result FSUSER_GetSdmcArchiveResource(Handle *handle, u32 *sectorSize, u32 *clusterSize, u32 *numClusters, u32 *freeClusters); -Result FSUSER_IsSdmcDetected(Handle *handle, u32 *detected); -Result FSUSER_IsSdmcWritable(Handle *handle, u32 *writable); +Result FSUSER_IsSdmcDetected(Handle *handle, u8 *detected); +Result FSUSER_IsSdmcWritable(Handle *handle, u8 *writable); Result FSFILE_Close(Handle handle); Result FSFILE_Read(Handle handle, u32 *bytesRead, u64 offset, void *buffer, u32 size); diff --git a/libctru/source/services/fs.c b/libctru/source/services/fs.c index 2ff991d..113f980 100644 --- a/libctru/source/services/fs.c +++ b/libctru/source/services/fs.c @@ -839,7 +839,7 @@ FSUSER_GetSdmcArchiveResource(Handle *handle, */ Result FSUSER_IsSdmcDetected(Handle *handle, - u32 *detected) + u8 *detected) { if(!handle) handle = &fsuHandle; @@ -883,7 +883,7 @@ FSUSER_IsSdmcDetected(Handle *handle, */ Result FSUSER_IsSdmcWritable(Handle *handle, - u32 *writable) + u8 *writable) { if(!handle) handle = &fsuHandle; From 1bc0073bd3b04e02194dd7f39b1ca8440f68f0e5 Mon Sep 17 00:00:00 2001 From: Dave Murphy Date: Thu, 4 Dec 2014 00:29:35 +0000 Subject: [PATCH 41/57] implement chdir & relative path support --- libctru/source/sdmc_dev.c | 116 +++++++++++++++++++++++++++++++++----- 1 file changed, 102 insertions(+), 14 deletions(-) diff --git a/libctru/source/sdmc_dev.c b/libctru/source/sdmc_dev.c index 3d9e269..ae99c16 100644 --- a/libctru/source/sdmc_dev.c +++ b/libctru/source/sdmc_dev.c @@ -1,7 +1,10 @@ #include #include #include +#include #include +#include + #include #include <3ds.h> @@ -96,14 +99,60 @@ static FS_archive sdmcArchive = /*! @endcond */ +static char __cwd[PATH_MAX+1] = "/"; +static char __fixedpath[PATH_MAX+1]; + +static const char *sdmc_fixpath(const char *path) +{ + // Move the path pointer to the start of the actual path + if (strchr (path, ':') != NULL) + { + path = strchr (path, ':') + 1; + } + + if (strchr (path, ':') != NULL) return NULL; + + + if (path[0]=='/') return path; + + strncpy(__fixedpath,__cwd,PATH_MAX); + strncat(__fixedpath,path,PATH_MAX); + __fixedpath[PATH_MAX] = 0; + + return __fixedpath; + +} + +int __system_argc; +char** __system_argv; + /*! Initialize SDMC device */ Result sdmcInit(void) { Result rc; + rc = FSUSER_OpenArchive(NULL, &sdmcArchive); + + if(rc == 0) - AddDevice(&sdmc_devoptab); + { + + int dev = AddDevice(&sdmc_devoptab); + + if (__system_argc != 0 && __system_argv[0] != NULL) + { + if (FindDevice(__system_argv[0]) == dev) + { + strncpy(__fixedpath,__system_argv[0],PATH_MAX); + char *last_slash = strrchr(__fixedpath,'/'); + if (last_slash != NULL) { + last_slash[0] = 0; + chdir(__fixedpath); + } + } + } + } return rc; } @@ -142,10 +191,15 @@ sdmc_open(struct _reent *r, Result rc; u32 sdmc_flags = 0; u32 attributes = FS_ATTRIBUTE_NONE; - char *pathptr = NULL; + const char *pathptr = NULL; - pathptr = strchr(path, '/'); - if(pathptr==NULL)pathptr = (char*)path; + pathptr = sdmc_fixpath(path); + + if(pathptr==NULL) + { + r->_errno=EINVAL; + return -1; + } /* get pointer to our data */ sdmc_file_t *file = (sdmc_file_t*)fileStruct; @@ -484,8 +538,32 @@ static int sdmc_chdir(struct _reent *r, const char *name) { - r->_errno = ENOSYS; - return -1; + Handle fd; + Result rc; + const char *pathptr = NULL; + + pathptr = sdmc_fixpath(name); + + if(pathptr==NULL) + { + r->_errno=EINVAL; + return -1; + } + + rc = FSUSER_OpenDirectory(NULL, &fd, sdmcArchive, FS_makePath(PATH_CHAR, pathptr)); + if(rc == 0) + { + FSDIR_Close(fd); + strncpy(__cwd,pathptr,PATH_MAX); + } + else + { + r->_errno=EINVAL; + return -1; + } + + return 0; + } /*! Rename a file @@ -521,10 +599,15 @@ sdmc_mkdir(struct _reent *r, int mode) { Result rc; - char *pathptr = NULL; + const char *pathptr = NULL; - pathptr = strchr(path, '/'); - if(pathptr==NULL)pathptr = (char*)path; + pathptr = sdmc_fixpath(path); + + if(pathptr==NULL) + { + r->_errno=EINVAL; + return -1; + } /* TODO: Use mode to set directory attributes. */ @@ -552,10 +635,15 @@ sdmc_diropen(struct _reent *r, { Handle fd; Result rc; - char *pathptr = NULL; + const char *pathptr = NULL; - pathptr = strchr(path, '/'); - if(pathptr==NULL)pathptr = (char*)path; + pathptr = sdmc_fixpath(path); + + if(pathptr==NULL) + { + r->_errno=EINVAL; + return NULL; + } /* get pointer to our data */ sdmc_dir_t *dir = (sdmc_dir_t*)(dirState->dirStruct); @@ -685,7 +773,7 @@ sdmc_statvfs(struct _reent *r, { Result rc; u32 clusterSize, numClusters, freeClusters; - u32 writable = 0; + u8 writable = 0; rc = FSUSER_GetSdmcArchiveResource(NULL, NULL, @@ -787,7 +875,7 @@ sdmc_fsync(struct _reent *r, * @returns 0 for success * @returns -1 for error */ -static int +static int sdmc_chmod(struct _reent *r, const char *path, mode_t mode) From bacd6f09ca8312a78ea05e130b5ccbe10f91f72d Mon Sep 17 00:00:00 2001 From: fincs Date: Thu, 4 Dec 2014 11:23:40 +0100 Subject: [PATCH 42/57] sdmc_dev.c: do not redefine __system_argc/argv --- libctru/source/sdmc_dev.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libctru/source/sdmc_dev.c b/libctru/source/sdmc_dev.c index ae99c16..4d48117 100644 --- a/libctru/source/sdmc_dev.c +++ b/libctru/source/sdmc_dev.c @@ -123,8 +123,8 @@ static const char *sdmc_fixpath(const char *path) } -int __system_argc; -char** __system_argv; +extern int __system_argc; +extern char** __system_argv; /*! Initialize SDMC device */ Result sdmcInit(void) From 3f9e0a630bd72c58df546cb4c4c837c37d429659 Mon Sep 17 00:00:00 2001 From: fincs Date: Wed, 3 Dec 2014 21:24:22 +0100 Subject: [PATCH 43/57] Switch to -mfloat-abi=hard, bump version to 0.2.0 --- libctru/Makefile | 4 ++-- template/Makefile | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/libctru/Makefile b/libctru/Makefile index d1174a3..31cd434 100644 --- a/libctru/Makefile +++ b/libctru/Makefile @@ -9,7 +9,7 @@ endif include $(DEVKITARM)/base_rules export LIBCTRU_MAJOR := 0 -export LIBCTRU_MINOR := 1 +export LIBCTRU_MINOR := 2 export LIBCTRU_PATCH := 0 @@ -36,7 +36,7 @@ INCLUDES := include #--------------------------------------------------------------------------------- # options for code generation #--------------------------------------------------------------------------------- -ARCH := -march=armv6k -mtune=mpcore -mfloat-abi=softfp +ARCH := -march=armv6k -mtune=mpcore -mfloat-abi=hard CFLAGS := -g -Wall -O2 -mword-relocations \ -fomit-frame-pointer -ffast-math \ diff --git a/template/Makefile b/template/Makefile index c4c758e..c21562a 100644 --- a/template/Makefile +++ b/template/Makefile @@ -35,7 +35,7 @@ INCLUDES := include #--------------------------------------------------------------------------------- # options for code generation #--------------------------------------------------------------------------------- -ARCH := -march=armv6k -mtune=mpcore -mfloat-abi=softfp +ARCH := -march=armv6k -mtune=mpcore -mfloat-abi=hard CFLAGS := -g -Wall -O2 -mword-relocations \ -fomit-frame-pointer -ffast-math \ From 2d072ab9aa267e9a2dad4b6c8ccca97d479c05d7 Mon Sep 17 00:00:00 2001 From: fincs Date: Wed, 3 Dec 2014 21:24:46 +0100 Subject: [PATCH 44/57] Add SMDH embedding to the template --- template/Makefile | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/template/Makefile b/template/Makefile index c21562a..576126e 100644 --- a/template/Makefile +++ b/template/Makefile @@ -113,6 +113,10 @@ else export APP_ICON := $(TOPDIR)/$(ICON) endif +ifeq ($(strip $(NO_SMDH)),) + export _3DSXFLAGS += --smdh=$(CURDIR)/$(TARGET).smdh +endif + .PHONY: $(BUILD) clean all #--------------------------------------------------------------------------------- @@ -137,10 +141,11 @@ DEPENDS := $(OFILES:.o=.d) # main targets #--------------------------------------------------------------------------------- ifeq ($(strip $(NO_SMDH)),) -.PHONY: all -all : $(OUTPUT).3dsx $(OUTPUT).smdh -endif +$(OUTPUT).3dsx : $(OUTPUT).elf $(OUTPUT).smdh +else $(OUTPUT).3dsx : $(OUTPUT).elf +endif + $(OUTPUT).elf : $(OFILES) #--------------------------------------------------------------------------------- From 0f93112ecb43ae145c7e5e353e1e378de31c4a33 Mon Sep 17 00:00:00 2001 From: fincs Date: Wed, 3 Dec 2014 21:25:32 +0100 Subject: [PATCH 45/57] Update example makefiles --- examples/app_launch/Makefile | 13 +++++++++---- examples/gpu/Makefile | 13 +++++++++---- examples/http/Makefile | 13 +++++++++---- examples/libapplet_launch/Makefile | 13 +++++++++---- examples/mic/Makefile | 13 +++++++++---- examples/mvd/Makefile | 13 +++++++++---- examples/sdmc/Makefile | 13 +++++++++---- 7 files changed, 63 insertions(+), 28 deletions(-) diff --git a/examples/app_launch/Makefile b/examples/app_launch/Makefile index c4c758e..576126e 100644 --- a/examples/app_launch/Makefile +++ b/examples/app_launch/Makefile @@ -35,7 +35,7 @@ INCLUDES := include #--------------------------------------------------------------------------------- # options for code generation #--------------------------------------------------------------------------------- -ARCH := -march=armv6k -mtune=mpcore -mfloat-abi=softfp +ARCH := -march=armv6k -mtune=mpcore -mfloat-abi=hard CFLAGS := -g -Wall -O2 -mword-relocations \ -fomit-frame-pointer -ffast-math \ @@ -113,6 +113,10 @@ else export APP_ICON := $(TOPDIR)/$(ICON) endif +ifeq ($(strip $(NO_SMDH)),) + export _3DSXFLAGS += --smdh=$(CURDIR)/$(TARGET).smdh +endif + .PHONY: $(BUILD) clean all #--------------------------------------------------------------------------------- @@ -137,10 +141,11 @@ DEPENDS := $(OFILES:.o=.d) # main targets #--------------------------------------------------------------------------------- ifeq ($(strip $(NO_SMDH)),) -.PHONY: all -all : $(OUTPUT).3dsx $(OUTPUT).smdh -endif +$(OUTPUT).3dsx : $(OUTPUT).elf $(OUTPUT).smdh +else $(OUTPUT).3dsx : $(OUTPUT).elf +endif + $(OUTPUT).elf : $(OFILES) #--------------------------------------------------------------------------------- diff --git a/examples/gpu/Makefile b/examples/gpu/Makefile index c4c758e..576126e 100644 --- a/examples/gpu/Makefile +++ b/examples/gpu/Makefile @@ -35,7 +35,7 @@ INCLUDES := include #--------------------------------------------------------------------------------- # options for code generation #--------------------------------------------------------------------------------- -ARCH := -march=armv6k -mtune=mpcore -mfloat-abi=softfp +ARCH := -march=armv6k -mtune=mpcore -mfloat-abi=hard CFLAGS := -g -Wall -O2 -mword-relocations \ -fomit-frame-pointer -ffast-math \ @@ -113,6 +113,10 @@ else export APP_ICON := $(TOPDIR)/$(ICON) endif +ifeq ($(strip $(NO_SMDH)),) + export _3DSXFLAGS += --smdh=$(CURDIR)/$(TARGET).smdh +endif + .PHONY: $(BUILD) clean all #--------------------------------------------------------------------------------- @@ -137,10 +141,11 @@ DEPENDS := $(OFILES:.o=.d) # main targets #--------------------------------------------------------------------------------- ifeq ($(strip $(NO_SMDH)),) -.PHONY: all -all : $(OUTPUT).3dsx $(OUTPUT).smdh -endif +$(OUTPUT).3dsx : $(OUTPUT).elf $(OUTPUT).smdh +else $(OUTPUT).3dsx : $(OUTPUT).elf +endif + $(OUTPUT).elf : $(OFILES) #--------------------------------------------------------------------------------- diff --git a/examples/http/Makefile b/examples/http/Makefile index c4c758e..576126e 100644 --- a/examples/http/Makefile +++ b/examples/http/Makefile @@ -35,7 +35,7 @@ INCLUDES := include #--------------------------------------------------------------------------------- # options for code generation #--------------------------------------------------------------------------------- -ARCH := -march=armv6k -mtune=mpcore -mfloat-abi=softfp +ARCH := -march=armv6k -mtune=mpcore -mfloat-abi=hard CFLAGS := -g -Wall -O2 -mword-relocations \ -fomit-frame-pointer -ffast-math \ @@ -113,6 +113,10 @@ else export APP_ICON := $(TOPDIR)/$(ICON) endif +ifeq ($(strip $(NO_SMDH)),) + export _3DSXFLAGS += --smdh=$(CURDIR)/$(TARGET).smdh +endif + .PHONY: $(BUILD) clean all #--------------------------------------------------------------------------------- @@ -137,10 +141,11 @@ DEPENDS := $(OFILES:.o=.d) # main targets #--------------------------------------------------------------------------------- ifeq ($(strip $(NO_SMDH)),) -.PHONY: all -all : $(OUTPUT).3dsx $(OUTPUT).smdh -endif +$(OUTPUT).3dsx : $(OUTPUT).elf $(OUTPUT).smdh +else $(OUTPUT).3dsx : $(OUTPUT).elf +endif + $(OUTPUT).elf : $(OFILES) #--------------------------------------------------------------------------------- diff --git a/examples/libapplet_launch/Makefile b/examples/libapplet_launch/Makefile index c4c758e..576126e 100644 --- a/examples/libapplet_launch/Makefile +++ b/examples/libapplet_launch/Makefile @@ -35,7 +35,7 @@ INCLUDES := include #--------------------------------------------------------------------------------- # options for code generation #--------------------------------------------------------------------------------- -ARCH := -march=armv6k -mtune=mpcore -mfloat-abi=softfp +ARCH := -march=armv6k -mtune=mpcore -mfloat-abi=hard CFLAGS := -g -Wall -O2 -mword-relocations \ -fomit-frame-pointer -ffast-math \ @@ -113,6 +113,10 @@ else export APP_ICON := $(TOPDIR)/$(ICON) endif +ifeq ($(strip $(NO_SMDH)),) + export _3DSXFLAGS += --smdh=$(CURDIR)/$(TARGET).smdh +endif + .PHONY: $(BUILD) clean all #--------------------------------------------------------------------------------- @@ -137,10 +141,11 @@ DEPENDS := $(OFILES:.o=.d) # main targets #--------------------------------------------------------------------------------- ifeq ($(strip $(NO_SMDH)),) -.PHONY: all -all : $(OUTPUT).3dsx $(OUTPUT).smdh -endif +$(OUTPUT).3dsx : $(OUTPUT).elf $(OUTPUT).smdh +else $(OUTPUT).3dsx : $(OUTPUT).elf +endif + $(OUTPUT).elf : $(OFILES) #--------------------------------------------------------------------------------- diff --git a/examples/mic/Makefile b/examples/mic/Makefile index c4c758e..576126e 100644 --- a/examples/mic/Makefile +++ b/examples/mic/Makefile @@ -35,7 +35,7 @@ INCLUDES := include #--------------------------------------------------------------------------------- # options for code generation #--------------------------------------------------------------------------------- -ARCH := -march=armv6k -mtune=mpcore -mfloat-abi=softfp +ARCH := -march=armv6k -mtune=mpcore -mfloat-abi=hard CFLAGS := -g -Wall -O2 -mword-relocations \ -fomit-frame-pointer -ffast-math \ @@ -113,6 +113,10 @@ else export APP_ICON := $(TOPDIR)/$(ICON) endif +ifeq ($(strip $(NO_SMDH)),) + export _3DSXFLAGS += --smdh=$(CURDIR)/$(TARGET).smdh +endif + .PHONY: $(BUILD) clean all #--------------------------------------------------------------------------------- @@ -137,10 +141,11 @@ DEPENDS := $(OFILES:.o=.d) # main targets #--------------------------------------------------------------------------------- ifeq ($(strip $(NO_SMDH)),) -.PHONY: all -all : $(OUTPUT).3dsx $(OUTPUT).smdh -endif +$(OUTPUT).3dsx : $(OUTPUT).elf $(OUTPUT).smdh +else $(OUTPUT).3dsx : $(OUTPUT).elf +endif + $(OUTPUT).elf : $(OFILES) #--------------------------------------------------------------------------------- diff --git a/examples/mvd/Makefile b/examples/mvd/Makefile index c4c758e..576126e 100644 --- a/examples/mvd/Makefile +++ b/examples/mvd/Makefile @@ -35,7 +35,7 @@ INCLUDES := include #--------------------------------------------------------------------------------- # options for code generation #--------------------------------------------------------------------------------- -ARCH := -march=armv6k -mtune=mpcore -mfloat-abi=softfp +ARCH := -march=armv6k -mtune=mpcore -mfloat-abi=hard CFLAGS := -g -Wall -O2 -mword-relocations \ -fomit-frame-pointer -ffast-math \ @@ -113,6 +113,10 @@ else export APP_ICON := $(TOPDIR)/$(ICON) endif +ifeq ($(strip $(NO_SMDH)),) + export _3DSXFLAGS += --smdh=$(CURDIR)/$(TARGET).smdh +endif + .PHONY: $(BUILD) clean all #--------------------------------------------------------------------------------- @@ -137,10 +141,11 @@ DEPENDS := $(OFILES:.o=.d) # main targets #--------------------------------------------------------------------------------- ifeq ($(strip $(NO_SMDH)),) -.PHONY: all -all : $(OUTPUT).3dsx $(OUTPUT).smdh -endif +$(OUTPUT).3dsx : $(OUTPUT).elf $(OUTPUT).smdh +else $(OUTPUT).3dsx : $(OUTPUT).elf +endif + $(OUTPUT).elf : $(OFILES) #--------------------------------------------------------------------------------- diff --git a/examples/sdmc/Makefile b/examples/sdmc/Makefile index c4c758e..576126e 100644 --- a/examples/sdmc/Makefile +++ b/examples/sdmc/Makefile @@ -35,7 +35,7 @@ INCLUDES := include #--------------------------------------------------------------------------------- # options for code generation #--------------------------------------------------------------------------------- -ARCH := -march=armv6k -mtune=mpcore -mfloat-abi=softfp +ARCH := -march=armv6k -mtune=mpcore -mfloat-abi=hard CFLAGS := -g -Wall -O2 -mword-relocations \ -fomit-frame-pointer -ffast-math \ @@ -113,6 +113,10 @@ else export APP_ICON := $(TOPDIR)/$(ICON) endif +ifeq ($(strip $(NO_SMDH)),) + export _3DSXFLAGS += --smdh=$(CURDIR)/$(TARGET).smdh +endif + .PHONY: $(BUILD) clean all #--------------------------------------------------------------------------------- @@ -137,10 +141,11 @@ DEPENDS := $(OFILES:.o=.d) # main targets #--------------------------------------------------------------------------------- ifeq ($(strip $(NO_SMDH)),) -.PHONY: all -all : $(OUTPUT).3dsx $(OUTPUT).smdh -endif +$(OUTPUT).3dsx : $(OUTPUT).elf $(OUTPUT).smdh +else $(OUTPUT).3dsx : $(OUTPUT).elf +endif + $(OUTPUT).elf : $(OFILES) #--------------------------------------------------------------------------------- From 377e753b7dbba879ea31485fd9ae49c520ba77cb Mon Sep 17 00:00:00 2001 From: fincs Date: Wed, 3 Dec 2014 23:40:49 +0100 Subject: [PATCH 46/57] Add getThreadLocalStorage(), major cleanup in svc.h/svc.s --- libctru/include/3ds/svc.h | 18 ++-- libctru/source/svc.s | 171 ++++++++++++++++++-------------------- 2 files changed, 93 insertions(+), 96 deletions(-) diff --git a/libctru/include/3ds/svc.h b/libctru/include/3ds/svc.h index 8a82e4e..d498d45 100644 --- a/libctru/include/3ds/svc.h +++ b/libctru/include/3ds/svc.h @@ -2,8 +2,7 @@ svc.h _ Syscall wrappers. */ -#ifndef SVC_H -#define SVC_H +#pragma once typedef enum { MEMOP_FREE =1, // Free heap @@ -42,8 +41,17 @@ typedef enum { ARBITER_KERNEL4 =4, } ArbitrationType; +static inline void* getThreadLocalStorage(void) +{ + void* ret; + asm volatile("mrc p15, 0, %[data], c13, c0, 3" : [data] "=r" (ret)); + return ret; +} -u32* getThreadCommandBuffer(void); +static inline u32* getThreadCommandBuffer(void) +{ + return (u32*)((u8*)getThreadLocalStorage() + 0x80); +} s32 svcControlMemory(u32* addr_out, u32 addr0, u32 addr1, u32 size, MemOp op, MemPerm perm); s32 svcQueryMemory(MemInfo* info, PageInfo* out, u32 addr); @@ -51,6 +59,7 @@ void __attribute__((noreturn)) svcExitProcess(); s32 svcCreateThread(Handle* thread, ThreadFunc entrypoint, u32 arg, u32* stack_top, s32 thread_priority, s32 processor_id); void __attribute__((noreturn)) svcExitThread(); void svcSleepThread(s64 ns); +s32 svcSetThreadPriority(Handle thread, s32 prio); s32 svcCreateMutex(Handle* mutex, bool initially_locked); s32 svcReleaseMutex(Handle handle); s32 svcCreateEvent(Handle* event, u8 reset_type); @@ -76,6 +85,3 @@ s32 svcConnectToPort(volatile Handle* out, const char* portName); s32 svcSendSyncRequest(Handle session); s32 svcGetProcessId(u32 *out, Handle handle); s32 svcOutputDebugString(const char* str, int length); -s32 svcSetThreadPriority(Handle thread, s32 prio); - -#endif diff --git a/libctru/source/svc.s b/libctru/source/svc.s index b16f479..2f2eb0e 100644 --- a/libctru/source/svc.s +++ b/libctru/source/svc.s @@ -1,72 +1,69 @@ .arm .align 4 -/* THIS DOES NOT BELONG HERE */ -.global getThreadCommandBuffer -.type getThreadCommandBuffer, %function -getThreadCommandBuffer: - mrc p15, 0, r0, c13, c0, 3 - add r0, #0x80 - bx lr - - .global svcControlMemory .type svcControlMemory, %function svcControlMemory: - stmfd sp!, {r0, r4} - ldr r0, [sp, #0x8] - ldr r4, [sp, #0x8+0x4] - svc 0x01 - ldr r2, [sp], #4 - str r1, [r2] - ldr r4, [sp], #4 - bx lr + push {r0, r4} + ldr r0, [sp, #0x8] + ldr r4, [sp, #0x8+0x4] + svc 0x01 + ldr r2, [sp], #4 + str r1, [r2] + ldr r4, [sp], #4 + bx lr .global svcQueryMemory .type svcQueryMemory, %function svcQueryMemory: - stmfd sp!, {r0,r1,r4-r6} - svc 2 - ldr r6, [sp] - str r1, [r6] - str r2, [r6,#4] - str r3, [r6,#8] - str r4, [r6,#0xc] - ldr r6, [sp,#4] - str r5, [r6] - add sp, sp, #8 - ldmfd sp!, {r4-r6} - bx lr + push {r0, r1, r4-r6} + svc 0x02 + ldr r6, [sp] + str r1, [r6] + str r2, [r6, #4] + str r3, [r6, #8] + str r4, [r6, #0xc] + ldr r6, [sp, #4] + str r5, [r6] + add sp, sp, #8 + pop {r4-r6} + bx lr .global svcExitProcess .type svcExitProcess, %function svcExitProcess: svc 0x03 - bx lr + bx lr .global svcCreateThread .type svcCreateThread, %function svcCreateThread: - stmfd sp!, {r0, r4} - ldr r0, [sp, #0x8] - ldr r4, [sp, #0x8+0x4] - svc 0x08 - ldr r2, [sp], #4 - str r1, [r2] - ldr r4, [sp], #4 - bx lr + push {r0, r4} + ldr r0, [sp, #0x8] + ldr r4, [sp, #0x8+0x4] + svc 0x08 + ldr r2, [sp], #4 + str r1, [r2] + ldr r4, [sp], #4 + bx lr .global svcExitThread .type svcExitThread, %function svcExitThread: svc 0x09 - bx lr + bx lr .global svcSleepThread .type svcSleepThread, %function svcSleepThread: svc 0x0A - bx lr + bx lr + +.global svcSetThreadPriority +.type svcSetThreadPriority, %function +svcSetThreadPriority: + svc 0x0C + bx lr .global svcCreateMutex .type svcCreateMutex, %function @@ -75,61 +72,61 @@ svcCreateMutex: svc 0x13 ldr r3, [sp], #4 str r1, [r3] - bx lr + bx lr .global svcReleaseMutex .type svcReleaseMutex, %function svcReleaseMutex: svc 0x14 - bx lr + bx lr .global svcCreateEvent .type svcCreateEvent, %function svcCreateEvent: - str r0, [sp,#-4]! + str r0, [sp, #-4]! svc 0x17 ldr r2, [sp], #4 str r1, [r2] - bx lr + bx lr .global svcSignalEvent .type svcSignalEvent, %function svcSignalEvent: svc 0x18 - bx lr + bx lr .global svcClearEvent .type svcClearEvent, %function svcClearEvent: svc 0x19 - bx lr + bx lr .global svcCreateTimer .type svcCreateTimer, %function svcCreateTimer: - str r0, [sp,#-4]! + str r0, [sp, #-4]! svc 0x1A ldr r2, [sp], #4 str r1, [r2] - bx lr + bx lr .global svcSetTimer .type svcSetTimer, %function svcSetTimer: svc 0x1B - bx lr + bx lr .global svcCancelTimer .type svcCancelTimer, %function svcCancelTimer: svc 0x1C - bx lr + bx lr .global svcClearTimer .type svcClearTimer, %function svcClearTimer: svc 0x1D - bx lr + bx lr .global svcCreateMemoryBlock .type svcCreateMemoryBlock, %function @@ -139,49 +136,49 @@ svcCreateMemoryBlock: svc 0x1E ldr r2, [sp], #4 str r1, [r2] - bx lr + bx lr .global svcMapMemoryBlock .type svcMapMemoryBlock, %function svcMapMemoryBlock: svc 0x1F - bx lr + bx lr .global svcUnmapMemoryBlock .type svcUnmapMemoryBlock, %function svcUnmapMemoryBlock: svc 0x20 - bx lr + bx lr .global svcCreateAddressArbiter .type svcCreateAddressArbiter, %function svcCreateAddressArbiter: svc 0x21 - bx lr + bx lr .global svcArbitrateAddress .type svcArbitrateAddress, %function svcArbitrateAddress: - push {r4,r5} + push {r4, r5} add sp, #8 ldr r5, [sp] ldr r4, [sp, #4] sub sp, #8 svc 0x22 - pop {r4,r5} - bx lr + pop {r4, r5} + bx lr .global svcCloseHandle .type svcCloseHandle, %function svcCloseHandle: svc 0x23 - bx lr + bx lr .global svcWaitSynchronization .type svcWaitSynchronization, %function svcWaitSynchronization: svc 0x24 - bx lr + bx lr .global svcWaitSynchronizationN .type svcWaitSynchronizationN, %function @@ -195,16 +192,16 @@ svcWaitSynchronizationN: str r1, [r5] ldr r4, [sp], #4 ldr r5, [sp], #4 - bx lr + bx lr .global svcDuplicateHandle .type svcDuplicateHandle, %function svcDuplicateHandle: - str r0, [sp,#-0x4]! + str r0, [sp, #-0x4]! svc 0x27 ldr r3, [sp], #4 str r1, [r3] - bx lr + bx lr .global svcGetSystemTick .type svcGetSystemTick, %function @@ -215,34 +212,34 @@ svcGetSystemTick: .global svcGetSystemInfo .type svcGetSystemInfo, %function svcGetSystemInfo: - stmfd sp!, {r0, r4} - svc 0x2A - ldr r4, [sp], #4 - str r1, [r4] - str r2, [r4, #4] - str r3, [r4, #8] - ldr r4, [sp], #4 - bx lr + push {r0, r4} + svc 0x2A + ldr r4, [sp], #4 + str r1, [r4] + str r2, [r4, #4] + str r3, [r4, #8] + ldr r4, [sp], #4 + bx lr .global svcGetProcessInfo .type svcGetProcessInfo, %function svcGetProcessInfo: - stmfd sp!, {r0, r4} - svc 0x2B - ldr r4, [sp], #4 - str r1, [r4] - str r2, [r4, #4] - ldr r4, [sp], #4 - bx lr + push {r0,r4} + svc 0x2B + ldr r4, [sp], #4 + str r1, [r4] + str r2, [r4, #4] + ldr r4, [sp], #4 + bx lr .global svcConnectToPort .type svcConnectToPort, %function svcConnectToPort: - str r0, [sp,#-0x4]! + str r0, [sp, #-0x4]! svc 0x2D ldr r3, [sp], #4 str r1, [r3] - bx lr + bx lr .global svcSendSyncRequest .type svcSendSyncRequest, %function @@ -253,23 +250,17 @@ svcSendSyncRequest: .global svcGetProcessId .type svcGetProcessId, %function svcGetProcessId: - str r0, [sp,#-0x4]! + str r0, [sp, #-0x4]! svc 0x35 ldr r3, [sp], #4 str r1, [r3] - bx lr - -.global svcSetThreadPriority -.type svcSetThreadPriority, %function -svcSetThreadPriority: - svc 0x0C - bx lr + bx lr .global svcOutputDebugString .type svcOutputDebugString, %function svcOutputDebugString: - str r0, [sp,#-0x4]! + str r0, [sp, #-0x4]! svc 0x3D ldr r2, [sp], #4 str r1, [r2] - bx lr + bx lr From 1aae1b2cd92e9ce640bd06df627583743c97bbe2 Mon Sep 17 00:00:00 2001 From: Dave Murphy Date: Fri, 5 Dec 2014 13:47:05 +0000 Subject: [PATCH 47/57] Revert "Switch to -mfloat-abi=hard, bump version to 0.2.0" This reverts commit 3f9e0a630bd72c58df546cb4c4c837c37d429659. --- libctru/Makefile | 4 ++-- template/Makefile | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/libctru/Makefile b/libctru/Makefile index 31cd434..d1174a3 100644 --- a/libctru/Makefile +++ b/libctru/Makefile @@ -9,7 +9,7 @@ endif include $(DEVKITARM)/base_rules export LIBCTRU_MAJOR := 0 -export LIBCTRU_MINOR := 2 +export LIBCTRU_MINOR := 1 export LIBCTRU_PATCH := 0 @@ -36,7 +36,7 @@ INCLUDES := include #--------------------------------------------------------------------------------- # options for code generation #--------------------------------------------------------------------------------- -ARCH := -march=armv6k -mtune=mpcore -mfloat-abi=hard +ARCH := -march=armv6k -mtune=mpcore -mfloat-abi=softfp CFLAGS := -g -Wall -O2 -mword-relocations \ -fomit-frame-pointer -ffast-math \ diff --git a/template/Makefile b/template/Makefile index 576126e..1ed1097 100644 --- a/template/Makefile +++ b/template/Makefile @@ -35,7 +35,7 @@ INCLUDES := include #--------------------------------------------------------------------------------- # options for code generation #--------------------------------------------------------------------------------- -ARCH := -march=armv6k -mtune=mpcore -mfloat-abi=hard +ARCH := -march=armv6k -mtune=mpcore -mfloat-abi=softfp CFLAGS := -g -Wall -O2 -mword-relocations \ -fomit-frame-pointer -ffast-math \ From 2d25b0359f4a33e2e6825f0fed49524ed8cc4d1f Mon Sep 17 00:00:00 2001 From: Dave Murphy Date: Fri, 5 Dec 2014 13:47:57 +0000 Subject: [PATCH 48/57] Revert "Update example makefiles" This reverts commit 0f93112ecb43ae145c7e5e353e1e378de31c4a33. --- examples/app_launch/Makefile | 13 ++++--------- examples/gpu/Makefile | 13 ++++--------- examples/http/Makefile | 13 ++++--------- examples/libapplet_launch/Makefile | 13 ++++--------- examples/mic/Makefile | 13 ++++--------- examples/mvd/Makefile | 13 ++++--------- examples/sdmc/Makefile | 13 ++++--------- 7 files changed, 28 insertions(+), 63 deletions(-) diff --git a/examples/app_launch/Makefile b/examples/app_launch/Makefile index 576126e..c4c758e 100644 --- a/examples/app_launch/Makefile +++ b/examples/app_launch/Makefile @@ -35,7 +35,7 @@ INCLUDES := include #--------------------------------------------------------------------------------- # options for code generation #--------------------------------------------------------------------------------- -ARCH := -march=armv6k -mtune=mpcore -mfloat-abi=hard +ARCH := -march=armv6k -mtune=mpcore -mfloat-abi=softfp CFLAGS := -g -Wall -O2 -mword-relocations \ -fomit-frame-pointer -ffast-math \ @@ -113,10 +113,6 @@ else export APP_ICON := $(TOPDIR)/$(ICON) endif -ifeq ($(strip $(NO_SMDH)),) - export _3DSXFLAGS += --smdh=$(CURDIR)/$(TARGET).smdh -endif - .PHONY: $(BUILD) clean all #--------------------------------------------------------------------------------- @@ -141,11 +137,10 @@ DEPENDS := $(OFILES:.o=.d) # main targets #--------------------------------------------------------------------------------- ifeq ($(strip $(NO_SMDH)),) -$(OUTPUT).3dsx : $(OUTPUT).elf $(OUTPUT).smdh -else -$(OUTPUT).3dsx : $(OUTPUT).elf +.PHONY: all +all : $(OUTPUT).3dsx $(OUTPUT).smdh endif - +$(OUTPUT).3dsx : $(OUTPUT).elf $(OUTPUT).elf : $(OFILES) #--------------------------------------------------------------------------------- diff --git a/examples/gpu/Makefile b/examples/gpu/Makefile index 576126e..c4c758e 100644 --- a/examples/gpu/Makefile +++ b/examples/gpu/Makefile @@ -35,7 +35,7 @@ INCLUDES := include #--------------------------------------------------------------------------------- # options for code generation #--------------------------------------------------------------------------------- -ARCH := -march=armv6k -mtune=mpcore -mfloat-abi=hard +ARCH := -march=armv6k -mtune=mpcore -mfloat-abi=softfp CFLAGS := -g -Wall -O2 -mword-relocations \ -fomit-frame-pointer -ffast-math \ @@ -113,10 +113,6 @@ else export APP_ICON := $(TOPDIR)/$(ICON) endif -ifeq ($(strip $(NO_SMDH)),) - export _3DSXFLAGS += --smdh=$(CURDIR)/$(TARGET).smdh -endif - .PHONY: $(BUILD) clean all #--------------------------------------------------------------------------------- @@ -141,11 +137,10 @@ DEPENDS := $(OFILES:.o=.d) # main targets #--------------------------------------------------------------------------------- ifeq ($(strip $(NO_SMDH)),) -$(OUTPUT).3dsx : $(OUTPUT).elf $(OUTPUT).smdh -else -$(OUTPUT).3dsx : $(OUTPUT).elf +.PHONY: all +all : $(OUTPUT).3dsx $(OUTPUT).smdh endif - +$(OUTPUT).3dsx : $(OUTPUT).elf $(OUTPUT).elf : $(OFILES) #--------------------------------------------------------------------------------- diff --git a/examples/http/Makefile b/examples/http/Makefile index 576126e..c4c758e 100644 --- a/examples/http/Makefile +++ b/examples/http/Makefile @@ -35,7 +35,7 @@ INCLUDES := include #--------------------------------------------------------------------------------- # options for code generation #--------------------------------------------------------------------------------- -ARCH := -march=armv6k -mtune=mpcore -mfloat-abi=hard +ARCH := -march=armv6k -mtune=mpcore -mfloat-abi=softfp CFLAGS := -g -Wall -O2 -mword-relocations \ -fomit-frame-pointer -ffast-math \ @@ -113,10 +113,6 @@ else export APP_ICON := $(TOPDIR)/$(ICON) endif -ifeq ($(strip $(NO_SMDH)),) - export _3DSXFLAGS += --smdh=$(CURDIR)/$(TARGET).smdh -endif - .PHONY: $(BUILD) clean all #--------------------------------------------------------------------------------- @@ -141,11 +137,10 @@ DEPENDS := $(OFILES:.o=.d) # main targets #--------------------------------------------------------------------------------- ifeq ($(strip $(NO_SMDH)),) -$(OUTPUT).3dsx : $(OUTPUT).elf $(OUTPUT).smdh -else -$(OUTPUT).3dsx : $(OUTPUT).elf +.PHONY: all +all : $(OUTPUT).3dsx $(OUTPUT).smdh endif - +$(OUTPUT).3dsx : $(OUTPUT).elf $(OUTPUT).elf : $(OFILES) #--------------------------------------------------------------------------------- diff --git a/examples/libapplet_launch/Makefile b/examples/libapplet_launch/Makefile index 576126e..c4c758e 100644 --- a/examples/libapplet_launch/Makefile +++ b/examples/libapplet_launch/Makefile @@ -35,7 +35,7 @@ INCLUDES := include #--------------------------------------------------------------------------------- # options for code generation #--------------------------------------------------------------------------------- -ARCH := -march=armv6k -mtune=mpcore -mfloat-abi=hard +ARCH := -march=armv6k -mtune=mpcore -mfloat-abi=softfp CFLAGS := -g -Wall -O2 -mword-relocations \ -fomit-frame-pointer -ffast-math \ @@ -113,10 +113,6 @@ else export APP_ICON := $(TOPDIR)/$(ICON) endif -ifeq ($(strip $(NO_SMDH)),) - export _3DSXFLAGS += --smdh=$(CURDIR)/$(TARGET).smdh -endif - .PHONY: $(BUILD) clean all #--------------------------------------------------------------------------------- @@ -141,11 +137,10 @@ DEPENDS := $(OFILES:.o=.d) # main targets #--------------------------------------------------------------------------------- ifeq ($(strip $(NO_SMDH)),) -$(OUTPUT).3dsx : $(OUTPUT).elf $(OUTPUT).smdh -else -$(OUTPUT).3dsx : $(OUTPUT).elf +.PHONY: all +all : $(OUTPUT).3dsx $(OUTPUT).smdh endif - +$(OUTPUT).3dsx : $(OUTPUT).elf $(OUTPUT).elf : $(OFILES) #--------------------------------------------------------------------------------- diff --git a/examples/mic/Makefile b/examples/mic/Makefile index 576126e..c4c758e 100644 --- a/examples/mic/Makefile +++ b/examples/mic/Makefile @@ -35,7 +35,7 @@ INCLUDES := include #--------------------------------------------------------------------------------- # options for code generation #--------------------------------------------------------------------------------- -ARCH := -march=armv6k -mtune=mpcore -mfloat-abi=hard +ARCH := -march=armv6k -mtune=mpcore -mfloat-abi=softfp CFLAGS := -g -Wall -O2 -mword-relocations \ -fomit-frame-pointer -ffast-math \ @@ -113,10 +113,6 @@ else export APP_ICON := $(TOPDIR)/$(ICON) endif -ifeq ($(strip $(NO_SMDH)),) - export _3DSXFLAGS += --smdh=$(CURDIR)/$(TARGET).smdh -endif - .PHONY: $(BUILD) clean all #--------------------------------------------------------------------------------- @@ -141,11 +137,10 @@ DEPENDS := $(OFILES:.o=.d) # main targets #--------------------------------------------------------------------------------- ifeq ($(strip $(NO_SMDH)),) -$(OUTPUT).3dsx : $(OUTPUT).elf $(OUTPUT).smdh -else -$(OUTPUT).3dsx : $(OUTPUT).elf +.PHONY: all +all : $(OUTPUT).3dsx $(OUTPUT).smdh endif - +$(OUTPUT).3dsx : $(OUTPUT).elf $(OUTPUT).elf : $(OFILES) #--------------------------------------------------------------------------------- diff --git a/examples/mvd/Makefile b/examples/mvd/Makefile index 576126e..c4c758e 100644 --- a/examples/mvd/Makefile +++ b/examples/mvd/Makefile @@ -35,7 +35,7 @@ INCLUDES := include #--------------------------------------------------------------------------------- # options for code generation #--------------------------------------------------------------------------------- -ARCH := -march=armv6k -mtune=mpcore -mfloat-abi=hard +ARCH := -march=armv6k -mtune=mpcore -mfloat-abi=softfp CFLAGS := -g -Wall -O2 -mword-relocations \ -fomit-frame-pointer -ffast-math \ @@ -113,10 +113,6 @@ else export APP_ICON := $(TOPDIR)/$(ICON) endif -ifeq ($(strip $(NO_SMDH)),) - export _3DSXFLAGS += --smdh=$(CURDIR)/$(TARGET).smdh -endif - .PHONY: $(BUILD) clean all #--------------------------------------------------------------------------------- @@ -141,11 +137,10 @@ DEPENDS := $(OFILES:.o=.d) # main targets #--------------------------------------------------------------------------------- ifeq ($(strip $(NO_SMDH)),) -$(OUTPUT).3dsx : $(OUTPUT).elf $(OUTPUT).smdh -else -$(OUTPUT).3dsx : $(OUTPUT).elf +.PHONY: all +all : $(OUTPUT).3dsx $(OUTPUT).smdh endif - +$(OUTPUT).3dsx : $(OUTPUT).elf $(OUTPUT).elf : $(OFILES) #--------------------------------------------------------------------------------- diff --git a/examples/sdmc/Makefile b/examples/sdmc/Makefile index 576126e..c4c758e 100644 --- a/examples/sdmc/Makefile +++ b/examples/sdmc/Makefile @@ -35,7 +35,7 @@ INCLUDES := include #--------------------------------------------------------------------------------- # options for code generation #--------------------------------------------------------------------------------- -ARCH := -march=armv6k -mtune=mpcore -mfloat-abi=hard +ARCH := -march=armv6k -mtune=mpcore -mfloat-abi=softfp CFLAGS := -g -Wall -O2 -mword-relocations \ -fomit-frame-pointer -ffast-math \ @@ -113,10 +113,6 @@ else export APP_ICON := $(TOPDIR)/$(ICON) endif -ifeq ($(strip $(NO_SMDH)),) - export _3DSXFLAGS += --smdh=$(CURDIR)/$(TARGET).smdh -endif - .PHONY: $(BUILD) clean all #--------------------------------------------------------------------------------- @@ -141,11 +137,10 @@ DEPENDS := $(OFILES:.o=.d) # main targets #--------------------------------------------------------------------------------- ifeq ($(strip $(NO_SMDH)),) -$(OUTPUT).3dsx : $(OUTPUT).elf $(OUTPUT).smdh -else -$(OUTPUT).3dsx : $(OUTPUT).elf +.PHONY: all +all : $(OUTPUT).3dsx $(OUTPUT).smdh endif - +$(OUTPUT).3dsx : $(OUTPUT).elf $(OUTPUT).elf : $(OFILES) #--------------------------------------------------------------------------------- From 6a195608aaed98a460d88174a3f383eb85c68f09 Mon Sep 17 00:00:00 2001 From: Dave Murphy Date: Fri, 5 Dec 2014 13:57:50 +0000 Subject: [PATCH 49/57] bump version for release, add dist target --- libctru/Makefile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libctru/Makefile b/libctru/Makefile index d1174a3..37ed8e8 100644 --- a/libctru/Makefile +++ b/libctru/Makefile @@ -9,7 +9,7 @@ endif include $(DEVKITARM)/base_rules export LIBCTRU_MAJOR := 0 -export LIBCTRU_MINOR := 1 +export LIBCTRU_MINOR := 2 export LIBCTRU_PATCH := 0 @@ -105,6 +105,8 @@ dist-bin: all dist-src: @tar -cjf libctru-src-$(VERSION).tar.bz2 include source Makefile Doxyfile Doxyfile.internal default_icon.png +dist: dist-src dist-bin + install: dist-bin mkdir -p $(DEVKITPRO)/libctru bzip2 -cd libctru-$(VERSION).tar.bz2 | tar -x -C $(DEVKITPRO)/libctru From a85c6edfaa16a43b6cb8fbd31fb3ad1fb1fc32ec Mon Sep 17 00:00:00 2001 From: Subv Date: Thu, 4 Dec 2014 12:04:59 -0500 Subject: [PATCH 50/57] Added svcReleaseSemaphore and svcCreateSemaphore. Tested. --- libctru/include/3ds/svc.h | 2 ++ libctru/source/svc.s | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/libctru/include/3ds/svc.h b/libctru/include/3ds/svc.h index d498d45..733db1a 100644 --- a/libctru/include/3ds/svc.h +++ b/libctru/include/3ds/svc.h @@ -62,6 +62,8 @@ void svcSleepThread(s64 ns); s32 svcSetThreadPriority(Handle thread, s32 prio); s32 svcCreateMutex(Handle* mutex, bool initially_locked); s32 svcReleaseMutex(Handle handle); +s32 svcCreateSemaphore(Handle* semaphore, s32 initial_count, s32 max_count); +s32 svcReleaseSemaphore(s32* count, Handle semaphore, s32 release_count); s32 svcCreateEvent(Handle* event, u8 reset_type); s32 svcSignalEvent(Handle handle); s32 svcClearEvent(Handle handle); diff --git a/libctru/source/svc.s b/libctru/source/svc.s index 2f2eb0e..3fac109 100644 --- a/libctru/source/svc.s +++ b/libctru/source/svc.s @@ -264,3 +264,21 @@ svcOutputDebugString: ldr r2, [sp], #4 str r1, [r2] bx lr + +.global svcCreateSemaphore +.type svcCreateSemaphore, %function +svcCreateSemaphore: + push {r0} + svc 0x15 + pop {r3} + str r1, [r3] + bx lr + +.global svcReleaseSemaphore +.type svcReleaseSemaphore, %function +svcReleaseSemaphore: + push {r0} + svc 0x16 + pop {r3} + str r1, [r3] + bx lr \ No newline at end of file From b5723c920939ec9051a0353150a490df940df599 Mon Sep 17 00:00:00 2001 From: fincs Date: Mon, 8 Dec 2014 15:57:39 +0100 Subject: [PATCH 51/57] Add gfxSetDoubleBuffering() for disabling double-buffering --- libctru/include/3ds/gfx.h | 1 + libctru/source/gfx.c | 25 +++++++++++++++---------- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/libctru/include/3ds/gfx.h b/libctru/include/3ds/gfx.h index 2965210..e7b33d3 100644 --- a/libctru/include/3ds/gfx.h +++ b/libctru/include/3ds/gfx.h @@ -22,6 +22,7 @@ void gfxExit(); //control stuff void gfxSet3D(bool enable); void gfxSetScreenFormat(gfxScreen_t screen, GSP_FramebufferFormats format); +void gfxSetDoubleBuffering(bool doubleBuffering); void gfxFlushBuffers(); void gfxSwapBuffers(); void gfxSwapBuffersGpu(); diff --git a/libctru/source/gfx.c b/libctru/source/gfx.c index 702051b..df99fcc 100644 --- a/libctru/source/gfx.c +++ b/libctru/source/gfx.c @@ -12,13 +12,14 @@ u8* gfxTopLeftFramebuffers[2]; u8* gfxTopRightFramebuffers[2]; u8* gfxBottomFramebuffers[2]; -u8 currentBuffer; -bool enable3d; +static u8 currentBuffer; +static bool enable3d; +static int doubleBuf = 1; Handle gspEvent, gspSharedMemHandle; -GSP_FramebufferFormats topFormat = GSP_BGR8_OES; -GSP_FramebufferFormats botFormat = GSP_BGR8_OES; +static GSP_FramebufferFormats topFormat = GSP_BGR8_OES; +static GSP_FramebufferFormats botFormat = GSP_BGR8_OES; void gfxSet3D(bool enable) { @@ -32,6 +33,10 @@ void gfxSetScreenFormat(gfxScreen_t screen, GSP_FramebufferFormats format) { botFormat = format; } +void gfxSetDoubleBuffering(bool doubleBuffering) { + doubleBuf = doubleBuffering ? 1 : 0; // make sure they're the integer values '1' and '0' +} + static u32 __get_bytes_per_pixel(GSP_FramebufferFormats format) { switch(format) { case GSP_RGBA8_OES: @@ -76,7 +81,7 @@ void gfxWriteFramebufferInfo(gfxScreen_t screen) u8* framebufferInfoHeader=gfxSharedMemory+0x200+gfxThreadID*0x80; if(screen==GFX_BOTTOM)framebufferInfoHeader+=0x40; GSP_FramebufferInfo* framebufferInfo=(GSP_FramebufferInfo*)&framebufferInfoHeader[0x4]; - framebufferInfoHeader[0x0]^=1; + framebufferInfoHeader[0x0]^=doubleBuf; framebufferInfo[framebufferInfoHeader[0x0]]=(screen==GFX_TOP)?(topFramebufferInfo):(bottomFramebufferInfo); framebufferInfoHeader[0x1]=1; } @@ -131,7 +136,7 @@ void gfxExit() // Exit event handler gspExitEventHandler(); - // Free framebuffers (let's pretend linearFree is actually implemented...) + // Free framebuffers linearFree(gfxTopRightFramebuffers[1]); linearFree(gfxTopRightFramebuffers[0]); linearFree(gfxBottomFramebuffers[1]); @@ -159,10 +164,10 @@ u8* gfxGetFramebuffer(gfxScreen_t screen, gfx3dSide_t side, u16* width, u16* hei if(screen==GFX_TOP) { if(height)*height=400; - return (side==GFX_LEFT || !enable3d)?(gfxTopLeftFramebuffers[currentBuffer^1]):(gfxTopRightFramebuffers[currentBuffer^1]); + return (side==GFX_LEFT || !enable3d)?(gfxTopLeftFramebuffers[currentBuffer^doubleBuf]):(gfxTopRightFramebuffers[currentBuffer^doubleBuf]); }else{ if(height)*height=320; - return gfxBottomFramebuffers[currentBuffer^1]; + return gfxBottomFramebuffers[currentBuffer^doubleBuf]; } } @@ -175,7 +180,7 @@ void gfxFlushBuffers() void gfxSwapBuffers() { - currentBuffer^=1; + currentBuffer^=doubleBuf; gfxSetFramebufferInfo(GFX_TOP, currentBuffer); gfxSetFramebufferInfo(GFX_BOTTOM, currentBuffer); GSPGPU_SetBufferSwap(NULL, GFX_TOP, &topFramebufferInfo); @@ -184,7 +189,7 @@ void gfxSwapBuffers() void gfxSwapBuffersGpu() { - currentBuffer^=1; + currentBuffer^=doubleBuf; gfxSetFramebufferInfo(GFX_TOP, currentBuffer); gfxSetFramebufferInfo(GFX_BOTTOM, currentBuffer); gfxWriteFramebufferInfo(GFX_TOP); From 8536e1e6ef4e49c62acf96510aec25c362db7b1c Mon Sep 17 00:00:00 2001 From: mtheall Date: Mon, 8 Dec 2014 12:12:34 -0600 Subject: [PATCH 52/57] Update poll.h --- libctru/include/poll.h | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/libctru/include/poll.h b/libctru/include/poll.h index 4315a43..67c7ae3 100644 --- a/libctru/include/poll.h +++ b/libctru/include/poll.h @@ -2,17 +2,12 @@ #include <3ds/types.h> -/* only POLLIN confirmed to work so far */ -#define POLLIN 0x001 -#define POLLPRI 0x002 -#define POLLOUT 0x004 -#define POLLERR 0x008 -#define POLLHUP 0x010 -#define POLLNVAL 0x020 -#define POLLRDNORM 0x040 -#define POLLRDBAND 0x080 -#define POLLWRNORM 0x100 -#define POLLWRBAND 0x200 +#define POLLIN 0x01 +#define POLLPRI 0x02 +#define POLLOUT 0x10 +#define POLLERR 0x00 // unknown ??? +#define POLLHUP 0x00 // unknown ??? +#define POLLNVAL 0x20 typedef u32 nfds_t; From f02082048ff3bd67840fabcafa01cb0c96f23de4 Mon Sep 17 00:00:00 2001 From: mtheall Date: Mon, 8 Dec 2014 16:19:07 -0600 Subject: [PATCH 53/57] Update poll.h --- libctru/include/poll.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libctru/include/poll.h b/libctru/include/poll.h index 67c7ae3..8b34a7a 100644 --- a/libctru/include/poll.h +++ b/libctru/include/poll.h @@ -4,9 +4,9 @@ #define POLLIN 0x01 #define POLLPRI 0x02 +#define POLLHUP 0x04 // unknown ??? +#define POLLERR 0x08 // probably #define POLLOUT 0x10 -#define POLLERR 0x00 // unknown ??? -#define POLLHUP 0x00 // unknown ??? #define POLLNVAL 0x20 typedef u32 nfds_t; From a2d2f4483ef67226dab56385b25ba78474e7b8fa Mon Sep 17 00:00:00 2001 From: Subv Date: Wed, 3 Dec 2014 21:15:38 -0500 Subject: [PATCH 54/57] SVC: Implemented svcGetThreadId --- libctru/include/3ds/svc.h | 1 + libctru/source/svc.s | 11 ++++++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/libctru/include/3ds/svc.h b/libctru/include/3ds/svc.h index 733db1a..ab0230c 100644 --- a/libctru/include/3ds/svc.h +++ b/libctru/include/3ds/svc.h @@ -86,4 +86,5 @@ s32 svcGetProcessInfo(s64* out, Handle process, u32 type); s32 svcConnectToPort(volatile Handle* out, const char* portName); s32 svcSendSyncRequest(Handle session); s32 svcGetProcessId(u32 *out, Handle handle); +s32 svcGetThreadId(u32 *out, Handle handle); s32 svcOutputDebugString(const char* str, int length); diff --git a/libctru/source/svc.s b/libctru/source/svc.s index 3fac109..a7d9efd 100644 --- a/libctru/source/svc.s +++ b/libctru/source/svc.s @@ -281,4 +281,13 @@ svcReleaseSemaphore: svc 0x16 pop {r3} str r1, [r3] - bx lr \ No newline at end of file + bx lr + +.global svcGetThreadId +.type svcGetThreadId, %function +svcGetThreadId: + str r0, [sp,#-0x4]! + svc 0x37 + ldr r3, [sp], #4 + str r1, [r3] + bx lr \ No newline at end of file From e0bf993fd999c1f6acd93575e163ba719b47a037 Mon Sep 17 00:00:00 2001 From: Subv Date: Mon, 8 Dec 2014 18:05:46 -0500 Subject: [PATCH 55/57] Styling --- libctru/source/svc.s | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/libctru/source/svc.s b/libctru/source/svc.s index a7d9efd..ded970f 100644 --- a/libctru/source/svc.s +++ b/libctru/source/svc.s @@ -286,8 +286,8 @@ svcReleaseSemaphore: .global svcGetThreadId .type svcGetThreadId, %function svcGetThreadId: - str r0, [sp,#-0x4]! - svc 0x37 - ldr r3, [sp], #4 - str r1, [r3] - bx lr \ No newline at end of file + str r0, [sp,#-0x4]! + svc 0x37 + ldr r3, [sp], #4 + str r1, [r3] + bx lr From 4b4b781ec39f46cf81b97be649a935143d44a5ae Mon Sep 17 00:00:00 2001 From: fincs Date: Tue, 9 Dec 2014 00:15:04 +0100 Subject: [PATCH 56/57] Minor code formatting fix in svc.s --- libctru/source/svc.s | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/libctru/source/svc.s b/libctru/source/svc.s index ded970f..4969df8 100644 --- a/libctru/source/svc.s +++ b/libctru/source/svc.s @@ -268,26 +268,26 @@ svcOutputDebugString: .global svcCreateSemaphore .type svcCreateSemaphore, %function svcCreateSemaphore: - push {r0} - svc 0x15 - pop {r3} - str r1, [r3] - bx lr - + push {r0} + svc 0x15 + pop {r3} + str r1, [r3] + bx lr + .global svcReleaseSemaphore .type svcReleaseSemaphore, %function svcReleaseSemaphore: - push {r0} - svc 0x16 - pop {r3} - str r1, [r3] - bx lr + push {r0} + svc 0x16 + pop {r3} + str r1, [r3] + bx lr .global svcGetThreadId .type svcGetThreadId, %function svcGetThreadId: - str r0, [sp,#-0x4]! - svc 0x37 - ldr r3, [sp], #4 - str r1, [r3] - bx lr + str r0, [sp, #-0x4]! + svc 0x37 + ldr r3, [sp], #4 + str r1, [r3] + bx lr From 88bef35b8f9d395da3cebf5d73bcacf273b19eee Mon Sep 17 00:00:00 2001 From: Dave Murphy Date: Mon, 8 Dec 2014 23:21:09 +0000 Subject: [PATCH 57/57] set default device so relative paths work in 3dmoo --- libctru/source/sdmc_dev.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/libctru/source/sdmc_dev.c b/libctru/source/sdmc_dev.c index 4d48117..1450574 100644 --- a/libctru/source/sdmc_dev.c +++ b/libctru/source/sdmc_dev.c @@ -140,15 +140,18 @@ Result sdmcInit(void) int dev = AddDevice(&sdmc_devoptab); - if (__system_argc != 0 && __system_argv[0] != NULL) - { - if (FindDevice(__system_argv[0]) == dev) + if (dev != -1) { + setDefaultDevice(dev); + if (__system_argc != 0 && __system_argv[0] != NULL) { - strncpy(__fixedpath,__system_argv[0],PATH_MAX); - char *last_slash = strrchr(__fixedpath,'/'); - if (last_slash != NULL) { - last_slash[0] = 0; - chdir(__fixedpath); + if (FindDevice(__system_argv[0]) == dev) + { + strncpy(__fixedpath,__system_argv[0],PATH_MAX); + char *last_slash = strrchr(__fixedpath,'/'); + if (last_slash != NULL) { + last_slash[0] = 0; + chdir(__fixedpath); + } } } }