├── .github ├── PULL_REQUEST_TEMPLATE.md └── workflows │ ├── auto-publish.yml │ └── tidy.yml ├── .pr-preview.json ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── ECHIDNA ├── LICENSE.md ├── README.md ├── extensions.html ├── gamepad.html ├── index.html ├── publish ├── gamepad.html └── index.html ├── standard_gamepad.svg ├── tidyconfig.txt └── w3c.json /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | Closes #??? 2 | 3 | The following tasks have been completed: 4 | 5 | * [ ] Modified Web platform tests (link to pull request) 6 | 7 | Implementation commitment: 8 | 9 | * [ ] WebKit (https://bugs.webkit.org/show_bug.cgi?id=) 10 | * [ ] Chromium (https://bugs.chromium.org/p/chromium/issues/detail?id=) 11 | * [ ] Gecko (https://bugzilla.mozilla.org/show_bug.cgi?id=) 12 | -------------------------------------------------------------------------------- /.github/workflows/auto-publish.yml: -------------------------------------------------------------------------------- 1 | name: Node CI 2 | 3 | on: 4 | push: 5 | branches: 6 | - gh-pages 7 | pull_request: {} 8 | 9 | jobs: 10 | ci: 11 | name: Validate and Publish 12 | runs-on: ubuntu-latest 13 | steps: 14 | - uses: actions/checkout@v3 15 | - uses: w3c/spec-prod@v2 16 | with: 17 | VALIDATE_INPUT_MARKUP: true 18 | W3C_ECHIDNA_TOKEN: ${{ secrets.ECHIDNA_TOKEN }} 19 | W3C_WG_DECISION_URL: "https://lists.w3.org/Archives/Public/public-webapps/2014JulSep/0627.html" 20 | W3C_NOTIFICATIONS_CC: "marcos@marcosc.com" 21 | W3C_BUILD_OVERRIDE: | 22 | specStatus: WD 23 | -------------------------------------------------------------------------------- /.github/workflows/tidy.yml: -------------------------------------------------------------------------------- 1 | name: Tidy document 2 | on: 3 | workflow_dispatch: {} 4 | push: 5 | branches: 6 | - gh-pages 7 | paths: 8 | - index.html 9 | 10 | jobs: 11 | tidy: 12 | name: Tidy up 13 | runs-on: macos-latest 14 | steps: 15 | - uses: actions/checkout@v4 16 | - run: brew install tidy-html5 17 | - run: tidy -config tidyconfig.txt -o index.html index.html 18 | - uses: peter-evans/create-pull-request@v6 19 | with: 20 | title: "Tidied up document using tidy-html5" 21 | commit-message: "chore: tidy up index.html" 22 | branch: html-tidy 23 | -------------------------------------------------------------------------------- /.pr-preview.json: -------------------------------------------------------------------------------- 1 | { 2 | "src_file": "index.html", 3 | "type": "respec" 4 | } -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Code of Conduct 2 | 3 | All documentation, code and communication under this repository are covered by the [W3C Code of Ethics and Professional Conduct](https://www.w3.org/Consortium/cepc/). 4 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | Contributions to this repository are intended to become part of Recommendation-track documents governed by the 3 | [W3C Patent Policy](http://www.w3.org/Consortium/Patent-Policy/) and 4 | [Software and Document License](http://www.w3.org/Consortium/Legal/copyright-software). To make substantive contributions to specifications, you must either participate 5 | in the relevant W3C Working Group or make a non-member patent licensing commitment. 6 | 7 | If you are not the sole contributor to a contribution (pull request), please identify all 8 | contributors in the pull request comment. 9 | 10 | To add a contributor (other than yourself, that's automatic), mark them one per line as follows: 11 | 12 | ``` 13 | +@github_username 14 | ``` 15 | 16 | If you added a contributor by mistake, you can remove them in a comment with: 17 | 18 | ``` 19 | -@github_username 20 | ``` 21 | 22 | If you are making a pull request on behalf of someone else but you had no part in designing the 23 | feature, you can remove yourself with the above syntax. 24 | 25 | ## Tests 26 | For normative changes, a corresponding 27 | [web-platform-tests](https://github.com/web-platform-tests/wpt) PR is highly appreciated. Typically, 28 | both PRs will be merged at the same time. Note that a test change that contradicts the spec should 29 | not be merged before the corresponding spec change. If testing is not practical, please explain why 30 | and if appropriate [file a web-platform-tests issue](https://github.com/web-platform-tests/wpt/issues/new) 31 | to follow up later. Add the `type:untestable` or `type:missing-coverage` label as appropriate. 32 | 33 | # Style guide to contributors 34 | 35 | - the spec uses [ReSpec](https://www.w3.org/respec/) 36 | - the spec is tidied using [HTML5 Tidy](https://github.com/w3c/tidy-html5). For 37 | instructions on running HTML5 tidy, see below. 38 | - put comments in front of sections, for better readability with 39 | syntax coloring editors. 40 | 41 | # Running HTML5 Tidy 42 | 43 | Please make sure you have HTML5 tidy installed, instead of 44 | the the one that ships with *nix systems. You can comfirm this by running: 45 | 46 | ```bash 47 | tidy --version #HTML Tidy for HTML5 (experimental) for ... 48 | ``` 49 | Once you have confirmed (make sure you have committed your changes before 50 | running tidy, as the changes are destructive ... in a good way:)): 51 | 52 | ```bash 53 | tidy -config tidyconfig.txt -o index.html index.html 54 | ``` 55 | -------------------------------------------------------------------------------- /ECHIDNA: -------------------------------------------------------------------------------- 1 | index.html?specStatus=WD&shortName=gamepad respec 2 | standard_gamepad.svg 3 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | All documents in this Repository are licensed by contributors 2 | under the 3 | [W3C Software and Document License](http://www.w3.org/Consortium/Legal/copyright-software). -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## 🎮 Gamepad API Specification 2 | 3 | The Gamepad specification defines a low-level interface that represents gamepad devices. 4 | 5 | This repository is for editing drafts and discussion of the [Gamepad](https://w3c.github.io/gamepad/) specification 6 | (and [extensions](https://w3c.github.io/gamepad/extensions.html) to it). 7 | 8 | This specification is part of the [Web Apps WG](https://github.com/w3c/webappswg). 9 | -------------------------------------------------------------------------------- /extensions.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 |[gamepad]
. See
122 | Bugzilla for this specification's open bugs.
123 | 129 | The Gamepad API provides a tightly scoped interface to gamepad devices 130 | and is focused on the most common elements of those devices, namely 131 | axis and button inputs. It specifically excludes support for more 132 | complex devices (e.g., those that do motion tracking or haptic 133 | feedback). 134 |
135 |136 | However, some uses of gamepads (e.g., those paired with Virtual Reality 137 | headsets) rely heavily on those more advanced features. This 138 | supplemetary spec describes extensions to the base API to accommodate 139 | those use cases. If they prove to be broadly useful, the hope is that 140 | they will be eventually merged into the main spec. 141 |
142 |149 | This enum defines the set of possible hands a gamepad may be held by. 150 |
151 |152 | enum GamepadHand { 153 | "", /* unknown, both hands, or not applicable */ 154 | "left", 155 | "right" 156 | }; 157 |158 |
186 | This interface defines the gamepad's position, orientation, velocity, 187 | and acceleration. 188 |
189 |190 | [Exposed=Window] 191 | interface GamepadPose { 192 | readonly attribute boolean hasOrientation; 193 | readonly attribute boolean hasPosition; 194 | 195 | readonly attribute Float32Array? position; 196 | readonly attribute Float32Array? linearVelocity; 197 | readonly attribute Float32Array? linearAcceleration; 198 | readonly attribute Float32Array? orientation; 199 | readonly attribute Float32Array? angularVelocity; 200 | readonly attribute Float32Array? angularAcceleration; 201 | }; 202 |203 |
hasOrientation
attribute MUST return whether the
209 | gamepad is capable of tracking its orientation.
210 | hasPosition
attribute MUST return whether the
216 | gamepad is capable of tracking its position.
217 | 223 | Position of the gamepad as a 3D vector, given in meters from an 224 | origin point, which is determined by the gamepad hardware and MAY 225 | be the position of the gamepad when first polled if no other 226 | reference point is available. The coordinate system uses these axis 227 | definitions, assuming the user is holding the gamepad in the 228 | forward orientation: 229 |
230 |
239 | MUST be null
if the gamepad is incapable of providing
240 | positional data. When not null
, MUST be a
241 | three-element array.
242 |
null
if the sensor is incapable of providing linear
250 | velocity. When not null
, MUST be a three-element array.
251 | null
if the sensor is incapable of providing linear
258 | acceleration. When not null
, MUST be a three-element
259 | array.
260 | [0, 0, 0, 1]
is considered to be forward
.
267 | The forward direction MUST be determined by the gamepad hardware. The
268 | forward direction MAY be the orientation of the hardware when it was
269 | first polled if no other reference orientation is available. If the
270 | sensor is incapable of providing orientation data, the orientation
271 | MUST be null
. When not null
, the
272 | orientation
MUST be a four-element array.
273 | null
if the sensor is incapable of providing angular
280 | velocity. When not null
, the
281 | angularVelocity
MUST be a three-element array.
282 | null
if the sensor is incapable of providing angular
289 | acceleration. When not null
,
290 | angularAcceleration
MUST be a three-element array.
291 | 299 | This partial interface supplements the Gamepad interface described in 300 | the main Gamepad spec. 301 |
302 |303 | partial interface Gamepad { 304 | readonly attribute GamepadHand hand; 305 | readonly attribute FrozenArray<GamepadHapticActuator> hapticActuators; 306 | readonly attribute GamepadPose? pose; 307 | }; 308 |309 |
310 | Instances of {{Gamepad}} are created with the internal slots described 311 | in the following table: 312 |
313 |316 | Internal slot 317 | | 318 |319 | Initial value 320 | | 321 |322 | Description (non-normative) 323 | | 324 |
---|---|---|
327 | [[\hand]] 328 | | 329 |330 | `undefined` 331 | | 332 |333 | Indicates the hand the controller is held in. 334 | | 335 |
338 | [[\hapticActuators]] 339 | | 340 |341 | `undefined` 342 | | 343 |344 | List of all the haptic actuators in the gamepad. 345 | | 346 |
349 | [[\pose]] 350 | | 351 |352 | `null` 353 | | 354 |355 | The current pose of the gamepad. 356 | | 357 |
389 | This section supplements the Receiving 391 | inputs section of the main Gamepad specification. 393 |
394 |400 | This section supplements the Constructing 402 | a `Gamepad` section of the main Gamepad specification. 404 |
405 |412 | This partial interface supplements the {{GamepadHapticActuator}} 413 | interface described in the main Gamepad spec. 415 |
416 |417 | [Exposed=Window] 418 | partial interface GamepadHapticActuator { 419 | Promise<boolean> pulse(double value, double duration); 420 | }; 421 |422 |
428 | {{GamepadHapticActuator/pulse()}} applies a |value:double| to the
429 | actuator for duration milliseconds. The value
430 | passed to pulse()
is clamped to limits defined by the
431 | actuator type. The returned Promise will resolve true
432 | once the pulse has completed.
433 |
435 | Repeated calls to pulse()
override the previous
436 | values.
437 |
445 |
446 |
447 |
448 |
449 |
450 |
535 | Copyright © 536 | 2015 537 | 538 | W3C® 539 | (MIT, 540 | ERCIM, 541 | Keio, Beihang). 542 | 543 | W3C liability, 544 | trademark and 545 | 546 | document use 547 | 548 | rules apply. 549 |
550 | 551 | 552 |555 | The Gamepad specification defines a low-level interface that represents 556 | gamepad devices. 557 |
562 | This section describes the status of this document at the time of its publication. 563 | Other documents may supersede this document. A list of current W3C publications and the 564 | latest revision of this technical report can be found in the W3C technical reports index at 565 | http://www.w3.org/TR/. 566 |
567 | 568 | 569 | If you have comments for this spec, please send them to 570 | public-webapps@w3.org 571 | with a Subject: prefix of[gamepad]
. See
572 | Bugzilla
573 | for this specification's open bugs.
574 |
575 |
576 | 577 | This document was published by the Web Applications Working Group as a Working Draft. 578 | 579 | This document is intended to become a W3C Recommendation. 580 | 581 | 582 | If you wish to make comments regarding this document, please send them to 583 | public-webapps@w3.org 584 | (subscribe, 585 | archives). 586 | 587 | 588 | 589 | 590 | 591 | 592 | All comments are welcome. 593 | 594 | 595 |
596 | 597 | 598 | 599 |600 | Publication as a Working Draft does not imply endorsement by the W3C 601 | Membership. This is a draft document and may be updated, replaced or obsoleted by other 602 | documents at any time. It is inappropriate to cite this document as other than work in 603 | progress. 604 |
605 | 606 | 607 | 608 |609 | 610 | This document was produced by a group operating under the 611 | 5 February 2004 W3C Patent 612 | Policy. 613 | 614 | 615 | 616 | 617 | W3C maintains a public list of any patent 618 | disclosures 619 | 620 | made in connection with the deliverables of the group; that page also includes 621 | instructions for disclosing a patent. An individual who has actual knowledge of a patent 622 | which the individual believes contains 623 | Essential 624 | Claim(s) must disclose the information in accordance with 625 | section 626 | 6 of the W3C Patent Policy. 627 | 628 | 629 |
630 | 631 |This document is governed by the 1 August 2014 W3C Process Document. 632 |
633 | 634 | 635 | 636 | 637 | 638 |This section is non-normative.
645 | 646 |Some user agents have connected gamepad devices. These devices 647 | are desirable and suited to input for gaming applications, and for 648 | "10 foot" user interfaces (presentations, media viewers).
649 | 650 |Currently, the only way for a gamepad to be used as input would be 651 | to emulate mouse or keyboard events, however this would lose information 652 | and require additional software outside of the user agent to 653 | accomplish emulation.
654 | 655 |Meanwhile, native applications are capable of accessing these devices 656 | via system APIs.
657 | 658 |The Gamepad API provides a solution to this problem by specifying 659 | interfaces that allow web applications to directly act on gamepad 660 | data.
661 | 662 |This specification references interfaces from a number of other 663 | specifications:
664 | 665 |676 | As well as sections marked as non-normative, all authoring guidelines, diagrams, examples, 677 | and notes in this specification are non-normative. Everything else in this specification is 678 | normative. 679 |
680 |The key words MUST, MUST NOT, RECOMMENDED, and SHOULD are 681 | to be interpreted as described in [RFC2119]. 682 |
683 | 684 |685 | This specification defines conformance criteria that apply to a single 686 | product: the user agent that implements 687 | the interfaces that it contains. 688 |
689 | 690 |691 | Implementations that use ECMAScript to implement the APIs defined in 692 | this specification MUST implement them in a manner consistent with the 693 | ECMAScript Bindings defined in the Web IDL specification [WEBIDL] as 694 | this specification uses that specification and terminology. 695 |
696 | 697 |698 | A conforming implementation is required to implement all fields 699 | defined in this specification. 700 |
701 |Interfacing with external devices designed to control games has the 708 | potential to become large and intractable if approached in full 709 | generality. In this specification we explicitly choose to narrow scope 710 | to provide a useful subset of functionality that can be widely 711 | implemented and broadly useful.
712 | 713 |Specifically, we choose to only support the functionality required to 714 | support gamepads. Support for gamepads requires two input types: buttons 715 | and axes. Both buttons and axes are reported as analog values, buttons 716 | ranging from [0..1], and axes ranging from [-1..1].
717 | 718 |While the primary goal is support for gamepad devices, supporting 719 | these two types of analog inputs allows support for other similar devices 720 | common to current gaming systems including joysticks, driving wheels, 721 | pedals, and accelerometers. As such, the name "gamepad" is exemplary 722 | rather than trying to be a generic name for the entire set of devices 723 | addressed by this specification.
724 | 725 |We specifically exclude support for more complex devices that may also 726 | be used in some gaming contexts, including those that that do motion 727 | sensing, depth sensing, video analysis, gesture recognition, and so 728 | on.
729 | 730 |735 | This interface defines an individual gamepad device. 736 |
737 | 738 |interface Gamepad {
739 | readonly attribute DOMString id;
740 | readonly attribute long index;
741 | readonly attribute boolean connected;
742 | readonly attribute DOMHighResTimeStamp timestamp;
743 | readonly attribute GamepadMappingType
mapping;
744 | readonly attribute double[] axes;
745 | readonly attribute GamepadButton
[] buttons;
746 | };
axes
of type array of double, readonly connected
of type boolean, readonly connected
attribute MUST be set to false.
775 | id
of type DOMString, readonly index
of type long, readonly mapping
of type GamepadMappingType
, readonly "standard"
, which corresponds
799 | to the Standard Gamepad layout.
800 |
801 | If the user agent does not have knowledge of the device layout
802 | and is simply providing the controls as represented by the
803 | driver in use, then it MUST set the mapping
property
804 | to an empty string.
805 | timestamp
of type DOMHighResTimeStamp, readonly axes
and button
data
810 | have been updated from the hardware. The value must be relative to
811 | the navigationStart
attribute of the PerformanceTiming
812 | interface. Since values are monotonically increasing they can be
813 | compared to determine the ordering of updates, as newer values will
814 | always be greater than or equal to older values.
815 |
816 | If no data has been received from the hardware, the value of
817 | the timestamp
attribute should be the time relative
818 | to navigationStart
when the Gamepad object was first
819 | made available to script.
820 | 861 | This enum defines the set of known mappings for a Gamepad. 862 |
863 | 864 |enum GamepadMappingType {
865 | "_",
866 | "standard"
867 | };
Enumeration description | |
---|---|
| 868 | The empty string indicates that no mapping is in use for this gamepad. 869 | Note: the WebIDL here is currently wrong due to a ReSpec bug. The actual enum value is the empty string (""). 870 | |
standard | 871 | The Gamepad's controls have been mapped to the 872 | Standard Gamepad layout. 873 | |
[Constructor(GamepadEventInit eventInitDict)]
923 | interface GamepadEvent : Event {
924 | readonly attribute Gamepad
gamepad;
925 | };
gamepad
of type Gamepad
, readonly dictionary GamepadEventInit : EventInit {
932 | required Gamepad gamepad;
933 | };
GamepadEventInit
Membersgamepad
of type required Gamepad942 | 943 | Each device manufacturer creates many different products and each has 944 | unique styles and layouts of buttons and axes. It is intended that the 945 | user agent support as many of these as possible. 946 | 947 |
948 | 949 |950 | 951 | Additionally there are de facto standard layouts that have 952 | been made popular by game consoles. When the user agent 953 | recognizes the attached device, it is RECOMMENDED that it be remapped 954 | to a canonical ordering when possible. Devices that are not recognized 955 | should still be exposed in their raw form. 956 | 957 |
958 | 959 |
960 |
961 | There is currently one canonical device, the "Standard
962 | Gamepad". The standard gamepad has 4 axes, and up to 17 buttons.
963 | When remapping, the indices in axes[]
964 | and buttons[]
965 | should correspond as closely as possible to the physical locations in
966 | the diagram below. Additionally, the
967 | mapping
property of the Gamepad SHOULD be set to the
968 | string "standard"
.
969 |
This section is non-normative.
977 | 978 |979 | 980 | The example below demonstrates typical access to gamepads. Note 981 | the relationship with the WindowAnimationTiming 982 | interface. 983 |
984 | 985 |function runAnimation() 987 | { 988 | window.requestAnimationFrame(runAnimation); 989 | 990 | var gamepads = navigator.getGamepads(); 991 | 992 | for (var i = 0; i < gamepads.length; ++i) 993 | { 994 | var pad = gamepads[i]; 995 | // todo; simple demo of displaying pad.axes and pad.buttons 996 | } 997 | } 998 | 999 | window.requestAnimationFrame(runAnimation);
1004 | Best Practice 1: Coordination with 1005 | WindowAnimationTiming
1006 |1007 | 1008 | Interactive applications will typically be using the 1009 | WindowAnimationTiming interface to drive animation, and 1010 | will want coordinate animation with user gamepad input. As 1011 | such, the gamepad data should be polled as closely as possible 1012 | to immediately before the animation callbacks are executed, and 1013 | with frequency matching that of the animation. That is, if the 1014 | animation callbacks are running at 60Hz, the gamepad inputs 1015 | should also be sampled at that rate. 1016 | 1017 |
1018 |
1028 | User agents implementing this specification must provide a new DOM
1029 | event, named gamepadconnected
. The corresponding event
1030 | MUST be of type GamepadEvent
and MUST fire on the
1031 | window
object. Registration for and firing of the
1032 | gamepadconnected
event MUST follow the usual behavior
1033 | of DOM4 Events. [DOM4]
1034 |
1037 | A user agent MUST dispatch this event type to indicate the 1038 | user has connected a gamepad. If a gamepad was already connected 1039 | when the page was loaded, the gamepadconnected event SHOULD be 1040 | dispatched when the user presses a button or moves an axis. 1041 |
1042 | 1043 |
1050 | User agents implementing this specification must provide a new DOM
1051 | event, named gamepaddisconnected
. The corresponding event
1052 | MUST be of type GamepadEvent
and MUST fire on the
1053 | window
object. Registration for and firing of the
1054 | gamepaddisconnected
event MUST follow the usual behavior
1055 | of DOM4 Events. [DOM4]
1056 |
1059 | When a gamepad is disconnected from the user agent, if the 1060 | user agent has previously dispatched a 1061 | gamepadconnected event for that gamepad to a window, a 1062 | gamepaddisconnected event MUST be dispatched to that same 1063 | window. 1064 |
1065 | 1066 |
1073 |
1074 | More discussion needed, on whether to include or exclude axis and button
1075 | changed events, and whether to roll them more together
1076 | (gamepadchanged
?), separate somewhat
1077 | (gamepadaxischanged
?), or separate by individual axis
1078 | and button.
1079 |
1080 |
This section is non-normative.
1086 |1087 | Many have made contributions in code, comments, or documentation: 1088 |
1089 |1098 | Please let me know if I have inadvertently omitted your name. 1099 |
1100 |