297. Main keyboard event controller update

Use pygame key events to update controller_1 in main_only_background.py.

Lesson 297 of 356 · tests/chapter_08_manual_main/test_297_main_keyboard_event_controller_update.py

File to update

main_only_background.py

Why this step exists

The emulator core already exposes controller port 1 through CpuBus $4016. main_only_background.py should translate pygame keyboard events into updates on the pure Controller object:

pygame KEYDOWN Z -> cpu_bus.controller_1.a = True
pygame KEYUP Z   -> cpu_bus.controller_1.a = False

Suggested implementation example

from emulator.input.controller import Controller
...

def handle_key_event(controller: Controller, key: int, pressed: bool) -> None:
    if key == KEYS["a"]:
        controller.a = pressed
    elif key == KEYS["b"]:
        controller.b = pressed
    elif key == KEYS["select"]:
        controller.select = pressed
    elif key == KEYS["start"]:
        controller.start = pressed
    elif key == KEYS["up"]:
        controller.up = pressed
    elif key == KEYS["down"]:
        controller.down = pressed
    elif key == KEYS["left"]:
        controller.left = pressed
    elif key == KEYS["right"]:
        controller.right = pressed

...
# Inside pygame event loop:

for event in pygame.event.get():
    if event.type == pygame.QUIT:
        running = False
    elif event.type == pygame.KEYDOWN:
        handle_key_event(cpu_bus.controller_1, event.key, True)
    elif event.type == pygame.KEYUP:
        handle_key_event(cpu_bus.controller_1, event.key, False)

Important boundary

main_only_background.py can import pygame and handle keyboard events because it is a manual visual runner. emulator/input/controller.py should remain pygame-free.

Out of scope

  • pygame joystick/gamepad support
  • configurable key bindings
  • controller port 2
  • calling main() from pytest

Run this lesson

uv run pytest tests/chapter_08_manual_main/test_297_main_keyboard_event_controller_update.py -v