259. PPU 时序计数器
实现基本的 PPU 时序计数器。
第 259 / 356 · tests/chapter_04_ppu_timing_and_vblank/test_259_ppu_timing_counters.py
参考资料
https://www.nesdev.org/wiki/PPU_rendering#Line-by-line_timing需要更新的文件
emulator/ppu/ppu.py需要添加的常量
PPU_CYCLES_PER_SCANLINE = 341
PPU_SCANLINES_PER_FRAME = 262需要添加的状态
cycle: int = 0
scanline: int = 0
frame: int = 0需要添加的方法
PPU.step(cycles: int = 1) -> None为什么需要这一步
PPU 是一个基于时间的设备。之后,VBlank、NMI、渲染以及帧节奏都要依赖于知道 PPU 当前处于这一帧内的什么位置。
在这一步,只需要添加计数器
cycle -> position inside the current scanline
scanline -> current scanline inside the frame
frame -> completed frame count初始的时序模型
341 PPU cycles per scanline
262 scanlines per frame建议的实现示例
def step(self, cycles: int = 1) -> None:
for _ in range(cycles):
self.cycle += 1
if self.cycle >= PPU_CYCLES_PER_SCANLINE:
self.cycle = 0
self.scanline += 1
if self.scanline >= PPU_SCANLINES_PER_FRAME:
self.scanline = 0
self.frame += 1未来的兼容性
这些测试有意只检查计数器的行为,暂时不要求精确的 VBlank/NMI 副作用。之后的步骤可能会在 PPU.step() 内部添加这些副作用,但这些计数器的不变式应该始终成立。
不在本步骤范围内
- VBlank 的产生
- NMI 请求
- 渲染
- 0 号精灵命中(sprite 0 hit)
- 精灵溢出
- 奇数帧的周期跳过
运行本课
uv run pytest tests/chapter_04_ppu_timing_and_vblank/test_259_ppu_timing_counters.py -v