3. Verwendung des Block-Grafik-Modus (Block-Font-Modus)

^

3.1 Übersicht über die Verwendung von Block-Grafiken

Aus Sicht des Computers sind Buchstaben einfach nur kleine Bilder, Grafiken, die einem bestimmten ASCII-Zeichen zugeordnet sind. Im Blockgrafik-Modus schreibt R-BASIC mit dem PRINT-Befehl anstelle der "systemdefinierten" Buchstaben kleine selbst definierte Grafiken mit bis zu 64x64 Pixeln. Diese Grafiken stehen in einem von R-BASIC verwalteten Speicherbereich, den man "Zeichengenerator" nennt. Damit können Sie eigene Zeichensätze definieren oder sehr einfach grafische Elemente auf den Bildschirm ausgeben, die aus einzelnen "Blöcken" (z.B. 8x14 Pixeln) bestehen. Diese Technik wird schon seit der Anfangszeit der Computer verwendet und "Block-Grafik" genannt. Mit dem Befehl FontSetBlock aktivieren Sie den Blockgrafik-Modus. Falls Sie FontSetBlock erstmalig im Programm verwenden oder eine andere als die aktuell gesetzte Zeichengröße verwenden wird der Zeichengenerator-Speicher gelöscht, d.h. alle Grafikzeichen sind nutzbar, aber leer.

R-BASIC unterstützt monochrome (einfarbig, mono = Eins, chromos = Farbe) und farbige Blockgrafikzeichen (256 Farben). Monochrome Grafikzeichen werden in der aktuellen Vordergrund/Hintergrund Farbkombination gezeichnet, wobei der Hinterfrund auch transparent sein kann (die Hintergrundfarbe ist dann auf den speziellen Wert BG_TRANSPARENT gesetzt).

Farbige Blockgrafikzeichen werden in ihren eigenen Farben gezeichnet, nur der Farbindex 255 wird durch die aktuelle Hintergundfarbe ersetzt (bzw. transparent gezeichnet).

Der einfachste Weg um Blockgrafik-Zeichen zu verwenden ist die Benutzung des Blockgrafik-Editors, den Sie im Menü "Extras"-"Tools" finden. Der Blockgrafik-Editor erlaubt das intuitive Erstellen von Grafikzeichen und schreibt sie in eine Datei (*.RBF), die vom Befehl BlockLoad in den Zeichengenerator gelesen werden kann.

Zur Verwaltung der Blockgrafik-Dateien stehen weiterhin die Befehle BlockSave, BlockSize, BlockInfo zur Verfügung.

Sie haben einen direkten Zugriff auf den Zeichengenerator durch die Verwendung der Befehle BlockPoke (Schreiben eines einzelnen Bytes in den Zeichengenerator) BlockPeek (Lesen eines einzelnen Bytes aus dem Zeichengenerator) BlockREAD (Lesen eines oder mehrerer Zeichen aus DATA-Zeilen. Die DATA-Werte werden in den Zeichengenerator kopiert).

BlockSelect schaltet zwischen zwei Zeichengeneratoren um.

Wichtig! Die Print-Anweisung erstellt eine Kopie des Zeichens (aus dem Zeichengenerator) auf dem Bildschirm. Eine nachträgliche Änderung des Zeichengenerators wirkt sich daher nicht auf den Bildschirm aus, wird aber bei der nächsten Print-Anweisung berücksichtigt.

^

3.2 Interner Aufbau eines Zeichens im Blockgrafik Modus

Je nach dem, ob die Blockgrafik monochrome oder farbige Zeichen enthält unterscheidet sich die interen Struktur des Zeichens etwas.

Farbige Zeichen

In diesem Modus besteht jedes Zeichen aus einer kleinen Farbgrafik mit 256 Farben aus der Systempalette. Eigene Paletten werden nicht unterstützt. Für jedes Pixel wird ein Byte benötigt. Das heißt, ein Zeichen der Größe 8x10 Pixel benötigt 80 Bytes. Die Zählung der Bytes beginnt immer bei Null und erfolgt zeilenweise, d.h. zuerst von links nach rechts. Soll ein Pixel transparent (oder in in der aktuellen Hintergrundfarbe) dargestellt werden so muss der Farbindex (Farbwert) 255 verwendet werden. Zu diesem Farbwert gehört die Farbe Weiß. Weiß hat aber auch den Index 16, so dass durch diese Wahl keine Einschränkungen entstehen. Beispiel:

Das im Bild oben dargestellte Zeichen der Größe 8x4 Pixel wird durch folgende Bytes beschrieben (Rot: 12, Blau: 9, transparent: 255):

255, 12, 12, 255, 255, 9, 9, 255
255, 12, 12, 255, 9, 9, 9, 9
255, 12, 12, 255, 9, 9, 9, 9
255, 12, 12, 255, 255, 9, 9, 255

Monochrome Zeichen

In diesem Modus besteht jedes Zeichen aus einer kleinen Monochrom-Grafik. Dabei kann jedes Pixel die Vordergrund- oder die Hintergrundfarbe annehmen. Für ein 8x8 Zeichen benötigt man 8 Byte, für ein 16x16 Zeichen bereits 32 Byte. Die Zählung der Bytes beginnt immer bei Null und erfolgt zeilenweise, d.h. zuerst von links nach rechts.

Den zu einem Byte gehörenden Zahlenwert erhält man, wenn man die gesetzten Bits (in der oberen Darstellung grau) entsprechend folgender Zuordnung addiert:

Für die ersten beiden Zeilen (Byte 0 bis 3) im Bild oben rechts (16x16 Pixel) stellt sich das so dar:

woraus sich ergibt:

Byte 0: 0
Byte 1: 16 + 8 + 4 = 28
Byte 2: 8 + 4 = 12
Byte 3: 16
Ganz anlog kann man sich die Werte für das 8x8 Grafikzeichen oben links ermitteln. Es setzt sich aus den folgenden Werten 8 zusammen:

0, 124, 68, 68, 207, 68, 124, 0

oder gleichbedeutend hexadezimal:

&h00, &h7C, &h44, &h44, &hCF, &h44, &h7C, &h00

Beispiel:

Der folgende Code schaltet in den Blockgrafik-Modus. Mini8x8.rbf ist eine Block-Font-Datei, die gemeinsam mit R-BASIC installiert wurde. Dann liest es das oben dargestellte 8x8 Zeichen in den Zeichengenerator auf die Position des Zeichens 'b'. Der Befehl PRINT "b" schreibt dann das Grafikzeichen auf den Schirm.

LABEL ZG
DATA 0, 124, 68, 68, 207, 68, 124, 0

FontSetBlock 8, 8
BlockLoad  "mini8x8.rbf" , 0, 256
Restore ZG
BlockREAD ASC("b"), 1
Color 7, 0                       ' Grau auf Schwarz
Print "aabbbb"                   ' 
Print INK(RED); "aabbcc"         ' 
Print COLOR(WHITE, RED); "bb"    ' 

^

3.3 Aufrufen des Blockgrafik Modus

FontSetBlock

Die Anweisung FontSetBlock versetzt R-BASIC in den Blockgrafik-Modus. Dabei wird intern die Systemvariable printFont mit den passenden Werten belegt. Falls Sie FontSetBlock erstmalig im Programm verwenden oder eine andere als die aktuell gesetzte Zeichengröße verwenden wird der Zeichengenerator-Speicher gelöscht, d.h. alle Grafikzeichen sind leer. Der Parameter "colored" bestimmt, ob die Grafikzeichen in diesem Fall als monochrom (einfarbig, default) oder als farbig (256 Farben) behandelt werden sollen.
Syntax: FontSetBlock sizex, sizey [ , colored]

sizex, sizey: Größe der Block-Grafiken in Pixel.
Erlaubte Werte liegen zwischen 2 und 64 (jeweils einschließlich).

colored: Ungeladenen Zeichensatz als monochrom (FALSE, default)
oder als farbig (256 Farben) behandeln.

Beispiel:
FontSetBlock 16, 24
Hinweise:
  • Im Block-Grafik-Modus stehen keine Textstile zur Verfügung.

  • Sie können das Flagbit TS_DONT_EXEC_CONTROLS im Feld printFont.style verwenden, um die Steuerzeichen mit den ASCII-Codes unter 32 als druckbare Zeichen auszugeben, statt sie "auszuführen".

  • Ein intuitives Erstellen von Grafiksymbolen ist mit dem Block-Grafik-Editor möglich, den Sie im Menü "Extras"-"Tools" finden.

  • FontSetBlock stellt automatisch das maximale Textfenster ein, der Cursor wird nach links oben gesetzt (siehe Window-Befehl). Sie können das Fenster anschließend mit dem WINDOW-Befehl ändern und/oder den Cursor mit LOCATE positionieren.

  • Verwenden Sie bei Bedarf den Befehl PRINT atXY(x,y); "Text...", um die Textausgaben pixelgenau zu positionieren.

  • Falls Sie FontSetBlock erstmalig im Programm verwenden wird der Zeichengenerator-Speicher gelöscht, d.h. alle Grafikzeichen sind leer. Das passiert auch, wenn die Größe der Zeichen (Parameter sizex oder sizey) seit dem letzten FontSetBlock geändert wird.

    Im Umkehrschluss bedeutet das, das im folgenden Code beim zweiten FontSetBlock(8, 8) der Zeichensatz nicht neu geladen wird, sondern der mit BlockLoad geladenen Zeichensatz wieder verwendet wird. Der Parameter "colored" wird in diesem Fall (d.h. wenn die Größe nicht geändert wird) ignoriert.

FontSetBlock (8, 8)             ' Klammern sind erlaubt
BlockLoad "MYFONT.RBF", 0, 256  ' farbiger Zeichensatz erlaubt
<.. diverse Befehle ..>
FontSetFixed (FID_UNIVERSITY, 18)
<.. diverse Befehle ..>
FontSetBlock (8, 8)             ' wieder "MYFONT" einstellen
                                ' auch wenn MYFONT ein
                                ' farbiger Zeichensatz ist
  • Das Laden eines Zeichensatzes aus einer Datei (Befehl BlockLoad) überschreibt die durch den Parameter colored gesetzte Einstellung.

Hinweise für fortgeschrittene Programmierer

  • Prinzipiell ist es möglich, die printFont-Variable direkt zu modifizieren. Die meisten Felder haben im Blockgrafik-Modus jedoch keine Bedeutung.

  • Fortgeschrittene Programmierer finden eventuell die Syntax
    <variable> = FontSetBlock(sizex, sizey)
    hilfreich. <variable> ist eine Variable vom Typ PrintFontStruct, die dann statt der Systemvariablen printFont belegt wird.

^

3.4 Direkter Zeichengenerator-Zugriff

Die im Blockgrafik-Modus ausgegebenen Grafiken stehen in einem von R-BASIC verwalteten Speicherbereich, den man "Zeichengenerator" nennt. Mit den folgenden Befehlen haben Sie direkten Zugriff auf den Zeichengenerator. Zum Verständnis der Arbeitsweise der Befehle finden Sie im Abschnitt 3.2 Informationen zum internen Aufbau eines Zeichens im Blockgrafik-Modus, d.h. der Organisation des Zeichengenerators.

BlockPoke

Schreibt ein einzelnes Byte in den Zeichengenerator. Die Änderungen werden beim nächsten "Print" des entsprechenden Zeichens berücksichtigt.
Syntax: BlockPoke zeichen, byteNr, wert

zeichen: ASCII-Code des zu ändernden Zeichens

byteNr: zu änderndes Byte. Zulässige Werte:
z.B. bei 8 x 8 - Zeichen: 0 .. 7
bei 16 x 16 - Zeichen: 0 .. 32
bei 32 x 32 - Zeichen: 0 .. 128

Hinweis: In x-Richtung gibt es evt. nicht genutzte Bits!
z.B. bei 20 x 30 - Zeichen 4 Bits --> byteNr ist von 0 .. 90 erlaubt


Beispiel:
! Das Zeichen 192 soll als schwarzer Block erscheinen
! 16 x 16 - Zeichen vorausgesetzt
FOR n = 0 TO 31
  BlockPoke 192, n , 255
NEXT
Print Chr$(192)

BlockPeek

Liest ein einzelnes Byte aus dem Zeichengenerator.
Syntax: <numVar> = BlockPeek ( zeichen, byteNr )

zeichen: ASCII-Code des zu lesenden Zeichens

byteNr: zu lesendes Byte.
Erlaubte Werte: siehe BlockPoke

Beispiel:
! Lesen der Daten des Zeichens 192
! 8 x 8 - Zeichen vorausgesetzt
DIM n, x as REAL
  FOR n = 0 TO 7
    x = BlockPeek ( 192, n )
    Print x; Hex$(x)
  NEXT

BlockREAD

Liest ein oder mehrere ganze Zeichen aus DATA-Zeilen in den Zeichengenerator. Die Änderungen werden beim nächsten "Print" des entsprechenden Zeichens berücksichtigt.
Syntax: BlockREAD zeichen, anzahl

zeichen: ASCII-Code des ersten zu ändernden Zeichens

anzahl: Anzahl der zu lesenden Zeichen.
Pro Zeichen werden so viele Werte gelesen, wie entsprechend der gesetzten Größe nötig sind.

Beispiel:
! Statt des Zeichens "b" soll ein Muster erscheinen, 
! das in einer DATA-Zeile definiert ist.
LABEL ZG
DATA 0, 124, 68, 68, 207, 68, 124, 0

Restore ZG
FontSetBlock 8, 8
BlockLoad "mini8x8.rbf", 0, 256
BlockREAD ASC("b"), 1
Print "abbc"            ! es erscheint ac

BlockSelect

R-BASIC verwaltet zwei Zeichengeneratoren. Damit ist ein schnelles Umschalten zwischen zwei Grafikzeichensätzen oder zwischen Text- und Grafikzeichen im Blockgrafik-Modus möglich. Standardmäßig ist Zeichengenerator 0 aktiv.
Syntax: BlockSelect ( nr )

nr: Nummer des Zeichengenerators, erlaubte Werte: 0 und 1


Hinweise:
  • Alle Block~ Befehle wirken immer auf den aktuellen Zeichengenerator.

  • Wird erstmalig in den alternativen Zeichengenerator gewechselt, so wird der aktuelle Zeichensatz dorthin kopiert.

  • Wird mit FontSetBlock() eine andere Größe eingestellt (Parameter sizex oder sizey), so wird auf Zeichensatz 0 gewechselt und der alternative Zeichengenerator zurückgesetzt. Im Umkehrschluss bedeutet das, bei einem FontSetBlock() mit der gleichen Größe der Zeichensatz nicht verändert wird, auch wenn zwischenzeitlich z.B. ein FontSetFixed erfolgte.

  • Es ist zulässig, dass in einem der Zeichengenaratoren ein monochromer Zeichensatz geladen ist, im anderen ein farbiger.

^

3.5 Zugriff auf RBF-Dateien

Der einfachste Weg um Blockgrafik-Zeichen zu verwenden, ist die Benutzung des Blockgrafik-Editors, den Sie im Menü "Extras"-"Tools" finden. Der Blockgrafik-Editor erlaubt das intuitive Erstellen von Grafikzeichen und schreibt sie in eine Datei (*.RBF). In diesem Abschnitt finden Sie die Befehle, die mit diesen R-BASIC-Blockgrafik-Font-Dateien arbeiten. Informationen zur Organisation des Zeichengenerators finden Sie im Abschnitt 3.2.

BlockLoad

Lädt ein oder mehrere Zeichen aus einer RBF-Datei in den Zeichengenerator. Die RBF-Datei befindet sich üblicherweise im Ordner "USERDATA\R-BASIC\Font". Sie können jedoch mit dem Parameter "local" festlegen, dass sie im aktuellen Ordner zu finden ist.
Syntax: BlockLoad fileName$, firstChar, count [, local]

fileName$: Name der Blockgrafikdatei, z.B. "MYFONT.RBF"

firstChar: ASCII-Code des ersten zu lesenden Zeichens

count: Anzahl der zu lesenden Zeichen.
Es muss gelten: firstChar + count <= 256

local: optional: TRUE oder FALSE (default: FALSE)
Suchen der Blockgrafikdatei im Ordner "USERDATA\R-BASIC\Font" (local = FALSE, default-Einstellung) oder im aktuellen Ordner (local = TRUE).

BlockLoad ignoriert die von FontSetBlock vorgegebene Farbtiefe und benutzt den Wert entsprechend der RBF-Datei. Insbesondere ist es zulässig in den einen Zeichengenerator einen monochromen Zeichensatz und in den anderen Zeichengenerator einen farbigen Zeichensatz zu laden, solange die Zeichengröße übereinstimmt. Das Mischen von monochromen und farbigen Zeichen im gleichen Zeichensatz ist nicht möglich.

Fehlerbehandlung:

  • Enthält die Datei keinen passenden Zeichensatz oder tritt ein anderer Fehler auf (z.B. Datei nicht gefunden), so wird der Zeichengenerator nicht geändert.

  • Die globale Variable fileError wird belegt, im Erfolgsfall mit Null, sonst mit einer Fehlernummer. Ist die Datei keine gültige RBF-Datei so wird fileError auf den Wert -12 (INVALID_FONT_FILE) gesetzt, stimmt die Größe der Grafikzeichen in der Datei nicht mir der aktuell eingestellten Größe überein, so wird fileError auf den Wert -13 (FONT_SIZE_MISMATCH) gesetzt.
Beispiel:
! Lesen der oberen 128 Zeichen aus einer Datei im Ordner "USERDATA\R-BASIC\Font"
BlockLoad "MYFONT.RBF", 128, 128
! Lesen der Zeichen a-f aus einer Datei im aktuellen Ordner
BlockLoad "NEWFONT.RBF",  ASC("a"), 6, TRUE

BlockSave

Speichert einen Zeichensatz in eine RBF-Datei. Existiert die Datei bereits, wird sie ohne Meldung überschrieben. Welche der ASCII-Zeichen in die Datei geschrieben werden hängt vom Parameter "saveBits" ab.
Syntax: BlockSave fileName$ , local, saveBits

fileName$: Name der Blockgrafikdatei, z.B. "MYFONT.RBF"

local: TRUE oder FALSE
Datei ins aktuelle Verzeichnis (TRUE) oder nach "USERDATA\R-BASIC\Font" (FALSE) schreiben.

saveBits: 16 Bit Wert, der bestimmt, welche Zeichen in die Datei zu schreiben sind.
Jedes Bit steht für einen Block von 16 Zeichen. Siehe Tabelle unten.

Fehlerbehandlung:
  • Die globale Variable fileError wird belegt, im Erfolgsfall mit Null, sonst mit einer Fehlernummer (z.B. Datei in Benutzung).

Verwendung des Parameters saveBits:

RBF-Dateien enthalten meist nicht für jeden ASCII-Code ein Grafikzeichen. Der Parameter saveBit legt jeweils für eine Gruppe von 16 ASCII-Codes fest, ob sie in die Datei geschrieben werden sollen oder nicht. Bit 0 steht dabei für die Codes 0 bis 15, Bit 1 für 16 bis 31 usw. Die folgenden Tabelle enthält die entsprechenden Werte für die einzelnen Gruppen. Den Wert für SaveBits erhält man, indem man die zu den entsprechenden Bits gehörenden Werte (rot markiert) addiert.

Tabelle

Tabelle

BlockSize

Liest die Größe der Grafikzeichen aus einer Datei. Der Rückgabewert enthält sowohl die Höhe als auch die Breite und berechnet sich zu 256 * breite + höhe.

Ermittlung der Höhe / Breite aus dem Rückgabewert x:

   breite = ShR(x,8) AND 255 oder :  breite = INT ( x / 256)
   höhe = x AND 255                  höhe = x - 256 * breite

Syntax: <numVar> = BlockSize ( fileName$ [, local] )

fileName$: Name der Blockgrafikdatei, z.B. "MYFONT.RBF"

local: optional: TRUE oder FALSE (default: FALSE)
Datei im aktuellen Verzeichnis (TRUE) oder in "USERDATA\R-BASIC\Font" (FALSE, default) suchen.

Fehlerbehandlung:
  • Die globale Variable fileError wird belegt, im Erfolgsfall mit Null, sonst mit einer Fehlernummer (z.B. Datei nicht gefunden). Konnte die Datei gefunden werden, ist aber keine gültige RBF-Datei, so wird fileError auf den Wert -12 (INVALID_FONT_FILE) gesetzt.

  • Im Fehlerfall (z.B. Datei nicht gefunden oder keine gültige RBF-Datei) liefert die Funktion den Wert 0 zurück.

BlockInfo

RBF-Dateien enthalten für jedes Zeichen die Information, ob es "belegt" ist oder nicht. BlockInfo liest diese Information für ein Zeichen aus (Rückgabewerte TRUE bzw. FALSE) . Zeichen die "nicht belegt" sind existieren trotzdem (können also mit BlockLoad gelesen werden), enthalten aber i.a. keine Daten. Beim Print wirken sie daher wie ein Leerzeichen.
Syntax: <numVar> = BlockInfo ( fileName$, zeichen [, local] )

Parameter: zeichen: ASCII-Codes des Zeichens.

Restliche Parameter: siehe BlockSize

Fehlerbehandlung: siehe BlockSize


^

Weiter...