/* Copyright 2022, Savanni D'Gerinel This file is part of Savanni's AVR library. This AVR library is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This AVR library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this AVR library. If not, see . */ #include lantern_t lantern_new(sk9822_t lights) { sk9822_init(&lights); return (lantern_t){ .lights = lights, .color_scheme = normal, .animations = { animation_new(), animation_new(), animation_new(), } }; } void lantern_start_normal(lantern_t *self, rng_t *rng, int light_idx) { switch (light_idx) { case 0: animation_begin( &self->animations[0], random_step(self->animations[0].color.r, 180, 255, rng), random_step(self->animations[0].color.g, 20, 50, rng), 0, 5); break; case 1: animation_begin( &self->animations[1], random_step(self->animations[1].color.r, 160, 230, rng), random_step(self->animations[1].color.g, 10, 30, rng), 0, 15); break; case 2: animation_begin( &self->animations[2], random_step(self->animations[2].color.r, 140, 170, rng), random_step(self->animations[2].color.g, 0, 10, rng), 0, 30); break; } } void lantern_start_spooky(lantern_t *self, rng_t *rng, int light_idx) { switch (light_idx) { case 0: animation_begin( &self->animations[0], 0, random_step(self->animations[0].color.g, 80, 120, rng), 0, 15); break; case 1: animation_begin( &self->animations[1], 0, random_step(self->animations[1].color.g, 60, 100, rng), 0, 15); break; case 2: animation_begin( &self->animations[2], 0, random_step(self->animations[2].color.g, 20, 40, rng), 0, 15); break; } } void lantern_start_eerie(lantern_t *self, rng_t *rng, int light_idx) { switch (light_idx) { case 0: animation_begin( &self->animations[0], random_step(self->animations[0].color.g, 20, 40, rng), random_step(self->animations[0].color.g, 20, 40, rng), random_step(self->animations[0].color.g, 80, 120, rng), 15); break; case 1: animation_begin( &self->animations[1], random_step(self->animations[0].color.g, 0, 30, rng), random_step(self->animations[0].color.g, 0, 30, rng), random_step(self->animations[1].color.g, 60, 100, rng), 30); break; case 2: animation_begin( &self->animations[2], random_step(self->animations[0].color.g, 0, 10, rng), random_step(self->animations[0].color.g, 0, 10, rng), random_step(self->animations[2].color.g, 20, 40, rng), 45); break; } } void lantern_set_mode(lantern_t *self, color_scheme_e scheme) { self->color_scheme = scheme; } void lantern_step(lantern_t *self, display_t *display, rng_t *rng, rgb_t colors[LIGHT_COUNT]) { for (int i = 0; i < LIGHT_COUNT; i++) { if (!animation_running(&self->animations[i])) { switch (self->color_scheme) { case normal: lantern_start_normal(self, rng, i); break; case spooky: lantern_start_spooky(self, rng, i); break; case eerie: lantern_start_eerie(self, rng, i); break; case flash: break; } } animation_step(&self->animations[i]); colors[i] = self->animations[i].color; } } void lantern_show(lantern_t *lantern, display_t *display) { char msg1[20]; char msg2[20]; snprintf(msg1, 20, "[%d,%d] %x,%x,%x", lantern->animations[0].frame, lantern->animations[0].duration, lantern->animations[0].color.r, lantern->animations[0].color.g, lantern->animations[0].color.b ); snprintf(msg2, 20, "%x,%x,%x %x,%x,%x", lantern->animations[1].color.r, lantern->animations[1].color.g, lantern->animations[1].color.b, lantern->animations[2].color.r, lantern->animations[2].color.g, lantern->animations[2].color.b ); display_clear(display); display_write_message(display, msg1); display_set_location(display, 1, 0); display_write_message(display, msg2); }