hid: add hidWaitForAnyEvent, allow user to override irrst usage check (#454)

This commit is contained in:
TuxSH 2020-05-13 22:09:55 +01:00 committed by GitHub
parent e86e906895
commit c9326f6bce
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 59 additions and 17 deletions

View File

@ -146,6 +146,14 @@ void hidGyroRead(angularRate* rate);
*/
void hidWaitForEvent(HID_Event id, bool nextEvent);
/**
* @brief Waits for any HID or IRRST event.
* @param nextEvents Whether to discard the current events and wait for the next events.
* @param cancelEvent Optional additional handle to wait on, otherwise 0.
* @param timeout Timeout.
*/
Result hidWaitForAnyEvent(bool nextEvents, Handle cancelEvent, s64 timeout);
/// Compatibility macro for hidScanInput.
#define scanKeys hidScanInput
/// Compatibility macro for hidKeysHeld.

View File

@ -14,6 +14,9 @@ extern Handle irrstMemHandle;
/// IRRST's shared memory.
extern vu32* irrstSharedMem;
/// IRRST's state update event
extern Handle irrstEvent;
/// Initializes IRRST.
Result irrstInit(void);

View File

@ -29,9 +29,16 @@ static angularRate gRate;
static int hidRefCount;
static bool usingIrrst;
bool __attribute__((weak)) hidShouldUseIrrst(void)
{
bool val;
return R_SUCCEEDED(APT_CheckNew3DS(&val)) && val;
}
Result hidInit(void)
{
bool val=false;
Result ret=0;
if (AtomicPostIncrement(&hidRefCount)) return 0;
@ -52,17 +59,12 @@ Result hidInit(void)
goto cleanup1;
}
if(R_FAILED(ret=svcMapMemoryBlock(hidMemHandle, (u32)hidSharedMem, MEMPERM_READ, 0x10000000)))goto cleanup2;
if(R_FAILED(ret=svcMapMemoryBlock(hidMemHandle, (u32)hidSharedMem, MEMPERM_READ, MEMPERM_DONTCARE)))goto cleanup2;
APT_CheckNew3DS(&val);
if(val)
{
usingIrrst = hidShouldUseIrrst();
if(usingIrrst)
ret = irrstInit();
}
// Reset internal state.
kOld = kHeld = kDown = kUp = 0;
return ret;
cleanup2:
@ -83,19 +85,17 @@ void hidExit(void)
{
if (AtomicDecrement(&hidRefCount)) return;
// Reset internal state.
kOld = kHeld = kDown = kUp = 0;
// Unmap HID sharedmem and close handles.
bool val=false;
int i; for(i=0; i<5; i++)svcCloseHandle(hidEvents[i]);
svcUnmapMemoryBlock(hidMemHandle, (u32)hidSharedMem);
svcCloseHandle(hidMemHandle);
svcCloseHandle(hidHandle);
APT_CheckNew3DS(&val);
if(val)
{
if(usingIrrst)
irrstExit();
}
if(hidSharedMem != NULL)
{
@ -115,6 +115,36 @@ void hidWaitForEvent(HID_Event id, bool nextEvent)
svcClearEvent(hidEvents[id]);
}
Result hidWaitForAnyEvent(bool nextEvents, Handle cancelEvent, s64 timeout)
{
Handle events[HIDEVENT_MAX + 2];
u32 numEvents = HIDEVENT_MAX + (irrstEvent != 0 ? 1 : 0) + (cancelEvent ? 1 : 0);
if (nextEvents)
{
for (u32 i = 0; i < HIDEVENT_MAX; i++)
svcClearEvent(hidEvents[i]);
svcClearEvent(irrstEvent);
}
memcpy(events, hidEvents, sizeof(hidEvents));
events[HIDEVENT_MAX] = irrstEvent;
events[HIDEVENT_MAX + 1] = cancelEvent;
s32 idx;
Result res = svcWaitSynchronizationN(&idx, events, numEvents, false, timeout);
if (res == 0 && !nextEvents)
{
// No timeout & next event
for (u32 i = 0; i < HIDEVENT_MAX; i++)
svcClearEvent(hidEvents[i]);
svcClearEvent(irrstEvent);
}
return res;
}
u32 hidCheckSectionUpdateTime(vu32 *sharedmem_section, u32 id)
{
s64 tick0=0, tick1=0;

View File

@ -48,8 +48,6 @@ Result irrstInit(void)
if(R_FAILED(ret = svcMapMemoryBlock(irrstMemHandle, (u32)irrstSharedMem, MEMPERM_READ, 0x10000000))) goto cleanup2;
// Reset internal state.
kHeld = 0;
return 0;
cleanup2:
@ -70,6 +68,9 @@ void irrstExit(void)
{
if (AtomicDecrement(&irrstRefCount)) return;
// Reset internal state.
kHeld = 0;
svcCloseHandle(irrstEvent);
// Unmap ir:rst sharedmem and close handles.
svcUnmapMemoryBlock(irrstMemHandle, (u32)irrstSharedMem);