DQ3 固定文字列2バイト化対応1

固定文字列(と勝手に読んでいますが)が移動中メッセージで使われるケースはところどころ存在していて、アイテム名、呪文名、職業名、性格、フローミでわかるフロア名がそれに当たります。固定文字列は1バイト文字コードで記述されているので、当然そのままだと移動中メッセージの2バイト文字でまともに表示できません。

どうやっているかというと当然1バイト文字コード→2バイト文字コードに変換する処理をかませるわけです。固定文字列を移動中メッセージで表示する場合はメッセージに[B2]を使い、メッセージ表示直前に$7EBE77に固定メッセージIDをセットします。

メッセージ例:(転職時のダーマ神官のメッセージ)

メッセージID 開始アドレス 文字列
$0B15 $3E42B5 [D6]なんと [C0]は まだ[AD]いちにんまえの [B2]に[AD]なっていないというに……。[AF][AD]みじゅく者の ぶんざいで[AD]もう 職をかえたいとは[AD]なにごとじゃ![AF]
  • SR:$03E477 転職メイン
$03E4C9 JSL $C4691B SR: $04691B 引数:1#$FE 引数:2#$FE 職業固定文字列ID取得
$03E4CF STX $BE77 $BE77=X

[B2]に限らずこの手の特殊文字(以前はエスケープシーケンスとか読んでましたが呼称を変えます)の動作について真面目に調べてみました。以下の過去記事を更新しています。
https://retrogamehackers.net/dq3-string-002/

この[B2]では何をやっているかというと、固定文字列のデコードです。

  • SR:$01B75C 文字列特殊処理_SR_0007 ([B2]固定文字列ID)
$01B75C JSR $B998 SR: $01B998 $BE59に$FFFFをセット
$01B75F LDA $BE77 A=$BE77
$01B762 STZ $BDFB $BDFB=#$00
$01B765 LDX #$0000 X=#$0000
$01B768 JSL $C1BA53 SR: $01BA53 固定文字列開始アドレス取得(オフセットをYにセット)
$01B76C JSL $C1BACC SR: $01BACC 固定文字列デコード+オフセットインクリメント
$01B770 STA $BDFD,X $BDFD+X=A 別バッファに固定文字列を展開
$01B773 CMP #$00AC A==#$00AC?
$01B776 BEQ #$04 if(z==on) goto $01B77C
$01B778 INX X++
$01B779 INX X++
$01B77A BRA #$F0 goto $01B76C
$01B77C LDA #$00AB A=#$00AB
$01B77F STA $BDFD,X $BDFD+X=A
$01B782 LDA #$0001 A=#$0001
$01B785 STA $BDF5 $BDF5=A 別バッファの文字を表示するフラグON
$01B788 RTL return
  • SR:$01B024 1バイト文字を2バイト文字に変換?
$01B024 LDA $BDF5 A=$BDF5
$01B027 CMP #$0001 A==#$0001?
$01B02A BNE #$0F if(z==off) goto $01B03B
$01B02C LDX $BDFB X=$BDFB
$01B02F LDA $BDFD,X A=$BDFD+X
$01B032 INX X++
$01B033 INX X++
$01B034 STX $BDFB $BDFB=X
$01B037 JSR $B078 SR: $01B078 1バイト文字を2バイト文字に変換?
$01B03A RTS return
  • SR:$01B078 1バイト文字を2バイト文字に変換(コア)
$01B078 AND #$00FF A&=#$00FF
$01B07B CMP #$00AB A>=#$00AB?
$01B07E BCC #$05 if(c==off) goto $01B085
$01B080 CMP #$00C9 A>=#$00C9?
$01B083 BCC #$06 if(c==off) goto $01B08B
$01B085 ASL A< <1
$01B086 TAX X=A
$01B087 LDA $C10CD5,X A=$010CD5+X 小フォント→大フォント変換
$01B08B RTS return

固定文字列の文字を$7EBDFD- に1文字2バイトで展開して、変換テーブル($010CD5-)で大フォントでの対応する文字IDに変換して表示しているということのようです。

この仕組みを踏まえた上で、固定文字列の一部を大フォントを使って表現できないかということに思い至りました。一番楽なのは、固定文字列IDから1バイト文字列のデコードをする直前で「固定文字列(2バイト文字)」に差し替えてデコードするというアプローチです。長くなったので続きはまた次回。