home *** CD-ROM | disk | FTP | other *** search
/ Large Pack of OldSkool DOS MOD Trackers / far094.zip / FARTRAK.CPP < prev    next >
C/C++ Source or Header  |  1994-02-18  |  14KB  |  459 lines

  1. #include "Far.HPP"
  2. #include "math.h"
  3.  
  4. word OverFlow=0,OCount=0,PlayTempo=CurTempo,PlayOrder=CurOrder;
  5. int  TempoBend=0;
  6. int  mTempo[16];
  7. long PitchWheel[16]={0},DestPitch[16]={0},Increment[16]={0},PresPitch[16]={0};
  8. int  VolWheel[16]={0},DestVol[16]={0},VIncrement[16]={0},PresVol[16]={0};
  9. long RetLeft[16]={0},RetSpc[16]={0},CurSpc[16]={0},RetSmp[16]={0},RetVol[16]={0xF};
  10. int  VibOn[16]={0};
  11. int  VibPtr[16]={0},VibInc[16]={0};
  12. int  CurFreqs[16]={0};
  13. int  CurVols[16]={15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15};
  14. int  SinTable[16][128]={0};
  15. int  VibAmp=4;
  16.  
  17. void UdTempo() {
  18.   UpdateTempo(mTempo[PlayTempo]);
  19.   return;
  20. }
  21.  
  22. void CalcTempo() {
  23.   word q;
  24.   double t,f=1,y,amp;
  25.  
  26.   mTempo[0]=256;
  27.   for (q=1;q<16;q++) mTempo[q]=128/q;
  28.  
  29.   for (amp=0;amp<16;amp++)
  30.     for (t=0;t<1;t+=(1.0/128)) {
  31.       y=sin(2*3.1415*f*t)*amp;
  32.       SinTable[amp][t*128]=y;
  33.     }
  34. }
  35.  
  36. extern "C" void IRQHook() {
  37.   pokeb(TSeg,132*2,peekb(TSeg,132*2)^128);
  38. }
  39.  
  40. byte Bars[16]={0};
  41. extern Flag BarsOff;
  42.  
  43. void UpdateBars();
  44. void KillBars() {
  45.   memset(Bars,0,16);
  46.   if (!BarsOff) {
  47.     DrawF(94,5,0xe,0xf,"ÇÇääêêîîÉÉööÿÿ££ááññ¿¿¼¼░░┤┤╕╕╝╝");
  48.     DrawF(94,6,0xd,0xc,"üüààëëììææòòÖÖ¥¥ííÑÑ⌐⌐¡¡▒▒╡╡╣╣╜╜");
  49.     DrawF(94,7,0xd,0xc,"ééååèèÄÄÆÆûûÜÜ₧₧ó󪪬¬««▓▓╢╢║║╛╛");
  50.     DrawF(94,8,0xd,0xc,"ââççïïÅÅôôùù¢¢ƒƒúúºº½½»»││╖╖╗╗┐┐");
  51.  
  52.     DrawF(94,4,0xb,0x9," 0 1 2 3 4 5 6 7 8 9 A B C D E F");
  53.     UpdateBars();
  54.   }
  55. }
  56.  
  57. void ASMUpd(word,word);
  58. void UpdateBars() {
  59.   if (!BarsOff) ASMUpd(FP_SEG(Bars),FP_OFF(Bars));
  60. }
  61.  
  62. word fsize;
  63. word fs;
  64.  
  65. void UpdateTops();
  66. extern Flag Locked,UDBars=FALSE,IsStolen;
  67. void interrupt (*OldInt8)(...);
  68. void interrupt Int8(...) {
  69.   word c,ov,m,q;
  70.   long fp,sp,t,ch;
  71.   byte fekt;
  72.  
  73.  
  74. //  outportb(0x20,0x20);
  75. /*  if (Locked)
  76.     asm {
  77.       Cli;
  78.       Hlt;
  79.     } */
  80.  
  81.   for (ch=0;ch<16;ch++) {
  82.     if (VibOn[ch]) {
  83.       VibPtr[ch]+=VibInc[ch];              // Update vibrato table cntr
  84.       if (VibPtr[ch]>=128)                 // Reset counter
  85.         VibPtr[ch]=0;
  86.       if (!Increment[ch])                  // Note port doing it for us?
  87.         Music.SetFreq(ch,CurFreqs[ch]+PitchWheel[ch]+SinTable[VibAmp][VibPtr[ch]]);
  88.     }
  89.     if (Increment[ch]) {                   // Deal with note port
  90.       t=(CurFreqs[ch]+PitchWheel[ch]);
  91.       if (Increment[ch]<0) {
  92.         if (t<=DestPitch[ch]) {
  93.           Increment[ch]=0;
  94.           PresPitch[ch]=0;
  95.           CurFreqs[ch]=DestPitch[ch];
  96.           DestPitch[ch]=0;
  97.         }
  98.         else
  99.           PresPitch[ch]+=Increment[ch];
  100.       }
  101.       else {
  102.         if (t>=DestPitch[ch]) {
  103.           Increment[ch]=0;
  104.           PresPitch[ch]=0;
  105.           CurFreqs[ch]=DestPitch[ch];
  106.           DestPitch[ch]=0;
  107.         }
  108.         else
  109.           PresPitch[ch]+=Increment[ch];
  110.       }
  111.     }
  112.     PitchWheel[ch]=PresPitch[ch]/256;
  113.     Music.SetFreq(ch,CurFreqs[ch]+PitchWheel[ch]+SinTable[VibAmp][VibPtr[ch]]);
  114.  
  115.     if (VIncrement[ch]) {                   // Deal with vol port
  116.       t=(CurVols[ch]*4)+VolWheel[ch];
  117.       if (VIncrement[ch]<0) {
  118.         if (t<=DestVol[ch]) {
  119.           VIncrement[ch]=0;
  120.           PresVol[ch]=0;
  121.           CurVols[ch]=DestVol[ch]/4;
  122.           DestVol[ch]=0;
  123.         }
  124.         else
  125.           PresVol[ch]+=VIncrement[ch];
  126.       }
  127.       else {
  128.         if (t>=DestVol[ch]) {
  129.           VIncrement[ch]=0;
  130.           PresVol[ch]=0;
  131.           CurVols[ch]=DestVol[ch]/4;
  132.           DestPitch[ch]=0;
  133.         }
  134.         else
  135.           PresVol[ch]+=VIncrement[ch];
  136.       }
  137.       VolWheel[ch]=PresVol[ch];
  138.       if ( ((CurVols[ch]*4)+VolWheel[ch])< 0) {
  139.         VIncrement[ch]=0;
  140.         PresVol[ch]=0;
  141.         CurVols[ch]=DestVol[ch]/4;
  142.         DestVol[ch]=0;
  143.         Music.SetVol(ch,VolTab[0]);
  144.       }
  145.       else
  146.         Music.SetVol(ch,VolTab[(CurVols[ch]*4)+VolWheel[ch]]);
  147.  
  148.     }
  149.  
  150.     if (RetLeft[ch] && ChanOn[CurVoice]) {         // Deal with retrigger
  151.       CurSpc[ch]+=2;
  152.       if (CurSpc[ch]>=RetSpc[ch]) {
  153.         q=RetSmp[ch];
  154.         m=Sample[q].LoopMode;
  155.         CurVols[ch]=RetVol[ch]-1;
  156.         if (m&(1<<2))
  157.           Music.PlaySample(Sample[q].Seg/2,
  158.                            Sample[q].Off/2,
  159.                            Sample[q].Rep/2,
  160.                            Sample[q].RepEnd/2,
  161.                            ch,m);
  162.         else
  163.           Music.PlaySample(Sample[q].Seg,
  164.                            Sample[q].Off,
  165.                            Sample[q].Rep,
  166.                            Sample[q].RepEnd,
  167.                            ch,m);
  168.         Music.SetVol(ch,VolTab[(CurVols[ch]*4)+VolWheel[ch]]);
  169.         RetLeft[ch]--;
  170.         CurSpc[ch]=0;
  171.       }
  172.     }
  173.   }
  174.  
  175.   if (OCount--) {
  176.     outportb(0x20,0x20);
  177.     return;
  178.   }
  179.   OCount=OverFlow;
  180.  
  181.   ov=CurVoice;
  182.   for (c=0;c<16;c++) {
  183.     CurVoice=c;
  184.     if (Bars[CurVoice]<(PlayTempo*2)) Bars[CurVoice]=0;
  185.     if (Bars[CurVoice]) Bars[CurVoice]-=PlayTempo*2;
  186.     fekt=Pattern[CurSpot+3]&0xF0;
  187.     if (Pattern[CurSpot] && ChanOn[CurVoice] && fekt!=0x30) {
  188.       q=Pattern[CurSpot+1];
  189.       m=Sample[q].LoopMode;
  190.       if (Sample[Pattern[CurSpot+1]].SType&1) m|=(1<<2);
  191.       CurFreqs[CurVoice]=Freqs[Pattern[CurSpot]-1];
  192.       Music.SetFreq(CurVoice,CurFreqs[CurVoice]);
  193.       if (m&(1<<2))
  194.         Music.PlaySample(Sample[q].Seg/2,
  195.                          Sample[q].Off/2,
  196.                          Sample[q].Rep/2,
  197.                          Sample[q].RepEnd/2,
  198.                          CurVoice,m);
  199.       else
  200.         Music.PlaySample(Sample[q].Seg,
  201.                          Sample[q].Off,
  202.                          Sample[q].Rep,
  203.                          Sample[q].RepEnd,
  204.                          CurVoice,m);
  205.       PresPitch[CurVoice]=0;
  206.       DestPitch[CurVoice]=0; Increment[CurVoice]=0;
  207.       Bars[CurVoice]=(Pattern[CurSpot+2]*fs)/16;
  208.     }
  209.     Music.SetBalance(CurVoice,CurBalance[CurVoice]);
  210.     if (Pattern[CurSpot+2] && ChanOn[CurVoice] && fekt!=0xa0) {
  211.       PresVol[CurVoice]=0; VolWheel[CurVoice]=0;
  212.       DestVol[CurVoice]=0; VIncrement[CurVoice]=0;
  213.  
  214.       CurVols[CurVoice]=(Pattern[CurSpot+2]-1);
  215.       Music.SetVol(CurVoice,VolTab[(CurVols[CurVoice]*4)]);
  216.       Bars[CurVoice]=(Pattern[CurSpot+2]*fs)/16;
  217.     }
  218.     if (Pattern[CurSpot+3]) {
  219.       switch(Pattern[CurSpot+3]&0xF0) {
  220.         case 0xf0:  // Modify tempo
  221.           CurTempo=Pattern[CurSpot+3]&0xF;
  222.           PlayTempo=CurTempo;
  223.           UpdateTempo(mTempo[PlayTempo]+TempoBend);
  224.           break;
  225.         case 0xe0:  // Fine tempo up/cancel
  226.           if (Pattern[CurSpot+3]&0xF) {
  227.             TempoBend+=Pattern[CurSpot+3]&0xF;
  228.             if ((TempoBend+mTempo[PlayTempo])>=100)
  229.               TempoBend=100;
  230.           }
  231.           else
  232.             TempoBend=0;
  233.           UpdateTempo(mTempo[PlayTempo]+TempoBend);
  234.           break;
  235.         case 0xd0:  // Fine tempo down/cancel
  236.           if (Pattern[CurSpot+3]&0xF) {
  237.             TempoBend-=Pattern[CurSpot+3]&0xF;
  238.             if ((TempoBend+mTempo[PlayTempo])<=0)
  239.               TempoBend=0;
  240.           }
  241.           else
  242.             TempoBend=0;
  243.           UpdateTempo(mTempo[PlayTempo]+TempoBend);
  244.           break;
  245.         case 0xb0:  // Set Balance
  246.           CurBalance[CurVoice]=Pattern[CurSpot+3]&0xF;
  247.           Music.SetBalance(CurVoice,CurBalance[CurVoice]);
  248.           if (Tracking)
  249.             UpdatePanning();
  250.           break;
  251.         case 0x10:  // raise pitch
  252.           PresPitch[CurVoice]+=((Pattern[CurSpot+3]&0xF)*4)*256;
  253.           PitchWheel[CurVoice]=PresPitch[CurVoice]/256;
  254.           DestPitch[CurVoice]=0; Increment[CurVoice]=0;
  255.           Music.SetFreq(ch,CurFreqs[ch]+PitchWheel[ch]+SinTable[VibAmp][VibPtr[ch]]);
  256.           break;
  257.         case 0x20:  // lower pitch
  258.           PresPitch[CurVoice]-=((Pattern[CurSpot+3]&0xF)*4)*256;
  259.           PitchWheel[CurVoice]=PresPitch[CurVoice]/256;
  260.           DestPitch[CurVoice]=0; Increment[CurVoice]=0;
  261.           Music.SetFreq(ch,CurFreqs[ch]+PitchWheel[ch]+SinTable[VibAmp][VibPtr[ch]]);
  262.           break;
  263.         case 0x30:  // Port to note
  264.           if (Pattern[CurSpot]) {
  265.             t=0;
  266.             fp=CurFreqs[CurVoice]+PitchWheel[CurVoice];
  267.             sp=Freqs[Pattern[CurSpot]-1];
  268.             DestPitch[CurVoice]=sp;
  269.             if (fp>sp) {t=sp;sp=fp;fp=t;}
  270.             if (Pattern[CurSpot+3]&0xF)
  271.               Increment[CurVoice]=((sp-fp)*256)/((Pattern[CurSpot+3]&0xF)*
  272.                 (mTempo[PlayTempo]+TempoBend));
  273.             else
  274.               Increment[CurVoice]=((sp-fp)*256)/(1*
  275.                 (mTempo[PlayTempo]+TempoBend));
  276.             Increment[CurVoice]*=8;
  277.             if (t) Increment[CurVoice]=-Increment[CurVoice];
  278.           }
  279.           break;
  280.         case 0x40:  // Retrigger
  281.           if (Pattern[CurSpot]) {
  282.             RetLeft[CurVoice]=(Pattern[CurSpot+3]&0xF)-1;
  283.             RetSpc[CurVoice]=((mTempo[PlayTempo]+TempoBend)/(RetLeft[CurVoice]+1))/4;
  284.             RetSmp[CurVoice]=Pattern[CurSpot+1];
  285.             RetVol[CurVoice]=Pattern[CurSpot+2];
  286.             CurSpc[CurVoice]=0;
  287.           }
  288.           break;
  289.         case 0x50:  // Set vibrato amplitude
  290.           VibAmp=Pattern[CurSpot+3]&0xF;
  291.           break;
  292.         case 0x60:  // Vibrato Control
  293.           if (!VibOn[CurVoice]) {
  294.             VibOn[CurVoice]=1;
  295.             VibInc[CurVoice]=(Pattern[CurSpot+3]&0xF)*6;
  296.             VibPtr[CurVoice]=0;
  297.           }
  298.           else
  299.             VibInc[CurVoice]=(Pattern[CurSpot+3]&0xF)*6;
  300.           break;
  301.         case 0x90:  // Sustained vibrato control
  302.           if (Pattern[CurSpot+3]&0xF) {   // On
  303.             if (!VibOn[CurVoice]) {
  304.               VibOn[CurVoice]=2;
  305.               VibInc[CurVoice]=(Pattern[CurSpot+3]&0xF)*6;
  306.               VibPtr[CurVoice]=0;
  307.             }
  308.             else
  309.               VibInc[CurVoice]=(Pattern[CurSpot+3]&0xF)*6;
  310.           }
  311.           else {                          // Off
  312.             VibPtr[CurVoice]=0;
  313.             VibInc[CurVoice]=0;
  314.             VibOn[CurVoice]=FALSE;
  315.           }
  316.           break;
  317.         case 0x70:  // VolSldUp
  318.           q=Pattern[CurSpot+3]&0xF;
  319.           CurVols[CurVoice]+=q;
  320.           if (CurVols[CurVoice]>0xF) CurVols[CurVoice]=0xF;
  321.           Music.SetVol(CurVoice,VolTab[(CurVols[CurVoice]*4)+VolWheel[CurVoice]]);
  322.           Bars[CurVoice]=((CurVols[CurVoice]+1)*fs)/16;
  323.           break;
  324.         case 0x80:  // VolSldDn
  325.           q=Pattern[CurSpot+3]&0xF;
  326.           CurVols[CurVoice]-=q;
  327.           if (CurVols[CurVoice]<0) CurVols[CurVoice]=0;
  328.           Music.SetVol(CurVoice,VolTab[(CurVols[CurVoice]*4)+VolWheel[CurVoice]]);
  329.           Bars[CurVoice]=((CurVols[CurVoice]+1)*fs)/16;
  330.           break;
  331.         case 0xA0:  // Port to Vol
  332.           if (Pattern[CurSpot+2]) {
  333.             t=0;
  334.             fp=(CurVols[CurVoice]*4)+VolWheel[CurVoice];
  335.             sp=(Pattern[CurSpot+2]*4)-1;
  336.             DestVol[CurVoice]=sp;
  337.             if (fp>sp) {t=sp;sp=fp;fp=t;}
  338.             if (Pattern[CurSpot+3]&0xF)
  339.               VIncrement[CurVoice]=((sp-fp)*16)/((Pattern[CurSpot+3]&0xF)*
  340.                 (mTempo[PlayTempo]+TempoBend));
  341.             else
  342.               VIncrement[CurVoice]=((sp-fp)*16)/(1*
  343.                 (mTempo[PlayTempo]+TempoBend));
  344.             if (t) VIncrement[CurVoice]=-VIncrement[CurVoice];
  345.           }
  346.           break;
  347.       }
  348.     }
  349.     if (VibOn[CurVoice]==1 && (Pattern[CurSpot+3]&0xF0)!=0x60) {
  350.       VibPtr[CurVoice]=0;
  351.       VibInc[CurVoice]=0;
  352.       VibOn[CurVoice]=FALSE;
  353.     }
  354.     if (Bars[CurVoice]>=fs) Bars[CurVoice]=fs-1;
  355.     if (Bars[CurVoice]<1) Bars[CurVoice]=1;
  356.   }
  357.   CurVoice=ov;
  358.   if (CurRow<=BreakLoc) {
  359.     if (CurRow-CurTop==31) {
  360.       if (Tracking) {
  361.         CurRow++;
  362.         CurTop=CurRow;
  363.         TrakUpdate=TRUE;
  364.       }
  365.       else
  366.         CurRow++;
  367.     }
  368.     else
  369.       if (Tracking) {
  370.         MoveCurs(CurVoice,CurRow+1);
  371.         UDBars=TRUE;;
  372.       }
  373.       else
  374.         CurRow++;
  375.   }
  376.   else {
  377.     if (PatLock) {
  378.       if (Tracking) {
  379.         TrakUpdate=TRUE;
  380.         CurRow=0; CurTop=0;
  381.       }
  382.       else
  383.         CurRow=0;
  384.     }
  385.     else {
  386.       PutAwayPat(CurPattern);
  387.       if ((CurOrder+1)==OrdLen)
  388.         CurOrder=LoopTo;
  389.       else
  390.         CurOrder++;
  391.       CurPattern=Order[CurOrder];
  392.       GetPat(CurPattern);
  393.       if (Tracking) {
  394.         CurTop=0;
  395.         CurRow=0;
  396.         TrakUpdate=TRUE;
  397.       }
  398.       else
  399.         CurRow=0;
  400.     }
  401.   }
  402.  
  403. //  Locked=TRUE;
  404.   outportb(0x20,0x20);
  405. }
  406.  
  407. void StartMusic() {
  408.   fs=fsize*4;
  409.   StopMusic();
  410.   KillBars();
  411.   memset(&PitchWheel[0],0,sizeof(PitchWheel));
  412.   memset(&VibOn[0],0,sizeof(VibOn));
  413.   memset(&VibPtr[0],0,sizeof(VibPtr));
  414.   memset(&VibInc[0],0,sizeof(VibInc));
  415.   memset(&RetLeft[0],0,sizeof(RetLeft));
  416. //  BarCnt=0;
  417.   PlayTempo=CurTempo;
  418. //  TempoBend=0;
  419.   UpdateChans();
  420.   UpdateOrder();
  421. //  Music.TurnOnInt(6);
  422.   OldInt8=getvect(8);
  423.   setvect(8,Int8);
  424.   UpdateTempo(mTempo[PlayTempo]+TempoBend);
  425.   OCount=OverFlow;
  426.   Playing=YES;
  427.  
  428.   if (!Tracking) {
  429.     DrawF(0,42,11,9," Playing song.. Press any key except D to stop playback - Press D to shell to DOS                                                   ");
  430.     do {
  431.       GetCh();
  432.       if (LKHit=='D') {
  433.         DosShell();
  434.         LKHit='D';
  435.       }
  436.     } while (LKHit=='D');
  437.     StopMusic();
  438.     UpdateStat();
  439.     UpdateChans();
  440.   }
  441. }
  442.  
  443. void StopMusic() {
  444.   word q;
  445.  
  446.   if (Playing) {
  447. //    Music.TurnOffInt();
  448.     setvect(8,OldInt8);
  449.     outportb(0x43,0x34);
  450.     outportb(0x40,0);
  451.     outportb(0x40,0);
  452.     if (Tracking) UpdateChans();
  453.   }
  454.   KillBars();
  455.   for (q=0;q<16;q++) Music.StopSample(q);
  456.   Playing=NO;
  457. }
  458.  
  459.