メガドライブ用ソフトのプログラミング その 13 - スプライトとスクロール面 | Arcade Cabinet

Arcade Cabinet

自作したゲームコントローラを紹介します


<メガドライブのプログラミングを初めて思ったこと>
1、CPUの処理能力が予想以上に高い
2、楽器といってもいいぐらいの素晴らしい音源チップ(FM音源)が載っている
3、ハードの構造が分かりやすい?
4、VRAMの容量が大きい(他の機種を知らないので自分の印象ですが)
5、C言語とレトロゲームプログラミングの勉強には最適なのかも

などいろいろと思いながら、プログラミングしています。

今日は、メガドライブのスプライトとスクロール面について自分で学んだ覚書をまとめてみました。独学なので間違っているかもしれません。
まず、VRAMの容量は64Kバイトあります。
VRAMには、
①スプライトやスクロール面(バックグラウンド面)の描画に使用するパターンジェネレータ・スプライトジェネレータ(8x8ドットを1セルとするグラフィックス情報)
②スクロールA面のパターンネームテーブル(パターンの指定と左右上下反転の有無、表示優先順位、カラーパレットの指定の情報)
③スクロールB面のパターンネームテーブル
④ウィンドウ面のパターンネームテーブル
⑤スプライトのアトリビュートテーブル(スプライトに使用するパターンの指定と左右上下反転の有無、表示優先順位、カラーパレットの指定の情報)
⑥水平方向へのスクロール情報
②~⑥のアドレスはある程度自由に設定でき、残った部分をパターンジェネレータ・スプライトジェネレータに使用できます。

<パターンネームテーブルって何のこと?>
最初は全く意味を理解できなかったですが、スクロール面は8x8ドットを1セルとするタイルで敷き詰められています。パターンネームテーブルとは、どのタイルをどの向きにどの色で敷き詰めるかの情報のようです。*タイルは横並びになっています。
スクロール面のサイズは可変で、縦横のサイズを32セル・64セル・128セルから選択できます。
ファンタジーゾーンの表のスクロール面は、2048ドット(256セル)あるので、一度に読み込むことはできなかったので、オパオパの動きに応じて見えない箇所で読み込む必要があります。

<アトリビュートって何?>
スプライトで使用するパターンネームテーブルのようなもので、スプライトで使用するスプライトジェネレータの情報のことのようです。
*スクロール面とことなり、タイルが縦並びになります。

また、1セルのパターンジェネレータ・スプライトジェネレータ32バイトの情報量があり、
1セルのパターンネームテーブル・アトリビュートは2バイト(16ビット)の情報量があります。
さらにスプライトには、サイズ情報(1x1セル~最大4x4セル)、位置情報、次のスプライトの指定(スプライトの優先順位の指定に使用)などがあります。


プログラミングしている、ファンタジーゾーン1面で使用しているVRAM情報です。
パターンジェネレータ・スプライトジェネレータは32バイトで、パターンネームテーブル・アトリビュートは2バイトなので、スプライトをアニメーションするためには、ゲーム中はスプライトのアトリビュート情報のみ書き換えたほうが、効率がよさそうなので、可能な限り、スタート時に、VRAMに一気にパターンジェネレータ・スプライトジェネレータ情報を読み込むようにプログラミングしました。

現在の状態です。
オパオパ、装備のパワーアップ、ステーション、敵機の処理に加え、コインを出せるようになりました。スコアやナビゲーションを表示してもほとんど処理落ちしなくなったのですが、7Wayの3連射では完全に処理落ちします。
当たり判定を高速にするにはどうしたらよいのだろう???
ちなみに当たり半径は矩形(四角形)で行っています。

u8 checkCollision(Col *col_1, Col *col_2)
{
    if(col_1->y0 > col_2->y1) return FALSE;
    if(col_2->y0 > col_1->y1) return FALSE;
    if(col_1->x0 > col_2->x1) return FALSE;
    if(col_2->x0 > col_1->x1) return FALSE;
    return TRUE;
}
*四角形1をcol_1、四角形2をcol_2とし、四角形の左上を(x0,y0)、右下を(x1,y1)としています。

目標はC言語のみであと20%ぐらい処理の効率化ができないか考えています。