hid: Internal state reading improvements.

Struct adjustments.
This commit is contained in:
yellows8 2020-11-16 23:29:32 -05:00 committed by fincs
parent 21647a76c8
commit 7340772267
No known key found for this signature in database
GPG Key ID: 62C7609ADA219C60
2 changed files with 69 additions and 31 deletions

View File

@ -445,6 +445,12 @@ typedef struct HidCommonStateHeader {
u64 max_entry; u64 max_entry;
} HidCommonStateHeader; } HidCommonStateHeader;
/// HidCommonStateEntry
typedef struct HidCommonStateEntry {
u64 timestamp;
u8 state[];
} HidCommonStateEntry;
// Begin HidTouchScreen // Begin HidTouchScreen
/// HidTouchScreenHeader /// HidTouchScreenHeader
@ -610,6 +616,19 @@ typedef struct HidControllerLayout {
HidControllerInputEntry entries[17]; HidControllerInputEntry entries[17];
} HidControllerLayout; } HidControllerLayout;
/// HidNpadGcTriggerState
typedef struct HidNpadGcTriggerState {
u64 timestamp;
u32 unk0;
u32 unk1;
} HidNpadGcTriggerState;
/// HidNpadGcTriggerStateEntry
typedef struct HidNpadGcTriggerStateEntry {
u64 timestamp;
HidNpadGcTriggerState state;
} HidNpadGcTriggerStateEntry;
/// HidNpadSixAxisSensorState /// HidNpadSixAxisSensorState
typedef struct HidNpadSixAxisSensorState { typedef struct HidNpadSixAxisSensorState {
u64 timestamp; u64 timestamp;
@ -696,8 +715,8 @@ typedef struct HidNpad {
}; };
u8 mutex[0x8]; u8 mutex[0x8];
u8 unk_x4210[0x18]; u8 unk_x4210[0x18];
u8 npad_gc_trigger_header[0x20]; HidCommonStateHeader npad_gc_trigger_header;
u8 npad_gc_trigger_state[0x198]; HidNpadGcTriggerStateEntry npad_gc_trigger_state[17];
u32 unk_x43E0; u32 unk_x43E0;
u32 unk_x43E4; u32 unk_x43E4;
u32 unk_x43E8; u32 unk_x43E8;

View File

@ -493,6 +493,41 @@ u8 hidGetAppletFooterUiTypes(u32 id) {
return tmp; return tmp;
} }
static Result _hidGetStates(HidCommonStateHeader *header, void* in_states, void* states, size_t entrysize, size_t count, size_t *total_out) {
if (total_out) *total_out = 0;
s32 total_entries = (s32)atomic_load_explicit(&header->max_entry, memory_order_acquire);
if (total_entries < 0) total_entries = 0;
if (total_entries > count) total_entries = count;
s32 latest_entry = (s32)atomic_load_explicit(&header->latest_entry, memory_order_acquire);
for (s32 i=0; i<total_entries; i++) {
s32 entrypos = (((latest_entry + 0x12) - total_entries) + i) % 0x11;
HidCommonStateEntry *state_entry = (HidCommonStateEntry*)((uintptr_t)in_states + entrypos*(entrysize+sizeof(u64)));
void* out_state = (void*)((uintptr_t)states + (total_entries-i-1)*entrysize);
void* out_state_prev = (void*)((uintptr_t)states + (total_entries-i)*entrysize);
u64 timestamp0=0, timestamp1=0;
timestamp0 = atomic_load_explicit(&state_entry->timestamp, memory_order_acquire);
memcpy(out_state, &state_entry->state, entrysize);
timestamp1 = atomic_load_explicit(&state_entry->timestamp, memory_order_acquire);
if (timestamp0 != timestamp1 || (i>0 && *((u64*)out_state) - *((u64*)out_state_prev) != 1)) {
s32 tmpcount = (s32)atomic_load_explicit(&header->max_entry, memory_order_acquire);
tmpcount = total_entries < tmpcount ? tmpcount : total_entries;
total_entries = tmpcount < count ? tmpcount : count;
latest_entry = (s32)atomic_load_explicit(&header->latest_entry, memory_order_acquire);
i=-1;
}
}
if (total_out) *total_out = total_entries;
return 0;
}
static Result _hidGetNpadStates(u32 id, u32 layout, HidNpadStateEntry *states, size_t count, size_t *total_out) { static Result _hidGetNpadStates(u32 id, u32 layout, HidNpadStateEntry *states, size_t count, size_t *total_out) {
if (total_out) *total_out = 0; if (total_out) *total_out = 0;
@ -505,60 +540,42 @@ static Result _hidGetNpadStates(u32 id, u32 layout, HidNpadStateEntry *states, s
HidControllerLayout *states_buf = &npad->layouts[layout]; HidControllerLayout *states_buf = &npad->layouts[layout];
s32 total_entries = (s32)atomic_load_explicit(&states_buf->header.max_entry, memory_order_acquire); return _hidGetStates(&states_buf->header, states_buf->entries, states, sizeof(HidNpadStateEntry), count, total_out);
if (total_entries < 0) total_entries = 0;
if (total_entries > count) total_entries = count;
s32 latest_entry = (s32)atomic_load_explicit(&states_buf->header.latest_entry, memory_order_acquire);
for (s32 i=0; i<total_entries; i++) {
s32 entrypos = (((latest_entry + 0x12) - total_entries) + i) % 0x11;
u64 timestamp0=0, timestamp1=0;
timestamp0 = atomic_load_explicit(&states_buf->entries[entrypos].timestamp, memory_order_acquire);
memcpy(&states[total_entries-i-1], &states_buf->entries[entrypos].state, sizeof(HidNpadStateEntry));
timestamp1 = atomic_load_explicit(&states_buf->entries[entrypos].timestamp, memory_order_acquire);
if (timestamp0 != timestamp1 || (i>0 && states[total_entries-i-1].timestamp - states[total_entries-i].timestamp != 1)) {
s32 tmpcount = (s32)atomic_load_explicit(&states_buf->header.max_entry, memory_order_acquire);
tmpcount = total_entries < tmpcount ? tmpcount : total_entries;
total_entries = tmpcount < count ? tmpcount : count;
latest_entry = (s32)atomic_load_explicit(&states_buf->header.latest_entry, memory_order_acquire);
i=-1;
}
}
if (total_out) *total_out = total_entries;
// sdknso would handle button-bitmasking with ControlPadRestriction here.
return 0;
} }
void hidGetNpadStatesFullKey(u32 id, HidNpadFullKeyState *states, size_t count, size_t *total_out) { void hidGetNpadStatesFullKey(u32 id, HidNpadFullKeyState *states, size_t count, size_t *total_out) {
Result rc = _hidGetNpadStates(id, 0, states, count, total_out); Result rc = _hidGetNpadStates(id, 0, states, count, total_out);
if (R_FAILED(rc)) diagAbortWithResult(rc); if (R_FAILED(rc)) diagAbortWithResult(rc);
// sdknso would handle button-bitmasking with ControlPadRestriction here.
} }
void hidGetNpadStatesHandheld(u32 id, HidNpadHandheldState *states, size_t count, size_t *total_out) { void hidGetNpadStatesHandheld(u32 id, HidNpadHandheldState *states, size_t count, size_t *total_out) {
Result rc = _hidGetNpadStates(id, 1, states, count, total_out); Result rc = _hidGetNpadStates(id, 1, states, count, total_out);
if (R_FAILED(rc)) diagAbortWithResult(rc); if (R_FAILED(rc)) diagAbortWithResult(rc);
// sdknso would handle button-bitmasking with ControlPadRestriction here.
} }
void hidGetNpadStatesJoyDual(u32 id, HidNpadJoyDualState *states, size_t count, size_t *total_out) { void hidGetNpadStatesJoyDual(u32 id, HidNpadJoyDualState *states, size_t count, size_t *total_out) {
Result rc = _hidGetNpadStates(id, 2, states, count, total_out); Result rc = _hidGetNpadStates(id, 2, states, count, total_out);
if (R_FAILED(rc)) diagAbortWithResult(rc); if (R_FAILED(rc)) diagAbortWithResult(rc);
// sdknso would handle button-bitmasking with ControlPadRestriction here.
} }
void hidGetNpadStatesJoyLeft(u32 id, HidNpadJoyLeftState *states, size_t count, size_t *total_out) { void hidGetNpadStatesJoyLeft(u32 id, HidNpadJoyLeftState *states, size_t count, size_t *total_out) {
Result rc = _hidGetNpadStates(id, 3, states, count, total_out); Result rc = _hidGetNpadStates(id, 3, states, count, total_out);
if (R_FAILED(rc)) diagAbortWithResult(rc); if (R_FAILED(rc)) diagAbortWithResult(rc);
// sdknso would handle button-bitmasking with ControlPadRestriction here.
} }
void hidGetNpadStatesJoyRight(u32 id, HidNpadJoyRightState *states, size_t count, size_t *total_out) { void hidGetNpadStatesJoyRight(u32 id, HidNpadJoyRightState *states, size_t count, size_t *total_out) {
Result rc = _hidGetNpadStates(id, 4, states, count, total_out); Result rc = _hidGetNpadStates(id, 4, states, count, total_out);
if (R_FAILED(rc)) diagAbortWithResult(rc); if (R_FAILED(rc)) diagAbortWithResult(rc);
// sdknso would handle button-bitmasking with ControlPadRestriction here.
} }
void hidGetNpadStatesPalma(u32 id, HidNpadPalmaState *states, size_t count, size_t *total_out) { void hidGetNpadStatesPalma(u32 id, HidNpadPalmaState *states, size_t count, size_t *total_out) {
@ -664,6 +681,8 @@ void hidGetNpadStatesLucia(u32 id, HidNpadLuciaState *states, size_t count, size
void hidGetNpadStatesSystemExt(u32 id, HidNpadSystemExtState *states, size_t count, size_t *total_out) { void hidGetNpadStatesSystemExt(u32 id, HidNpadSystemExtState *states, size_t count, size_t *total_out) {
Result rc = _hidGetNpadStates(id, 6, states, count, total_out); Result rc = _hidGetNpadStates(id, 6, states, count, total_out);
if (R_FAILED(rc)) diagAbortWithResult(rc); if (R_FAILED(rc)) diagAbortWithResult(rc);
// sdknso would handle button-bitmasking with ControlPadRestriction here.
} }
void hidGetNpadStatesSystem(u32 id, HidNpadSystemState *states, size_t count, size_t *total_out) { void hidGetNpadStatesSystem(u32 id, HidNpadSystemState *states, size_t count, size_t *total_out) {