Vollfarbige ASCII-Kunst war früher unter DOS sehr beliebt, das den erweiterten ASCII-Zeichensatz und seine Sammlung von Zeichnungselementen nutzen konnte. Sie können Ihrem nächsten FreeDOS-Programm ein wenig visuelles Interesse verleihen, indem Sie ASCII-Grafiken als coolen „Willkommens“-Bildschirm oder als farbenfrohen „Beenden“-Bildschirm mit weiteren Informationen über das Programm hinzufügen.
Aber dieser Stil von ASCII-Kunst ist nicht nur auf FreeDOS-Anwendungen beschränkt. Sie können die gleiche Methode in einem Linux-Programm im Terminalmodus verwenden. Während Linux ncurses zur Steuerung des Bildschirms anstelle von Conio von DOS verwendet, lassen sich die verwandten Konzepte gut auf Linux-Programme anwenden. Dieser Artikel befasst sich mit der Generierung farbiger ASCII-Grafiken aus einem C-Programm.
Weitere Linux-Ressourcen
- Spickzettel für Linux-Befehle
- Spickzettel für fortgeschrittene Linux-Befehle
- Kostenloser Online-Kurs:RHEL Technical Overview
- Spickzettel für Linux-Netzwerke
- SELinux-Spickzettel
- Spickzettel für allgemeine Linux-Befehle
- Was sind Linux-Container?
- Unsere neuesten Linux-Artikel
Eine ASCII-Grafikdatei
Sie können eine Vielzahl von Werkzeugen verwenden, um Ihre ASCII-Kunst zu zeichnen. Für dieses Beispiel habe ich eine alte DOS-Anwendung namens TheDraw verwendet, aber unter Linux finden Sie moderne Open-Source-ASCII-Kunstprogramme wie Moebius (Apache-Lizenz) oder PabloDraw (MIT-Lizenz). Es spielt keine Rolle, welches Tool Sie verwenden, solange Sie wissen, wie die gespeicherten Daten aussehen.
Hier ist ein Teil einer Beispiel-ASCII-Art-Datei, die als C-Quellcode gespeichert ist. Beachten Sie, dass das Code-Snippet einige Werte definiert:IMAGEDATA_WIDTH
und IMAGEDATA_DEPTH
Definieren Sie die Anzahl der Spalten und Zeilen auf dem Bildschirm. In diesem Fall handelt es sich um ein 80 x 25 ASCII-Bild. IMAGEDATA_LENGTH
definiert die Anzahl der Einträge in den IMAGEDATA
Reihe. Jedes Zeichen im ASCII-Grafikbildschirm kann durch zwei Datenbytes dargestellt werden:Das anzuzeigende Zeichen und ein Farbattribut, das sowohl die Vordergrund- als auch die Hintergrundfarbe für das Zeichen enthält. Bei einem 80x25-Bildschirm, bei dem jedes Zeichen mit einem Attribut gepaart ist, enthält das Array 4000 Einträge (das sind 80 * 25 * 2 =4000).
#define IMAGEDATA_WIDTH 80
#define IMAGEDATA_DEPTH 25
#define IMAGEDATA_LENGTH 4000
unsigned char IMAGEDATA [] ={
'.', 0x08, ' ', 0x08, ' ', 0x08, ' ', 0x08, ' ', 0x08, ' ', 0x08,
' ', 0x08, ' ', 0x08, '.', 0x0F, ' ', 0x08, ' ', 0x08, ' ', 0x08,
' ', 0x08, ' ', 0x08, ' ', 0x08, ' ', 0x08, ' ', 0x08, '.', 0x0F,
' ', 0x08, ' ' , 0x08, ' ', 0x08, ' ', 0x08, ' ', 0x08, ' ', 0x08,
' ', 0x08, ' ', 0x08, ' ', 0x08, ' ', 0x08, ' ', 0x08, ' ', 0x08,
und so weiter für den Rest des Arrays.
Um diese ASCII-Grafik auf dem Bildschirm anzuzeigen, müssen Sie ein kleines Programm schreiben, das das Array liest und jedes Zeichen mit den richtigen Farben ausgibt.
Ein Farbattribut festlegen
Das Farbattribut in dieser ASCII-Grafikdatei definiert sowohl die Hintergrund- als auch die Vordergrundfarbe in einem einzelnen Byte, dargestellt durch Hexadezimalwerte wie 0x08
oder 0x6E
. Hexadezimal stellt sich als kompakte Möglichkeit heraus, ein Farbpaar wie dieses auszudrücken.
Zeichenmodussysteme wie ncurses unter Linux oder conio unter DOS können nur sechzehn Farben darstellen. Das sind sechzehn mögliche Textfarben und acht Hintergrundfarben. Das Zählen von sechzehn Werten (von 0 bis 15) in Binärform erfordert nur vier Bits:
1111
ist 16 in binär
Und praktischerweise kann Hexadezimal 0 bis 15 mit einem einzigen Zeichen darstellen:0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E und F. Also der Wert F
hexadezimal ist die Zahl 15 oder 1111
im Binärformat.
Mit Farbpaaren können Sie sowohl die Hintergrund- als auch die Vordergrundfarbe in einem einzigen Byte von acht Bit codieren. Das sind vier Bits für die Textfarbe (0 bis 15 oder 0 bis F im Hexadezimalformat) und drei Bits für die Hintergrundfarbe (0 bis 7 oder 0 bis E im Hexadezimalformat). Das Restbit im Byte wird hier nicht verwendet, also können wir es ignorieren.
Um das Farbpaar oder Attribut in Farbwerte umzuwandeln, die Ihr Programm verwenden kann, müssen Sie eine Bitmaske verwenden, um nur die Bits anzugeben, die für die Text- oder Hintergrundfarbe verwendet werden. Mit dem OpenWatcom C-Compiler unter FreeDOS können Sie diese Funktion schreiben, um die Farben entsprechend aus dem Farbattribut festzulegen:
void
textattr(int newattr)
{
_settextcolor(newattr &15); /* 0000xxxx */
_setbkcolor((newatr>> 4) &7); /* 0xxx0000 */
}
Die _settextcolor
Funktion setzt nur die Textfarbe und den _setbkcolor
Funktion setzt die Hintergrundfarbe. Beide sind in graph.h
definiert . Beachten Sie, dass textattr
, da das Farbattribut sowohl die Hintergrundfarbe als auch die Vordergrundfarbe in einem einzelnen Bytewert enthält Funktion verwendet &
(binäres UND), um eine Bitmaske festzulegen, die nur die letzten vier Bits im Attribut isoliert. Dort speichert das Farbpaar die Werte 0 bis 15 für die Vordergrundfarbe.
Um die Hintergrundfarbe zu erhalten, führt die Funktion zunächst eine Bitverschiebung durch, um die Bits nach rechts zu „schieben“. Dadurch werden die „oberen“ Bits in den „unteren“ Bitbereich verschoben, also alle Bits wie 0xxx0000
zu 00000xxx
werden stattdessen. Wir können eine andere Bitmaske mit 7 verwenden (binär 0111
), um den Hintergrundfarbwert auszuwählen.
ASCII-Grafik anzeigen
Die IMAGEDATA
Das Array enthält den gesamten ASCII-Grafikbildschirm und die Farbwerte für jedes Zeichen. Um das ASCII-Bild auf dem Bildschirm anzuzeigen, muss Ihr Programm das Array scannen, das Farbattribut festlegen und dann den Bildschirm zeichenweise anzeigen.
Lassen Sie uns am unteren Rand des Bildschirms Platz für eine separate Nachricht oder Aufforderung an den Benutzer. Das heißt, anstatt alle 25 Zeilen eines 80-Spalten-ASCII-Bildschirms anzuzeigen, möchte ich nur die ersten 24 Zeilen anzeigen.
/* eine Zeile weniger als 80 x 25 ausgeben, die darin enthalten ist:
80 x 24 x 2 =3840 */
für (pos =0; pos <3840; pos +=2) {
...
}
Innerhalb des for
Schleife müssen wir die Farben einstellen und dann das Zeichen drucken. Der OpenWatcom C Compiler bietet eine Funktion _outtext
Text mit den aktuellen Farbwerten anzuzeigen. Dies erfordert jedoch die Übergabe eines Strings und wäre ineffizient, wenn wir jedes Zeichen einzeln verarbeiten müssten, falls jedes Zeichen in einer Zeile eine andere Farbe erfordert.
Stattdessen hat OpenWatcom eine ähnliche Funktion namens _outmem
Damit können Sie angeben, wie viele Zeichen angezeigt werden sollen. Für jeweils ein Zeichen können wir einen Zeiger auf einen Zeichenwert in IMAGEDATA
bereitstellen array und sag _outtext
nur ein Zeichen zu zeigen. Dadurch wird das Zeichen mit den aktuellen Farbattributen angezeigt, was wir brauchen.
for (pos =0; pos <3840; pos +=2) {
ch =&IMAGEDATA[pos]; /* Zeigerzuweisung */
attr =IMAGEDATA[pos + 1];
textattr(attr);
_outmem(ch, 1);
}Dies hat
for
aktualisiert loop setzt das Zeichench
durch Zuweisen eines Zeigers in dieIMAGEDATA
Reihe. Als nächstes setzt die Schleife die Textattribute und zeigt dann das Zeichen mit_outmem
an .Alles zusammenfügen
Mit dem
textattr
Funktion und denfor
-Schleife verwenden, um das Array zu verarbeiten, können wir ein vollständiges Programm schreiben, um den Inhalt einer ASCII-Art-Datei anzuzeigen. Speichern Sie für dieses Beispiel das ASCII-Bild alsimgdata.inc
und fügen Sie es mit einem#include
in die Quelldatei ein Aussage.#include
#include
#include
#include "imgdata.inc"
void
textattr(int newattr)
{
_settextcolor(newattr &15); /* 0000xxxx */
_setbkcolor((newatr>> 4) &7); /* 0xxx0000 */
}
int
main()
{
char *ch;
int attr;
int pos;
if (_setvideomode(_TEXTC80) ==0) {
fputs("Fehler beim Einstellen des Videomodus", stderr);
return 1;
}
/* Array zeichnen */
_settextposition(1, 1); /* oben links */
/* eine Zeile weniger als 80 x 25 ausgeben:
80 x 24 x 2 =3840 */
für ( pos =0; pos <3840; pos +=2) {
ch =&IMAGEDATA[pos]; /* Zeigerzuweisung */
attr =IMAGEDATA[pos + 1];
textattr(attr);
_outmem(ch, 1);
}
/* fertig */
_settextposition(25, 1); /* unten links */
textattr(0x0f);
_outtext("Zum Beenden eine beliebige Taste drücken");
getch();
textattr(0x00);
return 0;
}Kompilieren Sie das Programm mit dem OpenWatcom C Compiler unter FreeDOS, und Sie erhalten ein neues Programm, das diese Feiertagsnachricht anzeigt:
Allen ein frohes Halloween!
Laden Sie die INC-Code-Datei hier herunter.
imgdata.inc_.txt hallown.c.txt
Laden Sie die C-Code-Datei hier herunter.