New Curses
3DやGUIなど見た目がリッチな環境のプログラム環境が続きましたが、今回はとても地味なテキストユーザインターフェイス(TUI)を紹介します。UNIXの古くからあるライブラリで、ncurses(new curses)というものを使いました。
環境) Raspberry Pi2, TeraTerm / Windows
参考) https://www.kushiro-ct.ac.jp/yanagawa/ex-2017/2-game/01.html
インストール) sudo apt install ncurses-dev
アルゴリズムを考えたり、外部機器との通信をしたりするときなど、インターフェイスなんて、キーボードとパラメータの表示だけでいい、というようなケースでは、とても便利です。またCプログラムの基礎学習、ビルド環境の理解という点でも、ソースコードからコンパイル、実行とファイル生成の過程が統合環境(IDE)を使うより、わかりやすいです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
#include<ncurses.h> #include<stdio.h> #include<string.h> int getValue(int y, int x) { move(y, x+2); int c1 = inch(); move(y, x+1); int c2 = inch(); move(y, x); int c3 = inch(); if(c1 == ' ') c1 = '0'; if(c2 == ' ') c2 = '0'; if(c3 == ' ') c3 = '0'; return (c3-'0')*100+(c2-'0')*10+c1-'0'; } int main(int argc,char *argv[]) { int x[4], y[4], w, h; char str1[10], str2[10]; memset(str1, 0, sizeof(str1)); memset(str2, 0, sizeof(str2)); int key; int n[4], nn[4]; int p = 100; initscr(); start_color(); init_pair(1, COLOR_RED, COLOR_WHITE); init_pair(2, COLOR_GREEN, COLOR_BLUE); init_pair(3, COLOR_YELLOW, COLOR_BLUE); init_pair(4, COLOR_CYAN, COLOR_BLACK); noecho(); cbreak(); keypad(stdscr, TRUE); getmaxyx(stdscr, h, w); y[0] = y[1] = y[2] = y[3] = h/4; x[0] = w/5; x[1] = w/5*2; x[2] = w/5*3; x[3] = w/5*4; n[0] = n[1] = n[2] = n[3] = 0; mvprintw(1, 1, "*** ncurses test ***"); while (1) { attrset(0); move(y[p%4], x[p%4]); sprintf(str1,"%3d", n[p%4]); addstr(str1); int v = getValue(y[p%4], x[p%4]); if(n[p%4] > 150) attrset(COLOR_PAIR(2) | A_BOLD); else if(n[p%4] > 100) attrset(COLOR_PAIR(3) | A_BOLD | A_REVERSE); else if(n[p%4] > 50) attrset(COLOR_PAIR(4) | A_BOLD | A_REVERSE); else attrset(COLOR_PAIR(1) | A_BOLD | A_REVERSE); move(y[p%4]+5, x[p%4]); sprintf(str2,"%3d", v); addstr(str2); key = getch(); if (key == 'q') break; switch (key) { case KEY_UP: if(n[p%4] < 999) n[p%4]++; break; case KEY_DOWN: if(n[p%4] > 0) n[p%4]--; break; case KEY_LEFT: p--; break; case KEY_RIGHT: p++; break; } } endwin(); return 0; } |
ビルド) cc -o ncurtest ncurtest.c -lncurses
このプログラムは、カーソルキー操作で4つの値を増減するだけのものです。ただこのとき値の大きさによって色を変えています。
ちょっと変わったやり方として、値の複製をしていますが、この値は変数でなく画面から読み取っています。(わかる人はかなり少な目ですが、むかしNEC PC-9801シリーズでよく使われたテキストVRAM(ビデオRAM)を想定しました。)
Windowsが登場前のアプリ(パブリックドメインソフトとよく言われていたもの)は、表示速度が速いテキストVRAMを活用したものが多かったです。ゲームをはじめ実用アプリなどを作るのに十分な性能があったため、多くのアプリが作られました。(ほとんどがC言語(高速処理部分はアセンブラ)だったと思う・・)
ただ画面表示から値を読むため、カラー情報がないところから読む必要があります。(BGカラーは設定できない) また画面サイズ取得する関数getmaxyxは変数の参照を受け取っていますが、このような書き方は、最近ではNGです。マクロなのでできるようですが、古いCのライブラリは、他にも入力値を書き換えたりするようなものがあったりと、なんでもありなものがありますのでそのあたりは要注意です。
moveというような短い関数名を衝突を考えるといまどきあり得ないのですが、コマンドラインでファイルリストを表示するlsもそうですが、当時はこういう短い名前で表現することが普通でした。ちょっと歴史を感じるライブラリです。
昔を懐かしむことが目的ではなく、ここで重要なのは、開発コストが低いということです。見た目はさておき、手っ取り早くプログラム開発ができます。
コンソールてはプロクラムを編集するツールはviというものを使いますが、これはちょっとハードルが高いのでRasperryPiならGUIでエディタも使ってコーディングすることをおすすめします。
Category: 未分類