pitrix/src/effects/matrix.cpp

218 lines
4.8 KiB
C++

#include "effects/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; i<length; i++) {
CRGB color = _getColor(i);
window->setSubPixel(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);
}