UNIT info; {$project vt } { Generierung von Sonderseiten zum Programm VideoText } INTERFACE; FROM vt USES jobs; PROCEDURE topinfo(top0,top1: p_onepage); PROCEDURE kill_topmenu; PROCEDURE create_topmenu(pg0,pg2,pg3,pg4: p_onepage); PROCEDURE say_hello(version: Str80); PROCEDURE helpme; PROCEDURE rexxhelp; PROCEDURE testpage; PROCEDURE guru(nr: Byte); FUNCTION hunt(key: str80; target: p_onepage; blink: Boolean): Boolean; TYPE rxkeyid=(scn,top,tos,aut,tok,fif,lif,can,rty,clf,l2c,p2c,s2f,s2b, scl,snp,qit, pre,enq,dsp,hnt,kil,sav,fnm,fmd,ics,ifd,loa, laq,gpn,gpi,gst,nul); rxwords=ARRAY[rxkeyid] OF Str; VAR rxkeys: rxwords; { ---------------------------------------------------------------------- } IMPLEMENTATION; {$opt q,s+,i+ } { keine Laufzeitprüfungen außer Stack und Feldindizes } { eine VT-Seite, die nicht in der Liste verwaltet werden muß: } VAR infopage: onepage; STATIC; PROCEDURE topinfo{(top0,top1: p_onepage)}; { wertet die TOPtext-Seiten 1F0 und 1F1 aus, erzeugt zwei Seiten Information } { bzw., sofern schon vorhanden, aktualisiert diese nur. } VAR i,j,k,n: Integer; npg,nsp,nlrg: Integer; pg1,pg2: p_onepage; s: Str80; BEGIN pg1 := hunt_in_list($999,1,True); pg2 := hunt_in_list($999,2,True); IF pg1=Nil THEN BEGIN New(pg1); pg1^.pg := $999; pg1^.sp := 1; init_page(pg1); ins_to_list(pg1); update_list(pg1,1); END ELSE init_page(pg1); IF pg2=Nil THEN BEGIN New(pg2); pg2^.pg := $999; pg2^.sp := 2; init_page(pg2); ins_to_list(pg2); update_list(pg2,1); END ELSE init_page(pg2); npg := 0; nsp := 0; nlrg := 0; write_to_page(0,1,'Seitenbelegung (laut TOP-Text) 1/2',3,4,pg1); write_to_page(0,1,'Seitenbelegung (laut TOP-Text) 2/2',3,4,pg2); pg1^.cbits := pg1^.cbits OR PF_ISMAP; pg2^.cbits := pg2^.cbits OR PF_ISMAP; FOR i := 10 TO 89 DO BEGIN s := IntStr(10*i)+': ----------'; j := 10*i-60; FOR k := 0 TO 9 DO IF NOT (topcode[top0^.chars[j+k]] IN [0,16]) THEN BEGIN Inc(npg); n := topcode[top1^.chars[j+k]] CASE n OF 0: BEGIN s[k+6] := #127; Inc(nsp); END; 1..9: BEGIN s[k+6] := Chr(48+n); nsp := nsp + n; END; 10: BEGIN s[k+6] := '+'; Inc(nlrg); nsp := nsp + n; END; OTHERWISE s[k+6] := '?'; Dec(npg); { :-( } END; END ELSE IF topcode[top0^.chars[j+k]]=16 THEN s[k+6] := '?'; IF Odd(i DIV 10) THEN j := 2 ELSE j := 21; IF Odd((i+10) DIV 20) THEN k := i MOD 10+2 ELSE k := i MOD 10+13; IF i<50 THEN BEGIN write_to_page(j,k,s,7,-1,pg1); char_to_page(j+5,k,#6,pg1); END ELSE BEGIN write_to_page(j,k,s,7,-1,pg2); char_to_page(j+5,k,#6,pg2); END; END; s := IntStr(npg)+' Seitennummern'; write_to_page(0,12,s,7,5,pg1); s := ''; IF nlrg>0 THEN s := IntStr(nlrg)+' mit "mehr als 9" Unterseiten'; write_to_page(0,23,s,3,1,pg1); s := IntStr(nsp)+' kByte Text'; IF nlrg>0 THEN s := 'mind. ' + s; write_to_page(0,12,s,7,5,pg2); j := 0; FOR i := 100 TO 899 DO IF topcode[top0^.chars[i-60]]=1 THEN j := i; s := 'zur Zeit keine Untertitel'; IF j>0 THEN s := 'VT-Untertitel auf Seite '+IntStr(j); write_to_page(0,23,s,3,1,pg2); END; PROCEDURE kill_topmenu; { den ganzen Müll von create_topmenu aus der Seitenliste entfernen } VAR seite,hilf: p_onepage; BEGIN seite := root; WHILE seite<>Nil DO BEGIN hilf := seite; seite := seite^.next; IF hilf^.pg>=$900 THEN del_from_list(hilf); END; END; PROCEDURE create_topmenu{(pg0,pg2,pg3,pg4: p_onepage)}; { benutzt die TOPtext-Seiten 1F0, 1F2 [1F3 [1F4]], um ein Menü aus Seiten } { mit Schlagwörtern und anklickbaren Seitennummern zu erzeugen } VAR i,j,k,l,n,gap,npg,nttl,nblk: Integer; boff,goff: Integer; titel: ARRAY[0..3*2*23] OF RECORD name: String[13]; nr: Integer; typ: Byte; END; STATIC; block: ARRAY[1..23] OF RECORD adr,abh,menue: Integer; END; STATIC; pg: ARRAY[2..4] OF p_onepage; newpg: p_onepage; s: str80; ch: Char; BEGIN kill_topmenu; { die alten 900er Seiten entfernen } pg[2] := pg2; pg[3] := pg3; pg[4] := pg4; npg := 0; FOR i := 2 TO 4 DO IF pg[i]<>Nil THEN Inc(npg); FOR i := 1 TO 23 DO FOR j := 1 TO 2*npg DO WITH titel[23*(j-1)+i] DO BEGIN gettopnum(pg[1+(j+1) DIV 2],20*(1-j MOD 2),i,nr,k); IF (nr<0) OR (k<0) OR (nr>$899) THEN nr := $900; { ungültige Codierung! } IF nr<$100 THEN nr := nr + $800; nr := get_bcd(nr); IF nr<900 THEN typ := topcode[pg0^.chars[nr-60]] ELSE typ := 0; name[13] := #0; FOR k := 1 TO 12 DO BEGIN name[k] := Chr(pg[1+(j+1) DIV 2]^.chars[40*i+20*(1-j MOD 2)+7+k]); IF name[k]<' ' THEN name[k] := ' '; END; END; nttl := 2*23*npg; { nach Nummern sortieren (Shell-Sort): } gap := nttl DIV 2; WHILE gap>0 DO BEGIN FOR i := gap+1 TO nttl DO BEGIN j := i-gap; WHILE j>0 DO BEGIN IF titel[j].nr>titel[j+gap].nr THEN BEGIN titel[0] := titel[j]; titel[j] := titel[j+gap]; titel[j+gap] := titel[0]; j := j - gap; END ELSE j := 0; END; END; gap := gap DIV 2; END; WHILE (titel[nttl].typ=0) AND (nttl>0) DO Dec(nttl); { Feststellen, wieviele Blöcke es gibt, wieviele Gruppen- und normale } { Seiten von ihnen abhängig sind, und ob sie eine eigene Menüseite } { verdienen: } nblk := 0; n := 900; FOR i := 1 TO nttl DO IF (titel[i].typ IN [1..5]) AND (nblk<23) THEN BEGIN Inc(nblk); block[nblk].adr := i; block[nblk].abh := 0; block[nblk].menue := n; IF (titel[i].typ<>1) AND (i5 THEN Inc(block[nblk].abh); UNTIL (j=nttl) OR (titel[j].typ IN [2..5]); END; IF block[nblk].abh=0 THEN block[nblk].menue := 0 ELSE Inc(n); IF block[nblk].abh>23 THEN block[nblk].abh := 23; END; IF n=900 THEN block[1].menue := n; { häh? kein Block hat Gruppenseiten? } { Offset des Blockmenues in jeder Seite: } boff := 1 + (23-nblk) DIV 2; { Menüseiten aufbauen: } FOR i := 1 TO nblk DO IF block[i].menue>0 THEN BEGIN New(newpg); newpg^.pg := make_bcd(block[i].menue); newpg^.sp := 0; ins_to_list(newpg); init_page(newpg); { Offset des Gruppenmenues in dieser Seite: } goff := boff+i-(1+block[i].abh) DIV 2; IF goff+block[i].abh>24 THEN goff := 24-block[i].abh; IF goff<1 THEN goff := 1; { alle Blockseiten eintragen: } j := boff; FOR k := 1 TO nblk DO BEGIN l := block[k].adr; s := titel[l].name+' '; IF k=i THEN BEGIN { dieser Block } s := s+IntStr(titel[l].nr); IF titel[l].typ IN [3,5] THEN s := s+'+'; write_to_page(0,j,s,0,6,newpg); { Schwarz auf Türkis } END ELSE BEGIN { fremder Block } s := s+IntStr(block[k].menue); write_to_page(0,j,s,6,4,newpg) { Türkis auf Blau } IF block[k].menue=0 THEN BEGIN { Block ohne eigene Seite } write_to_page(15,j,IntStr(titel[l].nr),3,-1,newpg); { Gelb } IF titel[l].typ IN [3,5] THEN char_to_page(19,j,'+',newpg); END; write_to_page(21,j,' ',-1,0,newpg); { schwarzer Hintergrund } END; Inc(j); END; { Gruppen- und normale Seiten dieses Blocks eintragen: } j := goff; k := 0; l := block[i].adr; WHILE (k5 THEN BEGIN s := titel[l].name+' '+IntStr(titel[l].nr); IF titel[l].typ IN [7,10,11] THEN s := s+'+'; IF titel[l].typ<8 THEN write_to_page(20,j,s,0,3,newpg) { Schwarz auf Gelb } ELSE write_to_page(20,j,s,0,2,newpg) { Schwarz auf Grün } Inc(k); Inc(j); END; END; END; END; PROCEDURE say_hello{(version: Str80)}; VAR seite: p_onepage; i: Integer; BEGIN seite := ^infopage; seite^.pg := $1; seite^.sp := $0; init_page(seite); i := 1; write_to_page(0,i,#13,3,4,seite); write_to_page(13,i,Copy(version,7,14),-1,-1,seite); Inc(i); Inc(i); write_to_page(0,i,'Teletext-Browser. PubScreen: '+pubsname,4,6,seite); Inc(i); Inc(i); write_to_page(0,i, ' benötigte Hardware:',7,5,seite); Inc(i); write_to_page(0,i,' I2C-Bus Interface und VT-Decoder',6,-1,seite); Inc(i); write_to_page(0,i,' z. B. das Projekt aus der c''t 7/92',6,-1,seite); Inc(i); Inc(i); write_to_page(0,i, ' "i2c.library":',7,5,seite); Inc(i); write_to_page(0,i,' Copyright (c) Brian Ipsen',6,-1,seite); Inc(i); Inc(i); write_to_page(0,i, ' Compiler:',7,5,seite); Inc(i); write_to_page(0,i,' KICK-Pascal 2.12 von MAXON Computer',6,-1,seite); Inc(i); Inc(i); write_to_page(0,i, ' Programmautor (1992-97):',7,5,seite); Inc(i); write_to_page(0,i,' Wilhelm Nöker ',6,-1,seite); Inc(i); write_to_page(0,i,' Hertastr. 8, D-44388 Dortmund',6,-1,seite); Inc(i); Inc(i); write_to_page(0,i,#13' POSTCARD-WARE',3,4,seite); Inc(i); Inc(i); write_to_page(0,i,' "Keep developers developing" ;-)',4,6,seite); Inc(i); Inc(i); writepage(seite,True); END; PROCEDURE helpme; { Hilfstext ausgeben } VAR i,j: Integer; seite: p_onepage; BEGIN seite := ^infopage; seite^.pg := $2; seite^.sp := $0; init_page(seite); i := 1; write_to_page(0,i,#13' VideoText - Kurzanleitung',3,1,seite); Inc(i); Inc(i); write_to_page(0,i,' Seitenanforderung:',4,6,seite); Inc(i); write_to_page(0,i,' Einfach dreistellige Seitennummern',7,-1,seite); Inc(i); write_to_page(0,i,' eintippen, mit (Return) abschließen.',7,-1,seite); Inc(i); write_to_page(0,i,' Korrektur möglich mit (<-).',7,-1,seite); Inc(i); Inc(i); write_to_page(0,i,' Beispiele:',4,6,seite); Inc(i); write_to_page(0,i,' Grundform (reicht meistens): 100',7,-1,seite); Inc(i); write_to_page(0,i,' eine bestimmte Unterseite: 100/1',7,-1,seite); Inc(i); write_to_page(0,i,' eine beliebige Unterseite: 100/*',7,-1,seite); Inc(i); write_to_page(0,i,' selbstnumerierende Seiten: 100*7',7,-1,seite); Inc(i); write_to_page(0,i,' Bildschirmüberwachung: 150/.',7,-1,seite); Inc(i); write_to_page(0,i,' Dateiprotokoll: 150/!',7,-1,seite); Inc(i); FOR j := i-6 TO i-1 DO char_to_page(30,j,#3,seite); Inc(i); write_to_page(0,i,' Mausunterstützung:',4,6,seite); Inc(i); write_to_page(0,i,' Fast alles auf dem Bildschirm',7,-1,seite); Inc(i); write_to_page(0,i,' reagiert irgendwie auf Mausklick und',7,-1,seite); Inc(i); write_to_page(0,i,' -doppelklick, insbesondere Zahlen in',7,-1,seite); Inc(i); write_to_page(0,i,' den Seitentexten. Einfach ausprobieren',7,-1,seite); Inc(i); write_to_page(0,i,' oder für Details in der Anleitung',7,-1,seite); Inc(i); write_to_page(0,i,' nachschauen.',7,-1,seite); Inc(i); writepage(seite,True); END; PROCEDURE rexxhelp; { ARexx-Kommandos auflisten } VAR i,j,m: Integer; k: rxkeyid; typ: ARRAY[rxkeyid] OF Integer; cnt1,cnt2,cnt3: Integer; seite: p_onepage; BEGIN seite := ^infopage; seite^.pg := $3; seite^.sp := $0; init_page(seite); cnt1 := 0; cnt2 := 0; cnt3 := 0; FOR k := scn TO nul DO CASE k OF nul: ; top,tos,aut,tok,fif,lif,can,rty,clf, l2c,p2c,s2f,s2b,scl,snp,qit: BEGIN typ[k] := 1; Inc(cnt1); END; laq,gpn,gpi,gst: BEGIN typ[k] := 2; Inc(cnt2); END; OTHERWISE BEGIN typ[k] := 3; Inc(cnt3); END; END; i := 1; write_to_page(0,i,#13' VideoText - ARexx-Kommandos',7,1,seite); Inc(i); Inc(i); write_to_page(0,i,' ARexx-Port: '+portname,4,7,seite); Inc(i); Inc(i); write_to_page(0,i,' einfache Kommandos:',7,6,seite); Inc(i); j := 0; m := (cnt1 + 2) DIV 3; FOR k := scn TO nul DO IF typ[k]=1 THEN BEGIN write_to_page(1+13*(j DIV m),i+j MOD m,Copy(rxkeys[k],1,20),6,-1,seite); Inc(j); END; i := i + m + 1; write_to_page(0,i,' Kommandos mit Parametern:',7,6,seite); Inc(i); j := 0; m := (cnt3 + 2) DIV 3; FOR k := scn TO nul DO IF typ[k]=3 THEN BEGIN write_to_page(1+13*(j DIV m),i+j MOD m,Copy(rxkeys[k],1,20),6,-1,seite); Inc(j); END; i := i + m + 1; write_to_page(0,i,' Anfragen:',7,6,seite); Inc(i); j := 0; m := (cnt2 + 1) DIV 2; FOR k := scn TO nul DO IF typ[k]=2 THEN BEGIN write_to_page(1+20*(j DIV m),i+j MOD m,Copy(rxkeys[k],1,20),6,-1,seite); Inc(j); END; i := i + m + 1; writepage(seite,True); END; PROCEDURE testpage; { alle Farbkombinationen testen } VAR i,j,k: Integer; seite: p_onepage; BEGIN seite := ^infopage; seite^.pg := $4; seite^.sp := $0; init_page(seite); FOR i := 0 TO 7 DO BEGIN write_to_page(0,4+2*i,'',-1,i,seite); write_to_page(0,5+2*i,'',-1,i,seite); FOR j := 0 TO 6 DO BEGIN k := (i+j+1) MOD 8; write_to_page(2+5*j,4+2*i,'Test',k,-1,seite); write_to_page(2+5*j,5+2*i,IntStr(k)+'/'+IntStr(i),k,-1,seite); END; END; writepage(seite,True); END; PROCEDURE guru{(nr: Byte)}; { Seite, die wie ein "Software Failure" aussieht :-) } VAR seite: p_onepage; i,j,k: Integer; s: Str80; BEGIN WITH infopage DO BEGIN { benutzt nicht init_page()! } pg := 0; sp := 24; dejavu := False; cbits := $4A00; END; seite := ^infopage; { Ist das schon eine Seite mit Guru? } IF (seite^.chars[0]<>17) OR (seite^.chars[40]<>17) THEN FOR i := 959 DOWNTO 160 DO { ziemlich sicher nicht } IF visblpage=Nil THEN seite^.chars[i] := 32 ELSE seite^.chars[i] := visblpage^.chars[i-160]; i := 0; write_to_page(0,i,'<,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,l',1,-1,seite); Inc(i); write_to_page(0,i,'5 I2C failure. Hit space to continue. j',1,-1,seite); Inc(i); write_to_page(0,i,'5 j',1,-1,seite); s := 'Err: '+intstr(nr)+' Msg: '+i2c_error[nr]; write_to_page((41-Length(s)) DIV 2,i,s,-1,-1,seite); Inc(i); write_to_page(0,i,'-,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,.',1,-1,seite); Inc(i); { Steuerzeichen für die Grafik stimmen noch nicht ganz: } FOR j := 0 TO 3 DO char_to_page(0,j,#17,seite); FOR j := 1 TO 2 DO BEGIN char_to_page(2,j,#1,seite); char_to_page(38,j,#17,seite); END; writepage(seite,True); { den Rahmen einmal blinken lassen: } seite^.sp := 4; { nur noch 4 Zeilen ausgeben } FOR k := 0 TO 1 DO BEGIN FOR j := 0 TO 3 DO char_to_page(0,j,Chr(16+k),seite); FOR j := 1 TO 2 DO char_to_page(38,j,Chr(16+k),seite); Delay(25); writepage(seite,True); END; END; FUNCTION hunt{(key: str80; target: p_onepage; blink: Boolean): Boolean}; VAR i, j, k, l, i0: Integer; s: str80; found: Boolean; BEGIN l := Length(key); FOR j := 1 TO l DO key[j] := UpCase(key[j]); { keine Sorge: UpCase() konvertiert auch Umlaute } found := False; WHILE NOT found AND (target<>Nil) DO BEGIN FOR i := 0 TO 23 DO BEGIN makeascii(target, i, True, s); FOR j := 1 TO 40 DO s[j] := UpCase(s[j]); k := Pos(key, s); IF k>0 THEN BEGIN found := True; i0 := 40*i+k-1; END; END; IF NOT found THEN target := target^.next; END; IF found THEN BEGIN mark_list(False); thispage := target; mark_list(True); writepage(thispage,True); IF blink THEN BEGIN FOR i := 1 TO l DO BEGIN s[i] := Chr(thispage^.chars[i0+i-1]); thispage^.chars[i0+i-1] := 32; END; j := thispage^.pg; k := thispage^.sp; thispage^.pg := 0; thispage^.sp := 101*(i0 DIV 40); Delay(25); writepage(thispage,True); FOR i := 1 TO l DO thispage^.chars[i0+i-1] := Ord(s[i]); Delay(25); writepage(thispage,True); thispage^.pg := j; thispage^.sp := k; END; END; hunt := found; END; BEGIN { Initialisierungsteil } rxkeys := rxwords("SCAN","TOP","TOPSTAT","AUTOTOP","TOPKILL", "FIFO","LIFO","CANCEL","RETRY","CLEARFILE","LIST2CLIP", "PAGE2CLIP","SCRN2FRONT","SCRN2BACK","SETCLOCK", "SNAPSHOT","QUIT", "PRESETS","ENQUEUE","DISPLAY","HUNT","KILL","SAVE", "FILENAME","FILEMODE","ICONS","IFFDUMP","LOAD", "LOOK_AT_QUEUE","GET_PAGENO","GET_PAGEID","GET_STATION",""); infopage.next := Nil; infopage.prev := Nil; END.