■ [Program]: 逃避 メモ ひとつめ - bullet/barrage lua/language
Lua 側からデータを渡したいわけですけど、 Lua のスタックとかいじるのしんどいので、 できる限りテーブルで C と連絡するとかしたくない。 Lua で OO っぽいことをしても C++ なんかの OO と 直接マッピングされるわけでも無いので便利くない。 C++ の場合 luabind があるけど、D つかってるし。
それにスクリプトはプログラマ以外の人も書けるのが理想ですし。 趣味で作ってる分にはどうせ プログラマ==スクリプタ なんであまり関係無いけど。 まあ 嬉しい誤算 もあるわけで。
で、OpenGL みたいな state machine な設計はどうか。
blType(ZAKO) blName("zako") blLife(10) for i = 1, 3 do fire(0, 3) end
シンプルだし、実装しやすいし、効率も悪くなさそう。
■ [Program]: 逃避 メモ ふたつめ - 現実 vs 理想
AspectJ おもしろい。 C から C++ の iostream だけつまみ喰いしたりできるように、 基本は Java でちょっとだけ AOP つまみ喰い (有名な例ではクラスを横断する Log 出力部分のモジュール化とか) みたいな使い方もできるのが良いと思う。
MJ とは好対照かと。 AspectJ では AOP は OOP を補佐する感じで、 MJ では OOP と AOP は等価位の重みか。 AspectJ は Java に hook をかける感じ、 MJ はプロジェクトを完全に Aspect で分類するから設計に強く影響する。 AspectJ は Java互換強く、 MJ は互換性がかなり弱い。 AspectJ は実装が安定、MJ 不安定。 AspectJ は IDE などの環境が充実、MJ は荒野。 現状では AspectJ はクラス解析できず、 MJ はできるのは数少ない MJ の強みかも。
最後のは例外として、 AspectJ は現実的、MJ は夢見がち。 D と C++ & boost に近い関係な印象。 もちろんそんなに綺麗に二分できるわけでもなく、 Java なんかはバランスをとっている感じなんだろうか。
以上しったかぶりなので眉に唾をお付け下さいませ。
■ [Program]: 逃避 メモ みっつめ - マルチパラダイム vs シングルパラダイム
Io おもしろい。prototype-based (以下 POP)。 何がすごいってマイナーパラダイムの言語って 普通(偏見) 実用性は乏しいのに、 ioDesktop なるパッケージは OpenGL, Audio, FreeType, Image, Movie, Compression なんていうゲーム作れと言わんばかりの内容。 sample も豊富。 NeHe を rewrite したりとか、気合い入りすぎ。 Self が Sparc と OSX でしか動かん(たぶん) のとは大違い。
クラスとオブジェクトの区別がなくて、 Object オブジェクト(class じゃない) を コピーして新しいオブジェクトを作り、 そのコピーしたものに動的にメソッドをいくらか追加して、 (OOP で言うところのクラス作り) その新しいオブジェクトをコピーして (OOP で言うところの new) 使うのです。 うまく説明できないけどあまり説明する気もない、メモだから。 サンプル。いい世界観。
SmallTalk はクラスとオブジェクトしか無いけど、 POP ではオブジェクトしかない。 ミニマルな OOP の実現。
POP は非常に汎用的な機構ではあるけど、 AOP の目的であるところの差分プログラミングも実現できる。 ここでまた好対照。 POP は first class object を厳選し、 それをとても汎用化して自己拡張可能な機構にすることによって、 個々のパラダイムを同時に解決する。 AspectJ や MJ は個々のパラダイムそのものを言語レベルで強力にサポート。
SmallTalk, Lua, Scheme vs. C++, Perl, OCaml って感じかな… クラスとオブジェクトしかない SmallTalk、 table だけで OOP もやっちゃう Lua、 マクロが強いんですかよく知りません Scheme。 巨大マルチパラダイム言語 C++、 予約語はある程度の数が必要と Larry さんも言ってる Perl、 関数型なのに OOP もサポートしちゃいました?(よく知りません) OCaml。 どっちが好みかな。
C++ は言語レベルでサポートするパラダイムが非常に多いけど、 自己拡張性もとても強い、無茶な言語。
以上もしったかぶりなので眉に唾をお付け下さいませ。
03.10.18■ [Program]: 主に D のことなど
これに対して Fixed! ってメールを頂いたんですけど、 news に投げられなかったのは何故だろう…
Unicode の identifier って欲しいんでしょうか。 よくわかってないんですけど、 なんで Unicode と ShiftJIS のマッピングが欲しいんだろう…
implicit instantiation のはなし。
D news:909(Walter)んなもんいらんよ。
D news:7678(Walter)理由はね…実際問題ややこしくなるんよ。
D news:7693(Walter)そうそう、シンボル名が無茶苦茶にもなるんよ。
D news:15856(Other)std::make_pair を、std::max をくれー。そーだそーだ。…反応無し
D news:16951(Other)何故そんなに嫌いなさるのか教えてくれんかの?そーだ。…反応無し
絶望的だなー。自分で勝手に実装できないかな…
■ [Program]: D のハッシュのベンチマーク
このへん見て、 itoa のベンチですかと思って、 しばらくしても誰も検証せんので自分でやりました。 ハッシュのベンチといえば Tietewさんのおしごと が素晴しかった記憶があったので、 それと 比較しました。 なぜか rd を使ってみる。
03.09.21■ [Program]: もろもろ
D presence on the far east なるスレッドを見て発作的に 日本のリソースリンク in 英語 を作ったんですけど、こんなもんでしょうか。 ていうかこういうものこそ Wikiを使った方が良いのかも。 でもあそこ使うと table の左っかわの日本語混じっちゃうしねえ。 特に文句や意見が無ければ news に post しちゃいます。
リンクといえば BulletML とかそのへんの リンク。
D で property がサポートされたわけですけど、
int len = strlen = "hoge";
なんて書けるのは不気味だな。 まあんなことするな、ってことか。
SWIG for D を 使ってみた。 凄いです。こんなに速く d_cpp が obsolete になるとは。
03.09.17いやだー。 これみたい。症状酷似しすぎ。 リプライを見るに、VC のデバッグモードで起きる。 ある程度動かすと起きる。 環境によって動作は変わる。 安全だとわかってる Access Violation なんてリリースビルドで無視しちゃえ。 とのこと。
さて、どうしよう… こいつをムシするには phobos の deh.c を書き変えれば良さげ。 それかそもそも発生しない状態(リリースビルド相当の状態)に すればいいんだろうけど…結構面倒そうだ。 なにせ deh.c には
/*** From Digital Mars C runtime library ***/
なんて文字が燦然と。これって多分ソース無いよね。
とりあえず libBulletML のサンプルにはなるし、 Linux では動くし、置いとくかな。 くやしいからもいっこスクリーンショット。 自機視点緋蜂。わけわからん。
03.09.17■ [Program]: D メモ
libBulletML for D がちゃと使えるかの検証のために作ったものが、 Linux では こんな感じ。 (サイト容量がいよいよアレなので超低品質jpg)
で、Win に移動しようとするとはまりまくったのでメモ。
dmc。 ダメ。 libBulletML コンパイルできない。修正めんどうそう。
同じ OMFなら…と、Borland C++。 ダメ。 Borland C++ 独自の __turboFloat なんていう感じのシンボルがいくつか。 これを Borland C++ のライブラリから引っ張って来ようとすると 他のシンボルが多重定義になってダメ。
仕方が無いので、ilink32 でとりあえず dll を作って、 implib でインポートライブラリ作ってリンク。 test_bulletml.d はリンク、実行できた。
でも こっちはダメ。 いろいろやってみると画像処理を全部コメントアウトすれば動く。 libBulletML & 回避機関は無罪。
link axis+bulletss+camera+charactor+cpuinput+mymath+padinput,,,user32+bulletml+SDL+opengl32+glu32+cpu+kernel32/noi;
なんてやると ABAさんのおっしゃる通り、 glu32.lib が不正だと言われるんで glu32.dll から implib。 opengl32.lib も最初のアンダーバーが付いてないシンボルを持ってるようで、 うまくリンクできないから opengl32.dll から implib。
で、リンクして実行するとすぐ落ちちゃう。 SDL-doc の OpenGL のサンプルの D版 でも症状が同じだから GL の問題な気がするけど…
それはそれとして、libBulletML for D は間違いなく dll も配布すべきだと思いました。今度整理します。
あともう一つ、d_cpp は def ファイルも perl で生成して、 それ使って dll 作るような経路が良さそうな気もしました。
03.09.12■ [Program]: D Strings vs C++ Strings
うわーいはやいマンセー。
などと、言うはずもなく。 いかがわしいベンチっすねえ…
たぶん C++ プログラムのボトルネックはファイル読み込みと map。 このベンチで言えることは、「dmc では rdbuf は高速な実行ができない」 「map と hash_map なら hash が速い」なんていうこと位かと。 ページの内容と bench の内容は無関係。
つうわけで ちょちょいといじって、比較。 あと const 外しはマズかろうとか、hash_map 使うのは反則だろうとか、 icc使うのかよ、とかあるけど、まあ気にしない。
> icc -O3 -o wccpp1 wccpp1.cc
さて、
> time perl -e 'for ($i=0;$i<100;$i++){system("./wc alice30.txt >/dev/null")}' perl -e 'for ($i=0;$i<100;$i++){system("./wc alice30.txt >/dev/null")}' 4.96s user 0.71s system 93% cpu 6.042 total > time perl -e 'for ($i=0;$i<100;$i++){system("./wccpp1 alice30.txt >/dev/null")}' perl -e 'for ($i=0;$i<100;$i++){system("./wccpp1 alice30.txt >/dev/null")}' 4.60s user 0.77s system 100% cpu 5.363 total
まあこの結果においても、このベンチは何の役にも立たんと思います。 少なくとも String の比較として適切ではないでしょう。
後日 dmc についても調べてみて、 文句の一つも言ってみようかな。
ただまあ、D が速いのは事実なんですけどね。
しかし C++ で現実的にファイルを全部高速に stringに読む方法って何だろう。
FILE* fp = fopen(argv[i], "r"); fseek(fp, 0, SEEK_END); int len = ftell(fp); fseek(fp, 0, SEEK_SET); std::string input(len, '\0'); fread(const_cast<char*>(input.c_str()), 1, len, fp);
これはヒドすぎるよなあ…
縁あって触ってるんですけど… うーんアスペクト思考には魅かれるものがあるけどこの処理系とか… まあ研究目的…
Robocode でもういっこロボットを書こう書こうと思ってるんですけど、 普通の Java じゃやる気起こらんから気になってたんだけど。 AspectJ を見てみようかな。
03.09.04■ [Program]: SDL_image_j2k
なぜか知りませんが、jpeg2000 を調べてみた。 で、なぜかは知りませんが、 SDL_image_j2k。 こちら で libj2k を入手されたし。 j2k ファイルなんて無いよう、という方のために、 サンプル。 ちなみに rate 落としまくりで 480x640 でたったの 994バイト。
■ [Program]: D - foreach
きたね。
そういや、ABAさんのおっしゃっていた interfaceまわりの不具合って こっちの Bugs Fixed の三つめ だと思ったんだけどうちではうまく動かなかったんで保留してました。 Win32 だとどうなのか試してみよう…
03.08.27■ [Program]: D のはなし。
長くなりそうだからツッコミを使うのは放棄。
配列初期化の件。 {} って こっちの初期化に使うはずなんで、 ドキュメントがおかしげかと。
Exception。 Exception よりは Error を使う方が良い気がします。 next とかいうメンバ持ってるから、 エラーを複数所持したりするつもりなんですかね。 あと msg で取るよりは toString, print メソッドが良いかと。 ちなみに phobos の object.d を見ました。 ドキュメントされてるかどうかは知りません。
ガベコレ対策全くしてないや… new してそのままなオブジェクトが結構ある…ダメダメ。 ガベコレの速度が気になるようなものを ガベコレのある言語で書いたことないからなあ。
■ [Program]: SDL_kanji_rle
素晴しいおしごとのつまみ喰い。 結構サイズ減るなーと感動したんですが、 私的には 2D/3D 両方に出力したいので 2D 版をこさえました。 gl_kanji と同じフォントデータで使えます。
ソースは SDL_kanji を流用していると思いきや、 かなり遅げなレンダ処理を書き直したり、 データの持ち方が全然変わったりしてまして、 …つまり、ロクにテストされてません。 そのあたりのいろんなチェックと、 SDL_kanji といえば NetBSD なのでそちらでのチェックを したあとまともにリリースします。
さて、SDL_mixer & SDL_sound の目指している地点のように、 入力のしかた (bdf, f1b, ...)、 内部的なデータの持ち方、 出力のしかた (SDL_Surface, GL, ...)、 の接続を抽象化して組み合わせたらさぞかっこよかろうとは思いますが、 やりません、できません。
D はいいよー光線出し担当です。 そう、ゲーム屋こそ D。たぶん。 まだガベコレの挙動とか見てないんでそれだけ不安ですが。
で、 SDL_mixer.d。 自動的にこれ作るのは結構骨が折れると思います。たぶん。 ついでに、 playmus.d。 標準出力に音量を出すおまけつき。 コールバックがちゃんと使えるかどうかチェックしただけです。
ていうか SDL のバインディング位なら全部 D の インポートライブラリ作ろうと思っています…
■ [Program]: Lua-D など、D よしなし
Lua-D をほげほげやっとるんですが、 本家様のはちょっといいかげんみたいです。 まず現行のコンパイラではコンパイルが通らない、 ってのはちょこちょこいじったらいいとして、 lua_register の挙動がチェックされてないと思うんです。
// dfunc.d import stream; import string; typedef void (*F) (int); extern (C) { void ff(F f); } void f(int i) { stdout.writeLine("hoge" ~ string.toString(i)); } int main() { ff(f); return 0; }
/* cfunc.c */ typedef void (*F) (int); void ff(F f) { f(1); }
なんて書くと、
> dmd -c dfunc.d > cc -c cfunc.c > cc -o dfunc cfunc.o dfunc.o -lphobos -lpthread > ./dfunc hoge134517024
と、C から D linkage の関数はまともには呼べません。 解決するには typedef と関数 f を C linkage に押し込めれば OK。 で、Lua-D はそうなっとらんのではまったはまった。
で、今までやったことの パッチ。 もうちょっと様子を見てから本家に報告してみると良いかもと 思っていますが、newsgroup を見てないんで既出かどうかチェックしないと。
D はいい感じですよ。 とりあえず C++ 屋にはたまらんコンパイル速度です。
i@u wrk/cave/src> cat **/*.d | wc # ソースの行数を 2744 7904 60348 i@u wrk/cave/src> time make > /dev/null # コンパイル+リンク速度 make > /dev/null 2.49s user 0.32s system 83% cpu 3.359 total i@u wrk/cave/src> rm cave # 実行ファイルだけ消して… i@u wrk/cave/src> time make > /dev/null # リンク速度だけ make > /dev/null 1.40s user 0.11s system 100% cpu 1.497 total
つうわけで 2800行が 1秒。 このソースは bpo を地道に D 化しているもので、 書いてる内容の密度はそんなに変わらんはずです。
libBulletML の自分で書いた部分は 2300行程なんですが、 同じ環境で 33秒かかってるみたいです。 C++、特に g++ が遅すぎるという話もありますが。
あんまり速いんで ttyrec りました。
なんか不思議な希望に燃えてコーディングするような 元気が湧いてこない状態なので、 ダメダメなゲームになることが約束されている 自機が弾幕を発射するゲームを雑に作ってます。 D & Lua で。 こんなの。 cave という実行ファイル名は謎ですが。
あ、あと、 SDL_gfxPrimitives.d 。
D で SDL とそのまわり、OpenGL、Lua なんかが 普通に動かせるようになってきてて嬉しいんですが、 なんか微妙に欠けてる感じもします。 double linked list がたぶん無いとか。
ダルくて支離滅裂。まあいずれちゃんとまとめます。
■ [Program]: OpenGL with vertex shader
メモ。
vertex shader ってのは座標と色を受けとって、 表示する時の座標と色に変換して返す処理、ってなもの。 デフォルトではモデリング変換して、光があったら光あてて色計算して、 ってことをしてくれるんですが、小細工をしたい場合があるとか無いとか。 で、オリジナルの処理に差し替えれるらしい。 DirectX は 8 から。OpenGL は ARB拡張と NV拡張で。 僕が触りたいのは OpenGL & ARB拡張。 まあ一番広い環境 (OS, ビデオカード) で動きそうですし。
vertex shader はアセンブラで書いて OpenGL 経由でビデオカードに渡す。 そのへんの API は Cg + OpenGL プログラミング で十分わかった。
アセンブラは嫌だから高級言語を作ってくれたのが Cg。 NVIDIA が提唱してるってことで、NVIDIAのカード以外では あまし良くなかったりしそう、とか勝手に思ってたけど勘違いの模様。
Cg の利用法は二種類。 cgGL プレフィックスで始まるような API を駆使して、 Cg からアセンブラへの変換を実行時に行うやり方が一つ。 このへんは [t-pot] PROGRAMMINGが素晴しかったです。
もう一つは Cg コンパイラ cgc を用いて前もって OpenGL ARB拡張用のアセンブラコードを作っておいて それを OpenGL の ARB拡張 API から呼び出すやり方。 こっちのやり方では vertex shader にパラメータが渡せない (Cg内のシンボルがどのレジスタに割り当てられてるかがわからんから) と NVIDIA の資料には書いてあったんですが、 Cg + OpenGL プログラミング を見たら Cg 側にシンボルに対して使うレジスタを 指定することによってできるみたいでした。
あとはなんといっても、 NVIDIAのサイト。 ここから Cg_Users_Manual_JP をもらいました。
■ [Program]: くらえ、パルカナズンタ!
ちょっと面白いものを作ったんで見て下さい。お願いします。 ドラクエの魔法から新しい魔法を生成するのです。 ソース。 こっちの糞ゲーでも使ってる markov chain をしているだけっす。
キミは本当に自動生成とか好きね。 ガディンパルーンタ!
追記:あまりにもお約束な文字化けを解消。 ごめんなさい、ゾーラゴラリーン!
03.07.05■ [Program]: ICFP
ICFP Contest で自分の無力さを思い知りました。 くやしかったです。 今回の問題は車でコースを走る時の最短行動を求めるというようなものでした。 ドリフト無しのマリオカートシミュレータといったところ。 tie-breaker として用意されたルールがドリフト付きの マリオカートシミュレータかな。
基本的には A* でやろうと思ってたんですが、 今まで実装したこと無いのでうまくいくかどうかの自信も無く、 それだけに集中してアルゴリズムを書く根性も無く、 あれこれしてみて、うまくいきそうな方法があったらそれを煮詰めよう、 などと思ってたらどれもうまくいきそうじゃなかったという。 そうじゃなくてこれだっていうアルゴリズムを一つ決定して、 それと心中するのが正しかったか。
終わってから公開されたソースとか見ると思いの他 シンプルな A* で凄いタイムが出てたりして、なんとも… A* の実装に連想配列なんて使ってる時点でダメだったんだな。 そのプログラムは heap 使ってたんだけど、 私は使ったことすらないから微塵も思いつかなかったよ…
1 8383 2 13611 3 15720 4 16103 5 5776 6 5010 7 4238 8 8604 9 9991 sum 87526
参加者でないと意味のわからない数字の羅列。 色々プログラム書いたけど結局これはほぼ handmade。 一応参加しておくことで来年報復する決意をね。
K.INABA さんも参加されてたのか… 仲間がいるってのがいいな。
■ [Program]: うーん、わかんない。
D 言語では仮想関数にすべきかどうかを 勝手に判定してくれるってことなんで、 検証してみようと思って書いたこの ソース。
結果がよくわからんのです…
D D D Derived.func: 1030000 Base.vfunc: 1090000 Derived.vfunc: 1010000 BBase.vvfunc: 1020000 Base.vvfunc: 1030000 Base.vfunc: 1075470304 Derived.vvfunc: 1110000
最初の三つは多態が働いてるか見ただけ。
その後の三行目まではうまく行っていて、 vfunc はちゃんと仮想関数になってるらしく、 Base から呼出すと遅くなって、Derived からだと 多態的な動きをする必要がないので、速度は落ちない。
そっからは無茶苦茶… 速度もおかしいし、謎の関数呼出しは発生しているし。 結果が未定義なコードだとも思えないんだけど…
ちなみに Win32 でも… (といっても wine でコンパイル & 実行。しかし wine は便利だ。)
Derived.func: 2205 Base.vfunc: 2209 Derived.vfunc: 2164 BBase.vvfunc: 2165 Base.vvfunc: 2204 Base.vfunc: 1087319744 Derived.vvfunc: 2204
ちゃんと情報を収集する態勢を整えないと始まらんな。 とりあえず newsgroup 眺めれば良いのかな。 あ、無茶だとは思うけど がんばれ。
■ [Program]: testsprite
忙しいと小ネタを作りたくなります。で、testsprite。
ゲームライブラリとしての SDL において重要なのは、 速度、実行パッケージサイズ、使いやすさなどってところですか。
C。200FPS。30KB。
C++。200FPS。30KB。C をそのまま使える。ラッパ多数。コンパイル遅い。
D。200FPS。90KB。 dmd for Linux でコンパイルすると phobos とかは static link するみたい。 コンパイル速い。 dli でもやってみないとね。
OCaml。180FPS。72KB。 何もかも static link してるみたい。 OCaml 素人につき非効率なコード書いてる恐れ高し。 ttf, mixer, image ごちゃまぜ。 コンパイル速い。
Eiffel。170FPS。88KB。 ちなみに処理系は SmartEiffel 使用。 image が混じってます。 jegl は結構ちゃんと DbC しているみたいです。 コンパイル遅い。
C#。 150FPS。?KB。 Zinniaさん作。 mono で実行。なんか速いんですけど…
Java。165FPS。150KB。 C# のソースをいじって作りました。 つうかパクるんだったらパクるで シンボルの名前を無駄に変えるんはやめてくれ、C#。 VM ってこと考えると敵ながらあっぱれな数字ではあるかなあ。 まあ VM をインストールしてくれ、 っていう要求をしなけりゃならんのがなんともきつい。
Ruby。135FPS。130KB。 mixer, ttf, image, sge, smpeg, sdlskk がオプション。 RUDL ではなく Ruby/SDL。 今のところスクリプト言語では圧倒的な速さなのだけれども。 元のソースをほんの少しいじっています。
Perl。33FPS。140KB。 image, mixer, net, ttf, smpeg, gfx, console, sfont となんでもアリ。 この尋常じゃない遅さはナゼ?
Lua。88FPS。270KB。 組込み向き言語に低レベルAPI である SDL を触らせる理由が思いつきません。 サイズの巨大さは Lua と tolua の定義を持ってるからっぽい。なんで? testsprite.lua は luaSDL 付属サンプルの 汎用的なゲームフレームワークっぽいものから作ったので、 かなり非効率だと考えられます。 あと、環境作りがとても大変。lua-4.0.1, tolua, luamodule patch が必要。 全くお勧めできない。
Erlang は testsprite が入ってるんですが、うまく実行できませんでした。
Objective-C, Pascal, Python, PHP あたりが見てみたいところです。
が、testsprite を書くのはもう飽きました。
testsprite なんてほとんど描画処理のはずで、 その証拠に testsprite 自体のコンパイルオプションを 変えてもほとんど FPS に変化は無いんですが、 そういうプログラムがただ言語のせいだけで遅くなる、 ってのは複雑な処理をするプログラムではかなりの障害になるはずで、 実際問題としてはなかなか使いずらいもんですね。
あといずれのソースもかなりいい加減に書いています。 う飲みにせんで下さい。
ていうか Windows でも試せとか思いました。 あと HW_SURFACE が生きる環境でも。 そのへんの色んな比較を Knowledge Foundation でできると 面白いかもしれないと思いました。
さあ、あなたならどれを使いますか? C ですかそうですね。
追記です。ごにいさんが testsprite for pythonを 作ってくれたので早速チェック。 python のインストールに実に手間取る。110FPS。?KB。 確かにちょっと Ruby に負ける。 全部動的モジュールになってて使うものを好きに選べるんですかね。 しかし一つ一つがやたらでかいんですけど。 スクリプト言語のなかでは自由度的にも速度的にも Ruby/SDL が良く見えます。
そろそろ10回ほど icon.bmp が無いよ、というエラーを見たような。 しかし私のマシンにゃ何個言語処理系が入ってるんだろう…
■ [Program]: EnemyML とはあまり関係無くデータとかスクリプトとか。
キターということで。 あと、Lua は楽でいいですよ。 自分で独自言語作るなんて馬鹿らしくなってきます。
雑感。 well-known な形式である以上既存のライブラリの存在やら、 XML の愉快な仲間達は相当に魅力的ではあるんですが、 まあそれにしてもゲームに使うには重いし冗長だし、 最適解だとはとても思えないと思う。 まあでもネタとしては面白いし、 PC でやるんなら潤沢なリソースがあるし、 わりと良い解ではあると思うんだけれども。
んじゃ理想は何かっていうと、 YAML と Lua なんてどうじゃろ、と思いました。 YAML はスクリプト言語のデータ構造に 直にマッピングしやすいように作ってある言語で、 理想的には MVC の M = YAML, V = コンパイル言語, C = Lua みたいなことができれば面白いんでないかと。 YAML はコンパイル言語とは特別相性が良くないので、 M と V の接続が弱いのが厳しいところですが。
もうコンパイルするプログラムはエフェクトだの オブジェクトの保持だのといった処理のかかるところだけにして、 基本的なゲームの動きは Lua に任せてしまうというか。
あと、Lua のテーブルは元々 M を意識して作られてるけど、 YAML にも XML みたいな愉快な仲間達が出てくると予測されるので、 Lua と分離するメリットは十分にある気がする。
でも、それ使って弾幕書くかっていうと、 かなり前から弾幕書くのも飽きてるんで、 まあ別の機会に何かやってみたいところです。 D と Lua と YAML でゲーム作ったら相当マニアックで良いと思った。
■ [Program]: BulletML とスタイル指定
それはそうと、弾の色とかを指定できるようにしようと思う。 今のところは以下のような感じを妄想。名前はいいかげん。
<barrage> <barrageInfo> <group>user</group> <title>タイトル</title> <description>2説明</description> <capture>攻略</capture> </barrageInfo> <barrageStyles> <bulletStyle figure="ball" color="white" /> <!-- label が無いのはデフォルト --> <bulletStyle label="bomb" figure="bomb" color="red"/> <bulletStyle label="laser" figure="laser" color="blue" type="laser" /> <bulletLanguage name="bulletml" /> <!-- Lua とかもここで指定するとか --> </barrageStyles> <bulletml type="vertical" xmlns="http://www.asahi-net.or.jp/~cs8k-cyu/bulletml"> ... もちろんこの中に <bullet label="laser"> とかがあるわけ。 ...
本当は barrage 単体がルートノードというのは嫌で、 barrage と bulletml が両方ルートノードになれれば 今までのプログラムとも矛盾が発生しにくいと思うんだけど、 XML ってルートノード二つ持ってもいいんだろうか。
基本的には HTML とスタイルシートみたいな関係で、 bulletml の方は全く変更無しで、 スタイルだけ外から指定するってのと、 同じファイルに何がなんでも詰めこみたいなあと思っています。
03.05.25■ [Program]: testsprite
testsprite for C# 関係で、面白そうだったので quick hack。 testsprite for D。 testsprite for Ocaml。 D言語版は C 言語版と diff すればいかに何もしてないかがわかるかと。 OCaml版は OCamlSDL の sample である testalpha.ml のソースを流用しまくっています。
さて、FPS ですが、 C のが 200FPS, D のが 200FPS, OCaml のが 175FPS ってとこでした。 OCaml は不慣れなんで非効率なことをしている気がします。
しかし 1/3以下というのはキツいっすね。 だって Ruby/SDL でも 130FPS ということで半分以上は出てますし。
といっても終わってしまっている上に C++ は対称範囲外ですが。
#include <vector> #include <iostream> template <class T=int> struct C { T b(T _=0) const { return ~_<<_?_<_^_>_:_>>_; } }; template <template <class> class T, class U, class V> U a(U (V::*g) (U) const) { return sizeof((T<U>().*&T<U>::size)()) (C<>().*g)(0[""]); } int (*f(int (*g) (int (C<>::*) (int) const))) (int (C<>::*) (int) const) { return (int (* const) (int (C<>::*) (int) const))g; } int main() { std::cout << f(a<std::vector,int,C<> >)((1,&C<>::b)) << std::endl; return 0; }
typedef せずに関数ポインタは使うなというおはなし。 意味のある動作をするように育てていきたいところ。 今はそれぞれのトピックをばらしている感じだけど、 C 本来の邪悪コードと C++ の邪悪コードを うまく混ぜれば楽しいことになるに違いない。 trigraph はアリなのかねえ。
struct C { C operator()() { return *this; } C operator()(C c) { return *this; } C operator==(C c) { return *this; } C operator<=(C c) { return *this; } C operator>=(C c) { return *this; } C operator<(C c) { return *this; } C operator>(C c) { return *this; } C operator<<(C c) { return *this; } C operator>>(C c) { return *this; } }; int main() { C c(C()((C()())<=C(C()>>C()<C()))); };
そういえばどこかに…と探したところこんなのも見つけた。
■ [Program]: ttyrec's information in status line
ttyrec にステータスライン使って情報を表示する パッチを作った。
ファイル名、経過時間、現在の速度を表示します。 status line が使える端末で、ttyplay -h で起動すると良いかと。 試した環境は kterm on linux だけ。 しかし巻戻し機能欲しい…
ついでに… レベル1 でノームの炭坑町まで行って僧侶に AC を 8つ落としてもらった ttyrec ムービー。 炭坑町に行くまでの努力が重要なのに、 ttyrec り忘れてて炭坑町からでしょんぼり。 現状レベル1で AC -11。 この後はもうちょっとレベル1での AC を追及して、 寺院乗っ取りでもしようかな。
1年半ほど真剣に期待している言語です。 K.INABAさんの解説が超秀逸です。
K.INABAさんが細かく見ておられないところを見ていこうかと。 とりあえず partial specialization をチェックすることに。 C++ 的なコンパイルメタプログラミングはどうしても 再帰を多用したプログラミングになるということで、 再帰の例としてよく使われるけど全く例としてふさわしくないとして、 Efficient C++ で絶賛されているフィボナッチ数列を。 とりあえず C++ だと…
#include <stdio.h> template <int lp> struct p { enum { fib = p<lp-1>::fib p<lp-2>::fib }; }; struct p<0> { enum { fib = 0 }; }; struct p<1> { enum { fib = 1 }; }; int main() { printf("%d\n", p<1000>::fib); return 0; }
Dで書くと…
template p(int lp) { instance p(lp-1) p1; instance p(lp-2) p2; enum { fib = p1.fib + p2.fib }; } template p(int lp : 0) { enum { fib = 0 }; } template p(int lp : 1) { enum { fib = 1 }; } int main(char[][] arg) { instance p(1000) pi; printf("%d\n", pi.fib); return 0; }
両方ともオーバフローしまくってますが、 同じ結果が出ました。 素晴しいのがコンパイル速度。
g++ -o partial partial.cc -ftemplate-depth-100000 3.57s user 0.09s system 98% cpu 3.723 total dmd partial.d 1.04s user 0.04s system 99% cpu 1.088 total
速い速い。 dmd ってのは Linux 用コンパイラです。 残念ながら dli ではコンパイルできませんでした。
今度は DbC を見てみよう…
■ [Program]: 白い弾幕くんのいろいろな値。
game specific な値を書き出しておきます。
画面サイズは 300x400。 最初の敵の位置は (150, 100), 自機は (150, 350)。 スピードを省略した bullet の速度は 1。 速度 v の bullet は 1 秒で v ピクセル進みます。 BulletML の実行は必ず約 60FPS。 プレイヤー速度はコンフィグの値の 1.5倍(糞仕様)。 direction の type 省略時は aim。 term 要素は 0 と 1 は同義 1 を推奨。 action を持つ弾が発生したターンには その action は実行されない。 changeSpeed ででかい速度にして wait 1 してから 停止させるのは FPS 次第で動く量が変わったりするので非推奨(ダメ仕様)。 あと XML 形式のコメントが書けないのに最近気付いたのですが、 ただのバグなんで次回修正します。
東方スキンのデキが良いと思った。見やすい。 あと 東方弾幕も。 どっちも紫月飴さんに教えてもらいました。
I-Saint さんが XMLでスクリプトを作られているということで期待… EnemyML の夢が。
03.05.01■ [Program]: 細々と gcc pch
前回。
結果を一個追加。 3.4-1 は使っているライブラリを stdcpp.h に全部収めて、 それをプリコンパイルしてあります。 3.4-2 は STL を大体プリコンパイルしてあります。
cppll から持ってきたこのソース。 個々にコンパイルすることによってちょっと遅くなった。
2.96 : g++ -c cppll.cc 0.88s user 0.04s system 100% cpu 0.915 total 3.4 : g++ -c cppll.cc 2.68s user 0.22s system 77% cpu 3.728 total 3.4-1: g++ -c cppll.cc 0.43s user 0.06s system 101% cpu 0.483 total 3.4-2: g++ -c cppll.cc 0.59s user 0.11s system 20% cpu 3.496 total
bpo。 個々にコンパイルすることによってかなり速くなった。
2.96 : make 165.99s user 5.73s system 93% cpu 3:03.42 total 3.4 : make 218.56s user 5.21s system 95% cpu 3:53.78 total 3.4-1: make 247.63s user 6.12s system 95% cpu 4:26.22 total 3.4-2: make 214.95s user 5.43s system 96% cpu 3:49.18 total
これまでのまとめとして、
ということから、STL だの、汎用的によく使うライブラリなどは 全部一つずつプリコンパイルしておいて、 個々のプロジェクト内でよく使うライブラリは 一つの stdafx.h にまとめてそれをプリコンパイル、かな。
ていうか VC って多分そんな感じじゃないのかな… きっと熟練した Windows プログラマには何を今更な話に違いない…
■ [Program]: Robocode Rumble-JP
そろそろなんで、宣伝をしようと思いました。 Robocode っていうゲームがあります。 どんなゲームかっていうと、画面の中で一定のルール下で戦う ロボットのプログラムを書いて誰が強いかと競うっていうゲームで、 カルネージハート を知ってる方は、 アレのハード設計をなくして、ソフトを Java で書くものだと 思って頂ければ、まあそんなに間違いはありません。
で… いろいろあって、 とりあえず ジャパンカップ の追検証みたいなのを行い、 その後でまた大きな大会でもやりたいね、って話になっています。
で、Java, Tomcat, Struts, Axis, MySQL, EJB など 眩暈がするほど、流行っぽい技術が 使われた システムも、 私はたいしたこともしてませんが、 結構なクオリティになってきてまして、 とりあえずそろそろ追検証の方をやれそうになっています。
まあ、興味のある方はご注目の程を。 とりあえず、 システム以外 ML やら、 開発者 ML やら フォーラム やら。 今から強いロボットを作っておけばリナザウもらえるかもしれませんぜ。
そうそう、 SourceForge.jp でここしばらく活発なプロジェクト一位だった… と思ったら二位になってるや。
03.04.21■ [Program]: gcc pch 前回の嘘。
Merge from pch branch、ではなく、 PCH merge completeや、 Merging PCH to mainlineに リンクをはるつもりでした。
03.04.20■ [Program]: gcc pch
Merge from pch branch。 この嬉しいお知らせを発見したのはいつだったか忘れましたが、 忙しくてなかなか試してみれませんでした。 状況は良くはなってはいませんが、とりあえず試してみました。
もうメインブランチに入っちゃっているので普通に checkout、 ./configure, make, make install。 久しぶりだったからかなんか知らないけど、 コンパイルに多少手間取ったりしつつもインストールできました。
で、実験。なんでこれを選んだかは知りませんが、 cppll から持ってきたこのソースが対象。
2.96: g++ -c cppll.cc 0.88s user 0.04s system 100% cpu 0.915 total 3.4: g++ -c cppll.cc 2.68s user 0.22s system 77% cpu 3.728 total 3.4-pch: g++ stdafx.h 3.78s user 0.37s system 93% cpu 4.448 total 3.4-pch: g++ -c cppll.cc 0.43s user 0.06s system 101% cpu 0.483 total
2.96 なんて無いって話があるんですね。まあいいや。 pch 無しの 3.4 はなんでこんなに遅いのかなあ、 コンパイラ自体のコンパイル最適化が甘いのかと思います。 三つ目の結果は素晴しいですね。 ちなみに stdafx.h には
#include <iostream> #include <numeric> #include <vector> #include <functional>
と書いてあげました。 ところで stdafx ってなんだろう。 それもまあいいや。サイズは相変らず巨大。 gcc って zlib のソース持ってるんだからねえ。
-rw-r--r-- 1 i 8.4M 4月 21 00:33 stdafx.h.gch
前回 と比べて何が凄いって、落ちたりしない。 前回は boost とかはほとんどこけちゃっていた。 実用は近いって感じでしょうか。
実用っぽいをやってみる。 bpo。 どうやるべきなのか、よくわかってませんが、 とりあえず標準ライブラリを stdcpp.h に集め、 boost のものを boostall.h に集める。 うーん、pch が一番遅い…。 集めすぎってのも問題なのかな? ムダに include しすぎるわけだから…
2.96: make 165.99s user 5.73s system 93% cpu 3:03.42 total 3.4: make 218.56s user 5.21s system 95% cpu 3:53.78 total 3.4-pch: make 247.63s user 6.12s system 95% cpu 4:26.22 total
まあ、正しい運用法はこれから探っていこうと思います。 まだしばらくは ccache の お世話になりそうです。
とりあえず個々のヘッダごとにプリコンパイルしてベンチ、 ってのをタスクキューに放り込んでおこう…
03.02.27■ [Program]: Zaurus で Wiki したいですね
かといって CGI はチト重い、と。
で、 yEdit_0.0-5に対するパッチとして実装してみました。 こんなの。 やったことは…
Save auto file で一番最初の行をファイル名を抽出して保存できるように。
.yeditrc に auto_suffix=.txt などと書くと、 さっきの保存するファイルにサフィックスが付く。
.yeditrc に link_prefix=[, link_suffix=] などと書くと、 [] で囲まれた中身がリンクになる。 リンクをペンで叩くなりリターンするなりで発動させると、 それにカレントディレクトリにそのリンク名に さっきの auto_suffix を付けたファイルがあればそれを開き、 無ければそのファイル名で新しいファイルを開きます。
んだけ。設定とかは手動でやるしかないです。
03.02.22■ [Program]: boost quternion
adas さんに教えて頂いた問題について、 adas さんにはもうご報告したけれども、一応。 boost-1.29 までの quaternion はコピーコンストラクタが inline 関数じゃないので、複数のソースファイルで読み込むと 多重定義になっちゃう模様。
03.02.06■ [Program]: リナザウ関係。
白い弾幕くんの画面ずれについて。 なるほど。早速、修正してアップしておきました。
zgnuboy は この方同様 音が死んじゃっています。 /dev/dsp 決め打ちじゃなくて、 SDL による音出しもオプションで選択できると嬉しいですね。
znester は音も死んじゃってますが、 また別の問題もあるっぽくて、 突然キーが効かなくなったりするんですが、 これは A300 環境で調べた方が良さそうな問題なので、 ソースを公開されるのを待ちます。
TODO: zgnuboy, znester を眺めていろいろ。
うっかりバッテリを使いきってしまって、 メモリがふっとんじゃいました。 バックアップ環境をきっちり作ろうとしていた矢先に… とり急ぎ rsync でバックアップする環境を作る。 んー rsync サーバが立てれない。まあ rsh 使えばいいか。
いっぺんふっとんでから、libgcc_s.so が無くて、 色々アプリが動かないんですが、 これって昔は入ってたような気がするんだけどどうなんだろう。 とりあえず入れるけど、ひょっとして人様の環境には 入ってなかったりすると悲しいな。
TODO: bmda の移植終了。
■ [Program]: ロボコード関係。
実はイロイロやってました。 まとめてみます。
ジャパンカップ準優勝。 なんていうか、一生懸命作ったロボットを じゃんけん大会で評価するなんて非道く無いかい? と、嫌な感じ。
Robocodeスレッド の 892 で 間違ったロボットが決勝トーナメントで争うという、 どうしようもない事実が発覚。
スレッド 905 で返事。 返事の内容は新しいことやるんなら協力するけど、 まあ諦めろ、って感じ。
914 は私。 んじゃやりませんか。でしゃばる私。
とりあえず ML などでっちあげて、 基本的なことを議論。
IBM にメール。返事。なんか案外乗り気なのね。 一度会おうとのこと。
IBM 大和研究所に行く。なんか異常に乗り気。 ジャパンカップの追試及び新大会やろうじゃん、と。 追試はロボットを提供するよ、と。 新大会はスポンサー探しやら賞品提供とかやってやろう、と。
とりあえずジャパンカップの検証大会(アゲインと呼称)みたいなのを、 様々な練習をかねてやって、 その後新大会をでっちあげる予定。
アゲインはただジャパンカップのロボットをもう一度勝負させるだけ。 新大会はうまくいけば賞品とかスポンサーとかついて でかい大会ができるかも、ということらしい。
なんとなくアゲインのルールは固まった感じかな。 システムの方も素晴しいプロトタイプを作って頂けた模様。 とりあえずシステムの動きを把握しなければ。
というわけで、今までやってなかった人もレッツロボコード。
TODO: システムのコードの把握。システムの改良。
TODO: 新しいロボットを作りたいね。
■ [Program]: リナザウのおはなし。
えと、前回の saga1 が遅いってのは、嘘でした。すいません。 本体メモリの物体を SD に移したらほとんど解決しました。 まあほとんどフルスピードと言ってよい状態になっています。 画面ずれ。 SDL 側で xy が逆転してるんかな。 暇な時に眺めてみます… あと、 SL-5500 はネットで見る限りは、SL-B500 と 同じ扱いで問題無さそうな感じがします。自信皆無ですが。
03.01.14■ [Program]: リナザウ最後の日記的報告。
1月12日晩。SL-B500 と SDカードを見に渋谷へ。
B500 問題を見る。ソース見てもラチがあかんので、 唯一のてがかりである スクリーンショットを分析。 見たところ全てのドットが打たれているようだったので、 状況を理解するために復元するプログラムを書いて、 もとの画像を復元してみる。できた。 で、しばらく頭をひねっていると、ただ x-y が反転しているだけだと気付く。 凄くいい加減な B500 専用コードを書く。
1月13日。この日はほとんどネットに繋げない。 2ch に実験してくれんかと書き込み。 よし。嬉しいね。協力ありがとう、690, 691氏。
ネットから切れので、SD カードを買いに行こうと思った。 近所のビックカメラは 128MB が 7800円だったけど、 価格.com では通販価格 5500円だと。 秋葉に行く。6000円が一番安かった。Sandisk の 128M。 そこらのネットに繋がっている展示機で 動作実績があるかチェック(すいません)。 もろ 鬼門。 次善の 6400円の東芝の 128M になりました。 ビックカメラは一割還元で 7000円だとすると、 6400円 + 往復 380 円でロクに安くなってない。敗北感。 だいたいこんな吹けば飛ぶような (2グラムだそうな) ものが 何でドリームキャストより高いねん。 もともとあまりメモリを使うような作業をしない人間なので swap は保留。 ソフトを SD に移すとずいぶん速くなった。
1月13日晩。SDL のパッケージ化、KoboDeluxe の移植など。
せっかく母艦側で Webサーバが動いてるのだから、と、 母艦からソフトをネットワークインストールできるようにしてみた。 とても便利になりました。
だいぶ動きが鈍ってきた。
1月14日。 やっと qtopia の勉強。 sharp のチュートリアル がよくできていると思いました。 ありがとう sharp。 そろそろ熱が冷めないと真剣に放校になりそうなので、 もうこんなことを書くのはやめようと思う。
ていうかまだ貰ってから一週間たっていないのね。
■ [Program]: qtopia SDL
で、A300, B500 の fix をした SDL の ipk パッケージ。 パッチ。
本当は escape で SDLK_ESCAPE を発生させるんじゃなくて、 escape+space 位で SDLK_ESCAPE を発生させるように 環境変数で切り換えられる裏技を仕込みたいなあとか思ってるんですが、 いくらなんでも汚なすぎだよなあ… でも左押す時に絶対触っちゃうんだよね。
白い弾幕くんは BulletML ビューアにはなっているので、 ゲーセンで弾幕をコピーする、 という当初の目的は果たせそうなので半分満足していたりしますが、 ありがたいことに楽しみにされているとのことなので、 高速化してみたいと思います。 現状弾が増えると 10FPS 未満と死んでいます。 C700 なら15FPS 位にはなるのかな。 まあとにかく double の排除をすれば速くなるのではないかと。
パッチの件ですが、 とりあえず無闇に isSla300, isSlb500 などと増やしていますが、 どう考えても enum かなんかでマシン情報を保持すべきだと思います。 で、なんでそうしなかったかと言うと、 audio でもその情報を共有したいなーなどと思ったのですが、 はてさてどうやったものやら、というところで思考停止したからです。
zgnuboy は、GB の saga1 がまあ快適に動いています。 音飛びは常時我慢できる程度起こっていて、 絵の方はたまにフレームスキップ or 処理落ちしている感じです。 たぶんアクションゲームじゃなきゃ快適だと言えると思います。 GBC は本体及び ROM カートリッジを所持したことが無いので試せません…
案外頑張れているのは恐らく、blitRotate0 を使えているからではないかと。
NES が案外きついのはちょっと意外です。 移植頑張ってください。 私もなんか大物に手を付けたいな、などと思っていますが…
■ [Program]: ポータブルなコード
MetaProgramming 関係で。 そうじゃなくて、 MPL は凡人の意識できる限界を越えかねない、 C++ MetaProgramming を STL ライクな文法を持った 私みたいな凡人でも理解できる形式に ラップしてくれるライブラリなんだってば。 とかポストしようかと思ったけどまあやめた。 で、ここで言い捨て。ひでーヤツだ。
K.INABAさんも面白いものを作られていますね。 一度 ioccc を全部読みたいなあ。 月刊企画もむちゃくちゃ面白いです。 頑張って下さい。 私が Cマガで一番楽しんでる記事は千言万語だからなあ。
03.01.12■ [Program]: リナザウ続き
1月10日夕方。 うげげ、B500 は全然違う。 前回の勘違いはとんだ恥さらしということで。 で、SDL を眺める。コードを大体把握してきたけど、 B500 問題の解決法はわからじ。 とりあえず、B500 に関しては昔に戻すのもありだろうけど。
1月10日。18時から25時までバイトでそれから。 現実逃避に白い弾幕くん移植。完了。が、遅すぎ。 プロファイルしてみたところ、浮動小数点が遅すぎるっぽい。 そりゃそうか。 固定小数点数 に置きかえていくもうまくいかない。
1月11日。 とにかく移植。 ドリラー、 FALLING TOWER、 wok、 bmda。 ゲーム機にするつもりなのだろうか。
合間に SL-A300 のダメダメ十字入力をアドホックに修正。 十字キーの左を押したら隣りのキャンセルに 触っちゃった現象以外はだいぶ修正できていると思う。 emacs の c-basic-offset を変えまくった一日でした。
1月12日。公開できるものは公開しようかと思う。 リナザウゾーン。 白い弾幕くんと wok は処理が遅いからとりあえず保留。 bmda は BMS の圧縮とか色々しなけりゃならんことが。
SDL 本体についての SL-A300向けパッチ。は消しました。 続きをどうぞ。 入力周りが結構マシに。 阿川さんの成果物からの差分です。 ipk パッケージ。は消しました。 続きをどうぞ。 こんなところで A300 で結構満足にゲームができますので、 阿川さん、暇ができましたら C700 での動作確認の上、 パッチを取り込んで頂けんでしょうか?
03.01.10■ [Program]: SL-A300
が届きました。楽しすぎ。 もうある程度ノウハウが出回っているかららくちんらくちん。 全力で後を追うべか。
1月8日。届く。とりあえず TCP/IP を USB ごしに通す。
1月9日。ROM を 1.2 に。PDA としての体裁を整えるため、 handskk 関係や Opie Player とか文庫ビューアとかインストール。 クロスコンパイラを RPM で拾う。 宝箱 Pro から。 コードさえポータブルに書いていれば、 クロス開発で一番めんどくさいのはクロスコンパイラの コンパイルじゃないかと思うから、ものすごくありがたい。 ありがとう、シャープ。
で、SDL をコンパイルして、testsprite を動かす。6FPS。絶望的。 とりあえずいつも通り stetris を動くように持っていく。 -DQWS は超重要な模様。まあとにかく stetris は動いてます。 一応 ipk で入れてみる。TGM シリーズクローン。 万が一欲しい方はメールなりなんなり下され。
阿川さんが gnuboy 移植の偉業で 神になられた模様。 後を追うべし、と、 謹製 SDL をインストール。 はい画面が逆。
1月10日。 B500 で起こっているらしい問題 も同じ理由だろうて。 一瞬で解決。 適当パッチ、は消しました。 続きを見て下さい。 阿川さんはこれから しばらく network unreachable らしいんで、とりあえず、 暫定 ipk パッケージ、も消しました。 続きを見て下さい。
えと、testsprite が 51FPS とかになってるんですけど。わーい。 とりあえずこれをベースに、SL-A300 向けの改造を試みたいと思います。
あと、キーコードの話ですが、 SL-A300 では、十字のまん中が space、OK が enter、Menu が f11 だそうです。 だから、
bind enter +b bind f11 +a bind space +start
$HOME/.zgnuboy/zgnuboy.rc に、 こんな感じで書くと良いかと。
■ [Program]: SDL と zgnuboy を SL-A300 向けに
SDL へのパッチと SDL ipk パッケージは消しました。 続きをどうぞ。 やったことは、さっきの SL-C700 以外だと画面が反転しちゃうのの修正と、 阿川さんが取り込まなかった SL-A300 用音パッチの取り込み。 これは SL-A300 の時にだけ反応するようにしています。 SL-B500 の情報も欲しいっすね。 C700 でも問題無く動くはず。
gnuboy へのパッチ。 zgnuboy ipk パッケージ。 A300 はボタンが足りん、ということで、ペンで入力可能に。 $HOME/.zgnuboy/zgnuboy.rc に
bind penup +up bind penright +right bind pendown +down bind penleft +left bind pencenterright +a bind pencenterleft +b
てな感じで。centerright ってのは画面中央ちょっと右ってこと。 ちょっと中央が狭すぎるかもしれない。 ロープレとかならペンだけでできるかと。
気付いた嫌なこと。 まんなかの十字は上下左右と真ん中で、五つのボタンになっているんだが、 それらを同時押しすると、後で押した方の RELEASE イベントが発生してない。 そのボタンはずっと押しっぱなしになっちゃうの。
02.12.24なんかですねえ。music.c の 473 行目あたりなんですが、
#ifdef MP3_MUSIC if ( (ext && MIX_string_equals(ext, "MPG")) || (ext && MIX_string_equals(ext, "MPEG")) || magic[0]==0xFF && (magic[1]&0xF0)==0xF0){ /* 省略、 mp3 向けの処理。 } else #endif #ifdef MOD_MUSIC if ( 1 ) { /* 省略、 mod 向けの処理。 } else #endif { Mix_SetError("Unrecognized music format"); music->error = 1; }
とのことなんですが、これはちょっと頂けないのでは。 まず、拡張子の判断ですが、mp3 データに mpg とか mpeg とかの 拡張子を付ける人はどれだけいるんだろう? んで、magic[0]==0xFF うんぬんですが、 なんか最初によくわかんないヘッダが入った後に このデータが来る mp3 ファイルが結構ある。 そのデータが標準に準拠してないのかもしれないけど、 どっちにしろ拡張子 mp3 は mp3 データに決まっておろう。 で、
(ext && MIX_string_equals(ext, "MP3")) ||
を上記の3行目に加えたらとても幸せになれました。
あとデフォルトが mod っていうのもなんか。
ついでに。 SDL サブライブラリの中で、SDL_ttf だけドキュメントが無い、と思う。 でもヘッダにはいろいろ書いてあるからもったいない。 で、html 化しました。 mixer とかも同じスクリプトで html 化 できるけどドキュメントがあるからいいや。
■ [Program]: QNX でいろいろ。
SDL, smpeg, SDL_mixer, SDL_gfx は ./configure; make 一発でした。 sdljump もすぐに動く。さすがに C は簡単。 今は公開してない stetris もなんとか。 でも /usr/include/xstring の 1085行目に typename を付加。 あとは std::map がやばげ。 んで、 bpo。 math.h 558行、stdlib.h 239行、string.h 130行に、
#define __GCC_BUILTIN
を追加。その後 Internal Error が連打。 resource.(h|cc) がまずいっぽい。その場しのぎも通じず、断念。 とりあえず gcc を新しくて再挑戦しようと思う。
以上、QNX のメモというよりは gcc-2.95.2 のメモかもしれない。
02.12.18■ [Program]: Bullet Philharmonic Orchestra
最近、 こんなもの を作っています、って言ったらもの凄くしょうもないことを している気がしてくるけど、 こ ん な も の を作ってると言えば少しはマシに見えるからやはりグラフィックは重要だ。
おたまをリスペクトして、音から弾幕生成。 ABAさんをリスペクトして、画像データ無しでなんとか。 adasさんをリスペクトして、途中で開発状況を公開してみる。 bpo-0.0.1。 Winバイナリ無し。コンパイルしなきゃならんです。
まだ当り判定すら無くてゲームでは無いっす。 音から弾幕生成と言いつつランダムにしか見えないのが現状。 xmms プラグインとかのソースで勉強すれば良いのかな… なんかわかりやすい教材が無いものか。 仮に見どころがあるとすれば、clear_screen.cc。 SDL_gfx の SDL_imageFilter 面白いです。 MMX 命令って凄いのね…などと、とんでもなく遅らばせながら、 ハードウェア機能の素晴しさを実感。
■ [Program]: ハードウェアアクセラレートのある生活
OpenGL がホットらしいから相乗りして… TOGEさんが 紹介されていた、 ベンチマーク を見ると、なんでノートにこんなビデオカード積むんじゃ、とびびりますね。 かくいう私は ATI Technologies Inc Rage Mobility P/M AGP 2x なとと言われても何のこっちゃわからず、のほほんと生活しとりました。
先日、うちの大学がゴミと称して使えるマシンを捨てまくるという、 なんとも嫌な体質でちょっと沈むイベントを行っていて、 それはそれとして、まあ「ゴミ」を漁るわけですが、 その時の収穫が、 Athlon 650MHz + M/B, PentiumIII 600MHz + M/B, PentiumII, メモリ 128MB*2, NVidia SGS Thomson (Joint Venture) Riva128, NVidia Vanta [NV6], Creative Labs SB Live!, あと細かいパーツを色々と、まあ後半の方は /proc/pci を見ただけで、 なんのことかわからんのですが、ありがたそうなものを沢山拾いました。 で、ビデオカードの比較を xengine と SDL の testgl でやってみました。
ATI Technologies Inc Rage Mobility P/M AGP 2x: | 4500rpm, 100FPS |
NVidia SGS Thomson (Joint Venture) Riva128: | 3500rpm, 75FPS |
NVidia Vanta [NV6]: | 4370rpm, 85FPS |
NVidia Vanta [NV6] with NVidia driver: | 58000rpm, 265FPS |
Matrox MGA 6400 AGP: | 3500rpm, 830FPS |
いやー、始めてハードウェアアクセラレートっつうものを見てびっくりしました。 またもとんでもなく遅らばせながら。 Matrox の 830FPS がよくわからんのですが、 testgl はベンチマークソフトってわけじゃないしなあ。
これまでの積み重ねで 1000 円もかけずに、 Athlon-700, 128MB*3, 6GB+4GB+..., ビデオカードとかプリンタとかスキャナとか… な環境ができていたりする。 本当にそれはゴミなのか?くそったれ。ありがたいんだけど、複雑だ。
■ [Program]: SDL-HTML/HTTP
^C さんの日記の HTTP フレームワークの話を見てて、 昔 SDL-HTTP/HTML を作りたいなあと思ったことを思いだしました。 その時考えてたのは…
HTML ファイルを引数として渡し、 SDL_Surface に HTML をレンダリングして、 マウス・キーボード・ジョイスティックに対応した入力、 適当な設定値保存クラスで form タグの設定内容を返す。 つまり HTML を設定項目記述言語として用いる。
設定値保存クラスと同じフォーマットで入出力を行う CGI? できれば同じことを行う JavaScript も。 できれば同じことを行う GTK? アプリも。 まあ、ゲーム内で設定を行うのはめんどいですし。
SDL_Net を使って HTTP アクセスをして、 POST メソッドでインターネットランキングにスコア登録。
SDL_Net ごしにさっきのインターネットランキングから 順位表なんかを持ってきて、最初の HTML レンダラで表示。
なんてなことを考えててけど、一つ一つの機能が今一つちぐはぐだし、 そもそも HTML レンダラの辺りが工数的にムリってことでやめた。
要はゲーム用の設定 UI をゲームライブラリで作るのがめんどいんだから、 ややこしいことは考えず、GTK アプリとかで 設定するようにすれば良いとは昔から思ってるんだけど… 結構 Windows のゲームでも MFC アプリで設定するヤツがあるしね…
で… CGI, JavaScript ならすぐに作れるなと思ったのが、 これだったりします。 問題は使い勝手が悪すぎることだ。 誰がしょうもないゲームの設定をわざわざコピペするのだろうか。 やはり SDL_gui からマイフレームワークを作るのが良いかな。 ParaGUI テーマが魅力的だけどデカすぎるのが難点。
ちなみに私がバイト先で作ってるものはちょうどこんな感じで、 ブラウザでシステムの設定ができる。 でもそれはシステムが動いてるマシンと 設定 CGI が動いているマシンが同じだから通用する話で、 結局インハウスツールってことっすか。
うーんでもやっぱりブラウザの UI は魅力的だなあ。 なんかうまくローカルにデータを保存させられないものか。 ウィルスか。
■ [Program]: gcc がんばれ
Isseiさん、 zinniaさん、 けんとさん、 zinniaさん 経由で。 Call for testers for pch-branch。 ちょっと遊んでみました。
g++ hoge.h
とするだけで hoge.h.pch ができる。 hoge.h を #include するだけで勝手に pch を読みにいく。 最初一生懸命オプションを調べてたのがムダ。 証拠。
i@u ~/test/pch> strace -f g++ -c test.cc | grep "\.pch" -A 2 [pid 12185] open("test.h.pch", O_RDONLY|O_NOCTTY) = 4 [pid 12185] fstat64(4, {st_mode=S_IFREG|0644, st_size=338156, ...}) = 0 [pid 12185] read(4, "gpchC010", 8) = 8
見つかんない場合。
i@u ~/test/pch> strace -f g++ -c test.cc | grep "\.pch" -A 3 [pid 12196] open("test.h.pch", O_RDONLY|O_NOCTTY) = -1 ENOENT (No such file or directory) [pid 12196] open("test.h", O_RDONLY|O_NOCTTY) = 4 [pid 12196] fstat64(4, {st_mode=S_IFREG|0644, st_size=84, ...}) = 0 [pid 12196] read(4, "template <class T>\nclass A {\npub"..., 84) = 84
boost の下をかたっぱしから pch に。 まずびびったのが、
i@u src/boost_1_29_0/boost> ls -laH function.hpp.pch -rw-r--r-- 1 i 10M 12 6 17:20 function.hpp.pch
圧縮して欲しい。
i@u src/boost_1_29_0/boost> gzip function.hpp.pch i@u src/boost_1_29_0/boost> ls -laH function.hpp.pch.gz -rw-r--r-- 1 i 2.0M 12月 6 17:20 function.hpp.pch.gz
で、いろいろ今までのソースをコンパイルしてみるも、ほとんど失敗。 割と簡単そうな refTest.cc とか composeTest.cc もだめ。 確かに簡単な例なら上手くいくんだけどなあ。
とりあえず海の向こうの皆さんの努力に感謝。 これからもお願いします。
ところで gcc って cc1 とかの実行ファイルは バージョンごとに分かれてくれるけど、 gcc 本体は当然同じ場所だし、それはまあ、 gcc3 とか別の名前つけて対応できるんだけど、 できた実行ファイルの参照する libstdc++ を LD_LIBRARY_PATH で変えたりしなきゃならない。 私は、gcc を ./configure --prefix $HOME/local/gcc-pch とかして、 .zshrc に
swgcc () { d=/home/i/local if [ $* ]; then export PATH=$d/gcc-$*/bin:$PATH export LD_LIBRARY_PATH=$d/gcc-$*/lib:$LD_LIBRARY_PATH else export PATH=$OLD_PATH export LD_LIBRARY_PATH=$OLD_LD_LIBRARY_PATH fi } export OLD_PATH=$PATH export OLD_LD_LIBRARY_PATH=$LD_LIBRARY_PATH
とかして swgcc pch などと切り替えています。 手軽に切り替えれて結構便利。
02.12.06■ [Program]: Sunpro
cppllのsunpro より。
as303 ~> g++ -o main main.cc /var/tmp/ccY1lpqw.o: In function `main': /var/tmp/ccY1lpqw.o(.text+0xc): undefined reference to `C<int>::C(void)' collect2: ld returned 1 exit status Exit 1 as303 ~> CC -o main main.cc as303 ~>
ほんとだ。面白い。 hoge.h に template<class T> class C があって、 main.cc が hoge.h を include してます。 そして、hoge.cc に class C のコンストラクタがあるのです…
02.12.03■ [Program]: C++言語カルトクイズ
突如考えてみた。
以下、コンパイラ、ライブラリヘッダ、各種参考書などを 参照してもいいけどその部分は点数が半分になるとする。
問1.
const キーワードは複数の意味があるが、 それぞれについて、サンプルコードを書き、 何を定数と宣言しているかを述べよ。
問2.
関数ポインタというものがある。
int func(); int main() { int (*fp) () = func; fp(); }
このように使うことができる、では、
struct C { int func() const; } int main() { C c; // todo }
todo部分に c について、先の関数ポインタの例のように メソッドポインタ越しに呼び出すコードを書け。
問3.
export キーワードの意味を全て述べ、使用上の注意を述べよ。
問4.
protected キーワードの意味を全て述べよ。
問5.
virtual キーワードの意味を全て述べよ。
問6.
typename キーワードの意味を全て述べよ。
問7.
例外仕様について述べよ。
問8.
テンプレート特別バージョンを利用したコード例を示せ。
問9.
template <template typename T> class C {};
と宣言されているクラス C がある。 クラス C をインスタンシエイトせよ。
問10. (予習問題)
次期 C++ への参入が期待され、既に複数のコンパイラで実装されている typeof キーワードの使用例を示せ。
いかがでしょう? 私が考えたんだから成績が良くなるのは当たり前だけど 私はたぶんボーナス点無しで90点位。
答え。 当然嘘が含まれている恐れがあります…
02.10.29■ [Program]: iterator_adaptors
loopの数ですが、 私がバイトで for ループを置換していった時はほとんど消えました。 消えないような中身のでかいループはメソッド化すべき、 という一種のバロメータになるのがなんとも。
あわわこんなことが。 いいかげんちゃんと勉強した方がいいなあ。 cvs とか make とか vi とか zsh とか screen とか…
面白すぎ。一週間程はまってた。 週末は久しぶりに一日に30時間以上プログラム書いて疲れた。 結構強いのができてきた。でもまだまだ遊べる。 ジャパンカップでザウルス貰いたいなあと夢見る今日この頃。 無理っぽい。
これで Java でなければなあ。 まあ Java だからロボットを手軽にダイナミックロードできるんだけどね。 c++ は一定こだわりがあるけど、 Java は全く無いので恐しく適当にコーディングしていく自分を発見。
とりあえずしばらく他の部分はおろそかになる予感。 boost-dev ML も、まあ、 メール 500通程度なら溜めても処理できるだろう。たぶん。 とか思って放置気味。
■ [Program]: 履歴
久しぶりの Java だなあ。 バイトでアプレットいじってて以来だから半年ぶりくらいか。 私の Java 経験って 200時間弱位だろうか。ずいぶん少ない気がする。 まあ趣味で書いたことは一度も無いからか。 Java でコードを書いてた時間より長く遊んだゲームが 10タイトルはあるなあ。
とか思ってるとじゃあ c++ は何時間位だろうか、 と考えても想像もできなかったのですが、 とにかくコード書き始めてから 2年ちょいしか経って無いことに気付く。 もっと長い付き合いだと思ってたんだけど。 プログラミング言語 c++ を全部読んで OO な気分になったのが二年前。 そのちょっと後バイトで STL コンテナ/イテレータ。 半年後 STL アルゴリズム/アダプタ。 もう半年で boost。 んでもう半年で Loki その他経由でメタプログラミング。 半年単位でc++は感動的な物を見せてくれるらしい。 次は何だろうか?
02.10.22■ [Program]: boost::lambda の続き
私の表現が適当だったので、誤解が少し。 5%の差というのはオリジナルのソースでの話です。 改行を外してからは全く差が無かったです。 つまり、私達の間で最終的な結果は 相違無しということでめでたしめでたし、です。
boost::bind も boost::lambda も何回も関数呼びだしするけど、 全部インライン展開されるんじゃないでしょうか? 比較するコード を書いてみたんですが、 私の環境では最適化 -O で全部同じ速度になりました。 最適化しないと、
lambda 0.64s bind 0.54s normal 0.52s
ってとこでした。 ラムダオブジェクト作りまくりでオプション無しでは最適化しきらん、 ってとこだと思います。
しかし inline は魔法ですな。
その通りだと思いました。 じゃあちゃんと速度差が出まくってるのはなんでなんだろう? 出力先は /dev/null だからそのへんは考えなくていいとして、 iostream は出力の方はたいした処理をしてない、ってことかなあ。 まあそんな気がする。きっとそうだ。
■ [Program]: インターフェイスは何よりも考えるのがしんどい。
なかなか深く悩まれてますな。 OO的には setter なんだろうけど、 C的にはパラメータ構造体が良い気がします。 不思議。 多分 X なんかが後者を多用しているから刷り込みかなあ。 でも OpenGL は前者が適切な気がする。 この辺りを分かつものは…言語化しにくい。
…私はどうせ相手はプログラマ(しかも大抵自分のみ) なんだから適当でいいんだよ、 という結論に落ちます、大抵。 きちんと考える zinniaさんは立派だなあ、と思ったり。
02.10.20■ [Program]: 環境の差?
うーん。 私の環境ではそこまでの差は出なくて、 5%位の差でした。
if (_1 % 2 == 0) cout << _1 << "は偶数" << endl; else cout << _1 << "は奇数" << endl;
私んとこでは "は偶数" を "は偶数\n" に変えたら似たようになりましたが… それが真の原因かは自信無し。
GDB に catch というコマンドがあることを今頃知った。 でもうまく動かん、何故。
02.10.16で少し遊んでみた。 マンデルブロー集合。 コンパイルは、
> ocamlopt -c -I /usr/lib/ocaml/sdl mandel.ml > ocamlopt -cclib "-L/usr/local/lib -Wl,-rpath,/usr/local/lib -lSDL -lpthread -lSD L_ttf -lSDL_image -lSDL_mixer -lpng -lz -lm" -cclib "-L/usr/lib/ocaml/sdl -lstub " -o mandelocaml /usr/lib/ocaml/sdl/libstub.a /usr/lib/ocaml/sdl/sdl.cmxa bigarr ay.cmxa mandel.cmx
でやっている。 噂通り、とても速い。 最適化オプション -O の g++ で作った等価なコードと比べてみたが、 一割も遜色が無かった。 最適化オプションが無いと話にならない。 素晴らしい。
ただ残念なのが、OCamlSDLがまだまだ未完成であること。 Eventが足りなかったり、今回気付いたのだが、 (set/get)_pixel がバグ入りだったり。 CVSのヤツは随分良くなっているようだが、 ./configure; make ができなくて、結構めんどくさそう。 これからに期待。
■ [Program]: boost と long long
こいつはあっしも悩みの種でした。 んで、解決法は知ってるつもりだったんで、 1_28_0 に対する patch を作ってみました。 たぶんこれで -ansi -pedantic が通るはず。
そういや今まで誰にも patch の作り方って 教えてもらって無いから適当なんだけど、 これが適切なやり方なんだろうか?
仕組みは -ansi で現れる、__STRICT_ANSI__ が on になってたら、 BOOST_HAS_LONG_LONG を off にして、 後は BOOST_HAS_LONG_LONG 以外の条件で long long を使うかどうかを判定しているコードを ifdef BOOST_HAS_LONG_LONG で包んだだけです。
これ、boost-dev に投げたら採用してくれるかなあ。
あと、-ansi だけだと M_PI とかが消えるだけで、 チェックは変わってないと思います。
何故に cl.exe?と思ってしまいました。 コンパイラだけなら bcc32.exe に決まっておろう、と。 wine はいいですなあ。 あと、Kylix3 が良いコンパイラなのは Borland C++ そのまんまだからだと思います。たぶん。
02.10.09■ [Program]: intel c++ compiler
前回の続き。 前回眠い時に書いてたからなんか電波な文章だなあ。 とりあえずプログラムが一部間違ってたからそこだけ修正。 さて、どこでしょう?
前回の例では、 icc では template template parameter だけダメでした。 ずいぶん前に実験した時は partial specialization がダメだったような気がしたんだけどなあ。
なんつーか鬼のように c++ & linux に順風ですなあ。 放置しているこれ はこういう比較がやりたかったんだよなあ。 確か。 選択肢と判断材料を提示する、というか。 現状ではただかき集めただけだし、だんだん古くなるし。
c++ library に関してもそういうものがあったら良いと思う。 無きゃ java に勝てっこない。 いや、勝たなくてもいいんだけどね。
私的には最近心は ocaml なのですが。 こんないい言語があったなんてねえ。
■ [Program]: SDL_SaveMovie
なんか自信無いんですが… こう、がんがん描画しては画面を消し、 ってのを繰り返すゲームには適用不可ですか? たぶん画面を消去して真っ暗になった時に、 SaveJPG が呼ばれちゃうと思うんですが…
一定時間ごとに画像をひっぱってくるモードと別に、 クライアントコードが画像をひっぱるタイミングを 指定するモードが必要かなあ、と思うんですがどうでしょう。
最初見た時、相変わらず隙間を埋めるいい仕事だなあとか思って、 早速適当なムービー作ってみようかとしたんですが、 つまづいてしまって悩んでました。
あと、もちろんサンプルはうまく動きましたです。
02.10.07■ [Program]: gcc マンセイ。
gcc 3.3 comming soon? だそうです。 こりゃすごいっすね。 gcc-3 系列になって小さいファイルのコンパイルは遅くなって、 大きいファイルは速くなった、っていうのが私的結論だったのですが、 どっちも速くなってますねえ。 まあ、でもリリースは遅れまくるのが基本っぽいので気長に気長に。 ほんとかなあ。
オプションたくさん紹介ありがとうございます。 でもとりあえず -ansi -pedantic は是非。
私は -W -Wall -ansi -pedantic だけでしたが、 結構他にも入れた方が良さげなのがあるんですね。 ちなみに上記オプションだけなら sstream に ちょっと手を加えれば warning ゼロ生活です。
ls /usr/include/g++-3 | grep -v ".h$" | perl -ne 'chomp;print "#include <$_>\n"' > ~/std.cc
気になってたことなんでこんなことしてみました。 嫌になるほど warning が出た上、 warning の方が違うんじゃないかと思うような エラーメッセージまで出たんで少しいじって諦めました。
stlport 使えば良くなるのかなあと思いましたが、 全然変わらず。
_IO_istream_withassign& operator=(_IO_istream_withassign& rhs) { return operator= (static_cast<istream&> (rhs)); }
に対して、
g++-3/iostream.h: In method `_IO_istream_withassign &_IO_istream_withassign::operator= (_IO_istream_withassign &)': g++-3/iostream.h:238: warning: `operator=' should return a reference to `*this'
とかはキツすぎ。あと、
g++-3/stl_iterator.h:637: warning: `reverse_iterator<_Iterator>::operator+= (typename iterator_traits<_Iterator>::difference_type)' should return by value
嘘つくなよ。 これは gcc-3.0.4 => gcc-3.1 で修正されとりましたが。 地道に成長していくあなたが好き。 十バージョン近く入れても 200M 足らずなあなたが好き。
■ [Program]: やっぱり Kylix3 マンセー?
コンパイラをいたぶってみる。
template <class T> class C {}; class C<int> {}; template <template<class> class T> class D {}; class E { public: template <class T> void func(T t); }; template <class T> void E::func(T t) {} void a() {} void b() { return b(); } #include <vector> void test() { C<double> c1; C<int> c2; D<std::vector> d; E e; e.func(1); }
partial specialization と template template parameter がオッケーですか。 ついでに VC がダメな void関数での void関数 return と、 テンプレートメソッドの外部定義。 完璧。すげえ。 これはひょっとするとひょっとしますなあ。 ちょいとパフォーマンスとかもしっかり調べてみましょうか。
全てリンクフリーです。 コード片は自由に使用していただいて構いません。 その他のものはGPL扱いであればあらゆる使用に関して文句は言いません。 なにかあれば下記メールアドレスへ。