谁有m9街机m9模拟器器, 方向键在下面的那...

4697人阅读
IT技术(20)
转自=easyrock(2路转4路)=的原创,很少看见这么深入底层的与性机制详解,牛人啊,膜拜ing进而收藏之!
街机模拟器工作原理 &
& 这几天学习了一下finalburn的源代码,有一些心得,惊喜之余,整理出来与大家分享。 &
& 我们常说的芯片,通常都是接受一定的输入,完成特定的计算,并产生结果。输入通常来自相连的外设,输出也传递到外设。例如,最简单的计算器,内部也有一个芯片,我们在计算器的键盘上输入3+5=,就转化成了计算器芯片的输入参数,并启动内部的计算逻辑,算出结果8,在屏幕上显示出这个结果。作为cpu的计算器芯片,在这个过程中已经与两个外部设备进行了交互:键盘和显示屏。 &
& cpu与外围设备交互,通常有特定的方法。像x86系列cpu,提供了io端口,中断,内存映射这几种方式。例如cpu与显卡的交互,通常会使用到以上所有的方式:显卡的帧缓存通过内存映射,使cpu可以寻址到;显卡芯片的寄存器(显卡芯片也是一个cpu,也有寄存器)通过io端口进行读写,通过读写寄存器这种低级的编程方式,显卡开始各种工作(例如bitblt),cpu也并行的进行其他计算工作,当显卡完成某个功能调用后,通过x86中断通知cpu所需的请求已经完成,进而cpu可以再请求显卡做下一步工作。通过中断,cpu和显卡处于异步的方式,cpu不必等待显卡完成绘图。 &
& 几乎所有的芯片都是可编程的,也就是说,可以定制它们的工作方式。只是一些芯片提供了良好的编程接口。像x86系列,MC68000等这样的芯片,可以运行一段事先写好的程序,来完成某一特定的功能。而像早期的显卡芯片,只能通过读写寄存器来调用显卡的功能。 &
& 街机模拟器,最核心的功能就是模拟那些街机用到的芯片。比如《街霸2》这个游戏,用到了MC68000做cpu,Z80做音频处理,还用到了一个yamaha的音频芯片,视频方面应该用到了一个芯片做输出。 &
& 游戏的rom,包含音频、视频数据,和游戏代码。代码就是在MC68000上跑的,因此先说一下MC68000的模拟。 &
& MC68000(m68k)的模拟器是用汇编写的,来自于MAME。从代码中可以看出,m68k有一组寄存器、接受中断输入、通过内存映射与外设交互。m68k模拟器的内存接口由客户端(使用该模拟器的代码,在这里就是街机模拟程序)提供,这样一来,客户端就可以接管m68k与外设的交互了。例如,用于音频处理的z80,寄存器组被映射到m68k的某一地址段上。m68k在运行过程中读写z80的寄存器,实际上回调街机模拟程序的相应代码,转发给了z80模拟器。通过这种方式,就可以模拟m68k与其他外设的交互了。 &
& m68k模拟器用本机代码模拟m68k的指令集。每一条m68k指令用一段本机代码来模拟。对于一段m68k代码,结合ip(指令指针)找到对应的m68k指令,通过一个跳转表,跳到对应的那一段模拟代码执行。每一条m68k指令模拟出来的执行周期是原指令周期的数倍到数十倍。因为本机cpu的速度通常是m68k速度的数百倍,所以这样的模拟不会有问题。 &
& 那么本机cpu(host)与被模拟的cpu(m68k)是如何联系的呢?首先必须让模拟的m68k在正常的主频下运行。host用指定的频率(例如60Hz)来调用m68k模拟器,指定让m68k运行多少个时钟周期(cycle)。比如想让m68k跑在8MHz,那么每次要让m68k跑=133333个cycle。在m68k运行的过程中,自然会通过内存接口与外设交互,这样就让其他外设的模拟器开始相应的模拟工作。 &
& 视频部分没有用到模拟器,我推测是使用的帧缓存(framebuffer)。因为2D游戏的画面都是通过贴图(tile)完成的,不需要绘制。为了达到60Hz的刷新率,模拟程序每次在m68k跑完时钟周期后,读取这个帧缓存,转化成符合当前屏幕格式的位图,blt到显卡。这个过程还需要进一步的学习。&&&
& 我的最终目的是想移植finalburn到linux上。国外早就有了这样一个项目,但是为了学习,一切都要自己去尝试。 &
& finalburn的源代码直接在下载。逻辑上分为几块:底层的模拟库burn,上层的ui库burner。其中burn用到了更底层的a68k和doze两个模块,他们分别是MC68000模拟器和Z80模拟器。 &
& 街机游戏包含两块板卡:主机板和游戏板。主机板上有cpu,dsp等处理器,游戏板上存放的是游戏rom和加密用的电路。我们玩模拟器,需要解密后的游戏rom,相当于我们手头上有了游戏板,在模拟器中载入游戏rom,就可以开始游戏。所以模拟器还需要模拟主机板(基板),而不是光是单纯的MC68000cpu和Z80cpu。 &
& 基板有点像电脑主板,上面不光有cpu,还有很多外设,像声卡、网卡等。比如《街霸2》游戏使用的cps1基板(Capcom & Play & System-1),主控cpu是用的MC68000,音效cpu是用的Z80。为了能控制Z80,肯定是要把Z80的寄存器空间映射到MC68000的地址空间上来。MC68000读写某一段地址的内存,到底是要读写数据,还是访问某个外设的寄存器?不同的基板,各有特定的外设,和映射方式。所以正确的模拟出这些游戏机板,是模拟器的第二个重要工作(第一个当然是模拟各个独立的cpu)。 &
& 因此,模拟器的底层模块,分为模拟cpu和模拟基板两类。显然模拟cpu的模块是高度可复用的,比如mc68000的模拟模块,可以用于模拟cps1,cps2和mvs(neogeo)基板,因为他们都用到MC68000cpu。针对新出现的基板,如果用到的某个cpu已经有了模拟的模块,同样可以直接使用。MAME就是不断的模拟各种cpu和基板,以支持更多的游戏。 &
& 对于模拟的每一个游戏,也需要一个单独的模块。提供一些必要的信息和特定的处理。比如这个游戏有哪些rom,哪些用于视频,哪些用于音频,哪些是代码。有些游戏也需要特定的前期和后期处理。比如1944这个纵版游戏,在完成每一帧画面的组织后,要翻转90度。这些都是在特定游戏的模块中完成的。 &
& burn库模拟了cps1、cps2和system16基板。这三款基板都是用的MC68000cpu。加入更多的cpu模块,基版模块和游戏模块,就可以模拟更多的游戏了。 &
& 对于2D游戏的视频部分,因为不像3D游戏画面那样需要动态计算,2D游戏的所有图像数据都是事先画好的。通常分为几层,比如角色层、背景层等。每一帧的绘制都是按Z序来绘制这几层的。用&贴图&来形容这个过程比用&绘制&更贴切。因为每一层都被分成了NxM个方块,按照索引保存在rom的视频数据区。对于每一帧,计算出出现在屏幕上的那些方块,按照索引,就能找到每一个方块对应的图像。把这些方块贴到framebuffer中,就形成了生动的图像。&&
目前流行的模拟器都有Save/Load & Game的功能,和录像功能,这些是如何实现的呢? &
& 先谈谈游戏中随机事件的产生。比如玩《街霸2》,每次我们选同一个人物,第一关的对手也不一定是相同的。又比如,第一关对手即使相同,电脑每次的进攻策略也不一样。这些都是相当随机的。可以想象成游戏使用了一个类似于rand()的函数,根据函数产生的随机值作出随机的反应。当然电脑对手的动作不是完全依赖于这个随机值,肯定还依赖于游戏者的输入动作,比如游戏者跳重腿,电脑对手通常会发出对应的招式来反击,或者挡,而不是随机的乱动。当然决定是反击还是挡,这本身也存在一个随机的选择。正是因为游戏中处处充满的不可预测性,才使得游戏更具有娱乐性。 &
& 然而,事实上,真正的随机是不存在的。这些随机都是根据一个种子值,经过各种不相关的运算产生的伪随机值,计算出的值又作为计算下一个&随机&值的种子。也就是,只要初始给的那个种子相同,每次计算出的随机序列都是一样的。这样随机就变成可预见和可再现的了。如果让初始种子与时间相关,那么只有相同的时间计算出的随机序列才相同,这样就大大降低了随机重复的可能性。可以推测,游戏中也用到了时间值来做为随机数的种子。这个时间值要么来自于一个单独的计时器,要么就来自于cpu&&不管来自于哪里,每次复位后,这些值都变成初始值了。 &
& 打开两个模拟器,载入相同的游戏,开始运行。这两个游戏运行的画面肯定是完全相同的。当然这还不足以说明问题。但是你投币,开始游戏,即使选择相同的人物,相同的剧情,游戏的发展也可能完全不同。这个不同来自于另一种类型的随机&&用户输入。因为用户的输入序列不太可能做到每次都相同,即使按键的序列相同,按键时间几乎不可能是一样的(这个时间显然是相对于游戏复位的时间)。如果能够做到在每次复位后,输入的按键和按键的时间都相同,那么游戏就变成了重复的视频和音频序列,也就是&&录像回放。模拟器要做到精确到帧的输入是很容易的,所以录像功能的实现,就是记录游戏者每次输入的精确帧号(或时间)和按键。播放录像时,首先复位,然后在适当的帧(或时间)上输入适当的按键。就这么简单了。 &
& 这个功能可以进一步发展到网络对战的实现。首先,连网的多个模拟器需要复位,然后每一帧都需要同步,这个同步就包括很重要的游戏者输入信息。首先,帧的同步确保了游戏时间的一致,也就确保产生一致的随机序列。再加上用户输入的同步,另一个随机源也达到一致了,所以每一个模拟器上的运行效果就都是相同的&随机&情况了。当然,网络对战实现起来远比这里提到的复杂,需要容忍网络延时,和处理网络数据的高效率传送,同步本身也是一个相当伤脑筋的事情。 &
& 游戏的Save/Load功能相对简单,Save只需记录当前游戏的运行数据,以便下次Load时恢复。需要记录的数据首先是内存。把所有的RAM保存下来,这样包括那些映射的外设的寄存器也一并存了,恢复时外设也恢复到了相应的状态。最后还应该保存cpu的寄存器状态。但是我在finalburn的Load/Save代码里没有找到保存68000cpu寄存器的相应代码。推测:开始运行后,寄存器就处于稳定的状态,或者处于一个简单的循环&&读取RAM和ROM数据,分派到相应的子程序进行处理。所以只需要把RAM数据替换,游戏就来到了保存时的状态。这个推测不太合理......&&
2D街机游戏都是以恒定的帧率运行的。比如《街霸2》这款格斗游戏,帧率为60。显然游戏运行过程中,CPU并不是一直处于忙碌的状态,而是等待一个60Hz的时钟,每次到了时间点上,才运行一帧。这里的运行一帧,包括检测玩家输入,运行游戏逻辑,产生一帧图像,和产生时间长度为1/60秒的音频数据。这个60Hz的时钟,来自一个外部设备的中断。通常这个外部设备就是街机的显示器。该显示器刷新率为60Hz,每秒产生60次VBlank信号,中断到CPU,驱动游戏运行。 &
& 模拟器的工作循环的伪代码类似于这样: &
& while & (1) & { &
& 休眠直到时间点(); &
& & & & & 扫描输入(); &
& & & & & 设置虚拟机VBlank中断(); &
& & & & & 运行虚拟机n个周期(); &
& & & & & 播放音频采样(); &
& & & & & 更新视频画面(); &
& 但是有几个问题需要考虑。首先,音频的播放比较麻烦。声卡以一定的速率,从一个缓冲区中循环读取PCM采样,然后播放。这个恒定的读取速率由采样率决定。比如,采样率为44100Hz,速率就是每秒44100个采样。反过来也决定了,声卡每读取44100个采样,时间就是1秒。1/60秒的时间,就是声卡读取个采样的时间。所以,&休眠直到时间点&这个过程,就是等待声卡读取完735个采样的时间,而不是系统时钟的1/60秒。同时使用两个时钟源的结果将是视频和音频不同步。 &
& 一方面要以声卡作为时钟源,另一方面还要确保声卡的缓冲区总是有正确的数据可供读取。不能等到声卡播放完当前一帧的数据,才去准备下一帧数据。需要提前准备好即将播放的数据,也就是缓冲一定量的数据。但是缓冲的时间应该尽可能小,以保持模拟器的低延迟性。 &
& 通过查询当前声卡读取缓冲区的位置,可以计算大概的时间,以确定是休眠等待还是运行下一帧。但是这个时间只能是大概的,而声卡的播放速度决定的时间是精确的。每运行一帧,把产生的音频数据写到缓冲区,这个过程重复的速度只有跟声卡读取数据的速度一模一样,才不会导致缓冲区溢出。速度不匹配,就需要控制了,如果产生数据的速度太快,就需要休眠一些时间,等待声卡播放到合适的位置,反之,则要快速运行几帧,准备好需要的音频数据,同时只更新最后一帧的视频画面。这种情况下,视频就丢帧了,但是几帧的丢失不会影响视频的流畅性。另外值得注意的是,即使视频的帧率因为丢帧而达不到60,虚拟机的运行还是要保持每秒运行60帧的,这样确保音频,输入和其他逻辑的正常运行。 &
& 如果加入网络对战的支持,&扫描输入&这个过程,需要通过网络通信来得到对方的输入,并同步各方的运行。网络的延迟是不可预测的,所以在延迟较大的情况下,很难保持音频的流畅。如果通过缓冲数据来缓解这个问题,又将带来游戏的延迟。在这种限制下实现的最好效果,因该是不超过100ms的延迟,和偶尔的停顿。&
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:79414次
积分:1126
积分:1126
排名:千里之外
原创:25篇
转载:17篇
评论:15条
(1)(2)(2)(3)(2)(1)(1)(2)(5)(3)(4)(5)(9)(1)(1)街机模拟器的中文列表选项在哪??_百度知道查看: 8147|回复: 103
发个FC模拟器+游戏(M9亲测)
TA的每日心情怒 18:32签到天数: 6 天连续签到: 1 天[LV.2]偶尔看看I
本人M9亲测,不记得在哪看的了,今天在这里在发上来给大家
先看下截图& &建议把A、B键设置在坐面音量大小的地方,摁着舒服~
个人最喜欢里面的热血高校了
[ 本帖最后由 jiali906 于
10:35 编辑 ]
本帖子中包含更多资源
才可以下载或查看,没有帐号?
智能币 +30
谢谢楼主的好东西与大家分享/
谢谢LZ分享,辛苦了
该用户从未签到
谢谢楼主分享!
该用户从未签到
[c002 [c002 [c002 楼主真厚道。
该用户从未签到
不错,谢谢楼主分享!
该用户从未签到
(c010 (y07
该用户从未签到
不错 一直在用,,很怀旧.........
该用户从未签到
sadasdsad(y40 (y40
该用户从未签到
支持分享,很不错的
该用户从未签到
有必要下一个
该用户从未签到
Powered by请高手帮忙解决一下街机模拟器问题_百度知道魅族M9手机玩街机模拟器时,十字键在屏幕左上很不顺手,有办法把十字键调到屏幕左下方吗_百度知道}

我要回帖

更多关于 m9模拟器 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信