「ユーザーブロマガ」サービスの終了(10月7日を予定)にあたり、残したいユーザーブロマガ記事への投票を受け付けています

ドンキー 口寄せワープのその時、何が起こっているのか
閉じる
閉じる

ドンキー 口寄せワープのその時、何が起こっているのか

2017-04-25 18:51
  • 2

残したいユーザーブロマガ記事への投票はこちらです

一般に口寄せ、あるいはWrong Warpと呼ばれる有名なバグがドンキー1,2にありますが、どうやって行われているかは知っていても、その時実際に何が起こっているのかを知っている人はあまりいないと思います。
ここでは、HowではなくWhatを解説していきます。

○「無を取得」しているということは何を意味するのか
ドンキー各作には、画面内に入るなどしてロードされたスプライトが、各々の活動を正常に行うための情報を格納しているスプライトメモリと呼ばれるバッファがいくらかあります。DK2の場合、これは1つ0x5Eバイトで24本あります。一般的に0番と呼ばれているスロットは実際には2番です(真の0番はDD専用、1番はDX専用に予約されている)。DK3のばあいも似たような感じですが省略。
DK1の場合は少し事情が違いますが、26本あって-1番から24番と呼ばれます。0番がDK、1番がDDで-1番は通常は使用されません。
さて、このスプライトメモリには各々のスプライトに関する情報(座標、速度、その他もろもろ)が格納されていて、界隈ではこの情報のある番地をさして、変数XXXX番などと呼んでいます。DK1の場合$0D57、DK2の場合$00という変数は、そのスプライトのプログラムの番号が格納されています。ここが0のスプライトバッファは、空きとみなされて新しくスプライトをロードすることができます。逆に、ここに0を書込むと、そのスプライトメモリを占有していたスプライトは破棄されます破棄されたスプライトは、ふつうはそれ以降活動を停止します
さて、無を取得したとします。実は無を取得したときも破棄処理が実行されます。すなわち取得した無に対応するスプライトメモリは、空きとしてマークされることになります。それにもかかわらず、無に対応するスプライトメモリは依然として一部の活動を続けます
以上をまとめると、無を取得している状態とは、破棄されたはずのスプライトが活動している状態ということができます。

○メモリの書き換え
前項で「無を取得している状態」の内部的な実態を説明しました。次に無によるメモリの書き換えです。
無を取得するときにも破棄処理が走ることから、プログラム側からは、この無に対応するスプライトメモリは空きとみなされています。したがって、無に対応するスプライトメモリには、新しくスプライトをロードすることができます。実際、このロード処理は正常に実行され、新しくロードされたスプライトも正常に活動を行います。
この時、活動しているはずの無のデータが上書きされることになりますが、ここで無の実体は新しくロードされたスプライトにすり替わりますそれが持てるものであろうと、持てないものであろうと関係なく、新しくロードされたスプライトを持っていることになっています
この状態で無を投げたり置いたりして失うと、普通に樽などを投げたり置いたりした時と同じ処理が走ります。この処理の詳細はDK1とDK2で異なりますが、これが原因でメモリが書き換わるのです。DK2でスプライトが手元にワープするのも、これが原因で座標値が上書きされるためです。

○別のコースにワープするということ
前項で、無に新しいスプライトがロードされた場合に無を失うと、そのスプライトの活動データが破壊されることを説明しました。ここからは猿1の話です。無を投げるとボーナスの飛び先(正確には復帰先)が変わるというのですが、これはなぜか。
これも先ほど説明したメモリ書換が関与しています。
DK1では樽などを持っている際、$13FBという変数が変更されます。これは、持っている樽の自機のX座標を基準とした相対X座標を格納している変数です。樽を置いたり投げたりするときもこの変数は変更され、完全に手を離れたときに0がセットされます。
ところで、樽以外のスプライトでも$13FBという変数を使用しているスプライトがいくつかあります。そのひとつに、ボーナス用の壊せる壁が該当します。
ボーナス用の壊せる壁スプライトでは、この$13FBという変数はボーナスステージから戻ってきた際にロードするマップの番号がセットされています
(※DK1ではスタートから、中間から、各ボーナスから戻ってきた場合のマップはすべて別マップ扱いになっています。)
つまり、無に対応しているスプライトメモリに壊せる壁がロードされている際、無を失ってしまうと…皆さんもうお分かりですね?復帰先が樽を投げる処理によって書き換えられてしまうのです。
この変数は先ほども説明した通り、持っている樽の座標なので、適切なタイミングで犠牲するなどして瞬間的に無を解放すれば、比較的好きな値に調整することができます。ちなみにDKとDDでは少し持つ位置が違うため、移動先が変化します。
なお、この時壁が壊れるという(都合のいい)副作用が生じますが、これも樽を投げる処理の副作用によるものです(この処理が書き換える変数は$13FBだけでなく、ほかにもあります)。
なお、この座標は小さめの値しかとらないため、可能な移動先はマップ04番~20番ぐらいまでです。また、この中にはどう調整しても出せない値もあるため、実際にはもう少し少ないです。筆者は以下のコースへの移動を確認しています。
04:1-3のボーナス3
07:2-3
08:1-1(ボーナス1から復帰)
09:2-3(ボーナス1から復帰)
0B:1-3(ボーナス3から復帰)
0C:1-2
0E:1-1(ドンキーの家から復帰)
10:2-3(ウィンキー部屋から復帰) ←新口寄せルートの1つ目の口寄せで使われる値
12:6-2 ←新口寄せルートの2つ目の口寄せで使われる値、ダチョウ必須
14:4-5 ←旧口寄せルートで使われる値
24:4-1 ←これもダチョウ必須
なお、この範囲内にある値で、出せるとTASの更新につながりそうな値は0Aです。6-3に対応します。

○ステージを脱出するということ
ここからはDK2の話です。
無を取得して、そのスロットに樽大砲をロードした状態で無を失うと、樽大砲の挙動がおかしくなりますが、これもメモリ書換の影響によるものです。
(※アニマルバレルは実は樽大砲です。また、弾をセットするタイプの大砲も内部処理は樽大砲を流用していますのでここに含めます。)
DK2ではかなりのスプライトに共通する変数があり、ここで重要なのは$26という変数です。
この$26という変数は、一般的にX方向の速度が格納されています。(参考:ジンガーのスプライトメモリ)
樽を投げる際も、当然のようにこの変数は書き換えられます。速度ですからね。
ところが、樽大砲の場合は、この$26という変数には、アニマルバレルなら変身するアニマルの種類、ワープ系ならば移動するマップの番号が記されています。(参考:樽大砲のスプライトメモリ)
(※クラッシュエレベーターで最初のランビバレルを口寄せすると危険な状態になるのは、この変数が書き換えられ無効なコード呼び出しが発生するためです。)
さて、DK2の場合、それぞれのマップから移動することのできるマップの番号は、ステージ設定領域にまとめられていて、その配列のインデクスで移動先を指定します。ただし、普通のコースなら移動先0番は次のステージと決まっています(1-1なら移動先0番は1-2というふうに)。
このことから、$26を無によって0に書き換えてしまえば、その移動先は次のステージとなるわけで、これによってステージ脱出が達成できるわけです。
(※初期版ではこの辺の処理の仕様が異なるため、発射後に敵に当たるなどして死ななければ無限ループします)
なお、ほかにも書き換えられる変数がありますが、これによって飛距離や発射速度までもが操作されています。
なお、樽大砲が手元に移動するのは先にも説明した通り、座標値(変数$06及び$0A)が樽を投げる処理によって書き換えられるためです。
広告
×
動画が消えてしまっている事が残念で改造ドンキーまでマリオのように消されてしまうのは意外でした。sm31090902(このブログの解説動画)はYouTubeで会いたい(見たい)です。
46ヶ月前
×
弟作TASの動画でYouTubeに当たり判定表示、英語解説の動画があることからTAS制作にすごい気合が入っている事が伝わりました。弟作改造ドンキー2TAS完成も楽しみです。ゲームの細かい仕組みの知識がすごくてドンキーの原作TASもまだ進歩する気がして面白いと思いました。
46ヶ月前
コメントを書く
コメントをするには、
ログインして下さい。