319. Сброс sprite 0 hit перед предрендером
Сбрасываем sprite 0 hit на упрощённой границе предрендера.
Урок 319 из 356 · tests/chapter_11_sprite_zero_hit/test_319_clear_sprite_zero_hit_pre_render.py
Файл для обновления
emulator/ppu/ppu.pyЗачем нужен этот шаг
Sprite 0 hit — это бит 6 PPUSTATUS. Игры могут использовать его как сигнал тайминга, ожидая перехода флага через следующий жизненный цикл:
visible frame overlap -> sprite 0 hit becomes set
pre-render boundary -> sprite 0 hit becomes clear
next visible frame -> sprite 0 hit may become set againПрежде чем реализовывать обнаружение пересечения или установку флага, этот шаг устанавливает инвариант сброса/очистки. Без этого сброса будущий sprite 0 hit может остаться установленным навсегда и сломать игры, которые ждут очистки флага перед ожиданием следующего попадания.
Текущая модель тайминга
Проект в настоящее время продвигает тайминг на переходах между сканлиниями. Поэтому этот шаг очищает флаг при начале сканлинии 261. Точный тайминг по точкам на реальном оборудовании — это будущее уточнение точности.
Пример фрагмента реализации
if self.scanline == PPU_PRE_RENDER_SCANLINE:
self.status &= ~VBLANK_STARTED
# --- NEW BLOCK: CLEAR SPRITE 0 HIT FOR THE NEXT FRAME ---
self.status &= ~SPRITE_ZERO_HIT
# --- END NEW BLOCK ---Важный инвариант
Чтение PPUSTATUS очищает бит 7 VBlank, но не должно очищать бит 6 sprite 0 hit. В текущей модели sprite 0 hit очищается только событием жизненного цикла предрендера.
Текущая политика ручного ROM
Продолжайте использовать MarioBros.nes для текущих ручных проверок. Проверка на Super Mario Bros. откладывается до реализации обнаружения пересечения и установки попадания по времени.
Вне рамок
- обнаружение пересечения sprite 0/фона
- установка sprite 0 hit
- фиксированные/поддельные попадания по сканлинии
- переполнение спрайтов
- изменения в Console
- изменения рендеринга
- проверка на Super Mario Bros.
Запустить этот урок
uv run pytest tests/chapter_11_sprite_zero_hit/test_319_clear_sprite_zero_hit_pre_render.py -v