2016-11-30 06:55:37 +01:00
|
|
|
#include "pxt.h"
|
2016-04-02 04:55:51 +02:00
|
|
|
|
2019-12-02 05:58:26 +01:00
|
|
|
PXT_VTABLE(RefMImage, ValType::Object)
|
2016-04-02 04:55:51 +02:00
|
|
|
|
2019-12-02 05:58:26 +01:00
|
|
|
RefMImage::RefMImage(ImageData *d) : PXT_VTABLE_INIT(RefMImage), img(d) {
|
|
|
|
img->incr();
|
2016-04-02 04:55:51 +02:00
|
|
|
}
|
|
|
|
|
2019-12-02 05:58:26 +01:00
|
|
|
void RefMImage::destroy(RefMImage *t) {
|
|
|
|
t->img->decr();
|
|
|
|
}
|
2016-04-13 02:10:37 +02:00
|
|
|
|
2019-12-02 05:58:26 +01:00
|
|
|
void RefMImage::print(RefMImage *t) {
|
2020-08-19 22:03:58 +02:00
|
|
|
DMESG("RefMImage %p size=%d x %d", t, t->img->width, t->img->height);
|
2019-12-02 05:58:26 +01:00
|
|
|
}
|
2016-10-11 22:48:25 +02:00
|
|
|
|
2019-12-02 05:58:26 +01:00
|
|
|
void RefMImage::makeWritable() {
|
|
|
|
if (img->isReadOnly()) {
|
|
|
|
MicroBitImage i(img);
|
|
|
|
img = i.clone().leakData();
|
2016-04-13 02:10:37 +02:00
|
|
|
}
|
2019-12-02 05:58:26 +01:00
|
|
|
}
|
2016-10-11 22:48:25 +02:00
|
|
|
|
2019-12-02 05:58:26 +01:00
|
|
|
void RefMImage::scan(RefMImage *t) {}
|
2016-04-02 04:55:51 +02:00
|
|
|
|
2019-12-02 05:58:26 +01:00
|
|
|
unsigned RefMImage::gcsize(RefMImage *t) {
|
|
|
|
return (sizeof(*t) + 3) >> 2;
|
|
|
|
}
|
2016-04-02 04:55:51 +02:00
|
|
|
|
2019-12-02 05:58:26 +01:00
|
|
|
/**
|
|
|
|
* Creation, manipulation and display of LED images.
|
|
|
|
*/
|
|
|
|
//% color=#7600A8 weight=31 icon="\uf03e"
|
|
|
|
//% advanced=true
|
|
|
|
namespace images {
|
|
|
|
/**
|
|
|
|
* Creates an image that fits on the LED screen.
|
|
|
|
*/
|
|
|
|
//% weight=75 help=images/create-image
|
|
|
|
//% blockId=device_build_image block="create image"
|
|
|
|
//% parts="ledmatrix"
|
|
|
|
Image createImage(ImageLiteral_ leds) {
|
|
|
|
return NEW_GC(RefMImage, imageBytes(leds));
|
|
|
|
}
|
2016-04-02 04:55:51 +02:00
|
|
|
|
2019-12-02 05:58:26 +01:00
|
|
|
/**
|
|
|
|
* Creates an image with 2 frames.
|
|
|
|
*/
|
|
|
|
//% weight=74 help=images/create-big-image
|
|
|
|
//% blockId=device_build_big_image block="create big image" imageLiteral=2
|
|
|
|
//% parts="ledmatrix"
|
|
|
|
Image createBigImage(ImageLiteral_ leds) {
|
|
|
|
return createImage(leds);
|
|
|
|
}
|
2020-08-19 22:03:58 +02:00
|
|
|
|
|
|
|
//%
|
|
|
|
Buffer charCodeBuffer(int charCode) {
|
|
|
|
if(charCode < MICROBIT_FONT_ASCII_START || charCode > MICROBIT_FONT_ASCII_END)
|
|
|
|
return NULL;
|
|
|
|
#if MICROBIT_CODAL
|
|
|
|
auto font = codal::BitmapFont::getSystemFont();
|
|
|
|
#else
|
|
|
|
auto font = MicroBitFont::getSystemFont();
|
|
|
|
#endif
|
|
|
|
const int offset = (charCode - MICROBIT_FONT_ASCII_START) * 5;;
|
|
|
|
const uint8_t* charBuffer = font.characters + offset;
|
|
|
|
|
|
|
|
return PXT_CREATE_BUFFER(charBuffer, 5);
|
|
|
|
}
|
|
|
|
|
2019-12-02 05:58:26 +01:00
|
|
|
} // namespace images
|
2016-04-02 04:55:51 +02:00
|
|
|
|
2019-12-02 05:58:26 +01:00
|
|
|
namespace ImageMethods {
|
|
|
|
/**
|
|
|
|
* Plots the image at a given column to the screen
|
|
|
|
*/
|
|
|
|
//% help=images/plot-image
|
|
|
|
//% parts="ledmatrix"
|
|
|
|
void plotImage(Image i, int xOffset = 0) {
|
|
|
|
uBit.display.print(MicroBitImage(i->img), -xOffset, 0, 0, 0);
|
|
|
|
}
|
2016-04-02 04:55:51 +02:00
|
|
|
|
2019-12-02 05:58:26 +01:00
|
|
|
/**
|
|
|
|
* Shows an frame from the image at offset ``x offset``.
|
|
|
|
* @param xOffset column index to start displaying the image
|
|
|
|
*/
|
|
|
|
//% help=images/show-image weight=80 blockNamespace=images
|
|
|
|
//% blockId=device_show_image_offset block="show image %sprite(myImage)|at offset %offset"
|
|
|
|
//% blockGap=8 parts="ledmatrix" async
|
|
|
|
void showImage(Image sprite, int xOffset, int interval = 400) {
|
|
|
|
uBit.display.print(MicroBitImage(sprite->img), -xOffset, 0, 0, interval);
|
|
|
|
}
|
2016-04-13 02:10:37 +02:00
|
|
|
|
2019-12-02 05:58:26 +01:00
|
|
|
/**
|
|
|
|
* Draws the ``index``-th frame of the image on the screen.
|
|
|
|
* @param xOffset column index to start displaying the image
|
|
|
|
*/
|
|
|
|
//% help=images/plot-frame weight=80
|
|
|
|
//% parts="ledmatrix"
|
|
|
|
void plotFrame(Image i, int xOffset) {
|
|
|
|
// TODO showImage() used in original implementation
|
2020-08-19 22:03:58 +02:00
|
|
|
plotImage(i, xOffset * i->img->height);
|
2019-12-02 05:58:26 +01:00
|
|
|
}
|
2016-04-13 02:10:37 +02:00
|
|
|
|
2019-12-02 05:58:26 +01:00
|
|
|
/**
|
|
|
|
* Scrolls an image .
|
|
|
|
* @param frameOffset x offset moved on each animation step, eg: 1, 2, 5
|
|
|
|
* @param interval time between each animation step in milli seconds, eg: 200
|
|
|
|
*/
|
|
|
|
//% help=images/scroll-image weight=79 async blockNamespace=images
|
|
|
|
//% blockId=device_scroll_image
|
|
|
|
//% block="scroll image %sprite(myImage)|with offset %frameoffset|and interval (ms) %delay"
|
|
|
|
//% blockGap=8 parts="ledmatrix"
|
|
|
|
void scrollImage(Image id, int frameOffset, int interval) {
|
|
|
|
MicroBitImage i(id->img);
|
|
|
|
uBit.display.animate(i, interval, frameOffset, MICROBIT_DISPLAY_ANIMATE_DEFAULT_POS, 0);
|
|
|
|
}
|
2016-04-13 02:10:37 +02:00
|
|
|
|
2019-12-02 05:58:26 +01:00
|
|
|
/**
|
|
|
|
* Sets all pixels off.
|
|
|
|
*/
|
|
|
|
//% help=images/clear
|
|
|
|
//% parts="ledmatrix"
|
|
|
|
void clear(Image i) {
|
|
|
|
i->makeWritable();
|
|
|
|
MicroBitImage(i->img).clear();
|
|
|
|
}
|
2016-04-13 02:10:37 +02:00
|
|
|
|
2019-12-02 05:58:26 +01:00
|
|
|
/**
|
|
|
|
* Sets a specific pixel brightness at a given position
|
|
|
|
*/
|
|
|
|
//%
|
|
|
|
//% parts="ledmatrix"
|
|
|
|
void setPixelBrightness(Image i, int x, int y, int value) {
|
|
|
|
i->makeWritable();
|
|
|
|
MicroBitImage(i->img).setPixelValue(x, y, value);
|
|
|
|
}
|
2016-04-13 02:10:37 +02:00
|
|
|
|
2019-12-02 05:58:26 +01:00
|
|
|
/**
|
|
|
|
* Gets the pixel brightness ([0..255]) at a given position
|
|
|
|
*/
|
|
|
|
//%
|
|
|
|
//% parts="ledmatrix"
|
|
|
|
int pixelBrightness(Image i, int x, int y) {
|
|
|
|
int pix = MicroBitImage(i->img).getPixelValue(x, y);
|
|
|
|
if (pix < 0)
|
|
|
|
return 0;
|
|
|
|
return pix;
|
|
|
|
}
|
2016-04-13 02:10:37 +02:00
|
|
|
|
2019-12-02 05:58:26 +01:00
|
|
|
/**
|
|
|
|
* Gets the width in columns
|
|
|
|
*/
|
|
|
|
//% help=functions/width
|
|
|
|
int width(Image i) {
|
|
|
|
return i->img->width;
|
|
|
|
}
|
2016-04-13 02:10:37 +02:00
|
|
|
|
2019-12-02 05:58:26 +01:00
|
|
|
/**
|
|
|
|
* Gets the height in rows (always 5)
|
|
|
|
*/
|
|
|
|
//%
|
|
|
|
int height(Image i) {
|
|
|
|
return i->img->height;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Set a pixel state at position ``(x,y)``
|
|
|
|
* @param x pixel column
|
|
|
|
* @param y pixel row
|
|
|
|
* @param value pixel state
|
|
|
|
*/
|
|
|
|
//% help=images/set-pixel
|
|
|
|
//% parts="ledmatrix"
|
|
|
|
void setPixel(Image i, int x, int y, bool value) {
|
|
|
|
setPixelBrightness(i, x, y, value ? 255 : 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the pixel state at position ``(x,y)``
|
|
|
|
* @param x pixel column
|
|
|
|
* @param y pixel row
|
|
|
|
*/
|
|
|
|
//% help=images/pixel
|
|
|
|
//% parts="ledmatrix"
|
|
|
|
bool pixel(Image i, int x, int y) {
|
|
|
|
return pixelBrightness(i, x, y) > 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Show a particular frame of the image strip.
|
|
|
|
* @param frame image frame to show
|
|
|
|
*/
|
|
|
|
//% weight=70 help=images/show-frame
|
|
|
|
//% parts="ledmatrix"
|
|
|
|
void showFrame(Image i, int frame, int interval = 400) {
|
2020-08-19 22:03:58 +02:00
|
|
|
showImage(i, frame * i->img->height, interval);
|
2016-04-02 04:55:51 +02:00
|
|
|
}
|
2019-12-02 05:58:26 +01:00
|
|
|
} // namespace ImageMethods
|