home *** CD-ROM | disk | FTP | other *** search
- { Prozeduren, die in VT und VTview in identischer Frorm benötigt werden, }
- { gemeinsame Benutzung der entsprechenden Units wäre aber unökonomisch }
-
- {$if def unit_sys }
-
- PROCEDURE desaster{(meldung: Str80)};
- { erzeugt einen Alert }
- VAR egal: Boolean;
- buf: Str80;
- xpos: Integer;
- BEGIN
- xpos := 320 - 4*Length(meldung);
- buf := ' '+meldung;
- buf[1] := Chr(Hi(xpos)); buf[2] := Chr(Lo(xpos));
- buf[3] := Chr(18);
- buf [Length(meldung)+5] := Chr(0);
- egal := DisplayAlert(RECOVERY_ALERT,buf,32);
- END;
-
- PROCEDURE stretch_line{(zeile, sp0, sp1: Integer)};
- { Streckt eine Textzeile am Bildschirm von sp0 bis einschließlich sp1 auf }
- { doppelte Höhe. }
- { Zeilen und Spalten werden, wie bei GotoXY üblich, ab 1 gezählt! }
- VAR charx,chary,i,y0,x0,breite: Integer;
- BEGIN
- charx := MyWindow^.RPort^.TxWidth;
- chary := MyWindow^.RPort^.TxHeight;
- x0 := (sp0-1)*charx; breite := (sp1-sp0+1)*charx;
- y0 := (zeile-1)*chary;
- FOR i := chary-1 DOWNTO 0 DO BEGIN
- ClipBlit(MyWindow^.RPort,x0,y0+i,MyWindow^.RPort,x0,y0+2*i,breite,1,$C0);
- ClipBlit(MyWindow^.RPort,x0,y0+i,MyWindow^.RPort,x0,y0+2*i+1,breite,1,$C0);
- END;
- END;
-
- PROCEDURE raster_line{(zeile, sp0, sp1: Integer; farbe: Word)};
- { Grafikzeichen einer Zeile in seperate Rasterpunkte zerlegen, dazu dient }
- { Zeichen #159 des videotext.font }
- VAR charx,chary,baseline,y0,x0,i,anz: Integer;
- dummy: str80;
- egal: Long;
- BEGIN
- charx := MyWindow^.RPort^.TxWidth;
- chary := MyWindow^.RPort^.TxHeight;
- baseline := MyWindow^.RPort^.TxBaseline;
- x0 := (sp0-1)*charx; y0 := (zeile-1)*chary + baseline;
- anz := sp1-sp0+1;
- FOR i := 1 TO anz DO dummy[i] := #159;
- SetAPen(MyWindow^.RPort,farbe); SetDrMd(MyWindow^.RPort,JAM1);
- Move(MyWindow^.RPort,x0,y0); egal := _Text(MyWindow^.RPort,dummy,anz);
- END;
-
- { *** ein paar Hilfsroutinen für die Menüerstellung: }
-
- PROCEDURE AddMenu (dx: Integer; name: Str);
- VAR m: p_Menu;
- it: IntuiText;
- x: Integer;
- BEGIN
- x := dx;
- IF LastMenu<>Nil THEN x := x + LastMenu^.LeftEdge + LastMenu^.Width;
- it := IntuiText(0, 1, JAM1, 0, 0, MyWindow^.WScreen^.Font, name, Nil);
- New (m);
- m^ := Menu(Nil, x, 0, IntuiTextLength(^it) + 8,
- MyWindow^.WScreen^.Font^.ta_YSize, MENUENABLED,
- name, Nil, 0, 0, 0, 0);
- IF LastMenu=Nil THEN Strip := m
- ELSE LastMenu^.NextMenu := m;
- LastMenu := m; LastItem := Nil;
- END;
-
- PROCEDURE AddItem (dy: Integer; Flag: Word; name: Str; Com: Char);
- VAR i: p_MenuItem;
- t: p_IntuiText;
- w,y: Integer;
- BEGIN
- IF LastMenu=Nil THEN Error('MenItem without Menu!');
- y := dy;
- IF LastItem<>Nil THEN y := y + LastItem^.TopEdge + LastItem^.Height;
- New(i); New(t);
- IF com>' ' THEN Flag := Flag OR COMMSEQ;
- t^ := IntuiText(0,1, JAM1, 2,1, MyWindow^.WScreen^.Font, name, Nil);
- w := IntuiTextLength(t);
- i^ := MenuItem(Nil, 0,y, w + 4,MyWindow^.WScreen^.Font^.ta_YSize + 2,
- Flag OR ITEMTEXT OR ITEMENABLED OR HIGHCOMP,
- 0, t, Nil, Com, Nil, 0);
- IF LastItem=Nil THEN LastMenu^.FirstItem := i
- ELSE LastItem^.NextItem := i;
- LastItem := i; LastSubItem := Nil;
- END;
-
- PROCEDURE AddSubItem (dy: Integer; Flag: Word; name: Str; Com: Char);
- VAR s: p_MenuItem;
- t: p_IntuiText;
- w,y: Integer;
- BEGIN
- IF LastItem=Nil THEN Error('SubItem without MenItem');
- y := dy;
- IF LastSubItem<>Nil THEN y := y + LastSubItem^.TopEdge + LastSubItem^.Height;
- New(s); New(t);
- If com>' ' THEN Flag := Flag OR COMMSEQ;
- t^ := IntuiText(0,1, JAM1, 2,1, MyWindow^.WScreen^.Font, name, Nil);
- w := IntuiTextLength(t);
- s^ := MenuItem(Nil, LastItem^.Width-12, y, w+4,MyWindow^.WScreen^.Font^.ta_YSize + 2,
- Flag OR ITEMTEXT OR ITEMENABLED OR HIGHCOMP,
- 0, t, Nil, Com, Nil, 0);
- IF LastSubItem=Nil THEN LastItem^.SubItem := s
- ELSE LastSubItem^.NextItem := s;
- LastSubItem := s;
- END;
-
- PROCEDURE MutEx(exc: LongInt);
- VAR i: p_MenuItem;
- BEGIN
- i := LastItem;
- IF i=Nil THEN Error('no Item for MutEx');
- IF LastSubItem<>Nil THEN i := LastSubItem;
- i^.MutualExclude := exc;
- i^.Flags := i^.Flags AND NOT MENUTOGGLE;
- END;
-
- PROCEDURE ItEnable(really: Boolean);
- VAR i: p_MenuItem;
- BEGIN
- i := LastItem;
- IF i=Nil THEN Error('no Item for ItEnable');
- IF LastSubItem<>Nil THEN i := LastSubItem;
- IF NOT really THEN
- i^.Flags := i^.Flags AND NOT ITEMENABLED;
- END;
-
- PROCEDURE CalcMenuWidth(f: p_MenuItem);
- { alle Einträge einer Menüspalte auf gleiche Breite bringen }
- VAR i: p_MenuItem;
- t: p_IntuiText;
- max, w: Integer;
- BEGIN
- i := f;
- max := 8;
- WHILE i<>Nil DO BEGIN
- t := i^.ItemFill;
- w := 2 + IntuiTextLength(t) + t^.LeftEdge;
- IF i^.Flags AND COMMSEQ<>0 THEN w := w + 48;
- IF w>max THEN max := w;
- i := i^.NextItem;
- END;
- i := f;
- WHILE i<>Nil DO BEGIN
- i^.Width := max
- i := i^.NextItem
- END;
- END;
-
- PROCEDURE MenuWidths;
- { CalcMenuWidth auf alle Menüs und Untermenüs anwenden }
- VAR m: p_Menu;
- i: p_MenuItem;
- BEGIN
- m := Strip;
- WHILE m<>Nil DO BEGIN
- i := m^.FirstItem;
- IF i<>Nil THEN CalcMenuWidth(i);
- WHILE i<>Nil DO BEGIN
- IF i^.SubItem<>Nil THEN
- CalcMenuWidth(i^.SubItem);
- i := i^.NextItem;
- END;
- m := m^.NextMenu;
- END;
- END;
-
- PROCEDURE TrashMenu;
- { die aufgebaute Menü-Struktur wegwerfen }
- VAR m, m2: p_Menu;
- i, i2: p_MenuItem;
- t: p_IntuiText;
- BEGIN
- m := Strip;
- WHILE m<>Nil DO BEGIN
- i := m^.FirstItem;
- WHILE i<>Nil DO BEGIN
- i2 := i;
- t := i^.ItemFill;
- i := i^.NextItem;
- Dispose(t);
- Dispose(i2)
- END;
- m2 := m;
- m := m^.NextMenu;
- Dispose(m2)
- END;
- LastMenu := Nil; Strip := Nil;
- END;
-
- {$endif }
-
- {$if def unit_bildschirm }
-
- PROCEDURE writepage{(seite: p_onepage, verdeckt: Boolean)};
- { Seite am Bildschirm ausgeben }
- VAR zeile,limit,i,j,j0: Integer;
- farbe,farbe0: Word;
- out: bigstring;
- x: Byte;
- s,attrib: str80;
- dblheight,rastergfx,special: Boolean;
- normal: String[10];
- BEGIN
- incomplete := True;
- limit := 24;
- visblpage := seite;
- concealed := verdeckt;
- normal := #155'0;3'+colperms[7]+';4'+colperms[0]+'m'; { weiß auf schwarz }
- dblheight := False; rastergfx := False;
- IF seite<>Nil THEN BEGIN
- IF seite^.pg>0 THEN seite^.chars[0] := 2 { Seitennummer zunächst grün }
- { Seiten "ohne" Seitennummer dürfen sich wünschen, wieviele Zeilen von }
- { ihnen ausgegeben werden sollen: }
- ELSE IF seite^.sp IN [1..24] THEN limit := seite^.sp-1;
- END;
- FOR i := 0 TO limit DO BEGIN
- zeile := i MOD 24;
- IF i=24 THEN BEGIN
- { 1. Zeile nochmal, mit weißer Seitennummer: }
- IF seite<>Nil THEN IF seite^.pg>0 THEN
- seite^.chars[0] := 7;
- dblheight := False;
- END;
- IF dblheight THEN
- { auf eine doppelthohe Zeile folgt nur eine leere Zeile }
- dblheight := False
- ELSE BEGIN
- { normale Zeile ausgeben }
- IF seite<>Nil THEN
- decode_line(seite, zeile, verdeckt, out, attrib, dblheight, rastergfx)
- ELSE
- out := blank40;
- GotoXY(pgoffx,zeile+1); Write(normal,out,normal,' ');
- IF rastergfx THEN BEGIN { Zeile, die gerasterte Grafikzeichen enthält }
- special := False; farbe := 0;
- FOR j := 0 TO 39 DO BEGIN { zu rasternde Abschnitte suchen }
- farbe0 := farbe; farbe := Ord(attrib[j+1]);
- IF (farbe<>farbe0) AND special THEN BEGIN
- raster_line(zeile+1,pgoffx+j0,pgoffx+j-1,farbe0 AND 7);
- j0 := j; special := (farbe AND 16<>0);
- END;
- IF (farbe AND 16<>0) AND NOT special THEN BEGIN
- j0 := j; special := True;
- END;
- END;
- IF special THEN
- raster_line(zeile+1,pgoffx+j0,pgoffx+39,farbe0 AND 7);
- END;
- IF zeile=23 THEN dblheight := False; { unterste Zeile nie doppelthoch! }
- IF dblheight THEN BEGIN { Handhabung doppelthoher Zeilen }
- special := False;
- FOR j := 1 TO Length(out) DO BEGIN { alles außer den ANSI-Codes }
- { entfernen -> erzeugt Kopie der Hintergrundfarben der Zeile }
- IF out[j] = #155 THEN special := True;
- IF NOT special THEN out[j] := ' ';
- IF out[j] = 'm' THEN special := False;
- END;
- GotoXY(pgoffx,zeile+2); Write(normal,out,normal,' ');
- special := False;
- FOR j := 0 TO 39 DO { doppelthohe Abschnitte suchen }
- CASE seite^.chars[40*zeile+j] OF
- 13: BEGIN j0 := j; special := True; END;
- 12: IF special THEN BEGIN
- stretch_line(zeile+1,pgoffx+j0,pgoffx+j); special := False;
- END;
- OTHERWISE;
- END;
- IF special THEN
- stretch_line(zeile+1,pgoffx+j0,79);
- END;
- END;
- event_scan; IF newevent THEN Exit;
- END;
- incomplete := False; { Seite komplett }
- END;
-
- FUNCTION number_from_page{(x,y: Integer): Integer};
- { versucht zu einer angeklickten Bildschirmposition herauszufinden, auf }
- { was für eine Nummer geklickt wurde }
- VAR i,j,j0,n,m: Integer;
- ok,special,hidden: Boolean;
- BEGIN
- n := -1;
- IF (x IN [pgoffx..pgoffx+39]) AND (y IN [1..24]) AND (visblpage<>Nil) THEN BEGIN
- i := 40*(y-1); { 1. Zeichen der Zeile }
- { Sonderfall: untere Hälfte einer doppelthohen Zeile? }
- special := False;
- IF y>1 THEN
- FOR j := -40 TO -1 DO
- IF visblpage^.chars[i+j]=13 THEN special := True;
- IF special THEN i := i-40; { eine Zeile höher gehen }
- { versuchen eine Zahl zu lesen, die (x,y) enthält }
- ok := True; j0 := x-pgoffx;
- FOR j := x-pgoffx DOWNTO 0 DO BEGIN
- IF NOT (visblpage^.chars[i+j] IN [48..57]) THEN ok := False;
- IF ok THEN j0 := j;
- END;
- ok := True; n := 0; m := 0;
- FOR j := j0 TO 39 DO BEGIN
- IF NOT (visblpage^.chars[i+j] IN [48..57]) THEN ok := False;
- IF ok THEN BEGIN
- n := (n SHL 4) + visblpage^.chars[i+j]-48; Inc(m);
- END;
- END;
- IF m=0 THEN n := -1; { keine Ziffern gefunden }
- { die gefundene Zahl ist aber möglicherweise gar nicht sichtbar! }
- special := False; hidden := False;
- FOR j := 0 TO j0 DO
- IF visblpage^.chars[i+j]<32 THEN BEGIN
- hidden := False;
- CASE visblpage^.chars[i+j] OF
- 0..7: special := False;
- 16..23: special := True;
- 24: hidden := True;
- OTHERWISE;
- END;
- END;
- IF special OR (hidden AND concealed) THEN n := -1;
- END;
- number_from_page := n;
- END;
-
- {$endif }
-
- {$if def unit_datei }
-
- 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;
- head := getlong(datei);
- IF EoF(datei) THEN filetype := -1; { leere 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 SHR 16)=$E310 THEN filetype := 4;
- Close(datei);
- END ELSE
- filetype := -1; { Datei existiert nicht }
- END;
-
- FUNCTION getpages{(filename: Str80; sorted: Boolean): Integer};
- { Alle VT-Seiten aus einer VTPG-Datei einlesen und in die Seitenliste }
- { einreihen. 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
- 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
- New(seite);
- 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;
- IF sorted THEN ins_to_list(seite) ELSE add_to_list(seite);
- Inc(gelesen);
- END;
- { das Format der VTex-Software lesen: }
- IF l=fg24 THEN IF getlong(datei)=tvtx THEN BEGIN
- New(seite);
- 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;
- IF sorted THEN ins_to_list(seite) ELSE add_to_list(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 }
- New(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;
- IF sorted THEN ins_to_list(seite) ELSE add_to_list(seite);
- Inc(gelesen);
- END;
- END;
- Close(datei);
- getpages := gelesen;
- END;
-
- {$endif }
-