[Snippet] C++ Xinput 360Controller example

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;
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值