apple2js/js/ui/joystick.ts

112 lines
3.4 KiB
TypeScript

import Apple2IO from '../apple2io';
import { BOOLEAN_OPTION, OptionHandler } from '../options';
const JOYSTICK_DISABLE = 'disable_mouse';
const JOYSTICK_FLIP_X_AXIS = 'flip_x';
const JOYSTICK_FLIP_Y_AXIS = 'flip_y';
const JOYSTICK_SWAP_AXIS = 'swap_x_y';
let mouseMode = false;
export function enableMouseMode(on: boolean) {
mouseMode = on;
}
export class JoyStick implements OptionHandler {
private disableMouseJoystick = false;
private flipX = false;
private flipY = false;
private swapXY = false;
private gamepad = false;
constructor(private io: Apple2IO) {
document.addEventListener('mousemove', this.mousemove);
document.querySelectorAll('canvas').forEach((canvas) => {
canvas.addEventListener('mousedown', (evt) => {
if (!this.gamepad && !mouseMode) {
io.buttonDown(evt.which === 1 ? 0 : 1);
}
evt.preventDefault();
});
canvas.addEventListener('mouseup', (evt) => {
if (!this.gamepad && !mouseMode) {
io.buttonUp(evt.which === 1 ? 0 : 1);
}
});
canvas.addEventListener('contextmenu', (evt) => {
evt.preventDefault();
});
});
window.addEventListener('gamepadconnected', (e: GamepadEvent) => {
this.gamepad = !!e.gamepad;
});
}
getOptions() {
return [
{
name: 'Joystick',
options: [
{
name: JOYSTICK_DISABLE,
label: 'Disable Mouse Joystick',
type: BOOLEAN_OPTION,
defaultVal: false,
},
{
name: JOYSTICK_FLIP_X_AXIS,
label: 'Flip X-Axis',
type: BOOLEAN_OPTION,
defaultVal: false,
},
{
name: JOYSTICK_FLIP_Y_AXIS,
label: 'Flip Y-Axis',
type: BOOLEAN_OPTION,
defaultVal: false,
},
{
name: JOYSTICK_SWAP_AXIS,
label: 'Swap Axis',
type: BOOLEAN_OPTION,
defaultVal: false,
},
],
},
];
}
setOption(name: string, value: boolean) {
switch (name) {
case JOYSTICK_DISABLE:
this.io.paddle(0, 0.5);
this.io.paddle(1, 0.5);
this.disableMouseJoystick = value;
break;
case JOYSTICK_FLIP_X_AXIS:
case JOYSTICK_FLIP_Y_AXIS:
case JOYSTICK_SWAP_AXIS:
}
}
private mousemove = (evt: MouseEvent) => {
if (this.gamepad || this.disableMouseJoystick || mouseMode) {
return;
}
const s = document.querySelector<HTMLDivElement>('canvas')!;
const offset = s.getBoundingClientRect();
let x = (evt.pageX - offset.left) / s.clientWidth;
let y = (evt.pageY - offset.top) / s.clientHeight;
const z = x;
if (this.swapXY) {
x = y;
y = z;
}
this.io.paddle(0, this.flipX ? 1 - x : x);
this.io.paddle(1, this.flipY ? 1 - y : y);
};
}