MSXのVDP(TMS9918A, V9938, V9958)では、Mode1のスプライト(TMS9918A互換スプライト)を1スキャンラインあたり最大4つ描画できますが、5つ目以降のスプライトの描画はスキップされます。(優先度としてはOAM上位のものが最優先だったかな)
このことを「バグのようなもの」と仰っている方が居るようですが、これはバグではなくハードウェアリミット(仕様)です。
別にそのバグだと仰っている方のことを責め立てたい訳ではないです。
「リミットがキツイ」→「仕様の問題」→「バグのようなもの」という文脈も無い訳ではないので。
特に過去ハードウェアのエミュレーションというシーンでは、そのリミットを期待した過去のソフトウェアを動かす必要がある以上、バグというものはほぼ存在しなくてバグのような仕様上の問題もまた全て仕様...という非常に厄介な問題があります。
仕様変更には必ず副作用が伴います。
エミュレータ開発の場合、副作用を見極めることで、仕様上の問題による体験悪化を回避しつつ、改善を図ることも可能で、スプライト水平上限の問題はその例として最適だと思われるので取り上げてみました。
という訳で、
- 何故そのようなハードウェアリミットになっているか
- リミット撤廃(仕様変更)するとどのような副作用があるのか
を考察した上で適切な解決策を考えてみたいと思います。
※なお、私は昔のセガハードには結構詳しいと思うのですが、MSXは触ったことすら無いので、以下SG-1000と同じMSX1のVDP(TMS9918A)の前提で考えます。
-----【考察】-----
TMS9918Aは、NTSC方式ブラウン管テレビの262本(可視スキャンラインは240本)のスキャンラインを約1/60秒間隔(約60Hz)でリフレッシュ(描画)しています。
※ブラウン管テレビのスキャンライン本数は525本で可視スキャンラインは約480本でリフレッシュは約30Hzなので、インタレースして240本にすることで約60Hzにしているものと考えられ、TMS9918AのスプライトとBGはこの内192本が可視領域になっています。
1本のスキャンラインあたりの描画処理に費やせる時間は、1÷60÷262秒(約63.6マイクロ秒)ということになります。
更に、1つのスキャンラインには342個の画素(ピクセル)があり、画面左から1ピクセルづつ逐次的に描画が行われています。
なお、水平の可視画素数は284ピクセルで、BGとスプライトを描画できる領域は256ピクセルです。
1ピクセルあたりの描画処理に費やせる時間は、1÷60÷262÷342秒(約186ナノ秒)ということになります。
TMS9918Aはこの短い時間で、
- バックドロップ(BGの裏面の背景色)
- BGキャラクタ(1~2bit color & 透明色あり)
- スプライト(1bit color & 透明色あり)
という3種類のグラフィックの合成表示を行っています。
これらの内、描画プライオリティが最も高い(=一番最後に描画される)グラフィックがスプライトです。
スプライトは16pxの正方形で最大32枚表示できます。
スプライトの水平上限は、TMS9918Aの性能上スキャンライン辺りの限界ピクセル数が 604(284+256+64)以下であった為に設けられた仕様ではないかというのが私の仮説です。
バグは単純に直せば良いのですが、仕様は変更すると副作用が起こります。
水平上限を単純に撤廃する仕様修正をした場合の副作用としては、
- 演出としてスプライト表示を意図的にカットしていたものが表示されてしまう
- スプライトのコリジョン機能が誤動作する
などが考えられます。
-----【適切な解決策】-----
演出的にカットする時はTMS9918Aなら透明スプライトを利用するケースが大半だと考えられるので、エミュレーションであれば「①優先度が高い透明スプライトが水平に4つ並んでいた時は描画を省略」しつつ、「②コリジョンについてはハック描画した5つ目以降では発生させない」とすることでハードウェアリミットの影響による体験悪化(チラツキ)を抑えつつ副作用をほとんど回避できると考えられます。
副作用を回避できないパターンとしては、非透明スプライト(TMS9918Aのスプライトは1bitカラーで表示するパレット番号の0〜15を指定する仕様で、OAMにパレット0を指定しているスプライトが透明スプライト、パレット0以外を指定しているスプライトが非透明スプライト)を使って意図的なカット演出をしているパターンです。(私が知る限りではこのパターンに該当するソフトウェアは無いと思われます)
仕様を修正する時は、副作用を考慮した上で解決策を考えましょう。
0 件のコメント:
コメントを投稿
注: コメントを投稿できるのは、このブログのメンバーだけです。