226 lines
5.9 KiB
C++
226 lines
5.9 KiB
C++
class Effect {
|
|
public:
|
|
virtual void loop() {};
|
|
};
|
|
|
|
class Bell : public Effect {
|
|
private:
|
|
|
|
CRGB color_on = CRGB(0xFFFF00);
|
|
CRGB color_off= CRGB(0x000000);
|
|
boolean invert = false;
|
|
|
|
public:
|
|
void loop() {
|
|
for(int y=0; y<16; y++) {
|
|
for(int x=0; x<2; x++) {
|
|
for(int z=0; z<8; z++) {
|
|
leds[XYsafe(x*8+z, y)] = sprite_bell[y*2+x]>>(7-z) & 1 ^ invert ? color_on : color_off;
|
|
}
|
|
}
|
|
}
|
|
|
|
EVERY_N_MILLISECONDS(300) {
|
|
invert = !invert;
|
|
}
|
|
}
|
|
};
|
|
|
|
class Clock : public Effect {
|
|
private:
|
|
CRGB color_h = CRGB(0xFF0000);
|
|
CRGB color_m = CRGB(0x00FF00);
|
|
CRGB color_colon = CRGB(0xFFFF00);
|
|
|
|
void drawNumber(uint8_t number, int x, int y, CRGB color) {
|
|
char buffer[7];
|
|
sprintf(buffer, "%02d", number);
|
|
drawText(buffer, x, y, color);
|
|
}
|
|
|
|
void drawText(char *text, int x, int y, CRGB color) {
|
|
for (int i = 0; i < strlen(text); i++) {
|
|
drawSprite(font_char(numbers4x7, text[i]), x + i * 4, y, color);
|
|
}
|
|
}
|
|
|
|
unsigned char* font_char(unsigned char* font, char c) {
|
|
return &font[(c - 48) * 4];
|
|
}
|
|
|
|
void drawSprite(unsigned char* sprite, int xOffset, int yOffset, CRGB color) {
|
|
for ( byte y = 0; y < 7; y++) {
|
|
for ( byte x = 0; x < 4; x++) {
|
|
bool on = (sprite[x] >> y & 1) * 255;
|
|
if (on) {
|
|
leds[ XYsafe(x + xOffset, y + yOffset) ] = color;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
public:
|
|
Clock() {}
|
|
void loop() {
|
|
clear();
|
|
drawNumber(ntpClient.getHours(), 0, 0, color_h);
|
|
drawNumber(ntpClient.getMinutes(), 8, 0, color_m);
|
|
/*if (ntpClient.getSeconds() & 1) {
|
|
leds[XYsafe(13, 2)] = color_colon;
|
|
leds[XYsafe(13, 5)] = color_colon;
|
|
}*/
|
|
drawNumber(ntpClient.getSeconds(), 8, 8, color_colon);
|
|
}
|
|
};
|
|
|
|
class SmallClock : public Effect {
|
|
private:
|
|
CRGB color_h = CRGB(0xFF0000);
|
|
CRGB color_m = CRGB(0x00FF00);
|
|
CRGB color_colon = CRGB(0xFFFF00);
|
|
|
|
public:
|
|
SmallClock() {}
|
|
|
|
void loop() {
|
|
clear();
|
|
int h = ntpClient.getHours();
|
|
drawDigit(numbers3x5, 3, 5, 0, 11, h/10, color_h);
|
|
drawDigit(numbers3x5, 3, 5, 4, 11, h%10, color_h);
|
|
int m = ntpClient.getMinutes();
|
|
drawDigit(numbers3x5, 3, 5, 9, 11, m/10, color_m);
|
|
drawDigit(numbers3x5, 3, 5, 13, 11, m%10, color_m);
|
|
if (ntpClient.getSeconds() & 1) {
|
|
leds[XYsafe(7, 12)] = color_colon;
|
|
leds[XYsafe(7, 14)] = color_colon;
|
|
}
|
|
}
|
|
};
|
|
|
|
class Sinematrix3 : public Effect {
|
|
private:
|
|
double pangle = 0;
|
|
double angle = 0;
|
|
double sx = 0;
|
|
double sy = 0;
|
|
double tx = 0;
|
|
double ty = 0;
|
|
double cx = 0;
|
|
double cy = 0;
|
|
double rcx = 0;
|
|
double rcy = 0;
|
|
double angle2 = 0;
|
|
double sx2 = 0;
|
|
double sy2 = 0;
|
|
double tx2 = 0;
|
|
double ty2 = 0;
|
|
double basecol = 0;
|
|
double fx = 1.0/(LED_WIDTH/PI);
|
|
double fy = 1.0/(LED_HEIGHT/PI);
|
|
Matrix rotate;
|
|
|
|
public:
|
|
Sinematrix3() {}
|
|
void loop() {
|
|
pangle = addmodpi( pangle, 0.0133 + (angle/256) );
|
|
angle = cos(pangle) * PI;
|
|
sx = addmodpi( sx, 0.00673 );
|
|
sy = addmodpi( sy, 0.00437 );
|
|
tx = addmodpi( tx, 0.00239 );
|
|
ty = addmodpi( ty, 0.00293 );
|
|
cx = addmodpi( cx, 0.00197 );
|
|
cy = addmodpi( cy, 0.00227 );
|
|
rcx = (LED_WIDTH/2) + (sin(cx) * LED_WIDTH);
|
|
rcy = (LED_HEIGHT/2) + (sin(cy) * LED_HEIGHT);
|
|
angle2 = addmodpi( angle2, 0.0029 );
|
|
sx2 = addmodpi( sx2, 0.0041);
|
|
sy2 = addmodpi( sy2, 0.0031);
|
|
tx2 = addmodpi( tx2, 0.0011 );
|
|
ty2 = addmodpi( ty2, 0.0023 );
|
|
basecol = addmod( basecol, 1.0, 0.007 );
|
|
|
|
rotate = {
|
|
.a11 = cos(angle),
|
|
.a12 = -sin(angle),
|
|
.a21 = sin(angle),
|
|
.a22 = cos(angle)
|
|
};
|
|
Matrix zoom = {
|
|
.a11 = sin(sx)/4.0 + 0.15,
|
|
.a12 = 0, //atan(cos(sx2)),
|
|
.a21 = 0, //atan(cos(sy2)),
|
|
.a22 = cos(sy)/4.0 + 0.15
|
|
};
|
|
Vector translate = {
|
|
.x1 = sin(tx) * LED_WIDTH,
|
|
.x2 = sin(ty) * LED_HEIGHT
|
|
};
|
|
|
|
for( int x = 0; x < LED_WIDTH; x++ ) {
|
|
for( int y = 0; y < LED_HEIGHT; y++ ) {
|
|
Vector c = add(multiply( multiply(rotate, zoom), { .x1 = x-rcx, .x2 = y-rcy } ), translate);
|
|
//Vector c2 = add(multiply( multiply(zoom2, rotate2), { .x1 = x, .x2 = y } ), translate2);
|
|
leds[XYsafe(x,y)] = CHSV((basecol+basefield(c.x1, c.x2))*255, 255, 255); //31+(sines(c2.x1-10, c2.x2-10)*224));
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
class Static : public Effect {
|
|
private:
|
|
CRGB color;
|
|
public:
|
|
Static(CRGB col) {
|
|
color = col;
|
|
}
|
|
void loop() {
|
|
EVERY_N_SECONDS(1) {
|
|
for ( int i = 0; i < LED_COUNT; i++) {
|
|
leds[i] = color;
|
|
}
|
|
FastLED.show();
|
|
}
|
|
}
|
|
};
|
|
|
|
class Animation : public Effect {
|
|
private:
|
|
AnimationData *animation;
|
|
int frame = 0;
|
|
public:
|
|
Animation(AnimationData *anim) {
|
|
animation = anim;
|
|
}
|
|
void loop() {
|
|
CRGB colors[animation->color_count];
|
|
int led_index = 0;
|
|
for(int i=0; i<animation->color_count; i++) colors[i] = CRGB(animation->colors[i]);
|
|
for(int i=animation->offsets[frame]; i<animation->offsets[frame+1]; i++) {
|
|
if (animation->data[i]==255) { // Run-length encoded data
|
|
for (int j=0; j<animation->data[i+1]; j++) {
|
|
if (frame==0 || animation->data[i+2]>0) {
|
|
set(led_index, colors[animation->data[i+2]]);
|
|
}
|
|
led_index++;
|
|
}
|
|
i+=2;
|
|
} else {
|
|
if (frame==0 || animation->data[i]>0) {
|
|
set(led_index, colors[animation->data[i]]);
|
|
}
|
|
led_index++;
|
|
}
|
|
}
|
|
EVERY_N_MILLISECONDS(250) {
|
|
frame = (frame + 1) % animation->frame_count;
|
|
}
|
|
}
|
|
void set(int i, CRGB color) {
|
|
setPixel(i % animation->w, i / animation->h, color);
|
|
}
|
|
};
|
|
|
|
struct EffectEntry {
|
|
char* name;
|
|
Effect* effect;
|
|
};
|