reinhard@finalmedia.de cafeface
Mon May 25 01:42:41 PM CEST 2026
Public Domain
Befehle für fdraw sind linebased ascii char. dezimal werte. fdraw erwartet diese Form der Eingabe auf stdin. Das erste Zeichen einer Zeile ist immer der befehl. Dann folgen die Argumente cmd argumente name description ----------------------------------------------------------------------------------- c r g b color Setzt die Zeichenfarbe nach R G B m x y move Bewegt den Zeichencursor zu gewünschten Koordinaten r dx dy rect Zeichnet ein Rechteck p x y r g b pixel Zeichnet exakt einen Pixel an x y in Farbe r g b s n sleep Wartet angegebene Anzahl an Microsekunden o ox oy offset Definiert globalen Offset für Zeichenoperationen Befehle und Parameter/Argumente werden durch ein Leerzeichen /space) getrennt. Alle Argumente MÜSSEN postive Ganzzahlen (integer) sein.
Das Prinzip der Unix-Philosophie besagt, dass Datenströme zeilenbasiert und in ASCII (menschenlesbar) übertragen werden sollten, weil Text die universellste und flexibelste Schnittstelle zwischen Programmen ist.
Durch den zeilenbasierten Austausch über reine ASCII Texte gewinnt man diese Vorteile:
Nicht zu vergessen: Das Prinzip wurde weltberühmt durch Doug McIlroy, den Erfinder der UNIX-Pipe.
Er formulierte das Konzept 1978 im Bell System Technical Journal:
"Expect the output of every program to become the input to another, as yet unknown, program. Don't clutter output with extraneous information. Avoid stringently columnar or binary input formats. Don't insist on interactive input."
Die wichtigste Ergänzung dazu fasste Peter H. Salus 1994 als Philosophie in seinem Buch A Quarter Century of UNIX zusammen. Er formulierte die goldenen Regel:
"Write programs to handle text streams, because that is a universal interface." (Schreibe Programme so, dass sie Textströme verarbeiten, denn das ist eine universelle Schnittstelle.)
Die Intention dahinter ist recht einfach nachvollziehbar. Die Entwickler wollten Modularität statt monolithischer Software.
Wenn ein Programm seine Daten in einem komplexen Binärformat ausgibt, bricht die Kette. Ein binäres Format zwingt das nachfolgende Programm, die genaue Datenstruktur des Vorgängers zu kennen. Standardisierter ASCII-Text entkoppelt hingegen die Programme einer Pipe.
Das nächste Tool muss lediglich wissen, wie man Zeilen trennt. Alles bleibt menschlesbar und die Kette kann an jeder Stelle auseinandergenommen und geprüft werden. Zudem ist es dann ein Leichtes, auch zeilenbasierte Filter zu schreiben, um Ausgaben umzustruktieren, zu wandeln, zu extrahieren, wegzulassen oder aufzutrennen. Wenn du einmal die Magie dahinter verstanden hast, lässt sich das nicht mehr los. Du stellst dir dann eher die umgekehrte Frage: Warum sollte man das nicht so tun?
Hier zum Verständnis
Beispiele: c 140 20 0 Wechselt zur Farbe rot m 20 80 Wechselt zu den Koordinaten x=20 und y=80 r 10 10 Zeichnet ein Quadrat 10x10 px r 10 40 Zeichnet ein Rechteck 10px breit und 40px hoch s 50000 Wartet 50 Millisekunden (für Animationen) p 23 42 164 163 255 Zeichnet einen hellblauen Pixel an x=23 y=42 o 50 100 Definiert einen globalen Offset von x=50 y=100 Gerade das Definieren eines globalen offsets ermöglicht das verschieben eine frames, ohne dessen eigene steuersequenzen verändern zu müssen. Siehe daher auch die Tools charforce, intrange etc. auf https://finalmedia.de/code/ die wunderbar in diese Kette passen.
Hinweis: Für die nachfolgenden awk Demos wird ein awk mit math modul benötigt, z.B. gawk. einfaches busybox awk reicht nicht, solange nicht math support aktiviert ist.
Ob in deinem awk diese mathematischen Funktionen (wie sqrt, sin, log) verfügbar sind, hängtdavon ab, wie die jeweilige Linux-Distribution die BusyBox-Binärdatei kompiliert hat. Die Option muss aktiviert sein: Option CONFIG_FEATURE_AWK_MATH, und dann wird auch die libm mitgeladen. Mit Math-Support ist die binary geringfügig größer, bietet dafür aber alle POSIX-Standard-Mathefunktionen.
export SCREEN_FPS=30 export SCREEN_HEIGHT=240 export SCREEN_WIDTH=320 gawk -v width=320 -v height=240 -f torus.awk | \ fdraw 2>/dev/null | \ ffmpeg -f rawvideo -pixel_format rgba -video_size 320x240 -framerate 30 -i - -frames 300 -y torus.mp4 2>/dev/null
export SCREEN_FPS=30 export SCREEN_HEIGHT=240 export SCREEN_WIDTH=320 gawk -v width=320 -v height=240 -f raytracer.awk | fdraw 2>/dev/null | ffmpeg -f rawvideo -pixel_format rgba -video_size 320x240 -framerate 60 -i - -y raytracer%03d.png gawk -v width=320 -v height=240 -f raytracer.awk | fdraw 2>/dev/null | ffmpeg -f rawvideo -pixel_format rgba -video_size 320x240 -framerate 60 -i - -y raytracer.mp4
export SCREEN_FPS=30 export SCREEN_HEIGHT=240 export SCREEN_WIDTH=320 gawk -v width=320 -v height=240 -f voxel.awk | gzip -9 > voxel.precomputed zcat voxel.precomputed | fdraw 2>/dev/null | ffmpeg -f rawvideo -pixel_format rgba -video_size 320x240 -i - -vf "setpts=0.1*PTS,fps=30" -y voxel.mp4