@moonbase-machines/c64 0.11.0 → 0.13.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 +18 -29
- package/dist/moonbase-c64.js +5 -5
- package/dist/moonbase-c64.js.map +4 -4
- package/keys.js +10 -8
- package/package.json +3 -3
- package/test/keys.test.js +57 -0
package/browser.js
CHANGED
|
@@ -1,16 +1,17 @@
|
|
|
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 against the clock, a hitch caught up and a pause dropped (@moonbase-machines/mos6502/pace.js).
|
|
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
|
|
9
8
|
// its own)
|
|
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
|
-
// pace(m, after)
|
|
13
|
-
|
|
11
|
+
// pace(m, after, each) the machine run at 50 frames a second: each(frames) after
|
|
12
|
+
// each frame, after(frames) each animation frame
|
|
13
|
+
import { MATRIX, SHIFTED, WITH_SHIFT, CURSOR, MODIFIERS } from './keys.js';
|
|
14
|
+
import { pace as paced } from '@moonbase-machines/mos6502/pace.js';
|
|
14
15
|
import { PALETTE, WIDTH, HEIGHT } from './vic.js';
|
|
15
16
|
|
|
16
17
|
const PAD_DEAD = 0.4; // a stick pushed less far than this is at rest (the dead zone)
|
|
@@ -36,13 +37,12 @@ export function keyboard(m, { ignore = () => false, onKey = () => {}, log = fals
|
|
|
36
37
|
onKey(e);
|
|
37
38
|
if (e.metaKey || e.repeat) return;
|
|
38
39
|
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()];
|
|
40
|
+
const letter = /^Key([A-Z])$/.exec(e.code)?.[1]?.toLowerCase(), cursor = CURSOR[e.key];
|
|
41
|
+
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
42
|
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 &&
|
|
43
|
+
// (the left shift: a letter's graphic, a shifted sign, the cursor going up or left, and Shift with a function key,
|
|
44
|
+
// 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)
|
|
45
|
+
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
46
|
// (Control held, as the event says, the Commodore key down with the key, if Control's own
|
|
47
47
|
// keydown has not put it there, and let go with it)
|
|
48
48
|
const [cc, cr] = MODIFIERS.Control, cbm = e.ctrlKey && !(m.keys[cc] & 1 << cr) ? MODIFIERS.Control : null;
|
|
@@ -53,17 +53,16 @@ export function keyboard(m, { ignore = () => false, onKey = () => {}, log = fals
|
|
|
53
53
|
});
|
|
54
54
|
listen('keyup', e => {
|
|
55
55
|
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
56
|
const key = down.get(e.code);
|
|
58
57
|
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
58
|
});
|
|
60
59
|
// 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
|
-
//
|
|
60
|
+
// held, so everything is let go, the keys, the joystick and fire, or a key (CTRL by Tab) would stay
|
|
61
|
+
// down and every key after it be read wrongly
|
|
63
62
|
const letGo = () => { m.keys.fill(0); m.joystick = 0; down.clear(); held.length = 0; pressed.clear(); withCbm.clear(); padBits = 0; padStop = false; };
|
|
64
63
|
// 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
|
-
//
|
|
64
|
+
// (pushed past PAD_DEAD) the joystick in port 2, A or B its fire, Start RUN/STOP; let go with the
|
|
65
|
+
// pad
|
|
67
66
|
let padBits = 0, padStop = false;
|
|
68
67
|
const readPads = () => {
|
|
69
68
|
if (typeof navigator === 'undefined' || typeof navigator.getGamepads !== 'function') return;
|
|
@@ -105,14 +104,4 @@ export function painter(canvas) {
|
|
|
105
104
|
|
|
106
105
|
// the C64's 50 frames a second, kept up with the clock (two at most at a time, so a tab left in
|
|
107
106
|
// the background does not run on and on when it comes back); each(frame) after each one run
|
|
108
|
-
export
|
|
109
|
-
let frames = 0;
|
|
110
|
-
const started = performance.now();
|
|
111
|
-
function tick() {
|
|
112
|
-
const due = Math.min(2, Math.floor((performance.now() - started) / 20) - frames);
|
|
113
|
-
for (let i = 0; i < due; i++) { m.runFrame(); frames++; each(frames); }
|
|
114
|
-
after(frames);
|
|
115
|
-
requestAnimationFrame(tick);
|
|
116
|
-
}
|
|
117
|
-
tick();
|
|
118
|
-
}
|
|
107
|
+
export const pace = (m, after, each = () => {}) => paced(n => { m.runFrame(); each(n); }, 50, { after });
|