7 つの画面モードと、主に 2 つの状態変化がある。 画面モードは、0x2105 のビット 0 ~ 2 で設定できる。 モード 1 の状態変化は 0x2105 のビット 3 で設定でき、 モード 7 の状態変化は 0x2133 のビット 6 で設定できる。
モード | BGの色数 | |||
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 は透明色に設定されている。
それぞれのBGはVRAMの2つの領域が関係している。 1つはタイルマップ、もう1つはキャラクタデータに使用される。
タイルマップアドレスはは 0x2107 ~ 0x210a のビット 2 ~ 7 で選択する。 タイルマップのサイズは同じレジスタのビット 0 ~ 1 で選択する。 全てのタイルマップは 32x32 だが、ビット 0 ~ 1 は メモリ上でどのようにレイアウトされるかを指定する。
値 | サイズ | 内容 |
00 | 32x32 |
AA AA |
01 | 64x32 |
AB AB |
10 | 32x64 |
AA BB |
11 | 64x64 |
AB CD |
タイルマップアドレスの最初の 0x800 (2048) バイトはタイルマップAで、 次の 0x800 バイトが B、C、D というように続く。 Aのみが必要とされる場合、他の場所は空の領域とされる。
タイルマップのそれぞれの項目は 2 バイトで、次のようなフォーマットになっている。
15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 |
v | h | o | p | p | p | c | c |
7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
c | c | c | c | c | c | c | c |
タイルマップから特定タイルのワードアドレスを見つけるには (X と Y)、 次の式を使う。
(Addr<<9) + ((Y&0x1f)<<5) + (X&0x1f) + (SY ? ((Y&0x20)<<(SX ? 6 : 5)) : 0) + (SX ? ((X&0x20)<<5) : 0)
タイルのキャラクタデータは 0x210b ~ 0x210c で指定される場所から始まるアドレスに配置されている。
(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 でキャラクタサイズが指定された場合、 16x16 ピクセルブロックのタイルとすることができ、1 つのタイルに タイル、タイル + 1、タイル + 16、タイル + 17 が使われる。 この場合、32x32 タイルマップで、通常の 256x256 ピクセルサイズではなく、 512x512 サイズが使われる。 同様に、64x64 タイルマップでは、BG は 1024x1024 ピクセルまで拡張される。 これらは 16x16 スプライトの時のようにラッピング処理がされることはなく、 Tile=0x2ff を指定した場合、0x2ff, 0x300, 0x30f, 0x310 を使うことになる。 もちろん、 0x3FF からは 0x000 に行く。 このモードで反転フラグをセットした場合、個々の 8x8 タイルではなく、 16x16 タイルが反転される。
BG モードとインターレス設定によるが、 モード 0 ~ 6 は 256x224 か 256x239 ピクセルの画面を表示する。 0x210d ~ 0x2114 のスクロールレジスタで、 256x256 ~ 1024x1024 ピクセルの BG の表示領域を調節することができる。
BG を画面外に移動することはできず、 画面外に移動するような設定にした時は単純にラップされる。 (BG を 1024x1024 に設定した場合はどう考えてもできない)
0x210d ~ 0x2114 は全て 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を足す必要があるだろう)
モード 3, 4, 7 の 256 色 BG では、0x2130 のビット 0 に 1 が設定されている時、ダイレクトカラーモードが有効になる。 このモードでは、パレットの指定 ('ppp') が無視され、 キャラクタデータではパレットインデックスの代わりに BBGGGRRR で表される色を指定する。 3 ビットの ppp は bgr になり、色データの追加分として使われる。
ダイレクトカラーモードでは黒いピクセルを指定することはできない。 値が 0 のキャラクタデータは透明色として扱われる。 黒を表示するためには、黒に一番近い値を使うと良いだろう。 (01, 08, 09 辺りが良い)
それぞれ最大 4 色が出る 4 つの BG がある。 パレットエントリの開始位置は次の式で計算できる。
ppp * 4 + (BG# - 1) * 32
表示の優先順位は次の順 (前面から背面へ)
16 色の BG が 2 面と、4 色の BG が 1 面ある。 パレットエントリの開始位置は次の式で計算できる。
ppp * ncolors
0x2105 のビット 3 の設定によって背景の優先順位は変化する。 表示の優先順位は次の順 (前面から背面へ)
16 色の BG が 2 面ある。 パレットエントリの開始位置は次の式で計算できる。
ppp * 16
表示の優先順位は次の順 (前面から背面へ)
モード 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 に同じタイルを最後まで使う。
このモードは、256 色の BG と 16 色の BG がある。 パレットエントリの開始位置は次の式で計算できる。
BG1: 0 BG2: ppp*16
表示の優先順位は次の順 (前面から背面へ)
注 : 0x2130 レジスタで、BG1 をダイレクトカラーモードに設定できる。
このモードは、256 色の BG と 4 色の BG がある。 パレットエントリの開始位置は次の式で計算できる。
BG1: 0 BG2: ppp*4
表示の優先順位は次の順 (前面から背面へ)
注 : 0x2130 レジスタで、BG1 をダイレクトカラーモードに設定できる。
モード 4 は、 "タイル毎オフセット" を使う、2 番目のモード。 モード 2 と同じように機能する。 しかし SNES には、2つのオフセット値をロードする時間がないので、 代わりに次のような処理を行う。
Val = GetTile(BG3, ...) if (Val&0x8000) { Hval = 0 Vval = Val } else { Hval = Val Vval = 0 }
このモードは、16 色の BG と 4 色の BG がある。 パレットエントリの開始位置は次の式で計算できる。
ppp * ncolors
表示の優先順位は次の順 (前面から背面へ)
このモードは、これまでのモードと違う点が多々ある。 通常の 8/16 ピクセル幅のタイルを使う代わりに、 常に 16 ピクセル幅のタイルを使う (高さは 8 または 16 ピクセル)。 それから、ピクセル列の半分だけ使用する。 (0ベースで、偶数番号のピクセルはサブスクリーンに、 奇数番号のピクセルはメインスクリーンのタイルに使用される) そして、スクリーンを仮想的に 512 ピクセル幅で表示する。 同様に、インターレスモードが ON (0x2133 参照) の時、 224 か 239 の高さの代わりに、448 か 478 の高さを使う。 0x213F のビット 7 の指定で、偶数ラインと奇数ラインを交互に表示する。 注 : ここに書いたように表示するには、 0x212C と 0x212D で同じ値を指定しなければならない。
このモードでは、16 色の BG のみを使う。 パレットエントリの開始位置は次の式で計算できる。
ppp * ncolors
表示の優先順位は次の順 (前面から背面へ)
このモードは、モード 5 と同じように動作する。 また、 "タイル毎オフセット" の機能も追加される。 こちらはモード 2 のように動作する。 しかし、モード 6 では 8 ピクセル幅 (16 ハーフピクセル) のタイルが使用され、 BG3 も BG1 と同じようにこれが適応される。 8 ハーフピクセルにも 16 ピクセル幅の領域にも オフセットを適用することはできない。 (2 つの 8 ピクセル領域に 2 つのオフセット値を使う時は除く)
このモードは、他のモードと極端に違う。 256色のBGが1面あるが、タイルマップとキャラクタマップの 配置の仕方は全く異なる。
タイルマップとキャラクタマップは重なっており、
詳細は画面のレンダリング参照