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

どうやっているかというと当然1バイト文字コード→2バイト文字コードに変換する処理をかませるわけです。固定文字列を移動中メッセージで表示する場合はメッセージに[B2]を使い、メッセージ表示直前に$7EBE77に固定メッセージIDをセットします。
メッセージ例:(転職時のダーマ神官のメッセージ)
| メッセージID |
開始アドレス |
文字列 |
| $0B15 |
$3E42B5 |
[D6]なんと [C0]は まだ[AD]いちにんまえの [B2]に[AD]なっていないというに……。[AF][AD]みじゅく者の ぶんざいで[AD]もう 職をかえたいとは[AD]なにごとじゃ![AF] |
| 略 |
|
|
|
| $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バイト文字)」に差し替えてデコードするというアプローチです。長くなったので続きはまた次回。
コメント