([ゼビウス] AC版ゼビウスに総攻撃がプログラムされていた (4) からのつづき)
今回はロマン溢れる記事から一転、現実解的な内容になりますので、よろしくお願いします。インパクトある物量攻撃が起こる原因について少し見て行きたいと思います。
複合攻撃の仕組み
空中物が出現するとワークメモリに、出現機数とキャラクタ出現テーブルの位置がロードされます。例えば弾なしトーロイドを3機出現させる場合「0x03 0x01」になります。同時出現は6機までなので、1バイト目は 0x01~0x06 の範囲、2バイト目は 0x01~0x73 くらいの値を取ります。
キャラクタ出現テーブルは表のように定義されており、先の例だと1番目から6機分を出現させる指定になります。複合攻撃にしたい場合は、キャラクタの切り替わる境界を使うことで実現しています。例えば、弾なしトーロイド×3+弾ありトーロイド×3を出したい場合「0x06 0x04」と指定すれば良いことになります。
おなじみの、ジアラ×2+タルケン×3~4の組み合わせもジアラとタルケンが切り替わる境界のところで、「0x05 0x17」か「0x06 0x17」と指定します。機数の違いのみでタルケンを3機にしたり4機にしたりできる、とても巧妙な作りです。
| +0 | +1 | +2 | +3 | +4 | +5 | |
|---|---|---|---|---|---|---|
| 0x01 | トーロイド(弾なし) | トーロイド(弾なし) | トーロイド(弾なし) | トーロイド(弾なし) | トーロイド(弾なし) | トーロイド(弾なし) |
| 0x07 | トーロイド(弾あり) | トーロイド(弾あり) | トーロイド(弾あり) | トーロイド(弾あり) | トーロイド(弾あり) | トーロイド(弾あり) |
| 0x0D | ジアラ(弾あり) | ジアラ(弾あり) | ジアラ(弾あり) | ジアラ(弾あり) | ジアラ(弾あり) | ジアラ(弾あり) |
| 0x13 | ジアラ(弾なし) | ジアラ(弾なし) | ジアラ(弾なし) | ジアラ(弾なし) | ジアラ(弾なし) | ジアラ(弾なし) |
| 0x19 | タルケン | タルケン | タルケン | タルケン | タルケン | タルケン |
総攻撃はバッファオーバーランか
出現テーブルに従って機数分の空中物ワークへキャラクタが転送されると、キャラクタに対応するプログラムが紐づいて攻撃が始まります。また同様に、地上物は地上物用ワーク、バキュラはバキュラ用ワークを持っていて、出現テーブルに従ってセットされたりクリアされたりしながらエリアが進行していきます。
これらのワークはメモリ上で隣接しているため、例えばボザログラム(ワークを5個使用する)を11番目以降(地上物のワークは14個まで)に設定してしまうとバキュラ用ワークにはみ出します。それぞれのワーク領域では、自機に当たる・当たらない、ザッパーに当たる・当たらない、ブラスターに当たる・当たらない、の属性になっているので、このボザログラムはバキュラバリアを装備し、かつ自機との当たり判定も持つことになります。
ここで面白いのは、本来とは異なるワーク領域へキャラクタをロードさせてもそのキャラクタのプログラム(動き)はそのままな点です。左記のボザログラムはスクロールに同期して移動し、見た目上は地上物としてふるまいます。
総攻撃に話を戻しましょう。今までの前置きを踏まえると「空中物のワーク領域からオーバーランさせて、地上物やバキュラのワーク領域にロードさせた状態なのでは無いのか」という話が見えてきます。
実際に検証してみます
1番目のトーロイドを起点に実際にオーバーランさせて検証してみたいと思います。敵出現テーブルのメモリにブレークポイント入れて、読みだされた後の動きを追ってみると、XVI5 の 0x04D8~0x054B あたりまでが空中物の組み合わせを定義しているテーブルと分かりました(複合攻撃のところで書いた2バイト単位が羅列されています)。
このテーブルの機数のところを書き換えてオーバーランを起こさせます。しかし、適当に数を増やしてみても6機以上は出て来ず、極端に増やすとリセットが掛かりました。見当が外れたのかと思いましたが、71機以上設定すると地上物のワークを使い始めると判明。トーロイド起点だとカピ(71機目)からブラグザカート(87機目)までが地上物扱いになりました。
これ以降109機くらいまではバキュラのワークに配置され、バキュラバリアが付いた状態になります。
更に増やすとスパリオのワークに行くらしく、幻影弾が出るようになります。これ以上増やすとキャラクタのテーブルも終わるため、リセットや halt してしまいます。
0xA2、0xB2、0xA3 では何が起きているか
理由は分かりませんが上のキャラテーブルの続きではなく、XVI5 の 0x03D8~0x04D7 を参照していました。実は 0x80 以降の攻撃パターンは、0xE1 のジアラ+ギドスパリオぐらいしか使用されておらず、なぜこうなっているのか良くわかっていません。キャラテーブルに空きもあるし入れられると思うですけどね、謎です。
それぞれの参照先で何が定義されているか調べてみると下記の通りでした。
| 攻撃コード | 参照先(XVI5) | 定義(機数・起点キャラ) |
|---|---|---|
| 0xA2 | 0x041C | 0xA7 0xED |
| 0xB2 | 0x043C | 0xC1 0xC9 |
| 0xA3 | 0x041E | 0x52 0x19 |
うーむ。上2つは想像してたのとぜんぜん違いますね。これだとリセットコースなんですが、さっき書き換えてテストしていた部分に入れてみると A2, B2 と同じ攻撃が出て来ました。この A2 の定義だと範囲外のキャラを167機出現させるという指定であり、リセットが掛かってもおかしくありません。これでよく動いてるな、というのが心証です。
残りの A3 については、25番目(0x19)のタルケンを指定して82機出現させると言った意味になります。関連するキャラテーブルを書き出すと下記の通り。
| +0 | +1 | +2 | +3 | +4 | +5 | |
|---|---|---|---|---|---|---|
| 0x19 | タルケン | タルケン | タルケン | タルケン | タルケン | タルケン |
| 0x1F | ゾシー(乱) | ゾシー(乱) | ゾシー(乱) | ゾシー(乱) | ゾシー(乱) | ゾシー(乱) |
| 0x25 | トーロイド(弾) | トーロイド(弾) | ギドスパリオ | ギドスパリオ | ギドスパリオ | ギドスパリオ |
| 0x2B | ギドスパリオ | ギドスパリオ | ゾシー(追撃) | ゾシー(追撃) | ゾシー(追撃) | ゾシー(追撃) |
| 0x31 | ゾシー(追撃) | バックゾシー | バックゾシー | バックゾシー | バックゾシー | ザカート(落下) |
| 0x37 | ザカート(落下) | ザカート(落下) | ザカート(落下) | ザカート(落下) | ザカート(落下) | ザカート(自狙) |
| 0x3D | ザカート(自狙) | ザカート(自狙) | ザカート(自狙) | ザカート(自狙) | ザカート(自狙) | バックゾシー |
| 0x43 | バックゾシー | バックゾシー | カピ | カピ | カピ | カピ |
| 0x49 | カピ | カピ | ザカート(自狙) | ザカート(自狙) | ザカート(自狙) | テラジ |
| 0x4F | テラジ | テラジ | テラジ | テラジ | テラジ | ブラグザカート(自狙) |
| 0x55 | ブラグザカート(自狙) | ブラグザカート(自狙) | ブラグザカート(自狙) | ブラグザカート(自狙) | ブラグザカート(自狙) | ブラグザカート(自狙) |
| 0x5B | ブラグザカート(自狙) | タルケン | タルケン | ギドスパリオ | ギドスパリオ | ギドスパリオ |
| 0x61 | ギドスパリオ | ジアラ(弾) | ジアラ(弾) | カピ | カピ | ギドスパリオ |
| 0x67 | ギドスパリオ | ギドスパリオ | ギドスパリオ | テラジ | テラジ | ザカート(自狙) |
青字が通常の空中物として出ているタルケン6機、赤字が地上物扱いで出ているものになります。正直これ以外はメモリのゴミか無関係な参照かも知れませんが、こちらはキャラクタの区切りにきっちり設定してあり、キャラテーブル内の機数で設定され、かつ地上物ワークの範囲内に入れてある、という点を取って意図を感じてしまいます。
結びに
果たして、意図したものなのか、単に無意味な参照だったのか、判断はお任せします。個人的にはロマンあるほうを主張しておきたいですね。
最後に、すごくインパクトのある発見で久しぶりにゼビウスで楽しめましたし、ここ最近プレイもして久方ぶりに1000万点を出しました。あと、消失ソルを1バイトで出す方法(今までは2バイトだった)とか、複合攻撃のコントロール方法、その他改造に役立つ知見が得られました。消失ソルの件は時間が出来たら記事にしますので、お楽しみに。