diff --git a/web/css/ui.css b/web/css/ui.css index 280418930..49ef51935 100644 --- a/web/css/ui.css +++ b/web/css/ui.css @@ -248,3 +248,25 @@ border-radius: 5px 5px 5px 5px; box-shadow: 0 0 2px 2px rgba(25, 25, 25, 1); } + +.kbm-button { + top: 42px; + left: 126px; + + width: 1em; + text-align: center; + font-size: 70%; +} + +.strikethrough:before { + position: absolute; + content: ""; + left: -2px; + top: 50%; + right: 0; + border-top: 2px solid; + border-color: inherit; + + transform: rotate(-60deg); + width: 20px; +} diff --git a/web/index.html b/web/index.html index 09c311b17..61bbc6ddb 100644 --- a/web/index.html +++ b/web/index.html @@ -55,6 +55,8 @@
+ +
diff --git a/web/js/app.js b/web/js/app.js index 0b2aee135..98e03ea47 100644 --- a/web/js/app.js +++ b/web/js/app.js @@ -43,6 +43,7 @@ import { WEBRTC_SDP_ANSWER, WEBRTC_SDP_OFFER, WORKER_LIST_FETCHED, + KBM_SKIP, } from 'event'; import {gui} from 'gui'; import {keyboard, KEY, joystick, retropad, touch} from 'input'; @@ -457,6 +458,20 @@ const app = { } }; +// switch keyboard+mouse / retropad +const kbmEl = document.getElementById('kbm'); +if (kbmEl) { + let kbmSkip = false; + kbmEl.addEventListener('click', () => { + kbmSkip = !kbmSkip + kbmEl.classList.toggle('strikethrough', kbmSkip) + pub(KBM_SKIP, kbmSkip) + }) + sub(KB_MOUSE_FLAG, () => { + gui.show(kbmEl) + }) +} + // Browser lock API document.onpointerlockchange = () => { pub(POINTER_LOCK_CHANGE, document.pointerLockElement); diff --git a/web/js/event.js b/web/js/event.js index 3011d0b54..7ec3297ab 100644 --- a/web/js/event.js +++ b/web/js/event.js @@ -93,6 +93,7 @@ export const MOUSE_PRESSED = 'mousePressed'; export const FULLSCREEN_CHANGE = 'fsc'; export const POINTER_LOCK_CHANGE = 'plc'; +export const KBM_SKIP = 'kbmSkip'; export const DPAD_TOGGLE = 'dpadToggle'; export const HELP_OVERLAY_TOGGLED = 'helpOverlayToggled'; diff --git a/web/js/input/keyboard.js b/web/js/input/keyboard.js index c31769a21..f3b0c08f6 100644 --- a/web/js/input/keyboard.js +++ b/web/js/input/keyboard.js @@ -10,7 +10,8 @@ import { KEYBOARD_KEY_PRESSED, KEYBOARD_KEY_DOWN, KEYBOARD_KEY_UP, - KEYBOARD_TOGGLE_FILTER_MODE + KEYBOARD_TOGGLE_FILTER_MODE, + KBM_SKIP } from 'event'; import {KEY} from 'input'; import {log} from 'log' @@ -55,7 +56,8 @@ let isFullscreen = false; // special mode for changing button bindings in the options let isKeysFilteredMode = true; // if the browser supports Keyboard Lock API (Firefox does not) -let hasKeyboardLock = false; +let hasKeyboardLock = ('keyboard' in navigator) && ('lock' in navigator.keyboard); +let kbmSkip = false; const remap = (map = {}) => { settings.set(opts.INPUT_KEYBOARD_MAP, map); @@ -116,13 +118,15 @@ const onKey = (code, evt, state) => { sub(DPAD_TOGGLE, (data) => onDpadToggle(data.checked)); sub(KB_MOUSE_FLAG, () => { - hasKeyboardLock = ('keyboard' in navigator) && ('lock' in navigator.keyboard); if (!hasKeyboardLock) { log.warn("Browser doesn't support keyboard lock! It will be emulated."); } sub(FULLSCREEN_CHANGE, async (fullscreenEl) => { isFullscreen = !!fullscreenEl; + + if (kbmSkip) return; + if (hasKeyboardLock) { isFullscreen ? await navigator.keyboard.lock() : navigator.keyboard.unlock(); } @@ -130,6 +134,10 @@ sub(KB_MOUSE_FLAG, () => { }) }) +sub(KBM_SKIP, (v) => { + kbmSkip = v +}) + /** * Keyboard controls. */ @@ -142,12 +150,14 @@ export const keyboard = { e.stopPropagation(); !hasKeyboardLock && isFullscreen && e.preventDefault(); - let lock = isFullscreen; + let lock = isFullscreen ; // hack with Esc up when outside of lock if (e.code === 'Escape') { lock = true } + lock = lock && !kbmSkip + isKeysFilteredMode ? (lock ? pub(KEYBOARD_KEY_UP, e) : onKey(e.code, KEY_RELEASED, false)) : pub(KEYBOARD_KEY_PRESSED, {key: e.code}); @@ -157,8 +167,10 @@ export const keyboard = { e.stopPropagation(); !hasKeyboardLock && isFullscreen && e.preventDefault(); + const lock = isFullscreen && !kbmSkip + isKeysFilteredMode ? - (isFullscreen ? pub(KEYBOARD_KEY_DOWN, e) : onKey(e.code, KEY_PRESSED, true)) : + (lock ? pub(KEYBOARD_KEY_DOWN, e) : onKey(e.code, KEY_PRESSED, true)) : pub(KEYBOARD_KEY_PRESSED, {key: e.code}); }); diff --git a/web/js/screen.js b/web/js/screen.js index 1c8232707..ec0f83b24 100644 --- a/web/js/screen.js +++ b/web/js/screen.js @@ -6,6 +6,7 @@ import { MOUSE_PRESSED, POINTER_LOCK_CHANGE, SETTINGS_CHANGED, + KBM_SKIP, } from 'event'; import {browser, env} from 'env'; import {pointer} from 'input'; @@ -14,6 +15,7 @@ import {opts, settings} from 'settings'; const rootEl = document.getElementById('screen'); const state = { + kbmSkip: false, kbmLock: false, components: [], current: undefined, @@ -66,15 +68,14 @@ rootEl.addEventListener('fullscreenchange', async () => { if (state.current?.hasDisplay) { if (!state.kbmLock) return; - if (fullscreen) { - // event.pub(POINTER_LOCK_CHANGE, screen); - await rootEl.requestPointerLock( - // { unadjustedMovement: true,} - ); + const lockLock = fullscreen && !state.kbmSkip + + if (lockLock) { + await rootEl.requestPointerLock(/*{ unadjustedMovement: true}*/) } - rootEl.onpointerdown = fullscreen ? handlePointerDown : null; - rootEl.onpointerup = fullscreen ? handlePointerUp : null; + rootEl.onpointerdown = lockLock ? handlePointerDown : null; + rootEl.onpointerup = lockLock ? handlePointerUp : null; } }) @@ -93,6 +94,10 @@ sub(KB_MOUSE_FLAG, () => { }); }) +sub(KBM_SKIP, (v) => { + state.kbmSkip = v +}) + export const screen = { fullscreen, toggle,