5.12. 宿屋解析

5.12.1. 解析
5.12.1.1. 普通の宿屋
5.12.1.2. 旅の宿屋
5.12.1.3. すごろくの宿屋
5.12.1.4. 旅・すごろく宿屋共通
5.12.1.5. 宿屋構造体アクセス

SFC 版ドラクエ 3 では宿屋の処理は三種類存在する。 街中にある宿屋、 商人が使える「おおごえ」でフィールドで出現することがある宿屋、 そして各すごろくにある宿屋マスの宿屋である。 いずれも、まず宿屋のあいさつがあり、 宿代を提示して……という一連の振る舞いが共通している。 その共通する処理を調べる。

5.12.1. 解析

いきなり結論から述べるが、 街中にある宿屋は共通して $C3D0F8 サブルーチンを呼び出すことで実装してあり、 フィールドで遭遇する宿屋と、すごろくの宿屋マスの宿屋は共通サブルーチンで実装してある。

5.12.1.1. 普通の宿屋

街中にある宿屋は共通して $C3D0F8 サブルーチンを呼び出すことで実装してある。 このサブルーチンを呼び出す前に、A レジスタに宿屋 ID をセットしておく。 コードを解読した結果得た事実を下に列挙しておく。

  • 宿屋の最初のセリフは、昼か夜かで異なる (サブルーチン $C79190 呼出し後の carry フラグで判断)。

  • 宿屋構造体アクセス $C3D2DB で宿代の計算等をする。 呼び出し終了直後には $70 (3byte) に宿代が、$73 (2byte) に復帰用座標情報構造体 ID がセットされている。

  • 宿泊するかとの問いに「いいえ」またはキャンセル抜けでウィンドウを閉じると、 宿屋が「さようなら旅の人~」のセリフを言い、窓口処理が終了する。

  • 宿泊するかとの問いに「はい」を答えると、汎用サブルーチン $C45B66 を呼び出し、 パーティの所持金と宿代との大小比較を行う。

    • 所持金が不足している場合には 「でもお金が足りないようですね」→「さようなら~」という流れになる。

    • 所持金が十分のときは、所持金から宿代が引かれる。

    • 「それではごゆっくり」のセリフの後、パーティの生存メンバーの HP, MP が全回復する (サブルーチン $C3D332 呼び出しによる)。

    • 画面を暗転し、$73 にセット済みの復帰座標 ID を元に、 パーティのメンバーの立ち位置を変更して画面が元に戻る。

    • (タイミングは不明)この間におなじみの宿屋の効果音が流れる。

    • 「おはようございます」のセリフを表示し、 ウィンドウが閉じたら宿屋処理を終了する。

5.12.1.2. 旅の宿屋

フィールドで「おおごえ」を使うと出現する旅の宿屋は、 サブルーチン $C3D1D6 で実装されている。 このサブルーチンは、X レジスタに 0 をセットしてから 旅・すごろく宿屋共通サブルーチン を呼び出すだけで終わる。

5.12.1.3. すごろくの宿屋

すごろくの宿屋のマスに止まると、いきなり画面が変わって宿屋の処理に突入するが、 セリフ部分からの処理はサブルーチン $C3D1F1 で実装されている。 このサブルーチンは、X レジスタに 2 をセットしてから 旅・すごろく宿屋共通サブルーチン を呼び出すだけで終わる。

5.12.1.4. 旅・すごろく宿屋共通

サブルーチン $C3D20C は、旅の宿屋とすごろくの宿屋の実装である。 このサブルーチンを呼び出す前に、 A レジスタと X レジスタに宿屋 ID と 「表示セリフタイプ」をそれぞれにセットしておく。 コードを解読した結果得た事実を下に列挙しておく。

  • 普通の宿屋サブルーチンのコードをコピー&ペーストしてから、 差分だけを変更して作ったと思われる。

    • 宿屋のセリフ表示をサブルーチン $C1A95A 呼び出しで実現している。 これは A レジスタにメッセージ ID をセットしてから呼び出すものである。 例えば最初の台詞は LDA $C3D2C3,X でメッセージ ID をセットする。 旅の宿屋とすごろくの宿屋の違いは、 この LDA 命令の X の違いに他ならない。

    • 宿屋の第一声のセリフは昼夜を問わない。

X レジスタが台詞の種別を表現する。 X = 0 は旅の宿屋のそれであり、 X = 2 はすごろくの宿屋のそれである。 一人の宿屋は 6 種類の台詞を話すため、 6 個のメッセージ ID 配列を用意している。

$C3D2C3,X

最初の挨拶を表すメッセージ ID が 2 個からなる配列。 例えば旅の宿屋 (X = 0) の場合は、宿屋処理コードは 「おまたせしました。旅人の宿屋で ございます」 を表示する ID 値 0ABBh を参照することになる。

$C3D2C7,X

宿代を言うためのメッセージ ID 配列。

$C3D2CB,X

「さようなら旅の人」メッセージ ID 配列。

$C3D2CF,X

パーティの所持金が不足しているときに宿屋が言う台詞のメッセージ ID 配列。

$C3D2D3,X

「おやすみなさい」メッセージ ID 配列。

$C3D2D7,X

「いってらっしゃい」メッセージ ID 配列。

5.12.1.5. 宿屋構造体アクセス

サブルーチン $C2D2DB では、与えられた宿屋 ID を元に以下の処理を行う。

  • 宿屋構造体 $C30A98 データを読み取る

  • $70 (3byte) に宿代をセットし、さらにパーティの生存人数で乗じる。

  • $73 に構造体 $C89BB7(復帰用座標情報構造体)ID をセットする。

宿屋構造体 $C30A98 のメモリレイアウトは以下の通り。

表 5.19 $C30A98 宿屋構造体

Byte:Bit 80 40 20 10 08 04 02 01
00 一人頭の宿代(上位バイトの下位へ続く)
01 復帰用座標情報 ID (上位バイトの下位へ続く) 続き
02 未使用 続き

復帰用座標情報構造体 $C89BB7 のデータは、 一晩明けたときのパーティの立ち位置を決めるために参照される。 構造体については先行研究 [URL3] を参照。