update 2004.05.02

ファミコン版「スペランカー」 エンディングメッセージ変換


概要
3年ほど前、GCCODEの前身にDOS汎用でSSPGというツールをコッソリ公開しており、
これの目標が「スペランカーのエンディング抽出」だったので、三年来の目標達成というわけですねぇ。
というわけで、今回はスペランカーのエンディングメッセージコンバータ作成です。

元データは1バイト定義のキャラクタ文字ですが、半角→全角変換などを施さず、
独自文字コードをShift-JISに変換し、そのままコマンドプロンプト(DOS窓)に出力させてみます。

準備
この解析・変換ツール作成には以下のものを使用します。
・GCCODE 文字コード解析支援ツール
・VisualC++6.0 ツール作成用です。Borland C++ Compilter(フリー)などで代用できます。
前回までは解析にバイナリエディタを多用しましたが、現時点(2004年5月2日)のGCCODEは
バイナリエディタ無しである程度の解析が可能になっているので、今回は使用しません。

解析
解析より、この画面見るほうが大変でした…
まずエンディング画面を確認したら、動作を停止するか画面を保存しておきます。
GCCODEにスペランカーのROMイメージを読み込ませてから、1行目の CONGRATULATIONS を検索します。

-- BYTE型 文字コード検索 --
ファイル読み込み ... 完了
データ解析開始
(候補発見 001) OFFSET 00005902 : 3c 48 47 40 4b 3a 4d 4e 45 3a 4d 42 48 47 4c 
文字列テーブル出力(アルファベット)
 A:3a B:3b C:3c D:3d E:3e F:3f G:40 H:41 I:42
 J:43 K:44 L:45 M:46 N:47 O:48 P:49 Q:4a R:4b
 S:4c T:4d U:4e V:4f W:50 X:51 Y:52 Z:53
 差異 : SJIS A(0x41) - 0x3a = 0x07

解析終了
これでオフセット 00005902 以降にエンディングメッセージが格納されていることが判明したので、
以下の条件でフィルタリング出力します。
・オフセット 00005902 〜 00005993
・差異 7
・バイトサイズ 1:半角
・非表示文字をスペースに置き換え チェック
・オフセットと16進データを付加 チェック
これで実行すればエンディングメッセージを全て得ることができます。
-- フィルタリング出力(ログ) --
 範囲 : 5902 〜 5993
 バイトサイズ : 1(半角文字)
 基準値 : 7 (加算)
== オフセット & 16進データ付加出力 ==
00005902 : 3C C
00005903 : 48 O
00005904 : 47 N
00005905 : 40 G
00005906 : 4B R
00005907 : 3A A
00005908 : 4D T
00005909 : 4E U
0000590A : 45 L
0000590B : 3A A
0000590C : 4D T
0000590D : 42 I
0000590E : 48 O
0000590F : 47 N
00005910 : 4C S
00005911 : 00  
00005912 : 0F  
00005913 : 0F  
00005914 : 00  
00005915 : 00  
00005916 : 00  
00005917 : 00  
00005918 : 00  
00005919 : 00  
0000591A : 00  
0000591B : 00  
0000591C : 00  
0000591D : 00  
0000591E : 00  
0000591F : 52 Y
00005920 : 48 O
00005921 : 4E U
00005922 : 0E  
00005923 : 4F V
00005924 : 3E E …(以下略)
フィルタリング出力で「0E = ' 」「0F = ! 」ということがわかり、
「CONGRATULATIONS」「!!」の間に 00 があるので、これはスペースだとわかります。

…そして途中にある間の 0000000000000.. が行の区切りの部分なのですが、
改行コードも何も無しにいきなり次の行の文字が出てきています。
この00の羅列を画面に合わせて区切ると、1行が32バイトのブロックになり、
CONGRATULATION前の3つのスペースも含めると、以下のようなデータであることがわかります。
000058FF : 00 
00005900 : 00 
00005901 : 00 
00005902 : 3C C
00005903 : 48 O
00005904 : 47 N
00005905 : 40 G
00005906 : 4B R
00005907 : 3A A
00005908 : 4D T
00005909 : 4E U
0000590A : 45 L
0000590B : 3A A
0000590C : 4D T
0000590D : 42 I
0000590E : 48 O
0000590F : 47 N
00005910 : 4C S
00005911 : 00  
00005912 : 0F  
00005913 : 0F  
00005914 : 00  
00005915 : 00  
00005916 : 00  
00005917 : 00  
00005918 : 00  
00005919 : 00  
0000591A : 00  
0000591B : 00  
0000591C : 00  
0000591D : 00  
0000591E : 00 
0000591F : 52 Y
00005920 : 48 O
00005921 : 4E U
00005922 : 0E  
00005923 : 4F V
00005924 : 3E E
00005925 : 00  
00005926 : 40 G
00005927 : 3A A
00005928 : 42 I
00005929 : 47 N
0000592A : 3E E
0000592B : 3D D
0000592C : 00  
0000592D : 3A A
0000592E : 45 L
0000592F : 45 L
00005930 : 00  
00005931 : 4D T
00005932 : 41 H
00005933 : 3E E
00005934 : 00  
00005935 : 00  
00005936 : 00  
00005937 : 00  
00005938 : 00  
00005939 : 00  
0000593A : 00  
0000593B : 00  
0000593C : 00  
0000593D : 00  
0000593E : 00  
0000593F : 00  
00005940 : 00  
00005941 : 00  
00005942 : 00  
00005943 : 00  
00005944 : 4D T
00005945 : 4B R
00005946 : 3E E
00005947 : 3A A
00005948 : 4C S
00005949 : 4E U
0000594A : 4B R
0000594B : 3E E
0000594C : 4C S
0000594D : 00  
0000594E : 3A A
0000594F : 4D T
00005950 : 00  
00005951 : 45 L
00005952 : 3A A
00005953 : 4C S
00005954 : 4D T
00005955 : 00  
00005956 : 0F  
00005957 : 00  
00005958 : 00  
00005959 : 00  
0000595A : 00  
0000595B : 00  
0000595C : 00  
0000595D : 00  
0000595E : 00  
0000595F : 45 L
00005960 : 3E E
00005961 : 4D T
00005962 : 0E  
00005963 : 4C S
00005964 : 00  
00005965 : 4C S
00005966 : 4D T
00005967 : 3A A
00005968 : 4B R
00005969 : 4D T
0000596A : 00  
0000596B : 48 O
0000596C : 47 N
0000596D : 00  
0000596E : 00  
0000596F : 00  
00005970 : 00  
00005971 : 00  
00005972 : 00  
00005973 : 00  
00005974 : 00  
00005975 : 00  
00005976 : 00  
00005977 : 00  
00005978 : 00  
00005979 : 00  
0000597A : 00  
0000597B : 00  
0000597C : 00  
0000597D : 00  
0000597E : 00  
0000597F : 00  
00005980 : 00  
00005981 : 00  
00005982 : 00  
00005983 : 3A A
00005984 : 47 N
00005985 : 48 O
00005986 : 4D T
00005987 : 41 H
00005988 : 3E E
00005989 : 4B R
0000598A : 00  
0000598B : 3A A
0000598C : 3D D
0000598D : 4F V
0000598E : 3E E
0000598F : 47 N
00005990 : 4D T
00005991 : 4E U
00005992 : 4B R
00005993 : 3E E
00005994 : 00 
00005995 : 00 
00005996 : 00 
00005997 : 00 
00005998 : 00 
00005999 : 00 
0000599A : 00 
0000599B : 00 
0000599C : 00 
0000599D : 00 
0000599E : 00 

変換処理プログラムを組む
というわけで、コンバータ本体は
オフセット 000058FF 〜 0000599F の範囲を32バイトずつ合計5回読み込み、
00をスペース、0Eを「’」、0Fを「!」、それ以外を+7して出力する

という動作を行います。
あとはテーブルファイルなども一切使わない、シンプルな構成にします。

Cソース
VisualC++ 6.0で作ったコンバートサンプルプログラムです。
コンパイル済みのEXEファイルやドキュメントを同封しています。
プロジェクトは Win32 console application の "Hello,World!"アプリケーション を選択し、
丸ごとメインのソースに上書きすればコンパイル&ビルドができます。
Borland C++ Compilerでは1行目の#include "stdafx.h"を消去してからコンパイルしてください。
>>コンバータ本体・Cソースのダウンロード


TOPに戻る