Magic Disk 64

home to index to html: KURS-16-FARBEN-SCROLLING.html
          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 beein-
druckend wurde es  durch  die  Vertikal-
Bewegung, durch das sog.'Line-crunching'
was  soviel  wie  'Zeilen-Komprimierung'
bedeutet.                               
In Spielen setzte  sich  der  Trick  nur
sehr träge durch. In den beiden  "Storm-
lord"-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"  ver-
wendet 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  er-
wähnt wurde, wollen wir nun zum  Theore-
tischen 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  umfang-
reiche 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  ledig-
lich  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  1Mhz  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  dar-
gestellt; 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 Text-und  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 (Raster-
zeilen-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  "abge-
zwickt" 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  ar-
beitet 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  abge-
schlossen 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  Plat-
zieren", denn es ist bei Tricks mit  dem
$d011-Register  viel  Erfahrung,  Geduld
und vielleicht auch ein wenig Glück not-
wendig, doch ist dieses Grundschema  der
getimtem Zeilen-Initialisierng  der  (!)
Baustein beim Bitmap-Scrollen und  Line-
crunchen.                               
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  auf-
zubauen 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  "ver-
setzte" Darstellung des gesamten Screen-
Inhaltes, ab der Rasterzeile, in der wir
den VIC überlisten.                     
Wie weit der Inhalt nun nach rechts ver-
schoben 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 (1Mhz) genau der Zeit
entspricht, die der Strahl für die  Dar-
stellung von 8 Hires-Pixel braucht, kann
man also mit  geschicktem  Austimen  des
Opcodes  den  Bildschirm-Inhalt  cursor-
schrittweise  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 Bild-
schirm, 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  dies-
mal anhand eines  Source-Codes,  welchen
ich ausführlich  dokumentieren  und  er-
klä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,  ob-
wohl 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   richtig-
gesetzt (muß jeden  Rasterdurchlauf  re-
initialisiert  werden!)  und   auf   die
entsprechende   Raster-Y-Position    ge-
wartet   (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.  ge-
schrieben  wird,  erniedrigen  wir   das
Register $d02f, 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 $d02f!  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 #$5f. 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,   $d02f
re-initialisiert (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   durch-
fü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  nach-
dem, 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 "Bit-
map-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 2x2  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 er-
stellen. Beim anwählen der Pages  ändert
sich die Rahmen-farbe  mit,  das  heißt,
daß jede Page seine bestimmte Farbe  an-
zeigt. Somit ist das Arbeiten im  Field-
Editor leichter, da in diesem das  voll-
stä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 40x20  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,  "re-
defined" Format gebracht wird (der Bild-
schirmrand 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  ent-
steht.                                  
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  ver-
wenden, dann ist  folgende  Schrittfolge
anzuwenden:                             
Zuerst speichern wir die Grafik(Squares)
als "redefined Grafics" ab (Bereich  von
$2000 bis  $3f3f).  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  beeinflus-
sen...                                  
...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  (line-
   crunching) werden  7  Sprites  (X-und
   Y-expanded) dargestellt. Die  Koordi-
   naten,Blöcke  und  Farben  werden  im
   Programm   initialisiert.  Durch  ge-
   zieltes Ändern ist  diese  Gestaltung
   selbst   frei  einzurichten  (die  Y-
   Koordinaten müssen allerdings gleich-
   bleiben; Timing!).                   
 2.Das Programm arbeitet in einem Haupt-
   und einem Interrupt-Teil. Der  Haupt-
   teil wartet immer wieder  darauf,  ob
   neue Zeilen aufgebaut werden  müssen.
   Im Interrupt werden die Tasten  abge-
   fragt,  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 Haupt-oder  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  ver-
   ankert wurde (in die  Area  wird  das
   Square also auf jeden Fall  geschrie-
   ben).                                
 4.Gescrollt wird,  indem  man  die  ge-
   wü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  wer-
   den  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 ein-und  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  $47f8.  Gewöhnlich
ist dieser Bereich  frei  verfügbar,  da
der Text-Bildschirm  nur  einen  Bereich
von 1000 Bytes braucht (also bis $47d7).
Doch  durch  das   Linecrunching   kommt
dieser sonst  unsichtbare  Bereich  auch
zum Vorschein, da der VIC bei  der  Dar-
stellung des Screens dort fortsetzt,  wo
er aufgehört hat (also  bei  $47d8,  und
erst nach $47ff springt er zu $4400  zu-
rü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)



Valid HTML 4.0 Transitional Valid CSS!