From 7f57051c51c16c88e5dcaa7bd51ccaec31469c4a Mon Sep 17 00:00:00 2001 From: Bad Diode Date: Thu, 13 Jul 2023 12:00:11 +0200 Subject: Add working pattern chaining prototype --- src/drawing.c | 20 +++++++-------- src/globals.c | 4 ++- src/sequencer.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 85 insertions(+), 15 deletions(-) (limited to 'src') 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() { *ptr++ = 'n'; *ptr++ = ':'; *ptr++ = ' '; - for (size_t i = 0; i < chain.len; i++) { - if (i != 0) { + bool first = true; + for (size_t i = 0; i < MAX_CHAIN; i++) { + if (chain.active[i] != 1) { + continue; + } + if (!first) { *ptr++ = '-'; } *ptr++ = 'A' + chain.chain[i]; + first = false; } *ptr++ = '\0'; txt_drawf_small(msg, x0 + 2, y0 + 1, color); @@ -1338,13 +1343,8 @@ draw_pattern_chain() { if (chain.active[i]) { txt_drawc('A' + chain.chain[i], x0 + 4, y0 + 3, color); } + if (chain.current == i && chain.len != 0) { + draw_line(x0 + 5, y1 - 2, x1 - 5, y1 - 2, COL_ACC_0); + } } - // draw_rect( - // PARAMS_START_X, - // PARAMS_START_Y + 6, - // PARAMS_START_X + PARAMS_W, - // PARAMS_START_Y + PARAMS_H - 6, COL_FG); - // txt_drawf_small("Current pattern: %s", PARAMS_START_X + 3, PARAMS_START_Y + 8, COL_FG, "A"); - // txt_drawf_small("Next pattern: %s", PARAMS_START_X + 3, PARAMS_START_Y + 8 * 2, COL_FG, "A"); - // txt_drawf_small("Chain: %s", PARAMS_START_X + 3, PARAMS_START_Y + 8 * 3, COL_FG, "A - B - B - A - B"); } 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 { u8 chain[MAX_CHAIN]; u8 active[MAX_CHAIN]; u8 len; - u8 loop; u8 current; + u8 playing; } Chain; +// DEBUG:... +// 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}; 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) { TIMER_CTRL_3 = TIMER_CTRL_IRQ | TIMER_CTRL_ENABLE | TIMER_CTRL_FREQ_3; } +u8 +find_next_pattern(void) { + u8 idx = (chain.current + 1) % 16; + for (size_t i = 0; i < MAX_CHAIN; i++) { + if (chain.active[idx] == 1) { + break; + } + idx = (idx + 1) % 16; + } + return idx; +} + +u8 +find_prev_pattern(void) { + u8 idx = chain.current == 0 ? 15 : (chain.current - 1); + for (size_t i = 0; i < MAX_CHAIN; i++) { + if (chain.active[idx] == 1) { + break; + } + idx = chain.current == 0 ? 15 : (chain.current - 1); + } + return idx; +} + void play_step(void) { Pattern *pat = &patterns[current_pattern]; @@ -54,6 +78,18 @@ play_step(void) { current_pattern = next_pattern; redraw_pattern_buttons = true; update_bpm = true; + } else if (chain.len != 0 && step_counter == 15) { + redraw_pattern_buttons = true; + update_bpm = true; + if (!chain.playing) { + next_pattern = chain.chain[chain.current]; + current_pattern = next_pattern; + } else { + chain.current = find_next_pattern(); + next_pattern = chain.chain[chain.current]; + current_pattern = next_pattern; + } + chain.playing = true; } if (pat->ch1.active) { TriggerNote *trig = &pat->ch1.notes[step_counter]; @@ -316,6 +352,9 @@ stop_sound(void) { void stop_playing(void) { step_counter = 0; + chain.current = 15; + chain.current = find_next_pattern(); + chain.playing = false; stop_sound(); } @@ -323,6 +362,15 @@ void toggle_playing(void) { play_status ^= 1; step_counter = 0; + chain.current = 15; + chain.current = find_next_pattern(); + chain.playing = false; + if (current_pattern == next_pattern && chain.len > 0) { + chain.playing = true; + next_pattern = chain.chain[chain.current]; + current_pattern = next_pattern; + } + redraw_pattern_buttons = true; SOUND_SQUARE1_CTRL = 0; SOUND_SQUARE2_CTRL = 0; SOUND_WAVE_CTRL = 0; @@ -351,6 +399,12 @@ pause_playing(void) { SOUND_SQUARE2_CTRL = 0; SOUND_WAVE_CTRL = 0; SOUND_NOISE_CTRL = 0; + chain.playing = false; + if (current_pattern == next_pattern && chain.len > 0) { + chain.playing = true; + next_pattern = chain.chain[chain.current]; + current_pattern = next_pattern; + } redraw_play_pause = true; if (settings.sync == SYNC_IN_LINK) { return; @@ -530,23 +584,37 @@ handle_pattern_selection(void) { } } if (slot > -1) { + if (chain.len == 0) { + chain.current = slot; + } chain.chain[slot] = pattern_selection_loc; chain.active[slot] = 1; - chain.len++; // TODO: remove + chain.len++; } } if (key_tap(KEY_L)) { // Find last active slot. s16 slot = -1; + bool update_current = false; for (size_t i = 0; i < 16; i++) { - if (chain.active[15 - i] == 1) { - slot = 15 - i; + size_t idx = 15 - i; + if (chain.active[idx] == 1) { + // If the pattern is currently playing it can't be removed. + if (play_status && idx == chain.current) { + continue; + } else if (idx == chain.current) { + update_current = true; + } + slot = idx; break; } } if (slot > -1) { chain.active[slot] = 0; - chain.len--; // TODO: remove + chain.len--; + if (update_current) { + chain.current = find_prev_pattern(); + } } } } -- cgit v1.2.1