OpenRetroPad/src/gamepad/common.h

332 lines
7.7 KiB
C++

#ifndef GAMEPAD_COMMON_H
#define GAMEPAD_COMMON_H
#include <Arduino.h>
#define ARDUINO_ARCH_ESP32 1
#include "HIDTypes.h"
#if GAMEPAD_OUTPUT == 5 // nintendo switch
#define BUTTON_A NSButton_A
#define BUTTON_B NSButton_B
#define BUTTON_MENU NSButton_Home
#define BUTTON_X NSButton_X
#define BUTTON_Y NSButton_Y
#define BUTTON_TL NSButton_LeftTrigger
#define BUTTON_TR NSButton_RightTrigger
#define BUTTON_TL2 NSButton_LeftThrottle
#define BUTTON_TR2 NSButton_RightThrottle
#define BUTTON_SELECT NSButton_Minus
#define BUTTON_START NSButton_Plus
#define BUTTON_THUMBL NSButton_LeftStick
#define BUTTON_THUMBR NSButton_RightStick
#define DPAD_CENTER NSGAMEPAD_DPAD_CENTERED
#define DPAD_UP NSGAMEPAD_DPAD_UP
#define DPAD_UP_RIGHT NSGAMEPAD_DPAD_UP_RIGHT
#define DPAD_RIGHT NSGAMEPAD_DPAD_RIGHT
#define DPAD_DOWN_RIGHT NSGAMEPAD_DPAD_DOWN_RIGHT
#define DPAD_DOWN NSGAMEPAD_DPAD_DOWN
#define DPAD_DOWN_LEFT NSGAMEPAD_DPAD_DOWN_LEFT
#define DPAD_LEFT NSGAMEPAD_DPAD_LEFT
#define DPAD_UP_LEFT NSGAMEPAD_DPAD_UP_LEFT
#define AXIS_CENTER 128
#define AXIS_MAX 255
#define AXIS_MIN 0
// not supported by horipad yet...
#define TRIGGER_MAX 255
#define TRIGGER_MIN 0
#else
#define BUTTON_A 1
#define BUTTON_B 2
#define BUTTON_MENU 4
#define BUTTON_X 8
#define BUTTON_Y 16
#define BUTTON_TL 64
#define BUTTON_TR 128
#define BUTTON_TL2 256
#define BUTTON_TR2 512
#define BUTTON_SELECT 1024
#define BUTTON_START 2048
#define BUTTON_THUMBL 8192
#define BUTTON_THUMBR 16384
#define DPAD_CENTER 0
#define DPAD_UP 1
#define DPAD_UP_RIGHT 2
#define DPAD_RIGHT 3
#define DPAD_DOWN_RIGHT 4
#define DPAD_DOWN 5
#define DPAD_DOWN_LEFT 6
#define DPAD_LEFT 7
#define DPAD_UP_LEFT 8
#define AXIS_CENTER 0
#define AXIS_MAX 32767
#define AXIS_MIN -32767
#define TRIGGER_MAX 255
#define TRIGGER_MIN 0
#endif // nintendo switch
// aliases
#define BUTTON_HOME BUTTON_MENU
#define BUTTON_L BUTTON_TL
#define BUTTON_L1 BUTTON_TL
#define BUTTON_R BUTTON_TR
#define BUTTON_R1 BUTTON_TR
#define BUTTON_L2 BUTTON_TL2
#define BUTTON_R2 BUTTON_TR2
#define BUTTON_L3 BUTTON_THUMBL
#define BUTTON_R3 BUTTON_THUMBR
#define DPAD_CENTERED DPAD_CENTER
// end aliases
#ifndef AXIS_CENTER_IN
#define AXIS_CENTER_IN 0
#endif
#ifndef AXIS_MAX_IN
#define AXIS_MAX_IN 32767
#endif
#ifndef AXIS_MIN_IN
#define AXIS_MIN_IN -32767
#endif
#ifndef TRIGGER_MAX_IN
#define TRIGGER_MAX_IN 127
#endif
#ifndef TRIGGER_MIN_IN
#define TRIGGER_MIN_IN -127
#endif
#if 0
#define BUTTON_1 1
#define BUTTON_2 2
#define BUTTON_3 4
#define BUTTON_4 8
#define BUTTON_5 16
#define BUTTON_6 32
#define BUTTON_7 64
#define BUTTON_8 128
#define BUTTON_9 256
#define BUTTON_10 512
#define BUTTON_11 1024
#define BUTTON_12 2048
#define BUTTON_13 4096
#define BUTTON_14 8192
#define BUTTON_15 16384
#define BUTTON_16 32768
#define BUTTON_17 65536
#define BUTTON_18 131072
#define BUTTON_19 262144
#define BUTTON_20 524288
#define BUTTON_21 1048576
#define BUTTON_22 2097152
#define BUTTON_23 4194304
#define BUTTON_24 8388608
#define BUTTON_25 16777216
#define BUTTON_26 33554432
#define BUTTON_27 67108864
#define BUTTON_28 134217728
#define BUTTON_29 268435456
#define BUTTON_30 536870912
#define BUTTON_31 1073741824
#define BUTTON_32 2147483648
#endif
#ifndef GAMEPAD_REPORT_ARRAY_ADD
// this is used by radio gamepad to send additional info
#define GAMEPAD_REPORT_ARRAY_ADD 0
#endif
// this must match _hidReportDescriptor, length to actually send
#define GAMEPAD_REPORT_LEN 15
static const uint8_t _hidReportDescriptor[] PROGMEM = {
USAGE_PAGE(1),
0x01, // USAGE_PAGE (Generic Desktop)
USAGE(1),
0x05, // USAGE (Gamepad)
COLLECTION(1),
0x01, // COLLECTION (Application)
USAGE(1),
0x01, // USAGE (Pointer)
COLLECTION(1),
0x00, // COLLECTION (Physical)
// ------------------------------------------------- Buttons (1 to 32)
USAGE_PAGE(1),
0x09, // USAGE_PAGE (Button)
USAGE_MINIMUM(1),
0x01, // USAGE_MINIMUM (Button 1)
USAGE_MAXIMUM(1),
0x20, // USAGE_MAXIMUM (Button 32)
LOGICAL_MINIMUM(1),
0x00, // LOGICAL_MINIMUM (0)
LOGICAL_MAXIMUM(1),
0x01, // LOGICAL_MAXIMUM (1)
REPORT_SIZE(1),
0x01, // REPORT_SIZE (1)
REPORT_COUNT(1),
0x20, // REPORT_COUNT (32)
HIDINPUT(1),
0x02, // INPUT (Data, Variable, Absolute) ;32 button bits
// ------------------------------------------------- X/Y position, Z/rZ position
USAGE_PAGE(1),
0x01, // USAGE_PAGE (Generic Desktop)
COLLECTION(1),
0x00, // COLLECTION (Physical)
USAGE(1),
0x30, // USAGE (X)
USAGE(1),
0x31, // USAGE (Y)
USAGE(1),
0x32, // USAGE (Z)
USAGE(1),
0x35, // USAGE (rZ)
0x16,
0x01,
0x80, //LOGICAL_MINIMUM (-32767)
0x26,
0xFF,
0x7F, //LOGICAL_MAXIMUM (32767)
REPORT_SIZE(1),
0x10, // REPORT_SIZE (16)
REPORT_COUNT(1),
0x04, // REPORT_COUNT (4)
HIDINPUT(1),
0x02, // INPUT (Data,Var,Abs)
// ------------------------------------------------- Triggers
USAGE(1),
0x33, // USAGE (rX) Left Trigger
USAGE(1),
0x34, // USAGE (rY) Right Trigger
LOGICAL_MINIMUM(1),
0x81, // LOGICAL_MINIMUM (-127)
LOGICAL_MAXIMUM(1),
0x7f, // LOGICAL_MAXIMUM (127)
REPORT_SIZE(1),
0x08, // REPORT_SIZE (8)
REPORT_COUNT(1),
0x02, // REPORT_COUNT (2)
HIDINPUT(1),
0x02, // INPUT (Data, Variable, Absolute) ;4 bytes (X,Y,Z,rZ)
END_COLLECTION(0), // END_COLLECTION
USAGE_PAGE(1),
0x01, // USAGE_PAGE (Generic Desktop)
USAGE(1),
0x39, // USAGE (Hat switch)
USAGE(1),
0x39, // USAGE (Hat switch)
LOGICAL_MINIMUM(1),
0x01, // LOGICAL_MINIMUM (1)
LOGICAL_MAXIMUM(1),
0x08, // LOGICAL_MAXIMUM (8)
REPORT_SIZE(1),
0x04, // REPORT_SIZE (4)
REPORT_COUNT(1),
0x02, // REPORT_COUNT (2)
HIDINPUT(1),
0x02, // INPUT (Data, Variable, Absolute) ;1 byte Hat1, Hat2
END_COLLECTION(0), // END_COLLECTION
END_COLLECTION(0) // END_COLLECTION
};
class AbstractGamepad {
public:
uint32_t _buttons[GAMEPAD_COUNT];
uint8_t gamepadReport[GAMEPAD_REPORT_LEN + GAMEPAD_REPORT_ARRAY_ADD];
AbstractGamepad() {
}
virtual void begin(void) {
}
virtual void end(void) {
}
virtual bool isConnected(void) {
return true;
}
virtual void setAxis(const uint8_t cIdx, int16_t x, int16_t y, int16_t z, int16_t rZ, char rX, char rY, signed char hat) {
if (x == -32768) {
x = -32767;
}
if (y == -32768) {
y = -32767;
}
if (z == -32768) {
z = -32767;
}
if (rZ == -32768) {
rZ = -32767;
}
gamepadReport[0] = _buttons[cIdx];
gamepadReport[1] = (_buttons[cIdx] >> 8);
gamepadReport[2] = (_buttons[cIdx] >> 16);
gamepadReport[3] = (_buttons[cIdx] >> 24);
gamepadReport[4] = x;
gamepadReport[5] = (x >> 8);
gamepadReport[6] = y;
gamepadReport[7] = (y >> 8);
gamepadReport[8] = z;
gamepadReport[9] = (z >> 8);
gamepadReport[10] = rZ;
gamepadReport[11] = (rZ >> 8);
gamepadReport[12] = (signed char)(rX - 128);
gamepadReport[13] = (signed char)(rY - 128);
gamepadReport[14] = hat;
if (gamepadReport[12] == -128) {
gamepadReport[12] = -127;
}
if (gamepadReport[13] == -128) {
gamepadReport[13] = -127;
}
this->sync(cIdx);
}
virtual void setHatSync(const uint8_t cIdx, signed char hat) {
setAxis(cIdx, AXIS_CENTER, AXIS_CENTER, AXIS_CENTER, AXIS_CENTER, 0, 0, hat);
}
virtual void buttons(const uint8_t cIdx, uint32_t b) {
_buttons[cIdx] = b;
}
virtual void press(const uint8_t cIdx, uint32_t b) {
buttons(cIdx, _buttons[cIdx] | b);
}
virtual void release(const uint8_t cIdx, uint32_t b) {
buttons(cIdx, _buttons[cIdx] & ~b);
}
virtual bool isPressed(const uint8_t cIdx, uint32_t b) {
return ((b & _buttons[cIdx]) > 0);
}
virtual void sync(const uint8_t cIdx) {
sendHidReport(cIdx, &gamepadReport, GAMEPAD_REPORT_LEN);
}
virtual void sendHidReport(const uint8_t cIdx, const void* d, int len); // actually sends report
virtual ~AbstractGamepad() {
}
};
#endif // GAMEPAD_COMMON_H