PROGRAM VTType;
{ kleines VideoText-Utility: gibt VT-Dateien als ASCII aus }

FROM vt USES decode;

VAR leer, modulo, nummer: Integer;

FUNCTION getlong(VAR datei: Text): Long;
VAR l: Long;
    i: Integer;
    ch: Char;
BEGIN
  l := 0;
  FOR i := 1 TO 4 DO BEGIN
    Read(datei,ch);
    l := (l SHL 8) OR Ord(ch);
  END;
  getlong := l;
END;

FUNCTION filetype(name: Str80): Integer;
{ Typcodierung: }
{ -1: Datei existiert nicht (oder ist leer) }
{  0: unbekannter Typ (vermutlich roher ASCII-Text) }
{  1: programmeigener Typ 'VTPG'=$56545047 }
{     VTex-Format 'FG24'=$46473234 }
{     oder TeleText 'TELE'=$54454C45 }
{  2: AmigaDOS-Programmdatei $000003F3 }
{  3: IFF-Datei 'FORM'=$464F524D }
{  4: Workbench-Icon $E310 }
VAR head: Long;
    datei: Text;
BEGIN
  Reset(datei,name);
  IF IOresult=0 THEN BEGIN
    filetype := 0;
    IF FileSize(datei)=0 THEN filetype := -1; { leere Datei }
    head := getlong(datei);
    IF head=$56545047 THEN filetype := 1;
    IF head=$46473234 THEN filetype := 1;
    IF head=$54454C45 THEN filetype := 1;
    IF head=$000003F3 THEN filetype := 2;
    IF head=$464F524D THEN filetype := 3;
    IF (head AND $FFFF0000)=$E3100000 THEN filetype := 4;
    Close(datei);
  END ELSE
    filetype := -1; { Datei existiert nicht }
END;

PROCEDURE writepage(seite: p_onepage);
VAR i: Integer;
    s: Str80;
    do_ff: Boolean;
BEGIN
  do_ff := False;
  FOR i := 0 TO 23 DO BEGIN
    makeascii(seite, i, True, s);
    WriteLn(s);
  END;
  Inc(nummer);
  IF modulo>0 THEN
    IF (nummer MOD modulo)=0 THEN do_ff := True;
  IF do_ff THEN
    Write(#12)  { FormFeed }
  ELSE
    FOR i := 1 TO leer DO WriteLn;
END;

FUNCTION getpages(filename: Str80): Integer;
{ Alle VT-Seiten aus einer VTPG-Datei einlesen und am Bildschirm ausgeben. }
{ Rückgabewert: Anzahl der gelesenen Seiten }
VAR i,j, jlpageno, gelesen: Integer;
    bytes: ^ARRAY[1..41] OF Char;
    datei: Text;
    zeile: Str80;
    seite: p_onepage;
    l: Long;
    c: Char;
CONST vtpg=$56545047;
      fg24=$46473234;
      tvtx=$54565458;
      tele=$54454C45;
      texd=$54455854;
       sub=$535542;
PROCEDURE findword;
{ Hilft, zeile in Worte zu zerlegen. Parameter j: Startpunkt, Ergebnis: }
{ i: 1. Zeichen des Wortes, j: 1. Trennzeichen dahinter }
BEGIN
  i := j; WHILE (zeile[i]=' ') AND (zeile[i]<>#0) DO Inc(i);
  j := i + 1; WHILE NOT (zeile[j] IN [' ',#0]) DO Inc(j);
END;
BEGIN
  New(seite);
  gelesen := 0;
  Reset(datei,filename);
  IF (IOresult<>0) THEN     { Datei existiert nicht }
    Exit;
  Buffer(datei,200);
  WHILE NOT EoF(datei) DO BEGIN
    l := 0;
    REPEAT
      Read(datei,c); l := l SHL 8 OR Ord(c);
    UNTIL (l=vtpg) OR (l=fg24) OR (l=tele) OR (l AND $FFFFFF=sub)
    OR EoF(datei);
    { mein eigenes Format lesen: }
    IF l=vtpg THEN BEGIN
      Read(datei,c); { LF überlesen }
      FOR i := 0 TO 23 DO BEGIN
        bytes := Ptr(^seite^.chars[40*i]);
        BlockRead(datei,bytes^,40);
        Read(datei,c); { LF überlesen }
      END;
      ReadLn(datei,zeile); j := 1;
      findword; seite^.pg := hexval(Copy(zeile,i,j-i));
      findword; seite^.sp := hexval(Copy(zeile,i,j-i));
      findword; seite^.cbits := hexval(Copy(zeile,i,j-i));
      seite^.dejavu := False;
      writepage(seite);
      Inc(gelesen);     
    END;
    { das Format der VTex-Software lesen: }
    IF l=fg24 THEN IF getlong(datei)=tvtx THEN BEGIN
      seite^.pg := make_bcd(getlong(datei));
      seite^.sp := make_bcd(getlong(datei));
      seite^.cbits := 0;
      l := getlong(datei); { aus der Zeichensatz-Nummer die Steuerbits }
      FOR i := 14 DOWNTO 12 DO BEGIN { C12,C13,C14 "rekonstruieren" }
        IF Odd(l) THEN seite^.cbits := seite^.cbits OR (1 SHL i);
        l := l SHR 1;
      END;
      FOR i := 1 TO 18 DO Read(datei,c); { ??? }
      BlockRead(datei,seite^.chars,960);
      seite^.dejavu := False;
      writepage(seite);
      Inc(gelesen);
    END;
    { Jan Leuverink's TeleText-Format lesen: }
    IF l=tele THEN IF getlong(datei)=texd THEN BEGIN  { header }
      jlpageno := 0;
      FOR i := 1 TO 3 DO BEGIN
        Read(datei,c); jlpageno := (jlpageno SHL 4) OR (Ord(c)-Ord('0'));
      END;
    END;
    IF (l AND $FFFFFF=sub) THEN BEGIN  { eine Seite }
      seite^.pg := jlpageno;
      seite^.sp := 0;
      seite^.cbits := $4000;  { immer dt. Zeichensatz %-( }
      FOR i := 1 TO 4 DO BEGIN
        Read(datei,c); IF c>='0' THEN
          seite^.sp := (seite^.sp SHL 4) OR (Ord(c)-Ord('0'));
      END;
      BlockRead(datei,seite^.chars,960);
      seite^.dejavu := False;
      writepage(seite);
      Inc(gelesen);
    END;
  END;
  Close(datei);
  Dispose(seite);
  getpages := gelesen;
END;

PROCEDURE help;
BEGIN
  WriteLn('  VTType [Optionen] <Dateinamen>');
  WriteLn('Optionen sind:');
  WriteLn('  -l<n> : n Leerzeilen zwischen den Seiten');
  WriteLn('  -f<n> : nach jeder n. Seite ein FormFeed ausgeben');
END;

VAR s: ^String[1000];
    total,i,j,len: Integer;
    c: Char;

BEGIN
  IF FromWB THEN BEGIN
    Assign(input,'Con:0/11/640/180/Hello');
    Reset(input);
    output := input;
    WriteLn('Sorry, das hier ist ein reines CLI-Programm. Benutzung:');
    help;
    WriteLn;
    Write('Bitte "Return" drücken! > ');
    ReadLn(c);
    Close(input);
  END ELSE BEGIN
    len := ParameterLen;
    s := ParameterStr;
    total := 0; modulo := 0; nummer := 0; leer := 0;
    i := 1; WHILE i<=len DO BEGIN
      WHILE (s^[i]<=' ') AND (i<=len) DO Inc(i); { Leerzeichen überlesen }
      j := i + 1;
      IF s^[i]='"' THEN BEGIN
        Inc(i); WHILE (s^[j]<>'"') AND (j<=len) DO Inc(j);
      END ELSE BEGIN
        WHILE (s^[j]>' ') AND (j<=len) DO Inc(j);
      END;
      { Zeiger i: 1. Zeichen des Wortes, j: 1. Trennzeichen dahinter }
      IF j>i THEN BEGIN
        IF Copy(s^,i,2) = '-l' THEN BEGIN
          leer := Ord(s^[i+2])-Ord('0');
          IF leer<0 THEN leer := 1;
        END ELSE IF Copy(s^,i,2) = '-f' THEN BEGIN
          modulo := Ord(s^[i+2])-Ord('0');
          IF modulo<0 THEN modulo := 1;
        END ELSE
          total := total + getpages(Copy(s^,i,j-i));
      END;
      i := j + 1;
    END;
    IF total = 0 THEN BEGIN
      WriteLn('Keine VT-Seiten gefunden. Benutzung:');
      help;
    END;
  END;
END.

