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
** Description: Class constructor
*************************************************************************************x*/
***************************************************************************************/
TFT_eSprite::TFT_eSprite(TFT_eSPI *tft)
{
_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
** 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
void* TFT_eSprite::createSprite(int16_t w, int16_t h, uint8_t frames)
{
if ( _created ) return _img8_1;
if ( w < 1 || h < 1 ) return NULL;
if ( w < 1 || h < 1 ) return nullptr;
_iwidth = _dwidth = _bitwidth = w;
_iheight = _dheight = h;
@@ -105,17 +105,28 @@ void* TFT_eSprite::createSprite(int16_t w, int16_t h, uint8_t frames)
if (_img8)
{
_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
** Description: Returns true is sprite has been created
*************************************************************************************x*/
***************************************************************************************/
bool TFT_eSprite::created(void)
{
return _created;
@@ -125,7 +136,7 @@ bool TFT_eSprite::created(void)
/***************************************************************************************
** Function name: ~TFT_eSprite
** Description: Class destructor
*************************************************************************************x*/
***************************************************************************************/
TFT_eSprite::~TFT_eSprite(void)
{
deleteSprite();
@@ -139,14 +150,14 @@ TFT_eSprite::~TFT_eSprite(void)
/***************************************************************************************
** Function name: callocSprite
** 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)
{
// 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
// 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 < 1) frames = 1;
@@ -154,10 +165,17 @@ void* TFT_eSprite::callocSprite(int16_t w, int16_t h, uint8_t frames)
if (_bpp == 16)
{
#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
#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)
@@ -203,7 +221,7 @@ void* TFT_eSprite::callocSprite(int16_t w, int16_t h, uint8_t frames)
/***************************************************************************************
** Function name: createPalette (from RAM array)
** Description: Set a palette for a 4-bit per pixel sprite
*************************************************************************************x*/
***************************************************************************************/
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));
if (colors > 16) colors = 16;
// Copy map colors
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)
** Description: Set a palette for a 4-bit per pixel sprite
*************************************************************************************x*/
***************************************************************************************/
void TFT_eSprite::createPalette(const uint16_t colorMap[], uint8_t colors)
{
if (_colorMap != nullptr)
{
free(_colorMap);
}
if (colorMap == nullptr)
{
// 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
** Description: For 1 bpp Sprites, select the frame used for graphics
*************************************************************************************x*/
***************************************************************************************/
// Frames are numbered 1 and 2
void* TFT_eSprite::frameBuffer(int8_t f)
{
if (!_created) return NULL;
if (!_created) return nullptr;
if ( f == 2 ) _img8 = _img8_2;
else _img8 = _img8_1;
@@ -285,34 +298,37 @@ void* TFT_eSprite::frameBuffer(int8_t f)
/***************************************************************************************
** Function name: setColorDepth
** Description: Set bits per pixel for colour (1, 8 or 16)
*************************************************************************************x*/
***************************************************************************************/
void* TFT_eSprite::setColorDepth(int8_t b)
{
// Can't change an existing sprite's colour depth so delete it
if (_created) free(_img8_1);
// Do not re-create the sprite if the colour depth does not change
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
else if ( b > 4 ) _bpp = 8;
else if ( b > 1 ) _bpp = 4;
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 (_created)
{
_created = false;
return createSprite(_iwidth, _iheight);
return createSprite(_dwidth, _dheight);
}
return NULL;
return nullptr;
}
/***************************************************************************************
** Function name: getColorDepth
** Description: Get bits per pixel for colour (1, 8 or 16)
*************************************************************************************x*/
***************************************************************************************/
int8_t TFT_eSprite::getColorDepth(void)
{
@@ -357,7 +373,7 @@ uint16_t TFT_eSprite::getPaletteColor(uint8_t index)
/***************************************************************************************
** Function name: deleteSprite
** Description: Delete the sprite to free up memory (RAM)
*************************************************************************************x*/
***************************************************************************************/
void TFT_eSprite::deleteSprite(void)
{
if (!_created ) return;
@@ -369,6 +385,8 @@ void TFT_eSprite::deleteSprite(void)
free(_img8_1);
_img8 = nullptr;
_created = false;
}
@@ -376,7 +394,7 @@ void TFT_eSprite::deleteSprite(void)
/***************************************************************************************
** Function name: setPivot
** Description: Set the pivot point in this Sprite
*************************************************************************************x*/
***************************************************************************************/
void TFT_eSprite::setPivot(int16_t x, int16_t y)
{
_xpivot = x;
@@ -407,7 +425,7 @@ int16_t TFT_eSprite::getPivotY(void)
/***************************************************************************************
** Function name: pushRotated - Fast fixed point integer maths version
** Description: Push rotated Sprite to TFT screen
*************************************************************************************x*/
***************************************************************************************/
#define FP_SCALE 10
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 yt = min_y - _tft->_ypivot;
uint32_t xe = _iwidth << FP_SCALE;
uint32_t ye = _iheight << FP_SCALE;
uint32_t xe = _dwidth << FP_SCALE;
uint32_t ye = _dheight << FP_SCALE;
uint32_t tpcolor = transp; // convert to unsigned
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
// 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;
int32_t xp = xs >> FP_SCALE;
int32_t yp = ys >> FP_SCALE;
if (_bpp == 16) {rp = _img[xp + yp * _iwidth]; rp = rp>>8 | rp<<8; }
else rp = readPixel(xp, yp);
if (_bpp == 16) {rp = _img[xp + yp * _iwidth]; }
else { rp = readPixel(xp, yp); rp = rp>>8 | rp<<8; }
if (tpcolor == rp) {
if (pixel_count) {
// 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 {
sline_buffer[pixel_count++] = rp>>8 | rp<<8;
sline_buffer[pixel_count++] = rp;
}
} while (++x < max_x && (xs += _cosra) < xe && (ys += _sinra) < ye);
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
** 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)
{
@@ -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 yt = min_y - spr->_ypivot;
uint32_t xe = _iwidth << FP_SCALE;
uint32_t ye = _iheight << FP_SCALE;
uint32_t tpcolor = transp; // convert to unsigned
uint32_t xe = _dwidth << FP_SCALE;
uint32_t ye = _dheight << FP_SCALE;
uint32_t tpcolor = transp>>8 | transp<<8; // convert to unsigned swapped bytes
bool oldSwapBytes = spr->getSwapBytes();
spr->setSwapBytes(false);
@@ -518,8 +536,8 @@ bool TFT_eSprite::pushRotated(TFT_eSprite *spr, int16_t angle, int32_t transp)
uint32_t rp;
int32_t xp = xs >> FP_SCALE;
int32_t yp = ys >> FP_SCALE;
if (_bpp == 16) {rp = _img[xp + yp * _iwidth]; rp = rp>>8 | rp<<8; }
else rp = readPixel(xp, yp);
if (_bpp == 16) rp = _img[xp + yp * _iwidth];
else { rp = readPixel(xp, yp); rp = rp>>8 | rp<<8; }
if (tpcolor == rp) {
if (pixel_count) {
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
** 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,
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
** 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,
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
** 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,
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
** Description: Push the sprite to the TFT at x, y
*************************************************************************************x*/
***************************************************************************************/
void TFT_eSprite::pushSprite(int32_t x, int32_t y)
{
if (!_created) return;
@@ -671,7 +689,7 @@ void TFT_eSprite::pushSprite(int32_t x, int32_t y)
{
bool oldSwapBytes = _tft->getSwapBytes();
_tft->setSwapBytes(false);
_tft->pushImage(x, y, _iwidth, _iheight, _img );
_tft->pushImage(x, y, _dwidth, _dheight, _img );
_tft->setSwapBytes(oldSwapBytes);
}
else if (_bpp == 4)
@@ -685,7 +703,7 @@ void TFT_eSprite::pushSprite(int32_t x, int32_t y)
/***************************************************************************************
** Function name: pushSprite
** 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)
{
if (!_created) return;
@@ -694,7 +712,7 @@ void TFT_eSprite::pushSprite(int32_t x, int32_t y, uint16_t transp)
{
bool oldSwapBytes = _tft->getSwapBytes();
_tft->setSwapBytes(false);
_tft->pushImage(x, y, _iwidth, _iheight, _img, transp );
_tft->pushImage(x, y, _dwidth, _dheight, _img, transp );
_tft->setSwapBytes(oldSwapBytes);
}
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
** Description: Read the color map index of a pixel at defined coordinates
*************************************************************************************x*/
***************************************************************************************/
uint16_t TFT_eSprite::readPixelValue(int32_t x, int32_t y)
{
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 (x >= _dwidth) return 0xFF;
if ((x & 0x01) == 0)
return _img4[((x+y*_iwidth)>>1)] >> 4; // even index = bits 7 .. 4
else
@@ -740,6 +920,7 @@ uint16_t TFT_eSprite::readPixelValue(int32_t x, int32_t y)
if (_bpp == 1)
{
// Note: _dwidth and _dheight bounds not checked (rounded up -iwidth and _iheight used)
if (_rotation == 1)
{
uint16_t tx = x;
@@ -767,7 +948,7 @@ uint16_t TFT_eSprite::readPixelValue(int32_t x, int32_t y)
/***************************************************************************************
** Function name: readPixel
** Description: Read 565 colour of a pixel at defined coordinates
*************************************************************************************x*/
***************************************************************************************/
uint16_t TFT_eSprite::readPixel(int32_t x, int32_t y)
{
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];
return (color >> 8) | (color << 8);
}
if (_bpp == 8)
{
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 (x >= _dwidth) return 0xFFFF;
uint16_t color;
if ((x & 0x01) == 0)
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;
}
// Note: Must be 1bpp
// _dwidth and _dheight bounds not checked (rounded up -iwidth and _iheight used)
if (_rotation == 1)
{
uint16_t tx = x;
@@ -828,18 +1012,19 @@ uint16_t TFT_eSprite::readPixel(int32_t x, int32_t y)
/***************************************************************************************
** Function name: pushImage
** Description: push 565 colour image into a defined area of a sprite
*************************************************************************************x*/
** Description: push image into a defined area of a sprite
***************************************************************************************/
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;
int32_t xo = 0;
int32_t yo = 0;
int32_t xo = 0;
int32_t yo = 0;
int32_t xs = x;
int32_t ys = y;
int32_t xs = x;
int32_t ys = y;
int32_t ws = w;
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
{
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;
for (int32_t xp = xo; xp < xo + ws; xp++)
while (hs--)
{
uint16_t color = data[xp + yp * w];
if(_iswapBytes) color = color<<8 | color>>8;
_img[x + ys * _iwidth] = color;
x++;
// Fast copy with a 1 byte shift
memcpy(ptrs+1, ptro, (ws<<1) - 1);
// Now correct just the even numbered bytes
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
@@ -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++)
{
uint16_t color = data[xp + yp * w];
if(_iswapBytes) color = color<<8 | color>>8;
_img8[x + ys * _iwidth] = (uint8_t)((color & 0xE000)>>8 | (color & 0x0700)>>6 | (color & 0x0018)>>3);
// When data source is a sprite, the bytes are already swapped
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++;
}
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)
{
// 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
// tedious bit operations.
const uint8_t *dataBuf = (uint8_t *)data;
int sWidth = (_iwidth >> 1);
if ((xs & 0x01) == 0 && (xo & 0x01) == 0 && (ws & 0x01) == 0)
{
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
{
// _dwidth and _dheight bounds not checked (rounded up -iwidth and _iheight used)
for (int32_t yp = yo; yp < yo + hs; yp++)
{
x = xs;
@@ -917,7 +1121,7 @@ void TFT_eSprite::pushImage(int32_t x, int32_t y, int32_t w, int32_t h, uint16_
else
color = dataBuf[((xp-1+yp*w)>>1)] & 0x0F; // odd index = bits 3 .. 0.
drawPixel(x, ys, color);
x++;
x++;
}
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
** 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)
{
#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
{
// _dwidth and _dheight bounds not checked (rounded up -iwidth and _iheight used)
// Move coordinate rotation to support fn
if (_rotation == 1)
{
@@ -1090,26 +1295,26 @@ bool TFT_eSprite::getSwapBytes(void)
/***************************************************************************************
** Function name: setWindow
** Description: Set the bounds of a window for pushColor and writeColor
*************************************************************************************x*/
** Description: Set the bounds of a window in the sprite
***************************************************************************************/
void TFT_eSprite::setWindow(int32_t x0, int32_t y0, int32_t x1, int32_t y1)
{
if (x0 > x1) swap_coord(x0, x1);
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
_xs = 0;
_ys = _iheight;
_ys = _dheight;
_xe = 0;
_ye = _iheight;
_ye = _dheight;
}
else
{
if (x0 < 0) x0 = 0;
if (x1 >= _iwidth) x1 = _iwidth - 1;
if (x1 >= _dwidth) x1 = _dwidth - 1;
if (y0 < 0) y0 = 0;
if (y1 >= _iheight) y1 = _iheight - 1;
if (y1 >= _dheight) y1 = _dheight - 1;
_xs = x0;
_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
** Description: Send a new pixel to the set window
*************************************************************************************x*/
***************************************************************************************/
void TFT_eSprite::pushColor(uint32_t color)
{
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
}
}
else drawPixel(_xptr, _yptr, color);
// Increment x
@@ -1167,7 +1372,7 @@ void TFT_eSprite::pushColor(uint32_t color)
/***************************************************************************************
** Function name: pushColor
** Description: Send a "len" new pixels to the set window
*************************************************************************************x*/
***************************************************************************************/
void TFT_eSprite::pushColor(uint32_t color, uint16_t len)
{
if (!_created ) return;
@@ -1189,7 +1394,7 @@ void TFT_eSprite::pushColor(uint32_t color, uint16_t len)
/***************************************************************************************
** Function name: writeColor
** Description: Write a pixel with pre-formatted colour to the set window
*************************************************************************************x*/
***************************************************************************************/
void TFT_eSprite::writeColor(uint16_t color)
{
if (!_created ) return;
@@ -1227,7 +1432,7 @@ void TFT_eSprite::writeColor(uint16_t color)
/***************************************************************************************
** Function name: setScrollRect
** 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)
{
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 ((y + h) > _iheight) h = _iheight - y;
if ( w < 1 || h < 1) return;
if ( w < 1 || h < 1) return;
_sx = x;
_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
** Description: Scroll dx,dy pixels, positive right,down, negative left,up
*************************************************************************************x*/
***************************************************************************************/
void TFT_eSprite::scroll(int16_t dx, int16_t dy)
{
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()
uint32_t w = _sw - abs(dx); // line width 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()
uint32_t tx = _sx; // to x
@@ -1350,7 +1555,7 @@ void TFT_eSprite::scroll(int16_t dx, int16_t dy)
/***************************************************************************************
** Function name: fillSprite
** Description: Fill the whole sprite with defined colour
*************************************************************************************x*/
***************************************************************************************/
void TFT_eSprite::fillSprite(uint32_t color)
{
if (!_created ) return;
@@ -1381,7 +1586,7 @@ void TFT_eSprite::fillSprite(uint32_t color)
/***************************************************************************************
** Function name: setCursor
** Description: Set the sprite text cursor x,y position
*************************************************************************************x*/
***************************************************************************************/
// Not needed - using TFT_eSPI class function and this->cursor_x/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
** Description: Return the width of sprite
*************************************************************************************x*/
***************************************************************************************/
// Return the size of the display
int16_t TFT_eSprite::width(void)
{
if (!_created ) return 0;
if (_bpp > 1) return _iwidth;
if (_bpp > 1) return _dwidth;
if (_rotation == 1 || _rotation == 3) return _dheight;
@@ -1410,12 +1615,12 @@ int16_t TFT_eSprite::width(void)
/***************************************************************************************
** Function name: height
** Description: Return the height of sprite
*************************************************************************************x*/
***************************************************************************************/
int16_t TFT_eSprite::height(void)
{
if (!_created ) return 0;
if (_bpp > 1) return _iheight;
if (_bpp > 4) return _dheight;
if (_rotation == 1 || _rotation == 3) return _dwidth;
@@ -1426,7 +1631,7 @@ int16_t TFT_eSprite::height(void)
/***************************************************************************************
** Function name: setRotation
** Description: Rotate coordinate frame for 1bpp sprite
*************************************************************************************x*/
***************************************************************************************/
// Does nothing for 8 and 16 bpp sprites. TODO allow rotation of these sprites
void TFT_eSprite::setRotation(uint8_t rotation)
{
@@ -1443,7 +1648,7 @@ void TFT_eSprite::setRotation(uint8_t rotation)
/***************************************************************************************
** Function name: getRotation
** Description: Get rotation for 1bpp sprite
*************************************************************************************x*/
***************************************************************************************/
uint8_t TFT_eSprite::getRotation(void)
{
@@ -1454,7 +1659,7 @@ uint8_t TFT_eSprite::getRotation(void)
/***************************************************************************************
** Function name: drawPixel
** Description: push a single pixel at an arbitrary position
*************************************************************************************x*/
***************************************************************************************/
void TFT_eSprite::drawPixel(int32_t x, int32_t y, uint32_t color)
{
// Range checking
@@ -1510,7 +1715,7 @@ void TFT_eSprite::drawPixel(int32_t x, int32_t y, uint32_t color)
/***************************************************************************************
** Function name: drawLine
** 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)
{
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
** Description: draw a vertical line
*************************************************************************************x*/
***************************************************************************************/
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
** Description: draw a horizontal line
*************************************************************************************x*/
***************************************************************************************/
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
** 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)
{
if (!_created ) return;
if ((x >= _iwidth) || (y >= _iheight)) return;
if (x < 0) { w += x; x = 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
** Description: draw characters piped through serial stream
*************************************************************************************x*/
***************************************************************************************/
size_t TFT_eSprite::write(uint8_t utf8)
{
uint16_t uniCode = decodeUTF8(utf8);
@@ -1864,7 +2069,7 @@ size_t TFT_eSprite::write(uint8_t utf8)
height = height * textsize;
if (utf8 == '\n')
if (utf8 == '\n')
{
this->cursor_y += height;
this->cursor_x = 0;
@@ -1919,7 +2124,7 @@ size_t TFT_eSprite::write(uint8_t utf8)
/***************************************************************************************
** Function name: drawChar
** 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)
{
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
** Description: draw a unicode onto the screen
*************************************************************************************x*/
***************************************************************************************/
// Any UTF-8 decoding must be done before calling drawChar()
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
** Description: Write a character to the sprite cursor position
*************************************************************************************x*/
***************************************************************************************/
void TFT_eSprite::drawGlyph(uint16_t code)
{
if (code < 0x21)
@@ -2289,15 +2494,15 @@ void TFT_eSprite::drawGlyph(uint16_t code)
uint16_t gNum = 0;
bool found = this->getUnicodeIndex(code, &gNum);
uint16_t fg = this->textcolor;
uint16_t bg = this->textbgcolor;
if (found)
{
bool newSprite = !_created;
if (newSprite)
{
createSprite(this->gWidth[gNum], this->gFont.yAdvance);
@@ -2393,7 +2598,7 @@ void TFT_eSprite::drawGlyph(uint16_t code)
/***************************************************************************************
** Function name: printToSprite
** Description: Write a string to the sprite cursor position
*************************************************************************************x*/
***************************************************************************************/
void TFT_eSprite::printToSprite(String string)
{
if(!this->fontLoaded) return;
@@ -2408,14 +2613,14 @@ void TFT_eSprite::printToSprite(String string)
/***************************************************************************************
** Function name: printToSprite
** Description: Write a string to the sprite cursor position
*************************************************************************************x*/
***************************************************************************************/
void TFT_eSprite::printToSprite(char *cbuffer, uint16_t len) //String string)
{
if(!this->fontLoaded) return;
uint16_t n = 0;
bool newSprite = !_created;
if (newSprite)
{
int16_t sWidth = 1;
@@ -2459,7 +2664,7 @@ void TFT_eSprite::printToSprite(char *cbuffer, uint16_t len) //String string)
/***************************************************************************************
** Function name: printToSprite
** 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)
{
bool newSprite = !_created;

View File

@@ -10,6 +10,7 @@ class TFT_eSprite : public TFT_eSPI {
public:
TFT_eSprite(TFT_eSPI *tft);
~TFT_eSprite(void);
// 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
@@ -18,9 +19,10 @@ class TFT_eSprite : public TFT_eSPI {
// - 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);
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
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, 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),
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
#else
#if defined (TFT_PARALLEL_8_BIT)
#define DC_C GPIO.out_w1tc = (1 << TFT_DC)
#define DC_D GPIO.out_w1ts = (1 << TFT_DC)
// TFT_DC, by design, must be in range 0-31 for single register parallel write
#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
#if TFT_DC >= 32
#if (TFT_DC >= 32)
#ifdef RPI_DISPLAY_TYPE // RPi displays need a slower DC change
#define DC_C GPIO.out1_w1ts.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_D GPIO.out1_w1ts.val = (1 << (TFT_DC - 32))//;GPIO.out1_w1ts.val = (1 << (TFT_DC - 32))
#endif
#elif TFT_DC >= 0
#ifdef RPI_DISPLAY_TYPE // RPi ILI9486 display needs a slower DC change
#define DC_C GPIO.out_w1tc = (1 << TFT_DC); \
GPIO.out_w1tc = (1 << TFT_DC)
#define DC_D GPIO.out_w1tc = (1 << TFT_DC); \
GPIO.out_w1ts = (1 << TFT_DC)
#elif defined (RPI_DISPLAY_TYPE) // 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)
#elif (TFT_DC >= 0)
#if defined (RPI_DISPLAY_TYPE)
#if defined (ILI9486_DRIVER)
// RPi ILI9486 display needs a slower DC change
#define DC_C GPIO.out_w1tc = (1 << TFT_DC); \
GPIO.out_w1tc = (1 << TFT_DC)
#define DC_D GPIO.out_w1tc = (1 << TFT_DC); \
GPIO.out_w1ts = (1 << TFT_DC)
#else
// 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
#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)
@@ -131,8 +141,8 @@
#define CS_H
#endif
#else
#if TFT_CS >= 32
#ifdef RPI_DISPLAY_TYPE // RPi ILI9486 display needs a slower CS change
#if (TFT_CS >= 32)
#ifdef RPI_DISPLAY_TYPE // RPi display needs a slower CS change
#define CS_L GPIO.out1_w1ts.val = (1 << (TFT_CS - 32)); \
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_H GPIO.out1_w1ts.val = (1 << (TFT_CS - 32))//;GPIO.out1_w1ts.val = (1 << (TFT_CS - 32))
#endif
#elif TFT_CS >= 0
#ifdef RPI_DISPLAY_TYPE // RPi ILI9486 display needs a slower CS change
#elif (TFT_CS >= 0)
#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_H GPIO.out_w1tc = (1 << TFT_CS); GPIO.out_w1ts = (1 << TFT_CS)
#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)
#endif
#else
@@ -159,9 +169,18 @@
////////////////////////////////////////////////////////////////////////////////////////
// Define the WR (TFT Write) pin drive code
////////////////////////////////////////////////////////////////////////////////////////
#ifdef TFT_WR
#define WR_L GPIO.out_w1tc = (1 << TFT_WR)
#define WR_H GPIO.out_w1ts = (1 << TFT_WR)
#if defined (TFT_WR)
#if (TFT_WR >= 0)
// 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
////////////////////////////////////////////////////////////////////////////////////////
@@ -302,10 +321,18 @@
// Read pin
#ifdef TFT_RD
#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)
#if (TFT_RD >= 32)
#define RD_L GPIO.out1_w1tc.val = = (1 << (TFT_RD - 32))
#define RD_H GPIO.out1_w1ts.val = = (1 << (TFT_RD - 32))
#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
////////////////////////////////////////////////////////////////////////////////////////

View File

@@ -304,7 +304,7 @@ return;
SPI1U1 = (511 << SPILMOSI);
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
#endif
while(SPI1CMD & SPIBUSY) {}

View File

@@ -19,7 +19,7 @@
#define DMA_BUSY_CHECK // DMA not available, leave blank
// 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 \
spi.setBitOrder(MSBFIRST); \
spi.setDataMode(TFT_SPI_MODE); \

View File

@@ -58,6 +58,13 @@
#define CS_H digitalWrite(TFT_CS, HIGH)
#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
////////////////////////////////////////////////////////////////////////////////////////

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)
{
#ifdef STM_PORTA_DATA_BUS
#if defined (STM_PORTA_DATA_BUS)
#if defined (STM32F1xx)
if (mode == OUTPUT) GPIOA->CRL = 0x33333333;
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;
else GPIOA->MODER &= 0xFFFF0000;
#endif
#elif STM_PORTB_DATA_BUS
#elif defined (STM_PORTB_DATA_BUS)
#if defined (STM32F1xx)
if (mode == OUTPUT) GPIOB->CRL = 0x33333333;
else GPIOB->CRL = 0x88888888;
@@ -194,12 +194,12 @@ uint8_t TFT_eSPI::readByte(void)
uint8_t b = 0;
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) & 0xFF;
#elif STM_PORTB_DATA_BUS
#elif defined (STM_PORTB_DATA_BUS)
b = GPIOB->IDR;
b = GPIOB->IDR;
b = GPIOB->IDR;

View File

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

View File

@@ -335,8 +335,6 @@ void TFT_eSPI::init(uint8_t tc)
} // end of: if just _booted
// Toggle RST low to reset
begin_tft_write();
#ifdef TFT_RST
if (TFT_RST >= 0) {
digitalWrite(TFT_RST, HIGH);
@@ -350,8 +348,6 @@ void TFT_eSPI::init(uint8_t tc)
writecommand(TFT_SWRST); // Software reset
#endif
end_tft_write();
delay(150); // Wait for reset to complete
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
// The little endian transp color must be byte swapped if the image is big endian
if (!_swapBytes) transp = transp >> 8 | transp << 8;
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];
// The little endian transp color must be byte swapped if the image is big endian
if (!_swapBytes) transp = transp >> 8 | transp << 8;
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);
dy++;
}
_swapBytes = swap; // Restore old value

View File

@@ -16,7 +16,7 @@
#ifndef _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

View File

@@ -59,7 +59,7 @@
//#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/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
@@ -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/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/Setup45_TTGO_T_Watch.h> // Setup file for ESP32 and TTGO T-Watch 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/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
begin KEYWORD2
init KEYWORD2
drawPixel 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
drawFastVLine KEYWORD2
drawFastHLine KEYWORD2
drawRect 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
fillRoundRect KEYWORD2
setRotation KEYWORD2
invertDisplay KEYWORD2
drawCircle KEYWORD2
drawCircleHelper KEYWORD2
fillCircle KEYWORD2
@@ -30,18 +37,40 @@ drawEllipse KEYWORD2
fillEllipse KEYWORD2
drawTriangle KEYWORD2
fillTriangle KEYWORD2
setSwapBytes KEYWORD2
getSwapBytes KEYWORD2
drawBitmap 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
getCursorX KEYWORD2
getCursorY KEYWORD2
setTextColor KEYWORD2
setTextSize KEYWORD2
setTextFont KEYWORD2
setFreeFont KEYWORD2
setTextWrap KEYWORD2
setTextDatum KEYWORD2
getTextDatum KEYWORD2
setTextPadding KEYWORD2
getTextPadding KEYWORD2
setFreeFont KEYWORD2
setTextFont KEYWORD2
textWidth KEYWORD2
fontHeight KEYWORD2
decodeUTF8 KEYWORD2
write KEYWORD2
setCallback KEYWORD2
fontsLoaded KEYWORD2
spiwrite KEYWORD2
writecommand KEYWORD2
writedata KEYWORD2
@@ -49,56 +78,51 @@ commandList KEYWORD2
readcommand8 KEYWORD2
readcommand16 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
color16to8 KEYWORD2
color8to16 KEYWORD2
drawNumber KEYWORD2
drawFloat KEYWORD2
drawString KEYWORD2
drawCentreString KEYWORD2
drawRightString KEYWORD2
height KEYWORD2
width KEYWORD2
textWidth KEYWORD2
fontHeight KEYWORD2
getSetup KEYWORD2
setAttribute KEYWORD2
getAttribute KEYWORD2
color16to8 KEYWORD2
color16to24 KEYWORD2
color24to16 KEYWORD2
alphaBlend KEYWORD2
getSPIinstance KEYWORD2
pushBlock KEYWORD2
pushPixels KEYWORD2
alphaBlend24 KEYWORD2
initDMA KEYWORD2
deInitDMA KEYWORD2
pushImageDMA KEYWORD2
pushBlockDMA KEYWORD2
pushPixelsDMA KEYWORD2
dmaBusy KEYWORD2
dmaWait KEYWORD2
startWrite KEYWORD2
writeColor KEYWORD2
endWrite KEYWORD2
setAttribute KEYWORD2
getAttribute KEYWORD2
getSetup KEYWORD2
getSPIinstance KEYWORD2
# Touch functions
getTouchRaw KEYWORD2
convertRawXY KEYWORD2
getTouchRawZ KEYWORD2
convertRawXY KEYWORD2
getTouch KEYWORD2
calibrateTouch KEYWORD2
setTouch KEYWORD2
# Smooth font functions
loadFont KEYWORD2
unloadFont KEYWORD2
getUnicodeIndex KEYWORD2
showFont KEYWORD2
# Button class
TFT_eSPI_Button KEYWORD1
initButton KEYWORD2
textcolor KEYWORD2
initButtonUL KEYWORD2
setLabelDatum KEYWORD2
drawButton KEYWORD2
@@ -109,31 +133,30 @@ justPressed KEYWORD2
justReleased KEYWORD2
# Sprite class
TFT_eSprite KEYWORD1
createSprite KEYWORD2
createPalette KEYWORD2
getPointer KEYWORD2
created KEYWORD2
deleteSprite KEYWORD2
frameBuffer KEYWORD2
setColorDepth KEYWORD2
getColorDepth KEYWORD2
deleteSprite KEYWORD2
createPalette KEYWORD2
setPaletteColor KEYWORD2
getPaletteColor KEYWORD2
setBitmapColor KEYWORD2
fillSprite KEYWORD2
setScrollRect KEYWORD2
scroll KEYWORD2
pushRotated KEYWORD2
pushRotatedHP KEYWORD2
rotatedBounds KEYWORD2
setPivot KEYWORD2
getPivotX KEYWORD2
getPivotY KEYWORD2
fillSprite KEYWORD2
pushBitmap KEYWORD2
pushSprite KEYWORD2
setScrollRect KEYWORD2
scroll KEYWORD2
printToSprite KEYWORD2
frameBuffer KEYWORD2
setBitmapColor KEYWORD2
showFont KEYWORD2
loadFont KEYWORD2
unloadFont KEYWORD2
getUnicodeIndex KEYWORD2
decodeUTF8 KEYWORD2
getRotatedBounds KEYWORD2
readPixelValue KEYWORD2
drawGlyph KEYWORD2
printToSprite KEYWORD2
pushSprite KEYWORD2

View File

@@ -1,6 +1,6 @@
{
"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",
"description": "A TFT and ePaper SPI graphics library with optimisation for ESP8266, ESP32 and STM32",
"repository":

View File

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