Input: Fixed bug with gamepad buttons sometimes detected as unpressed when pressed (multithread bug)
This commit is contained in:
parent
5cd5c292b6
commit
c14f046990
4 changed files with 21 additions and 19 deletions
|
@ -354,12 +354,11 @@ bool DirectInputManager::IsPressed(int port, int button)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DirectInputManager::UpdateInputState(DirectInputData &data)
|
void DirectInputManager::UpdateInputState(DirectInputData &data)
|
||||||
{
|
{
|
||||||
|
DIJOYSTATE2 newState;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
|
||||||
data.stateValid = false;
|
|
||||||
|
|
||||||
// Poll the device to read the current state
|
// Poll the device to read the current state
|
||||||
hr = data.joystick->Poll();
|
hr = data.joystick->Poll();
|
||||||
if(FAILED(hr)) {
|
if(FAILED(hr)) {
|
||||||
|
@ -373,18 +372,19 @@ bool DirectInputManager::UpdateInputState(DirectInputData &data)
|
||||||
// hr may be DIERR_OTHERAPPHASPRIO or other errors. This may occur when the app is minimized or in the process of
|
// hr may be DIERR_OTHERAPPHASPRIO or other errors. This may occur when the app is minimized or in the process of
|
||||||
// switching, so just try again later
|
// switching, so just try again later
|
||||||
if(FAILED(hr)) {
|
if(FAILED(hr)) {
|
||||||
return true;
|
data.stateValid = false;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the input's device state
|
// Get the input's device state
|
||||||
if(FAILED(hr = data.joystick->GetDeviceState(sizeof(DIJOYSTATE2), &data.state))) {
|
if(FAILED(hr = data.joystick->GetDeviceState(sizeof(DIJOYSTATE2), &newState))) {
|
||||||
return false; // The device should have been acquired during the Poll()
|
data.stateValid = false;
|
||||||
|
return; // The device should have been acquired during the Poll()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
data.state = newState;
|
||||||
data.stateValid = true;
|
data.stateValid = true;
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,7 @@ private:
|
||||||
static std::vector<GUID> _directInputDeviceGuids;
|
static std::vector<GUID> _directInputDeviceGuids;
|
||||||
|
|
||||||
bool Initialize();
|
bool Initialize();
|
||||||
bool UpdateInputState(DirectInputData& joystick);
|
void UpdateInputState(DirectInputData& joystick);
|
||||||
static bool ProcessDevice(const DIDEVICEINSTANCE* pdidInstance, bool checkOnly);
|
static bool ProcessDevice(const DIDEVICEINSTANCE* pdidInstance, bool checkOnly);
|
||||||
static bool IsXInputDevice(const GUID* pGuidProductFromDirectInput);
|
static bool IsXInputDevice(const GUID* pGuidProductFromDirectInput);
|
||||||
static int __stdcall NeedToUpdateCallback(const DIDEVICEINSTANCE* pdidInstance, void* pContext);
|
static int __stdcall NeedToUpdateCallback(const DIDEVICEINSTANCE* pdidInstance, void* pContext);
|
||||||
|
|
|
@ -5,17 +5,21 @@ XInputManager::XInputManager()
|
||||||
{
|
{
|
||||||
for(int i = 0; i < XUSER_MAX_COUNT; i++) {
|
for(int i = 0; i < XUSER_MAX_COUNT; i++) {
|
||||||
_gamePadStates.push_back(shared_ptr<XINPUT_STATE>(new XINPUT_STATE()));
|
_gamePadStates.push_back(shared_ptr<XINPUT_STATE>(new XINPUT_STATE()));
|
||||||
|
_gamePadConnected.push_back(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void XInputManager::RefreshState()
|
void XInputManager::RefreshState()
|
||||||
{
|
{
|
||||||
|
XINPUT_STATE state;
|
||||||
for(DWORD i = 0; i < XUSER_MAX_COUNT; i++) {
|
for(DWORD i = 0; i < XUSER_MAX_COUNT; i++) {
|
||||||
if(_gamePadStates[i] != nullptr) {
|
if(_gamePadConnected[i]) {
|
||||||
ZeroMemory(_gamePadStates[i].get(), sizeof(XINPUT_STATE));
|
if(XInputGetState(i, &state) != ERROR_SUCCESS) {
|
||||||
if(XInputGetState(i, _gamePadStates[i].get()) != ERROR_SUCCESS) {
|
|
||||||
//XInputGetState is incredibly slow when no controller is plugged in
|
//XInputGetState is incredibly slow when no controller is plugged in
|
||||||
_gamePadStates[i] = nullptr;
|
ZeroMemory(_gamePadStates[i].get(), sizeof(XINPUT_STATE));
|
||||||
|
_gamePadConnected[i] = false;
|
||||||
|
} else {
|
||||||
|
*_gamePadStates[i] = state;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,9 +27,8 @@ void XInputManager::RefreshState()
|
||||||
|
|
||||||
bool XInputManager::NeedToUpdate()
|
bool XInputManager::NeedToUpdate()
|
||||||
{
|
{
|
||||||
bool needToUpdate = false;
|
|
||||||
for(int i = 0; i < XUSER_MAX_COUNT; i++) {
|
for(int i = 0; i < XUSER_MAX_COUNT; i++) {
|
||||||
if(_gamePadStates[i] == nullptr) {
|
if(!_gamePadConnected[i]) {
|
||||||
XINPUT_STATE state;
|
XINPUT_STATE state;
|
||||||
if(XInputGetState(i, &state) == ERROR_SUCCESS) {
|
if(XInputGetState(i, &state) == ERROR_SUCCESS) {
|
||||||
return true;
|
return true;
|
||||||
|
@ -39,15 +42,13 @@ void XInputManager::UpdateDeviceList()
|
||||||
{
|
{
|
||||||
//Periodically detect if a controller has been plugged in to allow controllers to be plugged in after the emu is started
|
//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++) {
|
for(int i = 0; i < XUSER_MAX_COUNT; i++) {
|
||||||
if(_gamePadStates[i] == nullptr) {
|
_gamePadConnected[i] = true;
|
||||||
_gamePadStates[i] = shared_ptr<XINPUT_STATE>(new XINPUT_STATE());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool XInputManager::IsPressed(uint8_t gamepadPort, uint8_t button)
|
bool XInputManager::IsPressed(uint8_t gamepadPort, uint8_t button)
|
||||||
{
|
{
|
||||||
if(_gamePadStates[gamepadPort] != nullptr) {
|
if(_gamePadConnected[gamepadPort]) {
|
||||||
XINPUT_GAMEPAD &gamepad = _gamePadStates[gamepadPort]->Gamepad;
|
XINPUT_GAMEPAD &gamepad = _gamePadStates[gamepadPort]->Gamepad;
|
||||||
if(button <= 16) {
|
if(button <= 16) {
|
||||||
WORD xinputButton = 1 << (button - 1);
|
WORD xinputButton = 1 << (button - 1);
|
||||||
|
|
|
@ -7,6 +7,7 @@ class XInputManager
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
vector<shared_ptr<XINPUT_STATE>> _gamePadStates;
|
vector<shared_ptr<XINPUT_STATE>> _gamePadStates;
|
||||||
|
vector<uint8_t> _gamePadConnected;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
XInputManager();
|
XInputManager();
|
||||||
|
|
Loading…
Add table
Reference in a new issue