Add gamepad library and hooks for Lua scripting
Merge !1870 (merged) first.
Example script: gamepad-lib-test.lua
Lua documentation
gamepad userdata fields:
| Field | Accepts | Returns | Description | 
|---|---|---|---|
#gamepad | 
integer | This returns the gamepad number. Gamepad numbers are 1-indexed. | |
gamepad.connected | 
boolean | This field returns true if the gamepad is connected, and false otherwise. | 
|
gamepad.type | 
string | This field returns the type of the gamepad. | |
gamepad.isXbox | 
boolean | 
true if the gamepad is an Xbox controller; false if otherwise. | 
|
gamepad.isPlayStation | 
boolean | 
true if the gamepad is a PlayStation controller; false if otherwise. | 
|
gamepad.isNintendoSwitch | 
boolean | 
true if the gamepad is a Nintendo Switch Pro Controller, a Joy-Con L, a Joy-Con R, or Joy-Con in the Joy-Con Grip; false if otherwise. | 
|
gamepad.isJoyCon | 
boolean | 
true if the gamepad is a Joy-Con L, or a Joy-Con R; false if otherwise. | 
|
gamepad.hasRumble | 
boolean | 
true if the gamepad has haptic feedback capabilities; false if otherwise. | 
|
gamepad.isRumbling | 
boolean | 
true if rumble is active in the gamepad; false if otherwise. | 
|
gamepad.isRumblePaused | 
boolean | boolean | This field will return true if the current haptic effect on the gamepad is paused, and false if it isn't. It can be set to pause the effect. | 
gamepad.largeMotorFrequency | 
fixed point value | fixed point value | The frequency of the large motor. This is usually physically located on the left side of a gamepad. | 
gamepad.smallMotorFrequency | 
fixed point value | fixed point value | The frequency of the small motor. This is usually physically located on the right side of a gamepad. | 
gamepad userdata functions:
| Function | Parameters | Description | Returns | 
|---|---|---|---|
gamepad:isButtonDown | 
string button | 
Checks if a gamepad button is down. | boolean | 
gamepad:getAxis | 
string axis, [fixed_t applyDeadzone] | 
Returns the value of an axis, from -FRACUNIT to FRACUNIT. For triggers, this always returns a value from 0 to FRACUNIT. applyDeadzone is true by default. | 
fixed point value | 
gamepad:getStick | 
"left" or "right", [fixed_t applyDeadzone] | 
Returns the X and Y values of a stick, from -FRACUNIT to FRACUNIT. applyDeadzone is true by default. | 
two fixed point values | 
gamepad:getTrigger | 
"left" or "right", [fixed_t applyDeadzone] | 
Returns the value of a stick, from 0 to FRACUNIT. applyDeadzone is true by default. | 
fixed point value | 
gamepad:getButtonName | 
string button | 
Returns the name of a button. This may vary depending on the gamepad type. This is useful for displaying in e.g. menus. | string | 
gamepad:getAxisName | 
string axis | 
Returns the name of an axis. This may vary depending on the gamepad type. This is useful for displaying in e.g. menus. | string | 
gamepad:getTriggerName | 
"left" or "right"
 | 
Returns the name of a trigger. This may vary depending on the gamepad type. This is useful for displaying in e.g. menus. | string | 
gamepad:rumble | 
fixed_t large_motor_frequency, [fixed_t small_motor_frequency, [tic_t duration]] | 
Changes the frequency of the gamepad's motors. If the small motor's frequency is nil, it'll be set to the large motor's frequency. If duration is nil or 0, the motors rotate forever, until they're stopped or their frequency changes. | 
true is succeeded, false if not | 
gamepad:stopRumble | 
Stops the motors on the gamepad from rotating. | string | 
Button names:
| Name | Description | 
|---|---|
"a" | 
Bottom face button | 
"b" | 
Right face button | 
"x" | 
Left face button | 
"y" | 
Top face button | 
"back" | 
Back button | 
"guide" | 
Guide button | 
"start" | 
Start | 
"left-stick" | 
Left stick click | 
"right-stick" | 
Right stick click | 
"left-shoulder" | 
Left shoulder | 
"right-shoulder" | 
Right shoulder | 
"dpad-up" | 
D-Pad Up | 
"dpad-down" | 
D-Pad Down | 
"dpad-left" | 
D-Pad Left | 
"dpad-right" | 
D-Pad Right | 
"misc1" | 
Depends on the type of the controller; if you want to know, check the controller type, or try using gamepad:getButtonName("misc1")
 | 
"paddle1" | 
P1 Paddle (Xbox Elite controllers) | 
"paddle2" | 
P2 Paddle (Xbox Elite controllers) | 
"paddle3" | 
P3 Paddle (Xbox Elite controllers) | 
"paddle4" | 
P4 Paddle (Xbox Elite controllers) | 
"touchpad" | 
Touchpad button (PlayStation 4 and 5 controllers) | 
Axis names:
| Name | Description | 
|---|---|
"left-x" | 
Left stick X | 
"left-y" | 
Left stick Y | 
"right-x" | 
Right stick X | 
"right-y" | 
Right stick Y | 
"trigger-left" | 
Left trigger | 
"trigger-right" | 
Right trigger | 
Gamepad types:
| Type | 
|---|
"xbox-360" | 
"xbox-one" | 
"xbox-series-xs" | 
"xbox-elite" | 
"ps3" | 
"ps4" | 
"ps5" | 
"switch-pro" | 
"switch-joy-con-grip" | 
"switch-joy-con-left" | 
"switch-joy-con-right" | 
"stadia" | 
"amazon-luna" | 
"steam-controller" | 
"virtual" | 
"unknown" | 
Functions added:
| Function | Parameters | Description | Returns | 
|---|---|---|---|
input.getPlayerGamepad | 
player_t player | 
Returns a gamepad for a specific player. If the specified player isn't "local" to the system running the game, this returns nil. | 
gamepad | 
Hooks added:
| Function | Parameters | Description | 
|---|---|---|
GamepadButtonDown | 
gamepad gamepad, string button | 
Called when a button in the gamepad is pressed. button is the button name. Works just like KeyDown. | 
GamepadButtonUp | 
gamepad gamepad, string button | 
Called when a button in the gamepad is no longer being pressed. button is the button name. Works just like KeyUp. | 
GamepadAdded | 
gamepad gamepad | 
Called when a gamepad is added. | 
GamepadRemoved | 
gamepad gamepad | 
Called when a gamepad is removed. | 
gamepads library:
| Field | Description | 
|---|---|
#gamepads | 
Returns how many gamepads may be connected at once. Always returns 2. | 
gamepads[n] | 
Returns the n-th gamepad. This is 1-indexed. | 
gamepads.iterate | 
Iterates through all connected gamepads. | 
Edited  by Lactozilla