diff --git a/examples/WatchFaces/DOS/DOS.ino b/examples/WatchFaces/DOS/DOS.ino index 4aef3cd..7ea4ef8 100644 --- a/examples/WatchFaces/DOS/DOS.ino +++ b/examples/WatchFaces/DOS/DOS.ino @@ -7,6 +7,3 @@ void setup(){ } void loop(){} - - - diff --git a/examples/WatchFaces/Pokemon/Pokemon.ino b/examples/WatchFaces/Pokemon/Pokemon.ino index ffa743b..eaccd44 100644 --- a/examples/WatchFaces/Pokemon/Pokemon.ino +++ b/examples/WatchFaces/Pokemon/Pokemon.ino @@ -7,6 +7,3 @@ void setup(){ } void loop(){} - - - diff --git a/examples/WatchFaces/StarryHorizon/StarryHorizon.ino b/examples/WatchFaces/StarryHorizon/StarryHorizon.ino index 0226130..cccf2a7 100644 --- a/examples/WatchFaces/StarryHorizon/StarryHorizon.ino +++ b/examples/WatchFaces/StarryHorizon/StarryHorizon.ino @@ -1,150 +1,150 @@ -// STARRY HORIZON for Watchy by SQFMI -// Copyright 2021 Dan Delany dan.delany@gmail.com -// Released under free MIT License : https://github.com/dandelany/watchy-faces/blob/main/LICENSE - -#include //include the Watchy library -#include //include any fonts you want to use -#include "MadeSunflower39pt7b.h" -#include "stars.h" - -#define STAR_COUNT 900 - -const int horizonY = 150; -const int planetR = 650; - -struct xyPoint { - int x; - int y; -}; - -//Star myStars[STAR_COUNT]; -void initStars() { - // The random star field is loaded from PROGMEM - see stars.h - // this is the function that was used to generate the stars in stars.h - // it does not run normally but can be used to re-generate stars with different parameters - // tweak as needed, call this function in init, open serial monitor, and paste the results into stars.h - srand(5287); // randomSeed() is not stable on ESP32, use srand - printf("const Star STARS[] PROGMEM = {\n"); - for(int i = 0; i < STAR_COUNT; i++) { - int starX = (rand() % 260) - 30; - int starY = (rand() % 260) - 30; - int radius = 0; - if (i > STAR_COUNT * 0.99) radius = 2; - else if (i > STAR_COUNT * 0.80) radius = 1; - printf(" { %d, %d, %d },\n", starX, starY, radius); -// myStars[i] = { starX, starY, radius }; - } - printf("};\n"); -} - -struct xyPoint rotatePointAround(int x, int y, int ox, int oy, double angle) { - // rotate X,Y point around given origin point by a given angle - // based on https://gist.github.com/LyleScott/e36e08bfb23b1f87af68c9051f985302#file-rotate_2d_point-py-L38 - double qx = (double)ox + (cos(angle) * (double)(x - ox)) + (sin(angle) * (double)(y - oy)); - double qy = (double)oy + (-sin(angle) * (double)(x - ox)) + (cos(angle) * (double)(y - oy)); - struct xyPoint newPoint; - newPoint.x = (int)qx; - newPoint.y = (int)qy; - return newPoint; -} - -class StarryHorizon : public Watchy { - public: - StarryHorizon() { - // uncomment to re-generate stars -// initStars(); - } - void drawWatchFace(){ - display.fillScreen(GxEPD_BLACK); - display.fillCircle(100, horizonY + planetR, planetR, GxEPD_WHITE); - drawGrid(); - drawStars(STARS); - drawTime(); - drawDate(); - } - void drawGrid() { - int prevY = horizonY; - for(int i = 0; i < 40; i+= 1) { - int y = prevY + int(abs(sin(double(i) / 10) * 10)); - if(y <= 200) { - display.drawFastHLine(0, y, 200, GxEPD_BLACK); - } - prevY = y; - } - int vanishY = horizonY - 25; - for (int x = -230; x < 430; x += 20) { - display.drawLine(x, 200, 100, vanishY, GxEPD_BLACK); - } - } - void drawStars(const Star stars[]) { - // draw field of stars - // rotate stars so that they make an entire revolution once per hour - int minute = (int)currentTime.Minute; - double minuteAngle = ((2.0 * M_PI) / 60.0) * (double)minute; -// printf("Minute %d, angle %f\n", (int)currentTime.Minute, minuteAngle); - - for(int starI = 0; starI < STAR_COUNT; starI++) { - int starX = stars[starI].x; - int starY = stars[starI].y; - int starR = stars[starI].r; - - struct xyPoint rotated = rotatePointAround(starX, starY, 100, 100, minuteAngle); - if(rotated.x < 0 || rotated.y < 0 || rotated.x > 200 || rotated.y > horizonY) { - continue; - } - if(starR == 0) { - display.drawPixel(rotated.x, rotated.y, GxEPD_WHITE); - } else { - display.fillCircle(rotated.x, rotated.y, starR, GxEPD_WHITE); - } - } - } - void drawTime() { - display.setFont(&MADE_Sunflower_PERSONAL_USE39pt7b); - display.setTextColor(GxEPD_WHITE); - display.setTextWrap(false); - char* timeStr; - asprintf(&timeStr, "%d:%02d", currentTime.Hour, currentTime.Minute); - drawCenteredString(timeStr, 100, 115, false); - free(timeStr); - } - - void drawDate() { - String monthStr = monthShortStr(currentTime.Month); - String dayOfWeek = dayShortStr(currentTime.Wday); - display.setFont(&FreeSansBold9pt7b); - display.setTextColor(GxEPD_WHITE); - display.setTextWrap(false); - char* dateStr; - asprintf(&dateStr, "%s %s %d", dayOfWeek, monthStr, currentTime.Day); - drawCenteredString(dateStr, 100, 140, true); - free(dateStr); - } - - void drawCenteredString(const String &str, int x, int y, bool drawBg) { - int16_t x1, y1; - uint16_t w, h; - - display.getTextBounds(str, x, y, &x1, &y1, &w, &h); -// printf("bounds: %d x %d y, %d x1 %d y1, %d w, %d h\n", 0, 100, x1, y1, w, h); - display.setCursor(x - w / 2, y); - if(drawBg) { - int padY = 3; - int padX = 10; - display.fillRect(x - (w / 2 + padX), y - (h + padY), w + padX*2, h + padY*2, GxEPD_BLACK); - } - // uncomment to draw bounding box -// display.drawRect(x - w / 2, y - h, w, h, GxEPD_WHITE); - display.print(str); - } -}; - -StarryHorizon face; //instantiate watchface - -void setup() { - face.init(); //call init in setup -} - -void loop() { - // this should never run, Watchy deep sleeps after init(); -} +// STARRY HORIZON for Watchy by SQFMI +// Copyright 2021 Dan Delany dan.delany@gmail.com +// Released under free MIT License : https://github.com/dandelany/watchy-faces/blob/main/LICENSE + +#include //include the Watchy library +#include //include any fonts you want to use +#include "MadeSunflower39pt7b.h" +#include "stars.h" + +#define STAR_COUNT 900 + +const int horizonY = 150; +const int planetR = 650; + +struct xyPoint { + int x; + int y; +}; + +//Star myStars[STAR_COUNT]; +void initStars() { + // The random star field is loaded from PROGMEM - see stars.h + // this is the function that was used to generate the stars in stars.h + // it does not run normally but can be used to re-generate stars with different parameters + // tweak as needed, call this function in init, open serial monitor, and paste the results into stars.h + srand(5287); // randomSeed() is not stable on ESP32, use srand + printf("const Star STARS[] PROGMEM = {\n"); + for(int i = 0; i < STAR_COUNT; i++) { + int starX = (rand() % 260) - 30; + int starY = (rand() % 260) - 30; + int radius = 0; + if (i > STAR_COUNT * 0.99) radius = 2; + else if (i > STAR_COUNT * 0.80) radius = 1; + printf(" { %d, %d, %d },\n", starX, starY, radius); +// myStars[i] = { starX, starY, radius }; + } + printf("};\n"); +} + +struct xyPoint rotatePointAround(int x, int y, int ox, int oy, double angle) { + // rotate X,Y point around given origin point by a given angle + // based on https://gist.github.com/LyleScott/e36e08bfb23b1f87af68c9051f985302#file-rotate_2d_point-py-L38 + double qx = (double)ox + (cos(angle) * (double)(x - ox)) + (sin(angle) * (double)(y - oy)); + double qy = (double)oy + (-sin(angle) * (double)(x - ox)) + (cos(angle) * (double)(y - oy)); + struct xyPoint newPoint; + newPoint.x = (int)qx; + newPoint.y = (int)qy; + return newPoint; +} + +class StarryHorizon : public Watchy { + public: + StarryHorizon() { + // uncomment to re-generate stars +// initStars(); + } + void drawWatchFace(){ + display.fillScreen(GxEPD_BLACK); + display.fillCircle(100, horizonY + planetR, planetR, GxEPD_WHITE); + drawGrid(); + drawStars(STARS); + drawTime(); + drawDate(); + } + void drawGrid() { + int prevY = horizonY; + for(int i = 0; i < 40; i+= 1) { + int y = prevY + int(abs(sin(double(i) / 10) * 10)); + if(y <= 200) { + display.drawFastHLine(0, y, 200, GxEPD_BLACK); + } + prevY = y; + } + int vanishY = horizonY - 25; + for (int x = -230; x < 430; x += 20) { + display.drawLine(x, 200, 100, vanishY, GxEPD_BLACK); + } + } + void drawStars(const Star stars[]) { + // draw field of stars + // rotate stars so that they make an entire revolution once per hour + int minute = (int)currentTime.Minute; + double minuteAngle = ((2.0 * M_PI) / 60.0) * (double)minute; +// printf("Minute %d, angle %f\n", (int)currentTime.Minute, minuteAngle); + + for(int starI = 0; starI < STAR_COUNT; starI++) { + int starX = stars[starI].x; + int starY = stars[starI].y; + int starR = stars[starI].r; + + struct xyPoint rotated = rotatePointAround(starX, starY, 100, 100, minuteAngle); + if(rotated.x < 0 || rotated.y < 0 || rotated.x > 200 || rotated.y > horizonY) { + continue; + } + if(starR == 0) { + display.drawPixel(rotated.x, rotated.y, GxEPD_WHITE); + } else { + display.fillCircle(rotated.x, rotated.y, starR, GxEPD_WHITE); + } + } + } + void drawTime() { + display.setFont(&MADE_Sunflower_PERSONAL_USE39pt7b); + display.setTextColor(GxEPD_WHITE); + display.setTextWrap(false); + char* timeStr; + asprintf(&timeStr, "%d:%02d", currentTime.Hour, currentTime.Minute); + drawCenteredString(timeStr, 100, 115, false); + free(timeStr); + } + + void drawDate() { + String monthStr = monthShortStr(currentTime.Month); + String dayOfWeek = dayShortStr(currentTime.Wday); + display.setFont(&FreeSansBold9pt7b); + display.setTextColor(GxEPD_WHITE); + display.setTextWrap(false); + char* dateStr; + asprintf(&dateStr, "%s %s %d", dayOfWeek, monthStr, currentTime.Day); + drawCenteredString(dateStr, 100, 140, true); + free(dateStr); + } + + void drawCenteredString(const String &str, int x, int y, bool drawBg) { + int16_t x1, y1; + uint16_t w, h; + + display.getTextBounds(str, x, y, &x1, &y1, &w, &h); +// printf("bounds: %d x %d y, %d x1 %d y1, %d w, %d h\n", 0, 100, x1, y1, w, h); + display.setCursor(x - w / 2, y); + if(drawBg) { + int padY = 3; + int padX = 10; + display.fillRect(x - (w / 2 + padX), y - (h + padY), w + padX*2, h + padY*2, GxEPD_BLACK); + } + // uncomment to draw bounding box +// display.drawRect(x - w / 2, y - h, w, h, GxEPD_WHITE); + display.print(str); + } +}; + +StarryHorizon face; //instantiate watchface + +void setup() { + face.init(); //call init in setup +} + +void loop() { + // this should never run, Watchy deep sleeps after init(); +} diff --git a/extras/WatchFaces/1_Basic.png b/extras/WatchFaces/1_Basic.png new file mode 100644 index 0000000..06d0fac Binary files /dev/null and b/extras/WatchFaces/1_Basic.png differ diff --git a/extras/WatchFaces/2_7_SEG.png b/extras/WatchFaces/2_7_SEG.png new file mode 100644 index 0000000..01e7b30 Binary files /dev/null and b/extras/WatchFaces/2_7_SEG.png differ diff --git a/extras/WatchFaces/3_DOS.png b/extras/WatchFaces/3_DOS.png new file mode 100644 index 0000000..b95c356 Binary files /dev/null and b/extras/WatchFaces/3_DOS.png differ diff --git a/extras/WatchFaces/4_Pokemon.png b/extras/WatchFaces/4_Pokemon.png new file mode 100644 index 0000000..ba3ffe6 Binary files /dev/null and b/extras/WatchFaces/4_Pokemon.png differ diff --git a/extras/WatchFaces/5_StarryHorizon.png b/extras/WatchFaces/5_StarryHorizon.png new file mode 100644 index 0000000..657e410 Binary files /dev/null and b/extras/WatchFaces/5_StarryHorizon.png differ diff --git a/extras/index.json b/extras/WatchFaces/index.json similarity index 68% rename from extras/index.json rename to extras/WatchFaces/index.json index f59d0d6..f1cc1ad 100644 --- a/extras/index.json +++ b/extras/WatchFaces/index.json @@ -4,7 +4,7 @@ "id" : "1", "name" : "Basic", "author" : "SQFMI", - "screenshot" : "", + "screenshot" : "https://raw.githubusercontent.com/sqfmi/Watchy/master/extras/WatchFaces/1_Basic.png", "source" : "https://github.com/sqfmi/Watchy/tree/master/examples/WatchFaces/Basic", "version" : "1.0.0" }, @@ -12,7 +12,7 @@ "id" : "2", "name" : "7_SEG", "author" : "SQFMI", - "screenshot" : "", + "screenshot" : "https://raw.githubusercontent.com/sqfmi/Watchy/master/extras/WatchFaces/2_7_SEG.png", "source" : "https://github.com/sqfmi/Watchy/tree/master/examples/WatchFaces/7_SEG", "version" : "1.0.0" }, @@ -20,7 +20,7 @@ "id" : "3", "name" : "DOS", "author" : "SQFMI", - "screenshot" : "", + "screenshot" : "https://raw.githubusercontent.com/sqfmi/Watchy/master/extras/WatchFaces/3_DOS.png", "source" : "https://github.com/sqfmi/Watchy/tree/master/examples/WatchFaces/DOS", "version" : "1.0.0" }, @@ -28,7 +28,7 @@ "id" : "4", "name" : "Pokemon", "author" : "SQFMI", - "screenshot" : "", + "screenshot" : "https://raw.githubusercontent.com/sqfmi/Watchy/master/extras/WatchFaces/4_Pokemon.png", "source" : "https://github.com/sqfmi/Watchy/tree/master/examples/WatchFaces/Pokemon", "version" : "1.0.0" }, @@ -36,7 +36,7 @@ "id" : "5", "name" : "StarryHorizon", "author" : "dandelany", - "screenshot" : "", + "screenshot" : "https://raw.githubusercontent.com/sqfmi/Watchy/master/extras/WatchFaces/5_StarryHorizon.png", "source" : "https://github.com/sqfmi/Watchy/tree/master/examples/WatchFaces/StarryHorizon", "version" : "1.0.0" }