forked from Jerware/PinSim
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathxInput.h
106 lines (89 loc) · 3.38 KB
/
xInput.h
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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
#include <NimBLEHIDDevice.h>
#include <NimBLECharacteristic.h>
#include <Callback.h>
#include "xInput_defs.h"
class HIDOutputCallbacks;
class ServerCallbacks;
// Dpad bitflags
enum XboxDpadFlags : uint8_t {
NONE = 0x00,
NORTH = 0x01,
EAST = 0x02,
SOUTH = 0x04,
WEST = 0x08
};
// Trigger range
#define XBOX_TRIGGER_MIN 0
#define XBOX_TRIGGER_MAX 1023
// Thumbstick range
#define XBOX_STICK_MIN -32768
#define XBOX_STICK_MAX 32767
#pragma pack(push, 1)
struct XboxGamepadInputReportData {
uint16_t x = 0; // Left joystick X
uint16_t y = 0; // Left joystick Y
uint16_t z = 0; // Right jostick X
uint16_t rz = 0; // Right joystick Y
uint16_t brake = 0; // 10 bits for brake (left trigger) + 6 bit padding (2 bytes)
uint16_t accelerator = 0; // 10 bits for accelerator (right trigger) + 6bit padding
uint8_t hat = 0x00; // 4bits for hat switch (Dpad) + 4 bit padding (1 byte)
uint16_t buttons = 0x00; // 15 * 1bit for buttons + 1 bit padding (2 bytes)
uint8_t share = 0x00; // 1 bits for share/menu button + 7 bit padding (1 byte)
};
#pragma pack(pop)
struct XboxGamepadOutputReportData {
uint8_t dcEnableActuators = 0x00; // 4bits for DC Enable Actuators, 4bits padding
uint8_t leftTriggerMagnitude = 0;
uint8_t rightTriggerMagnitude = 0;
uint8_t weakMotorMagnitude = 0;
uint8_t strongMotorMagnitude = 0;
uint8_t duration = 0; // UNUSED
uint8_t startDelay = 0; // UNUSED
uint8_t loopCount = 0; // UNUSED
constexpr XboxGamepadOutputReportData(uint64_t value = 0) noexcept :
dcEnableActuators((value & 0xFF)),
leftTriggerMagnitude((value >> 8) & 0xFF),
rightTriggerMagnitude((value >> 16) & 0xFF),
weakMotorMagnitude((value >> 24) & 0xFF),
strongMotorMagnitude((value >> 32) & 0xFF),
duration((value >> 40) & 0xFF),
startDelay((value >> 48) & 0xFF),
loopCount((value >> 56) & 0xFF)
{}
};
class XInput
{
public:
void startServer(const char *device_name, const char *manufacturer);
void startAdvertising(bool useBlackList);
void onAdvComplete(NimBLEAdvertising *advertising);
bool isConnected();
bool isAdvertising();
void clearPairedAddresses();
Signal<XboxGamepadOutputReportData> onVibrate;
void press(uint16_t button = XBOX_BUTTON_A);
void release(uint16_t button = XBOX_BUTTON_A);
bool isPressed(uint16_t button = XBOX_BUTTON_A);
void setLeftThumb(int16_t x = 0, int16_t y = 0);
void setRightThumb(int16_t z = 0, int16_t rZ = 0);
void setLeftTrigger(uint16_t rX = 0);
void setRightTrigger(uint16_t rY = 0);
void setTriggers(uint16_t rX = 0, uint16_t rY = 0);
void pressDPadDirection(XboxDpadFlags direction = XboxDpadFlags::NONE);
void releaseDPad();
bool isDPadPressed(XboxDpadFlags direction);
void pressShare();
void releaseShare();
void sendGamepadReport();
private:
NimBLEServer *_server;
NimBLEAdvertising *_advertising;
ServerCallbacks *_serverCallbacks;
NimBLEHIDDevice *_hid;
NimBLECharacteristic *_input;
NimBLECharacteristic *_output;
XboxGamepadInputReportData _inputReport;
HIDOutputCallbacks *_hidOutputCallbacks;
void pressDPadDirectionInternal(uint8_t direction = 0);
bool isDPadPressedInternal(uint8_t direction = 0);
};