Wie schon in der letzten Ausgabe der 'ST-Computer' beschrieben wurde, kann man mit Hilfe von GEM-Routinen viele nützliche Eigenschaften des ATARI ST erreichen, die leider im ST-Basic nicht enthalten sind. Der eigentliche Aufruf dieser Routinen erfolgt durch Angabe der jeweiligen Funktionsnummer und der dazugehörenden Parameter in den vordefinierten Feldern 'CONTRL, INTIN, PTSIN' mit anschließendem 'VDISYS'-Befehl.
Zur Erleichterung und zur Bewahrung des Überblicks wurden die GEM-Routinen in Unterprogramme eingebaut, die durch einen Namen, der dem Sinn der Routine entspricht, aufgerufen werden. Sämtliche Unterprogramme sind so aufgebaut, daß man sie alle gleichzeitig in einem Programm nutzen kann, deshalb sollten die Zeilennummern übernommen werden. Der Aufruf erfolgt wie bei jedem anderen Unterprogramm durch 'Gosub Programmname', jedoch müssen vorher die benötigten Variablenwerte übergeben werden.
Eine nützliche Eigenschaft der verwendeten GEM-Routinen ist, daß fast alle mit normalen Basicbefehlen kombinierbar sind.
63000 MAUS:
63002 ' <— XMAUS,YMAUS,KEY
63004 poke contrl ,124
63006 vdisys
63008 xmaus =peek(ptsout)-1
63010 ymaus =peek(ptsout +2)-38
63012 key =peek(intout)
63014 return
63016 '------------------------
Einer der wichtigsten Bestandteile des GEM, stellt die Maus dar, denn ohne dieses hilfreiche Tierchen wäre der ATARI ST wohl kaum noch denkbar. Denjenigen, die auch in Basic auf dieses Hilfsmittel nicht verzichten wollen, können auf einige GEM-Routinen zurückgreifen. Die interessanteste Routine ist die zur Abfrage der Mausposition und der Maustasten. Die dadurch entstehenden Möglichkeiten sind vielfältig, sie reichen von Eingabemenüs, bei denen die Abfrage der Menüpunkte nicht mehr mit Zahlen oder Buchstaben erfolgt, sondern durch einfaches Anklicken, bis hin zu grafischen Anwendungen, bei denen die Fähigkeiten dieser Routine erst zur Geltung kommen. Der Aufruf dieses Unterprogrammes erfolgt durch:
Gosub Maus
Routine Maus
5 ' merge "MAUS.bas"
9 '
10 fullw 2: clearw 2
20 color 1, 1 , 1 , 1, 1
30 Start: gosub maus
40 if key =1 then pcircle xmaus,ymaus,5,0,3600:
50 if key =2 then gotoxy 0,0 : print xmaus,ymaus
60 if key =3 then clearw 2
70 goto start
Listing 1: Maus demo
Die Routine liefert die gewünschten Werte in den Variablen 'XMAUS; YMAUS; KEY', wobei in XMAUS und YMAUS die Koordinaten der Maus enthalten sind.
Die Koordinaten sind in Bezug auf das Output-Window normalisiert, da diese Routine, genau wie alle anderen VDI-Routinen, direkt den Bildschirm ansprechen. Die Variable 'KEY' enthält die Informationen über beide Maustasten, wobei 'Bit 0' bei der linken Taste und 'Bit 1' bei der rechten Taste eine Eins enthält. Somit sind drei Zustände abfragbar:
gedrückte Taste Wert in 'KEY'
links 1
rechts 2
links + rechts 3
Ein einfaches Beispiel zu dieser Routine zeigt Listing 1.
Der ATARI ST hat noch einige andere Maussymbole zur Verfügung, welche auch in Basic eingeschaltet werden können (Siehe Bild 1). Zur Realisierung dieser Funktion wurde ein kleiner Abstecher in die AES-Programmierung unternommen. Auf das Prinzip dieser Programmierung soll hier aber nicht näher eingegangen werden.
Der Aufruf erfolgt durch:
MAUS NR = 0 .. 7 :
Gosub MAUSFORM
63280 MAUSFORM:
63282 ' --> MAUSNR
63284 ' 0-7
63286 if mausnr >7 then return
63288 add#=gb
63290 gintin=peek(add#+8)
63292 addrin=peek(add#+16)
63294 poke gintin,mausnr
63296 poke addrin,0
63298 gemsys(78)
63300 return
63302 '------------------------
Routine MAUSFORM
Bei einigen Anwendungen kann es lästig werden, daß das Maussymbol (Grafikcursor) des öfteren nicht auf dem Bildschirm zu sehen ist, denn bei jeder Bildschirmausgabe oder bei der Tastatureingabe wird es unsichtbar. Erst wenn man die Maus bewegt, erscheint das Symbol wieder. Man kann es aber auch per GEM-Befehl sichtbar machen.
Bei dem hier angegebenen Unterprogramm geschieht dies durch:
Gosub SHOWMAUS
Entsprechend zu dieser GEM-Routine, existiert noch eine weitere zum Unsichtbarmachen des Grafikcursors (Funktionsnummer 123), die allerdings in Basic, außer eventuellen Blinkeffekten, keine bedeutende Anwendung findet.
63030 showmaus:
63032 poke contrl,122
63034 poke intin,0
63036 vdisys
63038 return
63040 '-----------------
Routine SHOWMAUSE
Wem diese sechs zusätzlichen Maussymbole nicht genügen, dem steht die Möglichkeit offen, eigene Symbole zu entwerfen. Bei manchen Programmen, die auf die Maus zurückgreifen ist es sinnvoll, wenn das Maussymbol etwas über die momentane Aufgabe des Programmes aussagt (z. B. Stift, Pinsel, Radiergummi).
Eine Möglichkeit zum freien Gestalten des Maussymbols bietet die VDI-Routine Nr. 111, die auch im folgenden Unterprogramm benutzt wird. Vor Aufruf dieser Routine muß das Muster des Maussymbols und das Hintergrundmuster, jeweils aus 16 Worten je 16-Bit bestehend, in bestimmten Speicherzellen übergeben werden.
Das Hintergrundmuster gibt an, welche Punkte des Feldes (16*16) unter dem Maussymbol sichtbar bleiben und welche generell gelöscht werden. Dies ist wichtig, wenn sich die Maus über dunkle Flächen bewegt. Es ist daher empfehlenswert, die Hintergrundmaske immer etwas größer zu wählen als das eigentliche Mausmuster.
In Speicherzellen 'INTIN +8' wird angegeben, ob das Muster schwarz oder weiß angezeigt wird, in Speicherzelle 'INTIN +6' die entsprechende Farbinformation des Hintergrundes.
'INTIN +2' und 'INTIN +4' legen den Punkt innerhalb des Mauszeigers fest, der bei der Positionsabfrage dem Grafikcursor entspricht. So sollte beispielsweise bei einem Pfeil dieser Punkt an der Pfeilspitze liegen.
Bei diesem Programm wurden verschiedene Maussymbole in Data-Zeilen gespeichert. Vor dem Lesen dieser Datas muß der Data-Zeiger auf die jeweiligen Datas gesetzt werden.
Der Aufruf erfolgt somit durch:
Restore Datazeile
Gosub MAUSDATA
Daraufhin erscheint das gewählte Maussymbol.
63140 '----------MAUSDATAS-------------
63141 hammer:
63142 data 96,480,960,1984,3968,8064
63143 data 7936,16256,15872,32512,32512,65408
63144 data 65408,65472,63424,65504,25568,65520
63145 data 496,62456,248,508,124,254
63146 data 62,127,31,63,14,31
63147 data 4,14
63150 kaffee :
63151 data 4624,16184,9248,32376,4640,16368
63152 data 4672,16352,4384,16352,2624,8128
63153 data 0,16320,16352,32764,16380,32766
63154 data 16358,32767,16354,32767,16358,32767
63155 data 16380,32767,16352,32766,8128,16352
63156 data 0,8128
63160 wurm:
63161 data 0,8064,8064,16320,16320,32736
63162 data 26208,65520,30560,65520,32736,65532
63163 data 29132,65534,16318,32767,8054,16383
63164 data 7782,16383,7372,16382,7384,16380
63165 data 4080,8184,2022,4095,60,2046
63166 data 24,62
63199 ' ---------------------------------------
63200 mausdata:
63202 ' --> restore zeile
63204 for a=0 to 15
63206 read mustervor,musterhinter
63208 poke intin +a*2+42 ,mustervor
63210 poke intin +a*2+10 ,musterhinter
63212 next
63214 '-------------------------
63250 mausneu:
63252 poke contrl,111
63254 poke contrl+6,37
63256 poke intin,5
63258 poke intin+2,5
63260 poke intin+4,1
63262 poke intin+6,0
63264 poke intin+8,1
63266 vdisys
63268 out 2,7
63270 return
Routine: MAUSDATA
5 ' merge "MAUSDATA.bas"
6 ' merge "SHOWMAUS.bas"
9 '
10 restore wurm : gosub mausdata :gosub showmaus
20 warte =inp(2)
30 restore hammer : gosub mausdata :gosub showmaus
40 warte =inp(2)
50 restore kaffee : gosub mausdata :gosub showmaus
60 warte =inp(2)
70 end
Listing 2: MAUS SYMBOL
Das Programm 'MAUSEDITOR' dient zum einfachen Erstellen von Maussymbolen. Es rechnet die benötigten dualen Bitmuster-Werte in Dezimalwerte um und macht die sonst doch sehr mühselige Umrechnung mit Bleistift und Taschenrechner überflüssig. Weiterhin speichert sie die errechne-ten Werte in die zum GEM-Aufruf notwendigen Speicherzellen.
Nach Eingabe von
Gosub MAUSEDITOR
erscheint das neu berechnete Maussymbol auf dem Bildschirm.
Die dezimalen Werte des Mausmusters und seines Hintergrundmusters sollten nach Fertigstellung notiert und aus Geschwindigkeitsgründen in Data-Zeilen abgelegt werden (siehe Programm Mausdata).
Bei jedem Diskettenzugriff schaltet der Basic-Interpreter wieder den normalen Mauspfeil ein. Das neudefinierte Symbol kann in diesem Falle wieder eingeschaltet werden durch
Gosub Mausneu
63050 MAUSEDITOR:
63052 dim a$(16),b$C16)
63054 a$(0) = "-*—*-----*----":b$(0) = "— ******—***--"
63056 a$(1) = "--*--*-*-----":b$(1) = "-******—****-"
63058 a$(2) = "--*--* *----" : b$(2) = "—**********---"
63060 a$(3) = "--*--*— *----" : b$(3) = "—*********----"
63062 a$(4) = "--* * — *----":b$(4) = " — *********--"
63064 a$(5) = "--*-* — *----":b$(5) = "-*******-----"
63066 a$(6) = "--------------" : b$(6) = " — ********-"
63068 a$(7)="—*********----------":b$(7)="-*************—"
63070 a$(8)="—************—":b$(8)="-**************-"
63072 a$(9)="--*********--**-":b$(9)="-***************"
63074 a$(10)=" — *********-*-":b$(10) = "-***************"
63076 a$(11)="--*********—**-":b$(11)="-***************"
63078 a$(12)="—************--":b$(12)="-***************"
63080 a$(13)="--*********-----":b$(13)="-**************-"
63082 a$(14)= "-*******-":b$(14)= "—*********------"
63084 a$(15)= "------------" :b$(15) = "-*******----*"
63086 for a=0 to 15
63088 mustervor =0 :musterhinter =0
63090 for b=15 to 0 step -1
63092 if mid$(aß(a),b+1,1)="*" then bit=1 else bit=0
63094 mustervor = mustervor+2^(15-b)*bit
63096 if mid$(b$(a),b+1,1)="*" then bit=1 else bit =0
63098 musterhinter=musterhinter+Ä(15-b)*bit
63100 next
63102 poke intin +a*2+42 ,mustervor
63104 poke intin +a*2+10 ,musterhinter
63106 ' lprint mustervor,musterhinter
63108 next
63110 goto mausneu
63112 '---------------------------------------------------
63250 mausneu:
63252 poke contrl,111
63254 poke contrl+6,37
63256 poke intin,5
63258 poke intin+2,5
63260 poke intin+4,1
63262 poke intin+6,0
63264 poke intin+8,1
63266 vdisys
63268 out 2,7
63270 return
63272 '---------------
Routine MAUSEDITOR
Falls Sie durch dieses Programm angeregt werden und selbst eigene Maussymbole entwerfen, so können Sie uns diese gerne zuschicken. Wir werden einige in den nächsten Ausgaben veröffentlichen.
Es handelt sich hierbei um verschiedene Zeichen, die als Markierungen auf den Bildschirm gesetzt werden können. Es stehen folgende Zeichen (siehe Bild) zur Verfügung:
Außer dem Punkt können alle diese Markierungsarten in nahezu beliebiger Größe dargestellt werden.
Der Aufruf erfolgt durch:
XPOS= .. ; YPOS= .. ;
MARKERTYP = ..
MARKERGROESSE = ..
GOSUB POLYMARKER
Zum Darstellen einer weiteren Markierung kann man das Unterprogramm aufrufen mit:
XPOS= .. : YPOS = .. :
GOSUB MARKERSETZEN
Falls man gleichzeitig mehrere Markierungen setzen will, beispielsweise zum Markieren bestimmter Punkte in einem Diagramm, so ist dies auch mit dieser Routine möglich. Dazu muß man die weiteren Ortsparameter in die Speicherzellen (PTSIN+4, PTSIN+6, ...) schreiben und in die Speicherzelle 'CONTRL +2' die Anzahl der zu setzenden Markierungen.
Zum Löschen einer Markierung kann man theoretisch dieselbe Markierung an der gleichen Stelle mit der Farbe des Hintergrundes zeichnen. Dies hat aber zwangsweise den Verlust der Hintergrundinformation zur Folge und den Nachteil, daß man nicht auf dunklen Hintergrund zeichnen kann. Abhilfe schafft eine schon früher erwähnte GEM-Routine ('Grafikmodus'), welche den Modus bestimmt, mit der Text oder Grafik auf dem Bildschirm erscheinen. Für unsere Anwendung ist Modus '3' besonders geeignet. Es handelt sich hierbei um eine Exclusiv-ODER Verknüpfung des zu setzenden Bildpunktes mit dem schon vorhandenen. Durch zweimaliges Aufrufen einer beliebigen Bildschirmausgabefunktion, erhält man wieder die ursprüngliche Bildschirminformation; der Hintergrund bleibt also erhalten. Interessant ist dies beim kurzzeitigen Anzeigen von Markierungen, oder wenn man z. B. einen Kommentar in das Bild einblenden will, der später wieder verschwinden soll, ohne den Hintergrund mit zu löschen (siehe Bild 2).
63400 polymarker:
63402 '—> XPOS 5 YPOS
63404 '—> MARKERTYP ; MARKERGEOESSE
63406 '
63408 poke contrl,18
63410 poke contrl+2,0
63412 poke contrl+6,1
63414 poke intin, markertyp
63416 vdisys
63418 poke contrl,19
63420 poke contrl+2,1
63422 poke contrl+6,0
63424 poke ptsin,O
63426 poke ptsin+2 ,markergroesse
63428 vdisys
63430 '
63432 markersetzen:
63434 ' (—> XPOS ; YPOS)
63436 poke contrl,7
63438 poke contrl+2,1: ' oder mehr
63440 poke ptsin,xpos+1
63442 poke ptsin+2,ypos+38
63444 vdisys
63446 return
63466 '--------------------
65130 GRAFIKMODUS:
65132 ' —> MODUS
65134 ' 1 = ueberschreiben 2 = mischen
65136 * 3 = XOE-verknuepfen 4 = revers,misehen
65138 poke contrl ,32
65140 poke contrl+2,0
65142 poke contrl+6,1
65144 poke intin,modus
65146 vdisys
65148 return
65150 '----------------------------------------------
Routine POLYMARKER
5 ' merge "POLYMARKER.bas"
6 ' merge "GRAFIKMODUS.bas"
9 '
10 fullw 2: clearw 2
20 color 1, 1, 1 , 1, 1
30 modus = 3: gosub grafikmodus
40 pellipse 310,200,140,80,0,3600
50 Start:
60 xpos=50 : ypos=160:markergroesse=50
70 for markertyp = 1 to 7
80 xpos=xpos+60
90 gosub polymarker
100 next
110 gotoxy 15,11: print "Textausgabe
120 warte = inp(2)
130 goto start
Listing 3: Markierungen
Mit Hilfe der 'POLYLINE'-Funktion können mehrere Punkte verbunden werden. Prinzipiell ist dies auch mit dem normalen 'LINEF'-Befehl möglich, aber die GEM-Routine arbeitet schneller (siehe Beispiel). Diese Routine eignet sich beispielsweise zum Verbinden von errechneten Werten (in einem Diagramm) oder sonstiger Punkte (siehe Bild 3). Ein weiteres Anwendungsgebiet wäre das Verknüpfen von Eckpunkten eines dreidimensionalen Körpers, da es dort besonders auf hohe Geschwindigkeit ankommt.
Aufruf durch
XKOORD (1,...,n)
YKOORD (1,...,n)
Gosub POLYLINE
64300 POLYLINE:
64302 poke contrl,6
64304 poke contrl+6,0
64306 poke contrl+2,anzahl
64308 for i=0 to anzahl
64310 poke ptsin +i*4,xkoord(i)+1
64312 poke ptsin +2+i*4,ykoord(i)+38
64314 next
64316 vdisys
64318 return
64320 '---------------------
Routine POLYLINE
5 ' merge "polyline.bas"
9 '
10 dim xkoord(200),ykoord(200)
20 fullw 2:clearw 2
30 anzahl=80
40 for i=0 to anzahl
50 xkoord(i) = 10+i*600/anzahl
60 ykoord(i) = 100+rnd(1)*200
70 next
80 gosub polyline
90 warte=inp(2)
100 end
Listing 4: Linienbefehl
Ein ähnlicher Befehl wie der vorherige, aber weitaus interessanter, ist der 'POLYGON'-Befehl. Mit ihm können Flächen zwischen verschiedenen Punkten ausgemalt werden (Bild 4). Im Gegensatz zu einem Basic-Programm mit 'LINEF' und 'FILL'-Befehlen arbeitet diese GEM-Routine wiederum wesentlich schneller. Es können hiermit auch alle erdenklichen geometrische Gebilde erzeugt werden. Das Füllmuster kann mit dem 'CO-LOR'-Befehl definiert werden.
Aufruf durch
XKOORD (1,...,n)
YKOORD (1,...,n)
Gosub POLYGON
5 ' merge "POLYGON.bas"
9 '
10 dim Xkoord (20),Ykoord(20)
20 color 1,1,1, 7,2
30 fullw 2: clearw 2
40 ecken =6
50 for i= 1 to ecken
60 read xkoord(i),ykoord(i)
70 next
80 gosub polygon
90 warte = inp(2)
100 end
110 data 10,100, 400, 40, 250,200
120 data 380,290, 150,230, 70,240
Listing 5: POLYGON
64140 polygon:
64142 * —> K00RD C )
64144 poke contrl,9
64146 poke contrl+6,0
64148 poke contr1+2,ecken
64150 for i=1 to ecken
64152 poke ptsin+Ci- 1)*4,xkoordCi) + l
64154 poke ptsin+2+Ci-1)*4,ykoordCi)+38
64156 next
64158 vdisys
64160 return
64162 '-----------------------
Routine POLYGON
Dabei handelt es sich um eine spezielle Anwendung des POLYGON-Befehls. Er bietet die Möglichkeit, symmetrische Vielecke mit beliebiger Eckenzahl zu erzeugen (siehe Bild 5). Dazu gehören beispielsweise Dreiecke oder Vierecke, deren Ausrichtung zur horizontalen Achse beliebig ist. Wünscht man eine andere Lage der Figuren, so kann man den Anfangs- und Endwinkel im Unterprogramm entsprechend verschieben.
Der Aufruf erfolgt durch:
XPOS = .. ; YPOS = : RADIUS = .. ; ECKEN = GOSUB VIELECK
Das Füllmuster des entstehenden Vieleckes sollte vor dem Aufruf mit dem COLOR -Befehl definiert werden.
5 ' merge "VIELECK.bas"
9 '
10 fullw 2:clearw 2
20 color 1,1,1,7,2
30 xpos=-50 : ypos =150
35 radius=50
40 for ecken = 3 to 7
50 xpos =xpos+120
55 gosub Vieleck
60 next
70 warte = inp(2)
80 end
Listing 6: Vieleck
64100 VIELECK:
64102 ' —> XPOS ; YPOS
64104 ' —> RADIUS ; ECKEN
64106 phi=3.141593/ecken/2
64108 Stern:
64110 ' —> PHI
64112 poke contrl,9
64114 poke contrl+6,0
64116 poke contrl+2,ecken
64118 for eck=0 to ecken*4 Step 4
64120 poke ptsin +eck, 1 +xpos+cos(phi*eck )*radius
64122 poke ptsin+(eck+2),38+ypos+sin(phi*eck)*radius
64124 next
64126 vdisys
64128 return
64130 '----------------------------
Routine VIELECK
Obwohl es, unter Berücksichtigung der Jahreszeit, eher angebracht wäre, Ostereier zu produzieren, so soll doch auf diesen Weihnachtsnachtrag eingegangen werden. Es handelt sich hierbei um die leicht abgeänderte Form der vorherigen 'Vieleck-Routine', die, in Abhängigkeit von dem Winkel 'Phi', teils Sterne und teils bizarre Muster produziert (Bild 6). Beachtenswert ist hierbei die Geschwindigkeit, mit der eine solche Figur gezeichnet wird. (HS)
Fortsetzung folgt:
5 ' merge "VIELECK.bas"
9 '
10 fullw 2:clearw 2
20 color 1,1,1,8,2
30 ypos =150 :radius=50
40 ecken =7
50 xpos =100:phi=3.1416/2/ecken*2 : gosub stern
60 xpos =200:phi=3.1416/2/ecken*3 : gosub stern
70 xpos =300:phi=3.1416/2/ecken*2.8: gosub stern
80 xpos = 400:phi=3.1416/2/ecken*1.7: gosub stern
90 xpos =500:phi=3.1416/2/ecken*2.5: gosub stern
100 ecken =11:ypos=250
110 xpos =100:phi=3.1416/ecken*1.5: gosub stern
120 xpos =200:phi=3.1416/ecken*2 : gosub stern
130 xpos =300:phi=3.1416/ecken*2.5 : gosub stern
140 xpos =400:phi=3.1416/ecken*1.9 : gosub stern
150 xpos =500:phi=3.1416/ecken*2.6 : gosub stern
160 warte=inp(2)
170 end
Listing 7: Sterne