サブページ
スプライトの概要
スプライトは、プレイフィールドの表示とは独立して画面上のどこにでも配置できるグラフィックオブジェクトである。各スプライトの幅は16ピクセルで、高さは表示ウィンドウの範囲内で自由に設定できる。通常、スプライトはプレイフィールドの手前に表示され、背後のグラフィックスを隠す。マウスポインタはその典型的な例である。
Amigaは8つのハードウェアスプライトチャンネル(SPR0〜SPR7)を提供する。各スプライトは透明色を含む4つの値のうち3色を表示できる。2つのスプライトをアタッチペアとして結合すると、透明色を含む最大15色を実現できる。
スプライトのカラー構成
スプライトの各ラインは2つの16ビットデータワードで構成され、2つのミニビットプレーンのように機能する。各ピクセルの色は、両ワードの対応するビットの組み合わせで決定される。
- 両ワードのビット15が最も左のピクセルの色を決定
- 両ワードのビット0が最も右のピクセルの色を決定
- 2ビットの組み合わせで4つの値を選択:
00=透明、01/10/11=3色
スプライトには専用のカラーレジスタがない。代わりに、カラーパレットの上位半分(レジスタ16〜31)を共有する。スプライトはペアでグループ化され、各ペアが3つの連続するカラーレジスタを使用する。
スプライトはパレットエントリ16〜31をプレイフィールドと共有するため、プレイフィールドが16色以上を使用する場合にカラーの競合が発生する。00の組み合わせは常に透明であり、スプライトの背後にあるものが透けて見える。
スプライトDMAとデータ構造
AmigaのスプライトプログラミングはDMAコントローラが大部分の処理を行うため、比較的容易である。スプライトを表示するには、Chip RAMにスプライトデータリストを準備し、対応するDMAチャンネルをそのアドレスに向ける。
8つのスプライトにはそれぞれ専用のDMAチャンネルがある。ただし、各チャンネルはラスタライン1本あたり2ワードしか読めない。これが、スプライトの幅が16ピクセルに制限され、4色までしか使えない根本的な理由である。毎ライン2ワードのデータが読み込まれるため、スプライトの高さは表示ウィンドウによってのみ制限される。
スプライトデータリストの形式
スプライトデータリストはワードペアの連続である。各ペアは2つのコントロールワード(位置定義)か、2つのデータワード(1ラインのピクセルデータ)のいずれかを含む。
DMAコントローラはまずコントロールワードを読み取り、SPRxPOSおよびSPRxCTLレジスタに格納し、ビームが開始ライン(VSTART)に到達するまで待機する。その後、各ラインで2つのデータワードを読み込み、DENISEが正しい水平位置に16ピクセルを表示する。終了ライン(VSTOP)に達すると、次の2ワードが新しいコントロールワードとして解釈される。両方ともゼロであれば、DMAチャンネルは次のフレームまでアイドル状態になる。
コントロールワードのレイアウト
水平・垂直の位置指定にはそれぞれ9ビットが使われる。垂直方向の解像度は1ラスタライン、水平方向の解像度はローレゾリューション1ピクセルで、プレイフィールドの解像度モードとは無関係である。
開始位置はスプライトの左上隅を定義する。VSTOPはスプライトの後の最初のライン(最終ライン+1)である。したがって、スプライトの高さはVSTOP - VSTARTラインとなる。
例:3色スプライト
Start:
dc.w $A05A,$A800 ; HSTART=$B4, VSTART=$A0, VSTOP=$A8
dc.w %0000000000000000,%0000001111000000 ; ライン1
dc.w %0000000000000000,%0000110000110000 ; ライン2
dc.w %0000000110000000,%0001100110011000 ; ライン3
dc.w %0000001111000000,%0011001001001100 ; ライン4
dc.w %0000001111000000,%0011001001001100 ; ライン5
dc.w %0000000110000000,%0001100110011000 ; ライン6
dc.w %0000000000000000,%0000110000110000 ; ライン7
dc.w %0000000000000000,%0000001111000000 ; ライン8
dc.w 0,0 ; スプライトデータ終端
アタッチスプライト(15色モード)
3色では不十分な場合、2つのスプライトをアタッチして15色+透明のスプライトを構成できる。各スプライトの2つのデータワードが結合され、ピクセルあたり4ビットの値となり、15のカラーレジスタを参照する(値0000は透明)。
アタッチを有効にするには、ペアの奇数番号のスプライトのSPRxCTLのATビット(ビット7)をセットする。例えば、スプライト1にATをセットすると、そのデータビットがスプライト0のデータビットと結合される。
4ビットカラー値のビット順序:
4つのスプライトペア(0&1、2&3、4&5、6&7)はすべてアタッチスプライトを形成でき、このモードではCOLOR16〜COLOR31を使用する。アタッチが正しく動作するには、2つのスプライトの位置コントロールワードが一致している必要がある。位置が一致しない場合、自動的に通常の3色モードに戻る。
1つのDMAチャンネルで複数のスプライト
スプライトの表示が完了すると、そのDMAチャンネルは再び空く。2つのゼロワードで終端する代わりに、データリストに新しいコントロールワードを記述して同じチャンネルで2つ目のスプライトを表示できる。
制限が1つある:DMAチャンネルは新しいコントロールワードを読み込むために1ライン分の空白が必要である。最初のスプライトの最終ラインがラスタライン163の場合、コントロールワードはライン164で読み込まれ、2番目のスプライトはライン165から開始する。
この技法により、DMAチャンネルを多重化してフレームあたり8つ以上のスプライトを表示できる。ただし、同じチャンネルを共有するスプライトが垂直方向に重ならないこと(1ラインの間隔を含む)が条件となる。
スプライトレジスタ
各スプライトチャンネルにはポインタレジスタペアと4つの制御/データレジスタがある。ポインタレジスタはDMAの初期化に使用され、制御・データレジスタは表示中にDMAコントローラによって自動的に書き込まれる。
DMAコントローラはこれらをスプライトデータリストへのランニングポインタとして使用する。リスト全体の処理が終わると、ポインタは末尾を超えた位置に進んでいる。次のフレームで同じスプライトを再表示するには、垂直帰線期間中にポインタを再ロードする必要がある。これは通常Copperが行う。
; Copperリスト:毎フレームのスプライトポインタ再ロード
MOVE #StartSprite0H,SPR0PTH
MOVE #StartSprite0L,SPR0PTL
MOVE #StartSprite1H,SPR1PTH
MOVE #StartSprite1L,SPR1PTL
; ... 全8チャンネル分繰り返す ...
WAIT $FFFE ; Copperリスト終端
SPRxCTLに値が書き込まれると(DMAまたは68000によって)、DENISEはそのスプライトの出力をビームがVSTARTに到達するまで無効にする。SPRxDATAへの書き込みでスプライト出力が再有効化される。
各スプライトDMAチャンネルの個別有効/無効制御は存在しない。DMAコンのSPRENビット(ビット5)が全8チャンネルを同時に有効化する。
MOVE.W #$8220,$DFF096 ; DMAコンでSPREN + DMAENをセット
使用しないスプライトチャンネルも初期化が必要で、SPRxPTを2つのゼロワードを含むメモリ位置に向ける。
スプライト・プレイフィールド優先度
スプライトとプレイフィールドが重なった場合、優先度システムがどの要素を手前に表示するかを決定する。スプライト同士では番号が優先度を決め、スプライト0が最高優先度を持つ。
スプライト対プレイフィールドの優先度では、スプライトはペアでグループ化される:0&1、2&3、4&5、6&7。プレイフィールドはこれら4ペアの間の任意の位置に挿入でき、各プレイフィールドに5つの優先度位置がある。
これはBPLCON2レジスタ($DFF104、ライトオンリー)で制御される。
デュアルプレイフィールドモードでは、各プレイフィールドをスプライトペア間に独立して配置できる。PF2PRIビットがどちらのプレイフィールドを手前にするかを制御し、プレイフィールド間の優先度はスプライト・プレイフィールド間の優先度に優先する。シングルプレイフィールドモードではPF1Pxのみが有効で、PF2PRIとPF2Pxは効果がない。
衝突検出
Amigaハードウェアは、スプライト同士やスプライトとプレイフィールド間の衝突を自動的に検出できる。衝突は、2つの要素の不透明ピクセルが同じ画面位置で重なったときに発生する。
CLXDAT — 衝突データレジスタ($DFF00E、リードオンリー)
CLXCON — 衝突制御レジスタ($DFF098、ライトオンリー)
CLXCONレジスタは衝突検出に参加する要素を制御する。ENSPxビットは奇数番号スプライトの衝突テストを有効にする(偶数番号スプライトは常に参加)。ENBPx/MVBPxビットはプレイフィールド衝突をトリガーするビットプレーンカラーの組み合わせを選択する。
ENBPxビットがセットされると、対応するビットプレーンのピクセル値がMVBPxビットと一致する必要がある。ENBPxがクリアの場合、そのビットプレーンは比較から除外される(任意の値で一致)。すべてのENBPxを0にすると、プレイフィールドのすべてのピクセルが衝突をトリガーできる。