319. 在预渲染阶段清除精灵零命中标志

在简化后的预渲染边界处清除精灵 0 命中标志。

319 / 356 · tests/chapter_11_sprite_zero_hit/test_319_clear_sprite_zero_hit_pre_render.py

需要更新的文件

emulator/ppu/ppu.py

为什么需要这一步

精灵 0 命中是 PPUSTATUS 的第 6 位。游戏可以通过等待该标志经历如下生命周期,将其用作时序信号:

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

在实现重叠检测或设置该标志之前,这一步先确立清除/重置的不变量。如果没有这个重置操作,未来的精灵 0 命中可能会永久保持置位状态,从而破坏那些在等待下一次命中之前,需要先等待该标志清除的游戏。

当前的时序模型

该项目目前是在扫描线切换时推进时序的。因此这一步会在扫描线 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 会清除 VBlank 第 7 位,但不得清除精灵 0 命中第 6 位。在当前模型中,只有预渲染的生命周期事件才会清除精灵 0 命中标志。

当前的手动 ROM 策略

当前手动检查继续使用 MarioBros.nes。对《超级马里奥兄弟》的验证要延后到实现重叠检测和定时命中设置之后再进行。

本步骤范围之外

  • 检测精灵 0/背景重叠
  • 设置精灵 0 命中
  • 固定/伪造的扫描线命中
  • 精灵溢出
  • Console 相关更改
  • 渲染相关更改
  • 《超级马里奥兄弟》验证

运行本课

uv run pytest tests/chapter_11_sprite_zero_hit/test_319_clear_sprite_zero_hit_pre_render.py -v