#include #include #include #include #define FPS 60 #define FRAME_DELAY_MS 1000 / FPS uint8_t random_step(uint8_t value, uint8_t min, uint8_t max, rng_t *rng) { int8_t step = (rng_sample(rng) % 32) - 16; uint16_t new_value = value + step; if (new_value > max) { return max; } else if (new_value < min) { return min; } else { return new_value; } } typedef enum { normal, creepy, } color_scheme_e; typedef struct { rgb_t lamp; color_scheme_e color_scheme; int8_t red_step; int8_t green_step; int8_t blue_step; uint8_t frame; uint8_t duration; } animation_t; animation_t animation_new() { return (animation_t){ .lamp = (rgb_t){ .brightness = 9, .r = 212, .g = 50, .b = 0 }, .color_scheme = normal, .red_step = 0, .green_step = 0, .blue_step = 0, .frame = 0, .duration = 0, }; } void animation_flicker(animation_t *animation, rng_t *rng) { uint8_t rdest; uint8_t gdest; switch (animation->color_scheme) { case normal: rdest = random_step(animation->lamp.r, 180, 255, rng); gdest = random_step(animation->lamp.g, 10, 40, rng); animation->red_step = 60 / (rdest - animation->lamp.r); animation->green_step = 60 / (gdest - animation->lamp.g); animation->duration = 60; break; case creepy: break; } } void animation_step(animation_t *animation, rng_t *rng) { if (animation->duration == 0) { animation_flicker(animation, rng); } else { if (animation->frame == animation->duration) { animation->frame = 0; animation->duration = 0; animation->red_step = 0; animation->green_step = 0; animation->blue_step = 0; } else { animation->frame++; animation->lamp.r += animation->red_step; animation->lamp.g += animation->green_step; animation->lamp.b += animation->blue_step; } } } /* void flicker(rgb_t *pixel, rng_t *rng) { pixel->r = random_step(pixel->r, 180, 255, rng); pixel->g = random_step(pixel->g, 10, 40, rng); } */ int main (void) { DDRB = _BV(2) | _BV(1) | _BV(0); PORTB = 0; _delay_ms(50); io_pin_t data_pin = { .port = &PORTB, .pin = 0 }; io_pin_t clock_pin = { .port = &PORTB, .pin = 2 }; rng_t rng = rng_new(0); animation_t animation = animation_new(); while (1) { animation_step(&animation, &rng); send_pixels(data_pin, clock_pin, &animation.lamp, 1); _delay_ms(FRAME_DELAY_MS); } }