スクリプト言語を使う

ここ最近、ちょこちょこモジュールの準備だけはしてる自作ゲーム(ムービーテクスチャの動画プレイヤーもその一つ)に使うスクリプト言語を色々と試していたのだが、とりあえず Squirrel を使ってみることにした。


LuaSquirrelPython、ECL と触ってきたが、どれも使い方は似たようなものだった。
機能的にはECL(Embeddable Common Lisp)が一番充実している(言語機能だけでネイティブのスレッドが扱える)上に、バイトコードだけでなくネイティブのバイナリにコンパイルできる。
しかし、boost::thread と組み合わせると落ちる(pthread 単体だと大丈夫っぽい)ので、これはパス。
Python はリファレンスにやり方が書いてあるのだが、何故かWindows環境で上手く動かない(ファイル読み込み関数で落ちる。回避方法はある)ので、これもパス。
始めは Lua のほうを使おうかと思ったが、Squirrel は書式がC系の言語に似ているので採用することにした。
何か問題があれば切り替えることにする(GC周りの処理が違うらしいが試したことがないのでどう違うのかよくわからない)。


タイトルとは関係ないが、ムービーテクスチャ実装の動画プレイヤーがほぼ完成した。
といっても、以下の機能は結局入れていない。


・一時停止処理
・シーク処理


まあ、ゲーム中に流す程度ならとりあえず必要ないだろう。
パフォーマンスに関しては、オープンソースで配布されてる動画プレイヤーに並ぶくらいにはなった。


【OKな範囲】


FPS - 24〜60
サイズ - 320x240〜1280x720
ビデオフォーマット - mpeg4(avi)、XvidH.264、vp6、flv、wmv
オーディオフォーマット - mp3、ogg vorbisAACHE-AAC は警告メッセージが出まくるが再生に問題はなし)


【絵と音の同期処理】


・基本的に絵はフレームごとに格納されている描画時間、または(※1)平均値(FPS)を算出して、それを描画時間として使用している。
・同期の基準としては絵の描画時間を合計していったものになる。音の再生時間も記録しておき、それらの差分をとって遅延を割り出す。
・音の再生時間は、既に再生されたバッファをキューから取り出すときに、再生されたバッファの容量を合計し、そこから再生時間を計算(※1)し、総再生時間に加算する
・音が飛ぶと目立つので、最初は絵の描画時間を縮めたり長くしたりして、時間差が大きい場合は音を止めたり音をカット(※2)したりする


※1 何故かというと、描画時間とFPSが大きく違う動画ファイルがあって、きちんと同期を取るには、描画時間とFPSを比較して近ければ描画時間を、FPSと比べて速すぎたり遅すぎたりする場合はFPSを使うようにしないといけないから
※2 再生時間 = 再生されたバッファの容量 / (サンプルレート * チャンネル数 * 2)
※3 OpenAL はソースにバッファをキューとして格納し、それを順番に再生していく方式なので、遅延が発生した場合は既に格納されているキューを減らしていく処理を入れた。このときに再生時間もカットした分だけ加算するようにした