diff options
author | Bad Diode <bd@badd10de.dev> | 2023-04-24 19:13:03 +0200 |
---|---|---|
committer | Bad Diode <bd@badd10de.dev> | 2023-04-24 19:13:03 +0200 |
commit | 2abcb70459499dc5d729ec47b39bc43718ac6ced (patch) | |
tree | 242371a6479288d21db3f507c2ba53dc081506e5 | |
parent | ffdbbc90f042ba18697c78dfa3ab74640085a429 (diff) | |
download | stepper-2abcb70459499dc5d729ec47b39bc43718ac6ced.tar.gz stepper-2abcb70459499dc5d729ec47b39bc43718ac6ced.zip |
Add contextual drawing of piano notes
-rw-r--r-- | src/drawing.c | 59 | ||||
-rw-r--r-- | src/main.c | 16 | ||||
-rw-r--r-- | src/sequencer.c | 17 |
3 files changed, 66 insertions, 26 deletions
diff --git a/src/drawing.c b/src/drawing.c index 149aa19..3264ad8 100644 --- a/src/drawing.c +++ b/src/drawing.c | |||
@@ -11,6 +11,10 @@ draw_channel_sprite(size_t x, size_t y, u8 clr, u8 idx) { | |||
11 | 11 | ||
12 | void | 12 | void |
13 | draw_channels(void) { | 13 | draw_channels(void) { |
14 | // NOTE: Different channel colors can be interesting. | ||
15 | u8 colors[] = { | ||
16 | 1, 1, 1, 1, | ||
17 | }; | ||
14 | for (size_t i = 0; i < 4; i++) { | 18 | for (size_t i = 0; i < 4; i++) { |
15 | bool active = false; | 19 | bool active = false; |
16 | switch (i) { | 20 | switch (i) { |
@@ -19,7 +23,7 @@ draw_channels(void) { | |||
19 | case 2: { active = patterns[pattern_selection_loc].ch3.active; } break; | 23 | case 2: { active = patterns[pattern_selection_loc].ch3.active; } break; |
20 | case 3: { active = patterns[pattern_selection_loc].ch4.active; } break; | 24 | case 3: { active = patterns[pattern_selection_loc].ch4.active; } break; |
21 | } | 25 | } |
22 | u8 clr = active ? COL_FG : COL_GREY; | 26 | u8 clr = active ? colors[i] : COL_GREY; |
23 | size_t y = CHAN_START_Y + i * CHAN_OFFSET_Y; | 27 | size_t y = CHAN_START_Y + i * CHAN_OFFSET_Y; |
24 | draw_channel_sprite(CHAN_START_X, y, clr, i); | 28 | draw_channel_sprite(CHAN_START_X, y, clr, i); |
25 | } | 29 | } |
@@ -1107,3 +1111,56 @@ draw_cursors(void) { | |||
1107 | draw_params_cursor(param_selection_loc, COL_CURSOR); | 1111 | draw_params_cursor(param_selection_loc, COL_CURSOR); |
1108 | } | 1112 | } |
1109 | } | 1113 | } |
1114 | |||
1115 | TriggerNote * get_current_trig(void); | ||
1116 | |||
1117 | void | ||
1118 | draw_piano_notes(void) { | ||
1119 | draw_piano(); | ||
1120 | if (input_handler == handle_channel_selection) { | ||
1121 | // Show note on current channel only. | ||
1122 | Pattern *pat = &patterns[current_pattern]; | ||
1123 | u8 step = (step_counter - 1) % 16; | ||
1124 | switch (channel_selection_loc) { | ||
1125 | case 0: { | ||
1126 | if (pat->ch1.active && pat->ch1.notes[step].active) { | ||
1127 | draw_note(pat->ch1.notes[step].note, COL_NOTE_PRESSED); | ||
1128 | } | ||
1129 | } break; | ||
1130 | case 1: { | ||
1131 | if (pat->ch2.active && pat->ch2.notes[step].active) { | ||
1132 | draw_note(pat->ch2.notes[step].note, COL_NOTE_PRESSED); | ||
1133 | } | ||
1134 | } break; | ||
1135 | case 2: { | ||
1136 | if (pat->ch3.active && pat->ch3.notes[step].active) { | ||
1137 | draw_note(pat->ch3.notes[step].note, COL_NOTE_PRESSED); | ||
1138 | } | ||
1139 | } break; | ||
1140 | } | ||
1141 | |||
1142 | } else if (input_handler == handle_trigger_selection || | ||
1143 | input_handler == handle_param_selection_sq1 || | ||
1144 | input_handler == handle_param_selection_sq2 || | ||
1145 | input_handler == handle_param_selection_wave || | ||
1146 | input_handler == handle_param_selection_noise) { | ||
1147 | // Show currently selected trigger note. | ||
1148 | TriggerNote *trig = get_current_trig(); | ||
1149 | draw_note(trig->note, COL_NOTE_PRESSED); | ||
1150 | } else { | ||
1151 | // Show last/current played notes in all channels. | ||
1152 | if (play_status == 1) { | ||
1153 | Pattern *pat = &patterns[current_pattern]; | ||
1154 | u8 step = (step_counter - 1) % 16; | ||
1155 | if (pat->ch3.active && pat->ch3.notes[step].active) { | ||
1156 | draw_note(pat->ch3.notes[step].note, COL_NOTE_PRESSED); | ||
1157 | } | ||
1158 | if (pat->ch2.active && pat->ch2.notes[step].active) { | ||
1159 | draw_note(pat->ch2.notes[step].note, COL_NOTE_PRESSED); | ||
1160 | } | ||
1161 | if (pat->ch1.active && pat->ch1.notes[step].active) { | ||
1162 | draw_note(pat->ch1.notes[step].note, COL_NOTE_PRESSED); | ||
1163 | } | ||
1164 | } | ||
1165 | } | ||
1166 | } | ||
@@ -15,7 +15,7 @@ WITH REGARD TO THIS SOFTWARE. | |||
15 | // - Notification support for feedback when doing some operations | 15 | // - Notification support for feedback when doing some operations |
16 | // (copying/pasting) | 16 | // (copying/pasting) |
17 | // - Animations for cursor movement/current step highlight. (A fade out maybe?) | 17 | // - Animations for cursor movement/current step highlight. (A fade out maybe?) |
18 | // - Display played notes on all tonal channels when a trig or channel is not | 18 | // + Display played notes on all tonal channels when a trig or channel is not |
19 | // selected. If a channel is selected show active note in that channel, if | 19 | // selected. If a channel is selected show active note in that channel, if |
20 | // a trig is selected behaved as usual. These could be highlighted in | 20 | // a trig is selected behaved as usual. These could be highlighted in |
21 | // different colors to make it easier on the eyes. If a pattern is selected, | 21 | // different colors to make it easier on the eyes. If a pattern is selected, |
@@ -34,6 +34,7 @@ WITH REGARD TO THIS SOFTWARE. | |||
34 | // - Pattern chaining for more than 1 queue and/or song mode. | 34 | // - Pattern chaining for more than 1 queue and/or song mode. |
35 | // - Undo/Redo. | 35 | // - Undo/Redo. |
36 | // - Add a settings page to change some configuration parameters. | 36 | // - Add a settings page to change some configuration parameters. |
37 | // - Wrap around cursor left/right. | ||
37 | // | 38 | // |
38 | // Advanced | 39 | // Advanced |
39 | // - Sync via MIDI via arduinoboy or something similar. | 40 | // - Sync via MIDI via arduinoboy or something similar. |
@@ -85,18 +86,7 @@ render(void) { | |||
85 | redraw_play_pause = false; | 86 | redraw_play_pause = false; |
86 | } | 87 | } |
87 | if (redraw_piano_note) { | 88 | if (redraw_piano_note) { |
88 | PROF(draw_piano(), draw_piano_cycles); | 89 | PROF(draw_piano_notes(), draw_piano_cycles); |
89 | if (input_handler != handle_trigger_selection && | ||
90 | input_handler != handle_param_selection_sq1 && | ||
91 | input_handler != handle_param_selection_sq2 && | ||
92 | input_handler != handle_param_selection_wave && | ||
93 | input_handler != handle_param_selection_noise) { | ||
94 | // TODO: Show last/current played notes in all channels. | ||
95 | } else { | ||
96 | // Show currently selected trigger note. | ||
97 | TriggerNote *trig = get_current_trig(); | ||
98 | PROF(draw_note(trig->note, COL_NOTE_PRESSED), draw_piano_cycles); | ||
99 | } | ||
100 | redraw_piano_note = false; | 90 | redraw_piano_note = false; |
101 | } | 91 | } |
102 | if (redraw_params) { | 92 | if (redraw_params) { |
diff --git a/src/sequencer.c b/src/sequencer.c index 9c92ef0..1d5b3d6 100644 --- a/src/sequencer.c +++ b/src/sequencer.c | |||
@@ -136,6 +136,7 @@ play_step(void) { | |||
136 | SOUND_NOISE_FREQ = 0; | 136 | SOUND_NOISE_FREQ = 0; |
137 | } | 137 | } |
138 | step_counter = (step_counter + 1) % 16; | 138 | step_counter = (step_counter + 1) % 16; |
139 | redraw_piano_note = true; | ||
139 | } | 140 | } |
140 | 141 | ||
141 | void | 142 | void |
@@ -156,18 +157,10 @@ TriggerNote * | |||
156 | get_current_trig(void) { | 157 | get_current_trig(void) { |
157 | Pattern *pat = &patterns[pattern_selection_loc]; | 158 | Pattern *pat = &patterns[pattern_selection_loc]; |
158 | switch (channel_selection_loc) { | 159 | switch (channel_selection_loc) { |
159 | case 0: { | 160 | case 0: { return &pat->ch1.notes[trig_selection_loc]; } break; |
160 | return &pat->ch1.notes[trig_selection_loc]; | 161 | case 1: { return &pat->ch2.notes[trig_selection_loc]; } break; |
161 | } break; | 162 | case 2: { return &pat->ch3.notes[trig_selection_loc]; } break; |
162 | case 1: { | 163 | case 3: { return &pat->ch4.notes[trig_selection_loc]; } break; |
163 | return &pat->ch2.notes[trig_selection_loc]; | ||
164 | } break; | ||
165 | case 2: { | ||
166 | return &pat->ch3.notes[trig_selection_loc]; | ||
167 | } break; | ||
168 | case 3: { | ||
169 | return &pat->ch4.notes[trig_selection_loc]; | ||
170 | } break; | ||
171 | } | 164 | } |
172 | return NULL; | 165 | return NULL; |
173 | } | 166 | } |