識上網 自己搵啦
game development
アクションゲームツクール
http://www.gamfe.edu.hk
FC 模擬器
所有FC游戏下载
1. 你要有一定的英文看读水平,不会也没什么那就在网上多找找中文资料(可是比较少)。
2. 计算机语言编程语你要会。你最好会C/C++,但是你就会个C/C++是也是不行的。编程很多知识是贯通的,对吗?比如,你的汇编能力的要求大于C /C++的能力。你要执行FC ROM的程式,就一定要有CPU吧。FC这个CPU是6502。你要用软件来编写一个“虚拟的”CPU。就是像JAVA虚拟机那样的东西,解释执行每条指令。如果你对汇编不精通,那么你是根本就不能理解是怎么回事情的。那么又谈什么“用高级语言编写它”呢?我觉得,如果你不是从大学前就开始玩电脑的那部分 “天才儿童”,对于一个普通的计算机系的大二学生来说,这个模块有点挑战。会遇到很多细节问题。而且还要考虑到效率问题。而且非常不好调试。一开始还要自己开发一个调试器来调试代码。
总的说来,对于编程语言来说,至少要熟练掌握2种—— C/C++(VB当然也可以,只不过很麻烦) 和 汇编。最好是C/C++,我之所以我不考虑VB,JAVA之类的语言,确实是因为我水平太低了。这两个语言本来就很慢,如果自己编写的代码质量稍微差点儿,那么这个模拟器就慢了。大部分的模拟器都是用C/C++或加点汇编写的。不过也有牛人,国外的就不说了国内有个网友(ZYH)的用VB写出了一个FC 模拟器的,而且效率还可以。我想大部分人离这个水平有距离吧。所以就只有用效率较高点的高级语言来弥补自己知识的不足。也确实是如此。 :(
以上的课程是个大学都有开设。汇编你在学校学的肯定是X86的。一定要学懂。真正学懂后再使用其他芯片的指令集也就很轻松了。其他有关的课程肯定是《计算机体系结构》了。我觉得有用,很多知识都用到了。其他的课,虽然没直接用到,但你心中多点东西,可以想到的东西也就多点。
关于语言,最后谈一下我自己关于汇编的建议——不要用汇编去一大块一大块的编写软件。现在很多人迷信这个,觉得“用汇编写效率就是高”。说句不好听的,现在的编译器优化功能比蹩脚的汇编程序员强多了。你不信,你就用汇编写个1000行的程序,然后用C写个相同的程序,让编译器优化编译,然后反汇编出来比较一下两者即可见分晓。花很多时间精力去完成一个毫无移植性可言,而且效率也不甚高的软件模块——完全就是虐待自己。最后总结一下用汇编的时机:
①高级语言不支持该功能的时候,可用汇编辅助完成之;
②编译器编译出的东西不令你满意的时候,可用汇编局部修改之;
③你汇编功底强得出众,觉得微软的编译器就是一驮屎的时候,可用汇编完全书写之。
上面那个网站上就有一个完全用汇编写的6502核心,远没有另一个用C写的效率高。
3. 熟练掌握开发语言后,就可以编写上面说的那个CPU核心了。模拟不同的机器,也就是CPU不同(指令集不同)。大致就是解释执行。如下:
while (1) {
fetch();
exec();
}
让它在游戏ROM里“死循环”,不停地取指令,执行指令。这个原理在《计算机体系结构》之类的课里都有。我就不多说了。
对于指令的解释,就要参考上面获得的资料了。也就是看看每条指令做了什么,影响了什么寄存器,或内存什么地方的值。然后你用软件完成相同的工作就可以了。
exec()函数里像下面这样(当然是简化版本的,还要考虑到时序等问题):
void exec() {
switch (code) {
case ADD:
....
case SUB:
....
.
.
.
} // end of switch
IP += code_length;
} // end of exec()
比如,模拟ADD指令,看资料说它就是把A和B寄存器的值相加放到A里。于是,你解释这条指令的时候,就(其中reg_a, reg_b是你定义来模拟该芯片的寄存器)
case ADD:
reg_a = reg_a + reg_b;
break;
如此而已。体力劳动。因为一个CPU的指令是很多的,有些指令也的确比较复杂... 而且,这里千万不能出错!且不说导致游戏不能运行,而且你后面的工作就不能正常进行,因为一旦有问题,你根本就不能确定到底是哪个模块出错。所以最好写个简化的调试器,边写边调试。确定这个模块没有问题后,再做后面的工作。
像FC是8位的6502,GB是Z80,都是较简单的。GBA 32位的ARM有两种模式,解码也要比上两种复杂一点,但努力一下也不是很遥远。SFC,MD 16位,具体什么我不清楚,估计也不是很难。SS是双CPU,PS的也不清楚。不过看看可用的模拟器那么少,估计32位的次世代主机的模拟有难度。 PS2,N64之流的主机YY一下也就算了,只能望洋兴叹。:(
其实,主机的不同,多半都是在模拟视频和音频的时候体现出来的,所以虚拟CPU的编写方法都差不多。只是具体的指令不同而已。
4. 模拟视频。道理很简单。虚拟CPU转起来了,它就已经在执行游戏程序了。这个时候在模拟的内存里的东西都在正确的变动。这个时候其实游戏已经运行起来了。但是,看不到的东西如何玩啊?在模拟的内存中,有一块叫做显存,它表示游戏屏幕的状况。不同的机种,有不同的格式。读资料。按它的格式在我们的窗口屏幕上打有颜色的点即可。需要效率啊。用GDI绘图就不科学。那个慢啊,根本就不可能跑得起来。所以要想办法直接操作我们PC屏幕的显存,直接在上面操作象素。如果是在DOS系统下,那么容易办到。在Windows下可以借助DirectX。对这个不了解,就只有到学校图书馆借一本看几天了。其实也不一定要 DX,只要你能做到很快的在屏幕上打点即可。(FC中这个部件叫做 PPU, Picture Processing Unit )
5. 音频模拟。虚拟CPU里有几个寄存器。游戏ROM程序不停地更新它们,基本思想就是读出来,按机种格式转换一下,放到我们PC机的音频缓冲区里。这里要操作音频缓冲区,就又要用到DirectX了。我的FC模拟器里暂时都还没有加入声音模块(FC中由专门部件 APU, Audio Processing Unit 处理声音)所以也没有什么好向你吹的。基本上,所有的模拟器编写者,都是在模拟器其他部分接近完美的时候才开始写这部分的。我想是因为大部分程序员对较底层的声音编程这个领域不熟悉造成的吧。我自己就是一个白板...
6. 控制。就是模拟手柄输入。不同的机种有不同的方法。相比前两个问题这个简单多了,看看文档,想个方便的方法就可以了。只要结果相同即可,具体实现方法不限。也就是在模拟内存的某一个映射寄存器里适当的返回点东西即可。如果只支持键盘,用API就可以解决。如果要支持其他外部设备,比如USB小手柄之类的东东,就需要用DirectX。如果不怕麻烦,你给专门设备写驱动程序也可以,不过肯定有人要批评你是傻的。有些游戏机有除了手柄外的其他外设,比如FC 就有光线枪,四人分插等。其实和手柄差不多。只是占用的端口不一样罢了。
7. 存档功能。有两种,一是游戏正常存档,模拟内存中有专门的区域保留这部分信息。选择存档后,将这部分内容保留到文件中即可。二是游戏即时存档,很简单,将当前的所有寄存器值,所有要变动的内存段全部保存到文件中。读档时全部恢复即可。
8. 其他功能。比如什么 截图,录制声音,你完成了4和5,从底层完成了所有工作,就发现这些功能就都是些简单小问题了。截图只要将打点信息按格式写入文件,在加个文件头即可 (.bmp)。录制声音功能也是音频模拟的一个附属产物,将数据写文件,加个文件头(.wav)。
[
本帖最後由 alexlee2 於 2010-12-14 11:21 PM 編輯 ]