您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
ZenzaWatchをゲームパッドで操作
当前为
- // ==UserScript==
- // @name ZenzaGamePad
- // @namespace https://github.com/segabito/
- // @description ZenzaWatchをゲームパッドで操作
- // @include http://www.nicovideo.jp/*
- // @version 1.0.1
- // @author segabito macmoto
- // @license public domain
- // @grant none
- // ==/UserScript==
- (function() {
- var monkey = function(ZenzaWatch) {
- if (!window.navigator.getGamepads) {
- window.console.log('%cGamepad APIがサポートされていません', 'background: red; color: yellow;');
- return;
- }
- var _ = ZenzaWatch.lib._;
- var $ = ZenzaWatch.lib.$;
- var isZenzaWatchOpen = false;
- var console;
- var debugMode = !true;
- var dummyConsole = {
- log: _.noop, error: _.noop, time: _.noop, timeEnd: _.noop, trace: _.noop
- };
- console = debugMode ? window.console : dummyConsole;
- var execCommand = function(command, param) {
- ZenzaWatch.external.execCommand(command, param);
- };
- var onButtonDown = function(button) {
- if (!isZenzaWatchOpen) { return; }
- switch (button) {
- case 0: // A
- execCommand('togglePlay');
- break;
- case 1: // B
- execCommand('toggleMute');
- break;
- case 2: // X
- execCommand('toggleComment');
- break;
- case 3: // Y
- execCommand('playbackRate', 1.0);
- break;
- case 4: // LB
- execCommand('playPreviousVideo');
- break;
- case 5: // RB
- execCommand('playNextVideo');
- break;
- case 6: // LT
- execCommand('playbackRate', 0.5);
- break;
- case 7: // RT
- execCommand('playbackRate', 1.5);
- break;
- case 8: // ビューボタン (Back)
- execCommand('close');
- break;
- case 9: // メニューボタン (Start)
- execCommand('deflistAdd');
- break;
- case 10: // Lスティック
- execCommand('seek', 0);
- break;
- case 11: // Rスティック
- break;
- case 12: // up
- execCommand('volumeUp');
- break;
- case 13: // down
- execCommand('volumeDown');
- break;
- case 14: // left
- execCommand('seekBy', -5);
- break;
- case 15: // right
- execCommand('seekBy', +5);
- break;
- }
- };
- var onButtonRepeat = function(button) {
- if (!isZenzaWatchOpen) { return; }
- switch (button) {
- case 12: // up
- execCommand('volumeUp');
- break;
- case 13: // down
- execCommand('volumeDown');
- break;
- case 14: // left
- execCommand('seekBy', -5);
- break;
- case 15: // right
- execCommand('seekBy', +5);
- break;
- }
- };
- var onAxisChange = function(axis, value) {
- if (!isZenzaWatchOpen) { return; }
- switch (axis) {
- case 0: // Lスティック X
- execCommand('seekBy', value < 0 ? -5 : 5);
- break;
- case 1: // Lスティック Y
- execCommand(value < 0 ? 'volumeUp' : 'volumeDown');
- break;
- case 2: // Rスティック X
- break;
- case 3: // Rスティック Y
- break;
- }
- };
- var PollingTimer = (function() {
- var id = 0;
- var PollingTimer = function(callback, interval) {
- this._id = id++;
- this.initialize(callback, interval);
- };
- _.assign(PollingTimer.prototype, {
- initialize: function(callback, interval) {
- this._timer = null;
- this._callback = callback;
- if (typeof interval === 'number') {
- this.changeInterval(interval);
- }
- },
- changeInterval: function(interval) {
- if (this._timer) {
- if (this._currentInterval === interval) {
- return;
- }
- window.clearInterval(this._timer);
- }
- console.log('%cupdate Interval:%s', 'background: lightblue;', interval);
- this._currentInterval = interval;
- this._timer = window.setInterval(this._callback, interval);
- },
- pause: function() {
- window.clearInterval(this._timer);
- this._timer = null;
- },
- start: function() {
- if (typeof this._currentInterval !== 'number') {
- return;
- }
- this.changeInterval(this._currentInterval);
- }
- });
- return PollingTimer;
- })();
- var GamePadModel = (function($, _, emitter) {
- var GamePadModel = function(gamepadStatus) {
- this._gamepadStatus = gamepadStatus;
- this._buttons = [];
- this._axes = [];
- this.initialize(gamepadStatus);
- };
- _.extend(GamePadModel.prototype, emitter.prototype);
- _.assign(GamePadModel.prototype, {
- initialize: function(gamepadStatus) {
- this._buttons.length = gamepadStatus.buttons.length;
- this._axes.length = gamepadStatus.axes.length;
- this._id = gamepadStatus.id;
- this._index = gamepadStatus.index;
- this.reset();
- },
- reset: function() {
- var i, len;
- for (i = 0, len = this._gamepadStatus.buttons.length; i < len; i++) {
- this._buttons[i] = {pressed: false, repeat: 0};
- }
- for (i = 0, len = this._gamepadStatus.axes.length; i < len; i++) {
- this._axes[i] = {value: 0, repeat: 0};
- }
- },
- update: function() {
- var gamepadStatus = (navigator.getGamepads())[this._index];
- // gp || this._gamepadStatus;
- if (!gamepadStatus) { console.log('no status'); return; }
- this._gamepadStatus = gamepadStatus;
- var buttons = gamepadStatus.buttons, axes = gamepadStatus.axes;
- var i, len;
- for (i = 0, len = this._buttons.length; i < len; i++) {
- var buttonStatus = buttons[i].pressed ? 1 : 0;
- if (this._buttons[i].pressed !== buttonStatus) {
- var eventName = (buttonStatus === 1) ? 'onButtonDown' : 'onButtonUp';
- //console.log('%cbutton%s:%s', 'background: lightblue;', i, buttonStatus, 0);
- this.emit(eventName, i, 0);
- this.emit('onButtonStatusChange', i, buttonStatus);
- }
- this._buttons[i].pressed = buttonStatus;
- if (buttonStatus) {
- this._buttons[i].repeat++;
- if (this._buttons[i].repeat % 10 === 0) {
- //console.log('%cbuttonRepeat%s', 'background: lightblue;', i);
- this.emit('onButtonRepeat', i);
- }
- } else {
- this._buttons[i].repeat = 0;
- }
- }
- for (i = 0, len = this._axes.length; i < len; i++) {
- var axis = Math.round(axes[i] * 1000) / 1000;
- if (Math.round(Math.abs(axis - this._axes[i].value)) >= 1) {
- this._axes[i].repeat = 0;
- //console.log('%c%s %s', 'background: lightblue;', 'onAxisChange', i, axis, 0);
- this.emit('onAxisChange', i, axis);
- if (axis <= 0.05) {
- this.emit('onAxisRelease', i);
- } else {
- this._axes[i].repeat++;
- if (this._axes[i].repeat % 10 === 0) {
- //console.log('%caxisRepeat%s:%s', 'background: lightblue;', i, axis);
- this.emit('onAxisRepeat', i, axis);
- }
- }
- this._axes[i].value = axis;
- }
- }
- //console.log(JSON.stringify(this.dump()));
- },
- dump: function() {
- var gamepadStatus = this._gamepadStatus, buttons = gamepadStatus.buttons, axes = gamepadStatus.axes;
- var i, len, btmp = [], atmp = [];
- for (i = 0, len = axes.length; i < len; i++) {
- atmp.push('ax' + i + ': ' + axes[i]);
- }
- for (i = 0, len = buttons.length; i < len; i++) {
- btmp.push('bt' + i + ': ' + (buttons[i].pressed ? 1 : 0));
- }
- return atmp.join('\n') + '\n' + btmp.join(', ');
- },
- getX: function() {
- return this._axes.length > 0 ? this._axes[0] : 0;
- },
- getY: function() {
- return this._axes.length > 1 ? this._axes[1] : 0;
- },
- getZ: function() {
- return this._axes.length > 2 ? this._axes[2] : 0;
- },
- getButtonCount: function() {
- return this._buttons ? this._buttons.length : 0;
- },
- getButtonStatus: function(index) {
- return this._buttons[index] || 0;
- },
- getAxisCount: function() {
- return this._axes ? this._axes.length : 0;
- },
- getAxisValue: function(index) {
- return this._axes[index] || 0;
- },
- isConnected: function() {
- return !!this._gamepadStatus.connected;
- },
- getDeviceIndex: function() {
- return this._index;
- },
- getDeviceId: function() {
- return this._id;
- },
- release: function() {
- // TODO: clear events
- }
- });
- return GamePadModel;
- })($, _, ZenzaWatch.lib.AsyncEmitter);
- var ZenzaGamePad = (function ($, PollingTimer, GamePadModel) {
- var primaryGamepad = null;
- var pollingTimer = null;
- var ZenzaGamePad = new ZenzaWatch.lib.AsyncEmitter();
- var detectGamepad = function() {
- if (primaryGamepad) {
- return;
- }
- var gamepads = navigator.getGamepads();
- if (gamepads.length > 0) {
- var pad = _.find(gamepads, (pad, i) => { return pad !== undefined && pad.id; });
- if (!pad) { return; }
- window.console.log(
- '%cdetect gamepad index: %s, id: "%s"',
- 'background: lightgreen; font-weight: bolder;',
- pad.index, pad.id
- );
- var gamepad = new GamePadModel(pad);
- primaryGamepad = gamepad;
- var self = ZenzaGamePad;
- var onButtonDown = function(number) {
- self.emit('onButtonDown', number, gamepad.getDeviceIndex());
- };
- var onButtonRepeat = function(number) {
- self.emit('onButtonRepeat', number, gamepad.getDeviceIndex());
- };
- var onButtonUp = function(number) {
- self.emit('onButtonUp', number, gamepad.getDeviceIndex());
- };
- var onAxisChange = function(number, value) {
- self.emit('onAxisChange', number, value, gamepad.getDeviceIndex());
- };
- var onAxisRepeat = function(number, value) {
- self.emit('onAxisRepeat', number, value, gamepad.getDeviceIndex());
- };
- var onAxisRelease = function(number) {
- self.emit('onAxisRelease', number, gamepad.getDeviceIndex());
- };
- gamepad.on('onButtonDown', onButtonDown);
- gamepad.on('onButtonRepeat', onButtonRepeat);
- gamepad.on('onButtonUp', onButtonUp);
- gamepad.on('onAxisChange', onAxisChange);
- gamepad.on('onAxisRepeat', onAxisRepeat);
- gamepad.on('onAxisRelease', onAxisRelease);
- self.emit('onDeviceConnect', gamepad.getDeviceIndex(), gamepad.getDeviceId());
- pollingTimer.changeInterval(30);
- }
- };
- var onGamepadConnectStatusChange = function(e, isConnected) {
- console.log('onGamepadConnetcStatusChange', e, isConnected);
- if (e.gamepad.index !== 0) {
- return;
- }
- if (isConnected) {
- console.log('%cgamepad connected id:"%s"', 'background: lightblue;', e.gamepad.id);
- detectGamepad();
- } else {
- ZenzaGamePad.emit('onDeviceDisconnect', primaryGamepad.getDeviceIndex());
- if (primaryGamepad) {
- primaryGamepad.release();
- }
- primaryGamepad = null;
- console.log('%cgamepad disconneced id:"%s"', 'background: lightblue;', e.gamepad.id);
- }
- };
- var initializeTimer = function() {
- console.log('%cinitializeGamepadTimer', 'background: lightgreen;');
- var onTimerInterval = function() {
- if (!primaryGamepad) {
- detectGamepad();
- }
- if (!primaryGamepad || !primaryGamepad.isConnected) {
- return;
- }
- primaryGamepad.update();
- };
- pollingTimer = new PollingTimer(onTimerInterval, 1000);
- };
- var initializeGamepadConnectEvent = function() {
- console.log('%cinitializeGamepadConnectEvent', 'background: lightgreen;');
- window.addEventListener('gamepadconnected',
- function(e) { onGamepadConnectStatusChange(e, true); }, false);
- window.addEventListener('gamepaddisconnected',
- function(e) { onGamepadConnectStatusChange(e, false); }, false);
- if (primaryGamepad) {
- return;
- }
- window.setTimeout(detectGamepad, 1000);
- };
- ZenzaGamePad.startDetect = function() {
- ZenzaGamePad.startDetect = _.noop;
- initializeTimer();
- initializeGamepadConnectEvent();
- };
- return ZenzaGamePad;
- })($, PollingTimer, GamePadModel);
- var initGamePad = function() {
- initGamePad = _.noop;
- var deviceId, deviceIndex;
- var notifyDetect = function() {
- notifyDetect = _.noop;
- // 初めてボタンかキーが押されたタイミングで通知する
- execCommand(
- 'notify',
- 'ゲームパッド "' + deviceId + '" が検出されました'
- );
- };
- var _onButtonDown = function(number /*, deviceIndex*/) {
- notifyDetect();
- onButtonDown(number);
- //console.log('%conButtonDown: number=%s, device=%s', 'background: lightblue;', number, deviceIndex);
- };
- var _onButtonRepeat = function(number /*, deviceIndex*/) {
- onButtonRepeat(number);
- //console.log('%conButtonRepeat: number=%s, device=%s', 'background: lightblue;', number, deviceIndex);
- };
- var _onButtonUp = function(number /*, deviceIndex*/) {
- //console.log('%conButtonUp: number=%s, device=%s', 'background: lightblue;', number, deviceIndex);
- };
- var _onAxisChange = function(number, value, deviceIndex) {
- notifyDetect();
- onAxisChange(number, value, deviceIndex);
- //console.log('%conAxisChange: number=%s, value=%s, device=%s', 'background: lightblue;', number, value, deviceIndex);
- };
- var _onAxisRepeat = function(number, value, deviceIndex) {
- //console.log('%conAxisChange: number=%s, value=%s, device=%s', 'background: lightblue;', number, value, deviceIndex);
- };
- var _onAxisRelease = function(/* number, deviceIndex */) {
- };
- var onDeviceConnect = function(index, id) {
- onDeviceConnect = _.noop;
- deviceIndex = index;
- deviceId = id;
- ZenzaGamePad.on('onButtonDown', _onButtonDown);
- ZenzaGamePad.on('onButtonRepeat', _onButtonRepeat);
- ZenzaGamePad.on('onButtonUp', _onButtonUp);
- ZenzaGamePad.on('onAxisChange', _onAxisChange);
- ZenzaGamePad.on('onAxisRepeat', _onAxisRepeat);
- ZenzaGamePad.on('onAxisRelease', _onAxisRelease);
- };
- ZenzaGamePad.on('onDeviceConnect', onDeviceConnect);
- ZenzaGamePad.startDetect();
- };
- var onZenzaWatchOpen = function() {
- isZenzaWatchOpen = true;
- initGamePad();
- };
- var onZenzaWatchClose = function() {
- isZenzaWatchOpen = false;
- };
- var initialize = function() {
- ZenzaWatch.emitter.on('DialogPlayerOpen', onZenzaWatchOpen);
- ZenzaWatch.emitter.of('DialogPlayerClose', onZenzaWatchClose);
- };
- initialize();
- };
- var loadMonkey = function() {
- var script = document.createElement('script');
- script.id = 'ZenzaGamePadLoader';
- script.setAttribute('type', 'text/javascript');
- script.setAttribute('charset', 'UTF-8');
- script.appendChild(document.createTextNode('(' + monkey + ')(window.ZenzaWatch);'));
- document.body.appendChild(script);
- };
- var waitForZenzaWatch = function() {
- if (window.ZenzaWatch && window.ZenzaWatch.ready) {
- window.console.log('ZenzaWatch is Ready');
- loadMonkey();
- } else {
- window.jQuery('body').on('ZenzaWatchReady', function() {
- window.console.log('onZenzaWatchReady');
- loadMonkey();
- });
- }
- };
- waitForZenzaWatch();
- })();