home *** CD-ROM | disk | FTP | other *** search
/ POINT Software Programming / PPROG1.ISO / pascal / swag / ansi.swg / 0033_Pascal ANSI Engine.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1995-03-26  |  9.5 KB  |  347 lines

  1. program FastANSI;
  2.  
  3. {$R-,S-,B-,A-,F-,Q-,V-}
  4.  
  5. {FAST!  Buffered ANSI viewer--almost good enough for someone who wants to
  6.  view ANSI files without ever loading ANSI.SYS.
  7.  
  8.  Plusses:
  9.    - Don't hafta load ANSI.SYS
  10.    - SAFE:  Beeps if there's a key-redefine, and won't change the screen
  11.             mode
  12.    - Almost as fast as the real thing--the difference is probably not even
  13.      noticed on a fast computer, except for with HUGE files.
  14.  
  15.  Minuses:
  16.    - Takes up more disk space (but doesn't everything?  :-)
  17.    - Still not as fast as the real thing.
  18.    - Currently the code is a bit sloppy and probably hard to read
  19.      (I can read it, but then I helped write it. . . .)
  20.      * I've since given cleaner formatting to the code, but it's still
  21.        a bit tough to read, and isn't fully commented.  The style is
  22.        pretty dirty, and optimization could help it a lot.
  23.  
  24.  Yes, one of my *next* plans for this thing is to optimize, organize, and
  25.  comment the source
  26.  
  27.  Coauthored by:  Ben Kimball (Kzinti@Platte.UNK.edu)
  28.                  Scott Earnest (scott@whiplash.pc.cc.cmu.edu)
  29. }
  30.  
  31. uses CRT, DOS;
  32.  
  33. const
  34.   IBMColor : array [0 .. 7] of byte =
  35.     (0,4,2,6,1,5,3,7);
  36.   Tone = 2500;
  37.   Duration = 250;
  38.   buflen = 2047;
  39.  
  40. var  {EEEEK!--it's possible not all of these are used. . . .}
  41.   ch, lastch, inqchar : char;
  42.   f : file;
  43.   Fileinfo : searchrec;
  44.   bytesread : word;
  45.   bufloc : word;
  46.   ANSIbuf : array [0 .. buflen] of byte;
  47.   FName : string[80];
  48.   commandfetch, numsread : boolean;
  49.   ANSIParam : array[1 .. 16] of string;
  50.   index, ANSIPcount, loop, semicount : byte;
  51.   blink, reverse, bold : boolean;
  52.   tmpx, tmpy,
  53.   savecurx, savecury,
  54.   fgcolor, bgcolor : byte;
  55.   vidpage : byte absolute $0000:0462;
  56.   ncols : byte absolute $0000:$044a;
  57.   nrows : byte;
  58.   numbytes : longint;
  59.  
  60. function value(st : string) : integer;
  61.  
  62. Var
  63.   dummy,v : integer;
  64.  
  65. begin
  66.   val (st,v,dummy);
  67.   value := v;
  68. end;
  69.  
  70. procedure outchar (ch : char);
  71.  
  72. var
  73.   xp, yp : byte;
  74.   mp : word;
  75.  
  76. begin
  77.   xp := WhereX;
  78.   yp := WhereY;
  79.   case ch of
  80.     #13 : exit;
  81.     #10 : xp := ncols;
  82.   else
  83.     begin
  84.       mp := ((yp-1)*ncols+xp-1)*2;
  85.       mem[SegB800:mp] := ord(ch);
  86.       mem[SegB800:mp+1] := textattr;
  87.     end
  88.   end;
  89.   inc(xp);
  90.   if xp > ncols then
  91.     begin
  92.       xp := 1;
  93.       inc(yp);
  94.     end;
  95.   GotoXY (xp,yp);
  96. end;
  97.  
  98. procedure inchar (var ch : char);
  99.  
  100. begin
  101.   if bufloc = 0 then
  102.     BlockRead (f,ANSIbuf,buflen+1,bytesread);
  103.   ch := chr(ANSIbuf[bufloc]);
  104.   inc (bufloc);
  105.   inc (numbytes);
  106.   if (bufloc >= bytesread) then
  107.     bufloc := 0;
  108. end;
  109.  
  110. procedure execcode;
  111.  
  112. begin
  113.   Case Ch of
  114.     'H','f' : {Cursor Position}
  115.               begin
  116.                 case semicount of
  117.                   0 : case ANSIPcount of
  118.                         0 : GotoXY(1,1);
  119.                       else
  120.                         GotoXY(1,Value(ANSIParam[1]));
  121.                       end;
  122.                   1 : if value(ANSIParam[1]) = 0 then
  123.                         GotoXY(Value(ANSIParam[2]),1)
  124.                       else
  125.                         GotoXY(Value(ANSIParam[2]),Value(ANSIParam[1]));
  126.                 end;
  127.               end;
  128.  
  129.         'A' : {Cursor Up}
  130.               if ANSIPcount < 1 then
  131.                 begin
  132.                   if WhereY > 1 then
  133.                     GotoXY(WhereX, WhereY - 1)
  134.                 end
  135.               else
  136.                 if WhereY - Value(ANSIParam[1]) < 1 then
  137.                   GotoXY(WhereX, 1)
  138.                 else
  139.                   GotoXY(WhereX, WhereY - Value(ANSIParam[1]));
  140.  
  141.         'B' : {Cursor Down}
  142.               if ANSIPcount < 1 then
  143.                 begin
  144.                   if WhereY < nrows then
  145.                     GotoXY(WhereX, WhereY + 1)
  146.                 end
  147.               else
  148.                 if WhereY + Value(ANSIParam[1]) > nrows then
  149.                   GotoXY(WhereX, nrows)
  150.                 else
  151.                   GotoXY(WhereX, WhereY + Value(ANSIParam[1]));
  152.  
  153.         'C' : {Cursor Forward}
  154.               if ANSIPCount < 1 then
  155.                 begin
  156.                   if WhereX < ncols then
  157.                     GotoXY(WhereX + 1, WhereY)
  158.                 end
  159.               else
  160.                 if WhereX + Value(ANSIParam[1]) > ncols then
  161.                   GotoXY(ncols, WhereY)
  162.                 else
  163.                   GotoXY(WhereX + Value(ANSIParam[1]), WhereY);
  164.  
  165.         'D' : {Cursor Backward}
  166.               if ANSIPcount < 1 then
  167.                 begin
  168.                   if WhereX > 1 then
  169.                     GotoXY(WhereX - 1, WhereY)
  170.                 end
  171.               else
  172.                 if WhereX - Value(ANSIParam[1]) < 1 then
  173.                   GotoXY(1, WhereY)
  174.                 else
  175.                   GotoXY(WhereX - Value(ANSIParam[1]), WhereY);
  176.  
  177.         'p' : {Key-redefine}
  178.               begin
  179.                 Sound (Tone);
  180.                 Delay (Duration);
  181.                 NoSound;
  182.               end;
  183.  
  184.         's' : {Save Cursor Position}
  185.               begin
  186.                 SaveCurX := WhereX;
  187.                 SaveCurY := WhereY;
  188.               end;
  189.  
  190.         'u' : {Restore Cursor Position}
  191.               GotoXY(SaveCurX, SaveCurY);
  192.  
  193.         'J' : {Erase Display (if ESC[2J ) }
  194.               ClrScr;
  195.  
  196.         'K' : {Erase Line}
  197.               ClrEol;
  198.  
  199.         'm' : {Set Graphics Mode}
  200.               for Loop := 1 to AnsiPCount do
  201.                 case value(ANSIParam[Loop]) of
  202.                          0 : {All Attributes Off}
  203.                              begin
  204.                                Blink   := false;
  205.                                Reverse := false;
  206.                                Bold    := false;
  207.                                TextAttr := $07;
  208.                                FGColor := 7;
  209.                                BGColor := 0;
  210.                              end;
  211.                          1 : {Bold On}
  212.                              begin
  213.                                Bold := true;
  214.                                TextAttr := (TextAttr or $08);
  215.                              end;
  216.                          4 : {Underscore - ignored};
  217.                          5 : {Blink On}
  218.                              begin
  219.                                TextAttr := (TextAttr or $80);
  220.                                Blink := true;
  221.                              end;
  222.                          7 : {Reverse Video}
  223.                              begin
  224.                                Reverse := true;
  225.                                if FGColor > 7 then
  226.                                  FGColor := 8
  227.                                else FGColor := 0;
  228.                                BGColor := 7;
  229.                                TextColor(FGColor);
  230.                                TextBackGround(BGColor);
  231.                              end;
  232.  
  233.                   30 .. 37 : {Foreground}
  234.                              begin
  235.                                FGColor := IBMColor[Value(ANSIParam[Loop]) - 30];
  236.                                TextAttr := BGColor * 16 + FGColor;
  237.                                if blink then TextAttr := TextAttr or $80;
  238.                                if bold then TextAttr := TextAttr or $08;
  239.                              end;
  240.  
  241.                   40 .. 47 : {Background}
  242.                              begin
  243.                                BGColor := IBMColor[Value(ANSIParam[Loop]) - 40];
  244.                                TextAttr := BGColor * 16 + FGColor;
  245.                                if blink then TextAttr := TextAttr or $80;
  246.                                if bold then TextAttr := TextAttr or $08;
  247.                              end;
  248.                 end; {Case}
  249.  
  250.   end; {Case}
  251. end;
  252.  
  253. procedure readANSIdata;
  254.  
  255. begin
  256.   inchar (ch);
  257.   case ch of
  258.     '0' .. '9' : begin
  259.                    ANSIParam[ANSIPcount] := ANSIParam[ANSIPcount] + ch;
  260.                    numsread := true;
  261.                  end;
  262.            '"' : repeat
  263.                    inchar (inqchar);
  264.                  until inqchar = '"';
  265.            ';' : begin
  266.                    inc(ANSIPcount);
  267.                    inc(semicount);
  268.                  end;
  269.   else
  270.     begin
  271.       if not numsread then ANSIPCount := 0;
  272.       execcode;
  273.       commandfetch := false;
  274.     end;
  275.   end;
  276.   lastch := ch;
  277. end;
  278.  
  279. procedure parseANSI;
  280.  
  281. begin
  282.   fillchar (ANSIParam, sizeof(ANSIParam), 0);
  283.   ANSIPcount := 1;
  284.   semicount := 0;
  285.   commandfetch := true;
  286.   numsread := false;
  287.   repeat
  288.     readANSIdata;
  289.   until not commandfetch;
  290. end;
  291.  
  292. begin
  293.   nrows := mem[$0000:$0484] + 1;
  294.   TextAttr := $0f;
  295.   semicount := 0;
  296.   SaveCurX   := 1;
  297.   SaveCurY   := 1;
  298.   Bold       := false;
  299.   Blink      := false;
  300.   Reverse    := false;
  301.   ANSIPcount := 0; {No Params}
  302.   FGColor    := 7; {Light Grey}
  303.   BGColor    := 0; {Black}
  304.   numsread := false;
  305.   commandfetch := false;
  306.   bufloc := 0;
  307.   numbytes := 0;
  308.   bytesread := 0;
  309.   fillchar (ANSIbuf, sizeof(ANSIbuf), 0);
  310.   if ParamStr(1) = '' then
  311.     begin
  312.       write ('Enter Filename: ');
  313.       readln (FName);
  314.     end
  315.   else
  316.     FName := ParamStr(1);
  317.   findfirst (FName, AnyFile, fileinfo);
  318.   if fileinfo.name = '' then
  319.     begin
  320.       writeln ('File not found.');
  321.       halt;
  322.     end;
  323.   assign (F, FName);
  324.   reset (F,1);
  325.   clrscr;
  326.   while (numbytes < fileinfo.size) do
  327.     begin
  328.       inchar (ch);
  329.       if ch = #27 then
  330.         begin
  331.           lastch := ch;
  332.           inchar (ch);
  333.           if ch <> '[' then
  334.             begin
  335.               outchar (lastch);
  336.               outchar (ch);
  337.             end
  338.           else {parse}
  339.             parseANSI;
  340.         end
  341.       else
  342.         outchar (ch);
  343.     end;
  344.   readln;
  345.   close (f);
  346. end.
  347.