]> Chaos Git - corbenik/ctrulib.git/commitdiff
added c-stick, ZL and ZR support via ir:rst
authorsmea <smealum@gmail.com>
Sun, 26 Oct 2014 01:30:19 +0000 (18:30 -0700)
committersmea <smealum@gmail.com>
Sun, 26 Oct 2014 01:30:19 +0000 (18:30 -0700)
libctru/include/3ds.h
libctru/include/3ds/services/hid.h
libctru/include/3ds/services/irrst.h [new file with mode: 0644]
libctru/source/services/hid.c
libctru/source/services/irrst.c [new file with mode: 0644]

index 1f17a92e81bd21d2ffff7a8979f5006b1c8d892e..2111f0417417d296c5f43d9433e2770e2fc4558f 100644 (file)
@@ -19,6 +19,7 @@ extern "C" {
 #include <3ds/services/fs.h>
 #include <3ds/services/gsp.h>
 #include <3ds/services/hid.h>
+#include <3ds/services/irrst.h>
 #include <3ds/services/httpc.h>
 #include <3ds/services/ir.h>
 #include <3ds/services/ptm.h>
index 3333abb21455429d2d6594ecb0bfecd30c0a964b..4ba6aa746d2b1cb3f684b8e121cf7c6cc974483f 100644 (file)
@@ -6,29 +6,35 @@
 
 typedef enum
 {
-       KEY_A      = BIT(0),
-       KEY_B      = BIT(1),
-       KEY_SELECT = BIT(2),
-       KEY_START  = BIT(3),
-       KEY_DRIGHT = BIT(4),
-       KEY_DLEFT  = BIT(5),
-       KEY_DUP    = BIT(6),
-       KEY_DDOWN  = BIT(7),
-       KEY_R      = BIT(8),
-       KEY_L      = BIT(9),
-       KEY_X      = BIT(10),
-       KEY_Y      = BIT(11),
-       KEY_TOUCH  = BIT(20), // Not actually provided by HID
-       KEY_CRIGHT = BIT(28),
-       KEY_CLEFT  = BIT(29),
-       KEY_CUP    = BIT(30),
-       KEY_CDOWN  = BIT(31),
+       KEY_A       = BIT(0),
+       KEY_B       = BIT(1),
+       KEY_SELECT  = BIT(2),
+       KEY_START   = BIT(3),
+       KEY_DRIGHT  = BIT(4),
+       KEY_DLEFT   = BIT(5),
+       KEY_DUP     = BIT(6),
+       KEY_DDOWN   = BIT(7),
+       KEY_R       = BIT(8),
+       KEY_L       = BIT(9),
+       KEY_X       = BIT(10),
+       KEY_Y       = BIT(11),
+       KEY_ZL      = BIT(14), // (new 3DS only)
+       KEY_ZR      = BIT(15), // (new 3DS only)
+       KEY_TOUCH   = BIT(20), // Not actually provided by HID
+       KEY_CSTICK_RIGHT = BIT(24), // c-stick (new 3DS only)
+       KEY_CSTICK_LEFT  = BIT(25), // c-stick (new 3DS only)
+       KEY_CSTICK_UP    = BIT(26), // c-stick (new 3DS only)
+       KEY_CSTICK_DOWN  = BIT(27), // c-stick (new 3DS only)
+       KEY_CPAD_RIGHT = BIT(28), // circle pad
+       KEY_CPAD_LEFT  = BIT(29), // circle pad
+       KEY_CPAD_UP    = BIT(30), // circle pad
+       KEY_CPAD_DOWN  = BIT(31), // circle pad
 
        // Generic catch-all directions
-       KEY_UP    = KEY_DUP    | KEY_CUP,
-       KEY_DOWN  = KEY_DDOWN  | KEY_CDOWN,
-       KEY_LEFT  = KEY_DLEFT  | KEY_CLEFT,
-       KEY_RIGHT = KEY_DRIGHT | KEY_CRIGHT,
+       KEY_UP    = KEY_DUP    | KEY_CPAD_UP,
+       KEY_DOWN  = KEY_DDOWN  | KEY_CPAD_DOWN,
+       KEY_LEFT  = KEY_DLEFT  | KEY_CPAD_LEFT,
+       KEY_RIGHT = KEY_DRIGHT | KEY_CPAD_RIGHT,
 } PAD_KEY;
 
 typedef struct
diff --git a/libctru/include/3ds/services/irrst.h b/libctru/include/3ds/services/irrst.h
new file mode 100644 (file)
index 0000000..2390eb4
--- /dev/null
@@ -0,0 +1,25 @@
+#pragma once
+
+//See also: http://3dbrew.org/wiki/IR_Services http://3dbrew.org/wiki/IRRST_Shared_Memory
+
+#include "3ds/services/hid.h" // for circlePosition definition
+
+#define IRRST_SHAREDMEM_DEFAULT (0x1000A000)
+
+extern Handle irrstMemHandle;
+extern vu32* irrstSharedMem;
+
+Result irrstInit(u32* sharedMem);
+void irrstExit();
+
+void irrstScanInput();
+u32 irrstKeysHeld();
+void irrstCstickRead(circlePosition* pos);
+
+void irrstWaitForEvent(bool nextEvent);
+
+#define hidCstickRead irrstCstickRead // because why not
+
+Result IRRST_GetHandles(Handle* outMemHandle, Handle* outEventHandle);
+Result IRRST_Initialize(u32 unk1, u8 unk2);
+Result IRRST_Shutdown(void);
index 9e3256683833276cea97944ede67640eaaebf58d..eb14c5da1e4c4d14a29751aee8c5062fd661bc7d 100644 (file)
@@ -84,6 +84,7 @@ void hidScanInput()
        u32 Id=0;
 
        kOld = kHeld;
+       irrstScanInput();
 
        kHeld = 0;
        memset(&cPos, 0, sizeof(circlePosition));
@@ -108,6 +109,8 @@ void hidScanInput()
                        kHeld |= KEY_TOUCH;
        }
 
+       kHeld |= irrstKeysHeld();
+
        kDown = (~kOld) & kHeld;
        kUp = kOld & (~kHeld);
 
diff --git a/libctru/source/services/irrst.c b/libctru/source/services/irrst.c
new file mode 100644 (file)
index 0000000..f00aaa2
--- /dev/null
@@ -0,0 +1,140 @@
+/*
+  _irrst.c - C-stick, ZL/ZR
+*/
+#include <stdlib.h>
+#include <string.h>
+#include <3ds.h>
+
+Handle irrstHandle;
+Handle irrstMemHandle;
+Handle irrstEvent;
+
+vu32* irrstSharedMem;
+
+static u32 kHeld;
+static circlePosition csPos;
+static bool irrstUsed = false;
+
+Result irrstInit(u32* sharedMem)
+{
+       if(!sharedMem)sharedMem=(u32*)IRRST_SHAREDMEM_DEFAULT;
+       Result ret=0;
+
+       // Request service.
+       if((ret=srvGetServiceHandle(&irrstHandle, "ir:rst")))return ret;
+
+       // Get sharedmem handle.
+       if((ret=IRRST_GetHandles(&irrstMemHandle, &irrstEvent))) goto cleanup1;
+
+       // Map ir:rst shared memory at addr "sharedMem".
+       irrstSharedMem=sharedMem;
+       if((ret=svcMapMemoryBlock(irrstMemHandle, (u32)irrstSharedMem, MEMPERM_READ, 0x10000000)))goto cleanup2;
+
+       // Reset internal state.
+       irrstUsed = true;
+       kHeld = 0;
+       return 0;
+
+cleanup2:
+       svcCloseHandle(irrstMemHandle);
+cleanup1:
+       svcCloseHandle(irrstHandle);
+       return ret;
+}
+
+void irrstExit()
+{
+       irrstUsed = false;
+       // Unmap ir:rst sharedmem and close handles.
+       svcUnmapMemoryBlock(irrstMemHandle, (u32)irrstSharedMem);
+       svcCloseHandle(irrstMemHandle);
+       svcCloseHandle(irrstHandle);
+}
+
+void irrstWaitForEvent(bool nextEvent)
+{
+       if(nextEvent)svcClearEvent(irrstEvent);
+       svcWaitSynchronization(irrstEvent, U64_MAX);
+       if(!nextEvent)svcClearEvent(irrstEvent);
+}
+
+u32 irrstCheckSectionUpdateTime(vu32 *sharedmem_section, u32 id)
+{
+       s64 tick0=0, tick1=0;
+
+       if(id==0)
+       {
+               tick0 = *((u64*)&sharedmem_section[0]);
+               tick1 = *((u64*)&sharedmem_section[2]);
+
+               if(tick0==tick1 || tick0<0 || tick1<0)return 1;
+       }
+
+       return 0;
+}
+
+void irrstScanInput()
+{
+       if(!irrstUsed)return;
+       
+       u32 Id=0;
+       kHeld = 0;
+       memset(&csPos, 0, sizeof(circlePosition));
+
+       Id = irrstSharedMem[4]; //PAD / circle-pad
+       if(Id>7)Id=7;
+       if(irrstCheckSectionUpdateTime(irrstSharedMem, Id)==0)
+       {
+               kHeld = irrstSharedMem[6 + Id*4];
+               csPos = *(circlePosition*)&irrstSharedMem[6 + Id*4 + 3];
+       }
+}
+
+u32 irrstKeysHeld()
+{
+       if(irrstUsed)return kHeld;
+       return 0;
+}
+
+void irrstCstickRead(circlePosition* pos)
+{
+       if (pos) *pos = csPos;
+}
+
+Result IRRST_GetHandles(Handle* outMemHandle, Handle* outEventHandle)
+{
+       u32* cmdbuf=getThreadCommandBuffer();
+       cmdbuf[0]=0x00010000; //request header code
+
+       Result ret=0;
+       if((ret=svcSendSyncRequest(irrstHandle)))return ret;
+
+       if(outMemHandle)*outMemHandle=cmdbuf[3];
+       if(outEventHandle)*outEventHandle=cmdbuf[4];
+
+       return cmdbuf[1];
+}
+
+Result IRRST_Initialize(u32 unk1, u8 unk2)
+{
+       u32* cmdbuf=getThreadCommandBuffer();
+       cmdbuf[0]=0x00020080; //request header code
+       cmdbuf[1]=unk1;
+       cmdbuf[2]=unk2;
+
+       Result ret=0;
+       if((ret=svcSendSyncRequest(irrstHandle)))return ret;
+
+       return cmdbuf[1];
+}
+
+Result IRRST_Shutdown(void)
+{
+       u32* cmdbuf=getThreadCommandBuffer();
+       cmdbuf[0]=0x00030000; //request header code
+
+       Result ret=0;
+       if((ret=svcSendSyncRequest(irrstHandle)))return ret;
+
+       return cmdbuf[1];
+}