From 3caf8f1e040c9d186fddc3039e5e4e8dcf5c9d0f Mon Sep 17 00:00:00 2001 From: Bad Diode Date: Fri, 11 Jun 2021 14:41:55 +0200 Subject: Add prototype for CH3 parameter drawing --- src/sequencer.c | 138 ++++++++++++++++++++++++++++++++++++++++++++++++-------- src/text/text.h | 20 ++++++++ 2 files changed, 139 insertions(+), 19 deletions(-) diff --git a/src/sequencer.c b/src/sequencer.c index d31475e..0c2f2a5 100644 --- a/src/sequencer.c +++ b/src/sequencer.c @@ -105,30 +105,27 @@ static const u32 channel_buttons[] = { 0x0f080808, 0x0808080f, }; +static const u32 default_wave_buttons[] = { + 0xff013149, 0x850101ff, 0x3f202028, 0x2423203f, + 0xff016151, 0x49c501ff, 0x3f202c2a, 0x2928203f, + 0xff017d45, 0x45c501ff, 0x3f202828, 0x282f203f, + 0xff014911, 0x812501ff, 0x3f202128, 0x2420203f, +}; + // // Wave data. // -// TODO: Make them u32. -static const u8 sine_wave[16] = { - 0x89, 0xBC, 0xDE, 0xEF, - 0xFE, 0xED, 0xCB, 0x98, - 0x76, 0x43, 0x21, 0x10, - 0x01, 0x12, 0x34, 0x67, +static const u32 sine_wave[16] = { + 0xefdebc89, 0x98cbedfe, 0x10214376, 0x67341201, }; -static const u8 saw_wave[16] = { - 0x01, 0x23, 0x45, 0x67, - 0x89, 0xab, 0xcd, 0xef, - 0x01, 0x23, 0x45, 0x67, - 0x89, 0xab, 0xcd, 0xef, +static const u32 saw_wave[16] = { + 0x67452301, 0xefcdab89, 0x67452301, 0xefcdab89, }; -static const u8 square_wave[16] = { - 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, +static const u32 square_wave[16] = { + 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, }; // @@ -276,10 +273,10 @@ static ChannelWave ch3 = { }, .params = { {3, 0, {0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000},{0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000}}, + {3, 0, {0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000},{0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000}}, {3, 0, {0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000},{0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000}}, - {3, 0, {0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000},{0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000}}, - {3, 0, {0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000},{0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000}}, - {3, 0, {0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000},{0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000}}, + {3, 0, {0x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF},{0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000}}, + {3, 0, {0x00000000, 0x00000000, 0xFFFFFFFF, 0x00000000},{0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000}}, {3, 0, {0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000},{0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000}}, {3, 0, {0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000},{0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000}}, {3, 0, {0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000},{0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000}}, @@ -558,6 +555,103 @@ draw_piano(void) { } } +#define PARAMS_W 170 +#define PARAMS_H 48 +#define PARAMS_START_X 35 +#define PARAMS_START_Y 12 + +IWRAM_CODE +void +draw_wave_pattern(u8 *pattern, int x, int y, u8 clr) { + for (size_t i = 0; i < 16; ++i) { + u8 byte = pattern[i]; + u8 first = (byte >> 4) & 0xF; + u8 second = byte & 0xF; + u8 a = x + i * 4; + u8 b = y + 16; + draw_pixel(a, b - first, clr); + draw_pixel(a + 1, b - first, clr); + draw_pixel(a + 2, b - second, clr); + draw_pixel(a + 3, b - second, clr); + } +} + +IWRAM_CODE +void +clear_parameters(void) { + size_t x0 = PARAMS_START_X; + size_t y0 = PARAMS_START_Y; + size_t x1 = PARAMS_START_X + PARAMS_W; + size_t y1 = PARAMS_START_Y + PARAMS_H; + draw_filled_rect(x0, y0, x1, y1, COL_BG); +} + +IWRAM_CODE +void +draw_parameters(void) { + // Clear until the default parameters, since those don't change. + { + size_t x0 = PARAMS_START_X; + size_t y0 = PARAMS_START_Y; + size_t x1 = PARAMS_START_X + PARAMS_W; + size_t y1 = PARAMS_START_Y + PARAMS_H - 8; + draw_filled_rect(x0, y0, x1, y1, COL_BG); + } + + // TODO: Move to VRAM and decompress at the beginning. + Tile wave_tiles[4 * 2] = {0}; + unpack_tiles(default_wave_buttons, wave_tiles, 4 * 2); + + // Draw current wave data. + { + u8 *wave_a = ch3.params[trig_selection_loc].wave_a; + u8 *wave_b = ch3.params[trig_selection_loc].wave_b; + + size_t x = PARAMS_START_X; + size_t y = PARAMS_START_Y + 2; + + // Wave Patterns. + draw_wave_pattern(wave_a, x, y, COL_RED); + draw_wave_pattern(wave_b, x + 70, y, COL_CYAN); + + // Wave text. + x -= 2; + txt_drawf_small("%02x%02x%02x%02x", x, y + 20, 4, COL_FG, + wave_a[0], wave_a[1], wave_a[2], wave_a[3]); + txt_drawf_small("%02x%02x%02x%02x", x + 34, y + 20, 4, COL_FG, + wave_a[4], wave_a[5], wave_a[6], wave_a[7]); + txt_drawf_small("%02x%02x%02x%02x", x, y + 28, 4, COL_FG, + wave_a[8], wave_a[9], wave_a[10], wave_a[11]); + txt_drawf_small("%02x%02x%02x%02x", x + 34, y + 28, 4, COL_FG, + wave_a[12], wave_a[13], wave_a[14], wave_a[15]); + + x += 70; + txt_drawf_small("%02x%02x%02x%02x", x, y + 20, 4, COL_FG, + wave_b[0], wave_b[1], wave_b[2], wave_b[3]); + txt_drawf_small("%02x%02x%02x%02x", x + 34, y + 20, 4, COL_FG, + wave_b[4], wave_b[5], wave_b[6], wave_b[7]); + txt_drawf_small("%02x%02x%02x%02x", x, y + 28, 4, COL_FG, + wave_b[8], wave_b[9], wave_b[10], wave_b[11]); + txt_drawf_small("%02x%02x%02x%02x", x + 34, y + 28, 4, COL_FG, + wave_b[12], wave_b[13], wave_b[14], wave_b[15]); + } + + // Draw default wave buttons. + { + size_t x = PARAMS_START_X; + size_t y = PARAMS_START_Y + PARAMS_H - 7; + for (size_t i = 0, k = 0; i < 4 * 2; i += 2, k++) { + draw_tile(x + 17 * k, y, wave_tiles + i, COL_FG, true); + draw_tile(x + 17 * k + 8, y, wave_tiles + i + 1, COL_FG, true); + } + for (size_t i = 0, k = 0; i < 4 * 2; i += 2, k++) { + draw_tile(x + 17 * k + 70, y, wave_tiles + i, COL_FG, true); + draw_tile(x + 17 * k + 8 + 70, y, wave_tiles + i + 1, COL_FG, true); + } + } + +} + void irq_timer(void) { if (ch1.active) { @@ -721,6 +815,7 @@ handle_channel_selection(void) { draw_trig_cursor(trig_selection_loc, COL_BLUE); TriggerNote *trig = get_current_trig(); draw_note(trig->note, COL_BLUE); + draw_parameters(); } else if (key_tap(KEY_UP)) { draw_channel_cursor(channel_selection_loc, COL_BG); if (channel_selection_loc == 0) { @@ -1043,6 +1138,7 @@ handle_trigger_selection(void) { draw_note(trig->note, COL_FG); input_handler = handle_channel_selection; draw_channel_cursor(channel_selection_loc, COL_BLUE); + clear_parameters(); } else { draw_trig_cursor(trig_selection_loc, COL_BG); draw_note(trig->note, COL_FG); @@ -1050,6 +1146,7 @@ handle_trigger_selection(void) { trig = get_current_trig(); draw_trig_cursor(trig_selection_loc, COL_BLUE); draw_note(trig->note, COL_BLUE); + draw_parameters(); } } else if (key_tap(KEY_RIGHT)) { if (trig_selection_loc != 7) { @@ -1059,6 +1156,7 @@ handle_trigger_selection(void) { trig = get_current_trig(); draw_trig_cursor(trig_selection_loc, COL_BLUE); draw_note(trig->note, COL_BLUE); + draw_parameters(); } } else if (key_tap(KEY_UP) || key_tap(KEY_DOWN)) { draw_trig_cursor(trig_selection_loc, COL_BG); @@ -1067,6 +1165,7 @@ handle_trigger_selection(void) { trig = get_current_trig(); draw_trig_cursor(trig_selection_loc, COL_BLUE); draw_note(trig->note, COL_BLUE); + draw_parameters(); } else if (key_tap(KEY_A)) { // Switch to parameter selection. switch (channel_selection_loc) { @@ -1126,6 +1225,7 @@ sequencer_init(void) { draw_piano(); TriggerNote *trig = get_current_trig(); draw_note(trig->note, COL_BLUE); + draw_parameters(); // Initialize input handler. channel_selection_loc = 2; // DEBUG: Starting on CH3 diff --git a/src/text/text.h b/src/text/text.h index 931227c..647a021 100644 --- a/src/text/text.h +++ b/src/text/text.h @@ -136,4 +136,24 @@ txt_draws(char *msg, size_t x, size_t y, size_t spacing, u8 clr) { txt_draws(buf, x, y, s, c); \ } +// Small font is located after the initial ASCII characters, and only supports +// lowercase characters. +// NOTE: Slow, we should do this with a LUT. +#define txt_drawf_small(msg, x, y, s, c, ...) \ + { \ + char buf[256] = {0}; \ + posprintf(buf, msg, ##__VA_ARGS__); \ + for (size_t i = 0; i < 256; i++) { \ + if (buf[i] == 0) { \ + break; \ + } \ + if (buf[i] < 'a') { \ + buf[i] += 16 * 6; \ + } else { \ + buf[i] += 16 * 4; \ + }\ + } \ + txt_draws(buf, x, y, s, c); \ + } + #endif // TEXT_H -- cgit v1.2.1