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

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

  • SR: $04F82F 力取得
04F82FXBAExchange A(HighByte) and A(LowByte)
04F830SEP #$20m=on(A/M:8b)
04F832LDA $0011,XA=$0011+X
04F835AND #$01A&=#$01
04F837REP #$20m=off(A/M:16b)
04F839XBAExchange A(HighByte) and A(LowByte)
04F83AJSL $C5FCF0SR: $05FCF0
04F83ENOP
04F83FNOP
04F840NOP
04F841NOP
04F842RTSreturn

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

20090509203120.jpg

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

  • SR: 0$43450 力変更
043450JSL $C5FCF0SR: $05FCF0
043454NOP
043455NOP
043456NOP
043457NOP
043458SEP #$20m=on(A/M:8b)
04345AJSR $F843SR: $04F843
04345DREP #$20m=off(A/M:16b)
04345FRTLreturn

  • SR: $043497 力加算
043497PHAPush A
043498JSL $C43442SR: $043442
04349CCLCc=off
04349DADC $01,SA+=(Stack($01)+c)
04349FJSL $C5FD4BSR: $05FD4B
0434A3NOP
0434A4STA $01,SStack($01)=A
0434A6PLAPull A
0434A7JSL $C43450SR: $043450
0434ABRTLreturn

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

  • SR: $90F6E 力の種使用(移動中)
090F7BJSR $E4ADSR: $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)
09E4ADPHAPush A
09E4AEJSL $C5F84BSR: $05F84B 引数:1#$01 引数:2#$FE 引数:3#$FF
09E4B5CMP $01,SA==Stack($01)?
09E4B7BEQ #$05if(z==on) goto $09E4BE
09E4B9BCC #$03if(c==off) goto $09E4BE
09E4BBCLCc=off
09E4BCBRA #$01goto $09E4BF
09E4BESECc=on
09E4BFPLAPull A
09E4C0RTSreturn

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

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

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

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

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

  • SR: $05F84B 力の職業最大値を取得(新SR)
05F84BPHPPush P Flag
05F84CPHBPush DB
05F84DREP #$30m=off(A/M:16b) x=off(X/Y:16b)
05F84FPHAPush A
05F850PHXPush X
05F851PHYPush Y
05F852JSL $C42777SR: $042777
05F856PEA #$7E7EPush #$7E7E
05F859PLBPull DB
05F85APLBPull DB
05F85BLDX #$40B5X=#$40B5
05F85EJSL $C4289ESR: $04289E
05F862BCC #$03if(c==off) goto $05F867
05F864LDA #$3925A=#$3925
05F867TAXX=A
05F868JSL $C5FE80SR: $05FE80
05F86CLDX #$40B7X=#$40B7
05F86FJSL $C428FDSR: $0428FD
05F873PLYPull Y
05F874PLXPull X
05F875PLAPull A
05F876PLBPull DB
05F877PLPPull P Flag
05F878RTLreturn

基本は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をコピーしました