diff options
author | Bad Diode <bd@badd10de.dev> | 2023-07-13 12:00:11 +0200 |
---|---|---|
committer | Bad Diode <bd@badd10de.dev> | 2023-07-13 12:00:11 +0200 |
commit | 7f57051c51c16c88e5dcaa7bd51ccaec31469c4a (patch) | |
tree | b484dc485d7f9718238343ffb5952428d2f52621 | |
parent | d1c68125b6825f0327a4089aa8ddca5105e78ec1 (diff) | |
download | stepper-7f57051c51c16c88e5dcaa7bd51ccaec31469c4a.tar.gz stepper-7f57051c51c16c88e5dcaa7bd51ccaec31469c4a.zip |
Add working pattern chaining prototype
-rw-r--r-- | src/drawing.c | 20 | ||||
-rw-r--r-- | src/globals.c | 4 | ||||
-rw-r--r-- | src/sequencer.c | 76 |
3 files changed, 85 insertions, 15 deletions
diff --git a/src/drawing.c b/src/drawing.c index dff5db2..4e793ea 100644 --- a/src/drawing.c +++ b/src/drawing.c | |||
@@ -1305,11 +1305,16 @@ draw_notif_bar() { | |||
1305 | *ptr++ = 'n'; | 1305 | *ptr++ = 'n'; |
1306 | *ptr++ = ':'; | 1306 | *ptr++ = ':'; |
1307 | *ptr++ = ' '; | 1307 | *ptr++ = ' '; |
1308 | for (size_t i = 0; i < chain.len; i++) { | 1308 | bool first = true; |
1309 | if (i != 0) { | 1309 | for (size_t i = 0; i < MAX_CHAIN; i++) { |
1310 | if (chain.active[i] != 1) { | ||
1311 | continue; | ||
1312 | } | ||
1313 | if (!first) { | ||
1310 | *ptr++ = '-'; | 1314 | *ptr++ = '-'; |
1311 | } | 1315 | } |
1312 | *ptr++ = 'A' + chain.chain[i]; | 1316 | *ptr++ = 'A' + chain.chain[i]; |
1317 | first = false; | ||
1313 | } | 1318 | } |
1314 | *ptr++ = '\0'; | 1319 | *ptr++ = '\0'; |
1315 | txt_drawf_small(msg, x0 + 2, y0 + 1, color); | 1320 | txt_drawf_small(msg, x0 + 2, y0 + 1, color); |
@@ -1338,13 +1343,8 @@ draw_pattern_chain() { | |||
1338 | if (chain.active[i]) { | 1343 | if (chain.active[i]) { |
1339 | txt_drawc('A' + chain.chain[i], x0 + 4, y0 + 3, color); | 1344 | txt_drawc('A' + chain.chain[i], x0 + 4, y0 + 3, color); |
1340 | } | 1345 | } |
1346 | if (chain.current == i && chain.len != 0) { | ||
1347 | draw_line(x0 + 5, y1 - 2, x1 - 5, y1 - 2, COL_ACC_0); | ||
1348 | } | ||
1341 | } | 1349 | } |
1342 | // draw_rect( | ||
1343 | // PARAMS_START_X, | ||
1344 | // PARAMS_START_Y + 6, | ||
1345 | // PARAMS_START_X + PARAMS_W, | ||
1346 | // PARAMS_START_Y + PARAMS_H - 6, COL_FG); | ||
1347 | // txt_drawf_small("Current pattern: %s", PARAMS_START_X + 3, PARAMS_START_Y + 8, COL_FG, "A"); | ||
1348 | // txt_drawf_small("Next pattern: %s", PARAMS_START_X + 3, PARAMS_START_Y + 8 * 2, COL_FG, "A"); | ||
1349 | // txt_drawf_small("Chain: %s", PARAMS_START_X + 3, PARAMS_START_Y + 8 * 3, COL_FG, "A - B - B - A - B"); | ||
1350 | } | 1350 | } |
diff --git a/src/globals.c b/src/globals.c index 3a70005..1efa90c 100644 --- a/src/globals.c +++ b/src/globals.c | |||
@@ -144,8 +144,10 @@ typedef struct Chain { | |||
144 | u8 chain[MAX_CHAIN]; | 144 | u8 chain[MAX_CHAIN]; |
145 | u8 active[MAX_CHAIN]; | 145 | u8 active[MAX_CHAIN]; |
146 | u8 len; | 146 | u8 len; |
147 | u8 loop; | ||
148 | u8 current; | 147 | u8 current; |
148 | u8 playing; | ||
149 | } Chain; | 149 | } Chain; |
150 | 150 | ||
151 | // DEBUG:... | ||
152 | // static Chain chain = {.chain = {0, 1, 2, 3, 4, 5, 6}, .active = { 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1,1, 1,1,1,1}, .len = 14}; | ||
151 | static Chain chain = {0}; | 153 | static Chain chain = {0}; |
diff --git a/src/sequencer.c b/src/sequencer.c index 44ff90e..8d79c65 100644 --- a/src/sequencer.c +++ b/src/sequencer.c | |||
@@ -47,6 +47,30 @@ gate_on(void) { | |||
47 | TIMER_CTRL_3 = TIMER_CTRL_IRQ | TIMER_CTRL_ENABLE | TIMER_CTRL_FREQ_3; | 47 | TIMER_CTRL_3 = TIMER_CTRL_IRQ | TIMER_CTRL_ENABLE | TIMER_CTRL_FREQ_3; |
48 | } | 48 | } |
49 | 49 | ||
50 | u8 | ||
51 | find_next_pattern(void) { | ||
52 | u8 idx = (chain.current + 1) % 16; | ||
53 | for (size_t i = 0; i < MAX_CHAIN; i++) { | ||
54 | if (chain.active[idx] == 1) { | ||
55 | break; | ||
56 | } | ||
57 | idx = (idx + 1) % 16; | ||
58 | } | ||
59 | return idx; | ||
60 | } | ||
61 | |||
62 | u8 | ||
63 | find_prev_pattern(void) { | ||
64 | u8 idx = chain.current == 0 ? 15 : (chain.current - 1); | ||
65 | for (size_t i = 0; i < MAX_CHAIN; i++) { | ||
66 | if (chain.active[idx] == 1) { | ||
67 | break; | ||
68 | } | ||
69 | idx = chain.current == 0 ? 15 : (chain.current - 1); | ||
70 | } | ||
71 | return idx; | ||
72 | } | ||
73 | |||
50 | void | 74 | void |
51 | play_step(void) { | 75 | play_step(void) { |
52 | Pattern *pat = &patterns[current_pattern]; | 76 | Pattern *pat = &patterns[current_pattern]; |
@@ -54,6 +78,18 @@ play_step(void) { | |||
54 | current_pattern = next_pattern; | 78 | current_pattern = next_pattern; |
55 | redraw_pattern_buttons = true; | 79 | redraw_pattern_buttons = true; |
56 | update_bpm = true; | 80 | update_bpm = true; |
81 | } else if (chain.len != 0 && step_counter == 15) { | ||
82 | redraw_pattern_buttons = true; | ||
83 | update_bpm = true; | ||
84 | if (!chain.playing) { | ||
85 | next_pattern = chain.chain[chain.current]; | ||
86 | current_pattern = next_pattern; | ||
87 | } else { | ||
88 | chain.current = find_next_pattern(); | ||
89 | next_pattern = chain.chain[chain.current]; | ||
90 | current_pattern = next_pattern; | ||
91 | } | ||
92 | chain.playing = true; | ||
57 | } | 93 | } |
58 | if (pat->ch1.active) { | 94 | if (pat->ch1.active) { |
59 | TriggerNote *trig = &pat->ch1.notes[step_counter]; | 95 | TriggerNote *trig = &pat->ch1.notes[step_counter]; |
@@ -316,6 +352,9 @@ stop_sound(void) { | |||
316 | void | 352 | void |
317 | stop_playing(void) { | 353 | stop_playing(void) { |
318 | step_counter = 0; | 354 | step_counter = 0; |
355 | chain.current = 15; | ||
356 | chain.current = find_next_pattern(); | ||
357 | chain.playing = false; | ||
319 | stop_sound(); | 358 | stop_sound(); |
320 | } | 359 | } |
321 | 360 | ||
@@ -323,6 +362,15 @@ void | |||
323 | toggle_playing(void) { | 362 | toggle_playing(void) { |
324 | play_status ^= 1; | 363 | play_status ^= 1; |
325 | step_counter = 0; | 364 | step_counter = 0; |
365 | chain.current = 15; | ||
366 | chain.current = find_next_pattern(); | ||
367 | chain.playing = false; | ||
368 | if (current_pattern == next_pattern && chain.len > 0) { | ||
369 | chain.playing = true; | ||
370 | next_pattern = chain.chain[chain.current]; | ||
371 | current_pattern = next_pattern; | ||
372 | } | ||
373 | redraw_pattern_buttons = true; | ||
326 | SOUND_SQUARE1_CTRL = 0; | 374 | SOUND_SQUARE1_CTRL = 0; |
327 | SOUND_SQUARE2_CTRL = 0; | 375 | SOUND_SQUARE2_CTRL = 0; |
328 | SOUND_WAVE_CTRL = 0; | 376 | SOUND_WAVE_CTRL = 0; |
@@ -351,6 +399,12 @@ pause_playing(void) { | |||
351 | SOUND_SQUARE2_CTRL = 0; | 399 | SOUND_SQUARE2_CTRL = 0; |
352 | SOUND_WAVE_CTRL = 0; | 400 | SOUND_WAVE_CTRL = 0; |
353 | SOUND_NOISE_CTRL = 0; | 401 | SOUND_NOISE_CTRL = 0; |
402 | chain.playing = false; | ||
403 | if (current_pattern == next_pattern && chain.len > 0) { | ||
404 | chain.playing = true; | ||
405 | next_pattern = chain.chain[chain.current]; | ||
406 | current_pattern = next_pattern; | ||
407 | } | ||
354 | redraw_play_pause = true; | 408 | redraw_play_pause = true; |
355 | if (settings.sync == SYNC_IN_LINK) { | 409 | if (settings.sync == SYNC_IN_LINK) { |
356 | return; | 410 | return; |
@@ -530,23 +584,37 @@ handle_pattern_selection(void) { | |||
530 | } | 584 | } |
531 | } | 585 | } |
532 | if (slot > -1) { | 586 | if (slot > -1) { |
587 | if (chain.len == 0) { | ||
588 | chain.current = slot; | ||
589 | } | ||
533 | chain.chain[slot] = pattern_selection_loc; | 590 | chain.chain[slot] = pattern_selection_loc; |
534 | chain.active[slot] = 1; | 591 | chain.active[slot] = 1; |
535 | chain.len++; // TODO: remove | 592 | chain.len++; |
536 | } | 593 | } |
537 | } | 594 | } |
538 | if (key_tap(KEY_L)) { | 595 | if (key_tap(KEY_L)) { |
539 | // Find last active slot. | 596 | // Find last active slot. |
540 | s16 slot = -1; | 597 | s16 slot = -1; |
598 | bool update_current = false; | ||
541 | for (size_t i = 0; i < 16; i++) { | 599 | for (size_t i = 0; i < 16; i++) { |
542 | if (chain.active[15 - i] == 1) { | 600 | size_t idx = 15 - i; |
543 | slot = 15 - i; | 601 | if (chain.active[idx] == 1) { |
602 | // If the pattern is currently playing it can't be removed. | ||
603 | if (play_status && idx == chain.current) { | ||
604 | continue; | ||
605 | } else if (idx == chain.current) { | ||
606 | update_current = true; | ||
607 | } | ||
608 | slot = idx; | ||
544 | break; | 609 | break; |
545 | } | 610 | } |
546 | } | 611 | } |
547 | if (slot > -1) { | 612 | if (slot > -1) { |
548 | chain.active[slot] = 0; | 613 | chain.active[slot] = 0; |
549 | chain.len--; // TODO: remove | 614 | chain.len--; |
615 | if (update_current) { | ||
616 | chain.current = find_prev_pattern(); | ||
617 | } | ||
550 | } | 618 | } |
551 | } | 619 | } |
552 | } | 620 | } |