スプライトローテーションという技術
正しい呼び方があったわけでもないけれど、少なくとも僕はスプライトローテーションと呼んでいた技術について、ちょっと残しておこうというのが、今回のネタ。
おっそろしく古臭いハードの、おっそろしく古臭い技術で、残しておいたから「どうだ」ということでも全くないが、まあ後世のエミュレータを調べた人たちが「なんでこんなワケのわからんことをしていたんだ?」という疑問からは脱出することが出来るだろう。
めんどくさいので、以下の簡単な前提。
スプライトは、1980年代前半~1990年代半ばまでゲームで幅広く中心的に使われたグラフィックのハードウェア(および一部ソフトウェア)技術。
だいたい8x8~64x64ドットの矩形で、画面の座標を指定したら、速攻その場所に異動して、背景画面を壊さなくて、書き換え負荷がない神様みたいなモノ。透明色があったので、背景との重ね合わせも超カンタンである。ちなみにスプライトの指定座標は画面より大きいことが多く、画面外から出し入れするのも難しくなかった。
初期段階からスプライト単位での上下・左右反転ぐらいは出来て、後期は回転・拡大・縮小が出来るのも当たり前になったのだけど、回転・拡大・縮小が出来るようになったのは、アーケードでも80年代後半~90年代で、家庭用ゲームマシンではPS/サターン世代までは実質的に登場しなかった。
ファミコンだのPCエンジンだのメガドラだのSFCあたりの世代のマシンでは、敵だの弾だのマイキャラだのといった画面の上で自由に動くものにともかく使われていた。
ついでに書くと3DO・PS1・サターン世代はフレームバッファ形式なので、今回書くラインバッファ方式のスプライトとは全く制限が違う。
余談ついでに書くとセガのバーチャファイター1とかサターンあたりのハードやFM-TOWNSあたりのポリゴンともスプライトとも言えない過渡期のハードでは、変形可能な(雑には4点が指定され、矩形の必要がないということ)4頂点 指定のスプライト(四角ポリゴン)だったりする。三角形と比較して、扱いやすいところと扱いにくいところがあるのだけど、全体としてはメリットよりデメリットのほうが大きいので主流にならなかった。
(三角形は2枚を組み合わせると四角に出来るが四角形を三角にすることが出来ないとか、四角形だとねじれる問題が発生するなんてあたりが結構決定的な要因のひとつ)
このスプライト、とても便利なものだけど古のハードではひとつ大きな制約があった。
それは1ライン(ラスタ)の上に一定数以上の数が並ばないこと。一定数以上並ぶと、後ろの方のスプライトは消えてしまうのだ。
原理を説明するのはとてもめんどくさいのでパス。これの説明を始めると、本当にテレビの原理から説明しないといかんので、めっちゃめんどくさいのだ。
ともかく、1ライン上の数が一定数を超えると消えるのは問題はとても大きな問題だ。シューティングなら見えない弾に当たって死んだり、マイキャラの撃った弾が消えたりと、ゲームに致命的な影響が出るので、ともかく困ってしまう。
そこで使われていたのがスプライトローテーション。
これが一番最初にどこで使われたのかはわからないが、プログラムとしてどういう風に組んでいるのかを初めて見たのはSORD のM5の”Galax”というギャラガの移植バージョンだった。出来があまりにいいのに感動してROMの中身をディスアセンブルして解析したら、そのコードに当たって最初は理解できなかったのだけど、理解できたときにマジで感動した。ところで、この移植は僕は当時ナムコ内部で行われたと想像している。なんせ出来がスゴすぎる。
ついでに書くと、ファミコンの最初期は「スプライトローテーション」は一般化しておらず、平気でスプライトは消えるものだった。なんせ任天堂のファミコン初期のソフトからして思い切りスプライトが消えるものがあるぐらいだ。
またSORD M5(タカラのゲームパソコン)は1982年発売でファミコンより古い。確か発売直後にこの技術を見た記憶があるので82年にはナムコ周辺にはあった技術ということになる
では、スプライトローテーションは、どういうふうにやるのか?
仮想のダメダメファミリーコンピュータ、略してダメコンってのがあったとしよう。
このダメコンは最大4つのスプライトが出せて、そして3つ以上が同じラインに並ぶと消えるとする。
次ににダメコンはスプライトを表示するためには当然スプライトの位置を指定する画面座標が必要だ。3DじゃないのでX,Y。
もちろんスプライトは絵(今風に書くならテクスチャだ)なので、どの絵を表示するかを指定するなにかも必要だ。ここでは絵のそれぞれに番号が0からついていることにしよう。つまり絵の番号を指定すれば、その絵が選ばれる、ということだ。
ということで、一個のスプライトを表示するには(画面座標、スプライト番号)の2つが必要なことになる。
次にこれを表示するためのスプライトバッファというメモリを用意しなければならないとする。
これは上の一個のスプライトを表示するために必要なデータがズラズラと並んでいる場所だ。
具体的には
0番スプライト(座標、絵の番号)
1番スプライト(座標、絵の番号)
2番スプライト(座標、絵の番号)
3番スプライト(座標、絵の番号)
なんて具合になっているとする。
そしてVsync(垂直同期期間)毎に、このバッファの先頭アドレスをDMAに渡したり、それともVDPのレジスタに書き込んだり…ともかく、スプライトを表示する要求をビデオプロセッサに対して行って、秒60回、スプライトを表示するとしよう。
実在のハードでも、たいていこのバッファと表示をするための命令は必要だったけれど、仕様はずいぶんハードによって違って、かなりソフトウェア的なものもあれば、かなりハードウェア的なものもあった。で、このバッファを複数用意して、水平同期のタイミングで切り替えスプライト表示量を増やすとか、そういうムチャな方法もあった。
ここでもう一つのルールを説明すると、3つ目のスプライトが同じ座標に並ぶと消えるわけだけど、この3つめは、スプライトバッファ上の後ろのモノ。例えば0と1と2が同じ座標に並ぶと必ず2が消える。1と2と3なら3が消える。
この消えるルールも不正確な表現で、同一水平ラインに重なっている部分が描画されないが、当時のハードではより正しいが、そこらへんの乱暴な説明は許していただきたい。
と、一通りのルールを説明した所で、具体的な状況として、0番にAの絵、1番にBの絵、2番にCの絵、3番にDの絵が割り振られている状況を考える。そして0-1-2が同じ水平座標に置かれているとすると、下図のように2番のCが表示されない状態になる。表示されないのはマズい。
ここで登場するのがスプライトローテーションだ。
1フレーム(1/60秒)後、下の図のように風にスプライトの表示順をいじるとしてみよう。
アラ不思議。Aが非表示になり、Cが表示される。
こんな風に入れ替えを繰り返してみよう。
スプライトは下の図のようにAとCは1/30秒毎に表示される。
…つまりチラチラしながらも消えることはなく表示される。
スバラシイ。
かくして全スプライトが表示されることになった。
これがスプライトローテーションと呼ばれる技術の基礎(ちなみに図がちょっとわかりにくくなるのでローテーションの仕方にはウソがある)。
ここからいろいろ拡張したり修正したりして、自機と飾り枠だのマスクだのはチラつかせないなんて技術や、ローテーションの仕方の工夫などもあるのだけど、そういうのはまた気が向いたら紹介したい。
ところで、最初に書いたとおり、これを初めて見たのはSORD のM5(タカラのゲームパソコン)だったのだけど、そのカタログが下。
このパソコンにはBASIC-Gというゲーム用命令が多数用意されたBASICがあったのだけど、これを作ったのが当時大阪のマイコングループNEW ONにいたプログラマ(名前は失念)。驚異的な高速化が施されたプログラムで、当時のベンチマークで並みいる高級ハードウェアをなぎ倒して、最速を誇っていた。
ところが本人は、京都寺町の喫茶店で「最初のバージョンは未定義命令もフルに使ってて、もっと速かったんだよ! SORDが使うなってから、仕方なく使わないようにしたら遅くなっちゃってさ…未定義命令使わせてくれれば、もっと速かったのに!」って怒ってたりした。
未定義命令が何なのかは、面倒だから説明しないけど、当時のZ80のマニアはそれを使うのは結構当たり前だったので、それを使えないって遅いだろ! とか、僕も一緒になって怒っていた。
なにもかもが古い、30年以上前の昔の話と技術だ。
6件のコメント
コメントは現在停止中です。
AGENT: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:41.0) Gecko/20100101 Firefox/41.0
>(スプライト単位での?)回転・拡大・縮小が出来るようになったのは、アーケードでも80年代後半~90年代で、家庭用ゲームマシンではPS/サターン世代までは実質的に登場しなかった
とのことですが、ではSFCのウリの一つだった回転・拡大・縮小はまた別のものなんでしょうか?
AGENT: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36
SFCで回転・拡大・縮小が可能なのは、mode 7を選択している時の『背景画面』で、スプライトは出来ないのです。
AGENT: Mozilla/5.0 (Windows NT 6.1; rv:41.0) Gecko/20100101 Firefox/41.0
はじめまして。
ファミコン版沙羅曼蛇やグラディウスIIのレーザーやフォースフィールドのような、
肉眼では分からないような点滅も、この技術なのでしょうか?
スプライトがたくさん並んだ時のチラつき、とは違うように見えるので気になっていました。
AGENT: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36
記憶でしゃべると勘違いしてる可能性あると思って確認したんですが、グラⅡのレーザーは多分ローテーションではなく、それの変形の技術(並べると消える問題をできるだけ回避する他の技術)とローテーションの組み合わせですね。
AGENT: Mozilla/5.0 (Windows NT 6.1; rv:41.0) Gecko/20100101 Firefox/41.0
確認のうえご回答いただいてありがとうございます。
興味はあっても、きちんと理解できるだけの知識がないので、
こういったほどよく噛み砕いて説明されている記事は
大変ありがたく、楽しく読ませていただいております。
AGENT: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:41.0) Gecko/20100101 Firefox/41.0
>スプライトは出来ないのです。
ありがとうございます。なるほど、そうだったんですね。
そういえばF-ZEROをはじめ、背景がぐるぐる回るのは当然でしたが
自キャラなどが回ってるシーンはなかった気がします。