Registry data for game controllers

Note

This topic is meant for manufacturers of Windows 10-compatible game controllers, and doesn't apply to the majority of developers.

The Windows.Gaming.Input namespace allows independent hardware vendors (IHVs) to add data to the PC's registry, enabling their devices to appear as Gamepads, RacingWheels, ArcadeSticks, FlightSticks, and UINavigationControllers as appropriate. All IHVs should add this data for their compatible controllers. By doing this, all UWP games (and any desktop games that use the WinRT API) will be able to support your game controller.

Mapping scheme

Mappings for a device with Vendor ID (VID) VVVV, Product ID (PID) PPPP, Usage Page UUUU, and Usage ID XXXX, will be read out from this location in the registry:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\GameInput\Devices\VVVVPPPPUUUUXXXX

The table below explains the expected values under the device root location:

Name Type Required? Info
Disabled DWORD No

Indicates that this particular device should be disabled.

  • 0: Device is not disabled.
  • 1: Device is disabled.
Description REG_SZ No A short description of the device.

Your device installer should add this data to the registry (either via setup or an INF file).

Subkeys under the device root location are detailed in the following sections.

Gamepad

The table below lists the required and optional subkeys under the Gamepad subkey:

Subkey Required? Info
Menu Yes See Button mapping
View Yes
A Yes
B Yes
X Yes
Y Yes
LeftShoulder Yes
RightShoulder Yes
LeftThumbstickButton Yes
RightThumbstickButton Yes
DPadUp Yes
DPadDown Yes
DPadLeft Yes
DPadRight Yes
Paddle1 No
Paddle2 No
Paddle3 No
Paddle4 No
LeftTrigger Yes See Axis mapping
RightTrigger Yes
LeftThumbstickX Yes
LeftThumbstickY Yes
RightThumbstickX Yes
RightThumbstickY Yes

Note

If you add your game controller as a supported Gamepad, we highly recommend that you also add it as a supported UINavigationController.

RacingWheel

The table below lists the required and optional subkeys under the RacingWheel subkey:

Subkey Required? Info
PreviousGear Yes See Button mapping
NextGear Yes
DPadUp No
DPadDown No
DPadLeft No
DPadRight No
Button1 No
Button2 No
Button3 No
Button4 No
Button5 No
Button6 No
Button7 No
Button8 No
Button9 No
Button10 No
Button11 No
Button12 No
Button13 No
Button14 No
Button15 No
Button16 No
FirstGear No
SecondGear No
ThirdGear No
FourthGear No
FifthGear No
SixthGear No
SeventhGear No
ReverseGear No
Wheel Yes See Axis mapping
Throttle Yes
Brake Yes
Clutch No
Handbrake No
MaxWheelAngle Yes See Properties mapping

ArcadeStick

The table below lists the required and optional subkeys under the ArcadeStick subkey:

Subkey Required? Info
Action 1 Yes See Button mapping
Action2 Yes
Action3 Yes
Action4 Yes
Action5 Yes
Action6 Yes
Special1 Yes
Special2 Yes
StickUp Yes
StickDown Yes
StickLeft Yes
StickRight Yes

FlightStick

The table below lists the required and optional subkeys under the FlightStick subkey:

Subkey Required? Info
FirePrimary Yes See Button mapping
FireSecondary Yes
Roll Yes See Axis mapping
Pitch Yes
Yaw Yes
Throttle Yes
HatSwitch Yes See Switch mapping

UINavigation

The table below lists the required and optional subkeys under UINavigation subkey:

Subkey Required? Info
Menu Yes See Button mapping
View Yes
Accept Yes
Cancel Yes
PrimaryUp Yes
PrimaryDown Yes
PrimaryLeft Yes
PrimaryRight Yes
Context1 No
Context2 No
Context3 No
Context4 No
PageUp No
PageDown No
PageLeft No
PageRight No
ScrollUp No
ScrollDown No
ScrollLeft No
ScrollRight No
SecondaryUp No
SecondaryDown No
SecondaryLeft No
SecondaryRight No

For more information about UI navigation controllers and the above commands, see UI navigation controller.

Keys

The following sections explain the contents of each of the subkeys under the Gamepad, RacingWheel, ArcadeStick, FlightStick, and UINavigation keys.

Button mapping

The table below lists the values that are needed to map a button. For example, if pressing DPadUp on the game controller, the mapping for DPadUp should contain the ButtonIndex value (Source is Button). If DPadUp needs to be mapped from a switch position, then the DPadUp mapping should contain the values SwitchIndex and SwitchPosition (Source is Switch).

Source Value name Value type Required? Value info
Button ButtonIndex DWORD Yes Index in the RawGameController button array.
Axis AxisIndex DWORD Yes Index in the RawGameController axis array.
Invert DWORD No Indicates that the axis value should be inverted before the Threshold Percent and DebouncePercent factors are applied.
ThresholdPercent DWORD Yes Indicates the axis position at which the mapped button value transitions between the pressed and released states. The valid range of values is 0 to 100. The button is considered pressed if the axis value is greater than or equal to this value.
DebouncePercent DWORD Yes

Defines the size of a window around the ThresholdPercent value, which is used to debounce the reported button state. The valid range of values is 0 to 100. Button state transitions can only occur when the axis value crosses the upper or lower boundaries of the debounce window. For example, a ThresholdPercent of 50 and DebouncePercent of 10 results in debounce boundaries at 45% and 55% of the full-range axis values. The button can't transition to the pressed state until the axis value reaches 55% or above, and it can't transition back to the released state until the axis value reaches 45% or below.

The computed debounce window boundaries are clamped between 0% and 100%. For example, a threshold of 5% and a debounce window of 20% would result in the debounce window boundaries falling at 0% and 15%. The button state for axis values of 0% and 100% are always reported as released and pressed, respectively, regardless of the threshold and debounce values.

Switch SwitchIndex DWORD Yes Index in the RawGameController switch array.
SwitchPosition REG_SZ Yes

Indicates the switch position that will cause the mapped button to report that it's being pressed. The position values can be one of these strings:

  • Up
  • UpRight
  • Right
  • DownRight
  • Down
  • DownLeft
  • Left
  • UpLeft
IncludeAdjacent DWORD No Indicates that adjacent switch positions will also cause the mapped button to report that it's being pressed.

Axis mapping

The table below lists the values that are needed to map an axis:

Source Value name Value type Required? Value info
Button MaxValueButtonIndex DWORD Yes

Index in the RawGameController button array which gets translated to the mapped unidirectional axis value.

MaxButton AxisValue
FALSE 0.0
TRUE 1.0
MinValueButtonIndex DWORD No

Indicates that the mapped axis is bidirectional. Values of MaxButton and MinButton are combined into a single bidirectional axis as shown below.

MinButton MaxButton AxisValue
FALSE FALSE 0.5
FALSE TRUE 1.0
TRUE FALSE 0.0
TRUE TRUE 0.5
Axis AxisIndex DWORD Yes Index in the RawGameController axis array.
Invert DWORD No Indicates that the mapped axis value should be inverted before it's returned.
Switch SwitchIndex DWORD Yes Index in the RawGameController switch array.
MaxValueSwitchPosition REG_SZ Yes

One of the following strings:

  • Up
  • UpRight
  • Right
  • DownRight
  • Down
  • DownLeft
  • Left
  • UpLeft

It indicates the position of the switch that causes the mapped axis value to be reported as 1.0. The opposing direction of MaxValueSwitchPosition is treated as 0.0. For example, if MaxValueSwitchPosition is Up, the axis value translation is shown below:

Switch position AxisValue
Up 1.0
Center 0.5
Down 0.0
IncludeAdjacent DWORD No

Indicates that adjacent switch positions will also cause the mapped axis to report 1.0. In the above example, if IncludeAdjacent is set, then the axis translation is done as follows:

Switch position AxisValue
Up 1.0
UpRight 1.0
UpLeft 1.0
Center 0.5
Down 0.0
DownRight 0.0
DownLeft 0.0

Switch mapping

Switch positions can be mapped either from a set of buttons in the buttons array of the RawGameController or from an index in the switches array. Switch positions can't be mapped from axes.

Source Value name Value type Value info
Button ButtonCount DWORD 2, 4, or 8
SwitchKind REG_SZ TwoWay, FourWay, or EightWay
UpButtonIndex DWORD See *ButtonIndex values
DownButtonIndex DWORD
LeftButtonIndex DWORD
RightButtonIndex DWORD
UpRightButtonIndex DWORD
DownRightButtonIndex DWORD
DownLeftButtonIndex DWORD
UpLeftButtonIndex DWORD
Axis SwitchKind REG_SZ TwoWay, FourWay, or EightWay
XAxisIndex DWORD YAxisIndex is always present. XAxisIndex is only present when SwitchKind is FourWay or EightWay.
YAxisIndex DWORD
XDeadZonePercent DWORD Indicate the size of the dead zone around the center position of the axes.
YDeadZonePercent DWORD
XDebouncePercent DWORD Define the size of the windows around the upper and lower dead zone limits, which are used to de-bounce the reported switch state.
YDebouncePercent DWORD
XInvert DWORD Indicate that the corresponding axis values should be inverted before the dead zone and debounce window calculations are applied.
YInvert DWORD
Switch SwitchIndex DWORD Index in the RawGameController switch array.
Invert DWORD Indicates that the switch reports its positions in a counter-clockwise order, rather than the default clockwise order.
PositionBias DWORD

Shifts the starting point of how positions are reported by the specified amount. PositionBias is always counted clockwise from the original starting point, and is applied before the order of values is reversed.

For example, a switch that reports positions starting with DownRight in counter-clockwise order can be normalized by setting the Invert flag and specifying a PositionBias of 5:

Position Reported value After PositionBias and Invert flags
DownRight 0 3
Right 1 2
UpRight 2 1
Up 3 0
UpLeft 4 7
Left 5 6
DownLeft 6 5
Down 7 4

*ButtonIndex values

*ButtonIndex values index into the RawGameController's button array:

ButtonCount SwitchKind RequiredMappings
2 TwoWay
  • UpButtonIndex
  • DownButtonIndex
4 FourWay
  • UpButtonIndex
  • DownButtonIndex
  • LeftButtonIndex
  • RightButtonIndex
4 EightWay
  • UpButtonIndex
  • DownButtonIndex
  • LeftButtonIndex
  • RightButtonIndex
8 EightWay
  • UpButtonIndex
  • DownButtonIndex
  • LeftButtonIndex
  • RightButtonIndex
  • UpRightButtonIndex
  • DownRightButtonIndex
  • DownLeftButtonIndex
  • UpLeftButtonIndex

Properties mapping

These are static mapping values for different mapping types.

Mapping Value name Value type Value info
RacingWheel MaxWheelAngle DWORD Indicates the maximum physical wheel angle supported by the wheel in a single direction. For example, a wheel with a possible rotation of -90 degrees to 90 degrees would specify 90.

Labels

Labels should be present under the Labels key under the device root. Labels can have 3 subkeys: Buttons, Axes, and Switches.

Button labels

The Buttons key maps each of the button positions in the RawGameController's buttons array to a string. Each string is mapped internally to the corresponding GameControllerButtonLabel enum value. For example, if a gamepad has ten buttons and the order in which the RawGameController parses out the buttons and presents them in the buttons report is like this:

Menu,               // Index 0
View,               // Index 1
LeftStickButton,    // Index 2
RightStickButton,   // Index 3
LetterA,            // Index 4
LetterB,            // Index 5
LetterX,            // Index 6
LetterY,            // Index 7
LeftBumper,         // Index 8
RightBumper         // Index 9

The labels should appear in this order under the Buttons key:

Name Value (type: REG_SZ)
Button0 Menu
Button1 View
Button2 LeftStickButton
Button3 RightStickButton
Button4 LetterA
Button5 LetterB
Button6 LetterX
Button7 LetterY
Button8 LeftBumper
Button9 RightBumper

Axis labels

The Axes key will map each of the axis positions in the RawGameController's axis array to one of the labels listed in GameControllerButtonLabel Enum just like the button labels. See the example in Button labels.

Switch labels

The Switches key maps switch positions to labels. The values follow this naming convention: to label a position of a switch, whose index is x in the RawGameController's switch array, add these values under the Switches subkey:

  • SwitchxUp
  • SwitchxUpRight
  • SwitchxRight
  • SwitchxDownRight
  • SwitchxDown
  • SwitchxDownLeft
  • SwitchxUpLeft
  • SwitchxLeft

The following table shows an example set of labels for switch positions of a 4-way switch which shows up at index 0 in the RawGameController:

Name Value (type: REG_SZ)
Switch0Up XboxUp
Switch0Right XboxRight
Switch0Down XboxDown
Switch0Left XboxLeft

Example registry file

To show how all of these mappings and values come together, here is an example registry file for a generic RacingWheel:

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\GameInput\Devices\1234567800010004]
"Description" = "Example Wheel Device"

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\GameInput\Devices\1234567800010004\Labels\Buttons]
"Button0" = "LetterA"
"Button1" = "LetterB"
"Button2" = "LetterX"
"Button3" = "LetterY"
"Button6" = "Menu"
"Button7" = "View"
"Button8" = "RightStickButton"
"Button9" = "LeftStickButton"

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\GameInput\Devices\1234567800010004\Labels\Switches]
"Switch0Down" = "Down"
"Switch0Left" = "Left"
"Switch0Right" = "Right"
"Switch0Up" = "Up"

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\GameInput\Devices\1234567800010004\RacingWheel]
"MaxWheelAngle" = dword:000001c2

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\GameInput\Devices\1234567800010004\RacingWheel\Brake]
"AxisIndex" = dword:00000002
"Invert" = dword:00000001

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\GameInput\Devices\1234567800010004\RacingWheel\Button1]
"ButtonIndex" = dword:00000000

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\GameInput\Devices\1234567800010004\RacingWheel\Button2]
"ButtonIndex" = dword:00000001

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\GameInput\Devices\1234567800010004\RacingWheel\Button3]
"ButtonIndex" = dword:00000002

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\GameInput\Devices\1234567800010004\RacingWheel\Button4]
"ButtonIndex" = dword:00000003

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\GameInput\Devices\1234567800010004\RacingWheel\Button5]
"ButtonIndex" = dword:00000009

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\GameInput\Devices\1234567800010004\RacingWheel\Button6]
"ButtonIndex" = dword:00000008

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\GameInput\Devices\1234567800010004\RacingWheel\Button7]
"ButtonIndex" = dword:00000007

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\GameInput\Devices\1234567800010004\RacingWheel\Button8]
"ButtonIndex" = dword:00000006

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\GameInput\Devices\1234567800010004\RacingWheel\Clutch]
"AxisIndex" = dword:00000003
"Invert" = dword:00000001

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\GameInput\Devices\1234567800010004\RacingWheel\DPadDown]
"IncludeAdjacent" = dword:00000001
"SwitchIndex" = dword:00000000
"SwitchPosition" = "Down"

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\GameInput\Devices\1234567800010004\RacingWheel\DPadLeft]
"IncludeAdjacent" = dword:00000001
"SwitchIndex" = dword:00000000
"SwitchPosition" = "Left"

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\GameInput\Devices\1234567800010004\RacingWheel\DPadRight]
"IncludeAdjacent" = dword:00000001
"SwitchIndex" = dword:00000000
"SwitchPosition" = "Right"

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\GameInput\Devices\1234567800010004\RacingWheel\DPadUp]
"IncludeAdjacent" = dword:00000001
"SwitchIndex" = dword:00000000
"SwitchPosition" = "Up"

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\GameInput\Devices\1234567800010004\RacingWheel\FifthGear]
"ButtonIndex" = dword:00000010

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\GameInput\Devices\1234567800010004\RacingWheel\FirstGear]
"ButtonIndex" = dword:0000000c

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\GameInput\Devices\1234567800010004\RacingWheel\FourthGear]
"ButtonIndex" = dword:0000000f

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\GameInput\Devices\1234567800010004\RacingWheel\NextGear]
"ButtonIndex" = dword:00000004

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\GameInput\Devices\1234567800010004\RacingWheel\PreviousGear]
"ButtonIndex" = dword:00000005

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\GameInput\Devices\1234567800010004\RacingWheel\ReverseGear]
"ButtonIndex" = dword:0000000b

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\GameInput\Devices\1234567800010004\RacingWheel\SecondGear]
"ButtonIndex" = dword:0000000d

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\GameInput\Devices\1234567800010004\RacingWheel\SixthGear]
"ButtonIndex" = dword:00000011

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\GameInput\Devices\1234567800010004\RacingWheel\ThirdGear]
"ButtonIndex" = dword:0000000e

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\GameInput\Devices\1234567800010004\RacingWheel\Throttle]
"AxisIndex" = dword:00000001
"Invert" = dword:00000001

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\GameInput\Devices\1234567800010004\RacingWheel\Wheel]
"AxisIndex" = dword:00000000
"Invert" = dword:00000000

See also