pitrix/effects.h

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;
};