summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2021-05-04 14:40:38 +0200
committerBad Diode <bd@badd10de.dev>2021-05-04 14:40:38 +0200
commit0bf2a5a3f360f13d6195013a8e63b0519905202a (patch)
tree68b507898728b34f8c54c8f715e63c992cfa3841
parentff0e7f1442e0732f56fe5751fb13f15d415db14f (diff)
downloadgba-experiments-0bf2a5a3f360f13d6195013a8e63b0519905202a.tar.gz
gba-experiments-0bf2a5a3f360f13d6195013a8e63b0519905202a.zip
Update UI to enable channel selection
-rw-r--r--src/sequencer.c285
1 files changed, 212 insertions, 73 deletions
diff --git a/src/sequencer.c b/src/sequencer.c
index 0c6181f..ae06031 100644
--- a/src/sequencer.c
+++ b/src/sequencer.c
@@ -1,3 +1,20 @@
1// Positioning parameters.
2#define SEQ_TRIG_POS_X 45
3#define SEQ_TRIG_POS_Y 50
4#define SEQ_TRIG_DIST_X 18
5#define SEQ_TRIG_DIST_Y 28
6#define SEQ_CHANNEL_POS_X SEQ_TRIG_POS_X - 32
7#define SEQ_CHANNEL_POS_Y SEQ_TRIG_POS_Y
8#define SEQ_CHANNEL_DIST_Y 11
9#define SEQ_ENV_POS_X 10
10#define SEQ_ENV_POS_Y 10
11#define SEQ_ENV_DIST 32
12#define SEQ_DUTYCYCLE_POS_X SEQ_ENV_POS_X + SEQ_ENV_DIST * 3
13#define SEQ_DUTYCYCLE_POS_Y 10 - 8
14#define SEQ_SWEEP_POS_X SEQ_DUTYCYCLE_POS_X + SEQ_ENV_DIST
15#define SEQ_SWEEP_POS_Y SEQ_ENV_POS_Y
16#define SEQ_N_CHANNELS 2
17
1u32 sprite_note_names[] = { 18u32 sprite_note_names[] = {
2 0x000000e0, 0x202020e0, 0x0000000e, 0x080e020e, 19 0x000000e0, 0x202020e0, 0x0000000e, 0x080e020e,
3 0x00000098, 0xa8a8a898, 0x00000038, 0x203b0a39, 20 0x00000098, 0xa8a8a898, 0x00000038, 0x203b0a39,
@@ -223,6 +240,25 @@ u32 sprite_synth_param_selector[] = {
223 0x00000000, 0x00000000, 0x00000000, 0x00000000, 240 0x00000000, 0x00000000, 0x00000000, 0x00000000,
224}; 241};
225 242
243u32 sprite_channels[] = {
244 0xc0404040, 0x404040c0, 0xff005c44, 0xc45c00ff,
245 0xff002121, 0x212500ff, 0x03020202, 0x02020203,
246 0xc0404040, 0x404040c0, 0xff00aea2, 0xe2ae00ff,
247 0xff005050, 0x505200ff, 0x03020202, 0x02020203,
248 0xc0404040, 0x404040c0, 0xff005751, 0x715700ff,
249 0xff00a8a8, 0xa8a900ff, 0x03020202, 0x02020203,
250 0xc0404040, 0x404040c0, 0xff005751, 0x715700ff,
251 0xff00a8a8, 0xa8c900ff, 0x03020202, 0x02020203,
252 0xc0404040, 0x404040c0, 0xff007010, 0x301000ff,
253 0xff000507, 0x050500ff, 0x03020202, 0x02020203,
254};
255
256u32 sprite_channels_selector[] = {
257 0x70101000, 0x00000000, 0x00000000, 0x00000000,
258 0x00000000, 0x00000000, 0x0e080800, 0x00000000,
259 0x00101070, 0x00000000, 0x00000000, 0x00000000,
260 0x00000000, 0x00000000, 0x0008080e, 0x00000000,
261};
226 262
227typedef struct SeqTrigger { 263typedef struct SeqTrigger {
228 bool trigger; 264 bool trigger;
@@ -234,32 +270,39 @@ typedef struct SeqTrigger {
234 u8 sweep_number; 270 u8 sweep_number;
235 u8 sweep_time; 271 u8 sweep_time;
236 u8 sweep_direction; 272 u8 sweep_direction;
237 // TODO: ... 273 // TODO: Do we need other fields?
238} SeqTrigger; 274} SeqTrigger;
239 275
240static SeqTrigger sequence_synth[] = { 276static SeqTrigger sequence_synth[16] = {
241 {true , NOTE_D_4 , 0, 0, 0, 0, 0, 0, 0}, 277 {true, NOTE_C_4, 8, 4, 0, 2, 0, 0, 0},
242 {true , NOTE_F_4 , 1, 1, 0, 0, 1, 1, 0}, 278 {false, NOTE_C_4, 8, 4, 0, 2, 0, 0, 0},
243 {true , NOTE_A_4 , 2, 2, 0, 1, 2, 2, 1}, 279 {false, NOTE_C_4, 8, 4, 0, 2, 0, 0, 0},
244 {true , NOTE_C_5 , 3, 3, 0, 1, 3, 3, 1}, 280 {false, NOTE_C_4, 8, 4, 0, 2, 0, 0, 0},
245 281 {true, NOTE_C_4, 8, 4, 0, 2, 0, 0, 0},
246 {true , NOTE_D_4 , 4, 4, 1, 2, 4, 4, 0}, 282 {false, NOTE_C_4, 8, 4, 0, 2, 0, 0, 0},
247 {false , NOTE_C_SHARP_4 , 5, 5, 1, 2, 5, 5, 0}, 283 {false, NOTE_C_4, 8, 4, 0, 2, 0, 0, 0},
248 {false , NOTE_D_4 , 6, 6, 1, 3, 6, 6, 1}, 284 {false, NOTE_C_4, 8, 4, 0, 2, 0, 0, 0},
249 {false , NOTE_D_4 , 7, 7, 1, 3, 7, 7, 1}, 285 {true, NOTE_C_4, 8, 4, 0, 2, 0, 0, 0},
250 286 {false, NOTE_C_4, 8, 4, 0, 2, 0, 0, 0},
251 {true , NOTE_D_4 , 8, 0, 0, 0, 7, 0, 0}, 287 {false, NOTE_C_4, 8, 4, 0, 2, 0, 0, 0},
252 {true , NOTE_F_4 , 9, 1, 0, 0, 6, 1, 0}, 288 {false, NOTE_C_4, 8, 4, 0, 2, 0, 0, 0},
253 {true , NOTE_A_4 , 10, 2, 0, 1, 5, 2, 1}, 289 {true, NOTE_C_4, 8, 4, 0, 2, 0, 0, 0},
254 {true , NOTE_C_5 , 11, 3, 0, 1, 4, 3, 1}, 290 {false, NOTE_C_4, 8, 4, 0, 2, 0, 0, 0},
255 291 {false, NOTE_C_4, 8, 4, 0, 2, 0, 0, 0},
256 {true , NOTE_D_4 , 12, 4, 1, 2, 3, 4, 0}, 292 {false, NOTE_C_4, 8, 4, 0, 2, 0, 0, 0},
257 {false , NOTE_D_4 , 13, 5, 1, 2, 2, 5, 0},
258 {true , NOTE_A_4 , 14, 6, 1, 3, 1, 6, 1},
259 {false , NOTE_A_5 , 15, 7, 1, 3, 0, 7, 1},
260}; 293};
261 294
262static int bpm = 120; 295// TODO: Support for copy paste anything, contextual. If we are on trigger
296// selection mode, pressing the copy key (SELECT? SELECT+B?), all synth
297// parameters will be copied for that trigger. Pressing paste (SELECT+A?) will
298// update the params. This only works on compatible channels (Not on the wave
299// channel for example). If an entire channel is copied, all trigs in the
300// sequence will be copied. We can choose to copy only one of the parameters as
301// well or the note/duration.
302// TODO: Allow muting and unmuting channels. Show in grey when muted.
303// TODO: Show channel beat indicator if a note is being played.
304
305static int bpm = 180;
263static int step_counter = 0; 306static int step_counter = 0;
264static Note active_note; 307static Note active_note;
265 308
@@ -335,21 +378,15 @@ set_time(int bpm) {
335// - 048-048 sweep: direction indicator. 378// - 048-048 sweep: direction indicator.
336// - 049-049 sweep: sweep label. 379// - 049-049 sweep: sweep label.
337// - 050-050 synth parameter selector. 380// - 050-050 synth parameter selector.
381// - 051-051 channel 1.
382// - 052-052 channel 2.
383// - 053-053 channel 3.
384// - 054-054 channel 4.
385// - 055-055 RESERVED: FM synth?.
386// - 056-056 channel selector.
338// 387//
339 388
340 389
341// Positioning parameters.
342#define SEQ_TRIG_POS_X 45
343#define SEQ_TRIG_POS_Y 50
344#define SEQ_TRIG_DIST 20
345#define SEQ_ENV_POS_X 10
346#define SEQ_ENV_POS_Y 10
347#define SEQ_ENV_DIST 32
348#define SEQ_DUTYCYCLE_POS_X SEQ_ENV_POS_X + SEQ_ENV_DIST * 3
349#define SEQ_DUTYCYCLE_POS_Y 10 - 8
350#define SEQ_SWEEP_POS_X SEQ_DUTYCYCLE_POS_X + SEQ_ENV_DIST
351#define SEQ_SWEEP_POS_Y SEQ_ENV_POS_Y
352
353size_t obj_counter = 0; 390size_t obj_counter = 0;
354 391
355typedef struct SeqSprite { 392typedef struct SeqSprite {
@@ -365,14 +402,16 @@ typedef struct SeqSprite {
365 402
366typedef enum { 403typedef enum {
367 SEQ_SELECT_TRIGGER, 404 SEQ_SELECT_TRIGGER,
405 SEQ_SELECT_CHANNEL,
368 SEQ_SELECT_PARAMETER, 406 SEQ_SELECT_PARAMETER,
369} SeqSelect; 407} SeqSelect;
370 408
371int trig_selection_loc = 0; 409int trig_selection_loc = 0;
372int param_selection_loc = 0; 410int param_selection_loc = 0;
411int channel_selection_loc = 0;
373SeqSelect current_selection = SEQ_SELECT_TRIGGER; 412SeqSelect current_selection = SEQ_SELECT_TRIGGER;
374 413
375SeqSprite seq_sprites[51] = {0}; 414SeqSprite seq_sprites[57] = {0};
376 415
377void 416void
378init_sequencer_sprites(void) { 417init_sequencer_sprites(void) {
@@ -386,12 +425,12 @@ init_sequencer_sprites(void) {
386 // Sprite note names. 425 // Sprite note names.
387 size_t sprite_id = load_packed_sprite_data(&sprite_note_names, 2, 73); 426 size_t sprite_id = load_packed_sprite_data(&sprite_note_names, 2, 73);
388 for (size_t i = 0; i < 16; ++i) { 427 for (size_t i = 0; i < 16; ++i) {
389 int x = SEQ_TRIG_POS_X + i * SEQ_TRIG_DIST; 428 int x = SEQ_TRIG_POS_X + i * SEQ_TRIG_DIST_X;
390 int y = SEQ_TRIG_POS_Y; 429 int y = SEQ_TRIG_POS_Y;
391 int base_tile = sprites[sprite_id].tile_start; 430 int base_tile = sprites[sprite_id].tile_start;
392 if (i >= 8) { 431 if (i >= 8) {
393 y += 32; 432 y += SEQ_TRIG_DIST_Y;
394 x -= 8 * SEQ_TRIG_DIST; 433 x -= 8 * SEQ_TRIG_DIST_X;
395 } 434 }
396 seq_sprites[i].x = x; 435 seq_sprites[i].x = x;
397 seq_sprites[i].y = y; 436 seq_sprites[i].y = y;
@@ -406,12 +445,12 @@ init_sequencer_sprites(void) {
406 // Trigger boxes. 445 // Trigger boxes.
407 sprite_id = load_packed_sprite_data(&sprite_trigger_button, 8, 1); 446 sprite_id = load_packed_sprite_data(&sprite_trigger_button, 8, 1);
408 for (size_t i = 0; i < 16; ++i) { 447 for (size_t i = 0; i < 16; ++i) {
409 int x = SEQ_TRIG_POS_X + i * SEQ_TRIG_DIST; 448 int x = SEQ_TRIG_POS_X + i * SEQ_TRIG_DIST_X;
410 int y = SEQ_TRIG_POS_Y; 449 int y = SEQ_TRIG_POS_Y;
411 int base_tile = sprites[sprite_id].tile_start; 450 int base_tile = sprites[sprite_id].tile_start;
412 if (i >= 8) { 451 if (i >= 8) {
413 y += 32; 452 y += 28;
414 x -= 8 * SEQ_TRIG_DIST; 453 x -= 8 * SEQ_TRIG_DIST_X;
415 } 454 }
416 seq_sprites[i + 16].id = obj_counter++; 455 seq_sprites[i + 16].id = obj_counter++;
417 seq_sprites[i + 16].base_tile = base_tile; 456 seq_sprites[i + 16].base_tile = base_tile;
@@ -434,12 +473,12 @@ init_sequencer_sprites(void) {
434 473
435 sprite_id = load_packed_sprite_data(&sprite_trigger_selection, 16, 1); 474 sprite_id = load_packed_sprite_data(&sprite_trigger_selection, 16, 1);
436 { 475 {
437 int x = SEQ_TRIG_POS_X - 1 + trig_selection_loc * SEQ_TRIG_DIST; 476 int x = SEQ_TRIG_POS_X - 1 + trig_selection_loc * SEQ_TRIG_DIST_X;
438 int y = SEQ_TRIG_POS_Y - 2; 477 int y = SEQ_TRIG_POS_Y - 2;
439 int base_tile = sprites[sprite_id].tile_start; 478 int base_tile = sprites[sprite_id].tile_start;
440 if (trig_selection_loc >= 8) { 479 if (trig_selection_loc >= 8) {
441 y += 32; 480 y += SEQ_TRIG_DIST_Y;
442 x -= 8 * SEQ_TRIG_DIST; 481 x -= 8 * SEQ_TRIG_DIST_X;
443 } 482 }
444 seq_sprites[33].id = obj_counter++; 483 seq_sprites[33].id = obj_counter++;
445 seq_sprites[33].base_tile = base_tile; 484 seq_sprites[33].base_tile = base_tile;
@@ -643,6 +682,72 @@ init_sequencer_sprites(void) {
643 seq_sprites[50].obj_attr_1 = OBJ_SIZE_BIG | OBJ_X_COORD(x); 682 seq_sprites[50].obj_attr_1 = OBJ_SIZE_BIG | OBJ_X_COORD(x);
644 seq_sprites[50].obj_attr_2 = base_tile | OBJ_PAL_BANK(2); 683 seq_sprites[50].obj_attr_2 = base_tile | OBJ_PAL_BANK(2);
645 } 684 }
685
686 sprite_id = load_packed_sprite_data(&sprite_channels, 4, 5);
687 {
688 int x = SEQ_CHANNEL_POS_X;
689 int y = SEQ_CHANNEL_POS_Y;
690 int base_tile = sprites[sprite_id].tile_start;
691 seq_sprites[51].id = obj_counter++;
692 seq_sprites[51].base_tile = base_tile;
693 seq_sprites[51].obj_attr_0 = OBJ_SHAPE_WIDE | OBJ_Y_COORD(y);
694 seq_sprites[51].obj_attr_1 = OBJ_SIZE_MID | OBJ_X_COORD(x);
695 seq_sprites[51].obj_attr_2 = base_tile | OBJ_PAL_BANK(0);
696 }
697 {
698 int x = SEQ_CHANNEL_POS_X;
699 int y = SEQ_CHANNEL_POS_Y + SEQ_CHANNEL_DIST_Y;
700 int base_tile = sprites[sprite_id].tile_start + 4;
701 seq_sprites[52].id = obj_counter++;
702 seq_sprites[52].base_tile = base_tile;
703 seq_sprites[52].obj_attr_0 = OBJ_SHAPE_WIDE | OBJ_Y_COORD(y);
704 seq_sprites[52].obj_attr_1 = OBJ_SIZE_MID | OBJ_X_COORD(x);
705 seq_sprites[52].obj_attr_2 = base_tile | OBJ_PAL_BANK(0);
706 }
707 {
708 int x = SEQ_CHANNEL_POS_X;
709 int y = SEQ_CHANNEL_POS_Y + SEQ_CHANNEL_DIST_Y * 2;
710 int base_tile = sprites[sprite_id].tile_start + 8;
711 seq_sprites[53].id = obj_counter++;
712 seq_sprites[53].base_tile = base_tile;
713 seq_sprites[53].obj_attr_0 = OBJ_SHAPE_WIDE | OBJ_Y_COORD(y) | OBJ_HIDDEN;
714 seq_sprites[53].obj_attr_1 = OBJ_SIZE_MID | OBJ_X_COORD(x);
715 seq_sprites[53].obj_attr_2 = base_tile | OBJ_PAL_BANK(0);
716 }
717 {
718 int x = SEQ_CHANNEL_POS_X;
719 int y = SEQ_CHANNEL_POS_Y + SEQ_CHANNEL_DIST_Y * 3;
720 int base_tile = sprites[sprite_id].tile_start + 12;
721 seq_sprites[54].id = obj_counter++;
722 seq_sprites[54].base_tile = base_tile;
723 seq_sprites[54].obj_attr_0 = OBJ_SHAPE_WIDE | OBJ_Y_COORD(y) | OBJ_HIDDEN;
724 seq_sprites[54].obj_attr_1 = OBJ_SIZE_MID | OBJ_X_COORD(x);
725 seq_sprites[54].obj_attr_2 = base_tile | OBJ_PAL_BANK(0);
726 }
727 {
728 int x = SEQ_CHANNEL_POS_X;
729 int y = SEQ_CHANNEL_POS_Y + SEQ_CHANNEL_DIST_Y * 4;
730 int base_tile = sprites[sprite_id].tile_start + 16;
731 seq_sprites[55].id = obj_counter++;
732 seq_sprites[55].base_tile = base_tile;
733 seq_sprites[55].obj_attr_0 = OBJ_SHAPE_WIDE | OBJ_Y_COORD(y) | OBJ_HIDDEN;
734 seq_sprites[55].obj_attr_1 = OBJ_SIZE_MID | OBJ_X_COORD(x);
735 seq_sprites[55].obj_attr_2 = base_tile | OBJ_PAL_BANK(0);
736 }
737
738 sprite_id = load_packed_sprite_data(&sprite_channels_selector, 8, 1);
739 {
740 int x = SEQ_CHANNEL_POS_X;
741 int y = SEQ_CHANNEL_POS_Y - 2;
742 int base_tile = sprites[sprite_id].tile_start;
743 seq_sprites[56].id = obj_counter++;
744 seq_sprites[56].base_tile = base_tile;
745 // TODO: Start hidden.
746 // seq_sprites[55].obj_attr_0 = OBJ_SHAPE_WIDE | OBJ_Y_COORD(y) | OBJ_HIDDEN;
747 seq_sprites[56].obj_attr_0 = OBJ_SHAPE_WIDE | OBJ_Y_COORD(y);
748 seq_sprites[56].obj_attr_1 = OBJ_SIZE_BIG | OBJ_X_COORD(x);
749 seq_sprites[56].obj_attr_2 = base_tile | OBJ_PAL_BANK(2);
750 }
646} 751}
647 752
648void 753void
@@ -666,11 +771,11 @@ update_sequencer_sprites(void) {
666 771
667 // 33: Sequence indicator. 772 // 33: Sequence indicator.
668 { 773 {
669 int x = SEQ_TRIG_POS_X + step_counter * SEQ_TRIG_DIST + 3; 774 int x = SEQ_TRIG_POS_X + step_counter * SEQ_TRIG_DIST_X + 3;
670 int y = SEQ_TRIG_POS_Y + 15; 775 int y = SEQ_TRIG_POS_Y + 15;
671 if (step_counter >= 8) { 776 if (step_counter >= 8) {
672 y += 32; 777 y += SEQ_TRIG_DIST_Y;
673 x -= 8 * SEQ_TRIG_DIST; 778 x -= 8 * SEQ_TRIG_DIST_X;
674 } 779 }
675 seq_sprites[32].obj_attr_0 = OBJ_SHAPE_SQUARE | OBJ_Y_COORD(y); // TODO: Mask and update instead. 780 seq_sprites[32].obj_attr_0 = OBJ_SHAPE_SQUARE | OBJ_Y_COORD(y); // TODO: Mask and update instead.
676 seq_sprites[32].obj_attr_1 = OBJ_SIZE_SMALL | OBJ_X_COORD(x); // TODO: Mask and update instead. 781 seq_sprites[32].obj_attr_1 = OBJ_SIZE_SMALL | OBJ_X_COORD(x); // TODO: Mask and update instead.
@@ -678,13 +783,20 @@ update_sequencer_sprites(void) {
678 783
679 // 34: Trigger selection. 784 // 34: Trigger selection.
680 { 785 {
681 int x = SEQ_TRIG_POS_X - 1 + trig_selection_loc * SEQ_TRIG_DIST; 786 int x = SEQ_TRIG_POS_X - 1 + trig_selection_loc * SEQ_TRIG_DIST_X;
682 int y = SEQ_TRIG_POS_Y - 2; 787 int y = SEQ_TRIG_POS_Y - 2;
683 if (trig_selection_loc >= 8) { 788 if (trig_selection_loc >= 8) {
684 y += 32; 789 y += SEQ_TRIG_DIST_Y;
685 x -= 8 * SEQ_TRIG_DIST; 790 x -= 8 * SEQ_TRIG_DIST_X;
791 }
792 if (current_selection == SEQ_SELECT_TRIGGER
793 || current_selection == SEQ_SELECT_PARAMETER) {
794 seq_sprites[33].obj_attr_0 = OBJ_SHAPE_SQUARE | OBJ_Y_COORD(y);
795 } else {
796 seq_sprites[33].obj_attr_0 = OBJ_SHAPE_SQUARE
797 | OBJ_Y_COORD(y)
798 | OBJ_HIDDEN;
686 } 799 }
687 seq_sprites[33].obj_attr_0 = OBJ_SHAPE_SQUARE | OBJ_Y_COORD(y);
688 seq_sprites[33].obj_attr_1 = OBJ_SIZE_BIG | OBJ_X_COORD(x); 800 seq_sprites[33].obj_attr_1 = OBJ_SIZE_BIG | OBJ_X_COORD(x);
689 int base_tile = seq_sprites[33].base_tile; 801 int base_tile = seq_sprites[33].base_tile;
690 if (current_selection == SEQ_SELECT_TRIGGER) { 802 if (current_selection == SEQ_SELECT_TRIGGER) {
@@ -757,10 +869,6 @@ update_sequencer_sprites(void) {
757 { 869 {
758 int x = SEQ_ENV_POS_X + 1 + (param_selection_loc % 7) * SEQ_ENV_DIST; 870 int x = SEQ_ENV_POS_X + 1 + (param_selection_loc % 7) * SEQ_ENV_DIST;
759 int y = SEQ_ENV_POS_Y - 3; 871 int y = SEQ_ENV_POS_Y - 3;
760 if (param_selection_loc >= 8) {
761 y += 32;
762 x -= 8 * SEQ_TRIG_DIST;
763 }
764 int hidden = 0; 872 int hidden = 0;
765 if (current_selection != SEQ_SELECT_PARAMETER) { 873 if (current_selection != SEQ_SELECT_PARAMETER) {
766 hidden = OBJ_HIDDEN; 874 hidden = OBJ_HIDDEN;
@@ -768,40 +876,52 @@ update_sequencer_sprites(void) {
768 seq_sprites[50].obj_attr_0 = OBJ_SHAPE_SQUARE | OBJ_Y_COORD(y) | hidden; 876 seq_sprites[50].obj_attr_0 = OBJ_SHAPE_SQUARE | OBJ_Y_COORD(y) | hidden;
769 seq_sprites[50].obj_attr_1 = OBJ_SIZE_BIG | OBJ_X_COORD(x); 877 seq_sprites[50].obj_attr_1 = OBJ_SIZE_BIG | OBJ_X_COORD(x);
770 } 878 }
879
880 // 57: Parameter selector.
881 {
882 int x = SEQ_CHANNEL_POS_X;
883 int y = SEQ_CHANNEL_POS_Y - 2;
884 y += (channel_selection_loc % SEQ_N_CHANNELS * SEQ_CHANNEL_DIST_Y);
885 seq_sprites[56].obj_attr_0 = OBJ_SHAPE_SQUARE | OBJ_Y_COORD(y);
886 seq_sprites[56].obj_attr_1 = OBJ_SIZE_BIG | OBJ_X_COORD(x);
887 int base_tile = seq_sprites[56].base_tile;
888 if (current_selection == SEQ_SELECT_CHANNEL) {
889 seq_sprites[56].obj_attr_2 = base_tile | OBJ_PAL_BANK(2);
890 } else {
891 seq_sprites[56].obj_attr_2 = base_tile | OBJ_PAL_BANK(3);
892 }
893 }
771} 894}
772 895
773void 896void
774handle_sequencer_input(void) { 897handle_sequencer_input(void) {
775 if (current_selection == SEQ_SELECT_TRIGGER) { 898 if (current_selection == SEQ_SELECT_TRIGGER) {
776 if (key_pressed(KEY_LEFT)) { 899 if (key_pressed(KEY_LEFT)) {
777 if (trig_selection_loc == 0) { 900 if (trig_selection_loc == 0 || trig_selection_loc == 8) {
778 trig_selection_loc = 15; 901 current_selection = SEQ_SELECT_CHANNEL;
779 } else { 902 } else {
780 trig_selection_loc = CLAMP(trig_selection_loc - 1, 0, 15); 903 trig_selection_loc = CLAMP(trig_selection_loc - 1, 0, 15);
781 } 904 }
782 } 905 } else if (key_pressed(KEY_RIGHT)) {
783 if (key_pressed(KEY_RIGHT)) {
784 if (trig_selection_loc == 15) { 906 if (trig_selection_loc == 15) {
785 trig_selection_loc = 0; 907 trig_selection_loc = 0;
786 } else { 908 } else {
787 trig_selection_loc = CLAMP(trig_selection_loc + 1, 0, 15); 909 trig_selection_loc = CLAMP(trig_selection_loc + 1, 0, 15);
788 } 910 }
789 } 911 } else if (key_pressed(KEY_UP) || key_pressed(KEY_DOWN)) {
790 if (key_pressed(KEY_UP) || key_pressed(KEY_DOWN)) {
791 trig_selection_loc = (trig_selection_loc + 8) % 16; 912 trig_selection_loc = (trig_selection_loc + 8) % 16;
792 } 913 } else if (key_pressed(KEY_B)) {
793 if (key_pressed(KEY_B)) {
794 sequence_synth[trig_selection_loc].trigger ^= 1; 914 sequence_synth[trig_selection_loc].trigger ^= 1;
795 } 915 } else if (key_pressed(KEY_L)) {
796 if (key_pressed(KEY_L)) { 916 sequence_synth[trig_selection_loc].note = CLAMP(
797 sequence_synth[trig_selection_loc].note = CLAMP(sequence_synth[trig_selection_loc].note - 1, NOTE_C_2, NOTE_C_8); 917 sequence_synth[trig_selection_loc].note - 1,
798 } 918 NOTE_C_2, NOTE_C_8);
799 if (key_pressed(KEY_R)) { 919 } else if (key_pressed(KEY_R)) {
800 sequence_synth[trig_selection_loc].note = CLAMP(sequence_synth[trig_selection_loc].note + 1, NOTE_C_2, NOTE_C_8); 920 sequence_synth[trig_selection_loc].note = CLAMP(
801 } 921 sequence_synth[trig_selection_loc].note + 1,
802 922 NOTE_C_2, NOTE_C_8);
803 // Switch to parameter selection. 923 } else if (key_pressed(KEY_A)) {
804 if (key_pressed(KEY_A)) { 924 // Switch to parameter selection.
805 current_selection = SEQ_SELECT_PARAMETER; 925 current_selection = SEQ_SELECT_PARAMETER;
806 } 926 }
807 } else if (current_selection == SEQ_SELECT_PARAMETER) { 927 } else if (current_selection == SEQ_SELECT_PARAMETER) {
@@ -896,6 +1016,25 @@ handle_sequencer_input(void) {
896 if (key_pressed(KEY_B)) { 1016 if (key_pressed(KEY_B)) {
897 sequence_synth[trig_selection_loc].trigger ^= 1; 1017 sequence_synth[trig_selection_loc].trigger ^= 1;
898 } 1018 }
1019 } else if (current_selection == SEQ_SELECT_CHANNEL) {
1020 if (key_pressed(KEY_RIGHT)) {
1021 current_selection = SEQ_SELECT_TRIGGER;
1022 trig_selection_loc = 0;
1023 }
1024 if (key_pressed(KEY_UP)) {
1025 if (channel_selection_loc == 0) {
1026 channel_selection_loc = 3;
1027 } else {
1028 channel_selection_loc = CLAMP(channel_selection_loc - 1, 0, 6);
1029 }
1030 }
1031 if (key_pressed(KEY_DOWN)) {
1032 if (channel_selection_loc == 3) {
1033 channel_selection_loc = 0;
1034 } else {
1035 channel_selection_loc = CLAMP(channel_selection_loc + 1, 0, 6);
1036 }
1037 }
899 } 1038 }
900 1039
901 if (key_pressed(KEY_START)) { 1040 if (key_pressed(KEY_START)) {