16-FARBEN-SCROLLING
" Wow!- So bunt und' n irrer Speed!" ;
so in etwa lauteten die Reaktionen auf
die ersten 16- Farben-Bitmaps, die vom
VIC gesteuert über den Bildschirm des
C64 rasten.
Natürlich, wie so oft, waren die ersten
Programmierer, die den Brotkasten einmal
mehr austricksten, Coder aus der Demo-Szene. Zuerst sah man die Bitmaps nur
horizontal " tanzen", doch richtig beeindruckend wurde es durch die Vertikal-Bewegung, durch das sog.' Linecrunching' was soviel wie ' Zeilen-Komprimierung' bedeutet.
In Spielen setzte sich der Trick nur
sehr träge durch. In den beiden " Stormlord"- Games waren zwar bunte Pixels am
Scrollen, doch war dies durch gesamtes
Neuaufbauen und Umschalten zwischen zwei Screens realisiert worden." Phobia", ein
altes Baller-Spektakel bediente sich
des Horizontal-Tricks, um beim Scrollen
( ein Charakter+$ d800- Farbram-Scroller) Prozessor-Zeit zu sparen. Selbiger
Trick, allerdings schon für bunte
Bitmaps, wurde in " Eskimo Games" verwendet und " Another World" lief sogar
mit Linecrunching-Scrolling, allerdings
nur horizontal. Sogar " Creatures" wartete mit Bitmap-Scrolling auf, doch
nur im Miniatur-Format um die Level-Übersich darzustellen. Das Spiel selbst
scrollte wieder in normalen Character-Modus. . .
Wir sehen, daß sich der Trick mit dem
bunten 8- Wege-Scrolling in Spielen noch
nicht manifestieren konnte. Warum, wo
die Schwierigkeiten und Hindernisse
liegen, welche Möglichkeiten es gibt, sie zu überwinden und wo letztendlich
die Grenzen des C64 in diesem Bereich
liegen, das versuche ich in diesem Kurs zu übermitteln.
Folgender ist in 3 Teile unterteilt:
Teil I: Einführung, Theoretisches
Teil II: Beispiel und Dokumentation anhand des Source-Codes
Teil III: Praxis, Einbinden des Codes in eigene Programme, Arbeiten
mit dem " Bitmap-Manager" .
Da zur Einleitung eigentlich alles erwähnt wurde, wollen wir nun zum Theoretischen kommen. Um diesen Kurs mehr oder
weniger erfolgreich zu absolvieren sind
als Vorraussetzung recht gute Assembler-Kenntnisse sowie Erfahrung mit dem VIC
des C64 mitzubringen. Ich werde mich
aber bemühen, dieses doch recht umfangreiche Thema so einfach wie möglich, und
vor Allem für jeden verständlich zu
erläutern.
Beim Thema Bitmap-Grafik- Scrolling ist
immer die Rede von einem Trick. Ja
logisch, oder ? Beim ' normalen' Scrollen
im Character-3- Farben-Modus ist lediglich beim Überlauf eines der beiden
Scroll-Register der Screen-Inhalt um
ein Zeichen zu verschieben. Im Grafik-Modus sieht' s da ganz anders aus: Zu
verschieben sind die gesamte Bitmap, der Screen und das Farbram, also insg.
knapp 10 KB. Kurz gesagt für einen C64 mit einer Taktfrequenz von 1 Mhz ist
das flüssige Scrolling einer solchen
Daten-Menge schier unmöglich. . .
. . . doch - da war doch dieses eine Demo, mit dem großen bunten Logo, das da in
alle Richtungen flog, so schnell und
flüssig, Sprites wurden auch noch dargestellt; als ob Bitmap-Scrolling noch
weniger Prozessor-Zeit schlucken würde, als übliches Scrolling.
UND GENAU DAS (!) IST ES.
Am C64 gibt es eine Möglichkeit, den
Bildschirm ohne enormen Rasterzeit-Verlust in alle Richtungen zu bewegen, als ob man die Start-Werte links oben
für Textund Grafik-RAM selbst wählen
kann. Wer sich am Amiga auskennt, der
weiß, daß es dort durch Register ganz
einfach ist, die Start-Werte links
oben für die Grafiken zu bestimmen;
ab jetzt auch für den C64 ! ! !
Gut, Haupt-Register der Scroll-Routine
ist das Register $ d011( wer öfter mit
dem VIC herumexperimentiert, weiß, daß
jenes Register bei den meisten Tricks
und Effekten ( FLI, FLD, . . .) die Haupt-Regie führt) .
Grundlegend ist das $ d011- Register wie
folgt belegt:
Bit 0-2 . . . Softscrolling ( Werte 0-7) Bit 3 . . . . .1=24 Zeilen,0=25 Zeilen
Bit 4 . . . . .0= Screen off,1= Screen on Bit 5 . . . . .0= Charmode,1= Bitmapmode Bit 6 . . . . .1= Extended Colourmode Bit 7 . . . . .8 . Bit von Reg.$ d012( Raster)
Wichtig ist es zu wissen, daß der VIC
sich jede 8 . Rasterzeile ( im Bereich des
Textes/ der Grafik), und zwar zu Beginn
jeder Cursor-Zeile, Informationen aus
dem Bildschirm-Inhalt holt um die Cursor
Zeile korrekt darzustellen. In welchen
Raster-Zeilen dies geschieht, hängt davon
ab, welche Werte das Reg.$ d011 in den
ersten 3 Bits aufweist. Und genau diese
Abhängigkeit von Scroll-Register $ d011 zum Neu-Initialisiern jeder neuen Cursor
Zeile des VIC macht die Sache so enorm
interessant. . .
Durch genaues Timing ist es nämlich
möglich, das Neu-Initialisieren einer
Zeile durch den VIC zu verzögern, indem
man den $ d011- Scrollwert gerade dann
verändert, wenn eine Cursor-Zeile z. B.
erst halb aufgebaut ist und im selben
Frame ( Rahmen =1 Rasterdurchlauf) wieder auf den ursprünglichen Wert von
zuvor zurücksetzt. Der VIC baut nämlich
eine neue Zeile immer erst dann auf, wenn die ersten 3 Bits aus Reg.$ d011 mit
den ersten 3 Bits von Reg.$ d012( Rasterzeilen- Y-Position) übereinstimmen. So
ist die Y-Position der Cursor-Zeilen- Initialisierung linear zum $ d011- Scroll-Register auf 8(0-7) Werte flexibel.
Nebenbei sei erwähnt, daß der Prozessor
dadurch in jeder 8 .( eben in dieser!) Rasterzeile um einige Taktzyklen weniger
Rechenzeit hat, da diese vom VIC " abgezwickt" werden um Werte für die Cursor-Zeilen Initialisierung und Darstellung
aus dem Bildschirm-Inhalt zu holen. Dies
berührt uns im Moment zwar wenig, ist
aber für das spätere ' Linecrunchen' von
großer Bedeutung da dort Timing auf
Zyklen genau verlangt wird.
Gut, da wir nun wissen, wie der VIC arbeitet und auf welche Weise er vorgeht, um Cursor-Zeilen ( egal ob Grafik oder
Text) darzustellen, könnte man auf die
sinnlose Idee kommen, durch Austimen mit
dem $ d012- Register ganze Cursor-Zeilen
bereits darzustellen, obwohl die Zeile
zuvor in ihrer Darstellung nicht abgeschlossen war. Das hieße, eine Zeile
sozusagen " künstlich" zu platzieren.
Es ist zwar nicht ganz so einfach, wie es
klingt, das mit dem " künstlichen Platzieren", denn es ist bei Tricks mit dem
$ d011- Register viel Erfahrung, Geduld
und vielleicht auch ein wenig Glück notwendig, doch ist dieses Grundschema der
getimtem Zeilen-Initialisierng der ( !) Baustein beim Bitmap-Scrollen und Linecrunchen.
Zuerst möchte ich das Scrolling in der
Horizontalen erklären:
Wir wissen: Der Bildschirm wird 50 mal
pro Sekunde neu aufgebaut. Ein Ganzbild
besteht aus 312 Rasterzeilen. Dabei
jagt der Elektronenstrahl jede Zeile
von links nach rechts, um die Partikel
zum Leuchten zu bringen. Nach der 312 .
Zeile wird der Strahl wieder nach links
oben gesetzt, dadurch entsteht die sog.
vertikale Austastlücke ( es gibt auch
eine horiz. Austastlücke, bedingt durch
das Zurücksetzen des Elektronenstrahls
nach links, wenn er den rechten Rand
erreicht hat) .
Um nun den VIC zu überlisten, müssen wir
einfach einen Zustand produzieren, in
welchem er eine neue Cursor-Zeile aufzubauen beginnt. Diesen Moment wählen
wir so, daß der Elektronenstrahl gerade
über den sichtbaren Bereich rast. Wenn
er nun das Kommando für den Aufbau einer
neuen Cursor-Zeile erhält, stellt er
diese sofort dar, auch wenn der Strahl
sich gerade z. B. in der Bildschirm-Mitte befindet. So produzieren wir eine " versetzte" Darstellung des gesamten Screen-Inhaltes, ab der Rasterzeile, in der wir
den VIC überlisten.
Wie weit der Inhalt nun nach rechts verschoben wird ( der Bereich, der rechts
hinausgeschoben wurde, wird übrigens und
logischerweise links, eine Zeile tiefer, wieder sichtbar), hängt von der horiz.
Position des Elektronenstrahls ab. Da
ein Prozessor-Takt (1 Mhz) genau der Zeit
entspricht, die der Strahl für die Darstellung von 8 Hires-Pixel braucht, kann
man also mit geschicktem Austimen des
Opcodes den Bildschirm-Inhalt cursorschrittweise verschieben. Das X-Soft- Scrolling erledigt ohnehin Reg.$ d016, und schon funktioniert der Trick mit dem
Horizontalen Bildschirm-" Wanken" !
Das Vertikalscrolling oder Linecrunching
funktioniert ein wenig( !) komplizierter.
Gesagt sei nur kurz, daß dabei beliebig viele Cursor-Zeilen nach oben unsichtbar
" zusammengestaucht" werden, um den Bildschirm, wie zuvor nach rechts, diesmal
nach oben zu versetzen. . .
Programmierer, für welche dieses Gebiet
absolut Neuland ist, sollten sich durch
das viele Theoretische nicht verwirren
lassen. Im Teil 2 wird der dokumentierte
Source-Code für Klarheit sorgen. . .
(hs) 16-FARBEN-SCROLLING Teil II
Im ersten Teil dieses Kurses wurde viel
Theoretisches gesagt. Um nun langsam ( !) zur Praxis zu kommen, wollen wird diesmal anhand eines Source-Codes, welchen
ich ausführlich dokumentieren und erklären werde, einen Schritt in Richtung
" Linecrunching", so wie' s wirklich
funktioniert, machen.
Der " Linecrunching-Sourcecode" als
sequentielles File, wurde nur wenig
dokumentiert. Doch sollte er für jeden, der folgendes Kapitel " durchackert" hat, leicht verständlich sein.
Um kurz zu wiederholen:
Horizontale Bildverschiebung erreichen
wir, indem wir den VIC dazu bringen, eine neue Cursor-Zeile aufzubauen, obwohl die alte noch nicht abgeschlossen wurde und der darstellende Elektronen-Strahl gerade am sichtbaren Bereich
unterwegs ist. So läßt sich durch Timing
eine X-Versetzung auf Cursor-Positionen
genau erreichen.
Vertikal dupliziert sich die Trickserei!
Und zwar simuliert man für den oberen
Screen-Bereich beliebig viel Cursor-Zeilen, dir nur eine Rasterzeile hoch
sich ( Verhältnis 1 :8) . So werden die
Zeilen " geschrumpft" und der Bildscirm-Inhalt nach oben gezogen. Was oben
fehlt kommt ( so wie beim Horizontalen
Versetzen rechts) unten wieder rein.
Gut, nun wird' s ernst. Sehn' wir uns die
Sache mit dem $ d011- Register genauer an:
lda #$1b ;Register sta $d011 ;reinitialisieren lda #$2c fl1 cmp $d012 ;auf Rasterzeile #$2c bne fl1 ldx #4
fl2 dex ; extaktes Timing bne fl2
Bis jetzt wurde nur $ d011 richtiggesetzt ( muß jeden Rasterdurchlauf reinitialisiert werden!) und auf die
entsprechende Raster-Y- Position gewartet ( hängt ja bekanntlich vom
3- Bit-Wert im $ d011- Register ab. Die
Schleife danach bringt nur genaueres
Timing, damit der Rasterstrahl in etwa
dort ist, wo wir ihn brauchen ( dieses
Timing ist noch nicht auf Zyklen
ganau; die Schwankungen liegen von 1-4 Taktzyklen) .
fl4 lda dtab,x ;$d011-Wert-Tabelle dec $d02f ;$d02f(?) erniedrigen sta $d011 ;Wert schreiben inc $d02f ;(?) wieder erhöhen nop ;Timing-nops! . . u.s.w. .
Zuerst wird der entsprechende $ d011- Wert
aus einer angelegten Tabelle ( kommt
noch!) ausgelesen. Danach folgt wieder
was typisch " C64- Mäßiges" : Bevor nun
der ausgelesene Wert ins $ d011- Reg. geschrieben wird, erniedrigen wir das
Register $ d02 f, um es danach wieder zu
erhöhen. Rein sinnlos, oder ? Doch wer
die beiden " Sinnlosigkeiten" aus dem
Code entfernt, wird sich wundern: Kein
Linecrunching ohne $ d02 f! Warum ? Wer
den C64 so lange und gut kennt wie ich, fragt so was nicht. Er wundert sich gar
nicht mal.
Danach kommt wieder Rasterzeitfüllendes
Timen. Erwähnt sei, daß ein NOP-Befehl
genau 2 Taktzyklen benötigt, wohingegen
ein BIT $ XX-Befehl 3 braucht. So läßt
sich auf Zyklen genau verzögern. Ein
entsprechendes Beispiel finden wir
später beim X-Scrollen, da wir dort
den Rasterstrahl ja an jeder möglichen X-Position austricksen werden.
.
. ...und weiter: . inx ;Pointer erhöhen up cpx #2 ;fertig ? bne fl4 fll4 lda dtab+1,x ;aus Tabelle+#1 dec $d02f ;wie gehabt sta $d011 inc $d02f nop . . .
Ab " fll4" passiert anscheinend ganau
dasselbe wie zuvor, doch: Wir lesen den
$ d011- Wert aus der Tabelle+1 . Warum ?
Folgende Rasterzeilen wird sozusagen
nur Zeit verbraucht, um die Lücke zu
füllen. Die Lückenspanne ist linear zur
Y-Versetzung. Wenn viele Zeilen " ge- staucht" werden, ist die Spanne klein - und umgekehrt. Und dadurch, daß wir
aus der Tabelle+1 lesen, passiert gar
nichts. Allerdings müssen wir in $ d011 etwas schreiben, da wir sonst mit dem
Soft-Scrolling in Y-Richtung nicht
zurechtkommen.
.
. ...und weiter: . inx ;Pointer erhöhen cpx #28 ;Zeilen-Limit ? bne fll4 ;zurück! ldx #1 fl5 dex ;wieder timen... bne fl5 lda #$59 ;Neuer Fix-Wert für sta $d011 ;$d011 ldx #$4f ;x-Reg.für Raster-Check lda #$5f ;$d011-Wert in Akku fl6 cpx $d012 ;Rasterzeile schon bne fl6 ;erreicht ? ldx #3 fl7 dex ;und wieder timen... bne fl7 sta $d011 ;jetzt in $d011!
Linecrunching ist abgeschlossen ( max.
28 Rasters!) und zwischen den gewohnten
" Austimereien" wurde der Fixwert #$59 in $ d011 geschrieben und anschließend
nochmal #$5 f. Das war die Vorbereitung
für das X-Scrolling, dem jetzt nichts
mehr im Wege steht. . .
lda #208 ;Border eng ora xsoft ;mit Xsoft verknüpft sta 53270 ;ins X-Scroll-Register lda #$0f sta $d02f ;$d02f zurücksetzen ldx #3 jumpi dex ;zum Xten mal Timen bne jumpi
Alles ist nun vorbereitet:" Softscroll-3- Bit-Byte"(0-7) verknüpft,$ d02 f
reinitialisiert ( für nächsten Durchlauf
notwendig!) und wieder Verzögerung.
Warum zwei mal ins $ d011- Reg. geschrieben
wird, ist auch ganz einfach: Durch diese
besondere Zusammensetzung der beiden
Werte und auch dem Zeitraum zwischen
den beiden, erreichen wir, daß der
Prozessor nun den nächsten Befehl auf
einer fixen Raster-X- Position durchführt. D. h. das relativ ungenaue ( auf
1-4 Zyklen genaue) Timing ist jetzt
auf 1 Taktzyklus genau. Und genau das
ist absolut notwendig für den X-Trick, für das sog. Hard-Scrolling. . .
lda #$59 ;Wert für $d011 xhard bne jumpl+0 ;variabler jump jumpl cmp #$c9 ;22 x "cmp #$c9" cmp #$c9 . . cmp #$c9 bit $ea ;versteckter "NOP" sta $d011
Im Grunde genommen sind diese 22 platz- füllend wirkenden " cmp #$ c9" wieder
Timer-Elemente. Und zwar ist der Jump-BNE- Befehl ausschlaggebend: Gesprungen
wird immer ( da #$59 ja unequal 0 ist!), und zwar soweit, wie wir in xhard+1 schreiben. Logische Werte wären 0-39, da wir eine Cursor-Auflösung von 40 Zeichen haben.
Wir wissen, daß wir eine Verzögerung von
0-39 Taktzyklen brauchen, um den Screen
an alle möglichen Position versetzen zu
können. Genau das erledigen die " CMP
#$ c9" Befehle. Wenn wir uns den Opcode
dieses Befehls in einem Monitor ansehen, merken wir, daß der Opcode des Befehls
" CMP" den Wert #$ c9 besitzt. Das heißt, wir können den BNE-Jump irgendwo in die
Liste steuern, und der Prozessor wird
immer " CMP #$ c9" entdecken, egal ob
der Wert nach dem " BNE"( xhard+1) gerade
oder ungerade ist.
Schließlich wird die " CMP #$ c9"- Liste noch mit einem " BIT #$ ea" abgeschlossen.
Erraten!#$ ea ist der Opcode-Wert für
" NOP" . Nun liest der Prozessor je nachdem, ob es eine gerade oder ungerade
Sprungadresse ist, folgende Befehls-Serien. . .
gerade: ungerade:
... ... cmp #$c9 cmp #$c9 cmp #$c9 cmp #$c9 cmp #$c9 cmp #$24 ;#$24 = Opcode bit #$ea nop für BIT
Diese Lösung scheint auf den ersten
Blick vielleicht ein wenig aufwendig
und kompliziert, doch wenn man das
Prinzip und die Problemstellung richtig
verstanden hat, so entdeckt man einen
kleinen Touch von Genialität dahinter.
Gut, auch diesmal war wieder ' ne Menge
" Stuff" dabei, der Köpfe zum Rauchen
bringen kann. Doch Assembler-Tüftler werden mit Hilfe des Source-Files
bald den Durchblick haben.
Der HAMMER und die KRONE im Teil 3: Scroll-Action pur für eigene Projekte und ein super Editor für bunte, riesengroße Scrollfields... (hs/wk) 16-FARBEN-SCROLLING Teil III
Endlich! Diesmal wollen wir das Ding mit
der $ d011- Trickserei hinter uns bringen.
Als Krönung dazu befindet sich der " Bitmap- Manager" auf der Diskette. Dieser
Editor verwaltet Grafik-Areas für die
Routine des dok. Scroll-Source- Codes der
vorigen Ausgabe. Zu Beginn eine kurze
Einführung in das Arbeiten mit diesem
Editor. . .
Mit dem " Bitmap-Manager" lassen sich
Grafik-Backgrounds in einem Format von
100 x 40 Squares gestalten. Ein Square
ist ein Feld der Größe von 2 x2 Cursors.
Insgesamt also eine Area von rund
5 x 4 Screens. Die Squares werden von
einem Grafik-Bild von 40 x 20 Chars
ausgelesen ( z. B. ein normales Koala-Pic
in der Höhe von 20 Chars), womit wir bei 200 verschiedenen Squares wären.
Zu Beginn befindet man sich im Haupt-Menu, in welchem man mit den Cursor-Tasten und Return bestimmte Funktionen
startet. Wenn wir in den Field-Editor
gelangen, gelten folgende Tasten als
funktionstüchtig:
Return,Pfeil links........ins Haupt-Menu Cursor oder Joystick.....Pointer bewegen 1-8........................Square setzen Space oder Feuer........Square #0 setzen F1/F2...................Hintergrundfarbe F7....................in den Page-Editor +,-...................Page 0-31 anwählen shift+clr home...........Area löschen(!) *...................Sprite-Block-pointer (die '*'-Funktion wird später noch genauer erläutert werden...)
Die Squares lassen sich also mit den
Tasten 1-8 setzen, abhängig von der
aktuellen Page. Um nun die Pages zu editieren, gelangen wir mit ' F7' in den
Page-Editor, welcher mit folgenden
Tasten bedient wird:
F7...................in den Field-Editor Cursor oder Joystick.....Pointer bewegen 1-8.............Square in Page schreiben +,-........................Page anwählen
So lassen sich 32 verschiedene Pages erstellen. Beim anwählen der Pages ändert
sich die Rahmenfarbe mit, das heißt, daß jede Page seine bestimmte Farbe anzeigt. Somit ist das Arbeiten im Field-Editor leichter, da in diesem das vollständige Darstellen der 8 Squares einer
Page aus technischen Gründen nicht
möglich ist. Orientierung schafft nur
die Page-Nummer rechts oben und eben
die entsprechende Rahmenfarbe.
NUN GANZ PRAKTISCH:
Wie gestalte ich mein eigenes Demo/ Game?
Zuerst mal wird gemalt. Ein Picture in
der Größe 40 x20 Cursors, welches alle
200 Squares repräsentiert. Abgespeichert
wird im Koala-Format. Nun läßt sich
dieses Bild mit dem " Bitmap-Manager" laden, wonach es in das richtige," redefined" Format gebracht wird ( der Bildschirmrand flackert kurz) .
So, nun kann' s schon mit der Field-Gestaltung losgehen. Zuerst mal die
Pages zusammenstellen. Am Besten die
Squares, die in Verbindung miteinander
stehen ( ganze Grafik-Elemente), in die
gleiche Page bringen. Jetzt zurück in
den Field-Editor und den Background
designen. . .
Hat man sich einmal an das Prinzip mit
den Pages und dem 1-8- Modus gewöhnt, läuft das Gestalten so richtig schnell
und macht Spaß. Vor Allem dann, wenn
man schon weiß, wo bestimmte Squares sind, die man z. B. öfter braucht, was
nach einer gewissen Zeit sowieso entsteht.
Gut, die Area ist abgeschlossen und wir
begeben uns wieder ins Hauptmenu. Dort
speichern wir vorsorgend gleich die
Pages und die gesamte Area ($ c000-$ cfa0) . Beim Wiederbearbeiten einfach
die Grafik, Area und Pages reinladen, und losgeht' S ( die Pages haben also nur
für den Editor Bedeutung) !
Wollen wir ernst machen und den gesamten
Background für ein eigenes Projekt verwenden, dann ist folgende Schrittfolge
anzuwenden:
Zuerst speichern wir die Grafik( Squares) als " redefined Grafics" ab ( Bereich von
$2000 bis $3 f3 f) . Bevor wir nun die
Routine starten ( ich rede vom Sourcecode
der letzten Ausgabe von Kurs Teil 2), laden wir die Area ($ c000) normal und die " redefined Grafic"( gespeichert ab
$2000) nach $ e000 in den Speicher. Wenn
wir jetzt die Routine starten, haben
wir nicht viel Unterschied zum Editor, da die Routine ( vom Sourcecode) dem
Editor ähnlich ist. Aber wir befinden
uns schon mal im Assembler und können
die ganze Sache entscheidend beeinflussen. . .
. . . ab hier ist jeder Programmierer auf
sich selbst angewiesen. Man sollte sich
ein wenig in den Code einarbeiten und
herumexperimentieren. Ein wenig Tips
und Hilfe möchte ich hier aber noch
auflisten:
1 . Im schwarzen, oberen Bereich ( linecrunching) werden 7 Sprites ( Xund
Yexpanded) dargestellt. Die Koordinaten, Blöcke und Farben werden im
Programm initialisiert. Durch gezieltes Ändern ist diese Gestaltung
selbst frei einzurichten ( die Y- Koordinaten müssen allerdings gleichbleiben; Timing!) .
2 . Das Programm arbeitet in einem Hauptund einem Interrupt-Teil. Der Hauptteil wartet immer wieder darauf, ob
neue Zeilen aufgebaut werden müssen.
Im Interrupt werden die Tasten abgefragt, die Softscreenmoving-Routine
aufgerufen sowie ins Linecrunching
verzeigt. Wird nun im Hauptprogramm
gerade eine Cursor-Zeile aufgebaut, wird der Vorgang meist, denn er dauert
eine gewisse Zeit, vom Interrupt
unterbrochen.
Also: Routinen, die alle 1/50 Sekunde
stattfinden müssen, werden einfach in
den Interrupt eingabaut. Dabei ist zu
beachten, daß nicht zuviel Rasterzeit
verbraucht wird, da das Linecrunching
zur bestimmten Rasterzeile unbedingt
stattfinden muß. Wenn die freie Zeit
zuwenig ist, einfach den Raster-IRQ- Einsatz um ein paar Zeilen verfrühen,
und sozusagen vom Hauptoder Aufbau-Programm etwas abzwicken.
3 . Im Sourcecode befindet sich eine
Routine mit dem Namen " SET PIECE" .
Wenn ein Square auf den Bildschirm
gestzt wird, muß sie aufgerufen
werden. Die " set piece"- Routine ist
sehr praktisch: Sie prüft, ob das
Square, welches gesetzt wird, im
sichtbaren Bereich liegt oder nicht.
Wenn ja, wird es in die angezeigte, aktuelle Bitmap geschrieben. Wenn
nicht, dann nur als Byte in der Area
festgehalten, d. h. wenn dorthin
gescrollt wird, wird jenes Square
angezeigt, da' s ja in der Area verankert wurde ( in die Area wird das
Square also auf jeden Fall geschrieben) .
4 . Gescrollt wird, indem man die gewünschten Werte direkt in den Opcode
der Screenmoving-Routine schreibt.
Die Labels heißen " mo1"-" mo4" . Also
um nach oben zu scrollen, den Soft-Wert nach " mo1+1" schreiben und die
Routine Screenmoving aufrufen. Die
Werte können von 0-8 liegen und werden nach jedem Aufruf automatisch
gelöscht.
Zum Schluß möchte ich noch auf einen
kleinen " Hindernis"- Umstand eingehen, welchen ich oben zu Beginn dieses
Kurs-Teiles angesprochen habe. Es geht
um den Sprite-Blockpointer- Bereich, welcher sich im Editor durch die "*"- Taste und im Sourcecode mit der Return-Taste einund ausschalten läßt ( diese
8 nebeneinanderliegenden ( phew!) Cursor-Bytes " flashen" dann) .
Bekanntlich belegen die Blockpointer für
die Sprites die letzten 8 Bytes des
aktuellen Text-Bildschirms. In unserem
Beispiel liegt dieser ab $4400, die
Blockpointer also ab $47 f8 . Gewöhnlich ist dieser Bereich frei verfügbar, da
der Text-Bildschirm nur einen Bereich
von 1000 Bytes braucht ( also bis $47 d7) .
Doch durch das Linecrunching kommt
dieser sonst unsichtbare Bereich auch
zum Vorschein, da der VIC bei der Darstellung des Screens dort fortsetzt, wo
er aufgehört hat ( also bei $47 d8, und
erst nach $47 ff springt er zu $4400 zurück) .
Dies ist auch der Grund, warum beim
Linecrunchen der Bereich auch in X-Richtung versetzt auftaucht, nämlich
genau um diese 24 Bytes/ Cursors!
Um mit diesem Umstand keine " Troubles" zu bekommen, läßt man jene Cursors
einfach leer oder vom Screen-Colour- RAM
unbeeinflußt ( nur $ d800- Farb-RAM!) .
Wenn man auf Sprites über der Scroll-Area verzichtet, stellt sich selbiges
Problem ohnehin nicht.
Mein letzter und vielleicht wichtigster
Tip lautet:
Durchbeißen! Durchbeißen! Durchbeißen!
. . . und NIIIIIEEMALS aufgeben!
(Hannes Sommer,'93)