@antha/gamepad-type 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. package/LICENSE-CC0 +121 -0
  2. package/LICENSE-MIT +21 -0
  3. package/README.md +102 -0
  4. package/dist/create.d.ts +10 -0
  5. package/dist/create.js +20 -0
  6. package/dist/default-layouts.d.ts +8 -0
  7. package/dist/default-layouts.js +339 -0
  8. package/dist/default-models.d.ts +14 -0
  9. package/dist/default-models.js +46 -0
  10. package/dist/demo/elements/gamepad/vir-gamepad-axe.element.d.ts +7 -0
  11. package/dist/demo/elements/gamepad/vir-gamepad-axe.element.js +61 -0
  12. package/dist/demo/elements/gamepad/vir-gamepad-button.element.d.ts +7 -0
  13. package/dist/demo/elements/gamepad/vir-gamepad-button.element.js +87 -0
  14. package/dist/demo/elements/gamepad/vir-gamepad-input.element.d.ts +7 -0
  15. package/dist/demo/elements/gamepad/vir-gamepad-input.element.js +38 -0
  16. package/dist/demo/elements/gamepad/vir-gamepad-inputs.element.d.ts +20 -0
  17. package/dist/demo/elements/gamepad/vir-gamepad-inputs.element.js +110 -0
  18. package/dist/demo/elements/gamepad/vir-gamepad-name.element.d.ts +11 -0
  19. package/dist/demo/elements/gamepad/vir-gamepad-name.element.js +158 -0
  20. package/dist/demo/elements/gamepad/vir-gamepad.element.d.ts +8 -0
  21. package/dist/demo/elements/gamepad/vir-gamepad.element.js +41 -0
  22. package/dist/demo/elements/modals/vir-create-new-type.modal.element.d.ts +9 -0
  23. package/dist/demo/elements/modals/vir-create-new-type.modal.element.js +135 -0
  24. package/dist/demo/elements/modals/vir-edit-mappings.modal.element.d.ts +29 -0
  25. package/dist/demo/elements/modals/vir-edit-mappings.modal.element.js +185 -0
  26. package/dist/demo/elements/modals/vir-modal.element.d.ts +3 -0
  27. package/dist/demo/elements/modals/vir-modal.element.js +88 -0
  28. package/dist/demo/elements/vir-demo.element.d.ts +27 -0
  29. package/dist/demo/elements/vir-demo.element.js +469 -0
  30. package/dist/demo/events/modal-close.event.d.ts +1 -0
  31. package/dist/demo/events/modal-close.event.js +2 -0
  32. package/dist/demo/events/selected-gamepad-index-change.event.d.ts +1 -0
  33. package/dist/demo/events/selected-gamepad-index-change.event.js +2 -0
  34. package/dist/demo/gamepad-brand-color.d.ts +1 -0
  35. package/dist/demo/gamepad-brand-color.js +14 -0
  36. package/dist/demo/global-vars.d.ts +6 -0
  37. package/dist/demo/global-vars.js +3 -0
  38. package/dist/demo/overrides.d.ts +7 -0
  39. package/dist/demo/overrides.js +1 -0
  40. package/dist/demo/sentry-setup.d.ts +1 -0
  41. package/dist/demo/sentry-setup.js +11 -0
  42. package/dist/demo/util/casing.d.ts +1 -0
  43. package/dist/demo/util/casing.js +7 -0
  44. package/dist/demo/util/check-changes.d.ts +6 -0
  45. package/dist/demo/util/check-changes.js +28 -0
  46. package/dist/demo/util/local-save-data.d.ts +9 -0
  47. package/dist/demo/util/local-save-data.js +36 -0
  48. package/dist/demo/util/user-agent.d.ts +6 -0
  49. package/dist/demo/util/user-agent.js +2 -0
  50. package/dist/demo/util/window-listener.d.ts +1 -0
  51. package/dist/demo/util/window-listener.js +6 -0
  52. package/dist/find-matches.d.ts +42 -0
  53. package/dist/find-matches.js +77 -0
  54. package/dist/gamepad-layout.d.ts +29 -0
  55. package/dist/gamepad-layout.js +1 -0
  56. package/dist/gamepad-model.d.ts +67 -0
  57. package/dist/gamepad-model.js +69 -0
  58. package/dist/index.d.ts +8 -0
  59. package/dist/index.js +8 -0
  60. package/dist/known-input.d.ts +126 -0
  61. package/dist/known-input.js +128 -0
  62. package/dist/system-versions.d.ts +25 -0
  63. package/dist/system-versions.js +26 -0
  64. package/dist/util/lowercase-keys.d.ts +2 -0
  65. package/dist/util/lowercase-keys.js +10 -0
  66. package/package.json +67 -0
@@ -0,0 +1,42 @@
1
+ import { type GamepadDevice, type InputDevice } from 'input-device-handler';
2
+ import { type GamepadLayout } from './gamepad-layout.js';
3
+ import { type GamepadBrandMap, type GamepadModelMap } from './gamepad-model.js';
4
+ import { type SystemVersions } from './system-versions.js';
5
+ /**
6
+ * Given a gamepad name, tries to find the best matching predefined or custom gamepad layout based
7
+ * on system versions. Returns undefined if no possible matches are found.
8
+ *
9
+ * @category Main
10
+ */
11
+ export declare function findMatchingGamepadLayout({ gamepad, layouts, gamepadModelMap, systemVersions, }: {
12
+ /** The gamepad to match for. */
13
+ gamepad: Readonly<Pick<GamepadDevice, 'deviceName'>> | string | undefined;
14
+ /** Provide custom layouts. Defaults to this package's predefined layouts. */
15
+ layouts?: ReadonlyArray<Readonly<GamepadLayout>>;
16
+ /** Provide custom gamepad model maps. Defaults to this package's predefined model map. */
17
+ gamepadModelMap?: Readonly<GamepadModelMap>;
18
+ /** Provide custom system versions. Defaults to the current system's system versions. */
19
+ systemVersions?: Readonly<SystemVersions>;
20
+ }): GamepadLayout | undefined;
21
+ /**
22
+ * Find matching gamepad model, brand, and description. Will return PredefinedGamepadModel.Unknown,
23
+ * PredefinedGamepadBrand.Unknown, and an empty string respectively if the given gamepad name is not
24
+ * known.
25
+ *
26
+ * @category Main
27
+ */
28
+ export declare function findMatchingGamepadModel({ gamepad: gamepadNameOrDevice, gamepadModelMap, gamepadBrandMap, }: {
29
+ /**
30
+ * Either the gamepad's id / name or a gamepad object returned from the input-device-handler
31
+ * package.
32
+ */
33
+ gamepad: string | Readonly<Pick<InputDevice, 'deviceName'>> | undefined;
34
+ /** Defaults to the predefined internal model map. */
35
+ gamepadModelMap?: Readonly<GamepadModelMap> | undefined;
36
+ /** Defaults to the predefined internal brand map. */
37
+ gamepadBrandMap?: Readonly<GamepadBrandMap> | undefined;
38
+ }): {
39
+ gamepadModel: string | undefined;
40
+ gamepadBrand: string | undefined;
41
+ gamepadModelDescription: string | undefined;
42
+ };
@@ -0,0 +1,77 @@
1
+ import { check } from '@augment-vir/assert';
2
+ import { mapObjectValues } from '@augment-vir/common';
3
+ import { defaultGamepadLayouts } from './default-layouts.js';
4
+ import { defaultGamepadBrandMap, defaultGamepadModelMap } from './default-models.js';
5
+ import { predefinedGamepadModelDescriptions, } from './gamepad-model.js';
6
+ import { getSystemVersions } from './system-versions.js';
7
+ import { makeObjectKeysLowercase } from './util/lowercase-keys.js';
8
+ /**
9
+ * Given a gamepad name, tries to find the best matching predefined or custom gamepad layout based
10
+ * on system versions. Returns undefined if no possible matches are found.
11
+ *
12
+ * @category Main
13
+ */
14
+ export function findMatchingGamepadLayout({ gamepad, layouts = defaultGamepadLayouts, gamepadModelMap = defaultGamepadModelMap, systemVersions = getSystemVersions(), }) {
15
+ const gamepadName = (check.isString(gamepad) ? gamepad : gamepad?.deviceName) || '';
16
+ const { gamepadModel } = findMatchingGamepadModel({
17
+ gamepad: gamepadName,
18
+ gamepadModelMap,
19
+ });
20
+ // filter by gamepad model
21
+ const byGamepadModel = gamepadModel
22
+ ? layouts.filter((layout) => {
23
+ return layout.gamepadModels.includes(gamepadModel);
24
+ })
25
+ : [];
26
+ if (byGamepadModel.length <= 1) {
27
+ return byGamepadModel[0];
28
+ }
29
+ // filter by highest scoring system version match
30
+ const byLayoutScore = byGamepadModel.reduce((highestScoring, currentLayout) => {
31
+ const score = scoreLayoutSystemVersions(systemVersions, currentLayout);
32
+ if (score > highestScoring.score) {
33
+ return {
34
+ score,
35
+ layout: currentLayout,
36
+ };
37
+ }
38
+ else {
39
+ return highestScoring;
40
+ }
41
+ }, {
42
+ layout: undefined,
43
+ score: -1,
44
+ });
45
+ return byLayoutScore.layout;
46
+ }
47
+ /** Gives a score to the layout based on how closely it matches the current system. */
48
+ function scoreLayoutSystemVersions(systemVersions, layout) {
49
+ const scores = layout.systemVersions.map((layoutSystemVersions) => {
50
+ const matches = Object.values(mapObjectValues(systemVersions, (key, value) => {
51
+ return layoutSystemVersions[key].toLowerCase() === value.toLowerCase();
52
+ }));
53
+ return matches.reduce((sum, match) => {
54
+ return sum + (match ? 1 : 0);
55
+ }, 0);
56
+ });
57
+ return Math.max(...scores);
58
+ }
59
+ /**
60
+ * Find matching gamepad model, brand, and description. Will return PredefinedGamepadModel.Unknown,
61
+ * PredefinedGamepadBrand.Unknown, and an empty string respectively if the given gamepad name is not
62
+ * known.
63
+ *
64
+ * @category Main
65
+ */
66
+ export function findMatchingGamepadModel({ gamepad: gamepadNameOrDevice, gamepadModelMap = defaultGamepadModelMap, gamepadBrandMap = defaultGamepadBrandMap, }) {
67
+ const gamepadName = (typeof gamepadNameOrDevice === 'string'
68
+ ? gamepadNameOrDevice
69
+ : gamepadNameOrDevice?.deviceName) || undefined;
70
+ const gamepadModel = (gamepadName && makeObjectKeysLowercase(gamepadModelMap)[gamepadName.toLowerCase()]) ||
71
+ undefined;
72
+ return {
73
+ gamepadModel,
74
+ gamepadBrand: (gamepadModel && makeObjectKeysLowercase(gamepadBrandMap)[gamepadModel]) || undefined,
75
+ gamepadModelDescription: (gamepadModel && predefinedGamepadModelDescriptions[gamepadModel]) || undefined,
76
+ };
77
+ }
@@ -0,0 +1,29 @@
1
+ import { type PartialWithUndefined } from '@augment-vir/common';
2
+ import { type SystemVersions } from './system-versions.js';
3
+ /**
4
+ * A mapping of gamepad button and axe numbers to their names. Mappings depend on the current system
5
+ * and gamepad model (so those are included as well).
6
+ *
7
+ * @category Types
8
+ */
9
+ export type GamepadLayout = {
10
+ /**
11
+ * The list of supported gamepad models for this layout. These are _mapped_ model names, not the
12
+ * raw device names or gamepad ids directly from the browser.
13
+ */
14
+ gamepadModels: string[];
15
+ systemVersions: SystemVersions[];
16
+ inputMappings: Record<string, string>;
17
+ notes?: PartialWithUndefined<{
18
+ /**
19
+ * A simple note with an explanation that does not significantly impact the gamepad's
20
+ * performance.
21
+ */
22
+ info: string;
23
+ /**
24
+ * An important note that explains why the gamepad does not work or why it has has
25
+ * major issues.
26
+ */
27
+ warning: string;
28
+ }> | undefined;
29
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,67 @@
1
+ /**
2
+ * Mapping from Gamepad ids or names to model strings.
3
+ *
4
+ * @category Types
5
+ */
6
+ export type GamepadModelMap = Readonly<{
7
+ [GamepadId in string]: string | PredefinedGamepadModel;
8
+ }>;
9
+ /**
10
+ * Mapping from Gamepad ids or names to brand strings.
11
+ *
12
+ * @category Types
13
+ */
14
+ export type GamepadBrandMap = Readonly<{
15
+ [GamepadId in string]: string | PredefinedGamepadBrand;
16
+ }>;
17
+ /**
18
+ * All gamepad models known and defined by the
19
+ * [gamepad-type](https://www.npmjs.com/package/gamepad-type) package. It contains a new entry for
20
+ * each gamepad generation that features different button layouts.
21
+ *
22
+ * Note that any consumer of the [gamepad-type](https://www.npmjs.com/package/gamepad-type) package
23
+ * is able to freely define their own models as well, this is merely the _pre_ defined set of
24
+ * models.
25
+ *
26
+ * See {@link predefinedGamepadModelDescriptions} for comments on what each model is.
27
+ *
28
+ * @category Defaults
29
+ */
30
+ export declare enum PredefinedGamepadModel {
31
+ SwitchPro = "switch-pro",
32
+ PlaystationDualShock = "playstation-dual-shock",
33
+ PlaystationDualShock4 = "playstation-dual-shock-4",
34
+ PlaystationDualSense = "playstation-dual-sense",
35
+ SteamDeck = "steam-deck",
36
+ Xbox360 = "xbox-360",
37
+ XboxWireless = "xbox-wireless"
38
+ }
39
+ /**
40
+ * A map of {@link PredefinedGamepadModel} to pretty user facing names.
41
+ *
42
+ * @category Defaults
43
+ */
44
+ export declare const fancyGamepadModelName: Record<PredefinedGamepadModel, string>;
45
+ /**
46
+ * Gamepad brands known and defined by the
47
+ * [gamepad-type](https://www.npmjs.com/package/gamepad-type) package.
48
+ *
49
+ * Note that any consumer of the [gamepad-type](https://www.npmjs.com/package/gamepad-type) package
50
+ * is able to freely define their own brands as well, this is merely the _pre_ defined set of
51
+ * brands.
52
+ *
53
+ * @category Defaults
54
+ */
55
+ export declare enum PredefinedGamepadBrand {
56
+ Microsoft = "microsoft",
57
+ Nintendo = "nintendo",
58
+ Sony = "sony",
59
+ Valve = "valve"
60
+ }
61
+ /**
62
+ * Description of each gamepad model predefined by the
63
+ * [gamepad-type](https://www.npmjs.com/package/gamepad-type) package.
64
+ *
65
+ * @category Defaults
66
+ */
67
+ export declare const predefinedGamepadModelDescriptions: Readonly<Record<string, string>>;
@@ -0,0 +1,69 @@
1
+ /**
2
+ * All gamepad models known and defined by the
3
+ * [gamepad-type](https://www.npmjs.com/package/gamepad-type) package. It contains a new entry for
4
+ * each gamepad generation that features different button layouts.
5
+ *
6
+ * Note that any consumer of the [gamepad-type](https://www.npmjs.com/package/gamepad-type) package
7
+ * is able to freely define their own models as well, this is merely the _pre_ defined set of
8
+ * models.
9
+ *
10
+ * See {@link predefinedGamepadModelDescriptions} for comments on what each model is.
11
+ *
12
+ * @category Defaults
13
+ */
14
+ export var PredefinedGamepadModel;
15
+ (function (PredefinedGamepadModel) {
16
+ PredefinedGamepadModel["SwitchPro"] = "switch-pro";
17
+ PredefinedGamepadModel["PlaystationDualShock"] = "playstation-dual-shock";
18
+ PredefinedGamepadModel["PlaystationDualShock4"] = "playstation-dual-shock-4";
19
+ PredefinedGamepadModel["PlaystationDualSense"] = "playstation-dual-sense";
20
+ PredefinedGamepadModel["SteamDeck"] = "steam-deck";
21
+ PredefinedGamepadModel["Xbox360"] = "xbox-360";
22
+ PredefinedGamepadModel["XboxWireless"] = "xbox-wireless";
23
+ })(PredefinedGamepadModel || (PredefinedGamepadModel = {}));
24
+ /**
25
+ * A map of {@link PredefinedGamepadModel} to pretty user facing names.
26
+ *
27
+ * @category Defaults
28
+ */
29
+ export const fancyGamepadModelName = {
30
+ [PredefinedGamepadModel.SwitchPro]: 'Switch Pro Controller',
31
+ [PredefinedGamepadModel.PlaystationDualShock]: 'PlayStation DualShock',
32
+ [PredefinedGamepadModel.PlaystationDualShock4]: 'PlayStation DualShock 4',
33
+ [PredefinedGamepadModel.PlaystationDualSense]: 'PlayStation DualSense',
34
+ [PredefinedGamepadModel.SteamDeck]: 'Steam Deck',
35
+ [PredefinedGamepadModel.Xbox360]: 'Xbox 360',
36
+ [PredefinedGamepadModel.XboxWireless]: 'Xbox Wireless',
37
+ };
38
+ /**
39
+ * Gamepad brands known and defined by the
40
+ * [gamepad-type](https://www.npmjs.com/package/gamepad-type) package.
41
+ *
42
+ * Note that any consumer of the [gamepad-type](https://www.npmjs.com/package/gamepad-type) package
43
+ * is able to freely define their own brands as well, this is merely the _pre_ defined set of
44
+ * brands.
45
+ *
46
+ * @category Defaults
47
+ */
48
+ export var PredefinedGamepadBrand;
49
+ (function (PredefinedGamepadBrand) {
50
+ PredefinedGamepadBrand["Microsoft"] = "microsoft";
51
+ PredefinedGamepadBrand["Nintendo"] = "nintendo";
52
+ PredefinedGamepadBrand["Sony"] = "sony";
53
+ PredefinedGamepadBrand["Valve"] = "valve";
54
+ })(PredefinedGamepadBrand || (PredefinedGamepadBrand = {}));
55
+ /**
56
+ * Description of each gamepad model predefined by the
57
+ * [gamepad-type](https://www.npmjs.com/package/gamepad-type) package.
58
+ *
59
+ * @category Defaults
60
+ */
61
+ export const predefinedGamepadModelDescriptions = {
62
+ [PredefinedGamepadModel.SwitchPro]: 'Nintendo Switch Pro gamepad for the Nintendo Switch console.',
63
+ [PredefinedGamepadModel.PlaystationDualSense]: 'Sony PlayStation DualSense gamepad for the Sony PlayStation 5 console.',
64
+ [PredefinedGamepadModel.PlaystationDualShock]: 'Sony PlayStation DualShock gamepad for the Sony PlayStation 1 through Sony PlayStation 3 consoles.',
65
+ [PredefinedGamepadModel.PlaystationDualShock4]: 'Sony PlayStation DualShock 4 gamepad for the Sony PlayStation 4 console.',
66
+ [PredefinedGamepadModel.SteamDeck]: 'Gamepad for the Valve Steam Deck handheld console.',
67
+ [PredefinedGamepadModel.Xbox360]: 'Microsoft Xbox 360 gamepad for the Microsoft Xbox 360 console. Can be wired or wireless.',
68
+ [PredefinedGamepadModel.XboxWireless]: 'Microsoft Xbox Wireless gamepad for Microsoft Xbox One through Xbox Series X/S consoles.',
69
+ };
@@ -0,0 +1,8 @@
1
+ export * from './create.js';
2
+ export * from './default-layouts.js';
3
+ export * from './default-models.js';
4
+ export * from './find-matches.js';
5
+ export * from './gamepad-layout.js';
6
+ export * from './gamepad-model.js';
7
+ export * from './known-input.js';
8
+ export * from './system-versions.js';
package/dist/index.js ADDED
@@ -0,0 +1,8 @@
1
+ export * from './create.js';
2
+ export * from './default-layouts.js';
3
+ export * from './default-models.js';
4
+ export * from './find-matches.js';
5
+ export * from './gamepad-layout.js';
6
+ export * from './gamepad-model.js';
7
+ export * from './known-input.js';
8
+ export * from './system-versions.js';
@@ -0,0 +1,126 @@
1
+ /**
2
+ * Consolidated (as much as possible across each brand ) known inputs.
3
+ *
4
+ * @category Util
5
+ */
6
+ export declare enum KnownInput {
7
+ /** A on Xbox and Nintendo, X on Playstation. */
8
+ FaceAccept = "face-accept",
9
+ /** B on Xbox and Nintendo, Circle on Playstation. */
10
+ FaceCancel = "face-cancel",
11
+ /** X on Xbox and Nintendo, Square on Playstation. */
12
+ FaceAlt1 = "face-alt-1",
13
+ /** Y on Xbox and Nintendo, Triangle on Playstation. */
14
+ FaceAlt2 = "face-alt-2",
15
+ /** The top left trigger area button. */
16
+ L1 = "L1",
17
+ /** The bottom left trigger area button. */
18
+ L2 = "L2",
19
+ /** Left stick click. */
20
+ L3 = "L3",
21
+ /** The top right trigger area button. */
22
+ R1 = "R1",
23
+ /** The bottom right trigger area button. */
24
+ R2 = "R2",
25
+ /** Right stick click. */
26
+ R3 = "R3",
27
+ LeftStickX = "left-stick-x",
28
+ LeftStickY = "left-stick-y",
29
+ RightStickX = "right-stick-x",
30
+ RightStickY = "right-stick-y",
31
+ DPad = "d-pad",
32
+ DPadDown = "d-pad-down",
33
+ DPadLeft = "d-pad-left",
34
+ DPadRight = "d-pad-right",
35
+ DPadUp = "d-pad-up",
36
+ /** The primary center button to the left of the controller logo. */
37
+ Select = "select",
38
+ /** The button which is also the controller brand's logo. */
39
+ Logo = "logo",
40
+ /** The primary center button to the right of the controller logo. */
41
+ Start = "start",
42
+ /** Only exists on Nintendo controllers. */
43
+ Capture = "capture",
44
+ /** Only exists on Nintendo controllers. */
45
+ Home = "home",
46
+ /** Only exists on Playstation controllers. */
47
+ Mute = "mute",
48
+ /**
49
+ * Exists on Xbox controllers. Note that on Dualshock 4 controllers, which has a "Share" button,
50
+ * their share button is mapped to Select instead of Share.
51
+ */
52
+ Share = "share",
53
+ /** Only exists on Playstation controllers. */
54
+ TouchPad = "touch-pad"
55
+ }
56
+ /**
57
+ * Name overrides for each brand for consolidated input names from {@link KnownInput}.
58
+ *
59
+ * @category Util
60
+ */
61
+ export declare const modelInputNameOverrides: {
62
+ readonly "switch-pro": {
63
+ readonly L1: "L";
64
+ readonly R1: "R";
65
+ readonly L2: "ZL";
66
+ readonly R2: "ZR";
67
+ readonly "face-accept": "A";
68
+ readonly "face-cancel": "B";
69
+ readonly "face-alt-1": "X";
70
+ readonly "face-alt-2": "Y";
71
+ readonly select: "minus";
72
+ readonly start: "plus";
73
+ };
74
+ readonly "playstation-dual-shock": {
75
+ readonly "face-accept": "X";
76
+ readonly "face-cancel": "O";
77
+ readonly "face-alt-1": "square";
78
+ readonly "face-alt-2": "triangle";
79
+ };
80
+ readonly "playstation-dual-shock-4": {
81
+ readonly "face-accept": "X";
82
+ readonly "face-cancel": "O";
83
+ readonly "face-alt-1": "square";
84
+ readonly "face-alt-2": "triangle";
85
+ readonly select: "share";
86
+ };
87
+ readonly "playstation-dual-sense": {
88
+ readonly "face-accept": "X";
89
+ readonly "face-cancel": "O";
90
+ readonly "face-alt-1": "square";
91
+ readonly "face-alt-2": "triangle";
92
+ readonly select: "create";
93
+ readonly start: "options";
94
+ };
95
+ readonly "steam-deck": {
96
+ readonly "face-accept": "A";
97
+ readonly "face-cancel": "B";
98
+ readonly "face-alt-1": "X";
99
+ readonly "face-alt-2": "Y";
100
+ readonly select: "view";
101
+ readonly start: "menu";
102
+ };
103
+ readonly "xbox-360": {
104
+ readonly L1: "LB";
105
+ readonly R1: "RB";
106
+ readonly L2: "LT";
107
+ readonly R2: "RT";
108
+ readonly "face-accept": "A";
109
+ readonly "face-cancel": "B";
110
+ readonly "face-alt-1": "X";
111
+ readonly "face-alt-2": "Y";
112
+ readonly select: "back";
113
+ };
114
+ readonly "xbox-wireless": {
115
+ readonly L1: "LB";
116
+ readonly R1: "RB";
117
+ readonly L2: "LT";
118
+ readonly R2: "RT";
119
+ readonly "face-accept": "A";
120
+ readonly "face-cancel": "B";
121
+ readonly "face-alt-1": "X";
122
+ readonly "face-alt-2": "Y";
123
+ readonly select: "view";
124
+ readonly start: "menu";
125
+ };
126
+ };
@@ -0,0 +1,128 @@
1
+ import { PredefinedGamepadModel } from './gamepad-model.js';
2
+ /**
3
+ * Consolidated (as much as possible across each brand ) known inputs.
4
+ *
5
+ * @category Util
6
+ */
7
+ export var KnownInput;
8
+ (function (KnownInput) {
9
+ /** A on Xbox and Nintendo, X on Playstation. */
10
+ KnownInput["FaceAccept"] = "face-accept";
11
+ /** B on Xbox and Nintendo, Circle on Playstation. */
12
+ KnownInput["FaceCancel"] = "face-cancel";
13
+ /** X on Xbox and Nintendo, Square on Playstation. */
14
+ KnownInput["FaceAlt1"] = "face-alt-1";
15
+ /** Y on Xbox and Nintendo, Triangle on Playstation. */
16
+ KnownInput["FaceAlt2"] = "face-alt-2";
17
+ /** The top left trigger area button. */
18
+ KnownInput["L1"] = "L1";
19
+ /** The bottom left trigger area button. */
20
+ KnownInput["L2"] = "L2";
21
+ /** Left stick click. */
22
+ KnownInput["L3"] = "L3";
23
+ /** The top right trigger area button. */
24
+ KnownInput["R1"] = "R1";
25
+ /** The bottom right trigger area button. */
26
+ KnownInput["R2"] = "R2";
27
+ /** Right stick click. */
28
+ KnownInput["R3"] = "R3";
29
+ KnownInput["LeftStickX"] = "left-stick-x";
30
+ KnownInput["LeftStickY"] = "left-stick-y";
31
+ KnownInput["RightStickX"] = "right-stick-x";
32
+ KnownInput["RightStickY"] = "right-stick-y";
33
+ KnownInput["DPad"] = "d-pad";
34
+ KnownInput["DPadDown"] = "d-pad-down";
35
+ KnownInput["DPadLeft"] = "d-pad-left";
36
+ KnownInput["DPadRight"] = "d-pad-right";
37
+ KnownInput["DPadUp"] = "d-pad-up";
38
+ /** The primary center button to the left of the controller logo. */
39
+ KnownInput["Select"] = "select";
40
+ /** The button which is also the controller brand's logo. */
41
+ KnownInput["Logo"] = "logo";
42
+ /** The primary center button to the right of the controller logo. */
43
+ KnownInput["Start"] = "start";
44
+ /** Only exists on Nintendo controllers. */
45
+ KnownInput["Capture"] = "capture";
46
+ /** Only exists on Nintendo controllers. */
47
+ KnownInput["Home"] = "home";
48
+ /** Only exists on Playstation controllers. */
49
+ KnownInput["Mute"] = "mute";
50
+ /**
51
+ * Exists on Xbox controllers. Note that on Dualshock 4 controllers, which has a "Share" button,
52
+ * their share button is mapped to Select instead of Share.
53
+ */
54
+ KnownInput["Share"] = "share";
55
+ /** Only exists on Playstation controllers. */
56
+ KnownInput["TouchPad"] = "touch-pad";
57
+ })(KnownInput || (KnownInput = {}));
58
+ /**
59
+ * Name overrides for each brand for consolidated input names from {@link KnownInput}.
60
+ *
61
+ * @category Util
62
+ */
63
+ export const modelInputNameOverrides = {
64
+ [PredefinedGamepadModel.SwitchPro]: {
65
+ [KnownInput.L1]: 'L',
66
+ [KnownInput.R1]: 'R',
67
+ [KnownInput.L2]: 'ZL',
68
+ [KnownInput.R2]: 'ZR',
69
+ [KnownInput.FaceAccept]: 'A',
70
+ [KnownInput.FaceCancel]: 'B',
71
+ [KnownInput.FaceAlt1]: 'X',
72
+ [KnownInput.FaceAlt2]: 'Y',
73
+ [KnownInput.Select]: 'minus',
74
+ [KnownInput.Start]: 'plus',
75
+ },
76
+ [PredefinedGamepadModel.PlaystationDualShock]: {
77
+ [KnownInput.FaceAccept]: 'X',
78
+ [KnownInput.FaceCancel]: 'O',
79
+ [KnownInput.FaceAlt1]: 'square',
80
+ [KnownInput.FaceAlt2]: 'triangle',
81
+ },
82
+ [PredefinedGamepadModel.PlaystationDualShock4]: {
83
+ [KnownInput.FaceAccept]: 'X',
84
+ [KnownInput.FaceCancel]: 'O',
85
+ [KnownInput.FaceAlt1]: 'square',
86
+ [KnownInput.FaceAlt2]: 'triangle',
87
+ [KnownInput.Select]: 'share',
88
+ },
89
+ [PredefinedGamepadModel.PlaystationDualSense]: {
90
+ [KnownInput.FaceAccept]: 'X',
91
+ [KnownInput.FaceCancel]: 'O',
92
+ [KnownInput.FaceAlt1]: 'square',
93
+ [KnownInput.FaceAlt2]: 'triangle',
94
+ [KnownInput.Select]: 'create',
95
+ [KnownInput.Start]: 'options',
96
+ },
97
+ [PredefinedGamepadModel.SteamDeck]: {
98
+ [KnownInput.FaceAccept]: 'A',
99
+ [KnownInput.FaceCancel]: 'B',
100
+ [KnownInput.FaceAlt1]: 'X',
101
+ [KnownInput.FaceAlt2]: 'Y',
102
+ [KnownInput.Select]: 'view',
103
+ [KnownInput.Start]: 'menu',
104
+ },
105
+ [PredefinedGamepadModel.Xbox360]: {
106
+ [KnownInput.L1]: 'LB',
107
+ [KnownInput.R1]: 'RB',
108
+ [KnownInput.L2]: 'LT',
109
+ [KnownInput.R2]: 'RT',
110
+ [KnownInput.FaceAccept]: 'A',
111
+ [KnownInput.FaceCancel]: 'B',
112
+ [KnownInput.FaceAlt1]: 'X',
113
+ [KnownInput.FaceAlt2]: 'Y',
114
+ [KnownInput.Select]: 'back',
115
+ },
116
+ [PredefinedGamepadModel.XboxWireless]: {
117
+ [KnownInput.L1]: 'LB',
118
+ [KnownInput.R1]: 'RB',
119
+ [KnownInput.L2]: 'LT',
120
+ [KnownInput.R2]: 'RT',
121
+ [KnownInput.FaceAccept]: 'A',
122
+ [KnownInput.FaceCancel]: 'B',
123
+ [KnownInput.FaceAlt1]: 'X',
124
+ [KnownInput.FaceAlt2]: 'Y',
125
+ [KnownInput.Select]: 'view',
126
+ [KnownInput.Start]: 'menu',
127
+ },
128
+ };
@@ -0,0 +1,25 @@
1
+ /**
2
+ * System versions that are used to differentiate gamepad layouts, since layouts may differ
3
+ * dramatically between different browsers, operating systems, and versions of each.
4
+ *
5
+ * @category Types
6
+ */
7
+ export type SystemVersions = Readonly<{
8
+ osName: string;
9
+ osVersion: string;
10
+ browserName: string;
11
+ browserVersion: string;
12
+ }>;
13
+ /**
14
+ * Get the current system's versions. This is determined by parsing the user agent string using the
15
+ * [bowser](https://www.npmjs.com/package/bowser) package.
16
+ *
17
+ * @category Util
18
+ */
19
+ export declare function getSystemVersions(): SystemVersions;
20
+ /**
21
+ * Check if a system version is in an array of system versions.
22
+ *
23
+ * @category Util
24
+ */
25
+ export declare function includesSystemVersion(systemVersions: ReadonlyArray<Readonly<SystemVersions>>, systemVersion: Readonly<SystemVersions>): boolean;
@@ -0,0 +1,26 @@
1
+ import { check } from '@augment-vir/assert';
2
+ import Bowser from 'bowser';
3
+ const bowser = Bowser.getParser(navigator.userAgent);
4
+ /**
5
+ * Get the current system's versions. This is determined by parsing the user agent string using the
6
+ * [bowser](https://www.npmjs.com/package/bowser) package.
7
+ *
8
+ * @category Util
9
+ */
10
+ export function getSystemVersions() {
11
+ return {
12
+ /* node:coverage ignore next: supported browser user agents include a browser version. */
13
+ browserVersion: bowser.getBrowserVersion() || 'unknown',
14
+ browserName: bowser.getBrowserName(),
15
+ osName: bowser.getOSName(),
16
+ osVersion: bowser.getOSVersion(),
17
+ };
18
+ }
19
+ /**
20
+ * Check if a system version is in an array of system versions.
21
+ *
22
+ * @category Util
23
+ */
24
+ export function includesSystemVersion(systemVersions, systemVersion) {
25
+ return systemVersions.some((matchThis) => check.jsonEquals(matchThis, systemVersion));
26
+ }
@@ -0,0 +1,2 @@
1
+ import { type Values } from '@augment-vir/common';
2
+ export declare function makeObjectKeysLowercase<Generic extends Readonly<Record<PropertyKey, unknown>>>(input: Generic): Record<PropertyKey, Values<Generic>>;
@@ -0,0 +1,10 @@
1
+ import { check } from '@augment-vir/assert';
2
+ import { mapObject } from '@augment-vir/common';
3
+ export function makeObjectKeysLowercase(input) {
4
+ return mapObject(input, (key, value) => {
5
+ return {
6
+ key: check.isString(key) ? key.toLowerCase() : key,
7
+ value,
8
+ };
9
+ });
10
+ }