aboutsummaryrefslogtreecommitdiff
path: root/arm9/source/devices/input.c
blob: 401f05318d1bcdfa34658d15ac616e13f56503f5 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
#include "input.h"
#include "../config.h"


// Reset an input device.
void input_reset(InputDevice *input) {
    input->pointer = false;
    input->keyboard = false;
    input->x = 0;
    input->y = 0;
    input->x_read = 0;
    input->y_read = 0;
    circbuf_clear(&input->keybuffer);
    input->gamepad = 0;
    input->wake = false;
}

// Update the cached read value for the pointer x coordinate.
void input_read_x(InputDevice *input) {
    input->x_read = input->x;
}

// Update the cached read value for the pointer y coordinate.
void input_read_y(InputDevice *input) {
    input->y_read = input->y;
}

// Receive a byte from a keyboard.
// TODO: Make this function Unicode-aware by receiving a u32 instead of
// a u8, so that the keybuffer can be checked for capacity before pushing.
void input_receive_key(InputDevice *input, u8 byte) {
    circbuf_write(&input->keybuffer, byte);
    input->wake = true;
}

// Read the current gamepad state.
void input_update_gamepad(InputDevice *input) {
    u32 held = keysHeld();
    u8 gamepad = (
        TEST(held, KEY_UP)    << 7
      | TEST(held, KEY_DOWN)  << 6
      | TEST(held, KEY_LEFT)  << 5
      | TEST(held, KEY_RIGHT) << 4
      | TEST(held, KEY_A)     << 3
      | TEST(held, KEY_B)     << 2
      | TEST(held, KEY_X)     << 1
      | TEST(held, KEY_Y)     << 0
    );
    // If the L and R bumper keys aren't being used to switch between
    // instances, map them to be alternate X and Y keys.
    if (!SWITCH_BETWEEN_INSTANCES) {
        gamepad |= TEST(held, KEY_L) << 1;
        gamepad |= TEST(held, KEY_R) << 0;
    }
    if (gamepad != input->gamepad) {
        input->wake = true;
        input->gamepad = gamepad;
    }
}

// Read the current touchscreen state.
void input_update_touch(InputDevice *input) {
    // Test if pointer is active.
    bool pointer = TEST(keysHeld(), KEY_TOUCH);
    if (pointer != input->pointer) {
        input->wake = true;
        input->pointer = pointer;
    }
    // Update pointer position.
    if (pointer) {
        touchPosition position;
        touchRead(&position);
        if (position.px != input->x || position.py != input->y) {
            input->wake = true;
            input->x = position.px;
            input->y = position.py;
        }
    }
}