---
title: 'Rekayasa Balik TH04: Pola Peluru DOS-REA'
url: https://rea.tools/id/showcase/th04/
---

[Rumah](https://rea.tools/id/) / [Menampilkan](https://rea.tools/id/showcase/) / TH04

Studi kasus \* Touhou 4: Kisah Tanah Teratai

# Merekonstruksi TH04 pola peluru.

Cincin peluru dimulai dengan perhitungan sudut pendek. Gunakan REA untuk memeriksa fungsi DOS asli, lalu ikuti instruksinya ke dalam C++yang dapat dibaca.

PC-98 \* DOS 16-bit \* C++ dan perakitan

[Lihat rekonstruksi TH04](https://github.com/N0zoM1z0/th04)

Dari instruksi asli hingga sumber yang dicentang

1. 01 \* Game asli

   **UTAMA.EXE**

   PC-98 dapat dieksekusi dan pembantu sudut pelurunya.
2. 02 \* Periksa dengan REA

   **Instruksi + referensi**

   Verifikasi kode DOS yang dimuat dan baca perhitungan sudut dari yang dapat dieksekusi.
3. 03 \* Baca C++

   **Ruang →** 

   Hubungkan setiap operasi ke rekonstruksi yang dipertahankan.
4. 04 \* Periksa sumbernya

   **2.139 byte yang cocok**

   Pemeriksaan kompilator yang direkam mencakup kode pembuatan peluru yang berisi pembantu ini.

REA mengembalikan kode asli dan bukti analisisnya. Proyek TH04 menyediakan pemeriksaan sumber dan kompiler yang dipelihara.

## Bagaimana sebuah cincin mengincar pemain

Serangan Elly meminta cincin terarah dengan hitungan awal 16. Satu pembantu menghitung arah setiap peluru. Cincin yang sama dapat menghadap ke arah yang tetap atau berbelok ke arah pemain.

Agen pengkodean Anda

Gunakan REA untuk menemukan bagaimana TH04 membuat cincin peluru dan mengarahkannya ke pemain. Jelaskan perhitungannya dan tunjukkan kodenya.

Contoh prompt, dengan eksekusi asli dan checkout rekonstruksi tersedia secara lokal.

TH04 menyimpan putaran searah jarum jam penuh dalam 256 unit sudut. Untuk 16 peluru, setiap indeks menambahkan 16 unit: `0, 16, 32, …, 240`. Menambahkan arah pemain memutar posisi tersebut bersama-sama.

![Dua diagram cincin 16 peluru. Cincin tetap dimulai pada sudut nol. Menambahkan arah pemain sebanyak 40 memutar setiap arah dengan jumlah yang sama; poin-poin pertama yang disorot mengarah ke pemain. Keduanya menjaga jarak 16 unit sudut, atau 22,5 derajat.](https://rea.tools/assets/localized/id/figures/th04-bullet-ring.svg)

Ilustrasi matematika sudut yang dipulihkan untuk hitungan 16, arah pemain 40, dan rotasi templat 0. [Sosok terbuka](https://rea.tools/assets/localized/id/figures/th04-bullet-ring.svg)

### Templat penembakan di sumber yang dipulihkan

Serangan cincin Elly \* kutipan sumber

```
bullet_template.angle = 0;
bullet_template.group = BG_RING_AIMED;
bullet_template.count = 16;
bullet_template_tune();
```

Garis-garis ini memilih pola sebelum tingkat kesulitan dan penyetelan kinerja. [Baca sumber serangan itu](https://github.com/N0zoM1z0/th04/blob/0d72e9801a5c14c10384efcbb6734ceccb74ee63/src/main/boss/elly_phase_ring16.cpp#L26).

## Apa yang dikembalikan REA

Kami memeriksa `bullet_velocity_and_angle_set()`, fungsi yang mengatur kecepatan dan sudut setiap peluru. REA mengembalikan instruksi, pseudocode, dan referensinya. Tiga bagian dari hasil itu menjelaskan polanya.

1. #### Periksa gambar DOS sebelum membaca kodenya

   Agent → 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
   ```

   Pemeriksaan mengikat kode yang dimuat dan catatan relokasi ke executable yang disediakan. Jalur di atas dipersingkat untuk tampilan.
2. #### Baca perkalian dan pembagian cincin

   Agent → REA · `analyze_function`

   ```
   {"procedure": "0x2cfc8"}
   ```

   REA excerpt agen · kutipan instruksi

   ```
   0x2d0eb: MOV AX, SI
   0x2d0ed: SHL AX, 0x8
   0x2d0f0: MOV DL, byte ptr [0x53af]
   0x2d0f9: IDIV BX
   ```

   `SI` memegang indeks peluru. Pergeseran mengalikannya dengan 256, kemudian pembagian menggunakan hitungan yang dibaca dari `DS:53AF`. Nama sumber yang dipertahankan bidang itu `bullet_template.count`. Urutan lengkapnya muncul di bawah ini.
3. #### Temukan di mana polanya mengarah ke pemain

   Hasil fungsi yang sama \* kutipan tujuan

   ```
   0x2d190: SUB AX, word ptr [0x53a6]
   0x2d198: SUB AX, word ptr [0x53a4]
   0x2d19d: CALLF 0x1000:1da8
   0x2d1a2: ADD word ptr [BP + -0x2], AX
   ```

   C++yang dipertahankan sesuai

   ```
   group_angle_offset += iatan2(
     player_pos.cur.y - bullet_template.origin.y,
     player_pos.cur.x - bullet_template.origin.x
   );
   ```

   Operan instruksi mengekspos dua perbedaan koordinat dan pembantu arah. Nilai pengembaliannya ditambahkan ke sudut cincin relatif. Nama sumber membuat alamat tersebut dapat dibaca; REA memungkinkan agen memeriksa operasi asli di belakangnya.

## Dari perakitan ke C++yang dapat dibaca

Pilih langkah untuk mencocokkan instruksi asli dengan perhitungan sudut. Ringkasan ini mengikuti jalur aimed-ring; sumber lengkap juga menangani penyebaran, tumpukan, dan pola acak.

REA \* instruksi 16-bit asli

```
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
```

C++ yang dapat dibaca \* ringkasan aimed-ring

```
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 \* Baca indeks poin.** Argumen tumpukan dimuat ke dalam `SI`. Dalam cincin 16 peluru, indeks anggota ini berjalan dari 0 hingga 15.

**02 \* Beri jarak arah di sekitar belokan penuh.** `SHL AX,8` dikalikan dengan 256. Hitungannya nol-diperpanjang menjadi sebuah kata, lalu `IDIV` membagi produk dengan hitungan itu. Untuk hitungan 16, setiap indeks memajukan 16 satuan sudut.

**03 \* Tambahkan arah pemutar.** Kedua pengurangan tersebut membentuk koordinat pemain-minus-asal. Helper arah mengembalikan sudut dalam `AX`; menambahkannya mengubah seluruh cincin ke arah pemain.

**04 \* Tambahkan rotasi pola.** `ADD AL,[0x53ad]` menambahkan sudut templat. Templat awal Elly menyetelnya ke nol; pola lain dapat menggunakan helper yang sama dengan rotasi.

**05 \* Pertahankan sudut akhir dalam satu byte.** Toko menulis `AL` ke bidang spawn-angle. Nilai membungkus setelah 255, seperti yang dilakukan oleh pemeran unsigned-byte. Sumber di sekitarnya juga mengubah sudut dan kecepatan ini menjadi kecepatan.

Majelis memilih cabang aimed-ring, perhitungan aim, dan penyimpanan akhir. C++ di atas adalah ringkasan yang dapat dibaca. Pemeriksaan kompiler di bawah ini berlaku untuk sumber yang dipelihara dalam proyek tertaut.

Baca sumber ring dan aim yang dipelihara

Makro cincin \* cabang TH04, kutipan

```
angle_offset = (i * BULLET_ANGLE_FULL_TURN) / count;
if (i >= (count - 1)) {
    group_complete = true;
}
goto aim_or_no_aim;
```

Sudut dan kecepatan \* kutipan sumber

```
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);
```

[Ring makro](https://github.com/N0zoM1z0/th04/blob/0d72e9801a5c14c10384efcbb6734ceccb74ee63/src/main/bullet/add_impl.hpp#L4) · [Tujuan dan sumber kecepatan](https://github.com/N0zoM1z0/th04/blob/0d72e9801a5c14c10384efcbb6734ceccb74ee63/src/main/bullet/add.cpp#L422) · [Representasi sudut](https://github.com/N0zoM1z0/th04/blob/0d72e9801a5c14c10384efcbb6734ceccb74ee63/src/main/bullet/types.hpp#L6)

## Memeriksa sumber yang dipelihara

Pemeriksaan terekam proyek TH04 mengkompilasi kode pembuatan peluru, termasuk pembantu ini, dengan rantai alat Turbo C++ 4.0 J yang disematkan.

### 2.139 byte yang cocok

Kode pembuatan peluru yang dikompilasi cocok dengan bagian 2.139 byte dari executable asli.

### Dua bangunan bersih

Dua build terpisah menghasilkan byte pencocokan yang sama. Hash input yang direkam cocok dengan sumber yang dipelihara yang ditunjukkan di sini.

Direkam pada 3 Oktober 2026. [Baca pemeriksaan kompilator](https://github.com/N0zoM1z0/th04/blob/0d72e9801a5c14c10384efcbb6734ceccb74ee63/docs/reconstruction/product/TH04_SEMANTIC_BULLET_GENERATION_V1236.md#validation).

Identitas target dan ruang lingkup analisis

|  |  |
| --- | --- |
| Target asli | `MAIN.EXE`, 156.258 byte, DOS MZ |
| Entri pembantu | `0x2cfc8` dalam gambar yang dimuat REA |
| Offset berkas asli | `0x1e7c8`, dikembalikan oleh `address_to_file_offset` |
| Pemeriksaan kode yang direkam | REA 4.1.0 \* 7 Oktober 2026 |

Pemeriksaan kompiler mencakup bagian kode bullet-add lengkap, termasuk pembantu ini. Mereka juga membandingkan kontribusi PETANYA dan relokasi yang tumpang tindih.

REA memverifikasi gambar beban DOS statis pada segmen beban `0x1000`. Alamatnya menggambarkan gambar analisis itu. Hasil fungsi melaporkan 503 byte isi dalam dua rentang dalam rentang 517 byte; instruksi yang dipilih di atas terletak pada rentang yang dilaporkan tersebut.

Nama sumber dan pemeriksaan kompiler berasal dari pos pemeriksaan TH04 `0d72e980`. Pengamatan rekonstruksi sebelumnya menggunakan skrip analisis proyek itu sendiri; halaman ini menambahkan pemeriksaan REA baru dari target awal yang sama. Identitas game yang disediakan disematkan oleh manifes repositorinya, dengan asal pristine-dump independen masih terbuka.

Gambar tersebut mengilustrasikan perhitungan sudut. Kontrol permainan lengkap, pengaturan waktu, dan perilaku perangkat keras PC-98 memiliki pemeriksaan runtime terpisah dalam proyek rekonstruksi.

## Rekonstruksi lengkap TH04

Proyek ini membangun empat produk DOS game dari maintained C++ dan assembly. Di luar pembuatan peluru, sumbernya mencakup tahapan, bos, rendering, input, menu, akhiran, dan penanganan skor.

[Jelajahi repositori TH04](https://github.com/N0zoM1z0/th04)

- [Sumber pembuatan peluru](https://github.com/N0zoM1z0/th04/blob/0d72e9801a5c14c10384efcbb6734ceccb74ee63/src/main/bullet/add.cpp#L292)Pembantu lengkap, jenis pola lain, dan penyetelan templat.
- [Panduan membangun dan menjalankan DOS](https://github.com/N0zoM1z0/th04/blob/0d72e9801a5c14c10384efcbb6734ceccb74ee63/docs/DOS_BUILD.md)Bangun sumber dan uji dalam alur kerja emulator PC-98 proyek.
- [Status proyek saat ini](https://github.com/N0zoM1z0/th04/blob/0d72e9801a5c14c10384efcbb6734ceccb74ee63/docs/RE_HANDOFF.md)Verifikasi DOS dan port x64 asli yang terpisah.
