PCSX2での60FPS化コードのサーチ方法について

別でプレイ動画を投稿しているサイレン2の改造コードを探しておりました。

と言うのも隠しシナリオの出現条件がタイムアタックをすべて更新すると言う物であり、一からプレイしていたのでは時間がね・・・と言う事で結局欲しいものは見つからなかったのですが

調べている途中でPCSX2のフォーラムにてSiren2(アメリカ版?)は60FPS化できるという書き込みを見つけました。

今更サイレン2を60FPS化する事にはさほど興味はないのですが(練習には良いかも)、出来るなら他のゲームにも適用できたらと思いスレッドを読んでいたところ、サーチ方法が書いてありました。

60 fps codes (pcsx2.net)

とりあえず翻訳して保管

簡易な方法

1.昔ながらのメモリサーチ

チートエンジンなどのメモリエディタを利用する方法です。
この手法は、解析するゲームが30FPSで動く場面と60FPSで動く場面に
分かれているときに適用できるかも

このようなゲームはメモリの中のフラグでフレームレートを切り替えている場合があります。
例えば1の時に60FPSで2の時に30FPSなど
または、0の時にフレームレート制限なし(60FPS動作)1の時に制限あり(30FPS動作)など

つまり30FPSの場面と60FPSの場面を切り替えて、0,1,2のデータの変動を検索すると
当たりのアドレスにたどり着ける場合があります

例:MGS3、ダーククラウド2、キングダムハーツ等

ふむなるほどって感じですね

2.GSレジスタ

PCSX2のデバッガを開き、CTRL-Gのジャンプメニューから
12000000へ飛びます。
12000000から120000A0のアドレスでGSのレジスタを保存しています

12000080や120000A0の64bit値を通常メモリエリア(20000000-22000000)
で検索し、その付近のメモリでフレームリミットアドレスが存在する場合があります。
もし近くに1や2の値があれば、0や1にしてみてください。
例:MGS3、ICO、DQ8

多分自分の中でこうであろうと言うイメージは出来た。1で検索する場合はフレームレートが変動でないとサーチできないが、この手法であれば変動ではないタイトルでもきっとサーチできるってことだと思います。

3.GSレジスタマークⅡ

GSレジスタを使用するが、今回は12000070や12000090のアドレスを使います。
このアドレスでvsyncのカウントをしている場合がある。(なんとなくだけど)

検索については、まず12000090にwrite brakepointを仕掛けます。
すぐにゲームがbrakepointで止まるのでメモリエディタにて初期値不明4バイト整数で
状態をサーチします。
その後デバッガーのRUNボタンで再開すると、次の画面更新(vsync)が行われたときに
再度brakepointで止まるのでメモリエディタにて増加サーチを行います。
これを繰り返して対象を狭めていき、候補として残ったアドレスの付近に
フレームリミットアドレスがある場合があります。

例:ワイプアウト、FF12

まぁ意味は分かるかな

難しい方法

ディスアセンブルしてフレームリミットアドレスサーチ

PS2disを利用しシンボル残り実行ファイルからシンボルを移植しつつ解析を行う。
framelimitとかvsyncとかが見つかればその辺をサーチする
例:ダークラウド2、クロックタワー3

まぁ、PS2の改造コードの検索方法の事ですね。基本的なことは一応理解しているつもり

タイミングアドレスサーチ

さて、次はスピード調整の話です。
フレームリミッターを見つけるのが最初のステップで、それだけで十分な場合もあれば
すべてが2倍速になることもあります。

通常、欧米のゲームはフレームレートとは別にタイミングを計算し、日本の開発者はフレームレートと結びつけます。

3Dグラフィックスでは、実数を用いた乗算や除算が多く行われます。
実数(2.323,76.23など)や浮動小数点数を使った乗除算が多いです。

そのため、通常、私たちは
係数の値が1.0f(16進数で3F800000)のものを探し、これを0.5f(3F000000)にします。
0.5f(3F000000)となり、30fpsモードでは2.0f(40000000)となることもあります。
30fpsモードでは2.0f(40000000)、60fpsモードでは1.0f(3F800000)となることがあります(両方のモードがあるゲームの場合)。

その他の値1/30(3D088889)、1/60(3C888889)、30(41F00000)、60(42700000)または
30(1E) 60(3C)のように整数で直接指定される場合もある。

しかし、この値がRAMになく、直接レジスタに読み込まれることがあります。
MIPSアーキテクチャでは、「lui rn,value」で
その後、フロートレジスタmtc1 rn,fnにロードされます。
例 lui v0,0x3F80, mtc1 v0,f01
lui v0,0x3F80を16進数で表すと3C023F80なので、この値を検索します。
何百個も見つかることもあれば、数個しか見つからないこともあります。
RAMサーチャープログラムで、3C013F00(lui at,0x3F80)を検索すると、すべての値を3C013F00に修正します。
3C013F00(lui at,0x3F80)を検索し、それらを全て3C013F00(lui at,3F00)に修正し、
修正された新しい命令がロードされるように、エミュのインタプリタモードに切り替えます。

その後、インタープリタモードでは全てが遅いので、リコンパイラに戻します。
ゲーム内で何かが遅くなったり速くなったりしていないか確認してください。
時々、エミュがクラッシュしたり、フリーズすることがありますが、これはある命令を修正したためです。

この場合、変更した命令の数を制限して、悪いものを排除してください。
3Cxx3F80(xxは01から1bまでのレジスタの数)の検索を続けます。
例:3C1B3F80(lui k1,0x3F80))。
40000000、41F00000なども同様です。
0x001E(2401001E、実際には0x00001Eで加算されます)
0003c とか、もちろんレジスタのバリエーションもあります。このような場合は
を2401003Cに変更します。一般的な考え方は、値を2倍または半分にすることです。

簡単にまとめますと

フレームリミットを解除できたとしても1秒間に30回のゲーム画面処理が60回処理を行ってしまうとゲームの速度が2倍になってしまうよ。特に日本のゲームはフレームレートとタイマー処理を紐づけている場合が多いのでこうなってします。と

それで速度調整を行う必要が出てきて、それをサーチするときはフロート値で1.0,0.5,60,1/60や整数値で探すと良いって事ですね。

後半はMIPSの基礎が書いてありますのでMIPSは勉強しておきましょう。

見本もあるのでサイレン2で試してみようかな?

コメント

タイトルとURLをコピーしました