GNU/Linux >> Linux Esercitazione >  >> Linux

Stampa un saluto di Halloween con grafica ASCII su Linux

La grafica ASCII a colori era piuttosto popolare su DOS, che poteva sfruttare il set di caratteri ASCII esteso e la sua raccolta di elementi di disegno. Puoi aggiungere un po' di interesse visivo al tuo prossimo programma FreeDOS aggiungendo grafica ASCII come una bella schermata di "benvenuto" o come una colorata schermata di "uscita" con ulteriori informazioni sul programma.

Ma questo stile di grafica ASCII non si limita solo alle applicazioni FreeDOS. È possibile utilizzare lo stesso metodo in un programma in modalità terminale Linux. Mentre Linux usa ncurses per controllare lo schermo invece del conio di DOS, i concetti correlati si applicano bene ai programmi Linux. Questo articolo spiega come generare disegni ASCII colorati da un programma C.

Più risorse Linux

  • Comandi Linux cheat sheet
  • Cheat sheet sui comandi avanzati di Linux
  • Corso online gratuito:Panoramica tecnica RHEL
  • Cheat sheet della rete Linux
  • Cheat sheet di SELinux
  • Cheat sheet dei comandi comuni di Linux
  • Cosa sono i container Linux?
  • I nostri ultimi articoli su Linux

Un file artistico ASCII

Puoi utilizzare una varietà di strumenti per disegnare la tua arte ASCII. Per questo esempio, ho usato una vecchia applicazione DOS chiamata TheDraw, ma puoi trovare moderni programmi artistici ASCII open source su Linux, come Moebius (licenza Apache) o PabloDraw (licenza MIT). Non importa quale strumento utilizzi, purché tu sappia che aspetto hanno i dati salvati.

Ecco parte di un file artistico ASCII di esempio, salvato come codice sorgente C. Nota che lo snippet di codice definisce alcuni valori:IMAGEDATA_WIDTH e IMAGEDATA_DEPTH definire il numero di colonne e righe sullo schermo. In questo caso, si tratta di un'"immagine" artistica ASCII 80x25. IMAGEDATA_LENGTH definisce il numero di voci nel IMAGEDATA Vettore. Ciascun carattere nella schermata grafica ASCII può essere rappresentato da due byte di dati:il carattere da visualizzare e un attributo di colore contenente sia i colori di primo piano che quelli di sfondo per il carattere. Per uno schermo 80x25, in cui ogni carattere è associato a un attributo, l'array contiene 4000 voci (ovvero 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,

e così via per il resto dell'array.

Per visualizzare questa grafica ASCII sullo schermo, devi scrivere un piccolo programma per leggere l'array e stampare ogni carattere con i colori giusti.

Impostazione di un attributo di colore

L'attributo color in questo file artistico ASCII definisce sia il colore di sfondo che quello di primo piano in un singolo byte, rappresentato da valori esadecimali come 0x08 o 0x6E . L'esadecimale risulta essere un modo compatto per esprimere una "coppia" di colori come questa.

I sistemi in modalità carattere come ncurses su Linux o conio su DOS possono visualizzare solo sedici colori. Sono sedici possibili colori di testo e otto colori di sfondo. Il conteggio di sedici valori (da 0 a 15) in binario richiede solo quattro bit:

  • 1111 è 16 in binario

E convenientemente, l'esadecimale può rappresentare da 0 a 15 con un singolo carattere:0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E e F. Quindi il valore F in esadecimale è il numero 15, o 1111 in binario.

Con le coppie di colori, puoi codificare sia i colori di sfondo che quelli di primo piano in un singolo byte di otto bit. Sono quattro bit per il colore del testo (da 0 a 15 o da 0 a F in esadecimale) e tre bit per il colore di sfondo (da 0 a 7 o da 0 a E in esadecimale). Il bit rimanente nel byte non viene utilizzato qui, quindi possiamo ignorarlo.

Per convertire la coppia di colori o l'attributo in valori di colore che il tuo programma può utilizzare, dovrai utilizzare una maschera di bit per specificare solo i bit utilizzati per il colore del testo o il colore di sfondo. Usando il compilatore C di OpenWatcom su FreeDOS, puoi scrivere questa funzione per impostare i colori in modo appropriato dall'attributo color:

void
textattr(int newattr)
{
  _settextcolor(newattr & 15);         /* 0000xxxx */
  _setbkcolor((newattr >> 4) & 7);     /* 0xxx0000 */
}

Il _settextcolor la funzione imposta solo il colore del testo e il _setbkcolor la funzione imposta il colore di sfondo. Entrambi sono definiti in graph.h . Si noti che poiché l'attributo color includeva sia il colore di sfondo che il colore di primo piano in un singolo valore di byte, il textattr la funzione usa & (AND binario) per impostare una maschera di bit che isoli solo gli ultimi quattro bit nell'attributo. È qui che la coppia di colori memorizza i valori da 0 a 15 per il colore di primo piano.

Per ottenere il colore di sfondo, la funzione esegue prima uno spostamento di un po' per "spingere" i bit a destra. Questo mette i bit "superiori" nell'intervallo di bit "inferiore", quindi qualsiasi bit come 0xxx0000 diventa 00000xxx invece. Possiamo usare un'altra maschera di bit con 7 (binario 0111 ) per selezionare il valore del colore di sfondo.

Visualizzazione grafica ASCII

Il IMAGEDATA array contiene l'intero schermo artistico ASCII e i valori di colore per ciascun carattere. Per visualizzare l'immagine ASCII sullo schermo, il programma deve scansionare l'array, impostare l'attributo del colore, quindi mostrare lo schermo un carattere alla volta.

Lasciamo spazio nella parte inferiore dello schermo per un messaggio o un prompt separato per l'utente. Ciò significa che invece di visualizzare tutte le 25 righe di uno schermo ASCII a 80 colonne, voglio mostrare solo le prime 24 righe.

  /* print one line less than the 80x25 that's in there:
     80 x 24 x 2 = 3840 */

  for (pos = 0; pos < 3840; pos += 2) {
...
  }

Dentro il for loop, dobbiamo impostare i colori, quindi stampare il carattere. Il compilatore C di OpenWatcom fornisce una funzione _outtext per visualizzare il testo con i valori di colore correnti. Tuttavia, ciò richiede il passaggio di una stringa e sarebbe inefficiente se dobbiamo elaborare ogni carattere uno alla volta, nel caso in cui ogni carattere su una riga richieda un colore diverso.

Invece, OpenWatcom ha una funzione simile chiamata _outmem che permette di indicare quanti caratteri visualizzare. Per un carattere alla volta, possiamo fornire un puntatore a un valore di carattere in IMAGEDATA array e di' a _outtext per mostrare un solo carattere. Ciò visualizzerà il personaggio utilizzando gli attributi di colore correnti, che è ciò di cui abbiamo bisogno.

  for (pos = 0; pos < 3840; pos += 2) {
    ch = &IMAGEDATA[pos];              /* pointer assignment */
    attr = IMAGEDATA[pos + 1];
 
    textattr(attr);
    _outmem(ch, 1);
  }

Questo for aggiornato loop imposta il carattere ch assegnando un puntatore a IMAGEDATA Vettore. Successivamente, il ciclo imposta gli attributi del testo, quindi visualizza il carattere con _outmem .

Mettere tutto insieme

Con il textattr funzione e il for loop per elaborare l'array, possiamo scrivere un programma completo per visualizzare il contenuto di un file artistico ASCII. Per questo esempio, salva la grafica ASCII come imgdata.inc e includilo nel file sorgente con un #include dichiarazione.

#include <stdio.h>
#include <conio.h>
#include <graph.h>

#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("Error setting video mode", stderr);
    return 1;
  }

  /* draw the array */

  _settextposition(1, 1);              /* top left */

  /* print one line less than the 80x25 that's in there:
     80 x 24 x 2 = 3840 */

  for (pos = 0; pos < 3840; pos += 2) {
    ch = &IMAGEDATA[pos];              /* pointer assignment */
    attr = IMAGEDATA[pos + 1];

    textattr(attr);
    _outmem(ch, 1);
  }

  /* done */

  _settextposition(25, 1);             /* bottom left */

  textattr(0x0f);
  _outtext("Press any key to quit");

  getch();

  textattr(0x00);
  return 0;
}

Compila il programma usando il compilatore C di OpenWatcom su FreeDOS e otterrai un nuovo programma che mostra questo messaggio festivo:

Buon Halloween a tutti!

Scarica il file del codice INC qui.

Scarica il file del codice C qui.

imgdata.inc_.txt hallown.c.txt
Linux
  1. Gestione pacchetti Linux con apt

  2. Come analizzare e stampare in modo grazioso JSON con gli strumenti della riga di comando di Linux

  3. Linux:come combinare l'albero con la dimensione della directory?

  4. Stampa solo parole con lettere maiuscole (Linux)

  5. Come stampare un intervallo di indirizzi IP con il comando Linux seq

Ripristina un vecchio MacBook con Linux

Comando wc Linux con esempi

Comando IP Linux con esempi

15 Comando Linux ps con esempi

Stampa timestamp con output del comando Ping in Linux

Costruire 0verkill sul sottosistema Windows 10 per Linux - Gioco deathmatch artistico 2D ASCII