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 }