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;
}
}
總結
以上是生活随笔為你收集整理的java按键机nes模拟器_NES 模拟器开发教程 12 - 输入设备的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 项管行知05--可交付成果
- 下一篇: 百度人工智能变身作曲家 应用前景相当广泛