radium.png
HOME | ARCHIVE | PRODUCTS | ABOUT | RSS

Partial Evaluation

2002-06-01

えーと,一日あたり何個のバグを直せばいいのかな……


Todd Veldhuizen の "C++ Templates as Partial Evaluation" を通読した。

http://osl.iu.edu/~tveldhui/papers/pepm99/

C++ のテンプレートはこうやって使えば汎用化と最適化に役立てることができるんだぜ,みたいな内容。しかし,最後には C++ に対する苦言を述べつつ締めくくっているところが,この論文の背反性を物語っている。 C++ のテンプレートは,静的なプログラミング言語に対して汎用性を強化する手段としては通過点に過ぎない,みたいな雰囲気を漂わせつつも,でもやっぱり当分は C++ が最強のツールだからがしがし使いましょ,って結論に繋がってしまうところが,なんとも歯痒く感じる。

もっとも,氏は大規模算術演算を高速に解決するための汎用的な手段として C++ とテンプレートに注目しているようだから,それに引きずられてしまうのはあまりよくないかもしれない。あくまでも,静的に型が解決されてしまうという C++ の弱点を柔軟に解決する方法としてのテンプレートを考えた方が……いや,なんか分かってない気がする。実経験を伴ってないし。


MOSIX, Condor

2002-06-02

この前,何かの用事のついでに立ち寄った書店で Software Design 誌の最新号を立ち読みしたときに, "MOSIX" という PC クラスタリングのためのアーキテクチャが紹介されていたことを,ふと思い出した(今月号の SD 誌は,たしか分散環境の特集だったのだ)。算術演算用途の PC クラスタリングなんかにはちっとも縁が無いけれど,コンパイリングファーム/レンダリングファームなどの構築には興味がある。数十万行規模のコードを複数人数のチームで効率良く扱うためには,もはや分散環境の構築が欠かせないだろうと考えている。今回構築した分散環境は非常にプリミティブなものだったけれど,それでもそれなりに効果を上げることができた。ほとんどなにも工夫していなくてもこの程度なんだから,もっと厳密にシステム構築を行えば,もっと素晴らしいプロセサパワーを引き出すことができるはずだ。

なにはともあれ,まずはサーチにかけてみた。

http://www.mosix.org/

MOSIX はどうやら Linux のカーネルソースにパッチを当てて,複数台のマシンを対称的かつ負荷均衡を保ちつつむにゃむにゃ……って感じのシステムらしい。詳しいところまでは調べていないけれど,基本的には SMP 駆動している Linux カーネルみたいに,特にマルチプロセサを意識することなく,ただ単にジョブをガンガン発行するだけでその恩恵にあずかることができる,ってもののようだ。

MOSIX 絡みでついでに見つけたのが,ウィスコンシン大学の Condor プロジェクト。

http://www.cs.wisc.edu/condor/

Condor は High Throughput Computing 略して HTC な環境を提供するためのツール群を提供しよう,ってプロジェクトで,一般的な UNIX システムや WindowsNT をターゲットとしているらしい。 MOSIX みたいなカーネルレベルで制御を行うシステムではなく,それぞれのマシンで Condor デーモンを立ち上げておいて,そいつらがプロセサ間調停を行いつつジョブをぽいぽいと投げ合う,みたいなノリのシステムのようだ。

MOSIX はカーネルレベルでクラスタリングを実現するぶん,高等なクラスタリング環境を得られる望みがある。しかし, Linux カーネルにパッチを当てて使うものなので,導入やメンテナンスに多少なりとも手を煩わすことになるかもしれない。逆に Condor の方は「あたかも1台のマシンのように扱う」なんてことはできなさそうだけれど,仕組みがプリミティブなぶんシステムの管理は楽になりそうだ。僕の場合は,単にコンパイラのジョブを均等に分散したいと考えているだけなので, MOSIX ほど高等なものを扱う必要もないかもしれない。まあでも,この対象性にはちょっと惹かれるところがあるけれど……。

ちょっと今は暇が無いので,ちゃんと調べることはできなかったけれど,いずれまた本格的に調べてみたいと思っている。


SAT

2002-06-03

GDAlgorithmsList より Separating Axis Theorem スレッド。要するに「OBB って何がいいのさ」みたいな質問スレッド。

http://www.geocrawler.com/mail/thread.php3?subject=%5BAlgori...

本当にただの質問スレッドなんだけれど,実の所 OBB ってまだやったことないんで,参考になったりするかも……。

OBB vs OBB の交差検出では 3 x 2 (OBB axis) + 9 (edge pairwise) = 15 の Separating Axis を扱うことになるんだけれど,ほとんどの場合 OBB の軸を Separating Axis とする最初の6回で非交差状態が検出されるため,交差している場合やある種の特殊なケース以外では,ほとんどが最初の6回で検出が終了することになるらしい。しかも,最後の9回が重要になるのは「細長い形状の OBB の場合」や「非常に近接している場合」に限られるので,用途によっては最初の6回だけで近似してしまうこともできるかも,みたいな感じだ。

それに加えて cbloom 氏のワンポイントテクニック。

> In particular, for OBB-OBB , you can test just the axis
> between their two centers. In typical cases, I've found
> this to be correct 90% of the time.

ということで,ひとえに OBB と言えども,少々の特殊化によってアレンジすることで,さらなる高速化が期待できそうだ。


Game Asset Management

2002-06-04

flipcode だかどこだかの情報。 NXN のゲーム開発向けプロダクト管理システム "alienbrain" に "starter pack" が登場したらしい。

http://www.nxn-software.com/2581.htm

10人構成のチームを想定したパッケージで,お値段は $9,999 つまり120万円ぐらい。機能を考えれば法外に高いわけじゃないと思うけれど,気軽におねだりできるような価格ではないな,と思う。 alienbrain についてはそれなりに良い評価を耳にするものの,かならずしも満足させられるようなものではない,という意見を聞くことが多い。少なくとも,今のような無法状態よりかはまともな環境を提供してくれると思うんだけれど,それと値段と労力がつり合うだろうか,ってとこだ。

そういえば,ちょいと前の Game Developer Magazine に Ensemble Studio の Age of Empires チームが Microsoft SQL Server と自前のプラグインを使ってアセット管理システムを構築した,っていう記事があったなあ,と思い出して,ふと Gamasutra でサーチしてみた。あったあった,ちゃんとウェブ化されている。

http://www.gamasutra.com/features/20010221/marselas_01.htm

この記事は参考になるところが多いと,個人的には評価している。僕たちがまったくいい加減に処理している問題を,実に然るべき方法によって対処している所がうらやましく思えるのかもしれない。とにかく,できるものならこれくらいのことはやっておきたいものだと思う。

あとはこれを実装するためのコストが問題になるんだけれど,僕は一般的なアプリケーション作成の知識にかなり欠けているところがあるんで,こういったツールセットを簡単にでっち上げるってわけにはいかないかもしれない。まずシステムの研究調査の段階でかなりのコストを費やすことになってしまいそうだ。やはり,アプリ屋さん的なスキルを持ったタレントが一人くらいは必要なんだよなあ,と思う。


Epsilon Visibility

2002-06-05

収束に向かってるような向かっていないような日々。相変わらずのことなんだけれども,いったい本当の終わりはどこにあるのか,少なくとも僕には計り知ることの出来ないことのようだ。


Florent Duguet の "Robust Epsilon Visibility" に,なんとなく手を出してみる。

http://www-sop.inria.fr/reves/publications/data/2002/DD02/?L...

複雑なジオメトリに対して,いわゆる umbra / penumbra 領域を安定的に求めるというものらしいんだけど,その優位性などがさっぱり理解できなくて,途中で読むのを諦めてしまった。これをきちんと理解するには,もう少しこの分野におけるバックグラウンドが必要なようだ。 Quake 式 PVS なんかに興味を持っていた頃に Seth Teller を読もうとしたことがあったけれど,あそこら辺の話題と密接に関連しているんだろうと思う(結局 Teller の paper を読むことは無かった)。

http://graphics.lcs.mit.edu/~seth/


というわけで,無節操に Tim Rowley の SIGGRAPH 2002 paper コレクションをつまみ食いしている今日この頃。次はアニメーション関連に手を出してみようかと思ったんだけれど,それよりも先に,まず Baraff を読んでおくことにしようと思う。

http://www-2.cs.cmu.edu/~baraff/sigcourse/index.html

実の所, "Particle Dynamics" あたりまでしか読んだことがないので,剛体力学については,てんでからきしなのだ。とりあえず使うあては無くとも,一度くらいちゃんと目を通しておこうと思う。ちょうど IF さんの所でもやっているみたいだし……。


signal-specialized parametrization

2002-06-06

最近,このサイトのホスティングをしているサーバが午前4時から5時の間に必ず落ちるようだ。日次定期ミラーリングでもやっているんだろうか。だとしても,とにかく繋がらなくなってしまうのは困りものだ。いまのところ,ブックマークもメモ (Wiki) もすべてこのサーバに依存しているもんだから,アクセスしたいときにできないとなると,かなりもどかしい思いをすることになる。

やはり将来的にはお家でホスティングも考慮に入れておきたいところ。


GDAlgorithmsList より Hoppe の "signal-specialized parametrization" ネタ。

http://www.geocrawler.com/mail/thread.php3?subject=%5BAlgori...

http://research.microsoft.com/~hoppe/ssp.pdf

この Hoppe の論文は,サーフェス上の部分における信号特性に依存させた形でテクスチャ画像の変形とマッピングの調整を行う,という手法について述べたもののようだ。つまり,テクスチャデテールの細かい部分に対しては密に,逆に変化に乏しい部分に対しては疎に割り当てを行うことによって,より少ない容量でより鮮明なテクスチャ表現を実現しよう,というものらしい。

ネタ元の Adrian Perez 氏も指摘しているように,一般にデザイナさんは自分の作業のしやすいようにテクスチャの割り当てを行うだろうから,マッピング密度が均一になるように,とか,デテールの度合いに合わせてマッピングを調整するように,とか,そういった都合は考えてくれない事が多い。もっとも,密度に合わせて変形させた顔のテクスチャを描くなんてことは,とても人の手でできるような作業じゃないけれど……。

まあだから,こういった調整を一括して自動化することができれば,それはかなり素晴らしいことだろうと思う。しかしこの論文の内容はかなり高難度っぽいので,これを理解して実装するとなるとかなり骨の折れる作業になりそうな気がする。 Microsoft Game Studios の Franck Ouay 氏は実際にこの手法を応用したツールを作ってみたそうだけれど……ううむ,偉いなあ。


plane fitting to points

2002-06-07

もう後が無いような気がするんだけど……。今日は,とりあえず早く帰宅。ううむ。


http://www.geocrawler.com/mail/thread.php3?subject=%5BAlgori...

Bungie の Chris Butcher のスレッド。 BSP tree をポリゴン群から生成しようとしているんだけれど,恐らく同一平面上に存在するであろう頂点列を渡されたときに,その頂点列に対してもっとも誤差の少なくなるような平面の式を求めるにはどうしたらいいだろうか,っていう内容。一般に言って,モデラが吐くジオメトリ情報などというものは誤差だらけのもので,1つのポリゴンに含まれる頂点がすべて厳密に同一平面に乗っているとは限らないし,そもそも浮動小数点の演算誤差の問題もあるから,これから面ベースの構造である BSP tree を生成するのは,実はかなり骨の折れる仕事だ。低密度で軸垂直な面ばかりの実験データの場合には上手く動いても,実際にハイポリモデルを入力したとたんに破綻するような事は誰しも経験することだと思う。

Butcher 氏は,始めに "An=0" (A は頂点列からなる行列,n は平面を表す列ベクトル)を固有値によって解く方法を考えているけれど,途中で Gil Gribb 氏の勧めによって SVD (Singular Value Decomposition: 特異値分解法) を使った解法に切り換えている。この手の解法では SVD から得られる付加的な情報が価値を持つことがあるようだ。ふうむ,なかなか使える方法なんだなあ。

Peter-Pike 氏のコメントにある "Netlib Repository" や, Killpack 氏の挙げている "Why not use Numerical Recipes?" など,いろいろ面白い情報が得られたりもした。まあ確かに,あの奇怪で何の説明も無いソースを手で写す気にはなれないかもしれない……。

http://www.netlib.org/

http://math.jpl.nasa.gov/nr/


空白の一週間

2002-06-13

週の初めはあんなにも暑かった天候も,いつの間にかすっかり冷え込み梅雨模様となっていた。汗臭くすえた身体をしっとりと水分を含んだ冷ややかな風が包み込む感じ。職場に連泊しているあいだに気候が変わってしまった,なんてのはよくあること。こういうときに体調を崩しやすいんだから,気をつけねば,と思う。

担当している仕事量からすると比較的軽い方に分類されるゆえに,それほど追い込まれることもなく事を済ますことができようかと楽観していたのだけれど,やはり,最後の最後でひやりとさせられる事件が幾度となく発生することがあった。締め切り間際はまったく油断できない。特に今回のようなぎりぎりのスケジュールにおいては。

この1週間,何があったのかあまりよく覚えていない。曜日の感覚も無くなりかけている。勤務表などは,だいたいいい加減なものになってしまっている。風呂や着替えに帰った時間を休憩時間に計上すると,ほぼずっと継続で勤務したことになってしまう。24時間以上の勤務はちゃんと処理できてるんだろうか,これ。なんだかもう,こういうのはもっと適当に処理してしまった方がいいのかもしれない。これを管理する人のことも考えるならば。

明日は健康診断の精密検査に市ヶ谷まで行かなければならない。めんどくさいな……。これだから不健康は困る。特に今は不養生な状態にあるわけだし,なんだかとんでもない結果が出そうな雰囲気がするんだけれど,こればっかりはどうにもならんと思う。

もうこれで終わりにしたいとか,そういうわけじゃないんだけれど,いいかげん関係各所に少なからぬ影響を及ぼしはじめそうな時期に突入しつつあるわけで,そろそろ終止符を打たないことえらいことになってしまう。とにかく,無事に通ることを祈るのみだ。


NJS JavaScript Interpreter

2002-06-14

市ヶ谷の保険会館にて精密検査。腹にジェル状の謎液体を塗りたぐられた上に,超音波で内臓器官をデバッグされる。うへえ,気持ちわる。まあ,痛くはなかったからいいけど……。


ミキタさんの紹介していた "NJS JavaScript Interpreter" に手を出してみる。

http://www.bbassett.net/njs/

"NJS JavaScript Interpreter" は,名前の示す通り, JavaScript の組み込み用インタラプタだ。 JavaScript はちょっと OO っぽい仕組みを持っているので,他の組み込み用言語と比べていくぶんかっこいい使い方ができるかもしれない。

http://developer.netscape.com/docs/manuals/javascript.html

NJS は一度は打ち切られたプロジェクトらしいんだけれど,元の制作者がライセンスとして LGPL を使用していたために,今でも有志の手により開発が続けられているとのこと。良きことかな……。

お決まりの "The Great Computer Language Shootout" で順位を調べてみると,他のスクリプト言語を抑えての15位に位置付けられている。これはあまりあてにならないランキングなんだけれど, lua よりも高い成績をキープしているのは決して悪くないことだと思う。

http://www.bagley.org/~doug/shootout/

とりあえずダウンロードしてお試しビルド。インタラプタ本体のサイズはそれほど大きくないけれど,「全装備解除」状態の lua に比べると数倍の差がある。 JavaScript は基本ライブラリで正規表現とかサポートしているみたいだから,ベース部分がどうしても膨らんでしまうのかもしれない。そこんとこ,切り離して使うことができるかどうか検証してみないと。

あと,マルチタスキングの手段は用意されていないっぽい。ブラウザ上でアニメーションを実装する場合なんかも,タイマによるイベント駆動を使うのが定石だった気がする。ううむ,やはり生い立ちに影響されている部分が大きいなあ,と思う。


objective lua

2002-06-15

仕事のほうは,もう忙しさはだいぶ薄れているんだけれど,じりじりと緊張した状態での待機期間が続いている。また瀬戸際でひやっとさせられる事件もあったし,まったく油断できんわ。もう許して……。


NJS に興味を持ったのは,そもそも lua に OO 的な文法が用意されていないと思っていたのが主な動機なんだけれど,実は lua でも OO っぽいノリを実現するための機構が用意されているらしいってことを後になって知った。

http://www.lua.org/manual/manual.html#func-def

> The statement
>
>       function v:f (...) ... end
>
> is just syntactic sugar for
>
>       v.f = function (self, ...) ... end
>
> Note that the function gets an extra formal parameter called self.

簡単なトリックだけれど,まあ言ってみれば python もこんな感じだしなあ。この辺の小技については, lua-users の wiki が参考になる。

http://lua-users.org/wiki/ClassesAndMethods

特に,インスタンスを多数生成するようなクラスにおいては tag method を使った割り当て方法が常套手段になると思う。

しかしまたこの "tag method" ってのも, lua の怪しさ加減をうっすらと匂わせる要素だと思う。 lua 的に言うならば, lua の「自己拡張性」を維持する重要なメカニズムってことになっているらしい。雰囲気的には演算子オーバーロードみたいなもの。それを関数とは別の要素にまとめた所にどんな利点があるのかは,僕にはまだよくわからない。

軽くサンプルプログラムを組んでみて雰囲気をつかんでみる。悪くない感じ。わりといけるかもしれない。ただ, "obj . foobar()" と "obj : foobar()" が別物であることには注意しなければいけない。ここらへん, C や C++ みたいな強制的なチェック機構があるわけでもないので,エラーが出たとしても遠まわしなメッセージにしかならないし,下手すると文法的にはそのまま通ってしまうこともあり得る。慣れれば大したことないかもしれないけれど……。


Xbox

2002-06-16

まだ終わらない。今日は夜間召集指令が下された。帰る気力もなかったので,机の下で睡眠を取ってから帰宅。そんで職場にとんぼ返り。明日は無事に過ごせるといいけど……。


げーはなさんが紹介していた Andrew Huang の "Keeping Secrets in Hardware: the Microsoft Xbox Case Study" を読む。

http://web.mit.edu/bunnie/www/proj/anatak/xboxmod.html

http://web.mit.edu/bunnie/www/proj/anatak/AIM-2002-008.pdf

フラッシュ ROM にダミーのブートコードが潜ませてある辺りでたいていのハッカーは騙されるらしいんだけど,実際には RC4 チェック付きのブートコードがサウスブリッジ (MCPX) に格納されている。集積回路に内蔵されたコードを読み取るのは困難な上に, MCPX から CPU へのロードは Hypertransport バスを経由するため,これを拾い上げられることはないだろうという目算があったのかもしれないけれど, Bunnie 氏の執念のハッキングにはかなわなかったようだ。このブートコードを CPU チップ上,もしくはノースブリッジ上に内蔵すれば解析する手段をほとんど絶つことができたんだけれど,これはメンテナンス性を低下させるため,選択されなかったのかもしれない。つまり,その辺りのメンテナンス性とセキュリティ耐性はトレードオフの関係にある,ってのが Bunnie 氏の結論になっている。


ET

2002-06-17

ぬうう。そろそろやばいのかも……。


Todd Veldhuizen の "Techniques for Scientific C++" を,ほんのりと通読。

http://www.osl.iu.edu/~tveldhui/papers/techniques/

http://osl.iu.edu/~tveldhui/papers/techniques/techniques.ps

静的ポリモフィズムや "Traits" などの基本テクニックから "Expression Template" のような神髄まで,とにかく「高速な C++ 」を実現する上で必要となる様々なテクニックを解説している。

んで,これを読んだからってライブラリを作りはじめるわけでもなくて,

> Don't do an expression templates implementation yourself,
> except for fun. It's a waste of time, and nobody will be
> able to understand your code!

……の精神で行きたいと思う所存。先達者の功績にすがれればなあ,と思う。

ET なライブラリ(特に線形代数系)の候補としては, Blitz++, POOMA, tvmet などが挙げられるんだけれど, Blitz++, POOMA 辺りはちょっと毛色が違うみたいだ。 tvmet は,簡単なベクトル・マトリクス演算を一通り備えていて都合良さそうな気がする。

sl++ (Scientific Library) ってのも見つけたんだけれど,これはどうも長らくメンテされていない放置状態にあるようで,本格的な使用には少し支障がありそうな感じだ。クォータニオンを標準で装備しているのが,なかなか魅力なんだけれど。

http://ldeniau.home.cern.ch/ldeniau/html/sl++.html


続く日々

2002-06-18

まだじりじりと続く……


いろんな所で DOOM III だの "Cg" だの盛り上がっていて,早くもなんだか乗り遅れた気分になってきた。やっぱちゃんとした GPU 環境が手元に欲しいなあ,と思う。

"Cg" については,やはり OpenGL2 のシェーダ言語との関係が気になるところ。どちらも C 言語に近い高級な記述性を売りにしているみたいだけれど,今のところ,ひと足アクションの早かった Cg の方に分があるみたいだ。 OpenGL2 の方が先にモノは出していたんだけれど(確かソースも提供していたはず),実際に動くものを提示してきた意義は大きいのかもしれない。

やはりここらへん, NVIDIA と同業他社との間における役者の違い,ってことなんだと思う。


GDAlgorithms でのデータ圧縮に関するやりとりを見ていてふと気が付いたんだけれど,

http://www.geocrawler.com/mail/msg.php3?msg_id=8902785&list=...

Unisys の所有する LZW の特許が今年の12月をもって期限切れとなるようだ。裏は取っていないので本当かどうかわからないけれど,本当ならば,長きに渡った LZW の特許問題もようやっとこれで解決するってことだ。しかし,一般に LZW (LZ78) は LZ77 + huffman と比べても圧縮率で劣ると言われているので, LZW が解放されたからといってそれほど僕らに利益があるわけでもなさそうだ。たいていの場合は zlib を引っ張ってくればどうにでもなっちゃうし。

http://www.gzip.org/zlib/


cartoon rendering

2002-06-19

むちゃくちゃびびった。もう許して……。


GDAlgorithms より "cartoon rendering" スレッド。

http://www.geocrawler.com/mail/thread.php3?subject=%5BAlgori...

ここで紹介されていた輪郭線抽出のテクニック。絵描きさん向けの記事なんだけれど,面白いテクニックだと思う。

http://www.deathfall.com/tutorials.php?op=showcontent&id=67

いわゆる正規化キューブマップを適用した状態で単純にレンダリングして,その生成画像からポスト処理的に輪郭線を抽出しよう,というもの。こうすると,スクリーン上で法線が非連続的に変化している部分が輪郭として抽出されることになる。

この方法でなめらかな輪郭線を抽出するにはかなりのフィルレートを必要とすることになりそうだけれど,ジオメトリの複雑度にまったく影響されない,というのはなかなか面白いかなと思う。ていうか既に有名なテクニックなのかな,これ。


tvmet と gcc

2002-06-20

いろいろ調べまわったものの,結局 tvmet を使う方向性で行こうかと考えている。クオータニオンが用意されていないのが惜しいけれど,これは4−ベクトルから派生して数個のオペレーションを加えるだけでなんとかなりそうだ。そこさえ克服することができれば,ほとんどの部品は揃ったことになると思う。

それで,ちょいと tvmet と gcc の相性を調べてみることにした。サンプルとして用意したソースコードはこんな感じ。

#include <iostream>
#include <tvmet/Vector.h>

using namespace tvmet;

typedef Vector<int, 3> vector3d;

void test_func(vector3d& r, const vector3d& v1, const vector3d& v2)
{
        r = v1 + v2;
}

単純にベクトルの足し算を行うだけのプログラムだ,これを下のオプション設定でコンパイルする。

-O2 -finline-limit=5000 -ftemplate-depth-1000 -fomit-frame-pointer ¥
-fstrict-aliasing -fschedule-insns2 -fno-gcse -malign-double -Winline

まずは Redhat Linux 7.3 に付属の gcc2.96 でコンパイルしてみる。結果はこんな感じ。

   9                    .LFB1:
  10 0000 56                    pushl   %esi
  11                    .LCFI0:
  12 0001 53                    pushl   %ebx
  13                    .LCFI1:
  14 0002 81EC0401              subl    $260, %esp
  14      0000
  15                    .LCFI2:
  16 0008 8B942418              movl    280(%esp), %edx
  16      010000
  17 000f 8B8C2414              movl    276(%esp), %ecx
  17      010000
  18 0016 8B02                  movl    (%edx), %eax
  19 0018 8BB42410              movl    272(%esp), %esi
...

以下だらだらと続く。 -Winline オプションを付けているもんだから「インライン展開できませんでした」な警告がばんばん吐かれる。これだと expression template の力はほとんど発揮できていない状態だ。

次に,同じマシンに gcc3.1 をインストールして(ソースからビルドした)コンパイルさせてみる。すると出力はこんな感じになった。

  10                .LFB1:
  11 0000 83EC6C        subl    $108, %esp
  12                .LCFI0:
  13 0003 8B542474      movl    116(%esp), %edx
  14 0007 8B442478      movl    120(%esp), %eax
  15 000b 8B4C2470      movl    112(%esp), %ecx
  16 000f 89542450      movl    %edx, 80(%esp)
  17 0013 89542420      movl    %edx, 32(%esp)
  18 0017 89542430      movl    %edx, 48(%esp)
  19 001b 89442434      movl    %eax, 52(%esp)
  20 001f 89442454      movl    %eax, 84(%esp)
  21 0023 89442424      movl    %eax, 36(%esp)
  22 0027 8B00          movl    (%eax), %eax
  23 0029 0302          addl    (%edx), %eax
  24 002b 8901          movl    %eax, (%ecx)
  25 002d 8B542430      movl    48(%esp), %edx
  26 0031 8B442434      movl    52(%esp), %eax
  27 0035 89542440      movl    %edx, 64(%esp)
  28 0039 89442444      movl    %eax, 68(%esp)
  29 003d 8B4004        movl    4(%eax), %eax
  30 0040 034204        addl    4(%edx), %eax
  31 0043 894104        movl    %eax, 4(%ecx)
  32 0046 8B542440      movl    64(%esp), %edx
  33 004a 8B442444      movl    68(%esp), %eax
  34 004e 89542410      movl    %edx, 16(%esp)
  35 0052 89442414      movl    %eax, 20(%esp)
  36 0056 8B4008        movl    8(%eax), %eax
  37 0059 034208        addl    8(%edx), %eax
  38 005c 894108        movl    %eax, 8(%ecx)
  39 005f 83C46C        addl    $108, %esp
  40 0062 C3            ret
  41                .LFE1:

まずまずの結果。とりあえずインライン展開に関しては問題なくなったようだ。しかし細かいところを指摘すれば,ちらほらと意味の無いスタック操作が散見される。ここんとこ,よく見てみてもちょっと意味がわからない。テンポラリオブジェクトを生成しているのとはまたちょっと違うようだ。実処理には関わらないはずの expression object を消去しきれずにいるのかなあ,と思う。

これを,別のマシンに入っていた Redhat Linux 7.0 + gcc2.96 でコンパイルしてみると,さらに興味深い結果が得られた。

   9                    .LFB1:
  10 0000 53                    pushl   %ebx
  11                    .LCFI0:
  12 0001 8B542410              movl    16(%esp), %edx
  13 0005 8B4C240C              movl    12(%esp), %ecx
  14 0009 8B02                  movl    (%edx), %eax
  15 000b 8B5C2408              movl    8(%esp), %ebx
  16 000f 0301                  addl    (%ecx), %eax
  17 0011 8903                  movl    %eax, (%ebx)
  18 0013 8B4204                movl    4(%edx), %eax
  19 0016 034104                addl    4(%ecx), %eax
  20 0019 894304                movl    %eax, 4(%ebx)
  21 001c 8B4208                movl    8(%edx), %eax
  22 001f 034108                addl    8(%ecx), %eax
  23 0022 894308                movl    %eax, 8(%ebx)
  24 0025 5B                    popl    %ebx
  25 0026 C3                    ret
  26                    .LFE1:

文句なしに完璧なコードだ。ていうか gcc2.96 なのになんでこんなコードが吐けるんの?

その後しばらくの間,コンパイルオプションやらライブラリ設定やらと格闘してみたものの,どうがんばっても RH7.0 + gcc2.96 で得られた最適コードを gcc3.1 から捻り出すことはできなかった。うーん,まったくわけわからん。 gcc2.96 で実際に出てるもんは出てるんだから,どうにかすれば gcc3.1 からも同じ結果(もしくはそれ以上のもの)を得られるはずだと思うんだけど……うがー。

血眼になって gcc のメーリングリストや google をあさってみたものの,結局なしのつぶてだった。もうこれ以上ここに時間を費やしたところで良い結果を得られる気がしなくなってきたので,無念だけれど諦めることにした。とりあえず gcc3.1 で問題なくコンパイルできることは確認したから,しばらくの間これでしのいでおいて,また何か手がかりが得られればそのときにアクションを取ることにしようと思う。


irradiance volume

2002-06-21

結局一週間続いたな……。


GDAlgorithmsList の "sampling lighting environments" スレッドにて Charles Bloom と Peter-Pike Sloan の一問一答。

http://www.geocrawler.com/mail/thread.php3?subject=%5BAlgori...

ここで Peter-Pike が文献として挙げているのが,コーネル大は Gene Greger の "irradiance volume"。

http://www.graphics.cornell.edu/pubs/1998/GSHG98.html

内容はそれほど深いものでもなくて,空間において適当な間隔で放射照度をサンプリングしておいて,あとはそれを補間して使えばリアルタイムに厳密な環境光を求めることができるよねー,みたいな内容。実際には,サンプリング間隔と補間の方法をもうちょっと適応的に行う必要がありそうな気がする。例えば,机の上面と下面では非連続的に係数が変化しているわけで,それを適当にサンプリングして適当に補間したんじゃやばいよね……とか。


通販日和

2002-06-22

布団を叩けばいくらでもホコリが出てくるように,ソフトを叩けばいくらでもバグが……。


Real-Time Rendering 第二版の予約が開始されたようだ。

http://www.amazon.co.jp/exec/obidos/ASIN/1568811829

実際の発売日は7月になる模様。即ゲットするしか。

ちょこっと関連のあるところで "Game Developer magazine Back Issue CD-ROM" の第4弾が登場とのこと。

https://www.gamasutra.com/php-bin/store.php?item_id=99

重要な記事はほとんど Gamasutra で読める気もするけれど,この CD-ROM のボリューム感はなかなかのものだと思う。せっかくだから vol.1-4 をセットで買ってみるのもいいかもしれない。

https://www.gamasutra.com/php-bin/store.php?item_id=10

仕事疲れで金銭感覚が狂っているので,こういうのもばしばし自腹で買っていきますぞ,の心意気でゴー。ていうか経費で落とすのめんどくさいんだよね……。


ハンガリーはブダペスト大学の講義ノート "Monte-Carlo Global Illumination Methods" 。

http://www.fsz.bme.hu/~szirmay/mc.htm

教科書としてよさげな感じがするので,手を出してみようかと思う。せっかく Jansen 本を持ってるんだからそっちを読めばいいんだけど,鞄を持たない性分なので,ハードカバーを素で持ち歩くのはちょっと気が引ける。なもんだからほとんど積読状態だ。持ち歩くにはちょうどいい大きさではあるんだけどね。もったいない。


Minimalist GNU for Windows

2002-06-23

今夜は忙しくなることが最初から知れていたので,昼に帰宅して夜出社。来週の日曜はゆっくり過ごせてるといいけど。


C++ の勉強でもすっか……ってことで,おもむろに下調べを開始する。

まずはコンパイラの調達から。 Linux の方は gcc3.1 をビルド済みだけれど(いまだに主流は 2.95-2.96 にあるので gcc3 系列を使う場合はソースからビルドしなければならない) Windows の方は未整備。 cygwin で gcc3.1 をビルドするのも無理じゃないかもしれないけれど,とりあえず mingw のパッケージを使っとくのが無難そうだ。

http://mingw.sourceforge.net/

一括パッケージ (MinGW-1.1.tar.gz) の方は 2.95 ベースなので(騙されたっ)個別のパッケージをダウンロード。 cygwin を入れてある場合は binutil 等は要らない。 OpenGL とかフガフガやる程度だったら gcc3.1-core, mingw-runtime, win32api だけでOK。全部合わせて 8MB 程度。さすがは Minimalist GNU for Windows ってとこ。


あとは適当にライブラリの調達。

http://stlport.org/

STLport は,ポータブルかつ高速な STL の実装として有名なライブラリ。 GNU の stdc++ はいかんせん信用ならんので入れてみることにする。ちっとは速くなることも期待して。

http://boost.org/

boost は,泣く子も黙る問答無用のテンプレートライブラリ。なんだかマニアックなライブラリで使い方もさっぱり分からんけれど, boost::array や boost::smart_ptr なんかは普通に使える感じ。むしろ普通に使っていきたい所存。

http://boost.org/libs/array/array.html

http://boost.org/libs/smart_ptr/smart_ptr.htm

乱数ライブラリ boost::random には噂の Mersenne Twister なんかも入っている。これは素直に便利。

http://boost.org/libs/random/index.html

変態度の高いことで有名な boost::lambda も gcc3.1 なら問題なく使うことができるようだ。ていうかこれ C++ じゃないよー。内部構造がどうなっているのか見当さえもつかない……。

http://boost.org/libs/lambda/doc/index.html

boost::any や boost::iterator_adaptors あたりになると,もはや何がしたいのかさえも分からなくなってくる。あー,まずは STL の勉強をしないと。

http://www.sgi.com/tech/stl/table_of_contents.html

sgi の STL リファレンスはなかなかよく出来ていると思う。もっぱら参考書はこれ。 iostream については cplusplu.com のリファレンスが便利だと思う。

http://www.cplusplus.com/ref/iostream/

ここら辺のリファレンスは意外とまとまったものが少ないんで重宝する。あとは C++ 自体のリファレンスが欲しいなあ。


GLFW

2002-06-24

020624.png

なんだかすごい微妙な状況。げふげふっ。


C++ の練習がてら Paul Bourke の "Random Attractors" を OpenGL で実装してみることにした。

http://astronomy.swin.edu.au/~pbourke/fractals/lyapunov/

式とサンプルソースが載っているんで,わりとそのまま素直に実装。あとは適当に STL やら boost やらかき混ぜまくって遊んでみる。アルゴリズムテンプレートとか,使ってみるとわりと便利なもんですな。ふーむ。

今回,フレームワークには GLFW を使ってみた。

http://hem.passagen.se/opengl/glfw/

GLFW は OpenGL の表示関連とスレッド関連,あと入力操作とかを囲ってくれるライブラリだ。わりと最低限のラインだけをきっちりとこなしてくれるところがありがたい。特に,スレッド操作まで押さえているところが重要。ウィンドウメッセージ処理とメインフローを分離させるにはマルチスレッドが欠かせないんだけど,マルチスレッド API 自体の構造や,レンダリングコンテキストのスレッドに対する割り当て規則なんかがプラットフォームによって微妙に異なってくるので,この辺りをまとめて担当してくれることにはかなりのメリットがあると思う。

SDL + OpenGL もいいけれど,ほんとうに GL だけでいいよ,って場合には GLFW がもってこいかもしれない。こうなると,いよいよ glut を使う機会が減ってくると思う。


んでこのサンプル,頂点数がものをいうもんだから, GPU 搭載マシンと非 GPU マシンではまったく速度が異なってくる。 Mesa だと数万頂点ですでに紙芝居状態だけれど, GF2 なら10万頂点を超えてもまだ比較的スムースに動いてくれる。上の画像は15万頂点の集合をぐるぐる回しているところ。

ところで,ものはためしにと Matrox G400 上で動かしてみたら,数万頂点でハングアップ状態になってしまった。中途半端なハードウェアだとソフトウェアレンダリングよりも使いづらいってわけ……。


すっぱりあきらめ

2002-06-25

むむむ……


あれからしばらく C++ をこねくりまわしているものの,納得のいかないことが多くて弱り気味の日々。まず納得のいかないことに STLport の sstream にゴミが混入する。

{
  ostringstream oss;
  oss << 0.123456;
  cout << oss.str() << endl;
}
{
  ostringstream oss;
  oss << 0.12;
  cout << oss.str() << endl;
}

とかすると

0.123456
0.12````

なんて感じで,うっすらと原因が分かるような分からないような,非常に気合のこもっていない挙動をなされる。しかもたまに Segmentation fault でお亡くなりになられるから始末におえない。あーあ。

原因を調べるべくデバッガで追跡してみると,なんだかロケール関連の処理で異常が発生しているみたいな雰囲気。そんな変な設定しちゃったっけこのマシン……。その後もしばらくソースを追っかけてみたものの,追い切れるはずもなく撃破。がー。

ここでもうちょっと根性ひねくり出して対策を講じるのもいいけれど, STLport ってそんな労力を払うほどの価値があるもんなんだろうか? ってことで,軽くパフォーマンステストを行ってみることにした。

#include <iostream>
#include <vector>
#include <algorithm>
#include <boost/timer.hpp>

inline int generator()
{
  static int counter;
  return counter++;
}

int main(int argc, char **argv)
{
  const int ITERATION = 100 * 1000 * 1000;

  for (int size = 10; size <= 10000; size *= 10)
  {
    boost::timer timer;

    for (int i = 0; i < ITERATION / size; i++)
    {
      std::vector<int> array(size);
      std::generate(array.begin(), array.end(), generator);
    }

    std::cout << size << ", " << timer.elapsed() << std::endl;
  }

  return 0;
}

まあ,てきとうに vector を生成したり廃棄したり,代入したり,イテレータでおっかけてみたり……って,それだけのプログラム。パフォーマンスで気にするところなんてこんなもんでしょ。余談だけれど boost::timer とかポロっと使えちゃうところが素敵。便利ですな。

んで,さっそく実行。まずは stlport の場合。

10, 6.31
100, 1.84
1000, 1.22
10000, 1.16

次は GNU stdc++ (g++v3) の場合。

10, 2.59
100, 2
1000, 1.34
10000, 1.27

なんか,思ったほど差がないみたいだし,場合によっては標準 STL の方が良い結果を出すこともあるようだ。うーむ,そうであったか……。

ってわけで, STLport はすっぱり切り捨て。仕様に問題がない限り標準 STL の方を使うことにしようと思う。


結論を出したらなんだかすっきりしたんで,ついでにソースの整形でもしてさっぱりすっかー,って感じで,高性能整形ツール "artistic style" のダウンロード&ビルドに取り掛かった。

http://astyle.sourceforge.net/

悪夢が再来したのは,その直後のことだった。

bash$ ./astyle --help
Segmentation fault

うがー。


終わる日

2002-06-26

はあ,終わった。やっと終わった……。


取り除くのはなかなかめんどくさい

2002-06-27

ようやく仕事がひと段落して気が抜けてしまったものだから,かなり豪快に寝坊をかましてしまった。まあ,ぜんぜん忙しくないから遅刻しても大丈夫なんだけど……,やっぱり寝坊ってのはあんまし気持ちのいいもんじゃない。なんだか納得いかない気持ちで出社。


どうにも調子の悪い gcc3.1 の再ビルドを試みる。けっきょくそれでも失敗したんだけれど,なにげなく /usr/local/include/g++-v3 を削除してから再び make install してみたところ,とたんに調子が良くなった。うーむ,ってことは,インストール先にゴミの混ざっている状態で make install しちゃあいけないってことか……。そう言えば gcc3.1 を入れる前に gcc3.0 を入れてみたりとかいろいろ悪さをしていた記憶があるので,その影響でバグっぽい状態になっていたのかもしれない。

http://gcc.gnu.org/install/finalinstall.html

なるほど,よく見てみるとマニュアルにも「インストール先に古いバージョンの gcc が入っていないこと」との一文がある。しかし gcc の Makefile には uninstall 擬似ターゲットがないから,一度インストールした gcc を取り除くのはなかなかめんどくさいんだよね。

そんなもんだから, FAQ の 2.2 にあるような方法でもって "/usr/local/gcc3.1" とかにインストールしておくのがいい方法かもしれない。これなら,インストール先のディレクトリをまるごと削除するだけで古いバージョンを取り除くことができるはずだ。

http://gcc.gnu.org/faq.html#multiple


amazon.co.jp にて "Real-time Rendering" と "Game Programming Gems III" をまとめて注文。

http://www.amazon.co.jp/exec/obidos/ASIN/1568811829

http://www.amazon.co.jp/exec/obidos/ASIN/1584502339

どちらも来月発売予定なので,恐らくまとめて届くはずだ。

ついでになぜかヲノサトルの「ビキニ・ムーン」を注文。

http://www.amazon.co.jp/exec/obidos/ASIN/B00005G7AM

ヲノサトルはポップなやつが大好き。それにしても,多作なわりにはソロ作品が少なめなのがちょっと残念だ。脂の乗っているうちに,もっとキャラクタの濃く出ている作品をたくさん出して欲しいなあ,と思う。実験音楽っぽいのはちょっと僕にはつらいけども。


ついでに "Modern C++ Design" と「侍本」もいっしょに買おうと思ったんだけれど,これは明日紀伊国屋に行って直に購入することにした。あんまし一気に購入しても積読が増えちゃうだけだし,明日は新宿にちょっとした用事があるから(ついに GTA3 の発売日だ),そのついでに買ってこようってわけ。紀伊国屋の「ハイブリッドウェブ」で在庫も調べたから,骨折り損になる心配も無い。

https://bookweb.kinokuniya.co.jp/hb/index.cgi?MODE=3

書籍や CD ,ゲームなんかはたいてい amazon で用が済ませられるんだけれど,急に欲しくなった場合なんかには店舗に足を運ぶこともある。そういうときに,こういった在庫検索システムはとても便利だ。今回は侍本が amazon で売り切れになっていたし,なんだかちょっと得した気分。


やっと仕事も終わったし,ってことで,いきつけの寿司屋こと「おさえ」で軽く一杯。

http://www.asku.com/cgi-bin/jrg/osform/JRGRead?osform_templa...

寿司は美味しいし,日本酒もいい感じに混ざって上気分。最近,シケた飯しか食ってなかったからなあ……。うまい棒とか。

まあ,そんなわけで,これからはちょっとアルコール摂取が続きそうな感じだ。


重いだけならまだしも

2002-06-28

出社前に紀伊国屋に寄って侍本をゲット。コンピュータ関連書籍コーナーにあったはずの在庫はもうなくなっていて,店員に尋ねたところかろうじてゲーム本コーナーに置いてあった一冊を確保。 amazon でも速攻売り切れていたわけだし,なんだかわりと売れているみたいだ。

まだ読み途中だけれど,内容はかなりいい感じ。とりあえず,よくぞここまでリアルに書ききったなあ,の一言。それを許したアクワイヤもすごいと思う。大方の内容において嘘臭く感じる部分はまったくなくて,第三者の視点にある限り最も正確なドキュメンタリーなのではないかと思う。中小規模の独立企業に特有の悩み,ジレンマについては特に馴染みのない概念で,なかなか興味深い内容だった。


ついでに "Modern C++ Design" を購入する予定だったんだけれど

http://www.amazon.co.jp/exec/obidos/ASIN/4894714353

いきなり飛躍し過ぎだよなー,ってことで,急遽 "Effective STL" にターゲット変更。

http://www.amazon.co.jp/exec/obidos/ASIN/4894714108

まずは無難に STL を,ってことで。


本屋を出たあとは,そのまま徒歩で西新宿に直行。ヨドバシカメラにて今日発売の gta3 を購入。うちのやや古めなマシンのスペックで対応できるかどうかが心配だけれど……。


んでまあ,仕事の打ち上げ会だのなんだのあって,終電前には帰宅。半分酔った状態で gta3 のインストールを試みる。

んー,やはり GeForce2MX には荷が重かったみたいだ。ただほっつき歩いているだけでも紙芝居状態だし(しかも地面を見ながら歩いていると微妙に軽くなるのが,なんかいやだ),重いだけならまだしもハングアップしてしまうこともしばしば。ぬぬぬ,これじゃあまったくゲームにならんじゃないか……。 CD ドライブの回転音もやたらうるさいし(BGM を常時 CD からストリーミングしているみたいだ),不快なことこの上ない。


RADEON 8500 LE

2002-06-29

昨日の雪辱を晴らすべく秋葉原に出立。とは言っても,まだ何を買うかぜんぜん決めてない。その場の雰囲気でなんとかすんべ……。


まずは輸入系怪しげゲームショップこと "Game's Ark" にて "DUAL FORCE2" をゲット。

http://www.gamesark.co.jp/productscatalog/9121.htm

単に連射機能とコマンド機能が付いただけのパッドなんだけど,最近はこういう製品はあんま流行らないらしくて,普通のゲームショップなんかではなかなか入手しづらい。デバッグ時に連射パッドが欲しかったんだけど近場で入手できなかったことを思い出してなんとなく購入。

余談だけれど,連射パッドやプログラマブル・コントローラは意外とデバッグ作業に重宝する。ゲームステートが切り替わる瞬間(例えばフィールド画面から戦闘画面に切り替わる瞬間とか)に特定の機能をコールすると(例えばオプション画面を開くとか)ハングアップしてしまう,ってバグは,意外と混入しやすいうえに,普通にプレイしている分にはなかなか発症しないがために,開発の終盤になってから発覚し深刻な問題となることなんかもある。そういったバグの確認,検証を行うために連射パッドが欠かせない,ってわけ。


次にコレガの USB 対応 KVM 切換器を購入。

http://www.corega.co.jp/product/list/changer/ckvmu.htm

USB 対応な上に電源を USB から拾ってくれるので外部電源が不要なのがナイス。ディスプレイの同期設定を完全に一致させればほとんどシームレスにマシンを入れ換えることができる。す,すげえぜっ。久々にいい買物をした気分。

ちなみに, "KVM" は "Keyboard-Video-Mouse" の略らしい。ふーむ。

http://www.everything2.com/index.pl?node_id=1282041


んで,今日の本命はこれ。 low profile 対応の RADEON 8500 LE カード。

http://www.askselect.jp/ap64dl.htm

今日は予備知識無しに行ったんだけれど,偶然発見したので即購入。これで今の NLX マシンを生かし続けることができるかもしれない。


ぷらっとホームにて Kinesis 社の USB 対応フットスイッチを購入……

http://online.plathome.co.jp/cgi-bin/details.phtml?scd=11650...

……のつもりだったんだけど,案の定売り切れていた。うへえ,実はこれが今日最大の目玉だったんだけどなあ……。同時に購入したいなあと思っていた旧モデル HHK も一台も置いてないし,ぷらっとホームでは惨敗な感じ。

HHK Lite2 はいろんなところが微妙に弱まっていてダメな感じ。結局初代のが,素材やデザイン,キータッチの点で最もお気に入りだ。もう新品は入手不可能なんだろうなあ。


まあそんなこんなで帰宅したんだけれど,せっかく購入した仮想 CD ソフトを職場に置き忘れてしまって撃沈。こんな騒々しいドライブをけたたましく鳴らしてたんじゃ,おいそれとゲームできん。


Atari days

2002-06-30

ひさしぶりの土日休業。今日は寝て過ごす日。なにもしないまま,ただぼんやりと時を過ごした。


なにげなく Atari 2600 のゲームリストなんかを見てみる。なんでこんなページ見てるんだろ……。

http://www.vgmuseum.com/atari2.htm

膨大なリストをぺらぺらと流し見していると,ふと「アタリショック」なんて言葉を思い出す。そりゃあ,

http://www.vgmuseum.com/images/02/3d1.html

こんなソフトばっか千本以上も出されてたんじゃ,市場不信も起こるっしょ……って感じ。いくら時代が違うと言えども,市場が未成熟な状態でこんなにも貧弱なソフトばかり出していたら,やっぱりまずいんだよねえ,って思う。

この辺りの事情については "The Atari History Museum" の解説に詳しい。

http://www.atari-history.com/videogames/atari2600.html

> Atari 2600 は安っぽいゲームばかりのように見える。ビデオゲームの流行を当て
> こんだ企業の安直な参入が相次いだからだ。この安っぽいゲームの乱発は,誰も欲
> しがらないカートリッジの過剰生産を引き起こすことになる。今でこそレビューな
> どを見てから評価の高いゲームを買うという判断ができるものの,当時は何の疑問
> もなくカートリッジを買うしか手段がなかったのに,だ。
> そこで突然,安売りが開始される。人々はビデオゲームの一時的な流行が終わった
> と判断し,コンソールやアクセサリの売り上げは激減した。各企業の首脳たちは,
> 十分な知識が無いために,この動きが単なるパニック症状であることを理解できな
> かった。出資は撤回され,一夜のうちに会社がたたまれ,数百の発表済みのタイト
> ルが世から姿を消した。
> このビデオゲーム界最大の失敗は多くの関連企業を倒産させ,アタリ社は没落を迎
> えることになる。

それにしても Atari 2600 のサウンド機能は貧弱だ。どうやら,ピッチコントロールを 30kHz の分周指定でしか行えなかったようで,まともに音程を指定することさえままならないものだったらしい。 "ACID DROP Title Song" を聴いていると,その苦労がしのばれる。

http://www.tu-chemnitz.de/phil/hypertexte/gamesound/files/ac...

ところで,この mp3 が置いてある "Digital Sound and Music" の History ページでもって歴史の流れを辿っていくと, "SID 6581" − いわゆる「コモドール64」の登場がどんなに鮮烈なものであったのか,思い知ることができる。

http://www.tu-chemnitz.de/phil/hypertexte/gamesound/history....

僕は SID の音自体はあまり好きでも嫌いでもないんだけれど,この時代を身をもって体験した人たちにとってみれば,決して忘れることのできない黄金の記憶として刻み付けられてしまっているのだろうと思う。

僕的には PC の方が思い入れが強いので,ノスタルジーに浸るならこっち。 "That Oldskool Beat"

http://www.oldskool.org/pc/sound/

Adlib ってやっぱすごかったんだなあ……とか。日本で言うなら FM PAC って感じ? うーむ。