DQ3成長限界上昇パッチの拡張3

前回の実装で新規に作成した職業別ステータス最大値構造体から力を取得するSRの定義は終わりました。次にこのSRを45氏が拡張した部分に埋め込みます。

  • SR: $04F82F 力取得
04F82F XBA Exchange A(HighByte) and A(LowByte)
04F830 SEP #$20 m=on(A/M:8b)
04F832 LDA $0011,X A=$0011+X
04F835 AND #$01 A&=#$01
04F837 REP #$20 m=off(A/M:16b)
04F839 XBA Exchange A(HighByte) and A(LowByte)
04F83A JSL $C5FCF0 SR: $05FCF0
04F83E NOP
04F83F NOP
04F840 NOP
04F841 NOP
04F842 RTS return

変更している部分は後半部分です。変更前は$04F839で作成した力の値(9ビット)が500以上かを調べて500以上だったら500を返すという処理をしていました。というわけでこの部分を変更してSR: $05FD4Bを呼ぶように変えます。これで職業別ステータス最大値構造体の力の値でクリップされるようになるはずです。というわけで早速試してみました。

20090509203120.jpg

大丈夫そうですね。というわけで、変更を続けることにします。

  • SR: 0$43450 力変更
043450 JSL $C5FCF0 SR: $05FCF0
043454 NOP
043455 NOP
043456 NOP
043457 NOP
043458 SEP #$20 m=on(A/M:8b)
04345A JSR $F843 SR: $04F843
04345D REP #$20 m=off(A/M:16b)
04345F RTL return

  • SR: $043497 力加算
043497 PHA Push A
043498 JSL $C43442 SR: $043442
04349C CLC c=off
04349D ADC $01,S A+=(Stack($01)+c)
04349F JSL $C5FD4B SR: $05FD4B
0434A3 NOP
0434A4 STA $01,S Stack($01)=A
0434A6 PLA Pull A
0434A7 JSL $C43450 SR: $043450
0434AB RTL return

多分これで問題はないと思います。次は力の種使用時の処理を変更します。

  • SR: $90F6E 力の種使用(移動中)
090F7B JSR $E4AD SR: $09E4AD

力の種はステータスがMAXのときは「しかし なにもおこらなかった」と表示され消費されません。オリジナルではC9 FF 00(255と比較)、成長限界上昇パッチでもC9 F4 01(500と比較)となっていますが、今回は職業別最大値と比較する必要があります。しかし職業別最大値と比較するSRはバンク$05にあるため、呼ぶためには4バイト(#$22 + アドレス3バイト)が必要です。90F6Eの中身全部を別の場所に飛ばしてもいいのですが、容量節約のため「Aの値を職業最大値と比較して最大値未満ならOFF、最大値以上ならONを変えす」というSRを同じバンク$09に定義することにします。

  • SR: $09E4AD 力が職業最大値以上か調べる(以上c=on)(新SR)
09E4AD PHA Push A
09E4AE JSL $C5F84B SR: $05F84B 引数:1#$01 引数:2#$FE 引数:3#$FF
09E4B5 CMP $01,S A==Stack($01)?
09E4B7 BEQ #$05 if(z==on) goto $09E4BE
09E4B9 BCC #$03 if(c==off) goto $09E4BE
09E4BB CLC c=off
09E4BC BRA #$01 goto $09E4BF
09E4BE SEC c=on
09E4BF PLA Pull A
09E4C0 RTS return

ここで1つ問題があることがわかりました。今までのSRではXに「対象キャラクターの先頭アドレス」がセットされていることが前提条件だったために職業アドレスを取得することが容易でした。しかし今回のケースではXにセットされているのは「キャラクターのインデックス」です。従ってこのままでは職業最大値を取得できません。というわけで「キャラクターのインデックスを元にそのキャラクターのデータの先頭アドレスを取得してちからの職業最大値を取得する」SRを実装する必要があります。とはいえ、同様の処理がすでに存在するのでそれをパクれば問題ありません。ここではSR: $05F84Bが期待通りの値を返すとして話を続けます。期待した値がAにセットされて返ってくるので、あらかじめキャラクターの力の値をスタックにPUSHしておきます。そして値を比較するのですが、

A=職業最大値、Stack($01)=ステータス値

となっているのでちょっと処理が厄介です。A>Stack($01)のときにc=onでリターンするようにコードを書く必要があります。

c=off z=関係なし A<Stack($01) c=offをリターン
c=on z=on A=Stack($01) c=offをリターン
c=on z=off A>Stack($01) c=onをリターン

というわけでこの部分は終わりです。続けて力の職業最大値を取得するSRの実装を行います。

  • SR: $05F84B 力の職業最大値を取得(新SR)
05F84B PHP Push P Flag
05F84C PHB Push DB
05F84D REP #$30 m=off(A/M:16b) x=off(X/Y:16b)
05F84F PHA Push A
05F850 PHX Push X
05F851 PHY Push Y
05F852 JSL $C42777 SR: $042777
05F856 PEA #$7E7E Push #$7E7E
05F859 PLB Pull DB
05F85A PLB Pull DB
05F85B LDX #$40B5 X=#$40B5
05F85E JSL $C4289E SR: $04289E
05F862 BCC #$03 if(c==off) goto $05F867
05F864 LDA #$3925 A=#$3925
05F867 TAX X=A
05F868 JSL $C5FE80 SR: $05FE80
05F86C LDX #$40B7 X=#$40B7
05F86F JSL $C428FD SR: $0428FD
05F873 PLY Pull Y
05F874 PLX Pull X
05F875 PLA Pull A
05F876 PLB Pull DB
05F877 PLP Pull P Flag
05F878 RTL return

基本はSR: $043414 力取得と変わらないです。同じようなSRがその周辺に存在します。この手のSRは1バイトずつ3つの引数を取ります(バイナリスレで86氏に教えてもらいました)。1番目の引数はDPのアドレス($01)、FF=Aレジスタ、FE=Xレジスタ、FD=Yレジスタを意味するようで、この場合(SR: $09E4AD中の$09E4AE)では、2番目の引数(Xレジスタ)をもとに結果を3番目の引数(Aレジスタ)にセットして返せという意味のようです。というわけで力の種を投与、すごろくでステータスアップをさせてみて期待通りに動作すればOKです。思わぬところで長くなったので続きは次回。

コメント

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