forked from KolibriOS/kolibrios
ec76c66cd2
Graphics: fixed error when putimage and drawrect do not draw pixels on right and bottom window sides Processes: fixed kernel fault when program to load is too big Programs: EYES: now it works with new kernel (rev. 130). Size optimization. Blinking deleted. git-svn-id: svn://kolibrios.org@133 a494cfbc-eb01-0410-851d-a64ba20cac60
307 lines
4.8 KiB
NASM
307 lines
4.8 KiB
NASM
;
|
|
; EYES FOR MENUET
|
|
;
|
|
; Written by Nikita Lesnikov (nlo_one@mail.ru)
|
|
;
|
|
; Position of "eyes" is fixed. To close "eyes" just click on them.
|
|
;
|
|
; NOTE: quite big timeout is used to disable blinking when redrawing.
|
|
; If "eyes" blink on your system, enlarge the TIMEOUT. If not, you can
|
|
; decrease it due to more realistic movement.
|
|
;
|
|
|
|
TIMEOUT equ 5
|
|
|
|
; EXECUTABLE HEADER
|
|
|
|
use32
|
|
|
|
org 0x0
|
|
db "MENUET01"
|
|
dd 0x01
|
|
dd ENTRANCE
|
|
dd I_END
|
|
dd 0x3000
|
|
dd 0x3000
|
|
dd 0x0
|
|
dd 0x0
|
|
|
|
include 'macros.inc'
|
|
ENTRANCE: ; start of code
|
|
|
|
; ==== main ====
|
|
prepare_eyes:
|
|
|
|
mov esi,imagedata ; 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
|
|
int 0x40
|
|
shr eax,1
|
|
mov ax,59
|
|
sub eax,30*65536
|
|
mov [win_ebx],eax
|
|
mov [win_ecx],dword 10*65536+44
|
|
|
|
mov esi,imagedata ; 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
|
|
|
|
; -====- shape -====-
|
|
|
|
shape_window:
|
|
|
|
mov eax,50 ; set up shape reference area
|
|
xor ebx,ebx
|
|
mov ecx,winref
|
|
int 0x40
|
|
|
|
call draw_window
|
|
|
|
still:
|
|
|
|
call draw_eyes ; draw those funny "eyes"
|
|
|
|
_wait:
|
|
mov eax,23 ; wait for event with timeout
|
|
mov ebx,TIMEOUT
|
|
int 0x40
|
|
dec eax
|
|
jz redraw
|
|
dec eax
|
|
jz key
|
|
dec eax
|
|
jnz still
|
|
button:
|
|
or eax, -1
|
|
int 0x40
|
|
key:
|
|
mov al, 2
|
|
int 0x40
|
|
jmp still
|
|
redraw:
|
|
call draw_window
|
|
call redraw_eyes
|
|
jmp _wait
|
|
|
|
; -====- redrawing -====-
|
|
|
|
draw_eyes: ; check mousepos to disable blinking
|
|
|
|
mov eax,37
|
|
xor ebx,ebx
|
|
int 0x40
|
|
cmp dword [mouse],eax
|
|
jne redraw_ok
|
|
ret
|
|
redraw_ok:
|
|
mov [mouse],eax
|
|
|
|
redraw_eyes:
|
|
mov eax,7
|
|
mov ebx,skindata
|
|
mov ecx,60*65536+30
|
|
mov edx,15
|
|
int 0x40
|
|
|
|
mov eax,15
|
|
mov ebx,30
|
|
call draw_eye_point
|
|
add eax,30
|
|
call draw_eye_point
|
|
ret
|
|
|
|
draw_window:
|
|
|
|
mov eax,12
|
|
mov ebx,1
|
|
int 0x40
|
|
|
|
xor eax,eax ; define window
|
|
mov ebx,[win_ebx]
|
|
mov ecx,[win_ecx]
|
|
xor edx,edx
|
|
xor esi,esi
|
|
xor edi,edi
|
|
int 0x40
|
|
|
|
mov eax,8 ; define closebutton
|
|
mov ebx,60
|
|
mov ecx,45
|
|
mov edx,1
|
|
int 0x40
|
|
|
|
mov eax,12
|
|
mov ebx,2
|
|
int 0x40
|
|
|
|
ret
|
|
|
|
draw_eye_point: ; draw eye point (EAX=X, EBX=Y)
|
|
pusha
|
|
|
|
movzx ecx, word [mouse+2] ; ecx = mousex, esi = mousey
|
|
movzx esi, word [mouse]
|
|
|
|
; ===> calculate position
|
|
|
|
push eax
|
|
push ebx
|
|
mov byte [sign1],0
|
|
mov edx, [win_ebx]
|
|
shr edx,16
|
|
add eax,edx
|
|
sub ecx,eax ; ECX=ECX-EAX (signed) , ECX=|ECX|
|
|
jnc abs_ok_1
|
|
neg ecx
|
|
mov byte [sign1],1
|
|
abs_ok_1:
|
|
push ecx ; save x distance
|
|
mov byte [sign2],0
|
|
mov edx,[win_ecx]
|
|
shr edx,16
|
|
add ebx,edx
|
|
sub esi,ebx ; EDX=EDX-EBX (signed) , EDX=|EDX|
|
|
jnc abs_ok_2
|
|
neg esi
|
|
mov byte [sign2],1
|
|
abs_ok_2:
|
|
mov [temp2],esi
|
|
|
|
; ESI = ECX*ECX+ESI*ESI
|
|
imul ecx, ecx
|
|
imul esi, esi
|
|
add esi, ecx
|
|
|
|
xor ecx,ecx ; EDX=SQRT(EBX)
|
|
xor edx,edx
|
|
mov eax,1
|
|
sqrt_loop:
|
|
; in this moment ecx=edx*edx, eax=1+2*edx
|
|
add ecx,eax
|
|
inc eax
|
|
inc eax
|
|
inc edx
|
|
cmp ecx,esi
|
|
jbe sqrt_loop
|
|
dec edx
|
|
mov eax,edx ; EDX=EDX/7
|
|
mov dl,7
|
|
div dl
|
|
and eax,0xFF
|
|
mov edx,eax ; EDX ? 0 : EDX=1
|
|
jnz nozeroflag1
|
|
inc edx
|
|
nozeroflag1:
|
|
|
|
pop eax ; EAX = x distance
|
|
; ECX=EAX/EDX
|
|
div dl
|
|
movzx ecx,al
|
|
pop ebx
|
|
pop eax
|
|
|
|
cmp byte [sign1], 0
|
|
jz @f
|
|
neg ecx
|
|
@@:
|
|
add eax, ecx
|
|
|
|
push eax ; ESI=[temp2]/EDX
|
|
mov eax,[temp2]
|
|
div dl
|
|
movzx esi,al
|
|
pop eax
|
|
|
|
cmp byte [sign2], 0
|
|
jz @f
|
|
neg esi
|
|
@@:
|
|
add ebx, esi
|
|
|
|
; <===
|
|
|
|
; draw point
|
|
lea ecx, [ebx-2]
|
|
lea ebx, [eax-2]
|
|
shl ecx,16
|
|
add ecx,4
|
|
shl ebx,16
|
|
add ebx,4
|
|
mov eax,13
|
|
xor edx,edx
|
|
int 0x40
|
|
|
|
popa
|
|
ret
|
|
|
|
; -====- working on images and window -====-
|
|
|
|
copy_line: ; copy single line to shape reference area
|
|
mov ecx,30
|
|
cpl_loop:
|
|
lodsb
|
|
; input is image: 0xFF = white pixel, 0 = black pixel
|
|
; output is membership boolean: 0 = pixel no, 1 = pixel ok
|
|
inc eax
|
|
stosb
|
|
loop cpl_loop
|
|
ret
|
|
|
|
; DATA
|
|
|
|
; environment
|
|
|
|
win_ebx dd 0x0
|
|
win_ecx dd 0x0
|
|
mouse dd 0xFFFFFFFF
|
|
|
|
EYES_END: ; end of code
|
|
imagedata:
|
|
; texture is 900 bytes starting from 25th
|
|
file "eyes.raw":25,900
|
|
I_END:
|
|
|
|
; temporary storage for math routines
|
|
|
|
sign1 db ?
|
|
sign2 db ?
|
|
align 4
|
|
temp2 dd ?
|
|
|
|
skindata rb 60*30*3
|
|
winref rb 45*60
|