From d1c68125b6825f0327a4089aa8ddca5105e78ec1 Mon Sep 17 00:00:00 2001 From: Bad Diode Date: Thu, 13 Jul 2023 10:21:12 +0200 Subject: Add initial pattern chain UI --- src/clipboard.c | 4 ++-- src/drawing.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++---- src/globals.c | 18 ++++++++++++++++++ src/main.c | 17 +++++++---------- src/sequencer.c | 29 +++++++++++++++++++++++++++++ 5 files changed, 106 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/clipboard.c b/src/clipboard.c index edb9b31..d82f576 100644 --- a/src/clipboard.c +++ b/src/clipboard.c @@ -21,6 +21,8 @@ typedef struct Clipboard { static Clipboard clipboard = {CLIP_EMPTY, 0, 0, 0}; +void send_notif(char *msg); + void clipboard_paste(void) { Pattern *pat_dst = &patterns[pattern_selection_loc]; @@ -408,8 +410,6 @@ clipboard_paste(void) { } } -void send_notif(char *msg); - void clipboard_copy(void) { if (input_handler == handle_trigger_selection) { diff --git a/src/drawing.c b/src/drawing.c index 18504bc..dff5db2 100644 --- a/src/drawing.c +++ b/src/drawing.c @@ -1251,7 +1251,7 @@ draw_notif_bar() { if (notif.time > 0) { char msg[32] = {0}; if (notif.time <= 32) { - for (size_t i = 0; i < notif.time; i++) { + for (s16 i = 0; i < notif.time; i++) { msg[i] = notif.msg[i + 32 - notif.time]; } } else { @@ -1295,10 +1295,56 @@ draw_notif_bar() { return; } - if (play_status == 0) { - txt_drawf_small("STOPPED", x0 + 2, y0 + 1, color); + if (chain.len != 0) { + char msg[64] = {0}; + char *ptr = msg; + *ptr++ = 'c'; + *ptr++ = 'h'; + *ptr++ = 'a'; + *ptr++ = 'i'; + *ptr++ = 'n'; + *ptr++ = ':'; + *ptr++ = ' '; + for (size_t i = 0; i < chain.len; i++) { + if (i != 0) { + *ptr++ = '-'; + } + *ptr++ = 'A' + chain.chain[i]; + } + *ptr++ = '\0'; + txt_drawf_small(msg, x0 + 2, y0 + 1, color); } else { - txt_drawf_small("PLAYING", x0 + 2, y0 + 1, color); + if (play_status == 0) { + txt_drawf_small("STOPPED", x0 + 2, y0 + 1, color); + } else { + txt_drawf_small("PLAYING", x0 + 2, y0 + 1, color); + } + } + } +} + +void +draw_pattern_chain() { + clear_parameters(); + for (size_t i = 0; i < 16; i++) { + u8 color = COL_FG; + size_t offset_x = PAT_TRIG_OFFSET_X * (i % 8); + size_t offset_y = i < 8 ? 0 : 0 + PAT_TRIG_OFFSET_Y; + size_t x0 = PAT_TRIG_START_X + offset_x; + size_t x1 = PAT_TRIG_START_X + offset_x + PAT_TRIG_W; + size_t y0 = PAT_TRIG_START_Y + offset_y; + size_t y1 = PAT_TRIG_START_Y + offset_y + PAT_TRIG_H; + draw_rect(x0, y0, x1, y1, color); + if (chain.active[i]) { + txt_drawc('A' + chain.chain[i], x0 + 4, y0 + 3, color); } } + // 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 c2e2ee2..3a70005 100644 --- a/src/globals.c +++ b/src/globals.c @@ -80,6 +80,13 @@ bool clear_screen = true; #define BANK_START_X (R_SIDEBAR_X + 5) #define BANK_START_Y (PAT_START_Y) +#define PAT_TRIG_W 14 +#define PAT_TRIG_H 14 +#define PAT_TRIG_START_X 35 +#define PAT_TRIG_START_Y 29 +#define PAT_TRIG_OFFSET_X (PAT_TRIG_W + 7) +#define PAT_TRIG_OFFSET_Y (PAT_TRIG_H + 8) + #define SEQ_N_CHANNELS 4 enum RIGHT_COL_LOC { @@ -131,3 +138,14 @@ typedef struct Notification { static Notification notif = {0}; #define NOTIF_TIME (80 + 32) + +#define MAX_CHAIN 16 +typedef struct Chain { + u8 chain[MAX_CHAIN]; + u8 active[MAX_CHAIN]; + u8 len; + u8 loop; + u8 current; +} Chain; + +static Chain chain = {0}; diff --git a/src/main.c b/src/main.c index 54d46e6..2f073c7 100644 --- a/src/main.c +++ b/src/main.c @@ -92,17 +92,14 @@ render_sequencer(void) { if (redraw_params) { PROF(draw_parameters(), draw_param_cycles); redraw_params = false; - } else if (input_handler == handle_pattern_selection){ - // DEBUG: move to drawing file - 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"); } + + if (input_handler == handle_pattern_selection){ + // TODO: redraw_params in pattern_selection context? + draw_pattern_chain(); + } + + // TODO: redraw_notif? draw_notif_bar(); PROF(draw_cursors(), draw_cursor_cycles); } diff --git a/src/sequencer.c b/src/sequencer.c index 5b70bb2..44ff90e 100644 --- a/src/sequencer.c +++ b/src/sequencer.c @@ -520,6 +520,35 @@ handle_pattern_selection(void) { default: { right_col_selection_loc = R_COL_BPM; } break; } } + if (key_tap(KEY_R)) { + // Find next empty slot. + s16 slot = -1; + for (size_t i = 0; i < 16; i++) { + if (chain.active[i] == 0) { + slot = i; + break; + } + } + if (slot > -1) { + chain.chain[slot] = pattern_selection_loc; + chain.active[slot] = 1; + chain.len++; // TODO: remove + } + } + if (key_tap(KEY_L)) { + // Find last active slot. + s16 slot = -1; + for (size_t i = 0; i < 16; i++) { + if (chain.active[15 - i] == 1) { + slot = 15 - i; + break; + } + } + if (slot > -1) { + chain.active[slot] = 0; + chain.len--; // TODO: remove + } + } } bool -- cgit v1.2.1