メガドラ開発:スクロールの種類

 メガドライブには様々なスクロール方式があります。それぞれに一長一短があり、理解したうえで工夫すれば効果的な演出が可能です。他のハードでラスタースクロールを行う場合はHBlankで割り込みを発生させる必要がありますが、メガドライブはハードウェアで実装されているため、データテーブルをセットするだけ実現できます。これは使わない手はありません。今回は動画も交えてスクロール方式の違いやクセを見ていきたいと思います。

スクロールの種類

 まずは横スクロールの種類です。以下の3種類があります。

  • プレーン

  • タイル

  • ライン

 プレーンは画面全体をスクロールさせる、最もオーソドックスなスクロール方式です。タイルは上から8ドット単位でスクロール値を指定できます。ラインは1ドット単位です。
 次に縦スクロールの種類です。

  • プレーン

  • コラム

 プレーンは横スクロール同様、画面全体のスクロールです。コラムは日本語で行列の列、つまり縦の線を意味します。読み方はカラムの方が一般的かと思いますがが、メガドライバー的にはコラムスを尊重してコラムと呼称します。仕様的には16ドット単位での縦分割といった感じです。名称に関しては、SGDKの定数を参考にしています。それでは、順を追って各方式の特徴を説明していきます。

横:プレーン、縦:プレーン

 これは敢えて説明するほどのこともないですが、網羅する意味でも触れておきます。プレーンスクロールは画面全体をスクロールさせる方式です。縦、横それぞれ2byteで指定します。横スクロールのデータテーブルは最大で【224ピクセル(縦解像度)*2プレーン(メガドラはBGを2画面持っています)*2byte=896byte】必要ですが、この方式ですと4byte転送するだけで済みます。縦スクロールのデータテーブルも同様に【20byte(横解像度/16)*2プレーン*2byte=80byte】が最大ですが、プレーンxプレーンであれば4byteでOKです。DMA転送はメガドラの演出の要ですので、必要がないときは転送量を抑えられます。

横:タイル、縦プレーン

 横スクロールの方式の一つであるタイルスクロールは上から8ドットずつスクロール値を指定する方式です(224/8=28タイル)。プレーンA/B合わせてもわずか112byteで迫力ある画面を表現できる費用対効果の高い方式です。ポイントとしては、セル(8*8ピクセルのグラフィック)ごとにスクロールを切り替えるのではなく、画面上の8ドット単位でのスクロールということです。つまり、縦スクロール値が8の倍数のときはセル単位のように見えますが、それ以外のときはズレたような見た目となってしまいます。文章で説明するよりかは動画で見た方が早いと思いますので、以下の動画を見てみてください。

縦スクロールした途端にズレた印象を受けたかと思います。よく見ると、分割がセル単位ではなく、上から8ドットずつであることがわかるかと思います。
 つまりゲーム内でこの方式を使う場合には、縦スクロールしないようにするか、縦スクロールするときはラインスクロール方式を使うようにしないといけません。

横:ラインスクロール、縦:プレーン

 ファンタジーゾーンのタイトル画面や、ダライアス2の炎のうねうねなど、この時代の特殊効果としては代表的な表現ですね。タイルスクロール方式のような縦スクロールの影響もないため、無敵の表現力を持ちますが、メガドラの縦解像度は224ピクセルですので、プレーンA/B合わせて896byteの転送が必要です。これはどの方式でも同じですが、プレーンA/Bで別々の方式を指定できません。プレーンAだけラインスクロールさせたくとも、プレーンBは(例え平面的な表現だったとしても)同じ値を224ライン分セットする必要があります。それだけ処理に無駄が生じてしまうので、本当に必要なときだけ使うべきでしょう。

横:プレーン、縦:コラム

 縦のコラム方式は16ドット単位で縦に分割表現が可能です。これはメガドラならではのスクロール方式です。クセが強いですが、使いこなすと驚きある表現が可能です。横のタイル方式では上から8ドット単位でしたが、コラムは左から各コラムに対してスクロール値が設定されているような印象となります(恐らく、データを設定する優先の都合かと思います)。
 また、横スクロール値が16の倍数であれば問題ないですが、下位4bitが0x1~0xFの場合、一番左にチラ見えしている欠けたコラムに対して縦スクロールさせることができません。バグのようにも感じますが、これが仕様です。この問題に対して、市販のゲームでは【気にしない】、【スプライトでマスクする】、【気にならないような絵柄にする】など様々な方法で対処しています。
 横スクロールしていっても各コラムに値が設定できるように見えるため、横スクロールが進んでいくとカクンとズレたように見えてしまいます。各コラムに値が設定されているように見えますが、実際には画面上に見えているコラムに左から順番に値が設定されているわけですから、横スクロールが16を超えた段階で対象となるコラムが変わってしまっているわけです。わかりやすくするために、動画内ではスクロールデータと、対象となるコラムを視覚化しています。赤、青などのラインと数字が書かれているのが、縦スクロールデータとその対象となっている箇所です。

 このようなカクつきを抑えるには、横スクロール値が16を超えたら、指定する値と場所をソフト側で対応させる必要があります。

横:タイル、縦:ライン

 コラムスクロールの問題点について、横スクロール値が一定値を超えると指定対象が変化するためカクつくことを挙げました。横スクロール値に応じてコラムのデータを変えてあげれば問題ないわけですが、タイルやラインスクロールでは、設定箇所ごとにスクロール値が異なるためそうもいきません…。値のユレ幅が16ドットの範囲に収まるなら以下のような表現が可能です。

 ですが、このユレ幅が16を超えてしまうと…

 横スクロールが16ドット境界を越えたところから対象が変わってしまい、画面はグチャグチャになってしまいます。
 視点を変えて、コラム間の値のズレを小さくしてみました。これならあまり気にならないでしょう。以下の動画は各パラメータが一次関数のためあまりズレが目立ちません。特に動画だとほぼ問題がわかりにくいことですが、エミュレータ上ではモアレのようなズレが確認できます。縦のスクロール幅を大きくするとより顕著です。

横:タイル、縦:コラム

 順番としては逆になりますがタイルでもコラム指定は可能です。基本的には【横:ライン、縦:コラム】と同じ問題を抱えることになります。

補足:アウトランのようなアップダウン表現について

 ラスタースクロールを使った表現としては、アウトランなどで見られる地形の起伏表現があります。今回紹介したスクロール方式ではこの表現はできません。実現するにはHBlank割り込みを使って、縦スクロールの値を変更してあげればOKです。その際には縦スクロールはプレーンでないと値の設定が間に合いません。

この記事が気に入ったらサポートをしてみませんか?