290. 手柄定义
定义纯粹的 NES Controller 状态对象。
第 290 / 356 · tests/chapter_07_controller_input/test_290_controller_definition.py
本步骤要创建的文件
emulator/input/controller.py为什么需要这一步
在把手柄输入接入 CpuBus 地址 $4016 之前,我们需要为标准 NES 手柄建立一个纯数据模型。这样可以让手柄机制易于测试,而不需要涉及 pygame、CpuBus、ROM 执行或帧时序。
什么是标准 NES 手柄?
标准手柄有八个按钮
参考资料
https://www.nesdev.org/wiki/Standard_controller
https://www.nesdev.org/wiki/Controller_reading_code
A, B, Select, Start, Up, Down, Left, Right硬件串行读取顺序是
first read -> A
second read -> B
third read -> Select
fourth read -> Start
fifth read -> Up
sixth read -> Down
seventh read -> Left
eighth read -> Right重要区别
一些 NES 汇编例程会把这些读取值移位存入 RAM,使 A 键最终位于某个游戏自有字节的第 7 位。这并不意味着硬件是先发送 Right 的。模拟器应该按照硬件的串行顺序来建模。
建议的实现示例
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范围之外
- CpuBus $4016 路由
- pygame 键盘映射
- 手柄端口 2
- Famicom 扩展手柄
- DMC/手柄读取故障行为
运行本课
uv run pytest tests/chapter_07_controller_input/test_290_controller_definition.py -v