Arduboy-homemade-package/board-package-source/libraries/ArduboyFX/examples/drawframes/drawframes.ino

143 lines
5.6 KiB
Arduino
Raw Normal View History

/* *****************************************************************************
* FX drawDrame example v1.00 by Mr.Blinky Jan 2023 licenced under CC0
* *****************************************************************************
*
* This is a example that shows how you can draw animations from the FX external
* flash memory using the drawframes function
*
* Before this example sketch is uploaded and run on the Arduboy FX, make sure
* the fxdata used by this sketch has been build and uploaded to the Arduboy FX.
*
* If the Arduboy FX Arduino plugin has been installed you can simply choose the
* 'Build and upload Arduboy FX data' from the Arduino IDE Tools menu.
*
* Alternatively the fxdata.txt script file can be build using the fxdata-build.py
* Python script. using the command:
*
* fxdata-upload.py fxdata.txt
The created fxdata.bin file can be uploaded to your Arduboy by using the
*uploader-gui.py Python script using the command:
* fxdata-upload.py fxdata.bin
*
* On some OS you may need to type python3 infront of the script name and supply
* the full path to the script and fxdata files.
*
******************************************************************************
*
* There are 3 functions to make drawing animations of multiple bitmap images
* easier:
*
* - uint24_t FX::drawFrame(uint24_t address)
* - FX::setFrame(uint24_t frame, uint8_t repeat);
* - uint8_t FX::drawFrame();
*
* FX::drawFrame(uint24_t address)
* -------------------------------
* drawFrame is a bit like FX::drawBitmap but instead of passing the parameters
* along with the function directly, they are stored in FX memory at the given
* address. In addition to that parameters of multiple bitmaps can be stored at
* the address to draw multiple bitmaps by this function.
* the list of bitmap parameters is called a frame. The parameters are the same
* as used with FX::drawBitmap except the mode parameter. An extra flag value
* can be added to mark the end of a frame or to mark the frame as the last in
* the list of frames.
*
* this functions return the address of the next frame unless the frame is
* flagged as a last frame. In that case the function returns 0
*
* using this function has no effect on using the other frame functions.
*
* FX::setFrame(uint24_t address, uint8_t repeat)
* --------------------------------------------
* setFrame sets the current frame address and repeat value for the drawFrame
* function below.
*
* - address is the address of a frame list in FX memory.
* - repeat is number of times each frame should be repeated.
* Each frame is drawn repeat + 1 times.
*
* uint8_t FX::drawFrame()
* ------------------------
*
* drawFrame without parameters draws the current frame in the frame list set
* by the setFrame function above. When the last frame of the framelist is
* drawn and is also the last repeated frame, the current frame pointer is
* reset to start of the frame list. This effectively loops the frame list.
* the function also returns 0 in that case. This can be usedto detect the
* end of the animation.
*
******************************************************************************/
#include <Arduboy2.h> // required to build for Arduboy
#include <ArduboyFX.h> // required to access the FX external flash
#include "fxdata/fxdata.h" // this file contains all references to FX data
Arduboy2 arduboy;
enum class State : uint8_t {
init,
logo,
wait,
main,
};
State state;
uint8_t timer;
void setup() {
arduboy.boot(); // boot is used instead of begin as we don't want the Arduboy startup logo
arduboy.display(CLEAR_BUFFER); // another way to clear the display
arduboy.systemButtons(); // also do system buttons as it's normally used by begin
//arduboy.setFrameRate(60); // Only needed for frameRates other than 60
FX::begin(FX_DATA_PAGE); // initialise FX chip
state = State::init;
}
void loop() {
if (!arduboy.nextFrame()) return; // Do nothing until it's time for the next display frame
arduboy.pollButtons(); // required here for arduboy.justPressed() below
switch (state) {
//initialise animation using setFrame
case State::init:
{
FX::setFrame(ArduboyLogo_Frame, 0); // set frame list for drawFrame() and 0 repeats
state = State::logo; // changing the 0 into an higher value will
} // slow down the animation
break;
// do logo animation
case State::logo:
{ // draw a frame from the frame list and test if it was the last frame
if(!FX::drawFrame()) { // without this test the animation would loop continiously
state = State::wait; // it was the last frame go for wait state
timer = 60; // wait for 60 frames
}
}
break;
//wait and display a single frame
case State::wait:
{
FX::drawFrame(ArduboyLogo_LastFrame);
if (--timer == 0) state = State::main;
}
break;
case State::main:
{
// No special code here so the screen will turn black after the wait period
// pressing A or B button will restart the animation
if (arduboy.justPressed(A_BUTTON | B_BUTTON)) state = State::init;
}
break;
}
FX::display(CLEAR_BUFFER); // Using CLEAR_BUFFER will clear the display buffer after it is displayed
}