Skip to content

Commit

Permalink
Emulate XInputEnable behavior when using XInput 9.1.0
Browse files Browse the repository at this point in the history
  • Loading branch information
walbourn_cp authored and walbourn_cp committed Jan 27, 2015
1 parent 48cf6ab commit b6effa6
Showing 1 changed file with 79 additions and 9 deletions.
88 changes: 79 additions & 9 deletions Src/GamePad.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -504,12 +504,15 @@ class GamePad::Impl
public:
Impl()
{
for( size_t j = 0; j < XUSER_MAX_COUNT; ++j )
for( int j = 0; j < XUSER_MAX_COUNT; ++j )
{
mConnected[ j ] = false;
mLastReadTime[ j ] = 0;
ClearSlot( j, 0 );
}

#if (_WIN32_WINNT < _WIN32_WINNT_WIN8)
mSuspended = false;
#endif

if ( s_gamePad )
{
throw std::exception( "GamePad is a singleton" );
Expand All @@ -527,12 +530,20 @@ class GamePad::Impl
{
if ( !ThrottleRetry(player) )
{
#if (_WIN32_WINNT < _WIN32_WINNT_WIN8)
if ( mSuspended )
{
memset( &state, 0, sizeof(State) );
state.connected = mConnected[ player ];
return;
}
#endif

XINPUT_STATE xstate;
DWORD result = XInputGetState( DWORD(player), &xstate );
if ( result == ERROR_DEVICE_NOT_CONNECTED )
{
mConnected[ player ] = false;
mLastReadTime[ player ] = GetTickCount64();
ClearSlot( player, GetTickCount64() );
}
else
{
Expand Down Expand Up @@ -592,8 +603,7 @@ class GamePad::Impl
DWORD result = XInputGetCapabilities( DWORD(player), 0, &xcaps );
if ( result == ERROR_DEVICE_NOT_CONNECTED )
{
mConnected[ player ] = false;
mLastReadTime[ player ] = GetTickCount64();
ClearSlot( player, GetTickCount64() );
}
else
{
Expand Down Expand Up @@ -638,14 +648,21 @@ class GamePad::Impl
UNREFERENCED_PARAMETER(leftTrigger);
UNREFERENCED_PARAMETER(rightTrigger);

#if (_WIN32_WINNT < _WIN32_WINNT_WIN8)
mLeftMotor[ player ] = leftMotor;
mRightMotor[ player ] = rightMotor;

if ( mSuspended )
return mConnected[ player ];
#endif

XINPUT_VIBRATION xvibration;
xvibration.wLeftMotorSpeed = WORD( leftMotor * 0xFFFF );
xvibration.wRightMotorSpeed = WORD( rightMotor * 0xFFFF );
DWORD result = XInputSetState( DWORD(player), &xvibration );
if ( result == ERROR_DEVICE_NOT_CONNECTED )
{
mConnected[ player ] = false;
mLastReadTime[ player ] = GetTickCount64();
ClearSlot( player, GetTickCount64() );
return false;
}
else
Expand All @@ -659,20 +676,64 @@ class GamePad::Impl
{
#if (_WIN32_WINNT >= _WIN32_WINNT_WIN8)
XInputEnable( FALSE );
#else
// For XInput 9.1.0, we have to emulate the behavior of XInputEnable( FALSE )
if ( !mSuspended )
{
for( size_t j = 0; j < XUSER_MAX_COUNT; ++j )
{
if ( mConnected[ j ] )
{
XINPUT_VIBRATION xvibration;
xvibration.wLeftMotorSpeed = xvibration.wRightMotorSpeed = 0;
(void)XInputSetState( DWORD(j), &xvibration );
}
}

mSuspended = true;
}
#endif
}

void Resume()
{
#if (_WIN32_WINNT >= _WIN32_WINNT_WIN8)
XInputEnable( TRUE );
#else
// For XInput 9.1.0, we have to emulate the behavior of XInputEnable( TRUE )
if ( mSuspended )
{
for( int j = 0; j < XUSER_MAX_COUNT; ++j )
{
if ( mConnected[ j ] )
{
XINPUT_VIBRATION xvibration;
xvibration.wLeftMotorSpeed = WORD( mLeftMotor[ j ] * 0xFFFF );
xvibration.wRightMotorSpeed = WORD( mRightMotor[ j ] * 0xFFFF );
DWORD result = XInputSetState( DWORD(j), &xvibration );
if ( result == ERROR_DEVICE_NOT_CONNECTED )
{
ClearSlot( j, GetTickCount64() );
}
}
}

mSuspended = false;
}
#endif
}

private:
bool mConnected[ XUSER_MAX_COUNT ];
ULONGLONG mLastReadTime[ XUSER_MAX_COUNT ];

#if (_WIN32_WINNT < _WIN32_WINNT_WIN8)
// Variables for emulating XInputEnable on XInput 9.1.0
float mLeftMotor[ XUSER_MAX_COUNT ];
float mRightMotor[ XUSER_MAX_COUNT ];
bool mSuspended;
#endif

static GamePad::Impl* s_gamePad;

bool ThrottleRetry( int player )
Expand Down Expand Up @@ -706,6 +767,15 @@ class GamePad::Impl

return false;
}

void ClearSlot( int player, ULONGLONG time )
{
mConnected[ player ] = false;
mLastReadTime[ player ] = time;
#if (_WIN32_WINNT < _WIN32_WINNT_WIN8)
mLeftMotor[ player ] = mRightMotor[ player ] = 0.f;
#endif
}
};

GamePad::Impl* GamePad::Impl::s_gamePad = nullptr;
Expand Down

0 comments on commit b6effa6

Please sign in to comment.