Files
kolibrios/programs/games/mblocks/mblocks.asm

585 lines
9.5 KiB
NASM
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
use32
db 'MENUET01'
dd 1
dd start
dd i_end
dd mem
dd mem
dd 0
dd 0
; field size in items
FieldWidth = 10
FieldHeight = 6
; size of one picture in pixels
ImageWidth = 32
ImageHeight = 32
; size of one button in pixels
ButtonWidth = ImageWidth + 6
ButtonHeight = ImageHeight + 6
SpaceWidth = ButtonWidth + 4
SpaceHeight = ButtonHeight + 4
; size of window in pixels
WindowWidth = 434
WindowHeight = 291 ; excluding skin height
if FieldWidth*FieldHeight mod 2
error field size must be an even number!
end if
draw_frame:
; in: ebx=[xstart]*65536+[xsize],ecx=[ystart]*65536+[ysize],edx=color
; ystart is relative to SkinHeight
; out: nothing
; destroys: eax,ecx
push 13
pop eax
ror ecx, 16
add ecx, [SkinHeight]
push ecx
shl ecx, 16
inc ecx
int 0x40 ; ebx=[xstart]*65536+[xsize], ecx=[ystart]*65536+1
ror ecx, 16
add cx, [esp+2]
ror ecx, 16
int 0x40 ; ebx=[xstart]*65536+[xsize], ecx=([ystart]+[ysize])*65536+1
pop ecx
ror ecx, 16
push ebx
mov bx, 1
int 0x40 ; ebx=[xstart]*65536+1, ecx=[ystart]*65536+[ysize]
ror ebx, 16
add bx, [esp]
ror ebx, 16
inc ecx
int 0x40 ; ebx=([xstart]+[xsize])*65536+1, ecx=[ystart]*65536+([ysize]+1)
dec ecx
pop ebx
ret
draw_button:
; in: ebx=[xstart]*65536+[xsize],ecx=[ystart]*65536+[ysize],edx=button color,esi=id
; ystart is relative to SkinHeight
; out: nothing
; destroys: eax
push edx
mov edx, 0x94AECE
call draw_frame
mov edx, 0xFFFFFF
push ebx
add ebx, 0xFFFF
push ecx
add ecx, 0x10000
mov cx, 1
int 0x40 ; ebx=([xstart]+1)*65536+([xsize]-1), ecx=([ystart]+1)*65536+1
pop ecx
mov edx, 0xC0C0C0
dec ebx
push ecx
shr ecx, 16
add ecx, [esp]
dec ecx
shl ecx, 16
inc ecx
int 0x40 ; ebx=([xstart]+1)*65536+([xsize]-2), ecx=([ystart]+[ysize]-1)*65536+1
pop ecx
mov edx, 0xFFFFFF
push ecx
add ecx, 0xFFFF
push ebx
mov bx, 1
int 0x40 ; ebx=([xstart]+1)*65536+1, ecx=([ystart]+1)*65536+([ysize]-1)
pop ebx
push ebx
shr ebx, 16
add ebx, [esp]
shl ebx, 16
inc ebx
mov edx, 0xC0C0C0
add ecx, 0xFFFF
int 0x40 ; ebx=([xstart]+[xsize]-1)*65536+1, ecx=([ystart]+2)*65536+([ysize]-2)
pop ebx
pop ecx
pop ebx
pop edx
push ebx ecx
add ebx, 20000h - 3
add ecx, 20000h - 3
int 0x40
pop ecx ebx
push edx
mov edx, esi
or edx, 0x80000000
mov al, 8
int 0x40
mov edx, esi
or edx, 0x40000000
int 0x40
pop edx
ret
;digits_ptr dd 0
;digits_str rb 11
;images:
; file 'mblocks.raw'
images:
file 'mblocksi.raw'
palette:
file 'mblocksp.raw'
aNewGame_ru db '<27>®¢ ï ¨£à (F2)',0
aCount_ru db ' ‘ç¥â:',0
aRu db 'RU',0
aNewGame_en db 'New game (F2)',0
aCount_en db 'Count:',0
aEn db 'EN',0
CurLanguage db 0 ; 0=russian, 1=english
field_status rb 60 ; status of field elements: 0=closed, 1=temporarily opened, 2=permanently opened
field_items rb 60 ; items in field
count dd 0
start:
push 26
pop eax
push 5
pop ebx
int 0x40
cmp eax, 4
setnz [CurLanguage]
call generate
; get skin height
push 48
pop eax
push 4
pop ebx
int 0x40
mov [SkinHeight], eax
; no previous click
mov eax, 0xBAD
mov [FirstClick], eax
mov [SecondClick], eax
; draw window
redraw:
call draw_window
; events loop
evloop:
push 10
pop eax
int 0x40
dec eax
jz redraw
dec eax
jz key
mov al, 17
int 0x40
shr eax, 8
; cmp eax, 6
; jz set_lang
cmp eax, 5
jz new_game
cmp eax, 1
jnz field_pressed
push -1
pop eax
int 0x40
key:
mov al, 2
int 0x40
cmp ah, '3' ; F2?
jnz evloop
new_game:
mov edi, field_status
mov ecx, FieldWidth*FieldHeight/2
xor eax, eax
rep stosd
mov [count], eax
mov eax, 0xBAD
mov [FirstClick], eax
mov [SecondClick], eax
call generate
call draw_field
@@:
call draw_aux
jmp evloop
;set_lang:
; xor [CurLanguage], 1
; jmp @b
field_pressed:
sub eax, 100
cmp [field_status+eax], 0
jnz cont
mov ebx, [FirstClick]
mov ecx, [SecondClick]
cmp ebx, 0xBAD
jz first_click
cmp ecx, 0xBAD
jz second_click
mov dl, [field_items+ecx]
cmp [field_items+ebx], dl
jnz dont_match
mov [field_status+ebx], 2
mov [field_status+ecx], 2
jmp @f
dont_match:
mov [field_status+ebx], 0
mov [field_status+ecx], 0
@@:
push eax ecx
mov eax, ebx
call draw_field_item
pop eax
call draw_field_item
mov [SecondClick], 0xBAD
pop eax
mov [FirstClick], eax
jmp @f
second_click:
cmp [FirstClick], eax
jz cont
mov [SecondClick], eax
@@:
mov [field_status+eax], 1
call draw_field_item
inc [count]
cont:
call draw_count
jmp evloop
first_click:
mov [FirstClick], eax
jmp @b
draw_window:
mov eax, 48
mov ebx, 3
mov ecx, color_table
mov edx, 40
int 0x40 ; get color table
mov eax, 12
mov ebx, 1
int 0x40 ; start redraw
xor eax, eax
mov ebx, 100*65536 + WindowWidth
mov ecx, 100*65536 + WindowHeight
add ecx, [SkinHeight]
mov edx, 0x14C0C0C0
mov edi, caption
int 0x40
call draw_aux
call draw_field
mov eax, 12
mov ebx, 2
int 0x40 ; end redraw
ret
caption db 'Memory Blocks L&V Edition',0
generate:
; generate random field
xor edi, edi
.loop:
call random
cmp [field_items+edx], 0
jnz .loop
mov eax, edi
shr eax, 1
inc eax
mov [field_items+edx], al
inc edi
cmp edi, FieldWidth*FieldHeight
jb .loop
ret
draw_field_item:
; in: eax=field item
; out: nothing
; destroys: eax,ebx,ecx,edx,esi
mov esi, eax
lea edx, [eax+0x80000000+100]
push 8
pop eax
int 0x40 ; delete old button
mov ebx, [xstart+esi*4]
shl ebx, 16
mov bl, ButtonWidth
mov ecx, [ystart+esi*4]
add ecx, [SkinHeight]
shl ecx, 16
mov cl, ButtonHeight
lea edx, [esi+0x40000000+100]
int 0x40 ; define new button
ror ecx, 16
sub ecx, [SkinHeight]
ror ecx, 16
mov al, [field_status+esi]
dec eax
js draw_closed_item
jz draw_current_item
draw_opened_item:
mov edx, 0x94AECE
call draw_frame
mov edx, 0xEFEBEF
add ebx, 0xFFFF
add ecx, 0xFFFF
mov al, 13
int 0x40
jmp draw_item_image
draw_current_item:
push ebx ecx
mov edx, 0x94AECE
call draw_frame
pop ecx ebx
add ebx, 10000h
add ecx, 10000h
push ebx ecx
mov bl, ButtonWidth-2
mov cl, ButtonHeight-2
mov edx, 0x94DB00
call draw_frame
pop ecx ebx
add ebx, 10000h
add ecx, 10000h
mov bl, ButtonWidth-4
mov cl, ButtonHeight-4
mov edx, 0x94DB00
call draw_frame
add ebx, 10000h
add ecx, 10000h
mov bl, ButtonWidth-5
mov cl, ButtonHeight-5
mov edx, 0xEFEBEF
int 0x40
draw_item_image:
; push 7
; pop eax
; movzx ebx, [field_items+esi]
; dec ebx
; imul ebx, ImageWidth*ImageHeight*3
; add ebx, images
; mov ecx, ImageWidth*10000h+ImageHeight
; mov edx, [xstart+esi*4]
; shl edx, 16
; add edx, [ystart+esi*4]
; add edx, 3*10001h
; add edx, [SkinHeight]
; int 0x40
push 65
pop eax
movzx ebx, [field_items+esi]
dec ebx
imul ebx, ImageWidth*ImageHeight
add ebx, images
mov ecx, ImageWidth*10000h+ImageHeight
mov edx, [xstart+esi*4]
shl edx, 16
add edx, [ystart+esi*4]
add edx, 3*10001h
add edx, [SkinHeight]
push 8
pop esi
mov edi, palette
xor ebp, ebp
int 0x40
ret
draw_closed_item:
mov edx, 0x94AECE
call draw_frame
push 38
pop eax
shr ebx, 16
inc ebx
imul ebx, 0x10001
push ebx
add ebx, ButtonWidth-2
shr ecx, 16
inc ecx
imul ecx, 0x10001
mov edx, 0xFFFFFF
int 0x40
pop ebx
push ecx
add ecx, ButtonHeight-3
int 0x40
pop ecx
push ebx ecx
add ebx, ButtonWidth-2
shr ecx, 16
add ecx, ButtonHeight-2
imul ecx, 0x10001
mov edx, 0xDEDEDE
int 0x40
pop ecx
push ecx
movzx ebx, bx
imul ebx, 0x10001
add ecx, 10000h+ButtonHeight-3
int 0x40
pop ecx ebx
add ebx, 10000h
mov bx, ButtonWidth-3
add ecx, 10000h
mov cx, ButtonHeight-3
mov al, 13
mov edx, 0xBDC7D6
int 0x40
ret
draw_field:
xor ebx, ebx
xor ecx, ecx
mov edi, xstart
.loop:
mov eax, ebx
imul eax, SpaceWidth
add eax, 9
stosd
mov eax, ecx
imul eax, SpaceHeight
add eax, 4
mov [edi+ystart-xstart-4], eax
lea eax, [edi-xstart-4]
shr eax, 2
push ebx ecx edi
call draw_field_item
pop edi ecx ebx
inc ecx
cmp ecx, FieldHeight
jb .loop
xor ecx, ecx
inc ebx
cmp ebx, FieldWidth
jb .loop
ret
draw_aux:
push 13
pop eax
mov ebx, 5*65536 + 425
mov ecx, [SkinHeight]
shl ecx, 16
add ecx, 256*65536 + 1
mov edx, 0xFFFFFF
int 0x40
add ecx, 1*65536 + 29
mov edx, [color_table+5*4]
int 0x40
push 8
pop eax
mov ebx, 14*65536 + 107
add ecx, 3*65536 - 7
push 5
pop edx
mov esi, [color_table+6*4]
int 0x40
push 4
pop eax
mov ebx, 27*65536 + 268
add ebx, [SkinHeight]
mov ecx, [color_table+7*4]
or ecx, 0x80000000
mov edx, aNewGame_ru
cmp [CurLanguage], 0
jz @f
mov edx, aNewGame_en
@@:
int 0x40
mov ebx, 155*65536 + 268
add ebx, [SkinHeight]
mov ecx, [color_table+8*4]
or ecx, 0x80000000
mov edx, aCount_ru
cmp [CurLanguage], 0
jz @f
mov edx, aCount_en
@@:
int 0x40
call draw_count
mov al, 13
mov ecx, [SkinHeight]
shl ecx, 16
mov ebx, 405*65536 + 2
add ecx, 265*65536 + 2
mov edx, 0xBDCBDE
int 0x40
mov ebx, 403*65536 + 6
add ecx, (270*65536 + 6) - (265*65536 + 2)
int 0x40
mov ebx, 411*65536 + 6
add ecx, (275*65536 + 6) - (270*65536 + 6)
int 0x40
mov ebx, 412*65536 + 9
add ecx, (262*65536 + 8) - (275*65536 + 6)
mov edx, 0xD6D7CE
int 0x40
ret
draw_count:
mov edi, string_for_number+15
mov eax, [count]
push 10
pop ecx
@@:
xor edx, edx
div ecx
dec edi
add dl, '0'
mov [edi], dl
test eax, eax
jnz @b
mov al, 4
mov ebx, [SkinHeight]
add ebx, 195*65536 + 268
mov ecx, [color_table+8*4]
or ecx, 0xC0000000
mov edx, edi
mov edi, [color_table+5*4]
int 0x40
ret
random:
; in: nothing
; out: edx = random value in [0..FieldWidth*FieldHeight-1]
; destroys: eax,ecx,edx
rdtsc
xor edx, eax
not edx
mov eax, [RandSeed]
ror eax, 3
xor eax, 0DEADBEEFh
add eax, edx
mov [RandSeed], eax
add eax, edx
xor edx, edx
push FieldWidth*FieldHeight
pop ecx
div ecx
ret
i_end:
SkinHeight dd ?
color_table rd 10
RandSeed dd ?
FirstClick dd ?
SecondClick dd ?
string_for_number rb 16
xstart rd 60
ystart rd 60
align 1000h
stk rb 1000h
mem: