pxt-microbit 4.1.38 → 4.1.41
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/built/common-sim.d.ts +44 -0
- package/built/common-sim.js +139 -0
- package/built/editor.js +26 -45
- package/built/target.js +219 -32
- package/built/target.json +219 -32
- package/built/targetlight.json +6 -6
- package/built/web/react-common-authcode.css +140 -0
- package/built/web/react-common-skillmap.css +1 -1
- package/built/web/rtlreact-common-skillmap.css +1 -1
- package/built/web/rtlsemantic.css +1 -1
- package/built/web/semantic.css +1 -1
- package/package.json +3 -3
- package/pxtarget.json +1 -1
- package/targetconfig.json +426 -1473
package/built/common-sim.d.ts
CHANGED
|
@@ -728,6 +728,50 @@ declare namespace pxsim {
|
|
|
728
728
|
}
|
|
729
729
|
declare namespace pxsim.info {
|
|
730
730
|
}
|
|
731
|
+
declare namespace pxsim.keymap {
|
|
732
|
+
enum Key {
|
|
733
|
+
None = 0,
|
|
734
|
+
Left = 1,
|
|
735
|
+
Up = 2,
|
|
736
|
+
Right = 3,
|
|
737
|
+
Down = 4,
|
|
738
|
+
A = 5,
|
|
739
|
+
B = 6,
|
|
740
|
+
Menu = 7,
|
|
741
|
+
Screenshot = -1,
|
|
742
|
+
Gif = -2,
|
|
743
|
+
Reset = -3,
|
|
744
|
+
TogglePause = -4
|
|
745
|
+
}
|
|
746
|
+
function _setPlayerKeys(player: number, // player number is 1-based
|
|
747
|
+
up: number, down: number, left: number, right: number, A: number, B: number): void;
|
|
748
|
+
function _setSystemKeys(screenshot: number, gif: number, menu: number, reset: number): void;
|
|
749
|
+
}
|
|
750
|
+
declare namespace pxsim {
|
|
751
|
+
import Key = pxsim.keymap.Key;
|
|
752
|
+
interface KeymapBoard extends EventBusBoard {
|
|
753
|
+
keymapState: KeymapState;
|
|
754
|
+
}
|
|
755
|
+
function getKeymapState(): KeymapState;
|
|
756
|
+
class KeymapState {
|
|
757
|
+
keymap: {
|
|
758
|
+
[keyCode: number]: Key;
|
|
759
|
+
};
|
|
760
|
+
altmap: {
|
|
761
|
+
[keyCode: number]: Key;
|
|
762
|
+
};
|
|
763
|
+
mappings: {
|
|
764
|
+
[name: string]: number[];
|
|
765
|
+
};
|
|
766
|
+
constructor();
|
|
767
|
+
setPlayerKeys(player: number, // player number is 1-based
|
|
768
|
+
up: number, down: number, left: number, right: number, A: number, B: number): void;
|
|
769
|
+
setSystemKeys(screenshot: number, gif: number, menu: number, reset: number): void;
|
|
770
|
+
getKey(keyCode: number): Key;
|
|
771
|
+
private saveMap;
|
|
772
|
+
private clearMap;
|
|
773
|
+
}
|
|
774
|
+
}
|
|
731
775
|
declare namespace pxsim.multiplayer {
|
|
732
776
|
function postImage(im: pxsim.RefImage, goal: string): void;
|
|
733
777
|
function getCurrentImage(): pxsim.RefImage;
|
package/built/common-sim.js
CHANGED
|
@@ -2395,6 +2395,145 @@ var pxsim;
|
|
|
2395
2395
|
pxsim.ToggleState = ToggleState;
|
|
2396
2396
|
})(pxsim || (pxsim = {}));
|
|
2397
2397
|
var pxsim;
|
|
2398
|
+
(function (pxsim) {
|
|
2399
|
+
var keymap;
|
|
2400
|
+
(function (keymap) {
|
|
2401
|
+
// Keep in sync with pxt-arcade-sim/api.ts
|
|
2402
|
+
let Key;
|
|
2403
|
+
(function (Key) {
|
|
2404
|
+
Key[Key["None"] = 0] = "None";
|
|
2405
|
+
// Player 1
|
|
2406
|
+
Key[Key["Left"] = 1] = "Left";
|
|
2407
|
+
Key[Key["Up"] = 2] = "Up";
|
|
2408
|
+
Key[Key["Right"] = 3] = "Right";
|
|
2409
|
+
Key[Key["Down"] = 4] = "Down";
|
|
2410
|
+
Key[Key["A"] = 5] = "A";
|
|
2411
|
+
Key[Key["B"] = 6] = "B";
|
|
2412
|
+
Key[Key["Menu"] = 7] = "Menu";
|
|
2413
|
+
// Player 2 = Player 1 + 7
|
|
2414
|
+
// Player 3 = Player 2 + 7
|
|
2415
|
+
// Player 4 = Player 3 + 7
|
|
2416
|
+
// system keys
|
|
2417
|
+
Key[Key["Screenshot"] = -1] = "Screenshot";
|
|
2418
|
+
Key[Key["Gif"] = -2] = "Gif";
|
|
2419
|
+
Key[Key["Reset"] = -3] = "Reset";
|
|
2420
|
+
Key[Key["TogglePause"] = -4] = "TogglePause";
|
|
2421
|
+
})(Key = keymap.Key || (keymap.Key = {}));
|
|
2422
|
+
function _setPlayerKeys(player, // player number is 1-based
|
|
2423
|
+
up, down, left, right, A, B) {
|
|
2424
|
+
pxsim.getKeymapState().setPlayerKeys(player, up, down, left, right, A, B);
|
|
2425
|
+
}
|
|
2426
|
+
keymap._setPlayerKeys = _setPlayerKeys;
|
|
2427
|
+
function _setSystemKeys(screenshot, gif, menu, reset) {
|
|
2428
|
+
pxsim.getKeymapState().setSystemKeys(screenshot, gif, menu, reset);
|
|
2429
|
+
}
|
|
2430
|
+
keymap._setSystemKeys = _setSystemKeys;
|
|
2431
|
+
})(keymap = pxsim.keymap || (pxsim.keymap = {}));
|
|
2432
|
+
})(pxsim || (pxsim = {}));
|
|
2433
|
+
(function (pxsim) {
|
|
2434
|
+
var Key = pxsim.keymap.Key;
|
|
2435
|
+
function getKeymapState() {
|
|
2436
|
+
return pxsim.board().keymapState;
|
|
2437
|
+
}
|
|
2438
|
+
pxsim.getKeymapState = getKeymapState;
|
|
2439
|
+
const reservedKeyCodes = [
|
|
2440
|
+
27,
|
|
2441
|
+
9 // Tab
|
|
2442
|
+
];
|
|
2443
|
+
class KeymapState {
|
|
2444
|
+
constructor() {
|
|
2445
|
+
this.keymap = {};
|
|
2446
|
+
this.altmap = {};
|
|
2447
|
+
this.mappings = {};
|
|
2448
|
+
// Player 1 keymap
|
|
2449
|
+
this.setPlayerKeys(1, // Player 1
|
|
2450
|
+
87, // W - Up
|
|
2451
|
+
83, // D - Down
|
|
2452
|
+
65, // A - Left
|
|
2453
|
+
83, // S - Right
|
|
2454
|
+
32, // Space - A
|
|
2455
|
+
13 // Enter - B
|
|
2456
|
+
);
|
|
2457
|
+
// Player 2 keymap
|
|
2458
|
+
this.setPlayerKeys(2, // Player 2
|
|
2459
|
+
73, // I - Up
|
|
2460
|
+
75, // K - Down
|
|
2461
|
+
74, // J - Left
|
|
2462
|
+
75, // K - Right
|
|
2463
|
+
85, // U - A
|
|
2464
|
+
79 // O - B
|
|
2465
|
+
);
|
|
2466
|
+
// Note: Player 3 and 4 have no default keyboard mapping
|
|
2467
|
+
// System keymap
|
|
2468
|
+
this.setSystemKeys(80, // P - Screenshot
|
|
2469
|
+
82, // R - Gif
|
|
2470
|
+
0, // Menu - not mapped
|
|
2471
|
+
0 // Reset - not mapped
|
|
2472
|
+
);
|
|
2473
|
+
// Player 1 alternate mapping. This is cleared when the game sets any player keys explicitly
|
|
2474
|
+
this.altmap[38] = Key.Up; // UpArrow
|
|
2475
|
+
this.altmap[37] = Key.Left; // LeftArrow
|
|
2476
|
+
this.altmap[40] = Key.Down; // DownArrow
|
|
2477
|
+
this.altmap[39] = Key.Right; // RightArrow
|
|
2478
|
+
this.altmap[81] = Key.A; // Q
|
|
2479
|
+
this.altmap[90] = Key.A; // Z
|
|
2480
|
+
this.altmap[88] = Key.B; // X
|
|
2481
|
+
this.altmap[69] = Key.B; // E
|
|
2482
|
+
}
|
|
2483
|
+
setPlayerKeys(player, // player number is 1-based
|
|
2484
|
+
up, down, left, right, A, B) {
|
|
2485
|
+
// We only support four players
|
|
2486
|
+
if (player < 1 || player > 4)
|
|
2487
|
+
return;
|
|
2488
|
+
const keyCodes = [up, down, left, right, A, B];
|
|
2489
|
+
// Check for reserved key codes
|
|
2490
|
+
// TODO: How to surface this runtime error to the user?
|
|
2491
|
+
// TODO: Send message to UI: "Keyboard mapping contains a reserved key code"
|
|
2492
|
+
const filtered = keyCodes.filter(keyCode => reservedKeyCodes.includes(keyCode));
|
|
2493
|
+
if (filtered.length)
|
|
2494
|
+
return;
|
|
2495
|
+
// Clear existing mapped keys for player
|
|
2496
|
+
const mapName = `player-${player}`;
|
|
2497
|
+
this.clearMap(mapName);
|
|
2498
|
+
// Clear altmap When explicitly setting the player keys
|
|
2499
|
+
this.altmap = {};
|
|
2500
|
+
// Map the new keys
|
|
2501
|
+
const offset = (player - 1) * 7; // +7 for player 2's keys
|
|
2502
|
+
this.keymap[up] = Key.Up + offset;
|
|
2503
|
+
this.keymap[down] = Key.Down + offset;
|
|
2504
|
+
this.keymap[left] = Key.Left + offset;
|
|
2505
|
+
this.keymap[right] = Key.Right + offset;
|
|
2506
|
+
this.keymap[A] = Key.A + offset;
|
|
2507
|
+
this.keymap[B] = Key.B + offset;
|
|
2508
|
+
// Remember this mapping
|
|
2509
|
+
this.saveMap(mapName, keyCodes);
|
|
2510
|
+
}
|
|
2511
|
+
setSystemKeys(screenshot, gif, menu, reset) {
|
|
2512
|
+
const mapName = "system";
|
|
2513
|
+
// Clear existing mapped keys for system
|
|
2514
|
+
this.clearMap(mapName);
|
|
2515
|
+
this.keymap[screenshot] = Key.Screenshot;
|
|
2516
|
+
this.keymap[gif] = Key.Gif;
|
|
2517
|
+
this.keymap[menu] = Key.Menu;
|
|
2518
|
+
this.keymap[reset] = Key.Reset;
|
|
2519
|
+
// Remember this mapping
|
|
2520
|
+
this.saveMap(mapName, [screenshot, gif, menu, reset]);
|
|
2521
|
+
}
|
|
2522
|
+
getKey(keyCode) {
|
|
2523
|
+
return keyCode ? this.keymap[keyCode] || this.altmap[keyCode] || Key.None : Key.None;
|
|
2524
|
+
}
|
|
2525
|
+
saveMap(name, keyCodes) {
|
|
2526
|
+
this.mappings[name] = keyCodes;
|
|
2527
|
+
}
|
|
2528
|
+
clearMap(name) {
|
|
2529
|
+
const keyCodes = this.mappings[name];
|
|
2530
|
+
keyCodes === null || keyCodes === void 0 ? void 0 : keyCodes.forEach(keyCode => delete this.keymap[keyCode]);
|
|
2531
|
+
delete this.mappings[name];
|
|
2532
|
+
}
|
|
2533
|
+
}
|
|
2534
|
+
pxsim.KeymapState = KeymapState;
|
|
2535
|
+
})(pxsim || (pxsim = {}));
|
|
2536
|
+
var pxsim;
|
|
2398
2537
|
(function (pxsim) {
|
|
2399
2538
|
var multiplayer;
|
|
2400
2539
|
(function (multiplayer) {
|
package/built/editor.js
CHANGED
|
@@ -3245,26 +3245,25 @@ class DAPWrapper {
|
|
|
3245
3245
|
}
|
|
3246
3246
|
return len;
|
|
3247
3247
|
}
|
|
3248
|
-
startReadSerial() {
|
|
3249
|
-
const rid = this.connectionId;
|
|
3248
|
+
startReadSerial(connectionId) {
|
|
3250
3249
|
const startTime = Date.now();
|
|
3251
|
-
log(`start read serial ${
|
|
3250
|
+
log(`start read serial ${connectionId}`);
|
|
3252
3251
|
const readSerialLoop = async () => {
|
|
3253
3252
|
try {
|
|
3254
|
-
while (
|
|
3253
|
+
while (connectionId === this.connectionId) {
|
|
3255
3254
|
const len = await this.readSerial();
|
|
3256
3255
|
const hasData = len > 0;
|
|
3257
3256
|
//if (hasData)
|
|
3258
3257
|
// logV(`serial read ${len} bytes`)
|
|
3259
3258
|
await this.jacdacProcess(hasData);
|
|
3260
3259
|
}
|
|
3261
|
-
log(`stopped serial reader ${
|
|
3260
|
+
log(`stopped serial reader ${connectionId}`);
|
|
3262
3261
|
}
|
|
3263
3262
|
catch (err) {
|
|
3264
|
-
log(`serial error ${
|
|
3263
|
+
log(`serial error ${connectionId}: ${err.message}`);
|
|
3265
3264
|
console.error(err);
|
|
3266
|
-
if (
|
|
3267
|
-
log(`stopped serial reader ${
|
|
3265
|
+
if (connectionId != this.connectionId) {
|
|
3266
|
+
log(`stopped serial reader ${connectionId}`);
|
|
3268
3267
|
}
|
|
3269
3268
|
else {
|
|
3270
3269
|
pxt.tickEvent("hid.flash.serial.error");
|
|
@@ -3340,8 +3339,9 @@ class DAPWrapper {
|
|
|
3340
3339
|
log(`page size ${this.pageSize}, num pages ${this.numPages}`);
|
|
3341
3340
|
await this.checkStateAsync(true);
|
|
3342
3341
|
// start jacdac, serial async
|
|
3343
|
-
this.
|
|
3344
|
-
this.
|
|
3342
|
+
const connectionId = this.connectionId;
|
|
3343
|
+
this.startJacdacSetup(connectionId)
|
|
3344
|
+
.then(() => this.startReadSerial(connectionId));
|
|
3345
3345
|
}
|
|
3346
3346
|
async checkStateAsync(resume) {
|
|
3347
3347
|
const states = ["reset", "lockup", "sleeping", "halted", "running"];
|
|
@@ -3695,32 +3695,13 @@ class DAPWrapper {
|
|
|
3695
3695
|
async findJacdacXchgAddr(cid) {
|
|
3696
3696
|
const memStart = 536870912;
|
|
3697
3697
|
const memStop = memStart + 128 * 1024;
|
|
3698
|
-
const
|
|
3699
|
-
|
|
3700
|
-
|
|
3701
|
-
|
|
3702
|
-
|
|
3703
|
-
|
|
3704
|
-
|
|
3705
|
-
return null;
|
|
3706
|
-
const buf = await this.readWords(addr, checkSize >> 2);
|
|
3707
|
-
for (let i = 0; i < buf.length; ++i) {
|
|
3708
|
-
if (buf[i] == 0x786D444A && buf[i + 1] == 0xB0A6C0E9)
|
|
3709
|
-
return addr + (i << 2);
|
|
3710
|
-
}
|
|
3711
|
-
return 0;
|
|
3712
|
-
};
|
|
3713
|
-
while (cid == this.connectionId) {
|
|
3714
|
-
const a0 = await check(p0);
|
|
3715
|
-
if (a0)
|
|
3716
|
-
return a0;
|
|
3717
|
-
const a1 = await check(p1);
|
|
3718
|
-
if (a1)
|
|
3719
|
-
return a1;
|
|
3720
|
-
if (a0 === null && a1 === null)
|
|
3721
|
-
return null;
|
|
3722
|
-
p0 -= checkSize;
|
|
3723
|
-
p1 += checkSize;
|
|
3698
|
+
const addr = (await this.readWords(memStop - 4, 1))[0];
|
|
3699
|
+
if (cid != this.connectionId)
|
|
3700
|
+
return null;
|
|
3701
|
+
if (memStart <= addr && addr < memStop) {
|
|
3702
|
+
const buf = await this.readWords(addr, 2);
|
|
3703
|
+
if (buf[0] == 0x786D444A && buf[1] == 0xB0A6C0E9)
|
|
3704
|
+
return addr;
|
|
3724
3705
|
}
|
|
3725
3706
|
return null;
|
|
3726
3707
|
}
|
|
@@ -3729,9 +3710,10 @@ class DAPWrapper {
|
|
|
3729
3710
|
* and gracefull cancel as needed
|
|
3730
3711
|
* @returns
|
|
3731
3712
|
*/
|
|
3732
|
-
async startJacdacSetup() {
|
|
3713
|
+
async startJacdacSetup(connectionId) {
|
|
3733
3714
|
this.xchgAddr = null;
|
|
3734
3715
|
this.irqn = undefined;
|
|
3716
|
+
this.lastXchg = undefined;
|
|
3735
3717
|
if (!this.usesCODAL) {
|
|
3736
3718
|
log(`jacdac: CODAL disabled`);
|
|
3737
3719
|
return;
|
|
@@ -3740,19 +3722,18 @@ class DAPWrapper {
|
|
|
3740
3722
|
log(`jacdac: jacdac not compiled in`);
|
|
3741
3723
|
return;
|
|
3742
3724
|
}
|
|
3743
|
-
const cid = this.connectionId;
|
|
3744
3725
|
try {
|
|
3745
3726
|
// allow jacdac to boot
|
|
3746
3727
|
const now = pxt.U.now();
|
|
3747
3728
|
await pxt.Util.delay(1000);
|
|
3748
3729
|
let xchgRetry = 0;
|
|
3749
3730
|
let xchg;
|
|
3750
|
-
while (xchg == null && xchgRetry++ <
|
|
3731
|
+
while (xchg == null && xchgRetry++ < 3) {
|
|
3751
3732
|
log(`jacdac: finding xchg address (retry ${xchgRetry})`);
|
|
3752
|
-
await pxt.Util.delay(
|
|
3753
|
-
if (
|
|
3733
|
+
await pxt.Util.delay(500); // wait for the program to start and setup memory correctly
|
|
3734
|
+
if (connectionId != this.connectionId)
|
|
3754
3735
|
return;
|
|
3755
|
-
xchg = await this.findJacdacXchgAddr(
|
|
3736
|
+
xchg = await this.findJacdacXchgAddr(connectionId);
|
|
3756
3737
|
}
|
|
3757
3738
|
log(`jacdac: exchange address 0x${xchg ? xchg.toString(16) : "?"}; ${xchgRetry} retries; ${(pxt.U.now() - now) | 0}ms`);
|
|
3758
3739
|
if (xchg == null) {
|
|
@@ -3761,7 +3742,7 @@ class DAPWrapper {
|
|
|
3761
3742
|
pxt.tickEvent("hid.flash.jacdac.error.missingxchg");
|
|
3762
3743
|
return;
|
|
3763
3744
|
}
|
|
3764
|
-
if (
|
|
3745
|
+
if (connectionId != this.connectionId)
|
|
3765
3746
|
return;
|
|
3766
3747
|
const info = await this.readBytes(xchg, 16);
|
|
3767
3748
|
if (info[12 + 2] != 0xff) {
|
|
@@ -3771,7 +3752,7 @@ class DAPWrapper {
|
|
|
3771
3752
|
return;
|
|
3772
3753
|
}
|
|
3773
3754
|
// make sure connection is not outdated
|
|
3774
|
-
if (
|
|
3755
|
+
if (connectionId != this.connectionId)
|
|
3775
3756
|
return;
|
|
3776
3757
|
// clear initial lock
|
|
3777
3758
|
await this.writeWord(xchg + 12, 0);
|
|
@@ -3782,7 +3763,7 @@ class DAPWrapper {
|
|
|
3782
3763
|
pxt.tickEvent("hid.flash.jacdac.connected");
|
|
3783
3764
|
}
|
|
3784
3765
|
catch (e) {
|
|
3785
|
-
if (
|
|
3766
|
+
if (connectionId != this.connectionId) {
|
|
3786
3767
|
log(`jacdac: setup aborted`);
|
|
3787
3768
|
return;
|
|
3788
3769
|
}
|