From 484a4a8d6b3ca46ec8e37bce621933829566c28d Mon Sep 17 00:00:00 2001 From: "Mr.Blinky" Date: Wed, 23 Feb 2022 02:09:50 +0100 Subject: [PATCH] Remove double drawballs sketch --- .../ArduboyFX/drawballs/drawballs.ino | 179 ------------------ board-package/arduboy-homemade-1.3.1.zip | Bin 1324956 -> 1321816 bytes package_arduboy_homemade_index.json | 4 +- 3 files changed, 2 insertions(+), 181 deletions(-) delete mode 100644 board-package-source/libraries/ArduboyFX/drawballs/drawballs.ino diff --git a/board-package-source/libraries/ArduboyFX/drawballs/drawballs.ino b/board-package-source/libraries/ArduboyFX/drawballs/drawballs.ino deleted file mode 100644 index e54548a..0000000 --- a/board-package-source/libraries/ArduboyFX/drawballs/drawballs.ino +++ /dev/null @@ -1,179 +0,0 @@ -/* ***************************************************************************** - * FX draw balls test v1.16 by Mr.Blinky May 2019 Feb 2022 licenced under CC0 - * ***************************************************************************** - * - * Before this example sketch is uploaded and run on the Arduboy FX, make sure - * the fxdata 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 - * Phyton script and the fxdata.bin file can be uploaded using the uploader-gui.py, - * fxdata-upload.py or flash-writer.py Python script using the -d switch. - * - * This demo draws a moving background tilemap with a bunch of bouncing ball sprites. - * - * Button controls: - * - * A - increase the number of bounching balls up to MAX_BALLS - * B - decrease the number of balls down to zero - * - * D-Pad - scroll the background - * - */ - -#include -#include // Required library for accessing the FX flash chip -#include "fxdata.h" // this file contains all the references to FX data - // Check out fxdata.txt to see how this is done. -#define FRAME_RATE 60 - -#define MAX_BALLS 55 // 55 Balls possible at 60fps 155 at 30fps -#define CIRCLE_POINTS 84 -#define VISABLE_TILES_PER_COLUMN 5 // the maximum number of tiles visable vertically -#define VISABLE_TILES_PER_ROW 9 // the maximum number of tiles visable horizontally - -//datafile offsets -constexpr uint8_t ballWidth = 16; -constexpr uint8_t ballHeight = 16; -constexpr uint8_t tilemapWidth = 16; // number of tiles in a tilemap row -constexpr uint8_t tileWidth = 16; -constexpr uint8_t tileHeight = 16; - -Arduboy2 arduboy; - -Point circlePoints[CIRCLE_POINTS] = // all the points of a circle with radius 15 used for the circling background effect -{ - {-15,0}, {-15,1}, {-15,2}, {-15,3}, {-15,4}, {-14,5}, {-14,6}, {-13,7}, {-13,8}, {-12,9}, {-11,10}, {-10,11}, {-9,12}, {-8,13}, {-7,13}, {-6,14}, - {-5,14}, {-4,14}, {-3,15}, {-2,15}, {-1,15}, {0,15}, {1,15}, {2,15}, {3,15}, {4,14}, {5,14}, {6,14}, {7,13}, {8,13}, {9,12}, {10,11}, - {11,10}, {12,9}, {12,8}, {13,7}, {13,6}, {14,5}, {14,4}, {14,3}, {14,2}, {14,1}, {15,0}, {15,-1}, {15,-2}, {15,-3}, {15,-4}, {14,-5}, - {14,-6}, {13,-7}, {13,-8}, {12,-9}, {11,-10}, {10,-11}, {9,-12}, {8,-13}, {7,-13}, {6,-14}, {5,-14}, {4,-14}, {3,-15}, {2,-15}, {1,-15}, {0,-15}, - {-1,-15}, {-2,-15}, {-3,-15}, {-4,-14}, {-5,-14}, {-6,-14}, {-7,-13}, {-8,-13}, {-9,-12}, {-10,-11}, {-11,-10}, {-12,-9}, {-12,-8}, {-13,-7}, {-13,-6}, {-14,-5}, - {-14,-4}, {-14,-3}, {-14,-2}, {-14,-1} -}; - -Point camera; -Point mapLocation = {16,16}; - -struct Ball -{ - int8_t x; - int8_t y; - int8_t xspeed; - int8_t yspeed; -}; - -Ball ball[MAX_BALLS]; -uint8_t ballsVisible = MAX_BALLS; - -uint8_t pos; - -void setup() { - arduboy.begin(); - arduboy.setFrameRate(FRAME_RATE); - FX::begin(FX_DATA_PAGE); // wakeup external flash chip, initialize datapage, detect presence of external flash chip - - for (uint8_t i=0; i < MAX_BALLS; i++) // initialize ball sprites - { - ball[i].x = random(113); - ball[i].y = random(49); - ball[i].xspeed = 1;//random(1,3); - if (random(100) > 49) ball[i].xspeed = -ball[i].xspeed; - ball[i].yspeed = 1; //random(1,3); - if (random(100) > 49) ball[i].yspeed = -ball[i].yspeed; - } -} - -uint8_t tilemapBuffer[VISABLE_TILES_PER_ROW]; // a small buffer to store one horizontal row of tiles from the tilemap - -void loop() { - if (!arduboy.nextFrame()) return; // return until it's time to draw a new frame - - arduboy.pollButtons(); // pollButtons required for the justPressed() function - if ((arduboy.justPressed(A_BUTTON) && ballsVisible < MAX_BALLS)) ballsVisible++; // Pressing A button increases the number of visible balls until the maximum has been reached - if ((arduboy.justPressed(B_BUTTON) && ballsVisible > 0)) ballsVisible--; // Pressing B reduces the number of visible balls until none are visible - if (arduboy.pressed(UP_BUTTON) && mapLocation.y > 16) mapLocation.y--; // Pressing directional buttons will scroll the tilemap - if (arduboy.pressed(DOWN_BUTTON) && mapLocation.y < 176) mapLocation.y++; - if (arduboy.pressed(LEFT_BUTTON) && mapLocation.x > 16) mapLocation.x--; - if (arduboy.pressed(RIGHT_BUTTON) && mapLocation.x < 112) mapLocation.x++; - - camera.x = mapLocation.x + circlePoints[pos].x; // circle around a fixed point - camera.y = mapLocation.y + circlePoints[pos].y; - - //draw tilemap - for (int8_t y = 0; y < VISABLE_TILES_PER_COLUMN; y++) - { - FX::readDataArray(FX_DATA_TILEMAP, // read the visible tiles on a horizontal row from the tilemap in external flash - y + camera.y / tileHeight, // the tilemap row - camera.x / tileWidth, // the column within tilemap row - tilemapWidth, // use the width of tilemap as array element size - tilemapBuffer, // reading tiles into a small buffer is faster then reading each tile individually - VISABLE_TILES_PER_ROW); - - for (uint8_t x = 0; x < VISABLE_TILES_PER_ROW; x++) - { - FX::drawBitmap(x * tileWidth - camera.x % tileWidth, // we're substracting the tile width and height modulus for scrolling effect - y * tileHeight - camera.y % tileHeight, // - FX_DATA_TILES, // the tilesheet bitmap offset in external flash - tilemapBuffer[x], // tile index - dbmNormal); // draw a row of normal tiles - } - } - if (arduboy.notPressed(UP_BUTTON | DOWN_BUTTON | LEFT_BUTTON | RIGHT_BUTTON)) pos = ++pos % CIRCLE_POINTS; //only circle around when no directional buttons are pressed - - //draw balls - for (uint8_t i=0; i < ballsVisible; i++) - FX::drawBitmap(ball[i].x, // although this function is called drawBitmap it can also draw masked sprites - ball[i].y, - FX_DATA_BALLS, // the ball sprites masked bitmap offset in external flash memory - 0, // the fxdata was build using the single ball sprite.png image so there's only frame 0 - //i % 16, // comment above and uncomment this one if the fxdata is rebuild using the ball_16x16.png image - dbmMasked /* | dbmReverse */ ); // remove the '/*' and '/*' to reverse the balls into white balls - - //when uploading the drawballs-singe-datafile.bin into the development area, - //you can replace the "0" value in the drawBitmap function above with "i % 16" without the quotes to display 16 different balls - - //update ball movements - for (uint8_t i=0; i < ballsVisible; i++) - { - if (ball[i].xspeed > 0) // Moving right - { - ball[i].x += ball[i].xspeed; - if (ball[i].x > WIDTH - ballWidth) //off the right - { - ball[i].x = WIDTH - ballWidth; - ball[i].xspeed = - ball[i].xspeed; - } - } - else // moving left - { - ball[i].x += ball[i].xspeed; - if (ball[i].x < 0) // off the left - { - ball[i].x = 0; - ball[i].xspeed = - ball[i].xspeed; - } - } - if (ball[i].yspeed > 0) // moving down - { - ball[i].y += ball[i].yspeed; - if (ball[i].y > HEIGHT - tileHeight) // off the bottom - { - ball[i].y = HEIGHT - tileHeight; - ball[i].yspeed = - ball[i].yspeed; - } - } - else // moving up - { - ball[i].y += ball[i].yspeed; - if (ball[i].y < 0) // off the top - { - ball[i].y = 0; - ball[i].yspeed = - ball[i].yspeed; - } - } - } - - FX::display(CLEAR_BUFFER); // Using CLEAR_BUFFER will clear the display buffer after it is displayed -} diff --git a/board-package/arduboy-homemade-1.3.1.zip b/board-package/arduboy-homemade-1.3.1.zip index d7db7051f6cf323ba594cd27406c6a69dd929b22..6f05ffb6665ee55338b939f6b86096dcee76af0b 100644 GIT binary patch delta 6904 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 UJlbw-H|Ao&&!;iKgntYE4