Programmieren unter MiNT/MultiTOS, Teil 6: Alles bunt macht der Mai

Der Mac hat sie, Windows hat sie und nun hat sie auch der Atari: Die Farb-Icons sind unter uns! Es ist vollbracht. MultiTOS liegt in der Version 1.0 vor und der Falcon wird ausgeliefert. Damit ist der Verbreitung der hübschen bunten Bildchen Tür und Tor geöffnet.

Seit Version 3.31 des AES hat sich einiges entwickelt. Wer schon einmal MultiTOS oder den Falcon in Verbindung mit einem Farbbildschirm gesehen hat, dem sind sicher die bunten Icons und die dreidimensionalen Effekte aufgefallen. Atari hat es geschafft, diese Neuheiten kompatibel in das AES einzubinden; damit ist das friedliche Nebeneinander von Alt und Neu gewährleistet. Selbstredend sollten Programmierer nach Möglichkeit die neuen Elemente in ihren Programmen verwenden. Um zumindest Pure C-Programmierern das Warten auf ein Update zu ersparen, finden Sie auf der TOS-Diskette die »NEW_AES.LIB« mit dem Header-File“NEW_AES.H“, die alle AES-Neuheiten von MultiTOS 1.0 bzw. dem Falcon TOS 4.02 auch Ihren Programmen zugänglich macht.

Auf diese Library bzw. das Header-File beziehen sich auch die nun folgenden Schreibereien in Sachen Farb-Icons.

Die Farb-Icons

Für die Einbindung der Farb-Icons in das AES wurden ein neuer Objekt-Typ sowie mehrere Strukturen nötig. Farb-Icons firmieren zukünftig als »G_CICON« (Typ-Nr. 33). Steht dieser Wert in »ob_type«, verbirgt sich unter »ob_spec« ein Zeiger auf die Struktur »CICONBLK«.

typedef struct cicon_blk
{
	ICONBLK monoblk;	/* Hier steht das bekannte monochrome Icon */
	CICON *mainlist;	/* Und hier folgt ein Zeiger auf die Liste */
		/* mit den Farb-Icons für die verschiedenen */
		/* Auflösungen */
} CICONBLK;

Ein Farb-Icon besteht also immer aus einem normalen Monochrom-Icon und einer Liste von Farb-Icons für die verschiedenen Auflösungen. Es ist also möglich, für jede Anzahl der zur Verfügung stehenden Farben ein eigenes Farb-Icon zu verwenden. Aus dieser Liste wählt das AES dann immer die beste Lösung für die gerade aktuelle Auflösung aus. Enthält die Liste beispielsweise ein monochromes und ein 16-Farben-Icon, wählt das AES bei 16 oder 256 darstellbaren Farben das 16farbige Icon aus; bei nur vier möglichen Farben kommt das monochrome Icon zum Zuge. Wenn also kein exakt passendes Icon in der Liste ist, nimmt das AES das Icon mit der nächstniedrigeren Auflösung. Wer »faul« ist und alle Farbauflösungen mit nur einem bunten Icon abdecken will, bastelt sich ein vierfarbiges Icon. Den Rest erledigt das AES.

Die Liste der Farb-Icons ist als verkettete Struktur vom Typ »CICON« definiert:

typedef struct cicon_data
{
	int num_planes;	/* Die Anzahl der Planes des folgenden Icons */
	int *col_data;	/* Zeiger auf die »normale« Farbbitmap */
	int *col_mask;	/* Zeiger auf die Maske für das normale Icon */
	int *sel_data;	/* Zeiger auf die »selektierte« Farbbitmap */
	int *sel_mask;	/* Zeiger auf die Maske für das selektierte Icon */
	struct cicon_data *next_res;	/* Zeiger auf das nächste Icon mit einer anderen */
		/* Auflösung bzw. -1 wenn das Ende erreicht ist. */
} CICON;

Intern werden die Farb-Icons im Standardformat abgelegt, d.h. eine Plane nach der anderen. Für 4 Farben sind 2 Planes nötig, für 16 Farben 4 Planes und so weiter. In den meisten ST/TT/FALCON-Bildschirmformaten liegen die Planes nicht hintereinander, sondern wortweise gemischt vor. Die nötige Umrechnung in das Bildschirmformat erledigt das AES beim Laden der Resourcen mit »rsrc_load()«. Wer die Resourcen direkt in sein Programm einbinden möchte, der muß sie via »vr_trnfm()« selbst anpassen. Die Masken »col_mask/sel_mask« behandelt das AES wie die Masken des Monochrom-Icons, also als Single-Plane-Images. Informationen wie Lage, Größe und der Icon-Text stecken wie gehabt im Monochrom-Icon (monoblk). Die Icons einer Liste dürfen sich natürlich in ihrer Größe nicht unterscheiden.

Abgesehen von der Farbigkeit, ist ein weiteres »nettes« Feature in den Farb-Icons eingebaut. Bei den monochromen Icons war (und ist) es üblich, daß sie im selektierten Zustand einfach invers gezeichnet wurden. Bei den Farb-Icons kommt nun ein komplettes zweites Icon »sel_data« und »sel_mask« zur Darstellung, um diesen Zustand zu dokumentieren. Damit sind einfache Animationen beim Anwählen der Icons möglich. Wer keine Lust auf »Animation« hat und daher kein zweites Icon braucht, der kann die Zeiger sel_data und sel_mask auch mit NULL initialisieren. Das AES stellt dann im Falle der Anwahl das »normale« Farb-Icon dunkel dar. Auf der TOS-Diskette finden Sie das Programm »COL_ICON.APP« inklusive der Quellcodes. Dieses Programm stellt eine kleine Animation mit zwei Farb-Icons, also vier Bildchen insgesamt, dar. Diese Demo läuft allerdings erst ab AES-Version 3.3 1, da ältere AES-Versionen Resourcen, die Farb-Icons enthalten, nicht verarbeiten können.

In den neuen RSC-Files hat sich einiges geändert (z.B. können sie nun auch größer als 64 KByte werden), doch zu diesen Änderungen in einem Nachfolgeartikel. Wer also ein Programm schreiben möchte, das auch mit älteren TOS-Versionen läuft, sollte zwei Resource-Files anlegen, eines mit und eines ohne Farb-Icons und je nach AES-Version die entsprechende Datei mit »rsrc_load()« nachladen. Für Besitzer der neuen »interface«-Version, dem einzig farbfähigen Resource-Editor, geht es ein wenig bequemer, da diesem Programm eine Library beiliegt, um Farb-Icons mit allen TOS-Versionen darzustellen.

3D-Effekte

Was auf einem Schwarzweiß-Monitor zugegebenermaßen ein wenig dürftig aussieht, kommt auf einem Farbbildschirm ab 16 Farben recht gut zur Geltung: die 3D-Effekte. Buttons, Alert-Boxen, Fensterelemente usw. erstrahlen im neuen, ungewohnten dreidimensionalen Look.

Es gibt ab AES 3.32 drei Varianten, ein Objekt dreidimensional erscheinen zu lassen: »Indicator«, »Activator« und »Background«. Ein Indicator soll einen Zustand anzeigen. Speziell für Radiobuttons muß laut Atari dieser Typ verwendet werden. Wird ein Indicator angewählt, ändert er seine Farbe und »sinkt« in den Bildschirm. Der Activator dagegen sollte für alle Objekte verwendet werden, die ihren Zustand nicht dauerhaft ändern, also eine Aktion auslösen. Beispiele hierfür sind der »OK«- oder »Abbruch«-Button. Hier ändert sich die Farbe des Objekts nicht, es »sinkt« bei der Anwahl lediglich in den Bildschirm.

Zu guter Letzt haben wir noch den Background-Typ. Ein solches Objekt ist, wie der englischsprechende Leser schon geahnt hat, für den Hintergrund zuständig. Vorausgesetzt, es ist noch das »OUTLINED«-Flag gesetzt, wird es besonders hervorgehoben. Ohne das OUTLINED-Flag erhält es lediglich eine 3D-Farbe. Wird es angewählt, ändert es nur seine Farbe. Der letzte Fall entspricht nicht der Regel. Der Typ Background dient mehr zur Zierde.

Womit wir elegant bei den 3D-Farben gelandet sind. Für Licht und Schatten verwendet das AES grundsätzlich immer die Farben Schwarz und Weiß, ab 16 Farben kommen noch die VDI-Farben 8 und 9 (Hell- und Dunkelgrau) dazu. Sinnvollerweise sollten diese VDI-Farben auch auf Hell- bzw. Dunkelgrau gesetzt sein, um in den 3D-Genuß zu kommen. Grundsätzlich sollten Sie die ersten 16 VDI-Farben nicht ändern.

Aber nicht nur der Rand, auch das Innere eines 3D-Objekts bleibt ab AES 3.32 nicht verschont. Ist die Musterfarbe auf Weiß (0) gesetzt und auch das Muster als »leer« definiert, zeichnet das AES den Hintergrund eines 3D-Objekts in einer 3D-Farbe. Voreingestellt ist für jeden der drei möglichen 3D-Typen die VDI-Farbe 8 (Hellgrau). Wie Sie diese Voreinstellung ändern, erfahren Sie später.

Die Entstehung dieser ganzen 3D-Spielereien war in den Anfangszeiten recht konfus. So lagen die 3D-Kennungen im Falcon TOS 4.00/4.01 und bei den MultiTOS-Betaversionen im oberen Byte des »ob_type«. Der Wert 2 kennzeichnete einen Activator, 1 den Indicator, das Background-Objekt existierte noch nicht. Da aber eben dieses Byte gerne von anderen Libraries verwendet wurde, entschloß man sich bei Atari, die 3D-Kennungen in die »ob_flags« aufzunehmen (wo sie auch hingehören). Bei dieser Gelegenheit wurde auch noch das Background-Objekt hinzugefügt.

AES 3.32 verwendet nun die Bits 9 und 10 für die 3D-Darstellung: Ist Bit 9 gesetzt und Bit 10 gelöscht, handelt es sich um einen Indicator. Sind beide Bits gesetzt, ist es ein Activator und falls nur Bit 10 gesetzt ist, haben wir ein Background-Objekt. Ist keines der beiden Bits gesetzt, ist es auch Essig mit der 3D-Darstellung. Damit das Ganze nicht in eine »Bitpfriemelei« ausartet, gibt es auch einige neue C-Definitionen:

#define FL3DMASK Ox0600	/* Maske für die Abfrage */
#define FL3DNONE 0x0000	/* Keine 3D-Effekte */
#define FL3DIND  0x0200	/* Indicator */
#define FL3DBAK  0x0400	/* Background */
#define FL3DACT  0x0600	/* Aktivator */

Mit diesen Definitionen reduziert sich die Abfrage des 3D-Typs auf ein simples »ob_flags AND FL3DMASK«. Das Ergebnis dieser Operation ist dann: FL3DIND für einen Indikator, FL3DACT für einen Activator, FL3DBAK für Background und FL3DNONE für keinen 3D-Effekt. Auch das Setzen der entsprechenden 3 D-Flags ist mit diesen Definitionen einfach, »ob_flags OR FL3D ... « genügt. Übrigens: Die 3D-Flags dürfen Sie auch unbeschadet bei AES-Versionen kleiner 3.31 verwenden. Es tut sich dann zwar nichts Dreidimensionales auf dem Bildschirm, aber es schadet auch nicht und Ihre Programme sind für die 3D-Welt gerüstet.

Apropos »gerüstet«: Atari hat es auch nicht versäumt, eine neue AES-Funktion zur Beeinflussung bzw.Abfrage der 3D-Farben und Reaktionen zu implementieren. Leider hat bisher kein Programm zur Nutzung dieser Funktion die Labors von Atari verlassen. Aber natürlich sind wenigstens Sie auf die Zukunft vorbereitet. Die TOS-Diskette enthält ein CPX-Modul mit dem sinnigen Namen »3D_CPX.CPX«. Es erlaubt mit Hilfe der neuen Funktion »obj_sysvar()«, die Farben und Reaktionen der 3D-Objekte abzufragen oder zu setzen. Der Prototyp dieser Funktion in C:

int objc_sysvar (int ob_smode, int ob_swhich, int ob_siva11,
             int ob_siva12, int *ob_sova11, int *ob_sova12);

In »ob_smode« entscheiden Sie, ob die Werte abgefragt (0) oder gesetzt (1) werden sollen. In »ob_swich« steht, was Sie bearbeiten möchten. Dabei kommen folgende Definitionen zum Einsatz:

#define LK3DIND    1	/* Die Funktion der Indicatoren */
#define LK3DACT    2	/* Die Funktion der Activatoren */
#define INDBUTCOL  3	/* Die Farbe der Indicatoren */
#define ACTBUTCOL  4	/* Die Farbe der Activatoren */
#define BACKGRCOL  5	/* Die Farbe der Backgrounds */
#define AD3DVALUE  6	/* Verbreiterung */

Für das Setzen der Attribute kommen die neuen Werte in »ob_sival11« und »ob_siva12«. Die Ergebnisse einer Abfrage stehen in »ob_sova11« und »ob_sova12«. Wichtig: Auch beim Setzen von Werten müssen Sie in »ob_sova11« und »ob_sova12« sinnvolle Zeiger übergeben, auf keinen Fall einen NULL-Pointer. Das AES schreibt auch beim Setzen die tatsächlich eingestellten Werte in die Variablen.

Folgende Punkte dürfen Sie einstellen:

LK3DACT/LK3DIND: Setzen/Abfragen des Verhaltens der Aktivator/Indicator. Für das Setzen der Werte (ob_smode = 1) gilt: Wenn ob_siva11 = 1, dann wird der Button beim Selektieren bewegt. Wenn ob_siva11 = 0, dann rührt er sich nicht von der Stelle. Ist ob_siva12 = 1, dann ändert der Button beim Selektieren schamhaft die Farbe, bei ob_siva12 = 0 ändert sich nichts. Beim Abfragen (ob_smode = 0) erhalten Sie die aktuellen Einstellungen in ob_sova11 und ob_sova12. Die Voreinstellung für Indicator ist: ob_siva11 = 1 und ob_siva12 = 0, für Activator genau umgekehrt.

ACTBUTCOL/INDBUTCOL/BACKGROL: Setzen/Abfragen der 3D-Farbe von Activator/Indicator/Background. Zur Erinnerung: Dies ist die VDI-Farbe für 3D-Objekte, vorausgesetzt das Muster ist »leer« und die Musterfarbe ist »Weiß«. Hier wird nur ob_siva11 für das Setzen und ob_siva12 für die Abfrage benötigt. Voreingestellt ist die VDI-Farbe 8 (Hellgrau) oder Weiß. Nicht vergessen: Die Backgrounds existieren erst ab AES-Version 3.32.

AD3DVALUE: Abfragen der Verbreiterung von Objekten durch die 3D-Flags. Da die 3D-Darstellung mehr Platz benötigt, kann hier dieser zusätzliche »Pixel-Bedarf« für die horizontale (ob_sova11) und die vertikale (ob_sova12) Erweiterung abgefragt werden. Hier funktioniert nur die Abfrage, ob_smode ist also stets 0. Liefert die Funktion den Rückgabewert Null, ist ein Fehler aufgetreten.

Grundsätzlich sollten in normalen Programmen nur die Abfrage-Funktionen Verwendung finden, da das Setzen der Werte das Aussehen aller anderen Programme beeinflußt. Am sinnvollsten überläßt man also die Einstellung dieser Werte einem einzigen Programm, etwa unserem Modul »3D-CPX.CPX«. (ah)


Richard Kurz
Aus: TOS 05 / 1993, Seite 55

Links

Copyright-Bestimmungen: siehe Über diese Seite