diff options
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | src/drawing.c | 77 | ||||
-rw-r--r-- | src/globals.c | 55 | ||||
-rw-r--r-- | src/main.c | 38 |
4 files changed, 102 insertions, 70 deletions
@@ -27,7 +27,7 @@ INC_FLAGS := $(addprefix -I,$(INC_DIRS)) | |||
27 | INC_FLAGS += -I$(LIBGBA_SRC) | 27 | INC_FLAGS += -I$(LIBGBA_SRC) |
28 | 28 | ||
29 | # Output library names and executables. | 29 | # Output library names and executables. |
30 | TARGET := STEPPER-v1.6 | 30 | TARGET := STEPPER-v1.7-dev |
31 | ELF := $(BUILD_DIR)/$(TARGET).elf | 31 | ELF := $(BUILD_DIR)/$(TARGET).elf |
32 | BIN := $(BUILD_DIR)/$(TARGET).gba | 32 | BIN := $(BUILD_DIR)/$(TARGET).gba |
33 | 33 | ||
diff --git a/src/drawing.c b/src/drawing.c index a203f1c..c07b46d 100644 --- a/src/drawing.c +++ b/src/drawing.c | |||
@@ -126,6 +126,8 @@ draw_trig_cursor(size_t i, u8 clr) { | |||
126 | 126 | ||
127 | void | 127 | void |
128 | draw_right_col_cursor(int i, u8 clr) { | 128 | draw_right_col_cursor(int i, u8 clr) { |
129 | // TODO:... | ||
130 | return; | ||
129 | size_t x0 = 0; | 131 | size_t x0 = 0; |
130 | size_t x1 = 0; | 132 | size_t x1 = 0; |
131 | size_t y = 0; | 133 | size_t y = 0; |
@@ -192,21 +194,29 @@ draw_current_step(u8 step, u8 clr) { | |||
192 | 194 | ||
193 | void | 195 | void |
194 | draw_bank_buttons() { | 196 | draw_bank_buttons() { |
195 | size_t x = BANK_START_X; | 197 | size_t x = BANK_START_X + 1; |
196 | size_t y = BANK_START_Y; | 198 | size_t y = BANK_START_Y; |
197 | txt_drawf_small("BANK", x - 2, y - 10, COL_FG); | 199 | txt_drawf_small("BANK", x - 3, y - 10, COL_FG); |
198 | char bank_names[] = { | 200 | char bank_names[] = { |
199 | 'A', 'B', 'C', 'D', | 201 | 'A', 'B', 'C', 'D', 'E', 'F' |
202 | }; | ||
203 | s16 x_offset[] = { | ||
204 | -8, 8, -8, 8, -8, 8, | ||
205 | }; | ||
206 | size_t y_offset[] = { | ||
207 | 0, 0, 18, 18, 36, 36, | ||
200 | }; | 208 | }; |
201 | for (int i = 0; i < 4; i++) { | 209 | for (int i = 0; i < 6; i++) { |
202 | int color = COL_OFF; | 210 | int color = COL_OFF; |
203 | if (i == current_bank) { | 211 | if (i == current_bank) { |
204 | color = COL_FG; | 212 | color = COL_FG; |
205 | } | 213 | } |
206 | draw_filled_rect(x, y, x + PAT_W, y + PAT_H, COL_BG); | 214 | u8 x0 = x + x_offset[i]; |
207 | draw_rect(x, y, x + PAT_W, y + PAT_H, color); | 215 | u8 x1 = x + x_offset[i] + BANK_W; |
208 | txt_drawc(bank_names[i], x + 4, y + 1, color); | 216 | u8 y0 = y + y_offset[i]; |
209 | y += PAT_OFFSET_Y; | 217 | u8 y1 = y + y_offset[i] + BANK_H; |
218 | draw_rect(x0, y0, x1, y1, color); | ||
219 | txt_drawc(bank_names[i], x0 + 3, y0 + 1, color); | ||
210 | } | 220 | } |
211 | } | 221 | } |
212 | 222 | ||
@@ -264,15 +274,14 @@ draw_play() { | |||
264 | size_t x_btn = x + PLAY_STOP_W / 2 - 1; | 274 | size_t x_btn = x + PLAY_STOP_W / 2 - 1; |
265 | if (play_status == 1) { | 275 | if (play_status == 1) { |
266 | // Pause button | 276 | // Pause button |
267 | draw_filled_rect(x_btn - 1, y + 3, x_btn, y + 7, COL_ACC_2); | 277 | draw_filled_rect(x_btn - 1, y + 2, x_btn, y + 6, COL_ACC_2); |
268 | draw_filled_rect(x_btn + 2, y + 3, x_btn + 3, y + 7, COL_ACC_2); | 278 | draw_filled_rect(x_btn + 2, y + 2, x_btn + 3, y + 6, COL_ACC_2); |
269 | } else { | 279 | } else { |
270 | // Play button | 280 | // Play button |
271 | x += 1; | 281 | x += 1; |
272 | draw_line(x_btn + 0, y + 2, x_btn + 0, y + 8, COL_ACC_2); | 282 | draw_line(x_btn + 0, y + 2, x_btn + 0, y + 6, COL_ACC_2); |
273 | draw_line(x_btn + 1, y + 3, x_btn + 1, y + 7, COL_ACC_2); | 283 | draw_line(x_btn + 1, y + 3, x_btn + 1, y + 5, COL_ACC_2); |
274 | draw_line(x_btn + 2, y + 4, x_btn + 2, y + 6, COL_ACC_2); | 284 | draw_line(x_btn + 2, y + 4, x_btn + 2, y + 4, COL_ACC_2); |
275 | draw_line(x_btn + 3, y + 5, x_btn + 3, y + 5, COL_ACC_2); | ||
276 | } | 285 | } |
277 | } | 286 | } |
278 | 287 | ||
@@ -280,12 +289,12 @@ void | |||
280 | draw_settings() { | 289 | draw_settings() { |
281 | size_t x = SETTINGS_START_X; | 290 | size_t x = SETTINGS_START_X; |
282 | size_t y = SETTINGS_START_Y; | 291 | size_t y = SETTINGS_START_Y; |
283 | draw_rect(x + 2, y, x + R_COL_W - 2, y + PLAY_STOP_H, COL_OFF); | 292 | draw_rect(x + 2, y, x + R_COL_W, y + PLAY_STOP_H, COL_OFF); |
284 | draw_line(x + 6, y + 4, x + 9, y + 4, COL_OFF); | 293 | draw_line(x + 10, y + 3, x + 13, y + 3, COL_OFF); |
285 | draw_line(x + 6, y + 6, x + 9, y + 6, COL_OFF); | 294 | draw_line(x + 10, y + 5, x + 13, y + 5, COL_OFF); |
286 | draw_line(x + 15, y + 4, x + 18, y + 4, COL_OFF); | 295 | draw_line(x + 19, y + 3, x + 22, y + 3, COL_OFF); |
287 | draw_line(x + 15, y + 6, x + 18, y + 6, COL_OFF); | 296 | draw_line(x + 19, y + 5, x + 22, y + 5, COL_OFF); |
288 | draw_line(x + 9, y + 5, x + 15, y + 5, COL_OFF); | 297 | draw_line(x + 13, y + 4, x + 19, y + 4, COL_OFF); |
289 | } | 298 | } |
290 | 299 | ||
291 | void | 300 | void |
@@ -294,8 +303,7 @@ draw_stop() { | |||
294 | size_t y = STOP_START_Y; | 303 | size_t y = STOP_START_Y; |
295 | size_t x_btn = x + PLAY_STOP_W / 2 - 2; | 304 | size_t x_btn = x + PLAY_STOP_W / 2 - 2; |
296 | draw_rect(x, y, x + PLAY_STOP_W, y + PLAY_STOP_H, COL_ACC_1); | 305 | draw_rect(x, y, x + PLAY_STOP_W, y + PLAY_STOP_H, COL_ACC_1); |
297 | draw_filled_rect(x_btn, y + 3, x_btn + 4, y + 7, COL_ACC_1); | 306 | draw_filled_rect(x_btn, y + 2, x_btn + 4, y + 6, COL_ACC_1); |
298 | draw_settings(); | ||
299 | } | 307 | } |
300 | 308 | ||
301 | void | 309 | void |
@@ -304,21 +312,34 @@ draw_bpm() { | |||
304 | size_t y = BPM_START_Y + 2; | 312 | size_t y = BPM_START_Y + 2; |
305 | 313 | ||
306 | // Draw bounding box. | 314 | // Draw bounding box. |
307 | draw_filled_rect(x, y, x + R_COL_W, y + BPM_H - 4, COL_BG); | 315 | draw_filled_rect(x, y, x + R_COL_W - 2, y + BPM_H - 3, COL_BG); |
308 | draw_rect(x, y, x + R_COL_W, y + BPM_H - 4, COL_FG); | 316 | draw_rect(x, y, x + R_COL_W - 2, y + BPM_H - 3, COL_FG); |
309 | draw_line(x + 5, y, x + 19, y, COL_BG); | 317 | txt_drawf_small("BPM", x + 7, y - 10, COL_FG); |
310 | txt_drawf_small("BPM", x + 5, y - 4, COL_FG); | ||
311 | 318 | ||
312 | // Make sure its horizontally centered if only 2 digits | 319 | // Make sure its horizontally centered if only 2 digits |
313 | int bpm = patterns[pattern_selection_loc].bpm; | 320 | int bpm = patterns[pattern_selection_loc].bpm; |
314 | if (bpm >= 100) { | 321 | if (bpm >= 100) { |
315 | txt_drawf("%d", x + 3, y + 5, COL_FG, bpm); | 322 | txt_drawf("%d", x + 5, y + 2, COL_FG, bpm); |
316 | } else { | 323 | } else { |
317 | txt_drawf("%d", x + 6, y + 5, COL_FG, bpm); | 324 | txt_drawf("%d", x + 8, y + 2, COL_FG, bpm); |
318 | } | 325 | } |
319 | } | 326 | } |
320 | 327 | ||
321 | void | 328 | void |
329 | draw_scale() { | ||
330 | size_t x = SCALE_START_X; | ||
331 | size_t y = SCALE_START_Y; | ||
332 | |||
333 | // Draw bounding box. | ||
334 | draw_filled_rect(x, y, x + R_COL_W - 2, y + SCALE_H - 3, COL_BG); | ||
335 | draw_rect(x, y, x + R_COL_W - 2, y + SCALE_H - 3, COL_FG); | ||
336 | txt_drawf_small("SCALE", x + 3, y - 10, COL_FG); | ||
337 | |||
338 | // TODO: Switch for different scales here | ||
339 | txt_drawf("CHRM", x + 2, y + 2, COL_FG); | ||
340 | } | ||
341 | |||
342 | void | ||
322 | draw_triggers(void) { | 343 | draw_triggers(void) { |
323 | for (size_t i = 0; i < 16; i++) { | 344 | for (size_t i = 0; i < 16; i++) { |
324 | size_t offset_x = TRIG_OFFSET_X * (i % 8); | 345 | size_t offset_x = TRIG_OFFSET_X * (i % 8); |
diff --git a/src/globals.c b/src/globals.c index 57c77bb..842b39f 100644 --- a/src/globals.c +++ b/src/globals.c | |||
@@ -32,63 +32,68 @@ bool clear_screen = true; | |||
32 | 32 | ||
33 | #define CHAN_W 19 | 33 | #define CHAN_W 19 |
34 | #define CHAN_H 8 | 34 | #define CHAN_H 8 |
35 | #define CHAN_START_X 30 | 35 | #define CHAN_START_X 28 |
36 | #define CHAN_START_Y 98 | 36 | #define CHAN_START_Y 100 |
37 | #define CHAN_OFFSET_Y 15 | 37 | #define CHAN_OFFSET_Y 15 |
38 | 38 | ||
39 | #define TRIG_W 15 | 39 | #define TRIG_W 15 |
40 | #define TRIG_H 22 | 40 | #define TRIG_H 22 |
41 | #define TRIG_START_X 59 | 41 | #define TRIG_START_X 55 |
42 | #define TRIG_START_Y 98 | 42 | #define TRIG_START_Y 100 |
43 | #define TRIG_OFFSET_X (TRIG_W + 3) | 43 | #define TRIG_OFFSET_X (TRIG_W + 3) |
44 | #define TRIG_OFFSET_Y (TRIG_H + 8) | 44 | #define TRIG_OFFSET_Y (TRIG_H + 8) |
45 | 45 | ||
46 | #define PIANO_W 170 | 46 | #define PIANO_W 170 |
47 | #define PIANO_H 12 | 47 | #define PIANO_H 12 |
48 | #define PIANO_BLACK_H 10 | 48 | #define PIANO_BLACK_H 10 |
49 | #define PIANO_START_X 30 | 49 | #define PIANO_START_X 27 |
50 | #define PIANO_START_Y 80 | 50 | #define PIANO_START_Y 80 |
51 | #define PIANO_NOTE_W 2 | 51 | #define PIANO_NOTE_W 2 |
52 | 52 | ||
53 | #define NOTIF_W 170 | 53 | #define NOTIF_W 170 |
54 | #define NOTIF_H 10 | 54 | #define NOTIF_H 10 |
55 | #define NOTIF_START_X 30 | 55 | #define NOTIF_START_X 27 |
56 | #define NOTIF_START_Y 13 | 56 | #define NOTIF_START_Y 12 |
57 | 57 | ||
58 | #define PARAMS_W 166 | 58 | #define PARAMS_W 166 |
59 | #define PARAMS_H 52 | 59 | #define PARAMS_H 52 |
60 | #define PARAMS_START_X 32 | 60 | #define PARAMS_START_X 29 |
61 | #define PARAMS_START_Y 22 | 61 | #define PARAMS_START_Y 20 |
62 | #define PARAMS_BOX_W 30 | 62 | #define PARAMS_BOX_W 30 |
63 | #define PARAMS_BOX_H 24 | 63 | #define PARAMS_BOX_H 24 |
64 | #define PARAMS_BOX_OFFSET_X (PARAMS_BOX_W + 4) | 64 | #define PARAMS_BOX_OFFSET_X (PARAMS_BOX_W + 4) |
65 | #define PARAMS_BOX_OFFSET_Y (PARAMS_BOX_H + 4) | 65 | #define PARAMS_BOX_OFFSET_Y (PARAMS_BOX_H + 4) |
66 | 66 | ||
67 | #define R_SIDEBAR_X ((TRIG_START_X) + (TRIG_OFFSET_X) * 8 + 4) | 67 | #define R_SIDEBAR_X ((TRIG_START_X) + (TRIG_OFFSET_X) * 8 + 8) |
68 | #define L_SIDEBAR_X ((CHAN_START_X) - 26) | ||
69 | 68 | ||
70 | #define PAT_START_X (L_SIDEBAR_X + 4) | 69 | #define PAT_START_X 5 |
71 | #define PAT_START_Y 21 | 70 | #define PAT_START_Y 16 |
72 | #define PAT_W 14 | 71 | #define PAT_W 14 |
73 | #define PAT_H 10 | 72 | #define PAT_H 10 |
74 | #define PAT_OFFSET_Y 17 | 73 | #define PAT_OFFSET_Y 18 |
75 | 74 | ||
76 | #define R_COL_W 24 | 75 | #define R_COL_W 30 |
77 | #define BPM_START_X (R_SIDEBAR_X) | 76 | #define BPM_START_X (R_SIDEBAR_X - 2) |
78 | #define BPM_START_Y (TRIG_START_Y + TRIG_H + 8) | 77 | #define BPM_START_Y (TRIG_START_Y + 8) |
79 | #define BPM_H 22 | 78 | #define BPM_H 15 |
80 | 79 | ||
81 | #define SETTINGS_START_X (R_SIDEBAR_X) | 80 | #define SCALE_START_X (R_SIDEBAR_X - 2) |
82 | #define SETTINGS_START_Y (TRIG_START_Y - 7) | 81 | #define SCALE_START_Y (PIANO_START_Y) |
83 | #define PLAY_START_X (R_SIDEBAR_X) | 82 | #define SCALE_H 15 |
84 | #define PLAY_START_Y (TRIG_START_Y + 12) | 83 | |
84 | #define SETTINGS_START_X (R_SIDEBAR_X - 4) | ||
85 | #define SETTINGS_START_Y (TRIG_START_Y + 30) | ||
86 | #define PLAY_START_X (R_SIDEBAR_X - 2) | ||
87 | #define PLAY_START_Y (TRIG_START_Y + 44) | ||
85 | #define STOP_START_X (R_SIDEBAR_X + 14) | 88 | #define STOP_START_X (R_SIDEBAR_X + 14) |
86 | #define STOP_START_Y (TRIG_START_Y + 12) | 89 | #define STOP_START_Y (TRIG_START_Y + 44) |
87 | #define PLAY_STOP_W (10) | 90 | #define PLAY_STOP_W (12) |
88 | #define PLAY_STOP_H (10) | 91 | #define PLAY_STOP_H (8) |
89 | 92 | ||
90 | #define BANK_START_X (R_SIDEBAR_X + 5) | 93 | #define BANK_START_X (R_SIDEBAR_X + 5) |
91 | #define BANK_START_Y (PAT_START_Y) | 94 | #define BANK_START_Y (PAT_START_Y) |
95 | #define BANK_W 12 | ||
96 | #define BANK_H 10 | ||
92 | 97 | ||
93 | #define PAT_TRIG_W 14 | 98 | #define PAT_TRIG_W 14 |
94 | #define PAT_TRIG_H 14 | 99 | #define PAT_TRIG_H 14 |
@@ -14,11 +14,6 @@ WITH REGARD TO THIS SOFTWARE. | |||
14 | // UI tweaks. | 14 | // UI tweaks. |
15 | // - Add custom user themes | 15 | // - Add custom user themes |
16 | // - Animations for cursor movement/current step highlight. (A fade out maybe?) | 16 | // - Animations for cursor movement/current step highlight. (A fade out maybe?) |
17 | // - Improve "grey" cursor with dithering instead. | ||
18 | // - Remove thin cursor option and make the fat one default, it's just better. | ||
19 | // - Settings page overhaul. | ||
20 | // - Make sure there is an ALL notification when modifying channel params so | ||
21 | // that it's clear it's affecting all triggers. | ||
22 | // | 17 | // |
23 | // Quality of life improvements. | 18 | // Quality of life improvements. |
24 | // - When not on play mode, adjusting a note or a parameter triggers the sound. | 19 | // - When not on play mode, adjusting a note or a parameter triggers the sound. |
@@ -27,7 +22,6 @@ WITH REGARD TO THIS SOFTWARE. | |||
27 | // - Undo/Redo. | 22 | // - Undo/Redo. |
28 | // | 23 | // |
29 | // Advanced | 24 | // Advanced |
30 | // - Scale mode for entering notes. | ||
31 | // - Add tap tempo for BPM. | 25 | // - Add tap tempo for BPM. |
32 | // - Allow "marking" several trigs to be able to copy/paste them and/or adjust | 26 | // - Allow "marking" several trigs to be able to copy/paste them and/or adjust |
33 | // their parameters. | 27 | // their parameters. |
@@ -37,19 +31,30 @@ WITH REGARD TO THIS SOFTWARE. | |||
37 | // - Per trig LFO? How would we go about this? There is at least one empty slot | 31 | // - Per trig LFO? How would we go about this? There is at least one empty slot |
38 | // in all channels. LFO amount? LFO speed? Would need a dedicated page for | 32 | // in all channels. LFO amount? LFO speed? Would need a dedicated page for |
39 | // configuring LFOs | 33 | // configuring LFOs |
40 | // - Multiple pattern chains per bank that we can toggle between, gotta study | ||
41 | // if they fit in the SRAM. | ||
42 | // - Make sure bank switching is queued like patterns. | ||
43 | // - Add settings for "performance mode" in which banks are not saved by | ||
44 | // default while changing patterns. | ||
45 | // - Make sure sync works with the same cable for in/out. | ||
46 | // - Per-channel N steps to create polymeters? | 34 | // - Per-channel N steps to create polymeters? |
47 | // - Higher resolution clock to allow for microtiming and more accurate tempo. | ||
48 | // - Study how to better embed data into the cart that doesn't involve the | 35 | // - Study how to better embed data into the cart that doesn't involve the |
49 | // build system to generate .c files. Just use the linker to put binary data | 36 | // build system to generate .c files. Just use the linker to put binary data |
50 | // into the ROM. | 37 | // into the ROM. |
38 | // | ||
39 | // WIP (1.7) | ||
40 | // - Scale mode for entering notes. | ||
51 | // - Improve SRAM saving to make room for longer patterns and/or more banks. | 41 | // - Improve SRAM saving to make room for longer patterns and/or more banks. |
52 | // - Add CLEAR ALL to the settings menu. | 42 | // - Add CLEAR ALL to the settings menu. |
43 | // - Higher resolution clock to allow for microtiming and more accurate tempo. | ||
44 | // - Multiple pattern chains per bank that we can toggle between, gotta study | ||
45 | // if they fit in the SRAM. | ||
46 | // - Make sure bank switching is queued like patterns. | ||
47 | // - Add settings for "performance mode" in which banks are not saved by | ||
48 | // default while changing patterns. | ||
49 | // - Make sure sync works with the same cable for in/out. | ||
50 | // - Improve "grey" cursor with dithering instead. | ||
51 | // - Remove thin cursor option and make the fat one default, it's just better. | ||
52 | // - Settings page overhaul. | ||
53 | // - Make sure there is an ALL notification when modifying channel params so | ||
54 | // that it's clear it's affecting all triggers. | ||
55 | // - Blank patterns could show up as empty on the pattern view for better | ||
56 | // separation and section organization. | ||
57 | // - Study more improvements for a "performance mode". | ||
53 | // | 58 | // |
54 | 59 | ||
55 | #include "gba/gba.h" | 60 | #include "gba/gba.h" |
@@ -65,7 +70,6 @@ WITH REGARD TO THIS SOFTWARE. | |||
65 | 70 | ||
66 | void | 71 | void |
67 | render_sequencer(void) { | 72 | render_sequencer(void) { |
68 | PROF(draw_rect(0, 0, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1, 1), clear_cycles); | ||
69 | if (redraw_trigs) { | 73 | if (redraw_trigs) { |
70 | PROF(draw_triggers(), draw_trigs_cycles); | 74 | PROF(draw_triggers(), draw_trigs_cycles); |
71 | redraw_trigs = false; | 75 | redraw_trigs = false; |
@@ -89,6 +93,9 @@ render_sequencer(void) { | |||
89 | if (redraw_play_pause) { | 93 | if (redraw_play_pause) { |
90 | PROF(draw_play(), draw_btn_cycles); | 94 | PROF(draw_play(), draw_btn_cycles); |
91 | PROF(draw_stop(), draw_btn_cycles); | 95 | PROF(draw_stop(), draw_btn_cycles); |
96 | // TODO: Move to separate if condition | ||
97 | PROF(draw_settings(), draw_btn_cycles); | ||
98 | PROF(draw_scale(), draw_btn_cycles); | ||
92 | redraw_play_pause = false; | 99 | redraw_play_pause = false; |
93 | } | 100 | } |
94 | if (redraw_piano_note) { | 101 | if (redraw_piano_note) { |
@@ -112,7 +119,6 @@ render_sequencer(void) { | |||
112 | 119 | ||
113 | void | 120 | void |
114 | render_settings(void) { | 121 | render_settings(void) { |
115 | PROF(draw_rect(0, 0, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1, 1), clear_cycles); | ||
116 | txt_drawf_small("settings", 11, 5, COL_FG) | 122 | txt_drawf_small("settings", 11, 5, COL_FG) |
117 | txt_printf("\n\n\n"); | 123 | txt_printf("\n\n\n"); |
118 | txt_printf(" SYNC: %s\n\n", sync_setting_str[settings.sync]); | 124 | txt_printf(" SYNC: %s\n\n", sync_setting_str[settings.sync]); |
@@ -139,7 +145,7 @@ render(void) { | |||
139 | } break; | 145 | } break; |
140 | } | 146 | } |
141 | // DEBUG: Ensuring the saved data don't exceed SRAM size (32k). | 147 | // DEBUG: Ensuring the saved data don't exceed SRAM size (32k). |
142 | // txt_drawf("SIZE: %lu", 0, 0, COL_ACC_1, sizeof(Metadata) + sizeof(patterns) * 4 + sizeof(chain) * 4); | 148 | txt_drawf("SIZE: %lu", 0, 0, COL_ACC_1, sizeof(Metadata) + sizeof(patterns) * 6 + sizeof(chain) * 6); |
143 | } | 149 | } |
144 | 150 | ||
145 | void | 151 | void |