home *** CD-ROM | disk | FTP | other *** search
- program FastANSI;
-
- {$R-,S-,B-,A-,F-,Q-,V-}
-
- {FAST! Buffered ANSI viewer--almost good enough for someone who wants to
- view ANSI files without ever loading ANSI.SYS.
-
- Plusses:
- - Don't hafta load ANSI.SYS
- - SAFE: Beeps if there's a key-redefine, and won't change the screen
- mode
- - Almost as fast as the real thing--the difference is probably not even
- noticed on a fast computer, except for with HUGE files.
-
- Minuses:
- - Takes up more disk space (but doesn't everything? :-)
- - Still not as fast as the real thing.
- - Currently the code is a bit sloppy and probably hard to read
- (I can read it, but then I helped write it. . . .)
- * I've since given cleaner formatting to the code, but it's still
- a bit tough to read, and isn't fully commented. The style is
- pretty dirty, and optimization could help it a lot.
-
- Yes, one of my *next* plans for this thing is to optimize, organize, and
- comment the source
-
- Coauthored by: Ben Kimball (Kzinti@Platte.UNK.edu)
- Scott Earnest (scott@whiplash.pc.cc.cmu.edu)
- }
-
- uses CRT, DOS;
-
- const
- IBMColor : array [0 .. 7] of byte =
- (0,4,2,6,1,5,3,7);
- Tone = 2500;
- Duration = 250;
- buflen = 2047;
-
- var {EEEEK!--it's possible not all of these are used. . . .}
- ch, lastch, inqchar : char;
- f : file;
- Fileinfo : searchrec;
- bytesread : word;
- bufloc : word;
- ANSIbuf : array [0 .. buflen] of byte;
- FName : string[80];
- commandfetch, numsread : boolean;
- ANSIParam : array[1 .. 16] of string;
- index, ANSIPcount, loop, semicount : byte;
- blink, reverse, bold : boolean;
- tmpx, tmpy,
- savecurx, savecury,
- fgcolor, bgcolor : byte;
- vidpage : byte absolute $0000:0462;
- ncols : byte absolute $0000:$044a;
- nrows : byte;
- numbytes : longint;
-
- function value(st : string) : integer;
-
- Var
- dummy,v : integer;
-
- begin
- val (st,v,dummy);
- value := v;
- end;
-
- procedure outchar (ch : char);
-
- var
- xp, yp : byte;
- mp : word;
-
- begin
- xp := WhereX;
- yp := WhereY;
- case ch of
- #13 : exit;
- #10 : xp := ncols;
- else
- begin
- mp := ((yp-1)*ncols+xp-1)*2;
- mem[SegB800:mp] := ord(ch);
- mem[SegB800:mp+1] := textattr;
- end
- end;
- inc(xp);
- if xp > ncols then
- begin
- xp := 1;
- inc(yp);
- end;
- GotoXY (xp,yp);
- end;
-
- procedure inchar (var ch : char);
-
- begin
- if bufloc = 0 then
- BlockRead (f,ANSIbuf,buflen+1,bytesread);
- ch := chr(ANSIbuf[bufloc]);
- inc (bufloc);
- inc (numbytes);
- if (bufloc >= bytesread) then
- bufloc := 0;
- end;
-
- procedure execcode;
-
- begin
- Case Ch of
- 'H','f' : {Cursor Position}
- begin
- case semicount of
- 0 : case ANSIPcount of
- 0 : GotoXY(1,1);
- else
- GotoXY(1,Value(ANSIParam[1]));
- end;
- 1 : if value(ANSIParam[1]) = 0 then
- GotoXY(Value(ANSIParam[2]),1)
- else
- GotoXY(Value(ANSIParam[2]),Value(ANSIParam[1]));
- end;
- end;
-
- 'A' : {Cursor Up}
- if ANSIPcount < 1 then
- begin
- if WhereY > 1 then
- GotoXY(WhereX, WhereY - 1)
- end
- else
- if WhereY - Value(ANSIParam[1]) < 1 then
- GotoXY(WhereX, 1)
- else
- GotoXY(WhereX, WhereY - Value(ANSIParam[1]));
-
- 'B' : {Cursor Down}
- if ANSIPcount < 1 then
- begin
- if WhereY < nrows then
- GotoXY(WhereX, WhereY + 1)
- end
- else
- if WhereY + Value(ANSIParam[1]) > nrows then
- GotoXY(WhereX, nrows)
- else
- GotoXY(WhereX, WhereY + Value(ANSIParam[1]));
-
- 'C' : {Cursor Forward}
- if ANSIPCount < 1 then
- begin
- if WhereX < ncols then
- GotoXY(WhereX + 1, WhereY)
- end
- else
- if WhereX + Value(ANSIParam[1]) > ncols then
- GotoXY(ncols, WhereY)
- else
- GotoXY(WhereX + Value(ANSIParam[1]), WhereY);
-
- 'D' : {Cursor Backward}
- if ANSIPcount < 1 then
- begin
- if WhereX > 1 then
- GotoXY(WhereX - 1, WhereY)
- end
- else
- if WhereX - Value(ANSIParam[1]) < 1 then
- GotoXY(1, WhereY)
- else
- GotoXY(WhereX - Value(ANSIParam[1]), WhereY);
-
- 'p' : {Key-redefine}
- begin
- Sound (Tone);
- Delay (Duration);
- NoSound;
- end;
-
- 's' : {Save Cursor Position}
- begin
- SaveCurX := WhereX;
- SaveCurY := WhereY;
- end;
-
- 'u' : {Restore Cursor Position}
- GotoXY(SaveCurX, SaveCurY);
-
- 'J' : {Erase Display (if ESC[2J ) }
- ClrScr;
-
- 'K' : {Erase Line}
- ClrEol;
-
- 'm' : {Set Graphics Mode}
- for Loop := 1 to AnsiPCount do
- case value(ANSIParam[Loop]) of
- 0 : {All Attributes Off}
- begin
- Blink := false;
- Reverse := false;
- Bold := false;
- TextAttr := $07;
- FGColor := 7;
- BGColor := 0;
- end;
- 1 : {Bold On}
- begin
- Bold := true;
- TextAttr := (TextAttr or $08);
- end;
- 4 : {Underscore - ignored};
- 5 : {Blink On}
- begin
- TextAttr := (TextAttr or $80);
- Blink := true;
- end;
- 7 : {Reverse Video}
- begin
- Reverse := true;
- if FGColor > 7 then
- FGColor := 8
- else FGColor := 0;
- BGColor := 7;
- TextColor(FGColor);
- TextBackGround(BGColor);
- end;
-
- 30 .. 37 : {Foreground}
- begin
- FGColor := IBMColor[Value(ANSIParam[Loop]) - 30];
- TextAttr := BGColor * 16 + FGColor;
- if blink then TextAttr := TextAttr or $80;
- if bold then TextAttr := TextAttr or $08;
- end;
-
- 40 .. 47 : {Background}
- begin
- BGColor := IBMColor[Value(ANSIParam[Loop]) - 40];
- TextAttr := BGColor * 16 + FGColor;
- if blink then TextAttr := TextAttr or $80;
- if bold then TextAttr := TextAttr or $08;
- end;
- end; {Case}
-
- end; {Case}
- end;
-
- procedure readANSIdata;
-
- begin
- inchar (ch);
- case ch of
- '0' .. '9' : begin
- ANSIParam[ANSIPcount] := ANSIParam[ANSIPcount] + ch;
- numsread := true;
- end;
- '"' : repeat
- inchar (inqchar);
- until inqchar = '"';
- ';' : begin
- inc(ANSIPcount);
- inc(semicount);
- end;
- else
- begin
- if not numsread then ANSIPCount := 0;
- execcode;
- commandfetch := false;
- end;
- end;
- lastch := ch;
- end;
-
- procedure parseANSI;
-
- begin
- fillchar (ANSIParam, sizeof(ANSIParam), 0);
- ANSIPcount := 1;
- semicount := 0;
- commandfetch := true;
- numsread := false;
- repeat
- readANSIdata;
- until not commandfetch;
- end;
-
- begin
- nrows := mem[$0000:$0484] + 1;
- TextAttr := $0f;
- semicount := 0;
- SaveCurX := 1;
- SaveCurY := 1;
- Bold := false;
- Blink := false;
- Reverse := false;
- ANSIPcount := 0; {No Params}
- FGColor := 7; {Light Grey}
- BGColor := 0; {Black}
- numsread := false;
- commandfetch := false;
- bufloc := 0;
- numbytes := 0;
- bytesread := 0;
- fillchar (ANSIbuf, sizeof(ANSIbuf), 0);
- if ParamStr(1) = '' then
- begin
- write ('Enter Filename: ');
- readln (FName);
- end
- else
- FName := ParamStr(1);
- findfirst (FName, AnyFile, fileinfo);
- if fileinfo.name = '' then
- begin
- writeln ('File not found.');
- halt;
- end;
- assign (F, FName);
- reset (F,1);
- clrscr;
- while (numbytes < fileinfo.size) do
- begin
- inchar (ch);
- if ch = #27 then
- begin
- lastch := ch;
- inchar (ch);
- if ch <> '[' then
- begin
- outchar (lastch);
- outchar (ch);
- end
- else {parse}
- parseANSI;
- end
- else
- outchar (ch);
- end;
- readln;
- close (f);
- end.