フルカラーASCIIアートはDOSで非常に人気があり、拡張ASCII文字セットとその描画要素のコレクションを活用できました。 ASCIIアートをクールな「ウェルカム」画面として、またはプログラムに関する詳細情報を含むカラフルな「終了」画面として追加することで、次のFreeDOSプログラムに視覚的な興味を少し加えることができます。
しかし、このスタイルのASCIIアートは、FreeDOSアプリケーションだけに限定されていません。 Linuxターミナルモードプログラムでも同じ方法を使用できます。 LinuxはDOSのconioの代わりにncursesを使用して画面を制御しますが、関連する概念はLinuxプログラムにうまく適用されます。この記事では、CプログラムからカラフルなASCIIアートを生成する方法について説明します。
その他のLinuxリソース
- Linuxコマンドのチートシート
- 高度なLinuxコマンドのチートシート
- 無料のオンラインコース:RHELの技術概要
- Linuxネットワーキングのチートシート
- SELinuxチートシート
- Linuxの一般的なコマンドのチートシート
- Linuxコンテナとは何ですか?
- 最新のLinux記事
ASCIIアートファイル
さまざまなツールを使用して、ASCIIアートを描くことができます。この例では、TheDrawという古いDOSアプリケーションを使用しましたが、Linux上でMoebius(Apacheライセンス)やPabloDraw(MITライセンス)などの最新のオープンソースASCIIアートプログラムを見つけることができます。保存されたデータがどのように見えるかを知っていれば、どのツールを使用してもかまいません。
これは、Cソースコードとして保存されたサンプルASCIIアートファイルの一部です。コードスニペットはいくつかの値を定義していることに注意してください:IMAGEDATA_WIDTH
およびIMAGEDATA_DEPTH
画面上の列と行の数を定義します。この場合、それは80x25のASCIIアートの「画像」です。 IMAGEDATA_LENGTH
IMAGEDATA
のエントリ数を定義します 配列。 ASCIIアート画面の各文字は、2バイトのデータで表すことができます。表示する文字と、文字の前景色と背景色の両方を含む色属性です。各文字が属性とペアになっている80x25画面の場合、配列には4000エントリが含まれます(つまり、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,
アレイの残りの部分についても同様です。
このASCIIアートを画面に表示するには、配列を読み取り、各文字を適切な色で印刷する小さなプログラムを作成する必要があります。
色属性の設定
このASCIIアートファイルのcolor属性は、1バイトで背景色と前景色の両方を定義し、0x08
のような16進値で表されます。 または0x6E
。 16進数は、このような色の「ペア」を表現するためのコンパクトな方法であることがわかりました。
LinuxのncursesやDOSのconioなどの文字モードシステムでは、16色しか表示できません。これは、16の可能なテキストカラーと8つの背景カラーです。バイナリで16個の値(0から15)をカウントするには、4ビットしか必要ありません:
-
1111
バイナリで16です
そして便利なことに、16進数は0から15を1文字で表すことができます:0、1、2、3、4、5、6、7、8、9、A、B、C、D、E、およびF。 F
16進数は15、つまり1111
です。 バイナリで。
カラーペアを使用すると、背景色と前景色の両方を8ビットの1バイトでエンコードできます。これは、テキストの色(16進数で0から15または0からF)の場合は4ビット、背景色の場合(16進数で0から7または0からE)の3ビットです。バイトの残りのビットはここでは使用されないため、無視できます。
色のペアまたは属性をプログラムで使用できる色の値に変換するには、ビットマスクを使用して、テキストの色または背景色に使用されるビットのみを指定する必要があります。 FreeDOSでOpenWatcomCコンパイラを使用すると、次の関数を記述して、color属性から色を適切に設定できます。
void
textattr(int newattr)
{
_settextcolor(newattr & 15); /* 0000xxxx */
_setbkcolor((newattr >> 4) & 7); /* 0xxx0000 */
}
_settextcolor
関数は、テキストの色と_setbkcolor
だけを設定します 関数は背景色を設定します。どちらもgraph.h
で定義されています 。 color属性には、1バイトの値に背景色と前景色の両方が含まれているため、textattr
関数は&
を使用します (バイナリAND)属性の最後の4ビットのみを分離するビットマスクを設定します。ここで、色のペアに前景色の0〜15の値が格納されます。
背景色を取得するために、関数は最初にビットシフトを実行してビットを右に「プッシュ」します。これにより、「上位」ビットが「下位」ビット範囲に配置されるため、0xxx0000
などのビットはすべて 00000xxx
になります 代わりは。 7で別のビットマスクを使用できます(バイナリ0111
)背景色の値を選択します。
ASCIIアートの表示
IMAGEDATA
配列には、ASCIIアート画面全体と各文字の色の値が含まれています。アスキーアートを画面に表示するには、プログラムで配列をスキャンし、色属性を設定してから、一度に1文字ずつ画面に表示する必要があります。
画面の下部に、ユーザーへの別のメッセージまたはプロンプト用のスペースを残しましょう。つまり、80列のASCII画面の25行すべてを表示するのではなく、最初の24行だけを表示したいのです。
/* print one line less than the 80x25 that's in there:
80 x 24 x 2 = 3840 */
for (pos = 0; pos < 3840; pos += 2) {
...
}
for
の内部 ループ、色を設定してから文字を印刷する必要があります。 OpenWatcomCコンパイラは関数_outtext
を提供します 現在の色の値でテキストを表示します。ただし、これには文字列を渡す必要があり、行の各文字に異なる色が必要な場合に、各文字を一度に1つずつ処理する必要がある場合は、非効率的です。
代わりに、OpenWatcomには_outmem
と呼ばれる同様の関数があります これにより、表示する文字数を指定できます。一度に1文字ずつ、IMAGEDATA
の文字値へのポインタを指定できます。 配列して_outtext
に伝えます 1文字だけ表示します。これにより、現在の色属性を使用して文字が表示されます。これが必要です。
for (pos = 0; pos < 3840; pos += 2) {
ch = &IMAGEDATA[pos]; /* pointer assignment */
attr = IMAGEDATA[pos + 1];
textattr(attr);
_outmem(ch, 1);
}
この更新されたfor
ループは文字ch
を設定します IMAGEDATA
にポインタを割り当てる。 配列。次に、ループはテキスト属性を設定し、_outmem
で文字を表示します 。
すべてをまとめる
textattr
を使用 関数とfor
配列を処理するためのループ、ASCIIアートファイルの内容を表示するための完全なプログラムを書くことができます。この例では、ASCIIアートをimgdata.inc
として保存します #include
を使用してソースファイルに含めます ステートメント。
#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;
}
FreeDOSのOpenWatcomCコンパイラを使用してプログラムをコンパイルすると、このホリデーメッセージを表示する新しいプログラムが表示されます。
みなさん、ハッピーハロウィン!
ここからINCコードファイルをダウンロードします。
ここからCコードファイルをダウンロードします。