SFCGENEditor 1.1.2リリース

だいぶ更新間隔が空いてしまいましたが、例によって「ダウンロード」ページにうpしてあります。今回の変更点は以下のとおり。

  1. 複合型フィールドの対応
  2. 他内部的な構造の見直し

DQ5ではモンスターのHP、攻撃力などがなぜか分かれて保存されています(上2ビット、下8ビットなど)。これを直感的に参照・変更できるようにするというのが今回の変更の一番の大きいところです。この実装に絡んで内部構造の見直しも行ったため、実装にずいぶんと時間がかかってしまいました(ただ単にやる気が起きなくて投入時間自体も少なかったのですが…)。エラーチェックがまるでザルなので今後はその辺りのケアもする必要もあるのですがとりあえず現状あまりやる気が起きないので後で対応することにします。

プログラムの変更とは別にDQ5の解析も少し進めました。BRKの引数のバリエーションが多く、引数の数まではそこそこ正確に把握できるようになったものの、依然としてその多くは用途が不明のままです。戦闘部分は大枠は解析が進んだので仲間モンスター加入部分の処理がぼんやりとつかめてきました。あの有名な「ひとしこのみ」の実装も場所が特定出来ました。バグ技というよりはデバッグ用に仕込まれたものというのがわかります。

  • SR: 仲間モンスター加入判定(加入c=off)?
1041F6 LDA $208000 A=$100000
1041FA LSR A>>1
1041FB BCS #$2A if(c==on) goto $104227
1041FD BRK #$0B #$40 #$21 goto $000F80 #$0B #$40 #$21
104201 BEQ #$3C if(z==on) goto $10423F
104203 LDA $1010 A=$1010
104206 BEQ #$37 if(z==on) goto $10423F
104208 BRK #$88 #$A6 goto $000F80 #$88 #$A6 待機モンスター数取得
10420B LDA $46 A=DP($46)
10420D CMP #$32 A>=#$32?
10420F BCS #$2E if(c==on) goto $10423F
104211 LDA #$00 A=#$00
104213 BRK #$8A #$DB goto $000F80 #$8A #$DB
104216 LDA $47 A=DP($47)
104218 BRK #$8A #$27 goto $000F80 #$8A #$27
10421B LDA $100F A=$100F
10421E SEC c=on
10421F SBC $46 A-=(DP($46)+!c)
104221 BCC #$04 if(c==off) goto $104227
104223 CMP #$08 A>=#$08?
104225 BCS #$18 if(c==on) goto $10423F
104227 LDA $1117 A=$1117
10422A CMP #$FF A==#$FF?
10422C BEQ #$11 if(z==on) goto $10423F
10422E LDA #$00 A=#$00
104230 BRK #$8A #$78 goto $000F80 #$8A #$78
104233 LDX $46 X=DP($46)
104235 CPX $1117 X==$1117?
104238 BEQ #$07 if(z==on) goto $104241
10423A INC A++
10423B CMP #$10 A>=#$10?
10423D BCC #$F1 if(c==off) goto $104230
10423F SEC c=on
104240 RTS return
104241 BRK #$8A #$76 goto $000F80 #$8A #$76
104244 LDX $46 X=DP($46)
104246 STX $74 DP($74)=X
104248 BRK #$88 #$77 goto $000F80 #$88 #$77
10424B LDX $46 X=DP($46)
10424D STX $71 DP($71)=X
10424F LDA $7E29EA,X A=$7E29EA+X
104253 AND #$0F A&=#$0F
104255 STA $72 DP($72)=A
104257 TAX X=A
104258 BEQ #$44 if(z==on) goto $10429E
10425A LDA $278153,X A=$138153+X
10425E CMP #$02 A>=#$02?
104260 BCC #$1F if(c==off) goto $104281
104262 BNE #$DB if(z==off) goto $10423F
104264 JSL $268D0A SR: $130D0A 所持アイテムチェック(ひとしこのみ判定)
104268 BCS #$4F if(c==on) goto $1042B9
10426A LDA $74 A=DP($74)
10426C ASL A<<1
10426D TAX X=A
10426E REP #$20 m=off(A/M:16b)
104270 LDA $278182,X A=$138182+X
104274 JSL $00953E SR: $00153E 乱数発生?(0~A-1)
104278 CMP #$0000 A==or>=#$0000?
10427B SEP #$20 m=on(A/M:8b)
10427D BNE #$C0 if(z==off) goto $10423F
10427F BEQ #$38 if(z==on) goto $1042B9
104281 JSL $268D0A SR: $130D0A 所持アイテムチェック(ひとしこのみ判定)
104285 BCS #$32 if(c==on) goto $1042B9
104287 LDA $74 A=DP($74)
104289 ASL A<<1
10428A TAX X=A
10428B REP #$20 m=off(A/M:16b)
10428D LDA $278172,X A=$138172+X
104291 JSL $00953E SR: $00153E 乱数発生?(0~A-1)
104295 CMP #$0000 A==or>=#$0000?
104298 SEP #$20 m=on(A/M:8b)
10429A BNE #$A3 if(z==off) goto $10423F
10429C BEQ #$1B if(z==on) goto $1042B9
10429E JSL $268D0A SR: $130D0A 所持アイテムチェック(ひとしこのみ判定)
1042A2 BCS #$15 if(c==on) goto $1042B9
1042A4 LDA $74 A=DP($74)
1042A6 ASL A<<1
1042A7 TAX X=A
1042A8 REP #$20 m=off(A/M:16b)
1042AA LDA $278162,X A=$138162+X
1042AE JSL $00953E SR: $00153E 乱数発生?(0~A-1)
1042B2 CMP #$0000 A==or>=#$0000?
1042B5 SEP #$20 m=on(A/M:8b)
1042B7 BNE #$86 if(z==off) goto $10423F
1042B9 CLC c=off
1042BA RTS return

ざっくりとしか見ていませんが、待機モンスターが50体を超えていたら加入判定はスキップされます。同じ処理が3回繰り返されているのは1体目、2体目、3体目の判定のためのようです。乱数による判定の前に所持アイテムチェックを行い、合致していれば必ず仲間になるようになります。この部分が例の「ひとしこのみ」に相当するわけです。

  • SR: $130D14 所持アイテムチェック(ひとしこのみ判定)
130D14 LDA $7E2056,X A=$7E2056+X
130D18 CMP $268D33,X A==$130D33+X?
130D1C BNE #$0D if(z==off) goto $130D2B
130D1E INX X++
130D1F CPX #$07 X>=#$07?
130D21 BCC #$F1 if(c==off) goto $130D14
130D23 REP #$30 m=off(A/M:16b) x=off(X/Y:16b)
130D25 PLY Pull Y
130D26 PLX Pull X
130D27 PLA Pull A
130D28 PLP Pull P Flag
130D29 SEC c=on
130D2A RTL return
130D2B REP #$30 m=off(A/M:16b) x=off(X/Y:16b)
130D2D PLY Pull Y
130D2E PLX Pull X
130D2F PLA Pull A
130D30 PLP Pull P Flag
130D31 CLC c=off
130D32 RTL return

ちゃんとRAMの解析はしていませんが、どうやら7E2056が先頭のキャラクターのアイテムアドレスの開始位置なのでしょう。$130D33から6バイトは

00 ひのきのぼう
0A とがったホネ
91 しあわせのぼうし
02 こんぼう
3C のこぎりがたな
64 みかわしのふく

となっているので、この順番にアイテムを持っていると確実に仲間になる、ということのようです。しかし、正直残念グラフィックのDQ5はDQ3や6に比べると「変えてやろう」というモチベーションが段違いで沸かないのでどこまで続くかは未定です。モンスター画像やマップのデコードなんかもひと通りやりたい気はあるのですが、DQ5のグラフィックは圧縮されているとのことでデコードするプログラムを書くのも面倒だなあということでモチベーションは絶賛低下中です。ただ、ここしばらくツールの改良ばっかりやっていたわけですが、とりあえずそこそこ必要な機能は実装できたということでまた解析作業に戻れる感じです。そもそもDQ6やDQ5の解析をやっていたのは「AIの挙動を調べて可能であればDQ3にインポートしたい」「一応SFCのDQの解析はひと通りやりたい」というところから始まっていたのですが、最近改めてAI付きのDQをやって実感したのは「ボス戦はともかく、通常戦闘はAI任せだとボタン連打の白痴プレイになるわなあ」ということです。実装する側としては挑むべき壁としてはなかなか魅力的なネタではあるのですが、やっぱり便利なものがあると使ってしまうのは人間の性なので「実装したとして果たしておもろいんかね」というのが疑問として残ります。FC版のDQ4は自分で操作が一切できなかった+学習機能があったので自分の期待した通りの行動を取ってくれると嬉しかったりしたのですが、「命令させろ」があるのが当たり前の現在となってはAIは単なる自分のコマンド入力の手間を省くためのものに成り下がってしまっているという印象しか持てないので、モチベーションが湧きません。しばらくはゆるゆると作業をしようかと思います。