Integrate screen APIs from common packages (#343)
* starting screen api intergration * Further image integration * Aligning with new screen apis * Build fixes * Adjust to common screen state * Fix unpackPNG * Add game library * Optimize screen rendering * bumping common packages * updated shims * moving images into ev3 * upgrading to common packages * added try/use * cap * fixed tryp age
This commit is contained in:
parent
5bd9705966
commit
c2d26a8418
@ -7,14 +7,14 @@
|
||||
{
|
||||
"name": "Try",
|
||||
"imageUrl": "/static/lessons/try.png",
|
||||
"description": "TBD",
|
||||
"description": "Get a quick introduction to programming with EV3.",
|
||||
"url": "/getting-started/try",
|
||||
"cardType": "side"
|
||||
},
|
||||
{
|
||||
"name": "use",
|
||||
"name": "Use",
|
||||
"imageUrl": "/static/lessons/use.png",
|
||||
"description": "TBD",
|
||||
"description": "Build a robot and drive into the world of robotics!",
|
||||
"url": "/getting-started/use",
|
||||
"cardType": "side"
|
||||
}
|
||||
|
178
docs/getting-started/try.md
Normal file
178
docs/getting-started/try.md
Normal file
@ -0,0 +1,178 @@
|
||||
# Try
|
||||
|
||||
[IMG: Neutral Image Display on EV3 Brick with Music Notes]
|
||||
|
||||
Get a quick introduction to programming with EV3.
|
||||
|
||||
We are excited to help you get started with LEGO MINDSTORMS Education EV3. In this project we will guide you through connecting your EV3 brick, creating your first program, controlling a Large Motor, a Touch Sensor and a Color Sensor. These steps can take up to 45 minutes.
|
||||
|
||||
## Turn on your EV3 Brick
|
||||
|
||||
[IMG: Hand pressing power button, Neutral Image Display, EV3 Brick]
|
||||
|
||||
Power on your EV3 Brick by pressing the Center Button.
|
||||
|
||||
## Connect Your EV3 Brick to Your Device
|
||||
|
||||
[IMG: Hand on cable & computer, Neutral Image Display, EV3 Brick]
|
||||
|
||||
Use the USB cable to connect your EV3 Brick to your device.
|
||||
|
||||
## Create and Run your First Program
|
||||
|
||||
[IMG: Try Program Blocks (see JavaScript below)]
|
||||
|
||||
1 - Create the program shown here:
|
||||
|
||||
```blocks
|
||||
brick.buttonEnter.onEvent(ButtonEvent.Pressed, function () {
|
||||
brick.showMood(moods.neutral)
|
||||
music.playSoundEffect(sounds.communicationHello)
|
||||
})
|
||||
```
|
||||
|
||||
* Drag a Brick Screen show mood block inside the on button block
|
||||
* Change mood to
|
||||
|
||||
```block
|
||||
brick.showMood(moods.neutral)
|
||||
```
|
||||
|
||||
* Drag a Music play sound effect block below the show mood block
|
||||
* Change sound effect to
|
||||
|
||||
```block
|
||||
music.playSoundEffect(sounds.communicationHello)
|
||||
```
|
||||
|
||||
2 – Click Download and follow the instructions to get your code onto your EV3 Brick. Press the center button on the EV3 Brick to run the program.
|
||||
|
||||
## ~ hint
|
||||
|
||||
Note: Click here for help and more information about the programming blocks.
|
||||
|
||||
## ~
|
||||
|
||||
## Did It Work?
|
||||
|
||||
[IMG: Neutral Image Display, EV3 Brick]
|
||||
|
||||
Verify that the program you just created shows eyes on the Brick Display, and that the EV3 Brick played the sound “Hello!”
|
||||
|
||||
**Well done!**
|
||||
|
||||
## Connect a Large Motor
|
||||
|
||||
[IMG: EV3 Brick with hands connecting Large Motor to Port D]
|
||||
|
||||
Now you will learn to control the Large Motor.
|
||||
|
||||
Connect a Large Motor to Port D of your EV3 Brick using any of the connector cables.
|
||||
|
||||
## Create and Run This Program
|
||||
|
||||
[IMG: Program Blocks (see JavaScript below)]
|
||||
|
||||
1) Create the program shown here:
|
||||
|
||||
```blocks
|
||||
brick.buttonEnter.onEvent(ButtonEvent.Pressed, function () {
|
||||
motors.largeD.run(50, 1, MoveUnit.Rotations)
|
||||
})
|
||||
```
|
||||
|
||||
* Start a new program
|
||||
* Drag a run large A motor block inside the on button block
|
||||
* Change large A to large D motors.largeD.run(50)
|
||||
* Click on the + sign
|
||||
* Change to 1 rotation
|
||||
|
||||
2) Click Download and follow the instructions to get your code onto your EV3 Brick. Press the center button on the EV3 Brick to run the program.
|
||||
|
||||
## Did It Rotate?
|
||||
|
||||
[IMG: Large Motor D w/Rotating “WHRRR,” Hand, EV3 Brick]
|
||||
|
||||
Confirm that your motor has turned one rotation at power level 50 before stopping.
|
||||
|
||||
Download and run the program as many times as you want in order to verify this, or tinker with different power levels and different rotations.
|
||||
|
||||
## Connect a Touch Sensor
|
||||
|
||||
[IMG: Hands connecting Touch Sensor to Port 1 on EV3 Brick]
|
||||
|
||||
We will now control the Large Motor using a Touch Sensor.
|
||||
|
||||
Keeping the Large Motor connected to **Port D**, connect a Touch Sensor to **Port 1** of your EV3 Brick.
|
||||
|
||||
## Modify Your Program
|
||||
|
||||
[IMG: Program Blocks (see JavaScript below)]
|
||||
|
||||
```blocks
|
||||
brick.buttonEnter.onEvent(ButtonEvent.Pressed, function () {
|
||||
sensors.touch1.pauseUntil(ButtonEvent.Pressed)
|
||||
motors.largeD.run(50, 1, MoveUnit.Rotations)
|
||||
})
|
||||
```
|
||||
|
||||
1) Add a pause until touch 1 pressed Sensor block on top of the run large D Motor block
|
||||
|
||||
```block
|
||||
sensors.touch1.pauseUntil(ButtonEvent.Pressed)
|
||||
```
|
||||
|
||||
2) Click Download and follow the instructions to get your code onto your EV3 Brick. Press the center button on the EV3 Brick to run the program.
|
||||
|
||||
## Press the Touch Sensor
|
||||
|
||||
[IMG: Hand Touch Sensor Pressed & EV3 Brick & Large Motor]
|
||||
|
||||
Confirm that the Large Motor has turned one rotation AFTER you press the Touch Sensor.
|
||||
|
||||
Download and run the program as many times as you want in order to verify this, or tinker with different Touch Sensor and Large Motor values.
|
||||
|
||||
## Connect a Color Sensor
|
||||
|
||||
[IMG: Hand connecting Color Sensor to Port 4, Large Motor D, EV3 Brick]
|
||||
|
||||
Now we will try to control the Large Motor using another sensor.
|
||||
|
||||
Keeping the Large Motor connected to **Port D**, connect the Color Sensor to **Port 4**.
|
||||
Modify Your Program
|
||||
|
||||
[IMG: Program Blocks (see JavaScript below)]
|
||||
|
||||
```blocks
|
||||
brick.buttonEnter.onEvent(ButtonEvent.Pressed, function () {
|
||||
sensors.color3.pauseForColor(ColorSensorColor.Green)
|
||||
motors.largeD.run(50, 1, MoveUnit.Rotations)
|
||||
})
|
||||
```
|
||||
|
||||
1) Using the same program, replace the pause until touch 1 block with a pause color 3 for color block
|
||||
|
||||
```block
|
||||
sensors.color3.pauseForColor(ColorSensorColor.Green)
|
||||
```
|
||||
|
||||
2) Select the color you want to detect (e.g., green).
|
||||
|
||||
3) Click Download and follow the instructions to get your code onto your EV3 Brick. Press the center button on the EV3 Brick to run the program.
|
||||
|
||||
## Place a Colored Brick in Front of the Color Sensor
|
||||
|
||||
[IMG: Colored bricks in front of Color Sensor, hands, EV3 Brick]
|
||||
|
||||
Confirm that the Large Motor has turned one rotation AFTER the Color Sensor has detected the colored brick.
|
||||
|
||||
Download and run the program as many times as you want in order to verify this, or tinker with different Color Sensor and Large Motor values.
|
||||
|
||||
Click on the JavaScript tab and change the color the Color Sensor detects to Black, Blue, Green, Yellow, Red, White, or Brown. Use Title Case for the color names.
|
||||
|
||||
## Well Done!
|
||||
|
||||
[IMG: EV3 Driving Base]
|
||||
|
||||
You have now learned how to control some of the inputs and outputs of the EV3.
|
||||
|
114
docs/getting-started/use.md
Normal file
114
docs/getting-started/use.md
Normal file
@ -0,0 +1,114 @@
|
||||
# Use
|
||||
|
||||
[IMG: EV3 Driving Base full w/cuboid]
|
||||
|
||||
Build a robot and drive into the world of robotics!
|
||||
In this project we will guide you through building a Driving Base Robot and programming it to move straight and turn. You will also build and Object Detector Module, and program it to detect an object. It’s a good idea to have done the [Try](/getting-started/try) sequence first.
|
||||
|
||||
## Connect
|
||||
|
||||
[IMG: Apple Picker]
|
||||
|
||||
What if your school had a multipurpose robot? How would you use it?
|
||||
|
||||
Would you use it to clean the school or plant trees?
|
||||
|
||||
## Build Your Driving Base Robot
|
||||
|
||||
[IMG: EV3 Driving Base Building Instructions Cover Image]
|
||||
|
||||
* [Building instructions](https://le-www-live-s.legocdn.com/sc/media/lessons/mindstorms-ev3/building-instructions/ev3-rem-driving-base-79bebfc16bd491186ea9c9069842155e.pdf)
|
||||
|
||||
## Make It Move
|
||||
|
||||
[IMG: Program Blocks (see JavaScript below)]
|
||||
|
||||
1) Create a program that makes the Driving Base move forward and stop at the finish line, which is 1 meter away.
|
||||
|
||||
Start by building this program:
|
||||
|
||||
```blocks
|
||||
brick.buttonEnter.onEvent(ButtonEvent.Pressed, function () {
|
||||
motors.largeBC.steer(0, 50, 1, MoveUnit.Rotations)
|
||||
})
|
||||
```
|
||||
|
||||
* Drag a steer large B+C motor block inside the on button block
|
||||
* Click on the + sign
|
||||
* Change to 1 rotation
|
||||
|
||||
### ~ hint
|
||||
|
||||
Hint: You will have to modify the number of rotations until you find the number that matches the robot moving forward 1 meter and stopping.
|
||||
|
||||
### ~
|
||||
|
||||
2) Click Download and follow the instructions to get your code onto your EV3 Brick. Press the center button on the EV3 Brick to run the program.
|
||||
|
||||
## Make It Turn
|
||||
|
||||
[IMG: Program Blocks (see JavaScript below)]
|
||||
|
||||
```blocks
|
||||
brick.buttonEnter.onEvent(ButtonEvent.Pressed, function () {
|
||||
motors.largeBC.steer(-50, 50, 1, MoveUnit.Rotations)
|
||||
})
|
||||
```
|
||||
|
||||
1) Create a new program that turns the Driving Base 180 degrees.
|
||||
|
||||
### ~ hint
|
||||
|
||||
Hint: You will have to modify the turn ratio and the number of rotations until the robot reaches 180 degrees.
|
||||
|
||||
### ~
|
||||
|
||||
|
||||
2) Click Download and follow the instructions to get your code onto your EV3 Brick. Press the center button on the EV3 Brick to run the program.
|
||||
|
||||
## Add an Ultrasonic Sensor to Your Driving Base
|
||||
|
||||
[IMG: EV3 Ultrasonic Sensor Driving Base Building Instructions Main Image]
|
||||
|
||||
* [building instructions](https://le-www-live-s.legocdn.com/sc/media/lessons/mindstorms-ev3/building-instructions/ev3-ultrasonic-sensor-driving-base-61ffdfa461aee2470b8ddbeab16e2070.pdf)
|
||||
|
||||
## Detect an Object
|
||||
|
||||
[IMG: Program Blocks (see JavaScript below)]
|
||||
|
||||
1 - Create a program that moves the Driving Base and makes it stop ``6`` cm from the Cuboid.
|
||||
|
||||
Create a new program
|
||||
```blocks
|
||||
brick.buttonEnter.onEvent(ButtonEvent.Pressed, function () {
|
||||
motors.largeBC.tank(50, 50)
|
||||
sensors.ultrasonic4.setThreshold(UltrasonicSensorEvent.ObjectDetected, 6)
|
||||
sensors.ultrasonic4.pauseUntil(UltrasonicSensorEvent.ObjectDetected);
|
||||
motors.stopAll()
|
||||
})
|
||||
```
|
||||
|
||||
* Drag a tank large B+C motor block inside the on button block
|
||||
* Drag a threshold Ultrasonic Sensor block and place below the motor block
|
||||
* Drag a stop all motors block and place it below the sensor block
|
||||
|
||||
### ~ hint
|
||||
|
||||
Hint: You will have to modify the values of the Ultrasonic Sensor block until the robot reaches the desired position.
|
||||
|
||||
### ~
|
||||
|
||||
2) Click Download and follow the instructions to get your code onto your EV3 Brick. Press the center button on the EV3 Brick to run the program.
|
||||
|
||||
Click on the JavaScript tab and change and test the number value of the Ultrasonic Sensor
|
||||
|
||||
```typescript
|
||||
sensors.ultrasonic4.setThreshold(UltrasonicSensorEvent.ObjectDetected, 10)
|
||||
```
|
||||
|
||||
[IMG: EV3 Ultrasonic Sensor Driving Base Building Instructions Main Image]
|
||||
|
||||
**Congratulations!**
|
||||
|
||||
You are ready to move on to the next steps.
|
||||
Try a LEGO MINDSTORMS Design Engineering, Coding, or Maker activity.
|
9
libs/base/shims.d.ts
vendored
9
libs/base/shims.d.ts
vendored
@ -64,6 +64,15 @@ declare interface Buffer {
|
||||
//% shim=BufferMethods::write
|
||||
write(dstOffset: int32, src: Buffer): void;
|
||||
}
|
||||
declare namespace control {
|
||||
|
||||
/**
|
||||
* Create a new zero-initialized buffer.
|
||||
* @param size number of bytes in the buffer
|
||||
*/
|
||||
//% shim=control::createBuffer
|
||||
function createBuffer(size: int32): Buffer;
|
||||
}
|
||||
declare namespace loops {
|
||||
|
||||
/**
|
||||
|
@ -53,11 +53,11 @@ namespace console {
|
||||
//% weight=1
|
||||
//% help=console/send-to-screen
|
||||
export function sendToScreen(): void {
|
||||
console.screen.attach();
|
||||
console._screen.attach();
|
||||
}
|
||||
}
|
||||
|
||||
namespace console.screen {
|
||||
namespace console._screen {
|
||||
const maxLines = 100;
|
||||
const screenLines = 10;
|
||||
let lines: string[];
|
||||
@ -78,7 +78,7 @@ namespace console.screen {
|
||||
for (let i = 0; i < screenLines; ++i) {
|
||||
const line = lines[i + scrollPosition];
|
||||
if (line)
|
||||
brick.print(line, 0, 4 + i * brick.LINE_HEIGHT)
|
||||
screen.print(line, 0, 4 + i * brick.LINE_HEIGHT)
|
||||
}
|
||||
}
|
||||
|
||||
|
15
libs/core/enums.d.ts
vendored
15
libs/core/enums.d.ts
vendored
@ -11,19 +11,4 @@
|
||||
End = 2,
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Drawing modes
|
||||
*/
|
||||
|
||||
declare const enum Draw {
|
||||
Normal = 0x00,
|
||||
Clear = 0x01,
|
||||
Xor = 0x02,
|
||||
Fill = 0x04,
|
||||
Transparent = 0x08,
|
||||
Double = 0x10,
|
||||
Quad = 0x20,
|
||||
}
|
||||
|
||||
// Auto-generated. Do not edit. Really.
|
||||
|
@ -19,20 +19,13 @@ struct PNGHeader {
|
||||
uint8_t IDAT[4];
|
||||
} __attribute__((packed));
|
||||
|
||||
namespace screen {
|
||||
namespace image {
|
||||
|
||||
static uint32_t swap(uint32_t num) {
|
||||
return ((num >> 24) & 0xff) | ((num << 8) & 0xff0000) | ((num >> 8) & 0xff00) |
|
||||
((num << 24) & 0xff000000);
|
||||
}
|
||||
|
||||
static uint8_t revbits(uint8_t v) {
|
||||
v = (v & 0xf0) >> 4 | (v & 0x0f) << 4;
|
||||
v = (v & 0xcc) >> 2 | (v & 0x33) << 2;
|
||||
v = (v & 0xaa) >> 1 | (v & 0x55) << 1;
|
||||
return v;
|
||||
}
|
||||
|
||||
/** Decompresses a 1-bit gray scale PNG image to image format. */
|
||||
//%
|
||||
Image unpackPNG(Buffer png) {
|
||||
@ -101,12 +94,11 @@ Image unpackPNG(Buffer png) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Buffer res = mkBuffer(NULL, 2 + byteW * hd.height);
|
||||
res->data[0] = 0xf0;
|
||||
res->data[1] = hd.width;
|
||||
uint8_t *dst = res->data + 2;
|
||||
auto res = mkImage(hd.width, hd.height, 1);
|
||||
|
||||
uint8_t *dst = res->pix();
|
||||
uint8_t *src = tmp;
|
||||
uint8_t lastMask = (1 << (hd.width & 7)) - 1;
|
||||
uint8_t lastMask = 0xff << (8 - (hd.width & 7));
|
||||
if (lastMask == 0)
|
||||
lastMask = 0xff;
|
||||
for (uint32_t i = 0; i < hd.height; ++i) {
|
||||
@ -117,7 +109,7 @@ Image unpackPNG(Buffer png) {
|
||||
return NULL;
|
||||
}
|
||||
for (uint32_t j = 0; j < byteW; ++j) {
|
||||
*dst = ~revbits(*src++);
|
||||
*dst = ~*src++;
|
||||
if (j == byteW - 1) {
|
||||
*dst &= lastMask;
|
||||
}
|
||||
|
@ -32,7 +32,6 @@ class MMap : public RefObject {
|
||||
extern volatile bool paniced;
|
||||
|
||||
// Buffer, Sound, and Image share representation.
|
||||
typedef Buffer Image;
|
||||
typedef Buffer Sound;
|
||||
|
||||
}
|
||||
@ -41,4 +40,6 @@ typedef Buffer Sound;
|
||||
#define DEVICE_ID_NOTIFY 10000
|
||||
#define DEVICE_ID_NOTIFY_ONE 10001
|
||||
|
||||
#define IMAGE_BITS 1
|
||||
|
||||
#endif
|
||||
|
@ -16,7 +16,6 @@
|
||||
"buttons.ts",
|
||||
"png.cpp",
|
||||
"screen.cpp",
|
||||
"screen.ts",
|
||||
"battery.ts",
|
||||
"output.cpp",
|
||||
"output.ts",
|
||||
@ -26,8 +25,6 @@
|
||||
"shims.d.ts",
|
||||
"enums.d.ts",
|
||||
"dal.d.ts",
|
||||
"images.ts",
|
||||
"images.jres",
|
||||
"icons.jres",
|
||||
"ns.ts"
|
||||
],
|
||||
|
@ -9,39 +9,12 @@
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
/**
|
||||
* Drawing modes
|
||||
*/
|
||||
enum class Draw {
|
||||
Normal = 0x00, // set pixels to black, no fill
|
||||
Clear = 0x01,
|
||||
Xor = 0x02,
|
||||
Fill = 0x04,
|
||||
Transparent = 0x08,
|
||||
Double = 0x10,
|
||||
Quad = 0x20,
|
||||
};
|
||||
namespace pxt {
|
||||
|
||||
inline bool operator&(Draw a, Draw b) {
|
||||
return ((int)a & (int)b) != 0;
|
||||
}
|
||||
|
||||
inline Draw operator|(Draw a, Draw b) {
|
||||
return (Draw)((int)a | (int)b);
|
||||
}
|
||||
|
||||
#define XX(v) ((uint32_t)(v)&0xffff)
|
||||
#define YY(v) ((uint32_t)(v) >> 16)
|
||||
|
||||
// We only support up to 4 arguments for C++ functions - need to pack them on the TS side
|
||||
namespace screen {
|
||||
|
||||
#define ROW_SIZE 32
|
||||
#define ROW_SIZE 23
|
||||
#define FB_SIZE (60 * LCD_HEIGHT)
|
||||
|
||||
static const uint8_t pixmap[] = {0x00, 0xE0, 0x1C, 0xFC, 0x03, 0xE3, 0x1F, 0xFF};
|
||||
static uint8_t bitBuffer[ROW_SIZE * LCD_HEIGHT];
|
||||
static bool dirty;
|
||||
static const uint8_t pixmap[] = {0x00, 0x03, 0x1C, 0x1F, 0xE0, 0xE3, 0xFC, 0xFF};
|
||||
|
||||
static void bitBufferToFrameBuffer(uint8_t *bitBuffer, uint8_t *fb) {
|
||||
uint32_t pixels;
|
||||
@ -49,129 +22,48 @@ static void bitBufferToFrameBuffer(uint8_t *bitBuffer, uint8_t *fb) {
|
||||
for (int line = 0; line < LCD_HEIGHT; line++) {
|
||||
int n = 7;
|
||||
while (n--) {
|
||||
pixels = *bitBuffer++ << 0;
|
||||
pixels = *bitBuffer++ << 16;
|
||||
pixels |= *bitBuffer++ << 8;
|
||||
pixels |= *bitBuffer++ << 16;
|
||||
pixels |= *bitBuffer++ << 0;
|
||||
|
||||
int m = 8;
|
||||
while (m--) {
|
||||
*fb++ = pixmap[pixels & 0x07];
|
||||
pixels >>= 3;
|
||||
*fb++ = pixmap[(pixels >> 21) & 0x07];
|
||||
pixels <<= 3;
|
||||
}
|
||||
}
|
||||
|
||||
pixels = *bitBuffer++ << 0;
|
||||
pixels |= *bitBuffer++ << 8;
|
||||
|
||||
bitBuffer += ROW_SIZE - 23;
|
||||
pixels = *bitBuffer++ << 8;
|
||||
pixels |= *bitBuffer++ << 0;
|
||||
|
||||
int m = 4;
|
||||
while (m--) {
|
||||
*fb++ = pixmap[pixels & 0x07];
|
||||
pixels >>= 3;
|
||||
*fb++ = pixmap[(pixels >> 13) & 0x07];
|
||||
pixels <<= 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#define OFF(x, y) (((y) << 5) + ((x) >> 3))
|
||||
#define MASK(x, y) (1 << ((x)&7))
|
||||
#define PIX2BYTES(x) (((x) + 7) >> 3)
|
||||
|
||||
static inline void applyMask(int off, int mask, Draw mode) {
|
||||
if (mode & Draw::Clear)
|
||||
bitBuffer[off] &= ~mask;
|
||||
else if (mode & Draw::Xor)
|
||||
bitBuffer[off] ^= mask;
|
||||
else
|
||||
bitBuffer[off] |= mask;
|
||||
}
|
||||
|
||||
//%
|
||||
void _setPixel(int x, int y, Draw mode) {
|
||||
applyMask(OFF(x, y), MASK(x, y), mode);
|
||||
}
|
||||
|
||||
void blitLineCore(int x, int y, int w, uint8_t *data, Draw mode) {
|
||||
if (y < 0 || y >= LCD_HEIGHT)
|
||||
return;
|
||||
if (x + w <= 0)
|
||||
return;
|
||||
if (x >= LCD_WIDTH)
|
||||
return;
|
||||
|
||||
int shift = x & 7;
|
||||
int off = OFF(x, y);
|
||||
int off0 = OFF(0, y);
|
||||
int off1 = OFF(LCD_WIDTH - 1, y);
|
||||
int x1 = x + w + shift;
|
||||
int prev = 0;
|
||||
|
||||
while (x < x1 - 8) {
|
||||
int curr = *data++ << shift;
|
||||
if (off0 <= off && off <= off1)
|
||||
applyMask(off, curr | prev, mode);
|
||||
off++;
|
||||
prev = curr >> 8;
|
||||
x += 8;
|
||||
}
|
||||
|
||||
int left = x1 - x;
|
||||
if (left > 0) {
|
||||
int curr = *data << shift;
|
||||
if (off0 <= off && off <= off1)
|
||||
applyMask(off, (curr | prev) & ((1 << left) - 1), mode);
|
||||
}
|
||||
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
//%
|
||||
void _blitLine(int xw, int y, Buffer buf, Draw mode) {
|
||||
blitLineCore(XX(xw), y, YY(xw), buf->data, mode);
|
||||
}
|
||||
|
||||
/** Clear screen and reset font to normal. */
|
||||
//%
|
||||
void clear() {
|
||||
memset(bitBuffer, 0, sizeof(bitBuffer));
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
//%
|
||||
void dump() {
|
||||
char buf[LCD_WIDTH + 1];
|
||||
FILE *f = fopen("/tmp/screen.txt", "w");
|
||||
for (int i = 0; i < LCD_HEIGHT; ++i) {
|
||||
for (int j = 0; j < LCD_WIDTH; ++j) {
|
||||
if (bitBuffer[OFF(j, i)] & MASK(j, i))
|
||||
buf[j] = '#';
|
||||
else
|
||||
buf[j] = '.';
|
||||
}
|
||||
buf[LCD_WIDTH] = 0;
|
||||
fprintf(f, "%s\n", buf);
|
||||
}
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
static uint8_t *mappedFrameBuffer;
|
||||
static Image lastImg;
|
||||
|
||||
//%
|
||||
void updateLCD() {
|
||||
if (dirty && mappedFrameBuffer != MAP_FAILED) {
|
||||
dirty = false;
|
||||
bitBufferToFrameBuffer(bitBuffer, mappedFrameBuffer);
|
||||
void updateScreen(Image img) {
|
||||
if (img && img != lastImg) {
|
||||
decrRC(lastImg);
|
||||
incrRC(img);
|
||||
lastImg = img;
|
||||
}
|
||||
|
||||
if (lastImg && lastImg->isDirty() && mappedFrameBuffer != MAP_FAILED) {
|
||||
if (lastImg->bpp() != 1 || lastImg->width() != LCD_WIDTH || lastImg->height() != LCD_HEIGHT)
|
||||
target_panic(906);
|
||||
lastImg->clearDirty();
|
||||
bitBufferToFrameBuffer(lastImg->pix(), mappedFrameBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
void *screenRefresh(void *dummy) {
|
||||
while (true) {
|
||||
sleep_core_us(30000);
|
||||
updateLCD();
|
||||
}
|
||||
}
|
||||
|
||||
void init() {
|
||||
void screen_init() {
|
||||
DMESG("init screen");
|
||||
if (mappedFrameBuffer)
|
||||
return;
|
||||
@ -182,25 +74,19 @@ void init() {
|
||||
if (mappedFrameBuffer == MAP_FAILED) {
|
||||
target_panic(903);
|
||||
}
|
||||
clear();
|
||||
|
||||
pthread_t pid;
|
||||
pthread_create(&pid, NULL, screenRefresh, NULL);
|
||||
pthread_detach(pid);
|
||||
}
|
||||
|
||||
static const uint8_t numbers[] = {
|
||||
0x06, 0x09, 0x09, 0x09, 0x06, 0x04, 0x06, 0x04, 0x04, 0x0e, 0x07, 0x08, 0x06, 0x01, 0x0f, 0x0f,
|
||||
0x08, 0x04, 0x09, 0x06, 0x0c, 0x0a, 0x09, 0x1f, 0x08, 0x1f, 0x01, 0x0f, 0x10, 0x0f, 0x08, 0x04,
|
||||
0x0e, 0x11, 0x0e, 0x1f, 0x08, 0x04, 0x02, 0x01, 0x0e, 0x11, 0x0e, 0x11, 0x0e, 0x0e, 0x11, 0x0e,
|
||||
0x04, 0x02,
|
||||
// face
|
||||
0b11011, 0b11011, 0b00000, 0b11111, 0b11011,
|
||||
0x06, 0x09, 0x09, 0x09, 0x06, 0x04, 0x06, 0x04, 0x04, 0x0e, 0x07, 0x08, 0x06,
|
||||
0x01, 0x0f, 0x0f, 0x08, 0x04, 0x09, 0x06, 0x0c, 0x0a, 0x09, 0x1f, 0x08, 0x1f,
|
||||
0x01, 0x0f, 0x10, 0x0f, 0x08, 0x04, 0x0e, 0x11, 0x0e, 0x1f, 0x08, 0x04, 0x02,
|
||||
0x01, 0x0e, 0x11, 0x0e, 0x11, 0x0e, 0x0e, 0x11, 0x0e, 0x04, 0x02,
|
||||
|
||||
0x1b, 0x1b, 0x00, 0x1f, 0x1b,
|
||||
};
|
||||
|
||||
static void drawNumber(int off, int idx) {
|
||||
static void drawNumber(uint8_t *dst, int idx) {
|
||||
const uint8_t *src = &numbers[idx * 5];
|
||||
uint8_t *dst = &bitBuffer[off];
|
||||
for (int i = 0; i < 5; i++) {
|
||||
uint8_t ch = *src++;
|
||||
for (int jj = 0; jj < 8; ++jj) {
|
||||
@ -215,13 +101,19 @@ static void drawNumber(int off, int idx) {
|
||||
}
|
||||
|
||||
extern "C" void drawPanic(int code) {
|
||||
clear();
|
||||
int fd = open("/dev/lms_ui", O_RDWR);
|
||||
uint8_t cmd[] = {48 + 5, 0};
|
||||
write(fd, cmd, 2);
|
||||
close(fd);
|
||||
|
||||
int ptr = ROW_SIZE * 16 + 3 + 6;
|
||||
uint8_t bitBuffer[ROW_SIZE * LCD_HEIGHT];
|
||||
|
||||
memset(bitBuffer, 0, sizeof(bitBuffer));
|
||||
|
||||
auto ptr = &bitBuffer[ROW_SIZE * 16 + 3 + 6];
|
||||
drawNumber(ptr, 10);
|
||||
ptr += 6;
|
||||
|
||||
ptr = ROW_SIZE * 70 + 3;
|
||||
ptr = &bitBuffer[ROW_SIZE * 70 + 3];
|
||||
|
||||
drawNumber(ptr, (code / 100) % 10);
|
||||
ptr += 6;
|
||||
@ -230,132 +122,9 @@ extern "C" void drawPanic(int code) {
|
||||
drawNumber(ptr, (code / 1) % 10);
|
||||
ptr += 6;
|
||||
|
||||
updateLCD();
|
||||
|
||||
int fd = open("/dev/lms_ui", O_RDWR);
|
||||
uint8_t cmd[] = {48 + 5, 0};
|
||||
write(fd, cmd, 2);
|
||||
close(fd);
|
||||
}
|
||||
|
||||
bool isValidImage(Buffer buf) {
|
||||
return buf != NULL && buf->length >= 3 && buf->data[0] == 0xf0;
|
||||
}
|
||||
|
||||
/** Makes an image bound to a buffer. */
|
||||
//%
|
||||
Image imageOf(Buffer buf) {
|
||||
if (!isValidImage(buf))
|
||||
return NULL;
|
||||
incrRC(buf);
|
||||
return buf;
|
||||
}
|
||||
}
|
||||
|
||||
namespace pxt {
|
||||
void screen_init() {
|
||||
screen::init();
|
||||
}
|
||||
}
|
||||
|
||||
//% fixedInstances
|
||||
namespace ImageMethods {
|
||||
|
||||
using namespace screen;
|
||||
|
||||
static const uint8_t bitdouble[] = {
|
||||
0x00, 0x03, 0x0c, 0x0f, 0x30, 0x33, 0x3c, 0x3f, 0xc0, 0xc3, 0xcc, 0xcf, 0xf0, 0xf3, 0xfc, 0xff,
|
||||
};
|
||||
|
||||
static uint8_t ones[] = {
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
};
|
||||
|
||||
/** Returns the underlaying Buffer object. */
|
||||
//% property
|
||||
Buffer buffer(Image ic) {
|
||||
incrRC(ic);
|
||||
return ic;
|
||||
}
|
||||
|
||||
/** Returns the width of an image. */
|
||||
//% property
|
||||
int width(Image ic) {
|
||||
if (!isValidImage(ic))
|
||||
return 0;
|
||||
return ic->data[1];
|
||||
}
|
||||
|
||||
/** Returns the height of an image. */
|
||||
//% property
|
||||
int height(Image ic) {
|
||||
if (!isValidImage(ic))
|
||||
return 0;
|
||||
int bw = PIX2BYTES(ic->data[1]);
|
||||
return (ic->length - 2) / bw;
|
||||
}
|
||||
|
||||
/** Double size of an image. */
|
||||
//%
|
||||
Image doubled(Image buf) {
|
||||
if (!isValidImage(buf))
|
||||
return NULL;
|
||||
int w = buf->data[1];
|
||||
if (w > 126)
|
||||
return NULL;
|
||||
int bw = PIX2BYTES(w);
|
||||
int h = (buf->length - 2) / bw;
|
||||
int bw2 = PIX2BYTES(w * 2);
|
||||
Buffer out = mkBuffer(NULL, 2 + bw2 * h * 2);
|
||||
out->data[0] = 0xf0;
|
||||
out->data[1] = w * 2;
|
||||
uint8_t *src = buf->data + 2;
|
||||
uint8_t *dst = out->data + 2;
|
||||
for (int i = 0; i < h; ++i) {
|
||||
for (int jj = 0; jj < 2; ++jj) {
|
||||
auto p = src;
|
||||
for (int j = 0; j < bw; ++j) {
|
||||
*dst++ = bitdouble[*p & 0xf];
|
||||
*dst++ = bitdouble[*p >> 4];
|
||||
p++;
|
||||
if (mappedFrameBuffer != MAP_FAILED) {
|
||||
bitBufferToFrameBuffer(bitBuffer, mappedFrameBuffer);
|
||||
}
|
||||
}
|
||||
src += bw;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
/** Draw an image on the screen. */
|
||||
//%
|
||||
void draw(Image buf, int x, int y, Draw mode) {
|
||||
if (!isValidImage(buf))
|
||||
return;
|
||||
if (mode & (Draw::Double | Draw::Quad)) {
|
||||
buf = doubled(buf);
|
||||
if (mode & Draw::Quad) {
|
||||
auto pbuf = buf;
|
||||
buf = doubled(buf);
|
||||
decrRC(pbuf);
|
||||
}
|
||||
}
|
||||
|
||||
int pixwidth = buf->data[1];
|
||||
int ptr = 2;
|
||||
int bytewidth = PIX2BYTES(pixwidth);
|
||||
pixwidth = min(pixwidth, LCD_WIDTH);
|
||||
while (ptr + bytewidth <= buf->length) {
|
||||
if (mode & (Draw::Clear | Draw::Xor | Draw::Transparent)) {
|
||||
// no erase of background
|
||||
} else {
|
||||
blitLineCore(x, y, pixwidth, ones, Draw::Clear);
|
||||
}
|
||||
blitLineCore(x, y, pixwidth, &buf->data[ptr], mode);
|
||||
y++;
|
||||
ptr += bytewidth;
|
||||
}
|
||||
|
||||
if (mode & (Draw::Double | Draw::Quad))
|
||||
decrRC(buf);
|
||||
}
|
||||
}
|
||||
} // namespace pxt
|
||||
|
@ -1,214 +0,0 @@
|
||||
namespace brick {
|
||||
export const LINE_HEIGHT = 12;
|
||||
|
||||
//% shim=screen::_setPixel
|
||||
function _setPixel(p0: uint32, p1: uint32, mode: Draw): void { }
|
||||
|
||||
//% shim=screen::_blitLine
|
||||
function _blitLine(xw: uint32, y: uint32, buf: Buffer, mode: Draw): void { }
|
||||
|
||||
function pack(x: number, y: number) {
|
||||
return Math.clamp(0, 512, x) | (Math.clamp(0, 512, y) << 16)
|
||||
}
|
||||
|
||||
const ones = hex`ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff`
|
||||
|
||||
function setLineCore(x: number, x1: number, y: number, mode: Draw) {
|
||||
_blitLine(pack(x, x1 - x), y, ones, mode)
|
||||
}
|
||||
|
||||
export interface Font {
|
||||
charWidth: number;
|
||||
charHeight: number;
|
||||
firstChar: number;
|
||||
data: Buffer;
|
||||
}
|
||||
let currFont: Font
|
||||
|
||||
export function setFont(f: Font) {
|
||||
currFont = f
|
||||
}
|
||||
|
||||
export const heart = screen.imageOf(hex`f007 367f7f3e1c08`)
|
||||
|
||||
export function defaultFont(): Font {
|
||||
return {
|
||||
charWidth: 8,
|
||||
charHeight: 8,
|
||||
firstChar: 32,
|
||||
// source https://github.com/dhepper/font8x8
|
||||
data: hex`
|
||||
0000000000000000 183C3C1818001800 3636000000000000 36367F367F363600 0C3E031E301F0C00 006333180C666300
|
||||
1C361C6E3B336E00 0606030000000000 180C0606060C1800 060C1818180C0600 00663CFF3C660000 000C0C3F0C0C0000
|
||||
00000000000C0C06 0000003F00000000 00000000000C0C00 6030180C06030100 3E63737B6F673E00 0C0E0C0C0C0C3F00
|
||||
1E33301C06333F00 1E33301C30331E00 383C36337F307800 3F031F3030331E00 1C06031F33331E00 3F3330180C0C0C00
|
||||
1E33331E33331E00 1E33333E30180E00 000C0C00000C0C00 000C0C00000C0C06 180C0603060C1800 00003F00003F0000
|
||||
060C1830180C0600 1E3330180C000C00 3E637B7B7B031E00 0C1E33333F333300 3F66663E66663F00 3C66030303663C00
|
||||
1F36666666361F00 7F46161E16467F00 7F46161E16060F00 3C66030373667C00 3333333F33333300 1E0C0C0C0C0C1E00
|
||||
7830303033331E00 6766361E36666700 0F06060646667F00 63777F7F6B636300 63676F7B73636300 1C36636363361C00
|
||||
3F66663E06060F00 1E3333333B1E3800 3F66663E36666700 1E33070E38331E00 3F2D0C0C0C0C1E00 3333333333333F00
|
||||
33333333331E0C00 6363636B7F776300 6363361C1C366300 3333331E0C0C1E00 7F6331184C667F00 1E06060606061E00
|
||||
03060C1830604000 1E18181818181E00 081C366300000000 00000000000000FF 0C0C180000000000 00001E303E336E00
|
||||
0706063E66663B00 00001E3303331E00 3830303e33336E00 00001E333f031E00 1C36060f06060F00 00006E33333E301F
|
||||
0706366E66666700 0C000E0C0C0C1E00 300030303033331E 070666361E366700 0E0C0C0C0C0C1E00 0000337F7F6B6300
|
||||
00001F3333333300 00001E3333331E00 00003B66663E060F 00006E33333E3078 00003B6E66060F00 00003E031E301F00
|
||||
080C3E0C0C2C1800 0000333333336E00 00003333331E0C00 0000636B7F7F3600 000063361C366300 00003333333E301F
|
||||
00003F190C263F00 380C0C070C0C3800 1818180018181800 070C0C380C0C0700 6E3B000000000000 0000000000000000
|
||||
`
|
||||
}
|
||||
}
|
||||
|
||||
function setPixel(on: boolean, x: number, y: number) {
|
||||
x |= 0
|
||||
y |= 0
|
||||
if (0 <= x && x < DAL.LCD_WIDTH && 0 <= y && y < DAL.LCD_HEIGHT)
|
||||
_setPixel(x, y, on ? Draw.Normal : Draw.Clear)
|
||||
}
|
||||
|
||||
/**
|
||||
* Show text on the screen at a specific line.
|
||||
* @param text the text to print on the screen, eg: "Hello world"
|
||||
* @param line the line number to print the text at, eg: 1
|
||||
*/
|
||||
//% blockId=screen_print block="show string %text|at line %line"
|
||||
//% weight=98 group="Screen" inlineInputMode="inline" blockGap=8
|
||||
//% help=brick/show-string
|
||||
//% line.min=1 line.max=10
|
||||
export function showString(text: string, line: number) {
|
||||
const NUM_LINES = 9;
|
||||
const offset = 5;
|
||||
const y = offset + (Math.clamp(0, NUM_LINES, line - 1) / (NUM_LINES + 2)) * DAL.LCD_HEIGHT;
|
||||
brick.print(text, offset, y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows a number on the screen
|
||||
* @param value the numeric value
|
||||
* @param line the line number to print the text at, eg: 1
|
||||
*/
|
||||
//% blockId=screenShowNumber block="show number %name|at line %line"
|
||||
//% weight=96 group="Screen" inlineInputMode="inline" blockGap=8
|
||||
//% help=brick/show-number
|
||||
//% line.min=1 line.max=10
|
||||
export function showNumber(value: number, line: number) {
|
||||
showString("" + value, line);
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows a name, value pair on the screen
|
||||
* @param value the numeric value
|
||||
* @param line the line number to print the text at, eg: 1
|
||||
*/
|
||||
//% blockId=screenShowValue block="show value %name|= %text|at line %line"
|
||||
//% weight=96 group="Screen" inlineInputMode="inline" blockGap=8
|
||||
//% help=brick/show-value
|
||||
//% line.min=1 line.max=10
|
||||
export function showValue(name: string, value: number, line: number) {
|
||||
value = Math.round(value * 1000) / 1000;
|
||||
showString((name ? name + ": " : "") + value, line);
|
||||
}
|
||||
|
||||
export function print(text: string, x: number, y: number, mode = Draw.Normal) {
|
||||
x |= 0
|
||||
y |= 0
|
||||
if (!currFont) currFont = defaultFont()
|
||||
let x0 = x
|
||||
let cp = 0
|
||||
let byteWidth = (currFont.charWidth + 7) >> 3
|
||||
let charSize = byteWidth * currFont.charHeight
|
||||
let imgBuf = output.createBuffer(2 + charSize)
|
||||
let double = (mode & Draw.Quad) ? 4 : (mode & Draw.Double) ? 2 : 1
|
||||
imgBuf[0] = 0xf0
|
||||
imgBuf[1] = currFont.charWidth
|
||||
let img = screen.imageOf(imgBuf)
|
||||
while (cp < text.length) {
|
||||
let ch = text.charCodeAt(cp++)
|
||||
if (ch == 10) {
|
||||
y += double * currFont.charHeight + 2
|
||||
x = x0
|
||||
}
|
||||
if (ch < 32) continue
|
||||
let idx = (ch - currFont.firstChar) * charSize
|
||||
if (idx < 0 || idx + imgBuf.length - 1 > currFont.data.length)
|
||||
imgBuf.fill(0, 2)
|
||||
else
|
||||
imgBuf.write(2, currFont.data.slice(idx, charSize))
|
||||
img.draw(x, y, mode)
|
||||
x += double * currFont.charWidth
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Show an image on the screen
|
||||
* @param image image to draw
|
||||
*/
|
||||
//% blockId=screen_show_image block="show image %image=screen_image_picker"
|
||||
//% weight=100 group="Screen" blockGap=8
|
||||
//% help=brick/show-image
|
||||
export function showImage(image: Image) {
|
||||
if (!image) return;
|
||||
image.draw(0, 0, Draw.Normal);
|
||||
}
|
||||
|
||||
/**
|
||||
* An image
|
||||
* @param image the image
|
||||
*/
|
||||
//% blockId=screen_image_picker block="%image" shim=TD_ID
|
||||
//% image.fieldEditor="images"
|
||||
//% image.fieldOptions.columns=6
|
||||
//% image.fieldOptions.width=600
|
||||
//% group="Screen" weight=0 blockHidden=1
|
||||
export function __imagePicker(image: Image): Image {
|
||||
return image;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the screen
|
||||
*/
|
||||
//% blockId=screen_clear_screen block="clear screen"
|
||||
//% weight=90 group="Screen"
|
||||
//% help=brick/clear-screen
|
||||
export function clearScreen() {
|
||||
screen.clear();
|
||||
}
|
||||
|
||||
function drawRect(x: number, y: number, w: number, h: number, mode = Draw.Normal) {
|
||||
x |= 0;
|
||||
y |= 0;
|
||||
w |= 0;
|
||||
h |= 0;
|
||||
if (x < 0) {
|
||||
w += x;
|
||||
x = 0;
|
||||
}
|
||||
if (y < 0) {
|
||||
h += y;
|
||||
y = 0;
|
||||
}
|
||||
if (w <= 0)
|
||||
return;
|
||||
if (h <= 0)
|
||||
return;
|
||||
let x1 = Math.min(DAL.LCD_WIDTH, x + w);
|
||||
let y1 = Math.min(DAL.LCD_HEIGHT, y + h);
|
||||
if (w == 1) {
|
||||
while (y < y1)
|
||||
_setPixel(x, y++, mode);
|
||||
return;
|
||||
}
|
||||
|
||||
setLineCore(x, x1, y++, mode);
|
||||
while (y < y1 - 1) {
|
||||
if (mode & Draw.Fill) {
|
||||
setLineCore(x, x1, y, mode);
|
||||
} else {
|
||||
_setPixel(x, y, mode);
|
||||
_setPixel(x1 - 1, y, mode);
|
||||
}
|
||||
y++;
|
||||
}
|
||||
if (y < y1)
|
||||
setLineCore(x, x1, y, mode);
|
||||
}
|
||||
}
|
39
libs/core/shims.d.ts
vendored
39
libs/core/shims.d.ts
vendored
@ -75,47 +75,12 @@ declare namespace serial {
|
||||
//% shim=serial::writeDmesg
|
||||
function writeDmesg(): void;
|
||||
}
|
||||
declare namespace screen {
|
||||
declare namespace image {
|
||||
|
||||
/** Decompresses a 1-bit gray scale PNG image to image format. */
|
||||
//% shim=screen::unpackPNG
|
||||
//% shim=image::unpackPNG
|
||||
function unpackPNG(png: Buffer): Image;
|
||||
}
|
||||
declare namespace screen {
|
||||
|
||||
/** Clear screen and reset font to normal. */
|
||||
//% shim=screen::clear
|
||||
function clear(): void;
|
||||
|
||||
/** Makes an image bound to a buffer. */
|
||||
//% shim=screen::imageOf
|
||||
function imageOf(buf: Buffer): Image;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//% fixedInstances
|
||||
declare interface Image {
|
||||
/** Returns the underlaying Buffer object. */
|
||||
//% property shim=ImageMethods::buffer
|
||||
buffer: Buffer;
|
||||
|
||||
/** Returns the width of an image. */
|
||||
//% property shim=ImageMethods::width
|
||||
width: int32;
|
||||
|
||||
/** Returns the height of an image. */
|
||||
//% property shim=ImageMethods::height
|
||||
height: int32;
|
||||
|
||||
/** Double size of an image. */
|
||||
//% shim=ImageMethods::doubled
|
||||
doubled(): Image;
|
||||
|
||||
/** Draw an image on the screen. */
|
||||
//% shim=ImageMethods::draw
|
||||
draw(x: int32, y: int32, mode: Draw): void;
|
||||
}
|
||||
declare namespace output {
|
||||
|
||||
/**
|
||||
|
@ -1,229 +1,229 @@
|
||||
namespace images {
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const expressionsBigSmile = screen.unpackPNG(hex``);
|
||||
export const expressionsBigSmile = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const expressionsHeartLarge = screen.unpackPNG(hex``);
|
||||
export const expressionsHeartLarge = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const expressionsHeartSmall = screen.unpackPNG(hex``);
|
||||
export const expressionsHeartSmall = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const expressionsMouth1open = screen.unpackPNG(hex``);
|
||||
export const expressionsMouth1open = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const expressionsMouth1shut = screen.unpackPNG(hex``);
|
||||
export const expressionsMouth1shut = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const expressionsMouth2open = screen.unpackPNG(hex``);
|
||||
export const expressionsMouth2open = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const expressionsMouth2shut = screen.unpackPNG(hex``);
|
||||
export const expressionsMouth2shut = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const expressionsSad = screen.unpackPNG(hex``);
|
||||
export const expressionsSad = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const expressionsSick = screen.unpackPNG(hex``);
|
||||
export const expressionsSick = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const expressionsSmile = screen.unpackPNG(hex``);
|
||||
export const expressionsSmile = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const expressionsSwearing = screen.unpackPNG(hex``);
|
||||
export const expressionsSwearing = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const expressionsTalking = screen.unpackPNG(hex``);
|
||||
export const expressionsTalking = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const expressionsWink = screen.unpackPNG(hex``);
|
||||
export const expressionsWink = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const expressionsZzz = screen.unpackPNG(hex``);
|
||||
export const expressionsZzz = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const eyesAngry = screen.unpackPNG(hex``);
|
||||
export const eyesAngry = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const eyesAwake = screen.unpackPNG(hex``);
|
||||
export const eyesAwake = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const eyesBlackEye = screen.unpackPNG(hex``);
|
||||
export const eyesBlackEye = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const eyesBottomLeft = screen.unpackPNG(hex``);
|
||||
export const eyesBottomLeft = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const eyesBottomRight = screen.unpackPNG(hex``);
|
||||
export const eyesBottomRight = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const eyesCrazy1 = screen.unpackPNG(hex``);
|
||||
export const eyesCrazy1 = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const eyesCrazy2 = screen.unpackPNG(hex``);
|
||||
export const eyesCrazy2 = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const eyesDisappointed = screen.unpackPNG(hex``);
|
||||
export const eyesDisappointed = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const eyesDizzy = screen.unpackPNG(hex``);
|
||||
export const eyesDizzy = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const eyesDown = screen.unpackPNG(hex``);
|
||||
export const eyesDown = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const eyesEvil = screen.unpackPNG(hex``);
|
||||
export const eyesEvil = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const eyesHurt = screen.unpackPNG(hex``);
|
||||
export const eyesHurt = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const eyesKnockedOut = screen.unpackPNG(hex``);
|
||||
export const eyesKnockedOut = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const eyesLove = screen.unpackPNG(hex``);
|
||||
export const eyesLove = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const eyesMiddleLeft = screen.unpackPNG(hex``);
|
||||
export const eyesMiddleLeft = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const eyesMiddleRight = screen.unpackPNG(hex``);
|
||||
export const eyesMiddleRight = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const eyesNeutral = screen.unpackPNG(hex``);
|
||||
export const eyesNeutral = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const eyesNuclear = screen.unpackPNG(hex``);
|
||||
export const eyesNuclear = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const eyesPinchLeft = screen.unpackPNG(hex``);
|
||||
export const eyesPinchLeft = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const eyesPinchMiddle = screen.unpackPNG(hex``);
|
||||
export const eyesPinchMiddle = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const eyesPinchRight = screen.unpackPNG(hex``);
|
||||
export const eyesPinchRight = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const eyesSleeping = screen.unpackPNG(hex``);
|
||||
export const eyesSleeping = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const eyesTear = screen.unpackPNG(hex``);
|
||||
export const eyesTear = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const eyesTiredLeft = screen.unpackPNG(hex``);
|
||||
export const eyesTiredLeft = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const eyesTiredMiddle = screen.unpackPNG(hex``);
|
||||
export const eyesTiredMiddle = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const eyesTiredRight = screen.unpackPNG(hex``);
|
||||
export const eyesTiredRight = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const eyesToxic = screen.unpackPNG(hex``);
|
||||
export const eyesToxic = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const eyesUp = screen.unpackPNG(hex``);
|
||||
export const eyesUp = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const eyesWinking = screen.unpackPNG(hex``);
|
||||
export const eyesWinking = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const informationAccept = screen.unpackPNG(hex``);
|
||||
export const informationAccept = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const informationBackward = screen.unpackPNG(hex``);
|
||||
export const informationBackward = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const informationDecline = screen.unpackPNG(hex``);
|
||||
export const informationDecline = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const informationForward = screen.unpackPNG(hex``);
|
||||
export const informationForward = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const informationLeft = screen.unpackPNG(hex``);
|
||||
export const informationLeft = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const informationNoGo = screen.unpackPNG(hex``);
|
||||
export const informationNoGo = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const informationQuestionMark = screen.unpackPNG(hex``);
|
||||
export const informationQuestionMark = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const informationRight = screen.unpackPNG(hex``);
|
||||
export const informationRight = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const informationStop1 = screen.unpackPNG(hex``);
|
||||
export const informationStop1 = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const informationStop2 = screen.unpackPNG(hex``);
|
||||
export const informationStop2 = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const informationThumbsDown = screen.unpackPNG(hex``);
|
||||
export const informationThumbsDown = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const informationThumbsUp = screen.unpackPNG(hex``);
|
||||
export const informationThumbsUp = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const informationWarning = screen.unpackPNG(hex``);
|
||||
export const informationWarning = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const legoColorSensor = screen.unpackPNG(hex``);
|
||||
export const legoColorSensor = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const legoEv3icon = screen.unpackPNG(hex``);
|
||||
export const legoEv3icon = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const legoEv3 = screen.unpackPNG(hex``);
|
||||
export const legoEv3 = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const legoGyroSensor = screen.unpackPNG(hex``);
|
||||
export const legoGyroSensor = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const legoIrBeacon = screen.unpackPNG(hex``);
|
||||
export const legoIrBeacon = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const legoIrSensor = screen.unpackPNG(hex``);
|
||||
export const legoIrSensor = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const legoLego = screen.unpackPNG(hex``);
|
||||
export const legoLego = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const legoLargeMotor = screen.unpackPNG(hex``);
|
||||
export const legoLargeMotor = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const legoMindstorms = screen.unpackPNG(hex``);
|
||||
export const legoMindstorms = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const legoMediumMotor = screen.unpackPNG(hex``);
|
||||
export const legoMediumMotor = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const legoSoundSensor = screen.unpackPNG(hex``);
|
||||
export const legoSoundSensor = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const legoTempSensor = screen.unpackPNG(hex``);
|
||||
export const legoTempSensor = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const legoTouchSensor = screen.unpackPNG(hex``);
|
||||
export const legoTouchSensor = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const legoUsSensor = screen.unpackPNG(hex``);
|
||||
export const legoUsSensor = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const objectsBomb = screen.unpackPNG(hex``);
|
||||
export const objectsBomb = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const objectsBoom = screen.unpackPNG(hex``);
|
||||
export const objectsBoom = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const objectsFire = screen.unpackPNG(hex``);
|
||||
export const objectsFire = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const objectsFlowers = screen.unpackPNG(hex``);
|
||||
export const objectsFlowers = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const objectsForest = screen.unpackPNG(hex``);
|
||||
export const objectsForest = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const objectsLightOff = screen.unpackPNG(hex``);
|
||||
export const objectsLightOff = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const objectsLightOn = screen.unpackPNG(hex``);
|
||||
export const objectsLightOn = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const objectsLightning = screen.unpackPNG(hex``);
|
||||
export const objectsLightning = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const objectsNight = screen.unpackPNG(hex``);
|
||||
export const objectsNight = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const objectsPirate = screen.unpackPNG(hex``);
|
||||
export const objectsPirate = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const objectsSnow = screen.unpackPNG(hex``);
|
||||
export const objectsSnow = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const objectsTarget = screen.unpackPNG(hex``);
|
||||
export const objectsTarget = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const progressBar0 = screen.unpackPNG(hex``);
|
||||
export const progressBar0 = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const progressBar1 = screen.unpackPNG(hex``);
|
||||
export const progressBar1 = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const progressBar2 = screen.unpackPNG(hex``);
|
||||
export const progressBar2 = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const progressBar3 = screen.unpackPNG(hex``);
|
||||
export const progressBar3 = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const progressBar4 = screen.unpackPNG(hex``);
|
||||
export const progressBar4 = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const progressDial0 = screen.unpackPNG(hex``);
|
||||
export const progressDial0 = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const progressDial1 = screen.unpackPNG(hex``);
|
||||
export const progressDial1 = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const progressDial2 = screen.unpackPNG(hex``);
|
||||
export const progressDial2 = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const progressDial3 = screen.unpackPNG(hex``);
|
||||
export const progressDial3 = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const progressDial4 = screen.unpackPNG(hex``);
|
||||
export const progressDial4 = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const progressDots0 = screen.unpackPNG(hex``);
|
||||
export const progressDots0 = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const progressDots1 = screen.unpackPNG(hex``);
|
||||
export const progressDots1 = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const progressDots2 = screen.unpackPNG(hex``);
|
||||
export const progressDots2 = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const progressDots3 = screen.unpackPNG(hex``);
|
||||
export const progressDots3 = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const progressHourglass0 = screen.unpackPNG(hex``);
|
||||
export const progressHourglass0 = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const progressHourglass1 = screen.unpackPNG(hex``);
|
||||
export const progressHourglass1 = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const progressHourglass2 = screen.unpackPNG(hex``);
|
||||
export const progressHourglass2 = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const progressTimer0 = screen.unpackPNG(hex``);
|
||||
export const progressTimer0 = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const progressTimer1 = screen.unpackPNG(hex``);
|
||||
export const progressTimer1 = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const progressTimer2 = screen.unpackPNG(hex``);
|
||||
export const progressTimer2 = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const progressTimer3 = screen.unpackPNG(hex``);
|
||||
export const progressTimer3 = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const progressTimer4 = screen.unpackPNG(hex``);
|
||||
export const progressTimer4 = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const progressWaterLevel0 = screen.unpackPNG(hex``);
|
||||
export const progressWaterLevel0 = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const progressWaterLevel1 = screen.unpackPNG(hex``);
|
||||
export const progressWaterLevel1 = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const progressWaterLevel2 = screen.unpackPNG(hex``);
|
||||
export const progressWaterLevel2 = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const progressWaterLevel3 = screen.unpackPNG(hex``);
|
||||
export const progressWaterLevel3 = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const systemAccept1 = screen.unpackPNG(hex``);
|
||||
export const systemAccept1 = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const systemAccept2 = screen.unpackPNG(hex``);
|
||||
export const systemAccept2 = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const systemBox = screen.unpackPNG(hex``);
|
||||
export const systemBox = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const systemDecline1 = screen.unpackPNG(hex``);
|
||||
export const systemDecline1 = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const systemDecline2 = screen.unpackPNG(hex``);
|
||||
export const systemDecline2 = image.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
}
|
@ -4,11 +4,14 @@
|
||||
"files": [
|
||||
"README.md",
|
||||
"ns.ts",
|
||||
"startup.ts"
|
||||
"startup.ts",
|
||||
"images.jres",
|
||||
"images.ts"
|
||||
],
|
||||
"dependencies": {
|
||||
"base": "file:../base",
|
||||
"core": "file:../core",
|
||||
"screen": "file:../screen",
|
||||
"music": "file:../music",
|
||||
"color-sensor": "file:../color-sensor",
|
||||
"touch-sensor": "file:../touch-sensor",
|
||||
|
3
libs/game/pxt.json
Normal file
3
libs/game/pxt.json
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"additionalFilePath": "../../node_modules/pxt-common-packages/libs/game"
|
||||
}
|
3
libs/screen/pxt.json
Normal file
3
libs/screen/pxt.json
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"additionalFilePath": "../../node_modules/pxt-common-packages/libs/screen"
|
||||
}
|
128
libs/screen/shims.d.ts
vendored
Normal file
128
libs/screen/shims.d.ts
vendored
Normal file
@ -0,0 +1,128 @@
|
||||
// Auto-generated. Do not edit.
|
||||
|
||||
|
||||
declare interface Image {
|
||||
/**
|
||||
* Get the width of the image
|
||||
*/
|
||||
//% property shim=ImageMethods::width
|
||||
width: int32;
|
||||
|
||||
/**
|
||||
* Get the height of the image
|
||||
*/
|
||||
//% property shim=ImageMethods::height
|
||||
height: int32;
|
||||
|
||||
/**
|
||||
* True iff the image is monochromatic (black and white)
|
||||
*/
|
||||
//% property shim=ImageMethods::isMono
|
||||
isMono: boolean;
|
||||
|
||||
/**
|
||||
* Set pixel color
|
||||
*/
|
||||
//% shim=ImageMethods::set
|
||||
set(x: int32, y: int32, c: int32): void;
|
||||
|
||||
/**
|
||||
* Get a pixel color
|
||||
*/
|
||||
//% shim=ImageMethods::get
|
||||
get(x: int32, y: int32): int32;
|
||||
|
||||
/**
|
||||
* Fill entire image with a given color
|
||||
*/
|
||||
//% shim=ImageMethods::fill
|
||||
fill(c: int32): void;
|
||||
|
||||
/**
|
||||
* Return a copy of the current image
|
||||
*/
|
||||
//% shim=ImageMethods::clone
|
||||
clone(): Image;
|
||||
|
||||
/**
|
||||
* Flips (mirrors) pixels horizontally in the current image
|
||||
*/
|
||||
//% shim=ImageMethods::flipX
|
||||
flipX(): void;
|
||||
|
||||
/**
|
||||
* Flips (mirrors) pixels vertically in the current image
|
||||
*/
|
||||
//% shim=ImageMethods::flipY
|
||||
flipY(): void;
|
||||
|
||||
/**
|
||||
* Every pixel in image is moved by (dx,dy)
|
||||
*/
|
||||
//% shim=ImageMethods::scroll
|
||||
scroll(dx: int32, dy: int32): void;
|
||||
|
||||
/**
|
||||
* Stretches the image horizontally by 100%
|
||||
*/
|
||||
//% shim=ImageMethods::doubledX
|
||||
doubledX(): Image;
|
||||
|
||||
/**
|
||||
* Stretches the image vertically by 100%
|
||||
*/
|
||||
//% shim=ImageMethods::doubledY
|
||||
doubledY(): Image;
|
||||
|
||||
/**
|
||||
* Replaces one color in an image with another
|
||||
*/
|
||||
//% shim=ImageMethods::replace
|
||||
replace(from: int32, to: int32): void;
|
||||
|
||||
/**
|
||||
* Stretches the image in both directions by 100%
|
||||
*/
|
||||
//% shim=ImageMethods::doubled
|
||||
doubled(): Image;
|
||||
|
||||
/**
|
||||
* Draw given image on the current image
|
||||
*/
|
||||
//% shim=ImageMethods::drawImage
|
||||
drawImage(from: Image, x: int32, y: int32): void;
|
||||
|
||||
/**
|
||||
* Draw given image with transparent background on the current image
|
||||
*/
|
||||
//% shim=ImageMethods::drawTransparentImage
|
||||
drawTransparentImage(from: Image, x: int32, y: int32): void;
|
||||
|
||||
/**
|
||||
* Check if the current image "collides" with another
|
||||
*/
|
||||
//% shim=ImageMethods::overlapsWith
|
||||
overlapsWith(other: Image, x: int32, y: int32): boolean;
|
||||
}
|
||||
declare namespace image {
|
||||
|
||||
/**
|
||||
* Create new empty (transparent) image
|
||||
*/
|
||||
//% shim=image::create
|
||||
function create(width: int32, height: int32): Image;
|
||||
|
||||
/**
|
||||
* Create new image with given content
|
||||
*/
|
||||
//% shim=image::ofBuffer
|
||||
function ofBuffer(buf: Buffer): Image;
|
||||
|
||||
/**
|
||||
* Double the size of an icon
|
||||
*/
|
||||
//% shim=image::doubledIcon
|
||||
function doubledIcon(icon: Buffer): Buffer;
|
||||
}
|
||||
|
||||
// Auto-generated. Do not edit. Really.
|
107
libs/screen/targetoverrides.ts
Normal file
107
libs/screen/targetoverrides.ts
Normal file
@ -0,0 +1,107 @@
|
||||
/**
|
||||
* Tagged image literal converter
|
||||
*/
|
||||
//% shim=@f4 helper=image::ofBuffer
|
||||
//% groups=["0.,","1#*"]
|
||||
function img(lits: any, ...args: any[]): Image { return null }
|
||||
|
||||
|
||||
let screen = image.create(DAL.LCD_WIDTH, DAL.LCD_HEIGHT)
|
||||
|
||||
namespace _screen_internal {
|
||||
//% shim=pxt::updateScreen
|
||||
function updateScreen(img: Image): void {}
|
||||
|
||||
control.addFrameHandler(200, () => {
|
||||
updateScreen(screen)
|
||||
})
|
||||
|
||||
updateScreen(screen)
|
||||
|
||||
export function _stats(msg: string) {
|
||||
// show the msg somewhere - it contains frame rate etc
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
namespace brick {
|
||||
export const LINE_HEIGHT = 12;
|
||||
|
||||
/**
|
||||
* Show text on the screen at a specific line.
|
||||
* @param text the text to print on the screen, eg: "Hello world"
|
||||
* @param line the line number to print the text at, eg: 1
|
||||
*/
|
||||
//% blockId=screen_print block="show string %text|at line %line"
|
||||
//% weight=98 group="Screen" inlineInputMode="inline" blockGap=8
|
||||
//% help=brick/show-string
|
||||
//% line.min=1 line.max=10
|
||||
export function showString(text: string, line: number) {
|
||||
const NUM_LINES = 9;
|
||||
const offset = 5;
|
||||
const y = offset + (Math.clamp(0, NUM_LINES, line - 1) / (NUM_LINES + 2)) * DAL.LCD_HEIGHT;
|
||||
screen.print(text, offset, y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows a number on the screen
|
||||
* @param value the numeric value
|
||||
* @param line the line number to print the text at, eg: 1
|
||||
*/
|
||||
//% blockId=screenShowNumber block="show number %name|at line %line"
|
||||
//% weight=96 group="Screen" inlineInputMode="inline" blockGap=8
|
||||
//% help=brick/show-number
|
||||
//% line.min=1 line.max=10
|
||||
export function showNumber(value: number, line: number) {
|
||||
showString("" + value, line);
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows a name, value pair on the screen
|
||||
* @param value the numeric value
|
||||
* @param line the line number to print the text at, eg: 1
|
||||
*/
|
||||
//% blockId=screenShowValue block="show value %name|= %text|at line %line"
|
||||
//% weight=96 group="Screen" inlineInputMode="inline" blockGap=8
|
||||
//% help=brick/show-value
|
||||
//% line.min=1 line.max=10
|
||||
export function showValue(name: string, value: number, line: number) {
|
||||
value = Math.round(value * 1000) / 1000;
|
||||
showString((name ? name + ": " : "") + value, line);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show an image on the screen
|
||||
* @param image image to draw
|
||||
*/
|
||||
//% blockId=screen_show_image block="show image %image=screen_image_picker"
|
||||
//% weight=100 group="Screen" blockGap=8
|
||||
//% help=brick/show-image
|
||||
export function showImage(image: Image) {
|
||||
if (!image) return;
|
||||
screen.drawImage(image, 0, 0)
|
||||
}
|
||||
|
||||
/**
|
||||
* An image
|
||||
* @param image the image
|
||||
*/
|
||||
//% blockId=screen_image_picker block="%image" shim=TD_ID
|
||||
//% image.fieldEditor="images"
|
||||
//% image.fieldOptions.columns=6
|
||||
//% image.fieldOptions.width=600
|
||||
//% group="Screen" weight=0 blockHidden=1
|
||||
export function __imagePicker(image: Image): Image {
|
||||
return image;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the screen
|
||||
*/
|
||||
//% blockId=screen_clear_screen block="clear screen"
|
||||
//% weight=90 group="Screen"
|
||||
//% help=brick/clear-screen
|
||||
export function clearScreen() {
|
||||
screen.fill(0)
|
||||
}
|
||||
}
|
@ -21,6 +21,8 @@
|
||||
"libs/storage",
|
||||
"libs/datalog",
|
||||
"libs/tests",
|
||||
"libs/screen",
|
||||
"libs/game",
|
||||
"libs/automation"
|
||||
],
|
||||
"simulator": {
|
||||
|
@ -11,7 +11,7 @@ namespace pxsim {
|
||||
analogState: EV3AnalogState;
|
||||
uartState: EV3UArtState;
|
||||
motorState: EV3MotorState;
|
||||
screenState: EV3ScreenState;
|
||||
screenState: ScreenState;
|
||||
audioState: AudioState;
|
||||
remoteState: RemoteState;
|
||||
|
||||
@ -37,7 +37,7 @@ namespace pxsim {
|
||||
this.analogState = new EV3AnalogState();
|
||||
this.uartState = new EV3UArtState();
|
||||
this.motorState = new EV3MotorState();
|
||||
this.screenState = new EV3ScreenState();
|
||||
this.screenState = new ScreenState(["#97b5a6", "#000000"], visuals.SCREEN_WIDTH, visuals.SCREEN_HEIGHT);
|
||||
this.audioState = new AudioState();
|
||||
this.remoteState = new RemoteState();
|
||||
}
|
||||
|
@ -1,134 +1,8 @@
|
||||
|
||||
namespace pxsim {
|
||||
|
||||
function OFF(x: number, y: number) {
|
||||
return x + y * visuals.SCREEN_WIDTH
|
||||
}
|
||||
|
||||
|
||||
export class EV3ScreenState {
|
||||
changed: boolean = true;
|
||||
points: Uint8Array;
|
||||
constructor() {
|
||||
this.points = new Uint8Array(visuals.SCREEN_WIDTH * visuals.SCREEN_HEIGHT)
|
||||
}
|
||||
|
||||
applyMode(off: number, v: number) {
|
||||
if (v & Draw.Clear)
|
||||
this.points[off] = 0;
|
||||
else if (v & Draw.Xor)
|
||||
this.points[off] = this.points[off] ? 0 : 255;
|
||||
else
|
||||
this.points[off] = 255;
|
||||
}
|
||||
|
||||
setPixel(x: number, y: number, v: number) {
|
||||
this.applyMode(OFF(x, y), v)
|
||||
this.changed = true;
|
||||
}
|
||||
|
||||
clear() {
|
||||
for (let i = 0; i < this.points.length; ++i)
|
||||
this.points[i] = 0;
|
||||
this.changed = true;
|
||||
}
|
||||
|
||||
blitLineCore(x: number, y: number, w: number, buf: RefBuffer, mode: Draw, offset = 0) {
|
||||
if (y < 0 || y >= visuals.SCREEN_HEIGHT)
|
||||
return;
|
||||
if (x + w <= 0)
|
||||
return;
|
||||
if (x >= visuals.SCREEN_WIDTH)
|
||||
return;
|
||||
|
||||
let off = OFF(x, y);
|
||||
const off0 = OFF(0, y);
|
||||
const off1 = OFF(visuals.SCREEN_WIDTH - 1, y);
|
||||
let mask = 0x01
|
||||
let dp = offset
|
||||
|
||||
for (let i = 0; i < w; ++i) {
|
||||
if ((buf.data[dp] & mask) && off0 <= off && off <= off1) {
|
||||
this.applyMode(off, mode);
|
||||
}
|
||||
off++
|
||||
mask <<= 1
|
||||
if (mask & 0x100) {
|
||||
mask = 0x01
|
||||
dp++
|
||||
}
|
||||
}
|
||||
|
||||
this.changed = true;
|
||||
}
|
||||
|
||||
clearLine(x: number, y: number, w: number) {
|
||||
let off = OFF(x, y);
|
||||
const off0 = OFF(0, y);
|
||||
const off1 = OFF(visuals.SCREEN_WIDTH - 1, y);
|
||||
for (let i = 0; i < w; ++i) {
|
||||
if (off0 <= off && off <= off1) {
|
||||
this.points[off] = 0
|
||||
}
|
||||
off++
|
||||
}
|
||||
}
|
||||
|
||||
didChange() {
|
||||
const res = this.changed;
|
||||
this.changed = false;
|
||||
return res;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
namespace pxsim.screen {
|
||||
function XX(v: number) { return (v << 16) >> 16 }
|
||||
function YY(v: number) { return v >> 16 }
|
||||
|
||||
export function _setPixel(x: number, y: number, mode: Draw) {
|
||||
const screenState = ev3board().screenState;
|
||||
screenState.setPixel(x, y, mode);
|
||||
}
|
||||
|
||||
export function _blitLine(xw: number, y: number, buf: RefBuffer, mode: Draw) {
|
||||
const screenState = ev3board().screenState;
|
||||
screenState.blitLineCore(XX(xw), y, YY(xw), buf, mode)
|
||||
}
|
||||
|
||||
export function isValidImage(buf: RefBuffer) {
|
||||
return buf.data.length >= 3 && buf.data[0] == 0xf0;
|
||||
}
|
||||
|
||||
export function PIX2BYTES(x: number) {
|
||||
return ((x + 7) >> 3)
|
||||
}
|
||||
export function clear(): void {
|
||||
const screenState = ev3board().screenState;
|
||||
screenState.clear()
|
||||
}
|
||||
|
||||
export function dump() {
|
||||
// No need for this one.
|
||||
}
|
||||
|
||||
export function imageOf(buf: RefBuffer) {
|
||||
return incr(buf)
|
||||
}
|
||||
}
|
||||
|
||||
namespace pxsim.screen {
|
||||
namespace pxsim.image {
|
||||
function DMESG(msg: string) {
|
||||
control.dmesg(msg)
|
||||
}
|
||||
const NULL: RefBuffer = null;
|
||||
function revbits(v: number) {
|
||||
v = (v & 0xf0) >> 4 | (v & 0x0f) << 4;
|
||||
v = (v & 0xcc) >> 2 | (v & 0x33) << 2;
|
||||
v = (v & 0xaa) >> 1 | (v & 0x55) << 1;
|
||||
return v;
|
||||
}
|
||||
|
||||
export function unpackPNG(png: RefBuffer) {
|
||||
function memcmp(off: number, mark: string) {
|
||||
@ -198,10 +72,11 @@ namespace pxsim.screen {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const res = output.createBuffer(2 + byteW * height);
|
||||
res.data[0] = 0xf0;
|
||||
const res = output.createBuffer(3 + byteW * height);
|
||||
res.data[0] = 0xf1;
|
||||
res.data[1] = width;
|
||||
let dst = 2
|
||||
res.data[2] = height;
|
||||
let dst = 3
|
||||
let src = 0
|
||||
let lastMask = (1 << (width & 7)) - 1;
|
||||
if (lastMask == 0)
|
||||
@ -213,99 +88,13 @@ namespace pxsim.screen {
|
||||
return NULL;
|
||||
}
|
||||
for (let j = 0; j < byteW; ++j) {
|
||||
res.data[dst] = ~revbits(two[src++]);
|
||||
res.data[dst] = ~(two[src++]);
|
||||
if (j == byteW - 1) {
|
||||
res.data[dst] &= lastMask;
|
||||
}
|
||||
dst++;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
return image.ofBuffer(res)
|
||||
}
|
||||
}
|
||||
|
||||
namespace pxsim.ImageMethods {
|
||||
const bitdouble = [
|
||||
0x00, 0x03, 0x0c, 0x0f, 0x30, 0x33, 0x3c, 0x3f, 0xc0, 0xc3, 0xcc, 0xcf, 0xf0, 0xf3, 0xfc, 0xff,
|
||||
]
|
||||
|
||||
export function buffer(buf: RefBuffer) {
|
||||
return incr(buf)
|
||||
}
|
||||
|
||||
export function width(buf: RefBuffer) {
|
||||
if (!screen.isValidImage(buf)) return 0
|
||||
return buf.data[1]
|
||||
}
|
||||
|
||||
export function height(buf: RefBuffer) {
|
||||
if (!screen.isValidImage(buf)) return 0
|
||||
const bw = screen.PIX2BYTES(buf.data[1]);
|
||||
const h = ((buf.data.length - 2) / bw) | 0;
|
||||
return h
|
||||
}
|
||||
|
||||
export function draw(buf: RefBuffer, x: number, y: number, mode: Draw): void {
|
||||
const screenState = ev3board().screenState;
|
||||
|
||||
if (!screen.isValidImage(buf))
|
||||
return;
|
||||
|
||||
if (mode & (Draw.Double | Draw.Quad)) {
|
||||
buf = doubled(buf);
|
||||
if (mode & Draw.Quad) {
|
||||
let pbuf = buf;
|
||||
buf = doubled(buf);
|
||||
decr(pbuf);
|
||||
}
|
||||
}
|
||||
|
||||
let pixwidth = buf.data[1];
|
||||
let ptr = 2;
|
||||
const bytewidth = screen.PIX2BYTES(pixwidth);
|
||||
pixwidth = Math.min(pixwidth, visuals.SCREEN_WIDTH);
|
||||
while (ptr + bytewidth <= buf.data.length) {
|
||||
if (mode & (Draw.Clear | Draw.Xor | Draw.Transparent)) {
|
||||
// no erase of background
|
||||
} else {
|
||||
screenState.clearLine(x, y, pixwidth)
|
||||
}
|
||||
screenState.blitLineCore(x, y, pixwidth, buf, mode, ptr);
|
||||
y++;
|
||||
ptr += bytewidth;
|
||||
}
|
||||
|
||||
if (mode & (Draw.Double | Draw.Quad))
|
||||
decr(buf);
|
||||
}
|
||||
|
||||
export function doubled(buf: RefBuffer): RefBuffer {
|
||||
if (!screen.isValidImage(buf))
|
||||
return null;
|
||||
const w = buf.data[1];
|
||||
if (w > 126)
|
||||
return null;
|
||||
const bw = screen.PIX2BYTES(w);
|
||||
const h = ((buf.data.length - 2) / bw) | 0;
|
||||
const bw2 = screen.PIX2BYTES(w * 2);
|
||||
const out = pins.createBuffer(2 + bw2 * h * 2)
|
||||
out.data[0] = 0xf0;
|
||||
out.data[1] = w * 2;
|
||||
let src = 2
|
||||
let dst = 2
|
||||
for (let i = 0; i < h; ++i) {
|
||||
for (let jj = 0; jj < 2; ++jj) {
|
||||
let p = src;
|
||||
for (let j = 0; j < bw; ++j) {
|
||||
const v = buf.data[p++]
|
||||
out.data[dst++] = bitdouble[v & 0xf];
|
||||
out.data[dst++] = bitdouble[v >> 4];
|
||||
}
|
||||
}
|
||||
src += bw;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -500,7 +500,7 @@ namespace pxsim.visuals {
|
||||
}
|
||||
}
|
||||
|
||||
private updateScreenStep(state: EV3ScreenState) {
|
||||
private updateScreenStep(state: ScreenState) {
|
||||
const bBox = this.layoutView.getBrick().getScreenBBox();
|
||||
if (!bBox || bBox.width == 0) return;
|
||||
|
||||
@ -515,13 +515,7 @@ namespace pxsim.visuals {
|
||||
|
||||
this.screenCanvasData = this.screenCanvasCtx.getImageData(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
|
||||
|
||||
let sp = 3
|
||||
const points = state.points
|
||||
const data = this.screenCanvasData.data
|
||||
for (let i = 0; i < points.length; ++i) {
|
||||
data[sp] = points[i]
|
||||
sp += 4;
|
||||
}
|
||||
new Uint32Array(this.screenCanvasData.data.buffer).set(state.screen)
|
||||
|
||||
// Move the image to another canvas element in order to scale it
|
||||
this.screenCanvasTemp.style.width = `${SCREEN_WIDTH}`;
|
||||
|
Loading…
Reference in New Issue
Block a user