Better and more SimpleEffects.
* Calculations are done using doubles for much easier code. * Binary flags instead of boolean variables for configuration. * New effects sineline, barbershop and zigzag.
This commit is contained in:
parent
0a4a62d7c8
commit
a6af2829ee
@ -1,21 +1,30 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "Effect.h"
|
#include "Effect.h"
|
||||||
#include "prototypes.h"
|
#include "prototypes.h"
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
|
#define SE_CYCLE_COLORS 1 // Slowly cycle through the rainbow.
|
||||||
|
#define SE_RANDOM_PIXEL_COLORS 2 // Every pixel gets a random color every frame.
|
||||||
|
#define SE_ONLY_POSITIVE 4 // Only use colors, not white. This is equivalent to running your output through abs()
|
||||||
|
#define SE_FADEOUT 8 // Fades the old image out. Returning 0 doesn't change the pixel's value.
|
||||||
|
#define SE_RANDOM_STATIC_COLOR 16 // Sets a random static color at start of the effect.
|
||||||
|
#define SE_DEBUG 32 // Prints debug messages.
|
||||||
|
|
||||||
class SimpleEffect : public Effect {
|
class SimpleEffect : public Effect {
|
||||||
protected:
|
protected:
|
||||||
Window* window = &Window::window_full; // Use a full screen window per default.
|
Window* window = &Window::window_full; // Use a full screen window per default.
|
||||||
boolean _fade_out = false;
|
|
||||||
boolean _random_colors = false;
|
|
||||||
boolean _cycle_color = true;
|
|
||||||
uint8_t _color = 0;
|
uint8_t _color = 0;
|
||||||
|
uint16_t _flags;
|
||||||
String _name;
|
String _name;
|
||||||
simple_effect_t _method;
|
simple_effect_t _method;
|
||||||
public:
|
public:
|
||||||
SimpleEffect(String name, simple_effect_t method): _name { name }, _method { method } {};
|
SimpleEffect(String name, uint16_t flags, simple_effect_t method): _name { name }, _method { method } {
|
||||||
SimpleEffect* with_fadeout() { _fade_out=true; return this;}
|
_flags = flags;
|
||||||
SimpleEffect* with_random_colors() { _random_colors=true; return this;}
|
if (_flags & SE_RANDOM_STATIC_COLOR) {
|
||||||
SimpleEffect* with_static_color(uint8_t color) { _cycle_color=false; _color=color; return this; }
|
_color = random8();
|
||||||
|
_flags &= ~SE_CYCLE_COLORS & ~SE_RANDOM_PIXEL_COLORS;
|
||||||
|
}
|
||||||
|
};
|
||||||
void loop(uint16_t ms) override;
|
void loop(uint16_t ms) override;
|
||||||
String get_name() { return _name; };
|
String get_name() { return _name; };
|
||||||
boolean can_be_shown_with_clock() { return true; }
|
boolean can_be_shown_with_clock() { return true; }
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
#include "effects/clock.h"
|
#include "effects/clock.h"
|
||||||
#include "effects/timer.h"
|
#include "effects/timer.h"
|
||||||
|
|
||||||
#define SIMPLE_EFFECT [](accum88 t, uint16_t i, uint8_t x, uint8_t y)->int8_t
|
#define SIMPLE_EFFECT(name, use_in_cycle, flags, ...) {name, use_in_cycle, [](){ return new SimpleEffect(name, flags, [](double t, uint16_t i, uint8_t x, uint8_t y)->double __VA_ARGS__ ); }}
|
||||||
|
|
||||||
struct EffectEntry {
|
struct EffectEntry {
|
||||||
const char* name;
|
const char* name;
|
||||||
|
@ -33,4 +33,4 @@ typedef struct {
|
|||||||
uint16_t y;
|
uint16_t y;
|
||||||
} Coords;
|
} Coords;
|
||||||
|
|
||||||
typedef std::function<int8_t(accum88, uint16_t, uint8_t, uint8_t)> simple_effect_t;
|
typedef std::function<double(double, uint16_t, uint8_t, uint8_t)> simple_effect_t;
|
@ -1,21 +1,33 @@
|
|||||||
#include "SimpleEffect.h"
|
#include "SimpleEffect.h"
|
||||||
|
|
||||||
void SimpleEffect::loop(uint16_t ms) {
|
void SimpleEffect::loop(uint16_t ms) {
|
||||||
if (_fade_out) window->fadeToBlackBy(3);
|
if (_flags & SE_FADEOUT) window->fadeToBlackBy(3);
|
||||||
accum88 t = millis() * 0x100 / 1000;
|
double t = 0.001 * millis();
|
||||||
for(uint8_t x=0; x<window->width; x++) for(uint8_t y=0; y<window->height; y++) {
|
for(uint8_t x=0; x<window->width; x++) for(uint8_t y=0; y<window->height; y++) {
|
||||||
uint16_t i = y*window->width + x;
|
uint16_t i = y*window->width + x;
|
||||||
int8_t r = _method(t, i, x, y);
|
double r = _method(t, i, x, y);
|
||||||
|
//if (i==0) Serial.printf("t=%f i=%d x=%d y=%d => r=%f, abs(r)=%d\n", t, i, x, y, r, abs(r)*255);
|
||||||
if (_fade_out && r==0) {
|
if ((_flags & SE_DEBUG) && i==17) Serial.printf("t=%f i=%d x=%d y=%d => r=%f, abs(r*255)=%d\n", t, i, x, y, r, (int)abs(r*255));
|
||||||
|
if ((_flags & SE_FADEOUT) && r==0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Clamp r between -1.0 and +1.0
|
||||||
|
if (r<-1.0) {
|
||||||
|
r = -1.0;
|
||||||
|
} else if (r>1.0) {
|
||||||
|
r = 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_flags & SE_ONLY_POSITIVE) {
|
||||||
|
r = abs(r);
|
||||||
|
}
|
||||||
|
|
||||||
CRGB color;
|
CRGB color;
|
||||||
if (_random_colors) {
|
if (_flags & SE_RANDOM_PIXEL_COLORS) {
|
||||||
color = CHSV(random8(), 255, abs(r)*2);
|
color = CHSV(random8(), 255, abs(r*255));
|
||||||
} else {
|
} else {
|
||||||
color = CHSV(_cycle_color ? baseHue : _color, r<0?0:255, abs(r)*2);
|
color = CHSV(_flags & SE_CYCLE_COLORS ? baseHue : _color, r<0?0:255, abs(r*255));
|
||||||
}
|
}
|
||||||
|
|
||||||
window->setPixel(x, y, &color);
|
window->setPixel(x, y, &color);
|
||||||
|
@ -35,45 +35,48 @@ TimerEffect effect_timer;
|
|||||||
|
|
||||||
// We're using 0 instead of false to get a better visual difference between true and false.
|
// We're using 0 instead of false to get a better visual difference between true and false.
|
||||||
EffectEntry effects[] = {
|
EffectEntry effects[] = {
|
||||||
/* 0 */ {"sinematrix3", true, [](){ return new Sinematrix3Effect(); }},
|
/* 0 */ {"sinematrix3", true, [](){ return new Sinematrix3Effect(); }},
|
||||||
/* 1 */ {"big_clock", true, [](){ return new BigClockEffect(); }},
|
/* 1 */ {"big_clock", true, [](){ return new BigClockEffect(); }},
|
||||||
/* 2 */ {"clock", 0, [](){ return new ClockEffect(); }},
|
/* 2 */ {"clock", 0, [](){ return new ClockEffect(); }},
|
||||||
/* 3 */ {"bell", 0, [](){ return AnimationEffect::Blinker("/bell.pia", 300, 0xFFFF00); }},
|
/* 3 */ {"bell", 0, [](){ return AnimationEffect::Blinker("/bell.pia", 300, 0xFFFF00); }},
|
||||||
/* 4 */ {"off", 0, [](){ return new StaticEffect(0x000000); }},
|
/* 4 */ {"off", 0, [](){ return new StaticEffect(0x000000); }},
|
||||||
/* 5 */ {"single_dynamic", true, [](){ return new SingleDynamicEffect(); }},
|
/* 5 */ {"single_dynamic", true, [](){ return new SingleDynamicEffect(); }},
|
||||||
/* 6 */ {"multi_dynamic", true, [](){ return new MultiDynamicEffect(); }},
|
/* 6 */ {"multi_dynamic", true, [](){ return new MultiDynamicEffect(); }},
|
||||||
/* 7 */ {"big_dynamic", true, [](){ return new BigDynamicEffect(); }},
|
/* 7 */ {"big_dynamic", true, [](){ return new BigDynamicEffect(); }},
|
||||||
/* 8 */ {"matrix", true, [](){ return new MatrixEffect(); }},
|
/* 8 */ {"matrix", true, [](){ return new MatrixEffect(); }},
|
||||||
/* 9 */ {"random_matrix", true, [](){ return new RandomMatrixEffect(); }},
|
/* 9 */ {"random_matrix", true, [](){ return new RandomMatrixEffect(); }},
|
||||||
/* 10 */ {"rainbow_matrix", true, [](){ return new RainbowMatrixEffect(); }},
|
/* 10 */ {"rainbow_matrix", true, [](){ return new RainbowMatrixEffect(); }},
|
||||||
/* 11 */ {"cycle", 0, [](){ return new CycleEffect(); }},
|
/* 11 */ {"cycle", 0, [](){ return new CycleEffect(); }},
|
||||||
/* 12 */ {"twirl", true, [](){ return new TwirlEffect(); }},
|
/* 12 */ {"twirl", true, [](){ return new TwirlEffect(); }},
|
||||||
/* 13 */ {"confetti", true, [](){ return (new SimpleEffect("confetti", SIMPLE_EFFECT{return random8()>252 ? 127 : 0;}))->with_fadeout();}},
|
/* 13 */ SIMPLE_EFFECT("confetti", true, SE_CYCLE_COLORS | SE_FADEOUT, {return random8()>252?1:0;}),
|
||||||
/* 14 */ {"rainbow_confetti", true, [](){ return (new SimpleEffect("rainbow_confetti", SIMPLE_EFFECT{return random8()>252 ? 127 : 0;}))->with_fadeout()->with_random_colors();}},
|
/* 14 */ SIMPLE_EFFECT("rainbow_confetti", true, SE_RANDOM_PIXEL_COLORS | SE_FADEOUT, {return random8()>252?1:0;}),
|
||||||
/* 15 */ {"snake", true, [](){ return new SnakeEffect(); }},
|
/* 15 */ {"snake", true, [](){ return new SnakeEffect(); }},
|
||||||
/* 16 */ {"firework", true, [](){ return new FireworkEffect(); }},
|
/* 16 */ {"firework", true, [](){ return new FireworkEffect(); }},
|
||||||
/* 17 */ {"gol", true, [](){ return new GolEffect(); }},
|
/* 17 */ {"gol", true, [](){ return new GolEffect(); }},
|
||||||
/* 18 */ {"pixel_clock", 0, [](){ return new PixelClockEffect(); }},
|
/* 18 */ {"pixel_clock", 0, [](){ return new PixelClockEffect(); }},
|
||||||
/* 19 */ {"dvd", true, [](){ return new DvdEffect(); }},
|
/* 19 */ {"dvd", true, [](){ return new DvdEffect(); }},
|
||||||
/* 20 */ {"analog_clock", 0, [](){ return new AnalogClockEffect(); }},
|
/* 20 */ {"analog_clock", 0, [](){ return new AnalogClockEffect(); }},
|
||||||
/* 21 */ {"sines", true, [](){ return new SinesEffect(); }},
|
/* 21 */ {"sines", true, [](){ return new SinesEffect(); }},
|
||||||
/* 22 */ {"blur2d", true, [](){ return new Blur2DEffect(); }},
|
/* 22 */ {"blur2d", true, [](){ return new Blur2DEffect(); }},
|
||||||
/* 23 */ {"marquee", 0, [](){ return new MarqueeEffect(); }},
|
/* 23 */ {"marquee", 0, [](){ return new MarqueeEffect(); }},
|
||||||
/* 24 */ {"night_clock", 0, [](){ return new NightClockEffect(); }},
|
/* 24 */ {"night_clock", 0, [](){ return new NightClockEffect(); }},
|
||||||
/* 25 */ {"tv_static", 0, [](){ return new TvStaticEffect(); }},
|
/* 25 */ {"tv_static", 0, [](){ return new TvStaticEffect(); }},
|
||||||
/* 26 */ {"sinematrix3_rainbow", true, [](){ return new Sinematrix3Effect(SINEMATRIX_COLOR_RAINBOW); }},
|
/* 26 */ {"sinematrix3_rainbow", true, [](){ return new Sinematrix3Effect(SINEMATRIX_COLOR_RAINBOW); }},
|
||||||
/* 27 */ {"sinematrix3_purplefly", true, [](){ return new Sinematrix3Effect(SINEMATRIX_COLOR_PURPLEFLY); }},
|
/* 27 */ {"sinematrix3_purplefly", true, [](){ return new Sinematrix3Effect(SINEMATRIX_COLOR_PURPLEFLY); }},
|
||||||
/* 28 */ {"lightspeed", true, [](){ return new LightspeedEffect(); }},
|
/* 28 */ {"lightspeed", true, [](){ return new LightspeedEffect(); }},
|
||||||
/* 29 */ {"koopa", 0, [](){ return new AnimationEffect("/koopa.pia"); }},
|
/* 29 */ {"koopa", 0, [](){ return new AnimationEffect("/koopa.pia"); }},
|
||||||
/* 30 */ {"cake", 0, [](){ return new AnimationEffect("/cake.pia"); }},
|
/* 30 */ {"cake", 0, [](){ return new AnimationEffect("/cake.pia"); }},
|
||||||
/* 31 */ {"child", 0, [](){ return AnimationEffect::Blinker("/child.pia", 300, 0xFFFF00); }},
|
/* 31 */ {"child", 0, [](){ return AnimationEffect::Blinker("/child.pia", 300, 0xFFFF00); }},
|
||||||
/* 32 */ {"diamond", true, [](){ return new DiamondEffect(); }},
|
/* 32 */ {"diamond", true, [](){ return new DiamondEffect(); }},
|
||||||
/* 33 */ {"tpm2.net", 0, [](){ return new Tpm2NetEffect(); }},
|
/* 33 */ {"tpm2.net", 0, [](){ return new Tpm2NetEffect(); }},
|
||||||
/* 34 */ {"slow_blinking", true, [](){ return new SimpleEffect("slow_blinking", SIMPLE_EFFECT{return sin8((t>>3) + ((((x+1)*(y+1)*i*15) >> 2) & 0xFF))-128;});}},
|
/* 34 */ SIMPLE_EFFECT("slow_blinking", true, SE_CYCLE_COLORS, {return sin(t + (x+1)*(y+1)*i);} ),
|
||||||
/* 35 */ {"upwave", true, [](){ return new SimpleEffect("upwave", SIMPLE_EFFECT{return abs(cos8((t>>3)+(y<<4))-128);});}},
|
/* 35 */ SIMPLE_EFFECT("upwave", true, SE_CYCLE_COLORS, {return (cos(t+y/2));} ),
|
||||||
/* 36 */ {"centerwave", true, [](){ return new SimpleEffect("centerwave", SIMPLE_EFFECT{return sin8((t>>1) - sqrt((x-4)*(x-4) + (y-7)*(y-7))*32)-128;});}},
|
/* 36 */ SIMPLE_EFFECT("centerwave", true, SE_CYCLE_COLORS, {return sin(t*2 - sqrt((x-4)*(x-4) + (y-7)*(y-7)));} ),
|
||||||
|
/* 37 */ SIMPLE_EFFECT("sineline", true, SE_RANDOM_STATIC_COLOR, {return sin(x/2)-sin(x-t)-y+6;} ),
|
||||||
|
/* 38 */ SIMPLE_EFFECT("barbershop", true, SE_RANDOM_STATIC_COLOR, {return 1*cos(0.8*i-t*5);} ),
|
||||||
|
/* 39 */ SIMPLE_EFFECT("zigzag", true, SE_CYCLE_COLORS, { return cos(cos(x+y)-y*cos(t/8+x/16));} ),
|
||||||
};
|
};
|
||||||
const uint8_t effects_size = 37;
|
const uint8_t effects_size = 40;
|
||||||
|
|
||||||
|
|
||||||
Effect* select_effect(const char* name) {
|
Effect* select_effect(const char* name) {
|
||||||
|
Loading…
Reference in New Issue
Block a user