ネイティブ / 体験型ケーススタディ / 読了目安:22分

TH04:16発の弾はどうやって自機を狙う?

REA で TH04 の円形弾幕を調査。1バイトの角度、照準、回転を追い、操作できる図で小さな再実装を検証します。

このページの内容

01. 解析する前に試してみる

中央の周りでひし形を動かし、円形弾幕を発射してください。淡い線は最初の弾を示します。弾数を16から12にすると、整数の角度刻みでは円を等分できなくなります。キーボードを使う場合はスライダーで操作できます。

照準の実験試す / 観察する / 説明する
1バイトの角度 321周 256
ひし形をドラッグして狙いを動かす0 → / 64 ↓

16方向を16角度単位ずつ離して配置します。

ゲーム映像ではなく角度の図解です。マウスの照準は atan2 を使った近似で、元の実装は iatan2 を使います。

作るもの

操作できる角度図と、丸め・桁あふれの折り返しを明示的に検証する小さな円形配置の計算。

調査の前に

図はすぐに使えます。バイナリ調査を再現するには、一致する手元の TH04 MAIN.EXE、設定済み Ghidra プロバイダー、以下にリンクした固定版の再実装ソースが必要です。 REA を設定する →

02. 実行ファイルのアドレス体系を確認する

TH04 は PC-98 の DOS プログラムです。関数のアドレスをたどる前に、ローダーがファイルをメモリーへどう配置するかを確認します。実行ファイルのハッシュ、ロードセグメント、コードモード、アドレスとファイル位置の対応を記録してください。読み込み条件のないアドレスは、誤ったバイト列を指す可能性があります。

公式報告には、調査の手がかりとなる既知のヘルパーと固定版の再実装があります。それを起点にするのはガイド付きの演習であり、エージェントが単独でプログラム全体を発見した証拠ではありません。

この調査用プロンプトをコピー
REA を使い、手元の TH04 MAIN.EXE を Ghidra で開いてください。DOS MZ のロード設定とファイルの同一性を、リンク先の TH04 検証レポートと照合します。一致したら、報告にある bullet_velocity_and_angle_set ヘルパーを調べ、アドレスをファイルのバイト位置へ対応付けてください。ファイルやロード設定が異なる場合は過去のアドレスを使わず、対応するヘルパーの探し方を説明してください。

03. 円を描く前に一つの方向を読み解く

鍵は演算の順序です。インデックス、弾数、照準角、回転を別々に確認します。この円形配置の分岐は、floor(index × 256 / count) に照準角と回転を加え、1バイトに折り返すモデルで表せます。画面では時計回りに角度が増えます。

12発を試してください。先に掛けてから割るとオフセットは0、21、42、64…です。floor(256 / count) にインデックスを掛けると0、21、42、63…になります。最初は一致しても、途中からずれます。見た目がもっともらしい円でも、誤りは隠れています。

  • 16発、照準角なし:0、16、32、…、240。
  • 12発:インデックス3は63ではなく64。
  • 照準角250にオフセット16を加えると、折り返して10。
  • 右が0、下が64、左が128、上が192。

04. 円形配置と照準ヘルパーを分ける

自機と原点の座標が方向ヘルパーに入る箇所を追います。次にテンプレートの回転を加える場所と、最終的な1バイトを保存する場所を探します。各段階をテストできるよう、別々の調査結果として記録してください。

この図は、マウス方向に照準を合わせるため JavaScript の atan2 を使い、最も近い1バイト角度へ丸めています。元の実装は iatan2 です。すべての自機座標で完全な一致を示すには、そのヘルパーも読み解いて検証する必要があります。ここでは同等性を主張せず、円形配置の計算を示します。

この調査用プロンプトをコピー
自機狙いの円形弾幕の分岐だけを読み解いてください。乗算後に除算する命令列、照準角を求める呼び出し、テンプレートの回転の加算、最終バイトの保存を示します。円形配置の計算を独立して実装し、元の iatan2 の動作を別途確認するまでは、図の照準関数を近似と明記してください。12発と16発、負の回転、折り返しをテストします。

05. 見た目を判断する前に角度をテストする

意図的に扱いづらい入力を選び、角度の数値を出力します。スクリーンショットでは1単位の誤差が正しく見えることがあります。均等割りできない弾数、255に近い照準角、ゼロをまたぐ回転をテストし、間隔だけでなく最終的なバイトの範囲も確認します。

最初の線がポインターから少しずれる場合は、円形配置の式を変える前に角度の量子化を調べます。上下が反転するなら座標系を確認してください。ネイティブの呼び出しグラフに矛盾が見えるなら、リアルモードのセグメント対応と実際の命令を確認します。

06. 既知の結果と比較する

以下を明確な確認点として使います。一致しても、この小さなルールを裏付けるだけで、アプリ全体の互換性を示すものではありません。

入力値期待される角度見つけられる問題
弾数16、照準角0、回転00, 16, 32, …, 240等間隔
弾数12、照準角0、回転00, 21, 42, 64, …, 234乗算してから除算
弾数16、照準角250、回転0250, 10, 26, …, 2341バイトの折り返し
弾数4、照準角0、回転−1255, 63, 127, 191負の回転の正規化

両方を同じフォルダーに保存し、Node.js で検証を実行します。パッケージのインストールは不要です。

ターミナル
node check-case-labs.mjs

07. 実際に検証したのはどこまで?

当サイトでは、抽出した円形配置の計算を検証し、新しい図を描画しています。元の DOS プログラムの実行、iatan2 ヘルパーの再現、過去のコンパイラーテストの再実行は行っていません。16発は学習用に選んだ数で、ゲームのすべての難易度や発射状態を示すものではありません。

当サイトの数値テスト結果を読む →

出典: REA の TH04 検証レポート · 固定版の再実装にある円形配置マクロ。チュートリアル、図、ブラウザー実験は独自制作です。

次の実験音だけでブロックの左右が分かる? →

REA は初めてですか? REA とは? · ガイドの検証方針