光枪原理、光枪在模拟器中的应用

光枪其实是个接收机,其枪口处有个光电检测管(PD,photodiode),外加聚焦透镜,用来接收来自屏幕上某点处的光线。当光枪的扳机被按下时,光电检测管将检测接收到的光强,当光强超过一定阈值时,其输出1至游戏机,否则输出0。有两种方法可用来判断扳机触发时是否命中屏幕上的目标:

A. 逻辑判断:即闪烁屏幕。在扣下扳机的一瞬间,先涂黑整个屏幕,同时将所有目标绘制成白色,然后打开PD,此时,如果PD输出1,则目标命中。这种方法的优点在于足够简单,而缺陷在于:如果屏幕有多个目标,无法区分命中的究竟是哪一个目标(对光枪里面的PD别心存太多期望,它只是个廉价设备,无法用来判别颜色的)

B. 精确定时:即光栅计数器+微秒级定时器+闪烁屏幕。时序及说明如下:

  1. 扣下扳机的同时,开始涂黑整个屏幕
  2. 检测到第1个VBlank,此时屏幕已经全黑了
  3. 紧接着画下一帧,开始涂白整个屏幕,光枪PD打开,开始检测光输入
  4. PD输出一直为0,此间对HBlank个数进行计数,且每当发生了一个HBlank时,ms级定时器重新计时
  5. PD终于检测到了第一次光输入,且得到了此时的HBlank计数n和计时值t
  6. 接收到第2个VBlank,此时屏幕全白,光枪PD关闭
  7. 根据得到的n和计时值t,便可以知道扣动扳机时光枪所指向的究竟是屏幕上的哪个像素了:前者即为屏幕y坐标,而后者除以HBlank时间间隔再乘上光栅像素宽度即为屏幕x坐标,然后判断一下是否为目标,over
  8. 上述方法有两个前提:首先,需要2帧来完成判断,你的手抖动频率最好表超过30hz,否则瞄不准...其二,需要HBlank和VBlank计数,所以用CRT最简单,如果是投影和LCD的话,恐怕就得换换思路

一点思考:

  1. 现在总算知道为什么有些模拟器(尤其是Console,比方说变态的bsnes)需要达到光栅级以上的模拟精度了吧?
  2. hmmm...就模拟器而言,如果想用真实的光枪,不管是那种显示设备,方法1都完全适用。而对于方法2,只要达到了光栅级渲染精度,HBlank/VBlank的获得便不是问题;稍微麻烦点的在于方法2中第5步,单从硬件原理考虑,如果用户使用的是CRT,那么还好办,主要是一些数值校正方面的工作(也就是说,CRT+光栅级精度的模拟器,完全有可能直接使用真实光枪来玩,哈哈)
  3. 对于方法2,如果用的是LCD的话,想要用真实光枪,最简单的方法莫过于直接使用像素级渲染精度的模拟器(逐像素绘制,每画一个像素模拟定时同步一次),遗憾的是,现有的模拟器没哪个能达到这种精度(bsnes应该是这方面最为接近的尝试)...这样模拟效率实在太低,因此此路不通。其实可以变通一下,仍使用光栅级模拟精度,一次计算一根扫描线,然后将其像素从左至右地“逐点”绘制出来,以供光枪检测,即,模拟仍然是精确到光栅的,但绘制定时却是精确到像素的,如果定时把握得好,用LCD也能实现与CRT+光枪同样的效果,哈哈~但不知道时间同步粒度太小,对rom逻辑本身是否有影响
  4. 这里需要澄清一下:常见街机光枪游戏其实分2类(这里不讨论IR Camera定位),一类是枪下面有底座的,如野狼突击队,根据其底座机械运动本身便能将枪口所指向的位置坐标实时计算出来,因此这类光枪游戏根本无需使用上述光线检测法,在MAME中,这类游戏的输入是用鼠标来模拟的;屏幕上一般都实时显示出了枪口当前所指向的位置,这是其特征所在。而另一类是枪下面只有线缆、没有底座的,如死亡之屋等HandGun游戏,由于用的是光线检测法,因此其屏幕上并不会实时显示枪口瞄准镜,值得注意的是,这类游戏在移植到PC上时把光枪支持全砍了,而使用了鼠标模拟+显示瞄准镜的方式来替代,导致临场感大减
posted @ 2008-01-01 07:51 neoragex2002 阅读(...) 评论(...) 编辑 收藏