kolibrios/programs/develop/libraries/vector/trunk/vectors.asm

1252 lines
27 KiB
NASM
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

format MS COFF
public EXPORTS
section '.flat' code readable align 16
include 'vectors.inc' ;vectors functions constant
macro swap v1, v2 {
push v1
push v2
pop v1
pop v2
}
BUF_STRUCT_SIZE equ 17 ;размер структуры, описывающей буфер
BUF_MAX_COUNT equ 8 ;максимальное число буферов
fun_draw_pixel dd drawpixel_scrn ;указатель на функцию рисования точки
active_buffer: ;начало структуры активного буфера (буфера в который делается рисование фигур или текста)
dd 0 ;указатель на буфер изображения
dw 0 ; +4 left
dw 0 ; +6 top
dw 0 ; +8 w ширина буфера
dw 0 ;+10 h высота буфера
dd 0 ;+12 color цвет фона
db 24 ;+16 bit in pixel глубина цвета (в данной версии еще не используется)
rb BUF_STRUCT_SIZE * BUF_MAX_COUNT ;резервируем место для структур, описывающих буфера
;в активном буфере будет содержаться точная копия одной из этих структур
active_buffer_left equ active_buffer+ 4
active_buffer_top equ active_buffer+ 6
active_buffer_w equ active_buffer+ 8
active_buffer_h equ active_buffer+10
active_buffer_color equ active_buffer+12
;-----------------------------------------------------------------------------
;функция для выделения памяти
;input:
; ecx = size data
;otput:
; eax = pointer to memory
mem_Alloc:
push ebx
mov eax,68
mov ebx,12
int 0x40
pop ebx
ret
;-----------------------------------------------------------------------------
;функция для освобождения памяти
;input:
; ecx = pointer to memory
mem_Free:
push eax ebx
cmp ecx,0
jz @f
mov eax,68
mov ebx,13
int 0x40
@@:
pop ebx eax
ret
;функция рисующая точку сразу на экран (без участия буфера)
align 4
drawpixel_scrn:
bt bx,15
jc @f
bt cx,15
jc @f
; cmp bx,300
; jge @f
; cmp cx,300
; jge @f
int 0x40
@@:
ret
;функция рисующая точку в активном буфере
align 4
drawpixel_buf:
bt bx,15 ;проверяем знак числа, если координата меньше 0
jc @f ;тогда точка в экран не попала, конец функции
bt cx,15
jc @f
cmp bx,word[active_buffer_w] ;проверяем координату точки, если больше ширины буфера
jge @f ;тогда точка в экран не попала, конец функции
cmp cx,word[active_buffer_h]
jge @f
push esi
xor esi,esi ;тут будет указатель на пиксель из активного буфера
mov si,word[active_buffer_w] ;ширина буфера по оси x
imul esi,ecx ;size_x*y
add esi,ebx ;size_x*y+x
lea esi,[esi+esi*2] ;(size_x*y+x)*3
add esi,dword[active_buffer] ;ptr+(size_x*y+x)*3
mov word[esi],dx ;копируем зеленый и синий спектр
ror edx,16 ;крутим цвет на 2 байта
mov byte[esi+2],dl ;копируем красный спектр
ror edx,16 ;крутим цвет назад
pop esi
@@:
ret
;функция создающая новый буфер, принимает параметры нужные для структуры
;input:
; [esp+8] = bit on pixel, index created buffer
; [esp+10] = color
; [esp+14] = size: w,h
; [esp+18] = size: l,t
align 4
buf_create:
push ebp
mov ebp,esp
cmp byte[ebp+8],1 ;проверка правильности индекса создаваемого буфера
jl .error_ind ;пользователь указал индекс меньше 1-цы, ... error :(
cmp byte[ebp+8],BUF_MAX_COUNT ;проверка правильности индекса создаваемого буфера
jg .error_ind ;пользователь указал индекс больше максимально возможного, ... error :(
push eax ecx edi esi
mov eax,dword[ebp+14] ;берем ширину и высоту буфера
ror eax,16 ;меняем местами ширину и высоту, так будет удобнее при выводе для функции 7
mov dword[active_buffer_w],eax ;помещаем значения в структуру активного буфера
xor ecx,ecx ;тут вычисляем сколько памяти нужно для этого буфера
mov cx,ax ;берем нижний размер буфера
shr eax,16 ;затираем нижний размер, в eax теперь только верхний размер, на месте нижнего
imul ecx,eax ;умножаем высоту на ширину (может и наоборот ширину на высоту)
imul ecx,3 ; 24 bit = 3, 32 bit = 4 ... work if only 24
call mem_Alloc ;просим память из системы
mov dword[active_buffer],eax ;копируем указатель на полученую память в структуру активного буфера
mov eax,dword[ebp+18] ;берем отступы слева и справа
ror eax,16
mov dword[active_buffer_left],eax
mov eax,dword[ebp+10] ;get color - берем цвет для фона
mov dword[active_buffer_color],eax
;копируем всю структуру активного буфера, в память отведенную для буферов
;иначе если появится новый буфер, то он затрет собой активную структуру
;потому нужно дублировать эту информацию
mov di,word[ebp+8] ;copy buffer struct
and edi,0xff ;index <= 255
mov ecx,BUF_STRUCT_SIZE ;в ecx размер копируемых данных
imul edi,ecx
mov esi,active_buffer
add edi,esi
rep movsb ;повторяем копирование по байту, пока ecx станет не равно 0
push word[ebp+8] ;при создании буфера, в нем может быть мусор,
call buf_clear ;потому чистим его фоновым цветом
pop esi edi ecx eax
.error_ind:
pop ebp
ret 14
;функция установки активного буфера, если на входе 0 - то включается режим рисования на экран без буфера
;input:
; [esp+8] = index buffer (0-screen)
align 4
set_active_buf:
push ebp
mov ebp,esp
cmp word[ebp+8],0
jne @f
.to_scrn:
mov dword[fun_draw_pixel],drawpixel_scrn ;рисование в экран
jmp .end_fun
@@:
cmp byte[ebp+8],BUF_MAX_COUNT ;if buffer index out of range
jg .to_scrn
mov dword[fun_draw_pixel],drawpixel_buf ;рисование в буфер
push ecx esi edi
mov si,word[ebp+8] ;copy buffer struct
and esi,0xff ;index <= 255
mov ecx,BUF_STRUCT_SIZE
imul esi,ecx
mov edi,active_buffer
add esi,edi
rep movsb
pop edi esi ecx
cmp dword[active_buffer],0 ;if buffer is empty
je .to_scrn
.end_fun:
pop ebp
ret 2
;функция очистки буфера фоновым цветом
;input:
; [esp+8] = index buffer (0-screen)
align 4
buf_clear:
push ebp
mov ebp,esp
push eax ebx ecx edi
mov di,word[ebp+8] ;get pointer to buffer struct
and edi,0xff ;index <= 255
imul edi,BUF_STRUCT_SIZE
add edi,active_buffer ;edi = pointer to buffer struct
cmp dword[edi],0 ;проверяем пустой указатель на буфер или нет
je .no_draw ;если пустой, то выход
xor ecx,ecx ;тут будет размер буфера в пикселях
mov cx,word[edi+8] ;active_buffer_w]
xor eax,eax
mov ax,word[edi+10] ;active_buffer_h]
imul ecx,eax ;ecx=x*y
mov ebx,dword[edi+12] ;active_buffer_color]
mov ax,bx
shr ebx,16
;imul ecx,3
;rep stosb
push dword[edi] ;save value in pointer
pop edi ;get value in pointer
@@:
mov word[edi],ax
add edi,2
mov byte[edi],bl
inc edi
loop @b
.no_draw:
pop edi ecx ebx eax
pop ebp
ret 2
;функция рисующая содержимое буфера на экране, использует КОС функцию номер 7
;input:
; [esp+8] = index buffer (0-screen)
align 4
draw_buf:
push ebp
mov ebp,esp
mov di,word[ebp+8] ;get pointer to buffer struct
and edi,0xff ;index <= 255
imul edi,BUF_STRUCT_SIZE
add edi,active_buffer ;edi = pointer to buffer struct
mov eax,7
mov ebx,dword[edi] ;active_buffer]
mov ecx,dword[edi+8] ;active_buffer_w] ;ecx = w*0xffff+h
ror ecx,16
;push word[edi+4] ;active_buffer_left] ;загрузка точки левого верхнего угла
;pop dx
mov dx,word[edi+4]
shl edx,16
;push word[edi+6] ;active_buffer_top] ;загрузка точки левого верхнего угла
;pop dx
mov dx,word[edi+6]
int 0x40
pop ebp
ret 2
;функция очищающая память, занимаемую буфером
;input:
; [esp+8] = index buffer (0-screen)
align 4
buf_delete:
push ebp
mov ebp,esp
mov cx,word[ebp+8] ;get pointer to buffer struct
and ecx,0xff ;index <= 255
imul ecx,BUF_STRUCT_SIZE
add ecx,active_buffer ;edi = pointer to buffer struct
push dword[ecx] ;save value in pointer
pop ecx ;get value in pointer
call mem_Free
pop ebp
ret 2
;функция рисующая линию
;input:
; [esp+8] = p0
; [esp+12] = p1
; [esp+16] = color
loc_0 equ byte[ebp-4]
loc_1 equ word[ebp-6]
loc_2 equ word[ebp-8]
align 4
line_brs:
push ebp
mov ebp,esp
sub esp,6 ;=1+2*2
pushad ;eax ebx ecx edx si di
mov edx,dword[ebp+16]
;---
mov ax,word[ebp+14] ;y1
; cmp ax,0 ;if y1<0 return
; jl .coord_end
; cmp word[ebp+10],0 ;if y0<0 return
; jl .coord_end
sub ax,word[ebp+10] ;y1-y0
bt ax,15
jae @f
neg ax
inc ax
@@:
mov bx,word[ebp+12] ;x1
; cmp bx,0 ;if x1<0 return
; jl .coord_end
; cmp word[ebp+8],0 ;if x0<0 return
; jl .coord_end
sub bx,word[ebp+8] ;x1-x0
bt bx,15
jae @f
neg bx
inc bx
@@:
mov byte[ebp-4],byte 0 ;bool steep=false
cmp ax,bx
jle @f
mov byte[ebp-4],byte 1 ;bool steep=true
swap word[ebp+8],word[ebp+10] ;swap(x0, y0);
swap word[ebp+12],word[ebp+14] ;swap(x1, y1);
@@:
mov ax,word[ebp+8] ;x0
cmp ax,word[ebp+12] ;if(x0>x1)
jle @f
swap word[ebp+8],word[ebp+12] ;swap(x0, x1);
swap word[ebp+10],word[ebp+14] ;swap(y0, y1);
@@:
; int deltax si
; int deltay di
; int error ebp-6
; int ystep ebp-8
mov ax,word[ebp+8] ;x=x0
mov si,word[ebp+12] ;x1
sub si,ax ;deltax = x1-x0
mov bx,si
shr bx,1
mov loc_1,bx ;error = deltax/2
mov ax,word[ebp+10] ;y=y0
mov di,word[ebp+14] ;y1
mov loc_2,word -1 ;ystep = -1
cmp ax,di ;if (y0<y1) ystep = 1;
jge @f
mov loc_2,word 1 ;ystep = 1
@@:
sub di,ax ;y1-y0
bts di,15
jae @f
neg di
inc di
@@:
and di,0x7fff ;deltay = abs(y1-y0)
mov eax,1 ;function, draw point
xor ebx,ebx
xor ecx,ecx
cmp byte[ebp-4],0
jne .coord_yx
mov bx,word[ebp+10] ;y0
mov cx,word[ebp+8] ;x0
@@: ;for (x=x0 ; x<x1; x++) ;------------------------------------
cmp cx,word[ebp+12]
jg @f ;jge ???
call dword[fun_draw_pixel]
sub loc_1,di ;error -= deltay
cmp loc_1,0 ;if(error<0)
jge .if0
add bx,loc_2 ;y += ystep
add loc_1,si ;error += deltax
.if0:
inc cx
jmp @b
@@:
jmp .coord_end
.coord_yx:
mov bx,word[ebp+8] ;x0
mov cx,word[ebp+10] ;y0
@@: ;for (x=x0 ; x<x1; x++) ;------------------------------------
cmp bx,word[ebp+12]
jg @f ;jge ???
call dword[fun_draw_pixel]
sub loc_1,di ;error -= deltay
cmp loc_1,0 ;if(error<0)
jge .if1
add cx,loc_2 ;y += ystep
add loc_1,si ;error += deltax
.if1:
inc bx
jmp @b
@@:
.coord_end:
;---
popad
mov esp,ebp ; восстанавливаем стек
pop ebp
ret 12
;input:
; [esp+8] = p0
; [esp+12] = p1
; [esp+16] = p2
; [esp+20] = color
align 4
cruve_bezier:
push ebp
mov ebp,esp
pushad
;float t, xt,yt;
;for(t=.0;t<1.;t+=.005){
; xt=pow(1.-t,2)*x0+2*t*(1.-t)*x1+pow(t,2)*x2;
; yt=pow(1.-t,2)*y0+2*t*(1.-t)*y1+pow(t,2)*y2;
; dc.SetPixel(xt,yt,255L);
;}
.beg_fun: ;для входа из другой функции
mov edx,dword[ebp+20] ;set cruve color
xor ebx,ebx
xor ecx,ecx
finit
; calculate delta t - вычисление шага изменения параметра t для рисования кривой Безье
push dword[ebp+8]
push dword[ebp+12]
call line_len4i ;определяем длину отрезка p0p1
fld dword[o_len]
push dword[ebp+12]
push dword[ebp+16]
call line_len4i ;определяем длину отрезка p1p2
fadd dword[o_len] ;находим сумарную длину (p0p1 + p1p2)
fadd st0,st0 ; умножаем длинну (p0p1 + p1p2) на 2
ftst
fstsw ax
fld1
sahf
jle @f ;избегаем деления на 0
fdiv st0,st1 ;находим шаг для изменения параметра t по формуле 1 / (2 * (p0p1 + p1p2))
; т.к. прямая в некоторых случаях "рвется", то я думаю что данная формула не оптимальна,
; но ничего лучшего я пока не придумал, ... :(
@@:
fstp dword[delt_t]
finit
;fild word[ebp+18] ;y2
fild word[ebp+14] ;y1
fild word[ebp+10] ;y0
fild word[ebp+16] ;x2
fild word[ebp+12] ;x1
fild word[ebp+8] ;x0
fld dword[delt_t]
fldz ;t=.0
@@:
fld1
fsub st0,st1 ;1.-t
fmul st0,st0 ;pow(1.-t,2)
fmul st0,st3 ;...*x0
fstp dword[opr_param]
fld1
fsub st0,st1 ;1.-t
fmul st0,st1 ;(1.-t)*t
fadd st0,st0
fmul st0,st4 ;...*x1
mov edi,dword[opr_param]
fstp dword[opr_param]
fldz
fadd st0,st1 ;0+t
fmul st0,st0 ;t*t
fmul st0,st5 ;...*x2
fadd dword[opr_param]
mov dword[opr_param],edi
fadd dword[opr_param]
fistp word[v_poi_0] ;x
fld1
fsub st0,st1 ;1.-t
fmul st0,st0 ;pow(1.-t,2)
fmul st0,st6 ;...*y0
fstp dword[opr_param]
fld1
fsub st0,st1 ;1.-t
fmul st0,st1 ;(1.-t)*t
fadd st0,st0
fmul st0,st7 ;...*y1
mov edi,dword[opr_param]
fstp dword[opr_param]
fldz
fadd st0,st1 ;0+t
fmul st0,st0 ;t*t
fimul word[ebp+18] ;...*y2
fadd dword[opr_param]
mov dword[opr_param],edi
fadd dword[opr_param]
fistp word[v_poi_0+2] ;y
mov eax,1
mov bx,word[v_poi_0+2]
mov cx,word[v_poi_0]
call dword[fun_draw_pixel]
fadd st0,st1 ;t+dt
fld1
fcomp
fstsw ax
sahf
jae @b
.end_draw:
; btr word[opt_bez],0 ;снимаем флаг рисования прямой линии с кривой Безье
; btr word[opt_bez],1
;and word[opt_bez],0xfffc
popad
mov esp,ebp
pop ebp
ret 16
delt_t dd 0.05 ;шаг для параметра t из кривой Безье
;функция рисующая сегмент кривуй Безье по 3-м точкам, при этом координаты
; 1-й и 3-й точки смещаются ко 2-й точке, позволяя рисовать длинную кривую из нескольких кусков
;input:
; [esp+8] = p0
; [esp+12] = p1
; [esp+16] = p2
; [esp+20] = color
align 4
cruve_bezier_del2:
; btr word[opt_bez],1 ;test
; ret 16 ;test
push ebp
mov ebp,esp
pushad
;jmp cruve_bezier.end_draw
bt word[opt_bez],1 ;проверяем флаг рисования отрезка для 3-й точки (p2)
jae @f
push dword[ebp+20] ;line color
push dword[ebp+8]
@@:
;********* высчитывание усредненных координат *********
mov ax,word[ebp+8] ;x0
add ax,word[ebp+12]
shr ax,1
bt ax,14
jae @f
or ax,0x8000
@@:
mov word[ebp+8],ax
mov ax,word[ebp+10] ;y0
add ax,word[ebp+14]
shr ax,1
bt ax,14
jae @f
or ax,0x8000
@@:
mov word[ebp+10],ax
btr word[opt_bez],1 ;проверяем флаг рисования отрезка для 3-й точки (p2)
jae @f
push dword[ebp+8]
call line_brs ;рисуем прямой отрезок
@@:
bt word[opt_bez],0 ;проверяем флаг рисования отрезка для 1-й точки (p0)
jae @f
push dword[ebp+20] ;line color
push dword[ebp+16]
@@:
mov ax,word[ebp+16] ;x2
add ax,word[ebp+12]
shr ax,1
bt ax,14
jae @f
or ax,0x8000
@@:
mov word[ebp+16],ax
mov ax,word[ebp+18] ;y2
add ax,word[ebp+14]
shr ax,1
bt ax,14
jae @f
or ax,0x8000
@@:
mov word[ebp+18],ax
btr word[opt_bez],0 ;проверяем флаг рисования отрезка для 1-й точки (p0)
jae @f
push dword[ebp+16]
call line_brs ;рисуем прямой отрезок
@@:
;jmp cruve_bezier.end_draw
;********* переход на основную функцию *********
jmp cruve_bezier.beg_fun
;функция рисующая текст
;input:
; dword[ebp+8] = pointer to vector font data
; dword[ebp+12] = pointer to text param struct (color, x,y, angle, scale, ...)
; dword[ebp+16] = text string (0 - end string)
align 4
draw_text:
push ebp
mov ebp,esp
pushad
mov eax,dword[ebp+8]
mov ebx,dword[ebp+12]
mov edx,dword[ebp+16]
mov esi,ebx
add esi,4 ;skeep color
mov edi,text_point
mov ecx,12 ;(x+y+a)*3
rep movsb ;copy base point
finit
fild word[ebx+12+4]
fdiv dword[eax+4] ;sumbol height
fstp dword[text_point.s]
mov edi,dword[ebx];get color
xor esi,esi ;line number
;------------------------
@@:
cmp byte[edx],0
je @f
xor ecx,ecx
mov cl,byte[edx]
shl cx,2 ;cx*=4
add cx,32
add ecx,eax
;mov ecx,eax
;add ecx,32+256*4+4
push edi ;color
push dword[ecx] ;copy sumbol pointer
pop ecx
add ecx,eax ;добавляем к ссылке на символ смещение начала самого шрифта
push dword ecx
push dword text_point ;output point
call draw_poly_line
cmp byte[edx],13
je .new_line
finit
fld dword[eax] ;sumbol width
fmul dword[text_point.s]
fld dword[text_point.a]
fcos
fmul st0,st1
fadd dword[text_point.x]
fstp dword[text_point.x]
fld dword[text_point.a]
fsin
fmul st0,st1
fadd dword[text_point.y]
fstp dword[text_point.y]
inc edx ;move next sumbol
jmp @b
.new_line:
push edi esi
mov esi,dword[ebp+12]
add esi,4 ;skeep color
mov edi,text_point
mov ecx,8 ;(x+y)*4
rep movsb ;restore base point
pop esi edi
inc esi
mov dword[opr_param],esi
finit
fld dword[eax+4] ;sumbol height
fmul dword[text_point.s]
fimul dword[opr_param]
fld1
fld1
fadd st0,st1
fldpi
fdiv st0,st1
fadd dword[text_point.a]
fcos
; fld dword[eax+4] ;sumbol height
; fmul dword[text_point.s]
fmul st0,st3
fadd dword[text_point.x]
fstp dword[text_point.x]
fld1
fld1
fadd st0,st1
fldpi
fdiv st0,st1
fadd dword[text_point.a]
fsin
; fld dword[eax+4] ;sumbol height
; fmul dword[text_point.s]
fmul st0,st5
fadd dword[text_point.y]
fstp dword[text_point.y]
inc edx ;move next sumbol
jmp @b
@@:
popad
pop ebp
ret 12
text_point: ;точка для вывода текста
.x dd 0.0
.y dd 0.0
.a dd 0.0 ;angle
.s dd 1.0 ;scale
;функция для конвертирования координат из декартовой системы координат в полярную
;input:
; dword[ebp+8] = pointer to contur
align 4
convert_contur:
push ebp
mov ebp,esp
push eax ebx ecx
mov ebx,dword[ebp+8]
finit
.new_contur:
mov cx,word[ebx]
or word[ebx],VECT_POINTS_IS_POLAR
add ebx,2
btr cx,15 ;VECT_PARAM_COLOR
jae @f
add ebx,4
@@:
btr cx,14 ;VECT_PARAM_PROP_L
jae @f
add ebx,4
@@:
btr cx,12 ;проверка конвертированных
jae @f
and ecx,0xfff
cmp cx,0
je .end_contur
shl ecx,3
add ebx,ecx
jmp .new_contur
@@:
and cx,0xfff
cmp cx,0
je .end_contur
mov eax,opr_param
@@:
cmp cx,0
je .new_contur
dec cx
fld dword[ebx]
fistp word[eax]
fld dword[ebx+4]
fistp word[eax+2]
push dword[eax]
call opred2i
push dword[o_ang]
pop dword[ebx] ;x(n)
push dword[o_len]
pop dword[ebx+4] ;y(n)
add ebx,8 ;move next coord
jmp @b
.end_contur:
pop ecx ebx eax ebp
ret 4
;функция для рисования контуров, состоящих из разных наборов точек (прямые, Безье)
;input:
; [esp+8] = x0,y0,a0,s0 - параметры центральной точки: координаты, угол поворота, масштаб
; [esp+12] = contur - контур, заданный координатами точек
; [esp+16] = color - первоначальный цвет
align 4
draw_poly_line:
push ebp
mov ebp,esp
pushad
mov eax,dword[ebp+8]
mov ebx,dword[ebp+12]
mov edx,dword[ebp+16]
bt word[ebx],12 ;VECT_POINTS_IS_POLAR
jc @f
push dword ebx
call convert_contur
@@:
mov word[opt_bez],0 ;clear draw options
finit
fld dword[eax] ;x0 (st4)
fld dword[eax+4];y0 (st3)
fld dword[eax+8];a0 (st2)
fld dword[eax+12];s0(st1)
mov si,0 ;сплошная линия, без прерываний
.new_contur:
mov cx,word[ebx]
mov edi,ebx ;резервное сохранение начала контура
add ebx,2
btr cx,15 ;VECT_PARAM_COLOR
jae @f
mov edx,dword[ebx]
add ebx,4
@@:
btr cx,14 ;VECT_PARAM_PROP_L
jae @f
mov esi,dword[ebx] ;получаем новые параметры линии
add ebx,4
btr si,9 ;VECT_CONT_BEZIER = 0x200
jc .BezB ;дальше контур Безье, не линейный
and si,0xff
@@:
jmp .BezE
.BezB: ;пропуск всех точек Безье
bt word[opt_bez],2
jc .after_bez_draw
or word[opt_bez],4
push edx
push edi ;начало контура - ebx
push dword[ebp+8] ;eax
call draw_poly_bezier
.after_bez_draw:
and ecx,0xfff
cmp ecx,0
je .end_contur
shl ecx,3
add ebx,ecx
jmp .new_contur
.BezE:
and cx,0xfff
cmp cx,0
je .end_contur
mov di,cx
sub di,si
fld dword[ebx] ;st0=a(n)
fadd st0,st2
fcos
fmul dword[ebx+4] ;l(n)
fmul st0,st1 ;*=scale
fadd st0,st4
fistp word[v_poi_1+2] ;x(n)
fld dword[ebx] ;st0=a(n)
fadd st0,st2
fsin
fmul dword[ebx+4] ;l(n)
fmul st0,st1 ;*=scale
fadd st0,st3
fistp word[v_poi_1] ;y(n)
dec cx
add ebx,8 ;move next coord
@@: ;---------------------------------------------------------------
push dword[v_poi_1]
pop dword[v_poi_0]
; call draw_vect_point
cmp cx,0
je .new_contur ;во избежание зацикливания
fld dword[ebx] ;st0=a(n)
fadd st0,st2
fcos
fmul dword[ebx+4] ;l(n)
fmul st0,st1 ;*=scale
fadd st0,st4
fistp word[v_poi_1+2] ;x(n)
fld dword[ebx] ;st0=a(n)
fadd st0,st2
fsin
fmul dword[ebx+4] ;l(n)
fmul st0,st1 ;*=scale
fadd st0,st3
fistp word[v_poi_1] ;y(n)
add ebx,8 ;move next coord
cmp cx,di
je .end_draw_line
push dword edx ;line color
push dword[v_poi_0]
push dword[v_poi_1]
call line_brs
loop @b
jmp .new_contur
.end_draw_line: ;-------------------------------------------------------------
sub di,si
loop @b
jmp .new_contur
.end_contur:
popad
pop ebp
ret 12
;функция рисующая полигоны состоящие из кривых Безье
;input:
; [esp+8] = x0,y0,a0,...
; [esp+12] = contur
; [esp+16] = color
align 4
draw_poly_bezier:
push ebp
mov ebp,esp
pushad
mov eax,dword[ebp+8]
mov ebx,dword[ebp+12]
mov edx,dword[ebp+16]
finit
fld dword[eax] ;x0 (st4)
fld dword[eax+4];y0 (st3)
fld dword[eax+8];a0 (st2)
fld dword[eax+12];s0(st1)
mov si,0 ;сплошная линия, без прерываний
.new_contur:
mov cx,word[ebx]
add ebx,2
btr cx,15
jae @f
mov edx,dword[ebx]
add ebx,4
@@:
btr cx,14 ;VECT_PARAM_PROP_L
jae @f
mov esi,dword[ebx] ;получаем новые параметры линии
btr si,8 ;VECT_CONT_LINE = 0x100
;jc .end_contur ;дальше контур линейный, не Безье
jae .skip
and ecx,0xfff
cmp ecx,0
je .end_contur
add ebx,4
shl ecx,3
add ebx,ecx
jmp .new_contur
.skip:
and si,0xff
add ebx,4
@@:
and ecx,0xfff
cmp ecx,0
je .end_contur
cmp si,1 ;проверка контура на 3 точки
je @f
cmp si,2
je @f
jmp .3pt
shl ecx,3
add ebx,ecx
jmp .new_contur
.3pt: ;тут контуры минимум с 3-мя точками
mov di,si
fld dword[ebx] ;st0=a(n)
fadd st0,st2
fcos
fmul dword[ebx+4] ;l(n)
fmul st0,st1 ;*=scale
fadd st0,st4
fistp word[v_poi_1+2] ;x(n)
fld dword[ebx] ;st0=a(n)
fadd st0,st2
fsin
fmul dword[ebx+4] ;l(n)
fmul st0,st1 ;*=scale
fadd st0,st3
fistp word[v_poi_1] ;y(n)
dec cx
add ebx,8 ;move next coord
cmp cx,0
je .new_contur ;во избежание зацикливания
fld dword[ebx] ;st0=a(n)
fadd st0,st2
fcos
fmul dword[ebx+4] ;l(n)
fmul st0,st1 ;*=scale
fadd st0,st4
fistp word[v_poi_2+2] ;x(n)
fld dword[ebx] ;st0=a(n)
fadd st0,st2
fsin
fmul dword[ebx+4] ;l(n)
fmul st0,st1 ;*=scale
fadd st0,st3
fistp word[v_poi_2] ;y(n)
dec cx
add ebx,8 ;move next coord
or word[opt_bez],1 ;begin line
.bez_cycl: ;---------------------------------------------------------
dec di
push dword[v_poi_1]
pop dword[v_poi_0]
push dword[v_poi_2]
pop dword[v_poi_1]
cmp cx,0
je .new_contur ;во избежание зацикливания
fld dword[ebx] ;st0=a(n)
fadd st0,st2
fcos
fmul dword[ebx+4] ;l(n)
fmul st0,st1 ;*=scale
fadd st0,st4
fistp word[v_poi_2+2] ;x(n)
fld dword[ebx] ;st0=a(n)
fadd st0,st2
fsin
fmul dword[ebx+4] ;l(n)
fmul st0,st1 ;*=scale
fadd st0,st3
fistp word[v_poi_2] ;y(n)
add ebx,8 ;move next coord
cmp di,2
jne @f
or word[opt_bez],2 ;end line
@@:
cmp cx,1
jne @f
or word[opt_bez],2 ;end line
@@:
dec si
cmp di,si
jne @f
or word[opt_bez],1 ;begin line
@@:
inc si
cmp di,si
je @f
cmp di,1
je .end_draw_line
push dword edx ;line color
push dword[v_poi_0]
push dword[v_poi_1]
push dword[v_poi_2]
call cruve_bezier_del2
finit
fld dword[eax] ;x0 (st4)
fld dword[eax+4];y0 (st3)
fld dword[eax+8];a0 (st2)
fld dword[eax+12];s0(st1)
jmp @f
.end_draw_line: ;-------------------------------------------------------------
mov di,si
inc di
@@:
;loop .bez_cycl ;@b
dec cx
cmp cx,0
jg .bez_cycl
jmp .new_contur
.end_contur:
popad
pop ebp
ret 12
;функция принимает координаты точки x,y и определяет угол и длину
;input:
; ebp+8 = adress int coord x
; ebp+10 = adress int coord y
align 4
opred2i:
push ebp
mov ebp,esp
finit
fild word [ebp+8]
fmul st0,st0 ;st0=x^2
fild word [ebp+10]
fmul st0,st0 ;st0=y^2
fadd st0,st1
fsqrt
fst dword [o_len]
cmp dword [o_len],0
jne @f
mov dword [o_ang],0
jmp .retf
@@:
fild word [ebp+8]
fdiv dword [o_len]
call acos
cmp word [ebp+10],0
jl @f
fst [o_ang] ;a=acos(x/l);
jmp .retf
@@:
fldpi
fadd st0,st0 ;st0=2*pi
fsub st0,st1 ;st0=2*pi-aac
fst [o_ang] ;a=st0;
.retf:
pop ebp
ret 4
;функция определяющая расстояние между точками, результат попадает в o_len
;input:
; ebp+8 = p0
; ebp+12 = p1
align 4
line_len4i:
push ebp
mov ebp,esp
finit
fild word [ebp+8]
fisub word [ebp+12]
fmul st0,st0 ;st0=x^2
fild word [ebp+10]
fisub word [ebp+14]
fmul st0,st0 ;st0=y^2
fadd st0,st1
fsqrt
fstp dword [o_len]
pop ebp
ret 8
;функция для нахождения арккосинуса
;input:
; st0 = float value
align 4
acos:
fld1
fadd st, st1
fld1
fsub st, st2
fmulp st1, st
fsqrt
fxch st1
fpatan
ret
o_len dd ? ;длина
o_ang dd ? ;угол порота в радианах
opr_param dd ?
v_poi_0 dd ?
v_poi_1 dd ?
v_poi_2 dd ?
opt_bez dw ? ;опции рисования кусков для кривой Безье
align 16
EXPORTS:
dd sz_buf_create, buf_create
dd sz_set_active_buf, set_active_buf
dd sz_buf_clear, buf_clear
dd sz_draw_buf, draw_buf
dd sz_buf_delete, buf_delete
dd sz_line, line_brs
dd sz_cruve_bezier, cruve_bezier
dd sz_conv, convert_contur
dd sz_draw, draw_poly_line
dd sz_opred2i, opred2i
dd sz_line_len4i, line_len4i
dd sz_draw_text, draw_text
dd sz_o_len, o_len
dd sz_o_ang, o_ang
dd 0,0
sz_buf_create db 'vect_buf_create',0
sz_set_active_buf db 'vect_buf_set_active',0
sz_buf_clear db 'vect_buf_clear',0
sz_draw_buf db 'vect_buf_draw',0
sz_buf_delete db 'vect_buf_delete',0
sz_line db 'vect_line',0
sz_cruve_bezier db 'vect_c_bezier',0
sz_conv db 'vect_conv_cont',0
sz_draw db 'vect_draw_cont',0
sz_opred2i db 'vect_opred2i',0
sz_line_len4i db 'vect_line_len4i',0
sz_draw_text db 'vect_draw_text',0
sz_o_len db 'vect_o_len',0
sz_o_ang db 'vect_o_ang',0