@moonbase-machines/c64 0.11.0 → 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/browser.js +14 -17
- package/dist/moonbase-c64.js +5 -5
- package/dist/moonbase-c64.js.map +3 -3
- package/keys.js +10 -8
- package/package.json +3 -3
- package/test/keys.test.js +57 -0
package/browser.js
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
// A Commodore 64 (machine.js) in a browser page:
|
|
2
|
-
//
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
// clock, two frames at most at a time.
|
|
1
|
+
// A Commodore 64 (machine.js) in a browser page: each key one key of the C64's matrix and nothing else, the arrows its
|
|
2
|
+
// cursor keys, Escape RUN/STOP, Control the Commodore key, Tab CTRL; the joystick a gamepad plugged in (an 8BitDo, or
|
|
3
|
+
// any in the browser's standard mapping), never a key; the frame painted on a canvas doubled; and the machine run 50
|
|
4
|
+
// frames a second, keeping up with the clock, two frames at most at a time.
|
|
6
5
|
//
|
|
7
6
|
// const keys = keyboard(m, { ignore, onKey, log, listen }) ignore(e): a key the page keeps (a pane's); listen(type,
|
|
8
7
|
// f), where its keys come from (the window's, unless a player gives
|
|
@@ -10,7 +9,7 @@
|
|
|
10
9
|
// keys.press(column, row, frames) a key held for so many frames (RUN/STOP)
|
|
11
10
|
// const draw = painter(canvas) draw(m.vic.frame)
|
|
12
11
|
// pace(m, after) the frames run; after() each animation frame
|
|
13
|
-
import { MATRIX, SHIFTED,
|
|
12
|
+
import { MATRIX, SHIFTED, WITH_SHIFT, CURSOR, MODIFIERS } from './keys.js';
|
|
14
13
|
import { PALETTE, WIDTH, HEIGHT } from './vic.js';
|
|
15
14
|
|
|
16
15
|
const PAD_DEAD = 0.4; // a stick pushed less far than this is at rest (the dead zone)
|
|
@@ -36,13 +35,12 @@ export function keyboard(m, { ignore = () => false, onKey = () => {}, log = fals
|
|
|
36
35
|
onKey(e);
|
|
37
36
|
if (e.metaKey || e.repeat) return;
|
|
38
37
|
if (MODIFIERS[e.key]) { m.key(...MODIFIERS[e.key], true); e.preventDefault(); }
|
|
39
|
-
|
|
40
|
-
const letter =
|
|
41
|
-
const shifted = letter ? null : SHIFTED[e.key], key = letter ? MATRIX[letter] : shifted ? MATRIX[shifted] : MATRIX[e.key] || MATRIX[e.key.toLowerCase()];
|
|
38
|
+
const letter = /^Key([A-Z])$/.exec(e.code)?.[1]?.toLowerCase(), cursor = CURSOR[e.key];
|
|
39
|
+
const shifted = letter || cursor ? null : SHIFTED[e.key], key = cursor ? cursor.slice(0, 2) : letter ? MATRIX[letter] : shifted ? MATRIX[shifted] : MATRIX[e.key] || MATRIX[e.key.toLowerCase()];
|
|
42
40
|
if (!key) { if (MODIFIERS[e.key]) e.preventDefault(); return; }
|
|
43
|
-
// (the left shift: a letter's graphic, a shifted sign, and
|
|
44
|
-
// and F8 being shift with F1, F3, F5 and F7 on the 64)
|
|
45
|
-
if (letter ? (upper() ? e.altKey : e.shiftKey) : shifted || (e.key.length === 1 && e.key !== e.key.toLowerCase() && !/[0-9]/.test(e.key)) || (e.shiftKey &&
|
|
41
|
+
// (the left shift: a letter's graphic, a shifted sign, the cursor going up or left, and Shift with a function key,
|
|
42
|
+
// Home or DEL, F2, F4, F6 and F8, CLR and INST being shift with F1, F3, F5 and F7, HOME and DEL on the 64)
|
|
43
|
+
if (cursor ? cursor[2] : letter ? (upper() ? e.altKey : e.shiftKey) : shifted || (e.key.length === 1 && e.key !== e.key.toLowerCase() && !/[0-9]/.test(e.key)) || (e.shiftKey && WITH_SHIFT.test(e.key))) m.key(1, 7, true);
|
|
46
44
|
// (Control held, as the event says, the Commodore key down with the key, if Control's own
|
|
47
45
|
// keydown has not put it there, and let go with it)
|
|
48
46
|
const [cc, cr] = MODIFIERS.Control, cbm = e.ctrlKey && !(m.keys[cc] & 1 << cr) ? MODIFIERS.Control : null;
|
|
@@ -53,17 +51,16 @@ export function keyboard(m, { ignore = () => false, onKey = () => {}, log = fals
|
|
|
53
51
|
});
|
|
54
52
|
listen('keyup', e => {
|
|
55
53
|
if (MODIFIERS[e.key]) m.key(...MODIFIERS[e.key], false);
|
|
56
|
-
if (JOYSTICK[e.key]) { m.joystick &= ~JOYSTICK[e.key]; const cur = CURSOR[e.key]; if (cur) { m.key(cur[0], cur[1], false); if (cur[2]) m.key(1, 7, false); } return; }
|
|
57
54
|
const key = down.get(e.code);
|
|
58
55
|
if (key) { release(key, true); if (withCbm.delete(e.code)) release(MODIFIERS.Control, false); down.delete(e.code); } else m.key(1, 7, false);
|
|
59
56
|
});
|
|
60
57
|
// the page left (another window, another tab, Cmd-Tab): the browser sends no keyup for what was
|
|
61
|
-
// held, so everything is let go, the keys, the joystick and fire, or a key (CTRL by Tab
|
|
62
|
-
//
|
|
58
|
+
// held, so everything is let go, the keys, the joystick and fire, or a key (CTRL by Tab) would stay
|
|
59
|
+
// down and every key after it be read wrongly
|
|
63
60
|
const letGo = () => { m.keys.fill(0); m.joystick = 0; down.clear(); held.length = 0; pressed.clear(); withCbm.clear(); padBits = 0; padStop = false; };
|
|
64
61
|
// a gamepad, read each frame in the browser's standard mapping: the D-pad or the left stick
|
|
65
|
-
// (pushed past PAD_DEAD) the joystick in port 2, A or B its fire, Start RUN/STOP;
|
|
66
|
-
//
|
|
62
|
+
// (pushed past PAD_DEAD) the joystick in port 2, A or B its fire, Start RUN/STOP; let go with the
|
|
63
|
+
// pad
|
|
67
64
|
let padBits = 0, padStop = false;
|
|
68
65
|
const readPads = () => {
|
|
69
66
|
if (typeof navigator === 'undefined' || typeof navigator.getGamepads !== 'function') return;
|