性别:男-离线 WHITESHIP

★★
谏议大夫

Rank: 16
组别 翰林学士
级别 征北将军
功绩 380
帖子 4210
编号 170977
注册 2007-6-3
家族 轩辕学院


发表于 2013-2-15 13:26 资料 个人空间 短消息 看全部作者
补充下游戏里的计算代码

先列出汇编代码,这段代码全是计算,看得倍儿晕,我用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 编辑 ]


顶部

正在浏览此帖的会员 - 共 1 人在线




当前时区 GMT+8, 现在时间是 2025-8-1 20:25
京ICP备2023018092号 轩辕春秋 2003-2023 www.xycq.org.cn

Powered by Discuz! 5.0.0 2001-2006 Comsenz Inc.
Processed in 0.010044 second(s), 9 queries , Gzip enabled

清除 Cookies - 联系我们 - 轩辕春秋 - Archiver - WAP