vcruntime.h和XInput.h(GNU GCC)

时间:2018-02-02 18:54:56

标签: c++ codeblocks

几个星期以来,我一直对制作一个显示XBOX控制器输入的程序感兴趣,而且我一直有很多问题。我正在使用Code :: Blocks,而XInput.h有SAL注释,我已经读过GNU GCC编译器,不知何故不熟悉。我坚持用Code :: Blcoks编码,所以我决定链接Visual Studio中的包含文件(我已经读过这将解决一些与SAL相关的问题)。现在我有了新的问题。我使用的代码来自https://lcmccauley.wordpress.com/2014/01/05/gamepad-input-tutorial/的教程,由于我也包含了新文件夹,我在第81行的vcruntime.h中遇到了错误。另一个错误是winnt.h,第2444行。我现在完全没有想法。

P.S:请不要因为没有注意到一些明显的解决方案而杀了我。我还是个初学者。谢谢!

以下代码:

main.cpp中:

//------------------------------------------------------------
// C++ Xbox 360 gamepad Input using XInput
// Demo code by Lawrence M
//------------------------------------------------------------
// This is a demo program to demonstrate the 'Gamepad' class
// (based on the code from my 3-part tutorial).
//
// All code in this program (including 'Gamepad' class) was
// written and tested on a Windows 7 PC using Visual Studio
// 2013. A Microsoft (USB wired) Xbox 360 controller was used
// to test the gamepad code.
//------------------------------------------------------------
//#include <no_sal.h>
#include <iostream>


#include "Gamepad.h"

using namespace std;

bool running;    // Used to break the loop
Gamepad gamepad; // Gamepad instance

// This example checks input on all gamepad buttons (Guide/logo
// button not supported). For example code on using the triggers
// and thumbsticks, please refer to the tutorial.
void TestGamepad()
{
    // GetButtonDown only returns true on the frame it was first pressed.
    if (gamepad.GetButtonDown(xButtons.A))
    {
        cout << " Button [A] pressed" << endl;
    }

    if (gamepad.GetButtonDown(xButtons.X))
    {
        cout << " Button [X] pressed" << endl;
    }

    // GetButtonPressed will keep returning true until the button is released.
    if (gamepad.GetButtonPressed(xButtons.Y))
    {
        cout << " Button [Y] held, see how this doesn't appear just once?" << endl;
    }

    // Check the D-Pad buttons
    if (gamepad.GetButtonDown(xButtons.DPad_Up))
    {
        cout << " Button [DPad Up] pressed" << endl;
    }

    if (gamepad.GetButtonDown(xButtons.DPad_Down))
    {
        cout << " Button [DPad Down] pressed" << endl;
    }

    if (gamepad.GetButtonDown(xButtons.DPad_Left))
    {
        cout << " Button [DPad Left] pressed" << endl;
    }

    if (gamepad.GetButtonDown(xButtons.DPad_Right))
    {
        cout << " Button [DPad Right] pressed" << endl;
    }

    // Check the Shoulder ('bumper') buttons
    if (gamepad.GetButtonDown(xButtons.L_Shoulder))
    {
        cout << " Button [L Bumper] pressed" << endl;
    }

    if (gamepad.GetButtonDown(xButtons.R_Shoulder))
    {
        cout << " Button [R Bumper] pressed" << endl;
    }

    // Check the BACK and START buttons
    if (gamepad.GetButtonDown(xButtons.Back))
    {
        cout << " Button [BACK] pressed" << endl;
    }

    if (gamepad.GetButtonDown(xButtons.Start))
    {
        cout << " Button [START] pressed" << endl;
    }

    // Check the Thumbstick buttons (press in the thumbstick)
    if (gamepad.GetButtonDown(xButtons.L_Thumbstick))
    {
        cout << " Button [L STICK] pressed" << endl;
    }

    if (gamepad.GetButtonDown(xButtons.R_Thumbstick))
    {
        cout << " Button [R STICK] pressed" << endl;
    }
}

int main()
{
    // Set up
    running = true;
    gamepad = Gamepad(1); // Set gamepad ID to 1

    cout << " --------------------------------------------" << endl;
    cout << "          Xbox 360 Gamepad INPUT TEST        " << endl;
    cout << " --------------------------------------------" << endl << endl;

    cout << " Use gamepad buttons to test gamepad input." << endl;
    cout << " To quit, press the [B] button." << endl;
    cout << " --------------------------------------------" << endl << endl;

    // Pretend game loop, repeat until 'B' is pressed
    do
    {
        gamepad.Update(); // Update gamepad

        if (gamepad.Connected())
        {
            // Run gamepad input test
            TestGamepad();

            // Pressing B quits the program
            if (gamepad.GetButtonPressed(xButtons.B))
                running = false;
        }

        gamepad.Refresh(); // Update gamepad for next cycle
    }
    while (running);

    return 0;
}

Gamepad.cpp:

//------------------------------------------------------------
// C++ Xbox 360 gamepad Input using XInput
// Demo code by Lawrence M
//------------------------------------------------------------
// This code is based off my tutorial but I have dropped the
// notation style used in the tutorial to make the code easier
// to read.
//
// Some function and variable names may have changed. For
// more details on the Gamepad class and its features, please
// refer to the tutorial.
//------------------------------------------------------------

#include <no_sal.h>
#include "Gamepad.h"

// Link the 'XInput' library
// Note: For Visual Studio 2012 and above, XInput9_1_0 is the library
//       required to make XInput work.
#pragma comment(lib, "XInput.lib")

// Define the 'XInput_ButtonIDs' struct as 'xButtons'
XInput_ButtonIDs xButtons;

// XInput_ButtonIDs struct
//------------------------------------------------------------

// Set buttton values in constructor
XInput_ButtonIDs::XInput_ButtonIDs()
{
    A = 0;
    B = 1;
    X = 2;
    Y = 3;

    DPad_Up    = 4;
    DPad_Down  = 5;
    DPad_Left  = 6;
    DPad_Right = 7;

    L_Shoulder = 8;
    R_Shoulder = 9;

    L_Thumbstick = 10;
    R_Thumbstick = 11;

    Start = 12;
    Back  = 13;
}

// Gamepad class
//------------------------------------------------------------

// Constructor
Gamepad::Gamepad()
{

}

// Constructor - set pad ID
Gamepad::Gamepad(int id)
{
    pad_id = id - 1;

    for (int i = 0; i < button_count; i++)
    {
        prev_buttonStates[i] = false;
        buttonStates[i]      = false;
    }
}

// Update gamepad state
void Gamepad::Update()
{
    // Get current gamepad state
    state = GetState();

    for (int i = 0; i < button_count; i++)
    {
        // Set button state on current frame
        buttonStates[i] = (state.Gamepad.wButtons & XINPUT_Buttons[i]) == XINPUT_Buttons[i];
    }
}

// Update gamepad state for next cycle
void Gamepad::Refresh()
{
    memcpy(prev_buttonStates, buttonStates, sizeof(prev_buttonStates));
}

// Set gamepad vibration ('rumble')
void Gamepad::SetRumble(float left, float right)
{
    // XInput vibration state
    XINPUT_VIBRATION rumble;

    // Zero memory on vibration state
    ZeroMemory(&rumble, sizeof(XINPUT_VIBRATION));

    // Calculate vibration intensity
    int left_motor  = int(left * 65535.0f);
    int right_motor = int(right * 65535.0f);

    rumble.wLeftMotorSpeed  = left_motor;
    rumble.wRightMotorSpeed = right_motor;

    // Apply vibration
    XInputSetState(pad_id, &rumble);
}

// Return gamepad number
int Gamepad::GetID()
{
    return pad_id;
}

// Check if gamepad is connected
bool Gamepad::Connected()
{
    // Zero memory
    ZeroMemory(&state, sizeof(XINPUT_STATE));

    DWORD result = XInputGetState(pad_id, &state);

    if (result == ERROR_SUCCESS)
        return true;  // Connected
    else
        return false; // Not connected
}

// Check if specified button is pressed
bool Gamepad::GetButtonPressed(int button)
{
    if (state.Gamepad.wButtons & XINPUT_Buttons[button])
    {
        // Button is pressed
        return true;
    }

    return false; // Button is not pressed
}

// Check if specified button is pressed - CURRENT frame only!
bool Gamepad::GetButtonDown(int button)
{
    return !prev_buttonStates[button] && buttonStates[button];
}

// Check deadzone on left thumbstick
bool Gamepad::LStick_InDeadzone()
{
    short x = state.Gamepad.sThumbLX;
    short y = state.Gamepad.sThumbLY;

    if (x > XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE ||
        x < -XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE)
    {
        // X axis outside of deadzone
        return false;
    }

    if (y > XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE ||
        y < -XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE)
    {
        // Y axis outside of deadzone
        return false;
    }

    // One (or both) axis inside deadzone
    return true;
}

// Check deadzone on right thumbstick
bool Gamepad::RStick_InDeadzone()
{
    short x = state.Gamepad.sThumbRX;
    short y = state.Gamepad.sThumbRY;

    if (x > XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE ||
        x < -XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE)
    {
        // X axis outside of deadzone
        return false;
    }

    if (y > XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE ||
        y < -XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE)
    {
        // Y axis outside of deadzone
        return false;
    }

    // One (or both) axis inside deadzone
    return true;
}

// Return X axis of left thumbstick
float Gamepad::LeftStick_X()
{
    short x = state.Gamepad.sThumbLX;

    // Return value as a float
    return (static_cast<float>(x) / 32768.0f);
}

// Return Y axis of left thumbstick
float Gamepad::LeftStick_Y()
{
    short y = state.Gamepad.sThumbLY;

    // Return value as a float
    return (static_cast<float>(y) / 32768.0f);
}

// Return X axis of right thumbstick
float Gamepad::RightStick_X()
{
    short x = state.Gamepad.sThumbRX;

    // Return value as a float
    return (static_cast<float>(x) / 32768.0f);
}

// Return Y axis of right thumbstick
float Gamepad::RightStick_Y()
{
    short y = state.Gamepad.sThumbRY;

    // Return value as a float
    return (static_cast<float>(y) / 32768.0f);
}

// Return value of left trigger
float Gamepad::LeftTrigger()
{
    BYTE axis = state.Gamepad.bLeftTrigger;

    if (axis > XINPUT_GAMEPAD_TRIGGER_THRESHOLD)
        return axis / 255.0f;

    return 0.0f; // Trigger was not pressed
}

// Return value of right trigger
float Gamepad::RightTrigger()
{
    BYTE axis = state.Gamepad.bRightTrigger;

    if (axis > XINPUT_GAMEPAD_TRIGGER_THRESHOLD)
        return axis / 255.0f;

    return 0.0f; // Trigger was not pressed
}

// Return gamepad state
XINPUT_STATE Gamepad::GetState()
{
    XINPUT_STATE new_state;

    // Zero memory on state
    ZeroMemory(&state, sizeof(XINPUT_STATE));

    // Get new state from XInput
    XInputGetState(pad_id, &new_state);

    return new_state;
}

Gamepad.h

//------------------------------------------------------------
// C++ Xbox 360 gamepad Input using XInput
// Demo code by Lawrence M
//------------------------------------------------------------
// This code is based off my tutorial but I have dropped the
// notation style used in the tutorial to make the code easier
// to read.
//
// Some function and variable names may have changed. For
// more details on the Gamepad class and its features, please
// refer to the tutorial.
//------------------------------------------------------------

#include <no_sal.h>
#include "Gamepad.h"

// Link the 'XInput' library
// Note: For Visual Studio 2012 and above, XInput9_1_0 is the library
//       required to make XInput work.
#pragma comment(lib, "XInput.lib")

// Define the 'XInput_ButtonIDs' struct as 'xButtons'
XInput_ButtonIDs xButtons;

// XInput_ButtonIDs struct
//------------------------------------------------------------

// Set buttton values in constructor
XInput_ButtonIDs::XInput_ButtonIDs()
{
    A = 0;
    B = 1;
    X = 2;
    Y = 3;

    DPad_Up    = 4;
    DPad_Down  = 5;
    DPad_Left  = 6;
    DPad_Right = 7;

    L_Shoulder = 8;
    R_Shoulder = 9;

    L_Thumbstick = 10;
    R_Thumbstick = 11;

    Start = 12;
    Back  = 13;
}

// Gamepad class
//------------------------------------------------------------

// Constructor
Gamepad::Gamepad()
{

}

// Constructor - set pad ID
Gamepad::Gamepad(int id)
{
    pad_id = id - 1;

    for (int i = 0; i < button_count; i++)
    {
        prev_buttonStates[i] = false;
        buttonStates[i]      = false;
    }
}

// Update gamepad state
void Gamepad::Update()
{
    // Get current gamepad state
    state = GetState();

    for (int i = 0; i < button_count; i++)
    {
        // Set button state on current frame
        buttonStates[i] = (state.Gamepad.wButtons & XINPUT_Buttons[i]) == XINPUT_Buttons[i];
    }
}

// Update gamepad state for next cycle
void Gamepad::Refresh()
{
    memcpy(prev_buttonStates, buttonStates, sizeof(prev_buttonStates));
}

// Set gamepad vibration ('rumble')
void Gamepad::SetRumble(float left, float right)
{
    // XInput vibration state
    XINPUT_VIBRATION rumble;

    // Zero memory on vibration state
    ZeroMemory(&rumble, sizeof(XINPUT_VIBRATION));

    // Calculate vibration intensity
    int left_motor  = int(left * 65535.0f);
    int right_motor = int(right * 65535.0f);

    rumble.wLeftMotorSpeed  = left_motor;
    rumble.wRightMotorSpeed = right_motor;

    // Apply vibration
    XInputSetState(pad_id, &rumble);
}

// Return gamepad number
int Gamepad::GetID()
{
    return pad_id;
}

// Check if gamepad is connected
bool Gamepad::Connected()
{
    // Zero memory
    ZeroMemory(&state, sizeof(XINPUT_STATE));

    DWORD result = XInputGetState(pad_id, &state);

    if (result == ERROR_SUCCESS)
        return true;  // Connected
    else
        return false; // Not connected
}

// Check if specified button is pressed
bool Gamepad::GetButtonPressed(int button)
{
    if (state.Gamepad.wButtons & XINPUT_Buttons[button])
    {
        // Button is pressed
        return true;
    }

    return false; // Button is not pressed
}

// Check if specified button is pressed - CURRENT frame only!
bool Gamepad::GetButtonDown(int button)
{
    return !prev_buttonStates[button] && buttonStates[button];
}

// Check deadzone on left thumbstick
bool Gamepad::LStick_InDeadzone()
{
    short x = state.Gamepad.sThumbLX;
    short y = state.Gamepad.sThumbLY;

    if (x > XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE ||
        x < -XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE)
    {
        // X axis outside of deadzone
        return false;
    }

    if (y > XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE ||
        y < -XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE)
    {
        // Y axis outside of deadzone
        return false;
    }

    // One (or both) axis inside deadzone
    return true;
}

// Check deadzone on right thumbstick
bool Gamepad::RStick_InDeadzone()
{
    short x = state.Gamepad.sThumbRX;
    short y = state.Gamepad.sThumbRY;

    if (x > XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE ||
        x < -XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE)
    {
        // X axis outside of deadzone
        return false;
    }

    if (y > XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE ||
        y < -XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE)
    {
        // Y axis outside of deadzone
        return false;
    }

    // One (or both) axis inside deadzone
    return true;
}

// Return X axis of left thumbstick
float Gamepad::LeftStick_X()
{
    short x = state.Gamepad.sThumbLX;

    // Return value as a float
    return (static_cast<float>(x) / 32768.0f);
}

// Return Y axis of left thumbstick
float Gamepad::LeftStick_Y()
{
    short y = state.Gamepad.sThumbLY;

    // Return value as a float
    return (static_cast<float>(y) / 32768.0f);
}

// Return X axis of right thumbstick
float Gamepad::RightStick_X()
{
    short x = state.Gamepad.sThumbRX;

    // Return value as a float
    return (static_cast<float>(x) / 32768.0f);
}

// Return Y axis of right thumbstick
float Gamepad::RightStick_Y()
{
    short y = state.Gamepad.sThumbRY;

    // Return value as a float
    return (static_cast<float>(y) / 32768.0f);
}

// Return value of left trigger
float Gamepad::LeftTrigger()
{
    BYTE axis = state.Gamepad.bLeftTrigger;

    if (axis > XINPUT_GAMEPAD_TRIGGER_THRESHOLD)
        return axis / 255.0f;

    return 0.0f; // Trigger was not pressed
}

// Return value of right trigger
float Gamepad::RightTrigger()
{
    BYTE axis = state.Gamepad.bRightTrigger;

    if (axis > XINPUT_GAMEPAD_TRIGGER_THRESHOLD)
        return axis / 255.0f;

    return 0.0f; // Trigger was not pressed
}

// Return gamepad state
XINPUT_STATE Gamepad::GetState()
{
    XINPUT_STATE new_state;

    // Zero memory on state
    ZeroMemory(&state, sizeof(XINPUT_STATE));

    // Get new state from XInput
    XInputGetState(pad_id, &new_state);

    return new_state;
}

0 个答案:

没有答案