diff options
author | Bad Diode <bd@badd10de.dev> | 2023-04-23 15:48:59 +0200 |
---|---|---|
committer | Bad Diode <bd@badd10de.dev> | 2023-04-23 15:48:59 +0200 |
commit | ff6e784e7c5ebe223666c6c631305397ad358289 (patch) | |
tree | 0f87823d48366a6beb8d36d7eea5dc33663d7abd /src/drawing.c | |
parent | deb9c48fbd3dc5854de4ae3a04dc999029c10ae0 (diff) | |
download | stepper-ff6e784e7c5ebe223666c6c631305397ad358289.tar.gz stepper-ff6e784e7c5ebe223666c6c631305397ad358289.zip |
Start decoupling of rendering from update passes
Diffstat (limited to 'src/drawing.c')
-rw-r--r-- | src/drawing.c | 1237 |
1 files changed, 1237 insertions, 0 deletions
diff --git a/src/drawing.c b/src/drawing.c new file mode 100644 index 0000000..4f08e39 --- /dev/null +++ b/src/drawing.c | |||
@@ -0,0 +1,1237 @@ | |||
1 | // | ||
2 | // Channel render functions. | ||
3 | // | ||
4 | |||
5 | void | ||
6 | draw_channel_sprite(size_t x, size_t y, u8 clr, u8 idx) { | ||
7 | draw_icn(x, y, &ch_btn_sprite[0 + 6 * idx], clr, 0, 0); | ||
8 | draw_icn(x + 8, y, &ch_btn_sprite[2 + 6 * idx], clr, 0, 0); | ||
9 | draw_icn(x + 16, y, &ch_btn_sprite[4 + 6 * idx], clr, 0, 0); | ||
10 | } | ||
11 | |||
12 | void | ||
13 | draw_channels(void) { | ||
14 | for (size_t i = 0; i < 4; i++) { | ||
15 | bool active = false; | ||
16 | switch (i) { | ||
17 | case 0: { | ||
18 | active = patterns[pattern_selection_loc].ch1.active; | ||
19 | } break; | ||
20 | case 1: { | ||
21 | active = patterns[pattern_selection_loc].ch2.active; | ||
22 | } break; | ||
23 | case 2: { | ||
24 | active = patterns[pattern_selection_loc].ch3.active; | ||
25 | } break; | ||
26 | case 3: { | ||
27 | active = patterns[pattern_selection_loc].ch4.active; | ||
28 | } break; | ||
29 | } | ||
30 | u8 clr = active ? COL_FG : COL_GREY; | ||
31 | size_t y = CHAN_START_Y + i * CHAN_OFFSET_Y; | ||
32 | draw_channel_sprite(CHAN_START_X, y, active, i); | ||
33 | } | ||
34 | } | ||
35 | |||
36 | void | ||
37 | draw_channel_cursor(size_t i, u8 clr) { | ||
38 | size_t offset_x = 0; | ||
39 | size_t offset_y = CHAN_H + i * CHAN_OFFSET_Y + 1; | ||
40 | size_t x0 = CHAN_START_X + offset_x; | ||
41 | size_t x1 = CHAN_START_X + offset_x + CHAN_W; | ||
42 | size_t y = CHAN_START_Y + offset_y; | ||
43 | draw_line(x0, y, x1, y, clr); | ||
44 | } | ||
45 | |||
46 | // | ||
47 | // Trigger render functions. | ||
48 | // | ||
49 | |||
50 | void | ||
51 | clear_trigger(size_t i) { | ||
52 | size_t offset_x = TRIG_OFFSET_X * (i % 8); | ||
53 | size_t offset_y = i < 8 ? 0 : TRIG_OFFSET_Y; | ||
54 | size_t x0 = TRIG_START_X + offset_x + 1; | ||
55 | size_t x1 = TRIG_START_X + offset_x + TRIG_W - 1; | ||
56 | size_t y0 = TRIG_START_Y + offset_y + 1; | ||
57 | size_t y1 = TRIG_START_Y + offset_y + TRIG_H - 4; | ||
58 | draw_filled_rect(x0, y0, x1, y1, COL_BG); | ||
59 | } | ||
60 | |||
61 | void | ||
62 | draw_trigger(size_t chan, size_t i) { | ||
63 | TriggerNote trig = {0}; | ||
64 | switch (chan) { | ||
65 | case 0: { | ||
66 | trig = patterns[pattern_selection_loc].ch1.notes[i]; | ||
67 | } break; | ||
68 | case 1: { | ||
69 | trig = patterns[pattern_selection_loc].ch2.notes[i]; | ||
70 | } break; | ||
71 | case 2: { | ||
72 | trig = patterns[pattern_selection_loc].ch3.notes[i]; | ||
73 | } break; | ||
74 | case 3: { | ||
75 | trig = patterns[pattern_selection_loc].ch4.notes[i]; | ||
76 | } break; | ||
77 | } | ||
78 | if (trig.active) { | ||
79 | size_t offset_x = TRIG_OFFSET_X * (i % 8); | ||
80 | size_t offset_y = i < 8 ? 0 : TRIG_OFFSET_Y; | ||
81 | size_t x = TRIG_START_X + offset_x; | ||
82 | size_t y = TRIG_START_Y + offset_y; | ||
83 | u32 *tile = ¬e_name_sprites[4 * trig.note]; | ||
84 | draw_icn(x, y, &tile[0], COL_FG, 1, 0); | ||
85 | draw_icn(x + 8, y, &tile[2], COL_FG, 1, 0); | ||
86 | } else { | ||
87 | clear_trigger(i); | ||
88 | } | ||
89 | } | ||
90 | |||
91 | void | ||
92 | draw_trig_cursor(size_t i, u8 clr) { | ||
93 | size_t offset_x = TRIG_OFFSET_X * (i % 8); | ||
94 | size_t offset_y = i < 8 ? 2 : 2 + TRIG_OFFSET_Y; | ||
95 | size_t x0 = TRIG_START_X + offset_x; | ||
96 | size_t x1 = TRIG_START_X + TRIG_W + offset_x; | ||
97 | size_t y = TRIG_START_Y + TRIG_H + offset_y; | ||
98 | draw_line(x0, y, x1, y, clr); | ||
99 | } | ||
100 | |||
101 | void | ||
102 | draw_right_col_cursor(u8 clr) { | ||
103 | size_t x0 = 0; | ||
104 | size_t x1 = 0; | ||
105 | size_t y = 0; | ||
106 | switch (right_col_selection_loc) { | ||
107 | case R_COL_BPM: { | ||
108 | x0 = BPM_START_X; | ||
109 | x1 = x0 + R_COL_W; | ||
110 | y = BPM_START_Y + BPM_H + 2; | ||
111 | } break; | ||
112 | case R_COL_STOP: { | ||
113 | x0 = STOP_START_X; | ||
114 | x1 = x0 + R_COL_W; | ||
115 | y = STOP_START_Y + PLAY_STOP_H + 2; | ||
116 | } break; | ||
117 | case R_COL_PLAY: { | ||
118 | x0 = PLAY_START_X; | ||
119 | x1 = x0 + R_COL_W; | ||
120 | y = PLAY_START_Y + PLAY_STOP_H + 2; | ||
121 | } break; | ||
122 | case R_COL_BANK_A: { | ||
123 | x0 = BANK_START_X; | ||
124 | x1 = x0 + PAT_W; | ||
125 | y = BANK_START_Y + PAT_H + 2; | ||
126 | } break; | ||
127 | case R_COL_BANK_B: { | ||
128 | x0 = BANK_START_X; | ||
129 | x1 = x0 + PAT_W; | ||
130 | y = BANK_START_Y + PAT_H + 2 + 1 * PAT_OFFSET_Y; | ||
131 | } break; | ||
132 | case R_COL_BANK_C: { | ||
133 | x0 = BANK_START_X; | ||
134 | x1 = x0 + PAT_W; | ||
135 | y = BANK_START_Y + PAT_H + 2 + 2 * PAT_OFFSET_Y; | ||
136 | } break; | ||
137 | case R_COL_BANK_D: { | ||
138 | x0 = BANK_START_X; | ||
139 | x1 = x0 + PAT_W; | ||
140 | y = BANK_START_Y + PAT_H + 2 + 3 * PAT_OFFSET_Y; | ||
141 | } break; | ||
142 | } | ||
143 | draw_line(x0, y, x1, y, clr); | ||
144 | } | ||
145 | |||
146 | void | ||
147 | draw_current_step(u8 col) { | ||
148 | size_t offset_x = TRIG_OFFSET_X * (step_counter % 8); | ||
149 | size_t offset_y = step_counter < 8 ? 2 : 2 + TRIG_OFFSET_Y; | ||
150 | size_t x0 = TRIG_START_X + 3 + offset_x; | ||
151 | size_t x1 = TRIG_START_X - 3 + TRIG_W + offset_x; | ||
152 | size_t y = TRIG_START_Y - 4 + TRIG_H + offset_y; | ||
153 | draw_line(x0, y, x1, y, col); | ||
154 | } | ||
155 | |||
156 | void | ||
157 | draw_bank_buttons() { | ||
158 | size_t x = BANK_START_X; | ||
159 | size_t y = BANK_START_Y; | ||
160 | // txt_drawf_small("BANK", x - 2, y - 10, 4, COL_FG); | ||
161 | char bank_names[] = { | ||
162 | 'A', 'B', 'C', 'D', | ||
163 | }; | ||
164 | for (int i = 0; i < 4; i++) { | ||
165 | int color = COL_GREY; | ||
166 | if (i == current_bank) { | ||
167 | color = COL_FG; | ||
168 | } | ||
169 | draw_filled_rect(x, y, x + PAT_W, y + PAT_H, COL_BG); | ||
170 | draw_rect(x, y, x + PAT_W, y + PAT_H, color); | ||
171 | // txt_drawc(bank_names[i], x + 4, y + 2, 6, color); | ||
172 | y += PAT_OFFSET_Y; | ||
173 | } | ||
174 | } | ||
175 | |||
176 | void | ||
177 | draw_pattern_buttons() { | ||
178 | size_t x = PAT_START_X; | ||
179 | size_t y = PAT_START_Y; | ||
180 | // txt_drawf_small("PAT", x, y - 10, 4, COL_FG); | ||
181 | char pat_names[] = { | ||
182 | 'A', 'B', 'C', 'D', | ||
183 | 'E', 'F', 'G', 'H', | ||
184 | }; | ||
185 | for (int i = 0; i < 8; i++) { | ||
186 | int color = COL_GREY; | ||
187 | if (i == current_pattern) { | ||
188 | color = COL_FG; | ||
189 | } | ||
190 | if (i == next_pattern && current_pattern != next_pattern) { | ||
191 | color = COL_BLUE; | ||
192 | } | ||
193 | draw_filled_rect(x, y, x + PAT_W, y + PAT_H, COL_BG); | ||
194 | draw_rect(x, y, x + PAT_W, y + PAT_H, color); | ||
195 | // txt_drawc(pat_names[i], x + 4, y + 2, 6, color); | ||
196 | y += PAT_OFFSET_Y; | ||
197 | } | ||
198 | } | ||
199 | |||
200 | void | ||
201 | draw_pattern_cursor(size_t i, u8 clr) { | ||
202 | size_t offset_x = 0; | ||
203 | size_t offset_y = PAT_H + i * PAT_OFFSET_Y + 2; | ||
204 | size_t x0 = PAT_START_X + offset_x; | ||
205 | size_t x1 = PAT_START_X + offset_x + PAT_W; | ||
206 | size_t y = PAT_START_Y + offset_y; | ||
207 | draw_line(x0, y, x1, y, clr); | ||
208 | } | ||
209 | |||
210 | void | ||
211 | draw_play() { | ||
212 | size_t x = PLAY_START_X; | ||
213 | size_t y = PLAY_START_Y; | ||
214 | draw_filled_rect(x, y, x + R_COL_W, y + PLAY_STOP_H, COL_BG); | ||
215 | draw_rect(x, y, x + R_COL_W, y + PLAY_STOP_H, COL_CYAN); | ||
216 | if (play_status == 1) { | ||
217 | // Pause button | ||
218 | draw_filled_rect(x + 10, y + 3, x + 11, y + 7, COL_CYAN); | ||
219 | draw_filled_rect(x + 13, y + 3, x + 14, y + 7, COL_CYAN); | ||
220 | } else { | ||
221 | // Play button | ||
222 | x += 1; | ||
223 | draw_line(x + 10, y + 2, x + 10, y + 8, COL_CYAN); | ||
224 | draw_line(x + 11, y + 3, x + 11, y + 7, COL_CYAN); | ||
225 | draw_line(x + 12, y + 4, x + 12, y + 6, COL_CYAN); | ||
226 | draw_line(x + 13, y + 5, x + 13, y + 5, COL_CYAN); | ||
227 | } | ||
228 | } | ||
229 | |||
230 | void | ||
231 | draw_stop() { | ||
232 | size_t x = STOP_START_X; | ||
233 | size_t y = STOP_START_Y; | ||
234 | draw_rect(x, y, x + R_COL_W, y + PLAY_STOP_H, COL_RED); | ||
235 | draw_filled_rect(x + 10, y + 3, x + 14, y + 7, COL_RED); | ||
236 | } | ||
237 | |||
238 | void | ||
239 | draw_bpm() { | ||
240 | size_t x = BPM_START_X; | ||
241 | size_t y = BPM_START_Y; | ||
242 | |||
243 | // Draw bounding box. | ||
244 | draw_filled_rect(x, y, x + R_COL_W, y + BPM_H, COL_BG); | ||
245 | draw_rect(x, y, x + R_COL_W, y + BPM_H, COL_FG); | ||
246 | draw_line(x + 5, y, x + 19, y, COL_BG); | ||
247 | // txt_drawf_small("BPM", x + 5, y - 4, 4, COL_FG); | ||
248 | |||
249 | // Make sure its horizontally centered if only 2 digits | ||
250 | int bpm = patterns[pattern_selection_loc].bpm; | ||
251 | if (bpm >= 100) { | ||
252 | txt_drawf("%d", x + 3, y + 7, 6, COL_FG, bpm); | ||
253 | } else { | ||
254 | txt_drawf("%d", x + 6, y + 7, 6, COL_FG, bpm); | ||
255 | } | ||
256 | } | ||
257 | |||
258 | void | ||
259 | draw_triggers(void) { | ||
260 | for (size_t i = 0; i < 16; i++) { | ||
261 | size_t offset_x = TRIG_OFFSET_X * (i % 8); | ||
262 | size_t offset_y = i < 8 ? 0 : 0 + TRIG_OFFSET_Y; | ||
263 | size_t x0 = TRIG_START_X + offset_x; | ||
264 | size_t x1 = TRIG_START_X + offset_x + TRIG_W; | ||
265 | size_t y0 = TRIG_START_Y + offset_y; | ||
266 | size_t y1 = TRIG_START_Y + offset_y + TRIG_H; | ||
267 | draw_rect(x0, y0, x1, y1, COL_FG); | ||
268 | clear_trigger(i); | ||
269 | draw_trigger(channel_selection_loc, i); | ||
270 | } | ||
271 | } | ||
272 | |||
273 | void | ||
274 | draw_note(u8 note, u8 clr) { | ||
275 | size_t octave = note / 12; | ||
276 | size_t value = note % 12; | ||
277 | |||
278 | size_t x0 = 0; | ||
279 | size_t y0 = 0; | ||
280 | size_t x1 = 0; | ||
281 | size_t y1 = 0; | ||
282 | switch (value) { | ||
283 | // White notes. | ||
284 | case 0:{ | ||
285 | x0 = PIANO_START_X + 2 + octave * 28; | ||
286 | x1 = x0 + 1; | ||
287 | y0 = PIANO_START_Y + 2; | ||
288 | y1 = PIANO_START_Y - 2 + PIANO_H; | ||
289 | draw_filled_rect(x0, y0, x1, y1, clr); | ||
290 | x0 = PIANO_START_X + 2 + octave * 28 + 2; | ||
291 | x1 = x0; | ||
292 | y0 = y0 + 9; | ||
293 | draw_filled_rect(x0, y0, x1, y1, clr); | ||
294 | } break; | ||
295 | case 2:{ | ||
296 | x0 = PIANO_START_X + 2 + octave * 28 + 5; | ||
297 | x1 = x0; | ||
298 | y0 = PIANO_START_Y + 2; | ||
299 | y1 = PIANO_START_Y - 2 + 12; | ||
300 | draw_filled_rect(x0, y0, x1, y1, clr); | ||
301 | x0 = PIANO_START_X + 2 + octave * 28 + 4; | ||
302 | x1 = x0 + 2; | ||
303 | y0 = PIANO_START_Y - 2 + 13; | ||
304 | y1 = y0 + 7; | ||
305 | draw_filled_rect(x0, y0, x1, y1, clr); | ||
306 | } break; | ||
307 | case 4:{ | ||
308 | x0 = PIANO_START_X + 2 + octave * 28 + 9; | ||
309 | x1 = x0 + 1; | ||
310 | y0 = PIANO_START_Y + 2; | ||
311 | y1 = PIANO_START_Y - 2 + 12; | ||
312 | draw_filled_rect(x0, y0, x1, y1, clr); | ||
313 | x0 = PIANO_START_X + 2 + octave * 28 + 8; | ||
314 | x1 = x0 + 2; | ||
315 | y0 = PIANO_START_Y - 2 + 13; | ||
316 | y1 = y0 + 7; | ||
317 | draw_filled_rect(x0, y0, x1, y1, clr); | ||
318 | } break; | ||
319 | case 5:{ | ||
320 | x0 = PIANO_START_X + 2 + octave * 28 + 12; | ||
321 | x1 = x0 + 1; | ||
322 | y0 = PIANO_START_Y + 2; | ||
323 | y1 = PIANO_START_Y - 2 + PIANO_H; | ||
324 | draw_filled_rect(x0, y0, x1, y1, clr); | ||
325 | x0 = PIANO_START_X + 2 + octave * 28 + 14; | ||
326 | x1 = x0; | ||
327 | y0 = y0 + 9; | ||
328 | draw_filled_rect(x0, y0, x1, y1, clr); | ||
329 | } break; | ||
330 | case 7:{ | ||
331 | x0 = PIANO_START_X + 2 + octave * 28 + 17; | ||
332 | x1 = x0; | ||
333 | y0 = PIANO_START_Y + 2; | ||
334 | y1 = PIANO_START_Y - 2 + 12; | ||
335 | draw_filled_rect(x0, y0, x1, y1, clr); | ||
336 | x0 = PIANO_START_X + 2 + octave * 28 + 16; | ||
337 | x1 = x0 + 2; | ||
338 | y0 = PIANO_START_Y - 2 + 13; | ||
339 | y1 = y0 + 7; | ||
340 | draw_filled_rect(x0, y0, x1, y1, clr); | ||
341 | } break; | ||
342 | case 9:{ | ||
343 | x0 = PIANO_START_X + 2 + octave * 28 + 21; | ||
344 | x1 = x0; | ||
345 | y0 = PIANO_START_Y + 2; | ||
346 | y1 = PIANO_START_Y - 2 + 12; | ||
347 | draw_filled_rect(x0, y0, x1, y1, clr); | ||
348 | x0 = PIANO_START_X + 2 + octave * 28 + 20; | ||
349 | x1 = x0 + 2; | ||
350 | y0 = PIANO_START_Y - 2 + 13; | ||
351 | y1 = y0 + 7; | ||
352 | draw_filled_rect(x0, y0, x1, y1, clr); | ||
353 | } break; | ||
354 | case 11: { | ||
355 | x0 = PIANO_START_X + 2 + octave * 28 + 25; | ||
356 | x1 = x0 + 1; | ||
357 | y0 = PIANO_START_Y + 2; | ||
358 | y1 = PIANO_START_Y - 2 + 12; | ||
359 | draw_filled_rect(x0, y0, x1, y1, clr); | ||
360 | x0 = PIANO_START_X + 2 + octave * 28 + 24; | ||
361 | x1 = x0 + 2; | ||
362 | y0 = PIANO_START_Y - 2 + 13; | ||
363 | y1 = y0 + 7; | ||
364 | draw_filled_rect(x0, y0, x1, y1, clr); | ||
365 | } break; | ||
366 | default: { | ||
367 | if (clr == COL_FG) { | ||
368 | clr = COL_BG; | ||
369 | } | ||
370 | y0 = PIANO_START_Y + 2; | ||
371 | y1 = PIANO_START_Y - 2 + 11; | ||
372 | switch (value) { | ||
373 | case 1: { | ||
374 | x0 = PIANO_START_X + 2 + octave * 28 + 3; | ||
375 | } break; | ||
376 | case 3: { | ||
377 | x0 = PIANO_START_X + 2 + octave * 28 + 7; | ||
378 | } break; | ||
379 | case 6: { | ||
380 | x0 = PIANO_START_X + 2 + octave * 28 + 15; | ||
381 | } break; | ||
382 | case 8: { | ||
383 | x0 = PIANO_START_X + 2 + octave * 28 + 19; | ||
384 | } break; | ||
385 | case 10: { | ||
386 | x0 = PIANO_START_X + 2 + octave * 28 + 23; | ||
387 | } break; | ||
388 | } | ||
389 | x1 = x0; | ||
390 | draw_line(x0, y0, x1, y1, clr); | ||
391 | } break; | ||
392 | } | ||
393 | } | ||
394 | |||
395 | void | ||
396 | draw_piano(void) { | ||
397 | size_t x0 = PIANO_START_X; | ||
398 | size_t x1 = PIANO_START_X + PIANO_W; | ||
399 | size_t y0 = PIANO_START_Y; | ||
400 | size_t y1 = PIANO_START_Y + PIANO_H; | ||
401 | draw_rect(x0, y0, x1, y1, COL_FG); | ||
402 | for (size_t i = 0; i < 12 * 6; i++) { | ||
403 | draw_note(i, COL_FG); | ||
404 | } | ||
405 | } | ||
406 | |||
407 | void | ||
408 | draw_params_cursor_wave(size_t i, u8 clr) { | ||
409 | u8 x_positions[] = { | ||
410 | // 32 half bytes (Wave A). | ||
411 | 0, 4, 8, 12, 16, 20, 24, 28, | ||
412 | 34, 38, 42, 46, 50, 54, 58, 62, | ||
413 | 0, 4, 8, 12, 16, 20, 24, 28, | ||
414 | 34, 38, 42, 46, 50, 54, 58, 62, | ||
415 | // 32 half bytes (Wave B). | ||
416 | 70, 74, 78, 82, 86, 90, 94, 98, | ||
417 | 104, 108, 112, 116, 120, 124, 128, 132, | ||
418 | 70, 74, 78, 82, 86, 90, 94, 98, | ||
419 | 104, 108, 112, 116, 120, 124, 128, 132, | ||
420 | // Default wave A. | ||
421 | 1, 18, 35, 52, | ||
422 | // Default wave B. | ||
423 | 71, 88, 105, 122, | ||
424 | // Mode selection. | ||
425 | 141, | ||
426 | // Volume selection. | ||
427 | 141, | ||
428 | }; | ||
429 | u8 y_positions[] = { | ||
430 | // 32 half bytes (Wave A) | ||
431 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
432 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
433 | 8, 8, 8, 8, 8, 8, 8, 8, | ||
434 | 8, 8, 8, 8, 8, 8, 8, 8, | ||
435 | // 32 half bytes (Wave B) | ||
436 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
437 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
438 | 8, 8, 8, 8, 8, 8, 8, 8, | ||
439 | 8, 8, 8, 8, 8, 8, 8, 8, | ||
440 | // Default wave A. | ||
441 | 20, 20, 20, 20, | ||
442 | // Default wave B. | ||
443 | 20, 20, 20, 20, | ||
444 | // Mode selection. | ||
445 | 20, | ||
446 | // Volume selection. | ||
447 | 0, | ||
448 | }; | ||
449 | size_t cursor_length = 0; | ||
450 | if (i < 64) { | ||
451 | cursor_length = 4; | ||
452 | } else if (i < 72) { | ||
453 | cursor_length = 13; | ||
454 | } else { | ||
455 | cursor_length = 30; | ||
456 | } | ||
457 | size_t x = PARAMS_START_X + x_positions[i] - 1; | ||
458 | size_t y = PARAMS_START_Y + PARAMS_H - 23 + y_positions[i]; | ||
459 | draw_line(x, y, x + cursor_length, y, clr); | ||
460 | } | ||
461 | |||
462 | void | ||
463 | draw_params_cursor_noise(size_t i, u8 clr) { | ||
464 | u8 x_positions[] = { | ||
465 | 0, // Bit mode. | ||
466 | 31, // Env. Vol. | ||
467 | 59, // Env. Direction. | ||
468 | 87, // Env. Time. | ||
469 | }; | ||
470 | u8 y_positions[] = { | ||
471 | 20, // Bit mode. | ||
472 | 20, // Env. Vol. | ||
473 | 20, // Env. Direction. | ||
474 | 20, // Env. Time. | ||
475 | }; | ||
476 | size_t cursor_length = 24; | ||
477 | size_t x = PARAMS_START_X + x_positions[i] + 30; | ||
478 | size_t y = PARAMS_START_Y + PARAMS_H - 23 + y_positions[i]; | ||
479 | draw_line(x, y, x + cursor_length, y, clr); | ||
480 | } | ||
481 | |||
482 | void | ||
483 | draw_params_cursor_square(size_t i, u8 clr, bool sweep) { | ||
484 | size_t x_offset = sweep ? 0 : 30; | ||
485 | u8 x_positions[] = { | ||
486 | 0, // Duty. | ||
487 | 31, // Env. Vol. | ||
488 | 59, // Env. Direction. | ||
489 | 87, // Env. Time. | ||
490 | 118, // Sweep Number. | ||
491 | 146, // Sweep Time. | ||
492 | 132, // Sweep Direction. | ||
493 | }; | ||
494 | u8 y_positions[] = { | ||
495 | 20, // Duty. | ||
496 | 20, // Env. Vol. | ||
497 | 20, // Env. Direction. | ||
498 | 20, // Env. Time. | ||
499 | 20, // Sweep Number. | ||
500 | 20, // Sweep Time. | ||
501 | 0, // Sweep Direction. | ||
502 | }; | ||
503 | size_t cursor_length = 24; | ||
504 | size_t x = PARAMS_START_X + x_positions[i] + x_offset; | ||
505 | size_t y = PARAMS_START_Y + PARAMS_H - 23 + y_positions[i]; | ||
506 | draw_line(x, y, x + cursor_length, y, clr); | ||
507 | } | ||
508 | |||
509 | void | ||
510 | draw_params_cursor(size_t i, u8 clr) { | ||
511 | switch (channel_selection_loc) { | ||
512 | case 0: { | ||
513 | draw_params_cursor_square(i, clr, true); | ||
514 | } break; | ||
515 | case 1: { | ||
516 | draw_params_cursor_square(i, clr, false); | ||
517 | } break; | ||
518 | case 2: { | ||
519 | draw_params_cursor_wave(i, clr); | ||
520 | } break; | ||
521 | case 3: { | ||
522 | draw_params_cursor_noise(i, clr); | ||
523 | } break; | ||
524 | } | ||
525 | } | ||
526 | |||
527 | IWRAM_CODE | ||
528 | void | ||
529 | draw_wave_pattern(u8 *pattern, int x, int y, u8 clr) { | ||
530 | for (size_t i = 0; i < 16; ++i) { | ||
531 | u8 byte = pattern[i]; | ||
532 | u8 first = (byte >> 4) & 0xF; | ||
533 | u8 second = byte & 0xF; | ||
534 | u8 a = x + i * 4; | ||
535 | u8 b = y + 16; | ||
536 | draw_pixel(a, b - first, clr); | ||
537 | draw_pixel(a + 1, b - first, clr); | ||
538 | draw_pixel(a + 2, b - second, clr); | ||
539 | draw_pixel(a + 3, b - second, clr); | ||
540 | } | ||
541 | } | ||
542 | |||
543 | IWRAM_CODE | ||
544 | void | ||
545 | clear_parameters(void) { | ||
546 | size_t x0 = PARAMS_START_X; | ||
547 | size_t y0 = PARAMS_START_Y; | ||
548 | size_t x1 = PARAMS_START_X + PARAMS_W; | ||
549 | size_t y1 = PARAMS_START_Y + PARAMS_H - 1; | ||
550 | draw_filled_rect(x0, y0, x1, y1, COL_BG); | ||
551 | } | ||
552 | |||
553 | IWRAM_CODE | ||
554 | void | ||
555 | draw_parameters_wave(void) { | ||
556 | // Draw current wave data. | ||
557 | Pattern *pat = &patterns[pattern_selection_loc]; | ||
558 | { | ||
559 | u8 *wave_a = pat->ch3.params[trig_selection_loc].wave_a; | ||
560 | u8 *wave_b = pat->ch3.params[trig_selection_loc].wave_b; | ||
561 | |||
562 | size_t x = PARAMS_START_X; | ||
563 | size_t y = PARAMS_START_Y + 13; | ||
564 | |||
565 | // Wave Patterns. | ||
566 | draw_wave_pattern(wave_a, x, y, COL_WAVE_A); | ||
567 | draw_wave_pattern(wave_b, x + 70, y, COL_WAVE_B); | ||
568 | |||
569 | // Wave text. | ||
570 | x -= 2; | ||
571 | // txt_drawf_small("%02x%02x%02x%02x", x, y + 20, 4, COL_FG, | ||
572 | // wave_a[0], wave_a[1], wave_a[2], wave_a[3]); | ||
573 | // txt_drawf_small("%02x%02x%02x%02x", x + 34, y + 20, 4, COL_FG, | ||
574 | // wave_a[4], wave_a[5], wave_a[6], wave_a[7]); | ||
575 | // txt_drawf_small("%02x%02x%02x%02x", x, y + 28, 4, COL_FG, | ||
576 | // wave_a[8], wave_a[9], wave_a[10], wave_a[11]); | ||
577 | // txt_drawf_small("%02x%02x%02x%02x", x + 34, y + 28, 4, COL_FG, | ||
578 | // wave_a[12], wave_a[13], wave_a[14], wave_a[15]); | ||
579 | |||
580 | x += 70; | ||
581 | // txt_drawf_small("%02x%02x%02x%02x", x, y + 20, 4, COL_FG, | ||
582 | // wave_b[0], wave_b[1], wave_b[2], wave_b[3]); | ||
583 | // txt_drawf_small("%02x%02x%02x%02x", x + 34, y + 20, 4, COL_FG, | ||
584 | // wave_b[4], wave_b[5], wave_b[6], wave_b[7]); | ||
585 | // txt_drawf_small("%02x%02x%02x%02x", x, y + 28, 4, COL_FG, | ||
586 | // wave_b[8], wave_b[9], wave_b[10], wave_b[11]); | ||
587 | // txt_drawf_small("%02x%02x%02x%02x", x + 34, y + 28, 4, COL_FG, | ||
588 | // wave_b[12], wave_b[13], wave_b[14], wave_b[15]); | ||
589 | } | ||
590 | |||
591 | // Draw default wave buttons. | ||
592 | { | ||
593 | // Tile *wave_tiles = ASSETS_DEFAULT_WAVES; | ||
594 | size_t x = PARAMS_START_X; | ||
595 | size_t y = PARAMS_START_Y + PARAMS_H - 12; | ||
596 | for (size_t i = 0, k = 0; i < 4 * 2; i += 2, k++) { | ||
597 | // draw_tile(x + 17 * k, y, wave_tiles + i, COL_FG, true); | ||
598 | // draw_tile(x + 17 * k + 8, y, wave_tiles + i + 1, COL_FG, true); | ||
599 | } | ||
600 | for (size_t i = 0, k = 0; i < 4 * 2; i += 2, k++) { | ||
601 | // draw_tile(x + 17 * k + 70, y, wave_tiles + i, COL_FG, true); | ||
602 | // draw_tile(x + 17 * k + 8 + 70, y, wave_tiles + i + 1, COL_FG, true); | ||
603 | } | ||
604 | } | ||
605 | |||
606 | // Mode selection. | ||
607 | { | ||
608 | size_t x = PARAMS_START_X + 140; | ||
609 | size_t y = PARAMS_START_Y + PARAMS_H - 22; | ||
610 | draw_line(x, y + 4, x + 5, y + 4, COL_FG); | ||
611 | draw_line(x + 25, y + 4, x + 30, y + 4, COL_FG); | ||
612 | draw_line(x, y + 5, x, y + 16, COL_FG); | ||
613 | draw_line(x + 30, y + 5, x + 30, y + 17, COL_FG); | ||
614 | draw_line(x, y + 17, x + 30, y + 17, COL_FG); | ||
615 | // txt_drawf_small("mode", x + 6, y, 4, COL_FG); | ||
616 | |||
617 | switch (pat->ch3.params[trig_selection_loc].wave_mode) { | ||
618 | case 0: { | ||
619 | txt_drawf("A", x + 12, y + 7, 6, COL_FG); | ||
620 | } break; | ||
621 | case 1: { | ||
622 | txt_drawf("B", x + 12, y + 7, 6, COL_FG); | ||
623 | } break; | ||
624 | case 2: { | ||
625 | txt_drawf("A+B", x + 6, y + 7, 6, COL_FG); | ||
626 | } break; | ||
627 | } | ||
628 | } | ||
629 | |||
630 | // Wave volume. | ||
631 | { | ||
632 | size_t x = PARAMS_START_X + 140; | ||
633 | size_t y = PARAMS_START_Y + PARAMS_H - 45; | ||
634 | draw_line(x, y + 7, x + 7, y + 7, COL_FG); | ||
635 | draw_line(x + 23, y + 7, x + 30, y + 7, COL_FG); | ||
636 | draw_line(x, y + 8, x, y + 19, COL_FG); | ||
637 | draw_line(x + 30, y + 8, x + 30, y + 19, COL_FG); | ||
638 | draw_line(x, y + 20, x + 30, y + 20, COL_FG); | ||
639 | // txt_drawf_small("vol", x + 8, y + 3, 4, COL_FG); | ||
640 | |||
641 | switch (pat->ch3.params[trig_selection_loc].wave_volume) { | ||
642 | case 0: { | ||
643 | txt_drawf("0", x + 12, y + 10, 6, COL_FG); | ||
644 | } break; | ||
645 | case 1: { | ||
646 | txt_drawf("25", x + 9, y + 10, 6, COL_FG); | ||
647 | } break; | ||
648 | case 2: { | ||
649 | txt_drawf("50", x + 9, y + 10, 6, COL_FG); | ||
650 | } break; | ||
651 | case 3: { | ||
652 | txt_drawf("75", x + 9, y + 10, 6, COL_FG); | ||
653 | } break; | ||
654 | case 4: { | ||
655 | txt_drawf("100", x + 6, y + 10, 6, COL_FG); | ||
656 | } break; | ||
657 | } | ||
658 | } | ||
659 | } | ||
660 | |||
661 | void | ||
662 | draw_parameters_square(ChannelSquareParams *params, bool sweep) { | ||
663 | size_t x_offset = sweep ? 0 : 30; | ||
664 | |||
665 | // Duty cycle. | ||
666 | { | ||
667 | // Shape drawing. | ||
668 | { | ||
669 | size_t x = PARAMS_START_X + x_offset; | ||
670 | size_t y = PARAMS_START_Y + PARAMS_H - 44; | ||
671 | |||
672 | size_t x0 = x + 2; | ||
673 | size_t x1 = x0; | ||
674 | size_t x2 = x0; | ||
675 | size_t x3 = x0; | ||
676 | size_t x4 = x0; | ||
677 | size_t x5 = x0; | ||
678 | size_t y0 = y + 14; | ||
679 | size_t y1 = y + 2; | ||
680 | |||
681 | switch (params->duty_cycle) { | ||
682 | case 0: { | ||
683 | x1 += 4; | ||
684 | x2 += 6; | ||
685 | x3 += 13; | ||
686 | x4 += 15; | ||
687 | x5 += 20; | ||
688 | } break; | ||
689 | case 1: { | ||
690 | x1 += 4; | ||
691 | x2 += 7; | ||
692 | x3 += 13; | ||
693 | x4 += 16; | ||
694 | x5 += 20; | ||
695 | } break; | ||
696 | case 2: { | ||
697 | x1 += 3; | ||
698 | x2 += 8; | ||
699 | x3 += 12; | ||
700 | x4 += 17; | ||
701 | x5 += 20; | ||
702 | } break; | ||
703 | case 3: { | ||
704 | x1 += 2; | ||
705 | x2 += 9; | ||
706 | x3 += 11; | ||
707 | x4 += 18; | ||
708 | x5 += 20; | ||
709 | } break; | ||
710 | } | ||
711 | draw_line(x0, y0, x1, y0, COL_RED); | ||
712 | draw_line(x1, y1, x1, y0, COL_RED); | ||
713 | draw_line(x1, y1, x2, y1, COL_RED); | ||
714 | draw_line(x2, y1, x2, y0, COL_RED); | ||
715 | draw_line(x2, y0, x3, y0, COL_RED); | ||
716 | draw_line(x3, y1, x3, y0, COL_RED); | ||
717 | draw_line(x3, y1, x4, y1, COL_RED); | ||
718 | draw_line(x4, y1, x4, y0, COL_RED); | ||
719 | draw_line(x4, y0, x5, y0, COL_RED); | ||
720 | |||
721 | // Bounding box. | ||
722 | draw_rect(x, y - 3, x + 24, y + 18, COL_RED); | ||
723 | } | ||
724 | |||
725 | // Param box. | ||
726 | { | ||
727 | size_t x = PARAMS_START_X + x_offset; | ||
728 | size_t y = PARAMS_START_Y + PARAMS_H - 25; | ||
729 | draw_line(x, y + 7, x + 2, y + 7, COL_FG); | ||
730 | draw_line(x + 22, y + 7, x + 24, y + 7, COL_FG); | ||
731 | draw_line(x, y + 8, x, y + 19, COL_FG); | ||
732 | draw_line(x + 24, y + 8, x + 24, y + 19, COL_FG); | ||
733 | draw_line(x, y + 20, x + 24, y + 20, COL_FG); | ||
734 | // txt_drawf_small("duty", x + 3, y + 3, 4, COL_FG); | ||
735 | |||
736 | switch (params->duty_cycle) { | ||
737 | case 0: { | ||
738 | txt_drawf("12", x + 6, y + 10, 6, COL_FG); | ||
739 | } break; | ||
740 | case 1: { | ||
741 | txt_drawf("25", x + 6, y + 10, 6, COL_FG); | ||
742 | } break; | ||
743 | case 2: { | ||
744 | txt_drawf("50", x + 6, y + 10, 6, COL_FG); | ||
745 | } break; | ||
746 | case 3: { | ||
747 | txt_drawf("75", x + 6, y + 10, 6, COL_FG); | ||
748 | } break; | ||
749 | } | ||
750 | } | ||
751 | } | ||
752 | |||
753 | // Envelope. | ||
754 | { | ||
755 | // Env. drawing. | ||
756 | { | ||
757 | // Bounding box. | ||
758 | { | ||
759 | size_t x0 = PARAMS_START_X + 31 + x_offset; | ||
760 | size_t y0 = PARAMS_START_Y + PARAMS_H - 47; | ||
761 | size_t x1 = x0 + 79; | ||
762 | size_t y1 = y0 + 21; | ||
763 | draw_rect(x0, y0, x1, y1, COL_CYAN); | ||
764 | } | ||
765 | |||
766 | size_t x = PARAMS_START_X + 42 + x_offset; | ||
767 | size_t y = PARAMS_START_Y + PARAMS_H - 44; | ||
768 | size_t x0 = x; | ||
769 | size_t y0 = y + 15 - params->env_volume; | ||
770 | size_t x1 = x + 8 * params->env_time; | ||
771 | size_t y1 = params->env_direction == 0 ? y + 15 : y; | ||
772 | size_t x2 = x + 8 * 7 + 1; | ||
773 | size_t y2 = y1; | ||
774 | |||
775 | // Env. | ||
776 | if (params->env_time == 0) { | ||
777 | draw_line(x1, y0, x2, y0, COL_CYAN); | ||
778 | } else { | ||
779 | draw_line(x0, y0, x1, y1, COL_CYAN); | ||
780 | draw_line(x1, y1, x2, y2, COL_CYAN); | ||
781 | } | ||
782 | } | ||
783 | |||
784 | // Env. volume. | ||
785 | { | ||
786 | size_t x = PARAMS_START_X + 31 + x_offset; | ||
787 | size_t y = PARAMS_START_Y + PARAMS_H - 25; | ||
788 | draw_line(x, y + 7, x + 4, y + 7, COL_FG); | ||
789 | draw_line(x + 20, y + 7, x + 24, y + 7, COL_FG); | ||
790 | draw_line(x, y + 8, x, y + 19, COL_FG); | ||
791 | draw_line(x + 24, y + 8, x + 24, y + 19, COL_FG); | ||
792 | draw_line(x, y + 20, x + 24, y + 20, COL_FG); | ||
793 | // txt_drawf_small("vol", x + 5, y + 3, 4, COL_FG); | ||
794 | |||
795 | switch (params->env_volume) { | ||
796 | case 0: { | ||
797 | txt_drawf("0", x + 9, y + 10, 6, COL_FG); | ||
798 | } break; | ||
799 | case 1: { | ||
800 | txt_drawf("6", x + 9, y + 10, 6, COL_FG); | ||
801 | } break; | ||
802 | case 2: { | ||
803 | txt_drawf("13", x + 6, y + 10, 6, COL_FG); | ||
804 | } break; | ||
805 | case 3: { | ||
806 | txt_drawf("20", x + 6, y + 10, 6, COL_FG); | ||
807 | } break; | ||
808 | case 4: { | ||
809 | txt_drawf("26", x + 6, y + 10, 6, COL_FG); | ||
810 | } break; | ||
811 | case 5: { | ||
812 | txt_drawf("33", x + 6, y + 10, 6, COL_FG); | ||
813 | } break; | ||
814 | case 6: { | ||
815 | txt_drawf("40", x + 6, y + 10, 6, COL_FG); | ||
816 | } break; | ||
817 | case 7: { | ||
818 | txt_drawf("46", x + 6, y + 10, 6, COL_FG); | ||
819 | } break; | ||
820 | case 8: { | ||
821 | txt_drawf("53", x + 6, y + 10, 6, COL_FG); | ||
822 | } break; | ||
823 | case 9: { | ||
824 | txt_drawf("60", x + 6, y + 10, 6, COL_FG); | ||
825 | } break; | ||
826 | case 10: { | ||
827 | txt_drawf("66", x + 6, y + 10, 6, COL_FG); | ||
828 | } break; | ||
829 | case 11: { | ||
830 | txt_drawf("73", x + 6, y + 10, 6, COL_FG); | ||
831 | } break; | ||
832 | case 12: { | ||
833 | txt_drawf("80", x + 6, y + 10, 6, COL_FG); | ||
834 | } break; | ||
835 | case 13: { | ||
836 | txt_drawf("86", x + 6, y + 10, 6, COL_FG); | ||
837 | } break; | ||
838 | case 14: { | ||
839 | txt_drawf("93", x + 6, y + 10, 6, COL_FG); | ||
840 | } break; | ||
841 | case 15: { | ||
842 | txt_drawf("100", x + 3, y + 10, 6, COL_FG); | ||
843 | } break; | ||
844 | } | ||
845 | } | ||
846 | |||
847 | // Env. direction | ||
848 | { | ||
849 | size_t x = PARAMS_START_X + 59 + x_offset; | ||
850 | size_t y = PARAMS_START_Y + PARAMS_H - 25; | ||
851 | draw_line(x, y + 7, x + 4, y + 7, COL_FG); | ||
852 | draw_line(x + 20, y + 7, x + 24, y + 7, COL_FG); | ||
853 | draw_line(x, y + 8, x, y + 19, COL_FG); | ||
854 | draw_line(x + 24, y + 8, x + 24, y + 19, COL_FG); | ||
855 | draw_line(x, y + 20, x + 24, y + 20, COL_FG); | ||
856 | // txt_drawf_small("dir", x + 5, y + 3, 4, COL_FG); | ||
857 | |||
858 | char arr_up[2] = { 0x19, 0 }; | ||
859 | char arr_down[2] = { 0x18, 0 }; | ||
860 | switch (params->env_direction) { | ||
861 | case 0: { | ||
862 | txt_drawf(arr_up, x + 9, y + 11, 6, COL_FG); | ||
863 | } break; | ||
864 | case 1: { | ||
865 | txt_drawf(arr_down, x + 9, y + 11, 6, COL_FG); | ||
866 | } break; | ||
867 | } | ||
868 | } | ||
869 | |||
870 | // Env. time. | ||
871 | { | ||
872 | size_t x = PARAMS_START_X + 87 + x_offset; | ||
873 | size_t y = PARAMS_START_Y + PARAMS_H - 25; | ||
874 | draw_line(x, y + 7, x + 2, y + 7, COL_FG); | ||
875 | draw_line(x + 22, y + 7, x + 24, y + 7, COL_FG); | ||
876 | draw_line(x, y + 8, x, y + 19, COL_FG); | ||
877 | draw_line(x + 24, y + 8, x + 24, y + 19, COL_FG); | ||
878 | draw_line(x, y + 20, x + 24, y + 20, COL_FG); | ||
879 | // txt_drawf_small("time", x + 3, y + 3, 4, COL_FG); | ||
880 | |||
881 | switch (params->env_time) { | ||
882 | case 0: { | ||
883 | txt_drawf("0", x + 9, y + 10, 6, COL_FG); | ||
884 | } break; | ||
885 | case 1: { | ||
886 | txt_drawf("14", x + 6, y + 10, 6, COL_FG); | ||
887 | } break; | ||
888 | case 2: { | ||
889 | txt_drawf("28", x + 6, y + 10, 6, COL_FG); | ||
890 | } break; | ||
891 | case 3: { | ||
892 | txt_drawf("42", x + 6, y + 10, 6, COL_FG); | ||
893 | } break; | ||
894 | case 4: { | ||
895 | txt_drawf("57", x + 6, y + 10, 6, COL_FG); | ||
896 | } break; | ||
897 | case 5: { | ||
898 | txt_drawf("71", x + 6, y + 10, 6, COL_FG); | ||
899 | } break; | ||
900 | case 6: { | ||
901 | txt_drawf("85", x + 6, y + 10, 6, COL_FG); | ||
902 | } break; | ||
903 | case 7: { | ||
904 | txt_drawf("100", x + 3, y + 10, 6, COL_FG); | ||
905 | } break; | ||
906 | } | ||
907 | } | ||
908 | } | ||
909 | |||
910 | // Sweep number. | ||
911 | if (sweep) { | ||
912 | size_t x = PARAMS_START_X + 118; | ||
913 | size_t y = PARAMS_START_Y + PARAMS_H - 25; | ||
914 | draw_line(x, y + 7, x + 4, y + 7, COL_FG); | ||
915 | draw_line(x + 20, y + 7, x + 24, y + 7, COL_FG); | ||
916 | draw_line(x, y + 8, x, y + 19, COL_FG); | ||
917 | draw_line(x + 24, y + 8, x + 24, y + 19, COL_FG); | ||
918 | draw_line(x, y + 20, x + 24, y + 20, COL_FG); | ||
919 | // txt_drawf_small("num", x + 5, y + 3, 4, COL_FG); | ||
920 | |||
921 | switch (params->sweep_number) { | ||
922 | case 0: { | ||
923 | txt_drawf("0", x + 9, y + 10, 6, COL_FG); | ||
924 | } break; | ||
925 | case 1: { | ||
926 | txt_drawf("1", x + 9, y + 10, 6, COL_FG); | ||
927 | } break; | ||
928 | case 2: { | ||
929 | txt_drawf("2", x + 9, y + 10, 6, COL_FG); | ||
930 | } break; | ||
931 | case 3: { | ||
932 | txt_drawf("3", x + 9, y + 10, 6, COL_FG); | ||
933 | } break; | ||
934 | case 4: { | ||
935 | txt_drawf("4", x + 9, y + 10, 6, COL_FG); | ||
936 | } break; | ||
937 | case 5: { | ||
938 | txt_drawf("5", x + 9, y + 10, 6, COL_FG); | ||
939 | } break; | ||
940 | case 6: { | ||
941 | txt_drawf("6", x + 9, y + 10, 6, COL_FG); | ||
942 | } break; | ||
943 | case 7: { | ||
944 | txt_drawf("7", x + 9, y + 10, 6, COL_FG); | ||
945 | } break; | ||
946 | } | ||
947 | } | ||
948 | |||
949 | // Sweep time. | ||
950 | if (sweep) { | ||
951 | size_t x = PARAMS_START_X + 146; | ||
952 | size_t y = PARAMS_START_Y + PARAMS_H - 25; | ||
953 | draw_line(x, y + 7, x + 2, y + 7, COL_FG); | ||
954 | draw_line(x + 22, y + 7, x + 24, y + 7, COL_FG); | ||
955 | draw_line(x, y + 8, x, y + 19, COL_FG); | ||
956 | draw_line(x + 24, y + 8, x + 24, y + 19, COL_FG); | ||
957 | draw_line(x, y + 20, x + 24, y + 20, COL_FG); | ||
958 | // txt_drawf_small("time", x + 3, y + 3, 4, COL_FG); | ||
959 | |||
960 | switch (params->sweep_time) { | ||
961 | case 0: { | ||
962 | txt_drawf("0", x + 9, y + 10, 6, COL_FG); | ||
963 | } break; | ||
964 | case 1: { | ||
965 | txt_drawf("1", x + 9, y + 10, 6, COL_FG); | ||
966 | } break; | ||
967 | case 2: { | ||
968 | txt_drawf("2", x + 9, y + 10, 6, COL_FG); | ||
969 | } break; | ||
970 | case 3: { | ||
971 | txt_drawf("3", x + 9, y + 10, 6, COL_FG); | ||
972 | } break; | ||
973 | case 4: { | ||
974 | txt_drawf("4", x + 9, y + 10, 6, COL_FG); | ||
975 | } break; | ||
976 | case 5: { | ||
977 | txt_drawf("5", x + 9, y + 10, 6, COL_FG); | ||
978 | } break; | ||
979 | case 6: { | ||
980 | txt_drawf("6", x + 9, y + 10, 6, COL_FG); | ||
981 | } break; | ||
982 | case 7: { | ||
983 | txt_drawf("7", x + 9, y + 10, 6, COL_FG); | ||
984 | } break; | ||
985 | } | ||
986 | } | ||
987 | |||
988 | // Sweep direction. | ||
989 | if (sweep) { | ||
990 | size_t x = PARAMS_START_X + 132; | ||
991 | size_t y = PARAMS_START_Y + PARAMS_H - 45; | ||
992 | draw_line(x, y + 7, x + 4, y + 7, COL_FG); | ||
993 | draw_line(x + 20, y + 7, x + 24, y + 7, COL_FG); | ||
994 | draw_line(x, y + 8, x, y + 19, COL_FG); | ||
995 | draw_line(x + 24, y + 8, x + 24, y + 19, COL_FG); | ||
996 | draw_line(x, y + 20, x + 24, y + 20, COL_FG); | ||
997 | // txt_drawf_small("dir", x + 5, y + 3, 4, COL_FG); | ||
998 | |||
999 | char arr_up[2] = { 0x19, 0 }; | ||
1000 | char arr_down[2] = { 0x18, 0 }; | ||
1001 | switch (params->sweep_direction) { | ||
1002 | case 0: { | ||
1003 | txt_drawf(arr_up, x + 9, y + 11, 6, COL_FG); | ||
1004 | } break; | ||
1005 | case 1: { | ||
1006 | txt_drawf(arr_down, x + 9, y + 11, 6, COL_FG); | ||
1007 | } break; | ||
1008 | } | ||
1009 | } | ||
1010 | |||
1011 | // Labels. | ||
1012 | { | ||
1013 | size_t x = PARAMS_START_X + x_offset; | ||
1014 | size_t y = PARAMS_START_Y + PARAMS_H - 45; | ||
1015 | // txt_drawf_small("shape", x + 1, y - 12, 4, COL_FG); | ||
1016 | // txt_drawf_small("envelope", x + 54, y - 12, 4, COL_FG); | ||
1017 | if (sweep) { | ||
1018 | // txt_drawf_small("sweep", x + 133, y - 12, 4, COL_FG); | ||
1019 | } | ||
1020 | } | ||
1021 | } | ||
1022 | |||
1023 | void | ||
1024 | draw_parameters_noise(void) { | ||
1025 | size_t x_offset = 30; | ||
1026 | Pattern *pat = &patterns[pattern_selection_loc]; | ||
1027 | ChannelNoiseParams *params = &pat->ch4.params[trig_selection_loc]; | ||
1028 | |||
1029 | // Bit mode. | ||
1030 | { | ||
1031 | // Param box. | ||
1032 | { | ||
1033 | size_t x = PARAMS_START_X + x_offset; | ||
1034 | size_t y = PARAMS_START_Y + PARAMS_H - 25; | ||
1035 | draw_line(x, y + 7, x + 2, y + 7, COL_FG); | ||
1036 | draw_line(x + 22, y + 7, x + 24, y + 7, COL_FG); | ||
1037 | draw_line(x, y + 8, x, y + 19, COL_FG); | ||
1038 | draw_line(x + 24, y + 8, x + 24, y + 19, COL_FG); | ||
1039 | draw_line(x, y + 20, x + 24, y + 20, COL_FG); | ||
1040 | // txt_drawf_small("mode", x + 3, y + 3, 4, COL_FG); | ||
1041 | |||
1042 | switch (params->bit_mode) { | ||
1043 | case 0: { | ||
1044 | txt_drawf("A", x + 9, y + 10, 6, COL_FG); | ||
1045 | } break; | ||
1046 | case 1: { | ||
1047 | txt_drawf("B", x + 9, y + 10, 6, COL_FG); | ||
1048 | } break; | ||
1049 | } | ||
1050 | } | ||
1051 | } | ||
1052 | |||
1053 | // Envelope. | ||
1054 | { | ||
1055 | // Env. drawing. | ||
1056 | { | ||
1057 | // Bounding box. | ||
1058 | { | ||
1059 | size_t x0 = PARAMS_START_X + 31 + x_offset; | ||
1060 | size_t y0 = PARAMS_START_Y + PARAMS_H - 47; | ||
1061 | size_t x1 = x0 + 79; | ||
1062 | size_t y1 = y0 + 21; | ||
1063 | draw_rect(x0, y0, x1, y1, COL_CYAN); | ||
1064 | } | ||
1065 | |||
1066 | size_t x = PARAMS_START_X + 42 + x_offset; | ||
1067 | size_t y = PARAMS_START_Y + PARAMS_H - 44; | ||
1068 | size_t x0 = x; | ||
1069 | size_t y0 = y + 15 - params->env_volume; | ||
1070 | size_t x1 = x + 8 * params->env_time; | ||
1071 | size_t y1 = params->env_direction == 0 ? y + 15 : y; | ||
1072 | size_t x2 = x + 8 * 7 + 1; | ||
1073 | size_t y2 = y1; | ||
1074 | |||
1075 | // Env. | ||
1076 | if (params->env_time == 0) { | ||
1077 | draw_line(x1, y0, x2, y0, COL_CYAN); | ||
1078 | } else { | ||
1079 | draw_line(x0, y0, x1, y1, COL_CYAN); | ||
1080 | draw_line(x1, y1, x2, y2, COL_CYAN); | ||
1081 | } | ||
1082 | } | ||
1083 | |||
1084 | // Env. volume. | ||
1085 | { | ||
1086 | size_t x = PARAMS_START_X + 31 + x_offset; | ||
1087 | size_t y = PARAMS_START_Y + PARAMS_H - 25; | ||
1088 | draw_line(x, y + 7, x + 4, y + 7, COL_FG); | ||
1089 | draw_line(x + 20, y + 7, x + 24, y + 7, COL_FG); | ||
1090 | draw_line(x, y + 8, x, y + 19, COL_FG); | ||
1091 | draw_line(x + 24, y + 8, x + 24, y + 19, COL_FG); | ||
1092 | draw_line(x, y + 20, x + 24, y + 20, COL_FG); | ||
1093 | // txt_drawf_small("vol", x + 5, y + 3, 4, COL_FG); | ||
1094 | |||
1095 | switch (params->env_volume) { | ||
1096 | case 0: { | ||
1097 | txt_drawf("0", x + 9, y + 10, 6, COL_FG); | ||
1098 | } break; | ||
1099 | case 1: { | ||
1100 | txt_drawf("6", x + 9, y + 10, 6, COL_FG); | ||
1101 | } break; | ||
1102 | case 2: { | ||
1103 | txt_drawf("13", x + 6, y + 10, 6, COL_FG); | ||
1104 | } break; | ||
1105 | case 3: { | ||
1106 | txt_drawf("20", x + 6, y + 10, 6, COL_FG); | ||
1107 | } break; | ||
1108 | case 4: { | ||
1109 | txt_drawf("26", x + 6, y + 10, 6, COL_FG); | ||
1110 | } break; | ||
1111 | case 5: { | ||
1112 | txt_drawf("33", x + 6, y + 10, 6, COL_FG); | ||
1113 | } break; | ||
1114 | case 6: { | ||
1115 | txt_drawf("40", x + 6, y + 10, 6, COL_FG); | ||
1116 | } break; | ||
1117 | case 7: { | ||
1118 | txt_drawf("46", x + 6, y + 10, 6, COL_FG); | ||
1119 | } break; | ||
1120 | case 8: { | ||
1121 | txt_drawf("53", x + 6, y + 10, 6, COL_FG); | ||
1122 | } break; | ||
1123 | case 9: { | ||
1124 | txt_drawf("60", x + 6, y + 10, 6, COL_FG); | ||
1125 | } break; | ||
1126 | case 10: { | ||
1127 | txt_drawf("66", x + 6, y + 10, 6, COL_FG); | ||
1128 | } break; | ||
1129 | case 11: { | ||
1130 | txt_drawf("73", x + 6, y + 10, 6, COL_FG); | ||
1131 | } break; | ||
1132 | case 12: { | ||
1133 | txt_drawf("80", x + 6, y + 10, 6, COL_FG); | ||
1134 | } break; | ||
1135 | case 13: { | ||
1136 | txt_drawf("86", x + 6, y + 10, 6, COL_FG); | ||
1137 | } break; | ||
1138 | case 14: { | ||
1139 | txt_drawf("93", x + 6, y + 10, 6, COL_FG); | ||
1140 | } break; | ||
1141 | case 15: { | ||
1142 | txt_drawf("100", x + 3, y + 10, 6, COL_FG); | ||
1143 | } break; | ||
1144 | } | ||
1145 | } | ||
1146 | |||
1147 | // Env. direction | ||
1148 | { | ||
1149 | size_t x = PARAMS_START_X + 59 + x_offset; | ||
1150 | size_t y = PARAMS_START_Y + PARAMS_H - 25; | ||
1151 | draw_line(x, y + 7, x + 4, y + 7, COL_FG); | ||
1152 | draw_line(x + 20, y + 7, x + 24, y + 7, COL_FG); | ||
1153 | draw_line(x, y + 8, x, y + 19, COL_FG); | ||
1154 | draw_line(x + 24, y + 8, x + 24, y + 19, COL_FG); | ||
1155 | draw_line(x, y + 20, x + 24, y + 20, COL_FG); | ||
1156 | // txt_drawf_small("dir", x + 5, y + 3, 4, COL_FG); | ||
1157 | |||
1158 | char arr_up[2] = { 0x19, 0 }; | ||
1159 | char arr_down[2] = { 0x18, 0 }; | ||
1160 | switch (params->env_direction) { | ||
1161 | case 0: { | ||
1162 | txt_drawf(arr_up, x + 9, y + 11, 6, COL_FG); | ||
1163 | } break; | ||
1164 | case 1: { | ||
1165 | txt_drawf(arr_down, x + 9, y + 11, 6, COL_FG); | ||
1166 | } break; | ||
1167 | } | ||
1168 | } | ||
1169 | |||
1170 | // Env. time. | ||
1171 | { | ||
1172 | size_t x = PARAMS_START_X + 87 + x_offset; | ||
1173 | size_t y = PARAMS_START_Y + PARAMS_H - 25; | ||
1174 | draw_line(x, y + 7, x + 2, y + 7, COL_FG); | ||
1175 | draw_line(x + 22, y + 7, x + 24, y + 7, COL_FG); | ||
1176 | draw_line(x, y + 8, x, y + 19, COL_FG); | ||
1177 | draw_line(x + 24, y + 8, x + 24, y + 19, COL_FG); | ||
1178 | draw_line(x, y + 20, x + 24, y + 20, COL_FG); | ||
1179 | // txt_drawf_small("time", x + 3, y + 3, 4, COL_FG); | ||
1180 | |||
1181 | switch (params->env_time) { | ||
1182 | case 0: { | ||
1183 | txt_drawf("0", x + 9, y + 10, 6, COL_FG); | ||
1184 | } break; | ||
1185 | case 1: { | ||
1186 | txt_drawf("14", x + 6, y + 10, 6, COL_FG); | ||
1187 | } break; | ||
1188 | case 2: { | ||
1189 | txt_drawf("28", x + 6, y + 10, 6, COL_FG); | ||
1190 | } break; | ||
1191 | case 3: { | ||
1192 | txt_drawf("42", x + 6, y + 10, 6, COL_FG); | ||
1193 | } break; | ||
1194 | case 4: { | ||
1195 | txt_drawf("57", x + 6, y + 10, 6, COL_FG); | ||
1196 | } break; | ||
1197 | case 5: { | ||
1198 | txt_drawf("71", x + 6, y + 10, 6, COL_FG); | ||
1199 | } break; | ||
1200 | case 6: { | ||
1201 | txt_drawf("85", x + 6, y + 10, 6, COL_FG); | ||
1202 | } break; | ||
1203 | case 7: { | ||
1204 | txt_drawf("100", x + 3, y + 10, 6, COL_FG); | ||
1205 | } break; | ||
1206 | } | ||
1207 | } | ||
1208 | } | ||
1209 | |||
1210 | // Labels. | ||
1211 | { | ||
1212 | size_t x = PARAMS_START_X + x_offset; | ||
1213 | size_t y = PARAMS_START_Y + PARAMS_H - 45; | ||
1214 | // txt_drawf_small("envelope", x + 54, y - 12, 4, COL_FG); | ||
1215 | } | ||
1216 | } | ||
1217 | |||
1218 | void | ||
1219 | draw_parameters(void) { | ||
1220 | clear_parameters(); | ||
1221 | Pattern *pat = &patterns[pattern_selection_loc]; | ||
1222 | switch (channel_selection_loc) { | ||
1223 | case 0: { | ||
1224 | draw_parameters_square(&pat->ch1.params[trig_selection_loc], true); | ||
1225 | } break; | ||
1226 | case 1: { | ||
1227 | draw_parameters_square(&pat->ch2.params[trig_selection_loc], false); | ||
1228 | } break; | ||
1229 | case 2: { | ||
1230 | draw_parameters_wave(); | ||
1231 | } break; | ||
1232 | case 3: { | ||
1233 | draw_parameters_noise(); | ||
1234 | } break; | ||
1235 | } | ||
1236 | } | ||
1237 | |||