2.9.16
Coherent GT
A modern user interface library for games
Gamepad API

Table of Contents

Coherent GT supports the HTML5 gamepad API as defined here. On the C++ side, your application must feed the data to Coherent GT - much like it feeds keyboard and mouse events.

There's one major difference however - gamepads are defined system-wise, and not per view. Unlike the keyboard and mouse which use event-based notifications for changes, the gamepad API requires the user to poll the state of the entire gamepad each frame (usually during a call to requestAnimationFrame).

Imagine having two views and one of them moving a <div> across the screen depending on the left stick movement of the gamepad. Now, if the other view gets focused, the first one will stop receiving all state updates and will move the rectangle indefinitely which is why the gamepad input must be system-wise.

C++ API

On the C++ side three things are worth mentioning:

  1. The methods for handling gamepads are found on Coherent::UIGT::UISystem instead of Coherent::UIGT::View:
  2. Although updating the same state multiple times from different Views is not harmful, there's no reason to do so as all views share the same gamepads.
  3. If a view loses focus, it will continue to receive updates. You need to handle that in your JavaScript if this behaviour is undesired.

JavaScript API

The suggested way of using the gamepad API is inside a requestAnimationFrame call:

<div id="rect"></div>
<style>
    #rect {
        position: absolute;
        top: 0;
        left: 0;
    }
</style>

var animate = function () {
    var gamepad = navigator.getGamepads()[0];
    var rect = document.getElementById("rect");
    var speed = 5;
    rect.style.left += gamepad.axes[0] * speed;
    rect.style.top += gamepad.axes[1] * speed;
    requestAnimationFrame(animate);
};
animate();

Additionally, the gamepadconnected event is fired whenever a new gamepad is connected.

window.addEventListener("gamepadconnected", function(e) {
  console.log("Gamepad connected at index %d: %s. %d buttons, %d axes.",
    e.gamepad.index, e.gamepad.id,
    e.gamepad.buttons.length, e.gamepad.axes.length);
});

Similarly, gamepaddisconnected will be called when a gamepad is disconnected.

window.addEventListener("gamepaddisconnected", function(e) {
  console.log("Gamepad disconnected from index %d: %s",
    e.gamepad.index, e.gamepad.id);
});