blike
>blikeとは一体何なのか?
C言語やJavaをお勉強するための、K流の支援キットです。教材です。
>サンプルプログラムと、そのビルド方法を知りたいです。
たとえばCFB版(C言語を入門向きにしたもの)ならここで説明しています。
http://osask.net/w/?blike/CFB/p0002
C言語やJavaをお勉強するための、K流の支援キットです。教材です。
>サンプルプログラムと、そのビルド方法を知りたいです。
たとえばCFB版(C言語を入門向きにしたもの)ならここで説明しています。
http://osask.net/w/?blike/CFB/p0002
win機での挙動がわからないので想像ですが、linux用にblike.hを移植しようと思いました。
http://kemeconoajito.blog88.fc2.com/blog-entry-118.html
inkeyで得られる数値の仕様とか、colorでの色番号の仕様とか、いろいろ具体的な所の挙動が(当方、windouws機をもってないので)よく分からないので、だれか対応表みたいなのおねがいします…(ちらっ
http://kemeconoajito.blog88.fc2.com/blog-entry-118.html
inkeyで得られる数値の仕様とか、colorでの色番号の仕様とか、いろいろ具体的な所の挙動が(当方、windouws機をもってないので)よく分からないので、だれか対応表みたいなのおねがいします…(ちらっ
linux の gnome 上で gtk+2.0 でドライバー部分を書いてみました。
(グラフィック部分のみ)
http://blog-imgs-42.fc2.com/k/e/m/kemeconoajito/drvgtk03.png
blike.c は書き換えずに、drvwin32.c 以下のみを書き換えて、それで本当に動作するのか?
…を試すために書いたのですが、大方、動作するようです。
ドライバーを書いた際に、いくつか気づいた点、疑問点がありました。
ピクセル合成のモード? が、何を表してるのか分からないので、具体的な式による説明があるとありがたいです。
(ウインドウズにベッタリな処理なので、ブラックボックスで具体的な計算式がわからないので、移植にこまる)
たとえば「この合成モードでは (ピクセルA * ピクセルB) による乗算を行うことを期待している」みたいな具体的な説明をだれか補足してくれるとありがたいです。
各フラグの。
あと、bld_waitNF() に望んでる動作は、2ミリ秒スリープさせるってことでしょうか?
#define TIMER_INTERVAL 10
Sleep(TIMER_INTERVAL / 4);
この125Hz(2ミリ秒)を公式と考えなさいということですか?
当方windowsの実行環境が遠いので、実際のウインドウズ上で動作を試してなかったので誤解してたのですが、
printf の結果は、コンソールではなく、新しくウインドウ作って、そこに表示するみたいですが、
ならば、新規にウインドウを作る処理は、大多数のアプリケーションならば blmainの実行中に必ずあると考えて、
open window は必ず行うということにしてしまえばどうでしょうか?
(エコーのない cp コマンドを作る場合等は不要でしょうが、そういう例は稀だと思います。
大多数のアプリケーションでは、なんらかの文字や画像が情報として画面出力されるものだと思います。)
つまり、open window する関数を、ユーザーに任せずに、自動にしてしまえばどうでしょうか? (デフォルトサイズで)
あと、ユーザーがウインドウのサイズ変更をしたい場合には、open ではなく resize という名前を使った方が意味がわかりやすいと思うのですが。 resize window 的な名前の関数で。
あと、気になったのは、window の幅と高さを引数で受けとるとき、引数名が x y なのが奇妙に感じました。
最初混乱しました。(「デスクトップ上での初期表示座標か??」とか誤解して最初混乱しました)
幅と高さは w , h に変えた方がドライバー作る人に誤解が無くていいと思います。
あと、将来的にウインドウを複数作る場合に、おそらくウインドウ毎にスレッドを用意するのでしょうけど、その場合 bl_work を大域変数として、たった一個しか bl_work が無い状況は、複数ウインドウを開く場合に面倒なことになると思います。
将来的に、「複数ウインドウを開くことは考えてない」ということで、bl_work が(ポインタではなく実数での)大域変数なのですか?
たとえば bl_work をポインタとして用意してあれば、将来的に配列として扱うようにも簡単に変更できると思うのですが、現状の実数の状態だと、bl_work を配列化する際に、結構な置換が必要になるのでは… と不安を感じました。
blike.c が bl_work に依存してるので、ドライバ側では bl_work をポインタとして書き換えることができないので困りました。
複数ウインドウを作る場合は bl_work の扱いはどうなる予定なのでしょうか?
それとも、将来にわたって複数ウインドウはサポートしないということなのでしょうか?
(グラフィック部分のみ)
http://blog-imgs-42.fc2.com/k/e/m/kemeconoajito/drvgtk03.png
blike.c は書き換えずに、drvwin32.c 以下のみを書き換えて、それで本当に動作するのか?
…を試すために書いたのですが、大方、動作するようです。
ドライバーを書いた際に、いくつか気づいた点、疑問点がありました。
ピクセル合成のモード? が、何を表してるのか分からないので、具体的な式による説明があるとありがたいです。
(ウインドウズにベッタリな処理なので、ブラックボックスで具体的な計算式がわからないので、移植にこまる)
たとえば「この合成モードでは (ピクセルA * ピクセルB) による乗算を行うことを期待している」みたいな具体的な説明をだれか補足してくれるとありがたいです。
各フラグの。
あと、bld_waitNF() に望んでる動作は、2ミリ秒スリープさせるってことでしょうか?
#define TIMER_INTERVAL 10
Sleep(TIMER_INTERVAL / 4);
この125Hz(2ミリ秒)を公式と考えなさいということですか?
当方windowsの実行環境が遠いので、実際のウインドウズ上で動作を試してなかったので誤解してたのですが、
printf の結果は、コンソールではなく、新しくウインドウ作って、そこに表示するみたいですが、
ならば、新規にウインドウを作る処理は、大多数のアプリケーションならば blmainの実行中に必ずあると考えて、
open window は必ず行うということにしてしまえばどうでしょうか?
(エコーのない cp コマンドを作る場合等は不要でしょうが、そういう例は稀だと思います。
大多数のアプリケーションでは、なんらかの文字や画像が情報として画面出力されるものだと思います。)
つまり、open window する関数を、ユーザーに任せずに、自動にしてしまえばどうでしょうか? (デフォルトサイズで)
あと、ユーザーがウインドウのサイズ変更をしたい場合には、open ではなく resize という名前を使った方が意味がわかりやすいと思うのですが。 resize window 的な名前の関数で。
あと、気になったのは、window の幅と高さを引数で受けとるとき、引数名が x y なのが奇妙に感じました。
最初混乱しました。(「デスクトップ上での初期表示座標か??」とか誤解して最初混乱しました)
幅と高さは w , h に変えた方がドライバー作る人に誤解が無くていいと思います。
あと、将来的にウインドウを複数作る場合に、おそらくウインドウ毎にスレッドを用意するのでしょうけど、その場合 bl_work を大域変数として、たった一個しか bl_work が無い状況は、複数ウインドウを開く場合に面倒なことになると思います。
将来的に、「複数ウインドウを開くことは考えてない」ということで、bl_work が(ポインタではなく実数での)大域変数なのですか?
たとえば bl_work をポインタとして用意してあれば、将来的に配列として扱うようにも簡単に変更できると思うのですが、現状の実数の状態だと、bl_work を配列化する際に、結構な置換が必要になるのでは… と不安を感じました。
blike.c が bl_work に依存してるので、ドライバ側では bl_work をポインタとして書き換えることができないので困りました。
複数ウインドウを作る場合は bl_work の扱いはどうなる予定なのでしょうか?
それとも、将来にわたって複数ウインドウはサポートしないということなのでしょうか?
とてもよい質問をありがとうございます。Linuxへの移植を試してもらえてとてもうれしいです。コンソール版のときも含めて、ありがとうございます。
まず複数ウィンドウですが、ご想像のとおり、サポートしません。マルチスレッドも考えていません。それらは初心者向きではないと僕は思うのです。
そういうことがやりたいと思えるころには、blikeではない、もっと汎用的なライブラリを使うべきだと僕は考えていて、だからblikeではそれらの汎用性をすべて切り捨てました。
もしかしたらblikeっぽいライブラリとして汎用的なblike+みたいな物があったらいいのかもしれません。僕はまだそこまでは手が回りませんが。
ウィンドウのサイズの変数名が微妙なのはごめんなさい。直すとしたら、xsizeとysizeにしたいです(趣味の問題です)。
openWinですが、今(バージョン01e)はこういう動作になっています。
・ウィンドウをオープンする前にprintfや描画系の関数を使った場合→blike側でopenWin(640,400);してやる(だからドライバから見ると、openなしに描画命令が来ることはないです)。
・openWin命令が来たとき、まだウィンドウをオープンしてなければ、openしてやる。既にオープンしていたら、(リサイズとかしたくなかったので)完全に無視する。
とりあえずウィンドウはデフォルトでオープンして、その後リサイズするのはどうかという件ですが、Linux版のドライバをそういう作り方にしてもらってもかまいません。実害は無いと思うので。
bld_waitNF() に望んでる動作は、そのOSにとって負荷が十分に下がる程度に休むということです。長く休みするぎると、wait()の精度が落ちます。でもあまり休まないと、CPU負荷が上がりすぎます。
blikeは暇なときにbld_waitNF()を含んだループをまわしながら、いろいろな状態変化を見張っているのです(イベントとか割り込みとかコールバックとかを使って実装するほうがスマートなのですが、OSによってはドライバが書きにくいかもしれないと思ったので)。
ピクセル合成のモードは、ドライバの開発者が気にしなくてもいいようになっています。全部blike側で面倒を見ます。
今夜までにはバージョン01eをアップロードするので、そのドライバを眺めてみてください。
まず複数ウィンドウですが、ご想像のとおり、サポートしません。マルチスレッドも考えていません。それらは初心者向きではないと僕は思うのです。
そういうことがやりたいと思えるころには、blikeではない、もっと汎用的なライブラリを使うべきだと僕は考えていて、だからblikeではそれらの汎用性をすべて切り捨てました。
もしかしたらblikeっぽいライブラリとして汎用的なblike+みたいな物があったらいいのかもしれません。僕はまだそこまでは手が回りませんが。
ウィンドウのサイズの変数名が微妙なのはごめんなさい。直すとしたら、xsizeとysizeにしたいです(趣味の問題です)。
openWinですが、今(バージョン01e)はこういう動作になっています。
・ウィンドウをオープンする前にprintfや描画系の関数を使った場合→blike側でopenWin(640,400);してやる(だからドライバから見ると、openなしに描画命令が来ることはないです)。
・openWin命令が来たとき、まだウィンドウをオープンしてなければ、openしてやる。既にオープンしていたら、(リサイズとかしたくなかったので)完全に無視する。
とりあえずウィンドウはデフォルトでオープンして、その後リサイズするのはどうかという件ですが、Linux版のドライバをそういう作り方にしてもらってもかまいません。実害は無いと思うので。
bld_waitNF() に望んでる動作は、そのOSにとって負荷が十分に下がる程度に休むということです。長く休みするぎると、wait()の精度が落ちます。でもあまり休まないと、CPU負荷が上がりすぎます。
blikeは暇なときにbld_waitNF()を含んだループをまわしながら、いろいろな状態変化を見張っているのです(イベントとか割り込みとかコールバックとかを使って実装するほうがスマートなのですが、OSによってはドライバが書きにくいかもしれないと思ったので)。
ピクセル合成のモードは、ドライバの開発者が気にしなくてもいいようになっています。全部blike側で面倒を見ます。
今夜までにはバージョン01eをアップロードするので、そのドライバを眺めてみてください。
眺めてみました。
なぜbl_workを、直接アクセス可能な状態のまま、周囲を作り込んでしまってるんですか?
bl_workは、根本的に複数スレッドからアクセスされると想定するべきでは? と思うのですが。
すなわち、
bl_work へアクセスするためのインターフェースを用意し、
bl_work の排他制御を徹底する(基本的に直接書き込みは禁じ手とする)。 これをすべてのbl_workに対するアクセスで徹底すれば、lockもunlockも不要ではありませんか?
これを、なぜやらないんですか? 効率ですか?
(そもそも、key[]に関しては、なぜ配列なのですか? 配列でlock unlockなのですか? リングバッファーにすればいいだけのことじゃないですか。)
bl_workに対して、”書き込み読み込みの、許可フラグ”を用いずに、bl_workに「どのスレッドも、勝手なタイミングで自由に」アクセスできてしまう設計は、
そもそも複数スレッドの元で使われる共有変数の実装としては、あまりにも自由過ぎます。危なっかしいです。
正直な話、
bl_workへの、読み込み書き込みの排他制御が保証されてないが為に、
ドライバー側としても、じつに組みづらい設計だと感じます。(bl_workへ書き込むタイミングを計るという点で、じつに余計な神経を使わされます。)
他のスレッドの動作を能動的に止めたり動かしたりする、そんなことを一々手動で行わなければ安全に読み書きできない現状の bl_work は、
やはり設計として、根本的に稚拙だと思います。
素朴な疑問なのですが、
なぜbl_workを、こんなシングルスレッドみたいなやりかたでアクセスする設計にしてるんですか?
なぜbl_workを、直接アクセス可能な状態のまま、周囲を作り込んでしまってるんですか?
bl_workは、根本的に複数スレッドからアクセスされると想定するべきでは? と思うのですが。
すなわち、
bl_work へアクセスするためのインターフェースを用意し、
bl_work の排他制御を徹底する(基本的に直接書き込みは禁じ手とする)。 これをすべてのbl_workに対するアクセスで徹底すれば、lockもunlockも不要ではありませんか?
これを、なぜやらないんですか? 効率ですか?
(そもそも、key[]に関しては、なぜ配列なのですか? 配列でlock unlockなのですか? リングバッファーにすればいいだけのことじゃないですか。)
bl_workに対して、”書き込み読み込みの、許可フラグ”を用いずに、bl_workに「どのスレッドも、勝手なタイミングで自由に」アクセスできてしまう設計は、
そもそも複数スレッドの元で使われる共有変数の実装としては、あまりにも自由過ぎます。危なっかしいです。
正直な話、
bl_workへの、読み込み書き込みの排他制御が保証されてないが為に、
ドライバー側としても、じつに組みづらい設計だと感じます。(bl_workへ書き込むタイミングを計るという点で、じつに余計な神経を使わされます。)
他のスレッドの動作を能動的に止めたり動かしたりする、そんなことを一々手動で行わなければ安全に読み書きできない現状の bl_work は、
やはり設計として、根本的に稚拙だと思います。
素朴な疑問なのですが、
なぜbl_workを、こんなシングルスレッドみたいなやりかたでアクセスする設計にしてるんですか?
もともとはマルチスレッドでのアプリもドライバも想定していなかったせいです。それだけのことです。
そしてkbuf系だけ、lock/unlockになっています。ただしkbufは既にリングバッファにはなっています。しかしリングバッファであっても、lock/unlockは必要です。もちろんそれはアクセス関数で隠せますが。
ついこの間までのバージョンまでlock/unlockは存在せず、本当に完全にシングルスレッド用になっていました。しかしwin32版のキー入力周りを作っているうちに、マルチスレッドで書くことになり、キーバッファ周りを「急遽」lock/unlockではさむことになりました。
以上が「なぜ現状がこうなっているのか」の解答です。
それで、このままでいいのかということですが、もちろんよくないです。それはkemeppoさんのいうとおりです。
僕としては、現状はアプリプログラマ向けにどういう入出力関数を提供するべきかを試行錯誤している段階で、そのためにどういうドライバ関数のセットにするべきかは検討できていません。ドライバ向けの仕様は頻繁に変わる可能性が高いです。描画関数も信じられないくらい非効率に書かれている部分がたくさんあります。高速化も後回しになっているのです。
僕は今はこんな感じですと途中の状態を公開しているだけなので、今から完全なものを期待されてもそれには応えられません。すべて出来上がるまで何も公開しないこともできますが、それでは進んでいるのかいないのか、何をしようとしているのか、それを推測することもできません。
とりあえず、マルチスレッド前提のbl_workへのアクセス関数をそろえておいたほうがドライバが書きやすいと思う、というkemeppoさんのアドバイスは、ありがたく賜りました。たぶん最終的にはそのとおりにすると思います。
ちなみにアプリ側についてはマルチスレッドを最後まで想定しないと思います。それだけの記述力があるユーザはこのライブラリを必要としないと思いますし、対応OSにマルチスレッドのサポートを要求すると、多くの自作OS系でサポートできなくなってしまうからです。
そしてkbuf系だけ、lock/unlockになっています。ただしkbufは既にリングバッファにはなっています。しかしリングバッファであっても、lock/unlockは必要です。もちろんそれはアクセス関数で隠せますが。
ついこの間までのバージョンまでlock/unlockは存在せず、本当に完全にシングルスレッド用になっていました。しかしwin32版のキー入力周りを作っているうちに、マルチスレッドで書くことになり、キーバッファ周りを「急遽」lock/unlockではさむことになりました。
以上が「なぜ現状がこうなっているのか」の解答です。
それで、このままでいいのかということですが、もちろんよくないです。それはkemeppoさんのいうとおりです。
僕としては、現状はアプリプログラマ向けにどういう入出力関数を提供するべきかを試行錯誤している段階で、そのためにどういうドライバ関数のセットにするべきかは検討できていません。ドライバ向けの仕様は頻繁に変わる可能性が高いです。描画関数も信じられないくらい非効率に書かれている部分がたくさんあります。高速化も後回しになっているのです。
僕は今はこんな感じですと途中の状態を公開しているだけなので、今から完全なものを期待されてもそれには応えられません。すべて出来上がるまで何も公開しないこともできますが、それでは進んでいるのかいないのか、何をしようとしているのか、それを推測することもできません。
とりあえず、マルチスレッド前提のbl_workへのアクセス関数をそろえておいたほうがドライバが書きやすいと思う、というkemeppoさんのアドバイスは、ありがたく賜りました。たぶん最終的にはそのとおりにすると思います。
ちなみにアプリ側についてはマルチスレッドを最後まで想定しないと思います。それだけの記述力があるユーザはこのライブラリを必要としないと思いますし、対応OSにマルチスレッドのサポートを要求すると、多くの自作OS系でサポートできなくなってしまうからです。
gtk+2というライブラリーというものを用いて、某windows用ライブラリーのドライバー部分を、
ubuntu10.10上でも動作するように移植を試みてみました。
””” 動作テストをお願いしたいのですが、お願いできますでしょうか? ”””
当方の環境(cpu:core2, memory:2G, graphic:intel G45オンボード)環境では動作確認したのですが、
他の環境では動くかどうか不安です。
手順:
git と libgtk2.0-dev のインストール
sudo apt-get install git libgtk2.0-dev
ソースファイルのダウンロード
git clone git://git.pf.sourceforge.jp/gitroot/k/ke/kemeco/c_blike_01e_linux.git
コンパイル
cd ./c_blike_01e_linux/samples
./build.sh
コンパイルが成功すれば、./c_blike_01e_linux/samples ディレクトリーに、20個程度のサンプルプログラムができあがってるので、
実行できるか、動くかどうか? など、試してほしいです。
もしも動いた場合、もしくは、動かなかった場合、また、なにかバグがあった場合など、なにか報告してくれるとありがたいです。
(24bitグラフィックを前提に、ピクセルが LSB 側から RGBRGBRGB...... と扱われることを前提に決め打ちしてしまってるので、
もしかしたら、そのあたりでグラフィック表示にバグが出るかも…と思ったので。)
ソフトのライセンスは、ドライバー部分(./c_blike_01e_linux/lib_src/gtk以下)は、LGPL とします(gtk+2がLGPLなので)。 それ以外はたぶんKL-01だと思います。
ubuntu10.10上でも動作するように移植を試みてみました。
””” 動作テストをお願いしたいのですが、お願いできますでしょうか? ”””
当方の環境(cpu:core2, memory:2G, graphic:intel G45オンボード)環境では動作確認したのですが、
他の環境では動くかどうか不安です。
手順:
git と libgtk2.0-dev のインストール
sudo apt-get install git libgtk2.0-dev
ソースファイルのダウンロード
git clone git://git.pf.sourceforge.jp/gitroot/k/ke/kemeco/c_blike_01e_linux.git
コンパイル
cd ./c_blike_01e_linux/samples
./build.sh
コンパイルが成功すれば、./c_blike_01e_linux/samples ディレクトリーに、20個程度のサンプルプログラムができあがってるので、
実行できるか、動くかどうか? など、試してほしいです。
もしも動いた場合、もしくは、動かなかった場合、また、なにかバグがあった場合など、なにか報告してくれるとありがたいです。
(24bitグラフィックを前提に、ピクセルが LSB 側から RGBRGBRGB...... と扱われることを前提に決め打ちしてしまってるので、
もしかしたら、そのあたりでグラフィック表示にバグが出るかも…と思ったので。)
ソフトのライセンスは、ドライバー部分(./c_blike_01e_linux/lib_src/gtk以下)は、LGPL とします(gtk+2がLGPLなので)。 それ以外はたぶんKL-01だと思います。
>>21
いま>>20を読み返してみたら、けっこうキツい言い方をしてしまってて、反省してます。申し訳ないです。
急造ってのは、わかってたんですけど、ついついキツいことを言ってしまいました。(この掲示板、ログインして書き込みしてすら、発言の訂正させてくれないから困る)
さて、
キーバッファーの関数を確認してみたのですが、 おそらくバッファーとして連携して動く一連のグループは
int *key, key_wp, key_rp, key_c
の4っつで、おそらく
key[] : キーバッファー配列(インデックスの計算にビットマスク使ってる関係で、2の倍数長さになってる(現状8192))
key_c : 入力個数???
key_rp : リードポイント。 読む時の key[] 配列上のインデックス
key_wp : ライトポイント。 書く時の・・・・・・
だと思いました。
で、ドライバー側としては bld_input() だかで初期化したりすることを提供することになってるみたいですが、
ここのドライバー関数側から、BLIKE側関数(bl_...())を呼び出すのは設計として・・・ って、いや、すみません、急造ですから仕方ないですよね。(また>>20みたいなノリになってしまうところだった・・・ 自重
キー周りは、今後のバージョンで、設計として洗練されるでしょうから、01f以降の設計を期待して待ってます。
ところで、キーとは別に、フォントに関してですが、
./lib_src/common
のblikeのコアソースにて、hankaku.obj というバイナリを、コンパイル時にリンクする形で、 グローバル変数 unsigned char hankaku[4096] を提供してる(???)みたいですが、
これって、もろ、バイナリーですよね・・・ hankakku.obj って。 これ、なんとかしてテキストとかXMLでも何でもいいですけど、なんとかして「人間の読める形式」で提供できないものでしょうか・・・
あと、現状、commonのblikeコアに、埋め込む形でフォントを持たせてますけど、
本来、フォントのようなものは、共有ファイルとして、「フォントファイルを読み込んで使う」って形にした方が、自然だとおm・・・って、まぁまだベータ版なので、細かいこと言ってもしょうがないですよね。 すみません。 気になったので。
一応、気になったので、当方のドライバーでは、bld_initFont()だかでの”最初”の初期化の際に、フォントファイル hankaku.font を読み込んで、それを hankaku[] 配列に読み込むように変更してありますが・・・
(hankaku.font は hankaku.obj そのもの。 つまりバイナリですが、本当はxpmあたりの(人間が読めるテキスト形式)の画像ファイルにしたらいいとおもってます・・・なぜならプログラマーがエディターで読めるから)
(というか、読み込みの段階で1次元に変換するけど、データファイルの段階では、人間が(デザイナーが)普通にグラフィックソフトで修正したりできるような、普通の画像形式(xpmとか)がいいような気がします…オリジナルフォントとかにも簡単に差し替えられるでしょうし。)
余談:
c_blike_01e_linux でのドライバーには、 key に燗する部分を、いろいろ思うところあって実装してません。(今後、仕様が変わると思いますし)
でも、ドライバーとして提供してないだけで、ドライバー内部ではキーを扱うコードが動いてるので、おまけ機能として、キーボードの a を押すと、ウインドウが終了するようになってます。(動作確認作業とかが、ちょっと楽なように)
余談2:
「keyアクセスに関して、lockとunlockを不要にする方法があるのではないか?」と思い、試しにコードを書いてみました。
http://codepad.org/oELcvc0T
コンパイル方法 gcc -o a main.c -lpthread
コード詳細:
2つのスレッド(Blike側と、ドライバー側をイメージして)を動かして、これらスレッドが適当なタイミングで、共有メモリに書き込みと、読み込みをくりかえしますが、
この際に、key_rp と key_wp に相当する部分(インデックス部分)を操作するタイミングを、「データの書き込み後」にし、かつ、読み込み側・書き込み側として、スレッドの役割を限定すれば、
Blike側スレッドと、ドライバー側スレッドとの共有メモリへのIOについて、タイミングを(lock unlockなどで)調整しなくても整合性を保ったままIO可能な気がするのです。
いま>>20を読み返してみたら、けっこうキツい言い方をしてしまってて、反省してます。申し訳ないです。
急造ってのは、わかってたんですけど、ついついキツいことを言ってしまいました。(この掲示板、ログインして書き込みしてすら、発言の訂正させてくれないから困る)
さて、
キーバッファーの関数を確認してみたのですが、 おそらくバッファーとして連携して動く一連のグループは
int *key, key_wp, key_rp, key_c
の4っつで、おそらく
key[] : キーバッファー配列(インデックスの計算にビットマスク使ってる関係で、2の倍数長さになってる(現状8192))
key_c : 入力個数???
key_rp : リードポイント。 読む時の key[] 配列上のインデックス
key_wp : ライトポイント。 書く時の・・・・・・
だと思いました。
で、ドライバー側としては bld_input() だかで初期化したりすることを提供することになってるみたいですが、
ここのドライバー関数側から、BLIKE側関数(bl_...())を呼び出すのは設計として・・・ って、いや、すみません、急造ですから仕方ないですよね。(また>>20みたいなノリになってしまうところだった・・・ 自重
キー周りは、今後のバージョンで、設計として洗練されるでしょうから、01f以降の設計を期待して待ってます。
ところで、キーとは別に、フォントに関してですが、
./lib_src/common
のblikeのコアソースにて、hankaku.obj というバイナリを、コンパイル時にリンクする形で、 グローバル変数 unsigned char hankaku[4096] を提供してる(???)みたいですが、
これって、もろ、バイナリーですよね・・・ hankakku.obj って。 これ、なんとかしてテキストとかXMLでも何でもいいですけど、なんとかして「人間の読める形式」で提供できないものでしょうか・・・
あと、現状、commonのblikeコアに、埋め込む形でフォントを持たせてますけど、
本来、フォントのようなものは、共有ファイルとして、「フォントファイルを読み込んで使う」って形にした方が、自然だとおm・・・って、まぁまだベータ版なので、細かいこと言ってもしょうがないですよね。 すみません。 気になったので。
一応、気になったので、当方のドライバーでは、bld_initFont()だかでの”最初”の初期化の際に、フォントファイル hankaku.font を読み込んで、それを hankaku[] 配列に読み込むように変更してありますが・・・
(hankaku.font は hankaku.obj そのもの。 つまりバイナリですが、本当はxpmあたりの(人間が読めるテキスト形式)の画像ファイルにしたらいいとおもってます・・・なぜならプログラマーがエディターで読めるから)
(というか、読み込みの段階で1次元に変換するけど、データファイルの段階では、人間が(デザイナーが)普通にグラフィックソフトで修正したりできるような、普通の画像形式(xpmとか)がいいような気がします…オリジナルフォントとかにも簡単に差し替えられるでしょうし。)
余談:
c_blike_01e_linux でのドライバーには、 key に燗する部分を、いろいろ思うところあって実装してません。(今後、仕様が変わると思いますし)
でも、ドライバーとして提供してないだけで、ドライバー内部ではキーを扱うコードが動いてるので、おまけ機能として、キーボードの a を押すと、ウインドウが終了するようになってます。(動作確認作業とかが、ちょっと楽なように)
余談2:
「keyアクセスに関して、lockとunlockを不要にする方法があるのではないか?」と思い、試しにコードを書いてみました。
http://codepad.org/oELcvc0T
コンパイル方法 gcc -o a main.c -lpthread
コード詳細:
2つのスレッド(Blike側と、ドライバー側をイメージして)を動かして、これらスレッドが適当なタイミングで、共有メモリに書き込みと、読み込みをくりかえしますが、
この際に、key_rp と key_wp に相当する部分(インデックス部分)を操作するタイミングを、「データの書き込み後」にし、かつ、読み込み側・書き込み側として、スレッドの役割を限定すれば、
Blike側スレッドと、ドライバー側スレッドとの共有メモリへのIOについて、タイミングを(lock unlockなどで)調整しなくても整合性を保ったままIO可能な気がするのです。
お返事です。
Linux版ありがとうございます。僕は今はLinux環境を準備していないのでまだ試せません。でもそのうち試してみたいです。
きっとそのうち僕以外の誰かが先に試してくれるとは思います。
lockの件ですが、Windowsではキー入力のたびにコールバック関数が呼ばれるようになっていて、これはどういうタイミングで呼ぶことを保証しているのかまだいまいち分かっていません。つまり、kbufへの書き込みスレッド数は1とは限らないのです。読み込み側は1スレッドしかないことをあてにできると思うのですが。
そんなわけで、win32では書き込み側はやっぱりlock/unlockが必要そうに思いますし、もしかしたら他にもそういうOSが出てくるかもしれないので、blikeとしてはkbuf関連に限りlockを使っていこうと思っています。
ドライバ開発者向けのドキュメントも書き始めたので、少しずつ変なところを直していきたいです(変な仕様をそのままドキュメントにするのはできれば避けたいので)。
Linux版ありがとうございます。僕は今はLinux環境を準備していないのでまだ試せません。でもそのうち試してみたいです。
きっとそのうち僕以外の誰かが先に試してくれるとは思います。
lockの件ですが、Windowsではキー入力のたびにコールバック関数が呼ばれるようになっていて、これはどういうタイミングで呼ぶことを保証しているのかまだいまいち分かっていません。つまり、kbufへの書き込みスレッド数は1とは限らないのです。読み込み側は1スレッドしかないことをあてにできると思うのですが。
そんなわけで、win32では書き込み側はやっぱりlock/unlockが必要そうに思いますし、もしかしたら他にもそういうOSが出てくるかもしれないので、blikeとしてはkbuf関連に限りlockを使っていこうと思っています。
ドライバ開発者向けのドキュメントも書き始めたので、少しずつ変なところを直していきたいです(変な仕様をそのままドキュメントにするのはできれば避けたいので)。
ubuntu11.04上で動くようにドライバー書きました。
http://sourceforge.jp/users/kemeco/pf/c_blike_01f_linux/
ソースの入手は
git clone git://git.pf.sourceforge.jp/gitroot/k/ke/kemeco/c_blike_01f_linux.git
カレントディレクトリー以下に c_blike_01f_linux というディレクトリーがダウンロードされます。
ライブラリー及び、サンプルコードのビルドは
cd c_blike_01f_linux
cd sample
./build.sh
です
lock,unlockに対応してないので、あとで対応するように書きなおそうと思います。(現状、blike側のコードを少し書き換えてしまってます。純粋なc_bleke_01fではありません。)
もしくは誰かパッチ書いてくれるとありがたいです。
あと余談ですけどc_blike_01のダウンロードページが、googleで検索したら危険なページだと表示されました。
http://sourceforge.jp/users/kemeco/pf/c_blike_01f_linux/
ソースの入手は
git clone git://git.pf.sourceforge.jp/gitroot/k/ke/kemeco/c_blike_01f_linux.git
カレントディレクトリー以下に c_blike_01f_linux というディレクトリーがダウンロードされます。
ライブラリー及び、サンプルコードのビルドは
cd c_blike_01f_linux
cd sample
./build.sh
です
lock,unlockに対応してないので、あとで対応するように書きなおそうと思います。(現状、blike側のコードを少し書き換えてしまってます。純粋なc_bleke_01fではありません。)
もしくは誰かパッチ書いてくれるとありがたいです。
あと余談ですけどc_blike_01のダウンロードページが、googleで検索したら危険なページだと表示されました。
GIMPなどで出力できる.xpm形式の画像ファイルを、c_blike_01e以降で読み込むための関数を書きました。
http://sourceforge.jp/users/kemeco/pf/bl_load_xpm/
ソースの入手は
git clone git://git.pf.sourceforge.jp/gitroot/k/ke/kemeco/bl_load_xpm.git
コンパイルするソースファイルと一緒に bl_load_xpm.c と xpm画像ファイルをいっしょにコンパイルしてリンクすれば使えます。
(.xpm画像ファイルは、中身はCに似たソースファイルで、配列として宣言されてる)
使用方法は、ソースファイル内で
extern void bl_load_xpm(char** xpm_str, int x, int y);
として宣言し、
bl_load_xpm(xpm画像を表す配列の先頭アドレス, X座標, Y座標);
です。
(test_bl_load_xpm.c はサンプルコードです)
http://sourceforge.jp/users/kemeco/pf/bl_load_xpm/
ソースの入手は
git clone git://git.pf.sourceforge.jp/gitroot/k/ke/kemeco/bl_load_xpm.git
コンパイルするソースファイルと一緒に bl_load_xpm.c と xpm画像ファイルをいっしょにコンパイルしてリンクすれば使えます。
(.xpm画像ファイルは、中身はCに似たソースファイルで、配列として宣言されてる)
使用方法は、ソースファイル内で
extern void bl_load_xpm(char** xpm_str, int x, int y);
として宣言し、
bl_load_xpm(xpm画像を表す配列の先頭アドレス, X座標, Y座標);
です。
(test_bl_load_xpm.c はサンプルコードです)
test008a.cのバーの動きをキーリピート非依存にしました。http://codepad.org/kfYsZLj9
キーを離した場合にbl_inkey(BL_GETKEY)で4095が返ってくるのですが、
その4095が、何のキーを離した結果の4095かを判断する方法がわかりません。
たとえば A を押し続けてる状態で B を押し、
A, B の順で離した場合は 4095, 4095 となり、
B, A の順で離した場合も 4095, 4095 となり、見分けがつきません。
また、
A のみを離した場合は 4095 で
B のみを離した場合も 4095 なので、どちらか一方を離した場合も、そのボタンの見分けがつきません。
つまり、
A を押したまま B を連打した場合と、
A, B を交互に連打した場合と、
A, B を押したまま C を連打した場合とで現れる 4095 に関して、
どのボタンに対応した 4095 かを判断する方法がわからないので、
たとえば「右に歩き続けながらジャンプボタンを押した場合」に、ジャンプボタンの結果の4095なのか、右キーを離した結果の4095なのかを見分ける方法がわかりません。
なにか良い方法はないでしょうか。
キーを離した場合にbl_inkey(BL_GETKEY)で4095が返ってくるのですが、
その4095が、何のキーを離した結果の4095かを判断する方法がわかりません。
たとえば A を押し続けてる状態で B を押し、
A, B の順で離した場合は 4095, 4095 となり、
B, A の順で離した場合も 4095, 4095 となり、見分けがつきません。
また、
A のみを離した場合は 4095 で
B のみを離した場合も 4095 なので、どちらか一方を離した場合も、そのボタンの見分けがつきません。
つまり、
A を押したまま B を連打した場合と、
A, B を交互に連打した場合と、
A, B を押したまま C を連打した場合とで現れる 4095 に関して、
どのボタンに対応した 4095 かを判断する方法がわからないので、
たとえば「右に歩き続けながらジャンプボタンを押した場合」に、ジャンプボタンの結果の4095なのか、右キーを離した結果の4095なのかを見分ける方法がわかりません。
なにか良い方法はないでしょうか。
久しぶりに出てきてすみません。
ええとつまり、どのキーを離したのかを取得できるようになりたいわけですよね。そういう拡張モードを手元の仕様では考えていますが、win32版のドライバがぜんぜんうまくいかなくて、棚上げになっています(時々変なWM_KEYUPが来るので)。
4095はキーを連打したのかリピートだったのかの区別に内部的に(ドライバが)使っているだけで、本来はアプリが取得して制御に使うべきコードではありません。まあ使いたければ使ってもいいですが、そのアプリは他のOS上では満足には動かないかもしれません。
ご期待に添えない回答ですみません。
ええとつまり、どのキーを離したのかを取得できるようになりたいわけですよね。そういう拡張モードを手元の仕様では考えていますが、win32版のドライバがぜんぜんうまくいかなくて、棚上げになっています(時々変なWM_KEYUPが来るので)。
4095はキーを連打したのかリピートだったのかの区別に内部的に(ドライバが)使っているだけで、本来はアプリが取得して制御に使うべきコードではありません。まあ使いたければ使ってもいいですが、そのアプリは他のOS上では満足には動かないかもしれません。
ご期待に添えない回答ですみません。
linux(gtk+2)で動くc_blike_01f_linux に、
>>30,31の件の解決策として、キーボード状態の読み取りをドライバーの機能で提供してはどうか?と思い、
試しに実装してみました。
ダウンロードは
http://sourceforge.jp/downloads/users/0/320/c_blike_01f_linux_20110704.zip
またはgitで
git clone git://git.pf.sourceforge.jp/gitroot/k/ke/kemeco/c_blike_01f_linux.git
です。
sample ディレクトリに移動し、
./build.sh でサンプルコードなどのコンパイルが行われます。
./test_keybord_state
が追加した機能(キーボード状態読み取り)のサンプルです。
あと、それとは別に酔狂で bl3d という3D関係のライブラリを書きました。
任意の裏画面に読み込んだ画像を、テクスチャーマッピングした三角形をグローシェーディングで描画します。
サンプルコードは ./test_bl3d_triangle です。
また、それとは別に、以前作ってたxpm画像の読み込みライブラリーも c_blike_01f_linux のツリーに追加しました。
(テクスチャーを読み込むのに便利だったので)
全体的にライブラリーを、gtk+2のみに依存するコードに書き換えたので、もしかしたらwindows上のmingwなどでも、
gtk+2 ライブラリーをリンクしてコンパイルできるかもしれません。
当方ウインドウズ環境が無いので試せませんが、誰かコンパイルできるか試してくれれば高栄です。
(hello world くらいなら、なんとか動けばいいなと期待してます…)
>>30,31の件の解決策として、キーボード状態の読み取りをドライバーの機能で提供してはどうか?と思い、
試しに実装してみました。
ダウンロードは
http://sourceforge.jp/downloads/users/0/320/c_blike_01f_linux_20110704.zip
またはgitで
git clone git://git.pf.sourceforge.jp/gitroot/k/ke/kemeco/c_blike_01f_linux.git
です。
sample ディレクトリに移動し、
./build.sh でサンプルコードなどのコンパイルが行われます。
./test_keybord_state
が追加した機能(キーボード状態読み取り)のサンプルです。
あと、それとは別に酔狂で bl3d という3D関係のライブラリを書きました。
任意の裏画面に読み込んだ画像を、テクスチャーマッピングした三角形をグローシェーディングで描画します。
サンプルコードは ./test_bl3d_triangle です。
また、それとは別に、以前作ってたxpm画像の読み込みライブラリーも c_blike_01f_linux のツリーに追加しました。
(テクスチャーを読み込むのに便利だったので)
全体的にライブラリーを、gtk+2のみに依存するコードに書き換えたので、もしかしたらwindows上のmingwなどでも、
gtk+2 ライブラリーをリンクしてコンパイルできるかもしれません。
当方ウインドウズ環境が無いので試せませんが、誰かコンパイルできるか試してくれれば高栄です。
(hello world くらいなら、なんとか動けばいいなと期待してます…)
osaskのk氏のblike上の「画面に点を打つ」という機能を使って、3Dポリゴンを表示するライブラリーを書いてみました。
スクリーンショット
ttp://blog-imgs-42-origin.fc2.com/k/e/m/kemeconoajito/bl3d20110707.jpg
ソースコードはgitで管理してるので、直接クローンしてダウンロードすれば簡単だと思います。また、zipでも上げときました。
http://sourceforge.jp/users/kemeco/pf/c_blike_01f_linux/
あと、ウインドウズ用にコンパイルしたバイナリ-と、
ソースコードと、コンパイル用のバッチファイルのセットです。
http://sourceforge.jp/downloads/users/0/330/bl3d_cube.zip/
当方、ウインドウズは、ウインドウズ2000しか持ってないので、このバイナリ-が最新のウィンドウズ上で動くかはわかりませんが、
このディレクトリーをk氏オリジナルの c_blike_01f の./sampleディレクトリーに置いて、build.bat を実行すれば、
コンパイルならできるかもしれません。
(注意:当方の mingw のインストールディレクトリーは c:\minguなので、gccおよびarのパスがそこに決め打ちしてあります。
mingwを c:\program files\mingw などにインストールしてる方は、build.bat内のパスを書き換えないとコンパイルできないかもしれません)
bl3d_cube.exe は、例の猫をテクスチャーマッピングしたサイコロを表示します。
操作方法は jk hl um で、たしかキューブのxyz回転ができたような記憶です。(忘れた)
bl3d_cube2.exe は、重力の方向がX,Y,Zで変化する中で、例の猫のキューブが複数動く光景を観察するデモです。
操作方法:
視点の平行移動(shiftを押しながらだと回転操作)
j,k: 視点のY軸上での移動
h,l: 同X軸
u,m: 同Z軸
視点モードの変更
1: 通常の視点。
2: 追跡視点。1個目のキューブをカメラが追跡します。
(なるべく画面の中心に映すするように、カメラ角度が自動的に操作される)
キューブ数の増減
i, d: キューブ数を増やしたり、減らしたりします。(最大300個まで)
当方のcore2ペンティアム,2.4GHz環境では、
500個表示した状態でも、あまり処理落ちせずに60フレームで表示できてます。(ただし描画ピクセル数が増えると厳しいです)
1キューブは12ポリゴンで構成されるので、
12 * 500 * 60フレーム = 秒間約36万ポリゴン。
実際にはピクセル描画されないポリゴンも結構あるのですが、
頂点ジオメトリだけで考えれば、36万程度は全然余裕みたいです。
(テクスチャー&光源計算&グラデーション)
ただ、blikeはVRAM描画のボトルネックが小さくはないので、
各ポリゴンの表示サイズが大きくなった際にVRAMへのピクセル描画量が増えると、
最悪、数ポリゴン程度でも60フレームが不可能になってしまいます。
希望:
blikeのVRAM描画を、超高速で行う関数を、
setPix()などとは別に用意してくれるとありがたいです。
もしくはVRAMの配列を直接扱うことを、許可してくれるとありがたいです。
つまりヘッダーで変数名を公開するなどによって、公式に使用を許可してくれるとありがたいです。
あと、blikeで公式に sin cos sqrt log や asin acos atan2 などを用意してくれると、安心して使えていいと思います。
(
たとえば bl_sin(a) {return sin(a)} みたいなのでもいいので、公式に許可してくれれば安心して使えるのですが、
現状はsin()などは公式に使用を許可されてない状態なので不安です。
(
kcubeでsin()が使用されてるから、「公式に、使ってもいい事になってる…のかも…しれない??」という認識です。現状
bl_sin()などを用意して、公式に使用を許可してくれれば、いろいろ安心なのですが…
)
)
スクリーンショット
ttp://blog-imgs-42-origin.fc2.com/k/e/m/kemeconoajito/bl3d20110707.jpg
ソースコードはgitで管理してるので、直接クローンしてダウンロードすれば簡単だと思います。また、zipでも上げときました。
http://sourceforge.jp/users/kemeco/pf/c_blike_01f_linux/
あと、ウインドウズ用にコンパイルしたバイナリ-と、
ソースコードと、コンパイル用のバッチファイルのセットです。
http://sourceforge.jp/downloads/users/0/330/bl3d_cube.zip/
当方、ウインドウズは、ウインドウズ2000しか持ってないので、このバイナリ-が最新のウィンドウズ上で動くかはわかりませんが、
このディレクトリーをk氏オリジナルの c_blike_01f の./sampleディレクトリーに置いて、build.bat を実行すれば、
コンパイルならできるかもしれません。
(注意:当方の mingw のインストールディレクトリーは c:\minguなので、gccおよびarのパスがそこに決め打ちしてあります。
mingwを c:\program files\mingw などにインストールしてる方は、build.bat内のパスを書き換えないとコンパイルできないかもしれません)
bl3d_cube.exe は、例の猫をテクスチャーマッピングしたサイコロを表示します。
操作方法は jk hl um で、たしかキューブのxyz回転ができたような記憶です。(忘れた)
bl3d_cube2.exe は、重力の方向がX,Y,Zで変化する中で、例の猫のキューブが複数動く光景を観察するデモです。
操作方法:
視点の平行移動(shiftを押しながらだと回転操作)
j,k: 視点のY軸上での移動
h,l: 同X軸
u,m: 同Z軸
視点モードの変更
1: 通常の視点。
2: 追跡視点。1個目のキューブをカメラが追跡します。
(なるべく画面の中心に映すするように、カメラ角度が自動的に操作される)
キューブ数の増減
i, d: キューブ数を増やしたり、減らしたりします。(最大300個まで)
当方のcore2ペンティアム,2.4GHz環境では、
500個表示した状態でも、あまり処理落ちせずに60フレームで表示できてます。(ただし描画ピクセル数が増えると厳しいです)
1キューブは12ポリゴンで構成されるので、
12 * 500 * 60フレーム = 秒間約36万ポリゴン。
実際にはピクセル描画されないポリゴンも結構あるのですが、
頂点ジオメトリだけで考えれば、36万程度は全然余裕みたいです。
(テクスチャー&光源計算&グラデーション)
ただ、blikeはVRAM描画のボトルネックが小さくはないので、
各ポリゴンの表示サイズが大きくなった際にVRAMへのピクセル描画量が増えると、
最悪、数ポリゴン程度でも60フレームが不可能になってしまいます。
希望:
blikeのVRAM描画を、超高速で行う関数を、
setPix()などとは別に用意してくれるとありがたいです。
もしくはVRAMの配列を直接扱うことを、許可してくれるとありがたいです。
つまりヘッダーで変数名を公開するなどによって、公式に使用を許可してくれるとありがたいです。
あと、blikeで公式に sin cos sqrt log や asin acos atan2 などを用意してくれると、安心して使えていいと思います。
(
たとえば bl_sin(a) {return sin(a)} みたいなのでもいいので、公式に許可してくれれば安心して使えるのですが、
現状はsin()などは公式に使用を許可されてない状態なので不安です。
(
kcubeでsin()が使用されてるから、「公式に、使ってもいい事になってる…のかも…しれない??」という認識です。現状
bl_sin()などを用意して、公式に使用を許可してくれれば、いろいろ安心なのですが…
)
)
いつもありがとうございます。とてもきれいですね。
sinやcosなどは、標準関数に入っているものをそのまま使えばいいかなーと安易に考えていたのですが、bl_化したほうが安心ですか・・・確かにそうかもしれません。
もともとC言語の教育用に考えていたので、標準関数でできることは標準関数でやったほうがいいかなと思っていました。グラフィックが標準関数の範囲の外なので、それだけをblikeに背負わせようと思っていたのです。しかし別にbl_sin()があっても教材として教えるときは使わなければいいだけなので、kemeppoさんのような人の安心のためにつけるというのは反対ではありません。前向きに検討します。
ウィンドウのイメージデータへの直接アクセスを許すかどうかは悩み中です。ドライバが作りにくくなったらどうしようとか心配しているわけですが、これはもう少し悩ませてください。
sinやcosなどは、標準関数に入っているものをそのまま使えばいいかなーと安易に考えていたのですが、bl_化したほうが安心ですか・・・確かにそうかもしれません。
もともとC言語の教育用に考えていたので、標準関数でできることは標準関数でやったほうがいいかなと思っていました。グラフィックが標準関数の範囲の外なので、それだけをblikeに背負わせようと思っていたのです。しかし別にbl_sin()があっても教材として教えるときは使わなければいいだけなので、kemeppoさんのような人の安心のためにつけるというのは反対ではありません。前向きに検討します。
ウィンドウのイメージデータへの直接アクセスを許すかどうかは悩み中です。ドライバが作りにくくなったらどうしようとか心配しているわけですが、これはもう少し悩ませてください。
>>ウィンドウのイメージデータへの直接アクセスを許すかどうかは悩み中です。ドライバが作りにくくなったらどうしようとか心配しているわけですが、これはもう少し悩ませてください。
ウインドウのイメージデータと言っても、直接ドライバー側のウインドウが持つフレームバッファーに直接書くことは要求してません。
もしそれをblMain()から許可してしまえば、カラー形式は様々なので、途端にblMain()ソースの移植性が失われてしまいます。
(24bit,0xBBGGRR形式を前提に直接あつかえば、そのblMain()コードは32bit,0x00RRGGBB環境では当然正常に表示されませんし、移植性に問題が生じてしまう)
そうではなく、commonの扱うレベルのフレームバッファーへの直接アクセスを言ってます。
ここは32bit,0x00RRGGBB形式で固定なので、直接アクセスを許してもblMain()の移植性に問題は生じないと思います。
bld_内の、まさにウインドウの直接のバッファーを、直接読み書きすることを許可するような仕様変更に関しては、もちろん反対です。そんなことしたらblikeの意味(blMain()の移植性)が失われますし。
<bl_play_pcm()などを使えるようにしたい>
blikeでサウンドをサポートしようと思い、
どうやれば移植性のある実装になるかを思案してみました。
条件として考えたのは
1:ドライバー側の開発負担を最も小さくできる方法。(つまり、commonではどうしても実現できない機能のみの、最小限の実装)
2:ソフトウェアで可能な部分は、極力ソフトウェアによるエミュレートで行う。(機種依存せずに実現可能な機能は、すべてcommon側で行う)
3:ウィンドウズ環境に有利な設計をする。(波形は、ウインドウズで一般的なwav形式(リトルエンディアン、符号あり16bit,44100Hz)の使用を前提とする)
です。
これにより、結論としては
ドライバー側が担当する機能:
wav形式の断片(16bit,44100Hz,モノラルの波形パケット)を、指定された側のスピーカーで再生する。
common側が担当する機能:
wavファイルのロード。
複数チャンネルの波形を合成して、一つの波形パケットを生成し、それをドライバーに渡す。
各チャンネルの再生の管理。
(波形全体の再生が完了するまで、blMain()とは別スレッドで、波形パケット生成&ドライバー側へのパケット転送を独自に続ける)
という形になりました。
つまり、
ドライバー側はシンプルなパケット再生機能のみ。(渡されたパケットを、指定されたスピーカーで、ただ鳴らすだけ。)(ミキサーのような高レベルなことは一切行わない)
common側はミキサー全般と、波形再生の再生状況の管理全般を担当します。
ドライバー側は当然スレッドで独立して動かさねばなりません。ドライバー側では、ソースコードレベルでの移植性を考慮する必要が無いので、スレッド化できます。
問題は、common側です。
common側はソースコードの移植性(ソースコードの変更無しにコンパイル可能)を満たすためには、スレッドが使用できません。
なぜなら、blikeではスレッドがサポートされてないからです。
というわけで、commonでスレッド生成が可能になるように、bld_でスレッド関連の関数をサポートすべきだと思います。
それは必要最小限で十分で、
struct BLD_THREAD {...};
typedef void* (*bld_thread_func)(void*);
struct BLD_THREAD* bld_create_thread(bld_thread_func f, void* data);
void bld_join_thread(struct BLD_THREAD* a);
void bld_close_thread(struct BLD_THREAD* a);
の3つで十分だと思います。
これをbld_で提供すれば、common側でスレッドを使っても、移植性のあるコードになると思います。
もしもcommon側でスレッドを使わずにミキサーを作った場合、
音を再生してる間はblMain()の他の処理が全て停止する、という、悲惨な状況になると思います。
音を再生してる間、ゲームの動きが全て止まるなんてショボすぎます。これは現代のレベルでは許されないレベルのショボさだと思います。(まるでBASIC時代のゲーム)
commonでのスレッド使用を諦め、かつ、音を再生してもblMain()が停止しないようにするためには、
ドライバー側に、プレイヤー、ミキサー、波形再生管理、これら全て行うソースを書いてしまえば可能ですが、これだと、新規のドライバー移植作業がとてもシンドイことになります。
(
もっとも、これら全てをドライバーで書くならば、common, driverに分割する設計よりも、ずっと効率的に処理できるのも事実だし、
また、commonによるソフトウェアエミュレートによるミキサーではなく、ハードやALSAなどに依存したミキサー機能を直接使えるので、
より高速・高効率になるメリットもありますが。
)
blikeは、同じソースコードがどこでもコンパイルできて、まったく同じように動くのが売りだと思うので、
ソフトウェアエミュレートで可能なことは、極力common側で行うのが正しいスタイルだと思います。
ミキサーと波形再生管理のような、ソフトウェアエミュレートで可能な部分はcommonに書くべきだし、
ドライバー側に多チャンネルの合成や、波形再生管理のような、高レベルのコンポーネントを要求すべきでは無いと思います。
なので、ドライバーの仕様に、スレッドを扱う関数のサポートを、追加すべきだと思います。
もしもスレッドが扱えないOS上に、blikeのドライバーを移植する場合は、スレッド関連が使用不能なことを表すマクロなりをblike.hに設定しておいて、
単純にスレッド関連の関数は空としてドライバーを書けば良いと思います。
ドライバーのスレッド関連関数が空関数になることに伴い、commonに書かれてる関数のうち、スレッドに依存した関数も空関数として無効化するようにすれば、
blMain()のアプリ中でも、commonのスレッド依存関数を使用した部分は空関数で無効化されるので、おそらく有効機能のみでblMain()は無事に動くはずだと思います。
ドライバー側でスレッドを提供しても、スレッドの提供をcommonまでにしておけば(blMain()には提供しなければ)、
とりあえずblMain()レベル(アプリケーションレベル)では、移植に問題は生じないはずだと思います。
単純に、チープな環境では、blMain()がチープな環境なりに、一応、動くはずです。(それはたとえば音が鳴らない等の差として)
ただ、個人的には、スレッドの使用をblMain()にも提供すべきだと思います。
(スレッドを使えない環境では動かないblMain()アプリが書かれうるけど、それはそれで、「スレッドが使えないOSでは、動かないアプリも時々あるな…」程度で諦めてもらえば良いと思います。)
…個人的には、あまりに極端にチープな環境は、切り捨てるべきだと思います。
たとえば、スレッドが使えない、音が鳴らない、マウスが無い、ネットが無い、モニターが無い、等々、あまりにもチープな環境はサブターゲット(おまけ)と考えて設計すべきだと思います。
これをメインターゲットと考えて設計してしまってるから、サウンドが無い、ネットが無い、マウスが無い、そしてスレッドが無いなんて状況になってるんだと思います。
そこそこ新しくて、いまどきの普通のパソコンなら有って当然な機能は、遠慮せずにサポートしても、現実的なケースとして考えるにおいて、移植に重大な問題が生じるようなケースは稀だと思います。
大体、古いパソコンの想定は、10年前のペンティアム3機程度の機能を想定しておいて、それよりも古いパソコンやOSへの移植性は、ついで程度に考えておけば十分だと思います。
486レベルの古い低機能なパソコンを、おまけターゲットではなく、メインターゲットみたいに考えてしまうと、たぶん、身動き取れなくなると思います。
で、blikeの設計の妙な制約って、まさにそこだと思います。
20年前のパソコンが、亡霊みたいに後ろ髪を引っ張ってるような状況に思えます。おまけターゲットならぬ、おばけターゲットというか。
おまけターゲットも、せいぜいペンティアム3時代までで十分だと思います。個人的に。
これから先、多コア化に伴い、スレッドのサポートは必須になると思います。
スレッドが使えない環境は、今後、間違いなく廃れていくと確信してます。過去方向の普遍性ではなく、未来方向への普遍性を求めるべきだと思います。
ウインドウのイメージデータと言っても、直接ドライバー側のウインドウが持つフレームバッファーに直接書くことは要求してません。
もしそれをblMain()から許可してしまえば、カラー形式は様々なので、途端にblMain()ソースの移植性が失われてしまいます。
(24bit,0xBBGGRR形式を前提に直接あつかえば、そのblMain()コードは32bit,0x00RRGGBB環境では当然正常に表示されませんし、移植性に問題が生じてしまう)
そうではなく、commonの扱うレベルのフレームバッファーへの直接アクセスを言ってます。
ここは32bit,0x00RRGGBB形式で固定なので、直接アクセスを許してもblMain()の移植性に問題は生じないと思います。
bld_内の、まさにウインドウの直接のバッファーを、直接読み書きすることを許可するような仕様変更に関しては、もちろん反対です。そんなことしたらblikeの意味(blMain()の移植性)が失われますし。
<bl_play_pcm()などを使えるようにしたい>
blikeでサウンドをサポートしようと思い、
どうやれば移植性のある実装になるかを思案してみました。
条件として考えたのは
1:ドライバー側の開発負担を最も小さくできる方法。(つまり、commonではどうしても実現できない機能のみの、最小限の実装)
2:ソフトウェアで可能な部分は、極力ソフトウェアによるエミュレートで行う。(機種依存せずに実現可能な機能は、すべてcommon側で行う)
3:ウィンドウズ環境に有利な設計をする。(波形は、ウインドウズで一般的なwav形式(リトルエンディアン、符号あり16bit,44100Hz)の使用を前提とする)
です。
これにより、結論としては
ドライバー側が担当する機能:
wav形式の断片(16bit,44100Hz,モノラルの波形パケット)を、指定された側のスピーカーで再生する。
common側が担当する機能:
wavファイルのロード。
複数チャンネルの波形を合成して、一つの波形パケットを生成し、それをドライバーに渡す。
各チャンネルの再生の管理。
(波形全体の再生が完了するまで、blMain()とは別スレッドで、波形パケット生成&ドライバー側へのパケット転送を独自に続ける)
という形になりました。
つまり、
ドライバー側はシンプルなパケット再生機能のみ。(渡されたパケットを、指定されたスピーカーで、ただ鳴らすだけ。)(ミキサーのような高レベルなことは一切行わない)
common側はミキサー全般と、波形再生の再生状況の管理全般を担当します。
ドライバー側は当然スレッドで独立して動かさねばなりません。ドライバー側では、ソースコードレベルでの移植性を考慮する必要が無いので、スレッド化できます。
問題は、common側です。
common側はソースコードの移植性(ソースコードの変更無しにコンパイル可能)を満たすためには、スレッドが使用できません。
なぜなら、blikeではスレッドがサポートされてないからです。
というわけで、commonでスレッド生成が可能になるように、bld_でスレッド関連の関数をサポートすべきだと思います。
それは必要最小限で十分で、
struct BLD_THREAD {...};
typedef void* (*bld_thread_func)(void*);
struct BLD_THREAD* bld_create_thread(bld_thread_func f, void* data);
void bld_join_thread(struct BLD_THREAD* a);
void bld_close_thread(struct BLD_THREAD* a);
の3つで十分だと思います。
これをbld_で提供すれば、common側でスレッドを使っても、移植性のあるコードになると思います。
もしもcommon側でスレッドを使わずにミキサーを作った場合、
音を再生してる間はblMain()の他の処理が全て停止する、という、悲惨な状況になると思います。
音を再生してる間、ゲームの動きが全て止まるなんてショボすぎます。これは現代のレベルでは許されないレベルのショボさだと思います。(まるでBASIC時代のゲーム)
commonでのスレッド使用を諦め、かつ、音を再生してもblMain()が停止しないようにするためには、
ドライバー側に、プレイヤー、ミキサー、波形再生管理、これら全て行うソースを書いてしまえば可能ですが、これだと、新規のドライバー移植作業がとてもシンドイことになります。
(
もっとも、これら全てをドライバーで書くならば、common, driverに分割する設計よりも、ずっと効率的に処理できるのも事実だし、
また、commonによるソフトウェアエミュレートによるミキサーではなく、ハードやALSAなどに依存したミキサー機能を直接使えるので、
より高速・高効率になるメリットもありますが。
)
blikeは、同じソースコードがどこでもコンパイルできて、まったく同じように動くのが売りだと思うので、
ソフトウェアエミュレートで可能なことは、極力common側で行うのが正しいスタイルだと思います。
ミキサーと波形再生管理のような、ソフトウェアエミュレートで可能な部分はcommonに書くべきだし、
ドライバー側に多チャンネルの合成や、波形再生管理のような、高レベルのコンポーネントを要求すべきでは無いと思います。
なので、ドライバーの仕様に、スレッドを扱う関数のサポートを、追加すべきだと思います。
もしもスレッドが扱えないOS上に、blikeのドライバーを移植する場合は、スレッド関連が使用不能なことを表すマクロなりをblike.hに設定しておいて、
単純にスレッド関連の関数は空としてドライバーを書けば良いと思います。
ドライバーのスレッド関連関数が空関数になることに伴い、commonに書かれてる関数のうち、スレッドに依存した関数も空関数として無効化するようにすれば、
blMain()のアプリ中でも、commonのスレッド依存関数を使用した部分は空関数で無効化されるので、おそらく有効機能のみでblMain()は無事に動くはずだと思います。
ドライバー側でスレッドを提供しても、スレッドの提供をcommonまでにしておけば(blMain()には提供しなければ)、
とりあえずblMain()レベル(アプリケーションレベル)では、移植に問題は生じないはずだと思います。
単純に、チープな環境では、blMain()がチープな環境なりに、一応、動くはずです。(それはたとえば音が鳴らない等の差として)
ただ、個人的には、スレッドの使用をblMain()にも提供すべきだと思います。
(スレッドを使えない環境では動かないblMain()アプリが書かれうるけど、それはそれで、「スレッドが使えないOSでは、動かないアプリも時々あるな…」程度で諦めてもらえば良いと思います。)
…個人的には、あまりに極端にチープな環境は、切り捨てるべきだと思います。
たとえば、スレッドが使えない、音が鳴らない、マウスが無い、ネットが無い、モニターが無い、等々、あまりにもチープな環境はサブターゲット(おまけ)と考えて設計すべきだと思います。
これをメインターゲットと考えて設計してしまってるから、サウンドが無い、ネットが無い、マウスが無い、そしてスレッドが無いなんて状況になってるんだと思います。
そこそこ新しくて、いまどきの普通のパソコンなら有って当然な機能は、遠慮せずにサポートしても、現実的なケースとして考えるにおいて、移植に重大な問題が生じるようなケースは稀だと思います。
大体、古いパソコンの想定は、10年前のペンティアム3機程度の機能を想定しておいて、それよりも古いパソコンやOSへの移植性は、ついで程度に考えておけば十分だと思います。
486レベルの古い低機能なパソコンを、おまけターゲットではなく、メインターゲットみたいに考えてしまうと、たぶん、身動き取れなくなると思います。
で、blikeの設計の妙な制約って、まさにそこだと思います。
20年前のパソコンが、亡霊みたいに後ろ髪を引っ張ってるような状況に思えます。おまけターゲットならぬ、おばけターゲットというか。
おまけターゲットも、せいぜいペンティアム3時代までで十分だと思います。個人的に。
これから先、多コア化に伴い、スレッドのサポートは必須になると思います。
スレッドが使えない環境は、今後、間違いなく廃れていくと確信してます。過去方向の普遍性ではなく、未来方向への普遍性を求めるべきだと思います。
前半について。
ええと同じことは僕も前から考えていて、それで bl_getGrpB() という関数が作ってはありました。関数の本体は common/ の test.c にあります。バージョン01fにもあります。これを正規のblike関数として認めてしまいましょうか・・・。
後半について。
とても興味深い考察です。ありがとうございます。
まず僕はkemeppoさんの主張は分かります。そして少し誤解もあると思っています。その誤解を解いて、その上で僕もkemeppoさんも満足できるような方法を提案したいと思います。
blikeの目的はいろいろあります。目的が違えば理想も違ってくるので、目的を忘れないことは大切です。ただblikeは「使える(?)かもしれない」未来が見えてきたので、本来の目的を超えて使いたくもなって、それで少し欲が出てきたのでしょう。それらの目的を確認したいと思います。
目的1: C言語の入門者がprintf()だけじゃつまらなくてやる気が続かない。だから簡単に使える描画関数をつけてみた。この程度なら移植もそんなに大変じゃないだろう。いろんな環境に移植されれば、これらで勉強させても許されるだろう。これらを使って簡単なゲームを作らせれば、基本的な整数演算やif文などを理解することができるだろう。それゆえに応用の可能性よりはとにかく簡単に使えることを重視する(ウィンドウを1枚しか扱えない代わりに、ウィンドウハンドル的なものを理解しないで済む、引数も減らせる、とか)。
目的2: 「はりぼてOS」系のOSではアプリが不足している。じゃあそれらのOSでも移植可能な(チープな)仕様にとどめておけば、このライブラリを使って作られたアプリは、「はりぼてOS」でも動くことになるな。よし、これでいこう。
目的3: blikeはOS非依存APIとして有望である。だからスレッドやサウンドをサポートすれば、もっといろいろ作れるようになるはずだ。そのほうが有意義な目的であり、そのためであれば上記の目的を多少犠牲にしても問題ないはずだ。
僕が考えていたのは目的1と目的2であって、今回提案されたのが目的3だと思うのです。ただその路線で行くと、今度はじゃあ既存のGTK+とは何が違うのか?(方針において)という心配があります。・・・blikeという名前は「昔のBASICのように」という思いから名づけたので、目的3が後回しになるのは僕としては不本意なことではないのです。
僕としては、目的1と目的2を守る範囲でライブラリを仕上げてひとまず完成とするべきではないかと今でも思っています。そしてその上で、その延長線上で拡張仕様のblike2を考えて、そこで目的3を重視してはどうでしょうか。目的1から3までをblikeだけで全部満たすのは相当に無理があると思うのです。それを無理にやると、結局どの目的にとっても中途半端で使えないような、そんな結果に終わりそうに思うのです。
サブターゲットという話もありましたが、それよりはblike1とblike2みたいにレベルを分けたほうがずっと分かりやすいはずです。このアプリはblike1で書きましたとかblike2で書きましたというほうがいいのです。blikeの中の○○関数はサブターゲットではサポートされないとか、そういうのだと混乱しそうな気がします。
まずは目的1と目的2の範囲でblikeを仕上げて、こんなにpoorなライブラリでもこんなに面白いことができるよね?とアプリをいくつか作って遊ぶべきだと思うんです(教育上のサンプルを意識して作る)。それでその後にblike2の設計をしたら、それはなかなかいいものになるのではないでしょうか?
もしkemeppoさんが待ちきれなければ、kmplibみたいな名前でblike2相当のものを作ってしまってもいいかもしれません。そしたら将来に僕はその仕様を精査して、それをベースにblike2を作るかもしれません。
ええと同じことは僕も前から考えていて、それで bl_getGrpB() という関数が作ってはありました。関数の本体は common/ の test.c にあります。バージョン01fにもあります。これを正規のblike関数として認めてしまいましょうか・・・。
後半について。
とても興味深い考察です。ありがとうございます。
まず僕はkemeppoさんの主張は分かります。そして少し誤解もあると思っています。その誤解を解いて、その上で僕もkemeppoさんも満足できるような方法を提案したいと思います。
blikeの目的はいろいろあります。目的が違えば理想も違ってくるので、目的を忘れないことは大切です。ただblikeは「使える(?)かもしれない」未来が見えてきたので、本来の目的を超えて使いたくもなって、それで少し欲が出てきたのでしょう。それらの目的を確認したいと思います。
目的1: C言語の入門者がprintf()だけじゃつまらなくてやる気が続かない。だから簡単に使える描画関数をつけてみた。この程度なら移植もそんなに大変じゃないだろう。いろんな環境に移植されれば、これらで勉強させても許されるだろう。これらを使って簡単なゲームを作らせれば、基本的な整数演算やif文などを理解することができるだろう。それゆえに応用の可能性よりはとにかく簡単に使えることを重視する(ウィンドウを1枚しか扱えない代わりに、ウィンドウハンドル的なものを理解しないで済む、引数も減らせる、とか)。
目的2: 「はりぼてOS」系のOSではアプリが不足している。じゃあそれらのOSでも移植可能な(チープな)仕様にとどめておけば、このライブラリを使って作られたアプリは、「はりぼてOS」でも動くことになるな。よし、これでいこう。
目的3: blikeはOS非依存APIとして有望である。だからスレッドやサウンドをサポートすれば、もっといろいろ作れるようになるはずだ。そのほうが有意義な目的であり、そのためであれば上記の目的を多少犠牲にしても問題ないはずだ。
僕が考えていたのは目的1と目的2であって、今回提案されたのが目的3だと思うのです。ただその路線で行くと、今度はじゃあ既存のGTK+とは何が違うのか?(方針において)という心配があります。・・・blikeという名前は「昔のBASICのように」という思いから名づけたので、目的3が後回しになるのは僕としては不本意なことではないのです。
僕としては、目的1と目的2を守る範囲でライブラリを仕上げてひとまず完成とするべきではないかと今でも思っています。そしてその上で、その延長線上で拡張仕様のblike2を考えて、そこで目的3を重視してはどうでしょうか。目的1から3までをblikeだけで全部満たすのは相当に無理があると思うのです。それを無理にやると、結局どの目的にとっても中途半端で使えないような、そんな結果に終わりそうに思うのです。
サブターゲットという話もありましたが、それよりはblike1とblike2みたいにレベルを分けたほうがずっと分かりやすいはずです。このアプリはblike1で書きましたとかblike2で書きましたというほうがいいのです。blikeの中の○○関数はサブターゲットではサポートされないとか、そういうのだと混乱しそうな気がします。
まずは目的1と目的2の範囲でblikeを仕上げて、こんなにpoorなライブラリでもこんなに面白いことができるよね?とアプリをいくつか作って遊ぶべきだと思うんです(教育上のサンプルを意識して作る)。それでその後にblike2の設計をしたら、それはなかなかいいものになるのではないでしょうか?
もしkemeppoさんが待ちきれなければ、kmplibみたいな名前でblike2相当のものを作ってしまってもいいかもしれません。そしたら将来に僕はその仕様を精査して、それをベースにblike2を作るかもしれません。
わかりました。
blike で実現される機能は、あくまで現状のはりぼてOSが基準なので、
はりぼてOS上で動かない機能が、オリジナル版blikeに追加される可能性は0ということですね。
はりぼてOSで動かない機能が、オリジナル版blikeでサポートされることへの要望・期待をしないように、今後は気をつけます。
すみませんでした。
ところで、
先頭アドレスのアライメントを指定して確保できるmalloc(),free()を書いたのですが、blikeに追加してくれませんか?
使用してる関数は bld_malloc(), bld_free(), bl_printf() のみなので、common に属するソースだと思います。
(bl_malloc(), bl_free()が動かないので)
http://sourceforge.jp/users/kemeco/pf/c_blike_01f_linux/git/?a=blob&h=b779dbace15770497dbfa9cdf302e5de778198e6&hb=91108e45b0d1d2fc2d0951d2b44823a5c23e1f08&f=lib_src/common/bl_malloc_aligned.c
http://sourceforge.jp/users/kemeco/pf/c_blike_01f_linux/git/?a=blob&h=5fa6be5bb408c48c7f2360a4906ad7e7cfc332c5&hb=91108e45b0d1d2fc2d0951d2b44823a5c23e1f08&f=blike0.h
先頭アドレスを 456byte 境界に配置したい場合は、
void* p = bl_malloc_aligned(123, 456);
とすれば、先頭アドレスが 456 で割り切れるアドレスに配置されます。
解放する場合は
bl_malloc_free(p);
とすれば、確保したメモリーが全て解放されます。
余談:
blike の開発ツリーのソースコードを、 git で管理・公開してみてはどうでしょうか?
現状の変更状態がはっきりするし、
(過疎ってますが)ここのコミュニティーの人たちなどがblike開発版をダウンロードして使うことで、
デバッグ作業や修正パッチ作成を行って貰える形にもなるでしょうし。
blike で実現される機能は、あくまで現状のはりぼてOSが基準なので、
はりぼてOS上で動かない機能が、オリジナル版blikeに追加される可能性は0ということですね。
はりぼてOSで動かない機能が、オリジナル版blikeでサポートされることへの要望・期待をしないように、今後は気をつけます。
すみませんでした。
ところで、
先頭アドレスのアライメントを指定して確保できるmalloc(),free()を書いたのですが、blikeに追加してくれませんか?
使用してる関数は bld_malloc(), bld_free(), bl_printf() のみなので、common に属するソースだと思います。
(bl_malloc(), bl_free()が動かないので)
http://sourceforge.jp/users/kemeco/pf/c_blike_01f_linux/git/?a=blob&h=b779dbace15770497dbfa9cdf302e5de778198e6&hb=91108e45b0d1d2fc2d0951d2b44823a5c23e1f08&f=lib_src/common/bl_malloc_aligned.c
http://sourceforge.jp/users/kemeco/pf/c_blike_01f_linux/git/?a=blob&h=5fa6be5bb408c48c7f2360a4906ad7e7cfc332c5&hb=91108e45b0d1d2fc2d0951d2b44823a5c23e1f08&f=blike0.h
先頭アドレスを 456byte 境界に配置したい場合は、
void* p = bl_malloc_aligned(123, 456);
とすれば、先頭アドレスが 456 で割り切れるアドレスに配置されます。
解放する場合は
bl_malloc_free(p);
とすれば、確保したメモリーが全て解放されます。
余談:
blike の開発ツリーのソースコードを、 git で管理・公開してみてはどうでしょうか?
現状の変更状態がはっきりするし、
(過疎ってますが)ここのコミュニティーの人たちなどがblike開発版をダウンロードして使うことで、
デバッグ作業や修正パッチ作成を行って貰える形にもなるでしょうし。
c_blike_01fのアプリを、
HTML5が動くウェブブラウザー上で動かせるようにしました。
…っていうか、動かせるようになってたw
http://kemeconoajito.blog88.fc2.com/blog-entry-174.html
HTML5が動くウェブブラウザー上で動かせるようにしました。
…っていうか、動かせるようになってたw
http://kemeconoajito.blog88.fc2.com/blog-entry-174.html
http://sourceforge.jp/users/kemeco/pf/bl_clock/git/?a=blob&h=d14fed82e6d12cf385685c225207163c84779b6f&hb=d4f4e8dd2d7e5f64341cf9ae764dd36157599b12&f=bl_clock.c
c_blike_01f で時計
http://sakurasite.homeip.net/imgboard/img-box/img20120208220719.png
linuxでのビルド方法:
1.ライブラリーを落としてインストール
git clone git://git.pf.sourceforge.jp/gitroot/k/ke/kemeco/c_blike_01f_linux.git
cd c_blike_01f_linux
aclocal
autoheader
autoconf
./configure --prefix=/usr
make
sudo make install
ldconfig
2.普通にc_blikeをpkg-configでリンクしてビルド(sin,cosを使ってるので libm もリンクしてます)
gcc -o bl_clock bl_clock.c `pkg-config c_blike --libs --cflags` -lm
3.実行
./bl_clock
c_blike_01f で時計
http://sakurasite.homeip.net/imgboard/img-box/img20120208220719.png
linuxでのビルド方法:
1.ライブラリーを落としてインストール
git clone git://git.pf.sourceforge.jp/gitroot/k/ke/kemeco/c_blike_01f_linux.git
cd c_blike_01f_linux
aclocal
autoheader
autoconf
./configure --prefix=/usr
make
sudo make install
ldconfig
2.普通にc_blikeをpkg-configでリンクしてビルド(sin,cosを使ってるので libm もリンクしてます)
gcc -o bl_clock bl_clock.c `pkg-config c_blike --libs --cflags` -lm
3.実行
./bl_clock
c_blike_01f にて、任意の三角形塗りつぶしを行う関数を書きました。
(filltri.c)
http://sourceforge.jp/users/kemeco/pf/bl_filltri/git/?a=tree
依存する関数は bl_setPix() のみです。
数値計算は10bitの固定小数点数で行ってます。(川合さんがfloat嫌いっぽい雰囲気なので)
ソースコードのgitリポジトリー
git clone git://git.pf.sourceforge.jp/gitroot/k/ke/kemeco/bl_filltri.git
filltri.c を c_blike_01f の /common ディレクトリーに置いて、ライブラリーをビルドすれば、それだけで組み込めると思います。
ライブラリーに組み込まなくても、単体のcソースとしてリンクしても使えます。
他のファイルに依存しないように、1ファイル完結にしてあるので、/common に組み込んでも、あまり汚れないと思います。
と、ダメもとで書き込んでみる。
(filltri.c)
http://sourceforge.jp/users/kemeco/pf/bl_filltri/git/?a=tree
依存する関数は bl_setPix() のみです。
数値計算は10bitの固定小数点数で行ってます。(川合さんがfloat嫌いっぽい雰囲気なので)
ソースコードのgitリポジトリー
git clone git://git.pf.sourceforge.jp/gitroot/k/ke/kemeco/bl_filltri.git
filltri.c を c_blike_01f の /common ディレクトリーに置いて、ライブラリーをビルドすれば、それだけで組み込めると思います。
ライブラリーに組み込まなくても、単体のcソースとしてリンクしても使えます。
他のファイルに依存しないように、1ファイル完結にしてあるので、/common に組み込んでも、あまり汚れないと思います。
と、ダメもとで書き込んでみる。
同じく c_blike_01f にて、任意の三角形グラデーション塗りつぶしを行う関数です。
(filltrigr.c)
http://sourceforge.jp/users/kemeco/pf/bl_filltrigr/git/?a=tree
ベースは filltri.c なので、基本的に仕様は同じです。
1ファイル完結にしてあるので、/common に置いても、あまり汚れないと思います。
ソースコードのgitリポジトリー
git clone git://git.pf.sourceforge.jp/gitroot/k/ke/kemeco/bl_filltrigr.git
(filltrigr.c)
http://sourceforge.jp/users/kemeco/pf/bl_filltrigr/git/?a=tree
ベースは filltri.c なので、基本的に仕様は同じです。
1ファイル完結にしてあるので、/common に置いても、あまり汚れないと思います。
ソースコードのgitリポジトリー
git clone git://git.pf.sourceforge.jp/gitroot/k/ke/kemeco/bl_filltrigr.git
c_blike_01f にて、任意の三角形領域のコピーを行う関数です。
(copytri.c)
http://sourceforge.jp/users/kemeco/pf/bl_copytri/git/?a=tree
ベースは filltri.c なので、基本的に仕様は同じです。
/common に置いても、あまり汚れないと思います。
普通にファイルとしてコンパイル・リンクしても使えます。
<用途と使用方法>
コピー元のスクリーン番号の三角形領域から、コピー先のスクリーン番号の三角形領域へと、コピーを行う関数です。
また、その際に、単純な色調整もできます。
引数は多いですが、三角形2つと、色調整を指定してるだけなので、単純です。
引数の内訳は、
bl_copyTri(
コピー先のスクリーン番号、
コピー先の三角形領域(実際には6個の引数 x0,y0, x1,y1, x2,y2)、
コピー元のスクリーン番号、
コピー元の三角形領域(実際には6個の引数)、
RGBの増減%(実際には3個の引数 r, g, b)
);
となります。
例えば、
コピー先の三角形領域が、スクリーン番号0、頂点座標が 0,0, 100,0, 50,100
コピー元の三角形領域が、スクリーン番号0、頂点座標が 300,50, 300,0, 350,20
だとしたら、
bl_copyTri(
0, 0,0, 100,0, 50,100,
0, 300,50, 300,0, 350,20,
0,0,0
);
となります。
最後の 0,0,0 は、RGBの増減%が、0%ということです。
つまり、色調整しないで、そのままコピーされるということです。
もしも、全体的に少し明るくしたい場合は
bl_copyTri(コピー先三角形領域、 コピー元三角形領域、 512, 512, 512);
などとすればいいです。
逆に、全体的に真っ暗にしたい場合は
bl_copyTri(コピー先三角形領域、 コピー元三角形領域、 -1024, -1024, -1024);
とすれば、真っ黒の三角形になるはずです。
<RGB増減%の引数について詳しく>
10bit の固定小数点数として扱います。
1024 を1として考えます。つまり 1024 が 100% を意味します。
この%を 255 に乗算した値が、元の色に足し算される仕組みです。
+%の場合は足し算されるので明るくなり、-%の場合は引き算されるので暗くなります。単純です。
わりと雑な方法なので、色相(各RGB値の差の相対関係)などは保たれません。色ズレなどが起こりやすいです。
(色相・彩度・明度に即した、ちゃんとした方法で色をやろうとすると、どうしても一個一個のピクセルに対して、専用に値を計算しなくてはならなくなるので、速度が犠牲になると思ったので)
<画像の補間について>
まだサンプルコード書いてないので、これが本当に自由変形がうまく行くかどうか分からないのですが、
自由変形できることを目指して書いてたつもりです。
自由変形の際の、画像ピクセルの補間については、バイリニア補間にしようか、ニアレストネイパーにしようかで迷ってます。
現状、ニアレストネイパーです。
パラメーター的には、バイリニア補間するお膳立ては揃ってるのですが、やはり、若干速度が犠牲になるので躊躇してます。
(ただし、おそらくシフトとビットマスクと足し算だけでできそうな予感がするので、割り算が増える程の嫌さではありませんが)
もしかしたら来週あたり、git pull したら、しれっとバイリニア補間になってるかもしれません。
いや、別名で関数を用意すると思います。copuTri2() のように
<ソースコードのgitリポジトリー>
git clone git://git.pf.sourceforge.jp/gitroot/k/ke/kemeco/bl_copytri.git
余談:
git クローンしたディレクトリー内にて、git pull とすれば、
もしもソースコードに更新があった場合は、自動的にパッチをダウンロードして充てることができるので簡単です。
(svn update のように)
おそらく、バグが多いだろうし、ちゃんと動くかもまだテストしてないし、今後もちょくちょく修正するはずなので、git pull すれば、よく新しいのが落ちてくると思います。
もしもバグ修正や、高速化など、ソースコードを書き換えた場合は、
git diff ソースコード名
とすれば、画面に差分パッチが表示されます。それをそのまま > でファイルにリダイレクトすれば、パッチファイルができあがります。
git diff copytri.c > aaa.patch
バグ修正や高速化などのパッチを送ってくれるとありがたいです。
直接メールでもいいし、掲示板に直接テキストファイルを貼ってくれても大丈夫です。(ただし、TABとスペースが正しく機能する掲示板、たとえば codepad などで)
(copytri.c)
http://sourceforge.jp/users/kemeco/pf/bl_copytri/git/?a=tree
ベースは filltri.c なので、基本的に仕様は同じです。
/common に置いても、あまり汚れないと思います。
普通にファイルとしてコンパイル・リンクしても使えます。
<用途と使用方法>
コピー元のスクリーン番号の三角形領域から、コピー先のスクリーン番号の三角形領域へと、コピーを行う関数です。
また、その際に、単純な色調整もできます。
引数は多いですが、三角形2つと、色調整を指定してるだけなので、単純です。
引数の内訳は、
bl_copyTri(
コピー先のスクリーン番号、
コピー先の三角形領域(実際には6個の引数 x0,y0, x1,y1, x2,y2)、
コピー元のスクリーン番号、
コピー元の三角形領域(実際には6個の引数)、
RGBの増減%(実際には3個の引数 r, g, b)
);
となります。
例えば、
コピー先の三角形領域が、スクリーン番号0、頂点座標が 0,0, 100,0, 50,100
コピー元の三角形領域が、スクリーン番号0、頂点座標が 300,50, 300,0, 350,20
だとしたら、
bl_copyTri(
0, 0,0, 100,0, 50,100,
0, 300,50, 300,0, 350,20,
0,0,0
);
となります。
最後の 0,0,0 は、RGBの増減%が、0%ということです。
つまり、色調整しないで、そのままコピーされるということです。
もしも、全体的に少し明るくしたい場合は
bl_copyTri(コピー先三角形領域、 コピー元三角形領域、 512, 512, 512);
などとすればいいです。
逆に、全体的に真っ暗にしたい場合は
bl_copyTri(コピー先三角形領域、 コピー元三角形領域、 -1024, -1024, -1024);
とすれば、真っ黒の三角形になるはずです。
<RGB増減%の引数について詳しく>
10bit の固定小数点数として扱います。
1024 を1として考えます。つまり 1024 が 100% を意味します。
この%を 255 に乗算した値が、元の色に足し算される仕組みです。
+%の場合は足し算されるので明るくなり、-%の場合は引き算されるので暗くなります。単純です。
わりと雑な方法なので、色相(各RGB値の差の相対関係)などは保たれません。色ズレなどが起こりやすいです。
(色相・彩度・明度に即した、ちゃんとした方法で色をやろうとすると、どうしても一個一個のピクセルに対して、専用に値を計算しなくてはならなくなるので、速度が犠牲になると思ったので)
<画像の補間について>
まだサンプルコード書いてないので、これが本当に自由変形がうまく行くかどうか分からないのですが、
自由変形できることを目指して書いてたつもりです。
自由変形の際の、画像ピクセルの補間については、バイリニア補間にしようか、ニアレストネイパーにしようかで迷ってます。
現状、ニアレストネイパーです。
パラメーター的には、バイリニア補間するお膳立ては揃ってるのですが、やはり、若干速度が犠牲になるので躊躇してます。
(ただし、おそらくシフトとビットマスクと足し算だけでできそうな予感がするので、割り算が増える程の嫌さではありませんが)
もしかしたら来週あたり、git pull したら、しれっとバイリニア補間になってるかもしれません。
いや、別名で関数を用意すると思います。copuTri2() のように
<ソースコードのgitリポジトリー>
git clone git://git.pf.sourceforge.jp/gitroot/k/ke/kemeco/bl_copytri.git
余談:
git クローンしたディレクトリー内にて、git pull とすれば、
もしもソースコードに更新があった場合は、自動的にパッチをダウンロードして充てることができるので簡単です。
(svn update のように)
おそらく、バグが多いだろうし、ちゃんと動くかもまだテストしてないし、今後もちょくちょく修正するはずなので、git pull すれば、よく新しいのが落ちてくると思います。
もしもバグ修正や、高速化など、ソースコードを書き換えた場合は、
git diff ソースコード名
とすれば、画面に差分パッチが表示されます。それをそのまま > でファイルにリダイレクトすれば、パッチファイルができあがります。
git diff copytri.c > aaa.patch
バグ修正や高速化などのパッチを送ってくれるとありがたいです。
直接メールでもいいし、掲示板に直接テキストファイルを貼ってくれても大丈夫です。(ただし、TABとスペースが正しく機能する掲示板、たとえば codepad などで)
c_blike_01f_linux は、アプリ起動時の引数を取得できなかったので、ツール類を書く際に不便だったので、
アプリ起動時に引数を取得できるように、グローバル変数を追加してみました。
(int bl_argc と char** bl_argv)
git clone git://git.pf.sourceforge.jp/gitroot/k/ke/kemeco/c_blike_01f_linux.git
これによって
main(int argc, char** argv)に相当する情報を、
グローバル変数 int bl_argc; char** bl_argv; として参照できるようになりました。
sample/test_argc.c に、簡単な使い方の例を書いてあります。
備考:
c_blike_01f_linuxのビルド・インストール方法
aclocal
autoheader
autoconf
./configure --prefix=/usr
make
sudo make install
sudo ldconfig
で、以降、aiueo.cなどのソースコードを
gcc -o aiueo aiueo.c `pkg-config c_blike --libs --cflags`
でビルドできます。
sample/test*.c のサンプル群のビルドも、上記の記述法で手動でやってもいいですが、
面倒なのでバッチファイルを用意してあります。
./build.sh
アプリ起動時に引数を取得できるように、グローバル変数を追加してみました。
(int bl_argc と char** bl_argv)
git clone git://git.pf.sourceforge.jp/gitroot/k/ke/kemeco/c_blike_01f_linux.git
これによって
main(int argc, char** argv)に相当する情報を、
グローバル変数 int bl_argc; char** bl_argv; として参照できるようになりました。
sample/test_argc.c に、簡単な使い方の例を書いてあります。
備考:
c_blike_01f_linuxのビルド・インストール方法
aclocal
autoheader
autoconf
./configure --prefix=/usr
make
sudo make install
sudo ldconfig
で、以降、aiueo.cなどのソースコードを
gcc -o aiueo aiueo.c `pkg-config c_blike --libs --cflags`
でビルドできます。
sample/test*.c のサンプル群のビルドも、上記の記述法で手動でやってもいいですが、
面倒なのでバッチファイルを用意してあります。
./build.sh
c_blike_01f_linuxを更新しました。
ビルドシステムと、ライブラリー名の細かな修正だけで、ライブラリーのコア機能には変更はありません。
ソースコード入手方法:
git clone git://git.pf.sourceforge.jp/gitroot/k/ke/kemeco/c_blike_01f_linux.git
または
git pull
メモ:
内部的な話なので、普通に使う分には影響を受けませんが、
main()を直接、動的ライブラリー内に組み込んだので、c_blike_wrapper.a は不要になったので廃止しました。
また、ライブラリーのファイル名の命名規則を、基本的に blike へ変更しました。
(従来は c_blike だった)
pkg-config で指定する際も c_blike ではなく、blike としてください。
例:
gcc `pkg-config blike --libs --cflags` -o test test.c
ヘッダーのインストール先も、従来は
${prefix}/include/c_blike/ でしたが、
${prefix}/include/blike/ へと変更しました。
また、ライブラリー.soのファイル名の命名規則も
libc_blike_*.so から libblike-*.so へと変更しました。(gnu/linuxでは、あまりアンダーバーをライブラリー名等には用いずに、ハイフンを用いるのが一般的なようなので)
また、ライブラリー.soのインストール位置は、従来は
${prefix}/lib/c_blike/ 以下でしたが、
${prefix}/lib/ 以下へと変更しました。(libディレクトリーに直接置く)
そのため、/etc/ld.so.conf.d/c_blike.conf は不要になりました。
簡単にまとめると:
今後は c_blike_01f_linux アプリをビルドする際は
gcc `pkg-config blike --libs --cflags` -o test test.c
として用いてください。(c_blike → blike)
今回の変更による、ユーザーへの具体的な使用感への影響点は、この1点だけです。
ビルドシステムと、ライブラリー名の細かな修正だけで、ライブラリーのコア機能には変更はありません。
ソースコード入手方法:
git clone git://git.pf.sourceforge.jp/gitroot/k/ke/kemeco/c_blike_01f_linux.git
または
git pull
メモ:
内部的な話なので、普通に使う分には影響を受けませんが、
main()を直接、動的ライブラリー内に組み込んだので、c_blike_wrapper.a は不要になったので廃止しました。
また、ライブラリーのファイル名の命名規則を、基本的に blike へ変更しました。
(従来は c_blike だった)
pkg-config で指定する際も c_blike ではなく、blike としてください。
例:
gcc `pkg-config blike --libs --cflags` -o test test.c
ヘッダーのインストール先も、従来は
${prefix}/include/c_blike/ でしたが、
${prefix}/include/blike/ へと変更しました。
また、ライブラリー.soのファイル名の命名規則も
libc_blike_*.so から libblike-*.so へと変更しました。(gnu/linuxでは、あまりアンダーバーをライブラリー名等には用いずに、ハイフンを用いるのが一般的なようなので)
また、ライブラリー.soのインストール位置は、従来は
${prefix}/lib/c_blike/ 以下でしたが、
${prefix}/lib/ 以下へと変更しました。(libディレクトリーに直接置く)
そのため、/etc/ld.so.conf.d/c_blike.conf は不要になりました。
簡単にまとめると:
今後は c_blike_01f_linux アプリをビルドする際は
gcc `pkg-config blike --libs --cflags` -o test test.c
として用いてください。(c_blike → blike)
今回の変更による、ユーザーへの具体的な使用感への影響点は、この1点だけです。
Haskell で blike 関数を利用するためのラッパー
https://github.com/takeutch-kemeco/blike/wiki/Haskell-%28GHC%29-%E3%81%8B%E3%82%89-blike-%E3%82%92%E4%BD%BF%E3%81%86
test000a.c ~ test008a.cを試しにHaskellで書き換えてみました。動きます。
https://github.com/takeutch-kemeco/blike/wiki/Haskell-%28GHC%29-%E3%81%8B%E3%82%89-blike-%E3%82%92%E4%BD%BF%E3%81%86
test000a.c ~ test008a.cを試しにHaskellで書き換えてみました。動きます。
趣味な仕様によるスクリプト言語を作ってます。
全体的には昔のBASIC程度の表現力すらありませんが(for等のループ命令が無い。ループはifとgotoで行う等)、一方で変数が全て暗黙に複素数として扱われたり、式にラムダ関数を含められたり、歪な仕様の趣味言語です。
これの組み込み関数のバックエンドに blike をそのまま用いてみました。
https://github.com/takeutch-kemeco/memcalc
sample/bl_func/以下に、test000a.mc ~ test008a.mc として、blikeのサンプルコードに対応したものがあります。
全体的には昔のBASIC程度の表現力すらありませんが(for等のループ命令が無い。ループはifとgotoで行う等)、一方で変数が全て暗黙に複素数として扱われたり、式にラムダ関数を含められたり、歪な仕様の趣味言語です。
これの組み込み関数のバックエンドに blike をそのまま用いてみました。
https://github.com/takeutch-kemeco/memcalc
sample/bl_func/以下に、test000a.mc ~ test008a.mc として、blikeのサンプルコードに対応したものがあります。
linux版のblikeをメンテナンスするモチベーションが薄れてきたので、
もし誰かメンテナンスを引き継いでくれる方がいたら、お願いしたいです。
https://github.com/takeutch-kemeco/blike
のページから、pullリクエストのボタンを押せばできると思います。
(この機能を使ったことが無いので、詳しくは知りませんが)
・割と単純な仕組みの素朴なコードなので、K&R本に書いてあることの意味が大体わかる人ならば十分にメンテナンスできると思います。
・(ドライバー部分に関しては)改良する余地が多々ある未熟なコードなので、暇つぶしにもなると思います。
もし誰かメンテナンスを引き継いでくれる方がいたら、お願いしたいです。
https://github.com/takeutch-kemeco/blike
のページから、pullリクエストのボタンを押せばできると思います。
(この機能を使ったことが無いので、詳しくは知りませんが)
・割と単純な仕組みの素朴なコードなので、K&R本に書いてあることの意味が大体わかる人ならば十分にメンテナンスできると思います。
・(ドライバー部分に関しては)改良する余地が多々ある未熟なコードなので、暇つぶしにもなると思います。
ドライバーにマウスとペンタブのサポートを追加しました。
これでペイント作れます。
https://github.com/takeutch-kemeco/blike#%E3%82%AA%E3%83%AA%E3%82%B8%E3%83%8A%E3%83%AB%E3%81%A8%E3%81%AF%E7%95%B0%E3%81%AA%E3%82%8B-c_blike_01f_linux-%E5%9B%BA%E6%9C%89%E3%81%AE%E6%A9%9F%E8%83%BD
また、ウインドウ内では、ウインドウマネージャーによるデフォルトのマウスカーソルは消えるようにしてあるので、必要ならば自分でマウスカーソルを描くことも可能です。
これでペイント作れます。
https://github.com/takeutch-kemeco/blike#%E3%82%AA%E3%83%AA%E3%82%B8%E3%83%8A%E3%83%AB%E3%81%A8%E3%81%AF%E7%95%B0%E3%81%AA%E3%82%8B-c_blike_01f_linux-%E5%9B%BA%E6%9C%89%E3%81%AE%E6%A9%9F%E8%83%BD
また、ウインドウ内では、ウインドウマネージャーによるデフォルトのマウスカーソルは消えるようにしてあるので、必要ならば自分でマウスカーソルを描くことも可能です。