TOP > プログラミング関係解説&調査 > 文字データ

文字データ

当ページの内容は、ある程度のプログラミングの知識を必要とする。
まず、プログラミング関係解説&調査をひととおり読んでいただきたい。

スーパーファミコンのゲームソフトのデータは16進数で記述されており(バイナリデータ)、日本語が直接記録されているのではない。
文字データも16進数で記述されており、一定の法則でアルファベットや日本語に変換できる。
16進数のデータから日本語などへ変換することをデコード、その逆をエンコードという。

本作の文字は、セリフや戦闘中のテキストなどに使われている通常の文字の場合、1文字あたり、ひらがな・カタカナ・アルファベット・記号は1バイト、漢字は2バイトのデータを使っている。
(戦闘中に敵味方のダメージ量として表示される数字などは別扱い)

1~2バイトの文字コードから、「文字の画像ファイル」を呼び出して、ゲーム画面に表示、という手順で、本作のセリフや戦闘中の敵の名前・技名、メニュー画面のテキストが表示されている。

文字コード

文字コード表(Google スプレッドシート)

本作における文字のデコード・エンコードの法則は上表の通り。
ひらがな・カタカナ・アルファベット・記号は256種、漢字は256×3=768種。
容量節約のため、空白(スペース)複数個分に1バイトのデータを割り振っていたりもする。改行用コードなども記号に含まれる。

1バイトの場合は上の文字コード表に対応した値をそのまま使うが、漢字は上位バイトに$1D$1E$1F、下位バイトに$00$FFの数値を入れて、$1D??, $1E??, $1F??とする。

一部記号の$2C$2F, $3F、数字にあたる$30$39、アルファベット大文字にあたる$41$5AはASCII文字コード(ASCII - WikipediaJIS X 0201 - Wikipedia参照)からと思われる。

例えば、16進数の文字データで以下のように記されていたとする。

AD 88 67 1E D7 1D 2F

$1D, $1E, $1F は次の1バイトと続けて2バイトで漢字になるので、上の文字コード表から該当文字を当てはめると、

AD88671ED71D2F

となる。

雑に作ったがJavaScriptでデコード・エンコードできるようにした(エンコードはあまりあてにできない)。不具合がある可能性大。

キャラクターの名前

本作では各シナリオの主人公(功夫編は拳法の名前)をプレイヤーが決めることが可能であるが、決定した名前はシナリオ別キャラデータ$34$3Fの12バイトに記録される。
ひらがなやカタカナなら12文字まで格納できることになるが、実際には最大6文字である。
漢字だと2バイト使うため、漢字のみだと最大6文字になることに合わせていると思われる。
功夫編の拳法名は最大3文字だが、これはキャラ名が「○○○拳老師」「○○○拳師範」と、トータルで6文字に収まるよう調整しているためである。

例:
「オルステッド」だと、$7E:0D34$7E:0D3Fの12バイトに入っているデータは、

数値$65$89$6D$73$91$A5$00$00$00$00$00$00
対応文字------

「高原 日勝」だと、$7E:0E74$7E:E73Fの12バイトに入っているデータは、

数値$1D$E1$1D$BC$20$1F$3A$1E$55$00$00$00
対応文字(空白)---

文字の画像ファイル

本作では1文字に$16バイト(24バイト)分の画像データを使用している。
16×16ピクセルの正方形の中で12×12ピクセル分が文字である。
1バイト、つまり8ビットの1ビットずつが文字画像の1ピクセルに対応していて、1なら文字部分、0なら透過部分である。
2バイト、つまり16ビットを横に並べ、次からは2行目として、12行目まで並べることができる。
横16ビット×縦12ビットのビットマップ画像となるが、実際には右横の4ビット×12ビット部分は透過扱いの0しか並んでいない。

文字コードから文字の画像ファイルを呼び出すには、まず、該当の文字の画像ファイルがあるアドレスを計算する必要がある。
文字コード表では、漢字なら$1D, $1E, $1Fを頭につけて2バイトのデータにしたが、アドレス計算の場合、

  • ひらがな・カタカナ・アルファベット・記号:$00
  • 漢字$1D列:$01
  • 漢字$1E列:$02
  • 漢字$1F列:$03

と、頭に数字をつけて2バイトにする。
つまり、文字コード表(Google スプレッドシート)でいえば、一番左の列は上1バイトが00、そこから右の列は順に010203と値が入る、ということで、2バイトだと$0000$03FFと連番になったと見なしても良い。

該当の文字の画像ファイルの最初のアドレスは、

$D49200 + ($0000~$03FF) * $18

で計算できる。
例えば戦闘におけるコマンドの一番上、「戦う」という2文字であれば、「戦」「う」と別々に見ると、文字コードから、

「戦」$02A4
$D49200 + $02A4 * $18 = $D4 D160

「う」$00B3
$D49200 + $00B3 * $18 = $D4 A2C8

「戦」は$D4:D160$D4:D177$16バイト、「う」は$D4:A2C8$D4:A2DF$16バイトが画像データである。

「戦」$D4:D160$D4:D177

A4 A0 A8 90 00 80 F8 F0
AB 80 F8 90 A8 90 F8 A0
20 40 F8 D0 21 50 22 20

「う」$D4:A2C8$D4:A2DF

08 00 07 00 00 00 0F 00
30 80 00 40 00 40 00 40
00 80 03 00 0C 00 00 00

1文字ずつ、2進数8ビットに変換し、2バイトずつ12行並べると以下のようになる。
一番右の4ビット分は必ず0000である。

「戦」

1010 0100 1010 0000
1010 1000 1001 0000
0000 0000 1000 0000
1111 1000 1111 0000
1010 1011 1000 0000
1111 1000 1001 0000
1010 1000 1001 0000
1111 1000 1010 0000
0010 0000 0100 0000
1111 1000 1101 0000
0010 0001 0101 0000
0010 0010 0010 0000

「う」

0000 1000 0000 0000
0000 0111 0000 0000
0000 0000 0000 0000
0000 1111 0000 0000
0011 0000 1000 0000
0000 0000 0100 0000
0000 0000 0100 0000
0000 0000 0100 0000
0000 0000 1000 0000
0000 0011 0000 0000
0000 1100 0000 0000
0000 0000 0000 0000

これだけではわかりにくいから、1を■、0を□にしてみよう。

■□■□□■□□■□■□□□□□
■□■□■□□□■□□■□□□□
□□□□□□□□■□□□□□□□
■■■■■□□□■■■■□□□□
■□■□■□■■■□□□□□□□
■■■■■□□□■□□■□□□□
■□■□■□□□■□□■□□□□
■■■■■□□□■□■□□□□□
□□■□□□□□□■□□□□□□
■■■■■□□□■■□■□□□□
□□■□□□□■□■□■□□□□
□□■□□□■□□□■□□□□□

□□□□■□□□□□□□□□□□
□□□□□■■■□□□□□□□□
□□□□□□□□□□□□□□□□
□□□□■■■■□□□□□□□□
□□■■□□□□■□□□□□□□
□□□□□□□□□■□□□□□□
□□□□□□□□□■□□□□□□
□□□□□□□□□■□□□□□□
□□□□□□□□■□□□□□□□
□□□□□□■■□□□□□□□□
□□□□■■□□□□□□□□□□
□□□□□□□□□□□□□□□□

これでもちょっとわかりにくいと思うので、16×12のマスを作り、1の部分だけを黒で塗りつぶしてみた画像も作ってみた。
(あまりお行儀が良くはないがエクセル方眼紙的なものが楽)

というように、文字の画像データは、2進数の1が不透明部分、0が透明部分(透過)で作られている。
2進数でバイナリデータを記録するという意味ではWindows bitmap (*.bmp) ファイルと構造は同じなので、実際に16×16ピクセルのビットマップを作って、16進数の数値を入れると同じ画像を作ることができる。
(ビットマップの場合は一番下のラインから順に、2バイトの場合残り2バイトに00をつけて4バイトでデータを記述する)

※バイナリエディタはTSXBINを使用させていただきました。
バイナリエディタ TSXBIN 64版の詳細情報 : Vector



このページをシェアする

上へ