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