kolibrios/programs/demos/eyes/trunk/eyes.asm

370 lines
5.3 KiB
NASM
Raw Permalink Normal View History

;
; EYES FOR MENUET
;
; Written by Nikita Lesnikov (nlo_one@mail.ru)
;
; Position of "eyes" is fixed. To close "eyes" just click on them.
;
TIMEOUT equ 3
; EXECUTABLE HEADER
use32
org 0x0
db "MENUET01"
dd 0x01
dd ENTRANCE
dd EYES_END
dd 0x3000
dd 0x3000
dd 0x0
dd 0x0
include '..\..\..\macros.inc'
ENTRANCE: ; start of code
; ==== main ====
call prepare_eyes
call shape_window
still:
call draw_eyes ; draw those funny "eyes"
mcall 23,TIMEOUT ; wait for event with timeout
cmp eax,1 ; redraw ?
jnz no_draw
call redraw_overlap
no_draw:
cmp eax,2 ; key ?
jz key
cmp eax,3 ; button ?
jz button
jmp still ; loop
; EVENTS
key:
mcall 2 ; just read and ignore
jmp still
button: ; analyze button
mcall -1 ; exit
jmp still
; -====- declarations -====-
imagedata equ EYES_END
skindata equ EYES_END+925
winref equ EYES_END+6325
; -====- shape -====-
shape_window:
mov eax,50 ; set up shape reference area
mov ebx,0
mov ecx,winref
mcall
ret
; -====- redrawing -====-
draw_eyes: ; check mousepos to disable blinking
mov eax,37
xor ebx,ebx
mcall
cmp dword [mouse],eax
jne redraw_ok
ret
redraw_ok:
mov [mouse],eax
redraw_overlap: ; label for redraw event (without checkmouse)
mcall 12,1
xor eax,eax ; define window
mov ebx,[win_ebx]
mov ecx,[win_ecx]
mov edx,0x11000000 ; do not draw window, just define its area
xor esi,esi
xor edi,edi
mcall
mcall 8,60,45,1+0x40000000 ; define closebutton
mov ebx,skindata
mcall 7,,60*65536+30,15
mov eax,15
mov ebx,30
call draw_eye_point
add eax,30
call draw_eye_point
mcall 12,2
ret
draw_eye_point: ; draw eye point (EAX=X, EBX=Y)
pusha
mov ecx, [mouse] ; ecx = mousex, edx = mousey
mov edx,ecx
shr ecx,16
and edx,0xFFFF
; ===> calculate position
push eax
push ebx
mov byte [sign1],0
mov esi, [win_ebx]
shr esi,16
add eax,esi
sub ecx,eax ; ECX=ECX-EAX (signed) , ECX=|ECX|
jnc abs_ok_1
neg ecx
mov byte [sign1],1
abs_ok_1:
mov [temp1],ecx
mov byte [sign2],0
mov esi,[win_ecx]
shr esi,16
add ebx,esi
sub edx,ebx ; EDX=EDX-EBX (signed) , EDX=|EDX|
jnc abs_ok_2
neg edx
mov byte [sign2],1
abs_ok_2:
mov [temp2],edx
pop ebx
pop eax
push eax ; ECX*=ECX
push edx
xor eax,eax
xor edx,edx
mov ax,cx
mul cx
shl edx,16
or eax,edx
mov ecx,eax
pop edx
pop eax
push eax ; EDX*=EDX
push ecx
mov ecx,edx
xor eax,eax
xor edx,edx
mov ax,cx
mul cx
shl edx,16
or eax,edx
mov edx,eax
pop ecx
pop eax
push ebx
push ecx
push edx
push eax
mov ebx,ecx ; EBX=ECX+EDX
add ebx,edx
xor edi,edi ; ESI=SQRT(EBX)
mov ecx,edi
mov edx,edi
inc edi
mov eax,edi
inc edi
sqrt_loop:
add ecx,eax
add eax,edi
inc edx
cmp ecx,ebx
jbe sqrt_loop
dec edx
mov esi,edx
mov ax,si ; ESI=ESI/7
mov dl,7
div dl
and ax,0xFF
mov si,ax ; ESI ? 0 : ESI=1
jnz nozeroflag1
mov si,1
nozeroflag1:
pop eax
pop edx
pop ecx
pop ebx
push eax ; ECX=[temp1]/ESI
push edx
mov eax,[temp1]
mov dx,si
div dl
mov cl,al
and ecx,0xFF
pop edx
pop eax
cmp byte [sign1],1
je subtract_1
add eax,ecx ; EAX=EAX+ECX
jmp calc_ok_1
subtract_1:
sub eax,ecx ; EAX=EAX-ECX
calc_ok_1:
push eax ; EDX=[temp2]/ESI
push ecx
mov eax,[temp2]
mov dx,si
div dl
mov dl,al
and dx,0xFF
pop ecx
pop eax
cmp byte [sign2],1
je subtract_2
add ebx,edx ; EBX=EBX+EDX
jmp calc_ok_2
subtract_2:
sub ebx,edx ; EBX=EBX-EDX
calc_ok_2:
; <===
mov ecx,ebx ; draw point
mov ebx,eax
mov eax,13
dec ecx
dec ecx
dec ebx
dec ebx
shl ecx,16
add ecx,4
shl ebx,16
add ebx,4
mov eax,13
xor edx,edx
mcall
popa
ret
; -====- working on images and window -====-
prepare_eyes:
;mov eax,6 ; load EYES.RAW
;mov ebx,graphix
;mov ecx,0x00000000
;mov edx,0xFFFFFFFF
;mov esi,imagedata
;mcall
;cmp eax,0xFFFFFFFF
;jnz filefound
;mov eax,-1 ; file not exists...
;mcall
;filefound:
mov esi,imagedata+25 ; transform grayscale to putimage format
mov edi,skindata
mov ecx,30
transform_loop:
push ecx
mov ecx,30
lp1:
lodsb
stosb
stosb
stosb
loop lp1
sub esi,30
mov ecx,30
lp2:
lodsb
stosb
stosb
stosb
loop lp2
pop ecx
loop transform_loop
mov eax,14 ; calculating screen position
mcall
shr eax,1
mov ax,59
sub eax,30*65536
mov [win_ebx],eax
mov [win_ecx],dword 10*65536+44
mov esi,imagedata+25 ; calculate shape reference area
mov edi,winref
mov ecx,900 ; disable drag bar
mov al,0
rep stosb
mov ecx,30 ; calculate circles for eyes
shape_loop:
push ecx
call copy_line ; duplicate (we have two eyes :)
sub esi,30
call copy_line
pop ecx
loop shape_loop
ret
copy_line: ; copy single line to shape reference area
mov ecx,30
cpl_loop:
lodsb
cmp al,0xFF
jnz set_one
mov al,0
jmp cpl_ok
set_one:
mov al,1
cpl_ok:
stosb
loop cpl_loop
ret
; DATA
; environment
win_ebx dd 0x0
win_ecx dd 0x0
mouse dd 0xFFFFFFFF
;graphix db "EYES.RAW "
; temporary storage for math routines
temp1 dd 0
temp2 dd 0
sign1 db 0
sign2 db 0
EYES_END: ; end of code
file "eyes.raw"