![]() |
CUGL 3.0
Cornell University Game Library
|
#include <CUGameController.h>
Public Types | |
enum class | Button : int { INVALID = -1 , A = 0 , B = 1 , X = 2 , Y = 3 , BACK = 4 , GUIDE = 5 , START = 6 , LEFT_STICK = 7 , RIGHT_STICK = 8 , LEFT_SHOULDER = 9 , RIGHT_SHOULDER = 10 , DPAD_UP = 11 , DPAD_DOWN = 12 , DPAD_LEFT = 13 , DPAD_RIGHT = 14 , MISC = 15 , UPPER_LEFT_PADDLE = 16 , UPPER_RIGHT_PADDLE = 17 , LOWER_LEFT_PADDLE = 18 , LOWER_RIGHT_PADDLE = 19 , TOUCHPAD = 20 } |
enum class | Axis : int { INVALID = -1 , LEFT_X = 0 , LEFT_Y = 1 , RIGHT_X = 2 , RIGHT_Y = 3 , TRIGGER_LEFT = 4 , TRIGGER_RIGHT = 5 } |
enum class | DPad : int { CENTERED = 0 , LEFT_UP = 1 , UP = 2 , RIGHT_UP = 3 , RIGHT = 4 , RIGHT_DOWN = 5 , DOWN = 6 , LEFT_DOWN = 7 , LEFT = 8 } |
typedef std::function< void(const GameControllerAxisEvent &event, bool focus)> | AxisListener |
typedef std::function< void(const GameControllerDPadEvent &event, bool focus)> | DPadListener |
typedef std::function< void(const GameControllerButtonEvent &event, bool focus)> | ButtonListener |
Public Member Functions | |
GameController () | |
~GameController () | |
void | close () |
std::string | getName () const |
std::string | getUID () const |
bool | hasRumble () const |
bool | hasRumbleTriggers () const |
void | applyRumble (Uint16 low_freq, Uint16 high_freq, Uint32 duration) |
void | hasRumbleTriggers (Uint16 left, Uint16 right, Uint32 duration) const |
bool | requestFocus (Uint32 key) |
bool | isListener (Uint32 key) const |
bool | hasAxis (Axis axis) const |
float | getAxisPosition (Axis axis) const |
bool | axisDidChange (Axis axis) const |
const AxisListener | getAxisListener (Uint32 key) const |
bool | addAxisListener (Uint32 key, AxisListener listener) |
bool | removeAxisListener (Uint32 key) |
bool | hasButton (Button button) const |
bool | isButtonDown (Button button) const |
bool | isButtonPressed (Button button) const |
bool | isButtonReleased (Button button) const |
const ButtonListener | getButtonListener (Uint32 key) const |
bool | addButtonListener (Uint32 key, ButtonListener listener) |
bool | removeButtonListener (Uint32 key) |
bool | hasDPad () const |
DPad | getDPadPosition () const |
bool | dPadDidChange () const |
const DPadListener | getDPadListener (Uint32 key) const |
bool | addDPadListener (Uint32 key, DPadListener listener) |
bool | removeDPadListener (Uint32 key) |
Protected Attributes | |
SDL_GameController * | _input |
std::string | _uid |
std::string | _name |
std::vector< bool > | _axisState |
std::vector< bool > | _buttonState |
bool | _dpadState |
Uint32 | _focus |
std::unordered_map< Uint32, AxisListener > | _axisListeners |
std::unordered_map< Uint32, ButtonListener > | _buttonListeners |
std::unordered_map< Uint32, DPadListener > | _dpadListeners |
Friends | |
class | GameControllerInput |
This class is a reference to single game controller.
This class is built on top of the SDL GameController interface. This allows the developer to use a uniform input independent of the controller input type (i.e. D-input vs Xinput). This API is slightly more restrictive than the SDL joystick interface, in that it does not have support for hats or track balls). Instead, the types of input are limited to the following:
In this interface, D-Pads are treated as buttons and not hats. However, we do abstract out a D-Pad interface to replicate joystick hat functionality.
Note that SDL game controllers also support sensors (accelerometers) and touch pads (such as the PS4 touchpad). None of that is support currently.
The advantage of the SDL game controller API is that layout is uniform. All controllers have buttons and axes in the same place. Our API uses the XBox names of buttons (A, B, X, Y) instead of the Playstation names, as they are easier to reference.
There should only be one instance of a specific controller at any given time. In addition, controllers can be connected and removed while the application is running. For that reason, this class does not allow you to allocate an game controller object. Instead, you must access each game controller through the GameControllerInput
interface.
This type represents an axis listener for the GameController
class.
In CUGL, listeners are implemented as a set of callback functions, not as objects. This allows each listener to implement as much or as little functionality as it wants. A listener is identified by a key which should be a globally unique unsigned int.
An event is delivered whenever an axis changes its position. See the method GameController#getAxisPosition
for more information.
Listeners are guaranteed to be called at the start of an animation frame, before the method Application#update(float)
.
While game controller listeners do not traditionally require focus like a keyboard does, we have included that functionality. While only one listener can have focus at a time, all listeners will receive input from the game controller.
The function type is equivalent to
std::function<void(const GameControllerAxisEvent event, bool focus)>
event | The axis event |
focus | Whether the listener currently has focus |
This type represents a button listener for the GameController
class.
In CUGL, listeners are implemented as a set of callback functions, not as objects. This allows each listener to implement as much or as little functionality as it wants. A listener is identified by a key which should be a globally unique unsigned int.
A button event is delivered whenever a buttons changes state between up and/or down. See the methods GameController#isButtonPressed
and GameController#isButtonReleased
for more information. Note that this listener is ptotentially redundant to the DPadListener
, as that listener will also report D-Pad state.
Listeners are guaranteed to be called at the start of an animation frame, before the method Application#update(float)
.
While game controller listeners do not traditionally require focus like a keyboard does, we have included that functionality. While only one listener can have focus at a time, all listeners will receive input from the game controller.
The function type is equivalent to
std::function<void(const GameControllerButtonEvent event, bool focus)>
event | The button event |
focus | Whether the listener currently has focus |
This type represents a DPad listener for the GameController
class.
In CUGL, listeners are implemented as a set of callback functions, not as objects. This allows each listener to implement as much or as little functionality as it wants. A listener is identified by a key which should be a globally unique unsigned int.
A DPad event is delivered whenever a D-Pad button is pressed or released, changing the overall direction of the D-pad. See the method GameController#getDPadPosition
for more information. Note that this listener is ptotentially redundant to the ButtonListener
, as that listener will also report D-Pad state (as they are buttons).
Listeners are guaranteed to be called at the start of an animation frame, before the method Application#update(float)
.
While game controller listeners do not traditionally require focus like a keyboard does, we have included that functionality. While only one listener can have focus at a time, all listeners will receive input from the game controller.
The function type is equivalent to
std::function<void(const GameControllerHatEvent event, bool focus)>
event | The hat event |
focus | Whether the listener currently has focus |
|
strong |
An enumeration of the supported axes.
This is the list of all axes supported by this interface. Note that not all game controllers support all axes. For example, classic Nintendo gamepads have no axes at all! To determine if an axis is supported, use the method GameController#hasAxis
.
|
strong |
An enumeration of the supported buttons.
This is the list of all buttons supported by this interface. Note that not all game controllers support all buttons. For example, most game controllers do not support the paddles found on the XBox elite controller. To determine if a button is supported, use the method GameController#hasButton
.
|
strong |
An enumeration of the D-Pad positions.
Even though D-Pads are buttons, we allow the user to query the current direction as a function of the (cumulative) pressed buttons. A D-Pad has nine states – the center and the eight cardinal directions.
cugl::GameController::GameController | ( | ) |
Creates a degnerate game controller
This game controller is not actually attached to any devices. To activate a game controller, use GameControllerInput#open
instead.
|
inline |
Deletes this input device, disposing of all resources
bool cugl::GameController::addAxisListener | ( | Uint32 | key, |
AxisListener | listener | ||
) |
Adds an axis motion listener for the given object key
There can only be one axis listener for a given key (though you may share keys across other listener types). If a listener already exists for the key, the method will fail and return false. You must remove a listener before adding a new one for the same key.
This listener is invoked when an axis changes position.
key | The identifier for the listener |
listener | The listener to add |
bool cugl::GameController::addButtonListener | ( | Uint32 | key, |
ButtonListener | listener | ||
) |
Adds a button listener for the given object key
There can only be one button listener for a given key (though you may share keys across other listener types). If a listener already exists for the key, the method will fail and return false. You must remove a listener before adding a new one for the same key.
This listener is invoked when the button changes state. So it is invoked on a press or a release, but not a hold.
key | The identifier for the listener |
listener | The listener to add |
bool cugl::GameController::addDPadListener | ( | Uint32 | key, |
DPadListener | listener | ||
) |
Adds a D-Pad listener for the given object key
There can only be one D-Pad listener for a given key (though you may share keys across other listener types). If a listener already exists for the key, the method will fail and return false. You must remove a listener before adding a new one for the same key.
This listener is invoked when the D-Pad changes position.
key | The identifier for the listener |
listener | The listener to add |
void cugl::GameController::applyRumble | ( | Uint16 | low_freq, |
Uint16 | high_freq, | ||
Uint32 | duration | ||
) |
Starts a rumble effect for this controller.
low_freq | The intensity of the low frequency (left) rumble motor |
high_freq | The intensity of the high frequency (right) rumble motor |
duration | The rumble duration in milliseconds |
bool cugl::GameController::axisDidChange | ( | Axis | axis | ) | const |
Returns true if the given axis changed position this frame.
axis | The axis index |
void cugl::GameController::close | ( | ) |
Closes this game controller, releasing all resources.
This method not invalidates this game controller, so any shared pointers still referring to this controller are no longer usable. The only way to access the game controller again is to call GameControllerInput#open
.
It is often better to call the method GameControllerInput#close
instead of this one.
bool cugl::GameController::dPadDidChange | ( | ) | const |
Returns true if the D-Pad changed position this frame.
const AxisListener cugl::GameController::getAxisListener | ( | Uint32 | key | ) | const |
Returns the axis motion listener for the given object key
This listener is invoked when an axis changes position.
If there is no listener for the given key, it returns nullptr.
key | The identifier for the listener |
float cugl::GameController::getAxisPosition | ( | Axis | axis | ) | const |
Returns the current axis position.
The default value of any axis is 0. The joysticks all range from -1 to 1 (with negative values being left and down). The triggers all range from 0 to 1.
Note that the SDL only guarantees that a trigger at rest will be within 0.2 of zero. Most applications implement "dead zones" to ignore values in this range. However, this class does not implement any dead zones; that is the responsibility of the user.
If the axis is not supported by this controller, this method will return 0.
axis | The axis index |
const ButtonListener cugl::GameController::getButtonListener | ( | Uint32 | key | ) | const |
Returns the button listener for the given object key
This listener is invoked when the button changes state. So it is invoked on a press or a release, but not a hold.
If there is no listener for the given key, it returns nullptr.
key | The identifier for the listener |
const DPadListener cugl::GameController::getDPadListener | ( | Uint32 | key | ) | const |
Returns the D-Pad listener for the given object key
This listener is invoked when the D-Pad changes position.
If there is no listener for the given key, it returns nullptr.
key | The identifier for the listener |
DPad cugl::GameController::getDPadPosition | ( | ) | const |
Returns the D-Pad position
This method converts the current D-Pad button state into a directional state. This state can be centered (untouched) or one of the eight cardinal directions.
If this controller does not have a D-Pad, this method will always return CENTERED.
|
inline |
Returns the name of this game controller.
Names are descriptions provided by the vendor. They are not unique, and it is possible to have multiple devices with the same name connected at once.
|
inline |
Returns the UID of this game controller.
UIDs are unique identifiers assigned by GameControllerInput
.
bool cugl::GameController::hasAxis | ( | Axis | axis | ) | const |
Returns true if this game controller supports the specified axis
Note that not all game controllers support all axes. In particular, the classic Nintendo controllers have no axes at all.
axis | The axis to query |
bool cugl::GameController::hasButton | ( | Button | button | ) | const |
Returns true if this game controller supports the specified button
Note that not all game controllers support all buttons. In the paddles are currently unique to the XBox Elite controller.
button | The button to query |
bool cugl::GameController::hasDPad | ( | ) | const |
Returns true if the controller has a directional pad.
This method is the same a querying all four D-pad buttons.
bool cugl::GameController::hasRumble | ( | ) | const |
Returns true if this controller supports general rumble effects
bool cugl::GameController::hasRumbleTriggers | ( | ) | const |
Returns true if this controller supports trigger rumble effects
void cugl::GameController::hasRumbleTriggers | ( | Uint16 | left, |
Uint16 | right, | ||
Uint32 | duration | ||
) | const |
Starts a rumble effect for this controller.
left | The intensity of the left trigger rumble motor |
right | The intensity of the right trigger rumble motor |
duration | The rumble duration in milliseconds |
bool cugl::GameController::isButtonDown | ( | Button | button | ) | const |
Returns true if the given button is currently down.
This method does not distinguish presses or releases and will return true the entire duration of a button hold.
If the button is not supported by this controller, this method will return false.
button | The button to query |
bool cugl::GameController::isButtonPressed | ( | Button | button | ) | const |
Returns true if the given button was pressed this frame.
A press means that the button is down this animation frame, but was not down the previous frame.
If the button is not supported by this controller, this method will return false.
button | The button to query |
bool cugl::GameController::isButtonReleased | ( | Button | button | ) | const |
Returns true if the given button was released this frame.
A release means that the button is up this animation frame, but was not up the previous frame.
If the button is not supported by this controller, this method will return false.
button | The button to query |
bool cugl::GameController::isListener | ( | Uint32 | key | ) | const |
Returns true if key represents a listener object
An object is a listener if it is a listener for any of the three actions: axis movement, button press/release, or D-Pad movement
key | The identifier for the listener |
bool cugl::GameController::removeAxisListener | ( | Uint32 | key | ) |
Removes the axis motion listener for the given object key
If there is no active listener for the given key, this method fails and returns false.
This listener is invoked when an axis changes position.
key | The identifier for the listener |
bool cugl::GameController::removeButtonListener | ( | Uint32 | key | ) |
Removes the button listener for the given object key
If there is no active listener for the given key, this method fails and returns false.
This listener is invoked when the button changes state. So it is invoked on a press or a release, but not a hold.
key | The identifier for the listener |
bool cugl::GameController::removeDPadListener | ( | Uint32 | key | ) |
Removes the D-Pad listener for the given object key
If there is no active listener for the given key, this method fails and returns false.
This listener is invoked when the D-Pad changes position.
key | The identifier for the listener |
bool cugl::GameController::requestFocus | ( | Uint32 | key | ) |
Requests focus for the given identifier
Only an active listener can have focus. This method returns false if the key does not refer to an active listener (of any type). Note that keys may be shared across listeners of different types, but must be unique for each listener type.
key | The identifier for the focus object |
|
protected |
The set of listeners called on axis movement
|
protected |
Whether an axis changed state this animation frame
|
protected |
The set of listeners called on button state changes
|
protected |
Whether a button changed state this animation frame
|
protected |
The set of listeners called on D-Pad movement
|
protected |
Whether the D-Pad changed state this animation frame
|
protected |
The listener with focus
|
protected |
The SDL game controller reference
|
protected |
The game controller description
|
protected |
The joystick UID assigned by GameControllerInput