blob: 0ebc2d7ddf098d74a1bc14dfae7f901b78f4e1f9 [file] [log] [blame]
// 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;
}