Unterthema: Listing SCHMAL.BAS
Unterthema: Listing SchmalPrint1
Unterthema: Listing SchmalPrint2
Unterthema: Listing SchmalPrint3
Es gibt nämlich eine Reihe von Einsatzgebieten, in denen die herkömmlichen Textzeichen zu groß (insbesondere zu breit) sind - zum Beispiel, wenn es bei der Beschriftung angezeigter Kurvenskalen oder Skizzen eng wird oder viel Text etwa auf einer Seitenvorschau angezeigt werden soll.
Hier kommt die Routine `SchmalPrint´ zum Einsatz, die bei Bedarf einfach anstelle von PRINT verwendet wird. Extrem schmale Zeichen eines speziellen Zeichensatzes ermöglichen die Anzeige von bis zu 160 Zeichen pro Zeile auf EGA/VGA- und bis zu 180 Zeichen auf Hercules-Bildschirmen. Jedem Zeichen steht ein Raster von acht Punkten Höhe und vier Punkten Breite zur Verfügung. Der neue Font enthält sämtliche ASCII-Zeichen von 32 bis 255, inklusive Sonder- und Grafikzeichen.
Nebenbei werden in der Schmalschrift-Anzeigeroutine einige interessante Programmiertechniken vorgestellt. Unter anderem wird demonstriert, welch unterschiedliche Ausführungsgeschwindigkeiten die Wahl eines bestimmten Algorithmus zur Folge haben kann. Da die Routinen keine besonderen Interna der Microsoft-BASIC-Compiler verwenden, läßt sich das Programm auch ohne größere Hürden auf Entwicklungssysteme anderer Anbieter portieren.
Die Zeichenmatrix zeigt den Buchstaben `A´ des Schmalschrift-Zeichensatzes in `Großaufnahme´. Hier wird der Aufbau deutlich: Jedes Zeichen besteht aus vier Spalten mit je acht Punkten, die für BASIC in einem Datenfeld abgelegt werden müssen. Normale Zeichen belegen drei, Semigrafik-Zeichen alle vier Spalten. Acht Punkte - das läßt bereits ahnen, daß sich im Zeichensatz zu deren Unterbringung ein Byte anbietet.
Da die Elemente von BASICs kleinstem Datentyp Integer aus zwei Bytes bestehen, wir aber nur ein Byte benötigen, `verschwenden´ wir jedesmal ein Byte. Ohne Platzvergeudung kommt man jedoch zurecht, wenn man für jede Achter-Punktreihe ein Byte eines Strings verwendet. Diesem Zweck dient im vorgestellten Programm die Variable Font$: Je vier Bytes enthalten das Bitmuster eines Zeichens. Für 224 Zeichen werden daher 896 Bytes benötigt.
Beim Start des Programms werden daher zunächst die DATA-Zeilen gelesen und die darin enthaltenen Hex-Bytes in ASCII-Codes umgewandelt; diese werden dann an der entsprechenden Stelle im String `Font$´ eingesetzt. Den Zeiger dafür stellt der mittlere Parameter des MID$-Befehls dar, der grundsätzlich zur Positionsangabe innerhalb des behandelten Strings dient. Anstelle der Voreinstellung der String-Variablen auf die erforderliche Länge und der anschließenden Zeichen-Zuweisung mittels MID$ hätte man den String innerhalb der Schleife auch mit Hilfe einer Befehlszeile wie FONT$ = FONT$ + NaechstesZeichen$ `wachsen´ lassen können. Da in diesem Fall jedoch für die hinzukommenden Zeichen BASIC-intern laufend neuer Platz durch Verschieben anderer Daten geschaffen werden muß, ist die erste Methode schneller.
Befindet sich der Zeichensatz in der String-Variablen `Font$´, kommt die Zeichen-Anzeigeroutine zum Zuge. Das Prinzip ist einfach: Je nach ASCII-Zeichen wird ein Offset (Abstand) in den String ermittelt, das heißt jene Position, ab der die zu diesem Zeichen gehörigen Bytes zu finden sind. Da dies stets vier Bytes sind, ergibt sich der Offset als ASCII-Code mal vier minus 32 (der Font beginnt bei ASCII-Code 32, da es sich bei den Codes darunter um Steuerzeichen handelt).
Abschließend müssen dann die vier Bytes so auf den Bildschirm gebracht werden, daß sie das Zeichen anzeigen. Um zu prüfen, wie dies am schnellsten geschehen kann, können drei verschiedene Möglichkeiten verwendet werden. Die erste Methode ist wohl die naheliegendste - da BASIC die Möglichkeit zur Potenzierung bietet, wird sie nach folgendem Prinzip in einer Schleife zum bitweisen Auslesen eines jeden Bytes genutzt:
FOR Bit = 0 TO 7 IF Byte AND 2 ^ Bit THEN PSET ... NEXT BitAnhand eines jeden Bits wird dann - je nachdem, ob es den Wert 1 oder 0 hat - ein Punkt in der Vordergrund- oder Hintergrundfarbe geplottet. Die Bildschirmposition eines jeden Punktes ergibt sich aus den angegebenen x- und y-Koordinaten sowie der Position des Punktes innerhalb des gerade behandelten Bytes. Die Routine wurde als SUB-Unterprogramm ausgelegt, die folgendermaßen aufgerufen wird:
CALL SchmalPrint (Zeichen, Y, X)Statt Zeichen wird der Routine (zu finden im zweiten Listing) der ASCII-Code des anzuzeigenden Zeichens übergeben. Im Gegensatz zu BASICs PRINT-Befehl spart man sich hier die vorherige Koordinatenangabe mit LOCATE durch die direkte Angabe beim Aufruf. Nach Deklaration der Routine läßt sie sich sogar ohne CALL-Anweisung aufrufen und wirkt somit wie ein selbstentwickelter neuer BASIC-Befehl. Die Syntax beim Aufruf hieße dann:
SchmalPrint Zeichen, Y, XDaß jedoch die Potenz-Berechnung unter BASIC recht langsam ist, zeigt sich in der Print-Routine, die nach der ersten Methode arbeitet: Die niedrige Anzeigegeschwindigkeit macht sie nahezu unbrauchbar. Grund hierfür ist, daß BASIC bei der Abarbeitung von Potenzen - auch bei Integerwerten - auf Fließkomma-Routinen der Sprachbibliothek zurückgreifen muß.
In diesem Zusammenhang sei darauf hingewiesen, daß wohl die wichtigste Maßnahme zur Optimierung eines BASIC-Programms darin besteht, dem Listing ein DEFINT A-Z voranzustellen, um so weit wie möglich mit Integer-Variablen zu arbeiten. Auf Long-Integers sollte man erst dann zurückgreifen, wenn der Wertebereich der Integerzahlen nicht ausreicht. QuickBASIC muß nämlich bei den Grundrechenarten - im Gegensatz zu den Integerwerten - bei Operationen mit einfacher oder doppelter Genauigkeit spezielle Runtime-Routinen für Fließkommaberechnung verwenden.
IF Byte AND 128 THEN PSET ... IF Byte AND 64 THEN PSET ... ...Was auf den ersten Blick wie schlechter Programmierstil aussieht (`Hat denn dieser Mensch noch nichts von Schleifen gehört?´), erweist sich in der Praxis als drastische Verbesserung der Ausführungsgeschwindigkeit: Die Routine arbeitet rund 18mal schneller als das Programm der ersten Methode. Die Syntax zu dieser Routine (zu finden im dritten Programmlisting) lautet gleich wie die der ersten.
LINE (x1, y1) - (x2, y2), Farbe, , StrukturDie Parameter `x1, y1´ und `x2, y2´ geben Start- und Endpunkt der von LINE zu zeichnenden Linie an. `Farbe´ bestimmt die Farbe der Punkte, aus denen sich die Linie zusammensetzt. Beim optionalen (nur bei Bedarf zu verwendenden) Parameter `Struktur´ handelt es sich um einen 16-Bit-Wert, mit dessen Bitmuster sich die Struktur der Linie bestimmen läßt.
Der Hauptzweck des letzten Parameters liegt in der Möglichkeit, punktierte, gestrichelte und strichpunktierte Linien zeichnen zu können, zum Beispiel zur Unterscheidung verschiedener Kurven in Diagrammen. Wir wollen ihn nun jedoch dazu `mißbrauchen´, die Punktreihen unserer Zeichensatz-Bytes auszugeben, um uns das Auflösen der Bytes und das Umsetzen in PSET-Befehle zu ersparen:
LINE (X + Spalte, Y )-(X + Spalte, Y + 7), Farbe, , StrukturDie Bildschirmposition jeder Linie ergibt sich aus den angegebenen x- und y-Koordinaten zuzüglich der Punktposition innerhalb des gerade behandelten Bytes (Spalte). Die komplette Routine finden Sie im dritten Listing. Die Aufruf-Syntax ist wiederum dieselbe wie bei den Unterprogrammen der Methoden Nummer 1 und 2.
Bei allen drei Anzeige-Unterprogrammen lassen sich sowohl die Vorder- als auch die Hintergrundfarbe der angezeigten Schmalschrift-Zeichen einstellen (FrbVG und FrbHG); durch Vertauschen dieser Werte läßt sich die Schrift negativ darstellen (Anmerkungen in den Listings beachten). Auch Zeilen- und Zeichenabstand sind frei wählbar. Die x-/y-Koordinaten sind zeichenorientiert; sie beziehen sich auf die Zeichen- und Zeilenabstände, die Sie mit X1 und Y1 eingestellt haben (bei Bedarf lassen sich die Routinen mit wenig Aufwand auf punktweise Positionierung umschreiben).
Um eine möglichst schnelle Anzeige zu erzielen, werden diese Parameter - genau wie der Zeichensatz-String - nicht als CALL-Parameter an die Anzeigeroutinen übergeben (was zudem den Stack belasten würde), sondern als SHARED-Variable deklariert. Hiermit stehen die Inhalte der betroffenen Variablen auch den Unterprogrammen zur Verfügung.
Außer der in den drei Varianten vorgestellten Routine SchmalPrint zur Anzeige eines Zeichens wurde mit `SPrintString´ auch ein Unterprogramm zur Ausgabe von ganzen Strings vorgesehen. Die Syntax dafür lautet:
CALL SPrintString(Text$, Y, X)In Text$ wird der anzuzeigende String angegeben. Da SPrintString zur Anzeige das Unterprogramm SchmalPrint benutzt, werden alle ASCII-Zeichen ab 32 (Leerzeichen) berücksichtigt. Y und X bestimmen die Bildschirmkoordinate des ersten Zeichens. Die Angabe des Zeichen- und Zeilenabstands sowie der Vorder- und Hintergrundfarben geschieht wie bei SchmalPrint. Hier ein Aufruf-Beispiel:
Y1 = 8 ´Schmalschrift-Zeilenabstand X1 = 4 ´Schmalschrift-Zeichenabstand FrbHG = 15 ´Farbe der nicht gesetzten Pixel FrbVG = 0 ´Farbe der gesetzten Pixel X = 100 : Y = 20 ´Position des ersten Zeichens CALL SPrintString(" Weiter mit beliebiger Taste... ", Y, X)
Zu den Beispielen im Hauptprogramm:
Alle im ersten Listing enthaltenen Beispiele lassen sich wahlweise mit den Grafikmodi von EGA, VGA, CGA oder Hercules betreiben; die Grafikstufen-Einstellung erfolgt wie gewohnt mit SCREEN. Es ist lediglich auf die mit der jeweiligen Karte verwendbaren Farben und die maximale Auflösung der gewählten Grafikstufe zu achten. Während zum Beispiel mit EGA (SCREEN 9) und kleinstem Zeichenabstand bis zu 160 Zeichen in eine Zeile passen, lassen sich bei Hercules (SCREEN 3) bis zu 180 Zeichen darin unterbringen.
Beispiel 1 sorgt für eine formatierte Anzeige aller ASCII-Zeichen von 32 bis 255. Beispiel 2 demonstriert, wie sich mit Hilfe der Variablen X1 und Y2 die Zeichen- und Zeilenabstände variieren lassen. Soll Blockgrafik angezeigt werden, ist der kleinstmögliche Zeichenabstand (X1 = 4) zu verwenden.
Beispiel 3 ist eine kleine Uhrzeitanzeige, die im Grunde nichts weiter macht, als TIME$ mittels SPrintString auf dem Bildschirm anzuzeigen. Die Programmschleife zur Aktualisierung der Anzeige wird durchlaufen, bis irgendeine Taste gedrückt wird. Hier wird übrigens ganz gezielt LOOP UNTIL LEN(INKEY$) verwendet. Gegenüber ebenfalls zulässigen Befehlen wie LOOP WHILE INKEY$ = "" kommt die LEN-Abfrage auf Leerstring-Bedingung im kompilierten Programm mit weniger Bytes aus.
Mit kleinem Aufwand läßt sich auch eine Textdatei lesen und in Schmalschrift auf dem Bildschirm anzeigen. Prinzipiell geht man dabei wie folgt vor:
LinkerRand = 5 OPEN TextDatei$ FOR INPUT AS 1 WHILE NOT EOF(1) LINE INPUT #1, Text$ SPrintString Text$, y, LinkerRand y = y + 1 WEND CLOSE #1Umfaßt eine Textdatei mehr Zeilen, als auf den Bildschirm passen, muß die Anzeige portionsweise geschehen; ein Rollen der Anzeige (Scrolling) ist noch nicht vorgesehen. Erfolgt die Anzeige in einem Bildschirmausschnitt, läßt sich das Textfenster mit Hilfe des LINE-Befehls unter Angabe des optionalen Parameters BF (gefüllte Box) einfärben und löschen; alternativ läßt sich dies auch mit PAINT bewerkstelligen.
Wie schon die drei im Vergleich vorgestellten Anzeige-Methoden zeigen, gibt es meist mehrere Wege, ein Problem zu lösen, von denen sich einer als der am besten geeignete herausstellt. Mit Sicherheit gibt es im vorgestellten Programm weitere Ansatzpunkte, die Anzeigetechnik zu optimieren und ihre Möglichkeiten zu erweitern. (se)
1 ´ *********************************************** 2 ´ * SCHMAL.BAS: Schmalschrift-Anzeige für BASIC * 3 ´ * * 4 ´ * (c) c't, Harald Zoschke * 5 ´ *********************************************** 6 7 DEFINT A-Z 8 9 DECLARE SUB SPrintString (Text$, Y, X) 10 DECLARE FUNCTION Hex2Dez (H$) 11 DIM SHARED Font$, X1, Y1, FrbHG, FrbVG 12 13 ´*** Laden des Zeichensatzes in Font$ 14 ´*** (vor Benutzung der Schmalschrift einmal aufrufen) 15 16 Font$ = SPACE$(900) 17 18 RESTORE FontData 19 FOR i = 0 TO 44 20 READ HexZeile$ 21 FOR j = 1 TO 20 22 MID$(Font$,i*20+j,1) = CHR$(Hex2Dez(MID$(HexZeile$,(j-1)*3+1,2))) 23 NEXT j 24 NEXT i 25 26 ´*** Verwendung der Schmalschrift (Beispiele) 27 28 SCREEN 9 ´EGA 640 x 480 (zum Beispiel) 29 ´ SCREEN 3 ´Hercules (zuvor MSHERC.COM bzw. QBHERC.COM laden!) 30 CLS 31 32 ´*** Beispiel 1: 33 34 LOCATE 1, 3: PRINT "Alle ASCII-Zeichen von 32 bis 255:" 35 FrbHG = 0 ´Farbe nicht gesetzter Pixel 36 FrbVG = 14 ´Farbe gesetzter Pixel 37 X = 0 ´Startposition der Anzeige 38 Y = 1 39 Y1 = 10 ´Schmalschrift-Zeilenabstand 40 X1 = 6 ´Schmalschrift-Zeichenabstand 41 42 FOR Zeile = 1 TO 7 ´ASCII-Zeichensatz (32-255) anzeigen 43 FOR Stelle = 0 TO 31 44 Zeichen = Zeile * 32 + Stelle 45 X = X + 2 46 CALL SchmalPrint3(Zeichen, Y + Zeile, X) 47 NEXT Stelle 48 X = 0 49 NEXT Zeile 50 51 ´*** Beispiel 2: Der Zeichenabstand läßt sich variieren 52 53 FrbHG = 0 ´Farbe nicht gesetzter Pixel 54 FrbVG = 15 ´Farbe gesetzter Pixel 55 Y1 = 8 56 X1 = 8 ´großer Zeichenabstand 57 CALL SPrintString("Großer Zeichenabstand", 16, 1) 58 X1 = 5 ´kleinerer Zeichenabstand 59 CALL SPrintString("Kleinerer Zeichenabstand", 18, 2) 60 X1 = 4 ´kleinster Zeichenabstand (Normal-Einstellung) 61 CALL SPrintString(" Kleinster Zeichenabstand", 20, 2) 62 SPrintString STRING$(160, "A"), 13, 2 63 64 ´Invertieren (Negativ-Schrift) durch Tauschen der Farben: 65 FrbHG = 15 ´Farbe eines nicht gesetzten Pixels 66 FrbVG = 0 ´Farbe eines gesetzten Pixels 67 68 ´ (wie man sieht, kann der Text natürlich auch eine Variable sein): 69 Text$ = " Negativ-Schrift " 70 CALL SPrintString(Text$, 20, 35) 71 72 ´*** Beispiel 3: Zeitanzeige in einer simulierten LED-Uhr 73 74 CIRCLE (511, 54), 30, 7 ´Uhren-Gehäuse zeichnen 75 CIRCLE (509, 52), 30, 3 76 PAINT (509, 52), 3 77 Y1 = 8 78 X1 = 4 79 FrbHG = 3 80 FrbVG = 0 81 CALL SPrintString("+----------+", 5, 120) 82 CALL SPrintString("| |", 6, 120) 83 CALL SPrintString("+----------+", 7, 120) 84 85 FrbHG = 0 ´Zeit anzeigen... 86 FrbVG = 12 87 DO ´...bis eine Taste gedrückt wird 88 CALL SPrintString(" " + TIME$ + " ", 6, 121) 89 LOOP UNTIL LEN(INKEY$) 90 SCREEN 0 ´zurück zum Textbildschirm 91 92 ´*** Schmalschrift-Zeichensatztabelle 93 94 FontData: 95 DATA "41 00 00 00 00 00 FA 00 00 E0 00 E0 00 FF 24 FF 00 24 D6 48" 96 DATA "00 86 38 C2 00 FE CC 14 00 20 40 80 00 38 44 82 00 82 44 38" 97 DATA "00 54 38 54 00 10 7C 10 00 05 06 00 00 10 10 10 00 06 06 00" 98 DATA "00 06 38 C0 00 7C 82 7C 00 20 40 FE 00 CE 92 72 00 44 92 6C" 99 DATA "00 1E 62 87 00 E2 A2 9C 00 7C 92 8C 00 86 88 F0 00 6C 92 6C" 100 DATA "00 62 92 7C 00 00 24 00 00 05 16 00 00 10 28 44 00 28 28 28" 101 DATA "00 44 28 10 00 40 8A 70 00 3A EE B8 00 7E 90 7E 00 FE 92 6C" 102 DATA "00 7C 82 82 00 FE 82 7C 00 FE 92 82 00 FE 90 80 00 7C 92 5C" 103 DATA "00 FE 10 FE 00 82 FE 82 00 02 01 FE 00 FE 10 EE 00 FE 02 02" 104 DATA "00 FE 60 FE 00 FE 38 FE 00 FE 82 FE 00 FE 90 60 00 7C 86 7A" 105 DATA "00 FE 90 6E 00 64 92 4C 00 80 FE 80 00 FE 02 FE 00 FC 02 FC" 106 DATA "00 FE 0C FE 00 EE 10 EE 00 F0 0E F0 00 8E 92 E2 00 00 FE 82" 107 DATA "00 C0 38 06 00 82 FE 00 00 40 80 40 00 02 02 02 00 80 40 20" 108 DATA "00 2E 2A 1E 00 FE 22 1C 00 1C 22 22 00 1C 22 FE 00 1C 2A 1A" 109 DATA "00 10 7E 90 00 19 25 3E 00 FE 20 1E 00 10 5E 00 00 02 11 5E" 110 DATA "00 FE 08 16 00 80 FE 00 00 3E 38 1E 00 3E 1E 00 00 1C 22 1C" 111 DATA "00 3F 24 18 00 18 24 3F 00 3E 20 10 00 12 2A 24 00 FC 22 22" 112 DATA "00 3E 02 3E 00 3C 02 3C 00 3E 0C 3E 00 36 08 36 00 39 05 3E" 113 DATA "00 26 2A 32 00 10 6C 82 00 00 EE 00 00 82 6C 10 00 18 10 30" 114 DATA "00 0E 12 12 0E 7C 82 83 00 5E 02 5E 00 1C 2A 5A 80 6E AA 5E" 115 DATA "00 AE 2A 9E 00 AE AA 1E 00 2E EA 1E 00 1C 22 23 00 5C AA 5A" 116 DATA "00 5C 2A 5A 00 5C 6A 1A 00 50 1E 40 00 50 9E 40 00 90 5E 00" 117 DATA "00 BE 50 BE 00 1E A8 1E 00 3E 6A A2 00 3A 1C 2E 00 3E 50 7E" 118 DATA "52 5C A2 5C 00 9C 22 9C 00 9C 62 1C 00 5E 82 5E 00 9E 42 1E" 119 DATA "00 B9 05 BE 00 BE 22 BE 00 BE 02 BE 00 3C E7 24 00 FE D2 06" 120 DATA "00 D4 3E D4 00 FE A0 5E 0A 11 FF 90 00 2E 6A 9E 00 10 5E 80" 121 DATA "00 1C 62 9C 00 1E 42 9E 00 BE 9E 00 00 BE 9C BE 00 E8 E8 28" 122 DATA "00 E8 A8 E8 00 0C B2 04 00 1C 10 10 00 10 10 1C 00 66 38 CC" 123 DATA "04 66 38 E2 06 00 BE 00 00 28 10 28 10 10 28 10 28 AA 55 AA" 124 DATA "55 AA AA 55 55 FF 55 FF 55 00 FF 00 00 08 FF 00 00 18 FF 00" 125 DATA "00 08 FF FF 00 08 0F 0F 00 18 1F 00 00 18 FF FF 00 00 FF FF" 126 DATA "00 18 1F 1F 00 18 F8 F8 00 08 F8 F8 00 18 F8 00 00 08 0F 00" 127 DATA "00 00 F8 08 08 08 F8 08 08 08 0F 08 08 00 FF 08 08 08 08 08" 128 DATA "08 08 FF 08 08 00 FF 18 18 00 FF FF 08 00 F8 F8 18 00 1F 1F" 129 DATA "18 18 F8 F8 18 18 1F 1F 18 00 FF FF 18 18 18 18 18 18 FF FF" 130 DATA "18 18 F8 18 18 08 F8 F8 08 18 1F 18 18 08 0F 0F 08 00 F8 F8" 131 DATA "08 00 F8 18 18 00 1F 18 18 00 0F 0F 08 08 FF FF 08 18 FF 18" 132 DATA "18 08 F8 00 00 00 0F 08 08 FF FF FF FF 0F 0F 0F 0F FF FF 00" 133 DATA "00 00 00 FF FF F0 F0 F0 F0 3E 3E 1C 22 3F 54 28 00 7E 40 60" 134 DATA "00 3E 20 3E 20 C6 BA 92 00 1C 22 3C 20 3F 08 38 00 20 1E 20" 135 DATA "00 BA C6 BA 00 7C 92 7C 00 F6 88 F6 00 CE AA 9E 00 0C 0C 0C" 136 DATA "00 1D 36 5C 00 7C 92 82 00 7C 40 7C 00 54 54 54 00 24 74 24" 137 DATA "00 54 24 24 00 24 24 54 00 00 7F 60 00 06 FE 00 00 08 2A 08" 138 DATA "00 14 28 14 28 40 A0 40 00 00 18 00 00 00 08 00 00 18 0E F0" 139 DATA "80 F0 80 70 00 B0 90 50 00 00 18 18 00 00 00 00 00 00 00 00" 140 ´Die letzten drei "00" dienen nur zum Auffüllen (siehe Text) 141 142 ´*** Hexadezimalzahl (String) in Dezimalwert wandeln 143 FUNCTION Hex2Dez (H$) 144 D = 0 145 FOR i = 1 TO LEN(H$) 146 z = ASC(MID$(H$, i)) 147 z = z - 48 - 7 * INT((z - 48) / 17) 148 D = D * 16 + z 149 NEXT i 150 Hex2Dez = D 151 END FUNCTION 152 153 ´*** Textstring als Schmalschrift-Zeichen auf dem Bildschirm ausgeben 154 SUB SPrintString (Text$, Y, X) 155 X2 = X ´Um den Wert von X zu bewahren 156 FOR Stelle = 1 TO LEN(Text$) 157 Zeichen = ASC(MID$(Text$, Stelle, 1)) 158 X2 = X2 + 1 159 CALL SchmalPrint2(Zeichen, Y, X2) 160 NEXT Stelle 161 END SUB
1 DEFINT A-Z 2 SUB SchmalPrint1 (Zeichen, Y, X) 3 ´*** Ein Schmalschrift-Zeichen auf dem Bildschirm ausgeben 4 ´*** Methode 1: 5 ´*** Verarbeitung der acht Spalten-Bits in einer Schleife 6 Zeichen = Zeichen - 32 ´nur ASCII > 32 verwenden 7 ZE = Zeichen * 4 + 1 ´Offset in den String Font: Ab hier 8 ´bilden 4 Spalten-Bytes ein Zeichen 9 ´Die vier Pixelreihen eines Zeichens ermitteln und ausgeben 10 FOR Byte = 1 TO 4 11 A = ASC(MID$(Font$, ZE + Byte, 1)) 12 ´A = 255 - A ´hiermit wäre Invertieren möglich 13 ´ (ggf. REM-Zeichen entfernen) 14 FOR Bit = 0 TO 7 15 IF (A AND 2 ^ Bit) <> 0 THEN Frb = FrbVG ELSE Frb = FrbHG 16 Spalte = X * X1 + Byte: Zeile = Y * Y1 + 7 - Bit 17 PSET (Spalte, Zeile), Frb 18 NEXT Bit 19 NEXT Byte 20 END SUB
1 DEFINT A-Z 2 SUB SchmalPrint2 (Zeichen, Y, X) 3 ´*** Ein Schmalschrift-Zeichen auf dem Bildschirm ausgeben 4 ´*** Methode 2: 5 ´*** Für jedes Bit einer Zeichen-Spalte eine eigene Befehlsfolge 6 Zeichen = Zeichen - 32 ´nur ASCII > 32 verwenden 7 ZE = Zeichen * 4 + 1 ´Offset in den String Font$: Ab hier 8 ´bilden 4 Spalten-Bytes ein Zeichen 9 ´Die vier Pixelreihen eines Zeichens ermitteln und ausgeben 10 FOR Byte = 1 TO 4 11 A = ASC(MID$(Font$, ZE + Byte, 1)) 12 ´A = 255 - A ´hiermit wäre Invertieren möglich 13 ´ (ggf. REM-Zeichen entfernen) 14 IF (A AND 128) <> 0 THEN Frb = FrbVG ELSE Frb = FrbHG ´Bit 7 15 Spalte = X * X1 + Byte: Zeile = Y * Y1 16 PSET (Spalte, Zeile), Frb 17 IF (A AND 64) <> 0 THEN Frb = FrbVG ELSE Frb = FrbHG ´Bit 6 18 Spalte = X * X1 + Byte: Zeile = Y * Y1 + 1 19 PSET (Spalte, Zeile), Frb 20 IF (A AND 32) <> 0 THEN Frb = FrbVG ELSE Frb = FrbHG ´Bit 5 21 Spalte = X * X1 + Byte: Zeile = Y * Y1 + 2 22 PSET (Spalte, Zeile), Frb 23 IF (A AND 16) <> 0 THEN Frb = FrbVG ELSE Frb = FrbHG ´Bit 4 24 Spalte = X * X1 + Byte: Zeile = Y * Y1 + 3 25 PSET (Spalte, Zeile), Frb 26 IF (A AND 8) <> 0 THEN Frb = FrbVG ELSE Frb = FrbHG ´Bit 3 27 Spalte = X * X1 + Byte: Zeile = Y * Y1 + 4 28 PSET (Spalte, Zeile), Frb 29 IF (A AND 4) <> 0 THEN Frb = FrbVG ELSE Frb = FrbHG ´Bit 2 30 Spalte = X * X1 + Byte: Zeile = Y * Y1 + 5 31 PSET (Spalte, Zeile), Frb 32 IF (A AND 2) <> 0 THEN Frb = FrbVG ELSE Frb = FrbHG ´Bit 1 33 Spalte = X * X1 + Byte: Zeile = Y * Y1 + 6 34 PSET (Spalte, Zeile), Frb 35 IF (A AND 1) <> 0 THEN Frb = FrbVG ELSE Frb = FrbHG ´Bit 0 36 Spalte = X * X1 + Byte: Zeile = Y * Y1 + 7 37 PSET (Spalte, Zeile), Frb 38 NEXT Byte 39 END SUB
1 DEFINT A-Z 2 SUB SchmalPrint3 (Zeichen, Y, X) 3 ´*** Ein Schmalschrift-Zeichen auf dem Bildschirm ausgeben 4 ´*** Methode 3: 5 ´*** Nutzung des LINE-Befehls zur Bitmuster-Ausgabe 6 Zeichen = Zeichen - 32 ´nur ASCII > 32 verwenden 7 ZE = Zeichen * 4 + 1 ´Offset in den String Font$: Ab hier 8 ´bilden 4 Bytes ein Zeichen) 9 ´Die vier Pixelreihen eines Zeichens ermitteln und ausgeben 10 FOR Byte = 1 TO 4 11 A& = ASC(MID$(Font$, ZE + Byte, 1)) 12 ´ A& = 255 - A& ´hiermit wäre Invertieren möglich 13 ´ (ggf. REM-Zeichen entfernen) 14 Muster& = 256 * A& ´Bitmuster in die höhere Hälfte der 15 IF Muster& > 32767 THEN ´Variablen, die wir als Struktur- 16 M = Muster& - 65536 ´Parameter für LINE verwenden 17 ELSE 18 M = Muster& 19 END IF 20 ´Zeile nur freischalten, wenn der Hintergrund berücksichtigt werden 21 ´muß, z.B. wenn bereits vorhand. Schmalschrift überschrieben werden soll 22 ´LINE (x * X1 + Byte, y * Y1)-(x * X1 + Byte, y * Y1 + 7), FrbHG 23 LINE (X * X1 + Byte, Y * Y1)-(X * X1 + Byte, Y * Y1 + 7), FrbVG, , M 24 NEXT Byte 25 END SUB