Comment un anneau vise le joueur
L'attaque d'Elly demande un anneau visé avec un compte initial de 16. Un assistant calcule la direction de chaque balle. Le même anneau peut faire face à une direction fixe ou se tourner vers le joueur.
Utilisez REA pour découvrir comment TH04 crée un anneau de balles et le dirige vers le joueur. Expliquez le calcul et montrez le code.
Un exemple d'invite, avec l'exécutable d'origine et la récupération de reconstruction disponibles localement.
TH04 stocke un tour complet dans le sens des aiguilles d'une montre en 256 unités d'angle. Pour 16 puces, chaque index ajoute 16 unités: 0, 16, 32, …, 240. L'ajout de la direction du joueur fait pivoter ces positions ensemble.
Le modèle de tir dans la source récupérée
bullet_template.angle = 0;
bullet_template.group = BG_RING_AIMED;
bullet_template.count = 16;
bullet_template_tune();
Ces lignes sélectionnent le motif avant le réglage de la difficulté et des performances. Lire la source de l'attaque.
Quels sont les retours de REA
Nous inspectons bullet_velocity_and_angle_set(), la fonction qui définit la vitesse et l'angle de chaque balle. REA renvoie ses instructions, son pseudocode et ses références. Trois parties de ce résultat expliquent le schéma.
-
Vérifiez l'image DOS avant de lire son code
Agent → REAopen_binary {"path": "MAIN.EXE"} inspect_native_load_image {}REA → agent * champs sélectionnésstatus: "verified" format: "dos-mz" load_segment: 4096 header_bytes: 6144 module_bytes: 150114La vérification lie le code chargé et les enregistrements de relocalisation à l'exécutable fourni. Le chemin ci-dessus est raccourci pour l'affichage.
-
Lire la multiplication et la division de l'anneau
Agent → REA ·analyze_function{"procedure": "0x2cfc8"}REA → extrait d'instructions de l'agent ·0x2d0eb: MOV AX, SI 0x2d0ed: SHL AX, 0x8 0x2d0f0: MOV DL, byte ptr [0x53af] 0x2d0f9: IDIV BXSItient l'index de la balle. Le décalage le multiplie par 256, puis la division utilise le décompte lu à partir deDS:53AF. Les noms de source conservés dans ce champbullet_template.count. La séquence complète apparaît ci-dessous. -
Trouvez où le motif se tourne vers le joueur
Même fonction résultat · extrait de but0x2d190: SUB AX, word ptr [0x53a6] 0x2d198: SUB AX, word ptr [0x53a4] 0x2d19d: CALLF 0x1000:1da8 0x2d1a2: ADD word ptr [BP + -0x2], AXC++maintenu correspondantgroup_angle_offset += iatan2( player_pos.cur.y - bullet_template.origin.y, player_pos.cur.x - bullet_template.origin.x );Les opérandes d'instruction exposent deux différences de coordonnées et un assistant de direction. Sa valeur de retour est ajoutée à l'angle relatif de l'anneau. Les noms de source rendent ces adresses lisibles; REA permet à l'agent de vérifier les opérations d'origine derrière elles.
De l'assemblage au C++lisible
Sélectionnez une étape pour faire correspondre les instructions d'origine avec le calcul de l'angle. Ce résumé suit le chemin de l'anneau visé; la source complète gère également les spreads, les piles et les motifs aléatoires.
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 * Lire l'index des puces. L'argument de pile est chargé dans SI. Dans un anneau à 16 puces, cet indice de membre va de 0 à 15.
02 * Espacez les directions autour d'un tour complet. SHL AX,8 multiplie par 256. Le nombre est égal à zéro-étendu en un mot, puis IDIV divise le produit par ce nombre. Pour le compte 16, chaque index avance de 16 unités d'angle.
03 * Ajoutez la direction du joueur. Les deux soustractions forment les coordonnées d'origine du joueur-moins. L'assistant de direction renvoie un angle dans AX; en l'ajoutant, il tourne tout l'anneau vers le joueur.
04 * Ajouter la rotation du motif. ADD AL,[0x53ad] ajoute l'angle du modèle. Le modèle initial d'Elly le met à zéro; d'autres modèles peuvent utiliser le même assistant avec une rotation.
05 * Gardez l'angle final dans un octet. Le magasin écrit AL au champ d'angle d'apparition. Les valeurs s'enroulent après 255, tout comme le cast d'octets non signés. La source environnante convertit également cet angle et cette vitesse en vitesse.
L'ensemble sélectionne la branche de la bague visée, le calcul de la visée et la mémorisation finale. Le C++ ci-dessus est un résumé lisible. Les vérifications du compilateur ci-dessous s'appliquent à la source maintenue dans le projet lié.
Lire l'anneau maintenu et la source de visée
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);
Macro d'anneau · Source de visée et de vélocité · Représentation angulaire
Vérification de la source maintenue
Les vérifications enregistrées du projet TH04 compilent le code de génération de puces, y compris cet assistant, avec sa chaîne d'outils Turbo C++ 4.0 J épinglée.
2 139 octets correspondants
Le code de génération de puces compilé correspond à une section de 2 139 octets de l'exécutable d'origine.
Deux constructions propres
Deux builds distincts produisent les mêmes octets correspondants. Les hachages d'entrée enregistrés correspondent à la source maintenue illustrée ici.
Enregistré le 3 octobre 2026. Lire les vérifications du compilateur.
Identité cible et portée de l'analyse
| Cible d'origine | MAIN.EXE, 156 258 octets, sous-titres MZ |
|---|---|
| Entrée d'aide | 0x2cfc8 dans l'image chargée de REA |
| Décalage du fichier d'origine |
0x1e7c8, retourné par address_to_file_offset
|
| Inspection du code enregistré | REA 4.1.0 · 7 octobre 2026 |
Les vérifications du compilateur couvrent la section complète d'ajout de puces de code, y compris cette aide. Ils comparent également sa contribution à la CARTE et sa relocalisation qui se chevauchent.
REA a vérifié l'image de charge DOS statique au segment de charge 0x1000. Ses adresses décrivent cette image d'analyse. Le résultat de la fonction rapporte 503 octets de corps dans deux plages sur une étendue de 517 octets; les instructions sélectionnées ci-dessus se trouvent dans ces plages rapportées.
Les noms des sources et les vérifications du compilateur proviennent du point de contrôle TH04 0d72e980. Les observations de reconstruction antérieures utilisaient les propres scripts d'analyse du projet; cette page ajoute une nouvelle inspection REA de la même cible d'origine. L'identité du jeu fourni est épinglée par son manifeste de référentiel, avec une provenance de vidage vierge indépendante toujours ouverte.
La figure illustre le calcul de l'angle. Les contrôles complets du jeu, le timing et le comportement du matériel PC-98 ont des vérifications d'exécution distinctes dans le projet de reconstruction.
La reconstruction complète du TH04
Le projet construit les quatre produits DOS du jeu à partir de C++ et d'assembly maintenus. Au-delà de la génération de puces, la source couvre les étapes, les boss, le rendu, la saisie, les menus, les fins et la gestion des partitions.
- Source de génération de ballesL'assistant complet, d'autres types de motifs et le réglage des modèles.
- Guide de construction et d'exécution DOSCréez la source et testez-la dans le flux de travail de l'émulateur PC-98 du projet.
- État actuel du projetVérification DOS et port x64 natif séparé.