Gamepad Support
Gameface can receive and process input data from one or more gamepad devices. Cohtml supports the W3C standard for gamepads. However, previous versions of the software diverged from the standard in several significant ways which are described further down on this page.
Adding a gamepad controller
The current gamepad indexing interface for Gameface follows the guidelines described by the W3C standard for gamepad support. Registering a new gamepad is achieved through the RegisterGamepad
function, which takes several different attributes:
RegisterGamepad(unsigned id, const char* info, unsigned axesCount, unsigned buttonsCount, void* reserved = nullptr)
@param id
serves as the unique identifier for the gamepad.@param info
contains general information for the gamepad.@param axesCount
specifies the number of analog axes on the gamepad.@param buttonsCount
specifies the number of buttons on the gamepad.@param reserved
is a reserved parameter that must be set tonullptr
.
Updating and removing controllers
After adding a gamepad, you must call the function UpdateGamepad
at regular intervals to pass the state of the gamepad to Gameface. This function is used to communicate with Cohtml which buttons are pressed, and how the thumbsticks have been manipulated.
virtual void UpdateGamepadState(const cohtml::GamepadState& state) = 0;
@param state
specifies the new state of the gamepad. It should contain the ID of the gamepad to update, a timestamp, and the new values for the axes/buttons.
Removing gamepads is done by calling UnregisterGamepad
.
virtual void UnregisterGamepad(unsigned id) = 0;
@param id
specifies the id of the gamepad you want to unregister
Gamepad IDs on the C++ side
Each gamepad must always have exactly one unique ID, which should stay consistent throughout the calls to RegisterGamepad
, UnregisterGamepad
and UpdateGamepadState
. You can set any value for each gamepad, as long as you keep those values unique and consistent.
Differences between versions
Different versions of Gameface handle gamepad support differently. Older versions of the software diverge from the W3C, specifically when it comes to indexing gamepads.
Gameface 1.3.1 and earlier
Removing the gamepad element also removes the index of the element within the collection. This reduces the size of the collection.
If a gamepad is removed, then added again, it will be registered under a new index in the collection. Unregistering a gamepad removes the gamepad element from the collection. This reduces the size of the collection and therefore rightmost indices that are saved and used in JavaScript might get invalidated.
Gameface 1.3.2 to 1.4.2
Removing the controller does not remove the respective element from the gamepad collection. Instead, it sets the element to null
. If the same controller is reconnected, it will be assigned the same index it was initially given.
Gameface 1.4.2 and newer
From version 1.4.2 onward, Gameface handles gamepad indexing according to the guidelines detailed in the W3C standard. The id values that are passed to System::RegisterGamepad are kept as separate values from the gamepad indices.
Whenever a gamepad is connected, it will be assigned to the first free index, starting from 0. Indices are assigned based on a first-come, first-serve principle, starting at zero. If a gamepad is disconnected, the now available index is not reassigned to gamepads that are still connected. New connected or reconnected gamepads are assigned to the leftmost available slot in the gamepad collection or pushed at its back.
When a gamepad is unregistered, previously assigned indices are not reassigned to gamepads that continue to be connected. However, if the same or a new gamepad is connected, the lowest available index will be used.