feat(playground): expand gamepad support with face buttons and Steam Deck fixes
- Map A=Train, B=Clear Examples, X=Randomize, LB=Thumbs Down, RB=Thumbs Up - Add periodic gamepad polling fallback for environments where gamepadconnected event doesn't fire reliably (Steam Deck, some Linux browsers) - Show "Press any gamepad button to connect" hint on page load
This commit is contained in:
parent
affec8f604
commit
de75a3f0e4
4 changed files with 50 additions and 17 deletions
|
|
@ -1365,14 +1365,23 @@ function wireGamepad() {
|
|||
onJoystickMove();
|
||||
},
|
||||
onButton: (btn) => {
|
||||
if (btn === 'rb') onThumbsUp();
|
||||
if (btn === 'lb') onThumbsDown();
|
||||
if (btn === 'rb') onThumbsUp();
|
||||
if (btn === 'a') onTrain();
|
||||
if (btn === 'x') onRandomize();
|
||||
if (btn === 'b') onClearExamples();
|
||||
},
|
||||
onConnectionChange: (connected) => {
|
||||
const el = document.getElementById('gamepad-status');
|
||||
if (el) el.textContent = connected ? 'Gamepad connected' : '';
|
||||
if (el) el.textContent = connected ? 'Gamepad connected' : 'Press any button to activate gamepad';
|
||||
},
|
||||
});
|
||||
|
||||
// Show hint immediately if no gamepad detected yet
|
||||
if (!gamepad.connected) {
|
||||
const el = document.getElementById('gamepad-status');
|
||||
if (el) el.textContent = 'Press any gamepad button to connect';
|
||||
}
|
||||
}
|
||||
|
||||
// ---- Keyboard ----
|
||||
|
|
|
|||
|
|
@ -1241,15 +1241,23 @@ function init() {
|
|||
mappingView.drawOverlay();
|
||||
},
|
||||
onButton: (btn) => {
|
||||
if (btn === 'rb') onThumbsUp();
|
||||
if (btn === 'lb') onThumbsDown();
|
||||
if (btn === 'rb') onThumbsUp();
|
||||
if (btn === 'a') onTrain();
|
||||
if (btn === 'x') onRandomize();
|
||||
if (btn === 'b') onClearExamples();
|
||||
},
|
||||
onConnectionChange: (connected) => {
|
||||
const el = document.getElementById('gamepad-status');
|
||||
if (el) el.textContent = connected ? 'Gamepad connected' : '';
|
||||
if (el) el.textContent = connected ? 'Gamepad connected' : 'Press any button to activate gamepad';
|
||||
},
|
||||
});
|
||||
|
||||
if (!gamepad.connected) {
|
||||
const el = document.getElementById('gamepad-status');
|
||||
if (el) el.textContent = 'Press any gamepad button to connect';
|
||||
}
|
||||
|
||||
// Resize
|
||||
window.addEventListener('resize', () => {
|
||||
visualizer.resize();
|
||||
|
|
|
|||
|
|
@ -287,15 +287,20 @@ function init() {
|
|||
drawJoystick();
|
||||
},
|
||||
onButton: (btn) => {
|
||||
if (btn === 'rb') onThumbsUp();
|
||||
if (btn === 'lb') onThumbsDown();
|
||||
if (btn === 'rb') onThumbsUp();
|
||||
},
|
||||
onConnectionChange: (connected) => {
|
||||
const el = document.getElementById('gamepad-status');
|
||||
if (el) el.textContent = connected ? 'Gamepad connected' : '';
|
||||
if (el) el.textContent = connected ? 'Gamepad connected' : 'Press any button to activate gamepad';
|
||||
},
|
||||
});
|
||||
|
||||
if (!gamepad.connected) {
|
||||
const el = document.getElementById('gamepad-status');
|
||||
if (el) el.textContent = 'Press any gamepad button to connect';
|
||||
}
|
||||
|
||||
// Follow mode wiring
|
||||
wireFollowMode();
|
||||
|
||||
|
|
|
|||
|
|
@ -37,6 +37,17 @@ export class GamepadInput {
|
|||
|
||||
// Check if a gamepad is already connected
|
||||
this._findGamepad();
|
||||
|
||||
// Periodic fallback: some environments (Steam Deck, some Linux browsers)
|
||||
// don't fire gamepadconnected reliably. Poll every 500ms until found.
|
||||
this._probeInterval = setInterval(() => {
|
||||
if (!this.connected) {
|
||||
this._findGamepad();
|
||||
} else {
|
||||
clearInterval(this._probeInterval);
|
||||
this._probeInterval = null;
|
||||
}
|
||||
}, 500);
|
||||
}
|
||||
|
||||
_onConnected(e) {
|
||||
|
|
@ -126,18 +137,17 @@ export class GamepadInput {
|
|||
this.onMove(mappedX, mappedY);
|
||||
}
|
||||
|
||||
// Buttons: LB=4, RB=5
|
||||
// Buttons: A=0, B=1, X=2, Y=3, LB=4, RB=5
|
||||
if (this.onButton) {
|
||||
const lbPressed = !!gp.buttons[4]?.pressed;
|
||||
const rbPressed = !!gp.buttons[5]?.pressed;
|
||||
const lbPrev = !!this._buttonsPrev[4];
|
||||
const rbPrev = !!this._buttonsPrev[5];
|
||||
|
||||
if (lbPressed && !lbPrev) this.onButton('lb');
|
||||
if (rbPressed && !rbPrev) this.onButton('rb');
|
||||
|
||||
this._buttonsPrev[4] = lbPressed;
|
||||
this._buttonsPrev[5] = rbPressed;
|
||||
const watched = [0, 1, 2, 3, 4, 5];
|
||||
const names = ['a', 'b', 'x', 'y', 'lb', 'rb'];
|
||||
for (let i = 0; i < watched.length; i++) {
|
||||
const idx = watched[i];
|
||||
const pressed = !!gp.buttons[idx]?.pressed;
|
||||
const prev = !!this._buttonsPrev[idx];
|
||||
if (pressed && !prev) this.onButton(names[i]);
|
||||
this._buttonsPrev[idx] = pressed;
|
||||
}
|
||||
}
|
||||
|
||||
return moved;
|
||||
|
|
@ -153,5 +163,6 @@ export class GamepadInput {
|
|||
destroy() {
|
||||
window.removeEventListener('gamepadconnected', this._onConnected);
|
||||
window.removeEventListener('gamepaddisconnected', this._onDisconnected);
|
||||
if (this._probeInterval) clearInterval(this._probeInterval);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue