5.13. 教会解析

5.13.1. 解析
5.13.1.1. 教会処理神父バージョン
5.13.1.2. 教会処理シスターバージョン
5.13.1.3. 教会処理共通サブルーチン
5.13.1.4. 「いきかえらせる」サブルーチン
5.13.1.5. 「どくのちりょう」サブルーチン
5.13.1.6. 「のろいをとく」サブルーチン
5.13.1.7. 「寄付をよろしいかな」サブルーチン
5.13.1.8. 「いきかえらせる」- 寄付金計算サブルーチン
5.13.1.9. 「のろいをとく」- 寄付金計算サブルーチン
5.13.1.10. 「どくのちりょう」- 寄付金計算サブルーチン

教会にいる神父や(SFC 版ドラクエ 3 では稀だが)シスターに「はなす」ときのプログラムを解析する。 教会の仕事は仲間パーティーの状態異常を回復するという、非常にわかりやすいものだ。 そんなプログラムを解析する意味などあるのかと思われるかもしれないが、 ドラクエの基本処理はやはりおさえておきたい。

5.13.1. 解析

「はなす」対象が神父であるかシスターであるかによらず、同じサブルーチンを呼び出すことで彼らの仕事を実現している。 唯一の違いは、ウィンドウに表示する台詞が異なるだけである。 台詞表示サブルーチンは、A レジスタの値をメッセージ ID として処理する $C1A95A を用いる。

C3/D50C:    DC0A    ; [D6]たのもしき 神のしもべよ[AD]わが教会に
C3/D50E:    EE0A    ; [D6]ここは 神にみちびかれし[AD]迷える小羊たちの

C3/D510:    DE0A    ; [D6]どなたを この世へ[AD]呼びもどすのじゃな?[AF]
C3/D512:    F00A    ; [D6]どなたを 生きかえらせて[AD]ほしいのですか?[AF]

C3/D514:    DF0A    ; [D6]ごじょうだんを。[C0]どのは[AD]生きていらっしゃる![AF]
C3/D516:    F10A    ; [D6]あら? [C0]さんは[AD]生きていますわ。[AF]

こういう具合に、神父とシスターの同じ状況に話す台詞 ID が交互に配列されてある。 そのために、教会処理の先頭で X レジスタの値を固定しておき、 サブルーチン $C1A95A を呼び出すときには、 常にその直前に LDA addr,x 命令で表示直前に ID を変える。 以下の説明で引用する台詞は、特に断らない限り神父のものを使う。

5.13.1.1. 教会処理神父バージョン

教会にいる神父に「はなす」ときになされる通常の処理は、 サブルーチン $C3D466 である。

5.13.1.2. 教会処理シスターバージョン

教会にいるシスターに「はなす」ときになされる通常の処理は、 サブルーチン $C3D481 である。

5.13.1.3. 教会処理共通サブルーチン

サブルーチン $C3D49C は、神父とシスターのおつとめ処理の実装だ。 呼び出し前に A レジスタに「表示台詞タイプ」をロードしておくのが事前条件になっている。

  • X = A とする。これは上述の台詞表示のための対応である。

  • 汎用サブルーチン $C79190 を呼び出すことで昼夜チェックを行う。 それにより「はなす」による最初のあいさつを変えて表示する。

    • 夜ならば A = $C3D550,X

    • 昼ならば A = $C3D50C,X

  • 【メニュー】

    ウィンドウ「いきかえらせる・どくのちりょう・のろいをとく・やめる」を表示し、入力を待つ。 プレイヤーの入力が以下のいずれでもない場合は、制御を次に進める。

    • キャンセルボタンで抜けた場合は【終了】に制御を進める。

    • 「いきかえらせる」を選択した場合は、【いきかえらせる】に制御を進める。

    • 「どくのちりょう」を選択した場合は、【どくのちりょう】に制御を進める。

    • 「のろいをとく」を選択した場合は、【のろいをとく】に制御を進める。

  • 【終了】

    • メッセージ ID を $C3D540,X からロードし、台詞「では お気をつけて~」を表示する。

    • サブルーチン呼び出し元に制御を戻す。

  • 【いきかえらせる】

  • 【どくのちりょう】

  • 【のろいをとく】

  • 【ほかに】

    • メッセージ ID を $C3D53C,X からロードし、台詞「ほかにご用は~」を表示する。

    • 制御を【メニュー】に戻す。

5.13.1.4. 「いきかえらせる」サブルーチン

サブルーチン $D554 は教会処理「いきかえらせる」の実装である。

  • メッセージ ID を $C3D510,X からロードし、 メッセージ表示サブルーチンを呼び出すことで、 台詞「どなたをこの世へ呼びもどすのじゃな?」を言わせる。

  • 「だれを」ウィンドウを表示して、プレイヤーの入力を待つ。

    • キャンセルボタンを押したときには、 メッセージ ID を $C3D538,X からロードし、 メッセージ表示サブルーチンを呼び出すことで、 台詞「なんとやめると申されるか」を言わせる。 その後、サブルーチン呼び出し元に制御を戻す。

    • パーティのメンバーを選択したときは、制御を次へ進める。

  • 選択メンバーの生死状態を示すビットをテストするために 汎用サブルーチン $C43F87 を呼び出し、A レジスタの値の 0010h の位を見る。

    • もしビットが立っていない場合、 メッセージ ID を $C3D514,X からロードし、 メッセージ表示サブルーチンを呼び出すことで、 台詞「○○どのは生きていらっしゃる」を言わせる。 その後、サブルーチン呼び出し元に制御を戻す。

    • ビットが立っている場合は、次へ制御を進める。

  • サブルーチン $C3D700 呼び出しにより、寄付金を設定する。

  • サブルーチン $C3D6B7 呼び出しにより、寄付をよろしいかな処理を走らせる。

    • 寄付を支払っていない場合、制御をサブルーチン呼び出し元に戻す。

    • 寄付を支払った場合は、制御を次へ進める。

  • 汎用サブルーチン $C44045 呼び出しにより、 選択メンバーの(少なくとも)死亡状態フラグをセットする (詳細未調査)。

  • 汎用サブルーチン $C43231 呼び出しにより、 選択メンバーの HP を最大 HP と同じにする (詳細未調査)。

  • 汎用サブルーチン $C43337 呼び出しにより、 選択メンバーの MP を最大 MP と同じにする (詳細未調査)。

  • メッセージ ID を $C3D518,X からロードし、 メッセージ表示サブルーチンを呼び出すことで、 台詞「おお わが主よ!全知全能の神よ!」を言わせる。

  • 例の効果音を鳴らす。鳴り終わったら、制御を次へ進める。

  • サブルーチン $C3BD64 を呼び出す。 パーティの描画を更新するものと思われるが未調査。

  • メッセージ ID を $C3D51C,X からロードし、 メッセージ表示サブルーチン(ここだけは $C1A900 を用いる)を呼び出すことで、 「○○は よみがえった!」を表示する。

  • 制御をサブルーチン呼び出し元に戻す。

5.13.1.5. 「どくのちりょう」サブルーチン

サブルーチン $D5DD は教会処理「どくのちりょう」の実装である。

  • メッセージ ID を $C3D520,X からロードし、 メッセージ表示サブルーチンを呼び出すことで、 台詞「どなたの毒を とるのじゃな?」を言わせる。

  • 「だれを」ウィンドウを表示して、プレイヤーの入力を待つ。

    • キャンセルボタンを押したときには、 メッセージ ID を $C3D520,X からロードし、 メッセージ表示サブルーチンを呼び出すことで、 台詞「なんとやめると申されるか」を言わせる。 その後、サブルーチン呼び出し元に制御を戻す。

    • パーティのメンバーを選択したときは、制御を次へ進める。

  • 選択メンバーが毒にかかっているかどうかを示すビットをテストするために 汎用サブルーチン $C43F87 を呼び出し、A レジスタの値の 0001h の位を見る。

    • もしビットが立っていない場合、 メッセージ ID を $C3D524,X からロードし、 メッセージ表示サブルーチンを呼び出すことで、 台詞「○○どのは毒におかされていませんぞ」を言わせる。 その後、サブルーチン呼び出し元に制御を戻す。

    • ビットが立っている場合は、次へ制御を進める。

  • サブルーチン $C3D74C 呼び出しにより、寄付金を設定する。

  • サブルーチン $C3D6B7 呼び出しにより、寄付をよろしいかな処理を走らせる。

    • 寄付を支払っていない場合、制御をサブルーチン呼び出し元に戻す。

    • 寄付を支払った場合は、制御を次へ進める。

  • 汎用サブルーチン $C440B0 呼び出しにより、 選択メンバーの毒にかかっていることを示すビットをリセットする。

  • メッセージ ID を $C3D528,X からロードし、 メッセージ表示サブルーチンを呼び出すことで、 台詞「おお神よ おちからを!」を言わせる。

  • 例の効果音を鳴らす。 鳴り終わるのを待って、制御をサブルーチン呼び出し元に戻す。

5.13.1.6. 「のろいをとく」サブルーチン

サブルーチン $D64A は教会処理「のろいをとく」の実装である。

  • メッセージ ID を $C3D544,X からロードし、 メッセージ表示サブルーチンを呼び出すことで、 台詞「どなたの呪いを とくのじゃな?」を言わせる。

  • 「だれを」ウィンドウを表示して、プレイヤーの入力を待つ。

    • キャンセルボタンを押したときには、 メッセージ ID を $C3D538,X からロードし、 メッセージ表示サブルーチンを呼び出すことで、 台詞「なんとやめると申されるか」を言わせる。 その後、サブルーチン呼び出し元に制御を戻す。

    • パーティのメンバーを選択したときは、制御を次へ進める。

  • 選択メンバーが呪われているかどうかを示すビットをテストするために 汎用サブルーチン $C43F87 を呼び出し、A レジスタの値の 0004h の位を見る。

    • もしビットが立っていない場合、 メッセージ ID を $C3D548,X からロードし、 メッセージ表示サブルーチンを呼び出すことで、 台詞「○○どのは呪われてはいませんぞ」を言わせる。 その後、サブルーチン呼び出し元に制御を戻す。

    • ビットが立っている場合は、次へ制御を進める。

  • サブルーチン $C3D733 呼び出しにより、寄付金を設定する。

  • サブルーチン $C3D6B7 呼び出しにより、寄付をよろしいかな処理を走らせる。

    • 寄付を支払っていない場合、制御をサブルーチン呼び出し元に戻す。

    • 寄付を支払った場合は、制御を次へ進める。

  • 汎用サブルーチン $C44168 呼び出しにより、 選択メンバーの、呪われている状態であることを示すビットをリセットする。

  • メッセージ ID を $C3D54C,X からロードし、 メッセージ表示サブルーチンを呼び出すことで、 台詞「おお神よ おちからを!」を言わせる。

  • 例の効果音を鳴らす。 鳴り終わるのを待って、制御をサブルーチン呼び出し元に戻す。

5.13.1.7. 「寄付をよろしいかな」サブルーチン

サブルーチン $C3D6B7 は、各メニューに共通する寄付要求の実装である。

  • メッセージ ID を $C3D52C,X からロードし、かつ 呼び出し前に $70 にセット済みの寄付金額を用いて メッセージ表示サブルーチンを呼び出すことで、 台詞「さすれば わが教会に○○ゴールドの ご寄付を」を言わせる。

  • 「はい・いいえ」ウィンドウを表示して、プレイヤーの入力を待つ。 キャンセルボタン抜けもしくは「いいえ」選択の場合、制御を【No】まで進める。

  • 汎用サブルーチン $C45B66$70 を引数として渡すことと、 サブルーチン $C32209 呼び出しによって、 所持金から寄付金を減じることを試みる。

    • 所持金更新に失敗した場合、 メッセージ ID を $C3D530,X からロードし、 台詞「寄付をするにはお金がたりないでは~」を言わせる。

      【Finish】へ制御を進める。

    • 所持金更新に成功した場合、制御を呼び出し元に戻す。 このとき、Carry ビットはリセットされていることに注意。

  • 【No】

    メッセージ ID を $C3D534,X からロードし、 台詞「教会への寄付は神への感謝の気持ち~」を言わせる。

  • 【Finish】

    Carry ビットをセットして制御を呼び出し元に戻す。

5.13.1.8. 「いきかえらせる」- 寄付金計算サブルーチン

サブルーチン $C3D700 は選択したメンバーを生き返らせるための寄付金額を計算する。

  • 汎用サブルーチン $C42FEB により、選択メンバーのレベルを A レジスタにロードする。

  • レベルの値を A レジスタの上位バイト (AH) と下位バイト (AL) に移す。

  • 汎用乗算サブルーチン $C01098 により、積 A = AH * AL を計算する。

  • $70 = A とする。

  • 汎用除算サブルーチン $C0121C により、$70 /= 000Ah とする。

  • $70 += 1 とする。

  • A レジスタに値 000Ah をロードし、 汎用乗算サブルーチン $C010D6 により、$70 *= A とする。

  • 制御を呼び出し元に戻す。

このことから、生き返らせるための寄付金は、 (Lv2 / 10 + 1) * 10 と憶えておけばよいことがわかる。

5.13.1.9. 「のろいをとく」- 寄付金計算サブルーチン

サブルーチン $C3D733 は選択したメンバーの呪いを解くために寄付をする金額を計算する。

  • 汎用サブルーチン $C42FEB により、選択メンバーのレベルを A レジスタにロードする。

  • レベルの値を A レジスタの上位バイト (AH) に移す。

  • 1EhA レジスタの下位バイト (AL) に移す。

  • 汎用乗算サブルーチン $C01098 により、積 A = AH * AL を計算する。

  • A レジスタにロード済みの積を $70 にロードする。

  • さらに $72 にゼロをロードする。

  • 制御を呼び出し元に戻す。

このことから、呪いを解くための寄付金は、 レベル * 30 と憶えておけばよいことがわかる。

5.13.1.10. 「どくのちりょう」- 寄付金計算サブルーチン

サブルーチン $C3D74C は選択したメンバーの解毒をするために寄付をする金額を計算する。

  • 汎用サブルーチン $C42FEB により、選択メンバーのレベルを A レジスタにロードする。

  • A >> 2 + 4$70 にロードする。

  • さらに $72 にゼロをロードする。

  • 制御を呼び出し元に戻す。

このことから、毒の治療に必要な寄付金は、 レベル / 4 + 4 と憶えておけばよいことがわかる。