338. Инкремент горизонтальной составляющей vram addr
Инкрементировать горизонтальную составляющую текущего адреса отрисовки v.
Урок 338 из 356 · tests/chapter_13_scrolling/test_338_increment_horizontal_vram_addr.py
Файл для обновления
emulator/ppu/ppu.pyСправочные материалы
https://www.nesdev.org/wiki/PPU_scrolling#Coarse_X_increment
https://www.nesdev.org/wiki/PPU_scrolling#During_renderingЗачем нужен этот шаг
Во время выборки фона PPU продвигается за раз на один столбец тайлов шириной 8 пикселей. Текущий адрес отрисовки v хранит как столбец тайлов coarse X, так и выбор горизонтальной таблицы имён:
v: yyy NN YYYYY XXXXX
|
+-- coarse X, bits 0-4
horizontal nametable selection: bit 10Нормальное поведение
coarse X 0 -> 1
coarse X 30 -> 31Поведение на границе
coarse X 31, horizontal nametable 0
-> coarse X 0, horizontal nametable 1
coarse X 31, horizontal nametable 1
-> coarse X 0, horizontal nametable 0Переключение на границе переводит отрисовку через стык между логическими таблицами имён слева и справа. Позже, при чтении этих логических адресов, PpuBus применяет зеркалирование картриджа.
Важные инварианты
- меняться могут только coarse X и, при переполнении, горизонтальная таблица имён
- coarse Y, fine Y и вертикальная таблица имён остаются неизменными
- fine X — отдельная величина и не является аргументом этой операции
- вспомогательная функция возвращает значение и не мутирует PPU
Распространённое заблуждение
Это не сдвиг на один пиксель. Это продвижение на один столбец тайлов, что соответствует 8 пикселям. Fine X задаёт отдельное смещение 0-7 пикселей внутри первого тайла.
Вне объёма работ
- вызов вспомогательной функции из PPU.step()
- выбор точек выборки фона
- копирование горизонтальных битов t в v
- вертикальные инкременты
- отрисовка фреймбуфера
Полный пример реализации
# emulator/ppu/ppu.py
# --- NEW BLOCK: PURE HORIZONTAL v INCREMENT ---
def increment_horizontal_vram_addr(vram_addr: int) -> int:
# Advance v by one background tile column.
coarse_x = vram_addr & 0b1_1111
if coarse_x == 31:
vram_addr &= ~0b1_1111
vram_addr ^= 0b100_0000_0000
return vram_addr
return vram_addr + 1Запустить этот урок
uv run pytest tests/chapter_13_scrolling/test_338_increment_horizontal_vram_addr.py -v