summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2021-05-07 18:55:12 +0200
committerBad Diode <bd@badd10de.dev>2021-05-07 18:55:12 +0200
commit269f2326171982912f50c2b6ef0cd272ec3c0108 (patch)
treeb9374201762337780bafaf8f01965bb338a505ec
parentc1ac9aa30fa1c33ac09963bdb2f6a42ffadaa6c8 (diff)
downloadgba-experiments-269f2326171982912f50c2b6ef0cd272ec3c0108.tar.gz
gba-experiments-269f2326171982912f50c2b6ef0cd272ec3c0108.zip
Initial implementation of mode4 rendering and parameter editing on CH3
-rw-r--r--src/bitmap.h64
-rw-r--r--src/common.h2
-rw-r--r--src/main.c7
-rw-r--r--src/sequencer.c368
-rw-r--r--src/text.h10
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.
30static void 8static 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.
149static void 127static inline void
150put_pixel_m4(int x, int y, u8 col_index, vu16 *buffer) { 128put_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
141static inline void
142put_pixel_m3(int x, int y, u16 color, Scanline *buffer) {
143 buffer[y][x] = color;
144}
145
146static inline void
147clear_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))
150static 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
199static inline void 200static inline void
200flip_page(void) { 201flip_page(void) {
202 backbuffer = (u16*)((u32)backbuffer ^ 0x0A000);
201 DISP_CTRL ^= DISP_PAGE; 203 DISP_CTRL ^= DISP_PAGE;
202} 204}
203 205
diff --git a/src/main.c b/src/main.c
index 3065842..d4d49cc 100644
--- a/src/main.c
+++ b/src/main.c
@@ -15,7 +15,12 @@
15int main(void) { 15int 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
20u32 sprite_note_names[] = { 24u32 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;
548int channel_selection_loc = 2; 553int channel_selection_loc = 2;
549SeqSelect current_selection = SEQ_SELECT_TRIGGER; 554SeqSelect current_selection = SEQ_SELECT_TRIGGER;
550 555
551SeqSprite seq_sprites[57] = {0}; 556SeqSprite seq_sprites[58] = {0};
552 557
553void 558void
554draw_wave_pattern(u8 *pattern, int x, int y, Color clr) { 559draw_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) {
1294void init_sequencer() { 1363void 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}
diff --git a/src/text.h b/src/text.h
index 3c0b3a8..9aa3fdd 100644
--- a/src/text.h
+++ b/src/text.h
@@ -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
9typedef enum { 10typedef 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 }