1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > java按键机nes模拟器_NES 模拟器开发教程 12 - 输入设备

java按键机nes模拟器_NES 模拟器开发教程 12 - 输入设备

时间:2018-09-01 14:55:01

相关推荐

java按键机nes模拟器_NES 模拟器开发教程 12 - 输入设备

NES 支持许多设备,最常见的还是官方手柄,它有 8 个按键:

A

B

SELECT

START

UP

DOWN

LEFT

RIGHT

读取的时候比较奇怪,按道理来讲 8 个按键刚好可以用 1 个 byte 表示,读一次就可以了,但是 NES 读取的时候却是串行的,读 8 次,每次读一个按键,这样做应该是为了兼容性第三方控制器

1. 寄存器

手柄的寄存器位于 CPU 总线的 0x4016 和 0x4017,分别对应 1P 和 2P

7 bit 0

---- ----

xxxx xxxS

|

+- Controller shift register strobe

寄存器只有 bit 0 有效,做为选通标志。当写入选通为 1 时,则可以通过读取寄存器,每次返回一个按键状态,下一次读取返回下一个按钮状态。当写入 0 时,offset 被置位,再次选通读取时会重新从第一个按钮读取

需要注意的是,只能往 4016 写(写 4017 给 APU 用了),读可以往 4016 和 4017 读。写 4016 时,对两个手柄都有效,读时则 4016 为 P1,4017 为 P2

2. 按钮映射

按钮对应的比特位为:

bit

7

6

5

4

3

2

1

0

button

A

B

Select

Start

Up

Down

Left

Right

3. 实现

手柄实现非常简单,只需要读写和更新按钮状态的函数

export enum StandardControllerButton {

A = 0x80,

B = 0x40,

SELECT = 0x20,

START = 0x10,

UP = 0x08,

DOWN = 0x04,

LEFT = 0x02,

RIGHT = 0x01,

}

export class StandardController implements IStandardController {

private data: number;

private isStrobe = false;

private offset = 0;

public updateButton(button: StandardControllerButton, isPressDown: boolean) {

if (isPressDown) {

this.data |= button;

} else {

this.data &= ~button & 0xFF;

}

}

public write(data: uint8) {

if (data & 0x01) {

this.isStrobe = true;

} else {

this.offset = 0;

this.isStrobe = false;

}

}

public read(): uint8 {

const data = this.isStrobe ? this.data & StandardControllerButton.A : this.data & (0x80 >> this.offset++);

return data ? 1 : 0;

}

}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。