----------------------------------------------------
Kapitel
4
Player-Missile-Graphiken
----------------------------------------------------
Animation
ist eine wichtige Fähigkeit eines jeden Personal Computer Systems. Sie erhöht
die Begeisterungsfähigkeit und den Realismus eines Programms. Noch wichtiger
aber ist, daß ein bewegtes Bild mehr Information mit größerer Klarheit
übertragen kann, als ein stehendes Bild. Durch Bewegung eines Objektes wird
die Aufmerksamkeit des Benutzers hierauf gezogen. Ein dynamischer Vorgang wird durch
Animation deutlicher, als wenn er indirekt beschrieben wird. Animation ist logischerweise
entscheidend für die Wirkung vieler Computerspiele. Animation muß folglich
als ein wichtiges Element der Graphikmöglichkeiten eines Computers angesehen
worden.
Der
normale Weg, Animation zu erreichen, ist, die Bilddaten durch den Bereich des Bildschirm-RAMs
zu bewegen. Dieses erfordert einen 2-Stufen-Prozess. Als erstes muß das Programm
das alte Bild löschen, indem es Hintergrund (Farb-) -Werte in den Bereich schreibt,
der das augenblickliche Bild enthält. Danach müssen die Bilddaten in den
RAM-Bereich geschrieben werden, welcher der neuen Bildposition entspricht. Durch
wiederholtes Ausführen dieses Vorgangs erscheint auf dem Bildschirm ein sich
bewegendes Bild.
Bei
dieser Technik tauchen allerdings zwei Probleme auf. Erstens: wird die Animation
mit größeren Pixeln ausgeführt, so ist die Bewegung nicht mehr "gleitend";
das Bild bewegt sich ruckartig über den Schirm. Bei vielen Computern besteht
die einzige Lösung dieser Schwierigkeit in der Wahl kleinerer Pixel (höhere
Auflösung). Das zweite Problem ist allerdings weit wichtiger. Der Bildschirm
ist ein zweidimensionales Gebilde, wogegen der gesamte (und damit auch der ihm zugehörige)
RAM-Bereich eindimensional organisiert ist. Das bedeutet, daß Objekte, welche
auf dem Schirm nebeneinander liegen, im RAM nicht hintereinander liegen. Abbildung
4.1 verdeutlicht dieses.
Bild
Entsprechende
Bytes im RAM-Bereich
|
00 00 00
00 99 00
00 BD 00
00 FF 00
00 BD 00
00 00 00
Verteilung der Bild-Bytes im RAM
Abbildung
4.1
Bilder
auf dem Schirm liegen im RAM nicht hintereinander
Die
Bedeutung dieses Umstandes wird erst offensichtlich, wenn man ein Programm zum Bewegen
eines solchen Bildes schreibt. Um die im RAM verstreuten Bytes zu löschen, muß
das Programm ihre jeweilige Adressen berechnen. Diese Berechnung ist im allgemeinen
nicht sehr einfach. Ein Assembler-Programm, das auf ein einzelnes Byte an der Bildschirmposition
XPOS, YPOS zugreift, sieht wie folgt aus (es wird eine Zeilenlänge von 40 Zeichen
vorausgesetzt):
LDA
SCRNRM Anfangsadresse
des Bildschirm-RAMs
STA
POINTR Zero-Page-Zeiger
LDA
SCRNRM+1 Höherwertiges Byte
der Adresse
STA
POINTR+1 Höherwertiger Zeiger
LDA
#$00
STA
TEMPA+1 Zwischenregister
LDA
YPOS Senkrechte
Position
ASL
A
Mal 2
ROL
TEMPA+1 Schiebe ‹bertrag
nach TEMPA+1
ASL
A
Mal 4
ROL
TEMPA+1 Schiebe ein weiteres
Mal
ASL
A
Mal 8
ROL
TEMPA+1 Schiebe erneut
LDX
TEMPA+1 Speichere YPOS mal
8
STX
TEMPB+1 in TEMPB
STA
TEMPB Niederwertiges
Byte
ASL
A
Mal 16
ROL
TEMPA+1
ASL
A
Mal 32
ROL
TEMPA+1
CLC
ADC
TEMPB Addiere
zu YPOS x 8 um YPOS x 40 zu erhalten
STA
TEMPB
LDA
TEMPA+1 Nun bearbeite das
höherwertige Byte
ADC
TEMPB+1
STA
TEMPB+1
LDA
TEMPB TEMPB enthaelt
den Offset vom oberen
CLC
Bildschirmrand zum Pixel
ADC
POINTR
STA
POINTR
LDA
TEMPB+1
ADC
POINTR+1
STA
POINTR+1
LDY
XPOS
LDA
(POINTR),Y
Es
ist klar, daß dieses Programm zu "schwerfällig" zum Zugriff
auf eine Bildschirmadresse ist. Dieses ist also nicht die schnellste und eleganteste
Methode, um das Problem zu lösen; ein guter Programmierer könnte allerdings
das Programm mit Hilfe von speziellen Schaltungen verdichten und kompakter machen.
Der springende Punkt hierbei ist aber, daß das Zugreifen auf Pixel auf dem
Schirm sehr viel Berechnung benötigt. Die obere Routine braucht ungefähr
100 Maschinenzyklen, um auf ein einziges Bildschirm-Byte zuzugreifen. Um ein Bild
zu bewegen, das eine Größe von 50 Bytes besitzt, würden 100 solcher
Zugriffe benötigt, was 10.000 Maschinenzyklen oder ca. 10 Millisekunden entspricht.
Dieses klingt nicht nach viel, aber wenn eine gleitende Bewegung erreicht werden
soll, muß ein Objekt alle 17 Millisekunden bewegt werden. Werden nun noch andere
Objekte bewegt oder Berechnungen ausgeführt, dann hat der Prozessor nicht mehr
viel Zeit, um diese zu bearbeiten. Hinzu kommt allerdings noch, daß diese Art
der Animation (sog. "Playfield"-Animation: Playfield = Spielfeld) für
viele Zwecke zu langsam ist. Animation kann natürlich trotzdem auf diesem Wege
erreicht werden, sie muß dann allerdings auf wenige (oder kleinere) Objekte
oder langsamere Bewegung beschränkt werden. Die bei dieser Art der Animation
vom Programmierer zu machenden Abstriche sind also schwerwiegend.
Die
ATARI-Computer-Lösung dieses Problems sind die sogenannten "Player-Missile"
Graphiken. Um diese Graphik-Möglichkeit zu verstehen, ist es wichtig, daß
der Leser das grundsätzliche Problem der Playfield-Animation begreift: das Bild
auf dem Schirm ist zweidimensional, wogegen das Bild im RAM eindimensional ist. Die
Lösung dieser Schwierigkeit besteht in der Schaffung eines Bildes, das sowohl
im RAM, als auch auf dem Bildschirm eindimensional ist. Dieses Objekt, genannt Player,
erscheint im RAM als ein 128 bzw. 256 Bytes großer Bereich. Dieser Bereich
wird aus dem Speicher direkt auf den Bildschirm projeziert. Es erscheint auf dem
Bildschirm als ein senkrechtes Band, das vom oberen bis zum unteren Rand reicht.
Jedes Byte dem Bereichs entspricht entweder einer oder zwei Horizontal Scan Lines.
Diese Auswahl trifft der Programmierer. Das Bild auf dem Schirm ist ein einfacher
bitweiser Auswurf der Daten dieses Speicherabschnittes. Besitzt ein Bit in diesem
Bereich den Wert 1, so leuchtet das entsprechende Pixel auf der Mattscheibe; enthält
es den Wert 0, so ist das Pixel dunkel. Player-Bilder sind also nicht strikt eindimensional;
sie sind 8 Bits breit.
Das
Zeichnen eines Players auf dem Schirm ist sehr einfach. Als erstes muß das
gewünschte Bild auf kariertem Papier entworfen werden. Dieses Bild darf allerdings
nicht breiter als 8 Pixel sein. Danach wird das Bild in Binär-Code umgesetzt,
d.h. für jedes erleuchtete Pixel wird eine 1 notiert; für jedes dunkle
Pixel eine 0. Die so entstehende Zahl wird in eine Dezimal- oder Hexadezimalzahl
übersetzt, abhängig davon, was dem Programmierer vertrauter ist. Schließlich
werden die Bilddaten in den Player-RAM-Bereich geschrieben, wobei das erste Byte
des Player-Bildes oben und das letzte unten im Speicher steht (d.h. bei niedriger
bzw. höherer Adresse). Je weiter unten die Bilddaten innerhalb des entsprechenden
Bereichs im RAM plaziert werden, desto weiter unten erscheint das Bild auf der Mattscheibe.
Die
Animation dieses Bildes geht sehr einfach von statten. Senkrechte Bewegung wird erreicht,
indem die Bilddaten durch den RAM-Bereich geschoben werden. Dieses ist im Prinzip
die gleiche Methode, die auch bei der Playfield-Animation verwendet wird. Es gibt
allerdings einen großen Unterschied: die Bewegungsroutine für senkrechte
Bewegung ist eine eindimensionale, anstelle einer zweidimensionalen Bewegung. Das
Programm muß zur Errechnung der senkrechten Position des Objektes die Zeilenlänge
berücksichtigen, und es wird nur sehr selten von indirekter Adressierung Gebrauch
gemacht. Ein Programm für diese Aufgabe könnte folgendermaßen aussehen:
LDX #$01
LOOP LDA PLAYER,X
STA PLAYER-1,X
INX
BNE LOOP
Diese
Routine benötigt ungefähr 4 Millisekunden, um den gesamten Player zu bewegen;
das entspricht fast der halben Zeit, die die Playfield-Animation benötigt. Weiterhin
bewegt die Playfield-Animation nur 50 Bytes, wogegen die obige Routine 256 Bytes
verschiebt. Wenn noch höhere Geschwindigkeiten nötig sind, könnte
die Schleife darauf ausgerichtet werden, nur die Bild-Bytes selbst (anstelle des
gesamten Players) zu bewegen; eine solche Schleife würde leicht eine Ausführungszeit
von 100 bis 200 Mikrosekunden erreichen. Der maßgebliche Punkt bei dieser Art
der Animation ist, daß senkrechte Bewegung der Player sehr viel einfacher ist
als mit Playerfield-Objekten.
Einfacher
noch als die senkrechte Bewegung eines Players ist dessen waagerechte. Es gibt für
jeden Player ein Register, daß als "Horizontal Position"-Register
bezeichnet wird. Der Wert in diesem Register legt die waagerechte Position des Players
auf dem Bildschirm fest. Um einen Player an eine bestimmte Bildschirmposition zu
bringen, muß lediglich der entsprechende Wert in dieses Register geschrieben
werden.
Waagerechte
und senkrechte Bewegung eines Players sind voneinander unabhängig; sie können
beliebig miteinander kombiniert werden.
Die
Einheit für das Horizontal-Position-Register ist das Color Clock. Wird der Wert
des Registers um 1 erhöht, dann bewegt sich der Player um ein Color Clock nach
rechts. Es gibt 228 Color Clocks in einer einzelnen Scan Line, von denen aber aus
Gründen des Overscans nicht alle sichtbar sind. Abhängig vom Overscan des
jeweiligen Fernsehgerätes befinden sich die Positionen 0 bis 44 außerhalb
des linken, und die Positionen 220 bis 255 außerhalb des rechten Bildschirmrandes.
Die sichtbaren Player-Positionen liegen zwischen den Stellen 44 bis 220. Dieses kann
manchmal Probleme aufwerfen, eröffnet aber eine praktische Möglichkeit:
um den Player vom Bildschirm verschwinden zu lassen, muß seine waagerechte
Position auf 0 gesetzt werden. Durch einfaches Laden und Speichern (mit POKE in BASIC)
wird der Player unsichtbar.
Das
soweit beschriebene System macht Animation mit hoher Geschwindigkeit möglich.
Es sind allerdings noch einige zusätzliche Anmerkungen zu machen. Als erstes
gibt es vier voneinander unabhängige Player. Jeder dieser Player besitzt einen
eigenen RAM-Bereich; d.h. ihre Operationen sind voneinander völlig unabhängig.
Die Player besitzten die Label (Bezeichnungen) P0 bis P3. Sie können nebeneinander
benutzt werden, um eine Auflösung bis zu 32 Bits (in der Breite) zu liefern,
oder um einzelne Objekte darzustellen.
Jeder
Player besitzt weiterhin ein eigenes Farbregister, das unabhängig von allen
anderen (Playfield- oder Player-Farbregister) die Farbe des Players bestimmt. Dieses
Farbregister wird mit COLP(X) bezeichnet und besitzt eine Schattenadresse mit dem
Namen PCOLR(X). Dieses gibt dem Benutzer die Möglichkeit, mehr Farbe auf den
Bildschirm zu bringen. Jeder Player besitzt allerdings, da für jeden nur ein
Register vorhanden ist, eine Farbe; mehrfarbige Player sind nur mit Display Liest
Interrupts möglich (siehe Kapitel 5).
Jedem
Player wird außerdem ein Register zur Festlegung seiner Breite zugeordnet.
Er kann auf einfache, doppelte und vierfache Breite gesetzt werden. Dieses geschieht
mit dem SIZEP(X)-Register.
Schließlich
kann die senkrechte Auflösung vom Benutzer gesteuert werden. Es gibt eine Auswahl
zwischen Einzel-Zeilen- und Doppel-Zeilen-Auflösung. Bei ersterer legt ein Byte
des Speicherbereiches das Aussehen einer Scan Line fest; bei Doppel-Zeilen-Auflösung
das Aussehen von zwei Scan Lines. Bei Einzel-Zeilen-Auflösung ist der Speicherbereich
für einen Player 256 Bytes lang, bei Doppel-Zeilen-Auflösung 128 Bytes
lang.
Dieses
ist auch der einzige Fall, bei dem die einzelnen Player voneinander abhängig
sind; die senkrechte Auslösung gilt für alle Player. Sie wird durch Bit
D4 des DMACTL-Registers bestimmt. Bei Doppel-Zeilen-Auflösung befinden sich
die ersten 10 Bytes des Bereiches außerhalb des oberen und die letzten 20 Bytes
außerhalb des unteren Bildschirmrandes. Bei Einzel-Zeilen-Auflösung sind
es entsprechend 20 und 40 Bytes, die verlorengehen.
Die
nächste Erweiterung liegt in den sogenannten Missiles. Dieses sind 2-Bit breite
Graphik-Objekte, ähnlich den Playern. Jeweils eine Missile wird einem Player
zugeordnet; sie erhält ihre Farbe aus dem entsprechenden Farbregister des Players.
Das Aussehen einer Missile wird ebenfalls in einem bestimmten RAM-Bereich festgelegt.
Dieser liegt genau vor dem RAM-Bereich der Player. Alle Missiles befinden sich innerhalb
des gleichen Bereichs (4 Missiles mit jeweils 2 Bits sind zusammen 8 Bits). Missiles
können unabhängig von den Playern bewegt werden; sie besitzen ihre eigenen
Horizontal-Position-Register. Außerdem besitzen Missiles ein eigenes Register
für die Größe (SIZEM), das genauso wie das SIZEP(X)-Register für
die Player funktioniert. Dieses Register gilt allerdings für alle Missiles,
d.h. sie werden immer auf die gleiche Breite gesetzt.
Missiles
können als Kugeln oder dünne senkrechte Linien auf dem Bildschirm benutzt
werden. Wenn erforderlich, können die Missiles zu einem fünften Player
zusammengesetzt werden, wobei dessen Farbe dann durch das Farbregister für Playfield
3 bestimmt wird. Dieses wird durch Setzen des Bits D4 des Prioritäten-Kontroll-Registers
(PRIOR) erreicht. Die Missiles können natürlich auch in dieser Option unabhängig
voneinander bewegt werden, da ihre Positionen von den zugehörigen Horizontal-Position-Registern
gesteuert werden. Das "Einschalt-Bit" für den 5. Player beeinflußt
nur die Farbe der
Missiles.
Eine
senkrechte Bewegung der Missiles wird wie bei den Playern erreicht: durch Schieben
der Bilddaten durch den zugehörigen RAM-Bereich. Hierbei können sich allerdings
Probleme ergeben, da die Missiles, wie schon angesprochen, in ein- und demselben
Bereich stehen. Um also eine Missile senkrecht zu bewegen, müssen die Bits der
anderen ausmaskiert werden.
Eine
wichtige Fähigkeit der Player-Missile-Graphik ist die absolute Unabhängigkeit
der Player und Missiles vom Playfield.
Diese
Objekte können mit jedem Graphik- oder Textmodus gemischt werden. Dieses wirft
wiederum ein Problem auf: was geschieht, wenn ein Player oder eine Missile sich mit
einem Playfield-Objekt überschneidet? Welches Bild hat Vorrang? Hierfür
gibt es ein sogenanntes Prioritäten-Kontroll-Register, mit dem es dem Programmierer
möglich ist, diese Vorrangigkeit zu definieren. Dieses Register wird mit PRIOR
bezeichnet und besitzt eine ‹bertragungsadresse, genannt GPRIOR. Durch diese Auswahlmöglichkeit
können interessante Effekte erzeugt werden indem ein Player vor einem und hinter
einem anderen Playfield-Objekt vorbeiläuft.
Die
letzte Erweiterung liegt in der Lieferung der sogenannten Kollisions-Abfrage (Collision
Detection = Kollisions- Erfassung), die über die Hardware läuft. Es ist
hiermit möglich zu prüfen, ob ein Objekt (Player oder Missile) mit irgendeinem
anderen (Player, Missile oder Playfield) zusammengestoßen ist. Genaür
gesagt, können folgende Kollisionen erfaßt werden: Missile - Player, Missile
- Playfield, Player - Playfield, Player - Player sowie Player - Missile. Es gibt
54 Möglichkeiten solcher ‹berschneidungen, denen jeweils ein Bit zugeordnet
wird. Dieses Bit enthält eine 1, wenn eine zugehörige Kollision auftrat.
Die Bits befinden sich in 15 CTIA-Registern (wobei jeweils nur die unteren Nybbles
benutzt werden). Diese Register sind Nur-Lese-Register, d.h. sie können nicht
durch Nullschreiben gelöscht werden. Letzteres geschieht, indem irgendein beliebiger
Wert in das HITCLR-Register geschrieben wird, wodurch dann alle Kollisions-Register
gelöscht werden.
Hardwaremäßig
wird eine Kollision durch die ‹berschneidung von zwei Bildern, z.B. Player und Playfield,
verursacht; das bedeutet, das Kollisionsbit wird erst gesetzt, nachdem der Teil des
Bildschirmes, auf dem sich die ‹berlappung ereignet, gezeichnet wurde. Eine Kollision
wird daher frühestens 16 Millisekunden nachdem der Player bewegt wurde, registriert.
Die beste Lösung ist, eine Abfrage der Kollisionsregister während der Vertical-Blank-Interrupt-Routine
(siehe Anhang I) durchzuführen. In diesem Fall sollte als erstes die Kollisions-Abfrage
durchgeführt, dann die Register gelöscht und schließlich der Player
bewegt werden. Es kann allerdings auch 16 Millisekunden gewartet werden, bevor die
Kollisions-Register abgefragt werden.
Es
gibt eine Anzahl von Schritten, die für die Benutzung der Player-Missile-Graphiken
erforderlich sind. Als erstes muß ein RAM-Bereich für die Player und Missiles
vorbereitet werden. Danach wird dem Computer mitgeteilt, wo dieser Bereich sich befindet.
Wenn Einzel-Zeilen-Auflösung benutzt wird, ist dieser RAM-Bereich 1280 Bytes
lang; bei Doppel-Zeilen-Auflösung ist er 640 Bytes lang. Ein guter Platz für
diesen ist das RAM direkt vor dem Display-Bereich am Anfang des Speicherbereiches.
Das Layout des Player-Missile-Bereiches wird in Abbildung 4.2 dargestellt.
Abbildung
4.2
Layout
des Player-Missile Bereiches im RAM
Der
Zeiger, der auf den Anfang des Player-Missile Bereiches zeigt, wird mit PMBASE bezeichnet.
Aufgrund der internen Beschränkungen ANTICs muß PMBASE bei Einzel-Zeilen-Auflösung
an einer 1K-Grenze und bei Doppel-Zeilen-Auflösung an einer 2K-Grenze liegen.
Werden nicht alle Player benutzt, ist es vorteilhaft, den restlichen RAM-Bereich
wieder für andere Zwecke zu verwenden. Sobald festgelegt wurde, wo der RAM-Bereich
für die Player und Missiles liegen soll, wird ANTIC informiert, indem die Page-Nummer
von PMBASE in das PMBASE-Register ANTICs geschrieben wird.
Als
nächstes werden die Parameter der Player, z.B. Farbe, horizontale Position und
Breite, auf die gewünschten Werte gesetzt. Ebenso können die Prioritäten
gesetzt werden. Schließlich muß ANTIC noch über die senkrechte Auflösung
informiert werden. Für Einzel-Zeilen-Auflösung wird das Bit D4 im DMACTL-Register
gesetzt. Bei Doppel-Zeilen-Auflösung wird dieses Bit gelöscht. Die Schattenadresse
von DMACTL trägt die Bezeichnung SDMCTL. Als letztes wird die Player-Missile-Graphik
durch Setzen des PM-DMA-Bits in DMACTL aktiviert. Bei diesem Setzen muß darauf
geachtet werden, daß die anderen Bits dieses Registers nicht geändert
werden. Das folgende Programm ist ein Beispiel für das Aufbauen und Bewegen
eines Players.
1
PMBASE=54279:REM
Zeiger zum Anfang des
PM-Bereichs
2
RAMTOP=106:REM
Zeiger zum Ende des freien RAMs
3
SDMCTL=559:REM
Schattenadresse von DMACTL
4
GRACTL=53277:REM
Graphik-Kontroll-Register
im CTIA
5
HPOSP0=53248:REM
Horizontal-Position-Register PO
6
PCOLR0=704:REM
Farbregister für Player 0
10
GRAPHICS 0:SETCOLOR 2,0,0:REM Hintergrundfarbe-Schwarz
20
X=100:REM
waagerechte Playerposition
30
Y=48:REM
senkrechte Playerposition
40
A=PEEK(RAMTOP)-8:REM
2K-Grenze unter dem RAM-Anfang
50
POKE PMBASE,A:REM
Position vom PM-Bereich an ANTIC
60
MYPMBASE=256*A:REM
Adresse des PM-RAMs
"errechnen"
70
POKE SDMCTL,46:REM
Doppel-Zeilen-Auflösung
80
POKE GRACTL,3:REM
PM-Graphik aktivieren
90
POKE HPOSP0,100:REM
Waagerechte Position festlegen
100
FOR I=MYPMBASE+512 TO MYPMBASE+640:REM Bereich löschen
110
POKE I,0
120
NEXT I
130
FOR I=MYPMBASE+512+Y TO MYPMBASE+518+Y
140
READ A:REM
Bilddaten für Player lesen
150
POKE I,A
160
NEXT I
170
DATA 8,17,35,255,32,16,8
180
POKE PCOLR0,88:REM
Playerfarbe ist Pink
190
A=STICK(0):REM
Joystick abfragen
200
IF A=15 THEN GOTO 190:REM wenn inaktiv, nochmal versuchen
210
IF A=11 THEN X=X-1:POKE HPOSP0,X
220
IF A= 7 THEN X=X+1:POKE HPOSP0,X
230
IF A<>13 THEN GOTO 280
240
FOR I=8 TO 0 STEP -1
250
POKE MYPMBASE+512+Y+I,PEEK(MYPMBASE+511+Y+I)
260
NEXT I
270
Y=Y+1
280
IF A<>14 THEN GOTO 190
290
FOR I== TO 8
300
POKE MYPMBASE+511+Y+I,PEEK(MYPMBASE+512+Y+I)
310
NEXT I
320
Y=Y+1
330
GOTO 190
Sobald
Player einmal angezeigt wurden, ist es aufgrund der einzelnen Schritte, die beim
Anzeigen nötig sind, etwas schwierig, sie wieder vom Bildschirm zu löschen.
Erstens holt sich ANTIC die Player-Missile-Daten aus dem RAM (sofern dieses durch
das DMACTL-Register gestattet wird). Danach werden die Daten von ANTIC an den CTIA
übergeben (abhängig von dem Wert in GRACTL). Der CTIA zeigt an, was sich
in seinen Player-Missile-Registern befindet, egal was es ist (GRAFP0 bis GRAFP3,
sowie GRAFM). Durch Ausschalten der entsprechenden Kontrollbits in den DMACTL- und
GRACTL-Registern werden die Player-Missile-Objekte nicht gelöscht. Dieses verhindert
nur, daß ANTIC neue Bilddaten für die Player-Missile-Graphiken an den
CTIA weitergibt; die alten Daten in den GRAF(X)-Registern werden weiterhin angezeigt.
Um die Player-Missile-Graphiken zu löschen, müßen die Daten in den
GRAFP(X)-Registern gelöscht werden, nachdem die Kontrollbits in DMACTL und GRACTL
auf Null gesetzt worden sind. Eine einfachere Lösung besteht darin, die waagerechten
Positionen der zu löschenden Objekte auf 0 zu setzen. ANTIC wird hierdurch allerdings
nicht daran gehindert, weiter Daten an den CTIA zu übertragen, was pro Sekunde
ungefähr 10.000 Maschinenzyklen verbraucht.
Player-Missile-Graphiken
eröffnen eine Anzahl spezieller Möglichkeiten. Sie sind z.B. für Animation
von großem Wert. Es gibt allerdings auch Einschränkungen. So sind nur
vier Player vorhanden, wobei jeder Player eine Breite von nur 8 Bits, d.h. Pixel
hat. Werden für die waagerechte Auflösung mehr Bits benötigt, so muß
au+ normale Playfield-Animation zurückgegriffen werden. Für schnelle und
einfache Animation sind Player allerdings optimal.
Es
ist auch möglich, ANTIC zu "umgehen" und die Player-Missile-Bilddaten
direkt in die PM-Graphik-Register des CTIA-Prozessors (GRAFP(X)) zu schreiben, wodurch
dem Programmierer eine direktere Kontrolle über die Player-Missile-Graphiken
gestattet wird. Hierbei wird aber dem
Programmierer eine
größere Verantwortung übertragen, da er die
Bit-Ausgabe
für die Bilddaten aufrechterhalten und im richtigen Augenblick in die Graphik-Register
bringen muß. Hierbei muß der 6502-Prozessor herangezogen werden und im
Bildschirmzyklus arbeiten (siehe "Kernel" in Kapitel 5). Dieses ist eine
sehr umständliche Technik, die viel Konzentration beim Programmieren erfordert
und wenig Vorteile in der Ausführung einbringt.
Player-Missile-Graphiken
sind auch für andere Verwendungszwecke, als nur für Animation von Nutzen.
Player sind eine gute Möglichkeit, die Farbenzahl eines Displays zu erhöhen.
Die vier zusätzlichen Farbenregister liefern pro Zeile des Displays vier weitere
Farben. Die Spannweite der Anwendungen von Playern in dieser Richtung wird natürlich
durch ihre lediglich 8 Bit breite Auflösung eingeschränkt. Manchmal kann
dies allerdings umgangen werden: als erstes wird ein Player auf vierfache Breite
gesetzt. Danach werden die Prioritäten so gesetzt, daß er hinter einer
Playfield-Farbe verschwindet. Als nächstes wird diese Playfield-Farbe mit der
Hintergrund-Farbe vertauscht, so daß der scheinbare Hintergrund aus einer Playfield-Farbe
besteht. Der Player verschwindet hinter diesem falschen Hintergrund. Nun wird in
letzteren ein Loch geschnitten. Dieses geschieht, indem der richtige Hintergrund
an die betreffende Stelle gemalt wird. Der Player ist vor diesem richtigen Hintergrund
sichtbar, allerdings nur in dem Bereich, wo dieser gezeichnet wurde. Auf diese Weise
besitzt ein Player eine größere Auflösung als 8 Bits. Das folgende
Programm zeigt oben beschriebenen Trick:
1 RAMTOP=105
2 PMBASE=54279:REM
PM Basis-Zeiger ANTICs
3 SDMCTL=559:REM DMACTL-Schattenadresse
4 GRACTL=53277:REM
CTIA Graphik-Kontroll-Register
5 HPOSP0=53248:REM
Horizontal Pos.-Reg. von P0
6 PCOLR0=704:REM Farbregister-Schattenadresse
von P0
7 SIZEP0=53256:REM
Breitenregister für Player 0
8 GPRIOR=623:REM Prioritäts-Kontroll-Register
10 GRAPHICS 7
20 SETCOLOR 4,8,4
30 SETCOLOR 2,0,0
40 COLOR 3
50 FOR Y=0 TO 79:REM
Diese Schleife füllt den Schirm
60 PLOT 0,Y:REM mit
dem "falschen" Hintergrund.
70 DRAWTO 159,Y
80 NEXT Y
90 A=PEEK(RAMTOP)-20:REM
Muß wegen GRAPHICS 7 weiter "nach
100 POKE PMBASE,A:REM
oben" gesetzt werden.
110 MYPMBASE=256*A
120 POKE SDMCTL,46
130 POKE GRACTL,3
140 POKE HPOSP0,100
150 FOR I=MYPMBASE+512
TO MYPMBASE+640
160 POKE I,255:REM
Feste Farbe für den Player
170 NEXT I
190 POKE PCOLR0,88
190 POKE SIZEP0,3:REM
Player auf Einfache Breite setzen
200 POKE GPRIOR,4:REM
Prioritäten setzen
210 COLOR 4
220 FOR Y=30 TO 40:REM
"Loch schneiden"
230 PLOT Y+22,Y
240 DRAWTO Y+43,Y
250 NEXT Y
Dieses Programm erzeugt
folgendem Bild auf der Mattscheibe:
Abbildung
4.3
Maskieren
eines Players zum
Erreichen
einer höheren Auflösung
Eine
andere Anwendungsmöglichkeit von Playern besteht in der Darstellung von speziellen
Zeichen. Es gibt eine Anzahl von Zeichen, die die normalen vertikalen Begrenzungen
eines Zeichensatzes überschreiten würden. Eine Möglichkeit für
die Lösung dieses Problems wäre, spezielle Zeichensätze hierfür
zu entwerfen. Eine andere Möglichkeit besteht in der Verwendung der Player.
Unterstriche, Integralzeichen und andere spezielle Symbole können auf diese
Weise dargestellt werden. Das folgende Programm ist ein Beispiel für eine solche
Playerverwendung:
1 RAMTOP=106
2 PMBASE=54279
3 SDMCTL=559
4 GRACTL=53277
5 HPOSP0=53248
6 PCOLR0=704
10 GRAPHICS 0:A=PEEK(RAMTOP)-16:REM
Muß wegen Einzel-Zeilen 20 POKE PMBASE,A:REM
Auflösung weiter "nach
30 MYPMBASE=256*A:REM
oben" gesetzt werden.
40 POKE SDMCTL,62
50 POKE GRACTL,3
70 FOR I=MYPMBASE+1024
TO MYPMBASE+1280
60 POKE I,0
90 NEXT I
100 POKE PCOLR0,140
110 FOR I=0 TO 15
120 READ X
130 POKE MYPMBASE+1100+I,X
140 NEXT I
150 DATA 14,29,24,24,24,24,24,24
160 DATA 24,24,24,24,24,24,184,112
170 ? " ":REM
Bildschirm löschen
180 POSITION 15,6
190 ? "xdx"
Dieses Programm erzeugt
folgendem Bild:
Abbildung
4.4
Benutzung
eines Players als spezielles Zeichen
Eine
teilweise nützliche Verwendung von Playern wäre, sie als Cursor zu benutzen.
Mit ihrer Fähigkeit, sich fließend an jede Bildschirmposition zu bewegen,
sind sie ideal für solche Zwecke. Der Cursor kann außerdem seine Farbe
ändern, während er sich über den Bildschirm bewegt, um anzuzeigen,
was sich unter ihm befindet.
Player-Missile-Graphiken
besitzen viele Anwendungsmöglichkeiten. Ihre Verwendung als bewegtes Objekt
bei Telespielen ist offensichtlich. Sie besitzen aber mindestens ebensoviele "ernsthafte"
Anwendungen. Sie können die Farbenvielfalt und Auflösung eines jeden Displays
verbessern, ebenso als spezielle Zeichen verwendet, aber auch als Cursor benutzt
werden. Man kann daher nur zu ihrem Gebrauch aufrufen.