📄 cmd_tetris.cpp
字号:
inc block.id
test byte ptr [block.id], 3
jnz _F01
sub block.id, 4
_F01:
imul eax, block.id, 2*4*4+2
add eax, offset blocks+2*4*4
movzx eax,word ptr [eax]
mov [block.lines],eax
call DrawBlock
jc _F02
add esp, 8
retn
_F02:
pop block.lines
pop block.id
call DrawBlock
retn
}
}
void __declspec(naked) TetrisCompactLines()
{
__asm
{
push ebx
push ecx
push edx
push esi
push edi
mov ebx,WIDTH
call GetScreenPtr
mov esi,eax
mov eax,block.y
imul eax,ebx
add eax,board.x
lea esi,[2*eax+esi] ; esi: left border of blockwindow
mov ecx,block.lines
_loop_outer:
push ecx
mov edx,esi
mov ecx,board.width
_loop_inner:
lodsw
test ax,0x0F00
loopnz _loop_inner
mov esi,edx
jz _next_line
; compact a line
inc stats.lines
mov eax, stats.blocks
add stats.score,eax
test delay,111b ; gets faster after 8 completed lines
jnz _F01
cmp delay, 1 ; no that if anyone ever got this far...
jbe _F01
dec delay
_F01:
mov ecx,block.y
sub ecx,board.y
inc ecx
_loop_moveline:
push ecx
; move down upper neighbour
mov edi,esi
sub esi,ebx
sub esi,ebx
push esi
mov ecx,board.width
rep movsw
pop esi
pop ecx
loop _loop_moveline
mov esi,edx
_next_line:
lea esi,[2*ebx+esi]
pop ecx
loop _loop_outer
call si_UpdateScreen
pop edi
pop esi
pop edx
pop ecx
pop ebx
retn
}
}
void __declspec(naked) TetrisEraseBlock()
{
__asm
{
push ebx
push ecx
push edx
push esi
push edi
mov ebx, WIDTH
call GetScreenPtr
mov edi, eax
mov eax, block.y
imul eax, ebx
add eax, block.x
lea edi, [2*eax+edi] ; edi: upper left corner of block window
imul esi, block.id, 2*4*4+2
add esi, offset blocks ; esi: upper left corner of blockdata
mov edx, 0x20
mov ecx, block.lines
_loop_draw:
lodsw
test ax, ax
jz _F01
mov [edi], dx
_F01:
lodsw
test ax, ax
jz _F02
mov [edi+2], dx
_F02:
lodsw
test ax, ax
jz _F03
mov [edi+4], dx
_F03:
lodsw
test ax, ax
jz _F04
mov [edi+6], dx
_F04:
lea edi, [edi+2*ebx]
loop _loop_draw
call si_UpdateScreen
pop edi
pop esi
pop edx
pop ecx
pop ebx
retn
}
}
//////////////////////////////////////////////////////////////////////////////
//
// Tick
//
//////////////////////////////////////////////////////////////////////////////
void __declspec(naked) Tick ()
{
__asm
{
mov eax,1
call si_DelayMilliSec
inc ticks
retn
}
}
//////////////////////////////////////////////////////////////////////////////
// DrawHLine
// dl: left.x
// dh: left.y
// bl: char
// bh: color
// ecx: length
//////////////////////////////////////////////////////////////////////////////
void __declspec(naked) DrawHLine()
{
__asm
{
call si_PrintChar
retn
}
}
//////////////////////////////////////////////////////////////////////////////
// DrawVLine
// dl: top.x
// dh: top.y
// bl: char
// bh: color
// ecx: length
//////////////////////////////////////////////////////////////////////////////
void __declspec(naked) DrawVLine()
{
__asm
{
drawVloop:
push ecx
mov ecx,1
call si_PrintChar
inc dh
pop ecx
loop drawVloop
retn
}
}
//////////////////////////////////////////////////////////////////////////////
// Draw board
//////////////////////////////////////////////////////////////////////////////
void __declspec(naked) DrawBoard()
{
__asm
{
mov dl,byte ptr [board.x]
dec dl
mov dh,byte ptr [board.y]
add dh,byte ptr [board.lines]
movzx ecx,board.width
add ecx,2
mov ebx,0x7F20
call DrawHLine
mov dl,byte ptr [board.x]
dec dl
mov dh,byte ptr [board.y]
mov ecx,board.lines
inc ecx
mov ebx,0x7F20
call DrawVLine
mov dl, byte ptr [board.x]
add dl, byte ptr [board.width]
mov dh, byte ptr [board.y]
mov ecx, board.lines
inc ecx
mov ebx, 0x7F20
call DrawVLine
retn
}
}
//////////////////////////////////////////////////////////////////////////////
// GetRandomBlockID
//////////////////////////////////////////////////////////////////////////////
int __declspec(naked) GetRandomBlockID ()
{
__asm
{
push edx
rdtsc // MUST be supported by CPU
// TO DO: test for rdtsc support
xor edx,edx
idiv NumOfBlocks
lea eax,[4*edx]
pop edx
retn
}
/*
__asm
{
push edx
xor edx,edx
mov eax,seed
idiv q
imul eax,r
imul edx,a
sub edx,eax
lea eax,[edx+0x7FFFFFFF]
test edx,edx
jle _F01
mov eax,edx
_F01:
mov seed,eax
xor edx,edx
idiv NumOfBlocks
lea eax,[4*edx]
pop edx
retn
}
*/
}
//////////////////////////////////////////////////////////////////////////////
// Draw block
// stc if block cannot be drawn
//////////////////////////////////////////////////////////////////////////////
void __declspec(naked) DrawBlock()
{
__asm
{
push ebx
push ecx
push edx
push esi
push edi
mov ebx, WIDTH
call GetScreenPtr
mov edi,eax
mov eax,block.y
imul eax,ebx
add eax,block.x
lea edi,[2*eax+edi] ; edi: upper left corner of blockwindow
imul esi,[block.id], 2*4*4 + 2
add esi,offset blocks ; esi: upper left corner of blockdata
mov edx,esi
mov ecx,[block.lines]
loop_check:
lodsd
and eax,[edi]
and eax,0x0F000F00
jz _F01
stc
jmp _ret
_F01:
lodsd
and eax,[edi+4]
and eax,0x0F000F00
jz _F02
stc
jmp short _ret
_F02:
lea edi,[edi+2*ebx]
loop loop_check
; now let's draw it
imul eax,[block.lines],2
imul eax,ebx
sub edi,eax ; edi: upper left corner of blocwindow
mov esi,edx ; esi: upper left corner of blockdata
mov ecx,[block.lines]
_loop_draw:
lodsw
test ax,ax
jz _F03
mov [edi],ax
_F03:
lodsw
test ax,ax
jz _F04
mov [edi+2],ax
_F04:
lodsw
test ax,ax
jz _F05
mov [edi+4],ax
_F05:
lodsw
test ax,ax
jz _F06
mov [edi+6],ax
_F06:
lea edi,[edi+2*ebx]
loop _loop_draw
call si_UpdateScreen
clc
_ret:
pop edi
pop esi
pop edx
pop ecx
pop ebx
retn
}
}
//////////////////////////////////////////////////////////////////////////////
// Draw new block
// stc if board is full
//////////////////////////////////////////////////////////////////////////////
void __declspec(naked) DrawNewBlock()
{
__asm
{
mov eax,board.width
sub eax,2
shr eax,1
add eax,board.x
mov block.x,eax
mov eax,board.y
mov block.y,eax
call GetRandomBlockID
mov [block.id],eax
imul eax, 4*4*2+2
add eax, offset blocks + 2*4*4
movzx eax, word ptr [eax]
mov block.lines,eax
call DrawBlock
jc full
inc stats.blocks
full:
retn
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -