Monday, March 31, 2008

“系统增强”制作笔记

 

我把一些制作的要点整理出来,有兴趣的朋友可以做参考,也可以进一步加以修改。

 

1.升级算法

5B1F0开始是升级的相减处理,修改的方式与我以前发布的方法完全相同。

0005B1F0:  72 12                      JB      SHORT 0005B204
0005B1F2:  52                         PUSH    EDX
0005B1F3:  69D6 B6000000              IMUL    EDX,ESI,B6
0005B1F9:  8D48 01                    LEA     ECX,[EAX+1]
0005B1FC:  66:899A 6C010700           MOV     [EDX+7016C],BX
0005B203:  5A                         POP     EDX
0005B204:  C3                         RETN

2.伤害公式修改

下面是zz.ini里面的内容,从这些地方可以找到修改的地址。

[Hurt]

MinKnowledge = 391c4;  最低武学常识的地址,未改动。
Knowledge1 = 5b212;    我方武学常识地址,将代码移到5b210开始的位置改成标准乘法。
BaseAttack = 392ce;    攻击,未改动。
Magic = 5b553;         所使用武功,改成标准除法。
Energy1 = 5b55f;       内力,改成标准乘法。
Fist1 = 5b5a9;         拳掌。
Sword1 = 5b5be;        御剑。
Knife1 = 5b5d3;        耍刀。
Unusual1 = 5b5e8;      特殊。
Speed1 = 5b5fd;        轻功。

Knowledge2 = 5b222;    从这里开始是敌人的,基本差不多。
Energy2 = 5b250;
Fist2 = 5b265;
Sword2 = 5b27a;
Knife2 = 5b28f;
Unusual2 = 5b2a4;
Speed2 = 5b2b9;

Defence = 5b357;
Hurt1 = 5b1e2;         这个和下一个是总伤害的因子,改成标准乘法和除法。
Hurt2 = 5b1e4;

Random1 = 393b0;
Random2 = 393bc;

AddHurt = 393cd;
Random3 = 393dd;
Random4 = 393e9;

基本上我为了简单,将新添加的项写成了如下的形式:

0005B256:  66:83FF 01                 CMP     DI,1
0005B25A:  75 0F                      JNZ     SHORT 0005B26B
0005B25C:  0FBF81 FFFFFFFF            MOVSX   EAX,WORD PTR [ECX-1]
0005B263:  C1F8 01                    SAR     EAX,1
0005B266:  90                         NOP
0005B267:  90                         NOP
0005B268:  90                         NOP
0005B269:  03D0                       ADD     EDX,EAX

这个是防守方的拳掌相关的一部分。所有的新加项都是这样的。先设法取得武功的类型,再行比较。如果是类型1,则进行一些相关操作。如果某个加成与属性无关,就把jnz那句抹掉。 如果想屏蔽某一部分,就把jnz改为jmp。

上面写成FFFFFFFF并非真实的地址,这里的地址实际上由重定位表决定,写成这样是为了醒目。

3.物品选单

5B700开始是扩展物品选单用到的字符串,代码从5B7C0开始,开始是获取物品代码并绘制一个方框。由于刚开始考虑并不完善,实际上流程在其后的代码内部多次跳转。总共用了3个平行的循环显示3行数字,其后再显示了3行字符。

因为颜色是后添加的,所以流程多次去转到5B9F0处去确定颜色。同时多次用了pushad和popad处理现场。

4.状态选单

代码从5BA20开始,实际上用了两个循环和一个单独的显示字符函数。但是流程实际上是非常混乱的。因为这几个属性并不是连续存放并且实际上显示的顺序也不是由前到后的顺序,只能判断显示到第几个时进行跳转。

下面是显示那一排数字的代码,实际上在esi为7或1的时候,实际地址均有特殊的处理。

0005BA20:  60                         PUSHAD
0005BA21:  69DF B6000000              IMUL    EBX,EDI,B6
0005BA27:  81C3 6E002100              ADD     EBX,21006E
0005BA2D:  BE 08000000                MOV     ESI,8
0005BA32:  B9 16000000                MOV     ECX,16
0005BA37:  83FE 07                    CMP     ESI,7
0005BA3A:  75 03  &#1
60;                   JNZ     SHORT 0005BA3F
0005BA3C:  83C3 0A                    ADD     EBX,A
0005BA3F:  83FE 01                    CMP     ESI,1
0005BA42:  75 03                      JNZ     SHORT 0005BA47
0005BA44:  83EB 76                    SUB     EBX,76

0005BA47:  0FBF03                     MOVSX   EAX,WORD PTR [EBX]
0005BA4A:  60                         PUSHAD
0005BA4B:  50                         PUSH    EAX
0005BA4C:  68 FFFFFFFF                PUSH    -1
0005BA51:  68 FFFFFFFF                PUSH    -1
0005BA56:  E8 EF34FEFF                CALL    0003EF4A
0005BA5B:  83C4 0C                    ADD     ESP,C
0005BA5E:  61                         POPAD
0005BA5F:  60                         PUSHAD
0005BA60:  68 10000000                PUSH    10
0005BA65:  68 63660000                PUSH    6663
0005BA6A:  68 FFFFFFFF                PUSH    -1
0005BA6F:  68 FFFFFFFF                PUSH    -1
0005BA74:  51                         PUSH    ECX
0005BA75:  90                         NOP
0005BA76:  90                         NOP
0005BA77:  90                         NOP
0005BA78:  90                         NOP
0005BA79:  68 4E020000                PUSH    24E
0005BA7E:  E8 AF1DFEFF                CALL    0003D832
0005BA83:  83C4 18                    ADD     ESP,18
0005BA86:  61                         POPAD
0005BA87:  4E                         DEC     ESI
0005BA88:  83C1 11                    ADD     ECX,11
0005BA8B:  83C3 02                    ADD     EBX,2
0005BA8E:  83FE 00                    CMP     ESI,0
0005BA91:  75 A4                      JNZ     SHORT 0005BA37

这段汇编代码并不是一个好的例子,但它总算没有错误地完成了任务。直接修改代码费时费力,所以留下了一些空位,以及糟糕的地址处理方式。同上,代码中FFFFFFFF均是引用的地址,需要由重定位表确定。

5BB20开始是所需的一些字符。

5.其他

除了上面这些还有很多零碎的修改,比如四位数字的正常显示等。

 

下面是修改过程中添加的重定位项。

Offset      0  1  2  3  4  5  6  7   8  9  A  B  C  D  E  F

000189E0   07 10 FF 01 02 20 00 21  00 07 10 59 05 02 52 00   .... .!...Y..R.
000189F0   21 00 07 10 90 05 02 18  40 24 00 07 10 7F 05 02   !.......@$......
00018A00   7E 00 21 00 07 10 A3 05  02 64 00 21 00 07 10 B8   ~.!...?.d.!...?
00018A10   05 02 66 00 21 00 07 10  CD 05 02 68 00 21 00 07   ..f.!...?.h.!..
00018A20   10 E2 05 02 6A 00 21 00  07 10 4A 02 02 52 00 21   .?.j.!...J..R.!
00018A30   00 07 10 5F 02 02 64 00  21 00 07 10 74 02 02 66   ..._..d.!...t..f
00018A40   00 21 00 07 10 89 02 02  68 00 21 00 07 10 9E 02   .!...?.h.!...?
00018A50   02 6A 00 21 00 07 10 B3  02 02 58 00 21 00 07 10   .j.!...?.X.!...
00018A60   F7 05 02 58 00 21 00 07  10 0E 08 02 61 82 03 00   ?.X.!......a?.
00018A70   07 10 13 08 02 C4 07 1A  00 07 10 2A 08 02 00 00   .....?....*....
00018A80   25 00 07 10 2F 08 02 C4  07 1A 00 07 10 D2 07 02   %.../..?....?.
00018A90   C0 27 1B 00 07 10 DA 07  02 2C FE 16 00 07 10 E5   ?....?.,?...?
000
18AA0   07 02 00 00 23 00 07 10  6E 08 02 61 82 03 00 07   ....#...n..a?..
00018AB0   10 73 08 02 C4 07 1A 00  07 10 8A 08 02 00 00 25   .s..?....?...%
00018AC0   00 07 10 8F 08 02 C4 07  1A 00 07 10 CF 08 02 61   ......?....?.a
00018AD0   82 03 00 07 10 D4 08 02  C4 07 1A 00 07 10 EA 08   ?...?.?....?
00018AE0   02 00 00 25 00 07 10 EF  08 02 C4 07 1A 00 07 10   ...%...?.?....
00018AF0   2B 09 02 00 00 25 00 07  10 30 09 02 00 B7 03 00   +....%...0...?.
00018B00   07 10 5B 09 02 00 00 25  00 07 10 60 09 02 40 B7   ..[....%...`..@?
00018B10   03 00 07 10 8B 09 02 00  00 25 00 07 10 90 09 02   ....?...%......
00018B20   80 B7 03 00 07 10 C3 09  02 00 00 25 00 07 10 4D   €?...?...%...M
00018B30   0A 02 61 82 03 00 07 10  52 0A 02 C4 07 1A 00 07   ..a?...R..?...
00018B40   10 6B 0A 02 00 00 25 00  07 10 70 0A 02 C4 07 1A   .k....%...p..?.
00018B50   00 07 10 29 0A 02 62 00  21 00 07 10 9F 0A 02 00   ...)..b.!...?..
00018B60   00 25 00 07 10 A4 0A 02  20 BB 03 00 07 10 D6 0A   .%...?. ?...?
00018B70   02 00 00 25 00 07 10 C1  0A 02 29 BB 03 00         ...%...?.)?.

Friday, March 28, 2008

重定位表的作用

 

游戏的主程序文件z.dat实际上是一个线性可执行文件(LE),真实的扩展名应是exe。

重定位表用于标识可执行文件中与引用地址相关的语句。

在编译时,变量会被编译成地址,可以反汇编查看。但是代码段的地址位置通常只是形式上的,因为程序被载入内存时,究竟会被载入何处并不是确定的,所以代码段所写的地址通常跟真实的地址会差很远。在程序一开始,会依据重定位表,对代码段进行处理。

游戏主程序中的重定位表中的一项一般是这样的:

07 10 YY YY 02 XX XX XX XX

07 10 和 02 都是标志位,不同的标志位有不同的含义,游戏中只用了这一种。

重定位表一般是分段的,代码段中每 1000H 为一段,比如 20000H~20FFFH 的代码在重定位表中有单独一部分,而 21000H~21FFFH 又有另一部分。每一部分的开始位置写在重定位表的最前面,相当于索引。

在程序被载入时,一般可以这样理解:[段基址+YYYYH+程序实际载入的首地址]开始的4个字节会被替换成[XXXXXXXXH+程序实际载入的首地址]。

由于段基址是以 1000H 为一段的,所以 YYYYH 的最高位一般是0。

全部重定位项可以用一个应用程序 DUMPLX.EXE 导出。

我的描述仅仅是一个形象的说法,真正权威的解释和严格的格式定义可以从 LX 和 LE 格式的说明文档中找到。

Thursday, March 27, 2008

一些笔记

 

50指令的编写方式

1.保存现场。主要是ebx,edi,esi,ebp四个基本寄存器,eax和ecx均直接使用,不予保存。

2.从栈中提取参数。

2.处理标志位。方法是压入标志位位置标识,标志位,和参数。调用另一子程,返回标志位指定的数值或变量的值到eax。

3.指令功能。变量从内存120000H开始。有些是自编子程,完成某些系统功能的是引用原有的子程。

4.恢复现场,返回。

 

战场在内存中的保存方式

共3层:

第一层:26个人物数据。每个人物占据1CH字节,保存的数据主要有:人物战场id,人物实际id,敌友信息,坐标等。

第二层:效果信息。格式为40H*y+x+基址。在播放效果的时候会首先清空此层,之后根据所使用的招式重新对这一层的某些位置赋值为1,在播放效果的时候不为0的位置均会有效果。

第三层:保存整个战场信息。格式为(40H*y+x)*2+基址,每个位置占据一个字长,是战场上的人物信息,如对应位置有人,则是人物的战场id,如无人则是-1。

基址的位置在代码段和重定位表里面不同,需以重定位表中的值+20000H为准。

 

SwimmingFish未发现的

3B717H:人物最高等级。之前的修改器在30级之后一直不正常是因为漏了这个地址。

第二层战场信息的含义。

绘制背景矩形子程中第一个参数是透明度。对话框为4,其余大多为3。故对话框比其余很多框黑一些。

 

杂项

人物内场景坐标:1D295CH,1D295AH。

需要修改重定位表的有:属性引用,显示内存,直接用寄存器标示子程。

进入场景子程:28E40,参数一个,为场景编号,直接引用可进入某场景,如需切换场景则只引用部分。

游戏中使用的wav文件为11025bps,8bit,用其他软件生成的基本不能直接使用。

push会将字算术扩展为双字再入栈,提取时很可能已经不是原来的样子。需设法处理掉高位字的数据。

Thursday, March 13, 2008

改善对话框效果

我比较喜欢高分辨率的效果,前面很多显示补丁都和这个有关。目前可以说除了对话框能挪的都差不多了,还有几个小的字符串,比如进入场景的和战斗结束的,大概也无伤大雅。

这个补丁用于改善对话框的效果。增大了对话框大小和每页显示的字符数。

12个是对话框大小,对话框位置,头像位置,每个都对应不同情况下的4个值。因为头像大小固定,头像框大小就不用管了。至于每个数字控制什么,自己试一下吧。
注意对话框尺寸的y值不能超过127。
上面chinese charactors in 1 line 是一行中汉字的个数。

Pixels for 1 charartor in x (and y) axis 是一个汉字在x轴(和y轴)占的像素,如果是16和17就是原版的紧凑效果,想让汉字分开一些就把它们加大。

以下是两组不同的效果:

30, 102
16, 17, 4
512, 108, 512, 108
94, 17, 23, 336
23, 17, 546, 336

z_017

24,95
18,19,3
457,101,457,101
90,370,90,370
91,305,91,305

z1_004

Click here to download.

PTT版系统增强补丁

基本和“苍龙逐日”系统增强补丁内容是差不多的,但这次讲的详细些吧。

增强内容:

1、增强物品选单。在一页里显示72(6*12)个物品,同时在选单下方显示物品的详细属性。

2、增强人物状态选单。在一页里显示人物的全部属性,包括隐藏属性。

3、人物的属性值在1000以上时可以在状态、战斗、医疗中正常显示。

4、等级上限改为60级。使用了新的升级经验算法,可以正常升级。

5、使用新的伤害公式。内力,轻功,拳剑刀特均参与伤害计算。拳剑刀特4个属性仅在使用相应武功时有效,如御剑高的人用剑法伤害就会加强,同时对敌人的剑法防御也会加强。

6、增强医疗。

7、附带伤害公式编辑器,可以自己调整伤害公式和一些其他参数。

8、山洞场景里取消黑色遮盖。

一些细节说明:

1、PTT版里面许多属性是没有上限的。但这个补丁使用了0.72版的z.dat文件,取消上限比较麻烦,所以多数定为999。需要修改的请自己用Fishedit 0.72修改(至少我自己打通时还没到1000,但听说有把暗器练到几千的狂人)。

2、显示物品属性时,最后一行为秘笈或装备的要求,秘笈所需内力性质看数字的颜色。不过如果某个秘笈只要求阴性或阳性内力就看不到了,但这样的秘笈似乎没有。状态中还有中毒程度和受伤程度没显示。

3、修改器中有“空挥升级速度”和升级增加属性固定的修改。“空挥升级速度”越大,武功升级就越快,讨厌空挥的朋友可以试试。“升级增加属性固定”是在升级时加攻击防御轻功的值固定为资质所对应的最大值,在“苍龙逐日”中很多人问过类似的问题,但在PTT版里面这个大概没什么用。

4、由于PTT版很多地方比较夸张,级别升多点也没关系,所以解除了30级的限制。但注意敌人战斗后也会升级,所以你下次见到同一个人他可能会变强。

5、推荐使用dosbox运行游戏。

6、如果在使用时跳出并且报告缺少文件,可以自己先复制一个解决。出现类似问题请告知于我。

已知问题:

补丁与Fishedit 0.72基本兼容,但不要试图改回低分辨率。如果有些场景(主要是皇宫)有死角,可以暂时换回原来的z.dat。

我在编写新伤害公式的时候无意中占用了游泳的鱼为武器武功配合列表预留的一部分空间。目前来看不会导致bug,但是如果你需要自己增添这个列表,请不要超过30个。

Click here.

《再战江湖》系统增强

《再战江湖》是目前开放性最高的MOD,也是我最喜欢的。

这个补丁的内容与之前两个区别不大,是这个系列的最后一个,大概一段时间内不会再做。

请直接用z3.exe进入游戏(自己改成z.com或play.com或其他任何可执行文件名都可以)。

说明:

1、直接使用高分辨率。全属性密码正常,开始时正确显示主角躺在地上的图片,物品选单能够正常显示,所有属性的增加与原版一致。

2、取消山洞的遮盖,因为高分辨率时山洞遮盖效果不正常。

3、游戏中许多对话比较长,故附带对话框调整器,压缩包里的截图是我推荐的数值。不过《再战江湖》的对话文件并非talk.grp,而是zztt.ngm,所以可以先改文件名字,补丁后再改回去。另外注意主程序文件名不是z.dat。

4、其余请参考“PTT”版补丁的说明。

5、这个补丁中修正了物品数目超过32767后会出错的问题,如果物品数超过这个值之后就不再增加,之后就看着办吧。

已知问题:

1、我试过重新开始时品德指数总是很高,甚至有几次到了100,原因不明。

2、与liudu发布的修正补丁暂时不能兼容,因liudu修改了原版的一些内容。

感谢南宫老师同意放出本补丁。

感谢liudu协助测试。

Or click here to download.

《苍龙逐日》的系统增强补丁


08-01-25,Beta1:

征得原作者小小猪同意放出此补丁。

游戏数据没有任何修改,主要是物品选单上增加了显示物品的详细属性。同时附带伤害公式编辑器,可以自行调整伤害公式。修改器中添加了升级加属性固定的修改。
补丁中经验值的计算方法与原版不同(实际上补丁中的等级上限已经可以轻易取消),所以有些队友加入时经验可能过高。
需要修改进度请用fishedit0.72版。

这实际上可以算是最近制作的所有补丁在mod应用的一次集合和尝试。

08-01-26,Beta2:
秘笈需要内力性质可以显示,看最后一行数字的颜色。
显示人物隐藏属性。

08-01-26,Beta3:
隐藏属性漏了“抗毒”,补充上。

08-01-27,Beta4:
增加“生命增长”显示,修正一个字符串。
默认伤害公式略为修改。

08-01-27,Beta5:
修正队伍中有高武学常识角色时战斗跳出的错误。

08-01-28,Beta6:
选择初始属性可以看到资质,与原版一致。

08-01-29,Beta7:
进入游戏后即可正常查看物品菜单,无需黑屏。
在战斗时物品图像可以显示。
选择初始属性可以看到特殊。

不确定是否仍然有bug,使用时请多存档。

已知主要问题及修正记录:

1、刚进入游戏时物品选单不显示贴图,原因:主地图贴图个数未修改(Beta7中修正)。
2、在桃花岛打开机关时当机,原因不明。自己复制一个wav文件改名为atk36.wav可解决。
3、在选择性情节中,显示的字符串是“是否住宿”(Beta4中修正)。
4、队伍中如有高武学常识角色战斗时会跳出(Beta5中修正)。
5、战斗时物品贴图不显示,原因:初始内存未修改(Beta7中修正)。

Click here to download the Beta 7.