DQ6 Extended(拡張ベースパッチ)作成にあたっての考慮点2

DQ6 Extendedの作成はモンスターレコードの上限を+256にする部分が一番厄介だったものの、サイズの大きいデータの移動は終わっており、残すは本丸のアイテムレコードの上限を+256にする部分以外はだいたい終わったりしています(ショップやおしゃれな鍛冶屋のアイテムを9bit対応するのは先駆けて終わっています。こっちのほうが楽)。思ったより作業速度が早いのはバイナリwikiの(おそらく)45氏によるドキュメントのお陰でどこに何があるかはだいたいわかるので助かっているというのもあります。先人の知識の蓄積に感謝します。

アイテムの拡張はセーブデータをオリジナルと非互換にして拡張する必要と思われるので正直あまり気が進まず、とりあえず今作業ができているところまででテストプレイをちんたらやっているところです。自分の作ったインターフェース改良パッチを当てたいところですが、単体で問題がないことを確認することも兼ねてグッと我慢してオリジナルのままやっていますが、まあ使いづらい。アイテムを渡しても装備してくれないし、いちいちアイテムを使うとウィンドウは閉じちゃうし、ふくろからアイテムを直接実行できないし、全ウィンドウクローズもないのでステータスを見ている途中でウィンドウを閉じれないし。このへんはDQ6 Extendedベースならいくらでもいじれるので(領域もあるし、ウィンドウも新規定義可能なのでやりたい放題)、ゲーム性を変えるパッチを作る暁にはDQ6 IFIMPをベースにDQ3レベルまで持って行きたいなと思うところです(DQ6 IFIMPも細かいところで使い勝手はDQ3オリジナルには及びません)。とはいえ、DQ6はもともと使っているROMの容量がDQ3よりかなり多いので、空き領域はそれほど多くないです。今回いろいろ調子に乗って各固定長のレコードサイズを増やしましたが、残りは可変長のデータ(スプライトグラフィックやらマップ実データ)やプログラムのためにある程度空けておく必要があります。

今回一つの山だと思っていたのは「移動中メッセージをハフマン圧縮を解凍した状態でROMに書き戻し、さらにROM中の移動中メッセージのデコードプログラムも合わせて変更する」点でしたが、意外とあっさり終わってしまいした。ハフマン圧縮を解凍するのはSFCGENEditorのDQ6プラグインですでにできていたので、解凍した状態の文字列をバイナリ変換して本体、インデックスをバイナリファイルに書き出すという作業を行い、ROMの適当な場所に埋め込みます。次にメッセージデコードSRを変更し、ハフマン木を参照せずにそのままデコードするように変えます。この辺はDQ3 Extendedの該当部分を参照し、真似しただけです。メッセージインデックスは$122300-に、メッセージ本体は$123200-に移動してあります。

  • SR: $002B69 メッセージインデックスから開始アドレスを取得
002B69LDA $5998A=$5998
002B6CAND #$0007A&=#$0007インデックスは8毎なのでターゲットのメッセージの頭出しの回数を取得
002B6FSTA $5A1E$5A1E=A
002B72LDA $5998A=$5998
002B75LSRA>>1
002B76LSRA>>1
002B77LSRA>>1
002B78PHAPush A
002B79ASLA< <1
002B7AADC $01,SA+=(Stack($01)+c)
002B7CTAXX=Aインデックスの該当位置を決定
002B7DPLAPull A
002B7ELDA $D22300,XA=$122300+Xインデックスの指す開始アドレスを取得
002B82STA $A0DP($A0)=A
002B84LDA $D22302,XA=$122302+X
002B88AND #$00FFA&=#$00FF
002B8BSTA $A2DP($A2)=A
002B8DLDA $A0A=DP($A0)
002B8FCLCc=off
002B90ADC #$3200A+=(#$3200+c)インデックスのアドレスから本体のアドレスを取得
002B93STA $A0DP($A0)=A
002B95LDA $A2A=DP($A2)
002B97ADC #$00D2A+=(#$00D2+c)
002B9ASTA $A2DP($A2)=A
002B9CLDA $5A1EA=$5A1E
002B9FBEQ #$12if(z==on) goto $002BB3
002BA1JSR $2BD4SR: $002BD4メッセージ1文字読み出し?
002BA4CMP #$00ACA==#$00AC?
002BA7BEQ #$05if(z==on) goto $002BAE
002BA9CMP #$00AEA==#$00AE?
002BACBNE #$F3if(z==off) goto $002BA1
002BAEDEC $5A1E$5A1E–
002BB1BRA #$E9goto $002B9C
002BB3RTSreturn

メッセージのインデックスは8個ごとに設定されているので、ターゲットのメッセージの開始位置を特定するには、8で割った商の位置にあるアドレス(これが直近の8で割り切れるメッセージの開始位置)を取得してから8で割った余りの分だけデコードを繰り返し、区切り文字が出てきたら1カウントするようにしてターゲットのメッセージの位置を特定します。これにより、頭出しのためのデコードにかかる手間は最大6?メッセージ分ということになり、メッセージ表示にかかる時間をある程度の範囲内に収められるということになるようです。

  • SR: $002BD4 メッセージ1文字読み出し?
002BD4LDA $59AEA=$59AE
002BD7CMP #$0001A==#$0001?
002BDABNE #$0Fif(z==off) goto $002BEB
002BDCLDX $59B4X=$59B4
002BDFLDA $59B8,XA=$59B8+X
002BE2INXX++
002BE3INXX++
002BE4STX $59B4$59B4=X
002BE7JSR $2C28SR: $002C28
002BEARTSreturn
002BEBLDA $A0A=DP($A0)
002BEDSTA $5BDC$5BDC=A
002BF0LDA $A2A=DP($A2)
002BF2STA $5BDE$5BDE=A
002BF5LDA $A0A=$(DP[$A0])
002BF7INC $A0DP($A0)++
002BF9BNE #$02if(z==off) goto $002BFD
002BFBINC $A2DP($A2)++
002BFDINC $A0DP($A0)++
002BFFBNE #$02if(z==off) goto $002C03
002C01INC $A2DP($A2)++
002C03RTSreturn

このSRは現在アドレスをインクリメントしながらメッセージを1文字ずつ読みだして返しているようです。このSRをコールしているSRで頭出しの判断をしているようです。ハフマン木の参照がなくなった分シンプルになっています。正直これだけの変更でなんで未圧縮のデータが読めているのかいまいち不明ですが、オリジナルのDQ3とDQ3 Extendedの関連部分を比較する限り、他に変更している箇所は見当たりません。気持ち悪いですが、とりあえず解析は後回しにします。

スポンサーリンク

コメントを書く

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