Advertisement
MegaLoler

Sound Chip Tracker

May 6th, 2013
71
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // Backup #2
  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 &= 0b00011110; // weird bug causing the last bit to make the octave go really high
  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.     if(noteCommand->note || noteCommand->octave || noteCommand->volume)
  411.     {
  412.         playNote(noteCommand->note, noteCommand->octave, noteCommand->volume, osc);
  413.         //applyInstrument goes here
  414.     }
  415. }
  416.  
  417. void playEntry(Entry *entry, unsigned char osc)
  418. {
  419.     sendEffectCommand(&entry->effect, osc);
  420.     sendNoteCommand(&entry->noteCommand, osc);
  421. }
  422.  
  423. void playFrame(Frame *frame)
  424. {
  425.     playEntry(&frame->entries[0], 0);
  426.     playEntry(&frame->entries[1], 1);
  427.     playEntry(&frame->entries[2], 2);
  428.     playEntry(&frame->entries[3], 3);
  429. }
  430.  
  431. NoteCommand newNoteCommand(unsigned char note, unsigned char octave, unsigned char volume, unsigned char applyInstrument, unsigned char instrument)
  432. {
  433.     NoteCommand command;
  434.     command.note = note;
  435.     command.octave = octave;
  436.     command.volume = volume;
  437.     command.applyInstrument = applyInstrument;
  438.     command.instrument = instrument;
  439.     return command;
  440. }
  441.  
  442. NoteCommand newSimpleNoteCommand(unsigned char note, unsigned char octave, unsigned char volume)
  443. {
  444.     return newNoteCommand(note, octave, volume, 0, 0);
  445. }
  446.  
  447. NoteCommand newSimplestNoteCommand(unsigned char note, unsigned char octave)
  448. {
  449.     return newSimpleNoteCommand(note, octave, 0);
  450. }
  451.  
  452. NoteCommand newNullNoteCommand()
  453. {
  454.     return newSimplestNoteCommand(NOTE_NULL, 0);
  455. }
  456.  
  457. NoteCommand newResetNoteCommand()
  458. {
  459.     return newSimplestNoteCommand(NOTE_RESET, 0);
  460. }
  461.  
  462. NoteCommand newNoteOnCommand()
  463. {
  464.     return newSimplestNoteCommand(NOTE_ON, 0);
  465. }
  466.  
  467. NoteCommand newNoteOffCommand()
  468. {
  469.     return newSimplestNoteCommand(NOTE_OFF, 0);
  470. }
  471.  
  472. Effect newEffect(unsigned char effect, unsigned char argument)
  473. {
  474.     Effect new_effect;
  475.     new_effect.enable = 1;
  476.     new_effect.effect = effect;
  477.     new_effect.argument = argument;
  478.     return new_effect;
  479. }
  480.  
  481. Effect newNullEffect()
  482. {
  483.     Effect effect;
  484.     effect.enable = 0;
  485.     effect.effect = 0;
  486.     effect.argument = 0;
  487.     return effect;
  488. }
  489.  
  490. Entry newEntry(NoteCommand command, Effect effect)
  491. {
  492.     Entry entry;
  493.     entry.noteCommand = command;
  494.     entry.effect = effect;
  495.     return entry;
  496. }
  497.  
  498. Entry newSimpleEntry(NoteCommand command)
  499. {
  500.     return newEntry(command, newNullEffect());
  501. }
  502.  
  503. Entry newNullEntry()
  504. {
  505.     return newEntry(newNullNoteCommand(), newNullEffect());
  506. }
  507.  
  508. Frame newFrame(Entry entry1, Entry entry2, Entry entry3, Entry entry4)
  509. {
  510.     Frame frame;
  511.     frame.entries[0] = entry1;
  512.     frame.entries[1] = entry2;
  513.     frame.entries[2] = entry3;
  514.     frame.entries[3] = entry4;
  515.     return frame;
  516. }
  517.  
  518. Frame newUnisonFrame(Entry entry)
  519. {
  520.     return newFrame(entry, entry, entry, entry);
  521. }
  522.  
  523. Frame newQuietFrame()
  524. {
  525.     return newUnisonFrame(newSimpleEntry(newNoteOffCommand()));
  526. }
  527.  
  528. Order *newEmptyOrder()
  529. {
  530.     Order *order;
  531.    
  532.     int i;
  533.     for(i = 0; i < sizeof(order->frames) / sizeof(Frame); i++)
  534.     {
  535.         order->frames[i] = newQuietFrame();
  536.     }
  537.    
  538.     return order;
  539. }
  540.  
  541. WINDOW *orderWindow;
  542. WINDOW *instrumentWindow;
  543. WINDOW *effectWindow;
  544. WINDOW *trackerWindow;
  545.  
  546. int w1, w2, h1, h2;
  547.  
  548. #define WIN_ORDER 0
  549. #define WIN_INSTR 1
  550. #define WIN_EFFECT 2
  551. #define WIN_TRACKER 3
  552. int curWindow = WIN_TRACKER;
  553.  
  554. #define MODE_EDIT 0
  555. #define MODE_PLAY 1
  556. #define MODE_JAM 2
  557. int curMode = MODE_EDIT;
  558.  
  559. #define MAX_ORDERS 64
  560. #define MAX_INSTRUMENTS 16
  561.  
  562. Song song;
  563.  
  564. int curOrder = 0;
  565. int curInstrument = 0;
  566. int curEffect = 0;
  567. int orderScroll = 0;
  568. int instrumentScroll = 0;
  569.  
  570. int curOsc = 0;
  571. int curFrame = 0;
  572. int curCol = 0;
  573.  
  574. void placeCursor()
  575. {
  576.     move(LINES - 1, COLS - 1);
  577. }
  578.  
  579. void printTitle(WINDOW *window, char *title)
  580. {
  581.     int h, w;
  582.     getmaxyx(window, h, w);
  583.     wattron(window, A_BOLD);
  584.     mvwprintw(window, 0,( w - strlen(title)) / 2, "%s", title);
  585. }
  586.  
  587. void drawOrderWindow()
  588. {
  589.     wclear(orderWindow);
  590.     wattrset(orderWindow, A_NORMAL);
  591.     if(curWindow == WIN_ORDER && curMode == MODE_EDIT) wattrset(orderWindow, A_REVERSE);
  592.     box(orderWindow, 0, 0);
  593.     char t[20];
  594.     sprintf(t, "Orders (%i)", song.orderCount);
  595.     printTitle(orderWindow, t);
  596.     wattrset(orderWindow, A_NORMAL);
  597.    
  598.     int i;
  599.     int a;
  600.     for(i = orderScroll; i < song.orderCount && i < h1 - 2 + orderScroll; i++)
  601.     {
  602.         wattrset(orderWindow, curOrder == i ? A_REVERSE : A_NORMAL);
  603.         for(a = 0; a < w1 - 2; a++)
  604.         {
  605.             mvwprintw(orderWindow, i + 1 - orderScroll, a + 1, " ");
  606.         }
  607.         mvwprintw(orderWindow, i + 1 - orderScroll, 1, "%c 0x%x: ", song.repeat == i ? '*' : '-', i);
  608.     }
  609.    
  610.     wrefresh(orderWindow);
  611.     placeCursor();
  612. }
  613.  
  614. void drawInstrumentWindow()
  615. {
  616.     wclear(instrumentWindow);
  617.     wattrset(instrumentWindow, A_NORMAL);
  618.     if(curWindow == WIN_INSTR && curMode == MODE_EDIT) wattrset(instrumentWindow, A_REVERSE);
  619.     box(instrumentWindow, 0, 0);
  620.     char t[20];
  621.     sprintf(t, "Instruments (%i)", song.instrumentCount);
  622.     printTitle(instrumentWindow, t);
  623.     wattrset(instrumentWindow, A_NORMAL);
  624.    
  625.     int i;
  626.     int a;
  627.     for(i = instrumentScroll; i < song.instrumentCount && i < h1 - 2 + instrumentScroll; i++)
  628.     {
  629.         wattrset(instrumentWindow, curInstrument == i ? A_REVERSE : A_NORMAL);
  630.         for(a = 0; a < w1 - 2; a++)
  631.         {
  632.             mvwprintw(instrumentWindow, i + 1 - instrumentScroll, a + 1, " ");
  633.         }
  634.         mvwprintw(instrumentWindow, i + 1 - instrumentScroll, 1, "0x%x: ", i);
  635.     }
  636.    
  637.     wrefresh(instrumentWindow);
  638.     placeCursor();
  639. }
  640.  
  641. void drawEffectWindow()
  642. {
  643.     wclear(effectWindow);
  644.     wattrset(effectWindow, A_NORMAL);
  645.     if(curWindow == WIN_EFFECT && curMode == MODE_EDIT) wattrset(effectWindow, A_REVERSE);
  646.     box(effectWindow, 0, 0);
  647.     printTitle(effectWindow, "Effects");
  648.     wattrset(effectWindow, A_NORMAL);
  649.    
  650.     Instrument *instrument = &song.instruments[curInstrument];
  651.    
  652.     int i;
  653.     int a;
  654.     for(i = 0; i < sizeof(instrument->effects) / sizeof(Effect); i++)
  655.     {
  656.         Effect effect = instrument->effects[i];
  657.         wattrset(effectWindow, curEffect == i ? A_REVERSE : A_NORMAL);
  658.         for(a = 0; a < w1 - 2; a++)
  659.         {
  660.             mvwprintw(effectWindow, i + 1, a + 1, " ");
  661.         }
  662.         if(!effect.enable)
  663.         {
  664.             mvwprintw(effectWindow, i + 1, 1, "0x%x: DISABLED", i);
  665.         }
  666.         else
  667.         {
  668.             char eff[20];
  669.             switch(effect.effect)
  670.             {
  671.                 case 0x0:
  672.                     strcpy(eff, "ARPEGGIO:  ");
  673.                     break;
  674.                 case 0x1:
  675.                     strcpy(eff, "PORT UP:   ");
  676.                     break;
  677.                 case 0x2:
  678.                     strcpy(eff, "PORT DOWN: ");
  679.                     break;
  680.                 case 0x3:
  681.                     strcpy(eff, "PORTAMENTO:");
  682.                     break;
  683.                 case 0x4:
  684.                     strcpy(eff, "VIBRATO:   ");
  685.                     break;
  686.                 case 0x5:
  687.                     strcpy(eff, "WAVEFORM:  ");
  688.                     break;
  689.                 case 0x6:
  690.                     strcpy(eff, "DUTY CYCLE:");
  691.                     break;
  692.                 case 0x7:
  693.                     strcpy(eff, "TREMOLO:   ");
  694.                     break;
  695.                 case 0x8:
  696.                     strcpy(eff, "PWM:       ");
  697.                     break;
  698.                 case 0x9:
  699.                     strcpy(eff, "PITCH:     ");
  700.                     break;
  701.                 case 0xA:
  702.                     strcpy(eff, "VOL UP:    ");
  703.                     break;
  704.                 case 0xB:
  705.                     strcpy(eff, "VOL DOWN:  ");
  706.                     break;
  707.                 case 0xC:
  708.                     strcpy(eff, "SET VOL:   ");
  709.                     break;
  710.                 case 0xD:
  711.                     strcpy(eff, "ATCK/DECAY:");
  712.                     break;
  713.                 case 0xE:
  714.                     strcpy(eff, "SUS/RELEAS:");
  715.                     break;
  716.                 case 0xF:
  717.                     strcpy(eff, "FINE TUNE: ");
  718.                     break;
  719.             }
  720.             mvwprintw(effectWindow, i + 1, 1, "0x%x: (0x%x) %s 0x%x%x", i, effect.effect, eff, (effect.argument & 0xF0) >> 4, effect.argument & 0xF);
  721.         }
  722.     }
  723.    
  724.     wrefresh(effectWindow);
  725.     placeCursor();
  726. }
  727.  
  728. void drawTrackerWindow()
  729. {
  730.     wclear(trackerWindow);
  731.     wattrset(trackerWindow, A_NORMAL);
  732.     if(curWindow == WIN_TRACKER && curMode == MODE_EDIT) wattrset(trackerWindow, A_REVERSE);
  733.     wattron(trackerWindow, A_BOLD);
  734.     box(trackerWindow, 0, 0);
  735.     wattroff(trackerWindow, A_BOLD);
  736.     printTitle(trackerWindow, "Tracker");
  737.     wattrset(trackerWindow, A_NORMAL);
  738.    
  739.     int i;
  740.     for(i = -2; i <= 32 && i < h2 - 4; i++)
  741.     {
  742.         wattrset(trackerWindow, A_BOLD);
  743.         if(i >= 0 && i < 32)
  744.         {
  745.             if(curFrame == i) wattron(trackerWindow, A_REVERSE);
  746.             mvwprintw(trackerWindow, i + 3, 1, "0x%x%x ", (i & 0xF0) >> 4, i & 0xF);
  747.         }
  748.         else if(i == -2)
  749.         {
  750.             mvwprintw(trackerWindow, i + 3, 1, "(0x%x)", curOrder);
  751.         }
  752.         else if(i == -1 || i == 32)
  753.         {
  754.             wattrset(trackerWindow, A_NORMAL);
  755.             wmove(trackerWindow, i + 3, 1);
  756.             int a;
  757.             for(a = 0; a < 5; a++)
  758.             {
  759.                 waddch(trackerWindow, ACS_HLINE);
  760.             }
  761.         }
  762.         wattrset(trackerWindow, A_NORMAL);
  763.         waddch(trackerWindow, ACS_VLINE);
  764.        
  765.         int a;
  766.         for(a = 0; a < 4; a++)
  767.         {
  768.             if(i == -2)
  769.             {
  770.                 wattrset(trackerWindow, A_BOLD);
  771.                 if(curOsc == a) wattron(trackerWindow, A_REVERSE);
  772.                 mvwprintw(trackerWindow, i + 3, a * 10 + 7, "Osc #%i   ", a + 1);
  773.                 wattrset(trackerWindow, A_NORMAL);
  774.             }
  775.             else if(i == -1 || i == 32)
  776.             {
  777.                 wmove(trackerWindow, i + 3, a * 10 + 7);
  778.                 int a;
  779.                 for(a = 0; a < 9; a++)
  780.                 {
  781.                     waddch(trackerWindow, ACS_HLINE);
  782.                 }
  783.             }
  784.             else
  785.             {
  786.                 Entry entry = song.orders[curOrder].frames[i].entries[a];
  787.                 wattrset(trackerWindow, curFrame == i && curOsc == a && curCol == 0 ? A_REVERSE : A_NORMAL);
  788.                 switch(entry.noteCommand.note)
  789.                 {
  790.                     case 0x0:
  791.                         mvwprintw(trackerWindow, i + 3, a * 10 + 7, "---");
  792.                         break;
  793.                     case 0x1:
  794.                         mvwprintw(trackerWindow, i + 3, a * 10 + 7, "RES");
  795.                         break;
  796.                     case 0x2:
  797.                         mvwprintw(trackerWindow, i + 3, a * 10 + 7, "+++");
  798.                         break;
  799.                     case 0x3:
  800.                         mvwprintw(trackerWindow, i + 3, a * 10 + 7, "xxx");
  801.                         break;
  802.                     case 0x4:
  803.                         mvwprintw(trackerWindow, i + 3, a * 10 + 7, "C-%x", entry.noteCommand.octave);
  804.                         break;
  805.                     case 0x5:
  806.                         mvwprintw(trackerWindow, i + 3, a * 10 + 7, "C#%x", entry.noteCommand.octave);
  807.                         break;
  808.                     case 0x6:
  809.                         mvwprintw(trackerWindow, i + 3, a * 10 + 7, "D-%x", entry.noteCommand.octave);
  810.                         break;
  811.                     case 0x7:
  812.                         mvwprintw(trackerWindow, i + 3, a * 10 + 7, "D#%x", entry.noteCommand.octave);
  813.                         break;
  814.                     case 0x8:
  815.                         mvwprintw(trackerWindow, i + 3, a * 10 + 7, "E-%x", entry.noteCommand.octave);
  816.                         break;
  817.                     case 0x9:
  818.                         mvwprintw(trackerWindow, i + 3, a * 10 + 7, "F-%x", entry.noteCommand.octave);
  819.                         break;
  820.                     case 0xA:
  821.                         mvwprintw(trackerWindow, i + 3, a * 10 + 7, "F#%x", entry.noteCommand.octave);
  822.                         break;
  823.                     case 0xB:
  824.                         mvwprintw(trackerWindow, i + 3, a * 10 + 7, "G-%x", entry.noteCommand.octave);
  825.                         break;
  826.                     case 0xC:
  827.                         mvwprintw(trackerWindow, i + 3, a * 10 + 7, "G#%x", entry.noteCommand.octave);
  828.                         break;
  829.                     case 0xD:
  830.                         mvwprintw(trackerWindow, i + 3, a * 10 + 7, "A-%x", entry.noteCommand.octave);
  831.                         break;
  832.                     case 0xE:
  833.                         mvwprintw(trackerWindow, i + 3, a * 10 + 7, "A#%x", entry.noteCommand.octave);
  834.                         break;
  835.                     case 0xF:
  836.                         mvwprintw(trackerWindow, i + 3, a * 10 + 7, "B-%x", entry.noteCommand.octave);
  837.                         break;
  838.                 }
  839.                 wattrset(trackerWindow, curFrame == i && curOsc == a && curCol == 1 ? A_REVERSE : A_NORMAL);
  840.                 if(entry.noteCommand.applyInstrument)
  841.                 {
  842.                     wprintw(trackerWindow, "%x", entry.noteCommand.instrument);
  843.                 }
  844.                 else
  845.                 {
  846.                     wprintw(trackerWindow, "-", entry.noteCommand.instrument);
  847.                 }
  848.                 wattrset(trackerWindow, curFrame == i && curOsc == a && curCol == 2 ? A_REVERSE : A_NORMAL);
  849.                 if(entry.noteCommand.volume)
  850.                 {
  851.                     wprintw(trackerWindow, "%x%x", entry.noteCommand.volume >> 4, entry.noteCommand.volume & 0xF);
  852.                 }
  853.                 else
  854.                 {
  855.                     wprintw(trackerWindow, "--");
  856.                 }
  857.                 if(entry.effect.enable)
  858.                 {
  859.                     wattrset(trackerWindow, curFrame == i && curOsc == a && curCol == 3 ? A_REVERSE : A_NORMAL);
  860.                     wprintw(trackerWindow, "%x", entry.effect.effect & 0xF);
  861.                     wattrset(trackerWindow, curFrame == i && curOsc == a && curCol == 4 ? A_REVERSE : A_NORMAL);
  862.                     wprintw(trackerWindow, "%x%x", entry.effect.argument >> 4, entry.effect.argument & 0xF);
  863.                 }
  864.                 else
  865.                 {
  866.                     wattrset(trackerWindow, curFrame == i && curOsc == a && curCol == 3 ? A_REVERSE : A_NORMAL);
  867.                     wprintw(trackerWindow, "-");
  868.                     wattrset(trackerWindow, curFrame == i && curOsc == a && curCol == 4 ? A_REVERSE : A_NORMAL);
  869.                     wprintw(trackerWindow, "--");
  870.                 }
  871.             }
  872.             wattrset(trackerWindow, A_NORMAL);
  873.             waddch(trackerWindow, ACS_VLINE);
  874.         }
  875.     }
  876.    
  877.     wrefresh(trackerWindow);
  878.     placeCursor();
  879. }
  880.  
  881. void playOrder(Order *order, int fps)
  882. {
  883.     int i;
  884.     for(i = 0; i < sizeof(order->frames) / sizeof(Frame); i++)
  885.     {
  886.         curFrame = i;
  887.         drawTrackerWindow();
  888.         placeCursor();
  889.         playFrame(&order->frames[i]);
  890.         usleep(1000000 / fps);
  891.     }
  892. }
  893.  
  894. void drawWindows()
  895. {
  896.     drawOrderWindow();
  897.     drawInstrumentWindow();
  898.     drawEffectWindow();
  899.     drawTrackerWindow();
  900.     placeCursor();
  901.     refresh();
  902. }
  903.  
  904. void spam(int c, int y)
  905. {
  906.     move(y, 0);
  907.     int i;
  908.     for(i = 0; i < COLS; i++)
  909.     {
  910.         printw("%c", c);
  911.     }
  912. }
  913.  
  914. void drawStatus()
  915. {
  916.     char modeString[32];
  917.     switch(curMode)
  918.     {
  919.         case MODE_EDIT:
  920.             strcpy(modeString, "Edit");
  921.             break;
  922.         case MODE_PLAY:
  923.             strcpy(modeString, "Play");
  924.             break;
  925.         case MODE_JAM:
  926.             strcpy(modeString, "Jam");
  927.             break;
  928.     }
  929.     attrset(A_NORMAL);
  930.     spam(' ', LINES - 1);
  931.     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);
  932.     placeCursor();
  933.     refresh();
  934. }
  935.  
  936. void initWindows()
  937. {
  938.     w1 = COLS / 3;
  939.     h1 = 10;
  940.     w2 = w1 * 3;
  941.     h2 = LINES - h1 - 1;
  942.     orderWindow = newwin(h1, w1, 0, 0);
  943.     instrumentWindow = newwin(h1, w1, 0, w1);
  944.     effectWindow = newwin(h1, w1, 0, w1 * 2);
  945.     trackerWindow = newwin(h2, w2, h1, 0);
  946.    
  947.     clear();
  948.     refresh();
  949.     drawWindows();
  950.     drawStatus();
  951.     placeCursor();
  952.     refresh();
  953. }
  954.  
  955. void editInput(int c)
  956. {
  957.     Entry *entry = &song.orders[curOrder].frames[curFrame].entries[curOsc];
  958.     switch(c)
  959.     {
  960.         case '\t':
  961.             curWindow = (curWindow + 1) % 4;
  962.             drawWindows();
  963.             break;
  964.         default:
  965.             switch(curWindow)
  966.             {
  967.                 case WIN_ORDER:
  968.                     switch(c)
  969.                     {
  970.                         case KEY_DOWN:
  971.                             curOrder = (curOrder + 1) % song.orderCount;
  972.                             while(curOrder >= orderScroll + h1 - 2)
  973.                             {
  974.                                 orderScroll++;
  975.                             }
  976.                             while(curOrder < orderScroll)
  977.                             {
  978.                                 orderScroll--;
  979.                             }
  980.                             drawOrderWindow();
  981.                             drawTrackerWindow();
  982.                             break;
  983.                         case KEY_UP:
  984.                             curOrder = (curOrder - 1);
  985.                             while(curOrder < 0) curOrder += song.orderCount;
  986.                             while(curOrder >= orderScroll + h1 - 2)
  987.                             {
  988.                                 orderScroll++;
  989.                             }
  990.                             while(curOrder < orderScroll)
  991.                             {
  992.                                 orderScroll--;
  993.                             }
  994.                             drawOrderWindow();
  995.                             drawTrackerWindow();
  996.                             break;
  997.                         case 'r':
  998.                             song.repeat = curOrder;
  999.                             drawOrderWindow();
  1000.                             break;
  1001.                         case '=':
  1002.                             song.orderCount++;
  1003.                             if(song.orderCount > MAX_ORDERS) song.orderCount = MAX_ORDERS;
  1004.                             drawOrderWindow();
  1005.                             drawStatus();
  1006.                             break;
  1007.                         case '-':
  1008.                             song.orderCount--;
  1009.                             if(song.orderCount <= 0) song.orderCount = 1;
  1010.                             if(curOrder >= song.orderCount) curOrder = song.orderCount - 1;
  1011.                             while(curOrder >= orderScroll + h1 - 2)
  1012.                             {
  1013.                                 orderScroll++;
  1014.                             }
  1015.                             while(curOrder < orderScroll)
  1016.                             {
  1017.                                 orderScroll--;
  1018.                             }
  1019.                             if(song.repeat >= song.orderCount) song.repeat--;
  1020.                             drawOrderWindow();
  1021.                             drawStatus();
  1022.                             break;
  1023.                     }
  1024.                     break;
  1025.                 case WIN_INSTR:
  1026.                     switch(c)
  1027.                     {
  1028.                         case KEY_DOWN:
  1029.                             curInstrument = (curInstrument + 1) % song.instrumentCount;
  1030.                             while(curInstrument >= instrumentScroll + h1 - 2)
  1031.                             {
  1032.                                 instrumentScroll++;
  1033.                             }
  1034.                             while(curInstrument < instrumentScroll)
  1035.                             {
  1036.                                 instrumentScroll--;
  1037.                             }
  1038.                             drawInstrumentWindow();
  1039.                             drawEffectWindow();
  1040.                             break;
  1041.                         case KEY_UP:
  1042.                             curInstrument = (curInstrument - 1);
  1043.                             while(curInstrument < 0) curInstrument += song.instrumentCount;
  1044.                             while(curInstrument >= instrumentScroll + h1 - 2)
  1045.                             {
  1046.                                 instrumentScroll++;
  1047.                             }
  1048.                             while(curInstrument < instrumentScroll)
  1049.                             {
  1050.                                 instrumentScroll--;
  1051.                             }
  1052.                             drawInstrumentWindow();
  1053.                             drawEffectWindow();
  1054.                             break;
  1055.                         case '=':
  1056.                             song.instrumentCount++;
  1057.                             if(song.instrumentCount > MAX_INSTRUMENTS) song.instrumentCount = MAX_INSTRUMENTS;
  1058.                             drawInstrumentWindow();
  1059.                             drawStatus();
  1060.                             break;
  1061.                         case '-':
  1062.                             song.instrumentCount--;
  1063.                             if(song.instrumentCount <= 0) song.instrumentCount = 1;
  1064.                             if(curInstrument >= song.instrumentCount) curInstrument = song.instrumentCount - 1;
  1065.                             while(curInstrument >= instrumentScroll + h1 - 2)
  1066.                             {
  1067.                                 orderScroll++;
  1068.                             }
  1069.                             while(curInstrument < instrumentScroll)
  1070.                             {
  1071.                                 instrumentScroll--;
  1072.                             }
  1073.                             drawInstrumentWindow();
  1074.                             drawStatus();
  1075.                             break;
  1076.                     }
  1077.                     break;
  1078.                 case WIN_EFFECT:
  1079.                     switch(c)
  1080.                     {
  1081.                         case KEY_DOWN:
  1082.                             curEffect = (curEffect + 1) % 8;
  1083.                             drawEffectWindow();
  1084.                             break;
  1085.                         case KEY_UP:
  1086.                             curEffect = (curEffect - 1);
  1087.                             while(curEffect < 0) curEffect += 8;
  1088.                             drawEffectWindow();
  1089.                             break;
  1090.                         case KEY_RIGHT:
  1091.                             if(song.instruments[curInstrument].effects[curEffect].enable)
  1092.                             {
  1093.                                 song.instruments[curInstrument].effects[curEffect].effect++;
  1094.                                 if(song.instruments[curInstrument].effects[curEffect].effect > 0xF) song.instruments[curInstrument].effects[curEffect].effect = 0xF;
  1095.                             }
  1096.                             else
  1097.                             {
  1098.                                 song.instruments[curInstrument].effects[curEffect].enable = 1;
  1099.                             }
  1100.                             drawEffectWindow();
  1101.                             break;
  1102.                         case KEY_LEFT:
  1103.                             if(song.instruments[curInstrument].effects[curEffect].enable)
  1104.                             {
  1105.                                 song.instruments[curInstrument].effects[curEffect].effect--;
  1106.                                 if(song.instruments[curInstrument].effects[curEffect].effect > 0xF)
  1107.                                 {
  1108.                                     song.instruments[curInstrument].effects[curEffect].effect = 0;
  1109.                                     song.instruments[curInstrument].effects[curEffect].enable = 0;
  1110.                                 }
  1111.                                 drawEffectWindow();
  1112.                             }
  1113.                             break;
  1114.                         case '=':
  1115.                             if(song.instruments[curInstrument].effects[curEffect].enable)
  1116.                             {
  1117.                                 song.instruments[curInstrument].effects[curEffect].argument++;
  1118.                                 drawEffectWindow();
  1119.                             }
  1120.                             break;
  1121.                         case '-':
  1122.                             if(song.instruments[curInstrument].effects[curEffect].enable)
  1123.                             {
  1124.                                 song.instruments[curInstrument].effects[curEffect].argument--;
  1125.                                 drawEffectWindow();
  1126.                             }
  1127.                             break;
  1128.                         case ']':
  1129.                             if(song.instruments[curInstrument].effects[curEffect].enable)
  1130.                             {
  1131.                                 song.instruments[curInstrument].effects[curEffect].argument += 0x10;
  1132.                                 drawEffectWindow();
  1133.                             }
  1134.                             break;
  1135.                         case '[':
  1136.                             if(song.instruments[curInstrument].effects[curEffect].enable)
  1137.                             {
  1138.                                 song.instruments[curInstrument].effects[curEffect].argument -= 0x10;
  1139.                                 drawEffectWindow();
  1140.                             }
  1141.                             break;
  1142.                         }
  1143.                     break;
  1144.                 case WIN_TRACKER:
  1145.                     switch(c)
  1146.                     {
  1147.                         case KEY_F(1):
  1148.                             curOsc = 0;
  1149.                             drawTrackerWindow();
  1150.                             break;
  1151.                         case KEY_F(2):
  1152.                             curOsc = 1;
  1153.                             drawTrackerWindow();
  1154.                             break;
  1155.                         case KEY_F(3):
  1156.                             curOsc = 2;
  1157.                             drawTrackerWindow();
  1158.                             break;
  1159.                         case KEY_F(4):
  1160.                             curOsc = 3;
  1161.                             drawTrackerWindow();
  1162.                             break;
  1163.                         case KEY_RIGHT:
  1164.                             curCol++;
  1165.                             if(curCol > 4)
  1166.                             {
  1167.                                 curCol = 0;
  1168.                                 curOsc = (curOsc + 1) % 4;
  1169.                             }
  1170.                             drawTrackerWindow();
  1171.                             break;
  1172.                         case KEY_LEFT:
  1173.                             curCol--;
  1174.                             if(curCol < 0)
  1175.                             {
  1176.                                 curCol = 4;
  1177.                                 curOsc--;
  1178.                                 if(curOsc < 0) curOsc = 3;
  1179.                             }
  1180.                             drawTrackerWindow();
  1181.                             break;
  1182.                         case KEY_DOWN:
  1183.                             curFrame = (curFrame + 1) % 32;
  1184.                             drawTrackerWindow();
  1185.                             break;
  1186.                         case KEY_UP:
  1187.                             curFrame--;
  1188.                             if(curFrame < 0) curFrame = 31;
  1189.                             drawTrackerWindow();
  1190.                             break;
  1191.                         case 'p':
  1192.                             playEntry(entry, curOsc);
  1193.                             break;
  1194.                         default:
  1195.                             switch(curCol)
  1196.                             {
  1197.                                 case 0:
  1198.                                     switch(c)
  1199.                                     {
  1200.                                         case KEY_BACKSPACE:
  1201.                                             entry->noteCommand.note = NOTE_NULL;
  1202.                                             break;
  1203.                                         case '`':
  1204.                                             if(entry->noteCommand.note == NOTE_OFF)
  1205.                                             {
  1206.                                                 entry->noteCommand.note = NOTE_ON;
  1207.                                             }
  1208.                                             else
  1209.                                             {
  1210.                                                 entry->noteCommand.note = NOTE_OFF;
  1211.                                             }
  1212.                                             break;
  1213.                                         case '0':
  1214.                                             entry->noteCommand.octave = 0;
  1215.                                             break;
  1216.                                         case '1':
  1217.                                             entry->noteCommand.octave = 1;
  1218.                                             break;
  1219.                                         case '2':
  1220.                                             entry->noteCommand.octave = 2;
  1221.                                             break;
  1222.                                         case '3':
  1223.                                             entry->noteCommand.octave = 3;
  1224.                                             break;
  1225.                                         case '4':
  1226.                                             entry->noteCommand.octave = 4;
  1227.                                             break;
  1228.                                         case '5':
  1229.                                             entry->noteCommand.octave = 5;
  1230.                                             break;
  1231.                                         case '6':
  1232.                                             entry->noteCommand.octave = 6;
  1233.                                             break;
  1234.                                         case '7':
  1235.                                             entry->noteCommand.octave = 7;
  1236.                                             break;
  1237.                                         case 'a':
  1238.                                             entry->noteCommand.note = NOTE_C;
  1239.                                             break;
  1240.                                         case 'w':
  1241.                                             entry->noteCommand.note = NOTE_Cs;
  1242.                                             break;
  1243.                                         case 's':
  1244.                                             entry->noteCommand.note = NOTE_D;
  1245.                                             break;
  1246.                                         case 'e':
  1247.                                             entry->noteCommand.note = NOTE_Ds;
  1248.                                             break;
  1249.                                         case 'd':
  1250.                                             entry->noteCommand.note = NOTE_E;
  1251.                                             break;
  1252.                                         case 'f':
  1253.                                             entry->noteCommand.note = NOTE_F;
  1254.                                             break;
  1255.                                         case 't':
  1256.                                             entry->noteCommand.note = NOTE_Fs;
  1257.                                             break;
  1258.                                         case 'g':
  1259.                                             entry->noteCommand.note = NOTE_G;
  1260.                                             break;
  1261.                                         case 'y':
  1262.                                             entry->noteCommand.note = NOTE_Gs;
  1263.                                             break;
  1264.                                         case 'h':
  1265.                                             entry->noteCommand.note = NOTE_A;
  1266.                                             break;
  1267.                                         case 'u':
  1268.                                             entry->noteCommand.note = NOTE_As;
  1269.                                             break;
  1270.                                         case 'j':
  1271.                                             entry->noteCommand.note = NOTE_B;
  1272.                                             break;
  1273.                                         case 'k':
  1274.                                             entry->noteCommand.note = NOTE_C;
  1275.                                             break;
  1276.                                         case 'r':
  1277.                                             entry->noteCommand.note = NOTE_RESET;
  1278.                                             break;
  1279.                                         case '=':
  1280.                                             if(entry->noteCommand.note == NOTE_B)
  1281.                                             {
  1282.                                                 entry->noteCommand.note = NOTE_C;
  1283.                                                 entry->noteCommand.octave = (entry->noteCommand.octave + 1) % 8;
  1284.                                             }
  1285.                                             else if(entry->noteCommand.note > 3)
  1286.                                             {
  1287.                                                 entry->noteCommand.note++;
  1288.                                             }
  1289.                                             break;
  1290.                                         case '-':
  1291.                                             if(entry->noteCommand.note == 4)
  1292.                                             {
  1293.                                                 entry->noteCommand.note = 15;
  1294.                                                 if(entry->noteCommand.octave == 0)
  1295.                                                 {
  1296.                                                     entry->noteCommand.octave = 7;
  1297.                                                 }
  1298.                                                 else
  1299.                                                 {
  1300.                                                     entry->noteCommand.octave--;
  1301.                                                 }
  1302.                                             }
  1303.                                             else if(entry->noteCommand.note > 4)
  1304.                                             {
  1305.                                                 entry->noteCommand.note--;
  1306.                                             }
  1307.                                             break;
  1308.                                         case ']':
  1309.                                             entry->noteCommand.octave = (entry->noteCommand.octave + 1) % 8;
  1310.                                             break;
  1311.                                         case '[':
  1312.                                             if(entry->noteCommand.octave == 0)
  1313.                                             {
  1314.                                                 entry->noteCommand.octave = 7;
  1315.                                             }
  1316.                                             else
  1317.                                             {
  1318.                                                 entry->noteCommand.octave--;
  1319.                                             }
  1320.                                             break;
  1321.                                     }
  1322.                                     break;
  1323.                                 case 1:
  1324.                                     switch(c)
  1325.                                     {
  1326.                                         case KEY_BACKSPACE:
  1327.                                             entry->noteCommand.applyInstrument = 0;
  1328.                                             break;
  1329.                                         case '0':
  1330.                                             entry->noteCommand.instrument = 0;
  1331.                                             entry->noteCommand.applyInstrument = 1;
  1332.                                             break;
  1333.                                         case '1':
  1334.                                             entry->noteCommand.instrument = 1;
  1335.                                             entry->noteCommand.applyInstrument = 1;
  1336.                                             break;
  1337.                                         case '2':
  1338.                                             entry->noteCommand.instrument = 2;
  1339.                                             entry->noteCommand.applyInstrument = 1;
  1340.                                             break;
  1341.                                         case '3':
  1342.                                             entry->noteCommand.instrument = 3;
  1343.                                             entry->noteCommand.applyInstrument = 1;
  1344.                                             break;
  1345.                                         case '4':
  1346.                                             entry->noteCommand.instrument = 4;
  1347.                                             entry->noteCommand.applyInstrument = 1;
  1348.                                             break;
  1349.                                         case '5':
  1350.                                             entry->noteCommand.instrument = 5;
  1351.                                             entry->noteCommand.applyInstrument = 1;
  1352.                                             break;
  1353.                                         case '6':
  1354.                                             entry->noteCommand.instrument = 6;
  1355.                                             entry->noteCommand.applyInstrument = 1;
  1356.                                             break;
  1357.                                         case '7':
  1358.                                             entry->noteCommand.instrument = 7;
  1359.                                             entry->noteCommand.applyInstrument = 1;
  1360.                                             break;
  1361.                                         case '=':
  1362.                                             entry->noteCommand.instrument = (entry->noteCommand.instrument + 1) % 8;
  1363.                                             break;
  1364.                                         case '-':
  1365.                                             if(entry->noteCommand.instrument == 0)
  1366.                                             {
  1367.                                                 entry->noteCommand.instrument = 7;
  1368.                                             }
  1369.                                             else
  1370.                                             {
  1371.                                                 entry->noteCommand.instrument--;
  1372.                                             }
  1373.                                             break;
  1374.                                     }
  1375.                                     break;
  1376.                                 case 2:
  1377.                                     switch(c)
  1378.                                     {
  1379.                                         case KEY_BACKSPACE:
  1380.                                             entry->noteCommand.volume = 0;
  1381.                                             break;
  1382.                                         case '0':
  1383.                                             entry->noteCommand.volume = 0;
  1384.                                             break;
  1385.                                         case '`':
  1386.                                             entry->noteCommand.volume = 31;
  1387.                                             break;
  1388.                                         case '=':
  1389.                                             entry->noteCommand.volume = (entry->noteCommand.volume + 1) % 32;
  1390.                                             break;
  1391.                                         case '-':
  1392.                                             if(entry->noteCommand.volume == 0)
  1393.                                             {
  1394.                                                 entry->noteCommand.volume = 31;
  1395.                                             }
  1396.                                             else
  1397.                                             {
  1398.                                                 entry->noteCommand.volume--;
  1399.                                             }
  1400.                                             break;
  1401.                                         case ']':
  1402.                                             entry->noteCommand.volume = (entry->noteCommand.volume + 0x10) % 32;
  1403.                                             break;
  1404.                                         case '[':
  1405.                                             if(entry->noteCommand.volume <= 0x10)
  1406.                                             {
  1407.                                                 entry->noteCommand.volume = 31;
  1408.                                             }
  1409.                                             else
  1410.                                             {
  1411.                                                 entry->noteCommand.volume -= 0x10;
  1412.                                             }
  1413.                                             break;
  1414.                                     }
  1415.                                     break;
  1416.                                 case 3:
  1417.                                     switch(c)
  1418.                                     {
  1419.                                         case KEY_BACKSPACE:
  1420.                                             entry->effect.enable = 0;
  1421.                                             break;
  1422.                                         case '0':
  1423.                                             entry->effect.effect = 0;
  1424.                                             entry->effect.enable = 1;
  1425.                                             break;
  1426.                                         case '1':
  1427.                                             entry->effect.effect = 1;
  1428.                                             entry->effect.enable = 1;
  1429.                                             break;
  1430.                                         case '2':
  1431.                                             entry->effect.effect = 2;
  1432.                                             entry->effect.enable = 1;
  1433.                                             break;
  1434.                                         case '3':
  1435.                                             entry->effect.effect = 3;
  1436.                                             entry->effect.enable = 1;
  1437.                                             break;
  1438.                                         case '4':
  1439.                                             entry->effect.effect = 4;
  1440.                                             entry->effect.enable = 1;
  1441.                                             break;
  1442.                                         case '5':
  1443.                                             entry->effect.effect = 5;
  1444.                                             entry->effect.enable = 1;
  1445.                                             break;
  1446.                                         case '6':
  1447.                                             entry->effect.effect = 6;
  1448.                                             entry->effect.enable = 1;
  1449.                                             break;
  1450.                                         case '7':
  1451.                                             entry->effect.effect = 7;
  1452.                                             entry->effect.enable = 1;
  1453.                                             break;
  1454.                                         case '8':
  1455.                                             entry->effect.effect = 8;
  1456.                                             entry->effect.enable = 1;
  1457.                                             break;
  1458.                                         case '9':
  1459.                                             entry->effect.effect = 9;
  1460.                                             entry->effect.enable = 1;
  1461.                                             break;
  1462.                                         case 'a':
  1463.                                             entry->effect.effect = 0xA;
  1464.                                             entry->effect.enable = 1;
  1465.                                             break;
  1466.                                         case 'b':
  1467.                                             entry->effect.effect = 0xB;
  1468.                                             entry->effect.enable = 1;
  1469.                                             break;
  1470.                                         case 'c':
  1471.                                             entry->effect.effect = 0xC;
  1472.                                             entry->effect.enable = 1;
  1473.                                             break;
  1474.                                         case 'd':
  1475.                                             entry->effect.effect = 0xD;
  1476.                                             entry->effect.enable = 1;
  1477.                                             break;
  1478.                                         case 'e':
  1479.                                             entry->effect.effect = 0xE;
  1480.                                             entry->effect.enable = 1;
  1481.                                             break;
  1482.                                         case 'f':
  1483.                                             entry->effect.effect = 0xF;
  1484.                                             entry->effect.enable = 1;
  1485.                                             break;
  1486.                                         case '=':
  1487.                                             entry->effect.effect = (entry->effect.effect + 1) % 0x10;
  1488.                                             entry->effect.enable = 1;
  1489.                                             break;
  1490.                                         case '-':
  1491.                                             if(entry->effect.effect == 0)
  1492.                                             {
  1493.                                                 entry->effect.effect = 0xF;
  1494.                                             }
  1495.                                             else
  1496.                                             {
  1497.                                                 entry->effect.effect--;
  1498.                                             }
  1499.                                             entry->effect.enable = 1;
  1500.                                             break;
  1501.                                     }
  1502.                                     break;
  1503.                                 case 4:
  1504.                                     switch(c)
  1505.                                     {
  1506.                                         case KEY_BACKSPACE:
  1507.                                             entry->effect.enable = 0;
  1508.                                             break;
  1509.                                         case '0':
  1510.                                             entry->effect.argument = 0;
  1511.                                             entry->effect.enable = 1;
  1512.                                             break;
  1513.                                         case '=':
  1514.                                             entry->effect.argument++;
  1515.                                             entry->effect.enable = 1;
  1516.                                             break;
  1517.                                         case '-':
  1518.                                             entry->effect.argument--;
  1519.                                             entry->effect.enable = 1;
  1520.                                             break;
  1521.                                         case ']':
  1522.                                             entry->effect.argument += 0x10;
  1523.                                             entry->effect.enable = 1;
  1524.                                             break;
  1525.                                         case '[':
  1526.                                             entry->effect.argument -= 0x10;
  1527.                                             entry->effect.enable = 1;
  1528.                                             break;
  1529.                                     }
  1530.                                     break;
  1531.                             }
  1532.                             drawTrackerWindow();
  1533.                     }
  1534.                     break;
  1535.             }
  1536.     }
  1537. }
  1538.  
  1539. void playInput(int c)
  1540. {
  1541.    
  1542. }
  1543.  
  1544. void jamInput(int c)
  1545. {
  1546.    
  1547. }
  1548.  
  1549. void editMode()
  1550. {
  1551.     curMode = MODE_EDIT;
  1552.     drawWindows();
  1553.     drawStatus();
  1554. }
  1555.  
  1556. void playMode()
  1557. {
  1558.     curMode = MODE_PLAY;
  1559.     drawWindows();
  1560.     drawStatus();
  1561. }
  1562.  
  1563. void jamMode()
  1564. {
  1565.     curMode = MODE_JAM;
  1566.     drawWindows();
  1567.     drawStatus();
  1568. }
  1569.  
  1570. void broadcastEffect(Effect effect)
  1571. {
  1572.     sendEffectCommand(&effect, 0);
  1573.     sendEffectCommand(&effect, 1);
  1574.     sendEffectCommand(&effect, 2);
  1575.     sendEffectCommand(&effect, 3);
  1576. }
  1577.  
  1578. void resetEffects()
  1579. {
  1580.     broadcastEffect(newEffect(0x0, 0x00));
  1581.     broadcastEffect(newEffect(0x1, 0x00));
  1582.     broadcastEffect(newEffect(0x2, 0x00));
  1583.     broadcastEffect(newEffect(0x3, 0x00));
  1584.     broadcastEffect(newEffect(0x4, 0x00));
  1585.     broadcastEffect(newEffect(0x5, 0x00));
  1586.     broadcastEffect(newEffect(0x6, 0x7F));
  1587.     broadcastEffect(newEffect(0x7, 0x00));
  1588.     broadcastEffect(newEffect(0x8, 0x00));
  1589.     broadcastEffect(newEffect(0x9, 0x00));
  1590.     broadcastEffect(newEffect(0xA, 0x00));
  1591.     broadcastEffect(newEffect(0xB, 0x00));
  1592.     broadcastEffect(newEffect(0xC, 0xFF));
  1593.     broadcastEffect(newEffect(0xD, 0x00));
  1594.     broadcastEffect(newEffect(0xE, 0xF0));
  1595.     broadcastEffect(newEffect(0xF, 0x00));
  1596. }
  1597.  
  1598. Frame quietFrame;
  1599.  
  1600. void reset()
  1601. {
  1602.     playFrame(&quietFrame);
  1603.     resetEffects();
  1604. }
  1605.  
  1606. void playCurrentFrame()
  1607. {
  1608.     Frame f = song.orders[curOrder].frames[curFrame];
  1609.     playFrame(&f);
  1610. }
  1611.  
  1612. void playCurrentOrder()
  1613. {
  1614.     Order o = song.orders[curOrder];
  1615.     playOrder(&o, song.fps);
  1616. }
  1617.  
  1618. void inputLoop()
  1619. {
  1620.     quietFrame = newQuietFrame();
  1621.     int e = 1;
  1622.     while(e)
  1623.     {
  1624.         int c = getch();
  1625.         switch(c)
  1626.         {
  1627.             case KEY_F(5):
  1628.                 reset();
  1629.                 break;
  1630.             case KEY_F(6):
  1631.                 playNote(NOTE_C, 3, 0xFF, 0);
  1632.                 playNote(NOTE_E, 4, 0xFF, 1);
  1633.                 playNote(NOTE_G, 3, 0xFF, 2);
  1634.                 playNote(NOTE_Bb, 4, 0xFF, 3);
  1635.                 break;
  1636.             case KEY_F(7):
  1637.                 playCurrentFrame();
  1638.                 break;
  1639.             case KEY_F(8):
  1640.                 playCurrentOrder();
  1641.                 break;
  1642.             case 'q':
  1643.                 e = 0;
  1644.                 break;
  1645.             case KEY_RESIZE:
  1646.                 initWindows();
  1647.                 break;
  1648.             case '\n':
  1649.                 if(curMode == MODE_PLAY)
  1650.                 {
  1651.                     editMode();
  1652.                 }
  1653.                 else
  1654.                 {
  1655.                     playMode();
  1656.                 }
  1657.                 break;
  1658.             case ' ':
  1659.                 if(curMode == MODE_JAM)
  1660.                 {
  1661.                     editMode();
  1662.                 }
  1663.                 else
  1664.                 {
  1665.                     jamMode();
  1666.                 }
  1667.                 break;
  1668.             default:
  1669.                 switch(curMode)
  1670.                 {
  1671.                     case MODE_EDIT:
  1672.                         editInput(c);
  1673.                         break;
  1674.                     case MODE_PLAY:
  1675.                         playInput(c);
  1676.                         break;
  1677.                     case MODE_JAM:
  1678.                         jamInput(c);
  1679.                         break;
  1680.                 }
  1681.         }
  1682.     }
  1683. }
  1684.  
  1685. void gui()
  1686. {
  1687.     initscr();
  1688.     clear();
  1689.     noecho();
  1690.     cbreak();
  1691.     keypad(stdscr, TRUE);
  1692.     nodelay(stdscr, TRUE);
  1693.     refresh();
  1694.    
  1695.     initWindows();
  1696.     inputLoop();
  1697.    
  1698.     endwin();
  1699. }
  1700.  
  1701. void initSong()
  1702. {
  1703.     song.fps = 8;
  1704.     song.repeat = 0;
  1705.     song.orderCount = 1;
  1706.     song.instrumentCount = 1;
  1707.    
  1708.     Order orders[MAX_ORDERS];
  1709.     song.orders = orders;
  1710.    
  1711.     Instrument instruments[MAX_INSTRUMENTS];
  1712.     song.instruments = instruments;
  1713. }
  1714.  
  1715. int main(int argc, char *argv[])
  1716. {
  1717.     if(argc > 1)
  1718.     {
  1719.         strcpy(serialPort, argv[1]);
  1720.     }
  1721.     else
  1722.     {
  1723.         printf("Enter full path to serial device: ");
  1724.         scanf("%s", serialPort);
  1725.     }
  1726.    
  1727.     if(out = fopen(serialPort, "w"))
  1728.     {
  1729.         initSong();
  1730.         reset();
  1731.         gui();
  1732.         reset();
  1733.         fclose(out);
  1734.     }
  1735.     else
  1736.     {
  1737.         printf("Unable to open file!\n");
  1738.         exit(1);
  1739.     }
  1740.    
  1741.     return 0;
  1742. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement