From cf9912cd61c9499fc60a839042fcae1ac556e044 Mon Sep 17 00:00:00 2001 From: Bad Diode Date: Thu, 24 Aug 2023 18:38:46 +0200 Subject: Add visual feedback and control for scale roots --- src/drawing.c | 60 ++++++++++++++++++++++++++++++++++++++++++--------------- src/main.c | 20 ++++++++----------- src/scale.c | 2 +- src/sequencer.c | 40 ++++++++++++++++++-------------------- 4 files changed, 73 insertions(+), 49 deletions(-) (limited to 'src') diff --git a/src/drawing.c b/src/drawing.c index a432285..f3115c5 100644 --- a/src/drawing.c +++ b/src/drawing.c @@ -393,12 +393,16 @@ draw_bpm() { draw_rect(x, y, x + R_COL_W - 2, y + BPM_H - 3, COL_FG); txt_drawf_small("BPM", x + 7, y - 10, COL_FG); - // Make sure its horizontally centered if only 2 digits - int bpm = patterns[pattern_selection_loc].bpm; - if (bpm >= 100) { - txt_drawf("%d", x + 5, y + 2, COL_FG, bpm); + if (settings.sync == SYNC_IN_LINK) { + txt_drawf("SYNC", x + 2, y + 2, COL_FG); } else { - txt_drawf("%d", x + 8, y + 2, COL_FG, bpm); + // Make sure its horizontally centered if only 2 digits + int bpm = patterns[pattern_selection_loc].bpm; + if (bpm >= 100) { + txt_drawf("%d", x + 5, y + 2, COL_FG, bpm); + } else { + txt_drawf("%d", x + 8, y + 2, COL_FG, bpm); + } } } @@ -531,16 +535,18 @@ draw_note(u8 note, u8 clr) { draw_filled_rect(x0, y0, x1, y1, clr); } break; default: { - if (clr == COL_FG) { - clr = COL_BG; - } + // NOTE: Decide if this looks better or nah. Also, not the right + // place for it... + // if (clr == COL_FG) { + // clr = COL_BG; + // } y0 = base_y0; y1 = base_y1 + PIANO_BLACK_H - 2; switch (value) { - case 1: { x0 = base_x + octave * 28 + 3; } break; - case 3: { x0 = base_x + octave * 28 + 7; } break; - case 6: { x0 = base_x + octave * 28 + 15; } break; - case 8: { x0 = base_x + octave * 28 + 19; } break; + case 1: { x0 = base_x + octave * 28 + 3; } break; + case 3: { x0 = base_x + octave * 28 + 7; } break; + case 6: { x0 = base_x + octave * 28 + 15; } break; + case 8: { x0 = base_x + octave * 28 + 19; } break; case 10: { x0 = base_x + octave * 28 + 23; } break; } x1 = x0; @@ -557,7 +563,24 @@ draw_piano(void) { size_t y1 = PIANO_START_Y + PIANO_H; draw_rect(x0, y0, x1, y1, COL_FG); for (size_t i = 0; i < 12 * 6; i++) { - draw_note(i, COL_FG); + u8 clr = COL_FG; + if (input_handler == handle_right_col_selection && + right_col_selection_loc == R_COL_SCALE) { + s8 pos = i % 12; + if (pos == current_scale_root) { + clr = COL_ACC_1; + } else { + s8 scale_pos = (pos - current_scale_root) % 12; + if (scale_pos < 0) { + scale_pos *= -1; + scale_pos = 12 - scale_pos; + } + if (scales[current_scale][scale_pos] == 1) { + clr = COL_ACC_0; + } + } + } + draw_note(i, clr); } } @@ -1314,7 +1337,9 @@ draw_piano_notes(void) { // Show last/current played notes in all channels. if (play_status == 1) { Pattern *pat = &patterns[current_pattern]; - if (pat->empty || play_status == 0) { + if (pat->empty || + play_status == 0 || + input_handler == handle_right_col_selection) { return; } u8 step = step_counter % 16; @@ -1681,7 +1706,12 @@ draw_notif_bar() { txt_drawf_small("SETTINGS", x0 + 2, y0 + 1, color); } break; case R_COL_SCALE: { - txt_drawf_small("SCALE: %s", x0 + 2, y0 + 1, color, scale_long[current_scale]); + const char *roots[12] = { + "C ", "C#", "D ", "D#", "E ", "F ", + "F#", "G ", "G#", "A ", "A#", "B ", + }; + txt_drawf_small("ROOT: %s SCALE: %s", x0 + 2, y0 + 1, color, + roots[current_scale_root], scale_long[current_scale]); } break; case R_COL_BPM: { txt_drawf_small("TEMPO: %d bpm", x0 + 2, y0 + 1, color, patterns[pattern_selection_loc].bpm); diff --git a/src/main.c b/src/main.c index e3c60f8..c424d9c 100644 --- a/src/main.c +++ b/src/main.c @@ -36,6 +36,7 @@ WITH REGARD TO THIS SOFTWARE. // - Per-channel N steps to create polymeters? // - Channel params should show if there are some already on all triggers and // modify only the selected parameter, not all of them. +// - Should scale mode be toggleable? // // WIP (1.7) // + Improve "grey" cursor with dithering instead. @@ -52,20 +53,20 @@ WITH REGARD TO THIS SOFTWARE. // + Fix stop button behaviour. // + Scale mode for entering notes. // + Make sure bank switching is queued like patterns. -// - Should scale mode be toggleable? +// + If we are on sync in, BPM should display SYNC +// + Visual feedback for scale/root note adjustment. // - Shortcut to quickly exit/enter chain mode. -// - If we are on sync in, BPM should display SYNC +// - Add CREDITS to the documentation for now, should probably be a menu item +// later. +// - Settings page overhaul. +// - Remove thin cursor option and make the fat one default, it's just better. // // - Improve SRAM saving to make room for longer patterns and/or more banks. // - Higher resolution clock to allow for microtiming and more accurate tempo. // - Add settings for "performance mode" in which banks are not saved by // default while changing patterns. // - Make sure sync works with the same cable for in/out. -// - Remove thin cursor option and make the fat one default, it's just better. -// - Settings page overhaul. // - Study more improvements for a "performance mode". -// - Add CREDITS to the documentation for now, should probably be a menu item -// later. #include "gba/gba.h" @@ -111,10 +112,6 @@ render_sequencer(void) { PROF(draw_scale(), draw_btn_cycles); redraw_scale = false; } - if (redraw_piano_note) { - PROF(draw_piano_notes(), draw_piano_cycles); - redraw_piano_note = false; - } if (redraw_params) { PROF(draw_parameters(), draw_param_cycles); redraw_params = false; @@ -125,8 +122,8 @@ render_sequencer(void) { draw_pattern_chain(); } - // TODO: redraw_notif? draw_notif_bar(); + PROF(draw_piano_notes(), draw_piano_cycles); PROF(draw_cursors(), draw_cursor_cycles); } @@ -184,7 +181,6 @@ update(void) { redraw_bank_buttons = true; redraw_bpm = true; redraw_play_pause = true; - redraw_piano_note = true; redraw_params = true; redraw_scale = true; } diff --git a/src/scale.c b/src/scale.c index 7704815..197959e 100644 --- a/src/scale.c +++ b/src/scale.c @@ -88,7 +88,7 @@ scale_note(s32 current, s32 inc) { s32 pos = current % 12; s32 offset = 0; for (int i = 1; i <= 12; i++) { - s32 k = (current_scale_root + pos + i * inc) % 12; + s32 k = (pos - current_scale_root + i * inc) % 12; if (k < 0) { k *= -1; k = 12 - k; diff --git a/src/sequencer.c b/src/sequencer.c index 3635657..f3dff04 100644 --- a/src/sequencer.c +++ b/src/sequencer.c @@ -15,7 +15,6 @@ bool redraw_channels = true; bool redraw_bank_buttons = true; bool redraw_params = true; bool redraw_bpm = true; -bool redraw_piano_note = true; bool redraw_scale = true; bool update_bpm = false; u8 bar_counter = 0; @@ -352,7 +351,6 @@ play_step(void) { bar_counter++; } step_counter = (step_counter + 1) % 16; - redraw_piano_note = true; } void @@ -457,7 +455,6 @@ handle_channel_selection(void) { trig_selection_loc = 0; param_selection_loc = 0; input_handler = handle_trigger_selection; - redraw_piano_note = true; redraw_params = true; } else if (key_tap(KEY_LEFT)) { input_handler = handle_pattern_selection; @@ -503,7 +500,6 @@ stop_sound(void) { SOUND_NOISE_CTRL = 0; redraw_play_pause = true; redraw_pattern_buttons = true; - redraw_piano_note = true; } void @@ -544,7 +540,6 @@ toggle_playing(void) { SOUND_NOISE_CTRL = 0; redraw_play_pause = true; redraw_pattern_buttons = true; - redraw_piano_note = true; if (settings.sync == SYNC_IN_LINK) { return; } @@ -685,12 +680,18 @@ handle_right_col_selection(void) { } } break; case R_COL_SCALE: { - current_scale--; - if (current_scale < 0) { - current_scale = SCALE_NUM - 1; + if (key_hold(KEY_SELECT)) { + current_scale_root--; + if (current_scale_root < 0) { + current_scale_root = 11; + } + } else { + current_scale--; + if (current_scale < 0) { + current_scale = SCALE_NUM - 1; + } + redraw_scale = true; } - // TODO: add root note change & keyboard viz. - redraw_scale = true; } break; } } else if (key_tap(KEY_R)) { @@ -714,11 +715,15 @@ handle_right_col_selection(void) { } } break; case R_COL_SCALE: { - current_scale++; - if (current_scale >= SCALE_NUM) { - current_scale = 0; + if (key_hold(KEY_SELECT)) { + current_scale_root = (current_scale_root + 1) % 12; + } else { + current_scale++; + if (current_scale >= SCALE_NUM) { + current_scale = 0; + } + redraw_scale = true; } - redraw_scale = true; } break; } } else if (key_tap(KEY_B)) { @@ -1293,7 +1298,6 @@ handle_trigger_selection(void) { } trig->active ^= 1; redraw_trigs = true; - redraw_piano_note = true; } } else if (key_tap(KEY_L)) { s32 inc = -1; @@ -1305,7 +1309,6 @@ handle_trigger_selection(void) { trig->note = scale_note(trig->note, inc); } redraw_trigs = true; - redraw_piano_note = true; } else if (key_tap(KEY_R)) { s32 inc = 1; if (key_hold(KEY_SELECT)) { @@ -1316,7 +1319,6 @@ handle_trigger_selection(void) { trig->note = scale_note(trig->note, inc); } redraw_trigs = true; - redraw_piano_note = true; } // Move trigger cursor. @@ -1328,7 +1330,6 @@ handle_trigger_selection(void) { trig_selection_loc = MAX(trig_selection_loc - 1, 0); } redraw_params = true; - redraw_piano_note = true; } else if (key_tap(KEY_RIGHT)) { if (trig_selection_loc != 7 && trig_selection_loc != 15) { trig_selection_loc = MIN(trig_selection_loc + 1, 15); @@ -1340,11 +1341,9 @@ handle_trigger_selection(void) { input_handler = handle_right_col_selection; } redraw_params = true; - redraw_piano_note = true; } else if (key_tap(KEY_UP) || key_tap(KEY_DOWN)) { trig_selection_loc = (trig_selection_loc + 8) % 16; redraw_params = true; - redraw_piano_note = true; } else if (key_tap(KEY_A)) { if (key_hold(KEY_SELECT)) { if (patterns[pattern_selection_loc].empty) { @@ -1364,7 +1363,6 @@ handle_trigger_selection(void) { case 3: { input_handler = handle_param_selection_noise; } break; } redraw_params = true; - redraw_piano_note = true; } } } -- cgit v1.2.1