Gamepad Input

GameMaker has a number of dedicated functions that can be used to detect both analog and digital controls from multiple connected gamepads. These functions work similar to the Device Inputs, in that you can detect up to four different XInput game pads that are connected (and up to 8 DirectInput gamepads) and deal with the input from each one using the same functions. Note that when a gamepad is plugged in to your device (or it is removed) then an asynchronous System Event is triggered where you can deal with the situation using the appropriate functions.

The gamepad "slots" are indexed from 0 upwards, and the actual slot that a gamepad assigned will depend on a variety of factors, not least of which is the OS that the project is running on. On the Windows target, slots 0 - 3 inclusive are only for Xinput gamepads, ie: Xbox360 controllers and compatibles. However you can also check slots 4 - 11 inclusive for DirectInput gamepads, which means you can detect many other models of controller when connected through these slots. On other platforms, pads may be detected on any slot that the OS has assigned it, which could slot 3 or slot 20 or more. For example, Android devices will store bluetooth gamepads in a slot and then reserve that slot for that gamepad in the future, whether it is connected or not, so you cannot assume that a single connected gamepad is connected to slot 0, as this will probably not be the case.

It is worth noting that when using DirectInput gamepads on Windows, or generic gamepads on other platforms, the constants given below may not match exactly the buttons that you expect when they are pressed, due to the fragmented and non-standardised way that the API is implemented by controller manufacturers. Because of this, it is recommend that you have some kind of gamepad setup screen in your games where people can redefine the gamepad buttons based on input from any connected device to mitigate any issues (there are gamepad "mapping" functions that can help with this on Windows Desktop, Ubuntu, macOS, and Android targets, while on all others you would need to do this yourself using code).

Input Constants

When working with the gamepad functions, input can come from axes, buttons or hats, which GameMaker will assign to the following built-in constants (note that "hats" are generally only detected on non-standard controllers):

Gamepad Button Constant
ConstantDescription
gp_face1Top button 1 (this maps to the "A" on an Xbox controller and the cross on a PS controller)
gp_face2Top button 2 (this maps to the "B" on an Xbox controller and the circle on a PS controller)
gp_face3Top button 3 (this maps to the "X" on an Xbox controller and the square on a PS controller)
gp_face4Top button 4 (this maps to the "Y" on an Xbox controller and the triangle on a PS controller)
gp_shoulderlLeft shoulder button
gp_shoulderlbLeft shoulder trigger
gp_shoulderrRight shoulder button
gp_shoulderrbRight shoulder trigger
gp_selectThe select button (on a PS controller, this triggers when you press the touchpad down)
gp_startThe start button (this is the "options" button on a PS controller)
gp_sticklThe left stick pressed (as a button)
gp_stickrThe right stick pressed (as a button)
gp_paduD-pad up
gp_paddD-pad down
gp_padlD-pad left
gp_padrD-pad right
gp_homeThe "home" button on Switch controllers, and the PS/XBOX logo buttons on some controllers
gp_touchpadbuttonThe touchpad button on a PS controller
gp_paddlerUpper or primary paddle, under your right hand (e.g. Xbox Elite paddle P1)
gp_paddlelUpper or primary paddle, under your left hand (e.g. Xbox Elite paddle P3)
gp_paddlerbLower or secondary paddle, under your right hand (e.g. Xbox Elite paddle P2)
gp_paddlelbLower or secondary paddle, under your left hand (e.g. Xbox Elite paddle P4)
gp_extra1An extra button that may be mapped to anything
gp_extra2An extra button that may be mapped to anything
gp_extra3An extra button that may be mapped to anything
gp_extra4An extra button that may be mapped to anything
gp_extra5An extra button that may be mapped to anything
gp_extra6An extra button that may be mapped to anything
Gamepad Axis Constant
ConstantDescription
gp_axislhLeft stick horizontal axis (analog)
gp_axislvLeft stick vertical axis (analog)
gp_axisrhRight stick horizontal axis (analog)
gp_axisrvRight stick vertical axis (analog)
The constants below can only be used with the DualSense gamepad on a PS4 or PS5
gp_axis_acceleration_x*The gamepad's acceleration on the X axis
gp_axis_acceleration_y*The gamepad's acceleration on the Y axis
gp_axis_acceleration_z*The gamepad's acceleration on the Z axis
gp_axis_angular_velocity_x*The gamepad's angular velocity on the X axis
gp_axis_angular_velocity_y*The gamepad's angular velocity on the Y axis
gp_axis_angular_velocity_z*The gamepad's angular velocity on the Z axis
gp_axis_orientation_x*The gamepad's X orientation
gp_axis_orientation_y*The gamepad's Y orientation
gp_axis_orientation_z*The gamepad's Z orientation
gp_axis_orientation_w*The gamepad's W orientation

NOTE The gamepad's orientation is a Quaternion, which is why it has four values (X, Y, Z and W).

* These constants are only supported on PS4 and PS5, and when used on other platforms the input functions will return 0, even when using a DualSense gamepad.

To better understand exactly what part of the controller each constant represents, you can refer to the following image of a standard XInput gamepad:

Xinput gamepad illustration

Functions

Below you can find a list of all the gamepad functions:

 

The following gamepad functions also exist and are used for remapping the built in constants to the direct physical inputs of a given gamepad. These functions are only for the Windows Desktop, Ubuntu, macOS, and Android target platforms and on Windows, they will only be valid for Direct input devices. While GameMaker comes with mappings for a number of different gamepads based on SDL Gamepad Controller DB, however due to the huge number of controller types and brands out there, it is impossible to map the GML constants to the correct inputs for every make and model, so with these functions you have the possibility to create your own custom mappings.

 

It is worth noting that Direct Input gamepads are run in cooperative mode which means that your game only has access to them when it is the foreground application, which in turn will cause Direct Input controllers to be "lost" if the game loses focus and then "found" again when it comes back into focus (this can be detected in the System Event and dealt with). Similarly, no input from gamepads will be detected while the game is not in focus, and we recommend that you use the function os_is_paused() or window_has_focus() to detect this and pause the game or something similar as any button being held down at the time the game loses focus will maintain the held down state until the game regains focus.

Compatibility

The following list shows current compatibility across the platforms (note that this will change with future updates):

Ideally, on all target platforms, you want to enumerate a list of available gamepad "slots" and then check them to see if any devices are detected, something like this:

var _maxpads = gamepad_get_device_count();

for (var i = 0; i < _maxpads; i++)
{
    if (gamepad_is_connected(i))
    {
        // do stuff with pad "i"
    }
}