PROGRAM VT;

{$M 30000,20000,655360}

USES CleanHeap,
     SoundDevices,                   { Sound output devices.               }
     DevSbDAC, DevDAC, DevSB,        {                                     }
     DevFile, DevAdLib, DevSpkr,     {                                     }
     VTSpecial,                      { Installation check.                 }
     VTStrConst, StrConst,           { Language support.                   }
     Dos,                            { Standard TP UNITs.                  }
     Objects,                        {                                     }
     VTCfg, VTGlobal, VTCmd,         { VT-Specific UNITs.                  }
     VTWins, VTPlay, VTPartitura,    {                                     }
     VTScreens,                      {                                     }
     SongUnit, SongElements,         { Song definition UNITs.              }
     SongUtils,                      {                                     }
     PlayMod, Filters, ModCommands,  {                                     }
     SoundBlaster,                   {                                     }
     Vid43, Output43,                { Video routines.                     }
     Kbd, Debugging,                 { Miscelaneous UNITs.                 }
     HexConversions,
     CmdLine,                        {                                     }
     Heaps,                          {                                     }
     SwapStream, SwapManager,        {                                     }
     FileUtil;                       {                                     }




VAR
  nt             : TFullNote;
  pp             : PPattern;
  omd,
  md             : TPlayingNote;
  ThereIsNewNote : BOOLEAN;
  EmptySong      : TSong;

CONST
  Funking    : BOOLEAN = FALSE;
  FunkGoesUp : BOOLEAN = FALSE;
  FadingOut  : BOOLEAN = FALSE;
  FadedOut   : BOOLEAN = FALSE;
  FadeCount  : WORD    = 0;
  LastSeq    : BYTE    = 255;

VAR
  Sequences  : ARRAY[1..256] OF BOOLEAN;




{ -------------------------------------------------------------------------- }

FUNCTION IsAConsole(VAR f) : BOOLEAN; ASSEMBLER;
  ASM
                MOV     AX,$4400
                LES     BX,[f]
                MOV     BX,TextRec([ES:BX]).Handle
                INT     $21
                XOR     AX,AX
                TEST    DL,$80
                JZ      @@Fin
                INC     AX
@@Fin:
  END;

FUNCTION RJust(s: STRING; i: WORD) : STRING;
  VAR
    r : STRING;
  BEGIN
    IF i <= Length(s) THEN
      BEGIN
        RJust := s;
        EXIT;
      END;
    r[0] := CHAR(i - Length(s));
    FillChar(r[1], i - Length(s), ' ');
    RJust := r + s;
  END;


FUNCTION LJust(s: STRING; i: WORD) : STRING;
  VAR
    r : STRING;
  BEGIN
    IF i <= Length(s) THEN
      BEGIN
        LJust := s;
        EXIT;
      END;
    r[0] := CHAR(i - Length(s));
    FillChar(r[1], i - Length(s), ' ');
    LJust := s + r;
  END;


FUNCTION Char2Str(c: CHAR; n: BYTE) : STRING;
  VAR
    s : STRING;
  BEGIN
    FillChar(s, SIZEOF(s), c);
    s[0] := CHAR(n);
    Char2Str := s;
  END;


PROCEDURE MyWriteLn(s: STRING);
  CONST
    Linea : WORD = 0;
  BEGIN
    IF ((Linea > 24) OR (s = '')) AND IsAConsole(Output) THEN
      BEGIN
        Write(StdErr, GetString(StrUsagePressAKey));
        KbdReadKey;
        Write(StdErr, #13+Char2Str(' ', 79)+#13);
        Linea := 0;
      END;
    IF s <> '' THEN WriteLn(Output, s);
    INC(Linea);
  END;



PROCEDURE UsagePart(Str: WORD);
  BEGIN
    MyWriteLn(GetString(StrUsageTop));

    WHILE GetString(Str) <> #0 DO
      BEGIN
        IF GetString(Str) = '' THEN
          MyWriteLn(GetString(StrUsageEmpty))
        ELSE
          MyWriteLn(GetString(Str));
        INC(Str);
      END;

    MyWriteLn(GetString(StrUsageBottom));
  END;

PROCEDURE USAGE;
  VAR
    i : WORD;
    p : PSoundDevice;
  BEGIN
    MyWriteLn('                           ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»');
    MyWriteLn('                           º VangeliSTracker  v'+Version+' º');
    MyWriteLn('                           ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ¼');

    IF Beta THEN
      MyWriteLn('                                     (beta)');

    MyWriteLn(GetString(StrUsageTop));
    MyWriteLn(GetString(StrUsage01));
    MyWriteLn(GetString(StrUsageBottom));

    UsagePart(Strusage1Beg);
    MyWriteLn('');

    UsagePart(Strusage2Beg);
    MyWriteLn('');
    
    MyWriteLn(GetString(StrUsageTop));
    MyWriteLn(GetString(StrUsage3Beg));

    FOR i := 1 TO NumDevices DO
      BEGIN
        p := IndexDevice(i);
        MyWriteLn(LJust(' ³   '+RJust(p^.DevID+':', SIZEOF(TDevID))+' '+p^.Name, 78)+'³');
      END;

    MyWriteLn(GetString(StrUsageBottom));
    MyWriteLn('');

    UsagePart(Strusage4Beg);

    HALT(1);
  END;

{ -------------------------------------------------------------------------- }

PROCEDURE ORROR(s: STRING; Go: BOOLEAN);
  VAR
    OldScr : WORD;
  BEGIN
    QuitaVideoMode43;

    WriteLn('ORROR: ', s);

    IF Go THEN
      HALT(1);

    PoneVideoMode43;
    InitWinF8Demo;
    OldScr := ActiveWindows;
    SetUser(0);
    SetUser(OldScr);
    RefreshMiscInfo(EmptySong);
  END;

{ -------------------------------------------------------------------------- }

PROCEDURE DoNotes(VAR Song: TSong; VAR note, NewNote, L2ndForz: BOOLEAN);
  CONST
    i     : WORD     = 0;
    PSize : WORD     = 0;
    Patt  : PPattern = NIL;
  BEGIN
    IF NewNote THEN BEGIN
      md := NoteSound^;

      PSize := 0;
      Patt := Song.GetPatternSeq(md.SeqPlaying);
      IF (Patt <> NIL) AND (Patt^.Patt <> NIL) THEN
        PSize := Patt^.Patt^.NNotes;

      UpdateRunInfo(md.Tempo, Song.GetPatternSequence(md.SeqPlaying), md.NotePlaying, md.SeqPlaying, PSize);

      w2ndLine.forz := L2ndForz;


      FOR i := 1 TO Song.NumChannels DO BEGIN
        Song.GetNote(md.SeqPlaying, md.NotePlaying, i, nt);

        UpdateNoteInfo  (Song, nt, i);
        UpdateSampleInfo(Song, nt, i);
        ParseBarInit    (nt, i);
      END;


      IF (md.SeqPlaying <= 256) AND (LastSeq <> md.SeqPlaying) THEN
        BEGIN
          IF (NOT VTLoopMod) AND Sequences[md.SeqPlaying] THEN
            FadingOut := TRUE;

          Sequences[md.Seqplaying] := TRUE;
          LastSeq := md.SeqPlaying;
        END;

      NewNote  := FALSE;
      L2ndForz := FALSE;
    END;

    Update2ndLine(note);
    TickSampleInfo;
  END;


CONST
  StkSize = 500;
VAR
  Stack1 : ARRAY[1..StkSize] OF BYTE;

PROCEDURE TickProc(VAR Song: TSong; note: BOOLEAN); FAR;
  CONST
    Semaphor  : BYTE    = 0;
    Semaphor2 : BYTE    = 0;
    Semaphor3 : BYTE    = 0;
    Semaphor4 : BYTE    = 0;
    NewNote   : BOOLEAN = FALSE;
    L2ndForz  : BOOLEAN = FALSE;
    Count     : BYTE    = 0;
    i         : WORD    = 0;
    j         : WORD    = 0;
    k         : WORD    = 0;
    SS_1      : WORD    = 0;
    SP_1      : WORD    = 0;
    SongP     : PSong   = NIL;
    noteP     : BOOLEAN = FALSE;
  BEGIN

    IF (NOT Playing) AND (Semaphor4 = 0) THEN
      BEGIN
        INC(Semaphor4);
        UpdateBars;
{
        FillChar(nt, SIZEOF(nt), 0);
        FOR i := 1 TO ModUnit.NumChannels DO
          UpdateSampleInfo(nt, i);
        TickSampleInfo;
}
        DEC(Semaphor4);
        EXIT;
      END;

    IF note THEN BEGIN
      NewNote        := TRUE;
      ThereIsNewNote := TRUE;
    END;

    L2ndForz := L2ndForz OR w2ndLine.forz;

    IF Semaphor = 0 THEN BEGIN
      INC(Semaphor);

      SongP := @Song;
      noteP := note;

       ASM
                MOV     [SS_1],SS
                MOV     [SP_1],SP
                MOV     AX,DS
                MOV     SS,AX
                MOV     SP,OFFSET Stack1 + StkSize
       END;

       DoNotes(SongP^, noteP, NewNote, L2ndForz);

       ASM
                MOV     SS,[SS_1]
                MOV     SP,[SP_1]
       END;

      DEC(Semaphor);
    END;

    UpdateOscilloscInfo;

    IF Semaphor2 = 0 THEN
      BEGIN
        INC(Semaphor2);
        IF Funking THEN
          ASM
{
                MOV     DX,$3DA
@@lp1:           IN     AL,DX
                 AND    AL,8
                 JZ     @@lp1

                MOV     DX,$3D4
                MOV     AL,$18
                MOV     AH,[Count]
                OUT     DX,AX

                MOV     DL,[FunkGoesUp]
@@otra:         AND     DL,DL
                JZ      @@down
                 DEC    AH
                JMP     @@up
@@down:          INC    AH
@@up:           AND     AH,AH
                JNZ     @@ya
                 AND    DL,1
                 XOR    DL,1
                 MOV    [FunkGoesUp],DL
                 JMP    @@otra
@@ya:           MOV     [Count],AH
}
          END;
        DEC(Semaphor2);
      END;

    IF (FadingOut) AND (Semaphor3 = 0) THEN
      BEGIN
        INC(Semaphor3);
        IF NOT PermitFade THEN
          FadedOut := TRUE
        ELSE
          BEGIN
            INC(FadeCount, FadeIncr);
            FOR j := 1 TO HI(FadeCount) DO
              BEGIN
                FadedOut := TRUE; 
                FOR k := 1 TO MaxChannels DO
                  IF UserVols[k] > 0 THEN
                    BEGIN
                      DEC(UserVols[k]);
                      FadedOut := FALSE;
                    END;
              END;
            FadeCount := LO(FadeCount);
          END;
        DEC(Semaphor3);
      END;
  END;

{ -------------------------------------------------------------------------- }

PROCEDURE OsShell;
  VAR
    OldScr  : WORD;
    OldHz   : WORD;
    OldLMod : BOOLEAN;
    OldVMod : BOOLEAN;
    OldFall : BOOLEAN;
    i       : WORD;
    HeapSize: LONGINT;
  BEGIN
    OldFall       := MyCanFallBack;
    OldScr        := ActiveWindows;
    OldVMod       := VTLoopMod;
    OldLMod       := MyLoopMod;
    OldHz         := DesiredHz;

    MyCanFallBack := FALSE;
    VTLoopMod     := TRUE;
    MyLoopMod     := TRUE;

    SetNothing;
    QuitaVideoMode43;
    IF DesiredHz > ShellHz THEN
      DesiredHz := ShellHz;
    ChangeSamplingRate(DesiredHz);

    HeapSize := Heap.HTotalAvail;
    ShrinkSystemHeap(0);
    SwapVectors;
    Exec(ShellPath, ShellParam);
    SwapVectors;
    ShrinkSystemHeap(HeapSize);

{FOR i := 1 TO 50000 DO;}

    ChangeSamplingRate(OldHz);
    PoneVideoMode43;
    InitWinF8Demo;
    SetUser(OldScr);
    RefreshMiscInfo(PlayingSong^);
    MyLoopMod   := OldLMod;
    VTLoopMod   := OldVMod;
    MyCanFallBack := OldFall;
  END;



PROCEDURE DoFunk;
  VAR
    f : BOOLEAN;
  BEGIN
    f := NOT Funking;
    IF f THEN
      ASM

          MOV     DX,$3D4

          MOV     AL,9
          OUT     DX,AL
          INC     DX
          IN      AL,DX
          AND     AL,$BF
          OUT     DX,AL
          DEC     DX

          MOV     AL,$11
          OUT     DX,AL
          INC     DX
          IN      AL,DX
          AND     AL,$7F
          OUT     DX,AL
          DEC     DX

          MOV     AL,7
          OUT     DX,AL
          INC     DX
          IN      AL,DX
          AND     AL,$EF
          OUT     DX,AL
          DEC     DX

          MOV     AL,$18
          MOV     AH,8*10 - 1
          OUT     DX,AX

          MOV     AL,f
          MOV     Funking,AL

      END
    ELSE
      ASM

          MOV     AL,f
          MOV     Funking,AL

          MOV     DX,$3D4

          MOV     AL,9
          OUT     DX,AL
          INC     DX
          IN      AL,DX
          OR      AL,$40
          OUT     DX,AL
          DEC     DX

          MOV     AL,7
          OUT     DX,AL
          INC     DX
          IN      AL,DX
          OR      AL,$10
          OUT     DX,AL
          DEC     DX

          MOV     AL,$11
          OUT     DX,AL
          INC     DX
          IN      AL,DX
          OR      AL,$80
          OUT     DX,AL
          DEC     DX

      END;
  END;

{ -------------------------------------------------------------------------- }

FUNCTION DoPlayMod(VAR Song: TSong) : BOOLEAN;
  CONST
    BarVals : ARRAY[1..3] OF CHAR = ( '±', '¦', '˜' );
    BarIdx  : BYTE = 1;
  VAR
    cr   : CHAR;
    ch,
    LastVol,
    LastHz,
    MyHz,
    i, r : WORD;
    s    : STRING;
  BEGIN

    ThereIsNewNote := FALSE;

    IF FirstChannel > Song.NumChannels-3 THEN
      FirstChannel := Song.NumChannels-3;

    DrawPartiture(Song, 0, 0);

    ModTickProc      := TickProc;
    ModTickProcValid := TRUE;

    FadingOut := FALSE;
    FadedOut  := FALSE;

    FillChar(Sequences, SIZEOF(Sequences), FALSE);
    LastSeq := 255;

    FillChar(UserVols, SIZEOF(UserVols), VtVolume);

    LastHz := SoundHz;

{    VTLoopMod := TRUE;}

    FirstPattern := VT1stPattern;
    RepStart     := VTRepStart;
    SongLen      := VTSongLen;

    InitPlayData(Song);
    PlayStart(Song);
    ChangeSamplingRate(DesiredHz);
    RefreshMiscInfo(Song);

    { Adjust looping flag. }

{
    VTLoopMod := MyLoopMod;
    IF (NOT MyLoopMod) AND (Song.SequenceRepStart < Song.SequenceLength) THEN
      MyLoopMod := TRUE;
}
    REPEAT
      ch := 0;
      cr := #0;
      IF KbdKeyPressed THEN BEGIN
        ch := KbdReadKey;
        cr := UPCASE(CHAR(ch));
      END;

      CASE ch OF
        kbPgDn: IF NextSeq < Song.SequenceLength THEN BEGIN
                  Sequences[NextSeq]   := TRUE;
                  Sequences[NextSeq+1] := FALSE;
                  INC(NextSeq);
                END;
        kbPgUp: IF NextSeq > 1 THEN BEGIN
                  Sequences[NextSeq]   := FALSE;
                  Sequences[NextSeq-1] := FALSE;
                  DEC(NextSeq);
                END;
        kbHome: BEGIN
                  IF (NextNote < 8) AND (NextSeq > 1) THEN
                    BEGIN
                      Sequences[NextSeq]   := FALSE;
                      Sequences[NextSeq-1] := FALSE;
                      DEC(NextSeq);
                    END;
                  NextNote := 1;
                END;
        kbEnd:  IF NextSeq < Song.SequenceLength THEN BEGIN
                  Sequences[NextSeq]   := TRUE;
                  Sequences[NextSeq+1] := FALSE;
                  INC(NextSeq);
                  NextNote := 1;
                END;
{
        kbLeft: BEGIN
                  DEC(TicksPerSecond);
                END;
        kbRight:BEGIN
                  INC(TicksPerSecond);
                END;
}
        kbLeft: BEGIN
                  IF FirstChannel > 1 THEN
                    BEGIN
                      DEC(FirstChannel);
                      w2ndLine.forz             := TRUE;
                      VTPartitura.PartWin^.forz := TRUE;
                    END;
                END;
        kbRight:BEGIN
                  IF FirstChannel + 4 <= Song.NumChannels THEN
                    BEGIN
                      INC(FirstChannel);
                      w2ndLine.forz             := TRUE;
                      VTPartitura.PartWin^.forz := TRUE;
                    END;
                END;
        kbDown: BEGIN
                  IF DMAOffset > 0 THEN
                    BEGIN
                      DEC(DMAOffset);
                      HzChanged := TRUE;
                    END;
                END;
        kbUp:   BEGIN
                  INC(DMAOffset);
                  HzChanged := TRUE;
                END;
        kbF5:   SetBig;
        kbF6:   SetSmall_Samples;
        kbF7:   SetSmall_Oscillosc;
        kbF8:   SetCredits;
        kbF9:   DoFunk;
      ELSE
        CASE cr OF
          'L': DoEqualice := NOT DoEqualice;
          'D': OsShell;
          'N': FadingOut := TRUE;
          '1'..'9':
               BEGIN
                 i := BYTE(cr) - BYTE('0');
                 Permisos[i]               := NOT Permisos[i];
                 w2ndLine.forz             := TRUE;
                 VTPartitura.PartWin^.forz := TRUE;
               END;
          '0': BEGIN
                 i := 10;
                 Permisos[i]               := NOT Permisos[i];
                 w2ndLine.forz             := TRUE;
                 VTPartitura.PartWin^.forz := TRUE;
               END;
          'B': BEGIN
                 INC(BarIdx);
                 IF BarIdx > 3 THEN BarIdx := 1;
                 BarVal := BarVals[BarIdx];
               END;
          'F': FilterOn  := TFilterMethod((BYTE(FilterOn)  + 1) MOD FilterMod);
          'G': FilterOff := TFilterMethod((BYTE(FilterOff) + 1) MOD FilterMod);
          'W': IF ModCommands.Tempo > 1 THEN
                 DEC(ModCommands.Tempo);
          'E': IF ModCommands.Tempo < $30 THEN
                 INC(ModCommands.Tempo);
          '+': IF (NOT FadingOut) THEN
                 BEGIN
                   IF (VtVolume < 255-9) THEN
                     INC(VtVolume, 9)
                   ELSE
                     VtVolume := 255;
                   FOR i := 1 TO MaxChannels DO UserVols[i] := VtVolume;
                   RefreshMiscInfo(Song);
                 END;
          '-': IF (NOT FadingOut) THEN
                 BEGIN
                   IF (VtVolume > 9) THEN
                     DEC(VtVolume, 9)
                   ELSE
                     VtVolume := 0;
                   FOR i := 1 TO MaxChannels DO UserVols[i] := VtVolume;
                   RefreshMiscInfo(Song);
                 END;
          'R': BEGIN
                 MyHz := ActualHz;
                 WHILE (MyHz = ActualHz) AND (MyHz <> ActiveDevice^.GetRealFreqProc(0)) DO
                   BEGIN
                     DEC(DesiredHz, 100);
                     MyHz := ActiveDevice^.GetRealFreqProc(DesiredHz);
                   END;
                 ChangeSamplingRate(DesiredHz);
                 RefreshMiscInfo(Song);
               END;
          'T': BEGIN
                 MyHz := ActualHz;
                 WHILE (MyHz = ActualHz) AND (MyHz <> ActiveDevice^.GetRealFreqProc(65535))  DO
                   BEGIN
                     INC(DesiredHz, 100);
                     MyHz := ActiveDevice^.GetRealFreqProc(DesiredHz);
                   END;
                 ChangeSamplingRate(DesiredHz);
                 RefreshMiscInfo(Song);
               END;
          'S': BEGIN
                 Playing := NOT Playing;
               END;
        END;
      END;

      IF (SoundHz <> LastHz) OR (UserVols[1] <> LastVol) THEN
        BEGIN
          RefreshMiscInfo(Song);
          LastHz  := SoundHz;
          LastVol := UserVols[1];
        END;

      IF ThereIsNewNote THEN
        DrawPartiture(Song, md.NotePlaying, md.SeqPlaying);

      PollDevice;

    UNTIL (ch = kbESC) OR FadedOut OR NOT Playing;

    DoPlayMod := ch = kbESC;

    PlayStop;
  END;

{ -------------------------------------------------------------------------- }

VAR
  NoMods : BOOLEAN;

FUNCTION DoOneMOD(FName, InsidePath: PathStr) : BOOLEAN; FAR;
  VAR
    Song    : TSong;
    NoMod   : BOOLEAN;
{
    Cmd     : TVTCmdSwitch;
}
    SwName  : PathStr;
    Dir     : DirStr;
    Name    : NameStr;
    Ext     : ExtStr;
  LABEL
    Fin;
  BEGIN
    NoMods := FALSE;

    NoMod    := TRUE;
    DoOneMOD := FALSE;

{
    Cmd.Init;
}
    Song.Init;
    REPEAT
      Song.SetInsidePath(InsidePath);

      IF VT1stPattern <> 0 THEN
        Song.SongStart := VT1stPattern;

      IF VTSongLen <> 0 THEN
        Song.SongLen := VTSongLen;

      Song.LoadFName(FName);

      IF (Song.Status = msOk) OR (Song.Status = msFileTooShort) THEN
        BEGIN
          NoMod := FALSE;
{
          IF Song.GetInsidePath <> '' THEN
            BEGIN
              FSplit(Song.GetInsidePath, Dir, Name, Ext);
              SwName := Name + '.VTO';
              FSplit(FName, Dir, Name, Ext);
              SwName := Dir + SwName;
            END
          ELSE
            BEGIN
              FSplit(FName, Dir, Name, Ext);
              SwName := Dir + Name + '.VTO';
            END;

          Cmd.ParseFile(SwName);
}
          InitVTScreens(Song);
          RefreshVTScreens;

          IF DoPlayMod(Song) THEN GOTO Fin;
        END;
    UNTIL NOT Song.ThereIsMore;

    IF NoMod THEN
      ORROR(Song.GetErrorString + ' [' + FName + ']', FALSE);

    DoOneMOD := TRUE;
Fin:
    Song.Done;
{
    Cmd.Done;
}
  END;

{ -------------------------------------------------------------------------- }

CONST
  AppID : STRING[Length(NombreApp) + 2 + Length(Version) + Length(BetaStr)] = NombreApp+' v'+Version+BetaStr;

VAR
  Dir     : DirStr;
  Name    : NameStr;
  Ext     : ExtStr;
  p       : POINTER;
  l       : LONGINT;
  s       : STRING;
  i, r    : WORD;
LABEL
  Fin;
BEGIN

  { Initialize heaps }

  InitHeapVariables;
  InitUmbHeap;



  { Init command line objects }

  Cmd.Init;
  SongColl.Init(2, 3);



  { Initialize Song variables }

  EmptySong.Init;

    

  { Set debugging flag. }

  Debugging.Debug := FALSE{TRUE};



  { Initialize language file. }

  StringsFName := FExpand(StringsFName);
  FSplit(StringsFName, Dir, Name, Ext);
  IF NOT FileExists(StringsFName) THEN
    StringsFName := Name+Ext;
  IF NOT FileExists(StringsFName) THEN
    StringsFName := VTDir+Name+Ext;

  IF (NOT FileExists(StringsFName)) OR NOT InitStrings(StringsFName) THEN
    BEGIN
      WriteLn(StdErr, 'VT needs a valid language file to run.');
      WriteLn(StdErr, 'VT necesita un fichero de lenguaje v lido para funcionar.');
      EXIT;
    END;



  { Display usage and exit if no parameters. }

  IF ParamCount = 0 THEN USAGE;



  { Display Copyright notice. }

  WriteLn(AppID, ' (C) 1992-93, VangeliSTeam.');
  WriteLn;
  Write(GetString(StrInitializing));



  { Check for other VT's resident in memory. }

  VTResidentCheck(AppID);



  { Initialize Units. SoundDevices MUST be first. }

  InitSoundDevices;  Write('o');
  IF NOT InitSwapManager(New(PSwapStream, Init)) THEN
    BEGIN
      DoneSwapManager;
      WriteLn;
      WriteLn;
      WriteLn(GetString(StrSwapNotInit));
      EXIT;
    END;

  Write('o');

  InitVid43;          Write('o');
  InitModUnit;        Write('o');
  InitModVideoTables; Write('o');



  { Initialize and paint screen. }

  SetVTDevice;
  SetVTFreq;

  InitVTScreens(EmptySong); WriteLn;
  PoneVideoMode43;
  InitWinF8Demo;
  SetSmall_Samples;

  SetOffs(ScrOffset);

  OneModProc := DoOneMod;



  { Loop for all MODs. }

  NoMods := TRUE;

  Cmd.ParseLine(GetDOSCmdLine);
  IF NOT DoSongColl(Cmd.FileDir) THEN GOTO Fin;

  IF NoMods THEN
    ORROR(GetString(StrFileNotExist), FALSE);


Fin:

  { Cleanup and finish. }

  EndSampling;
  QuitaVideoMode43;
  DoneSwapManager;

END.
