Como um anel visa o jogador
O ataque de Elly solicita um anel apontado Com uma contagem inicial de 16. Um auxiliar calcula a direção de cada bala. O mesmo anel pode estar voltado para uma direção fixa ou virar em direção ao jogador.
Use REA para descobrir como TH04 cria um anel de balas e o aponta para o jogador. Explique o cálculo e mostre o código.
Um exemplo de prompt, com o executável original e o checkout de reconstrução disponíveis localmente.
TH04 armazena uma volta completa no sentido horário em 256 unidades do ângulo. Para 16 marcadores, cada índice adiciona 16 unidades: 0, 16, 32, …, 240. Adicionar a direção do jogador gira essas posições juntas.
O modelo de disparo na fonte recuperada
bullet_template.angle = 0;
bullet_template.group = BG_RING_AIMED;
bullet_template.count = 16;
bullet_template_tune();
Essas linhas selecionam o padrão antes da dificuldade e do ajuste de desempenho. Leia a fonte do ataque.
O que REA retorna
Nós inspecionamos bullet_velocity_and_angle_set(), a função que define a velocidade e o ângulo de cada bala. REA retorna suas instruções, pseudocódigo e referências. Três partes desse resultado explicam o padrão.
-
Verifique a imagem do DOS antes de ler seu código
Agente REAopen_binary {"path": "MAIN.EXE"} inspect_native_load_image {}REA extraterritorial * campos seleccionadosstatus: "verified" format: "dos-mz" load_segment: 4096 header_bytes: 6144 module_bytes: 150114A verificação vincula o código carregado e os registros de realocação ao executável fornecido. O caminho acima é encurtado para exibição.
-
Leia o anel multiplicar e dividir
Agente REA ·analyze_function{"procedure": "0x2cfc8"}REA7 agente * excerto de instruções0x2d0eb: MOV AX, SI 0x2d0ed: SHL AX, 0x8 0x2d0f0: MOV DL, byte ptr [0x53af] 0x2d0f9: IDIV BXSImantém o índice de marcadores. O deslocamento o multiplica por 256, então a divisão usa a contagem lida deDS:53AF. Os nomes de origem mantidos nesse campobullet_template.count. A sequência completa é apresentada abaixo. -
Encontre onde o padrão gira em direção ao jogador
Resultado da mesma função * trecho aim0x2d190: SUB AX, word ptr [0x53a6] 0x2d198: SUB AX, word ptr [0x53a4] 0x2d19d: CALLF 0x1000:1da8 0x2d1a2: ADD word ptr [BP + -0x2], AXC++mantido correspondentegroup_angle_offset += iatan2( player_pos.cur.y - bullet_template.origin.y, player_pos.cur.x - bullet_template.origin.x );Os operandos de instrução expõem duas diferenças de coordenadas e um auxiliar de direção. O seu valor de retorno é adicionado ao ângulo relativo do anel. Os nomes de origem tornam esses endereços legíveis; REA permite que o agente verifique as operações originais por trás deles.
Da montagem ao C++legível
Selecione uma etapa para corresponder às instruções originais com o cálculo do ângulo. Este resumo segue a trajectória do anel visado; a fonte completa também lida com spreads, stacks e padrões aleatórios.
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 * leia o índice do marcador. O argumento stack é carregado em SI. Num anel de 16 marcadores, este índice de membros vai de 0 a 15.
02 * Espaço as direções em torno de uma volta completa. SHL AX,8 multiplicado por 256. A contagem é zero-estendida em uma palavra, então IDIV divide o produto por essa contagem. Para a contagem 16, cada Índice avança 16 unidades angulares.
03 * adicione a direção do jogador. As duas subtrações formam coordenadas Jogador-menos-origem. O Auxiliar de direção retorna um ângulo em AX; adicionando-o vira todo o anel em direção ao jogador.
04 * adicionar a rotação do padrão. ADD AL,[0x53ad] adiciona o ângulo do modelo. O modelo inicial de Elly o define como zero; outros padrões podem usar o mesmo auxiliar com uma rotação.
05 * mantenha o ângulo final em um byte. A loja escreve AL para o campo spawn-angle. Valores wrap após 255, assim como o elenco unsigned-byte faz. A fonte circundante também converte este ângulo e velocidade em velocidade.
O conjunto selecciona a ramificação do anel de mira, o cálculo da mira e o armazenamento final. O C++ acima é um resumo legível. As verificações do compilador abaixo se aplicam à fonte mantida no projeto vinculado.
Leia o anel mantido e aim fonte
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);
Anel macro · Alvo e fonte de velocidade · Representação do ângulo
Verificação da fonte mantida
As verificações registadas do projecto TH04 compilam o código de geração de marcadores, incluindo este auxiliar, com a sua cadeia de ferramentas Turbo C++ 4.0 j fixada.
2.139 bytes correspondentes
O código compilado de geração de marcadores corresponde a uma seção de 2.139 bytes do executável original.
Duas construções limpas
Duas compilações separadas produzem os mesmos bytes correspondentes. Os hashes de entrada gravados correspondem à fonte mantida mostrada aqui.
Gravado em 3 de outubro de 2026. Leia as verificações do compilador.
Identidade-alvo e âmbito de análise
| Alvo Original | MAIN.EXE, 156.258 bytes, dos MZ |
|---|---|
| Entrada auxiliar | 0x2cfc8 na imagem carregada de REA |
| Deslocamento do ficheiro Original |
0x1e7c8, devolvido por address_to_file_offset
|
| Inspecção do Código registado | REA 4.1.0 * 7 de outubro de 2026 |
As verificações do compilador cobrem a seção completa do código de adição de marcadores, incluindo este auxiliar. Eles também comparam a contribuição do mapa e a deslocalização sobreposta.
REA verificou a imagem estática de Carga Dos no segmento de carga 0x1000. Os seus endereços descrevem essa imagem de análise. O resultado da função reporta 503 bytes de corpo em dois intervalos num intervalo de 517 bytes; as instruções seleccionadas acima situam-se nesses intervalos comunicados.
Os nomes de origem e as verificações do compilador vêm do ponto de verificação TH04 0d72e980. As observações de reconstrução anteriores utilizaram os próprios scripts de análise do projecto; esta página inclui uma nova inspecção REA do mesmo alvo original. A identidade do jogo fornecido é fixada por seu manifesto de repositório, com proveniência independente de despejo intocado ainda aberta.
A figura ilustra o cálculo do ângulo. Os controlos completos do jogo, a temporização e o comportamento do hardware PC-98 têm verificações de tempo de execução separadas no projecto de reconstrução.
A reconstrução completa do TH04
O projeto constrói os quatro produtos DOS do jogo a partir de C++ e assembly mantidos. Além da geração de marcadores, a fonte abrange estágios, chefes, renderização, entrada, menus, finais e manipulação de pontuação.
- Fonte de geração de marcadoresO auxiliar completo, outros tipos de padrões e ajuste de modelos.
- Guia de construção e execução do DOSConstrua a fonte e teste-a no fluxo de trabalho do emulador PC-98 do projeto.
- Estado actual do projectoVerificação DOS e a porta x64 nativa separada.