Scroller Word-Bender Diesen Scroller habe ich zur Abwechslung mal fr die hohe Aufl”sung geschrieben. Sogar in manchen Megademos gibt es ein Screen fr die hohe Aufl”sung ! Den bisher besten Monochrom-Screen habe ich in der Overdrive- Demo gefunden. Ein weiterer sw-Screen ist in der Demo von Galtan 6. Der Zeichensatz Ich wollte erst irgendein Signum-Zeichensatz verwenden. Aber leider sehen die Zeichen etwas eint”nig aus. Dann fiel mir ein, daž man die Farbzeichens„tze nach sw konvertieren kann. Nach einigen Versuchen habe ich einen guten Font gefunden (viele Fonts sehen nach den Konvertieren nicht mehr gut aus). Konvertiert habe ich mit 'Guck'. Nun haben wir einen sw- Zeichensatz in DOO-Format. Leider ist das DOO-Format fr den Scroller nicht besonders gut geeignet, da die Zeichen nicht gerade in der richtigen Reihenfolge (ASCII) vorliegen. Also: Basic starten und schnell ein Programm schreiben, daž den Font in die richtige Reihenfolge umkopiert. Der Zeichensatz ( Datei: SILENTS.FNT ) hat folgende Struktur: jedes Zeichen ist 7 Byte ( = 56 Pixel ) breit und hat 80 Zeilen. Ein Zeichen braucht demzufolge 560 Bytes. Ich habe 64 Zeichen vorgesehen, daraus ergibt sich, das SILENTS.FNT 35840 Bytes grož ist. Diese 64 Zeichen entsprechen der ASCII-Tabelle ab $20 (Space) bis $5f. Die nicht vorhandenen Zeichen werden von den Basic-Programm durch Space ersetzt. Der Scroller Ich werde erstmal die Grundlagen des Scrollers erkl„ren, der Bender wird im nexten Kapitel erkl„rt. Um einen ruckelfreies Scrolling zu erreichen, muž nach jedem Bildaufbau der Text komplett ein Stck nach links verschoben werden. W„hrend des Bildaufbaus sollte man jedoch keine Daten in den Bildspeicher schreiben, um Flimmereffekte zu vermeiden. Daraus folgt, daž man nur w„hrend des Vertikalblanks auf den Bildschirm schreiben darf. Hier nun das Timing fr den Colormodus ( 50 Hz ! ) und Monochrommodus: Colormodus Monochrommodus L„nge einer Zeile: 64 us 28 us Anzahl der Zeilen: 312 500 davon sichtbar: 200 400 unsichtbare Zeilen (Blank) 112 100 L„nge des Vertikallanks 7,158 ms 2,8 ms Bildwiederholfrequenz 50 Hz 71 Hz = 20 ms = 14 ms Der Vertikalblank ist aber viel zu kurz, die Zeit wrde vielleicht nur fr einige kleine Sprites reichen. Muž man nun doch die Flimmereffekte hinnehmen ? Nein, es gibt einen anderen Weg. Man muž mit 2 Bildschirmseiten arbeiten. W„hrend die 1. Bildschirmseite gerade auf den Monitor ausgegeben wird, kann auf der 2. Bilschirmseite das n„chste Bild aufgebaut werden, ohne das es auf dem Bildschirm zu irgendwelchen St”rungen kommt. Im Vertikalblank schaltet man dann auf den 2. Bildschirm um, und das n„chste Bild wird in der 1. Bildschirmseite aufgebaut. Bein n„chsten Vertikalblank wird wieder die 1. Bild schirmseite aktiviert .....u.s.w.u.s.f. Jetzt haben wir viel mehr Zeit, n„mlich genau die Zeit zwischen 2 Vertikalblanks ( Colormodus 20 ms, Monochrommodus 14 ms ). Und da es im ST ein Interrupt gibt, der bei jedem Vertikalblank ausgefhrt wird, ist das Bildschirmseiten-Umschalten kein Problem. Als erstes muž die Adresse der beiden Bildschirmseiten festgelegt werden: move.l #s1,d0 ;Screen 1 move.l #s2,d1 ;Screen 2 clr.b d0 ;Low-Byte muž 0 sein clr.b d1 move.l d0,screen1 ;Adresse Bildschirmseite 1 move.l d1,screen2 ;Adresse Bildschirmseite 2 W„hrend des Vertikalblanks wird die vbl-Routine aufgerufen, und die Bildschirmseiten werden vertauscht. vbl: clr.w vbl_flag move.l d0,-(sp) move.l screen1,d0 move.l screen2,screen1 ;Screens vertauschen move.l d0,screen2 lsr.w #8,d0 move.l d0,$ffff8200.w ;Video-Base, die andere ;Bildschirmseite setzen move.l (sp)+,d0 rte bss screen1: ds.l 1 screen2: ds.l 1 vbl_flag: ds.w 1 ds.b 256 s1: ds.b 32000 s2: ds.b 32000 Wo steht nun die Adresse der sichtbaren Bildschirmseite, im 'screen1' oder 'screen2' ? Die vbl-Routine l„dt die Adresse aus 'screen1' nach d0 und schreibt diese nach 'screen2' und in die Video-Base-Register. Also steht im 'screen2' die sichtbare Bildschirmseite !? Denkste ! Die Anfangsadresse des Bildschirmspeichers wird am Beginn des Vertikalblanks in den Videocounter bernommen. Wenn die vbl-Routine aufgerufen wird, ist aber Vertikal-blank schon eine Weile aktiv ( Interruptreaktionszeit ! ). Deswegen steht im 'screen2' die Adresse fr das unsichtbare Bild und im 'screen1' demzufolge die Adresse der sichtbaren Bildschirmseite ! ( Die Videobase-Adresse wird also um 1 vbl verz”gert wirksam ) Jetzt sind wir die Flimmer- und Zeitprobleme los. Wir warten einfach bis zu einen vbl ( 'vbl_flag' abfragen ) und haben nun fast 14 ms (oder 20 ms ) Zeit, ein neues Bild aufzubauen. Welche Bildschirm-seite neu aufgebaut werden muž, steht im 'screen2'. wait_vbl: tst.w vbl_flag ;auf vbl warten bne.s wait_vbl move.w #1,vbl_flag move.l screen2,a0 ;a0 zeigt auf den unsichtbaren Scre ;hier k”nnen alle Routinen stehen, ;die fr den Bildaufbau notwendig sind ;max 14 ms ! ( 20 ms ) bra wait_vbl Fast alle Demos oder Spiele arbeiten nach diesen 2-Seiten Prinzip. (Oder mit noch mehr Seiten, aber das ist ein Thema fr sich ) Wer die Flimmereffekte sehen will, kann in der vbl-Routine die Labels 'screen1' und 'screen2' untereinander vertauschen. Jetzt muž man sich berlegen, wie schnell der Scroller eigentlich scrollen soll. Da die Bildwiederholfrequenz fest vorgegeben ist, kann die Geschwindigkeit nur ber die Anzahl der Pixel, die der Scroller pro Bildwechsel nach links verschoben wird, festgelegt werden. Ich habe 8 Pixel ( = 1 Byte ) gew„hlt. Wenn die Anzahl der Pixel ein Vielfaches von 8 ist, werden die Scrollroutinen besonders einfach und effektiv. Aber im Colormodus werden viele Scroller mit 4 Pixel pro vbl bewegt, da 8 Pixel pro vbl etwas schnell ist. Das erfordert aber mehr Aufwand ( shift-Befehle oder Fonts vorshiften ). So, wer jetzt ber ein 8-Pixel-Verschieberoutine nachdenkt, denkt falsch ! Warum ? Da war noch die Sache mit den 2 Bildschirmseiten ! Dazu ein Beispiel: 'PAC' wird ber ein 10 Zeichen breiten 'Bildschirm' gescrollt. Bei allen ungeraden vbl's wir die Bildschirmseite 1 dargestellt, bei geraden vbl's die Seite 2. 'PAC' muž also um 2 Zeichen verschoben werden, da jede Seite erst wieder nach 2 vbl's dargestellt wird. vbl Seite 0123456789 1 1 | P| 2 2 | PA| 3 1 | PAC| 4 2 | PAC | 5 1 | PAC | 6 2 | PAC | 7 1 | PAC | 8 2 | PAC | 9 1 | PAC | 10 2 |PAC | 11 1 |AC | 12 2 |C | Wir brauchen also eine 16-Pixel-Verschieberoutine. Dazu teilen wird den Bildschirm in 40 senkrechte 16 Pixel breite Spalten ein ( 40 * 16 = 640 ). Die 16 Pixel lassen sich mit einen move.w Befehl kopieren. Wir fangen bei Spalte 1 an und kopieren 80 ( Zeichenh”he ) untereinanderliegenden Words nach Spalte 0. Dann folgen 80 Words von Spalte 2 nach Spalte 1 ...... und zuletzt die 80 Words von Spalte 39 nach Spalte 38. Jetzt muž die Spalte 39 mit den neuen Fontdaten versorgt werden. Die h”herwertigen 8 Bits besorgen wir uns von der anderen Bildschirmseite. Die niederwertigen 8 Bits werden aus dem Zeichensatz geholt. Zum besseren Verst„ndnis ein Beispiel: (Der 'Bildschirm' ist hier 144 Pixel breit, ein 'X' entspricht 8 Pixel, 144 / 16 = 9 16-Pixel-Spalten) | | die zur Zeit sichtbare Bildschirmseite | XXXXX XXXXXX XX| | X X X X X | | X X X X X | | XXXXX XXXXXX X | | X X X X | | X X X XX| ^ | | die unsichtbare Seite | XXXXX XXXXXX X| wird um 16 Pixel nach rechts verschoben | X X X X X| | X X X X X| | XXXXX XXXXXX X| | X X X X| | X X X X| | | durch die Verschiebung ist links eine leere | XXXXX XXXXXX X | 16-Pixel-Spalte entstanden | X X X X X | | X X X X X | | XXXXX XXXXXX X | | X X X X | | X X X X | | | | XXXXX XXXXXX XX | die h”herwertigen 8 Pixel werden von den nieder- | X X X X X | wertigen 8 Pixeln aus der letzten 16-Pixel-Spalte | X X X X X | des sichtbaren Bildes geholt (^) | XXXXX XXXXXX X | | X X X X | | X X X XX | | | die niederwerigen 8 Pixel werden von Zeichensatz | XXXXX XXXXXX XXX| geholt, jetzt kann diese Seite dargestellt werden | X X X X X | und die andere Seite kann gescrollt werden | X X X X X | | XXXXX XXXXXX X | | X X X X | | X X X XXX| | | Der Bender Bis jetzt haben wir einen einfachen Scroller, der immer auf der gleichen H”he scrollt. Um einen Bender zu realisieren, muž bei dem Umkopieren der Spalten ein y-Offset bercksichtigt werden. Dieser y-Offset wir aus einer Tabelle 'pos' geholt. Die Tabelle habe ich mit einen Basic-Programm erstellt. Die Werte sind immer ein Vielfaches von 80, da eine Bildzeile in Monochrommodus 80 Bytes lang ist. Die Werte werden mit einer Sinusfunktion ermittelt. Wichtig ist, daž am Ende der Tabelle wieder die gleichen Werte wie am Anfang sind. Dies ist notwendig, weil die Tabelle irgendwann mal zu Ende ist. Dann wird die Tabelle wieder vom Anfang an ausgelesen. Wenn die Endwerte und die Anfangswerte nicht bereinstimmen, springt der Scroller pl”tzlich in eine andere Position. Pro Bildaufbau werden 40 Werte aus der Tabelle ben”tigt. Wenn aber z.B. nach 30 Werten die Tabelle zu Ende ist, mžten die n„chsten 10 Werte ab Tabellenanfang gelesen werden. Um das Problem zu l”sen, wird einfach die Tabelle zweimal direkt hintereinander im Speicher gehalten. Die 10 Werte befinden sich dann gleich nach dem Ende der 1. Tabelle ( Anfang der 2. Tabelle ). Beim Umkopieren wird mit Hilfe der Tabelle die y-Position der Quell-Spalte und Ziel-Spalte bestimmt. Dabei werden 'clr-lines' Zeilen ber und unter der Zielspalte gel”scht. Warum das notwendig ist, kann man feststellen in dem 'clr_lines' z.B. auf 1 gesetzt wird. Je gr”žer die Frequenz ist, um so mehr Zeilen mssen gel”scht werden. Eigentlich br„uchte man nur 'clr_lines' Zeilen ber !oder! unter der Zielspalte zu l”schen, aber ich hatte keine Lust mehr, dafr einen Algorithmus auszudenken. Der Sound Damit der Scroller nicht so langweilig wird, habe ich noch ein Musikstck eingebunden. Das Thema 'Soundchipmusik' ist aber schon wieder eine andere Story ( ich will auch endlich mit diesen Artikel fertig werden :-) ) Nur soviel: Das Soundprogramm muž alle 20 ms aufgerufen werden. Im Colormodus ( 50 Hz ) wird dafr der VBL-Interrupt benutzt. Im sw-Modus wrde der Sound etwas zu schnell abgespielt ( 71 Hz ). Deswegen habe ich fr den Sound Timer B verwendet und diesen natrlich auf 50 Hz = 20 ms programmiert. PS: Als Extra gibt es noch einen Source-Code fr einen Byte-Bender-Distorter (fr Colormodus). Der Code ist von den Intro der Toxic-Mac 1. Dieser Scroller verbraucht viel ( fast 20 ms ) Rechenzeit und kann nur 1-Bitplane Fonts scrollen. Dafr ist er einfach und unaufwendig programmiert. written by bITmASTER