



Teil V


Dateiformate



An sich sollte es selbstverst„ndlich sein, dass eine Programmdokumentation auch eine Be-
schreibung der verwendeten Dateiformate enth„lt. Wie so vieles ist es das nicht, was mich
aber nicht hindern soll, hier mit gutem Beispiel voranzugehen.



1    CHAOSultd-Bilder


CHAOSultd verwendet fr Bilder ein eigenes Format34
Eine Bilddatei besteht aus einem Header, der Farbtabelle, den Parametern, zus„tzlichen
Parametern und den Bilddaten, wobei letztere immer gepackt werden, auch dann, wenn sie
dadurch l„nger werden35.
Der Header sieht (als C-Struktur) folgendermassen aus:


typedef struct
-
/* id's */
char chaos_id[8]; /* CHSultd5 */
char frac_id[8];
/* gr”sse, planes und colors */
unsigned int size_x;
unsigned int size_y;
unsigned int planes;
unsigned int colors;
/* zus. parameter */
int lastline;
int last_flag;
int xor_offset;
/* l„nge der folgenden daten */
long par_len;
long xpar_len;
long pic_len;
/* coltab in long */
/* parameter */
/* zus. parameter */
/* bilddaten */
" FRAC_HEAD;


chaos_id ist eine Kennung, die die Zeichen CHSultd5 beinhalten muss. frac_id ist eine wei-
tere Kennung, die die Berechnungsroutine, die fr das Bild verantwortlich ist, kennzeichnet.
____________________________________34
    Wozu Standartformate verwenden, wenn man auch eigene definieren kann?
  Aber im Ernst: die verschiedenen Bildgr”ssen und die Verwaltung der Parameter liessen mir ei*
 *n spezielles
Format sinnvoll erscheinen und wenn man sowieso ein eigenes Format verwendet, ist es auch schon*
 * egal, wie
speziell dieses Format dann ist (denkbar w„re h”chstens noch ein GEM-Image-Format gewesen, mi*
 *t einem
erweiterten Header; vielleicht fhre ich das mal als alternatives Format ein).
  35das ist kein Scherz, das kann wirklich passieren, die Daten werden aber nicht nennenswert l*
 *„nger



                                           45




size_x, size_y, planes und colors legen die Bildgr”sse, die Anzahl der Bitebenen und die
Zahl der Farben fest. Die Bildgr”sse ist - unabh„ngig davon, ob und wieweit das Bild schon
berechnet wurde - die Gr”sse des fertig berechneten Bildes.
lastline gibt an, ob das Bild fertig ist oder nicht. Ist lastline 0, so gibt es gar keine
Bilddaten, -1 bedeutet, dass das Bild fertig berechnet ist. Andernfalls gibt lastline die
Anzahl der berechneten und gespeicherten Zeilen an, aber nur falls das unterste Bit in
last_flag gesetzt ist36. Ist dieses Bit gel”scht, so ist fr lastline6= 0 stets das gesammte
Bild gespeichert.
xor_offset ist fr das Packen der Daten von Bedeutung und wird gleich erkl„rt; par_len,
xpar_len und pic_len gibt die L„nge der drei Datenbl”cke an. Die Parameter und zus.
Parameter sind natrlich Bildtypabh„ngig, bleiben also die Bilddaten.
Im Farbmodus werden zun„chst die Bitplanes, die im Screen-Format ja wortweise hinter-
einanderstehen getrennt, d.h. es kommt erst die ganze Bitplane 0, dann 1 usw. (man hat
also gewissermassen ein GEM-Standartformat, wobei die Gr”sse des Blockes durch size_x
und size_y festgelegt ist).
Dann werden die Bilddaten von hinten mit dem xor_offset mit sich selbst via xor ver-
knpft. Der Offset entspricht im Allgemeinen einer oder mehreren Bildschirmzeilen. Da-
durch entsteht ein Bild, dessen Zeilen (ausser der ersten) immer nur die Differenz zur
darberliegenden Zeile beinhalten und das deshalb i.a. besser zu packen ist. Ist xor_offset
0 so entf„llt die Xor-Verknpfung. Um die Xor-Verknpfung beim Laden rckg„ngig zu
machen muss man die Daten erneut via xor miteinander verknpfen, diesmal allerdings von
vorne.
Anschliessend werden die Bilddaten im Stad-Format gepackt und gespeichert.
Das heisst die gepackten Daten beginnen mit den drei Bytes Kennbyte, Packbyte und Spe-
zialbyte, anschliessend folgen die gepackten Graphikdaten, wobei folgende Kodierungen An-
wendung finden:
Das Kennbyte und das nachfolgende Byte n bedeuten, dass das Packbyte n+1 mal zusam-
mengefasst wurde.
Das Spezialbyte und die beiden nachfolgenden Bytes a und n bedeuten, dass das Byte a n+1
mal zusammengefasst wurde.
Alle anderen Bytes mssen so wie sie in der Datei stehen in das Bild bernommen werden.



2    Filme


Film-Dateien haben sich gegenber FRACTAL Version 4.1 (und 4.3) nicht ge„ndert.
Sie bestehen aus dem Header 'film', der (als 2 Byte Integer abgelegten) Anzahl verschie-
dener Bilder sowie der Anzahl der Bilder im Film. Es folgen die Anzeigeoptionen (eine
SHOW_OPTS-Struktur), daran schliessen sich die Informationen ber die im Film enthal-
tenen Bilder an. Und zwar fr jedes Bild Dateipfad, Name und Dateiextension, jeweils als
nullterminierter String (unter diesen Dateinamen werden die Bilder beim Einladen eines
Filmes gesucht). Deshalb ist es auch n”tig, dass die Bilder beim Speichern des Filmes ge-
speichert sind, FRACTAL k”nnte sonst h”chstens raten, wohin man die Bilder abspeichern
wird. Dateipfade k”nnen (seit FRACTAL V4.3) relativ sein, sie beginnen dann nicht mit
einem Laufwerk. In diesem Fall ist der Pfad relativ zum Verzeichnis der Filmdatei zu ver-
stehen.
____________________________________36
    die anderen Bits sind reserviert



                                           46




Zuletzt folgt eine Liste mit der Reihenfolge der Bilder im Film, wobei sich die Nummern (1
Byte Integer) auf die Reihenfolge der Dateinamen beziehen.
Filmdateien drfen nicht l„nger als 32000 Bytes sein.



3    Einstellungen


Die Einstellungsdateien will ich hier nicht im Detail erl„utern, da sie sicher nicht sonderlich
interessant sind.
Eventuell doch von Interesse ist allerdings der prinzipielle Aufbau dieser Dateien, die ja
nicht nur die Voreinstellungen von CHAOSultd selbst, sondern auch die der diversen Be-
rechungsroutinen - letztere in nicht festgelegter Reihenfolge und wom”glich wechselnder
Anzahl.
Realisiert wird dies durch eine Block-Struktur. Jeder Block beginnt mit einem 12 Byte
langen Header: die ersten 8 Byte erhalten eine Kennung (CHAOSultd verwendet fr seine
Einstellungen CHSultd5, fr die Berechnungsroutinen wird die gleiche Kennung verwendet
wie in Bilddateien. Es folgt als Langwort (4 Byte) die L„nge der folgenden Daten. Ansch-
liessend kommen die Einstellungsdaten sebler, deren Inhalt von den Berechnungsroutinen
abh„ngt; die CHAOSultd-Einstellungen bestehen aus einer CHS_SET-Struktur, die in der
Headerdatei XCOMMON.H definiert ist.



                                           47




Teil VI


die  Schnittstelle  fr  externe  Routinen



Die folgenden Erl„uterungen sind nur fr Programmierer bestimmt, die eigene Berechnungs-
routinen fr Bilder irgendeiner Art schreiben wollen.
Aus technischen Grnden ist es nicht ratsam dies in einer anderen Sprache als C37 und
vermutlich auch da wiederum nur in Pure C (bzw. Turbo C) zu versuchen. Wie weit andere
C-Compiler mit den Parameterbergabe-Konventionen von Turbo/Pure C zurecht kommen
weiss ich nicht (vermutlich eher nicht, Turbo/Pure C bergibt Parameter auch in Registern).
Man sei sich auch darber im Klaren, dass die eigentliche Berechnungsroutine (jedenfalls
solange man sie nicht sehr aufwendig optimiert) meist nur einen kleinen Teil der n”tigen
Routinen darstellt, insbesondere sollte man in der Lage sein, mit GEM-Dialogboxen umzu-
gehen. Ich setze im folgenden stets vorraus, dass Interessenten in C programmieren k”nnen,
insbesondere den Umgang mit Strukturen beherrschen, ebenso die Programmierung von
GEM-Programmen.
Wie aber werden externe Routinen berhaupt eingebunden? Und welches Format muss die
erzeugte XCH-Datei haben?
Um die zweite Frage zuerst zu beantworten: bei der XCH-Datei handelt es sich um eine
normale Programm-Datei, die aber keinen Startup-Code besitzt. Erzeugen kann man eine
solche Datei mit Pure C, indem man in der Projektdatei einfach den Startup-Code wegl„sst
(man kann das so erzeugte Programm natrlich nicht vom Desktop aus ausfhren).
Das Programm enth„lt auch keine Funktion main, eingebunden wird es vielmehr so, dass
die erste Funktion der Source-Datei nach dem Laden und Relozieren aufgerufen wird (bei
mehreren Sourcedateien ist es die erste Funktion der ersten Sourcedatei, es kommt nur dar-
auf an, dass diese Funktion am Anfang des TEXT-Segmentes steht, was man gegebenenfalls
mit einem Debugger berprfen sollte). Diese Funktion hat nur zwei Aufgaben: erstens
wird ihr von CHAOSultd ein Zeiger auf eine Struktur mit Routinen und globalen Variablen

bergeben, die CHAOSultd den externen Routinen zur Verfgung stellt, und zweitens gibt
die Routine an CHAOSultd einen Zeiger auf eine Struktur zurck, in der die Adressen der
externen Routinen stehen.
Das war's dann gewissermassen schon, zum Initialisieren der externen Routinen wird speziell
eine der Routinen aufgerufen.



1    Beschreibung der ben”tigten Routinen


Zun„chst eine Vorbemerkung: ich bin kein sonderlich guter Programmierer und insbesondere
programmiere ich zwar nicht konzeplos aber doch mit viel zu oft wechselnden Konzepton.
Dies macht sich auch bei den bereitzustellenden Routinen bemerkbar, etwa dadurch, dass
mal der Bildschirm vor Ausgabe einer Dialogbox schon gesichert ist, mal noch zu sichern
ist. Auch Rckgabecodes sind nicht unbedingt einheitlich. Sorry, das ist sicher nicht sehr
gelungen, aber die Schnittstelle ist halt nach und nach entstanden. Was bei den Routinen
jeweils zu beachten ist wird aber im Folgenden ausfhrlich erl„utert.
____________________________________37
    in Frage k„me h”chstens noch Assembler, aber es erscheint mir bertrieben, die ganzen Ro*
 *utinen zur
Parameter-Ein- und Ausgabe in Assembler zu schreiben



                                           48




Alle Angaben und Routinen mssen in eine CHAOS-Struktur eingetragen werden, die dann
bei der Initialisierung an CHAOSultd bergeben wird (genaueres siehe unten).
Die n”tigen Struktur-Deklarationen finden sich alle in der Headerdatei XCOMMON.H. CHAOS-
ultd gibt es bekanntlich in zwei Versionen, sw- und Farb-Version, diese haben einen ge-
meinsamen Quelltext, in dem jedoch mittels bedingter Compilierung zwischen den Ver-
sionen unterschieden wird. Fr die Farb-Version ist das Makro COLOR definiert (mittels
#define COLOR, oder einer Compileroption -dCOLOR), fr die sw-Version nicht. Dies gilt
auch fr die XCOMMON-Headerdatei.



1.1   allgemeine Angaben


id


char id[8];
Kennung der Routine, die auch in allen Bilddateien und fr den Parameter-Block in der
Einstellungsdatei verwendet wird.
Mein Vorschlag ist, die ersten vier Zeichen als Kennung fr den Autor, die anderen vier als
Kennung fr die Routine zu verwenden (dementsprechend beginnen meine Kennungen auch
alle mit TMMW).



menue


char *menue;
Zeiger auf den Meneintrag des Programmes (ohne vorangestellte Leerzeichen und Tasta-
turbefehl). Dieser darf maximal 16 Zeichen lang sein, er wird auch bei der Auflistung der
Berechnungsroutinen im Programm-Info verwendet.



name, version und text


char *name;
char *version;
char *text;
Diese drei Texte werden ausschliesslich fr das Programminfo verwendet. name sollte den
Namen des Programmautors (max. 24 Zeichen), version eine Versionsnummer und ein
Erstellungsdatum (max. 20 Zeichen) und text eine allgemeine Kurzbeschreibung (max. 64
Zeichen) enthalten (die Texte sind nicht optional, will man nichts angeben, so mssen die
Zeiger mindestens auf einen Leerstring zeigen).



icon und xicon


ICONBLK *icon; ICONBLK *xicon;
Zeiger auf Icon fr die Anzeige der Bilder auf dem Desktop. icon wird fr nicht gespeicherte
Bilder, xicon fr gespeicherte verwendet; Konvention ist, gespeicherte Bilder mit einem
Haken zu kennzeichnen.
Die Icon mssen eine Gr”sse von 48x24 Punkten haben, der Buchstabe des Icons wird fr
die Kennzeichnung der Bildgr”sse verwendet und sollte oben links liegen.



                                           49




set_len und set


long set_len;
void *set;
set_len bezeichnet die L„nge der Voreinstellungen, set zeigt auf diese (man muss also fr
die Voreinstellungen eine Struktur anlegen sowie eine globale Variable, auf deren Adresse
man dann in set eintr„gt).



par_len


long par_len;
L„nge der Bildparameter



make_len


long make_len;
L„nge  der  Eingabeparameter  fr  das  Erzeugen  neuer  Bilder,  im  folgenden  auch  als
Bild(er)parameter bezeichnet.



neu_len


long neu_len;
L„nge der Parameter fr make_neu.



neu_par und neu_flag


void *neu_par;
int neu_flag;
Flags fr make_neu, siehe Beschreibung der make_neu-Routinen



last_flag


int last_flag;
Flag: falls last_flag 1 ist, so entspricht ein lastline-Wert gr”sser Null in den Objekt-
Parametern der letzten berechneten Bildschirmzeile. Ist last_flag 0, so wird immer der
ganze Bildschirm abgelegt.



1.2   Routinen


Mit Ausnahme der Routinen do_init, get_param, get_picpar und do_draw sind alle Rou-
tinen optional, d.h. sie k”nnen fehlen, ohne dass dies zu Programm-Abstrzen fhrt. Diese
drei Routinen stellen natrlich nur die Minimalanforderungen an die Berechnungsroutinen
dar, mit ihnen kann man lediglich Bilder erzeugen.



do_init


int do_init(int nr);
Die Routine wird beim Programmstart aufgerufen. Sie sollte alle globalen Initialisierungen
vornehmen, also etwa Resourcen laden usw.
Der Parameter nr ist die Typ-Nummer der Routine unter der diese intern verwaltet wird.



                                           50




Zurckgeben muss die Routine 0, falls erfolgreich initialisiert wurde, konnte die Routine
nicht initialisiert werden, so gibt man 1 zurck, die Berechnungsroutinen werden dann nicht
aufgenommen.
Anmerkung: nicht kmmern muss sich die Routine um das Laden der Voreinstellung. Sie
werden von CHAOSultd selbst geladen. In der Initialisierungsroutine stehen sie allerdings
noch nicht zur Verfgung.



get_param


int get_param(void *param, X_PARAM *x_param);
Diese Routine dient der Eingabe der Bildparameter fr neu zu berechnende Bilder.
param ist ein Zeiger auf die Parameter fr die Erzeugung neuer Bilder. Diese Parameter sind
i.a. nicht direkt die Parameter eines Bildes, es soll ja auch die Erzeugung von Bildfolgen
m”glich sein. x_param ist ein Zeiger auf eine Strukur mit zus„tzlichen, Bildtyp-unabh„ngigen
Parametern, die die Routine get_param ausfllen muss.


typedef struct
-
int anzahl; /* Anzahl der zu erzeugenden Bilder */
int size; /* Bildgr”sse (0 klein, 1 mittel, 2 gross) */
#ifndef COLOR
int color; /* 0 normal, 1 invers */
#else
int col_tab[16]; /* Farbtabelle */
#endif
int xor_offset;
char name[16];
char path[64];
" X_PARAM;


Das drfte weitgehend klar sein. xor_offset ist der gleiche Wert wie auch in Bild-Dateien.
Er wird in Byte angegeben. Wichtig ist, dass bei Berechnungsabbruch mindestens soviele
Bilddaten vorliegen, wie xor_offset angibt, sonst kommt es zum Crash (das kann eigentlich
nur vorkommen, wenn das Bild nur soweit berechnet gespeichert wird (also wenn last_flag
1 ist). xor_offset ist normalerweise ein Vielfaches der Zeilenl„nge oder 0 (kein Xor beim
Packen).
Die Routine braucht sich nicht um das Sichern und Restaurieren des Bildhintergrundes
kmmern; Rckgabewerte sind 0 im Falle eines Abbruches und 1 fr Ok, also fr das
Erzeugen der Bilder.



get_picpar


void *get_picpar(void *param_in, int nr,int anzahl);
Diese Routine muss aus den von get_param eingelesenen Parametern (fr ein oder mehrere
Bilder) die Parameter eines konkreten Bildes machen.
šbergeben wird ein Zeiger auf die Bild(er)parameter (param_in), die Nummer des aktuell

zu erzeugenden Bildes (nr, gez„hlt wird von 0 an) und die Gesamtzahl der zu erzeugenden
Bilder.



                                           51




Zurckliefern muss die Routine die Parameter des Bildes Nummer nr. Dabei handelt es sich
jetzt wirklich um die Parameter eines Bildes, wie sie dann auch von CHAOSultd verwaltet
werden sollen.
Im einfachsten Fall, wenn die Berechnungsroutinen nur die Erzeugung einzelner Bilder
zul„sst, k”nnen die Bild(er)parameter natrlich mit den Bildparametern bereinstimmen,
und diese Routine hat nichts weiter zu tun, als den Zeiger param_in wieder zurckzugeben.
L„sst man die Berechnung mehrerer Bilder zu, so mssen die Parameter fr das aktuelle
Bild interpoliert werden. Fr die Bildparameter mit den interpolierten Werten sollte man
dabei in den Bild(er)parametern Platz bereithalten, da man sie natrlich nicht auf dem
Stack ablegen kann und globale Variablen unn”tig Speicherplatz brauchen.



set_param


void set_param(void);
Diese Routine ist zur Eingabe der Voreinstellungen der Parameter gedacht. Der Bildschirm-
hintergrund wird vor Aufruf gesichert und nachher restauriert.
Die Parameter mssen natrlich in dem in set angegebenen Speicherbereich verwaltet wer-
den, wenn sie korrekt gespeichert werden sollen.



extended


void extended(void);
Diese Routine wird bei Anklicken des Menpunktes der Berechnungsroutinen mit CONTROL
aufgerufen. Hierfr ist keine besondere Funktion vorgesehen, man kann mit der Routine
machen was man will.
Wie bei set_param wird der Bildschirm gerettet und restauriert.



get_neu_param


int get_neu_param(void *param);
Mit dieser Routine werden die Parameter fr neu berechnen eingegeben. param ist ein Zeiger
auf die zugeh”rigen Parameter, in den die Routine die eingelesenen Werte eintragen muss.
Die Routine muss darberhinaus die Eintr„ge neu_par und neu_flag setzen, in neu_par
tr„gt man param ein (nur bei Ok), neu_flag setzt man auf 1 falls Ok gew„hlt wurde, -1
sonst. Dass diese Parameter von den lokalen Routinen zu setzen sind liegt daran, dass nur so
die gemeinsamen Neu-Parameter der Fractal-Routinen zu realisieren waren.
Rckgabewert: 0 fr Ok, 1 fr Abbruch



make_neu_param


void *make_neu_param(FR_OBJC *objc, void *param, X_PARAM *x_par,
int *change, int *redraw, int *size);
Mit dieser Routine werden aus den Daten des neu zu berechnenden Objektes und den
Neu-Parametern die neuen Daten ermittlet.
objc  ist  ein  Zeiger  auf  das  Objekt  (die  Objektparameter  erh„lt  man  dann  mittels
objc->par->data), param ist ein Zeiger auf die Neu-Parameter, x_par einer auf die allg.
Parameter des neuen Bildes (n”tig um etwa neu Farben oder Gr”sse einzutragen).



                                           52




change, redraw und size sind Flags, um anzugeben, ob und wieweit die Parameter ge„ndert
wurden. Die Flags sind beim Aufruf von make_neu_param gel”scht (0) und mssen gege-
benenfalls auf 1 gesetzt werden und zwar change wenn sich irgendwas an den Parametern
ge„ndert hat, redraw wenn durch eine Žnderung die Neuberechnung des Bildes n”tig ist
(praktisch immer, nicht aber wenn nur die Farben ge„ndert wurden) und size wenn sich
die Bildgr”sse „ndert.
Zurckgegeben wird ein Zeiger auf die neuen Bildparameter (Platz fr diese reserviert man
vernnftigerweise in den Neu-Parametern).



make_vier


void make_vier(FR_OBJC *in, void *out, int nr);
Mit dieser Routine berechnet man die Parameter fr vier Bilder. in ist ein Zeiger auf das
zu vergr”ssernde Objekt, out einer auf die Parameter des neuen Bildes, deren Speicher man
ausnahmsweise nicht selber bereitstellen muss.
nr gibt an, welches der vier Viertelbilder gemeint ist, und zwar ist 0 links oben, 1 rechts
oben, 2 links unten und 3 rechts unten.



do_draw


int do_draw(FR_OBJC *object, void *param, void *puffer);
do_draw ist die zentrale Berechnungsroutine.
šbergeben wird object, ein Zeiger auf die Objekt-Struktur, param, ein Zeiger auf die Pa-

rameter (eigentlich berflssig, weil identisch object->par->data) und puffer ein Zeiger
auf einen 32000 Byte grossen (nicht 32kByte!) Puffer, mit dem man machen kann was man
will (fast).
Die Routine muss schlicht das Bild auf den Bildschirm zeichnen, alles andere erledigt
CHAOSultd.
Zurckgeben muss die Routine den Tastaturstatus (SHIFT, CONTROL etc.) beim Abbruch
(oder Null).



dont_draw


void dont_draw(FR_OBJC *object,void *param);
Diese Routine wird, falls existent, aufgerufen, falls ein neu erzeugtes Bild nicht gleich be-
rechnet werden soll (etwa bei Berechnungsabbruch beim Erzeugen von Bildfolgen). Sie ist
im allgemeinen berflssig und muss auch nicht existiern, wird aber gebraucht, wenn man
etwa eingegebene Parameter als zus„tzliche Parameter verwalten will (das erm”glicht eine
variable L„nge). object und param wie bei do_draw.



show_par


int show_par(FR_OBJC *object, long *buf);
Diese Routine soll die Bildparameter des Objektes object anzeigen. buf ist ein Puffer,
in den der Bildschirm bei Aufruf gerettet werden muss, der Bildschirm muss auch wieder
restauriert werden. Dies geschiet am einfachsten mit den von CHAOSultd zur Verfgung
gestellten Funktionen draw_objc und undraw_objc bzw. copy_screen (vgl. unten). Man



                                           53




darf nicht den Bildschirm auf buf umstellen, da buf nicht auf eine hinreichend gerade
Adresse zeigen muss.
Als Rckgabewert wird eine 0 erwartet, falls sich die Parameter sicher nicht ge„ndert haben
(Name oder Farben kann man unter Umst„nden hier „ndern), sonst eine 1.



show_info


void show_info(FR_OBJC *object, long *buf);
Die Funktion show_info dient der Anzeige eines Bildinfos, abgesehen vom (nicht vorhan-
denen) Rckgabewert gilt das gleiche wie bei show_par.



get_info


void get_info(FR_OBJC *object, PIC_INFO *info);
Mit get_info holt sich CHAOSultd die Informationen die es zur Anzeige ein Bildinfos ber
mehrere Bilder ben”tigt (Rechenzeit, Zahl der Iterationen und der Punkte). Existiert die
Funktion show_info nicht, so wird get_info - falls es existiert - auch fr einzelne Bilder
verwendet.



get_objcblk


void get_objcblk(FR_OBJC *object, double *x_min, double *x_max, double
*y_min, double *y_max);
Diese Routine gibt an CHAOSultd die Koordinaten des Bildrechteckes eines Objektes
zurck, natrlich nur wenn es solche gibt.
object ist ein Zeiger auf das Objekt, x_min, x_max, y_min und y_max sind Zeiger auf die
Koordiaten.
Falls dies Routine existiert, nimmt CHAOSultd auch an, dass der Bildschirm direkt ein Ko-
ordinatensystem darstellt, d.h. dass man die Bild-Koordinaten eines Raster-Punktes durch
Interpolation zwischen den Koordinaten des Bildrechteckes ermitteln kann38. Nur in diesem
Fall funktioniert die Koordinatenanzeige von Bilder zeigen oder das Anzeigen eines Blockes.



get_xobjcblk


void get_xobjcblk(FR_OBJC *object, double *x_min, double *x_max, double
*y_min, double *y_max);
Die Routine entspricht exakt der Routine get_objcblk, nur dass keine Folgerungen aus ihrer
Existenz gezogen werden.



get_pkt


void get_pkt(FR_OBJC *object, double *x, double *y);
Mit der Routine get_pkt holt sich CHAOSultd die Koordinaten fr den Punkt, der bei
Konstante anzeigen in Bilder zeigen angezeigt wird. Die Routine macht nur Sinn, wenn auch
die Routine get_objcblk existiert.
____________________________________38
    nicht der Fall ist dies z.B. bei 3d Fractalen



                                           54




show_pktinfo


void show_pktinfo(FR_OBJC *object, int x, int y, long *scr, long *buf);
Diese Routine wird fr die Anzeige eine Punktinfos aufgerufen.
object ist das betroffene Bildobjekt, x und y sind die (Bildschirm)-Koordinaten des Punk-
tes, scr ist ein Zeiger auf den Bildschirm, in dem das Bild liegt, und buf ist ein Puffer um
den Hintergrund zu retten.



dr_param


void dr_param(FR_OBJC *object);
Die Hardcopyroutine erlaubt es Bildparameter unter die Hardcopy zu drucken. Dazu wird
diese Funktion aufgerufen. object ist das ausgedruckte Objekt.
Die Parameter sollten sich auf vier Zeilen beschr„nken, damit zwei grosse Bilder auf eine
Druckerseite (11 Zoll) gehen.



cnv_load


int cnv_load(int frac_typ, L_PARAM *par, PIC_DATA *xparam, PIC_DATA *param,
PIC_DATA **x_par);
Diese Routine dient dazu, beim Laden die Parameter von Fraktalen anderer Aufl”sung
(oder auch einer anderen Version der Berechnungsroutinen) anzupassen.
šbergeben wird der Bildtyp (fr den Fall, dass mehrere Bildtypen zusammengefasst sind)

in frac_typ, ein Zeiger auf zus„tzliche Parameter in par mit Gr”sse, Farben, xor-Offset
etc. (vgl. Header-Datei) ein Zeiger auf die Parameter der Datei xparam, ein Zeiger auf
die Parameter des Bildes param. PIC_DATA *x ist ein Zeiger auf einen Block der internen
Speicherverwaltung, mit x->len erh„lt man die L„nge des Blockes + 8, x->data referenziert
den Blockinhalt.
Die geladenen Parameter mssen nach param kopiert werden, sie mssen ja nicht die
gleiche  L„nge  wie  die  Bildparameter  haben  (die  L„nge  erh„lt  man  wie  gesagt  durch
xparam->len-8).
Ausserdem erh„lt man einen Zeiger auf einen Zeiger auf die (geladenen) zus„tzlichen Para-
meter x_par. M”chte man letztere freigeben, so kann man dies mit pic_mfree(*x_par) tun,
muss dann aber auch *x_par auf 0 setzen.
Die Funktion kann 1 zurckgeben, wenn sie die Parameter nicht anpassen kann, dann wird
das Laden abgebrochen. Ansonsten muss 0 zurckgegeben werden.



reserved


Weitere achte Eintr„ge (4 Byte) sind reserviert fr m”gliche Erweiterungen. Sie mssen auf
0 gesetzt werden; falls es Erweiterungen geben wird, werden diese natrlich optional sein.



2    Beschreibung der von CHAOSultd zur Verfgung gestellten

     Routinen


Die von CHAOSultd zur Verfgung gestellten Routinen und Variablen sind in der COMMON-
Struktur zusammengefasst. Ein Zeiger auf diese Struktur wird beim ersten Aufruf der Rou-



                                           55




tinen unmittelbar nach dem Laden als Parameter bergeben, die Routine kann ihn dann
irgendwo sichern.



2.1   Routinen


CHAOSultd stellt den externen Routinen die folgenden Funktionen zur Verfgung:



draw_objc


void draw_objc(OBJECT *object, long *buffer);
Die Funktion draw_objc zeichnet die Dialogbox, auf die der Zeiger object zeigt. buffer
ist ein Zeiger auf einen 32000 Byte grossen Speicherbereich, in den vorher der Bildschirm-
hintergrund kopiert wird. Ist buffer 0, so wird der Hintergrund nicht gesichert39.



xdraw_objc


void xdraw_objc(long *buf);
xdraw_objc sichert lediglich den Bildschirm in den Puffer auf den buf zeigt (32000 Byte).
Ist buf 0, so geschieht nichts (auch kein Absturz).



undraw_objc


void undraw_objc(long *buf);
undraw_objc entfernt eine gezeichnete Dialogbox, indem es den Hintergrund aus dem Puffer
buf zurckkopiert. Dies funktioniert natrlich nur, wenn man den Hintergrund auch in den
Puffer gerettet hat.

Anmerkung: die Funktionen draw_objc, xdraw_objc und undraw_objc schalten die Maus ab
und wieder an, darum braucht man sich also nicht zu kmmern. Man sollte beim Kopieren
von Bildschirmen deswegen auch diese Funktionen und nicht die unten genannte Funktion
copy_screen verwenden, die solches nicht erledigt.
Des weiteren sei noch angemerkt, dass die Funktionen unter Bildschirm stets den logischen
Bildschirm verstehen, also den, der sich via Logbase() ermitteln l„sst.



write_dbl


void write_dbl(char *s, double zahl,int l,int p);
Die Funktion write_dbl dient zur Ausgabe einer Fliesskommazahl zahl in einen String s.
l gibt die gewnschte maximale L„nge, p die Zahl der Nachkommastellen an.
Die Zahl wird zun„chst mit sprintf(str,``%*.*lf``,l,p,zahl); in einen Zwischenpuffer
ausgegeben, der 128 Zeichen lang ist (sollte der String l„nger werden so ist mit Systemab-
sturz zu rechnen).
Anschliessend werden abschliessende Nullen entfernt (z.B. 1.2000 wird zu 1.2), lediglich eine
direkt auf den Dezimalpunkt folgende Null bleibt stehen; der String wird dann mit maximal
l Zeichen nach s kopiert.
____________________________________39
    der Zeiger buffer darf natrlich nicht auf eine ungerade Adresse zeigen, bei den folgenden*
 * Routinen sei
solches jeweils a priori angenommen, von CHAOSultd zur Verfgung gestellte Puffer erfllen di*
 *es Bedingung
natrlich; genauso muss object auch wirklich ein Zeiger auf eine Dialogbox sein, andernfalls i*
 *st mit dem
Schlimsten zu rechnen



                                           56




Erkl„rung: bei der Ausgabe einer Fliesskommazahl mit printf kann es erstens passieren
dass der String l„nger als die angegebene L„nge wird, was sich in Dialogboxen verheerend
auswirken kann, zweitens werden abschliessende Nullen ausgegeben, die die Lesbarkeit der
Zahlen nicht gerade erh”hen. Beides versucht zu Routine zu vermeiden, wobei im ersten
Fall in Kauf genommen wird, dass die ausgegebene Zahl wom”glich verstmmelt wird.
Eine Ausgabe in wissenschaftlicher Darstellung, d.h. mit Zehnerexponent, ist nicht vorgese-
hen, da alle bisher von mir realisierten Routinen mit Zahlen rechnen, die nicht in Bereiche
kommen, wo dies sinnvoll w„re.



ipol, xipol


double ipol(double anf, double end, int act_nr, int max_nr, int mode);
void xipol(double anf1, double end1, double anf2, double end2,
double *anf,double *end,int act_nr,int max_nr);
ipol dient zur Interpolation zwischen anf und end. act_nr stellt die Nummer des gewnsch-
ten Wertes, max_nr die maximale Nummer dar (da die Nummern von 0 gez„hlt werden, ist
max_nr gleich der Anzahl der Nummern-1). mode bezeichnet die Art der Interpolation:
_mode_|_________________________________________________________

 0      |degressive Interpolation, die Schrittweite nimmt ab
 1      |lineare Interpolation, die Schrittweite ist konstant
 2      ||progressive Interpolation, die Schrittweite nimmt zu

 3      |Zufallszahl zwischen anf und end (keine Interpolation)

xipol interpoliert ebenfalls und zwar mit Wertepaaren. Dabei „ndert sich die Differenz
zwischen den beiden Werten pro Schritt um einen konstanten Faktor. anf1 und end1 sowie
anf2 und end2 sind Anfangs- und Endwerte fr die beiden Werte. In anf und end werden
die interpolierten Werte zurckgegeben. act_nr und max_nr sind wie oben zu verstehen.
Die xipol-Routine erm”glicht das gleichm„ssige Vergr”ssern von Bl”cken. Interpoliert man
dabei die Koordinaten linear, so ergibt sich am Ende ein gr”sserer Vergr”sserungsfaktor,
da die absolute Žnderung konstant ist. Durch die degressive Interpolation wird dies zwar
abgeschw„cht, aber nicht wirklich behoben. Die xipol-Routine berechnet die Zwischenwerte
dagegen so, dass sich ein konstanter Vergr”sserungsfaktor ergibt.



plot_pixel


void plot_pixel(int x, int y,void *addr);
void plot_pixel(int x, int y,int col,void *addr);
Die Routine plot_pixel zeichnet einen Punkt. Die erste Deklaration gilt fr die sw-Version,
die zweite fr die Farbversion.
x und y beschreiben die Koordinaten des Punktes (in der blichen Weise, die linke obere
Bildschirmecke ist (0,0)). addr ist ein Zeiger auf den Bildschirmspeicher, in dem der Punkt
gesetzt werden soll.
col bezeichnet die Farbe, die der Punkt erhalten soll.
In der sw-Version werden lediglich Punkte gesetzt, L”schen ist nicht m”glich, deshalb wird
auch keine Farbe ben”tigt40.
____________________________________40
    in der Farbversion kann man durch col=0 Punkte auch l”schen



                                           57




Die unterschiedliche Deklaration der Funktion in den beiden Modi ist ein bisschen l„stig,
man kann sie aber durch Definition eines Makros unterdrcken:
#define pl_pixel(x,y,col,addr) plot_pixel(x,y,addr)
in der sw-Version bzw. in der Farb-Version:
#define pl_pixel(x,y,col,addr) plot_pixel(x,y,col,addr)
So kann man in beiden F„llen eine Farbe angeben, sollte natrlich immer bedenken, dass
diese in der sw-Version ignoriert wird.
Alternativ k”nnte man die Deklaration fr die Farb-Version auch fr die sw-Version ver-
wenden, dann wird eben ein zus„tzlicher Parameter (in D2) bergeben, den die aufgerufene
Funktion schlicht ignoriert.



set_point


void set_point(int x,int y,int col,int flag);
set_point zeichnet ebenfalls Punkte. Diese Funktion darf nur beim Zeichnen von Bildern
(also in der Routine do_draw) aufgerufen werden. Sonstiger Gebrauch wird mit Absturz
nicht unter zwei Bomben geahndet!
x und y sind wieder die Bildschirmkoordinaten des Punktes, col seine Farbe. flag ist in der
Farb-Version redundant, in der sw-Version wird mittels flag zwischen Einzelpixeln und 4er-
Gruppen unterschieden. Ist flag 0 so wird ein einzelnes Pixel gesetzt (nicht gel”scht, col
hat dann wieder keine Bedeutung). Ist flag 1 so wird ein aus vier Pixeln ((x,y), (x+1,y),
(x,y+1) und (x+1,y+1)) bestehender Bildpunkt in der Graustufe col gesetzt. col kann die
Werte 0 (weiss), 1 (ein Punkt), 2 (zwei diagonal liegende Punkte), 3 (ein Punkt nicht) und
4 (schwarz) annehmen. Auch hier werden grunds„tzlich Punkte nur gesetzt!



get_pixel


int get_pixel(int x,int y,void *addr);
get_pixel liefert die Farbe des Bildpunktes (x, y) im Bildschirm addr



copy_screen


void copy_screen(long *s,long *d);
copy_screen kopiert (ziemlich schnell) 32000 Byte von s (wie Source) nach d (wie Destina-
tion). Da dies genau die L„nge eines Bildschirmes ist (Overscan geht ja nicht) erkl„rt sich
wohl auch der Name.



clr_screen


void clr_screen(long *s);
clr_screen l”scht 32000 Byte ab s.



pic_malloc, pic_mfree und check_mem


PIC_DATA *pic_malloc(long len,PIC_DATA **mother);
void pic_mfree(PIC_DATA *addr);
int check_mem(long len);



                                           58




Diese Funktionen erlauben der Zugriff auf die interne Speicherverwaltung, der aber nicht
ganz unproblematisch ist.
Das Problem besteht vor allem in der Belegung von Speicher durch die do_draw-Routine
(etwa als zus„tzliche Parameter), da sichergestellt sein muss, dass fr das Ablegen des be-
rechneten Bildes garantiert genug Speicher brigbleibt.
Ich m”chte an dieser Stelle nicht weiter auf diese Funktionen eingehen, da man meist auch
ohne sie auskommen drfte.
Falls die Berechnungsroutinen generell zus„tzlichen Speicher brauchen, so sollten sie ihn in
der do_init-Routine vom TOS (also mit Malloc) anfordern.



gettime


long gettime(void);
Die Funktion gettime liefert den akutellen Wert des 200 Hz Z„hlers (also den Wert der
Systemvariablen an der Adresse $4BA).



get_objc, get_obblk, get_konst und get_block


FR_OBJC *get_objc(int typflag);
int xget_obblk(FR_OBJC *objc, double *x_min, double *x_max,
double *y_min, double *y_max);
FR_OBJC *get_konst(int typflag, double *x, double *y);
FR_OBJC *get_block(int typflag, double *x_min, double *x_max,
double *y_min, double *y_max);
Diese Funktionen erm”glichen die šbernahme von Parametern bestehender Bilder bei der
Eingabe von Parametern.
Die Funktion get_objc liefert einen Zeiger auf ein Objekt, das der Anwender auf dem
Desktop ausw„hlen kann, zurck (oder 0, falls kein Objekt gew„hlt wurde). typflag gibt
an, welche Objekte gew„hlt werden k”nnen: ist typflag -1, so k”nnen beliebige Fractale,
-2 beliebige Bilder (nicht Filme) gew„hlt werden. Ansonsten kann noch ein positiver Wert
(gr”sser 1) angegeben werden, dann k”nnen nur Fractale dieses Types ausgew„hlt werden
(normalerweise ist das dann natrlich die Typnummer der eigenen Routinen, wie man sie
beim Initialiseren bergeben bekommt). Der Bildschirmaufbau der Eingabefunktion wird
von dieser Routine nicht ver„ndert.
Die Funktion get_obblk liefert - falls m”glich - in den Rckgabeparametern x_min, x_max,
y_min und y_max das Koordinatenrechteck des Objektes objc zurck. Als Rckgabewert
wird 0 geliefert, wenn kein Rechteck ermittelt werden konnte, 1 bedeutet, dass die Werte in
x_min, x_max, y_min und y_max gltig sind.
Mit der Funktion get_konst kann man den Benutzer eine Koordinate in einem Bild, mit
get_block einen Ausschnitt w„hlen lassen. Rckgabewerte sind x und y bzw. x_min, x_max,
y_min und y_max sowie (als dierektes Funktionsergebnis) ein Zeiger auf des Objekt in dem
die Koordinate bzw. der Ausschnitt liegt.
Ein Rckgabewert von 0 bedeutet, dass kein Objekt ausgew„hlt wurde (oder im ausgew„hl-
ten Objekt kein Block/keine Konstante bestimmt werden kann); in diesem Fall ist der
Bildschirmaufbau der Eingabefunktion nicht ver„ndert. Ein Rckgabewert von -1 bedeutet
einen Abbruch der Auswahl beim Markieren der Konstante/des Blockes. In diesem Fall
wurde das Bild schon angezeigt, so dass der Bildschirm der Eingabefunktion berschrieben



                                           59




wurde; dargestellt wird dann wieder der CHAOSultd-Desktop und man muss die Dialogbox
neu zeichnen lassen.
typflag wird wie bei get_objc ausgewertet (-2 ist natrlich nicht sehr sinnig, da in Bildern
ohne Parameter natrlich keine Koordinaten zur Verfgung stehen).



fsel


int fsel(char *path,char *sel,int *button,char *label);
Aufruf der Dateiselectorbox entsprechend fsel_exinput, allerdings wird bei „lteren AES-
Versionen automatisch (unter Unterdrckung von label) fsel_input verwendet.



dr_string


void dr_string(char *str);
Ausgabe eines Strings str auf den Drucker entsprechend der gew„hlten Ausgabefunktion.
Zum Drucken der Parameter unter eine Hardcopy ist diese Funktion vernnftigerweise zu
verwenden, da man sich dann nicht selber um den eingestellen Ausgabemodus kmmern
muss.



set_unoutlined


void set_unoutlined(FR_OBJC *object);
Die Funktion set_unoutlined setzt fr das Objekt object den Status nicht fertig, etwa
wenn man (wie bei Hpfer m”glich) nachtr„glich die Zahl der gewnschten Iterationen
erh”ht.



irand und xrand


long irand(long dummy);
double xrand(long dummy);
Zufallszahlengenerator nach D. Knuth. irand liefert eine (Long-)Integer Zufallszahl zwi-
schen 0 und 1000 000 000, xrand eine Fliesskomma-Zufallszahl zwischen 0 und 1. dummy
dient der Initialisierung: ist dummy ungleich Null, so wird der Zufallszahlengenerator (fr
beide Routinen gemeinsam!) initialisiert und zwar mit einem zuf„lligen Wert (aus dem
xbios-Zufallszahlengenerator) falls dummy -1 ist, mit dummy selbst sonst.
Man beachte, dass die Zufallszahlen nach der Initialisierung mit einem bestimmten Wert
natrlich deterministisch und wiederholbar sind, initialisieren sollte man den Zufallszahlen-
generator auch nur einmal am Anfang einer Routine (wenn man ihn bei jedem Aufruf auf
einen festen Wert initialisiert, dann wird er auch immer den gleichen Wert liefern!).



conv_time


void conv_time(unsigned long ms, int *h, int *m, double *s);
Konvertiert die in Millisekunden angegebene Zeit ms in Stunden h, Minuten m und Sekunden
s. Man beachte, dass der letzte Wert als Fliekommazahl zurckgegeben wird.



                                           60




conv_sc_mm und conv_mm_sc


void conv_sc_mm(double scale, double offset, int delta, double *min, double
*max);
void conv_mm_sc(double min, double max, int delta, double *scale, double
*offset);
Mit diesen Routinen kann man zwischen der Definition von Bildschirmkoordinaten durch
Nullpunkt und Vergr”sserung (offset/scale) und durch minimalen und maximalen Achsen-
abschnitt umrechnen. delta gibt die halbe H”he bzw. Breite des gesamten Bildschirms an
( delta ist also die maximale und minimale Koordinate bei scale 1 und offset 0.



Spezielle Funktionen fr die Farb-Version


Die folgenden Funktionen existieren nur in der Farb-Version:



make_alert, make_drawobjc und make_undraw


int make_alert(int button,int *coltab,char *alert);
void make_drawobjc(OBJECT *objc);
void make_undraw(int *coltab);
Mit diesen Funktionen kann w„hrend des Berechnens eines Bildes eine Alert- bzw. Dialogbox
ausgegeben werden. Das Problem besteht dabei im Aufl”sungswechsel, da fr die Berech-
nung in niedrige Aufl”sung geschaltet wurde, fr die AES-Ausgabe aber mittlere Aufl”sung
gebraucht wird.
make_alert gibt eine Alertbox aus. button und alert entsprechen den Parametern von
form_alert, coltab ist ein Zeiger auf die Farbtabelle des Bildes (blicherweise die, die auch
in der FR_OBJC-Struktur steht). Zurckgegeben wird der Rckgabewert von form_alert also
der ausgew„hlte Button.
make_drawobjc und make_undraw sind die Analoga zu draw_objc und undraw_objc, wobei
ein Puffer nicht angegeben werden muss. Fr make_undraw muss man wie bei make_alert
die Farbtabelle angeben. Die Dialogbox wird bei make_drawobjc nur gezeichnet, nicht auf-
gerufen (mit form_do, dies bleibt der externen Routine vorbehalten.
Achtung! Die Routinen ben”tigen als Zwischenspeicher den Puffer, der auch der Zeichen-
routinen do_draw zur Verfgung steht. Der Inhalt dieses Puffers geht deshalb beim Aufruf
einer dieser Routine verloren!
Zur Ausgabe von Dialogboxen beim Anzeigen von Parametern etc. darf man diese Funktio-
nen nicht verwenden, dort man gibt einfach die Dialogbox (z.B. mit draw_objc) aus.



set_colors


void set_colors(int *col_tab,long *scrn,FR_OBJC *object,int flag);
Die Funktion set_colors dient zur Einstellung der Farbtabelle. Wird sie von externen
Routinen aufgerufen, so muss der Parameter scrn 0 sein, flag dagegen 1.
col_tab zeigt natrlich auf die einzustellende Farbtabelle, bleibt noch object. object ist
0 oder ein Zeiger auf ein Bild-Objekt; im letzteren Fall wird im oberen Bildteil bei der
Farbeinstellung das Bild, sonst einfach Farbbalken dargestellt. L„sst man die Farben eines
bestehenden Bildes „ndern, so sollte man natrlich einen Zeiger auf dieses Bild bergeben.



                                           61




2.2   Variable


CHAOSultd stellt noch eine Reihe von Variablen mit verschiedenen Daten zur Verfgung.
Alle diese Werte sind ausschliesslich read-only - Žnderungen darf man nicht vornehmen.



fr_x0, fr_y0, fr_dx, fr_dy und pic_size


int *fr_x0;
int *fr_y0;
int *fr_dx;
int *fr_dy;
int *pic_size;
int *line_len;
Integer-Arrays mit jeweils drei Eintr„gen fr die drei Bildgr”ssen 0 (klein), 1 (mittel) und*
 * 2
(gross).
fr_x0 und fr_y0 enthalten die Koordinaten der linken oberen Ecke, fr_dx und fr_dy die
Breite bzw. H”he der Bilder in Pixeln minus 1!
pic_size enth„lt die L„nge (ungepackter) Bilddaten in Byte, line_len ist die L„nge einer
Zeile, ebenfalls in Byte und zwar pro Bildebene.
Die Arrays enthalten die folgenden Werte:


#ifdef COLOR
int fr_x0[3]=-80,48,0";
int fr_y0[3]=-50,30,0";
int fr_dx[3]=-159,223,319";
int fr_dy[3]=-99,139,199";
int line_len[3]=-20,28,40";
#else
int fr_x0[3]=-160,96,0";
int fr_y0[3]=-100,60,0";
int fr_dx[3]=-319,447,639";
int fr_dy[3]=-199,279,399";
int line_len[3]=-40,56,80";
#endif


int pic_size[]=-8000,15680,32000";



scr


long *scr;
scr ist nur gltig w„hrend des Zeichnens von Bildern. Dann zeigt scr auf den Bildschirm,
und kann (und sollte) fr plot_pixel-Aufrufe verwendet werden.



settings


CHS_SET *settings;
settings ist ein Zeiger auf die Einstellungen von CHAOSultd. Die CHS_SET-Struktur ist in
der Headerdatei definiert.



                                           62




reserved


Auch in dieser Struktur ist Platz fr Erweiterungen gelassen, hier sogar 16 Lang-Worte, die
alle auf Null gesetzt sind.



3    Vorgehensweise


Zun„chst einmal kann man sich, nachdem man diese Beschreibung gelesen hat, die Beispiel-
routinen fr Feigenbaumdiagramme anschauen.
M”chte man eigene Routinen verwirklichen, so sollte man sich als erstes die n”tigen Para-
meter berlegen, und eine entsprechende Struktur fr die Bildparameter definieren, ebenso
eine fr die Eingabeparameter.
Dann muss man die Eingaberoutinen schreiben (natrlich nicht unbedingt gleich mit allen
Details) und die Routine zur Erzeugung des Bildparameter aus den Eingabeparametern;
das Laden der n”tigen Resourcedatei erledigt man in der do_init-Routine.
Hat man dies geschafft, so fehlt nur noch das Herz aller Berechnungsroutinen, n„mlich die
eigentliche Zeichen-Routine.
Hat man alle diese Routinen mehr oder weniger fertig, so erstellt man eine CHAOS-Struktur,
in die man alle Routinen und anderen Daten eintr„gt; fr noch nicht existierende Routinen
tr„gt man 0 ein.
Anmerkung: in der CHAOS-Struktur tauchen jede Menge Zeiger auf void auf, die man in
Deklarationen konkreter Berechnungsroutinen natrlich besser durch Zeiger auf die jewei-
ligen Strukturen ersetzt. Die Warnungen vor verd„chtigen Zeigerumwandlungen, die dann
bei Eintrag der Routinen in eine CHAOS-Struktur auftreten, kann man beispielsweise durch
das Pr„prozessorkommando #pragma warn -sus unterdrcken (falls man die Warnungen
nicht in den Compiler-Optionen eh abgeschaltet hat).
Um die CHAOS-Struktur nun bei der Initialisierung an CHAOSultd zurckzugeben braucht
man noch eine XCHAOS-Struktur, die aus Sicherheitsgrnden und fr die šbergabe mehrerer
CHAOS-Strukturen n”tig ist.
Die XCHAOS-Struktur besteht aus einer 8 Byte langen Id in die man "CHSultd5" eintr„gt, der
Anzahl der Routinen (anz) sowie einem Zeiger auf ein Array mit Integer-Flags (flag) und
einem Zeiger auf ein Array mit CHAOS-Strukturen (chs)41. In den Flags muss das unterste
Bit gesetzt sein, falls die Routine sw-tauglich ist, das 2. Bit steht fr Farbtauglichkeit (l"*
 *auft
die Routine in beiden Aufl”sungen, so setzt man eben beide Bits); die anderen Bits sind
reserviert und auf Null zu setzen).
Hat man dies geschafft, so schreibt man noch die šbergaberoutine fr die Parameter (ana-
log der der Feigenbaum-Diagramme); dann kann man sein Programm bersetzen und via
CHAOSultd aufrufen.
Beim Linken kann und sollte man brigens die Stack-Gr”sse auf Null setzen, da ohnedies der
Stack von CHAOSultd verwendet wird; ein eigener Stack w„re nur Speicherplatzverschwen-
dung. Der Stack von CHAOSultd ist brigens 8 kByte gross und drfte bei allen externen
Funktionen problemlos mit bis zu 6 kByte belastbar sein.
Ein echtes Problem ist das Debuggen, der Source-Level-Debugger hilft einem so gut wie
garnicht und auch Low-Level-Debugging geht nur ohne Label, also praktisch auch nicht.
____________________________________41
    es kann natrlich auch jeweils nur ein Wert vorhanden sein, dann ist anz halt 1 und flag z*
 *eigt auf einen
Integer-Wert, chs auf eine CHAOS-Struktur



                                           63




Wer hier Probleme hat, kann sich ja mal mit mir in Verbindung setzen, eventuell stelle ich
auch die Sourcen von CHAOSultd zur Verfgung, so dass die Routinen als Bestandteil des
Programmes entwickelt und so auch anst„ndig debuggt werden k”nnen. Eine generelle Frei-
gabe des Sourcecodes kommt aber nicht in Frage, dieser Hinweis steht nicht unbeabsichtigt
an wenig herausragender Stelle.



Weitere Hinweise


An Algorithmen kommen im Prinzip alle Algorithmen in Frage, die Bilder um ihrer selbst
willen erzeugen - natrlich auch wenn sie nicht chaotisch sind42.
Dabei sollte der Algorithmus aber auch eine gewisse Bandbreite an verschiedenen Bildern
bieten, Algorithmen, die die Erzeugung genau eines Bildes erm”glichen, sind ja vielleicht
ganz nett, in CHAOSultd aber fehl am Platze, es ist in solchen F„llen allemal einfacher, ein
Programm zu schreiben, dass ein solches Bild berechnet und auf den Bildschirm ausgibt, so
dass man es mit einem Screen-Dump-Programm abspeichern kann.
CHAOSultd ist dazu gedacht, viele Bilder zu berechnen; das Programm untersttzt durch
Berechnungsabbruch und -fortsetzen insbesondere das Berechnen von Bildern ber Nacht
oder wenn man sonst nicht da ist43.
Deswegen sollte man dem Benutzer bei der Wahl der Parameter freie Hand lassen und so
m”glichst viel Variationen zulassen.
Die Routinen sollten auch, so wie die vorhandenen, die Berechnung von Bildfolgen erm”gli-
chen.
In jedem Fall sind fr die Parametereingabe GEM-Dialoge zu verwenden. Man sollte dabei
darauf achten, dass alle Parameter in beliebiger Reihenfolge angegeben werden k”nnen,
braucht man mehr als eine Dialogbox, so sollte man zwischen diesen hin- und herschalten
k”nnen, bzw. die zweite Dialogbox w„re als Unterdialog (wie beim Farben einstellen fr
Fractale) zu realisieren44.
Soweit irgendm”glich sollten die Routinen den Benutzer bei der Eingabe der Parameter
untersttzen, insbesondere die šbernahme von Parametern aus bestehenden Objekten sollte
m”glich sein.
Sehr viele der Routinen sind optional, das heisst aber nicht, dass externe Routinen auf sie
alle verzichten k”nnen. Eine Option sollte nur dann weggelassen werden, wenn sie sich fr
den implementierten Bildtyp nicht, praktisch nicht oder nur mit unverh„ltnism„ssig grossem
Aufwand realisieren l„sst.
Ich denke die von mir bisher geschriebenen Routinen erfllen diese Forderungen recht gut
- am wenigsten die Feigenbaum-Routinen, die sind aber auch vor allem als Beispiel zur
Einbindung externer Berechnungsroutinen entstanden.
Generell sollte man sich diese Routinen zum Vorbild nehmen, nicht nur weil ich sie fr
ganz brauchbar halte, sondern auch, weil Einheitlichkeit fr ein Programm wie CHAOSultd
umso wichtiger ist, je mehr Routinen es gibt (vermutlich schreibt ja eh keiner welche und
ich k”nnte mir das ganze gelabere sparen).
Zur  Schnittstelle  gibt  es  noch  zu  sagen,  dass  sie  h”chstens  erweitert  wird,  nicht *
 * aber
ver„ndert, es sei denn, irgendeine unvorhergesehene Katastrophe tritt auf. Fr CHAOS-
____________________________________42
    nicht geeignet ist CHAOSultd allerdings fr bewegte Bilder (etwa zellul„re Automaten)
  43ein Punkt den externe Routinen auf jeden Fall untersttzen sollten, wenngleich dies fr m*
 *anche Berech-

nungsmethoden m”glicherweise nicht realisieren l„sst
  44die Eingabe der Berechnungsformel fr freidef. Fract. natrlich ein Verstoss gegen diese *
 *Regel



                                           64




ultd V5.0  entwickelte exteren Routinen werden somit auch (ohne Žnderungen) mit allen
weiteren Version von CHAOSultd V5.x zusammenarbeiten.
Dies gilt allerdings nicht fr eine etwaige GEM-Version. Da ich dafr das Programm mehr
oder weniger neu entwickeln msste (weshalb es eine GEM-Version auch nicht so bald geben
wird) wird auch die Schnittstelle neu definiert werden.



                                           65
