T:3195 Y:8176 Total:02760183 Online:39

    Flashの組み込みプログラミング講座

「AmebaKING」アメブロ売上倍増&アクセスアップの多機能ツール

2016/11/17

Unixにリアルタイムキー処理をプログラミングする。(C言語 kbhit) カテゴリー 徒然ぶろぐ

WindowsというかDOSの時代から、マイクロソフトのOSには非標準の機能をC言語の中に入れ込んでいました。つまりC言語にはリアルタイムキー処理関数は無いのです。

とはいうものの、そんな時代の遺物というか、C言語の本の多くに、getch() や kbhit() なる関数が出てきます。これらの機能は古きDOS時代には、OSの割り込み機能としてINT21というアセンブラレベルのシステムコールにより実現していた機能です。
よって、言語側には、本来そのようなハードとOSに依存するような機能の関数はないのです。
キー入力は、本来、getchar(),gets() であるべきなのですが、・・・

リアルタイムにおされているキーの処理ができないとつくれないものが出てくることになりました。
それはゲームです。

C言語標準のキーボードからの入力は、本来OSと一体化するので標準入力のみをファイルとして扱っています。よってバッファリングに溜め込まれ、エンターキーなどでFlashされるという流れになるのですが、これではゲームが成り立ちませんよね。^^;

そこで、リアルタイムにキーを処理する機能が当時のDOSに盛り込まれたのです。
int21 あるいはNECのPC9801時代なら、int18 などの割り込み機能です。
つまり、マイクロソフトのDOS〜Windowsの流れには存在していますが、LinuxやUnixには必要ありませんでした。
なぜなら、サーバーにターミナル(TTY)をネットワークで接続するタイプのものだったからです。
 
しかし、実際にはローグや、ハングマンといったゲームにもリアルにキー入力を扱わなければゲーム性が無くなるので、ひっそりとリアルタイムキー入力処理は実現可能ではありました。

現在は、カノニカルモード(バッファー処理有りのモード)と、RAWモードの門ブロッキング処理に分けています。
つまり、非標準な機能として、端末(TTY)を一時的にノンブロッキングモードでどうささせ、キーバッファーしょりをせずリアルにキーボード処理をおこなう機能も盛り込まれています。
つまり、getch() も使えるようにはなっています。

もっとも簡単な方法は、ライブラリのncursysです。ncurses は、端末に依存しない形式でテキストユーザインタフェース (TUI) を作成するためのAPIを提供するライブラリです。

ただ実際には、kbhit()のようなキーが押されているかというテスト関数が必要なので別途用意します。

以下のソースは、MacのBSD上で動作を確認しましたので、そのまま使えます。

ーーーktest.c
#include <stdio.h>
#include <termios.h>
#include <unistd.h>
#include <fcntl.h>

int kbhit(void)
{
struct termios oldt, newt;
int ch;
int oldf;

tcgetattr(STDIN_FILENO, &oldt);
newt = oldt;
newt.c_lflag &= ~(ICANON | ECHO);
tcsetattr(STDIN_FILENO, TCSANOW, &newt);
oldf = fcntl(STDIN_FILENO, F_GETFL, 0);
fcntl(STDIN_FILENO, F_SETFL, oldf | O_NONBLOCK);

ch = getchar();

tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
fcntl(STDIN_FILENO, F_SETFL, oldf);

if (ch != EOF) {
ungetc(ch, stdin);
return 1;
}

return 0;
}

int main(void)
{
puts("何かキーを押したら終了");

while (1) {
if (kbhit()) {
printf("'%c'を押しました。¥n", getchar());
break;
}
}

return 0;
}
ーーー
<>は全角文字なので半角に修正して下さいね

― posted by i2lab at 01:36 pm

この記事に対するコメントは締め切られています





Top! Top!
blog seo tool : track word blog SEO tool
[プレスブログ]価値あるブログに掲載料をお支払いします。