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.
|
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:
|
|
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.
|
|||||||||||||||
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.
|
||||||||||||||||
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:
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:
|
||||||||||||||||
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 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:
|
*ButtonIndex values
*ButtonIndex values index into the RawGameController's button array:
ButtonCount | SwitchKind | RequiredMappings |
---|---|---|
2 | TwoWay |
|
4 | FourWay |
|
4 | EightWay |
|
8 | EightWay |
|
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
Feedback
https://aka.ms/ContentUserFeedback.
Coming soon: Throughout 2024 we will be phasing out GitHub Issues as the feedback mechanism for content and replacing it with a new feedback system. For more information see:Submit and view feedback for