ケーススタディ*東方4:蓮の国物語

TH04の再構築
弾丸のパターン。

弾丸のリングは、短い角度の計算で始まります。 REAを使用して元のDOS関数を検査し、その指示に従って読み取り可能なC++に従います。

PC-98*16ビットDOS·C++およびアセンブリ

TH04再構成を見る

元の指示からチェックされたソースへ

  1. 01*オリジナルゲームメイン...EXEPC-98実行可能ファイルとそのbullet-angleヘルパー。
  2. 02*REAと点検して下さい 説明書+参考文献ロードされたDOSコードを確認し、実行可能ファイルから角度計算を読み取ります。
  3. 03*C++を読むスペース→狙い→回転各操作を維持された再構成に接続します。
  4. 04*ソースを確認する一致するバイト数2,139件記録されたコンパイラチェックは、このヘルパーを含む箇条書き生成コードをカバーします。
REAは、元のコードとその分析証拠を返します。 TH04プロジェクトは、保守されたソースとコンパイラのチェックを提供します。

リングがプレーヤーをどのように狙うか

エリーの攻撃は、最初のカウント16の目的としたリングを要求します。 一つのヘルパーは、各弾丸の方向を計算します。 同じリングは、固定方向に直面したり、プレイヤーに向かって回すことができます。

あなたのコーディングエージェント

REAを使用して、TH04が弾丸のリングを作成し、プレイヤーにそれを向ける方法を見つけます。 計算を説明し、コードを表示します。

元の実行可能ファイルと再構築チェックアウトがローカルで利用可能なプロンプトの例。

TH04は256の角度の単位で完全な右回りの回転を貯える。 16箇条書きの場合、各インデックスには16単位が追加されます: 0, 16, 32, …, 240. プレイヤーの方向を追加すると、それらの位置が一緒に回転します。

16弾のリングの2つの図。 固定リングは角度ゼロから始まります。 40のプレイヤーの方向を追加すると、すべての方向が同じ量だけ回転します。強調表示された最初の箇条書きは、プレイヤーに向かって指します。 どちらも16角度単位、つまり22.5度の間隔を保ちます。
カウント16、プレイヤーの方向40、およびテンプレートの回転0のための回収された角度の数学の図。 オープンフィギュア

回収されたソース内の発射テンプレート

エリーのリングアタック·ソース抜粋
bullet_template.angle = 0;
bullet_template.group = BG_RING_AIMED;
bullet_template.count = 16;
bullet_template_tune();

これらの行は、難易度とパフォーマンスチューニングの前にパターンを選択します。 攻撃のソースを読む.

REAが返すもの

私達は点検します bullet_velocity_and_angle_set()、各弾丸の速度と角度を設定する関数。 REAは、その命令、擬似コード、および参照を返します。 その結果の3つの部分がパターンを説明しています。

  1. コードを読む前にDOSイメージを確認してください

    エージェント→REA
    open_binary
    {"path": "MAIN.EXE"}
    
    inspect_native_load_image
    {}
    REA→エージェント·選択されたフィールド
    status: "verified"
    format: "dos-mz"
    load_segment: 4096
    header_bytes: 6144
    module_bytes: 150114

    このチェックは、ロードされたコードと再配置レコードを提供された実行可能ファイルに関連付けます。 上記のパスは表示のために短縮されています。

  2. リングの乗算と除算を読む

    エージェント→REA · analyze_function
    {"procedure": "0x2cfc8"}
    REA→エージェント*命令抜粋
    0x2d0eb: MOV AX, SI
    0x2d0ed: SHL AX, 0x8
    0x2d0f0: MOV DL, byte ptr [0x53af]
    0x2d0f9: IDIV BX

    SI 箇条書きのインデックスを保持します。 シフトはそれに256を乗算し、除算はから読み取られたカウントを使用します DS:53AF. そのフィールドに保持されているソース名 bullet_template.count. 完全なシーケンスが以下に表示されます。

  3. パターンがプレイヤーに向かって回転する場所を見つける

    同じ機能結果-目安抜粋
    0x2d190: SUB AX, word ptr [0x53a6]
    0x2d198: SUB AX, word ptr [0x53a4]
    0x2d19d: CALLF 0x1000:1da8
    0x2d1a2: ADD word ptr [BP + -0x2], AX
    対応c++
    group_angle_offset += iatan2(
      player_pos.cur.y - bullet_template.origin.y,
      player_pos.cur.x - bullet_template.origin.x
    );

    命令オペランドは、2つの座標差と方向ヘルパーを公開します。 その戻り値は相対的なリング角度に追加されます。 REAは、エージェントがそれらの背後にある元の操作をチェックすることができます。

アセンブリから読み取り可能なC++へ

元の指示と角度の計算に一致するステップを選択します。 完全なソースは、スプレッド、スタック、ランダムパターンも処理します。

REA•オリジナルの16ビット命令
0x2cfcf: MOV SI, word ptr [BP + 0x4]
0x2d0eb: MOV AX, SI
0x2d0ed: SHL AX, 0x8
0x2d0f0: MOV DL, byte ptr [0x53af]
0x2d0f4: MOV DH, 0x0
0x2d0f6: PUSH DX
0x2d0f7: CWD
0x2d0f8: POP BX
0x2d0f9: IDIV BX
0x2d0fb: MOV word ptr [BP + -0x2], AX
0x2d18d: MOV AX, [0x4650]
0x2d190: SUB AX, word ptr [0x53a6]
0x2d194: PUSH AX
0x2d195: MOV AX, [0x464e]
0x2d198: SUB AX, word ptr [0x53a4]
0x2d19c: PUSH AX
0x2d19d: CALLF 0x1000:1da8
0x2d1a2: ADD word ptr [BP + -0x2], AX
0x2d1b9: MOV AL, byte ptr [BP + -0x2]
0x2d1bc: ADD AL, byte ptr [0x53ad]
0x2d1c0: MOV [0xbcc8], AL
-----------
unsigned char aimed_ring_angle(
    int index, int count,
    int player_direction,
    unsigned char rotation)
{
    int angle = index;
    angle = (angle * 256) / count;
    angle += player_direction;
    angle += rotation;
    return (unsigned char)angle;
}

01*箇条書きの索引を読みます。 Stack引数は次の場所にロードされます SI. 16箇条書きのリングでは、このメンバーインデックスは0から15まで実行されます。

アセンブリは目的とされたリング枝、目的の計算および最終的な店を選ぶ。 上記のC++は読みやすい要約です。 以下のコンパイラチェックは、リンクされたプロジェクトの保守されたソースに適用されます。

リングを読み、ソースを目指してください。
リングマクロ·TH04ブランチ、抜粋
angle_offset = (i * BULLET_ANGLE_FULL_TURN) / count;
if (i >= (count - 1)) {
    group_complete = true;
}
goto aim_or_no_aim;
角度と速度·ソース抜粋
aim:
    group_angle_offset += iatan2(
        (player_pos.cur.y - bullet_template.origin.y),
        (player_pos.cur.x - bullet_template.origin.x)
    );

no_aim:
    vector2_near(
        bullet_template.velocity,
        (group_angle_offset + bullet_template.angle),
        speed
    );
    bullet_spawn_angle = (group_angle_offset + bullet_template.angle);

リングマクロ · 目的および速度の源 · 角度表現

保守されたソースの確認

TH04プロジェクトの記録されたチェックは、このヘルパーを含む箇条書き生成コードを、固定されたTurbo C++4.0Jツールチェーンでコンパイルします。

一致するバイト数2,139件

コンパイルされた箇条書き生成コードは、元の実行可能ファイルの2,139バイトのセクションに一致します。

二つのクリーンビルド

2つの別々のビルドでは、同じ一致するバイトが生成されます。 記録された入力ハッシュは、ここに示されている維持されたソースと一致します。

2026年10月3日に録音されました。 コンパイラチェックを読む.

ターゲットidと分析範囲
元のターゲット MAIN.EXE、156,258バイト、DOS MZ
ヘルパーエントリー 0x2cfc8 REAのロードされたイメージで
元のファイルオフセット 0x1e7c8、によって返される address_to_file_offset
記録されたコード検査 REA4.1.0•2026年10月7日

コンパイラチェックは、このヘルパーを含む完全なbullet-add codeセクションをカバーしています。 彼らはまた、そのマップの貢献と重複した再配置を比較します。

REAは負荷セグメントで静的DOS負荷イメージを検証しました 0x1000. そのアドレスは、その分析画像を記述します。 関数の結果は、517バイトのスパンにわたって2つの範囲で503のボディバイトを報告します。上記の選択された命令は、それらの報告された範囲にあります。

ソース名とコンパイラチェックはTH04チェックポイントから来ています 0d72e980. このページでは、同じ元のターゲットの新しいREA検査を追加します。 提供されたゲームのアイデンティティは、リポジトリマニフェストによって固定されており、独立した原始的なダンプの出所はまだ開いています。

図は角度の計算を示しています。 完全なゲームコントロール、タイミング、およびPC-98ハードウェアの動作には、再構築プロジェクトで別々のランタイムチェックがあります。

フルTH04の再構成

このプロジェクトは、維持されたC++とアセンブリからゲームの4つのDOS製品を構築します。 弾丸の生成を超えて、ソースはステージ、ボス、レンダリング、入力、メニュー、エンディングとスコアの処理をカバーしています。

TH04リポジトリを探索する

トップ