#include "effect_animation.h" #include "functions.h" AnimationEffect::AnimationEffect(AnimationData *anim) : AnimationEffect(anim, CRGB(0), 0, 0) {} AnimationEffect::AnimationEffect(AnimationData *anim, CRGB background_color) : AnimationEffect(anim, background_color, 0, 0) {} AnimationEffect::AnimationEffect(AnimationData *anim, CRGB bg_color, int x, int y) { animation = anim; background_color = bg_color; xOffset = x; yOffset = y; } void AnimationEffect::loop() { Serial.printf("Animation.loop. Animation is %p.", (void *)animation); CRGB colors[animation->color_count]; int led_index = 0; uint8_t *color_data = new uint8_t[animation->color_count * 3]; memcpy_P(color_data, animation->colors, animation->color_count * 3); for (int i = 0; i < animation->color_count; i++) colors[i] = CRGB(color_data[i * 3], color_data[i * 3 + 1], color_data[i * 3 + 2]); free(color_data); // Data is stored in progmem, so get it from there. int length = animation->offsets[frame + 1] - animation->offsets[frame]; uint8_t *data = new uint8_t[length]; memcpy_P(data, animation->data + animation->offsets[frame], length); for (int i = 0; i < length; i++) { uint8_t color_index; uint8_t count; if (data[i] == 255) { // Run-length encoded data color_index = data[i + 2]; count = data[i + 1]; i += 2; } else { color_index = data[i]; count = 1; } if (color_index == 0) { // color #0 = skip this pixels led_index += count; } else { CRGB* color; if (color_index == 1) { color = &background_color; } else if (color_index >= 2) { color = &colors[color_index - 2]; } for (int j = 0; j < count; j++) set(led_index++, color); } } free(data); if (frameSince == 0 || frameSince + frameDelay(animation, frame) < millis() || frameSince > millis()) { frame = (frame + 1) % animation->frame_count; frameSince = millis(); } } void AnimationEffect::set(int i, CRGB* color) { setPixel(xOffset + (i % animation->w), yOffset + (i / animation->h), *color); } uint16_t AnimationEffect::frameDelay(AnimationData* animation, int frame) { if (animation->individual_delays) return animation->delays[frame]; return animation->delays[0]; }