mirror of
https://github.com/thelastoutpostworkshop/ESP32ManyRoundScreenTest.git
synced 2025-11-04 14:49:41 +08:00
initial
This commit is contained in:
parent
a5f57cf1d3
commit
8f489017ac
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
build
|
||||||
|
.vscode
|
||||||
72
ESP32ManyRoundScreenTest.ino
Normal file
72
ESP32ManyRoundScreenTest.ino
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
// Animated GIF with Multiple Displays
|
||||||
|
//
|
||||||
|
// ESP32 40MHz SPI single frame rendering performance
|
||||||
|
|
||||||
|
#include <SPI.h>
|
||||||
|
#include <TFT_eSPI.h> // Install this library with the Arduino IDE Library Manager
|
||||||
|
#include <AnimatedGIF.h> // Install this library with the Arduino IDE Library Manager
|
||||||
|
#include "images/darthvader.h"
|
||||||
|
#include "images/x_wing.h"
|
||||||
|
#include "images/nostromo.h"
|
||||||
|
#include "images/hud_6.h"
|
||||||
|
|
||||||
|
const int NUM_DISPLAYS = 3; // Adjust this value based on the number of displays
|
||||||
|
AnimatedGIF gifs[NUM_DISPLAYS];
|
||||||
|
|
||||||
|
// Define CS pins for all displays
|
||||||
|
const int CS_PINS[NUM_DISPLAYS] = {19,22,21}; // Add more pins if you have more displays
|
||||||
|
|
||||||
|
// Define the images for all displays
|
||||||
|
const uint8_t *GIF_IMAGES[NUM_DISPLAYS] = {x_wing,darthvader,hud_6}; // Add more images if needed
|
||||||
|
const size_t GIF_SIZES[NUM_DISPLAYS] = {sizeof(x_wing),sizeof(darthvader),sizeof(hud_6)}; // Add more sizes if needed
|
||||||
|
|
||||||
|
TFT_eSPI tft;
|
||||||
|
|
||||||
|
void setup()
|
||||||
|
{
|
||||||
|
Serial.begin(115200);
|
||||||
|
|
||||||
|
tft.init();
|
||||||
|
for (int i = 0; i < NUM_DISPLAYS; i++)
|
||||||
|
{
|
||||||
|
pinMode(CS_PINS[i], OUTPUT);
|
||||||
|
digitalWrite(CS_PINS[i], HIGH); // Deselect the display
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < NUM_DISPLAYS; i++)
|
||||||
|
{
|
||||||
|
digitalWrite(CS_PINS[i], LOW); // Select the display
|
||||||
|
tft.fillScreen(TFT_BLACK);
|
||||||
|
tft.setRotation(2); // Adjust Rotation of your screen (0-3)
|
||||||
|
gifs[i].begin(BIG_ENDIAN_PIXELS);
|
||||||
|
if (!gifs[i].open((uint8_t *)GIF_IMAGES[i], GIF_SIZES[i], GIFDraw))
|
||||||
|
{
|
||||||
|
Serial.printf("Failed to open GIF%d\n", i + 1);
|
||||||
|
Serial.printf("Last Error=%d", gifs[i].getLastError());
|
||||||
|
Serial.printf("Image size=%d", sizeof(GIF_IMAGES[i]));
|
||||||
|
}
|
||||||
|
digitalWrite(CS_PINS[i], HIGH); // Deselect the display
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < NUM_DISPLAYS; i++)
|
||||||
|
{
|
||||||
|
digitalWrite(CS_PINS[i], LOW); // Select the display
|
||||||
|
|
||||||
|
tft.startWrite();
|
||||||
|
|
||||||
|
int res = gifs[i].playFrame(false, NULL);
|
||||||
|
if (res == 0)
|
||||||
|
{
|
||||||
|
// If no more frames are available, reset the GIF to the beginning
|
||||||
|
gifs[i].reset();
|
||||||
|
gifs[i].playFrame(false, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
tft.endWrite();
|
||||||
|
|
||||||
|
digitalWrite(CS_PINS[i], HIGH); // Deselect the display
|
||||||
|
}
|
||||||
|
}
|
||||||
131
GIFDraw.ino
Normal file
131
GIFDraw.ino
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
// GIFDraw is called by AnimatedGIF library frame to screen
|
||||||
|
|
||||||
|
#define DISPLAY_WIDTH tft.width()
|
||||||
|
#define DISPLAY_HEIGHT tft.height()
|
||||||
|
#define BUFFER_SIZE 256 // Optimum is >= GIF width or integral division of width
|
||||||
|
|
||||||
|
#ifdef USE_DMA
|
||||||
|
uint16_t usTemp[2][BUFFER_SIZE]; // Global to support DMA use
|
||||||
|
#else
|
||||||
|
uint16_t usTemp[1][BUFFER_SIZE]; // Global to support DMA use
|
||||||
|
#endif
|
||||||
|
bool dmaBuf = 0;
|
||||||
|
|
||||||
|
// Draw a line of image directly on the LCD
|
||||||
|
void GIFDraw(GIFDRAW *pDraw)
|
||||||
|
{
|
||||||
|
uint8_t *s;
|
||||||
|
uint16_t *d, *usPalette;
|
||||||
|
int x, y, iWidth, iCount;
|
||||||
|
|
||||||
|
// Displ;ay bounds chech and cropping
|
||||||
|
iWidth = pDraw->iWidth;
|
||||||
|
if (iWidth + pDraw->iX > DISPLAY_WIDTH)
|
||||||
|
iWidth = DISPLAY_WIDTH - pDraw->iX;
|
||||||
|
usPalette = pDraw->pPalette;
|
||||||
|
y = pDraw->iY + pDraw->y; // current line
|
||||||
|
if (y >= DISPLAY_HEIGHT || pDraw->iX >= DISPLAY_WIDTH || iWidth < 1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Old image disposal
|
||||||
|
s = pDraw->pPixels;
|
||||||
|
if (pDraw->ucDisposalMethod == 2) // restore to background color
|
||||||
|
{
|
||||||
|
for (x = 0; x < iWidth; x++)
|
||||||
|
{
|
||||||
|
if (s[x] == pDraw->ucTransparent)
|
||||||
|
s[x] = pDraw->ucBackground;
|
||||||
|
}
|
||||||
|
pDraw->ucHasTransparency = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply the new pixels to the main image
|
||||||
|
if (pDraw->ucHasTransparency) // if transparency used
|
||||||
|
{
|
||||||
|
uint8_t *pEnd, c, ucTransparent = pDraw->ucTransparent;
|
||||||
|
pEnd = s + iWidth;
|
||||||
|
x = 0;
|
||||||
|
iCount = 0; // count non-transparent pixels
|
||||||
|
while (x < iWidth)
|
||||||
|
{
|
||||||
|
c = ucTransparent - 1;
|
||||||
|
d = &usTemp[0][0];
|
||||||
|
while (c != ucTransparent && s < pEnd && iCount < BUFFER_SIZE)
|
||||||
|
{
|
||||||
|
c = *s++;
|
||||||
|
if (c == ucTransparent) // done, stop
|
||||||
|
{
|
||||||
|
s--; // back up to treat it like transparent
|
||||||
|
}
|
||||||
|
else // opaque
|
||||||
|
{
|
||||||
|
*d++ = usPalette[c];
|
||||||
|
iCount++;
|
||||||
|
}
|
||||||
|
} // while looking for opaque pixels
|
||||||
|
if (iCount) // any opaque pixels?
|
||||||
|
{
|
||||||
|
// DMA would degrtade performance here due to short line segments
|
||||||
|
tft.setAddrWindow(pDraw->iX + x, y, iCount, 1);
|
||||||
|
tft.pushPixels(usTemp, iCount);
|
||||||
|
x += iCount;
|
||||||
|
iCount = 0;
|
||||||
|
}
|
||||||
|
// no, look for a run of transparent pixels
|
||||||
|
c = ucTransparent;
|
||||||
|
while (c == ucTransparent && s < pEnd)
|
||||||
|
{
|
||||||
|
c = *s++;
|
||||||
|
if (c == ucTransparent)
|
||||||
|
x++;
|
||||||
|
else
|
||||||
|
s--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
s = pDraw->pPixels;
|
||||||
|
|
||||||
|
// Unroll the first pass to boost DMA performance
|
||||||
|
// Translate the 8-bit pixels through the RGB565 palette (already byte reversed)
|
||||||
|
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 // 71.6 fps (ST7796 84.5 fps)
|
||||||
|
tft.dmaWait();
|
||||||
|
tft.setAddrWindow(pDraw->iX, y, iWidth, 1);
|
||||||
|
tft.pushPixelsDMA(&usTemp[dmaBuf][0], iCount);
|
||||||
|
dmaBuf = !dmaBuf;
|
||||||
|
#else // 57.0 fps
|
||||||
|
tft.setAddrWindow(pDraw->iX, y, iWidth, 1);
|
||||||
|
tft.pushPixels(&usTemp[0][0], iCount);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
iWidth -= iCount;
|
||||||
|
// Loop if pixel buffer smaller than width
|
||||||
|
while (iWidth > 0)
|
||||||
|
{
|
||||||
|
// Translate the 8-bit pixels through the RGB565 palette (already byte reversed)
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} /* GIFDraw() */
|
||||||
7077
images/darthvader.h
Normal file
7077
images/darthvader.h
Normal file
File diff suppressed because it is too large
Load Diff
57196
images/hud_1.h
Normal file
57196
images/hud_1.h
Normal file
File diff suppressed because it is too large
Load Diff
45061
images/hud_2.h
Normal file
45061
images/hud_2.h
Normal file
File diff suppressed because it is too large
Load Diff
60361
images/hud_5.h
Normal file
60361
images/hud_5.h
Normal file
File diff suppressed because it is too large
Load Diff
19389
images/hud_6.h
Normal file
19389
images/hud_6.h
Normal file
File diff suppressed because it is too large
Load Diff
55191
images/hud_7.h
Normal file
55191
images/hud_7.h
Normal file
File diff suppressed because it is too large
Load Diff
15313
images/hyperspace.h
Normal file
15313
images/hyperspace.h
Normal file
File diff suppressed because it is too large
Load Diff
23045
images/nostromo.h
Normal file
23045
images/nostromo.h
Normal file
File diff suppressed because it is too large
Load Diff
26996
images/x_wing.h
Normal file
26996
images/x_wing.h
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user