Jak pierścień celuje w gracza
Atak Elly wymaga wycelowanego pierścienia z początkową liczbą 16. Jeden Pomocnik oblicza kierunek każdego pocisku. Ten sam pierścień może być skierowany w ustalonym kierunku lub skręcić w kierunku gracza.
Użyj REA, aby dowiedzieć się, jak TH04 tworzy pierścień pocisków i celuje w gracza. Wyjaśnij obliczenia i pokaż kod.
Przykładowy monit z oryginalnym plikiem wykonywalnym i kasą rekonstrukcji dostępną lokalnie.
TH04 przechowuje pełny obrót zgodnie z ruchem wskazówek zegara w jednostkach kąta 256. Dla 16 pocisków każdy indeks dodaje 16 jednostek: 0, 16, 32, …, 240. Dodanie kierunku gracza obraca te pozycje razem.
Szablon wypalania w odzyskanym źródle
bullet_template.angle = 0;
bullet_template.group = BG_RING_AIMED;
bullet_template.count = 16;
bullet_template_tune();
Linie te wybierają wzór przed trudnością i strojeniem wydajności. Przeczytaj źródło ataku.
Co zwraca REA
Sprawdzamy bullet_velocity_and_angle_set(), funkcja, która ustawia prędkość i kąt każdego pocisku. REA zwraca instrukcje, pseudokod i odwołania. Trzy części tego wyniku wyjaśniają wzór.
-
Sprawdź obraz DOS przed przeczytaniem jego kodu
Agent → REAopen_binary {"path": "MAIN.EXE"} inspect_native_load_image {}REA → agent * wybrane polastatus: "verified" format: "dos-mz" load_segment: 4096 header_bytes: 6144 module_bytes: 150114Sprawdzenie wiąże załadowany kod i rekordy relokacji z dostarczonym plikiem wykonywalnym. Ścieżka powyżej jest skrócona do wyświetlania.
-
Przeczytaj mnożenie i dzielenie pierścienia
Agent → REA ·analyze_function{"procedure": "0x2cfc8"}REA → agent * fragment instrukcji0x2d0eb: MOV AX, SI 0x2d0ed: SHL AX, 0x8 0x2d0f0: MOV DL, byte ptr [0x53af] 0x2d0f9: IDIV BXSIposiada indeks punktora. Przesunięcie mnoży go przez 256, a następnie podział wykorzystuje liczbę odczytaną zDS:53AF. Utrzymane nazwy źródłowe tego polabullet_template.count. Pełna sekwencja pojawia się poniżej. -
Znajdź, gdzie wzór obraca się w kierunku gracza
Ta sama funkcja wynik * aim fragment0x2d190: SUB AX, word ptr [0x53a6] 0x2d198: SUB AX, word ptr [0x53a4] 0x2d19d: CALLF 0x1000:1da8 0x2d1a2: ADD word ptr [BP + -0x2], AXOdpowiadający utrzymywany C++group_angle_offset += iatan2( player_pos.cur.y - bullet_template.origin.y, player_pos.cur.x - bullet_template.origin.x );Operandy instrukcji ujawniają dwie różnice współrzędnych i pomocnika kierunku. Jego wartość zwracana jest dodawana do względnego kąta pierścienia. Nazwy źródeł sprawiają, że adresy te są czytelne; REA pozwala agentowi sprawdzić oryginalne operacje za nimi.
Od zestawu do czytelnego C++
Wybierz krok, aby dopasować oryginalne instrukcje do obliczenia kąta. To podsumowanie podąża ścieżką ukierunkowanego pierścienia; pełne źródło obsługuje również spready, stosy i losowe wzory.
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 * przeczytaj indeks punktora. Argument stosu jest ładowany do SI. W pierścieniu z 16 pociskami ten indeks członków biegnie od 0 do 15.
02 * Rozmieść Kierunki wokół pełnego obrotu. SHL AX,8 mnoży się przez 256. Liczba jest zerowa-rozszerzona na słowo, a następnie IDIV dzieli produkt przez tę liczbę. W przypadku liczby 16 każdy indeks przesuwa się o 16 jednostek kąta.
03 * Dodaj kierunek gracza. Dwa odejmowania tworzą współrzędne player-minus-origin. Pomocnik kierunku zwraca kąt w AX; dodanie go obraca cały pierścień w kierunku gracza.
04 * Dodaj obrót wzoru. ADD AL,[0x53ad] dodaje kąt szablonu. Początkowy szablon Elly ustawia go na zero; inne wzory mogą używać tego samego pomocnika z obrotem.
05 * Zachowaj ostateczny kąt w jednym bajcie. Sklep pisze AL do pola kąta odrodzenia. Wartości zawijają się po 255, tak jak robi to odlewanie bez znaku. Otaczające źródło również przekształca ten kąt i prędkość w prędkość.
Zespół wybiera gałąź pierścienia celowanego, obliczenie celu i końcowy magazyn. Powyższy C++ jest czytelnym podsumowaniem. Poniższe kontrole kompilatora dotyczą utrzymywanego źródła w połączonym projekcie.
Przeczytaj utrzymane źródło pierścienia i celu
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);
Makro pierścienia · Cel i źródło prędkości · Reprezentacja kąta
Sprawdzanie utrzymywanego źródła
Zarejestrowane kontrole projektu TH04 kompilują kod generowania pocisków, w tym ten pomocnik, z przypiętym łańcuchem narzędzi Turbo C++ 4.0 J.
2139 pasujących bajtów
Skompilowany kod generowania punktorów pasuje do 2139-bajtowej sekcji oryginalnego pliku wykonywalnego.
Dwie czyste Kompilacje
Dwie oddzielne Kompilacje dają te same pasujące bajty. Zapisane skróty wejściowe odpowiadają wyświetlonemu tutaj utrzymywanemu źródłu.
Zarejestrowany 3 października 2026 roku. Przeczytaj kontrole kompilatora.
Tożsamość celu i zakres analizy
| Oryginalny cel | MAIN.EXE, 156 258 bajtów, DOS MZ |
|---|---|
| Wpis pomocnika | 0x2cfc8 w załadowanym obrazie REA |
| Oryginalny plik offset |
0x1e7c8, zwrócony przez address_to_file_offset
|
| Rejestrowana Kontrola kodu | REA 4.1.0 * 7 października 2026 |
Kontrole kompilatora obejmują pełną sekcję bullet-add code, w tym tego pomocnika. Porównują również wkład Mapy i nakładające się relokacje.
REA zweryfikował statyczny obraz obciążenia DOS w segmencie obciążenia 0x1000. Jego adresy opisują ten obraz analizy. Wynik funkcji zgłasza 503 bajty treści w dwóch zakresach w zakresie 517 bajtów; wybrane instrukcje powyżej znajdują się w tych zgłaszanych zakresach.
Nazwy źródeł i kontrole kompilatora pochodzą z punktu kontrolnego TH04 0d72e980. Wcześniejsze obserwacje rekonstrukcji wykorzystywały własne skrypty analityczne projektu; ta strona dodaje nową inspekcję REA tego samego oryginalnego celu. Tożsamość dostarczonej gry jest przypięta przez manifest repozytorium, a niezależne pochodzenie nieskazitelnego zrzutu jest nadal otwarte.
Rysunek ilustruje obliczenie kąta. Sterowanie pełną grą, czas i zachowanie sprzętowe PC-98 mają oddzielne kontrole środowiska wykonawczego w projekcie rekonstrukcji.
Pełna rekonstrukcja TH04
Projekt buduje cztery produkty dos gry z utrzymanego C++ i assembly. Poza generowaniem pocisków, źródło obejmuje etapy, bossów, renderowanie, wprowadzanie, menu, zakończenia i obsługę punktów.
- Źródło generowania pociskówKompletny Pomocnik, inne typy wzorów i strojenie szablonów.
- Dos build and run guideZbuduj źródło i przetestuj je w przepływie pracy emulatora PC-98 projektu.
- Aktualny stan projektuWeryfikacja DOS i oddzielny natywny port x64.