上に戻る
jsr $0005;スクロール制御を弄る
概要
 「部屋」単位で区切られ、スクロール方向が決まっていたファミコンのロックマン。エックスシリーズではそうではなく、巨大な一つのマップをスクロール制御することでボス部屋までを円滑に進行させています。
 これまでの記事からも分かるように、画面外のページは大抵ブランクとなっており、そういった「まずい」部分を見せないようにスクロール制御を行う必要があります。いったいどうすれば適切なスクロール制御が出来るでしょうか。
やはりオブジェクト
 前回のグラフィック転送と同様に、スクロールを制御するオブジェクトが存在しており、そのオブジェクトがスクロール領域を制御することで、今回のテーマであるスクロール制御が行われています。
 今回は、ObH(コンダクター)の、種類00を利用します。ObHのトップバッターです。そのくらい重要な制御といえるのでしょう。今回はこのオブジェクトの使い方についての記事という事になります。記事中で、種類00のObHのことを、ObH<00>と表記することにします。(以前からこう表記しておけばよかったのに)
 尚、シャッターに入ったときにもスクロール制御が行われるはずですが……調べていないので……その辺の話は今回は触れません。
スクロール限界
 ゲーム中、上下左右にどこまでスクロールできるかという、限界を示す値があります。それを、スクロール限界と呼ぶことにします。スクロール限界は上下左右に存在します。よーするに、でっかい矩形の中を、画面の矩形がフリースクロールするわけです。
 ObH<00>により、このスクロール限界の左右上下が適当に操作されることにより、円滑なゲーム進行が可能になっています。
 ちなみに、画面端がスクロール限界より外側にあったときは、じわじわと(割と遅い速さで)スクロール限界に向かって移動するようです。(イレギュラーハンター本部ステージの入り口や、マックの場所のように)

捕捉範囲
 通常のオブジェクトは、その中心の座標を1点記憶しておくのですが、ObH<00>は巨大なマップを切り取るように、左・右・上・下の位置を記憶し、利用します。Cls関数に渡す(x0,y0)-(x1,y1)みたいなもんです。ある意味では、ぶっといオブジェクトが存在しているとみることができるでしょうか。
 この矩形領域を、捕捉範囲と呼ぶことにします。ObH<00>が出現すると、その引数とステージ番号より、適当な捕捉範囲がセットされ、監視を開始します。捕捉範囲にエックスが進入したときに、スクロール限界をセットすることにより、スクロール制御が行われます。また、捕捉範囲が、画面から完全に外れると、そのObH<00>は消滅します。
エックスが
捕捉範囲(A)に入った時に横スクロール、
捕捉範囲(B)に入った時に縦スクロール
になるように、スクロール限界をセットする。
どこを書き換える?
 アドレス03DE43に、ステージ毎の16bitアドレスがあります。そのアドレスが指す先はまた16bitアドレスで、今度はObH<00>の引数毎のアドレスがあります。引数だけでなく、ステージ番号にも依存しているという点に気をつけてください。(この留意事項は1回前で書いておくべきだったが……)
 もう一度アドレスをたどると、なにやらデータに当たります。このデータを、スクロール構造体と呼ぶことにします。この、スクロール構造体が、捕捉範囲と、捕捉時のスクロール限界の値を決めます。
スクロール構造体
 スクロール構造体は、最低9バイトの可変長です。実際はAバイト以上ないと意味がありません。データ先頭から[0],[1]……としたとき
 [0][1]捕捉範囲の右(Xhi,Xhe)
 [2][3]捕捉範囲の左
 [4][5]捕捉範囲の下
 [6][7]捕捉範囲の上
 [8-]書込番号
 [最後]00終端
 となっています。[0]から[7]までは説明不要でしょう。
 [8]以降が可変長のデータであり、00で終端させます。非00のときに、その値に対応したある値が、上下左右のいずれかのスクロール限界に書き込まれます。
 値が複数あるときは、同じ処理を値の数だけ行います。つまり、上下左右の限界を全てセットしたいときは、[8][9][A][B]に適当な値をセットし、[0C]を00として終端させます。
 例として、値01が書込番号として指定されたときは、エックスが捕捉されると、スクロール限界の上が0200になります。
スクロール構造体の書込番号毎の書き込み値
 ここがかなりの曲者です。8bitの値に対応するデータを書き込むわけですが、具体的に言うと、アドレス(03F2CC+(書込番号-1)*4)にある4バイトのデータを先頭から[0],[1]……としたときに、[0][1]があらわすアドレス(バンクは03)に、16bit値[2][3]を書き込みます。
 例えば、その4バイトが
11 12 13 14
 なら、アドレス031211に1413を書き込む事になります。
 バンク03の0000-1FFFはLow RAMのミラーリングなので、7E1211に書き込まれるのと等価です。スクロール限界をセットすると言って来ましたが、実はスクロール限界ではない値に書き込むことも可能のようです。実際には書き込み先のデータは4通りしかなく、つまり、スクロール限界の上下左右となっています。
 困ったことに、この書込番号は、全ステージで共通です。ですので、このあたりを不用意に弄るわけにはいかないという苦しい状態に陥ります。
どうするかねぇ……
 自由にマップを構成する上で、スクロール制御を弄ることは必須となるはずなのですが、いかんせん弄りづらいです。
 エディタを充実させれば、スクロール構造体自体を弄ることは可能になると思うのですが、その書込番号毎のデータが全ステージで共有されているので、弄りたくありません。
 一応、書込番号は、デフォルトであるもののみから選択して利用すればどうにかなるかもしれません。しかし、自由とはいえないな……(一応、データを見る限り、端数が出ない値(ページ単位のスクロール位置)はある程度網羅されている様に思えます。)
 バイナリエディタでやる場合は、最悪、全てフリースクロールするような設定にしてしまえば、一応ゲームとしては成り立つかもしれません。操作性が非常に悪くなるでしょうが……

 結局のところ、うまーくプログラムを弄って(追加して)、汎用性が高くなるように拡張する必要があるかもしれません。何とかして、スクロール構造体自体に書き込み場所と値を含めるように改造できないかなぁ……
サンプルとこれから
 イレギュラーハンター本部ステージの、本部入り口でちょっと上にもスクロールできるようにしただけの例。(スクロール制御の改造は1バイトです)
es5_a10.ips.png
(※右クリックで保存した後.ips.png->.ipsとリネームしてipsにしてください)
 現状は、ページ配置が弄れないので、普段いけない場所にスクロールするようにしても延々と同じパターンしか利用できません。当然ですが、このページ配置を弄れないとお話になりませんね……その辺を次回にやれればと思っております。
(201)2011年11月13日 プレさ兵衛
inserted by FC2 system