1 #include "stdafx.h"
2 #include "XInputManager.h"
3 #include "../Core/Console.h"
4 #include "../Core/EmulationSettings.h"
5 
XInputManager(shared_ptr<Console> console)6 XInputManager::XInputManager(shared_ptr<Console> console)
7 {
8 	_console = console;
9 	for(int i = 0; i < XUSER_MAX_COUNT; i++) {
10 		_gamePadStates.push_back(shared_ptr<XINPUT_STATE>(new XINPUT_STATE()));
11 		_gamePadConnected.push_back(true);
12 	}
13 }
14 
RefreshState()15 void XInputManager::RefreshState()
16 {
17 	XINPUT_STATE state;
18 	for(DWORD i = 0; i < XUSER_MAX_COUNT; i++) {
19 		if(_gamePadConnected[i]) {
20 			if(XInputGetState(i, &state) != ERROR_SUCCESS) {
21 				//XInputGetState is incredibly slow when no controller is plugged in
22 				ZeroMemory(_gamePadStates[i].get(), sizeof(XINPUT_STATE));
23 				_gamePadConnected[i] = false;
24 			} else {
25 				*_gamePadStates[i] = state;
26 			}
27 		}
28 	}
29 }
30 
NeedToUpdate()31 bool XInputManager::NeedToUpdate()
32 {
33 	for(int i = 0; i < XUSER_MAX_COUNT; i++) {
34 		if(!_gamePadConnected[i]) {
35 			XINPUT_STATE state;
36 			if(XInputGetState(i, &state) == ERROR_SUCCESS) {
37 				return true;
38 			}
39 		}
40 	}
41 	return false;
42 }
43 
UpdateDeviceList()44 void XInputManager::UpdateDeviceList()
45 {
46 	//Periodically detect if a controller has been plugged in to allow controllers to be plugged in after the emu is started
47 	for(int i = 0; i < XUSER_MAX_COUNT; i++) {
48 		_gamePadConnected[i] = true;
49 	}
50 }
51 
IsPressed(uint8_t gamepadPort,uint8_t button)52 bool XInputManager::IsPressed(uint8_t gamepadPort, uint8_t button)
53 {
54 	if(_gamePadConnected[gamepadPort]) {
55 		XINPUT_GAMEPAD &gamepad = _gamePadStates[gamepadPort]->Gamepad;
56 		if(button <= 16) {
57 			WORD xinputButton = 1 << (button - 1);
58 			return (_gamePadStates[gamepadPort]->Gamepad.wButtons & xinputButton) != 0;
59 		} else {
60 			double ratio = _console->GetSettings()->GetControllerDeadzoneRatio() * 2;
61 
62 			switch(button) {
63 				case 17: return gamepad.bLeftTrigger > (XINPUT_GAMEPAD_TRIGGER_THRESHOLD * ratio);
64 				case 18: return gamepad.bRightTrigger > (XINPUT_GAMEPAD_TRIGGER_THRESHOLD * ratio);
65 				case 19: return gamepad.sThumbRY > (XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE * ratio);
66 				case 20: return gamepad.sThumbRY < -(XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE * ratio);
67 				case 21: return gamepad.sThumbRX < -(XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE * ratio);
68 				case 22: return gamepad.sThumbRX > (XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE * ratio);
69 				case 23: return gamepad.sThumbLY > (XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE * ratio);
70 				case 24: return gamepad.sThumbLY < -(XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE * ratio);
71 				case 25: return gamepad.sThumbLX < -(XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE * ratio);
72 				case 26: return gamepad.sThumbLX > (XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE * ratio);
73 			}
74 		}
75 	}
76 	return false;
77 }
78