mirror of
https://github.com/whscullin/apple2js.git
synced 2024-01-12 14:14:38 +00:00
Very crude mouse support. (#95)
This commit is contained in:
parent
2c02567309
commit
a9885dbfbd
88
asm/mouse.s
Normal file
88
asm/mouse.s
Normal file
@ -0,0 +1,88 @@
|
||||
;
|
||||
; Minimal mouse support. Only firmware routines are supported, no
|
||||
; I/O hooks or softswitches. This is enough to work with titles
|
||||
; that follow the documentation's recommendations to use the
|
||||
; firmware routines like Dazzle Draw and Apple II DeskTop
|
||||
;
|
||||
ORG $C700
|
||||
|
||||
; Constants for future reference
|
||||
|
||||
CLAMP_X_LOW EQU $478
|
||||
CLAMP_Y_LOW EQU $4F8
|
||||
CLAMP_X_HIGH EQU $578
|
||||
CLAMP_Y_HIGH EQU $5F8
|
||||
|
||||
X_LOW EQU $478
|
||||
Y_LOW EQU $4F8
|
||||
X_HIGH EQU $578
|
||||
Y_HIGH EQU $5F8
|
||||
RESERVED1 EQU $678
|
||||
RESERVED2 EQU $67F
|
||||
STATUS EQU $778
|
||||
MODE EQU $7F8
|
||||
|
||||
STATUS_DOWN EQU $80
|
||||
STATUS_LAST EQU $40
|
||||
INT_SCREEN EQU $08
|
||||
INT_BUTTON EQU $04
|
||||
INT_MOUSE EQU $02
|
||||
|
||||
ROMRTS EQU $FF58
|
||||
|
||||
DFB $00 ; $00
|
||||
DFB $00 ; $01
|
||||
DFB $00 ; $02
|
||||
DFB $00 ; $03
|
||||
DFB $00 ; $04
|
||||
; Cx05 - Pascal ID byte
|
||||
DFB $38 ; $05
|
||||
DFB $00 ; $06
|
||||
; Cx07 - Pascal ID byte
|
||||
DFB $18 ; $07
|
||||
DFB $00 ; $08
|
||||
DFB $00 ; $09
|
||||
DFB $00 ; $0A
|
||||
; Cx0B - Generic signature byte of firmware cards
|
||||
DFB $01 ; $0B
|
||||
; Cx0C - 2 = X-Y pointing device; 0 = identification code
|
||||
ID1 DFB $20 ; $0C
|
||||
DFB $00 ; $0D
|
||||
DFB $00 ; $0E
|
||||
DFB $00 ; $0F
|
||||
DFB $00 ; $10
|
||||
DFB $00 ; $11
|
||||
; The firmware routines point to individual RTS opcodes
|
||||
; that are intercepted by the card implementation which
|
||||
; manipulates memory and processor state directly
|
||||
DFB $20 ; $12 SETMOUSE
|
||||
DFB $21 ; $13 SERVEMOUSE
|
||||
DFB $22 ; $14 READMOUSE
|
||||
DFB $23 ; $15 CLEARMOUSE
|
||||
DFB $24 ; $16 POSMOUSE
|
||||
DFB $25 ; $17 CLAMPMOUSE
|
||||
DFB $26 ; $18 HOMEMOUSE
|
||||
DFB $27 ; $19 INITMOUSE
|
||||
DFB $00 ; $1A
|
||||
DFB $00 ; $1B
|
||||
DFB $00 ; $1C
|
||||
DFB $00 ; $1D
|
||||
DFB $00 ; $1E
|
||||
DFB $00 ; $1F
|
||||
RTS ; $20 SETMOUSE
|
||||
RTS ; $21 SERVEMOUSE
|
||||
RTS ; $22 READMOUSE
|
||||
RTS ; $23 CLEARMOUSE
|
||||
RTS ; $24 POSMOUSE
|
||||
RTS ; $25 CLAMPMOUSE
|
||||
RTS ; $26 HOMEMOUSE
|
||||
RTS ; $27 INITMOUSE
|
||||
PADDING DS $C7FB - PADDING
|
||||
ORG $C7FB
|
||||
; CxFB - A mouse identification byte
|
||||
ID2 DFB $D6 ; $FB
|
||||
DFB $00 ; $FC
|
||||
DFB $00 ; $FD
|
||||
DFB $00 ; $FE
|
||||
DFB $00 ; $FF
|
||||
END
|
@ -215,6 +215,10 @@ canvas {
|
||||
height: 416px;
|
||||
}
|
||||
|
||||
#screen.mouseMode {
|
||||
cursor: none;
|
||||
}
|
||||
|
||||
#screen:-webkit-full-screen {
|
||||
background-color: black;
|
||||
top: 0;
|
||||
|
322
js/cards/mouse.ts
Normal file
322
js/cards/mouse.ts
Normal file
@ -0,0 +1,322 @@
|
||||
import { Card, byte, word, Restorable } from '../types';
|
||||
import CPU6502, { CpuState } from '../cpu6502';
|
||||
import { debug } from '../util';
|
||||
import { rom } from '../roms/cards/mouse';
|
||||
|
||||
const CLAMP_MIN_LOW = 0x478;
|
||||
const CLAMP_MAX_LOW = 0x4F8;
|
||||
const CLAMP_MIN_HIGH = 0x578;
|
||||
const CLAMP_MAX_HIGH = 0x5F8;
|
||||
|
||||
const X_LOW = 0x478;
|
||||
const Y_LOW = 0x4F8;
|
||||
const X_HIGH = 0x578;
|
||||
const Y_HIGH = 0x5F8;
|
||||
const STATUS = 0x778;
|
||||
const MODE = 0x7F8;
|
||||
|
||||
const STATUS_DOWN = 0x80;
|
||||
const STATUS_LAST = 0x40;
|
||||
const STATUS_MOVED = 0x20;
|
||||
const INT_SCREEN = 0x08;
|
||||
const INT_PRESS = 0x04;
|
||||
const INT_MOVE = 0x02;
|
||||
|
||||
const MODE_ON = 0x01;
|
||||
const MODE_INT_MOVE = 0x02;
|
||||
const MODE_INT_PRESS = 0x04;
|
||||
const MODE_INT_VBL = 0x08;
|
||||
|
||||
/**
|
||||
* Firmware routine offset pointers
|
||||
*/
|
||||
const ENTRIES = {
|
||||
SET_MOUSE: 0x12,
|
||||
SERVE_MOUSE: 0x13,
|
||||
READ_MOUSE: 0x14,
|
||||
CLEAR_MOUSE: 0x15,
|
||||
POS_MOUSE: 0x16,
|
||||
CLAMP_MOUSE: 0x17,
|
||||
HOME_MOUSE: 0x18,
|
||||
INIT_MOUSE: 0x19
|
||||
};
|
||||
|
||||
interface MouseState {
|
||||
clampXMin: word;
|
||||
clampYMin: word;
|
||||
clampXMax: word
|
||||
clampYMax: word;
|
||||
x: word;
|
||||
y: word;
|
||||
mode: byte;
|
||||
down: boolean;
|
||||
lastDown: boolean;
|
||||
lastX: word;
|
||||
lastY: word;
|
||||
serve: byte;
|
||||
shouldIntMove: boolean;
|
||||
shouldIntPress: boolean;
|
||||
slot: byte;
|
||||
}
|
||||
|
||||
export default class Mouse implements Card, Restorable<MouseState> {
|
||||
/** Lowest mouse X */
|
||||
private clampXMin: word = 0;
|
||||
/** Lowest mouse Y */
|
||||
private clampYMin: word = 0;
|
||||
/** Highest mouse X */
|
||||
private clampXMax: word = 0x3FF;
|
||||
/** Highest mouse Y */
|
||||
private clampYMax: word = 0x3FF;
|
||||
/** Mouse X position */
|
||||
private x: word = 0;
|
||||
/** Mouse Y position */
|
||||
private y: word = 0;
|
||||
/** Mouse mode */
|
||||
private mode: byte = 0;
|
||||
/** Mouse button down state */
|
||||
private down = false;
|
||||
/** Last mouse button down state */
|
||||
private lastDown = false;
|
||||
/** Last mouse Y Position */
|
||||
private lastX: word = 0;
|
||||
/** Last mouse X position */
|
||||
private lastY: word = 0;
|
||||
/** Interrupt service flags */
|
||||
private serve: byte = 0;
|
||||
/** Move happened since last refresh */
|
||||
private shouldIntMove = false;
|
||||
/** Button press happened since last refresh */
|
||||
private shouldIntPress = false;
|
||||
/** Slot for screen hole indexing */
|
||||
private slot = 0;
|
||||
|
||||
constructor(
|
||||
private cpu: CPU6502,
|
||||
private cbs: {
|
||||
setMouse: (mouse: Mouse) => void,
|
||||
mouseMode: (on: boolean) => void
|
||||
}
|
||||
) {
|
||||
this.cbs.setMouse(this);
|
||||
}
|
||||
|
||||
ioSwitch(_off: byte, _val?: byte) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
read(_page: byte, off: byte) {
|
||||
let state = this.cpu.getState();
|
||||
|
||||
const holeWrite = (addr: word, val: byte) => {
|
||||
this.cpu.write(addr >> 8, (addr & 0xff) + this.slot, val);
|
||||
};
|
||||
|
||||
const holeRead = (addr: word) => {
|
||||
return this.cpu.read(addr >> 8, addr & 0xff);
|
||||
};
|
||||
|
||||
const clearCarry = (state: CpuState) => {
|
||||
state.s &= 0xFE;
|
||||
return state;
|
||||
};
|
||||
|
||||
if (this.cpu.getSync()) {
|
||||
switch (off) {
|
||||
case rom[ENTRIES.SET_MOUSE]:
|
||||
{
|
||||
this.mode = state.a;
|
||||
this.cbs.mouseMode(!!(this.mode & MODE_ON));
|
||||
state = clearCarry(state);
|
||||
// debug(
|
||||
// 'setMouse ',
|
||||
// (_mode & MODE_ON ? 'Mouse on ' : 'Mouse off '),
|
||||
// (_mode & MODE_INT_MOVE ? 'Move interrupt ' : '') +
|
||||
// (_mode & MODE_INT_PRESS ? 'Move press ' : '') +
|
||||
// (_mode & MODE_INT_VBL ? 'Move VBL ' : '')
|
||||
// );
|
||||
}
|
||||
break;
|
||||
case rom[ENTRIES.SERVE_MOUSE]:
|
||||
// debug('serveMouse');
|
||||
holeWrite(STATUS, this.serve);
|
||||
state = clearCarry(state);
|
||||
this.serve = 0;
|
||||
break;
|
||||
case rom[ENTRIES.READ_MOUSE]:
|
||||
{
|
||||
const moved = (this.lastX !== this.x) || (this.lastY !== this.y);
|
||||
const status =
|
||||
(this.down ? STATUS_DOWN : 0) |
|
||||
(this.lastDown ? STATUS_LAST : 0) |
|
||||
(moved ? STATUS_MOVED : 0);
|
||||
const mouseXLow = this.x & 0xff;
|
||||
const mouseYLow = this.y & 0xff;
|
||||
const mouseXHigh = this.x >> 8;
|
||||
const mouseYHigh = this.y >> 8;
|
||||
|
||||
// debug({ mouseXLow, mouseYLow, mouseXHigh, mouseYHigh });
|
||||
|
||||
holeWrite(X_LOW, mouseXLow);
|
||||
holeWrite(Y_LOW, mouseYLow);
|
||||
holeWrite(X_HIGH, mouseXHigh);
|
||||
holeWrite(Y_HIGH, mouseYHigh);
|
||||
holeWrite(STATUS, status);
|
||||
holeWrite(MODE, this.mode);
|
||||
|
||||
this.lastDown = this.down;
|
||||
this.lastX = this.x;
|
||||
this.lastY = this.y;
|
||||
|
||||
state = clearCarry(state);
|
||||
}
|
||||
break;
|
||||
case rom[ENTRIES.CLEAR_MOUSE]:
|
||||
debug('clearMouse');
|
||||
state = clearCarry(state);
|
||||
break;
|
||||
case rom[ENTRIES.POS_MOUSE]:
|
||||
debug('posMouse');
|
||||
state = clearCarry(state);
|
||||
break;
|
||||
case rom[ENTRIES.CLAMP_MOUSE]:
|
||||
{
|
||||
const clampY = state.a;
|
||||
if (clampY) {
|
||||
this.clampYMin = holeRead(CLAMP_MIN_LOW) | (holeRead(CLAMP_MIN_HIGH) << 8);
|
||||
this.clampYMax = holeRead(CLAMP_MAX_LOW) | (holeRead(CLAMP_MAX_HIGH) << 8);
|
||||
debug('clampMouse Y', this.clampYMin, this.clampYMax);
|
||||
} else {
|
||||
this.clampXMin = holeRead(CLAMP_MIN_LOW) | (holeRead(CLAMP_MIN_HIGH) << 8);
|
||||
this.clampXMax = holeRead(CLAMP_MAX_LOW) | (holeRead(CLAMP_MAX_HIGH) << 8);
|
||||
debug('clampMouse X', this.clampXMin, this.clampXMax);
|
||||
}
|
||||
state = clearCarry(state);
|
||||
}
|
||||
break;
|
||||
case rom[ENTRIES.HOME_MOUSE]:
|
||||
{
|
||||
debug('homeMouse');
|
||||
this.x = this.clampXMin;
|
||||
this.y = this.clampYMin;
|
||||
state = clearCarry(state);
|
||||
}
|
||||
break;
|
||||
case rom[ENTRIES.INIT_MOUSE]:
|
||||
{
|
||||
this.slot = state.y >> 4;
|
||||
debug('initMouse slot', this.slot);
|
||||
state = clearCarry(state);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
this.cpu.setState(state);
|
||||
}
|
||||
|
||||
return rom[off];
|
||||
}
|
||||
|
||||
write() {}
|
||||
|
||||
/**
|
||||
* Triggers interrupts based on activity since the last tick
|
||||
*/
|
||||
|
||||
tick() {
|
||||
if (this.mode & MODE_INT_VBL) {
|
||||
this.serve |= INT_SCREEN;
|
||||
}
|
||||
if ((this.mode & MODE_INT_PRESS) && this.shouldIntPress) {
|
||||
this.serve |= INT_PRESS;
|
||||
}
|
||||
if ((this.mode & MODE_INT_MOVE) && this.shouldIntMove) {
|
||||
this.serve |= INT_MOVE;
|
||||
}
|
||||
if (this.serve) {
|
||||
this.cpu.irq();
|
||||
}
|
||||
this.shouldIntMove = false;
|
||||
this.shouldIntPress = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Scales mouse position and clamps to min and max,and flags
|
||||
* potential mouse state change interrupt
|
||||
*
|
||||
* @param x Client mouse X position
|
||||
* @param y Client mouse Y position
|
||||
* @param w Client width
|
||||
* @param h Client height
|
||||
*/
|
||||
|
||||
setMouseXY(x: number, y: number, w: number, h: number) {
|
||||
const rangeX = this.clampXMax - this.clampXMin;
|
||||
const rangeY = this.clampYMax - this.clampYMin;
|
||||
this.x = (x * rangeX / w + this.clampXMin) & 0xffff;
|
||||
this.y = (y * rangeY / h + this.clampYMin) & 0xffff;
|
||||
this.shouldIntMove = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tracks mouse button state and flags potential
|
||||
* mouse state change interrupt
|
||||
*
|
||||
* @param down Mouse button down state
|
||||
*/
|
||||
|
||||
setMouseDown(down: boolean) {
|
||||
this.shouldIntPress = this.down !== down;
|
||||
this.down = down;
|
||||
}
|
||||
|
||||
/**
|
||||
* Restores saved state
|
||||
*
|
||||
* @param state stored state
|
||||
*/
|
||||
|
||||
setState(state: MouseState) {
|
||||
this.clampXMin = state.clampXMin;
|
||||
this.clampYMin = state.clampYMin;
|
||||
this.clampXMax = state.clampXMax;
|
||||
this.clampYMax = state.clampYMax;
|
||||
this.x = state.x;
|
||||
this.y = state.y;
|
||||
this.mode = state.mode;
|
||||
this.down = state.down;
|
||||
this.lastDown = state.lastDown;
|
||||
this.lastX = state.lastX;
|
||||
this.lastY = state.lastY;
|
||||
this.serve = state.serve;
|
||||
this.shouldIntMove = state.shouldIntMove;
|
||||
this.shouldIntPress = state.shouldIntPress;
|
||||
this.slot = state.slot;
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves state for restoration
|
||||
*
|
||||
* @returns restorable state
|
||||
*/
|
||||
|
||||
getState(): MouseState {
|
||||
return {
|
||||
clampXMin: this.clampXMin,
|
||||
clampYMin: this.clampYMin,
|
||||
clampXMax: this.clampXMax,
|
||||
clampYMax: this.clampYMax,
|
||||
x: this.x,
|
||||
y: this.y,
|
||||
mode: this.mode,
|
||||
down: this.down,
|
||||
lastDown: this.lastDown,
|
||||
lastX: this.lastX,
|
||||
lastY: this.lastY,
|
||||
serve: this.serve,
|
||||
shouldIntMove: this.shouldIntMove,
|
||||
shouldIntPress: this.shouldIntPress,
|
||||
slot: this.slot
|
||||
};
|
||||
}
|
||||
}
|
@ -2,12 +2,14 @@ import Prefs from './prefs';
|
||||
|
||||
import { driveLights, initUI, updateUI } from './ui/apple2';
|
||||
import Printer from './ui/printer';
|
||||
import { MouseUI } from './ui/mouse';
|
||||
|
||||
import DiskII from './cards/disk2';
|
||||
import Parallel from './cards/parallel';
|
||||
import RAMFactor from './cards/ramfactor';
|
||||
import SmartPort from './cards/smartport';
|
||||
import Thunderclock from './cards/thunderclock';
|
||||
import Mouse from './cards/mouse';
|
||||
|
||||
import { Apple2 } from './apple2';
|
||||
|
||||
@ -54,15 +56,18 @@ apple2.ready.then(() => {
|
||||
const cpu = apple2.getCPU();
|
||||
|
||||
const printer = new Printer('#printer-modal .paper');
|
||||
const mouseUI = new MouseUI('#screen');
|
||||
|
||||
const parallel = new Parallel(printer);
|
||||
const slinky = new RAMFactor(1024 * 1024);
|
||||
const disk2 = new DiskII(io, driveLights);
|
||||
const clock = new Thunderclock();
|
||||
const smartport = new SmartPort(cpu, { block: !enhanced });
|
||||
const mouse = new Mouse(cpu, mouseUI);
|
||||
|
||||
io.setSlot(1, parallel);
|
||||
io.setSlot(2, slinky);
|
||||
io.setSlot(4, mouse);
|
||||
io.setSlot(5, clock);
|
||||
io.setSlot(6, disk2);
|
||||
io.setSlot(7, smartport);
|
||||
|
37
js/roms/cards/mouse.ts
Normal file
37
js/roms/cards/mouse.ts
Normal file
@ -0,0 +1,37 @@
|
||||
import { ReadonlyUint8Array } from '../../types';
|
||||
|
||||
export const rom: ReadonlyUint8Array = new Uint8Array([
|
||||
0x00,0x00,0x00,0x00,0x00,0x38,0x00,0x18,
|
||||
0x00,0x00,0x00,0x01,0x20,0x00,0x00,0x00,
|
||||
0x00,0x00,0x20,0x21,0x22,0x23,0x24,0x25,
|
||||
0x26,0x27,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0xd6,0x00,0x00,0x00,0x00,
|
||||
]);
|
||||
|
@ -6,6 +6,12 @@ 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;
|
||||
@ -17,13 +23,13 @@ export class JoyStick implements OptionHandler {
|
||||
document.addEventListener('mousemove', this.mousemove);
|
||||
document.querySelectorAll('canvas').forEach((canvas) => {
|
||||
canvas.addEventListener('mousedown', (evt) => {
|
||||
if (!this.gamepad) {
|
||||
if (!this.gamepad && !mouseMode) {
|
||||
io.buttonDown(evt.which == 1 ? 0 : 1);
|
||||
}
|
||||
evt.preventDefault();
|
||||
});
|
||||
canvas.addEventListener('mouseup', (evt) => {
|
||||
if (!this.gamepad) {
|
||||
if (!this.gamepad && !mouseMode) {
|
||||
io.buttonUp(evt.which == 1 ? 0 : 1);
|
||||
}
|
||||
});
|
||||
@ -83,7 +89,7 @@ export class JoyStick implements OptionHandler {
|
||||
}
|
||||
|
||||
private mousemove = (evt: MouseEvent) => {
|
||||
if (this.gamepad || this.disableMouseJoystick) {
|
||||
if (this.gamepad || this.disableMouseJoystick || mouseMode) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
45
js/ui/mouse.ts
Normal file
45
js/ui/mouse.ts
Normal file
@ -0,0 +1,45 @@
|
||||
import type Mouse from '../cards/mouse';
|
||||
import { enableMouseMode } from './joystick';
|
||||
|
||||
export class MouseUI {
|
||||
private mouse: Mouse;
|
||||
private canvas: HTMLCanvasElement;
|
||||
|
||||
constructor(selector: string) {
|
||||
this.canvas = document.querySelector<HTMLCanvasElement>(selector)!;
|
||||
|
||||
this.canvas.addEventListener(
|
||||
'mousemove',
|
||||
(event: MouseEvent & { target: HTMLCanvasElement} ) => {
|
||||
const { offsetX, offsetY, target } = event;
|
||||
this.mouse.setMouseXY(
|
||||
offsetX,
|
||||
offsetY,
|
||||
target.clientWidth,
|
||||
target.clientHeight
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
this.canvas.addEventListener('mousedown', () => {
|
||||
this.mouse.setMouseDown(true);
|
||||
});
|
||||
|
||||
this.canvas.addEventListener('mouseup', () => {
|
||||
this.mouse.setMouseDown(false);
|
||||
});
|
||||
}
|
||||
|
||||
setMouse = (mouse: Mouse) => {
|
||||
this.mouse = mouse;
|
||||
};
|
||||
|
||||
mouseMode = (on: boolean) => {
|
||||
enableMouseMode(on);
|
||||
if (on) {
|
||||
this.canvas.classList.add('mouseMode');
|
||||
} else {
|
||||
this.canvas.classList.remove('mouseMode');
|
||||
}
|
||||
};
|
||||
}
|
@ -101,16 +101,14 @@ export class OptionsModal {
|
||||
const list = document.createElement('ul');
|
||||
for (const option of options) {
|
||||
const { name, label, defaultVal, type } = option;
|
||||
const onChange = (evt: InputEvent) => {
|
||||
if (evt.target) {
|
||||
const inputElement = evt.target as HTMLInputElement;
|
||||
switch (type) {
|
||||
case BOOLEAN_OPTION:
|
||||
this.setOption(name, inputElement.checked);
|
||||
break;
|
||||
default:
|
||||
this.setOption(name, inputElement.value);
|
||||
}
|
||||
const onChange = (evt: InputEvent & { target: HTMLInputElement }) => {
|
||||
const { target } = evt;
|
||||
switch (type) {
|
||||
case BOOLEAN_OPTION:
|
||||
this.setOption(name, target.checked);
|
||||
break;
|
||||
default:
|
||||
this.setOption(name, target.value);
|
||||
}
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user