336. Console 使用背景视口
将水平帧缓冲区和不透明度掩码视口集成到 Console 中。
第 336 / 356 · tests/chapter_13_scrolling/test_336_console_uses_background_viewport.py
待更新文件
emulator/console.py此步骤存在的原因
步骤 334 和 335 根据当前 PPU 滚动状态生成具备视口感知能力的背景数据。此步骤将这些新函数组装到 Console 内部,使整帧渲染路径同时使用已滚动的帧缓冲区及其匹配的不透明度掩码。
发生的变化
Console.render_background_framebuffer()
-> keeps the older fixed-background behavior
Console.render_framebuffer()
-> uses ppu_background_viewport_to_framebuffer(self.ppu)
-> uses the new viewport opacity mask through a compatibility alias
-> passes both new results to the existing sprite compositor为什么要给掩码起一个别名?早期课程已经在 Console 内部使用了 ppu_background_to_opaque_mask 这个名字。以该名字导入新的视口掩码函数,可以让整帧渲染路径使用新行为,同时不破坏与那些早期课程的兼容性。
《超级马里奥兄弟》的临时限制:如果它现在还没有按预期滚动,不必担心。此步骤在整帧中只使用一个滚动位置。《超级马里奥兄弟》在同一帧中,固定的状态栏使用一个位置,而移动的游戏区域使用另一个位置。因此,在这个测试通过之后,游戏仍然可能显示静止的背景、移动的状态栏,或其他不正确的滚动效果。这是预期之中的。后续步骤将记录滚动的变化,并把状态栏和游戏区域渲染为独立的水平条带。
范围之外
- 更改 sprite-zero-hit 调度
- 追踪 $2005 写入
- 分屏条带渲染
- 垂直像素滚动
- pygame
完整示例实现
# emulator/console.py
from emulator.rendering.ppu_background_renderer import (
ppu_background_to_framebuffer,
# --- NEW LINE: FULL-FRAME RENDERING USES THE VIEWPORT ADAPTER ---
ppu_background_viewport_to_framebuffer,
# --- UPDATED LINE: USE THE NEW MASK WITH THE EXISTING CONSOLE NAME ---
ppu_background_viewport_to_opaque_mask as ppu_background_to_opaque_mask,
PATTERN_TABLE_0_ADDR,
PATTERN_TABLE_1_ADDR,
)
...
def render_background_framebuffer(self) -> Framebuffer:
# Keep the older background-only behavior for compatibility.
return ppu_background_to_framebuffer(self.ppu)
def render_framebuffer(self) -> Framebuffer:
# --- UPDATED LINE: FULL-FRAME OUTPUT USES THE VIEWPORT FRAMEBUFFER ---
background = ppu_background_viewport_to_framebuffer(self.ppu)
# The existing name now refers to the new viewport-mask function.
background_opaque_mask = ppu_background_to_opaque_mask(self.ppu)
...
# Everything remains the same below this point.运行本课
uv run pytest tests/chapter_13_scrolling/test_336_console_uses_background_viewport.py -v