描画について
画面づくりの目標
今回の目標は「チラツキを出来るだけ見せずになめらかに動かす」です。
そのために、320x200のダブルバッファを使用しました。
このダブルバッファが使用できるのもX1の強みですね。
処理さえ間に合えば、スプライトと違って横に並んでもチラつく事もないし、
フレームバッファとして活用すれば色々な事ができそうです。
640x200の方がタイリングが細かくてキレイですが、今回はなめらかに動かすのが目的ですので採用していません。
描画の割り振りとして、GRAM=キャラクタ,PCG=地形にすることにしました。
X1のポテンシャルを発揮するには、広い面積を持つ地形部分をPCG、
移動するキャラクタをGRAMで実現するのがベストと考えました。
キャラクタをどうやって高速に描画するか?
性能評価
まず、8x8単位でGRAMを書き換えた時の性能を計測しました。
種類 | 処理時間 | 60fpsで描画可能な数 |
---|---|---|
RGB単純書込み | 156us | 106個 |
RGBブレンド | 316us | 52個 |
RGB単純書込み…単純にGRAMへ書き込み。(Write)
RGBブレンド…一度ReadしてAND/ORして書込み (Read/Write)
書込みとブレンド処理の速度差は約 2倍です。
ブレンド処理が発生すると一気に重くなるため、単純書込みとブレンドを判定するシステムが
あれば高速化が可能と考えました。
ビットラインアルゴリズム
単純書込みとブレンドを判定するシステムとして、
画面上8x8の領域に対応して、1byteの描画情報を持つバッファ、ビットラインバッファを定義します。
1bitが横8bit、各プレーンの1byteに対応しています。
書換えを行う際にビットラインバッファのチェックを行って、
その領域に何も書かれていなければ、単純書込み(Write)、
何か書かれていれば、ブレンド処理(Read/Write)を行います。
これはライン単位で判定を行うので、最小限の箇所だけブレンドを行う事で高速化が可能です。
例えば図中の緑色と赤色の領域は重なっていないので、単純書込みになります。
この方式をビットラインアルゴリズムと名付けました。
ビットラインバッファ
ビットラインバッファはダブルバッファ分を合わせて 2KB。
このビットラインバッファ領域は次のように計算して求めます。
ビットラインバッファアドレス = アクセスGRAMアドレス or 0f800h
0f800hをorする事で、RGBプレーンやライン(0-7),ついでにダブルバッファも吸収して、
対応するバッファ位置を求めています。
そのため、0f800~0fbdfh (Page0), 0fc00h~0ffdfh(Page1) の固定アドレスになります。
X1のGRAM配置がリニアではない事を活用しています。
消去
一度書いた後は、消去する必要があります。
これは X1の同時書込みモードを使って、3プレーンを一回でクリアしています。
その場合でも、ビットラインバッファをチェックして、一度クリアした所は、
クリア処理を実行しないようにしています。
改善点
このアルゴリズムにはまだ改善点があります。
それは一度書いた所を消すコストが高い事です。
ほとんどのケースで、一度描いた所は再度描く事が多いので、わざわざ消すのは非効率です。
このビットラインアルゴリズムは、そのフレーム内で初めて描いたか、2度目以降かを判定していますが、
前回のフレームで描かれた場所かどうかを判定することができれば、より高速化できるはずです。
これを改善したアルゴリズムを現在考えています。