原生程式 / 互動案例 / 閱讀約 22 分鐘
TH04:16 顆子彈怎麼知道你在哪?
用 REA 分析 TH04 環形彈幕,追蹤位元組角度、瞄準和旋轉,並在互動圖示中驗證一個小型重建實作。
本頁內容
01. 拆解之前,先試一試
把菱形拖到中心附近,再發射一圈子彈。淺色射線標記第一顆子彈。把數量從 16 改為 12:整數角度步長無法再均分整圈。也可以用鍵盤操作下方滑塊。
16 個方向,每個相隔 16 個角度單位。
這是角度圖示,並非遊戲實錄。滑鼠瞄準使用近似 atan2 換算;原程式使用 iatan2。
一個互動角度圖示,以及明確驗證捨入和迴繞的小型環形計算。
分析之前圖示可直接使用。若要重複二進位分析,請準備匹配的 TH04 MAIN.EXE 並設定 Ghidra 分析後端。還需要下方連結中的固定版本重建原始碼。 設定 REA →
02. 先弄清可執行檔案的地址體系
TH04 是 PC-98 DOS 程式。追蹤函式地址前,先確認載入器如何把檔案對映到記憶體。紀錄可執行檔案雜湊、載入段、程式碼模式和地址到檔案的對映關係。缺少載入設定的地址,可能讓你讀到錯誤位元組。
官方報告提供已知輔助函式和固定版本的重建程式碼,幫助確定分析方向。藉助這個錨點屬於引導練習,並不代表 AI 代理獨立發現了整個程式。
使用 REA 和 Ghidra 開啟我的 TH04 MAIN.EXE。對照連結的 TH04 證據報告,驗證 DOS MZ 載入設定和檔案身份。若匹配,分析報告中的 bullet_velocity_and_angle_set 輔助函式,並將地址對映回檔案位元組。若檔案或載入設定不同,停止使用歷史地址,並解釋如何找到等價函式。03. 畫圓之前,先還原一個方向
關鍵是運算順序。分別梳理索引、數量、瞄準和旋轉。這個環形分支可理解為 floor(index × 256 / count),再加上瞄準角和旋轉角,最後迴繞到一個位元組。螢幕上的角度沿順時針增加。
試試十二顆子彈。先乘再除得到偏移 0、21、42、64…;如果用索引乘以 floor(256 / count),則得到 0、21、42、63…。兩者起初相同,隨後偏離。看起來合理的圓形也可能藏著錯誤。
- 16 顆子彈,不加瞄準角:0、16、32、…、240。
- 12 顆子彈:索引 3 應為 64,而非 63。
- 瞄準角 250 加偏移 16,迴繞後為 10。
- 右側為 0,下方為 64,左側為 128,上方為 192。
04. 將環形規則與瞄準函式分開
追蹤玩家和發射原點座標從哪裡進入方向函式,再找到模板旋轉角的相加位置,以及最終位元組的儲存位置。將它們分別紀錄,才能逐階段測試。
圖示使用 JavaScript atan2,並四捨五入為最接近的位元組角度,用於滑鼠瞄準。原程式使用 iatan2。若要在每個玩家座標上完全一致,還需還原並測試該輔助函式;本圖示只示範環形算術,不聲稱兩者等價。
只還原瞄準環形彈幕分支。展示先乘後除的指令序列、計算瞄準方向的呼叫、模板旋轉相加以及最終位元組儲存。獨立實作環形算術。在單獨確認原版 iatan2 行為之前,圖示使用明確標註的近似瞄準函式。測試 12 和 16 顆子彈、負旋轉角以及迴繞。05. 先測試角度,再判斷畫面
刻意選擇幾個棘手輸入,匯出數值角度。截圖可能讓一個單位的誤差看起來正常。測試不能均分的數量、接近 255 的瞄準角,以及跨過零點的旋轉。檢查最終位元組範圍,不要只檢查間距。
如果第一條射線略微偏離指標,先檢查角度量化,再修改環形計算。如果圖示上下映象,檢查座標約定。如果原生呼叫圖不一致,檢查真實模式段對映和指令證據。
06. 比較已知結果
將這些結果作為明確的檢查點。與它們一致,只能支持這一小段規則,不能證明與整個應用程式相容。
| 輸入 | 預期角度 | 能發現的問題 |
|---|---|---|
| 數量 16;瞄準角 0;旋轉角 0 | 0, 16, 32, …, 240 | 均勻間距 |
| 數量 12;瞄準角 0;旋轉角 0 | 0, 21, 42, 64, …, 234 | 先乘後除 |
| 數量 16;瞄準角 250;旋轉角 0 | 250, 10, 26, …, 234 | 位元組迴繞 |
| 數量 4;瞄準角 0;旋轉角 −1 | 255, 63, 127, 191 | 負旋轉角正規化 |
將兩個檔案儲存在同一資料夾,用 Node.js 執行驗證指令碼,無需安裝套件。
node check-case-labs.mjs07. 到底驗證了什麼?
本站測試提取出的環形算術,並繪製獨立圖示。我們沒有執行原 DOS 程式、重現 iatan2 輔助函式,或重複歷史編譯器驗證。十六顆只是選定的教學數量,並不代表所有遊戲難度或發射狀態。
來源: REA 的 TH04 證據報告 · 固定版本的重建環形宏。教學、圖示和瀏覽器實驗均獨立編寫。