source: https://katyscode.wordpress.com/2013/08/30/xinput-tutorial-part-1-adding-gamepad-support-to-your-windows-game/
#include <iostream>
#include <Windows.h>
#include <Xinput.h>
//#pragma comment(lib, "XInput.lib")
//either this or if you are using VS : Linker - Input - AdditionalDependencies add XInput.lib
/*
> include Xinput9_1_0.lib as a linker input (if you want to link against XInput 1.3/1.4, use XInput.lib as the linker input).
>
> XInput 1.4: XInput 1.4 ships as part of Windows 10. Use this
> version for building UWP apps. XInput 9.1.0: XInput 9.1.0 ships as
> part of Windows Vista, Windows 7, and Windows 8. Use this version if
> your desktop app is intended to run on these versions of Windows and
> you are using basic XInput functionality. XInput 1.3: XInput 1.3 ships
> as a redistributable component in the DirectX SDK with support for
> Windows Vista, Windows 7, and Windows 8. Use this version if your
> desktop app is intended to run on these versions of Windows and you
> need functionality that is not supported by XInput 9.1.0.
>
*/
using std::cout;
using std::endl;
/* Insert the Gamepad class code here */
class Gamepad
{
private:
int cId;
XINPUT_STATE state;
float deadzoneX;
float deadzoneY;
public:
Gamepad() : deadzoneX(0.05f), deadzoneY(0.02f) {}
Gamepad(float dzX, float dzY) : deadzoneX(dzX), deadzoneY(dzY) {}
float leftStickX;
float leftStickY;
float rightStickX;
float rightStickY;
float leftTrigger;
float rightTrigger;
int GetPort();
XINPUT_GAMEPAD* GetState();
bool CheckConnection();
bool Refresh();
bool IsPressed(WORD);
};
int Gamepad::GetPort()
{
return cId + 1;
}
XINPUT_GAMEPAD* Gamepad::GetState()
{
return &state.Gamepad;
}
bool Gamepad::CheckConnection()
{
int controllerId = -1;
for (DWORD i = 0; i < XUSER_MAX_COUNT && controllerId == -1; i++)
{
XINPUT_STATE state;
ZeroMemory(&state, sizeof(XINPUT_STATE));
if (XInputGetState(i, &state) == ERROR_SUCCESS)
controllerId = i;
}
cId = controllerId;
return controllerId != -1;
}
// Returns false if the controller has been disconnected
bool Gamepad::Refresh()
{
if (cId == -1)
CheckConnection();
if (cId != -1)
{
ZeroMemory(&state, sizeof(XINPUT_STATE));
if (XInputGetState(cId, &state) != ERROR_SUCCESS)
{
cId = -1;
return false;
}
float normLX = fmaxf(-1, (float)state.Gamepad.sThumbLX / 32767);
float normLY = fmaxf(-1, (float)state.Gamepad.sThumbLY / 32767);
leftStickX = (abs(normLX) < deadzoneX ? 0 : (abs(normLX) - deadzoneX) * (normLX / abs(normLX)));
leftStickY = (abs(normLY) < deadzoneY ? 0 : (abs(normLY) - deadzoneY) * (normLY / abs(normLY)));
if (deadzoneX > 0) leftStickX *= 1 / (1 - deadzoneX);
if (deadzoneY > 0) leftStickY *= 1 / (1 - deadzoneY);
float normRX = fmaxf(-1, (float)state.Gamepad.sThumbRX / 32767);
float normRY = fmaxf(-1, (float)state.Gamepad.sThumbRY / 32767);
rightStickX = (abs(normRX) < deadzoneX ? 0 : (abs(normRX) - deadzoneX) * (normRX / abs(normRX)));
rightStickY = (abs(normRY) < deadzoneY ? 0 : (abs(normRY) - deadzoneY) * (normRY / abs(normRY)));
if (deadzoneX > 0) rightStickX *= 1 / (1 - deadzoneX);
if (deadzoneY > 0) rightStickY *= 1 / (1 - deadzoneY);
leftTrigger = (float)state.Gamepad.bLeftTrigger / 255;
rightTrigger = (float)state.Gamepad.bRightTrigger / 255;
return true;
}
return false;
}
bool Gamepad::IsPressed(WORD button)
{
return (state.Gamepad.wButtons & button) != 0;
}
//
int main()
{
Gamepad gamepad;
bool wasConnected = true;
while (true)
{
//Sleep(100);
if (!gamepad.Refresh())
{
if (wasConnected)
{
wasConnected = false;
cout << "Please connect an Xbox 360 controller." << endl;
}
}
else
{
if (!wasConnected)
{
wasConnected = true;
cout << "Controller connected on port " << gamepad.GetPort() << endl;
}
cout << "Left thumb stick: (" << gamepad.leftStickX << ", " << gamepad.leftStickY << ") Right thumb stick : (" << gamepad.rightStickX << ", " << gamepad.rightStickY << ")" << endl;
cout << "Left analog trigger: " << gamepad.leftTrigger << " Right analog trigger: " << gamepad.rightTrigger << endl;
if (gamepad.IsPressed(XINPUT_GAMEPAD_A)) cout << "(A) button pressed" << endl;
}
}
}