铁血丹心

 找回密码
 我要成为铁血侠客
搜索
查看: 3997|回复: 5

[通用] 修改z.dat教程—增添显示的项

[复制链接]
发表于 2008-2-3 21:08 | 显示全部楼层 |阅读模式

马上注册,结交更多侠友!

您需要 登录 才可以下载或查看,没有账号?我要成为铁血侠客

x
用实际的例子进行说明。

这次我们的目的比较简单,在人物状态选单上增加一个显示品德指数的项。

这是原来的状态选单的第一页,考虑一下加到哪里合适:



经过简单分析,认为把所有选项全部左移,在右面增加一列比较美观。但是在这个演示例子里不做那么多,我们仅把头像和第一个字符串左移。

在show_PersonStatus子程中可以找到:

dseg02:00022A9C                 push    3
dseg02:00022A9E                 push    offset array_VRAM
dseg02:00022AA3                 push    0
dseg02:00022AA5                 push    0FFh
dseg02:00022AAA                 push    0C8h            ; 200
dseg02:00022AAF                 push    0D2h            ; 210
dseg02:00022AB4                 push    0
dseg02:00022AB6                 push    37h             ; 55
dseg02:00022AB8                 call    sub_2CEBF
dseg02:00022ABD                 add     esp, 20h        ; 32
dseg02:00022AC0                 push    offset array_VRAM
dseg02:00022AC5                 imul    ebx, edi, 0B6h  ; 182
dseg02:00022ACB                 movsx   eax, word_9014E[ebx] ; 头像代号
dseg02:00022AD2                 push    eax
dseg02:00022AD3                 push    44h             ; 头像显示位置X坐标
dseg02:00022AD5                 push    4Eh             ; 头像显示位置Y坐标
dseg02:00022AD7                 call    sub_2D590
dseg02:00022ADC                 add     esp, 10h


注释得这么清楚,看来不用多解释了。但是注意这个注释有些错误,在计算机绘图时往往y轴是先被提到的,所以这个头像坐标的注释实际上写反了。

上面的200和210是你看到的那个矩形框的高度和宽度,0和55是框的起始坐标位置。需要注意y轴是向下的。改成:

dseg02:00022AAA                 push    0C8h            ; 200
dseg02:00022AAF                 push    12ch            ; 300
dseg02:00022AB4                 push    0
dseg02:00022AB6                 
push    0ah             ; 10

头像位置的x坐标改小一些,比如把4eh改成21h,左移2dh个像素。

而显示攻击力的位置也同样左移:

dseg02:00022FC7                 push    10h
dseg02:00022FC9                 push    6663h
dseg02:00022FCE                 push    offset array_VRAM
dseg02:00022FD3                 push    offset aZDo     ; 攻擊力
dseg02:00022FD8                 push    5
dseg02:00022FDA                 push    0A0h

这个改为73h,上面的两个是该字符串的纵横坐标。

dseg02:00022FDF                 call    draw_string     ; 显示字符串 “攻击力”3个字
dseg02:00022FE4                 add     esp, 18h
dseg02:00022FE7                 push    10h
dseg02:00022FE9                 push    705h
dseg02:00022FEE                 push    offset array_VRAM
dseg02:00022FF3                 push    offset byte_C07C4
dseg02:00022FF8                 push    5
dseg02:00022FFA                 push    0E6h

这个改为b9h

dseg02:00022FFF                 call    draw_string     ; 显示字符串 显示数字
dseg02:00023004                 add     esp, 18h
dseg02:00023007                 imul    edx, edi, 0B6h  这个后面会被改写为call

先看看阶段结果:



看起来乱了些,但是可以一一修改全部的项,这样在右侧就有了空间。这里就不做了。

分析一下原版中显示一个数字用了些什么代码,大致是先调用sprintf生成字符串,再输出。我们先找一个能改写成call语句的地方。在调用显示数字的函数之后是清栈,后面是一个乘指令,占用6字节,可以改写为call指令(我并不是建议你改写这里,这只是一个例子)。

在z.dat里面找一个连续空白的地方,这里我们用5b800的位置。

23007开始的69 D7 B6 00 00 00 改为 E8 F4 87 03 00 90 (5b800h-2300Ch=387f4h,即从call指令结束的地方到目标地点所隔的字节数)。

看看原版怎样调用攻击力的值的:

dseg02:00022F61                 imul    edx, edi, 0B6h
dseg02:00022F67                 movsx   eax, word_901A2[edx] ; 攻击力

以下用来将数字转成字符串:

dseg02:00022FB4                 push    eax
dseg02:00022FB5                 push    offset a3d      ; "%3d"
dseg02:00022FBA                 push    offset byte_C07C4
dseg02:00022FBF                 call    sprintf??
dseg02:00022FC4                 add     esp, 0Ch


我们看到是利用edi进行一个乘法。那么edi里面的值在整个子程中应该不会有变化,观察一下确实如此。这个子程中利用edi保存人物id,简化了过程。如果是用栈中的数据表示的,需要先修改栈顶(因为call指令就会修改栈顶,经常我们需要在自己的子程前面加上pushad,也会修改栈顶),计算之后再改回去。我们照着葫芦画瓢,写自己的一段程序:

pushad
imul    edx, edi, 0b6h
movsx   eax, word_pinde[edx]
push    eax
push    offset a3d
push    offset byte_C07C4

call    sprintf??
add     esp, 0ch
push    10h
push    705h
push    offset array_VRAM
push    offset byte_C07C4
push    5
push    118h
call    draw_string
add     esp, 18h

后面在这里会插上一段
popad
imul    edx, edi, 0b6
retn

pushad 和 popad 是为了保存现场和恢复现场,避免原有的程序出错。最后一个乘法指令是重复原有的。

这段程序有5处是要修改重定位表的,我们先把这段程序译成机器码,写入5b8000h的位置:

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

0005B800   60 69 D7 B6 00 00 00 0F  BF 82 FF FF FF FF 50 68
0005B810   FF FF FF FF 68 FF FF FF  FF E8 2C 37 FE FF 83 C4
0005B820   0C 6A 10 68 05 07 00 00  68 FF FF FF FF 68 FF FF

评分

参与人数 1 +30 收起 理由
lift_viper + 30 原创精品

查看全部评分

【武侠.中国】铁血丹心论坛(大武侠):致力于推广和发展武侠文化,让我们一起努力,做全球最大的武侠社区。
可能是目前为止最好的金庸群侠传MOD游戏交流论坛,各种经典武侠游戏等你来玩,各种开源制作工具等你来实现你的游戏开发之梦。
发表于 2008-2-3 21:12 | 显示全部楼层
沙发,很强大,很使用,谢谢了,慢慢学~!加精吧~!
【武侠.中国】铁血丹心论坛(大武侠):致力于推广和发展武侠文化,让我们一起努力,做全球最大的武侠社区。
可能是目前为止最好的金庸群侠传MOD游戏交流论坛,各种经典武侠游戏等你来玩,各种开源制作工具等你来实现你的游戏开发之梦。
发表于 2008-2-4 17:45 | 显示全部楼层
好用~~~谢谢LZ
【武侠.中国】铁血丹心论坛(大武侠):致力于推广和发展武侠文化,让我们一起努力,做全球最大的武侠社区。
可能是目前为止最好的金庸群侠传MOD游戏交流论坛,各种经典武侠游戏等你来玩,各种开源制作工具等你来实现你的游戏开发之梦。
发表于 2008-5-1 17:10 | 显示全部楼层
谢谢LZ,让我明白我还是很弱
【武侠.中国】铁血丹心论坛(大武侠):致力于推广和发展武侠文化,让我们一起努力,做全球最大的武侠社区。
可能是目前为止最好的金庸群侠传MOD游戏交流论坛,各种经典武侠游戏等你来玩,各种开源制作工具等你来实现你的游戏开发之梦。
发表于 2008-7-27 08:55 | 显示全部楼层
【武侠.中国】铁血丹心论坛(大武侠):致力于推广和发展武侠文化,让我们一起努力,做全球最大的武侠社区。
可能是目前为止最好的金庸群侠传MOD游戏交流论坛,各种经典武侠游戏等你来玩,各种开源制作工具等你来实现你的游戏开发之梦。
发表于 2008-7-27 08:56 | 显示全部楼层
强烈支持LZ!金庸群侠传的又一大突破~!
之前不知有多少人提出过
终于被LZ破解了!

[发帖际遇]: ziyanfeng用胡萝卜、白萝卜、玉米粒、葱花等材料仿制侠客岛“腊八粥”,获利银两14.
【武侠.中国】铁血丹心论坛(大武侠):致力于推广和发展武侠文化,让我们一起努力,做全球最大的武侠社区。
可能是目前为止最好的金庸群侠传MOD游戏交流论坛,各种经典武侠游戏等你来玩,各种开源制作工具等你来实现你的游戏开发之梦。

本版积分规则

小黑屋|手机版|铁血丹心

GMT+8, 2024-12-22 23:05

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表