1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
|
#include "pattern/twinkle.h"
#include <stdint.h>
#include <stdlib.h>
// The shape of a "spike"
uint8_t w_arr[91] = {1, 2, 4, 7, 11, 17, 24, 33, 44, 56, 70, 85,
101, 117, 134, 151, 167, 183, 197, 210, 222, 232, 240, 247,
251, 254, 255, 255, 253, 250, 246, 240, 234, 227, 219, 211,
202, 194, 185, 176, 167, 158, 149, 140, 132, 123, 116, 108,
101, 94, 87, 81, 75, 69, 64, 59, 54, 50, 46, 42,
39, 35, 32, 30, 27, 25, 22, 20, 18, 17, 15, 14,
12, 11, 10, 9, 8, 7, 6, 6, 5, 4, 4, 3,
3, 3, 2, 2, 2, 1, 1};
static inline uint8_t byte_scale(uint8_t n, uint8_t sc)
{
return n * sc / 255;
}
static uint8_t calc_w(uint8_t n, uint8_t shift)
{
uint8_t s = byte_scale(shift, 164);
uint8_t n_p = byte_scale(n, 255 - s) + s;
if (n_p < 164) {
return 0;
}
return w_arr[n_p - 164];
}
/* Produces a "pseudo-random" number given seed 'x' */
static uint8_t pseudo_random(uint8_t x)
{
return (1103515245 * x + 12345) & 0xFF; // & 0xFF ensures the result is 0-255
}
/* Produces a randomize "twinkle" effect. */
static uint8_t twinkle_raw(uint32_t time, size_t x, uint8_t amt)
{
uint8_t time_offset = pseudo_random(x);
uint32_t adj_time = time - time_offset;
uint32_t time8 = adj_time & 0xff;
uint32_t speed = pseudo_random((adj_time >> 8) + x) & 0x3;
time8 *= speed;
if (time8 <= 255) {
return calc_w(time8, amt);
} else {
return 0;
}
}
uint8_t twinkle(uint32_t time, size_t x, uint8_t amt)
{
if (time % 2 == 0) {
return twinkle_raw(time / 2, x, amt);
} else {
return (twinkle_raw(time / 2, x, amt) + twinkle_raw(time / 2 + 1, x, amt)) /
2;
}
}
|