「〜〜増加で即最大」コードだけだと、なんでもMAXになってしまい 「ゲームクリアの補助としてコードを使いたい」という人には ある意味即MAXは使い難いコードになってしまいます。 そこで、数値が即MAXではなく 倍々に増えていくという改造を覚えてみましょう これならちょっとした補助としてコードが使えます サモンナイト3を参考にその方法を見てみましょう。 まず、最大値検索などで最大値チェックの場所を探します 主に最大値チェックをする場合、数値が増えた後 もしくは数値が減った後に最大値を超えてないかチェックするので 最大値チェックを探せば数値加算命令が見つかり易く それを元に増加量倍などのコードを作る事が出来ます。 検索の結果、経験値の最大値チェックの場所が見つかりましたこの画像のうち、最大値チェック手前のaddu命令に注目して下さい レジスタの使い方などからここが経験値加算命令と考えられます ここで早速、経験値倍増に書き換えたい所ですが 命令がギッシリ詰まっていて、尚且つどの命令も無くてはならない物です このままでは経験値倍増改造が不可能・・・ そこで、経験値倍増を空きメモリに書き込んで この場所からそこへ処理が飛ぶように書き換える方法を取ります。 まず、空きメモリの適当なアドレスを決めます とりあえず今回は「000F5000」にしましょう 命令は「j $000F5000」これを数値にします(0803D400) ここへ上の画像の場所から処理を飛ばすように書き換えますが どの命令部分から空きメモリに飛ばすかが重要です sw命令で経験値の値がストアされる前に倍増にする必要があるので そこから上の3つの命令(lwとaddu)のどれかになりますが 遅延スロット(用語集参照)という物を考慮すると 一番上のlw命令から飛ばした方が効率がよさそうです。 実際にこう書き換えてみました 遅延スロットがあるので001FD964のlw命令が 実行されてから000F5000に処理が飛びます。
次に、000F5000から実行させる経験値倍増プログラムを組みます v1レジスタに現在の経験値、a0に加算する経験値が格納されているので a0レジスタの値を倍増させれば経験値倍増になります 倍増させるのにはいくつかの手段がありますが その中でも最もポピュラーな方法の「シフト命令」を使って見ましょう 倍増させるには「左にシフト」させればOKです(短っ) 長々と説明をしていますが(汗) 百聞は一見にしかず、見た目は非常に簡単です 実際に組んだ空きメモリの命令を見て下さい。
lw a0, $81f0(gp) は空きメモリに処理を飛ばすために潰した命令で 空きメモリに飛ばしてすぐに復帰させておきます ここで復帰させなかった場合は不具合が出てしまいます。 sll a0, a0, 1 シフト命令で、a0の値を1ビット左にシフトさせます 1ビット左にシフトさせる度に数値が倍々になっていきます 一番右の整数(10進数)がシフトさせる回数で 一回のシフトで2倍、二回のシフトで4倍、三回のシフトで8倍になります。 j $001fd968 処理を元の場所へ戻す為の命令です 000F5000へ処理を回す特に遅延スロットが実行されてるので その一つ先のアドレスである001FD968へ処理を戻します。 これら全てを纏めてコードにするとこうなります 経験値xxxx倍 9C8A5A88 0C539BA5 9C9AD328 91DA6615 9C9AD32C 145Axxxx 9C9AD330 0C57B96F 0765=2倍 0725=4倍 07E5=8倍 06A5=16倍 0665=32倍