Plnobarevné ASCII umění bývalo v DOSu docela populární, což mohlo využít rozšířenou znakovou sadu ASCII a její sbírku kreslicích prvků. Svému dalšímu programu FreeDOS můžete přidat trochu vizuálního zájmu přidáním ASCII artu jako skvělé „uvítací“ obrazovky nebo jako barevné „výstupní“ obrazovky s dalšími informacemi o programu.
Ale tento styl ASCII umění není omezen pouze na aplikace FreeDOS. Stejnou metodu můžete použít v programu v terminálovém režimu Linux. Zatímco Linux používá k ovládání obrazovky ncurses místo conio DOSu, související koncepty lze dobře aplikovat na linuxové programy. Tento článek se zabývá tím, jak generovat barevné ASCII umění z programu C.
Další zdroje pro Linux
- Cheat pro příkazy Linuxu
- Cheat sheet pro pokročilé příkazy systému Linux
- Bezplatný online kurz:Technický přehled RHEL
- Síťový cheat pro Linux
- Cheat sheet SELinux
- Cheat pro běžné příkazy pro Linux
- Co jsou kontejnery systému Linux?
- Naše nejnovější články o Linuxu
Soubor ASCII art
Ke kreslení ASCII umění můžete použít různé nástroje. Pro tento příklad jsem použil starou DOSovou aplikaci s názvem TheDraw, ale na Linuxu můžete najít moderní open source ASCII umělecké programy, jako je Moebius (licence Apache) nebo PabloDraw (licence MIT). Nezáleží na tom, jaký nástroj používáte, pokud víte, jak uložená data vypadají.
Zde je část ukázkového uměleckého souboru ASCII uloženého jako zdrojový kód C. Všimněte si, že fragment kódu definuje několik hodnot:IMAGEDATA_WIDTH
a IMAGEDATA_DEPTH
definovat počet sloupců a řádků na obrazovce. V tomto případě se jedná o 80x25 ASCII umělecký „obrázek“. IMAGEDATA_LENGTH
definuje počet položek v IMAGEDATA
pole. Každý znak na umělecké obrazovce ASCII může být reprezentován dvěma bajty dat:znakem, který se má zobrazit, a atributem barvy obsahujícím barvu popředí i pozadí znaku. Na obrazovce 80x25, kde je každý znak spárován s atributem, pole obsahuje 4000 položek (to je 80 * 25 * 2 =4000).
#define IMAGEDATA_WIDTH 80
#define IMAGEDATA_DEPTH 25
#define IMAGEDATA_LENGTH 4000
znak bez znaménka IMAGEDATA [] ={
'.', 0x08, 0 x' 8, ', 0x08, ' ', 0x08, ' ', 0x08, ' ', 0x08,
' ', 0x08, ' ', 0x08, '.', 0x0F, ' 8, 0 x 0 ', 0x08,
' ', 0x08, ' ', 0x08, ' ', 0x08, ' ', 0x08, ' ', 0x08, '.', 0x0F,
, 0 x ' , 0x08, ' ', 0x08, ' ', 0x08, ' ', 0x08, ' ', 0x08,
' ', 0x08, ' ', 0x08, 0x08, 0' 0, 0x08, 0x08, 0x08, 0x08 0x08, ' ', 0x08,
a tak dále pro zbytek pole.
Chcete-li zobrazit toto umění ASCII na obrazovce, musíte napsat malý program, který přečte pole a vytiskne každý znak správnými barvami.
Nastavení atributu barvy
Atribut color v tomto uměleckém souboru ASCII definuje barvu pozadí i popředí v jediném bajtu, reprezentovaném hexadecimálními hodnotami, jako je 0x08
nebo 0x6E
. Hexadecimální se ukazuje jako kompaktní způsob, jak vyjádřit barevný „pár“, jako je tento.
Systémy znakového režimu jako ncurses na Linuxu nebo conio na DOSu mohou zobrazit pouze šestnáct barev. To je šestnáct možných barev textu a osm barev pozadí. Počítání šestnácti hodnot (od 0 do 15) v binárním formátu vyžaduje pouze čtyři bity:
1111
je 16 v binární
Šestnáctkové číslo může pohodlně představovat 0 až 15 jediným znakem:0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E a F. Hodnota F
v šestnáctkové soustavě je číslo 15 nebo 1111
v binárním formátu.
Pomocí barevných párů můžete zakódovat barvy pozadí i popředí do jednoho bajtu o osmi bitech. To jsou čtyři bity pro barvu textu (0 až 15 nebo 0 až F v šestnáctkové soustavě) a tři bity pro barvu pozadí (0 až 7 nebo 0 až E v šestnáctkové soustavě). Zbývající bit v bajtu zde není použit, takže jej můžeme ignorovat.
Chcete-li převést dvojici barev nebo atribut na hodnoty barev, které může váš program použít, budete muset použít bitovou masku, která určí pouze bity použité pro barvu textu nebo barvu pozadí. Pomocí kompilátoru OpenWatcom C na FreeDOS můžete napsat tuto funkci pro správné nastavení barev z atributu color:
void
textattr(int newattr)
{
_settextcolor(newattr &15); /* 0000xxxx */
_setbkcolor((newattr>> 4) &7); /* 0xxx0000 */
}
_settextcolor
funkce nastaví pouze barvu textu a _setbkcolor
funkce nastaví barvu pozadí. Oba jsou definovány v graph.h
. Všimněte si, že protože atribut color zahrnoval barvu pozadí i barvu popředí v jedné bajtové hodnotě, textattr
funkce používá &
(binární AND) pro nastavení bitové masky, která izoluje pouze poslední čtyři bity v atributu. To je místo, kde pár barev ukládá hodnoty 0 až 15 pro barvu popředí.
Chcete-li získat barvu pozadí, funkce nejprve provede bitový posun, aby „tlačil“ bity doprava. Tím se „horní“ bity přesunou do „dolního“ bitového rozsahu, takže všechny bity jako 0xxx0000
stát se 00000xxx
namísto. Můžeme použít jinou bitovou masku se 7 (binární 0111
) a vyberte hodnotu barvy pozadí.
Zobrazení grafiky ASCII
IMAGEDATA
pole obsahuje celou ASCII uměleckou obrazovku a hodnoty barev pro každý znak. Chcete-li zobrazit ASCII umění na obrazovce, váš program potřebuje naskenovat pole, nastavit atribut color a poté zobrazit obrazovku jeden znak po druhém.
Necháme ve spodní části obrazovky místo pro samostatnou zprávu nebo výzvu pro uživatele. To znamená, že místo zobrazení všech 25 řádků 80sloupcové ASCII obrazovky chci zobrazit pouze prvních 24 řádků.
/* vytiskne o jeden řádek méně než 80x25, které je tam uvedeno:
80 x 24 x 2 =3840 */
pro (pos =0; pos <3840; pos +=2) {
...
}
Uvnitř for
smyčky, musíme nastavit barvy a poté vytisknout znak. OpenWatcom C Compiler poskytuje funkci _outtext
pro zobrazení textu s aktuálními hodnotami barev. To však vyžaduje předání řetězce a bylo by neefektivní, pokud potřebujeme zpracovávat každý znak jeden po druhém, v případě, že každý znak na řádku vyžaduje jinou barvu.
Místo toho má OpenWatcom podobnou funkci nazvanou _outmem
která vám umožňuje určit, kolik znaků se má zobrazit. Pro jeden znak po druhém můžeme poskytnout ukazatel na hodnotu znaku v IMAGEDATA
pole a sdělte _outtext
ukázat jen jednu postavu. Tím se znak zobrazí pomocí aktuálních atributů barev, což je to, co potřebujeme.
for (pos =0; pozice <3840; pozice +=2) {
ch =&IMAGEDATA[pos]; /* přiřazení ukazatele */
attr =IMAGEDATA[pos + 1];
textattr(attr);
_outmem(ch, 1);
}Toto bylo aktualizováno
for
loop nastavuje znakch
přiřazením ukazatele doIMAGEDATA
pole. Dále smyčka nastaví atributy textu a poté zobrazí znak s_outmem
.Dáme vše dohromady
Pomocí
textattr
funkce afor
smyčky pro zpracování pole, můžeme napsat úplný program pro zobrazení obsahu uměleckého souboru ASCII. Pro tento příklad uložte obrázek ASCII jakoimgdata.inc
a zahrňte jej do zdrojového souboru pomocí#include
prohlášení.#include
#include
#include
#include "imgdata.inc"
void
textattr(int newattr)
{
_settextcolor(newattr &15); /* 0000xxxx */
_setbkcolor((newattr>> 4) &7); /* 0xxx0000 */
}
int
main()
{
char *ch;
int attr;
int pos;
if (_setvideomode(_TEXTC80) ==0) {
fputs("Chyba při nastavení režimu videa", stderr);
return 1;
}
/* nakreslí pole */
_settextposition(1, 1); /* vlevo nahoře */
/* vytiskne o jeden řádek méně než 80x25, které tam je:
80 x 24 x 2 =3840 */
pro ( pozice =0; pozice <3840; pozice +=2) {
ch =&IMAGEDATA[pos]; /* přiřazení ukazatele */
attr =IMAGEDATA[pos + 1];
textattr(attr);
_outmem(ch, 1);
}
/* hotovo */
_settextposition(25, 1); /* vlevo dole */
textattr(0x0f);
_outtext("Stiskněte libovolnou klávesu pro ukončení");
getch();
textattr(0x00);
návrat 0;
}Zkompilujte program pomocí kompilátoru OpenWatcom C na FreeDOSu a získáte nový program, který zobrazí tuto prázdninovou zprávu:
Veselý Halloween, všichni!
Zde si stáhněte soubor s kódem INC.
imgdata.inc_.txt hallown.c.txt
Zde si stáhněte soubor s kódem C.
Linux