diff --git a/Extensions/Sprite.cpp b/Extensions/Sprite.cpp index f3d7e3e..30fe9ac 100644 --- a/Extensions/Sprite.cpp +++ b/Extensions/Sprite.cpp @@ -59,8 +59,6 @@ void* TFT_eSprite::createSprite(int16_t w, int16_t h, uint8_t frames) _iwidth = _dwidth = _bitwidth = w; _iheight = _dheight = h; - _colorMap = nullptr; - this->cursor_x = 0; this->cursor_y = 0; @@ -94,6 +92,8 @@ void* TFT_eSprite::createSprite(int16_t w, int16_t h, uint8_t frames) _img8_2 = _img8 + (w * h + 1); } + if ( (_bpp == 4) && (_colorMap == nullptr)) createPalette(default_4bit_palette); + // This is to make it clear what pointer size is expected to be used // but casting in the user sketch is needed due to the use of void* if ( (_bpp == 1) && (frames > 1) ) @@ -195,7 +195,7 @@ void* TFT_eSprite::callocSprite(int16_t w, int16_t h, uint8_t frames) ** Description: Set a palette for a 4-bit per pixel sprite *************************************************************************************x*/ -void TFT_eSprite::createPalette(uint16_t colorMap[], int colors) +void TFT_eSprite::createPalette(uint16_t colorMap[], uint8_t colors) { if (_colorMap != nullptr) { @@ -204,14 +204,18 @@ void TFT_eSprite::createPalette(uint16_t colorMap[], int colors) if (colorMap == nullptr) { - return; // do nothing other than clear the existing map + // Create a color map using the default FLASH map + createPalette(default_4bit_palette); + return; } - // allocate color map + // Allocate and clear memory for 16 color map _colorMap = (uint16_t *)calloc(16, sizeof(uint16_t)); - if (colors > 16) - colors = 16; - for (auto i = 0; i < colors; i++) + + if (colors > 16) colors = 16; + + // Copy map colors + for (uint8_t i = 0; i < colors; i++) { _colorMap[i] = colorMap[i]; } @@ -222,7 +226,7 @@ void TFT_eSprite::createPalette(uint16_t colorMap[], int colors) ** Description: Set a palette for a 4-bit per pixel sprite *************************************************************************************x*/ -void TFT_eSprite::createPalette(const uint16_t colorMap[], int colors) +void TFT_eSprite::createPalette(const uint16_t colorMap[], uint8_t colors) { if (_colorMap != nullptr) { @@ -231,14 +235,17 @@ void TFT_eSprite::createPalette(const uint16_t colorMap[], int colors) if (colorMap == nullptr) { - return; // do nothing other than clear the existing map + // Create a color map using the default FLASH map + colorMap = default_4bit_palette; } - // allocate color map + // Allocate and clear memory for 16 color map _colorMap = (uint16_t *)calloc(16, sizeof(uint16_t)); - if (colors > 16) - colors = 16; - for (auto i = 0; i < colors; i++) + + if (colors > 16) colors = 16; + + // Copy map colors + for (uint8_t i = 0; i < colors; i++) { _colorMap[i] = pgm_read_word(colorMap++); } @@ -306,7 +313,7 @@ int8_t TFT_eSprite::getColorDepth(void) /*************************************************************************************** ** Function name: setBitmapColor -** Description: Set the foreground foreground and background colour +** Description: Set the 1bpp foreground foreground and background colour ***************************************************************************************/ void TFT_eSprite::setBitmapColor(uint16_t c, uint16_t b) { @@ -317,23 +324,22 @@ void TFT_eSprite::setBitmapColor(uint16_t c, uint16_t b) /*************************************************************************************** ** Function name: setPaletteColor -** Description: Set the palette color at the given index +** Description: Set the 4bpp palette color at the given index ***************************************************************************************/ void TFT_eSprite::setPaletteColor(uint8_t index, uint16_t color) { - if (_colorMap == nullptr || index > 15) - return; // out of bounds + if (_colorMap == nullptr || index > 15) return; // out of bounds + _colorMap[index] = color; } /*************************************************************************************** ** Function name: getPaletteColor -** Description: Return the palette color at index, or 0 (black) on error. +** Description: Return the palette color at 4bpp index, or 0 on error. ***************************************************************************************/ uint16_t TFT_eSprite::getPaletteColor(uint8_t index) { - if (_colorMap == nullptr || index > 15) - return 0; + if (_colorMap == nullptr || index > 15) return 0; // out of bounds return _colorMap[index]; } @@ -395,7 +401,7 @@ int16_t TFT_eSprite::getPivotY(void) #define FP_SCALE 10 bool TFT_eSprite::pushRotated(int16_t angle, int32_t transp) { - if ( !_created || _bpp == 4) return false; + if ( !_created) return false; // Bounding box parameters int16_t min_x; @@ -413,6 +419,7 @@ bool TFT_eSprite::pushRotated(int16_t angle, int32_t transp) uint32_t xe = _iwidth << FP_SCALE; uint32_t ye = _iheight << FP_SCALE; uint32_t tpcolor = transp; // convert to unsigned + if (_bpp == 4) tpcolor = _colorMap[transp & 0x0F]; _tft->startWrite(); // Avoid transaction overhead for every tft pixel @@ -461,9 +468,10 @@ bool TFT_eSprite::pushRotated(int16_t angle, int32_t transp) ** Function name: pushRotated - Fast fixed point integer maths version ** Description: Push a rotated copy of the Sprite to another Sprite *************************************************************************************x*/ +// Not compatible with 4bpp bool TFT_eSprite::pushRotated(TFT_eSprite *spr, int16_t angle, int32_t transp) { - if ( !_created || _bpp == 4) return false; // Check this Sprite is created + if ( !_created || _bpp == 4) return false; // Check this Sprite is created if ( !spr->_created || spr->_bpp == 4) return false; // Ckeck destination Sprite is created // Bounding box parameters @@ -658,12 +666,8 @@ void TFT_eSprite::pushSprite(int32_t x, int32_t y) } else if (_bpp == 4) { - if (_colorMap == nullptr) { - return; - } _tft->pushImage(x, y, _dwidth, _dheight, _img4, false, _colorMap); } - else _tft->pushImage(x, y, _dwidth, _dheight, _img8, (bool)(_bpp == 8)); } diff --git a/Extensions/Sprite.h b/Extensions/Sprite.h index 74ba6b2..489ac69 100644 --- a/Extensions/Sprite.h +++ b/Extensions/Sprite.h @@ -15,6 +15,7 @@ class TFT_eSprite : public TFT_eSPI { // Sketch can cast returned value to (uint16_t*) for 16 bit depth if needed // RAM required is: // - 1 bit per pixel for 1 bit colour depth + // - 1 nibble per pixel for 4 bit colour // - 1 byte per pixel for 8 bit colour // - 2 bytes per pixel for 16 bit color depth ~TFT_eSprite(void); @@ -34,8 +35,8 @@ class TFT_eSprite : public TFT_eSPI { int8_t getColorDepth(void); // Set the palette for a 4 bit depth sprite. Only the first 16 colours in the map are used. - void createPalette(uint16_t *palette, int colors = 16); // Palette in RAM - void createPalette(const uint16_t *palette, int colors = 16); // Palette in FLASH + void createPalette(uint16_t *palette = nullptr, uint8_t colors = 16); // Palette in RAM + void createPalette(const uint16_t *palette = nullptr, uint8_t colors = 16); // Palette in FLASH // Set a single palette index to the given color void setPaletteColor(uint8_t index, uint16_t color); diff --git a/examples/Sprite/Rotated_Sprite_1/Rotated_Sprite_1.ino b/examples/Sprite/Rotated_Sprite_1/Rotated_Sprite_1.ino index b789b50..5bc3ffe 100644 --- a/examples/Sprite/Rotated_Sprite_1/Rotated_Sprite_1.ino +++ b/examples/Sprite/Rotated_Sprite_1/Rotated_Sprite_1.ino @@ -10,7 +10,7 @@ // screen very simple. The rotation is clockwise with increasing angle. The angle is in // degrees, an angle of 0 means no Sprite rotation. -// The pushRotated() function works with 1, 8 and 16 bit per pixel (bpp) Sprites. +// The pushRotated() function works with 1, 4, 8 and 16 bit per pixel (bpp) Sprites. // The original Sprite is unchanged so can be plotted again at a different angle. @@ -20,6 +20,10 @@ // For 1 bpp Sprites the foreground and background colours are defined with the // function spr.setBitmapColor(foregroundColor, backgroundColor). +// For 4 bpp Sprites the colour map index is used instead of the 16 bit colour +// e.g. spr.setTextColor(5); // Green text in default colour map +// See "Transparent_Sprite_Demo_4bit" example for default colour map details + // Created by Bodmer 6/1/19 as an example to the TFT_eSPI library: // https://github.com/Bodmer/TFT_eSPI @@ -46,7 +50,7 @@ void setup() { void loop() { - int xw = tft.width()/2; // xw, yh is midle of screen + int xw = tft.width()/2; // xw, yh is middle of screen int yh = tft.height()/2; diff --git a/examples/Sprite/Sprite_draw_4bit/Sprite_draw_4bit.ino b/examples/Sprite/Sprite_draw_4bit/Sprite_draw_4bit.ino index 40d9fc1..ca3ebe4 100644 --- a/examples/Sprite/Sprite_draw_4bit/Sprite_draw_4bit.ino +++ b/examples/Sprite/Sprite_draw_4bit/Sprite_draw_4bit.ino @@ -88,7 +88,7 @@ void loop(void) // Pass the palette to the Sprite class spr.createPalette(cmap); - // Push Sprite parially off-screen to test cropping + // Push Sprite partially off-screen to test cropping spr.pushSprite(-40, -40); spr.pushSprite(tft.width() / 2 - WIDTH / 2, tft.height() / 2 - HEIGHT / 2, 10); spr.pushSprite(tft.width() - WIDTH + 40, tft.height() - HEIGHT + 40); diff --git a/library.json b/library.json index 70efa62..a17e9ee 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "TFT_eSPI", - "version": "2.2.8", + "version": "2.2.9", "keywords": "Arduino, tft, ePaper, display, STM32, ESP8266, NodeMCU, ESP32, M5Stack, ILI9341, ST7735, ILI9163, S6D02A1, ILI9486, ST7789, RM68140", "description": "A TFT and ePaper SPI graphics library with optimisation for ESP8266, ESP32 and STM32", "repository": diff --git a/library.properties b/library.properties index a3b3ab4..8dd4766 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=TFT_eSPI -version=2.2.8 +version=2.2.9 author=Bodmer maintainer=Bodmer sentence=TFT graphics library for Arduino processors with performance optimisation for STM32, ESP8266 and ESP32