/* ***************************************************************************** * 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 // required to build for Arduboy #include // 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 }