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

Links

Copyright-Bestimmungen: siehe Über diese Seite