Come un anello mira al giocatore
L'attacco di Elly richiede un anello mirato con un conteggio iniziale di 16. Un aiutante calcola la direzione di ogni proiettile. Lo stesso anello può affrontare una direzione fissa o girare verso il giocatore.
Usa REA per scoprire come TH04 crea un anello di proiettili e lo mira al giocatore. Spiega il calcolo e mostra il codice.
Un prompt di esempio, con l'eseguibile originale e il checkout di ricostruzione disponibili localmente.
TH04 memorizza una rotazione completa in senso orario in 256 unità angolari. Per 16 punti, ogni indice aggiunge 16 unità: 0, 16, 32, …, 240. Aggiungendo la direzione del giocatore ruota insieme quelle posizioni.
Il modello di cottura nella fonte recuperata
bullet_template.angle = 0;
bullet_template.group = BG_RING_AIMED;
bullet_template.count = 16;
bullet_template_tune();
Queste linee selezionano il modello prima della difficoltà e della messa a punto delle prestazioni. Leggi la fonte dell'attacco.
Cosa restituisce REA
Controlliamo bullet_velocity_and_angle_set(), la funzione che imposta la velocità e l'angolo di ogni proiettile. REA restituisce le sue istruzioni, pseudocodice e riferimenti. Tre parti di questo risultato spiegano il modello.
-
Controllare l'immagine DOS prima di leggere il suo codice
Agente → REAopen_binary {"path": "MAIN.EXE"} inspect_native_load_image {}REA → agente * campi selezionatistatus: "verified" format: "dos-mz" load_segment: 4096 header_bytes: 6144 module_bytes: 150114Il controllo lega il codice caricato e i record di rilocazione all'eseguibile fornito. Il percorso sopra è abbreviato per la visualizzazione.
-
Leggi l'anello moltiplica e dividi
Agente → REA ·analyze_function{"procedure": "0x2cfc8"}REA → agente * estratto di istruzioni0x2d0eb: MOV AX, SI 0x2d0ed: SHL AX, 0x8 0x2d0f0: MOV DL, byte ptr [0x53af] 0x2d0f9: IDIV BXSIcontiene l'indice proiettile. Lo spostamento lo moltiplica per 256, quindi la divisione utilizza il conteggio letto daDS:53AF. I nomi di origine mantenuti quel campobullet_template.count. La sequenza completa appare sotto. -
Trova dove il modello gira verso il giocatore
Stesso risultato di funzione * estratto aim0x2d190: SUB AX, word ptr [0x53a6] 0x2d198: SUB AX, word ptr [0x53a4] 0x2d19d: CALLF 0x1000:1da8 0x2d1a2: ADD word ptr [BP + -0x2], AXCorrispondente mantenuto C++group_angle_offset += iatan2( player_pos.cur.y - bullet_template.origin.y, player_pos.cur.x - bullet_template.origin.x );Gli operandi di istruzione espongono due differenze di coordinate e un assistente di direzione. Il suo valore di ritorno viene aggiunto all'angolo dell'anello relativo. I nomi di origine rendono leggibili quegli indirizzi; REA consente all'agente di controllare le operazioni originali dietro di loro.
Dall'assembly al C++leggibile
Selezionare un passaggio che corrisponda alle istruzioni originali con il calcolo dell'angolo. Questo riepilogo segue il percorso dell'anello mirato; la fonte completa gestisce anche spread, stack e modelli casuali.
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 * Leggere l'indice proiettile. L'argomento stack viene caricato in SI. In un anello a 16 proiettili, questo indice membro va da 0 a 15.
02 * Spazio le direzioni intorno a un giro completo. SHL AX,8 moltiplicato per 256. Il conteggio è zero-esteso in una parola, quindi IDIV divide il prodotto per quel conteggio. Per il conteggio 16, ogni indice avanza di 16 unità angolari.
03 * Aggiungi la direzione del giocatore. Le due sottrazioni formano le coordinate player-minus-origin. L'assistente di direzione restituisce un angolo in AX; aggiungendo si gira l'intero anello verso il giocatore.
04 * Aggiungere la rotazione del modello. ADD AL,[0x53ad] aggiunge l'angolo del modello. Il modello iniziale di Elly lo imposta a zero; altri modelli possono utilizzare lo stesso helper con una rotazione.
05 * Mantenere l'angolo finale in un byte. Il negozio scrive AL al campo angolo di spawn. I valori si chiudono dopo 255, proprio come fa il cast di byte senza segno. La sorgente circostante converte anche questo angolo e velocità in velocità.
L'assemblaggio seleziona il ramo dell'anello di mira, il calcolo dell'obiettivo e l'archivio finale. Il C++ sopra è un riassunto leggibile. I controlli del compilatore riportati di seguito si applicano all'origine mantenuta nel progetto collegato.
Leggi l'anello mantenuto e la fonte aim
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);
Anello macro · Sorgente di mira e velocità · Rappresentazione angolare
Verifica della fonte mantenuta
I controlli registrati del progetto TH04 compilano il codice di generazione bullet, incluso questo helper, con la sua toolchain Turbo C++ 4.0 J bloccata.
2,139 byte corrispondenti
Il codice di generazione bullet compilato corrisponde a una sezione di 2.139 byte dell'eseguibile originale.
Due build pulite
Due build separate producono gli stessi byte corrispondenti. Gli hash di input registrati corrispondono alla sorgente mantenuta mostrata qui.
Registrato il 3 ottobre 2026. Leggi i controlli del compilatore.
Identità target e ambito di analisi
| Obiettivo originale | MAIN.EXE, 156,258 byte, DOS MZ |
|---|---|
| Helper entry | 0x2cfc8 nell ' immagine caricata di REA |
| Offset file originale |
0x1e7c8, restituito da address_to_file_offset
|
| Ispezione del codice registrato | REA 4.1.0 * 7 Ottobre 2026 |
I controlli del compilatore coprono la sezione completa del codice bullet-add, incluso questo helper. Confrontano anche il suo contributo alla MAPPA e il trasferimento sovrapposto.
REA verificato l'immagine di carico statico DOS al segmento di carico 0x1000. I suoi indirizzi descrivono quell'immagine di analisi. Il risultato della funzione riporta 503 byte del corpo in due intervalli su un intervallo di 517 byte; le istruzioni selezionate sopra si trovano in quegli intervalli riportati.
I nomi dei sorgenti e i controlli del compilatore provengono dal checkpoint TH04 0d72e980. Le precedenti osservazioni di ricostruzione utilizzavano gli script di analisi del progetto; questa pagina aggiunge una nuova ispezione REA dello stesso obiettivo originale. L'identità del gioco in dotazione è bloccata dal suo repository manifest, con la provenienza indipendente di pristine-dump ancora aperta.
La figura illustra il calcolo dell'angolo. I controlli di gioco completi, i tempi e il comportamento hardware PC-98 hanno controlli di runtime separati nel progetto di ricostruzione.
La ricostruzione completa TH04
Il progetto costruisce quattro prodotti DOS del gioco da mantenuto C++ e assembly. Oltre alla generazione di proiettili, la fonte copre fasi, boss, rendering, input, menu, finali e gestione dei punteggi.
- Fonte di generazione di proiettiliL'helper completo, altri tipi di pattern e template tuning.
- DOS costruire ed eseguire guidaCrea il sorgente e testalo nel flusso di lavoro dell'emulatore PC-98 del progetto.
- Stato attuale del progettoVerifica DOS e la porta x64 nativa separata.