Advertisement
MegaLoler

Sound Chip Tracker

May 6th, 2013
93
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 23.89 KB | None | 0 0
  1. // Just a backup for my uncompleted tracker program for my sound chip
  2.  
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #include <time.h>
  7. #include <ncurses.h>
  8.  
  9. #define NOTE_NULL 0x0
  10. #define NOTE_RESET 0x1
  11. #define NOTE_ON 0x2
  12. #define NOTE_OFF 0x3
  13. #define NOTE_C 0x4
  14. #define NOTE_Cs 0x5
  15. #define NOTE_Db 0x5
  16. #define NOTE_D 0x6
  17. #define NOTE_Ds 0x7
  18. #define NOTE_Eb 0x7
  19. #define NOTE_E 0x8
  20. #define NOTE_F 0x9
  21. #define NOTE_Fs 0xA
  22. #define NOTE_Gb 0xA
  23. #define NOTE_G 0xB
  24. #define NOTE_Gs 0xC
  25. #define NOTE_Ab 0xC
  26. #define NOTE_A 0xD
  27. #define NOTE_As 0xE
  28. #define NOTE_Bb 0xE
  29. #define NOTE_B 0xF
  30.  
  31. #define EFF_ARPEGGIO 0x0
  32. #define EFF_PITCH_SLIDE_UP 0x1
  33. #define EFF_PITCH_SLIDE_DOWN 0x2
  34. #define EFF_PORTAMENTO 0x3
  35. #define EFF_VIBRATO 0x4
  36. #define EFF_WAVEFORM 0x5
  37. #define EFF_DUTY_CYCLE 0x6
  38. #define EFF_TREMOLO 0x7
  39. #define EFF_PWM 0x8
  40. #define EFF_PITCH 0x9
  41. #define EFF_VOLUME_SLIDE_UP 0xA
  42. #define EFF_VOLUME_SLIDE_DOWN 0xB
  43. #define EFF_VOLUME 0xC
  44. #define EFF_ENVELOPE_ATTACK_DECAY 0xD
  45. #define EFF_ENVELOPE_SUSTAIN_RELEASE 0xE
  46. #define EFF_FINE_TUNE 0xF
  47.  
  48. FILE *out;
  49. char serialPort[255];
  50.  
  51. typedef struct
  52. {
  53.     unsigned char enable;
  54.     unsigned char effect;
  55.     unsigned char argument;
  56.    
  57. } Effect;
  58.  
  59. typedef struct
  60. {
  61.     unsigned char note;
  62.     unsigned char octave;
  63.     unsigned char volume;
  64.     unsigned char applyInstrument;
  65.     unsigned char instrument;
  66.    
  67. } NoteCommand;
  68.  
  69. typedef struct
  70. {
  71.     NoteCommand noteCommand;
  72.     Effect effect;
  73.    
  74. } Entry;
  75.  
  76. typedef struct
  77. {
  78.     Entry entries[4];
  79.    
  80. } Frame;
  81.  
  82. typedef struct
  83. {
  84.     Effect effects[8];
  85.    
  86. } Instrument;
  87.  
  88. typedef struct
  89. {
  90.     Frame frames[32];
  91.    
  92. } Order;
  93.  
  94. typedef struct
  95. {
  96.     unsigned char fps;
  97.     unsigned char orderCount;
  98.     unsigned char repeat;
  99.     unsigned char instrumentCount;
  100.     Instrument *instruments;
  101.     Order *orders;
  102.    
  103. } Song;
  104.  
  105. void printTabs(int tabs)
  106. {
  107.     int i;
  108.     for(i = 0; i < tabs; i++)
  109.     {
  110.         printf("\t");
  111.     }
  112. }
  113.  
  114. void printEffect(Effect *effect, int tabs)
  115. {
  116.     int s1, s2;
  117.     s1 = (effect->argument) >> 4;
  118.     s2 = (effect->argument) & 0x0F;
  119.     printTabs(tabs);
  120.     if(effect->enable)
  121.     {
  122.         switch(effect->effect)
  123.         {
  124.             case 0x0:
  125.                 if(s1 || s2)
  126.                 {
  127.                     printf("Arpeggio: Semitones: %i, %i\n", s1, s2);
  128.                 }
  129.                 else
  130.                 {
  131.                     printf("Arpeggio Off\n");
  132.                 }
  133.                 break;
  134.             case 0x1:
  135.                 printf("Pitch Slide Up: Rate: %i\n", effect->argument);
  136.                 break;
  137.             case 0x2:
  138.                 printf("Pitch Slide Down: Rate: %i\n", effect->argument);
  139.                 break;
  140.             case 0x3:
  141.                 if(effect->argument)
  142.                 {
  143.                     printf("Portamento: Rate: %i\n", effect->argument);
  144.                 }
  145.                 else
  146.                 {
  147.                     printf("Portamento Off");
  148.                 }
  149.                 break;
  150.             case 0x4:
  151.                 printf("Vibrato: Rate: %i, Depth: %i\n", s1, s2);
  152.                 break;
  153.             case 0x5:
  154.                 printf("Waveform: ");
  155.                 switch(effect->argument)
  156.                 {
  157.                     case 0:
  158.                         printf("Pulse\n");
  159.                         break;
  160.                     case 1:
  161.                         printf("Triangle\n");
  162.                         break;
  163.                     case 2:
  164.                         printf("Sawtooth\n");
  165.                         break;
  166.                     case 3:
  167.                         printf("Noise\n");
  168.                         break;
  169.                     default:
  170.                         printf("Unknown\n");
  171.                 }
  172.                 break;
  173.             case 0x6:
  174.                 printf("Duty Cycle: %i\%\n", effect->argument / 256 * 100);
  175.                 break;
  176.             case 0x7:
  177.                 printf("Tremolo: Rate: %i, Depth: %i\n", s1, s2);
  178.                 break;
  179.             case 0x8:
  180.                 printf("Pulse Width Modulation: Rate: %i, Depth: %i\n", s1, s2);
  181.                 break;
  182.             case 0x9:
  183.                 printf("Pitch: %i\n", effect->argument);
  184.                 break;
  185.             case 0xA:
  186.                 printf("Volume Slide Up: Rate: %i\n", effect->argument);
  187.                 break;
  188.             case 0xB:
  189.                 printf("Volume Slide Down: Rate: %i\n", effect->argument);
  190.                 break;
  191.             case 0xC:
  192.                 printf("Volume: %i\n", effect->argument);
  193.                 break;
  194.             case 0xD:
  195.                 printf("Envelope: Attack: %i, Decay: %i\n", s1, s2);
  196.                 break;
  197.             case 0xE:
  198.                 printf("Envelope: Sustain: %i\%, Release: %i\n", s1 / 16 * 100, s2);
  199.                 break;
  200.             case 0xF:
  201.                 printf("Fine Tune: %i\n", effect->argument);
  202.                 break;
  203.             default:
  204.                 printf("Unknown Effect\n");
  205.         }
  206.     }
  207.     else
  208.     {
  209.         printf("No Effect\n");
  210.     }
  211. }
  212.  
  213. void printInstrumentInfo(Instrument *instrument, int tabs)
  214. {
  215.     int i;
  216.     for(i = 0; i < sizeof(instrument->effects) / sizeof(Effect); i++)
  217.     {
  218.         printTabs(tabs);
  219.         printf("Effect #%i:\n", i + 1);
  220.         printEffect(&(instrument->effects[i]), tabs + 1);
  221.     }
  222. }
  223.  
  224. void printNote(unsigned char note, unsigned char octave, int tabs)
  225. {
  226.     printTabs(tabs);
  227.     switch(note)
  228.     {
  229.         case 0x0:
  230.             printf("No Note\n");
  231.             break;
  232.         case 0x1:
  233.             printf("Reset Oscillator Timer\n");
  234.             break;
  235.         case 0x2:
  236.             printf("Enable Oscillator\n");
  237.             break;
  238.         case 0x3:
  239.             printf("Disable Oscillator\n");
  240.             break;
  241.         case 0x4:
  242.             printf("Play Note C%i\n", octave);
  243.             break;
  244.         case 0x5:
  245.             printf("Play Note C#%i\n", octave);
  246.             break;
  247.         case 0x6:
  248.             printf("Play Note D%i\n", octave);
  249.             break;
  250.         case 0x7:
  251.             printf("Play Note D#%i\n", octave);
  252.             break;
  253.         case 0x8:
  254.             printf("Play Note E%i\n", octave);
  255.             break;
  256.         case 0x9:
  257.             printf("Play Note F%i\n", octave);
  258.             break;
  259.         case 0xA:
  260.             printf("Play Note F#%i\n", octave);
  261.             break;
  262.         case 0xB:
  263.             printf("Play Note G%i\n", octave);
  264.             break;
  265.         case 0xC:
  266.             printf("Play Note G#%i\n", octave);
  267.             break;
  268.         case 0xD:
  269.             printf("Play Note A%i\n", octave);
  270.             break;
  271.         case 0xE:
  272.             printf("Play Note A#%i\n", octave);
  273.             break;
  274.         case 0xF:
  275.             printf("Play Note B%i\n", octave);
  276.             break;
  277.         default:
  278.             printf("Unknown Command\n");
  279.     }
  280. }
  281.  
  282. void printVolume(unsigned char volume, int tabs)
  283. {
  284.     printTabs(tabs);
  285.     if(volume)
  286.     {
  287.         printf("Volume: %i\%\n", volume / 32 * 100);
  288.     }
  289.     else
  290.     {
  291.         printf("Ignore Volume\n");
  292.     }
  293. }
  294.  
  295. void printInstrumentID(unsigned char applyInstrument, unsigned char instrument, int tabs)
  296. {
  297.     printTabs(tabs);
  298.     if(applyInstrument)
  299.     {
  300.         printf("Apply Instrument #%i\n", instrument + 1);
  301.     }
  302.     else
  303.     {
  304.         printf("Ignore Instrument\n");
  305.     }
  306. }
  307.  
  308. void printNoteCommand(NoteCommand *noteCommand, int tabs)
  309. {
  310.     printNote(noteCommand->note, noteCommand->octave, tabs);
  311.     printVolume(noteCommand->volume, tabs);
  312.     printInstrumentID(noteCommand->applyInstrument, noteCommand->instrument, tabs);
  313. }
  314.  
  315. void printEntry(Entry *entry, int tabs)
  316. {
  317.     printNoteCommand(&(entry->noteCommand), tabs);
  318.     printEffect(&(entry->effect), tabs);
  319. }
  320.  
  321. void printFrame(Frame *frame, int tabs)
  322. {
  323.     int i;
  324.     for(i = 0; i < sizeof(frame->entries) / sizeof(Entry); i++)
  325.     {
  326.         printTabs(tabs);
  327.         printf("Channel #%i:\n", i + 1);
  328.         printEntry(&(frame->entries[i]), tabs + 1);
  329.     }
  330. }
  331.  
  332. void printOrderInfo(Order *order, int tabs)
  333. {
  334.     int i;
  335.     for(i = 0; i < sizeof(order->frames) / sizeof(Frame); i++)
  336.     {
  337.         printTabs(tabs);
  338.         printf("Frame #%i:\n", i + 1);
  339.         printFrame(&(order->frames[i]), tabs + 1);
  340.     }
  341. }
  342.  
  343. void printSongInfo(Song *song)
  344. {
  345.     printf("Speed: %i FPS\n", song->fps);
  346.     printf("Length: %i Orders\n", song->orderCount);
  347.     printf("Repeat: Order #%i\n", song->repeat + 1);
  348.     printf("Instrument Count: %i\n", song->instrumentCount);
  349.    
  350.     printf("Instruments:\n");
  351.     int i;
  352.     for(i = 0; i <  song->instrumentCount; i++)
  353.     {
  354.         printf("\tInstrument #%i:\n", i + 1);
  355.         printInstrumentInfo(&(song->instruments[0]), 2);
  356.     }
  357.    
  358.     printf("Orders:\n");
  359.     for(i = 0; i <  song->orderCount; i++)
  360.     {
  361.         printf("\tOrder #%i:\n", i + 1);
  362.         printOrderInfo(&(song->orders[0]), 2);
  363.     }
  364. }
  365.  
  366. void playNote(unsigned char note, unsigned char octave, unsigned char volume, unsigned char osc)
  367. {
  368.     note &= 0x0F;
  369.     octave &= 0b00000111;
  370.     volume &= 0b00011111;
  371.     osc &= 0b00000011;
  372.    
  373.     char highByte = (octave >> 1) | (volume << 2) | (1 << 7);
  374.     char lowByte = (osc << 1) | (note << 3) | (octave << 7);
  375.    
  376.     fputc(highByte, out);
  377.     fputc(lowByte, out);
  378.     fputc(0xFF, out);
  379.    
  380.     fclose(out);
  381.     out = fopen(serialPort, "w");
  382. }
  383.  
  384. void playEffect(unsigned char effect, unsigned char argument, unsigned char osc)
  385. {
  386.     effect &= 0x0F;
  387.     osc &= 0b00000011;
  388.    
  389.     char highByte = (argument >> 1) | (1 << 7);
  390.     char lowByte = 1 | (osc << 1) | (effect << 3) | (argument << 7);
  391.    
  392.     fputc(highByte, out);
  393.     fputc(lowByte, out);
  394.     fputc(0xFF, out);
  395.    
  396.     fclose(out);
  397.     out = fopen(serialPort, "w");
  398. }
  399.  
  400. void sendEffectCommand(Effect *effect, unsigned char osc)
  401. {
  402.     if(effect->enable)
  403.     {
  404.         playEffect(effect->effect, effect->argument, osc);
  405.     }
  406. }
  407.  
  408. void sendNoteCommand(NoteCommand *noteCommand, unsigned char osc)
  409. {
  410.     playNote(noteCommand->note, noteCommand->octave, noteCommand->volume, osc);
  411.     //applyInstrument goes here
  412. }
  413.  
  414. void playEntry(Entry *entry, unsigned char osc)
  415. {
  416.     sendEffectCommand(&entry->effect, osc);
  417.     sendNoteCommand(&entry->noteCommand, osc);
  418. }
  419.  
  420. void playFrame(Frame *frame)
  421. {
  422.     playEntry(&frame->entries[0], 0);
  423.     playEntry(&frame->entries[1], 1);
  424.     playEntry(&frame->entries[2], 2);
  425.     playEntry(&frame->entries[3], 3);
  426. }
  427.  
  428. NoteCommand newNoteCommand(unsigned char note, unsigned char octave, unsigned char volume, unsigned char applyInstrument, unsigned char instrument)
  429. {
  430.     NoteCommand command;
  431.     command.note = note;
  432.     command.octave = octave;
  433.     command.volume = volume;
  434.     command.applyInstrument = applyInstrument;
  435.     command.instrument = instrument;
  436.     return command;
  437. }
  438.  
  439. NoteCommand newSimpleNoteCommand(unsigned char note, unsigned char octave, unsigned char volume)
  440. {
  441.     return newNoteCommand(note, octave, volume, 0, 0);
  442. }
  443.  
  444. NoteCommand newSimplestNoteCommand(unsigned char note, unsigned char octave)
  445. {
  446.     return newSimpleNoteCommand(note, octave, 0);
  447. }
  448.  
  449. NoteCommand newNullNoteCommand()
  450. {
  451.     return newSimplestNoteCommand(NOTE_NULL, 0);
  452. }
  453.  
  454. NoteCommand newResetNoteCommand()
  455. {
  456.     return newSimplestNoteCommand(NOTE_RESET, 0);
  457. }
  458.  
  459. NoteCommand newNoteOnCommand()
  460. {
  461.     return newSimplestNoteCommand(NOTE_ON, 0);
  462. }
  463.  
  464. NoteCommand newNoteOffCommand()
  465. {
  466.     return newSimplestNoteCommand(NOTE_OFF, 0);
  467. }
  468.  
  469. Effect newEffect(unsigned char effect, unsigned char argument)
  470. {
  471.     Effect new_effect;
  472.     new_effect.enable = 1;
  473.     new_effect.effect = effect;
  474.     new_effect.argument = argument;
  475.     return new_effect;
  476. }
  477.  
  478. Effect newNullEffect()
  479. {
  480.     Effect effect;
  481.     effect.enable = 0;
  482.     effect.effect = 0;
  483.     effect.argument = 0;
  484.     return effect;
  485. }
  486.  
  487. Entry newEntry(NoteCommand command, Effect effect)
  488. {
  489.     Entry entry;
  490.     entry.noteCommand = command;
  491.     entry.effect = effect;
  492.     return entry;
  493. }
  494.  
  495. Entry newSimpleEntry(NoteCommand command)
  496. {
  497.     return newEntry(command, newNullEffect());
  498. }
  499.  
  500. Entry newNullEntry()
  501. {
  502.     return newEntry(newNullNoteCommand(), newNullEffect());
  503. }
  504.  
  505. Frame newFrame(Entry entry1, Entry entry2, Entry entry3, Entry entry4)
  506. {
  507.     Frame frame;
  508.     frame.entries[0] = entry1;
  509.     frame.entries[1] = entry2;
  510.     frame.entries[2] = entry3;
  511.     frame.entries[3] = entry4;
  512.     return frame;
  513. }
  514.  
  515. Frame newUnisonFrame(Entry entry)
  516. {
  517.     return newFrame(entry, entry, entry, entry);
  518. }
  519.  
  520. Frame newQuietFrame()
  521. {
  522.     return newUnisonFrame(newSimpleEntry(newNoteOffCommand()));
  523. }
  524.  
  525. Order *newEmptyOrder()
  526. {
  527.     Order *order;
  528.    
  529.     int i;
  530.     for(i = 0; i < sizeof(order->frames) / sizeof(Frame); i++)
  531.     {
  532.         order->frames[i] = newQuietFrame();
  533.     }
  534.    
  535.     return order;
  536. }
  537.  
  538. void playOrder(Order *order, int fps)
  539. {
  540.     int i;
  541.     for(i = 0; i < sizeof(order->frames) / sizeof(Frame); i++)
  542.     {
  543.         printFrame(&order->frames[i], 0);
  544.         playFrame(&order->frames[i]);
  545.         usleep(1000000 / fps);
  546.     }
  547.    
  548.     Frame frame = newQuietFrame();
  549.     playFrame(&frame);
  550. }
  551.  
  552. WINDOW *orderWindow;
  553. WINDOW *instrumentWindow;
  554. WINDOW *effectWindow;
  555. WINDOW *trackerWindow;
  556.  
  557. int w1, w2, h1, h2;
  558.  
  559. #define WIN_ORDER 0
  560. #define WIN_INSTR 1
  561. #define WIN_EFFECT 2
  562. #define WIN_TRACKER 3
  563. int curWindow = WIN_TRACKER;
  564.  
  565. #define MODE_EDIT 0
  566. #define MODE_PLAY 1
  567. #define MODE_JAM 2
  568. int curMode = MODE_EDIT;
  569.  
  570. #define MAX_ORDERS 64
  571. #define MAX_INSTRUMENTS 16
  572.  
  573. Song song;
  574.  
  575. int curOrder = 0;
  576. int curInstrument = 0;
  577. int curEffect = 0;
  578. int orderScroll = 0;
  579. int instrumentScroll = 0;
  580.  
  581. int curY = 5;
  582. int curX = 5;
  583.  
  584. void placeCursor()
  585. {
  586.     move(curY + h1, curX);
  587. }
  588.  
  589. void printTitle(WINDOW *window, char *title)
  590. {
  591.     int h, w;
  592.     getmaxyx(window, h, w);
  593.     wattron(window, A_BOLD);
  594.     mvwprintw(window, 0,( w - strlen(title)) / 2, "%s", title);
  595. }
  596.  
  597. void drawOrderWindow()
  598. {
  599.     wclear(orderWindow);
  600.     wattrset(orderWindow, A_NORMAL);
  601.     if(curWindow == WIN_ORDER && curMode == MODE_EDIT) wattrset(orderWindow, A_REVERSE);
  602.     box(orderWindow, 0, 0);
  603.     char t[20];
  604.     sprintf(t, "Orders (%i)", song.orderCount);
  605.     printTitle(orderWindow, t);
  606.     wattrset(orderWindow, A_NORMAL);
  607.    
  608.     int i;
  609.     int a;
  610.     for(i = orderScroll; i < song.orderCount && i < h1 - 2 + orderScroll; i++)
  611.     {
  612.         wattrset(orderWindow, curOrder == i ? A_REVERSE : A_NORMAL);
  613.         for(a = 0; a < w1 - 2; a++)
  614.         {
  615.             mvwprintw(orderWindow, i + 1 - orderScroll, a + 1, " ");
  616.         }
  617.         mvwprintw(orderWindow, i + 1 - orderScroll, 1, "%c 0x%x", song.repeat == i ? '*' : '-', i);
  618.     }
  619.    
  620.     wrefresh(orderWindow);
  621.     placeCursor();
  622. }
  623.  
  624. void drawInstrumentWindow()
  625. {
  626.     wclear(instrumentWindow);
  627.     wattrset(instrumentWindow, A_NORMAL);
  628.     if(curWindow == WIN_INSTR && curMode == MODE_EDIT) wattrset(instrumentWindow, A_REVERSE);
  629.     box(instrumentWindow, 0, 0);
  630.     char t[20];
  631.     sprintf(t, "Instruments (%i)", song.instrumentCount);
  632.     printTitle(instrumentWindow, t);
  633.     wattrset(instrumentWindow, A_NORMAL);
  634.    
  635.     int i;
  636.     int a;
  637.     for(i = instrumentScroll; i < song.instrumentCount && i < h1 - 2 + instrumentScroll; i++)
  638.     {
  639.         wattrset(instrumentWindow, curInstrument == i ? A_REVERSE : A_NORMAL);
  640.         for(a = 0; a < w1 - 2; a++)
  641.         {
  642.             mvwprintw(instrumentWindow, i + 1 - instrumentScroll, a + 1, " ");
  643.         }
  644.         mvwprintw(instrumentWindow, i + 1 - instrumentScroll, 1, "0x%x", i);
  645.     }
  646.    
  647.     wrefresh(instrumentWindow);
  648.     placeCursor();
  649. }
  650.  
  651. void drawEffectWindow()
  652. {
  653.     wclear(effectWindow);
  654.     wattrset(effectWindow, A_NORMAL);
  655.     if(curWindow == WIN_EFFECT && curMode == MODE_EDIT) wattrset(effectWindow, A_REVERSE);
  656.     box(effectWindow, 0, 0);
  657.     printTitle(effectWindow, "Effects");
  658.     wattrset(effectWindow, A_NORMAL);
  659.    
  660.     Instrument *instrument = &song.instruments[curInstrument];
  661.    
  662.     int i;
  663.     int a;
  664.     for(i = 0; i < sizeof(instrument->effects) / sizeof(Effect); i++)
  665.     {
  666.         Effect effect = instrument->effects[i];
  667.         wattrset(effectWindow, curEffect == i ? A_REVERSE : A_NORMAL);
  668.         for(a = 0; a < w1 - 2; a++)
  669.         {
  670.             mvwprintw(effectWindow, i + 1, a + 1, " ");
  671.         }
  672.         if(!effect.enable)
  673.         {
  674.             mvwprintw(effectWindow, i + 1, 1, "0x%x: DISABLED", i);
  675.         }
  676.         else
  677.         {
  678.             char eff[20];
  679.             switch(effect.effect)
  680.             {
  681.                 case 0x0:
  682.                     strcpy(eff, "ARPEGGIO:  ");
  683.                     break;
  684.                 case 0x1:
  685.                     strcpy(eff, "PORT UP:   ");
  686.                     break;
  687.                 case 0x2:
  688.                     strcpy(eff, "PORT DOWN: ");
  689.                     break;
  690.                 case 0x3:
  691.                     strcpy(eff, "PORTAMENTO:");
  692.                     break;
  693.                 case 0x4:
  694.                     strcpy(eff, "VIBRATO:   ");
  695.                     break;
  696.                 case 0x5:
  697.                     strcpy(eff, "WAVEFORM:  ");
  698.                     break;
  699.                 case 0x6:
  700.                     strcpy(eff, "DUTY CYCLE:");
  701.                     break;
  702.                 case 0x7:
  703.                     strcpy(eff, "TREMOLO:   ");
  704.                     break;
  705.                 case 0x8:
  706.                     strcpy(eff, "PWM:       ");
  707.                     break;
  708.                 case 0xA:
  709.                     strcpy(eff, "VOL UP:    ");
  710.                     break;
  711.                 case 0xB:
  712.                     strcpy(eff, "VOL DOWN:  ");
  713.                     break;
  714.                 case 0xC:
  715.                     strcpy(eff, "STE VOL:   ");
  716.                     break;
  717.                 case 0xD:
  718.                     strcpy(eff, "ATCK/DECAY:");
  719.                     break;
  720.                 case 0xE:
  721.                     strcpy(eff, "SUS/RELEAS:");
  722.                     break;
  723.                 case 0xF:
  724.                     strcpy(eff, "FINE TUNE: ");
  725.                     break;
  726.             }
  727.             mvwprintw(effectWindow, i + 1, 1, "0x%x: (0x%x) %s 0x%x%x", i, effect.effect, eff, (effect.argument & 0xF0) >> 4, effect.argument & 0xF);
  728.         }
  729.     }
  730.    
  731.     wrefresh(effectWindow);
  732.     placeCursor();
  733. }
  734.  
  735. void drawTrackerWindow()
  736. {
  737.     wclear(trackerWindow);
  738.     wattrset(trackerWindow, A_NORMAL);
  739.     if(curWindow == WIN_TRACKER && curMode == MODE_EDIT) wattrset(trackerWindow, A_REVERSE);
  740.     box(trackerWindow, 0, 0);
  741.     printTitle(trackerWindow, "Tracker");
  742.     wattrset(trackerWindow, A_NORMAL);
  743.     wrefresh(trackerWindow);
  744.     placeCursor();
  745. }
  746.  
  747. void drawWindows()
  748. {
  749.     drawOrderWindow();
  750.     drawInstrumentWindow();
  751.     drawEffectWindow();
  752.     drawTrackerWindow();
  753.     placeCursor();
  754.     refresh();
  755. }
  756.  
  757. void spam(int c, int y)
  758. {
  759.     move(y, 0);
  760.     int i;
  761.     for(i = 0; i < COLS; i++)
  762.     {
  763.         printw("%c", c);
  764.     }
  765. }
  766.  
  767. void drawStatus()
  768. {
  769.     char modeString[32];
  770.     switch(curMode)
  771.     {
  772.         case MODE_EDIT:
  773.             strcpy(modeString, "Edit");
  774.             break;
  775.         case MODE_PLAY:
  776.             strcpy(modeString, "Play");
  777.             break;
  778.         case MODE_JAM:
  779.             strcpy(modeString, "Jam");
  780.             break;
  781.     }
  782.     attrset(A_NORMAL);
  783.     spam(' ', LINES - 1);
  784.     mvprintw(LINES - 1, 0, "MODE: %s | SPEED: %i FPS | REPEAT: 0x%x | ORDERS: %i | INSTRUMENTS: %i", modeString, song.fps, song.repeat, song.orderCount, song.instrumentCount);
  785.     placeCursor();
  786.     refresh();
  787. }
  788.  
  789. void initWindows()
  790. {
  791.     w1 = COLS / 3;
  792.     h1 = 10;
  793.     w2 = w1 * 3;
  794.     h2 = LINES - h1 - 1;
  795.     orderWindow = newwin(h1, w1, 0, 0);
  796.     instrumentWindow = newwin(h1, w1, 0, w1);
  797.     effectWindow = newwin(h1, w1, 0, w1 * 2);
  798.     trackerWindow = newwin(h2, w2, h1, 0);
  799.    
  800.     clear();
  801.     refresh();
  802.     drawWindows();
  803.     drawStatus();
  804.     placeCursor();
  805.     refresh();
  806. }
  807.  
  808. void editInput(int c)
  809. {
  810.     switch(c)
  811.     {
  812.         case '\t':
  813.             curWindow = (curWindow + 1) % 4;
  814.             drawWindows();
  815.             break;
  816.         default:
  817.             switch(curWindow)
  818.             {
  819.                 case WIN_ORDER:
  820.                     switch(c)
  821.                     {
  822.                         case KEY_DOWN:
  823.                             curOrder = (curOrder + 1) % song.orderCount;
  824.                             while(curOrder >= orderScroll + h1 - 2)
  825.                             {
  826.                                 orderScroll++;
  827.                             }
  828.                             while(curOrder < orderScroll)
  829.                             {
  830.                                 orderScroll--;
  831.                             }
  832.                             drawOrderWindow();
  833.                             drawTrackerWindow();
  834.                             break;
  835.                         case KEY_UP:
  836.                             curOrder = (curOrder - 1);
  837.                             while(curOrder < 0) curOrder += song.orderCount;
  838.                             while(curOrder >= orderScroll + h1 - 2)
  839.                             {
  840.                                 orderScroll++;
  841.                             }
  842.                             while(curOrder < orderScroll)
  843.                             {
  844.                                 orderScroll--;
  845.                             }
  846.                             drawOrderWindow();
  847.                             drawTrackerWindow();
  848.                             break;
  849.                         case 'r':
  850.                             song.repeat = curOrder;
  851.                             drawOrderWindow();
  852.                             break;
  853.                         case '=':
  854.                             song.orderCount++;
  855.                             if(song.orderCount > MAX_ORDERS) song.orderCount = MAX_ORDERS;
  856.                             drawOrderWindow();
  857.                             drawStatus();
  858.                             break;
  859.                         case '-':
  860.                             song.orderCount--;
  861.                             if(song.orderCount <= 0) song.orderCount = 1;
  862.                             if(curOrder >= song.orderCount) curOrder = song.orderCount - 1;
  863.                             while(curOrder >= orderScroll + h1 - 2)
  864.                             {
  865.                                 orderScroll++;
  866.                             }
  867.                             while(curOrder < orderScroll)
  868.                             {
  869.                                 orderScroll--;
  870.                             }
  871.                             if(song.repeat >= song.orderCount) song.repeat--;
  872.                             drawOrderWindow();
  873.                             drawStatus();
  874.                             break;
  875.                     }
  876.                     break;
  877.                 case WIN_INSTR:
  878.                     switch(c)
  879.                     {
  880.                         case KEY_DOWN:
  881.                             curInstrument = (curInstrument + 1) % song.instrumentCount;
  882.                             while(curInstrument >= instrumentScroll + h1 - 2)
  883.                             {
  884.                                 instrumentScroll++;
  885.                             }
  886.                             while(curInstrument < instrumentScroll)
  887.                             {
  888.                                 instrumentScroll--;
  889.                             }
  890.                             drawInstrumentWindow();
  891.                             drawEffectWindow();
  892.                             break;
  893.                         case KEY_UP:
  894.                             curInstrument = (curInstrument - 1);
  895.                             while(curInstrument < 0) curInstrument += song.instrumentCount;
  896.                             while(curInstrument >= instrumentScroll + h1 - 2)
  897.                             {
  898.                                 instrumentScroll++;
  899.                             }
  900.                             while(curInstrument < instrumentScroll)
  901.                             {
  902.                                 instrumentScroll--;
  903.                             }
  904.                             drawInstrumentWindow();
  905.                             drawEffectWindow();
  906.                             break;
  907.                         case '=':
  908.                             song.instrumentCount++;
  909.                             if(song.instrumentCount > MAX_INSTRUMENTS) song.instrumentCount = MAX_INSTRUMENTS;
  910.                             drawInstrumentWindow();
  911.                             drawStatus();
  912.                             break;
  913.                         case '-':
  914.                             song.instrumentCount--;
  915.                             if(song.instrumentCount <= 0) song.instrumentCount = 1;
  916.                             if(curInstrument >= song.instrumentCount) curInstrument = song.instrumentCount - 1;
  917.                             while(curInstrument >= instrumentScroll + h1 - 2)
  918.                             {
  919.                                 orderScroll++;
  920.                             }
  921.                             while(curInstrument < instrumentScroll)
  922.                             {
  923.                                 instrumentScroll--;
  924.                             }
  925.                             drawInstrumentWindow();
  926.                             drawStatus();
  927.                             break;
  928.                     }
  929.                     break;
  930.                 case WIN_EFFECT:
  931.                     switch(c)
  932.                     {
  933.                         case KEY_DOWN:
  934.                             curEffect = (curEffect + 1) % 8;
  935.                             drawEffectWindow();
  936.                             break;
  937.                         case KEY_UP:
  938.                             curEffect = (curEffect - 1);
  939.                             while(curEffect < 0) curEffect += 8;
  940.                             drawEffectWindow();
  941.                             break;
  942.                         case KEY_RIGHT:
  943.                             if(song.instruments[curInstrument].effects[curEffect].enable)
  944.                             {
  945.                                 song.instruments[curInstrument].effects[curEffect].effect++;
  946.                                 if(song.instruments[curInstrument].effects[curEffect].effect > 0xF) song.instruments[curInstrument].effects[curEffect].effect = 0xF;
  947.                             }
  948.                             else
  949.                             {
  950.                                 song.instruments[curInstrument].effects[curEffect].enable = 1;
  951.                             }
  952.                             drawEffectWindow();
  953.                             break;
  954.                         case KEY_LEFT:
  955.                             if(song.instruments[curInstrument].effects[curEffect].enable)
  956.                             {
  957.                                 song.instruments[curInstrument].effects[curEffect].effect--;
  958.                                 if(song.instruments[curInstrument].effects[curEffect].effect > 0xF)
  959.                                 {
  960.                                     song.instruments[curInstrument].effects[curEffect].effect = 0;
  961.                                     song.instruments[curInstrument].effects[curEffect].enable = 0;
  962.                                 }
  963.                                 drawEffectWindow();
  964.                             }
  965.                             break;
  966.                         case '=':
  967.                             if(song.instruments[curInstrument].effects[curEffect].enable)
  968.                             {
  969.                                 song.instruments[curInstrument].effects[curEffect].argument++;
  970.                                 drawEffectWindow();
  971.                             }
  972.                             break;
  973.                         case '-':
  974.                             if(song.instruments[curInstrument].effects[curEffect].enable)
  975.                             {
  976.                                 song.instruments[curInstrument].effects[curEffect].argument--;
  977.                                 drawEffectWindow();
  978.                             }
  979.                             break;
  980.                         case ']':
  981.                             if(song.instruments[curInstrument].effects[curEffect].enable)
  982.                             {
  983.                                 song.instruments[curInstrument].effects[curEffect].argument += 0x10;
  984.                                 drawEffectWindow();
  985.                             }
  986.                             break;
  987.                         case '[':
  988.                             if(song.instruments[curInstrument].effects[curEffect].enable)
  989.                             {
  990.                                 song.instruments[curInstrument].effects[curEffect].argument -= 0x10;
  991.                                 drawEffectWindow();
  992.                             }
  993.                             break;
  994.                         }
  995.                     break;
  996.                 case WIN_TRACKER:
  997.                     switch(c)
  998.                     {
  999.                         case KEY_RIGHT:
  1000.                             curX++;
  1001.                             placeCursor();
  1002.                             break;
  1003.                         case KEY_LEFT:
  1004.                             curX--;
  1005.                             placeCursor();
  1006.                             break;
  1007.                         case KEY_DOWN:
  1008.                             curY++;
  1009.                             placeCursor();
  1010.                             break;
  1011.                         case KEY_UP:
  1012.                             curY--;
  1013.                             placeCursor();
  1014.                             break;
  1015.                     }
  1016.                     break;
  1017.             }
  1018.     }
  1019. }
  1020.  
  1021. void playInput(int c)
  1022. {
  1023.    
  1024. }
  1025.  
  1026. void jamInput(int c)
  1027. {
  1028.    
  1029. }
  1030.  
  1031. void editMode()
  1032. {
  1033.     curMode = MODE_EDIT;
  1034.     drawWindows();
  1035.     drawStatus();
  1036. }
  1037.  
  1038. void playMode()
  1039. {
  1040.     curMode = MODE_PLAY;
  1041.     drawWindows();
  1042.     drawStatus();
  1043. }
  1044.  
  1045. void jamMode()
  1046. {
  1047.     curMode = MODE_JAM;
  1048.     drawWindows();
  1049.     drawStatus();
  1050. }
  1051.  
  1052. void inputLoop()
  1053. {
  1054.     while(true)
  1055.     {
  1056.         int c = getch();
  1057.         switch(c)
  1058.         {
  1059.             case KEY_RESIZE:
  1060.                 initWindows();
  1061.                 break;
  1062.             case '\n':
  1063.                 if(curMode == MODE_PLAY)
  1064.                 {
  1065.                     editMode();
  1066.                 }
  1067.                 else
  1068.                 {
  1069.                     playMode();
  1070.                 }
  1071.                 break;
  1072.             case ' ':
  1073.                 if(curMode == MODE_JAM)
  1074.                 {
  1075.                     editMode();
  1076.                 }
  1077.                 else
  1078.                 {
  1079.                     jamMode();
  1080.                 }
  1081.                 break;
  1082.             default:
  1083.                 switch(curMode)
  1084.                 {
  1085.                     case MODE_EDIT:
  1086.                         editInput(c);
  1087.                         break;
  1088.                     case MODE_PLAY:
  1089.                         playInput(c);
  1090.                         break;
  1091.                     case MODE_JAM:
  1092.                         jamInput(c);
  1093.                         break;
  1094.                 }
  1095.         }
  1096.     }
  1097. }
  1098.  
  1099. void gui()
  1100. {
  1101.     initscr();
  1102.     clear();
  1103.     noecho();
  1104.     cbreak();
  1105.     keypad(stdscr, TRUE);
  1106.     refresh();
  1107.    
  1108.     initWindows();
  1109.     inputLoop();
  1110.    
  1111.     endwin();
  1112. }
  1113.  
  1114. void initSong()
  1115. {
  1116.     song.fps = 8;
  1117.     song.repeat = 0;
  1118.     song.orderCount = 1;
  1119.     song.instrumentCount = 1;
  1120.    
  1121.     Order orders[MAX_ORDERS];
  1122.     song.orders = orders;
  1123.    
  1124.     Instrument instruments[MAX_INSTRUMENTS];
  1125.     song.instruments = instruments;
  1126. }
  1127.  
  1128. int main(int argc, char *argv[])
  1129. {
  1130.     if(argc > 1)
  1131.     {
  1132.         strcpy(serialPort, argv[1]);
  1133.     }
  1134.     else
  1135.     {
  1136.         printf("Enter full path to serial device: ");
  1137.         scanf("%s", serialPort);
  1138.     }
  1139.    
  1140.     if(out = fopen(serialPort, "w"))
  1141.     {
  1142.         initSong();
  1143.        
  1144.         gui();
  1145.        
  1146.         fclose(out);
  1147.     }
  1148.     else
  1149.     {
  1150.         printf("Unable to open file!\n");
  1151.         exit(1);
  1152.     }
  1153.    
  1154.     return 0;
  1155. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement