#define NORMAL_SPEED
#include <AnimatedGIF.h>
AnimatedGIF gif;
#include "loading.h"
#define GIF_IMAGE angry_80px_gif
#include <SPI.h>
#include <TFT_eSPI.h>
#define DISPLAY_WIDTH tft.width()
#define DISPLAY_HEIGHT tft.height()
#define BUFFER_SIZE \
60
#ifdef USE_DMA
uint16_t usTemp[2][BUFFER_SIZE];
#else
uint16_t usTemp[1][BUFFER_SIZE];
#endif
bool dmaBuf = 0;
TFT_eSPI tft = TFT_eSPI();
void GIFDraw(GIFDRAW *pDraw) {
uint8_t *s;
uint16_t *d, *usPalette;
int x, y, iWidth, iCount;
iWidth = pDraw->iWidth;
if (iWidth + pDraw->iX > DISPLAY_WIDTH) iWidth = DISPLAY_WIDTH - pDraw->iX;
usPalette = pDraw->pPalette;
y = pDraw->iY + pDraw->y;
if (y >= DISPLAY_HEIGHT || pDraw->iX >= DISPLAY_WIDTH || iWidth < 1) return;
s = pDraw->pPixels;
if (pDraw->ucDisposalMethod == 2)
{
for (x = 0; x < iWidth; x++) {
if (s[x] == pDraw->ucTransparent) s[x] = pDraw->ucBackground;
}
pDraw->ucHasTransparency = 0;
}
if (pDraw->ucHasTransparency)
{
uint8_t *pEnd, c, ucTransparent = TFT_BLACK;
pEnd = s + iWidth;
x = 0;
iCount = 0;
while (x < iWidth) {
c = ucTransparent - 1;
d = &usTemp[0][0];
while (c != ucTransparent && s < pEnd && iCount < BUFFER_SIZE) {
c = *s++;
if (c == ucTransparent)
{
s--;
} else
{
*d++ = usPalette[c];
iCount++;
}
}
if (iCount)
{
tft.setAddrWindow(pDraw->iX + x, y, iCount, 1);
tft.pushPixels(usTemp, iCount);
x += iCount;
iCount = 0;
}
c = ucTransparent;
while (c == ucTransparent && s < pEnd) {
c = *s++;
if (c == ucTransparent)
x++;
else
s--;
}
}
} else {
s = pDraw->pPixels;
if (iWidth <= BUFFER_SIZE)
for (iCount = 0; iCount < iWidth; iCount++)
usTemp[dmaBuf][iCount] = usPalette[*s++];
else
for (iCount = 0; iCount < BUFFER_SIZE; iCount++)
usTemp[dmaBuf][iCount] = usPalette[*s++];
#ifdef USE_DMA
tft.dmaWait();
tft.setAddrWindow(pDraw->iX, y, iWidth, 1);
tft.pushPixelsDMA(&usTemp[dmaBuf][0], iCount);
dmaBuf = !dmaBuf;
#else
tft.setAddrWindow(pDraw->iX, y, iWidth, 1);
tft.pushPixels(&usTemp[0][0], iCount);
#endif
iWidth -= iCount;
while (iWidth > 0) {
if (iWidth <= BUFFER_SIZE)
for (iCount = 0; iCount < iWidth; iCount++)
usTemp[dmaBuf][iCount] = usPalette[*s++];
else
for (iCount = 0; iCount < BUFFER_SIZE; iCount++)
usTemp[dmaBuf][iCount] = usPalette[*s++];
#ifdef USE_DMA
tft.dmaWait();
tft.pushPixelsDMA(&usTemp[dmaBuf][0], iCount);
dmaBuf = !dmaBuf;
#else
tft.pushPixels(&usTemp[0][0], iCount);
#endif
iWidth -= iCount;
}
}
}
void setup() {
Serial.begin(115200);
tft.begin();
#ifdef USE_DMA
tft.initDMA();
#endif
tft.setRotation(1);
tft.fillScreen(TFT_BLACK);
gif.begin(BIG_ENDIAN_PIXELS);
}
#ifdef NORMAL_SPEED
void loop() {
if (gif.open((uint8_t *)GIF_IMAGE, sizeof(GIF_IMAGE), GIFDraw)) {
Serial.printf("Successfully opened GIF; Canvas size = %d x %d\n",
gif.getCanvasWidth(), gif.getCanvasHeight());
tft.startWrite();
while (gif.playFrame(true, NULL)) {
yield();
}
gif.close();
tft.endWrite();
}
}
#else
void loop() {
long lTime = micros();
int iFrames = 0;
if (gif.open((uint8_t *)GIF_IMAGE, sizeof(GIF_IMAGE), GIFDraw)) {
tft.startWrite();
while (gif.playFrame(false, NULL)) {
iFrames++;
yield();
}
gif.close();
tft.endWrite();
lTime = micros() - lTime;
Serial.print(iFrames / (lTime / 1000000.0));
Serial.println(" fps");
}
}
#endif