98 lines
2.2 KiB
C++
98 lines
2.2 KiB
C++
#include "effect_gol.h"
|
|
#include "my_fastled.h"
|
|
|
|
GolEffect::GolEffect() {
|
|
this->window = new Window(0, 0, LED_WIDTH, LED_HEIGHT-6);
|
|
|
|
_data = new uint8_t[this->window->count];
|
|
_old = new uint8_t[this->window->count];
|
|
for(uint16_t i=0; i<this->window->count; i++) {
|
|
_old[i] = 0;
|
|
}
|
|
_initialize();
|
|
}
|
|
|
|
bool GolEffect::can_be_shown_with_clock() { return true; }
|
|
|
|
void GolEffect::_initialize() {
|
|
for(uint16_t i=0; i<this->window->count; i++) {
|
|
_data[i] = random8() < EFFECT_GOL_START_PERCENTAGE ? 1 : 0;
|
|
}
|
|
_old_hue = _hue;
|
|
_hue = random8();
|
|
_step = 0;
|
|
}
|
|
|
|
GolEffect::~GolEffect() {
|
|
delete[] _data;
|
|
delete[] _old;
|
|
delete window;
|
|
}
|
|
|
|
void GolEffect::loop() {
|
|
if (EFFECT_GOL_BLEND_SPEED + _blend > 255) {
|
|
_blend = 0;
|
|
_advance();
|
|
} else {
|
|
_blend += EFFECT_GOL_BLEND_SPEED;
|
|
}
|
|
|
|
_draw();
|
|
}
|
|
|
|
void GolEffect::_advance() {
|
|
_step++;
|
|
_old_hue = _hue;
|
|
if (_step >= EFFECT_GOL_RESTART_AFTER_STEPS) {
|
|
_initialize();
|
|
} else {
|
|
for(uint16_t i=0; i<this->window->count; i++) {
|
|
_old[i] = _data[i];
|
|
}
|
|
uint8_t w = this->window->width;
|
|
uint16_t changes = 0;
|
|
for(uint8_t x=0; x<this->window->width; x++) for(uint8_t y=0; y<this->window->height; y++) {
|
|
uint16_t index = y*w + x;
|
|
uint8_t count =
|
|
(x>0 && y>0 && _old[index - w - 1]) +
|
|
(y>0 && _old[index - w]) +
|
|
(x<this->window->width-1 && y>0 && _old[index - w + 1]) +
|
|
|
|
(x>0 && _old[index - 1]) +
|
|
(x<this->window->width-1 && _old[index + 1]) +
|
|
|
|
(x>0 && y<this->window->height-1 && _old[index + w - 1]) +
|
|
(y<this->window->height-1 && _old[index + w]) +
|
|
(x<this->window->width-1 && y<this->window->height-1 && _old[index + w + 1]);
|
|
if (_old[index]==0 && count==3) {
|
|
// birth
|
|
_data[index]=1;
|
|
changes++;
|
|
}
|
|
if (_old[index]>0) {
|
|
if (count<2 || count>3) {
|
|
//death
|
|
_data[index]=0;
|
|
changes++;
|
|
} else if (_data[index] < 255) {
|
|
//ageing
|
|
_data[index]++;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (changes == 0) {
|
|
_initialize();
|
|
}
|
|
}
|
|
}
|
|
|
|
void GolEffect::_draw() {
|
|
for(uint16_t i=0; i<this->window->count; i++) {
|
|
CRGB o = _old[i]==0 ? CRGB::Black : (CRGB)CHSV(_old_hue, 180, 255);
|
|
CRGB n = _data[i]==0 ? CRGB::Black : (CRGB)CHSV(_hue, 180, 255);
|
|
CRGB result = nblend(o, n, _blend);
|
|
this->window->setPixelByIndex(i, &result);
|
|
}
|
|
}
|