补充下游戏里的计算代码
先列出汇编代码,这段代码全是计算,看得倍儿晕,我用IDA转成C才看懂,C代码贴在后面了。
汇编代码只做几个注释。
4272C5函数只会依次根据人物的坐标计算位置,并不会对20000个字节依次计算。
004272C5 /$ 55 PUSH EBP
004272C6 |. 8BEC MOV EBP,ESP
004272C8 |. 83EC 10 SUB ESP,10
004272CB |. 56 PUSH ESI
004272CC |. 8B45 08 MOV EAX,DWORD PTR SS:[EBP+8] 读取人物的横坐标
004272CF |. 33C9 XOR ECX,ECX
004272D1 |. 66:8B08 MOV CX,WORD PTR DS:[EAX]
004272D4 |. C1E1 03 SHL ECX,3
004272D7 |. 66:894D F0 MOV WORD PTR SS:[EBP-10],CX
004272DB |. 8B55 0C MOV EDX,DWORD PTR SS:[EBP+C] 读取人物的纵坐标
004272DE |. 33C0 XOR EAX,EAX
004272E0 |. 66:8B02 MOV AX,WORD PTR DS:[EDX]
004272E3 |. 6BC0 F8 IMUL EAX,EAX,-8
004272E6 |. 66:8945 FC MOV WORD PTR SS:[EBP-4],AX
004272EA |. 8B4D F0 MOV ECX,DWORD PTR SS:[EBP-10]
004272ED |. 81E1 FFFF0000 AND ECX,0FFFF
004272F3 |. 8B55 FC MOV EDX,DWORD PTR SS:[EBP-4]
004272F6 |. 81E2 FFFF0000 AND EDX,0FFFF
004272FC |. 03CA ADD ECX,EDX
004272FE |. 66:894D F8 MOV WORD PTR SS:[EBP-8],CX
00427302 |. 8B45 08 MOV EAX,DWORD PTR SS:[EBP+8]
00427305 |. 33C9 XOR ECX,ECX
00427307 |. 66:8B08 MOV CX,WORD PTR DS:[EAX]
0042730A |. 8B55 0C MOV EDX,DWORD PTR SS:[EBP+C]
0042730D |. 33C0 XOR EAX,EAX
0042730F |. 66:8B02 MOV AX,WORD PTR DS:[EDX]
00427312 |. 03C8 ADD ECX,EAX
00427314 |. C1E1 02 SHL ECX,2
00427317 |. 8B55 10 MOV EDX,DWORD PTR SS:[EBP+10]
0042731A |. 81E2 FFFF0000 AND EDX,0FFFF
00427320 |. C1E2 03 SHL EDX,3
00427323 |. 2BCA SUB ECX,EDX
00427325 |. 66:894D F4 MOV WORD PTR SS:[EBP-C],CX
00427329 |. 8B75 F8 MOV ESI,DWORD PTR SS:[EBP-8]
0042732C |. 81E6 FFFF0000 AND ESI,0FFFF
00427332 |. 6A 08 PUSH 8 ; /Arg1 = 00000008
00427334 |. E8 7DF8FFFF CALL 00426BB6
00427339 |. 83C4 04 ADD ESP,4
0042733C |. 25 FFFF0000 AND EAX,0FFFF
00427341 |. C1E0 03 SHL EAX,3
00427344 |. 99 CDQ
00427345 |. 2BC2 SUB EAX,EDX
00427347 |. D1F8 SAR EAX,1
00427349 |. 8D4406 F8 LEA EAX,DWORD PTR DS:[ESI+EAX-8]
0042734D |. 66:8945 F8 MOV WORD PTR SS:[EBP-8],AX
00427351 |. 33C9 XOR ECX,ECX
00427353 |. 66:8B0D B4CE4>MOV CX,WORD PTR DS:[49CEB4] 49CEB4=60
0042735A |. C1E1 03 SHL ECX,3
0042735D |. 66:8B55 F8 MOV DX,WORD PTR SS:[EBP-8]
00427361 |. 66:2BD1 SUB DX,CX
00427364 |. 66:8955 F8 MOV WORD PTR SS:[EBP-8],DX
00427368 |. 33C0 XOR EAX,EAX
0042736A |. 66:A1 B6CE490>MOV AX,WORD PTR DS:[49CEB6] 49CEB6=25
00427370 |. 8D0CC5 F8FFFF>LEA ECX,DWORD PTR DS:[EAX*8-8]
00427377 |. 66:8B55 F4 MOV DX,WORD PTR SS:[EBP-C]
0042737B |. 66:2BD1 SUB DX,CX
0042737E |. 66:8955 F4 MOV WORD PTR SS:[EBP-C],DX
00427382 |. 8B45 08 MOV EAX,DWORD PTR SS:[EBP+8]
00427385 |. 66:8B4D F8 MOV CX,WORD PTR SS:[EBP-8]
00427389 |. 66:8908 MOV WORD PTR DS:[EAX],CX
0042738C |. 8B55 0C MOV EDX,DWORD PTR SS:[EBP+C]
0042738F |. 66:8B45 F4 MOV AX,WORD PTR SS:[EBP-C]
00427393 |. 66:8902 MOV WORD PTR DS:[EDX],AX
00427396 |. 5E POP ESI
00427397 |. 8BE5 MOV ESP,EBP
00427399 |. 5D POP EBP
0042739A \. C3 RETN
49CEB4和49CEB6的值在这里改。但改了人物也只有垂直或水平方向的偏移。
00429828 |. 66:C745 F8 3C>MOV WORD PTR SS:[EBP-8],3C
0042982E |. 66:C745 F4 19>MOV WORD PTR SS:[EBP-C],19
0042984F |. 66:8B4D F4 MOV CX,WORD PTR SS:[EBP-C]
00429853 |. 66:890D B6CE4>MOV WORD PTR DS:[49CEB6],CX
0042985A |. 66:8B55 F8 MOV DX,WORD PTR SS:[EBP-8]
0042985E |. 66:8915 B4CE4>MOV WORD PTR DS:[49CEB4],DX
=======================================
int16 cdecl sub_4272C5(int a1, int a2, int16 a3)
int16 result; // ax@1
int16 v4; // ST0C_2@1
v4 = 4 *(a2 + a1)-8 * a3-(8 * word_49CEB6 - 8);
a1 = -8*a2 + 8*a1 + 8 * (unsigned __int16)sub_426BB6(8) / 2 - 8 - 8 * word_49CEB4;
result = v4;
a2 = v4;
return result;
}
其中
a1=游戏里横坐标
a2=游戏里纵坐标
a3=0
(unsigned __int16)sub_426BB6(8)的输出值是0C8H,也就是200。(这两个值是否浮动还未知。)
word_49CEB6=19H。
word_49CEB4=3CH。
所以计算得到的公式:
设bmp里横坐标为x (0<x<640)
纵坐标为y (0<y<400)
游戏里横坐标为a
纵坐标为b
x= 4*(b + a)-8*0-(8*25-8)
y= -8*b + 8*a + 8*200/2-8-8*60
==>化简得:
x=(a-b)*8+312
y=(a+b)*4-216
这个就是最终公式了。
但是不知为什么,算出来的a和b与地形编辑器里的坐标不一样,有点误差。当然大体上对了,常数误差而已。
因为我在游戏里看到的bmp坐标(点击人物后在49CED8,49CEDC显示)和画图软件中查看的坐标不同。
所以这个公式现在还只供参考。
不过要是改成直坐标,那就是非常简单了。
[ 本帖最后由 WHITESHIP 于 2013-2-15 13:32 编辑 ]
|