求街机游戏,名字不详 - 街机寻觅 -
mamecn--街机中国 街机模拟游戏,街机游戏下载,模拟器游戏下载 - Powered by Discuz!后使用快捷导航没有帐号?
查看: 3824|回复: 4
新人欢迎积分0 阅读权限40积分821精华0UID422408帖子金钱588 威望0
Lv.4, 积分 821, 距离下一级还需 179 积分
UID422408帖子威望0 多玩草10 草信仰力0
&&最近入了ipad mini 出门基本用它,觉得还是以前的游戏好玩,可惜imame支持的经典游戏太少了,变身忍者等游戏都玩不了,有些游戏还无声,苹果上还有更好支持更多游戏的街机模拟器么?
新人欢迎积分1 阅读权限80积分13389精华24UID107196帖子金钱23702 威望3
Lv.8, 积分 13389, 距离下一级还需 6611 积分
UID107196帖子威望3 多玩草363 草信仰力0
当然是mame4IOS reloaded,至不济也是ifba。老版的imame就用来玩CPS1的各种hack版游戏好了
&感谢,已经找到了Mame4ios 了,还是猪哥对模拟器了解深啊&
新人欢迎积分1 阅读权限20积分38精华0UID帖子金钱51 威望0
Lv.2, 积分 38, 距离下一级还需 12 积分
UID帖子威望0 多玩草0 草信仰力0
当然是mame4IOS reloaded,至不济也是ifba。老版的imame就用来玩CPS1的各种hack版游戏好了
新人欢迎积分1 阅读权限20积分38精华0UID帖子金钱51 威望0
Lv.2, 积分 38, 距离下一级还需 12 积分
UID帖子威望0 多玩草0 草信仰力0
当然是mame4IOS reloaded,至不济也是ifba。老版的imame就用来玩CPS1的各种hack版游戏好了
新人欢迎积分0 阅读权限50积分1995精华0UID2291001帖子金钱1743 威望0
Lv.5, 积分 1995, 距离下一级还需 505 积分
UID2291001帖子威望0 多玩草10 草信仰力0
我下了个mame4IOS reloaded,一点击就闪退,根本运行不起来,这是怎么回事?我是IPAD2
需要金钱:1100
手机盒子客户端点击或扫描下载
Powered by街机模拟器工作原理 - CSDN博客
街机模拟器工作原理
转自=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的延迟,和偶尔的停顿。&
本文已收录于以下专栏:
相关文章推荐
VMware Workstation v6.0.1 正式版下载Workstation 6.0包含了许多令人兴奋的新功能: 1、支持Windows Vista--使用Windows Vista作为主机操...
一.java虚拟机
java虚拟机是软件模拟的计算机,可以在任何处理器上(无论是在计算机中还是在其它电子设备中)安全并且兼容的执行保存在.class文件中的字节码。java虚拟机的&机器码&保存在....
一、类加载器
首先来看一下java程序的执行过程。
从这个框图很容易大体上了解java程序工作原理。首先,你写...
一、类加载器
首先来看一下Java程序的执行过程。
从这个框图很容易大体上了解java程序工作原理。首先,你写好java代码,保存到硬盘当中。然后你在命令行中输入
[java]vie...
他的最新文章
讲师:何宇健
讲师:董岩
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)