334. Ppu background viewport to framebuffer
Compose the horizontal background framebuffer from current PPU scroll state.
Lesson 334 of 356 · tests/chapter_13_scrolling/test_334_ppu_background_viewport_to_framebuffer.py
File to update
emulator/rendering/ppu_background_renderer.pyReferences
https://www.nesdev.org/wiki/PPU_scrolling
https://www.nesdev.org/wiki/PPU_nametablesWhy this step exists
Previous steps can render one selected logical nametable and can compose two existing framebuffers. This adapter connects those mechanisms to current PPU scroll state.
Horizontal flow
temp_vram_addr + fine_x
|
v
decode viewport X
|
v
select horizontal logical pair
|
v
render left and right nametables
|
v
compose one 256x240 framebufferLogical pair selection
nametable Y = 0 -> left $2000, right $2400
nametable Y = 1 -> left $2800, right $2C00Nametable X remains part of decoded viewport X. For example, nametable X=1, coarse X=5, and fine X=3 produce viewport X 299.
Compatibility
The existing ppu_background_to_framebuffer() function continues rendering one selected nametable. This new adapter calls it twice and then composes the results.
Out of scope
- opacity-mask composition
- Console integration
- sprite-zero-hit integration
- vertical pixel scrolling
- pygame
Complete example implementation
# emulator/rendering/ppu_background_renderer.py
# --- NEW LINES: HORIZONTAL VIEWPORT OPERATIONS ---
from emulator.rendering.background_viewport import (
compose_horizontal_framebuffer_viewport,
compose_horizontal_opaque_mask_viewport,
decode_background_viewport_position,
)
...
# --- NEW BLOCK: COMPOSE THE HORIZONTAL FRAMEBUFFER VIEWPORT ---
def ppu_background_viewport_to_framebuffer(ppu: PPU) -> Framebuffer:
viewport_x, _ = decode_background_viewport_position(
temp_vram_addr=ppu.temp_vram_addr,
fine_x=ppu.fine_x,
)
nametable_y = (ppu.temp_vram_addr >> 11) & 1
left_base = BASE_NAMETABLE_ADDR + nametable_y * 0x0800
right_base = left_base + 0x0400
left = ppu_background_to_framebuffer(
ppu,
base_nametable_addr=left_base,
)
right = ppu_background_to_framebuffer(
ppu,
base_nametable_addr=right_base,
)
return compose_horizontal_framebuffer_viewport(
left=left,
right=right,
viewport_x=viewport_x,
)Run this lesson
uv run pytest tests/chapter_13_scrolling/test_334_ppu_background_viewport_to_framebuffer.py -v