acid-drop- Hacking the planet from a LilyGo T-Deck using custom firmware |
git clone git://git.acid.vegas/acid-drop.git |
Log | Files | Refs | Archive | README | LICENSE |
Sprite_draw_4bit.ino (5760B)
1 /* 2 Sketch to show how a 4 bit Sprite is created, how to draw pixels 3 and text within the Sprite and then push the Sprite onto 4 the display screen. 5 6 The advantage of 4 bit sprites is: 7 1. Small memory footprint 8 2. Any set of 16 colours can be specified 9 3. Colours can be changed without redrawing in Sprite 10 4. Simple animations like flashing text can be achieved 11 by colour palette cycling and pushing sprite to TFT: 12 https://en.wikipedia.org/wiki/Color_cycling 13 14 Example for library: 15 https://github.com/Bodmer/TFT_eSPI 16 17 A Sprite is notionally an invisible graphics screen that is 18 kept in the processors RAM. Graphics can be drawn into the 19 Sprite just as it can be drawn directly to the screen. Once 20 the Sprite is completed it can be plotted onto the screen in 21 any position. If there is sufficient RAM then the Sprite can 22 be the same size as the screen and used as a frame buffer. 23 24 A 4 bit Sprite occupies (width * height)/2 bytes in RAM. 25 26 */ 27 28 // Set delay after plotting the sprite 29 #define DELAY 1000 30 31 // Width and height of sprite 32 #define WIDTH 128 33 #define HEIGHT 128 34 35 #include <TFT_eSPI.h> // Include the graphics library (this includes the sprite functions) 36 37 TFT_eSPI tft = TFT_eSPI(); // Declare object "tft" 38 39 TFT_eSprite spr = TFT_eSprite(&tft); // Declare Sprite object "spr" with pointer to "tft" object 40 41 42 void setup() 43 { 44 Serial.begin(115200); 45 Serial.println(); 46 47 delay(500); 48 49 // Initialise the TFT registers 50 tft.init(); 51 52 // Set the sprite colour depth to 4 53 spr.setColorDepth(4); 54 55 // Create a sprite of defined size 56 spr.createSprite(WIDTH, HEIGHT); 57 58 // Clear the TFT screen to blue 59 tft.fillScreen(TFT_BLUE); 60 } 61 62 void loop(void) 63 { 64 // Fill the whole sprite with color 0 (Sprite is in memory so not visible yet) 65 spr.fillSprite(0); 66 67 // create a color map with known colors (16 maximum for 4 bit Sprite 68 uint16_t cmap[16]; 69 70 71 cmap[0] = TFT_BLACK; // We will keep this as black 72 cmap[1] = TFT_NAVY; 73 cmap[2] = TFT_DARKGREEN; 74 cmap[3] = TFT_DARKCYAN; 75 cmap[4] = TFT_MAROON; 76 cmap[5] = TFT_PURPLE; 77 cmap[6] = TFT_PINK; 78 cmap[7] = TFT_LIGHTGREY; 79 cmap[8] = TFT_YELLOW; 80 cmap[9] = TFT_BLUE; 81 cmap[10] = TFT_GREEN; 82 cmap[11] = TFT_CYAN; 83 cmap[12] = TFT_RED; 84 cmap[13] = TFT_MAGENTA; 85 cmap[14] = TFT_WHITE; // Keep as white for text 86 cmap[15] = TFT_BLUE; // Keep as blue for sprite border 87 88 // Pass the palette to the Sprite class 89 spr.createPalette(cmap); 90 91 // Push Sprite partially off-screen to test cropping 92 spr.pushSprite(-40, -40); 93 spr.pushSprite(tft.width() / 2 - WIDTH / 2, tft.height() / 2 - HEIGHT / 2, 10); 94 spr.pushSprite(tft.width() - WIDTH + 40, tft.height() - HEIGHT + 40); 95 96 // Number of pixels to draw 97 uint16_t n = 100; 98 99 // Draw 100 random color pixels at random positions in sprite 100 while (n--) 101 { 102 uint16_t color = random(0x10); // Returns color 0 - 0x0F (i.e. 0-15) 103 int16_t x = random(WIDTH); // Random x coordinate 104 int16_t y = random(HEIGHT); // Random y coordinate 105 spr.drawPixel(x, y, color); // Draw pixel in sprite 106 } 107 108 // Draw some lines 109 spr.drawLine(1, 0, WIDTH, HEIGHT-1, 10); 110 spr.drawLine(0, 0, WIDTH, HEIGHT, 10); 111 spr.drawLine(0, 1, WIDTH-1, HEIGHT, 10); 112 spr.drawLine(0, HEIGHT-1, WIDTH-1, 0, 12); 113 spr.drawLine(0, HEIGHT, WIDTH, 0, 12); 114 spr.drawLine(1, HEIGHT, WIDTH, 1, 12); 115 116 // Draw some text with Middle Centre datum 117 spr.setTextDatum(MC_DATUM); 118 spr.setTextColor(14); // White text 119 spr.drawString("Sprite", WIDTH / 2, HEIGHT / 2, 4); 120 121 // Now push the sprite to the TFT at 3 positions on screen 122 spr.pushSprite(-40, -40); 123 spr.pushSprite(tft.width() / 2 - WIDTH / 2, tft.height() / 2 - HEIGHT / 2); 124 spr.pushSprite(tft.width() - WIDTH + 40, tft.height() - HEIGHT + 40); 125 126 delay(DELAY * 4); 127 128 // create a new color map for colours 1-13 and use it instead 129 for (auto i = 1; i <= 13; i++) 130 { 131 cmap[i] = random(0x10000); 132 } 133 134 spr.createPalette(cmap, 16); 135 // Now push the sprite to the TFT at position 0,0 on screen 136 137 spr.pushSprite(-40, -40); 138 spr.pushSprite(tft.width() / 2 - WIDTH / 2, tft.height() / 2 - HEIGHT / 2); 139 spr.pushSprite(tft.width() - WIDTH + 40, tft.height() - HEIGHT + 40); 140 141 delay(DELAY); 142 143 // Fill TFT screen with blue 144 tft.fillScreen(TFT_BLUE); 145 146 // Draw a blue rectangle in sprite so when we move it 1 pixel it does not leave a trail 147 // on the blue screen background 148 spr.createPalette(cmap); 149 150 spr.drawRect(0, 0, WIDTH, HEIGHT, 15); // Blue rectangle 151 152 int x = tft.width() / 2 - WIDTH / 2; 153 int y = tft.height() / 2 - HEIGHT / 2; 154 155 uint32_t updateTime = 0; // time for next update 156 157 while (true) 158 { 159 // Random movement direction 160 int dx = 1; if (random(2)) dx = -1; 161 int dy = 1; if (random(2)) dy = -1; 162 163 // Pull it back onto screen if it wanders off 164 if (x < -WIDTH/2) dx = 1; 165 if (x >= tft.width()-WIDTH/2) dx = -1; 166 if (y < -HEIGHT/2) dy = 1; 167 if (y >= tft.height()-HEIGHT/2) dy = -1; 168 169 // Randomise the palette to change colours without redrawing 170 // the sprite 171 for (auto i = 1; i <= 13; i++) 172 { 173 cmap[i] = random(0x10000); 174 } 175 spr.createPalette(cmap); // Update sprite class palette 176 177 // Draw it 50 times, moving in random direct or staying still 178 n = 50; 179 int wait = random (50); 180 while (n) 181 { 182 if (updateTime <= millis()) 183 { 184 // Use time delay so sprite does not move fast when not all on screen 185 updateTime = millis() + wait; 186 187 // Push the sprite to the TFT screen 188 spr.pushSprite(x, y); 189 190 // Change coord for next loop 191 x += dx; 192 y += dy; 193 n--; 194 yield(); // Stop watchdog reset 195 } 196 } 197 } // Infinite while, will not exit! 198 }