ずっと前からMAMEでのATARI STARWARSの描画に納得がいってなかった。敵弾はもっとギラギラ光ってたし、被ダメージ時には画面がチカチカするし、デス・スター爆発は眩しかったし。そう思ってたけど、修正するのは大変そう。
ちょっと前に、あることがきっかけで「MAMEでSTARWARSを動かして描画されたベクターデータをファイルにダンプ」「そのダンプファイルをSVGに変換して1フレームずつ表示するWebアプリ」をClaude Codeに作ってもらったことを書いた。その時にいろいろ調べた結果、「敵弾がキラキラする理由」「被ダメージ時に画面が点滅する理由」「デス・スター爆発が眩しく見える理由」がおおよそ判明した。
ATARIのカラーベクターゲームに使用されているAVG(Analog Vector Generator)では、下記のコマンドで描画を行う。実際にはジャンプやコール・リターンなどもあるけど省略。
- CNTR 描画位置を画面中心にリセット
- SCAL 描画時のスケールを設定
- STAT 描画時の輝度・カラーを設定
- VCTR 指定されたX/Y方向に指定した輝度でベクターを描画、輝度が0だと描画位置の移動のみ
STARWARSだとSTATで指定するIntensity(輝度)が8bit、VCTRで指定するIntensityが3bitである。で、眩しく光ってる敵弾とデス・スター爆発の時のベクターは「STAT Intensity:0xff」「VCTR Intensity:0x7」と最大レベル。つまり最高輝度で何かが起こってる。
古くから存在しているドキュメント「The Secret Life of Vector Generators」を改めて読んでみると、今まで気づかなかった部分を発見した。
The Secret Life of Vector Generators
該当部分を翻訳して引用したのが下記の一節。
デス・スターを思い通りに爆発させるには、同心円をたくさん描くだけでは不十分でした。ビームをぼかして、画面を埋め尽くしたかったのです。フォーカス電圧を制御するために、モニターに真空管を追加することも検討しました。幸いなことに、その部品の納期が長すぎました。そこで、ベクトルジェネレーターにモニターのカラー入力をオーバードライブする機能を持たせることにしました。入力をオーバードライブすると、CRTは通常よりも多くの電流を消費し、高電圧が低下します。これにより、フォーカスグリッド電圧とアノード電圧の通常の比率が変化し、ビームがぼやけます。
つまり設計上、Intensityはオーバードライブ領域まで突っ込めるようになっていて、その時にビームがぼやけて太くなると。コレですわ。
先の「ベクターダンプデータを元に表示するWebアプリ」に、そのオーバードライブ時の処理を入れてみたらいい感じに表示された。ビンゴだ。被ダメージ時に画面が点滅するのは、画面外にこのオーバードライブ状態のベクターが描かれたら光らせればいい。これも良い感じ。
じゃあこれをリアルタイムでやればいいのか? MAMEの改造とかしんどすぎるよ、と思いつつClaude Codeに頼んでみると行けそうな感じ。マジか?
しかし上手く行かない。bgfxとか知らなかったので、Claudeに指示する方もふんわりした言葉でしか出せないのが原因。作って壊して勉強しての繰り返し。なんとか三回目で納得いくものが出来た。
ある時、Windows限定でMAMEを「-video d3d -hlsl_enable」で起動すると、Direct3D9を利用したレンダラがベクタースキャンゲームで有効になることに気づく。こっちの方が見た目がいい。じゃあこれを急遽マルチプラットフォーム対応のbgfxに移植して、先のオーバードライブと画面点滅を実装すればいいんじゃねと。
しかしそのまま移植するとかなり重たくなってしまった。たまたま40fpsのSTARWARSだとギリギリで動いてしまうので気づかなかったけど、60fpsのTEMPESTだと処理落ちする始末。慌てて軽量版を作って回避したり、RTXの自動輝度補正が悪さをして原因究明に時間がかかったり。
そしてなんとかなった。ソースコード・ドキュメントはほぼすべてClaude Codeによるもの。動画はNVIDIAツールで録画しただけの代物。敵弾と被ダメージ表現は我ながらいい感じだと思う。デス・スター爆発はもうちょいなんとかしたかったけど、改善するにはMAMEの表示周りを大改造しないとダメだと思う。
被ダメージ時のモニタ点滅のメカニズムを動画で再現、蛍光面の外に強いビームを出すとブラウン管内部で拡散されてモニタが光る。エミュレータでもちゃんと実物と同じ動きをするのは作った本人でも感動する。
TEMPESTデモアトラクトも出しておく。実機には負けるけどタイトルの眩しい感がポン出しで出せたのは嬉しい、実機だとモニタが焼けるほどの輝度だし。
Windows 64bitバイナリは下記からダウンロード出来るので、試せる人は試してください。当たり前だがROMイメージは付いてないので自分で用意する事。アーカイブ中のvector-mod.txtを読んでbgfxにしないと見た目が変わらないので注意。非力なマシンだとちょい厳しい。CPUよりグラボ依存。
Release MAME Vector CRT Mod (0.288, Windows x64) · okaz-code/mame
そしてMAME devにpull requestも出してしまった。ちゃんと規則を守って出してる。大丈夫なんかなコレ。
MAMEに元からあるD3D hlslから移植・改造した項目は下記の通り
- 蛍光体残像
- 色変換/コンバージェンス
- デフォーカス
- シャドウマスク
- 球面(樽)歪み
- 長いベクター線の輝度減少
- 多段BLOOM(8 段・RGBA16F 累積)、オリジナルの15段を軽量化
自分で設計して追加した項目は下記の通り
- ベクター線両端の円描画処理
- HALO平滑化(BLOOMの段数が少なくなった代わりの措置)
- 糸巻き歪み
- 縮小によるオーバースキャン領域の表示
- フレーム単位でのフリッカー処理
- RGBカラーの調整
- オーバードライブ(STARWARSのみ)
- モニター発光(STARWARSのみ)
その他いろいろあったかも。ありすぎて分からん。
非力なマシンではダメだと思ってはいたけど、手持ちのSurface Pro4でフレームレートガタ落ちになったのには笑えなかった。さすがに仕方がないか?
まだやりたいネタは色々あるけど、これ以上は流石に手間暇が大変そうなのでちょっと休もう。