diff options
-rw-r--r-- | src/common.h | 9 | ||||
-rw-r--r-- | src/main.c | 5 | ||||
-rw-r--r-- | src/sequencer.c | 440 |
3 files changed, 376 insertions, 78 deletions
diff --git a/src/common.h b/src/common.h index b688711..d78f11a 100644 --- a/src/common.h +++ b/src/common.h | |||
@@ -105,7 +105,7 @@ rgb15(u32 red, u32 green, u32 blue ) { | |||
105 | #define COLOR_RED rgb15(31, 0, 12) | 105 | #define COLOR_RED rgb15(31, 0, 12) |
106 | #define COLOR_BLUE rgb15(2, 15, 30) | 106 | #define COLOR_BLUE rgb15(2, 15, 30) |
107 | #define COLOR_CYAN rgb15(0, 30, 30) | 107 | #define COLOR_CYAN rgb15(0, 30, 30) |
108 | #define COLOR_GREY rgb15(4, 4, 4) | 108 | #define COLOR_GREY rgb15(12, 12, 12) |
109 | #define COLOR_BLACK rgb15(0, 0, 0) | 109 | #define COLOR_BLACK rgb15(0, 0, 0) |
110 | #define COLOR_WHITE rgb15(28, 28, 28) | 110 | #define COLOR_WHITE rgb15(28, 28, 28) |
111 | 111 | ||
@@ -594,9 +594,14 @@ sound_volume(SoundChannel channels, u8 volume) { | |||
594 | #define SOUND_SQUARE_LEN(N) (N) | 594 | #define SOUND_SQUARE_LEN(N) (N) |
595 | #define SOUND_SQUARE_DUTY(N) ((N) << 0x6) | 595 | #define SOUND_SQUARE_DUTY(N) ((N) << 0x6) |
596 | #define SOUND_SQUARE_ENV_TIME(N) ((N) << 0x8) | 596 | #define SOUND_SQUARE_ENV_TIME(N) ((N) << 0x8) |
597 | #define SOUND_SQUARE_ENV_INC(N) ((N) << 0xB) | 597 | #define SOUND_SQUARE_ENV_DIR(N) ((N) << 0xB) |
598 | #define SOUND_SQUARE_ENV_VOL(N) ((N) << 0xC) | 598 | #define SOUND_SQUARE_ENV_VOL(N) ((N) << 0xC) |
599 | 599 | ||
600 | // DMG square 1 sweep control bits. | ||
601 | #define SOUND_SWEEP_NUMBER(N) (N) | ||
602 | #define SOUND_SWEEP_DIR(N) ((N) << 0x3) | ||
603 | #define SOUND_SWEEP_TIME(N) ((N) << 0x4) | ||
604 | |||
600 | // DMG square frequency bits. | 605 | // DMG square frequency bits. |
601 | #define SOUND_SQUARE_TIMED (1 << 0xE) | 606 | #define SOUND_SQUARE_TIMED (1 << 0xE) |
602 | #define SOUND_SQUARE_RESET (1 << 0xF) | 607 | #define SOUND_SQUARE_RESET (1 << 0xF) |
@@ -20,11 +20,6 @@ int main(void) { | |||
20 | // sequential. | 20 | // sequential. |
21 | DISP_CTRL = DISP_ENABLE_SPRITES | DISP_MODE_0 | DISP_BG_0; | 21 | DISP_CTRL = DISP_ENABLE_SPRITES | DISP_MODE_0 | DISP_BG_0; |
22 | 22 | ||
23 | // Initialize sprite button overlay. | ||
24 | init_sprite_pal(0, COLOR_WHITE); | ||
25 | init_sprite_pal(16, COLOR_CYAN); | ||
26 | init_sprite_pal(32, COLOR_RED); | ||
27 | init_sprites(0); | ||
28 | init_sequencer_sprites(); | 23 | init_sequencer_sprites(); |
29 | 24 | ||
30 | // Initialize text engine. | 25 | // Initialize text engine. |
diff --git a/src/sequencer.c b/src/sequencer.c index 5db1b5d..b55ceca 100644 --- a/src/sequencer.c +++ b/src/sequencer.c | |||
@@ -101,7 +101,7 @@ u32 sprite_env_label_volume[] = { | |||
101 | 0xaaeaaaaa, 0xae000000, 0x0e020602, 0x0e000000, | 101 | 0xaaeaaaaa, 0xae000000, 0x0e020602, 0x0e000000, |
102 | }; | 102 | }; |
103 | 103 | ||
104 | u32 sprite_env_label_time[] = { | 104 | u32 sprite_env_sweep_label_time[] = { |
105 | 0x00000000, 0x00000000, 0xee444444, 0xe4000000, | 105 | 0x00000000, 0x00000000, 0xee444444, 0xe4000000, |
106 | 0xea2e6a2a, 0xea000000, 0x00000000, 0x00000000, | 106 | 0xea2e6a2a, 0xea000000, 0x00000000, 0x00000000, |
107 | }; | 107 | }; |
@@ -116,6 +116,16 @@ u32 sprite_env_label_env[] = { | |||
116 | 0x62a2a2a2, 0xee000000, 0xee2a6e22, 0xe2000000, | 116 | 0x62a2a2a2, 0xee000000, 0xee2a6e22, 0xe2000000, |
117 | }; | 117 | }; |
118 | 118 | ||
119 | u32 sprite_sweep_number_label[] = { | ||
120 | 0x60a0a0a0, 0xa0000000, 0xaaeaaaaa, 0xae000000, | ||
121 | 0xee2a662a, 0xee000000, 0x0e0a060a, 0x0a000000, | ||
122 | }; | ||
123 | |||
124 | u32 sprite_sweep_label[] = { | ||
125 | 0x8040c000, 0xc0000000, 0xa5a4a5b5, 0xa8000000, | ||
126 | 0xbb889988, 0xbb000000, 0x03020300, 0x00000000, | ||
127 | }; | ||
128 | |||
119 | u32 sprite_duty_cycle_label[] = { | 129 | u32 sprite_duty_cycle_label[] = { |
120 | 0x00000000, 0x00000080, 0xa6aaaaaa, 0xe60000ab, | 130 | 0x00000000, 0x00000080, 0xa6aaaaaa, 0xe60000ab, |
121 | 0xaea4e444, 0x4400008b, 0x00000000, 0x00000003, | 131 | 0xaea4e444, 0x4400008b, 0x00000000, 0x00000003, |
@@ -195,6 +205,25 @@ u32 sprite_env_sweep_direction[] = { | |||
195 | 0xb2b2b2b2, 0xb2ba9400, 0x0d0f0e0c, 0x0c0c0c00, | 205 | 0xb2b2b2b2, 0xb2ba9400, 0x0d0f0e0c, 0x0c0c0c00, |
196 | }; | 206 | }; |
197 | 207 | ||
208 | u32 sprite_sweep_time_number[] = { | ||
209 | 0x7c646464, 0x64647c00, 0x18181818, 0x18181800, | ||
210 | 0x7c60607c, 0x0c0c7c00, 0x7c606078, 0x60607c00, | ||
211 | 0x60706864, 0x7c606000, 0x7c0c0c7c, 0x60607c00, | ||
212 | 0x7c0c0c7c, 0x4c4c7c00, 0x7c606030, 0x180c0c00, | ||
213 | }; | ||
214 | |||
215 | u32 sprite_synth_param_selector[] = { | ||
216 | 0x07010100, 0x00000000, 0x00000000, 0x00000000, | ||
217 | 0x00000000, 0x00000000, 0xe0808000, 0x00000000, | ||
218 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||
219 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||
220 | 0x00000101, 0x07000000, 0x00000000, 0x00000000, | ||
221 | 0x00000000, 0x00000000, 0x00008080, 0xe0000000, | ||
222 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||
223 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||
224 | }; | ||
225 | |||
226 | |||
198 | typedef struct SeqTrigger { | 227 | typedef struct SeqTrigger { |
199 | bool trigger; | 228 | bool trigger; |
200 | Note note; | 229 | Note note; |
@@ -202,29 +231,32 @@ typedef struct SeqTrigger { | |||
202 | u8 env_time; | 231 | u8 env_time; |
203 | u8 env_direction; | 232 | u8 env_direction; |
204 | u8 duty_cycle; | 233 | u8 duty_cycle; |
234 | u8 sweep_number; | ||
235 | u8 sweep_time; | ||
236 | u8 sweep_direction; | ||
205 | // TODO: ... | 237 | // TODO: ... |
206 | } SeqTrigger; | 238 | } SeqTrigger; |
207 | 239 | ||
208 | static SeqTrigger sequence_synth[] = { | 240 | static SeqTrigger sequence_synth[] = { |
209 | {true , NOTE_D_4 , 0, 0, 0, 0}, | 241 | {true , NOTE_D_4 , 0, 0, 0, 0, 0, 0, 0}, |
210 | {true , NOTE_F_4 , 1, 1, 0, 0}, | 242 | {true , NOTE_F_4 , 1, 1, 0, 0, 1, 1, 0}, |
211 | {true , NOTE_A_4 , 2, 2, 0, 1}, | 243 | {true , NOTE_A_4 , 2, 2, 0, 1, 2, 2, 1}, |
212 | {true , NOTE_C_5 , 3, 3, 0, 1}, | 244 | {true , NOTE_C_5 , 3, 3, 0, 1, 3, 3, 1}, |
213 | 245 | ||
214 | {true , NOTE_D_4 , 4, 4, 1, 2}, | 246 | {true , NOTE_D_4 , 4, 4, 1, 2, 4, 4, 0}, |
215 | {false , NOTE_C_SHARP_4 , 5, 5, 1, 2}, | 247 | {false , NOTE_C_SHARP_4 , 5, 5, 1, 2, 5, 5, 0}, |
216 | {false , NOTE_D_4 , 6, 6, 1, 3}, | 248 | {false , NOTE_D_4 , 6, 6, 1, 3, 6, 6, 1}, |
217 | {false , NOTE_D_4 , 7, 7, 1, 3}, | 249 | {false , NOTE_D_4 , 7, 7, 1, 3, 7, 7, 1}, |
218 | 250 | ||
219 | {true , NOTE_D_4 , 8, 0, 0, 0}, | 251 | {true , NOTE_D_4 , 8, 0, 0, 0, 7, 0, 0}, |
220 | {true , NOTE_F_4 , 9, 1, 0, 0}, | 252 | {true , NOTE_F_4 , 9, 1, 0, 0, 6, 1, 0}, |
221 | {true , NOTE_A_4 , 10, 2, 0, 1}, | 253 | {true , NOTE_A_4 , 10, 2, 0, 1, 5, 2, 1}, |
222 | {true , NOTE_C_5 , 11, 3, 0, 1}, | 254 | {true , NOTE_C_5 , 11, 3, 0, 1, 4, 3, 1}, |
223 | 255 | ||
224 | {true , NOTE_D_4 , 12, 4, 1, 2}, | 256 | {true , NOTE_D_4 , 12, 4, 1, 2, 3, 4, 0}, |
225 | {false , NOTE_D_4 , 13, 5, 1, 2}, | 257 | {false , NOTE_D_4 , 13, 5, 1, 2, 2, 5, 0}, |
226 | {true , NOTE_A_4 , 14, 6, 1, 3}, | 258 | {true , NOTE_A_4 , 14, 6, 1, 3, 1, 6, 1}, |
227 | {false , NOTE_A_5 , 15, 7, 1, 3}, | 259 | {false , NOTE_A_5 , 15, 7, 1, 3, 0, 7, 1}, |
228 | }; | 260 | }; |
229 | 261 | ||
230 | static int bpm = 120; | 262 | static int bpm = 120; |
@@ -236,11 +268,15 @@ irq_timer_0(void) { | |||
236 | SeqTrigger *trig = &sequence_synth[step_counter]; | 268 | SeqTrigger *trig = &sequence_synth[step_counter]; |
237 | active_note = trig->note; | 269 | active_note = trig->note; |
238 | if (trig->trigger) { | 270 | if (trig->trigger) { |
271 | SOUND_SQUARE1_SWEEP = SOUND_SWEEP_NUMBER(trig->sweep_number) | ||
272 | | SOUND_SWEEP_DIR(trig->sweep_direction) | ||
273 | | SOUND_SWEEP_TIME(trig->sweep_time); | ||
239 | SOUND_SQUARE1_CTRL = SOUND_SQUARE_ENV_VOL(trig->env_volume) | 274 | SOUND_SQUARE1_CTRL = SOUND_SQUARE_ENV_VOL(trig->env_volume) |
240 | | SOUND_SQUARE_ENV_TIME(trig->env_time) | 275 | | SOUND_SQUARE_ENV_TIME(trig->env_time) |
241 | | SOUND_SQUARE_ENV_INC(trig->env_direction) | 276 | | SOUND_SQUARE_ENV_DIR(trig->env_direction) |
242 | | SOUND_SQUARE_DUTY(trig->duty_cycle); | 277 | | SOUND_SQUARE_DUTY(trig->duty_cycle); |
243 | SOUND_SQUARE1_FREQ = SOUND_SQUARE_RESET | sound_rates[active_note]; | 278 | SOUND_SQUARE1_FREQ = SOUND_SQUARE_RESET |
279 | | sound_rates[active_note]; | ||
244 | } | 280 | } |
245 | step_counter = (step_counter + 1) % 16; | 281 | step_counter = (step_counter + 1) % 16; |
246 | } | 282 | } |
@@ -250,7 +286,7 @@ set_time(int bpm) { | |||
250 | // The number of ticks of a 1024 cycle clock in a step based on the BPM can | 286 | // The number of ticks of a 1024 cycle clock in a step based on the BPM can |
251 | // be calculated as: | 287 | // be calculated as: |
252 | // X bpm -> 60000 / 4 / bpm = Y ms = Ye-3 s | 288 | // X bpm -> 60000 / 4 / bpm = Y ms = Ye-3 s |
253 | // Y ms -> Ye-3 / 59.99e-9 /1024 = Z ticks | 289 | // Y ms -> Ye-3 / 59.99e-9 / 1024 = Z ticks |
254 | // We have to operate on integer values, so the numbers have been | 290 | // We have to operate on integer values, so the numbers have been |
255 | // precalculated to `n_ticks = 244181 / bmp` | 291 | // precalculated to `n_ticks = 244181 / bmp` |
256 | int n_ticks = -244181 / bpm; | 292 | int n_ticks = -244181 / bpm; |
@@ -291,6 +327,14 @@ set_time(int bpm) { | |||
291 | // - 040-040 envelope: envelope label. | 327 | // - 040-040 envelope: envelope label. |
292 | // - 041-041 duty-cycle label. | 328 | // - 041-041 duty-cycle label. |
293 | // - 042-042 duty-cycle indicator. | 329 | // - 042-042 duty-cycle indicator. |
330 | // - 043-043 sweep: number label. | ||
331 | // - 044-044 sweep: number indicator. | ||
332 | // - 045-045 sweep: time label. | ||
333 | // - 046-046 sweep: time indicator. | ||
334 | // - 047-047 sweep: direction label. | ||
335 | // - 048-048 sweep: direction indicator. | ||
336 | // - 049-049 sweep: sweep label. | ||
337 | // - 050-050 synth parameter selector. | ||
294 | // | 338 | // |
295 | 339 | ||
296 | 340 | ||
@@ -300,9 +344,11 @@ set_time(int bpm) { | |||
300 | #define SEQ_TRIG_DIST 20 | 344 | #define SEQ_TRIG_DIST 20 |
301 | #define SEQ_ENV_POS_X 10 | 345 | #define SEQ_ENV_POS_X 10 |
302 | #define SEQ_ENV_POS_Y 10 | 346 | #define SEQ_ENV_POS_Y 10 |
303 | #define SEQ_ENV_DIST 34 | 347 | #define SEQ_ENV_DIST 32 |
304 | #define SEQ_DUTYCYCLE_POS_X SEQ_ENV_POS_X + SEQ_ENV_DIST * 3 | 348 | #define SEQ_DUTYCYCLE_POS_X SEQ_ENV_POS_X + SEQ_ENV_DIST * 3 |
305 | #define SEQ_DUTYCYCLE_POS_Y 10 - 8 | 349 | #define SEQ_DUTYCYCLE_POS_Y 10 - 8 |
350 | #define SEQ_SWEEP_POS_X SEQ_DUTYCYCLE_POS_X + SEQ_ENV_DIST | ||
351 | #define SEQ_SWEEP_POS_Y SEQ_ENV_POS_Y | ||
306 | 352 | ||
307 | size_t obj_counter = 0; | 353 | size_t obj_counter = 0; |
308 | 354 | ||
@@ -316,12 +362,27 @@ typedef struct SeqSprite { | |||
316 | u16 obj_attr_2; | 362 | u16 obj_attr_2; |
317 | } SeqSprite; | 363 | } SeqSprite; |
318 | 364 | ||
319 | int trig_selection_loc = 1; | ||
320 | 365 | ||
321 | SeqSprite seq_sprites[43] = {0}; | 366 | typedef enum { |
367 | SEQ_SELECT_TRIGGER, | ||
368 | SEQ_SELECT_PARAMETER, | ||
369 | } SeqSelect; | ||
370 | |||
371 | int trig_selection_loc = 0; | ||
372 | int param_selection_loc = 0; | ||
373 | SeqSelect current_selection = SEQ_SELECT_TRIGGER; | ||
374 | |||
375 | SeqSprite seq_sprites[51] = {0}; | ||
322 | 376 | ||
323 | void | 377 | void |
324 | init_sequencer_sprites(void) { | 378 | init_sequencer_sprites(void) { |
379 | // Load palette. | ||
380 | init_sprite_pal(0, COLOR_WHITE); | ||
381 | init_sprite_pal(16, COLOR_CYAN); | ||
382 | init_sprite_pal(32, COLOR_RED); | ||
383 | init_sprite_pal(48, COLOR_GREY); | ||
384 | init_sprites(0); | ||
385 | |||
325 | // Sprite note names. | 386 | // Sprite note names. |
326 | size_t sprite_id = load_packed_sprite_data(&sprite_note_names, 2, 73); | 387 | size_t sprite_id = load_packed_sprite_data(&sprite_note_names, 2, 73); |
327 | for (size_t i = 0; i < 16; ++i) { | 388 | for (size_t i = 0; i < 16; ++i) { |
@@ -396,7 +457,7 @@ init_sequencer_sprites(void) { | |||
396 | seq_sprites[34].base_tile = base_tile; | 457 | seq_sprites[34].base_tile = base_tile; |
397 | seq_sprites[34].obj_attr_0 = OBJ_SHAPE_WIDE | OBJ_Y_COORD(y); | 458 | seq_sprites[34].obj_attr_0 = OBJ_SHAPE_WIDE | OBJ_Y_COORD(y); |
398 | seq_sprites[34].obj_attr_1 = OBJ_SIZE_MID | OBJ_X_COORD(x); | 459 | seq_sprites[34].obj_attr_1 = OBJ_SIZE_MID | OBJ_X_COORD(x); |
399 | seq_sprites[34].obj_attr_2 = base_tile | OBJ_PAL_BANK(2); | 460 | seq_sprites[34].obj_attr_2 = base_tile; |
400 | } | 461 | } |
401 | 462 | ||
402 | sprite_id = load_packed_sprite_data(&sprite_env_volume, 4, 16); | 463 | sprite_id = load_packed_sprite_data(&sprite_env_volume, 4, 16); |
@@ -408,10 +469,10 @@ init_sequencer_sprites(void) { | |||
408 | seq_sprites[35].base_tile = base_tile; | 469 | seq_sprites[35].base_tile = base_tile; |
409 | seq_sprites[35].obj_attr_0 = OBJ_SHAPE_WIDE | OBJ_Y_COORD(y); | 470 | seq_sprites[35].obj_attr_0 = OBJ_SHAPE_WIDE | OBJ_Y_COORD(y); |
410 | seq_sprites[35].obj_attr_1 = OBJ_SIZE_MID | OBJ_X_COORD(x); | 471 | seq_sprites[35].obj_attr_1 = OBJ_SIZE_MID | OBJ_X_COORD(x); |
411 | seq_sprites[35].obj_attr_2 = base_tile | OBJ_PAL_BANK(2); | 472 | seq_sprites[35].obj_attr_2 = base_tile; |
412 | } | 473 | } |
413 | 474 | ||
414 | sprite_id = load_packed_sprite_data(&sprite_env_label_time, 4, 1); | 475 | sprite_id = load_packed_sprite_data(&sprite_env_sweep_label_time, 4, 1); |
415 | { | 476 | { |
416 | int x = SEQ_ENV_POS_X + SEQ_ENV_DIST; | 477 | int x = SEQ_ENV_POS_X + SEQ_ENV_DIST; |
417 | int y = SEQ_ENV_POS_Y; | 478 | int y = SEQ_ENV_POS_Y; |
@@ -420,7 +481,17 @@ init_sequencer_sprites(void) { | |||
420 | seq_sprites[36].base_tile = base_tile; | 481 | seq_sprites[36].base_tile = base_tile; |
421 | seq_sprites[36].obj_attr_0 = OBJ_SHAPE_WIDE | OBJ_Y_COORD(y); | 482 | seq_sprites[36].obj_attr_0 = OBJ_SHAPE_WIDE | OBJ_Y_COORD(y); |
422 | seq_sprites[36].obj_attr_1 = OBJ_SIZE_MID | OBJ_X_COORD(x); | 483 | seq_sprites[36].obj_attr_1 = OBJ_SIZE_MID | OBJ_X_COORD(x); |
423 | seq_sprites[36].obj_attr_2 = base_tile | OBJ_PAL_BANK(2); | 484 | seq_sprites[36].obj_attr_2 = base_tile; |
485 | } | ||
486 | { | ||
487 | int x = SEQ_SWEEP_POS_X + SEQ_ENV_DIST; | ||
488 | int y = SEQ_SWEEP_POS_Y; | ||
489 | int base_tile = sprites[sprite_id].tile_start; | ||
490 | seq_sprites[45].id = obj_counter++; | ||
491 | seq_sprites[45].base_tile = base_tile; | ||
492 | seq_sprites[45].obj_attr_0 = OBJ_SHAPE_WIDE | OBJ_Y_COORD(y); | ||
493 | seq_sprites[45].obj_attr_1 = OBJ_SIZE_MID | OBJ_X_COORD(x); | ||
494 | seq_sprites[45].obj_attr_2 = base_tile; | ||
424 | } | 495 | } |
425 | 496 | ||
426 | sprite_id = load_packed_sprite_data(&sprite_env_time, 4, 8); | 497 | sprite_id = load_packed_sprite_data(&sprite_env_time, 4, 8); |
@@ -432,7 +503,7 @@ init_sequencer_sprites(void) { | |||
432 | seq_sprites[37].base_tile = base_tile; | 503 | seq_sprites[37].base_tile = base_tile; |
433 | seq_sprites[37].obj_attr_0 = OBJ_SHAPE_WIDE | OBJ_Y_COORD(y); | 504 | seq_sprites[37].obj_attr_0 = OBJ_SHAPE_WIDE | OBJ_Y_COORD(y); |
434 | seq_sprites[37].obj_attr_1 = OBJ_SIZE_MID | OBJ_X_COORD(x); | 505 | seq_sprites[37].obj_attr_1 = OBJ_SIZE_MID | OBJ_X_COORD(x); |
435 | seq_sprites[37].obj_attr_2 = base_tile | OBJ_PAL_BANK(2); | 506 | seq_sprites[37].obj_attr_2 = base_tile; |
436 | } | 507 | } |
437 | 508 | ||
438 | sprite_id = load_packed_sprite_data(&sprite_env_label_direction, 4, 1); | 509 | sprite_id = load_packed_sprite_data(&sprite_env_label_direction, 4, 1); |
@@ -444,7 +515,17 @@ init_sequencer_sprites(void) { | |||
444 | seq_sprites[38].base_tile = base_tile; | 515 | seq_sprites[38].base_tile = base_tile; |
445 | seq_sprites[38].obj_attr_0 = OBJ_SHAPE_WIDE | OBJ_Y_COORD(y); | 516 | seq_sprites[38].obj_attr_0 = OBJ_SHAPE_WIDE | OBJ_Y_COORD(y); |
446 | seq_sprites[38].obj_attr_1 = OBJ_SIZE_MID | OBJ_X_COORD(x); | 517 | seq_sprites[38].obj_attr_1 = OBJ_SIZE_MID | OBJ_X_COORD(x); |
447 | seq_sprites[38].obj_attr_2 = base_tile | OBJ_PAL_BANK(2); | 518 | seq_sprites[38].obj_attr_2 = base_tile; |
519 | } | ||
520 | { | ||
521 | int x = SEQ_SWEEP_POS_X + SEQ_ENV_DIST * 2; | ||
522 | int y = SEQ_SWEEP_POS_Y; | ||
523 | int base_tile = sprites[sprite_id].tile_start; | ||
524 | seq_sprites[47].id = obj_counter++; | ||
525 | seq_sprites[47].base_tile = base_tile; | ||
526 | seq_sprites[47].obj_attr_0 = OBJ_SHAPE_WIDE | OBJ_Y_COORD(y); | ||
527 | seq_sprites[47].obj_attr_1 = OBJ_SIZE_MID | OBJ_X_COORD(x); | ||
528 | seq_sprites[47].obj_attr_2 = base_tile; | ||
448 | } | 529 | } |
449 | 530 | ||
450 | sprite_id = load_packed_sprite_data(&sprite_env_sweep_direction, 4, 2); | 531 | sprite_id = load_packed_sprite_data(&sprite_env_sweep_direction, 4, 2); |
@@ -456,19 +537,29 @@ init_sequencer_sprites(void) { | |||
456 | seq_sprites[39].base_tile = base_tile; | 537 | seq_sprites[39].base_tile = base_tile; |
457 | seq_sprites[39].obj_attr_0 = OBJ_SHAPE_WIDE | OBJ_Y_COORD(y); | 538 | seq_sprites[39].obj_attr_0 = OBJ_SHAPE_WIDE | OBJ_Y_COORD(y); |
458 | seq_sprites[39].obj_attr_1 = OBJ_SIZE_MID | OBJ_X_COORD(x); | 539 | seq_sprites[39].obj_attr_1 = OBJ_SIZE_MID | OBJ_X_COORD(x); |
459 | seq_sprites[39].obj_attr_2 = base_tile | OBJ_PAL_BANK(2); | 540 | seq_sprites[39].obj_attr_2 = base_tile; |
541 | } | ||
542 | { | ||
543 | int x = SEQ_SWEEP_POS_X + SEQ_ENV_DIST * 2; | ||
544 | int y = SEQ_SWEEP_POS_Y + 8; | ||
545 | int base_tile = sprites[sprite_id].tile_start; | ||
546 | seq_sprites[48].id = obj_counter++; | ||
547 | seq_sprites[48].base_tile = base_tile; | ||
548 | seq_sprites[48].obj_attr_0 = OBJ_SHAPE_WIDE | OBJ_Y_COORD(y); | ||
549 | seq_sprites[48].obj_attr_1 = OBJ_SIZE_MID | OBJ_X_COORD(x); | ||
550 | seq_sprites[48].obj_attr_2 = base_tile; | ||
460 | } | 551 | } |
461 | 552 | ||
462 | sprite_id = load_packed_sprite_data(&sprite_env_label_env, 4, 1); | 553 | sprite_id = load_packed_sprite_data(&sprite_env_label_env, 4, 1); |
463 | { | 554 | { |
464 | int x = SEQ_ENV_POS_X + SEQ_ENV_DIST; | 555 | int x = SEQ_ENV_POS_X + SEQ_ENV_DIST; |
465 | int y = SEQ_ENV_POS_Y - 8; | 556 | int y = SEQ_ENV_POS_Y - 10; |
466 | int base_tile = sprites[sprite_id].tile_start; | 557 | int base_tile = sprites[sprite_id].tile_start; |
467 | seq_sprites[40].id = obj_counter++; | 558 | seq_sprites[40].id = obj_counter++; |
468 | seq_sprites[40].base_tile = base_tile; | 559 | seq_sprites[40].base_tile = base_tile; |
469 | seq_sprites[40].obj_attr_0 = OBJ_SHAPE_WIDE | OBJ_Y_COORD(y); | 560 | seq_sprites[40].obj_attr_0 = OBJ_SHAPE_WIDE | OBJ_Y_COORD(y); |
470 | seq_sprites[40].obj_attr_1 = OBJ_SIZE_MID | OBJ_X_COORD(x); | 561 | seq_sprites[40].obj_attr_1 = OBJ_SIZE_MID | OBJ_X_COORD(x); |
471 | seq_sprites[40].obj_attr_2 = base_tile | OBJ_PAL_BANK(2); | 562 | seq_sprites[40].obj_attr_2 = base_tile; |
472 | } | 563 | } |
473 | 564 | ||
474 | sprite_id = load_packed_sprite_data(&sprite_duty_cycle_label, 8, 1); | 565 | sprite_id = load_packed_sprite_data(&sprite_duty_cycle_label, 8, 1); |
@@ -480,8 +571,9 @@ init_sequencer_sprites(void) { | |||
480 | seq_sprites[41].base_tile = base_tile; | 571 | seq_sprites[41].base_tile = base_tile; |
481 | seq_sprites[41].obj_attr_0 = OBJ_SHAPE_WIDE | OBJ_Y_COORD(y); | 572 | seq_sprites[41].obj_attr_0 = OBJ_SHAPE_WIDE | OBJ_Y_COORD(y); |
482 | seq_sprites[41].obj_attr_1 = OBJ_SIZE_BIG | OBJ_X_COORD(x); | 573 | seq_sprites[41].obj_attr_1 = OBJ_SIZE_BIG | OBJ_X_COORD(x); |
483 | seq_sprites[41].obj_attr_2 = base_tile | OBJ_PAL_BANK(2); | 574 | seq_sprites[41].obj_attr_2 = base_tile; |
484 | } | 575 | } |
576 | |||
485 | sprite_id = load_packed_sprite_data(&sprite_duty_cycle, 4, 4); | 577 | sprite_id = load_packed_sprite_data(&sprite_duty_cycle, 4, 4); |
486 | { | 578 | { |
487 | int x = SEQ_DUTYCYCLE_POS_X; | 579 | int x = SEQ_DUTYCYCLE_POS_X; |
@@ -491,7 +583,65 @@ init_sequencer_sprites(void) { | |||
491 | seq_sprites[42].base_tile = base_tile; | 583 | seq_sprites[42].base_tile = base_tile; |
492 | seq_sprites[42].obj_attr_0 = OBJ_SHAPE_WIDE | OBJ_Y_COORD(y); | 584 | seq_sprites[42].obj_attr_0 = OBJ_SHAPE_WIDE | OBJ_Y_COORD(y); |
493 | seq_sprites[42].obj_attr_1 = OBJ_SIZE_MID | OBJ_X_COORD(x); | 585 | seq_sprites[42].obj_attr_1 = OBJ_SIZE_MID | OBJ_X_COORD(x); |
494 | seq_sprites[42].obj_attr_2 = base_tile | OBJ_PAL_BANK(2); | 586 | seq_sprites[42].obj_attr_2 = base_tile; |
587 | } | ||
588 | |||
589 | sprite_id = load_packed_sprite_data(&sprite_sweep_number_label, 4, 1); | ||
590 | { | ||
591 | int x = SEQ_SWEEP_POS_X; | ||
592 | int y = SEQ_SWEEP_POS_Y; | ||
593 | int base_tile = sprites[sprite_id].tile_start; | ||
594 | seq_sprites[43].id = obj_counter++; | ||
595 | seq_sprites[43].base_tile = base_tile; | ||
596 | seq_sprites[43].obj_attr_0 = OBJ_SHAPE_WIDE | OBJ_Y_COORD(y); | ||
597 | seq_sprites[43].obj_attr_1 = OBJ_SIZE_MID | OBJ_X_COORD(x); | ||
598 | seq_sprites[43].obj_attr_2 = base_tile; | ||
599 | } | ||
600 | |||
601 | sprite_id = load_packed_sprite_data(&sprite_sweep_time_number, 1, 8); | ||
602 | { | ||
603 | int x = SEQ_SWEEP_POS_X + 12; | ||
604 | int y = SEQ_SWEEP_POS_Y + 8; | ||
605 | int base_tile = sprites[sprite_id].tile_start; | ||
606 | seq_sprites[44].id = obj_counter++; | ||
607 | seq_sprites[44].base_tile = base_tile; | ||
608 | seq_sprites[44].obj_attr_0 = OBJ_SHAPE_SQUARE | OBJ_Y_COORD(y); | ||
609 | seq_sprites[44].obj_attr_1 = OBJ_SIZE_SMALL | OBJ_X_COORD(x); | ||
610 | seq_sprites[44].obj_attr_2 = base_tile; | ||
611 | } | ||
612 | { | ||
613 | int x = SEQ_SWEEP_POS_X + 12 + SEQ_ENV_DIST; | ||
614 | int y = SEQ_SWEEP_POS_Y + 8; | ||
615 | int base_tile = sprites[sprite_id].tile_start; | ||
616 | seq_sprites[46].id = obj_counter++; | ||
617 | seq_sprites[46].base_tile = base_tile; | ||
618 | seq_sprites[46].obj_attr_0 = OBJ_SHAPE_SQUARE | OBJ_Y_COORD(y); | ||
619 | seq_sprites[46].obj_attr_1 = OBJ_SIZE_SMALL | OBJ_X_COORD(x); | ||
620 | seq_sprites[46].obj_attr_2 = base_tile; | ||
621 | } | ||
622 | |||
623 | sprite_id = load_packed_sprite_data(&sprite_sweep_label, 4, 1); | ||
624 | { | ||
625 | int x = SEQ_SWEEP_POS_X + SEQ_ENV_DIST; | ||
626 | int y = SEQ_SWEEP_POS_Y - 10; | ||
627 | int base_tile = sprites[sprite_id].tile_start; | ||
628 | seq_sprites[49].id = obj_counter++; | ||
629 | seq_sprites[49].base_tile = base_tile; | ||
630 | seq_sprites[49].obj_attr_0 = OBJ_SHAPE_WIDE | OBJ_Y_COORD(y); | ||
631 | seq_sprites[49].obj_attr_1 = OBJ_SIZE_MID | OBJ_X_COORD(x); | ||
632 | seq_sprites[49].obj_attr_2 = base_tile; | ||
633 | } | ||
634 | |||
635 | sprite_id = load_packed_sprite_data(&sprite_synth_param_selector, 16, 1); | ||
636 | { | ||
637 | int x = SEQ_ENV_POS_X + 1; | ||
638 | int y = SEQ_ENV_POS_Y - 3; | ||
639 | int base_tile = sprites[sprite_id].tile_start; | ||
640 | seq_sprites[50].id = obj_counter++; | ||
641 | seq_sprites[50].base_tile = base_tile; | ||
642 | seq_sprites[50].obj_attr_0 = OBJ_SHAPE_SQUARE | OBJ_Y_COORD(y); | ||
643 | seq_sprites[50].obj_attr_1 = OBJ_SIZE_BIG | OBJ_X_COORD(x); | ||
644 | seq_sprites[50].obj_attr_2 = base_tile | OBJ_PAL_BANK(2); | ||
495 | } | 645 | } |
496 | } | 646 | } |
497 | 647 | ||
@@ -534,79 +684,227 @@ update_sequencer_sprites(void) { | |||
534 | y += 32; | 684 | y += 32; |
535 | x -= 8 * SEQ_TRIG_DIST; | 685 | x -= 8 * SEQ_TRIG_DIST; |
536 | } | 686 | } |
537 | // TODO: Mask and update instead. | ||
538 | seq_sprites[33].obj_attr_0 = OBJ_SHAPE_SQUARE | OBJ_Y_COORD(y); | 687 | seq_sprites[33].obj_attr_0 = OBJ_SHAPE_SQUARE | OBJ_Y_COORD(y); |
539 | seq_sprites[33].obj_attr_1 = OBJ_SIZE_BIG | OBJ_X_COORD(x); | 688 | seq_sprites[33].obj_attr_1 = OBJ_SIZE_BIG | OBJ_X_COORD(x); |
689 | int base_tile = seq_sprites[33].base_tile; | ||
690 | if (current_selection == SEQ_SELECT_TRIGGER) { | ||
691 | seq_sprites[33].obj_attr_2 = base_tile | OBJ_PAL_BANK(2); | ||
692 | } else { | ||
693 | seq_sprites[33].obj_attr_2 = base_tile | OBJ_PAL_BANK(3); | ||
694 | } | ||
540 | } | 695 | } |
541 | 696 | ||
542 | // 36: Envelope initial volume | 697 | // 36: Envelope initial volume. |
543 | { | 698 | { |
544 | size_t tile_diff = sequence_synth[trig_selection_loc].env_volume * 4; | 699 | size_t tile_diff = sequence_synth[trig_selection_loc].env_volume * 4; |
545 | size_t base_tile = seq_sprites[35].base_tile; | 700 | size_t base_tile = seq_sprites[35].base_tile; |
546 | size_t tile = base_tile + tile_diff; | 701 | size_t tile = base_tile + tile_diff; |
547 | seq_sprites[35].obj_attr_2 = tile | OBJ_PAL_BANK(2); | 702 | seq_sprites[35].obj_attr_2 = tile; |
548 | } | 703 | } |
549 | 704 | ||
550 | // 38: Envelope initial volume | 705 | // 38: Envelope time. |
551 | { | 706 | { |
552 | size_t tile_diff = sequence_synth[trig_selection_loc].env_time * 4; | 707 | size_t tile_diff = sequence_synth[trig_selection_loc].env_time * 4; |
553 | size_t base_tile = seq_sprites[37].base_tile; | 708 | size_t base_tile = seq_sprites[37].base_tile; |
554 | size_t tile = base_tile + tile_diff; | 709 | size_t tile = base_tile + tile_diff; |
555 | seq_sprites[37].obj_attr_2 = tile | OBJ_PAL_BANK(2); | 710 | seq_sprites[37].obj_attr_2 = tile; |
556 | } | 711 | } |
557 | 712 | ||
558 | // 40: Envelope initial volume | 713 | // 40: Envelope direction. |
559 | { | 714 | { |
560 | size_t tile_diff = sequence_synth[trig_selection_loc].env_direction * 4; | 715 | size_t tile_diff = 0; |
716 | if (sequence_synth[trig_selection_loc].env_direction == 0) { | ||
717 | tile_diff = 4; | ||
718 | } | ||
561 | size_t base_tile = seq_sprites[39].base_tile; | 719 | size_t base_tile = seq_sprites[39].base_tile; |
562 | size_t tile = base_tile + tile_diff; | 720 | size_t tile = base_tile + tile_diff; |
563 | seq_sprites[39].obj_attr_2 = tile | OBJ_PAL_BANK(2); | 721 | seq_sprites[39].obj_attr_2 = tile; |
564 | } | 722 | } |
565 | 723 | ||
566 | // 43: Envelope initial volume | 724 | // 43: Duty cycle. |
567 | { | 725 | { |
568 | size_t tile_diff = sequence_synth[trig_selection_loc].duty_cycle * 4; | 726 | size_t tile_diff = sequence_synth[trig_selection_loc].duty_cycle * 4; |
569 | size_t base_tile = seq_sprites[42].base_tile; | 727 | size_t base_tile = seq_sprites[42].base_tile; |
570 | size_t tile = base_tile + tile_diff; | 728 | size_t tile = base_tile + tile_diff; |
571 | seq_sprites[42].obj_attr_2 = tile | OBJ_PAL_BANK(2); | 729 | seq_sprites[42].obj_attr_2 = tile; |
730 | } | ||
731 | |||
732 | // 45: Sweep number. | ||
733 | { | ||
734 | size_t tile_diff = sequence_synth[trig_selection_loc].sweep_number; | ||
735 | size_t base_tile = seq_sprites[44].base_tile; | ||
736 | size_t tile = base_tile + tile_diff; | ||
737 | seq_sprites[44].obj_attr_2 = tile; | ||
738 | } | ||
739 | |||
740 | // 47: Sweep time. | ||
741 | { | ||
742 | size_t tile_diff = sequence_synth[trig_selection_loc].sweep_time; | ||
743 | size_t base_tile = seq_sprites[46].base_tile; | ||
744 | size_t tile = base_tile + tile_diff; | ||
745 | seq_sprites[46].obj_attr_2 = tile; | ||
746 | } | ||
747 | |||
748 | // 49: Sweep direction. | ||
749 | { | ||
750 | size_t tile_diff = sequence_synth[trig_selection_loc].sweep_direction * 4; | ||
751 | size_t base_tile = seq_sprites[48].base_tile; | ||
752 | size_t tile = base_tile + tile_diff; | ||
753 | seq_sprites[48].obj_attr_2 = tile; | ||
754 | } | ||
755 | |||
756 | // 51: Parameter selector. | ||
757 | { | ||
758 | int x = SEQ_ENV_POS_X + 1 + (param_selection_loc % 7) * SEQ_ENV_DIST; | ||
759 | int y = SEQ_ENV_POS_Y - 2; | ||
760 | if (param_selection_loc >= 8) { | ||
761 | y += 32; | ||
762 | x -= 8 * SEQ_TRIG_DIST; | ||
763 | } | ||
764 | int hidden = 0; | ||
765 | if (current_selection != SEQ_SELECT_PARAMETER) { | ||
766 | hidden = OBJ_HIDDEN; | ||
767 | } | ||
768 | seq_sprites[50].obj_attr_0 = OBJ_SHAPE_SQUARE | OBJ_Y_COORD(y) | hidden; | ||
769 | seq_sprites[50].obj_attr_1 = OBJ_SIZE_BIG | OBJ_X_COORD(x); | ||
572 | } | 770 | } |
573 | } | 771 | } |
574 | 772 | ||
575 | void | 773 | void |
576 | handle_sequencer_input(void) { | 774 | handle_sequencer_input(void) { |
577 | if (key_pressed(KEY_LEFT)) { | 775 | if (current_selection == SEQ_SELECT_TRIGGER) { |
578 | if (trig_selection_loc == 0) { | 776 | if (key_pressed(KEY_LEFT)) { |
579 | trig_selection_loc = 15; | 777 | if (trig_selection_loc == 0) { |
580 | } else { | 778 | trig_selection_loc = 15; |
581 | trig_selection_loc = CLAMP(trig_selection_loc - 1, 0, 15); | 779 | } else { |
780 | trig_selection_loc = CLAMP(trig_selection_loc - 1, 0, 15); | ||
781 | } | ||
582 | } | 782 | } |
583 | } | 783 | if (key_pressed(KEY_RIGHT)) { |
584 | if (key_pressed(KEY_RIGHT)) { | 784 | if (trig_selection_loc == 15) { |
585 | if (trig_selection_loc == 15) { | 785 | trig_selection_loc = 0; |
586 | trig_selection_loc = 0; | 786 | } else { |
587 | } else { | 787 | trig_selection_loc = CLAMP(trig_selection_loc + 1, 0, 15); |
588 | trig_selection_loc = CLAMP(trig_selection_loc + 1, 0, 15); | 788 | } |
789 | } | ||
790 | if (key_pressed(KEY_UP) || key_pressed(KEY_DOWN)) { | ||
791 | trig_selection_loc = (trig_selection_loc + 8) % 16; | ||
792 | } | ||
793 | if (key_pressed(KEY_B)) { | ||
794 | sequence_synth[trig_selection_loc].trigger ^= 1; | ||
795 | } | ||
796 | if (key_pressed(KEY_L)) { | ||
797 | sequence_synth[trig_selection_loc].note = CLAMP(sequence_synth[trig_selection_loc].note - 1, NOTE_C_2, NOTE_C_8); | ||
798 | } | ||
799 | if (key_pressed(KEY_R)) { | ||
800 | sequence_synth[trig_selection_loc].note = CLAMP(sequence_synth[trig_selection_loc].note + 1, NOTE_C_2, NOTE_C_8); | ||
801 | } | ||
802 | |||
803 | // Switch to parameter selection. | ||
804 | if (key_pressed(KEY_A)) { | ||
805 | current_selection = SEQ_SELECT_PARAMETER; | ||
806 | } | ||
807 | } else if (current_selection == SEQ_SELECT_PARAMETER) { | ||
808 | // Move through the selected synth parameters. | ||
809 | if (key_pressed(KEY_LEFT)) { | ||
810 | if (param_selection_loc == 0) { | ||
811 | param_selection_loc = 6; | ||
812 | } else { | ||
813 | param_selection_loc = CLAMP(param_selection_loc - 1, 0, 6); | ||
814 | } | ||
815 | } | ||
816 | if (key_pressed(KEY_RIGHT)) { | ||
817 | if (param_selection_loc == 6) { | ||
818 | param_selection_loc = 0; | ||
819 | } else { | ||
820 | param_selection_loc = CLAMP(param_selection_loc + 1, 0, 6); | ||
821 | } | ||
822 | } | ||
823 | |||
824 | // Adjust the parameters up or down. | ||
825 | if (key_pressed(KEY_L)) { | ||
826 | switch (param_selection_loc) { | ||
827 | case 0: { | ||
828 | sequence_synth[trig_selection_loc].env_volume = CLAMP( | ||
829 | sequence_synth[trig_selection_loc].env_volume - 1, 0, 15); | ||
830 | } break; | ||
831 | case 1: { | ||
832 | sequence_synth[trig_selection_loc].env_time = CLAMP( | ||
833 | sequence_synth[trig_selection_loc].env_time - 1, 0, 7); | ||
834 | } break; | ||
835 | case 2: { | ||
836 | sequence_synth[trig_selection_loc].env_direction ^= 1; | ||
837 | } break; | ||
838 | case 3: { | ||
839 | sequence_synth[trig_selection_loc].duty_cycle = CLAMP( | ||
840 | sequence_synth[trig_selection_loc].duty_cycle - 1, 0, 3); | ||
841 | } break; | ||
842 | case 4: { | ||
843 | sequence_synth[trig_selection_loc].sweep_number = CLAMP( | ||
844 | sequence_synth[trig_selection_loc].sweep_number - 1, 0, 7); | ||
845 | } break; | ||
846 | case 5: { | ||
847 | sequence_synth[trig_selection_loc].sweep_time = CLAMP( | ||
848 | sequence_synth[trig_selection_loc].sweep_time - 1, 0, 7); | ||
849 | } break; | ||
850 | case 6: { | ||
851 | if (sequence_synth[trig_selection_loc].sweep_direction == 0) { | ||
852 | sequence_synth[trig_selection_loc].sweep_direction = 1; | ||
853 | } else { | ||
854 | sequence_synth[trig_selection_loc].sweep_direction = 0; | ||
855 | } | ||
856 | } break; | ||
857 | } | ||
858 | } | ||
859 | if (key_pressed(KEY_R)) { | ||
860 | switch (param_selection_loc) { | ||
861 | case 0: { | ||
862 | sequence_synth[trig_selection_loc].env_volume = CLAMP( | ||
863 | sequence_synth[trig_selection_loc].env_volume + 1, 0, 15); | ||
864 | } break; | ||
865 | case 1: { | ||
866 | sequence_synth[trig_selection_loc].env_time = CLAMP( | ||
867 | sequence_synth[trig_selection_loc].env_time + 1, 0, 7); | ||
868 | } break; | ||
869 | case 2: { | ||
870 | sequence_synth[trig_selection_loc].env_direction ^= 1; | ||
871 | } break; | ||
872 | case 3: { | ||
873 | sequence_synth[trig_selection_loc].duty_cycle = CLAMP( | ||
874 | sequence_synth[trig_selection_loc].duty_cycle + 1, 0, 3); | ||
875 | } break; | ||
876 | case 4: { | ||
877 | sequence_synth[trig_selection_loc].sweep_number = CLAMP( | ||
878 | sequence_synth[trig_selection_loc].sweep_number + 1, 0, 7); | ||
879 | } break; | ||
880 | case 5: { | ||
881 | sequence_synth[trig_selection_loc].sweep_time = CLAMP( | ||
882 | sequence_synth[trig_selection_loc].sweep_time + 1, 0, 7); | ||
883 | } break; | ||
884 | case 6: { | ||
885 | sequence_synth[trig_selection_loc].sweep_direction ^= 1; | ||
886 | } break; | ||
887 | } | ||
888 | } | ||
889 | |||
890 | // Go back to trigger selection. | ||
891 | if (key_pressed(KEY_A)) { | ||
892 | current_selection = SEQ_SELECT_TRIGGER; | ||
589 | } | 893 | } |
590 | } | ||
591 | if (key_pressed(KEY_UP) || key_pressed(KEY_DOWN)) { | ||
592 | trig_selection_loc = (trig_selection_loc + 8) % 16; | ||
593 | } | ||
594 | if (key_pressed(KEY_B)) { | ||
595 | sequence_synth[trig_selection_loc].trigger ^= 1; | ||
596 | } | ||
597 | if (key_pressed(KEY_L)) { | ||
598 | sequence_synth[trig_selection_loc].note = CLAMP(sequence_synth[trig_selection_loc].note - 1, NOTE_C_2, NOTE_C_8); | ||
599 | } | ||
600 | if (key_pressed(KEY_R)) { | ||
601 | sequence_synth[trig_selection_loc].note = CLAMP(sequence_synth[trig_selection_loc].note + 1, NOTE_C_2, NOTE_C_8); | ||
602 | } | 894 | } |
603 | 895 | ||
604 | if (key_pressed(KEY_START)) { | 896 | if (key_pressed(KEY_START)) { |
605 | step_counter = 0; | 897 | step_counter = 0; |
606 | set_time(bpm); | 898 | if ((TIMER_CTRL_0 & TIMER_CTRL_ENABLE) == 0) { |
899 | set_time(bpm); | ||
900 | } else { | ||
901 | TIMER_CTRL_0 ^= TIMER_CTRL_ENABLE; | ||
902 | SOUND_SQUARE1_CTRL = 0; | ||
903 | } | ||
607 | } | 904 | } |
608 | if (key_pressed(KEY_SELECT)) { | 905 | if (key_pressed(KEY_SELECT)) { |
609 | TIMER_CTRL_0 ^= TIMER_CTRL_ENABLE; | 906 | TIMER_CTRL_0 ^= TIMER_CTRL_ENABLE; |
907 | SOUND_SQUARE1_CTRL = 0; | ||
610 | } | 908 | } |
611 | } | 909 | } |
612 | 910 | ||