Appearance
输入系统概念 (Input System Concepts)
输入流程总览
pokeemerald-wasm 的输入系统将多种浏览器输入源统一转换为 GBA 的按键寄存器值。整个流程如下:
GBA 按键布局与寄存器
GBA 有 10 个物理按键,对应 REG_KEYINPUT 寄存器(地址 0x04000130)的低 10 位:
低电平有效 (Active-Low)
GBA 按键寄存器使用低电平有效逻辑:
| 状态 | 寄存器值 | 说明 |
|---|---|---|
| 无按键按下 | 0x03FF | 所有位为 1 |
| A 键按下 | 0x03FE | Bit 0 = 0 |
| A + B 同时按下 | 0x03FC | Bit 0, 1 = 0 |
| Start 按下 | 0x03F7 | Bit 3 = 0 |
游戏 C 代码检测按键的典型方式:
c
// 检测 A 键是否按下
if (!(REG_KEYINPUT & KEY_A)) {
// A 键被按下
}
// 检测 A 键是否刚被按下(结合上一帧状态)
if (!(REG_KEYINPUT & KEY_A) && (prevKeys & KEY_A)) {
// A 键刚被按下(上升沿)
}键盘映射
默认映射设计原则:
- Z/X 对应 A/B:经典 GBA 模拟器布局,Z 键在键盘底部对应 A(主要交互键),X 对应 B(取消/返回键)
- 方向键直接映射:
ArrowUp/Down/Left/Right对应 GBA 方向键 - Enter = Start:符合直觉——Enter 通常用于"开始/确认"
- A/S = L/R:左手的 A/S 键对应肩膀按键 L/R
触摸控制
移动设备没有物理键盘,pokeemerald-wasm 通过虚拟按键 (overlay buttons) 提供触摸输入:
触摸控制的特殊考虑:
- 多点触控:
touchstart/touchend事件可能同时有多个触点,需要逐个处理 - 触点追踪:通过
touch.identifier追踪每个触点,确保正确的按下/释放配对 - 防止页面滚动:触摸事件处理中调用
event.preventDefault()防止页面意外滚动 - 视觉反馈:虚拟按键被按下时应有视觉变化(高亮/缩放)
Gamepad API
Gamepad API 使用轮询模式(而非事件模式),因此在每帧的 requestAnimationFrame 回调中读取手柄状态。标准映射:
| Gamepad 按钮 | GBA 按键 |
|---|---|
| buttons[0] (A/Cross) | A |
| buttons[1] (B/Circle) | B |
| buttons[8] (Select) | Select |
| buttons[9] (Start) | Start |
| buttons[4] (L1) | L |
| buttons[5] (R1) | R |
| axes[0] < -0.5 | ← |
| axes[0] > 0.5 | → |
| axes[1] < -0.5 | ↑ |
| axes[1] > 0.5 | ↓ |
相关概念
- WebAssembly -- WebAssembly 内存模型,REG_KEYINPUT 位于线性内存中
- WASM 内存模型 -- 理解 I/O 寄存器在内存中的位置
- 存档系统 -- 另一个通过内存映射实现的硬件模拟
- 渲染管线 -- 输入如何影响游戏画面