ゲーム : してログ

前から欲しかったディスクシステム版のゼビウスをようやくゲットできました。カセット版との違いはたぶんタイトル画面の年号だけだと思われます。ちなみに、裏面はボンバーマンでした。

同時購入でゲームボーイ版のネメシスです。ゲームボーイは持っていなかったので分かりませんが、グラディウスじゃなくネメシスということで購入してみました。レトロフリークだと入力遅延があるみたいですが、実機もこうなのか良くわかりません。

表ゼビウス

アーケード版ゼビウスでは自動難易度設定が導入され、プレイする度に内容が異なるようになっています。これが効果的に機能しているかは微妙ですが、「完全にパターン化できないがある程度調整可能」といった独特のプレイ感覚になっています。詳しい説明は他所に譲るとして、これには 0~127 で定義される攻撃パターンテーブルを指すポインタを増減させることによって実現しています。

先日気づいたことに「偶数番の攻撃コードだけが使用されているのでは無いか」ということがあります。理由は単純で、この増減の幅がひとつを除いて偶数になるためです。奇数になるのは、マップ上の決められたチェックポイント通過時に「出撃1機あたりのスコアが1万点以下(厳密には少し違う)でスコアの千の位が奇数のとき」だけになります。普通にプレイしている限り、この条件に該当するのは無いに等しく、結果として偶数攻撃コードの「表ゼビウス」が進行して行きます。

ポインタの増減

マップの進行による増加と、プレイヤーの行動による減少によってゲームが進行していきます(表は難易度がノーマル設定の場合)。

イベント増減値
空中物出現時(固定以外)2増加
決められたチェックポイントを通過するプレイ内容によって最大16増加
ゾルバクを破壊する2減少
残機を失う16減少

だいたいエリア2序盤付近で2万点を超え、ある程度上達するとミスもしなくなるため、以降のチェックポイントでは毎回最大値(16)増加することになります。また、チェックポイントはエリア1で4箇所、エリア2で0箇所設定されていますが、エリア1の設定箇所は2個ずつ連続していて「奇数判定されても×2で偶数」になってしまいます。ただし、ごく稀に連続したチェックポイントの間でスコアが変動した場合のみ奇数になることはあり得ます。

裏ゼビウスへの入り方

意図的にプレイしてチェックポイントで奇数判定させれば、奇数番の攻撃コードで進行する「裏ゼビウス」に移行できます。エリア1は意図的にこれを行うのは難しく、エリア2は設定されていないため、次に設定されているエリア3のスペシャルフラッグゾーン付近で調整します。

  • エリア3のスペシャルフラッグゾーン時点でのスコアを9、7、5、3、1千点代の何れかに調整する
  • 例えば空中物ノーショットで、エリア1のスペシャルフラッグ、エリア2までのソル全出現で9千点
  • スペシャルフラッグゾーン直後の空中物が出現すれば、奇数判定済みなのでスぺフラも空中物も普通に撃って大丈夫
  • これ以降普通にプレイすれば「裏ゼビウス」のまま維持される

表と裏の違い

ほとんど違いはありませんが、いくつかの攻撃テーブルで敵機の数が1つ多く設定されています。良く分かるのがブラグザカートで、表ゼビウスでは1個、裏ゼビウスでは2個ずつ出現します。また、テラジの最大機数が1機多い5機となっており、総じて裏ゼビウスのほうが難易度が高くなります。詳しくは、以下の攻撃テーブル表で確認してください。

総攻撃 A3 も

奇数コードなので A3 は当初出せないと思いましたが、裏ゼビウスに移行してからエリア12まで行くことで出すことに成功しました。研究され尽くされていると思っていましたが、まだまだ色々とありますね。

追記:ファミコン版でも確認

ファミコン版ゼビウスでも同様のプレイをすることで、出現テーブル上のブラグザカートが2個ずつ出現するのを確認できました。この部分はアーケードの出現テーブルとロジックを忠実に移植しているようです。

[ゼビウス] AC版ゼビウスに総攻撃がプログラムされていた (6) からのつづき)

調整方法の早見表

エリア11の攻撃パターンの組み合わせから、エリア12で必要なテーブル調整方法をまとめてみました。なお、通常プレイでは偶数コード進行になるため奇数コードは除いています(奇数コードは参考資料を参照)。

他のエリアでも再現可能

難易度設定によって、ミス時の減少値、空中物出現時の増加値が変わってくるため、HARD や HARDEST では他にも可能なエリアがありました。ただし、エリア3は HARDEST+5機設定でないと難しい(チェックポイント通過時の判定を最大にするために点稼ぎも必要)です。

難易度設定空中物出現時
(固定を除く)
チェックポイント
通過時(最大)
ゾルバク破壊再スタート時
(ミス)
EASY0+16-2-24
NORMAL+2+16-2-16
HARD+6+16-2-8
HARDEST+16+16-20
  • 空中物出現時に128以上かどうか判定されます

仕込み時の進行ポイントの目安

各進行ポイントまで進んでミスした場合、難易度設定毎に攻撃ポインタは下記のように変化します。

エリア進行ポイントEASYNORMALHARDHARDEST
エリア3スペシャルフラッグゾーンまで進行-80+8+16
エリア12斜めに道路が交差するあたりまで進行+8+16+24+32
エリア13埠頭の手前のゾルバク×4まで進行-80+8+16

注意など

ご自分の所有する基板、エミュレータ実装の市販ゲームなどでお試しください。ゲームセンターなどでは迷惑が掛かるのでやってはいけません。

[ゼビウス] AC版ゼビウスに総攻撃がプログラムされていた (5) からのつづき)

前回の検証で終わったはずでしたが、なんとプログラムの解析結果から未改造のゼビウスで総攻撃が発動する可能性があることが判明しました。ただし意図されたものでは無く、コード上のバグを利用して攻撃テーブルポインタをオーバーランさせることによって可能になります。

条件が成立するマップを探したところ1箇所だけ合致するポイントを発見しました。それがエリア12の冒頭部分で、ここは都合のいいことにテーブル調整が安定して行える正にうってつけのポイントでした。ほとんど同じ動きを最低5回繰り返す必要があるので、意図せず遭遇した人はいないと思いますが、まったく無いとも言えません。先日検証した巨大バキュラバグよりも、実は再現するのは簡単だと思います。

仕込み方法

再現条件は下記の通りで、普通にプレイしてフラグを立てることが可能です。攻撃パターンのチャートがあれば、テーブルの数値を頭で計算しながら調整できます。

  1. エリア12まで行く(残機はある程度必要です)
  2. エリア12の開始時に、空中物のテーブルポインタを調整しておく(直前のエリア11で、テラジ×3、またはテラジ×4が理想)
  3. エリア12のゾルバクを破壊しないでバーラ4つの右側の道路を降りてくるドモグラムの弾(タイミングの目安なので別のドモグラムのでも良い)に当たってミスする
  4. この手順を5回繰り返す(テラジ以外は後述の回数で)
  5. 6回目はそのまま4本ソルのところまで行くと総攻撃が始まるはずです(失敗するとリセットが掛かるか、何も起こらない)

テーブル調整はテラジが一番分かりやすいのですが、他にも下記のような空中物を目安にすることができます。カッコ内はエリア12でミスをする回数を表しています。

  • ジアラ(6回)
  • カピ(7回)
  • タルケン+ジアラ(8回)

※目安なのでゾルバク調整が必要な場合があります(それぞれ4~6パターン同じ機種の数違いが続くのでポインタの数値を確定できません/上記でだいたい40%~50%の成功率です)

追記:追記のほうに書いた「ザカート>ジアラ」で調整するのが確実です。 仕込み完了後に操作可能なリプレイファイルも用意しました。

具体的な調整方法

これはだいたいの目安なので、ネットで攻撃パターンのチャートを探して(時間が出来たら私も資料作りますが)ください。具体的な手順は、エリア11の攻撃パターンをよく見ておいて、今どこにいるか把握します。エリア11の最後の攻撃が今いるポイントになるので、その数値を基準に下記の計算をしながら調整します。

  • エリア12のバーラ4基(の先の道路が交わる部分が画面に出る)まで進むとプラス32
  • ミスでマイナス16
  • ゾルバク破壊で1基マイナス2
  • 攻撃テーブルによる空中物の出現でプラス2
    (ただし空中物の出現時に128以上かどうかチェックされるので仕込み中は出さないようにしよう)

これをうまく使って、エリア12スタート時に攻撃テーブルの数値を112~113に調整できれば勝ち確定です。この状態で上のプレイを1回行うごとにポインタをオーバーランさせ、6回目にそのまま川まで進むと総攻撃が始まります(調整に失敗した場合はリセット)。ただし、発動できても川の手前のごく僅かの時間だけで、川に差し掛かると通常攻撃に戻ってしまいます。

参考画像
参考画像

エリア12のみでテーブル調整(未検証/理論上可能)

残機があればエリア12の川直前の空中物で調整する方法があります。この空中物の種類がテラジ、カピ、タルケン+ジアラのときミスした場合、上記の回数+1回繰り返すと仕込みのラインに乗ります。もし違う空中物の場合は、ゾルバクを少し倒すなりして調整してください。ジアラを外したのは、攻撃パターンのグループが2つあり特定ができないからです。

何が起きているか

からくりは「攻撃テーブルポインタを2加算>128以上になったら64減算する>ポインタに対応する空中物を出現させる」というロジックになっているためです。つまり元のポインタが128未満であることしか考慮していないことを利用しています。更に、得点とミス回数から16加算する処理のバグ(範囲外になってもチェックしていない)を組み合わせることにより、次の空中物が出るときに総攻撃のパターンコード(162~163)を指すよう調整しています。

エリア12の序盤では、バグのあるこの処理が2回実行されるため、攻撃テーブルポインタが32進みます。ミスしたときは単純に16減算しているのみなので、1回のプレイでプラス16進むことになります。従って、(仕込み5回分で)112+16×5=192、(6回目のプレイで)192+32-64+2=162(総攻撃パターンコード0xA2)となります。

なお、ハードやベリーハードの場合はまだ可能性のあるエリアがあるかも知れませんし、テーブル調整がしやすいかも知れません。こちらはまだ想像の範囲ですが、きちんと調べれば入り口の間口は広がるかも知れません。

とりあえず、総攻撃への入り口はエリア12にありました、というご報告でした。動画を作成していますので、できしだい追記&アップロード致します。

追記1

下記に動画をアップしました。

この動画ではエリア11の攻撃が「ザカート>ジアラ」だったのでポインタが104か105で確定できました。(上の目安で書いたジアラの少し後に出てくる2パターン連続しているジアラと特定)そのため、エリア12のゾルバクで調整を入れて必ず発動するよう調整しています。また、エリア11を繰り上げで抜けているので1回分多く仕込み作業をしています。ここら辺はややこしいので早見表を作っておくと成功率が上がると思います。

また想定外ですが仕込み中、変なところでスぺフラ効果音みたいなのが鳴っています。これ、コード上鳴りそうもないのに、どうしてなのかはまったく分かりません。

エリア12が総攻撃への入り口だった
エリア12が総攻撃への入り口だった

追記2

仕込み完了直後にプレイ可能になるリプレイファイルを作りましたので試せる方はご利用ください。

だんだん慣れて成功率が上がってきました。エリア11の斜めの地上物から2回空中物が来ますが、ここが「ザカート>ジアラ」となった場合は、仕込み×6回、ゾルバク×4個破壊、これで仕込み完了になります。もし、動画やリプレイファイルのように繰り上げでエリア12に来た場合は、仕込み×7回、ゾルバク×4個破壊、になります。

リプレイファイルでは、カウントを間違えて5個破壊していますが、恐らく1回目の仕込みの際に、若干スクロールさせすぎて空中物の+2が入ってしまい帳尻が合ったと思われます。もう少し早めに当たった方が成功率が上がると思います。

追記3

A3 を出そうと思って少し気づいたことを書いときます。この出現テーブルポインタですが、加算も減算も偶数で難易度設定変えてもそれは変わらないと思います。そうだとすると、奇数には絶対にならないため A3 は出せないばかりか、出現テーブルの半分は実際には使われていないっぽいです。

追記の追記:チェックポイントで得点とミス数から出現テーブルポインタの加算値を算出しますが、その際に奇数になることがありました。 ただ、ゲーム開始の早いうちでないと以降ほぼ確実に +16 の判定になるっぽい(後ほど検証します)。 また、奇数になっているのはテーブル上のブラグザカートが ×2 になることで判断できます。

固定の空中物としてコードを直接指定されれば別ですが、それでも多くの使われない攻撃パターンがあると思われます。加算や減算の数値を半分にすれば、出現テーブルを倍使えるので非常にもったいないと思います。

おかげで A3 がちょっと難しそうですが、B2 であれば仕込み回数をもう1回増やすだけなので、後で挑戦してみようと思います追記2のリプレイファイルから仕込みを1回追加すると B2 の攻撃になります(動画も追加しておきました)。

あと、先ほどの偶数奇数の話に戻ると「ザカート>ジアラ」と来た場合は仕込み方法がひとつしかありません。出現テーブル上は、同じジアラの攻撃が2連続定義されていますが、片方が奇数になるためポインタが 104 であることが確定するからです。テラジや他の機体でも編隊の機数によって、仕込み回数とゾルバク破壊個数が確定的に言えそうです。

更に改造のアイディアも。ということはですよ、何らかのトリガーで奇数にレーンチェンジできれば、出現テーブルが2本できますよね。ゼビウスアレンジメントのように、出現テーブルを2つ用意してプレイヤーを苦しめることができますね。

追記4:調整の早見表

攻撃順から起点攻撃コードを特定できるものを早見表にしてみました。繰り上げでエリア12に来た場合は、仕込み回数を+1してください。

エリア11の攻撃パターン起点攻撃コード仕込み回数ゾルバク破壊数
ザカート > ジアラ0x68 (104)64
ジアラ > トーロイド0x6A (106)65
テラジ×2 > テラジ×30x70 (112)50
テラジ×3 > テラジ×40x72 (114)51
テラジ > トーロイド0x74 (116)52
発動後に再チャレンジしたい場合

A2 の発動後はテーブルポインタが 146(0x92)になっているので、ゾルバク1個破壊することでもう一度ラインに乗せることができます。ラインに乗ったら、また仕込み3回行うと再びチャレンジできる状態になります。ただし、川付近まで進んだ場合は仕込みが壊れているので諦めましょう。

また、16進で考えたほうが分かりやすいです。まず、ラインに乗せた状態は16進で1桁目がゼロの場合になりますので、ゾルバクを使って乗せてください。仕込み1回で +0x10 進むので 0x90 → 0xA0 → 0xB0 → 0xC0 と仕込みを繰り返し、出撃の際に 0xC0 になっていれば条件が成立しています。

[ゼビウス] AC版ゼビウスに総攻撃がプログラムされていた (7) につづく)

ROM チェックエラー
ROM チェックエラー

今まで ROM チェックを無視して結果判定のところだけ NG に分岐しないよう改造してたんですけど、それをちゃんとチェックが通るようにしよう、ということで重い腰を上げてみた。

ROM データの最終バイトにチェックサム調整の数値が書き込まれているのは気づいていたので、恐らく総和の下位8ビットがゼロになるよう調整してあるんだろうと察しはついていました。実際に計算してみるとその通りだったので、チェックサムを計算してこの調整バイトに書き込んで終わり、と思ったのになぜかチェックが通らない。調べてみると、チェックサムを計算した計算結果が並ぶメモリがあって、そこの恐らく XVI6 に当たる部分がゼロになっていませんでした。でも、こちらのエクセルの計算結果はゼロになります。

プログラムを追ってようやく分かったのは、なんとサブ CPU にマップされる ROM はチェックサムを計算していない、ということです。データの中でたまたまゼロになっている1バイトのアドレスを、ただ計算結果のメモリにコピーしてるだけ! そんなの有りですか? 時間を返して欲しいです。

だから、プログラム内のたまたまゼロ値であるアドレスは変わりようがないので、XVI5 についてはチェックサムは関係なくてもパスします。しかし、出現テーブルの XVI6 は改変したら大きくずれて参照先アドレスがゼロ値でなくなり、チェックサムが合っていても ROM エラーとなります。しかも、ROM 5 という表示でいかにも XVI5 がエラーというふうなのですが、XVI6 がエラーというトラップもありました。

散々苦労しましたが、最初の ROM チェックを無視するというコードが正解でした。同時にプログラムの ROM を改造する場合は、最終バイトまで心置きなく使っても大丈夫なことが判明しました。たぶん、サブ CPU のほうはメンドクサイからそうしたのか、チェック完了のタイミングが CPU 同士で取るのが大変だから、とかそういう理由でしょうね。

ちなみに、エリア8の中盤で右側道路に3台のドモグラムが下りてくるシーンがあると思いますが、そのうち真ん中の1台のデータがそれです。このドモグラムを弄るか、この前のエリアに何か追加してずれてしまうと ROM エラーになります。

再現できたガル・バキュラ
再現できたガル・バキュラ

デモプレイに画面が切り替わる瞬間にクレジットを投入した際、ソルバルウなどが画面に残った状態で PUSH START BUTTON の画面になることが、このバグが成立した状態になります。ただし、状況によっては目立った変化が無い動画もあります、何れにしてもこれが成立していれば、スタート直後に横一列にバキュラが並んだ状態で出現します。こちらのページにそのリプレイファイルがあったので、今回はこのバグが成立する条件を探ってみました。

まず、大量のバキュラが出る原因はすぐに分かりました。バキュラのキャラクターコードが 0x01 で、これが地上物、空中物、バキュラ、スパリオなどのワークメモリすべて埋め尽くされるために起きています。これは総攻撃などと同じ原理で、どのワークに入れても指定したコードのキャラクタが出現するのと一緒です。そのため、空中物に入れられたバキュラは破壊可能で、得点テーブルも 0x01 で埋められているので対応した得点が加算されます。

問題はなぜこのような現象(0x01 で埋め尽くされる)が起きるかですが、やはりメインとサブの CPU が関係していました。画面モードが切り替わった直後にメイン CPU がワークメモリを 0x00 でクリアしています。原因はそのゼロクリアのし方が下記のようになっているためです。

該当箇所のコード(XVI4 の先頭から)
  1. クリアする先頭アドレスに 0x00 を書き込む
  2. ブロック転送命令で1バイト前のアドレスの値を指定回数コピーする
ld   hl,$7900
ld   de,$7901
ld   bc,$06FF
ld   (hl),$00
ldir

このコードはシングル CPU であれば問題は起こりませんが、このブロック転送の最中にサブ CPU が介入してキャラクタの状態を表すワーク領域に 0x01 を書き込むと、意図しない値がコピーされてしまいます。具体的には、ひとつ前のアドレスをメイン CPU が読み出す直前に、サブ CPU がそのアドレスに 0x01 を書き込んだ場合です。本来は先頭に書き込んだ 0x00 がバケツリレーのようにコピーされるはずが、途中から 0x01 に差し替えられてしまい、以降の領域のすべてが 0x01 で埋め尽くされることによります。なお、画面にスプライトが残る残らないの違いは、どの場所をクリアできてどの場所がクリアできなかったかの違いで起きていると思われます。

この条件が成立するのはかなりシビアであり、狙って出すのはかなり難しいと考えます。それはデモ画面に切り替わった直後『サブ CPU がキャラクタの状態のワーク領域に 0x01 を書き込む直前』にクレジットを投入する、というタイミングと思われますが、クロック単位のシビアなタイミングが予想されます。

状況の再現

ロジックが分かったので再現して確かめてみました。前述のコードの先頭に書き込む 0x00 を 0x01 に変更しただけで再現できました。ただし、強制的にやっている関係でミスしても元に戻りません。

ld   hl,$7900
ld   de,$7901
ld   bc,$06FF
ld   (hl),$01
ldir

ゼビウスの他のバグと根っこは同じ

ゼビウスってこれ系のバグが多いですよね。エリア繰り上げワープ然り、森の地上物さん然り、CPU 間でメモリを共有しているにも関わらず、タイミングが取れてないから意図しないデータ参照や書き込みが起きてしまう。もしかしたらまだまだレアな怪奇現象が起こるかも知れません。

[ゼビウス] 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)定義(機数・起点キャラ)
0xA20x041C0xA7 0xED
0xB20x043C0xC1 0xC9
0xA30x041E0x52 0x19

うーむ。上2つは想像してたのとぜんぜん違いますね。これだとリセットコースなんですが、さっき書き換えてテストしていた部分に入れてみると A2, B2 と同じ攻撃が出て来ました。この A2 の定義だと範囲外のキャラを167機出現させるという指定であり、リセットが掛かってもおかしくありません。これでよく動いてるな、というのが心証です。

追記:0x80~0xFF までの参照で実際有効なのは 0xE0~0xFF(XVI5 の 0x0498~0x04D7)です。 残念ながらプログラムコードの一部を拾ってしてしまい、バグって総攻撃に至っているというのが事の真相のようです。

残りの 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機、赤字が地上物扱いで出ているものになります。正直これ以外はメモリのゴミか無関係な参照かも知れませんが、こちらはキャラクタの区切りにきっちり設定してあり、キャラテーブル内の機数で設定され、かつ地上物ワークの範囲内に入れてある、という点を取って意図を感じてしまいます。

追記:地上物ワークまで間が空くのは、<地上物>~<バキュラ>~<スパリオ>~<空中物>~<未使用>の順に配置されているためでした(2バイト単位なので128機(うち有効なのが最大54機)で1周しています)。 細かく書くとバキュラとスパリオの間も、自機や照準など7機分の空きがあるようです。

結びに

果たして、意図したものなのか、単に無意味な参照だったのか、判断はお任せします。個人的にはロマンあるほうを主張しておきたいですね。

最後に、すごくインパクトのある発見で久しぶりにゼビウスで楽しめましたし、ここ最近プレイもして久方ぶりに1000万点を出しました。あと、消失ソルを1バイトで出す方法(今までは2バイトだった)とか、複合攻撃のコントロール方法、その他改造に役立つ知見が得られました。消失ソルの件は時間が出来たら記事にしますので、お楽しみに。

[ゼビウス] AC版ゼビウスに総攻撃がプログラムされていた (6) につづく)

追記:残念ながら意図してプログラムされたものでは無いと思われます。 詳しくは(5)を見てください。

[ゼビウス] AC版ゼビウスに総攻撃がプログラムされていた (3) からのつづき)

書き忘れがあったので続けます。

地上物レイヤーにいる敵はブラスターで撃墜可能

照準器が赤く点滅することがあるので、薄々気づいてはいました。コマ送りで確認したところ、ブラスターによるタルケン撃墜の様子が撮れていたので、スロー再生動画にしました。タルケンの50点もちゃんと加算されているようです。

爆撃によるタルケンの撃墜

[ゼビウス] AC版ゼビウスに総攻撃がプログラムされていた (5) につづく)

追記:残念ながら意図してプログラムされたものでは無いと思われます。 詳しくは(5)を見てください。

[ゼビウス] AC版ゼビウスに総攻撃がプログラムされていた (2) からのつづき)

検証用コードを準備しましたので、試せる環境のある方は参考にしてください。なお、書き換えにあっては自己責任でお願いいたします。

総攻撃検証コード

検証に必要なもの

ROM データはご自身の所有するアーケード基板より取得していただきますようお願いします。検証にはバイナリエディタ(Stirling 以外でも構いません)を準備してください。Stirling は Windows10 でも動作しますが、アップデートされていないためか遅い場合があります。

書き換え箇所とデータ

XVI6 に相当するデータファイルを Stirling で開いて 0x003C からの3バイトを下記のように変更します。以降の 0x003F ~ 0x00C6 まではすべて 00 で埋めていただければ OK です。書き換え終わったら保存(Stirling なら変更前のバックアップファイル .bak も保存されます)して終了です。

CODE A2
#003C: F0 02 A2

下記のスクショでハイライトした部分を参考にしてください。

書き換え箇所
書き換え箇所
エミュレータ実装の市販ソフトなどを書き換える場合

EXE ファイルなどをバイナリエディタで開き「20 10 C8 10」のバイト列を検索すると、変更箇所付近がヒットすると思います。前項のスクリーンショットを参考にして対応する箇所を書き換えてください。

なお、ISO イメージにバックアップしたものを直接バイナリエディタで書き換えても構いません。その場合は複数個所がヒットすると思いますが、ベンチマーク版かと思いますので両方書き換えてください。SUPER は微妙な違いがあるので前述のバイト列ではヒットしません(攻撃パターンのマップも異なると思いますので動かないと思います)。

他の総攻撃パターンを試す場合

書き換えコードの A2 の箇所を、B2 または A3 にするとそれに対応する総攻撃パターンを試せます。

CODE B2
#003C: F0 02 B2
CODE A3
#003C: F0 02 A3

最後に

書き換え箇所がちょうどエリア1の範囲になり、エリア2からは通常のゼビウスに戻ります。ただし、A2 と B2 はスパリオがキャラ化けしてしまい、つぶつぶや色のおかしいカピやザカート弾(一度ミスすれば戻る)を撃ってきます。とは言え、恐らくこの攻撃を抜けられる方はいないでしょう。しかし、A3 は頑張れば抜けられると思いますので、腕に自信のある方はぜひ挑戦してみてください。

上記のコードでは強制発動を維持させるため、結構な範囲を書き換えています。しかし、条件としては最小1バイトで済むため、何らかの理由(ROM の読み出しに失敗したり)でバグった場合に発動する(していた)可能性はあると思われます。もし、当時この光景を目撃していたとしたら相当な騒ぎになったはずですが、今まで聞いたことがありません。

またひとつ、ゼビウスの謎が解かれました。

もしかしたら、エリア1のボザログラムをある順番で破壊したら...、とか何らかのトリガーが全16エリアのどこかに存在している可能性は依然として残ります。いつかすべての謎が解かれ、真のエンディングが訪れることを期待します。

[ゼビウス] AC版ゼビウスに総攻撃がプログラムされていた (4) につづく)

検証報告お待ちしております
追記:残念ながら意図してプログラムされたものでは無いと思われます。 詳しくは(5)を見てください。

[ゼビウス] AC版ゼビウスに総攻撃がプログラムされていた (1) からのつづき)

発見した攻撃パターンコード(A2 / B2 / A3)は、通常の出現テーブルセットの後ろのものになります。これとは別の出現テーブルセット(使われていないと思う)にも、同じ攻撃パターンコード(E2 / F2 / E3)がありますが、先に発見したコードで識別しています。

CODE A2 の攻撃パターン

ゼビウスの通常攻撃でテラジは最大5機までですが、この攻撃では6機も同時に出現します。これだけでもお手上げしそうなのに、加えザカート大量、ブラグザカート、バックゾシー、その他という信じられないほどの物量攻撃です。スパリオがキャラ化けしていて、つぶつぶや、カピなどの断片で飛んできます。

CODE A2
CODE A2

数の正確な確認は困難

  • テラジ×6
  • カピ×8
  • ジアラ×2
  • タルケン×2
  • ザカート×16(落下タイプと自機狙いが混じるが判別困難)
  • ブラグザカート×2
  • ギドスパリオ×8
  • バックゾシー×6

CODE B2 の攻撃パターン

テラジの代わりにゾシーが大量に出る以外、A2 と大差ないと思います。A2 もそうですが、ほとんどの敵はこちらの攻撃を弾きます。

CODE B2
CODE B2

数の正確な確認は困難

  • トーロイド×2
  • タルケン×5
  • ジアラ×8
  • カピ×4
  • テラジ×1
  • ザカート×16
  • ギドスパリオ×6
  • ゾシー×7
  • バックゾシー×3

CODE A3 の攻撃パターン

バキュラバリアが無く、スパリオも通常弾です。タルケン以外はゴーストなので、当たってもミスになりませんが、こちらの攻撃も通りません。スパリオを良くみて避けることは十分可能な範囲です。

CODE A3
CODE A3

数はだいたい合っていると思います

  • タルケン×6
  • ジアラ×2
  • カピ×2
  • テラジ×1
  • ギドスパリオ×6

考察(1):どうやってこの物量を出しているのか?

ゼビウスの空中物は同時に6機しか出ないため、管理領域も6機分と考えられます。総攻撃ではざっと数えただけでも50機以上は出現しているので、普通のやり方では実現できないはずです。だいたい想像はついているので、先に言っちゃうとバキュラや地上物の管理テーブルも使って出していると思われます。

実は、アンドアジェネシスもこの手法を使っていて、出現範囲には一切地上物は置けないのです。なので14面は、アンドアジェネシスが2基出現するために、一切の地上物が設定されていないと言う訳です。ただ、アンドアジェネシスは地上物と共存できないだけで、バキュラとは共存可能です。

次のスクショでは、バキュラを出してから A2 と A3 の攻撃をそれぞれ開始させています。A2 は攻撃が開始された途端バキュラの出現が止まってしまいますが、A3 は止まりません(敵の出現量を少なくしてバキュラの領域まで使っていないと思われます)。

考察(2):A2 と B2 はただのお遊びでは無いのか?

どのぐらいまでキャラを出しても行けるか確認するため、もしくは単に大量に出してみたいという好奇心を満たすためです。たいていの人(プログラマ)はこういうことを考えるもの(ファミコンロッキーが証明しています)だと思いますし、自分も似たような経験があります。

それに、この物量はあまりにもかけ離れていて、もはや別のゲームであり、本気で組み込もうと思っていたとは思えません。発動後に完全に元の状態に戻らないのも、おかしな幻影弾を撃ってくるのも、限界量さえ分かればいいというロジックであれば理解できます。

ただ、わざわざイレギュラーな処理をしてまで地上物やバキュラの領域を使うプログラムを組んだ、という点はどうでしょう。ここまでは無いにしても、実験的に限界点を探っていたというのが事の真相かも知れませんし、私だったら面倒を承知でも好奇心のほうが勝ったと思います。

いずれにしても、これは採用する目的でプログラムはしていなかった、というのはかなり信憑性があると思います。

考察(3):A3 は本作のラストとして組み込もうとした残骸なのか?

他の2つと違い A3 は避けようと思えば可能なレベルに抑えてあり、バキュラや他の地上物と共存が可能になっています。また地上物の領域を潰して空中物を増やしてはいますが、その領域は10個分(上限は14個まで)に留めており、こちらとも共存可能となっています。この配置できる地上物を残した、というのがこの考察のポイントです。

残りの領域は4個、仮に16面と同じくガルデロータ2基(ガル系は領域を2個消費します)とすれば、ドモグラムや他の地上物はあと2つ置ける計算になります。ちょうど置ける計算になります(夜書いたので計算間違えたわ)。ほらほらほら、最終要塞を組むのに十分な気がしてきませんか? 光景が目に浮かぶようです。

エリア16のラストの川付近はデロータで固められています。もし、この付近の地上物(もしかすると第2防衛ラインのガルデロータまで)を排除して、A3 の空中戦が展開されたとしたらどうでしょう。激しい空中戦を何とか潜り抜けた先に、ガルデロータ2基が鎮座しています。もしかしたら、警備用のドモグラムが周囲を警戒しているかも知れません。今までのエリアと違ったラストに相応しいドラマティックな展開になったはずです。

なぜバキュラの領域を使わなかったのか? という点が残りますが、これについてはエリア7に繋ぐためとも考えられます。もし領域を使ってしまうと、少なくとも1.5画面前くらいまでに攻撃を停止させ、領域をクリアにしておかねかればならないはずです。ゼビウスは制約が多くてエリア間もうまく調整しないと、前のエリアの影響を受けてしまうのです(エリア7は、6→7 と 16→7 両方とも調整が必要なのです)。つまり16面のラストに A3 の攻撃を展開しようとすると、必然的にバキュラの領域は使えない、ということになるのです。

ではなぜ採用しなかったのか? という点についてはこうです。出現させるまでは簡単にできても、重ね合わせや当たり判定その他もろもろ、イレギュラーな使い方をするが故にその調整に掛かるコスト(コード量)が確保できなかったのでは無いでしょうか。爆発痕の下を潜ってしまうのは無視できても、健在な地上物の下を空中物が潜るのは明らかに変です。作ってみたはいいけど、こういった点を解消するために更にコード量がかさむとなれば、諦めるのも仕方がありません。

追記: 16面最後のガルデロータ2基の管理領域番号を確かめたところ 18 1A と 1C 1E でした。 これは A3 の総攻撃パターンが使わない 18 1A 1C 1E にぴったりと当てはまります。

結びに

現代であれば容量など気にしなくてもいいし、欲しいだけメモリや、CPU、GPU のリソースを使えます。しかしゼビウスが作られた当時は、16進から10進に変換する処理すら削ったり、論理演算をうまく使って計算したりして節約していました。例えば残機表示がずらっと並ぶのや、10機以上になるとアルファベットや記号になるのも、そういった背景があります。

今回の発見はゼビウスの基板は貧弱で、キャラオーバーでソルは消えちゃうし、敵機も弾幕もこの程度しか出せなかったんだ、というのが思い過ごしだったことに気づかされました。あえて性能の半分も使わない代わりに、世界観の表現やゲームバランスを箱庭のように丁寧に作り込んで行った。正にあの当時として、ゼビウスはあらゆる面でオーパーツだったんだなあ、と思った次第です。

なお、ここで書いたことは筆者の妄想であり、恐らく半分も合っていないでしょう。巷では「もう深まる謎など残っていない」などと言われる本作ですが、久しぶりの新しい発見を楽しんでいただければ幸いです。

[ゼビウス] AC版ゼビウスに総攻撃がプログラムされていた (3) につづく)