GEM-Routinen Teil 2

Grundprinzip

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.

Mausabfrage Position & Tasten

		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.

Mausform


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

Showmaus

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

Definieren des Maussysmbols

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

Mauseditor

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.

Polymarker

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).


Bild 2: Polymarker & Grafikmodus 3

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

Polyline


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

Füllfläche


Bild 4: ausgefüllte Fläche

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

Vieleck


Bild 5

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

Stern

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:


Bild 6: Sterne & bizarre Figuren
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



Aus: ST-Computer 03 / 1986, Seite 34

Links

Copyright-Bestimmungen: siehe Über diese Seite