From d2f8227b1a21137e2690c823d7a080729c28669c Mon Sep 17 00:00:00 2001 From: "Mr.Blinky" <4971163+MrBlinky@users.noreply.github.com> Date: Sun, 9 May 2021 22:06:58 +0200 Subject: [PATCH] update ArduboyFX library Added more example sketches to library. + minor changes --- .../libraries/ArduboyFX/README.md | 2 +- .../examples/basic-example/assets/FXlogo.png | Bin 0 -> 613 bytes .../examples/basic-example/basic-example.ino | 52 +++++ .../examples/basic-example/fxdata.bin | Bin 0 -> 234 bytes .../ArduboyFX/examples/basic-example/fxdata.h | 12 ++ .../examples/basic-example/fxdata.txt | 65 ++++++ .../examples/chompies/assets/licence.txt | 2 + .../examples/chompies/assets/map.png | Bin 0 -> 14747 bytes .../examples/chompies/assets/whale.png | Bin 0 -> 920 bytes .../ArduboyFX/examples/chompies/chompies.ino | 85 ++++++++ .../ArduboyFX/examples/chompies/fxdata.bin | Bin 0 -> 39470 bytes .../ArduboyFX/examples/chompies/fxdata.h | 13 ++ .../ArduboyFX/examples/chompies/fxdata.txt | 69 +++++++ .../examples/drawballs/drawballs.ino | 2 +- .../ArduboyFX/examples/drawballs/fxdata.txt | 194 +++++++++--------- .../libraries/ArduboyFX/library.properties | 2 +- 16 files changed, 398 insertions(+), 100 deletions(-) create mode 100644 board-package-source/libraries/ArduboyFX/examples/basic-example/assets/FXlogo.png create mode 100644 board-package-source/libraries/ArduboyFX/examples/basic-example/basic-example.ino create mode 100644 board-package-source/libraries/ArduboyFX/examples/basic-example/fxdata.bin create mode 100644 board-package-source/libraries/ArduboyFX/examples/basic-example/fxdata.h create mode 100644 board-package-source/libraries/ArduboyFX/examples/basic-example/fxdata.txt create mode 100644 board-package-source/libraries/ArduboyFX/examples/chompies/assets/licence.txt create mode 100644 board-package-source/libraries/ArduboyFX/examples/chompies/assets/map.png create mode 100644 board-package-source/libraries/ArduboyFX/examples/chompies/assets/whale.png create mode 100644 board-package-source/libraries/ArduboyFX/examples/chompies/chompies.ino create mode 100644 board-package-source/libraries/ArduboyFX/examples/chompies/fxdata.bin create mode 100644 board-package-source/libraries/ArduboyFX/examples/chompies/fxdata.h create mode 100644 board-package-source/libraries/ArduboyFX/examples/chompies/fxdata.txt diff --git a/board-package-source/libraries/ArduboyFX/README.md b/board-package-source/libraries/ArduboyFX/README.md index d6abb56..a4aa025 100644 --- a/board-package-source/libraries/ArduboyFX/README.md +++ b/board-package-source/libraries/ArduboyFX/README.md @@ -1,2 +1,2 @@ # ArduboyFX -Arduboy library for accessing external flash memory +Library for accessing the external flash memory of the Arduboy FX and home made Arduboys with a flash chip. diff --git a/board-package-source/libraries/ArduboyFX/examples/basic-example/assets/FXlogo.png b/board-package-source/libraries/ArduboyFX/examples/basic-example/assets/FXlogo.png new file mode 100644 index 0000000000000000000000000000000000000000..5af98a2b5ae6ff2ca6623bf14e5a3ec094940276 GIT binary patch literal 613 zcmeAS@N?(olHy`uVBq!ia0vp^#Xu~;!2~2%IbL@KQjEnx?oJHr&dIz4a#+$GeH|GX zHuiJ>Nn{1`ISV`@fjY!gL734qNaX`i!!J)4$B+p3wPz#C4jb?|Uwl)4SvT9k%3t7V z+OBwo1s43jBx~01S-YpPed_jwx~gh(58giZ`9WF6>7rNawjB4&&aTQTvflCb$I+vq z$MyB9jSGYFUNTljRPKJ$d*{1)9gAFBjg==sJ*yyT9?*yW^}TU#yO*uh?fzw733S9XxfAz% z=FDJLPXl?Z{qmJ>THW~{3JSMoEn6mKq4|D`U#=!d`Wes(bCzw(KmGk~O`q`Q6`K3> ztCe4QSNr8%Pd^0-j6baM&e8kcKP#RyLw)Me@0ZVat$w@x==bgW-OMjvzw?J3WW}R9 zkdWW;>IZ8@MCI)}>+ctSmY*}j*~hARd++mux*)*{xjSY5YCo(z{#d+!OMv3m1-nau PNrS=D)z4*}Q$iB}X(At_ literal 0 HcmV?d00001 diff --git a/board-package-source/libraries/ArduboyFX/examples/basic-example/basic-example.ino b/board-package-source/libraries/ArduboyFX/examples/basic-example/basic-example.ino new file mode 100644 index 0000000..f10f05c --- /dev/null +++ b/board-package-source/libraries/ArduboyFX/examples/basic-example/basic-example.ino @@ -0,0 +1,52 @@ +/* ***************************************************************************** + * FX basic example v1.0 by Mr.Blinky May 2021 licenced under CC0 + * ***************************************************************************** + * + * This is a basic example that shows how you can draw a image from FX external + * flash memory. It will draw the Arduboy FX logo and move it around the screen. + * + * This test depend on the file fxdata.bin being uploaded to the external FX flash + * chip using the uploader-gui.py or flash-writer.py Python script in the + * development area. When using the flash writer script. Use the following command: + * + * python flash-writer.py -d fxdata.bin + * + ******************************************************************************/ + +#include // required to build for Arduboy +#include // required to access the FX external flash +#include "fxdata.h" // this file contains all references to FX data + +//constant values +constexpr uint8_t FXlogoWidth = 115; +constexpr uint8_t FXlogoHeight = 16; + +Arduboy2 arduboy; + +//assign values; +int16_t x = (WIDTH - FXlogoWidth) / 2; +int16_t y = 25; +int8_t xDir = 1; +int8_t yDir = 1; + +void setup() { + arduboy.begin(); // normal initialisation with Arduboy startup logo + //arduboy.setFrameRate(60); // Only needed when frameRate != 60 + FX::disableOLED(); // OLED must be disabled before external flash is accessed. OLED display should only be enabled prior updating the display. + FX::begin(FX_DATA_PAGE); // external flash chip may be in power down mode so wake it up (Cathy bootloader puts chip into powerdown mode) +} + +void loop() { + if (!arduboy.nextFrame()) return; // Do nothing until it's time for the next frame + + //program code + FX::drawBitmap(x, y, FXlogo, 0, dbmNormal); + x += xDir; + y += yDir; + if (x == 0 || x == WIDTH - FXlogoWidth) xDir = -xDir; + if (y == 0 || y == HEIGHT - FXlogoHeight) yDir = -yDir; + + FX::enableOLED(); // only enable OLED for updating the display + arduboy.display(CLEAR_BUFFER); // Using CLEAR_BUFFER will clear the display buffer after it is displayed + FX::disableOLED(); // disable display again so external flash can be accessed at any time +} diff --git a/board-package-source/libraries/ArduboyFX/examples/basic-example/fxdata.bin b/board-package-source/libraries/ArduboyFX/examples/basic-example/fxdata.bin new file mode 100644 index 0000000000000000000000000000000000000000..21d7ede13522ac53fc3c682445faf3dde09c9aa4 GIT binary patch literal 234 zcmZQ5W)S%BV@_Xtb9>*MA0HSP{{3eL0d~GWKhQY;|1&@Ui1F`#GYA}iS7X7z@Z%33 zJ6w-_{euGy4F?|7+cPjo-1+n8-@S9k-P4n+cYl8H;K7Fq8#_6EcBcRT86f~<*8l%J zKp5TUY>zL-oD@goKye*AP77zx06AW0XmBjXd=jUGV<&|gMkbd SHa4J}7#V@?Vq;?h3IG7dQdhPB literal 0 HcmV?d00001 diff --git a/board-package-source/libraries/ArduboyFX/examples/basic-example/fxdata.h b/board-package-source/libraries/ArduboyFX/examples/basic-example/fxdata.h new file mode 100644 index 0000000..a8c9646 --- /dev/null +++ b/board-package-source/libraries/ArduboyFX/examples/basic-example/fxdata.h @@ -0,0 +1,12 @@ +#pragma once + +/**** FX data header generated by fx-data.py tool version 1.00 ****/ + +using uint24_t = __uint24; + +// Initialize FX hardware using FX::begin(FX_DATA_PAGE); in the setup() function. + +constexpr uint16_t FX_DATA_PAGE = 0xffff; +constexpr uint24_t FX_DATA_BYTES = 234; + +constexpr uint24_t FXlogo = 0x000000; diff --git a/board-package-source/libraries/ArduboyFX/examples/basic-example/fxdata.txt b/board-package-source/libraries/ArduboyFX/examples/basic-example/fxdata.txt new file mode 100644 index 0000000..f922a61 --- /dev/null +++ b/board-package-source/libraries/ArduboyFX/examples/basic-example/fxdata.txt @@ -0,0 +1,65 @@ +/******************************************************************************* + FX Data resource file. +******************************************************************************** + + Run this file through the fx-data.py Python script (drag and drop) to create + a c-style header file that can be included with your project. + + a .bin file will also be created containing the actual resource data. This .bin + file can be uploaded to the FX flash chip using the uploader-gui.py Python + script (Use Upload Development data button). + + The .bin file can also be uploaded to FX flash chip using the flash-writer.py + Python command line script using the -d switch. + + Data types: + + int8_t, uint8_t values will be stored as 8-bit bytes (unsigned char) + + int16_t, uint16_t values will be stored as 16-bit (half)words (int) + + int24_t,uint24_t values will be stored as 24-bit address that points to + a FX data resource + + int32_t,uint32_t values will be stored as 32-bit long words + + image_t a filename with a relative path to a .bmp or .png image file + raw_t a filename with a relative path to a raw file + + to create a constant to point to a FX resource, a similar format as in C(++): + is used. + + image_t FXlogo = "FX-logo.png"; + image_t FxSprite = "FXSprite.png"; + + when data of the same format is used the data type may be ommited. The semicolon + may also be ommited in all cases. + + image_t FXlogo = "FX-logo.png" + FxSprite = "FXSprite.png" + + or even: + + image_t FXlogo = "FX-logo.png", FxSprite = "FXSprite.png" + + When specifying multiple data make sure they are seperated by at least a space + (comma is optional). A data array can be simplified. For examle: + + uint8_t tilemap[] = { + 0, 1, 2, 3, 4, 5, 6 + }; + + can also be written simply as: + + uint8_t tilemap = 0 1 2 3 4 5 6 + + data can be commented out using // for a single line or + using /* */ for a block comment + +******************************************************************************** + basic example : +*******************************************************************************/ + +// Arduboy FX logo image: + +image_t FXlogo = "assets/FXlogo.png" diff --git a/board-package-source/libraries/ArduboyFX/examples/chompies/assets/licence.txt b/board-package-source/libraries/ArduboyFX/examples/chompies/assets/licence.txt new file mode 100644 index 0000000..3ab4546 --- /dev/null +++ b/board-package-source/libraries/ArduboyFX/examples/chompies/assets/licence.txt @@ -0,0 +1,2 @@ +The map and whale images were made by Arduboy community member and twitter user +2bitCrook and are shared under a CC-BY-NC-SA licence. diff --git a/board-package-source/libraries/ArduboyFX/examples/chompies/assets/map.png b/board-package-source/libraries/ArduboyFX/examples/chompies/assets/map.png new file mode 100644 index 0000000000000000000000000000000000000000..9ec0a2ac03d6b6ac8fd5fcf9a2aee477e79da88d GIT binary patch literal 14747 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 literal 0 HcmV?d00001 diff --git a/board-package-source/libraries/ArduboyFX/examples/chompies/assets/whale.png b/board-package-source/libraries/ArduboyFX/examples/chompies/assets/whale.png new file mode 100644 index 0000000000000000000000000000000000000000..70e84f8ff34ec47a1f0ee3ca69944ccd8f029435 GIT binary patch literal 920 zcmV;J184k+P)CeE5fO#|X z9FS%(%blRK0R;wDPWcmooY6cINbzVy25E!31>N()F=E$0XRqN{B z^HqvH&-vS3Aq2B>S^r5v$80%0x^mL_KooAA!(isDk{f(qI|V3hb~zNFX8aaGW=+6g z3%Mt_x)vZbbg|HVkw+-ykp>nh8+$?9>IO$f8iI=)WlF0KOTb#08?6FSOQ)vbia!9* zYVfpmtCdj|EcEJv25_@|OTR~f)Z%!uH3(^-V;HT-} zZetVrz{|UZ%oQifmcZQhHpZU#`yoHSBz zzvno0zo)NsJ-)vLsMJ@oLr)-~#jc~=U=8p?E(`o^H8(S;c#q<@!F!DU+-Jm~&$A^L znUV=%?s{bKE12*$aEp6v8Trz)YWl~3A+yVUB~+JKyxXm6H?M85*rn7Mu(#i+Tyao= zK4<-jXG!qfXijY_ngNC1tb(zyn(-O1;yGpX_=|u$6riNAUJCPD%T}LrgMldQ8kri# zUIEw$Gql{O%ekYSt|e#qngsZh%z9W=Tc*(jPm>X-?9vQQd@hM>&Hir~=`HV#LBIL< z<;lGjgc;#Jli&tR%&NJ5Yh`0*P6qu6yBenM92l#UWsjJnw8+sK8P?t#(L4B*!Zkt0 z2mmQ#^ggp@Eh+_U+!t|ei;38$lqm_@q6nHXa=9CF^F1zOG{7irY^lAMw5g_c{p|gF z=`Ug+16_5m0lk-5@ouTo?kRX?-O{8ziI8A15i@hp5;CwoOQJmeuu%<7}AncDD8QCYVqji0|$#&-Afs_Pm7hsxm u#VHJHoqBxgCdM!ffQrl_5VqY8PTYPNvTaKk)aj%E0000 // required to build for Arduboy +#include // required to access the FX external flash +#include "fxdata.h" // this file contains all references to FX data + +#define FRAME_RATE 120 + +Arduboy2 arduboy; +bool showposition = true; +uint8_t select,color; +int x [2]; +int y [2]; + +void setup() { + arduboy.begin(); + arduboy.setFrameRate(FRAME_RATE); + FX::disableOLED(); // OLED must be disabled before external flash is accessed. OLED display should only be enabled prior updating the display. + FX::begin(FX_DATA_PAGE); //external flash chip may be in power down mode so wake it up (Cathy bootloader puts chip into powerdown mode) +} + +void loop() { + if (!arduboy.nextFrame()) return; + + arduboy.pollButtons(); + if (arduboy.justPressed(B_BUTTON)) showposition = !showposition; + if (arduboy.pressed(B_BUTTON)) select = 0; + else select = 1; + if (arduboy.justPressed(A_BUTTON)) color ^= dbmReverse; + if (arduboy.pressed(A_BUTTON)) + { + if (arduboy.justPressed(UP_BUTTON)) y[select]--; + if (arduboy.justPressed(DOWN_BUTTON)) y[select]++; + if (arduboy.justPressed(LEFT_BUTTON)) x[select]--; + if (arduboy.justPressed(RIGHT_BUTTON)) x[select]++; + } + else + { + if (arduboy.pressed(UP_BUTTON)) y[select]--; + if (arduboy.pressed(DOWN_BUTTON)) y[select]++; + if (arduboy.pressed(LEFT_BUTTON)) x[select]--; + if (arduboy.pressed(RIGHT_BUTTON)) x[select]++; + } + + FX::drawBitmap(x[0],y[0],mapGfx,0,dbmNormal); + FX::drawBitmap(x[1],y[1],whaleGfx,0,dbmMasked | color); // comment this line and uncomment one below to test the drawing modes + //FX::drawBitmap(x[1],y[1],whaleGfx,0,dbmMasked | dbmBlack); // black pixels as drawn solid. White pixels are transparent. Mask is ignored. + //FX::drawBitmap(x[1],y[1],whaleGfx,0,dbmMasked | dbmWhite); // white pixels are drawn solid. Black pixels are transparent. Mask is ignored. + //FX::drawBitmap(x[1],y[1],whaleGfx,0,dbmMasked | dbmInvert); // white pixels are xored together with background pixels. Mask is ignored. + //FX::drawBitmap(x[1],y[1],whaleGfx,0,dbmMasked | dbmReverse); // Inverts the image: white pixels are drawn as black, black pixels are drawn as white pixels. Mask is applied. + if (showposition) + { + arduboy.setCursor(0,0); + arduboy.print(x[select]); + arduboy.setCursor(0,8); + arduboy.print(y[select]); + } + FX::enableOLED(); // only enable OLED for updating the display + arduboy.display(CLEAR_BUFFER); // Using CLEAR_BUFFER will clear the display buffer after it is displayed + FX::disableOLED(); // disable display again so external flash can be accessed at any time +} diff --git a/board-package-source/libraries/ArduboyFX/examples/chompies/fxdata.bin b/board-package-source/libraries/ArduboyFX/examples/chompies/fxdata.bin new file mode 100644 index 0000000000000000000000000000000000000000..0d172cd938940c3cdcf7c8a01d9f83a0157485f8 GIT binary patch literal 39470 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

FW-d2AKpUX)%56h%=|2%95UZnokZi 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