![]() |
CUGL 2.5
Cornell University Game Library
|
#include <CUGameController.h>
Public Types | |
enum class | Hat : 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 GameControllerBallEvent &event, bool focus)> | BallListener |
typedef std::function< void(const GameControllerHatEvent &event, bool focus)> | HatListener |
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 |
Uint8 | numberAxes () const |
Uint8 | numberBalls () const |
Uint8 | numberHats () const |
Uint8 | numberButtons () 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 |
float | getAxisPosition (Uint8 axis) const |
bool | axisDidChange (Uint8 axis) const |
bool | axisIsTrigger (Uint8 axis) const |
Vec2 | getBallOffset (Uint8 ball) const |
Hat | getHatPosition (Uint8 hat) const |
bool | hatDidChange (Uint8 hat) const |
bool | isButtonDown (Uint8 button) const |
bool | isButtonPressed (Uint8 button) const |
bool | isButtonReleased (Uint8 button) const |
bool | requestFocus (Uint32 key) |
bool | isListener (Uint32 key) const |
const AxisListener | getAxisListener (Uint32 key) const |
const BallListener | getBallListener (Uint32 key) const |
const HatListener | getHatListener (Uint32 key) const |
const ButtonListener | getButtonListener (Uint32 key) const |
bool | addAxisListener (Uint32 key, AxisListener listener) |
bool | addBallListener (Uint32 key, BallListener listener) |
bool | addHatListener (Uint32 key, HatListener listener) |
bool | addButtonListener (Uint32 key, ButtonListener listener) |
bool | removeAxisListener (Uint32 key) |
bool | removeBallListener (Uint32 key) |
bool | removeHatListener (Uint32 key) |
bool | removeButtonListener (Uint32 key) |
Protected Attributes | |
SDL_Joystick * | _input |
std::string | _uid |
std::string | _name |
std::vector< bool > | _axisState |
Uint32 | _ballCount |
std::vector< bool > | _hatState |
std::vector< bool > | _buttonState |
Uint32 | _focus |
std::unordered_map< Uint32, AxisListener > | _axisListeners |
std::unordered_map< Uint32, BallListener > | _ballListeners |
std::unordered_map< Uint32, HatListener > | _hatListeners |
std::unordered_map< Uint32, ButtonListener > | _buttonListeners |
Friends | |
class | GameControllerInput |
This class is a reference to single game controller.
A game controller is a collection of four types of input devices:
While individual game controllers (like XBox controllers or PS5 controllers) have a very specific layout, this is a general class that makes no assumptions about the layout of the individual controls. Instead, each attached input device is referred to by an index.
With that said, the index number an attached device is fixed for all controllers of the same type. For example, and XBox controller uses axes 0 (left-right) and 1 (up-down) for the left analogue stick and axes 2 (left-right) and 3 (up-down) for the right analogue stick. With some experimentation, you should be able to figure the layout for any popular controller.
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 track ball 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 a track ball moves. See the method GameController#getBallOffset
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 GameControllerBallEvent event, bool focus)>
event | The track ball 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.
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 hat 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 hat event is delivered whenever a hat changes position. See the method GameController#getHatPosition
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 GameControllerHatEvent event, bool focus)>
event | The hat event |
focus | Whether the listener currently has focus |
|
strong |
An enumeration of the hat positions.
A hat is a directional pad. It 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::addBallListener | ( | Uint32 | key, |
BallListener | listener | ||
) |
Adds a ball motion listener for the given object key
There can only be one ball 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 a track ball is moved.
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::addHatListener | ( | Uint32 | key, |
HatListener | listener | ||
) |
Adds a hat listener for the given object key
There can only be one hat 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 hat 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 | ( | Uint8 | axis | ) | const |
Returns true if the given axis changed position this frame.
axis | The axis index |
bool cugl::GameController::axisIsTrigger | ( | Uint8 | axis | ) | const |
Returns true if the given axis is a trigger.
Triggers are axes whose default value is -1 (so they are one-sided).
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.
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 | ( | Uint8 | axis | ) | const |
Returns the current axis position.
The axis position is a value between -1 and 1, inclusive. It is often either an axis of an analogue joystick or a trigger. If it is a joystick, then its default value will be near 0. It is a trigger, then its default value will be -1.
This class does not implement any dead zones (e.g. axis values to be ignored and treated as the default position). That is the responsibility of the user. A standard recommendation for a deadzone is -0.8 or lower for triggers and -0.2 to 0.2 for joysticks.
axis | The axis index |
const BallListener cugl::GameController::getBallListener | ( | Uint32 | key | ) | const |
Returns the ball motion listener for the given object key
This listener is invoked when a track ball is moved.
If there is no listener for the given key, it returns nullptr.
key | The identifier for the listener |
Vec2 cugl::GameController::getBallOffset | ( | Uint8 | ball | ) | const |
Returns the relative motion of the track ball.
The vector coordinates are between -1 and 1, inclusive. The values 1 or -1 represent maximum movement in a direction. The values returned are the relative movement since the last animation frame. A zero vector means that the track ball did not move.
ball | The track ball 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 HatListener cugl::GameController::getHatListener | ( | Uint32 | key | ) | const |
Returns the hat listener for the given object key
This listener is invoked when the hat changes position.
If there is no listener for the given key, it returns nullptr.
key | The identifier for the listener |
Hat cugl::GameController::getHatPosition | ( | Uint8 | hat | ) | const |
Returns the hat position
A "hat" is the official name of a D-Pad. Its state can be centered (untouched) or one of the eight cardinal directions. Note that just because a game controller has a D-Pad does not mean it has a hat. Some game controllers treat their D-Pad as four separate buttons (one for each direction).
hat | The hat index |
|
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::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::hatDidChange | ( | Uint8 | hat | ) | const |
Returns true if the given hat changed position this frame.
hat | The hat index |
bool cugl::GameController::isButtonDown | ( | Uint8 | button | ) | const |
Returns true if the given button is currently down.
This method does not distinguish presses or releases and will return true the duration of a button hold.
button | The button index |
bool cugl::GameController::isButtonPressed | ( | Uint8 | 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.
button | The button index |
bool cugl::GameController::isButtonReleased | ( | Uint8 | 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.
button | The button index |
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 four actions: axis movement, ball movement, hat movement, or button press/release.
key | The identifier for the listener |
Uint8 cugl::GameController::numberAxes | ( | ) | const |
Returns the number of axes.
An axis is either a single axis of a analogue joystick (which consists of two perpendicular axes) or a trigger.
Axes are refered to by their index. The index of an axis is any positive integer less than the returned value.
Uint8 cugl::GameController::numberBalls | ( | ) | const |
Returns the number of track balls.
Trackballs only measure a change in position. They do not have a absolute position like axes do. ␐Most joysticks do not have track balls.
Track balls are refered to by their index. The index of a track ball is any positive integer less than the returned value.
Uint8 cugl::GameController::numberButtons | ( | ) | const |
Returns the number of buttons.
A button is simply that – something that can be pressed. Most game controllers have the classic 4 buttons (X
, Y
, A
, B
on XBox controllers). But the start and "back" buttons also count as buttons, as do any bumpers above the triggers. Finally, on some controllers the D-Pad is interpretted as four buttons instead of as hat.
Buttons are refered to by their index. The index of a button is any positive integer less than the returned value.
Uint8 cugl::GameController::numberHats | ( | ) | const |
Returns the number of hats.
A "hat" is the official name of a D-Pad. Its state can be centered (untouched) or one of the eight cardinal directions. Note that just because a game controller has a D-Pad does not mean it has a hat. Some game controllers treat their D-Pad as four separate buttons (one for each direction).
Hats are refered to by their index. The index of a hat is any positive integer less than the returned value.
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::removeBallListener | ( | Uint32 | key | ) |
Removes the ball 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 a track ball is moved.
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 method will succeed if there is a motion listener for the given key, even if the pointer awareness if BUTTON or DRAG.
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::removeHatListener | ( | Uint32 | key | ) |
Removes the hat listener for the given object key
If there is no active listener for the given key, this method fails and returns false. This method will succeed if there is a drag listener for the given key, even if the pointer awareness if BUTTON.
This listener is invoked when the hat 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 number of track balls
|
protected |
The set of listeners called on track ball movement
|
protected |
The set of listeners called on button state changes
|
protected |
Whether a button changed state this animation frame
|
protected |
The listener with focus
|
protected |
The set of listeners called on hat movement
|
protected |
Whether a hat changed state this animation frame
|
protected |
The SDL joystick for the accelerometer
|
protected |
The game controller description
|
protected |
The joystick UID assigned by GameControllerInput