update 2003.09.01

ファミコン版「スーパーマリオブラザーズ」 エンディングメッセージ変換


概要
長きステージ8(大抵は1面→3面→4面→8面でワープしまくるんですが)をクリアして、
やっとピーチ姫を助け出した感動の場面のメッセージを吸い出すテストです。

…しかし、この薄幸のヒロイン的立場だったピーチが後々にカートを乗り回したり、
大暴れするなんて誰が予想したでしょうねぇ(遠い目

まあそれはさておき、基本的にこのゲームは半角英数のみですから、
文字コードの変換だけでOKということですね。
 半角英数(MARIO CODE)→半角英数(ASCII CODE)
に変換し、コマンドプロンプト(DOS窓)に出力する変換ツールを作成します。

準備
この解析・変換ツール作成には以下のものを使用します。
・GCCODE 解析ツール無しだとキツイです。
・バイナリエディタ 数列から内容を解析したり、パターンテーブルを作るのに使います。
・VisualC++6.0 ツール作成用です。Borland C++ Compilter(フリー)で代用できます。

解析
斧といっしょにクッパを踏んだため、マリオ死亡のままエンディングだったりする
とりあえずスーパーマリオをクリアしてエンディングを見ます。
わずか1画面の数十文字程度のシンプルな英文で、変換するまでもないしやすい
まさにコンバータ制作入門用とも言える文章です。

まずいつもどおり GCCODE を起動して最初の一文である THANK YOU を探します。
間のスペースは文字コード依存のためワイルドカードを使いTHANK?YOUと検索しましょう。
GCCODE画面
これで2件ヒットしますが、ここでちょっと気づくことがあります。

まずこの2件は THANK YOU MARIO! と THANK YOU LUIGI! の部分にヒットしているのですが、
その後に続くメッセージは BUT OUR PRINCESS〜… と YOUR QUEST IS OVER〜…が連なっています。
つまり同じような辺りにクリアメッセージを複数定義していて、プレイヤーキャラ名や
ステージごとにそれらの指標を変えることで画面表示内容を変更しているようです。

今回は「THANK YOU MARIO!」から始まり「YOUR QUEST IS OVER…」とピーチ姫の
言葉が続くエンディングメッセージテキストの抽出が目的ですので、
この辺はコンバートプログラムレベルでの対応が必要になります。

ひとまず、この状態で判明したことは
・抽出したいメッセージは断片的に定義されている
・文字コードは 0x0A="A" 〜 0x23="Z"
以上の2点ですが、この規模のメッセージコンバータであればこれだけあれば十分、
次のステップに進むことができます。

必要個所のアドレス絞り込み
断片的に定義されている文節を繋ぐため、必要なデータを絞ります。
THANK YOU〜、YOUR QUEST〜、と1行ごとのメッセージを検索してその先頭オフセットを得て、
そしてプログラムはその情報を元に組むことになります。
オフセットメッセージ
00000d67THANK YOU!〜
00000dbbYOUR QUEST〜
00000dd2WE PRESENT〜
00000df1PUSH B〜
00000e02TO SELECT〜

変換処理プログラムを組む
今回は文字コードの差異が 0x37 で依存文字が非常に少ないため、
前回(参考リンク)で言う差異吸収を数式で行う方法を使います。

単純な半角英字変換には AsciiCode=MarioCode + 0x37 から求めることができ、
それ以外のスペースなどの機種依存文字に対してはプログラムレベルで対応します。
例えば半角英字の Z が 0x23 なので、それよりも上の数値(0x24など)は依存文字や
制御コードであることが考えられますので、バイナリエディタ等で解析します。
(今回は制御コード処理を全部無視してプログラム側でフォローしてますが…)

Cソース
VisualC++ 6.0で作ったコンバートサンプルプログラムです。
上でも説明したように「差異吸収を数式で行う」のルーチンで組んでいます。
パターンテーブルを使わないためデータの無駄も少なく非常にコンパクトです。

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



TOPに戻る