エンカウント無し 良くあるエンカウントの仕方は 1・予め決められた歩数(距離)を現在数が越えるとエンカウント 2・敵オブジェに接触するとエンカウント の2つがあります、今回のテイルズは前者で ゼノサーガや.hackシリーズなどは後者に当たります これを頭に入れておいて読み進めてください。
注・以下の記事はかなり前に作成した物を殆ど手を加えず掲載しています。 記事内ではワークアドレスをセーブデータから突き止めていますが 実際には違う手法でワークアドレスを特定していた可能性もあるので セーブデータ比較の部分は参考程度でお読み下さい。 テイルズオブリバースでは敵オブジェは存在しません なので歩数(距離)でエンカウントをしてると考えられます その歩数を調べるのに今回はセーブデータ比較をします。 まずエンカウント直後のセーブデータを1つ、少し歩いたセーブデータを1つ作成し お互いのセーブデータを比較して数値に違いがあるアドレスを探して行きます。 それを繰り返した結果、PS2のメモリアドレスで言うと 「00236438」にその歩数が格納されてる事が分かりました ここをコードで0にするとエンカウントしなくなります。 「エンカウント無し」ならこれで完成なのですが どうせならパッドで操作出来るようにしましょう。 リバースの実行ファイルを開いて 「00236438」を参照しているプログラムを検索して行くと 0012D000周辺でのみ使用されている事が分かりました。 歩数のワークアドレスの参照先を調べているので どこかで歩数を増加させている命令が存在するハズです 検索に引っかかる場所を詳しく見ていくと この画像の場所が歩数を増加させてるように読み取れます。0012D2A0のaddu命令が歩数を増加させているようなので 「addu a0, a0, v0」を「addu a0, zero, zero」と書き換えて 歩数を常に0にするようにしましょう これでプログラム面からエンカウント無しが出来ます。 後はパッドコードを使用して 「addu a0, a0, v0」と「addu a0, zero, zero」 を切り替えればエンカウント無し(切り替え版)が出来ますが ここでもうちょっとだけ作り込む事にします。
良く見ると「00236434」からロードした値と 歩数の値を比較している命令が「0012D2A8」に存在します。 わざわざ現在歩数と比較しているという事は 「00236434」はエンカウントまでの歩数ではないかと考えられます ワークアドレスも近いのでこの状況から考えると確実です。 それらを踏まえて改めてプログラムを見てみると0012D29C lw v0, $36b8(v1) 現在歩数の値をv0レジスタへロード 0012D2A0 addu a0, a0, v0 現在歩数(v0)と今歩いた歩数(a0)を加算してa0レジスタへ格納 0012D2A4 lw v0, $36b4(v1) v0レジスタへエンカウントまでの歩数をロード 0012D2A8 sltu v0, a0, v0 現在歩数(a0)とエンカウント歩数(v0)を比較して結果をv0へ格納 0012D2AC beq v0, zero, $0012d2bc v0の値が0なら分岐、1なら分岐しない 現在歩数がエンカウントまでの歩数を超えてるとv0には0 超えていない場合は1が格納されている。 つまり、エンカウントする時は分岐命令で分岐するという事です 分岐後の処理は現在歩数にエンカウントまでの歩数をストアし 同じ値になるように調整していたりします。 (0012D2C0〜0012D2C4) 分岐命令で分岐すればエンカウントする仕組みなので ここを細工して、普段はエンカウントしないのに 特定のボタンを押した時だけエンカウントするようにします。 scePadPortOpenを利用して「002425C2」が マイナス形式のアドレスであると調べてあったので このアドレスを利用します、プラス形式は必要ありません。 早速ですが、完成した物はこちらです
0012D29C movn a0, zero, ra 現在歩数(a0)にzeroを転送して歩数をリセットする 0012D2A0 lui v0, $0024 0012D2A4 lhu v0, $25c2(v0) v0レジスタにパッド情報をロードする 0012D2A8 andi v0, v0, $xxxx パッド情報と$xxxxの値をandする xxxxにはエンカウントさせたい時に押すボタンの値を入れます 基礎知識のパッド情報の項目で紹介しているマイナス形式の値 この値を入れてください、□なら8000、R2なら0200です。 andi命令で使うボタンを□とした場合を例にすると lhuでロードした値が、例えばキー上を押して移動した場合はFFEF □を押しながらキー上で移動した場合は7FEFになります。 この値を8000でandするとどうなるかと言うと キー上だけを押して移動した場合は、ANDすると8000という値が算出され □を押しつつ移動した時だけは0000が算出されるようになります。 言い方を変えると、他のどんなボタンを押していても □を押さない限りはv0には8000しか格納されないという事です。 □を押してるとv0には0が入るので分岐命令で分岐する 押していないと8000になるので分岐しない つまりandiの値でエンカウント操作が出来るという事です。 これでエンカウント無し(改良版)の完成です 9C8555C4 143F07A0 9C8555C8 2054E7C1 9C8555CC 88940AE7 9C8555D0 249467A5 □を押しながら歩いた時のみエンカウント。 ちなみに、見付けたパッドアドレスがプラス形式の物だった場合は andiの$xxxxをプラス形式で加算する値(□なら0080)にして 分岐命令もbeqからbneに変更して下さい andiの性質上、分岐命令も変更しなければいけません。 このあたりの値の変化は経験を積まないと分からないと思うので ある程度、自分で狙ったコードが探せるようになってから試してみて下さい。