diff options
author | Bad Diode <bd@badd10de.dev> | 2021-05-07 18:55:12 +0200 |
---|---|---|
committer | Bad Diode <bd@badd10de.dev> | 2021-05-07 18:55:12 +0200 |
commit | 269f2326171982912f50c2b6ef0cd272ec3c0108 (patch) | |
tree | b9374201762337780bafaf8f01965bb338a505ec | |
parent | c1ac9aa30fa1c33ac09963bdb2f6a42ffadaa6c8 (diff) | |
download | gba-experiments-269f2326171982912f50c2b6ef0cd272ec3c0108.tar.gz gba-experiments-269f2326171982912f50c2b6ef0cd272ec3c0108.zip |
Initial implementation of mode4 rendering and parameter editing on CH3
-rw-r--r-- | src/bitmap.h | 64 | ||||
-rw-r--r-- | src/common.h | 2 | ||||
-rw-r--r-- | src/main.c | 7 | ||||
-rw-r--r-- | src/sequencer.c | 368 | ||||
-rw-r--r-- | src/text.h | 10 |
5 files changed, 253 insertions, 198 deletions
diff --git a/src/bitmap.h b/src/bitmap.h index bae9b40..c839900 100644 --- a/src/bitmap.h +++ b/src/bitmap.h | |||
@@ -1,30 +1,8 @@ | |||
1 | #ifndef GBAEXP_BITMAP_H | 1 | #ifndef GBAEXP_BITMAP_H |
2 | #define GBAEXP_BITMAP_H | 2 | #define GBAEXP_BITMAP_H |
3 | 3 | ||
4 | // #include "bd-font.c" | ||
5 | #include "common.h" | 4 | #include "common.h" |
6 | 5 | ||
7 | // Using bd-font, an 8x8 bitmap font. | ||
8 | // static void | ||
9 | // put_char(int x, int y, Color clr, u8 chr) { | ||
10 | // for (size_t i = 0; i < 8; ++i) { | ||
11 | // for (size_t j = 0; j < 8; ++j) { | ||
12 | // if ((font[chr][i] >> (7 - j)) & 0x1) { | ||
13 | // FRAMEBUFFER[y + i][x + j] = clr; | ||
14 | // } | ||
15 | // } | ||
16 | // } | ||
17 | // } | ||
18 | |||
19 | // static void | ||
20 | // put_text(int x, int y, Color clr, char *msg) { | ||
21 | // int count = 0; | ||
22 | // while (*msg) { | ||
23 | // put_char(x + count, y, clr, *msg++); | ||
24 | // count += 8; | ||
25 | // } | ||
26 | // } | ||
27 | |||
28 | // Draws a line with the given color between (x0,y0) and (x1,y1) using the | 6 | // Draws a line with the given color between (x0,y0) and (x1,y1) using the |
29 | // Bresenham's line drawing algorithm using exclusively integer arithmetic. | 7 | // Bresenham's line drawing algorithm using exclusively integer arithmetic. |
30 | static void | 8 | static void |
@@ -146,17 +124,31 @@ draw_fill_rect(int x0, int y0, int x1, int y1, Color clr) { | |||
146 | // GBA needs to meet memory alignment requirements, we can't write a u8 into | 124 | // GBA needs to meet memory alignment requirements, we can't write a u8 into |
147 | // memory, instead we need to read a u16 word, mask and or the corresponding | 125 | // memory, instead we need to read a u16 word, mask and or the corresponding |
148 | // bits and wave the updated u16. | 126 | // bits and wave the updated u16. |
149 | static void | 127 | static inline void |
150 | put_pixel_m4(int x, int y, u8 col_index, vu16 *buffer) { | 128 | put_pixel_m4(int x, int y, u8 clr_idx, vu16 *buffer) { |
151 | int buffer_index = (y * SCREEN_WIDTH + x) / 2; | 129 | int buffer_index = (y * SCREEN_WIDTH + x) / 2; |
152 | vu16 *destination = &buffer[buffer_index]; | 130 | vu16 *destination = &buffer[buffer_index]; |
153 | // Odd pixels will go to the top 8 bits of the destination. Even pixels to | 131 | // Odd pixels will go to the top 8 bits of the destination. Even pixels to |
154 | // the lower 8 bits. | 132 | // the lower 8 bits. |
155 | int odd = x & 0x1; | 133 | int odd = x & 0x1; |
156 | if(odd) { | 134 | if(odd) { |
157 | *destination= (*destination & 0xFF) | (col_index << 8); | 135 | *destination= (*destination & 0xFF) | (clr_idx << 8); |
158 | } else { | 136 | } else { |
159 | *destination= (*destination & ~0xFF) | col_index; | 137 | *destination= (*destination & ~0xFF) | clr_idx; |
138 | } | ||
139 | } | ||
140 | |||
141 | static inline void | ||
142 | put_pixel_m3(int x, int y, u16 color, Scanline *buffer) { | ||
143 | buffer[y][x] = color; | ||
144 | } | ||
145 | |||
146 | static inline void | ||
147 | clear_screen_m4() { | ||
148 | size_t size = SCREEN_WIDTH * SCREEN_HEIGHT / 8; | ||
149 | u32 *buf = backbuffer; | ||
150 | for (size_t i = 0; i < size; ++i) { | ||
151 | buf[i] = 0; | ||
160 | } | 152 | } |
161 | } | 153 | } |
162 | 154 | ||
@@ -205,24 +197,4 @@ draw_logo(void) { | |||
205 | draw_line(x + height, y + 1, x + height + line, y + 1, COLOR_WHITE); | 197 | draw_line(x + height, y + 1, x + height + line, y + 1, COLOR_WHITE); |
206 | } | 198 | } |
207 | 199 | ||
208 | // void | ||
209 | // copy_font_to_tile_memory(Tile *tile) { | ||
210 | // // Hex to bits translation table. | ||
211 | // const u32 conversion_u32[16] = { | ||
212 | // 0x00000000, 0x00001000, 0x00000100, 0x00001100, | ||
213 | // 0x00000010, 0x00001010, 0x00000110, 0x00001110, | ||
214 | // 0x00000001, 0x00001001, 0x00000101, 0x00001101, | ||
215 | // 0x00000011, 0x00001011, 0x00000111, 0x00001111, | ||
216 | // }; | ||
217 | // for (size_t i = 0; i < 250; ++i) { | ||
218 | // for (size_t j = 0; j < 8; ++j) { | ||
219 | // u8 row = font[i][j]; | ||
220 | // u32 tile_idx = 0x00000000; | ||
221 | // tile_idx = conversion_u32[row & 0xF] << 16; | ||
222 | // tile_idx |= conversion_u32[(row >> 4) & 0xF]; | ||
223 | // (tile + i)->data[j] = tile_idx; | ||
224 | // } | ||
225 | // } | ||
226 | // } | ||
227 | |||
228 | #endif // GBAEXP_BITMAP_H | 200 | #endif // GBAEXP_BITMAP_H |
diff --git a/src/common.h b/src/common.h index aa7261e..cf263db 100644 --- a/src/common.h +++ b/src/common.h | |||
@@ -147,6 +147,7 @@ typedef Color Scanline[SCREEN_WIDTH]; | |||
147 | #define PAL_BUFFER_SPRITES ((u16*)(MEM_PAL + 0x200)) | 147 | #define PAL_BUFFER_SPRITES ((u16*)(MEM_PAL + 0x200)) |
148 | #define PAL_BANK_BG ((Palette*) MEM_PAL) | 148 | #define PAL_BANK_BG ((Palette*) MEM_PAL) |
149 | #define PAL_BANK_SPRITES ((Palette*)(MEM_PAL + 0x200)) | 149 | #define PAL_BANK_SPRITES ((Palette*)(MEM_PAL + 0x200)) |
150 | static u16 *backbuffer = ((vu16*)(MEM_VRAM + 0x0A000)); | ||
150 | 151 | ||
151 | // | 152 | // |
152 | // Sprites. | 153 | // Sprites. |
@@ -198,6 +199,7 @@ typedef Color Scanline[SCREEN_WIDTH]; | |||
198 | 199 | ||
199 | static inline void | 200 | static inline void |
200 | flip_page(void) { | 201 | flip_page(void) { |
202 | backbuffer = (u16*)((u32)backbuffer ^ 0x0A000); | ||
201 | DISP_CTRL ^= DISP_PAGE; | 203 | DISP_CTRL ^= DISP_PAGE; |
202 | } | 204 | } |
203 | 205 | ||
@@ -15,7 +15,12 @@ | |||
15 | int main(void) { | 15 | int main(void) { |
16 | // Configure the display in mode 0 to show OBJs, where tile memory is | 16 | // Configure the display in mode 0 to show OBJs, where tile memory is |
17 | // sequential. | 17 | // sequential. |
18 | DISP_CTRL = DISP_ENABLE_SPRITES | DISP_MODE_3 | DISP_BG_2; | 18 | DISP_CTRL = DISP_ENABLE_SPRITES | DISP_MODE_4 | DISP_BG_2; |
19 | // DISP_CTRL = DISP_ENABLE_SPRITES | DISP_MODE_3 | DISP_BG_2; | ||
20 | |||
21 | PAL_BUFFER_BG[1] = COLOR_WHITE; | ||
22 | PAL_BUFFER_BG[2] = COLOR_RED; | ||
23 | PAL_BUFFER_BG[3] = COLOR_CYAN; | ||
19 | 24 | ||
20 | // Initialize text engine. | 25 | // Initialize text engine. |
21 | txt_init_bitmap( | 26 | txt_init_bitmap( |
diff --git a/src/sequencer.c b/src/sequencer.c index a19cef7..c09fb01 100644 --- a/src/sequencer.c +++ b/src/sequencer.c | |||
@@ -15,6 +15,10 @@ | |||
15 | #define SEQ_DUTYCYCLE_POS_Y 10 - 8 | 15 | #define SEQ_DUTYCYCLE_POS_Y 10 - 8 |
16 | #define SEQ_SWEEP_POS_X SEQ_DUTYCYCLE_POS_X + SEQ_ENV_DIST | 16 | #define SEQ_SWEEP_POS_X SEQ_DUTYCYCLE_POS_X + SEQ_ENV_DIST |
17 | #define SEQ_SWEEP_POS_Y SEQ_ENV_POS_Y | 17 | #define SEQ_SWEEP_POS_Y SEQ_ENV_POS_Y |
18 | #define SEQ_CH3_PARAM_X SEQ_TRIG_POS_X | ||
19 | #define SEQ_CH3_PARAM_Y SEQ_ENV_POS_Y | ||
20 | #define SEQ_CH3_PARAM_SEL_X SEQ_CH3_PARAM_X - 5 | ||
21 | #define SEQ_CH3_PARAM_SEL_Y SEQ_CH3_PARAM_Y + 22 | ||
18 | #define SEQ_N_CHANNELS 3 | 22 | #define SEQ_N_CHANNELS 3 |
19 | 23 | ||
20 | u32 sprite_note_names[] = { | 24 | u32 sprite_note_names[] = { |
@@ -522,6 +526,7 @@ set_time(int bpm) { | |||
522 | // - 054-054 channel 4. | 526 | // - 054-054 channel 4. |
523 | // - 055-055 RESERVED: FM synth?. | 527 | // - 055-055 RESERVED: FM synth?. |
524 | // - 056-056 channel selector. | 528 | // - 056-056 channel selector. |
529 | // - 057-057 ch3 selector. | ||
525 | // | 530 | // |
526 | 531 | ||
527 | 532 | ||
@@ -548,18 +553,20 @@ int param_selection_loc = 0; | |||
548 | int channel_selection_loc = 2; | 553 | int channel_selection_loc = 2; |
549 | SeqSelect current_selection = SEQ_SELECT_TRIGGER; | 554 | SeqSelect current_selection = SEQ_SELECT_TRIGGER; |
550 | 555 | ||
551 | SeqSprite seq_sprites[57] = {0}; | 556 | SeqSprite seq_sprites[58] = {0}; |
552 | 557 | ||
553 | void | 558 | void |
554 | draw_wave_pattern(u8 *pattern, int x, int y, Color clr) { | 559 | draw_wave_pattern(u8 *pattern, int x, int y, u16 clr_idx) { |
555 | for (size_t i = 0; i < 16; ++i) { | 560 | for (size_t i = 0; i < 16; ++i) { |
556 | u8 byte = pattern[i]; | 561 | u8 byte = pattern[i]; |
557 | u8 first = (byte >> 4) & 0xF; | 562 | u8 first = (byte >> 4) & 0xF; |
558 | u8 second = byte & 0xF; | 563 | u8 second = byte & 0xF; |
559 | FRAMEBUFFER[y + 16 - first][x + i * 4] = clr; | 564 | u8 a = x + i * 4; |
560 | FRAMEBUFFER[y + 16 - first][x + i * 4 + 1] = clr; | 565 | u8 b = y + 16; |
561 | FRAMEBUFFER[y + 16 - second][x + i * 4 + 2] = clr; | 566 | put_pixel_m4(a, b - first, clr_idx, backbuffer); |
562 | FRAMEBUFFER[y + 16 - second][x + i * 4 + 3] = clr; | 567 | put_pixel_m4(a + 1, b - first, clr_idx, backbuffer); |
568 | put_pixel_m4(a + 2, b - second, clr_idx, backbuffer); | ||
569 | put_pixel_m4(a + 3, b - second, clr_idx, backbuffer); | ||
563 | } | 570 | } |
564 | } | 571 | } |
565 | 572 | ||
@@ -616,10 +623,20 @@ init_sequencer_sprites(void) { | |||
616 | int base_tile = sprites[sprite_id].tile_start; | 623 | int base_tile = sprites[sprite_id].tile_start; |
617 | seq_sprites[32].id = obj_counter++; | 624 | seq_sprites[32].id = obj_counter++; |
618 | seq_sprites[32].base_tile = base_tile; | 625 | seq_sprites[32].base_tile = base_tile; |
619 | seq_sprites[32].obj_attr_0 = OBJ_SHAPE_SQUARE | OBJ_Y_COORD(y); | 626 | seq_sprites[32].obj_attr_0 = OBJ_SHAPE_SQUARE | OBJ_Y_COORD(y) | OBJ_HIDDEN; |
620 | seq_sprites[32].obj_attr_1 = OBJ_SIZE_SMALL | OBJ_X_COORD(x); | 627 | seq_sprites[32].obj_attr_1 = OBJ_SIZE_SMALL | OBJ_X_COORD(x); |
621 | seq_sprites[32].obj_attr_2 = base_tile | OBJ_PAL_BANK(1); | 628 | seq_sprites[32].obj_attr_2 = base_tile | OBJ_PAL_BANK(1); |
622 | } | 629 | } |
630 | { | ||
631 | int x = SEQ_CH3_PARAM_SEL_X; | ||
632 | int y = SEQ_CH3_PARAM_SEL_Y; | ||
633 | int base_tile = sprites[sprite_id].tile_start; | ||
634 | seq_sprites[57].id = obj_counter++; | ||
635 | seq_sprites[57].base_tile = base_tile; | ||
636 | seq_sprites[57].obj_attr_0 = OBJ_SHAPE_SQUARE | OBJ_Y_COORD(y); | ||
637 | seq_sprites[57].obj_attr_1 = OBJ_SIZE_SMALL | OBJ_X_COORD(x); | ||
638 | seq_sprites[57].obj_attr_2 = base_tile | OBJ_PAL_BANK(2); | ||
639 | } | ||
623 | 640 | ||
624 | sprite_id = load_packed_sprite_data(&sprite_trigger_selection, 16, 1); | 641 | sprite_id = load_packed_sprite_data(&sprite_trigger_selection, 16, 1); |
625 | { | 642 | { |
@@ -632,7 +649,7 @@ init_sequencer_sprites(void) { | |||
632 | } | 649 | } |
633 | seq_sprites[33].id = obj_counter++; | 650 | seq_sprites[33].id = obj_counter++; |
634 | seq_sprites[33].base_tile = base_tile; | 651 | seq_sprites[33].base_tile = base_tile; |
635 | seq_sprites[33].obj_attr_0 = OBJ_SHAPE_SQUARE | OBJ_Y_COORD(y); | 652 | seq_sprites[33].obj_attr_0 = OBJ_SHAPE_SQUARE | OBJ_Y_COORD(y) | OBJ_HIDDEN; |
636 | seq_sprites[33].obj_attr_1 = OBJ_SIZE_BIG | OBJ_X_COORD(x); | 653 | seq_sprites[33].obj_attr_1 = OBJ_SIZE_BIG | OBJ_X_COORD(x); |
637 | seq_sprites[33].obj_attr_2 = base_tile | OBJ_PAL_BANK(2); | 654 | seq_sprites[33].obj_attr_2 = base_tile | OBJ_PAL_BANK(2); |
638 | } | 655 | } |
@@ -644,7 +661,7 @@ init_sequencer_sprites(void) { | |||
644 | int base_tile = sprites[sprite_id].tile_start; | 661 | int base_tile = sprites[sprite_id].tile_start; |
645 | seq_sprites[34].id = obj_counter++; | 662 | seq_sprites[34].id = obj_counter++; |
646 | seq_sprites[34].base_tile = base_tile; | 663 | seq_sprites[34].base_tile = base_tile; |
647 | seq_sprites[34].obj_attr_0 = OBJ_SHAPE_WIDE | OBJ_Y_COORD(y); | 664 | seq_sprites[34].obj_attr_0 = OBJ_SHAPE_WIDE | OBJ_Y_COORD(y) | OBJ_HIDDEN; |
648 | seq_sprites[34].obj_attr_1 = OBJ_SIZE_MID | OBJ_X_COORD(x); | 665 | seq_sprites[34].obj_attr_1 = OBJ_SIZE_MID | OBJ_X_COORD(x); |
649 | seq_sprites[34].obj_attr_2 = base_tile; | 666 | seq_sprites[34].obj_attr_2 = base_tile; |
650 | } | 667 | } |
@@ -656,7 +673,7 @@ init_sequencer_sprites(void) { | |||
656 | int base_tile = sprites[sprite_id].tile_start; | 673 | int base_tile = sprites[sprite_id].tile_start; |
657 | seq_sprites[35].id = obj_counter++; | 674 | seq_sprites[35].id = obj_counter++; |
658 | seq_sprites[35].base_tile = base_tile; | 675 | seq_sprites[35].base_tile = base_tile; |
659 | seq_sprites[35].obj_attr_0 = OBJ_SHAPE_WIDE | OBJ_Y_COORD(y); | 676 | seq_sprites[35].obj_attr_0 = OBJ_SHAPE_WIDE | OBJ_Y_COORD(y) | OBJ_HIDDEN; |
660 | seq_sprites[35].obj_attr_1 = OBJ_SIZE_MID | OBJ_X_COORD(x); | 677 | seq_sprites[35].obj_attr_1 = OBJ_SIZE_MID | OBJ_X_COORD(x); |
661 | seq_sprites[35].obj_attr_2 = base_tile; | 678 | seq_sprites[35].obj_attr_2 = base_tile; |
662 | } | 679 | } |
@@ -668,7 +685,7 @@ init_sequencer_sprites(void) { | |||
668 | int base_tile = sprites[sprite_id].tile_start; | 685 | int base_tile = sprites[sprite_id].tile_start; |
669 | seq_sprites[36].id = obj_counter++; | 686 | seq_sprites[36].id = obj_counter++; |
670 | seq_sprites[36].base_tile = base_tile; | 687 | seq_sprites[36].base_tile = base_tile; |
671 | seq_sprites[36].obj_attr_0 = OBJ_SHAPE_WIDE | OBJ_Y_COORD(y); | 688 | seq_sprites[36].obj_attr_0 = OBJ_SHAPE_WIDE | OBJ_Y_COORD(y) | OBJ_HIDDEN; |
672 | seq_sprites[36].obj_attr_1 = OBJ_SIZE_MID | OBJ_X_COORD(x); | 689 | seq_sprites[36].obj_attr_1 = OBJ_SIZE_MID | OBJ_X_COORD(x); |
673 | seq_sprites[36].obj_attr_2 = base_tile; | 690 | seq_sprites[36].obj_attr_2 = base_tile; |
674 | } | 691 | } |
@@ -678,7 +695,7 @@ init_sequencer_sprites(void) { | |||
678 | int base_tile = sprites[sprite_id].tile_start; | 695 | int base_tile = sprites[sprite_id].tile_start; |
679 | seq_sprites[45].id = obj_counter++; | 696 | seq_sprites[45].id = obj_counter++; |
680 | seq_sprites[45].base_tile = base_tile; | 697 | seq_sprites[45].base_tile = base_tile; |
681 | seq_sprites[45].obj_attr_0 = OBJ_SHAPE_WIDE | OBJ_Y_COORD(y); | 698 | seq_sprites[45].obj_attr_0 = OBJ_SHAPE_WIDE | OBJ_Y_COORD(y) | OBJ_HIDDEN; |
682 | seq_sprites[45].obj_attr_1 = OBJ_SIZE_MID | OBJ_X_COORD(x); | 699 | seq_sprites[45].obj_attr_1 = OBJ_SIZE_MID | OBJ_X_COORD(x); |
683 | seq_sprites[45].obj_attr_2 = base_tile; | 700 | seq_sprites[45].obj_attr_2 = base_tile; |
684 | } | 701 | } |
@@ -690,7 +707,7 @@ init_sequencer_sprites(void) { | |||
690 | int base_tile = sprites[sprite_id].tile_start; | 707 | int base_tile = sprites[sprite_id].tile_start; |
691 | seq_sprites[37].id = obj_counter++; | 708 | seq_sprites[37].id = obj_counter++; |
692 | seq_sprites[37].base_tile = base_tile; | 709 | seq_sprites[37].base_tile = base_tile; |
693 | seq_sprites[37].obj_attr_0 = OBJ_SHAPE_WIDE | OBJ_Y_COORD(y); | 710 | seq_sprites[37].obj_attr_0 = OBJ_SHAPE_WIDE | OBJ_Y_COORD(y) | OBJ_HIDDEN; |
694 | seq_sprites[37].obj_attr_1 = OBJ_SIZE_MID | OBJ_X_COORD(x); | 711 | seq_sprites[37].obj_attr_1 = OBJ_SIZE_MID | OBJ_X_COORD(x); |
695 | seq_sprites[37].obj_attr_2 = base_tile; | 712 | seq_sprites[37].obj_attr_2 = base_tile; |
696 | } | 713 | } |
@@ -702,7 +719,7 @@ init_sequencer_sprites(void) { | |||
702 | int base_tile = sprites[sprite_id].tile_start; | 719 | int base_tile = sprites[sprite_id].tile_start; |
703 | seq_sprites[38].id = obj_counter++; | 720 | seq_sprites[38].id = obj_counter++; |
704 | seq_sprites[38].base_tile = base_tile; | 721 | seq_sprites[38].base_tile = base_tile; |
705 | seq_sprites[38].obj_attr_0 = OBJ_SHAPE_WIDE | OBJ_Y_COORD(y); | 722 | seq_sprites[38].obj_attr_0 = OBJ_SHAPE_WIDE | OBJ_Y_COORD(y) | OBJ_HIDDEN; |
706 | seq_sprites[38].obj_attr_1 = OBJ_SIZE_MID | OBJ_X_COORD(x); | 723 | seq_sprites[38].obj_attr_1 = OBJ_SIZE_MID | OBJ_X_COORD(x); |
707 | seq_sprites[38].obj_attr_2 = base_tile; | 724 | seq_sprites[38].obj_attr_2 = base_tile; |
708 | } | 725 | } |
@@ -712,7 +729,7 @@ init_sequencer_sprites(void) { | |||
712 | int base_tile = sprites[sprite_id].tile_start; | 729 | int base_tile = sprites[sprite_id].tile_start; |
713 | seq_sprites[47].id = obj_counter++; | 730 | seq_sprites[47].id = obj_counter++; |
714 | seq_sprites[47].base_tile = base_tile; | 731 | seq_sprites[47].base_tile = base_tile; |
715 | seq_sprites[47].obj_attr_0 = OBJ_SHAPE_WIDE | OBJ_Y_COORD(y); | 732 | seq_sprites[47].obj_attr_0 = OBJ_SHAPE_WIDE | OBJ_Y_COORD(y) | OBJ_HIDDEN; |
716 | seq_sprites[47].obj_attr_1 = OBJ_SIZE_MID | OBJ_X_COORD(x); | 733 | seq_sprites[47].obj_attr_1 = OBJ_SIZE_MID | OBJ_X_COORD(x); |
717 | seq_sprites[47].obj_attr_2 = base_tile; | 734 | seq_sprites[47].obj_attr_2 = base_tile; |
718 | } | 735 | } |
@@ -724,7 +741,7 @@ init_sequencer_sprites(void) { | |||
724 | int base_tile = sprites[sprite_id].tile_start; | 741 | int base_tile = sprites[sprite_id].tile_start; |
725 | seq_sprites[39].id = obj_counter++; | 742 | seq_sprites[39].id = obj_counter++; |
726 | seq_sprites[39].base_tile = base_tile; | 743 | seq_sprites[39].base_tile = base_tile; |
727 | seq_sprites[39].obj_attr_0 = OBJ_SHAPE_WIDE | OBJ_Y_COORD(y); | 744 | seq_sprites[39].obj_attr_0 = OBJ_SHAPE_WIDE | OBJ_Y_COORD(y) | OBJ_HIDDEN; |
728 | seq_sprites[39].obj_attr_1 = OBJ_SIZE_MID | OBJ_X_COORD(x); | 745 | seq_sprites[39].obj_attr_1 = OBJ_SIZE_MID | OBJ_X_COORD(x); |
729 | seq_sprites[39].obj_attr_2 = base_tile; | 746 | seq_sprites[39].obj_attr_2 = base_tile; |
730 | } | 747 | } |
@@ -734,7 +751,7 @@ init_sequencer_sprites(void) { | |||
734 | int base_tile = sprites[sprite_id].tile_start; | 751 | int base_tile = sprites[sprite_id].tile_start; |
735 | seq_sprites[48].id = obj_counter++; | 752 | seq_sprites[48].id = obj_counter++; |
736 | seq_sprites[48].base_tile = base_tile; | 753 | seq_sprites[48].base_tile = base_tile; |
737 | seq_sprites[48].obj_attr_0 = OBJ_SHAPE_WIDE | OBJ_Y_COORD(y); | 754 | seq_sprites[48].obj_attr_0 = OBJ_SHAPE_WIDE | OBJ_Y_COORD(y) | OBJ_HIDDEN; |
738 | seq_sprites[48].obj_attr_1 = OBJ_SIZE_MID | OBJ_X_COORD(x); | 755 | seq_sprites[48].obj_attr_1 = OBJ_SIZE_MID | OBJ_X_COORD(x); |
739 | seq_sprites[48].obj_attr_2 = base_tile; | 756 | seq_sprites[48].obj_attr_2 = base_tile; |
740 | } | 757 | } |
@@ -746,7 +763,7 @@ init_sequencer_sprites(void) { | |||
746 | int base_tile = sprites[sprite_id].tile_start; | 763 | int base_tile = sprites[sprite_id].tile_start; |
747 | seq_sprites[40].id = obj_counter++; | 764 | seq_sprites[40].id = obj_counter++; |
748 | seq_sprites[40].base_tile = base_tile; | 765 | seq_sprites[40].base_tile = base_tile; |
749 | seq_sprites[40].obj_attr_0 = OBJ_SHAPE_WIDE | OBJ_Y_COORD(y); | 766 | seq_sprites[40].obj_attr_0 = OBJ_SHAPE_WIDE | OBJ_Y_COORD(y) | OBJ_HIDDEN; |
750 | seq_sprites[40].obj_attr_1 = OBJ_SIZE_MID | OBJ_X_COORD(x); | 767 | seq_sprites[40].obj_attr_1 = OBJ_SIZE_MID | OBJ_X_COORD(x); |
751 | seq_sprites[40].obj_attr_2 = base_tile; | 768 | seq_sprites[40].obj_attr_2 = base_tile; |
752 | } | 769 | } |
@@ -758,7 +775,7 @@ init_sequencer_sprites(void) { | |||
758 | int base_tile = sprites[sprite_id].tile_start; | 775 | int base_tile = sprites[sprite_id].tile_start; |
759 | seq_sprites[41].id = obj_counter++; | 776 | seq_sprites[41].id = obj_counter++; |
760 | seq_sprites[41].base_tile = base_tile; | 777 | seq_sprites[41].base_tile = base_tile; |
761 | seq_sprites[41].obj_attr_0 = OBJ_SHAPE_WIDE | OBJ_Y_COORD(y); | 778 | seq_sprites[41].obj_attr_0 = OBJ_SHAPE_WIDE | OBJ_Y_COORD(y) | OBJ_HIDDEN; |
762 | seq_sprites[41].obj_attr_1 = OBJ_SIZE_BIG | OBJ_X_COORD(x); | 779 | seq_sprites[41].obj_attr_1 = OBJ_SIZE_BIG | OBJ_X_COORD(x); |
763 | seq_sprites[41].obj_attr_2 = base_tile; | 780 | seq_sprites[41].obj_attr_2 = base_tile; |
764 | } | 781 | } |
@@ -770,7 +787,7 @@ init_sequencer_sprites(void) { | |||
770 | int base_tile = sprites[sprite_id].tile_start; | 787 | int base_tile = sprites[sprite_id].tile_start; |
771 | seq_sprites[42].id = obj_counter++; | 788 | seq_sprites[42].id = obj_counter++; |
772 | seq_sprites[42].base_tile = base_tile; | 789 | seq_sprites[42].base_tile = base_tile; |
773 | seq_sprites[42].obj_attr_0 = OBJ_SHAPE_WIDE | OBJ_Y_COORD(y); | 790 | seq_sprites[42].obj_attr_0 = OBJ_SHAPE_WIDE | OBJ_Y_COORD(y) | OBJ_HIDDEN; |
774 | seq_sprites[42].obj_attr_1 = OBJ_SIZE_MID | OBJ_X_COORD(x); | 791 | seq_sprites[42].obj_attr_1 = OBJ_SIZE_MID | OBJ_X_COORD(x); |
775 | seq_sprites[42].obj_attr_2 = base_tile; | 792 | seq_sprites[42].obj_attr_2 = base_tile; |
776 | } | 793 | } |
@@ -782,7 +799,7 @@ init_sequencer_sprites(void) { | |||
782 | int base_tile = sprites[sprite_id].tile_start; | 799 | int base_tile = sprites[sprite_id].tile_start; |
783 | seq_sprites[43].id = obj_counter++; | 800 | seq_sprites[43].id = obj_counter++; |
784 | seq_sprites[43].base_tile = base_tile; | 801 | seq_sprites[43].base_tile = base_tile; |
785 | seq_sprites[43].obj_attr_0 = OBJ_SHAPE_WIDE | OBJ_Y_COORD(y); | 802 | seq_sprites[43].obj_attr_0 = OBJ_SHAPE_WIDE | OBJ_Y_COORD(y) | OBJ_HIDDEN; |
786 | seq_sprites[43].obj_attr_1 = OBJ_SIZE_MID | OBJ_X_COORD(x); | 803 | seq_sprites[43].obj_attr_1 = OBJ_SIZE_MID | OBJ_X_COORD(x); |
787 | seq_sprites[43].obj_attr_2 = base_tile; | 804 | seq_sprites[43].obj_attr_2 = base_tile; |
788 | } | 805 | } |
@@ -794,7 +811,7 @@ init_sequencer_sprites(void) { | |||
794 | int base_tile = sprites[sprite_id].tile_start; | 811 | int base_tile = sprites[sprite_id].tile_start; |
795 | seq_sprites[44].id = obj_counter++; | 812 | seq_sprites[44].id = obj_counter++; |
796 | seq_sprites[44].base_tile = base_tile; | 813 | seq_sprites[44].base_tile = base_tile; |
797 | seq_sprites[44].obj_attr_0 = OBJ_SHAPE_SQUARE | OBJ_Y_COORD(y); | 814 | seq_sprites[44].obj_attr_0 = OBJ_SHAPE_SQUARE | OBJ_Y_COORD(y) | OBJ_HIDDEN; |
798 | seq_sprites[44].obj_attr_1 = OBJ_SIZE_SMALL | OBJ_X_COORD(x); | 815 | seq_sprites[44].obj_attr_1 = OBJ_SIZE_SMALL | OBJ_X_COORD(x); |
799 | seq_sprites[44].obj_attr_2 = base_tile; | 816 | seq_sprites[44].obj_attr_2 = base_tile; |
800 | } | 817 | } |
@@ -804,7 +821,7 @@ init_sequencer_sprites(void) { | |||
804 | int base_tile = sprites[sprite_id].tile_start; | 821 | int base_tile = sprites[sprite_id].tile_start; |
805 | seq_sprites[46].id = obj_counter++; | 822 | seq_sprites[46].id = obj_counter++; |
806 | seq_sprites[46].base_tile = base_tile; | 823 | seq_sprites[46].base_tile = base_tile; |
807 | seq_sprites[46].obj_attr_0 = OBJ_SHAPE_SQUARE | OBJ_Y_COORD(y); | 824 | seq_sprites[46].obj_attr_0 = OBJ_SHAPE_SQUARE | OBJ_Y_COORD(y) | OBJ_HIDDEN; |
808 | seq_sprites[46].obj_attr_1 = OBJ_SIZE_SMALL | OBJ_X_COORD(x); | 825 | seq_sprites[46].obj_attr_1 = OBJ_SIZE_SMALL | OBJ_X_COORD(x); |
809 | seq_sprites[46].obj_attr_2 = base_tile; | 826 | seq_sprites[46].obj_attr_2 = base_tile; |
810 | } | 827 | } |
@@ -816,7 +833,7 @@ init_sequencer_sprites(void) { | |||
816 | int base_tile = sprites[sprite_id].tile_start; | 833 | int base_tile = sprites[sprite_id].tile_start; |
817 | seq_sprites[49].id = obj_counter++; | 834 | seq_sprites[49].id = obj_counter++; |
818 | seq_sprites[49].base_tile = base_tile; | 835 | seq_sprites[49].base_tile = base_tile; |
819 | seq_sprites[49].obj_attr_0 = OBJ_SHAPE_WIDE | OBJ_Y_COORD(y); | 836 | seq_sprites[49].obj_attr_0 = OBJ_SHAPE_WIDE | OBJ_Y_COORD(y) | OBJ_HIDDEN; |
820 | seq_sprites[49].obj_attr_1 = OBJ_SIZE_MID | OBJ_X_COORD(x); | 837 | seq_sprites[49].obj_attr_1 = OBJ_SIZE_MID | OBJ_X_COORD(x); |
821 | seq_sprites[49].obj_attr_2 = base_tile; | 838 | seq_sprites[49].obj_attr_2 = base_tile; |
822 | } | 839 | } |
@@ -828,7 +845,7 @@ init_sequencer_sprites(void) { | |||
828 | int base_tile = sprites[sprite_id].tile_start; | 845 | int base_tile = sprites[sprite_id].tile_start; |
829 | seq_sprites[50].id = obj_counter++; | 846 | seq_sprites[50].id = obj_counter++; |
830 | seq_sprites[50].base_tile = base_tile; | 847 | seq_sprites[50].base_tile = base_tile; |
831 | seq_sprites[50].obj_attr_0 = OBJ_SHAPE_SQUARE | OBJ_Y_COORD(y); | 848 | seq_sprites[50].obj_attr_0 = OBJ_SHAPE_SQUARE | OBJ_Y_COORD(y) | OBJ_HIDDEN; |
832 | seq_sprites[50].obj_attr_1 = OBJ_SIZE_BIG | OBJ_X_COORD(x); | 849 | seq_sprites[50].obj_attr_1 = OBJ_SIZE_BIG | OBJ_X_COORD(x); |
833 | seq_sprites[50].obj_attr_2 = base_tile | OBJ_PAL_BANK(2); | 850 | seq_sprites[50].obj_attr_2 = base_tile | OBJ_PAL_BANK(2); |
834 | } | 851 | } |
@@ -1017,19 +1034,7 @@ update_sequencer_sprites(void) { | |||
1017 | seq_sprites[48].obj_attr_2 = tile; | 1034 | seq_sprites[48].obj_attr_2 = tile; |
1018 | } | 1035 | } |
1019 | 1036 | ||
1020 | // 51: Parameter selector. | 1037 | // 57: Channel selector. |
1021 | { | ||
1022 | int x = SEQ_ENV_POS_X + 1 + (param_selection_loc % 7) * SEQ_ENV_DIST; | ||
1023 | int y = SEQ_ENV_POS_Y - 3; | ||
1024 | int hidden = 0; | ||
1025 | if (current_selection != SEQ_SELECT_PARAMETER) { | ||
1026 | hidden = OBJ_HIDDEN; | ||
1027 | } | ||
1028 | seq_sprites[50].obj_attr_0 = OBJ_SHAPE_SQUARE | OBJ_Y_COORD(y) | hidden; | ||
1029 | seq_sprites[50].obj_attr_1 = OBJ_SIZE_BIG | OBJ_X_COORD(x); | ||
1030 | } | ||
1031 | |||
1032 | // 57: Parameter selector. | ||
1033 | { | 1038 | { |
1034 | int x = SEQ_CHANNEL_POS_X; | 1039 | int x = SEQ_CHANNEL_POS_X; |
1035 | int y = SEQ_CHANNEL_POS_Y - 2; | 1040 | int y = SEQ_CHANNEL_POS_Y - 2; |
@@ -1044,31 +1049,17 @@ update_sequencer_sprites(void) { | |||
1044 | } | 1049 | } |
1045 | } | 1050 | } |
1046 | 1051 | ||
1047 | // TODO: Hide all parameter control sprites for now, we unhide it later. | ||
1048 | // Very inefficient but we may change the parameter rendering of all modes | ||
1049 | // to use bitmaps instead of sprites later. | ||
1050 | for (size_t i = 34; i <= 50; ++i) { | ||
1051 | seq_sprites[i].obj_attr_0 |= OBJ_HIDDEN; | ||
1052 | } | ||
1053 | |||
1054 | if (update_params_screen) { | ||
1055 | // Clear screen. | ||
1056 | // draw_fill_rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT / 2, COLOR_BLACK); | ||
1057 | int zero = 0; | ||
1058 | dma_fill(FRAMEBUFFER, zero, SCREEN_WIDTH * SCREEN_HEIGHT * 2, 3); | ||
1059 | |||
1060 | } | ||
1061 | if (channel_selection_loc == 2) { | 1052 | if (channel_selection_loc == 2) { |
1062 | if (update_params_screen) { | 1053 | if (update_params_screen) { |
1063 | u8 *wave_a = sequences[channel_selection_loc][trig_selection_loc].wave_a; | 1054 | u8 *wave_a = sequences[channel_selection_loc][trig_selection_loc].wave_a; |
1064 | u8 *wave_b = sequences[channel_selection_loc][trig_selection_loc].wave_b; | 1055 | u8 *wave_b = sequences[channel_selection_loc][trig_selection_loc].wave_b; |
1065 | 1056 | ||
1066 | // Draw wave patterns for this trig. | 1057 | // Draw wave patterns for this trig. |
1067 | int x = SEQ_ENV_POS_X; | 1058 | int x = SEQ_CH3_PARAM_X; |
1068 | int y = SEQ_ENV_POS_Y; | 1059 | int y = SEQ_CH3_PARAM_Y; |
1069 | 1060 | ||
1070 | // Wave A. | 1061 | // Wave A. |
1071 | draw_wave_pattern(wave_a, x, y, COLOR_RED); | 1062 | draw_wave_pattern(wave_a, x, y, 2); |
1072 | txt_position(x - 1, y + 20); | 1063 | txt_position(x - 1, y + 20); |
1073 | txt_printf("%02x%02x%02x%02x %02x%02x%02x%02x", | 1064 | txt_printf("%02x%02x%02x%02x %02x%02x%02x%02x", |
1074 | wave_a[0], wave_a[1], wave_a[2], wave_a[3], | 1065 | wave_a[0], wave_a[1], wave_a[2], wave_a[3], |
@@ -1079,8 +1070,8 @@ update_sequencer_sprites(void) { | |||
1079 | wave_a[12], wave_a[13], wave_a[14], wave_a[15]); | 1070 | wave_a[12], wave_a[13], wave_a[14], wave_a[15]); |
1080 | 1071 | ||
1081 | // Wave B. | 1072 | // Wave B. |
1082 | x += 64 + 32 + 12; | 1073 | x += 64 + 12; |
1083 | draw_wave_pattern(wave_b, x, y, COLOR_CYAN); | 1074 | draw_wave_pattern(wave_b, x, y, 3); |
1084 | txt_position(x - 1, y + 20); | 1075 | txt_position(x - 1, y + 20); |
1085 | txt_printf("%02x%02x%02x%02x %02x%02x%02x%02x", | 1076 | txt_printf("%02x%02x%02x%02x %02x%02x%02x%02x", |
1086 | wave_b[0], wave_b[1], wave_b[2], wave_b[3], | 1077 | wave_b[0], wave_b[1], wave_b[2], wave_b[3], |
@@ -1089,27 +1080,66 @@ update_sequencer_sprites(void) { | |||
1089 | txt_printf("%02x%02x%02x%02x %02x%02x%02x%02x", | 1080 | txt_printf("%02x%02x%02x%02x %02x%02x%02x%02x", |
1090 | wave_b[8], wave_b[9], wave_b[10], wave_b[11], | 1081 | wave_b[8], wave_b[9], wave_b[10], wave_b[11], |
1091 | wave_b[12], wave_b[13], wave_b[14], wave_b[15]); | 1082 | wave_b[12], wave_b[13], wave_b[14], wave_b[15]); |
1083 | |||
1084 | // Clear the backbuffer. | ||
1085 | flip_page(); | ||
1086 | clear_screen_m4(); | ||
1092 | } | 1087 | } |
1093 | } else if ((current_selection == SEQ_SELECT_TRIGGER | 1088 | |
1094 | || current_selection == SEQ_SELECT_PARAMETER) | 1089 | // Update parameter selection. |
1095 | && channel_selection_loc == 0) { | 1090 | { |
1096 | for (size_t i = 34; i <= 50; ++i) { | 1091 | int x = SEQ_CH3_PARAM_SEL_X + param_selection_loc * 4; |
1097 | seq_sprites[i].obj_attr_0 &= ~OBJ_HIDDEN; | 1092 | int y = SEQ_CH3_PARAM_SEL_Y; |
1093 | int base_tile = seq_sprites[57].base_tile; | ||
1094 | int hidden = 0; | ||
1095 | if (current_selection != SEQ_SELECT_PARAMETER) { | ||
1096 | hidden = OBJ_HIDDEN; | ||
1097 | } | ||
1098 | seq_sprites[57].obj_attr_0 = OBJ_SHAPE_SQUARE | OBJ_Y_COORD(y) | hidden; | ||
1099 | seq_sprites[57].obj_attr_1 = OBJ_SIZE_SMALL | OBJ_X_COORD(x); | ||
1100 | seq_sprites[57].obj_attr_2 = base_tile | OBJ_PAL_BANK(2); | ||
1098 | } | 1101 | } |
1099 | } else if ((current_selection == SEQ_SELECT_TRIGGER | 1102 | } |
1100 | || current_selection == SEQ_SELECT_PARAMETER) | 1103 | |
1101 | && channel_selection_loc == 1) { | 1104 | if (channel_selection_loc == 0) { |
1102 | for (size_t i = 34; i < 43; ++i) { | 1105 | if (current_selection == SEQ_SELECT_TRIGGER |
1103 | seq_sprites[i].obj_attr_0 &= ~OBJ_HIDDEN; | 1106 | || current_selection == SEQ_SELECT_PARAMETER) { |
1107 | for (size_t i = 34; i < 50; ++i) { | ||
1108 | seq_sprites[i].obj_attr_0 &= ~OBJ_HIDDEN; | ||
1109 | } | ||
1104 | } | 1110 | } |
1105 | seq_sprites[50].obj_attr_0 &= ~OBJ_HIDDEN; | 1111 | } |
1106 | } else { | ||
1107 | int x = SEQ_ENV_POS_X + 8; | ||
1108 | int y = SEQ_ENV_POS_Y; | ||
1109 | 1112 | ||
1110 | // Clear parameters for channel 3. | 1113 | if (channel_selection_loc == 1) { |
1111 | draw_fill_rect(x, y, x + 64, y + 16, COLOR_BLACK); | 1114 | if (current_selection == SEQ_SELECT_TRIGGER |
1112 | draw_fill_rect(x + 64 + 16, y, x + 64 * 2 + 16, y + 16, COLOR_BLACK); | 1115 | || current_selection == SEQ_SELECT_PARAMETER) { |
1116 | for (size_t i = 34; i <= 42; ++i) { | ||
1117 | seq_sprites[i].obj_attr_0 &= ~OBJ_HIDDEN; | ||
1118 | } | ||
1119 | } | ||
1120 | } | ||
1121 | |||
1122 | if (channel_selection_loc == 0 || channel_selection_loc == 1) { | ||
1123 | // 51: Parameter selector. | ||
1124 | int x = SEQ_ENV_POS_X + 1 + (param_selection_loc % 7) * SEQ_ENV_DIST; | ||
1125 | int y = SEQ_ENV_POS_Y - 3; | ||
1126 | int hidden = 0; | ||
1127 | if (current_selection != SEQ_SELECT_PARAMETER) { | ||
1128 | hidden = OBJ_HIDDEN; | ||
1129 | } | ||
1130 | seq_sprites[50].obj_attr_0 = OBJ_SHAPE_SQUARE | OBJ_Y_COORD(y) | hidden; | ||
1131 | seq_sprites[50].obj_attr_1 = OBJ_SIZE_BIG | OBJ_X_COORD(x); | ||
1132 | } | ||
1133 | |||
1134 | if (current_selection == SEQ_SELECT_CHANNEL && update_params_screen) { | ||
1135 | // TODO: Hide all parameter control sprites for now, we unhide it later. | ||
1136 | // Very inefficient but we may change the parameter rendering of all | ||
1137 | // modes to use bitmaps instead of sprites later. | ||
1138 | for (size_t i = 34; i <= 50; ++i) { | ||
1139 | seq_sprites[i].obj_attr_0 |= OBJ_HIDDEN; | ||
1140 | } | ||
1141 | flip_page(); | ||
1142 | clear_screen_m4(); | ||
1113 | } | 1143 | } |
1114 | update_params_screen = false; | 1144 | update_params_screen = false; |
1115 | } | 1145 | } |
@@ -1133,91 +1163,129 @@ handle_sequencer_input(void) { | |||
1133 | } else if (key_pressed(KEY_B)) { | 1163 | } else if (key_pressed(KEY_B)) { |
1134 | trig->trigger ^= 1; | 1164 | trig->trigger ^= 1; |
1135 | } else if (key_pressed(KEY_L)) { | 1165 | } else if (key_pressed(KEY_L)) { |
1136 | trig->note = MAX(trig->note - 1, NOTE_C_2); | 1166 | if (trig->trigger) { |
1167 | trig->note = MAX(trig->note - 1, NOTE_C_2); | ||
1168 | } | ||
1137 | } else if (key_pressed(KEY_R)) { | 1169 | } else if (key_pressed(KEY_R)) { |
1138 | trig->note = MIN( trig->note + 1, NOTE_C_8); | 1170 | if (trig->trigger) { |
1171 | trig->note = MIN( trig->note + 1, NOTE_C_8); | ||
1172 | } | ||
1139 | } else if (key_pressed(KEY_A)) { | 1173 | } else if (key_pressed(KEY_A)) { |
1140 | // Switch to parameter selection. | 1174 | // Switch to parameter selection. |
1141 | current_selection = SEQ_SELECT_PARAMETER; | 1175 | current_selection = SEQ_SELECT_PARAMETER; |
1142 | } | 1176 | } |
1143 | } else if (current_selection == SEQ_SELECT_PARAMETER) { | 1177 | } else if (current_selection == SEQ_SELECT_PARAMETER) { |
1144 | // Move through the selected synth parameters. | 1178 | if (channel_selection_loc < 2) { |
1145 | if (key_pressed(KEY_LEFT)) { | 1179 | // Move through the selected synth parameters. |
1146 | int max_param = 6; | 1180 | if (key_pressed(KEY_LEFT)) { |
1147 | if (channel_selection_loc == 1) { | 1181 | int max_param = 6; |
1148 | max_param = 3; | 1182 | if (channel_selection_loc == 1) { |
1183 | max_param = 3; | ||
1184 | } | ||
1185 | if (param_selection_loc == 0) { | ||
1186 | param_selection_loc = max_param; | ||
1187 | } else { | ||
1188 | param_selection_loc = MAX(param_selection_loc - 1, 0); | ||
1189 | } | ||
1149 | } | 1190 | } |
1150 | if (param_selection_loc == 0) { | 1191 | if (key_pressed(KEY_RIGHT)) { |
1151 | param_selection_loc = max_param; | 1192 | int max_param = 6; |
1152 | } else { | 1193 | if (channel_selection_loc == 1) { |
1153 | param_selection_loc = MAX(param_selection_loc - 1, 0); | 1194 | max_param = 3; |
1195 | } | ||
1196 | if (param_selection_loc == max_param) { | ||
1197 | param_selection_loc = 0; | ||
1198 | } else { | ||
1199 | param_selection_loc = MIN(param_selection_loc + 1, max_param); | ||
1200 | } | ||
1154 | } | 1201 | } |
1155 | } | 1202 | |
1156 | if (key_pressed(KEY_RIGHT)) { | 1203 | // Adjust the parameters up or down. |
1157 | int max_param = 6; | 1204 | if (key_pressed(KEY_L)) { |
1158 | if (channel_selection_loc == 1) { | 1205 | switch (param_selection_loc) { |
1159 | max_param = 3; | 1206 | case 0: { |
1207 | trig->env_volume = MAX(trig->env_volume - 1, 0); | ||
1208 | } break; | ||
1209 | case 1: { | ||
1210 | trig->env_time = MAX(trig->env_time - 1, 0); | ||
1211 | } break; | ||
1212 | case 2: { | ||
1213 | trig->env_direction ^= 1; | ||
1214 | } break; | ||
1215 | case 3: { | ||
1216 | trig->duty_cycle = MAX(trig->duty_cycle - 1, 0); | ||
1217 | } break; | ||
1218 | case 4: { | ||
1219 | trig->sweep_number = MAX(trig->sweep_number - 1, 0); | ||
1220 | } break; | ||
1221 | case 5: { | ||
1222 | trig->sweep_time = MAX(trig->sweep_time - 1, 0); | ||
1223 | } break; | ||
1224 | case 6: { | ||
1225 | if (trig->sweep_direction == 0) { | ||
1226 | trig->sweep_direction = 1; | ||
1227 | } else { | ||
1228 | trig->sweep_direction = 0; | ||
1229 | } | ||
1230 | } break; | ||
1231 | } | ||
1160 | } | 1232 | } |
1161 | if (param_selection_loc == max_param) { | 1233 | if (key_pressed(KEY_R)) { |
1162 | param_selection_loc = 0; | 1234 | switch (param_selection_loc) { |
1163 | } else { | 1235 | case 0: { |
1164 | param_selection_loc = MIN(param_selection_loc + 1, max_param); | 1236 | trig->env_volume = MIN(trig->env_volume + 1, 15); |
1237 | } break; | ||
1238 | case 1: { | ||
1239 | trig->env_time = MIN(trig->env_time + 1, 7); | ||
1240 | } break; | ||
1241 | case 2: { | ||
1242 | trig->env_direction ^= 1; | ||
1243 | } break; | ||
1244 | case 3: { | ||
1245 | trig->duty_cycle = MIN(trig->duty_cycle + 1, 3); | ||
1246 | } break; | ||
1247 | case 4: { | ||
1248 | trig->sweep_number = MIN(trig->sweep_number + 1, 7); | ||
1249 | } break; | ||
1250 | case 5: { | ||
1251 | trig->sweep_time = MIN(trig->sweep_time + 1, 7); | ||
1252 | } break; | ||
1253 | case 6: { | ||
1254 | trig->sweep_direction ^= 1; | ||
1255 | } break; | ||
1256 | } | ||
1165 | } | 1257 | } |
1166 | } | 1258 | } else if (channel_selection_loc == 2) { |
1167 | 1259 | // TODO:... | |
1168 | // Adjust the parameters up or down. | 1260 | if (key_pressed(KEY_LEFT)) { |
1169 | if (key_pressed(KEY_L)) { | 1261 | param_selection_loc -= 1; |
1170 | switch (param_selection_loc) { | 1262 | // int max_param = 6; |
1171 | case 0: { | 1263 | // if (channel_selection_loc == 1) { |
1172 | trig->env_volume = MAX(trig->env_volume - 1, 0); | 1264 | // max_param = 3; |
1173 | } break; | 1265 | // } |
1174 | case 1: { | 1266 | // if (param_selection_loc == 0) { |
1175 | trig->env_time = MAX(trig->env_time - 1, 0); | 1267 | // param_selection_loc = max_param; |
1176 | } break; | 1268 | // } else { |
1177 | case 2: { | 1269 | // param_selection_loc = MAX(param_selection_loc - 1, 0); |
1178 | trig->env_direction ^= 1; | 1270 | // } |
1179 | } break; | ||
1180 | case 3: { | ||
1181 | trig->duty_cycle = MAX(trig->duty_cycle - 1, 0); | ||
1182 | } break; | ||
1183 | case 4: { | ||
1184 | trig->sweep_number = MAX(trig->sweep_number - 1, 0); | ||
1185 | } break; | ||
1186 | case 5: { | ||
1187 | trig->sweep_time = MAX(trig->sweep_time - 1, 0); | ||
1188 | } break; | ||
1189 | case 6: { | ||
1190 | if (trig->sweep_direction == 0) { | ||
1191 | trig->sweep_direction = 1; | ||
1192 | } else { | ||
1193 | trig->sweep_direction = 0; | ||
1194 | } | ||
1195 | } break; | ||
1196 | } | 1271 | } |
1197 | } | 1272 | if (key_pressed(KEY_RIGHT)) { |
1198 | if (key_pressed(KEY_R)) { | 1273 | param_selection_loc += 1; |
1199 | switch (param_selection_loc) { | 1274 | // int max_param = 6; |
1200 | case 0: { | 1275 | // if (channel_selection_loc == 1) { |
1201 | trig->env_volume = MIN(trig->env_volume + 1, 15); | 1276 | // max_param = 3; |
1202 | } break; | 1277 | // } |
1203 | case 1: { | 1278 | // if (param_selection_loc == max_param) { |
1204 | trig->env_time = MIN(trig->env_time + 1, 7); | 1279 | // param_selection_loc = 0; |
1205 | } break; | 1280 | // } else { |
1206 | case 2: { | 1281 | // param_selection_loc = MIN(param_selection_loc + 1, max_param); |
1207 | trig->env_direction ^= 1; | 1282 | // } |
1208 | } break; | 1283 | } |
1209 | case 3: { | 1284 | if (key_pressed(KEY_R)) { |
1210 | trig->duty_cycle = MIN(trig->duty_cycle + 1, 3); | 1285 | sequences[2][trig_selection_loc].wave_a[param_selection_loc] += 1; |
1211 | } break; | 1286 | } |
1212 | case 4: { | 1287 | if (key_pressed(KEY_L)) { |
1213 | trig->sweep_number = MIN(trig->sweep_number + 1, 7); | 1288 | sequences[2][trig_selection_loc].wave_a[param_selection_loc] -= 1; |
1214 | } break; | ||
1215 | case 5: { | ||
1216 | trig->sweep_time = MIN(trig->sweep_time + 1, 7); | ||
1217 | } break; | ||
1218 | case 6: { | ||
1219 | trig->sweep_direction ^= 1; | ||
1220 | } break; | ||
1221 | } | 1289 | } |
1222 | } | 1290 | } |
1223 | 1291 | ||
@@ -1234,6 +1302,7 @@ handle_sequencer_input(void) { | |||
1234 | if (key_pressed(KEY_RIGHT)) { | 1302 | if (key_pressed(KEY_RIGHT)) { |
1235 | current_selection = SEQ_SELECT_TRIGGER; | 1303 | current_selection = SEQ_SELECT_TRIGGER; |
1236 | trig_selection_loc = 0; | 1304 | trig_selection_loc = 0; |
1305 | param_selection_loc = 0; | ||
1237 | } | 1306 | } |
1238 | if (key_pressed(KEY_UP)) { | 1307 | if (key_pressed(KEY_UP)) { |
1239 | if (channel_selection_loc == 0) { | 1308 | if (channel_selection_loc == 0) { |
@@ -1294,6 +1363,7 @@ render_sequencer_sprites(void) { | |||
1294 | void init_sequencer() { | 1363 | void init_sequencer() { |
1295 | init_sequencer_sprites(); | 1364 | init_sequencer_sprites(); |
1296 | SOUND_STATUS = SOUND_ENABLE; | 1365 | SOUND_STATUS = SOUND_ENABLE; |
1297 | SOUND_DMG_MASTER = sound_volume(SOUND_SQUARE1 | SOUND_SQUARE2 | SOUND_WAVE, 3); | 1366 | SOUND_DMG_MASTER = sound_volume( |
1367 | SOUND_SQUARE1 | SOUND_SQUARE2 | SOUND_WAVE, 3); | ||
1298 | SOUND_DSOUND_MASTER = SOUND_DMG25; | 1368 | SOUND_DSOUND_MASTER = SOUND_DMG25; |
1299 | } | 1369 | } |
@@ -5,6 +5,7 @@ | |||
5 | #include <stdio.h> | 5 | #include <stdio.h> |
6 | 6 | ||
7 | #include "common.h" | 7 | #include "common.h" |
8 | #include "bitmap.h" | ||
8 | 9 | ||
9 | typedef enum { | 10 | typedef enum { |
10 | TXT_MODE_TILED_BG, | 11 | TXT_MODE_TILED_BG, |
@@ -15,7 +16,7 @@ typedef struct Font { | |||
15 | // A pointer to an area of memory containing font data. | 16 | // A pointer to an area of memory containing font data. |
16 | // TODO: Should we unpack each char everytime or unpack everything into RAM? | 17 | // TODO: Should we unpack each char everytime or unpack everything into RAM? |
17 | // Maybe this should be optional? | 18 | // Maybe this should be optional? |
18 | u32 *data; | 19 | u16 *data; |
19 | // The char_map stores the index to the character position within the font | 20 | // The char_map stores the index to the character position within the font |
20 | // array depending on the ascii number we want to render. This allows | 21 | // array depending on the ascii number we want to render. This allows |
21 | // the usage reduced font sets, for example just uppercase letters and | 22 | // the usage reduced font sets, for example just uppercase letters and |
@@ -93,7 +94,12 @@ txt_putc_m3(char c) { | |||
93 | for (size_t i = 0; i < text_engine.font.char_height; ++i) { | 94 | for (size_t i = 0; i < text_engine.font.char_height; ++i) { |
94 | for (size_t j = 0; j < text_engine.font.char_width; ++j) { | 95 | for (size_t j = 0; j < text_engine.font.char_width; ++j) { |
95 | if ((tile.row[i] >> 4 * j) & 0x1) { | 96 | if ((tile.row[i] >> 4 * j) & 0x1) { |
96 | FRAMEBUFFER[y + i][x + j] = text_engine.font.color; | 97 | put_pixel_m4(x + j, y + i, 1, backbuffer); |
98 | // TODO: Clean this up please. | ||
99 | // put_pixel_m3(x + j, | ||
100 | // y + i, | ||
101 | // text_engine.font.color, | ||
102 | // FRAMEBUFFER); | ||
97 | } | 103 | } |
98 | } | 104 | } |
99 | } | 105 | } |