Go to the documentation of this file.
20 uint8_t Arduboy2Base::eachFrameMillis = 16;
21 uint8_t Arduboy2Base::thisFrameStart;
22 uint8_t Arduboy2Base::lastFrameDurationMs;
23 bool Arduboy2Base::justRendered =
false;
71 #ifndef ARDUBOY_CORE // for Arduboy core timer 0 should remain enabled
75 power_timer0_disable();
95 void Arduboy2Base::sysCtrlSound(uint8_t buttons, uint8_t led, uint8_t eeVal)
101 EEPROM.update(eepromAudioOnOff, eeVal);
114 void Arduboy2Base::drawLogoBitmap(int16_t y)
124 void Arduboy2Base::drawLogoCompressed(int16_t y)
134 void Arduboy2Base::drawLogoSpritesSelfMasked(int16_t y)
144 void Arduboy2Base::drawLogoSpritesOverwrite(int16_t y)
154 void Arduboy2Base::drawLogoSpritesBSelfMasked(int16_t y)
164 void Arduboy2Base::drawLogoSpritesBOverwrite(int16_t y)
183 for (int16_t y = -15; y <= 24; y++) {
189 if (showLEDs && y == 4) {
224 eachFrameMillis = 1000 / rate;
229 eachFrameMillis = duration;
239 uint8_t now = (uint8_t) millis();
240 uint8_t frameDurationMs = now - thisFrameStart;
243 lastFrameDurationMs = frameDurationMs;
244 justRendered =
false;
247 else if (frameDurationMs < eachFrameMillis) {
250 if (++frameDurationMs < eachFrameMillis) {
259 thisFrameStart = now;
270 if (lastFrameDurationMs > eachFrameMillis)
280 return lastFrameDurationMs*100 / eachFrameMillis;
297 if (x < 0 || x > (
WIDTH-1) || y < 0 || y > (
HEIGHT-1))
316 "andi %A[y], 0xf8 \n"
317 "mul %[width_offset], %A[y] \n"
318 "movw %[row_offset], r0 \n"
319 "clr __zero_reg__ \n"
320 "add %A[row_offset], %[x] \n"
322 "adc %B[row_offset], __zero_reg__ \n"
324 : [row_offset]
"=&x" (row_offset),
327 : [width_offset]
"r" ((uint8_t)(
WIDTH/8)),
331 uint8_t data =
sBuffer[row_offset] | bit;
332 if (!(color & _BV(0))) data ^= bit;
339 if (x < 0 || x > (
WIDTH-1) || y < 0 || y > (
HEIGHT-1))
348 row_offset = (y & 0xF8) *
WIDTH / 8 + x;
349 uint8_t data =
sBuffer[row_offset] | bit;
350 if (!color) data ^= bit;
358 uint8_t bit_position = y % 8;
359 return (
sBuffer[(row*
WIDTH) + x] & _BV(bit_position)) >> bit_position;
366 int16_t ddF_y = -2 * r;
399 void Arduboy2Base::drawCircleHelper
400 (int16_t x0, int16_t y0, uint8_t r, uint8_t corners, uint8_t color)
404 int16_t ddF_y = -2 * r;
447 fillCircleHelper(x0, y0, r, 3, 0, color);
450 void Arduboy2Base::fillCircleHelper
451 (int16_t x0, int16_t y0, uint8_t r, uint8_t sides, int16_t delta,
456 int16_t ddF_y = -2 * r;
488 (int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint8_t color)
491 bool steep = abs(y1 - y0) > abs(x1 - x0);
506 int16_t err = dx / 2;
518 for (; x0 <= x1; x0++)
539 (int16_t x, int16_t y, uint8_t w, uint8_t h, uint8_t color)
548 (int16_t x, int16_t y, uint8_t h, uint8_t color)
551 for (
int a = max(0,y); a < min(end,
HEIGHT); a++)
558 (int16_t x, int16_t y, uint8_t w, uint8_t color)
569 if (xEnd <= 0 || x >=
WIDTH)
584 register uint8_t *pBuf =
sBuffer + ((y / 8) *
WIDTH) + x;
587 register uint8_t mask = 1 << (y & 7);
609 (int16_t x, int16_t y, uint8_t w, uint8_t h, uint8_t color)
612 for (int16_t i=x; i<x+w; i++)
643 "cpse %[color], __zero_reg__\n"
644 "ldi %[color], 0xFF\n"
659 : [color]
"+d" (color),
667 (int16_t x, int16_t y, uint8_t w, uint8_t h, uint8_t r, uint8_t color)
675 drawCircleHelper(x+r, y+r, r, 1, color);
676 drawCircleHelper(x+w-r-1, y+r, r, 2, color);
677 drawCircleHelper(x+w-r-1, y+h-r-1, r, 4, color);
678 drawCircleHelper(x+r, y+h-r-1, r, 8, color);
682 (int16_t x, int16_t y, uint8_t w, uint8_t h, uint8_t r, uint8_t color)
688 fillCircleHelper(x+w-r-1, y+r, r, 1, h-2*r-1, color);
689 fillCircleHelper(x+r, y+r, r, 2, h-2*r-1, color);
693 (int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2, uint8_t color)
701 (int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2, uint8_t color)
704 int16_t a, b, y, last;
708 swapInt16(y0, y1); swapInt16(x0, x1);
712 swapInt16(y2, y1); swapInt16(x2, x1);
716 swapInt16(y0, y1); swapInt16(x0, x1);
742 int16_t dx01 = x1 - x0,
767 for(y = y0; y <= last; y++)
784 sa = dx12 * (y - y1);
785 sb = dx02 * (y - y0);
804 (int16_t x, int16_t y,
const uint8_t *bitmap, uint8_t w, uint8_t h,
808 if (x + w <= 0 || x >
WIDTH - 1 || y + h <= 0 || y >
HEIGHT - 1)
811 int yOffset = abs(y) % 8;
815 yOffset = 8 - yOffset;
819 for (
int a = 0; a < rows; a++) {
821 if (bRow > (
HEIGHT/8)-1)
break;
823 for (
int iCol = 0; iCol<w; iCol++) {
824 if (iCol + x > (
WIDTH-1))
break;
828 sBuffer[(bRow*
WIDTH) + x + iCol] |= pgm_read_byte(bitmap+(a*w)+iCol) << yOffset;
829 else if (color ==
BLACK)
830 sBuffer[(bRow*
WIDTH) + x + iCol] &= ~(pgm_read_byte(bitmap+(a*w)+iCol) << yOffset);
832 sBuffer[(bRow*
WIDTH) + x + iCol] ^= pgm_read_byte(bitmap+(a*w)+iCol) << yOffset;
834 if (yOffset && bRow<(
HEIGHT/8)-1 && bRow > -2) {
836 sBuffer[((bRow+1)*
WIDTH) + x + iCol] |= pgm_read_byte(bitmap+(a*w)+iCol) >> (8-yOffset);
837 else if (color ==
BLACK)
838 sBuffer[((bRow+1)*
WIDTH) + x + iCol] &= ~(pgm_read_byte(bitmap+(a*w)+iCol) >> (8-yOffset));
840 sBuffer[((bRow+1)*
WIDTH) + x + iCol] ^= pgm_read_byte(bitmap+(a*w)+iCol) >> (8-yOffset);
850 (int16_t x, int16_t y,
const uint8_t *bitmap, uint8_t w, uint8_t h, uint8_t color)
853 if (x + w <= 0 || x >
WIDTH - 1 || y + h <= 0 || y >
HEIGHT - 1)
856 int16_t xi, yi, byteWidth = (w + 7) / 8;
857 for(yi = 0; yi < h; yi++) {
858 for(xi = 0; xi < w; xi++ ) {
859 if(pgm_read_byte(bitmap + yi * byteWidth + xi / 8) & (128 >> (xi & 7))) {
867 class Arduboy2Base::BitStreamReader
870 const uint8_t *source;
871 uint16_t sourceIndex;
876 BitStreamReader(
const uint8_t *bitmap)
877 : source(bitmap), sourceIndex(), bitBuffer(), byteBuffer()
881 uint16_t readBits(uint16_t bitCount)
884 for (uint16_t i = 0; i < bitCount; i++)
889 byteBuffer = pgm_read_byte(&source[sourceIndex]);
893 if ((byteBuffer & bitBuffer) != 0)
905 BitStreamReader cs(bitmap);
908 int width = (int)cs.readBits(8) + 1;
909 int height = (int)cs.readBits(8) + 1;
910 uint8_t spanColour = (uint8_t)cs.readBits(1);
917 int yOffset = abs(sy) % 8;
918 int startRow = sy / 8;
921 yOffset = 8 - yOffset;
928 int columnOffset = 0;
932 while (rowOffset < rows)
934 uint16_t bitLength = 1;
935 while (cs.readBits(1) == 0)
938 uint16_t len = cs.readBits(bitLength) + 1;
941 for (uint16_t i = 0; i < len; ++i)
950 int bRow = startRow + rowOffset;
953 if ((bRow <= (
HEIGHT / 8) - 1) && (bRow > -2) &&
954 (columnOffset + sx <= (
WIDTH - 1)) && (columnOffset + sx >= 0))
956 int16_t offset = (bRow *
WIDTH) + sx + columnOffset;
959 int16_t index = offset;
960 uint8_t value =
byte << yOffset;
967 if ((yOffset != 0) && (bRow < (
HEIGHT / 8) - 1))
969 int16_t index = offset +
WIDTH;
970 uint8_t value =
byte >> (8 - yOffset);
981 if (columnOffset >=
width)
1045 return ((point.
x >= rect.
x) && (point.
x < rect.
x + rect.
width) &&
1046 (point.
y >= rect.
y) && (point.
y < rect.
y + rect.
height));
1051 return !(rect2.
x >= rect1.
x + rect1.
width ||
1052 rect2.
x + rect2.
width <= rect1.
x ||
1053 rect2.
y >= rect1.
y + rect1.
height ||
1054 rect2.
y + rect2.
height <= rect1.
y);
1059 return EEPROM.read(eepromUnitID) |
1060 (((uint16_t)(EEPROM.read(eepromUnitID + 1))) << 8);
1065 EEPROM.update(eepromUnitID, (uint8_t)(
id & 0xff));
1066 EEPROM.update(eepromUnitID + 1, (uint8_t)(
id >> 8));
1073 uint8_t src = eepromUnitName;
1077 val = EEPROM.read(src);
1080 if (val == 0x00 || (
byte)val == 0xFF) {
1092 uint8_t dest = eepromUnitName;
1096 if (name[src] == 0x00) {
1100 EEPROM.update(dest, done ? 0x00 : name[src]);
1107 return (EEPROM.read(eepromSysFlags) & sysFlagShowLogoMask);
1112 uint8_t flags = EEPROM.read(eepromSysFlags);
1114 bitWrite(flags, sysFlagShowLogoBit, val);
1115 EEPROM.update(eepromSysFlags, flags);
1120 return (EEPROM.read(eepromSysFlags) & sysFlagUnameMask);
1125 uint8_t flags = EEPROM.read(eepromSysFlags);
1127 bitWrite(flags, sysFlagUnameBit, val);
1128 EEPROM.update(eepromSysFlags, flags);
1133 return (EEPROM.read(eepromSysFlags) & sysFlagShowLogoLEDsMask);
1138 uint8_t flags = EEPROM.read(eepromSysFlags);
1140 bitWrite(flags, sysFlagShowLogoLEDsBit, val);
1141 EEPROM.update(eepromSysFlags, flags);
1144 void Arduboy2Base::swapInt16(int16_t& a, int16_t& b)
1156 int16_t Arduboy2::cursor_x = 0;
1157 int16_t Arduboy2::cursor_y = 0;
1158 uint8_t Arduboy2::textColor =
WHITE;
1159 uint8_t Arduboy2::textBackground =
BLACK;
1160 uint8_t Arduboy2::textSize = 1;
1161 bool Arduboy2::textWrap =
false;
1162 bool Arduboy2::textRaw =
false;
1249 for (int16_t y = -15; y <= 24; y++) {
1255 if (showLEDs && y == 4) {
1266 print(F(
"ARDUBOY"));
1291 c = EEPROM.read(eepromUnitName);
1293 if (c != 0xFF && c != 0x00)
1295 uint8_t i = eepromUnitName;
1302 c = EEPROM.read(++i);
1313 if ((c ==
'\r') && !textRaw)
1318 if (((c ==
'\n') && !textRaw) ||
1319 (textWrap && (cursor_x > (
WIDTH - (characterWidth * textSize)))))
1322 cursor_y += fullCharacterHeight * textSize;
1325 if ((c !=
'\n') || textRaw)
1327 drawChar(cursor_x, cursor_y, c, textColor, textBackground, textSize);
1328 cursor_x += fullCharacterWidth * textSize;
1335 (int16_t x, int16_t y, uint8_t c, uint8_t color, uint8_t bg, uint8_t size)
1343 ((x + characterWidth * size - 1) < 0) ||
1344 ((y + characterHeight * size - 1) < 0)
1351 bool drawBackground = bg != color;
1352 const uint8_t* bitmap =
1353 &
font5x7[c * characterWidth * ((characterHeight + 8 - 1) / 8)];
1355 for (uint8_t i = 0; i < fullCharacterWidth; i++)
1359 if (characterHeight <= 8)
1361 column = (i < characterWidth) ? pgm_read_byte(bitmap++) : 0;
1370 for (uint8_t j = 0; j < characterHeight; j++)
1372 if (characterHeight > 8)
1376 if ((j % 8 == 0) && (i < characterWidth))
1378 column = pgm_read_byte(bitmap++);
1384 uint8_t pixelIsSet = column & 0x01;
1386 if (pixelIsSet || drawBackground)
1388 for (uint8_t a = 0; a < size; a++)
1390 for (uint8_t b = 0; b < size; b++)
1392 drawPixel(x + (i * size) + a, y + (j * size) + b,
1393 pixelIsSet ? color : bg);
1403 for (uint8_t j = characterHeight; j < fullCharacterHeight; j++)
1405 for (uint8_t a = 0; a < size; a++)
1407 for (uint8_t b = 0; b < size; b++)
1409 drawPixel(x + (i * size) + a, y + (j * size) + b, bg);
1455 textBackground = bg;
1460 return textBackground;
1466 textSize = max(1, s);
1497 cursor_x = cursor_y = 0;
static void drawFastVLine(int16_t x, int16_t y, uint8_t h, uint8_t color=WHITE)
Draw a vertical line.
static void boot()
Initialize the Arduboy's hardware.
static void display()
Copy the contents of the display buffer to the display.
static void fillRect(int16_t x, int16_t y, uint8_t w, uint8_t h, uint8_t color=WHITE)
Draw a filled-in rectangle of a specified width and height.
static uint8_t previousButtonState
Used by pollButtons() to hold the previous button state.
static void pollButtons()
Poll the buttons and track their state over time.
static void bootLogoSpritesSelfMasked()
Display the boot logo sequence using Sprites::drawSelfMasked().
static void sendLCDCommand(uint8_t command)
Send a single command byte to the display.
static void drawRoundRect(int16_t x, int16_t y, uint8_t w, uint8_t h, uint8_t r, uint8_t color=WHITE)
Draw a rectangle with rounded corners.
static void drawLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint8_t color=WHITE)
Draw a line between two specified points.
static void fillTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2, uint8_t color=WHITE)
Draw a filled-in triangle given the coordinates of each corner.
static void drawTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2, uint8_t color=WHITE)
Draw a triangle given the coordinates of each corner.
void bootLogoSpritesBOverwrite()
Display the boot logo sequence using SpritesB::drawOverwrite().
static bool everyXFrames(uint8_t frames)
Indicate if the specified number of frames has elapsed.
static void initRandomSeed()
Seed the random number generator with a random value.
static bool justPressed(uint8_t button)
Check if a button has just been pressed.
static void drawCircle(int16_t x0, int16_t y0, uint8_t r, uint8_t color=WHITE)
Draw a circle of a given radius.
static void clear()
Clear the display buffer.
static uint8_t currentButtonState
Used by pollButtons() to hold the current button state.
static uint8_t getTextBackground()
Get the currently set text background color.
static void drawCompressed(int16_t sx, int16_t sy, const uint8_t *bitmap, uint8_t color=WHITE)
Draw a bitmap from an array of compressed data.
static void setTextBackground(uint8_t bg)
Set the text background color.
static void setTextColor(uint8_t color)
Set the text foreground color.
void bootLogoSpritesSelfMasked()
Display the boot logo sequence using Sprites::drawSelfMasked().
static void idle()
Idle the CPU to save power.
static void drawPixel(int16_t x, int16_t y, uint8_t color=WHITE)
Set a single pixel in the display buffer to the specified color.
static int cpuLoad()
Return the load on the CPU as a percentage.
static uint8_t sBuffer[(HEIGHT *WIDTH)/8]
The display buffer array in RAM.
static bool nextFrameDEV()
Indicate that it's time to render the next frame, and visually indicate if the code is running slower...
static unsigned long generateRandomSeed()
Create a seed suitable for use with a pseudorandom number generator.
static void writeShowBootLogoFlag(bool val)
Write the "Show Boot Logo" flag in system EEPROM.
static void writeUnitID(uint16_t id)
Write a unit ID to system EEPROM.
static bool collide(Point point, Rect rect)
Test if a point falls within a rectangle.
virtual size_t write(uint8_t)
Write a single character at the current text cursor position.
static void setTextWrap(bool w)
Set or disable text wrap mode.
void bootLogoSpritesBSelfMasked()
Display the boot logo sequence using SpritesB::drawSelfMasked().
static void setTextRawMode(bool raw)
Set or disable text raw mode, allowing special characters to be displayed.
static void paintScreen(const uint8_t *image)
Paints an entire image directly to the display from program memory.
static constexpr uint8_t height()
Get the height of the display in pixels.
static void drawRect(int16_t x, int16_t y, uint8_t w, uint8_t h, uint8_t color=WHITE)
Draw a rectangle of a specified width and height.
static constexpr uint8_t width()
Get the width of the display in pixels.
static void bootLogoCompressed()
Display the boot logo sequence using drawCompressed().
static const PROGMEM uint8_t font5x7[]
The font used for text functions.
static Arduboy2Audio audio
An object created to provide audio control functions within this class.
static void drawSlowXYBitmap(int16_t x, int16_t y, const uint8_t *bitmap, uint8_t w, uint8_t h, uint8_t color=WHITE)
Draw a bitmap from a horizontally oriented array in program memory.
static bool nextFrame()
Indicate that it's time to render the next frame.
static bool notPressed(uint8_t buttons)
Test if the specified buttons are not pressed.
static const PROGMEM uint8_t arduboy_logo_sprite[]
The bitmap for the ARDUBOY logo in Sprites class drawSelfMasked() or drawOverwrite() format.
static void drawBitmap(int16_t x, int16_t y, const uint8_t *bitmap, uint8_t w, uint8_t h, uint8_t color=WHITE)
Draw a bitmap from an array in program memory.
static void bootLogoSpritesBOverwrite()
Display the boot logo sequence using SpritesB::drawOverwrite().
static void fillRoundRect(int16_t x, int16_t y, uint8_t w, uint8_t h, uint8_t r, uint8_t color=WHITE)
Draw a filled-in rectangle with rounded corners.
void bootLogoSpritesOverwrite()
Display the boot logo sequence using Sprites::drawOverwrite().
static uint8_t * getBuffer()
Get a pointer to the display buffer in RAM.
void begin()
Initialize the hardware, display the boot logo, provide boot utilities, etc.
static uint16_t frameCount
A counter which is incremented once per frame.
static bool pressed(uint8_t buttons)
Test if the all of the specified buttons are pressed.
static void bootLogoSpritesBSelfMasked()
Display the boot logo sequence using SpritesB::drawSelfMasked().
static uint8_t getPixel(uint8_t x, uint8_t y)
Returns the state of the given pixel in the screen buffer.
void bootLogo()
Display the boot logo sequence using drawBitmap().
An object to define a single point for collision functions.
static void clear()
Clear the display buffer and set the text cursor to location 0, 0.
static uint8_t buttonsState()
Get the current state of all buttons as a bitmask.
static uint8_t getTextSize()
Get the currently set text size.
static void begin()
Initialize the hardware, display the boot logo, provide boot utilities, etc.
static int16_t getCursorX()
Get the X coordinate of the current text cursor position.
static void setFrameDuration(uint8_t duration)
Set the frame rate, used by the frame control functions, by giving the duration of each frame.
static void bootLogoSpritesOverwrite()
Display the boot logo sequence using Sprites::drawOverwrite().
static const PROGMEM uint8_t arduboy_logo_compressed[]
The bitmap for the ARDUBOY logo in drawCompressed() format.
static bool anyPressed(uint8_t buttons)
Test if any of the specified buttons are pressed.
#define ARDUBOY_UNIT_NAME_LEN
The maximum number of characters in an unterminated unit name.
static void bootLogo()
Display the boot logo sequence using drawBitmap().
static uint8_t readUnitName(char *name)
Read the unit name from system EEPROM.
void bootLogoText()
Display the boot logo sequence using printed text instead of a bitmap.
static void flashlight()
Turn the RGB LED and display fully on to act as a small flashlight/torch.
static void fillCircle(int16_t x0, int16_t y0, uint8_t r, uint8_t color=WHITE)
Draw a filled-in circle of a given radius.
static bool readShowBootLogoFlag()
Read the "Show Boot Logo" flag in system EEPROM.
void bootLogoCompressed()
Display the boot logo sequence using drawCompressed().
static void setTextSize(uint8_t s)
Set the text character size.
static void setCursor(int16_t x, int16_t y)
Set the location of the text cursor.
static void setCursorY(int16_t y)
Set the Y coordinate of the text cursor location.
static void digitalWriteRGB(uint8_t red, uint8_t green, uint8_t blue)
Set the RGB LEDs digitally, to either fully on or fully off.
static uint8_t getTextColor()
Get the currently set text foreground color.
static void drawOverwrite(int16_t x, int16_t y, const uint8_t *bitmap, uint8_t frame)
Draw a sprite by replacing the existing content completely.
The Arduboy2Base and Arduboy2 classes and support objects and definitions.
static void setCursorX(int16_t x)
Set the X coordinate of the text cursor location.
static void begin()
Initialize the speaker based on the current mute setting.
static void delayShort(uint16_t ms) __attribute__((noinline))
Delay for the number of milliseconds, specified as a 16 bit value.
static void waitNoButtons()
Wait until all buttons have been released.
static bool getTextWrap()
Get the currently set text wrap mode.
static uint16_t readUnitID()
Read the unit ID from system EEPROM.
static void systemButtons()
Handle buttons held on startup for system control.
static void drawChar(int16_t x, int16_t y, uint8_t c, uint8_t color, uint8_t bg, uint8_t size)
Draw a single character at the specified location in the screen buffer.
static bool readShowBootLogoLEDsFlag()
Read the "Show LEDs with boot logo" flag in system EEPROM.
static bool readShowUnitNameFlag()
Read the "Show Unit Name" flag in system EEPROM.
static void setFrameRate(uint8_t rate)
Set the frame rate used by the frame control functions.
static void drawSelfMasked(int16_t x, int16_t y, const uint8_t *bitmap, uint8_t frame)
Draw a sprite using only the bits set to 1.
static void drawFastHLine(int16_t x, int16_t y, uint8_t w, uint8_t color=WHITE)
Draw a horizontal line.
static void writeShowBootLogoLEDsFlag(bool val)
Write the "Show LEDs with boot logo" flag in system EEPROM.
A rectangle object for collision functions.
static void writeUnitName(const char *name)
Write a unit name to system EEPROM.
static void fillScreen(uint8_t color=WHITE)
Fill the screen buffer with the specified color.
static bool justReleased(uint8_t button)
Check if a button has just been released.
static void drawSelfMasked(int16_t x, int16_t y, const uint8_t *bitmap, uint8_t frame)
Draw a sprite using only the bits set to 1.
static void writeShowUnitNameFlag(bool val)
Write the "Show Unit Name" flag in system EEPROM.
static const PROGMEM uint8_t arduboy_logo[]
The bitmap for the ARDUBOY logo in drawBitmap() format.
static int16_t getCursorY()
Get the Y coordinate of the current text cursor position.
static void beginDoFirst()
Helper function that calls the inital functions used by begin()
static bool getTextRawMode()
Get the current state of text raw mode.
void bootLogoExtra()
Show the unit name at the bottom of the boot logo screen.
static void drawOverwrite(int16_t x, int16_t y, const uint8_t *bitmap, uint8_t frame)
Draw a sprite by replacing the existing content completely.
static bool bootLogoShell(void(&drawLogo)(int16_t))
Display the boot logo sequence using the provided function.