315 lines
6.1 KiB
C
315 lines
6.1 KiB
C
/*
|
|
* ledprog.c: led programs
|
|
*/
|
|
|
|
#include "matrix.h"
|
|
#include "misc/tinymt.h"
|
|
|
|
|
|
static uint32_t s[8] = {0};
|
|
static uint32_t t[8] = {0};
|
|
|
|
|
|
|
|
void lp_ribbon_init()
|
|
{
|
|
uint8_t i;
|
|
|
|
for (i = 0; i < 8; i++) {
|
|
s[i] = 0;
|
|
}
|
|
}
|
|
|
|
void lp_ribbon_upward(uint16_t wait, uint16_t rate, uint8_t fade)
|
|
{
|
|
uint32_t i;
|
|
uint32_t x;
|
|
|
|
/*
|
|
0: state
|
|
1: timeout
|
|
2: index
|
|
*/
|
|
|
|
if (fade > 0x80)
|
|
fade = 0x80;
|
|
|
|
// reduce 1-frame bright blip
|
|
for (i = 0; i < sizeof(led_set.ribbon); i++) {
|
|
if (led_set.ribbon[i] >= 0xd0) {
|
|
led_set.ribbon[i] = 0xd0;
|
|
}
|
|
}
|
|
|
|
switch (s[0]) {
|
|
case 0: { // timeout
|
|
if (!s[1]) {
|
|
s[0]++;
|
|
s[2] = 0;
|
|
return;
|
|
}
|
|
|
|
s[1]--;
|
|
|
|
break;
|
|
}
|
|
case 1: { // upward trails
|
|
// rate delay
|
|
if (!s[1]) {
|
|
s[1] = rate;
|
|
} else {
|
|
s[1]--;
|
|
break;
|
|
}
|
|
|
|
x = s[2]++;
|
|
|
|
// are we done?
|
|
if (x >= sizeof(led_set.ribbon)) {
|
|
s[0] = 0;
|
|
s[1] = wait;
|
|
break;
|
|
}
|
|
|
|
// fade in and up
|
|
led_set.ribbon[x] = 0x20;
|
|
if (x) led_set.ribbon[x - 1] = 0x66;
|
|
if (x > 1) led_set.ribbon[x - 2] = 0xef;
|
|
}
|
|
}
|
|
|
|
// fade out LEDs
|
|
for (i = 0; i < sizeof(led_set.ribbon); i++) {
|
|
if (led_set.ribbon[i] >= 0x70) {
|
|
led_set.ribbon[i] -= fade;
|
|
}
|
|
if (led_set.ribbon[i] >= fade) {
|
|
led_set.ribbon[i] -= fade;
|
|
} else {
|
|
// led_set.ribbon[i] >>= 1;
|
|
if (led_set.ribbon[i])
|
|
led_set.ribbon[i]--;
|
|
}
|
|
}
|
|
|
|
matrix_flag_update();
|
|
}
|
|
|
|
void lp_ribbon_twinkle(uint8_t idle, uint8_t max, uint8_t thresh_lo, uint8_t thresh_hi)
|
|
{
|
|
/*
|
|
idle: attempted idle target. ideally an odd number not a power of two.
|
|
max: maximum brightness. anything higher is clamped to this
|
|
thresh_lo: rand must be lower than this to make any adjustment this cycle
|
|
thresh_hi: rand must be this or higher to force a bright twinkle
|
|
*/
|
|
|
|
uint32_t i;
|
|
uint32_t w, x;
|
|
|
|
s[1]++;
|
|
|
|
for (i = 0; i < sizeof(led_set.ribbon); i++) {
|
|
x = prng_get8();
|
|
|
|
if (x < thresh_lo) {
|
|
w = (idle > 3) ? 3 : idle;
|
|
|
|
// swing around idle level
|
|
if (led_set.ribbon[i] > idle) {
|
|
led_set.ribbon[i] >>= 1;
|
|
} else {
|
|
led_set.ribbon[i] += (w - 1);
|
|
}
|
|
}
|
|
|
|
// only make bright stars every 4 frames
|
|
if ((x >= thresh_hi) && ((s[1] & 3) == 0)) {
|
|
w = prng_get8();
|
|
led_set.ribbon[i] += w;
|
|
if (led_set.ribbon[i] > max) {
|
|
led_set.ribbon[i] = max;
|
|
}
|
|
}
|
|
}
|
|
|
|
matrix_flag_update();
|
|
}
|
|
|
|
|
|
void lp_aii_init()
|
|
{
|
|
uint8_t i;
|
|
|
|
for (i = 0; i < 8; i++) {
|
|
t[i] = 0;
|
|
}
|
|
|
|
// also clear LEDs
|
|
for (int i = 0; i < sizeof(led_set.a); i++) {
|
|
led_set.a[i] = 0;
|
|
}
|
|
for (int i = 0; i < sizeof(led_set.ii_lf); i++) {
|
|
led_set.ii_lf[i] = 0;
|
|
led_set.ii_rt[i] = 0;
|
|
}
|
|
|
|
matrix_flag_update();
|
|
}
|
|
|
|
void lp_aii_filldown(uint16_t prewait, uint16_t downrate, uint16_t postwait, uint8_t setrate, uint8_t max)
|
|
{
|
|
/*
|
|
0: state
|
|
1: timeout
|
|
2: index or setrate >>= 1
|
|
*/
|
|
|
|
uint32_t i;
|
|
uint32_t x;
|
|
|
|
if (setrate == 1)
|
|
setrate = 2;
|
|
|
|
switch (t[0]) {
|
|
case 0: // timeout before start
|
|
case 2: { // timeout after set
|
|
if (!t[1]) {
|
|
t[0]++;
|
|
t[2] = 0;
|
|
return;
|
|
}
|
|
|
|
t[1]--;
|
|
|
|
break;
|
|
}
|
|
|
|
case 1: { // fill down
|
|
// rate delay
|
|
if (!t[1]) {
|
|
t[1] = downrate;
|
|
} else {
|
|
t[1]--;
|
|
break;
|
|
}
|
|
|
|
x = t[2]++;
|
|
|
|
// done filling?
|
|
if (x > 10) {
|
|
t[0]++;
|
|
t[1] = postwait;
|
|
}
|
|
|
|
for (i = 0; i <= x; i++) {
|
|
led_set.a[9 + i] += setrate;
|
|
if (led_set.a[9 + i] > max)
|
|
led_set.a[9 + i] = max;
|
|
|
|
led_set.a[9 - i] += setrate;
|
|
if (led_set.a[9 - i] > max)
|
|
led_set.a[9 - i] = max;
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
case 3: { // fade out
|
|
x = 0;
|
|
t[2] = setrate >>= 1;
|
|
|
|
for (i = 0; i < sizeof(led_set.a); i++) {
|
|
if (led_set.a[i] < setrate) {
|
|
led_set.a[i] = 0;
|
|
} else {
|
|
led_set.a[i] -= setrate;
|
|
x++;
|
|
}
|
|
}
|
|
|
|
// all blank?
|
|
if (!x) {
|
|
t[0] = 0;
|
|
t[1] = prewait;
|
|
}
|
|
}
|
|
}
|
|
|
|
for (i = 0; i < 5; i++) {
|
|
led_set.ii_lf[i] = led_set.ii_rt[i] = led_set.a[i + 12];
|
|
}
|
|
|
|
matrix_flag_update();
|
|
}
|
|
|
|
void lp_aii_bounce(uint8_t rate, uint8_t set, uint8_t faderate, uint8_t fadeamt)
|
|
{
|
|
/*
|
|
0: direction
|
|
1: rate timeout
|
|
2: faderate timeout
|
|
3: index
|
|
4: changedir timeout
|
|
*/
|
|
|
|
uint8_t *a;
|
|
uint32_t i;
|
|
uint32_t x;
|
|
|
|
if (!t[1]) {
|
|
if (t[4]) {
|
|
t[4]--;
|
|
if (t[4]) {
|
|
goto fadeout;
|
|
}
|
|
}
|
|
|
|
t[1] = rate;
|
|
t[3]++;
|
|
|
|
if (t[3] >= 19) {
|
|
t[0] ^= 1;
|
|
t[3] = 0;
|
|
t[4] = rate << 2;
|
|
}
|
|
|
|
if (t[0]) {
|
|
x = 18 - t[3];
|
|
} else {
|
|
x = t[3];
|
|
}
|
|
|
|
led_set.a[x] = set;
|
|
|
|
if (t[3] >= 3) {
|
|
if (t[3] <= 7) {
|
|
led_set.ii_lf[7 - t[3]] = set >> 1;
|
|
}
|
|
}
|
|
if (t[3] >= 13) {
|
|
if (t[3] <= 17) {
|
|
led_set.ii_rt[t[3] - 13] = set >> 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
t[1]--;
|
|
|
|
fadeout:
|
|
if (!t[2]) {
|
|
t[2] = faderate;
|
|
|
|
a = (uint8_t *)&led_set.a;
|
|
for (i = 0; i < (sizeof(led_set.a) + sizeof(led_set.ii_lf) + sizeof(led_set.ii_rt)); i++) {
|
|
if (*a <= fadeamt) {
|
|
*a = 0;
|
|
} else {
|
|
*a -= fadeamt;
|
|
}
|
|
a++;
|
|
}
|
|
}
|
|
|
|
t[2]--;
|
|
} |