290. Definición del mando

Definir el objeto de estado puro del Controller del NES.

Lección 290 de 356 · tests/chapter_07_controller_input/test_290_controller_definition.py

Archivos a crear en este paso

emulator/input/controller.py

Por qué existe este paso

Antes de conectar la entrada del mando a la dirección $4016 de CpuBus, necesitamos un modelo de datos puro para el mando estándar del NES. Esto mantiene el mecanismo del mando fácil de probar sin involucrar a pygame, CpuBus, la ejecución de la ROM ni la temporización de fotogramas.

¿Qué es un mando estándar del NES?

El mando estándar tiene ocho botones

Referencias

https://www.nesdev.org/wiki/Standard_controller
https://www.nesdev.org/wiki/Controller_reading_code

A, B, Select, Start, Up, Down, Left, Right

El orden de lectura serial del hardware es

first read  -> A
second read -> B
third read  -> Select
fourth read -> Start
fifth read  -> Up
sixth read  -> Down
seventh read -> Left
eighth read -> Right

Distinción importante

Algunas rutinas en ensamblador del NES desplazan estas lecturas a la RAM de modo que A termina en el bit 7 de un byte propio del juego. Eso no significa que el hardware envíe Right primero. El emulador debería modelar el orden serial del hardware.

Ejemplo de implementación sugerida

from dataclasses import dataclass


BUTTON_A = 1 << 0
BUTTON_B = 1 << 1
BUTTON_SELECT = 1 << 2
BUTTON_START = 1 << 3
BUTTON_UP = 1 << 4
BUTTON_DOWN = 1 << 5
BUTTON_LEFT = 1 << 6
BUTTON_RIGHT = 1 << 7


@dataclass
class Controller:
    a: bool = False
    b: bool = False
    select: bool = False
    start: bool = False
    up: bool = False
    down: bool = False
    left: bool = False
    right: bool = False

    strobe: bool = False
    captured_buttons: int = 0
    read_index: int = 0

Fuera de alcance

  • enrutamiento de $4016 en CpuBus
  • asignación de teclado de pygame
  • puerto de mando 2
  • mandos de expansión de Famicom
  • comportamiento de fallo (glitch) de lectura de DMC/mando

Ejecutar esta lección

uv run pytest tests/chapter_07_controller_input/test_290_controller_definition.py -v