| // GPIO dpad + ABXY |
| #include "input.hpp" |
| |
| #include "hardware/gpio.h" |
| |
| #include "pico/binary_info.h" |
| |
| #include "class/hid/hid.h" |
| |
| #include "engine/api_private.hpp" |
| #include "engine/input.hpp" |
| |
| // from USB code |
| extern uint32_t hid_gamepad_id; |
| extern bool hid_keyboard_detected; |
| extern uint8_t hid_joystick[2]; |
| extern uint8_t hid_hat; |
| extern uint32_t hid_buttons; |
| extern uint8_t hid_keys[6]; |
| |
| struct GamepadMapping { |
| uint32_t id; // vid:pid |
| uint8_t a, b, x, y; |
| uint8_t up, down, left, right; // if no hat |
| uint8_t menu, home, joystick; |
| }; |
| |
| #define NO 0xFF |
| |
| static const GamepadMapping gamepad_mappings[]{ |
| {0x15320705, 0, 1, 3, 4, NO, NO, NO, NO, 16, 15, 13}, // Razer Raiju Mobile |
| {0x20D6A711, 2, 1, 3, 0, NO, NO, NO, NO, 8, 12, 10}, // PowerA wired Switch pro controller |
| {0x2DC89018, 0, 1, 3, 4, NO, NO, NO, NO, 10, 11, NO}, // 8BitDo Zero 2 |
| {0x00000000, 0, 1, 2, 3, NO, NO, NO, NO, 4, 5, 6} // probably wrong fallback |
| }; |
| |
| #undef NO |
| |
| // hat -> dpad |
| const uint32_t dpad_map[]{ |
| blit::Button::DPAD_UP, |
| blit::Button::DPAD_UP | blit::Button::DPAD_RIGHT, |
| blit::Button::DPAD_RIGHT, |
| blit::Button::DPAD_DOWN | blit::Button::DPAD_RIGHT, |
| blit::Button::DPAD_DOWN, |
| blit::Button::DPAD_DOWN | blit::Button::DPAD_LEFT, |
| blit::Button::DPAD_LEFT, |
| blit::Button::DPAD_UP | blit::Button::DPAD_LEFT, |
| 0 |
| }; |
| |
| void init_input() { |
| } |
| |
| void update_input() { |
| using namespace blit; |
| |
| if(!hid_keyboard_detected && !hid_gamepad_id) { |
| blit::api_data.buttons = 0; |
| return; |
| } |
| |
| uint32_t new_buttons = 0; |
| |
| // keyboard |
| if(hid_keyboard_detected) { |
| |
| for(int i = 0; i < 6; i++) { |
| switch(hid_keys[i]) { |
| case HID_KEY_ARROW_UP: |
| case HID_KEY_W: |
| new_buttons |= uint32_t(Button::DPAD_UP); |
| break; |
| case HID_KEY_ARROW_DOWN: |
| case HID_KEY_S: |
| new_buttons |= uint32_t(Button::DPAD_DOWN); |
| break; |
| case HID_KEY_ARROW_LEFT: |
| case HID_KEY_A: |
| new_buttons |= uint32_t(Button::DPAD_LEFT); |
| break; |
| case HID_KEY_ARROW_RIGHT: |
| case HID_KEY_D: |
| new_buttons |= uint32_t(Button::DPAD_RIGHT); |
| break; |
| |
| case HID_KEY_Z: |
| case HID_KEY_U: |
| new_buttons |= uint32_t(Button::A); |
| break; |
| case HID_KEY_X: |
| case HID_KEY_I: |
| new_buttons |= uint32_t(Button::B); |
| break; |
| case HID_KEY_C: |
| case HID_KEY_O: |
| new_buttons |= uint32_t(Button::X); |
| break; |
| case HID_KEY_V: |
| case HID_KEY_P: |
| new_buttons |= uint32_t(Button::Y); |
| break; |
| |
| case HID_KEY_1: |
| new_buttons |= uint32_t(Button::HOME); |
| break; |
| |
| case HID_KEY_2: |
| case HID_KEY_ESCAPE: |
| new_buttons |= uint32_t(Button::MENU); |
| break; |
| |
| case HID_KEY_3: |
| new_buttons |= uint32_t(Button::JOYSTICK); |
| break; |
| } |
| } |
| } |
| |
| if(!hid_gamepad_id) |
| return; |
| |
| // gamepad |
| auto mapping = gamepad_mappings; |
| while(mapping->id && mapping->id != hid_gamepad_id) |
| mapping++; |
| |
| new_buttons = new_buttons |
| | dpad_map[hid_hat > 8 ? 8 : hid_hat] |
| | (hid_buttons & (1 << mapping->left) ? uint32_t(Button::DPAD_LEFT) : 0) |
| | (hid_buttons & (1 << mapping->right) ? uint32_t(Button::DPAD_RIGHT) : 0) |
| | (hid_buttons & (1 << mapping->up) ? uint32_t(Button::DPAD_UP) : 0) |
| | (hid_buttons & (1 << mapping->down) ? uint32_t(Button::DPAD_DOWN) : 0) |
| | (hid_buttons & (1 << mapping->a) ? uint32_t(Button::A) : 0) |
| | (hid_buttons & (1 << mapping->b) ? uint32_t(Button::B) : 0) |
| | (hid_buttons & (1 << mapping->x) ? uint32_t(Button::X) : 0) |
| | (hid_buttons & (1 << mapping->y) ? uint32_t(Button::Y) : 0) |
| | (hid_buttons & (1 << mapping->menu) ? uint32_t(Button::MENU) : 0) |
| | (hid_buttons & (1 << mapping->home) ? uint32_t(Button::HOME) : 0) |
| | (hid_buttons & (1 << mapping->joystick) ? uint32_t(Button::JOYSTICK) : 0); |
| |
| api_data.buttons = new_buttons; |
| |
| api_data.joystick.x = (float(hid_joystick[0]) - 0x80) / 0x80; |
| api_data.joystick.y = (float(hid_joystick[1]) - 0x80) / 0x80; |
| } |