Sokoban-Zeichensatz
Umgang mit Zeichensätzen
Umgang mit Zeichensätzen

Neue Zeichensätze erstellt man am besten mit einem Zeichensatz-Editor (zum Beispiel mit dem C64 Studio), das ist bequemer und man kann bei vielen zu ändernden Zeichen leichter den Überblick bewahren. Der Erfolg vieler C64-Spiele beruht auf speziellen Zeichensätzen, nachvollziehbar z.B. beim Spiel "Uridium", wie es auf dieser Seite sehr schön beschrieben steht.

Für manche Zwecke reicht es aber, nur einige wenige Zeichen zu verändern. So etwas kann man dann ganz leicht auch mit TSB und den Befehlen MEM und DESIGN erledigen. Hier ein Beispiel, in dem nur ein einziges verändertes Zeichen verwendet wird, um einen bestimmten Effekt zu erzeugen:

Color Combiner

Das Programm (auf der TSB-Disk enthalten) zeigt, wie man zwei Farben so miteinander kombinieren kann, dass im Auge des Betrachters scheinbar eine neue Farbe entsteht. In diesem Bild vermischen sich rot und blau zu einem eindeutigen Violett. Das liegt daran, dass auf der großen violetten Fläche die beiden ausgewählten Farben (2, rot, und 6, blau) durch das Muster des zur Anzeige verwendeten Zeichens ganz dicht beieinander liegen.

Hier der entsprechende Definitionsabschnitt im Code des Programms "colorcombi.dmo":


1020 design 2,$e800+8*96
1021 @b.b.b.b.
1022 @.b.b.b.b
1023 @b.b.b.b.
1024 @.b.b.b.b
1025 @b.b.b.b.
1026 @.b.b.b.b
1027 @b.b.b.b.
1028 @.b.b.b.b
Das Zeichen mit dem Bildschirm-Code 96 (ein nicht
von der Tastatur aus erreichbares Leerzeichen)
erhält hiermit ein ganz enges Schachbrettmuster
mit Ein-Pixel-Abstand.

Die Zeilennummerierung wie sie hier zu sehen ist,
ist empfehlenswert: Die @-Definitionszeilen gehen
von xxx1 bis xxx8, weshalb man nicht mal eben
eine Zeile vergisst oder falsch einordnet.

Die Startadresse $E800 ist die Adresse des Groß-
Klein-Zeichensatzes (CSET 1).

<nach oben>

Kommen wir zu TSB-spezifischeren Tipps: Es gibt den Multicolor-Modus auch für Textzeichen, worauf die meisten der oben angesprochenen Spiele beruhen. Mit dem Text-Multi-Modus teilt man seinen Zeichensatz in zwei unabhängige Abteilungen: normal gefärbte Chars (zwei Farben pro Zeichen, eine davon generell für den ganzen Screen) und vierfarbige Chars (drei Farben davon für den ganzen Screen, eine individuell, ganz ähnlich wie bei den Sprites). Die individuelle Farbe wird aber im folgenden "Rasterbar"-Beispiel auch erst einmal nur da gesetzt, wo eine Ausgabe überhaupt erfolgt (verändert das Color-Ram ab $D800 nur an den Stellen, wo die Ausgabe stattfindet).

Für Multicolor-Zeichen brauchen wir in TSB nur drei weitere Befehle neben DESIGN. Für die Aktivierung des Multi-Modus den Befehl MULTI ON und für die Einfärbung der Zeichen BCKGNDS f0,f1,f2,x sowie COLOUR,f3. Folgende Zuordnung tritt nach MULTI inkraft:

Farbe : Bitmap-Muster : Befehl  : Hinweis
      :               :
f0    :      %00      : BCKGNDS : $D021, Hintergrundfarbe (plus 128 als Flag für MULTI)
f1    :      %01      :         : $D022, generelle Farbe 1
f2    :      %10      :         : $D023, generelle Farbe 2
f3    :      %11      : COLOUR  : dies ist die "individuelle" Farbe (aus dem Color-Ram).

Die individuelle Farbe beeinflusst schließlich den Multi-Modus. Ist sie in den Farben 0 bis 7 kodiert, werden die zugehörigen Zeichen im normalen Text-Zweifarbmodus angezeigt, die verschiedenen Graus, Braun und die hellen Farben bleiben dann außen vor. Liegt ihr Wert zwischen 8 und 15, "verwandeln" sich die Zeichen in vielfarbige Chars, allerdings beim Bitmuster %11 auch nur in den Farben von 0 bis 7 (die Farben werden dargestellt wie tatsächliche Farbe = Farbwert AND 7). Die mit BCKGNDS gewählten Farben für die genannten Bitmuster %01 und %10 werden aktiviert.

Rasterbar

Beispiel. Dieser wie ein Rasterbar aussehende Streifen wird mit den folgenden Befehlen erzeugt (Ausgabe in Z. 25 und 30):

1100 proc rasterbar

1120 design 3,$e000+8*27:" key [
1121 @....
1122 @bbbb
1123 @bbbb
1124 @....
1125 @cccc
1126 @cccc
1127 @....
1128 @dddd

1140 design 3,$e000+8*29:" key ]
1141 @dddd
1142 @....
1143 @cccc
1144 @cccc
1145 @....
1146 @bbbb
1147 @bbbb
1148 @....

1185 end proc

10 mem: cset 0: bckgnds 128+12,9,8,x: colour,10
15 multi on
20 rasterbar
25 print at(4,0) dup("[",40);
30 print dup("]",40): colour,0
35 do null
40 end

In PROC rasterbar werden die beiden Zeichen "[" und "]" umdefiniert zu vierfarbigen Multicolor-Zeichen. In der Aufrufroutine (Z. 10) lautet die Color-Ram-Farbe hier f3=10. Das ist mehr als 7, also tritt der Multicolor-Modus in Kraft und es wird auf dem Bildschirm an allen Stellen mit dem Buchstaben D in den Definitionszeilen rot angezeigt (10 AND 7 = 2, rot). Der Buchstabe B erhält f1 zugewiesen (9, braun) und Buchstabe C ist f2 (8, orange). Die Punkte in der Definition erhalten die generelle Hintergrundfarbe f0, hier 12 (mittelgrau). Ändert man aber f3 auf einen Wert kleiner als 8, z.B. zu 6, ist der ganze Zauber vorbei und alle gesetzten Pixel sind (in dem Fall) nur noch blau (Farbe 6).

<nach oben>


Solange es um nur wenige Zeichen geht, ist gegen das Vorgehen per MEM und DESIGN nichts einzuwenden, denn vom so wertvollen freien Basic-Speicher geht dann nicht viel verloren.

Sokoban-Zeichensatz

Sollten es aber mehr Zeichen werden (und damit kommen wir zum Eingangsbild dieses Tipps-Abschnitts, dem Sokoban-Zeichensatz), dann fressen die DESIGN-Zeilen den Basic-Speicher auf und eine Zeichensatzdefinition auf diesem Wege lohnt sich nicht mehr.

Also besser einen Zeichenssatzeditor verwenden? Nicht unbedingt. Man ändert nur die Vorbereitungen zu so einem Programm wie dem "Sokoban". Es reicht ja, wenn im eigentlichen Programm die geänderten Zeichen irgendwie zur Verfügung gestellt werden können. Geht das?

Ja, da haben wir gleich mehrere Möglichkeiten. Vorausgesetzt, uns stehen die geänderten Zeichen als Datei zur Verfügung, können wir sie auch zu unserem Programm hinzuladen.

 

1. Möglichkeit: (Laden mit Zieladress-Angabe)

LOAD "Zeichen",dr,0,Zieladresse

Der Wert von DR (DR für "Drivenummer") ist egal und wird von USE bestimmt. Der Umfang eines Datensatzes ist bei LOAD beliebig.

 

2. Möglichkeit: (SCRLD mit Adress-Patch)

POKE $a5d4,$e8: POKE $a5d0,$ec: SCRLD 1,dr,2,"zeichen": POKE $a5d4,$04: POKE $a5d0,$d8

Dateien, die von dieser Möglichkeit Gebrauch machen, müssen sowohl beim Speichern als auch beim Laden die gleichen POKEs verwenden. Die beiden POKEs patchen die TSB-Befehle SCRLD und SCRSV, um beliebige Quell- bzw. Zieladressen für zweimal 1 KB große Datensätze verwenden zu können (8 Pages, ergibt 9 Blöcke auf Disk). Hier werden durch die POKEs die Adressen $E800 und $EC00 angepeilt (und nach dem Laden wieder auf ihre Defaultwerte zurückgesetzt, $0400 und $D800). Die Zeichendaten werden also an die TSB-MEM-Position des Groß-Klein-Zeichensatzes geladen (der durch CSET 1 eingestellt wird).

 

3. Möglichkeit: (SCRLD mit Sekundäradresse 3 für fortlaufende Daten)

POKE $a579,8: SCRLD 1,dr,3,"zeichen": POKE $a579,32 (hier an Standard-Zieladresse $E000)

In diesem Fall wirkt sich der POKE nur auf die Anzahl der einzulesenden Bytes aus. Der Wert 8 lädt acht Pages, das sind 2 KB, also der Umfang z.B. des Groß-Klein-Zeichensatzes (9 Blöcke auf Disk). Im Unterschied zu Möglichkeit 2 müssen die Daten hier nicht extra mit SCRSV vorbereitet werden, man kann direkt beliebige bereits vorhandene Zeichensätze benutzen. Der Standardwert an Speicherstelle $a579 ist 32.

 

4. Möglichkeit: (SCRLD mit Parametern über SCRLD DEF)

SCRLD DEF $CC,4,1,3: SCRLD 1,u,3,"name": SCRLD RESTORE
(Zieladresse hier: $CC00, Länge: 4 Pages, in fortlaufenden Bytes: 3, der Wert von U ist egal)

Mit dieser Vorgehensweise ist man weitaus am flexibelsten. Man übergibt dem SCRLD-Befehl via SCRLD DEF weitere Anweisungen dazu, wohin und im welchem Umfang eine Datei in den Speicher geholt werden soll. Genaueres im nächsten Abschnitt über den "Umgang mit Bildern" (ganz unten).

 

Da der Umfang der Zeichensatzdaten beim Sokoban-Projekt nicht so riesig war, haben wir dort die erste Alternative eingesetzt, um den geänderten Zeichensatz einzubinden.

90 if display=$0400 then mem: cset 1:
   print "wait...":
   load "sokoban.chr",0,0,$ec00

DISPLAY liefert die aktuelle Adressse des Textbildschirms. Lautet sie anders als $0400 (dezimal 1024), ist der veränderte Zeichensatz bereits geladen und aktiviert und der Rest der Zeile braucht nicht noch einmal ausgeführt zu werden. Beim ersten Mal allerdings kopiert TSB mit MEM den ROM- (Doppel-) Zeichensatz nach Position $E000 (Länge: 4 KB von $E000 bis $EFFF), wo er jetzt frei verändert werden kann. Der LOAD-Befehl lädt hier die veränderten 26 Zeichen - das sind 208 Bytes - nach $EC00, das liegt im Bereich des Groß-Klein-Zeichensatzes an der Position der invertierten Kleinbuchstaben. Im Sokoban-Programm werden also die invertierten Kleinbuchstaben dazu verwendet, den Spielplan und die Spielfiguren darzustellen (siehe Bild).

Erstellt wurden die Zeichen dennoch mit TSB-Befehlen, wie oben beschrieben, allerdings in einem Extraprogramm, das nur dazu da war, die Zeichen zu definieren und abzuspeichern. Sie wurden dabei nicht an ihre eigentliche Position gelegt ($E000), sondern an eine zum Abspeichern mit PRINT# leichter zugängliche Stelle, nach $6000. Das geht ganz einfach, indem man beim DESIGN-Befehl die Basisadresse entsprechend anpasst: DESIGN 2,$6000+8*Bildschirm-Code.

Hier als Beispiel der Code für das letzte veränderte Zeichen darin: das invertierte "y", Bildschirm-Code 153.Die Basisadresse des Groß-Klein-Zeichensatzes liegt in diesem Fall bei $6800, wir überspringen aber die ersten 128 Zeichen und zählen erst ab $6C00, wo die invertierten Kleinbuchstaben beginnen. Der Offset von dort aus beträgt 25, 25 ist der Bildschirmcode des Zeichens "y", ein Plus von 128 (zusammen 153) macht es invers.

900 B=$6C00
999 :
1250 DESIGN 2,B+8*25
1251 @........
1252 @.BB..BB.
1253 @.B.BBBB.
1254 @.BB..BB.
1255 @.BBBB.B.
1256 @.BBBB.B.
1257 @.B...BB.
1258 @........
1259 :

Das ganze Ergebnis der Definitionszeilen landete hier also an der Adresse $6C00 und reichte bei 26 Zeichen bis $6CCF (208 Bytes, 1 Diskblock). Mit einer kleinen FOR..NEXT-Schleife waren die Bytes schnell abgespeichert. In "Sokoban" reichte dann die oben wiedergegebene Zeile 90 zum Einbinden der neuen Zeichen. Hier noch einmal deren Aussehen:

Sokoban-Chars

So ein Vorgehen kann man natürlich auch auf einen ganzen Zeichensatz ausdehnen und dann damit solche atemberaubenden Szenen wie die folgende aus dem Spiel "Mayhem in Monsterland" präsentieren.

<nach oben>

Den Zeichensatz von "Mayhem in Monsterland" haben wir in den Beispieldateien zum PC-Programm CharPad gefunden. Alles andere in unserem Bild hat TSB erledigt:

Mayhem in Monsterland

Im Folgenden der dazugehörige Programmabschnitt, wobei der Zeichensatz und der Bildschirm- und Farbram-Inhalt in den Zeilen 1130 und 1140 (mit der oben genannten Methode 2) nachgeladen werden. Im Color-Ram-Bereich liegen hier tatsächlich individuelle Farben, die den Multi-Modus je nach Bedarf aktivieren (die Wolken und Sterne sind z.B. im Standard-Textmodus). Das Programm befindet sich auf der TSB-Disk unter dem Namen "mayhem.dmo". Hier ein Link auf den Ausschnitt aus dem TSB-Programm, das die Vorlage für beiden Nachladedateien (".fnt" und ".scr") erzeugt hat. Eingebunden werden sie so:

1100 proc mayhem
1110 mem: cset 1: bckgnds $83,10,9,x
1120 multi on
1125 poke $a5d4,$e8:poke $a5d0,$ec
1130 scrld 1,dr,2,"mayhem3a90.fnt"
1135 poke $a5d4,$cc:poke $a5d0,$d8
1140 scrld 1,dr,2,"mayhem.scr"
1145 poke $a5d4,$04
1150 do null
1160 nrm
1170 end proc



POKE $a5d4,$68: POKE $a5d0,$6c: SCRSV 1,dr,2,"mayhem.fnt,p,w": POKE $a5d4,4: POKE $a5d0,$d8

POKE $a5d4,$cc: SCRSV 1,dr,2,"mayhem.scr,p,w": POKE $a5d4,4

In diesem Fall haben wir also den Zeichensatz mit einem nach Möglichkeit 2 gepatchten SCRSV abgespeichert. Der Bildschirminhalt wurde schließlich mit einem ebenso gepatchten SCRSV gesichert. Diese beiden Zeilen reichten dafür aus. Die erste für den Zeichensatz (lag hier an $6800) und die zweite für den Bildschirminhalt (an $cc00) wie im Bild zu sehen.

Man kann also in TSB Zeichensätze sehr flexibel handhaben.

<nach oben>