17 12
发新话题
打印

[已解决] [向游泳的鱼提问] 战斗中事件导致事件重入的问题

[向游泳的鱼提问] 战斗中事件导致事件重入的问题

因为战斗中事件会导致事件重入,所以我是使用的50 43指令来调用战斗事件,但是这个方法有一个瑕疵:就是如果一个事件一句话都不讲直接开战会导致战斗结束之后原事件后面的指令不能正常执行。
尽管这种情况很少见,但是使战斗指令不够完美。不知鱼大师有什么更好的方案。

此外fishedit中最严重的几个bug我认为是索引下标越界和输入类型不匹配,都是会导致修改器立刻崩溃的。不知有无较好的解决方案。因我对VB并不熟悉。

[ 本帖最后由 weyl 于 2008-8-11 00:46 编辑 ]
向所有在灾难中遇难的同胞致哀
感时花溅泪 恨别鸟惊心 烽火连三月 家书抵万金
blog for KYS

TOP

游泳的鱼不是神,一些错误是必然会有的,LZ只要经常备份就行了.
落花消魂红泥逝,昔燕末寒把手去.
故人不复于尘世,点点幽思有何益?
如今但待风云来,趁势回鸣天地厮!

TOP

不知道楼上为什么总是来答非所问

[发帖际遇]: KG遭遇四大恶人,狼狈逃窜,丢失银两20.
你们为什么要欺负我的朋友朱公子

TOP

我还以为KG会回答什么呢。。。。

TOP

你的意思我没有完全看明白,因为我对你在战斗中是如何调用事件的并不清楚。但是我讲一下我是如何编写50 43指令的你可能就会明白了。

z.dat中解析事件的函数Call_event只有一个参数,就是事件编号。但是它是把这个事件读入内存固定地址的。如果嵌套调用,则后面的事件会覆盖前面的事件。因此我在设计43指令时,在调用前先分配一块内存,然后把当前事件地址的内容复制到内存中。然后再调用call_event。调用完成后再复制回来。

addkdef.txt 中有这段代码:


  68 00 20 00 00            ;push 2000H
    e8 &3ed5b                 ;call 3ed5b    malloc
    83 c4 04                  ;add esp,04
    8b d8                     ;mov ebx,eax   分配的内存
   
    be *1d9e90                ;mov esi,offset 1d9e90         
    8b fb                     ;mov edi,ebx
    b9 00 08 00 00            ;mov ecx,800h
    f3 a5                     ;rep movsd        ; 把原来的事件内容复制到分配内存
   
    55                        ;push ebp
    e8 &2c319                 ;call 2c319    call event
    83 c4 04                  ;add esp,04

    8b f3                     ;mov esi,ebx
    bf *1d9e90                ;mov edi,offset 1d9e90
    b9 00 08 00 00            ;mov ecx,800h
    f3 a5                     ;rep movsd        ; 把原来的事件内容从分配内存复制回来

    53                        ;push ebx     
    e8 &45229                 ;call 45229    free
    83 c4 04                  ;add esp,04

  1d9e90,在原始z.dat中是d9e90,就是保存一条事件全部指令的起始地址,共2000H个字节。因此一个事件的指令字节数不能超过这个值。

我不知道你在战斗中是如何调用事件的。如果不进行处理,仍然避免不了重入问题。至于你说的问题具体是什么原因我也不太清楚。现在有源代码,你可以试着直接调用43指令的函数sub_2b,估计就没有问题了。有问题再说吧!

[发帖际遇]: 参与红花会陈家洛的计划:行动失败,遭清廷缉捕损失银两9.
我的网络硬盘:http://swimmingfish.ys168.com/
我的博客:http://blog.sina.com.cn/u/1271207321

TOP

至于修改器的错误处理不好,这个我也没有太多精力去一一处理。只能大家小心了。
不过既然有源代码,建议在vb6.0环境下运行,出错了编译器还可以捕获,然后移到下一条指令继续运行,估计能好一些。

[发帖际遇]: 游泳的鱼替小昭千里送信给张无忌,途中被赵敏拦截,损失银两11.
我的网络硬盘:http://swimmingfish.ys168.com/
我的博客:http://blog.sina.com.cn/u/1271207321

TOP

在战斗中使用物品调用事件和武功调用事件都是用了50 43指令,首先截获武功的代码,检查某个偏移是否设为大于0的值,如是则调用该值指定的事件。
我在使用的时候并未完全看懂,只是确定使用50 43会避免很多错误。
最初我是直接使用CallEvent,但是发现某些战斗不能返回,必须在战斗之前插入比使用的战斗事件更长的空指令才可以,也就是说在战斗前必须预留缓冲区。
后来改用50 43子程之后,这个缓冲区大小缩短为4个指令位长,也就是只要在战斗之前有1句对话,那么执行就会正常。这样这个问题基本是可以忽略的。

我不知道VB里面是不是可以试着重载转换函数,呵呵,源码的问题我们就尽量不麻烦你了。

[发帖际遇]: weyl请陈园园签名,被胡逸之发现,引为知己,增加奖惩积分7.
向所有在灾难中遇难的同胞致哀
感时花溅泪 恨别鸟惊心 烽火连三月 家书抵万金
blog for KYS

TOP

有两个问题是游戏引擎的,并没有完美解决。

一是场景内动态效果。
因为如果直接重画全部场景效率较低,所以我是先生成场景的映像,再实时画主角。
这样场景内动态效果在重画时就比较麻烦,因为重画这里的时候总要重画附近建筑层。所以我是屏蔽了占据范围较大的旗子的动态效果。

二是大地图山脉的遮挡,怎样确定绘图的顺序比较合适?

[ 本帖最后由 weyl 于 2008-8-5 20:03 编辑 ]
向所有在灾难中遇难的同胞致哀
感时花溅泪 恨别鸟惊心 烽火连三月 家书抵万金
blog for KYS

TOP

1. 关于战斗调用 50 43 事件的bug, 因为我对你修改的战斗指令不熟,如果你有时间,可以做个例子程序email给我,我可以测试一下。
2. 关于图形引擎,不知道你用的是什么技术,不过你可以试试我的jywin0.4的执行速度如何,我那里使用的是directx的directxdraw,就是全部重绘的。 过几天我把这个源代码也发布了吧,如果有人有兴趣可以继续开发,没兴趣也可以参考里面的代码实现。
3. 关于大地图山脉的问题,我也头疼了很久,后来硬着头皮看反汇编。在fishedit的大地图修改中就用了这个。frmMMapEdit.frm中的Game_Mmap_Build函数就是确定build的先后顺序的。你可以看看这个代码。另我的z.dat反汇编的24F8C位置就是处理先后顺序的函数,里面有些注释,你可以看看。具体原理我也忘了。好像就是做个列表,先按照顺序列,然后根据buildx和buildy判断阻挡,如果有阻挡,就调整列表的顺序。

[发帖际遇]: 游泳的鱼卖下一个mod的制作人绝密采访稿,狂赚银两1.
我的网络硬盘:http://swimmingfish.ys168.com/
我的博客:http://blog.sina.com.cn/u/1271207321

TOP

我采取的方法是判定山的中心点的位置。fenghou曾经给出过一套递归的算法,但是我没用。
用中心点基本可以准确判定95%的绘图顺序,少数出错的在地图边上,马马虎虎可以接受。
你用的算法我先试着看懂吧..

我试过直接画图的效率不高,也许可以试试双缓冲...不过我经常很懒的...

[发帖际遇]: weyl遭遇四大恶人,狼狈逃窜,丢失银两8.
向所有在灾难中遇难的同胞致哀
感时花溅泪 恨别鸟惊心 烽火连三月 家书抵万金
blog for KYS

TOP

使用directx的提高速度关键在于把贴图都放入VRAM,要知道从VRAM到VRAM的内存复制blit是不占用cpu时间的,速度要快的多。

我最开始是用在内存中生成总图,然后再blit到VRAM,后来发现速度比较慢,于是就在VRAM中开辟双缓冲,事先把贴图也blit到VRAM中,这样速度就快很多了。

不过我的机器VRAM很小,于是我针对贴图做了一个Cache,只把最近绘过的1000个贴图复制到VRAM中。这样基本可以保证速度了,毕竟大部分贴图是重复的,而且移动也是一格一格移动的。读取新贴图的机会就少很多了。

当然现在显卡的VRAM都很大,完全可以把全部贴图都放进去。这样编程就更简单了。

[发帖际遇]: 游泳的鱼无意中获得赵敏的木制倚天剑,卖给摆地摊的,获利银两1.
我的网络硬盘:http://swimmingfish.ys168.com/
我的博客:http://blog.sina.com.cn/u/1271207321

TOP

我使用的是SDL,在Windows下面实际上就是对DirectX的封装。
至于你说的直接操作VRAM的方法我倒还真没试过,看看有没有这个API吧。要是没有我也没办法了......

[发帖际遇]: weyl参与红花会陈家洛的计划:叛变勾结清廷,得到赏赐银两6.
向所有在灾难中遇难的同胞致哀
感时花溅泪 恨别鸟惊心 烽火连三月 家书抵万金
blog for KYS

TOP

我写的代码里对基本子程的封装太夸张了……晕倒中。

如果有3000个贴图,就先建立3000个表面(Surface is stored in system memory),在需要绘图时一一合并?

受不了了实在编不下去。现在有点浮躁。目前这个方法还能凑合,以后静下心来再改吧。至少现在已经知道较适合的办法了。

其实我对你和chaoliu,wind当年研究的精神是很推崇的。那些早期扩展列表的方法,很多可以说是天才的方法。如今很多的修改方案是站在你们的肩膀上才有的。

向所有在灾难中遇难的同胞致哀
感时花溅泪 恨别鸟惊心 烽火连三月 家书抵万金
blog for KYS

TOP

SDL为了通用性,效率方面就有些低了。我是直接用DirectDraw,用视频缓冲区保存贴图,俺就是在那里保存了1000个directx的surface对象。这样效率高很多。
不过directdraw还是不能处理alpha混合。象对话的半暗背景和淡入淡出效果,都是只能自己编程实现了。据说directx8以上可以实现,不过我不会用。

[发帖际遇]: 游泳的鱼在华山山谷捡到被令狐冲打落的宝剑,送回给宁女侠,宁女侠感谢万分,送你银两24.
我的网络硬盘:http://swimmingfish.ys168.com/
我的博客:http://blog.sina.com.cn/u/1271207321

TOP

sdl还可以, 也许以后还能移植? 而且用法比较简单, 适合我这种业余的用.
源码以后发布了别人也容易看懂.......

混合颜色的时候我是直接计算颜色值再混合, 毕竟这个游戏本身并不复杂.

[发帖际遇]: weyl遭遇四大恶人,狼狈逃窜,丢失银两18.
向所有在灾难中遇难的同胞致哀
感时花溅泪 恨别鸟惊心 烽火连三月 家书抵万金
blog for KYS

TOP

 17 12
发新话题