2024-04-17 20:21:17 -03:00
|
|
|
#ifndef XNA_INPUT_GAMEPAD_HPP
|
|
|
|
#define XNA_INPUT_GAMEPAD_HPP
|
|
|
|
|
|
|
|
#include "../default.hpp"
|
2024-05-18 16:22:00 -03:00
|
|
|
#include "../common/numerics.hpp"
|
2024-04-17 20:21:17 -03:00
|
|
|
|
|
|
|
namespace xna {
|
2024-06-22 16:24:11 -03:00
|
|
|
//Structure that defines the position of the left and right triggers on an Xbox Controller.
|
2024-05-21 09:40:59 -03:00
|
|
|
struct GamePadTriggers {
|
|
|
|
constexpr GamePadTriggers() = default;
|
|
|
|
|
|
|
|
constexpr GamePadTriggers(float left, float right) : _left(left), _right(right) {
|
|
|
|
clamp();
|
|
|
|
}
|
|
|
|
|
|
|
|
constexpr float Left() const {
|
|
|
|
return _left;
|
|
|
|
}
|
|
|
|
|
|
|
|
constexpr float Right() const {
|
|
|
|
return _right;
|
|
|
|
}
|
|
|
|
|
|
|
|
constexpr bool operator==(const GamePadTriggers& other) const {
|
|
|
|
return _left == other._left && _right == other._right;
|
|
|
|
}
|
|
|
|
|
2024-04-17 20:21:17 -03:00
|
|
|
public:
|
2024-05-21 09:40:59 -03:00
|
|
|
float _left{ 0 };
|
|
|
|
float _right{ 0 };
|
|
|
|
|
|
|
|
private:
|
|
|
|
void constexpr clamp() {
|
|
|
|
_left = _left < 1.0F ? _left : 1.0F;
|
|
|
|
_left = _left > 0.0F ? _left : 0.0F;
|
|
|
|
_right = _right < 1.0F ? _right : 1.0F;
|
|
|
|
_right = _right > 0.0F ? _right : 0.0F;
|
|
|
|
}
|
2024-04-17 20:21:17 -03:00
|
|
|
};
|
|
|
|
|
2024-06-22 16:24:11 -03:00
|
|
|
//Structure that represents the position of left and right sticks (thumbsticks) on an Xbox Controller.
|
2024-05-21 09:40:59 -03:00
|
|
|
struct GamePadThumbSticks {
|
|
|
|
constexpr GamePadThumbSticks() = default;
|
|
|
|
|
|
|
|
constexpr GamePadThumbSticks(Vector2 left, Vector2 right) : _left(left), _right(right) {
|
|
|
|
clamp();
|
|
|
|
}
|
|
|
|
|
|
|
|
constexpr Vector2 Left() const {
|
|
|
|
return _left;
|
|
|
|
}
|
|
|
|
|
|
|
|
constexpr Vector2 Right() const {
|
|
|
|
return _right;
|
|
|
|
}
|
|
|
|
|
|
|
|
constexpr bool operator==(const GamePadThumbSticks& other) const {
|
|
|
|
return _left == other._left && _right == other._right;
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
Vector2 _left{};
|
|
|
|
Vector2 _right{};
|
|
|
|
|
|
|
|
private:
|
|
|
|
constexpr void clamp() {
|
|
|
|
_left = Vector2::Min(_left, Vector2::One());
|
|
|
|
_left = Vector2::Max(_left, -Vector2::One());
|
|
|
|
_right = Vector2::Min(_right, Vector2::One());
|
|
|
|
_right = Vector2::Max(_right, -Vector2::One());
|
|
|
|
}
|
2024-04-17 20:21:17 -03:00
|
|
|
};
|
|
|
|
|
2024-06-22 16:24:11 -03:00
|
|
|
//Identifies which directions on the directional pad of an Xbox Controller are being pressed.
|
2024-05-21 09:40:59 -03:00
|
|
|
struct GamePadDPad {
|
|
|
|
constexpr GamePadDPad() = default;
|
|
|
|
|
|
|
|
constexpr GamePadDPad(const ButtonState& up, const ButtonState& down,
|
|
|
|
const ButtonState& left, const ButtonState& right)
|
|
|
|
: Up(up), Right(right), Down(down), Left(left) {
|
|
|
|
}
|
|
|
|
|
|
|
|
ButtonState Up{};
|
|
|
|
ButtonState Right{};
|
|
|
|
ButtonState Down{};
|
|
|
|
ButtonState Left{};
|
2024-04-17 20:21:17 -03:00
|
|
|
};
|
|
|
|
|
2024-06-22 16:24:11 -03:00
|
|
|
//Identifies whether buttons on an Xbox Controller are pressed or released.
|
2024-05-21 09:40:59 -03:00
|
|
|
struct GamePadButtons {
|
|
|
|
constexpr GamePadButtons() = default;
|
|
|
|
|
|
|
|
constexpr GamePadButtons(
|
|
|
|
ButtonState a,
|
|
|
|
ButtonState b,
|
|
|
|
ButtonState x,
|
|
|
|
ButtonState y,
|
|
|
|
ButtonState leftStick,
|
|
|
|
ButtonState rightStick,
|
|
|
|
ButtonState leftShoulder,
|
|
|
|
ButtonState rightShoulder,
|
|
|
|
ButtonState back,
|
|
|
|
ButtonState start,
|
|
|
|
ButtonState bigButton) {
|
|
|
|
A = a;
|
|
|
|
B = b;
|
|
|
|
X = x;
|
|
|
|
Y = y;
|
|
|
|
LeftStick = leftStick;
|
|
|
|
RightStick = rightStick;
|
|
|
|
LeftShoulder = leftShoulder;
|
|
|
|
RightShoulder = rightShoulder;
|
|
|
|
Back = back;
|
|
|
|
Start = start;
|
|
|
|
BigButton = bigButton;
|
|
|
|
}
|
|
|
|
|
|
|
|
constexpr GamePadButtons(Buttons buttons) {
|
|
|
|
A = static_cast<Buttons>((static_cast<int>(buttons) & static_cast<int>(Buttons::A))) == Buttons::A ? ButtonState::Pressed : ButtonState::Released;
|
|
|
|
B = static_cast<Buttons>((static_cast<int>(buttons) & static_cast<int>(Buttons::B))) == Buttons::B ? ButtonState::Pressed : ButtonState::Released;
|
|
|
|
X = static_cast<Buttons>((static_cast<int>(buttons) & static_cast<int>(Buttons::X))) == Buttons::X ? ButtonState::Pressed : ButtonState::Released;
|
|
|
|
Y = static_cast<Buttons>((static_cast<int>(buttons) & static_cast<int>(Buttons::Y))) == Buttons::Y ? ButtonState::Pressed : ButtonState::Released;
|
|
|
|
Start = static_cast<Buttons>((static_cast<int>(buttons) & static_cast<int>(Buttons::Start))) == Buttons::Start ? ButtonState::Pressed : ButtonState::Released;
|
|
|
|
Back = static_cast<Buttons>((static_cast<int>(buttons) & static_cast<int>(Buttons::Back))) == Buttons::Back ? ButtonState::Pressed : ButtonState::Released;
|
|
|
|
LeftStick = static_cast<Buttons>((static_cast<int>(buttons) & static_cast<int>(Buttons::LeftStick))) == Buttons::LeftStick ? ButtonState::Pressed : ButtonState::Released;
|
|
|
|
RightStick = static_cast<Buttons>((static_cast<int>(buttons) & static_cast<int>(Buttons::RightStick))) == Buttons::RightStick ? ButtonState::Pressed : ButtonState::Released;
|
|
|
|
LeftShoulder = static_cast<Buttons>((static_cast<int>(buttons) & static_cast<int>(Buttons::LeftShoulder))) == Buttons::LeftShoulder ? ButtonState::Pressed : ButtonState::Released;
|
|
|
|
RightShoulder = static_cast<Buttons>((static_cast<int>(buttons) & static_cast<int>(Buttons::RightShoulder))) == Buttons::RightShoulder ? ButtonState::Pressed : ButtonState::Released;
|
|
|
|
BigButton = static_cast<Buttons>((static_cast<int>(buttons) & static_cast<int>(Buttons::BigButton))) == Buttons::BigButton ? ButtonState::Pressed : ButtonState::Released;
|
|
|
|
}
|
|
|
|
|
|
|
|
ButtonState A{};
|
|
|
|
ButtonState B{};
|
|
|
|
ButtonState X{};
|
|
|
|
ButtonState Y{};
|
|
|
|
ButtonState LeftStick{};
|
|
|
|
ButtonState RightStick{};
|
|
|
|
ButtonState LeftShoulder{};
|
|
|
|
ButtonState RightShoulder{};
|
|
|
|
ButtonState Back{};
|
|
|
|
ButtonState Start{};
|
|
|
|
ButtonState BigButton{};
|
2024-04-17 20:21:17 -03:00
|
|
|
};
|
|
|
|
|
2024-05-21 09:40:59 -03:00
|
|
|
#ifdef USING_GAMEINPUT
|
|
|
|
using GamePadId = APP_LOCAL_DEVICE_ID;
|
|
|
|
#elif defined(USING_WINDOWS_GAMING_INPUT)
|
|
|
|
using GamePadId = std::wstring;
|
|
|
|
#else
|
|
|
|
using GamePadId = uint64_t;
|
|
|
|
#endif
|
2024-04-17 20:23:43 -03:00
|
|
|
|
2024-06-22 16:24:11 -03:00
|
|
|
//Describes the capabilities of an Xbox Controller, including controller type, and identifies if the controller supports voice.
|
2024-05-21 09:40:59 -03:00
|
|
|
struct GamePadCapabilities {
|
|
|
|
constexpr GamePadCapabilities() = default;
|
|
|
|
|
|
|
|
GamePadCapabilitiesType Type{};
|
|
|
|
bool Connected{ false };
|
|
|
|
Ushort Vid{ 0 };
|
|
|
|
Ushort Pid{ 0 };
|
2024-05-24 12:31:24 -03:00
|
|
|
GamePadId Id{};
|
2024-04-17 20:21:17 -03:00
|
|
|
};
|
|
|
|
|
2024-06-22 16:24:11 -03:00
|
|
|
//Represents specific information about the state of an Xbox Controller, including the current state of buttons and sticks.
|
2024-05-21 09:40:59 -03:00
|
|
|
struct GamePadState {
|
2024-05-21 14:20:37 -03:00
|
|
|
constexpr GamePadState() = default;
|
2024-05-21 09:40:59 -03:00
|
|
|
|
|
|
|
constexpr bool IsButtonDown(xna::Buttons button) const {
|
|
|
|
switch (button)
|
|
|
|
{
|
|
|
|
case xna::Buttons::A:
|
|
|
|
return this->Buttons.A == ButtonState::Pressed;
|
|
|
|
case xna::Buttons::B:
|
|
|
|
return this->Buttons.B == ButtonState::Pressed;
|
|
|
|
case xna::Buttons::X:
|
|
|
|
return this->Buttons.X == ButtonState::Pressed;
|
|
|
|
case xna::Buttons::Y:
|
|
|
|
return this->Buttons.Y == ButtonState::Pressed;
|
|
|
|
case xna::Buttons::Back:
|
|
|
|
return this->Buttons.Back == ButtonState::Pressed;
|
|
|
|
case xna::Buttons::Start:
|
|
|
|
return this->Buttons.Start == ButtonState::Pressed;
|
|
|
|
case xna::Buttons::DPadUp:
|
|
|
|
return this->Dpad.Up == ButtonState::Pressed;
|
|
|
|
case xna::Buttons::DPadDown:
|
|
|
|
return this->Dpad.Down == ButtonState::Pressed;
|
|
|
|
case xna::Buttons::DPadLeft:
|
|
|
|
return this->Dpad.Left == ButtonState::Pressed;
|
|
|
|
case xna::Buttons::DPadRight:
|
|
|
|
return this->Dpad.Right == ButtonState::Pressed;
|
|
|
|
case xna::Buttons::LeftShoulder:
|
|
|
|
return this->Buttons.LeftShoulder == ButtonState::Pressed;
|
|
|
|
case xna::Buttons::RightShoulder:
|
|
|
|
return this->Buttons.RightShoulder == ButtonState::Pressed;
|
|
|
|
case xna::Buttons::LeftStick:
|
|
|
|
return this->Buttons.LeftStick == ButtonState::Pressed;
|
|
|
|
case xna::Buttons::RightStick:
|
|
|
|
return this->Buttons.RightStick == ButtonState::Pressed;
|
|
|
|
case xna::Buttons::BigButton:
|
|
|
|
return this->Buttons.BigButton == ButtonState::Pressed;
|
|
|
|
case xna::Buttons::LeftThumbstickLeft:
|
2024-05-27 16:44:01 -03:00
|
|
|
return this->ThumbSticks.Left().X < 0.5F;
|
2024-05-21 09:40:59 -03:00
|
|
|
case xna::Buttons::LeftThumbstickRight:
|
2024-05-27 16:44:01 -03:00
|
|
|
return this->ThumbSticks.Left().X > 0.5F;
|
2024-05-21 09:40:59 -03:00
|
|
|
case xna::Buttons::LeftThumbstickDown:
|
2024-05-27 16:44:01 -03:00
|
|
|
return this->ThumbSticks.Left().Y > 0.5F;
|
2024-05-21 09:40:59 -03:00
|
|
|
case xna::Buttons::LeftThumbstickUp:
|
2024-05-27 16:44:01 -03:00
|
|
|
return this->ThumbSticks.Left().Y < 0.5F;
|
2024-05-21 09:40:59 -03:00
|
|
|
case xna::Buttons::RightThumbstickLeft:
|
2024-05-27 16:44:01 -03:00
|
|
|
return this->ThumbSticks.Right().X < 0.5F;
|
2024-05-21 09:40:59 -03:00
|
|
|
case xna::Buttons::RightThumbstickRight:
|
2024-05-27 16:44:01 -03:00
|
|
|
return this->ThumbSticks.Right().X > 0.5F;
|
2024-05-21 09:40:59 -03:00
|
|
|
case xna::Buttons::RightThumbstickDown:
|
2024-05-27 16:44:01 -03:00
|
|
|
return this->ThumbSticks.Right().Y > 0.5F;
|
2024-05-21 09:40:59 -03:00
|
|
|
case xna::Buttons::RightThumbstickUp:
|
2024-05-27 16:44:01 -03:00
|
|
|
return this->ThumbSticks.Right().Y < 0.5F;
|
2024-05-21 09:40:59 -03:00
|
|
|
case xna::Buttons::LeftTrigger:
|
|
|
|
return this->Triggers.Left() > 0.5F;
|
|
|
|
case xna::Buttons::RightTrigger:
|
|
|
|
return this->Triggers.Right() > 0.5F;
|
|
|
|
default:
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
constexpr bool IsButtonUp(xna::Buttons button) const {
|
|
|
|
return !IsButtonDown(button);
|
|
|
|
}
|
|
|
|
|
2024-05-22 10:56:16 -03:00
|
|
|
GamePadButtons Buttons{};
|
|
|
|
GamePadDPad Dpad{};
|
|
|
|
bool IsConnected{false};
|
|
|
|
Ulong PackedNumber{0};
|
2024-05-27 16:44:01 -03:00
|
|
|
GamePadThumbSticks ThumbSticks{};
|
2024-05-22 10:56:16 -03:00
|
|
|
GamePadTriggers Triggers{};
|
2024-04-17 20:21:17 -03:00
|
|
|
};
|
|
|
|
|
2024-06-22 16:24:11 -03:00
|
|
|
//Allows retrieval of user interaction with an Xbox Controller and setting of controller vibration motors.
|
2024-05-21 09:40:59 -03:00
|
|
|
class GamePad {
|
|
|
|
public:
|
2024-06-22 16:24:11 -03:00
|
|
|
//Gets the current state of a game pad controller. As an option, it specifies a dead zone processing method for the analog sticks.
|
2024-05-21 09:40:59 -03:00
|
|
|
static GamePadState GetState(PlayerIndex index);
|
2024-06-22 16:24:11 -03:00
|
|
|
//Gets the current state of a game pad controller. As an option, it specifies a dead zone processing method for the analog sticks.
|
2024-05-21 09:40:59 -03:00
|
|
|
static GamePadState GetState(PlayerIndex index, GamePadDeadZone deadZone);
|
2024-06-22 16:24:11 -03:00
|
|
|
|
|
|
|
//Retrieves the capabilities of an Xbox 360 Controller.
|
2024-05-21 09:40:59 -03:00
|
|
|
static GamePadCapabilities GetCapabilities(PlayerIndex index);
|
2024-06-22 16:24:11 -03:00
|
|
|
//Sets the vibration motor speeds on an Xbox 360 Controller.
|
2024-05-21 09:40:59 -03:00
|
|
|
static bool SetVibration(PlayerIndex index, float leftMotor, float rightMotor, float leftTrigger = 0, float rightTrigger = 0);
|
2024-06-22 16:24:11 -03:00
|
|
|
|
|
|
|
GamePad() = delete;
|
|
|
|
GamePad(GamePad&) = delete;
|
|
|
|
GamePad(GamePad&&) = delete;
|
|
|
|
|
|
|
|
private:
|
|
|
|
friend class Game;
|
2024-05-21 09:40:59 -03:00
|
|
|
static void Initialize();
|
|
|
|
|
2024-04-17 20:21:17 -03:00
|
|
|
public:
|
2024-05-21 09:40:59 -03:00
|
|
|
struct PlatformImplementation;
|
2024-06-22 16:24:11 -03:00
|
|
|
inline static uptr<PlatformImplementation> impl = nullptr;
|
2024-04-17 20:21:17 -03:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|