这次先分析个基本功能吧,选中棋子,就是我们点击一个棋子,它的颜色变了,代表选中
看起来一个简单的操作,让我们看看内部是怎么样的
先让我们看看一个结构体
FF FF FF FF 00 00 00 00
12 00 00 00 0C 00 00 00
1C 00 00 00 21 00 00 00 0B 00 00 00 14 00 00 00
08 00 00 00 09 00 00 00 09 00 00 00 00 00 00 00
00 00 00 00 FF FF FF FF
大小38h,红色的有9个,我们对照游戏棋盘一看,哈哈,正好一列
恩,这是一个列结构体,非0值代表棋子ID,然后好多列结构体
下面来看点击棋子函数
这个函数有3个栈参数 (01,Xpos,Ypos),ecx传入数据基地址
Xpos,Ypos 鼠标点击的 X,Y 坐标
00404BB0 . 64:A1 0000000>MOV EAX,DWORD PTR FS:[0]
00404BB6 . 6A FF PUSH -1
00404BB8 . 68 F1974300 PUSH llk4.004397F1
00404BBD . 50 PUSH EAX
00404BBE . 64:8925 00000>MOV DWORD PTR FS:[0],ESP
00404BC5 . 81EC 10010000 SUB ESP,110
00404BCB . 53 PUSH EBX
00404BCC . 55 PUSH EBP
00404BCD . 56 PUSH ESI
00404BCE . 8BF1 MOV ESI,ECX
00404BD0 . BD 01000000 MOV EBP,1
00404BD5 . 57 PUSH EDI
00404BD6 . 39AE DC050000 CMP DWORD PTR DS:[ESI+5DC],EBP
;EBP=1,:[ESI+5DC],保存是否开局的标志
00404BDC . 0F85 3D090000 JNZ llk4.0040551F
;开局向下执行,没有开局跳至返回
00404BE2 . 8B86 F8000000 MOV EAX,DWORD PTR DS:[ESI+F8]
;:[ESI+F8] 保存已经选中棋子的个数的标志
00404BE8 . BF 02000000 MOV EDI,2
00404BED . 3BC7 CMP EAX,EDI
00404BEF . 0F8D 2A090000 JGE llk4.0040551F
;;已经选中棋子的个数大于等于2跳至返回,哈哈,玩过的应该知道是游戏基本规则
00404BF5 . 8B8C24 380100>MOV ECX,DWORD PTR SS:[ESP+138]
;Y坐标
00404BFC . 8B8424 340100>MOV EAX,DWORD PTR SS:[ESP+134]
;X坐标
00404C03 . 8D5424 18 LEA EDX,DWORD PTR SS:[ESP+18]
00404C07 . 894C24 1C MOV DWORD PTR SS:[ESP+1C],ECX
00404C0B . 52 PUSH EDX
00404C0C . 8BCE MOV ECX,ESI
00404C0E . 894424 1C MOV DWORD PTR SS:[ESP+1C],EAX
;上面的操作取了一个8字节的空间,放入X坐标,Y坐标,空间的地址入栈作为参数
00404C12 . E8 39090000 CALL llk4.00405550
; 此函数根据坐标得到ID所在的棋盘的位置,位置返回上面的地址中
00404C17 . 8B4424 18 MOV EAX,DWORD PTR SS:[ESP+18]
; 列结构体编号,
00404C1B . 8B5424 1C MOV EDX,DWORD PTR SS:[ESP+1C]
; 列结构体内位置编号
00404C1F . 33DB XOR EBX,EBX
00404C21 . 8D0CC5 000000>LEA ECX,DWORD PTR DS:[EAX*8]
00404C28 . 2BC8 SUB ECX,EAX
00404C2A . 8D044A LEA EAX,DWORD PTR DS:[EDX+ECX*2]
; 计算得到EAX*4的值为ID的为相对于棋盘的偏移
00404C2D . 399C86 E00500>CMP DWORD PTR DS:[ESI+EAX*4+5E0],EBX
;:[ESI+5E0],为棋盘地址,+EAX*4 为选中棋子ID地址
00404C34 . 0F8E E5080000 JLE llk4.0040551F
; 检查ID是否为零,为零跳至返回
00404C3A . 83C9 FF OR ECX,FFFFFFFF
00404C3D . 898E C0000000 MOV DWORD PTR DS:[ESI+C0],ECX
00404C43 . 898E C4000000 MOV DWORD PTR DS:[ESI+C4],ECX
00404C49 . 898E C8000000 MOV DWORD PTR DS:[ESI+C8],ECX
00404C4F . 898E CC000000 MOV DWORD PTR DS:[ESI+CC],ECX
00404C55 . 8B8C86 0C0100>MOV ECX,DWORD PTR DS:[ESI+EAX*4+10C]
;这里说明一下,它有2个棋盘 ,一个ID棋盘,一个是是否被选中的标志的棋盘
; 在是否被选中这个棋盘中,选中为1,没选为0
00404C5C . 3BCB CMP ECX,EBX ;EBX=0
00404C5E . 0F85 5B080000 JNZ llk4.004054BF
;这个棋子如果已经被选中,跳转(我们知道有可能同一个棋子点2次),没选向下执行
00404C64 . 89AC86 0C0100>MOV DWORD PTR DS:[ESI+EAX*4+10C],EBP
; 是否选中的标志的棋盘中,此ID所在位置写1,标志选中
00404C6B . 8B96 F8000000 MOV EDX,DWORD PTR DS:[ESI+F8]
00404C71 . 8B4424 18 MOV EAX,DWORD PTR SS:[ESP+18]
; 列结构体编号,
00404C75 . 8984D6 FC0000>MOV DWORD PTR DS:[ESI+EDX*8+FC],EAX
00404C7C . 8B4C24 1C MOV ECX,DWORD PTR SS:[ESP+1C]
00404C80 . 898CD6 000100>MOV DWORD PTR DS:[ESI+EDX*8+100],ECX
; 列结构体内位置编号
00404C87 . 8B8E F8000000 MOV ECX,DWORD PTR DS:[ESI+F8]
00404C8D . 41 INC ECX
;已经选中的棋子的个数的标志加1
00404C8E . 8BC1 MOV EAX,ECX
00404C90 . 898E F8000000 MOV DWORD PTR DS:[ESI+F8],ECX
; 放回原位置
00404C96 . 3BC7 CMP EAX,EDI
; EDI=2 检查是否选中两个棋子
00404C98 . 0F8C C1070000 JL llk4.0040545F
; 如果选中2个棋子不跳转,下面会检查是否可消除
;我们现在只看选中1个的情况跳转到
0040545F > \399E F4000000 CMP DWORD PTR DS:[ESI+F4],EBX
; 检查声音开关
00405465 . 74 1C JE SHORT llk4.00405483
00405467 . E8 F70E0300 CALL llk4.00436363
0040546C . 8B40 04 MOV EAX,DWORD PTR DS:[EAX+4]
0040546F . 68 85000400 PUSH 40085
00405474 . 8B48 68 MOV ECX,DWORD PTR DS:[EAX+68]
00405477 . 51 PUSH ECX
00405478 . 68 8A000000 PUSH 8A
0040547D . FF15 1CB54300 CALL DWORD PTR DS:[<&WINMM.PlaySoundA>] ; WINMM.PlaySoundA
;;;;;;;;;;;;;;;;;;;;;
00405483 > 56 PUSH ESI ; 没开声音道这里执行
00405484 . 8D4C24 24 LEA ECX,DWORD PTR SS:[ESP+24]
00405488 . E8 13EC0200 CALL llk4.004340A0
; 得到一个hdc,放在esp+24里 ,说明要开始绘图了,哈哈
0040548D . 8B5424 1C MOV EDX,DWORD PTR SS:[ESP+1C]
; 列结构体编号
00405491 . 8B4424 18 MOV EAX,DWORD PTR SS:[ESP+18]
; 列 结构体内位置编号
00405495 . 52 PUSH EDX
00405496 . 8D4C24 24 LEA ECX,DWORD PTR SS:[ESP+24]
0040549A . 50 PUSH EAX
0040549B . 51 PUSH ECX
0040549C . 8BCE MOV ECX,ESI
0040549E . C78424 340100>MOV DWORD PTR SS:[ESP+134],0A
004054A9 . E8 122E0000 CALL llk4.004082C0
; 此 选中的棋子涂色,变灰,如图
004054AE . C78424 280100>MOV DWORD PTR SS:[ESP+128],-1
; [esp+128]=上面的[esp+134],意思暂时不明确
004054B9 . 8D4C24 20 LEA ECX,DWORD PTR SS:[ESP+20]
004054BD . EB 5B JMP SHORT llk4.0040551A ;跳转
。。。。。。。。。。。。。。。。。。。。。。。。
。。。。。。。。。。。。。。。。。。。。。。。。
。。。。。。。。。。。。。。。。。。。。。。。
0040551A > E8 F3EB0200 CALL llk4.00434112 ; 释放hdc
0040551F > 8BCE MOV ECX,ESI
00405521 . E8 B3910200 CALL llk4.0042E6D9 ; 变量的一些设置
00405526 . 8B8C24 200100>MOV ECX,DWORD PTR SS:[ESP+120]
0040552D . 5F POP EDI
0040552E . 5E POP ESI
0040552F . 5D POP EBP
00405530 . 64:890D 00000>MOV DWORD PTR FS:[0],ECX
00405537 . 5B POP EBX
00405538 . 81C4 1C010000 ADD ESP,11C
0040553E . C2 0C00 RETN 0C
选中一个棋子的过程就分析到这里,休息一下