Einführung in GEM (Teil 4)

Clipping

Bei intensiver Nutzung der GEM-Routinen kann es schon manchmal zu unangenehmen Begleiterscheinungen kommen, einfach gesagt, zu einem Programmabsturz. Sei es durch nicht initialisierte AES-Befehle oder durch falsche Parameter bei der Bildschirmausgabe. Gegen die zweite Ursache, die auftritt, wenn Ausgabebefehle einen Bereich weit außerhalb des Bildschirms ansprechen, existiert eine Routine, die die ßildschirmausgabe auf einen bestimmten Bereich beschränkt. Dadurch werden alle illegalen Bildschirmkoordinaten eliminiert. Natürlich kann auch ein kleiner Ausschnitt gewählt werden. Die darauffolgenden GEM-Grafikbefehle finden dann nur innerhalb des definierten Bereiches statt. Die Größe des Ausschnittes wird in diesem Unterprogramm in den Variablen ’XPOSl; YPOS1; XPOS2; YPOS2’ angegeben. Diese Routine arbeitet nur mit den GEM-Routinen zusammen, bei Basic-Ausgabebefehlen wird das Clipping nicht beachtet, bzw. sogar ausgeschaltet, so daß nachfolgende GEM-Ausgaberoutinen den gesamten Bildschirm ansprechen. Das angegebene Beispiel demonstriert die Funktionsweise dieses Befehls. Prinzipieller Aufruf:

XPOS 1 = .. : YPOS1 = ..: 
XPOS2 = .. : YP0S2 :
Gosub CLIPPING

Diese Routine erspart beispielsweise bei Kurvendiskussionen die ständige Abfrage, ob die errechneten Werte außerhalb des erlaubten Bereiches liegen, und erleichtern bzw. beschleunigen die Berechnung.

64200 CLIPPING:
64202 ' —> XPOS1, YPOS1, XPOS2, YPOS2 
64204 poke	contrl ,129
64210 poke	intin, 1	'Ausschnitt ein (0=aus)
64212 poke	ptsin ,XPOS1	'0
64214 poke	ptsin+2,YPOS1	'0
64216 poke	ptsin+4,XPOS2	'600
64218 poke	ptsin+6,XPOS2	'400
64220 vdisys
64222 return
64224 '-------------------------------

Routine CLIPPING

Definieren des Füllmusters

Trotz der vielen vorgegebenen Füllmuster soll dennoch auf die Möglichkeit zum freien Definieren des Musters hingewiesen werden. Bei dem Füllmuster handelt es sich um ein 16^ 16 Bit großes Muster, das bei allen ausfüllenden Grafikoperationen zur Geltung kommt. Dazu gehören neben den Basic-Befehlen ’PCIRCLE; PELLIPSE; FILL’ auch die schon zuvor besprochenen GEM-Routinen ’RECHTECK’, ’RECHTECKRUND’ und 'POLYGON’.

Die Werte des Füllmusters, bestehend aus 16 Worten (2 Byte), werden hierbei in Data-Zeilen abgelegt und mit dem dazugehörenden Namen versehen. Die Definition des neuen Musters geschieht durch:

Restore MUSTER 
Gosub FUELLMUSTER

Die Aktivierung dieses Musters wird durch ’COLOR 1,1,1,1,4 vorgenommen.

63500 FUELLMUSTER:
63502 ' —> restore MUSTER 
63504 poke contrl,112 
63506 poke contrl+6,16 
63508 for st=0 to 30 step 2 
63510 read muster 
63512 poke intin+st,muster 
63514 next : vdisys 
63516 return
63518 ’---------------------

Routine FÜLLMUSTER

5	’merge "FUELLMUSTER.bas“
6	’merge “RECHTECK.bas“
7	’merge “RECHTECKRUND.bas“
9	'
10	fullw 2 :clearw 2
20	WURM:
30 data 0,8064,16320,26208,30560,32736
40	data 29132,16318,8054,7782,7372,7384
50	data 4080,2022,60,24
60	RESTORE WURM:	gosub fuellmuster
70	color 1 , 1 , 1 , 1,4
80	pellipse 130,100,100,60
90	'
100 xpos1= 270:ypos1-30 : xpos2=350:ypos2=300 
110	gosub rechteck
120	'
130 xpos1 — 400:ypos1 = 200: xpos2=500:ypos2=300
140	fuell=1: gosub rechteckrund
150	'
160	warte= inp(2)
170	end

Listing 2: Definition eines Füllmusters

Zeichenhöhe

Zwei der interessantesten GEM-Routinen sind laut Leserzuschriften — die zum Verändern der Schriftart und der Schriftgröße, welche schon im ersten Teil des Kurses besprochen wurden. Eine weitere Routine erlaubt auf dem Monochrommonitor die Größendefinition des Zeichensatzes in 24 Stufen (siehe Bild). Die Routine arbeitet mit allen Schriftarten zusammen (kursiv, ...). Alle Schriftarten, die von der Normalgröße abweichen, können nicht per ’PRINT’ ausgegeben werden, da dieser Befehl nur auf Standardgröße ausgelegt ist. Hierzu dient die GEM-Ausgaberoutine.

Der Aufruf erfolgt durch:

ZEICHENHOEHE = (3 .. 26) : 
Gosub ZEICHENHOCH

Bei monochromem Monitor beträgt der Parameter der normalen Schrifthöhe ’12’, bei einem Farbmonitor hingegen, auf Grund der niedrigeren Vertikalauflösung, ’6’. Die unterschiedlichen Auflösungsstufen eines Farbmonitors sind auch dafür verantwortlich, daß die entstehenden Schriftgrößen nicht denen eines Monochrommonitors entsprechen, sondern grundsätzlich größer sind.

5	’merge "ZEICHENHOCH.bas“
6	’merge "TEXTAUSGABE.bas“
7	’merge "GRAFIKAUSSCHNITT.BAS"
9	'
10	fullw 2:clearw 2
20	XPOS1=0:YPOS1=0:XPOS2=600:YP0S2=360
30	gosub grafikausschnitt
40	for zeichenhoehe= 1 to 12
50	gosub zeichenhoch
60	xpos=30 :ypos=25*zeichenhoehe
70	text$=“Sehriftgroesse !"
80	gosub textausgabe:	next
90	xpos=300: ypos=0
100	for zeichenhoehe= 13 to 26
110	gosub zeichenhoch
120 ypos=ypos+zeichenhoehe+4 : gosub textausgabe:next 
130 zeichenhoehe=13: gosub zeichenhoch
140	warte=inp(2):end

Listing 3: Einstellen der Zeichenhöhe

65300 ZEICHENHOCH:
65302 '--> ZEICHENHOEHE
65304 poke contrl,12 
65306 poke ptsin+2,zeichenhoehe 
65308 vdisys 
65310 return 
65312 ' ------------------------

Routine ZEICHENHÖHE

Entsprechendes gilt für die Routine 'Schriftgröße’ die schon im ersten Teil erwähnt wurde. Der Unterschied zwischen diesen zwei Routinen besteht in der Schrittweite, in der die verschiedenen Größen angegeben werden können.

'Schriftgroesse' läßt nur sechs Größenstufen zu, während ’Schrifthöhe’ durch Bildung von Zwischenstufen eine fast kontinuierliche Größe ermöglicht, bei denen einige allerdings etwas unsauber abgebildet werden. Für bestimmte Anwendungen ist es aber sicher von Vorteil, eine passende Schrift auszuwählen. Bei mittlerer oder niedriger Auflösungsstufe (Farbe) stehen die kleinsten Größen nicht zur Verfügung.

Rahmung

Normalerweise werden alle Grafikoperationen, die ein Füllmuster beinhalten, mit einer Linie umrahmt. Mit der folgenden Routine kann dieser Effekt ausgeschaltet werden.

RAHMEN = (0 , 1) :
Gosub UMRAHMUNG

Bei Aneinanderreihung von Füllkörpern entsteht so eine geschlossene Fläche.

Die Funktion arbeitet mit folgenden Basic- bzw. GEM-Befehlen zusammen:

Routine UMRAHMUNG

5	’merge ”UMRAHMUNG.bas "
9	'
10	fullw 2: clearw	2
20	color 1, 1, 1,3,3
30	rahmen=1 :gosub umrahmung
40	pcircle 150,150,100,0,2800
50	rahmen=0 :gosub umrahmung
60	pcircle 400,150,100,0,2800
70	warte = inp(2)
80	end

Listing 4: Umrahmung ein/aus

Mausbefehle

Das AES bietet auch einige interessante Befehle, die von der Maus unterstützt werden. Neben der auch im VDI enthaltenen 'Position & Tastenabfrage’, existiert eine Routine, die kontrolliert, ob sich die Maus in einem bestimmten Rechteck befindet, und eine weitere, die das Markieren von Bildschirmbereichen ermöglicht.

Dabei ist zu beachten, das AES-Routinen einer Initialisierung durch ’INIT’ bedürfen.

# Routine INIT
62900 INIT:
62902 aes#=9b 
62904 control = peektaesH) 
62906 global = peek(aes#+4 ) 
62908 giritiri = peek(aes#+8 ) 
62910 gintaut = peek(aes#+12) 
62912 addriri = peek(aes#+16) 
62914 addrout = peek(aes#+20) 62916 return
62918 ’---------------------

MOUSE

Diese Routine enthält die gleichen Funktionen wie die VDI-Routine zur Mausabfrage. Mit ihr kann die Position der Maus und die Information über die Maustasten ermittelt werden. Zusätzlich gibt sie noch den Status der 'CONTROL, ALTERNATE’ und den beiden 'SHIFT’-Tasten zurück.

# Routine MOUSE 62550 MOUSE: 62552 ' <— MAUSX l MAUSY 62554 ' <— TASTE; KEY 62556 mausx=peek(gintout+2)-1 62558 mausy=peek(gintout+4)-38 62560 taste=peek(gintout+6) 62562 key = peek(gintout+8) 62564 gemsys 79 62566 return 62568 ’------------------------

Der Aufruf erfolgt durch:

Gosub MOUSE

Die Informationen über Mausposition, Maustasten und der Tastatur sind anschließend in den Variablen MAUSX, MAUSY, TASTE und KEY enthalten. Die erhaltenen Werte sind folgendermaßen zu interpretieren.

TASTE:

Taste Wert
links 1
rechts 2
links + rechts 3

KEY:

Taste Wert
Shift rechts 1
Shift links 2
Control 4
Alternate 8
5	' merge "INIT.bas“
6	' merge “MOUSE.bas“
9	'
10	gosub init
20	Start:
30	gosub mouse
40	print mausx,mausy,taste,key
50	goto Start

Listing 5: Abfrage der Mausposition

Mausereignis

Diese Routine kontrolliert die Anwesenheit des Maussymbols in einem bestimmten, vordefinierten Rechteck. Der Anfangspunkt wird in XPOS und YPOS übergeben und legt die linke obere Ecke fest, die Variablen BREIT und HOCH bestimmen die horizontale und vertikale Ausdehnung des Bildschirmausschnittes, auf den die Routine reagiert. Dazu existieren zwei verschiedene Modi. Entweder wartet die Routine, bis die Maus den Bildschirmausschnitt betritt oder, bis sie ihn verläßt. Dies wird in Speicherzelle ’GINTIN’ festgelegt, wobei eine Null bewirkt, daß die Routine wartet, bis die Maus in den Bereich eintritt, eine Eins entsprechend das Gegenteil. Der Aufruf erfolgt durch:

XPOS1 = .. : YPOS1 = ..:
BREIT = .. : HOCH = ..:
GOSUB EVENTMAUS

62500 EVENTMAUS:
62502 ' —> XPOS1 ; YPOS1 
62504 ’ —> BREIT ; HOCH 
62506 poke gintin,0
62508 poke gintin+2,xpos1+1 
62510 poke gintin+4,ypos1+38 
62512 poke gintin+6,breit 
62514 poke gintin+8,hoch 
62516 gemsys 22 
62518 return
62520 '----------------------

5	'merge "INIT.bas"
6	'merge "EVENTMAUS.bas”
7	'merge "SHOWMAUS.bas"
8	'merge "RECHTECK.bas"
9	'
10	gosub init
20	fullw 2 : color 1,1,1,3,3
30	xpos1=100:ypos1=100:xpos2=150:ypos2=120
40	breit = 50 : hoch = 20
50	Start:
55	gosub rechteck
60	gosub showmaus
70	gosub eventmaus:
80	out 2,7	: goto Start
90	end

Routine EVENTMAUS

Listing 6: Warten auf Mausereignis

63030 SHOWMAUS:
63032 poke contrl,122
63034 poke intin,0
63036 vdisys
63038 return
63040 '---------------
63042 HIDEMAUS:
63044 poke contrl,123 
63046 vdisys
63048	return
63049	'---------------
64000 RECHTECK:
64002 ' --> XPOS1 ; YPOS1 ; XPOS2 ; YP0S2
64004 poke contrl ,11
64006 poke contrl+2 ,2
64008 poke contrl+6 ,0
64010 poke contrl+10,1
64012 poke ptsin ,XPOS1 +1
64014 poke ptsin+2,YPOS1 +38
64016 poke ptsin+4,XPOS2 +1
64018 poke ptsin+6,YP0S2 +38
64020 vdisys
64022 return
64024 '-------------------------------------

Routine RECHTECK Routinen SHOWMAUS / HIDEMAUS

Definieren eines Rechteckes

62200 RUBBERBOX:
62202 '—> MAUSX ; MAUSY 
62204 ' <— BREIT ; HOCH 
62206 poke gintin , mausx+1 
62208 poke gintin+2 , mausy+38 
62210 poke gintin+4 , 1 
62212 poke gintin+6 ,	1
62214 AES.3: gemsys 70 
62216 breit = peek(gintout+2)
62218 hoch = peek(gintout+4)
62220 if hoch<3 or breit<3 then goto AES.3 
62222 return
62224 ' -----------------------------------------

Routine RUBBERBOX

5	' merge "INIT.bas"
6	’ merge "MOUSE.bas“
7	' merge "RUBBERBOX.bas"
10	gosub INIT
20	openw 2:clearw 2
30	Start: gosub MOUSE
40	if taste=l then gosub	rubberbox else goto start
50	? "Die Box ist "breit" breit und "hoch“ hoch"
60	end

Listing 7: Rechteckdefinition mit Maus

Rubberbox

Zwei weitere, nützliche Routinen dienen zum Festlegen eines Rechtecks mit der Maus. Die erste erzeugt ein Rechteck, dessen eine Ecke fixiert ist, wobei die andere, bei gedrückter Maustaste, der Mausbewegung folgt.

Die linke obere Ecke wird durch Anklicken mit der Maus bestimmt. Daraufhin entsteht ein gestricheltes Rechteck, das den Bewegungen der Maus folgt. Dabei muß die linke Maustaste gedrückt bleiben.

Sobald sie losgelassen wird, gibt die Routine die Breite und Höhe des momentan markierten Rechtecks zurück.

Der Aufruf erfolgt durch:

Gosub RUBBERBOX

Bevor diese Routine angesprochen wird, sollte mit Hilfe des ’MOUSE’-Unterprogrammes abgefragt werden, ob die linke Maustaste gedrückt wurde, um den Startpunkt des Rechtecks an die betreffende Stelle zu legen. ’RUBBERBOX’ entnimmt dann den Startpunkt aus den von der MOUSE-Routine stammenden Variablen MAUSX und MAUSY.

Drag box

Diese Routine dient zum Verschieben eines Rechtecks. Die Größe des zu verschiebenden Rechtecks wird dabei vorgegeben (BREIT,HOCH). Es ist zweckmäßig, die Anfangskoordinaten mittels der MOUSE-Routine festzulegen, damit der Anfangspunkt des Rechtecks auch der Mausposition entspricht. Die Routine ist deshalb darauf ausgelegt, daß sie den Anfangspunkt den Variablen MAUSX und MAUSY entnimmt. Weiterhin ist diese Routine in der Lage, einen Bereich zu kennzeichnen, den dieses Rechteck nicht verlassen kann. Definiert wird er in X.MIN, Y.MIN und X.MAX, YMAX.

Aufruf durch

X.MIN = .. : Y.MIN = .. X.MAX = .. ; 
Y.MAX = .. BREIT = .. : HOCH = .. 
Gosub DRAGBOX

Die Routine gibt in den Variablen XPOS1 und YPOS1 die neue Lage des Rechtecks an das Hauptprogramm zurück.

Bei dem Beispielprogramm hierzu kommen neben der Rechteckroutine zwei weitere VDI-Routinen zur Geltung. Sie sorgen dafür, daß die Maus bei gegebener Zeit sichtbar bzw. unsichtbar wird, da sonst das Rechteck an dem Punkt, wo es mit der Maus überlappt, gelöscht würde. Um das zu verhindern, wird vor Aufruf einer GEM-Ausgaberoutine, die Maus mittels ’Gosub HIDEMAUS’ aus- und anschließend durch ’Gosub SHOWMAUS’ wieder eingeschaltet.

Aus diesem Beispiel wird ersichtlich, daß gerade durch Kombination der einzelnen GEM-Routinen die besten Ergebnisse erzielt werden. Auch die hier angeführten Demoprogramme demonstrieren lediglich die prinzipielle Arbeitsweise der einzelnen Routinen, die sicherlich in fast allen Programmen ihre Anwendung finden und Ihnen helfen, den ATARI ST ein wenig mehr auszureizen.

Zur umfangreichen GEM Nutzung ist aber trotzdem die Verwendung einer anderen Programmiersprache (C, Pascal) sehr empfehlenswert bzw. unbedingt anzuraten, da einerseits nicht alle Routinen im Basic ansprechbar sind und andererseits die Handhabung wesentlich bequemer ist, nicht zuletzt auch wegen des Geschwindigkeitsgewinns einer Compilersprache. So mag sich mancher C-Programmierer sicher gewundert haben, wieso man die GEM-Routinen, die in C ohne Kompromisse aufrufbar sind, in einer Sprache anwendet, die für solche Anwendungen weniger geeignet ist. Den Basic-Pro-grammierern aber hoffen wir, eine Hilfe für die ausgedehntere Nutzung ihres Rechners gegeben zu haben, und nicht zuletzt einen Anreiz auf die GEM-Programmierung in C oder Pascal.

★ Ende des Kurses ★

62250 DRAGBOX:
62252 ’ —> BREIT ; HOCH 
62254 ’ —> X.MIN ; Y.MIN 
62256 ' —> X.MAX ; Y.MAX 
62258 ’ <— XPOS1 5 YPOS1 
62260 poke control+2,8 
62262 poke control+4,3 
62264 poke gintin, breit 
62266 poke gintin+2, hoch 
62268 poke gintin+4, mausx+1 
62270 poke gintin+6, mausy+38 
62272 poke gintin+8, x.min+1 
62274 poke gintin+10,y.min+38 
62276 poke gintin+L2,x.max+1 
62278 poke gintin+14,y.max+38 
62280 gemsys 71 
62282 xpos1=peek(gintout+2)-1 
62284 ypos1=peek(gintout+4)-38 
62286 return 62288 ’----------------------

Routine DRAGBOX

3	’merge "INIT.bas"
4	’merge "DRAGBOX.bas"
5	’merge “MOUSE.bas"
6	’merge "RECHTECK.bas"
7	'merge "SHOWMAUS.bas"
8	’merge "HIDEMAUS.bas"
9	'
10	gosub init
20	fullw	2:clearw	2:	color	1,1,1,2,3
30 breit =200:hoch =150:x.min=100:y.min=100 
40	x.max=500:y.max=250
50	gosub mouse
60	Start:	gosub mouse
70	if taste=l then gosub dragbox else goto Start
80	xpos2 = xpos1+breit: ypos2 = ypos1+hoch
90	gosub	hidemaus:	gosub	rechteck
100	gosub	showmaus
110	gotoxy 0,0
120 ?"Das Rechteck befindet sich nun bei " xpos1,ypos1 
130	end

Listing 8: Rechteckverschieben mit Maus



Aus: ST-Computer 05 / 1986, Seite 18

Links

Copyright-Bestimmungen: siehe Über diese Seite