added c-stick, ZL and ZR support via ir:rst
This commit is contained in:
parent
40d35ee420
commit
e115853aee
@ -19,6 +19,7 @@ extern "C" {
|
|||||||
#include <3ds/services/fs.h>
|
#include <3ds/services/fs.h>
|
||||||
#include <3ds/services/gsp.h>
|
#include <3ds/services/gsp.h>
|
||||||
#include <3ds/services/hid.h>
|
#include <3ds/services/hid.h>
|
||||||
|
#include <3ds/services/irrst.h>
|
||||||
#include <3ds/services/httpc.h>
|
#include <3ds/services/httpc.h>
|
||||||
#include <3ds/services/ir.h>
|
#include <3ds/services/ir.h>
|
||||||
#include <3ds/services/ptm.h>
|
#include <3ds/services/ptm.h>
|
||||||
|
@ -6,29 +6,35 @@
|
|||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
KEY_A = BIT(0),
|
KEY_A = BIT(0),
|
||||||
KEY_B = BIT(1),
|
KEY_B = BIT(1),
|
||||||
KEY_SELECT = BIT(2),
|
KEY_SELECT = BIT(2),
|
||||||
KEY_START = BIT(3),
|
KEY_START = BIT(3),
|
||||||
KEY_DRIGHT = BIT(4),
|
KEY_DRIGHT = BIT(4),
|
||||||
KEY_DLEFT = BIT(5),
|
KEY_DLEFT = BIT(5),
|
||||||
KEY_DUP = BIT(6),
|
KEY_DUP = BIT(6),
|
||||||
KEY_DDOWN = BIT(7),
|
KEY_DDOWN = BIT(7),
|
||||||
KEY_R = BIT(8),
|
KEY_R = BIT(8),
|
||||||
KEY_L = BIT(9),
|
KEY_L = BIT(9),
|
||||||
KEY_X = BIT(10),
|
KEY_X = BIT(10),
|
||||||
KEY_Y = BIT(11),
|
KEY_Y = BIT(11),
|
||||||
KEY_TOUCH = BIT(20), // Not actually provided by HID
|
KEY_ZL = BIT(14), // (new 3DS only)
|
||||||
KEY_CRIGHT = BIT(28),
|
KEY_ZR = BIT(15), // (new 3DS only)
|
||||||
KEY_CLEFT = BIT(29),
|
KEY_TOUCH = BIT(20), // Not actually provided by HID
|
||||||
KEY_CUP = BIT(30),
|
KEY_CSTICK_RIGHT = BIT(24), // c-stick (new 3DS only)
|
||||||
KEY_CDOWN = BIT(31),
|
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
|
// Generic catch-all directions
|
||||||
KEY_UP = KEY_DUP | KEY_CUP,
|
KEY_UP = KEY_DUP | KEY_CPAD_UP,
|
||||||
KEY_DOWN = KEY_DDOWN | KEY_CDOWN,
|
KEY_DOWN = KEY_DDOWN | KEY_CPAD_DOWN,
|
||||||
KEY_LEFT = KEY_DLEFT | KEY_CLEFT,
|
KEY_LEFT = KEY_DLEFT | KEY_CPAD_LEFT,
|
||||||
KEY_RIGHT = KEY_DRIGHT | KEY_CRIGHT,
|
KEY_RIGHT = KEY_DRIGHT | KEY_CPAD_RIGHT,
|
||||||
} PAD_KEY;
|
} PAD_KEY;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
|
25
libctru/include/3ds/services/irrst.h
Normal file
25
libctru/include/3ds/services/irrst.h
Normal file
@ -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);
|
@ -84,6 +84,7 @@ void hidScanInput()
|
|||||||
u32 Id=0;
|
u32 Id=0;
|
||||||
|
|
||||||
kOld = kHeld;
|
kOld = kHeld;
|
||||||
|
irrstScanInput();
|
||||||
|
|
||||||
kHeld = 0;
|
kHeld = 0;
|
||||||
memset(&cPos, 0, sizeof(circlePosition));
|
memset(&cPos, 0, sizeof(circlePosition));
|
||||||
@ -108,6 +109,8 @@ void hidScanInput()
|
|||||||
kHeld |= KEY_TOUCH;
|
kHeld |= KEY_TOUCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
kHeld |= irrstKeysHeld();
|
||||||
|
|
||||||
kDown = (~kOld) & kHeld;
|
kDown = (~kOld) & kHeld;
|
||||||
kUp = kOld & (~kHeld);
|
kUp = kOld & (~kHeld);
|
||||||
|
|
||||||
|
140
libctru/source/services/irrst.c
Normal file
140
libctru/source/services/irrst.c
Normal file
@ -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];
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user