import { gamepadHandler } from "./gamepadEvents.js"; import * as Logger from "../../module/logger.js"; import { Keymap } from "../../module/keymap.js"; const InputEvent = { Keyboard: 0, Mouse: 1, MouseWheel: 2, Touch: 3, ButtonClick: 4, Gamepad: 5 }; const KeyboardEventType = { Up: 0, Down: 1 }; const GamepadEventType = { ButtonUp: 0, ButtonDown: 1, ButtonPressed: 2, Axis: 3 }; const PointerPhase = { None: 0, Began: 1, Moved: 2, Ended: 3, Canceled: 4, Stationary: 5 }; let sendGamepadButtonDown = undefined; let sendGamepadButtonUp = undefined; let sendGamepadButtonPressed; let gamepadAxisChange = undefined; let gamepadConnected = undefined; let gamepadDisconnected = undefined; export function registerGamepadEvents(videoPlayer) { const _videoPlayer = videoPlayer; sendGamepadButtonDown = (e) => { Logger.log("gamepad id: " + e.id + " button index: " + e.index + " value " + e.value + " down"); let data = new DataView(new ArrayBuffer(19)); data.setUint8(0, InputEvent.Gamepad); data.setUint8(1, GamepadEventType.ButtonDown); data.setUint8(2, e.index); data.setFloat64(3, e.value, true); _videoPlayer && _videoPlayer.sendMsg(data.buffer); }; sendGamepadButtonUp = (e) => { Logger.log("gamepad id: " + e.id + " button index: " + e.index + " value " + e.value + " up"); let data = new DataView(new ArrayBuffer(19)); data.setUint8(0, InputEvent.Gamepad); data.setUint8(1, GamepadEventType.ButtonUp); data.setUint8(2, e.index); data.setFloat64(3, e.value, true); _videoPlayer && _videoPlayer.sendMsg(data.buffer); }; sendGamepadButtonPressed = (e) => { Logger.log("gamepad id: " + e.id + " button index: " + e.index + " value " + e.value + " pressed"); let data = new DataView(new ArrayBuffer(19)); data.setUint8(0, InputEvent.Gamepad); data.setUint8(1, GamepadEventType.ButtonPressed); data.setUint8(2, e.index); data.setFloat64(3, e.value, true); _videoPlayer && _videoPlayer.sendMsg(data.buffer); }; gamepadAxisChange = (e) => { Logger.log("gamepad id: " + e.id + " axis: " + e.index + " value " + e.value + " x:" + e.x + " y:" + e.y); let data = new DataView(new ArrayBuffer(27)); data.setUint8(0, InputEvent.Gamepad); data.setUint8(1, GamepadEventType.Axis); data.setUint8(2, e.index); data.setFloat64(3, e.x, true); data.setFloat64(11, e.y, true); _videoPlayer && _videoPlayer.sendMsg(data.buffer); }; gamepadConnected = (e) => { gamepadHandler(e, true); }; gamepadDisconnected = (e) => { gamepadHandler(e, false); }; document.addEventListener("gamepadButtonDown", sendGamepadButtonDown, false); document.addEventListener("gamepadButtonUp", sendGamepadButtonUp, false); document.addEventListener("gamepadButtonPressed", sendGamepadButtonPressed, false); document.addEventListener("gamepadAxis", gamepadAxisChange, false); window.addEventListener("gamepadconnected", gamepadConnected, false); window.addEventListener("gamepaddisconnected", gamepadDisconnected, false); } export function unregisterGamepadEvents() { document.removeEventListener("gamepadButtonDown", sendGamepadButtonDown, false); document.removeEventListener("gamepadButtonUp", sendGamepadButtonUp, false); document.removeEventListener("gamepadButtonPressed", sendGamepadButtonPressed, false); document.removeEventListener("gamepadAxis", gamepadAxisChange, false); window.removeEventListener("gamepadconnected", gamepadConnected, false); window.removeEventListener("gamepaddisconnected", gamepadDisconnected, false); } let sendKeyUp = undefined; let sendKeyDown = undefined; export function registerKeyboardEvents(videoPlayer) { const _videoPlayer = videoPlayer; function sendKey(e, type) { const key = Keymap[e.code]; const character = e.key.length === 1 ? e.key.charCodeAt(0) : 0; Logger.log("key down " + key + ", repeat = " + e.repeat + ", character = " + character); _videoPlayer && _videoPlayer.sendMsg(new Uint8Array([InputEvent.Keyboard, type, e.repeat, key, character]).buffer); } sendKeyUp = (e) => { sendKey(e, KeyboardEventType.Up); }; sendKeyDown = (e) => { sendKey(e, KeyboardEventType.Down); }; document.addEventListener('keyup', sendKeyUp, false); document.addEventListener('keydown', sendKeyDown, false); } export function unregisterKeyboardEvents() { //Stop listening to keyboard events document.removeEventListener('keyup', sendKeyUp, false); document.removeEventListener('keydown', sendKeyDown, false); } let sendMouse = undefined; let sendMouseWheel = undefined; let sendTouchEnd = undefined; let sendTouchStart = undefined; let sendTouchCancel = undefined; let sendTouchMove = undefined; export function registerMouseEvents(videoPlayer, playerElement) { const _videoPlayer = videoPlayer; function sendTouch(e, phase) { const changedTouches = Array.from(e.changedTouches); const touches = Array.from(e.touches); const phrases = []; for (let i = 0; i < changedTouches.length; i++) { if (touches.find(function (t) { return t.identifier === changedTouches[i].identifier; }) === undefined) { touches.push(changedTouches[i]); } } for (let i = 0; i < touches.length; i++) { touches[i].identifier; phrases[i] = changedTouches.find( function (e) { return e.identifier === touches[i].identifier; }) === undefined ? PointerPhase.Stationary : phase; } Logger.log("touch phase:" + phase + " length:" + changedTouches.length + " pageX" + changedTouches[0].pageX + ", pageX: " + changedTouches[0].pageY + ", force:" + changedTouches[0].force); let data = new DataView(new ArrayBuffer(2 + 13 * touches.length)); data.setUint8(0, InputEvent.Touch); data.setUint8(1, touches.length); let byteOffset = 2; for (let i = 0; i < touches.length; i++) { const scale = _videoPlayer.videoScale; const originX = _videoPlayer.videoOriginX; const originY = _videoPlayer.videoOriginY; const x = (touches[i].pageX - originX) / scale; // According to Unity Coordinate system // const y = (touches[i].pageX - originY) / scale; const y = _videoPlayer.videoHeight - (touches[i].pageY - originY) / scale; data.setInt32(byteOffset, touches[i].identifier, true); byteOffset += 4; data.setUint8(byteOffset, phrases[i]); byteOffset += 1; data.setInt16(byteOffset, x, true); byteOffset += 2; data.setInt16(byteOffset, y, true); byteOffset += 2; data.setFloat32(byteOffset, touches[i].force, true); byteOffset += 4; } _videoPlayer && _videoPlayer.sendMsg(data.buffer); } sendTouchMove = (e) => { sendTouch(e, PointerPhase.Moved); e.preventDefault(); }; sendTouchStart = (e) => { sendTouch(e, PointerPhase.Began); e.preventDefault(); }; sendTouchEnd = (e) => { sendTouch(e, PointerPhase.Ended); e.preventDefault(); }; sendTouchCancel = (e) => { sendTouch(e, PointerPhase.Canceled); e.preventDefault(); }; sendMouse = (e) => { const scale = _videoPlayer.videoScale; const originX = _videoPlayer.videoOriginX; const originY = _videoPlayer.videoOriginY; const x = (e.clientX - originX) / scale; // According to Unity Coordinate system // const y = (e.clientY - originY) / scale; const y = _videoPlayer.videoHeight - (e.clientY - originY) / scale; Logger.log("x: " + x + ", y: " + y + ", scale: " + scale + ", originX: " + originX + ", originY: " + originY + " mouse button:" + e.buttons); let data = new DataView(new ArrayBuffer(6)); data.setUint8(0, InputEvent.Mouse); data.setInt16(1, x, true); data.setInt16(3, y, true); data.setUint8(5, e.buttons); _videoPlayer && _videoPlayer.sendMsg(data.buffer); }; function sendMouseWheel(e) { Logger.log("mouse wheel with delta " + e.wheelDelta); let data = new DataView(new ArrayBuffer(9)); data.setUint8(0, InputEvent.MouseWheel); data.setFloat32(1, e.deltaX, true); data.setFloat32(5, e.deltaY, true); _videoPlayer && _videoPlayer.sendMsg(data.buffer); } // Listen to mouse events playerElement.addEventListener('click', sendMouse, false); playerElement.addEventListener('mousedown', sendMouse, false); playerElement.addEventListener('mouseup', sendMouse, false); playerElement.addEventListener('mousemove', sendMouse, false); playerElement.addEventListener('wheel', sendMouseWheel, false); // Listen to touch events based on "Touch Events Level1" TR. // // Touch event Level1 https://www.w3.org/TR/touch-events/ // Touch event Level2 https://w3c.github.io/touch-events/ // playerElement.addEventListener('touchend', sendTouchEnd, false); playerElement.addEventListener('touchstart', sendTouchStart, false); playerElement.addEventListener('touchcancel', sendTouchCancel, false); playerElement.addEventListener('touchmove', sendTouchMove, false); } export function unregisterMouseEvents(playerElement) { // Stop listening to mouse events playerElement.removeEventListener('click', sendMouse, false); playerElement.removeEventListener('mousedown', sendMouse, false); playerElement.removeEventListener('mouseup', sendMouse, false); playerElement.removeEventListener('mousemove', sendMouse, false); playerElement.removeEventListener('wheel', sendMouseWheel, false); // Stop listening to touch events based on "Touch Events Level1" TR. playerElement.removeEventListener('touchend', sendTouchEnd, false); playerElement.removeEventListener('touchstart', sendTouchStart, false); playerElement.removeEventListener('touchcancel', sendTouchCancel, false); playerElement.removeEventListener('touchmove', sendTouchMove, false); } export function sendClickEvent(videoPlayer, elementId) { let data = new DataView(new ArrayBuffer(3)); data.setUint8(0, InputEvent.ButtonClick); data.setInt16(1, elementId, true); videoPlayer && videoPlayer.sendMsg(data.buffer); }