diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/sequencer.c | 318 | ||||
-rw-r--r-- | src/text/text.h | 9 |
2 files changed, 205 insertions, 122 deletions
diff --git a/src/sequencer.c b/src/sequencer.c index 8c3f89a..fbdbbfd 100644 --- a/src/sequencer.c +++ b/src/sequencer.c | |||
@@ -29,6 +29,35 @@ | |||
29 | #define COL_WAVE_A COL_RED | 29 | #define COL_WAVE_A COL_RED |
30 | #define COL_WAVE_B COL_CYAN | 30 | #define COL_WAVE_B COL_CYAN |
31 | 31 | ||
32 | #define CHAN_W 19 | ||
33 | #define CHAN_H 8 | ||
34 | #define CHAN_START_X 34 | ||
35 | #define CHAN_START_Y 92 | ||
36 | #define CHAN_OFFSET_Y 12 | ||
37 | |||
38 | #define TRIG_W 15 | ||
39 | #define TRIG_H 24 | ||
40 | #define TRIG_START_X 63 | ||
41 | #define TRIG_START_Y 92 | ||
42 | #define TRIG_OFFSET_X (TRIG_W + 3) | ||
43 | #define TRIG_OFFSET_Y (TRIG_H + 7) | ||
44 | |||
45 | #define PIANO_W 170 | ||
46 | #define PIANO_H 20 | ||
47 | #define PIANO_START_X 34 | ||
48 | #define PIANO_START_Y 65 | ||
49 | #define PIANO_NOTE_W 2 | ||
50 | |||
51 | #define PARAMS_W 170 | ||
52 | #define PARAMS_H 64 | ||
53 | #define PARAMS_START_X 34 | ||
54 | #define PARAMS_START_Y 1 | ||
55 | |||
56 | #define R_SIDEBAR_X ((TRIG_START_X) + (TRIG_OFFSET_X) * 8 + 2) | ||
57 | #define L_SIDEBAR_X ((CHAN_START_X) - 29) | ||
58 | |||
59 | #define SEQ_N_CHANNELS 4 | ||
60 | |||
32 | // | 61 | // |
33 | // Assets. | 62 | // Assets. |
34 | // | 63 | // |
@@ -155,11 +184,12 @@ static const u32 square_wave[16] = { | |||
155 | // Globals. | 184 | // Globals. |
156 | // | 185 | // |
157 | 186 | ||
158 | static int bpm = 115; | 187 | static int bpm = 75; |
159 | static int step_counter = 0; | 188 | static int step_counter = 0; |
160 | int trig_selection_loc = 0; | 189 | int trig_selection_loc = 0; |
161 | int param_selection_loc = 0; | 190 | int param_selection_loc = 0; |
162 | int channel_selection_loc = 3; | 191 | int channel_selection_loc = 0; |
192 | int play_status = 0; | ||
163 | 193 | ||
164 | typedef struct TriggerNote { | 194 | typedef struct TriggerNote { |
165 | bool active; | 195 | bool active; |
@@ -183,6 +213,13 @@ typedef struct ChannelWaveParams { | |||
183 | u32 wave_b[4]; | 213 | u32 wave_b[4]; |
184 | } ChannelWaveParams; | 214 | } ChannelWaveParams; |
185 | 215 | ||
216 | typedef struct ChannelNoiseParams { | ||
217 | u8 env_volume; | ||
218 | u8 env_time; | ||
219 | u8 env_direction; | ||
220 | u8 bit_mode; | ||
221 | } ChannelNoiseParams; | ||
222 | |||
186 | typedef struct ChannelSquare { | 223 | typedef struct ChannelSquare { |
187 | bool active; | 224 | bool active; |
188 | TriggerNote notes[16]; | 225 | TriggerNote notes[16]; |
@@ -198,6 +235,7 @@ typedef struct ChannelWave { | |||
198 | typedef struct ChannelNoise { | 235 | typedef struct ChannelNoise { |
199 | bool active; | 236 | bool active; |
200 | TriggerNote notes[16]; | 237 | TriggerNote notes[16]; |
238 | ChannelNoiseParams params[16]; | ||
201 | } ChannelNoise; | 239 | } ChannelNoise; |
202 | 240 | ||
203 | static ChannelSquare ch1 = { | 241 | static ChannelSquare ch1 = { |
@@ -323,7 +361,7 @@ static ChannelWave ch3 = { | |||
323 | // TODO: Add default noise parameters data. | 361 | // TODO: Add default noise parameters data. |
324 | static ChannelNoise ch4 = { | 362 | static ChannelNoise ch4 = { |
325 | .notes = { | 363 | .notes = { |
326 | {true, 0}, | 364 | {true, NOTE_C_4}, |
327 | {false, NOTE_D_4}, | 365 | {false, NOTE_D_4}, |
328 | {false, NOTE_E_4}, | 366 | {false, NOTE_E_4}, |
329 | {false, NOTE_F_4}, | 367 | {false, NOTE_F_4}, |
@@ -340,19 +378,74 @@ static ChannelNoise ch4 = { | |||
340 | {false, NOTE_C_4}, | 378 | {false, NOTE_C_4}, |
341 | {false, NOTE_C_4}, | 379 | {false, NOTE_C_4}, |
342 | }, | 380 | }, |
381 | .params = { | ||
382 | {0xF, 0x2, 0, 0}, | ||
383 | {0xF, 0x2, 0, 0}, | ||
384 | {0xF, 0x2, 0, 0}, | ||
385 | {0xF, 0x2, 0, 0}, | ||
386 | {0xF, 0x2, 0, 0}, | ||
387 | {0xF, 0x2, 0, 0}, | ||
388 | {0xF, 0x2, 0, 0}, | ||
389 | {0xF, 0x2, 0, 0}, | ||
390 | {0xF, 0x2, 0, 0}, | ||
391 | {0xF, 0x2, 0, 0}, | ||
392 | {0xF, 0x2, 0, 0}, | ||
393 | {0xF, 0x2, 0, 0}, | ||
394 | {0xF, 0x2, 0, 0}, | ||
395 | {0xF, 0x2, 0, 0}, | ||
396 | {0xF, 0x2, 0, 0}, | ||
397 | {0xF, 0x2, 0, 0}, | ||
398 | }, | ||
343 | .active = true, | 399 | .active = true, |
344 | }; | 400 | }; |
345 | 401 | ||
346 | // | 402 | // |
347 | // Trigger render functions. | 403 | // Channel render functions. |
348 | // | 404 | // |
349 | 405 | ||
350 | #define TRIG_W 15 | 406 | void |
351 | #define TRIG_H 24 | 407 | draw_channels(void) { |
352 | #define TRIG_START_X 64 | 408 | // Contains 5 channel buttons: Ch. 1-4 + FM. We are only drawing the DMG |
353 | #define TRIG_START_Y 92 | 409 | // channels for now, since FM may take some time to develop. |
354 | #define TRIG_OFFSET_X (TRIG_W + 3) | 410 | Tile *channel_tiles = ASSETS_CHANNEL_BUTTONS; |
355 | #define TRIG_OFFSET_Y (TRIG_H + 7) | 411 | size_t k = 0; |
412 | for (size_t i = 0; i < 4; i++) { | ||
413 | bool active = false; | ||
414 | switch (i) { | ||
415 | case 0: { | ||
416 | active = ch1.active; | ||
417 | } break; | ||
418 | case 1: { | ||
419 | active = ch2.active; | ||
420 | } break; | ||
421 | case 2: { | ||
422 | active = ch3.active; | ||
423 | } break; | ||
424 | case 3: { | ||
425 | active = ch4.active; | ||
426 | } break; | ||
427 | } | ||
428 | u8 clr = active ? COL_FG : COL_GREY; | ||
429 | size_t y = CHAN_START_Y + i * CHAN_OFFSET_Y; | ||
430 | draw_tile(CHAN_START_X, y, channel_tiles + k++, clr, false); | ||
431 | draw_tile(CHAN_START_X + 8, y, channel_tiles + k++, clr, false); | ||
432 | draw_tile(CHAN_START_X + 16, y, channel_tiles + k++, clr, false); | ||
433 | } | ||
434 | } | ||
435 | |||
436 | void | ||
437 | draw_channel_cursor(size_t i, u8 clr) { | ||
438 | size_t offset_x = 0; | ||
439 | size_t offset_y = CHAN_H + i * CHAN_OFFSET_Y + 1; | ||
440 | size_t x0 = CHAN_START_X + offset_x; | ||
441 | size_t x1 = CHAN_START_X + offset_x + CHAN_W; | ||
442 | size_t y = CHAN_START_Y + offset_y; | ||
443 | draw_line(x0, y, x1, y, clr); | ||
444 | } | ||
445 | |||
446 | // | ||
447 | // Trigger render functions. | ||
448 | // | ||
356 | 449 | ||
357 | void | 450 | void |
358 | clear_trigger(size_t i) { | 451 | clear_trigger(size_t i) { |
@@ -407,6 +500,80 @@ draw_trig_cursor(size_t i, u8 clr) { | |||
407 | } | 500 | } |
408 | 501 | ||
409 | void | 502 | void |
503 | draw_current_step(u8 col) { | ||
504 | size_t offset_x = TRIG_OFFSET_X * (step_counter % 8); | ||
505 | size_t offset_y = step_counter < 8 ? 2 : 2 + TRIG_OFFSET_Y; | ||
506 | size_t x0 = TRIG_START_X + 4 + offset_x; | ||
507 | size_t x1 = TRIG_START_X - 4 + TRIG_W + offset_x; | ||
508 | size_t y = TRIG_START_Y - 4 + TRIG_H + offset_y; | ||
509 | draw_line(x0, y, x1, y, col); | ||
510 | } | ||
511 | |||
512 | void | ||
513 | draw_play() { | ||
514 | size_t x = R_SIDEBAR_X; | ||
515 | size_t y = TRIG_START_Y; | ||
516 | draw_filled_rect(x, y, x + 24, y + 10, COL_BG); | ||
517 | draw_rect(x, y, x + 24, y + 10, COL_CYAN); | ||
518 | if (play_status == 1) { | ||
519 | // Pause button | ||
520 | draw_filled_rect(x + 10, y + 3, x + 11, y + 7, COL_CYAN); | ||
521 | draw_filled_rect(x + 13, y + 3, x + 14, y + 7, COL_CYAN); | ||
522 | } else { | ||
523 | // Play button | ||
524 | x += 1; | ||
525 | draw_line(x + 10, y + 2, x + 10, y + 8, COL_CYAN); | ||
526 | draw_line(x + 11, y + 3, x + 11, y + 7, COL_CYAN); | ||
527 | draw_line(x + 12, y + 4, x + 12, y + 6, COL_CYAN); | ||
528 | draw_line(x + 13, y + 5, x + 13, y + 5, COL_CYAN); | ||
529 | } | ||
530 | } | ||
531 | |||
532 | void | ||
533 | draw_pattern_buttons() { | ||
534 | size_t x = L_SIDEBAR_X; | ||
535 | size_t y = PARAMS_START_Y + 17; | ||
536 | txt_drawf_small("PAT", x + 5, y - 10, 4, COL_FG); | ||
537 | char pat_names[] = { | ||
538 | 'A', 'B', 'C', 'D', | ||
539 | 'E', 'F', 'G', 'H', | ||
540 | }; | ||
541 | for (size_t i = 0; i < 8; i++) { | ||
542 | draw_rect(x + 5, y, x + 19, y + 12, COL_GREY); | ||
543 | txt_drawc(pat_names[i], x + 9, y + 2, 6, COL_GREY); | ||
544 | y += 17; | ||
545 | } | ||
546 | } | ||
547 | |||
548 | void | ||
549 | draw_stop() { | ||
550 | size_t x = R_SIDEBAR_X; | ||
551 | size_t y = TRIG_START_Y + 14; | ||
552 | draw_rect(x, y, x + 24, y + 10, COL_RED); | ||
553 | draw_filled_rect(x + 10, y + 3, x + 14, y + 7, COL_RED); | ||
554 | // DEBUG: ... | ||
555 | draw_pattern_buttons(); | ||
556 | } | ||
557 | |||
558 | void | ||
559 | draw_bpm() { | ||
560 | size_t x = R_SIDEBAR_X; | ||
561 | size_t y = TRIG_START_Y + TRIG_H + 9; | ||
562 | |||
563 | // Draw bounding box. | ||
564 | draw_rect(x, y, x + 24, y + 22, COL_FG); | ||
565 | draw_line(x + 5, y, x + 19, y, COL_BG); | ||
566 | txt_drawf_small("BPM", x + 5, y - 4, 4, COL_FG); | ||
567 | |||
568 | // Make sure its horizontally centered if only 2 digits | ||
569 | if (bpm >= 100) { | ||
570 | txt_drawf("%d", x + 3, y + 7, 6, COL_FG, bpm); | ||
571 | } else { | ||
572 | txt_drawf("%d", x + 6, y + 7, 6, COL_FG, bpm); | ||
573 | } | ||
574 | } | ||
575 | |||
576 | void | ||
410 | draw_triggers(void) { | 577 | draw_triggers(void) { |
411 | for (size_t i = 0; i < 16; i++) { | 578 | for (size_t i = 0; i < 16; i++) { |
412 | size_t offset_x = TRIG_OFFSET_X * (i % 8); | 579 | size_t offset_x = TRIG_OFFSET_X * (i % 8); |
@@ -421,62 +588,6 @@ draw_triggers(void) { | |||
421 | } | 588 | } |
422 | } | 589 | } |
423 | 590 | ||
424 | // | ||
425 | // Channel render functions. | ||
426 | // | ||
427 | |||
428 | #define CHAN_W 19 | ||
429 | #define CHAN_H 8 | ||
430 | #define CHAN_START_X 35 | ||
431 | #define CHAN_START_Y 92 | ||
432 | #define CHAN_OFFSET_Y 12 | ||
433 | |||
434 | void | ||
435 | draw_channels(void) { | ||
436 | // Contains 5 channel buttons: Ch. 1-4 + FM. We are only drawing the DMG | ||
437 | // channels for now, since FM may take some time to develop. | ||
438 | Tile *channel_tiles = ASSETS_CHANNEL_BUTTONS; | ||
439 | size_t k = 0; | ||
440 | for (size_t i = 0; i < 4; i++) { | ||
441 | bool active = false; | ||
442 | switch (i) { | ||
443 | case 0: { | ||
444 | active = ch1.active; | ||
445 | } break; | ||
446 | case 1: { | ||
447 | active = ch2.active; | ||
448 | } break; | ||
449 | case 2: { | ||
450 | active = ch3.active; | ||
451 | } break; | ||
452 | case 3: { | ||
453 | active = ch4.active; | ||
454 | } break; | ||
455 | } | ||
456 | u8 clr = active ? COL_FG : COL_GREY; | ||
457 | size_t y = CHAN_START_Y + i * CHAN_OFFSET_Y; | ||
458 | draw_tile(CHAN_START_X, y, channel_tiles + k++, clr, false); | ||
459 | draw_tile(CHAN_START_X + 8, y, channel_tiles + k++, clr, false); | ||
460 | draw_tile(CHAN_START_X + 16, y, channel_tiles + k++, clr, false); | ||
461 | } | ||
462 | } | ||
463 | |||
464 | void | ||
465 | draw_channel_cursor(size_t i, u8 clr) { | ||
466 | size_t offset_x = 0; | ||
467 | size_t offset_y = CHAN_H + i * CHAN_OFFSET_Y + 1; | ||
468 | size_t x0 = CHAN_START_X + offset_x; | ||
469 | size_t x1 = CHAN_START_X + offset_x + CHAN_W; | ||
470 | size_t y = CHAN_START_Y + offset_y; | ||
471 | draw_line(x0, y, x1, y, clr); | ||
472 | } | ||
473 | |||
474 | #define PIANO_W 170 | ||
475 | #define PIANO_H 20 | ||
476 | #define PIANO_START_X 35 | ||
477 | #define PIANO_START_Y 65 | ||
478 | #define PIANO_NOTE_W 2 | ||
479 | |||
480 | void | 591 | void |
481 | draw_note(u8 note, u8 clr) { | 592 | draw_note(u8 note, u8 clr) { |
482 | size_t octave = note / 12; | 593 | size_t octave = note / 12; |
@@ -611,11 +722,6 @@ draw_piano(void) { | |||
611 | } | 722 | } |
612 | } | 723 | } |
613 | 724 | ||
614 | #define PARAMS_W 170 | ||
615 | #define PARAMS_H 64 | ||
616 | #define PARAMS_START_X 35 | ||
617 | #define PARAMS_START_Y 1 | ||
618 | |||
619 | void | 725 | void |
620 | draw_params_cursor_wave(size_t i, u8 clr) { | 726 | draw_params_cursor_wave(size_t i, u8 clr) { |
621 | u8 x_positions[] = { | 727 | u8 x_positions[] = { |
@@ -1373,49 +1479,11 @@ irq_timer(void) { | |||
1373 | } | 1479 | } |
1374 | if (ch4.active) { | 1480 | if (ch4.active) { |
1375 | TriggerNote *trig = &ch4.notes[step_counter]; | 1481 | TriggerNote *trig = &ch4.notes[step_counter]; |
1376 | // ChannelNoiseParams *params = &ch4.params[step_counter]; | 1482 | ChannelNoiseParams *params = &ch4.params[step_counter]; |
1483 | SOUND_NOISE_CTRL = SOUND_NOISE_ENV_VOL(params->env_volume) | ||
1484 | | SOUND_NOISE_ENV_TIME(params->env_time) | ||
1485 | | SOUND_NOISE_ENV_DIR(params->env_direction); | ||
1377 | if (trig->active) { | 1486 | if (trig->active) { |
1378 | // switch (params->wave_mode) { | ||
1379 | // case 0: { | ||
1380 | // SOUND_WAVE_MODE = SOUND_WAVE_BANK_SELECT(1); | ||
1381 | // memcpy32(SOUND_WAVE_RAM, params->wave_a, 16); | ||
1382 | // SOUND_WAVE_MODE = SOUND_WAVE_BANK_MODE(0) | ||
1383 | // | SOUND_WAVE_BANK_SELECT(0); | ||
1384 | // } break; | ||
1385 | // case 1: { | ||
1386 | // SOUND_WAVE_MODE = SOUND_WAVE_BANK_SELECT(0); | ||
1387 | // memcpy32(SOUND_WAVE_RAM, params->wave_b, 16); | ||
1388 | // SOUND_WAVE_MODE = SOUND_WAVE_BANK_MODE(0) | ||
1389 | // | SOUND_WAVE_BANK_SELECT(1); | ||
1390 | // } break; | ||
1391 | // case 2: { | ||
1392 | // SOUND_WAVE_MODE = SOUND_WAVE_BANK_SELECT(0); | ||
1393 | // memcpy32(SOUND_WAVE_RAM, params->wave_b, 16); | ||
1394 | // SOUND_WAVE_MODE = SOUND_WAVE_BANK_SELECT(1); | ||
1395 | // memcpy32(SOUND_WAVE_RAM, params->wave_a, 16); | ||
1396 | // SOUND_WAVE_MODE = SOUND_WAVE_BANK_MODE(1) | ||
1397 | // | SOUND_WAVE_BANK_SELECT(0); | ||
1398 | // } break; | ||
1399 | // } | ||
1400 | // SOUND_WAVE_MODE |= SOUND_WAVE_ENABLE; | ||
1401 | |||
1402 | // switch (params->wave_volume) { | ||
1403 | // case 0: { | ||
1404 | // SOUND_WAVE_CTRL = SOUND_WAVE_MUTE; | ||
1405 | // } break; | ||
1406 | // case 1: { | ||
1407 | // SOUND_WAVE_CTRL = SOUND_WAVE_VOL_25; | ||
1408 | // } break; | ||
1409 | // case 2: { | ||
1410 | // SOUND_WAVE_CTRL = SOUND_WAVE_VOL_50; | ||
1411 | // } break; | ||
1412 | // case 3: { | ||
1413 | // SOUND_WAVE_CTRL = SOUND_WAVE_VOL_75; | ||
1414 | // } break; | ||
1415 | // case 4: { | ||
1416 | // SOUND_WAVE_CTRL = SOUND_WAVE_VOL_100; | ||
1417 | // } break; | ||
1418 | // } | ||
1419 | static const u8 div_freq[] = { | 1487 | static const u8 div_freq[] = { |
1420 | 7, 6, 5, 4, 7, 6, 5, 4, 7, 6, 5, 4, | 1488 | 7, 6, 5, 4, 7, 6, 5, 4, 7, 6, 5, 4, |
1421 | 7, 6, 5, 4, 7, 6, 5, 4, 7, 6, 5, 4, | 1489 | 7, 6, 5, 4, 7, 6, 5, 4, 7, 6, 5, 4, |
@@ -1432,14 +1500,10 @@ irq_timer(void) { | |||
1432 | 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, | 1500 | 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, |
1433 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 1501 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
1434 | }; | 1502 | }; |
1435 | SOUND_NOISE_CTRL = SOUND_NOISE_ENV_VOL(0xF) | ||
1436 | | SOUND_NOISE_ENV_TIME(0x2) | ||
1437 | | SOUND_NOISE_ENV_DIR(0) | ||
1438 | | SOUND_NOISE_LENGTH(50); | ||
1439 | SOUND_NOISE_FREQ = SOUND_FREQ_RESET | 1503 | SOUND_NOISE_FREQ = SOUND_FREQ_RESET |
1440 | | SOUND_NOISE_PRESTEP_FREQ(pre_freq[trig->note]) | 1504 | | SOUND_NOISE_PRESTEP_FREQ(pre_freq[trig->note]) |
1441 | | SOUND_NOISE_DIV_FREQ(div_freq[trig->note]) | 1505 | | SOUND_NOISE_DIV_FREQ(div_freq[trig->note]) |
1442 | | SOUND_NOISE_COUNTER_STAGE(0) | 1506 | | SOUND_NOISE_COUNTER_STAGE(1) |
1443 | | SOUND_NOISE_TIMED_MODE(0); | 1507 | | SOUND_NOISE_TIMED_MODE(0); |
1444 | } else { | 1508 | } else { |
1445 | SOUND_NOISE_FREQ = 0; | 1509 | SOUND_NOISE_FREQ = 0; |
@@ -1448,7 +1512,9 @@ irq_timer(void) { | |||
1448 | SOUND_NOISE_CTRL = 0; | 1512 | SOUND_NOISE_CTRL = 0; |
1449 | SOUND_NOISE_FREQ = 0; | 1513 | SOUND_NOISE_FREQ = 0; |
1450 | } | 1514 | } |
1515 | draw_current_step(COL_BG); | ||
1451 | step_counter = (step_counter + 1) % 16; | 1516 | step_counter = (step_counter + 1) % 16; |
1517 | draw_current_step(COL_RED); | ||
1452 | } | 1518 | } |
1453 | 1519 | ||
1454 | void | 1520 | void |
@@ -1489,8 +1555,6 @@ get_current_trig(void) { | |||
1489 | // selection. | 1555 | // selection. |
1490 | void (*input_handler)(void); | 1556 | void (*input_handler)(void); |
1491 | 1557 | ||
1492 | #define SEQ_N_CHANNELS 4 | ||
1493 | |||
1494 | void handle_trigger_selection(void); | 1558 | void handle_trigger_selection(void); |
1495 | void handle_channel_selection(void); | 1559 | void handle_channel_selection(void); |
1496 | void handle_param_selection_sq1(void); | 1560 | void handle_param_selection_sq1(void); |
@@ -2132,23 +2196,31 @@ handle_sequencer_input(void) { | |||
2132 | 2196 | ||
2133 | if (key_tap(KEY_START)) { | 2197 | if (key_tap(KEY_START)) { |
2134 | // Stop the sequencer or start playing from the beginning. | 2198 | // Stop the sequencer or start playing from the beginning. |
2199 | play_status ^= 1; | ||
2200 | if (step_counter != 0) { | ||
2201 | draw_current_step(COL_BG); | ||
2202 | } | ||
2135 | step_counter = 0; | 2203 | step_counter = 0; |
2136 | if ((TIMER_CTRL_0 & TIMER_CTRL_ENABLE) == 0) { | 2204 | if ((TIMER_CTRL_0 & TIMER_CTRL_ENABLE) == 0) { |
2137 | set_time(bpm); | 2205 | set_time(bpm); |
2138 | } else { | 2206 | } else { |
2207 | draw_current_step(COL_RED); | ||
2139 | TIMER_CTRL_0 ^= TIMER_CTRL_ENABLE; | 2208 | TIMER_CTRL_0 ^= TIMER_CTRL_ENABLE; |
2140 | SOUND_SQUARE1_CTRL = 0; | 2209 | SOUND_SQUARE1_CTRL = 0; |
2141 | SOUND_SQUARE2_CTRL = 0; | 2210 | SOUND_SQUARE2_CTRL = 0; |
2142 | SOUND_WAVE_CTRL = 0; | 2211 | SOUND_WAVE_CTRL = 0; |
2143 | SOUND_NOISE_CTRL = 0; | 2212 | SOUND_NOISE_CTRL = 0; |
2144 | } | 2213 | } |
2214 | draw_play(); | ||
2145 | } else if (key_tap(KEY_SELECT)) { | 2215 | } else if (key_tap(KEY_SELECT)) { |
2146 | // Play/pause. | 2216 | // Play/pause. |
2217 | play_status ^= 1; | ||
2147 | TIMER_CTRL_0 ^= TIMER_CTRL_ENABLE; | 2218 | TIMER_CTRL_0 ^= TIMER_CTRL_ENABLE; |
2148 | SOUND_SQUARE1_CTRL = 0; | 2219 | SOUND_SQUARE1_CTRL = 0; |
2149 | SOUND_SQUARE2_CTRL = 0; | 2220 | SOUND_SQUARE2_CTRL = 0; |
2150 | SOUND_WAVE_CTRL = 0; | 2221 | SOUND_WAVE_CTRL = 0; |
2151 | SOUND_NOISE_CTRL = 0; | 2222 | SOUND_NOISE_CTRL = 0; |
2223 | draw_play(); | ||
2152 | } | 2224 | } |
2153 | } | 2225 | } |
2154 | 2226 | ||
@@ -2178,7 +2250,11 @@ sequencer_init(void) { | |||
2178 | input_handler = handle_trigger_selection; | 2250 | input_handler = handle_trigger_selection; |
2179 | draw_trig_cursor(trig_selection_loc, COL_CURSOR); | 2251 | draw_trig_cursor(trig_selection_loc, COL_CURSOR); |
2180 | draw_channel_cursor(channel_selection_loc, COL_CURRENT_CHANNEL); | 2252 | draw_channel_cursor(channel_selection_loc, COL_CURRENT_CHANNEL); |
2253 | draw_current_step(COL_RED); | ||
2181 | draw_parameters(); | 2254 | draw_parameters(); |
2255 | draw_bpm(); | ||
2256 | draw_play(); | ||
2257 | draw_stop(); | ||
2182 | 2258 | ||
2183 | // Initialize sound system. | 2259 | // Initialize sound system. |
2184 | SOUND_STATUS = SOUND_ENABLE; | 2260 | SOUND_STATUS = SOUND_ENABLE; |
@@ -2187,6 +2263,4 @@ sequencer_init(void) { | |||
2187 | | SOUND_WAVE | 2263 | | SOUND_WAVE |
2188 | | SOUND_NOISE, 3); | 2264 | | SOUND_NOISE, 3); |
2189 | SOUND_DSOUND_MASTER = SOUND_DMG25; | 2265 | SOUND_DSOUND_MASTER = SOUND_DMG25; |
2190 | // SOUND_NOISE_CTRL = SOUND_NOISE_ENV_VOL(0x8) | SOUND_NOISE_ENV_TIME(0) | SOUND_NOISE_ENV_DIR(1) | 0x4; | ||
2191 | // SOUND_NOISE_FREQ = SOUND_FREQ_RESET | SOUND_NOISE_PRESTEP_FREQ(0x7) | SOUND_NOISE_DIV_FREQ(2) | SOUND_NOISE_COUNTER_STAGE(1); | ||
2192 | } | 2266 | } |
diff --git a/src/text/text.h b/src/text/text.h index 647a021..0bcf090 100644 --- a/src/text/text.h +++ b/src/text/text.h | |||
@@ -119,6 +119,15 @@ txt_draws(char *msg, size_t x, size_t y, size_t spacing, u8 clr) { | |||
119 | } | 119 | } |
120 | } | 120 | } |
121 | 121 | ||
122 | static inline | ||
123 | void | ||
124 | txt_drawc(char c, size_t x, size_t y, size_t spacing, u8 clr) { | ||
125 | Tile *tile = FONT_DATA; | ||
126 | tile += c; | ||
127 | draw_tile(x, y, tile, clr, true); | ||
128 | x += spacing; | ||
129 | } | ||
130 | |||
122 | // Print text to the screen with formatting. | 131 | // Print text to the screen with formatting. |
123 | #define txt_printf(msg, ...) \ | 132 | #define txt_printf(msg, ...) \ |
124 | { \ | 133 | { \ |