43 lines1.3 KBC
1/*
2input.c: presses and auto-repeat on top of the backend's held buttons.
3*/
4#include "plat.h"
5#include "input.h"
6
7#define REPEAT_MASK (BTN_UP | BTN_DOWN | BTN_LEFT | BTN_RIGHT) // not L1/R1: held, they would skip track after track
8#define REPEAT_DELAY_US 380000
9#define REPEAT_RATE_US 70000
10
11static uint32_t held, pressed, fresh;
12static uint64_t since[16], last_rep[16];
13
14void input_update(void)
15{
16 uint32_t now = plat_input_held();
17 // a console that confirms with O: the app's "X" is that button, its "O" the other
18 if (plat_circle_confirms() && ((now & BTN_CROSS) != 0) != ((now & BTN_CIRCLE) != 0))
19 now ^= BTN_CROSS | BTN_CIRCLE;
20 uint64_t t = plat_time_us();
21 pressed = now & ~held;
22 fresh = pressed;
23 for (int b = 0; b < 16; b++) {
24 uint32_t bit = 1u << b;
25 if (pressed & bit) {
26 since[b] = t;
27 last_rep[b] = t;
28 } else if ((now & bit) && (bit & REPEAT_MASK)) {
29 // held longer, it speeds up: long lists don't take all day
30 uint64_t held_for = t - since[b];
31 uint64_t rate = held_for > 2500000 ? REPEAT_RATE_US / 3 : held_for > 1200000 ? REPEAT_RATE_US / 2 : REPEAT_RATE_US;
32 if (held_for > REPEAT_DELAY_US && t - last_rep[b] > rate) {
33 pressed |= bit;
34 last_rep[b] = t;
35 }
36 }
37 }
38 held = now;
39}
40
41uint32_t input_pressed(void) { return pressed; }
42uint32_t input_held(void) { return held; }
43uint32_t input_fresh(void) { return fresh; }