player: zelpikukirby, su
special thanks: sup39, Noki doki
Emulator: Dolphin 5.0 lua core
re-records: 45151
Uses credit warp by arbitrary code execution.
cutscene underflow glitch causes it.
explanation of cutscene underflow glich(quote from noki doki) "The game has 8 “slots” to store active cutscenes, numbered 0 to 7. It also keeps track of the slot number of the last cutscene that started and the slot number of the last cutscene that ended. When a cutscene starts, the last started cutscene slot number increases, cycles back to 0 if it would go past 7, and the new cutscene gets loaded into that slot. Once the cutscene ends, the last ended cutscene slot number increases in turn, becoming equal to the last started cutscene slot number. Since both slot numbers are equal, the game knows it ended as many cutscenes as it started, so there are no more cutscenes to process.
Since there’s usually no way to end more cutscenes than you start, and the slot numbers are being used in a cycle, any time the last started and ended slot numbers don’t match up, that must mean there are cutscenes left to process, even if the last ended cutscene seems to be ahead of the last started cutscene. But when a Shine Get cutscene starts during another cutscene, for some reason, it ends twice, leaving the game with -1 cutscenes left to play, which it sees as 8-1=7.
hat if you replay a cutscene in a different area than it was originally played? For most cutscenes, nothing interesting happens: either they play normally, or they end instantly, depending on whether the associated camera movement filename was overwritten in the transition or not. But some cutscenes retain a callback to execute before and after the cutscene (even if the camera movement couldn’t be found), and a pointer to a relevant object to be passed to the callback. Most notably, Shine spawns keep a pointer to the Shine being spawned.
At the beginning of a Shine spawn cutscene, its callback will lead to one of the Shine’s virtual functions, TMapObjBase::makeObjAppeared, being called. When replaying the cutscene with cross-area cutscene underflow, its Shine pointer will be stale and the virtual call can be redirected to arbitrary code. Let S be the Shine pointer; *S will be read as a pointer to the Shine’s virtual table, and *(*S + 0x100) will be set as the instruction pointer. "
setting right bell cutscene on slot4 while peach is kidnapped. the game has some delfino plaza status, each plazas objects have different memory address. so the value of right bell cutscene(8134A65C) while peach is kidnapped will be related turbo gate address while poluted piranha appearances on ricco harbor.
By looking turbo gate on screen, the value of (8134A65C) can be changed. so setting the value to be related to controller address.(this part was made by su)
at the last, get a shine while blue coin cutscene is playing. then input codes by 4 controlles for credit warp.(this part was made by su)
"cutscene underflow glitch" と呼ばれるバグを用いてコードを実行しエンディングへ到達します
ゲームにはムービーを管理するためのメモリスロットが8つ存在し、青コインムービー等を見ると順番に埋まっていき、全て埋まるとまた1から上書きしていきます。
このスロットはビアンコなどのステージに入るとリセットされますが、ドルピックタウンでは保持されます
通常ではこのスロットを余分に参照する事はありませんが、他のムービーが流れている時にシャイン取得をすると、まだ埋まっていないスロットも参照してしまい、大抵フリーズします。(スロットが8つ全て有効な値で埋まっていればフリーズしません)
しかしメモリを調整しておけばこの時に更なるバグを引き起こせ、これがcutscene underflow glitchです。
ドルピックタウンは街の状態(どろパックンがいる、ニセマリオがいる等)によって異なるメモリアドレスが割り当てられています。
ピーチ誘拐イベント中に右ベルのシャイン出現シーンを見ると、メモリに[8134A65C]という値で保存されますが、この値はリコにどろパックンがいるドルピックタウンでは"ターボゲートの描画"のアドレスとして使われています。
描画に関わるアドレスはそれを画面に映す事で値を調整可能なので、バグの利用には都合が良いです。
そこで、コード実行パートで青コイン×2、シャイン取得ムービーの計3つのムービーを見ても上書きされないよう、スロット4に右ベルシャインの出現シーンをセットします。
リコパックンが出現したら青コインムービーを真っ先に見ます。これは時間経過でコインが消滅した直後であればラクガキを1滴で消せて再びムービーを発生させられるからです。
壁の中から完全な状態の落書きを消すのは、壁に水が当たってしまう事が大半なので現実的ではありません。
青コイン消滅までの間に、ターボゲートを画面に映して[8134A65C]からの値をコントローラ関係のアドレスになるように調整します(この位置調整はsu氏制作)。
調整が完了したら画面外に持っていく事で値の更新を防ぎ、そのまま水面抜けで地下へ行きます。
地下からマンホールの端っこギリギリに位置取りすると土管内部へ引き寄せられることなく脱出用ジャンプが可能なので、それで建物内部の即死床へ移動。
青コインの消滅まで適当に時間を潰して、消滅した瞬間に落書きを消してムービー発生、その間に鐘の下のシャインを取る事でcutscene underflow glitchを発生させます。
スロット4に残っていた右ベルシャイン出現シーン[8134A65C]を読み取ろうとした際に、アドレス[8134A65C]の値がコントローラ領域のアドレス値になっているため、コントローラ入力をコードとして実行します。
ここでコントローラを4つ接続し、エンディングへ再生するようなコードとフリーズ回避のためのコードを入力し、エンディングへ到達できます(ここもsu氏制作)。
Информация по комментариям в разработке