Commit | Line | Data |
---|---|---|
03b67a73 TW |
1 | package kaka.cakelight; |
2 | ||
aa9e49c2 TW |
3 | import java.util.Arrays; |
4 | ||
03b67a73 | 5 | public class LedFrame { |
0bf6c885 | 6 | private Configuration config; |
ed56b145 | 7 | private byte[] bytes; |
6e568391 | 8 | private int start, stride; |
aa9e49c2 | 9 | private int roff, goff, boff; // RGB offsets |
03b67a73 TW |
10 | |
11 | public static LedFrame from(Configuration config) { | |
12 | LedFrame frame = new LedFrame(); | |
0bf6c885 | 13 | frame.config = config; |
aa9e49c2 TW |
14 | switch (config.leds.type) { |
15 | /* | |
16 | * The WS2801 strip takes its input as a plain list of 24-bit colors in RBG order (at least mine did). | |
17 | */ | |
18 | case WS2801: | |
6e568391 | 19 | frame.start = 0; |
aa9e49c2 TW |
20 | frame.stride = 3; |
21 | frame.roff = 0; | |
22 | frame.goff = 2; | |
23 | frame.boff = 1; | |
24 | frame.bytes = new byte[config.leds.getCount() * frame.stride]; | |
25 | break; | |
26 | ||
27 | /* | |
28 | * The APA102 strip takes its input as: | |
29 | * <ol> | |
30 | * <li>a start frame of 4 bytes (all zeroes)</li> | |
31 | * <li>a frame of 4 bytes for each LED (111 (3 bits) + global illumination (5 bits) + BGR)</li> | |
32 | * <li>an (optional) end frame of 4 bytes (all ones)</li> | |
33 | * </ol> | |
34 | */ | |
35 | case APA102: | |
6e568391 | 36 | frame.start = 4; |
aa9e49c2 | 37 | frame.stride = 4; |
6e568391 TW |
38 | frame.roff = 3; |
39 | frame.goff = 2; | |
40 | frame.boff = 1; | |
41 | frame.bytes = new byte[4 + config.leds.getCount() * frame.stride + 4 * 2]; // 1 end frame doesn't seem to work, so we add another | |
42 | Arrays.fill(frame.bytes, 4, frame.bytes.length - 9, (byte)(0b11100000 | config.leds.brightness)); // Initiate the first byte of each LED | |
43 | Arrays.fill(frame.bytes, frame.bytes.length - 9, frame.bytes.length, (byte)0xff); // Initiate the end frame(s) with ones | |
aa9e49c2 TW |
44 | break; |
45 | } | |
03b67a73 TW |
46 | return frame; |
47 | } | |
48 | ||
6e568391 TW |
49 | public LedFrame fillColor(int r, int g, int b) { |
50 | return fillColor(Color.rgb(r, g, b)); | |
ed56b145 TW |
51 | } |
52 | ||
6e568391 | 53 | public LedFrame fillColor(Color color) { |
38c759f8 | 54 | byte r = (byte)color.r(), g = (byte)color.g(), b = (byte)color.b(); // Gamma corrected values |
6e568391 | 55 | for (int i = start, max = start + config.leds.getCount() * stride; i < max; i += stride) { |
38c759f8 TW |
56 | bytes[i + roff] = r; |
57 | bytes[i + goff] = g; | |
58 | bytes[i + boff] = b; | |
59 | } | |
6e568391 | 60 | return this; |
ed56b145 TW |
61 | } |
62 | ||
03b67a73 | 63 | public void setLedColor(int led, Color color) { |
6e568391 | 64 | int offset = start + led * stride; |
ed56b145 TW |
65 | bytes[offset + roff] = (byte)color.r(); |
66 | bytes[offset + goff] = (byte)color.g(); | |
67 | bytes[offset + boff] = (byte)color.b(); | |
03b67a73 TW |
68 | } |
69 | ||
70 | public Color getLedColor(int led) { | |
6e568391 | 71 | int offset = start + led * stride; |
ed56b145 TW |
72 | return Color.rgb( |
73 | bytes[offset + roff] & 0xff, | |
74 | bytes[offset + goff] & 0xff, | |
75 | bytes[offset + boff] & 0xff | |
76 | ); | |
77 | } | |
78 | ||
79 | public byte[] getBytes() { | |
80 | return bytes; | |
03b67a73 | 81 | } |
0bf6c885 TW |
82 | |
83 | // TODO this needs to be improved | |
84 | /** The x position of the led from 0.0-1.0. */ | |
85 | public double xOf(int led) { | |
86 | /* left */ if (led >= config.leds.cols * 2 + config.leds.rows) return 0; | |
87 | /* top */ if (led >= config.leds.cols + config.leds.rows) return 1 - (double)(led - config.leds.cols - config.leds.rows) / config.leds.cols; | |
88 | /* right */ if (led >= config.leds.cols) return 1; | |
89 | /* bottom */ return (double)led / config.leds.cols; | |
90 | } | |
91 | ||
92 | /** The y position of the led from 0.0-1.0. */ | |
93 | public double yOf(int led) { | |
94 | /* left */ if (led >= config.leds.cols * 2 + config.leds.rows) return (double)(led - config.leds.cols * 2 - config.leds.rows) / config.leds.rows; | |
95 | /* top */ if (led >= config.leds.cols + config.leds.rows) return 0; | |
96 | /* right */ if (led >= config.leds.cols) return 1 - (double)(led - config.leds.cols) / config.leds.rows; | |
97 | /* bottom */ return 1; | |
98 | } | |
03b67a73 | 99 | } |