avr/lantern/lantern.c

168 lines
5.7 KiB
C
Raw Normal View History

2022-07-27 01:12:42 +00:00
/*
Copyright 2022, Savanni D'Gerinel <savanni@luminescent-dreams.com>
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 <https://www.gnu.org/licenses/>.
*/
#include <sk9822.h>
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);
}