GNU/Linux >> Tutoriels Linux >  >> Linux

Imprimer une salutation d'Halloween avec l'art ASCII sur Linux

L'art ASCII en couleur était autrefois très populaire sur DOS, qui pouvait tirer parti du jeu de caractères ASCII étendu et de sa collection d'éléments de dessin. Vous pouvez ajouter un peu d'intérêt visuel à votre prochain programme FreeDOS en ajoutant de l'art ASCII comme écran de "bienvenue" sympa ou comme écran de "sortie" coloré avec plus d'informations sur le programme.

Mais ce style d'art ASCII ne se limite pas aux applications FreeDOS. Vous pouvez utiliser la même méthode dans un programme Linux en mode terminal. Alors que Linux utilise ncurses pour contrôler l'écran au lieu du conio de DOS, les concepts associés s'appliquent bien aux programmes Linux. Cet article explique comment générer de l'art ASCII coloré à partir d'un programme C.

Plus de ressources Linux

  • Aide-mémoire des commandes Linux
  • Aide-mémoire des commandes Linux avancées
  • Cours en ligne gratuit :Présentation technique de RHEL
  • Aide-mémoire sur le réseau Linux
  • Aide-mémoire SELinux
  • Aide-mémoire sur les commandes courantes de Linux
  • Que sont les conteneurs Linux ?
  • Nos derniers articles Linux

Un fichier graphique ASCII

Vous pouvez utiliser une variété d'outils pour dessiner votre art ASCII. Pour cet exemple, j'ai utilisé une ancienne application DOS appelée TheDraw, mais vous pouvez trouver des programmes d'art ASCII open source modernes sur Linux, tels que Moebius (licence Apache) ou PabloDraw (licence MIT). Peu importe l'outil que vous utilisez tant que vous savez à quoi ressemblent les données enregistrées.

Voici une partie d'un exemple de fichier d'art ASCII, enregistré en tant que code source C. Notez que l'extrait de code définit quelques valeurs :IMAGEDATA_WIDTH et IMAGEDATA_DEPTH définir le nombre de colonnes et de lignes à l'écran. Dans ce cas, il s'agit d'une "image" d'art ASCII 80x25. IMAGEDATA_LENGTH définit le nombre d'entrées dans IMAGEDATA déployer. Chaque caractère de l'écran d'art ASCII peut être représenté par deux octets de données :le caractère à afficher et un attribut de couleur contenant à la fois les couleurs de premier plan et d'arrière-plan du caractère. Pour un écran 80x25, où chaque caractère est associé à un attribut, le tableau contient 4000 entrées (soit 80 * 25 * 2 =4000).

#define IMAGEDATA_WIDTH 80
#define IMAGEDATA_DEPTH 25
#define IMAGEDATA_LENGTH 4000
caractère non signé 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,

et ainsi de suite pour le reste du tableau.

Pour afficher cet art ASCII à l'écran, vous devez écrire un petit programme pour lire le tableau et imprimer chaque caractère avec les bonnes couleurs.

Définir un attribut de couleur

L'attribut de couleur dans ce fichier d'art ASCII définit à la fois la couleur d'arrière-plan et de premier plan dans un seul octet, représenté par des valeurs hexadécimales telles que 0x08 ou 0x6E . L'hexadécimal s'avère être un moyen compact d'exprimer une "paire" de couleurs comme celle-ci.

Les systèmes en mode caractère comme ncurses sous Linux ou conio sous DOS ne peuvent afficher que seize couleurs. C'est seize couleurs de texte possibles et huit couleurs d'arrière-plan. Compter seize valeurs (de 0 à 15) en binaire ne nécessite que quatre bits :

  • 1111 vaut 16 en binaire

Et commodément, l'hexadécimal peut représenter 0 à 15 avec un seul caractère :0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E et F. Ainsi, la valeur F en hexadécimal est le nombre 15, ou 1111 en binaire.

Avec les paires de couleurs, vous pouvez coder à la fois les couleurs d'arrière-plan et de premier plan dans un seul octet de huit bits. C'est quatre bits pour la couleur du texte (0 à 15 ou 0 à F en hexadécimal) et trois bits pour la couleur de fond (0 à 7 ou 0 à E en hexadécimal). Le bit restant dans l'octet n'est pas utilisé ici, nous pouvons donc l'ignorer.

Pour convertir la paire de couleurs ou l'attribut en valeurs de couleur que votre programme peut utiliser, vous devrez utiliser un masque de bits pour spécifier uniquement les bits utilisés pour la couleur du texte ou la couleur d'arrière-plan. En utilisant le compilateur OpenWatcom C sur FreeDOS, vous pouvez écrire cette fonction pour définir les couleurs de manière appropriée à partir de l'attribut color :

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

Le _settextcolor la fonction définit uniquement la couleur du texte et le _setbkcolor La fonction définit la couleur d'arrière-plan. Les deux sont définis dans graph.h . Notez que parce que l'attribut de couleur incluait à la fois la couleur d'arrière-plan et la couleur de premier plan dans une seule valeur d'octet, le textattr la fonction utilise & (ET binaire) pour définir un masque de bits qui isole uniquement les quatre derniers bits de l'attribut. C'est là que la paire de couleurs stocke les valeurs de 0 à 15 pour la couleur de premier plan.

Pour obtenir la couleur de fond, la fonction effectue d'abord un décalage de bit pour "pousser" les bits vers la droite. Cela place les bits "supérieurs" dans la plage de bits "inférieur", donc tous les bits comme 0xxx0000 devient 00000xxx Au lieu. Nous pouvons utiliser un autre masque de bits avec 7 (binaire 0111 ) pour sélectionner la valeur de la couleur d'arrière-plan.

Affichage de l'art ASCII

Les IMAGEDATA array contient l'intégralité de l'écran d'art ASCII et les valeurs de couleur pour chaque caractère. Pour afficher l'art ASCII à l'écran, votre programme doit balayer le tableau, définir l'attribut de couleur, puis afficher l'écran un caractère à la fois.

Laissons de la place en bas de l'écran pour un message séparé ou une invite à l'utilisateur. Cela signifie qu'au lieu d'afficher les 25 lignes d'un écran ASCII à 80 colonnes, je souhaite uniquement afficher les 24 premières lignes.

  /* imprime une ligne de moins que le 80 x 25 qui s'y trouve :
     80 x 24 x 2 =3840 */

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

À l'intérieur du for boucle, nous devons définir les couleurs, puis imprimer le caractère. Le compilateur OpenWatcom C fournit une fonction _outtext pour afficher le texte avec les valeurs de couleur actuelles. Cependant, cela nécessite de passer une chaîne et serait inefficace si nous devions traiter chaque caractère un à la fois, au cas où chaque caractère sur une ligne nécessiterait une couleur différente.

Au lieu de cela, OpenWatcom a une fonction similaire appelée _outmem qui permet d'indiquer le nombre de caractères à afficher. Pour un caractère à la fois, nous pouvons fournir un pointeur vers une valeur de caractère dans IMAGEDATA tableau et dites _outtext pour afficher un seul caractère. Cela affichera le personnage en utilisant les attributs de couleur actuels, ce dont nous avons besoin.

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

Ce for mis à jour boucle définit le caractère ch en affectant un pointeur dans le IMAGEDATA déployer. Ensuite, la boucle définit les attributs de texte, puis affiche le caractère avec _outmem .

Tout mettre ensemble

Avec le textattr fonction et le for boucle pour traiter le tableau, nous pouvons écrire un programme complet pour afficher le contenu d'un fichier art ASCII. Pour cet exemple, enregistrez l'art ASCII sous imgdata.inc et incluez-le dans le fichier source avec un #include déclaration.

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

  /* dessine le tableau */

  _settextposition(1, 1); /* en haut à gauche */

  /* imprime une ligne de moins que le 80x25 qui s'y trouve :
     80 x 24 x 2 =3840 */

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

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

  /* terminé */

  _settextposition(25, 1); /* en bas à gauche */

  textattr(0x0f);
  _outtext("Appuyez sur n'importe quelle touche pour quitter");

  getch();

  textattr(0x00);
  return 0;
}

Compilez le programme à l'aide du compilateur OpenWatcom C sur FreeDOS, et vous obtiendrez un nouveau programme qui affiche ce message de vacances :

Joyeux Halloween à tous !

Téléchargez le fichier de code INC ici.

Téléchargez le fichier de code C ici.

imgdata.inc_.txt hallown.c.txt
Linux
  1. Gestion des packages Linux avec apt

  2. Comment analyser et joliment imprimer JSON avec les outils de ligne de commande Linux

  3. Commande JQ sous Linux avec exemples

  4. Linux - Comment combiner l'arborescence avec la taille du répertoire ?

  5. Imprimer uniquement les mots avec des lettres majuscules (Linux)

Restaurer un ancien MacBook avec Linux

Commande Linux wc avec exemples

Commande Linux ip avec exemples

15 Commande Linux ps avec exemples

Imprimer l'horodatage avec la sortie de la commande Ping sous Linux

Construire 0verkill sur le sous-système Windows 10 pour Linux - Jeu de combat à mort d'art 2D ASCII