home *** CD-ROM | disk | FTP | other *** search
/ Multimedia Classic / MultimediaClassic.mdf / utility / vts139b.arj / VT.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1993-12-22  |  30.4 KB  |  1,208 lines

  1. PROGRAM VT;
  2.  
  3. {$M 30000,20000,655360}
  4.  
  5. USES CleanHeap,
  6.      SoundDevices,                   { Sound output devices.               }
  7.      {DevSbDAC, DevDAC, DevSB, }DevGUS,{                                     }
  8.      {DevFile, DevAdLib, DevSpkr,}     {                                     }
  9.      VTSpecial,                      { Installation check.                 }
  10.      VTStrConst, StrConst,           { Language support.                   }
  11.      Dos,                            { Standard TP UNITs.                  }
  12.      Objects,                        {                                     }
  13.      VTCfg, VTGlobal, VTCmd,         { VT-Specific UNITs.                  }
  14.      VTWins, VTPlay, VTPartitura,    {                                     }
  15.      VTScreens, VTShell,             {                                     }
  16.      SongUnit, SongElements,         { Song definition UNITs.              }
  17.      SongUtils,                      {                                     }
  18.      PlayMod, Filters, ModCommands,  {                                     }
  19.      SoundBlaster,                   {                                     }
  20.      Vid43, Output43,                { Video routines.                     }
  21.      Kbd, Debugging,                 { Miscelaneous UNITs.                 }
  22.      HexConversions, Mouse,          {                                     }
  23.      CmdLine,                        {                                     }
  24.      Heaps,                          {                                     }
  25.      SwapStream, SwapManager,        {                                     }
  26.      FileUtil;                       {                                     }
  27.  
  28.  
  29.  
  30.  
  31. VAR
  32.   nt             : TFullNote;
  33.   pp             : PPattern;
  34.   omd,
  35.   md             : TPlayingNote;
  36.   ThereIsNewNote : BOOLEAN;
  37.   EmptySong      : TSong;
  38.  
  39. CONST
  40.   Funking    : BOOLEAN = FALSE;
  41.   FunkGoesUp : BOOLEAN = FALSE;
  42.   FadingOut  : BOOLEAN = FALSE;
  43.   FadedOut   : BOOLEAN = FALSE;
  44.   FadeCount  : WORD    = 0;
  45.   LastSeq    : BYTE    = 255;
  46.  
  47. VAR
  48.   Sequences  : ARRAY[1..256] OF BOOLEAN;
  49.  
  50.  
  51.  
  52.  
  53. { -------------------------------------------------------------------------- }
  54.  
  55. FUNCTION IsAConsole(VAR f) : BOOLEAN; ASSEMBLER;
  56.   ASM
  57.                 MOV     AX,$4400
  58.                 LES     BX,[f]
  59.                 MOV     BX,TextRec([ES:BX]).Handle
  60.                 INT     $21
  61.                 XOR     AX,AX
  62.                 TEST    DL,$80
  63.                 JZ      @@Fin
  64.                 INC     AX
  65. @@Fin:
  66.   END;
  67.  
  68. FUNCTION RJust(s: STRING; i: WORD) : STRING;
  69.   VAR
  70.     r : STRING;
  71.   BEGIN
  72.     IF i <= Length(s) THEN
  73.       BEGIN
  74.         RJust := s;
  75.         EXIT;
  76.       END;
  77.     r[0] := CHAR(i - Length(s));
  78.     FillChar(r[1], i - Length(s), ' ');
  79.     RJust := r + s;
  80.   END;
  81.  
  82.  
  83. FUNCTION LJust(s: STRING; i: WORD) : STRING;
  84.   VAR
  85.     r : STRING;
  86.   BEGIN
  87.     IF i <= Length(s) THEN
  88.       BEGIN
  89.         LJust := s;
  90.         EXIT;
  91.       END;
  92.     r[0] := CHAR(i - Length(s));
  93.     FillChar(r[1], i - Length(s), ' ');
  94.     LJust := s + r;
  95.   END;
  96.  
  97.  
  98. FUNCTION Char2Str(c: CHAR; n: BYTE) : STRING;
  99.   VAR
  100.     s : STRING;
  101.   BEGIN
  102.     FillChar(s, SIZEOF(s), c);
  103.     s[0] := CHAR(n);
  104.     Char2Str := s;
  105.   END;
  106.  
  107.  
  108. PROCEDURE MyWriteLn(s: STRING);
  109.   CONST
  110.     Linea : WORD = 0;
  111.   BEGIN
  112.     IF ((Linea > 24) OR (s = '')) AND IsAConsole(Output) THEN
  113.       BEGIN
  114.         Write(StdErr, GetString(StrUsagePressAKey));
  115.         KbdReadKey;
  116.         Write(StdErr, #13+Char2Str(' ', 79)+#13);
  117.         Linea := 0;
  118.       END;
  119.     IF s <> '' THEN WriteLn(Output, s);
  120.     INC(Linea);
  121.   END;
  122.  
  123.  
  124.  
  125. PROCEDURE UsagePart(Str: WORD);
  126.   BEGIN
  127.     MyWriteLn(GetString(StrUsageTop));
  128.  
  129.     WHILE GetString(Str) <> #0 DO
  130.       BEGIN
  131.         IF GetString(Str) = '' THEN
  132.           MyWriteLn(GetString(StrUsageEmpty))
  133.         ELSE
  134.           MyWriteLn(GetString(Str));
  135.         INC(Str);
  136.       END;
  137.  
  138.     MyWriteLn(GetString(StrUsageBottom));
  139.   END;
  140.  
  141. PROCEDURE USAGE;
  142.   VAR
  143.     i : WORD;
  144.     p : PSoundDevice;
  145.   BEGIN
  146.     MyWriteLn('                           ╔════════════════════════╗');
  147.     MyWriteLn('                           ║ VangeliSTracker  v'+Version+' ║');
  148.     MyWriteLn('                           ╚════════════════════════╝');
  149.  
  150.     IF Beta THEN
  151.       MyWriteLn('                                    '+BetaStr);
  152.  
  153.     MyWriteLn(GetString(StrUsageTop));
  154.     MyWriteLn(GetString(StrUsage01));
  155.     MyWriteLn(GetString(StrUsageBottom));
  156.  
  157.     UsagePart(Strusage1Beg);
  158.     MyWriteLn('');
  159.  
  160.     UsagePart(Strusage2Beg);
  161.     MyWriteLn('');
  162.     
  163. {    MyWriteLn(GetString(StrUsageTop));}
  164.     UsagePart(StrUsage3Beg);
  165. {
  166.     FOR i := 1 TO NumDevices DO
  167.       BEGIN
  168.         p := IndexDevice(i);
  169.         MyWriteLn(LJust(' │   '+RJust(p^.DevID+':', SIZEOF(TDevID))+' '+p^.Name, 78)+'│');
  170.       END;
  171.     MyWriteLn(GetString(StrUsageBottom));
  172. }
  173.     MyWriteLn('');
  174.  
  175.     UsagePart(Strusage4Beg);
  176.  
  177.     HALT(1);
  178.   END;
  179.  
  180. { -------------------------------------------------------------------------- }
  181.  
  182. PROCEDURE ORROR(s: STRING; Go: BOOLEAN);
  183.   VAR
  184.     OldScr : WORD;
  185.   BEGIN
  186.     QuitaVideoMode43;
  187.  
  188.     WriteLn('ORROR: ', s);
  189.  
  190.     IF Go THEN
  191.       HALT(1);
  192.  
  193.     PoneVideoMode43;
  194.     InitWinF8Demo;
  195.     OldScr := ActiveWindows;
  196.     SetUser(0);
  197.     SetUser(OldScr);
  198.     RefreshMiscInfo(EmptySong);
  199.   END;
  200.  
  201. { -------------------------------------------------------------------------- }
  202.  
  203. PROCEDURE DoNotes(VAR Song: TSong; VAR note, NewNote, L2ndForz: BOOLEAN);
  204.   CONST
  205.     i     : WORD     = 0;
  206.     PSize : WORD     = 0;
  207.     Patt  : PPattern = NIL;
  208.   BEGIN
  209.     IF NewNote THEN BEGIN
  210.       md := NoteSound^;
  211.  
  212.       PSize := 0;
  213.       Patt := Song.GetPatternSeq(md.SeqPlaying);
  214.       IF (Patt <> NIL) AND (Patt^.Patt <> NIL) THEN
  215.         PSize := Patt^.Patt^.NNotes;
  216.  
  217.       UpdateRunInfo(BPMIncrement, md.Tempo, Song.GetPatternSequence(md.SeqPlaying), md.NotePlaying, md.SeqPlaying, PSize);
  218.  
  219.       w2ndLine.forz := L2ndForz;
  220.  
  221.  
  222.       FOR i := 1 TO Song.NumChannels DO BEGIN
  223.         Song.GetNote(md.SeqPlaying, md.NotePlaying, i, nt);
  224.  
  225.         UpdateNoteInfo  (Song, nt, i);
  226.         UpdateSampleInfo(Song, nt, i);
  227.         ParseBarInit    (nt, i);
  228.       END;
  229.  
  230.  
  231.       IF (md.SeqPlaying <= 256) AND (LastSeq <> md.SeqPlaying) THEN
  232.         BEGIN
  233.           IF (NOT VTLoopMod) AND Sequences[md.SeqPlaying] THEN
  234.             FadingOut := TRUE;
  235.  
  236.           Sequences[md.Seqplaying] := TRUE;
  237.           LastSeq := md.SeqPlaying;
  238.         END;
  239.  
  240.       NewNote  := FALSE;
  241.       L2ndForz := FALSE;
  242.     END;
  243.  
  244.     Update2ndLine(Song, note);
  245.     TickSampleInfo;
  246.   END;
  247.  
  248.  
  249. CONST
  250.   StkSize = 500;
  251. VAR
  252.   Stack1 : ARRAY[1..StkSize] OF BYTE;
  253.  
  254. PROCEDURE TickProc(VAR Song: TSong; note: BOOLEAN); FAR;
  255.   CONST
  256.     Semaphor  : BYTE    = 0;
  257.     Semaphor2 : BYTE    = 0;
  258.     Semaphor3 : BYTE    = 0;
  259.     Semaphor4 : BYTE    = 0;
  260.     NewNote   : BOOLEAN = FALSE;
  261.     L2ndForz  : BOOLEAN = FALSE;
  262.     Count     : BYTE    = 0;
  263.     i         : WORD    = 0;
  264.     j         : WORD    = 0;
  265.     k         : WORD    = 0;
  266.     SS_1      : WORD    = 0;
  267.     SP_1      : WORD    = 0;
  268.     SongP     : PSong   = NIL;
  269.     noteP     : BOOLEAN = FALSE;
  270.   BEGIN
  271.  
  272.     IF (NOT Playing) AND (Semaphor4 = 0) THEN
  273.       BEGIN
  274.         INC(Semaphor4);
  275.         UpdateBars;
  276. {
  277.         FillChar(nt, SIZEOF(nt), 0);
  278.         FOR i := 1 TO ModUnit.NumChannels DO
  279.           UpdateSampleInfo(nt, i);
  280.         TickSampleInfo;
  281. }
  282.         DEC(Semaphor4);
  283.         EXIT;
  284.       END;
  285.  
  286.     IF note THEN BEGIN
  287.       NewNote        := TRUE;
  288.       ThereIsNewNote := TRUE;
  289.     END;
  290.  
  291.     L2ndForz := L2ndForz OR w2ndLine.forz;
  292.  
  293.     IF Semaphor = 0 THEN BEGIN
  294.       INC(Semaphor);
  295.  
  296.       SongP := @Song;
  297.       noteP := note;
  298.  
  299.        ASM
  300.                 MOV     [SS_1],SS
  301.                 MOV     [SP_1],SP
  302.                 MOV     AX,DS
  303.                 MOV     SS,AX
  304.                 MOV     SP,OFFSET Stack1 + StkSize
  305.        END;
  306.  
  307.        DoNotes(SongP^, noteP, NewNote, L2ndForz);
  308.  
  309.        ASM
  310.                 MOV     SS,[SS_1]
  311.                 MOV     SP,[SP_1]
  312.        END;
  313.  
  314.       DEC(Semaphor);
  315.     END;
  316.  
  317.     UpdateOscilloscInfo;
  318.  
  319.     IF Semaphor2 = 0 THEN
  320.       BEGIN
  321.         INC(Semaphor2);
  322.         IF Funking THEN
  323.           ASM
  324. {
  325.                 MOV     DX,$3DA
  326. @@lp1:           IN     AL,DX
  327.                  AND    AL,8
  328.                  JZ     @@lp1
  329.  
  330.                 MOV     DX,$3D4
  331.                 MOV     AL,$18
  332.                 MOV     AH,[Count]
  333.                 OUT     DX,AX
  334.  
  335.                 MOV     DL,[FunkGoesUp]
  336. @@otra:         AND     DL,DL
  337.                 JZ      @@down
  338.                  DEC    AH
  339.                 JMP     @@up
  340. @@down:          INC    AH
  341. @@up:           AND     AH,AH
  342.                 JNZ     @@ya
  343.                  AND    DL,1
  344.                  XOR    DL,1
  345.                  MOV    [FunkGoesUp],DL
  346.                  JMP    @@otra
  347. @@ya:           MOV     [Count],AH
  348. }
  349.           END;
  350.         DEC(Semaphor2);
  351.       END;
  352.  
  353.     IF (FadingOut) AND (Semaphor3 = 0) THEN
  354.       BEGIN
  355.         INC(Semaphor3);
  356.         IF NOT PermitFade THEN
  357.           FadedOut := TRUE
  358.         ELSE
  359.           BEGIN
  360.             INC(FadeCount, FadeIncr);
  361.             FOR j := 1 TO HI(FadeCount) DO
  362.               BEGIN
  363.                 FadedOut := TRUE; 
  364.                 FOR k := 1 TO MaxChannels DO
  365.                   IF UserVols[k] > 0 THEN
  366.                     BEGIN
  367.                       DEC(UserVols[k]);
  368.                       FadedOut := FALSE;
  369.                     END;
  370.               END;
  371.             FadeCount := LO(FadeCount);
  372.           END;
  373.         DEC(Semaphor3);
  374.       END;
  375.   END;
  376.  
  377. { -------------------------------------------------------------------------- }
  378.  
  379. PROCEDURE OsShell;
  380.   VAR
  381.     OldScr  : WORD;
  382.     OldHz   : WORD;
  383.     OldLMod : BOOLEAN;
  384.     OldVMod : BOOLEAN;
  385.     OldFall : BOOLEAN;
  386.     i       : WORD;
  387.     HeapSize: LONGINT;
  388.   BEGIN
  389.     OldFall       := MyCanFallBack;
  390.     OldScr        := ActiveWindows;
  391.     OldVMod       := VTLoopMod;
  392.     OldLMod       := MyLoopMod;
  393.     OldHz         := DesiredHz;
  394.  
  395.     MyCanFallBack := FALSE;
  396.     VTLoopMod     := TRUE;
  397.     MyLoopMod     := TRUE;
  398.  
  399.     SetNothing;
  400.     QuitaVideoMode43;
  401.     IF DesiredHz > ShellHz THEN
  402.       DesiredHz := ShellHz;
  403.     ChangeSamplingRate(DesiredHz);
  404.  
  405.     WriteLn('Type EXIT to return to VangeliSTracker');
  406.  
  407.     HeapSize := Heap.HTotalAvail;
  408.     ShrinkSystemHeap(0);
  409.     SwapVectors;
  410.     Exec(ShellPath, ShellParam);
  411.     SwapVectors;
  412.     ShrinkSystemHeap(HeapSize);
  413.  
  414. {FOR i := 1 TO 50000 DO;}
  415.  
  416.     ChangeSamplingRate(OldHz);
  417.     PoneVideoMode43;
  418.     InitWinF8Demo;
  419.     SetUser(OldScr);
  420.     RefreshMiscInfo(PlayingSong^);
  421.     HideMouse;
  422.     MOUReset(FALSE);
  423.     ShowMouse;
  424.     MyLoopMod   := OldLMod;
  425.     VTLoopMod   := OldVMod;
  426.     MyCanFallBack := OldFall;
  427.   END;
  428.  
  429.  
  430.  
  431. PROCEDURE WindowShell;
  432.   VAR
  433.     OldScr  : WORD;
  434.     OldHz   : WORD;
  435.     OldLMod : BOOLEAN;
  436.     OldVMod : BOOLEAN;
  437.     OldFall : BOOLEAN;
  438.     i       : WORD;
  439.   BEGIN
  440.     OldFall       := MyCanFallBack;
  441.     OldScr        := ActiveWindows;
  442.     OldVMod       := VTLoopMod;
  443.     OldLMod       := MyLoopMod;
  444.     OldHz         := DesiredHz;
  445.  
  446.     MyCanFallBack := FALSE;
  447.     VTLoopMod     := TRUE;
  448.     MyLoopMod     := TRUE;
  449.  
  450.     IF DesiredHz > ShellHz THEN
  451.       DesiredHz := ShellHz;
  452.     ChangeSamplingRate(DesiredHz);
  453.  
  454.     DoWindowShell;
  455.  
  456.     ChangeSamplingRate(OldHz);
  457.     SetUser(OldScr);
  458.     RefreshMiscInfo(PlayingSong^);
  459.     MyLoopMod   := OldLMod;
  460.     VTLoopMod   := OldVMod;
  461.     MyCanFallBack := OldFall;
  462.   END;
  463.  
  464.  
  465.  
  466. PROCEDURE DoFunk;
  467.   CONST
  468.     f : BOOLEAN = FALSE;
  469.   BEGIN
  470.  
  471.     IF NOT f THEN
  472.       ASM
  473.  
  474.           MOV     DX,$3D4
  475.  
  476.           MOV     AL,9
  477.           OUT     DX,AL
  478.           INC     DX
  479.           IN      AL,DX
  480.           AND     AL,$BF
  481.           OUT     DX,AL
  482.           DEC     DX
  483.  
  484.           MOV     AL,$11
  485.           OUT     DX,AL
  486.           INC     DX
  487.           IN      AL,DX
  488.           AND     AL,$7F
  489.           OUT     DX,AL
  490.           DEC     DX
  491.  
  492.           MOV     AL,7
  493.           OUT     DX,AL
  494.           INC     DX
  495.           IN      AL,DX
  496.           AND     AL,$EF
  497.           OUT     DX,AL
  498.           DEC     DX
  499.  
  500.           MOV     AL,$18
  501.           MOV     AH,8*23 - 1
  502.           OUT     DX,AX
  503.  
  504.       END
  505.     ELSE
  506.       ASM
  507.  
  508.           MOV     DX,$3D4
  509.  
  510.           MOV     AL,9
  511.           OUT     DX,AL
  512.           INC     DX
  513.           IN      AL,DX
  514.           OR      AL,$40
  515.           OUT     DX,AL
  516.           DEC     DX
  517.  
  518.           MOV     AL,7
  519.           OUT     DX,AL
  520.           INC     DX
  521.           IN      AL,DX
  522.           OR      AL,$10
  523.           OUT     DX,AL
  524.           DEC     DX
  525.  
  526.           MOV     AL,$11
  527.           OUT     DX,AL
  528.           INC     DX
  529.           IN      AL,DX
  530.           OR      AL,$80
  531.           OUT     DX,AL
  532.           DEC     DX
  533.  
  534.       END;
  535.  
  536.     f := NOT f;
  537.  
  538.   END;
  539.  
  540. {
  541. PROCEDURE DoFunk;
  542.   CONST
  543.     f : BOOLEAN = FALSE;
  544.   BEGIN
  545.  
  546.     IF NOT f THEN
  547.       BEGIN
  548.         ASM
  549.  
  550.           MOV     DX,$3D4
  551.  
  552.           MOV     AL,9
  553.           OUT     DX,AL
  554.           INC     DX
  555.           IN      AL,DX
  556.           AND     AL,$BF
  557.           OUT     DX,AL
  558.           DEC     DX
  559.  
  560.           MOV     AL,$11
  561.           OUT     DX,AL
  562.           INC     DX
  563.           IN      AL,DX
  564.           AND     AL,$7F
  565.           OUT     DX,AL
  566.           DEC     DX
  567.  
  568.           MOV     AL,7
  569.           OUT     DX,AL
  570.           INC     DX
  571.           IN      AL,DX
  572.           AND     AL,$EF
  573.           OUT     DX,AL
  574.           DEC     DX
  575.  
  576.           MOV     AL,$18
  577.           MOV     AH,8*11 - 1
  578.           OUT     DX,AX
  579.  
  580.       END
  581.     ELSE
  582.       ASM
  583.  
  584.           MOV     DX,$3D4
  585.  
  586.           MOV     AL,9
  587.           OUT     DX,AL
  588.           INC     DX
  589.           IN      AL,DX
  590.           OR      AL,$40
  591.           OUT     DX,AL
  592.           DEC     DX
  593.  
  594.           MOV     AL,7
  595.           OUT     DX,AL
  596.           INC     DX
  597.           IN      AL,DX
  598.           OR      AL,$10
  599.           OUT     DX,AL
  600.           DEC     DX
  601.  
  602.           MOV     AL,$11
  603.           OUT     DX,AL
  604.           INC     DX
  605.           IN      AL,DX
  606.           OR      AL,$80
  607.           OUT     DX,AL
  608.           DEC     DX
  609.  
  610.       END;
  611.  
  612.       f := NOT f;
  613.  
  614.   END;
  615. }
  616. { -------------------------------------------------------------------------- }
  617.  
  618. PROCEDURE IncVal(VAR Val: INTEGER; Incr, Min, Max: INTEGER);
  619.   BEGIN
  620.     IF      Val + Incr < Min THEN Val := Min
  621.     ELSE IF Val + Incr > Max THEN Val := Max
  622.     ELSE                          INC(Val, Incr);
  623.   END;
  624.  
  625.  
  626. FUNCTION DoPlayMod(VAR Song: TSong) : BOOLEAN;
  627.   CONST
  628.     Puerto  : BYTE = 4;
  629.  
  630.   PROCEDURE WriteCRTC;
  631.     BEGIN
  632.       DirectWriteAttr(2, 'CRTC:   Reg ' + HexByte(Puerto) + '  val ' + HexByte(Port[$3d5]), $97);
  633.     END;
  634.  
  635.   PROCEDURE WriteFilt;
  636.     BEGIN
  637.       DirectWriteAttr(182, 'Loudness filter.' +
  638.         '   HI pass: shape ' + HexDigit(TrebleFilterVal_Left) +
  639.            '  amplif ' + HexDigit(TrebleFilterMult_Left)     +
  640.         '   LO pass: shape ' + HexDigit(BassFilterVal_Left)   +
  641.            '  amplif ' + HexDigit(BassFilterMult_Left)       , $97);
  642.     END;
  643.  
  644.   VAR
  645.     cr   : CHAR;
  646.     ch,
  647.     LastVol,
  648.     LastHz,
  649.     MyHz,
  650.     i, r : WORD;
  651.     s    : STRING;
  652.   BEGIN
  653.  
  654.     Port[$3d4] := Puerto;
  655.  
  656.     WriteCRTC;
  657.     WriteFilt;
  658.  
  659.     ThereIsNewNote := FALSE;
  660.  
  661.     IF FirstChannel > Song.NumChannels-3 THEN
  662.       FirstChannel := Song.NumChannels-3;
  663.  
  664.     IF Song.NumChannels <= 4 THEN
  665.       FirstChannel := 1;
  666.  
  667.     DrawPartiture(Song, 0, 0);
  668.  
  669.     ModTickProc      := TickProc;
  670.     ModTickProcValid := TRUE;
  671.  
  672.     FadingOut := FALSE;
  673.     FadedOut  := FALSE;
  674.  
  675.     FillChar(Sequences, SIZEOF(Sequences), FALSE);
  676.     LastSeq := 255;
  677.  
  678.     FillChar(UserVols, SIZEOF(UserVols), VtVolume);
  679.  
  680.     LastHz := SoundHz;
  681.  
  682. {    VTLoopMod := TRUE;}
  683.  
  684.     FirstPattern := VT1stPattern;
  685.     RepStart     := VTRepStart;
  686.     SongLen      := VTSongLen;
  687.  
  688.     InitPlayData(Song);
  689.     PlayStart(Song);
  690.  
  691.     ChangeSamplingRate(DesiredHz);
  692.     RefreshMiscInfo(Song);
  693.  
  694.     { Adjust looping flag. }
  695.  
  696. {
  697.     VTLoopMod := MyLoopMod;
  698.     IF (NOT MyLoopMod) AND (Song.SequenceRepStart < Song.SequenceLength) THEN
  699.       MyLoopMod := TRUE;
  700. }
  701.     REPEAT
  702.  
  703. {
  704.       WHILE NOT KbdKeyPressed DO;
  705. }
  706.  
  707.       ch := 0;
  708.       cr := #0;
  709.       WHILE KbdKeyPressed DO
  710.         BEGIN
  711.           ch := KbdReadKey;
  712.           cr := UPCASE(CHAR(ch));
  713.  
  714.           CASE ch OF
  715.             kbPgDn: IF NextSeq < Song.SequenceLength THEN BEGIN
  716.                       Sequences[NextSeq]   := TRUE;
  717.                       Sequences[NextSeq+1] := FALSE;
  718.                       INC(NextSeq);
  719.                     END;
  720.             kbPgUp: IF NextSeq > 1 THEN BEGIN
  721.                       Sequences[NextSeq]   := FALSE;
  722.                       Sequences[NextSeq-1] := FALSE;
  723.                       DEC(NextSeq);
  724.                     END;
  725.             kbHome: BEGIN
  726.                       IF (NextNote < 8) AND (NextSeq > 1) THEN
  727.                         BEGIN
  728.                           Sequences[NextSeq]   := FALSE;
  729.                           Sequences[NextSeq-1] := FALSE;
  730.                           DEC(NextSeq);
  731.                         END;
  732.                       NextNote := 1;
  733.                     END;
  734.             kbEnd:  IF NextSeq < Song.SequenceLength THEN BEGIN
  735.                       Sequences[NextSeq]   := TRUE;
  736.                       Sequences[NextSeq+1] := FALSE;
  737.                       INC(NextSeq);
  738.                       NextNote := 1;
  739.                     END;
  740.     {
  741.             kbLeft: BEGIN
  742.                       DEC(TicksPerSecond);
  743.                     END;
  744.             kbRight:BEGIN
  745.                       INC(TicksPerSecond);
  746.                     END;
  747.     }
  748.             kbLeft: BEGIN
  749.                       IF FirstChannel > 1 THEN
  750.                         BEGIN
  751.                           DEC(FirstChannel);
  752.                           w2ndLine.forz             := TRUE;
  753.                           VTPartitura.PartWin^.forz := TRUE;
  754.                         END;
  755.                     END;
  756.             kbRight:BEGIN
  757.                       IF FirstChannel + 4 <= Song.NumChannels THEN
  758.                         BEGIN
  759.                           INC(FirstChannel);
  760.                           w2ndLine.forz             := TRUE;
  761.                           VTPartitura.PartWin^.forz := TRUE;
  762.                         END;
  763.                     END;
  764. {
  765.             kbDown: BEGIN
  766.                       IF DMAOffset > 0 THEN
  767.                         BEGIN
  768.                           DEC(DMAOffset);
  769.                           HzChanged := TRUE;
  770.                         END;
  771.                     END;
  772.             kbUp:   BEGIN
  773.                       INC(DMAOffset);
  774.                       HzChanged := TRUE;
  775.                     END;
  776.             kbCtrlPgUp: BEGIN
  777.                       INC(Puerto);
  778.                       Port[$3d4] := Puerto;
  779.                       WriteCRTC;
  780.                     END;
  781.             kbCtrlPgDn: BEGIN
  782.                       DEC(Puerto);
  783.                       Port[$3d4] := Puerto;
  784.                       WriteCRTC;
  785.                     END;
  786. }
  787.             kbCtrlLeft: BEGIN
  788.                       Port[$3d4] := Puerto;
  789.                       Port[$3d5] := Port[$3d5] + 1;
  790.                       WriteCRTC;
  791.                     END;
  792.             kbCtrlRight: BEGIN
  793.                       Port[$3d4] := Puerto;
  794.                       Port[$3d5] := Port[$3d5] - 1;
  795.                       WriteCRTC;
  796.                     END;
  797. {
  798.             kbCtrlHome: BEGIN
  799.                       Port[$3d4] := Puerto;
  800.                       WriteCRTC;
  801.                       WriteFilt;
  802.                     END;
  803.             kbF1:   Playing := NOT Playing;
  804. }
  805.             kbF5:   SetBig;
  806.             kbF6:   SetSmall_Samples;
  807.             kbF7:   SetSmall_Oscillosc;
  808.             kbF8:   SetCredits;
  809. {
  810.             kbF9:   DoFunk;
  811.             kbAltA: BEGIN IncVal(INTEGER(TrebleFilterVal_Left),  -1, 0, 15); WriteFilt; END;
  812.             kbAltQ: BEGIN IncVal(INTEGER(TrebleFilterVal_Left),   1, 0, 15); WriteFilt; END;
  813.             kbAltS: BEGIN IncVal(INTEGER(TrebleFilterMult_Left), -1, 0, 15); WriteFilt; END;
  814.             kbAltW: BEGIN IncVal(INTEGER(TrebleFilterMult_Left),  1, 0, 15); WriteFilt; END;
  815.             kbAltD: BEGIN IncVal(INTEGER(BassFilterVal_Left),    -1, 0, 15); WriteFilt; END;
  816.             kbAltE: BEGIN IncVal(INTEGER(BassFilterVal_Left),     1, 0, 15); WriteFilt; END;
  817.             kbAltF: BEGIN IncVal(INTEGER(BassFilterMult_Left),   -1, 0, 15); WriteFilt; END;
  818.             kbAltR: BEGIN IncVal(INTEGER(BassFilterMult_Left),    1, 0, 15); WriteFilt; END;
  819. }
  820.             kbAlt1..kbAlt6:
  821.                     BEGIN
  822.                       i := HI(ch - kbAlt1) + 11;
  823.                       Permisos[i]               := NOT Permisos[i];
  824.                       w2ndLine.forz             := TRUE;
  825.                       VTPartitura.PartWin^.forz := TRUE;
  826.                     END;
  827.           ELSE
  828.             CASE cr OF
  829. {
  830.               'L': DoBassPower := NOT DoBassPower;
  831. }
  832.               'D': OsShell;
  833.               'N': FadingOut := TRUE;
  834.               '1'..'9':
  835.                    BEGIN
  836.                      i := BYTE(cr) - BYTE('0');
  837.                      Permisos[i]               := NOT Permisos[i];
  838.                      w2ndLine.forz             := TRUE;
  839.                      VTPartitura.PartWin^.forz := TRUE;
  840.                    END;
  841.               '0': BEGIN
  842.                      i := 10;
  843.                      Permisos[i]               := NOT Permisos[i];
  844.                      w2ndLine.forz             := TRUE;
  845.                      VTPartitura.PartWin^.forz := TRUE;
  846.                    END;
  847. {
  848.               'F': FilterOn  := TFilterMethod((BYTE(FilterOn)  + 1) MOD FilterMod);
  849.               'G': FilterOff := TFilterMethod((BYTE(FilterOff) + 1) MOD FilterMod);
  850. }
  851.               'W': IF ModCommands.Tempo > 1 THEN
  852.                      DEC(ModCommands.Tempo);
  853.               'E': IF ModCommands.Tempo < $30 THEN
  854.                      INC(ModCommands.Tempo);
  855.               '+': IF (NOT FadingOut) THEN
  856.                      BEGIN
  857.                        IF (VtVolume < 255-9) THEN
  858.                          INC(VtVolume, 9)
  859.                        ELSE
  860.                          VtVolume := 255;
  861.                        FOR i := 1 TO MaxChannels DO UserVols[i] := VtVolume;
  862.                        RefreshMiscInfo(Song);
  863.                      END;
  864.               '-': IF (NOT FadingOut) THEN
  865.                      BEGIN
  866.                        IF (VtVolume > 9) THEN
  867.                          DEC(VtVolume, 9)
  868.                        ELSE
  869.                          VtVolume := 0;
  870.                        FOR i := 1 TO MaxChannels DO UserVols[i] := VtVolume;
  871.                        RefreshMiscInfo(Song);
  872.                      END;
  873. {
  874.               'R': BEGIN
  875.                      MyHz := ActualHz;
  876.                      WHILE (MyHz = ActualHz) AND (MyHz <> ActiveDevice^.GetRealFreqProc(0)) DO
  877.                        BEGIN
  878.                          DEC(DesiredHz, 100);
  879.                          MyHz := ActiveDevice^.GetRealFreqProc(DesiredHz);
  880.                        END;
  881.                      ChangeSamplingRate(DesiredHz);
  882.                      RefreshMiscInfo(Song);
  883.                    END;
  884.               'T': BEGIN
  885.                      MyHz := ActualHz;
  886.                      WHILE (MyHz = ActualHz) AND (MyHz <> ActiveDevice^.GetRealFreqProc(65535))  DO
  887.                        BEGIN
  888.                          INC(DesiredHz, 100);
  889.                          MyHz := ActiveDevice^.GetRealFreqProc(DesiredHz);
  890.                        END;
  891.                      ChangeSamplingRate(DesiredHz);
  892.                      RefreshMiscInfo(Song);
  893.                    END;
  894. }
  895.               'S': BEGIN
  896.                      Playing := NOT Playing;
  897.                    END;
  898.             END;
  899.           END;
  900.  
  901.         END;
  902.  
  903.       IF (SoundHz <> LastHz) OR (UserVols[1] <> LastVol) THEN
  904.         BEGIN
  905.           RefreshMiscInfo(Song);
  906.           LastHz  := SoundHz;
  907.           LastVol := UserVols[1];
  908.         END;
  909.  
  910.       IF ThereIsNewNote THEN
  911.         DrawPartiture(Song, md.NotePlaying, md.SeqPlaying);
  912.  
  913.       WriteNum( 0, TrebleFilterVal_Left,  10);
  914.       WriteNum(20, TrebleFilterMult_Left, 10);
  915.       WriteNum(40, BassFilterVal_Left,    10);
  916.       WriteNum(60, BassFilterMult_Left,   10);
  917.  
  918.       PollDevice;
  919.  
  920.     UNTIL (ch = kbESC) OR FadedOut OR NOT Playing;
  921.     DoPlayMod := ch = kbESC;
  922.  
  923.     PlayStop;
  924.   END;
  925.  
  926. { -------------------------------------------------------------------------- }
  927.  
  928. VAR
  929.   NoMods : BOOLEAN;
  930.  
  931. FUNCTION DoOneMOD(FName, InsidePath: PathStr) : BOOLEAN; FAR;
  932.   VAR
  933.     Song    : TSong;
  934.     NoMod   : BOOLEAN;
  935. {
  936.     Cmd     : TVTCmdSwitch;
  937. }
  938.     SwName  : PathStr;
  939.     Dir     : DirStr;
  940.     Name    : NameStr;
  941.     Ext     : ExtStr;
  942.  
  943.     i       : WORD;
  944.     s       : STRING[2];
  945.   LABEL
  946.     Fin;
  947.   BEGIN
  948.     IF FirstSong <> '' THEN
  949.       BEGIN
  950.         FSplit(FName, Dir, Name, Ext);
  951.         IF FirstSong = Name+Ext THEN
  952.           FirstSong := ''
  953.         ELSE
  954.           BEGIN
  955.             DoOneMod := TRUE;
  956. {
  957.             WriteLn(FName, ' <> ', FirstSong);
  958. }
  959.             EXIT;
  960.           END;
  961.       END;
  962.  
  963.     NoMods := FALSE;
  964.  
  965.     NoMod    := TRUE;
  966.     DoOneMOD := FALSE;
  967.  
  968.  
  969.     SetVTDevice;
  970.     SetVTFreq;
  971.  
  972.  
  973. {
  974.     Cmd.Init;
  975. }
  976.     Song.Init;
  977.     REPEAT
  978.       Song.SetInsidePath(InsidePath);
  979.  
  980.       IF VT1stPattern <> 0 THEN
  981.         Song.SongStart := VT1stPattern;
  982.  
  983.       IF VTSongLen <> 0 THEN
  984.         Song.SongLen := VTSongLen;
  985.  
  986. {      StartSampling;}
  987.  
  988.       Song.LoadFName(FName);
  989.  
  990.       IF (Song.Status = msOk) OR (Song.Status = msFileTooShort) THEN
  991.         BEGIN
  992.           NoMod := FALSE;
  993. {
  994.           IF Song.GetInsidePath <> '' THEN
  995.             BEGIN
  996.               FSplit(Song.GetInsidePath, Dir, Name, Ext);
  997.               SwName := Name + '.VTO';
  998.               FSplit(FName, Dir, Name, Ext);
  999.               SwName := Dir + SwName;
  1000.             END
  1001.           ELSE
  1002.             BEGIN
  1003.               FSplit(FName, Dir, Name, Ext);
  1004.               SwName := Dir + Name + '.VTO';
  1005.             END;
  1006.  
  1007.           Cmd.ParseFile(SwName);
  1008. }
  1009.           InitVTScreens(Song);
  1010.           RefreshVTScreens;
  1011.  
  1012.           IF DoPlayMod(Song) THEN GOTO Fin;
  1013.         END;
  1014.     UNTIL NOT Song.ThereIsMore;
  1015.  
  1016.     IF NoMod THEN
  1017.       ORROR(Song.GetErrorString + ' [' + FName + ']', FALSE);
  1018.  
  1019.     DoOneMOD := TRUE;
  1020. Fin:
  1021.     Song.Done;
  1022. {
  1023.     Cmd.Done;
  1024. }
  1025.   END;
  1026.  
  1027. { -------------------------------------------------------------------------- }
  1028.  
  1029. CONST
  1030.   AppID : STRING[Length(NombreApp) + 2 + Length(Version) + Length(BetaStr)] = NombreApp+' v'+Version+BetaStr;
  1031.  
  1032. VAR
  1033.   Dir     : DirStr;
  1034.   Name    : NameStr;
  1035.   Ext     : ExtStr;
  1036.   p       : POINTER;
  1037.   l       : LONGINT;
  1038.   s       : STRING;
  1039.   i, r    : WORD;
  1040. LABEL
  1041.   Fin;
  1042. BEGIN
  1043.  
  1044.   { Initialize heaps }
  1045.  
  1046.   InitHeapVariables;
  1047.   InitUmbHeap;
  1048.  
  1049.  
  1050.  
  1051.   { Init command line objects }
  1052.  
  1053.   Cmd.Init;
  1054.   SongColl.Init(2, 3);
  1055.  
  1056.  
  1057.  
  1058.   { Initialize Song variables }
  1059.  
  1060.   EmptySong.Init;
  1061.  
  1062.     
  1063.  
  1064.   { Set debugging flag. }
  1065.  
  1066.   Debugging.Debug := FALSE;
  1067.   IF (ParamStr(1) = '/DEB') OR (ParamStr(1) = '/deb') THEN
  1068.     Debugging.Debug := TRUE;
  1069.  
  1070.  
  1071.  
  1072.   { Initialize language file. }
  1073.  
  1074.   StringsFName := FExpand(StringsFName);
  1075.   FSplit(StringsFName, Dir, Name, Ext);
  1076.   IF NOT FileExists(StringsFName) THEN
  1077.     StringsFName := Name+Ext;
  1078.   IF NOT FileExists(StringsFName) THEN
  1079.     StringsFName := VTDir+Name+Ext;
  1080.  
  1081.   IF (NOT FileExists(StringsFName)) OR NOT InitStrings(StringsFName) THEN
  1082.     BEGIN
  1083.       WriteLn(StdErr, 'VT needs a valid language file to run.');
  1084.       WriteLn(StdErr, 'VT necesita un fichero de lenguaje válido para funcionar.');
  1085.       EXIT;
  1086.     END;
  1087.  
  1088.  
  1089.  
  1090.   { Display usage and exit if no parameters. }
  1091.  
  1092.   IF ParamCount = 0 THEN USAGE;
  1093.  
  1094.   ASM
  1095.         MOV     AX,3
  1096.         INT     10h
  1097.   END;
  1098.  
  1099.   WriteLn;
  1100.   WriteLn('   ┌──────────────────────────────────────────────────────────────────────┐    ');
  1101.   WriteLn('   │ BETA    BETA    BETA    BETA    BETA    BETA    BETA    BETA    BETA │    ');
  1102.   WriteLn('   └──────────────────────────────────────────────────────────────────────┘    ');
  1103.   WriteLn;
  1104.   WriteLn(' This is a beta version of the VangeliSTracker. It''s purposely incomplete.     ');
  1105.   WriteLn(' It was created to test two things:                                            ');
  1106.   WriteLn;
  1107.   WriteLn('   1st - The VIDEO MODE: experimental 90x63 text mode.                         ');
  1108.   WriteLn;
  1109.   WriteLn('   2nd - The GUS SUPPORT. See VT.CFG                                           ');
  1110.   WriteLn;
  1111.   WriteLn(' If the screen is misaligned, try CTRL+LEFT ARROW and CTRL+RIGHT ARROW.        ');
  1112.   WriteLn;
  1113.   WriteLn;
  1114.   WriteLn(' Comments welcome to:                                                          ');
  1115.   WriteLn;
  1116.   WriteLn('   Juan Carlos Arévalo                                                         ');
  1117.   WriteLn('     Fidonet:  2:341/27.16, 2:341/8.36                                        ');
  1118.   WriteLn('     CdNet:    94:640/200                                                      ');
  1119.   WriteLn('     Internet: jcarlos@gw.iic.uam.es                                           ');
  1120.   WriteLn('               mpetit@dit.upm.es                                               ');
  1121.   WriteLn('     P. O. Box 156405 (28080 - Madrid, Spain)                                  ');
  1122.   WriteLn;
  1123.   Write  ('Press any key to continue.');
  1124.  
  1125.   KbdReadKey;
  1126.  
  1127.   WriteLn;
  1128.   WriteLn;
  1129.  
  1130.  
  1131.   { Display Copyright notice. }
  1132.  
  1133.   WriteLn(AppID, ' (C) 1992-93, VangeliSTeam.');
  1134.   WriteLn;
  1135.   Write(GetString(StrInitializing));
  1136.  
  1137.  
  1138.  
  1139.   { Check for other VT's resident in memory. }
  1140.  
  1141.   VTResidentCheck(AppID);
  1142.  
  1143.  
  1144.  
  1145.   { Initialize Units. SoundDevices MUST be first. }
  1146.  
  1147.   InitSoundDevices;  Write('o');
  1148.   IF NOT InitSwapManager(New(PSwapStream, Init)) THEN
  1149.     BEGIN
  1150.       DoneSwapManager;
  1151.       WriteLn;
  1152.       WriteLn;
  1153.       WriteLn(GetString(StrSwapNotInit));
  1154.       EXIT;
  1155.     END;
  1156.  
  1157.   Write('o');
  1158.  
  1159.   InitVid43;          Write('o');
  1160.   InitModUnit;        Write('o');
  1161.   InitModVideoTables; Write('o');
  1162.  
  1163.  
  1164.  
  1165.   { Initialize and paint screen. }
  1166.  
  1167.   SetVTDevice;
  1168.   SetVTFreq;
  1169.  
  1170.   InitVTScreens(EmptySong); WriteLn;
  1171.   PoneVideoMode43;
  1172.  
  1173.   InitWinF8Demo;
  1174.   SetSmall_Samples;
  1175.  
  1176.   SetOffs(ScrOffset);
  1177.  
  1178.   InitMouse;
  1179.   SetMouse(TRUE);
  1180.   ShowMouse;
  1181.  
  1182.   InitPlayData(PSong(NIL)^);
  1183.  
  1184.   OneModProc := DoOneMod;
  1185.  
  1186.  
  1187.  
  1188.   { Loop for all MODs. }
  1189.  
  1190.   NoMods := TRUE;
  1191.  
  1192.   Cmd.ParseLine(GetDOSCmdLine);
  1193.   IF NOT DoSongColl(Cmd.FileDir) THEN GOTO Fin;
  1194.  
  1195.   IF NoMods THEN
  1196.     ORROR(GetString(StrFileNotExist), FALSE);
  1197.  
  1198.  
  1199. Fin:
  1200.  
  1201.   { Cleanup and finish. }
  1202.  
  1203.   EndSampling;
  1204.   QuitaVideoMode43;
  1205.   DoneSwapManager;
  1206.  
  1207. END.
  1208.