FF2 の script を調べた

他の作業がスランプのためファミコンソフトの解析をしてごまかしてます...

script data の解析

エンディング呼び出しだけ調べてましたが他のも調べました.

data 0x00 から 0xbf (1 byte)

キャラの移動と方向転換、あとは初期化ができるかもしれません.

databit
7:4 chara ID
3   ?
2   move flag (0:move, 1:方向転換のみ)
1:0 direction (0:right, 1:left, 2:down, 3:up)

bit 3 = 1 は初期化に使ってるようですが情報量が少なすぎるのでスクリプトだけではできない気がします.

data 0xc0 から 0xcf (1 byte)
databit
7:4 chara ID 0xc
3   mode
(bit 3 == 0 のときは data 0x00 から 0xbf と同じ)
(bit 3 == 1 のとき)
2:0 button を押したことにするためのコード

chara ID 0xc はプレイヤーを操作しますが、bit 3 == 1 のときは address $0020 を操作してます. 最初のヒルダに会うところとか定期航路での操舵とか聖堂での蘇生後に出る配置用メニューで使われています.

0xc8 は A ボタンを押したことにする操作でしたが、これで会話相手がいるといと event ID #1 が強制実行されたり、会話相手が各種店員だと想定外のことを言ったりしました. このバグの利用はできなさそうです.

data 0xd0 から 0xdf (1 byte)

address $6012-$6013 の data を 1 bit 単位で反転します.
エンディングが呼び出せるので相対的に重要ではないと感じています.

databit
7:4 0xd
3   byte offset
2:0 bit number

address $62bb (宿屋のイベントID 兼 ブリンクの本の武器としての熟練度経験値), data 0x5c の場合、スクリプトが address $6011 (セーブした外のY座標)から実行できますので、任意の 3 byte を生成するにはこれが利用できます. しかし address $6011 の操作にはその場所まで行くのがかなりの手間です.
さらに address $6012-$6013 のゲームの進行中のフラグの管理で操作するとアルテアの町が破壊されて宿屋が減ることを確認しています.

data 0xe0 から 0xef (1 byte)
e0 shake the screen
e1 run battle ship
e2 break battle ship
e3 light off screen?
e4 dance
e5 ???
e6 flash the screen
e7 go to epilogue
e8 sleep; wait key input
e9 tsunami
ea-ec swap backup chara status and chara #3
ed copy chara #3 to backup chara and add Lyla
ee add Leon to chara #3
ef remove chara #3?
  • e1-e3 はスクリプトが続行できないような動きでした.
  • ea-ec は実行アドレスが同じで違いはないみたいです.
  • ea を2度実行するとフラグだけで消えてる初期型レオンにいさんを追加
  • ed は#3にいるキャラを一旦離脱用に退避してレイラを追加
  • ee は後期型レオンにいさんを追加(上書き)
  • 他のキャラはスクリプトから呼べない
data 0xf0 から 0xf8 (2 byte)

引数が 1 byte あります. 各引数は想定値が大きくないものもあるので、変な値をいれるとちょっとおかしくなりますが、致命的なものはなさそうです.

f0 xx show message
f1 xx teleport to outside
f2 xx teleport to inside
f3 xx start battle
f4 xx same command f2
f5 xx set music
f6 xx bit flag set for address $6040-$6043
f7 xx bit flag clear for address $6040-$6043
f8 xx wait xx frames
data 0xf9 から 0xfc (2 byte)

1つ前に実行した移動系コマンドを引数の数繰り返します.
移動系以外をいれると無限ループになってしまうようです.

jump table で実行する PC がすべて同じで違いはないようです(自信なし).

data 0xfd (1 byte)

場所のスタックを pop します. デジョンレベル1と同じです.

data 0xfe (1 byte)

無限ループしてしまうようです. (data 0xff と同じ処理に見えるのですが...)

data 0xff (1 byte)

スクリプト終了で通常操作に戻ります.

TAS の説明の補足

宿屋で「はい」を選ぶときに address 0x0020 の data を 0xe7 にするとエンディングにいけるのは事実なのですが、動作の詳細が私の想定外でしたので記載します.

現状では script system は address 0x0020 を読み、その次の address 0x0021 の data が 0xe7 だったのでエンディングにいけます. address 0x0020 は「いいゆめを...」の反応のときに押すキーで、ここで引数をもつ script data をいれると address 0x0021 はコマンドとしては無効になります.

「いいゆめを...」のところは一旦ボタンを全部離してからなにか押すと動作が進みます. ボタンを1こだけ押すとなにかの移動コマンドになるので重要ではないのですが、ここに data 0xe4 をいれると宿屋のスタッフが踊ったあとエンディングにいけます. ただし指定したボタンを1度に(16.6ms 単位の精度で)全部押す必要があるので手動ではかなり厳しいです.

address 0x0021 は START, SELECT, B,A に関してはOFF->ON のトリガ検出のためのバッファで、方向は上下や左右の同時押しを解消しているプログラムになっているのは確認しましたがちょっと意味がわかりませんでした. そのために入力値にはいくつか制限があります.

bit7 は A ボタンのため 1, bit6:4 は自由, bit3:0 はよくわからないのですが入力可能値は 5 6 7 9 A B D E F の 9 通りです. 引数にあまり自由をもたせられないことになります.

つまり TAS の最後のボタン入力に何かしら演出をいれるとエンディングの発生が伸びますが、TAS としては終わっているので入力時間は変わらないことになります.