2023-12-06 10:50:31 -07:00
|
|
|
#include <FastLED.h>
|
2022-07-19 21:14:34 -06:00
|
|
|
#include <ArduinoHttpClient.h>
|
|
|
|
#include <WiFiClientSecure.h>
|
2023-01-07 12:12:46 -07:00
|
|
|
#include <WiFiUdp.h>
|
2023-09-04 16:30:21 -06:00
|
|
|
#include <TimeLib.h>
|
2023-04-09 12:42:02 -06:00
|
|
|
#include "durations.h"
|
2022-01-01 09:35:06 -07:00
|
|
|
#include "picker.h"
|
2022-07-17 22:22:16 -06:00
|
|
|
#include "network.h"
|
2024-06-09 21:53:19 -06:00
|
|
|
#include "settings.h"
|
2021-12-31 15:58:27 -07:00
|
|
|
|
2024-06-09 21:53:19 -06:00
|
|
|
#define VERSION 2
|
2022-07-17 22:22:16 -06:00
|
|
|
#define GRIDLEN 64
|
2021-12-31 15:58:27 -07:00
|
|
|
|
2022-07-19 21:14:34 -06:00
|
|
|
#define HTTPS_TIMEOUT (2 * SECOND)
|
2023-12-06 13:33:33 -07:00
|
|
|
#define IMAGE_PULL_MIN_INTERVAL (5 * MINUTE)
|
2022-07-19 21:14:34 -06:00
|
|
|
|
2021-12-31 15:58:27 -07:00
|
|
|
CRGB grid[GRIDLEN];
|
2024-06-09 21:53:19 -06:00
|
|
|
CRGB actual[GRIDLEN];
|
|
|
|
|
|
|
|
// Rotation, in degrees: [0, 90, 180, 270]
|
|
|
|
int rotation = 0;
|
|
|
|
|
|
|
|
void show() {
|
|
|
|
for (int y = 0; y < 8; y++) {
|
|
|
|
for (int x = 0; x < 8; x++) {
|
|
|
|
int pos;
|
|
|
|
switch (rotation) {
|
|
|
|
case 90:
|
|
|
|
pos = (x)*8 + (7-y);
|
|
|
|
break;
|
|
|
|
case 180:
|
|
|
|
pos = (7-y)*8 + (7-x);
|
|
|
|
break;
|
|
|
|
case 270:
|
|
|
|
pos = (7-x)*8 + y;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
pos = (y)*8 + x;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
actual[pos] = grid[y*8 + x];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
FastLED.show();
|
|
|
|
}
|
|
|
|
|
|
|
|
void clear() {
|
|
|
|
fill_solid(grid, GRIDLEN, CRGB::Black);
|
|
|
|
}
|
|
|
|
|
|
|
|
// I am so ashamed of this.
|
|
|
|
// But C++ is a real pain for me at this point.
|
|
|
|
#include "clock.h"
|
2021-12-31 15:58:27 -07:00
|
|
|
|
2022-01-01 09:35:06 -07:00
|
|
|
void fade(int cycles = 2) {
|
|
|
|
int reps = (cycles*GRIDLEN) + random(GRIDLEN);
|
2021-12-31 15:58:27 -07:00
|
|
|
int hue = random(256);
|
|
|
|
for (int i = 0; i < reps; i++) {
|
|
|
|
for (int pos = 0; pos < 8; pos++) {
|
2023-01-06 12:50:46 -07:00
|
|
|
uint8_t p = cm5xlat(8, (i+pos) % GRIDLEN);
|
|
|
|
grid[p] = CHSV(hue, 255, pos * 32);
|
2021-12-31 15:58:27 -07:00
|
|
|
}
|
2024-06-09 21:53:19 -06:00
|
|
|
show();
|
2022-07-17 22:22:16 -06:00
|
|
|
pause(80);
|
2021-12-31 15:58:27 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-01-01 09:35:06 -07:00
|
|
|
void singleCursor(int count = 80) {
|
2022-07-17 22:22:16 -06:00
|
|
|
for (int i = 0; i < count; i++) {
|
2021-12-31 15:58:27 -07:00
|
|
|
grid[20] = CHSV(0, 210, 127 * (i%2));
|
2024-06-09 21:53:19 -06:00
|
|
|
show();
|
2022-07-17 22:22:16 -06:00
|
|
|
pause(120);
|
2021-12-31 15:58:27 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#define NUM_SPARKS 3
|
2022-01-01 09:35:06 -07:00
|
|
|
void sparkle(int cycles=50) {
|
2022-07-18 07:42:52 -06:00
|
|
|
int pos[NUM_SPARKS] = {0};
|
|
|
|
|
|
|
|
for (int i = 0; i < cycles; i++) {
|
|
|
|
for (int j = 0; j < NUM_SPARKS; j++) {
|
|
|
|
grid[pos[j]] = CRGB::Black;
|
|
|
|
pos[j] = random(GRIDLEN);
|
|
|
|
grid[pos[j]] = CRGB::Gray;
|
|
|
|
}
|
2024-06-09 21:53:19 -06:00
|
|
|
show();
|
2022-07-18 07:42:52 -06:00
|
|
|
pause(40);
|
|
|
|
}
|
2021-12-31 15:58:27 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#define NUM_GLITCH 4
|
|
|
|
#define GLITCH_FRAMES 64
|
2022-01-01 09:35:06 -07:00
|
|
|
void glitchPulse(int cycles=1000) {
|
2021-12-31 15:58:27 -07:00
|
|
|
int steps[NUM_GLITCH] = {0};
|
|
|
|
int pos[NUM_GLITCH] = {0};
|
|
|
|
CRGB color[NUM_GLITCH];
|
|
|
|
|
|
|
|
for (int i = 0; i < NUM_GLITCH; i++) {
|
|
|
|
steps[i] = GLITCH_FRAMES / NUM_GLITCH * i;
|
|
|
|
color[i] = CRGB::Brown;
|
|
|
|
}
|
|
|
|
|
2022-01-01 09:35:06 -07:00
|
|
|
for (int frame = 0; frame < cycles; frame++) {
|
2021-12-31 15:58:27 -07:00
|
|
|
for (int i = 0; i < NUM_GLITCH; i++) {
|
|
|
|
if (steps[i] == 0) {
|
|
|
|
steps[i] = GLITCH_FRAMES;
|
|
|
|
pos[i] = random(GRIDLEN);
|
|
|
|
color[i] = CHSV(random(256), 64 + random(64), 255);
|
|
|
|
}
|
|
|
|
CRGB c = color[i];
|
|
|
|
int bmask = (0xff * steps[i] / 32) & 0xff;
|
|
|
|
if (steps[i] == GLITCH_FRAMES/2) {
|
|
|
|
bmask = 0xff - bmask;
|
|
|
|
}
|
|
|
|
c.red &= bmask;
|
|
|
|
c.green &= bmask;
|
|
|
|
c.blue &= bmask;
|
|
|
|
grid[pos[i]] = c;
|
|
|
|
steps[i]--;
|
|
|
|
}
|
2024-06-09 21:53:19 -06:00
|
|
|
show();
|
2022-07-17 22:22:16 -06:00
|
|
|
pause(100);
|
2021-12-31 15:58:27 -07:00
|
|
|
}
|
2022-01-01 09:35:06 -07:00
|
|
|
}
|
|
|
|
|
2022-07-17 22:22:16 -06:00
|
|
|
void conwayish(int cycles=5000) {
|
2022-01-01 09:35:06 -07:00
|
|
|
uint8_t total[GRIDLEN];
|
|
|
|
uint8_t left[GRIDLEN] = {0};
|
|
|
|
uint8_t hue = random(0, 64);
|
|
|
|
|
|
|
|
for (int i = 0; i < GRIDLEN; i++) {
|
|
|
|
total[i] = random(64, 256);
|
|
|
|
left[i] = total[i];
|
|
|
|
}
|
2021-12-31 15:58:27 -07:00
|
|
|
|
2022-01-01 09:35:06 -07:00
|
|
|
for (int frame = 0; frame < cycles; frame++) {
|
|
|
|
for (int i = 0; i < GRIDLEN; i++) {
|
|
|
|
if (left[i] == 0) {
|
|
|
|
left[i] = total[i];
|
|
|
|
if (grid[i].getLuma() == 0) {
|
|
|
|
grid[i].setHSV(hue, 180, 192);
|
|
|
|
} else {
|
|
|
|
grid[i] = CRGB::Black;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
left[i]--;
|
|
|
|
}
|
|
|
|
}
|
2024-06-09 21:53:19 -06:00
|
|
|
show();
|
2022-07-17 22:22:16 -06:00
|
|
|
pause(20);
|
2022-01-01 09:35:06 -07:00
|
|
|
}
|
2021-12-31 15:58:27 -07:00
|
|
|
}
|
|
|
|
|
2023-01-06 12:50:46 -07:00
|
|
|
uint8_t cm5xlat(uint8_t width, uint8_t pos) {
|
|
|
|
if (width == 0) {
|
|
|
|
return pos;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint8_t x = pos % width;
|
|
|
|
uint8_t y = pos / width;
|
|
|
|
uint8_t odd = y % 2;
|
|
|
|
|
|
|
|
return (y*width) + ((width-x-1)*odd) + (x*(1-odd));
|
|
|
|
}
|
|
|
|
|
|
|
|
void cm5(uint8_t width=0, int cycles=200) {
|
2022-07-17 22:22:16 -06:00
|
|
|
for (int frame = 0; frame < cycles; frame++) {
|
|
|
|
int val = 127 * random(2);
|
2023-01-06 12:50:46 -07:00
|
|
|
for (uint8_t pos = 0; pos < GRIDLEN; pos++) {
|
|
|
|
uint8_t xpos = cm5xlat(width, pos);
|
2022-07-17 22:22:16 -06:00
|
|
|
if (pos < GRIDLEN-1) {
|
2023-01-06 12:50:46 -07:00
|
|
|
uint8_t x2pos = cm5xlat(width, pos+1);
|
|
|
|
grid[xpos] = grid[x2pos];
|
2022-07-17 22:22:16 -06:00
|
|
|
} else {
|
2023-01-06 12:50:46 -07:00
|
|
|
grid[xpos] = CHSV(0, 255, val);
|
2022-07-17 22:22:16 -06:00
|
|
|
}
|
|
|
|
}
|
2024-06-09 21:53:19 -06:00
|
|
|
show();
|
2022-07-17 22:22:16 -06:00
|
|
|
pause(500);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-06-09 21:53:19 -06:00
|
|
|
// Display MAC address at startup.
|
2023-12-06 13:33:33 -07:00
|
|
|
void displayMacAddress(int cycles=40) {
|
|
|
|
uint64_t addr = ESP.getEfuseMac();
|
|
|
|
|
2024-06-09 21:53:19 -06:00
|
|
|
Serial.println("mac=" + String(ESP.getEfuseMac(), HEX));
|
|
|
|
|
|
|
|
// Set some custom things per device.
|
|
|
|
// It would have been nice if doing this in the Access Point UI were easier than switching the MAC address.
|
|
|
|
switch (addr) {
|
|
|
|
case 0x18fc1d519140:
|
|
|
|
rotation = 270;
|
|
|
|
break;
|
|
|
|
}
|
2023-12-06 13:33:33 -07:00
|
|
|
|
2024-06-09 21:53:19 -06:00
|
|
|
for (; cycles > 0; cycles -= 1) {
|
|
|
|
// Top: version
|
|
|
|
for (int i = 0; i < 8; i++) {
|
|
|
|
bool bit = (VERSION>>i) & 1;
|
|
|
|
grid[7-i] = bit ? CRGB::Black : CRGB::Aqua;
|
2023-12-06 13:33:33 -07:00
|
|
|
}
|
2024-06-09 21:53:19 -06:00
|
|
|
|
|
|
|
// Middle: MAC address
|
2024-06-09 22:16:11 -06:00
|
|
|
for (int i = 0; i < 48; i++) {
|
|
|
|
int pos = i + 8;
|
|
|
|
grid[pos] = CHSV(HUE_YELLOW, 255, ((addr>>(47-i)) & 1)?255:64);
|
2023-12-06 13:33:33 -07:00
|
|
|
}
|
2024-06-09 21:53:19 -06:00
|
|
|
|
|
|
|
// Bottom: connected status
|
|
|
|
fill_solid(grid+56, 8, connected() ? CRGB::Aqua : CRGB::Red);
|
|
|
|
|
|
|
|
show();
|
2023-12-06 13:33:33 -07:00
|
|
|
pause(250*MILLISECOND);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-07-17 22:22:16 -06:00
|
|
|
// Art from the network
|
2022-07-19 21:14:34 -06:00
|
|
|
int NetArtFrames = 0;
|
|
|
|
CRGB NetArt[8][GRIDLEN];
|
2022-07-17 22:22:16 -06:00
|
|
|
|
2022-07-19 21:14:34 -06:00
|
|
|
void netart(int count=40) {
|
|
|
|
if (NetArtFrames < 1) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (int i = 0; i < count; i++) {
|
|
|
|
memcpy(grid, NetArt[i%NetArtFrames], GRIDLEN*3);
|
2024-06-09 21:53:19 -06:00
|
|
|
show();
|
2022-07-19 21:14:34 -06:00
|
|
|
pause(500);
|
2022-07-17 22:22:16 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-07-19 21:14:34 -06:00
|
|
|
uint8_t netgetStatus(uint8_t hue) {
|
2022-07-17 22:22:16 -06:00
|
|
|
static int positions[4] = {0};
|
|
|
|
for (int j = 0; j < 4; j++) {
|
|
|
|
grid[positions[j]] = CHSV(0, 0, 0);
|
|
|
|
positions[j] = random(GRIDLEN);
|
|
|
|
grid[positions[j]] = CHSV(hue, 255, 180);
|
|
|
|
}
|
2024-06-09 21:53:19 -06:00
|
|
|
show();
|
2022-07-17 22:22:16 -06:00
|
|
|
pause(500);
|
|
|
|
return hue;
|
2021-12-31 15:58:27 -07:00
|
|
|
}
|
|
|
|
|
2022-07-19 21:14:34 -06:00
|
|
|
void netget(int count=60) {
|
|
|
|
uint8_t hue = netgetStatus(HUE_BLUE);
|
2023-12-06 13:33:33 -07:00
|
|
|
static unsigned long nextPull = 0; // when to pull next
|
2022-07-17 22:22:16 -06:00
|
|
|
|
2023-01-06 12:50:46 -07:00
|
|
|
#if defined(ART_HOSTNAME) && defined(ART_PORT) && defined(ART_PATH)
|
2023-12-06 13:33:33 -07:00
|
|
|
if (millis() < nextPull) {
|
|
|
|
// Let's not bombard the server
|
|
|
|
hue = HUE_ORANGE;
|
|
|
|
} else if (connected()) {
|
2022-07-17 22:22:16 -06:00
|
|
|
WiFiClientSecure scli;
|
|
|
|
|
2023-12-06 13:33:33 -07:00
|
|
|
nextPull = millis() + IMAGE_PULL_MIN_INTERVAL;
|
|
|
|
|
2023-01-06 12:50:46 -07:00
|
|
|
hue = netgetStatus(HUE_AQUA);
|
2022-07-17 22:22:16 -06:00
|
|
|
scli.setInsecure();
|
|
|
|
|
2022-07-19 21:14:34 -06:00
|
|
|
HttpClient https(scli, ART_HOSTNAME, ART_PORT);
|
|
|
|
do {
|
2023-12-06 13:33:33 -07:00
|
|
|
String path = String(ART_PATH) + "?mac=" + String(ESP.getEfuseMac(), HEX);
|
|
|
|
Serial.println(path);
|
|
|
|
if (https.get(path) != 0) break;
|
2023-01-06 12:50:46 -07:00
|
|
|
hue = netgetStatus(HUE_GREEN);
|
2022-07-19 21:14:34 -06:00
|
|
|
|
|
|
|
if (https.skipResponseHeaders() != HTTP_SUCCESS) break;
|
2023-01-06 12:50:46 -07:00
|
|
|
hue = netgetStatus(HUE_YELLOW);
|
2022-07-19 21:14:34 -06:00
|
|
|
|
2023-09-04 16:30:21 -06:00
|
|
|
size_t readBytes = 0;
|
|
|
|
for (int i = 0; i < 12; i++) {
|
|
|
|
size_t artBytesLeft = sizeof(NetArt) - readBytes;
|
|
|
|
|
|
|
|
if (https.endOfBodyReached() || (artBytesLeft == 0)) {
|
|
|
|
hue = netgetStatus(HUE_ORANGE);
|
|
|
|
NetArtFrames = (readBytes / 3) / GRIDLEN;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
int l = https.read((uint8_t *)NetArt + readBytes, artBytesLeft);
|
|
|
|
if (-1 == l) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
readBytes += l;
|
|
|
|
}
|
2022-07-19 21:14:34 -06:00
|
|
|
} while(false);
|
|
|
|
https.stop();
|
2022-07-17 22:22:16 -06:00
|
|
|
}
|
2023-01-06 12:50:46 -07:00
|
|
|
#endif
|
2022-07-17 22:22:16 -06:00
|
|
|
|
|
|
|
for (int i = 0; i < count; i++) {
|
|
|
|
netgetStatus(hue);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-07-18 07:43:19 -06:00
|
|
|
const int spinner_pos[4] = {27, 28, 36, 35};
|
|
|
|
void spinner(int count=32) {
|
2022-07-18 07:42:52 -06:00
|
|
|
for (int i = 0; i < count; i++) {
|
2022-07-18 07:43:19 -06:00
|
|
|
int pos = spinner_pos[i % 4];
|
2022-07-18 07:42:52 -06:00
|
|
|
grid[pos] = CRGB::OliveDrab;
|
2024-06-09 21:53:19 -06:00
|
|
|
show();
|
2022-07-18 07:42:52 -06:00
|
|
|
pause(125);
|
|
|
|
grid[pos] = CRGB::Black;
|
|
|
|
}
|
|
|
|
}
|
2022-07-17 22:22:16 -06:00
|
|
|
|
2024-06-09 21:53:19 -06:00
|
|
|
void displayTimeDozenal(unsigned long duration = 20*SECOND) {
|
2023-12-08 20:37:55 -07:00
|
|
|
if (!clock_is_set()) return;
|
2023-01-07 12:12:46 -07:00
|
|
|
unsigned long end = millis() + duration;
|
2023-12-08 20:37:55 -07:00
|
|
|
|
2024-06-09 21:53:19 -06:00
|
|
|
clear();
|
2023-01-07 12:12:46 -07:00
|
|
|
|
|
|
|
while (millis() < end) {
|
2023-12-08 20:37:55 -07:00
|
|
|
struct tm info;
|
|
|
|
getLocalTime(&info);
|
|
|
|
|
|
|
|
int hh = info.tm_hour;
|
|
|
|
int mmss = (info.tm_min * 60) + info.tm_sec;
|
2023-01-07 12:12:46 -07:00
|
|
|
uint8_t hue = HUE_YELLOW;
|
|
|
|
|
2023-01-08 17:15:33 -07:00
|
|
|
// Top: Hours
|
2023-12-08 20:37:55 -07:00
|
|
|
if (hh >= 12) {
|
2023-01-07 12:12:46 -07:00
|
|
|
hue = HUE_ORANGE;
|
|
|
|
hh -= 12;
|
|
|
|
}
|
|
|
|
|
2023-01-08 17:15:33 -07:00
|
|
|
// Middle: 5m (300s)
|
|
|
|
uint8_t mm = (mmss/300) % 12;
|
|
|
|
|
|
|
|
// Bottom: 25s
|
|
|
|
uint8_t ss = (mmss/25) % 12;
|
|
|
|
|
|
|
|
// Outer: 5s
|
|
|
|
uint8_t s = (mmss/5) % 5;
|
2023-12-08 20:37:55 -07:00
|
|
|
grid[64 - 7 - 1] = CHSV(HUE_GREEN, 128, (s==1)?96:0);
|
|
|
|
grid[64 - 15 - 1] = CHSV(HUE_GREEN, 128, (s==2)?96:0);
|
|
|
|
grid[64 - 8 - 1] = CHSV(HUE_GREEN, 128, (s==3)?96:0);
|
|
|
|
grid[64 - 0 - 1] = CHSV(HUE_GREEN, 128, (s==4)?96:0);
|
2023-01-08 17:15:33 -07:00
|
|
|
|
2023-01-07 12:12:46 -07:00
|
|
|
for (int i = 0; i < 12; i++) {
|
|
|
|
// Omit first and last position on a row
|
|
|
|
int pos = i + 1;
|
|
|
|
if (pos > 6) {
|
|
|
|
pos += 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
grid[pos + 0] = CHSV(hue, 255, (i<hh)?128:48);
|
2023-01-08 17:15:33 -07:00
|
|
|
grid[pos + 24] = CHSV(HUE_RED, 255, (i<mm)?128:48);
|
|
|
|
grid[pos + 48] = CHSV(HUE_PINK, 128, (i<ss)?96:48);
|
2023-01-07 12:12:46 -07:00
|
|
|
}
|
2024-06-09 21:53:19 -06:00
|
|
|
show();
|
2023-01-07 12:12:46 -07:00
|
|
|
|
|
|
|
pause(250 * MILLISECOND);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-12-06 13:33:33 -07:00
|
|
|
void setup() {
|
|
|
|
pinMode(RESET_PIN, INPUT_PULLUP);
|
|
|
|
pinMode(LED_BUILTIN, OUTPUT);
|
|
|
|
Serial.begin(19200);
|
2024-06-09 21:53:19 -06:00
|
|
|
FastLED.addLeds<WS2812, NEOPIXEL_PIN, GRB>(actual, GRIDLEN);
|
2023-12-06 13:33:33 -07:00
|
|
|
// Maybe it's the plexiglass, but for my build, I need to dial back the red
|
2024-06-09 21:53:19 -06:00
|
|
|
//FastLED.setCorrection(0xd0ffff);
|
2023-12-06 13:33:33 -07:00
|
|
|
network_setup(WFM_PASSWORD);
|
|
|
|
|
|
|
|
// Show our mac address, for debugging?
|
2024-06-09 21:53:19 -06:00
|
|
|
FastLED.setBrightness(DAY_BRIGHTNESS);
|
2023-12-06 13:33:33 -07:00
|
|
|
displayMacAddress();
|
|
|
|
sparkle();
|
|
|
|
}
|
|
|
|
|
2021-12-31 15:58:27 -07:00
|
|
|
void loop() {
|
2022-07-17 22:22:16 -06:00
|
|
|
Picker p;
|
2023-01-07 12:12:46 -07:00
|
|
|
bool day = true;
|
|
|
|
|
2023-12-08 20:37:55 -07:00
|
|
|
if (clock_is_set()) {
|
|
|
|
struct tm info;
|
|
|
|
getLocalTime(&info);
|
|
|
|
day = ((info.tm_hour >= DAY_BEGIN) && (info.tm_hour < DAY_END));
|
2023-01-07 12:12:46 -07:00
|
|
|
}
|
|
|
|
FastLED.setBrightness(day?DAY_BRIGHTNESS:NIGHT_BRIGHTNESS);
|
2022-07-17 22:22:16 -06:00
|
|
|
|
2024-06-09 21:53:19 -06:00
|
|
|
// At night, always display the clock
|
2023-12-08 20:37:55 -07:00
|
|
|
if (!day && clock_is_set()) {
|
2024-06-09 21:53:19 -06:00
|
|
|
displayTimeDigits(day);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (p.Pick(4) && clock_is_set()) {
|
|
|
|
displayTimeDigits(day, 2 * MINUTE);
|
2023-12-08 20:37:55 -07:00
|
|
|
} else if (p.Pick(4) && clock_is_set()) {
|
2024-06-09 21:53:19 -06:00
|
|
|
displayTimeDozenal();
|
|
|
|
} else if (p.Pick(4)) {
|
2023-01-07 12:12:46 -07:00
|
|
|
netget();
|
|
|
|
} else if (day && p.Pick(4)) {
|
|
|
|
// These can be hella bright
|
2023-01-06 12:50:46 -07:00
|
|
|
netart();
|
2023-01-07 12:12:46 -07:00
|
|
|
} else if (p.Pick(1)) {
|
2022-07-17 22:22:16 -06:00
|
|
|
fade();
|
|
|
|
singleCursor(20);
|
|
|
|
} else if (p.Pick(1)) {
|
|
|
|
sparkle();
|
|
|
|
} else if (p.Pick(4)) {
|
|
|
|
singleCursor();
|
|
|
|
} else if (p.Pick(8)) {
|
|
|
|
conwayish();
|
|
|
|
} else if (p.Pick(8)) {
|
|
|
|
glitchPulse();
|
2023-01-06 12:50:46 -07:00
|
|
|
} else if (p.Pick(2)) {
|
|
|
|
cm5(0);
|
|
|
|
} else if (p.Pick(2)) {
|
|
|
|
cm5(8);
|
|
|
|
} else if (p.Pick(2)) {
|
|
|
|
cm5(16);
|
2023-01-08 17:15:33 -07:00
|
|
|
}
|
2022-07-17 22:22:16 -06:00
|
|
|
}
|