PPU > BG

「PPU/BG」の編集履歴(バックアップ)一覧はこちら

PPU/BG - (2017/08/28 (月) 13:28:22) の1つ前との変更点

追加された行は緑色になります。

削除された行は赤色になります。

***目次 [#lcf94fc4] -[[BGモード>#rf00f240]] -[[タイルマップとキャラクタマップ>#ue7ed8c6]] -[[BGスクロール>#n902fda8]] -[[ダイレクトカラーモード>#dc67e4d8]] -[[モード 0>#mode0]] -[[モード 1>#mode1]] -[[モード 2>#mode2]] -[[モード 3>#mode3]] -[[モード 4>#mode4]] -[[モード 5>#mode5]] -[[モード 6>#mode6]] -[[モード 7>#mode7]] -[[BGのレンダリング>#jc1c09b6]] ***BGモード [#rf00f240] 7 つの画面モードと、主に 2 つの状態変化がある。 画面モードは、[[0x2105>IO ポート (メイン)/0x2105]] のビット 0 ~ 2 で設定できる。 モード 1 の状態変化は [[0x2105>IO ポート (メイン)/0x2105]] のビット 3 で設定でき、 モード 7 の状態変化は [[0x2133>IO ポート (メイン)/0x2133]] のビット 6 で設定できる。 |モード|>|>|>|BGの色数|h |~|1|2|3|4| |0|4|4|4|4| |1|16|16|4|-| |2|16|16|-|-| |3|256|16|-|-| |4|256|4|-|-| |5|16|4|-|-| |6|16|-|-|-| |7|256|-|-|-| |7 拡張BG|256|128|-|-| 全てのモードの全てのBGでパレット番号 0 は透明色に設定されている。 ***タイルマップとキャラクタマップ [#ue7ed8c6] それぞれのBGはVRAMの2つの領域が関係している。 1つはタイルマップ、もう1つはキャラクタデータに使用される。 タイルマップアドレスはは [[0x2107 ~ 0x210a>IO ポート (メイン)/0x2107]] のビット 2 ~ 7 で選択する。 タイルマップのサイズは同じレジスタのビット 0 ~ 1 で選択する。 全てのタイルマップは 32x32 だが、ビット 0 ~ 1 は メモリ上でどのようにレイアウトされるかを指定する。 |値|サイズ|内容|h |00|32x32|AA&br;AA| |01|64x32|AB&br;AB| |10|32x64|AA&br;BB| |11|64x64|AB&br;CD| タイルマップアドレスの最初の 0x800 (2048) バイトはタイルマップAで、 次の 0x800 バイトが B、C、D というように続く。 Aのみが必要とされる場合、他の場所は空の領域とされる。 タイルマップのそれぞれの項目は 2 バイトで、次のようなフォーマットになっている。 |15|14|13|12|11|10|9|8|h |v|h|o|p|p|p|c|c| |7|6|5|4|3|2|1|0|h |c|c|c|c|c|c|c|c| -v/h : タイルの垂直/水平反転 -o : タイルの優先順位 -ppp : タイルのパレット パレットの色数は画面モードとBGに依存 -cccccccccc : タイル番号 タイルマップから特定タイルのワードアドレスを見つけるには (X と Y)、 次の式を使う。 (Addr<<9) + ((Y&0x1f)<<5) + (X&0x1f) + (SY ? ((Y&0x20)<<(SX ? 6 : 5)) : 0) + (SX ? ((X&0x20)<<5) : 0) タイルのキャラクタデータは [[0x210b ~ 0x210c>IO ポート (メイン)/0x210B]] で指定される場所から始まるアドレスに配置されている。 (Base<<13) + (TileNumber * 8*NumBitplanes) それぞれのタイルは通常 8x8 ピクセルのサイズで、ビットプレーンで保存される。 1行はそれぞれ 1 バイトで構成され、一番左端はビット 7 で指定する。 4 色のタイルでは、ビットプレーン 0 と 1 が 1 ワードの下位バイト、 上位バイトとして保存され、8 ワードで 1 つのタイルを構成する。 16 色タイルでは、4 色と同様に 0, 1 が保存され、それに 2, 3 が続くような 形式で保存される。 256 色タイルでは同じ方法で、2 つの 16 色タイルが続くような形式で保存される。 [[0x2105>IO ポート (メイン)/0x2105]] でキャラクタサイズが指定された場合、 16x16 ピクセルブロックのタイルとすることができ、1 つのタイルに タイル、タイル + 1、タイル + 16、タイル + 17 が使われる。 この場合、32x32 タイルマップで、通常の 256x256 ピクセルサイズではなく、 512x512 サイズが使われる。 同様に、64x64 タイルマップでは、BG は 1024x1024 ピクセルまで拡張される。 これらは 16x16 スプライトの時のようにラッピング処理がされることはなく、 Tile=0x2ff を指定した場合、0x2ff, 0x300, 0x30f, 0x310 を使うことになる。 もちろん、 0x3FF からは 0x000 に行く。 このモードで反転フラグをセットした場合、個々の 8x8 タイルではなく、 16x16 タイルが反転される。 ***BGスクロール [#n902fda8] BG モードとインターレス設定によるが、 モード 0 ~ 6 は 256x224 か 256x239 ピクセルの画面を表示する。 [[0x210d ~ 0x2114>IO ポート (メイン)/0x210D]] のスクロールレジスタで、 256x256 ~ 1024x1024 ピクセルの BG の表示領域を調節することができる。 BG を画面外に移動することはできず、 画面外に移動するような設定にした時は単純にラップされる。 (BG を 1024x1024 に設定した場合はどう考えてもできない) [[0x210d ~ 0x2114>IO ポート (メイン)/0x210D]] は全て 2 度書きレジスタで、16ビット値を設定する。 これらのレジスタへ値を書き込んだ場合、その値はバッファに保存される。 これらいずれかのレジスタに新しい値を書き込んだ場合、 現在のレジスタ値と、6バイトのいずれかのレジスタに対して 直前に書き込まれた 1 バイトの値が新しい値と合成されて書き込まれる。 BGnHOFS の場合 : (NewByte<<8) | (PrevByte&~7) | ((CurrentValue>>8)&7) BGnVOFS の場合 : (NewByte<<8) | PrevByte ほとんどの場合、この詳細は重要ではなく、普通に 1 つのレジスタに 2 度書き込めば 問題は起こらないのだが、いくつかのゲームで 1 度だけ書き込んだり、 他に変なことをしていることがある。 タイルマップエントリからスクリーン上の特定のX,Y座標を計算する時には 次の式を使う。 Size = 8 か 16。0x2105 で指定される TileX = (X + BGnHOFS) / Size TileY = (Y + BGnVOFS) / Size TileX と TileY の位置にあるタイルを検索する。詳細は以下 注 : 多くのゲームで垂直スクロール位置は 0 ではなく -1 に設定されている。 これは、SNES が OBJ データをスキャンライン毎に 1 つ前の位置を参照するためである。 1番最初の行では、OBJ データは何もロードされていない。 SNESは実際にはスキャンライン0に出力しない。 インターレス画面では、行 0 を無視するために -1 ではなく -2 を指定する必要がある。 (エミュレータでは1の代わりに2を足す必要があるだろう) ***ダイレクトカラーモード [#dc67e4d8] モード 3, 4, 7 の 256 色 BG では、[[0x2130>IO ポート (メイン)/0x2130]] のビット 0 に 1 が設定されている時、ダイレクトカラーモードが有効になる。 このモードでは、パレットの指定 ('ppp') が無視され、 キャラクタデータではパレットインデックスの代わりに BBGGGRRR で表される色を指定する。 3 ビットの ppp は bgr になり、色データの追加分として使われる。 -赤 (R) = RRRr0 -緑 (G) = GGGg0 -青 (B) = BBb00 ダイレクトカラーモードでは黒いピクセルを指定することはできない。 値が 0 のキャラクタデータは透明色として扱われる。 黒を表示するためには、黒に一番近い値を使うと良いだろう。 (01, 08, 09 辺りが良い) ***モード 0 [#mode0] それぞれ最大 4 色が出る 4 つの BG がある。 パレットエントリの開始位置は次の式で計算できる。 ppp * 4 + (BG# - 1) * 32 表示の優先順位は次の順 (前面から背面へ) -優先順位 3 のスプライト -優先順位 1 の BG1 -優先順位 1 の BG2 -優先順位 2 のスプライト -優先順位 0 の BG1 -優先順位 0 の BG2 -優先順位 1 のスプライト -優先順位 1 の BG3 -優先順位 1 の BG4 -優先順位 0 のスプライト -優先順位 0 の BG3 -優先順位 0 の BG4 ***モード 1 [#mode1] 16 色の BG が 2 面と、4 色の BG が 1 面ある。 パレットエントリの開始位置は次の式で計算できる。 ppp * ncolors [[0x2105>IO ポート (メイン)/0x2105]] のビット 3 の設定によって背景の優先順位は変化する。 表示の優先順位は次の順 (前面から背面へ) -優先順位 1 の BG3 ([[0x2105>IO ポート (メイン)/0x2105]] のビット 3 がセットされている時) -優先順位 3 のスプライト -優先順位 1 の BG1 -優先順位 1 の BG2 -優先順位 2 のスプライト -優先順位 0 の BG1 -優先順位 0 の BG2 -優先順位 1 のスプライト -優先順位 1 の BG3 ([[0x2105>IO ポート (メイン)/0x2105]] のビット 3 がクリアされている時) -優先順位 0 のスプライト -優先順位 0 の BG3 ***モード 2 [#mode2] 16 色の BG が 2 面ある。 パレットエントリの開始位置は次の式で計算できる。 ppp * 16 表示の優先順位は次の順 (前面から背面へ) -優先順位 3 のスプライト -優先順位 1 の BG1 -優先順位 2 のスプライト -優先順位 1 の BG2 -優先順位 1 のスプライト -優先順位 0 の BG1 -優先順位 0 のスプライト -優先順位 0 の BG2 モード 2 は、"タイル毎オフセット" を使う最初のモード。 このモードでは、BG3 のタイルデータはエンコードされていて、 BG1, BG2 の両方またはいずれかの、それぞれのタイルの (可能であれば) HOffset, VOffset の両方またはいずれかを 置き換える。 可視状態のスキャンラインについて考えると、 通常、次に示すような方法でピクセルを取得する。 HOFS = X + BGnHOFS VOFS = Y + BGnVOFS Pixel[X,Y] = GetPixel(GetTile(BGn, HOFS, VOFS), HOFS, VOFS) "タイル毎オフセット" の時は、もう少し複雑になる。 HOFS = X + BGnHOFS VOFS = Y + BGnVOFS ValidBit = BG1 の時 : 0x2000, BG2 の時 : 0x4000 if (!IsFirst8x8Tile(BGn, HOFS)) { /* この計算は正しいだろうと思うが... */ Hval = GetTile(BG3, (HOFS&7)|(((X-8)&~7)+(BG3HOFS&~7)), BG3VOFS) Vval = GetTile(BG3, (HOFS&7)|(((X-8)&~7)+(BG3HOFS&~7)), BG3VOFS + 8) if (Hval&ValidBit) HOFS = (HOFS&7) | ((X&~7) + (Hval&~7)) if (Vval&ValidBit) VOFS = Y + Vval } Pixel[X,Y] = GetPixel(Get8x8Tile(BGn, HOFS, VOFS), HOFS, VOFS) 言い換えれば、BGn の 0-32 の可視状態のタイルと、 BG3 の"可視" のタイルは同じになる。 BGn のタイル 0 のオフセットは普通で、 1 <= T < 33 の範囲にある BGn のタイル T はオフセットデータを BG3 の タイル T - 1 から取得する。 このとき、タイルが実際に配置されているかどうかは問題ではない。 可視の左端のタイルはいつでも通常で (最短、1 ピクセルが可視になるが、 クリップウインドウを使う時にまだ悩むことになるだろう)、 次のタイルは、BG3 の左端のタイルのが何になるかによって、タイルマップエントリを使う。 "新しい"オフセットは BGnVOFS レジスタをオーバーライドするが、 BGnHOFS オフセットの下位 3 ビットはまだ使われるだろう。 スクリーンの現在の Y 座標は BG3 のタイルマップの参照している どの行にも影響しない。Y 座標が常に 0 の時も 一方、たとえ BGn が 16x16 タイルでも、 BG3 は、それぞれ 8x8 サブタイルのオフセットを指定することができる。 BG3 が 16x16 の時、オフセットは関連する BGn の 8x8 サブタイルに適用される。 BG3 が 16x16 の時、Hval と Vval に同じタイルを最後まで使う。 ***モード 3 [#mode3] このモードは、256 色の BG と 16 色の BG がある。 パレットエントリの開始位置は次の式で計算できる。 BG1: 0 BG2: ppp*16 表示の優先順位は次の順 (前面から背面へ) -優先順位 3 のスプライト -優先順位 1 の BG1 -優先順位 2 のスプライト -優先順位 1 の BG2 -優先順位 1 のスプライト -優先順位 0 の BG1 -優先順位 0 のスプライト -優先順位 0 の BG2 注 : [[0x2130>IO ポート (メイン)/0x2130]] レジスタで、BG1 をダイレクトカラーモードに設定できる。 ***モード 4 [#mode4] このモードは、256 色の BG と 4 色の BG がある。 パレットエントリの開始位置は次の式で計算できる。 BG1: 0 BG2: ppp*4 表示の優先順位は次の順 (前面から背面へ) -優先順位 3 のスプライト -優先順位 1 の BG1 -優先順位 2 のスプライト -優先順位 1 の BG2 -優先順位 1 のスプライト -優先順位 0 の BG1 -優先順位 0 のスプライト -優先順位 0 の BG2 注 : [[0x2130>IO ポート (メイン)/0x2130]] レジスタで、BG1 をダイレクトカラーモードに設定できる。 モード 4 は、 "タイル毎オフセット" を使う、2 番目のモード。 モード 2 と同じように機能する。 しかし SNES には、2つのオフセット値をロードする時間がないので、 代わりに次のような処理を行う。 Val = GetTile(BG3, ...) if (Val&0x8000) { Hval = 0 Vval = Val } else { Hval = Val Vval = 0 } ***モード 5 [#mode5] このモードは、16 色の BG と 4 色の BG がある。 パレットエントリの開始位置は次の式で計算できる。 ppp * ncolors 表示の優先順位は次の順 (前面から背面へ) -優先順位 3 のスプライト -優先順位 1 の BG1 -優先順位 2 のスプライト -優先順位 1 の BG2 -優先順位 1 のスプライト -優先順位 0 の BG1 -優先順位 0 のスプライト -優先順位 0 の BG2 このモードは、これまでのモードと違う点が多々ある。 通常の 8/16 ピクセル幅のタイルを使う代わりに、 常に 16 ピクセル幅のタイルを使う (高さは 8 または 16 ピクセル)。 それから、ピクセル列の半分だけ使用する。 (0ベースで、偶数番号のピクセルはサブスクリーンに、 奇数番号のピクセルはメインスクリーンのタイルに使用される) そして、スクリーンを仮想的に 512 ピクセル幅で表示する。 同様に、インターレスモードが ON ([[0x2133>IO ポート (メイン)/0x2133]] 参照) の時、 224 か 239 の高さの代わりに、448 か 478 の高さを使う。 [[0x213F>IO ポート (メイン)/0x213F]] のビット 7 の指定で、偶数ラインと奇数ラインを交互に表示する。 注 : ここに書いたように表示するには、 [[0x212C と 0x212D>IO ポート (メイン)/0x212C]] で同じ値を指定しなければならない。 ***モード 6 [#mode6] このモードでは、16 色の BG のみを使う。 パレットエントリの開始位置は次の式で計算できる。 ppp * ncolors 表示の優先順位は次の順 (前面から背面へ) -優先順位 3 のスプライト -優先順位 1 の BG1 -優先順位 2 のスプライト -優先順位 1 のスプライト -優先順位 0 の BG1 -優先順位 0 のスプライト このモードは、モード 5 と同じように動作する。 また、 "タイル毎オフセット" の機能も追加される。 こちらはモード 2 のように動作する。 しかし、モード 6 では 8 ピクセル幅 (16 ハーフピクセル) のタイルが使用され、 BG3 も BG1 と同じようにこれが適応される。 8 ハーフピクセルにも 16 ピクセル幅の領域にも オフセットを適用することはできない。 (2 つの 8 ピクセル領域に 2 つのオフセット値を使う時は除く) ***モード 7 [#mode7] このモードは、他のモードと極端に違う。 256色のBGが1面あるが、タイルマップとキャラクタマップの 配置の仕方は全く異なる。 タイルマップとキャラクタマップは重なっており、 ***BGのレンダリング [#jc1c09b6] +水平・垂直オフセットを取得 (それぞれレジスタから取得するか、"タイル毎オフセット" により計算される) +これらの値をプレイ画面に変換する 注 : モード 7 ではこの工程がかなり複雑 +座標に合わせてタイルマップを取得する +タイルマップを使ってキャラクタデータを取得する +必要であれば、画像を非ビットプレーンに展開してバッファに格納する 詳細は[[画面のレンダリング>PPU/画面のレンダリング]]参照
#contents() ***BGモード [#rf00f240] 7 つの画面モードと、主に 2 つの状態変化がある。 画面モードは、[[0x2105>IO ポート (メイン)/0x2105]] のビット 0 ~ 2 で設定できる。 モード 1 の状態変化は [[0x2105>IO ポート (メイン)/0x2105]] のビット 3 で設定でき、 モード 7 の状態変化は [[0x2133>IO ポート (メイン)/0x2133]] のビット 6 で設定できる。 |モード|>|>|>|BGの色数|h |~|1|2|3|4| |0|4|4|4|4| |1|16|16|4|-| |2|16|16|-|-| |3|256|16|-|-| |4|256|4|-|-| |5|16|4|-|-| |6|16|-|-|-| |7|256|-|-|-| |7 拡張BG|256|128|-|-| 全てのモードの全てのBGでパレット番号 0 は透明色に設定されている。 ***タイルマップとキャラクタマップ [#ue7ed8c6] それぞれのBGはVRAMの2つの領域が関係している。 1つはタイルマップ、もう1つはキャラクタデータに使用される。 タイルマップアドレスはは [[0x2107 ~ 0x210a>IO ポート (メイン)/0x2107]] のビット 2 ~ 7 で選択する。 タイルマップのサイズは同じレジスタのビット 0 ~ 1 で選択する。 全てのタイルマップは 32x32 だが、ビット 0 ~ 1 は メモリ上でどのようにレイアウトされるかを指定する。 |値|サイズ|内容|h |00|32x32|AA&br;AA| |01|64x32|AB&br;AB| |10|32x64|AA&br;BB| |11|64x64|AB&br;CD| タイルマップアドレスの最初の 0x800 (2048) バイトはタイルマップAで、 次の 0x800 バイトが B、C、D というように続く。 Aのみが必要とされる場合、他の場所は空の領域とされる。 タイルマップのそれぞれの項目は 2 バイトで、次のようなフォーマットになっている。 |15|14|13|12|11|10|9|8|h |v|h|o|p|p|p|c|c| |7|6|5|4|3|2|1|0|h |c|c|c|c|c|c|c|c| -v/h : タイルの垂直/水平反転 -o : タイルの優先順位 -ppp : タイルのパレット パレットの色数は画面モードとBGに依存 -cccccccccc : タイル番号 タイルマップから特定タイルのワードアドレスを見つけるには (X と Y)、 次の式を使う。 (Addr<<9) + ((Y&0x1f)<<5) + (X&0x1f) + (SY ? ((Y&0x20)<<(SX ? 6 : 5)) : 0) + (SX ? ((X&0x20)<<5) : 0) タイルのキャラクタデータは [[0x210b ~ 0x210c>IO ポート (メイン)/0x210B]] で指定される場所から始まるアドレスに配置されている。 (Base<<13) + (TileNumber * 8*NumBitplanes) それぞれのタイルは通常 8x8 ピクセルのサイズで、ビットプレーンで保存される。 1行はそれぞれ 1 バイトで構成され、一番左端はビット 7 で指定する。 4 色のタイルでは、ビットプレーン 0 と 1 が 1 ワードの下位バイト、 上位バイトとして保存され、8 ワードで 1 つのタイルを構成する。 16 色タイルでは、4 色と同様に 0, 1 が保存され、それに 2, 3 が続くような 形式で保存される。 256 色タイルでは同じ方法で、2 つの 16 色タイルが続くような形式で保存される。 [[0x2105>IO ポート (メイン)/0x2105]] でキャラクタサイズが指定された場合、 16x16 ピクセルブロックのタイルとすることができ、1 つのタイルに タイル、タイル + 1、タイル + 16、タイル + 17 が使われる。 この場合、32x32 タイルマップで、通常の 256x256 ピクセルサイズではなく、 512x512 サイズが使われる。 同様に、64x64 タイルマップでは、BG は 1024x1024 ピクセルまで拡張される。 これらは 16x16 スプライトの時のようにラッピング処理がされることはなく、 Tile=0x2ff を指定した場合、0x2ff, 0x300, 0x30f, 0x310 を使うことになる。 もちろん、 0x3FF からは 0x000 に行く。 このモードで反転フラグをセットした場合、個々の 8x8 タイルではなく、 16x16 タイルが反転される。 ***BGスクロール [#n902fda8] BG モードとインターレス設定によるが、 モード 0 ~ 6 は 256x224 か 256x239 ピクセルの画面を表示する。 [[0x210d ~ 0x2114>IO ポート (メイン)/0x210D]] のスクロールレジスタで、 256x256 ~ 1024x1024 ピクセルの BG の表示領域を調節することができる。 BG を画面外に移動することはできず、 画面外に移動するような設定にした時は単純にラップされる。 (BG を 1024x1024 に設定した場合はどう考えてもできない) [[0x210d ~ 0x2114>IO ポート (メイン)/0x210D]] は全て 2 度書きレジスタで、16ビット値を設定する。 これらのレジスタへ値を書き込んだ場合、その値はバッファに保存される。 これらいずれかのレジスタに新しい値を書き込んだ場合、 現在のレジスタ値と、6バイトのいずれかのレジスタに対して 直前に書き込まれた 1 バイトの値が新しい値と合成されて書き込まれる。 BGnHOFS の場合 : (NewByte<<8) | (PrevByte&~7) | ((CurrentValue>>8)&7) BGnVOFS の場合 : (NewByte<<8) | PrevByte ほとんどの場合、この詳細は重要ではなく、普通に 1 つのレジスタに 2 度書き込めば 問題は起こらないのだが、いくつかのゲームで 1 度だけ書き込んだり、 他に変なことをしていることがある。 タイルマップエントリからスクリーン上の特定のX,Y座標を計算する時には 次の式を使う。 Size = 8 か 16。0x2105 で指定される TileX = (X + BGnHOFS) / Size TileY = (Y + BGnVOFS) / Size TileX と TileY の位置にあるタイルを検索する。詳細は以下 注 : 多くのゲームで垂直スクロール位置は 0 ではなく -1 に設定されている。 これは、SNES が OBJ データをスキャンライン毎に 1 つ前の位置を参照するためである。 1番最初の行では、OBJ データは何もロードされていない。 SNESは実際にはスキャンライン0に出力しない。 インターレス画面では、行 0 を無視するために -1 ではなく -2 を指定する必要がある。 (エミュレータでは1の代わりに2を足す必要があるだろう) ***ダイレクトカラーモード [#dc67e4d8] モード 3, 4, 7 の 256 色 BG では、[[0x2130>IO ポート (メイン)/0x2130]] のビット 0 に 1 が設定されている時、ダイレクトカラーモードが有効になる。 このモードでは、パレットの指定 ('ppp') が無視され、 キャラクタデータではパレットインデックスの代わりに BBGGGRRR で表される色を指定する。 3 ビットの ppp は bgr になり、色データの追加分として使われる。 -赤 (R) = RRRr0 -緑 (G) = GGGg0 -青 (B) = BBb00 ダイレクトカラーモードでは黒いピクセルを指定することはできない。 値が 0 のキャラクタデータは透明色として扱われる。 黒を表示するためには、黒に一番近い値を使うと良いだろう。 (01, 08, 09 辺りが良い) ***モード 0 [#mode0] それぞれ最大 4 色が出る 4 つの BG がある。 パレットエントリの開始位置は次の式で計算できる。 ppp * 4 + (BG# - 1) * 32 表示の優先順位は次の順 (前面から背面へ) -優先順位 3 のスプライト -優先順位 1 の BG1 -優先順位 1 の BG2 -優先順位 2 のスプライト -優先順位 0 の BG1 -優先順位 0 の BG2 -優先順位 1 のスプライト -優先順位 1 の BG3 -優先順位 1 の BG4 -優先順位 0 のスプライト -優先順位 0 の BG3 -優先順位 0 の BG4 ***モード 1 [#mode1] 16 色の BG が 2 面と、4 色の BG が 1 面ある。 パレットエントリの開始位置は次の式で計算できる。 ppp * ncolors [[0x2105>IO ポート (メイン)/0x2105]] のビット 3 の設定によって背景の優先順位は変化する。 表示の優先順位は次の順 (前面から背面へ) -優先順位 1 の BG3 ([[0x2105>IO ポート (メイン)/0x2105]] のビット 3 がセットされている時) -優先順位 3 のスプライト -優先順位 1 の BG1 -優先順位 1 の BG2 -優先順位 2 のスプライト -優先順位 0 の BG1 -優先順位 0 の BG2 -優先順位 1 のスプライト -優先順位 1 の BG3 ([[0x2105>IO ポート (メイン)/0x2105]] のビット 3 がクリアされている時) -優先順位 0 のスプライト -優先順位 0 の BG3 ***モード 2 [#mode2] 16 色の BG が 2 面ある。 パレットエントリの開始位置は次の式で計算できる。 ppp * 16 表示の優先順位は次の順 (前面から背面へ) -優先順位 3 のスプライト -優先順位 1 の BG1 -優先順位 2 のスプライト -優先順位 1 の BG2 -優先順位 1 のスプライト -優先順位 0 の BG1 -優先順位 0 のスプライト -優先順位 0 の BG2 モード 2 は、"タイル毎オフセット" を使う最初のモード。 このモードでは、BG3 のタイルデータはエンコードされていて、 BG1, BG2 の両方またはいずれかの、それぞれのタイルの (可能であれば) HOffset, VOffset の両方またはいずれかを 置き換える。 可視状態のスキャンラインについて考えると、 通常、次に示すような方法でピクセルを取得する。 HOFS = X + BGnHOFS VOFS = Y + BGnVOFS Pixel[X,Y] = GetPixel(GetTile(BGn, HOFS, VOFS), HOFS, VOFS) "タイル毎オフセット" の時は、もう少し複雑になる。 HOFS = X + BGnHOFS VOFS = Y + BGnVOFS ValidBit = BG1 の時 : 0x2000, BG2 の時 : 0x4000 if (!IsFirst8x8Tile(BGn, HOFS)) { /* この計算は正しいだろうと思うが... */ Hval = GetTile(BG3, (HOFS&7)|(((X-8)&~7)+(BG3HOFS&~7)), BG3VOFS) Vval = GetTile(BG3, (HOFS&7)|(((X-8)&~7)+(BG3HOFS&~7)), BG3VOFS + 8) if (Hval&ValidBit) HOFS = (HOFS&7) | ((X&~7) + (Hval&~7)) if (Vval&ValidBit) VOFS = Y + Vval } Pixel[X,Y] = GetPixel(Get8x8Tile(BGn, HOFS, VOFS), HOFS, VOFS) 言い換えれば、BGn の 0-32 の可視状態のタイルと、 BG3 の"可視" のタイルは同じになる。 BGn のタイル 0 のオフセットは普通で、 1 <= T < 33 の範囲にある BGn のタイル T はオフセットデータを BG3 の タイル T - 1 から取得する。 このとき、タイルが実際に配置されているかどうかは問題ではない。 可視の左端のタイルはいつでも通常で (最短、1 ピクセルが可視になるが、 クリップウインドウを使う時にまだ悩むことになるだろう)、 次のタイルは、BG3 の左端のタイルのが何になるかによって、タイルマップエントリを使う。 "新しい"オフセットは BGnVOFS レジスタをオーバーライドするが、 BGnHOFS オフセットの下位 3 ビットはまだ使われるだろう。 スクリーンの現在の Y 座標は BG3 のタイルマップの参照している どの行にも影響しない。Y 座標が常に 0 の時も 一方、たとえ BGn が 16x16 タイルでも、 BG3 は、それぞれ 8x8 サブタイルのオフセットを指定することができる。 BG3 が 16x16 の時、オフセットは関連する BGn の 8x8 サブタイルに適用される。 BG3 が 16x16 の時、Hval と Vval に同じタイルを最後まで使う。 ***モード 3 [#mode3] このモードは、256 色の BG と 16 色の BG がある。 パレットエントリの開始位置は次の式で計算できる。 BG1: 0 BG2: ppp*16 表示の優先順位は次の順 (前面から背面へ) -優先順位 3 のスプライト -優先順位 1 の BG1 -優先順位 2 のスプライト -優先順位 1 の BG2 -優先順位 1 のスプライト -優先順位 0 の BG1 -優先順位 0 のスプライト -優先順位 0 の BG2 注 : [[0x2130>IO ポート (メイン)/0x2130]] レジスタで、BG1 をダイレクトカラーモードに設定できる。 ***モード 4 [#mode4] このモードは、256 色の BG と 4 色の BG がある。 パレットエントリの開始位置は次の式で計算できる。 BG1: 0 BG2: ppp*4 表示の優先順位は次の順 (前面から背面へ) -優先順位 3 のスプライト -優先順位 1 の BG1 -優先順位 2 のスプライト -優先順位 1 の BG2 -優先順位 1 のスプライト -優先順位 0 の BG1 -優先順位 0 のスプライト -優先順位 0 の BG2 注 : [[0x2130>IO ポート (メイン)/0x2130]] レジスタで、BG1 をダイレクトカラーモードに設定できる。 モード 4 は、 "タイル毎オフセット" を使う、2 番目のモード。 モード 2 と同じように機能する。 しかし SNES には、2つのオフセット値をロードする時間がないので、 代わりに次のような処理を行う。 Val = GetTile(BG3, ...) if (Val&0x8000) { Hval = 0 Vval = Val } else { Hval = Val Vval = 0 } ***モード 5 [#mode5] このモードは、16 色の BG と 4 色の BG がある。 パレットエントリの開始位置は次の式で計算できる。 ppp * ncolors 表示の優先順位は次の順 (前面から背面へ) -優先順位 3 のスプライト -優先順位 1 の BG1 -優先順位 2 のスプライト -優先順位 1 の BG2 -優先順位 1 のスプライト -優先順位 0 の BG1 -優先順位 0 のスプライト -優先順位 0 の BG2 このモードは、これまでのモードと違う点が多々ある。 通常の 8/16 ピクセル幅のタイルを使う代わりに、 常に 16 ピクセル幅のタイルを使う (高さは 8 または 16 ピクセル)。 それから、ピクセル列の半分だけ使用する。 (0ベースで、偶数番号のピクセルはサブスクリーンに、 奇数番号のピクセルはメインスクリーンのタイルに使用される) そして、スクリーンを仮想的に 512 ピクセル幅で表示する。 同様に、インターレスモードが ON ([[0x2133>IO ポート (メイン)/0x2133]] 参照) の時、 224 か 239 の高さの代わりに、448 か 478 の高さを使う。 [[0x213F>IO ポート (メイン)/0x213F]] のビット 7 の指定で、偶数ラインと奇数ラインを交互に表示する。 注 : ここに書いたように表示するには、 [[0x212C と 0x212D>IO ポート (メイン)/0x212C]] で同じ値を指定しなければならない。 ***モード 6 [#mode6] このモードでは、16 色の BG のみを使う。 パレットエントリの開始位置は次の式で計算できる。 ppp * ncolors 表示の優先順位は次の順 (前面から背面へ) -優先順位 3 のスプライト -優先順位 1 の BG1 -優先順位 2 のスプライト -優先順位 1 のスプライト -優先順位 0 の BG1 -優先順位 0 のスプライト このモードは、モード 5 と同じように動作する。 また、 "タイル毎オフセット" の機能も追加される。 こちらはモード 2 のように動作する。 しかし、モード 6 では 8 ピクセル幅 (16 ハーフピクセル) のタイルが使用され、 BG3 も BG1 と同じようにこれが適応される。 8 ハーフピクセルにも 16 ピクセル幅の領域にも オフセットを適用することはできない。 (2 つの 8 ピクセル領域に 2 つのオフセット値を使う時は除く) ***モード 7 [#mode7] このモードは、他のモードと極端に違う。 256色のBGが1面あるが、タイルマップとキャラクタマップの 配置の仕方は全く異なる。 タイルマップとキャラクタマップは重なっており、 ***BGのレンダリング [#jc1c09b6] +水平・垂直オフセットを取得 (それぞれレジスタから取得するか、"タイル毎オフセット" により計算される) +これらの値をプレイ画面に変換する 注 : モード 7 ではこの工程がかなり複雑 +座標に合わせてタイルマップを取得する +タイルマップを使ってキャラクタデータを取得する +必要であれば、画像を非ビットプレーンに展開してバッファに格納する 詳細は[[画面のレンダリング>PPU/画面のレンダリング]]参照

表示オプション

横に並べて表示:
変化行の前後のみ表示: