- Added IGamepadButton interface.

- Modified IGamepad interface by buttons and axes.
- Modified IVibrator and Vibrator to use update function.
- Added AppDiagnostic component, view, route and redirect.
- Changed faq-link to gamepad-master to wavelovers-diagnostic.
This commit is contained in:
Eugene Serb 2022-08-08 22:09:56 +03:00
parent 7894b381f9
commit d0cdbda70a
11 changed files with 189 additions and 3 deletions

11
public/diagnostic.html Normal file
View File

@ -0,0 +1,11 @@
<!DOCTYPE html>
<html lang="en-us" dir="ltr" xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Wavelovers Redirect</title>
<meta charset="UTF-8" />
<meta http-equiv="refresh" content="0; URL=https://wavelovers.ru/?diagnostic" />
</head>
<body>
</body>
</html>

View File

@ -112,7 +112,7 @@
<div class="content-item"> <div class="content-item">
<h2 class="content-item__header">Troubleshooting</h2> <h2 class="content-item__header">Troubleshooting</h2>
<span>If you are having difficulty detecting a gamepad by the browser, you can use the utility </span> <span>If you are having difficulty detecting a gamepad by the browser, you can use the utility </span>
<a href="https://eugene-serb.github.io/gamepad-master/" target="_blank">Gamepad Master</a><br /><br /> <a href="https://wavelovers.ru/?diagnostic" target="_blank">Wavelovers Diagnostic</a><br /><br />
<dl> <dl>
<dt>The app does not see my device.</dt> <dt>The app does not see my device.</dt>
<dd>Make sure you have a chromium-based browser, then update the app and reconnect your device.</dd> <dd>Make sure you have a chromium-based browser, then update the app and reconnect your device.</dd>

View File

@ -1,7 +1,7 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en-us" dir="ltr" xmlns="http://www.w3.org/1999/xhtml"> <html lang="en-us" dir="ltr" xmlns="http://www.w3.org/1999/xhtml">
<head> <head>
<title>Wavelovers Redirect</title> <title>Wavelovers Redirect</title>
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<meta http-equiv="refresh" content="0; URL=https://wavelovers.ru/?manual" /> <meta http-equiv="refresh" content="0; URL=https://wavelovers.ru/?manual" />
</head> </head>

View File

@ -0,0 +1,136 @@
<template>
<div class="content-item">
<div v-for="gamepad in gamepads"
:key="gamepad.id">
<div class="output-gamepad">
<h3>#{{ gamepad.unit.index + 1 }}. {{ gamepad.unit.id }}</h3>
<div class="gamepad-group">
<div>
<span :class="[ gamepad.unit.buttons[0].value === 1 ? 'pressed' : '' ]"
>A: {{ gamepad.unit.buttons[0].value.toFixed(2) }}</span>
<span :class="[gamepad.unit.buttons[1].value === 1 ? 'pressed' : '' ]"
>B: {{ gamepad.unit.buttons[1].value.toFixed(2) }}</span>
<span :class="[ gamepad.unit.buttons[2].value === 1 ? 'pressed' : '' ]"
>X: {{ gamepad.unit.buttons[2].value.toFixed(2) }}</span>
<span :class="[ gamepad.unit.buttons[3].value === 1 ? 'pressed' : '' ]"
>Y: {{ gamepad.unit.buttons[3].value.toFixed(2) }}</span>
</div>
<div>
<span :class="[ gamepad.unit.buttons[4].value === 1 ? 'pressed' : '' ]"
>LB: {{ gamepad.unit.buttons[4].value.toFixed(2) }}</span>
<span :class="[ gamepad.unit.buttons[5].value === 1 ? 'pressed' : '' ]"
>RB: {{ gamepad.unit.buttons[5].value.toFixed(2) }}</span>
<span :class="[ gamepad.unit.buttons[6].value === 1 ? 'pressed' : '' ]"
>LT: {{ gamepad.unit.buttons[6].value.toFixed(2) }}</span>
<span :class="[ gamepad.unit.buttons[7].value === 1 ? 'pressed' : '' ]"
>RT: {{ gamepad.unit.buttons[7].value.toFixed(2) }}</span>
</div>
<div>
<span :class="[ gamepad.unit.buttons[8].value === 1 ? 'pressed' : '' ]"
>Back: {{ gamepad.unit.buttons[8].value.toFixed(2) }}</span>
<span :class="[ gamepad.unit.buttons[9].value === 1 ? 'pressed' : '' ]"
>Start: {{ gamepad.unit.buttons[9].value.toFixed(2) }}</span>
<span :class="[ gamepad.unit.buttons[10].value === 1 ? 'pressed' : '' ]"
>Left Stick: {{gamepad.unit.buttons[10].value.toFixed(2) }}</span>
<span :class="[ gamepad.unit.buttons[11].value === 1 ? 'pressed' : '' ]"
>Right Stick: {{ gamepad.unit.buttons[11].value.toFixed(2) }}</span>
</div>
<div>
<span :class="[ gamepad.unit.buttons[12].value === 1 ? 'pressed' : '' ]"
>Forward: {{ gamepad.unit.buttons[12].value.toFixed(2) }}</span>
<span :class="[ gamepad.unit.buttons[13].value === 1 ? 'pressed' : '' ]"
>Backward: {{ gamepad.unit.buttons[13].value.toFixed(2) }}</span>
<span :class="[ gamepad.unit.buttons[14].value === 1 ? 'pressed' : '' ]"
>Left: {{ gamepad.unit.buttons[14].value.toFixed(2) }}</span>
<span :class="[ gamepad.unit.buttons[15].value === 1 ? 'pressed' : '' ]"
>Right: {{ gamepad.unit.buttons[15].value.toFixed(2) }}</span>
</div>
<div>
<span>Left Stick X: {{ gamepad.unit.axes[0] ? gamepad.unit.axes[0].toFixed(2) : 'missing' }}</span>
<span>Left Stick Y: {{ gamepad.unit.axes[1] ? gamepad.unit.axes[1].toFixed(2) : 'missing' }}</span>
<span>Right Stick X: {{ gamepad.unit.axes[2] ? gamepad.unit.axes[2].toFixed(2) : 'missing' }}</span>
<span>Right Stick Y: {{ gamepad.unit.axes[3] ? gamepad.unit.axes[3].toFixed(2) : 'missing' }}</span>
</div>
</div>
<span>Vibration Actuator: {{ gamepad.unit.vibrationActuator ? 'Available' : 'missing' }}</span>
</div>
</div>
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import store from '@/store/index';
import Vibrator from '@/models/Vibrator';
export default defineComponent({
name: 'AppDiagnostic',
data: () => {
return {
timestamp: 0 as number,
interval: 0 as number,
};
},
computed: {
gamepads: function (): Vibrator[] {
const timestamp: number = this.timestamp;
return store.getters.gamepads as Vibrator[];
},
},
methods: {
updateTimestamp: function (): void {
this.timestamp = Date.now();
},
},
mounted() {
this.interval = setInterval(this.updateTimestamp, 1);
},
unmounted() {
clearInterval(this.interval);
},
});
</script>
<style lang="scss">
.message-box {
text-align: center;
}
.output-wrapper {
margin-block-start: 32px;
display: flex;
flex-direction: column;
text-align: center;
justify-content: center;
gap: 32px;
}
.output-gamepad {
width: 100%;
padding: 16px;
border: 2px solid var(--color-border);
border-radius: var(--number-border-radius);
display: flex;
flex-direction: column;
justify-content: space-between;
gap: 16px;
}
.gamepad-group {
display: grid;
grid-template-columns: repeat(5, 1fr);
}
.gamepad-group > div {
display: flex;
flex-direction: column;
justify-content: space-between;
gap: 8px;
}
.pressed {
background-color: var(--color-link-hover);
color: var(--color-background);
}
</style>

View File

@ -2,6 +2,7 @@
<div class="content-item navigation-list"> <div class="content-item navigation-list">
<router-link to="/manual" class="navigation-item">Manual</router-link> <router-link to="/manual" class="navigation-item">Manual</router-link>
<router-link to="/" class="navigation-item">Patterns</router-link> <router-link to="/" class="navigation-item">Patterns</router-link>
<router-link to="/diagnostic" class="navigation-item">Diagnostic</router-link>
</div> </div>
</template> </template>

View File

@ -1,10 +1,14 @@
import IVibrationActuator from '@/models/IVibrationActuator'; import IVibrationActuator from '@/models/IVibrationActuator';
import IGamepadButton from '@/models/IGamepadButton';
interface IGamepad { interface IGamepad {
id: string; id: string;
index: number; index: number;
timestamp: number; timestamp: number;
connected: boolean; connected: boolean;
mapping: string;
axes: number[];
buttons: IGamepadButton[];
vibrationActuator: IVibrationActuator; vibrationActuator: IVibrationActuator;
} }

View File

@ -0,0 +1,8 @@
interface IGamepadButton {
pressed: boolean;
touched: boolean;
value: number;
}
export default IGamepadButton;

View File

@ -7,6 +7,7 @@ interface IVibrator {
isVibrating: boolean; isVibrating: boolean;
unit: IGamepad; unit: IGamepad;
pattern: TPatternUnit[]; pattern: TPatternUnit[];
interval: number;
update(): void; update(): void;
reset(): void; reset(): void;
vibrate(pattern: TPatternUnit[]): void; vibrate(pattern: TPatternUnit[]): void;

View File

@ -8,6 +8,7 @@ class Vibrator implements IVibrator {
isVibrating: boolean; isVibrating: boolean;
unit: IGamepad; unit: IGamepad;
pattern: TPatternUnit[]; pattern: TPatternUnit[];
interval: number;
constructor(unit: IGamepad) { constructor(unit: IGamepad) {
this.unit = unit; this.unit = unit;
@ -15,11 +16,14 @@ class Vibrator implements IVibrator {
this.canVibrate = (this.unit.vibrationActuator) ? true : false; this.canVibrate = (this.unit.vibrationActuator) ? true : false;
this.isVibrating = false; this.isVibrating = false;
this.pattern = []; this.pattern = [];
this.update = this.update.bind(this);
this.interval = setInterval(this.update, 1);
} }
update(): void { update(): void {
const gamepads = navigator.getGamepads(); const gamepads = navigator.getGamepads();
this.unit = <IGamepad><unknown>gamepads[this.unit.index]; this.unit = gamepads[this.unit.index] as unknown as IGamepad;
} }
reset(): void { reset(): void {

View File

@ -12,6 +12,11 @@ const routes: Array<RouteRecordRaw> = [
name: 'manual-view', name: 'manual-view',
component: () => import('@/views/ManualView.vue'), component: () => import('@/views/ManualView.vue'),
}, },
{
path: '/diagnostic',
name: 'diagnostic-view',
component: () => import('@/views/DiagnosticView.vue'),
},
{ {
path: '/404', path: '/404',
name: '404', name: '404',

View File

@ -0,0 +1,16 @@
<template>
<AppDiagnostic />
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import AppDiagnostic from '@/components/AppDiagnostic.vue';
export default defineComponent({
name: 'DiagnosticView',
components: {
AppDiagnostic: AppDiagnostic,
},
});
</script>