2016-02-13 17:29:56 +01:00
|
|
|
#include "hid.h"
|
2016-10-17 23:45:22 +02:00
|
|
|
#include "i2c.h"
|
2016-05-30 01:54:09 +02:00
|
|
|
#include "timer.h"
|
2018-03-07 01:15:12 +01:00
|
|
|
#include "screenshot.h" // for screenshots
|
2016-02-13 17:29:56 +01:00
|
|
|
|
2019-04-17 11:58:54 -03:00
|
|
|
#include "arm.h"
|
2019-04-18 16:39:45 -03:00
|
|
|
#include "shmem.h"
|
2019-04-17 11:58:54 -03:00
|
|
|
|
2019-04-18 16:39:45 -03:00
|
|
|
// there's some weird thing going on when reading this
|
|
|
|
// with an LDRD instruction so for now they'll be two
|
|
|
|
// separate things - hopefully LTO won't get in the way
|
2019-04-17 11:58:54 -03:00
|
|
|
u32 HID_ReadState(void)
|
2019-04-18 16:39:45 -03:00
|
|
|
{
|
|
|
|
return ARM_GetSHMEM()->hid_state;
|
|
|
|
}
|
|
|
|
|
|
|
|
u32 HID_ReadRawTouchState(void)
|
|
|
|
{
|
|
|
|
return ARM_GetSHMEM()->hid_state >> 32;
|
2019-04-17 11:58:54 -03:00
|
|
|
}
|
|
|
|
|
2017-08-04 02:08:56 +02:00
|
|
|
u32 InputWait(u32 timeout_sec) {
|
2016-05-30 03:03:40 +02:00
|
|
|
static u64 delay = 0;
|
2017-08-04 02:08:56 +02:00
|
|
|
u64 timer = timer_start();
|
2019-04-17 11:58:54 -03:00
|
|
|
|
|
|
|
u32 oldpad = HID_ReadState();
|
|
|
|
u32 oldcart = CART_STATE;
|
|
|
|
u32 oldsd = SD_STATE;
|
|
|
|
|
|
|
|
delay = delay ? 72 : 128;
|
|
|
|
|
|
|
|
do {
|
|
|
|
u32 newpad = HID_ReadState();
|
|
|
|
|
|
|
|
if (!newpad) { // no buttons pressed, check for I/O changes instead
|
|
|
|
u32 state = CART_STATE;
|
|
|
|
if (state != oldcart)
|
|
|
|
return state ? CART_INSERT : CART_EJECT;
|
|
|
|
|
|
|
|
state = SD_STATE;
|
|
|
|
if (state != oldsd)
|
|
|
|
return state ? SD_INSERT : SD_EJECT;
|
|
|
|
|
|
|
|
oldpad = 0;
|
2016-05-30 03:03:40 +02:00
|
|
|
delay = 0;
|
2016-04-05 23:19:29 +02:00
|
|
|
continue;
|
|
|
|
}
|
2019-04-17 11:58:54 -03:00
|
|
|
|
|
|
|
// special case for dpad keys
|
|
|
|
// if any of those are held, don't wait for key changes
|
|
|
|
// but do insert a small latency to make
|
|
|
|
// sure any menus don't go flying off
|
|
|
|
if ((newpad == oldpad) &&
|
|
|
|
(!(newpad & BUTTON_ARROW) ||
|
2017-08-04 02:08:56 +02:00
|
|
|
(delay && (timer_msec(timer) < delay))))
|
2016-04-05 23:19:29 +02:00
|
|
|
continue;
|
2019-04-17 11:58:54 -03:00
|
|
|
|
2016-04-05 23:19:29 +02:00
|
|
|
u32 t_pressed = 0;
|
2019-04-17 11:58:54 -03:00
|
|
|
while((t_pressed++ < 0x13000) && (newpad == HID_ReadState()));
|
2018-03-07 01:15:12 +01:00
|
|
|
if (t_pressed >= 0x13000) {
|
2019-04-17 11:58:54 -03:00
|
|
|
if ((newpad & BUTTON_ANY) == (BUTTON_R1 | BUTTON_L1))
|
2018-03-07 01:15:12 +01:00
|
|
|
CreateScreenshot(); // screenshot handling
|
2019-04-17 11:58:54 -03:00
|
|
|
return newpad;
|
2018-03-07 01:15:12 +01:00
|
|
|
}
|
2019-04-17 11:58:54 -03:00
|
|
|
} while (!timeout_sec || (timeout_sec && (timer_sec(timer) < timeout_sec)));
|
|
|
|
|
|
|
|
return TIMEOUT_HID;
|
2016-02-13 17:29:56 +01:00
|
|
|
}
|
2016-10-17 23:45:22 +02:00
|
|
|
|
|
|
|
bool CheckButton(u32 button) {
|
2019-04-17 11:58:54 -03:00
|
|
|
return (HID_ReadState() & button) == button;
|
2016-10-17 23:45:22 +02:00
|
|
|
}
|
2018-04-25 15:25:07 +02:00
|
|
|
|
|
|
|
void ButtonToString(u32 button, char* str) {
|
|
|
|
const char* strings[] = { BUTTON_STRINGS };
|
|
|
|
|
|
|
|
*str = '\0';
|
|
|
|
if (button) {
|
|
|
|
u32 b = 0;
|
|
|
|
for (b = 0; !((button>>b)&0x1); b++);
|
|
|
|
if (b < countof(strings)) strcpy(str, strings[b]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
u32 StringToButton(char* str) {
|
|
|
|
const char* strings[] = { BUTTON_STRINGS };
|
|
|
|
|
|
|
|
u32 b = 0;
|
|
|
|
for (b = 0; b < countof(strings); b++)
|
|
|
|
if (strcmp(str, strings[b]) == 0) break;
|
|
|
|
|
|
|
|
return (b == countof(strings)) ? 0 : 1<<b;
|
|
|
|
}
|