update 2005.03.12

No.03 もじぴったん 可変式ノーウェイト
概要
今回は、当コンテンツの「はじめに」で述べられている、
「PS2DISと平行利用することで作業効率を上げることも可能ですね」
のところを主題にサーチを行います。
本当は、ウチではPS2DISを使ったサーチを扱う予定は無かったのですが、
mixiで少し話題になったので、試しにやってみました。

内容は「もじぴったん」で、ゲーム中にL1ボタンを押すとノーウェイトです。
ウェイトを制御している処理(プログラム)の解析にはPS2DISを使用し、
ボタン入力情報(リアルタイムメモリ)のサーチには拙作Phasteを使うわけですね。

このようにボタンで通常状態とノーウェイトを切り替えることにより、
実機では「速すぎて操作できない」という問題を回避し、「飛ばしたい場面のみ加速」という融通が利き、
PCSX2では「処理が重くて操作しづらい」というスペック上の問題を回避できます。

準備
今回のサーチには以下のものを使用します。
・PCSX2言うまでもなくPS2エミュレータ本体。今回はVer0.7を使用しました。
・Phaste改造コードサーチツール
・PS2DIS「PSのBIOS吸出し」でおなじみのhanimarさん作のツール。PS2改造コードサーチの世界標準
・もじぴったん(ベスト版)SYSTEM.CNFに記載されたバージョンはVER = 1.30
また、PCSX2のパッドプラグインは標準のものをご使用ください。
(バックグラウンドで動作していてもパッド情報を得ることができるため)。

サーチ1)ウェイトを制御している処理を探す
PS2DISで「もじぴったん」のプログラム SLPS_202.59 を開いたら、
解析さんメニューの「逆参照解析さん」を実行します(基本ですな)。

さらに、関数ラベルがいい具合に残っているソフトからラベルを移植するのですが、
(「もじぴったん」ではほとんどのラベルが残っておらず、ウェイト処理も探しづらい)
有名どころとしては「デビルメイクライ」が非常に適しています。
CTRL+Iを押すと、関数ラベル移植元ファイルを指定する画面が出るので、
そのままデビルメイクライのプログラム SLPM_650.38 を選んで開きましょう。
その後、CTRL+Gを押して「ラベルにジャンプ」の関数ラベルのリストを表示してみれば、
今までよりも多くのラベルが表示されていることに気づくはずです。
(特に sce〜 から始まるPS2制御ライブラリが増えるので解析がぐっと楽になります)。

そのまま sceGsSyncV ラベルを探しましょう。
そのラベルをダブルクリックすれば、アドレス0018ae80(sceGsSyncVの処理)に移動できます。
0018ae80 27bdffe0::sceGsSyncV   addui sp, sp, $ffe0
0018ae84 ffb00000               sd    s0, $0000(sp)
0018ae88 ffbf0010               sd    ra, $0010(sp)
0018ae8c 0c062952               jal   $0018a548 (-593▲FNC_0018a548)
0018ae90 00000000               nop
・・・
とまあ、こんな感じで処理が続いています。
もじぴったんの場合、この処理を…
0018ae80 03e00008::sceGsSyncV   jr    ra
0018ae84 00000000               nop
に置き換えてやることでノーウェイト化することが出来ます。
(jr raはリターンアドレス(大抵は呼び出し元)に戻る命令。
 後ろにnopをはさむのは「遅延スロット」のためですが、詳細は各自で調べてください)。
ただし、全てのゲームがこれでノーウェイト化できるわけではないことに注意してください。
sceGsSyncV以外のラベルが使われることもありますし、フリーズしてしまうゲームもあります。
(ナムコのMotoGPはローディング画面以外でこの方法を使うと固まってしまいますね)。

これをそのまま改造コードにするとこんな感じです。
もじぴったんノーウェイト
(Phaste用。生コード)
2018AE80 03E00008
2018AE84 00000000
もじぴったんノーウェイト
(PS2-PAR用。暗号化コード)
9C8F31A8 15F6E79D
9C8F31AC 1456E7A5
なお、PS2-PARで試すときはプログラム領域は1回だけ書き込めば良いので、
Aコード(マスターコード不要)を使っています。

サーチ2)パッド情報を格納しているアドレスを探す
ここからはPhasteの出番になります。
PCSX2で「もじぴったん」を立ち上げたら、PhasteでPCSX2を捕捉してサーチ開始。
ゲーム中に、
「何もボタンを押さずに 00 をサーチ」
「L1ボタンを押しながら 04 をサーチ」
「R1ボタンを押しながら 08 をサーチ」
これで、すぐに該当アドレスが 001a88a0 と 001a88b4 の2つに絞られます。
(要は、ボタンを押した際に変化した値を直接サーチしているわけですね。
 どんな数値が割り当てられているか不明の場合は、増減サーチを使うとOKです)。

これで前者のアドレス 001a88a0 を使うとして、今回の目標は「L1ボタンの状態によって速度を可変」
つまり、条件分岐による通常動作とノーウェイト状態の切り替えのコードを作れば完成ですね。
複雑そうな雰囲気はありますが、これは普通にDコード(判定)で十分、実現できます。

改造コードにすると、こんな感じになります。
L1を押すとノーウェイト
(Phaste用。生コード)
D01A88A0 00000004
2018AE80 03E00008
D01A88A0 00000004
2018AE84 00000000
D01A88A0 00000000
2018AE80 27BDFFE0
D01A88A0 00000000
2018AE84 FFB00000
これ、要するにアドレス001A88A0が
「00000004(L1を押してる)ならばノーウェイトのコードを実行して、
 00000000(何も押してない)ならば本来の処理に書き戻す」

だけだったりします。

てわけで、PS2-PAR用の改造コードはこんな感じ
マスターコードEC87821C 1456E60A
L1を押すとノーウェイト
(PS2-PAR用)
0C8D0BC8 1456E7A1
1C8F31A8 15F6E79D
0C8D0BC8 1456E7A1
1C8F31AC 1456E7A5
0C8D0BC8 1456E7A5
1C8F31A8 39A1B005
0C8D0BC8 1456E7A5
1C8F31AC 61A6E7A5

以下は本編には関係ないオマケです。

詳細情報)ボタン情報格納アドレスについて
L1ボタンを押したときにはアドレス 001a88a0 へ 04 という値の「論理輪(OR)」が入ります。
先ほど「R1を押して 08 をサーチ」としたように、このアドレスには他のボタンの情報も入ります。
2進数で表記すればわかりやすいのですが、
L1ボタン(04)=00000100
L2ボタン(08)=00001000
L1とL2の同時=00001100=(0C)
こんな感じにビット単位の加算によって値が決められているわけですね。
今回は D01A88A0 00000004 (アドレス001A88A0が00000004(L1)ならば〜)というコードを使いましたが、
当然ながらL1とL2を同時に押すとアドレス001A88A0の値が0000000Cになってしまい、不発します。
「もじぴったん」には「同時押し」という概念がほとんど無いので気になりませんが、
シューティングやアクションといった、リアルタイム性・複雑操作を必要とするジャンルでは、
「不発」の頻度も上がるため、少々、使い勝手の悪いコードになってしまいます。

それに対応するためには
「自作処理を空きメモリに展開し、そこでアドレス001A88A0の値をコピーし、
 その値と00000004の論理積(ビットマスク)で不要な情報を払い落としてL1の情報だけを得る」

という手法を要求されます。
そのアプローチを行ったメモはこちら
興味のある方はどうぞ。