diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/sequencer.c | 778 |
1 files changed, 473 insertions, 305 deletions
diff --git a/src/sequencer.c b/src/sequencer.c index 43e6ffc..46e57ef 100644 --- a/src/sequencer.c +++ b/src/sequencer.c | |||
@@ -1,4 +1,98 @@ | |||
1 | #include "rng.c" | 1 | #include "rng.c" |
2 | #include "text.h" | ||
3 | |||
4 | // | ||
5 | // Assets. | ||
6 | // | ||
7 | |||
8 | #define ASSETS_DATA ((u32*)(MEM_VRAM + KB(32))) | ||
9 | |||
10 | static const u32 note_names[] = { | ||
11 | 0x000000e0, 0x202020e0, 0x0000000e, 0x080e020e, | ||
12 | 0x00000098, 0xa8a8a898, 0x00000038, 0x203b0a39, | ||
13 | 0x00000060, 0xa0a0a060, 0x0000000e, 0x080e020e, | ||
14 | 0x000000b8, 0x889888b8, 0x00000038, 0x203b0a39, | ||
15 | 0x000000e0, 0x206020e0, 0x0000000e, 0x080e020e, | ||
16 | 0x000000e0, 0x20602020, 0x0000000e, 0x080e020e, | ||
17 | 0x000000b8, 0x8888a8b8, 0x00000038, 0x203b0a39, | ||
18 | 0x000000e0, 0x2020a0e0, 0x0000000e, 0x080e020e, | ||
19 | 0x000000b8, 0xa8a8b8a8, 0x00000038, 0x203b0a39, | ||
20 | 0x000000e0, 0xa0a0e0a0, 0x0000000e, 0x080e020e, | ||
21 | 0x000000b8, 0xa898a8b8, 0x00000038, 0x203b0a39, | ||
22 | 0x000000e0, 0xa060a0e0, 0x0000000e, 0x080e020e, | ||
23 | 0x000000e0, 0x202020e0, 0x0000000e, 0x080c080e, | ||
24 | 0x00000098, 0xa8a8a898, 0x00000038, 0x20332239, | ||
25 | 0x00000060, 0xa0a0a060, 0x0000000e, 0x080c080e, | ||
26 | 0x000000b8, 0x889888b8, 0x00000038, 0x20332239, | ||
27 | 0x000000e0, 0x206020e0, 0x0000000e, 0x080c080e, | ||
28 | 0x000000e0, 0x20602020, 0x0000000e, 0x080c080e, | ||
29 | 0x000000b8, 0x8888a8b8, 0x00000038, 0x20332239, | ||
30 | 0x000000e0, 0x2020a0e0, 0x0000000e, 0x080c080e, | ||
31 | 0x000000b8, 0xa8a8b8a8, 0x00000038, 0x20332239, | ||
32 | 0x000000e0, 0xa0a0e0a0, 0x0000000e, 0x080c080e, | ||
33 | 0x000000b8, 0xa898a8b8, 0x00000038, 0x20332239, | ||
34 | 0x000000e0, 0xa060a0e0, 0x0000000e, 0x080c080e, | ||
35 | 0x000000e0, 0x202020e0, 0x0000000a, 0x0a0e0808, | ||
36 | 0x00000098, 0xa8a8a898, 0x00000028, 0x283b2221, | ||
37 | 0x00000060, 0xa0a0a060, 0x0000000a, 0x0a0e0808, | ||
38 | 0x000000b8, 0x889888b8, 0x00000028, 0x283b2221, | ||
39 | 0x000000e0, 0x206020e0, 0x0000000a, 0x0a0e0808, | ||
40 | 0x000000e0, 0x20602020, 0x0000000a, 0x0a0e0808, | ||
41 | 0x000000b8, 0x8888a8b8, 0x00000028, 0x283b2221, | ||
42 | 0x000000e0, 0x2020a0e0, 0x0000000a, 0x0a0e0808, | ||
43 | 0x000000b8, 0xa8a8b8a8, 0x00000028, 0x283b2221, | ||
44 | 0x000000e0, 0xa0a0e0a0, 0x0000000a, 0x0a0e0808, | ||
45 | 0x000000b8, 0xa898a8b8, 0x00000028, 0x283b2221, | ||
46 | 0x000000e0, 0xa060a0e0, 0x0000000a, 0x0a0e0808, | ||
47 | 0x000000e0, 0x202020e0, 0x0000000e, 0x020e080e, | ||
48 | 0x00000098, 0xa8a8a898, 0x00000038, 0x083b2239, | ||
49 | 0x00000060, 0xa0a0a060, 0x0000000e, 0x020e080e, | ||
50 | 0x000000b8, 0x889888b8, 0x00000038, 0x083b2239, | ||
51 | 0x000000e0, 0x206020e0, 0x0000000e, 0x020e080e, | ||
52 | 0x000000e0, 0x20602020, 0x0000000e, 0x020e080e, | ||
53 | 0x000000b8, 0x8888a8b8, 0x00000038, 0x083b2239, | ||
54 | 0x000000e0, 0x2020a0e0, 0x0000000e, 0x020e080e, | ||
55 | 0x000000b8, 0xa8a8b8a8, 0x00000038, 0x083b2239, | ||
56 | 0x000000e0, 0xa0a0e0a0, 0x0000000e, 0x020e080e, | ||
57 | 0x000000b8, 0xa898a8b8, 0x00000038, 0x083b2239, | ||
58 | 0x000000e0, 0xa060a0e0, 0x0000000e, 0x020e080e, | ||
59 | 0x000000e0, 0x202020e0, 0x0000000e, 0x020e0a0e, | ||
60 | 0x00000098, 0xa8a8a898, 0x00000038, 0x083b2a39, | ||
61 | 0x00000060, 0xa0a0a060, 0x0000000e, 0x020e0a0e, | ||
62 | 0x000000b8, 0x889888b8, 0x00000038, 0x083b2a39, | ||
63 | 0x000000e0, 0x206020e0, 0x0000000e, 0x020e0a0e, | ||
64 | 0x000000e0, 0x20602020, 0x0000000e, 0x020e0a0e, | ||
65 | 0x000000b8, 0x8888a8b8, 0x00000038, 0x083b2a39, | ||
66 | 0x000000e0, 0x2020a0e0, 0x0000000e, 0x020e0a0e, | ||
67 | 0x000000b8, 0xa8a8b8a8, 0x00000038, 0x083b2a39, | ||
68 | 0x000000e0, 0xa0a0e0a0, 0x0000000e, 0x020e0a0e, | ||
69 | 0x000000b8, 0xa898a8b8, 0x00000038, 0x083b2a39, | ||
70 | 0x000000e0, 0xa060a0e0, 0x0000000e, 0x020e0a0e, | ||
71 | 0x000000e0, 0x202020e0, 0x0000000e, 0x08040202, | ||
72 | 0x00000098, 0xa8a8a898, 0x00000038, 0x20130a09, | ||
73 | 0x00000060, 0xa0a0a060, 0x0000000e, 0x08040202, | ||
74 | 0x000000b8, 0x889888b8, 0x00000038, 0x20130a09, | ||
75 | 0x000000e0, 0x206020e0, 0x0000000e, 0x08040202, | ||
76 | 0x000000e0, 0x20602020, 0x0000000e, 0x08040202, | ||
77 | 0x000000b8, 0x8888a8b8, 0x00000038, 0x20130a09, | ||
78 | 0x000000e0, 0x2020a0e0, 0x0000000e, 0x08040202, | ||
79 | 0x000000b8, 0xa8a8b8a8, 0x00000038, 0x20130a09, | ||
80 | 0x000000e0, 0xa0a0e0a0, 0x0000000e, 0x08040202, | ||
81 | 0x000000b8, 0xa898a8b8, 0x00000038, 0x20130a09, | ||
82 | 0x000000e0, 0xa060a0e0, 0x0000000e, 0x08040202, | ||
83 | 0x000000e0, 0x202020e0, 0x0000000e, 0x0a0e0a0e, | ||
84 | }; | ||
85 | |||
86 | static const u32 channel_buttons[] = { | ||
87 | 0xff017111, 0x117101ff, 0xff008585, 0x879500ff, | ||
88 | 0x0f080808, 0x0808080f, 0xff01b989, 0x89b901ff, | ||
89 | 0xff004242, 0x434a00ff, 0x0f080909, 0x0909080f, | ||
90 | 0xff015d45, 0xc55d01ff, 0xff00a1a1, 0xa1a500ff, | ||
91 | 0x0f080a0a, 0x0a0a080f, 0xff015d45, 0xc55d01ff, | ||
92 | 0xff00a1a1, 0xa12500ff, 0x0f080a0a, 0x0a0b080f, | ||
93 | 0xff01c141, 0xc14101ff, 0xff00151c, 0x141400ff, | ||
94 | 0x0f080808, 0x0808080f, | ||
95 | }; | ||
2 | 96 | ||
3 | // | 97 | // |
4 | // Globals. | 98 | // Globals. |
@@ -12,7 +106,7 @@ static int bpm = 115; | |||
12 | static int step_counter = 0; | 106 | static int step_counter = 0; |
13 | int trig_selection_loc = 0; | 107 | int trig_selection_loc = 0; |
14 | int param_selection_loc = 64; | 108 | int param_selection_loc = 64; |
15 | int channel_selection_loc = 2; | 109 | int channel_selection_loc = 0; |
16 | SeqSelect current_selection = SEQ_SELECT_TRIGGER; | 110 | SeqSelect current_selection = SEQ_SELECT_TRIGGER; |
17 | 111 | ||
18 | // | 112 | // |
@@ -61,19 +155,19 @@ typedef struct SeqTrigger { | |||
61 | static SeqTrigger sequences[3][16] = { | 155 | static SeqTrigger sequences[3][16] = { |
62 | // Synth 1. | 156 | // Synth 1. |
63 | { | 157 | { |
64 | {false, NOTE_C_4, 8, 4, 0, 2, 0, 0, 0, 0, 0, {0}, {0}}, | 158 | {true, NOTE_C_4, 8, 4, 0, 2, 0, 0, 0, 0, 0, {0}, {0}}, |
65 | {false, NOTE_D_4, 8, 4, 0, 2, 0, 0, 0, 0, 0, {0}, {0}}, | 159 | {true, NOTE_D_4, 8, 4, 0, 2, 0, 0, 0, 0, 0, {0}, {0}}, |
66 | {false, NOTE_E_4, 8, 4, 0, 2, 0, 0, 0, 0, 0, {0}, {0}}, | 160 | {false, NOTE_E_4, 8, 4, 0, 2, 0, 0, 0, 0, 0, {0}, {0}}, |
67 | {false, NOTE_F_4, 8, 4, 0, 2, 0, 0, 0, 0, 0, {0}, {0}}, | 161 | {false, NOTE_F_4, 8, 4, 0, 2, 0, 0, 0, 0, 0, {0}, {0}}, |
68 | {false, NOTE_G_4, 8, 4, 0, 2, 0, 0, 0, 0, 0, {0}, {0}}, | 162 | {true, NOTE_G_4, 8, 4, 0, 2, 0, 0, 0, 0, 0, {0}, {0}}, |
69 | {false, NOTE_A_4, 8, 4, 0, 2, 0, 0, 0, 0, 0, {0}, {0}}, | 163 | {true, NOTE_A_4, 8, 4, 0, 2, 0, 0, 0, 0, 0, {0}, {0}}, |
70 | {false, NOTE_B_4, 8, 4, 0, 2, 0, 0, 0, 0, 0, {0}, {0}}, | 164 | {false, NOTE_B_4, 8, 4, 0, 2, 0, 0, 0, 0, 0, {0}, {0}}, |
71 | {false, NOTE_C_5, 8, 4, 0, 2, 0, 0, 0, 0, 0, {0}, {0}}, | 165 | {false, NOTE_C_5, 8, 4, 0, 2, 0, 0, 0, 0, 0, {0}, {0}}, |
166 | {true, NOTE_C_4, 8, 4, 0, 2, 0, 0, 0, 0, 0, {0}, {0}}, | ||
167 | {true, NOTE_C_4, 8, 4, 0, 2, 0, 0, 0, 0, 0, {0}, {0}}, | ||
72 | {false, NOTE_C_4, 8, 4, 0, 2, 0, 0, 0, 0, 0, {0}, {0}}, | 168 | {false, NOTE_C_4, 8, 4, 0, 2, 0, 0, 0, 0, 0, {0}, {0}}, |
73 | {false, NOTE_C_4, 8, 4, 0, 2, 0, 0, 0, 0, 0, {0}, {0}}, | 169 | {false, NOTE_C_4, 8, 4, 0, 2, 0, 0, 0, 0, 0, {0}, {0}}, |
74 | {false, NOTE_C_4, 8, 4, 0, 2, 0, 0, 0, 0, 0, {0}, {0}}, | 170 | {true, NOTE_C_4, 8, 4, 0, 2, 0, 0, 0, 0, 0, {0}, {0}}, |
75 | {false, NOTE_C_4, 8, 4, 0, 2, 0, 0, 0, 0, 0, {0}, {0}}, | ||
76 | {false, NOTE_C_4, 8, 4, 0, 2, 0, 0, 0, 0, 0, {0}, {0}}, | ||
77 | {false, NOTE_C_4, 8, 4, 0, 2, 0, 0, 0, 0, 0, {0}, {0}}, | 171 | {false, NOTE_C_4, 8, 4, 0, 2, 0, 0, 0, 0, 0, {0}, {0}}, |
78 | {false, NOTE_C_4, 8, 4, 0, 2, 0, 0, 0, 0, 0, {0}, {0}}, | 172 | {false, NOTE_C_4, 8, 4, 0, 2, 0, 0, 0, 0, 0, {0}, {0}}, |
79 | {false, NOTE_C_4, 8, 4, 0, 2, 0, 0, 0, 0, 0, {0}, {0}}, | 173 | {false, NOTE_C_4, 8, 4, 0, 2, 0, 0, 0, 0, 0, {0}, {0}}, |
@@ -99,22 +193,22 @@ static SeqTrigger sequences[3][16] = { | |||
99 | }, | 193 | }, |
100 | // Synth 3. | 194 | // Synth 3. |
101 | { | 195 | { |
102 | {true, NOTE_C_5, 8, 4, 0, 2, 0, 0, 0, 3, 0, {0xffffffff, 0x00000000, 0xffffffff, 0x00000000}, {0}}, | 196 | {true, NOTE_C_5, 8, 4, 0, 2, 0, 0, 0, 3, 0, {0}, {0}}, |
103 | {true, NOTE_D_5, 8, 4, 0, 2, 0, 0, 0, 3, 0, {0xffffffff, 0x00000000, 0xffffffff, 0x00000000}, {0}}, | 197 | {true, NOTE_D_5, 8, 4, 0, 2, 0, 0, 0, 3, 0, {0}, {0}}, |
104 | {true, NOTE_E_5, 8, 4, 0, 2, 0, 0, 0, 3, 0, {0xffffffff, 0x00000000, 0xffffffff, 0x00000000}, {0}}, | 198 | {true, NOTE_E_5, 8, 4, 0, 2, 0, 0, 0, 3, 0, {0}, {0}}, |
105 | {true, NOTE_F_5, 8, 4, 0, 2, 0, 0, 0, 3, 0, {0xffffffff, 0x00000000, 0xffffffff, 0x00000000}, {0}}, | 199 | {true, NOTE_F_5, 8, 4, 0, 2, 0, 0, 0, 3, 0, {0}, {0}}, |
106 | {true, NOTE_G_5, 8, 4, 0, 2, 0, 0, 0, 3, 0, {0xffffffff, 0x00000000, 0xffffffff, 0x00000000}, {0}}, | 200 | {true, NOTE_G_5, 8, 4, 0, 2, 0, 0, 0, 3, 0, {0}, {0}}, |
107 | {true, NOTE_A_5, 8, 4, 0, 2, 0, 0, 0, 3, 0, {0xffffffff, 0x00000000, 0xffffffff, 0x00000000}, {0}}, | 201 | {true, NOTE_A_5, 8, 4, 0, 2, 0, 0, 0, 3, 0, {0}, {0}}, |
108 | {true, NOTE_B_5, 8, 4, 0, 2, 0, 0, 0, 3, 0, {0xffffffff, 0x00000000, 0xffffffff, 0x00000000}, {0}}, | 202 | {true, NOTE_B_5, 8, 4, 0, 2, 0, 0, 0, 3, 0, {0}, {0}}, |
109 | {true, NOTE_C_6, 8, 4, 0, 2, 0, 0, 0, 3, 0, {0xffffffff, 0x00000000, 0xffffffff, 0x00000000}, {0}}, | 203 | {true, NOTE_C_6, 8, 4, 0, 2, 0, 0, 0, 3, 0, {0}, {0}}, |
110 | {true, NOTE_C_5, 8, 4, 0, 2, 0, 0, 0, 3, 0, {0xffffffff, 0x00000000, 0xffffffff, 0x00000000}, {0}}, | 204 | {true, NOTE_C_5, 8, 4, 0, 2, 0, 0, 0, 3, 0, {0}, {0}}, |
111 | {true, NOTE_D_5, 8, 4, 0, 2, 0, 0, 0, 3, 0, {0xffffffff, 0x00000000, 0xffffffff, 0x00000000}, {0}}, | 205 | {true, NOTE_D_5, 8, 4, 0, 2, 0, 0, 0, 3, 0, {0}, {0}}, |
112 | {true, NOTE_E_5, 8, 4, 0, 2, 0, 0, 0, 3, 0, {0xffffffff, 0x00000000, 0xffffffff, 0x00000000}, {0}}, | 206 | {true, NOTE_E_5, 8, 4, 0, 2, 0, 0, 0, 3, 0, {0}, {0}}, |
113 | {true, NOTE_F_5, 8, 4, 0, 2, 0, 0, 0, 3, 0, {0xffffffff, 0x00000000, 0xffffffff, 0x00000000}, {0}}, | 207 | {true, NOTE_F_5, 8, 4, 0, 2, 0, 0, 0, 3, 0, {0}, {0}}, |
114 | {true, NOTE_G_5, 8, 4, 0, 2, 0, 0, 0, 3, 0, {0xffffffff, 0x00000000, 0xffffffff, 0x00000000}, {0}}, | 208 | {true, NOTE_G_5, 8, 4, 0, 2, 0, 0, 0, 3, 0, {0}, {0}}, |
115 | {true, NOTE_A_5, 8, 4, 0, 2, 0, 0, 0, 3, 0, {0xffffffff, 0x00000000, 0xffffffff, 0x00000000}, {0}}, | 209 | {true, NOTE_A_5, 8, 4, 0, 2, 0, 0, 0, 3, 0, {0}, {0}}, |
116 | {true, NOTE_B_5, 8, 4, 0, 2, 0, 0, 0, 3, 0, {0xffffffff, 0x00000000, 0xffffffff, 0x00000000}, {0}}, | 210 | {true, NOTE_B_5, 8, 4, 0, 2, 0, 0, 0, 3, 0, {0}, {0}}, |
117 | {true, NOTE_C_6, 8, 4, 0, 2, 0, 0, 0, 3, 0, {0xffffffff, 0x00000000, 0xffffffff, 0x00000000}, {0}}, | 211 | {true, NOTE_C_6, 8, 4, 0, 2, 0, 0, 0, 3, 0, {0}, {0}}, |
118 | }, | 212 | }, |
119 | }; | 213 | }; |
120 | 214 | ||
@@ -127,20 +221,53 @@ static SeqTrigger sequences[3][16] = { | |||
127 | #define TRIG_OFFSET_Y (TRIG_H + 7) | 221 | #define TRIG_OFFSET_Y (TRIG_H + 7) |
128 | 222 | ||
129 | void | 223 | void |
130 | draw_triggers(void) { | 224 | clear_trigger(size_t i) { |
131 | for (size_t i = 0; i < 8; i++) { | 225 | size_t offset_x = TRIG_OFFSET_X * (i % 8); |
132 | size_t x0 = TRIG_START_X + TRIG_OFFSET_X * i; | 226 | size_t offset_y = i < 8 ? 0 : TRIG_OFFSET_Y; |
133 | size_t x1 = TRIG_START_X + TRIG_W + TRIG_OFFSET_X * i; | 227 | size_t x0 = TRIG_START_X + offset_x + 1; |
134 | size_t y0 = TRIG_START_Y; | 228 | size_t x1 = TRIG_START_X + offset_x + TRIG_W - 1; |
135 | size_t y1 = TRIG_START_Y + TRIG_H; | 229 | size_t y0 = TRIG_START_Y + offset_y + 1; |
136 | draw_rect(x0, y0, x1, y1, 1); | 230 | size_t y1 = TRIG_START_Y + offset_y + TRIG_H - 1; |
231 | draw_filled_rect(x0, y0, x1, y1, 0); | ||
232 | } | ||
233 | |||
234 | void | ||
235 | draw_trigger(size_t chan, size_t i) { | ||
236 | if (sequences[chan][i].trigger) { | ||
237 | size_t offset_x = TRIG_OFFSET_X * (i % 8); | ||
238 | size_t offset_y = i < 8 ? 0 : TRIG_OFFSET_Y; | ||
239 | size_t x = TRIG_START_X + offset_x; | ||
240 | size_t y = TRIG_START_Y + offset_y; | ||
241 | Tile *tiles = ASSETS_DATA; | ||
242 | tiles += 2 * sequences[chan][i].note; | ||
243 | draw_tile(x, y, tiles, true); | ||
244 | draw_tile(x + 8, y, tiles + 1, true); | ||
245 | } else { | ||
246 | clear_trigger(i); | ||
137 | } | 247 | } |
138 | for (size_t i = 0; i < 8; i++) { | 248 | } |
139 | size_t x0 = TRIG_START_X + TRIG_OFFSET_X * i; | 249 | |
140 | size_t x1 = TRIG_START_X + TRIG_W + TRIG_OFFSET_X * i; | 250 | void |
141 | size_t y0 = TRIG_START_Y + TRIG_OFFSET_Y; | 251 | draw_trig_cursor(size_t i, u8 clr) { |
142 | size_t y1 = TRIG_START_Y + TRIG_H + TRIG_OFFSET_Y; | 252 | size_t offset_x = TRIG_OFFSET_X * (i % 8); |
253 | size_t offset_y = i < 8 ? 1 : 1 + TRIG_OFFSET_Y; | ||
254 | size_t x0 = TRIG_START_X + offset_x; | ||
255 | size_t x1 = TRIG_START_X + TRIG_W + offset_x; | ||
256 | size_t y = TRIG_START_Y + TRIG_H + offset_y; | ||
257 | draw_line(x0, y, x1, y, clr); | ||
258 | } | ||
259 | |||
260 | void | ||
261 | draw_triggers(void) { | ||
262 | for (size_t i = 0; i < 16; i++) { | ||
263 | size_t offset_x = TRIG_OFFSET_X * (i % 8); | ||
264 | size_t offset_y = i < 8 ? 0 : 0 + TRIG_OFFSET_Y; | ||
265 | size_t x0 = TRIG_START_X + offset_x; | ||
266 | size_t x1 = TRIG_START_X + offset_x + TRIG_W; | ||
267 | size_t y0 = TRIG_START_Y + offset_y; | ||
268 | size_t y1 = TRIG_START_Y + offset_y + TRIG_H; | ||
143 | draw_rect(x0, y0, x1, y1, 1); | 269 | draw_rect(x0, y0, x1, y1, 1); |
270 | draw_trigger(channel_selection_loc, i); | ||
144 | } | 271 | } |
145 | } | 272 | } |
146 | 273 | ||
@@ -152,16 +279,6 @@ void | |||
152 | draw_channels(void) { | 279 | draw_channels(void) { |
153 | // Contains 5 channel buttons: Ch. 1-4 + FM. We are only drawing the DMG | 280 | // Contains 5 channel buttons: Ch. 1-4 + FM. We are only drawing the DMG |
154 | // channels for now, since FM may take some time to develop. | 281 | // channels for now, since FM may take some time to develop. |
155 | u32 channel_buttons[] = { | ||
156 | 0xff017111, 0x117101ff, 0xff008585, 0x879500ff, | ||
157 | 0x0f080808, 0x0808080f, 0xff01b989, 0x89b901ff, | ||
158 | 0xff004242, 0x434a00ff, 0x0f080909, 0x0909080f, | ||
159 | 0xff015d45, 0xc55d01ff, 0xff00a1a1, 0xa1a500ff, | ||
160 | 0x0f080a0a, 0x0a0a080f, 0xff015d45, 0xc55d01ff, | ||
161 | 0xff00a1a1, 0xa12500ff, 0x0f080a0a, 0x0a0b080f, | ||
162 | 0xff01c141, 0xc14101ff, 0xff00151c, 0x141400ff, | ||
163 | 0x0f080808, 0x0808080f, | ||
164 | }; | ||
165 | Tile channel_tiles[3 * 4] = {0}; | 282 | Tile channel_tiles[3 * 4] = {0}; |
166 | unpack_tiles(channel_buttons, channel_tiles, 3 * 4); | 283 | unpack_tiles(channel_buttons, channel_tiles, 3 * 4); |
167 | size_t k = 0; | 284 | size_t k = 0; |
@@ -213,9 +330,9 @@ irq_timer_0(void) { | |||
213 | // TODO: Should we compare if previous and current wave are the | 330 | // TODO: Should we compare if previous and current wave are the |
214 | // same before updating? | 331 | // same before updating? |
215 | SOUND_WAVE_MODE = SOUND_WAVE_BANK_SELECT(1); | 332 | SOUND_WAVE_MODE = SOUND_WAVE_BANK_SELECT(1); |
216 | memcpy(SOUND_WAVE_RAM, trig->wave_a, 16); | 333 | dma_copy(SOUND_WAVE_RAM, trig->wave_a, 16, 3); |
217 | SOUND_WAVE_MODE = SOUND_WAVE_BANK_SELECT(0); | 334 | SOUND_WAVE_MODE = SOUND_WAVE_BANK_SELECT(0); |
218 | memcpy(SOUND_WAVE_RAM, trig->wave_b, 16); | 335 | dma_copy(SOUND_WAVE_RAM, trig->wave_b, 16, 3); |
219 | 336 | ||
220 | switch (trig->wave_mode) { | 337 | switch (trig->wave_mode) { |
221 | case 0: { | 338 | case 0: { |
@@ -261,252 +378,306 @@ irq_timer_0(void) { | |||
261 | step_counter = (step_counter + 1) % 16; | 378 | step_counter = (step_counter + 1) % 16; |
262 | } | 379 | } |
263 | 380 | ||
381 | void | ||
382 | set_time(int bpm) { | ||
383 | // The number of ticks of a 1024 cycle clock in a step based on the BPM can | ||
384 | // be calculated as: | ||
385 | // X bpm -> 60000 / 4 / bpm = Y ms = Ye-3 s | ||
386 | // Y ms -> Ye-3 / 59.99e-9 / 1024 = Z ticks | ||
387 | // We have to operate on integer values, so the numbers have been | ||
388 | // precalculated to `n_ticks = 244181 / bmp` | ||
389 | int n_ticks = -244181 / bpm; | ||
390 | irs_set(IRQ_TIMER_0, irq_timer_0); | ||
391 | TIMER_DATA_0 = n_ticks; | ||
392 | TIMER_CTRL_0 = TIMER_CTRL_IRQ | TIMER_CTRL_ENABLE | TIMER_CTRL_FREQ_3; | ||
393 | } | ||
394 | |||
264 | #define SEQ_N_CHANNELS 3 | 395 | #define SEQ_N_CHANNELS 3 |
265 | 396 | ||
266 | void | 397 | void |
267 | handle_sequencer_input(void) { | 398 | trigger_cursor(void) { |
268 | poll_keys(); | ||
269 | SeqTrigger *trig = &sequences[channel_selection_loc][trig_selection_loc]; | 399 | SeqTrigger *trig = &sequences[channel_selection_loc][trig_selection_loc]; |
270 | if (current_selection == SEQ_SELECT_TRIGGER) { | 400 | if (key_tap(KEY_LEFT)) { |
271 | if (key_tap(KEY_LEFT)) { | 401 | if (trig_selection_loc == 0 || trig_selection_loc == 8) { |
272 | if (trig_selection_loc == 0 || trig_selection_loc == 8) { | 402 | // current_selection = SEQ_SELECT_CHANNEL; |
273 | current_selection = SEQ_SELECT_CHANNEL; | 403 | } else { |
274 | } else { | 404 | draw_trig_cursor(trig_selection_loc, 0); |
275 | trig_selection_loc = MAX(trig_selection_loc - 1, 0); | 405 | trig_selection_loc = MAX(trig_selection_loc - 1, 0); |
276 | } | 406 | draw_trig_cursor(trig_selection_loc, 3); |
277 | } else if (key_tap(KEY_RIGHT)) { | ||
278 | if (trig_selection_loc != 7) { | ||
279 | trig_selection_loc = MIN(trig_selection_loc + 1, 15); | ||
280 | } | ||
281 | } else if (key_tap(KEY_UP) || key_tap(KEY_DOWN)) { | ||
282 | trig_selection_loc = (trig_selection_loc + 8) % 16; | ||
283 | } else if (key_tap(KEY_B)) { | ||
284 | trig->trigger ^= 1; | ||
285 | } else if (key_tap(KEY_L)) { | ||
286 | if (trig->trigger) { | ||
287 | trig->note = MAX(trig->note - 1, NOTE_C_2); | ||
288 | } | ||
289 | } else if (key_tap(KEY_R)) { | ||
290 | if (trig->trigger) { | ||
291 | trig->note = MIN( trig->note + 1, NOTE_C_8); | ||
292 | } | ||
293 | } else if (key_tap(KEY_A)) { | ||
294 | // Switch to parameter selection. | ||
295 | current_selection = SEQ_SELECT_PARAMETER; | ||
296 | } | ||
297 | } else if (current_selection == SEQ_SELECT_PARAMETER) { | ||
298 | if (channel_selection_loc < 2) { | ||
299 | // Move through the selected synth parameters. | ||
300 | if (key_tap(KEY_LEFT)) { | ||
301 | int max_param = 6; | ||
302 | if (channel_selection_loc == 1) { | ||
303 | max_param = 3; | ||
304 | } | ||
305 | if (param_selection_loc == 0) { | ||
306 | param_selection_loc = max_param; | ||
307 | } else { | ||
308 | param_selection_loc = MAX(param_selection_loc - 1, 0); | ||
309 | } | ||
310 | } | ||
311 | if (key_tap(KEY_RIGHT)) { | ||
312 | int max_param = 6; | ||
313 | if (channel_selection_loc == 1) { | ||
314 | max_param = 3; | ||
315 | } | ||
316 | if (param_selection_loc == max_param) { | ||
317 | param_selection_loc = 0; | ||
318 | } else { | ||
319 | param_selection_loc = MIN(param_selection_loc + 1, max_param); | ||
320 | } | ||
321 | } | ||
322 | |||
323 | // Adjust the parameters up or down. | ||
324 | if (key_tap(KEY_L) || key_tap(KEY_R)) { | ||
325 | int inc; | ||
326 | if (key_tap(KEY_L)) { | ||
327 | inc = -1; | ||
328 | } else { | ||
329 | inc = 1; | ||
330 | } | ||
331 | switch (param_selection_loc) { | ||
332 | case 0: { | ||
333 | trig->env_volume = CLAMP(trig->env_volume + inc, 0, 15); | ||
334 | } break; | ||
335 | case 1: { | ||
336 | trig->env_time = CLAMP(trig->env_time + inc, 0, 7); | ||
337 | } break; | ||
338 | case 2: { | ||
339 | trig->env_direction ^= 1; | ||
340 | } break; | ||
341 | case 3: { | ||
342 | trig->duty_cycle = CLAMP(trig->duty_cycle + inc, 0, 3); | ||
343 | } break; | ||
344 | case 4: { | ||
345 | trig->sweep_number = CLAMP(trig->sweep_number + inc, 0, 7); | ||
346 | } break; | ||
347 | case 5: { | ||
348 | trig->sweep_time = CLAMP(trig->sweep_time + inc, 0, 7); | ||
349 | } break; | ||
350 | case 6: { | ||
351 | if (trig->sweep_direction == 0) { | ||
352 | trig->sweep_direction = 1; | ||
353 | } else { | ||
354 | trig->sweep_direction = 0; | ||
355 | } | ||
356 | } break; | ||
357 | } | ||
358 | } | ||
359 | } else if (channel_selection_loc == 2) { | ||
360 | if (key_tap(KEY_LEFT) || key_tap(KEY_RIGHT)) { | ||
361 | int inc = 0; | ||
362 | int loc = param_selection_loc; | ||
363 | if (key_tap(KEY_RIGHT)) { | ||
364 | if (loc == 15 || loc == 31) { | ||
365 | inc = 17; | ||
366 | } else if (loc != 47 && loc != 63){ | ||
367 | inc = 1; | ||
368 | } | ||
369 | } else { | ||
370 | if (loc == 32 || loc == 48) { | ||
371 | inc = -17; | ||
372 | } else if (loc != 16 && loc != 64){ | ||
373 | inc = -1; | ||
374 | } | ||
375 | } | ||
376 | param_selection_loc = CLAMP(loc + inc, 0, 71); | ||
377 | } | ||
378 | if (key_tap(KEY_UP) || key_tap(KEY_DOWN)) { | ||
379 | int inc = 0; | ||
380 | int loc = param_selection_loc; | ||
381 | if (key_tap(KEY_UP)) { | ||
382 | if ((loc >= 16 && loc < 32) || (loc >= 48 && loc < 64)) { | ||
383 | inc = -16; | ||
384 | } else if (loc == 64) { | ||
385 | inc = -48; | ||
386 | } else if (loc == 65) { | ||
387 | inc = -45; | ||
388 | } else if (loc == 66) { | ||
389 | inc = -42; | ||
390 | } else if (loc == 67) { | ||
391 | inc = -39; | ||
392 | } else if (loc == 68) { | ||
393 | inc = -20; | ||
394 | } else if (loc == 69) { | ||
395 | inc = -17; | ||
396 | } else if (loc == 70) { | ||
397 | inc = -14; | ||
398 | } else if (loc == 71) { | ||
399 | inc = -11; | ||
400 | } | ||
401 | } else { | ||
402 | if (loc < 16 || (loc >= 32 && loc < 48)) { | ||
403 | inc = 16; | ||
404 | } else if (loc >= 16 && loc <= 19){ | ||
405 | inc = 48 - (loc - 16); | ||
406 | } else if (loc >= 20 && loc <= 23){ | ||
407 | inc = 45 - (loc - 20); | ||
408 | } else if (loc >= 24 && loc <= 27){ | ||
409 | inc = 42 - (loc - 24); | ||
410 | } else if (loc >= 28 && loc <= 31){ | ||
411 | inc = 39 - (loc - 28); | ||
412 | } else if (loc >= 48 && loc <= 51){ | ||
413 | inc = 20 - (loc - 48); | ||
414 | } else if (loc >= 52 && loc <= 55){ | ||
415 | inc = 17 - (loc - 52); | ||
416 | } else if (loc >= 56 && loc <= 59){ | ||
417 | inc = 14 - (loc - 56); | ||
418 | } else if (loc >= 60 && loc <= 63){ | ||
419 | inc = 11 - (loc - 60); | ||
420 | } | ||
421 | } | ||
422 | param_selection_loc = CLAMP(loc + inc, 0, 71); | ||
423 | } | ||
424 | if (key_tap(KEY_R) || key_tap(KEY_L)) { | ||
425 | int odd = param_selection_loc & 0x1; | ||
426 | int inc; | ||
427 | if (key_tap(KEY_R)) { | ||
428 | inc = 1; | ||
429 | } else { | ||
430 | inc = -1; | ||
431 | } | ||
432 | // Wave: AA BB CC DD ... | ||
433 | // ^^ | ||
434 | // |`- odd | ||
435 | // `-- even | ||
436 | if (param_selection_loc < 32) { | ||
437 | u8 byte_number = param_selection_loc >> 1; | ||
438 | u8 byte = sequences[2][trig_selection_loc].wave_a[byte_number]; | ||
439 | if (odd) { | ||
440 | byte = (~0xF & byte) | ((byte + inc) & 0xF); | ||
441 | } else { | ||
442 | byte = (0xF & byte) | (((byte >> 4) + inc) & 0xF) << 4; | ||
443 | } | ||
444 | sequences[2][trig_selection_loc].wave_a[byte_number] = byte; | ||
445 | } else if (param_selection_loc < 64){ | ||
446 | u8 byte_number = (param_selection_loc - 32) >> 1; | ||
447 | u8 byte = sequences[2][trig_selection_loc].wave_b[byte_number]; | ||
448 | if (odd) { | ||
449 | byte = (~0xF & byte) | (byte + inc); | ||
450 | } else { | ||
451 | byte = (0xF & byte) | ((byte >> 4) + inc) << 4; | ||
452 | } | ||
453 | sequences[2][trig_selection_loc].wave_b[byte_number] = byte; | ||
454 | } else if (param_selection_loc == 64){ | ||
455 | memcpy(&trig->wave_a, &sine_wave, 16); | ||
456 | } else if (param_selection_loc == 65){ | ||
457 | memcpy(&trig->wave_a, &saw_wave, 16); | ||
458 | } else if (param_selection_loc == 66){ | ||
459 | memcpy(&trig->wave_a, &square_wave, 16); | ||
460 | } else if (param_selection_loc == 67){ | ||
461 | u32 rand_wave[4] = { | ||
462 | rng32(), rng32(), rng32(), rng32(), | ||
463 | }; | ||
464 | memcpy(&trig->wave_a, &rand_wave, 16); | ||
465 | } else if (param_selection_loc == 68){ | ||
466 | memcpy(&trig->wave_b, &sine_wave, 16); | ||
467 | } else if (param_selection_loc == 69){ | ||
468 | memcpy(&trig->wave_b, &saw_wave, 16); | ||
469 | } else if (param_selection_loc == 70){ | ||
470 | memcpy(&trig->wave_b, &square_wave, 16); | ||
471 | } else if (param_selection_loc == 71){ | ||
472 | u32 rand_wave[4] = { | ||
473 | rng32(), rng32(), rng32(), rng32(), | ||
474 | }; | ||
475 | memcpy(&trig->wave_b, &rand_wave, 16); | ||
476 | } | ||
477 | } | ||
478 | } | ||
479 | |||
480 | // Go back to trigger selection. | ||
481 | if (key_tap(KEY_A)) { | ||
482 | current_selection = SEQ_SELECT_TRIGGER; | ||
483 | } | ||
484 | |||
485 | // Enable disable trigger. | ||
486 | if (key_tap(KEY_B)) { | ||
487 | trig->trigger ^= 1; | ||
488 | } | 407 | } |
489 | } else if (current_selection == SEQ_SELECT_CHANNEL) { | 408 | } else if (key_tap(KEY_RIGHT)) { |
490 | if (key_tap(KEY_RIGHT)) { | 409 | if (trig_selection_loc != 7) { |
491 | current_selection = SEQ_SELECT_TRIGGER; | 410 | draw_trig_cursor(trig_selection_loc, 0); |
492 | trig_selection_loc = 0; | 411 | trig_selection_loc = MIN(trig_selection_loc + 1, 15); |
493 | param_selection_loc = 0; | 412 | draw_trig_cursor(trig_selection_loc, 3); |
494 | } | 413 | } |
495 | if (key_tap(KEY_UP)) { | 414 | } else if (key_tap(KEY_UP) || key_tap(KEY_DOWN)) { |
496 | if (channel_selection_loc == 0) { | 415 | draw_trig_cursor(trig_selection_loc, 0); |
497 | channel_selection_loc = SEQ_N_CHANNELS - 1; | 416 | trig_selection_loc = (trig_selection_loc + 8) % 16; |
498 | } else { | 417 | draw_trig_cursor(trig_selection_loc, 3); |
499 | channel_selection_loc = MAX(channel_selection_loc - 1, 0); | 418 | } else if (key_tap(KEY_B)) { |
500 | } | 419 | trig->trigger ^= 1; |
420 | } else if (key_tap(KEY_L)) { | ||
421 | if (trig->trigger) { | ||
422 | trig->note = MAX(trig->note - 1, NOTE_C_2); | ||
501 | } | 423 | } |
502 | if (key_tap(KEY_DOWN)) { | 424 | } else if (key_tap(KEY_R)) { |
503 | if (channel_selection_loc == SEQ_N_CHANNELS - 1) { | 425 | if (trig->trigger) { |
504 | channel_selection_loc = 0; | 426 | trig->note = MIN( trig->note + 1, NOTE_C_8); |
505 | } else { | ||
506 | channel_selection_loc = MIN(channel_selection_loc + 1, SEQ_N_CHANNELS); | ||
507 | } | ||
508 | } | 427 | } |
428 | } else if (key_tap(KEY_A)) { | ||
429 | // Switch to parameter selection. | ||
430 | // current_selection = SEQ_SELECT_PARAMETER; | ||
509 | } | 431 | } |
432 | } | ||
433 | |||
434 | void (*input_handler)(void); | ||
435 | |||
436 | void | ||
437 | handle_sequencer_input(void) { | ||
438 | poll_keys(); | ||
439 | input_handler(); | ||
440 | // SeqTrigger *trig = &sequences[channel_selection_loc][trig_selection_loc]; | ||
441 | // if (current_selection == SEQ_SELECT_TRIGGER) { | ||
442 | // if (key_tap(KEY_LEFT)) { | ||
443 | // if (trig_selection_loc == 0 || trig_selection_loc == 8) { | ||
444 | // current_selection = SEQ_SELECT_CHANNEL; | ||
445 | // } else { | ||
446 | // trig_selection_loc = MAX(trig_selection_loc - 1, 0); | ||
447 | // } | ||
448 | // } else if (key_tap(KEY_RIGHT)) { | ||
449 | // if (trig_selection_loc != 7) { | ||
450 | // trig_selection_loc = MIN(trig_selection_loc + 1, 15); | ||
451 | // } | ||
452 | // } else if (key_tap(KEY_UP) || key_tap(KEY_DOWN)) { | ||
453 | // trig_selection_loc = (trig_selection_loc + 8) % 16; | ||
454 | // } else if (key_tap(KEY_B)) { | ||
455 | // trig->trigger ^= 1; | ||
456 | // } else if (key_tap(KEY_L)) { | ||
457 | // if (trig->trigger) { | ||
458 | // trig->note = MAX(trig->note - 1, NOTE_C_2); | ||
459 | // } | ||
460 | // } else if (key_tap(KEY_R)) { | ||
461 | // if (trig->trigger) { | ||
462 | // trig->note = MIN( trig->note + 1, NOTE_C_8); | ||
463 | // } | ||
464 | // } else if (key_tap(KEY_A)) { | ||
465 | // // Switch to parameter selection. | ||
466 | // current_selection = SEQ_SELECT_PARAMETER; | ||
467 | // } | ||
468 | // } else if (current_selection == SEQ_SELECT_PARAMETER) { | ||
469 | // if (channel_selection_loc < 2) { | ||
470 | // // Move through the selected synth parameters. | ||
471 | // if (key_tap(KEY_LEFT)) { | ||
472 | // int max_param = 6; | ||
473 | // if (channel_selection_loc == 1) { | ||
474 | // max_param = 3; | ||
475 | // } | ||
476 | // if (param_selection_loc == 0) { | ||
477 | // param_selection_loc = max_param; | ||
478 | // } else { | ||
479 | // param_selection_loc = MAX(param_selection_loc - 1, 0); | ||
480 | // } | ||
481 | // } | ||
482 | // if (key_tap(KEY_RIGHT)) { | ||
483 | // int max_param = 6; | ||
484 | // if (channel_selection_loc == 1) { | ||
485 | // max_param = 3; | ||
486 | // } | ||
487 | // if (param_selection_loc == max_param) { | ||
488 | // param_selection_loc = 0; | ||
489 | // } else { | ||
490 | // param_selection_loc = MIN(param_selection_loc + 1, max_param); | ||
491 | // } | ||
492 | // } | ||
493 | |||
494 | // // Adjust the parameters up or down. | ||
495 | // if (key_tap(KEY_L) || key_tap(KEY_R)) { | ||
496 | // int inc; | ||
497 | // if (key_tap(KEY_L)) { | ||
498 | // inc = -1; | ||
499 | // } else { | ||
500 | // inc = 1; | ||
501 | // } | ||
502 | // switch (param_selection_loc) { | ||
503 | // case 0: { | ||
504 | // trig->env_volume = CLAMP(trig->env_volume + inc, 0, 15); | ||
505 | // } break; | ||
506 | // case 1: { | ||
507 | // trig->env_time = CLAMP(trig->env_time + inc, 0, 7); | ||
508 | // } break; | ||
509 | // case 2: { | ||
510 | // trig->env_direction ^= 1; | ||
511 | // } break; | ||
512 | // case 3: { | ||
513 | // trig->duty_cycle = CLAMP(trig->duty_cycle + inc, 0, 3); | ||
514 | // } break; | ||
515 | // case 4: { | ||
516 | // trig->sweep_number = CLAMP(trig->sweep_number + inc, 0, 7); | ||
517 | // } break; | ||
518 | // case 5: { | ||
519 | // trig->sweep_time = CLAMP(trig->sweep_time + inc, 0, 7); | ||
520 | // } break; | ||
521 | // case 6: { | ||
522 | // if (trig->sweep_direction == 0) { | ||
523 | // trig->sweep_direction = 1; | ||
524 | // } else { | ||
525 | // trig->sweep_direction = 0; | ||
526 | // } | ||
527 | // } break; | ||
528 | // } | ||
529 | // } | ||
530 | // } else if (channel_selection_loc == 2) { | ||
531 | // if (key_tap(KEY_LEFT) || key_tap(KEY_RIGHT)) { | ||
532 | // int inc = 0; | ||
533 | // int loc = param_selection_loc; | ||
534 | // if (key_tap(KEY_RIGHT)) { | ||
535 | // if (loc == 15 || loc == 31) { | ||
536 | // inc = 17; | ||
537 | // } else if (loc != 47 && loc != 63){ | ||
538 | // inc = 1; | ||
539 | // } | ||
540 | // } else { | ||
541 | // if (loc == 32 || loc == 48) { | ||
542 | // inc = -17; | ||
543 | // } else if (loc != 16 && loc != 64){ | ||
544 | // inc = -1; | ||
545 | // } | ||
546 | // } | ||
547 | // param_selection_loc = CLAMP(loc + inc, 0, 71); | ||
548 | // } | ||
549 | // if (key_tap(KEY_UP) || key_tap(KEY_DOWN)) { | ||
550 | // int inc = 0; | ||
551 | // int loc = param_selection_loc; | ||
552 | // if (key_tap(KEY_UP)) { | ||
553 | // if ((loc >= 16 && loc < 32) || (loc >= 48 && loc < 64)) { | ||
554 | // inc = -16; | ||
555 | // } else if (loc == 64) { | ||
556 | // inc = -48; | ||
557 | // } else if (loc == 65) { | ||
558 | // inc = -45; | ||
559 | // } else if (loc == 66) { | ||
560 | // inc = -42; | ||
561 | // } else if (loc == 67) { | ||
562 | // inc = -39; | ||
563 | // } else if (loc == 68) { | ||
564 | // inc = -20; | ||
565 | // } else if (loc == 69) { | ||
566 | // inc = -17; | ||
567 | // } else if (loc == 70) { | ||
568 | // inc = -14; | ||
569 | // } else if (loc == 71) { | ||
570 | // inc = -11; | ||
571 | // } | ||
572 | // } else { | ||
573 | // if (loc < 16 || (loc >= 32 && loc < 48)) { | ||
574 | // inc = 16; | ||
575 | // } else if (loc >= 16 && loc <= 19){ | ||
576 | // inc = 48 - (loc - 16); | ||
577 | // } else if (loc >= 20 && loc <= 23){ | ||
578 | // inc = 45 - (loc - 20); | ||
579 | // } else if (loc >= 24 && loc <= 27){ | ||
580 | // inc = 42 - (loc - 24); | ||
581 | // } else if (loc >= 28 && loc <= 31){ | ||
582 | // inc = 39 - (loc - 28); | ||
583 | // } else if (loc >= 48 && loc <= 51){ | ||
584 | // inc = 20 - (loc - 48); | ||
585 | // } else if (loc >= 52 && loc <= 55){ | ||
586 | // inc = 17 - (loc - 52); | ||
587 | // } else if (loc >= 56 && loc <= 59){ | ||
588 | // inc = 14 - (loc - 56); | ||
589 | // } else if (loc >= 60 && loc <= 63){ | ||
590 | // inc = 11 - (loc - 60); | ||
591 | // } | ||
592 | // } | ||
593 | // param_selection_loc = CLAMP(loc + inc, 0, 71); | ||
594 | // } | ||
595 | // if (key_tap(KEY_R) || key_tap(KEY_L)) { | ||
596 | // int odd = param_selection_loc & 0x1; | ||
597 | // int inc; | ||
598 | // if (key_tap(KEY_R)) { | ||
599 | // inc = 1; | ||
600 | // } else { | ||
601 | // inc = -1; | ||
602 | // } | ||
603 | // // Wave: AA BB CC DD ... | ||
604 | // // ^^ | ||
605 | // // |`- odd | ||
606 | // // `-- even | ||
607 | // if (param_selection_loc < 32) { | ||
608 | // u8 byte_number = param_selection_loc >> 1; | ||
609 | // u8 byte = sequences[2][trig_selection_loc].wave_a[byte_number]; | ||
610 | // if (odd) { | ||
611 | // byte = (~0xF & byte) | ((byte + inc) & 0xF); | ||
612 | // } else { | ||
613 | // byte = (0xF & byte) | (((byte >> 4) + inc) & 0xF) << 4; | ||
614 | // } | ||
615 | // sequences[2][trig_selection_loc].wave_a[byte_number] = byte; | ||
616 | // } else if (param_selection_loc < 64){ | ||
617 | // u8 byte_number = (param_selection_loc - 32) >> 1; | ||
618 | // u8 byte = sequences[2][trig_selection_loc].wave_b[byte_number]; | ||
619 | // if (odd) { | ||
620 | // byte = (~0xF & byte) | (byte + inc); | ||
621 | // } else { | ||
622 | // byte = (0xF & byte) | ((byte >> 4) + inc) << 4; | ||
623 | // } | ||
624 | // sequences[2][trig_selection_loc].wave_b[byte_number] = byte; | ||
625 | // } else if (param_selection_loc == 64){ | ||
626 | // dma_copy(&trig->wave_a, &sine_wave, 16); | ||
627 | // } else if (param_selection_loc == 65){ | ||
628 | // dma_copy(&trig->wave_a, &saw_wave, 16); | ||
629 | // } else if (param_selection_loc == 66){ | ||
630 | // dma_copy(&trig->wave_a, &square_wave, 16); | ||
631 | // } else if (param_selection_loc == 67){ | ||
632 | // u32 rand_wave[4] = { | ||
633 | // rng32(), rng32(), rng32(), rng32(), | ||
634 | // }; | ||
635 | // dma_copy(&trig->wave_a, &rand_wave, 16); | ||
636 | // } else if (param_selection_loc == 68){ | ||
637 | // dma_copy(&trig->wave_b, &sine_wave, 16); | ||
638 | // } else if (param_selection_loc == 69){ | ||
639 | // dma_copy(&trig->wave_b, &saw_wave, 16); | ||
640 | // } else if (param_selection_loc == 70){ | ||
641 | // dma_copy(&trig->wave_b, &square_wave, 16); | ||
642 | // } else if (param_selection_loc == 71){ | ||
643 | // u32 rand_wave[4] = { | ||
644 | // rng32(), rng32(), rng32(), rng32(), | ||
645 | // }; | ||
646 | // dma_copy(&trig->wave_b, &rand_wave, 16); | ||
647 | // } | ||
648 | // } | ||
649 | // } | ||
650 | |||
651 | // // Go back to trigger selection. | ||
652 | // if (key_tap(KEY_A)) { | ||
653 | // current_selection = SEQ_SELECT_TRIGGER; | ||
654 | // } | ||
655 | |||
656 | // // Enable disable trigger. | ||
657 | // if (key_tap(KEY_B)) { | ||
658 | // trig->trigger ^= 1; | ||
659 | // } | ||
660 | // } else if (current_selection == SEQ_SELECT_CHANNEL) { | ||
661 | // if (key_tap(KEY_RIGHT)) { | ||
662 | // current_selection = SEQ_SELECT_TRIGGER; | ||
663 | // trig_selection_loc = 0; | ||
664 | // param_selection_loc = 0; | ||
665 | // } | ||
666 | // if (key_tap(KEY_UP)) { | ||
667 | // if (channel_selection_loc == 0) { | ||
668 | // channel_selection_loc = SEQ_N_CHANNELS - 1; | ||
669 | // } else { | ||
670 | // channel_selection_loc = MAX(channel_selection_loc - 1, 0); | ||
671 | // } | ||
672 | // } | ||
673 | // if (key_tap(KEY_DOWN)) { | ||
674 | // if (channel_selection_loc == SEQ_N_CHANNELS - 1) { | ||
675 | // channel_selection_loc = 0; | ||
676 | // } else { | ||
677 | // channel_selection_loc = MIN(channel_selection_loc + 1, SEQ_N_CHANNELS); | ||
678 | // } | ||
679 | // } | ||
680 | // } | ||
510 | 681 | ||
511 | if (key_tap(KEY_START)) { | 682 | if (key_tap(KEY_START)) { |
512 | step_counter = 0; | 683 | step_counter = 0; |
@@ -526,41 +697,38 @@ handle_sequencer_input(void) { | |||
526 | SOUND_WAVE_CTRL = 0; | 697 | SOUND_WAVE_CTRL = 0; |
527 | } | 698 | } |
528 | 699 | ||
529 | if (key_tap(KEY_LEFT) | 700 | // if (key_tap(KEY_LEFT) |
530 | || key_tap(KEY_RIGHT) | 701 | // || key_tap(KEY_RIGHT) |
531 | || key_tap(KEY_UP) | 702 | // || key_tap(KEY_UP) |
532 | || key_tap(KEY_DOWN) | 703 | // || key_tap(KEY_DOWN) |
533 | || key_tap(KEY_L) | 704 | // || key_tap(KEY_L) |
534 | || key_tap(KEY_R) | 705 | // || key_tap(KEY_R) |
535 | ) { | 706 | // ) { |
536 | } | 707 | // } |
537 | } | 708 | } |
538 | 709 | ||
539 | void | 710 | void |
540 | set_time(int bpm) { | 711 | load_note_names(void) { |
541 | // The number of ticks of a 1024 cycle clock in a step based on the BPM can | 712 | unpack_tiles(note_names, ASSETS_DATA, 2 * 73); |
542 | // be calculated as: | ||
543 | // X bpm -> 60000 / 4 / bpm = Y ms = Ye-3 s | ||
544 | // Y ms -> Ye-3 / 59.99e-9 / 1024 = Z ticks | ||
545 | // We have to operate on integer values, so the numbers have been | ||
546 | // precalculated to `n_ticks = 244181 / bmp` | ||
547 | int n_ticks = -244181 / bpm; | ||
548 | irs_set(IRQ_TIMER_0, irq_timer_0); | ||
549 | TIMER_DATA_0 = n_ticks; | ||
550 | TIMER_CTRL_0 = TIMER_CTRL_IRQ | TIMER_CTRL_ENABLE | TIMER_CTRL_FREQ_3; | ||
551 | } | 713 | } |
552 | 714 | ||
553 | void | 715 | void |
554 | sequencer_init(void) { | 716 | sequencer_init(void) { |
717 | // TODO: Unpack non-sprite tiles directly on the VRAM. | ||
718 | load_note_names(); | ||
719 | |||
555 | // Initialize background objects and sprites. | 720 | // Initialize background objects and sprites. |
556 | draw_triggers(); | 721 | draw_triggers(); |
557 | draw_channels(); | 722 | draw_channels(); |
558 | 723 | ||
724 | // Initialize input handler. | ||
725 | input_handler = trigger_cursor; | ||
726 | draw_trig_cursor(trig_selection_loc, 3); | ||
727 | |||
559 | // Initialize sound system. | 728 | // Initialize sound system. |
560 | SOUND_STATUS = SOUND_ENABLE; | 729 | SOUND_STATUS = SOUND_ENABLE; |
561 | SOUND_DMG_MASTER = sound_volume(SOUND_SQUARE1 | 730 | SOUND_DMG_MASTER = sound_volume(SOUND_SQUARE1 |
562 | | SOUND_SQUARE2 | 731 | | SOUND_SQUARE2 |
563 | | SOUND_WAVE, 3); | 732 | | SOUND_WAVE, 3); |
564 | SOUND_DSOUND_MASTER = SOUND_DMG25; | 733 | SOUND_DSOUND_MASTER = SOUND_DMG25; |
565 | set_time(bpm); | ||
566 | } | 734 | } |