' JJJJ ?\>' L-=l>  ԠéԠˠ鷎귭෍ᷩ췩緈JJJJx Lȿ L8ᷭ緍췩 緍i 8 `巬 췌`x (`(8`I`B` ``#͘*~ "Ʒ"͌#>?͌͘ =_.:;<> Oƅo$>!Y2*O"ʉ@G:ʐ:wÖx2p0ʹ#*©6?ëw˜0ï#6 ¹.0#*6?w0#6 #6"  Ň!˶2:2a{_:˷ʖ:˷>Ľʖ:=2–!B!6#5ʖ:˷Ľ!ͬʧ )!F#xʺ~0wëw!" !~6ͽ:ý(!\XDIR*.* COPYRIGHT (C) 1979, DIGITAL RESEARCH _͌> ͒> Ò> Ò͘~#͌ì _2<į2: :):>:(y2E!|"*wɍ`JX)^>EE??++ ԩ  [\ ĭ ?  JL ``LLL $Lq<`ΧԠĠڸčԠԠ͠Ԡ؍2>o:= gw8H<8H=` }Hx / hJ Leh<> > @A @A>i =<>+ LeÍڍh@(L>*// -П( ( $8` %  ZNx`. }x$50x.$50xL JJJJ`Hjf5 }h $50x`  Ȍ` Hx  -(hL(h8֩`Ӕu`êL 0IA 𷽐轐!췩  `轐 LCL L LLL` Lɛ x,w)ş0,LL,HHHv9wxww x&x,whhh6789Lhhhl6Ӕu`".Q`pNФbptťܥm2<(-Py0\|e<6e<g< LJJJJj귍hI  aUL@ kU8  L  Q^R(jQ0l^l\  wUuW ԧ H h@ [_ /QIRb_L`LLLL`ª`LQLYLeLXLeLee ўQH\(h0L& Ꝥ$`( R \ZLl8 ўR HH\`\Z[YS6`LxQ#ɿu3'U ,>J>V J>V `8'x0| &HhHh V Y V '&Y V x ꪽV ' `Hh` ! ~ 3#0 Wx x ƀ Ƃ G ~ # 3x~#B!Y~ɯ2:˷=!˾ý:˷=!˾:ý^T!~  6?#ˆ:`O> K{͘A͒>:͒͢>:͒͢xK > K > ͒x  ͢ØÆ^ BRͧ9!5‚#~Y‚#"T<ÆALL (Y/N)?^ Tʧ͘!6!~ڇ ɯw4!Y~ʆ͌†t=ʆf ^ T ɯ2o&)|+!<ͧ&E`( 80 0 DDLDLDL›^ t^`,tP ȟpMt-^^`DH hWLԧ d@` Lꢩ  c ȢL LqLգcl mllm ꢥELȦAD@ C N cLuɠ% d: L 2>2T*CGͻ:ẅ́n>2;O ^DM;}H>"*C :ٷ:ddslO s#r:EϷ͊:==»y==»*Ww#*"͸*:G#š"͸:!پw4!iw:Z!E~=26 w ~>2!E5T*C!"C"C!w# F! w͌xѯ2͢*C ~<wʃG:٠!٦ʎì 4~ʶ¬:<ʶ$ʶïZͻЯx>2>2ͻ:!پZկ2:EϷẅ́͊Ͳ> *C ^OT *C~wD -'  -@ͦ~^*C Ox! N!Fwyxʋ>ڋ>*Cw~#+w#w+ɯ2E22i^ *C :ٷ~w~͔͔# # ::/GyO>2!q*C"͡ʔ*JҔ^:Oyʃ?|x | sӖ-|N-# S:2E!~Яw>T D^6k-äPYy 5*{zBK5:AϾ#~$=2Ek͌ ):BO!yoxg*:BO}!N#F "*#*s#r^ ~!J! J*:مo$*C~i6iw**{#zr+s{ozg**͕** Ѿ,w͜͸Ͳ!!N#F$**O!~#O: \зSЀ*C :ٷqn& ^#V>O^"*}:*)=":O:١o"*C *C!ͮ~2~2ͦ:٦2ͮ:ЯO:فw:w |g}o*ٯ# 3 E>! ^#V w#P:BO|^#V#"##"##"##"!O*!O*|!6ʝ6>گ*w#w*w#w'û*ڷ! J*""!N#F*^#V*~#foyx*{_zW+*x: 2 p&x~+é7ͯ2 H! >w_: ! Ͼ5ͤNkͱ¦ͱxʊ#Nx: Ϸ! ϖ2 ͤ! 5™#wO~x½p Hy<< ڷʑ :!qMD# O͐  :ϷE B 2>: Ϸb# : Ϸy! 4 5~yy5 6yҐ^H@Oy H H: –ͬ  #H: ! Ͼ Hù H H $O͐: 2 *CN# ʽ7̙̥̫̱"C{2!"E9"1Aϯ22!ty)K!G_^#V*Cΐ~؃E؜إث ,&-AGMSϛ!!ô!ô!Bdos Err On : $Bad Sector$Select$File R/O$:BA2!~6=qf^!~2>`~2˯2\!!B!~> >#0~O#Cx2͘1)ͽÂf zͧÆBAD LOADCOMf^: !˶ Â$$$ SUB· JLǵBȵC`,յp` 䯩 R-յյ`յ0` K R-յյ`ɵʵӵԵ` 4 K ( ѵҵLBȱBL8` DBHBH : ַ޵BȭߵBhhӵԵ RBܵmڵ޵ȱBݵm۵ߵ` 䯩LR˵̵ֵ׵`Ls+p+q-*C ͥ!!q#p#w*:BOYG}*MD "ã:!BϾw!>2*C~=2u:B2~2wE:A*C϶w>"!""ٯ2B!"!rQQQâ~?ͦ~?rQ*"CQ-Q͜QüQrQ$Q*):B"*)*)Q;*"E:;:A2AQÓQÜQ*C}/_|/*٤W}_*"}o|g":ٷʑ*C6:ٷʑw:2E**E}DQ>2C0T"I !>"H>2J: !͢:d::d!s~B#1!P!J߇o~,foɷp:BB Apple ][ CP/M 56K Ver. 2.20B (C) 1980 Microsoft ;ۯ2>EE??++B#1!P!J߇o~,foɷp;ۯ2:޷;ۯ2e ]~6(*} *:޽ y(3:޷s:2G<2x/a2:oa":޷zޯ2{![:޷ <2:>sɯ2>!>2!;:*     1>2>2*"?ۯ2:08 !"Y"BT"->2:8Y"/:8Y"F~!xq!;`~0,~!M;!x~1.~8[q>:޷ 2y2!!{o!:=8 ~y!3w.y2Cɯ2>!w#w#wOa."y .:g"*"!~((5:# :*޽ :޼ $| 8g,"ޯ2!"_!ޅoN!޷((+! ~O#O:x >2ޯ2:޷*(*D*:wk*(:$_"~28 ?@wx( !;!܅ony 2$8!2E!y>>?22!ɯog"$2E!.B...X&*}(8.|8&"$պ`~(,qy2E[22G: 2:O*:P!O#~#'۹~y/:02?"2O: K*:*(0**:8'(*:08* *: 8(*7!w˹#~(=5:!( +_ywɷ+ͱ*:]lc_O{- OMG!~_ :( 6>83! ~èCfuÇKmVÉÎÓãݯ`iޓښ:ޓڦJޓڲZޓھjޓzޓߊ / !~ `66= !; !{g1:Q!͢گ22>2!"2!"͎>2GRAF DOC GRAF DOC GRAF INCGRAF SYSGRAFKEY INCTURTLE INCFLIPMENUINC WINDOW INC'!"#$%rste Grafikseite hineinreicht, kann nur die zweite Grafikseite verwendet werden. Der Rest der ersten Grafikseite dient jetzt als Buffer f}r die Grafikroutinen. ChrTab: array [0..1151] of byte absolute $2A78 Tabelle der Zeichendefinitionen. Jer entwickelt worden. 1.2. Ben|tigte Software Die Grafikroutinen sind zur Benutzung mit TURBO- PASCAL (Trademark of BORLAND Inc.) Version 2.0 oder 3.0 angepasst. Sie ben|tigen auf Ihrer Diskette die Files 'GRAF.SYS' und 'GRAF.INC'. Die Include-F------------- 2.2. Typen Das Includefile 'GRAF.INC' enth{lt folgende Typen- deklaration: 'type longstring=string[255]' Verwenden Sie den Namen 'longstring' daher bitte nicht mehr. 2.3. Konstanten StrBuf=$2F00 Startadresse des StringbuffWINDOW80DOCU&'()*+,-./0WINDOW80INCG123456789TEXTMODECOM:GRAFMODECOM;TEXTMODE.COM' k|nnen Sie von CP/M aus die Anzeige umschalten. 2. Das Grafikpaket 2.1. Compilierung F}gen Sie nach der Deklaration des Programmnamens, der Konstanten, der Typen und der Variablen vor die erste Prozedurdeklaration folgende Compiiles 'TURTLE.INC', 'FLIPMENU.INC' und 'WINDOW.INC' ent- halten Erweiterungen der Grafik-Befehle. Das File 'GRAFDEMO.PAS' (mit 'GRAFDEMO.INC') demonstriert die Verwendung der verschiedenen Grafikroutinen. Mit den Kommandos 'GRAFMODE.COM' und 'ers f}r die Prozeduren WString und Draw. Kann auch als Zwischenspeicher f}r Get und Put verwendet werden. 2.4. Variablen GrafSys: array [0..$A88] of byte absolute $20F0 Buffer f}r das Grafikpaket. Da die TURBO-PASCAL Library bis in die eKlaus Rindtorff 4.9.85 T U R B O - G R A F I K V 1.3 1. Programmumgebung 1.1. Ben|tigte Hardware Das Grafikpaket ist f}r einen Apple II+ oder IIe mit CP/M Softcard und CP/M Version 2.20 oder neueler-Option ein: '{$I GRAF.INC}' . --------------------------------------------------- WICHTIG: Ein Programm, das die Grafik benutzt, mu~ stets als COM-File mit einer Startadresse von $5000 compiliert werden! --------------------------------------des Zeichen ist in 9 Bytes wie folgt kodiert: bit 7 6 5 4 3 2 1 0 Byte 1 [ ! . . . . . . ] bit 7: 1=Unterl{nge Byte 2 [ . . . . . . . ] bit 0-6: Zeichenbreite Byte 3 [ . . .1.1.1.1. ] Byte 4 [ . .1. . . .1. ] Byte 2-9 enthaltenbare Teil der Linie (Clipping). Der Grafikcursor bleibt unver{ndert. MoveTo(x,y:integer) Zieht eine Linie von der Position des Grafikcursors zu den Koordinaten (x,y). Der Punkt (x,y) darf auch au~erhalb des darstellbaren Bereiches liegen. Ange- z auf die Textdarstellung umzuschalten. Clear Der Grafikbildschirm wird gel|scht. Inverse Alle Punkte des Grafikbildschirmes werden inver- tiert, dh. helle Punkte werden dunkel und umge- kehrt. SetMode(n:byte) Auswahl der Zeichenfarbe fEcke Ihres Bildschirms. Size: byte absolute $20F4 Vergr|~erungsfaktor f}r das Zeichnen von Shapes. Der Wert 0 f}r Size wird als 256 interpretiert. Mode: byte absolute $20F5 Enth{lt die Nummer des aktuellen Zeichenmodus. Two: array[0..7] oflb des darstellbaren Bereiches, wird der Befehl ignoriert. Der Wert 0 f}r dx wird als 256 interpretiert. VLine(x,y:integer; dy:byte) Ziehen einer vertikalen Linie von den Koordinaten (x,y) aus dy Punkte nach oben. Liegt der Punkt (x,y) ikcursor wird auf die Bild- mitte (140,96) gesetzt und es wird Mode(1) einge- schaltet. Size wird mit 1 initialisiert. GrafMode Einschalten der Grafikdarstellung. ACHTUNG: Besitzer eines Apple IIe m}ssen nach Ver- wendung von Readln oder Write die Byte 5 [ . .1. . . .1. ] spiegelverkehrte Zei- Byte 6 [ . . .1.1.1.1. ] chenmatrix. Die rechte Byte 7 [ . . . .1. .1. ] und die obere Zeile Byte 8 [ . . .1. . .1. ] der Matrix bleiben als Byte 9 [ . .1. . . .1. ] Zwischenr (x,y). Liegt der Punkt au~erhalb des darstellbaren Bereiches (0<=x<=279 , 0<=y<=191) wird der Befehl ignoriert. Point(x,y:integer):boolean Ermittelt, ob der Punkt mit den Koordinaten (x,y) gesetzt ist (Point=true) oder nicht (Point=false). }r alle Grafik-Befehle: 0 = Schwarz (Punkte l|schen) 1 = Wei~ (Punkte setzen) 2 = Invertierend (XOR Verkn}pfung) 3-255 = unsichtbar (keine Wirkung) 3.2. Einzelpunkte Plot(x,y:integer) Setzen des Punktes mit den Koordinaten byte absolute $2EF8 Enth{lt die Zweierpotenzen von (2)^0 bis (2)^7. 3. Grafikprozeduren Alle folgenden Koordinatenangaben beziehen sich auf ein Koordinatensystem mit dem Ursprung (0,0) in der linken unteren Ecke. Der darstellbare Bereich um- fau~erhalb des darstellbaren Bereiches, so wird der Befehl ignoriert. Line(x1,y1,x2,y2:integer) Zieht eine Linie von (x1,y1) nach (x2,y2). Zugelas- sen sind auch Koordinaten au~erhalb des darstellba- ren Bereiches. Angezeigt wird nur der sichtln im GrafMode, diesen erneut durch 'GrafMode' aktivieren, da die Firmware der 80-Zeichen Karte nicht richtig umschaltet. TextMode Es wird wieder auf Textdarstellung umgeschaltet. Denken Sie unbedingt daran, vor Beenden eines Pro- gramms wiederaum frei. xc,yc: integer absolute $20F0 bzw. $20F2 Die aktuellen Koordinaten des Grafikcursors. Diese Variablen k|nnen Sie auch in Ihren Programmen ver- wenden. Der Ursprung des rechtwinkligen Koordina- tensystems liegt in der linken unteren Liegt der Punkt au~erhalb des darstellbaren Berei- ches, so gilt er als nicht gesetzt. 3.3. Linien HLine(x,y:integer; dx:byte) Ziehen einer horizontalen Linie von den Koordinaten (x,y) aus dx Punkte nach rechts. Liegt der Punkt (x,y) au~erhan Ihrem Pro- gramm m}ssen sie einmal die Prozedur 'InitGraf' aufgerufen haben. Sie l{dt das Grafikpaket in den Buffer und f}hrt einmal die Prozedur 'Init' aus. Init Der Grafikbildschirm wird gel|scht und anschlie~end eingeschaltet. Der Grafasst 280 Punkte horizontal und 192 Punkte verti- kal. Der Grafikcursor ist ein gedachter, nicht angezeigter Cursor, dessen Koordinaten in den Va- riablen xc,yc stehen. 3.1. Initialisierung InitGraf Vor Verwendung der Grafikprozeduren ieigt wird nur der sichtbare Teil der Linie. Der Grafikcursor steht anschlie~end bei (x,y). ToXY(x,y:integer) Die Koordinaten des Grafikcursors werden mit den Werten von x und y neu initialisiert. 3.4. Figuren Frame(dx,dy:integer) Es wird invers:boolean) Die durch eine Begrenzung aus gesetzten Punkten umgebene schwarze Fl{che, die durch einen ihrer Punkte (x,y) bestimmt wird, wird mit dem Muster der Nummer m gef}llt. Die Nummer des Musters mu~ im Bereich von 0 bis 127 l$83 = 131 . ! . . . ._._. . ! . 1 001 0011 = $93 = 147 . ! . . . ! . ! . ! . 0 100 0111 = $47 = 71 . ! . . . ! . ! . ! . 1 000 0010 = $82 = 130 . !_._._._!_._!_._! . 1 010 0001 = $A1 = 161 . . . . . . . . . . . 1 100 0010 = $C2 = 1st wie Frame. Circle(x,y:integer; r:byte) Es wird ein Kreis mit dem Radius r und dem Mittel- punkt (x,y) gezeichnet. Der Mittelpunkt darf auch au~erhalb des darstellbaren Bereiches liegen. Ange- zeigt wird nur der sichtbare Teil des Kreises. Dern linken unteren Ecke, wird horizontal mit dem Faktor 2 gestreckt. Die linke untere Ecke bleibt fest. Das Rechteck mu~ ganz innerhalb des darstellbaren Bereiches liegen. VZoom(dx,dy:byte) Das Rechteck mit der Breite dx, der H|he dy und der durch / | \ +----+ 5 | 3 3 | L3 | \ 4 +----+ \ 2 | L2 | \ +----+ > L{nge der Linie in Punkten -1 1 | L1 | / +----+ / 0 | L0 | / + ein Rechteck mit der Breite dx und der H|he dy gezeichnet, dessen linke untere Ecke durch die Position des Grafikcursors bestimmt wird. Der Wert 0 f}r dx oder dy wird als 256 interpretiert. Das Rechteck mu~ komplett innerhalb des darstellbarenPosition des Grafikcursors. Liegt der Punkt (x,y) oder der Grafikcursor au~erhalb des darstellbaren Bereiches, wird der Befehl ignoriert. Der Wert 0 f}r dx wird als 256 interpretiert. VCopy(x,y:integer; dy:byte) Kopiert eine Spalte aus dy Pu94 Startposition ist die Spitze des Daches. s:=chr(179)+chr(195)+chr(231)+... +chr(194); Draw(s); {oder direkt: Draw(chr(179)+... )} 3.6. Kopieren HCopy(x,y:integer; dx:byte) Kopiert eine Zeile aus dx Punkten beginnend bei (x,y) an die Wert 0 f}r den Radius wird als 256 interpretiert. Disk(x,y:integer; r:byte) Es wird eine Scheibe mit dem Radius r und dem Mit- telpunkt (x,y) gezeichnet. Der Radius 0 wird als 256 interpretiert. Sonst wie Circle. 3.5. Shapes Draw(s:longst den Grafikcursor bestimmten linken unteren Ecke, wird vertikal mit dem Faktor 2 gestreckt. Die linke untere Ecke bleibt fest. Das Rechteck mu~ ganz innerhalb des darstellbaren Bereiches liegen. 3.8. Fl{chen f}llen Fill(x,y:integer; m:byte;----+ Beispiel: . . . . . . . . . . . wird kodiert als: . . . . ./.\. . . . . 1 011 0011 = $B3 = 179 . . . ./. . .\. . . . 1 100 0011 = $C3 = 195 . . ./. . . . .\. . . 1 110 0111 = $E7 = 231 . ./. . . . . . .\. . 1 000 0011 = Bereiches liegen. (Verwendung von HLine und VLine) Box(dx,dy:integer) Es wird ein ausgef}lltes Rechteck mit der Breite dx und der H|he dy gezeichnet. Liegt der Grafikcursor au~erhalb des darstellbaren Bereiches, wird der Befehl ignoriert. Sonnkten beginnend bei (x,y) an die Position des Grafikcursors. Der Wert 0 f}r dy wird als 256 interpretiert. Sonst wie HCopy. 3.7. Vergr|~ern HZoom(dx,dy:byte) Das Rechteck mit der Breite dx, der H|he dy und der durch den Grafikcursor bestimmte 7 | LZ | <-- 1=Linie ziehen 0=keine Linie +----+ 6 | R2 | \ 0 +----+ \ 7 | 1 5 | R1 | > Richtung 0..7 \ | / +----+ / 6 ----+---- 2 4 | R0 | /ring) Die im String s kodierte Figur wird gezeichnet. Der Startpunkt wird durch den Grafikcursor bestimmt, dessen Position unver{ndert bleibt. Der Vergr|~er- ungsfaktor wird durch Zuweisung an die Variable Size eingestellt. bit +----+ iegen. Die Zeichen 0 bis 31 des Grafikzeichensatzes in 'ChrTab' enthalten solche Muster. Sie k|nnen jedoch auch Buchstaben (32 bis 127) als Muster benutzen. Der Wahrheitswert invers entscheidet, ob das Muster normal (False) oder invers (Trueite des Menus wird durch dx bestimmt. Sie mu~ mindestens 12 sein. Die linke untere Ecke wird durch den Grafikcursor bestimmt. Die H|he bestimmt die Funktion selbst aus der An- zahl der Optionen durch dy:=Optionen*10+4 . Daher ergibt sich eine le Punkte, die zum Bildwiederholspeicher des Be- reichs geh|ren, der eine Breite von dx und eine H|he von dy Punkten besitzt und dessen linke untere Ecke durch den Grafikcursor bestimmt wird, werden in den Speicher ab Adresse Ad kopiert. Die A ! x ! ! x ! !________! !________! Zerlegung in konvexe Teilfiguren 3.9. Schrift WChar(n:byte) Das Zeichen Nummer n wird mit der linken unteren Ecke an die Position des Grafikcursors gebracht. Liegt der Grafikcurskel in 'Phi'. Turn(Winkel:integer) TurnTo(Winkel:integer) 'Turn' dreht die Blickrichtung gegen den Uhrzeiger- sinn und 'TurnTo' setzt sie auf einen neuen Winkel. Walk(Abstand:real) Bewegen der Turtle in ihrer Blickrichtung. 4.2. Pull-down Menult wird um 10 Zeilen nach oben gescrollt. Der Grafikcursor bleibt unver{ndert. 3.10. Hardcopy Send(c:byte) Schickt das Zeichen c direkt an den Drucker. Ihr Interface mu~ in der Lage sein, 8-bit Daten zu }bertragen (zB. IBS AP4, EPSON AP) verwendet wird. Die Fl{che mu~ mindestens horizontal konvex sein, d.h. eine Ver- bindungslinie zwischen zwei Punkten gleicher H|he darf die Fl{che nicht verlassen. Um nicht konvexe Fl{chen zu f}llen, zerlegen Sie diese in mehrere konvexe des Bereichs mit gleicher Breite dx und H|he dy, in den zur}ckkopiert wird. 4. Include-Files Die folgenden Include-Files enthalten jeweils eine Erweiterung der Grafik-Befehle. Sie werden wie un- ter (2.1.) beschrieben in Ihr Programm aufgenommenzahl der kopierten Bytes betr{gt n=(dx*dy)shr 3+1 . Put(dx,dy:byte; Ad:integer) Der mit Get in den Speicher ab Adresse Ad kopierte Bereich wird wieder in den Bildwiederholspeicher zur}ckkopiert. Der Grafikcursor bestimmt die linke untere Eckeor au~erhalb des darstellbaren Bereiches, oder ist nicht mehr gen}gend Platz f}r das ganze Zeichen vorhanden (xc>272), so wird der Befehl ignoriert. Die Unterl{nge eines Zeichens betr{gt zwei Zeilen. Der Grafikcursor wird danach um die Brei {$I FLIPMENU.INC} FlipMenu(x,y,dx:byte;s:longstring):integer Es wird ein Pulldown Menu an der Position (x,y) an- zeigt. Der Text der einzelnen Optionen, die durch ein '_' chr(95) getrennt werden m}ssen, wird im String s }bergeben. Die BreL, PARALLEL). GrafDump Der Inhalt des Grafik-Bildschirms wird mit einer Gr|~e von etwa 13*17 cm auf dem Drucker ausgegeben. Die Adressen der Drucker Steuercodes finden Sie im File 'GRAF.INC'. 3.11. Speichern Get(dx,dy:byte; Ad:integer) Alund rufen die Prozedur mehrmals auf. __________________________ ! ! ! ! Fill(a,b,m,i) ! ________ ........! Fill(c,d,m,i) ! ! ! ! ! (a,b) ! ! (c,d) ! n. 4.1. Turtle-Grafik {$I TURTLE.INC} InitTurtle Die Turtle wird auf die Koordinaten des Grafikcur- sors gesetzt und der Blickwinkel mit 0 Grad initia- lisiert. Die Koordinaten befinden sich in den Real- Variablen 'xt', 'yt' und der BlickwinDer Grafikcursor wird an den linken Bildrand gesetzt und um 10 Zeilen nach unten verschoben. Liegt er unterhalb der drit- ten Zeile, so wird der Bildschirm gescrollt und der Grafikcursor auf die Postion (0,2) gesetzt. Scroll Der Bildschirminhate des Zeichens nach rechts verschoben. WString(S:longstring); Der String S wird ab der Cursorposition auf dem Bildschirm ausgegeben. Zeilenvorschub und Scrollen werden bei Bedarf automatisch ausgel|st. NewLine Bewirkt einen Zeilenvorschub. maximale Anzahl von 18 Optionen. Zu lange Texte werden gek}rzt, es wird nicht ge- scrollt. Die Steuertasten zur Auswahl sind durch die Konstanten 'NachOben','NachUnten' und 'Auswahl' festgelegt. Nach der Auswahl wird die Nummer der angew{hlte Window wird wieder geschlos- sen. Der Grafikcursor steht wieder an der gleichen Stelle wie vor Aufruf von 'OpenWindow'. Der ur- spr}ngliche Bildhintergrund wird wiederhergestellt. 5. Fehlermeldungen Folgende Fehlermeldungen werden von don nun an in diesem Window. Die Parameter sind so zu w{hlen, da~ das Window komplett innerhalb des darstellbaren Bereiches liegt. Die Breite mu~ mindestens 12, die H|he mindestens 14 Punkte betragen. Die Anzahl der f}r den Hintergrund auf dem H unver{ndert. ClearWindow Der Inhalt des aktuellen Windows wird gel|scht. Das Window wird dazu gel|scht und neu gezeichnet. ChangeWindow(WindowNr:integer) Die Prozedur erlaubt den Wechsel des aktuellen Win- dows, dessen Nummer in Window gespeicheen Option als Ergebnis zur}ckgegeben. Die Position des Grafikcursors bleibt erhalten. 4.3. Windows {$I WINDOW.INC} InitWindow Die Prozedur initialisiert den Window-Stack und mu~ vor Verwendung der Windows einmal aufgerufen wer- den. Die reserviert. 'Maximal n Windows' Die zul{ssige Zahl der Windows wurde }berschritten. 'Alle Windows bereits geschlossen' Es wurde versucht ein Window zu schlie~en, obwohl keines mehr offen ist. 'Window Nr. x existiert nicht' Es wurde versuchten Include- Files 'FLIPMENU.INC' und 'WINDOW.INC' erzeugt: 'Falsche Menu Parameter' Aufruf von FlipMenu mit falschen Parametern. 'Falsche Window Parameter' Aufruf von OpenWindow mit falschen Parametern oder zu wenig Speicherplatz auf dem Heapeap ben|tigten Bytes betr{gt n=Multi(dx,dy)shr 3+1. Der Grafikcursor wird ab jetzt von der Prozedur Print benutzt. Seine alte Position sowie die H|he und die Breite des Windows werden in den Variablen wx,wy,dx und dy gespeichert. Print(S:lort wird. Das neue aktuelle Window sollte dabei komplett sichtbar sein, da eventuell }berlappende Windows sonst }ber- schrieben werden k|nnten. Die Nummer des obersten Windows wird in der Variablen Top gespeichert. CloseWindow Das zuletzt ge|ffnetmaximale Anzahl der Windows wird durch die Konstante 'MaxWindow' bestimmt. OpenWindow(x,y,b,h:integer) Ein Window mit der Breite b , der H|he h und der linken unteren Ecke bei (x,y) wird ge|ffnet. Die Ausgabe mit der Prozedur 'Print' erfolgt v, mit ChangeWindow in ein nicht ge|ffnetes Window zu wechseln. Es wurde versucht ein Window zu schlie~en, obwohl keines mehr offen ist. 'Window Nr. x existiert nicht' Es wurde versuchtt. Die Variablen 'Links', 'Rechts', 'Oben' und 'Unten' enthalten die Schreibgrenzen des Windows. ClearLine Die Zeile, in der der Grafikcursor momentan steht, wird ab dessen Position bis zum Rand des Windows gel|scht. Die Position bleibt dabeingstring) Der String S wird in das momentan aktuelle Window geschrieben. Ist noch kein Window offen, so wird auf den Grafikbildschirm geschrieben. Das Zeichen '_' chr(95) bewirkt dabei einen Zeilenvorschub. Das Window wird automatisch gescroll(********************************************************************) (* Turbo Grafik V 1.3 [Apple II+/IIe] (c) Klaus Rindtorff 04.09.85 *) (* Compiler Option Com-File mit Startadresse 5000 setzen! *) (***************************************DM![ R`i;)~G#: O~Gx0ͷ!8*@89*@8)@8 *x( >2 2 " " `i]b))z0*͟$&j)))DMB |(|()))zկWZW$$: ͙!͙!͙!͙!͙!͙!͙!͙! ########* DM* * VZoom(dx,dy:byte); external $2658; procedure Fill(X,Y:integer;M:byte;Invers:boolean); external $26A2; procedure Send(c:integer); external $27BF; procedure GrafDump; external $27EB; procedure NewLine; ungen: (angepasst an EPSON Drucker)} {Grafikmodus (>=560 Punkte): GrafSys[$716] = '*' } { gefolgt von LSB/MSB Anzahl GrafSys[$71B] = chr(5) } {Zeilenabstand (8/72"): GrafSys[$704] = 'A' } { hier patchen fuer n/216" GrafSys[$709] = chr(8)!ѷR0DM!R`iG;)ͷ!)y!ѷR0DM!R`iG;)ͷ! *y!ѷR0DM!R`iG;)![ RDM![ R`i;)~~w w))y!ѷR0DM!R`iG;)![ RDM![ R`i;)~~w $22FE; procedure MoveTo(X,Y:integer); external $230A; procedure Line(X1,Y1,X2,Y2:integer); external $2323; procedure Draw(var S:longstring); external $23E2; procedure Disk(X,Y:integer;r:byte); external $2450; procedure Circle(X,Y:integer*****************************) const StrBuf=$2F00; type longstring=string[255]; var sys: file; GrafSys: array[0..$A88] of byte absolute $20F0; xc: integer absolute $20F0; yc: integer InitGraf; begin assign(sys,'GRAF.SYS'); reset(sys); blockread(sys,GrafSys,filesize(sys)); close(sys); Init; end; {InitGraf}  external $2866; procedure Scroll; external $2880; procedure WString(S:longstring); external $28C6; procedure Get(dx,dy:byte;Ad:integer); external $28FD; procedure Put(dx,dy:byte;Ad:integer); external $2960; procedure } {Zeilenabstand normal: GrafSys[$768] = '2' } procedure Init; external $20FF; procedure GrafMode; external $2124; procedure TextMode; external $2134; procedure Clear; w * *" " * * " " " "  " " * RF#(|(|/g}/o#* Rh#(|(|/g}/o#DMٯ`iRgo0-͙!* ѷR )k*8R PY͙!* ѷR )k*8R![ R;r:byte); external $2457; procedure Box(dx,dy:byte); external $250C; procedure Frame(dx,dy:byte); external $254A; procedure WChar(n:byte); external $258C; procedure HZoom(dx,dy:byte); external $2612; procedure absolute $20F2; Size: byte absolute $20F4; Mode: byte absolute $20F5; ChrTab: array[0..1151] of byte absolute $2A78; Two: array[0..7] of byte absolute $2EF8; {Drucker Anpass!" !`" !"!S%S%>2 >!22P2R2U2W2T2Q2ɯ!00w!0 ~w# x }2 != != !!"!S%S%!ѷR0DM!R`i;)~w!ѷR0!DM!R!`i;)~!+yLine(X,Y:integer;dx:byte); external $21EC; procedure Vline(X,Y:integer;dy:byte); external $2217; procedure HCopy(X,Y:integer;dx:byte); external $2242; procedure VCopy(X,Y:integer;dy:byte); external $22A0; procedure ToXY(X,Y:integer); external external $213E; procedure Inverse; external $214C; procedure SetMode(n:byte); external $215D; procedure Plot(X,Y:integer); external $2199; function Point(X,Y:integer):boolean; external $21BF; procedure HR* R* RA{![ RDM![ R`iG;)ͷ!)8 *P* * ! ! * #""}[ !RDM![ R`i;)yO!x*_)))~#^y8##;O(9*9*n} function GetString(OkSet:SetOfChar; MaxLen:Integer):longstring; var m:Byte; S1:Char; Stemp:longstring; begin Stemp:=''; if MaxLen<1 then MaxLen:=1; OkSet:=OkSet+[Chr(8),Chr(13)]; repeat if Length(Stemp)=MaxLen then S     ****    """""**""        '>A'>'!>'>*'>'>0'>'Ϳ!}!!y(O'y'#| }(\(z >'>2'> '> '!" * } 8o" ." !;) }(;)(#!;)(w#9*0/!D9~O/G* |( }8f(; x:=xc; while not KeyPressed do begin Wchar(ord(C)); Delay(200); xc:=x; Wchar(ord(C)); Delay(200); xc:=x; end; SetMode(m); end; {Flash} function GetChar(OkSet:SetOfChar):Char; var Ch:Char; begin repeat Read(Kbd**>> "2*&"" >> ">> """> """"""<  >>" ":*:<"">"""""""""""">>~w#~Zw *y* o>g" P* " A* ͠"* +" * ͠"* +" +#" P* " A* B"* +" * B"* +" +#" }2 !x*˻)))#!ѷR0DM!R`i{G;)~/'* @o͌%A![ RDM![ R`i;)G)~ ( xw#( Ax *x wA~![ RDM![ R`i;)G)~8w #~G( Ax *}g}.8.P).:{ZJ00#0<,Ch); if not (Ch in OkSet) then Write(Chr(7)) else if Ch in [' '..'~'] then Wchar(Ord(Ch)); until Ch in OkSet; GetChar:=Ch; end; {GetChar} function JaNein:Boolean; begin JaNein:=(UpCase(GetChar(['j','J','n','N']))='J'); end; {JaNei><2""<""">"""8 "  ">ƪ""&*2""""""""""""*,"" "" ">""""""""""D"""""""> >""">"""""""""""""*~Vx  * * * *8 ͗'0/'" " " " 9*͗'/'|o&F: (x/Gx٠(~wS C *8~(S C )8~ x٠(~w~7[ K : : )~7 }:( :82>2>22:(>{einige nuetzliche Ein/Ausgaberoutinen -- Klaus Rindtorff 30.08.84} {angepasst an die TURBO-Grafik V 1.2 -- Klaus Rindtorff 06.08.85} type SetOfChar=set of Char; procedure Flash(C:char); var x:integer; m:byte; begin m:=Mode; SetMode(2)̙3f̙CCCC""A]Uu`oo`w.:wA> ! !D9Dww3333>>"AɈ"""")TDT)wAwAuuWPW >>< (&20 *, >' {'||(gg(%<|g}(Po!7||(gg($<|g}(Po!7||s*ɺ}UUUUUUUUDDDDDD @0 @ UUUUUUUUD"D""D"Df3f33f1:=GetChar([Chr(8),Chr(13)]) else S1:=GetChar(OkSet); if (S1=Chr(8)) and (Length(Stemp)>0) then begin S1:=Stemp[Length(Stemp)]; Delete(Stemp,Length(Stemp),1); xc:=xc-(ChrTab[Ord(S1)*9] and $7F); dx*dy)shr 3+1); ToXY(x,y); Get(dx,dy,ord(Buffer)); SetMode(0); Box(dx,dy); xc:=xc+1; yc:=yc+1; SetMode(1); Frame(dx-2,dy-2); Links:=xc+1; Rechts:=Links+dx-4; Unten:=yc+3; yc:=Unten+dy-14; xc:=Links; for i:=1 to length(s) dole X-Koordinate} yt:real; {Turtle Y-Koordinate} procedure InitTurtle; begin xt:=xc; yt:=yc; Phi:=0; end; {InitTurtle} procedure Turn(Winkel:integer); {+ linksrum, - rechtsrum} begin if Winkel<0 then Phi:=Phi+(360-abs(Winkel)m' then Code:=-1 else Val(S,Num,Code); Fehler:=(Code<>0) or (NumMaxval); if Fehler then begin Write(Chr(7)); m:=Mode; SetMode(2); for i:=Length(S) downto 1 do begin xc:=xc-(string):integer; var OldX,OldY,OldMode,Anzahl,i, Links,Rechts,Unten:integer; Buffer:^integer; dy :byte; Ch :char; begin OldX:=xc; OldY:=yc; OldMode:=Mode; Anzahl:=1; for i:=1 to Length(s) do if s[i]='_' then Anzahl:= m:=Mode; SetMode(2); Wchar(Ord(S1)); xc:=xc-(ChrTab[Ord(S1)*9] and $7F); SetMode(m); end else if (S1<>Chr(13)) and (S1<>Chr(8)) then Stemp:=Stemp+S1; until S1=Chr(13); GetString:=Stemp; begin xt:=xt+Abstand*Cos(Phi/Bogenmass); yt:=yt+Abstand*Sin(Phi/Bogenmass); MoveTo(round(xt),round(yt)); end; {Walk} {Move is standard procedure} od 360) else Phi:=(Phi+Winkel)mod 360; end; {Turn} procedure TurnTo(PhiNeu:integer); begin if PhiNeu<0 then Phi:=360-abs(PhiNeu)mod 360 else Phi:=PhiNeu mod 360; end; {TurnTo} procedure Walk(Abstand:real); {+ vorwaerts, - rueckwaerts} ChrTab[Ord(S[i])*9] and $7F); Wchar(Ord(S[i])); xc:=xc-(ChrTab[Ord(S[i])*9] and $7F); end; SetMode(m); end; until not Fehler; Getinteger:=Num; end; {GetInteger}Anzahl+1; dy:=Anzahl*10+4; if (x<0) or (y<0) or (x+dx>279) or (y+dy>191) or (dx<12) or (Anzahl>18) then begin TextMode; writeln(^G,'FlipMenu: Falsche Menu Parameter'); Halt; end; GetMem(Buffer,({Standardprozeduren fuer eine Turtlegrafik -- Klaus Rindtorff 4.9.85} {Version 1.3 (TURBO 3.0) -- Option COM-File Startadresse 5000 setzen} const Bogenmass=57.29578; {Grad nach Bogenmass} var Phi:integer; {Turtle Blickwinkel} xt:real; {Turtend; {GetString} function GetInteger(Minval,Maxval:Integer):Integer; var S:longstring; I,Num,Code:Integer; Fehler:Boolean; m:Byte; begin if Minval>Maxval then Minval:=Maxval; repeat S:=GetString(['-','0'..'9'],6); if S='{ FlipMenu Standardroutinen Version 1.3 angepasst an TURBO PASCAL 3.0} { Klaus Rindtorff 4.9.85 / Option Com-File Startadresse 5000 setzen! } const NachOben=8; NachUnten=32; Auswahl=13; {ord() der Steuertasten} function FlipMenu(x,y,dx:byte;s:long if s[i]<>'_' then begin if (xc+(ChrTab[ord(s[i])*9] and $7F)Rechts) or (s[i]='_') then ToXY(Links,yc-10); es Window loeschen} var m:integer; begin ToXY(wx,wy); m:=Mode; SetMode(0); Box(wb,wh); ToXY(xc+1,yc+1); SetMode(1); Frame(wb-2,wh-2); SetMode(m); Links:=wx+2; Rechts:=wx+wb-2; Unten:=wy+4; Oben:=wy+wh-10; ToXY(Links,Oben); NachUnten: if i>1 then i:=i-1 else i:=Anzahl; end; yc:=Unten+(i-1)*10; Box(dx-4,10); end else if Ch=chr(Auswahl) then FlipMenu:=Anzahl+1-i; until Ch=chr(Auswahl); Towb:=b; wh:=h; if (wx>=0) and (wx<=279) and (wy>=0) and (wy<=191) and (wb>=12) and (wh>=14) and ((wx+wb)<=279) and ((wy+wh)<=191) then begin PushWindow; ToXY(wx,wy); GetMem(WindPtr[Top],(wb*wh)shr 3+1); tuelles Window und Stapelzeiger} WindowStack :array [1..MaxWindow] of WindowElement; {Stapel} WindPtr :array [1..MaxWindow] of ^integer; {Window Buffer} procedure InitWindow; {Diese procedure muss vor Verwendung der Windows einmal aufr; end; var wx,wy, {Linke untere Ecke des Windows} Links,Unten, Rechts,Oben :integer; {Schreibgrenzen des aktuellen Windows} wb,wh :byte; {Breite und Hoehe des aktuellen Windows} Window,Top :0..MaxWindow; {ak SetMode(m); yc:=Unten; end; {Scrollen} if s[i]<>'_' {chr(95) bedeutet Zeilenvorschub} then Wchar(ord(s[i])); end; end; {Print} procedure ClearLine; var m:integer; beginiven. Typen: longstring=string[255]; F}r die Verwendung in Prozedurdeklarationen. WindowElement=record wx0,wy0,wb0,wh0,xc0,yc0:integer; Buffer:^integer; end; F}r jedes Window wird auf dem Stack ilten sein und durch die Sequenz ^Z chr(n) ausge- geben werden. Die Sequenz ^Z '0' mu~ den Bildschirm l|schen. Der Bildschirm darf w{hrend der Verwendung der Window-Befehle nicht komplett scrollen. 1. Bezeichner Die Window-Befehle sind im Inow] do begin xc0:=xc; yc0:=yc; end; {alte Position merken} Window:=WindowNr; with WindowStack[Window] do begin ToXY(xc0,yc0); wx:=wx0; wy:=wy0; wb:=wb0; wh:=wh0; end; Links:=wx+2; Unten:uertasten an Ihre Bed}rfnisse (zB. Funktions- tasten) anpassen. LinksOben=22; {32} Waagerecht=26; {95} RechtsOben=28; {32} Senkrecht=21; {33} LinksUnten=19; {33} RechtsUnten=25; {33} Um ein Window auf dem Bildschirm zu begrenzen werdenut(wb,wh,ord(WindPtr[Top])); FreeMem(WindPtr[Top],(wb*wh)shr 3+1); PopWindow; end; {CloseWindow}  geschlossen'); Halt; end; end; {PopWindow} begin {CloseWindow} ChangeWindow(Top); ToXY(wx,wy); P m:=Mode; SetMode(0); yc:=yc-2; Box(Rechts-xc,12); yc:=yc+2; SetMode(m); end; {ClearLine} procedure ChangeWindow(WindowNr:integer); {Wechsel des aktuellen Windows auf eigene Gefahr. Das Window muss komplett} {sichtbar sein, eventuell ueberung reserviert bleiben sollten: Konstanten: MaxWindow=8; Diese Konstante gibt die maximale Anzahl der verwalteten Windows an. Sie richtet sich in erster Linie nach dem verf}gbaren Speicherplatz auf dem Heap. Falls n|tig kann sie auf h|here cludefile 'WINDOW80.INC' enthalten und werden beim Compilieren durch die Compileroption '{$IWINDOW80.INC}' hinter der Variablendeklaration mit in das Programm eingebunden. Das File definiert die folgenden Bezeichner, die f}r die Windowverwalt=wy+4; Rechts:=wx+wb-2; Oben:=wy+wh-10; end; {ChangeWindow} procedure CloseWindow; {aktuelles Window schliessen} procedure PopWindow; {Window Parameter vom Stack holen} begin if Top>0 then begin with WindowStack[Top] die entsprechenden Son- derzeichen der 80-Zeichen Karte benutzt. Wenn Sie einen anderen Zeichensatz besitzen, definieren Sie die Konstanten durch die ASCII Nummern Ihrer Ersatz- zeichen oder w{hlen Sie die in Kommentarklammern angegebenen AlternatKlaus Rindtorff 18.6.85 Beschreibung der W i n d o w - B e f e h l e Vorausgesetzt wird ein Apple II+ mit einer 80-Zeichen Karte. Die Sonderzeichen f}r Strichgrafik m}ssen enthalappende Windows werden sonst ueberschrieben.} begin if (WindowNr<1) or (WindowNr>Top) then begin TextMode; write(^G,'ChangeWindow: Window Nr. ',WindowNr,' existiert nicht!'); Halt; end; with WindowStack[WindWerte gesetzt werden. Auswahl=13; NachOben=8; NachUnten=32; Zur Auswahl eines Punktes aus einem Menu werden die Tasten = chr(13), = chr(32) und = chr(8) verwendet. Durch [ndern der Konstanten k|nnen Sie die Steen:=wy+wh-10; end else begin {Stack leer} TextMode; writeln(^G,'CloseWindow: Alle Windows bereits geschlossen'); Halt; end; end; {PopWindow} begin {CloseWindow} ChangeWindow(Top); ToXY(wx,wy); P do begin ToXY(xc0,yc0); wb:=wb0; wh:=wh0; wx:=wx0; wy:=wy0; end; Top:=Top-1; Window:=Top; Links:=wx+2; Unten:=wy+4; Rechts:=wx+wb-2; Obn einem Record die Position der linken oberen Ecke in Bildkoordinaten (xc0,yc0), die Breite wb0, die H|he wh0, und die Position des Cursors beim letzten Verlassen des Windows gespeichert. Zus{tzlich wird die Anfangsadresse des Buffers f}r dWindow- h|he wh-2. Andernfalls wird eine Fehlermeldung ausgegeben. Durch den Aufruf 'PrintAt(1+Rechts-Links,1+Unten-Oben)' wird der Cursor beispielsweise in die untere rechte Ecke des aktuellen Windows gesetzt. procedure Print(s:longstring); DeWerte nicht }berpr}fen. function Screen(x,y:integer):byte; Durch die relativen Koordinaten (x,y) kann der Inhalt eines Bytes im Bild- wiederholspeicher (und damit das an dieser Position stehende Zeichen) bestimmt werden. Da f}r den Rahmen des Wimmen wie Konstanten benutzen. Links,Rechts,Unten,Oben:integer; Die Schreibgrenzen des aktuellen Windows in Bildkoordinaten. Mit ihnen ist die Positionierung durch die Standardprozedur GotoXY innerhalb eines Windows m|g- lich. 'GotoXY(Links,Unten)' swird eine Fehlermeldung ausgegeben und das Programm abgebrochen. procedure ClearLine; Die Zeile in der der Cursor momentan steht wird ab dem Cursor bis zum rechten Rand des Windows gel|scht. Die Cursorposition bleibt dabei unver{ndert. procedurdschirm. Zuvor mu~ auf dem Heap ein mindestens b*h Bytes gro~er Bereich reserviert worden sein. Das Window liegt mit der lin- ken oberen Ecke bei (x,y) und hat die Breite b und die H|he h. procedure LoadScreen(x,y,b,h,Ad:integer); Der Hintergrunden Hintergrund (die von einem Window }berdeckte Fl{che) festgehalten. Bildkoordinaten liegen beim Apple im Bereich von 1 bis 80 horizontal und 1 bis 24 vertikal. Sie werden bei der Positionierung mit der Standardprozedur GotoXY verwendet. Variablenrocedure ClearWindow; Das aktuelle Window wird neu auf dem Bildschirm gezeichnet. Der Inhalt wird dabei gel|scht. Der Cursor steht anschlie~end in der linken oberen Ecke. procedure OpenWindow(x,y,b,h:integer); Es wird ein neues Window mit der linndows jeweils 2 Zeilen bzw. Spalten ben|tigt werden, mu~ der Wert von x im Bereich 1 bis Windowbreite wb-2 und der Wert von y im Bereich 1 bis Windowh|he wh-2 liegen. Falsche Werte f}hren zu einer Fehlermeldung und dem Abbruch des Programms. ptellt den Cursor zum Beispiel in die linke untere Zeile des Windows. Da die Cursorposition in den Variablen xc,yc dabei nicht aktualisiert wird, verwenden Sie stattdessen besser die Prozedur PrintAt. WindowStack:array [0..MaxWindow] of WindowElemene PrintAt(x,y:integer); Diese Prozedur entspricht der PASCAL Standardprozedur GotoXY(x,y) f}r Windows. Der Cursor wird in die x-te Spalte der y-ten Zeile gesetzt. Die Werte von x bzw. y liegen dabei im Bereich von 1 bis Windowbreite wb-2 bzw. 1 bis eines Windows mit den angegebenen Abmessungen wird aus dem Speicher ab Adresse Ad wieder auf den Bildschirm kopiert. Die beiden letzten Prozeduren dienen zur Windowverwaltung. Sie sollten diese Prozeduren nicht explizit verwenden, da sie ihre : xc,yc:integer; Aktuelle Cursorposition in Bildkoordinaten. wx,wy,wb,wh:integer; Position der linken oberen Ecke des aktuellen Windows in Bildkoordinaten sowie die Windowbreite wb und die Windowh|he wh. Sie k|nnen diese Variablen in Ihren Prograken oberen Ecke an den Koordinaten (x,y) und einer Breite b und H|he h ge|ffnet. Der Cursor wird in die linke obere Ecke des Windows gesetzt. Wenn das Window nicht ganz auf dem Bildschirm passt oder die Breite oder die H|he kleiner als 3 sind, ls Stapelzeiger und enth{lt daher stets die Nummer des zuletzt ge|ffneten bzw. obersten Windows. Sie k|nnen diese Variablen in Ihren Programmen wie Konstanten benutzen. 2. Window-Befehle procedure InitWindow; Diese Prozedur l|scht den Bilt; Stapel zur Verwaltung der Windows. Zu jedem offenen Window werden hier dessen Werte gespeichert. Window,Top:0..MaxWindow; Die Variable Window enth{lt die Nummer des aktuellen Windows in dem gerade geschrieben wird. Die Variable Top dient ar String s wird im aktuellen Window ausgegeben. Zeilenvorschub und Scrollen werden bei Bedarf automatisch ausgel|st. Ein beabsichtigter Zeilenvorschub kann durch Ausgabe von '_' = chr(95) ausgel|st werden. Print benutzt bei der Ausgabe die PASCAen nennen zuerst den Namen der Prozedur bzw. Funktion, in der der Fehler auftrat. Dann folgt die Beschreibung des Fehlers. Das Programm wird anschlie~end abgebrochen. 5. Warnung Bei Verwendung der TURBO-PASCAL Version 1.0 d}rfen w{hrend ein W Dabei werden die Sonderzeichen f}r den Rand der Windows durch allgemein auf Druckern verf}gbare Zeichen ersetzt. Sollten Sie auf Ihrem Drucker auch Strichgrafik ausgeben k|nnen, {ndern Sie die Zeichen innerhalb der case-Anweisung. 3. Flip-Menuht von anderen }berdeckt wird. Andernfalls k|nnten Teile dieser Windows }berschrieben werden. Durch Verwendung der Prozedur TopWindow k|nnen Sie das verhindern. Sollte der Wert von WindowNr kleiner als 1 oder gr|~er als Top sein, wird eine Fehler- Wortlaut der einzelnen Optionen wird durch ein '_' = chr(95) getrennt im String s }bergeben. Es empfiehlt sich dem Text einer jeden Option ein Leerzeichen voranzustellen, da der Cursor bei der Auswahl auf das erste Zeichen einer Zeile gesetzt wird. Dt wenn kein Window mit dieser Nummer existiert. Da diese Prozedur ausgiebigen Gebrauch vom Heap macht, sollten Sie auf den verf}gbaren Speicherplatz achten. procedure CloseWindow; Das zuoberst liegende Window (nicht unbeding das aktuelle) wird gL Prozedur Write. Escape-Sequenzen oder Sonderzeichen geben Sie aber besser direkt mit Write aus. Beachten Sie, da~ der Bildschirm dabei nicht scrollen darf! procedure ChangeWindow(WindowNr:integer); Das aktuelle Window wird gewechselt. Nach Aufruem Bildschirm. Mit drei Steuertasten f}r 'Auswahl', 'Cursor nach unten' und 'Cursor nach oben' (normalerweise , und ) wird eine der angezeigten Optionen ausgew{hlt. Die Funktion gibt als Wert die Nummer der angew{hlten Op function FlipMenu(x,y,b:integer;s:longstring):integer; F}r eine schnelle Auswahl aus wenigen Optionen ohne dabei den Bildschirm zu ver{ndern eignet sich diese Funktion. Sie erzeugt ein sogenanntes Flip-Menu ({hnlich den Pull-down Menus) auf d meldung ausgegeben. procedure MoveWindow(x,y:integer); Das aktuelle Window wird mit der linken oberen Ecke an die neuen Koordinaten (x,y) verschoben. Ist dies nicht m|glich, weil kein Window offen ist oder die neuen Koordinaten keine komplette Die Breite sollte ausreichend gro~ gew{hlt werden, so da~ die Texte nicht durch Scrollen ausein- andergerissen werden. Sollte das Menu nicht komplett auf den Bildschirm pas- sen, wird eine Fehlermeldung erzeugt. 4. Fehlermeldungen Fehlermeldungeschlossen. Das aktuelle Window wird jetzt das direkt darunterliegende. Der Cursor steht an derselben Position, an der das Window zuletzt verlassen wurde. procedure ScreenDump; Der Inhalt des 80-Zeichen Bildschirms wird auf dem Drucker ausgegeben.f der Prozedur wird die Ausgabe in das Window mit der Nummer WindowNr gelenkt. Der Cursor wird an die Position gesetzt, an der das Window zuletzt verlassen wurde. Sie sollten diese Prozedur nur benutzen, wenn Sie sicher sind, da~ das neue Window niction zur}ck. Das Menu wird nach der Auswahl wieder vom Bildschirm entfernt und der Cursor hat die gleiche Position wie vorher. Die Position der linken oberen Ecke des Menus wird durch die Bildkoordinaten (x,y) und die Breite durch b festgelegt. Derntfernt und anschlie~end wieder in der neuen Reihenfolge angezeigt. Das angegebene Window ist dann das aktuelle Window und liegt nun zuoberst. Der Cursor steht an der Position, an der das Window zuletzt verlassen wurde. Eine Fehlermeldung erscheinarstellung des Windows auf dem Bildschirm zulassen, wird eine Fehlermeldung ausgegeben. procedure TopWindow(WindowNr:integer); Das Window mit der Nummer WindowNr wird }ber die anderen Windows gelegt. Dazu werden zun{chst die }berlappenden Windows eindow ge|ffnet ist keine neuen Variablen auf dem Heap erzeugt werden, da diese sonst nach dem Schliessen des Windows wegen Benutzung von MARK und RELEASE ung}ltig werden! 6. Beispiele Beispiele zur Verwendung der Window-Befehle finden Sie im Filexc,yc); end; {ClearWindow} procedure OpenWindow(x,y,b,h:integer); procedure PushWindow; begin if Top>=MaxWindow then begin write(^G,'OpenWindow: Maximal ',MaxWindow,' Windows'); Halt; end; with mem[(k+i) and $1FF +$EC00]:=mem[Ad+i]; end; Ad:=Ad+b; k:=k+80; end; end; {LoadScreen} function Screen(x,y:integer):byte; var k:integer; begin if (x<1) or (x>80) or (y<1) or (y>24) then begin if (i=0) or (i=b) then c:=Senkrecht else c:=ord(' '); mem[(k+i) shr 7 and $0C +$E0B0]:=0; mem[(k+i) and $1FF +$EC00]:=c; end; k:=k+80; end; for i:=0 to b do begin :integer; begin k:=(y-1)*80+(x-1); for j:=0 to h-1 do begin for i:=0 to b-1 do begin mem[(k+i) shr 7 and $0C +$E0B0]:=0; mem[Ad+i]:=mem[(k+i) and $1FF +$EC00]; end; Ad:=Ad+b; k: 'WINDDEMO.PAS'. Es demonstriert ihnen au~erdem das Flip-Menu und die Ausgabe des 80-Zeichen Bildschirms auf dem Drucker. ]bersetzen Sie dieses File wie gewohnt mit Ihrem TURBO-PASCAL System. Achten Sie dabei darauf, da~ es an Ihre Version angepasstcht=26; RechtsOben=28; Senkrecht=21; LinksUnten=19; RechtsUnten=25; var i,j,k,b,c:integer; begin b:=wb-1; k:=(wy-1)*80+(wx-1); for i:=0 to b do begin {oberer Rand} if i=0 then c:=LinksOben e write(^G,'Screen: Falsche Zeichenkoordinaten'); Halt; end; k:=(y-1)*80+(x-1); mem[k shr 7 and $0C +$E0B0]:=0; Screen:=mem[k and $1FF +$EC00]; end; {Screen} procedure ClearWindow; const LinksOben=22; Waagere{ Windowroutinen Apple II+ 80-Zeichen-Karte Klaus Rindtorff 16.8.85 } const MaxWindow=8; type longstring=string[255]; WindowElement=record xc0,yc0,wb0,wh0,wx0,wy0:integer; Buffer:^integer; if i=0 then c:=LinksUnten else if i=b then c:=RechtsUnten else c:=Waagerecht; mem[(k+i) shr 7 and $0C +$E0B0]:=0; mem[(k+i) and $1FF +$EC00]:=c; end; xc:=Links; yc:=Oben; GotoXY(=k+80; end; end; {SaveScreen} procedure LoadScreen(x,y,b,h,Ad:integer); var i,j,k:integer; begin k:=(y-1)*80+(x-1); for j:=0 to h-1 do begin for i:=0 to b-1 do begin mem[(k+i) shr 7 and $0C +$E0B0]:=0; wird. [ndern Die dazu gegebenenfalls die entsprechend gekennzeichneten Stellen des Includefiles 'WINDOW80.INC'. ]bersetzen Sie dieses File wie gewohnt mit Ihrem TURBO-PASCAL System. Achten Sie dabei darauf, da~ es an Ihre Version angepasstlse if i=b then c:=RechtsOben else c:=Waagerecht; mem[(k+i) shr 7 and $0C +$E0B0]:=0; mem[(k+i) and $1FF +$EC00]:=c; end; k:=k+80; for j:=1 to wh-2 do begin for i:=0 to b do begin wb:=82; wh:=26; Top:=0; Window:=0; Links:=1; Rechts:=80; Oben:=1; Unten:=24; with WindowStack[Top] do begin xc0:=xc; yc0:=yc; wx0:=wx; wy0:=wy; wb0:=wb; wh0:=wh; end; end; {InitWindow} procedure SaveScreen(x,y,b,h,Ad:integer); var i,j,k end; var xc,yc,Links,Rechts,Unten,Oben:integer; wx,wy,wb,wh:integer; WindowStack:array [0..MaxWindow] of WindowElement; Window,Top:0..MaxWindow; procedure InitWindow; begin write(^Z'0'); xc:=1; yc:=1; wx:=0; wy:=0; WindowStack[Window] do begin xc0:=xc; yc0:=yc; end; Top:=Top+1; Window:=Top; with WindowStack[Top] do begin xc0:=xc; yc0:=yc; wb0:=wb; wh0:=wh; wx0:=wx; wy0:=wy; end; end; {PushWindow} begilt[i],wb0*wh0); SaveScreen(wx0,wy0,wb0,wh0,ord(Inhalt[i])); LoadScreen(wx0,wy0,wb0,wh0,ord(Buffer)); end; Hilf1:=WindowStack[WindowNr]; WindowStack[WindowNr]:=WindowStack[Top]; WindowStack[Top]:=Hilf1; Hilf2:=InhaWindowNr<1) or (WindowNr>Top) then begin write(^G,'ChangeWindow: Window Nr. ',WindowNr,'existiert nicht!'); Halt; end; with WindowStack[Window] do begin xc0:=xc; yc0:=yc; end; Window:=WindowNr; nteger; begin j:=(yc-1)*80-1; for i:=j+xc to j+Rechts do begin mem[i shr 7 and $0C +$E0B0]:=0; mem[i and $1FF +$EC00]:=ord(' '); end; end; {ClearLine} procedure PrintAt(x,y:integer); begin if (Links+x-1>Rechts) or ; LoadScreen(wx,wy,wb,wh,ord(Inhalt)); FreeMem(Inhalt,wb*wh); GotoXY(xc,yc); end; {MoveWindow} procedure TopWindow(WindowNr:integer); var Inhalt:array [1..MaxWindow] of ^integer; Hilf1:WindowElement; Hilf2:^integer; i:integer end; {Scroll} begin {Print} GotoXY(xc,yc); for i:=1 to length(s) do begin if (xc>Rechts) or (s[i]='_') then begin xc:=Links; yc:=yc+1; if yc>Unten then Scroll n {OpenWindow} if (x<1) or (x>80) or (y<1) or (y>80) or (b<3) or (h<3) or (x+b-1>80) or (y+h-1>24) then begin write(^G,'OpenWindow: Falsche Window Parameter'); Halt; end; wx:=x; wy:=y; wb:=b; wh:=h; Links:=wx+1,y:integer); var Inhalt:^integer; begin if (Top<1) or (x<0) or (x+wb-1>80) or (y<0) or (y+wh-1>24) then begin write(^G,'MoveWindow: Window kann nicht verschoben werden'); Halt; end; GetMem(Inhalt,wb*wh); with WindowStack[Window] do begin xc:=xc0; yc:=yc0; wx:=wx0; wy:=wy0; wb:=wb0; wh:=wh0; end; Links:=wx+1; Rechts:=wx+wb-2; Unten:=wy+wh-2; Oben:=wy+1; GotoXY(xc,yc); end; {ChangeWindow} procedure MoveWindow(x(x<1) or (Oben+y-1>Unten) or (y<1) then begin write(^G,'PrintAt: Positionierung ausserhalb des Windows'); Halt; end; xc:=Links+x-1; yc:=Oben+y-1; GotoXY(xc,yc); end; {PrintAt} procedure Print(s:longstring; begin if (WindowNr<1) or (WindowNr>Top) then begin write(^G,'TopWindow: Window Nr. ',WindowNr,' existiert nicht'); Halt; end; for i:=Top downto WindowNr do with WindowStack[i] do begin GetMem(Inha else GotoXY(xc,yc); end; {neue Zeile} if s[i]<>'_' then begin write(s[i]); xc:=xc+1; end; end; end; {Print} procedure ChangeWindow(WindowNr:integer); begin if (; Rechts:=wx+wb-2; Unten:=wy+wh-2; Oben:=wy+1; PushWindow; with WindowStack[Top] do begin GetMem(Buffer,wb*wh); SaveScreen(wx,wy,wb,wh,ord(Buffer)); end; ClearWindow; end; {OpenWindow} procedure ClearLine; var i,j:i SaveScreen(wx,wy,wb,wh,ord(Inhalt)); {Inhalt} with WindowStack[Top] do begin LoadScreen(wx,wy,wb,wh,ord(Buffer)); xc:=xc-wx+x; yc:=yc-wy+y; wx:=x; wy:=y; wx0:=x; wy0:=y; SaveScreen(wx,wy,wb,wh,ord(Buffer)); end c:=mem[i and $1FF +$EC00]; mem[(i-80) shr 7 and $0C +$E0B0]:=0; mem[(i-80) and $1FF +$EC00]:=c; end; k:=k+80; end; xc:=Links; yc:=Unten; GotoXY(Links,Unten); ClearLine; ); var i:integer; procedure Scroll; var i,j,k,c:integer; begin k:=80*Oben+Links-1; for j:=0 to (Unten-Oben-1) do begin for i:=k to k+(Rechts-Links) do begin mem[i shr 7 and $0C +$E0B0]:=0; lt[WidowNr]; Inhalt[WindowNr]:=Inhalt[Top]; Inhalt[Top]:=Hilf2; for i:=WindowNr to Top do with WindowStack[i] do begin SaveScreen(wx0,wy0,wb0,wh0,ord(Buffer)); LoadScreen(wx0,wy0,wb0,wh0,ord(Inhalt[i])); +wb-2; Oben:=wy+1; GotoXY(xc,yc); end; {PopWindow} begin {CloseWindow} ChangeWindow(Top); with WindowStack[Top] do begin LoadScreen(wx,wy,wb,wh,ord(Buffer)); FreeMem(Buffer,wb*wh); end; PopWindow; end; {CloseWi until Ch=chr(Auswahl); CloseWindow; end; {FlipMenu}  NachUnten: if i1 then i:=i-1 else i:=Anzahl; end; FreeMem(Inhalt[i],wb0*wh0); end; Window:=WindowNr; ChangeWindow(Top); end; {TopWindow} procedure CloseWindow; procedure PopWindow; begin if Top<1 then begin write(^G,'CloseWindow: Alle Windows bereits gescndow} function FlipMenu(x,y,Breite:integer;s:longstring):integer; const Auswahl=13; NachOben=8; NachUnten=32; var i,Anzahl:integer; Ch:char; begin Anzahl:=1; for i:=1 to length(s) do if s[i]='_' then Anzahl:=Anzahl+1; 2T2Q2hlossen'); Halt; end; Top:=Top-1; Window:=Top; with WindowStack[Top] do begin xc:=xc0; yc:=yc0; wb:=wb0; wh:=wh0; wx:=wx0; wy:=wy0; end; Links:=wx+1; Unten:=wy+wh-2; Rechts:=wx22P2R2U2W Print(s); i:=1; repeat GotoXY(x+1,y+i); read(kbd,Ch); case ord(Ch) of Auswahl: FlipMenu:=i; NachUnten: if i1 then i:=i-1 else i:=Anzahl; end; if (Anzahl+2>24) or (Breite>80) or (Breite<3) or (x+Breite-1>80) or (x<1) or (y+Anzahl+1>24) or (y<1) then begin write(^G,'FlipMenu: Falsche Menu Parameter'); Halt; end; OpenWindow(x,y,Breite,Anzahl+2);