From 83bfd951f0c21974f9002dff609a10454a66cfdc Mon Sep 17 00:00:00 2001 From: "Kirill Lipatov (Leency)" Date: Mon, 5 Nov 2012 11:12:45 +0000 Subject: [PATCH] vector library by IgorA git-svn-id: svn://kolibrios.org@3001 a494cfbc-eb01-0410-851d-a64ba20cac60 --- .../libraries/vector/trunk/example_logo.asm | 313 +++++ .../libraries/vector/trunk/vectors.asm | 1251 +++++++++++++++++ 2 files changed, 1564 insertions(+) create mode 100644 programs/develop/libraries/vector/trunk/example_logo.asm create mode 100644 programs/develop/libraries/vector/trunk/vectors.asm diff --git a/programs/develop/libraries/vector/trunk/example_logo.asm b/programs/develop/libraries/vector/trunk/example_logo.asm new file mode 100644 index 0000000000..e81121d3a4 --- /dev/null +++ b/programs/develop/libraries/vector/trunk/example_logo.asm @@ -0,0 +1,313 @@ +use32 + org 0x0 + db 'MENUET01' ;идентиф. исполняемого файла всегда 8 байт + dd 0x1 + dd start + dd i_end ; размер приложения + dd mem + dd stacktop + dd 0x0 + dd cur_dir_path + +include 'macros.inc' +include 'vectors.inc' ;vectors functions constant +include 'load_lib.mac' + +@use_library + +delt_angl dd 0.15708 ;угол поворота при нажатии курсоров +delt_size dd 0.05 ;шаг изменения масштаба +scale_min dd 0.05 ;минимальный масштаб +delt_x dd 10.0 ;передвижение по оси x +delt_y equ delt_x + +arr0c: + .x dd 200.0 + .y dd 150.0 + .a dd 0.0 ;angle + .s dd 0.35 ;scale +arr1v: + dw 12+VECT_PARAM_PROP_L+VECT_PARAM_COLOR ;туловище + dd 0xffd040 + dd VECT_CONT_BEZIER + dd 6.0,128.0, 41.0,113.0, 175.0,94.0, 211.0,78.0 + dd 263.0,48.0, 300.0,29.0, 345.0,30.0, 383.0,52.0 + dd 415.0,85.0, 443.0,100.0, 476.0,112.0, 519.0,135.0 + dw 32+VECT_PARAM_PROP_L + dd VECT_CONT_BEZIER + dd 6.0,128.0, 48.0,127.0, 119.0,116.0, 202.0,114.0 + dd 233.0,127.0, 274.0,185.0, 300.0,211.0, 351.0,243.0 + dd 386.0,271.0, 398.0,292.0, 429.0,328.0, 507.0,384.0 + dd 517.0,401.0, 534.0,402.0, 545.0,388.0, 568.0,386.0 + dd 587.0,370.0, 612.0,393.0, 660.0,409.0, 712.0,447.0 + dd 711.0,422.0, 764.0,438.0, 837.0,481.0, 853.0,480.0 + dd 838.0,470.0, 860.0,466.0, 836.0,451.0, 851.0,447.0 + dd 796.0,412.0, 743.0,361.0, 719.0,335.0, 677.0,290.0 + + dw 23+VECT_PARAM_PROP_L ;крылья + dd VECT_CONT_BEZIER + dd 437.0,130.0, 519.0,135.0, 591.0,139.0, 616.0,150.0 + dd 697.0,163.0, 776.0,183.0, 849.0,230.0, 811.0,245.0 + dd 808.0,265.0, 771.0,258.0, 769.0,281.0, 729.0,277.0 + dd 718.0,296.0, 679.0,284.0, 665.0,294.0, 642.0,290.0 + dd 636.0,304.0, 609.0,296.0, 596.0,306.0, 574.0,301.0 + dd 541.0,299.0, 514.0,302.0, 495.0,299.0 + dw 16+VECT_PARAM_PROP_L + dd VECT_CONT_BEZIER + dd 484.0,116.0, 514.0,110.0, 564.0,82.0, 618.0,63.0 + dd 712.0,25.0, 774.0,25.0, 796.0,39.0, 778.0,51.0 + dd 779.0,64.0, 754.0,78.0, 745.0,97.0, 720.0,113.0 + dd 713.0,132.0, 688.0,146.0, 683.0,153.0, 668.0,158.0 + + dw 7+VECT_PARAM_PROP_L+VECT_PARAM_COLOR ;глаз + dd 0x0 + dd VECT_CONT_BEZIER + dd 292.0,88.0, 278.0,78.0, 262.0,86.0, 261.0,101.0 + dd 274.0,110.0, 291.0,105.0, 292.0,88.0, 778.0,51.0 + dw 0 + +align 4 +start: + mov ecx,sc + mov edx,sizeof.system_colors + mcall 48,3 + mcall 40,0x27 + + sys_load_library vectors_name, cur_dir_path, library_path, system_path, \ + err_message_found_lib, head_f_l, vectors_lib_import, err_message_import, head_f_i + + push 5*65536+40 + push 500*65536+350 + push 0xffffd0 ;цвет фона + push word 24*256+1 + call [vect_buf_create] + + push word 1 + call [vect_buf_set_active] ;устанавливаем режим рисования в 1-й буфер + +red_win: + call draw_window + +still: + mcall 10 + + cmp al,0x1 ;изм. положение окна + jz red_win + cmp al,0x2 + jz key + cmp al,0x3 + jz button + jmp still + +draw_window: + mcall 12,1 + + xor eax,eax + mov ebx,10*65536+520 + mov ecx,10*65536+430 + mov edx,0xffffff;[sc.work] + or edx,0x33000000 + mov edi,hed + mcall + + mov eax,4 + mov ebx,5*65536+5 + mov ecx,0x808000 + or ecx,0x80000000 + mov edx,txtInfo1 + int 0x40 + mov ebx,5*65536+20 + mov edx,txtInfo2 + int 0x40 + + call draw_vect_image + + mcall 12,2 + ret + +draw_vect_image: + push word 1 + call [vect_buf_clear] ;чистим 1-й буфер + + push dword 0x808000 + push dword arr1v + push dword arr0c + call [vect_draw_cont] + + push word 1 + call [vect_buf_draw] ;выводим 1-й буфер на экран + ret + +button: +; mcall 17 ;получить код нажатой кнопки +; cmp ah,1 +; jne still +.exit: + push word 1 + call [vect_buf_delete] ;удаляем 1-й буфер + mcall -1 ;выход из программы + +key: + mcall 2 + + cmp ah,27 ;Esc + je button.exit + + cmp ah,176 ;Left + jne @f + call Image_RotLeft + call draw_vect_image + @@: + cmp ah,179 ;Right + jne @f + call Image_RotRight + call draw_vect_image + @@: + cmp ah,178 ;Up + jne @f + fld dword[arr0c.s] + fadd dword[delt_size] + fstp dword[arr0c.s] + call draw_vect_image + @@: + cmp ah,177 ;Down + jne @f + call ScaleDec + call draw_vect_image + @@: + cmp ah,119 ;w + jne @f + call Image_MoveUp + call draw_vect_image + @@: + cmp ah,115 ;s + jne @f + call Image_MoveDown + call draw_vect_image + @@: + cmp ah,100 ;d + jne @f + call Image_MoveRight + call draw_vect_image + @@: + cmp ah,97 ;a + jne @f + call Image_MoveLeft + call draw_vect_image + @@: + + jmp still + +;d +Image_MoveRight: + fld dword[arr0c.x] + fadd dword[delt_x] + fstp dword[arr0c.x] + ret + +;a +Image_MoveLeft: + fld dword[arr0c.x] + fsub dword[delt_x] + fstp dword[arr0c.x] + ret + +;w +Image_MoveUp: + fld dword[arr0c.y] + fsub dword[delt_y] + fstp dword[arr0c.y] + ret + +;s +Image_MoveDown: + fld dword[arr0c.y] + fadd dword[delt_y] + fstp dword[arr0c.y] + ret + +Image_RotLeft: + mov bl,1 + fld dword[arr0c.a] + fsub dword[delt_angl] + fstp dword[arr0c.a] + ret + +Image_RotRight: + mov bl,1 + fld dword[arr0c.a] + fadd dword[delt_angl] + fstp dword[arr0c.a] + ret + +ScaleDec: + push ax + finit + fld dword[arr0c.s] + fsub dword[delt_size] + + fcom dword[scale_min] + fstsw ax + sahf + jbe @f + fstp dword[arr0c.s] + @@: + pop ax +ret + +o_dan dd ? +hed db 'Drawing vector image',0 +txtInfo1 db 'Љгаб®ал: [',27,'], [',26,'] - Ї®ў®а®в; [',24,'], [',25,'] - а §¬Ґа',0 +txtInfo2 db 'Љ­®ЇЄЁ: [a], [d] - ў«Ґў®, ўЇа ў®; [w], [s] - ўўҐае, ў­Ё§',0 +sc system_colors + +;-------------------------------------------------- +align 4 +vectors_lib_import: + vect_buf_create dd av_buf_create + vect_buf_set_active dd av_buf_set_active + vect_buf_clear dd av_buf_clear + vect_buf_draw dd av_draw_buf + vect_buf_delete dd av_buf_delete + vect_line dd av_line + vect_c_bezier dd av_c_bezier + vect_conv_cont dd av_conv_cont + vect_draw_cont dd av_draw_cont + vect_opred2i dd av_opred2i + vect_line_len4i dd av_line_len4i + vect_o_len dd av_o_len + vect_o_ang dd av_o_ang + + dd 0,0 + av_buf_create db 'vect_buf_create',0 + av_buf_set_active db 'vect_buf_set_active',0 + av_buf_clear db 'vect_buf_clear',0 + av_draw_buf db 'vect_buf_draw',0 + av_buf_delete db 'vect_buf_delete',0 + av_line db 'vect_line',0 + av_c_bezier db 'vect_c_bezier',0 + av_conv_cont db 'vect_conv_cont',0 + av_draw_cont db 'vect_draw_cont',0 + av_opred2i db 'vect_opred2i',0 + av_line_len4i db 'vect_line_len4i',0 + av_o_len db 'vect_o_len',0 + av_o_ang db 'vect_o_ang',0 + +;-------------------------------------------------- +system_path db '/sys/lib/' +vectors_name db 'vectors.obj',0 +err_message_found_lib db 'Sorry I cannot load library vectors.obj',0 +head_f_i: +head_f_l db 'System error',0 +err_message_import db 'Error on load import library vectors.obj',0 +;-------------------------------------------------- + +i_end: ;конец кода + rb 1024 +stacktop: + cur_dir_path: + rb 4096 + library_path: + rb 4096 +mem: + diff --git a/programs/develop/libraries/vector/trunk/vectors.asm b/programs/develop/libraries/vector/trunk/vectors.asm new file mode 100644 index 0000000000..5849ebf616 --- /dev/null +++ b/programs/develop/libraries/vector/trunk/vectors.asm @@ -0,0 +1,1251 @@ +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