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",
|
"name": "Try",
|
||||||
"imageUrl": "/static/lessons/try.png",
|
"imageUrl": "/static/lessons/try.png",
|
||||||
"description": "TBD",
|
"description": "Get a quick introduction to programming with EV3.",
|
||||||
"url": "/getting-started/try",
|
"url": "/getting-started/try",
|
||||||
"cardType": "side"
|
"cardType": "side"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "use",
|
"name": "Use",
|
||||||
"imageUrl": "/static/lessons/use.png",
|
"imageUrl": "/static/lessons/use.png",
|
||||||
"description": "TBD",
|
"description": "Build a robot and drive into the world of robotics!",
|
||||||
"url": "/getting-started/use",
|
"url": "/getting-started/use",
|
||||||
"cardType": "side"
|
"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
|
//% shim=BufferMethods::write
|
||||||
write(dstOffset: int32, src: Buffer): void;
|
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 {
|
declare namespace loops {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -53,11 +53,11 @@ namespace console {
|
|||||||
//% weight=1
|
//% weight=1
|
||||||
//% help=console/send-to-screen
|
//% help=console/send-to-screen
|
||||||
export function sendToScreen(): void {
|
export function sendToScreen(): void {
|
||||||
console.screen.attach();
|
console._screen.attach();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace console.screen {
|
namespace console._screen {
|
||||||
const maxLines = 100;
|
const maxLines = 100;
|
||||||
const screenLines = 10;
|
const screenLines = 10;
|
||||||
let lines: string[];
|
let lines: string[];
|
||||||
@ -78,7 +78,7 @@ namespace console.screen {
|
|||||||
for (let i = 0; i < screenLines; ++i) {
|
for (let i = 0; i < screenLines; ++i) {
|
||||||
const line = lines[i + scrollPosition];
|
const line = lines[i + scrollPosition];
|
||||||
if (line)
|
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,
|
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.
|
// Auto-generated. Do not edit. Really.
|
||||||
|
@ -19,20 +19,13 @@ struct PNGHeader {
|
|||||||
uint8_t IDAT[4];
|
uint8_t IDAT[4];
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
|
|
||||||
namespace screen {
|
namespace image {
|
||||||
|
|
||||||
static uint32_t swap(uint32_t num) {
|
static uint32_t swap(uint32_t num) {
|
||||||
return ((num >> 24) & 0xff) | ((num << 8) & 0xff0000) | ((num >> 8) & 0xff00) |
|
return ((num >> 24) & 0xff) | ((num << 8) & 0xff0000) | ((num >> 8) & 0xff00) |
|
||||||
((num << 24) & 0xff000000);
|
((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. */
|
/** Decompresses a 1-bit gray scale PNG image to image format. */
|
||||||
//%
|
//%
|
||||||
Image unpackPNG(Buffer png) {
|
Image unpackPNG(Buffer png) {
|
||||||
@ -101,12 +94,11 @@ Image unpackPNG(Buffer png) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
Buffer res = mkBuffer(NULL, 2 + byteW * hd.height);
|
auto res = mkImage(hd.width, hd.height, 1);
|
||||||
res->data[0] = 0xf0;
|
|
||||||
res->data[1] = hd.width;
|
uint8_t *dst = res->pix();
|
||||||
uint8_t *dst = res->data + 2;
|
|
||||||
uint8_t *src = tmp;
|
uint8_t *src = tmp;
|
||||||
uint8_t lastMask = (1 << (hd.width & 7)) - 1;
|
uint8_t lastMask = 0xff << (8 - (hd.width & 7));
|
||||||
if (lastMask == 0)
|
if (lastMask == 0)
|
||||||
lastMask = 0xff;
|
lastMask = 0xff;
|
||||||
for (uint32_t i = 0; i < hd.height; ++i) {
|
for (uint32_t i = 0; i < hd.height; ++i) {
|
||||||
@ -117,7 +109,7 @@ Image unpackPNG(Buffer png) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
for (uint32_t j = 0; j < byteW; ++j) {
|
for (uint32_t j = 0; j < byteW; ++j) {
|
||||||
*dst = ~revbits(*src++);
|
*dst = ~*src++;
|
||||||
if (j == byteW - 1) {
|
if (j == byteW - 1) {
|
||||||
*dst &= lastMask;
|
*dst &= lastMask;
|
||||||
}
|
}
|
||||||
|
@ -32,7 +32,6 @@ class MMap : public RefObject {
|
|||||||
extern volatile bool paniced;
|
extern volatile bool paniced;
|
||||||
|
|
||||||
// Buffer, Sound, and Image share representation.
|
// Buffer, Sound, and Image share representation.
|
||||||
typedef Buffer Image;
|
|
||||||
typedef Buffer Sound;
|
typedef Buffer Sound;
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -41,4 +40,6 @@ typedef Buffer Sound;
|
|||||||
#define DEVICE_ID_NOTIFY 10000
|
#define DEVICE_ID_NOTIFY 10000
|
||||||
#define DEVICE_ID_NOTIFY_ONE 10001
|
#define DEVICE_ID_NOTIFY_ONE 10001
|
||||||
|
|
||||||
|
#define IMAGE_BITS 1
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -16,7 +16,6 @@
|
|||||||
"buttons.ts",
|
"buttons.ts",
|
||||||
"png.cpp",
|
"png.cpp",
|
||||||
"screen.cpp",
|
"screen.cpp",
|
||||||
"screen.ts",
|
|
||||||
"battery.ts",
|
"battery.ts",
|
||||||
"output.cpp",
|
"output.cpp",
|
||||||
"output.ts",
|
"output.ts",
|
||||||
@ -26,8 +25,6 @@
|
|||||||
"shims.d.ts",
|
"shims.d.ts",
|
||||||
"enums.d.ts",
|
"enums.d.ts",
|
||||||
"dal.d.ts",
|
"dal.d.ts",
|
||||||
"images.ts",
|
|
||||||
"images.jres",
|
|
||||||
"icons.jres",
|
"icons.jres",
|
||||||
"ns.ts"
|
"ns.ts"
|
||||||
],
|
],
|
||||||
|
@ -9,39 +9,12 @@
|
|||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
|
|
||||||
/**
|
namespace pxt {
|
||||||
* 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,
|
|
||||||
};
|
|
||||||
|
|
||||||
inline bool operator&(Draw a, Draw b) {
|
#define ROW_SIZE 23
|
||||||
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 FB_SIZE (60 * LCD_HEIGHT)
|
#define FB_SIZE (60 * LCD_HEIGHT)
|
||||||
|
|
||||||
static const uint8_t pixmap[] = {0x00, 0xE0, 0x1C, 0xFC, 0x03, 0xE3, 0x1F, 0xFF};
|
static const uint8_t pixmap[] = {0x00, 0x03, 0x1C, 0x1F, 0xE0, 0xE3, 0xFC, 0xFF};
|
||||||
static uint8_t bitBuffer[ROW_SIZE * LCD_HEIGHT];
|
|
||||||
static bool dirty;
|
|
||||||
|
|
||||||
static void bitBufferToFrameBuffer(uint8_t *bitBuffer, uint8_t *fb) {
|
static void bitBufferToFrameBuffer(uint8_t *bitBuffer, uint8_t *fb) {
|
||||||
uint32_t pixels;
|
uint32_t pixels;
|
||||||
@ -49,129 +22,48 @@ static void bitBufferToFrameBuffer(uint8_t *bitBuffer, uint8_t *fb) {
|
|||||||
for (int line = 0; line < LCD_HEIGHT; line++) {
|
for (int line = 0; line < LCD_HEIGHT; line++) {
|
||||||
int n = 7;
|
int n = 7;
|
||||||
while (n--) {
|
while (n--) {
|
||||||
pixels = *bitBuffer++ << 0;
|
pixels = *bitBuffer++ << 16;
|
||||||
pixels |= *bitBuffer++ << 8;
|
pixels |= *bitBuffer++ << 8;
|
||||||
pixels |= *bitBuffer++ << 16;
|
pixels |= *bitBuffer++ << 0;
|
||||||
|
|
||||||
int m = 8;
|
int m = 8;
|
||||||
while (m--) {
|
while (m--) {
|
||||||
*fb++ = pixmap[pixels & 0x07];
|
*fb++ = pixmap[(pixels >> 21) & 0x07];
|
||||||
pixels >>= 3;
|
pixels <<= 3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pixels = *bitBuffer++ << 0;
|
pixels = *bitBuffer++ << 8;
|
||||||
pixels |= *bitBuffer++ << 8;
|
pixels |= *bitBuffer++ << 0;
|
||||||
|
|
||||||
bitBuffer += ROW_SIZE - 23;
|
|
||||||
|
|
||||||
int m = 4;
|
int m = 4;
|
||||||
while (m--) {
|
while (m--) {
|
||||||
*fb++ = pixmap[pixels & 0x07];
|
*fb++ = pixmap[(pixels >> 13) & 0x07];
|
||||||
pixels >>= 3;
|
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 uint8_t *mappedFrameBuffer;
|
||||||
|
static Image lastImg;
|
||||||
|
|
||||||
//%
|
//%
|
||||||
void updateLCD() {
|
void updateScreen(Image img) {
|
||||||
if (dirty && mappedFrameBuffer != MAP_FAILED) {
|
if (img && img != lastImg) {
|
||||||
dirty = false;
|
decrRC(lastImg);
|
||||||
bitBufferToFrameBuffer(bitBuffer, mappedFrameBuffer);
|
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) {
|
void screen_init() {
|
||||||
while (true) {
|
|
||||||
sleep_core_us(30000);
|
|
||||||
updateLCD();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void init() {
|
|
||||||
DMESG("init screen");
|
DMESG("init screen");
|
||||||
if (mappedFrameBuffer)
|
if (mappedFrameBuffer)
|
||||||
return;
|
return;
|
||||||
@ -182,25 +74,19 @@ void init() {
|
|||||||
if (mappedFrameBuffer == MAP_FAILED) {
|
if (mappedFrameBuffer == MAP_FAILED) {
|
||||||
target_panic(903);
|
target_panic(903);
|
||||||
}
|
}
|
||||||
clear();
|
|
||||||
|
|
||||||
pthread_t pid;
|
|
||||||
pthread_create(&pid, NULL, screenRefresh, NULL);
|
|
||||||
pthread_detach(pid);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const uint8_t numbers[] = {
|
static const uint8_t numbers[] = {
|
||||||
0x06, 0x09, 0x09, 0x09, 0x06, 0x04, 0x06, 0x04, 0x04, 0x0e, 0x07, 0x08, 0x06, 0x01, 0x0f, 0x0f,
|
0x06, 0x09, 0x09, 0x09, 0x06, 0x04, 0x06, 0x04, 0x04, 0x0e, 0x07, 0x08, 0x06,
|
||||||
0x08, 0x04, 0x09, 0x06, 0x0c, 0x0a, 0x09, 0x1f, 0x08, 0x1f, 0x01, 0x0f, 0x10, 0x0f, 0x08, 0x04,
|
0x01, 0x0f, 0x0f, 0x08, 0x04, 0x09, 0x06, 0x0c, 0x0a, 0x09, 0x1f, 0x08, 0x1f,
|
||||||
0x0e, 0x11, 0x0e, 0x1f, 0x08, 0x04, 0x02, 0x01, 0x0e, 0x11, 0x0e, 0x11, 0x0e, 0x0e, 0x11, 0x0e,
|
0x01, 0x0f, 0x10, 0x0f, 0x08, 0x04, 0x0e, 0x11, 0x0e, 0x1f, 0x08, 0x04, 0x02,
|
||||||
0x04, 0x02,
|
0x01, 0x0e, 0x11, 0x0e, 0x11, 0x0e, 0x0e, 0x11, 0x0e, 0x04, 0x02,
|
||||||
// face
|
|
||||||
0b11011, 0b11011, 0b00000, 0b11111, 0b11011,
|
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];
|
const uint8_t *src = &numbers[idx * 5];
|
||||||
uint8_t *dst = &bitBuffer[off];
|
|
||||||
for (int i = 0; i < 5; i++) {
|
for (int i = 0; i < 5; i++) {
|
||||||
uint8_t ch = *src++;
|
uint8_t ch = *src++;
|
||||||
for (int jj = 0; jj < 8; ++jj) {
|
for (int jj = 0; jj < 8; ++jj) {
|
||||||
@ -215,13 +101,19 @@ static void drawNumber(int off, int idx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
extern "C" void drawPanic(int code) {
|
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);
|
drawNumber(ptr, 10);
|
||||||
ptr += 6;
|
|
||||||
|
|
||||||
ptr = ROW_SIZE * 70 + 3;
|
ptr = &bitBuffer[ROW_SIZE * 70 + 3];
|
||||||
|
|
||||||
drawNumber(ptr, (code / 100) % 10);
|
drawNumber(ptr, (code / 100) % 10);
|
||||||
ptr += 6;
|
ptr += 6;
|
||||||
@ -230,132 +122,9 @@ extern "C" void drawPanic(int code) {
|
|||||||
drawNumber(ptr, (code / 1) % 10);
|
drawNumber(ptr, (code / 1) % 10);
|
||||||
ptr += 6;
|
ptr += 6;
|
||||||
|
|
||||||
updateLCD();
|
if (mappedFrameBuffer != MAP_FAILED) {
|
||||||
|
bitBufferToFrameBuffer(bitBuffer, mappedFrameBuffer);
|
||||||
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++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
src += bw;
|
|
||||||
}
|
}
|
||||||
return out;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Draw an image on the screen. */
|
} // namespace pxt
|
||||||
//%
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -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
|
//% shim=serial::writeDmesg
|
||||||
function writeDmesg(): void;
|
function writeDmesg(): void;
|
||||||
}
|
}
|
||||||
declare namespace screen {
|
declare namespace image {
|
||||||
|
|
||||||
/** Decompresses a 1-bit gray scale PNG image to image format. */
|
/** Decompresses a 1-bit gray scale PNG image to image format. */
|
||||||
//% shim=screen::unpackPNG
|
//% shim=image::unpackPNG
|
||||||
function unpackPNG(png: Buffer): Image;
|
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 {
|
declare namespace output {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,229 +1,229 @@
|
|||||||
namespace images {
|
namespace images {
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const expressionsBigSmile = screen.unpackPNG(hex``);
|
export const expressionsBigSmile = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const expressionsHeartLarge = screen.unpackPNG(hex``);
|
export const expressionsHeartLarge = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const expressionsHeartSmall = screen.unpackPNG(hex``);
|
export const expressionsHeartSmall = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const expressionsMouth1open = screen.unpackPNG(hex``);
|
export const expressionsMouth1open = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const expressionsMouth1shut = screen.unpackPNG(hex``);
|
export const expressionsMouth1shut = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const expressionsMouth2open = screen.unpackPNG(hex``);
|
export const expressionsMouth2open = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const expressionsMouth2shut = screen.unpackPNG(hex``);
|
export const expressionsMouth2shut = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const expressionsSad = screen.unpackPNG(hex``);
|
export const expressionsSad = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const expressionsSick = screen.unpackPNG(hex``);
|
export const expressionsSick = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const expressionsSmile = screen.unpackPNG(hex``);
|
export const expressionsSmile = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const expressionsSwearing = screen.unpackPNG(hex``);
|
export const expressionsSwearing = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const expressionsTalking = screen.unpackPNG(hex``);
|
export const expressionsTalking = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const expressionsWink = screen.unpackPNG(hex``);
|
export const expressionsWink = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const expressionsZzz = screen.unpackPNG(hex``);
|
export const expressionsZzz = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const eyesAngry = screen.unpackPNG(hex``);
|
export const eyesAngry = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const eyesAwake = screen.unpackPNG(hex``);
|
export const eyesAwake = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const eyesBlackEye = screen.unpackPNG(hex``);
|
export const eyesBlackEye = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const eyesBottomLeft = screen.unpackPNG(hex``);
|
export const eyesBottomLeft = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const eyesBottomRight = screen.unpackPNG(hex``);
|
export const eyesBottomRight = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const eyesCrazy1 = screen.unpackPNG(hex``);
|
export const eyesCrazy1 = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const eyesCrazy2 = screen.unpackPNG(hex``);
|
export const eyesCrazy2 = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const eyesDisappointed = screen.unpackPNG(hex``);
|
export const eyesDisappointed = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const eyesDizzy = screen.unpackPNG(hex``);
|
export const eyesDizzy = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const eyesDown = screen.unpackPNG(hex``);
|
export const eyesDown = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const eyesEvil = screen.unpackPNG(hex``);
|
export const eyesEvil = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const eyesHurt = screen.unpackPNG(hex``);
|
export const eyesHurt = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const eyesKnockedOut = screen.unpackPNG(hex``);
|
export const eyesKnockedOut = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const eyesLove = screen.unpackPNG(hex``);
|
export const eyesLove = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const eyesMiddleLeft = screen.unpackPNG(hex``);
|
export const eyesMiddleLeft = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const eyesMiddleRight = screen.unpackPNG(hex``);
|
export const eyesMiddleRight = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const eyesNeutral = screen.unpackPNG(hex``);
|
export const eyesNeutral = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const eyesNuclear = screen.unpackPNG(hex``);
|
export const eyesNuclear = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const eyesPinchLeft = screen.unpackPNG(hex``);
|
export const eyesPinchLeft = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const eyesPinchMiddle = screen.unpackPNG(hex``);
|
export const eyesPinchMiddle = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const eyesPinchRight = screen.unpackPNG(hex``);
|
export const eyesPinchRight = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const eyesSleeping = screen.unpackPNG(hex``);
|
export const eyesSleeping = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const eyesTear = screen.unpackPNG(hex``);
|
export const eyesTear = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const eyesTiredLeft = screen.unpackPNG(hex``);
|
export const eyesTiredLeft = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const eyesTiredMiddle = screen.unpackPNG(hex``);
|
export const eyesTiredMiddle = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const eyesTiredRight = screen.unpackPNG(hex``);
|
export const eyesTiredRight = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const eyesToxic = screen.unpackPNG(hex``);
|
export const eyesToxic = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const eyesUp = screen.unpackPNG(hex``);
|
export const eyesUp = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const eyesWinking = screen.unpackPNG(hex``);
|
export const eyesWinking = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const informationAccept = screen.unpackPNG(hex``);
|
export const informationAccept = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const informationBackward = screen.unpackPNG(hex``);
|
export const informationBackward = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const informationDecline = screen.unpackPNG(hex``);
|
export const informationDecline = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const informationForward = screen.unpackPNG(hex``);
|
export const informationForward = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const informationLeft = screen.unpackPNG(hex``);
|
export const informationLeft = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const informationNoGo = screen.unpackPNG(hex``);
|
export const informationNoGo = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const informationQuestionMark = screen.unpackPNG(hex``);
|
export const informationQuestionMark = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const informationRight = screen.unpackPNG(hex``);
|
export const informationRight = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const informationStop1 = screen.unpackPNG(hex``);
|
export const informationStop1 = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const informationStop2 = screen.unpackPNG(hex``);
|
export const informationStop2 = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const informationThumbsDown = screen.unpackPNG(hex``);
|
export const informationThumbsDown = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const informationThumbsUp = screen.unpackPNG(hex``);
|
export const informationThumbsUp = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const informationWarning = screen.unpackPNG(hex``);
|
export const informationWarning = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const legoColorSensor = screen.unpackPNG(hex``);
|
export const legoColorSensor = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const legoEv3icon = screen.unpackPNG(hex``);
|
export const legoEv3icon = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const legoEv3 = screen.unpackPNG(hex``);
|
export const legoEv3 = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const legoGyroSensor = screen.unpackPNG(hex``);
|
export const legoGyroSensor = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const legoIrBeacon = screen.unpackPNG(hex``);
|
export const legoIrBeacon = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const legoIrSensor = screen.unpackPNG(hex``);
|
export const legoIrSensor = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const legoLego = screen.unpackPNG(hex``);
|
export const legoLego = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const legoLargeMotor = screen.unpackPNG(hex``);
|
export const legoLargeMotor = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const legoMindstorms = screen.unpackPNG(hex``);
|
export const legoMindstorms = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const legoMediumMotor = screen.unpackPNG(hex``);
|
export const legoMediumMotor = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const legoSoundSensor = screen.unpackPNG(hex``);
|
export const legoSoundSensor = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const legoTempSensor = screen.unpackPNG(hex``);
|
export const legoTempSensor = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const legoTouchSensor = screen.unpackPNG(hex``);
|
export const legoTouchSensor = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const legoUsSensor = screen.unpackPNG(hex``);
|
export const legoUsSensor = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const objectsBomb = screen.unpackPNG(hex``);
|
export const objectsBomb = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const objectsBoom = screen.unpackPNG(hex``);
|
export const objectsBoom = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const objectsFire = screen.unpackPNG(hex``);
|
export const objectsFire = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const objectsFlowers = screen.unpackPNG(hex``);
|
export const objectsFlowers = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const objectsForest = screen.unpackPNG(hex``);
|
export const objectsForest = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const objectsLightOff = screen.unpackPNG(hex``);
|
export const objectsLightOff = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const objectsLightOn = screen.unpackPNG(hex``);
|
export const objectsLightOn = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const objectsLightning = screen.unpackPNG(hex``);
|
export const objectsLightning = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const objectsNight = screen.unpackPNG(hex``);
|
export const objectsNight = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const objectsPirate = screen.unpackPNG(hex``);
|
export const objectsPirate = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const objectsSnow = screen.unpackPNG(hex``);
|
export const objectsSnow = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const objectsTarget = screen.unpackPNG(hex``);
|
export const objectsTarget = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const progressBar0 = screen.unpackPNG(hex``);
|
export const progressBar0 = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const progressBar1 = screen.unpackPNG(hex``);
|
export const progressBar1 = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const progressBar2 = screen.unpackPNG(hex``);
|
export const progressBar2 = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const progressBar3 = screen.unpackPNG(hex``);
|
export const progressBar3 = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const progressBar4 = screen.unpackPNG(hex``);
|
export const progressBar4 = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const progressDial0 = screen.unpackPNG(hex``);
|
export const progressDial0 = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const progressDial1 = screen.unpackPNG(hex``);
|
export const progressDial1 = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const progressDial2 = screen.unpackPNG(hex``);
|
export const progressDial2 = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const progressDial3 = screen.unpackPNG(hex``);
|
export const progressDial3 = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const progressDial4 = screen.unpackPNG(hex``);
|
export const progressDial4 = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const progressDots0 = screen.unpackPNG(hex``);
|
export const progressDots0 = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const progressDots1 = screen.unpackPNG(hex``);
|
export const progressDots1 = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const progressDots2 = screen.unpackPNG(hex``);
|
export const progressDots2 = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const progressDots3 = screen.unpackPNG(hex``);
|
export const progressDots3 = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const progressHourglass0 = screen.unpackPNG(hex``);
|
export const progressHourglass0 = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const progressHourglass1 = screen.unpackPNG(hex``);
|
export const progressHourglass1 = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const progressHourglass2 = screen.unpackPNG(hex``);
|
export const progressHourglass2 = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const progressTimer0 = screen.unpackPNG(hex``);
|
export const progressTimer0 = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const progressTimer1 = screen.unpackPNG(hex``);
|
export const progressTimer1 = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const progressTimer2 = screen.unpackPNG(hex``);
|
export const progressTimer2 = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const progressTimer3 = screen.unpackPNG(hex``);
|
export const progressTimer3 = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const progressTimer4 = screen.unpackPNG(hex``);
|
export const progressTimer4 = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const progressWaterLevel0 = screen.unpackPNG(hex``);
|
export const progressWaterLevel0 = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const progressWaterLevel1 = screen.unpackPNG(hex``);
|
export const progressWaterLevel1 = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const progressWaterLevel2 = screen.unpackPNG(hex``);
|
export const progressWaterLevel2 = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const progressWaterLevel3 = screen.unpackPNG(hex``);
|
export const progressWaterLevel3 = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const systemAccept1 = screen.unpackPNG(hex``);
|
export const systemAccept1 = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const systemAccept2 = screen.unpackPNG(hex``);
|
export const systemAccept2 = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const systemBox = screen.unpackPNG(hex``);
|
export const systemBox = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const systemDecline1 = screen.unpackPNG(hex``);
|
export const systemDecline1 = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const systemDecline2 = screen.unpackPNG(hex``);
|
export const systemDecline2 = image.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
}
|
}
|
@ -4,11 +4,14 @@
|
|||||||
"files": [
|
"files": [
|
||||||
"README.md",
|
"README.md",
|
||||||
"ns.ts",
|
"ns.ts",
|
||||||
"startup.ts"
|
"startup.ts",
|
||||||
|
"images.jres",
|
||||||
|
"images.ts"
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"base": "file:../base",
|
"base": "file:../base",
|
||||||
"core": "file:../core",
|
"core": "file:../core",
|
||||||
|
"screen": "file:../screen",
|
||||||
"music": "file:../music",
|
"music": "file:../music",
|
||||||
"color-sensor": "file:../color-sensor",
|
"color-sensor": "file:../color-sensor",
|
||||||
"touch-sensor": "file:../touch-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/storage",
|
||||||
"libs/datalog",
|
"libs/datalog",
|
||||||
"libs/tests",
|
"libs/tests",
|
||||||
|
"libs/screen",
|
||||||
|
"libs/game",
|
||||||
"libs/automation"
|
"libs/automation"
|
||||||
],
|
],
|
||||||
"simulator": {
|
"simulator": {
|
||||||
|
@ -11,7 +11,7 @@ namespace pxsim {
|
|||||||
analogState: EV3AnalogState;
|
analogState: EV3AnalogState;
|
||||||
uartState: EV3UArtState;
|
uartState: EV3UArtState;
|
||||||
motorState: EV3MotorState;
|
motorState: EV3MotorState;
|
||||||
screenState: EV3ScreenState;
|
screenState: ScreenState;
|
||||||
audioState: AudioState;
|
audioState: AudioState;
|
||||||
remoteState: RemoteState;
|
remoteState: RemoteState;
|
||||||
|
|
||||||
@ -37,7 +37,7 @@ namespace pxsim {
|
|||||||
this.analogState = new EV3AnalogState();
|
this.analogState = new EV3AnalogState();
|
||||||
this.uartState = new EV3UArtState();
|
this.uartState = new EV3UArtState();
|
||||||
this.motorState = new EV3MotorState();
|
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.audioState = new AudioState();
|
||||||
this.remoteState = new RemoteState();
|
this.remoteState = new RemoteState();
|
||||||
}
|
}
|
||||||
|
@ -1,134 +1,8 @@
|
|||||||
|
namespace pxsim.image {
|
||||||
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 {
|
|
||||||
function DMESG(msg: string) {
|
function DMESG(msg: string) {
|
||||||
control.dmesg(msg)
|
control.dmesg(msg)
|
||||||
}
|
}
|
||||||
const NULL: RefBuffer = null;
|
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) {
|
export function unpackPNG(png: RefBuffer) {
|
||||||
function memcmp(off: number, mark: string) {
|
function memcmp(off: number, mark: string) {
|
||||||
@ -198,10 +72,11 @@ namespace pxsim.screen {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
const res = output.createBuffer(2 + byteW * height);
|
const res = output.createBuffer(3 + byteW * height);
|
||||||
res.data[0] = 0xf0;
|
res.data[0] = 0xf1;
|
||||||
res.data[1] = width;
|
res.data[1] = width;
|
||||||
let dst = 2
|
res.data[2] = height;
|
||||||
|
let dst = 3
|
||||||
let src = 0
|
let src = 0
|
||||||
let lastMask = (1 << (width & 7)) - 1;
|
let lastMask = (1 << (width & 7)) - 1;
|
||||||
if (lastMask == 0)
|
if (lastMask == 0)
|
||||||
@ -213,99 +88,13 @@ namespace pxsim.screen {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
for (let j = 0; j < byteW; ++j) {
|
for (let j = 0; j < byteW; ++j) {
|
||||||
res.data[dst] = ~revbits(two[src++]);
|
res.data[dst] = ~(two[src++]);
|
||||||
if (j == byteW - 1) {
|
if (j == byteW - 1) {
|
||||||
res.data[dst] &= lastMask;
|
res.data[dst] &= lastMask;
|
||||||
}
|
}
|
||||||
dst++;
|
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();
|
const bBox = this.layoutView.getBrick().getScreenBBox();
|
||||||
if (!bBox || bBox.width == 0) return;
|
if (!bBox || bBox.width == 0) return;
|
||||||
|
|
||||||
@ -515,13 +515,7 @@ namespace pxsim.visuals {
|
|||||||
|
|
||||||
this.screenCanvasData = this.screenCanvasCtx.getImageData(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
|
this.screenCanvasData = this.screenCanvasCtx.getImageData(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
|
||||||
|
|
||||||
let sp = 3
|
new Uint32Array(this.screenCanvasData.data.buffer).set(state.screen)
|
||||||
const points = state.points
|
|
||||||
const data = this.screenCanvasData.data
|
|
||||||
for (let i = 0; i < points.length; ++i) {
|
|
||||||
data[sp] = points[i]
|
|
||||||
sp += 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Move the image to another canvas element in order to scale it
|
// Move the image to another canvas element in order to scale it
|
||||||
this.screenCanvasTemp.style.width = `${SCREEN_WIDTH}`;
|
this.screenCanvasTemp.style.width = `${SCREEN_WIDTH}`;
|
||||||
|
Loading…
Reference in New Issue
Block a user