update comment in inputs-controller.ts

pull/685/head
Greenlamp 2024-05-12 13:40:16 +02:00
parent 32a9b7170c
commit ba42f072e1
3 changed files with 99 additions and 69 deletions

View File

@ -42,7 +42,7 @@ export function getCurrenlyAssignedIconFromInputIndex(config: GamepadConfig, ind
}
// Given a setting name, return the icon currently assigned to this setting name
export function getCurrentlyAssignedIconToSettingName(config: GamepadConfig, settingName: string) {
export function getCurrentlyAssignedIconToSettingName(config: GamepadConfig, settingName: string): string {
const key = getCurrentlyAssignedToSettingName(config, settingName);
return config.icons[key];
}

View File

@ -6,7 +6,7 @@ import {Button} from "../enums/buttons";
*/
const pad_unlicensedSNES = {
padID: '081f-e401',
padType: 'snes',
padType: 'xbox',
gamepadMapping : {
RC_S: 2,
RC_E: 1,

View File

@ -188,6 +188,12 @@ export class InputsController {
}
}
/**
* Sets the currently chosen gamepad and initializes related settings.
* This method first deactivates any active key presses and then initializes the gamepad settings.
*
* @param gamepad - The identifier of the gamepad to set as chosen.
*/
setChosenGamepad(gamepad: String): void {
this.deactivatePressedKey();
this.initChosenGamepad(gamepad)
@ -196,15 +202,13 @@ export class InputsController {
/**
* Updates the interaction handling by processing input states.
* This method gives priority to certain buttons by reversing the order in which they are checked.
* This method loops through all button values, checks for valid and timely interactions, and conditionally processes
* or ignores them based on the current state of gamepad support and other criteria.
*
* @remarks
* The method iterates over all possible buttons, checking for specific conditions such as:
* - If the button is registered in the `interactions` dictionary.
* - If the button has been held down long enough.
* - If the button is currently pressed.
* It handles special conditions such as the absence of gamepad support or mismatches between the source of the input and
* the currently chosen gamepad. It also respects the paused state of updates to prevent unwanted input processing.
*
* Special handling is applied if gamepad support is disabled but a gamepad source is still triggering inputs,
* preventing potential infinite loops by removing the last processed movement time for the button.
* If an interaction is valid and should be processed, it emits an 'input_down' event with details of the interaction.
*/
update(): void {
for (const b of Utils.getEnumValues(Button).reverse()) {
@ -233,34 +237,39 @@ export class InputsController {
}
}
/**
* Retrieves the identifiers of all connected gamepads, excluding any that are currently marked as disconnected.
* @returns Array<String> An array of strings representing the IDs of the connected gamepads.
*/
getGamepadsName(): Array<String> {
return this.gamepads.filter(g => !this.disconnectedGamepads.includes(g.id)).map(g => g.id);
}
/**
* Initializes the chosen gamepad by setting its identifier in the local storage and updating the UI to reflect the chosen gamepad.
* If a gamepad name is provided, it uses that as the chosen gamepad; otherwise, it defaults to the currently chosen gamepad.
* @param gamepadName Optional parameter to specify the name of the gamepad to initialize as chosen.
*/
initChosenGamepad(gamepadName?: String): void {
// if we have a gamepad name in parameter, we set the chosen gamepad with this value
let name = gamepadName;
if (gamepadName)
this.chosenGamepad = gamepadName;
else
name = this.chosenGamepad; // otherwise we use the chosen gamepad's name
name = this.chosenGamepad;
localStorage.setItem('chosenGamepad', name);
// we update the ui with the chosen gamepad
const handler = this.scene.ui?.handlers[Mode.SETTINGS_GAMEPAD] as SettingsGamepadUiHandler;
handler && handler.updateChosenGamepadDisplay()
}
clearChosenGamepad() {
this.chosenGamepad = null;
if (localStorage.hasOwnProperty('chosenGamepad'))
localStorage.removeItem('chosenGamepad');
}
/**
* Handles the disconnection of a gamepad by adding its identifier to a list of disconnected gamepads.
* This is necessary because Phaser retains memory of previously connected gamepads, and without tracking
* disconnections, it would be impossible to determine the connection status of gamepads. This method ensures
* that disconnected gamepads are recognized and can be appropriately hidden in the gamepad selection menu.
*
* @param thisGamepad The gamepad that has been disconnected.
*/
onDisconnect(thisGamepad: Phaser.Input.Gamepad.Gamepad): void {
// We need to add the disconnected gamepad into a local array
// Because Phaser keep in memory the previously connected gamepad
// If we don't do that, we have no way to determine if the gamepad is connected or not.
// We want to know that because we want to hide it in the selection menu of gamepad to use
this.disconnectedGamepads.push(thisGamepad.id);
/** commented for now this code because i don't know anymore if it's good to do that
* for example i'm playing with a wireless gamepad that shutdown after 5 min
@ -280,27 +289,28 @@ export class InputsController {
// }
}
/**
* Updates the tracking of disconnected gamepads when a gamepad is reconnected.
* It removes the reconnected gamepad's identifier from the `disconnectedGamepads` array,
* effectively updating its status to connected.
*
* @param thisGamepad The gamepad that has been reconnected.
*/
onReconnect(thisGamepad: Phaser.Input.Gamepad.Gamepad): void {
// We check if a gamepad reconnect by looking in the disconnectedGamepads array if is there
// If he is there, we remove it.
this.disconnectedGamepads = this.disconnectedGamepads.filter(g => g !== thisGamepad.id);
}
/**
* Configures a gamepad for use based on its device ID.
* Initializes or updates configurations for connected gamepads.
* It retrieves the names of all connected gamepads, sets up their configurations according to stored or default settings,
* and ensures these configurations are saved. If the connected gamepad is the currently chosen one,
* it reinitializes the chosen gamepad settings.
*
* @param thisGamepad - The gamepad to set up.
*
* @remarks
* This method initializes a gamepad by mapping its ID to a predefined configuration.
* It updates the player's gamepad mapping based on the identified configuration, ensuring
* that the gamepad controls are correctly mapped to in-game actions.
* @param thisGamepad The gamepad that is being set up.
*/
setupGamepad(thisGamepad: Phaser.Input.Gamepad.Gamepad): void {
// we fetch all the gamepads name
const allGamepads = this.getGamepadsName();
for (const gamepad of allGamepads) {
// for each gamepad, we set its mapping in this.configs
const gamepadID = gamepad.toLowerCase();
const config = this.getConfig(gamepadID);
config.custom = this.configs[gamepad]?.custom || {...config.default};
@ -330,21 +340,17 @@ export class InputsController {
}
/**
* Handles the 'down' event for gamepad buttons, emitting appropriate events and updating the interaction state.
* Handles button press events on a gamepad. This method sets the gamepad as chosen on the first input if no gamepad is currently chosen.
* It checks if gamepad support is enabled and if the event comes from the chosen gamepad. If so, it maps the button press to a specific
* action using a custom configuration, emits an event for the button press, and records the time of the action.
*
* @param pad - The gamepad on which the button press occurred.
* @param button - The button that was pressed.
* @param value - The value associated with the button press, typically indicating pressure or degree of activation.
*
* @remarks
* This method is triggered when a gamepad button is pressed. If gamepad support is enabled, it:
* - Retrieves the current gamepad action mapping.
* - Checks if the pressed button is mapped to a game action.
* - If mapped, emits an 'input_down' event with the controller type and button action, and updates the interaction of this button.
* @param pad The gamepad on which the button was pressed.
* @param button The specific button that was pressed.
* @param value The intensity or value of the button press, if applicable.
*/
gamepadButtonDown(pad: Phaser.Input.Gamepad.Gamepad, button: Phaser.Input.Gamepad.Button, value: number): void {
if (!pad) return;
if (!this.chosenGamepad) // at the very first input, if we have not yet a chosen gamepad, we set it
if (!this.chosenGamepad)
this.setChosenGamepad(pad.id);
if (!this.gamepadSupport || pad.id.toLowerCase() !== this.chosenGamepad.toLowerCase()) return;
const key = getKeyFromInputIndex(this.configs[pad.id], button.index);
@ -360,17 +366,13 @@ export class InputsController {
}
/**
* Handles the 'up' event for gamepad buttons, emitting appropriate events and clearing the interaction state.
* Responds to a button release event on a gamepad by checking if the gamepad is supported and currently chosen.
* If conditions are met, it identifies the configured action for the button, emits an event signaling the button release,
* and clears the record of the button.
*
* @param pad - The gamepad on which the button release occurred.
* @param button - The button that was released.
* @param value - The value associated with the button release, typically indicating pressure or degree of deactivation.
*
* @remarks
* This method is triggered when a gamepad button is released. If gamepad support is enabled, it:
* - Retrieves the current gamepad action mapping.
* - Checks if the released button is mapped to a game action.
* - If mapped, emits an 'input_up' event with the controller type and button action, and clears the interaction for this button.
* @param pad The gamepad from which the button was released.
* @param button The specific button that was released.
* @param value The intensity or value of the button release, if applicable.
*/
gamepadButtonUp(pad: Phaser.Input.Gamepad.Gamepad, button: Phaser.Input.Gamepad.Button, value: number): void {
if (!pad) return;
@ -481,17 +483,12 @@ export class InputsController {
}
/**
* Maps a gamepad ID to a specific gamepad configuration based on the ID's characteristics.
* Retrieves the configuration object for a gamepad based on its identifier. The method identifies specific gamepad models
* based on substrings in the identifier and returns predefined configurations for recognized models.
* If no specific configuration matches, it defaults to a generic gamepad configuration.
*
* @param id - The gamepad ID string, typically representing a unique identifier for a gamepad model or make.
* @returns A `GamepadConfig` object corresponding to the identified gamepad model.
*
* @remarks
* This function analyzes the provided gamepad ID and matches it to a predefined configuration based on known identifiers:
* - If the ID includes both '081f' and 'e401', it is identified as an unlicensed SNES gamepad.
* - If the ID contains 'xbox' and '360', it is identified as an Xbox 360 gamepad.
* - If the ID contains '054c', it is identified as a DualShock gamepad.
* If no specific identifiers are recognized, a generic gamepad configuration is returned.
* @param id The identifier string of the gamepad.
* @returns GamepadConfig The configuration object corresponding to the identified gamepad type.
*/
getConfig(id: string): GamepadConfig {
id = id.toLowerCase();
@ -504,7 +501,7 @@ export class InputsController {
return pad_dualshock;
}
// return pad_dualshock;
return pad_unlicensedSNES;
return pad_generic;
}
@ -648,20 +645,46 @@ export class InputsController {
else if (this.buttonLock2 === button) this.buttonLock2 = null;
}
getActiveConfig(): GamepadConfig {
/**
* Retrieves the active configuration for the currently chosen gamepad.
* It checks if a specific gamepad ID is stored under the chosen gamepad's configurations and returns it.
*
* @returns GamepadConfig The configuration object for the active gamepad, or null if not set.
*/
getActiveConfig(): GamepadConfig | null {
if (this.configs[this.chosenGamepad]?.padID) return this.configs[this.chosenGamepad]
return null;
}
getPressedButtonLabel(button: Phaser.Input.Gamepad.Button) {
/**
* Determines icon for a button pressed on the currently chosen gamepad based on its configuration.
*
* @param button The button for which to retrieve the label and icon.
* @returns Array Tuple containing the pad type and the currently assigned icon for the button index.
*/
getPressedButtonLabel(button: Phaser.Input.Gamepad.Button): [string, string] {
return [this.configs[this.chosenGamepad].padType, getCurrenlyAssignedIconFromInputIndex(this.configs[this.chosenGamepad], button.index)];
}
getCurrentlyAssignedIconToDisplay(target: SettingGamepad) {
/**
* Retrieves the currently assigned icon for a specific setting on the chosen gamepad.
*
* @param target The gamepad setting for which to retrieve the assigned icon.
* @returns string The icon assigned to the specified setting.
*/
getCurrentlyAssignedIconToDisplay(target: SettingGamepad): string {
return getCurrentlyAssignedIconToSettingName(this.configs[this.chosenGamepad], target);
}
swapBinding(settingName, pressedButton) {
/**
* Swaps the binding of two controls on the chosen gamepad configuration.
* It temporarily pauses updates, swaps the key bindings, saves the new configuration,
* and then resumes updates after a short delay.
*
* @param settingName The name of the setting for which to swap the binding.
* @param pressedButton The button index whose binding is to be swapped.
*/
swapBinding(settingName, pressedButton): void {
this.pauseUpdate = true;
const keyTarget = getCurrentlyAssignedToSettingName(this.configs[this.chosenGamepad], settingName)
const keyNewBinding = getKeyFromInputIndex(this.configs[this.chosenGamepad], pressedButton);
@ -673,6 +696,13 @@ export class InputsController {
setTimeout(() => this.pauseUpdate = false, 500);
}
/**
* Injects a custom mapping configuration into the gamepad configuration for a specific gamepad.
* If the gamepad does not have an existing configuration, it initializes one first.
*
* @param gamepadName The identifier of the gamepad to configure.
* @param customMappings The custom mapping configuration to apply to the gamepad.
*/
injectConfig(gamepadName: String, customMappings: MappingLayout): void {
if (!this.configs[gamepadName]) this.configs[gamepadName] = {};
this.configs[gamepadName].custom = customMappings;