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 - 输入设备相关推荐

  1. MM32F3273G8P火龙果开发板MindSDK开发教程12 -获取msa311加速器的敲击事件

    MM32F3273G8P火龙果开发板MindSDK开发教程12 -获取msa311加速器的敲击事件 1.功能描述 msa311可以识别单击.双击事件,类似手机上的点击返回,双击截屏功能. 单击,双击都 ...

  2. PalmOS开发教程-12

    第十二章 专业编程技巧      随着程序变得越来越大,我们会发现很多问题.这些问题或许在编制几千行代码时不会出现,但是当编到上万行或更多时并且程序由不同的程序员来编写,在运行时问题就出现了. 这就要 ...

  3. python博客开发教程_Django 博客开发教程 12 - 评论

    创建评论应用 相对来说,评论其实是另外一个比较独立的功能.Django 提倡,如果功能相对比较独立的话,最好是创建一个应用,把相应的功能代码写到这个应用里.我们的第一个应用叫 blog,它里面放了展示 ...

  4. 【开发教程12】AI语音人脸识别(会议记录仪/人脸打卡机)-语音采集

    CC3200AI实验教程 --疯壳·开发板系列 语音采集 音频采集板卡主要运用的是TI官方的方案TLV320AIC3254音频编解码器+TPA2012D2RTJ功率放大器,如图1.0.1为语音采集主板 ...

  5. DuiVision开发教程(12)-任务类和任务队列

    基于MFC的界面程序中,如果存在多线程,一般情况下只有主线程(界面线程)可以调用Windows窗口相关的函数,否则如果在其他线程中调用了界面函数,很可能会造成异常.为此DuiVision界面库提供了一 ...

  6. Android开发教程JAVA基础(汇总)

    Android游戏开发视频教程(汇总) Android开发教程JAVA基础之Java 概述 Android开发教程JAVA基础之标示符.关键字1 Android开发教程JAVA基础之标示符.关键字2 ...

  7. autojs零基础入门视频教程,跟我学Auto.js Pro安卓免ROOT引流脚本开发教程,飞云脚本学院2019最新录制

    课程大纲(更新中-) 基础课程 [已完成]01安装Visual Studio Code(时长9分33秒)在线观看 [已完成]02安装Auto.js Pro(时长5分48秒)在线观看 [已完成]03解读 ...

  8. (二)01- DCloud平台 HTML5+ App开发——真机调试运行 夜神模拟器运行HBuilderX中的html文件 夜神模拟器运行App的基础功能示例-手机设备-分享功能-拍照功能

    DCloud 平台 HTML5 + App 开发 下载安装 HBuilderX 下载地址:https://www.dcloud.io/hbuilderx.html HBuilderX-使用步骤: 第一 ...

  9. android 区分 真机模拟器_Android模拟器和真机总结的九点区别 Android程序如何在手机上运行...

    Android是一个包括操作系统.中间件.用户界面和关键应用软件的移动设备软件堆.换言之,Android是基于Java并运行在Linux内核上的轻量级操作系统,其功能全面,包括一系列Google公司在 ...

  10. iOS 9应用开发教程之创建iOS 9项目与模拟器介绍

    iOS 9应用开发教程之创建iOS 9项目与模拟器介绍 编写第一个iOS 9应用 本节将以一个iOS 9应用程序为例,为开发者讲解如何使用Xcode 7.0去创建项目,以及iOS模拟器的一些功能.编辑 ...

最新文章

  1. 完美/兼容版添加事件以及删除事件
  2. SpringCloud-Eureka-ProviderConsumer
  3. spring 集成hibernate
  4. 今晚直播:WLS/WAS故障基本分析介绍
  5. springboot (spring mvc)集成swagger
  6. tensorflow之XORerr1例题
  7. linux编译器下载地址,GNU Compiler Collection(gcc编译器) v4.9.1 linux版
  8. ugui 九宫格和图片切割
  9. 百度人脸识别,一次耗时600毫秒
  10. 惠普局域网共享打印机设置_网络共享惠普打印机的操作方法
  11. Failed to lookup view “error“ in views directory 解决方案
  12. 纯CSS实现四种方式文本反差色效果
  13. 薄荷 (2009-06-07)
  14. java 图片 大小_在JAVA中调整图片大小
  15. 【SQL server】基础入门0——理论部分
  16. 如何将微信服务号改成订阅号?
  17. 高端运动耳机哪个品牌最好、最好的运动耳机品牌排行
  18. CPU,处理器插槽,逻辑处理器,处理器内核
  19. OpenGL(5)Texture - 两张图片
  20. 第一单元----(4)认识编译器 源代码和可执行程序的关系

热门文章

  1. echarts图表格式记录
  2. 【玩转微信公众平台之中的一个】序章(纯粹扯淡)
  3. 计算机竞赛奖学金申请书,计算机专业奖学金申请书
  4. Promethues (普罗米修斯)详细介绍
  5. 50个查询系列-第七个查询:查询学过“叶平”老师所教的所有课的同学的学号、姓名...
  6. 用python贴吧自动回帖_python基于selenium实现贴吧自动发帖
  7. Java实现CCF/CSP 201312-2 ISBN编号(零分!!!
  8. SystemUI自定义电池图标
  9. 百度竞价需抓住消费者心理
  10. Mybatis中Mapper标签总结大全