@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/keys.js CHANGED
@@ -1,5 +1,5 @@
1
- // The browser's keys as the C64's keyboard matrix, column then row, and the joystick in port 2
2
- // on the arrow keys with the fire button on the left control key or shift.
1
+ // The browser's keys as the C64's keyboard matrix, column then row: each key one key of the 64's, and nothing else.
2
+ // The joystick in port 2 is a joystick, a gamepad plugged in (browser.js), never a key.
3
3
  export const MATRIX = {
4
4
  Backspace: [0, 0], Delete: [0, 0], Enter: [0, 1], F7: [0, 3], F1: [0, 4], F3: [0, 5], F5: [0, 6],
5
5
  '3': [1, 0], w: [1, 1], a: [1, 2], '4': [1, 3], z: [1, 4], s: [1, 5], e: [1, 6],
@@ -7,15 +7,17 @@ export const MATRIX = {
7
7
  '7': [3, 0], y: [3, 1], g: [3, 2], '8': [3, 3], b: [3, 4], h: [3, 5], u: [3, 6], v: [3, 7],
8
8
  '9': [4, 0], i: [4, 1], j: [4, 2], '0': [4, 3], m: [4, 4], k: [4, 5], o: [4, 6], n: [4, 7],
9
9
  '+': [5, 0], p: [5, 1], l: [5, 2], '-': [5, 3], '.': [5, 4], ':': [5, 5], '@': [5, 6], ',': [5, 7],
10
- '£': [6, 0], '*': [6, 1], ';': [6, 2], Home: [6, 3], '=': [6, 5], '^': [6, 6], '/': [6, 7],
11
- '1': [7, 0], _: [7, 1], '2': [7, 3], ' ': [7, 4], q: [7, 6], Escape: [7, 7],
10
+ '£': [6, 0], '\\': [6, 0], '*': [6, 1], ';': [6, 2], Home: [6, 3], '=': [6, 5], '^': [6, 6], '/': [6, 7],
11
+ '1': [7, 0], _: [7, 1], '`': [7, 1], '2': [7, 3], ' ': [7, 4], q: [7, 6], Escape: [7, 7],
12
12
  };
13
+ // (the 64's £ also on \ and its ← also on `, where a Mac's keyboard has them: £ near the top right, ← at the top left,
14
+ // as the 64's are; and ← on _ as before)
13
15
  // keys that need shift on the C64: the shifted character (or function key) and its unshifted key
14
16
  export const SHIFTED = { '!': '1', '"': '2', '#': '3', '$': '4', '%': '5', '&': '6', "'": '7', '(': '8', ')': '9', '?': '/', '<': ',', '>': '.', '[': ':', ']': ';',
15
17
  F2: 'F1', F4: 'F3', F6: 'F5', F8: 'F7' }; // (F2, F4, F6 and F8 are shift with F1, F3, F5 and F7 on the 64)
16
- // the C64's own modifier keys, where VICE puts them: Control the Commodore key (and the
17
- // joystick's fire too), Tab CTRL
18
+ // keys that Shift with them makes the 64's shifted key: the function keys (F2, F4, F6, F8), Home (CLR), DEL (INST)
19
+ export const WITH_SHIFT = /^(F[1357]|Home|Backspace|Delete)$/;
20
+ // the C64's own modifier keys, where VICE puts them: Control the Commodore key, Tab CTRL
18
21
  export const MODIFIERS = { Control: [7, 5], Tab: [7, 2] };
19
- export const JOYSTICK = { ArrowUp: 1, ArrowDown: 2, ArrowLeft: 4, ArrowRight: 8, Control: 16, Shift: 16, Alt: 16 };
20
- // the arrow keys are also the cursor keys: down and right, and with shift, up and left
22
+ // the arrow keys are the cursor keys: down and right, and with shift, up and left
21
23
  export const CURSOR = { ArrowDown: [0, 7, 0], ArrowRight: [0, 2, 0], ArrowUp: [0, 7, 1], ArrowLeft: [0, 2, 1] };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@moonbase-machines/c64",
3
- "version": "0.11.0",
3
+ "version": "0.13.0",
4
4
  "description": "A Commodore 64 as far as the games use it: the VIC-II, the SID, a 1541, a printer, and Moonbase's own KERNAL and BASIC in place of Commodore's ROMs.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -10,8 +10,8 @@
10
10
  "./*": "./*"
11
11
  },
12
12
  "dependencies": {
13
- "@moonbase-machines/mos6502": "0.11.0",
14
- "@moonbase-machines/charset": "0.11.0"
13
+ "@moonbase-machines/mos6502": "0.13.0",
14
+ "@moonbase-machines/charset": "0.13.0"
15
15
  },
16
16
  "scripts": {
17
17
  "prepack": "node ../../tools/package-files.mjs c64"
@@ -0,0 +1,57 @@
1
+ // The page's keys (browser.js `keyboard`, keys.js): each key one key of the 64's and nothing else, the arrows its
2
+ // cursor keys, never the joystick; Control the Commodore key, never fire; Shift with Home CLR, with DEL INST; ` the
3
+ // 64's ←, \ its £. A key pressed on a page stood in for here, and what the 64's matrix and joystick get from it.
4
+ import { test } from 'node:test';
5
+ import assert from 'node:assert/strict';
6
+ import { keyboard } from '@moonbase-machines/c64/browser.js';
7
+
8
+ globalThis.window ??= { addEventListener() {} };
9
+ globalThis.document ??= { addEventListener() {}, hidden: false };
10
+
11
+ // a 64 that keeps what it is told: the matrix's keys down, and the joystick
12
+ function page() {
13
+ const m = { keys: new Uint8Array(8), joystick: 0, vic: { r: Object.assign(new Uint8Array(0x40), { 0x18: 0x15 }) },
14
+ key(column, row, down) { if (down) this.keys[column] |= 1 << row; else this.keys[column] &= ~(1 << row); } };
15
+ const on = { keydown: [], keyup: [] };
16
+ keyboard(m, { listen: (type, f) => on[type].push(f) });
17
+ const event = (key, code, mods = {}) => ({ key, code, metaKey: false, repeat: false, ctrlKey: false, shiftKey: false, altKey: false, preventDefault() {}, ...mods });
18
+ const press = (key, code = key, mods) => { const e = event(key, code, mods); on.keydown.forEach(f => f(e)); };
19
+ // the 64's keys down, as [column, row], in order
20
+ const down = () => [...m.keys].flatMap((bits, column) => Array.from({ length: 8 }, (_, row) => bits & 1 << row ? [[column, row]] : []).flat());
21
+ return { m, press, down };
22
+ }
23
+ const SHIFT = [1, 7];
24
+
25
+ test('an arrow is a cursor key and nothing else: down and right as they are, up and left with Shift', () => {
26
+ for (const [key, keys] of [['ArrowDown', [[0, 7]]], ['ArrowRight', [[0, 2]]], ['ArrowUp', [[0, 7], SHIFT]], ['ArrowLeft', [[0, 2], SHIFT]]]) {
27
+ const { m, press, down } = page();
28
+ press(key);
29
+ assert.deepEqual(down(), keys, key);
30
+ assert.equal(m.joystick, 0, `${key}: not the joystick`);
31
+ }
32
+ });
33
+
34
+ test('Control is the Commodore key, Shift and Option nothing of their own, and none of them fire', () => {
35
+ for (const [key, keys] of [['Control', [[7, 5]]], ['Shift', []], ['Alt', []]]) {
36
+ const { m, press, down } = page();
37
+ press(key, key + 'Left');
38
+ assert.deepEqual(down(), keys, key);
39
+ assert.equal(m.joystick, 0, `${key}: not fire`);
40
+ }
41
+ });
42
+
43
+ test('Shift with Home is CLR, with DEL INST, with F1 F2; and Home, DEL and F1 alone as they are', () => {
44
+ for (const [key, shift] of [['Home', true], ['Backspace', true], ['Delete', true], ['F1', true], ['Home', false], ['Backspace', false]]) {
45
+ const { press, down } = page();
46
+ press(key, key, { shiftKey: shift });
47
+ assert.equal(down().some(([c, r]) => c === SHIFT[0] && r === SHIFT[1]), shift, `${shift ? 'Shift and ' : ''}${key}`);
48
+ }
49
+ });
50
+
51
+ test('` is the 64\'s ←, \\ its £, and £ itself and _ still as they were, none with Shift', () => {
52
+ for (const [key, code, at] of [['`', 'Backquote', [7, 1]], ['\\', 'Backslash', [6, 0]], ['£', 'Digit3', [6, 0]], ['_', 'Minus', [7, 1]]]) {
53
+ const { press, down } = page();
54
+ press(key, code);
55
+ assert.deepEqual(down(), [at], key);
56
+ }
57
+ });