From 7738920ecb9e65ad133e4c58e63b83d757198586 Mon Sep 17 00:00:00 2001 From: Arturo Manzoli Date: Wed, 2 Oct 2024 07:57:44 -0300 Subject: [PATCH 1/4] Joystick: Add support for up to 32 axes and buttons Signed-off-by: Arturo Manzoli --- src/stores/controller.ts | 61 +++++++++++++++++++++---- src/types/joystick.ts | 34 ++++++++++++-- src/views/ConfigurationJoystickView.vue | 12 ++--- 3 files changed, 89 insertions(+), 18 deletions(-) diff --git a/src/stores/controller.ts b/src/stores/controller.ts index dd7d4c5b4..c9454594b 100644 --- a/src/stores/controller.ts +++ b/src/stores/controller.ts @@ -2,7 +2,7 @@ import { useDocumentVisibility } from '@vueuse/core' import { saveAs } from 'file-saver' import { defineStore } from 'pinia' import { v4 as uuid4 } from 'uuid' -import { computed, ref, toRaw, watch } from 'vue' +import { computed, onMounted, ref, toRaw, watch } from 'vue' import { availableGamepadToCockpitMaps, @@ -82,6 +82,44 @@ export const useControllerStore = defineStore('controller', () => { protocolMappingIndex.value = mappingIndex } + const initializeProtocolMapping = (mapping: JoystickProtocolActionsMapping): void => { + // Initialize axesCorrespondencies for all axes up to 31 + for (let axis = 0; axis <= 31; axis++) { + if (mapping.axesCorrespondencies[axis] === undefined) { + mapping.axesCorrespondencies[axis] = { + action: otherAvailableActions.no_function, + min: -1.0, + max: 1.0, + } + } + } + + // Initialize buttonsCorrespondencies for all buttons up to 31 + const modifierKeys = Object.keys(mapping.buttonsCorrespondencies) + for (const modKey of modifierKeys) { + const buttonsCorrespondency = mapping.buttonsCorrespondencies[modKey as CockpitModifierKeyOption] + for (let button = 0; button <= 31; button++) { + if (buttonsCorrespondency[button] === undefined) { + buttonsCorrespondency[button] = { + action: otherAvailableActions.no_function, + } + } + } + } + } + + onMounted(() => { + initializeProtocolMapping(protocolMapping.value) + }) + + watch( + () => protocolMapping.value, + (newMapping) => { + initializeProtocolMapping(newMapping) + }, + { immediate: true, deep: true } + ) + const registerControllerUpdateCallback = (callback: controllerUpdateCallback): void => { updateCallbacks.value.push(callback) } @@ -161,13 +199,13 @@ export const useControllerStore = defineStore('controller', () => { ): ProtocolAction[] => { let modifierKeyId = modifierKeyActions.regular.id - Object.entries(mapping.buttonsCorrespondencies.regular).forEach((e) => { - const buttonActive = joystickState.buttons[Number(e[0])] ?? 0 > 0.5 + Object.entries(mapping.buttonsCorrespondencies.regular).forEach(([key, value]) => { + const buttonActive = joystickState.buttons[Number(key)] ?? 0 > 0.5 const isModifier = Object.values(modifierKeyActions) .map((a) => JSON.stringify(a)) - .includes(JSON.stringify(e[1].action)) + .includes(JSON.stringify(value.action)) if (buttonActive && isModifier) { - modifierKeyId = e[1].action.id + modifierKeyId = value.action.id } }) @@ -176,10 +214,15 @@ export const useControllerStore = defineStore('controller', () => { const activeActions = joystickState.buttons .map((btnState, idx) => ({ id: idx, value: btnState })) .filter((btn) => btn.value ?? 0 > 0.5) - .map( - (btn) => - mapping.buttonsCorrespondencies[modifierKeyId as CockpitModifierKeyOption][btn.id as JoystickButton].action - ) + .map((btn) => { + const btnMapping = mapping.buttonsCorrespondencies[modifierKeyId as CockpitModifierKeyOption][btn.id] + if (btnMapping && btnMapping.action) { + return btnMapping.action + } else { + // Return a default action or handle accordingly + return otherAvailableActions.no_function + } + }) return activeActions.concat(modKeyAction) } diff --git a/src/types/joystick.ts b/src/types/joystick.ts index d550152d5..199753b49 100644 --- a/src/types/joystick.ts +++ b/src/types/joystick.ts @@ -94,7 +94,7 @@ export type JoystickAxisActionCorrespondency = { /** * The ID of the axis that holds the correspondent action */ - [key in JoystickAxis]: { + [key in number]: { /** * The protocol action that should be triggered */ @@ -117,7 +117,7 @@ export type JoystickButtonActionCorrespondency = { /** * The ID of the button that holds the correspondent action */ - [key in JoystickButton]: { + [key in number]: { /** * The protocol action that should be triggered */ @@ -159,7 +159,7 @@ export interface JoystickProtocolActionsMapping { } export type CockpitButton = null | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 // eslint-disable-line -export type CockpitAxis = null | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 +export type CockpitAxis = null | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 // eslint-disable-line /** * This interface defines the mapping for a specific controller from the Gamepad API to Cockpit's standard. @@ -233,6 +233,34 @@ export enum JoystickAxis { A1 = 1, // Vertical axis for left stick (negative up/positive down) A2 = 2, // Horizontal axis for right stick (negative left/positive right) A3 = 3, // Vertical axis for right stick (negative up/positive down) + A4 = 4, // Left trigger (positive pressed) + A5 = 5, // Right trigger (positive pressed) + A6 = 6, // Horizontal axis for D-pad (negative left/positive right) + A7 = 7, // Vertical axis for D-pad (negative up/positive down) + A8 = 8, // Extra non-standard axes + A9 = 9, // Extra non-standard axes + A10 = 10, // Extra non-standard axes + A11 = 11, // Extra non-standard axes + A12 = 12, // Extra non-standard axes + A13 = 13, // Extra non-standard axes + A14 = 14, // Extra non-standard axes + A15 = 15, // Extra non-standard axes + A16 = 16, // Extra non-standard axes + A17 = 17, // Extra non-standard axes + A18 = 18, // Extra non-standard axes + A19 = 19, // Extra non-standard axes + A20 = 20, // Extra non-standard axes + A21 = 21, // Extra non-standard axes + A22 = 22, // Extra non-standard axes + A23 = 23, // Extra non-standard axes + A24 = 24, // Extra non-standard axes + A25 = 25, // Extra non-standard axes + A26 = 26, // Extra non-standard axes + A27 = 27, // Extra non-standard axes + A28 = 28, // Extra non-standard axes + A29 = 29, // Extra non-standard axes + A30 = 30, // Extra non-standard axes + A31 = 31, // Extra non-standard axes } /** diff --git a/src/views/ConfigurationJoystickView.vue b/src/views/ConfigurationJoystickView.vue index 4166c2a86..cb96386a3 100644 --- a/src/views/ConfigurationJoystickView.vue +++ b/src/views/ConfigurationJoystickView.vue @@ -21,7 +21,7 @@ :is-expanded="!interfaceStore.isOnPhoneScreen" compact > - +