DQ6ルイーダ熟練度表示バグの解析(完全版)

以前下記のエントリで不完全に直したつもりになっていましたが、改めて調査をして原因がわかりました。

DQ6 ルイーダ熟練度表示バグの解析(不完全版)
相変わらずrcで止まっているDQ6インターフェース改良パッチですが、ルイーダの酒場での熟練度表示バグについて説明して欲しいというコメント...

結論から言うと前回の修正は直した「気」になっていただけで正しい変更法ではありませんでした。改めて不具合の内容については下記の動画を見てください。

問題としては軽微で「ルイーダに預けている仲間の職業熟練度の表示(熟練度の☆の部分)が別のキャラクターのもので表示される」というものです。データが破壊されているわけでもなく、仲間にして表示すると正しい内容で表示されます。

まずルイーダに預けている仲間の職業熟練度表示は以下のSRで処理されています。

  • SR:$0328D0 ウィンドウ_描画SR_001F
0328D0JSL $C3736CSR: $03736C
0328D4LDX $386EX=$386E
0328D7JSL $C43674SR: $043674 引数:1#$03 引数:2#$FE
0328DDLDA #$0070A=#$0070
0328E0JSL $C383FESR: $0383FE
0328E4LDA #$0070A=#$0070
0328E7JSL $C37C95SR: $037C95
0328EBLDA #$0092A=#$0092ルイーダ待機中の仲間の職業熟練度表示(職業名)
0328EEJSL $C37C95SR: $037C95
0328F2LDA #$0093A=#$0093ルイーダ待機中の仲間の職業熟練度表示(熟練度)
0328F5JSL $C37C95SR: $037C95
0328F9LDA #$008AA=#$008A
0328FCJSL $C37C95SR: $037C95
032900LDA #$0003A=#$0003
032903JSL $C37C95SR: $037C95
032907LDX #$0001X=#$0001
03290AJSL $C37854SR: $037854
03290EPLBPull DB
03290FREP #$30m=off(A/M:16b) x=off(X/Y:16b)
032911PLYPull Y
032912PLXPull X
032913PLAPull A
032914PLPPull P Flag
032915RTLreturn

大体は移動中のつよさ表示処理中で呼び出される職業熟練度表示処理SR: $0337DCと同じなのですが、$0328EC、$0328F3でセットしている値が、#$0092、#$0093と異なります。まだ完全には把握できていませんがDQ6のウィンドウ描画処理は「ウィンドウに描画したい項目のIDをセット→後でセットされたIDに対応する項目を一括描画」という手順らしく、実際の描画はSR: $037854がコールされるまでは行われません。この点逐次描画処理をやっているDQ3とは実装が異なります。当たり前ですが、後発のDQ3のほうがベースはDQ6を使っているものの、各所の実装もかなり洗練されている感があります。散々DQ3の実装に慣れてからDQ6を見るといろいろ不便に感じるところは多いです。

さて、動画を見てもらうとわかりますが、正しくない情報を表示しているのは「職業熟練度」のほうだけです。「職業名」自体は問題ないことがわかります。次に#$0092、#$0093コールされるSRを見てみます。

  • SR:$03A4D3 ウィンドウ描画処理アドレスリスト_SR_0092
03A4D3LDX $3868X=$3868
03A4D6JSL $C42C26SR: $042C26 引数:1#$03 引数:2#$FE 引数:3#$FD指定位置のキャラクターID取得
03A4DDJSL $C42DB2SR: $042DB2 引数:1#$FD 引数:2#$00 引数:3#$FE指定キャラクターIDの並び順取得
03A4E4STX $3868$3868=X
03A4E7BRL #$FE7Bgoto $03A365

このSRがコールされた時点で$7E3868には選択したキャラクターのウィンドウ中のインデックス(待機中の一番最初の仲間が0)がセットされています。これを元に最終的にはパーティメンバーも含めた何番目に相当するのかを調べて$7E3868にセットしなおしてやるという処理をしています。SR: $042C26のようなSRはDQ3にもありますが、「1番目の引数のモードで」「2番目の引数の値のインデックスを」「キャラクターIDに変換して3番目の場所にセットして返す」という意味です。キャラクターIDというのは$08BD12-に定義されている主人公が1、ハッサンが2…のIDのことです。#$FFならAレジスタ、#$FEならXレジスタ、#$FDならYレジスタ、それ以外ならDP($??)にセットされて返ってきます。この辺の解釈はDQ3、DQ6で共通なので知っておくとSRの理解がかなり進みます。自分も最初は何のことやらさっぱりわかりませんでしたが、今となってはそこそこ自在に操れます(他に使いどころがないのが笑えますが)。SR: $042DB2は「1番目の引数のキャラクターIDを」「2番目の引数のモードで」「3番目の引数に(モードに応じた)並び順等を返す」という意味のようです。モードについてはバリエーションが8つあるようです。なお、このSRの後は通常の職業熟練度表示処理(職業名のみ)に飛ばし表示処理をしているようです。これ自体は何も問題はありませんが、問題は次のSRです。

  • SR:$03A4EA ウィンドウ描画処理アドレスリスト_SR_0093
03A4EALDX $3868X=$3868
03A4EDJSL $C42C26SR: $042C26 引数:1#$03 引数:2#$FE 引数:3#$FD
03A4F4JSL $C42DB2SR: $042DB2 引数:1#$FD 引数:2#$00 引数:3#$FE
03A4FBSTX $3868$3868=X
03A4FEBRL #$FF74goto $03A475

この後のジャンプ先は今度は職業熟練度の表示(☆マークの方)に飛ばしています。同じことやってるだけなんだから別にいいじゃん、とぱっと見思ってしまうのですが、実はこのSRが呼ばれた時点で$7E3868にはSR: $03A4D3ですでに変換された値がセットされたままなのです。これをウィンドウ中のIDとして再度変換しているので、実質1ページ後ろのキャラクターを指してしまう(正確にはパーティメンバーの数によって変わると思いますが)ということになります。結論として、どう直すのが正しいかというと

  1. SR: $03A4EAの先頭で間の変換処理を挟まずにすぐに$03A4FEにジャンプしてしまう
  2. 変換自体が不要なので、通常のキャラクターの職業熟練度描画用のID(#$0090)を$0328F3でセットしてしまう

のどっちかということになります。キャラクターの情報の管理の仕方についても触れようと思ったのですが、非常に重要な部分なのでまた別途(投稿予定は未定)とします。

スポンサーリンク

コメント

  1. マジックソース より:

    さっそく完全版の修正法を試してみました。ばっちり表示されました。
    実害はないバグとはいえ、育成キャラを眺めてニヤニヤしたいプレイヤーにはありがたいですよ!

    管理者より返信:

    この変更はDQ6 Extended対応のインターフェース改良パッチにも含める予定です。

コメントを書く

メールアドレスが公開されることはありません。コメントは管理者の承認後表示されます。