-
Notifications
You must be signed in to change notification settings - Fork 243
Expand file tree
/
Copy pathXInputManager.cpp
More file actions
109 lines (97 loc) · 3.26 KB
/
XInputManager.cpp
File metadata and controls
109 lines (97 loc) · 3.26 KB
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
#include "Common.h"
#include "XInputManager.h"
#include "Core/Shared/Emulator.h"
#include "Core/Shared/EmuSettings.h"
XInputManager::XInputManager(Emulator* emu)
{
_emu = emu;
for(int i = 0; i < XUSER_MAX_COUNT; i++) {
_gamePadConnected[i] = true;
}
}
void XInputManager::RefreshState()
{
XINPUT_STATE state;
for(DWORD i = 0; i < XUSER_MAX_COUNT; i++) {
if(_gamePadConnected[i]) {
if(XInputGetState(i, &state) != ERROR_SUCCESS) {
//XInputGetState is incredibly slow when no controller is plugged in
ZeroMemory(&_gamePadStates[i], sizeof(XINPUT_STATE));
_gamePadConnected[i] = false;
} else {
_gamePadStates[i] = state;
}
}
}
}
bool XInputManager::NeedToUpdate()
{
for(int i = 0; i < XUSER_MAX_COUNT; i++) {
if(!_gamePadConnected[i]) {
XINPUT_STATE state;
if(XInputGetState(i, &state) == ERROR_SUCCESS) {
return true;
}
}
}
return false;
}
void XInputManager::UpdateDeviceList()
{
//Periodically detect if a controller has been plugged in to allow controllers to be plugged in after the emu is started
for(int i = 0; i < XUSER_MAX_COUNT; i++) {
_gamePadConnected[i] = true;
}
}
bool XInputManager::IsPressed(uint8_t gamepadPort, uint8_t button)
{
if(_gamePadConnected[gamepadPort]) {
XINPUT_GAMEPAD &gamepad = _gamePadStates[gamepadPort].Gamepad;
bool pressed = false;
if(button <= 16) {
WORD xinputButton = 1 << (button - 1);
pressed = (_gamePadStates[gamepadPort].Gamepad.wButtons & xinputButton) != 0;
} else {
double ratio = _emu->GetSettings()->GetControllerDeadzoneRatio() * 2;
switch(button) {
case 17: pressed = gamepad.bLeftTrigger > (XINPUT_GAMEPAD_TRIGGER_THRESHOLD * ratio); break;
case 18: pressed = gamepad.bRightTrigger > (XINPUT_GAMEPAD_TRIGGER_THRESHOLD * ratio); break;
case 19: pressed = gamepad.sThumbRY > (XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE * ratio); break;
case 20: pressed = gamepad.sThumbRY < -(XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE * ratio); break;
case 21: pressed = gamepad.sThumbRX < -(XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE * ratio); break;
case 22: pressed = gamepad.sThumbRX > (XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE * ratio); break;
case 23: pressed = gamepad.sThumbLY > (XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE * ratio); break;
case 24: pressed = gamepad.sThumbLY < -(XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE * ratio); break;
case 25: pressed = gamepad.sThumbLX < -(XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE * ratio); break;
case 26: pressed = gamepad.sThumbLX > (XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE * ratio); break;
}
}
_enableForceFeedback[gamepadPort] |= pressed;
return pressed;
}
return false;
}
optional<int16_t> XInputManager::GetAxisPosition(uint8_t port, int axis)
{
if(_gamePadConnected[port]) {
XINPUT_GAMEPAD& gamepad = _gamePadStates[port].Gamepad;
switch(axis - 27) {
case 0: return gamepad.sThumbLY;
case 1: return gamepad.sThumbLX;
case 2: return gamepad.sThumbRY;
case 3: return gamepad.sThumbRX;
}
}
return std::nullopt;
}
void XInputManager::SetForceFeedback(uint16_t magnitudeRight, uint16_t magnitudeLeft)
{
XINPUT_VIBRATION settings = {};
settings.wRightMotorSpeed = magnitudeRight;
settings.wLeftMotorSpeed = magnitudeLeft;
for(int i = 0; i < XUSER_MAX_COUNT; i++) {
if(_enableForceFeedback[i]) {
XInputSetState(i, &settings);
}
}
}