<< Inhalt >> Spieleteil Inhalt

7. Tech-Abteilung: Informationen von Richard Fagher, Autor von »BabeAnoid«

Alles in meinen Programmen ist AMOS-spezifisch, wenn man die Standarderweiterungen wie z.B. AMCAF usw. nicht mitzählt. Ich benutze keine Library-Aufrufe oder externe Maschinencode-Routinen. Es ist nur gute Programmierung. Ich gebe gern ein paar hilfreiche Tipps, viele davon sind auch in anderen Sprachen anwendbar.

(Natürlich kann ich hier nicht in der gebotenen Kürze auf die Details meiner Programmiertechnik eingehen, aber wenn ein Programmierer einen Blick in meine Quellcodes werfen möchte, kann er sich gern bei mir melden.)

Zu Anfang ein grundlegendes Konzept, das für die Amiga-Classic- (und AMOS-) Programmierung gilt. Das Amiga-System ist hauptsächlich in zwei Gruppen unterteilt: Die Grafik (Blitter, etc.) und Code (Prozessor). Für jede Gruppe separat steht begrenzte Performance zur Verfügung. Man kann den kleinsten und schnellsten Code haben, aber wenn der Blitter nur ein Pixel zuviel zeichnen muss, kann es passieren, dass das Spiel mit 25 FPS statt mit 50 FPS läuft, weil es auf den nächsten VBL (Bildschirm-Refresh) warten muss. Selbst wenn der Code alle verfügbare CPU-Zeit benötigt - der Blitter kann immer noch eine Menge Grafik in dieser Zeit zeichnen.

Im optimalen Fall sollte man soviel Code und Grafik bearbeiten lassen, wie überhaupt in 1/50 s bearbeitet werden kann, um die Amiga/AMOS-Ressourcen voll zu nutzen.

Ein paar Tipps: Vom Offensichtlichen zum Genialen ;) :

1. Man benutze _nie_ mehr Farben (Bitplanes), als tatsächlich benötigt werden, jede zusätzliche Bitplane kostet Zeit! (Eine schnellere CPU bringt hier keinen großen Unterschied.)

Einschub:

Die Hintergrundgrafiken von BabeAnoid belegen nur die ersten beiden Bitplanes eines 32-Farben-Screens. Es muss viel zwischen dem Hauptscreen und den beiden anderen Screens (Buffer) kopiert werden, um die Schatten und die Hintergrunderneuerung zu handhaben. Obwohl alle Screens 32 Farben haben, ist es manchmal möglich, nur die ersten beiden Bitplanes unter Einsatz des "screen copy"-Kommandos zu kopieren.

2. BOBs sollten nie größer sein, als tatsächlich notwendig ist. BOBs sind sehr langsam, und große BOBs sind noch langsamer...

3. Das Gesetz der 16: Wegen der Art, wie der Amiga (und ein Computer allgemein) aufgebaut ist, sollte die horizontale Größe eines Grafikelements vorzugsweise durch 16 oder 8 teilbar sein, da dies im allgemeinen schneller bearbeitet werden kann (gerade Byteanzahl). Man sollte also ein BOB _nicht_ 33 Pixel lang machen, wenn man auch mit 32 Pixel leben kann. Dasselbe gilt für die Koordinaten, an denen eine Grafikaktion ihren Ausgangspunkt hat, man versuche immer, mit dem ersten Bit eines Bytes zu beginnen, also z.B. die Pixel 0, 8, 16, 24, 32, usw.

(Unglücklicherweise sind die Blöcke in BabeAnoid 12 Pixel groß, ironischerweise wären Blocks mit 16 Pixel Größe in einigen Bereichen schneller gewesen und hätten es möglicherweise sogar erlaubt, Blöcke zu animieren)

4. Wenn möglich, sollte man Sprites anstelle von BOBs benutzen, weil diese mittels DMA dargestellt werden und daher weder CPU- noch Blitter-Zeit kosten. Man erstelle die Palette so, dass sie zu den Sprite-Paaren passt, um diese optimal einsetzen zu können.

5. Positionierung: Für einige kleinere Grafikelemente wie Raketen, Sterne, usw. kann man dasselbe Sprite in zwei (oder mehr) verschiedenen Positionen nutzen, indem man es in jedem neuen Frame an anderer Position darstellen lässt. Diese Elemente werden dann zwar flackern und manchmal zitternd dargestellt, aber dies kann durchaus ein erwünschter Effekt sein. (Die sechs Sterne, die in "BabeAnoid" am unteren Bildschirmrand gescrollt werden, sind nur zwei Sprites... und darüber hinaus: Sie werden auch noch für andere Effekte genutzt, wie die fallende Münze und den Laserstrahl.)

6. Aufgaben aufteilen: Wenn möglich, sollte man intensive Grafikoperationen in mehrere Teile aufteilen und je einen Teil pro Frame zeichnen lassen (die Routine, die die Wiederherstellung der Schatten und des Hintergrunds ausführt, wird über den Zeitraum von drei bis vier Frames ausgeführt, um eine Verlangsamung des Spiels zu vermeiden).

7. Die Ausführungszeiten beachten: Einige AMOS-Kommandos sind wirklich langsam, und es gibt oft besseren Ersatz in manchen AMOS-Erweiterungen. Man kann die Zeiten messen, indem man die verschiedenen Kommandos/Routinen in einer Schleife laufen lässt und die benötigte Zeit stoppt. Damit lässt sich herausfinden, welches Kommando/welche Routine am besten/schnellsten läuft (man beachte, dass eine Methode, die auf einer Konfiguration sehr schnell läuft, nicht immer auch die beste Lösung auf einer anderen Konfiguration ist. Das ist oft abhängig vom eingesetzten Prozessor, Fast-RAM und Grafikchip).

8. Eigene Routinen? Wenn das Programm auf schnelle Amigas (040/060) mit Fast-RAM zielt, ist es möglich, dass man eigene Speicherzugriffsroutinen (peek & poke) schreiben kann, die wesentlich schneller sind als die eingebauten Kommandos. Man vermeide die Kommandos für Bit-Operationen von AMOS (und den Erweiterungen), da diese extrem langsam sind. Dagegen sind die Poke-, Doke-, Loke-, Peek-, usw. -Kommandos unheimlich schnell.

(Die Info-Bildschirme mit den animierten Hintergründen zu Beginn von BabeAnoid werden mit einer Routine dargestellt, die eine Vierfach- Vergrößerung in Echtzeit durchführt, erreicht durch Konvertierung von Bytes in Longwords. Diese Routine kann auf einem 68060 in einer Sekunde 100 160x128-16-Farben-Bilder auf volle Bildschirmgröße skalieren!)

9. Prozeduren: Man braucht sich nicht vor den AMOS-Prozeduren zu fürchten, sie werden genauso schnell ausgeführt wie anderer Code. Sie sind im Gegenteil ein ausgezeichneter Weg, den eigenen Code in Form zu halten - besonders, um die Hauptschleife in großen Programmen kurz zu fassen, da AMOS abstürzt, wenn die Hauptschleife 30 KByte überschreitet.

10. Der heilige Gral: Der Schlüssel zum Programmiererfolg ist: Tue nie etwas, was du nicht unbedingt tun musst! Man kann davon ausgehen, dass in den meisten Programmen 25 bis 50 Prozent der CPU-Zeit verschwendet werden, weil das Programm einige Schritte öfter ausführt als tatsächlich nötig wäre! (Für Windows schätzen wir mal, dass es 90 - 99% sind. ;) )

Ein paar Beispiele dafür:

Ein guter Weg, die Arbeit vieler kleiner Routinen und zeitabhängiger Animationen aufzufächern, sind die "rotierenden Variablen"

Beispiel:

DO
    ADD A,1,0 to 5
        IF A=1: "Do thing 1":ENDIF
        IF A=2: "Do thing 2":ENDIF
        IF A=3: ...usw.
LOOP

(Für die Nicht-AMOS-Programmierer: Dies führt eine Reihe von fünf Tasks aus, einen Task pro Frame über einen Zyklus von fünf Frames.)

Man kann auch ein Prioritäten-System anlegen, indem man eine "Time Available"(verfügbare Zeit)-Variable nutzt, die immer bis auf 0 heruntergezählt wird und wieder hochgesetzt wird, wenn wichtige und große Funktionen ausgeführt werden müssen.

Beispiel:

DO
    ADD TA,-1,0 to TA: (REM reduziere TA bis TA auf 0 ist)
        IF mouse key = 1: "Dann Code ausführen, der über mehrere Frames hinweg Zeit benötigt.": ADD TA,10
        IF TA = 0 and "Punktezahl ist verändert" then "Punktezahl aktualisieren"
LOOP

Dieser "Code" sorgt dafür, dass eine Funktion niedriger Priorität, wie die Aktualisierung des Punktestands, warten muss, bis eine Funktion höherer Priorität ausgeführt wurde, falls notwendig.

Das waren die Tipps und Tricks von Richard Fagher. Sollte jemand Interesse an weiteren Tipps und Tricks haben, kann er sich gern an Richard Fagher direkt wenden (dawnbringer@hem.utfors.se).

Wolfgang Hosemann <whose@gmx.de>

<< >>