我是用IDA8.3版本打开的,而且也找到了sub_41AF49函数,不过可能你文件里分析由于版本不同我看不到了,不过也能用F5或Tab(16位程序没法是真的痛苦啊),在看到了其中C语言就大致明白了,还一眼辨认出了sub_38AD2和sub_41AF49其中相同之处。
for ( j = 0; v17 && a3 > (int)j; j = v18 )
{
v17 = 0;
v18 = -1;
v24 = -1;
for ( k = 0; (unsigned __int8)byte_46FCC9 > k; ++k )
{
for ( m = 0; (unsigned __int8)byte_46FCC8 > m; ++m )
{
v13 = *(_BYTE *)(m + k * (unsigned __int8)byte_46FCC8 + v20);
if ( v13 > (int)j && v13 != 255 && v13 < (int)v24 )
v24 = *(_BYTE *)(m + k * (unsigned __int8)byte_46FCC8 + v20);
这段很明显就是sub_38AD2里的那个三重循环,a3是最大移动力,byte_46FCC9是高,byte_46FCC8是宽,v17与var_1E作用类似,v18与var_8作用类似。
v24与英杰传不同,它应该优化了Zoc-Skip的问题,v24在一轮循环后的最终值是所有点里大于j中的最小值,就不会出来有点漏过搜索的问题,不过反汇编好像还不够智能。直接v24 = v13不就行了。
for ( n = 0; n < 4; ++n )
{
v9 = sub_419655(v31, n);
sub_401890(v9);
if ( (unsigned __int8)v27[0] != 255 )
{
v19 = (unsigned __int8)v27[0] + (unsigned __int8)v27[1] * (unsigned __int8)byte_46FCC8;
这段是sub_38AD2里的探索四个方向的新点再保存到v27里,和sub_38AD2保存到var_1A应该是相似的。
v12 = sub_4195DA(v27);
v11 = sub_42A2D9(v12);
if ( v11 != 255
&& v11 + v13 <= a3
&& (*v29 == 255 || sub_409220((char *)dword_46C098 + 23 * *v29) == v25) )
{
*v32 = v11 + v13;
v17 = 1;
这段就是判断如何新点是否能到底以及是不是不超过a3,v11就是新点的移动消耗,判断v11 + v13 <= a3也是一样的,更新v17就是英杰传的sub_38AD2更新var_1E,真是浪费,一个变量就不停在0和1之间改。
if ( *v32 < (int)v18 )
{
if ( !a7 || v26 )
{
v18 = *v32;
}
else if ( !sub_41922C(v27, v25) )
{
v18 = *v32;
if ( v24 < (int)*v32 )
v18 = v24;
}
}
v18由于有v24的辅助,不会出现sub_38AD2的var_8问题了。
if ( (a4 & 8) != 0 && *(unsigned __int8 *)(v19 + sub_447720(0, 0, 4)) != 255 )
{
sub_447720(0, 0, 4);
if ( sub_409360(32) )
return *(_BYTE *)(v19 + sub_447720(0, 0, 4));
}
if ( (a4 & 2) != 0 && sub_41E280(v27, v34) )
return 1;
if ( (a4 & 4) != 0 )
sub_41D148(v27);
这也太明显了,连test a4, 8到test a4, 2到test a4, 4的顺序都是一样的。
sub_41AF49应该修正了Zoc-Bug,太不容易了,这个实习生写的代码终于有同事帮忙改了。。
只用了一点点时间分析,如果有什么错的还希望你能指正一下。