Add hidWaitForAnyEvent

This commit is contained in:
TuxSH 2020-05-13 20:23:05 +01:00
parent e86e906895
commit 56cf58c020
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); 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. /// Compatibility macro for hidScanInput.
#define scanKeys hidScanInput #define scanKeys hidScanInput
/// Compatibility macro for hidKeysHeld. /// Compatibility macro for hidKeysHeld.

View File

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

View File

@ -29,9 +29,16 @@ static angularRate gRate;
static int hidRefCount; static int hidRefCount;
static bool usingIrrst;
bool __attribute__((weak)) hidShouldUseIrrst(void)
{
bool val;
return R_SUCCEEDED(APT_CheckNew3DS(&val)) && val;
}
Result hidInit(void) Result hidInit(void)
{ {
bool val=false;
Result ret=0; Result ret=0;
if (AtomicPostIncrement(&hidRefCount)) return 0; if (AtomicPostIncrement(&hidRefCount)) return 0;
@ -52,17 +59,12 @@ Result hidInit(void)
goto cleanup1; 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); usingIrrst = hidShouldUseIrrst();
if(usingIrrst)
if(val)
{
ret = irrstInit(); ret = irrstInit();
}
// Reset internal state.
kOld = kHeld = kDown = kUp = 0;
return ret; return ret;
cleanup2: cleanup2:
@ -83,19 +85,17 @@ void hidExit(void)
{ {
if (AtomicDecrement(&hidRefCount)) return; if (AtomicDecrement(&hidRefCount)) return;
// Reset internal state.
kOld = kHeld = kDown = kUp = 0;
// Unmap HID sharedmem and close handles. // Unmap HID sharedmem and close handles.
bool val=false;
int i; for(i=0; i<5; i++)svcCloseHandle(hidEvents[i]); int i; for(i=0; i<5; i++)svcCloseHandle(hidEvents[i]);
svcUnmapMemoryBlock(hidMemHandle, (u32)hidSharedMem); svcUnmapMemoryBlock(hidMemHandle, (u32)hidSharedMem);
svcCloseHandle(hidMemHandle); svcCloseHandle(hidMemHandle);
svcCloseHandle(hidHandle); svcCloseHandle(hidHandle);
APT_CheckNew3DS(&val); if(usingIrrst)
if(val)
{
irrstExit(); irrstExit();
}
if(hidSharedMem != NULL) if(hidSharedMem != NULL)
{ {
@ -115,6 +115,36 @@ void hidWaitForEvent(HID_Event id, bool nextEvent)
svcClearEvent(hidEvents[id]); 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) u32 hidCheckSectionUpdateTime(vu32 *sharedmem_section, u32 id)
{ {
s64 tick0=0, tick1=0; 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; if(R_FAILED(ret = svcMapMemoryBlock(irrstMemHandle, (u32)irrstSharedMem, MEMPERM_READ, 0x10000000))) goto cleanup2;
// Reset internal state.
kHeld = 0;
return 0; return 0;
cleanup2: cleanup2:
@ -70,6 +68,9 @@ void irrstExit(void)
{ {
if (AtomicDecrement(&irrstRefCount)) return; if (AtomicDecrement(&irrstRefCount)) return;
// Reset internal state.
kHeld = 0;
svcCloseHandle(irrstEvent); svcCloseHandle(irrstEvent);
// Unmap ir:rst sharedmem and close handles. // Unmap ir:rst sharedmem and close handles.
svcUnmapMemoryBlock(irrstMemHandle, (u32)irrstSharedMem); svcUnmapMemoryBlock(irrstMemHandle, (u32)irrstSharedMem);