summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2021-06-08 14:34:13 +0200
committerBad Diode <bd@badd10de.dev>2021-06-08 14:34:13 +0200
commit2faf84d78bf261b6f02648e66f0c84efc1eefd05 (patch)
tree3f780b2835eaa8505ebc87769b252fa9d639fe03
parent436b4a1d28f5939e1c0f8792317a639b091b0f29 (diff)
downloadgba-sequencer-2faf84d78bf261b6f02648e66f0c84efc1eefd05.tar.gz
gba-sequencer-2faf84d78bf261b6f02648e66f0c84efc1eefd05.zip
Change draw_tile to allow coloring of flat tiles
-rw-r--r--src/renderer.c20
-rw-r--r--src/renderer.h6
-rw-r--r--src/sequencer.c214
-rw-r--r--src/text/text.h8
4 files changed, 126 insertions, 122 deletions
diff --git a/src/renderer.c b/src/renderer.c
index afc9904..0ce3107 100644
--- a/src/renderer.c
+++ b/src/renderer.c
@@ -276,7 +276,7 @@ draw_filled_rect(size_t x0, size_t y0, size_t x1, size_t y1, u8 clr) {
276 276
277IWRAM_CODE 277IWRAM_CODE
278void 278void
279draw_tile(size_t x, size_t y, Tile *tile, bool merge) { 279draw_tile(size_t x, size_t y, Tile *tile, u8 clr, bool merge) {
280 BOUNDCHECK_SCREEN(x, y); 280 BOUNDCHECK_SCREEN(x, y);
281 281
282 // Find row position for the given x/y coordinates. 282 // Find row position for the given x/y coordinates.
@@ -305,40 +305,40 @@ draw_tile(size_t x, size_t y, Tile *tile, bool merge) {
305 if (start_col == 0 && start_row == 0) { 305 if (start_col == 0 && start_row == 0) {
306 for (size_t i = 0; i < (8 - start_row); i++, backbuffer++) { 306 for (size_t i = 0; i < (8 - start_row); i++, backbuffer++) {
307 BOUNDCHECK_SCREEN(x, y + i); 307 BOUNDCHECK_SCREEN(x, y + i);
308 backbuffer[0] = (backbuffer[0] & ~row_mask_left) | row[i]; 308 backbuffer[0] = (backbuffer[0] & ~row_mask_left) | row[i] * clr;
309 } 309 }
310 dirty_tiles[tile_y] |= 1 << tile_x; 310 dirty_tiles[tile_y] |= 1 << tile_x;
311 } else if (start_row == 0) { 311 } else if (start_row == 0) {
312 for (size_t i = 0; i < 8; i++, backbuffer++) { 312 for (size_t i = 0; i < 8; i++, backbuffer++) {
313 BOUNDCHECK_SCREEN(x, y + i); 313 BOUNDCHECK_SCREEN(x, y + i);
314 backbuffer[0] = (backbuffer[0] & ~row_mask_left) | (row[i] << shift_left); 314 backbuffer[0] = (backbuffer[0] & ~row_mask_left) | (row[i] * clr << shift_left);
315 backbuffer[8] = (backbuffer[8] & ~row_mask_right) | (row[i] >> shift_right); 315 backbuffer[8] = (backbuffer[8] & ~row_mask_right) | (row[i] * clr >> shift_right);
316 } 316 }
317 dirty_tiles[tile_y] |= 1 << tile_x; 317 dirty_tiles[tile_y] |= 1 << tile_x;
318 dirty_tiles[tile_y] |= 1 << (tile_x + 1); 318 dirty_tiles[tile_y] |= 1 << (tile_x + 1);
319 } else if (start_col == 0) { 319 } else if (start_col == 0) {
320 for (size_t i = 0; i < (8 - start_row); i++, backbuffer++) { 320 for (size_t i = 0; i < (8 - start_row); i++, backbuffer++) {
321 BOUNDCHECK_SCREEN(x, y + i); 321 BOUNDCHECK_SCREEN(x, y + i);
322 backbuffer[0] = (backbuffer[0] & ~row_mask_left) | row[i]; 322 backbuffer[0] = (backbuffer[0] & ~row_mask_left) | row[i] * clr;
323 } 323 }
324 backbuffer += 8 * 31; 324 backbuffer += 8 * 31;
325 for (size_t i = (8 - start_row); i < 8; i++, backbuffer++) { 325 for (size_t i = (8 - start_row); i < 8; i++, backbuffer++) {
326 BOUNDCHECK_SCREEN(x, y + i); 326 BOUNDCHECK_SCREEN(x, y + i);
327 backbuffer[0] = (backbuffer[0] & ~row_mask_left) | row[i]; 327 backbuffer[0] = (backbuffer[0] & ~row_mask_left) | row[i] * clr;
328 } 328 }
329 dirty_tiles[tile_y] |= 1 << tile_x; 329 dirty_tiles[tile_y] |= 1 << tile_x;
330 dirty_tiles[tile_y + 1] |= 1 << tile_x; 330 dirty_tiles[tile_y + 1] |= 1 << tile_x;
331 } else { 331 } else {
332 for (size_t i = 0; i < (8 - start_row); i++, backbuffer++) { 332 for (size_t i = 0; i < (8 - start_row); i++, backbuffer++) {
333 BOUNDCHECK_SCREEN(x, y + i); 333 BOUNDCHECK_SCREEN(x, y + i);
334 backbuffer[0] = (backbuffer[0] & ~row_mask_left) | (row[i] << shift_left); 334 backbuffer[0] = (backbuffer[0] & ~row_mask_left) | (row[i] * clr << shift_left);
335 backbuffer[8] = (backbuffer[8] & ~row_mask_right) | (row[i] >> shift_right); 335 backbuffer[8] = (backbuffer[8] & ~row_mask_right) | (row[i] * clr >> shift_right);
336 } 336 }
337 backbuffer += 8 * 31; 337 backbuffer += 8 * 31;
338 for (size_t i = (8 - start_row); i < 8; i++, backbuffer++) { 338 for (size_t i = (8 - start_row); i < 8; i++, backbuffer++) {
339 BOUNDCHECK_SCREEN(x, y + i); 339 BOUNDCHECK_SCREEN(x, y + i);
340 backbuffer[0] = (backbuffer[0] & ~row_mask_left) | (row[i] << shift_left); 340 backbuffer[0] = (backbuffer[0] & ~row_mask_left) | (row[i] * clr << shift_left);
341 backbuffer[8] = (backbuffer[8] & ~row_mask_right) | (row[i] >> shift_right); 341 backbuffer[8] = (backbuffer[8] & ~row_mask_right) | (row[i] * clr >> shift_right);
342 } 342 }
343 dirty_tiles[tile_y] |= 1 << tile_x; 343 dirty_tiles[tile_y] |= 1 << tile_x;
344 dirty_tiles[tile_y] |= 1 << (tile_x + 1); 344 dirty_tiles[tile_y] |= 1 << (tile_x + 1);
diff --git a/src/renderer.h b/src/renderer.h
index a240b17..4620c27 100644
--- a/src/renderer.h
+++ b/src/renderer.h
@@ -43,8 +43,10 @@ void draw_filled_rect(size_t x0, size_t y0, size_t x1, size_t y1, u8 clr);
43 43
44// Draw a 8x8 tile starting at the (x, y) position. If the merge parameter is 44// Draw a 8x8 tile starting at the (x, y) position. If the merge parameter is
45// set, colors will be added together instead of replaced. This could lead to 45// set, colors will be added together instead of replaced. This could lead to
46// some merging issues if we are not careful with the chosen colors. 46// some merging issues if we are not careful with the chosen colors. The tile
47void draw_tile(size_t x, size_t y, Tile *tile, bool merge); 47// color will be multiplied by the given clr parameter, which is useful to
48// change the color of flat tiles.
49void draw_tile(size_t x, size_t y, Tile *tile, u8 clr, bool merge);
48 50
49// Fills the framebuffer with color 0. 51// Fills the framebuffer with color 0.
50void clear_screen(void); 52void clear_screen(void);
diff --git a/src/sequencer.c b/src/sequencer.c
index 46e57ef..dc3249c 100644
--- a/src/sequencer.c
+++ b/src/sequencer.c
@@ -2,6 +2,16 @@
2#include "text.h" 2#include "text.h"
3 3
4// 4//
5// Color indexes.
6//
7#define COL_BG 0
8#define COL_FG 1
9#define COL_RED 2
10#define COL_BLUE 3
11#define COL_CYAN 4
12#define COL_GREY 5
13
14//
5// Assets. 15// Assets.
6// 16//
7 17
@@ -97,17 +107,11 @@ static const u32 channel_buttons[] = {
97// 107//
98// Globals. 108// Globals.
99// 109//
100typedef enum {
101 SEQ_SELECT_TRIGGER,
102 SEQ_SELECT_CHANNEL,
103 SEQ_SELECT_PARAMETER,
104} SeqSelect;
105static int bpm = 115; 110static int bpm = 115;
106static int step_counter = 0; 111static int step_counter = 0;
107int trig_selection_loc = 0; 112int trig_selection_loc = 0;
108int param_selection_loc = 64; 113int param_selection_loc = 64;
109int channel_selection_loc = 0; 114int channel_selection_loc = 0;
110SeqSelect current_selection = SEQ_SELECT_TRIGGER;
111 115
112// 116//
113// Wave data. 117// Wave data.
@@ -228,7 +232,7 @@ clear_trigger(size_t i) {
228 size_t x1 = TRIG_START_X + offset_x + TRIG_W - 1; 232 size_t x1 = TRIG_START_X + offset_x + TRIG_W - 1;
229 size_t y0 = TRIG_START_Y + offset_y + 1; 233 size_t y0 = TRIG_START_Y + offset_y + 1;
230 size_t y1 = TRIG_START_Y + offset_y + TRIG_H - 1; 234 size_t y1 = TRIG_START_Y + offset_y + TRIG_H - 1;
231 draw_filled_rect(x0, y0, x1, y1, 0); 235 draw_filled_rect(x0, y0, x1, y1, COL_BG);
232} 236}
233 237
234void 238void
@@ -240,8 +244,8 @@ draw_trigger(size_t chan, size_t i) {
240 size_t y = TRIG_START_Y + offset_y; 244 size_t y = TRIG_START_Y + offset_y;
241 Tile *tiles = ASSETS_DATA; 245 Tile *tiles = ASSETS_DATA;
242 tiles += 2 * sequences[chan][i].note; 246 tiles += 2 * sequences[chan][i].note;
243 draw_tile(x, y, tiles, true); 247 draw_tile(x, y, tiles, COL_FG, true);
244 draw_tile(x + 8, y, tiles + 1, true); 248 draw_tile(x + 8, y, tiles + 1, COL_FG, true);
245 } else { 249 } else {
246 clear_trigger(i); 250 clear_trigger(i);
247 } 251 }
@@ -266,11 +270,14 @@ draw_triggers(void) {
266 size_t x1 = TRIG_START_X + offset_x + TRIG_W; 270 size_t x1 = TRIG_START_X + offset_x + TRIG_W;
267 size_t y0 = TRIG_START_Y + offset_y; 271 size_t y0 = TRIG_START_Y + offset_y;
268 size_t y1 = TRIG_START_Y + offset_y + TRIG_H; 272 size_t y1 = TRIG_START_Y + offset_y + TRIG_H;
269 draw_rect(x0, y0, x1, y1, 1); 273 draw_rect(x0, y0, x1, y1, COL_FG);
274 clear_trigger(i);
270 draw_trigger(channel_selection_loc, i); 275 draw_trigger(channel_selection_loc, i);
271 } 276 }
272} 277}
273 278
279#define CHAN_W 19
280#define CHAN_H 8
274#define CHAN_START_X 35 281#define CHAN_START_X 35
275#define CHAN_START_Y 90 282#define CHAN_START_Y 90
276#define CHAN_OFFSET_Y 12 283#define CHAN_OFFSET_Y 12
@@ -284,13 +291,23 @@ draw_channels(void) {
284 size_t k = 0; 291 size_t k = 0;
285 for (size_t i = 0; i < 4; i++) { 292 for (size_t i = 0; i < 4; i++) {
286 size_t y = CHAN_START_Y + i * CHAN_OFFSET_Y; 293 size_t y = CHAN_START_Y + i * CHAN_OFFSET_Y;
287 draw_tile(CHAN_START_X, y, channel_tiles + k++, false); 294 draw_tile(CHAN_START_X, y, channel_tiles + k++, COL_FG, false);
288 draw_tile(CHAN_START_X + 8, y, channel_tiles + k++, false); 295 draw_tile(CHAN_START_X + 8, y, channel_tiles + k++, COL_FG, false);
289 draw_tile(CHAN_START_X + 16, y, channel_tiles + k++, false); 296 draw_tile(CHAN_START_X + 16, y, channel_tiles + k++, COL_FG, false);
290 } 297 }
291} 298}
292 299
293void 300void
301draw_channel_cursor(size_t i, u8 clr) {
302 size_t offset_x = 0;
303 size_t offset_y = CHAN_H + i * CHAN_OFFSET_Y;
304 size_t x0 = CHAN_START_X + offset_x;
305 size_t x1 = CHAN_START_X + offset_x + CHAN_W;
306 size_t y = CHAN_START_Y + offset_y;
307 draw_line(x0, y, x1, y, clr);
308}
309
310void
294irq_timer_0(void) { 311irq_timer_0(void) {
295 Note active_note; 312 Note active_note;
296 { 313 {
@@ -392,79 +409,102 @@ set_time(int bpm) {
392 TIMER_CTRL_0 = TIMER_CTRL_IRQ | TIMER_CTRL_ENABLE | TIMER_CTRL_FREQ_3; 409 TIMER_CTRL_0 = TIMER_CTRL_IRQ | TIMER_CTRL_ENABLE | TIMER_CTRL_FREQ_3;
393} 410}
394 411
412
413void (*input_handler)(void);
414
395#define SEQ_N_CHANNELS 3 415#define SEQ_N_CHANNELS 3
396 416
417void handle_trigger_cursor(void);
418void handle_channel_cursor(void);
419
397void 420void
398trigger_cursor(void) { 421handle_channel_cursor(void) {
399 SeqTrigger *trig = &sequences[channel_selection_loc][trig_selection_loc]; 422 if (key_tap(KEY_RIGHT)) {
400 if (key_tap(KEY_LEFT)) { 423 trig_selection_loc = 0;
401 if (trig_selection_loc == 0 || trig_selection_loc == 8) { 424 param_selection_loc = 0;
402 // current_selection = SEQ_SELECT_CHANNEL; 425 input_handler = handle_trigger_cursor;
426 draw_channel_cursor(channel_selection_loc, COL_GREY);
427 draw_trig_cursor(trig_selection_loc, COL_BLUE);
428 }
429 if (key_tap(KEY_UP)) {
430 draw_channel_cursor(channel_selection_loc, COL_BG);
431 if (channel_selection_loc == 0) {
432 channel_selection_loc = SEQ_N_CHANNELS - 1;
403 } else { 433 } else {
404 draw_trig_cursor(trig_selection_loc, 0); 434 channel_selection_loc = MAX(channel_selection_loc - 1, 0);
405 trig_selection_loc = MAX(trig_selection_loc - 1, 0);
406 draw_trig_cursor(trig_selection_loc, 3);
407 } 435 }
408 } else if (key_tap(KEY_RIGHT)) { 436 draw_channel_cursor(channel_selection_loc, COL_BLUE);
409 if (trig_selection_loc != 7) { 437 draw_triggers();
410 draw_trig_cursor(trig_selection_loc, 0); 438 }
411 trig_selection_loc = MIN(trig_selection_loc + 1, 15); 439 if (key_tap(KEY_DOWN)) {
412 draw_trig_cursor(trig_selection_loc, 3); 440 draw_channel_cursor(channel_selection_loc, COL_BG);
441 if (channel_selection_loc == SEQ_N_CHANNELS - 1) {
442 channel_selection_loc = 0;
443 } else {
444 channel_selection_loc = MIN(channel_selection_loc + 1, SEQ_N_CHANNELS);
413 } 445 }
414 } else if (key_tap(KEY_UP) || key_tap(KEY_DOWN)) { 446 draw_channel_cursor(channel_selection_loc, COL_BLUE);
415 draw_trig_cursor(trig_selection_loc, 0); 447 draw_triggers();
416 trig_selection_loc = (trig_selection_loc + 8) % 16; 448 }
417 draw_trig_cursor(trig_selection_loc, 3); 449}
418 } else if (key_tap(KEY_B)) { 450
451void
452handle_trigger_cursor(void) {
453 SeqTrigger *trig = &sequences[channel_selection_loc][trig_selection_loc];
454
455 if (key_tap(KEY_B)) {
456 // Toggle trigger.
419 trig->trigger ^= 1; 457 trig->trigger ^= 1;
458 draw_trigger(channel_selection_loc, trig_selection_loc);
459 } else if (key_tap(KEY_A)) {
460 // Switch to parameter selection.
461 // current_selection = SEQ_SELECT_PARAMETER;
420 } else if (key_tap(KEY_L)) { 462 } else if (key_tap(KEY_L)) {
463 // Decrease note.
421 if (trig->trigger) { 464 if (trig->trigger) {
422 trig->note = MAX(trig->note - 1, NOTE_C_2); 465 trig->note = MAX(trig->note - 1, NOTE_C_2);
466 clear_trigger(trig_selection_loc);
467 draw_trigger(channel_selection_loc, trig_selection_loc);
423 } 468 }
424 } else if (key_tap(KEY_R)) { 469 } else if (key_tap(KEY_R)) {
470 // Increase note.
425 if (trig->trigger) { 471 if (trig->trigger) {
426 trig->note = MIN( trig->note + 1, NOTE_C_8); 472 trig->note = MIN( trig->note + 1, NOTE_C_8);
473 clear_trigger(trig_selection_loc);
474 draw_trigger(channel_selection_loc, trig_selection_loc);
427 } 475 }
428 } else if (key_tap(KEY_A)) {
429 // Switch to parameter selection.
430 // current_selection = SEQ_SELECT_PARAMETER;
431 } 476 }
432}
433 477
434void (*input_handler)(void); 478 // Move trigger cursor.
479 if (key_tap(KEY_LEFT)) {
480 if (trig_selection_loc == 0 || trig_selection_loc == 8) {
481 // We are at the boundary, switch to channel selection.
482 draw_trig_cursor(trig_selection_loc, COL_BG);
483 input_handler = handle_channel_cursor;
484 draw_channel_cursor(channel_selection_loc, COL_BLUE);
485 } else {
486 draw_trig_cursor(trig_selection_loc, COL_BG);
487 trig_selection_loc = MAX(trig_selection_loc - 1, 0);
488 draw_trig_cursor(trig_selection_loc, COL_BLUE);
489 }
490 } else if (key_tap(KEY_RIGHT)) {
491 if (trig_selection_loc != 7) {
492 draw_trig_cursor(trig_selection_loc, COL_BG);
493 trig_selection_loc = MIN(trig_selection_loc + 1, 15);
494 draw_trig_cursor(trig_selection_loc, COL_BLUE);
495 }
496 } else if (key_tap(KEY_UP) || key_tap(KEY_DOWN)) {
497 draw_trig_cursor(trig_selection_loc, COL_BG);
498 trig_selection_loc = (trig_selection_loc + 8) % 16;
499 draw_trig_cursor(trig_selection_loc, COL_BLUE);
500 }
501}
435 502
436void 503void
437handle_sequencer_input(void) { 504handle_sequencer_input(void) {
438 poll_keys(); 505 poll_keys();
439 input_handler(); 506 input_handler();
440 // SeqTrigger *trig = &sequences[channel_selection_loc][trig_selection_loc]; 507 // SeqTrigger *trig = &sequences[channel_selection_loc][trig_selection_loc];
441 // if (current_selection == SEQ_SELECT_TRIGGER) {
442 // if (key_tap(KEY_LEFT)) {
443 // if (trig_selection_loc == 0 || trig_selection_loc == 8) {
444 // current_selection = SEQ_SELECT_CHANNEL;
445 // } else {
446 // trig_selection_loc = MAX(trig_selection_loc - 1, 0);
447 // }
448 // } else if (key_tap(KEY_RIGHT)) {
449 // if (trig_selection_loc != 7) {
450 // trig_selection_loc = MIN(trig_selection_loc + 1, 15);
451 // }
452 // } else if (key_tap(KEY_UP) || key_tap(KEY_DOWN)) {
453 // trig_selection_loc = (trig_selection_loc + 8) % 16;
454 // } else if (key_tap(KEY_B)) {
455 // trig->trigger ^= 1;
456 // } else if (key_tap(KEY_L)) {
457 // if (trig->trigger) {
458 // trig->note = MAX(trig->note - 1, NOTE_C_2);
459 // }
460 // } else if (key_tap(KEY_R)) {
461 // if (trig->trigger) {
462 // trig->note = MIN( trig->note + 1, NOTE_C_8);
463 // }
464 // } else if (key_tap(KEY_A)) {
465 // // Switch to parameter selection.
466 // current_selection = SEQ_SELECT_PARAMETER;
467 // }
468 // } else if (current_selection == SEQ_SELECT_PARAMETER) { 508 // } else if (current_selection == SEQ_SELECT_PARAMETER) {
469 // if (channel_selection_loc < 2) { 509 // if (channel_selection_loc < 2) {
470 // // Move through the selected synth parameters. 510 // // Move through the selected synth parameters.
@@ -648,38 +688,8 @@ handle_sequencer_input(void) {
648 // } 688 // }
649 // } 689 // }
650 690
651 // // Go back to trigger selection.
652 // if (key_tap(KEY_A)) {
653 // current_selection = SEQ_SELECT_TRIGGER;
654 // }
655
656 // // Enable disable trigger.
657 // if (key_tap(KEY_B)) {
658 // trig->trigger ^= 1;
659 // }
660 // } else if (current_selection == SEQ_SELECT_CHANNEL) {
661 // if (key_tap(KEY_RIGHT)) {
662 // current_selection = SEQ_SELECT_TRIGGER;
663 // trig_selection_loc = 0;
664 // param_selection_loc = 0;
665 // }
666 // if (key_tap(KEY_UP)) {
667 // if (channel_selection_loc == 0) {
668 // channel_selection_loc = SEQ_N_CHANNELS - 1;
669 // } else {
670 // channel_selection_loc = MAX(channel_selection_loc - 1, 0);
671 // }
672 // }
673 // if (key_tap(KEY_DOWN)) {
674 // if (channel_selection_loc == SEQ_N_CHANNELS - 1) {
675 // channel_selection_loc = 0;
676 // } else {
677 // channel_selection_loc = MIN(channel_selection_loc + 1, SEQ_N_CHANNELS);
678 // }
679 // }
680 // }
681
682 if (key_tap(KEY_START)) { 691 if (key_tap(KEY_START)) {
692 // Stop the sequencer or start playing from the beginning.
683 step_counter = 0; 693 step_counter = 0;
684 if ((TIMER_CTRL_0 & TIMER_CTRL_ENABLE) == 0) { 694 if ((TIMER_CTRL_0 & TIMER_CTRL_ENABLE) == 0) {
685 set_time(bpm); 695 set_time(bpm);
@@ -689,22 +699,13 @@ handle_sequencer_input(void) {
689 SOUND_SQUARE2_CTRL = 0; 699 SOUND_SQUARE2_CTRL = 0;
690 SOUND_WAVE_CTRL = 0; 700 SOUND_WAVE_CTRL = 0;
691 } 701 }
692 } 702 } else if (key_tap(KEY_SELECT)) {
693 if (key_tap(KEY_SELECT)) { 703 // Play/pause.
694 TIMER_CTRL_0 ^= TIMER_CTRL_ENABLE; 704 TIMER_CTRL_0 ^= TIMER_CTRL_ENABLE;
695 SOUND_SQUARE1_CTRL = 0; 705 SOUND_SQUARE1_CTRL = 0;
696 SOUND_SQUARE2_CTRL = 0; 706 SOUND_SQUARE2_CTRL = 0;
697 SOUND_WAVE_CTRL = 0; 707 SOUND_WAVE_CTRL = 0;
698 } 708 }
699
700 // if (key_tap(KEY_LEFT)
701 // || key_tap(KEY_RIGHT)
702 // || key_tap(KEY_UP)
703 // || key_tap(KEY_DOWN)
704 // || key_tap(KEY_L)
705 // || key_tap(KEY_R)
706 // ) {
707 // }
708} 709}
709 710
710void 711void
@@ -722,8 +723,9 @@ sequencer_init(void) {
722 draw_channels(); 723 draw_channels();
723 724
724 // Initialize input handler. 725 // Initialize input handler.
725 input_handler = trigger_cursor; 726 input_handler = handle_trigger_cursor;
726 draw_trig_cursor(trig_selection_loc, 3); 727 draw_trig_cursor(trig_selection_loc, 3);
728 draw_channel_cursor(channel_selection_loc, 5);
727 729
728 // Initialize sound system. 730 // Initialize sound system.
729 SOUND_STATUS = SOUND_ENABLE; 731 SOUND_STATUS = SOUND_ENABLE;
diff --git a/src/text/text.h b/src/text/text.h
index 01dddb0..931227c 100644
--- a/src/text/text.h
+++ b/src/text/text.h
@@ -109,12 +109,12 @@ txt_position(size_t tile_x, size_t tile_y) {
109// color merging issues. 109// color merging issues.
110static inline 110static inline
111void 111void
112txt_draws(char *msg, size_t x, size_t y, size_t spacing) { 112txt_draws(char *msg, size_t x, size_t y, size_t spacing, u8 clr) {
113 while (*msg) { 113 while (*msg) {
114 char c = *msg++; 114 char c = *msg++;
115 Tile *tile = FONT_DATA; 115 Tile *tile = FONT_DATA;
116 tile += c; 116 tile += c;
117 draw_tile(x, y, tile, true); 117 draw_tile(x, y, tile, clr, true);
118 x += spacing; 118 x += spacing;
119 } 119 }
120} 120}
@@ -129,11 +129,11 @@ txt_draws(char *msg, size_t x, size_t y, size_t spacing) {
129 129
130// Draws text to the screen with formatting starting on the x and y position and 130// Draws text to the screen with formatting starting on the x and y position and
131// with custom character spacing. 131// with custom character spacing.
132#define txt_drawf(msg, x, y, s, ...) \ 132#define txt_drawf(msg, x, y, s, c, ...) \
133 { \ 133 { \
134 char buf[256] = {0}; \ 134 char buf[256] = {0}; \
135 posprintf(buf, msg, ##__VA_ARGS__); \ 135 posprintf(buf, msg, ##__VA_ARGS__); \
136 txt_draws(buf, x, y, s); \ 136 txt_draws(buf, x, y, s, c); \
137 } 137 }
138 138
139#endif // TEXT_H 139#endif // TEXT_H