168 lines
5.7 KiB
C
168 lines
5.7 KiB
C
|
/*
|
||
|
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);
|
||
|
}
|
||
|
|
||
|
|