remove localStorage for gamepads connected + fix lost focus effect on controller change + disconnect/reconnect handling
parent
b58a444f80
commit
d34d48f1b5
|
@ -6,6 +6,8 @@ import pad_unlicensedSNES from "./configs/pad_unlicensedSNES";
|
||||||
import pad_xbox360 from "./configs/pad_xbox360";
|
import pad_xbox360 from "./configs/pad_xbox360";
|
||||||
import pad_dualshock from "./configs/pad_dualshock";
|
import pad_dualshock from "./configs/pad_dualshock";
|
||||||
import {Button} from "./enums/buttons";
|
import {Button} from "./enums/buttons";
|
||||||
|
import {Mode} from "./ui/ui";
|
||||||
|
import SettingsGamepadUiHandler from "./ui/settings-gamepad-ui-handler";
|
||||||
|
|
||||||
export interface GamepadMapping {
|
export interface GamepadMapping {
|
||||||
[key: string]: number;
|
[key: string]: number;
|
||||||
|
@ -34,17 +36,19 @@ export class InputsController {
|
||||||
private buttonLock2: Button;
|
private buttonLock2: Button;
|
||||||
private interactions: Map<Button, Map<string, boolean>> = new Map();
|
private interactions: Map<Button, Map<string, boolean>> = new Map();
|
||||||
private time: Time;
|
private time: Time;
|
||||||
private player: Map<String, GamepadMapping> = new Map();
|
private player;
|
||||||
|
|
||||||
private gamepadSupport: boolean = true;
|
private gamepadSupport: boolean = true;
|
||||||
|
|
||||||
public customGamepadMapping = new Map();
|
public customGamepadMapping = new Map();
|
||||||
public chosenGamepad: String;
|
public chosenGamepad: String;
|
||||||
|
private disconnectedGamepads: Array<String> = new Array();
|
||||||
|
|
||||||
constructor(scene: Phaser.Scene) {
|
constructor(scene: Phaser.Scene) {
|
||||||
this.scene = scene;
|
this.scene = scene;
|
||||||
this.time = this.scene.time;
|
this.time = this.scene.time;
|
||||||
this.buttonKeys = [];
|
this.buttonKeys = [];
|
||||||
|
this.player = {};
|
||||||
|
|
||||||
for (const b of Utils.getEnumValues(Button)) {
|
for (const b of Utils.getEnumValues(Button)) {
|
||||||
this.interactions[b] = {
|
this.interactions[b] = {
|
||||||
|
@ -74,6 +78,10 @@ export class InputsController {
|
||||||
this.scene.input.gamepad.on('connected', function (thisGamepad) {
|
this.scene.input.gamepad.on('connected', function (thisGamepad) {
|
||||||
this.refreshGamepads();
|
this.refreshGamepads();
|
||||||
this.setupGamepad(thisGamepad);
|
this.setupGamepad(thisGamepad);
|
||||||
|
this.onReconnect(thisGamepad);
|
||||||
|
}, this);
|
||||||
|
this.scene.input.gamepad.on('disconnected', function (thisGamepad) {
|
||||||
|
this.onDisconnect(thisGamepad);
|
||||||
}, this);
|
}, this);
|
||||||
|
|
||||||
// Check to see if the gamepad has already been setup by the browser
|
// Check to see if the gamepad has already been setup by the browser
|
||||||
|
@ -108,7 +116,7 @@ export class InputsController {
|
||||||
|
|
||||||
setChosenGamepad(gamepad: String): void {
|
setChosenGamepad(gamepad: String): void {
|
||||||
this.deactivatePressedKey();
|
this.deactivatePressedKey();
|
||||||
this.chosenGamepad = gamepad;
|
this.initChosenGamepad(gamepad)
|
||||||
}
|
}
|
||||||
|
|
||||||
update(): void {
|
update(): void {
|
||||||
|
@ -136,17 +144,52 @@ export class InputsController {
|
||||||
}
|
}
|
||||||
|
|
||||||
getGamepadsName(): Array<String> {
|
getGamepadsName(): Array<String> {
|
||||||
return this.gamepads.map(g => g.id);
|
return this.gamepads.filter(g => !this.disconnectedGamepads.includes(g.id)).map(g => g.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
initChosenGamepad(gamepadName?: String): void {
|
||||||
|
let name = gamepadName;
|
||||||
|
if (gamepadName)
|
||||||
|
this.chosenGamepad = gamepadName;
|
||||||
|
else
|
||||||
|
name = this.chosenGamepad;
|
||||||
|
localStorage.setItem('chosenGamepad', name);
|
||||||
|
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');
|
||||||
|
}
|
||||||
|
|
||||||
|
onDisconnect(thisGamepad: Phaser.Input.Gamepad.Gamepad): void {
|
||||||
|
this.disconnectedGamepads.push(thisGamepad.id);
|
||||||
|
const gamepadsLeft = this.gamepads.filter(g => !this.disconnectedGamepads.includes(g.id)).map(g => g);
|
||||||
|
const chosenIsConnected = gamepadsLeft.some(g => g.id === this.chosenGamepad);
|
||||||
|
if (!chosenIsConnected && gamepadsLeft?.length) {
|
||||||
|
this.clearChosenGamepad();
|
||||||
|
this.setChosenGamepad(gamepadsLeft[0].id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onReconnect(thisGamepad: Phaser.Input.Gamepad.Gamepad): void {
|
||||||
|
if (this.disconnectedGamepads.some(g => g === thisGamepad.id)) {
|
||||||
|
this.disconnectedGamepads = this.disconnectedGamepads.filter(g => g !== thisGamepad.id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setupGamepad(thisGamepad: Phaser.Input.Gamepad.Gamepad): void {
|
setupGamepad(thisGamepad: Phaser.Input.Gamepad.Gamepad): void {
|
||||||
let gamepadID = this.chosenGamepad?.toLowerCase() || thisGamepad.id.toLowerCase();
|
const allGamepads = this.getGamepadsName();
|
||||||
const mappedPad = this.mapGamepad(gamepadID);
|
for (const gamepad of allGamepads) {
|
||||||
this.player['mapping'] = mappedPad.gamepadMapping;
|
const gamepadID = gamepad.toLowerCase();
|
||||||
if (!this.chosenGamepad) {
|
const mappedPad = this.mapGamepad(gamepadID);
|
||||||
this.chosenGamepad = thisGamepad.id;
|
if (!this.player[gamepad]) this.player[gamepad] = {};
|
||||||
localStorage.setItem('chosenGamepad', this.chosenGamepad);
|
this.player[gamepad]['mapping'] = mappedPad.gamepadMapping;
|
||||||
}
|
}
|
||||||
|
if (this.chosenGamepad === thisGamepad.id) this.initChosenGamepad(this.chosenGamepad)
|
||||||
}
|
}
|
||||||
|
|
||||||
refreshGamepads(): void {
|
refreshGamepads(): void {
|
||||||
|
@ -162,29 +205,31 @@ export class InputsController {
|
||||||
|
|
||||||
getActionGamepadMapping(): ActionGamepadMapping {
|
getActionGamepadMapping(): ActionGamepadMapping {
|
||||||
const gamepadMapping = {};
|
const gamepadMapping = {};
|
||||||
if (!this.player?.mapping) return gamepadMapping;
|
if (!this.player[this.chosenGamepad] || !this.player[this.chosenGamepad]?.mapping || !this.chosenGamepad) return gamepadMapping;
|
||||||
gamepadMapping[this.player.mapping.LC_N] = Button.UP;
|
gamepadMapping[this.player[this.chosenGamepad].mapping.LC_N] = Button.UP;
|
||||||
gamepadMapping[this.player.mapping.LC_S] = Button.DOWN;
|
gamepadMapping[this.player[this.chosenGamepad].mapping.LC_S] = Button.DOWN;
|
||||||
gamepadMapping[this.player.mapping.LC_W] = Button.LEFT;
|
gamepadMapping[this.player[this.chosenGamepad].mapping.LC_W] = Button.LEFT;
|
||||||
gamepadMapping[this.player.mapping.LC_E] = Button.RIGHT;
|
gamepadMapping[this.player[this.chosenGamepad].mapping.LC_E] = Button.RIGHT;
|
||||||
gamepadMapping[this.player.mapping.TOUCH] = Button.SUBMIT;
|
gamepadMapping[this.player[this.chosenGamepad].mapping.TOUCH] = Button.SUBMIT;
|
||||||
gamepadMapping[this.player.mapping.RC_S] = this.scene.abSwapped ? Button.CANCEL : Button.ACTION;
|
gamepadMapping[this.player[this.chosenGamepad].mapping.RC_S] = this.scene.abSwapped ? Button.CANCEL : Button.ACTION;
|
||||||
gamepadMapping[this.player.mapping.RC_E] = this.scene.abSwapped ? Button.ACTION : Button.CANCEL;
|
gamepadMapping[this.player[this.chosenGamepad].mapping.RC_E] = this.scene.abSwapped ? Button.ACTION : Button.CANCEL;
|
||||||
gamepadMapping[this.player.mapping.SELECT] = Button.STATS;
|
gamepadMapping[this.player[this.chosenGamepad].mapping.SELECT] = Button.STATS;
|
||||||
gamepadMapping[this.player.mapping.START] = Button.MENU;
|
gamepadMapping[this.player[this.chosenGamepad].mapping.START] = Button.MENU;
|
||||||
gamepadMapping[this.player.mapping.RB] = Button.RB;
|
gamepadMapping[this.player[this.chosenGamepad].mapping.RB] = Button.RB;
|
||||||
gamepadMapping[this.player.mapping.LB] = Button.LB;
|
gamepadMapping[this.player[this.chosenGamepad].mapping.LB] = Button.LB;
|
||||||
gamepadMapping[this.player.mapping.LT] = Button.CYCLE_GENDER;
|
gamepadMapping[this.player[this.chosenGamepad].mapping.LT] = Button.CYCLE_GENDER;
|
||||||
gamepadMapping[this.player.mapping.RT] = Button.CYCLE_ABILITY;
|
gamepadMapping[this.player[this.chosenGamepad].mapping.RT] = Button.CYCLE_ABILITY;
|
||||||
gamepadMapping[this.player.mapping.RC_W] = Button.CYCLE_NATURE;
|
gamepadMapping[this.player[this.chosenGamepad].mapping.RC_W] = Button.CYCLE_NATURE;
|
||||||
gamepadMapping[this.player.mapping.RC_N] = Button.CYCLE_VARIANT;
|
gamepadMapping[this.player[this.chosenGamepad].mapping.RC_N] = Button.CYCLE_VARIANT;
|
||||||
gamepadMapping[this.player.mapping.LS] = Button.SPEED_UP;
|
gamepadMapping[this.player[this.chosenGamepad].mapping.LS] = Button.SPEED_UP;
|
||||||
gamepadMapping[this.player.mapping.RS] = Button.SLOW_DOWN;
|
gamepadMapping[this.player[this.chosenGamepad].mapping.RS] = Button.SLOW_DOWN;
|
||||||
|
|
||||||
return gamepadMapping;
|
return gamepadMapping;
|
||||||
}
|
}
|
||||||
|
|
||||||
gamepadButtonDown(pad: Phaser.Input.Gamepad.Gamepad, button: Phaser.Input.Gamepad.Button, value: number): void {
|
gamepadButtonDown(pad: Phaser.Input.Gamepad.Gamepad, button: Phaser.Input.Gamepad.Button, value: number): void {
|
||||||
|
if (!this.chosenGamepad)
|
||||||
|
this.setChosenGamepad(pad.id);
|
||||||
if (!this.gamepadSupport || pad.id.toLowerCase() !== this.chosenGamepad.toLowerCase()) return;
|
if (!this.gamepadSupport || pad.id.toLowerCase() !== this.chosenGamepad.toLowerCase()) return;
|
||||||
const actionMapping = this.getActionGamepadMapping();
|
const actionMapping = this.getActionGamepadMapping();
|
||||||
const buttonDown = actionMapping.hasOwnProperty(button.index) && actionMapping[button.index];
|
const buttonDown = actionMapping.hasOwnProperty(button.index) && actionMapping[button.index];
|
||||||
|
@ -198,7 +243,7 @@ export class InputsController {
|
||||||
}
|
}
|
||||||
|
|
||||||
gamepadButtonUp(pad: Phaser.Input.Gamepad.Gamepad, button: Phaser.Input.Gamepad.Button, value: number): void {
|
gamepadButtonUp(pad: Phaser.Input.Gamepad.Gamepad, button: Phaser.Input.Gamepad.Button, value: number): void {
|
||||||
if (!this.gamepadSupport || pad.id.toLowerCase() !== this.chosenGamepad.toLowerCase()) return;
|
if (!this.gamepadSupport || pad.id !== this.chosenGamepad) return;
|
||||||
const actionMapping = this.getActionGamepadMapping();
|
const actionMapping = this.getActionGamepadMapping();
|
||||||
const buttonUp = actionMapping.hasOwnProperty(button.index) && actionMapping[button.index];
|
const buttonUp = actionMapping.hasOwnProperty(button.index) && actionMapping[button.index];
|
||||||
if (buttonUp !== undefined) {
|
if (buttonUp !== undefined) {
|
||||||
|
|
|
@ -2,6 +2,7 @@ import BattleScene from "../battle-scene";
|
||||||
import {SettingDefaults, SettingOptions} from "#app/system/settings";
|
import {SettingDefaults, SettingOptions} from "#app/system/settings";
|
||||||
import SettingsGamepadUiHandler from "#app/ui/settings-gamepad-ui-handler";
|
import SettingsGamepadUiHandler from "#app/ui/settings-gamepad-ui-handler";
|
||||||
import {Mode} from "#app/ui/ui";
|
import {Mode} from "#app/ui/ui";
|
||||||
|
import {truncateString} from "../utils";
|
||||||
|
|
||||||
export enum SettingGamepad {
|
export enum SettingGamepad {
|
||||||
Default_Controller = "DEFAULT_CONTROLLER",
|
Default_Controller = "DEFAULT_CONTROLLER",
|
||||||
|
@ -57,13 +58,6 @@ export const settingGamepadDefaults: SettingDefaults = {
|
||||||
// [SettingGamepad.Button_Slow_Down]: Button.SLOW_DOWN,
|
// [SettingGamepad.Button_Slow_Down]: Button.SLOW_DOWN,
|
||||||
};
|
};
|
||||||
|
|
||||||
function truncateString(str: String, maxLength: number = 10) {
|
|
||||||
if (str.length > maxLength) {
|
|
||||||
return str.slice(0, maxLength - 3) + "..."; // Subtract 3 to accommodate the ellipsis
|
|
||||||
}
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function setSettingGamepad(scene: BattleScene, setting: SettingGamepad, value: integer): boolean {
|
export function setSettingGamepad(scene: BattleScene, setting: SettingGamepad, value: integer): boolean {
|
||||||
switch (setting) {
|
switch (setting) {
|
||||||
case SettingGamepad.Gamepad_Support:
|
case SettingGamepad.Gamepad_Support:
|
||||||
|
@ -97,7 +91,6 @@ export function setSettingGamepad(scene: BattleScene, setting: SettingGamepad, v
|
||||||
};
|
};
|
||||||
const changeGamepadHandler = (gamepad: string) => {
|
const changeGamepadHandler = (gamepad: string) => {
|
||||||
scene.inputController.setChosenGamepad(gamepad);
|
scene.inputController.setChosenGamepad(gamepad);
|
||||||
localStorage.setItem('chosenGamepad', gamepad);
|
|
||||||
cancelHandler();
|
cancelHandler();
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
|
@ -10,6 +10,7 @@ import {
|
||||||
settingGamepadDefaults,
|
settingGamepadDefaults,
|
||||||
settingGamepadOptions
|
settingGamepadOptions
|
||||||
} from "../system/settings-gamepad";
|
} from "../system/settings-gamepad";
|
||||||
|
import {truncateString} from "../utils";
|
||||||
|
|
||||||
export default class SettingsGamepadUiHandler extends UiHandler {
|
export default class SettingsGamepadUiHandler extends UiHandler {
|
||||||
private settingsContainer: Phaser.GameObjects.Container;
|
private settingsContainer: Phaser.GameObjects.Container;
|
||||||
|
@ -193,6 +194,15 @@ export default class SettingsGamepadUiHandler extends UiHandler {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateChosenGamepadDisplay(): void {
|
||||||
|
for (const [index, key] of Object.keys(SettingGamepad).entries()) {
|
||||||
|
const setting = SettingGamepad[key]
|
||||||
|
if (setting === SettingGamepad.Default_Controller) {
|
||||||
|
this.optionValueLabels[index][0].setText(truncateString(this.scene.inputController.chosenGamepad, 30));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
setOptionCursor(settingIndex: integer, cursor: integer, save?: boolean): boolean {
|
setOptionCursor(settingIndex: integer, cursor: integer, save?: boolean): boolean {
|
||||||
const setting = SettingGamepad[Object.keys(SettingGamepad)[settingIndex]];
|
const setting = SettingGamepad[Object.keys(SettingGamepad)[settingIndex]];
|
||||||
|
|
||||||
|
|
|
@ -357,3 +357,10 @@ export function rgbHexToRgba(hex: string) {
|
||||||
export function rgbaToInt(rgba: integer[]): integer {
|
export function rgbaToInt(rgba: integer[]): integer {
|
||||||
return (rgba[0] << 24) + (rgba[1] << 16) + (rgba[2] << 8) + rgba[3];
|
return (rgba[0] << 24) + (rgba[1] << 16) + (rgba[2] << 8) + rgba[3];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function truncateString(str: String, maxLength: number = 10) {
|
||||||
|
if (str.length > maxLength) {
|
||||||
|
return str.slice(0, maxLength - 3) + "..."; // Subtract 3 to accommodate the ellipsis
|
||||||
|
}
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue