]> git.openfl.eu Git - unitime.git/commitdiff
initial commit main
authorFl_GUI <flor.guilini@hotmail.com>
Fri, 9 Jan 2026 21:51:54 +0000 (22:51 +0100)
committerFl_GUI <flor.guilini@hotmail.com>
Fri, 9 Jan 2026 21:51:54 +0000 (22:51 +0100)
.gitignore [new file with mode: 0644]
include/README [new file with mode: 0644]
lib/README [new file with mode: 0644]
platformio.ini [new file with mode: 0644]
src/main.cc [new file with mode: 0644]
src/sprites.h [new file with mode: 0644]
src/sprites.xcf [new file with mode: 0644]
test/README [new file with mode: 0644]

diff --git a/.gitignore b/.gitignore
new file mode 100644 (file)
index 0000000..fed1372
--- /dev/null
@@ -0,0 +1,2 @@
+.pio
+*.png
diff --git a/include/README b/include/README
new file mode 100644 (file)
index 0000000..49819c0
--- /dev/null
@@ -0,0 +1,37 @@
+
+This directory is intended for project header files.
+
+A header file is a file containing C declarations and macro definitions
+to be shared between several project source files. You request the use of a
+header file in your project source file (C, C++, etc) located in `src` folder
+by including it, with the C preprocessing directive `#include'.
+
+```src/main.c
+
+#include "header.h"
+
+int main (void)
+{
+ ...
+}
+```
+
+Including a header file produces the same results as copying the header file
+into each source file that needs it. Such copying would be time-consuming
+and error-prone. With a header file, the related declarations appear
+in only one place. If they need to be changed, they can be changed in one
+place, and programs that include the header file will automatically use the
+new version when next recompiled. The header file eliminates the labor of
+finding and changing all the copies as well as the risk that a failure to
+find one copy will result in inconsistencies within a program.
+
+In C, the convention is to give header files names that end with `.h'.
+
+Read more about using header files in official GCC documentation:
+
+* Include Syntax
+* Include Operation
+* Once-Only Headers
+* Computed Includes
+
+https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html
diff --git a/lib/README b/lib/README
new file mode 100644 (file)
index 0000000..9379397
--- /dev/null
@@ -0,0 +1,46 @@
+
+This directory is intended for project specific (private) libraries.
+PlatformIO will compile them to static libraries and link into the executable file.
+
+The source code of each library should be placed in a separate directory
+("lib/your_library_name/[Code]").
+
+For example, see the structure of the following example libraries `Foo` and `Bar`:
+
+|--lib
+|  |
+|  |--Bar
+|  |  |--docs
+|  |  |--examples
+|  |  |--src
+|  |     |- Bar.c
+|  |     |- Bar.h
+|  |  |- library.json (optional. for custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html
+|  |
+|  |--Foo
+|  |  |- Foo.c
+|  |  |- Foo.h
+|  |
+|  |- README --> THIS FILE
+|
+|- platformio.ini
+|--src
+   |- main.c
+
+Example contents of `src/main.c` using Foo and Bar:
+```
+#include <Foo.h>
+#include <Bar.h>
+
+int main (void)
+{
+  ...
+}
+
+```
+
+The PlatformIO Library Dependency Finder will find automatically dependent
+libraries by scanning project source files.
+
+More information about PlatformIO Library Dependency Finder
+- https://docs.platformio.org/page/librarymanager/ldf.html
diff --git a/platformio.ini b/platformio.ini
new file mode 100644 (file)
index 0000000..9fb383f
--- /dev/null
@@ -0,0 +1,20 @@
+; PlatformIO Project Configuration File
+;
+;   Build options: build flags, source filter
+;   Upload options: custom upload port, speed and extra flags
+;   Library options: dependencies, extra library storages
+;   Advanced options: extra scripting
+;
+; Please visit documentation for the other options and examples
+; https://docs.platformio.org/page/projectconf.html
+
+[platformio]
+name = unitime
+description = see all of time at once
+
+[env:dev]
+platform = espressif32
+board = esp32-c3-devkitm-1
+framework = arduino
+lib_deps = 
+       adafruit/Adafruit SSD1306@^2.5.16
diff --git a/src/main.cc b/src/main.cc
new file mode 100644 (file)
index 0000000..4408775
--- /dev/null
@@ -0,0 +1,138 @@
+#include <Arduino.h>
+#include <Wire.h>
+#include <Adafruit_SSD1306.h>
+#include "sprites.h"
+
+#define SCREEN_WIDTH 128
+#define SCREEN_HEIGHT 32
+#define SCREEN_ADDRS 0x3C
+
+// Coordinate system is origin top left, x going right, y going down
+
+typedef struct {
+  // in pixels
+  int x;
+  int y;
+  int w;
+  int h;
+} t_swatch;
+
+#define S_COUNT 24
+static t_swatch swatches[S_COUNT] =
+{
+  // 0-9
+  t_swatch{0, 0, 8, 16},
+  t_swatch{8, 0, 8, 16},
+  t_swatch{16, 0, 8, 16},
+  t_swatch{24, 0, 8, 16},
+  t_swatch{32, 0, 8, 16},
+  t_swatch{40, 0, 8, 16},
+  t_swatch{48, 0, 8, 16},
+  t_swatch{56, 0, 8, 16},
+  t_swatch{64, 0, 8, 16},
+  t_swatch{72, 0, 8, 16},
+  // small 0-9
+  t_swatch{80, 0, 4, 8},
+  t_swatch{80, 8, 4, 8},
+  t_swatch{84, 0, 4, 8},
+  t_swatch{84, 8, 4, 8},
+  t_swatch{88, 0, 4, 8},
+  t_swatch{88, 8, 4, 8},
+  t_swatch{92, 0, 4, 8},
+  t_swatch{92, 8, 4, 8},
+  t_swatch{96, 0, 4, 8},
+  t_swatch{96, 8, 4, 8},
+  // gmt, +, -
+  t_swatch{100, 0, 16, 8},
+  t_swatch{100, 8, 4, 4},
+  t_swatch{100, 12, 4, 4},
+  // :
+  t_swatch{116, 0, 4, 16},
+};
+
+#define S_ZERO 0
+#define S_ONE 1
+#define S_TWO 2
+#define S_THREE 3
+#define S_FOUR 4
+#define S_FIVE 5
+#define S_SIX 6
+#define S_SEVEN 7
+#define S_EIGHT 8
+#define S_NINE 9
+#define S_ZERO_SM 10
+#define S_ONE_SM 11
+#define S_TWO_SM 12
+#define S_THREE_SM 13
+#define S_FOUR_SM 14
+#define S_FIVE_SM 15
+#define S_SIX_SM 16
+#define S_SEVEN_SM 17
+#define S_EIGHT_SM 18
+#define S_NINE_SM 19
+#define S_GMT 20
+#define S_PLUS 21
+#define S_MINUS 22
+#define S_COLON 23
+
+void drawSwatch(int x, int y, t_swatch swatch);
+void drawSwatchLine(int x, int y, int count, t_swatch *swatches);
+
+Adafruit_SSD1306 display;
+
+void setup() {
+  Wire.setPins(7,6);
+  display = Adafruit_SSD1306(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
+  Serial.begin(9600);
+  // wait for display
+  delay(100);
+
+  if (!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRS)) {
+    while (true) {
+      Serial.println("dead");
+      delay(100);
+    }
+  }
+
+  display.clearDisplay();
+  display.display();
+  delay(100);
+}
+
+void loop() {
+
+  t_swatch mainLine[5] = {swatches[S_TWO], swatches[S_TWO], swatches[S_COLON], swatches[S_FOUR], swatches[S_SIX]};
+  drawSwatchLine(40, 8, 5, mainLine);
+
+  t_swatch timezone[3] = {swatches[S_GMT], swatches[S_PLUS], swatches[S_ONE_SM]};
+  drawSwatch(68, 20, timezone[0]);
+  drawSwatch(84, 22, timezone[1]);
+  drawSwatch(88, 20, timezone[2]);
+
+  display.display();
+  delay(1000);
+}
+
+void drawSwatch(int x, int y, t_swatch swatch) {
+  char* image;
+  int pixel[3] = {};
+  int maxx = x+swatch.w;
+  int maxy = y+swatch.h;
+  for (int dy = 0; dy < swatch.h; dy++) {
+    image = header_data + 4*(dy*width + swatch.x + swatch.y*width);
+    for (int dx = x; dx < maxx; dx++) {
+      HEADER_PIXEL(image, pixel);
+      if (pixel[0])
+        display.drawPixel(dx, y+dy, SSD1306_WHITE);
+      else
+        display.drawPixel(dx, y+dy, SSD1306_BLACK);
+    }
+  }
+}
+
+void drawSwatchLine(int x, int y, int count, t_swatch *swatches) {
+  for (int i = 0; i < count ; i++) {
+    drawSwatch(x, y, swatches[i]);
+    x += swatches[i].w;
+  }
+}
diff --git a/src/sprites.h b/src/sprites.h
new file mode 100644 (file)
index 0000000..de1ae1a
--- /dev/null
@@ -0,0 +1,271 @@
+/*  GIMP header image file format (RGB): /home/Fl_GUI/repos/unitime/src/sprites.h  */
+
+static unsigned int width = 128;
+static unsigned int height = 32;
+
+/*  Call this macro repeatedly.  After each use, the pixel data can be extracted  */
+
+#define HEADER_PIXEL(data,pixel) {\
+pixel[0] = (((data[0] - 33) << 2) | ((data[1] - 33) >> 4)); \
+pixel[1] = ((((data[1] - 33) & 0xF) << 4) | ((data[2] - 33) >> 2)); \
+pixel[2] = ((((data[2] - 33) & 0x3) << 6) | ((data[3] - 33))); \
+data += 4; \
+}
+static char *header_data =
+       "!!!!!!!!````````````````!!!!!!!!!!!!!!!!!!!!!!!!````````!!!!!!!!"
+       "!!!!!!!!````````````````!!!!!!!!!!!!!!!!````````````````!!!!!!!!"
+       "!!!!````````!!!!!!!!````````!!!!!!!!````````````````````````!!!!"
+       "!!!!!!!!````````````````!!!!!!!!!!!!````````````````````````!!!!"
+       "!!!!!!!!````````````````!!!!!!!!!!!!!!!!````````````````!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!````````````````````````!!!!!!!!!!!!!!!!````````````!!!!!!!!"
+       "!!!!````````````````````````!!!!!!!!````````````````````````!!!!"
+       "!!!!````````!!!!!!!!````````!!!!!!!!````````````````````````!!!!"
+       "!!!!````````````````````````!!!!!!!!````````````````````````!!!!"
+       "!!!!````````````````````````!!!!!!!!````````````````````````!!!!"
+       "!!!!````````!!!!!!!!````````!!!!!!!!````!!!!````!!!!````````````"
+       "!!!!````````!!!!!!!!_@HZ_@HZ````````!!!!````!!!!!!!!_@HZ!!!!_@HZ"
+       "_@HZ_@HZ_@HZ_@HZ!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!````````!!!!!!!!````````!!!!!!!!!!!!````````````````!!!!!!!!"
+       "!!!!````````!!!!!!!!````````!!!!!!!!````````!!!!!!!!````````!!!!"
+       "!!!!````````!!!!!!!!````````!!!!!!!!````````!!!!!!!!!!!!!!!!!!!!"
+       "!!!!````````!!!!!!!!````````!!!!!!!!````````!!!!!!!!````````!!!!"
+       "!!!!````````!!!!!!!!````````!!!!!!!!````````!!!!!!!!````````!!!!"
+       "!!!!````!!!!````!!!!!!!!!!!!````!!!!````!!!!````!!!!````!!!!!!!!"
+       "!!!!````!!!!````!!!!_@HZ!!!!!!!!!!!!!!!!````````_@HZ_@HZ!!!!!!!!"
+       "!!!!_@HZ!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!````````!!!!!!!!````````!!!!!!!!````````````````````!!!!!!!!"
+       "!!!!````````!!!!!!!!````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````"
+       "!!!!````````!!!!!!!!````````!!!!!!!!````````!!!!!!!!!!!!!!!!!!!!"
+       "!!!!````````!!!!!!!!````````!!!!!!!!!!!!!!!!!!!!!!!!````````!!!!"
+       "!!!!````````!!!!!!!!````````!!!!!!!!````````!!!!!!!!````````!!!!"
+       "!!!!````!!!!````!!!!!!!!!!!!````!!!!````!!!!````!!!!````!!!!!!!!"
+       "!!!!````!!!!````!!!!_@HZ!!!!!!!!!!!!!!!!````!!!!!!!!_@HZ!!!!!!!!"
+       "!!!!_@HZ!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!````````!!!!!!!!````````!!!!!!!!````````!!!!````````!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````"
+       "!!!!````````````````````````!!!!!!!!````````!!!!!!!!!!!!!!!!!!!!"
+       "!!!!````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````!!!!"
+       "!!!!````````!!!!!!!!````````!!!!!!!!````````!!!!!!!!````````!!!!"
+       "!!!!````!!!!````!!!!````````!!!!!!!!````````````!!!!````````````"
+       "!!!!````````````!!!!_@HZ!!!!````````!!!!````!!!!!!!!_@HZ!!!!!!!!"
+       "!!!!_@HZ!!!!!!!!!!!!````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!````````!!!!!!!!````````!!!!!!!!!!!!!!!!!!!!````````!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````"
+       "!!!!````````````````````````!!!!!!!!````````!!!!!!!!!!!!!!!!!!!!"
+       "!!!!````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````!!!!"
+       "!!!!````````!!!!!!!!````````!!!!!!!!````````!!!!!!!!````````!!!!"
+       "!!!!````!!!!````!!!!````!!!!!!!!!!!!!!!!!!!!````!!!!````!!!!````"
+       "!!!!````!!!!````!!!!_@HZ!!!!!!!!_@HZ!!!!````!!!!!!!!_@HZ!!!!!!!!"
+       "!!!!_@HZ!!!!!!!!!!!!````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!````````!!!!!!!!````````!!!!!!!!!!!!!!!!!!!!````````!!!!!!!!"
+       "!!!!!!!!!!!!!!!!````````````!!!!!!!!!!!!!!!!!!!!!!!!````````````"
+       "!!!!!!!!!!!!!!!!!!!!````````!!!!!!!!````````````````!!!!!!!!!!!!"
+       "!!!!````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````!!!!!!!!"
+       "!!!!````````!!!!!!!!````````!!!!!!!!````````!!!!!!!!````````!!!!"
+       "!!!!````!!!!````!!!!````!!!!!!!!!!!!!!!!!!!!````!!!!````!!!!````"
+       "!!!!````!!!!````!!!!_@HZ!!!!!!!!_@HZ!!!!````!!!!!!!!_@HZ!!!!!!!!"
+       "!!!!_@HZ!!!!!!!!!!!!````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!````````!!!!!!!!````````!!!!!!!!!!!!!!!!!!!!````````!!!!!!!!"
+       "!!!!!!!!!!!!````````````!!!!!!!!!!!!!!!!!!!!````````````````!!!!"
+       "!!!!!!!!!!!!!!!!!!!!````````!!!!!!!!````````````````````!!!!!!!!"
+       "!!!!````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````!!!!!!!!"
+       "!!!!!!!!````````````````!!!!!!!!!!!!````````````````````````!!!!"
+       "!!!!````````````!!!!````````````!!!!!!!!!!!!````!!!!````````!!!!"
+       "!!!!````````!!!!!!!!_@HZ_@HZ_@HZ_@HZ!!!!````!!!!!!!!_@HZ!!!!!!!!"
+       "!!!!_@HZ!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!````````!!!!!!!!````````!!!!!!!!!!!!!!!!!!!!````````!!!!!!!!"
+       "!!!!!!!!!!!!````````!!!!!!!!!!!!!!!!!!!!!!!!````````````````!!!!"
+       "!!!!!!!!!!!!!!!!!!!!````````!!!!!!!!!!!!!!!!````````````!!!!!!!!"
+       "!!!!````````````````````!!!!!!!!!!!!!!!!!!!!````````````!!!!!!!!"
+       "!!!!!!!!````````````````!!!!!!!!!!!!!!!!````````````````!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!````````!!!!!!!!````````!!!!!!!!!!!!!!!!!!!!````````!!!!!!!!"
+       "!!!!!!!!````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````"
+       "!!!!!!!!!!!!!!!!!!!!````````!!!!!!!!!!!!!!!!!!!!````````````!!!!"
+       "!!!!````````````````````````!!!!!!!!!!!!````````````!!!!!!!!!!!!"
+       "!!!!````````!!!!!!!!````````!!!!!!!!!!!!!!!!!!!!````````!!!!!!!!"
+       "!!!!!!!!````!!!!!!!!````````!!!!!!!!````````````!!!!````````````"
+       "!!!!````````#!A)!!!!!!!!````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!````````!!!!!!!!````````!!!!!!!!!!!!!!!!!!!!````````!!!!!!!!"
+       "!!!!````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````"
+       "!!!!!!!!!!!!!!!!!!!!````````!!!!!!!!!!!!!!!!!!!!!!!!````````!!!!"
+       "!!!!````````!!!!!!!!````````!!!!!!!!!!!!````````!!!!!!!!!!!!!!!!"
+       "!!!!````````!!!!!!!!````````!!!!!!!!!!!!!!!!!!!!````````!!!!!!!!"
+       "!!!!````````!!!!!!!!!!!!!!!!````!!!!````!!!!!!!!!!!!!!!!!!!!````"
+       "!!!!````!!!!````!!!!````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!````````!!!!!!!!````````!!!!!!!!!!!!!!!!!!!!````````!!!!!!!!"
+       "!!!!````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````"
+       "!!!!!!!!!!!!!!!!!!!!````````!!!!!!!!!!!!!!!!!!!!!!!!````````!!!!"
+       "!!!!````````!!!!!!!!````````!!!!!!!!!!!!````````!!!!!!!!!!!!!!!!"
+       "!!!!````````!!!!!!!!````````!!!!!!!!!!!!!!!!````````!!!!!!!!!!!!"
+       "!!!!!!!!````!!!!!!!!!!!!!!!!````!!!!````!!!!!!!!!!!!!!!!!!!!````"
+       "!!!!````!!!!````!!!!!!!!````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!````````!!!!!!!!````````!!!!!!!!!!!!!!!!!!!!````````!!!!!!!!"
+       "!!!!````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````"
+       "!!!!!!!!!!!!!!!!!!!!````````!!!!!!!!!!!!!!!!!!!!````````````!!!!"
+       "!!!!````````!!!!!!!!````````!!!!!!!!!!!!````````!!!!!!!!!!!!!!!!"
+       "!!!!````````!!!!!!!!````````!!!!!!!!!!!!!!!!````````!!!!!!!!!!!!"
+       "!!!!!!!!````!!!!!!!!````````!!!!!!!!!!!!````````!!!!!!!!````!!!!"
+       "!!!!````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!````````!!!!!!!!````````!!!!!!!!!!!!!!!!!!!!````````!!!!!!!!"
+       "!!!!````````!!!!!!!!!!!!!!!!!!!!!!!!````````!!!!!!!!````````!!!!"
+       "!!!!!!!!!!!!!!!!!!!!````````!!!!!!!!!!!!!!!!````````````!!!!!!!!"
+       "!!!!````````!!!!!!!!````````!!!!!!!!!!!!````````!!!!!!!!!!!!!!!!"
+       "!!!!````````!!!!!!!!````````!!!!!!!!!!!!````````````!!!!!!!!!!!!"
+       "!!!!!!!!````!!!!!!!!!!!!!!!!````!!!!!!!!!!!!````!!!!!!!!````!!!!"
+       "!!!!!!!!!!!!````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!````````````````````````!!!!!!!!!!!!````````````````````!!!!"
+       "!!!!````````````````````!!!!!!!!!!!!````````````````````````!!!!"
+       "!!!!!!!!!!!!!!!!!!!!````````!!!!!!!!````````````````````!!!!!!!!"
+       "!!!!````````````````````````!!!!!!!!!!!!````````!!!!!!!!!!!!!!!!"
+       "!!!!````````````````````````!!!!!!!!!!!!````````!!!!!!!!!!!!!!!!"
+       "!!!!!!!!````!!!!!!!!!!!!!!!!````!!!!!!!!!!!!````!!!!!!!!````!!!!"
+       "!!!!!!!!!!!!````!!!!````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!````````````````!!!!!!!!!!!!````````````````````````!!!!"
+       "!!!!````````````````````````!!!!!!!!!!!!````````````````!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!````````!!!!!!!!````````````````!!!!!!!!!!!!"
+       "!!!!!!!!````````````````!!!!!!!!!!!!!!!!````````!!!!!!!!!!!!!!!!"
+       "!!!!!!!!````````````````!!!!!!!!!!!!!!!!````````!!!!!!!!!!!!!!!!"
+       "!!!!!!!!````!!!!!!!!````````````!!!!````````!!!!!!!!!!!!````!!!!"
+       "!!!!````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+       "";
diff --git a/src/sprites.xcf b/src/sprites.xcf
new file mode 100644 (file)
index 0000000..20ad822
Binary files /dev/null and b/src/sprites.xcf differ
diff --git a/test/README b/test/README
new file mode 100644 (file)
index 0000000..9b1e87b
--- /dev/null
@@ -0,0 +1,11 @@
+
+This directory is intended for PlatformIO Test Runner and project tests.
+
+Unit Testing is a software testing method by which individual units of
+source code, sets of one or more MCU program modules together with associated
+control data, usage procedures, and operating procedures, are tested to
+determine whether they are fit for use. Unit testing finds problems early
+in the development cycle.
+
+More information about PlatformIO Unit Testing:
+- https://docs.platformio.org/en/latest/advanced/unit-testing/index.html