285. Ручные помощники отображения framebuffer
Добавить ручные помощники отображения framebuffer с использованием отрисовки pygame Surface.
Урок 285 из 356 · tests/chapter_05_rendering_pipeline/test_285_manual_framebuffer_display_helpers.py
Файл для создания
tools/show_framebuffer.pyЗачем нужен этот шаг
Ядро эмулятора теперь создаёт чистые данные Framebuffer. Прежде чем строить полноценный фронтенд, нужен небольшой ручной инструмент, способный отрисовать Framebuffer с помощью pygame для визуальных проверок работоспособности.
Важная граница
Этот файл находится в tools/, поскольку pygame — это забота фронтенда/ручного отображения.
Основные модули эмулятора не должны импортировать pygame
emulator/rendering/framebuffer.py
emulator/rendering/nametable_renderer.py
emulator/rendering/ppu_background_renderer.py
emulator/console.pyЧто такое pygame Surface? Surface — это отрисовываемый буфер пикселей, управляемый pygame. Окно, созданное функцией pygame.display.set_mode(...), тоже является Surface.
Минимальный пример
surface.fill((255, 0, 0), pygame.Rect(0, 0, 10, 10))Это закрашивает прямоугольник 10x10 красным цветом.
Как работает draw_framebuffer:
Framebuffer pixel (x, y)
-> RGB color
-> pygame Rect(x * scale, y * scale, scale, scale)
-> surface.fill(color, rect)Пример предлагаемой реализации
import pygame
from emulator.rendering.framebuffer import Framebuffer
def make_checkerboard_framebuffer(width: int = 64, height: int = 64) -> Framebuffer:
framebuffer = Framebuffer(width=width, height=height)
for y in range(height):
for x in range(width):
block_x = x // 8
block_y = y // 8
if (block_x + block_y) % 2 == 0:
framebuffer.set_pixel(x, y, (255, 255, 255))
else:
framebuffer.set_pixel(x, y, (40, 40, 40))
return framebuffer
def draw_framebuffer(
surface: pygame.Surface,
framebuffer: Framebuffer,
scale: int,
) -> None:
for y in range(framebuffer.height):
for x in range(framebuffer.width):
color = framebuffer.get_pixel(x, y)
rect = pygame.Rect(
x * scale,
y * scale,
scale,
scale,
)
surface.fill(color, rect)Политика тестирования
Этот тест не открывает настоящее окно pygame. Он использует внеэкранный pygame Surface для проверки помощника отрисовки. Шаг с окном/главным циклом рассматривается отдельно.
Вне рамок этого шага
- главный цикл pygame
- pygame.display.set_mode
- обработка событий
- отображение вывода ROM
- ввод с контроллера
- спрайты
Запустить этот урок
uv run pytest tests/chapter_05_rendering_pipeline/test_285_manual_framebuffer_display_helpers.py -v