From fc16837ded8df8ffe7ba77dc0e2387d7af3ddde2 Mon Sep 17 00:00:00 2001 From: Bad Diode Date: Sun, 2 May 2021 18:10:20 +0200 Subject: Add UI elements for envelope filter per trig --- src/common.h | 2 +- src/sequencer.c | 174 +++++++++++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 148 insertions(+), 28 deletions(-) diff --git a/src/common.h b/src/common.h index ece94cd..b688711 100644 --- a/src/common.h +++ b/src/common.h @@ -594,7 +594,7 @@ sound_volume(SoundChannel channels, u8 volume) { #define SOUND_SQUARE_LEN(N) (N) #define SOUND_SQUARE_DUTY(N) ((N) << 0x6) #define SOUND_SQUARE_ENV_TIME(N) ((N) << 0x8) -#define SOUND_SQUARE_ENV_INC (1 << 0xB) +#define SOUND_SQUARE_ENV_INC(N) ((N) << 0xB) #define SOUND_SQUARE_ENV_VOL(N) ((N) << 0xC) // DMG square frequency bits. diff --git a/src/sequencer.c b/src/sequencer.c index 39f083f..f76b0f8 100644 --- a/src/sequencer.c +++ b/src/sequencer.c @@ -99,12 +99,26 @@ u32 sprite_trigger_selection[] = { 0x04040407, 0x00000000, 0x00000000, 0x00000000, }; -u32 sprite_env_labels[] = { - // Volume. +u32 sprite_env_label_volume[] = { 0xa0a0a0a0, 0xc0000000, 0x262a2a2a, 0xee000000, 0xaaeaaaaa, 0xae000000, 0x0e020602, 0x0e000000, }; +u32 sprite_env_label_time[] = { + 0x00000000, 0x00000000, 0xee444444, 0xe4000000, + 0xea2e6a2a, 0xea000000, 0x00000000, 0x00000000, +}; + +u32 sprite_env_label_direction[] = { + 0x00000000, 0x00000000, 0xcc949494, 0xcc000000, + 0x1d140cd4, 0xd5000000, 0x00000000, 0x00000000, +}; + +u32 sprite_env_label_env[] = { + 0x6ea2a6a2, 0xae000000, 0xea2a6a2a, 0xec000000, + 0x62a2a2a2, 0xee000000, 0xee2a6e22, 0xe2000000, +}; + u32 sprite_env_volume[] = { 0x80808080, 0x80808000, 0x0f0c0c0c, 0x0c6c6f00, 0x1f999919, 0x19999f00, 0x00090d06, 0x030d0c00, @@ -140,33 +154,61 @@ u32 sprite_env_volume[] = { 0xf0909090, 0x9096f600, 0x0199d961, 0x31d9c900, }; +u32 sprite_env_time[] = { + 0x80808080, 0x80808000, 0x0f0c0c0c, 0x0c6c6f00, + 0x1f999919, 0x19999f00, 0x00090d06, 0x030d0c00, + 0x60606060, 0x60606000, 0x181c1a19, 0x1fd8d800, + 0x3e30303c, 0x30303e00, 0x00131b0c, 0x061b1900, + 0xf8c0c0f8, 0x1818f800, 0x3e32323e, 0x32b2be00, + 0x7c0c0c7c, 0x4c4d7d00, 0x00263618, 0x0c363200, + 0xc0e0d0c8, 0xf8c0c000, 0x3e30303e, 0x0686be00, + 0x7c64647c, 0x60617d00, 0x00263618, 0x0c363200, + 0xe06060e0, 0x0000e000, 0xfbc0c063, 0x331b1b00, + 0x30303030, 0x30363600, 0x00131b0c, 0x061b1900, + 0xe0000080, 0xc0606000, 0x1b1b1b19, 0x18d8d800, + 0x30383432, 0x3e303000, 0x00131b0c, 0x061b1900, + 0xf8c8c8f8, 0xc8c8f800, 0x3e06063e, 0x30b0be00, + 0x7c606030, 0x180d0d00, 0x00263618, 0x0c363200, + 0xec2c2c2c, 0x2c2cec00, 0xfbcbcbcb, 0xcbcbfb00, + 0xf0909090, 0x9096f600, 0x0199d961, 0x31d9c900, +}; + +u32 sprite_env_sweep_direction[] = { + 0x00000000, 0x00000000, 0xc8c8c8c8, 0xc8c8f800, + 0x3e32323e, 0x02020200, 0x00000000, 0x00000000, + 0xe0202020, 0x2020e000, 0x71cbcbcb, 0xcbcb7100, + 0xb2b2b2b2, 0xb2ba9400, 0x0d0f0e0c, 0x0c0c0c00, +}; + typedef struct SeqTrigger { bool trigger; Note note; u8 env_volume; + u8 env_time; + u8 env_direction; // TODO: ... } SeqTrigger; static SeqTrigger sequence_synth[] = { - {true, NOTE_D_4, 0}, - {true, NOTE_F_4, 1}, - {true, NOTE_A_4, 2}, - {true, NOTE_C_5, 3}, - - {true, NOTE_D_4, 4}, - {false, NOTE_C_SHARP_4, 5}, - {false, NOTE_D_4, 6}, - {false, NOTE_D_4, 7}, - - {true, NOTE_D_4, 8}, - {true, NOTE_F_4, 9}, - {true, NOTE_A_4, 10}, - {true, NOTE_C_5, 11}, - - {true, NOTE_D_4, 12}, - {false, NOTE_D_4, 13}, - {true, NOTE_A_4, 14}, - {false, NOTE_A_5, 15}, + {true , NOTE_D_4 , 0, 0, 0}, + {true , NOTE_F_4 , 1, 1, 0}, + {true , NOTE_A_4 , 2, 2, 0}, + {true , NOTE_C_5 , 3, 3, 0}, + + {true , NOTE_D_4 , 4, 4, 1}, + {false , NOTE_C_SHARP_4 , 5, 5, 1}, + {false , NOTE_D_4 , 6, 6, 1}, + {false , NOTE_D_4 , 7, 7, 1}, + + {true , NOTE_D_4 , 8, 0, 0}, + {true , NOTE_F_4 , 9, 1, 0}, + {true , NOTE_A_4 , 10, 2, 0}, + {true , NOTE_C_5 , 11, 3, 0}, + + {true , NOTE_D_4 , 12, 4, 1}, + {false , NOTE_D_4 , 13, 5, 1}, + {true , NOTE_A_4 , 14, 6, 1}, + {false , NOTE_A_5 , 15, 7, 1}, }; static int bpm = 120; @@ -179,7 +221,8 @@ irq_timer_0(void) { active_note = trig->note; if (trig->trigger) { SOUND_SQUARE1_CTRL = SOUND_SQUARE_ENV_VOL(trig->env_volume) - | SOUND_SQUARE_ENV_TIME(4) + | SOUND_SQUARE_ENV_TIME(trig->env_time) + | SOUND_SQUARE_ENV_INC(trig->env_direction) | SOUND_SQUARE_DUTY(2); SOUND_SQUARE1_FREQ = SOUND_SQUARE_RESET | sound_rates[active_note]; } @@ -222,6 +265,8 @@ set_time(int bpm) { // - 033-033 trigger selection indicator. // - 034-034 envelope: volume label. // - 035-0xx envelope: volume indicator. +// - 0xx-0xx envelope: time label. +// - 0xx-0xx envelope: time indicator. // @@ -231,6 +276,7 @@ set_time(int bpm) { #define SEQ_TRIG_DIST 20 #define SEQ_ENV_POS_X 10 #define SEQ_ENV_POS_Y 10 +#define SEQ_ENV_DIST 34 size_t obj_counter = 0; @@ -246,7 +292,7 @@ typedef struct SeqSprite { int trig_selection_loc = 1; -SeqSprite seq_sprites[36] = {0}; +SeqSprite seq_sprites[41] = {0}; void init_sequencer_sprites(void) { @@ -265,9 +311,7 @@ init_sequencer_sprites(void) { seq_sprites[i].id = obj_counter++; seq_sprites[i].base_tile = base_tile; - seq_sprites[i].obj_attr_0 = OBJ_SHAPE_WIDE | OBJ_Y_COORD(y); - // TODO: They should start hidden until the update function changes that. - // seq_sprites[i].obj_attr_0 = OBJ_SHAPE_WIDE | OBJ_HIDDEN; + seq_sprites[i].obj_attr_0 = OBJ_SHAPE_WIDE | OBJ_HIDDEN | OBJ_Y_COORD(y); seq_sprites[i].obj_attr_1 = OBJ_SIZE_SMALL | OBJ_X_COORD(x); seq_sprites[i].obj_attr_2 = base_tile; } @@ -317,7 +361,7 @@ init_sequencer_sprites(void) { seq_sprites[33].obj_attr_2 = base_tile | OBJ_PAL_BANK(2); } - sprite_id = load_packed_sprite_data(&sprite_env_labels, 4, 1); + sprite_id = load_packed_sprite_data(&sprite_env_label_volume, 4, 1); { int x = SEQ_ENV_POS_X; int y = SEQ_ENV_POS_Y; @@ -340,6 +384,66 @@ init_sequencer_sprites(void) { seq_sprites[35].obj_attr_1 = OBJ_SIZE_MID | OBJ_X_COORD(x); seq_sprites[35].obj_attr_2 = base_tile | OBJ_PAL_BANK(2); } + + sprite_id = load_packed_sprite_data(&sprite_env_label_time, 4, 1); + { + int x = SEQ_ENV_POS_X + SEQ_ENV_DIST; + int y = SEQ_ENV_POS_Y; + int base_tile = sprites[sprite_id].tile_start; + seq_sprites[36].id = obj_counter++; + seq_sprites[36].base_tile = base_tile; + seq_sprites[36].obj_attr_0 = OBJ_SHAPE_WIDE | OBJ_Y_COORD(y); + seq_sprites[36].obj_attr_1 = OBJ_SIZE_MID | OBJ_X_COORD(x); + seq_sprites[36].obj_attr_2 = base_tile | OBJ_PAL_BANK(2); + } + + sprite_id = load_packed_sprite_data(&sprite_env_time, 4, 8); + { + int x = SEQ_ENV_POS_X + SEQ_ENV_DIST; + int y = SEQ_ENV_POS_Y + 8; + int base_tile = sprites[sprite_id].tile_start; + seq_sprites[37].id = obj_counter++; + seq_sprites[37].base_tile = base_tile; + seq_sprites[37].obj_attr_0 = OBJ_SHAPE_WIDE | OBJ_Y_COORD(y); + seq_sprites[37].obj_attr_1 = OBJ_SIZE_MID | OBJ_X_COORD(x); + seq_sprites[37].obj_attr_2 = base_tile | OBJ_PAL_BANK(2); + } + + sprite_id = load_packed_sprite_data(&sprite_env_label_direction, 4, 1); + { + int x = SEQ_ENV_POS_X + SEQ_ENV_DIST * 2; + int y = SEQ_ENV_POS_Y; + int base_tile = sprites[sprite_id].tile_start; + seq_sprites[38].id = obj_counter++; + seq_sprites[38].base_tile = base_tile; + seq_sprites[38].obj_attr_0 = OBJ_SHAPE_WIDE | OBJ_Y_COORD(y); + seq_sprites[38].obj_attr_1 = OBJ_SIZE_MID | OBJ_X_COORD(x); + seq_sprites[38].obj_attr_2 = base_tile | OBJ_PAL_BANK(2); + } + + sprite_id = load_packed_sprite_data(&sprite_env_sweep_direction, 4, 2); + { + int x = SEQ_ENV_POS_X + SEQ_ENV_DIST * 2; + int y = SEQ_ENV_POS_Y + 8; + int base_tile = sprites[sprite_id].tile_start; + seq_sprites[39].id = obj_counter++; + seq_sprites[39].base_tile = base_tile; + seq_sprites[39].obj_attr_0 = OBJ_SHAPE_WIDE | OBJ_Y_COORD(y); + seq_sprites[39].obj_attr_1 = OBJ_SIZE_MID | OBJ_X_COORD(x); + seq_sprites[39].obj_attr_2 = base_tile | OBJ_PAL_BANK(2); + } + + sprite_id = load_packed_sprite_data(&sprite_env_label_env, 4, 1); + { + int x = SEQ_ENV_POS_X + SEQ_ENV_DIST; + int y = SEQ_ENV_POS_Y - 8; + int base_tile = sprites[sprite_id].tile_start; + seq_sprites[40].id = obj_counter++; + seq_sprites[40].base_tile = base_tile; + seq_sprites[40].obj_attr_0 = OBJ_SHAPE_WIDE | OBJ_Y_COORD(y); + seq_sprites[40].obj_attr_1 = OBJ_SIZE_MID | OBJ_X_COORD(x); + seq_sprites[40].obj_attr_2 = base_tile | OBJ_PAL_BANK(2); + } } void @@ -393,6 +497,22 @@ update_sequencer_sprites(void) { size_t tile = base_tile + tile_diff; seq_sprites[35].obj_attr_2 = tile | OBJ_PAL_BANK(2); } + + // 38: Envelope initial volume + { + size_t tile_diff = sequence_synth[trig_selection_loc].env_time * 4; + size_t base_tile = seq_sprites[37].base_tile; + size_t tile = base_tile + tile_diff; + seq_sprites[37].obj_attr_2 = tile | OBJ_PAL_BANK(2); + } + + // 40: Envelope initial volume + { + size_t tile_diff = sequence_synth[trig_selection_loc].env_direction * 4; + size_t base_tile = seq_sprites[39].base_tile; + size_t tile = base_tile + tile_diff; + seq_sprites[39].obj_attr_2 = tile | OBJ_PAL_BANK(2); + } } void -- cgit v1.2.1