#include "effect_matrix.h" #include "my_color_palettes.h" #include "functions.h" MatrixEffectColumn::MatrixEffectColumn(Window* win, uint8_t dir, bool rand) { window = win; _direction = dir; _random_direction = rand; restart(true); } void MatrixEffectColumn::restart(bool completely_random) { if (_random_direction) { _direction = random8(4); } if (completely_random) { x = random8(window->width)<<8; y = random8(window->height)<<8; } else { switch(_direction) { case DIR_NORTH: x = random8(window->width)<<8; y = (window->height - 1)<<8; break; case DIR_EAST: x = 0; y = random8(window->height)<<8; break; case DIR_SOUTH: x = random8(window->width)<<8; y = 0; break; case DIR_WEST: x = (window->width - 1)<<8; y = random8(window->height)<<8; break; } } length = random8(settings.effects.matrix.length_min, settings.effects.matrix.length_max); running = true; speed = random8(settings.effects.matrix.speed_min, settings.effects.matrix.speed_max); } void MatrixEffectColumn::advance(uint16_t ms) { switch(_direction) { case DIR_NORTH: y-=speed * ms; if ((y>>8) + length < 0) running=false; break; case DIR_EAST: x+=speed * ms; if ((x>>8) - length > window->width) running=false; break; case DIR_SOUTH: y+=speed * ms; if ((y>>8) - length > window->height) running=false; break; case DIR_WEST: x-=speed * ms; if ((x>>8) + length < 0) running=false; break; } } void MatrixEffectColumn::draw() { int16_t xdir = 0; int16_t ydir = 0; switch (_direction) { case DIR_NORTH: ydir = 0xFF; break; case DIR_EAST: xdir = -0xFF; break; case DIR_SOUTH: ydir = -0xFF; break; case DIR_WEST: xdir = 0xFF; break; } for(int i=0; isetSubPixel(x+(xdir*i), y+(ydir*i), &color); } } void MatrixEffectColumn::loop(uint16_t ms) { if (!running) { if (random8() < 20) { // Start the column again. restart(false); } } else { advance(ms); draw(); } } CRGB MatrixEffectColumn::_getColor(uint8_t i) { CRGB color; if (i==0) { color = CRGB(255, 255, 255); } else { color = CHSV(83, 255, 255 * (length - i) / length); } return color; } CRGB RainbowMatrixEffectColumn::_getColor(uint8_t i) { CRGB color; if (i==0) { color = CRGB(255, 255, 255); } else { color = CHSV(255 * x / window->width, 255, 255 * (length - i) / length); } return color; } CRGB RandomMatrixEffectColumn::_getColor(uint8_t i) { CRGB color; //Serial.print("RandomMatrixEffectColumn::_getColor, hue="); Serial.println(_hue); if (i==0) { color = CRGB(255, 255, 255); } else { color = CHSV(_hue, 255, 255 * (length - i) / length); } return color; } void RandomMatrixEffectColumn::restart(bool completely_random) { MatrixEffectColumn::restart(completely_random); _hue = random8(); } CRGB ColumnMatrixEffectColumn::_getColor(uint8_t i) { CRGB color; uint8_t dist = abs(length / 2 - i); color = CHSV(_hue, 255, 255 - dist * 5); return color; } void ColumnMatrixEffectColumn::restart(bool completely_random) { MatrixEffectColumn::restart(completely_random); _hue = random8(); } boolean MatrixEffectBase::can_be_shown_with_clock() { return true; }; void MatrixEffectBase::_init() { _count = _get_count(); _columns = new MatrixEffectColumn* [_count]; } uint8_t MatrixEffectBase::_get_count() { return settings.effects.matrix.count; } MatrixEffect::MatrixEffect() { _init(); _create(); } void MatrixEffect::_create() { for (int i=0; i<_count; i++) _columns[i] = new MatrixEffectColumn(window, MatrixEffectColumn::DIR_SOUTH); } RandomMatrixEffect::RandomMatrixEffect() { _init(); _create(); } void RandomMatrixEffect::_create() { for (int i=0; i<_count; i++) _columns[i] = new RandomMatrixEffectColumn(window, random8(4), true); } uint8_t RandomMatrixEffect::_get_count() { return settings.effects.matrix.random_count; } RainbowMatrixEffect::RainbowMatrixEffect() { _init(); _create(); } void RainbowMatrixEffect::_create() { for (int i=0; i<_count; i++) _columns[i] = new RainbowMatrixEffectColumn(window, MatrixEffectColumn::DIR_SOUTH); } ColumnMatrixEffect::ColumnMatrixEffect() { _init(); _create(); } void ColumnMatrixEffect::_create() { for (int i=0; i<_count; i++) _columns[i] = new ColumnMatrixEffectColumn(window, MatrixEffectColumn::DIR_NORTH); } MatrixEffectBase::~MatrixEffectBase() { _delete(); } void MatrixEffectBase::_delete() { for (int i=0; i<_count; i++) { delete _columns[i]; } delete[] _columns; } void MatrixEffectBase::loop(uint16_t ms) { if (_count != _get_count()) { _delete(); _init(); _create(); } window->clear(); for (int i=0; i<_count; i++) _columns[i]->loop(ms); }