![]() |
CUGL 4.0
Cornell University Game Library
|
#include <CUGamepad.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 GamepadAxisEvent &event, bool focus)> | AxisListener |
| typedef std::function< void(const GamepadDPadEvent &event, bool focus)> | DPadListener |
| typedef std::function< void(const GamepadButtonEvent &event, bool focus)> | ButtonListener |
Public Member Functions | |
| Gamepad () | |
| ~Gamepad () | |
| 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_Gamepad * | _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 | GamepadInput |
This class is a reference to single gamepad.
This class is built on top of the SDL Gamepad 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 gamepads also support sensors (accelerometers) and touch pads (such as the PS4 touchpad). None of that is currently supported.
The advantage of the SDL gamepad API is that layout is uniform. All gamepads 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 gamepad at any given time. In addition, gamepads can be connected and removed while the application is running. For that reason, this class does not allow you to allocate a gamepad object. Instead, you must access each gamepad through the GamepadInput interface.
This type represents an axis listener for the Gamepad 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 Gamepad#getAxisPosition for more information.
Listeners are guaranteed to be called at the start of an animation frame, before the method Application#update(float).
While gamepad 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 gamepad.
The function type is equivalent to
std::function<void(const GamepadAxisEvent event, bool focus)>
| event | The axis event |
| focus | Whether the listener currently has focus |
This type represents a button listener for the Gamepad 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 Gamepad#isButtonPressed and Gamepad#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 gamepad 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 gamepad.
The function type is equivalent to
std::function<void(const GamepadButtonEvent event, bool focus)>
| event | The button event |
| focus | Whether the listener currently has focus |
This type represents a DPad listener for the Gamepad 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 Gamepad#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 gamepad 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 gamepad.
The function type is equivalent to
std::function<void(const GamepadHatEvent 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 gamepads support all axes. For example, classic Nintendo gamepads have no axes at all! To determine if an axis is supported, use the method Gamepad#hasAxis.
|
strong |
An enumeration of the supported buttons.
This is the list of all buttons supported by this interface. Note that not all gamepads support all buttons. For example, most gamepads do not support the paddles found on the XBox elite controller. To determine if a button is supported, use the method Gamepad#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::Gamepad::Gamepad | ( | ) |
Creates a degnerate gamepad
This gamepad is not actually attached to any devices. To activate a gamepad, use GamepadInput#open instead.
|
inline |
Deletes this input device, disposing of all resources
| bool cugl::Gamepad::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::Gamepad::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::Gamepad::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::Gamepad::applyRumble | ( | Uint16 | low_freq, |
| Uint16 | high_freq, | ||
| Uint32 | duration | ||
| ) |
Starts a rumble effect for this gamepad.
| 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::Gamepad::axisDidChange | ( | Axis | axis | ) | const |
Returns true if the given axis changed position this frame.
| axis | The axis index |
| void cugl::Gamepad::close | ( | ) |
Closes this gamepad, releasing all resources.
This method invalidates this gamepad, so any shared pointers still referring to this gamepad are no longer usable. The only way to access the gamepad again is to call GamepadInput#open.
It is often better to call the method GamepadInput#close instead of this one.
| bool cugl::Gamepad::dPadDidChange | ( | ) | const |
Returns true if the D-Pad changed position this frame.
| const AxisListener cugl::Gamepad::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::Gamepad::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 gamepad, this method will return 0.
| axis | The axis index |
| const ButtonListener cugl::Gamepad::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::Gamepad::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::Gamepad::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 gamepad does not have a D-Pad, this method will always return CENTERED.
|
inline |
Returns the name of this gamepad.
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 gamepad.
UIDs are unique identifiers assigned by GamepadInput.
| bool cugl::Gamepad::hasAxis | ( | Axis | axis | ) | const |
Returns true if this gamepad supports the specified axis
Note that not all gamepads support all axes. In particular, the classic Nintendo controllers have no axes at all.
| axis | The axis to query |
| bool cugl::Gamepad::hasButton | ( | Button | button | ) | const |
Returns true if this gamepad supports the specified button
Note that not all gamepads support all buttons. In particular, many paddles are currently unique to the XBox Elite controller.
| button | The button to query |
| bool cugl::Gamepad::hasDPad | ( | ) | const |
Returns true if the gamepad has a directional pad.
This method is the same a querying all four D-pad buttons.
| bool cugl::Gamepad::hasRumble | ( | ) | const |
Returns true if this gamepad supports general rumble effects
| bool cugl::Gamepad::hasRumbleTriggers | ( | ) | const |
Returns true if this gamepad supports trigger rumble effects
| void cugl::Gamepad::hasRumbleTriggers | ( | Uint16 | left, |
| Uint16 | right, | ||
| Uint32 | duration | ||
| ) | const |
Starts a rumble effect for this gamepad.
| 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::Gamepad::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 gamepad, this method will return false.
| button | The button to query |
| bool cugl::Gamepad::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 gamepad, this method will return false.
| button | The button to query |
| bool cugl::Gamepad::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 gamepad, this method will return false.
| button | The button to query |
| bool cugl::Gamepad::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::Gamepad::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::Gamepad::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::Gamepad::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::Gamepad::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 gamepad reference
|
protected |
The gamepad description
|
protected |
The joystick UID assigned by GamepadInput