Commit | Line | Data |
---|---|---|
d626bc9b MS |
1 | /** |
2 | * DOUBLE BLACK DIAMOND DOUBLE BLACK DIAMOND | |
3 | * | |
4 | * //\\ //\\ //\\ //\\ | |
5 | * ///\\\ ///\\\ ///\\\ ///\\\ | |
6 | * \\\/// \\\/// \\\/// \\\/// | |
7 | * \\// \\// \\// \\// | |
8 | * | |
9 | * EXPERTS ONLY!! EXPERTS ONLY!! | |
10 | * | |
11 | * Overlay UI that indicates pattern control, etc. This will be moved | |
12 | * into the Processing library once it is stabilized and need not be | |
13 | * regularly modified. | |
14 | */ | |
15 | ||
16 | class DebugUI { | |
17 | ||
18 | final ChannelMapping[] channelList; | |
19 | final int debugX = 5; | |
20 | final int debugY = 5; | |
21 | final int debugXSpacing = 28; | |
22 | final int debugYSpacing = 21; | |
23 | final int[][] debugState; | |
24 | final int[] indexState; | |
25 | ||
26 | final int CUBE_STATE_UNUSED = 0; | |
27 | final int CUBE_STATE_USED = 1; | |
28 | final int CUBE_STATE_DUPLICATED = 2; | |
29 | ||
30 | final int DEBUG_STATE_ANIM = 0; | |
31 | final int DEBUG_STATE_WHITE = 1; | |
32 | final int DEBUG_STATE_OFF = 2; | |
33 | final int DEBUG_STATE_UNUSED = 3; | |
34 | ||
35 | DebugUI(PandaMapping[] pandaMappings) { | |
36 | int totalChannels = pandaMappings.length * PandaMapping.CHANNELS_PER_BOARD; | |
37 | debugState = new int[totalChannels+1][ChannelMapping.CUBES_PER_CHANNEL+1]; | |
38 | indexState = new int[glucose.model.cubes.size()+1]; | |
39 | ||
40 | channelList = new ChannelMapping[totalChannels]; | |
41 | int channelIndex = 0; | |
42 | for (PandaMapping pm : pandaMappings) { | |
43 | for (ChannelMapping channel : pm.channelList) { | |
44 | channelList[channelIndex++] = channel; | |
45 | } | |
46 | } | |
47 | for (int i = 0; i < debugState.length; ++i) { | |
48 | for (int j = 0; j < debugState[i].length; ++j) { | |
49 | debugState[i][j] = DEBUG_STATE_ANIM; | |
50 | } | |
51 | } | |
52 | ||
53 | for (int rawIndex = 0; rawIndex < glucose.model.cubes.size()+1; ++rawIndex) { | |
54 | indexState[rawIndex] = CUBE_STATE_UNUSED; | |
55 | } | |
56 | for (ChannelMapping channel : channelList) { | |
57 | for (int rawCubeIndex : channel.objectIndices) { | |
58 | if (rawCubeIndex > 0) | |
59 | ++indexState[rawCubeIndex]; | |
60 | } | |
61 | } | |
62 | } | |
63 | ||
64 | void draw() { | |
65 | noStroke(); | |
66 | int xBase = debugX; | |
67 | int yPos = debugY; | |
68 | ||
69 | textSize(10); | |
70 | ||
71 | fill(#000000); | |
72 | rect(0, 0, debugX + 5*debugXSpacing, height); | |
73 | ||
74 | int channelNum = 0; | |
75 | for (ChannelMapping channel : channelList) { | |
76 | int xPos = xBase; | |
77 | drawNumBox(xPos, yPos, channelNum+1, debugState[channelNum][0]); | |
78 | xPos += debugXSpacing; | |
79 | ||
80 | switch (channel.mode) { | |
81 | case ChannelMapping.MODE_CUBES: | |
82 | int stateIndex = 0; | |
83 | boolean first = true; | |
84 | for (int rawCubeIndex : channel.objectIndices) { | |
85 | if (rawCubeIndex < 0) { | |
86 | break; | |
87 | } | |
88 | if (first) { | |
89 | first = false; | |
90 | } else { | |
91 | stroke(#999999); | |
92 | line(xPos - 12, yPos + 8, xPos, yPos + 8); | |
93 | } | |
94 | drawNumBox(xPos, yPos, rawCubeIndex, debugState[channelNum][stateIndex+1], indexState[rawCubeIndex]); | |
95 | ++stateIndex; | |
96 | xPos += debugXSpacing; | |
97 | } | |
98 | break; | |
99 | case ChannelMapping.MODE_BASS: | |
100 | drawNumBox(xPos, yPos, "B", debugState[channelNum][1]); | |
101 | break; | |
102 | case ChannelMapping.MODE_SPEAKER: | |
103 | drawNumBox(xPos, yPos, "S" + channel.objectIndices[0], debugState[channelNum][1]); | |
104 | break; | |
105 | case ChannelMapping.MODE_STRUTS_AND_FLOOR: | |
106 | drawNumBox(xPos, yPos, "F", debugState[channelNum][1]); | |
107 | break; | |
108 | case ChannelMapping.MODE_NULL: | |
109 | break; | |
110 | default: | |
111 | throw new RuntimeException("Unhandled channel mapping mode: " + channel.mode); | |
112 | } | |
113 | ||
114 | yPos += debugYSpacing; | |
115 | ++channelNum; | |
116 | } | |
117 | drawNumBox(xBase, yPos, "A", debugState[channelNum][0]); | |
118 | yPos += debugYSpacing * 2; | |
119 | ||
120 | noFill(); | |
121 | fill(#CCCCCC); | |
122 | text("Unused Cubes", xBase, yPos + 12); | |
123 | yPos += debugYSpacing; | |
124 | ||
125 | int xIndex = 0; | |
126 | for (int rawIndex = 1; rawIndex <= glucose.model.cubes.size(); ++rawIndex) { | |
127 | if (indexState[rawIndex] == CUBE_STATE_UNUSED) { | |
128 | drawNumBox(xBase + (xIndex * debugXSpacing), yPos, rawIndex, DEBUG_STATE_UNUSED); | |
129 | ++xIndex; | |
130 | if (xIndex > 4) { | |
131 | xIndex = 0; | |
132 | yPos += debugYSpacing + 2; | |
133 | } | |
134 | } | |
135 | } | |
136 | } | |
137 | ||
138 | ||
139 | void drawNumBox(int xPos, int yPos, int label, int state) { | |
140 | drawNumBox(xPos, yPos, "" + label, state); | |
141 | } | |
142 | ||
143 | void drawNumBox(int xPos, int yPos, String label, int state) { | |
144 | drawNumBox(xPos, yPos, "" + label, state, CUBE_STATE_USED); | |
145 | } | |
146 | ||
147 | void drawNumBox(int xPos, int yPos, int label, int state, int cubeState) { | |
148 | drawNumBox(xPos, yPos, "" + label, state, cubeState); | |
149 | } | |
150 | ||
151 | void drawNumBox(int xPos, int yPos, String label, int state, int cubeState) { | |
152 | noFill(); | |
153 | color textColor = #cccccc; | |
154 | switch (state) { | |
155 | case DEBUG_STATE_ANIM: | |
156 | noStroke(); | |
157 | fill(#880000); | |
158 | rect(xPos, yPos, 16, 8); | |
159 | fill(#000088); | |
160 | rect(xPos, yPos+8, 16, 8); | |
161 | noFill(); | |
162 | stroke(textColor); | |
163 | break; | |
164 | case DEBUG_STATE_WHITE: | |
165 | stroke(textColor); | |
166 | fill(#e9e9e9); | |
167 | textColor = #333333; | |
168 | break; | |
169 | case DEBUG_STATE_OFF: | |
170 | stroke(textColor); | |
171 | break; | |
172 | case DEBUG_STATE_UNUSED: | |
173 | stroke(textColor); | |
174 | fill(#880000); | |
175 | break; | |
176 | } | |
177 | ||
178 | if (cubeState >= CUBE_STATE_DUPLICATED) { | |
179 | stroke(textColor = #FF0000); | |
180 | } | |
181 | ||
182 | rect(xPos, yPos, 16, 16); | |
183 | noStroke(); | |
184 | fill(textColor); | |
185 | text(label, xPos + 2, yPos + 12); | |
186 | } | |
187 | ||
188 | void maskColors(color[] colors) { | |
189 | color white = #FFFFFF; | |
190 | color off = #000000; | |
191 | int channelIndex = 0; | |
192 | int state; | |
193 | for (ChannelMapping channel : channelList) { | |
194 | switch (channel.mode) { | |
195 | case ChannelMapping.MODE_CUBES: | |
196 | int cubeIndex = 1; | |
197 | for (int rawCubeIndex : channel.objectIndices) { | |
198 | if (rawCubeIndex >= 0) { | |
199 | state = debugState[channelIndex][cubeIndex]; | |
200 | if (state != DEBUG_STATE_ANIM) { | |
201 | color debugColor = (state == DEBUG_STATE_WHITE) ? white : off; | |
202 | Cube cube = glucose.model.getCubeByRawIndex(rawCubeIndex); | |
2bb56822 | 203 | for (LXPoint p : cube.points) { |
d626bc9b MS |
204 | colors[p.index] = debugColor; |
205 | } | |
206 | } | |
207 | } | |
208 | ++cubeIndex; | |
209 | } | |
210 | break; | |
211 | ||
212 | case ChannelMapping.MODE_BASS: | |
213 | state = debugState[channelIndex][1]; | |
214 | if (state != DEBUG_STATE_ANIM) { | |
215 | color debugColor = (state == DEBUG_STATE_WHITE) ? white : off; | |
216 | for (Strip s : glucose.model.bassBox.boxStrips) { | |
2bb56822 | 217 | for (LXPoint p : s.points) { |
d626bc9b MS |
218 | colors[p.index] = debugColor; |
219 | } | |
220 | } | |
221 | } | |
222 | break; | |
223 | ||
224 | case ChannelMapping.MODE_STRUTS_AND_FLOOR: | |
225 | state = debugState[channelIndex][1]; | |
226 | if (state != DEBUG_STATE_ANIM) { | |
227 | color debugColor = (state == DEBUG_STATE_WHITE) ? white : off; | |
2bb56822 | 228 | for (LXPoint p : glucose.model.boothFloor.points) { |
d626bc9b MS |
229 | colors[p.index] = debugColor; |
230 | } | |
231 | for (Strip s : glucose.model.bassBox.struts) { | |
2bb56822 | 232 | for (LXPoint p : s.points) { |
d626bc9b MS |
233 | colors[p.index] = debugColor; |
234 | } | |
235 | } | |
236 | } | |
237 | break; | |
238 | ||
239 | case ChannelMapping.MODE_SPEAKER: | |
240 | state = debugState[channelIndex][1]; | |
241 | if (state != DEBUG_STATE_ANIM) { | |
242 | color debugColor = (state == DEBUG_STATE_WHITE) ? white : off; | |
2bb56822 | 243 | for (LXPoint p : glucose.model.speakers.get(channel.objectIndices[0]).points) { |
d626bc9b MS |
244 | colors[p.index] = debugColor; |
245 | } | |
246 | } | |
247 | break; | |
248 | ||
249 | case ChannelMapping.MODE_NULL: | |
250 | break; | |
251 | ||
252 | default: | |
253 | throw new RuntimeException("Unhandled channel mapping mode: " + channel.mode); | |
254 | } | |
255 | ++channelIndex; | |
256 | } | |
257 | } | |
258 | ||
259 | boolean mousePressed() { | |
260 | int dx = (mouseX - debugX) / debugXSpacing; | |
261 | int dy = (mouseY - debugY) / debugYSpacing; | |
262 | if ((dy < 0) || (dy >= debugState.length)) { | |
263 | return false; | |
264 | } | |
265 | if ((dx < 0) || (dx >= debugState[dy].length)) { | |
266 | return false; | |
267 | } | |
268 | int newState = debugState[dy][dx] = (debugState[dy][dx] + 1) % 3; | |
269 | if (dy == debugState.length-1) { | |
270 | for (int[] states : debugState) { | |
271 | for (int i = 0; i < states.length; ++i) { | |
272 | states[i] = newState; | |
273 | } | |
274 | } | |
275 | } else if (dx == 0) { | |
276 | for (int i = 0; i < debugState[dy].length; ++i) { | |
277 | debugState[dy][i] = newState; | |
278 | } | |
279 | } | |
280 | return true; | |
281 | } | |
282 | } | |
283 |