GUC コードステーション情報
ソフト名 4-2.条件分岐操作系コード編
ソフト品番情報
ソフト対応機種 PS(PlayStaition)
改造対応ツール
投稿者(敬称略) D-RAM【GUC】
投稿者連絡先 mopro@jade.dti.ne.jp
登録日 1999/07/26
更新日 1999/07/26
サーチ環境
コメント 「何か動作がおかしい」とか、「こういうことができるコードが欲しい」
また、「ここはこうするべきでは」等のご意見がありましたら、お手数ですが
D-RAM【GUC】
e-mail mopro@jade.dti.ne.jp
までメールをいただけると大変ありがたいです。


4-2.技術コード作成技法(条件分岐操作系コード編) 次に紹介するのは、条件分岐(BASICのIF文にあたる) を操作してプログラムの流れを変更することによって 様々なことを実現するコードです。 代表例としては、全員の能力値MAX・制限を解除するなどです。 難易度は若干上がりますが、能力値MAXあたりは 比較的やりやすいようです。 なぜ条件分岐の操作で能力値がMAXにできるかは、 次のように考えると分かりやすいと思います。 例えばRPGでは、キャラが強くなって最大HPが999や9999になると、 それ以上は上がらなくなる場合があります。 理由は、最大HPが9999以上になった場合は9999に固定するよう プログラム内で処理されているためです。 言いかえると、最大HPが9999以上の時のみ、 最大HPを9999にする命令が実行されていることになります。 そこの「最大HPが9999以上の時のみ」の条件判定を外してしまえば 常に最大HP9999=最大HPMAXになります。 しかもプログラムを操作しているので、全員分に対応することができます。 欠点は最大HPが増加した時に初めて効果が現れるということです。 既にレベルが最大などの理由で最大HPを増やす手段がない場合だと、 まったく役に立たなくなってしまいます。 この方法が利用できるのは、能力値が一定値以上に上がらなくなる ものに限定されます。 まずはメモリエディットで可能な限り大きい値を入れます。 1バイトならFF(255)、2バイトなら7FFF(32767)、 4バイトなら7FFFFFFF(2147483647) 次に、ゲーム内でその値を増やし、その結果が きりのいい値(10のn乗や9の並び数字)、または変化なしならば 値の上限チェックが効いているので、 ここで初めて条件分岐操作コードの作成に入れるわけです。 蛇足ですが、能力値の上限チェックがない場合、 値が大きくなりすぎてメモリ内に格納しきれなくなり、 正しい値が保持できなくなる現象(桁あふれ)が起こることがあります。 例1:チョコボの不思議なダンジョン2・HPが全回復 RPG系では現在HPを最大HPより大きくしてしまうと ステータス画面で最大HPと同じ値に補正されることがあります。 チョコボ2でも補正されることを利用して、 条件分岐命令の操作で常に現在HPを最大HPと同じ値にしてしまいます。 HBPに監視させるアドレスは 現在HPの値を数値サーチした結果、80101A10。 下準備として、現在HPに最大HPより大きい値を入れる。 HBPの設定 Breakpoint Address:$80101A10 Address Mask :$0FFFFFFF Event :Write Break Count :$0001 この状態でステータス画面を開閉してみると、HBPがブレークした。 HBPの結果 $800645a8 addu a0,a0,v0 ;a0=a0+v0 $800645ac slti v0,a0,#$03e8 ;a0の値と$3e8(1000)を比較し結果をv0に代入 $800645b0 bne v0,zero,$800645bc ;v0がゼロ以外(a0が$3e8未満)ならば ;$800645bcへ分岐 $800645b4 nop ;遅延スロット、何もしない $800645b8 li a0,#$03e7 ;a0に$3e7(999)を代入 $800645bc lh v0,$0000(s0) ;アドレスs0+$0から2バイトの値を符号拡張して ;v1に読み込み $800645c0 nop ;ロード待ち、何もしない $800645c4 slt v0,a0,v0 ;a0の値とv0の値を比較し結果をv0に代入 $800645c8 beq v0,zero,$800645d4 ;v0がゼロ(a0がv0より大きい)ならば ;$800645d4へ分岐 $800645cc sh a0,$001c(s0) ;a0の値をアドレスa1+$1cに2バイト分書き込み >$800645d0 sh a0,$0000(s0) ;a0の値をアドレスa1+$0に2バイト分書き込み $800645d4 li v0,#$0020 ;v0に$20を代入 まず気になるのが、800645acの$03e8と800645b8の$03e7です。 10進数に直すと1000、999になります。 このような数字をプログラム内で見かけた場合は、 値の上限チェックをしている可能性が高いです。 HBPのヒットした場所から、最大HPの上限チェックと考えられます。 そこで、目的とはずれますが先に最大HPの最大化をしてみます。 ここでの最終目的は、800645b8の li a0,$03e7 という数値代入命令が実行されるようにプログラムの流れを変えることです。 すぐ上のほうにbne命令がありますが、これこそが条件分岐命令です。 R3000では一般にbで始まる命令は条件分岐を表します。 bne xx,yy,$80zzzzzz はxxとyyが等しくなければ分岐、 beq xx,yy,$80zzzzzz はxxとyyが等しければ分岐するという意味です。 他にもbltz(xxがゼロ未満なら分岐)、 bgez(xxがゼロまたはそれ以上なら分岐)、 blez(xxがゼロまたはそれ以下なら分岐)、 bgtz(xxがゼロより大きければ分岐)がありますが、 とりあえず覚えておくとあとあと便利です。 800645b0のbne v0,zero,$800645bc これを操作すれば最大HPの最大化ができそうです。 方法としては、 bne zero,zero,$800645bc(0≠0) として条件を成り立たなくするか、 bne v0,zero,$800645b8 として1つ先の命令に分岐させるようにすることが考えられます。 (800645b4は遅延スロットで分岐の有無に限らず実行されるので指定しない) さて、データ変換ですが、例によって2進数で表すと bne xx,yy,$80zzzzzz =000101xx xxxyyyyy zzzzzzzz zzzzzzzz となります。 xxとyyはレジスタの識別番号、 zzzzzzはスキップする命令数で、負の値を指定すれば手前に分岐させれます。 このことから、前者の方法は xx,yyともにzeroレジスタを表す0が入るので、 上位2バイトの下位10ビットをOFFにする。 これに、bne命令を表す000101が上位6ビットに加わるので、 結果は 00010100 00000000 16進数で表すと1400です。 これは、元の命令がbneでもbeqでも同じです。 つまり、条件分岐命令の上位2バイトを1400にするということになります。 後者の方法では、分岐先を変更するので、対象は下位2バイトです。 1つ先の命令に分岐ということで、スキップする命令数0001が入ります。 0000とした場合、遅延スロットに分岐するということで、 分岐した場合、遅延スロットが2度実行されてしまいます。 また、FFFF(-1)とした場合、これは分岐条件を満たした場合、 永久に同じ命令が実行され続けることになります。無限ループです。 特定の条件でゲームをハングさせるのには利用できるかもしれません。 しかし基本的には条件分岐命令の下位2バイトを0001にする、 こう覚えて下さい。 これらのことから、最大HPMAXは、 800645B2 1400 または、 800645B0 0001 となります。 次にHPが全回復するコードに取りかかります。 これはHBPがヒットした部分からさかのぼって、 最初の条件分岐命令に注目すると分かりやすいです。 ここでは800645c8の beq v0,zero,$800645d4 に相当します。 条件分岐命令の分岐先は800645d4、 HBPがヒットしたアドレスは800645d0なので、 分岐しないようにすれば 「現在HPに最大HPの値を入れる」処理が行われることになります。 よって、HPが全回復するコードは、 800645CA 1400 または、 800645C8 0001 でうまくいくと思います。 今回のコードは、場面によって別のプログラム・データがロード されない位置にあるので、誤動作防止のDコードは必要ありません。 見分け方は、ゲーム起動直後のメモリイメージをPC側に保存しておいて、 ゲーム中のメモリイメージとそれをバイナリエディタ等で比較すると 一目でわかります。 一般に若いアドレスほどデータの変化が少ない傾向がありますが、 実際に確認してみないと分からないのが現状です。 ここでは説明しませんでしたが、逆に必ず分岐させたい場合も生じるでしょう。 そういうときは、 beq zero,zero,$80xxxxx(0=0) とすれば必ず分岐するようになります。 データ変換では、 beq xx,yy,$80zzzzzz =000100xx xxxyyyyy zzzzzzzz zzzzzzzz xxとyyにゼロが入るので、上位2バイトを1000に変更となります。 ------------------------------- まとめ 条件分岐操作系コードの作成法 HBPがヒットした部分からさかのぼって、 最初の条件分岐命令(bで始まる命令)について、 (分岐しなくする場合) bne zero,zero,$80xxxxxxに変更 =条件分岐命令の上位2バイトを1400にする または、分岐先を1つ先の命令に変更 =条件分岐命令の下位2バイトを0001にする (分岐させる場合) beq zero,zero,$80xxxxxxに変更 =条件分岐命令の上位2バイトを1000にする いまいち分かりにくい場合は、 「分岐しなくするパターン」と、 「分岐させるパターン」をそれぞれ実行すれば、 どちらかで目的の効果が現れると思います。 能力値MAX系は「分岐しなくするパターン」、 制限解除系は「分岐させるパターン」 になるケースが比較的多いようです。 さて、条件分岐操作系コードですが、 これだけでかなりのことができます。 私が今まで見かけたものを挙げますと、 能力値MAX・体力全回復・無敵・ザコ敵出ない・どこでもセーブ・ おまけ全て閲覧できる・データチェックを外す・起動コード などなどです。



無断転載・無断商用利用・無断直接リンク禁止
ホームページサイト登録はこちらゲーム個別検索登録はこちら