ワイルドアームズ ザ フォースデトネイター

キーワード
相対アドレス
パッドコード
ワークコード
レジスタ
論理積(and)


内容
ACG減らない
Ex.ファイル全ノルマ達成


ACG減らない

かなり遠回りをして作っていると思いますが勘と根性でなんとか出来たのでそのやり方を説明します。
私がとった方法は『パッドの判定をしている箇所を探す』というもの。探した後減少させている処理はすぐ見つかるので
R1を押しているかどうかという処理を探せると後はそれほど大変ではありません。
R1のパッドの値は$0008もしくは$0800。この値から数値検索をするのは引っ掛かる箇所が多すぎるので出来ません。
後からわかったのですがこの$0008もしくは$0800という値はアクセラレイター発動時のパッド処理では
使われていませんでした。

それではどこから探すのか。GCの振り分けの際の処理を先に見つけていたのでこの周辺に
『andもしくはandiと分岐命令』がないか見ていきます。
特定のパッドを押しているかどうかを見分けるために使用されるのがこのand・andiと分岐命令です。例えば

andi v0,v1,$0008
beq v0,zero,$〜
v1レジスタにはパッド情報が格納されている

とあった場合通常のプラス形式であればR1のボタンが押されているとv1には$0008が格納されています。
他のボタンを押していたとしてもR1さえ押していればv0には$0008が格納され分岐しなくなり、
R1を押していなければv0には0が入り分岐する。という形になります。
$0008の部分が変われば対応するボタンも変わる

では$00262940の左ボタンを押して+1される処理を遡ってみていくと次のような箇所がありました。

00262848 lw   a1, $0054(s0)
0026284c lui   a0, $0051        a0=$00510000
00262850 lw   a3, $81b4(gp)
00262854 addiu  a0, a0, $a8a4      a0=$0050a8a4
00262858 lui   v1, $0003        v1=$00030000
0026285c addu  a0, a0, a1
00262860 and   v1, a3, v1
00262864 bne   v1, zero, $00262ee0
00262868 lb   s1, $0000(a0)
0026286c lui   v1, $0004        v1=$00040000
00262870 and   v1, a3, v1             
00262874 beq   v1, zero, $00262958

lw a3, $81b4(gp)のa3と$00040000を論理積して分岐するかしないかという形になっています。
すぐ上の$00030000との論理積が0でなければ分岐。という処理は対応したボタンを押していると
GCから+1している処理にまわらなくなる為無視して下さい。
つまり$00040000が左ボタンの値、lw x, $81b4(gp)のxにパッド情報が格納されているということになります。
ちなみにGCはワークアドレスに参照箇所があるのでそこから参照箇所を検索していくと
振り分けの処理をしている箇所が見つかります。

gpレジスタは1度設定されると値が変わらないそうなので、このlw x, $81b4(gp)を埋め込み
所持金にxの値を表示させるとそれぞれのボタンの値がわかります。
頻繁に通る処理に埋め込めばいいのですが今回は所持金の表示させている箇所に埋め込んでみます

001c44c4 lw   a2, $9784(at)      a2=所持金 
001c44c8 addiu  a0, sp, $0070
001c44cc jal   print          ▼$00240308

このjal $00240308のジャンプ先はシンボル残りのソフトでこの様な形の処理があり、それがprint〜とあったので
これは文字の表示させる処理なのだと思いラベルにprintと書き込んでいます。

xの値はhw単位で見るとこの様になっています。
0001=上
0002=下
0004=左
0008=右
0010=△
0020=×
0040=□
0080=○
0100=L1
0200=R1
0400=L2
0800=R2
1000=L3
2000=R3
4000=SELECT
8000=START
詳しくはコードのページの最後にあるパッド関係のメモを見て下さい。

それではlw x, $81b4(gp)とR1の値である$0200でandしている箇所を探していきます。探し方は$81b4を数値検索すると
$0200よりは引っ掛かる箇所が少ないです。それでも多いですけど…
見つかった$0200を全てR1ではないボタンの値に変えてみますSELECTの$4000に変え、SELECTを押してみます。
するとアクセラレイターが発動しませんでした。
R1を押すと発動するのでlw x, $81b4(gp)はアクセラレイターの発動とは関係ないということになります。
もう1度$81b4を数値検索するとアドレス00145b34にこの様な箇所があります。
sw zero, $81ac(gp)
sw zero, $81b4(gp)
もしかするとここはパッド値の初期化をしているのかもしれないと思い
(これは単なる勘でこの推測があっているわけではありません)、
ここの0をストアしている相対アドレスの値を手当たり次第所持金に表示させてみると
$81ac(gp)で1部のパッドの値が入っているとわかりました。

値はhw単位で見るとこの様になっています。
0404=△
0022=×
0008=□
0011=○
0080=L1
0040=R1
0100=L2
0200=R2
0800=SELECT
1000=START
こちらも上と同じ

それではもう1度lw x, $81ac(gp)とR1の値である$0040でandしている箇所を探し、
また押しても影響のないSELECTの$0800に変えてみます。
コードを使用しSELECTボタンを押してみるとアクセラレイターが発動しました。
ここがアクセラレイター発動の処理です。

00175260 lw   v1, $81ac(gp)            
00175264 andi  v1, v1, $0040
00175268 beq   v1, zero, $00175288
0017526c nop
00175270 lw   v1, $0488(s0)      v1=$0050ad38
00175274 bne   v1, zero, $001752d8
00175278 addiu  v1, zero, $0001     v1=$00000001
0017527c beq   zero, zero, $001752d8
00175280 sw   v1, $0488(s0)      [0050ad38]
00175284 nop
00175288 lw   a0, $0488(s0)      a0=$0050ad38
0017528c addiu  v1, zero, $0002     v1=$00000002
00175290 bne   a0, v1, $001752d8
00175294 addiu  v1, zero, $0003     v1=$00000003
00175298 beq   zero, zero, $001752d8
0017529c sw   v1, $0488(s0)      [0050ad38]
001752a0 lw   a0, $81ac(gp)
001752a4 lui   v1, $0040        v1=$00400000
001752a8 and   v1, a0, v1
001752ac beq   v1, zero, $001752d8
001752b0 nop
001752b4 lw   a0, $0488(s0)      a0=$0050ad38

lw v1, $0488(s0)でアクセラレイターの状況が管理されています。$0001,$0002,$0003それぞれが格納されるように
してみると$0003で終了の様です。$0488を数値検索し$0003がストアされている箇所を探すとここが見つかります。

00175448 lw   a0, $0494(s1)
0017544c addiu  v1, zero, $012d     v1=$0000012d
00175450 beq   a0, v1, $00175480
00175454 nop
00175458 blez  a0, $00175468
0017545c addiu  v1, a0, $ffff            
00175460 beq   zero, zero, $00175480
00175464 sw   v1, $0494(s1)
00175468 addiu  a0, zero, $0007     a0=$00000007
0017546c jal   $00254680
00175470 addiu  a1, zero, $ffff     a1=$ffffffff
00175474 addiu  v1, zero, $0003     v1=$00000003
00175478 sw   v1, $0488(s1)

lw a0, $0494(s1)のa0の値が0以下になると分岐して$0003がストアされる処理を通過しますつまりこのlw a0, $0494(s1)が
ACGの値ということです。
addiu v1, a0, $ffffを潰す。または$00175458で必ず分岐しない様にすることでアクセラレイターを発動しても
ACGが減らなくなります。

この周辺にENCの切り替えボタンR2の値である$0200とlw x, $81ac(gp)でandしている箇所があり、分岐命令を潰して
必ずその部分を通るようにするとENCの切り替えが可能になります。コードの3行目の部分はENCのON,OFF表示を
させるものですが、これは切り換えてストアさせているアドレスに参照箇所があるのでそのアドレスから参照箇所を
検索し、エンカウントブレイクしたフラグがあるかないかの判定を潰して表示させています。

Ex.ファイル全ノルマ達成

ノルマは9種類ありその中で具体的な数値があるものがあります
例えば
アクセラレイターで1500ギャラ以上獲得
ダメージ5万以上与える
バトルで200回以上勝利

この数値を検索するとフラグ管理しているところがあります。
$05dc(1500)で検索すると数カ所しかなくそのうちにフラグに関係ありそうなところはここ

00175798 lh v0, $0136(s1)
0017579c slti v0, v0, $05dc             
001757a0 bne v0, zero, $001757b0
001757a4 addiu a0, zero, $10df      a0=$000010df
001757a8 jal  flag追加          ▼$002054e0

フラグの処理はorで追加。norとand等で除去。andとsltでフラグが立っているかどうかの3種類があります。

002054e0 addiu  v1, zero, $ffff     v1=$ffffffff flag追加(ラベル)
002054e4 beq   a0, v1, $00205560
002054e8 slti  at, a0, $1400
002054ec beq   at, zero, $00205560
002054f0 slti  v1, a0, $08fd
002054f4 bne   v1, zero, $00205518
002054f8 slti  at, a0, $0ce5
002054fc beq   at, zero, $00205518
00205500 nop
00205504 lui   at, $0050        at=$00500000
00205508 sw   a0, $3588(at)      [00503588]
0020550c lui   at, $0050        at=$00500000
00205510 sw   a0, $cf90(at)      [004fcf90]
00205514 nop
00205518 bgez  a0, $0020552c
0020551c andi  a2, a0, $001f
00205520 beq   a2, zero, $00205530
00205524 addiu  a1, zero, $0001     a1=$00000001
00205528 addiu  a2, a2, $ffe0
0020552c addiu  a1, zero, $0001     a1=$00000001
00205530 sra   v1, a0, 5
00205534 bgez  a0, $00205544
00205538 sllv  a1, a1, a2
0020553c addiu  v1, a0, $001f
00205540 sra   v1, v1, 5
00205544 sll   a0, v1, 2
00205548 lui   v1, $0050        v1=$00500000
0020554c addiu  v1, v1, $d2e0      v1=$004fd2e0
00205550 addu  a0, v1, a0
00205554 lw   v1, $0000(a0)
00205558 or   v1, v1, a1             
0020555c sw   v1, $0000(a0)
00205560 jr   ra

この様にどんな処理かわかった場合はその処理の先頭にラベルを貼るとジャンプ命令のアドレスの横にラベルが
表示され、分かりやすくなりますので書き込んでいくことをお勧めします。

フラグの追加に使用されるa0の$10dfこの値のアドレスにいくとデータがアドレスと認識され参照箇所があります
途中2箇所ないところがありますが全てのデータが引っ掛かるわけではないのでこの$000010de〜$000010e6箇所が9種類の
フラグ追加に使用されるa0レジスタの値です。ワークコードだと1行ですみますが他の人と同じになる為出来れば
使いたくないのでプログラムコードで作りました。その他にもビット処理が苦手なので色々と不安だという事もあります

どのタイミングで割り込ませるかは戦闘後にしてみました。ノルマに「戦闘で200回以上勝利」がある為そこのフラグを
追加するかどうかのところにこの様にして割り込ませています。

0020f45c lw   v0, $d0f0(at)      v0=$004fd0f0
0020f460 slti  v0, v0, $00c8            
0020f464 bne   v0, zero, $0020f478
0020f468 nop
0020f46c jal   flag追加         ▲$002054e0
0020f470 addiu  a0, zero, $10e5     a0=$000010e5

000f70d0 addiu  t7, zero, $10de     t7=$000010de
000f70d4 slti  t6, t7, $10e6
000f70d8 nop
000f70dc jal   flag追加         ▼$002054e0
000f70e0 addu  a0, t7, zero       a0=$000010de
000f70e4 nop
000f70e8 bne   t6, zero, $000f70d4
000f70ec addiu  t7, t7, $0001      t7=$000010df
000f70f0 j    $0020f478

戻る