今回のTASについてざっくり説明
1:ロックマンの位置やドロップアイテムの出現時間を調整したりする
2:バグを引き起こす
3:エンディングが呼ばれるよう調整してある
このようなTASはACE(任意コード実行)というジャンル名で呼ばれています。
ACEは最近急に発展してきたため、普通にクリアしていくTASとは違ったジャンルになり発展しつつあります。
大百科:任意コード実行
今回はロックマン1でACEをするととても速くエンディングを見られるのでは?というTASの方向性の1つを形にしました。
新TASに至った経緯
2010/11/28
前回のTASの完成
2011/01/21
ディレイFFオブジェクトテクを見つけ、アイスマンステージでオブジェクト00~FFが出現することを発見
2014/4/29
FinalFighterが、ピロ彦先生のスーパーマリオブラザーズ3のTASについて簡単に解説を読む
SMB3の任意コード実行の機構を知る
2014/4/30
「ディレイオブジェクト」のうちいくつかのオブジェクトが$700以下のRAMアドレスを実行していたことに気づく
以前はリセットがかかるので使えないオブジェクトとしてチェックしていなかったが、
SMB3TASの任意コード実行の機構を知ったので、メモリの事前調整によってロックマン1でもできるのではないかと思い出す。
ピロ彦先生と共同で任意コードをどう書けばうまくいくかを調査する
ディレイオブジェクトFFテクで、オブジェクト55の出現が可能なことをBOTで確認。
オブジェクト55の呼び出し先アドレスが$600で合っていることを確認。
$600(Y座標)からジャンプさせて$650(アイテムが出現すると増加し消すと止まるカウンタ:ObjectFireDelay)を調整するとうまくいくことを発見
ピロ彦氏曰く<もしロックマン1で任意コードが実行されるようになったとしたら、それはSMB3TASに影響を受けた結果であり、巡り巡ってkentora12氏の影響であることは確定的に明らか。
2014/5/1
FinalFighterがディレィオブジェクトがどのメモリから読み込まれたか確認できるLuaScriptの作成。それにより、アイスマンステージのディレイオブジェクトFFテクでアドレス:$0023の内容を0x55にするとオブジェクト55が出現することを確認、ディレイFFオブジェクトテクがロックバスター+4ドロップアイテム程度の重さで実行できることをBOTで確認
アイスマンステージでディレイエンディングが完結できることをピロ彦先生がメモリ操作で確認
2014/5/3
新TAS作成開始
ピロ彦先生が事前のメモリ調整担当に。
2つに分離するロボットがオブジェクト20(パンチ)をやたら出すためそのたびにスロットが破壊されるので調整が非常に大変なようであった。
2014/5/8
ロックマン2でもFinalFighterとピロ彦氏がガッツタンク戦で新技を発見
ロックマン2のやり直しが確定した(´・ω・`)<バブルマンステージまで進んでたのに…
2014/5/11
スロットを空けていてもなかなかうまく狙ったスロットに納まってくれないという問題が多発していたため、FinalFighterがオブジェクト出現予測Luaを作成しオブジェクトの出現条件及び原因を突き止める。
2014/5/12
FinalFighterがオブジェクト1のObjectFireDelayの変動する原因を突き止め。これにより最適な任意コードが確定。
2014/5/13
80F程待てばもっと重い音楽のFがあるためディレイエンディング再現は余裕だったのだが、
われわれは妥協したくなかった。$23=0x55となる最速のチャンスでどうしても成功させたかった。BOTが待てども待てども結果を出さないため、
ピロ彦先生は、$8C=6かつ処理量がNMIが割り込む位置が合う条件をロックマン2のディレイスクロールのように支援LuaScriptを使って手作業で狙い始めた。$8C=4ではすぐにいい例が出た。
これで$8C=6でもうまくいけばいいのだがなかなか処理量がうまく調整できない。
処理量がオーバーしてしまう例がでたので解は近くにきっとあるはずなのだが…
しかし、どうしてもうまくいかず、あきらめて80Fほど待つかな…と思った瞬間、
ピロ彦先生が処理量が多い例としてアップしていたfm2を元にFinalFighterが作成しまわしていたBOTが解を導きだす。
最後はピロ彦先生が$0018のコントローラの入力をしてキタ―(゚∀゚)― !!と発言。
ついにわれわれは感動のエンディングを見ることができたのだ。
2010年以来久々の更新がついに完成である!
ディレイオブジェクトFFテク
ロックマンでは特定のマップのある地点を通過すると「0xFF」という番号の見えないオブジェクトが出現することがあります。
例としてアイスマンステージの下記の場所があります。
このオブジェクトはPPUのパターンテーブルのリマップ処理を実行します。
おそらくグラフィックの再構築などに使われているオブジェクトと推定されます。
この処理は通常以下のような手順で動いています。
敵のロード処理 |
|
1フレームの処理量を重くする行動で調整しNMIを敵番号の読み込み処理に割り込ませると下記のような異常な処理となります。
敵のロード処理 |
|
アイスマンステージの画像の箇所では、「ディレイオブジェクトFFテク」を実行すると
従来の「ディレイオブジェクトテク」(バンク5を参照する)では「オブジェクト1、オブジェクト1F」しか出現しなかった場所で、
別の種類のオブジェクトが出現するようになり、0x00~0xFFの全てのオブジェクトが出現するようになります。
オブジェクトのAIのジャンプ先異常
この処理は通常ロックマン1に存在するオブジェクト(00~4Aのオブジェクト)で以下のような手順で動いています。
オブジェクト(00~4A)のAIの処理 |
※0x80以上のオブジェクトの場合はオブジェクト番号-0x80した結果と同様となる。 |
ところが、ディレイオブジェクトテクやディレイオブジェクトFFテクを使うと通常ロックマン1に存在しない
異常な4B~7F,CB~FEのオブジェクトが発生するため下記のような間違いが生じます。
|
例として以前使っていた「ディレイステージクリア(Object75)」の例を見てみよう
オブジェクト75(ディレイステージクリア)のAIの処理 |
|
今回のTASで用いた「オブジェクト55(Object55)」の例を見てみよう
オブジェクト55のAIの処理 |
つまり、$600が実行されるタイミングにあわせてメモリ内容を上手に変化させておくことでファミコンの処理を実行できるのだ。 |
今回のTASの実行手順
今回のTASの実行手順 |
|
LuaScript集
ディレイオブジェクトテクを支援するLuaScriptです。 NEXTの値を1に調整するとディレイオブジェクトテクが成功します。 オブジェクトが出現した場合オブジェクト番号と、オブジェクト番号が読み込まれたアドレス、 出現したフレームが表示されます。 |
ディレイオブジェクトFFテクを支援するLuaScriptです。 オブジェクトFFが出現するところでのみ、各種値が変動します。 NEXTの値を1~33に調整するとディレイオブジェクトFFテクが成功します。 オブジェクトが出現した場合オブジェクト番号と、 オブジェクト番号が読み込まれたアドレス、出現したフレームが表示されます。 |
ディレイオブジェクトテクを支援するLuaScriptです。 そのマップでディレイ量が十分足りたときその行動でオブジェクト番号が、 どの種類のものが出現するか推定します。 また、オブジェクトが出現すると予測される場合のオブジェクト番号と、 オブジェクト番号が読み込まれたアドレス、出現したフレームが表示されます。 ディレイオブジェクトテクでどんなオブジェクトが出現するかの事前調査に使います。 |
ディレイオブジェクトFFテクを支援するLuaScriptです。 オブジェクトFFが出現するところでのみ、各種値が変動します。 そのマップでディレイ量が十分足りたときその行動でオブジェクト番号が、 どの種類のものが出現するか推定します。 また、オブジェクトが出現すると予測される場合のオブジェクト番号と、 オブジェクト番号が読み込まれたアドレス、出現したフレームが表示されます。 ディレイオブジェクトFFテクでどんなオブジェクトが出現するかの事前調査に使います。 モード1と2を変更することができ、モード1では敵アドレスを指すポインタの両方、 モード2では敵アドレスを指すポインタの下位ポインタを変更します。 |
ディレイオブジェクトFFテクの調査に使われた調査スクリプトです SpawnObject オブジェクト番号[X=X座標,Y=Y座標] [ObjectFireDelay][ObjectScreenNumberを読み込んだアドレス:ObjectScreenNumber < $1B]を出力します。 下記のような結果を調査しました。 $8C = 4 : No Object $8C = 5 , $20 < $1B=#0x04 , $21 < $1A : SpawnObject0,3,1,(0x23) $8C = 6 , $20 < $1B=#0x04 , $21 < $1A : SpawnObject3,1,(0x23) 01のObjectFireDelayは00 03のObjectFireDelayは3C 55のObjectFireDelayは00 |
ディレイオブジェクトFFテクに使われたBOTです。 下記のようなテキストをログとして出力します。 BOTを動作させながらディレイオブジェクトFFテクで、 どのアドレスを調整すべきかを調査することができます。 [Rerecord数]->出現したオブジェクト番号 :オブジェクト番号が読み込まれたアドレス [238075]->83 :A538 [238695]->20 :85AC [242295]->20 :85AC [242295]->83 :A538 [243493]->20 :85AC [243493]->1 :1F [243493]->55 :23 |
P.S.
今回のような任意コードを実行するTASをTASVideosでは「ACE(arbitrary code execution,任意コード実行)」と呼んでいます。最近はバグからACEへつなぎエンディングへ飛ぶTASが急増しており、マリオとかでは以下の作品などで実行されています。
本家TASVideosでは、ACEを使わない普通にクリアしていくTASもジャンルとして健在であり、最近では別ジャンルとして分離しつつあります。
ファミコンの場合、このLuaをFCEUXに読み込ませてフリーズやリセットが起きるバグを起こしたときにポーズ(RAM領域の0x00~0x1FFのアドレスが実行される例)があったらそれは今回のTASのような「ACE」の実行の可能性がある有望な例なのです。
アクションやRPGでフリーズやリセットされる再現性があるバグを知っている人、ぜひ試してみてください。もしかしたら任意コード実行の穴を見つけるチャンスかもしれません!
思いつくだけでもロックマン3、ロックマン5、FF3、FF4、DQ5ではフリーズやリセットがかかるバグがありますし、ACEVideos祭りはもう始まっているのかもしれませんね。
そして…ロックマン2にも大幅な更新が見つかっています。
次はロックマン2TASの更新に取り掛かる予定です!
-
次の記事これより新しい記事はありません。
-
前の記事これより過去の記事はありません。