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