-
Notifications
You must be signed in to change notification settings - Fork 0
/
gamepad.cpp
126 lines (102 loc) · 4.05 KB
/
gamepad.cpp
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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
#include "moonlight.hpp"
#include "ppapi/c/ppb_gamepad.h"
#include <Limelight.h>
static const unsigned short k_StandardGamepadButtonMapping[] = {
A_FLAG, B_FLAG, X_FLAG, Y_FLAG,
LB_FLAG, RB_FLAG,
0, 0, // Triggers
BACK_FLAG, PLAY_FLAG,
LS_CLK_FLAG, RS_CLK_FLAG,
UP_FLAG, DOWN_FLAG, LEFT_FLAG, RIGHT_FLAG,
SPECIAL_FLAG
};
static const unsigned int k_StandardGamepadTriggerButtonIndexes[] = {
6, 7
};
static short GetActiveGamepadMask(PP_GamepadsSampleData& gamepadData) {
short controllerIndex = 0;
short activeGamepadMask = 0;
for (unsigned int p = 0; p < gamepadData.length; p++) {
PP_GamepadSampleData& padData = gamepadData.items[p];
if (!padData.connected) {
// Not connected
continue;
}
if (padData.timestamp == 0) {
// On some platforms, Chrome returns "connected" pads that
// really aren't, so timestamp stays at zero. To work around this,
// we'll only count gamepads that have a non-zero timestamp in our
// controller index.
continue;
}
activeGamepadMask |= (1 << controllerIndex);
controllerIndex++;
}
return activeGamepadMask;
}
void MoonlightInstance::PollGamepads() {
PP_GamepadsSampleData gamepadData;
short controllerIndex = 0;
short activeGamepadMask;
m_GamepadApi->Sample(pp_instance(), &gamepadData);
// We must determine which gamepads are connected before reporting
// any events.
activeGamepadMask = GetActiveGamepadMask(gamepadData);
for (unsigned int p = 0; p < gamepadData.length; p++) {
PP_GamepadSampleData& padData = gamepadData.items[p];
if (!padData.connected) {
// Not connected
continue;
}
if (padData.timestamp == 0) {
// On some platforms, Chrome returns "connected" pads that
// really aren't, so timestamp stays at zero. To work around this,
// we'll only count gamepads that have a non-zero timestamp in our
// controller index.
continue;
}
if (padData.timestamp == m_LastPadTimestamps[p]) {
// No change from last poll, but this controller is still valid
// so we skip this index.
controllerIndex++;
continue;
}
m_LastPadTimestamps[p] = padData.timestamp;
short buttonFlags = 0;
unsigned char leftTrigger = 0, rightTrigger = 0;
short leftStickX = 0, leftStickY = 0;
short rightStickX = 0, rightStickY = 0;
// Handle buttons and triggers
for (unsigned int i = 0; i < padData.buttons_length; i++) {
if (i >= sizeof(k_StandardGamepadButtonMapping) / sizeof(k_StandardGamepadButtonMapping[0])) {
// Ignore unmapped buttons
break;
}
// Handle triggers first
if (i == k_StandardGamepadTriggerButtonIndexes[0]) {
leftTrigger = padData.buttons[i] * 0xFF;
}
else if (i == k_StandardGamepadTriggerButtonIndexes[1]) {
rightTrigger = padData.buttons[i] * 0xFF;
}
// Now normal buttons
else if (padData.buttons[i] > 0.5f) {
buttonFlags |= k_StandardGamepadButtonMapping[i];
}
}
// Get left stick values
if (padData.axes_length >= 2) {
leftStickX = padData.axes[0] * 0x7FFF;
leftStickY = -padData.axes[1] * 0x7FFF;
}
// Get right stick values
if (padData.axes_length >= 4) {
rightStickX = padData.axes[2] * 0x7FFF;
rightStickY = -padData.axes[3] * 0x7FFF;
}
LiSendMultiControllerEvent(controllerIndex, activeGamepadMask,
buttonFlags, leftTrigger, rightTrigger,
leftStickX, leftStickY, rightStickX, rightStickY);
controllerIndex++;
}
}