Srite class updates + others

Add 2 new pushSprite functions:
1. Sprite to sprite
2. windowed are of sprite to screen
Examples to follow
Bug fixes to sprite class
This commit is contained in:
Bodmer
2020-08-05 20:06:44 +01:00
parent c124688ab1
commit dc114db01b
15 changed files with 507 additions and 230 deletions

View File

@@ -13,7 +13,7 @@
/*************************************************************************************** /***************************************************************************************
** Function name: TFT_eSprite ** Function name: TFT_eSprite
** Description: Class constructor ** Description: Class constructor
*************************************************************************************x*/ ***************************************************************************************/
TFT_eSprite::TFT_eSprite(TFT_eSPI *tft) TFT_eSprite::TFT_eSprite(TFT_eSPI *tft)
{ {
_tft = tft; // Pointer to tft class so we can call member functions _tft = tft; // Pointer to tft class so we can call member functions
@@ -47,14 +47,14 @@ TFT_eSprite::TFT_eSprite(TFT_eSPI *tft)
/*************************************************************************************** /***************************************************************************************
** Function name: createSprite ** Function name: createSprite
** Description: Create a sprite (bitmap) of defined width and height ** Description: Create a sprite (bitmap) of defined width and height
*************************************************************************************x*/ ***************************************************************************************/
// cast returned value to (uint8_t*) for 8 bit or (uint16_t*) for 16 bit colours // cast returned value to (uint8_t*) for 8 bit or (uint16_t*) for 16 bit colours
void* TFT_eSprite::createSprite(int16_t w, int16_t h, uint8_t frames) void* TFT_eSprite::createSprite(int16_t w, int16_t h, uint8_t frames)
{ {
if ( _created ) return _img8_1; if ( _created ) return _img8_1;
if ( w < 1 || h < 1 ) return NULL; if ( w < 1 || h < 1 ) return nullptr;
_iwidth = _dwidth = _bitwidth = w; _iwidth = _dwidth = _bitwidth = w;
_iheight = _dheight = h; _iheight = _dheight = h;
@@ -105,17 +105,28 @@ void* TFT_eSprite::createSprite(int16_t w, int16_t h, uint8_t frames)
if (_img8) if (_img8)
{ {
_created = true; _created = true;
return _img8; return _img8_1;
} }
return NULL; return nullptr;
}
/***************************************************************************************
** Function name: getPointer
** Description: Returns pointer to start of sprite memory area
***************************************************************************************/
void* TFT_eSprite::getPointer(void)
{
if (!_created) return nullptr;
return _img8_1;
} }
/*************************************************************************************** /***************************************************************************************
** Function name: created ** Function name: created
** Description: Returns true is sprite has been created ** Description: Returns true is sprite has been created
*************************************************************************************x*/ ***************************************************************************************/
bool TFT_eSprite::created(void) bool TFT_eSprite::created(void)
{ {
return _created; return _created;
@@ -125,7 +136,7 @@ bool TFT_eSprite::created(void)
/*************************************************************************************** /***************************************************************************************
** Function name: ~TFT_eSprite ** Function name: ~TFT_eSprite
** Description: Class destructor ** Description: Class destructor
*************************************************************************************x*/ ***************************************************************************************/
TFT_eSprite::~TFT_eSprite(void) TFT_eSprite::~TFT_eSprite(void)
{ {
deleteSprite(); deleteSprite();
@@ -139,14 +150,14 @@ TFT_eSprite::~TFT_eSprite(void)
/*************************************************************************************** /***************************************************************************************
** Function name: callocSprite ** Function name: callocSprite
** Description: Allocate a memory area for the Sprite and return pointer ** Description: Allocate a memory area for the Sprite and return pointer
*************************************************************************************x*/ ***************************************************************************************/
void* TFT_eSprite::callocSprite(int16_t w, int16_t h, uint8_t frames) void* TFT_eSprite::callocSprite(int16_t w, int16_t h, uint8_t frames)
{ {
// Add one extra "off screen" pixel to point out-of-bounds setWindow() coordinates // Add one extra "off screen" pixel to point out-of-bounds setWindow() coordinates
// this means push/writeColor functions do not need additional bounds checks and // this means push/writeColor functions do not need additional bounds checks and
// hence will run faster in normal circumstances. // hence will run faster in normal circumstances.
uint8_t* ptr8 = NULL; uint8_t* ptr8 = nullptr;
if (frames > 2) frames = 2; // Currently restricted to 2 frame buffers if (frames > 2) frames = 2; // Currently restricted to 2 frame buffers
if (frames < 1) frames = 1; if (frames < 1) frames = 1;
@@ -154,10 +165,17 @@ void* TFT_eSprite::callocSprite(int16_t w, int16_t h, uint8_t frames)
if (_bpp == 16) if (_bpp == 16)
{ {
#if defined (ESP32) && defined (CONFIG_SPIRAM_SUPPORT) #if defined (ESP32) && defined (CONFIG_SPIRAM_SUPPORT)
if ( psramFound() && this->_psram_enable && !_tft->DMA_Enabled) ptr8 = ( uint8_t*) ps_calloc(frames * w * h + frames, sizeof(uint16_t)); if ( psramFound() && this->_psram_enable && !_tft->DMA_Enabled)
{
ptr8 = ( uint8_t*) ps_calloc(frames * w * h + frames, sizeof(uint16_t));
//Serial.println("PSRAM");
}
else else
#endif #endif
ptr8 = ( uint8_t*) calloc(frames * w * h + frames, sizeof(uint16_t)); {
ptr8 = ( uint8_t*) calloc(frames * w * h + frames, sizeof(uint16_t));
//Serial.println("Normal RAM");
}
} }
else if (_bpp == 8) else if (_bpp == 8)
@@ -203,7 +221,7 @@ void* TFT_eSprite::callocSprite(int16_t w, int16_t h, uint8_t frames)
/*************************************************************************************** /***************************************************************************************
** Function name: createPalette (from RAM array) ** Function name: createPalette (from RAM array)
** Description: Set a palette for a 4-bit per pixel sprite ** Description: Set a palette for a 4-bit per pixel sprite
*************************************************************************************x*/ ***************************************************************************************/
void TFT_eSprite::createPalette(uint16_t colorMap[], uint8_t colors) void TFT_eSprite::createPalette(uint16_t colorMap[], uint8_t colors)
{ {
@@ -223,7 +241,7 @@ void TFT_eSprite::createPalette(uint16_t colorMap[], uint8_t colors)
_colorMap = (uint16_t *)calloc(16, sizeof(uint16_t)); _colorMap = (uint16_t *)calloc(16, sizeof(uint16_t));
if (colors > 16) colors = 16; if (colors > 16) colors = 16;
// Copy map colors // Copy map colors
for (uint8_t i = 0; i < colors; i++) for (uint8_t i = 0; i < colors; i++)
{ {
@@ -234,15 +252,10 @@ void TFT_eSprite::createPalette(uint16_t colorMap[], uint8_t colors)
/*************************************************************************************** /***************************************************************************************
** Function name: createPalette (from FLASH array) ** Function name: createPalette (from FLASH array)
** Description: Set a palette for a 4-bit per pixel sprite ** Description: Set a palette for a 4-bit per pixel sprite
*************************************************************************************x*/ ***************************************************************************************/
void TFT_eSprite::createPalette(const uint16_t colorMap[], uint8_t colors) void TFT_eSprite::createPalette(const uint16_t colorMap[], uint8_t colors)
{ {
if (_colorMap != nullptr)
{
free(_colorMap);
}
if (colorMap == nullptr) if (colorMap == nullptr)
{ {
// Create a color map using the default FLASH map // Create a color map using the default FLASH map
@@ -264,11 +277,11 @@ void TFT_eSprite::createPalette(const uint16_t colorMap[], uint8_t colors)
/*************************************************************************************** /***************************************************************************************
** Function name: frameBuffer ** Function name: frameBuffer
** Description: For 1 bpp Sprites, select the frame used for graphics ** Description: For 1 bpp Sprites, select the frame used for graphics
*************************************************************************************x*/ ***************************************************************************************/
// Frames are numbered 1 and 2 // Frames are numbered 1 and 2
void* TFT_eSprite::frameBuffer(int8_t f) void* TFT_eSprite::frameBuffer(int8_t f)
{ {
if (!_created) return NULL; if (!_created) return nullptr;
if ( f == 2 ) _img8 = _img8_2; if ( f == 2 ) _img8 = _img8_2;
else _img8 = _img8_1; else _img8 = _img8_1;
@@ -285,34 +298,37 @@ void* TFT_eSprite::frameBuffer(int8_t f)
/*************************************************************************************** /***************************************************************************************
** Function name: setColorDepth ** Function name: setColorDepth
** Description: Set bits per pixel for colour (1, 8 or 16) ** Description: Set bits per pixel for colour (1, 8 or 16)
*************************************************************************************x*/ ***************************************************************************************/
void* TFT_eSprite::setColorDepth(int8_t b) void* TFT_eSprite::setColorDepth(int8_t b)
{ {
// Can't change an existing sprite's colour depth so delete it // Do not re-create the sprite if the colour depth does not change
if (_created) free(_img8_1); if (_bpp == b) return _img8_1;
// Now define the new colour depth // Validate the new colour depth
if ( b > 8 ) _bpp = 16; // Bytes per pixel if ( b > 8 ) _bpp = 16; // Bytes per pixel
else if ( b > 4 ) _bpp = 8; else if ( b > 4 ) _bpp = 8;
else if ( b > 1 ) _bpp = 4; else if ( b > 1 ) _bpp = 4;
else _bpp = 1; else _bpp = 1;
// Can't change an existing sprite's colour depth so delete it
if (_created) free(_img8_1);
// If it existed, re-create the sprite with the new colour depth // If it existed, re-create the sprite with the new colour depth
if (_created) if (_created)
{ {
_created = false; _created = false;
return createSprite(_iwidth, _iheight); return createSprite(_dwidth, _dheight);
} }
return NULL; return nullptr;
} }
/*************************************************************************************** /***************************************************************************************
** Function name: getColorDepth ** Function name: getColorDepth
** Description: Get bits per pixel for colour (1, 8 or 16) ** Description: Get bits per pixel for colour (1, 8 or 16)
*************************************************************************************x*/ ***************************************************************************************/
int8_t TFT_eSprite::getColorDepth(void) int8_t TFT_eSprite::getColorDepth(void)
{ {
@@ -357,7 +373,7 @@ uint16_t TFT_eSprite::getPaletteColor(uint8_t index)
/*************************************************************************************** /***************************************************************************************
** Function name: deleteSprite ** Function name: deleteSprite
** Description: Delete the sprite to free up memory (RAM) ** Description: Delete the sprite to free up memory (RAM)
*************************************************************************************x*/ ***************************************************************************************/
void TFT_eSprite::deleteSprite(void) void TFT_eSprite::deleteSprite(void)
{ {
if (!_created ) return; if (!_created ) return;
@@ -369,6 +385,8 @@ void TFT_eSprite::deleteSprite(void)
free(_img8_1); free(_img8_1);
_img8 = nullptr;
_created = false; _created = false;
} }
@@ -376,7 +394,7 @@ void TFT_eSprite::deleteSprite(void)
/*************************************************************************************** /***************************************************************************************
** Function name: setPivot ** Function name: setPivot
** Description: Set the pivot point in this Sprite ** Description: Set the pivot point in this Sprite
*************************************************************************************x*/ ***************************************************************************************/
void TFT_eSprite::setPivot(int16_t x, int16_t y) void TFT_eSprite::setPivot(int16_t x, int16_t y)
{ {
_xpivot = x; _xpivot = x;
@@ -407,7 +425,7 @@ int16_t TFT_eSprite::getPivotY(void)
/*************************************************************************************** /***************************************************************************************
** Function name: pushRotated - Fast fixed point integer maths version ** Function name: pushRotated - Fast fixed point integer maths version
** Description: Push rotated Sprite to TFT screen ** Description: Push rotated Sprite to TFT screen
*************************************************************************************x*/ ***************************************************************************************/
#define FP_SCALE 10 #define FP_SCALE 10
bool TFT_eSprite::pushRotated(int16_t angle, int32_t transp) bool TFT_eSprite::pushRotated(int16_t angle, int32_t transp)
{ {
@@ -426,11 +444,11 @@ bool TFT_eSprite::pushRotated(int16_t angle, int32_t transp)
int32_t xt = min_x - _tft->_xpivot; int32_t xt = min_x - _tft->_xpivot;
int32_t yt = min_y - _tft->_ypivot; int32_t yt = min_y - _tft->_ypivot;
uint32_t xe = _iwidth << FP_SCALE; uint32_t xe = _dwidth << FP_SCALE;
uint32_t ye = _iheight << FP_SCALE; uint32_t ye = _dheight << FP_SCALE;
uint32_t tpcolor = transp; // convert to unsigned uint32_t tpcolor = transp; // convert to unsigned
if (_bpp == 4) tpcolor = _colorMap[transp & 0x0F]; if (_bpp == 4) tpcolor = _colorMap[transp & 0x0F];
tpcolor = tpcolor>>8 | tpcolor<<8; // Working with swapped color bytes
_tft->startWrite(); // Avoid transaction overhead for every tft pixel _tft->startWrite(); // Avoid transaction overhead for every tft pixel
// Scan destination bounding box and fetch transformed pixels from source Sprite // Scan destination bounding box and fetch transformed pixels from source Sprite
@@ -447,8 +465,8 @@ bool TFT_eSprite::pushRotated(int16_t angle, int32_t transp)
uint32_t rp; uint32_t rp;
int32_t xp = xs >> FP_SCALE; int32_t xp = xs >> FP_SCALE;
int32_t yp = ys >> FP_SCALE; int32_t yp = ys >> FP_SCALE;
if (_bpp == 16) {rp = _img[xp + yp * _iwidth]; rp = rp>>8 | rp<<8; } if (_bpp == 16) {rp = _img[xp + yp * _iwidth]; }
else rp = readPixel(xp, yp); else { rp = readPixel(xp, yp); rp = rp>>8 | rp<<8; }
if (tpcolor == rp) { if (tpcolor == rp) {
if (pixel_count) { if (pixel_count) {
// TFT window is already clipped, so this is faster than pushImage() // TFT window is already clipped, so this is faster than pushImage()
@@ -458,7 +476,7 @@ bool TFT_eSprite::pushRotated(int16_t angle, int32_t transp)
} }
} }
else { else {
sline_buffer[pixel_count++] = rp>>8 | rp<<8; sline_buffer[pixel_count++] = rp;
} }
} while (++x < max_x && (xs += _cosra) < xe && (ys += _sinra) < ye); } while (++x < max_x && (xs += _cosra) < xe && (ys += _sinra) < ye);
if (pixel_count) { if (pixel_count) {
@@ -477,7 +495,7 @@ bool TFT_eSprite::pushRotated(int16_t angle, int32_t transp)
/*************************************************************************************** /***************************************************************************************
** Function name: pushRotated - Fast fixed point integer maths version ** Function name: pushRotated - Fast fixed point integer maths version
** Description: Push a rotated copy of the Sprite to another Sprite ** Description: Push a rotated copy of the Sprite to another Sprite
*************************************************************************************x*/ ***************************************************************************************/
// Not compatible with 4bpp // Not compatible with 4bpp
bool TFT_eSprite::pushRotated(TFT_eSprite *spr, int16_t angle, int32_t transp) bool TFT_eSprite::pushRotated(TFT_eSprite *spr, int16_t angle, int32_t transp)
{ {
@@ -497,9 +515,9 @@ bool TFT_eSprite::pushRotated(TFT_eSprite *spr, int16_t angle, int32_t transp)
int32_t xt = min_x - spr->_xpivot; int32_t xt = min_x - spr->_xpivot;
int32_t yt = min_y - spr->_ypivot; int32_t yt = min_y - spr->_ypivot;
uint32_t xe = _iwidth << FP_SCALE; uint32_t xe = _dwidth << FP_SCALE;
uint32_t ye = _iheight << FP_SCALE; uint32_t ye = _dheight << FP_SCALE;
uint32_t tpcolor = transp; // convert to unsigned uint32_t tpcolor = transp>>8 | transp<<8; // convert to unsigned swapped bytes
bool oldSwapBytes = spr->getSwapBytes(); bool oldSwapBytes = spr->getSwapBytes();
spr->setSwapBytes(false); spr->setSwapBytes(false);
@@ -518,8 +536,8 @@ bool TFT_eSprite::pushRotated(TFT_eSprite *spr, int16_t angle, int32_t transp)
uint32_t rp; uint32_t rp;
int32_t xp = xs >> FP_SCALE; int32_t xp = xs >> FP_SCALE;
int32_t yp = ys >> FP_SCALE; int32_t yp = ys >> FP_SCALE;
if (_bpp == 16) {rp = _img[xp + yp * _iwidth]; rp = rp>>8 | rp<<8; } if (_bpp == 16) rp = _img[xp + yp * _iwidth];
else rp = readPixel(xp, yp); else { rp = readPixel(xp, yp); rp = rp>>8 | rp<<8; }
if (tpcolor == rp) { if (tpcolor == rp) {
if (pixel_count) { if (pixel_count) {
spr->pushImage(x - pixel_count, y, pixel_count, 1, sline_buffer); spr->pushImage(x - pixel_count, y, pixel_count, 1, sline_buffer);
@@ -540,7 +558,7 @@ bool TFT_eSprite::pushRotated(TFT_eSprite *spr, int16_t angle, int32_t transp)
/*************************************************************************************** /***************************************************************************************
** Function name: getRotatedBounds ** Function name: getRotatedBounds
** Description: Get TFT bounding box of a rotated Sprite wrt pivot ** Description: Get TFT bounding box of a rotated Sprite wrt pivot
*************************************************************************************x*/ ***************************************************************************************/
bool TFT_eSprite::getRotatedBounds(int16_t angle, int16_t *min_x, int16_t *min_y, bool TFT_eSprite::getRotatedBounds(int16_t angle, int16_t *min_x, int16_t *min_y,
int16_t *max_x, int16_t *max_y) int16_t *max_x, int16_t *max_y)
{ {
@@ -572,7 +590,7 @@ bool TFT_eSprite::getRotatedBounds(int16_t angle, int16_t *min_x, int16_t *min_y
/*************************************************************************************** /***************************************************************************************
** Function name: getRotatedBounds ** Function name: getRotatedBounds
** Description: Get destination Sprite bounding box of a rotated Sprite wrt pivot ** Description: Get destination Sprite bounding box of a rotated Sprite wrt pivot
*************************************************************************************x*/ ***************************************************************************************/
bool TFT_eSprite::getRotatedBounds(TFT_eSprite *spr, int16_t angle, int16_t *min_x, int16_t *min_y, bool TFT_eSprite::getRotatedBounds(TFT_eSprite *spr, int16_t angle, int16_t *min_x, int16_t *min_y,
int16_t *max_x, int16_t *max_y) int16_t *max_x, int16_t *max_y)
{ {
@@ -608,7 +626,7 @@ bool TFT_eSprite::getRotatedBounds(TFT_eSprite *spr, int16_t angle, int16_t *min
/*************************************************************************************** /***************************************************************************************
** Function name: rotatedBounds ** Function name: rotatedBounds
** Description: Get bounding box of a rotated Sprite wrt pivot ** Description: Get bounding box of a rotated Sprite wrt pivot
*************************************************************************************x*/ ***************************************************************************************/
void TFT_eSprite::getRotatedBounds(int16_t angle, int16_t w, int16_t h, int16_t xp, int16_t yp, void TFT_eSprite::getRotatedBounds(int16_t angle, int16_t w, int16_t h, int16_t xp, int16_t yp,
int16_t *min_x, int16_t *min_y, int16_t *max_x, int16_t *max_y) int16_t *min_x, int16_t *min_y, int16_t *max_x, int16_t *max_y)
{ {
@@ -662,7 +680,7 @@ void TFT_eSprite::getRotatedBounds(int16_t angle, int16_t w, int16_t h, int16_t
/*************************************************************************************** /***************************************************************************************
** Function name: pushSprite ** Function name: pushSprite
** Description: Push the sprite to the TFT at x, y ** Description: Push the sprite to the TFT at x, y
*************************************************************************************x*/ ***************************************************************************************/
void TFT_eSprite::pushSprite(int32_t x, int32_t y) void TFT_eSprite::pushSprite(int32_t x, int32_t y)
{ {
if (!_created) return; if (!_created) return;
@@ -671,7 +689,7 @@ void TFT_eSprite::pushSprite(int32_t x, int32_t y)
{ {
bool oldSwapBytes = _tft->getSwapBytes(); bool oldSwapBytes = _tft->getSwapBytes();
_tft->setSwapBytes(false); _tft->setSwapBytes(false);
_tft->pushImage(x, y, _iwidth, _iheight, _img ); _tft->pushImage(x, y, _dwidth, _dheight, _img );
_tft->setSwapBytes(oldSwapBytes); _tft->setSwapBytes(oldSwapBytes);
} }
else if (_bpp == 4) else if (_bpp == 4)
@@ -685,7 +703,7 @@ void TFT_eSprite::pushSprite(int32_t x, int32_t y)
/*************************************************************************************** /***************************************************************************************
** Function name: pushSprite ** Function name: pushSprite
** Description: Push the sprite to the TFT at x, y with transparent colour ** Description: Push the sprite to the TFT at x, y with transparent colour
*************************************************************************************x*/ ***************************************************************************************/
void TFT_eSprite::pushSprite(int32_t x, int32_t y, uint16_t transp) void TFT_eSprite::pushSprite(int32_t x, int32_t y, uint16_t transp)
{ {
if (!_created) return; if (!_created) return;
@@ -694,7 +712,7 @@ void TFT_eSprite::pushSprite(int32_t x, int32_t y, uint16_t transp)
{ {
bool oldSwapBytes = _tft->getSwapBytes(); bool oldSwapBytes = _tft->getSwapBytes();
_tft->setSwapBytes(false); _tft->setSwapBytes(false);
_tft->pushImage(x, y, _iwidth, _iheight, _img, transp ); _tft->pushImage(x, y, _dwidth, _dheight, _img, transp );
_tft->setSwapBytes(oldSwapBytes); _tft->setSwapBytes(oldSwapBytes);
} }
else if (_bpp == 8) else if (_bpp == 8)
@@ -710,10 +728,171 @@ void TFT_eSprite::pushSprite(int32_t x, int32_t y, uint16_t transp)
} }
/***************************************************************************************
** Function name: pushSprite
** Description: Push the sprite to another sprite at x, y
***************************************************************************************/
// Note: The following sprite to sprite colour depths are currently supported:
// Source Destination
// 16bpp -> 16bpp
// 16bpp -> 8bpp
// 4bpp -> 4bpp (note: color translation depends on the 2 sprites pallet colors)
// 1bpp -> 1bpp (note: color translation depends on the 2 sprites bitmap colors)
bool TFT_eSprite::pushSprite(TFT_eSprite *spr, int32_t x, int32_t y)
{
if (!_created) return false;
if (!spr->created()) return false;
// Check destination sprite compatibility
int8_t ds_bpp = spr->getColorDepth();
if (_bpp == 16 && ds_bpp != 16 && ds_bpp != 8) return false;
if (_bpp == 8) return false;
if (_bpp == 4 && ds_bpp != 4) return false;
if (_bpp == 1 && ds_bpp != 1) return false;
bool oldSwapBytes = spr->getSwapBytes();
spr->setSwapBytes(false);
spr->pushImage(x, y, _dwidth, _dheight, _img );
spr->setSwapBytes(oldSwapBytes);
return true;
}
/***************************************************************************************
** Function name: pushSprite
** Description: Push the sprite to another sprite at x, y with transparent colour
***************************************************************************************/
/* >>>>>> Using a transparent color is not supported at the moment <<<<<<
void TFT_eSprite::pushSprite(TFT_eSprite *spr, int32_t x, int32_t y, uint16_t transp)
{
if (!_created) return;
if (_bpp == 16)
{
bool oldSwapBytes = spr->getSwapBytes();
spr->setSwapBytes(false);
spr->pushImage(x, y, _dwidth, _dheight, _img, transp );
spr->setSwapBytes(oldSwapBytes);
}
else if (_bpp == 8)
{
transp = (uint8_t)((transp & 0xE000)>>8 | (transp & 0x0700)>>6 | (transp & 0x0018)>>3);
spr->pushImage(x, y, _dwidth, _dheight, _img8, (uint8_t)transp, (bool)true);
}
else if (_bpp == 4)
{
spr->pushImage(x, y, _dwidth, _dheight, _img4, (uint8_t)(transp & 0x0F), false, _colorMap);
}
else spr->pushImage(x, y, _dwidth, _dheight, _img8, 0, (bool)false);
}
*/
/***************************************************************************************
** Function name: pushSprite
** Description: Push a cropped sprite to the TFT at tx, ty
***************************************************************************************/
bool TFT_eSprite::pushSprite(int32_t tx, int32_t ty, int32_t sx, int32_t sy, int32_t sw, int32_t sh)
{
if (!_created) return false;
// Perform window boundary checks and crop if needed
setWindow(sx, sy, sx + sw - 1, sy + sh - 1);
/* These global variables are now populated for the sprite
_xs = x start coordinate
_ys = y start coordinate
_xe = x end coordinate (inclusive)
_ye = y end coordinate (inclusive)
*/
// Calculate new sprite window bounding box width and height
sw = _xe - _xs + 1;
sh = _ye - _ys + 1;
if (_ys >= _iheight) return false;
if (_bpp == 16)
{
bool oldSwapBytes = _tft->getSwapBytes();
_tft->setSwapBytes(false);
// Check if a faster block copy to screen is possible
if ( sx == 0 && sw == _dwidth)
_tft->pushImage(tx, ty, sw, sh, _img + _iwidth * _ys );
else // Render line by line
while (sh--)
_tft->pushImage(tx, ty++, sw, 1, _img + _xs + _iwidth * _ys++ );
_tft->setSwapBytes(oldSwapBytes);
}
else if (_bpp == 8)
{
// Check if a faster block copy to screen is possible
if ( sx == 0 && sw == _dwidth)
_tft->pushImage(tx, ty, sw, sh, _img8 + _iwidth * _ys, true );
else // Render line by line
while (sh--)
_tft->pushImage(tx, ty++, sw, 1, _img8 + _xs + _iwidth * _ys++, true );
}
else if (_bpp == 4)
{
// Check if a faster block copy to screen is possible
if ( sx == 0 && sw == _dwidth)
_tft->pushImage(tx, ty, sw, sh, _img4 + (_iwidth>>1) * _ys, false, _colorMap );
else // Render line by line
{
uint32_t ds = _xs&1; // Odd x start pixel
uint32_t de = 0; // Odd x end pixel
if ((sw > ds) && (_xe&1)) de = 1;
uint32_t dm = 0; // Midsection pixel count
if (sw > (ds+de)) dm = sw - ds - de;
sw--;
uint32_t yp = (_xs + ds + _iwidth * _ys)>>1;
_tft->startWrite();
while (sh--)
{
if (ds) _tft->drawPixel(tx, ty, readPixel(_xs, _ys) );
if (dm) _tft->pushImage(tx + ds, ty, dm, 1, _img4 + yp, false, _colorMap );
if (de) _tft->drawPixel(tx + sw, ty, readPixel(_xe, _ys) );
_ys++;
ty++;
yp += (_iwidth>>1);
}
_tft->endWrite();
}
}
else // 1bpp
{
// Check if a faster block copy to screen is possible
if ( sx == 0 && sw == _dwidth)
_tft->pushImage(tx, ty, sw, sh, _img8 + (_iwidth>>3) * _ys, false );
else // Render line by line
{
_tft->startWrite();
_tft->setWindow(tx, ty, tx+sw-1, ty+sh-1);
while (sh--)
{
for (uint32_t dx = _xs; dx < _xs + sw; dx++) _tft->pushColor(readPixel(dx, _ys));
ty++;
_ys++;
}
_tft->endWrite();
}
}
return true;
}
/*************************************************************************************** /***************************************************************************************
** Function name: readPixelValue ** Function name: readPixelValue
** Description: Read the color map index of a pixel at defined coordinates ** Description: Read the color map index of a pixel at defined coordinates
*************************************************************************************x*/ ***************************************************************************************/
uint16_t TFT_eSprite::readPixelValue(int32_t x, int32_t y) uint16_t TFT_eSprite::readPixelValue(int32_t x, int32_t y)
{ {
if ((x < 0) || (x >= _iwidth) || (y < 0) || (y >= _iheight) || !_created) return 0xFF; if ((x < 0) || (x >= _iwidth) || (y < 0) || (y >= _iheight) || !_created) return 0xFF;
@@ -732,6 +911,7 @@ uint16_t TFT_eSprite::readPixelValue(int32_t x, int32_t y)
if (_bpp == 4) if (_bpp == 4)
{ {
if (x >= _dwidth) return 0xFF;
if ((x & 0x01) == 0) if ((x & 0x01) == 0)
return _img4[((x+y*_iwidth)>>1)] >> 4; // even index = bits 7 .. 4 return _img4[((x+y*_iwidth)>>1)] >> 4; // even index = bits 7 .. 4
else else
@@ -740,6 +920,7 @@ uint16_t TFT_eSprite::readPixelValue(int32_t x, int32_t y)
if (_bpp == 1) if (_bpp == 1)
{ {
// Note: _dwidth and _dheight bounds not checked (rounded up -iwidth and _iheight used)
if (_rotation == 1) if (_rotation == 1)
{ {
uint16_t tx = x; uint16_t tx = x;
@@ -767,7 +948,7 @@ uint16_t TFT_eSprite::readPixelValue(int32_t x, int32_t y)
/*************************************************************************************** /***************************************************************************************
** Function name: readPixel ** Function name: readPixel
** Description: Read 565 colour of a pixel at defined coordinates ** Description: Read 565 colour of a pixel at defined coordinates
*************************************************************************************x*/ ***************************************************************************************/
uint16_t TFT_eSprite::readPixel(int32_t x, int32_t y) uint16_t TFT_eSprite::readPixel(int32_t x, int32_t y)
{ {
if ((x < 0) || (x >= _iwidth) || (y < 0) || (y >= _iheight) || !_created) return 0xFFFF; if ((x < 0) || (x >= _iwidth) || (y < 0) || (y >= _iheight) || !_created) return 0xFFFF;
@@ -777,7 +958,7 @@ uint16_t TFT_eSprite::readPixel(int32_t x, int32_t y)
uint16_t color = _img[x + y * _iwidth]; uint16_t color = _img[x + y * _iwidth];
return (color >> 8) | (color << 8); return (color >> 8) | (color << 8);
} }
if (_bpp == 8) if (_bpp == 8)
{ {
uint16_t color = _img8[x + y * _iwidth]; uint16_t color = _img8[x + y * _iwidth];
@@ -793,6 +974,7 @@ uint16_t TFT_eSprite::readPixel(int32_t x, int32_t y)
if (_bpp == 4) if (_bpp == 4)
{ {
if (x >= _dwidth) return 0xFFFF;
uint16_t color; uint16_t color;
if ((x & 0x01) == 0) if ((x & 0x01) == 0)
color = _colorMap[_img4[((x+y*_iwidth)>>1)] >> 4]; // even index = bits 7 .. 4 color = _colorMap[_img4[((x+y*_iwidth)>>1)] >> 4]; // even index = bits 7 .. 4
@@ -801,6 +983,8 @@ uint16_t TFT_eSprite::readPixel(int32_t x, int32_t y)
return color; return color;
} }
// Note: Must be 1bpp
// _dwidth and _dheight bounds not checked (rounded up -iwidth and _iheight used)
if (_rotation == 1) if (_rotation == 1)
{ {
uint16_t tx = x; uint16_t tx = x;
@@ -828,18 +1012,19 @@ uint16_t TFT_eSprite::readPixel(int32_t x, int32_t y)
/*************************************************************************************** /***************************************************************************************
** Function name: pushImage ** Function name: pushImage
** Description: push 565 colour image into a defined area of a sprite ** Description: push image into a defined area of a sprite
*************************************************************************************x*/ ***************************************************************************************/
void TFT_eSprite::pushImage(int32_t x, int32_t y, int32_t w, int32_t h, uint16_t *data) void TFT_eSprite::pushImage(int32_t x, int32_t y, int32_t w, int32_t h, uint16_t *data)
{ {
if ((x >= _iwidth) || (y >= _iheight) || (w == 0) || (h == 0) || !_created) return; if (data == nullptr || !_created) return;
if ((x >= _iwidth) || (y >= _iheight) || (w == 0) || (h == 0)) return;
if ((x + w < 0) || (y + h < 0)) return; if ((x + w < 0) || (y + h < 0)) return;
int32_t xo = 0; int32_t xo = 0;
int32_t yo = 0; int32_t yo = 0;
int32_t xs = x; int32_t xs = x;
int32_t ys = y; int32_t ys = y;
int32_t ws = w; int32_t ws = w;
int32_t hs = h; int32_t hs = h;
@@ -852,17 +1037,34 @@ void TFT_eSprite::pushImage(int32_t x, int32_t y, int32_t w, int32_t h, uint16_
if (_bpp == 16) // Plot a 16 bpp image into a 16 bpp Sprite if (_bpp == 16) // Plot a 16 bpp image into a 16 bpp Sprite
{ {
for (int32_t yp = yo; yp < yo + hs; yp++) // Pointer within original image
uint8_t *ptro = (uint8_t *)data + ((xo + yo * w) << 1);
// Pointer within sprite image
uint8_t *ptrs = (uint8_t *)_img + ((xs + ys * _iwidth) << 1);
if(_iswapBytes)
{ {
x = xs; while (hs--)
for (int32_t xp = xo; xp < xo + ws; xp++)
{ {
uint16_t color = data[xp + yp * w]; // Fast copy with a 1 byte shift
if(_iswapBytes) color = color<<8 | color>>8; memcpy(ptrs+1, ptro, (ws<<1) - 1);
_img[x + ys * _iwidth] = color; // Now correct just the even numbered bytes
x++; for (int32_t xp = 0; xp < (ws<<1); xp+=2)
{
ptrs[xp] = ptro[xp+1];;
}
ptro += w<<1;
ptrs += _iwidth<<1;
}
}
else
{
while (hs--)
{
memcpy(ptrs, ptro, ws<<1);
ptro += w << 1;
ptrs += _iwidth << 1;
} }
ys++;
} }
} }
else if (_bpp == 8) // Plot a 16 bpp image into a 8 bpp Sprite else if (_bpp == 8) // Plot a 16 bpp image into a 8 bpp Sprite
@@ -873,8 +1075,9 @@ void TFT_eSprite::pushImage(int32_t x, int32_t y, int32_t w, int32_t h, uint16_
for (int32_t xp = xo; xp < xo + ws; xp++) for (int32_t xp = xo; xp < xo + ws; xp++)
{ {
uint16_t color = data[xp + yp * w]; uint16_t color = data[xp + yp * w];
if(_iswapBytes) color = color<<8 | color>>8; // When data source is a sprite, the bytes are already swapped
_img8[x + ys * _iwidth] = (uint8_t)((color & 0xE000)>>8 | (color & 0x0700)>>6 | (color & 0x0018)>>3); if(!_iswapBytes) _img8[x + ys * _iwidth] = (uint8_t)((color & 0xE0) | (color & 0x07)<<2 | (color & 0x1800)>>11);
else _img8[x + ys * _iwidth] = (uint8_t)((color & 0xE000)>>8 | (color & 0x0700)>>6 | (color & 0x0018)>>3);
x++; x++;
} }
ys++; ys++;
@@ -882,13 +1085,13 @@ void TFT_eSprite::pushImage(int32_t x, int32_t y, int32_t w, int32_t h, uint16_
} }
else if (_bpp == 4) else if (_bpp == 4)
{ {
// the image is assumed to be 4 bit, where each byte corresponds to two pixels. // The image is assumed to be 4 bit, where each byte corresponds to two pixels.
// much faster when aligned to a byte boundary, because the alternative is slower, requiring // much faster when aligned to a byte boundary, because the alternative is slower, requiring
// tedious bit operations. // tedious bit operations.
const uint8_t *dataBuf = (uint8_t *)data; const uint8_t *dataBuf = (uint8_t *)data;
int sWidth = (_iwidth >> 1); int sWidth = (_iwidth >> 1);
if ((xs & 0x01) == 0 && (xo & 0x01) == 0 && (ws & 0x01) == 0) if ((xs & 0x01) == 0 && (xo & 0x01) == 0 && (ws & 0x01) == 0)
{ {
if ((ws & 0x01) == 0) // use memcpy for better perf. if ((ws & 0x01) == 0) // use memcpy for better perf.
@@ -906,6 +1109,7 @@ void TFT_eSprite::pushImage(int32_t x, int32_t y, int32_t w, int32_t h, uint16_
} }
else // not optimized else // not optimized
{ {
// _dwidth and _dheight bounds not checked (rounded up -iwidth and _iheight used)
for (int32_t yp = yo; yp < yo + hs; yp++) for (int32_t yp = yo; yp < yo + hs; yp++)
{ {
x = xs; x = xs;
@@ -917,7 +1121,7 @@ void TFT_eSprite::pushImage(int32_t x, int32_t y, int32_t w, int32_t h, uint16_
else else
color = dataBuf[((xp-1+yp*w)>>1)] & 0x0F; // odd index = bits 3 .. 0. color = dataBuf[((xp-1+yp*w)>>1)] & 0x0F; // odd index = bits 3 .. 0.
drawPixel(x, ys, color); drawPixel(x, ys, color);
x++; x++;
} }
ys++; ys++;
} }
@@ -964,7 +1168,7 @@ void TFT_eSprite::pushImage(int32_t x, int32_t y, int32_t w, int32_t h, uint16_
/*************************************************************************************** /***************************************************************************************
** Function name: pushImage ** Function name: pushImage
** Description: push 565 colour FLASH (PROGMEM) image into a defined area ** Description: push 565 colour FLASH (PROGMEM) image into a defined area
*************************************************************************************x*/ ***************************************************************************************/
void TFT_eSprite::pushImage(int32_t x, int32_t y, int32_t w, int32_t h, const uint16_t *data) void TFT_eSprite::pushImage(int32_t x, int32_t y, int32_t w, int32_t h, const uint16_t *data)
{ {
#ifdef ESP32 #ifdef ESP32
@@ -1031,6 +1235,7 @@ void TFT_eSprite::pushImage(int32_t x, int32_t y, int32_t w, int32_t h, const u
else // 1bpp else // 1bpp
{ {
// _dwidth and _dheight bounds not checked (rounded up -iwidth and _iheight used)
// Move coordinate rotation to support fn // Move coordinate rotation to support fn
if (_rotation == 1) if (_rotation == 1)
{ {
@@ -1090,26 +1295,26 @@ bool TFT_eSprite::getSwapBytes(void)
/*************************************************************************************** /***************************************************************************************
** Function name: setWindow ** Function name: setWindow
** Description: Set the bounds of a window for pushColor and writeColor ** Description: Set the bounds of a window in the sprite
*************************************************************************************x*/ ***************************************************************************************/
void TFT_eSprite::setWindow(int32_t x0, int32_t y0, int32_t x1, int32_t y1) void TFT_eSprite::setWindow(int32_t x0, int32_t y0, int32_t x1, int32_t y1)
{ {
if (x0 > x1) swap_coord(x0, x1); if (x0 > x1) swap_coord(x0, x1);
if (y0 > y1) swap_coord(y0, y1); if (y0 > y1) swap_coord(y0, y1);
if ((x0 >= _iwidth) || (x1 < 0) || (y0 >= _iheight) || (y1 < 0)) if ((x0 >= _dwidth) || (x1 < 0) || (y0 >= _dheight) || (y1 < 0))
{ // Point to that extra "off screen" pixel { // Point to that extra "off screen" pixel
_xs = 0; _xs = 0;
_ys = _iheight; _ys = _dheight;
_xe = 0; _xe = 0;
_ye = _iheight; _ye = _dheight;
} }
else else
{ {
if (x0 < 0) x0 = 0; if (x0 < 0) x0 = 0;
if (x1 >= _iwidth) x1 = _iwidth - 1; if (x1 >= _dwidth) x1 = _dwidth - 1;
if (y0 < 0) y0 = 0; if (y0 < 0) y0 = 0;
if (y1 >= _iheight) y1 = _iheight - 1; if (y1 >= _dheight) y1 = _dheight - 1;
_xs = x0; _xs = x0;
_ys = y0; _ys = y0;
@@ -1125,7 +1330,7 @@ void TFT_eSprite::setWindow(int32_t x0, int32_t y0, int32_t x1, int32_t y1)
/*************************************************************************************** /***************************************************************************************
** Function name: pushColor ** Function name: pushColor
** Description: Send a new pixel to the set window ** Description: Send a new pixel to the set window
*************************************************************************************x*/ ***************************************************************************************/
void TFT_eSprite::pushColor(uint32_t color) void TFT_eSprite::pushColor(uint32_t color)
{ {
if (!_created ) return; if (!_created ) return;
@@ -1147,7 +1352,7 @@ void TFT_eSprite::pushColor(uint32_t color)
_img4[(_xptr + _yptr * _iwidth)>>1] = (_img4[(_xptr + _yptr * _iwidth)>>1] & 0xF0) | c; // new color is the low bits _img4[(_xptr + _yptr * _iwidth)>>1] = (_img4[(_xptr + _yptr * _iwidth)>>1] & 0xF0) | c; // new color is the low bits
} }
} }
else drawPixel(_xptr, _yptr, color); else drawPixel(_xptr, _yptr, color);
// Increment x // Increment x
@@ -1167,7 +1372,7 @@ void TFT_eSprite::pushColor(uint32_t color)
/*************************************************************************************** /***************************************************************************************
** Function name: pushColor ** Function name: pushColor
** Description: Send a "len" new pixels to the set window ** Description: Send a "len" new pixels to the set window
*************************************************************************************x*/ ***************************************************************************************/
void TFT_eSprite::pushColor(uint32_t color, uint16_t len) void TFT_eSprite::pushColor(uint32_t color, uint16_t len)
{ {
if (!_created ) return; if (!_created ) return;
@@ -1189,7 +1394,7 @@ void TFT_eSprite::pushColor(uint32_t color, uint16_t len)
/*************************************************************************************** /***************************************************************************************
** Function name: writeColor ** Function name: writeColor
** Description: Write a pixel with pre-formatted colour to the set window ** Description: Write a pixel with pre-formatted colour to the set window
*************************************************************************************x*/ ***************************************************************************************/
void TFT_eSprite::writeColor(uint16_t color) void TFT_eSprite::writeColor(uint16_t color)
{ {
if (!_created ) return; if (!_created ) return;
@@ -1227,7 +1432,7 @@ void TFT_eSprite::writeColor(uint16_t color)
/*************************************************************************************** /***************************************************************************************
** Function name: setScrollRect ** Function name: setScrollRect
** Description: Set scroll area within the sprite and the gap fill colour ** Description: Set scroll area within the sprite and the gap fill colour
*************************************************************************************x*/ ***************************************************************************************/
void TFT_eSprite::setScrollRect(int32_t x, int32_t y, int32_t w, int32_t h, uint16_t color) void TFT_eSprite::setScrollRect(int32_t x, int32_t y, int32_t w, int32_t h, uint16_t color)
{ {
if ((x >= _iwidth) || (y >= _iheight) || !_created ) return; if ((x >= _iwidth) || (y >= _iheight) || !_created ) return;
@@ -1238,7 +1443,7 @@ void TFT_eSprite::setScrollRect(int32_t x, int32_t y, int32_t w, int32_t h, uint
if ((x + w) > _iwidth ) w = _iwidth - x; if ((x + w) > _iwidth ) w = _iwidth - x;
if ((y + h) > _iheight) h = _iheight - y; if ((y + h) > _iheight) h = _iheight - y;
if ( w < 1 || h < 1) return; if ( w < 1 || h < 1) return;
_sx = x; _sx = x;
_sy = y; _sy = y;
@@ -1252,7 +1457,7 @@ void TFT_eSprite::setScrollRect(int32_t x, int32_t y, int32_t w, int32_t h, uint
/*************************************************************************************** /***************************************************************************************
** Function name: scroll ** Function name: scroll
** Description: Scroll dx,dy pixels, positive right,down, negative left,up ** Description: Scroll dx,dy pixels, positive right,down, negative left,up
*************************************************************************************x*/ ***************************************************************************************/
void TFT_eSprite::scroll(int16_t dx, int16_t dy) void TFT_eSprite::scroll(int16_t dx, int16_t dy)
{ {
if (abs(dx) >= _sw || abs(dy) >= _sh) if (abs(dx) >= _sw || abs(dy) >= _sh)
@@ -1264,7 +1469,7 @@ void TFT_eSprite::scroll(int16_t dx, int16_t dy)
// Fetch the scroll area width and height set by setScrollRect() // Fetch the scroll area width and height set by setScrollRect()
uint32_t w = _sw - abs(dx); // line width to copy uint32_t w = _sw - abs(dx); // line width to copy
uint32_t h = _sh - abs(dy); // lines to copy uint32_t h = _sh - abs(dy); // lines to copy
int32_t iw = _iwidth; // width of sprite int32_t iw = _iwidth; // rounded up width of sprite
// Fetch the x,y origin set by setScrollRect() // Fetch the x,y origin set by setScrollRect()
uint32_t tx = _sx; // to x uint32_t tx = _sx; // to x
@@ -1350,7 +1555,7 @@ void TFT_eSprite::scroll(int16_t dx, int16_t dy)
/*************************************************************************************** /***************************************************************************************
** Function name: fillSprite ** Function name: fillSprite
** Description: Fill the whole sprite with defined colour ** Description: Fill the whole sprite with defined colour
*************************************************************************************x*/ ***************************************************************************************/
void TFT_eSprite::fillSprite(uint32_t color) void TFT_eSprite::fillSprite(uint32_t color)
{ {
if (!_created ) return; if (!_created ) return;
@@ -1381,7 +1586,7 @@ void TFT_eSprite::fillSprite(uint32_t color)
/*************************************************************************************** /***************************************************************************************
** Function name: setCursor ** Function name: setCursor
** Description: Set the sprite text cursor x,y position ** Description: Set the sprite text cursor x,y position
*************************************************************************************x*/ ***************************************************************************************/
// Not needed - using TFT_eSPI class function and this->cursor_x/y // Not needed - using TFT_eSPI class function and this->cursor_x/y
//void TFT_eSprite::setCursor(int16_t x, int16_t y) //void TFT_eSprite::setCursor(int16_t x, int16_t y)
//{ //{
@@ -1393,13 +1598,13 @@ void TFT_eSprite::fillSprite(uint32_t color)
/*************************************************************************************** /***************************************************************************************
** Function name: width ** Function name: width
** Description: Return the width of sprite ** Description: Return the width of sprite
*************************************************************************************x*/ ***************************************************************************************/
// Return the size of the display // Return the size of the display
int16_t TFT_eSprite::width(void) int16_t TFT_eSprite::width(void)
{ {
if (!_created ) return 0; if (!_created ) return 0;
if (_bpp > 1) return _iwidth; if (_bpp > 1) return _dwidth;
if (_rotation == 1 || _rotation == 3) return _dheight; if (_rotation == 1 || _rotation == 3) return _dheight;
@@ -1410,12 +1615,12 @@ int16_t TFT_eSprite::width(void)
/*************************************************************************************** /***************************************************************************************
** Function name: height ** Function name: height
** Description: Return the height of sprite ** Description: Return the height of sprite
*************************************************************************************x*/ ***************************************************************************************/
int16_t TFT_eSprite::height(void) int16_t TFT_eSprite::height(void)
{ {
if (!_created ) return 0; if (!_created ) return 0;
if (_bpp > 1) return _iheight; if (_bpp > 4) return _dheight;
if (_rotation == 1 || _rotation == 3) return _dwidth; if (_rotation == 1 || _rotation == 3) return _dwidth;
@@ -1426,7 +1631,7 @@ int16_t TFT_eSprite::height(void)
/*************************************************************************************** /***************************************************************************************
** Function name: setRotation ** Function name: setRotation
** Description: Rotate coordinate frame for 1bpp sprite ** Description: Rotate coordinate frame for 1bpp sprite
*************************************************************************************x*/ ***************************************************************************************/
// Does nothing for 8 and 16 bpp sprites. TODO allow rotation of these sprites // Does nothing for 8 and 16 bpp sprites. TODO allow rotation of these sprites
void TFT_eSprite::setRotation(uint8_t rotation) void TFT_eSprite::setRotation(uint8_t rotation)
{ {
@@ -1443,7 +1648,7 @@ void TFT_eSprite::setRotation(uint8_t rotation)
/*************************************************************************************** /***************************************************************************************
** Function name: getRotation ** Function name: getRotation
** Description: Get rotation for 1bpp sprite ** Description: Get rotation for 1bpp sprite
*************************************************************************************x*/ ***************************************************************************************/
uint8_t TFT_eSprite::getRotation(void) uint8_t TFT_eSprite::getRotation(void)
{ {
@@ -1454,7 +1659,7 @@ uint8_t TFT_eSprite::getRotation(void)
/*************************************************************************************** /***************************************************************************************
** Function name: drawPixel ** Function name: drawPixel
** Description: push a single pixel at an arbitrary position ** Description: push a single pixel at an arbitrary position
*************************************************************************************x*/ ***************************************************************************************/
void TFT_eSprite::drawPixel(int32_t x, int32_t y, uint32_t color) void TFT_eSprite::drawPixel(int32_t x, int32_t y, uint32_t color)
{ {
// Range checking // Range checking
@@ -1510,7 +1715,7 @@ void TFT_eSprite::drawPixel(int32_t x, int32_t y, uint32_t color)
/*************************************************************************************** /***************************************************************************************
** Function name: drawLine ** Function name: drawLine
** Description: draw a line between 2 arbitrary points ** Description: draw a line between 2 arbitrary points
*************************************************************************************x*/ ***************************************************************************************/
void TFT_eSprite::drawLine(int32_t x0, int32_t y0, int32_t x1, int32_t y1, uint32_t color) void TFT_eSprite::drawLine(int32_t x0, int32_t y0, int32_t x1, int32_t y1, uint32_t color)
{ {
if (!_created ) return; if (!_created ) return;
@@ -1566,7 +1771,7 @@ void TFT_eSprite::drawLine(int32_t x0, int32_t y0, int32_t x1, int32_t y1, uint3
/*************************************************************************************** /***************************************************************************************
** Function name: drawFastVLine ** Function name: drawFastVLine
** Description: draw a vertical line ** Description: draw a vertical line
*************************************************************************************x*/ ***************************************************************************************/
void TFT_eSprite::drawFastVLine(int32_t x, int32_t y, int32_t h, uint32_t color) void TFT_eSprite::drawFastVLine(int32_t x, int32_t y, int32_t h, uint32_t color)
{ {
@@ -1621,7 +1826,7 @@ void TFT_eSprite::drawFastVLine(int32_t x, int32_t y, int32_t h, uint32_t color)
/*************************************************************************************** /***************************************************************************************
** Function name: drawFastHLine ** Function name: drawFastHLine
** Description: draw a horizontal line ** Description: draw a horizontal line
*************************************************************************************x*/ ***************************************************************************************/
void TFT_eSprite::drawFastHLine(int32_t x, int32_t y, int32_t w, uint32_t color) void TFT_eSprite::drawFastHLine(int32_t x, int32_t y, int32_t w, uint32_t color)
{ {
@@ -1677,13 +1882,13 @@ void TFT_eSprite::drawFastHLine(int32_t x, int32_t y, int32_t w, uint32_t color)
/*************************************************************************************** /***************************************************************************************
** Function name: fillRect ** Function name: fillRect
** Description: draw a filled rectangle ** Description: draw a filled rectangle
*************************************************************************************x*/ ***************************************************************************************/
void TFT_eSprite::fillRect(int32_t x, int32_t y, int32_t w, int32_t h, uint32_t color) void TFT_eSprite::fillRect(int32_t x, int32_t y, int32_t w, int32_t h, uint32_t color)
{ {
if (!_created ) return; if (!_created ) return;
if ((x >= _iwidth) || (y >= _iheight)) return; if ((x >= _iwidth) || (y >= _iheight)) return;
if (x < 0) { w += x; x = 0; } if (x < 0) { w += x; x = 0; }
if (y < 0) { h += y; y = 0; } if (y < 0) { h += y; y = 0; }
@@ -1782,7 +1987,7 @@ void TFT_eSprite::fillRect(int32_t x, int32_t y, int32_t w, int32_t h, uint32_t
/*************************************************************************************** /***************************************************************************************
** Function name: write ** Function name: write
** Description: draw characters piped through serial stream ** Description: draw characters piped through serial stream
*************************************************************************************x*/ ***************************************************************************************/
size_t TFT_eSprite::write(uint8_t utf8) size_t TFT_eSprite::write(uint8_t utf8)
{ {
uint16_t uniCode = decodeUTF8(utf8); uint16_t uniCode = decodeUTF8(utf8);
@@ -1864,7 +2069,7 @@ size_t TFT_eSprite::write(uint8_t utf8)
height = height * textsize; height = height * textsize;
if (utf8 == '\n') if (utf8 == '\n')
{ {
this->cursor_y += height; this->cursor_y += height;
this->cursor_x = 0; this->cursor_x = 0;
@@ -1919,7 +2124,7 @@ size_t TFT_eSprite::write(uint8_t utf8)
/*************************************************************************************** /***************************************************************************************
** Function name: drawChar ** Function name: drawChar
** Description: draw a single character in the Adafruit GLCD or freefont ** Description: draw a single character in the Adafruit GLCD or freefont
*************************************************************************************x*/ ***************************************************************************************/
void TFT_eSprite::drawChar(int32_t x, int32_t y, uint16_t c, uint32_t color, uint32_t bg, uint8_t size) void TFT_eSprite::drawChar(int32_t x, int32_t y, uint16_t c, uint32_t color, uint32_t bg, uint8_t size)
{ {
if (!_created ) return; if (!_created ) return;
@@ -2061,7 +2266,7 @@ void TFT_eSprite::drawChar(int32_t x, int32_t y, uint16_t c, uint32_t color, uin
/*************************************************************************************** /***************************************************************************************
** Function name: drawChar ** Function name: drawChar
** Description: draw a unicode onto the screen ** Description: draw a unicode onto the screen
*************************************************************************************x*/ ***************************************************************************************/
// Any UTF-8 decoding must be done before calling drawChar() // Any UTF-8 decoding must be done before calling drawChar()
int16_t TFT_eSprite::drawChar(uint16_t uniCode, int32_t x, int32_t y) int16_t TFT_eSprite::drawChar(uint16_t uniCode, int32_t x, int32_t y)
{ {
@@ -2258,7 +2463,7 @@ int16_t TFT_eSprite::drawChar(uint16_t uniCode, int32_t x, int32_t y, uint8_t fo
/*************************************************************************************** /***************************************************************************************
** Function name: drawGlyph ** Function name: drawGlyph
** Description: Write a character to the sprite cursor position ** Description: Write a character to the sprite cursor position
*************************************************************************************x*/ ***************************************************************************************/
void TFT_eSprite::drawGlyph(uint16_t code) void TFT_eSprite::drawGlyph(uint16_t code)
{ {
if (code < 0x21) if (code < 0x21)
@@ -2289,15 +2494,15 @@ void TFT_eSprite::drawGlyph(uint16_t code)
uint16_t gNum = 0; uint16_t gNum = 0;
bool found = this->getUnicodeIndex(code, &gNum); bool found = this->getUnicodeIndex(code, &gNum);
uint16_t fg = this->textcolor; uint16_t fg = this->textcolor;
uint16_t bg = this->textbgcolor; uint16_t bg = this->textbgcolor;
if (found) if (found)
{ {
bool newSprite = !_created; bool newSprite = !_created;
if (newSprite) if (newSprite)
{ {
createSprite(this->gWidth[gNum], this->gFont.yAdvance); createSprite(this->gWidth[gNum], this->gFont.yAdvance);
@@ -2393,7 +2598,7 @@ void TFT_eSprite::drawGlyph(uint16_t code)
/*************************************************************************************** /***************************************************************************************
** Function name: printToSprite ** Function name: printToSprite
** Description: Write a string to the sprite cursor position ** Description: Write a string to the sprite cursor position
*************************************************************************************x*/ ***************************************************************************************/
void TFT_eSprite::printToSprite(String string) void TFT_eSprite::printToSprite(String string)
{ {
if(!this->fontLoaded) return; if(!this->fontLoaded) return;
@@ -2408,14 +2613,14 @@ void TFT_eSprite::printToSprite(String string)
/*************************************************************************************** /***************************************************************************************
** Function name: printToSprite ** Function name: printToSprite
** Description: Write a string to the sprite cursor position ** Description: Write a string to the sprite cursor position
*************************************************************************************x*/ ***************************************************************************************/
void TFT_eSprite::printToSprite(char *cbuffer, uint16_t len) //String string) void TFT_eSprite::printToSprite(char *cbuffer, uint16_t len) //String string)
{ {
if(!this->fontLoaded) return; if(!this->fontLoaded) return;
uint16_t n = 0; uint16_t n = 0;
bool newSprite = !_created; bool newSprite = !_created;
if (newSprite) if (newSprite)
{ {
int16_t sWidth = 1; int16_t sWidth = 1;
@@ -2459,7 +2664,7 @@ void TFT_eSprite::printToSprite(char *cbuffer, uint16_t len) //String string)
/*************************************************************************************** /***************************************************************************************
** Function name: printToSprite ** Function name: printToSprite
** Description: Print character in a Sprite, create sprite if needed ** Description: Print character in a Sprite, create sprite if needed
*************************************************************************************x*/ ***************************************************************************************/
int16_t TFT_eSprite::printToSprite(int16_t x, int16_t y, uint16_t index) int16_t TFT_eSprite::printToSprite(int16_t x, int16_t y, uint16_t index)
{ {
bool newSprite = !_created; bool newSprite = !_created;

View File

@@ -10,6 +10,7 @@ class TFT_eSprite : public TFT_eSPI {
public: public:
TFT_eSprite(TFT_eSPI *tft); TFT_eSprite(TFT_eSPI *tft);
~TFT_eSprite(void);
// Create a sprite of width x height pixels, return a pointer to the RAM area // Create a sprite of width x height pixels, return a pointer to the RAM area
// Sketch can cast returned value to (uint16_t*) for 16 bit depth if needed // Sketch can cast returned value to (uint16_t*) for 16 bit depth if needed
@@ -18,9 +19,10 @@ class TFT_eSprite : public TFT_eSPI {
// - 1 nibble per pixel for 4 bit colour // - 1 nibble per pixel for 4 bit colour
// - 1 byte per pixel for 8 bit colour // - 1 byte per pixel for 8 bit colour
// - 2 bytes per pixel for 16 bit color depth // - 2 bytes per pixel for 16 bit color depth
~TFT_eSprite(void); void* createSprite(int16_t width, int16_t height, uint8_t frames = 1);
void* createSprite(int16_t width, int16_t height, uint8_t frames = 1); // Returns a pointer to the sprite or nullptr if not created, user must cast to pointer type
void* getPointer(void);
// Returns true if sprite has been created // Returns true if sprite has been created
bool created(void); bool created(void);
@@ -131,6 +133,13 @@ class TFT_eSprite : public TFT_eSPI {
void pushSprite(int32_t x, int32_t y); void pushSprite(int32_t x, int32_t y);
void pushSprite(int32_t x, int32_t y, uint16_t transparent); void pushSprite(int32_t x, int32_t y, uint16_t transparent);
// Push the sprite to another sprite, this fn calls pushImage() in the destination sprite class.
// >>>>>> Using a transparent color is not supported at the moment <<<<<<
bool pushSprite(TFT_eSprite *spr, int32_t x, int32_t y);
// Push a windowed area of the sprite to the TFT at tx, ty
bool pushSprite(int32_t tx, int32_t ty, int32_t sx, int32_t sy, int32_t sw, int32_t sh);
int16_t drawChar(uint16_t uniCode, int32_t x, int32_t y, uint8_t font), int16_t drawChar(uint16_t uniCode, int32_t x, int32_t y, uint8_t font),
drawChar(uint16_t uniCode, int32_t x, int32_t y); drawChar(uint16_t uniCode, int32_t x, int32_t y);

View File

@@ -489,7 +489,7 @@ void TFT_eSPI::pushPixels(const void* data_in, uint32_t len){
//////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////
#if defined ESP32_DMA && !defined (TFT_PARALLEL_8_BIT) // DMA FUNCTIONS #if defined (ESP32_DMA) && !defined (TFT_PARALLEL_8_BIT) // DMA FUNCTIONS
//////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////
/*************************************************************************************** /***************************************************************************************

View File

@@ -77,10 +77,16 @@
#define DC_D // No macro allocated so it generates no code #define DC_D // No macro allocated so it generates no code
#else #else
#if defined (TFT_PARALLEL_8_BIT) #if defined (TFT_PARALLEL_8_BIT)
#define DC_C GPIO.out_w1tc = (1 << TFT_DC) // TFT_DC, by design, must be in range 0-31 for single register parallel write
#define DC_D GPIO.out_w1ts = (1 << TFT_DC) #if (TFT_DC >= 0) && (TFT_DC < 32)
#define DC_C GPIO.out_w1tc = (1 << TFT_DC)
#define DC_D GPIO.out_w1ts = (1 << TFT_DC)
#else
#define DC_C
#define DC_D
#endif
#else #else
#if TFT_DC >= 32 #if (TFT_DC >= 32)
#ifdef RPI_DISPLAY_TYPE // RPi displays need a slower DC change #ifdef RPI_DISPLAY_TYPE // RPi displays need a slower DC change
#define DC_C GPIO.out1_w1ts.val = (1 << (TFT_DC - 32)); \ #define DC_C GPIO.out1_w1ts.val = (1 << (TFT_DC - 32)); \
GPIO.out1_w1tc.val = (1 << (TFT_DC - 32)) GPIO.out1_w1tc.val = (1 << (TFT_DC - 32))
@@ -90,16 +96,20 @@
#define DC_C GPIO.out1_w1tc.val = (1 << (TFT_DC - 32))//;GPIO.out1_w1tc.val = (1 << (TFT_DC - 32)) #define DC_C GPIO.out1_w1tc.val = (1 << (TFT_DC - 32))//;GPIO.out1_w1tc.val = (1 << (TFT_DC - 32))
#define DC_D GPIO.out1_w1ts.val = (1 << (TFT_DC - 32))//;GPIO.out1_w1ts.val = (1 << (TFT_DC - 32)) #define DC_D GPIO.out1_w1ts.val = (1 << (TFT_DC - 32))//;GPIO.out1_w1ts.val = (1 << (TFT_DC - 32))
#endif #endif
#elif TFT_DC >= 0 #elif (TFT_DC >= 0)
#ifdef RPI_DISPLAY_TYPE // RPi ILI9486 display needs a slower DC change #if defined (RPI_DISPLAY_TYPE)
#define DC_C GPIO.out_w1tc = (1 << TFT_DC); \ #if defined (ILI9486_DRIVER)
GPIO.out_w1tc = (1 << TFT_DC) // RPi ILI9486 display needs a slower DC change
#define DC_D GPIO.out_w1tc = (1 << TFT_DC); \ #define DC_C GPIO.out_w1tc = (1 << TFT_DC); \
GPIO.out_w1ts = (1 << TFT_DC) GPIO.out_w1tc = (1 << TFT_DC)
#elif defined (RPI_DISPLAY_TYPE) // Other RPi displays need a slower C->D change #define DC_D GPIO.out_w1tc = (1 << TFT_DC); \
#define DC_C GPIO.out_w1tc = (1 << TFT_DC) GPIO.out_w1ts = (1 << TFT_DC)
#define DC_D GPIO.out_w1tc = (1 << TFT_DC); \ #else
GPIO.out_w1ts = (1 << TFT_DC) // Other RPi displays need a slower C->D change
#define DC_C GPIO.out_w1tc = (1 << TFT_DC)
#define DC_D GPIO.out_w1tc = (1 << TFT_DC); \
GPIO.out_w1ts = (1 << TFT_DC)
#endif
#else #else
#define DC_C GPIO.out_w1tc = (1 << TFT_DC)//;GPIO.out_w1tc = (1 << TFT_DC) #define DC_C GPIO.out_w1tc = (1 << TFT_DC)//;GPIO.out_w1tc = (1 << TFT_DC)
#define DC_D GPIO.out_w1ts = (1 << TFT_DC)//;GPIO.out_w1ts = (1 << TFT_DC) #define DC_D GPIO.out_w1ts = (1 << TFT_DC)//;GPIO.out_w1ts = (1 << TFT_DC)
@@ -131,8 +141,8 @@
#define CS_H #define CS_H
#endif #endif
#else #else
#if TFT_CS >= 32 #if (TFT_CS >= 32)
#ifdef RPI_DISPLAY_TYPE // RPi ILI9486 display needs a slower CS change #ifdef RPI_DISPLAY_TYPE // RPi display needs a slower CS change
#define CS_L GPIO.out1_w1ts.val = (1 << (TFT_CS - 32)); \ #define CS_L GPIO.out1_w1ts.val = (1 << (TFT_CS - 32)); \
GPIO.out1_w1tc.val = (1 << (TFT_CS - 32)) GPIO.out1_w1tc.val = (1 << (TFT_CS - 32))
#define CS_H GPIO.out1_w1tc.val = (1 << (TFT_CS - 32)); \ #define CS_H GPIO.out1_w1tc.val = (1 << (TFT_CS - 32)); \
@@ -141,12 +151,12 @@
#define CS_L GPIO.out1_w1tc.val = (1 << (TFT_CS - 32)); GPIO.out1_w1tc.val = (1 << (TFT_CS - 32)) #define CS_L GPIO.out1_w1tc.val = (1 << (TFT_CS - 32)); GPIO.out1_w1tc.val = (1 << (TFT_CS - 32))
#define CS_H GPIO.out1_w1ts.val = (1 << (TFT_CS - 32))//;GPIO.out1_w1ts.val = (1 << (TFT_CS - 32)) #define CS_H GPIO.out1_w1ts.val = (1 << (TFT_CS - 32))//;GPIO.out1_w1ts.val = (1 << (TFT_CS - 32))
#endif #endif
#elif TFT_CS >= 0 #elif (TFT_CS >= 0)
#ifdef RPI_DISPLAY_TYPE // RPi ILI9486 display needs a slower CS change #ifdef RPI_DISPLAY_TYPE // RPi display needs a slower CS change
#define CS_L GPIO.out_w1ts = (1 << TFT_CS); GPIO.out_w1tc = (1 << TFT_CS) #define CS_L GPIO.out_w1ts = (1 << TFT_CS); GPIO.out_w1tc = (1 << TFT_CS)
#define CS_H GPIO.out_w1tc = (1 << TFT_CS); GPIO.out_w1ts = (1 << TFT_CS) #define CS_H GPIO.out_w1tc = (1 << TFT_CS); GPIO.out_w1ts = (1 << TFT_CS)
#else #else
#define CS_L GPIO.out_w1tc = (1 << TFT_CS);GPIO.out_w1tc = (1 << TFT_CS) #define CS_L GPIO.out_w1tc = (1 << TFT_CS); GPIO.out_w1tc = (1 << TFT_CS)
#define CS_H GPIO.out_w1ts = (1 << TFT_CS)//;GPIO.out_w1ts = (1 << TFT_CS) #define CS_H GPIO.out_w1ts = (1 << TFT_CS)//;GPIO.out_w1ts = (1 << TFT_CS)
#endif #endif
#else #else
@@ -159,9 +169,18 @@
//////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////
// Define the WR (TFT Write) pin drive code // Define the WR (TFT Write) pin drive code
//////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////
#ifdef TFT_WR #if defined (TFT_WR)
#define WR_L GPIO.out_w1tc = (1 << TFT_WR) #if (TFT_WR >= 0)
#define WR_H GPIO.out_w1ts = (1 << TFT_WR) // TFT_WR, by design, must be in range 0-31 for single register parallel write
#define WR_L GPIO.out_w1tc = (1 << TFT_WR)
#define WR_H GPIO.out_w1ts = (1 << TFT_WR)
#else
#define WR_L
#define WR_H
#endif
#else
#define WR_L
#define WR_H
#endif #endif
//////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////
@@ -302,10 +321,18 @@
// Read pin // Read pin
#ifdef TFT_RD #ifdef TFT_RD
#define RD_L GPIO.out_w1tc = (1 << TFT_RD) #if (TFT_RD >= 32)
//#define RD_L digitalWrite(TFT_WR, LOW) #define RD_L GPIO.out1_w1tc.val = = (1 << (TFT_RD - 32))
#define RD_H GPIO.out_w1ts = (1 << TFT_RD) #define RD_H GPIO.out1_w1ts.val = = (1 << (TFT_RD - 32))
//#define RD_H digitalWrite(TFT_WR, HIGH) #elif (TFT_RD >= 0)
#define RD_L GPIO.out_w1tc = (1 << TFT_RD)
//#define RD_L digitalWrite(TFT_WR, LOW)
#define RD_H GPIO.out_w1ts = (1 << TFT_RD)
//#define RD_H digitalWrite(TFT_WR, HIGH)
#else
#define RD_L
#define RD_H
#endif
#endif #endif
//////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////

View File

@@ -304,7 +304,7 @@ return;
SPI1U1 = (511 << SPILMOSI); SPI1U1 = (511 << SPILMOSI);
while(len>31) while(len>31)
{ {
#if defined SPI_FREQUENCY && (SPI_FREQUENCY == 80000000) #if (defined (SPI_FREQUENCY) && (SPI_FREQUENCY == 80000000))
if(SPI1CMD & SPIBUSY) // added to sync with flag change if(SPI1CMD & SPIBUSY) // added to sync with flag change
#endif #endif
while(SPI1CMD & SPIBUSY) {} while(SPI1CMD & SPIBUSY) {}

View File

@@ -19,7 +19,7 @@
#define DMA_BUSY_CHECK // DMA not available, leave blank #define DMA_BUSY_CHECK // DMA not available, leave blank
// Initialise processor specific SPI functions, used by init() // Initialise processor specific SPI functions, used by init()
#if !defined (SUPPORT_TRANSACTIONS) && defined (ESP8266) #if (!defined (SUPPORT_TRANSACTIONS) && defined (ESP8266))
#define INIT_TFT_DATA_BUS \ #define INIT_TFT_DATA_BUS \
spi.setBitOrder(MSBFIRST); \ spi.setBitOrder(MSBFIRST); \
spi.setDataMode(TFT_SPI_MODE); \ spi.setDataMode(TFT_SPI_MODE); \

View File

@@ -58,6 +58,13 @@
#define CS_H digitalWrite(TFT_CS, HIGH) #define CS_H digitalWrite(TFT_CS, HIGH)
#endif #endif
////////////////////////////////////////////////////////////////////////////////////////
// Make sure TFT_RD is defined if not used to avoid an error message
////////////////////////////////////////////////////////////////////////////////////////
#ifndef TFT_RD
#define TFT_RD -1
#endif
//////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////
// Define the WR (TFT Write) pin drive code // Define the WR (TFT Write) pin drive code
//////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////

View File

@@ -131,7 +131,7 @@ void TFT_eSPI::pushPixels(const void* data_in, uint32_t len){
***************************************************************************************/ ***************************************************************************************/
void TFT_eSPI::busDir(uint32_t mask, uint8_t mode) void TFT_eSPI::busDir(uint32_t mask, uint8_t mode)
{ {
#ifdef STM_PORTA_DATA_BUS #if defined (STM_PORTA_DATA_BUS)
#if defined (STM32F1xx) #if defined (STM32F1xx)
if (mode == OUTPUT) GPIOA->CRL = 0x33333333; if (mode == OUTPUT) GPIOA->CRL = 0x33333333;
else GPIOA->CRL = 0x88888888; else GPIOA->CRL = 0x88888888;
@@ -139,7 +139,7 @@ void TFT_eSPI::busDir(uint32_t mask, uint8_t mode)
if (mode == OUTPUT) GPIOA->MODER = (GPIOA->MODER & 0xFFFF0000) | 0x00005555; if (mode == OUTPUT) GPIOA->MODER = (GPIOA->MODER & 0xFFFF0000) | 0x00005555;
else GPIOA->MODER &= 0xFFFF0000; else GPIOA->MODER &= 0xFFFF0000;
#endif #endif
#elif STM_PORTB_DATA_BUS #elif defined (STM_PORTB_DATA_BUS)
#if defined (STM32F1xx) #if defined (STM32F1xx)
if (mode == OUTPUT) GPIOB->CRL = 0x33333333; if (mode == OUTPUT) GPIOB->CRL = 0x33333333;
else GPIOB->CRL = 0x88888888; else GPIOB->CRL = 0x88888888;
@@ -194,12 +194,12 @@ uint8_t TFT_eSPI::readByte(void)
uint8_t b = 0; uint8_t b = 0;
RD_L; RD_L;
#ifdef STM_PORTA_DATA_BUS #if defined (STM_PORTA_DATA_BUS)
b = GPIOA->IDR; b = GPIOA->IDR;
b = GPIOA->IDR; b = GPIOA->IDR;
b = GPIOA->IDR; b = GPIOA->IDR;
b = (GPIOA->IDR) & 0xFF; b = (GPIOA->IDR) & 0xFF;
#elif STM_PORTB_DATA_BUS #elif defined (STM_PORTB_DATA_BUS)
b = GPIOB->IDR; b = GPIOB->IDR;
b = GPIOB->IDR; b = GPIOB->IDR;
b = GPIOB->IDR; b = GPIOB->IDR;

View File

@@ -243,12 +243,21 @@
// Define the RD (TFT Read) pin drive code // Define the RD (TFT Read) pin drive code
//////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////
#ifdef TFT_RD #ifdef TFT_RD
// Convert Arduino pin reference Dx or STM pin reference PXn to port and mask #if (TFT_RD >= 0)
#define RD_PORT digitalPinToPort(TFT_RD) // Convert Arduino pin reference Dx or STM pin reference PXn to port and mask
#define RD_PIN_MASK digitalPinToBitMask(TFT_RD) #define RD_PORT digitalPinToPort(TFT_RD)
// Use bit set reset register #define RD_PIN_MASK digitalPinToBitMask(TFT_RD)
#define RD_L RD_PORT->BSRR = RD_PIN_MASK<<16 // Use bit set reset register
#define RD_H RD_PORT->BSRR = RD_PIN_MASK #define RD_L RD_PORT->BSRR = RD_PIN_MASK<<16
#define RD_H RD_PORT->BSRR = RD_PIN_MASK
#else
#define RD_L
#define RD_H
#endif
#else
#define TFT_RD -1
#define RD_L
#define RD_H
#endif #endif
//////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////

View File

@@ -335,8 +335,6 @@ void TFT_eSPI::init(uint8_t tc)
} // end of: if just _booted } // end of: if just _booted
// Toggle RST low to reset // Toggle RST low to reset
begin_tft_write();
#ifdef TFT_RST #ifdef TFT_RST
if (TFT_RST >= 0) { if (TFT_RST >= 0) {
digitalWrite(TFT_RST, HIGH); digitalWrite(TFT_RST, HIGH);
@@ -350,8 +348,6 @@ void TFT_eSPI::init(uint8_t tc)
writecommand(TFT_SWRST); // Software reset writecommand(TFT_SWRST); // Software reset
#endif #endif
end_tft_write();
delay(150); // Wait for reset to complete delay(150); // Wait for reset to complete
begin_tft_write(); begin_tft_write();
@@ -946,6 +942,7 @@ void TFT_eSPI::pushImage(int32_t x, int32_t y, int32_t w, int32_t h, uint16_t *d
uint16_t lineBuf[dw]; // Use buffer to minimise setWindow call count uint16_t lineBuf[dw]; // Use buffer to minimise setWindow call count
// The little endian transp color must be byte swapped if the image is big endian
if (!_swapBytes) transp = transp >> 8 | transp << 8; if (!_swapBytes) transp = transp >> 8 | transp << 8;
while (dh--) while (dh--)
@@ -1062,6 +1059,7 @@ void TFT_eSPI::pushImage(int32_t x, int32_t y, int32_t w, int32_t h, const uint1
uint16_t lineBuf[dw]; uint16_t lineBuf[dw];
// The little endian transp color must be byte swapped if the image is big endian
if (!_swapBytes) transp = transp >> 8 | transp << 8; if (!_swapBytes) transp = transp >> 8 | transp << 8;
while (dh--) { while (dh--) {
@@ -1247,7 +1245,6 @@ void TFT_eSPI::pushImage(int32_t x, int32_t y, int32_t w, int32_t h, uint8_t *da
} }
pushPixels(lineBuf, dw); pushPixels(lineBuf, dw);
dy++; dy++;
} }
_swapBytes = swap; // Restore old value _swapBytes = swap; // Restore old value

View File

@@ -16,7 +16,7 @@
#ifndef _TFT_eSPIH_ #ifndef _TFT_eSPIH_
#define _TFT_eSPIH_ #define _TFT_eSPIH_
#define TFT_ESPI_VERSION "2.2.15" #define TFT_ESPI_VERSION "2.2.16"
/*************************************************************************************** /***************************************************************************************
** Section 1: Load required header files ** Section 1: Load required header files

View File

@@ -59,7 +59,7 @@
//#include <User_Setups/Setup29_ILI9341_STM32.h> // Setup for Nucleo board //#include <User_Setups/Setup29_ILI9341_STM32.h> // Setup for Nucleo board
//#include <User_Setups/Setup30_ILI9341_Parallel_STM32.h> // Setup for Nucleo board and parallel display //#include <User_Setups/Setup30_ILI9341_Parallel_STM32.h> // Setup for Nucleo board and parallel display
//#include <User_Setups/Setup31_ST7796_Parallel_STM32.h> // Setup for Nucleo board and parallel display //#include <User_Setups/Setup31_ST7796_Parallel_STM32.h> // Setup for Nucleo board and parallel display
//#include <User_Setups/Setup32_ILI9341_STM32F103.h> // Setup for "Blue Pill" //#include <User_Setups/Setup32_ILI9341_STM32F103.h> // Setup for "Blue Pill"
//#include <User_Setups/Setup33_RPi_ILI9486_STM32.h> // Setup for Nucleo board //#include <User_Setups/Setup33_RPi_ILI9486_STM32.h> // Setup for Nucleo board
@@ -69,8 +69,8 @@
//#include <User_Setups/Setup36_RPi_touch_ILI9341.h> // Setup file configured for ESP32 and RPi TFT with touch //#include <User_Setups/Setup36_RPi_touch_ILI9341.h> // Setup file configured for ESP32 and RPi TFT with touch
//#include <User_Setups/Setup43_ST7735.h> // Setup file configured for my ST7735S 80x160 //#include <User_Setups/Setup43_ST7735.h> // Setup file configured for my ST7735S 80x160
//#include <User_Setups/Setup44_TTGO_CameraPlus.h> // Setup file for ESP32 and TTGO T-CameraPlus ST7789 SPI bus TFT 240x240 //#include <User_Setups/Setup44_TTGO_CameraPlus.h> // Setup file for ESP32 and TTGO T-CameraPlus ST7789 SPI bus TFT 240x240
//#include <User_Setups/Setup45_TTGO_T_Watch.h> // Setup file for ESP32 and TTGO T-Watch ST7789 SPI bus TFT 240x240 //#include <User_Setups/Setup45_TTGO_T_Watch.h> // Setup file for ESP32 and TTGO T-Watch ST7789 SPI bus TFT 240x240
//#include <User_Setups/Setup135_ST7789.h> // Setup file for ESP8266 and ST7789 135 x 240 TFT //#include <User_Setups/Setup135_ST7789.h> // Setup file for ESP8266 and ST7789 135 x 240 TFT

View File

@@ -1,27 +1,34 @@
# TFT_eSPI core library
TFT_eSPI KEYWORD1 TFT_eSPI KEYWORD1
begin KEYWORD2
init KEYWORD2 init KEYWORD2
drawPixel KEYWORD2 drawPixel KEYWORD2
drawChar KEYWORD2 drawChar KEYWORD2
setAddrWindow KEYWORD2
setWindow KEYWORD2
startWrite KEYWORD2
writeColor KEYWORD2
endWrite KEYWORD2
pushColor KEYWORD2
pushColors KEYWORD2
fillScreen KEYWORD2
writeBegin KEYWORD2
writeEnd KEYWORD2
drawLine KEYWORD2 drawLine KEYWORD2
drawFastVLine KEYWORD2 drawFastVLine KEYWORD2
drawFastHLine KEYWORD2 drawFastHLine KEYWORD2
drawRect KEYWORD2
fillRect KEYWORD2 fillRect KEYWORD2
height KEYWORD2
width KEYWORD2
setRotation KEYWORD2
getRotation KEYWORD2
invertDisplay KEYWORD2
setAddrWindow KEYWORD2
setWindow KEYWORD2
pushColor KEYWORD2
pushColors KEYWORD2
pushBlock KEYWORD2
pushPixels KEYWORD2
readPixel KEYWORD2
tft_Read_8 KEYWORD2
begin_SDA_Read KEYWORD2
end_SDA_Read KEYWORD2
fillScreen KEYWORD2
drawRect KEYWORD2
drawRoundRect KEYWORD2 drawRoundRect KEYWORD2
fillRoundRect KEYWORD2 fillRoundRect KEYWORD2
setRotation KEYWORD2
invertDisplay KEYWORD2
drawCircle KEYWORD2 drawCircle KEYWORD2
drawCircleHelper KEYWORD2 drawCircleHelper KEYWORD2
fillCircle KEYWORD2 fillCircle KEYWORD2
@@ -30,18 +37,40 @@ drawEllipse KEYWORD2
fillEllipse KEYWORD2 fillEllipse KEYWORD2
drawTriangle KEYWORD2 drawTriangle KEYWORD2
fillTriangle KEYWORD2 fillTriangle KEYWORD2
setSwapBytes KEYWORD2
getSwapBytes KEYWORD2
drawBitmap KEYWORD2 drawBitmap KEYWORD2
drawXBitmap KEYWORD2 drawXBitmap KEYWORD2
setPivot KEYWORD2
getPivotX KEYWORD2
getPivotY KEYWORD2
readRect KEYWORD2
pushRect KEYWORD2
pushImage KEYWORD2
readRectRGB KEYWORD2
drawNumber KEYWORD2
drawFloat KEYWORD2
drawString KEYWORD2
drawCentreString KEYWORD2
drawRightString KEYWORD2
setCursor KEYWORD2 setCursor KEYWORD2
getCursorX KEYWORD2 getCursorX KEYWORD2
getCursorY KEYWORD2 getCursorY KEYWORD2
setTextColor KEYWORD2 setTextColor KEYWORD2
setTextSize KEYWORD2 setTextSize KEYWORD2
setTextFont KEYWORD2
setFreeFont KEYWORD2
setTextWrap KEYWORD2 setTextWrap KEYWORD2
setTextDatum KEYWORD2 setTextDatum KEYWORD2
getTextDatum KEYWORD2
setTextPadding KEYWORD2 setTextPadding KEYWORD2
getTextPadding KEYWORD2
setFreeFont KEYWORD2
setTextFont KEYWORD2
textWidth KEYWORD2
fontHeight KEYWORD2
decodeUTF8 KEYWORD2
write KEYWORD2
setCallback KEYWORD2
fontsLoaded KEYWORD2
spiwrite KEYWORD2 spiwrite KEYWORD2
writecommand KEYWORD2 writecommand KEYWORD2
writedata KEYWORD2 writedata KEYWORD2
@@ -49,56 +78,51 @@ commandList KEYWORD2
readcommand8 KEYWORD2 readcommand8 KEYWORD2
readcommand16 KEYWORD2 readcommand16 KEYWORD2
readcommand32 KEYWORD2 readcommand32 KEYWORD2
readPixel KEYWORD2
readRect KEYWORD2
pushRect KEYWORD2
pushImage KEYWORD2
setSwapBytes KEYWORD2
getSwapBytes KEYWORD2
readRectRGB KEYWORD2
getRotation KEYWORD2
getTextDatum KEYWORD2
fontsLoaded KEYWORD2
color565 KEYWORD2 color565 KEYWORD2
color16to8 KEYWORD2
color8to16 KEYWORD2 color8to16 KEYWORD2
drawNumber KEYWORD2 color16to8 KEYWORD2
drawFloat KEYWORD2 color16to24 KEYWORD2
drawString KEYWORD2 color24to16 KEYWORD2
drawCentreString KEYWORD2
drawRightString KEYWORD2
height KEYWORD2
width KEYWORD2
textWidth KEYWORD2
fontHeight KEYWORD2
getSetup KEYWORD2
setAttribute KEYWORD2
getAttribute KEYWORD2
alphaBlend KEYWORD2 alphaBlend KEYWORD2
alphaBlend24 KEYWORD2
getSPIinstance KEYWORD2
pushBlock KEYWORD2
pushPixels KEYWORD2
initDMA KEYWORD2 initDMA KEYWORD2
deInitDMA KEYWORD2 deInitDMA KEYWORD2
pushImageDMA KEYWORD2 pushImageDMA KEYWORD2
pushBlockDMA KEYWORD2
pushPixelsDMA KEYWORD2 pushPixelsDMA KEYWORD2
dmaBusy KEYWORD2 dmaBusy KEYWORD2
dmaWait KEYWORD2 dmaWait KEYWORD2
startWrite KEYWORD2
writeColor KEYWORD2
endWrite KEYWORD2
setAttribute KEYWORD2
getAttribute KEYWORD2
getSetup KEYWORD2
getSPIinstance KEYWORD2
# Touch functions
getTouchRaw KEYWORD2 getTouchRaw KEYWORD2
convertRawXY KEYWORD2
getTouchRawZ KEYWORD2 getTouchRawZ KEYWORD2
convertRawXY KEYWORD2
getTouch KEYWORD2 getTouch KEYWORD2
calibrateTouch KEYWORD2 calibrateTouch KEYWORD2
setTouch KEYWORD2 setTouch KEYWORD2
# Smooth font functions
loadFont KEYWORD2
unloadFont KEYWORD2
getUnicodeIndex KEYWORD2
showFont KEYWORD2
# Button class
TFT_eSPI_Button KEYWORD1 TFT_eSPI_Button KEYWORD1
initButton KEYWORD2 initButton KEYWORD2
textcolor KEYWORD2
initButtonUL KEYWORD2 initButtonUL KEYWORD2
setLabelDatum KEYWORD2 setLabelDatum KEYWORD2
drawButton KEYWORD2 drawButton KEYWORD2
@@ -109,31 +133,30 @@ justPressed KEYWORD2
justReleased KEYWORD2 justReleased KEYWORD2
# Sprite class
TFT_eSprite KEYWORD1 TFT_eSprite KEYWORD1
createSprite KEYWORD2 createSprite KEYWORD2
createPalette KEYWORD2 getPointer KEYWORD2
created KEYWORD2
deleteSprite KEYWORD2
frameBuffer KEYWORD2
setColorDepth KEYWORD2 setColorDepth KEYWORD2
getColorDepth KEYWORD2 getColorDepth KEYWORD2
deleteSprite KEYWORD2 createPalette KEYWORD2
setPaletteColor KEYWORD2
getPaletteColor KEYWORD2
setBitmapColor KEYWORD2
fillSprite KEYWORD2
setScrollRect KEYWORD2
scroll KEYWORD2
pushRotated KEYWORD2 pushRotated KEYWORD2
pushRotatedHP KEYWORD2
rotatedBounds KEYWORD2
setPivot KEYWORD2 setPivot KEYWORD2
getPivotX KEYWORD2 getPivotX KEYWORD2
getPivotY KEYWORD2 getPivotY KEYWORD2
fillSprite KEYWORD2 getRotatedBounds KEYWORD2
pushBitmap KEYWORD2 readPixelValue KEYWORD2
pushSprite KEYWORD2
setScrollRect KEYWORD2
scroll KEYWORD2
printToSprite KEYWORD2
frameBuffer KEYWORD2
setBitmapColor KEYWORD2
showFont KEYWORD2
loadFont KEYWORD2
unloadFont KEYWORD2
getUnicodeIndex KEYWORD2
decodeUTF8 KEYWORD2
drawGlyph KEYWORD2 drawGlyph KEYWORD2
printToSprite KEYWORD2
pushSprite KEYWORD2

View File

@@ -1,6 +1,6 @@
{ {
"name": "TFT_eSPI", "name": "TFT_eSPI",
"version": "2.2.15", "version": "2.2.16",
"keywords": "Arduino, tft, ePaper, display, STM32, ESP8266, NodeMCU, ESP32, M5Stack, ILI9341, ST7735, ILI9163, S6D02A1, ILI9486, ST7789, RM68140", "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", "description": "A TFT and ePaper SPI graphics library with optimisation for ESP8266, ESP32 and STM32",
"repository": "repository":

View File

@@ -1,5 +1,5 @@
name=TFT_eSPI name=TFT_eSPI
version=2.2.15 version=2.2.16
author=Bodmer author=Bodmer
maintainer=Bodmer maintainer=Bodmer
sentence=TFT graphics library for Arduino processors with performance optimisation for STM32, ESP8266 and ESP32 sentence=TFT graphics library for Arduino processors with performance optimisation for STM32, ESP8266 and ESP32