作者:胡颖卓
FinalBurn Alpha是当今最好的CPS1/2模拟器之一,更可贵的是它是完全开放源码的。从FinalBurn Alpha 2.93开始,FinalBurn Alpha小组(以后简称FBA小组)便转向了多功能、多机种的支持,而不是像其它模拟器那样,出一个新游戏的破解就出一个新版,或是有一点儿改进就出一个新版。这样做利了开发者,而玩家却是觉得有些不便。
起初,我为大家写一些新版本的FBA,但这样会和FBA小组的版本对应不上。更是近来,我需要将主要精力放在网络游戏上,所以也没有太多的时间为大家写这些驱动。在这里,我针对FinalBurn Alpha 2.93的CPS2游戏19xx驱动为例,给大家做一下讲解,以便大家能自己写出新的驱动。
首先,要包含驱动头文件cps.h,语句如下:
#include”cps.h” |
再者,是输入设备定义,也不用讲解,照例子抄就行了:
static struct BurnInputInfo DrvInputList[] = { {“P1 Coin” , 0, CpsInp020+4, “p1 coin” }, {“P1 Start” , 0, CpsInp020+0, “p1 start” }, {“P1 Up” , 0, CpsInp001+3, “p1 up” }, {“P1 Down” , 0, CpsInp001+2, “p1 down” }, {“P1 Left” , 0, CpsInp001+1, “p1 left” }, {“P1 Right” , 0, CpsInp001+0, “p1 right” }, {“P1 Shot” , 0, CpsInp001+4, “p1 fire 1”}, {“P1 Bomb” , 0, CpsInp001+5, “p1 fire 2”}, //19xx是两键游戏,如果是3键游戏,只需要按顺序加上就行了,例如 //{“P1 AutoFire”, 0, CpsInp001+6, “p1 auto fire”}, {“P2 Coin” , 0, CpsInp020+5, “p2 coin” }, {“P2 Start” , 0, CpsInp020+1, “p2 start” }, {“P2 Up” , 0, CpsInp000+3, “p2 up” }, {“P2 Down” , 0, CpsInp000+2, “p2 down” }, {“P2 Left” , 0, CpsInp000+1, “p2 left” }, {“P2 Right” , 0, CpsInp000+0, “p2 right” }, {“P2 Shot” , 0, CpsInp000+4, “p2 fire 1”}, {“P2 Bomb” , 0, CpsInp000+5, “p2 fire 2”}, {“Reset” , 0, &CpsReset , “reset” }, STDINPUTINFO(Drv); |
也有一种特殊情况,由于CPS2下格斗游戏非常多,而且使用的按键定义方法也一样,比如《少年街霸3》,我们就可以使用以下方法来定义:
STDINPUTINFOSPEC(Drv, CpsFsi); |
ROM表的写法我们来看看19XX的写法:
static struct BurnRomInfo NinexxRomDesc[]= { //文件名 ,文件长度,CRC校验码 ,类型 {“19xux.03” ,0x80000,0x239a08ae, 0x10}, // 0 XOR 表 {“19xux.04” ,0x80000,0xc13a1072, 0x10}, // 1 {“19xux.05” ,0x80000,0x8c066ec3, 0x10}, // 2 {“19xux.06” ,0x80000,0x4b1caeb9, 0x10}, // 3 {“19xu.03” ,0x80000,0x05955268, 0x10}, // 4 68000 代码 需要上面的进行解密 {“19x.13” ,0x080000,0x427aeb18, 1}, // 9 图像数据,此处要按3,5,7,9,4,6,8,0此类顺序排列 {“19x.01” ,0x020000,0xef55195e, 2}, // 17 QSound数据 z80声音数据 {“19x.11” ,0x200000,0xd38beef3, 2}, // 18 QSound声音采样 STD_ROM_PICK(Ninexx) STD_ROM_FN(Ninexx) |
这里面Ninexx是我们自己可以定义的名称,改成_19xx也是可以的。
之后是驱动信息结构,19XX的写法如下:
游戏ROM文件名称,为19xx的话,那对应19xx.zip 最大玩家数量 硬件类型 取zip名称特殊函数 Rom信息结构 Rom名称结构 输入配置信息表 DIP配置表 驱动初始化函数 |
struct BurnDriver BurnDrvCps19xx= { {“19xx”, “19XX: The War Against Destiny (US 951207)”, “”, “Capcom”, “CPS2”, “1995”, NULL, NULL}, BDF_GAME_WORKING | BDF_ROTATE_GRAPHICS_CCW, 2, HARDWARE_CAPCOM_CPS2, NULL, NinexxRomInfo, NinexxRomName, DrvInputInfo, NULL, DrvInit, |
DrvExit函数我们不用去管它,直接照抄一个就行了,关键在于DrvInit函数。下面我们来看一下19XX的DrvInit函数,并为大家做详细的讲解:
static int DrvInit() { int nRet=0; int i=0; unsigned char *pqs=NULL; Cps=2; //CPS1型游戏为1,CPS2型游戏为2 nCpsRomLen = 5*0x080000; //程序数据长度 对应文件3-10nCpsCodeLen= 4*0x080000; //需要XOR表解密的长度 对应文件3-10 nCpsGfxLen = 0x1000000; //图象数据长度 对应文件13-20 nCpsZRomLen= 1*0x020000; //QSoundDataZ80数据长度 对应文件1-2 nCpsQSamLen= 2*0x200000; //QSoundSample长度 对应文件11-12 nRet=CpsInit(); // 装载程序ROM,这里5为程序ROM数量,4为XOR表ROM数量 // 解密程序ROM,这里4为XOR表ROM数量 // 装载图像ROM // 装载Z80 ROM // 装载QSound Samples ROM nRet=CpsRunInit(); if (nRet!=0) return 1; |
至此,以上的讲解已足够大家为新的游戏写出一个驱动了,希望下次Razoola放出新的CPS2游戏XOR表时,大家能够不至于等待谁写出新的驱动,而可以自己解决。