Cómo apunta un anillo al jugador
El ataque de Elly solicita un anillo apuntado con un conteo inicial de 16. Un ayudante calcula la dirección de cada bala. El mismo anillo puede mirar en una dirección fija o girar hacia el jugador.
Usa REA para descubrir cómo TH04 crea un anillo de balas y lo apunta al jugador. Explique el cálculo y muestre el código.
Un indicador de ejemplo, con el ejecutable original y el pago de reconstrucción disponibles localmente.
TH04 almacena un giro completo en el sentido de las agujas del reloj en 256 unidades de ángulo. Para 16 viñetas, cada índice agrega 16 unidades: 0, 16, 32, …, 240. Al agregar la dirección del jugador, se rotan esas posiciones juntas.
La plantilla de cocción en la fuente recuperada
bullet_template.angle = 0;
bullet_template.group = BG_RING_AIMED;
bullet_template.count = 16;
bullet_template_tune();
Estas líneas seleccionan el patrón antes de la dificultad y el ajuste del rendimiento. Lea la fuente del ataque.
Qué devuelve REA
Inspeccionamos bullet_velocity_and_angle_set(), la función que establece la velocidad y el ángulo de cada bala. REA devuelve sus instrucciones, pseudocódigo y referencias. Tres partes de ese resultado explican el patrón.
-
Verifique la imagen de DOS antes de leer su código
Agente → REAopen_binary {"path": "MAIN.EXE"} inspect_native_load_image {}REA → agente * campos seleccionadosstatus: "verified" format: "dos-mz" load_segment: 4096 header_bytes: 6144 module_bytes: 150114La comprobación vincula el código cargado y los registros de reubicación al ejecutable suministrado. La ruta anterior se acorta para su visualización.
-
Lee el anillo multiplica y divide
Agente → REA ·analyze_function{"procedure": "0x2cfc8"}REA → extracto de instrucciones del agente ·0x2d0eb: MOV AX, SI 0x2d0ed: SHL AX, 0x8 0x2d0f0: MOV DL, byte ptr [0x53af] 0x2d0f9: IDIV BXSIsostiene el índice de bala. El desplazamiento lo multiplica por 256, luego la división usa el recuento leído deDS:53AF. La fuente mantenida nombra ese campobullet_template.count. La secuencia completa aparece a continuación. -
Encuentra dónde se dirige el patrón hacia el jugador
Resultado de la misma función · extracto del objetivo0x2d190: SUB AX, word ptr [0x53a6] 0x2d198: SUB AX, word ptr [0x53a4] 0x2d19d: CALLF 0x1000:1da8 0x2d1a2: ADD word ptr [BP + -0x2], AXCorrespondiente C ++ mantenidogroup_angle_offset += iatan2( player_pos.cur.y - bullet_template.origin.y, player_pos.cur.x - bullet_template.origin.x );Los operandos de instrucción exponen dos diferencias de coordenadas y un ayudante de dirección. Su valor de retorno se suma al ángulo relativo del anillo. Los nombres de origen hacen que esas direcciones sean legibles; REA permite al agente verificar las operaciones originales detrás de ellas.
Del ensamblado al C ++ legible
Seleccione un paso para que coincida con las instrucciones originales con el cálculo del ángulo. Este resumen sigue la ruta del anillo objetivo; la fuente completa también maneja spreads, pilas y patrones aleatorios.
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 * Lea el índice de viñetas. El argumento de la pila se carga en SI. En un anillo de 16 balas, este índice de miembros va de 0 a 15.
02 * Espacie las direcciones alrededor de una vuelta completa · SHL AX,8 multiplica por 256. El conteo es cero, extendido a una palabra, luego IDIV divide el producto por ese conteo. Para el conteo 16, cada índice avanza 16 unidades de ángulo.
03 * Agregue la dirección del jugador. Las dos restas forman coordenadas jugador-menos-origen. El ayudante de dirección devuelve un ángulo en AX; agregarlo gira todo el anillo hacia el jugador.
04 * Añadir la rotación del patrón. ADD AL,[0x53ad] agrega el ángulo de la plantilla. La plantilla inicial de Elly la establece en cero; otros patrones pueden usar el mismo ayudante con una rotación.
05 * Mantenga el ángulo final en un byte. La tienda escribe AL al campo de ángulo de generación. Los valores se ajustan después de 255, tal como lo hace la conversión de bytes sin signo. La fuente circundante también convierte este ángulo y velocidad en velocidad.
El conjunto selecciona la rama del anillo objetivo, el cálculo del objetivo y el almacén final. El C++ anterior es un resumen legible. Las comprobaciones del compilador a continuación se aplican a la fuente mantenida en el proyecto vinculado.
Lea el anillo mantenido y apunte la fuente
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 de anillo · Objetivo y fuente de velocidad · Representación de ángulos
Comprobación de la fuente mantenida
Las comprobaciones grabadas del proyecto TH04 compilan el código de generación de viñetas, incluido este ayudante, con su cadena de herramientas Turbo C++ 4.0 J anclada.
2.139 bytes coincidentes
El código compilado de generación de viñetas coincide con una sección de 2139 bytes del ejecutable original.
Dos construcciones limpias
Dos compilaciones separadas producen los mismos bytes coincidentes. Los hashes de entrada grabados coinciden con la fuente mantenida que se muestra aquí.
Grabado el 3 de octubre de 2026. Leer las comprobaciones del compilador.
Identidad del objetivo y alcance del análisis
| Objetivo original | MAIN.EXE, 156,258 bytes, DOS MZ |
|---|---|
| Entrada auxiliar | 0x2cfc8 en la imagen cargada de REA |
| Desplazamiento del archivo original |
0x1e7c8, devuelto por address_to_file_offset
|
| Inspección de código grabado | REA 4.1.0 * 7 de octubre de 2026 |
Las comprobaciones del compilador cubren la sección completa de código de adición de viñetas, incluido este ayudante. También comparan su contribución al MAPA y la reubicación superpuesta.
REA verificó la imagen de carga estática de DOS en el segmento de carga 0x1000. Sus direcciones describen esa imagen de análisis. El resultado de la función informa 503 bytes de cuerpo en dos rangos en un intervalo de 517 bytes; las instrucciones seleccionadas anteriormente se encuentran en esos rangos informados.
Los nombres de origen y las comprobaciones del compilador provienen del punto de control TH04 0d72e980. Las observaciones de reconstrucción anteriores utilizaron los propios scripts de análisis del proyecto; esta página agrega una nueva inspección REA del mismo objetivo original. La identidad del juego suministrado está anclada por su manifiesto de repositorio, con la procedencia independiente de volcado prístino aún abierta.
La figura ilustra el cálculo del ángulo. Los controles de juego completo, el tiempo y el comportamiento del hardware PC-98 tienen comprobaciones de tiempo de ejecución separadas en el proyecto de reconstrucción.
La reconstrucción completa del TH04
El proyecto construye los cuatro productos DOS del juego a partir de C++ y ensamblado mantenidos. Más allá de la generación de viñetas, la fuente cubre etapas, jefes, renderizado, entrada, menús, finales y manejo de partituras.
- Fuente de generación de balasEl ayudante completo, otros tipos de patrones y ajuste de plantillas.
- Guía de compilación y ejecución de DOSCompile el código fuente y pruébelo en el flujo de trabajo del emulador PC-98 del proyecto.
- Estado actual del proyectoVerificación DOS y el puerto x64 nativo separado.