i wrote a function to draw a gradient color rectangle (vertical gradient);but i think it should be optimized:
can someone help me with this?
Code: Select all
;void VerticalGradient(x1,y1,x2,y2,c1,c2)
.VerticalGradient:
push ebp
mov ebp,esp
pusha
;; save the values
mov eax,[ebp+8] ;end color
mov [.tmp_bcolor],eax
mov eax,[ebp+12] ; start color
mov [.tmp_color],eax
mov eax,[ebp+16] ;y2
mov [.tmp_y2],eax
mov eax,[ebp+20] ;x2
mov [.tmp_x2],eax
mov eax,[ebp+24] ;y1
mov [.tmp_y1],eax
mov eax,[ebp+28] ;x1
mov [.tmp_x1],eax
;compute the y difference
mov eax,[.tmp_y2]
cmp eax,[.tmp_y1]
ja @f
mov ebx,[.tmp_y1]
mov [.tmp_y1],eax
mov [.tmp_y2],ebx
@@:
mov eax,[.tmp_y2]
sub eax,[.tmp_y1]
mov [.diff_y],eax
;begin of loop (for tmp_y = tmp_y1;tmp_y< tmp_y2;tmp_y++)
mov edx,[.tmp_y1]
.forY1:
cmp edx,[.tmp_y2]
jnb .nextY1
mov [.tmp_y],edx
;new value for red
mov ebx,[.tmp_color]
shr ebx,16
mov ecx,[.tmp_bcolor]
shr ecx,16
cmp ebx,ecx
jnb @f
sub ecx,ebx ; ;red should be incremented
mov [.red_inc],0x1
jmp .endred1
@@:
sub ebx,ecx ;red will be decremented
mov [.red_inc],0x0
mov ecx,ebx
.endred1:
;new red_step= (tmp_y-tmp_y1) * ( (red2 - red1)/diff_y )
mov eax,ecx
cmp [.diff_y],0x0
jna @f
push edx
xor edx,edx
mov ebx,[.diff_y]
div ebx
pop edx
push edx
sub edx,[.tmp_y1]
imul eax,edx
pop edx
@@:
shl eax,16
and eax,0xff0000
mov [.red_step],eax
;same for green
mov ebx,[.tmp_color]
shr ebx,8
and ebx,0xff
mov ecx,[.tmp_bcolor]
shr ecx,8
and ecx,0xff
cmp ebx,ecx
jnb @f
sub ecx,ebx ;ecx contains red
mov [.green_inc],0x1
jmp .endgreen1
@@:
sub ebx,ecx
mov [.green_inc],0x0
mov ecx,ebx
.endgreen1:
mov eax,ecx
cmp [.diff_y],0x0
jna @f
push edx
xor edx,edx
mov ebx,[.diff_y]
div ebx
pop edx
push edx
sub edx,[.tmp_y1]
imul eax,edx
pop edx
@@:
shl eax,8
and eax,0x00ff00
mov [.green_step],eax
;same for blue
mov ebx,[.tmp_color]
and ebx,0xff
mov ecx,[.tmp_bcolor]
and ecx,0xff
cmp ebx,ecx
jnb @f
sub ecx,ebx ;ecx contains red
mov [.blue_inc],0x1
jmp .endblue1
@@:
sub ebx,ecx
mov [.blue_inc],0x0
mov ecx,ebx
.endblue1:
mov eax,ecx
cmp [.diff_y],0x0
jna @f
push edx
xor edx,edx
mov ebx,[.diff_y]
div ebx
pop edx
push edx
sub edx,[.tmp_y1]
imul eax,edx
pop edx
@@:
and eax,0x0000ff
mov [.blue_step],eax
;new color.red = tmp_color.red+red_step or tmp_color.red-red.step (in case of red_inc=0)
mov eax,[.tmp_color]
and eax,0xff0000
cmp [.red_inc],0x1
jne @f
add eax,[.red_step]
jmp .suite_red1
@@:
sub eax,[.red_step]
.suite_red1:
and eax,0xff0000
mov [.red_step],eax
;same for green
mov eax,[.tmp_color]
and eax,0x00ff00
cmp [.green_inc],0x1
jne @f
add eax,[.green_step]
jmp .suite_green1
@@:
sub eax,[.green_step]
.suite_green1:
and eax,0x00ff00
mov [.green_step],eax
;same for blue
mov eax,[.tmp_color]
and eax,0x0000ff
cmp [.blue_inc],0x1
jne @f
add eax,[.blue_step]
jmp .suite_blue1
@@:
sub eax,[.blue_step]
.suite_blue1:
and eax,0x0000ff
mov [.blue_step],eax
;combine colors
mov eax,[.red_step]
mov ebx,[.green_step]
mov ecx,[.blue_step]
or eax,ebx
or eax,ecx
DrawLine [.tmp_x1],[.tmp_y],[.tmp_x2],[.tmp_y],eax
;next line
mov edx,[.tmp_y]
inc edx
jmp .forY1
.nextY1:
popa
mov esp,ebp
pop ebp
ret 24 ;return and remove the stack parameters