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