Skip to content

Commit

Permalink
Add alternative boot logo functions
Browse files Browse the repository at this point in the history
New functions bootLogoCompressed(), bootLogoSpritesSelfMasked() and
bootLogoSpritesOverwrite() can be used in place of bootLogo() to
reduce code size in cases where their drawing functions are shared
with the same functions used by the sketch.

New function bootLogoShell() added to provide common code for the
above functions.

Also, the Sprites class functions, and functions used for drawing the
logos, were made static.
  • Loading branch information
MLXXXp committed Apr 25, 2017
1 parent 79f24c4 commit 449532f
Show file tree
Hide file tree
Showing 6 changed files with 210 additions and 44 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,7 @@ This saves whatever code *blank()*, *systemButtons()* and *bootLogo()* would use
There are a few functions provided that are roughly equivalent to the standard functions used by *begin()* but which use less code space.
- *bootLogoCompressed()*, *bootLogoSpritesSelfMasked()* and *bootLogoSpritesOverwrite()* will do the same as *bootLogo()* but will use *drawCompressed()*, or *Sprites* class *drawSelfMasked()* or *drawOverwrite()*, functions respectively, instead of *drawBitmask()*, to render the logo. If the sketch uses one of these functions, then using the boot logo function that also uses it may reduce code size. It's best to try each of them to see which one produces the smallest size.
- *bootLogoText()* can be used in place *bootLogo()* in the case where the sketch uses text functions. It renders the logo as text instead of as a bitmap (so doesn't look as good).
- *safeMode()* can be used in place of *flashlight()* for cases where it's needed to allow uploading a new sketch when the bootloader "magic key" problem is an issue. It only lights the red RGB LED, so you don't get the bright light that is the primary purpose of *flashlight()*.
Expand Down
4 changes: 4 additions & 0 deletions keywords.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ begin KEYWORD2
blank KEYWORD2
boot KEYWORD2
bootLogo KEYWORD2
bootLogoCompressed KEYWORD2
bootLogoShell KEYWORD2
bootLogoSpritesOverwrite KEYWORD2
bootLogoSpritesSelfMasked KEYWORD2
bootLogoText KEYWORD2
buttonsState KEYWORD2
clear KEYWORD2
Expand Down
50 changes: 45 additions & 5 deletions src/Arduboy2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,13 +97,53 @@ void Arduboy2Base::sysCtrlSound(uint8_t buttons, uint8_t led, uint8_t eeVal)
}
}

// bootLogoText() should be kept in sync with bootLogo()
// if changes are made to one, equivalent changes should be made to the other
void Arduboy2Base::bootLogo()
{
bootLogoShell(drawLogoBitmap);
}

void Arduboy2Base::drawLogoBitmap(int16_t y)
{
drawBitmap(20, y, arduboy_logo, 88, 16);
}

void Arduboy2Base::bootLogoCompressed()
{
bootLogoShell(drawLogoCompressed);
}

void Arduboy2Base::drawLogoCompressed(int16_t y)
{
drawCompressed(20, y, arduboy_logo_compressed);
}

void Arduboy2Base::bootLogoSpritesSelfMasked()
{
bootLogoShell(drawLogoSpritesSelfMasked);
}

void Arduboy2Base::drawLogoSpritesSelfMasked(int16_t y)
{
Sprites::drawSelfMasked(20, y, arduboy_logo_sprite, 0);
}

void Arduboy2Base::bootLogoSpritesOverwrite()
{
bootLogoShell(drawLogoSpritesOverwrite);
}

void Arduboy2Base::drawLogoSpritesOverwrite(int16_t y)
{
Sprites::drawOverwrite(20, y, arduboy_logo_sprite, 0);
}

// bootLogoText() should be kept in sync with bootLogoShell()
// if changes are made to one, equivalent changes should be made to the other
void Arduboy2Base::bootLogoShell(void (*drawLogo)(int16_t))
{
digitalWriteRGB(RED_LED, RGB_ON);

for (int8_t y = -18; y <= 24; y++) {
for (int16_t y = -18; y <= 24; y++) {
if (pressed(RIGHT_BUTTON)) {
digitalWriteRGB(RGB_OFF, RGB_OFF, RGB_OFF); // all LEDs off
return;
Expand All @@ -119,7 +159,7 @@ void Arduboy2Base::bootLogo()
}

clear();
drawBitmap(20, y, arduboy_logo, 88, 16, WHITE);
(*drawLogo)(y); // call the function that actually draws the logo
display();
delay(27);
// longer delay post boot, we put it inside the loop to
Expand Down Expand Up @@ -1010,7 +1050,7 @@ Arduboy2::Arduboy2()
textWrap = 0;
}

// bootLogoText() should be kept in sync with bootLogo()
// bootLogoText() should be kept in sync with bootLogoShell()
// if changes are made to one, equivalent changes should be made to the other
void Arduboy2::bootLogoText()
{
Expand Down
90 changes: 82 additions & 8 deletions src/Arduboy2.h
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ class Arduboy2Base : public Arduboy2Core
void systemButtons();

/** \brief
* Display the boot logo sequence.
* Display the boot logo sequence using `drawBitmap()`.
*
* \details
* This function is called by `begin()` and can be called by a sketch
Expand All @@ -258,11 +258,78 @@ class Arduboy2Base : public Arduboy2Core
* which derived classes can implement to add additional information to the
* logo screen. The `Arduboy2` class uses this to display the unit name.
*
* \see begin() boot() Arduboy2::bootLogoExtra() Arduboy2::bootLogoText()
* \see begin() boot() Arduboy2::bootLogoExtra() bootLogoShell()
* Arduboy2::bootLogoText()
*/
void bootLogo();

// Called by bootLogo() to allow derived classes to display additional
/** \brief
* Display the boot logo sequence using `drawCompressed()`.
*
* \details
* This function can be called by a sketch after `boot()` as an alternative to
* `bootLogo()`. This may reduce code size if the sketch itself uses
* `drawCompressed()`.
*
* \see bootLogo() begin() boot()
*/
void bootLogoCompressed();

/** \brief
* Display the boot logo sequence using the `Sprites` class
* `drawSelfMasked()` function.
*
* \details
* This function can be called by a sketch after `boot()` as an alternative to
* `bootLogo()`. This may reduce code size if the sketch itself uses
* `Sprites` class functions.
*
* \see bootLogo() begin() boot() Sprites
*/
void bootLogoSpritesSelfMasked();

/** \brief
* Display the boot logo sequence using the `Sprites` class
* `drawOverwrite()` function.
*
* \details
* This function can be called by a sketch after `boot()` as an alternative to
* `bootLogo()`. This may reduce code size if the sketch itself uses
* `Sprites` class functions.
*
* \see bootLogo() begin() boot() Sprites
*/
void bootLogoSpritesOverwrite();

/** \brief
* Display the boot logo sequence using the provided function
*
* \param drawLogo A reference to a function which will draw the boot logo
* at the given Y position.
*
* \details
* This common function executes the sequence to display the boot logo.
* It is called by `bootLogo()` and other similar functions which provide it
* with a reference to a function which will do the actual drawing of the
* logo.
*
* The prototype for the function provided to draw the logo is:
* \code
* void drawLogo(int16_t y);
* \endcode
*
* The y parameter is the Y offset for the top of the logo. It is expected
* that the logo will be 16 pixels high and centered horizontally. This will
* result in the logo stopping in the middle of the screen at the end of the
* sequence. If the logo height is not 16 pixels, the Y value can be adjusted
* to compensate.
*
* \see bootLogo() boot()
*/
void bootLogoShell(void (*drawLogo)(int16_t));

// Called by bootLogoShell() to allow derived classes to display additional
// information after the logo stops scrolling down.
virtual void bootLogoExtra();

Expand Down Expand Up @@ -495,7 +562,7 @@ class Arduboy2Base : public Arduboy2Core
*
* The array must be located in program memory by using the PROGMEM modifier.
*/
void drawBitmap(int16_t x, int16_t y, const uint8_t *bitmap, uint8_t w, uint8_t h, uint8_t color = WHITE);
static void drawBitmap(int16_t x, int16_t y, const uint8_t *bitmap, uint8_t w, uint8_t h, uint8_t color = WHITE);

/** \brief
* Draw a bitmap from a horizontally oriented array in program memory.
Expand Down Expand Up @@ -533,6 +600,7 @@ class Arduboy2Base : public Arduboy2Core
* \param sy The Y coordinate of the top left pixel affected by the bitmap.
* \param bitmap A pointer to the compressed bitmap array in program memory.
* \param color The color of pixels for bits set to 1 in the bitmap.
* (optional; defaults to WHITE).
*
* \details
* Draw a bitmap starting at the given coordinates from an array that has
Expand All @@ -547,7 +615,7 @@ class Arduboy2Base : public Arduboy2Core
*
* The array must be located in program memory by using the PROGMEM modifier.
*/
void drawCompressed(int16_t sx, int16_t sy, const uint8_t *bitmap, uint8_t color = WHITE);
static void drawCompressed(int16_t sx, int16_t sy, const uint8_t *bitmap, uint8_t color = WHITE);

/** \brief
* Get a pointer to the display buffer in RAM.
Expand Down Expand Up @@ -1040,6 +1108,12 @@ class Arduboy2Base : public Arduboy2Core
// helper function for sound enable/disable system control
void sysCtrlSound(uint8_t buttons, uint8_t led, uint8_t eeVal);

// functions passed to bootLogoShell() to draw the logo
static void drawLogoBitmap(int16_t y);
static void drawLogoCompressed(int16_t y);
static void drawLogoSpritesSelfMasked(int16_t y);
static void drawLogoSpritesOverwrite(int16_t y);

// For button handling
uint8_t currentButtonState;
uint8_t previousButtonState;
Expand Down Expand Up @@ -1135,7 +1209,7 @@ class Arduboy2 : public Print, public Arduboy2Base
* Show the unit name at the bottom of the boot logo screen.
*
* \details
* This function is called by `bootLogo()` and `bootlogoText()`.
* This function is called by `bootLogoShell()` and `bootlogoText()`.
*
* If a unit name has been saved in system EEPROM, it will be displayed at
* the bottom of the screen. This function pauses for a short time to allow
Expand All @@ -1147,8 +1221,8 @@ class Arduboy2 : public Print, public Arduboy2Base
* This function would not normally be called directly from within a sketch
* itself.
*
* \see readUnitName() writeUnitName() bootLogo() bootLogoText()
* writeShowUnitNameFlag() begin()
* \see readUnitName() writeUnitName() bootLogo() bootLogoShell()
* bootLogoText() writeShowUnitNameFlag() begin()
*/
virtual void bootLogoExtra();

Expand Down
26 changes: 13 additions & 13 deletions src/Sprites.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,8 @@ class Sprites
* ..O.. OOOOO OOOOO ..O..
* ..... .OOO. OOOOO O...O
*/
void drawExternalMask(int16_t x, int16_t y, const uint8_t *bitmap,
const uint8_t *mask, uint8_t frame, uint8_t mask_frame);
static void drawExternalMask(int16_t x, int16_t y, const uint8_t *bitmap,
const uint8_t *mask, uint8_t frame, uint8_t mask_frame);

/** \brief
* Draw a sprite using an array containing both image and mask values.
Expand Down Expand Up @@ -124,7 +124,7 @@ class Sprites
* ..O.. OOOOO OOOOO ..O..
* ..... .OOO. OOOOO O...O
*/
void drawPlusMask(int16_t x, int16_t y, const uint8_t *bitmap, uint8_t frame);
static void drawPlusMask(int16_t x, int16_t y, const uint8_t *bitmap, uint8_t frame);

/** \brief
* Draw a sprite by replacing the existing content completely.
Expand Down Expand Up @@ -155,7 +155,7 @@ class Sprites
* ..O.. OOOOO ..O..
* ..... OOOOO .....
*/
void drawOverwrite(int16_t x, int16_t y, const uint8_t *bitmap, uint8_t frame);
static void drawOverwrite(int16_t x, int16_t y, const uint8_t *bitmap, uint8_t frame);

/** \brief
* "Erase" a sprite.
Expand Down Expand Up @@ -186,7 +186,7 @@ class Sprites
* ..O.. OOOOO OO.OO
* ..... OOOOO OOOOO
*/
void drawErase(int16_t x, int16_t y, const uint8_t *bitmap, uint8_t frame);
static void drawErase(int16_t x, int16_t y, const uint8_t *bitmap, uint8_t frame);

/** \brief
* Draw a sprite using only the bits set to 1.
Expand Down Expand Up @@ -216,20 +216,20 @@ class Sprites
* ..O.. OOOOO OOOOO
* ..... OOOOO OOOOO
*/
void drawSelfMasked(int16_t x, int16_t y, const uint8_t *bitmap, uint8_t frame);
static void drawSelfMasked(int16_t x, int16_t y, const uint8_t *bitmap, uint8_t frame);

// Master function. Needs to be abstracted into separate function for
// every render type.
// (Not officially part of the API)
void draw(int16_t x, int16_t y,
const uint8_t *bitmap, uint8_t frame,
const uint8_t *mask, uint8_t sprite_frame,
uint8_t drawMode);
static void draw(int16_t x, int16_t y,
const uint8_t *bitmap, uint8_t frame,
const uint8_t *mask, uint8_t sprite_frame,
uint8_t drawMode);

// (Not officially part of the API)
void drawBitmap(int16_t x, int16_t y,
const uint8_t *bitmap, const uint8_t *mask,
uint8_t w, uint8_t h, uint8_t draw_mode);
static void drawBitmap(int16_t x, int16_t y,
const uint8_t *bitmap, const uint8_t *mask,
uint8_t w, uint8_t h, uint8_t draw_mode);
};

#endif
Loading

0 comments on commit 449532f

Please sign in to comment.