353. Sprite zero hit usa la máscara de viewport
Usar la opacidad de fondo consciente del viewport para la detección de solapamiento de sprite-zero-hit.
Lección 353 de 356 · tests/chapter_13_scrolling/test_353_sprite_zero_hit_uses_viewport_mask.py
Archivo a actualizar
emulator/rendering/sprite_zero_hit.pyReferencias
https://www.nesdev.org/wiki/PPU_rendering
https://www.nesdev.org/wiki/PPU_scrollingPor qué existe este paso
Sprite zero hit es una señal de estado de la PPU que se produce cuando un píxel opaco de la entrada de sprite 0 de OAM se solapa con un píxel de fondo opaco. Los juegos pueden sondear esta señal para temporizar un cambio de registro a mitad de fotograma, como separar un área de estado fija del juego con desplazamiento.
El helper de solapamiento indexa la opacidad de fondo usando coordenadas de pantalla
mask_index = screen_y * 256 + screen_xPor tanto, esa máscara debe describir el fondo realmente visible en esas mismas coordenadas. Tras el desplazamiento temporizado, la X de pantalla puede corresponder a una columna coarse-X distinta o a una nametable lógica distinta en cada fila. La antigua máscara fija en $2000 puede inspeccionar un píxel de fondo distinto aunque el sprite 0 permanezca en la misma posición de pantalla.
Ejemplo
sprite 0 screen X: 100
scanline viewport X: 40
visible background X: 140
fixed mask inspects X: 100
viewport mask inspects X: 140Si la X de origen 140 es opaca y la X de origen 100 es transparente, la máscara fija pasa por alto el solapamiento. El adaptador consciente del viewport selecciona la composición temporizada para un fotograma completo y conserva la reserva de instantánea ya probada cuando los datos temporizados no están disponibles.
¿Por qué usar un alias de importación? Las pruebas históricas de sprite-zero-hit hacen monkeypatch del nombre local del módulo ppu_background_to_opaque_mask. Cambiar cada llamada a un nuevo nombre local rompería ese punto de prueba estable. Importar el adaptador consciente del viewport bajo el nombre histórico cambia el comportamiento de producción manteniendo las pruebas antiguas sin cambios:
new viewport-aware function as old module-local nameInvariantes importantes
- sprite-zero-hit consume el adaptador de opacidad consciente del viewport
- el nombre histórico de la dependencia local sigue siendo monkeypatchable
- la máscara seleccionada se pasa sin cambios al helper de solapamiento puro
- la selección de la tabla de patrones CHR del sprite permanece independiente del enmascarado de fondo
- el código de renderizado no establece PPUSTATUS directamente
- Console y la temporización de la PPU siguen programando y estableciendo el hit
Concepto erróneo habitual
Sprite zero hit no es detección de colisiones de juego y no significa que Mario haya golpeado a un enemigo o un bloque. Es un solapamiento de renderizado que involucra únicamente la entrada de sprite 0 y un píxel de patrón de fondo opaco, usado habitualmente por el software como señal de temporización.
Estrategia de pruebas
Una prueba comprueba la identidad de la dependencia de producción para que el antiguo productor fijo no pueda volver silenciosamente. Otra sigue un fotograma temporizado completo a través del adaptador de viewport real reemplazando solo su costoso compositor de filas, y luego verifica que la máscara resultante llega sin cambios al límite existente del helper de solapamiento puro.
Fuera de alcance
- cambiar la búsqueda de solapamiento pura
- cambiar la selección de la tabla de patrones del sprite
- cambiar la programación de fotogramas de Console
- comportamiento exacto de hardware del borde izquierdo, X=255 y OAM Y+1
- desplazamiento vertical completo de la fila de origen
Implementación de ejemplo completa
# emulator/rendering/sprite_zero_hit.py
# --- UPDATED BLOCK: VIEWPORT MASK WITH HISTORICAL LOCAL NAME ---
from emulator.rendering.ppu_background_renderer import (
PATTERN_TABLE_0_ADDR,
PATTERN_TABLE_1_ADDR,
ppu_background_viewport_to_opaque_mask as ppu_background_to_opaque_mask,
)
...Ejecutar esta lección
uv run pytest tests/chapter_13_scrolling/test_353_sprite_zero_hit_uses_viewport_mask.py -v