pxt-common-packages 12.3.1 → 12.3.3

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.
Files changed (41) hide show
  1. package/built/common-sim.d.ts +4 -0
  2. package/built/common-sim.js +275 -0
  3. package/libs/azureiot/built/debug/binary.js +461 -461
  4. package/libs/browser-events/browserEvents.ts +9 -9
  5. package/libs/color/built/debug/binary.js +8 -8
  6. package/libs/color-sensor/built/debug/binary.js +8 -8
  7. package/libs/controller/built/debug/binary.js +9969 -8494
  8. package/libs/controller---none/built/debug/binary.js +9948 -8473
  9. package/libs/datalogger/built/debug/binary.js +63 -63
  10. package/libs/edge-connector/built/debug/binary.js +8 -8
  11. package/libs/esp32/built/debug/binary.js +462 -462
  12. package/libs/game/_locales/game-strings.json +4 -0
  13. package/libs/game/built/debug/binary.js +9843 -8368
  14. package/libs/game/docs/reference/sprites/on-overlap.md +32 -109
  15. package/libs/game/docs/reference/sprites/sprite/say.md +43 -18
  16. package/libs/game/hitbox.ts +13 -9
  17. package/libs/game/pxt.json +1 -0
  18. package/libs/game/rotation.ts +194 -0
  19. package/libs/game/sprite.ts +102 -8
  20. package/libs/lcd/built/debug/binary.js +8 -8
  21. package/libs/light-spectrum-sensor/built/debug/binary.js +9 -9
  22. package/libs/lora/built/debug/binary.js +8 -8
  23. package/libs/matrix-keypad/built/debug/binary.js +8 -8
  24. package/libs/mqtt/built/debug/binary.js +176 -176
  25. package/libs/net/built/debug/binary.js +176 -176
  26. package/libs/net-game/built/debug/binary.js +11768 -10293
  27. package/libs/palette/built/debug/binary.js +9860 -8385
  28. package/libs/pixel/built/debug/binary.js +8 -8
  29. package/libs/power/built/debug/binary.js +8 -8
  30. package/libs/proximity/built/debug/binary.js +8 -8
  31. package/libs/radio/built/debug/binary.js +8 -8
  32. package/libs/radio-broadcast/built/debug/binary.js +8 -8
  33. package/libs/rotary-encoder/built/debug/binary.js +8 -8
  34. package/libs/screen/built/debug/binary.js +50 -50
  35. package/libs/screen/image.cpp +374 -0
  36. package/libs/screen/image.ts +42 -0
  37. package/libs/screen/sim/image.ts +406 -0
  38. package/libs/servo/built/debug/binary.js +8 -8
  39. package/libs/sprite-scaling/built/debug/binary.js +9860 -8385
  40. package/libs/storyboard/built/debug/binary.js +9860 -8385
  41. package/package.json +1 -1
@@ -1,5 +1,6 @@
1
1
  #include "pxt.h"
2
2
 
3
+
3
4
  #if IMAGE_BITS == 1
4
5
  // OK
5
6
  #elif IMAGE_BITS == 4
@@ -1125,6 +1126,379 @@ bool blit(Image_ dst, Image_ src, pxt::RefCollection *args) {
1125
1126
  return false;
1126
1127
  }
1127
1128
 
1129
+ #define FX_SHIFT 16
1130
+ #define FX_ONE (1 << FX_SHIFT)
1131
+
1132
+ inline int fxMul(int a, int b) {
1133
+ return (int)(((int64_t)a * b) >> FX_SHIFT);
1134
+ }
1135
+
1136
+ inline int fxDiv(int a, int b) {
1137
+ return (int)(((int64_t)a << FX_SHIFT) / b);
1138
+ }
1139
+
1140
+ inline int fxToInt(int v) {
1141
+ return v >> FX_SHIFT;
1142
+ }
1143
+
1144
+ inline int fxFloor(int v) {
1145
+ return v & 0xffff0000;
1146
+ }
1147
+
1148
+ #define TWO_PI 6.28318530718
1149
+ #define PI 3.14159265359
1150
+ #define HALF_PI 1.57079632679
1151
+ #define THREE_HALF_PI 4.71238898038
1152
+
1153
+ #define SHEAR(x, y, xShear, yShear) \
1154
+ shearedX = fxFloor(x + fxMul(y, xShear)); \
1155
+ shearedY = fxFloor(y + fxMul(shearedX, yShear)); \
1156
+ shearedX = fxFloor(shearedX + fxMul(shearedY, xShear));
1157
+
1158
+ #define REVERSE_SHEAR(x, y, xShear, yShear) \
1159
+ unshearedX = fxFloor(x - fxMul(y, xShear)); \
1160
+ unshearedY = fxFloor(y - fxMul(unshearedX, yShear)); \
1161
+ unshearedX = fxFloor(unshearedX - fxMul(unshearedY, xShear));
1162
+
1163
+
1164
+ typedef struct {
1165
+ int sx;
1166
+ int sy;
1167
+ int xShear;
1168
+ int yShear;
1169
+ int minX;
1170
+ int minY;
1171
+ int maxX;
1172
+ int maxY;
1173
+ int scaledWidth;
1174
+ int scaledHeight;
1175
+ bool flip;
1176
+ } ParsedShearArgs;
1177
+
1178
+ ParsedShearArgs parseShearArgs(Image_ src, pxt::RefCollection *args, int argIndex) {
1179
+ ParsedShearArgs parsed;
1180
+ int sx = pxt::toDouble(args->getAt(argIndex)) * FX_ONE;
1181
+ int sy = pxt::toDouble(args->getAt(argIndex + 1)) * FX_ONE;
1182
+ double angle = pxt::toDouble(args->getAt(argIndex + 2));
1183
+
1184
+ parsed.sx = sx;
1185
+ parsed.sy = sy;
1186
+
1187
+ if (sx <= 0 || sy <= 0) {
1188
+ return parsed;
1189
+ }
1190
+
1191
+ parsed.flip = false;
1192
+
1193
+ angle = fmod(angle, TWO_PI);
1194
+
1195
+ if (angle < 0) {
1196
+ angle = angle + TWO_PI;
1197
+ }
1198
+
1199
+ if (angle > HALF_PI && angle <= THREE_HALF_PI) {
1200
+ parsed.flip = true;
1201
+ angle = fmod(angle + PI, TWO_PI);
1202
+ }
1203
+
1204
+ int xShear = (-1.0 * tan(angle / 2.0)) * FX_ONE;
1205
+ int yShear = (sin(angle)) * FX_ONE;
1206
+
1207
+ int scaledWidth = sx * src->width();
1208
+ int scaledHeight = sy * src->height();
1209
+
1210
+ int shearedX = 0;
1211
+ int shearedY = 0;
1212
+
1213
+ SHEAR(0, 0, xShear, yShear);
1214
+ int minX = shearedX;
1215
+ int minY = shearedY;
1216
+ int maxX = shearedX;
1217
+ int maxY = shearedY;
1218
+
1219
+ SHEAR(scaledWidth - FX_ONE, 0, xShear, yShear);
1220
+ minX = min(minX, shearedX);
1221
+ minY = min(minY, shearedY);
1222
+ maxX = max(maxX, shearedX);
1223
+ maxY = max(maxY, shearedY);
1224
+
1225
+ SHEAR(scaledWidth - FX_ONE, scaledHeight - FX_ONE, xShear, yShear);
1226
+ minX = min(minX, shearedX);
1227
+ minY = min(minY, shearedY);
1228
+ maxX = max(maxX, shearedX);
1229
+ maxY = max(maxY, shearedY);
1230
+
1231
+ SHEAR(0, scaledHeight - FX_ONE, xShear, yShear);
1232
+ minX = min(minX, shearedX);
1233
+ minY = min(minY, shearedY);
1234
+ maxX = max(maxX, shearedX);
1235
+ maxY = max(maxY, shearedY);
1236
+
1237
+ parsed.minX = minX;
1238
+ parsed.minY = minY;
1239
+ parsed.maxX = maxX;
1240
+ parsed.maxY = maxY;
1241
+ parsed.scaledWidth = scaledWidth;
1242
+ parsed.scaledHeight = scaledHeight;
1243
+ parsed.xShear = xShear;
1244
+ parsed.yShear = yShear;
1245
+
1246
+ return parsed;
1247
+ }
1248
+
1249
+ //%
1250
+ void _drawScaledRotatedImage(Image_ dst, Image_ src, pxt::RefCollection *args) {
1251
+ int xDst = pxt::toInt(args->getAt(0));
1252
+ int yDst = pxt::toInt(args->getAt(1));
1253
+ if (xDst >= dst->width() || yDst >= dst->height()) {
1254
+ return;
1255
+ }
1256
+
1257
+ ParsedShearArgs shearArgs = parseShearArgs(src, args, 2);
1258
+
1259
+ if (
1260
+ shearArgs.sx <= 0 ||
1261
+ shearArgs.sy <= 0 ||
1262
+ xDst + fxToInt(shearArgs.maxX - shearArgs.minX) < 0 ||
1263
+ yDst + fxToInt(shearArgs.maxY - shearArgs.minY) < 0
1264
+ ) {
1265
+ return;
1266
+ }
1267
+
1268
+ int shearedX = 0;
1269
+ int shearedY = 0;
1270
+
1271
+ dst->makeWritable();
1272
+
1273
+ if (shearArgs.flip) {
1274
+ for (int y = 0; y < shearArgs.scaledHeight; y += FX_ONE) {
1275
+ for (int x = 0; x < shearArgs.scaledWidth; x += FX_ONE) {
1276
+ int color = getPixel(
1277
+ src,
1278
+ fxToInt(fxDiv((shearArgs.scaledWidth - x - FX_ONE), shearArgs.sx)),
1279
+ fxToInt(fxDiv((shearArgs.scaledHeight - y - FX_ONE), shearArgs.sy))
1280
+ );
1281
+
1282
+ if (!color) continue;
1283
+
1284
+ SHEAR(x, y, shearArgs.xShear, shearArgs.yShear);
1285
+ setPixel(dst, xDst + fxToInt(shearedX - shearArgs.minX), yDst + fxToInt(shearedY - shearArgs.minY), color);
1286
+ }
1287
+ }
1288
+ }
1289
+ else {
1290
+ for (int y = 0; y < shearArgs.scaledHeight; y += FX_ONE) {
1291
+ for (int x = 0; x < shearArgs.scaledWidth; x += FX_ONE) {
1292
+ int color = getPixel(
1293
+ src,
1294
+ fxToInt(fxDiv(x, shearArgs.sx)),
1295
+ fxToInt(fxDiv(y,shearArgs. sy))
1296
+ );
1297
+
1298
+ if (!color) continue;
1299
+
1300
+ SHEAR(x, y, shearArgs.xShear, shearArgs.yShear);
1301
+ setPixel(dst, xDst + fxToInt(shearedX - shearArgs.minX), yDst + fxToInt(shearedY - shearArgs.minY), color);
1302
+ }
1303
+ }
1304
+ }
1305
+ }
1306
+
1307
+ //%
1308
+ bool _checkOverlapsScaledRotatedImage(Image_ dst, Image_ src, pxt::RefCollection *args) {
1309
+ int xDst = pxt::toInt(args->getAt(0));
1310
+ int yDst = pxt::toInt(args->getAt(1));
1311
+ if (xDst >= dst->width() || yDst >= dst->height()) {
1312
+ return false;
1313
+ }
1314
+
1315
+ ParsedShearArgs shearArgs = parseShearArgs(src, args, 2);
1316
+
1317
+ if (
1318
+ shearArgs.sx <= 0 ||
1319
+ shearArgs.sy <= 0 ||
1320
+ xDst + fxToInt(shearArgs.maxX - shearArgs.minX) < 0 ||
1321
+ yDst + fxToInt(shearArgs.maxY - shearArgs.minY) < 0
1322
+ ) {
1323
+ return false;
1324
+ }
1325
+
1326
+ int shearedX = 0;
1327
+ int shearedY = 0;
1328
+
1329
+ if (shearArgs.flip) {
1330
+ for (int y = 0; y < shearArgs.scaledHeight; y += FX_ONE) {
1331
+ for (int x = 0; x < shearArgs.scaledWidth; x += FX_ONE) {
1332
+ int color = getPixel(
1333
+ src,
1334
+ fxToInt(fxDiv((shearArgs.scaledWidth - x - FX_ONE), shearArgs.sx)),
1335
+ fxToInt(fxDiv((shearArgs.scaledHeight - y - FX_ONE), shearArgs.sy))
1336
+ );
1337
+
1338
+ if (!color) continue;
1339
+
1340
+ SHEAR(x, y, shearArgs.xShear, shearArgs.yShear);
1341
+ if (getPixel(dst, xDst + fxToInt(shearedX - shearArgs.minX), yDst + fxToInt(shearedY - shearArgs.minY))) {
1342
+ return true;
1343
+ }
1344
+ }
1345
+ }
1346
+ }
1347
+ else {
1348
+ for (int y = 0; y < shearArgs.scaledHeight; y += FX_ONE) {
1349
+ for (int x = 0; x < shearArgs.scaledWidth; x += FX_ONE) {
1350
+ int color = getPixel(
1351
+ src,
1352
+ fxToInt(fxDiv(x, shearArgs.sx)),
1353
+ fxToInt(fxDiv(y,shearArgs. sy))
1354
+ );
1355
+
1356
+ if (!color) continue;
1357
+
1358
+ SHEAR(x, y, shearArgs.xShear, shearArgs.yShear);
1359
+ if (getPixel(dst, xDst + fxToInt(shearedX - shearArgs.minX), yDst + fxToInt(shearedY - shearArgs.minY))) {
1360
+ return true;
1361
+ }
1362
+ }
1363
+ }
1364
+ }
1365
+ return false;
1366
+ }
1367
+
1368
+ //%
1369
+ bool _checkOverlapsTwoScaledRotatedImages(Image_ dst, Image_ src, pxt::RefCollection *args) {
1370
+ int xDst = pxt::toInt(args->getAt(0)) * FX_ONE;
1371
+ int yDst = pxt::toInt(args->getAt(1)) * FX_ONE;
1372
+ ParsedShearArgs dstArgs = parseShearArgs(dst, args, 2);
1373
+
1374
+ if (
1375
+ dstArgs.sx <= 0 ||
1376
+ dstArgs.sy <= 0 ||
1377
+ xDst >= dstArgs.maxX - dstArgs.minX ||
1378
+ yDst >= dstArgs.maxY - dstArgs.minY
1379
+ ) {
1380
+ return false;
1381
+ }
1382
+
1383
+ ParsedShearArgs srcArgs = parseShearArgs(src, args, 5);
1384
+
1385
+ if (
1386
+ srcArgs.sx <= 0 ||
1387
+ srcArgs.sy <= 0 ||
1388
+ xDst + srcArgs.maxX - srcArgs.minX < 0 ||
1389
+ yDst + srcArgs.maxY - srcArgs.minY < 0
1390
+ ) {
1391
+ return false;
1392
+ }
1393
+
1394
+ int shearedX = 0;
1395
+ int shearedY = 0;
1396
+ int unshearedX = 0;
1397
+ int unshearedY = 0;
1398
+
1399
+ if (srcArgs.flip) {
1400
+ for (int y = 0; y < srcArgs.scaledHeight; y += FX_ONE) {
1401
+ for (int x = 0; x < srcArgs.scaledWidth; x += FX_ONE) {
1402
+ int color = getPixel(
1403
+ src,
1404
+ fxToInt(fxDiv((srcArgs.scaledWidth - x - FX_ONE), srcArgs.sx)),
1405
+ fxToInt(fxDiv((srcArgs.scaledHeight - y - FX_ONE), srcArgs.sy))
1406
+ );
1407
+
1408
+ if (!color) continue;
1409
+
1410
+ SHEAR(x, y, srcArgs.xShear, srcArgs.yShear);
1411
+
1412
+ int screenX = xDst + shearedX - srcArgs.minX;
1413
+ int screenY = yDst + shearedY - srcArgs.minY;
1414
+
1415
+ if (
1416
+ screenX < 0 ||
1417
+ screenY < 0 ||
1418
+ screenX >= dstArgs.maxX - dstArgs.minX ||
1419
+ screenY >= dstArgs.maxY - dstArgs.minY
1420
+ ) {
1421
+ continue;
1422
+ }
1423
+
1424
+ REVERSE_SHEAR(screenX + dstArgs.minX, screenY + dstArgs.minY, dstArgs.xShear, dstArgs.yShear);
1425
+
1426
+ if (dstArgs.flip) {
1427
+ if (
1428
+ getPixel(
1429
+ dst,
1430
+ fxToInt(fxDiv(dstArgs.scaledWidth - unshearedX - FX_ONE, dstArgs.sx)),
1431
+ fxToInt(fxDiv(dstArgs.scaledHeight - unshearedY - FX_ONE, dstArgs.sy))
1432
+ )
1433
+ ) {
1434
+ return true;
1435
+ }
1436
+ }
1437
+ else if (
1438
+ getPixel(
1439
+ dst,
1440
+ fxToInt(fxDiv(unshearedX, dstArgs.sx)),
1441
+ fxToInt(fxDiv(unshearedY, dstArgs.sy))
1442
+ )
1443
+ ) {
1444
+ return true;
1445
+ }
1446
+ }
1447
+ }
1448
+ }
1449
+ else {
1450
+ for (int y = 0; y < srcArgs.scaledHeight; y += FX_ONE) {
1451
+ for (int x = 0; x < srcArgs.scaledWidth; x += FX_ONE) {
1452
+ int color = getPixel(
1453
+ src,
1454
+ fxToInt(fxDiv(x, srcArgs.sx)),
1455
+ fxToInt(fxDiv(y, srcArgs.sy))
1456
+ );
1457
+
1458
+ if (!color) continue;
1459
+
1460
+ SHEAR(x, y, srcArgs.xShear, srcArgs.yShear);
1461
+
1462
+ int screenX = xDst + shearedX - srcArgs.minX;
1463
+ int screenY = yDst + shearedY - srcArgs.minY;
1464
+
1465
+ if (
1466
+ screenX < 0 ||
1467
+ screenY < 0 ||
1468
+ screenX >= dstArgs.maxX - dstArgs.minX ||
1469
+ screenY >= dstArgs.maxY - dstArgs.minY
1470
+ ) {
1471
+ continue;
1472
+ }
1473
+
1474
+ REVERSE_SHEAR(screenX + dstArgs.minX, screenY + dstArgs.minY, dstArgs.xShear, dstArgs.yShear);
1475
+
1476
+ if (dstArgs.flip) {
1477
+ if (
1478
+ getPixel(
1479
+ dst,
1480
+ fxToInt(fxDiv(dstArgs.scaledWidth - unshearedX - FX_ONE, dstArgs.sx)),
1481
+ fxToInt(fxDiv(dstArgs.scaledHeight - unshearedY - FX_ONE, dstArgs.sy))
1482
+ )
1483
+ ) {
1484
+ return true;
1485
+ }
1486
+ }
1487
+ else if (
1488
+ getPixel(
1489
+ dst,
1490
+ fxToInt(fxDiv(unshearedX, dstArgs.sx)),
1491
+ fxToInt(fxDiv(unshearedY, dstArgs.sy))
1492
+ )
1493
+ ) {
1494
+ return true;
1495
+ }
1496
+ }
1497
+ }
1498
+ }
1499
+ return false;
1500
+ }
1501
+
1128
1502
  //%
1129
1503
  bool _blit(Image_ img, Image_ src, pxt::RefCollection *args) {
1130
1504
  return blit(img, src, args);
@@ -165,6 +165,15 @@ namespace helpers {
165
165
  //% shim=ImageMethods::_blit
166
166
  declare function _blit(img: Image, src: Image, args: number[]): boolean;
167
167
 
168
+ //% shim=ImageMethods::_drawScaledRotatedImage
169
+ declare function _drawScaledRotatedImage(img: Image, src: Image, args: number[]): void;
170
+
171
+ //% shim=ImageMethods::_checkOverlapsScaledRotatedImage
172
+ declare function _checkOverlapsScaledRotatedImage(img: Image, src: Image, args: number[]): boolean;
173
+
174
+ //% shim=ImageMethods::_checkOverlapsTwoScaledRotatedImages
175
+ declare function _checkOverlapsTwoScaledRotatedImages(img: Image, src: Image, args: number[]): boolean;
176
+
168
177
  //% shim=ImageMethods::_fillTriangle
169
178
  declare function _fillTriangle(img: Image, args: number[]): void;
170
179
 
@@ -280,6 +289,39 @@ namespace helpers {
280
289
  _fillPolygon4(img, _blitArgs);
281
290
  }
282
291
 
292
+ export function imageDrawScaledRotated(dest: Image, destX: number, destY: number, src: Image, sx: number, sy: number, angle: number) {
293
+ _blitArgs = _blitArgs || [];
294
+ _blitArgs[0] = destX | 0;
295
+ _blitArgs[1] = destY | 0;
296
+ _blitArgs[2] = sx;
297
+ _blitArgs[3] = sy;
298
+ _blitArgs[4] = angle;
299
+ _drawScaledRotatedImage(dest, src, _blitArgs);
300
+ }
301
+
302
+ export function checkOverlapsScaledRotatedImage(dest: Image, destX: number, destY: number, src: Image, sx: number, sy: number, angle: number) {
303
+ _blitArgs = _blitArgs || [];
304
+ _blitArgs[0] = destX | 0;
305
+ _blitArgs[1] = destY | 0;
306
+ _blitArgs[2] = sx;
307
+ _blitArgs[3] = sy;
308
+ _blitArgs[4] = angle;
309
+ return _checkOverlapsScaledRotatedImage(dest, src, _blitArgs);
310
+ }
311
+
312
+ export function checkOverlapsTwoScaledRotatedImages(dest: Image, destX: number, destY: number, destSx: number, destSy: number, destAngle: number, src: Image, sx: number, sy: number, angle: number) {
313
+ _blitArgs = _blitArgs || [];
314
+ _blitArgs[0] = destX | 0;
315
+ _blitArgs[1] = destY | 0;
316
+ _blitArgs[2] = destSx;
317
+ _blitArgs[3] = destSy;
318
+ _blitArgs[4] = destAngle;
319
+ _blitArgs[5] = sx;
320
+ _blitArgs[6] = sy;
321
+ _blitArgs[7] = angle;
322
+ return _checkOverlapsTwoScaledRotatedImages(dest, src, _blitArgs);
323
+ }
324
+
283
325
  /**
284
326
  * Returns an image rotated by 90, 180, 270 deg clockwise
285
327
  */