home *** CD-ROM | disk | FTP | other *** search
/ Beijing Paradise BBS Backup / PARADISE.ISO / software / BBSDOORW / MKMSG102.ZIP / MKMSGCVT.ZIP / MKAVATAR.PAS next >
Encoding:
Pascal/Delphi Source File  |  1993-08-15  |  18.2 KB  |  692 lines

  1. Unit MKAvatar;
  2. {$I-}
  3. {$I MKB.Def}
  4.  
  5. Interface
  6.  
  7. {$IFDEF WINDOWS}
  8. Uses MKWCrt;
  9. {$ELSE}
  10.   {$IfDef OPRO}
  11.     Uses OpCrt,
  12.   {$ELSE}
  13.     Uses Crt,
  14.   {$EndIf}
  15.   MKScrn;
  16. {$EndIF}
  17.  
  18.  
  19. Function InAvatar: Boolean;
  20.  
  21. Function AnsiColor (Fore:Byte;Back:Byte):String;
  22.   {return Ansi String to set color}
  23.  
  24. Function AnsiAttr(AA: Byte): String;
  25.   {return ansi string for attribute}
  26.  
  27. Function AnsiAttrDiff(OldA: Byte; NewA: Byte): String;
  28.   {return minimal ansi string to update attribute}
  29.  
  30. Procedure AvatarChar (ch:Char);
  31.   {interpret Ansi/Avatar codes and display to screen}
  32.  
  33. Function CvtColor(colr:Byte):String;
  34.   {Convert attr color codes to ansi numbers}
  35.  
  36. Procedure AVReset;
  37.  
  38. Procedure AvStr(St: String);
  39. Procedure AvStrLn(St: String);
  40.  
  41. Const AnsiSoundOn: Boolean = True;
  42.  
  43. Implementation
  44.  
  45.  
  46. Uses MKMusic;
  47.  
  48. Const
  49.   ControlCh: Set of Char = ['A','B','C','D','f','s','u','H','J','K','m',';',
  50.     'P', '@', 'M', 'L'];
  51.  
  52.   MusicCh: Set of Char = ['A','B','C','D','E','F','G','#','+','-','O','>',
  53.     '<','N','L','P','T','L','S','0','1','2','3','4','5','6','7','8','9','.',
  54.     ' '];
  55.  
  56. Const
  57.   MaxParms = 200;
  58.  
  59. Var
  60.   AvState: Word;            {0=normal, 1=esc, 2=esc[}        {Ansi}
  61.                             {5=^Y, 6=^Y#, 7=^V, 8=^V^A}      {Avatar}
  62.                             {9=^V^H 10=^V^H#}
  63.                             {11=Collect Parameters}
  64.                             {12="ansi" music, 13="ansi" music}
  65.   AvAttr: Byte;
  66.   AnsiParm: Array [1..MaxParms] of Byte;
  67.   AnsiParmNo: Byte;
  68.   SaveX: Byte;
  69.   SaveY: Byte;
  70.   InsertMode: Boolean;
  71.   CommandType: Word;
  72.   RemainingParms: Byte;
  73.   RepCount: Byte;
  74.   MusicStr: String[128];
  75.  
  76.  
  77. Function InAvatar: Boolean;
  78.   Begin
  79.   InAvatar := (AvState > 0);
  80.   End;
  81.  
  82.  
  83. Procedure AvStr(St: String);
  84.   Var
  85.     i: Word;
  86.  
  87.   Begin
  88.   For i := 1 To Length(St) Do
  89.     AvatarChar(St[i]);
  90.   End;
  91.  
  92.  
  93. Procedure AvStrLn(St: String);
  94.   Begin
  95.   AvStr(St);
  96.   AvatarChar(#13);
  97.   AvatarChar(#10);
  98.   End;
  99.  
  100.  
  101. Function CvtColor(colr:Byte):String;
  102.   Begin
  103.   Colr := Colr mod 8;
  104.   Case Colr of
  105.     0: cvtcolor := '0';
  106.     1: cvtcolor := '4';
  107.     2: cvtcolor := '2';
  108.     3: cvtcolor := '6';
  109.     4: cvtcolor := '1';
  110.     5: cvtcolor := '5';
  111.     6: cvtcolor := '3';
  112.     7: cvtcolor := '7';
  113.     End;
  114.   End;
  115.  
  116.  
  117. Function AnsiAttrDiff(OldA: Byte; NewA: Byte): String;
  118.   Var
  119.     DoReset: Boolean;
  120.     DoBlink: Boolean;
  121.     DoHigh: Boolean;
  122.     DoFore: Boolean;
  123.     DoBack: Boolean;
  124.     TmpStr: String;
  125.  
  126.   Begin
  127.   If OldA = NewA Then
  128.     AnsiAttrDiff := ''
  129.   Else
  130.     Begin
  131.     DoReset := ((OldA and $88) and (Not (NewA and $88))) <> 0;
  132.     DoBlink := ((NewA and $80) <> 0) And (DoReset or (OldA and $80 = 0));
  133.     DoHigh  := ((NewA and $08) <> 0) and (DoReset or (OldA and $08 = 0));
  134.     DoFore  := (((NewA and $07) <> (OldA and $07)) or (DoReset and ((NewA and $07) <> 7)));
  135.     DoBack  := (((NewA and $70) <> (OldA and $70)) or (DoReset and ((NewA and $70) <> 0)));
  136.     TmpStr := #27 + '[';
  137.     If DoReset Then
  138.       TmpStr := TmpStr + '0;';
  139.     If DoBlink Then
  140.       TmpStr := TmpStr + '5;';
  141.     If DoHigh Then
  142.       TmpStr := TmpStr + '1;';
  143.     If DoFore Then
  144.       TmpStr := TmpStr + '3' + CvtColor(NewA and $07) + ';';
  145.     If DoBack Then
  146.       TmpStr := TmpStr + '4' + CvtColor((NewA shr 4) and $07) + ';';
  147.     TmpStr[Length(TmpStr)] := 'm';
  148.     AnsiAttrDiff := TmpStr;
  149.     End;
  150.   End;
  151.  
  152.  
  153. Function AnsiColor(Fore:Byte;Back:Byte):String;
  154.   Var
  155.     TempStr:    String;
  156.  
  157.   Begin
  158.   TempStr := #027;
  159.   TempStr := TempStr +'['+ '0;';
  160.   If Fore > 7 Then
  161.     Begin
  162.     TempStr := TempStr + '1;';
  163.     Fore := Fore - 8;
  164.     End;
  165.   If Back > 7 Then
  166.     Begin
  167.     TempStr := TempStr + '5;';
  168.     Back := Back - 8;
  169.     End;
  170.   TempStr := TempStr + '3';
  171.   TempStr := TempStr + CvtColor(Fore) + ';' + '4' + CvtColor(Back) + 'm';
  172.   AnsiColor := TempStr;
  173.   End;
  174.  
  175.  
  176. Function AnsiAttr(AA: Byte): String;
  177.   Begin
  178.   AnsiAttr := AnsiColor(AA and $0f, AA shr 4);
  179.   End;
  180.  
  181.  
  182. Procedure AVReset;
  183.   Begin
  184.   AvState := 0;
  185.   AvAttr := 3;
  186.   TextAttr := AvAttr;
  187.   ClrScr;
  188.   InsertMode := False;
  189.   End;
  190.  
  191.  
  192. Procedure AVInit;
  193.   Begin
  194.   SaveX := 0;
  195.   SaveY := 0;
  196.   AvState := 0;
  197.   AvAttr := 3;
  198.   TextAttr := AvAttr;
  199.   InsertMode := False;
  200.   End;
  201.  
  202.  
  203. Procedure ColorParm(Parm:Byte);
  204.   Var
  205.     Temp: Word;
  206.  
  207.   Begin
  208.   Case parm of
  209.     00: AvAttr := LightGray;
  210.     01: AvAttr := AvAttr or $08;             {Hi intensity}
  211.     04: AvAttr := (AvAttr and $F8) or Blue;
  212.     05: AvAttr := AvAttr or $80;             {Blink}
  213.     07: Begin
  214.         Temp := AvAttr and $77;
  215.         AvAttr := (AvAttr and $88) or ((Temp shr 4) and $07);
  216.         AvAttr := AvAttr or ((Temp shl 4) and $70);
  217.         End;
  218.     08: AvAttr := AvAttr and $88;      {black on black}
  219.     30: AvAttr := (AvAttr and $F8) or Black;
  220.     31: AvAttr := (AvAttr and $F8) or Red;
  221.     32: AvAttr := (AvAttr and $F8) or Green;
  222.     33: AvAttr := (AvAttr and $F8) or Brown;
  223.     34: AvAttr := (AvAttr and $F8) or Blue;
  224.     35: AvAttr := (AvAttr and $F8) or Magenta;
  225.     36: AvAttr := (AvAttr and $F8) or Cyan;
  226.     37: AvAttr := (AvAttr and $F8) or LightGray;
  227.     40: AvAttr := (AvAttr and $8F) or (Black shl 4);
  228.     41: AvAttr := (AvAttr and $8F) or (Red shl 4);
  229.     42: AvAttr := (AvAttr and $8F) or (Green shl 4);
  230.     43: AvAttr := (AvAttr and $8F) or (Brown shl 4);
  231.     44: AvAttr := (AvAttr and $8F) or (Blue shl 4);
  232.     45: AvAttr := (AvAttr and $8F) or (Magenta shl 4);
  233.     46: AvAttr := (AvAttr and $8F) or (Cyan shl 4);
  234.     47: AvAttr := (AvAttr and $8F) or (LightGray shl 4);
  235.     End;
  236.   End;
  237.  
  238.  
  239. Procedure ProcCtl(ch:Char);
  240.   Var
  241.     i:  Word;
  242.  
  243.   Begin
  244.   Case ch of
  245.     ';': Begin
  246.          Ansiparmno := Ansiparmno + 1;
  247.          if Ansiparmno > 10 Then
  248.            Ansiparmno := 10;
  249.          End;
  250.     'A': Begin  {cursor up}
  251.          If Ansiparm[1] = 0 Then
  252.            Ansiparm[1] := 1;
  253.          i := WhereY;
  254.          Dec(i,AnsiParm[1]);
  255.          If i < 0 Then
  256.            i := 0;
  257.          GoToXy(WhereX, i);
  258.          AvState := 0;
  259.          End;
  260.     'B': Begin {cursor down}
  261.          If Ansiparm[1] = 0 Then
  262.            AnsiParm[1] := 1;
  263.          GoToXy(WhereX, WhereY + AnsiParm[1]);
  264.          AvState := 0;
  265.          End;
  266.     'C': Begin {cursor right}
  267.          If Ansiparm[1] = 0 Then
  268.            Ansiparm[1] := 1;
  269.          GoToXy(WhereX + AnsiParm[1], WhereY);
  270.          AvState := 0;
  271.          End;
  272.     'D': Begin {cursor left}
  273.          If AnsiParm[1] = 0 Then
  274.             AnsiParm[1] := 1;
  275.          i := WhereX;
  276.          Dec(i, AnsiParm[1]);
  277.          If i < 0 Then
  278.            i := 0;
  279.          GoToXy(i, WhereY);
  280.          AvState := 0;
  281.          End;
  282.     'H','f': {set cursor position}
  283.          Begin
  284.          if Ansiparm[1] = 0 Then
  285.            Ansiparm[1] := 1;
  286.          If Ansiparm[2] = 0 Then
  287.             Ansiparm[2] := 1;
  288.          GoToXy(Ansiparm[2],Ansiparm[1]);
  289.          AvState := 0;
  290.          End;
  291.     'J': Begin
  292.          AvState := 0;
  293.          Case AnsiParm[1] of
  294.            0: Begin {erase to end of screen}
  295.               ClrEol;
  296.               InitializeScrnRegion(1, WhereY + 1, ScrnWidth, ScrnHeight, ' ');
  297.               End;
  298.            1: Begin {erase from start of screen}
  299.               InitializeScrnRegion(1, 1, ScrnWidth, WhereY - 1, ' ');
  300.               InitializeScrnRegion(1, WhereY, WhereX - 1, WhereY, ' ');
  301.               End;
  302.            2: Begin  {clear screen}
  303.               TextAttr := AvAttr;
  304.               ClrScr;
  305.               End;
  306.            End;
  307.          End;
  308.     'K': Begin
  309.          AvState := 0;
  310.          Case AnsiParm[1] of
  311.            0: Begin {clear to end of line}
  312.               ClrEol;
  313.               End;
  314.            1: Begin {clear from start of line}
  315.               InitializeScrnRegion(1, WhereY, WhereX - 1, WhereY, ' ');
  316.               End;
  317.            2: Begin {erase whole line}
  318.               InitializeScrnRegion(1, WhereY ,ScrnWidth, WhereY, ' ');
  319.               End;
  320.            End;
  321.          End;
  322.     's': Begin {save cursor position}
  323.          SaveX := WhereX;
  324.          SaveY := WhereY;
  325.          AvState := 0;
  326.          End;
  327.     'u': Begin {restore cursor position}
  328.          GoToXy(SaveX, SaveY);
  329.          AvState := 0;
  330.          End;
  331.     'm': Begin {set color attribute}
  332.          AvState := 0;
  333.          If AnsiParmNo > 0 Then
  334.            For i := 1 to AnsiParmNo Do
  335.              ColorParm(AnsiParm[i]);
  336.          TextAttr := AvAttr;
  337.          End;
  338.     'P': Begin {delete characters}
  339.          AvState := 0;
  340.          If AnsiParm[1] = 0 Then
  341.            AnsiParm[1] := 1;
  342.          For i := 1 to AnsiParm[1] Do
  343.            DelCharInLine(WhereX, WhereY);
  344.          End;
  345.     '@': Begin {insert characters}
  346.          AvState := 0;
  347.          If AnsiParm[1] = 0 Then
  348.            AnsiParm[1] := 1;
  349.          For i := 1 to AnsiParm[1] Do
  350.            InsCharInLine(WhereX, WhereY, ' ');
  351.          End;
  352.     'M': Begin {delete lines or "ansi" music}
  353.          If ((AnsiParmNo = 1) and (AnsiParm[1] = 0)) Then
  354.            Begin
  355.            AvState := 12;
  356.            MusicStr := '';
  357.            End
  358.          Else
  359.            Begin
  360.            AvState := 0;
  361.            If AnsiParm[1] = 0 Then
  362.              AnsiParm[1] := 1;
  363.            ScrollScrnRegionUp(1, WhereY + 1, ScrnWidth, ScrnHeight, AnsiParm[1]);
  364.            End;
  365.          End;
  366.     'L': Begin {insert lines}
  367.          AvState := 0;
  368.          If AnsiParm[1] = 0 Then
  369.            AnsiParm[1] := 1;
  370.          ScrollScrnRegionDown(1, WhereY, ScrnWidth, ScrnHeight, AnsiParm[1]);
  371.          End;
  372.     Else
  373.       AvState := 0;
  374.     End;
  375.   End;
  376.  
  377.  
  378. Procedure Accum(ch: Char);
  379.   Begin
  380.   AnsiParm[AnsiParmNo] := (AnsiParm[AnsiParmNo] * 10)  + (Ord(ch) - 48);
  381.   End;
  382.  
  383.  
  384. Procedure MusicChar(ch: Char);
  385.   Begin
  386.   Case ch of
  387.     #27: AvState := 1;
  388.     #$0e: AvState := 0;
  389.     #13: Begin
  390.          If Length(MusicStr) > 0 Then
  391.            Begin
  392.            If AnsiSoundOn Then
  393.              Play(MusicStr);
  394.            MusicStr := '';
  395.            End;
  396.          End;
  397.     #10:;
  398.     Else
  399.       Begin
  400.       If ch in MusicCh Then
  401.         Begin
  402.         If Length(MusicStr) > 120 Then
  403.           Begin
  404.           If AnsiSoundOn Then
  405.             Play(MusicStr);
  406.           MusicStr := '';
  407.           End;
  408.         Inc(MusicStr[0]);
  409.         MusicStr[Length(MusicStr)] := ch;
  410.         End
  411.       Else
  412.         Begin
  413.         AVState := 0;
  414.         End;
  415.       End;
  416.     End;
  417.   If ((AvState < 12) and (Length(MusicStr) > 0)) Then
  418.     Begin
  419.     If AnsiSoundOn Then
  420.       Play(MusicStr);
  421.     MusicStr := '';
  422.     End;
  423.   End;
  424.  
  425.  
  426. Procedure AvatarChar(ch:Char);
  427.   Var
  428.     i: Word;
  429.  
  430.   Begin
  431.   Case AvState of
  432.     0: Begin
  433.        Case ch of
  434.          #027: AvState := 1;
  435.          #012: AvReset;                      {^L - Avatar}
  436.          #025: AvState := 5;                 {^Y - Avatar}
  437.          #022: AvState := 7;                 {^V - Avatar}
  438.          Else
  439.            If InsertMode Then
  440.              InsCharInLine(WhereX, WhereY, ch);
  441.            Write(ch);
  442.          End;
  443.        End;
  444.     1: Begin
  445.        Case ch of
  446.          #27: Begin
  447.               AvState := 1;
  448.               If InsertMode Then
  449.                 InsCharInLine(WhereX, WhereY, #27);
  450.               Write(#27);
  451.               End;
  452.          '[': Begin
  453.               AvState := 2;
  454.               AnsiParmNo := 1;
  455.               For i := 1 To 10 Do
  456.                 Ansiparm[i] := 0;
  457.               End;
  458.          #12: Begin
  459.               AvReset;
  460.               AvState := 0;
  461.               End;
  462.          #25: Begin
  463.               If InsertMode Then
  464.                 InsCharInLine(WhereX, WhereY, #27);
  465.               Write(#27);
  466.               AvState := 5;
  467.               End;
  468.          #22: Begin
  469.               If InsertMode Then
  470.                 InsCharInLine(WhereX, WhereY, #27);
  471.               Write(#27);
  472.               AvState := 6;
  473.               End
  474.          Else
  475.            Begin
  476.            If InsertMode Then
  477.              InsCharInLine(WhereX, WhereY, #27);
  478.            Write(#27);
  479.            If InsertMode Then
  480.              InsCharInLine(WhereX, WhereY, ch);
  481.            Write(ch);
  482.            AvState := 0;
  483.            End;
  484.          End;
  485.        End;
  486.     2: Begin
  487.        Case ch of
  488.          #27: Begin
  489.               AvState := 1;
  490.               If InsertMode Then
  491.                 InsCharInLine(WhereX, WhereY, #27);
  492.               Write(#27);
  493.               If InsertMode Then
  494.                 InsCharInLine(WhereX, WhereY, '[');
  495.               Write('[');
  496.               End;
  497.          '0' .. '9': Accum(ch);
  498.          Else
  499.            If ch in ControlCh Then
  500.              ProcCtl(ch)
  501.            Else
  502.              AvState :=0;
  503.          End;
  504.        End;
  505.     5: Begin
  506.        AnsiParm[1] := Ord(ch);
  507.        AvState := 6;
  508.        End;
  509.     6: Begin
  510.        AvState := 0;
  511.        i := 1;
  512.        While i <= Ord(ch) Do
  513.          Begin
  514.          If InsertMode Then
  515.            InsCharInLine(WhereX, WhereY, Chr(AnsiParm[1]));
  516.          Write(Chr(AnsiParm[1]));
  517.          Inc(i);
  518.          End;
  519.        End;
  520.     7: Begin
  521.        Case ch of
  522.          #001: AvState := 8;                 {^V^A}
  523.          #002: Begin
  524.                AvAttr := AvAttr or Blink;    {^B}
  525.                InsertMode := False;
  526.                AvState := 0;
  527.                End;
  528.          #003: Begin
  529.                If WhereY > 1 Then            {^C}
  530.                  GoToXy(WhereX, WhereY - 1);
  531.                InsertMode := False;
  532.                AvState := 0;
  533.                End;
  534.          #004: Begin
  535.                GoToXy(WhereX, WhereY + 1);   {^D}
  536.                InsertMode := False;
  537.                AvState := 0;
  538.                End;
  539.          #005: Begin
  540.                GoToXy(WhereX + 1, WhereY);   {^E}
  541.                InsertMode := False;
  542.                AvState := 0;
  543.                End;
  544.          #006: Begin
  545.                If WhereX > 1 Then            {^F}
  546.                  GoToXy(WhereX - 1, WhereY);
  547.                InsertMode := False;
  548.                AvState := 0;
  549.                End;
  550.          #007: Begin
  551.                ClrEol;                       {^G}
  552.                InsertMode := False;
  553.                AvState := 0;
  554.                End;
  555.          #008: AvState := 9;                 {^H}
  556.          #009: Begin
  557.                InsertMode := True;           {^I}
  558.                AvState := 0;
  559.                End;
  560.          #010: Begin                         {^J}
  561.                AvState := 11;
  562.                RemainingParms := 5;
  563.                CommandType := 1;
  564.                InsertMode := False;
  565.                AnsiParmNo := 1;
  566.                End;
  567.          #011: Begin                         {^K}
  568.                AvState := 11;
  569.                RemainingParms := 5;
  570.                CommandType := 2;
  571.                InsertMode := False;
  572.                AnsiParmNo := 1;
  573.                End;
  574.          #012: Begin                         {^L}
  575.                AvState := 11;
  576.                RemainingParms := 3;
  577.                CommandType := 3;
  578.                InsertMode := False;
  579.                AnsiParmNo := 1;
  580.                End;
  581.          #013: Begin                         {^M}
  582.                AvState := 11;
  583.                RemainingParms := 4;
  584.                CommandType := 4;
  585.                InsertMode := False;
  586.                AnsiParmNo := 1;
  587.                End;
  588.          #014: Begin
  589.                DelCharInLine(WhereX, WhereY);{^N}
  590.                InsertMode := False;
  591.                AvState := 0;
  592.                End;
  593.          #025: Begin                         {^Y}
  594.                AvState := 11;
  595.                RemainingParms := 1;
  596.                CommandType := 5;
  597.                AnsiParmNo := 1;
  598.                End;
  599.          End;
  600.        End;
  601.     8: Begin                                 {^V^A}
  602.        AvAttr := Ord(ch);
  603.        TextAttr := AvAttr;
  604.        AvState := 0;
  605.        InsertMode := False;
  606.        End;
  607.     9: Begin                                 {^V^H}
  608.        AvState := 10;
  609.        AnsiParm[1] := Ord(ch);
  610.        End;
  611.     10:Begin                                 {^V^H#}
  612.        AvState := 0;
  613.        GoToXy(Ord(ch), AnsiParm[1]);
  614.        InsertMode := False;
  615.        End;
  616.     11:Begin
  617.        AnsiParm[AnsiParmNo] := Ord(ch);
  618.        Inc(AnsiParmNo);
  619.        If AnsiParmNo > MaxParms Then
  620.          AnsiParmNo := MaxParms;
  621.        Dec(RemainingParms);
  622.        If RemainingParms < 1 Then
  623.          Begin
  624.          Case CommandType of
  625.            1: Begin                         {^V^J}
  626.               ScrollScrnRegionUp(AnsiParm[3], AnsiParm[2], AnsiParm[5],
  627.                 AnsiParm[4], AnsiParm[1]);
  628.               AvState := 0;
  629.               End;
  630.            2: Begin                         {^V^K}
  631.               ScrollScrnRegionDown(AnsiParm[3], AnsiParm[2], AnsiParm[5],
  632.                 AnsiParm[4], AnsiParm[1]);
  633.               AvState := 0;
  634.               End;
  635.            3: Begin                         {^V^L}
  636.               TextAttr := AnsiParm[1];
  637.               InitializeScrnRegion(WhereX, WhereY, WhereX + AnsiParm[3],
  638.                 WhereY + AnsiParm[2], ' ');
  639.               AvState := 0;
  640.               End;
  641.            4: Begin                         {^V^M}
  642.               TextAttr := AnsiParm[1];
  643.               InitializeScrnRegion(WhereX, WhereY, WhereX + AnsiParm[4],
  644.                 WhereY + AnsiParm[3], Chr(AnsiParm[2]));
  645.               AvState := 0;
  646.               End;
  647.            5: Begin                         {Have num chars swith to 6}
  648.               RemainingParms := Ord(Ch) + 2;
  649.               CommandType := 6;
  650.               End;
  651.            6: Begin                         {^V^Y}
  652.               RepCount := AnsiParm[AnsiParmNo - 1];
  653.               While RepCount > 0 Do
  654.                 Begin
  655.                 AnsiParmNo := 2;
  656.                 While AnsiParmNo < (AnsiParm[1]+ 3) Do
  657.                   Begin
  658.                   Write(Chr(AnsiParm[AnsiParmNo]));
  659.                   Inc(AnsiParmNo);
  660.                   End;
  661.                 Dec(RepCount);
  662.                 End;
  663.               AvState := 0;
  664.               End;
  665.            End;
  666.          End;
  667.        End;
  668.     12:Begin {"ansi" music}
  669.        Case ch of
  670.          'F': AvState := 13;
  671.          'B': AvState := 13;
  672.          Else
  673.            Begin
  674.            AvState := 13;
  675.            MusicChar(UpCase(ch));
  676.            End;
  677.          End;
  678.        End;
  679.     13:Begin {"Ansi" music after F/B}
  680.        MusicChar(UpCase(ch));
  681.        End;
  682.     End;
  683.   End;
  684.  
  685.  
  686.  
  687. Begin
  688. AvInit;
  689. End.
  690.  
  691.  
  692.